All of lore.kernel.org
 help / color / mirror / Atom feed
From: Andrew Morton <akpm@linux-foundation.org>
To: Anton Vorontsov <avorontsov@ru.mvista.com>
Cc: dbrownell@users.sourceforge.net, greg@kroah.com,
	linux-usb@vger.kernel.org, linux-kernel@vger.kernel.org,
	linuxppc-dev@ozlabs.org, leoli@freescale.com,
	timur@freescale.com
Subject: Re: [PATCH] USB: Driver for Freescale QUICC Engine USB Host Controller
Date: Tue, 23 Dec 2008 13:28:40 -0800	[thread overview]
Message-ID: <20081223132840.55e7b666.akpm@linux-foundation.org> (raw)
In-Reply-To: <20081223210322.GA2802@oksana.dev.rtsoft.ru>

On Wed, 24 Dec 2008 00:03:22 +0300
Anton Vorontsov <avorontsov@ru.mvista.com> wrote:

> This patch adds support for the FHCI USB controller, as found
> in the Freescale MPC836x and MPC832x processors. It can support
> Full or Low speed modes.
> 
> Quite a lot the hardware is doing by itself (SOF generation, CRC
> generation and checking), though scheduling and retransmission is on
> software's shoulders.
> 
> This controller does not integrate the root hub, so this driver also
> fakes one-port hub. External hub is required to support more than
> one device.
> 

<quick scan>

Nice-looking driver.  But the namespace pollution is tremendous!

>
> ...
>
> +static int fhci_mem_init(struct fhci_hcd *fhci)
> +{
> +	int i;
> +	int error = 0;
> +
> +	fhci->hc_list = kzalloc(sizeof(*fhci->hc_list), GFP_KERNEL);
> +	if (!fhci->hc_list)
> +		return -ENOMEM;
> +
> +	INIT_LIST_HEAD(&fhci->hc_list->ctrl_list);
> +	INIT_LIST_HEAD(&fhci->hc_list->bulk_list);
> +	INIT_LIST_HEAD(&fhci->hc_list->iso_list);
> +	INIT_LIST_HEAD(&fhci->hc_list->intr_list);
> +	INIT_LIST_HEAD(&fhci->hc_list->done_list);
> +
> +	fhci->vroot_hub = kzalloc(sizeof(*fhci->vroot_hub), GFP_KERNEL);
> +	if (!fhci->vroot_hub)
> +		return -ENOMEM;

Did we leak fhci->hc_list?

> +	INIT_LIST_HEAD(&fhci->empty_eds);
> +	INIT_LIST_HEAD(&fhci->empty_tds);
> +
> +	/* initialize work queue to handle done list */
> +	fhci_tasklet.data = (unsigned long)fhci;
> +	fhci->process_done_task = &fhci_tasklet;
> +
> +	for (i = 0; i < MAX_TDS; i++) {
> +		struct td *td = kmalloc(sizeof(*td), GFP_KERNEL);
> +
> +		if (!td) {
> +			error = 1;
> +			break;
> +		}
> +		recycle_empty_td(fhci, td);
> +	}
> +	for (i = 0; i < MAX_EDS; i++) {
> +		struct ed *ed = kmalloc(sizeof(*ed), GFP_KERNEL);
> +
> +		if (!ed) {
> +			error = 1;
> +			break;
> +		}
> +		recycle_empty_ed(fhci, ed);
> +	}
> +
> +	if (error) {
> +		fhci_mem_free(fhci);
> +		return -ENOMEM;
> +	}
> +
> +	fhci->active_urbs = 0;
> +
> +	return error;
> +}
> +
>
> ...
>
> +void config_transceiver(struct fhci_hcd *fhci, enum fhci_port_status status)

poorly-chosen global identifier.

