All of lore.kernel.org
 help / color / mirror / Atom feed
From: Johan Hovold <johan@kernel.org>
To: Octavian Purdila <octavian.purdila@intel.com>
Cc: gregkh@linuxfoundation.org, linus.walleij@linaro.org,
	gnurou@gmail.com, wsa@the-dreams.de, sameo@linux.intel.com,
	lee.jones@linaro.org, arnd@arndb.de, johan@kernel.org,
	daniel.baluta@intel.com, laurentiu.palcu@intel.com,
	linux-usb@vger.kernel.org, linux-kernel@vger.kernel.org,
	linux-gpio@vger.kernel.org, linux-i2c@vger.kernel.org
Subject: Re: [PATCH v6 1/4] mfd: add support for Diolan DLN-2 devices
Date: Wed, 8 Oct 2014 11:23:47 +0200	[thread overview]
Message-ID: <20141008092347.GB1990@localhost> (raw)
In-Reply-To: <1411661254-5204-2-git-send-email-octavian.purdila@intel.com>

On Thu, Sep 25, 2014 at 07:07:31PM +0300, Octavian Purdila wrote:

> +static void dln2_rx_transfer(struct dln2_dev *dln2, struct urb *urb,
> +			     u16 handle, u16 rx_slot)
> +{
> +	struct dln2_mod_rx_slots *rxs = &dln2->mod_rx_slots[handle];
> +	struct dln2_rx_context *rxc;
> +	struct device *dev = &dln2->interface->dev;
> +
> +	spin_lock(&rxs->lock);

You must use spin_lock_irqsave here as you call it from the completion
handler.

> +
> +	rxc = &rxs->slots[rx_slot];
> +
> +	if (rxc->in_use && !rxc->urb) {
> +		rxc->urb = urb;
> +		complete(&rxc->done);
> +		/* URB will be resubmitted in free_rx_slot */
> +	} else {
> +		dev_warn(dev, "bad/late response %d/%d\n", handle, rx_slot);
> +		dln2_submit_urb(dln2, urb, GFP_ATOMIC);
> +	}
> +
> +	spin_unlock(&rxs->lock);
> +}

> +static int _dln2_transfer(struct dln2_dev *dln2, u16 handle, u16 cmd,
> +			  const void *obuf, unsigned obuf_len,
> +			  void *ibuf, unsigned *ibuf_len)
> +{
> +	int ret = 0;
> +	u16 result;
> +	int rx_slot;
> +	struct dln2_response *rsp;
> +	struct dln2_rx_context *rxc;
> +	struct device *dev;
> +	const int timeout = DLN2_USB_TIMEOUT * HZ / 1000;
> +	struct dln2_mod_rx_slots *rxs = &dln2->mod_rx_slots[handle];
> +
> +	spin_lock(&dln2->disconnect_lock);

How did you test this version? You never initialise disconnect_lock so
lockdep complains loudly when calling _dln2_transfer during probe.

> +	if (!dln2->disconnect)
> +		dln2->active_transfers++;
> +	else
> +		ret = -ENODEV;
> +	spin_unlock(&dln2->disconnect_lock);
> +
> +	if (ret)
> +		return ret;
> +
> +	rx_slot = alloc_rx_slot(dln2, handle);
> +	if (rx_slot < 0) {
> +		ret = rx_slot;
> +		goto out_decr;
> +	}
> +
> +	dev = &dln2->interface->dev;
> +
> +	ret = dln2_send_wait(dln2, handle, cmd, rx_slot, obuf, obuf_len);
> +	if (ret < 0) {
> +		dev_err(dev, "USB write failed: %d\n", ret);
> +		goto out_free_rx_slot;
> +	}
> +
> +	rxc = &rxs->slots[rx_slot];
> +
> +	ret = wait_for_completion_interruptible_timeout(&rxc->done, timeout);
> +	if (ret <= 0) {
> +		if (!ret)
> +			ret = -ETIMEDOUT;
> +		goto out_free_rx_slot;
> +	}
> +
> +	if (!rxc->urb) {
> +		ret = -ENODEV;
> +		goto out_free_rx_slot;
> +	}
> +
> +	/* if we got here we know that the response header has been checked */
> +	rsp = rxc->urb->transfer_buffer;
> +
> +	if (rsp->hdr.size < sizeof(*rsp)) {
> +		ret = -EPROTO;
> +		goto out_free_rx_slot;
> +	}
> +
> +	result = le16_to_cpu(rsp->result);
> +	if (result) {
> +		dev_dbg(dev, "%d received response with error %d\n",
> +			handle, result);
> +		ret = -EREMOTEIO;
> +		goto out_free_rx_slot;
> +	}
> +
> +	if (!ibuf) {
> +		ret = 0;
> +		goto out_free_rx_slot;
> +	}
> +
> +	if (*ibuf_len > rsp->hdr.size - sizeof(*rsp))
> +		*ibuf_len = rsp->hdr.size - sizeof(*rsp);
> +
> +	memcpy(ibuf, rsp + 1, *ibuf_len);
> +
> +out_free_rx_slot:
> +	free_rx_slot(dln2, handle, rx_slot);
> +out_decr:
> +	spin_lock(&dln2->disconnect_lock);
> +	dln2->active_transfers--;
> +	spin_unlock(&dln2->disconnect_lock);
> +	if (dln2->disconnect)
> +		wake_up(&dln2->disconnect_wq);
> +
> +	return ret;
> +}

