Skip to contentSkip to conversation

usb: gadget: ccid: add support for USB CCID Gadget Device

PATCH Superseded Marcus Folkesson 5 participants 13 messages May 26, 2018 – May 29, 2018

Subsystems (2)

v2 of 4 Superseded Latest is v4 →

lore
Share & tools
lore
#0 lore raw

PATCH v2 1/3 usb: gadget: ccid: add support for USB CCID Gadget Device

Chip Card Interface Device (CCID) protocol is a USB protocol that allows a smartcard device to be connected to a computer via a card reader using a standard USB interface, without the need for each manufacturer of smartcards to provide its own reader or protocol.

This gadget driver makes Linux show up as a CCID device to the host and let a userspace daemon act as the smartcard.

This is useful when the Linux gadget itself should act as a cryptographic device or forward APDUs to an embedded smartcard device.

---
 drivers/usb/gadget/Kconfig           |  17 +
 drivers/usb/gadget/function/Makefile |   1 +
 drivers/usb/gadget/function/f_ccid.c | 988 +++++++++++++++++++++++++++++++++++
 drivers/usb/gadget/function/f_ccid.h |  91 ++++
 include/uapi/linux/usb/ccid.h        |  93 ++++
 5 files changed, 1190 insertions(+)
 create mode 100644 drivers/usb/gadget/function/f_ccid.c
 create mode 100644 drivers/usb/gadget/function/f_ccid.h
 create mode 100644 include/uapi/linux/usb/ccid.h
drivers/usb/gadget/Kconfig +17 -0
index 31cce7805eb2..bdebdf1ffa2b 100644
@@ -149,6 +149,9 @@ config USB_LIBCOMPOSITE
 config USB_F_ACM
 	tristate
 
+config USB_F_CCID
+	tristate
+
 config USB_F_SS_LB
 	tristate
 
@@ -248,6 +251,20 @@ config USB_CONFIGFS_ACM
 	  ACM serial link.  This function can be used to interoperate with
 	  MS-Windows hosts or with the Linux-USB "cdc-acm" driver.
 
+config USB_CONFIGFS_CCID
+	bool "Chip Card Interface Device (CCID)"
+	depends on USB_CONFIGFS
+	select USB_F_CCID
+	help
+	  The CCID function driver provides generic emulation of a
+	  Chip Card Interface Device (CCID).
+
+	  You will need a user space server talking to /dev/ccidg*,
+	  since the kernel itself does not implement CCID/TPDU/APDU
+	  protocol.
+
+	  For more information, see Documentation/usb/gadget_ccid.rst.
+
 config USB_CONFIGFS_OBEX
 	bool "Object Exchange Model (CDC OBEX)"
 	depends on USB_CONFIGFS
drivers/usb/gadget/function/Makefile +1 -0
index 5d3a6cf02218..629851009e1a 100644
@@ -9,6 +9,7 @@ ccflags-y			+= -I$(srctree)/drivers/usb/gadget/udc/
 # USB Functions
 usb_f_acm-y			:= f_acm.o
 obj-$(CONFIG_USB_F_ACM)		+= usb_f_acm.o
+obj-$(CONFIG_USB_F_CCID)	+= f_ccid.o
 usb_f_ss_lb-y			:= f_loopback.o f_sourcesink.o
 obj-$(CONFIG_USB_F_SS_LB)	+= usb_f_ss_lb.o
 obj-$(CONFIG_USB_U_SERIAL)	+= u_serial.o
drivers/usb/gadget/function/f_ccid.c new file +988 -0

988 lines not on this page · raw message

drivers/usb/gadget/function/f_ccid.h new file +91 -0

91 lines not on this page · raw message

include/uapi/linux/usb/ccid.h new file +93 -0

93 lines not on this page · raw message

#1 lore raw

PATCH v2 2/3 Documentation: usb: add documentation for USB CCID Gadget Device

Add documentation to give a brief description on how to use the CCID Gadget Device.
This includes a description for all attributes followed by an example on how to setup the device with ConfigFS.

---
 Documentation/usb/gadget_ccid.rst | 267 ++++++++++++++++++++++++++++++++++++++
 1 file changed, 267 insertions(+)
 create mode 100644 Documentation/usb/gadget_ccid.rst