> +{
> +	fhci_dbg(fhci, "-> %s: %d\n", __func__, status);
> +
> +	switch (status) {
> +	case FHCI_PORT_POWER_OFF:
> +		fhci_gpio_set_value(fhci, GPIO_POWER, false);
> +		break;
> +	case FHCI_PORT_DISABLED:
> +	case FHCI_PORT_WAITING:
> +		fhci_gpio_set_value(fhci, GPIO_POWER, true);
> +		break;
> +	case FHCI_PORT_LOW:
> +		fhci_gpio_set_value(fhci, GPIO_SPEED, false);
> +		break;
> +	case FHCI_PORT_FULL:
> +		fhci_gpio_set_value(fhci, GPIO_SPEED, true);
> +		break;
> +	default:
> +		WARN_ON(1);
> +		break;
> +	}
> +
> +	fhci_dbg(fhci, "<- %s: %d\n", __func__, status);
> +}
> +
> +/* disable the USB port by clearing the EN bit in the USBMOD register */
> +void usb_port_disable(struct fhci_hcd *fhci)

another 

> +{
> +	struct fhci_usb *usb = (struct fhci_usb *)fhci->usb_lld;
> +	enum fhci_port_status port_status;
> +
> +	fhci_dbg(fhci, "-> %s\n", __func__);
> +
> +	fhci_stop_sof_timer(fhci);
> +
> +	flush_all_transmissions(usb);
> +
> +	fhci_usb_disable_interrupt((struct fhci_usb *)fhci->usb_lld);
> +	port_status = usb->port_status;
> +	usb->port_status = FHCI_PORT_DISABLED;
> +
> +	/* Enable IDLE since we want to know if something comes along */
> +	usb->saved_msk |= USB_E_IDLE_MASK;
> +	out_be16(&usb->fhci->regs->usb_mask, usb->saved_msk);
> +
> +	/* check if during the disconnection process attached new device */
> +	if (port_status == FHCI_PORT_WAITING)
> +		device_connected_interrupt(fhci);
> +	usb->vroot_hub->port.wPortStatus &= ~USB_PORT_STAT_ENABLE;
> +	usb->vroot_hub->port.wPortChange |= USB_PORT_STAT_C_ENABLE;
> +	fhci_usb_enable_interrupt((struct fhci_usb *)fhci->usb_lld);
> +
> +	fhci_dbg(fhci, "<- %s\n", __func__);
> +}
> +
> +/* enable the USB port by setting the EN bit in the USBMOD register */
> +void usb_port_enable(void *lld)

another.  Please review all non-static symbols which this driver adds.

> +{
> +	struct fhci_usb *usb = (struct fhci_usb *)lld;
> +	struct fhci_hcd *fhci = usb->fhci;
> +
> +	fhci_dbg(fhci, "-> %s\n", __func__);
> +
> +	config_transceiver(fhci, usb->port_status);
> +
> +	if ((usb->port_status != FHCI_PORT_FULL) &&
> +			(usb->port_status != FHCI_PORT_LOW))
> +		fhci_start_sof_timer(fhci);
> +
> +	usb->vroot_hub->port.wPortStatus |= USB_PORT_STAT_ENABLE;
> +	usb->vroot_hub->port.wPortChange |= USB_PORT_STAT_C_ENABLE;
> +
> +	fhci_dbg(fhci, "<- %s\n", __func__);
> +}
> +
>
> ...
>
> +static struct td *get_empty_td(struct fhci_hcd *fhci)
> +{
> +	struct td *td;
> +
> +	if (!list_empty(&fhci->empty_tds)) {
> +		td = list_entry(fhci->empty_tds.next, struct td, node);
> +		list_del(fhci->empty_tds.next);
> +	} else {
> +		td = kmalloc(sizeof(*td), GFP_ATOMIC);
> +		if (!td)
> +			fhci_err(fhci, "No memory to allocate to TD\n");
> +		else
> +			init_td(td);
> +	}
> +
> +	return td;
> +}
> +
> +void recycle_empty_td(struct fhci_hcd *fhci, struct td *td)
> +{
> +	init_td(td);
> +	list_add(&td->node, &fhci->empty_tds);
> +}
> +
> +struct ed *get_empty_ed(struct fhci_hcd *fhci)
> +{
> +	struct ed *ed;
> +
> +	if (!list_empty(&fhci->empty_eds)) {
> +		ed = list_entry(fhci->empty_eds.next, struct ed, node);
> +		list_del(fhci->empty_eds.next);
> +	} else {
> +		ed = kmalloc(sizeof(*ed), GFP_ATOMIC);
> +		if (!ed)
> +			fhci_err(fhci, "No memory to allocate to ED\n");
> +		else
> +			init_ed(ed);
> +	}
> +
> +	return ed;
> +}

