On Mon, Apr 30, 2018 at 07:54:17AM -0500, David R. Bild wrote:
> This commit adds a driver for the Xaptum ENF Access Card, a TPM2.0
> hardware module for authenticating IoT devices and gateways.
> 
> The card consists of a SPI TPM 2.0 chip and a USB-SPI bridge. This
> driver configures the bridge, registers the bridge as an SPI
> controller, and adds the TPM 2.0 as an SPI device.  The in-kernel TPM
> 2.0 driver is then automatically loaded to configure the TPM and
> expose it to userspace.

A few random USB driver-like review comments of minor things to tweak
for your next submission.  Overall it looks good to me, but you should
also get the TPM maintainers/developers to review it as I will require
their review before I can take it in the USB tree.

> --- /dev/null
> +++ b/drivers/usb/misc/xapea00x/Kconfig
> @@ -0,0 +1,16 @@
> +config  USB_XAPEA00X
> +        tristate "Xaptum ENF Access card support (XAP-EA-00x)"
> +        depends on USB_SUPPORT
> +        select SPI
> +        select TCG_TPM
> +        select TCG_TIS_SPI

Do you really want to 'select' these?  Why not just depend on them?


> --- /dev/null
> +++ b/drivers/usb/misc/xapea00x/xapea00x-bridge.c
> @@ -0,0 +1,400 @@
> +// SPDX-License-Identifier: GPL-2.0+
> +/*
> + *  Driver for the XAP-EA-00x series of the Xaptum Edge Access Card, a
> + *  TPM 2.0-based hardware module for authenticating IoT devices and
> + *  gateways.
> + *
> + *  Copyright (c) 2017 Xaptum, Inc.

It's 2018 now :)

> + */
> +
> +#include "xapea00x.h"
> +
> +#define XAPEA00X_BR_CMD_READ           0x00
> +#define XAPEA00X_BR_CMD_WRITE                  0x01
> +#define XAPEA00X_BR_CMD_WRITEREAD      0x02
> +
> +#define XAPEA00X_BR_BREQTYP_SET                0x40
> +
> +#define XAPEA00X_BR_BREQ_SET_GPIO_VALUES  0x21
> +#define XAPEA00X_BR_BREQ_SET_GPIO_CS   0x25
> +#define XAPEA00X_BR_BREQ_SET_SPI_WORD          0x31
> +
> +#define XAPEA00X_BR_USB_TIMEOUT                1000 // msecs
> +
> +#define XAPEA00X_BR_CS_DISABLED                0x00

Odd placement of spaces after the tabs, why?


> +
> +/*******************************************************************************
> + * Bridge USB transfers
> + */
> +
> +struct xapea00x_br_bulk_command {
> +     __u16  reserved1;
> +     __u8   command;
> +     __u8   reserved2;
> +     __le32 length;
> +} __attribute__((__packed__));
> +
> +/**
> + * xapea00x_br_prep_bulk_command - Prepares the bulk command header with
> + * the supplied values.
> + * @hdr: pointer to header to prepare
> + * @command: the command id for the command
> + * @length: length in bytes of the command data
> + *
> + * Context: !in_interrupt()
> + *
> + * Return: If successful, 0. Otherwise a negative error number.
> + */

You don't need kerneldoc comments for static functions.  Nice, but not a
requirement at all.

> +static int xapea00x_br_bulk_read(struct xapea00x_device *dev, void *data,
> +                              int len)
> +{
> +     unsigned int pipe;
> +     void *buf;
> +     int actual_len, retval;
> +
> +     buf = kzalloc(len, GFP_KERNEL);
> +     if (!buf) {
> +             retval = -ENOMEM;
> +             goto out;
> +     }
> +
> +     pipe = usb_rcvbulkpipe(dev->udev, dev->bulk_in->bEndpointAddress);
> +     retval = usb_bulk_msg(dev->udev, pipe, buf, len, &actual_len,
> +                           XAPEA00X_BR_USB_TIMEOUT);
> +
> +     if (retval) {
> +             dev_warn(&dev->interface->dev,
> +                      "%s: usb_bulk_msg() failed with %d\n",
> +                      __func__, retval);
> +             goto free_buf;
> +     }

Is this going to get noisy when the device gets removed from the system?

> +
> +     memcpy(data, buf, actual_len);
> +     retval = 0;
> +
> +free_buf:
> +     kzfree(buf);
> +
> +out:
> +     return retval;
> +}
> +
> +/**
> + * xapea00x_br_ctrl_write - Issues a send control transfer to the bridge
> + * chip.
> + * @dev: pointer to the device to write to
> + * @bRequest: the command
> + * @wValue: the command value
> + * @wIndex: the command index
> + * @data: pointer to the command data
> + * @len: length in bytes of the command data
> + *
> + * The possible bRequest, wValue, and wIndex values and data format
> + * are specified in the hardware datasheet.
> + *
> + * Context: !in_interrupt()
> + *
> + * Return: If successful, 0. Otherwise a negative error code.
> + */
> +static int xapea00x_br_ctrl_write(struct xapea00x_device *dev, u8 bRequest,
> +                               u16 wValue, u16 wIndex, u8 *data, u16 len)
> +{
> +     unsigned int pipe;
> +     void *buf;
> +     int retval;
> +
> +     /* control_msg buffer must be dma-capable (e.g.k kmalloc-ed,
> +      * not stack).  Copy data into such buffer here, so we can use
> +      * simpler stack allocation in the callers - we have no
> +      * performance concerns given the small buffers and low
> +      * throughputs of this device.
> +      */

This is well known and a requirement for all USB drivers, no need to
have to document it here :)

