Re: [PATCH v8 2/4] fpga manager: add sysfs interface document
On Sun 2015-01-11 10:29:00, atull wrote: > On Sat, 10 Jan 2015, Pavel Machek wrote: > > > On Sat 2015-01-10 10:10:51, Pantelis Antoniou wrote: > > > Hi Pavel, > > > > > > > On Jan 9, 2015, at 22:56 , Pavel Machek wrote: > > > > > > > > On Fri 2015-01-09 13:14:24, atull wrote: > > > >> On Wed, 7 Jan 2015, Pavel Machek wrote: > > > >> > > > >>> On Tue 2015-01-06 14:13:37, at...@opensource.altera.com wrote: > > > + > > > +What: /sys/class/fpga_manager//firmware > > > +Date: October 2014 > > > +KernelVersion: 3.18 > > > +Contact:Alan Tull > > > +Description:Name of the FPGA image file to load using > > > firmware > > > class. > > > >>> > > > >>> This one is ugly: it unneccessarily passes firmware name through the > > > >>> kernel. Just make interface and code simpler by always passing > > > >>> "socfpga-fpga-image" or something like that. > > > >>> > > > >>> Thanks, > > > >>> > > > >>> Pavel > > > >> > > > >> Hi Pavel, > > > >> > > > >> It might be ugly. It's not unnecessary. Some uses of FPGAs involve > > > >> switching out the FPGA images dynamically under control of the > > > >> userspace. > > > > > > > > Then configure udev to load right firmware for you, or ln -s > > > > image-i-want-now socfpga-fpga-image to select the one to read…? > > > > > > > > > > Who said that udev is going to be available in the kind of system this is > > > going to end in? > > > > Noone. > > > > > Doing ln -s tricks to load a different image? Really? > > > > But if you don't have udev, you can do ln -s. It is better than > > open-coding symlink functionality into > > /sys/class/fpga_manager//firmware ... cause that's what this is. > > > > Actually, clean implementation of "firmware" would be symlink in > > sysfs; but I'd say that would be overdoing it. > > > > > I say the interface is fine as it is. > > > > I say it is not. > > Pavel > > Hi Pavel, > > I see that we could do it that way and it would eliminate one of the > sysfs files (../fpga_manager//firmware). Either way we are assuming > that there are fpga images in the filesystem in the firmware search path, > so I don't see why adding a piece of indirection (symlink) makes things > better. Well.. you are basically re-implementing symlink with ../fpga_manager//firmware "file" in sysfs, and doing it badly. It has no advantages over real symlink. > We want to be able to switch out the FPGA image > under control of userspace. So we don't want an interface that makes > it more cumbersome or tries to pretend that there's only one image. What is cumbersome about symlink? Why is "fake" symlink in sysfs better? > Previous uses of the firmware layer has been to use it to load once after > bootup; this is different since some use cases will want to switch out > the FPGA image. If someone wants there to be only one FPGA image on > the FGPA forever, they will probably not be using this framework; their > FPGA will probably be loaded before Linux boots up. Why? I have just one image on the fpga, and would prefer to load it from Linux. Pavel -- (english) http://www.livejournal.com/~pavelmachek (cesky, pictures) http://atrey.karlin.mff.cuni.cz/~pavel/picture/horses/blog.html ___ devel mailing list de...@linuxdriverproject.org http://driverdev.linuxdriverproject.org/mailman/listinfo/driverdev-devel
Re: [PATCH 00/25] line6usb cleanup
These patches look really nice. Thanks for doing this. regards, dan carpenter ___ devel mailing list de...@linuxdriverproject.org http://driverdev.linuxdriverproject.org/mailman/listinfo/driverdev-devel
Re: [PATCH v8 2/4] fpga manager: add sysfs interface document
On 01/12/2015 09:45 AM, Pavel Machek wrote: > On Sun 2015-01-11 10:29:00, atull wrote: >> On Sat, 10 Jan 2015, Pavel Machek wrote: >> >>> On Sat 2015-01-10 10:10:51, Pantelis Antoniou wrote: Hi Pavel, > On Jan 9, 2015, at 22:56 , Pavel Machek wrote: > > On Fri 2015-01-09 13:14:24, atull wrote: >> On Wed, 7 Jan 2015, Pavel Machek wrote: >> >>> On Tue 2015-01-06 14:13:37, at...@opensource.altera.com wrote: + +What: /sys/class/fpga_manager//firmware +Date: October 2014 +KernelVersion:3.18 +Contact: Alan Tull +Description: Name of the FPGA image file to load using firmware class. >>> >>> This one is ugly: it unneccessarily passes firmware name through the >>> kernel. Just make interface and code simpler by always passing >>> "socfpga-fpga-image" or something like that. >>> >>> Thanks, >>> >>> Pavel >> >> Hi Pavel, >> >> It might be ugly. It's not unnecessary. Some uses of FPGAs involve >> switching out the FPGA images dynamically under control of the userspace. > > Then configure udev to load right firmware for you, or ln -s > image-i-want-now socfpga-fpga-image to select the one to read…? > Who said that udev is going to be available in the kind of system this is going to end in? >>> >>> Noone. >>> Doing ln -s tricks to load a different image? Really? >>> >>> But if you don't have udev, you can do ln -s. It is better than >>> open-coding symlink functionality into >>> /sys/class/fpga_manager//firmware ... cause that's what this is. >>> >>> Actually, clean implementation of "firmware" would be symlink in >>> sysfs; but I'd say that would be overdoing it. >>> I say the interface is fine as it is. >>> >>> I say it is not. >>> Pavel >> >> Hi Pavel, >> >> I see that we could do it that way and it would eliminate one of the >> sysfs files (../fpga_manager//firmware). Either way we are assuming >> that there are fpga images in the filesystem in the firmware search path, >> so I don't see why adding a piece of indirection (symlink) makes things >> better. > > Well.. you are basically re-implementing symlink with > ../fpga_manager//firmware "file" in sysfs, and doing it > badly. It has no advantages over real symlink. > >> We want to be able to switch out the FPGA image >> under control of userspace. So we don't want an interface that makes >> it more cumbersome or tries to pretend that there's only one image. > > What is cumbersome about symlink? Why is "fake" symlink in sysfs better? > >> Previous uses of the firmware layer has been to use it to load once after >> bootup; this is different since some use cases will want to switch out >> the FPGA image. If someone wants there to be only one FPGA image on >> the FGPA forever, they will probably not be using this framework; their >> FPGA will probably be loaded before Linux boots up. > > Why? I have just one image on the fpga, and would prefer to load it > from Linux. Pavel: These patches target staging and sysfs interface doesn't need to be stable at this time. I would prefer to add these patches to staging for 3.20 and feel free to send the patch which fix this. With your code will be exactly clear how you want to use it and we can talk about it. Thanks, Michal ___ devel mailing list de...@linuxdriverproject.org http://driverdev.linuxdriverproject.org/mailman/listinfo/driverdev-devel
Re: [PATCH v8 0/4] FPGA Manager Framework
On 01/11/2015 10:31 PM, Pavel Machek wrote: > On Sun 2015-01-11 21:58:00, Konrad Zapalowicz wrote: >> On 01/11, Pavel Machek wrote: >>> On Sun 2015-01-11 17:24:26, Konrad Zapalowicz wrote: On 01/11, atull wrote: > On Sat, 10 Jan 2015, Konrad Zapalowicz wrote: > >> On 01/06, at...@opensource.altera.com wrote: >>> From: Alan Tull >> >> Alan, there is something wrong with your email client configuration >> and you need to fix. >> >> thanks, >> konrad > > Hi Konrad, > > Can you be more specific? What problem are you seeing? Is it a problem > with the original patch post or when I reply? When I a post, I'm using > 'git send-email' with sendmail and when I am replying, I am using alpine. I think that because you email client configuration sets the 'From' header to "atull@..." and at the same time you sign-off messages with "Alan Tull atull@..." the "From" is added at the beginning of the message to indicate the original author. This should be fixed as the "from" is not welcomed in the body of the commit message. >>> >>> Actually, why not? Tools should know to look at From: in the >>> commit. AFAICT, Alan has it set up correctly. >> >> I think he has not. I suspect that the sendmail configuration in the git >> config might be wrong. The 'from' must contain the same data as the git >> is configured for the user.name and user.email options. Otherwise the >> send-email is adding the "From: ..." to the message body. > > And what is the problem with From: in the message body? Tools should > handle that ok. Konrad: Problem is probably just on your end. I have also no problem to handle these patches. Alan: From my point of view you don't need to change anything. Thanks, Michal ___ devel mailing list de...@linuxdriverproject.org http://driverdev.linuxdriverproject.org/mailman/listinfo/driverdev-devel
Re: [PATCH v8 0/4] FPGA Manager Framework
On Sun, Jan 11, 2015 at 08:52:19PM +0100, Pavel Machek wrote: > > Actually, why not? Tools should know to look at From: in the > commit. AFAICT, Alan has it set up correctly. > Pavel Normally, the Extra From header should only be used if the patches were sent on behalf of someone else. It's just a bit of a pain to verify that the Extra From matches the email headers. Also sometimes people can't get their corporate email configured properly for patches and so they use gmail but specify an Extra From so their employer gets credit... That's ok. The patches apply fine so it's not a "redo the patch" type thing, it's just a "In the long term, please, fix your email From header so the Extra From isn't needed." regards, dan carpenter ___ devel mailing list de...@linuxdriverproject.org http://driverdev.linuxdriverproject.org/mailman/listinfo/driverdev-devel
Re: [PATCH] staging: skein: Fix checkpatch warnings
Arno, On Sat, Jan 10, 2015 at 04:00:47PM +0100, Arno Tiemersma wrote: > Remove do {} while (0) loops around single statements in > skein/skein_block.c > > Signed-off-by: Arno Tiemersma > --- > drivers/staging/skein/skein_block.c | 16 > 1 file changed, 4 insertions(+), 12 deletions(-) Is this a V2? Several people have been submitting patches for this checkpatch issue. Please check the staging ML and deconflict with other submitters. thx, Jason. ___ devel mailing list de...@linuxdriverproject.org http://driverdev.linuxdriverproject.org/mailman/listinfo/driverdev-devel
Re: [PATCH v2] staging: skein: Remove all do{} while (0) loop from single statement.
On Sun, Jan 11, 2015 at 03:41:05PM -0800, Shirish Gajera wrote: > This patch fixes the checkpatch.pl warning: > > WARNING: Single statement macros should not use a do {} while (0) loop > > I remove do while from the single statement macro. > > Signed-off-by: Shirish Gajera > --- > drivers/staging/skein/skein_block.c | 31 +-- > 1 file changed, 9 insertions(+), 22 deletions(-) Several people have submitted patches for this checkpatch warning. Please check the mailinglist archives and deconflict with the other submitters. thx, Jason. ___ devel mailing list de...@linuxdriverproject.org http://driverdev.linuxdriverproject.org/mailman/listinfo/driverdev-devel
Re: [PATCH] staging: skein: Fix checkpatch warnings
On Mon, Jan 12, 2015 at 09:14:18AM -0500, Jason Cooper wrote: > Arno, > > On Sat, Jan 10, 2015 at 04:00:47PM +0100, Arno Tiemersma wrote: > > Remove do {} while (0) loops around single statements in > > skein/skein_block.c > > > > Signed-off-by: Arno Tiemersma > > --- > > drivers/staging/skein/skein_block.c | 16 > > 1 file changed, 4 insertions(+), 12 deletions(-) > > Is this a V2? Several people have been submitting patches for this > checkpatch issue. Please check the staging ML and deconflict with other > submitters. Why would it be a v2? It's really normal to get a wave of people sending the exact same patch. There was one time where 7 people deleted the same whitespace in panel.c. Don't worry too much about conflicts. It either applies when Greg reads it or it doesn't and he kicks off an email. Not a big deal. regards, dan carpenter ___ devel mailing list de...@linuxdriverproject.org http://driverdev.linuxdriverproject.org/mailman/listinfo/driverdev-devel
Re: [PATCH] staging: skein: Fix checkpatch warnings
On Mon, Jan 12, 2015 at 05:33:47PM +0300, Dan Carpenter wrote: > On Mon, Jan 12, 2015 at 09:14:18AM -0500, Jason Cooper wrote: > > Arno, > > > > On Sat, Jan 10, 2015 at 04:00:47PM +0100, Arno Tiemersma wrote: > > > Remove do {} while (0) loops around single statements in > > > skein/skein_block.c > > > > > > Signed-off-by: Arno Tiemersma > > > --- > > > drivers/staging/skein/skein_block.c | 16 > > > 1 file changed, 4 insertions(+), 12 deletions(-) > > > > Is this a V2? Several people have been submitting patches for this > > checkpatch issue. Please check the staging ML and deconflict with other > > submitters. > > Why would it be a v2? I had asked one person to do a little extra work validating that removing the do{}while's hadn't changed the resulting object code. Unfortunately, I forgot who that was :( Only because there have been so many people submitting the exact same thing, though... > It's really normal to get a wave of people sending the exact same patch. > There was one time where 7 people deleted the same whitespace in > panel.c. I suspect this is a combination of a) checkpatch.pl getting a more enhanced handling of do{}while's in macros, and b) more folks doing the Eudiptula (sp?) challenge. > Don't worry too much about conflicts. It either applies when Greg reads > it or it doesn't and he kicks off an email. Not a big deal. Agreed from a patch management side. I was attempting to encourage the new submitters to starting integrating the mailinglist into their workflow. thx, Jason. ___ devel mailing list de...@linuxdriverproject.org http://driverdev.linuxdriverproject.org/mailman/listinfo/driverdev-devel
Re: [PATCH v8 2/4] fpga manager: add sysfs interface document
On Sun, Jan 11, 2015 at 10:29 AM, atull wrote: > On Sat, 10 Jan 2015, Pavel Machek wrote: > >> On Sat 2015-01-10 10:10:51, Pantelis Antoniou wrote: >> > Hi Pavel, >> > >> > > On Jan 9, 2015, at 22:56 , Pavel Machek wrote: >> > > >> > > On Fri 2015-01-09 13:14:24, atull wrote: >> > >> On Wed, 7 Jan 2015, Pavel Machek wrote: >> > >> >> > >>> On Tue 2015-01-06 14:13:37, at...@opensource.altera.com wrote: >> > + >> > +What: /sys/class/fpga_manager//firmware >> > +Date: October 2014 >> > +KernelVersion:3.18 >> > +Contact: Alan Tull >> > +Description: Name of the FPGA image file to load using firmware >> > class. >> > >>> >> > >>> This one is ugly: it unneccessarily passes firmware name through the >> > >>> kernel. Just make interface and code simpler by always passing >> > >>> "socfpga-fpga-image" or something like that. >> > >>> >> > >>> Thanks, >> > >>> >> > >>> Pavel >> > >> >> > >> Hi Pavel, >> > >> >> > >> It might be ugly. It's not unnecessary. Some uses of FPGAs involve >> > >> switching out the FPGA images dynamically under control of the >> > >> userspace. >> > > >> > > Then configure udev to load right firmware for you, or ln -s >> > > image-i-want-now socfpga-fpga-image to select the one to read…? >> > > >> > >> > Who said that udev is going to be available in the kind of system this is >> > going to end in? >> >> Noone. >> >> > Doing ln -s tricks to load a different image? Really? >> >> But if you don't have udev, you can do ln -s. It is better than >> open-coding symlink functionality into >> /sys/class/fpga_manager//firmware ... cause that's what this is. >> >> Actually, clean implementation of "firmware" would be symlink in >> sysfs; but I'd say that would be overdoing it. >> >> > I say the interface is fine as it is. >> >> I say it is not. >> Pavel > > Hi Pavel, > > I see that we could do it that way and it would eliminate one of the > sysfs files (../fpga_manager//firmware). Either way we are assuming > that there are fpga images in the filesystem in the firmware search path, > so I don't see why adding a piece of indirection (symlink) makes things > better. > > We want to be able to switch out the FPGA image > under control of userspace. So we don't want an interface that makes > it more cumbersome or tries to pretend that there's only one image. > > Previous uses of the firmware layer has been to use it to load once after > bootup; this is different since some use cases will want to switch out > the FPGA image. If someone wants there to be only one FPGA image on > the FGPA forever, they will probably not be using this framework; their > FPGA will probably be loaded before Linux boots up. That's not really true. Some WiFi devices have to load different firmware for client and AP modes and switching is a common usecase in phones. There may be other instances of drivers wanting configurable firmware names already. A common interface here would be nice. It could also be useful to expose the firmware names such that you could generate a list of all firmware files needed for a machine (that may already be possible with uevents?). Rob ___ devel mailing list de...@linuxdriverproject.org http://driverdev.linuxdriverproject.org/mailman/listinfo/driverdev-devel
[PATCH] lowmemorykiller: Avoid excessive/redundant calling of LMK
The global shrinker will invoke lowmem_shrink in a loop. The loop will be run (total_scan_pages/batch_size) times. The default batch_size will be 128 which will make shrinker invoking 100s of times. LMK does meaningful work only during first 2-3 times and then rest of the invocations are just CPU cycle waste. Fix that by giving excessively large batch size so that lowmem_shrink will be called just once and in the same try LMK does the needful. Signed-off-by: Chintan Pandya --- drivers/staging/android/lowmemorykiller.c | 5 - 1 file changed, 4 insertions(+), 1 deletion(-) diff --git a/drivers/staging/android/lowmemorykiller.c b/drivers/staging/android/lowmemorykiller.c index b545d3d..5bf483f 100644 --- a/drivers/staging/android/lowmemorykiller.c +++ b/drivers/staging/android/lowmemorykiller.c @@ -110,7 +110,7 @@ static unsigned long lowmem_scan(struct shrinker *s, struct shrink_control *sc) if (min_score_adj == OOM_SCORE_ADJ_MAX + 1) { lowmem_print(5, "lowmem_scan %lu, %x, return 0\n", sc->nr_to_scan, sc->gfp_mask); - return 0; + return SHRINK_STOP; } selected_oom_score_adj = min_score_adj; @@ -163,6 +163,9 @@ static unsigned long lowmem_scan(struct shrinker *s, struct shrink_control *sc) set_tsk_thread_flag(selected, TIF_MEMDIE); send_sig(SIGKILL, selected, 0); rem += selected_tasksize; + } else { + rcu_read_unlock(); + return SHRINK_STOP; } lowmem_print(4, "lowmem_scan %lu, %x, return %lu\n", -- Chintan Pandya QUALCOMM INDIA, on behalf of Qualcomm Innovation Center, Inc. is a member of the Code Aurora Forum, hosted by The Linux Foundation ___ devel mailing list de...@linuxdriverproject.org http://driverdev.linuxdriverproject.org/mailman/listinfo/driverdev-devel
Re: [PATCH] lowmemorykiller: Avoid excessive/redundant calling of LMK
Please ignore this patch. My extreme bad that I merged commit messages applicable to some very old kernel into this patch. Updating shortly. On 01/12/2015 09:38 PM, Chintan Pandya wrote: The global shrinker will invoke lowmem_shrink in a loop. The loop will be run (total_scan_pages/batch_size) times. The default batch_size will be 128 which will make shrinker invoking 100s of times. LMK does meaningful work only during first 2-3 times and then rest of the invocations are just CPU cycle waste. Fix that by giving excessively large batch size so that lowmem_shrink will be called just once and in the same try LMK does the needful. Signed-off-by: Chintan Pandya --- drivers/staging/android/lowmemorykiller.c | 5 - 1 file changed, 4 insertions(+), 1 deletion(-) diff --git a/drivers/staging/android/lowmemorykiller.c b/drivers/staging/android/lowmemorykiller.c index b545d3d..5bf483f 100644 --- a/drivers/staging/android/lowmemorykiller.c +++ b/drivers/staging/android/lowmemorykiller.c @@ -110,7 +110,7 @@ static unsigned long lowmem_scan(struct shrinker *s, struct shrink_control *sc) if (min_score_adj == OOM_SCORE_ADJ_MAX + 1) { lowmem_print(5, "lowmem_scan %lu, %x, return 0\n", sc->nr_to_scan, sc->gfp_mask); - return 0; + return SHRINK_STOP; } selected_oom_score_adj = min_score_adj; @@ -163,6 +163,9 @@ static unsigned long lowmem_scan(struct shrinker *s, struct shrink_control *sc) set_tsk_thread_flag(selected, TIF_MEMDIE); send_sig(SIGKILL, selected, 0); rem += selected_tasksize; + } else { + rcu_read_unlock(); + return SHRINK_STOP; } lowmem_print(4, "lowmem_scan %lu, %x, return %lu\n", -- Chintan Pandya QUALCOMM INDIA, on behalf of Qualcomm Innovation Center, Inc. is a member of the Code Aurora Forum, hosted by The Linux Foundation ___ devel mailing list de...@linuxdriverproject.org http://driverdev.linuxdriverproject.org/mailman/listinfo/driverdev-devel
[PATCH] lowmemorykiller: Avoid excessive/redundant calling of LMK
The global shrinker will invoke lowmem_shrink in a loop. The loop will be run (total_scan_pages/batch_size) times. The default batch_size will be 128 which will make shrinker invoking 100s of times. LMK does meaningful work only during first 2-3 times and then rest of the invocations are just CPU cycle waste. Fix that by returning to the shrinker with SHRINK_STOP when LMK doesn't find any more work to do. The deciding factor here is, no process found in the selected LMK bucket or memory conditions are sane. Signed-off-by: Chintan Pandya --- drivers/staging/android/lowmemorykiller.c | 5 - 1 file changed, 4 insertions(+), 1 deletion(-) diff --git a/drivers/staging/android/lowmemorykiller.c b/drivers/staging/android/lowmemorykiller.c index b545d3d..5bf483f 100644 --- a/drivers/staging/android/lowmemorykiller.c +++ b/drivers/staging/android/lowmemorykiller.c @@ -110,7 +110,7 @@ static unsigned long lowmem_scan(struct shrinker *s, struct shrink_control *sc) if (min_score_adj == OOM_SCORE_ADJ_MAX + 1) { lowmem_print(5, "lowmem_scan %lu, %x, return 0\n", sc->nr_to_scan, sc->gfp_mask); - return 0; + return SHRINK_STOP; } selected_oom_score_adj = min_score_adj; @@ -163,6 +163,9 @@ static unsigned long lowmem_scan(struct shrinker *s, struct shrink_control *sc) set_tsk_thread_flag(selected, TIF_MEMDIE); send_sig(SIGKILL, selected, 0); rem += selected_tasksize; + } else { + rcu_read_unlock(); + return SHRINK_STOP; } lowmem_print(4, "lowmem_scan %lu, %x, return %lu\n", -- Chintan Pandya QUALCOMM INDIA, on behalf of Qualcomm Innovation Center, Inc. is a member of the Code Aurora Forum, hosted by The Linux Foundation ___ devel mailing list de...@linuxdriverproject.org http://driverdev.linuxdriverproject.org/mailman/listinfo/driverdev-devel
[PATCH] staging: lustre: lnet: Removed spaces before increments and decrements
Fixed a coding style issue Signed-off-by: Igor Ishchenko --- drivers/staging/lustre/lnet/klnds/o2iblnd/o2iblnd.c | 14 +++--- 1 file changed, 7 insertions(+), 7 deletions(-) diff --git a/drivers/staging/lustre/lnet/klnds/o2iblnd/o2iblnd.c b/drivers/staging/lustre/lnet/klnds/o2iblnd/o2iblnd.c index 62b575d..6510169 100644 --- a/drivers/staging/lustre/lnet/klnds/o2iblnd/o2iblnd.c +++ b/drivers/staging/lustre/lnet/klnds/o2iblnd/o2iblnd.c @@ -1538,7 +1538,7 @@ kiblnd_fmr_pool_unmap(kib_fmr_t *fmr, int status) fmr->fmr_pfmr = NULL; spin_lock(&fps->fps_lock); - fpo->fpo_map_count --; /* decref the pool */ + fpo->fpo_map_count--; /* decref the pool */ list_for_each_entry_safe(fpo, tmp, &fps->fps_pool_list, fpo_list) { /* the first pool is persistent */ @@ -1547,7 +1547,7 @@ kiblnd_fmr_pool_unmap(kib_fmr_t *fmr, int status) if (kiblnd_fmr_pool_is_idle(fpo, now)) { list_move(&fpo->fpo_list, &zombies); - fps->fps_version ++; + fps->fps_version++; } } spin_unlock(&fps->fps_lock); @@ -1752,7 +1752,7 @@ kiblnd_pool_free_node(kib_pool_t *pool, struct list_head *node) LASSERT (pool->po_allocated > 0); list_add(node, &pool->po_free_list); - pool->po_allocated --; + pool->po_allocated--; list_for_each_entry_safe(pool, tmp, &ps->ps_pool_list, po_list) { /* the first pool is persistent */ @@ -1781,7 +1781,7 @@ kiblnd_pool_alloc_node(kib_poolset_t *ps) if (list_empty(&pool->po_free_list)) continue; - pool->po_allocated ++; + pool->po_allocated++; pool->po_deadline = cfs_time_shift(IBLND_POOL_DEADLINE); node = pool->po_free_list.next; list_del(node); @@ -1864,7 +1864,7 @@ kiblnd_pmr_pool_map(kib_pmr_poolset_t *pps, kib_hca_dev_t *hdev, return -EAGAIN; } - for (i = 0; i < rd->rd_nfrags; i ++) { + for (i = 0; i < rd->rd_nfrags; i++) { pmr->pmr_ipb[i].addr = rd->rd_frags[i].rf_addr; pmr->pmr_ipb[i].size = rd->rd_frags[i].rf_nob; } @@ -2117,7 +2117,7 @@ kiblnd_tx_init(kib_pool_t *pool, struct list_head *node) tps_poolset); kib_tx_t *tx = list_entry(node, kib_tx_t, tx_list); - tx->tx_cookie = tps->tps_next_tx_cookie ++; + tx->tx_cookie = tps->tps_next_tx_cookie++; } static void @@ -2326,7 +2326,7 @@ kiblnd_hdev_get_attr(kib_hca_dev_t *hdev) } for (hdev->ibh_mr_shift = 0; -hdev->ibh_mr_shift < 64; hdev->ibh_mr_shift ++) { +hdev->ibh_mr_shift < 64; hdev->ibh_mr_shift++) { if (hdev->ibh_mr_size == (1ULL << hdev->ibh_mr_shift) || hdev->ibh_mr_size == (1ULL << hdev->ibh_mr_shift) - 1) return 0; -- 2.1.4 ___ devel mailing list de...@linuxdriverproject.org http://driverdev.linuxdriverproject.org/mailman/listinfo/driverdev-devel
Re: [PATCH 00/25] line6usb cleanup
At Sun, 11 Jan 2015 15:04:55 -0600, Chris Rorvick wrote: > > > At Fri, 9 Jan 2015 23:35:46 -0600, > > Chris Rorvick wrote: > >> > >> I have a TonePort UX2 that I've used for testing, meaning that some of > >> this is really only compile-tested. > > > > If anyone is responsible for testing with real hardware, I'll happily > > review. > > To be clear, the TonePort UX2 is real hardware. But this driver > basically supports four classes of Line 6 devices and I'm only covering > one of them. > > So this series is a first step in trying to address this. Having this > as a single driver probably made sense when it was a separate project, > but now that it is in-tree it seems like the POD, PODHD, TonePort, and > Variax pieces should each be separate drivers that each depend on a core > Line 6 driver. I think the cleanup in this series will make that > easier. None of this is my area of expertise, though, so advice and > feedback is very welcome. > > > are there any active developers for this driver? > > I intended to do further work. I know there is quite a bit of mundane > checkpatch cleanup that would need to get done before this could get > promoted, and I believe I read that it's using sysfs for stuff that > would normally be done via an ALSA interface, and the sysfs interface > has not been documented nor has it been justified. All stuff I thought > I might look into. > > But I'm just doing this for fun so I can't promise anything. :-) OK, so the situation looks fairly good, we have a few active developers and/or testers. And the current code doesn't look so terrible despite of it being in staging directory. That said, I think we can promote this stuff into sound/usb/line6 directory, then apply Chris' cleanup patches, and work on it further. Does it sound OK for you guys? Greg? Once when I get approval, I'll start a new clean branch on sound.git tree so that you guys can work on it further for 3.20 kernel. thanks, Takashi ___ devel mailing list de...@linuxdriverproject.org http://driverdev.linuxdriverproject.org/mailman/listinfo/driverdev-devel
[PATCH] staging: octeon: Fix checkpatch line spacing warnings
Fix missing blank lines after declarations in octeon/ethernet-rx.c Signed-off-by: Tero Marttila --- drivers/staging/octeon/ethernet-rx.c | 2 ++ 1 file changed, 2 insertions(+) diff --git a/drivers/staging/octeon/ethernet-rx.c b/drivers/staging/octeon/ethernet-rx.c index fcbe836..22667db 100644 --- a/drivers/staging/octeon/ethernet-rx.c +++ b/drivers/staging/octeon/ethernet-rx.c @@ -109,6 +109,7 @@ static inline int cvm_oct_check_rcv_error(cvmx_wqe_t *work) int interface = cvmx_helper_get_interface_num(work->ipprt); int index = cvmx_helper_get_interface_index_num(work->ipprt); union cvmx_gmxx_rxx_frm_ctl gmxx_rxx_frm_ctl; + gmxx_rxx_frm_ctl.u64 = cvmx_read_csr(CVMX_GMXX_RXX_FRM_CTL(index, interface)); if (gmxx_rxx_frm_ctl.s.pre_chk == 0) { @@ -214,6 +215,7 @@ static int cvm_oct_napi_poll(struct napi_struct *napi, int budget) did_work_request = 0; if (work == NULL) { union cvmx_pow_wq_int wq_int; + wq_int.u64 = 0; wq_int.s.iq_dis = 1 << pow_receive_group; wq_int.s.wq_int = 1 << pow_receive_group; -- 1.9.1 ___ devel mailing list de...@linuxdriverproject.org http://driverdev.linuxdriverproject.org/mailman/listinfo/driverdev-devel
[PATCH v3] Drivers: hv: vmbus: prevent cpu offlining on newer hypervisors
When an SMP Hyper-V guest is running on top of 2012R2 Server and secondary cpus are sent offline (with echo 0 > /sys/devices/system/cpu/cpu$cpu/online) the system freeze is observed. This happens due to the fact that on newer hypervisors (Win8, WS2012R2, ...) vmbus channel handlers are distributed across all cpus (see init_vp_index() function in drivers/hv/channel_mgmt.c) and on cpu offlining nobody reassigns them to CPU0. Prevent cpu offlining when vmbus is loaded until the issue is fixed host-side. This patch also disables hibernation but it is OK as it is also broken (MCE error is hit on resume). Suspend still works. Tested with WS2008R2 and WS2012R2. Signed-off-by: Vitaly Kuznetsov --- Changes since v2: - repair the build when vmbus is builded as a module [Greg KH] by saving current cpu_disable pointer to previous_cpu_disable and restoring it on unload; - return -ENOSYS (same as native_cpu_disable when !CONFIG_HOTPLUG_CPU) instead of -1 in hyperv_cpu_disable(). Changes since v1: - introduce hv_cpu_hotplug_quirk() function to not spread #ifdefs [Greg KH]; - add pr_notice() message "hv_vmbus: CPU offlining is not supported by hypervisor". --- drivers/hv/vmbus_drv.c | 36 1 file changed, 36 insertions(+) diff --git a/drivers/hv/vmbus_drv.c b/drivers/hv/vmbus_drv.c index 4d6b269..233da0b 100644 --- a/drivers/hv/vmbus_drv.c +++ b/drivers/hv/vmbus_drv.c @@ -32,6 +32,7 @@ #include #include #include +#include #include #include #include @@ -671,6 +672,39 @@ static void vmbus_isr(void) tasklet_schedule(&msg_dpc); } +#ifdef CONFIG_HOTPLUG_CPU +static int hyperv_cpu_disable(void) +{ + return -ENOSYS; +} + +static void hv_cpu_hotplug_quirk(bool vmbus_loaded) +{ + static void *previous_cpu_disable; + + /* +* Offlining a CPU when running on newer hypervisors (WS2012R2, Win8, +* ...) is not supported at this moment as channel interrupts are +* distributed across all of them. +*/ + + if ((vmbus_proto_version == VERSION_WS2008) || + (vmbus_proto_version == VERSION_WIN7)) + return; + + if (vmbus_loaded) { + previous_cpu_disable = smp_ops.cpu_disable; + smp_ops.cpu_disable = hyperv_cpu_disable; + pr_notice("CPU offlining is not supported by hypervisor\n"); + } else if (previous_cpu_disable) + smp_ops.cpu_disable = previous_cpu_disable; +} +#else +static void hv_cpu_hotplug_quirk(bool vmbus_loaded) +{ +} +#endif + /* * vmbus_bus_init -Main vmbus driver initialization routine. * @@ -711,6 +745,7 @@ static int vmbus_bus_init(int irq) if (ret) goto err_alloc; + hv_cpu_hotplug_quirk(true); vmbus_request_offers(); return 0; @@ -964,6 +999,7 @@ static void __exit vmbus_exit(void) bus_unregister(&hv_bus); hv_cleanup(); acpi_bus_unregister_driver(&vmbus_acpi_driver); + hv_cpu_hotplug_quirk(false); } -- 1.9.3 ___ devel mailing list de...@linuxdriverproject.org http://driverdev.linuxdriverproject.org/mailman/listinfo/driverdev-devel
[PATCH v2] Staging: vt6656: Checkpatch fix: else after break or return
This patch fixes the following checkpatch.pl error: rxtx.c:588: WARNING: else is not generally useful after a break or return Signed-off-by: Emrys Bayliss --- drivers/staging/vt6656/rxtx.c | 2 -- 1 file changed, 2 deletions(-) diff --git a/drivers/staging/vt6656/rxtx.c b/drivers/staging/vt6656/rxtx.c index ea5140a..0cce140 100644 --- a/drivers/staging/vt6656/rxtx.c +++ b/drivers/staging/vt6656/rxtx.c @@ -574,8 +574,6 @@ static u16 vnt_fill_cts_head(struct vnt_usb_send_context *tx_context, return vnt_rxtx_datahead_g(tx_context, &buf->data_head); } - - return 0; } static u16 vnt_rxtx_rts(struct vnt_usb_send_context *tx_context, -- 2.2.1 ___ devel mailing list de...@linuxdriverproject.org http://driverdev.linuxdriverproject.org/mailman/listinfo/driverdev-devel
Re: [PATCH v8 2/4] fpga manager: add sysfs interface document
On Mon, Jan 12, 2015 at 10:05:49AM -0600, Rob Herring wrote: > On Sun, Jan 11, 2015 at 10:29 AM, atull wrote: > > Previous uses of the firmware layer has been to use it to load once after > > bootup; this is different since some use cases will want to switch out > > the FPGA image. If someone wants there to be only one FPGA image on > > the FGPA forever, they will probably not be using this framework; their > > FPGA will probably be loaded before Linux boots up. > That's not really true. Some WiFi devices have to load different > firmware for client and AP modes and switching is a common usecase in > phones. Right, this is also very common for audio DSPs - the DSPs are frequently much smaller than the total set of firmware they might want to run so they need to switch at runtime. > There may be other instances of drivers wanting configurable firmware > names already. A common interface here would be nice. It could also be > useful to expose the firmware names such that you could generate a > list of all firmware files needed for a machine (that may already be > possible with uevents?). Some standard mechanism for enumerating the possible firmwares and switching between them would definitely make life easier on the audio side. It'd also be good for userspace to be able to say it's got new firmware to add to the list, but that's suggesting to me that the enumeration part of things might be better handled in userspace. signature.asc Description: Digital signature ___ devel mailing list de...@linuxdriverproject.org http://driverdev.linuxdriverproject.org/mailman/listinfo/driverdev-devel
Re: [PATCH 00/29] staging: add drivers from the fbtft project
> Here is a proposal to include in the staging tree the drivers from the > fbtft project at https://github.com/notro/fbtft. This project contains > a number of drivers small TFT LCD display modules, which are not > otherwise supported by the Linux kernel. This set of drivers appears > to be quite widely used in the RasberryPi community, and it's a shame > that they are not submitted to the upstream Linux kernel. > > This is for now just a raw import, with only minimal changes compared > to the upstream version: I have not tried to fix any coding style > issue, or make any other improvement. I have only verified that the > entire set of drivers was building fine, which I believe is the main > rule when it comes to get code added to the staging tree. > > Best regards, > > Thomas Petazzoni Hi, I'm the maintainer of the fbtft project. Even though I didn't know about this submission beforehand, I'm all for having this in staging. I didn't know about the staging tree, that drivers not meeting the strict Linux coding practices still could be included. Signed-off-by: Noralf Tronnes Previously this project was almost only used by the Raspberry Pi community, and some use on Beagle Bone Black, but in the last 6 months it has seen use on many more platforms (which I have lost count of). Not just ARM, but also Intel Edison and Galileo. In the same timeperiod there has been an explosion in display shields/capes for the Raspberry Pi using these drivers. I have also started to see fbtft being pulled into board specific kernel trees. Two months ago I started rewriting this project from scratch to make it a better fit for inclusion. Fbtft was the first kernel programming I did, so I have picked up a better understanding of the kernel since then. I have also a much better understanding of the differences and similarities between these LCD controllers, yielding better and cleaner abstractions. It will take some time to get it ready for review, and even more time to get the same controller/display coverage. I'm hoping to have something ready for review during this year, but since it's a for fun freetime project, it's hard to predict when it's ready. Status: https://github.com/notro/fbdbi/wiki Regards, Noralf Trønnes ___ devel mailing list de...@linuxdriverproject.org http://driverdev.linuxdriverproject.org/mailman/listinfo/driverdev-devel
[PATCH 12/37] staging: comedi: ni_at_a2150: introduce struct a2150_dma_desc
For aesthetics, introduce a struct to hold the DMA descriptor data. Signed-off-by: H Hartley Sweeten Cc: Ian Abbott Cc: Greg Kroah-Hartman --- drivers/staging/comedi/drivers/ni_at_a2150.c | 76 +++- 1 file changed, 41 insertions(+), 35 deletions(-) diff --git a/drivers/staging/comedi/drivers/ni_at_a2150.c b/drivers/staging/comedi/drivers/ni_at_a2150.c index de2e877..a1300e0 100644 --- a/drivers/staging/comedi/drivers/ni_at_a2150.c +++ b/drivers/staging/comedi/drivers/ni_at_a2150.c @@ -145,11 +145,15 @@ static const struct a2150_board a2150_boards[] = { }, }; +struct a2150_dma_desc { + unsigned int chan; /* DMA channel */ + uint16_t *virt_addr;/* virtual address of DMA buffer */ + unsigned int size; /* size of DMA transfer (in bytes) */ +}; + struct a2150_private { + struct a2150_dma_desc dma_desc; unsigned int count; /* number of data points left to be taken */ - unsigned int dma; /* dma channel */ - uint16_t *dma_buffer; /* dma buffer */ - unsigned int dma_transfer_size; /* size in bytes of dma transfers */ int irq_dma_bits; /* irq/dma register bits */ int config_bits;/* config register bits */ }; @@ -162,6 +166,7 @@ static irqreturn_t a2150_interrupt(int irq, void *d) unsigned long flags; struct comedi_device *dev = d; struct a2150_private *devpriv = dev->private; + struct a2150_dma_desc *dma = &devpriv->dma_desc; struct comedi_subdevice *s = dev->read_subdev; struct comedi_async *async; struct comedi_cmd *cmd; @@ -198,18 +203,18 @@ static irqreturn_t a2150_interrupt(int irq, void *d) } flags = claim_dma_lock(); - disable_dma(devpriv->dma); + disable_dma(dma->chan); /* clear flip-flop to make sure 2-byte registers for * count and address get set correctly */ - clear_dma_ff(devpriv->dma); + clear_dma_ff(dma->chan); /* figure out how many points to read */ - max_points = comedi_bytes_to_samples(s, devpriv->dma_transfer_size); + max_points = comedi_bytes_to_samples(s, dma->size); /* residue is the number of points left to be done on the dma * transfer. It should always be zero at this point unless * the stop_src is set to external triggering. */ - residue = comedi_bytes_to_samples(s, get_dma_residue(devpriv->dma)); + residue = comedi_bytes_to_samples(s, get_dma_residue(dma->chan)); num_points = max_points - residue; if (devpriv->count < num_points && cmd->stop_src == TRIG_COUNT) num_points = devpriv->count; @@ -217,8 +222,7 @@ static irqreturn_t a2150_interrupt(int irq, void *d) /* figure out how many points will be stored next time */ leftover = 0; if (cmd->stop_src == TRIG_NONE) { - leftover = comedi_bytes_to_samples(s, - devpriv->dma_transfer_size); + leftover = comedi_bytes_to_samples(s, dma->size); } else if (devpriv->count > max_points) { leftover = devpriv->count - max_points; if (leftover > max_points) @@ -233,7 +237,7 @@ static irqreturn_t a2150_interrupt(int irq, void *d) for (i = 0; i < num_points; i++) { /* write data point to comedi buffer */ - dpnt = devpriv->dma_buffer[i]; + dpnt = dma->virt_addr[i]; /* convert from 2's complement to unsigned coding */ dpnt ^= 0x8000; comedi_buf_write_samples(s, &dpnt, 1); @@ -246,10 +250,10 @@ static irqreturn_t a2150_interrupt(int irq, void *d) } /* re-enable dma */ if (leftover) { - set_dma_addr(devpriv->dma, virt_to_bus(devpriv->dma_buffer)); - set_dma_count(devpriv->dma, + set_dma_addr(dma->chan, virt_to_bus(dma->virt_addr)); + set_dma_count(dma->chan, comedi_samples_to_bytes(s, leftover)); - enable_dma(devpriv->dma); + enable_dma(dma->chan); } release_dma_lock(flags); @@ -264,13 +268,14 @@ static irqreturn_t a2150_interrupt(int irq, void *d) static int a2150_cancel(struct comedi_device *dev, struct comedi_subdevice *s) { struct a2150_private *devpriv = dev->private; + struct a2150_dma_desc *dma = &devpriv->dma_desc; /* disable dma on card */ devpriv->irq_dma_bits &= ~DMA_INTR_EN_BIT & ~DMA_EN_BIT; outw(devpriv->irq_dma_bits, dev->iobase + IRQ_DMA_CNTRL_REG); /* disable computer's dma */ - disable_dma(devpriv->dma); + disable_dma(dma->chan); /* clear fifo and reset triggering circuitry */ outw(0, dev->iobase + FIFO_RESET_REG); @@ -502,6 +507,7 @@ static int a2150_ai_cmdtest(struct comedi_device *dev, static in
[PATCH 19/37] staging: comedi: pcl818: introduce struct pcl818_dma_desc
For aesthetics, introduce a struct to hold the DMA descriptor data. Signed-off-by: H Hartley Sweeten Cc: Ian Abbott Cc: Greg Kroah-Hartman --- drivers/staging/comedi/drivers/pcl818.c | 44 +++-- 1 file changed, 25 insertions(+), 19 deletions(-) diff --git a/drivers/staging/comedi/drivers/pcl818.c b/drivers/staging/comedi/drivers/pcl818.c index beb03ec..f34c5cc0 100644 --- a/drivers/staging/comedi/drivers/pcl818.c +++ b/drivers/staging/comedi/drivers/pcl818.c @@ -302,13 +302,17 @@ static const struct pcl818_board boardtypes[] = { }, }; +struct pcl818_dma_desc { + unsigned long dmabuf; /* pointers to begin of DMA buffers */ + unsigned int hwdmaptr; /* hardware address of DMA buffers */ +}; + struct pcl818_private { unsigned int dma; /* used DMA, 0=don't use DMA */ unsigned int dmapages; unsigned int hwdmasize; - unsigned long dmabuf[2];/* pointers to begin of DMA buffers */ - unsigned int hwdmaptr[2]; /* hardware address of DMA buffers */ - int next_dma_buf; /* which DMA buffer will be used next round */ + struct pcl818_dma_desc dma_desc[2]; + int cur_dma; long dma_runs_to_end; /* how many we must permorm DMA transfer to end of record */ unsigned long last_dma_run; /* how many bytes we must transfer on last DMA page */ unsigned int ns_min;/* manimal allowed delay between samples (in us) for actual card */ @@ -343,6 +347,7 @@ static void pcl818_ai_setup_dma(struct comedi_device *dev, struct comedi_subdevice *s) { struct pcl818_private *devpriv = dev->private; + struct pcl818_dma_desc *dma = &devpriv->dma_desc[0]; struct comedi_cmd *cmd = &s->async->cmd; unsigned int flags; unsigned int bytes; @@ -358,11 +363,11 @@ static void pcl818_ai_setup_dma(struct comedi_device *dev, bytes = devpriv->hwdmasize; } - devpriv->next_dma_buf = 0; + devpriv->cur_dma = 0; set_dma_mode(devpriv->dma, DMA_MODE_READ); flags = claim_dma_lock(); clear_dma_ff(devpriv->dma); - set_dma_addr(devpriv->dma, devpriv->hwdmaptr[0]); + set_dma_addr(devpriv->dma, dma->hwdmaptr); set_dma_count(devpriv->dma, bytes); release_dma_lock(flags); enable_dma(devpriv->dma); @@ -373,16 +378,17 @@ static void pcl818_ai_setup_next_dma(struct comedi_device *dev, { struct pcl818_private *devpriv = dev->private; struct comedi_cmd *cmd = &s->async->cmd; + struct pcl818_dma_desc *dma; unsigned long flags; disable_dma(devpriv->dma); - devpriv->next_dma_buf = 1 - devpriv->next_dma_buf; + devpriv->cur_dma = 1 - devpriv->cur_dma; if (devpriv->dma_runs_to_end > -1 || cmd->stop_src == TRIG_NONE) { /* switch dma bufs */ + dma = &devpriv->dma_desc[devpriv->cur_dma]; set_dma_mode(devpriv->dma, DMA_MODE_READ); flags = claim_dma_lock(); - set_dma_addr(devpriv->dma, -devpriv->hwdmaptr[devpriv->next_dma_buf]); + set_dma_addr(devpriv->dma, dma->hwdmaptr); if (devpriv->dma_runs_to_end || cmd->stop_src == TRIG_NONE) set_dma_count(devpriv->dma, devpriv->hwdmasize); else @@ -558,15 +564,14 @@ static void pcl818_handle_dma(struct comedi_device *dev, struct comedi_subdevice *s) { struct pcl818_private *devpriv = dev->private; - unsigned short *ptr; + struct pcl818_dma_desc *dma = &devpriv->dma_desc[devpriv->cur_dma]; + unsigned short *ptr = (unsigned short *)dma->dmabuf; unsigned int chan; unsigned int val; int i, len, bufptr; pcl818_ai_setup_next_dma(dev, s); - ptr = (unsigned short *)devpriv->dmabuf[1 - devpriv->next_dma_buf]; - len = devpriv->hwdmasize >> 1; bufptr = 0; @@ -1057,6 +1062,7 @@ static void pcl818_set_ai_range_table(struct comedi_device *dev, static int pcl818_alloc_dma(struct comedi_device *dev, unsigned int dma_chan) { struct pcl818_private *devpriv = dev->private; + struct pcl818_dma_desc *dma; int i; if (!(dma_chan == 3 || dma_chan == 1)) @@ -1070,14 +1076,12 @@ static int pcl818_alloc_dma(struct comedi_device *dev, unsigned int dma_chan) devpriv->hwdmasize = (1 << devpriv->dmapages) * PAGE_SIZE; for (i = 0; i < 2; i++) { - unsigned long dmabuf; + dma = &devpriv->dma_desc[i]; - dmabuf = __get_dma_pages(GFP_KERNEL, devpriv->dmapages); - if (!dmabuf) + dma->dmabuf = __get_dma_pages(GFP_KERNEL, devpriv->dmapages); + if (!dma->dmabuf) return -ENOMEM; - - devpriv->dmabuf[i] = dmabuf; -
[PATCH 22/37] staging: comedi: pcl816: introduce pcl816_alloc_dma()
The IRA and DMA are optional with this driver but both are required to support async commands. Introduce a helper function to request the IRQ and DMA channel and allocate the buffers. Don't fail the driver attach if the user passed an invalid IRQ or DMA channel or they cannot be requested. Signed-off-by: H Hartley Sweeten Cc: Ian Abbott Cc: Greg Kroah-Hartman --- drivers/staging/comedi/drivers/pcl816.c | 91 - 1 file changed, 56 insertions(+), 35 deletions(-) diff --git a/drivers/staging/comedi/drivers/pcl816.c b/drivers/staging/comedi/drivers/pcl816.c index 73deb4b..0374f83 100644 --- a/drivers/staging/comedi/drivers/pcl816.c +++ b/drivers/staging/comedi/drivers/pcl816.c @@ -657,13 +657,59 @@ static void pcl816_reset(struct comedi_device *dev) outb(0, dev->iobase + PCL816_DO_DI_MSB_REG); } +static int pcl816_alloc_dma(struct comedi_device *dev, + unsigned int irq_num, unsigned int dma_chan) +{ + struct pcl816_private *devpriv = dev->private; + int i; + + /* +* Only IRQs 2-7 are valid. +* Only DMA channels 3 and 1 are valid. +* +* Both must be valid for async command support. +*/ + if (!(irq_num >= 2 && irq_num <= 7) || + !(dma_chan == 3 || dma_chan == 1)) + return 0; + + /* +* Request the IRQ and DMA channels and allocate the DMA buffers. +* If the requests or allocations fail async command supprt will +* not be available. +*/ + if (request_irq(irq_num, pcl816_interrupt, 0, dev->board_name, dev)) + return 0; + if (request_dma(dma_chan, dev->board_name)) { + free_irq(irq_num, dev); + return 0; + } + + dev->irq = irq_num; + devpriv->dma = dma_chan; + + devpriv->dmapages = 2; /* we need 16KB */ + devpriv->hwdmasize = (1 << devpriv->dmapages) * PAGE_SIZE; + + for (i = 0; i < 2; i++) { + unsigned long dmabuf; + + dmabuf = __get_dma_pages(GFP_KERNEL, devpriv->dmapages); + if (!dmabuf) + return -ENOMEM; + + devpriv->dmabuf[i] = dmabuf; + devpriv->hwdmaptr[i] = virt_to_bus((void *)dmabuf); + } + return 0; +} + static int pcl816_attach(struct comedi_device *dev, struct comedi_devconfig *it) { const struct pcl816_board *board = dev->board_ptr; struct pcl816_private *devpriv; struct comedi_subdevice *s; int ret; - int i; devpriv = comedi_alloc_devpriv(dev, sizeof(*devpriv)); if (!devpriv) @@ -673,39 +719,14 @@ static int pcl816_attach(struct comedi_device *dev, struct comedi_devconfig *it) if (ret) return ret; - /* we can use IRQ 2-7 for async command support */ - if (it->options[1] >= 2 && it->options[1] <= 7) { - ret = request_irq(it->options[1], pcl816_interrupt, 0, - dev->board_name, dev); - if (ret == 0) - dev->irq = it->options[1]; - } - - /* we need an IRQ to do DMA on channel 3 or 1 */ - if (dev->irq && (it->options[2] == 3 || it->options[2] == 1)) { - ret = request_dma(it->options[2], dev->board_name); - if (ret) { - dev_err(dev->class_dev, - "unable to request DMA channel %d\n", - it->options[2]); - return -EBUSY; - } - devpriv->dma = it->options[2]; - - devpriv->dmapages = 2; /* we need 16KB */ - devpriv->hwdmasize = (1 << devpriv->dmapages) * PAGE_SIZE; - - for (i = 0; i < 2; i++) { - unsigned long dmabuf; - - dmabuf = __get_dma_pages(GFP_KERNEL, devpriv->dmapages); - if (!dmabuf) - return -ENOMEM; - - devpriv->dmabuf[i] = dmabuf; - devpriv->hwdmaptr[i] = virt_to_bus((void *)dmabuf); - } - } + /* +* An IRQ and DMA are required to support async commands. +* pcl816_alloc_dma() will only fail if the DMA buffers +* cannot be allocated. +*/ + ret = pcl816_alloc_dma(dev, it->options[1], it->options[2]); + if (ret) + return ret; ret = comedi_alloc_subdevices(dev, 4); if (ret) @@ -718,7 +739,7 @@ static int pcl816_attach(struct comedi_device *dev, struct comedi_devconfig *it) s->maxdata = board->ai_maxdata; s->range_table = &range_pcl816; s->insn_read= pcl816_ai_insn_read; - if (devpriv->dma) { + if (dev->irq) { dev->read_subdev = s; s->subdev_flags |= SDF_CMD_READ; s->len_chanlist = board->ai_chanl
[PATCH 08/37] staging: comedi: ni_at_a2150: remove 'volatile' from private data variable
As indicated by checkpatch.pl, "WARNING: Use of volatile is usually wrong: ...", the 'count' member of the private data does not need to be volatile. Signed-off-by: H Hartley Sweeten Cc: Ian Abbott Cc: Greg Kroah-Hartman --- drivers/staging/comedi/drivers/ni_at_a2150.c | 3 +-- 1 file changed, 1 insertion(+), 2 deletions(-) diff --git a/drivers/staging/comedi/drivers/ni_at_a2150.c b/drivers/staging/comedi/drivers/ni_at_a2150.c index 69e543a..8265322 100644 --- a/drivers/staging/comedi/drivers/ni_at_a2150.c +++ b/drivers/staging/comedi/drivers/ni_at_a2150.c @@ -146,8 +146,7 @@ static const struct a2150_board a2150_boards[] = { }; struct a2150_private { - - volatile unsigned int count;/* number of data points left to be taken */ + unsigned int count; /* number of data points left to be taken */ unsigned int dma; /* dma channel */ uint16_t *dma_buffer; /* dma buffer */ unsigned int dma_transfer_size; /* size in bytes of dma transfers */ -- 2.0.3 ___ devel mailing list de...@linuxdriverproject.org http://driverdev.linuxdriverproject.org/mailman/listinfo/driverdev-devel
[PATCH 01/37] staging: comedi: adl_pci9118: remove VIRT_TO_BUS dependancy
This driver no longer uses virt_to_bus(). Remove the dependancy. Signed-off-by: H Hartley Sweeten Cc: Ian Abbott Cc: Greg Kroah-Hartman --- drivers/staging/comedi/Kconfig | 1 - 1 file changed, 1 deletion(-) diff --git a/drivers/staging/comedi/Kconfig b/drivers/staging/comedi/Kconfig index a8201fe..1cdbf1f 100644 --- a/drivers/staging/comedi/Kconfig +++ b/drivers/staging/comedi/Kconfig @@ -724,7 +724,6 @@ config COMEDI_ADL_PCI9111 config COMEDI_ADL_PCI9118 tristate "ADLink PCI-9118DG, PCI-9118HG, PCI-9118HR support" depends on HAS_DMA - depends on VIRT_TO_BUS ---help--- Enable support for ADlink PCI-9118DG, PCI-9118HG, PCI-9118HR cards -- 2.0.3 ___ devel mailing list de...@linuxdriverproject.org http://driverdev.linuxdriverproject.org/mailman/listinfo/driverdev-devel
[PATCH 27/37] staging: comedi: pcl812: introduce pcl812_alloc_dma()
DMA is optional with this driver. Introduce a helper function to request the DMA channel and allocate the buffers. Don't fail the driver attach if the user passed an invalid DMA channel or the channel cannot be requested. Signed-off-by: H Hartley Sweeten Cc: Ian Abbott Cc: Greg Kroah-Hartman --- drivers/staging/comedi/drivers/pcl812.c | 57 ++--- 1 file changed, 32 insertions(+), 25 deletions(-) diff --git a/drivers/staging/comedi/drivers/pcl812.c b/drivers/staging/comedi/drivers/pcl812.c index ac243ca..38cf14e 100644 --- a/drivers/staging/comedi/drivers/pcl812.c +++ b/drivers/staging/comedi/drivers/pcl812.c @@ -1192,6 +1192,34 @@ static void pcl812_set_ai_range_table(struct comedi_device *dev, } } +static int pcl812_alloc_dma(struct comedi_device *dev, unsigned int dma_chan) +{ + struct pcl812_private *devpriv = dev->private; + int i; + + if (!(dma_chan == 3 || dma_chan == 1)) + return 0; + + if (request_dma(dma_chan, dev->board_name)) + return 0; + devpriv->dma = dma_chan; + + devpriv->dmapages = 1; /* we want 8KB */ + devpriv->hwdmasize = (1 << devpriv->dmapages) * PAGE_SIZE; + + for (i = 0; i < 2; i++) { + unsigned long dmabuf; + + dmabuf = __get_dma_pages(GFP_KERNEL, devpriv->dmapages); + if (!dmabuf) + return -ENOMEM; + + devpriv->dmabuf[i] = dmabuf; + devpriv->hwdmaptr[i] = virt_to_bus((void *)dmabuf); + } + return 0; +} + static int pcl812_attach(struct comedi_device *dev, struct comedi_devconfig *it) { const struct pcl812_board *board = dev->board_ptr; @@ -1200,7 +1228,6 @@ static int pcl812_attach(struct comedi_device *dev, struct comedi_devconfig *it) int n_subdevices; int subdev; int ret; - int i; devpriv = comedi_alloc_devpriv(dev, sizeof(*devpriv)); if (!devpriv) @@ -1218,30 +1245,10 @@ static int pcl812_attach(struct comedi_device *dev, struct comedi_devconfig *it) } /* we need an IRQ to do DMA on channel 3 or 1 */ - if (dev->irq && board->has_dma && - (it->options[2] == 3 || it->options[2] == 1)) { - ret = request_dma(it->options[2], dev->board_name); - if (ret) { - dev_err(dev->class_dev, - "unable to request DMA channel %d\n", - it->options[2]); - return -EBUSY; - } - devpriv->dma = it->options[2]; - - devpriv->dmapages = 1; /* we want 8KB */ - devpriv->hwdmasize = (1 << devpriv->dmapages) * PAGE_SIZE; - - for (i = 0; i < 2; i++) { - unsigned long dmabuf; - - dmabuf = __get_dma_pages(GFP_KERNEL, devpriv->dmapages); - if (!dmabuf) - return -ENOMEM; - - devpriv->dmabuf[i] = dmabuf; - devpriv->hwdmaptr[i] = virt_to_bus((void *)dmabuf); - } + if (dev->irq && board->has_dma) { + ret = pcl812_alloc_dma(dev, it->options[2]); + if (ret) + return ret; } /* differential analog inputs? */ -- 2.0.3 ___ devel mailing list de...@linuxdriverproject.org http://driverdev.linuxdriverproject.org/mailman/listinfo/driverdev-devel
[PATCH 00/37] staging: comedi: tidy up legacy DMA drivers
This series removes all the VIRT_TO_BUS dependancies from the legacy comedi drivers. It also tidies up the allocation and freeing of the DMA and the buffers used for DMA. H Hartley Sweeten (37): staging: comedi: adl_pci9118: remove VIRT_TO_BUS dependancy staging: comedi: das1800: reduce indent level of das1800_init_dma() staging: comedi: das1800: separate AI FIFO bounce buffer from DMA buffer staging: comedi: das1800: introduce struct das1800_dma_desc staging: comedi: das1800: tidy up das1800_init_dma() staging: comedi: das1800: remove VIRT_TO_BUS dependancy staging: comedi: das1800: introduce das1800_free_dma() staging: comedi: ni_at_a2150: remove 'volatile' from private data variable staging: comedi: ni_at_a2150: use comedi_bytes_per_sample() staging: comedi: ni_at_a2150: introduce a2150_alloc_irq_dma() staging: comedi: ni_at_a2150: introduce a2150_free_dma() staging: comedi: ni_at_a2150: introduce struct a2150_dma_desc staging: comedi: ni_at_a2150: remove VIRT_TO_BUS dependancy staging: comedi: ni_labpc: introduce struct labpc_dma_desc staging: comedi: ni_labpc_isadma: tidy up labpc_init_dma_chan() staging: comedi: ni_labpc: remove VIRT_TO_BUS dependancy staging: comedi: pcl818: introduce pcl818_alloc_dma() staging: comedi: pcl818: introduce pcl818_dma_free() staging: comedi: pcl818: introduce struct pcl818_dma_desc staging: comedi: pcl818: remove VIRT_TO_BUS dependancy staging: comedi: pcl818: fix pcl818_handle_dma() for short DMA transaction staging: comedi: pcl816: introduce pcl816_alloc_dma() staging: comedi: pcl816: introduce pcl816_free_dma() staging: comedi: pcl816: introduce struct pcl816_dma_desc staging: comedi: pcl816: remove VIRT_TO_BUS dependancy staging: comedi: pcl816: fix short DMA transactions staging: comedi: pcl812: introduce pcl812_alloc_dma() staging: comedi: pcl812: introduce pcl812_free_dma() staging: comedi: pcl812: introduce struct pcl812_dma_desc staging: comedi: pcl812: remove VIRT_TO_BUS dependancy staging: comedi: dt282x: introduce dt282x_alloc_dma() staging: comedi: dt282x: introduce struct dt282x_dma_desc staging: comedi: dt282x: remove VIRT_TO_BUS dependancy staging: comedi: das16: introduce struct das16_dma_desc staging: comedi: das16 introduce das16_alloc_dma() staging: comedi: das16: introduce das16_free_dma() staging: comedi: das16: board is not a PCI device drivers/staging/comedi/Kconfig | 15 +- drivers/staging/comedi/drivers/das16.c | 134 ++-- drivers/staging/comedi/drivers/das1800.c | 265 --- drivers/staging/comedi/drivers/dt282x.c | 190 drivers/staging/comedi/drivers/ni_at_a2150.c | 164 -- drivers/staging/comedi/drivers/ni_labpc.h| 15 +- drivers/staging/comedi/drivers/ni_labpc_isadma.c | 80 --- drivers/staging/comedi/drivers/ni_labpc_isadma.h | 9 +- drivers/staging/comedi/drivers/pcl812.c | 170 --- drivers/staging/comedi/drivers/pcl816.c | 183 +--- drivers/staging/comedi/drivers/pcl818.c | 143 +++- 11 files changed, 743 insertions(+), 625 deletions(-) -- 2.0.3 ___ devel mailing list de...@linuxdriverproject.org http://driverdev.linuxdriverproject.org/mailman/listinfo/driverdev-devel
[PATCH 30/37] staging: comedi: pcl812: remove VIRT_TO_BUS dependancy
Use dma_{alloc,free}_coherent() to allocate and free the DMA buffers. This removes the dependancy on VIRT_TO_BUS. Signed-off-by: H Hartley Sweeten Cc: Ian Abbott Cc: Greg Kroah-Hartman --- drivers/staging/comedi/Kconfig | 2 +- drivers/staging/comedi/drivers/pcl812.c | 20 +--- 2 files changed, 10 insertions(+), 12 deletions(-) diff --git a/drivers/staging/comedi/Kconfig b/drivers/staging/comedi/Kconfig index 59c17e6..4441600 100644 --- a/drivers/staging/comedi/Kconfig +++ b/drivers/staging/comedi/Kconfig @@ -168,7 +168,7 @@ config COMEDI_PCL730 config COMEDI_PCL812 tristate "Advantech PCL-812/813 and ADlink ACL-8112/8113/8113/8216" - depends on VIRT_TO_BUS && ISA_DMA_API + depends on ISA_DMA_API ---help--- Enable support for Advantech PCL-812/PG, PCL-813/B, ADLink ACL-8112DG/HG/PG, ACL-8113, ACL-8216, ICP DAS A-821PGH/PGL/PGL-NDA, diff --git a/drivers/staging/comedi/drivers/pcl812.c b/drivers/staging/comedi/drivers/pcl812.c index d9f94c9..2c2e7dd 100644 --- a/drivers/staging/comedi/drivers/pcl812.c +++ b/drivers/staging/comedi/drivers/pcl812.c @@ -507,8 +507,8 @@ static const struct pcl812_board boardtypes[] = { }; struct pcl812_dma_desc { - unsigned long virt_addr;/* virtual address of DMA buffer */ - unsigned int hw_addr; /* hardware (bus) address of DMA buffer */ + void *virt_addr;/* virtual address of DMA buffer */ + dma_addr_t hw_addr; /* hardware (bus) address of DMA buffer */ unsigned int size; /* transfer size (in bytes) */ }; @@ -518,7 +518,6 @@ struct pcl812_private { unsigned int last_ai_chanspec; unsigned char mode_reg_int; /* there is stored INT number for some card */ unsigned int ai_poll_ptr; /* how many sampes transfer poll */ - unsigned int dmapages; unsigned int hwdmasize; struct pcl812_dma_desc dma_desc[2]; int cur_dma; @@ -905,7 +904,7 @@ static void pcl812_handle_dma(struct comedi_device *dev, bufptr = devpriv->ai_poll_ptr; devpriv->ai_poll_ptr = 0; - transfer_from_dma_buf(dev, s, (void *)dma->virt_addr, bufptr, nsamples); + transfer_from_dma_buf(dev, s, dma->virt_addr, bufptr, nsamples); } static irqreturn_t pcl812_interrupt(int irq, void *d) @@ -964,7 +963,7 @@ static int pcl812_ai_poll(struct comedi_device *dev, struct comedi_subdevice *s) return 0; } - transfer_from_dma_buf(dev, s, (void *)dma->virt_addr, + transfer_from_dma_buf(dev, s, dma->virt_addr, devpriv->ai_poll_ptr, top2); devpriv->ai_poll_ptr = top1;/* new buffer position */ @@ -1203,17 +1202,15 @@ static int pcl812_alloc_dma(struct comedi_device *dev, unsigned int dma_chan) return 0; devpriv->dma = dma_chan; - devpriv->dmapages = 1; /* we want 8KB */ - devpriv->hwdmasize = (1 << devpriv->dmapages) * PAGE_SIZE; + devpriv->hwdmasize = PAGE_SIZE * 2; /* we want 8KB */ for (i = 0; i < 2; i++) { dma = &devpriv->dma_desc[i]; - dma->virt_addr = __get_dma_pages(GFP_KERNEL, devpriv->dmapages); + dma->virt_addr = dma_alloc_coherent(NULL, devpriv->hwdmasize, + &dma->hw_addr, GFP_KERNEL); if (!dma->virt_addr) return -ENOMEM; - - dma->hw_addr = virt_to_bus((void *)dma->virt_addr); } return 0; } @@ -1230,7 +1227,8 @@ static void pcl812_free_dma(struct comedi_device *dev) for (i = 0; i < 2; i++) { dma = &devpriv->dma_desc[i]; if (dma->virt_addr) - free_pages(dma->virt_addr, devpriv->dmapages); + dma_free_coherent(NULL, devpriv->hwdmasize, + dma->virt_addr, dma->hw_addr); } if (devpriv->dma) free_dma(devpriv->dma); -- 2.0.3 ___ devel mailing list de...@linuxdriverproject.org http://driverdev.linuxdriverproject.org/mailman/listinfo/driverdev-devel
[PATCH 09/37] staging: comedi: ni_at_a2150: use comedi_bytes_per_sample()
From: H Hartley Sweeten For aesthetics, use the helper function to get the byte size of each sample instead of using sizeof() the first buffer element. Signed-off-by: H Hartley Sweeten Cc: Ian Abbott Cc: Greg Kroah-Hartman --- drivers/staging/comedi/drivers/ni_at_a2150.c | 8 1 file changed, 4 insertions(+), 4 deletions(-) diff --git a/drivers/staging/comedi/drivers/ni_at_a2150.c b/drivers/staging/comedi/drivers/ni_at_a2150.c index 8265322..7380dac 100644 --- a/drivers/staging/comedi/drivers/ni_at_a2150.c +++ b/drivers/staging/comedi/drivers/ni_at_a2150.c @@ -551,14 +551,14 @@ static int a2150_ai_cmd(struct comedi_device *dev, struct comedi_subdevice *s) /* set size of transfer to fill in 1/3 second */ #define ONE_THIRD_SECOND 3 devpriv->dma_transfer_size = - sizeof(devpriv->dma_buffer[0]) * cmd->chanlist_len * + comedi_bytes_per_sample(s) * cmd->chanlist_len * ONE_THIRD_SECOND / cmd->scan_begin_arg; if (devpriv->dma_transfer_size > A2150_DMA_BUFFER_SIZE) devpriv->dma_transfer_size = A2150_DMA_BUFFER_SIZE; - if (devpriv->dma_transfer_size < sizeof(devpriv->dma_buffer[0])) - devpriv->dma_transfer_size = sizeof(devpriv->dma_buffer[0]); + if (devpriv->dma_transfer_size < comedi_bytes_per_sample(s)) + devpriv->dma_transfer_size = comedi_bytes_per_sample(s); devpriv->dma_transfer_size -= - devpriv->dma_transfer_size % sizeof(devpriv->dma_buffer[0]); + devpriv->dma_transfer_size % comedi_bytes_per_sample(s); set_dma_count(devpriv->dma, devpriv->dma_transfer_size); enable_dma(devpriv->dma); release_dma_lock(lock_flags); -- 2.0.3 ___ devel mailing list de...@linuxdriverproject.org http://driverdev.linuxdriverproject.org/mailman/listinfo/driverdev-devel
[PATCH 23/37] staging: comedi: pcl816: introduce pcl816_free_dma()
For aesthetics, move the freeing of the DMA channel and the buffers to a helper function. Signed-off-by: H Hartley Sweeten Cc: Ian Abbott Cc: Greg Kroah-Hartman --- drivers/staging/comedi/drivers/pcl816.c | 25 + 1 file changed, 17 insertions(+), 8 deletions(-) diff --git a/drivers/staging/comedi/drivers/pcl816.c b/drivers/staging/comedi/drivers/pcl816.c index 0374f83..4cff02a 100644 --- a/drivers/staging/comedi/drivers/pcl816.c +++ b/drivers/staging/comedi/drivers/pcl816.c @@ -704,6 +704,22 @@ static int pcl816_alloc_dma(struct comedi_device *dev, return 0; } +static void pcl816_free_dma(struct comedi_device *dev) +{ + struct pcl816_private *devpriv = dev->private; + int i; + + if (!devpriv) + return; + + if (devpriv->dma) + free_dma(devpriv->dma); + for (i = 0; i < 2; i++) { + if (devpriv->dmabuf[i]) + free_pages(devpriv->dmabuf[i], devpriv->dmapages); + } +} + static int pcl816_attach(struct comedi_device *dev, struct comedi_devconfig *it) { const struct pcl816_board *board = dev->board_ptr; @@ -785,18 +801,11 @@ static int pcl816_attach(struct comedi_device *dev, struct comedi_devconfig *it) static void pcl816_detach(struct comedi_device *dev) { - struct pcl816_private *devpriv = dev->private; - if (dev->private) { pcl816_ai_cancel(dev, dev->read_subdev); pcl816_reset(dev); - if (devpriv->dma) - free_dma(devpriv->dma); - if (devpriv->dmabuf[0]) - free_pages(devpriv->dmabuf[0], devpriv->dmapages); - if (devpriv->dmabuf[1]) - free_pages(devpriv->dmabuf[1], devpriv->dmapages); } + pcl816_free_dma(dev); comedi_legacy_detach(dev); } -- 2.0.3 ___ devel mailing list de...@linuxdriverproject.org http://driverdev.linuxdriverproject.org/mailman/listinfo/driverdev-devel
[PATCH 33/37] staging: comedi: dt282x: remove VIRT_TO_BUS dependancy
Use dma_{alloc,free}_coherent() to allocate and free the DMA buffers. This removes the dependancy on VIRT_TO_BUS. Signed-off-by: H Hartley Sweeten Cc: Ian Abbott Cc: Greg Kroah-Hartman --- drivers/staging/comedi/Kconfig | 2 +- drivers/staging/comedi/drivers/dt282x.c | 13 - 2 files changed, 9 insertions(+), 6 deletions(-) diff --git a/drivers/staging/comedi/Kconfig b/drivers/staging/comedi/Kconfig index 4441600..37f33c4 100644 --- a/drivers/staging/comedi/Kconfig +++ b/drivers/staging/comedi/Kconfig @@ -372,7 +372,7 @@ config COMEDI_DT2817 config COMEDI_DT282X tristate "Data Translation DT2821 series and DT-EZ ISA card support" - depends on VIRT_TO_BUS && ISA_DMA_API + depends on ISA_DMA_API ---help--- Enable support for Data Translation DT2821 series including DT-EZ DT2821, DT2821-F-16SE, DT2821-F-8DI, DT2821-G-16SE, DT2821-G-8DI, diff --git a/drivers/staging/comedi/drivers/dt282x.c b/drivers/staging/comedi/drivers/dt282x.c index 8ee6186..f24ad66 100644 --- a/drivers/staging/comedi/drivers/dt282x.c +++ b/drivers/staging/comedi/drivers/dt282x.c @@ -302,7 +302,8 @@ static const struct dt282x_board boardtypes[] = { struct dt282x_dma_desc { unsigned int chan; /* DMA channel */ - unsigned short *virt_addr; /* virtual address of DMA buffer */ + void *virt_addr;/* virtual address of DMA buffer */ + dma_addr_t hw_addr; /* hardware (bus) address of DMA buffer */ unsigned int size; /* transfer size (in bytes) */ }; @@ -344,7 +345,7 @@ static int dt282x_prep_ai_dma(struct comedi_device *dev, int dma_index, int n) set_dma_mode(dma->chan, DMA_MODE_READ); flags = claim_dma_lock(); clear_dma_ff(dma->chan); - set_dma_addr(dma->chan, virt_to_bus(dma->virt_addr)); + set_dma_addr(dma->chan, dma->hw_addr); set_dma_count(dma->chan, dma->size); release_dma_lock(flags); @@ -364,7 +365,7 @@ static int dt282x_prep_ao_dma(struct comedi_device *dev, int dma_index, int n) set_dma_mode(dma->chan, DMA_MODE_WRITE); flags = claim_dma_lock(); clear_dma_ff(dma->chan); - set_dma_addr(dma->chan, virt_to_bus(dma->virt_addr)); + set_dma_addr(dma->chan, dma->hw_addr); set_dma_count(dma->chan, dma->size); release_dma_lock(flags); @@ -1087,7 +1088,8 @@ static int dt282x_alloc_dma(struct comedi_device *dev, struct dt282x_dma_desc *dma = &devpriv->dma_desc[i]; dma->chan = dma_chan[i]; - dma->virt_addr = (void *)__get_free_page(GFP_KERNEL | GFP_DMA); + dma->virt_addr = dma_alloc_coherent(NULL, devpriv->dma_maxsize, + &dma->hw_addr, GFP_KERNEL); if (!dma->virt_addr) return -ENOMEM; } @@ -1109,7 +,8 @@ static void dt282x_free_dma(struct comedi_device *dev) if (dma->chan) free_dma(dma->chan); if (dma->virt_addr) - free_page((unsigned long)dma->virt_addr); + dma_free_coherent(NULL, devpriv->dma_maxsize, + dma->virt_addr, dma->hw_addr); } } -- 2.0.3 ___ devel mailing list de...@linuxdriverproject.org http://driverdev.linuxdriverproject.org/mailman/listinfo/driverdev-devel
[PATCH 25/37] staging: comedi: pcl816: remove VIRT_TO_BUS dependancy
Use dma_{alloc,free}_coherent() to allocate and free the DMA buffers. This removes the dependancy on VIRT_TO_BUS. Signed-off-by: H Hartley Sweeten Cc: Ian Abbott Cc: Greg Kroah-Hartman --- drivers/staging/comedi/Kconfig | 2 +- drivers/staging/comedi/drivers/pcl816.c | 20 +--- 2 files changed, 10 insertions(+), 12 deletions(-) diff --git a/drivers/staging/comedi/Kconfig b/drivers/staging/comedi/Kconfig index c48ee22..59c17e6 100644 --- a/drivers/staging/comedi/Kconfig +++ b/drivers/staging/comedi/Kconfig @@ -179,7 +179,7 @@ config COMEDI_PCL812 config COMEDI_PCL816 tristate "Advantech PCL-814 and PCL-816 ISA card support" - depends on VIRT_TO_BUS && ISA_DMA_API + depends on ISA_DMA_API ---help--- Enable support for Advantech PCL-814 and PCL-816 ISA cards diff --git a/drivers/staging/comedi/drivers/pcl816.c b/drivers/staging/comedi/drivers/pcl816.c index 49c1f17..1b76085 100644 --- a/drivers/staging/comedi/drivers/pcl816.c +++ b/drivers/staging/comedi/drivers/pcl816.c @@ -114,13 +114,12 @@ static const struct pcl816_board boardtypes[] = { }; struct pcl816_dma_desc { - unsigned long virt_addr;/* virtual address of DMA buffer */ - unsigned int hw_addr; /* hardware (bus) address of DMA buffer */ + void *virt_addr;/* virtual address of DMA buffer */ + dma_addr_t hw_addr; /* hardware (bus) address of DMA buffer */ }; struct pcl816_private { unsigned int dma; /* used DMA, 0=don't use DMA */ - unsigned int dmapages; unsigned int hwdmasize; struct pcl816_dma_desc dma_desc[2]; int cur_dma; @@ -345,8 +344,7 @@ static irqreturn_t pcl816_interrupt(int irq, void *d) bufptr = devpriv->ai_poll_ptr; devpriv->ai_poll_ptr = 0; - transfer_from_dma_buf(dev, s, (unsigned short *)dma->virt_addr, - bufptr, len); + transfer_from_dma_buf(dev, s, dma->virt_addr, bufptr, len); pcl816_ai_clear_eoc(dev); @@ -552,7 +550,7 @@ static int pcl816_ai_poll(struct comedi_device *dev, struct comedi_subdevice *s) return 0; } - transfer_from_dma_buf(dev, s, (unsigned short *)dma->virt_addr, + transfer_from_dma_buf(dev, s, dma->virt_addr, devpriv->ai_poll_ptr, top2); devpriv->ai_poll_ptr = top1;/* new buffer position */ @@ -693,16 +691,15 @@ static int pcl816_alloc_dma(struct comedi_device *dev, dev->irq = irq_num; devpriv->dma = dma_chan; - devpriv->dmapages = 2; /* we need 16KB */ - devpriv->hwdmasize = (1 << devpriv->dmapages) * PAGE_SIZE; + devpriv->hwdmasize = PAGE_SIZE * 4; /* we need 16KB */ for (i = 0; i < 2; i++) { dma = &devpriv->dma_desc[i]; - dma->virt_addr = __get_dma_pages(GFP_KERNEL, devpriv->dmapages); + dma->virt_addr = dma_alloc_coherent(NULL, devpriv->hwdmasize, + &dma->hw_addr, GFP_KERNEL); if (!dma->virt_addr) return -ENOMEM; - dma->hw_addr = virt_to_bus((void *)dma->virt_addr); } return 0; } @@ -721,7 +718,8 @@ static void pcl816_free_dma(struct comedi_device *dev) for (i = 0; i < 2; i++) { dma = &devpriv->dma_desc[i]; if (dma->virt_addr) - free_pages(dma->virt_addr, devpriv->dmapages); + dma_free_coherent(NULL, devpriv->hwdmasize, + dma->virt_addr, dma->hw_addr); } } -- 2.0.3 ___ devel mailing list de...@linuxdriverproject.org http://driverdev.linuxdriverproject.org/mailman/listinfo/driverdev-devel
[PATCH 11/37] staging: comedi: ni_at_a2150: introduce a2150_free_dma()
From: H Hartley Sweeten For aesthetics, introduce a helper function to free the DMA channel and buffer. Signed-off-by: H Hartley Sweeten Cc: Ian Abbott Cc: Greg Kroah-Hartman --- drivers/staging/comedi/drivers/ni_at_a2150.c | 20 +--- 1 file changed, 13 insertions(+), 7 deletions(-) diff --git a/drivers/staging/comedi/drivers/ni_at_a2150.c b/drivers/staging/comedi/drivers/ni_at_a2150.c index 11b1681..de2e877 100644 --- a/drivers/staging/comedi/drivers/ni_at_a2150.c +++ b/drivers/staging/comedi/drivers/ni_at_a2150.c @@ -720,6 +720,18 @@ static void a2150_alloc_irq_dma(struct comedi_device *dev, set_dma_mode(dma_chan, DMA_MODE_READ); } +static void a2150_free_dma(struct comedi_device *dev) +{ + struct a2150_private *devpriv = dev->private; + + if (!devpriv) + return; + + if (devpriv->dma) + free_dma(devpriv->dma); + kfree(devpriv->dma_buffer); +} + /* probes board type, returns offset */ static int a2150_probe(struct comedi_device *dev) { @@ -808,15 +820,9 @@ static int a2150_attach(struct comedi_device *dev, struct comedi_devconfig *it) static void a2150_detach(struct comedi_device *dev) { - struct a2150_private *devpriv = dev->private; - if (dev->iobase) outw(APD_BIT | DPD_BIT, dev->iobase + CONFIG_REG); - if (devpriv) { - if (devpriv->dma) - free_dma(devpriv->dma); - kfree(devpriv->dma_buffer); - } + a2150_free_dma(dev); comedi_legacy_detach(dev); }; -- 2.0.3 ___ devel mailing list de...@linuxdriverproject.org http://driverdev.linuxdriverproject.org/mailman/listinfo/driverdev-devel
[PATCH 03/37] staging: comedi: das1800: separate AI FIFO bounce buffer from DMA buffer
This driver can use DMA or the hardware FIFO to read analog input samples. When DMA is enabled it's also possible for some async commands to cause DMA to be disabled and the FIFO is used instead. Currently the first DMA channels buffer is used for the bounce buffer when using the FIFO. For aesthetics, add a new member to the private data and use that for the FIFO bounce buffer. Signed-off-by: H Hartley Sweeten Cc: Ian Abbott Cc: Greg Kroah-Hartman --- drivers/staging/comedi/drivers/das1800.c | 17 - 1 file changed, 8 insertions(+), 9 deletions(-) diff --git a/drivers/staging/comedi/drivers/das1800.c b/drivers/staging/comedi/drivers/das1800.c index c415b57..2e087b1 100644 --- a/drivers/staging/comedi/drivers/das1800.c +++ b/drivers/staging/comedi/drivers/das1800.c @@ -433,6 +433,7 @@ struct das1800_private { uint16_t *ai_buf0; /* pointers to dma buffers */ uint16_t *ai_buf1; uint16_t *dma_current_buf; /* pointer to dma buffer currently being used */ + uint16_t *fifo_buf; /* bounce buffer for analog input FIFO */ unsigned int dma_transfer_size; /* size of transfer currently used, in bytes */ unsigned long iobase2; /* secondary io address used for analog out on 'ao' boards */ unsigned short ao_update_bits; /* remembers the last write to the @@ -480,9 +481,9 @@ static void das1800_handle_fifo_half_full(struct comedi_device *dev, struct das1800_private *devpriv = dev->private; unsigned int nsamples = comedi_nsamples_left(s, FIFO_SIZE / 2); - insw(dev->iobase + DAS1800_FIFO, devpriv->ai_buf0, nsamples); - munge_data(dev, devpriv->ai_buf0, nsamples); - comedi_buf_write_samples(s, devpriv->ai_buf0, nsamples); + insw(dev->iobase + DAS1800_FIFO, devpriv->fifo_buf, nsamples); + munge_data(dev, devpriv->fifo_buf, nsamples); + comedi_buf_write_samples(s, devpriv->fifo_buf, nsamples); } static void das1800_handle_fifo_not_empty(struct comedi_device *dev, @@ -1442,12 +1443,9 @@ static int das1800_attach(struct comedi_device *dev, return ret; } - if (devpriv->ai_buf0 == NULL) { - devpriv->ai_buf0 = - kmalloc(FIFO_SIZE * sizeof(uint16_t), GFP_KERNEL); - if (devpriv->ai_buf0 == NULL) - return -ENOMEM; - } + devpriv->fifo_buf = kmalloc(FIFO_SIZE * sizeof(uint16_t), GFP_KERNEL); + if (!devpriv->fifo_buf) + return -ENOMEM; ret = comedi_alloc_subdevices(dev, 4); if (ret) @@ -1531,6 +1529,7 @@ static void das1800_detach(struct comedi_device *dev) free_dma(devpriv->dma1); kfree(devpriv->ai_buf0); kfree(devpriv->ai_buf1); + kfree(devpriv->fifo_buf); if (devpriv->iobase2) release_region(devpriv->iobase2, DAS1800_SIZE); } -- 2.0.3 ___ devel mailing list de...@linuxdriverproject.org http://driverdev.linuxdriverproject.org/mailman/listinfo/driverdev-devel
[PATCH 05/37] staging: comedi: das1800: tidy up das1800_init_dma()
Refactor this function so that a for loop can be used to request and set up the two DMA descriptors. Signed-off-by: H Hartley Sweeten Cc: Ian Abbott Cc: Greg Kroah-Hartman --- drivers/staging/comedi/drivers/das1800.c | 52 +++- 1 file changed, 25 insertions(+), 27 deletions(-) diff --git a/drivers/staging/comedi/drivers/das1800.c b/drivers/staging/comedi/drivers/das1800.c index 2d376fd..df28d36a 100644 --- a/drivers/staging/comedi/drivers/das1800.c +++ b/drivers/staging/comedi/drivers/das1800.c @@ -1228,15 +1228,24 @@ static int das1800_do_wbits(struct comedi_device *dev, return insn->n; } -static int das1800_init_dma(struct comedi_device *dev, unsigned int dma0, - unsigned int dma1) +static int das1800_init_dma(struct comedi_device *dev, + struct comedi_devconfig *it) { struct das1800_private *devpriv = dev->private; struct das1800_dma_desc *dma; + unsigned int *dma_chan; unsigned long flags; + int i; + + /* +* it->options[2] is DMA channel 0 +* it->options[3] is DMA channel 1 +* +* Encode the DMA channels into 2 digit hexadecimal for switch. +*/ + dma_chan = &it->options[2]; - /* encode dma0 and dma1 into 2 digit hexadecimal for switch */ - switch ((dma0 & 0x7) | (dma1 << 4)) { + switch ((dma_chan[0] & 0x7) | (dma_chan[1] << 4)) { case 0x5: /* dma0 == 5 */ devpriv->dma_bits |= DMA_CH5; break; @@ -1265,33 +1274,24 @@ static int das1800_init_dma(struct comedi_device *dev, unsigned int dma0, return -EINVAL; } - dma = &devpriv->dma_desc[0]; - if (request_dma(dma0, dev->driver->driver_name)) { - dev_err(dev->class_dev, - "failed to allocate dma channel %i\n", dma0); - return -EINVAL; - } - dma->chan = dma0; - dma->virt_addr = kmalloc(DMA_BUF_SIZE, GFP_KERNEL | GFP_DMA); - if (!dma->virt_addr) - return -ENOMEM; - flags = claim_dma_lock(); - disable_dma(dma->chan); - set_dma_mode(dma->chan, DMA_MODE_READ); - release_dma_lock(flags); + for (i = 0; i < 2; i++) { + dma = &devpriv->dma_desc[i]; - if (dma1) { - dma = &devpriv->dma_desc[1]; - if (request_dma(dma1, dev->driver->driver_name)) { + if (dma_chan[i] == 0) + break; + + if (request_dma(dma_chan[i], dev->board_name)) { dev_err(dev->class_dev, "failed to allocate dma channel %i\n", - dma1); + dma_chan[i]); return -EINVAL; } - dma->chan = dma1; + dma->chan = dma_chan[i]; + dma->virt_addr = kmalloc(DMA_BUF_SIZE, GFP_KERNEL | GFP_DMA); if (!dma->virt_addr) return -ENOMEM; + flags = claim_dma_lock(); disable_dma(dma->chan); set_dma_mode(dma->chan, DMA_MODE_READ); @@ -1366,8 +1366,6 @@ static int das1800_attach(struct comedi_device *dev, struct das1800_private *devpriv; struct comedi_subdevice *s; unsigned int irq = it->options[1]; - unsigned int dma0 = it->options[2]; - unsigned int dma1 = it->options[3]; int board; int ret; @@ -1430,8 +1428,8 @@ static int das1800_attach(struct comedi_device *dev, } /* an irq and one dma channel is required to use dma */ - if (dev->irq & dma0) { - ret = das1800_init_dma(dev, dma0, dma1); + if (dev->irq & it->options[2]) { + ret = das1800_init_dma(dev, it); if (ret < 0) return ret; } -- 2.0.3 ___ devel mailing list de...@linuxdriverproject.org http://driverdev.linuxdriverproject.org/mailman/listinfo/driverdev-devel
[PATCH 15/37] staging: comedi: ni_labpc_isadma: tidy up labpc_init_dma_chan()
DMA support is optional for the labpc driver. The return value from labpc_init_dma_chan() is not even checked by the caller. Change the return type to void and tidy up the function a bit. Signed-off-by: H Hartley Sweeten Cc: Ian Abbott Cc: Greg Kroah-Hartman --- drivers/staging/comedi/drivers/ni_labpc_isadma.c | 22 -- drivers/staging/comedi/drivers/ni_labpc_isadma.h | 7 +++ 2 files changed, 11 insertions(+), 18 deletions(-) diff --git a/drivers/staging/comedi/drivers/ni_labpc_isadma.c b/drivers/staging/comedi/drivers/ni_labpc_isadma.c index b7217a7..829c4e4 100644 --- a/drivers/staging/comedi/drivers/ni_labpc_isadma.c +++ b/drivers/staging/comedi/drivers/ni_labpc_isadma.c @@ -163,28 +163,24 @@ void labpc_handle_dma_status(struct comedi_device *dev) } EXPORT_SYMBOL_GPL(labpc_handle_dma_status); -int labpc_init_dma_chan(struct comedi_device *dev, unsigned int dma_chan) +void labpc_init_dma_chan(struct comedi_device *dev, unsigned int dma_chan) { struct labpc_private *devpriv = dev->private; struct labpc_dma_desc *dma = &devpriv->dma_desc; - void *dma_buffer; unsigned long dma_flags; - int ret; if (dma_chan != 1 && dma_chan != 3) - return -EINVAL; + return; - dma_buffer = kmalloc(dma_buffer_size, GFP_KERNEL | GFP_DMA); - if (!dma_buffer) - return -ENOMEM; + if (request_dma(dma_chan, dev->board_name)) + return; - ret = request_dma(dma_chan, dev->board_name); - if (ret) { - kfree(dma_buffer); - return ret; + dma->virt_addr = kmalloc(dma_buffer_size, GFP_KERNEL | GFP_DMA); + if (!dma->virt_addr) { + free_dma(dma_chan); + return; } - dma->virt_addr = dma_buffer; dma->chan = dma_chan; dma->hw_addr = virt_to_bus(dma->virt_addr); @@ -192,8 +188,6 @@ int labpc_init_dma_chan(struct comedi_device *dev, unsigned int dma_chan) disable_dma(dma->chan); set_dma_mode(dma->chan, DMA_MODE_READ); release_dma_lock(dma_flags); - - return 0; } EXPORT_SYMBOL_GPL(labpc_init_dma_chan); diff --git a/drivers/staging/comedi/drivers/ni_labpc_isadma.h b/drivers/staging/comedi/drivers/ni_labpc_isadma.h index 2582f22..8f062f7 100644 --- a/drivers/staging/comedi/drivers/ni_labpc_isadma.h +++ b/drivers/staging/comedi/drivers/ni_labpc_isadma.h @@ -16,7 +16,7 @@ static inline bool labpc_have_dma_chan(struct comedi_device *dev) return (bool)devpriv->dma_desc.chan; } -int labpc_init_dma_chan(struct comedi_device *dev, unsigned int dma_chan); +void labpc_init_dma_chan(struct comedi_device *dev, unsigned int dma_chan); void labpc_free_dma_chan(struct comedi_device *dev); void labpc_setup_dma(struct comedi_device *dev, struct comedi_subdevice *s); void labpc_drain_dma(struct comedi_device *dev); @@ -29,10 +29,9 @@ static inline bool labpc_have_dma_chan(struct comedi_device *dev) return false; } -static inline int labpc_init_dma_chan(struct comedi_device *dev, - unsigned int dma_chan) +static inline void labpc_init_dma_chan(struct comedi_device *dev, + unsigned int dma_chan) { - return -ENOTSUPP; } static inline void labpc_free_dma_chan(struct comedi_device *dev) -- 2.0.3 ___ devel mailing list de...@linuxdriverproject.org http://driverdev.linuxdriverproject.org/mailman/listinfo/driverdev-devel
[PATCH 36/37] staging: comedi: das16: introduce das16_free_dma()
For aesthetics, move the freeing of the DMA channel and the buffers to a helper function. Signed-off-by: H Hartley Sweeten Cc: Ian Abbott Cc: Greg Kroah-Hartman --- drivers/staging/comedi/drivers/das16.c | 33 +++-- 1 file changed, 19 insertions(+), 14 deletions(-) diff --git a/drivers/staging/comedi/drivers/das16.c b/drivers/staging/comedi/drivers/das16.c index 0f4a587..e0b41ae 100644 --- a/drivers/staging/comedi/drivers/das16.c +++ b/drivers/staging/comedi/drivers/das16.c @@ -1028,6 +1028,24 @@ static int das16_alloc_dma(struct comedi_device *dev, unsigned int dma_chan) return 0; } +static void das16_free_dma(struct comedi_device *dev) +{ + struct das16_private_struct *devpriv = dev->private; + struct das16_dma_desc *dma; + int i; + + if (devpriv->timer.data) + del_timer_sync(&devpriv->timer); + for (i = 0; i < 2; i++) { + dma = &devpriv->dma_desc[i]; + if (dma->virt_addr) + pci_free_consistent(NULL, DAS16_DMA_SIZE, + dma->virt_addr, dma->hw_addr); + } + if (devpriv->dma_chan) + free_dma(devpriv->dma_chan); +} + static int das16_attach(struct comedi_device *dev, struct comedi_devconfig *it) { const struct das16_board *board = dev->board_ptr; @@ -1226,24 +1244,11 @@ static void das16_detach(struct comedi_device *dev) { const struct das16_board *board = dev->board_ptr; struct das16_private_struct *devpriv = dev->private; - struct das16_dma_desc *dma; - int i; if (devpriv) { - if (devpriv->timer.data) - del_timer_sync(&devpriv->timer); if (dev->iobase) das16_reset(dev); - - for (i = 0; i < 2; i++) { - dma = &devpriv->dma_desc[i]; - if (dma->virt_addr) - pci_free_consistent(NULL, DAS16_DMA_SIZE, - dma->virt_addr, - dma->hw_addr); - } - if (devpriv->dma_chan) - free_dma(devpriv->dma_chan); + das16_free_dma(dev); kfree(devpriv->user_ai_range_table); kfree(devpriv->user_ao_range_table); -- 2.0.3 ___ devel mailing list de...@linuxdriverproject.org http://driverdev.linuxdriverproject.org/mailman/listinfo/driverdev-devel
[PATCH 32/37] staging: comedi: dt282x: introduce struct dt282x_dma_desc
For aesthetics, introduce a struct to hold the DMA descriptor data. Signed-off-by: H Hartley Sweeten Cc: Ian Abbott Cc: Greg Kroah-Hartman --- drivers/staging/comedi/drivers/dt282x.c | 111 +++- 1 file changed, 53 insertions(+), 58 deletions(-) diff --git a/drivers/staging/comedi/drivers/dt282x.c b/drivers/staging/comedi/drivers/dt282x.c index 873aae6..8ee6186 100644 --- a/drivers/staging/comedi/drivers/dt282x.c +++ b/drivers/staging/comedi/drivers/dt282x.c @@ -300,6 +300,12 @@ static const struct dt282x_board boardtypes[] = { }, }; +struct dt282x_dma_desc { + unsigned int chan; /* DMA channel */ + unsigned short *virt_addr; /* virtual address of DMA buffer */ + unsigned int size; /* transfer size (in bytes) */ +}; + struct dt282x_private { unsigned int ad_2scomp:1; @@ -312,21 +318,16 @@ struct dt282x_private { int ntrig; int nread; - struct { - int chan; - unsigned short *buf;/* DMA buffer */ - int size; /* size of current transfer */ - } dma[2]; + struct dt282x_dma_desc dma_desc[2]; int dma_maxsize;/* max size of DMA transfer (in bytes) */ - int current_dma_index; + int cur_dma; int dma_dir; }; static int dt282x_prep_ai_dma(struct comedi_device *dev, int dma_index, int n) { struct dt282x_private *devpriv = dev->private; - int dma_chan; - unsigned long dma_ptr; + struct dt282x_dma_desc *dma = &devpriv->dma_desc[dma_index]; unsigned long flags; if (!devpriv->ntrig) @@ -338,18 +339,16 @@ static int dt282x_prep_ai_dma(struct comedi_device *dev, int dma_index, int n) n = devpriv->ntrig * 2; devpriv->ntrig -= n / 2; - devpriv->dma[dma_index].size = n; - dma_chan = devpriv->dma[dma_index].chan; - dma_ptr = virt_to_bus(devpriv->dma[dma_index].buf); + dma->size = n; - set_dma_mode(dma_chan, DMA_MODE_READ); + set_dma_mode(dma->chan, DMA_MODE_READ); flags = claim_dma_lock(); - clear_dma_ff(dma_chan); - set_dma_addr(dma_chan, dma_ptr); - set_dma_count(dma_chan, n); + clear_dma_ff(dma->chan); + set_dma_addr(dma->chan, virt_to_bus(dma->virt_addr)); + set_dma_count(dma->chan, dma->size); release_dma_lock(flags); - enable_dma(dma_chan); + enable_dma(dma->chan); return n; } @@ -357,22 +356,19 @@ static int dt282x_prep_ai_dma(struct comedi_device *dev, int dma_index, int n) static int dt282x_prep_ao_dma(struct comedi_device *dev, int dma_index, int n) { struct dt282x_private *devpriv = dev->private; - int dma_chan; - unsigned long dma_ptr; + struct dt282x_dma_desc *dma = &devpriv->dma_desc[dma_index]; unsigned long flags; - devpriv->dma[dma_index].size = n; - dma_chan = devpriv->dma[dma_index].chan; - dma_ptr = virt_to_bus(devpriv->dma[dma_index].buf); + dma->size = n; - set_dma_mode(dma_chan, DMA_MODE_WRITE); + set_dma_mode(dma->chan, DMA_MODE_WRITE); flags = claim_dma_lock(); - clear_dma_ff(dma_chan); - set_dma_addr(dma_chan, dma_ptr); - set_dma_count(dma_chan, n); + clear_dma_ff(dma->chan); + set_dma_addr(dma->chan, virt_to_bus(dma->virt_addr)); + set_dma_count(dma->chan, dma->size); release_dma_lock(flags); - enable_dma(dma_chan); + enable_dma(dma->chan); return n; } @@ -381,8 +377,8 @@ static void dt282x_disable_dma(struct comedi_device *dev) { struct dt282x_private *devpriv = dev->private; - disable_dma(devpriv->dma[0].chan); - disable_dma(devpriv->dma[1].chan); + disable_dma(devpriv->dma_desc[0].chan); + disable_dma(devpriv->dma_desc[1].chan); } static unsigned int dt282x_ns_to_timer(unsigned int *ns, unsigned int flags) @@ -444,11 +440,11 @@ static unsigned int dt282x_ao_setup_dma(struct comedi_device *dev, int cur_dma) { struct dt282x_private *devpriv = dev->private; - void *ptr = devpriv->dma[cur_dma].buf; + struct dt282x_dma_desc *dma = &devpriv->dma_desc[cur_dma]; unsigned int nsamples = comedi_bytes_to_samples(s, devpriv->dma_maxsize); unsigned int nbytes; - nbytes = comedi_buf_read_samples(s, ptr, nsamples); + nbytes = comedi_buf_read_samples(s, dma->virt_addr, nsamples); if (nbytes) dt282x_prep_ao_dma(dev, cur_dma, nbytes); else @@ -461,39 +457,35 @@ static void dt282x_ao_dma_interrupt(struct comedi_device *dev, struct comedi_subdevice *s) { struct dt282x_private *devpriv = dev->private; - int cur_dma = devpriv->current_dma_index; + struct dt282x_dma_desc *dma = &devpriv->dma_desc[devpriv->cur_dma]; outw(devpriv->supcsr | DT2821_SU
[PATCH 24/37] staging: comedi: pcl816: introduce struct pcl816_dma_desc
For aesthetics, introduce a struct to hold the DMA descriptor data. Signed-off-by: H Hartley Sweeten Cc: Ian Abbott Cc: Greg Kroah-Hartman --- drivers/staging/comedi/drivers/pcl816.c | 51 ++--- 1 file changed, 28 insertions(+), 23 deletions(-) diff --git a/drivers/staging/comedi/drivers/pcl816.c b/drivers/staging/comedi/drivers/pcl816.c index 4cff02a..49c1f17 100644 --- a/drivers/staging/comedi/drivers/pcl816.c +++ b/drivers/staging/comedi/drivers/pcl816.c @@ -113,13 +113,17 @@ static const struct pcl816_board boardtypes[] = { }, }; +struct pcl816_dma_desc { + unsigned long virt_addr;/* virtual address of DMA buffer */ + unsigned int hw_addr; /* hardware (bus) address of DMA buffer */ +}; + struct pcl816_private { unsigned int dma; /* used DMA, 0=don't use DMA */ unsigned int dmapages; unsigned int hwdmasize; - unsigned long dmabuf[2];/* pointers to begin of DMA buffers */ - unsigned int hwdmaptr[2]; /* hardware address of DMA buffers */ - int next_dma_buf; /* which DMA buffer will be used next round */ + struct pcl816_dma_desc dma_desc[2]; + int cur_dma; long dma_runs_to_end; /* how many we must permorm DMA transfer to end of record */ unsigned long last_dma_run; /* how many bytes we must transfer on last DMA page */ unsigned int ai_poll_ptr; /* how many sampes transfer poll */ @@ -152,6 +156,7 @@ static void pcl816_ai_setup_dma(struct comedi_device *dev, struct comedi_subdevice *s) { struct pcl816_private *devpriv = dev->private; + struct pcl816_dma_desc *dma = &devpriv->dma_desc[0]; struct comedi_cmd *cmd = &s->async->cmd; unsigned int dma_flags; unsigned int bytes; @@ -172,11 +177,11 @@ static void pcl816_ai_setup_dma(struct comedi_device *dev, } else devpriv->dma_runs_to_end = -1; - devpriv->next_dma_buf = 0; + devpriv->cur_dma = 0; set_dma_mode(devpriv->dma, DMA_MODE_READ); dma_flags = claim_dma_lock(); clear_dma_ff(devpriv->dma); - set_dma_addr(devpriv->dma, devpriv->hwdmaptr[0]); + set_dma_addr(devpriv->dma, dma->hw_addr); set_dma_count(devpriv->dma, bytes); release_dma_lock(dma_flags); enable_dma(devpriv->dma); @@ -187,16 +192,17 @@ static void pcl816_ai_setup_next_dma(struct comedi_device *dev, { struct pcl816_private *devpriv = dev->private; struct comedi_cmd *cmd = &s->async->cmd; + struct pcl816_dma_desc *dma; unsigned long dma_flags; disable_dma(devpriv->dma); if (devpriv->dma_runs_to_end > -1 || cmd->stop_src == TRIG_NONE) { /* switch dma bufs */ - devpriv->next_dma_buf = 1 - devpriv->next_dma_buf; + devpriv->cur_dma = 1 - devpriv->cur_dma; + dma = &devpriv->dma_desc[devpriv->cur_dma]; set_dma_mode(devpriv->dma, DMA_MODE_READ); dma_flags = claim_dma_lock(); - set_dma_addr(devpriv->dma, -devpriv->hwdmaptr[devpriv->next_dma_buf]); + set_dma_addr(devpriv->dma, dma->hw_addr); if (devpriv->dma_runs_to_end) set_dma_count(devpriv->dma, devpriv->hwdmasize); else @@ -318,7 +324,7 @@ static irqreturn_t pcl816_interrupt(int irq, void *d) struct comedi_device *dev = d; struct comedi_subdevice *s = dev->read_subdev; struct pcl816_private *devpriv = dev->private; - unsigned short *ptr; + struct pcl816_dma_desc *dma = &devpriv->dma_desc[devpriv->cur_dma]; unsigned int bufptr; unsigned int len; @@ -333,15 +339,14 @@ static irqreturn_t pcl816_interrupt(int irq, void *d) return IRQ_HANDLED; } - ptr = (unsigned short *)devpriv->dmabuf[devpriv->next_dma_buf]; - pcl816_ai_setup_next_dma(dev, s); len = (devpriv->hwdmasize >> 1) - devpriv->ai_poll_ptr; bufptr = devpriv->ai_poll_ptr; devpriv->ai_poll_ptr = 0; - transfer_from_dma_buf(dev, s, ptr, bufptr, len); + transfer_from_dma_buf(dev, s, (unsigned short *)dma->virt_addr, + bufptr, len); pcl816_ai_clear_eoc(dev); @@ -521,6 +526,7 @@ static int pcl816_ai_cmd(struct comedi_device *dev, struct comedi_subdevice *s) static int pcl816_ai_poll(struct comedi_device *dev, struct comedi_subdevice *s) { struct pcl816_private *devpriv = dev->private; + struct pcl816_dma_desc *dma = &devpriv->dma_desc[devpriv->cur_dma]; unsigned long flags; unsigned int top1, top2, i; @@ -546,9 +552,7 @@ static int pcl816_ai_poll(struct comedi_device *dev, struct comedi_subdevice *s) return 0; } - transfer_from_dma_buf(dev, s, -
[PATCH 17/37] staging: comedi: pcl818: introduce pcl818_alloc_dma()
DMA is optional with this driver. Introduce a helper function to request the DMA channel and allocate the buffers. Don't fail the driver attach if the user passed an invalid DMA channel or the channel cannot be requested. Signed-off-by: H Hartley Sweeten Cc: Ian Abbott Cc: Greg Kroah-Hartman --- drivers/staging/comedi/drivers/pcl818.c | 57 ++--- 1 file changed, 32 insertions(+), 25 deletions(-) diff --git a/drivers/staging/comedi/drivers/pcl818.c b/drivers/staging/comedi/drivers/pcl818.c index 8edea35..b25ff35 100644 --- a/drivers/staging/comedi/drivers/pcl818.c +++ b/drivers/staging/comedi/drivers/pcl818.c @@ -1054,13 +1054,40 @@ static void pcl818_set_ai_range_table(struct comedi_device *dev, } } +static int pcl818_alloc_dma(struct comedi_device *dev, unsigned int dma_chan) +{ + struct pcl818_private *devpriv = dev->private; + int i; + + if (!(dma_chan == 3 || dma_chan == 1)) + return 0; + + if (request_dma(dma_chan, dev->board_name)) + return 0; + devpriv->dma = dma_chan; + + devpriv->dmapages = 2; /* we need 16KB */ + devpriv->hwdmasize = (1 << devpriv->dmapages) * PAGE_SIZE; + + for (i = 0; i < 2; i++) { + unsigned long dmabuf; + + dmabuf = __get_dma_pages(GFP_KERNEL, devpriv->dmapages); + if (!dmabuf) + return -ENOMEM; + + devpriv->dmabuf[i] = dmabuf; + devpriv->hwdmaptr[i] = virt_to_bus((void *)dmabuf); + } + return 0; +} + static int pcl818_attach(struct comedi_device *dev, struct comedi_devconfig *it) { const struct pcl818_board *board = dev->board_ptr; struct pcl818_private *devpriv; struct comedi_subdevice *s; int ret; - int i; devpriv = comedi_alloc_devpriv(dev, sizeof(*devpriv)); if (!devpriv) @@ -1084,30 +,10 @@ static int pcl818_attach(struct comedi_device *dev, struct comedi_devconfig *it) devpriv->usefifo = 1; /* we need an IRQ to do DMA on channel 3 or 1 */ - if (dev->irq && board->has_dma && - (it->options[2] == 3 || it->options[2] == 1)) { - ret = request_dma(it->options[2], dev->board_name); - if (ret) { - dev_err(dev->class_dev, - "unable to request DMA channel %d\n", - it->options[2]); - return -EBUSY; - } - devpriv->dma = it->options[2]; - - devpriv->dmapages = 2; /* we need 16KB */ - devpriv->hwdmasize = (1 << devpriv->dmapages) * PAGE_SIZE; - - for (i = 0; i < 2; i++) { - unsigned long dmabuf; - - dmabuf = __get_dma_pages(GFP_KERNEL, devpriv->dmapages); - if (!dmabuf) - return -ENOMEM; - - devpriv->dmabuf[i] = dmabuf; - devpriv->hwdmaptr[i] = virt_to_bus((void *)dmabuf); - } + if (dev->irq && board->has_dma) { + ret = pcl818_alloc_dma(dev, it->options[2]); + if (ret) + return ret; } ret = comedi_alloc_subdevices(dev, 4); -- 2.0.3 ___ devel mailing list de...@linuxdriverproject.org http://driverdev.linuxdriverproject.org/mailman/listinfo/driverdev-devel
[PATCH 02/37] staging: comedi: das1800: reduce indent level of das1800_init_dma()
An IRQ and at least one DMA channel are required to use DMA with this driver. Move the check to the caller to reduce the indent level of this function. Signed-off-by: H Hartley Sweeten Cc: Ian Abbott Cc: Greg Kroah-Hartman --- drivers/staging/comedi/drivers/das1800.c | 129 --- 1 file changed, 65 insertions(+), 64 deletions(-) diff --git a/drivers/staging/comedi/drivers/das1800.c b/drivers/staging/comedi/drivers/das1800.c index be825d2..c415b57 100644 --- a/drivers/staging/comedi/drivers/das1800.c +++ b/drivers/staging/comedi/drivers/das1800.c @@ -1240,72 +1240,70 @@ static int das1800_init_dma(struct comedi_device *dev, unsigned int dma0, struct das1800_private *devpriv = dev->private; unsigned long flags; - /* need an irq to do dma */ - if (dev->irq && dma0) { - /* encode dma0 and dma1 into 2 digit hexadecimal for switch */ - switch ((dma0 & 0x7) | (dma1 << 4)) { - case 0x5: /* dma0 == 5 */ - devpriv->dma_bits |= DMA_CH5; - break; - case 0x6: /* dma0 == 6 */ - devpriv->dma_bits |= DMA_CH6; - break; - case 0x7: /* dma0 == 7 */ - devpriv->dma_bits |= DMA_CH7; - break; - case 0x65: /* dma0 == 5, dma1 == 6 */ - devpriv->dma_bits |= DMA_CH5_CH6; - break; - case 0x76: /* dma0 == 6, dma1 == 7 */ - devpriv->dma_bits |= DMA_CH6_CH7; - break; - case 0x57: /* dma0 == 7, dma1 == 5 */ - devpriv->dma_bits |= DMA_CH7_CH5; - break; - default: - dev_err(dev->class_dev, - "only supports dma channels 5 through 7\n"); - dev_err(dev->class_dev, - "Dual dma only allows the following combinations:\n"); - dev_err(dev->class_dev, - "dma 5,6 / 6,7 / or 7,5\n"); - return -EINVAL; - } - if (request_dma(dma0, dev->driver->driver_name)) { + /* encode dma0 and dma1 into 2 digit hexadecimal for switch */ + switch ((dma0 & 0x7) | (dma1 << 4)) { + case 0x5: /* dma0 == 5 */ + devpriv->dma_bits |= DMA_CH5; + break; + case 0x6: /* dma0 == 6 */ + devpriv->dma_bits |= DMA_CH6; + break; + case 0x7: /* dma0 == 7 */ + devpriv->dma_bits |= DMA_CH7; + break; + case 0x65: /* dma0 == 5, dma1 == 6 */ + devpriv->dma_bits |= DMA_CH5_CH6; + break; + case 0x76: /* dma0 == 6, dma1 == 7 */ + devpriv->dma_bits |= DMA_CH6_CH7; + break; + case 0x57: /* dma0 == 7, dma1 == 5 */ + devpriv->dma_bits |= DMA_CH7_CH5; + break; + default: + dev_err(dev->class_dev, + "only supports dma channels 5 through 7\n"); + dev_err(dev->class_dev, + "Dual dma only allows the following combinations:\n"); + dev_err(dev->class_dev, + "dma 5,6 / 6,7 / or 7,5\n"); + return -EINVAL; + } + if (request_dma(dma0, dev->driver->driver_name)) { + dev_err(dev->class_dev, + "failed to allocate dma channel %i\n", dma0); + return -EINVAL; + } + devpriv->dma0 = dma0; + devpriv->dma_current = dma0; + if (dma1) { + if (request_dma(dma1, dev->driver->driver_name)) { dev_err(dev->class_dev, - "failed to allocate dma channel %i\n", dma0); + "failed to allocate dma channel %i\n", + dma1); return -EINVAL; } - devpriv->dma0 = dma0; - devpriv->dma_current = dma0; - if (dma1) { - if (request_dma(dma1, dev->driver->driver_name)) { - dev_err(dev->class_dev, - "failed to allocate dma channel %i\n", - dma1); - return -EINVAL; - } - devpriv->dma1 = dma1; - } - devpriv->ai_buf0 = kmalloc(DMA_BUF_SIZE, GFP_KERNEL | GFP_DMA); - if (devpriv->ai_buf0 == NULL) + devpriv->dma1 = dma1; + } + devpriv->ai_buf0 = kmalloc(DMA_BUF_SIZE, GFP_KERNEL | GFP_DMA); + if (devpriv->ai_buf0 == NULL) +
[PATCH 13/37] staging: comedi: ni_at_a2150: remove VIRT_TO_BUS dependancy
Use dma_{alloc,free}_coherent() to allocate and free the DMA buffers. This removes the dependancy on VIRT_TO_BUS. Signed-off-by: H Hartley Sweeten Cc: Ian Abbott Cc: Greg Kroah-Hartman --- drivers/staging/comedi/Kconfig | 2 +- drivers/staging/comedi/drivers/ni_at_a2150.c | 17 +++-- 2 files changed, 12 insertions(+), 7 deletions(-) diff --git a/drivers/staging/comedi/Kconfig b/drivers/staging/comedi/Kconfig index fe030a3..982b03f 100644 --- a/drivers/staging/comedi/Kconfig +++ b/drivers/staging/comedi/Kconfig @@ -462,7 +462,7 @@ config COMEDI_ADQ12B config COMEDI_NI_AT_A2150 tristate "NI AT-A2150 ISA card support" - depends on VIRT_TO_BUS && ISA_DMA_API + depends on ISA_DMA_API ---help--- Enable support for National Instruments AT-A2150 cards diff --git a/drivers/staging/comedi/drivers/ni_at_a2150.c b/drivers/staging/comedi/drivers/ni_at_a2150.c index a1300e0..3905097 100644 --- a/drivers/staging/comedi/drivers/ni_at_a2150.c +++ b/drivers/staging/comedi/drivers/ni_at_a2150.c @@ -147,7 +147,8 @@ static const struct a2150_board a2150_boards[] = { struct a2150_dma_desc { unsigned int chan; /* DMA channel */ - uint16_t *virt_addr;/* virtual address of DMA buffer */ + void *virt_addr;/* virtual address of DMA buffer */ + dma_addr_t hw_addr; /* hardware (bus) address of DMA buffer */ unsigned int size; /* size of DMA transfer (in bytes) */ }; @@ -170,6 +171,7 @@ static irqreturn_t a2150_interrupt(int irq, void *d) struct comedi_subdevice *s = dev->read_subdev; struct comedi_async *async; struct comedi_cmd *cmd; + unsigned short *buf = dma->virt_addr; unsigned int max_points, num_points, residue, leftover; unsigned short dpnt; @@ -237,7 +239,7 @@ static irqreturn_t a2150_interrupt(int irq, void *d) for (i = 0; i < num_points; i++) { /* write data point to comedi buffer */ - dpnt = dma->virt_addr[i]; + dpnt = buf[i]; /* convert from 2's complement to unsigned coding */ dpnt ^= 0x8000; comedi_buf_write_samples(s, &dpnt, 1); @@ -250,7 +252,7 @@ static irqreturn_t a2150_interrupt(int irq, void *d) } /* re-enable dma */ if (leftover) { - set_dma_addr(dma->chan, virt_to_bus(dma->virt_addr)); + set_dma_addr(dma->chan, dma->hw_addr); set_dma_count(dma->chan, comedi_samples_to_bytes(s, leftover)); enable_dma(dma->chan); @@ -553,7 +555,7 @@ static int a2150_ai_cmd(struct comedi_device *dev, struct comedi_subdevice *s) /* clear flip-flop to make sure 2-byte registers for * count and address get set correctly */ clear_dma_ff(dma->chan); - set_dma_addr(dma->chan, virt_to_bus(dma->virt_addr)); + set_dma_addr(dma->chan, dma->hw_addr); /* set size of transfer to fill in 1/3 second */ #define ONE_THIRD_SECOND 3 dma->size = comedi_bytes_per_sample(s) * cmd->chanlist_len * @@ -709,7 +711,8 @@ static void a2150_alloc_irq_dma(struct comedi_device *dev, free_irq(irq_num, dev); return; } - dma->virt_addr = kmalloc(A2150_DMA_BUFFER_SIZE, GFP_KERNEL | GFP_DMA); + dma->virt_addr = dma_alloc_coherent(NULL, A2150_DMA_BUFFER_SIZE, + &dma->hw_addr, GFP_KERNEL); if (!dma->virt_addr) { free_dma(dma_chan); free_irq(irq_num, dev); @@ -735,7 +738,9 @@ static void a2150_free_dma(struct comedi_device *dev) dma = &devpriv->dma_desc; if (dma->chan) free_dma(dma->chan); - kfree(dma->virt_addr); + if (dma->virt_addr) + dma_free_coherent(NULL, A2150_DMA_BUFFER_SIZE, + dma->virt_addr, dma->hw_addr); } /* probes board type, returns offset */ -- 2.0.3 ___ devel mailing list de...@linuxdriverproject.org http://driverdev.linuxdriverproject.org/mailman/listinfo/driverdev-devel
[PATCH 31/37] staging: comedi: dt282x: introduce dt282x_alloc_dma()
The IRA and DMA are optional with this driver but both are required to support async commands. Introduce a helper function to request the IRQ and DMA channel and allocate the buffers. Don't fail the driver attach if the user passed an invalid IRQ or DMA channel or they cannot be requested. Signed-off-by: H Hartley Sweeten Cc: Ian Abbott Cc: Greg Kroah-Hartman --- drivers/staging/comedi/drivers/dt282x.c | 84 - 1 file changed, 40 insertions(+), 44 deletions(-) diff --git a/drivers/staging/comedi/drivers/dt282x.c b/drivers/staging/comedi/drivers/dt282x.c index cfa0f97..873aae6 100644 --- a/drivers/staging/comedi/drivers/dt282x.c +++ b/drivers/staging/comedi/drivers/dt282x.c @@ -1053,26 +1053,49 @@ static const struct comedi_lrange *opt_ai_range_lkup(int ispgl, int x) return ai_range_table[x]; } -static int dt282x_grab_dma(struct comedi_device *dev, int dma1, int dma2) +static int dt282x_alloc_dma(struct comedi_device *dev, + struct comedi_devconfig *it) { struct dt282x_private *devpriv = dev->private; - int ret; + unsigned int irq_num = it->options[1]; + unsigned int dma_chan[2]; + int i; - ret = request_dma(dma1, "dt282x A"); - if (ret) - return -EBUSY; - devpriv->dma[0].chan = dma1; + if (it->options[2] < it->options[3]) { + dma_chan[0] = it->options[2]; + dma_chan[1] = it->options[3]; + } else { + dma_chan[0] = it->options[3]; + dma_chan[1] = it->options[2]; + } - ret = request_dma(dma2, "dt282x B"); - if (ret) - return -EBUSY; - devpriv->dma[1].chan = dma2; + if (!irq_num || dma_chan[0] == dma_chan[1] || + dma_chan[0] < 5 || dma_chan[0] > 7 || + dma_chan[1] < 5 || dma_chan[1] > 7) + return 0; + + if (request_irq(irq_num, dt282x_interrupt, 0, dev->board_name, dev)) + return 0; + if (request_dma(dma_chan[0], dev->board_name)) { + free_irq(irq_num, dev); + return 0; + } + if (request_dma(dma_chan[1], dev->board_name)) { + free_dma(dma_chan[0]); + free_irq(irq_num, dev); + return 0; + } + + dev->irq = irq_num; devpriv->dma_maxsize = PAGE_SIZE; - devpriv->dma[0].buf = (void *)__get_free_page(GFP_KERNEL | GFP_DMA); - devpriv->dma[1].buf = (void *)__get_free_page(GFP_KERNEL | GFP_DMA); - if (!devpriv->dma[0].buf || !devpriv->dma[1].buf) - return -ENOMEM; + for (i = 0; i < 2; i++) { + devpriv->dma[i].chan = dma_chan[i]; + devpriv->dma[i].buf = + (void *)__get_free_page(GFP_KERNEL | GFP_DMA); + if (!devpriv->dma[i].buf) + return -ENOMEM; + } return 0; } @@ -1150,36 +1173,9 @@ static int dt282x_attach(struct comedi_device *dev, struct comedi_devconfig *it) return -ENOMEM; /* an IRQ and 2 DMA channels are required for async command support */ - if (it->options[1] && it->options[2] && it->options[3]) { - unsigned int irq = it->options[1]; - unsigned int dma1 = it->options[2]; - unsigned int dma2 = it->options[3]; - - if (dma2 < dma1) { - unsigned int swap; - - swap = dma1; - dma1 = dma2; - dma2 = swap; - } - - if (dma1 != dma2 && - dma1 >= 5 && dma1 <= 7 && - dma2 >= 5 && dma2 <= 7) { - ret = request_irq(irq, dt282x_interrupt, 0, - dev->board_name, dev); - if (ret == 0) { - dev->irq = irq; - - ret = dt282x_grab_dma(dev, dma1, dma2); - if (ret < 0) { - dt282x_free_dma(dev); - free_irq(dev->irq, dev); - dev->irq = 0; - } - } - } - } + ret = dt282x_alloc_dma(dev, it); + if (ret) + return ret; ret = comedi_alloc_subdevices(dev, 3); if (ret) -- 2.0.3 ___ devel mailing list de...@linuxdriverproject.org http://driverdev.linuxdriverproject.org/mailman/listinfo/driverdev-devel
[PATCH 04/37] staging: comedi: das1800: introduce struct das1800_dma_desc
For aesthetics, introduce a struct to hold the DMA descriptor data. Signed-off-by: H Hartley Sweeten Cc: Ian Abbott Cc: Greg Kroah-Hartman --- drivers/staging/comedi/drivers/das1800.c | 145 +++ 1 file changed, 70 insertions(+), 75 deletions(-) diff --git a/drivers/staging/comedi/drivers/das1800.c b/drivers/staging/comedi/drivers/das1800.c index 2e087b1..2d376fd 100644 --- a/drivers/staging/comedi/drivers/das1800.c +++ b/drivers/staging/comedi/drivers/das1800.c @@ -420,6 +420,11 @@ static const struct das1800_board das1800_boards[] = { }, }; +struct das1800_dma_desc { + unsigned int chan; /* DMA channel */ + uint16_t *virt_addr;/* virtual address of DMA buffer */ +}; + struct das1800_private { unsigned int divisor1; /* value to load into board's counter 1 for timed conversions */ unsigned int divisor2; /* value to load into board's counter 2 for timed conversions */ @@ -427,12 +432,8 @@ struct das1800_private { /* dma bits for control register b, stored so that dma can be * turned on and off */ int dma_bits; - unsigned int dma0; /* dma channels used */ - unsigned int dma1; - unsigned int dma_current; /* dma channel currently in use */ - uint16_t *ai_buf0; /* pointers to dma buffers */ - uint16_t *ai_buf1; - uint16_t *dma_current_buf; /* pointer to dma buffer currently being used */ + struct das1800_dma_desc dma_desc[2]; + int cur_dma; uint16_t *fifo_buf; /* bounce buffer for analog input FIFO */ unsigned int dma_transfer_size; /* size of transfer currently used, in bytes */ unsigned long iobase2; /* secondary io address used for analog out on 'ao' boards */ @@ -540,24 +541,18 @@ static void das1800_flush_dma(struct comedi_device *dev, struct comedi_subdevice *s) { struct das1800_private *devpriv = dev->private; + struct das1800_dma_desc *dma = &devpriv->dma_desc[devpriv->cur_dma]; unsigned long flags; const int dual_dma = devpriv->irq_dma_bits & DMA_DUAL; flags = claim_dma_lock(); - das1800_flush_dma_channel(dev, s, devpriv->dma_current, - devpriv->dma_current_buf); + das1800_flush_dma_channel(dev, s, dma->chan, dma->virt_addr); if (dual_dma) { /* switch to other channel and flush it */ - if (devpriv->dma_current == devpriv->dma0) { - devpriv->dma_current = devpriv->dma1; - devpriv->dma_current_buf = devpriv->ai_buf1; - } else { - devpriv->dma_current = devpriv->dma0; - devpriv->dma_current_buf = devpriv->ai_buf0; - } - das1800_flush_dma_channel(dev, s, devpriv->dma_current, - devpriv->dma_current_buf); + devpriv->cur_dma = 1 - devpriv->cur_dma; + dma = &devpriv->dma_desc[devpriv->cur_dma]; + das1800_flush_dma_channel(dev, s, dma->chan, dma->virt_addr); } release_dma_lock(flags); @@ -570,47 +565,43 @@ static void das1800_handle_dma(struct comedi_device *dev, struct comedi_subdevice *s, unsigned int status) { struct das1800_private *devpriv = dev->private; + struct das1800_dma_desc *dma = &devpriv->dma_desc[devpriv->cur_dma]; unsigned long flags; const int dual_dma = devpriv->irq_dma_bits & DMA_DUAL; flags = claim_dma_lock(); - das1800_flush_dma_channel(dev, s, devpriv->dma_current, - devpriv->dma_current_buf); + das1800_flush_dma_channel(dev, s, dma->chan, dma->virt_addr); /* re-enable dma channel */ - set_dma_addr(devpriv->dma_current, -virt_to_bus(devpriv->dma_current_buf)); - set_dma_count(devpriv->dma_current, devpriv->dma_transfer_size); - enable_dma(devpriv->dma_current); + set_dma_addr(dma->chan, virt_to_bus(dma->virt_addr)); + set_dma_count(dma->chan, devpriv->dma_transfer_size); + enable_dma(dma->chan); release_dma_lock(flags); if (status & DMATC) { /* clear DMATC interrupt bit */ outb(CLEAR_INTR_MASK & ~DMATC, dev->iobase + DAS1800_STATUS); /* switch dma channels for next time, if appropriate */ - if (dual_dma) { - /* read data from the other channel next time */ - if (devpriv->dma_current == devpriv->dma0) { - devpriv->dma_current = devpriv->dma1; - devpriv->dma_current_buf = devpriv->ai_buf1; - } else { - devpriv->dma_current = devpriv->dma0; - devpriv->dma_curre
[PATCH 35/37] staging: comedi: das16 introduce das16_alloc_dma()
DMA is optional with this driver. Introduce a helper function to request the DMA channel and allocate the buffers. Don't fail the driver attach if the user passed an invalid DMA channel or the channel cannot be requested. Signed-off-by: H Hartley Sweeten Cc: Ian Abbott Cc: Greg Kroah-Hartman --- drivers/staging/comedi/drivers/das16.c | 72 ++ 1 file changed, 38 insertions(+), 34 deletions(-) diff --git a/drivers/staging/comedi/drivers/das16.c b/drivers/staging/comedi/drivers/das16.c index 1c32cbc..0f4a587 100644 --- a/drivers/staging/comedi/drivers/das16.c +++ b/drivers/staging/comedi/drivers/das16.c @@ -993,6 +993,41 @@ static void das16_reset(struct comedi_device *dev) outb(0, dev->iobase + DAS16_TIMER_BASE_REG + i8254_control_reg); } +static int das16_alloc_dma(struct comedi_device *dev, unsigned int dma_chan) +{ + struct das16_private_struct *devpriv = dev->private; + struct das16_dma_desc *dma; + unsigned long flags; + int i; + + if (!(dma_chan == 1 || dma_chan == 3)) + return 0; + + if (request_dma(dma_chan, dev->board_name)) + return 0; + devpriv->dma_chan = dma_chan; + + for (i = 0; i < 2; i++) { + dma = &devpriv->dma_desc[i]; + + dma->virt_addr = pci_alloc_consistent(NULL, DAS16_DMA_SIZE, + &dma->hw_addr); + if (!dma->virt_addr) + return -ENOMEM; + } + + flags = claim_dma_lock(); + disable_dma(devpriv->dma_chan); + set_dma_mode(devpriv->dma_chan, DMA_MODE_READ); + release_dma_lock(flags); + + init_timer(&devpriv->timer); + devpriv->timer.function = das16_timer_interrupt; + devpriv->timer.data = (unsigned long)dev; + + return 0; +} + static int das16_attach(struct comedi_device *dev, struct comedi_devconfig *it) { const struct das16_board *board = dev->board_ptr; @@ -1000,7 +1035,6 @@ static int das16_attach(struct comedi_device *dev, struct comedi_devconfig *it) struct comedi_subdevice *s; struct comedi_lrange *lrange; struct comedi_krange *krange; - unsigned int dma_chan = it->options[2]; unsigned int status; int ret; @@ -1055,39 +1089,9 @@ static int das16_attach(struct comedi_device *dev, struct comedi_devconfig *it) devpriv->clockbase = I8254_OSC_BASE_1MHZ; } - /* initialize dma */ - if (dma_chan == 1 || dma_chan == 3) { - unsigned long flags; - int i; - - if (request_dma(dma_chan, dev->board_name)) { - dev_err(dev->class_dev, - "failed to request dma channel %i\n", - dma_chan); - return -EINVAL; - } - devpriv->dma_chan = dma_chan; - - /* allocate dma buffers */ - for (i = 0; i < 2; i++) { - struct das16_dma_desc *dma = &devpriv->dma_desc[i]; - - dma->virt_addr = pci_alloc_consistent(NULL, - DAS16_DMA_SIZE, - &dma->hw_addr); - if (!dma->virt_addr) - return -ENOMEM; - } - - flags = claim_dma_lock(); - disable_dma(devpriv->dma_chan); - set_dma_mode(devpriv->dma_chan, DMA_MODE_READ); - release_dma_lock(flags); - - init_timer(&devpriv->timer); - devpriv->timer.function = das16_timer_interrupt; - devpriv->timer.data = (unsigned long)dev; - } + ret = das16_alloc_dma(dev, it->options[2]); + if (ret) + return ret; /* get any user-defined input range */ if (board->ai_pg == das16_pg_none && -- 2.0.3 ___ devel mailing list de...@linuxdriverproject.org http://driverdev.linuxdriverproject.org/mailman/listinfo/driverdev-devel
[PATCH 34/37] staging: comedi: das16: introduce struct das16_dma_desc
For aesthetics, introduce a struct to hold the DMA descriptor data. Signed-off-by: H Hartley Sweeten Cc: Ian Abbott Cc: Greg Kroah-Hartman --- drivers/staging/comedi/drivers/das16.c | 48 ++ 1 file changed, 26 insertions(+), 22 deletions(-) diff --git a/drivers/staging/comedi/drivers/das16.c b/drivers/staging/comedi/drivers/das16.c index 64b0ada..1c32cbc 100644 --- a/drivers/staging/comedi/drivers/das16.c +++ b/drivers/staging/comedi/drivers/das16.c @@ -439,6 +439,11 @@ static inline int timer_period(void) return HZ / 20; } +struct das16_dma_desc { + uint16_t *virt_addr;/* virtual address of DMA buffer */ + dma_addr_t hw_addr; /* hardware (bus) address of DMA buffer */ +}; + struct das16_private_struct { unsigned intclockbase; unsigned intctrl_reg; @@ -446,9 +451,8 @@ struct das16_private_struct { unsigned intdivisor1; unsigned intdivisor2; unsigned intdma_chan; - uint16_t*dma_buffer[2]; - dma_addr_t dma_buffer_addr[2]; - unsigned intcurrent_buffer; + struct das16_dma_desc dma_desc[2]; + unsigned intcur_dma; unsigned intdma_transfer_size; struct comedi_lrange*user_ai_range_table; struct comedi_lrange*user_ao_range_table; @@ -528,11 +532,12 @@ static void das16_interrupt(struct comedi_device *dev) struct comedi_subdevice *s = dev->read_subdev; struct comedi_async *async = s->async; struct comedi_cmd *cmd = &async->cmd; + struct das16_dma_desc *dma = &devpriv->dma_desc[devpriv->cur_dma]; + struct das16_dma_desc *nxt_dma; unsigned long spin_flags; unsigned long dma_flags; unsigned int nsamples; int num_bytes, residue; - int buffer_index; spin_lock_irqsave(&dev->spinlock, spin_flags); if (!(devpriv->ctrl_reg & DAS16_CTRL_DMAE)) { @@ -558,14 +563,13 @@ static void das16_interrupt(struct comedi_device *dev) async->events |= COMEDI_CB_EOA; } - buffer_index = devpriv->current_buffer; - devpriv->current_buffer = (devpriv->current_buffer + 1) % 2; + devpriv->cur_dma = 1 - devpriv->cur_dma; devpriv->adc_byte_count -= num_bytes; /* re-enable dma */ if ((async->events & COMEDI_CB_EOA) == 0) { - set_dma_addr(devpriv->dma_chan, -devpriv->dma_buffer_addr[devpriv->current_buffer]); + nxt_dma = &devpriv->dma_desc[devpriv->cur_dma]; + set_dma_addr(devpriv->dma_chan, nxt_dma->hw_addr); set_dma_count(devpriv->dma_chan, devpriv->dma_transfer_size); enable_dma(devpriv->dma_chan); } @@ -574,8 +578,7 @@ static void das16_interrupt(struct comedi_device *dev) spin_unlock_irqrestore(&dev->spinlock, spin_flags); nsamples = comedi_bytes_to_samples(s, num_bytes); - comedi_buf_write_samples(s, devpriv->dma_buffer[buffer_index], -nsamples); + comedi_buf_write_samples(s, dma->virt_addr, nsamples); comedi_handle_events(dev, s); } @@ -746,6 +749,7 @@ static int das16_cmd_exec(struct comedi_device *dev, struct comedi_subdevice *s) { const struct das16_board *board = dev->board_ptr; struct das16_private_struct *devpriv = dev->private; + struct das16_dma_desc *dma = &devpriv->dma_desc[0]; struct comedi_async *async = s->async; struct comedi_cmd *cmd = &async->cmd; unsigned int byte; @@ -800,9 +804,8 @@ static int das16_cmd_exec(struct comedi_device *dev, struct comedi_subdevice *s) /* clear flip-flop to make sure 2-byte registers for * count and address get set correctly */ clear_dma_ff(devpriv->dma_chan); - devpriv->current_buffer = 0; - set_dma_addr(devpriv->dma_chan, -devpriv->dma_buffer_addr[devpriv->current_buffer]); + devpriv->cur_dma = 0; + set_dma_addr(devpriv->dma_chan, dma->hw_addr); devpriv->dma_transfer_size = DAS16_DMA_SIZE; set_dma_count(devpriv->dma_chan, devpriv->dma_transfer_size); enable_dma(devpriv->dma_chan); @@ -1067,13 +1070,13 @@ static int das16_attach(struct comedi_device *dev, struct comedi_devconfig *it) /* allocate dma buffers */ for (i = 0; i < 2; i++) { - void *p; + struct das16_dma_desc *dma = &devpriv->dma_desc[i]; - p = pci_alloc_consistent(NULL, DAS16_DMA_SIZE, -&devpriv->dma_buffer_addr[i]); - if (!p) + dma->virt_addr = pci_alloc_consistent(NULL, + DAS16_DMA_SIZE, +
[PATCH 21/37] staging: comedi: pcl818: fix pcl818_handle_dma() for short DMA transaction
Currently this function always transfers the full DMA buffer to the comedi async buffer. When the cmd->stop_src == TRIG_COUNT the last DMA transfer might be smaller than the buffer size. This results in invalid data being added to the asunc buffer. Add a 'size' member to the DMA descriptor and initialize it with the actual size of the DMA transfer. Use that in pcl818_handle_dma() to return the proper number of samples. Use the comedi_bytes_to_samples() helper to convert the byte size to comedi samples. Remove the unnecessary 'bufptr' local variable. Signed-off-by: H Hartley Sweeten Cc: Ian Abbott Cc: Greg Kroah-Hartman --- drivers/staging/comedi/drivers/pcl818.c | 34 - 1 file changed, 17 insertions(+), 17 deletions(-) diff --git a/drivers/staging/comedi/drivers/pcl818.c b/drivers/staging/comedi/drivers/pcl818.c index 3656ecf..19f6b59 100644 --- a/drivers/staging/comedi/drivers/pcl818.c +++ b/drivers/staging/comedi/drivers/pcl818.c @@ -305,6 +305,7 @@ static const struct pcl818_board boardtypes[] = { struct pcl818_dma_desc { void *virt_addr;/* virtual address of DMA buffer */ dma_addr_t hw_addr; /* hardware (bus) address of DMA buffer */ + unsigned int size; /* transfer size (in bytes) */ }; struct pcl818_private { @@ -349,17 +350,17 @@ static void pcl818_ai_setup_dma(struct comedi_device *dev, struct pcl818_dma_desc *dma = &devpriv->dma_desc[0]; struct comedi_cmd *cmd = &s->async->cmd; unsigned int flags; - unsigned int bytes; disable_dma(devpriv->dma); /* disable dma */ - bytes = devpriv->hwdmasize; if (cmd->stop_src == TRIG_COUNT) { - bytes = cmd->stop_arg * comedi_bytes_per_scan(s); - devpriv->dma_runs_to_end = bytes / devpriv->hwdmasize; - devpriv->last_dma_run = bytes % devpriv->hwdmasize; + dma->size = cmd->stop_arg * comedi_bytes_per_scan(s); + devpriv->dma_runs_to_end = dma->size / devpriv->hwdmasize; + devpriv->last_dma_run = dma->size % devpriv->hwdmasize; devpriv->dma_runs_to_end--; if (devpriv->dma_runs_to_end >= 0) - bytes = devpriv->hwdmasize; + dma->size = devpriv->hwdmasize; + } else { + dma->size = devpriv->hwdmasize; } devpriv->cur_dma = 0; @@ -367,7 +368,7 @@ static void pcl818_ai_setup_dma(struct comedi_device *dev, flags = claim_dma_lock(); clear_dma_ff(devpriv->dma); set_dma_addr(devpriv->dma, dma->hw_addr); - set_dma_count(devpriv->dma, bytes); + set_dma_count(devpriv->dma, dma->size); release_dma_lock(flags); enable_dma(devpriv->dma); } @@ -385,13 +386,14 @@ static void pcl818_ai_setup_next_dma(struct comedi_device *dev, if (devpriv->dma_runs_to_end > -1 || cmd->stop_src == TRIG_NONE) { /* switch dma bufs */ dma = &devpriv->dma_desc[devpriv->cur_dma]; + if (devpriv->dma_runs_to_end || cmd->stop_src == TRIG_NONE) + dma->size = devpriv->hwdmasize; + else + dma->size = devpriv->last_dma_run; set_dma_mode(devpriv->dma, DMA_MODE_READ); flags = claim_dma_lock(); set_dma_addr(devpriv->dma, dma->hw_addr); - if (devpriv->dma_runs_to_end || cmd->stop_src == TRIG_NONE) - set_dma_count(devpriv->dma, devpriv->hwdmasize); - else - set_dma_count(devpriv->dma, devpriv->last_dma_run); + set_dma_count(devpriv->dma, dma->size); release_dma_lock(flags); enable_dma(devpriv->dma); } @@ -565,17 +567,15 @@ static void pcl818_handle_dma(struct comedi_device *dev, struct pcl818_private *devpriv = dev->private; struct pcl818_dma_desc *dma = &devpriv->dma_desc[devpriv->cur_dma]; unsigned short *ptr = dma->virt_addr; + unsigned int nsamples = comedi_bytes_to_samples(s, dma->size); unsigned int chan; unsigned int val; - int i, len, bufptr; + int i; pcl818_ai_setup_next_dma(dev, s); - len = devpriv->hwdmasize >> 1; - bufptr = 0; - - for (i = 0; i < len; i++) { - val = ptr[bufptr++]; + for (i = 0; i < nsamples; i++) { + val = ptr[i]; chan = val & 0xf; val = (val >> 4) & s->maxdata; -- 2.0.3 ___ devel mailing list de...@linuxdriverproject.org http://driverdev.linuxdriverproject.org/mailman/listinfo/driverdev-devel
[PATCH 20/37] staging: comedi: pcl818: remove VIRT_TO_BUS dependancy
Use dma_{alloc,free}_coherent() to allocate and free the DMA buffers. This removes the dependancy on VIRT_TO_BUS. Signed-off-by: H Hartley Sweeten Cc: Ian Abbott Cc: Greg Kroah-Hartman --- drivers/staging/comedi/Kconfig | 2 +- drivers/staging/comedi/drivers/pcl818.c | 25 - 2 files changed, 13 insertions(+), 14 deletions(-) diff --git a/drivers/staging/comedi/Kconfig b/drivers/staging/comedi/Kconfig index 76d66e0..c48ee22 100644 --- a/drivers/staging/comedi/Kconfig +++ b/drivers/staging/comedi/Kconfig @@ -188,7 +188,7 @@ config COMEDI_PCL816 config COMEDI_PCL818 tristate "Advantech PCL-718 and PCL-818 ISA card support" - depends on VIRT_TO_BUS && ISA_DMA_API + depends on ISA_DMA_API ---help--- Enable support for Advantech PCL-818 ISA cards PCL-818L, PCL-818H, PCL-818HD, PCL-818HG, PCL-818 and PCL-718 diff --git a/drivers/staging/comedi/drivers/pcl818.c b/drivers/staging/comedi/drivers/pcl818.c index f34c5cc0..3656ecf 100644 --- a/drivers/staging/comedi/drivers/pcl818.c +++ b/drivers/staging/comedi/drivers/pcl818.c @@ -303,13 +303,12 @@ static const struct pcl818_board boardtypes[] = { }; struct pcl818_dma_desc { - unsigned long dmabuf; /* pointers to begin of DMA buffers */ - unsigned int hwdmaptr; /* hardware address of DMA buffers */ + void *virt_addr;/* virtual address of DMA buffer */ + dma_addr_t hw_addr; /* hardware (bus) address of DMA buffer */ }; struct pcl818_private { unsigned int dma; /* used DMA, 0=don't use DMA */ - unsigned int dmapages; unsigned int hwdmasize; struct pcl818_dma_desc dma_desc[2]; int cur_dma; @@ -367,7 +366,7 @@ static void pcl818_ai_setup_dma(struct comedi_device *dev, set_dma_mode(devpriv->dma, DMA_MODE_READ); flags = claim_dma_lock(); clear_dma_ff(devpriv->dma); - set_dma_addr(devpriv->dma, dma->hwdmaptr); + set_dma_addr(devpriv->dma, dma->hw_addr); set_dma_count(devpriv->dma, bytes); release_dma_lock(flags); enable_dma(devpriv->dma); @@ -388,7 +387,7 @@ static void pcl818_ai_setup_next_dma(struct comedi_device *dev, dma = &devpriv->dma_desc[devpriv->cur_dma]; set_dma_mode(devpriv->dma, DMA_MODE_READ); flags = claim_dma_lock(); - set_dma_addr(devpriv->dma, dma->hwdmaptr); + set_dma_addr(devpriv->dma, dma->hw_addr); if (devpriv->dma_runs_to_end || cmd->stop_src == TRIG_NONE) set_dma_count(devpriv->dma, devpriv->hwdmasize); else @@ -565,7 +564,7 @@ static void pcl818_handle_dma(struct comedi_device *dev, { struct pcl818_private *devpriv = dev->private; struct pcl818_dma_desc *dma = &devpriv->dma_desc[devpriv->cur_dma]; - unsigned short *ptr = (unsigned short *)dma->dmabuf; + unsigned short *ptr = dma->virt_addr; unsigned int chan; unsigned int val; int i, len, bufptr; @@ -1072,16 +1071,15 @@ static int pcl818_alloc_dma(struct comedi_device *dev, unsigned int dma_chan) return 0; devpriv->dma = dma_chan; - devpriv->dmapages = 2; /* we need 16KB */ - devpriv->hwdmasize = (1 << devpriv->dmapages) * PAGE_SIZE; + devpriv->hwdmasize = PAGE_SIZE * 4; /* we need 16KB */ for (i = 0; i < 2; i++) { dma = &devpriv->dma_desc[i]; - dma->dmabuf = __get_dma_pages(GFP_KERNEL, devpriv->dmapages); - if (!dma->dmabuf) + dma->virt_addr = dma_alloc_coherent(NULL, devpriv->hwdmasize, + &dma->hw_addr, GFP_KERNEL); + if (!dma->virt_addr) return -ENOMEM; - dma->hwdmaptr = virt_to_bus((void *)dma->dmabuf); } return 0; } @@ -1099,8 +1097,9 @@ static void pcl818_free_dma(struct comedi_device *dev) free_dma(devpriv->dma); for (i = 0; i < 2; i++) { dma = &devpriv->dma_desc[i]; - if (dma->dmabuf) - free_pages(dma->dmabuf, devpriv->dmapages); + if (dma->virt_addr) + dma_free_coherent(NULL, devpriv->hwdmasize, + dma->virt_addr, dma->hw_addr); } } -- 2.0.3 ___ devel mailing list de...@linuxdriverproject.org http://driverdev.linuxdriverproject.org/mailman/listinfo/driverdev-devel
[PATCH 37/37] staging: comedi: das16: board is not a PCI device
The DAS16 board is an ISA device not a PCI device. For aesthetics, use dma_{alloc,free}_coherent() to allocate and free the DMA buffers instead of the PCI versions. Signed-off-by: H Hartley Sweeten Cc: Ian Abbott Cc: Greg Kroah-Hartman --- drivers/staging/comedi/drivers/das16.c | 9 - 1 file changed, 4 insertions(+), 5 deletions(-) diff --git a/drivers/staging/comedi/drivers/das16.c b/drivers/staging/comedi/drivers/das16.c index e0b41ae..294cd81 100644 --- a/drivers/staging/comedi/drivers/das16.c +++ b/drivers/staging/comedi/drivers/das16.c @@ -72,7 +72,6 @@ #include #include #include -#include #include #include @@ -1010,8 +1009,8 @@ static int das16_alloc_dma(struct comedi_device *dev, unsigned int dma_chan) for (i = 0; i < 2; i++) { dma = &devpriv->dma_desc[i]; - dma->virt_addr = pci_alloc_consistent(NULL, DAS16_DMA_SIZE, - &dma->hw_addr); + dma->virt_addr = dma_alloc_coherent(NULL, DAS16_DMA_SIZE, + &dma->hw_addr, GFP_KERNEL); if (!dma->virt_addr) return -ENOMEM; } @@ -1039,8 +1038,8 @@ static void das16_free_dma(struct comedi_device *dev) for (i = 0; i < 2; i++) { dma = &devpriv->dma_desc[i]; if (dma->virt_addr) - pci_free_consistent(NULL, DAS16_DMA_SIZE, - dma->virt_addr, dma->hw_addr); + dma_free_coherent(NULL, DAS16_DMA_SIZE, + dma->virt_addr, dma->hw_addr); } if (devpriv->dma_chan) free_dma(devpriv->dma_chan); -- 2.0.3 ___ devel mailing list de...@linuxdriverproject.org http://driverdev.linuxdriverproject.org/mailman/listinfo/driverdev-devel
[PATCH 29/37] staging: comedi: pcl812: introduce struct pcl812_dma_desc
For aesthetics, introduce a struct to hold the DMA descriptor data. Signed-off-by: H Hartley Sweeten Cc: Ian Abbott Cc: Greg Kroah-Hartman --- drivers/staging/comedi/drivers/pcl812.c | 100 1 file changed, 50 insertions(+), 50 deletions(-) diff --git a/drivers/staging/comedi/drivers/pcl812.c b/drivers/staging/comedi/drivers/pcl812.c index b628f06..d9f94c9 100644 --- a/drivers/staging/comedi/drivers/pcl812.c +++ b/drivers/staging/comedi/drivers/pcl812.c @@ -506,6 +506,12 @@ static const struct pcl812_board boardtypes[] = { }, }; +struct pcl812_dma_desc { + unsigned long virt_addr;/* virtual address of DMA buffer */ + unsigned int hw_addr; /* hardware (bus) address of DMA buffer */ + unsigned int size; /* transfer size (in bytes) */ +}; + struct pcl812_private { unsigned char dma; /* >0 use dma ( usedDMA channel) */ unsigned char range_correction; /* =1 we must add 1 to range number */ @@ -514,10 +520,8 @@ struct pcl812_private { unsigned int ai_poll_ptr; /* how many sampes transfer poll */ unsigned int dmapages; unsigned int hwdmasize; - unsigned long dmabuf[2];/* PTR to DMA buf */ - unsigned int hwdmaptr[2]; /* HW PTR to DMA buf */ - unsigned int dmabytestomove[2]; /* how many bytes DMA transfer */ - int next_dma_buf; /* which buffer is next to use */ + struct pcl812_dma_desc dma_desc[2]; + int cur_dma; unsigned int dma_runs_to_end; /* how many times we must switch DMA buffers */ unsigned int last_dma_run; /* how many bytes to transfer on last DMA buffer */ unsigned int max_812_ai_mode0_rangewait;/* setling time for gain */ @@ -549,23 +553,23 @@ static void pcl812_ai_setup_dma(struct comedi_device *dev, struct comedi_subdevice *s) { struct pcl812_private *devpriv = dev->private; + struct pcl812_dma_desc *dma0 = &devpriv->dma_desc[0]; + struct pcl812_dma_desc *dma1 = &devpriv->dma_desc[1]; struct comedi_cmd *cmd = &s->async->cmd; unsigned int dma_flags; unsigned int bytes; /* we use EOS, so adapt DMA buffer to one scan */ if (devpriv->ai_eos) { - devpriv->dmabytestomove[0] = comedi_bytes_per_scan(s); - devpriv->dmabytestomove[1] = comedi_bytes_per_scan(s); + dma0->size = comedi_bytes_per_scan(s); + dma1->size = comedi_bytes_per_scan(s); devpriv->dma_runs_to_end = 1; } else { - devpriv->dmabytestomove[0] = devpriv->hwdmasize; - devpriv->dmabytestomove[1] = devpriv->hwdmasize; + dma0->size = devpriv->hwdmasize; + dma1->size = devpriv->hwdmasize; if (s->async->prealloc_bufsz < devpriv->hwdmasize) { - devpriv->dmabytestomove[0] = - s->async->prealloc_bufsz; - devpriv->dmabytestomove[1] = - s->async->prealloc_bufsz; + dma0->size = s->async->prealloc_bufsz; + dma1->size = s->async->prealloc_bufsz; } if (cmd->stop_src == TRIG_NONE) { devpriv->dma_runs_to_end = 1; @@ -574,32 +578,29 @@ static void pcl812_ai_setup_dma(struct comedi_device *dev, bytes = cmd->stop_arg * comedi_bytes_per_scan(s); /* how many DMA pages we must fill */ - devpriv->dma_runs_to_end = - bytes / devpriv->dmabytestomove[0]; + devpriv->dma_runs_to_end = bytes / dma0->size; /* on last dma transfer must be moved */ - devpriv->last_dma_run = - bytes % devpriv->dmabytestomove[0]; + devpriv->last_dma_run = bytes % dma0->size; if (devpriv->dma_runs_to_end == 0) - devpriv->dmabytestomove[0] = - devpriv->last_dma_run; + dma0->size = devpriv->last_dma_run; devpriv->dma_runs_to_end--; } } - if (devpriv->dmabytestomove[0] > devpriv->hwdmasize) { - devpriv->dmabytestomove[0] = devpriv->hwdmasize; + if (dma0->size > devpriv->hwdmasize) { + dma0->size = devpriv->hwdmasize; devpriv->ai_eos = 0; } - if (devpriv->dmabytestomove[1] > devpriv->hwdmasize) { - devpriv->dmabytestomove[1] = devpriv->hwdmasize; + if (dma1->size > devpriv->hwdmasize) { + dma1->size = devpriv->hwdmasize; devpriv->ai_eos = 0; } - devpriv->next_dma_buf = 0; + devpriv->cur_dma = 0;
[PATCH 06/37] staging: comedi: das1800: remove VIRT_TO_BUS dependancy
Use dma_{alloc,free}_coherent() to allocate and free the DMA buffers. This removes the dependancy on VIRT_TO_BUS. Signed-off-by: H Hartley Sweeten Cc: Ian Abbott Cc: Greg Kroah-Hartman --- drivers/staging/comedi/Kconfig | 2 +- drivers/staging/comedi/drivers/das1800.c | 16 ++-- 2 files changed, 11 insertions(+), 7 deletions(-) diff --git a/drivers/staging/comedi/Kconfig b/drivers/staging/comedi/Kconfig index 1cdbf1f..fe030a3 100644 --- a/drivers/staging/comedi/Kconfig +++ b/drivers/staging/comedi/Kconfig @@ -309,7 +309,7 @@ config COMEDI_DAS800 config COMEDI_DAS1800 tristate "DAS1800 and compatible ISA card support" - depends on VIRT_TO_BUS && ISA_DMA_API + depends on ISA_DMA_API ---help--- Enable support for DAS1800 and compatible ISA cards Keithley Metrabyte DAS-1701ST, DAS-1701ST-DA, DAS-1701/AO, diff --git a/drivers/staging/comedi/drivers/das1800.c b/drivers/staging/comedi/drivers/das1800.c index df28d36a..dd46a91 100644 --- a/drivers/staging/comedi/drivers/das1800.c +++ b/drivers/staging/comedi/drivers/das1800.c @@ -422,7 +422,8 @@ static const struct das1800_board das1800_boards[] = { struct das1800_dma_desc { unsigned int chan; /* DMA channel */ - uint16_t *virt_addr;/* virtual address of DMA buffer */ + void *virt_addr;/* virtual address of DMA buffer */ + dma_addr_t hw_addr; /* hardware (bus) address of DMA buffer */ }; struct das1800_private { @@ -572,7 +573,7 @@ static void das1800_handle_dma(struct comedi_device *dev, flags = claim_dma_lock(); das1800_flush_dma_channel(dev, s, dma->chan, dma->virt_addr); /* re-enable dma channel */ - set_dma_addr(dma->chan, virt_to_bus(dma->virt_addr)); + set_dma_addr(dma->chan, dma->hw_addr); set_dma_count(dma->chan, devpriv->dma_transfer_size); enable_dma(dma->chan); release_dma_lock(flags); @@ -1013,7 +1014,7 @@ static void setup_dma(struct comedi_device *dev, const struct comedi_cmd *cmd) /* clear flip-flop to make sure 2-byte registers for * count and address get set correctly */ clear_dma_ff(dma->chan); - set_dma_addr(dma->chan, virt_to_bus(dma->virt_addr)); + set_dma_addr(dma->chan, dma->hw_addr); /* set appropriate size of transfer */ set_dma_count(dma->chan, devpriv->dma_transfer_size); enable_dma(dma->chan); @@ -1024,7 +1025,7 @@ static void setup_dma(struct comedi_device *dev, const struct comedi_cmd *cmd) /* clear flip-flop to make sure 2-byte registers for * count and address get set correctly */ clear_dma_ff(dma->chan); - set_dma_addr(dma->chan, virt_to_bus(dma->virt_addr)); + set_dma_addr(dma->chan, dma->hw_addr); /* set appropriate size of transfer */ set_dma_count(dma->chan, devpriv->dma_transfer_size); enable_dma(dma->chan); @@ -1288,7 +1289,8 @@ static int das1800_init_dma(struct comedi_device *dev, } dma->chan = dma_chan[i]; - dma->virt_addr = kmalloc(DMA_BUF_SIZE, GFP_KERNEL | GFP_DMA); + dma->virt_addr = dma_alloc_coherent(NULL, DMA_BUF_SIZE, + &dma->hw_addr, GFP_KERNEL); if (!dma->virt_addr) return -ENOMEM; @@ -1520,7 +1522,9 @@ static void das1800_detach(struct comedi_device *dev) dma = &devpriv->dma_desc[i]; if (dma->chan) free_dma(dma->chan); - kfree(dma->virt_addr); + if (dma->virt_addr) + dma_free_coherent(NULL, DMA_BUF_SIZE, + dma->virt_addr, dma->hw_addr); } kfree(devpriv->fifo_buf); if (devpriv->iobase2) -- 2.0.3 ___ devel mailing list de...@linuxdriverproject.org http://driverdev.linuxdriverproject.org/mailman/listinfo/driverdev-devel
[PATCH 28/37] staging: comedi: pcl812: introduce pcl812_free_dma()
For aesthetics, move the freeing of the DMA channel and the buffers to a helper function. Signed-off-by: H Hartley Sweeten Cc: Ian Abbott Cc: Greg Kroah-Hartman --- drivers/staging/comedi/drivers/pcl812.c | 27 +-- 1 file changed, 17 insertions(+), 10 deletions(-) diff --git a/drivers/staging/comedi/drivers/pcl812.c b/drivers/staging/comedi/drivers/pcl812.c index 38cf14e..b628f06 100644 --- a/drivers/staging/comedi/drivers/pcl812.c +++ b/drivers/staging/comedi/drivers/pcl812.c @@ -1220,6 +1220,22 @@ static int pcl812_alloc_dma(struct comedi_device *dev, unsigned int dma_chan) return 0; } +static void pcl812_free_dma(struct comedi_device *dev) +{ + struct pcl812_private *devpriv = dev->private; + int i; + + if (!devpriv) + return; + + for (i = 0; i < 2; i++) { + if (devpriv->dmabuf[i]) + free_pages(devpriv->dmabuf[i], devpriv->dmapages); + } + if (devpriv->dma) + free_dma(devpriv->dma); +} + static int pcl812_attach(struct comedi_device *dev, struct comedi_devconfig *it) { const struct pcl812_board *board = dev->board_ptr; @@ -1391,16 +1407,7 @@ static int pcl812_attach(struct comedi_device *dev, struct comedi_devconfig *it) static void pcl812_detach(struct comedi_device *dev) { - struct pcl812_private *devpriv = dev->private; - - if (devpriv) { - if (devpriv->dmabuf[0]) - free_pages(devpriv->dmabuf[0], devpriv->dmapages); - if (devpriv->dmabuf[1]) - free_pages(devpriv->dmabuf[1], devpriv->dmapages); - if (devpriv->dma) - free_dma(devpriv->dma); - } + pcl812_free_dma(dev); comedi_legacy_detach(dev); } -- 2.0.3 ___ devel mailing list de...@linuxdriverproject.org http://driverdev.linuxdriverproject.org/mailman/listinfo/driverdev-devel
[PATCH 18/37] staging: comedi: pcl818: introduce pcl818_dma_free()
For aesthetics, move the freeing of the DMA channel and the buffers to a helper function. Signed-off-by: H Hartley Sweeten Cc: Ian Abbott Cc: Greg Kroah-Hartman --- drivers/staging/comedi/drivers/pcl818.c | 23 +-- 1 file changed, 17 insertions(+), 6 deletions(-) diff --git a/drivers/staging/comedi/drivers/pcl818.c b/drivers/staging/comedi/drivers/pcl818.c index b25ff35..beb03ec 100644 --- a/drivers/staging/comedi/drivers/pcl818.c +++ b/drivers/staging/comedi/drivers/pcl818.c @@ -1082,6 +1082,22 @@ static int pcl818_alloc_dma(struct comedi_device *dev, unsigned int dma_chan) return 0; } +static void pcl818_free_dma(struct comedi_device *dev) +{ + struct pcl818_private *devpriv = dev->private; + int i; + + if (!devpriv) + return; + + if (devpriv->dma) + free_dma(devpriv->dma); + for (i = 0; i < 2; i++) { + if (devpriv->dmabuf[i]) + free_pages(devpriv->dmabuf[i], devpriv->dmapages); + } +} + static int pcl818_attach(struct comedi_device *dev, struct comedi_devconfig *it) { const struct pcl818_board *board = dev->board_ptr; @@ -1217,13 +1233,8 @@ static void pcl818_detach(struct comedi_device *dev) if (devpriv) { pcl818_ai_cancel(dev, dev->read_subdev); pcl818_reset(dev); - if (devpriv->dma) - free_dma(devpriv->dma); - if (devpriv->dmabuf[0]) - free_pages(devpriv->dmabuf[0], devpriv->dmapages); - if (devpriv->dmabuf[1]) - free_pages(devpriv->dmabuf[1], devpriv->dmapages); } + pcl818_free_dma(dev); comedi_legacy_detach(dev); } -- 2.0.3 ___ devel mailing list de...@linuxdriverproject.org http://driverdev.linuxdriverproject.org/mailman/listinfo/driverdev-devel
[PATCH 07/37] staging: comedi: das1800: introduce das1800_free_dma()
For aesthetics, introduce a helper function to free the DMA channels and allocated buffers. Signed-off-by: H Hartley Sweeten Cc: Ian Abbott Cc: Greg Kroah-Hartman --- drivers/staging/comedi/drivers/das1800.c | 30 -- 1 file changed, 20 insertions(+), 10 deletions(-) diff --git a/drivers/staging/comedi/drivers/das1800.c b/drivers/staging/comedi/drivers/das1800.c index dd46a91..1eb5eab 100644 --- a/drivers/staging/comedi/drivers/das1800.c +++ b/drivers/staging/comedi/drivers/das1800.c @@ -1303,6 +1303,25 @@ static int das1800_init_dma(struct comedi_device *dev, return 0; } +static void das1800_free_dma(struct comedi_device *dev) +{ + struct das1800_private *devpriv = dev->private; + struct das1800_dma_desc *dma; + int i; + + if (!devpriv) + return; + + for (i = 0; i < 2; i++) { + dma = &devpriv->dma_desc[i]; + if (dma->chan) + free_dma(dma->chan); + if (dma->virt_addr) + dma_free_coherent(NULL, DMA_BUF_SIZE, + dma->virt_addr, dma->hw_addr); + } +} + static int das1800_probe(struct comedi_device *dev) { const struct das1800_board *board = dev->board_ptr; @@ -1514,18 +1533,9 @@ static int das1800_attach(struct comedi_device *dev, static void das1800_detach(struct comedi_device *dev) { struct das1800_private *devpriv = dev->private; - struct das1800_dma_desc *dma; - int i; + das1800_free_dma(dev); if (devpriv) { - for (i = 0; i < 2; i++) { - dma = &devpriv->dma_desc[i]; - if (dma->chan) - free_dma(dma->chan); - if (dma->virt_addr) - dma_free_coherent(NULL, DMA_BUF_SIZE, - dma->virt_addr, dma->hw_addr); - } kfree(devpriv->fifo_buf); if (devpriv->iobase2) release_region(devpriv->iobase2, DAS1800_SIZE); -- 2.0.3 ___ devel mailing list de...@linuxdriverproject.org http://driverdev.linuxdriverproject.org/mailman/listinfo/driverdev-devel
[PATCH 16/37] staging: comedi: ni_labpc: remove VIRT_TO_BUS dependancy
Use dma_{alloc,free}_coherent() to allocate and free the DMA buffers. This removes the dependancy on VIRT_TO_BUS. Signed-off-by: H Hartley Sweeten Cc: Ian Abbott Cc: Greg Kroah-Hartman --- drivers/staging/comedi/Kconfig | 2 +- drivers/staging/comedi/drivers/ni_labpc.h| 4 ++-- drivers/staging/comedi/drivers/ni_labpc_isadma.c | 8 +--- 3 files changed, 8 insertions(+), 6 deletions(-) diff --git a/drivers/staging/comedi/Kconfig b/drivers/staging/comedi/Kconfig index 982b03f..76d66e0 100644 --- a/drivers/staging/comedi/Kconfig +++ b/drivers/staging/comedi/Kconfig @@ -502,7 +502,7 @@ config COMEDI_NI_ATMIO16D config COMEDI_NI_LABPC_ISA tristate "NI Lab-PC and compatibles ISA support" select COMEDI_NI_LABPC - select COMEDI_NI_LABPC_ISADMA if ISA_DMA_API && VIRT_TO_BUS + select COMEDI_NI_LABPC_ISADMA if ISA_DMA_API ---help--- Enable support for National Instruments Lab-PC and compatibles Lab-PC-1200, Lab-PC-1200AI, Lab-PC+. diff --git a/drivers/staging/comedi/drivers/ni_labpc.h b/drivers/staging/comedi/drivers/ni_labpc.h index 7ba7f2f..c26d7ee 100644 --- a/drivers/staging/comedi/drivers/ni_labpc.h +++ b/drivers/staging/comedi/drivers/ni_labpc.h @@ -36,8 +36,8 @@ struct labpc_boardinfo { struct labpc_dma_desc { unsigned int chan; /* DMA channel */ - u16 *virt_addr; /* virtual address of DMA buffer */ - phys_addr_t hw_addr;/* hardware (bus) address of DMA buffer */ + void *virt_addr;/* virtual address of DMA buffer */ + dma_addr_t hw_addr; /* hardware (bus) address of DMA buffer */ unsigned int size; /* size of DMA transfer (in bytes) */ }; diff --git a/drivers/staging/comedi/drivers/ni_labpc_isadma.c b/drivers/staging/comedi/drivers/ni_labpc_isadma.c index 829c4e4..ecdbe11 100644 --- a/drivers/staging/comedi/drivers/ni_labpc_isadma.c +++ b/drivers/staging/comedi/drivers/ni_labpc_isadma.c @@ -175,14 +175,14 @@ void labpc_init_dma_chan(struct comedi_device *dev, unsigned int dma_chan) if (request_dma(dma_chan, dev->board_name)) return; - dma->virt_addr = kmalloc(dma_buffer_size, GFP_KERNEL | GFP_DMA); + dma->virt_addr = dma_alloc_coherent(NULL, dma_buffer_size, + &dma->hw_addr, GFP_KERNEL); if (!dma->virt_addr) { free_dma(dma_chan); return; } dma->chan = dma_chan; - dma->hw_addr = virt_to_bus(dma->virt_addr); dma_flags = claim_dma_lock(); disable_dma(dma->chan); @@ -196,7 +196,9 @@ void labpc_free_dma_chan(struct comedi_device *dev) struct labpc_private *devpriv = dev->private; struct labpc_dma_desc *dma = &devpriv->dma_desc; - kfree(dma->virt_addr); + if (dma->virt_addr) + dma_free_coherent(NULL, dma_buffer_size, + dma->virt_addr, dma->hw_addr); if (dma->chan) free_dma(dma->chan); } -- 2.0.3 ___ devel mailing list de...@linuxdriverproject.org http://driverdev.linuxdriverproject.org/mailman/listinfo/driverdev-devel
[PATCH 14/37] staging: comedi: ni_labpc: introduce struct labpc_dma_desc
For aesthetics, introduce a struct to hold the DMA descriptor data. Signed-off-by: H Hartley Sweeten Cc: Ian Abbott Cc: Greg Kroah-Hartman --- drivers/staging/comedi/drivers/ni_labpc.h| 15 -- drivers/staging/comedi/drivers/ni_labpc_isadma.c | 58 drivers/staging/comedi/drivers/ni_labpc_isadma.h | 2 +- 3 files changed, 41 insertions(+), 34 deletions(-) diff --git a/drivers/staging/comedi/drivers/ni_labpc.h b/drivers/staging/comedi/drivers/ni_labpc.h index ac2c01f..7ba7f2f 100644 --- a/drivers/staging/comedi/drivers/ni_labpc.h +++ b/drivers/staging/comedi/drivers/ni_labpc.h @@ -34,6 +34,13 @@ struct labpc_boardinfo { unsigned is_labpc1200:1;/* has extra regs compared to pc+ */ }; +struct labpc_dma_desc { + unsigned int chan; /* DMA channel */ + u16 *virt_addr; /* virtual address of DMA buffer */ + phys_addr_t hw_addr;/* hardware (bus) address of DMA buffer */ + unsigned int size; /* size of DMA transfer (in bytes) */ +}; + struct labpc_private { /* number of data points left to be taken */ unsigned long long count; @@ -61,11 +68,9 @@ struct labpc_private { * conversions */ unsigned int divisor_b1; - unsigned int dma_chan; /* dma channel to use */ - u16 *dma_buffer;/* buffer ai will dma into */ - phys_addr_t dma_addr; - /* transfer size in bytes for current transfer */ - unsigned int dma_transfer_size; + + struct labpc_dma_desc dma_desc; + /* we are using dma/fifo-half-full/etc. */ enum transfer_type current_transfer; /* diff --git a/drivers/staging/comedi/drivers/ni_labpc_isadma.c b/drivers/staging/comedi/drivers/ni_labpc_isadma.c index 6d38605..b7217a7 100644 --- a/drivers/staging/comedi/drivers/ni_labpc_isadma.c +++ b/drivers/staging/comedi/drivers/ni_labpc_isadma.c @@ -60,22 +60,23 @@ static unsigned int labpc_suggest_transfer_size(const struct comedi_cmd *cmd) void labpc_setup_dma(struct comedi_device *dev, struct comedi_subdevice *s) { struct labpc_private *devpriv = dev->private; + struct labpc_dma_desc *dma = &devpriv->dma_desc; struct comedi_cmd *cmd = &s->async->cmd; unsigned long irq_flags; irq_flags = claim_dma_lock(); - disable_dma(devpriv->dma_chan); + disable_dma(dma->chan); /* clear flip-flop to make sure 2-byte registers for * count and address get set correctly */ - clear_dma_ff(devpriv->dma_chan); - set_dma_addr(devpriv->dma_chan, devpriv->dma_addr); + clear_dma_ff(dma->chan); + set_dma_addr(dma->chan, dma->hw_addr); /* set appropriate size of transfer */ - devpriv->dma_transfer_size = labpc_suggest_transfer_size(cmd); + dma->size = labpc_suggest_transfer_size(cmd); if (cmd->stop_src == TRIG_COUNT && - devpriv->count * sample_size < devpriv->dma_transfer_size) - devpriv->dma_transfer_size = devpriv->count * sample_size; - set_dma_count(devpriv->dma_chan, devpriv->dma_transfer_size); - enable_dma(devpriv->dma_chan); + devpriv->count * sample_size < dma->size) + dma->size = devpriv->count * sample_size; + set_dma_count(dma->chan, dma->size); + enable_dma(dma->chan); release_dma_lock(irq_flags); /* set CMD3 bits for caller to enable DMA and interrupt */ devpriv->cmd3 |= (CMD3_DMAEN | CMD3_DMATCINTEN); @@ -85,6 +86,7 @@ EXPORT_SYMBOL_GPL(labpc_setup_dma); void labpc_drain_dma(struct comedi_device *dev) { struct labpc_private *devpriv = dev->private; + struct labpc_dma_desc *dma = &devpriv->dma_desc; struct comedi_subdevice *s = dev->read_subdev; struct comedi_async *async = s->async; struct comedi_cmd *cmd = &async->cmd; @@ -95,18 +97,18 @@ void labpc_drain_dma(struct comedi_device *dev) status = devpriv->stat1; flags = claim_dma_lock(); - disable_dma(devpriv->dma_chan); + disable_dma(dma->chan); /* clear flip-flop to make sure 2-byte registers for * count and address get set correctly */ - clear_dma_ff(devpriv->dma_chan); + clear_dma_ff(dma->chan); /* figure out how many points to read */ - max_points = devpriv->dma_transfer_size / sample_size; + max_points = dma->size / sample_size; /* residue is the number of points left to be done on the dma * transfer. It should always be zero at this point unless * the stop_src is set to external triggering. */ - residue = get_dma_residue(devpriv->dma_chan) / sample_size; + residue = get_dma_residue(dma->chan) / sample_size; num_points = max_points - residue; if (cmd->stop_src == TRIG_COUNT && devpriv->count < num_points) num_points = devpriv->count; @@ -114,21 +116,21 @@ void labpc_drain_dma(struct comedi_device *dev)
[PATCH 10/37] staging: comedi: ni_at_a2150: introduce a2150_alloc_irq_dma()
From: H Hartley Sweeten This driver requires an IRQ and DMA in order to support async commands. For aesthetics, introduce a helper function to request the IRQ and DMA channels and allocate the DMA buffer. Since the async command support is optional, make the helper function handle any request/allocation errors and allow the driver to still attach without async command support. Signed-off-by: H Hartley Sweeten Cc: Ian Abbott Cc: Greg Kroah-Hartman --- drivers/staging/comedi/drivers/ni_at_a2150.c | 74 +--- 1 file changed, 46 insertions(+), 28 deletions(-) diff --git a/drivers/staging/comedi/drivers/ni_at_a2150.c b/drivers/staging/comedi/drivers/ni_at_a2150.c index 7380dac..11b1681 100644 --- a/drivers/staging/comedi/drivers/ni_at_a2150.c +++ b/drivers/staging/comedi/drivers/ni_at_a2150.c @@ -676,6 +676,50 @@ static int a2150_ai_rinsn(struct comedi_device *dev, struct comedi_subdevice *s, return n; } +static void a2150_alloc_irq_dma(struct comedi_device *dev, + struct comedi_devconfig *it) +{ + struct a2150_private *devpriv = dev->private; + unsigned int irq_num = it->options[1]; + unsigned int dma_chan = it->options[2]; + + /* +* Only IRQs 15, 14, 12-9, and 7-3 are valid. +* Only DMA channels 7-5 and 3-0 are valid. +* +* Both must be valid for async command support. +*/ + if (irq_num > 15 || dma_chan > 7 || + !((1 << irq_num) & 0xdef8) || !((1 << dma_chan) & 0xef)) + return; + + /* +* Request the IRQ and DMA channels and allocate the DMA buffer. +* If the requests or allocation fail async command supprt will +* not be available. +*/ + if (request_irq(irq_num, a2150_interrupt, 0, dev->board_name, dev)) + return; + if (request_dma(dma_chan, dev->board_name)) { + free_irq(irq_num, dev); + return; + } + devpriv->dma_buffer = kmalloc(A2150_DMA_BUFFER_SIZE, + GFP_KERNEL | GFP_DMA); + if (!devpriv->dma_buffer) { + free_dma(dma_chan); + free_irq(irq_num, dev); + return; + } + + dev->irq = irq_num; + devpriv->dma = dma_chan; + devpriv->irq_dma_bits = IRQ_LVL_BITS(irq_num) | DMA_CHAN_BITS(dma_chan); + + disable_dma(dma_chan); + set_dma_mode(dma_chan, DMA_MODE_READ); +} + /* probes board type, returns offset */ static int a2150_probe(struct comedi_device *dev) { @@ -689,8 +733,6 @@ static int a2150_attach(struct comedi_device *dev, struct comedi_devconfig *it) const struct a2150_board *thisboard; struct a2150_private *devpriv; struct comedi_subdevice *s; - unsigned int irq = it->options[1]; - unsigned int dma = it->options[2]; static const int timeout = 2000; int i; int ret; @@ -711,31 +753,7 @@ static int a2150_attach(struct comedi_device *dev, struct comedi_devconfig *it) thisboard = dev->board_ptr; dev->board_name = thisboard->name; - if ((irq >= 3 && irq <= 7) || (irq >= 9 && irq <= 12) || - irq == 14 || irq == 15) { - ret = request_irq(irq, a2150_interrupt, 0, - dev->board_name, dev); - if (ret == 0) { - devpriv->irq_dma_bits |= IRQ_LVL_BITS(irq); - dev->irq = irq; - } - } - - if (dev->irq && dma <= 7 && dma != 4) { - ret = request_dma(dma, dev->board_name); - if (ret == 0) { - devpriv->dma = dma; - devpriv->dma_buffer = kmalloc(A2150_DMA_BUFFER_SIZE, - GFP_KERNEL | GFP_DMA); - if (!devpriv->dma_buffer) - return -ENOMEM; - - disable_dma(dma); - set_dma_mode(dma, DMA_MODE_READ); - - devpriv->irq_dma_bits |= DMA_CHAN_BITS(dma); - } - } + a2150_alloc_irq_dma(dev, it); ret = comedi_alloc_subdevices(dev, 1); if (ret) @@ -749,7 +767,7 @@ static int a2150_attach(struct comedi_device *dev, struct comedi_devconfig *it) s->maxdata = 0x; s->range_table = &range_a2150; s->insn_read = a2150_ai_rinsn; - if (dev->irq && devpriv->dma) { + if (dev->irq) { dev->read_subdev = s; s->subdev_flags |= SDF_CMD_READ; s->len_chanlist = s->n_chan; -- 2.0.3 ___ devel mailing list de...@linuxdriverproject.org http://driverdev.linuxdriverproject.org/mailman/listinfo/driverdev-devel
[PATCH 26/37] staging: comedi: pcl816: fix short DMA transactions
When the cmd->stop_src == TRIG_COUNT the last DMA transfer might be smaller than the buffer size. This results in invalid data being added to the async buffer. Add a 'size' member to the DMA descriptor and initialize it with the actual size of the DMA transfer. Use that in interrupt and ai subdevice (*poll) function to return the proper number of samples. Use the comedi_bytes_to_samples() helper to convert the byte size to comedi samples in the interrupt handler. Signed-off-by: H Hartley Sweeten Cc: Ian Abbott Cc: Greg Kroah-Hartman --- drivers/staging/comedi/drivers/pcl816.c | 34 + 1 file changed, 18 insertions(+), 16 deletions(-) diff --git a/drivers/staging/comedi/drivers/pcl816.c b/drivers/staging/comedi/drivers/pcl816.c index 1b76085..f880cb9 100644 --- a/drivers/staging/comedi/drivers/pcl816.c +++ b/drivers/staging/comedi/drivers/pcl816.c @@ -116,6 +116,7 @@ static const struct pcl816_board boardtypes[] = { struct pcl816_dma_desc { void *virt_addr;/* virtual address of DMA buffer */ dma_addr_t hw_addr; /* hardware (bus) address of DMA buffer */ + unsigned int size; /* transfer size (in bytes) */ }; struct pcl816_private { @@ -158,30 +159,30 @@ static void pcl816_ai_setup_dma(struct comedi_device *dev, struct pcl816_dma_desc *dma = &devpriv->dma_desc[0]; struct comedi_cmd *cmd = &s->async->cmd; unsigned int dma_flags; - unsigned int bytes; - bytes = devpriv->hwdmasize; if (cmd->stop_src == TRIG_COUNT) { /* how many */ - bytes = cmd->stop_arg * comedi_bytes_per_scan(s); + dma->size = cmd->stop_arg * comedi_bytes_per_scan(s); /* how many DMA pages we must fill */ - devpriv->dma_runs_to_end = bytes / devpriv->hwdmasize; + devpriv->dma_runs_to_end = dma->size / devpriv->hwdmasize; /* on last dma transfer must be moved */ - devpriv->last_dma_run = bytes % devpriv->hwdmasize; + devpriv->last_dma_run = dma->size % devpriv->hwdmasize; devpriv->dma_runs_to_end--; if (devpriv->dma_runs_to_end >= 0) - bytes = devpriv->hwdmasize; - } else + dma->size = devpriv->hwdmasize; + } else { + dma->size = devpriv->hwdmasize; devpriv->dma_runs_to_end = -1; + } devpriv->cur_dma = 0; set_dma_mode(devpriv->dma, DMA_MODE_READ); dma_flags = claim_dma_lock(); clear_dma_ff(devpriv->dma); set_dma_addr(devpriv->dma, dma->hw_addr); - set_dma_count(devpriv->dma, bytes); + set_dma_count(devpriv->dma, dma->size); release_dma_lock(dma_flags); enable_dma(devpriv->dma); } @@ -199,13 +200,14 @@ static void pcl816_ai_setup_next_dma(struct comedi_device *dev, /* switch dma bufs */ devpriv->cur_dma = 1 - devpriv->cur_dma; dma = &devpriv->dma_desc[devpriv->cur_dma]; + if (devpriv->dma_runs_to_end) + dma->size = devpriv->hwdmasize; + else + dma->size = devpriv->last_dma_run; set_dma_mode(devpriv->dma, DMA_MODE_READ); dma_flags = claim_dma_lock(); set_dma_addr(devpriv->dma, dma->hw_addr); - if (devpriv->dma_runs_to_end) - set_dma_count(devpriv->dma, devpriv->hwdmasize); - else - set_dma_count(devpriv->dma, devpriv->last_dma_run); + set_dma_count(devpriv->dma, dma->size); release_dma_lock(dma_flags); enable_dma(devpriv->dma); } @@ -324,8 +326,8 @@ static irqreturn_t pcl816_interrupt(int irq, void *d) struct comedi_subdevice *s = dev->read_subdev; struct pcl816_private *devpriv = dev->private; struct pcl816_dma_desc *dma = &devpriv->dma_desc[devpriv->cur_dma]; + unsigned int nsamples; unsigned int bufptr; - unsigned int len; if (!dev->attached || !devpriv->ai_cmd_running) { pcl816_ai_clear_eoc(dev); @@ -340,11 +342,11 @@ static irqreturn_t pcl816_interrupt(int irq, void *d) pcl816_ai_setup_next_dma(dev, s); - len = (devpriv->hwdmasize >> 1) - devpriv->ai_poll_ptr; + nsamples = comedi_bytes_to_samples(s, dma->size) - devpriv->ai_poll_ptr; bufptr = devpriv->ai_poll_ptr; devpriv->ai_poll_ptr = 0; - transfer_from_dma_buf(dev, s, dma->virt_addr, bufptr, len); + transfer_from_dma_buf(dev, s, dma->virt_addr, bufptr, nsamples); pcl816_ai_clear_eoc(dev); @@ -542,7 +544,7 @@ static int pcl816_ai_poll(struct comedi_device *dev, struct comedi_subdevice *s) } /* where is now DMA in buffer */ - top1 = devpriv->hwdmasize - top1; + top1 = dma->size - top
Re: [PATCH v8 2/4] fpga manager: add sysfs interface document
On Sun, Jan 11, 2015 at 10:29:00AM -0600, atull wrote: > the FPGA image. If someone wants there to be only one FPGA image on > the FGPA forever, they will probably not be using this framework; their > FPGA will probably be loaded before Linux boots up. Nonsense, loading the FPGA through Linux is much better, it avoids having to deal with this complexity in the boot loader and means that Linux can be used to locate the huge image in some kind of sensible filesystem, log failures, do any FPGA startup sequence/etc. With hotplug and DT I find this this works very well. The FPGA devices simply are not registered with the kernel until userspace gives the OK (in future a DT overload can handle this) If you keep with the notion that the DT overload specifies the matching FPGA firmware then it makes alot more sense to me to use DT overlays as the API to change the file name - not sysfs. To reload a FPGA, unload the DT overlay (this would have to disconnect all the drivers), de-program the FPGA, the load a new DT overlay, which reprograms and re-binds the new drivers. All those steps have to be done anyhow, you can't just swap the HW while drivers are attached. .. and if there are no drivers then Alan is right, this is the wrong interface for the 'FPGA as a user space co-processor' model. I would also re-iterate my earlier comments: requiring the whole FPGA image to be held in ram makes this useless for any of my applications. Jason ___ devel mailing list de...@linuxdriverproject.org http://driverdev.linuxdriverproject.org/mailman/listinfo/driverdev-devel
RE: [PATCH v3] Drivers: hv: vmbus: prevent cpu offlining on newer hypervisors
> -Original Message- > From: Vitaly Kuznetsov [mailto:vkuzn...@redhat.com] > Sent: Monday, January 12, 2015 8:50 AM > To: KY Srinivasan; de...@linuxdriverproject.org > Cc: Haiyang Zhang; Greg Kroah-Hartman; linux-ker...@vger.kernel.org; > Dexuan Cui > Subject: [PATCH v3] Drivers: hv: vmbus: prevent cpu offlining on newer > hypervisors > > When an SMP Hyper-V guest is running on top of 2012R2 Server and > secondary > cpus are sent offline (with echo 0 > > /sys/devices/system/cpu/cpu$cpu/online) > the system freeze is observed. This happens due to the fact that on newer > hypervisors (Win8, WS2012R2, ...) vmbus channel handlers are distributed > across all cpus (see init_vp_index() function in drivers/hv/channel_mgmt.c) > and on cpu offlining nobody reassigns them to CPU0. Prevent cpu offlining > when vmbus is loaded until the issue is fixed host-side. > > This patch also disables hibernation but it is OK as it is also broken (MCE > error is hit on resume). Suspend still works. > > Tested with WS2008R2 and WS2012R2. > > Signed-off-by: Vitaly Kuznetsov Thank you. Signed-off-by: K. Y. Srinivasan > --- > Changes since v2: > - repair the build when vmbus is builded as a module [Greg KH] by saving > current cpu_disable pointer to previous_cpu_disable and restoring it on > unload; > - return -ENOSYS (same as native_cpu_disable when > !CONFIG_HOTPLUG_CPU) instead > of -1 in hyperv_cpu_disable(). > > Changes since v1: > - introduce hv_cpu_hotplug_quirk() function to not spread #ifdefs [Greg > KH]; > - add pr_notice() message "hv_vmbus: CPU offlining is not supported by > hypervisor". > --- > drivers/hv/vmbus_drv.c | 36 > 1 file changed, 36 insertions(+) > > diff --git a/drivers/hv/vmbus_drv.c b/drivers/hv/vmbus_drv.c > index 4d6b269..233da0b 100644 > --- a/drivers/hv/vmbus_drv.c > +++ b/drivers/hv/vmbus_drv.c > @@ -32,6 +32,7 @@ > #include > #include > #include > +#include > #include > #include > #include > @@ -671,6 +672,39 @@ static void vmbus_isr(void) > tasklet_schedule(&msg_dpc); > } > > +#ifdef CONFIG_HOTPLUG_CPU > +static int hyperv_cpu_disable(void) > +{ > + return -ENOSYS; > +} > + > +static void hv_cpu_hotplug_quirk(bool vmbus_loaded) > +{ > + static void *previous_cpu_disable; > + > + /* > + * Offlining a CPU when running on newer hypervisors (WS2012R2, > Win8, > + * ...) is not supported at this moment as channel interrupts are > + * distributed across all of them. > + */ > + > + if ((vmbus_proto_version == VERSION_WS2008) || > + (vmbus_proto_version == VERSION_WIN7)) > + return; > + > + if (vmbus_loaded) { > + previous_cpu_disable = smp_ops.cpu_disable; > + smp_ops.cpu_disable = hyperv_cpu_disable; > + pr_notice("CPU offlining is not supported by hypervisor\n"); > + } else if (previous_cpu_disable) > + smp_ops.cpu_disable = previous_cpu_disable; > +} > +#else > +static void hv_cpu_hotplug_quirk(bool vmbus_loaded) > +{ > +} > +#endif > + > /* > * vmbus_bus_init -Main vmbus driver initialization routine. > * > @@ -711,6 +745,7 @@ static int vmbus_bus_init(int irq) > if (ret) > goto err_alloc; > > + hv_cpu_hotplug_quirk(true); > vmbus_request_offers(); > > return 0; > @@ -964,6 +999,7 @@ static void __exit vmbus_exit(void) > bus_unregister(&hv_bus); > hv_cleanup(); > acpi_bus_unregister_driver(&vmbus_acpi_driver); > + hv_cpu_hotplug_quirk(false); > } > > > -- > 1.9.3 ___ devel mailing list de...@linuxdriverproject.org http://driverdev.linuxdriverproject.org/mailman/listinfo/driverdev-devel
Re: [PATCH] Staging: line6: fix parentheses around macro in usbdefs.h
On Wed, Dec 03, 2014 at 07:34:42PM +0100, Sam van Kampen wrote: > This patch fixes the error "Macros with complex values should be enclosed in > parentheses", as reported by checkpatch.pl. > > Signed-off-by: Sam van Kampen > --- > drivers/staging/line6/usbdefs.h | 2 +- > 1 file changed, 1 insertion(+), 1 deletion(-) > > diff --git a/drivers/staging/line6/usbdefs.h b/drivers/staging/line6/usbdefs.h > index 2d1cc47..48958b5 100644 > --- a/drivers/staging/line6/usbdefs.h > +++ b/drivers/staging/line6/usbdefs.h > @@ -40,7 +40,7 @@ > #define LINE6_DEVID_TONEPORT_UX2 0x4142 > #define LINE6_DEVID_VARIAX0x534d > > -#define LINE6_BIT(x) LINE6_BIT_ ## x = 1 << LINE6_INDEX_ ## x > +#define LINE6_BIT(x) (LINE6_BIT_ ## x = 1 << LINE6_INDEX_ ## x) > > enum { > LINE6_INDEX_BASSPODXT, I love this line in the driver, it proves that people make changes to the code without even building it. Please ALWAYS test-build your patches, otherwise you waste people's time and make them grumpy. greg k-h ___ devel mailing list de...@linuxdriverproject.org http://driverdev.linuxdriverproject.org/mailman/listinfo/driverdev-devel
Re: [PATCH 00/25] line6usb cleanup
On Mon, Jan 12, 2015 at 05:35:01PM +0100, Takashi Iwai wrote: > At Sun, 11 Jan 2015 15:04:55 -0600, > Chris Rorvick wrote: > > > > > At Fri, 9 Jan 2015 23:35:46 -0600, > > > Chris Rorvick wrote: > > >> > > >> I have a TonePort UX2 that I've used for testing, meaning that some of > > >> this is really only compile-tested. > > > > > > If anyone is responsible for testing with real hardware, I'll happily > > > review. > > > > To be clear, the TonePort UX2 is real hardware. But this driver > > basically supports four classes of Line 6 devices and I'm only covering > > one of them. > > > > So this series is a first step in trying to address this. Having this > > as a single driver probably made sense when it was a separate project, > > but now that it is in-tree it seems like the POD, PODHD, TonePort, and > > Variax pieces should each be separate drivers that each depend on a core > > Line 6 driver. I think the cleanup in this series will make that > > easier. None of this is my area of expertise, though, so advice and > > feedback is very welcome. > > > > > are there any active developers for this driver? > > > > I intended to do further work. I know there is quite a bit of mundane > > checkpatch cleanup that would need to get done before this could get > > promoted, and I believe I read that it's using sysfs for stuff that > > would normally be done via an ALSA interface, and the sysfs interface > > has not been documented nor has it been justified. All stuff I thought > > I might look into. > > > > But I'm just doing this for fun so I can't promise anything. :-) > > OK, so the situation looks fairly good, we have a few active > developers and/or testers. And the current code doesn't look so > terrible despite of it being in staging directory. That said, I think > we can promote this stuff into sound/usb/line6 directory, then apply > Chris' cleanup patches, and work on it further. > > Does it sound OK for you guys? Greg? > > Once when I get approval, I'll start a new clean branch on sound.git > tree so that you guys can work on it further for 3.20 kernel. That sounds fine with me. I have 4 other patches in my "to-apply" queue other than these 25 for this driver that I'll forward on to you for inclusion in your tree. thanks, greg k-h ___ devel mailing list de...@linuxdriverproject.org http://driverdev.linuxdriverproject.org/mailman/listinfo/driverdev-devel
Re: [PATCH 00/25] line6usb cleanup
At Mon, 12 Jan 2015 11:52:27 -0800, Greg Kroah-Hartman wrote: > > On Mon, Jan 12, 2015 at 05:35:01PM +0100, Takashi Iwai wrote: > > At Sun, 11 Jan 2015 15:04:55 -0600, > > Chris Rorvick wrote: > > > > > > > At Fri, 9 Jan 2015 23:35:46 -0600, > > > > Chris Rorvick wrote: > > > >> > > > >> I have a TonePort UX2 that I've used for testing, meaning that some of > > > >> this is really only compile-tested. > > > > > > > > If anyone is responsible for testing with real hardware, I'll happily > > > > review. > > > > > > To be clear, the TonePort UX2 is real hardware. But this driver > > > basically supports four classes of Line 6 devices and I'm only covering > > > one of them. > > > > > > So this series is a first step in trying to address this. Having this > > > as a single driver probably made sense when it was a separate project, > > > but now that it is in-tree it seems like the POD, PODHD, TonePort, and > > > Variax pieces should each be separate drivers that each depend on a core > > > Line 6 driver. I think the cleanup in this series will make that > > > easier. None of this is my area of expertise, though, so advice and > > > feedback is very welcome. > > > > > > > are there any active developers for this driver? > > > > > > I intended to do further work. I know there is quite a bit of mundane > > > checkpatch cleanup that would need to get done before this could get > > > promoted, and I believe I read that it's using sysfs for stuff that > > > would normally be done via an ALSA interface, and the sysfs interface > > > has not been documented nor has it been justified. All stuff I thought > > > I might look into. > > > > > > But I'm just doing this for fun so I can't promise anything. :-) > > > > OK, so the situation looks fairly good, we have a few active > > developers and/or testers. And the current code doesn't look so > > terrible despite of it being in staging directory. That said, I think > > we can promote this stuff into sound/usb/line6 directory, then apply > > Chris' cleanup patches, and work on it further. > > > > Does it sound OK for you guys? Greg? > > > > Once when I get approval, I'll start a new clean branch on sound.git > > tree so that you guys can work on it further for 3.20 kernel. > > That sounds fine with me. I have 4 other patches in my "to-apply" queue > other than these 25 for this driver that I'll forward on to you for > inclusion in your tree. OK, feel free to mail me. Thanks! Takashi ___ devel mailing list de...@linuxdriverproject.org http://driverdev.linuxdriverproject.org/mailman/listinfo/driverdev-devel
Re: [PATCH] Staging: line6: Updated comma spacing to fit within coding style
On Sat, Dec 27, 2014 at 05:00:10PM +1100, Damon Swayn wrote: > Fixed a coding style issue reported by checkpatch surrounding the > spacing of comma's > > Signed-off-by: Damon Swayn > --- > drivers/staging/line6/pcm.h | 6 +++--- > 1 file changed, 3 insertions(+), 3 deletions(-) Sorry, someone else sent this same patch in before you :( ___ devel mailing list de...@linuxdriverproject.org http://driverdev.linuxdriverproject.org/mailman/listinfo/driverdev-devel
Re: [PATCH] Staging: line6: fix coding style issue in pcm.h
On Mon, Dec 22, 2014 at 10:45:01PM +0200, Dmitriy Polyanskiy wrote: > This is a patch to pcm.h file that fixes up some space warnings > found by checkpatch.pl > > Signed-off-by: Dmitriy Polyanskiy > --- > drivers/staging/line6/pcm.h |6 +++--- > 1 file changed, 3 insertions(+), 3 deletions(-) Sorry, someone else already sent this patch in and got it merged first :( ___ devel mailing list de...@linuxdriverproject.org http://driverdev.linuxdriverproject.org/mailman/listinfo/driverdev-devel
[PATCH 07/27] staging: line6: Define a device type enum
From: Chris Rorvick Define an enum containing the supported devices and associate each entry in the device table to the respective value. Signed-off-by: Chris Rorvick Reviewed-by: Stefan Hajnoczi Signed-off-by: Greg Kroah-Hartman --- drivers/staging/line6/driver.c | 54 -- drivers/staging/line6/driver.h | 21 2 files changed, 57 insertions(+), 18 deletions(-) diff --git a/drivers/staging/line6/driver.c b/drivers/staging/line6/driver.c index a263bce95414..2797e4132cfa 100644 --- a/drivers/staging/line6/driver.c +++ b/drivers/staging/line6/driver.c @@ -34,24 +34,42 @@ /* table of devices that work with this driver */ static const struct usb_device_id line6_id_table[] = { - { LINE6_DEVICE(LINE6_DEVID_BASSPODXT) }, - { LINE6_DEVICE(LINE6_DEVID_BASSPODXTLIVE) }, - { LINE6_DEVICE(LINE6_DEVID_BASSPODXTPRO) }, - { LINE6_DEVICE(LINE6_DEVID_GUITARPORT) }, - { LINE6_DEVICE(LINE6_DEVID_POCKETPOD) }, - { LINE6_DEVICE(LINE6_DEVID_PODHD300) }, - { LINE6_DEVICE(LINE6_DEVID_PODHD400) }, - { LINE6_DEVICE(LINE6_DEVID_PODHD500) }, - { LINE6_DEVICE(LINE6_DEVID_PODSTUDIO_GX) }, - { LINE6_DEVICE(LINE6_DEVID_PODSTUDIO_UX1) }, - { LINE6_DEVICE(LINE6_DEVID_PODSTUDIO_UX2) }, - { LINE6_DEVICE(LINE6_DEVID_PODXT) }, - { LINE6_DEVICE(LINE6_DEVID_PODXTLIVE) }, - { LINE6_DEVICE(LINE6_DEVID_PODXTPRO) }, - { LINE6_DEVICE(LINE6_DEVID_TONEPORT_GX) }, - { LINE6_DEVICE(LINE6_DEVID_TONEPORT_UX1) }, - { LINE6_DEVICE(LINE6_DEVID_TONEPORT_UX2) }, - { LINE6_DEVICE(LINE6_DEVID_VARIAX) }, + { LINE6_DEVICE(LINE6_DEVID_BASSPODXT), + .driver_info = LINE6_BASSPODXT }, + { LINE6_DEVICE(LINE6_DEVID_BASSPODXTLIVE), + .driver_info = LINE6_BASSPODXTLIVE }, + { LINE6_DEVICE(LINE6_DEVID_BASSPODXTPRO), + .driver_info = LINE6_BASSPODXTPRO }, + { LINE6_DEVICE(LINE6_DEVID_GUITARPORT), + .driver_info = LINE6_GUITARPORT }, + { LINE6_DEVICE(LINE6_DEVID_POCKETPOD), + .driver_info = LINE6_POCKETPOD }, + { LINE6_DEVICE(LINE6_DEVID_PODHD300), + .driver_info = LINE6_PODHD300 }, + { LINE6_DEVICE(LINE6_DEVID_PODHD400), + .driver_info = LINE6_PODHD400 }, + { LINE6_DEVICE(LINE6_DEVID_PODHD500), + .driver_info = LINE6_PODHD500 }, + { LINE6_DEVICE(LINE6_DEVID_PODSTUDIO_GX), + .driver_info = LINE6_PODSTUDIO_GX }, + { LINE6_DEVICE(LINE6_DEVID_PODSTUDIO_UX1), + .driver_info = LINE6_PODSTUDIO_UX1 }, + { LINE6_DEVICE(LINE6_DEVID_PODSTUDIO_UX2), + .driver_info = LINE6_PODSTUDIO_UX2 }, + { LINE6_DEVICE(LINE6_DEVID_PODXT), + .driver_info = LINE6_PODXT }, + { LINE6_DEVICE(LINE6_DEVID_PODXTLIVE), + .driver_info = LINE6_PODXTLIVE }, + { LINE6_DEVICE(LINE6_DEVID_PODXTPRO), + .driver_info = LINE6_PODXTPRO }, + { LINE6_DEVICE(LINE6_DEVID_TONEPORT_GX), + .driver_info = LINE6_TONEPORT_GX }, + { LINE6_DEVICE(LINE6_DEVID_TONEPORT_UX1), + .driver_info = LINE6_TONEPORT_UX1 }, + { LINE6_DEVICE(LINE6_DEVID_TONEPORT_UX2), + .driver_info = LINE6_TONEPORT_UX2 }, + { LINE6_DEVICE(LINE6_DEVID_VARIAX), + .driver_info = LINE6_VARIAX }, {} }; diff --git a/drivers/staging/line6/driver.h b/drivers/staging/line6/driver.h index 1cc7532257b6..8fb4a9c073b2 100644 --- a/drivers/staging/line6/driver.h +++ b/drivers/staging/line6/driver.h @@ -20,6 +20,27 @@ #define DRIVER_NAME "line6usb" +enum line6_device_type { + LINE6_BASSPODXT, + LINE6_BASSPODXTLIVE, + LINE6_BASSPODXTPRO, + LINE6_GUITARPORT, + LINE6_POCKETPOD, + LINE6_PODHD300, + LINE6_PODHD400, + LINE6_PODHD500, + LINE6_PODSTUDIO_GX, + LINE6_PODSTUDIO_UX1, + LINE6_PODSTUDIO_UX2, + LINE6_PODXT, + LINE6_PODXTLIVE, + LINE6_PODXTPRO, + LINE6_TONEPORT_GX, + LINE6_TONEPORT_UX1, + LINE6_TONEPORT_UX2, + LINE6_VARIAX +}; + #define LINE6_TIMEOUT 1 #define LINE6_BUFSIZE_LISTEN 32 #define LINE6_MESSAGE_MAXLEN 256 -- 2.2.1 ___ devel mailing list de...@linuxdriverproject.org http://driverdev.linuxdriverproject.org/mailman/listinfo/driverdev-devel
[PATCH 06/27] staging: line6: Cleanup device table
From: Chris Rorvick Wrap USB_DEVICE to avoid repeating the Line 6 vendor ID. Signed-off-by: Chris Rorvick Reviewed-by: Stefan Hajnoczi Signed-off-by: Greg Kroah-Hartman --- drivers/staging/line6/driver.c | 40 +--- 1 file changed, 21 insertions(+), 19 deletions(-) diff --git a/drivers/staging/line6/driver.c b/drivers/staging/line6/driver.c index e40400b842a0..a263bce95414 100644 --- a/drivers/staging/line6/driver.c +++ b/drivers/staging/line6/driver.c @@ -30,27 +30,29 @@ #define DRIVER_DESC"Line6 USB Driver" #define DRIVER_VERSION "0.9.1beta" DRIVER_REVISION +#define LINE6_DEVICE(prod) USB_DEVICE(LINE6_VENDOR_ID, prod) + /* table of devices that work with this driver */ static const struct usb_device_id line6_id_table[] = { - {USB_DEVICE(LINE6_VENDOR_ID, LINE6_DEVID_BASSPODXT)}, - {USB_DEVICE(LINE6_VENDOR_ID, LINE6_DEVID_BASSPODXTLIVE)}, - {USB_DEVICE(LINE6_VENDOR_ID, LINE6_DEVID_BASSPODXTPRO)}, - {USB_DEVICE(LINE6_VENDOR_ID, LINE6_DEVID_GUITARPORT)}, - {USB_DEVICE(LINE6_VENDOR_ID, LINE6_DEVID_POCKETPOD)}, - {USB_DEVICE(LINE6_VENDOR_ID, LINE6_DEVID_PODHD300)}, - {USB_DEVICE(LINE6_VENDOR_ID, LINE6_DEVID_PODHD400)}, - {USB_DEVICE(LINE6_VENDOR_ID, LINE6_DEVID_PODHD500)}, - {USB_DEVICE(LINE6_VENDOR_ID, LINE6_DEVID_PODSTUDIO_GX)}, - {USB_DEVICE(LINE6_VENDOR_ID, LINE6_DEVID_PODSTUDIO_UX1)}, - {USB_DEVICE(LINE6_VENDOR_ID, LINE6_DEVID_PODSTUDIO_UX2)}, - {USB_DEVICE(LINE6_VENDOR_ID, LINE6_DEVID_PODXT)}, - {USB_DEVICE(LINE6_VENDOR_ID, LINE6_DEVID_PODXTLIVE)}, - {USB_DEVICE(LINE6_VENDOR_ID, LINE6_DEVID_PODXTPRO)}, - {USB_DEVICE(LINE6_VENDOR_ID, LINE6_DEVID_TONEPORT_GX)}, - {USB_DEVICE(LINE6_VENDOR_ID, LINE6_DEVID_TONEPORT_UX1)}, - {USB_DEVICE(LINE6_VENDOR_ID, LINE6_DEVID_TONEPORT_UX2)}, - {USB_DEVICE(LINE6_VENDOR_ID, LINE6_DEVID_VARIAX)}, - {}, + { LINE6_DEVICE(LINE6_DEVID_BASSPODXT) }, + { LINE6_DEVICE(LINE6_DEVID_BASSPODXTLIVE) }, + { LINE6_DEVICE(LINE6_DEVID_BASSPODXTPRO) }, + { LINE6_DEVICE(LINE6_DEVID_GUITARPORT) }, + { LINE6_DEVICE(LINE6_DEVID_POCKETPOD) }, + { LINE6_DEVICE(LINE6_DEVID_PODHD300) }, + { LINE6_DEVICE(LINE6_DEVID_PODHD400) }, + { LINE6_DEVICE(LINE6_DEVID_PODHD500) }, + { LINE6_DEVICE(LINE6_DEVID_PODSTUDIO_GX) }, + { LINE6_DEVICE(LINE6_DEVID_PODSTUDIO_UX1) }, + { LINE6_DEVICE(LINE6_DEVID_PODSTUDIO_UX2) }, + { LINE6_DEVICE(LINE6_DEVID_PODXT) }, + { LINE6_DEVICE(LINE6_DEVID_PODXTLIVE) }, + { LINE6_DEVICE(LINE6_DEVID_PODXTPRO) }, + { LINE6_DEVICE(LINE6_DEVID_TONEPORT_GX) }, + { LINE6_DEVICE(LINE6_DEVID_TONEPORT_UX1) }, + { LINE6_DEVICE(LINE6_DEVID_TONEPORT_UX2) }, + { LINE6_DEVICE(LINE6_DEVID_VARIAX) }, + {} }; MODULE_DEVICE_TABLE(usb, line6_id_table); -- 2.2.1 ___ devel mailing list de...@linuxdriverproject.org http://driverdev.linuxdriverproject.org/mailman/listinfo/driverdev-devel
[PATCH 03/27] staging: line6: Remove `device_bit' from properties
From: Chris Rorvick The `device_bit' member was no longer used as of commit 2807904441d4 (staging: line6: drop MIDI parameter sysfs attrs). Signed-off-by: Chris Rorvick Reviewed-by: Stefan Hajnoczi Signed-off-by: Greg Kroah-Hartman --- drivers/staging/line6/driver.c | 44 +++--- drivers/staging/line6/driver.h | 5 drivers/staging/line6/pcm.h | 2 ++ drivers/staging/line6/usbdefs.h | 59 - 4 files changed, 24 insertions(+), 86 deletions(-) diff --git a/drivers/staging/line6/driver.c b/drivers/staging/line6/driver.c index 503b2d763595..15f3bc4ddb7d 100644 --- a/drivers/staging/line6/driver.c +++ b/drivers/staging/line6/driver.c @@ -57,32 +57,32 @@ static const struct usb_device_id line6_id_table[] = { MODULE_DEVICE_TABLE(usb, line6_id_table); -#define L6PROP(dev_bit, dev_id, dev_name, dev_cap)\ - {.device_bit = LINE6_BIT_##dev_bit, .id = dev_id,\ +#define L6PROP(dev_id, dev_name, dev_cap)\ + {.id = dev_id,\ .name = dev_name, .capabilities = LINE6_BIT_##dev_cap} /* *INDENT-OFF* */ static const struct line6_properties line6_properties_table[] = { - L6PROP(BASSPODXT, "BassPODxt", "BassPODxt",CTRL_PCM_HW), - L6PROP(BASSPODXTLIVE, "BassPODxtLive", "BassPODxt Live", CTRL_PCM_HW), - L6PROP(BASSPODXTPRO, "BassPODxtPro", "BassPODxt Pro",CTRL_PCM_HW), - L6PROP(GUITARPORT,"GuitarPort","GuitarPort", PCM), - L6PROP(POCKETPOD, "PocketPOD", "Pocket POD", CONTROL), - L6PROP(PODHD300, "PODHD300", "POD HD300",CTRL_PCM_HW), - L6PROP(PODHD400, "PODHD400", "POD HD400",CTRL_PCM_HW), - L6PROP(PODHD500, "PODHD500", "POD HD500",CTRL_PCM_HW), - L6PROP(PODSTUDIO_GX, "PODStudioGX", "POD Studio GX",PCM), - L6PROP(PODSTUDIO_UX1, "PODStudioUX1", "POD Studio UX1", PCM), - L6PROP(PODSTUDIO_UX2, "PODStudioUX2", "POD Studio UX2", PCM), - L6PROP(PODX3, "PODX3", "POD X3", PCM), - L6PROP(PODX3LIVE, "PODX3Live", "POD X3 Live", PCM), - L6PROP(PODXT, "PODxt", "PODxt",CTRL_PCM_HW), - L6PROP(PODXTLIVE, "PODxtLive", "PODxt Live", CTRL_PCM_HW), - L6PROP(PODXTPRO, "PODxtPro", "PODxt Pro",CTRL_PCM_HW), - L6PROP(TONEPORT_GX, "TonePortGX","TonePort GX", PCM), - L6PROP(TONEPORT_UX1, "TonePortUX1", "TonePort UX1", PCM), - L6PROP(TONEPORT_UX2, "TonePortUX2", "TonePort UX2", PCM), - L6PROP(VARIAX,"Variax","Variax Workbench", CONTROL), + L6PROP("BassPODxt", "BassPODxt",CTRL_PCM_HW), + L6PROP("BassPODxtLive", "BassPODxt Live", CTRL_PCM_HW), + L6PROP("BassPODxtPro", "BassPODxt Pro",CTRL_PCM_HW), + L6PROP("GuitarPort","GuitarPort", PCM), + L6PROP("PocketPOD", "Pocket POD", CONTROL), + L6PROP("PODHD300", "POD HD300",CTRL_PCM_HW), + L6PROP("PODHD400", "POD HD400",CTRL_PCM_HW), + L6PROP("PODHD500", "POD HD500",CTRL_PCM_HW), + L6PROP("PODStudioGX", "POD Studio GX",PCM), + L6PROP("PODStudioUX1", "POD Studio UX1", PCM), + L6PROP("PODStudioUX2", "POD Studio UX2", PCM), + L6PROP("PODX3", "POD X3", PCM), + L6PROP("PODX3Live", "POD X3 Live", PCM), + L6PROP("PODxt", "PODxt",CTRL_PCM_HW), + L6PROP("PODxtLive", "PODxt Live", CTRL_PCM_HW), + L6PROP("PODxtPro", "PODxt Pro",CTRL_PCM_HW), + L6PROP("TonePortGX","TonePort GX", PCM), + L6PROP("TonePortUX1", "TonePort UX1", PCM), + L6PROP("TonePortUX2", "TonePort UX2", PCM), + L6PROP("Variax","Variax Workbench", CONTROL), }; /* *INDENT-ON* */ diff --git a/drivers/staging/line6/driver.h b/drivers/staging/line6/driver.h index 16e3fc2f1f15..1cc7532257b6 100644 --- a/drivers/staging/line6/driver.h +++ b/drivers/staging/line6/driver.h @@ -76,11 +76,6 @@ static const int SYSEX_EXTRA_SIZE = sizeof(line6_midi_id) + 4; */ struct line6_properties { /** -Bit identifying this device in the line6usb driver. - */ - int device_bit; - - /** Card id string (maximum 16 characters). This can be used to address the device in ALSA programs as "default:CARD=" diff --git a/drivers/staging/line6/pcm.h b/drivers/staging/line6/pcm.h index 5d87934691ec..4f608237c006 100644 --- a/drivers/staging/line6/pcm.h +++ b/drivers/staging/line6/pcm.h @@ -98,6 +98,8 @@ enum { LINE6_INDEX_PAUSE_PLAYBACK, LINE6_INDEX_PREPARED, +#define LINE6_BIT(x) LINE6_BIT_ ## x = 1 << LINE6_INDEX_ ## x + /* individual bit masks: */ LINE6_BIT(PCM_ALSA_PLAYBACK_BUFFER),
[PATCH 01/27] staging: line6: toneport.c: Fix for possible null pointer dereference
From: Rickard Strandqvist The NULL check was done to late, and there it was a risk of a possible null pointer dereference. This was partially found by using a static code analysis program called cppcheck. Signed-off-by: Rickard Strandqvist Reviewed-by: Stefan Hajnoczi Signed-off-by: Greg Kroah-Hartman --- drivers/staging/line6/toneport.c | 15 --- 1 file changed, 8 insertions(+), 7 deletions(-) diff --git a/drivers/staging/line6/toneport.c b/drivers/staging/line6/toneport.c index 69437158d383..660dc3f2aa61 100644 --- a/drivers/staging/line6/toneport.c +++ b/drivers/staging/line6/toneport.c @@ -433,12 +433,16 @@ void line6_toneport_reset_resume(struct usb_line6_toneport *toneport) void line6_toneport_disconnect(struct usb_interface *interface) { struct usb_line6_toneport *toneport; + struct snd_line6_pcm *line6pcm; u16 idProduct; if (interface == NULL) return; toneport = usb_get_intfdata(interface); + if (NULL == toneport) + return; + del_timer_sync(&toneport->timer); idProduct = le16_to_cpu(toneport->line6.usbdev->descriptor.idProduct); @@ -447,13 +451,10 @@ void line6_toneport_disconnect(struct usb_interface *interface) device_remove_file(&interface->dev, &dev_attr_led_green); } - if (toneport != NULL) { - struct snd_line6_pcm *line6pcm = toneport->line6.line6pcm; - - if (line6pcm != NULL) { - line6_pcm_release(line6pcm, LINE6_BITS_PCM_MONITOR); - line6_pcm_disconnect(line6pcm); - } + line6pcm = toneport->line6.line6pcm; + if (line6pcm != NULL) { + line6_pcm_release(line6pcm, LINE6_BITS_PCM_MONITOR); + line6_pcm_disconnect(line6pcm); } toneport_destruct(interface); -- 2.2.1 ___ devel mailing list de...@linuxdriverproject.org http://driverdev.linuxdriverproject.org/mailman/listinfo/driverdev-devel
[PATCH 00/27] staging: line6 patches queued up
Hi Takashi, Here are all of the line6 patches that have been sent to me that were in my queue, including the series from Chris that caused you to want to move the driver out of staging. I included it here as it had to be tweaked due to some earlier patches in my queue. thanks, greg k-h ___ devel mailing list de...@linuxdriverproject.org http://driverdev.linuxdriverproject.org/mailman/listinfo/driverdev-devel
[PATCH 05/27] staging: line6: Remove unsupported X3 devices
From: Chris Rorvick Support for these devices appears to have never been completed. Remove them from the device table along with a minimal amount of supporting code. Signed-off-by: Chris Rorvick Reviewed-by: Stefan Hajnoczi Signed-off-by: Greg Kroah-Hartman --- drivers/staging/line6/driver.c | 26 -- drivers/staging/line6/pcm.c | 2 -- drivers/staging/line6/usbdefs.h | 2 -- 3 files changed, 30 deletions(-) diff --git a/drivers/staging/line6/driver.c b/drivers/staging/line6/driver.c index 15f3bc4ddb7d..e40400b842a0 100644 --- a/drivers/staging/line6/driver.c +++ b/drivers/staging/line6/driver.c @@ -43,8 +43,6 @@ static const struct usb_device_id line6_id_table[] = { {USB_DEVICE(LINE6_VENDOR_ID, LINE6_DEVID_PODSTUDIO_GX)}, {USB_DEVICE(LINE6_VENDOR_ID, LINE6_DEVID_PODSTUDIO_UX1)}, {USB_DEVICE(LINE6_VENDOR_ID, LINE6_DEVID_PODSTUDIO_UX2)}, - {USB_DEVICE(LINE6_VENDOR_ID, LINE6_DEVID_PODX3)}, - {USB_DEVICE(LINE6_VENDOR_ID, LINE6_DEVID_PODX3LIVE)}, {USB_DEVICE(LINE6_VENDOR_ID, LINE6_DEVID_PODXT)}, {USB_DEVICE(LINE6_VENDOR_ID, LINE6_DEVID_PODXTLIVE)}, {USB_DEVICE(LINE6_VENDOR_ID, LINE6_DEVID_PODXTPRO)}, @@ -74,8 +72,6 @@ static const struct line6_properties line6_properties_table[] = { L6PROP("PODStudioGX", "POD Studio GX",PCM), L6PROP("PODStudioUX1", "POD Studio UX1", PCM), L6PROP("PODStudioUX2", "POD Studio UX2", PCM), - L6PROP("PODX3", "POD X3", PCM), - L6PROP("PODX3Live", "POD X3 Live", PCM), L6PROP("PODxt", "PODxt",CTRL_PCM_HW), L6PROP("PODxtLive", "PODxt Live", CTRL_PCM_HW), L6PROP("PODxtPro", "PODxt Pro",CTRL_PCM_HW), @@ -673,8 +669,6 @@ static int line6_probe(struct usb_interface *interface, break; case LINE6_DEVID_PODHD500: - case LINE6_DEVID_PODX3: - case LINE6_DEVID_PODX3LIVE: switch (interface_number) { case 0: alternate = 1; @@ -765,14 +759,6 @@ static int line6_probe(struct usb_interface *interface, ep_write = 0x02; break; - case LINE6_DEVID_PODX3: - case LINE6_DEVID_PODX3LIVE: - /* currently unused! */ - size = sizeof(struct usb_line6_pod); - ep_read = 0x81; - ep_write = 0x01; - break; - case LINE6_DEVID_PODSTUDIO_GX: case LINE6_DEVID_PODSTUDIO_UX1: case LINE6_DEVID_PODSTUDIO_UX2: @@ -898,8 +884,6 @@ static int line6_probe(struct usb_interface *interface, case LINE6_DEVID_BASSPODXTLIVE: case LINE6_DEVID_BASSPODXTPRO: case LINE6_DEVID_POCKETPOD: - case LINE6_DEVID_PODX3: - case LINE6_DEVID_PODX3LIVE: case LINE6_DEVID_PODXT: case LINE6_DEVID_PODXTPRO: ret = line6_pod_init(interface, (struct usb_line6_pod *)line6); @@ -971,14 +955,6 @@ static int line6_probe(struct usb_interface *interface, dev_info(&interface->dev, "Line6 %s now attached\n", line6->properties->name); - switch (product) { - case LINE6_DEVID_PODX3: - case LINE6_DEVID_PODX3LIVE: - dev_info(&interface->dev, -"NOTE: the Line6 %s is detected, but not yet supported\n", -line6->properties->name); - } - /* increment reference counters: */ usb_get_intf(interface); usb_get_dev(usbdev); @@ -1026,8 +1002,6 @@ static void line6_disconnect(struct usb_interface *interface) case LINE6_DEVID_BASSPODXTLIVE: case LINE6_DEVID_BASSPODXTPRO: case LINE6_DEVID_POCKETPOD: - case LINE6_DEVID_PODX3: - case LINE6_DEVID_PODX3LIVE: case LINE6_DEVID_PODXT: case LINE6_DEVID_PODXTPRO: line6_pod_disconnect(interface); diff --git a/drivers/staging/line6/pcm.c b/drivers/staging/line6/pcm.c index a3136b189ee5..076c87b689d0 100644 --- a/drivers/staging/line6/pcm.c +++ b/drivers/staging/line6/pcm.c @@ -442,8 +442,6 @@ int line6_init_pcm(struct usb_line6 *line6, break; case LINE6_DEVID_PODHD500: - case LINE6_DEVID_PODX3: - case LINE6_DEVID_PODX3LIVE: ep_read = 0x86; ep_write = 0x02; break; diff --git a/drivers/staging/line6/usbdefs.h b/drivers/staging/line6/usbdefs.h index 2bc2fe7bd102..06bf909620e9 100644 --- a/drivers/staging/line6/usbdefs.h +++ b/drivers/staging/line6/usbdefs.h @@ -30,8 +30,6 @@ #define LINE6_DEVID_PODSTUDIO_GX 0x4153 #define LINE6_DEVID_PODSTUDIO_UX1 0x4150 #define LINE6_DEVID_PODSTUDIO_UX2 0x4151 -#define LINE6_DEVID_PODX3 0x414a -#define LINE6_DEVID_PODX3LIVE 0x414b #define LINE6_DEVID_PODXT 0x5044 #define LINE6_DEVID_PODXTLIVE 0x4650 #d
[PATCH 19/27] staging: line6: Move altsetting to properties
From: Chris Rorvick The device type can now be used to determine the altsetting for the interface. Drop the conditional logic and make this value a property. Signed-off-by: Chris Rorvick Reviewed-by: Stefan Hajnoczi Signed-off-by: Greg Kroah-Hartman --- drivers/staging/line6/driver.c | 74 +- drivers/staging/line6/driver.h | 2 ++ 2 files changed, 25 insertions(+), 51 deletions(-) diff --git a/drivers/staging/line6/driver.c b/drivers/staging/line6/driver.c index f04ff800a009..01504704796e 100644 --- a/drivers/staging/line6/driver.c +++ b/drivers/staging/line6/driver.c @@ -67,6 +67,7 @@ static const struct line6_properties line6_properties_table[] = { .capabilities = LINE6_CAP_CONTROL | LINE6_CAP_PCM | LINE6_CAP_HWMON, + .altsetting = 5, }, [LINE6_BASSPODXTLIVE] = { .id = "BassPODxtLive", @@ -74,6 +75,7 @@ static const struct line6_properties line6_properties_table[] = { .capabilities = LINE6_CAP_CONTROL | LINE6_CAP_PCM | LINE6_CAP_HWMON, + .altsetting = 1, }, [LINE6_BASSPODXTPRO] = { .id = "BassPODxtPro", @@ -81,16 +83,19 @@ static const struct line6_properties line6_properties_table[] = { .capabilities = LINE6_CAP_CONTROL | LINE6_CAP_PCM | LINE6_CAP_HWMON, + .altsetting = 5, }, [LINE6_GUITARPORT] = { .id = "GuitarPort", .name = "GuitarPort", .capabilities = LINE6_CAP_PCM, + .altsetting = 2, /* 1..4 seem to be ok */ }, [LINE6_POCKETPOD] = { .id = "PocketPOD", .name = "Pocket POD", .capabilities = LINE6_CAP_CONTROL, + .altsetting = 0, }, [LINE6_PODHD300] = { .id = "PODHD300", @@ -98,6 +103,7 @@ static const struct line6_properties line6_properties_table[] = { .capabilities = LINE6_CAP_CONTROL | LINE6_CAP_PCM | LINE6_CAP_HWMON, + .altsetting = 5, }, [LINE6_PODHD400] = { .id = "PODHD400", @@ -105,6 +111,7 @@ static const struct line6_properties line6_properties_table[] = { .capabilities = LINE6_CAP_CONTROL | LINE6_CAP_PCM | LINE6_CAP_HWMON, + .altsetting = 5, }, [LINE6_PODHD500_0] = { .id = "PODHD500", @@ -112,6 +119,7 @@ static const struct line6_properties line6_properties_table[] = { .capabilities = LINE6_CAP_CONTROL | LINE6_CAP_PCM | LINE6_CAP_HWMON, + .altsetting = 1, }, [LINE6_PODHD500_1] = { .id = "PODHD500", @@ -119,21 +127,25 @@ static const struct line6_properties line6_properties_table[] = { .capabilities = LINE6_CAP_CONTROL | LINE6_CAP_PCM | LINE6_CAP_HWMON, + .altsetting = 1, }, [LINE6_PODSTUDIO_GX] = { .id = "PODStudioGX", .name = "POD Studio GX", .capabilities = LINE6_CAP_PCM, + .altsetting = 2, /* 1..4 seem to be ok */ }, [LINE6_PODSTUDIO_UX1] = { .id = "PODStudioUX1", .name = "POD Studio UX1", .capabilities = LINE6_CAP_PCM, + .altsetting = 2, /* 1..4 seem to be ok */ }, [LINE6_PODSTUDIO_UX2] = { .id = "PODStudioUX2", .name = "POD Studio UX2", .capabilities = LINE6_CAP_PCM, + .altsetting = 2, /* defaults to 44.1kHz, 16-bit */ }, [LINE6_PODXT] = { .id = "PODxt", @@ -141,6 +153,7 @@ static const struct line6_properties line6_properties_table[] = { .capabilities = LINE6_CAP_CONTROL | LINE6_CAP_PCM | LINE6_CAP_HWMON, + .altsetting = 5, }, [LINE6_PODXTLIVE_POD] = { .id = "PODxtLive", @@ -148,6 +161,7 @@ static const struct line6_properties line6_properties_table[] = { .capabilities = LINE6_CAP_CONTROL | LINE6_CAP_PCM | LINE6_CAP_HWMON, + .altsetting = 1, }, [LINE6_PODXTLIVE_VARIAX] = { .id = "PODxtLive", @@ -155,6 +169,7 @@ static const struct line6_properties line6_properties_table[] = { .capabili
[PATCH 02/27] Staging: line6: remove spaces before commas.
From: Jonas Lundqvist Fix three space prohibited errors in pcm.h found by checkpatch.pl. Signed-off-by: Jonas Lundqvist Reviewed-by: Jeremiah Mahler Signed-off-by: Greg Kroah-Hartman --- drivers/staging/line6/pcm.h | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/drivers/staging/line6/pcm.h b/drivers/staging/line6/pcm.h index 6aa0d46a2890..5d87934691ec 100644 --- a/drivers/staging/line6/pcm.h +++ b/drivers/staging/line6/pcm.h @@ -145,21 +145,21 @@ enum { LINE6_BIT_PCM_IMPULSE_PLAYBACK_BUFFER | #endif LINE6_BIT_PCM_ALSA_PLAYBACK_BUFFER | - LINE6_BIT_PCM_MONITOR_PLAYBACK_BUFFER , + LINE6_BIT_PCM_MONITOR_PLAYBACK_BUFFER, LINE6_BITS_PLAYBACK_STREAM = #ifdef CONFIG_LINE6_USB_IMPULSE_RESPONSE LINE6_BIT_PCM_IMPULSE_PLAYBACK_STREAM | #endif LINE6_BIT_PCM_ALSA_PLAYBACK_STREAM | - LINE6_BIT_PCM_MONITOR_PLAYBACK_STREAM , + LINE6_BIT_PCM_MONITOR_PLAYBACK_STREAM, LINE6_BITS_CAPTURE_BUFFER = #ifdef CONFIG_LINE6_USB_IMPULSE_RESPONSE LINE6_BIT_PCM_IMPULSE_CAPTURE_BUFFER | #endif LINE6_BIT_PCM_ALSA_CAPTURE_BUFFER | - LINE6_BIT_PCM_MONITOR_CAPTURE_BUFFER , + LINE6_BIT_PCM_MONITOR_CAPTURE_BUFFER, LINE6_BITS_CAPTURE_STREAM = #ifdef CONFIG_LINE6_USB_IMPULSE_RESPONSE -- 2.2.1 ___ devel mailing list de...@linuxdriverproject.org http://driverdev.linuxdriverproject.org/mailman/listinfo/driverdev-devel
[PATCH 21/27] staging: line6: Remove stale Pocket POD PCM endpoints
From: Chris Rorvick Commit 1027f476f507 (staging: line6: sync with upstream) removed PCM from the Pocket POD capabilities but left the endpoint configuration. Signed-off-by: Chris Rorvick Reviewed-by: Stefan Hajnoczi Signed-off-by: Greg Kroah-Hartman --- drivers/staging/line6/pcm.c | 5 - 1 file changed, 5 deletions(-) diff --git a/drivers/staging/line6/pcm.c b/drivers/staging/line6/pcm.c index d8450afe7d66..19aa92765887 100644 --- a/drivers/staging/line6/pcm.c +++ b/drivers/staging/line6/pcm.c @@ -448,11 +448,6 @@ int line6_init_pcm(struct usb_line6 *line6, ep_write = 0x02; break; - case LINE6_POCKETPOD: - ep_read = 0x82; - ep_write = 0x02; - break; - case LINE6_GUITARPORT: case LINE6_PODSTUDIO_GX: case LINE6_PODSTUDIO_UX1: -- 2.2.1 ___ devel mailing list de...@linuxdriverproject.org http://driverdev.linuxdriverproject.org/mailman/listinfo/driverdev-devel
[PATCH 04/27] staging: line6: Remove line6_pod_transmit_paramter()
From: Chris Rorvick This function was no longer used as of commit 2807904441d4 (staging: line6: drop MIDI parameter sysfs attrs). Signed-off-by: Chris Rorvick Reviewed-by: Stefan Hajnoczi Signed-off-by: Greg Kroah-Hartman --- drivers/staging/line6/pod.c | 9 - drivers/staging/line6/pod.h | 2 -- 2 files changed, 11 deletions(-) diff --git a/drivers/staging/line6/pod.c b/drivers/staging/line6/pod.c index 44f4b2f98570..7b4ec92fe020 100644 --- a/drivers/staging/line6/pod.c +++ b/drivers/staging/line6/pod.c @@ -159,15 +159,6 @@ void line6_pod_process_message(struct usb_line6_pod *pod) } /* - Transmit PODxt Pro control parameter. -*/ -void line6_pod_transmit_parameter(struct usb_line6_pod *pod, int param, - u8 value) -{ - line6_transmit_parameter(&pod->line6, param, value); -} - -/* Send system parameter (from integer). */ static int pod_set_system_param_int(struct usb_line6_pod *pod, int value, diff --git a/drivers/staging/line6/pod.h b/drivers/staging/line6/pod.h index 3e3f1671337a..397d94c559f7 100644 --- a/drivers/staging/line6/pod.h +++ b/drivers/staging/line6/pod.h @@ -96,7 +96,5 @@ extern void line6_pod_disconnect(struct usb_interface *interface); extern int line6_pod_init(struct usb_interface *interface, struct usb_line6_pod *pod); extern void line6_pod_process_message(struct usb_line6_pod *pod); -extern void line6_pod_transmit_parameter(struct usb_line6_pod *pod, int param, -u8 value); #endif -- 2.2.1 ___ devel mailing list de...@linuxdriverproject.org http://driverdev.linuxdriverproject.org/mailman/listinfo/driverdev-devel
[PATCH 18/27] staging: line6: Filter on UX2 interfaces
From: Chris Rorvick The driver only supports interface 0 of the TonePort UX2 and POD Studio UX2 devices. Use the device table to filter on this. Signed-off-by: Chris Rorvick Reviewed-by: Stefan Hajnoczi Signed-off-by: Greg Kroah-Hartman --- drivers/staging/line6/driver.c | 20 1 file changed, 4 insertions(+), 16 deletions(-) diff --git a/drivers/staging/line6/driver.c b/drivers/staging/line6/driver.c index 8b03bc03d4d0..f04ff800a009 100644 --- a/drivers/staging/line6/driver.c +++ b/drivers/staging/line6/driver.c @@ -46,14 +46,14 @@ static const struct usb_device_id line6_id_table[] = { { LINE6_IF_NUM(0x414D, 1), .driver_info = LINE6_PODHD500_1 }, { LINE6_DEVICE(0x4153),.driver_info = LINE6_PODSTUDIO_GX }, { LINE6_DEVICE(0x4150),.driver_info = LINE6_PODSTUDIO_UX1 }, - { LINE6_DEVICE(0x4151),.driver_info = LINE6_PODSTUDIO_UX2 }, + { LINE6_IF_NUM(0x4151, 0), .driver_info = LINE6_PODSTUDIO_UX2 }, { LINE6_DEVICE(0x5044),.driver_info = LINE6_PODXT }, { LINE6_IF_NUM(0x4650, 0), .driver_info = LINE6_PODXTLIVE_POD }, { LINE6_IF_NUM(0x4650, 1), .driver_info = LINE6_PODXTLIVE_VARIAX }, { LINE6_DEVICE(0x5050),.driver_info = LINE6_PODXTPRO }, { LINE6_DEVICE(0x4147),.driver_info = LINE6_TONEPORT_GX }, { LINE6_DEVICE(0x4141),.driver_info = LINE6_TONEPORT_UX1 }, - { LINE6_DEVICE(0x4142),.driver_info = LINE6_TONEPORT_UX2 }, + { LINE6_IF_NUM(0x4142, 0), .driver_info = LINE6_TONEPORT_UX2 }, { LINE6_DEVICE(0x534d),.driver_info = LINE6_VARIAX }, {} }; @@ -768,20 +768,8 @@ static int line6_probe(struct usb_interface *interface, case LINE6_TONEPORT_UX2: case LINE6_PODSTUDIO_UX2: - switch (interface_number) { - case 0: - /* defaults to 44.1kHz, 16-bit */ - alternate = 2; - break; - case 1: - /* don't know yet what this is ... - alternate = 1; - break; -*/ - return -ENODEV; - default: - MISSING_CASE; - } + /* defaults to 44.1kHz, 16-bit */ + alternate = 2; break; default: -- 2.2.1 ___ devel mailing list de...@linuxdriverproject.org http://driverdev.linuxdriverproject.org/mailman/listinfo/driverdev-devel
[PATCH 09/27] staging: line6: Key off of device type
From: Chris Rorvick The driver currently uses the device's idProduct as input to several switch statements. In some cases this is not sufficiently granular and the interface number must be taken into account. Store the device type in `usb_line6' and key off of it instead. New types can then be added that map to specific interfaces on the device so that this conditional logic can be flattened out. Signed-off-by: Chris Rorvick Reviewed-by: Stefan Hajnoczi Signed-off-by: Greg Kroah-Hartman --- drivers/staging/line6/driver.c | 203 --- drivers/staging/line6/driver.h | 4 +- drivers/staging/line6/pcm.c | 38 drivers/staging/line6/toneport.c | 42 4 files changed, 144 insertions(+), 143 deletions(-) diff --git a/drivers/staging/line6/driver.c b/drivers/staging/line6/driver.c index c090b2bb1729..81d5a27421cb 100644 --- a/drivers/staging/line6/driver.c +++ b/drivers/staging/line6/driver.c @@ -363,23 +363,23 @@ static void line6_data_received(struct urb *urb) line6->message_length = done; line6_midi_receive(line6, line6->buffer_message, done); - switch (le16_to_cpu(line6->usbdev->descriptor.idProduct)) { - case LINE6_DEVID_BASSPODXT: - case LINE6_DEVID_BASSPODXTLIVE: - case LINE6_DEVID_BASSPODXTPRO: - case LINE6_DEVID_PODXT: - case LINE6_DEVID_PODXTPRO: - case LINE6_DEVID_POCKETPOD: + switch (line6->type) { + case LINE6_BASSPODXT: + case LINE6_BASSPODXTLIVE: + case LINE6_BASSPODXTPRO: + case LINE6_PODXT: + case LINE6_PODXTPRO: + case LINE6_POCKETPOD: line6_pod_process_message((struct usb_line6_pod *) line6); break; - case LINE6_DEVID_PODHD300: - case LINE6_DEVID_PODHD400: - case LINE6_DEVID_PODHD500: + case LINE6_PODHD300: + case LINE6_PODHD400: + case LINE6_PODHD500: break; /* let userspace handle MIDI */ - case LINE6_DEVID_PODXTLIVE: + case LINE6_PODXTLIVE: switch (line6->interface_number) { case PODXTLIVE_INTERFACE_POD: line6_pod_process_message((struct usb_line6_pod @@ -399,7 +399,7 @@ static void line6_data_received(struct urb *urb) } break; - case LINE6_DEVID_VARIAX: + case LINE6_VARIAX: line6_variax_process_message((struct usb_line6_variax *) line6); break; @@ -629,7 +629,6 @@ static int line6_probe(struct usb_interface *interface, struct usb_line6 *line6; const struct line6_properties *properties; int interface_number, alternate = 0; - int product; int size = 0; int ep_read = 0, ep_write = 0; int ret; @@ -651,19 +650,18 @@ static int line6_probe(struct usb_interface *interface, /* initialize device info: */ properties = &line6_properties_table[devtype]; dev_info(&interface->dev, "Line6 %s found\n", properties->name); - product = le16_to_cpu(usbdev->descriptor.idProduct); /* query interface number */ interface_number = interface->cur_altsetting->desc.bInterfaceNumber; - switch (product) { - case LINE6_DEVID_BASSPODXTLIVE: - case LINE6_DEVID_PODXTLIVE: - case LINE6_DEVID_VARIAX: + switch (devtype) { + case LINE6_BASSPODXTLIVE: + case LINE6_PODXTLIVE: + case LINE6_VARIAX: alternate = 1; break; - case LINE6_DEVID_POCKETPOD: + case LINE6_POCKETPOD: switch (interface_number) { case 0: return -ENODEV; /* this interface has no endpoints */ @@ -675,7 +673,7 @@ static int line6_probe(struct usb_interface *interface, } break; - case LINE6_DEVID_PODHD500: + case LINE6_PODHD500: switch (interface_number) { case 0: alternate = 1; @@ -688,25 +686,25 @@ static int line6_probe(struct usb_interface *interface, } break; - case LINE6_DEVID_BASSPODXT: - case LINE6_DEVID_BASSPODXTPRO: - case LINE6_DEVID_PODXT: - case LINE6_DEVID_PODXTPRO: - case LINE6_DEVID_PODHD300: - case LINE6_DEVID_PODHD400: + case LINE6_BASSPODXT: + case LINE6_BASSPODXTPRO: + case LINE6_PODXT: + case LINE6_PODXTPRO: + case LINE6_PODHD300: + case LINE6_PODHD400: alternate = 5; break;
[PATCH 27/27] staging: line6: Make *_disconnect() functions static
From: Chris Rorvick Remove declarations from the header and move the definitions up in the source so they need not be forward declared. Signed-off-by: Chris Rorvick Reviewed-by: Stefan Hajnoczi Signed-off-by: Greg Kroah-Hartman --- drivers/staging/line6/pod.c | 58 ++-- drivers/staging/line6/pod.h | 1 - drivers/staging/line6/podhd.c| 42 +- drivers/staging/line6/podhd.h| 1 - drivers/staging/line6/toneport.c | 64 +--- drivers/staging/line6/toneport.h | 1 - drivers/staging/line6/variax.c | 22 +++--- drivers/staging/line6/variax.h | 1 - 8 files changed, 94 insertions(+), 96 deletions(-) diff --git a/drivers/staging/line6/pod.c b/drivers/staging/line6/pod.c index b9af5cf50ecf..85a43631996e 100644 --- a/drivers/staging/line6/pod.c +++ b/drivers/staging/line6/pod.c @@ -338,6 +338,35 @@ static void pod_destruct(struct usb_interface *interface) } /* + POD device disconnected. +*/ +static void line6_pod_disconnect(struct usb_interface *interface) +{ + struct usb_line6_pod *pod; + + if (interface == NULL) + return; + pod = usb_get_intfdata(interface); + + if (pod != NULL) { + struct snd_line6_pcm *line6pcm = pod->line6.line6pcm; + struct device *dev = &interface->dev; + + if (line6pcm != NULL) + line6_pcm_disconnect(line6pcm); + + if (dev != NULL) { + /* remove sysfs entries: */ + device_remove_file(dev, &dev_attr_device_id); + device_remove_file(dev, &dev_attr_firmware_version); + device_remove_file(dev, &dev_attr_serial_number); + } + } + + pod_destruct(interface); +} + +/* Create sysfs entries. */ static int pod_create_files2(struct device *dev) @@ -422,32 +451,3 @@ int line6_pod_init(struct usb_interface *interface, struct usb_line6 *line6) return err; } - -/* - POD device disconnected. -*/ -void line6_pod_disconnect(struct usb_interface *interface) -{ - struct usb_line6_pod *pod; - - if (interface == NULL) - return; - pod = usb_get_intfdata(interface); - - if (pod != NULL) { - struct snd_line6_pcm *line6pcm = pod->line6.line6pcm; - struct device *dev = &interface->dev; - - if (line6pcm != NULL) - line6_pcm_disconnect(line6pcm); - - if (dev != NULL) { - /* remove sysfs entries: */ - device_remove_file(dev, &dev_attr_device_id); - device_remove_file(dev, &dev_attr_firmware_version); - device_remove_file(dev, &dev_attr_serial_number); - } - } - - pod_destruct(interface); -} diff --git a/drivers/staging/line6/pod.h b/drivers/staging/line6/pod.h index 0d78ca76a72f..87a8f0fa9cba 100644 --- a/drivers/staging/line6/pod.h +++ b/drivers/staging/line6/pod.h @@ -86,7 +86,6 @@ struct usb_line6_pod { int device_id; }; -extern void line6_pod_disconnect(struct usb_interface *interface); extern int line6_pod_init(struct usb_interface *interface, struct usb_line6 *line6); diff --git a/drivers/staging/line6/podhd.c b/drivers/staging/line6/podhd.c index a57fbce3503e..27c5402cece8 100644 --- a/drivers/staging/line6/podhd.c +++ b/drivers/staging/line6/podhd.c @@ -87,6 +87,27 @@ static void podhd_destruct(struct usb_interface *interface) } /* + POD HD device disconnected. +*/ +static void line6_podhd_disconnect(struct usb_interface *interface) +{ + struct usb_line6_podhd *podhd; + + if (interface == NULL) + return; + podhd = usb_get_intfdata(interface); + + if (podhd != NULL) { + struct snd_line6_pcm *line6pcm = podhd->line6.line6pcm; + + if (line6pcm != NULL) + line6_pcm_disconnect(line6pcm); + } + + podhd_destruct(interface); +} + +/* Try to init POD HD device. */ static int podhd_try_init(struct usb_interface *interface, @@ -133,24 +154,3 @@ int line6_podhd_init(struct usb_interface *interface, struct usb_line6 *line6) return err; } - -/* - POD HD device disconnected. -*/ -void line6_podhd_disconnect(struct usb_interface *interface) -{ - struct usb_line6_podhd *podhd; - - if (interface == NULL) - return; - podhd = usb_get_intfdata(interface); - - if (podhd != NULL) { - struct snd_line6_pcm *line6pcm = podhd->line6.line6pcm; - - if (line6pcm != NULL) - line6_pcm_disconnect(line6pcm); - } - - podhd_destruct(interface); -} diff --git a/drivers/staging/line6/podhd.h b/drivers/staging/line6/podhd.h index b7d9568e3a6c..a14f711f9725 100644
[PATCH 23/27] staging: line6: Pass *_init() `usb_line6' pointers
From: Chris Rorvick Casting the `struct usb_line6' pointer at the call point makes the code difficult to read. This is substantially cleaned up by moving the cast into the callees. Signed-off-by: Chris Rorvick Reviewed-by: Stefan Hajnoczi Signed-off-by: Greg Kroah-Hartman --- drivers/staging/line6/driver.c | 21 ++--- drivers/staging/line6/pod.c | 8 drivers/staging/line6/pod.h | 2 +- drivers/staging/line6/podhd.c| 4 ++-- drivers/staging/line6/podhd.h| 2 +- drivers/staging/line6/toneport.c | 8 drivers/staging/line6/toneport.h | 2 +- drivers/staging/line6/variax.c | 8 drivers/staging/line6/variax.h | 2 +- 9 files changed, 24 insertions(+), 33 deletions(-) diff --git a/drivers/staging/line6/driver.c b/drivers/staging/line6/driver.c index 4bfef2126931..08f805157330 100644 --- a/drivers/staging/line6/driver.c +++ b/drivers/staging/line6/driver.c @@ -959,33 +959,26 @@ static int line6_probe(struct usb_interface *interface, case LINE6_POCKETPOD: case LINE6_PODXT: case LINE6_PODXTPRO: - ret = line6_pod_init(interface, (struct usb_line6_pod *)line6); + ret = line6_pod_init(interface, line6); break; case LINE6_PODHD300: case LINE6_PODHD400: case LINE6_PODHD500_0: case LINE6_PODHD500_1: - ret = line6_podhd_init(interface, - (struct usb_line6_podhd *)line6); + ret = line6_podhd_init(interface, line6); break; case LINE6_PODXTLIVE_POD: - ret = - line6_pod_init(interface, - (struct usb_line6_pod *)line6); + ret = line6_pod_init(interface, line6); break; case LINE6_PODXTLIVE_VARIAX: - ret = - line6_variax_init(interface, - (struct usb_line6_variax *)line6); + ret = line6_variax_init(interface, line6); break; case LINE6_VARIAX: - ret = - line6_variax_init(interface, - (struct usb_line6_variax *)line6); + ret = line6_variax_init(interface, line6); break; case LINE6_PODSTUDIO_GX: @@ -995,9 +988,7 @@ static int line6_probe(struct usb_interface *interface, case LINE6_TONEPORT_UX1: case LINE6_TONEPORT_UX2: case LINE6_GUITARPORT: - ret = - line6_toneport_init(interface, - (struct usb_line6_toneport *)line6); + ret = line6_toneport_init(interface, line6); break; default: diff --git a/drivers/staging/line6/pod.c b/drivers/staging/line6/pod.c index 0fb178848182..9292b7215d64 100644 --- a/drivers/staging/line6/pod.c +++ b/drivers/staging/line6/pod.c @@ -353,10 +353,10 @@ static int pod_create_files2(struct device *dev) Try to init POD device. */ static int pod_try_init(struct usb_interface *interface, - struct usb_line6_pod *pod) + struct usb_line6 *line6) { int err; - struct usb_line6 *line6 = &pod->line6; + struct usb_line6_pod *pod = (struct usb_line6_pod *) line6; init_timer(&pod->startup_timer); INIT_WORK(&pod->startup_work, pod_startup4); @@ -409,9 +409,9 @@ static int pod_try_init(struct usb_interface *interface, /* Init POD device (and clean up in case of failure). */ -int line6_pod_init(struct usb_interface *interface, struct usb_line6_pod *pod) +int line6_pod_init(struct usb_interface *interface, struct usb_line6 *line6) { - int err = pod_try_init(interface, pod); + int err = pod_try_init(interface, line6); if (err < 0) pod_destruct(interface); diff --git a/drivers/staging/line6/pod.h b/drivers/staging/line6/pod.h index 91fd4c58f63c..cf6c75cd6760 100644 --- a/drivers/staging/line6/pod.h +++ b/drivers/staging/line6/pod.h @@ -88,7 +88,7 @@ struct usb_line6_pod { extern void line6_pod_disconnect(struct usb_interface *interface); extern int line6_pod_init(struct usb_interface *interface, - struct usb_line6_pod *pod); + struct usb_line6 *line6); extern void line6_pod_process_message(struct usb_line6_pod *pod); #endif diff --git a/drivers/staging/line6/podhd.c b/drivers/staging/line6/podhd.c index 7ef45437b4f2..3bb942e7ff93 100644 --- a/drivers/staging/line6/podhd.c +++ b/drivers/staging/line6/podhd.c @@ -121,9 +121,9 @@ static int podhd_try_init(struct usb_interface *interface, /* Init POD HD device (and clean up in case of failure). */ -int line6_podhd_init(struct usb_interface *interface, -struct usb_line6_podhd *podhd) +int line6_podhd_init(struct usb_interface *interface,
[PATCH 13/27] staging: line6: Use explicit indexes when defining properties
From: Chris Rorvick Specify the index of the properties entry explicitly to define this structure more robustly. Also, drop the `L6PROP' macro in favor of initializing each member explicitly on its own line since horizontal space is limited and more attributes will be added later. Signed-off-by: Chris Rorvick Reviewed-by: Stefan Hajnoczi Signed-off-by: Greg Kroah-Hartman --- drivers/staging/line6/driver.c | 112 + 1 file changed, 90 insertions(+), 22 deletions(-) diff --git a/drivers/staging/line6/driver.c b/drivers/staging/line6/driver.c index 4ec87a37ace4..c988b7882869 100644 --- a/drivers/staging/line6/driver.c +++ b/drivers/staging/line6/driver.c @@ -57,29 +57,97 @@ static const struct usb_device_id line6_id_table[] = { MODULE_DEVICE_TABLE(usb, line6_id_table); -#define L6PROP(dev_id, dev_name, dev_cap)\ - {.id = dev_id,\ -.name = dev_name, .capabilities = LINE6_CAP_##dev_cap} - static const struct line6_properties line6_properties_table[] = { - L6PROP("BassPODxt", "BassPODxt",CTRL_PCM_HW), - L6PROP("BassPODxtLive", "BassPODxt Live", CTRL_PCM_HW), - L6PROP("BassPODxtPro", "BassPODxt Pro",CTRL_PCM_HW), - L6PROP("GuitarPort","GuitarPort", PCM), - L6PROP("PocketPOD", "Pocket POD", CONTROL), - L6PROP("PODHD300", "POD HD300",CTRL_PCM_HW), - L6PROP("PODHD400", "POD HD400",CTRL_PCM_HW), - L6PROP("PODHD500", "POD HD500",CTRL_PCM_HW), - L6PROP("PODStudioGX", "POD Studio GX",PCM), - L6PROP("PODStudioUX1", "POD Studio UX1", PCM), - L6PROP("PODStudioUX2", "POD Studio UX2", PCM), - L6PROP("PODxt", "PODxt",CTRL_PCM_HW), - L6PROP("PODxtLive", "PODxt Live", CTRL_PCM_HW), - L6PROP("PODxtPro", "PODxt Pro",CTRL_PCM_HW), - L6PROP("TonePortGX","TonePort GX", PCM), - L6PROP("TonePortUX1", "TonePort UX1", PCM), - L6PROP("TonePortUX2", "TonePort UX2", PCM), - L6PROP("Variax","Variax Workbench", CONTROL), + [LINE6_BASSPODXT] = { + .id = "BassPODxt", + .name = "BassPODxt", + .capabilities = LINE6_CAP_CTRL_PCM_HW, + }, + [LINE6_BASSPODXTLIVE] = { + .id = "BassPODxtLive", + .name = "BassPODxt Live", + .capabilities = LINE6_CAP_CTRL_PCM_HW, + }, + [LINE6_BASSPODXTPRO] = { + .id = "BassPODxtPro", + .name = "BassPODxt Pro", + .capabilities = LINE6_CAP_CTRL_PCM_HW, + }, + [LINE6_GUITARPORT] = { + .id = "GuitarPort", + .name = "GuitarPort", + .capabilities = LINE6_CAP_PCM, + }, + [LINE6_POCKETPOD] = { + .id = "PocketPOD", + .name = "Pocket POD", + .capabilities = LINE6_CAP_CONTROL, + }, + [LINE6_PODHD300] = { + .id = "PODHD300", + .name = "POD HD300", + .capabilities = LINE6_CAP_CTRL_PCM_HW, + }, + [LINE6_PODHD400] = { + .id = "PODHD400", + .name = "POD HD400", + .capabilities = LINE6_CAP_CTRL_PCM_HW, + }, + [LINE6_PODHD500] = { + .id = "PODHD500", + .name = "POD HD500", + .capabilities = LINE6_CAP_CTRL_PCM_HW, + }, + [LINE6_PODSTUDIO_GX] = { + .id = "PODStudioGX", + .name = "POD Studio GX", + .capabilities = LINE6_CAP_PCM, + }, + [LINE6_PODSTUDIO_UX1] = { + .id = "PODStudioUX1", + .name = "POD Studio UX1", + .capabilities = LINE6_CAP_PCM, + }, + [LINE6_PODSTUDIO_UX2] = { + .id = "PODStudioUX2", + .name = "POD Studio UX2", + .capabilities = LINE6_CAP_PCM, + }, + [LINE6_PODXT] = { + .id = "PODxt", + .name = "PODxt", + .capabilities = LINE6_CAP_CTRL_PCM_HW, + }, + [LINE6_PODXTLIVE] = { + .id = "PODxtLive", + .name = "PODxt Live", + .capabilities = LINE6_CAP_CTRL_PCM_HW, + }, + [LINE6_PODXTPRO] = { + .id = "PODxtPro", + .name = "PODxt Pro", + .capabilities = LINE6_CAP_CTRL_PCM_HW, + }, + [LINE6_TONEPORT_GX] = { + .id = "TonePortGX", + .name = "TonePort GX", + .capabilities = LINE6_CAP_PCM, + }, + [LINE6_TONEPORT_UX1] = { + .id = "TonePortUX1", + .name = "TonePort UX1", + .capabilities = LINE6_CAP_PCM, + }, + [LINE6_TONEPORT_UX2] = { + .id = "TonePortUX2", + .name = "TonePort UX2", + .capabilities = LINE6_CAP_PC
[PATCH 26/27] staging: line6: Call *_disconnect() via pointer
From: Chris Rorvick Which *_disconnect() to call on disconnect is known at initialization. Add a function pointer to the `usb_line6' struct and use to call into the appropriate logic instead of evaluating the conditional logic. Signed-off-by: Chris Rorvick Reviewed-by: Stefan Hajnoczi Signed-off-by: Greg Kroah-Hartman --- drivers/staging/line6/driver.c | 43 +--- drivers/staging/line6/driver.h | 1 + drivers/staging/line6/pod.c | 1 + drivers/staging/line6/podhd.c| 2 ++ drivers/staging/line6/toneport.c | 2 ++ drivers/staging/line6/variax.c | 1 + 6 files changed, 8 insertions(+), 42 deletions(-) diff --git a/drivers/staging/line6/driver.c b/drivers/staging/line6/driver.c index f7629cbe01a3..fc852f6ab8bc 100644 --- a/drivers/staging/line6/driver.c +++ b/drivers/staging/line6/driver.c @@ -1017,48 +1017,7 @@ static void line6_disconnect(struct usb_interface *interface) dev_err(line6->ifcdev, "driver bug: inconsistent usb device\n"); - switch (line6->type) { - case LINE6_BASSPODXT: - case LINE6_BASSPODXTLIVE: - case LINE6_BASSPODXTPRO: - case LINE6_POCKETPOD: - case LINE6_PODXT: - case LINE6_PODXTPRO: - line6_pod_disconnect(interface); - break; - - case LINE6_PODHD300: - case LINE6_PODHD400: - case LINE6_PODHD500_0: - case LINE6_PODHD500_1: - line6_podhd_disconnect(interface); - break; - - case LINE6_PODXTLIVE_POD: - line6_pod_disconnect(interface); - break; - - case LINE6_PODXTLIVE_VARIAX: - line6_variax_disconnect(interface); - break; - - case LINE6_VARIAX: - line6_variax_disconnect(interface); - break; - - case LINE6_PODSTUDIO_GX: - case LINE6_PODSTUDIO_UX1: - case LINE6_PODSTUDIO_UX2: - case LINE6_TONEPORT_GX: - case LINE6_TONEPORT_UX1: - case LINE6_TONEPORT_UX2: - case LINE6_GUITARPORT: - line6_toneport_disconnect(interface); - break; - - default: - MISSING_CASE; - } + line6->disconnect(interface); dev_info(&interface->dev, "Line6 %s now disconnected\n", line6->properties->name); diff --git a/drivers/staging/line6/driver.h b/drivers/staging/line6/driver.h index 220813f1cbb9..ad203f197e80 100644 --- a/drivers/staging/line6/driver.h +++ b/drivers/staging/line6/driver.h @@ -196,6 +196,7 @@ struct usb_line6 { int message_length; void (*process_message)(struct usb_line6 *); + void (*disconnect)(struct usb_interface *); }; extern char *line6_alloc_sysex_buffer(struct usb_line6 *line6, int code1, diff --git a/drivers/staging/line6/pod.c b/drivers/staging/line6/pod.c index 79dcff4ae5a7..b9af5cf50ecf 100644 --- a/drivers/staging/line6/pod.c +++ b/drivers/staging/line6/pod.c @@ -360,6 +360,7 @@ static int pod_try_init(struct usb_interface *interface, struct usb_line6_pod *pod = (struct usb_line6_pod *) line6; line6->process_message = line6_pod_process_message; + line6->disconnect = line6_pod_disconnect; init_timer(&pod->startup_timer); INIT_WORK(&pod->startup_work, pod_startup4); diff --git a/drivers/staging/line6/podhd.c b/drivers/staging/line6/podhd.c index 3bb942e7ff93..a57fbce3503e 100644 --- a/drivers/staging/line6/podhd.c +++ b/drivers/staging/line6/podhd.c @@ -98,6 +98,8 @@ static int podhd_try_init(struct usb_interface *interface, if ((interface == NULL) || (podhd == NULL)) return -ENODEV; + line6->disconnect = line6_podhd_disconnect; + /* initialize audio system: */ err = line6_init_audio(line6); if (err < 0) diff --git a/drivers/staging/line6/toneport.c b/drivers/staging/line6/toneport.c index de91910a102c..5c462b72a850 100644 --- a/drivers/staging/line6/toneport.c +++ b/drivers/staging/line6/toneport.c @@ -347,6 +347,8 @@ static int toneport_try_init(struct usb_interface *interface, if ((interface == NULL) || (toneport == NULL)) return -ENODEV; + line6->disconnect = line6_toneport_disconnect; + /* initialize audio system: */ err = line6_init_audio(line6); if (err < 0) diff --git a/drivers/staging/line6/variax.c b/drivers/staging/line6/variax.c index ccb1f689e335..ca25b41ea88b 100644 --- a/drivers/staging/line6/variax.c +++ b/drivers/staging/line6/variax.c @@ -181,6 +181,7 @@ static int variax_try_init(struct usb_interface *interface, int err;
[PATCH 15/27] staging: line6: Split out PODxt Live interfaces
From: Chris Rorvick The PODxt Live device has both a POD and a Variax interface. Add device type entries for each of these. Signed-off-by: Chris Rorvick Reviewed-by: Stefan Hajnoczi Signed-off-by: Greg Kroah-Hartman --- drivers/staging/line6/driver.c | 112 - drivers/staging/line6/driver.h | 8 +-- drivers/staging/line6/pcm.c| 3 +- drivers/staging/line6/pod.h| 6 --- 4 files changed, 48 insertions(+), 81 deletions(-) diff --git a/drivers/staging/line6/driver.c b/drivers/staging/line6/driver.c index 6fecc1b94e5c..cb9602941207 100644 --- a/drivers/staging/line6/driver.c +++ b/drivers/staging/line6/driver.c @@ -31,6 +31,7 @@ #define DRIVER_VERSION "0.9.1beta" DRIVER_REVISION #define LINE6_DEVICE(prod) USB_DEVICE(0x0e41, prod) +#define LINE6_IF_NUM(prod, n) USB_DEVICE_INTERFACE_NUMBER(0x0e41, prod, n) /* table of devices that work with this driver */ static const struct usb_device_id line6_id_table[] = { @@ -46,7 +47,8 @@ static const struct usb_device_id line6_id_table[] = { { LINE6_DEVICE(0x4150),.driver_info = LINE6_PODSTUDIO_UX1 }, { LINE6_DEVICE(0x4151),.driver_info = LINE6_PODSTUDIO_UX2 }, { LINE6_DEVICE(0x5044),.driver_info = LINE6_PODXT }, - { LINE6_DEVICE(0x4650),.driver_info = LINE6_PODXTLIVE }, + { LINE6_IF_NUM(0x4650, 0), .driver_info = LINE6_PODXTLIVE_POD }, + { LINE6_IF_NUM(0x4650, 1), .driver_info = LINE6_PODXTLIVE_VARIAX }, { LINE6_DEVICE(0x5050),.driver_info = LINE6_PODXTPRO }, { LINE6_DEVICE(0x4147),.driver_info = LINE6_TONEPORT_GX }, { LINE6_DEVICE(0x4141),.driver_info = LINE6_TONEPORT_UX1 }, @@ -132,7 +134,14 @@ static const struct line6_properties line6_properties_table[] = { | LINE6_CAP_PCM | LINE6_CAP_HWMON, }, - [LINE6_PODXTLIVE] = { + [LINE6_PODXTLIVE_POD] = { + .id = "PODxtLive", + .name = "PODxt Live", + .capabilities = LINE6_CAP_CONTROL + | LINE6_CAP_PCM + | LINE6_CAP_HWMON, + }, + [LINE6_PODXTLIVE_VARIAX] = { .id = "PODxtLive", .name = "PODxt Live", .capabilities = LINE6_CAP_CONTROL @@ -445,24 +454,15 @@ static void line6_data_received(struct urb *urb) case LINE6_PODHD500: break; /* let userspace handle MIDI */ - case LINE6_PODXTLIVE: - switch (line6->interface_number) { - case PODXTLIVE_INTERFACE_POD: - line6_pod_process_message((struct usb_line6_pod + case LINE6_PODXTLIVE_POD: + line6_pod_process_message((struct usb_line6_pod *)line6); - break; - - case PODXTLIVE_INTERFACE_VARIAX: - line6_variax_process_message((struct - usb_line6_variax - *)line6); - break; - - default: - dev_err(line6->ifcdev, - "PODxt Live interface %d not supported\n", - line6->interface_number); - } + break; + + case LINE6_PODXTLIVE_VARIAX: + line6_variax_process_message((struct + usb_line6_variax + *)line6); break; case LINE6_VARIAX: @@ -722,7 +722,8 @@ static int line6_probe(struct usb_interface *interface, switch (devtype) { case LINE6_BASSPODXTLIVE: - case LINE6_PODXTLIVE: + case LINE6_PODXTLIVE_POD: + case LINE6_PODXTLIVE_VARIAX: case LINE6_VARIAX: alternate = 1; break; @@ -841,24 +842,16 @@ static int line6_probe(struct usb_interface *interface, /* these don't have a control channel */ break; - case LINE6_PODXTLIVE: - switch (interface_number) { - case PODXTLIVE_INTERFACE_POD: - size = sizeof(struct usb_line6_pod); - ep_read = 0x84; - ep_write = 0x03; - break; - - case PODXTLIVE_INTERFACE_VARIAX: - size = sizeof(struct usb_line6_variax); - ep_read = 0x86; - ep_write = 0x05; - break; + case LINE6_PODXTLIVE_POD: + size = sizeof(struct usb_line6_pod); +
[PATCH 14/27] staging: line6: List out capabilities individually
From: Chris Rorvick The `LINE6_CAP_CTRL_PCM_HW' macro combines three capabilities to save horizontal space when defining the properties entries. Now that these are no longer limited to single lines this is not such a concern. Specify capabilities individually when defining each property for better clarity. Signed-off-by: Chris Rorvick Reviewed-by: Stefan Hajnoczi Signed-off-by: Greg Kroah-Hartman --- drivers/staging/line6/driver.c | 54 +++-- drivers/staging/line6/usbdefs.h | 4 --- 2 files changed, 36 insertions(+), 22 deletions(-) diff --git a/drivers/staging/line6/driver.c b/drivers/staging/line6/driver.c index c988b7882869..6fecc1b94e5c 100644 --- a/drivers/staging/line6/driver.c +++ b/drivers/staging/line6/driver.c @@ -61,92 +61,110 @@ static const struct line6_properties line6_properties_table[] = { [LINE6_BASSPODXT] = { .id = "BassPODxt", .name = "BassPODxt", - .capabilities = LINE6_CAP_CTRL_PCM_HW, + .capabilities = LINE6_CAP_CONTROL + | LINE6_CAP_PCM + | LINE6_CAP_HWMON, }, [LINE6_BASSPODXTLIVE] = { .id = "BassPODxtLive", .name = "BassPODxt Live", - .capabilities = LINE6_CAP_CTRL_PCM_HW, + .capabilities = LINE6_CAP_CONTROL + | LINE6_CAP_PCM + | LINE6_CAP_HWMON, }, [LINE6_BASSPODXTPRO] = { .id = "BassPODxtPro", .name = "BassPODxt Pro", - .capabilities = LINE6_CAP_CTRL_PCM_HW, + .capabilities = LINE6_CAP_CONTROL + | LINE6_CAP_PCM + | LINE6_CAP_HWMON, }, [LINE6_GUITARPORT] = { .id = "GuitarPort", .name = "GuitarPort", - .capabilities = LINE6_CAP_PCM, + .capabilities = LINE6_CAP_PCM, }, [LINE6_POCKETPOD] = { .id = "PocketPOD", .name = "Pocket POD", - .capabilities = LINE6_CAP_CONTROL, + .capabilities = LINE6_CAP_CONTROL, }, [LINE6_PODHD300] = { .id = "PODHD300", .name = "POD HD300", - .capabilities = LINE6_CAP_CTRL_PCM_HW, + .capabilities = LINE6_CAP_CONTROL + | LINE6_CAP_PCM + | LINE6_CAP_HWMON, }, [LINE6_PODHD400] = { .id = "PODHD400", .name = "POD HD400", - .capabilities = LINE6_CAP_CTRL_PCM_HW, + .capabilities = LINE6_CAP_CONTROL + | LINE6_CAP_PCM + | LINE6_CAP_HWMON, }, [LINE6_PODHD500] = { .id = "PODHD500", .name = "POD HD500", - .capabilities = LINE6_CAP_CTRL_PCM_HW, + .capabilities = LINE6_CAP_CONTROL + | LINE6_CAP_PCM + | LINE6_CAP_HWMON, }, [LINE6_PODSTUDIO_GX] = { .id = "PODStudioGX", .name = "POD Studio GX", - .capabilities = LINE6_CAP_PCM, + .capabilities = LINE6_CAP_PCM, }, [LINE6_PODSTUDIO_UX1] = { .id = "PODStudioUX1", .name = "POD Studio UX1", - .capabilities = LINE6_CAP_PCM, + .capabilities = LINE6_CAP_PCM, }, [LINE6_PODSTUDIO_UX2] = { .id = "PODStudioUX2", .name = "POD Studio UX2", - .capabilities = LINE6_CAP_PCM, + .capabilities = LINE6_CAP_PCM, }, [LINE6_PODXT] = { .id = "PODxt", .name = "PODxt", - .capabilities = LINE6_CAP_CTRL_PCM_HW, + .capabilities = LINE6_CAP_CONTROL + | LINE6_CAP_PCM + | LINE6_CAP_HWMON, }, [LINE6_PODXTLIVE] = { .id = "PODxtLive", .name = "PODxt Live", - .capabilities = LINE6_CAP_CTRL_PCM_HW, + .capabilities = LINE6_CAP_CONTROL + | LINE6_CAP_PCM + | LINE6_CAP_HWMON, }, [LINE6_PODXTPRO] = { .id = "PODxtPro", .name = "PODxt Pro", - .capabilities = LINE6_CAP_CTRL_PCM_HW, + .capabilities = LINE6_CAP_CONTROL + | LINE6_CAP_PCM + | LINE6_CAP_HWMON, }, [LINE6_TONEPORT_GX] = { .id = "TonePortGX", .name = "TonePort GX", - .capabilities = LINE6_CAP_PCM, +
[PATCH 25/27] staging: line6: Call *_process_message() via pointer
From: Chris Rorvick Which *_process_message() function (if any) to call when data is received is known at initialization. Add a function pointer to the `usb_line6' struct and use to call into the appropriate logic instead of evaluating the conditional logic for each message. Signed-off-by: Chris Rorvick Reviewed-by: Stefan Hajnoczi Signed-off-by: Greg Kroah-Hartman --- drivers/staging/line6/driver.c | 33 ++--- drivers/staging/line6/driver.h | 2 ++ drivers/staging/line6/pod.c| 4 +++- drivers/staging/line6/pod.h| 1 - drivers/staging/line6/variax.c | 4 +++- drivers/staging/line6/variax.h | 1 - 6 files changed, 10 insertions(+), 35 deletions(-) diff --git a/drivers/staging/line6/driver.c b/drivers/staging/line6/driver.c index 369e60e070e1..f7629cbe01a3 100644 --- a/drivers/staging/line6/driver.c +++ b/drivers/staging/line6/driver.c @@ -537,37 +537,8 @@ static void line6_data_received(struct urb *urb) line6->message_length = done; line6_midi_receive(line6, line6->buffer_message, done); - switch (line6->type) { - case LINE6_BASSPODXT: - case LINE6_BASSPODXTLIVE: - case LINE6_BASSPODXTPRO: - case LINE6_PODXT: - case LINE6_PODXTPRO: - case LINE6_POCKETPOD: - line6_pod_process_message(line6); - break; - - case LINE6_PODHD300: - case LINE6_PODHD400: - case LINE6_PODHD500_0: - case LINE6_PODHD500_1: - break; /* let userspace handle MIDI */ - - case LINE6_PODXTLIVE_POD: - line6_pod_process_message(line6); - break; - - case LINE6_PODXTLIVE_VARIAX: - line6_variax_process_message(line6); - break; - - case LINE6_VARIAX: - line6_variax_process_message(line6); - break; - - default: - MISSING_CASE; - } + if (line6->process_message) + line6->process_message(line6); } line6_start_listen(line6); diff --git a/drivers/staging/line6/driver.h b/drivers/staging/line6/driver.h index a4bde717e790..220813f1cbb9 100644 --- a/drivers/staging/line6/driver.h +++ b/drivers/staging/line6/driver.h @@ -194,6 +194,8 @@ struct usb_line6 { Length of message to be processed. */ int message_length; + + void (*process_message)(struct usb_line6 *); }; extern char *line6_alloc_sysex_buffer(struct usb_line6 *line6, int code1, diff --git a/drivers/staging/line6/pod.c b/drivers/staging/line6/pod.c index aa8977d1814f..79dcff4ae5a7 100644 --- a/drivers/staging/line6/pod.c +++ b/drivers/staging/line6/pod.c @@ -131,7 +131,7 @@ static char *pod_alloc_sysex_buffer(struct usb_line6_pod *pod, int code, /* Process a completely received message. */ -void line6_pod_process_message(struct usb_line6 *line6) +static void line6_pod_process_message(struct usb_line6 *line6) { struct usb_line6_pod *pod = (struct usb_line6_pod *) line6; const unsigned char *buf = pod->line6.buffer_message; @@ -359,6 +359,8 @@ static int pod_try_init(struct usb_interface *interface, int err; struct usb_line6_pod *pod = (struct usb_line6_pod *) line6; + line6->process_message = line6_pod_process_message; + init_timer(&pod->startup_timer); INIT_WORK(&pod->startup_work, pod_startup4); diff --git a/drivers/staging/line6/pod.h b/drivers/staging/line6/pod.h index 984a00bd294d..0d78ca76a72f 100644 --- a/drivers/staging/line6/pod.h +++ b/drivers/staging/line6/pod.h @@ -89,6 +89,5 @@ struct usb_line6_pod { extern void line6_pod_disconnect(struct usb_interface *interface); extern int line6_pod_init(struct usb_interface *interface, struct usb_line6 *line6); -extern void line6_pod_process_message(struct usb_line6 *line6); #endif diff --git a/drivers/staging/line6/variax.c b/drivers/staging/line6/variax.c index 4d419940a6bb..ccb1f689e335 100644 --- a/drivers/staging/line6/variax.c +++ b/drivers/staging/line6/variax.c @@ -130,7 +130,7 @@ static void variax_startup6(struct work_struct *work) /* Process a completely received message. */ -void line6_variax_process_message(struct usb_line6 *line6) +static void line6_variax_process_message(struct usb_line6 *line6) { struct usb_line6_variax *variax = (struct usb_line6_variax *) line6; const unsigned char *buf = variax->line6.buffer_message; @@ -180,6 +180,8 @@ static int variax_try_init(struct usb_interface *interface, struct usb_line6_variax *variax = (struct usb_line6_variax *) line6; int err; + line6->process_message = line6_variax_process_message; + init_timer(&variax->startup_tim
[PATCH 24/27] staging: line6: Pass *_process_message() `usb_line6' pointers
From: Chris Rorvick Casting the `struct usb_line6' pointer at the call point makes the code difficult to read. This is substantially cleaned up by moving the cast into the callees. Signed-off-by: Chris Rorvick Reviewed-by: Stefan Hajnoczi Signed-off-by: Greg Kroah-Hartman --- drivers/staging/line6/driver.c | 13 - drivers/staging/line6/pod.c| 3 ++- drivers/staging/line6/pod.h| 2 +- drivers/staging/line6/variax.c | 3 ++- drivers/staging/line6/variax.h | 2 +- 5 files changed, 10 insertions(+), 13 deletions(-) diff --git a/drivers/staging/line6/driver.c b/drivers/staging/line6/driver.c index 08f805157330..369e60e070e1 100644 --- a/drivers/staging/line6/driver.c +++ b/drivers/staging/line6/driver.c @@ -544,8 +544,7 @@ static void line6_data_received(struct urb *urb) case LINE6_PODXT: case LINE6_PODXTPRO: case LINE6_POCKETPOD: - line6_pod_process_message((struct usb_line6_pod *) - line6); + line6_pod_process_message(line6); break; case LINE6_PODHD300: @@ -555,19 +554,15 @@ static void line6_data_received(struct urb *urb) break; /* let userspace handle MIDI */ case LINE6_PODXTLIVE_POD: - line6_pod_process_message((struct usb_line6_pod - *)line6); + line6_pod_process_message(line6); break; case LINE6_PODXTLIVE_VARIAX: - line6_variax_process_message((struct - usb_line6_variax - *)line6); + line6_variax_process_message(line6); break; case LINE6_VARIAX: - line6_variax_process_message((struct usb_line6_variax *) -line6); + line6_variax_process_message(line6); break; default: diff --git a/drivers/staging/line6/pod.c b/drivers/staging/line6/pod.c index 9292b7215d64..aa8977d1814f 100644 --- a/drivers/staging/line6/pod.c +++ b/drivers/staging/line6/pod.c @@ -131,8 +131,9 @@ static char *pod_alloc_sysex_buffer(struct usb_line6_pod *pod, int code, /* Process a completely received message. */ -void line6_pod_process_message(struct usb_line6_pod *pod) +void line6_pod_process_message(struct usb_line6 *line6) { + struct usb_line6_pod *pod = (struct usb_line6_pod *) line6; const unsigned char *buf = pod->line6.buffer_message; if (memcmp(buf, pod_version_header, sizeof(pod_version_header)) == 0) { diff --git a/drivers/staging/line6/pod.h b/drivers/staging/line6/pod.h index cf6c75cd6760..984a00bd294d 100644 --- a/drivers/staging/line6/pod.h +++ b/drivers/staging/line6/pod.h @@ -89,6 +89,6 @@ struct usb_line6_pod { extern void line6_pod_disconnect(struct usb_interface *interface); extern int line6_pod_init(struct usb_interface *interface, struct usb_line6 *line6); -extern void line6_pod_process_message(struct usb_line6_pod *pod); +extern void line6_pod_process_message(struct usb_line6 *line6); #endif diff --git a/drivers/staging/line6/variax.c b/drivers/staging/line6/variax.c index f5b618bc3dbe..4d419940a6bb 100644 --- a/drivers/staging/line6/variax.c +++ b/drivers/staging/line6/variax.c @@ -130,8 +130,9 @@ static void variax_startup6(struct work_struct *work) /* Process a completely received message. */ -void line6_variax_process_message(struct usb_line6_variax *variax) +void line6_variax_process_message(struct usb_line6 *line6) { + struct usb_line6_variax *variax = (struct usb_line6_variax *) line6; const unsigned char *buf = variax->line6.buffer_message; switch (buf[0]) { diff --git a/drivers/staging/line6/variax.h b/drivers/staging/line6/variax.h index 9bf1464d45ec..7d445ff8c9dc 100644 --- a/drivers/staging/line6/variax.h +++ b/drivers/staging/line6/variax.h @@ -67,6 +67,6 @@ struct usb_line6_variax { extern void line6_variax_disconnect(struct usb_interface *interface); extern int line6_variax_init(struct usb_interface *interface, struct usb_line6 *line6); -extern void line6_variax_process_message(struct usb_line6_variax *variax); +extern void line6_variax_process_message(struct usb_line6 *line6); #endif -- 2.2.1 ___ devel mailing list de...@linuxdriverproject.org http://driverdev.linuxdriverproject.org/mailman/listinfo/driverdev-devel
[PATCH 11/27] staging: line6: Remove useless comments
From: Chris Rorvick Signed-off-by: Chris Rorvick Reviewed-by: Stefan Hajnoczi Signed-off-by: Greg Kroah-Hartman --- drivers/staging/line6/driver.c | 2 -- 1 file changed, 2 deletions(-) diff --git a/drivers/staging/line6/driver.c b/drivers/staging/line6/driver.c index 6dc8a0d4c4b6..acde205a62ba 100644 --- a/drivers/staging/line6/driver.c +++ b/drivers/staging/line6/driver.c @@ -61,7 +61,6 @@ MODULE_DEVICE_TABLE(usb, line6_id_table); {.id = dev_id,\ .name = dev_name, .capabilities = LINE6_BIT_##dev_cap} -/* *INDENT-OFF* */ static const struct line6_properties line6_properties_table[] = { L6PROP("BassPODxt", "BassPODxt",CTRL_PCM_HW), L6PROP("BassPODxtLive", "BassPODxt Live", CTRL_PCM_HW), @@ -82,7 +81,6 @@ static const struct line6_properties line6_properties_table[] = { L6PROP("TonePortUX2", "TonePort UX2", PCM), L6PROP("Variax","Variax Workbench", CONTROL), }; -/* *INDENT-ON* */ /* This is Line6's MIDI manufacturer ID. -- 2.2.1 ___ devel mailing list de...@linuxdriverproject.org http://driverdev.linuxdriverproject.org/mailman/listinfo/driverdev-devel
[PATCH 12/27] staging: line6: Rename capability macros
From: Chris Rorvick Including "BIT" in the macro name is pointless. Replace with "CAP" to provide some context for what its value represents. Signed-off-by: Chris Rorvick Reviewed-by: Stefan Hajnoczi Signed-off-by: Greg Kroah-Hartman --- drivers/staging/line6/driver.c | 8 drivers/staging/line6/midi.c | 2 +- drivers/staging/line6/pcm.c | 2 +- drivers/staging/line6/playback.c | 2 +- drivers/staging/line6/pod.c | 2 +- drivers/staging/line6/usbdefs.h | 12 ++-- 6 files changed, 14 insertions(+), 14 deletions(-) diff --git a/drivers/staging/line6/driver.c b/drivers/staging/line6/driver.c index acde205a62ba..4ec87a37ace4 100644 --- a/drivers/staging/line6/driver.c +++ b/drivers/staging/line6/driver.c @@ -59,7 +59,7 @@ MODULE_DEVICE_TABLE(usb, line6_id_table); #define L6PROP(dev_id, dev_name, dev_cap)\ {.id = dev_id,\ -.name = dev_name, .capabilities = LINE6_BIT_##dev_cap} +.name = dev_name, .capabilities = LINE6_CAP_##dev_cap} static const struct line6_properties line6_properties_table[] = { L6PROP("BassPODxt", "BassPODxt",CTRL_PCM_HW), @@ -830,7 +830,7 @@ static int line6_probe(struct usb_interface *interface, usb_set_intfdata(interface, line6); - if (properties->capabilities & LINE6_BIT_CONTROL) { + if (properties->capabilities & LINE6_CAP_CONTROL) { /* initialize USB buffers: */ line6->buffer_listen = kmalloc(LINE6_BUFSIZE_LISTEN, GFP_KERNEL); @@ -1052,7 +1052,7 @@ static int line6_suspend(struct usb_interface *interface, pm_message_t message) snd_power_change_state(line6->card, SNDRV_CTL_POWER_D3hot); - if (line6->properties->capabilities & LINE6_BIT_CONTROL) + if (line6->properties->capabilities & LINE6_CAP_CONTROL) line6_stop_listen(line6); if (line6pcm != NULL) { @@ -1071,7 +1071,7 @@ static int line6_resume(struct usb_interface *interface) { struct usb_line6 *line6 = usb_get_intfdata(interface); - if (line6->properties->capabilities & LINE6_BIT_CONTROL) + if (line6->properties->capabilities & LINE6_CAP_CONTROL) line6_start_listen(line6); snd_power_change_state(line6->card, SNDRV_CTL_POWER_D0); diff --git a/drivers/staging/line6/midi.c b/drivers/staging/line6/midi.c index 1ac343b649c1..c453485065a3 100644 --- a/drivers/staging/line6/midi.c +++ b/drivers/staging/line6/midi.c @@ -279,7 +279,7 @@ int line6_init_midi(struct usb_line6 *line6) int err; struct snd_line6_midi *line6midi; - if (!(line6->properties->capabilities & LINE6_BIT_CONTROL)) { + if (!(line6->properties->capabilities & LINE6_CAP_CONTROL)) { /* skip MIDI initialization and report success */ return 0; } diff --git a/drivers/staging/line6/pcm.c b/drivers/staging/line6/pcm.c index 86c7bcba7ad6..e09772f609b8 100644 --- a/drivers/staging/line6/pcm.c +++ b/drivers/staging/line6/pcm.c @@ -424,7 +424,7 @@ int line6_init_pcm(struct usb_line6 *line6, int ep_read = 0, ep_write = 0; struct snd_line6_pcm *line6pcm; - if (!(line6->properties->capabilities & LINE6_BIT_PCM)) + if (!(line6->properties->capabilities & LINE6_CAP_PCM)) return 0; /* skip PCM initialization and report success */ /* initialize PCM subsystem based on device: */ diff --git a/drivers/staging/line6/playback.c b/drivers/staging/line6/playback.c index 2ca8900e68c3..54b7f60624f8 100644 --- a/drivers/staging/line6/playback.c +++ b/drivers/staging/line6/playback.c @@ -261,7 +261,7 @@ static int submit_audio_out_urb(struct snd_line6_pcm *line6pcm) #endif if (! (line6pcm->line6-> -properties->capabilities & LINE6_BIT_HWMON) +properties->capabilities & LINE6_CAP_HWMON) && (line6pcm->flags & LINE6_BITS_PLAYBACK_STREAM) && (line6pcm->flags & LINE6_BITS_CAPTURE_STREAM)) add_monitor_signal(urb_out, line6pcm->prev_fbuf, diff --git a/drivers/staging/line6/pod.c b/drivers/staging/line6/pod.c index 7b4ec92fe020..0fb178848182 100644 --- a/drivers/staging/line6/pod.c +++ b/drivers/staging/line6/pod.c @@ -396,7 +396,7 @@ static int pod_try_init(struct usb_interface *interface, handler. */ - if (pod->line6.properties->capabilities & LINE6_BIT_CONTROL) { + if (pod->line6.properties->capabilities & LINE6_CAP_CONTROL) { pod->monitor_level = POD_SYSTEM_INVALID; /* initiate startup procedure: */ diff --git a/drivers/staging/line6/usbdefs.h b/drivers/staging/line6/usbdefs.h index c897dba67a3b..d6e46ee8fa02 100644 --- a/drivers/staging/line6/usbdefs.h +++ b/drivers/staging/line6/usbdefs.h @@ -15,15 +15,15 @@ #define USB_INTERVALS_PER_SECOND 1000
[PATCH 20/27] staging: line6: Move control endpoints to properties
From: Chris Rorvick The device type can now be used to determine the addresses of the control endpoints for the interface. Drop the conditional logic and make these values properties. Signed-off-by: Chris Rorvick Reviewed-by: Stefan Hajnoczi Signed-off-by: Greg Kroah-Hartman --- drivers/staging/line6/driver.c | 73 +- drivers/staging/line6/driver.h | 13 ++-- drivers/staging/line6/midi.c | 2 +- 3 files changed, 48 insertions(+), 40 deletions(-) diff --git a/drivers/staging/line6/driver.c b/drivers/staging/line6/driver.c index 01504704796e..40ec57c17b1b 100644 --- a/drivers/staging/line6/driver.c +++ b/drivers/staging/line6/driver.c @@ -68,6 +68,8 @@ static const struct line6_properties line6_properties_table[] = { | LINE6_CAP_PCM | LINE6_CAP_HWMON, .altsetting = 5, + .ep_ctrl_r = 0x84, + .ep_ctrl_w = 0x03, }, [LINE6_BASSPODXTLIVE] = { .id = "BassPODxtLive", @@ -76,6 +78,8 @@ static const struct line6_properties line6_properties_table[] = { | LINE6_CAP_PCM | LINE6_CAP_HWMON, .altsetting = 1, + .ep_ctrl_r = 0x84, + .ep_ctrl_w = 0x03, }, [LINE6_BASSPODXTPRO] = { .id = "BassPODxtPro", @@ -84,18 +88,23 @@ static const struct line6_properties line6_properties_table[] = { | LINE6_CAP_PCM | LINE6_CAP_HWMON, .altsetting = 5, + .ep_ctrl_r = 0x84, + .ep_ctrl_w = 0x03, }, [LINE6_GUITARPORT] = { .id = "GuitarPort", .name = "GuitarPort", .capabilities = LINE6_CAP_PCM, .altsetting = 2, /* 1..4 seem to be ok */ + /* no control channel */ }, [LINE6_POCKETPOD] = { .id = "PocketPOD", .name = "Pocket POD", .capabilities = LINE6_CAP_CONTROL, .altsetting = 0, + .ep_ctrl_r = 0x82, + .ep_ctrl_w = 0x02, }, [LINE6_PODHD300] = { .id = "PODHD300", @@ -104,6 +113,8 @@ static const struct line6_properties line6_properties_table[] = { | LINE6_CAP_PCM | LINE6_CAP_HWMON, .altsetting = 5, + .ep_ctrl_r = 0x84, + .ep_ctrl_w = 0x03, }, [LINE6_PODHD400] = { .id = "PODHD400", @@ -112,6 +123,8 @@ static const struct line6_properties line6_properties_table[] = { | LINE6_CAP_PCM | LINE6_CAP_HWMON, .altsetting = 5, + .ep_ctrl_r = 0x84, + .ep_ctrl_w = 0x03, }, [LINE6_PODHD500_0] = { .id = "PODHD500", @@ -120,6 +133,8 @@ static const struct line6_properties line6_properties_table[] = { | LINE6_CAP_PCM | LINE6_CAP_HWMON, .altsetting = 1, + .ep_ctrl_r = 0x81, + .ep_ctrl_w = 0x01, }, [LINE6_PODHD500_1] = { .id = "PODHD500", @@ -128,24 +143,29 @@ static const struct line6_properties line6_properties_table[] = { | LINE6_CAP_PCM | LINE6_CAP_HWMON, .altsetting = 1, + .ep_ctrl_r = 0x81, + .ep_ctrl_w = 0x01, }, [LINE6_PODSTUDIO_GX] = { .id = "PODStudioGX", .name = "POD Studio GX", .capabilities = LINE6_CAP_PCM, .altsetting = 2, /* 1..4 seem to be ok */ + /* no control channel */ }, [LINE6_PODSTUDIO_UX1] = { .id = "PODStudioUX1", .name = "POD Studio UX1", .capabilities = LINE6_CAP_PCM, .altsetting = 2, /* 1..4 seem to be ok */ + /* no control channel */ }, [LINE6_PODSTUDIO_UX2] = { .id = "PODStudioUX2", .name = "POD Studio UX2", .capabilities = LINE6_CAP_PCM, .altsetting = 2, /* defaults to 44.1kHz, 16-bit */ + /* no control channel */ }, [LINE6_PODXT] = { .id = "PODxt", @@ -154,6 +174,8 @@ static const struct line6_properties line6_properties_table[] = { | LINE6_CAP_PCM | LINE6_CAP_HWMON, .altsetting = 5, + .ep_ctrl_r = 0x84, + .ep_ctrl_w = 0x03, }, [LINE6_PODXTLIVE_POD] = { .id = "PODxtLive", @@ -162,6 +184,
[PATCH 16/27] staging: line6: Split out POD HD500 interfaces
From: Chris Rorvick The driver uses a different altsetting depending on the interface. Add device type entries for each of these. Signed-off-by: Chris Rorvick Reviewed-by: Stefan Hajnoczi Signed-off-by: Greg Kroah-Hartman --- drivers/staging/line6/driver.c | 41 - drivers/staging/line6/driver.h | 3 ++- drivers/staging/line6/pcm.c| 3 ++- 3 files changed, 28 insertions(+), 19 deletions(-) diff --git a/drivers/staging/line6/driver.c b/drivers/staging/line6/driver.c index cb9602941207..e97e2cb747fe 100644 --- a/drivers/staging/line6/driver.c +++ b/drivers/staging/line6/driver.c @@ -42,7 +42,8 @@ static const struct usb_device_id line6_id_table[] = { { LINE6_DEVICE(0x5051),.driver_info = LINE6_POCKETPOD }, { LINE6_DEVICE(0x5057),.driver_info = LINE6_PODHD300 }, { LINE6_DEVICE(0x5058),.driver_info = LINE6_PODHD400 }, - { LINE6_DEVICE(0x414D),.driver_info = LINE6_PODHD500 }, + { LINE6_IF_NUM(0x414D, 0), .driver_info = LINE6_PODHD500_0 }, + { LINE6_IF_NUM(0x414D, 1), .driver_info = LINE6_PODHD500_1 }, { LINE6_DEVICE(0x4153),.driver_info = LINE6_PODSTUDIO_GX }, { LINE6_DEVICE(0x4150),.driver_info = LINE6_PODSTUDIO_UX1 }, { LINE6_DEVICE(0x4151),.driver_info = LINE6_PODSTUDIO_UX2 }, @@ -105,7 +106,14 @@ static const struct line6_properties line6_properties_table[] = { | LINE6_CAP_PCM | LINE6_CAP_HWMON, }, - [LINE6_PODHD500] = { + [LINE6_PODHD500_0] = { + .id = "PODHD500", + .name = "POD HD500", + .capabilities = LINE6_CAP_CONTROL + | LINE6_CAP_PCM + | LINE6_CAP_HWMON, + }, + [LINE6_PODHD500_1] = { .id = "PODHD500", .name = "POD HD500", .capabilities = LINE6_CAP_CONTROL @@ -451,7 +459,8 @@ static void line6_data_received(struct urb *urb) case LINE6_PODHD300: case LINE6_PODHD400: - case LINE6_PODHD500: + case LINE6_PODHD500_0: + case LINE6_PODHD500_1: break; /* let userspace handle MIDI */ case LINE6_PODXTLIVE_POD: @@ -740,17 +749,12 @@ static int line6_probe(struct usb_interface *interface, } break; - case LINE6_PODHD500: - switch (interface_number) { - case 0: - alternate = 1; - break; - case 1: - alternate = 0; - break; - default: - MISSING_CASE; - } + case LINE6_PODHD500_0: + alternate = 1; + break; + + case LINE6_PODHD500_1: + alternate = 0; break; case LINE6_BASSPODXT: @@ -819,7 +823,8 @@ static int line6_probe(struct usb_interface *interface, ep_write = 0x03; break; - case LINE6_PODHD500: + case LINE6_PODHD500_0: + case LINE6_PODHD500_1: size = sizeof(struct usb_line6_podhd); ep_read = 0x81; ep_write = 0x01; @@ -954,7 +959,8 @@ static int line6_probe(struct usb_interface *interface, case LINE6_PODHD300: case LINE6_PODHD400: - case LINE6_PODHD500: + case LINE6_PODHD500_0: + case LINE6_PODHD500_1: ret = line6_podhd_init(interface, (struct usb_line6_podhd *)line6); break; @@ -1061,7 +1067,8 @@ static void line6_disconnect(struct usb_interface *interface) case LINE6_PODHD300: case LINE6_PODHD400: - case LINE6_PODHD500: + case LINE6_PODHD500_0: + case LINE6_PODHD500_1: line6_podhd_disconnect(interface); break; diff --git a/drivers/staging/line6/driver.h b/drivers/staging/line6/driver.h index 085aa44da64c..9d6b351ec9b3 100644 --- a/drivers/staging/line6/driver.h +++ b/drivers/staging/line6/driver.h @@ -28,7 +28,8 @@ enum line6_device_type { LINE6_POCKETPOD, LINE6_PODHD300, LINE6_PODHD400, - LINE6_PODHD500, + LINE6_PODHD500_0, + LINE6_PODHD500_1, LINE6_PODSTUDIO_GX, LINE6_PODSTUDIO_UX1, LINE6_PODSTUDIO_UX2, diff --git a/drivers/staging/line6/pcm.c b/drivers/staging/line6/pcm.c index d09d1eae8f9e..d8450afe7d66 100644 --- a/drivers/staging/line6/pcm.c +++ b/drivers/staging/line6/pcm.c @@ -442,7 +442,8 @@ int line6_init_pcm(struct usb_line6 *line6, ep_write = 0x01; break; - case LINE6_PODHD500: + case LINE6_PODHD500_0: + case LINE6_PODHD500_1: ep_read = 0x86;
[PATCH 08/27] staging: line6: Index properties array with device type
From: Chris Rorvick The current logic uses the index of the matched entry from the device table as an offset to the corresponding properties entry. The values of the new `line6_device_type' enum are ordered such that they can be used as an index into either of these arrays. Drop the device entry lookup logic and use the device type (via the .driver_info member) instead. Signed-off-by: Chris Rorvick Reviewed-by: Stefan Hajnoczi Signed-off-by: Greg Kroah-Hartman --- drivers/staging/line6/driver.c | 17 ++--- 1 file changed, 2 insertions(+), 15 deletions(-) diff --git a/drivers/staging/line6/driver.c b/drivers/staging/line6/driver.c index 2797e4132cfa..c090b2bb1729 100644 --- a/drivers/staging/line6/driver.c +++ b/drivers/staging/line6/driver.c @@ -624,7 +624,7 @@ static void line6_destruct(struct usb_interface *interface) static int line6_probe(struct usb_interface *interface, const struct usb_device_id *id) { - int devtype; + enum line6_device_type devtype; struct usb_device *usbdev; struct usb_line6 *line6; const struct line6_properties *properties; @@ -646,20 +646,7 @@ static int line6_probe(struct usb_interface *interface, goto err_put; } - /* check vendor and product id */ - for (devtype = ARRAY_SIZE(line6_id_table) - 1; devtype--;) { - u16 idVendor = le16_to_cpu(usbdev->descriptor.idVendor); - u16 idProduct = le16_to_cpu(usbdev->descriptor.idProduct); - - if (idVendor == line6_id_table[devtype].idVendor && - idProduct == line6_id_table[devtype].idProduct) - break; - } - - if (devtype < 0) { - ret = -ENODEV; - goto err_put; - } + devtype = id->driver_info; /* initialize device info: */ properties = &line6_properties_table[devtype]; -- 2.2.1 ___ devel mailing list de...@linuxdriverproject.org http://driverdev.linuxdriverproject.org/mailman/listinfo/driverdev-devel
[PATCH 22/27] staging: line6: Move audio endpoints to properties
From: Chris Rorvick The device type can now be used to determine the addresses of the audio endpoints for the interface. Drop the conditional logic and make these values properties. Signed-off-by: Chris Rorvick Reviewed-by: Stefan Hajnoczi Signed-off-by: Greg Kroah-Hartman --- drivers/staging/line6/capture.c | 9 drivers/staging/line6/driver.c | 38 +++ drivers/staging/line6/driver.h | 2 ++ drivers/staging/line6/pcm.c | 48 ++-- drivers/staging/line6/pcm.h | 10 - drivers/staging/line6/playback.c | 9 6 files changed, 52 insertions(+), 64 deletions(-) diff --git a/drivers/staging/line6/capture.c b/drivers/staging/line6/capture.c index e6ca631e3f79..f24c7c5e0a3e 100644 --- a/drivers/staging/line6/capture.c +++ b/drivers/staging/line6/capture.c @@ -400,6 +400,7 @@ struct snd_pcm_ops snd_line6_capture_ops = { int line6_create_audio_in_urbs(struct snd_line6_pcm *line6pcm) { + struct usb_line6 *line6 = line6pcm->line6; int i; /* create audio URBs and fill in constant values: */ @@ -411,14 +412,14 @@ int line6_create_audio_in_urbs(struct snd_line6_pcm *line6pcm) usb_alloc_urb(LINE6_ISO_PACKETS, GFP_KERNEL); if (urb == NULL) { - dev_err(line6pcm->line6->ifcdev, "Out of memory\n"); + dev_err(line6->ifcdev, "Out of memory\n"); return -ENOMEM; } - urb->dev = line6pcm->line6->usbdev; + urb->dev = line6->usbdev; urb->pipe = - usb_rcvisocpipe(line6pcm->line6->usbdev, - line6pcm->ep_audio_read & + usb_rcvisocpipe(line6->usbdev, + line6->properties->ep_audio_r & USB_ENDPOINT_NUMBER_MASK); urb->transfer_flags = URB_ISO_ASAP; urb->start_frame = -1; diff --git a/drivers/staging/line6/driver.c b/drivers/staging/line6/driver.c index 40ec57c17b1b..4bfef2126931 100644 --- a/drivers/staging/line6/driver.c +++ b/drivers/staging/line6/driver.c @@ -70,6 +70,8 @@ static const struct line6_properties line6_properties_table[] = { .altsetting = 5, .ep_ctrl_r = 0x84, .ep_ctrl_w = 0x03, + .ep_audio_r = 0x82, + .ep_audio_w = 0x01, }, [LINE6_BASSPODXTLIVE] = { .id = "BassPODxtLive", @@ -80,6 +82,8 @@ static const struct line6_properties line6_properties_table[] = { .altsetting = 1, .ep_ctrl_r = 0x84, .ep_ctrl_w = 0x03, + .ep_audio_r = 0x82, + .ep_audio_w = 0x01, }, [LINE6_BASSPODXTPRO] = { .id = "BassPODxtPro", @@ -90,6 +94,8 @@ static const struct line6_properties line6_properties_table[] = { .altsetting = 5, .ep_ctrl_r = 0x84, .ep_ctrl_w = 0x03, + .ep_audio_r = 0x82, + .ep_audio_w = 0x01, }, [LINE6_GUITARPORT] = { .id = "GuitarPort", @@ -97,6 +103,8 @@ static const struct line6_properties line6_properties_table[] = { .capabilities = LINE6_CAP_PCM, .altsetting = 2, /* 1..4 seem to be ok */ /* no control channel */ + .ep_audio_r = 0x82, + .ep_audio_w = 0x01, }, [LINE6_POCKETPOD] = { .id = "PocketPOD", @@ -105,6 +113,7 @@ static const struct line6_properties line6_properties_table[] = { .altsetting = 0, .ep_ctrl_r = 0x82, .ep_ctrl_w = 0x02, + /* no audio channel */ }, [LINE6_PODHD300] = { .id = "PODHD300", @@ -115,6 +124,8 @@ static const struct line6_properties line6_properties_table[] = { .altsetting = 5, .ep_ctrl_r = 0x84, .ep_ctrl_w = 0x03, + .ep_audio_r = 0x82, + .ep_audio_w = 0x01, }, [LINE6_PODHD400] = { .id = "PODHD400", @@ -125,6 +136,8 @@ static const struct line6_properties line6_properties_table[] = { .altsetting = 5, .ep_ctrl_r = 0x84, .ep_ctrl_w = 0x03, + .ep_audio_r = 0x82, + .ep_audio_w = 0x01, }, [LINE6_PODHD500_0] = { .id = "PODHD500", @@ -135,6 +148,8 @@ static const struct line6_properties line6_properties_table[] = { .altsetting = 1, .ep_ctrl_r = 0x81, .ep_ctrl_w = 0x01, + .ep_audio_r = 0x86, + .ep_audio_w = 0x02, }, [LINE6_PODHD500_1] = { .id = "PODHD500", @@ -145,6 +160,8 @@ static const struct l
[PATCH 10/27] staging: line6: Remove idVendor and idProduct macros
From: Chris Rorvick These are now only used to build the device table. Each entry in this table is already clearly documented as to what device it maps to so the macros become unnecessary indirection. Signed-off-by: Chris Rorvick Reviewed-by: Stefan Hajnoczi Signed-off-by: Greg Kroah-Hartman --- drivers/staging/line6/driver.c | 56 ++--- drivers/staging/line6/usbdefs.h | 24 -- 2 files changed, 19 insertions(+), 61 deletions(-) diff --git a/drivers/staging/line6/driver.c b/drivers/staging/line6/driver.c index 81d5a27421cb..6dc8a0d4c4b6 100644 --- a/drivers/staging/line6/driver.c +++ b/drivers/staging/line6/driver.c @@ -30,46 +30,28 @@ #define DRIVER_DESC"Line6 USB Driver" #define DRIVER_VERSION "0.9.1beta" DRIVER_REVISION -#define LINE6_DEVICE(prod) USB_DEVICE(LINE6_VENDOR_ID, prod) +#define LINE6_DEVICE(prod) USB_DEVICE(0x0e41, prod) /* table of devices that work with this driver */ static const struct usb_device_id line6_id_table[] = { - { LINE6_DEVICE(LINE6_DEVID_BASSPODXT), - .driver_info = LINE6_BASSPODXT }, - { LINE6_DEVICE(LINE6_DEVID_BASSPODXTLIVE), - .driver_info = LINE6_BASSPODXTLIVE }, - { LINE6_DEVICE(LINE6_DEVID_BASSPODXTPRO), - .driver_info = LINE6_BASSPODXTPRO }, - { LINE6_DEVICE(LINE6_DEVID_GUITARPORT), - .driver_info = LINE6_GUITARPORT }, - { LINE6_DEVICE(LINE6_DEVID_POCKETPOD), - .driver_info = LINE6_POCKETPOD }, - { LINE6_DEVICE(LINE6_DEVID_PODHD300), - .driver_info = LINE6_PODHD300 }, - { LINE6_DEVICE(LINE6_DEVID_PODHD400), - .driver_info = LINE6_PODHD400 }, - { LINE6_DEVICE(LINE6_DEVID_PODHD500), - .driver_info = LINE6_PODHD500 }, - { LINE6_DEVICE(LINE6_DEVID_PODSTUDIO_GX), - .driver_info = LINE6_PODSTUDIO_GX }, - { LINE6_DEVICE(LINE6_DEVID_PODSTUDIO_UX1), - .driver_info = LINE6_PODSTUDIO_UX1 }, - { LINE6_DEVICE(LINE6_DEVID_PODSTUDIO_UX2), - .driver_info = LINE6_PODSTUDIO_UX2 }, - { LINE6_DEVICE(LINE6_DEVID_PODXT), - .driver_info = LINE6_PODXT }, - { LINE6_DEVICE(LINE6_DEVID_PODXTLIVE), - .driver_info = LINE6_PODXTLIVE }, - { LINE6_DEVICE(LINE6_DEVID_PODXTPRO), - .driver_info = LINE6_PODXTPRO }, - { LINE6_DEVICE(LINE6_DEVID_TONEPORT_GX), - .driver_info = LINE6_TONEPORT_GX }, - { LINE6_DEVICE(LINE6_DEVID_TONEPORT_UX1), - .driver_info = LINE6_TONEPORT_UX1 }, - { LINE6_DEVICE(LINE6_DEVID_TONEPORT_UX2), - .driver_info = LINE6_TONEPORT_UX2 }, - { LINE6_DEVICE(LINE6_DEVID_VARIAX), - .driver_info = LINE6_VARIAX }, + { LINE6_DEVICE(0x4250),.driver_info = LINE6_BASSPODXT }, + { LINE6_DEVICE(0x4642),.driver_info = LINE6_BASSPODXTLIVE }, + { LINE6_DEVICE(0x4252),.driver_info = LINE6_BASSPODXTPRO }, + { LINE6_DEVICE(0x4750),.driver_info = LINE6_GUITARPORT }, + { LINE6_DEVICE(0x5051),.driver_info = LINE6_POCKETPOD }, + { LINE6_DEVICE(0x5057),.driver_info = LINE6_PODHD300 }, + { LINE6_DEVICE(0x5058),.driver_info = LINE6_PODHD400 }, + { LINE6_DEVICE(0x414D),.driver_info = LINE6_PODHD500 }, + { LINE6_DEVICE(0x4153),.driver_info = LINE6_PODSTUDIO_GX }, + { LINE6_DEVICE(0x4150),.driver_info = LINE6_PODSTUDIO_UX1 }, + { LINE6_DEVICE(0x4151),.driver_info = LINE6_PODSTUDIO_UX2 }, + { LINE6_DEVICE(0x5044),.driver_info = LINE6_PODXT }, + { LINE6_DEVICE(0x4650),.driver_info = LINE6_PODXTLIVE }, + { LINE6_DEVICE(0x5050),.driver_info = LINE6_PODXTPRO }, + { LINE6_DEVICE(0x4147),.driver_info = LINE6_TONEPORT_GX }, + { LINE6_DEVICE(0x4141),.driver_info = LINE6_TONEPORT_UX1 }, + { LINE6_DEVICE(0x4142),.driver_info = LINE6_TONEPORT_UX2 }, + { LINE6_DEVICE(0x534d),.driver_info = LINE6_VARIAX }, {} }; diff --git a/drivers/staging/line6/usbdefs.h b/drivers/staging/line6/usbdefs.h index 06bf909620e9..c897dba67a3b 100644 --- a/drivers/staging/line6/usbdefs.h +++ b/drivers/staging/line6/usbdefs.h @@ -12,32 +12,8 @@ #ifndef USBDEFS_H #define USBDEFS_H -#define LINE6_VENDOR_ID 0x0e41 - #define USB_INTERVALS_PER_SECOND 1000 -/* - Device ids. -*/ -#define LINE6_DEVID_BASSPODXT 0x4250 -#define LINE6_DEVID_BASSPODXTLIVE 0x4642 -#define LINE6_DEVID_BASSPODXTPRO 0x4252 -#define LINE6_DEVID_GUITARPORT0x4750 -#define LINE6_DEVID_POCKETPOD 0x5051 -#define LINE6_DEVID_PODHD300 0x5057 -#define LINE6_DEVID_PODHD400 0x5058 -#define LINE6_DEVID_PODHD500 0x414D -#define LINE6_DEVID_PODSTUDIO_GX 0x4153 -#define LINE6_DEVID_PODSTUDIO_UX1 0x4150 -#define LINE6_DEVID_PODSTUDIO_UX2 0x4151 -#define LINE6_DEVID_PODXT 0x5044 -#define LINE6_DEVID_PODXTLIVE 0x4650 -#define LINE6_D
[PATCH 17/27] staging: line6: Filter on Pocket POD interface
From: Chris Rorvick The driver only supports interface 1 of the Pocket POD. Use the device table to filter on this. Signed-off-by: Chris Rorvick Reviewed-by: Stefan Hajnoczi Signed-off-by: Greg Kroah-Hartman --- drivers/staging/line6/driver.c | 12 ++-- 1 file changed, 2 insertions(+), 10 deletions(-) diff --git a/drivers/staging/line6/driver.c b/drivers/staging/line6/driver.c index e97e2cb747fe..8b03bc03d4d0 100644 --- a/drivers/staging/line6/driver.c +++ b/drivers/staging/line6/driver.c @@ -39,7 +39,7 @@ static const struct usb_device_id line6_id_table[] = { { LINE6_DEVICE(0x4642),.driver_info = LINE6_BASSPODXTLIVE }, { LINE6_DEVICE(0x4252),.driver_info = LINE6_BASSPODXTPRO }, { LINE6_DEVICE(0x4750),.driver_info = LINE6_GUITARPORT }, - { LINE6_DEVICE(0x5051),.driver_info = LINE6_POCKETPOD }, + { LINE6_IF_NUM(0x5051, 1), .driver_info = LINE6_POCKETPOD }, { LINE6_DEVICE(0x5057),.driver_info = LINE6_PODHD300 }, { LINE6_DEVICE(0x5058),.driver_info = LINE6_PODHD400 }, { LINE6_IF_NUM(0x414D, 0), .driver_info = LINE6_PODHD500_0 }, @@ -738,15 +738,7 @@ static int line6_probe(struct usb_interface *interface, break; case LINE6_POCKETPOD: - switch (interface_number) { - case 0: - return -ENODEV; /* this interface has no endpoints */ - case 1: - alternate = 0; - break; - default: - MISSING_CASE; - } + alternate = 0; break; case LINE6_PODHD500_0: -- 2.2.1 ___ devel mailing list de...@linuxdriverproject.org http://driverdev.linuxdriverproject.org/mailman/listinfo/driverdev-devel
Re: [PATCH v8 2/4] fpga manager: add sysfs interface document
> Then configure udev to load right firmware for you, or ln -s > image-i-want-now socfpga-fpga-image to select the one to read...? Your conceptual model is wrong. FPGA firmware is dynamic. There are already people who lazy reload FPGA firmware on taskswitches. This proposed fpga manager is broken but it's broken in exactly the reverse direction to the one you are arguing for. There are plenty of people today who treat the FPGA as an entirely dynamic resource. It's not like flashing a controller, its near immediate. The udev/sysfs model is broken because - it's too slow for dynamic switching - it doesn't address permissions - it doesn't address namespaces - it doesn't address dynamic management of resources (open/use/close) with dyanmic resource recovery on the final close as is the Unix way. not because FPGA's are some static boot time resource. If you look at all the academic work on this you see the same kind of dynamic usage, even more so. The library API you actually need is much closer to /* Get my firmware */ fw = fpga_openfirmware("foo.fpga"); /* Get me a suitable FPGA for it */ fd = fpga_alloc(&w); /* Load it */ fgpa_load(fd, "foo.fpga"); do_shit(fd); fpga_close(fd); You want to be able to have things like your game just load up an audio physics engine, lob it into a random fpga, play it, drop it. Likewise lots of other FPGA apps - video processing for example, crypto, format convertors, gesture analysers and so on. Think a world where there are gimp filters that want to just grab an fpga for 3 seconds. Its completely dynamic and it will get more so as we switch from the painful world of VHDL and friends to high level parallel aware language compilers for FPGAs and everyone will be knocking up quick FPGA hacks. Alan ___ devel mailing list de...@linuxdriverproject.org http://driverdev.linuxdriverproject.org/mailman/listinfo/driverdev-devel
Re: [PATCH v8 2/4] fpga manager: add sysfs interface document
On Mon, Jan 12, 2015 at 09:01:34PM +, One Thousand Gnomes wrote: > There are plenty of people today who treat the FPGA as an entirely > dynamic resource. It's not like flashing a controller, its near > immediate. But this is a completely different use case. Remember, there are *megabytes* of internal state in a FPGA, and it isn't really feasible to dump/restore that state. It is one thing to context switch a maths algorithm that is built to be stateless, it is quite another to context switch between, say an ethernet core with an operating Linux Net driver doing DMA and a maths algorithm. A DT overlay approach where the overlay has to be unloaded to 'free' the FPGA makes alot of sense to me for the stateful kernel driver environment, and open/close/etc makes alot of sense for the stateless switchable userspace environment - other than sharing configuration code, is there any overlap between these use cases > Its completely dynamic and it will get more so as we switch from the > painful world of VHDL and friends to high level parallel aware language > compilers for FPGAs and everyone will be knocking up quick FPGA hacks. Only for some users. In my world FPGAs are filled with bus interface logic, ethernet controllers, memory controllers, packet processing engines, etc. This is all incredibly stateful - both in the FPGA itself, and in the Linux side w/ drviers. It certainly will not ever work in the model you are talking about. Even if the digital state could somehow be frozen, dumped and restored, all the FPGA external interface logic has *ANALOG* state that cannot ever be dump/restored. It just isn't feasible for that class of application. Jason ___ devel mailing list de...@linuxdriverproject.org http://driverdev.linuxdriverproject.org/mailman/listinfo/driverdev-devel
Re: [PATCH 00/27] staging: line6 patches queued up
At Mon, 12 Jan 2015 12:42:33 -0800, Greg Kroah-Hartman wrote: > > Hi Takashi, > > Here are all of the line6 patches that have been sent to me that were in > my queue, including the series from Chris that caused you to want to > move the driver out of staging. I included it here as it had to be > tweaked due to some earlier patches in my queue. Thanks, now I applied all to topic/line6 branch of sound git tree (which is merged into for-next branch). Takashi ___ devel mailing list de...@linuxdriverproject.org http://driverdev.linuxdriverproject.org/mailman/listinfo/driverdev-devel
Re: [PATCH 00/25] line6usb cleanup
At Mon, 12 Jan 2015 17:35:01 +0100, Takashi Iwai wrote: > > At Sun, 11 Jan 2015 15:04:55 -0600, > Chris Rorvick wrote: > > > > > At Fri, 9 Jan 2015 23:35:46 -0600, > > > Chris Rorvick wrote: > > >> > > >> I have a TonePort UX2 that I've used for testing, meaning that some of > > >> this is really only compile-tested. > > > > > > If anyone is responsible for testing with real hardware, I'll happily > > > review. > > > > To be clear, the TonePort UX2 is real hardware. But this driver > > basically supports four classes of Line 6 devices and I'm only covering > > one of them. > > > > So this series is a first step in trying to address this. Having this > > as a single driver probably made sense when it was a separate project, > > but now that it is in-tree it seems like the POD, PODHD, TonePort, and > > Variax pieces should each be separate drivers that each depend on a core > > Line 6 driver. I think the cleanup in this series will make that > > easier. None of this is my area of expertise, though, so advice and > > feedback is very welcome. > > > > > are there any active developers for this driver? > > > > I intended to do further work. I know there is quite a bit of mundane > > checkpatch cleanup that would need to get done before this could get > > promoted, and I believe I read that it's using sysfs for stuff that > > would normally be done via an ALSA interface, and the sysfs interface > > has not been documented nor has it been justified. All stuff I thought > > I might look into. > > > > But I'm just doing this for fun so I can't promise anything. :-) > > OK, so the situation looks fairly good, we have a few active > developers and/or testers. And the current code doesn't look so > terrible despite of it being in staging directory. That said, I think > we can promote this stuff into sound/usb/line6 directory, then apply > Chris' cleanup patches, and work on it further. > > Does it sound OK for you guys? Greg? > > Once when I get approval, I'll start a new clean branch on sound.git > tree so that you guys can work on it further for 3.20 kernel. JFYI, I merged all patches Greg forwarded to me into topic/line6 branch of sound git tree. It's included to linux-next, so you can work on linux-next or my branch as well. Now the code has been moved from driver/staging/line6 to sound/usb/line6. I'm going to apply some driver rename and cleanup patches to follow to other ALSA driver standards, and think of splitting to each driver with a core line6 helper module after that. Feel free to send the further development patches to me and/or alsa-devel ML like other sound drivers. thanks, Takashi ___ devel mailing list de...@linuxdriverproject.org http://driverdev.linuxdriverproject.org/mailman/listinfo/driverdev-devel
Re: [PATCH 00/27] staging: line6 patches queued up
On Mon, Jan 12, 2015 at 11:01:03PM +0100, Takashi Iwai wrote: > At Mon, 12 Jan 2015 12:42:33 -0800, > Greg Kroah-Hartman wrote: > > > > Hi Takashi, > > > > Here are all of the line6 patches that have been sent to me that were in > > my queue, including the series from Chris that caused you to want to > > move the driver out of staging. I included it here as it had to be > > tweaked due to some earlier patches in my queue. > > Thanks, now I applied all to topic/line6 branch of sound git tree > (which is merged into for-next branch). Wonderful, I'll now reject all line6 patches that get sent to me for this merge window, if that happens, and point them at you. thanks, greg k-h ___ devel mailing list de...@linuxdriverproject.org http://driverdev.linuxdriverproject.org/mailman/listinfo/driverdev-devel
[PATCH RESEND 1/1] X86: Mark the Hyper-V clocksource as being continuous
The Hyper-V clocksource is continuous; mark it accordingly. Signed-off-by: K. Y. Srinivasan Cc: stable --- arch/x86/kernel/cpu/mshyperv.c |1 + 1 files changed, 1 insertions(+), 0 deletions(-) diff --git a/arch/x86/kernel/cpu/mshyperv.c b/arch/x86/kernel/cpu/mshyperv.c index a450373..939155f 100644 --- a/arch/x86/kernel/cpu/mshyperv.c +++ b/arch/x86/kernel/cpu/mshyperv.c @@ -107,6 +107,7 @@ static struct clocksource hyperv_cs = { .rating = 400, /* use this when running on Hyperv*/ .read = read_hv_clock, .mask = CLOCKSOURCE_MASK(64), + .flags = CLOCK_SOURCE_IS_CONTINUOUS, }; static void __init ms_hyperv_init_platform(void) -- 1.7.4.1 ___ devel mailing list de...@linuxdriverproject.org http://driverdev.linuxdriverproject.org/mailman/listinfo/driverdev-devel
Re: [PATCH RESEND 1/1] X86: Mark the Hyper-V clocksource as being continuous
On Tue, Jan 13, 2015 at 8:26 AM, K. Y. Srinivasan wrote: The Hyper-V clocksource is continuous; mark it accordingly. Signed-off-by: K. Y. Srinivasan Cc: stable --- arch/x86/kernel/cpu/mshyperv.c |1 + 1 files changed, 1 insertions(+), 0 deletions(-) Acked-by: Jason Wang diff --git a/arch/x86/kernel/cpu/mshyperv.c b/arch/x86/kernel/cpu/mshyperv.c index a450373..939155f 100644 --- a/arch/x86/kernel/cpu/mshyperv.c +++ b/arch/x86/kernel/cpu/mshyperv.c @@ -107,6 +107,7 @@ static struct clocksource hyperv_cs = { .rating = 400, /* use this when running on Hyperv*/ .read = read_hv_clock, .mask = CLOCKSOURCE_MASK(64), + .flags = CLOCK_SOURCE_IS_CONTINUOUS, }; static void __init ms_hyperv_init_platform(void) -- 1.7.4.1 -- To unsubscribe from this list: send the line "unsubscribe linux-kernel" in the body of a message to majord...@vger.kernel.org More majordomo info at http://vger.kernel.org/majordomo-info.html Please read the FAQ at http://www.tux.org/lkml/ ___ devel mailing list de...@linuxdriverproject.org http://driverdev.linuxdriverproject.org/mailman/listinfo/driverdev-devel