The GFP_ATOMICs here are regrettable.  Are these functions ever called
from a context in which a more reliable allocation mode can be used? 
If so, the caller should pass in the gfp_t.

>
> ...
>
> +u32 create_endpoint(struct fhci_usb *usb, enum fhci_mem_alloc data_mem,
> +			   u32 ring_len)

This is a poorly chosen global identifier.  fhci_create_endpoint()
would be better.

WARNING: multiple messages have this Message-ID (diff)
From: Andrew Morton <akpm@linux-foundation.org>
To: Anton Vorontsov <avorontsov@ru.mvista.com>
Cc: greg@kroah.com, dbrownell@users.sourceforge.net,
	timur@freescale.com, leoli@freescale.com,
	linux-usb@vger.kernel.org, linuxppc-dev@ozlabs.org,
	linux-kernel@vger.kernel.org
Subject: Re: [PATCH] USB: Driver for Freescale QUICC Engine USB Host Controller
Date: Tue, 23 Dec 2008 13:28:40 -0800	[thread overview]
Message-ID: <20081223132840.55e7b666.akpm@linux-foundation.org> (raw)
In-Reply-To: <20081223210322.GA2802@oksana.dev.rtsoft.ru>

On Wed, 24 Dec 2008 00:03:22 +0300
Anton Vorontsov <avorontsov@ru.mvista.com> wrote:

> This patch adds support for the FHCI USB controller, as found
> in the Freescale MPC836x and MPC832x processors. It can support
> Full or Low speed modes.
> 
> Quite a lot the hardware is doing by itself (SOF generation, CRC
> generation and checking), though scheduling and retransmission is on
> software's shoulders.
> 
> This controller does not integrate the root hub, so this driver also
> fakes one-port hub. External hub is required to support more than
> one device.
> 

<quick scan>

Nice-looking driver.  But the namespace pollution is tremendous!

>
> ...
>
> +static int fhci_mem_init(struct fhci_hcd *fhci)
> +{
> +	int i;
> +	int error = 0;
> +
> +	fhci->hc_list = kzalloc(sizeof(*fhci->hc_list), GFP_KERNEL);
> +	if (!fhci->hc_list)
> +		return -ENOMEM;
> +
> +	INIT_LIST_HEAD(&fhci->hc_list->ctrl_list);
> +	INIT_LIST_HEAD(&fhci->hc_list->bulk_list);
> +	INIT_LIST_HEAD(&fhci->hc_list->iso_list);
> +	INIT_LIST_HEAD(&fhci->hc_list->intr_list);
> +	INIT_LIST_HEAD(&fhci->hc_list->done_list);
> +
> +	fhci->vroot_hub = kzalloc(sizeof(*fhci->vroot_hub), GFP_KERNEL);
> +	if (!fhci->vroot_hub)
> +		return -ENOMEM;

Did we leak fhci->hc_list?

> +	INIT_LIST_HEAD(&fhci->empty_eds);
> +	INIT_LIST_HEAD(&fhci->empty_tds);
> +
> +	/* initialize work queue to handle done list */
> +	fhci_tasklet.data = (unsigned long)fhci;
> +	fhci->process_done_task = &fhci_tasklet;
> +
> +	for (i = 0; i < MAX_TDS; i++) {
> +		struct td *td = kmalloc(sizeof(*td), GFP_KERNEL);
> +
> +		if (!td) {
> +			error = 1;
> +			break;
> +		}
> +		recycle_empty_td(fhci, td);
> +	}
> +	for (i = 0; i < MAX_EDS; i++) {
> +		struct ed *ed = kmalloc(sizeof(*ed), GFP_KERNEL);
> +
> +		if (!ed) {
> +			error = 1;
> +			break;
> +		}
> +		recycle_empty_ed(fhci, ed);
> +	}
> +
> +	if (error) {
> +		fhci_mem_free(fhci);
> +		return -ENOMEM;
> +	}
> +
> +	fhci->active_urbs = 0;
> +
> +	return error;
> +}
> +
>
> ...
>
> +void config_transceiver(struct fhci_hcd *fhci, enum fhci_port_status status)