> +     /* ---------------------- TPM SPI Device ------------------------ */
> +     probe = kzalloc(sizeof(*probe), GFP_KERNEL);
> +     if (!probe) {
> +             retval = -ENOMEM;
> +             goto free_spi;
> +     }
> +     xapea00x_init_async_probe(probe, dev, xapea00x_tpm_probe);
> +
> +     schedule_work(&probe->work);
> +     dev_info(&interface->dev, "scheduled initialization of TPM\n");

We do not care :)

Drivers should be silent, unless something bad happens.  Please remove
noisy stuff like this, and:

> +     /* ---------------------- Finished ------------------------ */
> +     dev_info(&interface->dev, "device connected\n");

That line.  Not needed at all.

> +     return 0;
> +
> +free_spi:
> +     spi_unregister_master(dev->spi_master);
> +
> +free_dev:
> +     kref_put(&dev->kref, xapea00x_delete);
> +
> +     dev_err(&interface->dev, "device failed with %d\n", retval);
> +     return retval;
> +}
> +
> +static void xapea00x_disconnect(struct usb_interface *interface)
> +{
> +     struct xapea00x_device *dev = usb_get_intfdata(interface);
> +
> +     usb_set_intfdata(interface, NULL);
> +     spi_unregister_master(dev->spi_master);
> +
> +     mutex_lock(&dev->usb_mutex);
> +     dev->interface = NULL;
> +     mutex_unlock(&dev->usb_mutex);
> +
> +     kref_put(&dev->kref, xapea00x_delete);
> +
> +     dev_info(&dev->udev->dev, "device disconnected\n");

No need for that either.

> +}
> +
> +static struct usb_driver xapea00x_driver = {
> +     .name                 = "xapea00x",

KBUILD_MOD_NAME instead?

> +     .probe                = xapea00x_probe,
> +     .disconnect           = xapea00x_disconnect,
> +     .suspend              = NULL,
> +     .resume               = NULL,
> +     .reset_resume         = NULL,

Leave NULL fields alone, no need to even list them here.

> +     .id_table             = xapea00x_devices,
> +     .supports_autosuspend = 0

And drop this, as it's set to 0 by default.

> +};
> +
> +module_usb_driver(xapea00x_driver);
> +
> +MODULE_AUTHOR("David R. Bild <david.b...@xaptum.com>");
> +MODULE_DESCRIPTION("Xaptum XAP-EA-00x ENF Access card");
> +MODULE_LICENSE("GPL");
> +
> +MODULE_ALIAS("xapea00x");

Ick, no, the build system will add the properly MODULE_ALIAS to the
code, do not write it out "by hand" here at all.  Bad things can happen
if you get it wrong.

> +struct xapea00x_device {
> +     struct kref kref;
> +
> +     struct usb_device *udev;
> +     /*
> +      * The interface pointer will be set NULL when the device
> +      * disconnects.  Accessing it safe only while holding the
> +      * usb_mutex.
> +      */
> +     struct usb_interface *interface;
> +     /*
> +      * Th usb_mutex must be held while synchronous USB requests are
> +      * in progress. It is acquired during disconnect to be sure
> +      * that there is not an outstanding request.
> +      */
> +     struct mutex usb_mutex;
> +
> +     struct usb_endpoint_descriptor *bulk_in;
> +     struct usb_endpoint_descriptor *bulk_out;
> +
> +     u16 pid;
> +     u16 vid;

Why do you care about these vid/pid values?  You set them and never use
them.  If you really needed them, you can get them from the pointer to
the interface above.


thanks,

greg k-h
--
To unsubscribe from this list: send the line "unsubscribe linux-usb" in
the body of a message to majord...@vger.kernel.org
More majordomo info at  http://vger.kernel.org/majordomo-info.html

Reply via email to