> +static void dln2_disconnect(struct usb_interface *interface)
> +{
> +	struct dln2_dev *dln2 = usb_get_intfdata(interface);
> +	int i, j;
> +
> +	/* don't allow starting new transfers */
> +	spin_lock(&dln2->disconnect_lock);
> +	dln2->disconnect = true;
> +	spin_unlock(&dln2->disconnect_lock);
> +
> +	/* cancel in progress transfers */
> +	for (i = 0; i < DLN2_HANDLES; i++) {
> +		struct dln2_mod_rx_slots *rxs = &dln2->mod_rx_slots[i];
> +		unsigned long flags;
> +
> +		spin_lock_irqsave(&rxs->lock, flags);

Just stick to spin_lock in this function.

> +
> +		/* cancel all response waiters */
> +		for (j = 0; j < DLN2_MAX_RX_SLOTS; j++) {
> +			struct dln2_rx_context *rxc = &rxs->slots[j];
> +
> +			if (rxc->in_use)
> +				complete(&rxc->done);
> +		}
> +
> +		spin_unlock_irqrestore(&rxs->lock, flags);
> +	}
> +
> +	/* wait for transfers to end */
> +	wait_event(dln2->disconnect_wq, !dln2->active_transfers);
> +
> +	mfd_remove_devices(&interface->dev);
> +
> +	dln2_free(dln2);
> +}
> +
> +static int dln2_probe(struct usb_interface *interface,
> +		      const struct usb_device_id *usb_id)
> +{
> +	struct usb_host_interface *hostif = interface->cur_altsetting;
> +	struct device *dev = &interface->dev;
> +	struct dln2_dev *dln2;
> +	int ret;
> +	int i, j;
> +	int id;
> +
> +	if (hostif->desc.bInterfaceNumber != 0 ||
> +	    hostif->desc.bNumEndpoints < 2)
> +		return -ENODEV;
> +
> +	dln2 = kzalloc(sizeof(*dln2), GFP_KERNEL);
> +	if (!dln2)
> +		return -ENOMEM;
> +
> +	dln2->ep_out = hostif->endpoint[0].desc.bEndpointAddress;
> +	dln2->ep_in = hostif->endpoint[1].desc.bEndpointAddress;
> +	dln2->usb_dev = usb_get_dev(interface_to_usbdev(interface));
> +	dln2->interface = interface;
> +	usb_set_intfdata(interface, dln2);
> +	init_waitqueue_head(&dln2->disconnect_wq);
> +
> +	for (i = 0; i < DLN2_HANDLES; i++) {
> +		init_waitqueue_head(&dln2->mod_rx_slots[i].wq);
> +		spin_lock_init(&dln2->mod_rx_slots[i].lock);
> +		for (j = 0; j < DLN2_MAX_RX_SLOTS; j++)
> +			init_completion(&dln2->mod_rx_slots[i].slots[j].done);
> +	}
> +
> +	spin_lock_init(&dln2->event_cb_lock);
> +	INIT_LIST_HEAD(&dln2->event_cb_list);

The disconnect_lock is never initialised, as mentioned above.

> +
> +	ret = dln2_setup_rx_urbs(dln2, hostif);
> +	if (ret) {
> +		dln2_free(dln2);
> +		return ret;
> +	}
> +
> +	ret = dln2_hw_init(dln2);
> +	if (ret < 0) {
> +		dev_err(dev, "failed to initialize hardware\n");
> +		goto out_cleanup;
> +	}
> +
> +	id = dln2->usb_dev->bus->busnum << 8 | dln2->usb_dev->devnum;
> +	ret = mfd_add_devices(dev, id, dln2_devs, ARRAY_SIZE(dln2_devs),
> +			      NULL, 0, NULL);
> +	if (ret != 0) {
> +		dev_err(dev, "failed to add mfd devices to core\n");
> +		goto out_cleanup;
> +	}
> +
> +	return 0;
> +
> +out_cleanup:
> +	dln2_free(dln2);
> +
> +	return ret;
> +}
> +
> +static const struct usb_device_id dln2_table[] = {
> +	{ USB_DEVICE(0xa257, 0x2013) },
> +	{ }
> +};
> +
> +MODULE_DEVICE_TABLE(usb, dln2_table);
> +
> +static struct usb_driver dln2_driver = {
> +	.name = "usb-dln2",

Just call the usb driver "dln2". 

> +	.probe = dln2_probe,
> +	.disconnect = dln2_disconnect,
> +	.id_table = dln2_table,
> +};