poorly-chosen global identifier.

> +{
> +	fhci_dbg(fhci, "-> %s: %d\n", __func__, status);
> +
> +	switch (status) {
> +	case FHCI_PORT_POWER_OFF:
> +		fhci_gpio_set_value(fhci, GPIO_POWER, false);
> +		break;
> +	case FHCI_PORT_DISABLED:
> +	case FHCI_PORT_WAITING:
> +		fhci_gpio_set_value(fhci, GPIO_POWER, true);
> +		break;
> +	case FHCI_PORT_LOW:
> +		fhci_gpio_set_value(fhci, GPIO_SPEED, false);
> +		break;
> +	case FHCI_PORT_FULL:
> +		fhci_gpio_set_value(fhci, GPIO_SPEED, true);
> +		break;
> +	default:
> +		WARN_ON(1);
> +		break;
> +	}
> +
> +	fhci_dbg(fhci, "<- %s: %d\n", __func__, status);
> +}
> +
> +/* disable the USB port by clearing the EN bit in the USBMOD register */
> +void usb_port_disable(struct fhci_hcd *fhci)

another 

> +{
> +	struct fhci_usb *usb = (struct fhci_usb *)fhci->usb_lld;
> +	enum fhci_port_status port_status;
> +
> +	fhci_dbg(fhci, "-> %s\n", __func__);
> +
> +	fhci_stop_sof_timer(fhci);
> +
> +	flush_all_transmissions(usb);
> +
> +	fhci_usb_disable_interrupt((struct fhci_usb *)fhci->usb_lld);
> +	port_status = usb->port_status;
> +	usb->port_status = FHCI_PORT_DISABLED;
> +
> +	/* Enable IDLE since we want to know if something comes along */
> +	usb->saved_msk |= USB_E_IDLE_MASK;
> +	out_be16(&usb->fhci->regs->usb_mask, usb->saved_msk);
> +
> +	/* check if during the disconnection process attached new device */
> +	if (port_status == FHCI_PORT_WAITING)
> +		device_connected_interrupt(fhci);
> +	usb->vroot_hub->port.wPortStatus &= ~USB_PORT_STAT_ENABLE;
> +	usb->vroot_hub->port.wPortChange |= USB_PORT_STAT_C_ENABLE;
> +	fhci_usb_enable_interrupt((struct fhci_usb *)fhci->usb_lld);
> +
> +	fhci_dbg(fhci, "<- %s\n", __func__);
> +}
> +
> +/* enable the USB port by setting the EN bit in the USBMOD register */
> +void usb_port_enable(void *lld)

another.  Please review all non-static symbols which this driver adds.

> +{
> +	struct fhci_usb *usb = (struct fhci_usb *)lld;
> +	struct fhci_hcd *fhci = usb->fhci;
> +
> +	fhci_dbg(fhci, "-> %s\n", __func__);
> +
> +	config_transceiver(fhci, usb->port_status);
> +
> +	if ((usb->port_status != FHCI_PORT_FULL) &&
> +			(usb->port_status != FHCI_PORT_LOW))
> +		fhci_start_sof_timer(fhci);
> +
> +	usb->vroot_hub->port.wPortStatus |= USB_PORT_STAT_ENABLE;
> +	usb->vroot_hub->port.wPortChange |= USB_PORT_STAT_C_ENABLE;
> +
> +	fhci_dbg(fhci, "<- %s\n", __func__);
> +}
> +
>
> ...
>
> +static struct td *get_empty_td(struct fhci_hcd *fhci)
> +{
> +	struct td *td;
> +
> +	if (!list_empty(&fhci->empty_tds)) {
> +		td = list_entry(fhci->empty_tds.next, struct td, node);
> +		list_del(fhci->empty_tds.next);
> +	} else {
> +		td = kmalloc(sizeof(*td), GFP_ATOMIC);
> +		if (!td)
> +			fhci_err(fhci, "No memory to allocate to TD\n");
> +		else
> +			init_td(td);
> +	}
> +
> +	return td;
> +}
> +
> +void recycle_empty_td(struct fhci_hcd *fhci, struct td *td)
> +{
> +	init_td(td);
> +	list_add(&td->node, &fhci->empty_tds);
> +}
> +
> +struct ed *get_empty_ed(struct fhci_hcd *fhci)
> +{
> +	struct ed *ed;
> +
> +	if (!list_empty(&fhci->empty_eds)) {
> +		ed = list_entry(fhci->empty_eds.next, struct ed, node);
> +		list_del(fhci->empty_eds.next);
> +	} else {
> +		ed = kmalloc(sizeof(*ed), GFP_ATOMIC);
> +		if (!ed)
> +			fhci_err(fhci, "No memory to allocate to ED\n");
> +		else
> +			init_ed(ed);
> +	}
> +
> +	return ed;
> +}

