Hi,

--On March 06, 2014 16:57 -0500 David Miller <da...@davemloft.net> wrote:

From: Christian Riesch <christian.rie...@omicron.at>
Date: Wed, 5 Mar 2014 11:25:28 +0100

@@ -1641,7 +1640,15 @@ static int emac_dev_open(struct net_device *ndev)

 rollback:

-       dev_err(emac_dev, "DaVinci EMAC: devm_request_irq() failed");
+       dev_err(emac_dev, "DaVinci EMAC: request_irq() failed");
+
+       for (q = k; k >= 0; k--) {
+               for (m = i; m >= res->start; m--)
+                       free_irq(m, ndev);
+               res = platform_get_resource(priv->pdev, IORESOURCE_IRQ, k-1);
+               m = res->end;
           ^^^^
So this should definitely read "i = res->end;".

+       }

This final assignment in the loop of 'm' is unused?

The inner for() loop always started with "m = i;"

But it is more than just that. The entire rollback mechanism of emac_dev_open is a mess. It just won't work.

1) Freeing the interrupts. Currently, the code tries to do a platform_get_resource(priv->pdev, IORESOURCE_IRQ, -1) in its last iteration. To make this work, the code should be something like

for (q = k; q >= 0; q--) {
        res = platform_get_resource(priv->pdev, IORESOURCE_IRQ, k-1);
        if (q != k)
                i = res->end;

        for (m = i; m >= res->start; m--)
                free_irq(m, ndev);
}               

2) Wrong order of err: and rollback: labels. Currently the function does something like this:

        pm_runtime_get
        request irq
                if requesting irqs fails, goto rollback
        setup phy
                if phy setup fails, goto err
        return 0

rollback:
        free irqs
err:
        pm_runtime_put

So if PHY initialization fails, the IRQs are never freed. So rollback and err must be exchanged, and some additonal code must be added to keep the correct values of k and i for rollback.

3) RX DMA descriptors are not freed in case of an error: Right before requesting the irqs, the function creates DMA descriptors for the RX channel. These RX descriptors are never freed when we jump to either rollback or err. And I think there is also no way to free them as long as cpdma_ctlr_start() has not been called (which is done between requesting irqs and phy setup in the code).

Problems 1+2 are easy to solve. Prabhakar, Mugunthan, any ideas for 3? I think cpsw_ndo_start() in cpsw.c has the same problem. It will also try to call cpdma_ctlr_stop in error handling before cpdma_ctlr_start was called in some cases.

Regards, Christian




_______________________________________________
Davinci-linux-open-source mailing list
Davinci-linux-open-source@linux.davincidsp.com
http://linux.davincidsp.com/mailman/listinfo/davinci-linux-open-source

Reply via email to