Documentation/usb/gadget_ccid.rst new file +267 -0
new file mode 100644
index 000000000000..5ac806b14604
@@ -0,0 +1,267 @@
+.. SPDX-License-Identifier: GPL-2.0
+
+============
+CCID Gadget
+============
+
+:Author: Marcus Folkesson <[email protected]>
+
+Introduction
+============
+
+The CCID Gadget will present itself as a CCID device to the host system.
+The device supports two endpoints for now; BULK IN and BULK OUT.
+These endpoints is exposed to userspace via /dev/ccidg*.
+
+All CCID commands are sent on the BULK-OUT endpoint. Each command sent to the CCID
+has an associated ending response. Some commands can also have intermediate
+responses. The response is sent on the BULK-IN endpoint.
+See Figure 3-3 in the CCID Specification [1]_ for more details.
+
+The CCID commands must be handled in userspace since the driver is only working
+as a transport layer for the TPDUs.
+
+
+CCID Commands
+--------------
+
+All CCID commands begins with a 10 bytes header followed by an optional
+data field depending on message type.
+
++--------+--------------+-------+----------------------------------+
+| Offset | Field        | Size  | Description                      |
++========+==============+=======+==================================+
+| 0      | bMessageType | 1     | Type of message                  |
++--------+--------------+-------+----------------------------------+
+| 1      | dwLength     | 4     | Message specific data length     |
+|        |              |       |                                  |
++--------+--------------+-------+----------------------------------+
+| 5      | bSlot        | 1     | Identifies the slot number       |
+|        |              |       | for this command                 |
++--------+--------------+-------+----------------------------------+
+| 6      | bSeq         | 1     | Sequence number for command      |
++--------+--------------+-------+----------------------------------+
+| 7      | ...          | 3     | Fields depends on message type   |
++--------+--------------+-------+----------------------------------+
+| 10     | abData       | array | Message specific data (OPTIONAL) |
++--------+--------------+-------+----------------------------------+
+
+
+Multiple CCID gadgets
+----------------------
+
+It is possible to create multiple instances of the CCID gadget, however,
+a much more flexible way is to create one gadget and set the `nslots` attribute
+to the number of desired CCID devices.
+
+All CCID commands specifies which slot that is the receiver in the `bSlot` field
+of the CCID header.
+
+Usage
+=====
+
+Access from userspace
+----------------------
+All communication is by read(2) and write(2) to the corresponding /dev/ccidg* device.
+Only one filedescriptor is allowed to be open to the device at a time.
+
+The buffer size provided to read(2) **must be at least** 522 (10 bytes header + 512 bytes payload)
+bytes as we are working with whole commands.
+
+The buffer size provided to write(2) **may not exceed** 522 (10 bytes header + 512 bytes payload)
+bytes as we are working with whole commands.
+
+
+Configuration with configfs
+----------------------------
+
+ConfigFS is used to create and configure the CCID gadget.
+In order to get a device to work as intended, a few attributes must
+be considered.
+
+The attributes is described below followed by an example.
+
+features
+~~~~~~~~~
+
+The `feature` attribute writes to the dwFeatures field in the class descriptor.
+See Table 5.1-1 Smart Card Device Descriptors in the CCID Specification [1]_.
+
+The value indicates what intelligent features the CCID has.
+These values are available to user application as defines in ccid.h [2]_.
+The default value is 0x00000000.
+
+The value is a bitwise OR operation performed on the following values:
+
++------------+----------------------------------------------------------------+
+| Value      | Description                                                    |
++============+================================================================+
+| 0x00000000 | No special characteristics                                     |
++------------+----------------------------------------------------------------+
+| 0x00000002 | Automatic parameter configuration based on ATR data            |
++------------+----------------------------------------------------------------+
+| 0x00000004 | Automatic activation of ICC on inserting                       |
++------------+----------------------------------------------------------------+
+| 0x00000008 | Automatic ICC voltage selection                                |
++------------+----------------------------------------------------------------+
+| 0x00000010 | Automatic ICC clock frequency change according to active       |
+|            | parameters provided by the Host or self determined             |
++------------+----------------------------------------------------------------+
+| 0x00000020 | Automatic baud rate change according to active                 |
+|            | parameters provided by the Host or self determined             |
++------------+----------------------------------------------------------------+
+| 0x00000040 | Automatic parameters negotiation made by the CCID              |
++------------+----------------------------------------------------------------+
+| 0x00000080 | Automatic PPS made by the CCID according to the                |
+|            | active parameters                                              |
++------------+----------------------------------------------------------------+
+| 0x00000100 | CCID can set ICC in clock stop mode                            |
++------------+----------------------------------------------------------------+
+| 0x00000200 | NAD value other than 00 accepted (T=1 protocol in use)         |
++------------+----------------------------------------------------------------+
+| 0x00000400 | Automatic IFSD exchange as first exchange                      |
++------------+----------------------------------------------------------------+
+
+
+Only one of the following values may be present to select a level of exchange:
+
++------------+--------------------------------------------------+
+| Value      | Description                                      |
++============+==================================================+
+| 0x00010000 | TPDU level exchanges with CCID                   |
++------------+--------------------------------------------------+
+| 0x00020000 | Short APDU level exchange with CCID              |
++------------+--------------------------------------------------+
+| 0x00040000 | Short and Extended APDU level exchange with CCID |
++------------+--------------------------------------------------+
+
+If none of those values is indicated the level of exchange is
+character.
+
+
+protocols
+~~~~~~~~~~
+The `protocols` attribute writes to the dwProtocols field in the class descriptor.
+See Table 5.1-1 Smart Card Device Descriptors in the CCID Specification [1]_.
+
+The value is a bitwise OR operation performed on the following values:
+
++--------+--------------+
+| Value  | Description  |
++========+==============+
+| 0x0001 | Protocol T=0 |
++--------+--------------+
+| 0x0002 | Protocol T=1 |
++--------+--------------+
+
+If no protocol is selected both T=0 and T=1 will be supported (`protocols` = 0x0003).
+
+nslots
+~~~~~~
+
+The `nslots` attribute writes to the bMaxSlotIndex field in the class descriptor.
+See Table 5.1-1 Smart Card Device Descriptors in the CCID Specification [1]_.
+
+This is the index of the highest available slot on this device. All slots are consecutive starting at 00h.
+i.e. 0Fh = 16 slots on this device numbered 00h to 0Fh.
+
+The default value is 0, which means one slot.
+
+
+pinsupport
+~~~~~~~~~~~~
+
+This value indicates what PIN support features the CCID has.
+
+The `pinsupport` attribute writes to the dwPINSupport field in the class descriptor.
+See Table 5.1-1 Smart Card Device Descriptors in the CCID Specification [1]_.
+
+
+The value is a bitwise OR operation performed on the following values:
+
++--------+----------------------------+
+| Value  | Description                |
++========+============================+
+| 0x00   | No PIN support             |
++--------+----------------------------+
+| 0x01   | PIN Verification supported |
++--------+----------------------------+
+| 0x02   | PIN Modification supported |
++--------+----------------------------+
+
+The default value is set to 0x00.
+
+
+lcdlayout
+~~~~~~~~~~
+
+Number of lines and characters for the LCD display used to send messages for PIN entry.
+
+The `lcdLayout` attribute writes to the wLcdLayout field in the class descriptor.
+See Table 5.1-1 Smart Card Device Descriptors in the CCID Specification [1]_.
+
+
+The value is set as follows:
+
++--------+------------------------------------+
+| Value  | Description                        |
++========+====================================+
+| 0x0000 | No LCD                             |
++--------+------------------------------------+
+| 0xXXYY | XX: number of lines                |
+|        | YY: number of characters per line. |
++--------+------------------------------------+
+
+The default value is set to 0x0000.
+
+
+Example
+-------
+
+Here is an example on how to setup a CCID gadget with configfs ::
+
+    #!/bin/sh
+
+    CONFIGDIR=/sys/kernel/config
+    GADGET=$CONFIGDIR/usb_gadget/g0
+    FUNCTION=$GADGET/functions/ccid.sc0
+
+    VID=YOUR_VENDOR_ID_HERE
+    PID=YOUR_PRODUCT_ID_HERE
+    UDC=YOUR_UDC_HERE
+
+    #Mount filesystem
+    mount none -t configfs $CONFIGDIR
+
+    #Populate ID:s
+    echo $VID > $GADGET/idVendor
+    echo $PID > $GADGET/idProduct
+
+    #Create and configure the gadget
+    mkdir $FUNCTION
+    echo 0x000407B8 > $FUNCTION/features
+    echo 0x02 > $FUNCTION/protocols
+
+    #Create our english strings
+    mkdir  $GADGET/strings/0x409
+    echo 556677 > $GADGET/strings/0x409/serialnumber
+    echo "Hungry Penguins" > $GADGET/strings/0x409/manufacturer
+    echo "Harpoon With SmartCard"  > $GADGET/strings/0x409/product
+
+    #Create configuration
+    mkdir  $GADGET/configs/c.1
+    mkdir  $GADGET/configs/c.1/strings/0x409
+    echo Config1 > $GADGET/configs/c.1/strings/0x409/configuration
+
+    #Use `Config1` for our CCID gadget
+    ln -s $FUNCTION $GADGET/configs/c.1
+
+    #Execute
+    echo $UDC > $GADGET/UDC
+
+
+References
+==========
+
+.. [1] http://www.usb.org/developers/docs/devclass_docs/DWG_Smart-Card_CCID_Rev110.pdf
+.. [2] include/uapi/linux/usb/ccid.h
reviewer
#2 lore raw

Re: [PATCH v2 2/3] Documentation: usb: add documentation for USB CCID Gadget Device

Hi,

I have a few documentation comments below...

Quoted 21 lines · Marcus Folkesson

Add documentation to give a brief description on how to use the CCID Gadget Device.
This includes a description for all attributes followed by an example on how to setup the device with ConfigFS.

---
 Documentation/usb/gadget_ccid.rst | 267 ++++++++++++++++++++++++++++++++++++++
 1 file changed, 267 insertions(+)
 create mode 100644 Documentation/usb/gadget_ccid.rst
Documentation/usb/gadget_ccid.rst new file +4 -0
new file mode 100644
index 000000000000..5ac806b14604
@@ -0,0 +1,267 @@
+.. SPDX-License-Identifier: GPL-2.0
+
+============
+CCID Gadget

Documentation/usb/gadget_ccid.rst line 14

Quoted 10 lines
Documentation/usb/gadget_ccid.rst new file +10 -0
+============
+
+:Author: Marcus Folkesson <[email protected]>
+
+Introduction
+============
+
+The CCID Gadget will present itself as a CCID device to the host system.
+The device supports two endpoints for now; BULK IN and BULK OUT.
+These endpoints is exposed to userspace via /dev/ccidg*.

are exposed

Quoted 4 lines
Documentation/usb/gadget_ccid.rst new file +4 -0
+
+All CCID commands are sent on the BULK-OUT endpoint. Each command sent to the CCID
+has an associated ending response. Some commands can also have intermediate
+responses. The response is sent on the BULK-IN endpoint.

Documentation/usb/gadget_ccid.rst line 28

Quoted 10 lines
Documentation/usb/gadget_ccid.rst new file +10 -0
+See Figure 3-3 in the CCID Specification [1]_ for more details.
+
+The CCID commands must be handled in userspace since the driver is only working
+as a transport layer for the TPDUs.
+
+
+CCID Commands
+--------------
+
+All CCID commands begins with a 10 bytes header followed by an optional

