linux-usb.vger.kernel.org archive mirror
 help / color / mirror / Atom feed
From: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
To: "David R. Bild" <david.bild@xaptum.com>
Cc: Oliver Neukum <oneukum@suse.com>, linux-usb@vger.kernel.org
Subject: [v2,1/2] usb: misc: xapea00x: add driver for Xaptum ENF Access Card
Date: Mon, 30 Apr 2018 09:05:26 -0700	[thread overview]
Message-ID: <20180430160526.GA8479@kroah.com> (raw)

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.bild@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 majordomo@vger.kernel.org
More majordomo info at  http://vger.kernel.org/majordomo-info.html

             reply	other threads:[~2018-04-30 16:05 UTC|newest]

Thread overview: 3+ messages / expand[flat|nested]  mbox.gz  Atom feed  top
2018-04-30 16:05 Greg Kroah-Hartman [this message]
  -- strict thread matches above, loose matches on Subject: below --
2018-05-01 13:30 [v2,1/2] usb: misc: xapea00x: add driver for Xaptum ENF Access Card David R. Bild
2018-04-30 12:54 David R. Bild

Reply instructions:

You may reply publicly to this message via plain-text email
using any one of the following methods:

* Save the following mbox file, import it into your mail client,
  and reply-to-all from there: mbox

  Avoid top-posting and favor interleaved quoting:
  https://en.wikipedia.org/wiki/Posting_style#Interleaved_style

* Reply using the --to, --cc, and --in-reply-to
  switches of git-send-email(1):

  git send-email \
    --in-reply-to=20180430160526.GA8479@kroah.com \
    --to=gregkh@linuxfoundation.org \
    --cc=david.bild@xaptum.com \
    --cc=linux-usb@vger.kernel.org \
    --cc=oneukum@suse.com \
    /path/to/YOUR_REPLY

  https://kernel.org/pub/software/scm/git/docs/git-send-email.html

* If your mail client supports setting the In-Reply-To header
  via mailto: links, try the mailto: link
Be sure your reply has a Subject: header at the top and a blank line before the message body.
This is a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox;
as well as URLs for NNTP newsgroup(s).