The GFP_ATOMICs here are regrettable.  Are these functions ever called
from a context in which a more reliable allocation mode can be used? 
If so, the caller should pass in the gfp_t.

>
> ...
>
> +u32 create_endpoint(struct fhci_usb *usb, enum fhci_mem_alloc data_mem,
> +			   u32 ring_len)

This is a poorly chosen global identifier.  fhci_create_endpoint()
would be better.



  reply	other threads:[~2008-12-23 21:29 UTC|newest]

Thread overview: 30+ messages / expand[flat|nested]  mbox.gz  Atom feed  top
2008-12-23 21:03 [PATCH] USB: Driver for Freescale QUICC Engine USB Host Controller Anton Vorontsov
2008-12-23 21:03 ` Anton Vorontsov
2008-12-23 21:28 ` Andrew Morton [this message]
2008-12-23 21:28   ` Andrew Morton
2008-12-24 19:11   ` Anton Vorontsov
2008-12-24 19:11     ` Anton Vorontsov
2008-12-24  2:45 ` Alan Stern
2008-12-24  2:45   ` Alan Stern
2008-12-24 19:11   ` Anton Vorontsov
2008-12-24 19:11     ` Anton Vorontsov
2008-12-24 19:13 ` [PATCH -mm 1/3] USB: FHCI: Driver should be responsible for managing endpoint queues Anton Vorontsov
2008-12-24 19:13   ` Anton Vorontsov
2008-12-24 19:59   ` Greg KH
2008-12-24 19:59     ` Greg KH
2008-12-24 20:08     ` Anton Vorontsov
2008-12-24 20:08       ` Anton Vorontsov
2008-12-24 20:18       ` Andrew Morton
2008-12-24 20:18         ` Andrew Morton
2008-12-24 20:53         ` [PATCH v2] USB: Driver for Freescale QUICC Engine USB Host Controller Anton Vorontsov
2008-12-24 20:53           ` Anton Vorontsov
2008-12-24 20:58         ` [PATCH -mm 1/3] USB: FHCI: Driver should be responsible for managing endpoint queues Greg KH
2008-12-24 20:58           ` Greg KH
2008-12-24 21:07           ` Anton Vorontsov
2008-12-24 21:07             ` Anton Vorontsov
2008-12-24 22:54   ` Alan Stern
2008-12-24 22:54     ` Alan Stern
2008-12-24 19:13 ` [PATCH -mm 2/3] USB: FHCI: Fix namespace pollution Anton Vorontsov
2008-12-24 19:13   ` Anton Vorontsov
2008-12-24 19:13 ` [PATCH -mm 3/3] USB: FHCI: Fix memory leaks in fhci_mem_{init,free} Anton Vorontsov
2008-12-24 19:13   ` Anton Vorontsov

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=20081223132840.55e7b666.akpm@linux-foundation.org \
    --to=akpm@linux-foundation.org \
    --cc=avorontsov@ru.mvista.com \
    --cc=dbrownell@users.sourceforge.net \
    --cc=greg@kroah.com \
    --cc=leoli@freescale.com \
    --cc=linux-kernel@vger.kernel.org \
    --cc=linux-usb@vger.kernel.org \
    --cc=linuxppc-dev@ozlabs.org \
    --cc=timur@freescale.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 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.