lkml.org 
[lkml]   [2007]   [Mar]   [19]   [last100]   RSS Feed
Views: [wrap][no wrap]   [headers]  [forward] 
 
Messages in this thread
    Patch in this message
    /
    Date
    From
    Subject[PATCH] dmaenginge.c: class_device_register() return value
    Hi,

    this patch makes dma_async_device_register() in drivers/dma/dmaengine.c
    handle a failing class_device_register(). Patched against Linus' git
    tree, compile-tested.

    I also thought about calling dma_async_device_unregister on failure, but
    I was not quite sure if this would work. And I noticed that memory is
    allocated for chan->local in dma_async_device_register() but I couldn't
    find where it is released again.

    I am quite new to this all, please give me feedback!


    Signed-off-by: Johannes Weiner <hannes-kernel@saeurebad.de>
    diff --git a/drivers/dma/dmaengine.c b/drivers/dma/dmaengine.c
    index 322ee29..5560e39 100644
    --- a/drivers/dma/dmaengine.c
    +++ b/drivers/dma/dmaengine.c
    @@ -316,8 +316,8 @@ EXPORT_SYMBOL(dma_async_client_chan_request);
    int dma_async_device_register(struct dma_device *device)
    {
    static int id;
    - int chancnt = 0;
    - struct dma_chan* chan;
    + int chancnt, err;
    + struct dma_chan *chan, *last;

    if (!device)
    return -ENODEV;
    @@ -326,9 +326,13 @@ int dma_async_device_register(struct dma_device *device)
    kref_init(&device->refcount);
    device->dev_id = id++;

    + err = chancnt = 0;
    +
    /* represent channels in sysfs. Probably want devs too */
    list_for_each_entry(chan, &device->channels, device_node) {
    chan->local = alloc_percpu(typeof(*chan->local));
    +
    + /* Should this be handled less relaxed? */
    if (chan->local == NULL)
    continue;

    @@ -339,7 +343,11 @@ int dma_async_device_register(struct dma_device *device)
    device->dev_id, chan->chan_id);

    kref_get(&device->refcount);
    - class_device_register(&chan->class_dev);
    + err = class_device_register(&chan->class_dev);
    + if (err) {
    + last = chan;
    + goto err_dev_reg;
    + }
    }

    mutex_lock(&dma_list_mutex);
    @@ -349,6 +357,22 @@ int dma_async_device_register(struct dma_device *device)
    dma_chans_rebalance();

    return 0;
    +
    +err_dev_reg:
    + list_for_each_entry(chan, &device->channels, device_node) {
    + kref_put(&device->refcount, dma_async_device_cleanup);
    +
    + if (chan->local)
    + free_percpu(chan->local);
    +
    + if (chan == last)
    + break;
    +
    + class_device_unregister(&chan->class_dev);
    + }
    + wait_for_completion(&device->done);
    + device->dev_id = 0;
    + return err;
    }
    EXPORT_SYMBOL(dma_async_device_register);

    diff --git a/drivers/dma/ioatdma.c b/drivers/dma/ioatdma.c
    index 8e87261..c25f548 100644
    --- a/drivers/dma/ioatdma.c
    +++ b/drivers/dma/ioatdma.c
    @@ -768,10 +768,13 @@ static int __devinit ioat_probe(struct pci_dev *pdev,
    if (err)
    goto err_self_test;

    - dma_async_device_register(&device->common);
    + err = dma_async_device_register(&device->common)
    + if (err)
    + goto err_dev_reg;

    return 0;

    +err_dev_reg:
    err_self_test:
    err_irq:
    pci_pool_destroy(device->completion_pool);
    \
     
     \ /
      Last update: 2007-03-19 20:41    [W:0.023 / U:2.472 seconds]
    ©2003-2016 Jasper Spaans. hosted at Digital OceanAdvertise on this site