with a 10-byte header
(or maybe that's a locale difference)

Quoted 19 lines
Documentation/usb/gadget_ccid.rst new file +19 -0
+data field depending on message type.
+
++--------+--------------+-------+----------------------------------+
+| Offset | Field        | Size  | Description                      |
++========+==============+=======+==================================+
+| 0      | bMessageType | 1     | Type of message                  |
++--------+--------------+-------+----------------------------------+
+| 1      | dwLength     | 4     | Message specific data length     |
+|        |              |       |                                  |
++--------+--------------+-------+----------------------------------+
+| 5      | bSlot        | 1     | Identifies the slot number       |
+|        |              |       | for this command                 |
++--------+--------------+-------+----------------------------------+
+| 6      | bSeq         | 1     | Sequence number for command      |
++--------+--------------+-------+----------------------------------+
+| 7      | ...          | 3     | Fields depends on message type   |
++--------+--------------+-------+----------------------------------+
+| 10     | abData       | array | Message specific data (OPTIONAL) |
++--------+--------------+-------+----------------------------------+

Documentation/usb/gadget_ccid.rst line 57

Quoted 10 lines
Documentation/usb/gadget_ccid.rst new file +10 -0
+
+
+Multiple CCID gadgets
+----------------------
+
+It is possible to create multiple instances of the CCID gadget, however,
+a much more flexible way is to create one gadget and set the `nslots` attribute
+to the number of desired CCID devices.
+
+All CCID commands specifies which slot that is the receiver in the `bSlot` field

specify which slot is the receiver

Documentation/usb/gadget_ccid.rst line 66

Quoted 9 lines
Documentation/usb/gadget_ccid.rst new file +9 -0
+of the CCID header.
+
+Usage
+=====
+
+Access from userspace
+----------------------
+All communication is by read(2) and write(2) to the corresponding /dev/ccidg* device.
+Only one filedescriptor is allowed to be open to the device at a time.

file descriptor

Quoted 6 lines
Documentation/usb/gadget_ccid.rst new file +6 -0
+
+The buffer size provided to read(2) **must be at least** 522 (10 bytes header + 512 bytes payload)
+bytes as we are working with whole commands.
+
+The buffer size provided to write(2) **may not exceed** 522 (10 bytes header + 512 bytes payload)
+bytes as we are working with whole commands.

Documentation/usb/gadget_ccid.rst line 82

Quoted 10 lines
Documentation/usb/gadget_ccid.rst new file +10 -0
+
+
+Configuration with configfs
+----------------------------
+
+ConfigFS is used to create and configure the CCID gadget.
+In order to get a device to work as intended, a few attributes must
+be considered.
+
+The attributes is described below followed by an example.

are

Documentation/usb/gadget_ccid.rst line 91

Quoted 9 lines
Documentation/usb/gadget_ccid.rst new file +9 -0
+
+features
+~~~~~~~~~
+
+The `feature` attribute writes to the dwFeatures field in the class descriptor.
+See Table 5.1-1 Smart Card Device Descriptors in the CCID Specification [1]_.
+
+The value indicates what intelligent features the CCID has.
+These values are available to user application as defines in ccid.h [2]_.

as defined

Documentation/usb/gadget_ccid.rst line 92

Quoted 1 line
Documentation/usb/gadget_ccid.rst new file +1 -0
+The default value is 0x00000000.

[snip]

HTH.

#3 lore raw

Re: [PATCH v2 2/3] Documentation: usb: add documentation for USB CCID Gadget Device

Hi Randy,

Quoted 132 lines · Randy Dunlap

Hi,

I have a few documentation comments below...

Quoted 21 lines · Marcus Folkesson

Add documentation to give a brief description on how to use the CCID Gadget Device.
This includes a description for all attributes followed by an example on how to setup the device with ConfigFS.

---
 Documentation/usb/gadget_ccid.rst | 267 ++++++++++++++++++++++++++++++++++++++
 1 file changed, 267 insertions(+)
 create mode 100644 Documentation/usb/gadget_ccid.rst
Documentation/usb/gadget_ccid.rst new file +4 -0
new file mode 100644
index 000000000000..5ac806b14604
@@ -0,0 +1,267 @@
+.. SPDX-License-Identifier: GPL-2.0
+
+============
+CCID Gadget

Documentation/usb/gadget_ccid.rst line 14

Quoted 10 lines
Documentation/usb/gadget_ccid.rst new file +10 -0
+============
+
+:Author: Marcus Folkesson <[email protected]>
+
+Introduction
+============
+
+The CCID Gadget will present itself as a CCID device to the host system.
+The device supports two endpoints for now; BULK IN and BULK OUT.
+These endpoints is exposed to userspace via /dev/ccidg*.

are exposed

Quoted 4 lines
Documentation/usb/gadget_ccid.rst new file +4 -0
+
+All CCID commands are sent on the BULK-OUT endpoint. Each command sent to the CCID
+has an associated ending response. Some commands can also have intermediate
+responses. The response is sent on the BULK-IN endpoint.

Documentation/usb/gadget_ccid.rst line 28

Quoted 10 lines
Documentation/usb/gadget_ccid.rst new file +10 -0
+See Figure 3-3 in the CCID Specification [1]_ for more details.
+
+The CCID commands must be handled in userspace since the driver is only working
+as a transport layer for the TPDUs.
+
+
+CCID Commands
+--------------
+
+All CCID commands begins with a 10 bytes header followed by an optional

with a 10-byte header
(or maybe that's a locale difference)

Quoted 19 lines
Documentation/usb/gadget_ccid.rst new file +19 -0
+data field depending on message type.
+
++--------+--------------+-------+----------------------------------+
+| Offset | Field        | Size  | Description                      |
++========+==============+=======+==================================+
+| 0      | bMessageType | 1     | Type of message                  |
++--------+--------------+-------+----------------------------------+
+| 1      | dwLength     | 4     | Message specific data length     |
+|        |              |       |                                  |
++--------+--------------+-------+----------------------------------+
+| 5      | bSlot        | 1     | Identifies the slot number       |
+|        |              |       | for this command                 |
++--------+--------------+-------+----------------------------------+
+| 6      | bSeq         | 1     | Sequence number for command      |
++--------+--------------+-------+----------------------------------+
+| 7      | ...          | 3     | Fields depends on message type   |
++--------+--------------+-------+----------------------------------+
+| 10     | abData       | array | Message specific data (OPTIONAL) |
++--------+--------------+-------+----------------------------------+

Documentation/usb/gadget_ccid.rst line 57

Quoted 10 lines
Documentation/usb/gadget_ccid.rst new file +10 -0
+
+
+Multiple CCID gadgets
+----------------------
+
+It is possible to create multiple instances of the CCID gadget, however,
+a much more flexible way is to create one gadget and set the `nslots` attribute
+to the number of desired CCID devices.
+
+All CCID commands specifies which slot that is the receiver in the `bSlot` field

specify which slot is the receiver

Documentation/usb/gadget_ccid.rst line 66

Quoted 9 lines
Documentation/usb/gadget_ccid.rst new file +9 -0
+of the CCID header.
+
+Usage
+=====
+
+Access from userspace
+----------------------
+All communication is by read(2) and write(2) to the corresponding /dev/ccidg* device.
+Only one filedescriptor is allowed to be open to the device at a time.

file descriptor

Quoted 6 lines
Documentation/usb/gadget_ccid.rst new file +6 -0
+
+The buffer size provided to read(2) **must be at least** 522 (10 bytes header + 512 bytes payload)
+bytes as we are working with whole commands.
+
+The buffer size provided to write(2) **may not exceed** 522 (10 bytes header + 512 bytes payload)
+bytes as we are working with whole commands.

Documentation/usb/gadget_ccid.rst line 82

Quoted 10 lines
Documentation/usb/gadget_ccid.rst new file +10 -0
+
+
+Configuration with configfs
+----------------------------
+
+ConfigFS is used to create and configure the CCID gadget.
+In order to get a device to work as intended, a few attributes must
+be considered.
+
+The attributes is described below followed by an example.

are

Documentation/usb/gadget_ccid.rst line 91

Quoted 9 lines
Documentation/usb/gadget_ccid.rst new file +9 -0
+
+features
+~~~~~~~~~
+
+The `feature` attribute writes to the dwFeatures field in the class descriptor.
+See Table 5.1-1 Smart Card Device Descriptors in the CCID Specification [1]_.
+
+The value indicates what intelligent features the CCID has.
+These values are available to user application as defines in ccid.h [2]_.

as defined

Quoted 8 lines

Documentation/usb/gadget_ccid.rst line 92

Quoted 1 line
Documentation/usb/gadget_ccid.rst new file +1 -0
+The default value is 0x00000000.

[snip]

HTH.

Signature · 1 line
~Randy

Thank you for your comments, I will take it with me for v3.

Best regards
Marcus Folkesson
---
To unsubscribe from this list: send the line "unsubscribe linux-usb" in the body of a message to [email protected]
More majordomo info at http://vger.kernel.org/majordomo-info.html

#4 lore raw

PATCH v2 3/3 MAINTAINERS: add USB CCID Gadget Device

In reply to Marcus Folkesson

Add MAINTAINERS entry for USB CCID Gadget Device

---
 MAINTAINERS | 8 ++++++++
 1 file changed, 8 insertions(+)
MAINTAINERS +8 -0
index 078fd80f664f..e77c3d2bec89 100644
@@ -14541,6 +14541,14 @@ L:	[email protected]
 S:	Maintained
 F:	drivers/usb/storage/uas.c
 
+USB CCID GADGET
+M:	Marcus Folkesson <[email protected]>
+L:	[email protected]
+S:	Maintained
+F:	drivers/usb/gadget/function/f_ccid.*
+F:	include/uapi/linux/usb/ccid.h
+F:	Documentation/usb/gadget_ccid.rst
+
 USB CDC ETHERNET DRIVER
 M:	Oliver Neukum <[email protected]>
 L:	[email protected]
#5 lore raw
In reply to Marcus Folkesson

Mi Marcus,

W dniu 26.05.2018 o 23:19, Marcus Folkesson pisze:

Quoted 16 lines

Chip Card Interface Device (CCID) protocol is a USB protocol that allows a smartcard device to be connected to a computer via a card reader using a standard USB interface, without the need for each manufacturer of smartcards to provide its own reader or protocol.

This gadget driver makes Linux show up as a CCID device to the host and let a userspace daemon act as the smartcard.

This is useful when the Linux gadget itself should act as a cryptographic device or forward APDUs to an embedded smartcard device.

---

drivers/usb/gadget/Kconfig +1 -0
+config USB_CONFIGFS_CCID

drivers/usb/gadget/Kconfig config USB_CONFIGFS_ACM · line 264

Quoted 10 lines
drivers/usb/gadget/Kconfig +10 -0
+	bool "Chip Card Interface Device (CCID)"
+	depends on USB_CONFIGFS
+	select USB_F_CCID
+	help
+	  The CCID function driver provides generic emulation of a
+	  Chip Card Interface Device (CCID).
+
+	  You will need a user space server talking to /dev/ccidg*,
+	  since the kernel itself does not implement CCID/TPDU/APDU
+	  protocol.

Your function needs a userspace daemon to work. It seems you want to use FunctionFS for such a purpose instead of creating a new function.

Andrzej
---
To unsubscribe from this list: send the line "unsubscribe linux-usb" in the body of a message to [email protected]
More majordomo info at http://vger.kernel.org/majordomo-info.html

#6 lore raw

Hi Andrzej,

Quoted 34 lines · Andrzej Pietrasiewicz

Mi Marcus,

W dniu 26.05.2018 o 23:19, Marcus Folkesson pisze:

Quoted 16 lines

Chip Card Interface Device (CCID) protocol is a USB protocol that allows a smartcard device to be connected to a computer via a card reader using a standard USB interface, without the need for each manufacturer of smartcards to provide its own reader or protocol.

This gadget driver makes Linux show up as a CCID device to the host and let a userspace daemon act as the smartcard.

This is useful when the Linux gadget itself should act as a cryptographic device or forward APDUs to an embedded smartcard device.

---

drivers/usb/gadget/Kconfig +1 -0
+config USB_CONFIGFS_CCID

drivers/usb/gadget/Kconfig config USB_CONFIGFS_ACM · line 264

Quoted 10 lines
drivers/usb/gadget/Kconfig +10 -0
+	bool "Chip Card Interface Device (CCID)"
+	depends on USB_CONFIGFS
+	select USB_F_CCID
+	help
+	  The CCID function driver provides generic emulation of a
+	  Chip Card Interface Device (CCID).
+
+	  You will need a user space server talking to /dev/ccidg*,
+	  since the kernel itself does not implement CCID/TPDU/APDU
+	  protocol.

Your function needs a userspace daemon to work. It seems you want to use FunctionFS for such a purpose instead of creating a new function.

Quoted 3 lines

Andrzej

drivers/usb/gadget/Kconfig config USB_CONFIGFS_ACM · line 263

Quoted 1 line
drivers/usb/gadget/Kconfig +1 -0
+	  since the kernel itself does not implement CCID/TPDU/APDU

Oops, the driver does handle CCID.

Well, yes, It needs an application that perform the "smartcard operations", such as generate keys or sign data, as this depends on how it should be used.

The actual smartcard operations could for example be in software, use a crypto engine in SoC or external HSM (Hardware Security Module).

Without the application, the gadget shows up as a smart card reader with an unconnected smartcard.

I guess it could be accomplished with FunctionFS as well.

Best regards
Marcus Folkesson
---
To unsubscribe from this list: send the line "unsubscribe linux-usb" in the body of a message to [email protected]
More majordomo info at http://vger.kernel.org/majordomo-info.html

#7 lore raw

W dniu 28.05.2018 o 10:38, Marcus Folkesson pisze:

Quoted 37 lines

Hi Andrzej,

Quoted 34 lines · Andrzej Pietrasiewicz

Mi Marcus,

W dniu 26.05.2018 o 23:19, Marcus Folkesson pisze:

Quoted 16 lines

Chip Card Interface Device (CCID) protocol is a USB protocol that allows a smartcard device to be connected to a computer via a card reader using a standard USB interface, without the need for each manufacturer of smartcards to provide its own reader or protocol.

This gadget driver makes Linux show up as a CCID device to the host and let a userspace daemon act as the smartcard.

This is useful when the Linux gadget itself should act as a cryptographic device or forward APDUs to an embedded smartcard device.

---

drivers/usb/gadget/Kconfig +1 -0
+config USB_CONFIGFS_CCID

drivers/usb/gadget/Kconfig config USB_CONFIGFS_ACM · line 264

Quoted 10 lines
drivers/usb/gadget/Kconfig +10 -0
+	bool "Chip Card Interface Device (CCID)"
+	depends on USB_CONFIGFS
+	select USB_F_CCID
+	help
+	  The CCID function driver provides generic emulation of a
+	  Chip Card Interface Device (CCID).
+
+	  You will need a user space server talking to /dev/ccidg*,
+	  since the kernel itself does not implement CCID/TPDU/APDU
+	  protocol.

Your function needs a userspace daemon to work. It seems you want to use FunctionFS for such a purpose instead of creating a new function.

Quoted 4 lines
Quoted 3 lines

Andrzej

drivers/usb/gadget/Kconfig config USB_CONFIGFS_ACM · line 263

Quoted 1 line
drivers/usb/gadget/Kconfig +1 -0
+	  since the kernel itself does not implement CCID/TPDU/APDU

Oops, the driver does handle CCID.

Which parts of code do this handling?

Is there any kind of state machine usual for protocols? If the protocol is stateless then isn't it just a data format then?

Which part of this handling must be done in kernel and why?

Does the said handling do anything other than forwarding the traffic between USB and a character device?

What is the character device used for? I know: read, write and poll. But why? To do what?

Quoted 10 lines

Well, yes, It needs an application that perform the "smartcard operations", such as generate keys or sign data, as this depends on how it should be used.

The actual smartcard operations could for example be in software, use a crypto engine in SoC or external HSM (Hardware Security Module).

Without the application, the gadget shows up as a smart card reader with an unconnected smartcard.

Does showing up as anything require anything other than merely providing USB descriptors?

Andrzej
---
To unsubscribe from this list: send the line "unsubscribe linux-usb" in the body of a message to [email protected]
More majordomo info at http://vger.kernel.org/majordomo-info.html

#8 lore raw

Hi Andrzej,

Thank you for reviewing.

Quoted 38 lines · Andrzej Pietrasiewicz

W dniu 28.05.2018 o 10:38, Marcus Folkesson pisze:

Quoted 37 lines

Hi Andrzej,

Quoted 34 lines · Andrzej Pietrasiewicz

Mi Marcus,

W dniu 26.05.2018 o 23:19, Marcus Folkesson pisze:

Quoted 16 lines

Chip Card Interface Device (CCID) protocol is a USB protocol that allows a smartcard device to be connected to a computer via a card reader using a standard USB interface, without the need for each manufacturer of smartcards to provide its own reader or protocol.

This gadget driver makes Linux show up as a CCID device to the host and let a userspace daemon act as the smartcard.

This is useful when the Linux gadget itself should act as a cryptographic device or forward APDUs to an embedded smartcard device.

---

drivers/usb/gadget/Kconfig +1 -0
+config USB_CONFIGFS_CCID

drivers/usb/gadget/Kconfig config USB_CONFIGFS_ACM · line 264

Quoted 10 lines
drivers/usb/gadget/Kconfig +10 -0
+	bool "Chip Card Interface Device (CCID)"
+	depends on USB_CONFIGFS
+	select USB_F_CCID
+	help
+	  The CCID function driver provides generic emulation of a
+	  Chip Card Interface Device (CCID).
+
+	  You will need a user space server talking to /dev/ccidg*,
+	  since the kernel itself does not implement CCID/TPDU/APDU
+	  protocol.

Your function needs a userspace daemon to work. It seems you want to use FunctionFS for such a purpose instead of creating a new function.

Quoted 6 lines
Quoted 4 lines
Quoted 3 lines

Andrzej

drivers/usb/gadget/Kconfig config USB_CONFIGFS_ACM · line 263

Quoted 1 line
drivers/usb/gadget/Kconfig +1 -0
+	  since the kernel itself does not implement CCID/TPDU/APDU

Oops, the driver does handle CCID.

Which parts of code do this handling?

My bad, I was thinking about the USB descriptors and endpoints setup. That is of cause not part of the CCID protocol.

Quoted 3 lines

Is there any kind of state machine usual for protocols? If the protocol is stateless then isn't it just a data format then?

The protocol is stateless.

Quoted 5 lines

Which part of this handling must be done in kernel and why?

Does the said handling do anything other than forwarding the traffic between USB and a character device?

No, it forward the CCID messages to the character device to be handled by the application.

Quoted 3 lines

What is the character device used for? I know: read, write and poll. But why? To do what?

It is used for the application to fetch, interpret and then perform actions depending on commands.

Quoted 8 lines
Quoted 8 lines

Well, yes, It needs an application that perform the "smartcard operations", such as generate keys or sign data, as this depends on how it should be used.

The actual smartcard operations could for example be in software, use a crypto engine in SoC or external HSM (Hardware Security Module).

Quoted 6 lines
Quoted 3 lines

Without the application, the gadget shows up as a smart card reader with an unconnected smartcard.

Does showing up as anything require anything other than merely providing USB descriptors?

I guess.

Quoted 2 lines

Andrzej

Thank you,
Marcus
---
To unsubscribe from this list: send the line "unsubscribe linux-usb" in the body of a message to [email protected]
More majordomo info at http://vger.kernel.org/majordomo-info.html

#9 lore raw

W dniu 28.05.2018 o 11:32, Marcus Folkesson pisze:

Quoted 60 lines

Hi Andrzej,

Thank you for reviewing.

Quoted 38 lines · Andrzej Pietrasiewicz

W dniu 28.05.2018 o 10:38, Marcus Folkesson pisze:

Quoted 37 lines

Hi Andrzej,

Quoted 34 lines · Andrzej Pietrasiewicz

Mi Marcus,

W dniu 26.05.2018 o 23:19, Marcus Folkesson pisze:

Quoted 16 lines

Chip Card Interface Device (CCID) protocol is a USB protocol that allows a smartcard device to be connected to a computer via a card reader using a standard USB interface, without the need for each manufacturer of smartcards to provide its own reader or protocol.

This gadget driver makes Linux show up as a CCID device to the host and let a userspace daemon act as the smartcard.

This is useful when the Linux gadget itself should act as a cryptographic device or forward APDUs to an embedded smartcard device.

---

drivers/usb/gadget/Kconfig +1 -0
+config USB_CONFIGFS_CCID

drivers/usb/gadget/Kconfig config USB_CONFIGFS_ACM · line 264

Quoted 10 lines
drivers/usb/gadget/Kconfig +10 -0
+	bool "Chip Card Interface Device (CCID)"
+	depends on USB_CONFIGFS
+	select USB_F_CCID
+	help
+	  The CCID function driver provides generic emulation of a
+	  Chip Card Interface Device (CCID).
+
+	  You will need a user space server talking to /dev/ccidg*,
+	  since the kernel itself does not implement CCID/TPDU/APDU
+	  protocol.

Your function needs a userspace daemon to work. It seems you want to use FunctionFS for such a purpose instead of creating a new function.

Quoted 6 lines
Quoted 4 lines
Quoted 3 lines

Andrzej

drivers/usb/gadget/Kconfig config USB_CONFIGFS_ACM · line 263

Quoted 1 line
drivers/usb/gadget/Kconfig +1 -0
+	  since the kernel itself does not implement CCID/TPDU/APDU

Oops, the driver does handle CCID.

Which parts of code do this handling?

My bad, I was thinking about the USB descriptors and endpoints setup. That is of cause not part of the CCID protocol.

Quoted 3 lines

Is there any kind of state machine usual for protocols? If the protocol is stateless then isn't it just a data format then?

The protocol is stateless.

Quoted 1 line
Quoted 9 lines
Quoted 4 lines

Which part of this handling must be done in kernel and why?

Does the said handling do anything other than forwarding the traffic between USB and a character device?

No, it forward the CCID messages to the character device to be handled by the application.

Quoted 1 line

My opinion is: this wants to be done with FunctionFS.

Andrzej
---
To unsubscribe from this list: send the line "unsubscribe linux-usb" in the body of a message to [email protected]
More majordomo info at http://vger.kernel.org/majordomo-info.html

#10 lore raw
In reply to Marcus Folkesson
Thank you for the patch! Perhaps something to improve:

Hi Marcus,

Thank you for the patch! Perhaps something to improve:

[auto build test WARNING on balbi-usb/next]
[also build test WARNING on v4.17-rc7]
[if your patch is applied to the wrong git tree, please drop us a note to help improve the system]

url:    https://github.com/0day-ci/linux/commits/Marcus-Folkesson/usb-gadget-ccid-add-support-for-USB-CCID-Gadget-Device/20180529-014427
base:   https://git.kernel.org/pub/scm/linux/kernel/git/balbi/usb.git next
config: s390-allyesconfig (attached as .config)
compiler: s390x-linux-gnu-gcc (Debian 7.2.0-11) 7.2.0

reproduce:
wget https://raw.githubusercontent.com/intel/lkp-tests/master/sbin/make.cross -O ~/bin/make.cross chmod +x ~/bin/make.cross
# save the attached .config to linux build tree
make.cross ARCH=s390

All warnings (new ones prefixed by >>):

In file included from include/linux/printk.h:332:0,
from include/linux/kernel.h:14,
from include/linux/list.h:9,
from include/linux/kobject.h:19,
from include/linux/cdev.h:5,
from drivers/usb/gadget/function/f_ccid.c:8:
drivers/usb/gadget/function/f_ccid.c: In function 'ccidg_bulk_read':

>> drivers/usb/gadget/function/f_ccid.c:612:5: warning: format '%i' expects argument of type 'int', but argument 4 has type 'size_t {aka long unsigned int}' [-Wformat=]
        "ccid: too small buffer size. %i provided, need at least %i\n",
        ^
   include/linux/dynamic_debug.h:135:39: note: in definition of macro 'dynamic_dev_dbg'
      __dynamic_dev_dbg(&descriptor, dev, fmt, \
                                          ^~~
>> include/linux/usb/composite.h:632:2: note: in expansion of macro 'dev_dbg'
     dev_dbg(&(d)->gadget->dev , fmt , ## args)
     ^~~~~~~
>> drivers/usb/gadget/function/f_ccid.c:611:3: note: in expansion of macro 'DBG'
      DBG(ccidg->function.config->cdev,
      ^~~
>> drivers/usb/gadget/function/f_ccid.c:612:5: warning: format '%i' expects argument of type 'int', but argument 5 has type 'long unsigned int' [-Wformat=]
        "ccid: too small buffer size. %i provided, need at least %i\n",
        ^
   include/linux/dynamic_debug.h:135:39: note: in definition of macro 'dynamic_dev_dbg'
      __dynamic_dev_dbg(&descriptor, dev, fmt, \
                                          ^~~
>> include/linux/usb/composite.h:632:2: note: in expansion of macro 'dev_dbg'
     dev_dbg(&(d)->gadget->dev , fmt , ## args)
     ^~~~~~~
>> drivers/usb/gadget/function/f_ccid.c:611:3: note: in expansion of macro 'DBG'
      DBG(ccidg->function.config->cdev,
      ^~~
   drivers/usb/gadget/function/f_ccid.c: In function 'ccidg_bulk_write':
   drivers/usb/gadget/function/f_ccid.c:683:5: warning: format '%i' expects argument of type 'int', but argument 4 has type 'size_t {aka long unsigned int}' [-Wformat=]
        "ccid: too much data. %i provided, but we can only handle %i\n",
        ^
   include/linux/dynamic_debug.h:135:39: note: in definition of macro 'dynamic_dev_dbg'
      __dynamic_dev_dbg(&descriptor, dev, fmt, \
                                          ^~~
>> include/linux/usb/composite.h:632:2: note: in expansion of macro 'dev_dbg'
     dev_dbg(&(d)->gadget->dev , fmt , ## args)
     ^~~~~~~
   drivers/usb/gadget/function/f_ccid.c:682:3: note: in expansion of macro 'DBG'
      DBG(ccidg->function.config->cdev,
      ^~~
   drivers/usb/gadget/function/f_ccid.c:683:5: warning: format '%i' expects argument of type 'int', but argument 5 has type 'long unsigned int' [-Wformat=]
        "ccid: too much data. %i provided, but we can only handle %i\n",
        ^
   include/linux/dynamic_debug.h:135:39: note: in definition of macro 'dynamic_dev_dbg'
      __dynamic_dev_dbg(&descriptor, dev, fmt, \
                                          ^~~
>> include/linux/usb/composite.h:632:2: note: in expansion of macro 'dev_dbg'
     dev_dbg(&(d)->gadget->dev , fmt , ## args)
     ^~~~~~~
   drivers/usb/gadget/function/f_ccid.c:682:3: note: in expansion of macro 'DBG'
      DBG(ccidg->function.config->cdev,
      ^~~

---
In file included from include/linux/printk.h:332:0,
from include/linux/kernel.h:14,
from include/linux/list.h:9,
from include/linux/kobject.h:19,
from include/linux/cdev.h:5,
from drivers/usb//gadget/function/f_ccid.c:8:
drivers/usb//gadget/function/f_ccid.c: In function 'ccidg_bulk_read':
drivers/usb//gadget/function/f_ccid.c:612:5: warning: format '%i' expects argument of type 'int', but argument 4 has type 'size_t {aka long unsigned int}' [-Wformat=]
"ccid: too small buffer size. %i provided, need at least %i\n",
^
include/linux/dynamic_debug.h:135:39: note: in definition of macro 'dynamic_dev_dbg'

      __dynamic_dev_dbg(&descriptor, dev, fmt, \
                                          ^~~
>> include/linux/usb/composite.h:632:2: note: in expansion of macro 'dev_dbg'
     dev_dbg(&(d)->gadget->dev , fmt , ## args)
     ^~~~~~~
   drivers/usb//gadget/function/f_ccid.c:611:3: note: in expansion of macro 'DBG'
      DBG(ccidg->function.config->cdev,
      ^~~
   drivers/usb//gadget/function/f_ccid.c:612:5: warning: format '%i' expects argument of type 'int', but argument 5 has type 'long unsigned int' [-Wformat=]
        "ccid: too small buffer size. %i provided, need at least %i\n",
        ^
   include/linux/dynamic_debug.h:135:39: note: in definition of macro 'dynamic_dev_dbg'
      __dynamic_dev_dbg(&descriptor, dev, fmt, \
                                          ^~~
>> include/linux/usb/composite.h:632:2: note: in expansion of macro 'dev_dbg'
     dev_dbg(&(d)->gadget->dev , fmt , ## args)
     ^~~~~~~
   drivers/usb//gadget/function/f_ccid.c:611:3: note: in expansion of macro 'DBG'
      DBG(ccidg->function.config->cdev,
      ^~~
   drivers/usb//gadget/function/f_ccid.c: In function 'ccidg_bulk_write':
   drivers/usb//gadget/function/f_ccid.c:683:5: warning: format '%i' expects argument of type 'int', but argument 4 has type 'size_t {aka long unsigned int}' [-Wformat=]
        "ccid: too much data. %i provided, but we can only handle %i\n",
        ^
   include/linux/dynamic_debug.h:135:39: note: in definition of macro 'dynamic_dev_dbg'
      __dynamic_dev_dbg(&descriptor, dev, fmt, \
                                          ^~~
>> include/linux/usb/composite.h:632:2: note: in expansion of macro 'dev_dbg'
     dev_dbg(&(d)->gadget->dev , fmt , ## args)
     ^~~~~~~
   drivers/usb//gadget/function/f_ccid.c:682:3: note: in expansion of macro 'DBG'
      DBG(ccidg->function.config->cdev,
      ^~~
   drivers/usb//gadget/function/f_ccid.c:683:5: warning: format '%i' expects argument of type 'int', but argument 5 has type 'long unsigned int' [-Wformat=]
        "ccid: too much data. %i provided, but we can only handle %i\n",
        ^
   include/linux/dynamic_debug.h:135:39: note: in definition of macro 'dynamic_dev_dbg'
      __dynamic_dev_dbg(&descriptor, dev, fmt, \
                                          ^~~
>> include/linux/usb/composite.h:632:2: note: in expansion of macro 'dev_dbg'
     dev_dbg(&(d)->gadget->dev , fmt , ## args)
     ^~~~~~~
   drivers/usb//gadget/function/f_ccid.c:682:3: note: in expansion of macro 'DBG'
      DBG(ccidg->function.config->cdev,
      ^~~

vim +612 drivers/usb/gadget/function/f_ccid.c

599
600 static ssize_t ccidg_bulk_read(struct file *file, char __user *buf,
601 size_t count, loff_t *pos)
602 {
603 struct f_ccidg *ccidg = file->private_data;
604 struct ccidg_bulk_dev *bulk_dev = &ccidg->bulk_dev;
605 struct usb_request *req;
606 int r = count, xfer;
607 int ret;
608
609 /* Make sure we have enough space for a whole package */
610 if (count < sizeof(struct ccidg_bulk_out_header)) {

 > 611			DBG(ccidg->function.config->cdev,
 > 612					"ccid: too small buffer size. %i provided, need at least %i\n",

613 count, sizeof(struct ccidg_bulk_out_header));
614 return -ENOMEM;
615 }
616
617 if (!atomic_read(&ccidg->online))
618 return -ENODEV;
619
620 /* queue a request */
621 req = bulk_dev->rx_req;
622 req->length = count;
623 atomic_set(&bulk_dev->rx_done, 0);
624
625 ret = usb_ep_queue(ccidg->out, req, GFP_KERNEL);
626 if (ret < 0) {
627 ERROR(ccidg->function.config->cdev,
628 "ccid: usb ep queue failed\n");
629 return -EIO;
630 }
631
632 if (!atomic_read(&bulk_dev->rx_done) &&
633 file->f_flags & (O_NONBLOCK | O_NDELAY))
634 return -EAGAIN;
635
636 /* wait for a request to complete */
637 ret = wait_event_interruptible(bulk_dev->read_wq,
638 atomic_read(&bulk_dev->rx_done) ||
639 !atomic_read(&ccidg->online));
640 if (ret < 0) {
641 usb_ep_dequeue(ccidg->out, req);
642 return -ERESTARTSYS;
643 }
644
645 /* Still online? */
646 if (!atomic_read(&ccidg->online))
647 return -ENODEV;
648
649 atomic_set(&bulk_dev->rx_req_busy, 1);
650 xfer = (req->actual < count) ? req->actual : count;
651
652 if (copy_to_user(buf, req->buf, xfer))
653 r = -EFAULT;
654
655 atomic_set(&bulk_dev->rx_req_busy, 0);
656 if (!atomic_read(&ccidg->online)) {
657 ccidg_request_free(bulk_dev->rx_req, ccidg->out);
658 return -ENODEV;
659 }
660
661 return xfer;
662 }
663

---
0-DAY kernel test infrastructure Open Source Technology Center
https://lists.01.org/pipermail/kbuild-all Intel Corporation

#11 lore raw

[RFC PATCH] usb: gadget: ccid: ccidg_start_ep() can be static

In reply to Marcus Folkesson
-- To unsubscribe from this list: send the line "unsubscribe linux-usb" in the body of a message to [email protected] More majordomo info at http://vger.kernel.org/majordomo-info.html
Fixes 0760b8dd303b ("usb: gadget: ccid: add support for USB CCID Gadget Device")
---
 f_ccid.c |    2 +-
 1 file changed, 1 insertion(+), 1 deletion(-)

--
To unsubscribe from this list: send the line "unsubscribe linux-usb" in the body of a message to [email protected]
More majordomo info at http://vger.kernel.org/majordomo-info.html

drivers/usb/gadget/function/f_ccid.c +1 -1
index 9ff8615..35b392c 100644
@@ -478,7 +478,7 @@ static void ccidg_function_disable(struct usb_function *f)
 	wake_up(&bulk_dev->read_wq);
 }
 
-int ccidg_start_ep(struct f_ccidg *ccidg, struct usb_function *f,
+static int ccidg_start_ep(struct f_ccidg *ccidg, struct usb_function *f,
 			struct usb_ep *ep)
 {
 	struct usb_composite_dev *cdev = f->config->cdev;
#12 lore raw
In reply to Marcus Folkesson
Thank you for the patch! Perhaps something to improve:

Hi Marcus,

Thank you for the patch! Perhaps something to improve:

[auto build test WARNING on balbi-usb/next]
[also build test WARNING on v4.17-rc7]
[if your patch is applied to the wrong git tree, please drop us a note to help improve the system]

url:    https://github.com/0day-ci/linux/commits/Marcus-Folkesson/usb-gadget-ccid-add-support-for-USB-CCID-Gadget-Device/20180529-014427
base:   https://git.kernel.org/pub/scm/linux/kernel/git/balbi/usb.git next
reproduce:
        # apt-get install sparse
        make ARCH=x86_64 allmodconfig
        make C=1 CF=-D__CHECK_ENDIAN__

sparse warnings: (new ones prefixed by >>)

>> drivers/usb/gadget/function/f_ccid.c:423:43: sparse: incorrect type in assignment (different base types) @@    expected unsigned int [unsigned] [usertype] <noident> @@    got ed int [unsigned] [usertype] <noident> @@
   drivers/usb/gadget/function/f_ccid.c:423:43:    expected unsigned int [unsigned] [usertype] <noident>
   drivers/usb/gadget/function/f_ccid.c:423:43:    got restricted __le32 [usertype] <noident>
>> drivers/usb/gadget/function/f_ccid.c:424:31: sparse: expression using sizeof(void)
   drivers/usb/gadget/function/f_ccid.c:429:43: sparse: incorrect type in assignment (different base types) @@    expected unsigned int [unsigned] [usertype] <noident> @@    got ed int [unsigned] [usertype] <noident> @@
   drivers/usb/gadget/function/f_ccid.c:429:43:    expected unsigned int [unsigned] [usertype] <noident>
   drivers/usb/gadget/function/f_ccid.c:429:43:    got restricted __le32 [usertype] <noident>
   drivers/usb/gadget/function/f_ccid.c:430:31: sparse: expression using sizeof(void)
>> drivers/usb/gadget/function/f_ccid.c:481:5: sparse: symbol 'ccidg_start_ep' was not declared. Should it be static?
>> drivers/usb/gadget/function/f_ccid.c:669:35: sparse: Using plain integer as NULL pointer
>> drivers/usb/gadget/function/f_ccid.c:831:41: sparse: incorrect type in assignment (different base types) @@    expected unsigned int static [unsigned] [addressable] [toplevel] [usertype] dwFeatures @@    got sable] [toplevel] [usertype] dwFeatures @@
   drivers/usb/gadget/function/f_ccid.c:831:41:    expected unsigned int static [unsigned] [addressable] [toplevel] [usertype] dwFeatures
   drivers/usb/gadget/function/f_ccid.c:831:41:    got restricted __le32 [usertype] <noident>
>> drivers/usb/gadget/function/f_ccid.c:833:41: sparse: incorrect type in assignment (different base types) @@    expected unsigned short static [unsigned] [addressable] [toplevel] [assigned] [usertype] wLcdLayout @@    got level] [assigned] [usertype] wLcdLayout @@
   drivers/usb/gadget/function/f_ccid.c:833:41:    expected unsigned short static [unsigned] [addressable] [toplevel] [assigned] [usertype] wLcdLayout
   drivers/usb/gadget/function/f_ccid.c:833:41:    got restricted __le16 [usertype] <noident>
>> drivers/usb/gadget/function/f_ccid.c:835:41: sparse: incorrect type in assignment (different base types) @@    expected unsigned int static [unsigned] [addressable] [toplevel] [assigned] [usertype] dwProtocols @@    got level] [assigned] [usertype] dwProtocols @@
   drivers/usb/gadget/function/f_ccid.c:835:41:    expected unsigned int static [unsigned] [addressable] [toplevel] [assigned] [usertype] dwProtocols
   drivers/usb/gadget/function/f_ccid.c:835:41:    got restricted __le32 [usertype] <noident>
   In file included from include/linux/printk.h:332:0,
                    from include/linux/kernel.h:14,
                    from include/linux/list.h:9,
                    from include/linux/kobject.h:19,
                    from include/linux/cdev.h:5,
                    from drivers/usb/gadget/function/f_ccid.c:8:
   drivers/usb/gadget/function/f_ccid.c: In function 'ccidg_bulk_read':
   drivers/usb/gadget/function/f_ccid.c:612:5: warning: format '%i' expects argument of type 'int', but argument 4 has type 'size_t {aka long unsigned int}' [-Wformat=]
        "ccid: too small buffer size. %i provided, need at least %in",
        ^
   include/linux/dynamic_debug.h:135:39: note: in definition of macro 'dynamic_dev_dbg'
      __dynamic_dev_dbg(&descriptor, dev, fmt, 32-                                       ^~~
   include/linux/usb/composite.h:632:2: note: in expansion of macro 'dev_dbg'
     dev_dbg(&(d)->gadget->dev , fmt , ## args)
     ^~~~~~~
   drivers/usb/gadget/function/f_ccid.c:611:3: note: in expansion of macro 'DBG'
      DBG(ccidg->function.config->cdev,
      ^~~
   drivers/usb/gadget/function/f_ccid.c:612:5: warning: format '%i' expects argument of type 'int', but argument 5 has type 'long unsigned int' [-Wformat=]
        "ccid: too small buffer size. %i provided, need at least %in",
        ^
   include/linux/dynamic_debug.h:135:39: note: in definition of macro 'dynamic_dev_dbg'
      __dynamic_dev_dbg(&descriptor, dev, fmt, 44-                                       ^~~
   include/linux/usb/composite.h:632:2: note: in expansion of macro 'dev_dbg'
     dev_dbg(&(d)->gadget->dev , fmt , ## args)
     ^~~~~~~
   drivers/usb/gadget/function/f_ccid.c:611:3: note: in expansion of macro 'DBG'
      DBG(ccidg->function.config->cdev,
      ^~~
   drivers/usb/gadget/function/f_ccid.c: In function 'ccidg_bulk_write':
   drivers/usb/gadget/function/f_ccid.c:683:5: warning: format '%i' expects argument of type 'int', but argument 4 has type 'size_t {aka long unsigned int}' [-Wformat=]
        "ccid: too much data. %i provided, but we can only handle %in",
        ^
   include/linux/dynamic_debug.h:135:39: note: in definition of macro 'dynamic_dev_dbg'
      __dynamic_dev_dbg(&descriptor, dev, fmt, 57-                                       ^~~
   include/linux/usb/composite.h:632:2: note: in expansion of macro 'dev_dbg'
     dev_dbg(&(d)->gadget->dev , fmt , ## args)
     ^~~~~~~
   drivers/usb/gadget/function/f_ccid.c:682:3: note: in expansion of macro 'DBG'
      DBG(ccidg->function.config->cdev,
      ^~~
   drivers/usb/gadget/function/f_ccid.c:683:5: warning: format '%i' expects argument of type 'int', but argument 5 has type 'long unsigned int' [-Wformat=]
        "ccid: too much data. %i provided, but we can only handle %in",
        ^
   include/linux/dynamic_debug.h:135:39: note: in definition of macro 'dynamic_dev_dbg'
      __dynamic_dev_dbg(&descriptor, dev, fmt, 69-                                       ^~~
   include/linux/usb/composite.h:632:2: note: in expansion of macro 'dev_dbg'
     dev_dbg(&(d)->gadget->dev , fmt , ## args)
     ^~~~~~~
   drivers/usb/gadget/function/f_ccid.c:682:3: note: in expansion of macro 'DBG'
      DBG(ccidg->function.config->cdev,
      ^~~

Please review and possibly fold the followup patch.

vim +423 drivers/usb/gadget/function/f_ccid.c

403
404 static int ccidg_function_setup(struct usb_function *f,
405 const struct usb_ctrlrequest *ctrl)
406 {
407 struct f_ccidg *ccidg = container_of(f, struct f_ccidg, function);
408 struct usb_composite_dev *cdev = f->config->cdev;
409 struct usb_request *req = cdev->req;
410 int ret = -EOPNOTSUPP;
411 u16 w_index = le16_to_cpu(ctrl->wIndex);
412 u16 w_value = le16_to_cpu(ctrl->wValue);
413 u16 w_length = le16_to_cpu(ctrl->wLength);
414
415 if (!atomic_read(&ccidg->online))
416 return -ENOTCONN;
417
418 switch (ctrl->bRequestType & USB_TYPE_MASK) {
419 case USB_TYPE_CLASS:
420 {
421 switch (ctrl->bRequest) {
422 case CCIDGENERICREQ_GET_CLOCK_FREQUENCIES:

 > 423				*(u32 *) req->buf = cpu_to_le32(ccid_class_desc.dwDefaultClock);
 > 424				ret = min_t(u32, w_length,
   425						sizeof(ccid_class_desc.dwDefaultClock));
   426				break;
   427	
   428			case CCIDGENERICREQ_GET_DATA_RATES:
 > 429				*(u32 *) req->buf = cpu_to_le32(ccid_class_desc.dwDataRate);
 > 430				ret = min_t(u32, w_length, sizeof(ccid_class_desc.dwDataRate));
   431				break;
   432	
   433			default:
   434				VDBG(f->config->cdev,
   435					"ccid: invalid control req%02x.%02x v%04x i%04x l%d\n",
   436					ctrl->bRequestType, ctrl->bRequest,
   437					w_value, w_index, w_length);
   438			}
   439			}
   440		}
   441	
   442		/* responded with data transfer or status phase? */
   443		if (ret >= 0) {
   444			VDBG(f->config->cdev, "ccid: req%02x.%02x v%04x i%04x l%d\n",
   445				ctrl->bRequestType, ctrl->bRequest,
   446				w_value, w_index, w_length);
   447	
   448			req->length = ret;
   449			ret = usb_ep_queue(cdev->gadget->ep0, req, GFP_ATOMIC);
   450			if (ret < 0)
   451				ERROR(f->config->cdev,
   452					"ccid: ep0 enqueue err %d\n", ret);
   453		}
   454	
   455		return ret;
   456	}
   457	
   458	static void ccidg_function_disable(struct usb_function *f)
   459	{
   460		struct f_ccidg *ccidg = func_to_ccidg(f);
   461		struct ccidg_bulk_dev *bulk_dev = &ccidg->bulk_dev;
   462		struct usb_request *req;
   463	
   464		/* Disable endpoints */
   465		usb_ep_disable(ccidg->in);
   466		usb_ep_disable(ccidg->out);
   467	
   468		/* Free endpoint related requests */
   469		if (!atomic_read(&bulk_dev->rx_req_busy))
   470			ccidg_request_free(bulk_dev->rx_req, ccidg->out);
   471		while ((req = ccidg_req_get(ccidg, &bulk_dev->tx_idle)))
   472			ccidg_request_free(req, ccidg->in);
   473	
   474		atomic_set(&ccidg->online, 0);
   475	
   476		/* Wake up threads */
   477		wake_up(&bulk_dev->write_wq);
   478		wake_up(&bulk_dev->read_wq);
   479	}
   480	
 > 481	int ccidg_start_ep(struct f_ccidg *ccidg, struct usb_function *f,

482 struct usb_ep *ep)
483 {
484 struct usb_composite_dev *cdev = f->config->cdev;
485 int ret;
486
487 usb_ep_disable(ep);
488
489 ret = config_ep_by_speed(cdev->gadget, f, ep);
490 if (ret) {
491 ERROR(cdev, "ccid: can't configure %s: %d\n", ep->name, ret);
492 return ret;
493 }
494
495 ret = usb_ep_enable(ep);
496 if (ret) {
497 ERROR(cdev, "ccid: can't start %s: %d\n", ep->name, ret);
498 return ret;
499 }
500
501 ep->driver_data = ccidg;
502
503 return ret;
504 }
505
---
0-DAY kernel test infrastructure Open Source Technology Center
https://lists.01.org/pipermail/kbuild-all Intel Corporation
--
To unsubscribe from this list: send the line "unsubscribe linux-usb" in the body of a message to [email protected]
More majordomo info at http://vger.kernel.org/majordomo-info.html