Johan

  parent reply	other threads:[~2014-10-08  9:26 UTC|newest]

Thread overview: 35+ messages / expand[flat|nested]  mbox.gz  Atom feed  top
2014-09-25 16:07 [PATCH v6 0/4] mfd: add support for Diolan DLN-2 Octavian Purdila
2014-09-25 16:07 ` [PATCH v6 1/4] mfd: add support for Diolan DLN-2 devices Octavian Purdila
     [not found]   ` <1411661254-5204-2-git-send-email-octavian.purdila-ral2JQCrhuEAvxtiuMwx3w@public.gmane.org>
2014-10-03 17:12     ` Johan Hovold
2014-10-03 17:12       ` Johan Hovold
2014-10-06 12:17       ` Octavian Purdila
2014-10-06 12:17         ` Octavian Purdila
2014-10-07 17:10         ` Johan Hovold
2014-10-07 18:01           ` Octavian Purdila
2014-10-07 18:01             ` Octavian Purdila
2014-10-08  9:30             ` Johan Hovold
2014-10-08  9:23   ` Johan Hovold [this message]
2014-10-08 10:54     ` Octavian Purdila
     [not found]       ` <CAE1zotKHq1Fj_AqKzfnBHoypetb6Yz3OsHnqfeHN5PrVJtuHVw-JsoAwUIsXosN+BqQ9rBEUg@public.gmane.org>
2014-10-08 12:04         ` Johan Hovold
2014-10-08 12:04           ` Johan Hovold
2014-10-08 12:33           ` Octavian Purdila
2014-10-08 12:33             ` Octavian Purdila
     [not found]             ` <CAE1zot+muJn5ngxpq8LeF9J+7kZqCiStzvcxLLP0wf08TjWG4A-JsoAwUIsXosN+BqQ9rBEUg@public.gmane.org>
2014-10-09 13:16               ` Johan Hovold
2014-10-09 13:16                 ` Johan Hovold
     [not found] ` <1411661254-5204-1-git-send-email-octavian.purdila-ral2JQCrhuEAvxtiuMwx3w@public.gmane.org>
2014-09-25 16:07   ` [PATCH v6 2/4] i2c: add support for Diolan DLN-2 USB-I2C adapter Octavian Purdila
2014-09-25 16:07     ` Octavian Purdila
     [not found]     ` <1411661254-5204-3-git-send-email-octavian.purdila-ral2JQCrhuEAvxtiuMwx3w@public.gmane.org>
2014-10-03  1:14       ` Wolfram Sang
2014-10-03  1:14         ` Wolfram Sang
2014-10-03 12:30         ` Octavian Purdila
2014-10-03 12:30           ` Octavian Purdila
2014-10-07 16:46       ` Johan Hovold
2014-10-07 16:46         ` Johan Hovold
2014-10-07 17:52         ` Octavian Purdila
     [not found]           ` <CAE1zotKiYGXDbE0yVOz1ROuTxMf_Sfpn-0ghOM1dLEu1oEGZuw-JsoAwUIsXosN+BqQ9rBEUg@public.gmane.org>
2014-10-07 17:55             ` Johan Hovold
2014-10-07 17:55               ` Johan Hovold
2014-10-08 10:42     ` Johan Hovold
2014-10-08 11:07       ` Octavian Purdila
2014-09-25 16:07 ` [PATCH v6 3/4] gpiolib: add irq_not_threaded flag to gpio_chip Octavian Purdila
2014-09-25 16:07 ` [PATCH v6 4/4] gpio: add support for the Diolan DLN-2 USB GPIO driver Octavian Purdila
     [not found]   ` <1411661254-5204-5-git-send-email-octavian.purdila-ral2JQCrhuEAvxtiuMwx3w@public.gmane.org>
2014-10-07 16:56     ` Johan Hovold
2014-10-07 16:56       ` Johan Hovold

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=20141008092347.GB1990@localhost \
    --to=johan@kernel.org \
    --cc=arnd@arndb.de \
    --cc=daniel.baluta@intel.com \
    --cc=gnurou@gmail.com \
    --cc=gregkh@linuxfoundation.org \
    --cc=laurentiu.palcu@intel.com \
    --cc=lee.jones@linaro.org \
    --cc=linus.walleij@linaro.org \
    --cc=linux-gpio@vger.kernel.org \
    --cc=linux-i2c@vger.kernel.org \
    --cc=linux-kernel@vger.kernel.org \
    --cc=linux-usb@vger.kernel.org \
    --cc=octavian.purdila@intel.com \
    --cc=sameo@linux.intel.com \
    --cc=wsa@the-dreams.de \
    /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 an external index of several public inboxes,
see mirroring instructions on how to clone and mirror
all data and code used by this external index.