From: Julian Scheel <julian@jusst.de>
To: Ezequiel Garcia <elezegarcia@gmail.com>
Cc: linux-media@vger.kernel.org
Subject: Re: [PATCH] tm6000: Add parameter to keep urb bufs allocated.
Date: Mon, 08 Oct 2012 10:49:32 +0200 [thread overview]
Message-ID: <1349686172.28116.0.camel@avionic-0108.adnet.avionic-design.de> (raw)
In-Reply-To: <CALF0-+U7uPNb058y-FZGt_tvtgh8FMtqf7uRHA5p7h+BCDCXow@mail.gmail.com>
Hi Ezequiel,
Am Donnerstag, den 04.10.2012, 14:35 -0300 schrieb Ezequiel Garcia:
> Nice work! Just one pico-tiny nitpick:
Should I update the patch to reflect this? Or is it ok if the maintainer
integrated your proposal when comitting it?
> On Thu, Oct 4, 2012 at 11:04 AM, Julian Scheel <julian@jusst.de> wrote:
> > On systems where it cannot be assured that enough continous memory is available
> > all the time it can be very useful to only allocate the memory once when it is
> > needed the first time. Afterwards the initially allocated memory will be
> > reused, so it is ensured that the memory will stay available until the driver
> > is unloaded.
> >
> > Signed-off-by: Julian Scheel <julian@jusst.de>
> > ---
> > drivers/media/video/tm6000/tm6000-video.c | 111 +++++++++++++++++++++++++-----
> > drivers/media/video/tm6000/tm6000.h | 5 ++
> > 2 files changed, 97 insertions(+), 19 deletions(-)
> >
> > diff --git a/drivers/media/video/tm6000/tm6000-video.c b/drivers/media/video/tm6000/tm6000-video.c
> > index 03de3d8..1b8db35 100644
> > --- a/drivers/media/video/tm6000/tm6000-video.c
> > +++ b/drivers/media/video/tm6000/tm6000-video.c
> > @@ -49,12 +49,15 @@
> > #define TM6000_MIN_BUF 4
> > #define TM6000_DEF_BUF 8
> >
> > +#define TM6000_NUM_URB_BUF 8
> > +
> > #define TM6000_MAX_ISO_PACKETS 46 /* Max number of ISO packets */
> >
> > /* Declare static vars that will be used as parameters */
> > static unsigned int vid_limit = 16; /* Video memory limit, in Mb */
> > static int video_nr = -1; /* /dev/videoN, -1 for autodetect */
> > static int radio_nr = -1; /* /dev/radioN, -1 for autodetect */
> > +static int keep_urb = 0; /* keep urb buffers allocated */
> >
>
> There's no need to initialize this one to zero.
>
> > /* Debug level */
> > int tm6000_debug;
> > @@ -570,6 +573,70 @@ static void tm6000_irq_callback(struct urb *urb)
> > }
> >
> > /*
> > + * Allocate URB buffers
> > + */
> > +static int tm6000_alloc_urb_buffers(struct tm6000_core *dev)
> > +{
> > + int num_bufs = TM6000_NUM_URB_BUF;
> > + int i;
> > +
> > + if (dev->urb_buffer != NULL)
> > + return 0;
> > +
> > + dev->urb_buffer = kmalloc(sizeof(void *)*num_bufs, GFP_KERNEL);
> > + if (!dev->urb_buffer) {
> > + tm6000_err("cannot allocate memory for urb buffers\n");
> > + return -ENOMEM;
> > + }
> > +
> > + dev->urb_dma = kmalloc(sizeof(dma_addr_t *)*num_bufs, GFP_KERNEL);
> > + if (!dev->urb_dma) {
> > + tm6000_err("cannot allocate memory for urb dma pointers\n");
> > + return -ENOMEM;
> > + }
> > +
> > + for (i = 0; i < num_bufs; i++) {
> > + dev->urb_buffer[i] = usb_alloc_coherent(dev->udev, dev->urb_size,
> > + GFP_KERNEL, &dev->urb_dma[i]);
> > + if (!dev->urb_buffer[i]) {
> > + tm6000_err("unable to allocate %i bytes for transfer"
> > + " buffer %i\n", dev->urb_size, i);
> > + return -ENOMEM;
> > + }
> > + memset(dev->urb_buffer[i], 0, dev->urb_size);
> > + }
> > +
> > + return 0;
> > +}
> > +
> > +/*
> > + * Free URB buffers
> > + */
> > +static int tm6000_free_urb_buffers(struct tm6000_core *dev)
> > +{
> > + int i;
> > +
> > + if (dev->urb_buffer == NULL)
> > + return 0;
> > +
> > + for (i = 0; i < TM6000_NUM_URB_BUF; i++) {
> > + if (dev->urb_buffer[i]) {
> > + usb_free_coherent(dev->udev,
> > + dev->urb_size,
> > + dev->urb_buffer[i],
> > + dev->urb_dma[i]);
> > + dev->urb_buffer[i] = NULL;
> > + }
> > + }
> > + kfree (dev->urb_buffer);
> > + kfree (dev->urb_dma);
> > + dev->urb_buffer = NULL;
> > + dev->urb_dma = NULL;
> > +
> > + return 0;
> > +}
> > +
> > +/*
> > * Stop and Deallocate URBs
> > */
> > static void tm6000_uninit_isoc(struct tm6000_core *dev)
> > @@ -585,18 +652,15 @@ static void tm6000_uninit_isoc(struct tm6000_core *dev)
> > if (urb) {
> > usb_kill_urb(urb);
> > usb_unlink_urb(urb);
> > - if (dev->isoc_ctl.transfer_buffer[i]) {
> > - usb_free_coherent(dev->udev,
> > - urb->transfer_buffer_length,
> > - dev->isoc_ctl.transfer_buffer[i],
> > - urb->transfer_dma);
> > - }
> > usb_free_urb(urb);
> > dev->isoc_ctl.urb[i] = NULL;
> > }
> > dev->isoc_ctl.transfer_buffer[i] = NULL;
> > }
> >
> > + if (!keep_urb)
> > + tm6000_free_urb_buffers(dev);
> > +
> > kfree(dev->isoc_ctl.urb);
> > kfree(dev->isoc_ctl.transfer_buffer);
> >
> > @@ -606,12 +670,12 @@ static void tm6000_uninit_isoc(struct tm6000_core *dev)
> > }
> >
> > /*
> > - * Allocate URBs and start IRQ
> > + * Assign URBs and start IRQ
> > */
> > static int tm6000_prepare_isoc(struct tm6000_core *dev)
> > {
> > struct tm6000_dmaqueue *dma_q = &dev->vidq;
> > - int i, j, sb_size, pipe, size, max_packets, num_bufs = 8;
> > + int i, j, sb_size, pipe, size, max_packets, num_bufs = TM6000_NUM_URB_BUF;
> > struct urb *urb;
> >
> > /* De-allocates all pending stuff */
> > @@ -634,6 +698,7 @@ static int tm6000_prepare_isoc(struct tm6000_core *dev)
> >
> > max_packets = TM6000_MAX_ISO_PACKETS;
> > sb_size = max_packets * size;
> > + dev->urb_size = sb_size;
> >
> > dev->isoc_ctl.num_bufs = num_bufs;
> >
> > @@ -656,6 +721,17 @@ static int tm6000_prepare_isoc(struct tm6000_core *dev)
> > max_packets, num_bufs, sb_size,
> > dev->isoc_in.maxsize, size);
> >
> > +
> > + if (!dev->urb_buffer && tm6000_alloc_urb_buffers(dev) < 0) {
> > + tm6000_err("cannot allocate memory for urb buffers\n");
> > +
> > + /* call free, as some buffers might have been allocated */
> > + tm6000_free_urb_buffers(dev);
> > + kfree(dev->isoc_ctl.urb);
> > + kfree(dev->isoc_ctl.transfer_buffer);
> > + return -ENOMEM;
> > + }
> > +
> > /* allocate urbs and transfer buffers */
> > for (i = 0; i < dev->isoc_ctl.num_bufs; i++) {
> > urb = usb_alloc_urb(max_packets, GFP_KERNEL);
> > @@ -667,17 +743,8 @@ static int tm6000_prepare_isoc(struct tm6000_core *dev)
> > }
> > dev->isoc_ctl.urb[i] = urb;
> >
> > - dev->isoc_ctl.transfer_buffer[i] = usb_alloc_coherent(dev->udev,
> > - sb_size, GFP_KERNEL, &urb->transfer_dma);
> > - if (!dev->isoc_ctl.transfer_buffer[i]) {
> > - tm6000_err("unable to allocate %i bytes for transfer"
> > - " buffer %i%s\n",
> > - sb_size, i,
> > - in_interrupt() ? " while in int" : "");
> > - tm6000_uninit_isoc(dev);
> > - return -ENOMEM;
> > - }
> > - memset(dev->isoc_ctl.transfer_buffer[i], 0, sb_size);
> > + urb->transfer_dma = dev->urb_dma[i];
> > + dev->isoc_ctl.transfer_buffer[i] = dev->urb_buffer[i];
> >
> > usb_fill_bulk_urb(urb, dev->udev, pipe,
> > dev->isoc_ctl.transfer_buffer[i], sb_size,
> > @@ -1833,6 +1900,9 @@ int tm6000_v4l2_unregister(struct tm6000_core *dev)
> > {
> > video_unregister_device(dev->vfd);
> >
> > + /* if URB buffers are still allocated free them now */
> > + tm6000_free_urb_buffers(dev);
> > +
> > if (dev->radio_dev) {
> > if (video_is_registered(dev->radio_dev))
> > video_unregister_device(dev->radio_dev);
> > @@ -1858,3 +1928,6 @@ MODULE_PARM_DESC(debug, "activates debug info");
> > module_param(vid_limit, int, 0644);
> > MODULE_PARM_DESC(vid_limit, "capture memory limit in megabytes");
> >
> > +module_param(keep_urb, bool, 0);
> > +MODULE_PARM_DESC(keep_urb, "Keep urb buffers allocated even when the device "
> > + "is closed by the user");
> > diff --git a/drivers/media/video/tm6000/tm6000.h b/drivers/media/video/tm6000/tm6000.h
> > index 6531d16..4bd3a0d 100644
> > --- a/drivers/media/video/tm6000/tm6000.h
> > +++ b/drivers/media/video/tm6000/tm6000.h
> > @@ -267,6 +267,11 @@ struct tm6000_core {
> >
> > spinlock_t slock;
> >
> > + /* urb dma buffers */
> > + char **urb_buffer;
> > + dma_addr_t *urb_dma;
> > + unsigned int urb_size;
> > +
> > unsigned long quirks;
> > };
> >
> > --
> > 1.7.12.2
> >
next prev parent reply other threads:[~2012-10-08 8:45 UTC|newest]
Thread overview: 4+ messages / expand[flat|nested] mbox.gz Atom feed top
2012-10-04 14:04 [PATCH] tm6000: Add parameter to keep urb bufs allocated Julian Scheel
2012-10-04 17:35 ` Ezequiel Garcia
2012-10-08 8:49 ` Julian Scheel [this message]
2012-10-08 17:36 ` Ezequiel Garcia
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=1349686172.28116.0.camel@avionic-0108.adnet.avionic-design.de \
--to=julian@jusst.de \
--cc=elezegarcia@gmail.com \
--cc=linux-media@vger.kernel.org \
/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).