# This is a BitKeeper generated diff -Nru style patch. # # ChangeSet # 2004/02/28 07:58:28-08:00 viro@parcelfarce.linux.theplanet.co.uk # [PATCH] oops on HPFS filesystem file rename # # Maurice van der Stee noted that he got an oops on a HPFS filesystem when # saving an edited file.. # # # # # # # # This fixes it. That, BTW, means that *nobody* had ever tried to use # hpfs r/w since 2.5.3-pre3. # # fs/hpfs/buffer.c # 2004/02/27 22:33:29-08:00 viro@parcelfarce.linux.theplanet.co.uk +14 -42 # oops on HPFS filesystem file rename # # ChangeSet # 2004/02/28 07:54:20-08:00 bunk@fs.tum.de # [PATCH] move rme96xx to Documentation/sound/oss/ # # From Hans Ulrich Niedermann # # All sound documentation with the exception of the OSS rme96xx # documentation is under Documentation/sound/{alsa,oss}. # # Move the rme966xx docs, and fix the Kconfig comments # # sound/oss/Kconfig # 2004/01/13 12:23:01-08:00 bunk@fs.tum.de +1 -1 # move rme96xx to Documentation/sound/oss/ # # Documentation/sound/oss/rme96xx # 2004/02/28 07:50:54-08:00 torvalds@ppc970.osdl.org +0 -0 # Rename: Documentation/sound/rme96xx -> Documentation/sound/oss/rme96xx # # ChangeSet # 2004/02/28 07:50:29-08:00 phil.el@wanadoo.fr # [PATCH] oprofile needs smp_num_siblings on x86-64 # # P4 oprofile needs cpu_sibling_map and smp_num_siblings, the later # was not exported # # arch/x86_64/kernel/x8664_ksyms.c # 2004/02/27 22:10:55-08:00 phil.el@wanadoo.fr +1 -0 # oprofile needs smp_num_siblings on x86-64 # # ChangeSet # 2004/02/28 07:48:48-08:00 olof@austin.ibm.com # [PATCH] ppc64: Use iommu=force instead of iommu=on for commonality with x86_64 # # arch/ppc64/kernel/prom.c # 2004/02/28 00:27:02-08:00 olof@austin.ibm.com +1 -1 # ppc64: Use iommu=force instead of iommu=on for commonality with x86_64 # # ChangeSet # 2004/02/28 02:02:53-08:00 davidm@tiger.hpl.hp.com # ia64: Fix pdflush-triggered stack-overflow due to long thread-creation chains. # # The pdflush kernel threads can lead to an unbounded chain of thread-creations # which can overflow the kernel stacks because we didn't uses to reset # the stack on kernel thread-creation. We do now. # # Reported by Andreas Schwab, tracked down with help from Keith Owens. # # arch/ia64/kernel/process.c # 2004/02/28 02:02:47-08:00 davidm@tiger.hpl.hp.com +49 -37 # (copy_thread): Reset the stack to the beginning. This prevents stack- # overflows for poorly written kernel threads which cause an # (unbounded) chain of thread creations as is currentl the case # for the pdflush threads. # (kernel_thread): Directly setup a call to do_fork(), bypassing the system- # call and simultaneously resetting the stack to the beginning. # (kernel_thread_helper): New function. # # arch/ia64/kernel/head.S # 2004/02/28 02:02:47-08:00 davidm@tiger.hpl.hp.com +13 -0 # (ia64_invoke_kernel_thread_helper): New routine. # # ChangeSet # 2004/02/27 21:45:51-08:00 peterc@gelato.unsw.edu.au # [PATCH] ia64: greatly speed-up I/O-SAPIC irq_enable()/irq_disable() # # This patch changes the I/O SAPIC code to cache the low 32 bits of the mask # word in kernel memory. This greatly speeds up mask_irq() and unmask_irq(). # # Normally, these operations are not on the speed-critical path of the # kernel but with certain devices drivers (including users-level device- # drivers) they can become performance-critical. # # include/asm-ia64/iosapic.h # 2004/02/27 03:39:17-08:00 peterc@gelato.unsw.edu.au +2 -2 # ia64: greatly speed-up I/O-SAPIC irq_enable()/irq_disable() # # arch/ia64/kernel/iosapic.c # 2004/02/27 03:39:48-08:00 peterc@gelato.unsw.edu.au +8 -8 # ia64: greatly speed-up I/O-SAPIC irq_enable()/irq_disable() # # ChangeSet # 2004/02/27 21:39:54-08:00 eranian@hpl.hp.com # [PATCH] ia64: perfmon update # # - fix bug in pfm_unload(), not allowed when not on correct CPU for # system-wide # - some perf/cleanup in overflow handler # - fix reset_pmds to be on a per PMD basis on counter overflow rather # than global # - remove timing debug code on messages # - no kernel info leak on PFM_END_MSG # - remove double-store on reg_flags for pfm_write_pmcs, pfm_write_pmds # - on restart reset_pmds is 0 by default # - cleanup useless macros # - cleanup some debug prints # - added ability to remove debug code # - streamlined sys_perfmonctl(), pfm_read_pmds(), pfm_write_*() # - added current->tgid to default format sample header by using one # reserved field # # include/asm-ia64/perfmon_default_smpl.h # 2004/02/26 09:25:52-08:00 eranian@hpl.hp.com +2 -2 # ia64: perfmon update # # arch/ia64/kernel/perfmon_default_smpl.c # 2004/02/26 09:26:27-08:00 eranian@hpl.hp.com +1 -0 # ia64: perfmon update # # arch/ia64/kernel/perfmon.c # 2004/02/27 08:40:40-08:00 eranian@hpl.hp.com +180 -177 # ia64: perfmon update # # ChangeSet # 2004/02/27 21:17:14-08:00 davidm@tiger.hpl.hp.com # ia64: Fix IDE block-layer BUG_ON() reported by Darren Williams. # # The problem was that IDE-disks on machines with IDE harddisks, # memory above 4GB and no hardware I/O TLB would go BUG_ON() in # blk_queue_bounce_limit() because the IDE-controller could only # address 4GB of memory and that was much less than BLK_BOUNCE_ISA # (which is equal to ISA_DMA_THRESHOLD). Note that the problem does # NOT trigger with CD-ROMs, which always uses the software I/O TLB # (and hence bounce-buffers) on such machines. # # The best fix seems to be to simply lower ISA_DMA_THRESHOLD to 4GB-1 since # that will ensure that the IDE block layer allocates memory with GFP_DMA, # which will minimize bounce buffering. # # include/asm-ia64/scatterlist.h # 2004/02/27 21:17:07-08:00 davidm@tiger.hpl.hp.com +10 -2 # (ISA_DMA_THRESHOLD): Lower from 0xffffffffffffffff to 0xffffffff so it # matches the max. physical address returned for GFP_DMA allocations # on platforms which don't have a hardware I/O MMU. # # ChangeSet # 2004/02/27 17:23:31-08:00 olof@austin.ibm.com # [PATCH] ppc64: Add iommu=on for enabling DART on small-mem machines # # This makes it possible for people like me with a small-mem G5 to enable # the DART. I see two reasons for wanting to do so: # # 1. To debug/test DART/iommu code itself (small audience, including # myself). # 2. To debug drivers on small-mem machines, since bad pci_map*() usage will # be punished (possibly larger audience). # # arch/ppc64/kernel/prom.c # 2004/02/27 07:48:10-08:00 olof@austin.ibm.com +10 -3 # ppc64: Add iommu=on for enabling DART on small-mem machines # # ChangeSet # 2004/02/27 17:22:53-08:00 torvalds@ppc970.osdl.org # Merge bk://kernel.bkbits.net/gregkh/linux/pci-2.6 # into ppc970.osdl.org:/home/torvalds/v2.5/linux # # drivers/pci/hotplug/rpaphp_core.c # 2004/02/27 17:22:51-08:00 torvalds@ppc970.osdl.org +0 -1 # Auto merged # # drivers/pci/hotplug/rpaphp.h # 2004/02/27 17:22:51-08:00 torvalds@ppc970.osdl.org +0 -1 # Auto merged # # drivers/pci/hotplug/Kconfig # 2004/02/27 17:22:51-08:00 torvalds@ppc970.osdl.org +0 -0 # Auto merged # # ChangeSet # 2004/02/27 17:22:02-08:00 chip@pobox.com # [PATCH] export locks_remove_posix # # kNFSd needs it. # # fs/locks.c # 2004/02/27 16:44:02-08:00 chip@pobox.com +2 -0 # export locks_remove_posix # # ChangeSet # 2004/02/27 17:13:54-08:00 davidm@tiger.hpl.hp.com # Merge tiger.hpl.hp.com:/data1/bk/vanilla/linux-2.5 # into tiger.hpl.hp.com:/data1/bk/lia64/to-linus-2.5 # # arch/ia64/kernel/irq.c # 2004/02/27 17:13:48-08:00 davidm@tiger.hpl.hp.com +0 -0 # Auto merged # # arch/ia64/Kconfig # 2004/02/27 17:13:47-08:00 davidm@tiger.hpl.hp.com +0 -0 # Auto merged # # ChangeSet # 2004/02/27 15:07:27-08:00 kenneth.w.chen@intel.com # [PATCH] ia64: move irq_entry()/irq_exit() to ia64_handle_irq() # # This patch fixes a bug which could cause do_softirq() to be called # at the wrong time (from do_IRQ()) or without pre-emption protection. # # arch/ia64/kernel/irq_ia64.c # 2004/02/26 14:13:14-08:00 kenneth.w.chen@intel.com +2 -2 # ia64: move irq_entry()/irq_exit() to ia64_handle_irq() # # arch/ia64/kernel/irq.c # 2004/02/26 14:13:11-08:00 kenneth.w.chen@intel.com +0 -2 # ia64: move irq_entry()/irq_exit() to ia64_handle_irq() # # ChangeSet # 2004/02/27 22:45:22+00:00 rmk@flint.arm.linux.org.uk # [MTD] Update integrator-flash.c with MTD CVS. # # Allow command line partitioning for use with Integrator flash. # # drivers/mtd/maps/integrator-flash.c # 2004/02/27 22:43:16+00:00 rmk@flint.arm.linux.org.uk +4 -3 # Allow command line partitioning for use with Integrator flash. # Sync with MTD CVS. # # ChangeSet # 2004/02/27 22:14:34+00:00 rmk@flint.arm.linux.org.uk # [MTD] Fix ARM Firmware Suite MTD partition detection. # # Tighten AFS partition checks: # - check footer checksum. # - check that the image name is NUL terminated. # - return error from mtd->read intact. # This prevents us finding bogus AFS partitions. # # drivers/mtd/afs.c # 2004/02/27 22:12:51+00:00 rmk@flint.arm.linux.org.uk +45 -5 # Tighten AFS partition checks: # - check footer checksum. # - check that the image name is NUL terminated. # - return error from mtd->read intact. # This prevents us finding bogus AFS partitions. # # ChangeSet # 2004/02/27 21:52:15+00:00 rmk@flint.arm.linux.org.uk # [ARM] Fix SA1111 OHCI IRQ handler return type. # # drivers/usb/host/ohci-sa1111.c # 2004/02/27 21:50:27+00:00 rmk@flint.arm.linux.org.uk +2 -2 # IRQ handlers return irqreturn_t. # # ChangeSet # 2004/02/27 21:18:15+00:00 rmk@flint.arm.linux.org.uk # [MTD] Fix build errors in Lubbock MTD map driver. # # drivers/mtd/maps/lubbock-flash.c # 2004/02/27 21:11:47+00:00 rmk@flint.arm.linux.org.uk +3 -3 # Fix build errors: # lubbock-flash.c: In function `init_lubbock': # lubbock-flash.c:77: error: too few arguments to function `__ioremap' # lubbock-flash.c:101: warning: ISO C90 forbids mixed declarations and code # # ChangeSet # 2004/02/27 10:41:00-08:00 kenneth.w.chen@intel.com # [PATCH] ia64: make hugetlbfs page size a boot-time option # # This patch makes it possible to select the hugetlbfs page size at boot-time, # rather than at compile-time. We believe we have resolved all the remaining # issues. All critical speed path has been taken care of, i.e., vhpt handler # and context switch. There should be no performance penalty with this dynamic # hugetlb page size feature. # # We would like to thank Jack Steiner for his initiative on this feature # and his initial cool working patch. # # include/asm-ia64/page.h # 2004/02/26 12:18:51-08:00 kenneth.w.chen@intel.com +8 -24 # ia64: make hugetlbfs page size a boot-time option # # include/asm-ia64/mmu_context.h # 2004/02/26 12:18:51-08:00 kenneth.w.chen@intel.com +3 -2 # ia64: make hugetlbfs page size a boot-time option # # arch/ia64/mm/init.c # 2004/02/26 12:18:51-08:00 kenneth.w.chen@intel.com +4 -0 # ia64: make hugetlbfs page size a boot-time option # # arch/ia64/mm/hugetlbpage.c # 2004/02/26 12:18:51-08:00 kenneth.w.chen@intel.com +37 -5 # ia64: make hugetlbfs page size a boot-time option # # arch/ia64/kernel/ivt.S # 2004/02/26 12:18:51-08:00 kenneth.w.chen@intel.com +3 -2 # ia64: make hugetlbfs page size a boot-time option # # arch/ia64/Kconfig # 2004/02/26 12:18:51-08:00 kenneth.w.chen@intel.com +0 -33 # ia64: make hugetlbfs page size a boot-time option # # ChangeSet # 2004/02/24 14:04:40-08:00 greg@kroah.com # PCI Hotplug: clean up the Makefile a bit more. # # Still need to fix up the pcie and shpc options to be saner for distros to use. # # drivers/pci/hotplug/Makefile # 2004/02/24 06:04:19-08:00 greg@kroah.com +8 -10 # PCI Hotplug: clean up the Makefile a bit more. # # Still need to fix up the pcie and shpc options to be saner for distros to use. # # ChangeSet # 2004/02/24 14:02:08-08:00 greg@kroah.com # PCI Hotplug: remove unneeded ACPI Makefile rules. # # drivers/pci/hotplug/Makefile # 2004/02/24 06:01:25-08:00 greg@kroah.com +5 -14 # PCI Hotplug: remove unneeded ACPI Makefile rules. # # ChangeSet # 2004/02/24 11:08:29-08:00 dlsy@snoqualmie.dp.intel.com # [PATCH] PCI Hotplug: Patch to get polling mode in SHPC hot-plug driver properly working # # Here is the patch to get polling mode in SHPC hot-plug properly # working. # # drivers/pci/hotplug/shpchp_hpc.c # 2004/02/23 14:45:31-08:00 dlsy@snoqualmie.dp.intel.com +29 -20 # PCI Hotplug: Patch to get polling mode in SHPC hot-plug driver properly working # # drivers/pci/hotplug/shpchp_ctrl.c # 2004/02/23 14:45:31-08:00 dlsy@snoqualmie.dp.intel.com +2 -0 # PCI Hotplug: Patch to get polling mode in SHPC hot-plug driver properly working # # drivers/pci/hotplug/shpchp.h # 2004/02/23 14:53:13-08:00 dlsy@snoqualmie.dp.intel.com +2 -2 # PCI Hotplug: Patch to get polling mode in SHPC hot-plug driver properly working # # drivers/pci/hotplug/pciehp_ctrl.c # 2004/02/23 14:45:31-08:00 dlsy@snoqualmie.dp.intel.com +2 -0 # PCI Hotplug: Patch to get polling mode in SHPC hot-plug driver properly working # # ChangeSet # 2004/02/24 11:08:13-08:00 lxiep@ltcfwd.linux.ibm.com # [PATCH] PCI Hotplug: fix rpaphp bugs # # The attached patch has a fix for the conflict between fakephp and # rpaphp so that fakephp and rpaphp can't be built into the kernel at the # same time and a couple of problems I missed in my previous patch. # (Sorry about that). # # drivers/pci/hotplug/rpaphp_core.c # 2004/02/20 04:16:33-08:00 lxiep@ltcfwd.linux.ibm.com +1 -3 # PCI Hotplug: fix rpaphp bugs # # drivers/pci/hotplug/rpaphp.h # 2004/02/20 04:16:33-08:00 lxiep@ltcfwd.linux.ibm.com +1 -1 # PCI Hotplug: fix rpaphp bugs # # drivers/pci/hotplug/Kconfig # 2004/02/20 04:16:33-08:00 lxiep@ltcfwd.linux.ibm.com +1 -1 # PCI Hotplug: fix rpaphp bugs # # ChangeSet # 2004/02/24 11:07:59-08:00 rmk-pci@arm.linux.org.uk # [PATCH] PCI: Introduce bus->bridge_ctl member # # GregKH mentioned confirmed that people have been waiting for this patch. # Appologies, it had completely evaporated from my mind. # # This patch introduces the "bridge_ctl" member of pci_bus, which allows # architectures to tweak the bridge control register (eg, for setting # fast back to back modes etc) in pcibios_fixup_bus(). # # Please note, though, that the value is only written back if # pci_setup_bridge() is called. This will be called if an architecture # is using the generic PCI bus setup functionality in setup-bus.c. # If an architecture doesn't, then it is the responsibility of the # architecture to write this value to the bridge as appropriate. # # (That said, the bridge control register is only ever changed if an # architecture is using setup-bus.c anyway, so there should be no # overall functional change.) # # include/linux/pci.h # 2004/02/18 15:41:55-08:00 rmk-pci@arm.linux.org.uk +2 -0 # PCI: Introduce bus->bridge_ctl member # # drivers/pci/setup-bus.c # 2003/11/24 02:33:06-08:00 rmk-pci@arm.linux.org.uk +10 -12 # PCI: Introduce bus->bridge_ctl member # # drivers/pci/probe.c # 2004/02/18 14:41:09-08:00 rmk-pci@arm.linux.org.uk +4 -0 # PCI: Introduce bus->bridge_ctl member # # ChangeSet # 2004/02/24 11:07:43-08:00 rmk-pci@arm.linux.org.uk # [PATCH] PCI: Don't report pci_request_regions() failure twice # # pci_request_regions() reports an error when pci_request_region() fails. # However, since pci_request_region() already reports an error on failure, # pci_request_regions() has some unwanted duplication. # # drivers/pci/pci.c # 2004/02/20 12:00:29-08:00 rmk-pci@arm.linux.org.uk +0 -5 # PCI: Don't report pci_request_regions() failure twice # # ChangeSet # 2004/02/24 11:07:29-08:00 rmk-pci@arm.linux.org.uk # [PATCH] PCI: Report meaningful error for failed resource allocation # # pci_assign_resource reports odd messages when resource allocation fails. # This is because res->end and res->start are modified by allocate_resource. # For example: # # PCI: Failed to allocate resource 1(0-ffffffff) for 0000:00:01.0 # # The following patch reports whether it's an IO or memory resource, and # includes the correct size. For consistency, we report it in a similar # way to the failure message in pci_request_region(), even though # res->start is unlikely to be useful. # # drivers/pci/setup-res.c # 2004/02/20 11:58:19-08:00 rmk-pci@arm.linux.org.uk +3 -2 # PCI: Report meaningful error for failed resource allocation # diff -Nru a/Documentation/sound/oss/rme96xx b/Documentation/sound/oss/rme96xx --- /dev/null Wed Dec 31 16:00:00 1969 +++ b/Documentation/sound/oss/rme96xx Sun Feb 29 12:54:28 2004 @@ -0,0 +1,767 @@ +Beta release of the rme96xx (driver for RME 96XX cards like the +"Hammerfall" and the "Hammerfall light") + +Important: The driver module has to be installed on a freshly rebooted system, +otherwise the driver might not be able to acquire its buffers. + +features: + + - OSS programming interface (i.e. runs with standard OSS soundsoftware) + - OSS/Multichannel interface (OSS multichannel is done by just aquiring + more than 2 channels). The driver does not use more than one device + ( yet .. this feature may be implemented later ) + - more than one RME card supported + +The driver uses a specific multichannel interface, which I will document +when the driver gets stable. (take a look at the defines in rme96xx.h, +which adds blocked multichannel formats i.e instead of +lrlrlrlr --> llllrrrr etc. + +Use the "rmectrl" programm to look at the status of the card .. +or use xrmectrl, a GUI interface for the ctrl program. + +What you can do with the rmectrl program is to set the stereo device for +OSS emulation (e.g. if you use SPDIF out). + +You do: + +./ctrl offset 24 24 + +which makes the stereo device use channels 25 and 26. + +Guenter Geiger + +copy the first part of the attached source code into rmectrl.c +and the second part into xrmectrl (or get the program from +http://gige.xdv.org/pages/soft/pages/rme) + +to compile: gcc -o rmectrl rmectrl.c +------------------------------ snip ------------------------------------ + +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include "rme96xx.h" + +/* + remctrl.c + (C) 2000 Guenter Geiger + HP20020201 - Heiko Purnhagen +*/ + +/* # define DEVICE_NAME "/dev/mixer" */ +# define DEVICE_NAME "/dev/mixer1" + + +void usage(void) +{ + fprintf(stderr,"usage: rmectrl [/dev/mixer] [command [options]]\n\n"); + fprintf(stderr,"where command is one of:\n"); + fprintf(stderr," help show this help\n"); + fprintf(stderr," status show status bits\n"); + fprintf(stderr," control show control bits\n"); + fprintf(stderr," mix show mixer/offset status\n"); + fprintf(stderr," master set sync master\n"); + fprintf(stderr," pro set spdif out pro\n"); + fprintf(stderr," emphasis set spdif out emphasis\n"); + fprintf(stderr," dolby set spdif out no audio\n"); + fprintf(stderr," optout set spdif out optical\n"); + fprintf(stderr," wordclock set sync wordclock\n"); + fprintf(stderr," spdifin set spdif in (0=optical,1=coax,2=intern)\n"); + fprintf(stderr," syncref set sync source (0=ADAT1,1=ADAT2,2=ADAT3,3=SPDIF)\n"); + fprintf(stderr," adat1cd set ADAT1 on internal CD\n"); + fprintf(stderr," offset set dev (0..3) offset (0..25)\n"); + exit(-1); +} + + +int main(int argc, char* argv[]) +{ + int cards; + int ret; + int i; + double ft; + int fd, fdwr; + int param,orig; + rme_status_t stat; + rme_ctrl_t ctrl; + char *device; + int argidx; + + if (argc < 2) + usage(); + + if (*argv[1]=='/') { + device = argv[1]; + argidx = 2; + } + else { + device = DEVICE_NAME; + argidx = 1; + } + + fprintf(stdout,"mixer device %s\n",device); + if ((fd = open(device,O_RDONLY)) < 0) { + fprintf(stdout,"opening device failed\n"); + exit(-1); + } + + if ((fdwr = open(device,O_WRONLY)) < 0) { + fprintf(stdout,"opening device failed\n"); + exit(-1); + } + + if (argc < argidx+1) + usage(); + + if (!strcmp(argv[argidx],"help")) + usage(); + if (!strcmp(argv[argidx],"-h")) + usage(); + if (!strcmp(argv[argidx],"--help")) + usage(); + + if (!strcmp(argv[argidx],"status")) { + ioctl(fd,SOUND_MIXER_PRIVATE2,&stat); + fprintf(stdout,"stat.irq %d\n",stat.irq); + fprintf(stdout,"stat.lockmask %d\n",stat.lockmask); + fprintf(stdout,"stat.sr48 %d\n",stat.sr48); + fprintf(stdout,"stat.wclock %d\n",stat.wclock); + fprintf(stdout,"stat.bufpoint %d\n",stat.bufpoint); + fprintf(stdout,"stat.syncmask %d\n",stat.syncmask); + fprintf(stdout,"stat.doublespeed %d\n",stat.doublespeed); + fprintf(stdout,"stat.tc_busy %d\n",stat.tc_busy); + fprintf(stdout,"stat.tc_out %d\n",stat.tc_out); + fprintf(stdout,"stat.crystalrate %d (0=64k 3=96k 4=88.2k 5=48k 6=44.1k 7=32k)\n",stat.crystalrate); + fprintf(stdout,"stat.spdif_error %d\n",stat.spdif_error); + fprintf(stdout,"stat.bufid %d\n",stat.bufid); + fprintf(stdout,"stat.tc_valid %d\n",stat.tc_valid); + exit (0); + } + + if (!strcmp(argv[argidx],"control")) { + ioctl(fd,SOUND_MIXER_PRIVATE3,&ctrl); + fprintf(stdout,"ctrl.start %d\n",ctrl.start); + fprintf(stdout,"ctrl.latency %d (0=64 .. 7=8192)\n",ctrl.latency); + fprintf(stdout,"ctrl.master %d\n",ctrl.master); + fprintf(stdout,"ctrl.ie %d\n",ctrl.ie); + fprintf(stdout,"ctrl.sr48 %d\n",ctrl.sr48); + fprintf(stdout,"ctrl.spare %d\n",ctrl.spare); + fprintf(stdout,"ctrl.doublespeed %d\n",ctrl.doublespeed); + fprintf(stdout,"ctrl.pro %d\n",ctrl.pro); + fprintf(stdout,"ctrl.emphasis %d\n",ctrl.emphasis); + fprintf(stdout,"ctrl.dolby %d\n",ctrl.dolby); + fprintf(stdout,"ctrl.opt_out %d\n",ctrl.opt_out); + fprintf(stdout,"ctrl.wordclock %d\n",ctrl.wordclock); + fprintf(stdout,"ctrl.spdif_in %d (0=optical,1=coax,2=intern)\n",ctrl.spdif_in); + fprintf(stdout,"ctrl.sync_ref %d (0=ADAT1,1=ADAT2,2=ADAT3,3=SPDIF)\n",ctrl.sync_ref); + fprintf(stdout,"ctrl.spdif_reset %d\n",ctrl.spdif_reset); + fprintf(stdout,"ctrl.spdif_select %d\n",ctrl.spdif_select); + fprintf(stdout,"ctrl.spdif_clock %d\n",ctrl.spdif_clock); + fprintf(stdout,"ctrl.spdif_write %d\n",ctrl.spdif_write); + fprintf(stdout,"ctrl.adat1_cd %d\n",ctrl.adat1_cd); + exit (0); + } + + if (!strcmp(argv[argidx],"mix")) { + rme_mixer mix; + int i; + + for (i=0; i<4; i++) { + mix.devnr = i; + ioctl(fd,SOUND_MIXER_PRIVATE1,&mix); + if (mix.devnr == i) { + fprintf(stdout,"devnr %d\n",mix.devnr); + fprintf(stdout,"mix.i_offset %2d (0-25)\n",mix.i_offset); + fprintf(stdout,"mix.o_offset %2d (0-25)\n",mix.o_offset); + } + } + exit (0); + } + +/* the control flags */ + + if (argc < argidx+2) + usage(); + + if (!strcmp(argv[argidx],"master")) { + int val = atoi(argv[argidx+1]); + ioctl(fd,SOUND_MIXER_PRIVATE3,&ctrl); + printf("master = %d\n",val); + ctrl.master = val; + ioctl(fdwr,SOUND_MIXER_PRIVATE3,&ctrl); + exit (0); + } + + if (!strcmp(argv[argidx],"pro")) { + int val = atoi(argv[argidx+1]); + ioctl(fd,SOUND_MIXER_PRIVATE3,&ctrl); + printf("pro = %d\n",val); + ctrl.pro = val; + ioctl(fdwr,SOUND_MIXER_PRIVATE3,&ctrl); + exit (0); + } + + if (!strcmp(argv[argidx],"emphasis")) { + int val = atoi(argv[argidx+1]); + ioctl(fd,SOUND_MIXER_PRIVATE3,&ctrl); + printf("emphasis = %d\n",val); + ctrl.emphasis = val; + ioctl(fdwr,SOUND_MIXER_PRIVATE3,&ctrl); + exit (0); + } + + if (!strcmp(argv[argidx],"dolby")) { + int val = atoi(argv[argidx+1]); + ioctl(fd,SOUND_MIXER_PRIVATE3,&ctrl); + printf("dolby = %d\n",val); + ctrl.dolby = val; + ioctl(fdwr,SOUND_MIXER_PRIVATE3,&ctrl); + exit (0); + } + + if (!strcmp(argv[argidx],"optout")) { + int val = atoi(argv[argidx+1]); + ioctl(fd,SOUND_MIXER_PRIVATE3,&ctrl); + printf("optout = %d\n",val); + ctrl.opt_out = val; + ioctl(fdwr,SOUND_MIXER_PRIVATE3,&ctrl); + exit (0); + } + + if (!strcmp(argv[argidx],"wordclock")) { + int val = atoi(argv[argidx+1]); + ioctl(fd,SOUND_MIXER_PRIVATE3,&ctrl); + printf("wordclock = %d\n",val); + ctrl.wordclock = val; + ioctl(fdwr,SOUND_MIXER_PRIVATE3,&ctrl); + exit (0); + } + + if (!strcmp(argv[argidx],"spdifin")) { + int val = atoi(argv[argidx+1]); + ioctl(fd,SOUND_MIXER_PRIVATE3,&ctrl); + printf("spdifin = %d\n",val); + ctrl.spdif_in = val; + ioctl(fdwr,SOUND_MIXER_PRIVATE3,&ctrl); + exit (0); + } + + if (!strcmp(argv[argidx],"syncref")) { + int val = atoi(argv[argidx+1]); + ioctl(fd,SOUND_MIXER_PRIVATE3,&ctrl); + printf("syncref = %d\n",val); + ctrl.sync_ref = val; + ioctl(fdwr,SOUND_MIXER_PRIVATE3,&ctrl); + exit (0); + } + + if (!strcmp(argv[argidx],"adat1cd")) { + int val = atoi(argv[argidx+1]); + ioctl(fd,SOUND_MIXER_PRIVATE3,&ctrl); + printf("adat1cd = %d\n",val); + ctrl.adat1_cd = val; + ioctl(fdwr,SOUND_MIXER_PRIVATE3,&ctrl); + exit (0); + } + +/* setting offset */ + + if (argc < argidx+4) + usage(); + + if (!strcmp(argv[argidx],"offset")) { + rme_mixer mix; + + mix.devnr = atoi(argv[argidx+1]); + + mix.i_offset = atoi(argv[argidx+2]); + mix.o_offset = atoi(argv[argidx+3]); + ioctl(fdwr,SOUND_MIXER_PRIVATE1,&mix); + fprintf(stdout,"devnr %d\n",mix.devnr); + fprintf(stdout,"mix.i_offset to %d\n",mix.i_offset); + fprintf(stdout,"mix.o_offset to %d\n",mix.o_offset); + exit (0); + } + + usage(); + exit (0); /* to avoid warning */ +} + + +---------------------------- -------------------------------- +#!/usr/bin/wish + +# xrmectrl +# (C) 2000 Guenter Geiger +# HP20020201 - Heiko Purnhagen + +#set defaults "-relief ridged" +set CTRLPROG "./rmectrl" +if {$argc} { + set CTRLPROG "$CTRLPROG $argv" +} +puts "CTRLPROG $CTRLPROG" + +frame .butts +button .butts.exit -text "Exit" -command "exit" -relief ridge +#button .butts.state -text "State" -command "get_all" + +pack .butts.exit -side left +pack .butts -side bottom + + +# +# STATUS +# + +frame .status + +# Sampling Rate + +frame .status.sr +label .status.sr.text -text "Sampling Rate" -justify left +radiobutton .status.sr.441 -selectcolor red -text "44.1 kHz" -width 10 -anchor nw -variable srate -value 44100 -font times +radiobutton .status.sr.480 -selectcolor red -text "48 kHz" -width 10 -anchor nw -variable srate -value 48000 -font times +radiobutton .status.sr.882 -selectcolor red -text "88.2 kHz" -width 10 -anchor nw -variable srate -value 88200 -font times +radiobutton .status.sr.960 -selectcolor red -text "96 kHz" -width 10 -anchor nw -variable srate -value 96000 -font times + +pack .status.sr.text .status.sr.441 .status.sr.480 .status.sr.882 .status.sr.960 -side top -padx 3 + +# Lock + +frame .status.lock +label .status.lock.text -text "Lock" -justify left +checkbutton .status.lock.adat1 -selectcolor red -text "ADAT1" -anchor nw -width 10 -variable adatlock1 -font times +checkbutton .status.lock.adat2 -selectcolor red -text "ADAT2" -anchor nw -width 10 -variable adatlock2 -font times +checkbutton .status.lock.adat3 -selectcolor red -text "ADAT3" -anchor nw -width 10 -variable adatlock3 -font times + +pack .status.lock.text .status.lock.adat1 .status.lock.adat2 .status.lock.adat3 -side top -padx 3 + +# Sync + +frame .status.sync +label .status.sync.text -text "Sync" -justify left +checkbutton .status.sync.adat1 -selectcolor red -text "ADAT1" -anchor nw -width 10 -variable adatsync1 -font times +checkbutton .status.sync.adat2 -selectcolor red -text "ADAT2" -anchor nw -width 10 -variable adatsync2 -font times +checkbutton .status.sync.adat3 -selectcolor red -text "ADAT3" -anchor nw -width 10 -variable adatsync3 -font times + +pack .status.sync.text .status.sync.adat1 .status.sync.adat2 .status.sync.adat3 -side top -padx 3 + +# Timecode + +frame .status.tc +label .status.tc.text -text "Timecode" -justify left +checkbutton .status.tc.busy -selectcolor red -text "busy" -anchor nw -width 10 -variable tcbusy -font times +checkbutton .status.tc.out -selectcolor red -text "out" -anchor nw -width 10 -variable tcout -font times +checkbutton .status.tc.valid -selectcolor red -text "valid" -anchor nw -width 10 -variable tcvalid -font times + +pack .status.tc.text .status.tc.busy .status.tc.out .status.tc.valid -side top -padx 3 + +# SPDIF In + +frame .status.spdif +label .status.spdif.text -text "SPDIF In" -justify left +label .status.spdif.sr -text "--.- kHz" -anchor n -width 10 -font times +checkbutton .status.spdif.error -selectcolor red -text "Input Lock" -anchor nw -width 10 -variable spdiferr -font times + +pack .status.spdif.text .status.spdif.sr .status.spdif.error -side top -padx 3 + +pack .status.sr .status.lock .status.sync .status.tc .status.spdif -side left -fill x -anchor n -expand 1 + + +# +# CONTROL +# + +proc setprof {} { + global CTRLPROG + global spprof + exec $CTRLPROG pro $spprof +} + +proc setemph {} { + global CTRLPROG + global spemph + exec $CTRLPROG emphasis $spemph +} + +proc setnoaud {} { + global CTRLPROG + global spnoaud + exec $CTRLPROG dolby $spnoaud +} + +proc setoptical {} { + global CTRLPROG + global spoptical + exec $CTRLPROG optout $spoptical +} + +proc setspdifin {} { + global CTRLPROG + global spdifin + exec $CTRLPROG spdifin [expr $spdifin - 1] +} + +proc setsyncsource {} { + global CTRLPROG + global syncsource + exec $CTRLPROG syncref [expr $syncsource -1] +} + + +proc setmaster {} { + global CTRLPROG + global master + exec $CTRLPROG master $master +} + +proc setwordclock {} { + global CTRLPROG + global wordclock + exec $CTRLPROG wordclock $wordclock +} + +proc setadat1cd {} { + global CTRLPROG + global adat1cd + exec $CTRLPROG adat1cd $adat1cd +} + + +frame .control + +# SPDIF In & SPDIF Out + + +frame .control.spdif + +frame .control.spdif.in +label .control.spdif.in.text -text "SPDIF In" -justify left +radiobutton .control.spdif.in.input1 -text "Optical" -anchor nw -width 13 -variable spdifin -value 1 -command setspdifin -selectcolor blue -font times +radiobutton .control.spdif.in.input2 -text "Coaxial" -anchor nw -width 13 -variable spdifin -value 2 -command setspdifin -selectcolor blue -font times +radiobutton .control.spdif.in.input3 -text "Intern " -anchor nw -width 13 -variable spdifin -command setspdifin -value 3 -selectcolor blue -font times + +checkbutton .control.spdif.in.adat1cd -text "ADAT1 Intern" -anchor nw -width 13 -variable adat1cd -command setadat1cd -selectcolor blue -font times + +pack .control.spdif.in.text .control.spdif.in.input1 .control.spdif.in.input2 .control.spdif.in.input3 .control.spdif.in.adat1cd + +label .control.spdif.space + +frame .control.spdif.out +label .control.spdif.out.text -text "SPDIF Out" -justify left +checkbutton .control.spdif.out.pro -text "Professional" -anchor nw -width 13 -variable spprof -command setprof -selectcolor blue -font times +checkbutton .control.spdif.out.emphasis -text "Emphasis" -anchor nw -width 13 -variable spemph -command setemph -selectcolor blue -font times +checkbutton .control.spdif.out.dolby -text "NoAudio" -anchor nw -width 13 -variable spnoaud -command setnoaud -selectcolor blue -font times +checkbutton .control.spdif.out.optout -text "Optical Out" -anchor nw -width 13 -variable spoptical -command setoptical -selectcolor blue -font times + +pack .control.spdif.out.optout .control.spdif.out.dolby .control.spdif.out.emphasis .control.spdif.out.pro .control.spdif.out.text -side bottom + +pack .control.spdif.in .control.spdif.space .control.spdif.out -side top -fill y -padx 3 -expand 1 + +# Sync Mode & Sync Source + +frame .control.sync +frame .control.sync.mode +label .control.sync.mode.text -text "Sync Mode" -justify left +checkbutton .control.sync.mode.master -text "Master" -anchor nw -width 13 -variable master -command setmaster -selectcolor blue -font times +checkbutton .control.sync.mode.wc -text "Wordclock" -anchor nw -width 13 -variable wordclock -command setwordclock -selectcolor blue -font times + +pack .control.sync.mode.text .control.sync.mode.master .control.sync.mode.wc + +label .control.sync.space + +frame .control.sync.src +label .control.sync.src.text -text "Sync Source" -justify left +radiobutton .control.sync.src.input1 -text "ADAT1" -anchor nw -width 13 -variable syncsource -value 1 -command setsyncsource -selectcolor blue -font times +radiobutton .control.sync.src.input2 -text "ADAT2" -anchor nw -width 13 -variable syncsource -value 2 -command setsyncsource -selectcolor blue -font times +radiobutton .control.sync.src.input3 -text "ADAT3" -anchor nw -width 13 -variable syncsource -command setsyncsource -value 3 -selectcolor blue -font times +radiobutton .control.sync.src.input4 -text "SPDIF" -anchor nw -width 13 -variable syncsource -command setsyncsource -value 4 -selectcolor blue -font times + +pack .control.sync.src.input4 .control.sync.src.input3 .control.sync.src.input2 .control.sync.src.input1 .control.sync.src.text -side bottom + +pack .control.sync.mode .control.sync.space .control.sync.src -side top -fill y -padx 3 -expand 1 + +label .control.space -text "" -width 10 + +# Buffer Size + +frame .control.buf +label .control.buf.text -text "Buffer Size (Latency)" -justify left +radiobutton .control.buf.b1 -selectcolor red -text "64 (1.5 ms)" -width 13 -anchor nw -variable ssrate -value 1 -font times +radiobutton .control.buf.b2 -selectcolor red -text "128 (3 ms)" -width 13 -anchor nw -variable ssrate -value 2 -font times +radiobutton .control.buf.b3 -selectcolor red -text "256 (6 ms)" -width 13 -anchor nw -variable ssrate -value 3 -font times +radiobutton .control.buf.b4 -selectcolor red -text "512 (12 ms)" -width 13 -anchor nw -variable ssrate -value 4 -font times +radiobutton .control.buf.b5 -selectcolor red -text "1024 (23 ms)" -width 13 -anchor nw -variable ssrate -value 5 -font times +radiobutton .control.buf.b6 -selectcolor red -text "2048 (46 ms)" -width 13 -anchor nw -variable ssrate -value 6 -font times +radiobutton .control.buf.b7 -selectcolor red -text "4096 (93 ms)" -width 13 -anchor nw -variable ssrate -value 7 -font times +radiobutton .control.buf.b8 -selectcolor red -text "8192 (186 ms)" -width 13 -anchor nw -variable ssrate -value 8 -font times + +pack .control.buf.text .control.buf.b1 .control.buf.b2 .control.buf.b3 .control.buf.b4 .control.buf.b5 .control.buf.b6 .control.buf.b7 .control.buf.b8 -side top -padx 3 + +# Offset + +frame .control.offset + +frame .control.offset.in +label .control.offset.in.text -text "Offset In" -justify left +label .control.offset.in.off0 -text "dev\#0: -" -anchor nw -width 10 -font times +label .control.offset.in.off1 -text "dev\#1: -" -anchor nw -width 10 -font times +label .control.offset.in.off2 -text "dev\#2: -" -anchor nw -width 10 -font times +label .control.offset.in.off3 -text "dev\#3: -" -anchor nw -width 10 -font times + +pack .control.offset.in.text .control.offset.in.off0 .control.offset.in.off1 .control.offset.in.off2 .control.offset.in.off3 + +label .control.offset.space + +frame .control.offset.out +label .control.offset.out.text -text "Offset Out" -justify left +label .control.offset.out.off0 -text "dev\#0: -" -anchor nw -width 10 -font times +label .control.offset.out.off1 -text "dev\#1: -" -anchor nw -width 10 -font times +label .control.offset.out.off2 -text "dev\#2: -" -anchor nw -width 10 -font times +label .control.offset.out.off3 -text "dev\#3: -" -anchor nw -width 10 -font times + +pack .control.offset.out.off3 .control.offset.out.off2 .control.offset.out.off1 .control.offset.out.off0 .control.offset.out.text -side bottom + +pack .control.offset.in .control.offset.space .control.offset.out -side top -fill y -padx 3 -expand 1 + + +pack .control.spdif .control.sync .control.space .control.buf .control.offset -side left -fill both -anchor n -expand 1 + + +label .statustext -text Status -justify center -relief ridge +label .controltext -text Control -justify center -relief ridge + +label .statusspace +label .controlspace + +pack .statustext .status .statusspace .controltext .control .controlspace -side top -anchor nw -fill both -expand 1 + + +proc get_bit {output sstr} { + set idx1 [string last [concat $sstr 1] $output] + set idx1 [expr $idx1 != -1] + return $idx1 +} + +proc get_val {output sstr} { + set val [string wordend $output [string last $sstr $output]] + set val [string range $output $val [expr $val+1]] + return $val +} + +proc get_val2 {output sstr} { + set val [string wordend $output [string first $sstr $output]] + set val [string range $output $val [expr $val+2]] + return $val +} + +proc get_control {} { + global spprof + global spemph + global spnoaud + global spoptical + global spdifin + global ssrate + global master + global wordclock + global syncsource + global CTRLPROG + + set f [open "| $CTRLPROG control" r+] + set ooo [read $f 1000] + close $f +# puts $ooo + + set spprof [ get_bit $ooo "pro"] + set spemph [ get_bit $ooo "emphasis"] + set spnoaud [ get_bit $ooo "dolby"] + set spoptical [ get_bit $ooo "opt_out"] + set spdifin [ expr [ get_val $ooo "spdif_in"] + 1] + set ssrate [ expr [ get_val $ooo "latency"] + 1] + set master [ expr [ get_val $ooo "master"]] + set wordclock [ expr [ get_val $ooo "wordclock"]] + set syncsource [ expr [ get_val $ooo "sync_ref"] + 1] +} + +proc get_status {} { + global srate + global ctrlcom + + global adatlock1 + global adatlock2 + global adatlock3 + + global adatsync1 + global adatsync2 + global adatsync3 + + global tcbusy + global tcout + global tcvalid + + global spdiferr + global crystal + global .status.spdif.text + global CTRLPROG + + + set f [open "| $CTRLPROG status" r+] + set ooo [read $f 1000] + close $f +# puts $ooo + +# samplerate + + set idx1 [string last "sr48 1" $ooo] + set idx2 [string last "doublespeed 1" $ooo] + if {$idx1 >= 0} { + set fact1 48000 + } else { + set fact1 44100 + } + + if {$idx2 >= 0} { + set fact2 2 + } else { + set fact2 1 + } + set srate [expr $fact1 * $fact2] +# ADAT lock + + set val [get_val $ooo lockmask] + set adatlock1 0 + set adatlock2 0 + set adatlock3 0 + if {[expr $val & 1]} { + set adatlock3 1 + } + if {[expr $val & 2]} { + set adatlock2 1 + } + if {[expr $val & 4]} { + set adatlock1 1 + } + +# ADAT sync + set val [get_val $ooo syncmask] + set adatsync1 0 + set adatsync2 0 + set adatsync3 0 + + if {[expr $val & 1]} { + set adatsync3 1 + } + if {[expr $val & 2]} { + set adatsync2 1 + } + if {[expr $val & 4]} { + set adatsync1 1 + } + +# TC busy + + set tcbusy [get_bit $ooo "busy"] + set tcout [get_bit $ooo "out"] + set tcvalid [get_bit $ooo "valid"] + set spdiferr [expr [get_bit $ooo "spdif_error"] == 0] + +# 000=64kHz, 100=88.2kHz, 011=96kHz +# 111=32kHz, 110=44.1kHz, 101=48kHz + + set val [get_val $ooo crystalrate] + + set crystal "--.- kHz" + if {$val == 0} { + set crystal "64 kHz" + } + if {$val == 4} { + set crystal "88.2 kHz" + } + if {$val == 3} { + set crystal "96 kHz" + } + if {$val == 7} { + set crystal "32 kHz" + } + if {$val == 6} { + set crystal "44.1 kHz" + } + if {$val == 5} { + set crystal "48 kHz" + } + .status.spdif.sr configure -text $crystal +} + +proc get_offset {} { + global inoffset + global outoffset + global CTRLPROG + + set f [open "| $CTRLPROG mix" r+] + set ooo [read $f 1000] + close $f +# puts $ooo + + if { [string match "*devnr*" $ooo] } { + set ooo [string range $ooo [string wordend $ooo [string first devnr $ooo]] end] + set val [get_val2 $ooo i_offset] + .control.offset.in.off0 configure -text "dev\#0: $val" + set val [get_val2 $ooo o_offset] + .control.offset.out.off0 configure -text "dev\#0: $val" + } else { + .control.offset.in.off0 configure -text "dev\#0: -" + .control.offset.out.off0 configure -text "dev\#0: -" + } + if { [string match "*devnr*" $ooo] } { + set ooo [string range $ooo [string wordend $ooo [string first devnr $ooo]] end] + set val [get_val2 $ooo i_offset] + .control.offset.in.off1 configure -text "dev\#1: $val" + set val [get_val2 $ooo o_offset] + .control.offset.out.off1 configure -text "dev\#1: $val" + } else { + .control.offset.in.off1 configure -text "dev\#1: -" + .control.offset.out.off1 configure -text "dev\#1: -" + } + if { [string match "*devnr*" $ooo] } { + set ooo [string range $ooo [string wordend $ooo [string first devnr $ooo]] end] + set val [get_val2 $ooo i_offset] + .control.offset.in.off2 configure -text "dev\#2: $val" + set val [get_val2 $ooo o_offset] + .control.offset.out.off2 configure -text "dev\#2: $val" + } else { + .control.offset.in.off2 configure -text "dev\#2: -" + .control.offset.out.off2 configure -text "dev\#2: -" + } + if { [string match "*devnr*" $ooo] } { + set ooo [string range $ooo [string wordend $ooo [string first devnr $ooo]] end] + set val [get_val2 $ooo i_offset] + .control.offset.in.off3 configure -text "dev\#3: $val" + set val [get_val2 $ooo o_offset] + .control.offset.out.off3 configure -text "dev\#3: $val" + } else { + .control.offset.in.off3 configure -text "dev\#3: -" + .control.offset.out.off3 configure -text "dev\#3: -" + } +} + + +proc get_all {} { +get_status +get_control +get_offset +} + +# main +while {1} { + after 200 + get_all + update +} diff -Nru a/Documentation/sound/rme96xx b/Documentation/sound/rme96xx --- a/Documentation/sound/rme96xx Sun Feb 29 12:54:28 2004 +++ /dev/null Wed Dec 31 16:00:00 1969 @@ -1,767 +0,0 @@ -Beta release of the rme96xx (driver for RME 96XX cards like the -"Hammerfall" and the "Hammerfall light") - -Important: The driver module has to be installed on a freshly rebooted system, -otherwise the driver might not be able to acquire its buffers. - -features: - - - OSS programming interface (i.e. runs with standard OSS soundsoftware) - - OSS/Multichannel interface (OSS multichannel is done by just aquiring - more than 2 channels). The driver does not use more than one device - ( yet .. this feature may be implemented later ) - - more than one RME card supported - -The driver uses a specific multichannel interface, which I will document -when the driver gets stable. (take a look at the defines in rme96xx.h, -which adds blocked multichannel formats i.e instead of -lrlrlrlr --> llllrrrr etc. - -Use the "rmectrl" programm to look at the status of the card .. -or use xrmectrl, a GUI interface for the ctrl program. - -What you can do with the rmectrl program is to set the stereo device for -OSS emulation (e.g. if you use SPDIF out). - -You do: - -./ctrl offset 24 24 - -which makes the stereo device use channels 25 and 26. - -Guenter Geiger - -copy the first part of the attached source code into rmectrl.c -and the second part into xrmectrl (or get the program from -http://gige.xdv.org/pages/soft/pages/rme) - -to compile: gcc -o rmectrl rmectrl.c ------------------------------- snip ------------------------------------ - -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include "rme96xx.h" - -/* - remctrl.c - (C) 2000 Guenter Geiger - HP20020201 - Heiko Purnhagen -*/ - -/* # define DEVICE_NAME "/dev/mixer" */ -# define DEVICE_NAME "/dev/mixer1" - - -void usage(void) -{ - fprintf(stderr,"usage: rmectrl [/dev/mixer] [command [options]]\n\n"); - fprintf(stderr,"where command is one of:\n"); - fprintf(stderr," help show this help\n"); - fprintf(stderr," status show status bits\n"); - fprintf(stderr," control show control bits\n"); - fprintf(stderr," mix show mixer/offset status\n"); - fprintf(stderr," master set sync master\n"); - fprintf(stderr," pro set spdif out pro\n"); - fprintf(stderr," emphasis set spdif out emphasis\n"); - fprintf(stderr," dolby set spdif out no audio\n"); - fprintf(stderr," optout set spdif out optical\n"); - fprintf(stderr," wordclock set sync wordclock\n"); - fprintf(stderr," spdifin set spdif in (0=optical,1=coax,2=intern)\n"); - fprintf(stderr," syncref set sync source (0=ADAT1,1=ADAT2,2=ADAT3,3=SPDIF)\n"); - fprintf(stderr," adat1cd set ADAT1 on internal CD\n"); - fprintf(stderr," offset set dev (0..3) offset (0..25)\n"); - exit(-1); -} - - -int main(int argc, char* argv[]) -{ - int cards; - int ret; - int i; - double ft; - int fd, fdwr; - int param,orig; - rme_status_t stat; - rme_ctrl_t ctrl; - char *device; - int argidx; - - if (argc < 2) - usage(); - - if (*argv[1]=='/') { - device = argv[1]; - argidx = 2; - } - else { - device = DEVICE_NAME; - argidx = 1; - } - - fprintf(stdout,"mixer device %s\n",device); - if ((fd = open(device,O_RDONLY)) < 0) { - fprintf(stdout,"opening device failed\n"); - exit(-1); - } - - if ((fdwr = open(device,O_WRONLY)) < 0) { - fprintf(stdout,"opening device failed\n"); - exit(-1); - } - - if (argc < argidx+1) - usage(); - - if (!strcmp(argv[argidx],"help")) - usage(); - if (!strcmp(argv[argidx],"-h")) - usage(); - if (!strcmp(argv[argidx],"--help")) - usage(); - - if (!strcmp(argv[argidx],"status")) { - ioctl(fd,SOUND_MIXER_PRIVATE2,&stat); - fprintf(stdout,"stat.irq %d\n",stat.irq); - fprintf(stdout,"stat.lockmask %d\n",stat.lockmask); - fprintf(stdout,"stat.sr48 %d\n",stat.sr48); - fprintf(stdout,"stat.wclock %d\n",stat.wclock); - fprintf(stdout,"stat.bufpoint %d\n",stat.bufpoint); - fprintf(stdout,"stat.syncmask %d\n",stat.syncmask); - fprintf(stdout,"stat.doublespeed %d\n",stat.doublespeed); - fprintf(stdout,"stat.tc_busy %d\n",stat.tc_busy); - fprintf(stdout,"stat.tc_out %d\n",stat.tc_out); - fprintf(stdout,"stat.crystalrate %d (0=64k 3=96k 4=88.2k 5=48k 6=44.1k 7=32k)\n",stat.crystalrate); - fprintf(stdout,"stat.spdif_error %d\n",stat.spdif_error); - fprintf(stdout,"stat.bufid %d\n",stat.bufid); - fprintf(stdout,"stat.tc_valid %d\n",stat.tc_valid); - exit (0); - } - - if (!strcmp(argv[argidx],"control")) { - ioctl(fd,SOUND_MIXER_PRIVATE3,&ctrl); - fprintf(stdout,"ctrl.start %d\n",ctrl.start); - fprintf(stdout,"ctrl.latency %d (0=64 .. 7=8192)\n",ctrl.latency); - fprintf(stdout,"ctrl.master %d\n",ctrl.master); - fprintf(stdout,"ctrl.ie %d\n",ctrl.ie); - fprintf(stdout,"ctrl.sr48 %d\n",ctrl.sr48); - fprintf(stdout,"ctrl.spare %d\n",ctrl.spare); - fprintf(stdout,"ctrl.doublespeed %d\n",ctrl.doublespeed); - fprintf(stdout,"ctrl.pro %d\n",ctrl.pro); - fprintf(stdout,"ctrl.emphasis %d\n",ctrl.emphasis); - fprintf(stdout,"ctrl.dolby %d\n",ctrl.dolby); - fprintf(stdout,"ctrl.opt_out %d\n",ctrl.opt_out); - fprintf(stdout,"ctrl.wordclock %d\n",ctrl.wordclock); - fprintf(stdout,"ctrl.spdif_in %d (0=optical,1=coax,2=intern)\n",ctrl.spdif_in); - fprintf(stdout,"ctrl.sync_ref %d (0=ADAT1,1=ADAT2,2=ADAT3,3=SPDIF)\n",ctrl.sync_ref); - fprintf(stdout,"ctrl.spdif_reset %d\n",ctrl.spdif_reset); - fprintf(stdout,"ctrl.spdif_select %d\n",ctrl.spdif_select); - fprintf(stdout,"ctrl.spdif_clock %d\n",ctrl.spdif_clock); - fprintf(stdout,"ctrl.spdif_write %d\n",ctrl.spdif_write); - fprintf(stdout,"ctrl.adat1_cd %d\n",ctrl.adat1_cd); - exit (0); - } - - if (!strcmp(argv[argidx],"mix")) { - rme_mixer mix; - int i; - - for (i=0; i<4; i++) { - mix.devnr = i; - ioctl(fd,SOUND_MIXER_PRIVATE1,&mix); - if (mix.devnr == i) { - fprintf(stdout,"devnr %d\n",mix.devnr); - fprintf(stdout,"mix.i_offset %2d (0-25)\n",mix.i_offset); - fprintf(stdout,"mix.o_offset %2d (0-25)\n",mix.o_offset); - } - } - exit (0); - } - -/* the control flags */ - - if (argc < argidx+2) - usage(); - - if (!strcmp(argv[argidx],"master")) { - int val = atoi(argv[argidx+1]); - ioctl(fd,SOUND_MIXER_PRIVATE3,&ctrl); - printf("master = %d\n",val); - ctrl.master = val; - ioctl(fdwr,SOUND_MIXER_PRIVATE3,&ctrl); - exit (0); - } - - if (!strcmp(argv[argidx],"pro")) { - int val = atoi(argv[argidx+1]); - ioctl(fd,SOUND_MIXER_PRIVATE3,&ctrl); - printf("pro = %d\n",val); - ctrl.pro = val; - ioctl(fdwr,SOUND_MIXER_PRIVATE3,&ctrl); - exit (0); - } - - if (!strcmp(argv[argidx],"emphasis")) { - int val = atoi(argv[argidx+1]); - ioctl(fd,SOUND_MIXER_PRIVATE3,&ctrl); - printf("emphasis = %d\n",val); - ctrl.emphasis = val; - ioctl(fdwr,SOUND_MIXER_PRIVATE3,&ctrl); - exit (0); - } - - if (!strcmp(argv[argidx],"dolby")) { - int val = atoi(argv[argidx+1]); - ioctl(fd,SOUND_MIXER_PRIVATE3,&ctrl); - printf("dolby = %d\n",val); - ctrl.dolby = val; - ioctl(fdwr,SOUND_MIXER_PRIVATE3,&ctrl); - exit (0); - } - - if (!strcmp(argv[argidx],"optout")) { - int val = atoi(argv[argidx+1]); - ioctl(fd,SOUND_MIXER_PRIVATE3,&ctrl); - printf("optout = %d\n",val); - ctrl.opt_out = val; - ioctl(fdwr,SOUND_MIXER_PRIVATE3,&ctrl); - exit (0); - } - - if (!strcmp(argv[argidx],"wordclock")) { - int val = atoi(argv[argidx+1]); - ioctl(fd,SOUND_MIXER_PRIVATE3,&ctrl); - printf("wordclock = %d\n",val); - ctrl.wordclock = val; - ioctl(fdwr,SOUND_MIXER_PRIVATE3,&ctrl); - exit (0); - } - - if (!strcmp(argv[argidx],"spdifin")) { - int val = atoi(argv[argidx+1]); - ioctl(fd,SOUND_MIXER_PRIVATE3,&ctrl); - printf("spdifin = %d\n",val); - ctrl.spdif_in = val; - ioctl(fdwr,SOUND_MIXER_PRIVATE3,&ctrl); - exit (0); - } - - if (!strcmp(argv[argidx],"syncref")) { - int val = atoi(argv[argidx+1]); - ioctl(fd,SOUND_MIXER_PRIVATE3,&ctrl); - printf("syncref = %d\n",val); - ctrl.sync_ref = val; - ioctl(fdwr,SOUND_MIXER_PRIVATE3,&ctrl); - exit (0); - } - - if (!strcmp(argv[argidx],"adat1cd")) { - int val = atoi(argv[argidx+1]); - ioctl(fd,SOUND_MIXER_PRIVATE3,&ctrl); - printf("adat1cd = %d\n",val); - ctrl.adat1_cd = val; - ioctl(fdwr,SOUND_MIXER_PRIVATE3,&ctrl); - exit (0); - } - -/* setting offset */ - - if (argc < argidx+4) - usage(); - - if (!strcmp(argv[argidx],"offset")) { - rme_mixer mix; - - mix.devnr = atoi(argv[argidx+1]); - - mix.i_offset = atoi(argv[argidx+2]); - mix.o_offset = atoi(argv[argidx+3]); - ioctl(fdwr,SOUND_MIXER_PRIVATE1,&mix); - fprintf(stdout,"devnr %d\n",mix.devnr); - fprintf(stdout,"mix.i_offset to %d\n",mix.i_offset); - fprintf(stdout,"mix.o_offset to %d\n",mix.o_offset); - exit (0); - } - - usage(); - exit (0); /* to avoid warning */ -} - - ----------------------------- -------------------------------- -#!/usr/bin/wish - -# xrmectrl -# (C) 2000 Guenter Geiger -# HP20020201 - Heiko Purnhagen - -#set defaults "-relief ridged" -set CTRLPROG "./rmectrl" -if {$argc} { - set CTRLPROG "$CTRLPROG $argv" -} -puts "CTRLPROG $CTRLPROG" - -frame .butts -button .butts.exit -text "Exit" -command "exit" -relief ridge -#button .butts.state -text "State" -command "get_all" - -pack .butts.exit -side left -pack .butts -side bottom - - -# -# STATUS -# - -frame .status - -# Sampling Rate - -frame .status.sr -label .status.sr.text -text "Sampling Rate" -justify left -radiobutton .status.sr.441 -selectcolor red -text "44.1 kHz" -width 10 -anchor nw -variable srate -value 44100 -font times -radiobutton .status.sr.480 -selectcolor red -text "48 kHz" -width 10 -anchor nw -variable srate -value 48000 -font times -radiobutton .status.sr.882 -selectcolor red -text "88.2 kHz" -width 10 -anchor nw -variable srate -value 88200 -font times -radiobutton .status.sr.960 -selectcolor red -text "96 kHz" -width 10 -anchor nw -variable srate -value 96000 -font times - -pack .status.sr.text .status.sr.441 .status.sr.480 .status.sr.882 .status.sr.960 -side top -padx 3 - -# Lock - -frame .status.lock -label .status.lock.text -text "Lock" -justify left -checkbutton .status.lock.adat1 -selectcolor red -text "ADAT1" -anchor nw -width 10 -variable adatlock1 -font times -checkbutton .status.lock.adat2 -selectcolor red -text "ADAT2" -anchor nw -width 10 -variable adatlock2 -font times -checkbutton .status.lock.adat3 -selectcolor red -text "ADAT3" -anchor nw -width 10 -variable adatlock3 -font times - -pack .status.lock.text .status.lock.adat1 .status.lock.adat2 .status.lock.adat3 -side top -padx 3 - -# Sync - -frame .status.sync -label .status.sync.text -text "Sync" -justify left -checkbutton .status.sync.adat1 -selectcolor red -text "ADAT1" -anchor nw -width 10 -variable adatsync1 -font times -checkbutton .status.sync.adat2 -selectcolor red -text "ADAT2" -anchor nw -width 10 -variable adatsync2 -font times -checkbutton .status.sync.adat3 -selectcolor red -text "ADAT3" -anchor nw -width 10 -variable adatsync3 -font times - -pack .status.sync.text .status.sync.adat1 .status.sync.adat2 .status.sync.adat3 -side top -padx 3 - -# Timecode - -frame .status.tc -label .status.tc.text -text "Timecode" -justify left -checkbutton .status.tc.busy -selectcolor red -text "busy" -anchor nw -width 10 -variable tcbusy -font times -checkbutton .status.tc.out -selectcolor red -text "out" -anchor nw -width 10 -variable tcout -font times -checkbutton .status.tc.valid -selectcolor red -text "valid" -anchor nw -width 10 -variable tcvalid -font times - -pack .status.tc.text .status.tc.busy .status.tc.out .status.tc.valid -side top -padx 3 - -# SPDIF In - -frame .status.spdif -label .status.spdif.text -text "SPDIF In" -justify left -label .status.spdif.sr -text "--.- kHz" -anchor n -width 10 -font times -checkbutton .status.spdif.error -selectcolor red -text "Input Lock" -anchor nw -width 10 -variable spdiferr -font times - -pack .status.spdif.text .status.spdif.sr .status.spdif.error -side top -padx 3 - -pack .status.sr .status.lock .status.sync .status.tc .status.spdif -side left -fill x -anchor n -expand 1 - - -# -# CONTROL -# - -proc setprof {} { - global CTRLPROG - global spprof - exec $CTRLPROG pro $spprof -} - -proc setemph {} { - global CTRLPROG - global spemph - exec $CTRLPROG emphasis $spemph -} - -proc setnoaud {} { - global CTRLPROG - global spnoaud - exec $CTRLPROG dolby $spnoaud -} - -proc setoptical {} { - global CTRLPROG - global spoptical - exec $CTRLPROG optout $spoptical -} - -proc setspdifin {} { - global CTRLPROG - global spdifin - exec $CTRLPROG spdifin [expr $spdifin - 1] -} - -proc setsyncsource {} { - global CTRLPROG - global syncsource - exec $CTRLPROG syncref [expr $syncsource -1] -} - - -proc setmaster {} { - global CTRLPROG - global master - exec $CTRLPROG master $master -} - -proc setwordclock {} { - global CTRLPROG - global wordclock - exec $CTRLPROG wordclock $wordclock -} - -proc setadat1cd {} { - global CTRLPROG - global adat1cd - exec $CTRLPROG adat1cd $adat1cd -} - - -frame .control - -# SPDIF In & SPDIF Out - - -frame .control.spdif - -frame .control.spdif.in -label .control.spdif.in.text -text "SPDIF In" -justify left -radiobutton .control.spdif.in.input1 -text "Optical" -anchor nw -width 13 -variable spdifin -value 1 -command setspdifin -selectcolor blue -font times -radiobutton .control.spdif.in.input2 -text "Coaxial" -anchor nw -width 13 -variable spdifin -value 2 -command setspdifin -selectcolor blue -font times -radiobutton .control.spdif.in.input3 -text "Intern " -anchor nw -width 13 -variable spdifin -command setspdifin -value 3 -selectcolor blue -font times - -checkbutton .control.spdif.in.adat1cd -text "ADAT1 Intern" -anchor nw -width 13 -variable adat1cd -command setadat1cd -selectcolor blue -font times - -pack .control.spdif.in.text .control.spdif.in.input1 .control.spdif.in.input2 .control.spdif.in.input3 .control.spdif.in.adat1cd - -label .control.spdif.space - -frame .control.spdif.out -label .control.spdif.out.text -text "SPDIF Out" -justify left -checkbutton .control.spdif.out.pro -text "Professional" -anchor nw -width 13 -variable spprof -command setprof -selectcolor blue -font times -checkbutton .control.spdif.out.emphasis -text "Emphasis" -anchor nw -width 13 -variable spemph -command setemph -selectcolor blue -font times -checkbutton .control.spdif.out.dolby -text "NoAudio" -anchor nw -width 13 -variable spnoaud -command setnoaud -selectcolor blue -font times -checkbutton .control.spdif.out.optout -text "Optical Out" -anchor nw -width 13 -variable spoptical -command setoptical -selectcolor blue -font times - -pack .control.spdif.out.optout .control.spdif.out.dolby .control.spdif.out.emphasis .control.spdif.out.pro .control.spdif.out.text -side bottom - -pack .control.spdif.in .control.spdif.space .control.spdif.out -side top -fill y -padx 3 -expand 1 - -# Sync Mode & Sync Source - -frame .control.sync -frame .control.sync.mode -label .control.sync.mode.text -text "Sync Mode" -justify left -checkbutton .control.sync.mode.master -text "Master" -anchor nw -width 13 -variable master -command setmaster -selectcolor blue -font times -checkbutton .control.sync.mode.wc -text "Wordclock" -anchor nw -width 13 -variable wordclock -command setwordclock -selectcolor blue -font times - -pack .control.sync.mode.text .control.sync.mode.master .control.sync.mode.wc - -label .control.sync.space - -frame .control.sync.src -label .control.sync.src.text -text "Sync Source" -justify left -radiobutton .control.sync.src.input1 -text "ADAT1" -anchor nw -width 13 -variable syncsource -value 1 -command setsyncsource -selectcolor blue -font times -radiobutton .control.sync.src.input2 -text "ADAT2" -anchor nw -width 13 -variable syncsource -value 2 -command setsyncsource -selectcolor blue -font times -radiobutton .control.sync.src.input3 -text "ADAT3" -anchor nw -width 13 -variable syncsource -command setsyncsource -value 3 -selectcolor blue -font times -radiobutton .control.sync.src.input4 -text "SPDIF" -anchor nw -width 13 -variable syncsource -command setsyncsource -value 4 -selectcolor blue -font times - -pack .control.sync.src.input4 .control.sync.src.input3 .control.sync.src.input2 .control.sync.src.input1 .control.sync.src.text -side bottom - -pack .control.sync.mode .control.sync.space .control.sync.src -side top -fill y -padx 3 -expand 1 - -label .control.space -text "" -width 10 - -# Buffer Size - -frame .control.buf -label .control.buf.text -text "Buffer Size (Latency)" -justify left -radiobutton .control.buf.b1 -selectcolor red -text "64 (1.5 ms)" -width 13 -anchor nw -variable ssrate -value 1 -font times -radiobutton .control.buf.b2 -selectcolor red -text "128 (3 ms)" -width 13 -anchor nw -variable ssrate -value 2 -font times -radiobutton .control.buf.b3 -selectcolor red -text "256 (6 ms)" -width 13 -anchor nw -variable ssrate -value 3 -font times -radiobutton .control.buf.b4 -selectcolor red -text "512 (12 ms)" -width 13 -anchor nw -variable ssrate -value 4 -font times -radiobutton .control.buf.b5 -selectcolor red -text "1024 (23 ms)" -width 13 -anchor nw -variable ssrate -value 5 -font times -radiobutton .control.buf.b6 -selectcolor red -text "2048 (46 ms)" -width 13 -anchor nw -variable ssrate -value 6 -font times -radiobutton .control.buf.b7 -selectcolor red -text "4096 (93 ms)" -width 13 -anchor nw -variable ssrate -value 7 -font times -radiobutton .control.buf.b8 -selectcolor red -text "8192 (186 ms)" -width 13 -anchor nw -variable ssrate -value 8 -font times - -pack .control.buf.text .control.buf.b1 .control.buf.b2 .control.buf.b3 .control.buf.b4 .control.buf.b5 .control.buf.b6 .control.buf.b7 .control.buf.b8 -side top -padx 3 - -# Offset - -frame .control.offset - -frame .control.offset.in -label .control.offset.in.text -text "Offset In" -justify left -label .control.offset.in.off0 -text "dev\#0: -" -anchor nw -width 10 -font times -label .control.offset.in.off1 -text "dev\#1: -" -anchor nw -width 10 -font times -label .control.offset.in.off2 -text "dev\#2: -" -anchor nw -width 10 -font times -label .control.offset.in.off3 -text "dev\#3: -" -anchor nw -width 10 -font times - -pack .control.offset.in.text .control.offset.in.off0 .control.offset.in.off1 .control.offset.in.off2 .control.offset.in.off3 - -label .control.offset.space - -frame .control.offset.out -label .control.offset.out.text -text "Offset Out" -justify left -label .control.offset.out.off0 -text "dev\#0: -" -anchor nw -width 10 -font times -label .control.offset.out.off1 -text "dev\#1: -" -anchor nw -width 10 -font times -label .control.offset.out.off2 -text "dev\#2: -" -anchor nw -width 10 -font times -label .control.offset.out.off3 -text "dev\#3: -" -anchor nw -width 10 -font times - -pack .control.offset.out.off3 .control.offset.out.off2 .control.offset.out.off1 .control.offset.out.off0 .control.offset.out.text -side bottom - -pack .control.offset.in .control.offset.space .control.offset.out -side top -fill y -padx 3 -expand 1 - - -pack .control.spdif .control.sync .control.space .control.buf .control.offset -side left -fill both -anchor n -expand 1 - - -label .statustext -text Status -justify center -relief ridge -label .controltext -text Control -justify center -relief ridge - -label .statusspace -label .controlspace - -pack .statustext .status .statusspace .controltext .control .controlspace -side top -anchor nw -fill both -expand 1 - - -proc get_bit {output sstr} { - set idx1 [string last [concat $sstr 1] $output] - set idx1 [expr $idx1 != -1] - return $idx1 -} - -proc get_val {output sstr} { - set val [string wordend $output [string last $sstr $output]] - set val [string range $output $val [expr $val+1]] - return $val -} - -proc get_val2 {output sstr} { - set val [string wordend $output [string first $sstr $output]] - set val [string range $output $val [expr $val+2]] - return $val -} - -proc get_control {} { - global spprof - global spemph - global spnoaud - global spoptical - global spdifin - global ssrate - global master - global wordclock - global syncsource - global CTRLPROG - - set f [open "| $CTRLPROG control" r+] - set ooo [read $f 1000] - close $f -# puts $ooo - - set spprof [ get_bit $ooo "pro"] - set spemph [ get_bit $ooo "emphasis"] - set spnoaud [ get_bit $ooo "dolby"] - set spoptical [ get_bit $ooo "opt_out"] - set spdifin [ expr [ get_val $ooo "spdif_in"] + 1] - set ssrate [ expr [ get_val $ooo "latency"] + 1] - set master [ expr [ get_val $ooo "master"]] - set wordclock [ expr [ get_val $ooo "wordclock"]] - set syncsource [ expr [ get_val $ooo "sync_ref"] + 1] -} - -proc get_status {} { - global srate - global ctrlcom - - global adatlock1 - global adatlock2 - global adatlock3 - - global adatsync1 - global adatsync2 - global adatsync3 - - global tcbusy - global tcout - global tcvalid - - global spdiferr - global crystal - global .status.spdif.text - global CTRLPROG - - - set f [open "| $CTRLPROG status" r+] - set ooo [read $f 1000] - close $f -# puts $ooo - -# samplerate - - set idx1 [string last "sr48 1" $ooo] - set idx2 [string last "doublespeed 1" $ooo] - if {$idx1 >= 0} { - set fact1 48000 - } else { - set fact1 44100 - } - - if {$idx2 >= 0} { - set fact2 2 - } else { - set fact2 1 - } - set srate [expr $fact1 * $fact2] -# ADAT lock - - set val [get_val $ooo lockmask] - set adatlock1 0 - set adatlock2 0 - set adatlock3 0 - if {[expr $val & 1]} { - set adatlock3 1 - } - if {[expr $val & 2]} { - set adatlock2 1 - } - if {[expr $val & 4]} { - set adatlock1 1 - } - -# ADAT sync - set val [get_val $ooo syncmask] - set adatsync1 0 - set adatsync2 0 - set adatsync3 0 - - if {[expr $val & 1]} { - set adatsync3 1 - } - if {[expr $val & 2]} { - set adatsync2 1 - } - if {[expr $val & 4]} { - set adatsync1 1 - } - -# TC busy - - set tcbusy [get_bit $ooo "busy"] - set tcout [get_bit $ooo "out"] - set tcvalid [get_bit $ooo "valid"] - set spdiferr [expr [get_bit $ooo "spdif_error"] == 0] - -# 000=64kHz, 100=88.2kHz, 011=96kHz -# 111=32kHz, 110=44.1kHz, 101=48kHz - - set val [get_val $ooo crystalrate] - - set crystal "--.- kHz" - if {$val == 0} { - set crystal "64 kHz" - } - if {$val == 4} { - set crystal "88.2 kHz" - } - if {$val == 3} { - set crystal "96 kHz" - } - if {$val == 7} { - set crystal "32 kHz" - } - if {$val == 6} { - set crystal "44.1 kHz" - } - if {$val == 5} { - set crystal "48 kHz" - } - .status.spdif.sr configure -text $crystal -} - -proc get_offset {} { - global inoffset - global outoffset - global CTRLPROG - - set f [open "| $CTRLPROG mix" r+] - set ooo [read $f 1000] - close $f -# puts $ooo - - if { [string match "*devnr*" $ooo] } { - set ooo [string range $ooo [string wordend $ooo [string first devnr $ooo]] end] - set val [get_val2 $ooo i_offset] - .control.offset.in.off0 configure -text "dev\#0: $val" - set val [get_val2 $ooo o_offset] - .control.offset.out.off0 configure -text "dev\#0: $val" - } else { - .control.offset.in.off0 configure -text "dev\#0: -" - .control.offset.out.off0 configure -text "dev\#0: -" - } - if { [string match "*devnr*" $ooo] } { - set ooo [string range $ooo [string wordend $ooo [string first devnr $ooo]] end] - set val [get_val2 $ooo i_offset] - .control.offset.in.off1 configure -text "dev\#1: $val" - set val [get_val2 $ooo o_offset] - .control.offset.out.off1 configure -text "dev\#1: $val" - } else { - .control.offset.in.off1 configure -text "dev\#1: -" - .control.offset.out.off1 configure -text "dev\#1: -" - } - if { [string match "*devnr*" $ooo] } { - set ooo [string range $ooo [string wordend $ooo [string first devnr $ooo]] end] - set val [get_val2 $ooo i_offset] - .control.offset.in.off2 configure -text "dev\#2: $val" - set val [get_val2 $ooo o_offset] - .control.offset.out.off2 configure -text "dev\#2: $val" - } else { - .control.offset.in.off2 configure -text "dev\#2: -" - .control.offset.out.off2 configure -text "dev\#2: -" - } - if { [string match "*devnr*" $ooo] } { - set ooo [string range $ooo [string wordend $ooo [string first devnr $ooo]] end] - set val [get_val2 $ooo i_offset] - .control.offset.in.off3 configure -text "dev\#3: $val" - set val [get_val2 $ooo o_offset] - .control.offset.out.off3 configure -text "dev\#3: $val" - } else { - .control.offset.in.off3 configure -text "dev\#3: -" - .control.offset.out.off3 configure -text "dev\#3: -" - } -} - - -proc get_all {} { -get_status -get_control -get_offset -} - -# main -while {1} { - after 200 - get_all - update -} diff -Nru a/arch/ia64/Kconfig b/arch/ia64/Kconfig --- a/arch/ia64/Kconfig Sun Feb 29 12:54:28 2004 +++ b/arch/ia64/Kconfig Sun Feb 29 12:54:28 2004 @@ -288,39 +288,6 @@ int default "18" -choice - prompt "Huge TLB page size" - depends on HUGETLB_PAGE - default HUGETLB_PAGE_SIZE_16MB - -config HUGETLB_PAGE_SIZE_4GB - depends on MCKINLEY - bool "4GB" - -config HUGETLB_PAGE_SIZE_1GB - depends on MCKINLEY - bool "1GB" - -config HUGETLB_PAGE_SIZE_256MB - bool "256MB" - -config HUGETLB_PAGE_SIZE_64MB - bool "64MB" - -config HUGETLB_PAGE_SIZE_16MB - bool "16MB" - -config HUGETLB_PAGE_SIZE_4MB - bool "4MB" - -config HUGETLB_PAGE_SIZE_1MB - bool "1MB" - -config HUGETLB_PAGE_SIZE_256KB - bool "256KB" - -endchoice - config IA64_PAL_IDLE bool "Use PAL_HALT_LIGHT in idle loop" help diff -Nru a/arch/ia64/kernel/head.S b/arch/ia64/kernel/head.S --- a/arch/ia64/kernel/head.S Sun Feb 29 12:54:28 2004 +++ b/arch/ia64/kernel/head.S Sun Feb 29 12:54:28 2004 @@ -816,6 +816,19 @@ br.ret.sptk.many rp END(ia64_delay_loop) +GLOBAL_ENTRY(ia64_invoke_kernel_thread_helper) + .prologue + .save rp, r0 // this is the end of the call-chain + .body + alloc r2 = ar.pfs, 0, 0, 2, 0 + mov out0 = r9 + mov out1 = r11;; + br.call.sptk.many rp = kernel_thread_helper;; + mov out0 = r8 + br.call.sptk.many rp = sys_exit;; +1: br.sptk.few 1b // not reached +END(ia64_invoke_kernel_thread_helper) + #ifdef CONFIG_IA64_BRL_EMU /* diff -Nru a/arch/ia64/kernel/iosapic.c b/arch/ia64/kernel/iosapic.c --- a/arch/ia64/kernel/iosapic.c Sun Feb 29 12:54:28 2004 +++ b/arch/ia64/kernel/iosapic.c Sun Feb 29 12:54:28 2004 @@ -103,6 +103,7 @@ static struct iosapic_intr_info { char *addr; /* base address of IOSAPIC */ + u32 low32; /* current value of low word of Redirection table entry */ unsigned int gsi_base; /* first GSI assigned to this IOSAPIC */ char rte_index; /* IOSAPIC RTE index (-1 => not an IOSAPIC interrupt) */ unsigned char dmode : 3; /* delivery mode (see iosapic.h) */ @@ -213,6 +214,7 @@ writel(high32, addr + IOSAPIC_WINDOW); writel(IOSAPIC_RTE_LOW(rte_index), addr + IOSAPIC_REG_SELECT); writel(low32, addr + IOSAPIC_WINDOW); + iosapic_intr_info[vector].low32 = low32; } static void @@ -239,9 +241,10 @@ spin_lock_irqsave(&iosapic_lock, flags); { writel(IOSAPIC_RTE_LOW(rte_index), addr + IOSAPIC_REG_SELECT); - low32 = readl(addr + IOSAPIC_WINDOW); - low32 |= (1 << IOSAPIC_MASK_SHIFT); /* set only the mask bit */ + /* set only the mask bit */ + low32 = iosapic_intr_info[vec].low32 |= IOSAPIC_MASK; + writel(low32, addr + IOSAPIC_WINDOW); } spin_unlock_irqrestore(&iosapic_lock, flags); @@ -264,9 +267,7 @@ spin_lock_irqsave(&iosapic_lock, flags); { writel(IOSAPIC_RTE_LOW(rte_index), addr + IOSAPIC_REG_SELECT); - low32 = readl(addr + IOSAPIC_WINDOW); - - low32 &= ~(1 << IOSAPIC_MASK_SHIFT); /* clear only the mask bit */ + low32 = iosapic_intr_info[vec].low32 &= ~IOSAPIC_MASK; writel(low32, addr + IOSAPIC_WINDOW); } spin_unlock_irqrestore(&iosapic_lock, flags); @@ -307,9 +308,7 @@ { /* get current delivery mode by reading the low32 */ writel(IOSAPIC_RTE_LOW(rte_index), addr + IOSAPIC_REG_SELECT); - low32 = readl(addr + IOSAPIC_WINDOW); - - low32 &= ~(7 << IOSAPIC_DELIVERY_SHIFT); + low32 = iosapic_intr_info[vec].low32 & ~(7 << IOSAPIC_DELIVERY_SHIFT); if (redir) /* change delivery mode to lowest priority */ low32 |= (IOSAPIC_LOWEST_PRIORITY << IOSAPIC_DELIVERY_SHIFT); @@ -317,6 +316,7 @@ /* change delivery mode to fixed */ low32 |= (IOSAPIC_FIXED << IOSAPIC_DELIVERY_SHIFT); + iosapic_intr_info[vec].low32 = low32; writel(IOSAPIC_RTE_HIGH(rte_index), addr + IOSAPIC_REG_SELECT); writel(high32, addr + IOSAPIC_WINDOW); writel(IOSAPIC_RTE_LOW(rte_index), addr + IOSAPIC_REG_SELECT); diff -Nru a/arch/ia64/kernel/irq.c b/arch/ia64/kernel/irq.c --- a/arch/ia64/kernel/irq.c Sun Feb 29 12:54:28 2004 +++ b/arch/ia64/kernel/irq.c Sun Feb 29 12:54:28 2004 @@ -455,7 +455,6 @@ unsigned int status; int cpu; - irq_enter(); cpu = smp_processor_id(); /* for CONFIG_PREEMPT, this must come after irq_enter()! */ kstat_cpu(cpu).irqs[irq]++; @@ -525,7 +524,6 @@ desc->handler->end(irq); spin_unlock(&desc->lock); } - irq_exit(); return 1; } diff -Nru a/arch/ia64/kernel/irq_ia64.c b/arch/ia64/kernel/irq_ia64.c --- a/arch/ia64/kernel/irq_ia64.c Sun Feb 29 12:54:28 2004 +++ b/arch/ia64/kernel/irq_ia64.c Sun Feb 29 12:54:28 2004 @@ -120,6 +120,7 @@ * 16 (without this, it would be ~240, which could easily lead * to kernel stack overflows). */ + irq_enter(); saved_tpr = ia64_getreg(_IA64_REG_CR_TPR); ia64_srlz_d(); while (vector != IA64_SPURIOUS_INT_VECTOR) { @@ -143,8 +144,7 @@ * handler needs to be able to wait for further keyboard interrupts, which can't * come through until ia64_eoi() has been done. */ - if (local_softirq_pending()) - do_softirq(); + irq_exit(); } #ifdef CONFIG_SMP diff -Nru a/arch/ia64/kernel/ivt.S b/arch/ia64/kernel/ivt.S --- a/arch/ia64/kernel/ivt.S Sun Feb 29 12:54:28 2004 +++ b/arch/ia64/kernel/ivt.S Sun Feb 29 12:54:28 2004 @@ -118,10 +118,11 @@ #ifdef CONFIG_HUGETLB_PAGE extr.u r26=r25,2,6 ;; - cmp.eq p8,p0=HPAGE_SHIFT,r26 + cmp.ne p8,p0=r18,r26 + sub r27=r26,r18 ;; (p8) dep r25=r18,r25,2,6 -(p8) shr r22=r22,HPAGE_SHIFT-PAGE_SHIFT +(p8) shr r22=r22,r27 #endif ;; cmp.eq p6,p7=5,r17 // is IFA pointing into to region 5? diff -Nru a/arch/ia64/kernel/perfmon.c b/arch/ia64/kernel/perfmon.c --- a/arch/ia64/kernel/perfmon.c Sun Feb 29 12:54:28 2004 +++ b/arch/ia64/kernel/perfmon.c Sun Feb 29 12:54:28 2004 @@ -82,7 +82,7 @@ #define PFM_REG_IMPL 0x1 /* register implemented */ #define PFM_REG_END 0x2 /* end marker */ #define PFM_REG_MONITOR (0x1<<4|PFM_REG_IMPL) /* a PMC with a pmc.pm field only */ -#define PFM_REG_COUNTING (0x2<<4|PFM_REG_MONITOR|PFM_REG_IMPL) /* a monitor + pmc.oi+ PMD used as a counter */ +#define PFM_REG_COUNTING (0x2<<4|PFM_REG_MONITOR) /* a monitor + pmc.oi+ PMD used as a counter */ #define PFM_REG_CONTROL (0x4<<4|PFM_REG_IMPL) /* PMU control register */ #define PFM_REG_CONFIG (0x8<<4|PFM_REG_IMPL) /* configuration register */ #define PFM_REG_BUFFER (0xc<<4|PFM_REG_IMPL) /* PMD used as buffer */ @@ -109,14 +109,15 @@ #define PMD_PMD_DEP(i) pmu_conf.pmd_desc[i].dep_pmd[0] #define PMC_PMD_DEP(i) pmu_conf.pmc_desc[i].dep_pmd[0] -/* k assumed unsigned (up to 64 registers) */ -#define IBR_IS_IMPL(k) (k< IA64_NUM_DBG_REGS) -#define DBR_IS_IMPL(k) (k< IA64_NUM_DBG_REGS) +#define PFM_NUM_IBRS IA64_NUM_DBG_REGS +#define PFM_NUM_DBRS IA64_NUM_DBG_REGS #define CTX_OVFL_NOBLOCK(c) ((c)->ctx_fl_block == 0) #define CTX_HAS_SMPL(c) ((c)->ctx_fl_is_sampling) #define PFM_CTX_TASK(h) (h)->ctx_task +#define PMU_PMC_OI 5 /* position of pmc.oi bit */ + /* XXX: does not support more than 64 PMDs */ #define CTX_USED_PMD(ctx, mask) (ctx)->ctx_used_pmds[0] |= (mask) #define CTX_IS_USED_PMD(ctx, c) (((ctx)->ctx_used_pmds[0] & (1UL << (c))) != 0UL) @@ -218,6 +219,8 @@ /* * debugging */ +#define PFM_DEBUGGING 1 +#ifdef PFM_DEBUGGING #define DPRINT(a) \ do { \ if (unlikely(pfm_sysctl.debug >0)) { printk("%s.%d: CPU%d [%d] ", __FUNCTION__, __LINE__, smp_processor_id(), current->pid); printk a; } \ @@ -227,18 +230,7 @@ do { \ if (unlikely(pfm_sysctl.debug > 0 && pfm_sysctl.debug_ovfl >0)) { printk("%s.%d: CPU%d [%d] ", __FUNCTION__, __LINE__, smp_processor_id(), current->pid); printk a; } \ } while (0) -/* - * Architected PMC structure - */ -typedef struct { - unsigned long pmc_plm:4; /* privilege level mask */ - unsigned long pmc_ev:1; /* external visibility */ - unsigned long pmc_oi:1; /* overflow interrupt */ - unsigned long pmc_pm:1; /* privileged monitor */ - unsigned long pmc_ig1:1; /* reserved */ - unsigned long pmc_es:8; /* event select */ - unsigned long pmc_ig2:48; /* reserved */ -} pfm_monitor_t; +#endif /* * 64-bit software counter structure @@ -469,20 +461,13 @@ #define PFM_CMD_STOP 0x08 /* command does not work on zombie context */ -#define PFM_CMD_IDX(cmd) (cmd) -#define PFM_CMD_IS_VALID(cmd) ((PFM_CMD_IDX(cmd) >= 0) && (PFM_CMD_IDX(cmd) < PFM_CMD_COUNT) \ - && pfm_cmd_tab[PFM_CMD_IDX(cmd)].cmd_func != NULL) - -#define PFM_CMD_NAME(cmd) pfm_cmd_tab[PFM_CMD_IDX(cmd)].cmd_name -#define PFM_CMD_READ_ARG(cmd) (pfm_cmd_tab[PFM_CMD_IDX(cmd)].cmd_flags & PFM_CMD_ARG_READ) -#define PFM_CMD_RW_ARG(cmd) (pfm_cmd_tab[PFM_CMD_IDX(cmd)].cmd_flags & PFM_CMD_ARG_RW) -#define PFM_CMD_USE_FD(cmd) (pfm_cmd_tab[PFM_CMD_IDX(cmd)].cmd_flags & PFM_CMD_FD) -#define PFM_CMD_STOPPED(cmd) (pfm_cmd_tab[PFM_CMD_IDX(cmd)].cmd_flags & PFM_CMD_STOP) +#define PFM_CMD_NAME(cmd) pfm_cmd_tab[(cmd)].cmd_name +#define PFM_CMD_READ_ARG(cmd) (pfm_cmd_tab[(cmd)].cmd_flags & PFM_CMD_ARG_READ) +#define PFM_CMD_RW_ARG(cmd) (pfm_cmd_tab[(cmd)].cmd_flags & PFM_CMD_ARG_RW) +#define PFM_CMD_USE_FD(cmd) (pfm_cmd_tab[(cmd)].cmd_flags & PFM_CMD_FD) +#define PFM_CMD_STOPPED(cmd) (pfm_cmd_tab[(cmd)].cmd_flags & PFM_CMD_STOP) #define PFM_CMD_ARG_MANY -1 /* cannot be zero */ -#define PFM_CMD_NARG(cmd) (pfm_cmd_tab[PFM_CMD_IDX(cmd)].cmd_narg) -#define PFM_CMD_ARG_SIZE(cmd) (pfm_cmd_tab[PFM_CMD_IDX(cmd)].cmd_argsize) -#define PFM_CMD_GETSIZE(cmd) (pfm_cmd_tab[PFM_CMD_IDX(cmd)].cmd_getsize) typedef struct { int debug; /* turn on/off debugging via syslog */ @@ -2834,10 +2819,11 @@ pfm_write_pmcs(pfm_context_t *ctx, void *arg, int count, struct pt_regs *regs) { struct thread_struct *thread = NULL; + struct task_struct *task; pfarg_reg_t *req = (pfarg_reg_t *)arg; - unsigned long value; - unsigned long smpl_pmds, reset_pmds; - unsigned int cnum, reg_flags, flags; + unsigned long value, pmc_pm; + unsigned long smpl_pmds, reset_pmds, impl_pmds; + unsigned int cnum, reg_flags, flags, pmc_type; int i, can_access_pmu = 0, is_loaded, is_system; int is_monitor, is_counting, state; int ret = -EINVAL; @@ -2846,12 +2832,13 @@ state = ctx->ctx_state; is_loaded = state == PFM_CTX_LOADED ? 1 : 0; is_system = ctx->ctx_fl_system; + task = ctx->ctx_task; + impl_pmds = pmu_conf.impl_pmds[0]; if (state == PFM_CTX_TERMINATED || state == PFM_CTX_ZOMBIE) return -EINVAL; - if (is_loaded) { - thread = &ctx->ctx_task->thread; + thread = &task->thread; /* * In system wide and when the context is loaded, access can only happen * when the caller is running on the CPU being monitored by the session. @@ -2861,7 +2848,7 @@ DPRINT(("[%d] should be running on CPU%d\n", current->pid, ctx->ctx_cpu)); return -EBUSY; } - can_access_pmu = GET_PMU_OWNER() == ctx->ctx_task || is_system ? 1 : 0; + can_access_pmu = GET_PMU_OWNER() == task || is_system ? 1 : 0; } for (i = 0; i < count; i++, req++) { @@ -2873,16 +2860,24 @@ reset_pmds = req->reg_reset_pmds[0]; flags = 0; - is_counting = PMC_IS_COUNTING(cnum); - is_monitor = PMC_IS_MONITOR(cnum); + + if (cnum >= PMU_MAX_PMCS) { + DPRINT(("pmc%u is invalid\n", cnum)); + goto error; + } + + pmc_type = pmu_conf.pmc_desc[cnum].type; + pmc_pm = (value >> pmu_conf.pmc_desc[cnum].pm_pos) & 0x1; + is_counting = (pmc_type & PFM_REG_COUNTING) == PFM_REG_COUNTING ? 1 : 0; + is_monitor = (pmc_type & PFM_REG_MONITOR) == PFM_REG_MONITOR ? 1 : 0; /* * we reject all non implemented PMC as well * as attempts to modify PMC[0-3] which are used * as status registers by the PMU */ - if (PMC_IS_IMPL(cnum) == 0 || PMC_IS_CONTROL(cnum)) { - DPRINT(("pmc%u is unimplemented or invalid\n", cnum)); + if ((pmc_type & PFM_REG_IMPL) == 0 || (pmc_type & PFM_REG_CONTROL) == PFM_REG_CONTROL) { + DPRINT(("pmc%u is unimplemented or no-access pmc_type=%x\n", cnum, pmc_type)); goto error; } /* @@ -2890,21 +2885,20 @@ * - system-wide session: PMCx.pm=1 (privileged monitor) * - per-task : PMCx.pm=0 (user monitor) */ - if ((is_monitor || is_counting) && value != PMC_DFL_VAL(cnum) && PFM_CHECK_PMC_PM(ctx, cnum, value)) { - DPRINT(("pmc%u pmc_pm=%ld fl_system=%d\n", + if (is_monitor && value != PMC_DFL_VAL(cnum) && is_system ^ pmc_pm) { + DPRINT(("pmc%u pmc_pm=%lu is_system=%d\n", cnum, - PMC_PM(cnum, value), - ctx->ctx_fl_system)); + pmc_pm, + is_system)); goto error; } if (is_counting) { - pfm_monitor_t *p = (pfm_monitor_t *)&value; /* * enforce generation of overflow interrupt. Necessary on all * CPUs. */ - p->pmc_oi = 1; + value |= 1 << PMU_PMC_OI; if (reg_flags & PFM_REGFL_OVFL_NOTIFY) { flags |= PFM_REGFL_OVFL_NOTIFY; @@ -2913,13 +2907,13 @@ if (reg_flags & PFM_REGFL_RANDOM) flags |= PFM_REGFL_RANDOM; /* verify validity of smpl_pmds */ - if ((smpl_pmds & pmu_conf.impl_pmds[0]) != smpl_pmds) { + if ((smpl_pmds & impl_pmds) != smpl_pmds) { DPRINT(("invalid smpl_pmds 0x%lx for pmc%u\n", smpl_pmds, cnum)); goto error; } /* verify validity of reset_pmds */ - if ((reset_pmds & pmu_conf.impl_pmds[0]) != reset_pmds) { + if ((reset_pmds & impl_pmds) != reset_pmds) { DPRINT(("invalid reset_pmds 0x%lx for pmc%u\n", reset_pmds, cnum)); goto error; } @@ -2935,7 +2929,7 @@ * execute write checker, if any */ if (PMC_WR_FUNC(cnum)) { - ret = PMC_WR_FUNC(cnum)(ctx->ctx_task, ctx, cnum, &value, regs); + ret = PMC_WR_FUNC(cnum)(task, ctx, cnum, &value, regs); if (ret) goto error; ret = -EINVAL; } @@ -2997,7 +2991,7 @@ * * The value in ctx_pmcs[] can only be changed in pfm_write_pmcs(). * - * The value in t->pmc[] may be modified on overflow, i.e., when + * The value in thread->pmcs[] may be modified on overflow, i.e., when * monitoring needs to be stopped. */ if (is_monitor) CTX_USED_MONITOR(ctx, 1UL << cnum); @@ -3056,11 +3050,6 @@ return 0; error: PFM_REG_RETFLAG_SET(req->reg_flags, PFM_REG_RETFL_EINVAL); - - req->reg_flags = PFM_REG_RETFL_EINVAL; - - DPRINT(("pmc[%u]=0x%lx error %d\n", cnum, value, ret)); - return ret; } @@ -3068,6 +3057,7 @@ pfm_write_pmds(pfm_context_t *ctx, void *arg, int count, struct pt_regs *regs) { struct thread_struct *thread = NULL; + struct task_struct *task; pfarg_reg_t *req = (pfarg_reg_t *)arg; unsigned long value, hw_value, ovfl_mask; unsigned int cnum; @@ -3080,25 +3070,26 @@ is_loaded = state == PFM_CTX_LOADED ? 1 : 0; is_system = ctx->ctx_fl_system; ovfl_mask = pmu_conf.ovfl_val; + task = ctx->ctx_task; - if (state == PFM_CTX_TERMINATED || state == PFM_CTX_ZOMBIE) return -EINVAL; + if (unlikely(state == PFM_CTX_TERMINATED || state == PFM_CTX_ZOMBIE)) return -EINVAL; /* * on both UP and SMP, we can only write to the PMC when the task is * the owner of the local PMU. */ - if (is_loaded) { - thread = &ctx->ctx_task->thread; + if (likely(is_loaded)) { + thread = &task->thread; /* * In system wide and when the context is loaded, access can only happen * when the caller is running on the CPU being monitored by the session. * It does not have to be the owner (ctx_task) of the context per se. */ - if (is_system && ctx->ctx_cpu != smp_processor_id()) { + if (unlikely(is_system && ctx->ctx_cpu != smp_processor_id())) { DPRINT(("[%d] should be running on CPU%d\n", current->pid, ctx->ctx_cpu)); return -EBUSY; } - can_access_pmu = GET_PMU_OWNER() == ctx->ctx_task || is_system ? 1 : 0; + can_access_pmu = GET_PMU_OWNER() == task || is_system ? 1 : 0; } for (i = 0; i < count; i++, req++) { @@ -3118,7 +3109,7 @@ if (PMD_WR_FUNC(cnum)) { unsigned long v = value; - ret = PMD_WR_FUNC(cnum)(ctx->ctx_task, ctx, cnum, &v, regs); + ret = PMD_WR_FUNC(cnum)(task, ctx, cnum, &v, regs); if (ret) goto abort_mission; value = v; @@ -3243,16 +3234,6 @@ * for now, we have only one possibility for error */ PFM_REG_RETFLAG_SET(req->reg_flags, PFM_REG_RETFL_EINVAL); - - /* - * we change the return value to EFAULT in case we cannot write register return code. - * The caller first must correct this error, then a resubmission of the request will - * eventually yield the EINVAL. - */ - req->reg_flags = PFM_REG_RETFL_EINVAL; - - DPRINT(("pmd[%u]=0x%lx ret %d\n", cnum, value, ret)); - return ret; } @@ -3269,11 +3250,12 @@ pfm_read_pmds(pfm_context_t *ctx, void *arg, int count, struct pt_regs *regs) { struct thread_struct *thread = NULL; - unsigned long val = 0UL, lval, ovfl_mask; + struct task_struct *task; + unsigned long val = 0UL, lval, ovfl_mask, sval; pfarg_reg_t *req = (pfarg_reg_t *)arg; unsigned int cnum, reg_flags = 0; int i, can_access_pmu = 0, state; - int is_loaded, is_system; + int is_loaded, is_system, is_counting; int ret = -EINVAL; /* @@ -3285,32 +3267,33 @@ is_loaded = state == PFM_CTX_LOADED ? 1 : 0; is_system = ctx->ctx_fl_system; ovfl_mask = pmu_conf.ovfl_val; + task = ctx->ctx_task; if (state == PFM_CTX_ZOMBIE) return -EINVAL; - if (is_loaded) { - thread = &ctx->ctx_task->thread; + if (likely(is_loaded)) { + thread = &task->thread; /* * In system wide and when the context is loaded, access can only happen * when the caller is running on the CPU being monitored by the session. * It does not have to be the owner (ctx_task) of the context per se. */ - if (is_system && ctx->ctx_cpu != smp_processor_id()) { + if (unlikely(is_system && ctx->ctx_cpu != smp_processor_id())) { DPRINT(("[%d] should be running on CPU%d\n", current->pid, ctx->ctx_cpu)); return -EBUSY; } /* * this can be true when not self-monitoring only in UP */ - can_access_pmu = GET_PMU_OWNER() == ctx->ctx_task || is_system ? 1 : 0; + can_access_pmu = GET_PMU_OWNER() == task || is_system ? 1 : 0; if (can_access_pmu) ia64_srlz_d(); } - DPRINT(("enter loaded=%d access_pmu=%d ctx_state=%d\n", + DPRINT(("loaded=%d access_pmu=%d ctx_state=%d\n", is_loaded, can_access_pmu, - ctx->ctx_state)); + state)); /* * on both UP and SMP, we can only read the PMD from the hardware register when @@ -3319,11 +3302,10 @@ for (i = 0; i < count; i++, req++) { - lval = 0UL; cnum = req->reg_num; reg_flags = req->reg_flags; - if (!PMD_IS_IMPL(cnum)) goto error; + if (unlikely(!PMD_IS_IMPL(cnum))) goto error; /* * we can only read the register that we use. That includes * the one we explicitely initialize AND the one we want included @@ -3332,7 +3314,11 @@ * Having this restriction allows optimization in the ctxsw routine * without compromising security (leaks) */ - if (!CTX_IS_USED_PMD(ctx, cnum)) goto error; + if (unlikely(!CTX_IS_USED_PMD(ctx, cnum))) goto error; + + sval = ctx->ctx_pmds[cnum].val; + lval = ctx->ctx_pmds[cnum].lval; + is_counting = PMD_IS_COUNTING(cnum); /* * If the task is not the current one, then we check if the @@ -3347,23 +3333,21 @@ * if context is zombie, then task does not exist anymore. * In this case, we use the full value saved in the context (pfm_flush_regs()). */ - val = state == PFM_CTX_LOADED ? thread->pmds[cnum] : 0UL; + val = is_loaded ? thread->pmds[cnum] : 0UL; } - if (PMD_IS_COUNTING(cnum)) { + if (is_counting) { /* * XXX: need to check for overflow when loaded */ val &= ovfl_mask; - val += ctx->ctx_pmds[cnum].val; - - lval = ctx->ctx_pmds[cnum].lval; + val += sval; } /* * execute read checker, if any */ - if (PMD_RD_FUNC(cnum)) { + if (unlikely(PMD_RD_FUNC(cnum))) { unsigned long v = val; ret = PMD_RD_FUNC(cnum)(ctx->ctx_task, ctx, cnum, &v, regs); if (ret) goto error; @@ -3373,12 +3357,7 @@ PFM_REG_RETFLAG_SET(reg_flags, 0); - DPRINT(("pmd[%u]=0x%lx loaded=%d access_pmu=%d ctx_state=%d\n", - cnum, - val, - is_loaded, - can_access_pmu, - ctx->ctx_state)); + DPRINT(("pmd[%u]=0x%lx\n", cnum, val)); /* * update register return value, abort all if problem during copy. @@ -3393,12 +3372,7 @@ return 0; error: - PFM_REG_RETFLAG_SET(reg_flags, PFM_REG_RETFL_EINVAL); - - req->reg_flags = PFM_REG_RETFL_EINVAL; - - DPRINT(("error pmd[%u]=0x%lx\n", cnum, val)); - + PFM_REG_RETFLAG_SET(req->reg_flags, PFM_REG_RETFL_EINVAL); return ret; } @@ -3628,7 +3602,7 @@ prefetch(ctx->ctx_smpl_hdr); rst_ctrl.bits.mask_monitoring = 0; - rst_ctrl.bits.reset_ovfl_pmds = 1; + rst_ctrl.bits.reset_ovfl_pmds = 0; if (state == PFM_CTX_LOADED) ret = pfm_buf_fmt_restart_active(fmt, task, &rst_ctrl, ctx->ctx_smpl_hdr, regs); @@ -3748,6 +3722,7 @@ pfm_write_ibr_dbr(int mode, pfm_context_t *ctx, void *arg, int count, struct pt_regs *regs) { struct thread_struct *thread = NULL; + struct task_struct *task; pfarg_dbreg_t *req = (pfarg_dbreg_t *)arg; unsigned long flags; dbreg_t dbreg; @@ -3762,6 +3737,7 @@ state = ctx->ctx_state; is_loaded = state == PFM_CTX_LOADED ? 1 : 0; is_system = ctx->ctx_fl_system; + task = ctx->ctx_task; if (state == PFM_CTX_TERMINATED || state == PFM_CTX_ZOMBIE) return -EINVAL; @@ -3770,17 +3746,17 @@ * the owner of the local PMU. */ if (is_loaded) { - thread = &ctx->ctx_task->thread; + thread = &task->thread; /* * In system wide and when the context is loaded, access can only happen * when the caller is running on the CPU being monitored by the session. * It does not have to be the owner (ctx_task) of the context per se. */ - if (is_system && ctx->ctx_cpu != smp_processor_id()) { + if (unlikely(is_system && ctx->ctx_cpu != smp_processor_id())) { DPRINT(("[%d] should be running on CPU%d\n", current->pid, ctx->ctx_cpu)); return -EBUSY; } - can_access_pmu = GET_PMU_OWNER() == ctx->ctx_task || is_system ? 1 : 0; + can_access_pmu = GET_PMU_OWNER() == task || is_system ? 1 : 0; } /* @@ -3796,7 +3772,7 @@ * don't bother if we are loaded and task is being debugged */ if (is_loaded && (thread->flags & IA64_THREAD_DBG_VALID) != 0) { - DPRINT(("debug registers already in use for [%d]\n", ctx->ctx_task->pid)); + DPRINT(("debug registers already in use for [%d]\n", task->pid)); return -EBUSY; } @@ -3837,7 +3813,7 @@ * is shared by all processes running on it */ if (first_time && can_access_pmu) { - DPRINT(("[%d] clearing ibrs, dbrs\n", ctx->ctx_task->pid)); + DPRINT(("[%d] clearing ibrs, dbrs\n", task->pid)); for (i=0; i < pmu_conf.num_ibrs; i++) { ia64_set_ibr(i, 0UL); ia64_srlz_i(); @@ -3860,7 +3836,7 @@ ret = -EINVAL; - if ((mode == PFM_CODE_RR && !IBR_IS_IMPL(rnum)) || ((mode == PFM_DATA_RR) && !DBR_IS_IMPL(rnum))) { + if ((mode == PFM_CODE_RR && rnum >= PFM_NUM_IBRS) || ((mode == PFM_DATA_RR) && rnum >= PFM_NUM_DBRS)) { DPRINT(("invalid register %u val=0x%lx mode=%d i=%d count=%d\n", rnum, dbreg.val, mode, i, count)); @@ -4434,6 +4410,7 @@ struct task_struct *task = PFM_CTX_TASK(ctx); struct pt_regs *tregs; int state, is_system; + int ret; DPRINT(("ctx_state=%d task [%d]\n", ctx->ctx_state, task ? task->pid : -1)); @@ -4451,7 +4428,8 @@ /* * clear psr and dcr bits */ - pfm_stop(ctx, NULL, 0, regs); + ret = pfm_stop(ctx, NULL, 0, regs); + if (ret) return ret; ctx->ctx_state = state = PFM_CTX_UNLOADED; @@ -4760,37 +4738,45 @@ void *args_k = NULL; long ret; /* will expand int return types */ size_t base_sz, sz, xtra_sz = 0; - int narg, completed_args = 0, call_made = 0; + int narg, completed_args = 0, call_made = 0, cmd_flags; + int (*func)(pfm_context_t *ctx, void *arg, int count, struct pt_regs *regs); + int (*getsize)(void *arg, size_t *sz); #define PFM_MAX_ARGSIZE 4096 /* - * reject any call if perfmon was disabled at initialization time - mask*/ - if (PFM_IS_DISABLED()) return -ENOSYS; + * reject any call if perfmon was disabled at initialization + */ + if (unlikely(PFM_IS_DISABLED())) return -ENOSYS; + + if (unlikely(cmd < 0 || cmd >= PFM_CMD_COUNT)) { + DPRINT(("[%d] invalid cmd=%d\n", current->pid, cmd)); + return -EINVAL; + } + + func = pfm_cmd_tab[cmd].cmd_func; + narg = pfm_cmd_tab[cmd].cmd_narg; + base_sz = pfm_cmd_tab[cmd].cmd_argsize; + getsize = pfm_cmd_tab[cmd].cmd_getsize; + cmd_flags = pfm_cmd_tab[cmd].cmd_flags; - if (unlikely(PFM_CMD_IS_VALID(cmd) == 0)) { + if (unlikely(func == NULL)) { DPRINT(("[%d] invalid cmd=%d\n", current->pid, cmd)); return -EINVAL; } - DPRINT(("cmd=%s idx=%d valid=%d narg=0x%x argsz=%lu count=%d\n", + DPRINT(("cmd=%s idx=%d narg=0x%x argsz=%lu count=%d\n", PFM_CMD_NAME(cmd), - PFM_CMD_IDX(cmd), - PFM_CMD_IS_VALID(cmd), - PFM_CMD_NARG(cmd), - PFM_CMD_ARG_SIZE(cmd), + cmd, + narg, + base_sz, count)); /* * check if number of arguments matches what the command expects */ - narg = PFM_CMD_NARG(cmd); - if ((narg == PFM_CMD_ARG_MANY && count <= 0) || (narg > 0 && narg != count)) + if (unlikely((narg == PFM_CMD_ARG_MANY && count <= 0) || (narg > 0 && narg != count))) return -EINVAL; - /* get single argument size */ - base_sz = PFM_CMD_ARG_SIZE(cmd); - restart_args: sz = xtra_sz + base_sz*count; /* @@ -4804,7 +4790,7 @@ /* * allocate default-sized argument buffer */ - if (count && args_k == NULL) { + if (likely(count && args_k == NULL)) { args_k = kmalloc(PFM_MAX_ARGSIZE, GFP_KERNEL); if (args_k == NULL) return -ENOMEM; } @@ -4824,11 +4810,11 @@ /* * check if command supports extra parameters */ - if (completed_args == 0 && PFM_CMD_GETSIZE(cmd)) { + if (completed_args == 0 && getsize) { /* * get extra parameters size (based on main argument) */ - ret = PFM_CMD_GETSIZE(cmd)(args_k, &xtra_sz); + ret = (*getsize)(args_k, &xtra_sz); if (ret) goto error_args; completed_args = 1; @@ -4836,45 +4822,45 @@ DPRINT(("[%d] restart_args sz=%lu xtra_sz=%lu\n", current->pid, sz, xtra_sz)); /* retry if necessary */ - if (xtra_sz) goto restart_args; + if (likely(xtra_sz)) goto restart_args; } - if (PFM_CMD_USE_FD(cmd)) { + if (unlikely((cmd_flags & PFM_CMD_FD) == 0)) goto skip_fd; - ret = -EBADF; - - file = fget(fd); - if (file == NULL) { - DPRINT(("[%d] invalid fd %d\n", current->pid, fd)); - goto error_args; - } - if (PFM_IS_FILE(file) == 0) { - DPRINT(("[%d] fd %d not related to perfmon\n", current->pid, fd)); - goto error_args; - } + ret = -EBADF; + file = fget(fd); + if (unlikely(file == NULL)) { + DPRINT(("[%d] invalid fd %d\n", current->pid, fd)); + goto error_args; + } + if (unlikely(PFM_IS_FILE(file) == 0)) { + DPRINT(("[%d] fd %d not related to perfmon\n", current->pid, fd)); + goto error_args; + } - ctx = (pfm_context_t *)file->private_data; - if (ctx == NULL) { - DPRINT(("[%d] no context for fd %d\n", current->pid, fd)); - goto error_args; - } + ctx = (pfm_context_t *)file->private_data; + if (unlikely(ctx == NULL)) { + DPRINT(("[%d] no context for fd %d\n", current->pid, fd)); + goto error_args; + } + prefetch(&ctx->ctx_state); - PROTECT_CTX(ctx, flags); + PROTECT_CTX(ctx, flags); - /* - * check task is stopped - */ - ret = pfm_check_task_state(ctx, cmd, flags); - if (ret) goto abort_locked; - } + /* + * check task is stopped + */ + ret = pfm_check_task_state(ctx, cmd, flags); + if (unlikely(ret)) goto abort_locked; - ret = (*pfm_cmd_tab[PFM_CMD_IDX(cmd)].cmd_func)(ctx, args_k, count, regs); +skip_fd: + ret = (*func)(ctx, args_k, count, regs); call_made = 1; abort_locked: - if (ctx) { + if (likely(ctx)) { DPRINT(("[%d] context unlocked\n", current->pid)); UNPROTECT_CTX(ctx, flags); fput(file); @@ -4907,7 +4893,7 @@ if (CTX_HAS_SMPL(ctx)) { rst_ctrl.bits.mask_monitoring = 0; - rst_ctrl.bits.reset_ovfl_pmds = 1; + rst_ctrl.bits.reset_ovfl_pmds = 0; if (state == PFM_CTX_LOADED) ret = pfm_buf_fmt_restart_active(fmt, current, &rst_ctrl, ctx->ctx_smpl_hdr, regs); @@ -5096,7 +5082,7 @@ msg->pfm_ovfl_msg.msg_ovfl_pmds[1] = 0UL; msg->pfm_ovfl_msg.msg_ovfl_pmds[2] = 0UL; msg->pfm_ovfl_msg.msg_ovfl_pmds[3] = 0UL; - msg->pfm_ovfl_msg.msg_tstamp = ia64_get_itc(); /* relevant on UP only */ + msg->pfm_ovfl_msg.msg_tstamp = 0UL; } DPRINT(("ovfl msg: msg=%p no_msg=%d fd=%d pid=%d ovfl_pmds=0x%lx\n", @@ -5119,10 +5105,12 @@ printk(KERN_ERR "perfmon: pfm_end_notify_user no more notification msgs\n"); return -1; } + /* no leak */ + memset(msg, 0, sizeof(*msg)); msg->pfm_end_msg.msg_type = PFM_MSG_END; msg->pfm_end_msg.msg_ctx_fd = ctx->ctx_fd; - msg->pfm_ovfl_msg.msg_tstamp = ia64_get_itc(); /* relevant on UP only */ + msg->pfm_ovfl_msg.msg_tstamp = 0UL; DPRINT(("end msg: msg=%p no_msg=%d ctx_fd=%d pid=%d\n", msg, @@ -5141,8 +5129,8 @@ { pfm_ovfl_arg_t ovfl_arg; unsigned long mask; - unsigned long old_val, ovfl_val; - unsigned long ovfl_notify = 0UL, ovfl_pmds = 0UL, smpl_pmds = 0UL; + unsigned long old_val, ovfl_val, new_val; + unsigned long ovfl_notify = 0UL, ovfl_pmds = 0UL, smpl_pmds = 0UL, reset_pmds; unsigned long tstamp; pfm_ovfl_ctrl_t ovfl_ctrl; unsigned int i, has_smpl; @@ -5155,21 +5143,19 @@ */ if (unlikely((pmc0 & 0x1) == 0)) goto sanity_check; - tstamp = ia64_get_itc(); - + tstamp = ia64_get_itc(); mask = pmc0 >> PMU_FIRST_COUNTER; ovfl_val = pmu_conf.ovfl_val; + has_smpl = CTX_HAS_SMPL(ctx); DPRINT_ovfl(("pmc0=0x%lx pid=%d iip=0x%lx, %s " - "used_pmds=0x%lx reload_pmcs=0x%lx\n", + "used_pmds=0x%lx\n", pmc0, task ? task->pid: -1, (regs ? regs->cr_iip : 0), CTX_OVFL_NOBLOCK(ctx) ? "nonblocking" : "blocking", - ctx->ctx_used_pmds[0], - ctx->ctx_reload_pmcs[0])); + ctx->ctx_used_pmds[0])); - has_smpl = CTX_HAS_SMPL(ctx); /* * first we update the virtual counters @@ -5180,29 +5166,31 @@ /* skip pmd which did not overflow */ if ((mask & 0x1) == 0) continue; - DPRINT_ovfl(("pmd[%d] overflowed hw_pmd=0x%lx ctx_pmd=0x%lx\n", - i, ia64_get_pmd(i), ctx->ctx_pmds[i].val)); - /* * Note that the pmd is not necessarily 0 at this point as qualified events * may have happened before the PMU was frozen. The residual count is not * taken into consideration here but will be with any read of the pmd via * pfm_read_pmds(). */ - old_val = ctx->ctx_pmds[i].val; - ctx->ctx_pmds[i].val += 1 + ovfl_val; + old_val = new_val = ctx->ctx_pmds[i].val; + new_val += 1 + ovfl_val; + ctx->ctx_pmds[i].val = new_val; /* * check for overflow condition */ - if (likely(old_val > ctx->ctx_pmds[i].val)) { + if (likely(old_val > new_val)) { ovfl_pmds |= 1UL << i; if (PMC_OVFL_NOTIFY(ctx, i)) ovfl_notify |= 1UL << i; } - DPRINT_ovfl(("ctx_pmd[%d].val=0x%lx old_val=0x%lx pmd=0x%lx ovfl_pmds=0x%lx ovfl_notify=0x%lx smpl_pmds=0x%lx\n", - i, ctx->ctx_pmds[i].val, old_val, - ia64_get_pmd(i) & ovfl_val, ovfl_pmds, ovfl_notify, smpl_pmds)); + DPRINT_ovfl(("ctx_pmd[%d].val=0x%lx old_val=0x%lx pmd=0x%lx ovfl_pmds=0x%lx ovfl_notify=0x%lx\n", + i, + new_val, + old_val, + ia64_get_pmd(i) & ovfl_val, + ovfl_pmds, + ovfl_notify)); } /* @@ -5214,6 +5202,7 @@ * reset all control bits */ ovfl_ctrl.val = 0; + reset_pmds = 0UL; /* * if a sampling format module exists, then we "cache" the overflow by @@ -5225,7 +5214,7 @@ int j, k, ret = 0; int this_cpu = smp_processor_id(); - pmd_mask = ovfl_pmds >> PMU_FIRST_COUNTER; + pmd_mask = ovfl_pmds >> PMU_FIRST_COUNTER; prefetch(ctx->ctx_smpl_hdr); @@ -5275,7 +5264,10 @@ ovfl_ctrl.bits.notify_user |= ovfl_arg.ovfl_ctrl.bits.notify_user; ovfl_ctrl.bits.block_task |= ovfl_arg.ovfl_ctrl.bits.block_task; ovfl_ctrl.bits.mask_monitoring |= ovfl_arg.ovfl_ctrl.bits.mask_monitoring; - ovfl_ctrl.bits.reset_ovfl_pmds |= ovfl_arg.ovfl_ctrl.bits.reset_ovfl_pmds; /* yes or no */ + /* + * build the bitmask of pmds to reset now + */ + if (ovfl_arg.ovfl_ctrl.bits.reset_ovfl_pmds) reset_pmds |= mask; pfm_stats[this_cpu].pfm_smpl_handler_cycles += end_cycles - start_cycles; } @@ -5287,6 +5279,10 @@ current->pid, pmd_mask<pid, + ovfl_pmds, + reset_pmds)); /* - * if we (still) have some overflowed PMD but no notification is requested - * then we use the short reset period. + * reset the requested PMD registers using the short reset values */ - if (ovfl_ctrl.bits.reset_ovfl_pmds) { - unsigned long bm = ovfl_pmds; + if (reset_pmds) { + unsigned long bm = reset_pmds; pfm_reset_regs(ctx, &bm, PFM_PMD_SHORT_RESET); } diff -Nru a/arch/ia64/kernel/perfmon_default_smpl.c b/arch/ia64/kernel/perfmon_default_smpl.c --- a/arch/ia64/kernel/perfmon_default_smpl.c Sun Feb 29 12:54:28 2004 +++ b/arch/ia64/kernel/perfmon_default_smpl.c Sun Feb 29 12:54:28 2004 @@ -178,6 +178,7 @@ ent->tstamp = stamp; ent->cpu = smp_processor_id(); ent->set = arg->active_set; + ent->tgid = current->tgid; /* * selectively store PMDs in increasing index number diff -Nru a/arch/ia64/kernel/process.c b/arch/ia64/kernel/process.c --- a/arch/ia64/kernel/process.c Sun Feb 29 12:54:28 2004 +++ b/arch/ia64/kernel/process.c Sun Feb 29 12:54:28 2004 @@ -259,10 +259,12 @@ * * We get here through the following call chain: * - * - * sys_clone - * do_fork - * copy_thread + * from user-level: from kernel: + * + * + * sys_clone : + * do_fork do_fork + * copy_thread copy_thread * * This means that the stack layout is as follows: * @@ -276,9 +278,6 @@ * | | <-- sp (lowest addr) * +---------------------+ * - * Note: if we get called through kernel_thread() then the memory above "(highest addr)" - * is valid kernel stack memory that needs to be copied as well. - * * Observe that we copy the unat values that are in pt_regs and switch_stack. Spilling an * integer to address X causes bit N in ar.unat to be set to the NaT bit of the register, * with N=(X & 0x1ff)/8. Thus, copying the unat value preserves the NaT bits ONLY if the @@ -291,9 +290,9 @@ unsigned long user_stack_base, unsigned long user_stack_size, struct task_struct *p, struct pt_regs *regs) { - unsigned long rbs, child_rbs, rbs_size, stack_offset, stack_top, stack_used; - struct switch_stack *child_stack, *stack; extern char ia64_ret_from_clone, ia32_ret_from_clone; + struct switch_stack *child_stack, *stack; + unsigned long rbs, child_rbs, rbs_size; struct pt_regs *child_ptregs; int retval = 0; @@ -306,16 +305,13 @@ return 0; #endif - stack_top = (unsigned long) current + IA64_STK_OFFSET; stack = ((struct switch_stack *) regs) - 1; - stack_used = stack_top - (unsigned long) stack; - stack_offset = IA64_STK_OFFSET - stack_used; - child_stack = (struct switch_stack *) ((unsigned long) p + stack_offset); - child_ptregs = (struct pt_regs *) (child_stack + 1); + child_ptregs = (struct pt_regs *) ((unsigned long) p + IA64_STK_OFFSET) - 1; + child_stack = (struct switch_stack *) child_ptregs - 1; /* copy parent's switch_stack & pt_regs to child: */ - memcpy(child_stack, stack, stack_used); + memcpy(child_stack, stack, sizeof(*child_ptregs) + sizeof(*child_stack)); rbs = (unsigned long) current + IA64_RBS_OFFSET; child_rbs = (unsigned long) p + IA64_RBS_OFFSET; @@ -324,7 +320,7 @@ /* copy the parent's register backing store to the child: */ memcpy((void *) child_rbs, (void *) rbs, rbs_size); - if (user_mode(child_ptregs)) { + if (likely(user_mode(child_ptregs))) { if ((clone_flags & CLONE_SETTLS) && !IS_IA32_PROCESS(regs)) child_ptregs->r13 = regs->r16; /* see sys_clone2() in entry.S */ if (user_stack_base) { @@ -341,14 +337,14 @@ * been taken care of by the caller of sys_clone() * already. */ - child_ptregs->r12 = (unsigned long) (child_ptregs + 1); /* kernel sp */ + child_ptregs->r12 = (unsigned long) child_ptregs - 16; /* kernel sp */ child_ptregs->r13 = (unsigned long) p; /* set `current' pointer */ } + child_stack->ar_bspstore = child_rbs + rbs_size; if (IS_IA32_PROCESS(regs)) child_stack->b0 = (unsigned long) &ia32_ret_from_clone; else child_stack->b0 = (unsigned long) &ia64_ret_from_clone; - child_stack->ar_bspstore = child_rbs + rbs_size; /* copy parts of thread_struct: */ p->thread.ksp = (unsigned long) child_stack - 16; @@ -358,8 +354,8 @@ * therefore we must specify them explicitly here and not include them in * IA64_PSR_BITS_TO_CLEAR. */ - child_ptregs->cr_ipsr = ((child_ptregs->cr_ipsr | IA64_PSR_BITS_TO_SET) - & ~(IA64_PSR_BITS_TO_CLEAR | IA64_PSR_PP | IA64_PSR_UP)); + child_ptregs->cr_ipsr = ((child_ptregs->cr_ipsr | IA64_PSR_BITS_TO_SET) + & ~(IA64_PSR_BITS_TO_CLEAR | IA64_PSR_PP | IA64_PSR_UP)); /* * NOTE: The calling convention considers all floating point @@ -578,27 +574,43 @@ pid_t kernel_thread (int (*fn)(void *), void *arg, unsigned long flags) { - struct task_struct *parent = current; - int result; - pid_t tid; + extern void ia64_invoke_kernel_thread_helper (void); + unsigned long *helper_fptr = (unsigned long *) &ia64_invoke_kernel_thread_helper; + struct { + struct switch_stack sw; + struct pt_regs pt; + } regs; + + memset(®s, 0, sizeof(regs)); + regs.pt.cr_iip = helper_fptr[0]; /* set entry point (IP) */ + regs.pt.r1 = helper_fptr[1]; /* set GP */ + regs.pt.r9 = (unsigned long) fn; /* 1st argument */ + regs.pt.r11 = (unsigned long) arg; /* 2nd argument */ + /* Preserve PSR bits, except for bits 32-34 and 37-45, which we can't read. */ + regs.pt.cr_ipsr = ia64_getreg(_IA64_REG_PSR) | IA64_PSR_BN; + regs.pt.cr_ifs = 1UL << 63; /* mark as valid, empty frame */ + regs.sw.ar_fpsr = regs.pt.ar_fpsr = ia64_getreg(_IA64_REG_AR_FPSR); + regs.sw.ar_bspstore = (unsigned long) current + IA64_RBS_OFFSET; + + return do_fork(flags | CLONE_VM | CLONE_UNTRACED, 0, ®s.pt, 0, NULL, NULL); +} +EXPORT_SYMBOL(kernel_thread); - tid = clone(flags | CLONE_VM | CLONE_UNTRACED, 0); - if (parent != current) { +/* This gets called from kernel_thread() via ia64_invoke_thread_helper(). */ +int +kernel_thread_helper (int (*fn)(void *), void *arg) +{ #ifdef CONFIG_IA32_SUPPORT - if (IS_IA32_PROCESS(ia64_task_regs(current))) { - /* A kernel thread is always a 64-bit process. */ - current->thread.map_base = DEFAULT_MAP_BASE; - current->thread.task_size = DEFAULT_TASK_SIZE; - ia64_set_kr(IA64_KR_IO_BASE, current->thread.old_iob); - ia64_set_kr(IA64_KR_TSSD, current->thread.old_k1); - } -#endif - result = (*fn)(arg); - _exit(result); + if (IS_IA32_PROCESS(ia64_task_regs(current))) { + /* A kernel thread is always a 64-bit process. */ + current->thread.map_base = DEFAULT_MAP_BASE; + current->thread.task_size = DEFAULT_TASK_SIZE; + ia64_set_kr(IA64_KR_IO_BASE, current->thread.old_iob); + ia64_set_kr(IA64_KR_TSSD, current->thread.old_k1); } - return tid; +#endif + return (*fn)(arg); } -EXPORT_SYMBOL(kernel_thread); /* * Flush thread state. This is called when a thread does an execve(). diff -Nru a/arch/ia64/mm/hugetlbpage.c b/arch/ia64/mm/hugetlbpage.c --- a/arch/ia64/mm/hugetlbpage.c Sun Feb 29 12:54:28 2004 +++ b/arch/ia64/mm/hugetlbpage.c Sun Feb 29 12:54:28 2004 @@ -1,7 +1,11 @@ /* * IA-64 Huge TLB Page Support for Kernel. * - * Copyright (C) 2002, Rohit Seth + * Copyright (C) 2002-2004 Rohit Seth + * Copyright (C) 2003-2004 Ken Chen + * + * Sep, 2003: add numa support + * Feb, 2004: dynamic hugetlb page size via boot parameter */ #include @@ -18,11 +22,10 @@ #include #include -#define TASK_HPAGE_BASE (REGION_HPAGE << REGION_SHIFT) - static long htlbpagemem; int htlbpage_max; static long htlbzone_pages; +unsigned int hpage_shift=HPAGE_SHIFT_DEFAULT; static struct list_head hugepage_freelists[MAX_NUMNODES]; static spinlock_t htlbpage_lock = SPIN_LOCK_UNLOCKED; @@ -407,7 +410,7 @@ return -EINVAL; /* This code assumes that REGION_HPAGE != 0. */ if ((REGION_NUMBER(addr) != REGION_HPAGE) || (addr & (HPAGE_SIZE - 1))) - addr = TASK_HPAGE_BASE; + addr = HPAGE_REGION_BASE; else addr = ALIGN(addr, HPAGE_SIZE); for (vmm = find_vma(current->mm, addr); ; vmm = vmm->vm_next) { @@ -520,6 +523,35 @@ } __setup("hugepages=", hugetlb_setup); +static int __init hugetlb_setup_sz(char *str) +{ + u64 tr_pages; + unsigned long long size; + + if (ia64_pal_vm_page_size(&tr_pages, NULL) != 0) + /* + * shouldn't happen, but just in case. + */ + tr_pages = 0x15557000UL; + + size = memparse(str, &str); + if (*str || (size & (size-1)) || !(tr_pages & size) || + size <= PAGE_SIZE || + size >= (1UL << PAGE_SHIFT << MAX_ORDER)) { + printk(KERN_WARNING "Invalid huge page size specified\n"); + return 1; + } + + hpage_shift = __ffs(size); + /* + * boot cpu already executed ia64_mmu_init, and has HPAGE_SHIFT_DEFAULT + * override here with new page shift. + */ + ia64_set_rr(HPAGE_REGION_BASE, hpage_shift << 2); + return 1; +} +__setup("hugepagesz=", hugetlb_setup_sz); + static int __init hugetlb_init(void) { int i; @@ -540,7 +572,7 @@ printk("Total HugeTLB memory allocated, %ld\n", htlbpagemem); return 0; } -module_init(hugetlb_init); +__initcall(hugetlb_init); int hugetlb_report_meminfo(char *buf) { diff -Nru a/arch/ia64/mm/init.c b/arch/ia64/mm/init.c --- a/arch/ia64/mm/init.c Sun Feb 29 12:54:28 2004 +++ b/arch/ia64/mm/init.c Sun Feb 29 12:54:28 2004 @@ -342,6 +342,10 @@ ia64_tlb_init(); +#ifdef CONFIG_HUGETLB_PAGE + ia64_set_rr(HPAGE_REGION_BASE, HPAGE_SHIFT << 2); +#endif + #ifdef CONFIG_IA64_MCA cpu = smp_processor_id(); diff -Nru a/arch/ppc64/kernel/prom.c b/arch/ppc64/kernel/prom.c --- a/arch/ppc64/kernel/prom.c Sun Feb 29 12:54:28 2004 +++ b/arch/ppc64/kernel/prom.c Sun Feb 29 12:54:28 2004 @@ -516,6 +516,9 @@ return mem; } +#ifdef CONFIG_PMAC_DART +static int dart_force_on; +#endif static unsigned long __init prom_initialize_lmb(unsigned long mem) @@ -539,10 +542,12 @@ prom_print(opt); prom_print(RELOC("\n")); opt += 6; - while(*opt && *opt == ' ') + while (*opt && *opt == ' ') opt++; if (!strncmp(opt, RELOC("off"), 3)) nodart = 1; + else if (!strncmp(opt, RELOC("force"), 5)) + RELOC(dart_force_on) = 1; } #else nodart = 1; @@ -763,8 +768,10 @@ extern unsigned long dart_tablebase; extern unsigned long dart_tablesize; - /* Only reserve DART space if machine has more than 2Gb of RAM */ - if (lmb_end_of_DRAM() <= 0x80000000ull) + /* Only reserve DART space if machine has more than 2GB of RAM + * or if requested with iommu=on on cmdline. + */ + if (lmb_end_of_DRAM() <= 0x80000000ull && !RELOC(dart_force_on)) return; /* 512 pages is max DART tablesize. */ diff -Nru a/arch/x86_64/kernel/x8664_ksyms.c b/arch/x86_64/kernel/x8664_ksyms.c --- a/arch/x86_64/kernel/x8664_ksyms.c Sun Feb 29 12:54:28 2004 +++ b/arch/x86_64/kernel/x8664_ksyms.c Sun Feb 29 12:54:28 2004 @@ -196,6 +196,7 @@ #ifdef CONFIG_SMP EXPORT_SYMBOL(cpu_sibling_map); +EXPORT_SYMBOL(smp_num_siblings); #endif extern void do_softirq_thunk(void); diff -Nru a/drivers/mtd/afs.c b/drivers/mtd/afs.c --- a/drivers/mtd/afs.c Sun Feb 29 12:54:28 2004 +++ b/drivers/mtd/afs.c Sun Feb 29 12:54:28 2004 @@ -57,6 +57,17 @@ u32 checksum; /* Image checksum (inc. this struct) */ }; +static u32 word_sum(void *words, int num) +{ + u32 *p = words; + u32 sum = 0; + + while (num--) + sum += *p++; + + return sum; +} + static int afs_read_footer(struct mtd_info *mtd, u_int *img_start, u_int *iis_start, u_int off, u_int mask) @@ -85,6 +96,12 @@ ret = 0; /* + * Check the checksum. + */ + if (word_sum(&fs, sizeof(fs) / sizeof(u32)) != 0xffffffff) + ret = 0; + + /* * Don't touch the SIB. */ if (fs.type == 2) @@ -114,16 +131,35 @@ afs_read_iis(struct mtd_info *mtd, struct image_info_struct *iis, u_int ptr) { size_t sz; - int ret; + int ret, i; memset(iis, 0, sizeof(*iis)); ret = mtd->read(mtd, ptr, sizeof(*iis), &sz, (u_char *) iis); - if (ret >= 0 && sz != sizeof(*iis)) - ret = -EINVAL; if (ret < 0) - printk(KERN_ERR "AFS: mtd read failed at 0x%x: %d\n", - ptr, ret); + goto failed; + + if (sz != sizeof(*iis)) { + ret = -EINVAL; + goto failed; + } + + ret = 0; + + /* + * Validate the name - it must be NUL terminated. + */ + for (i = 0; i < sizeof(iis->name); i++) + if (iis->name[i] == '\0') + break; + if (i < sizeof(iis->name)) + ret = 1; + + return ret; + + failed: + printk(KERN_ERR "AFS: mtd read failed at 0x%x: %d\n", + ptr, ret); return ret; } @@ -160,6 +196,8 @@ ret = afs_read_iis(mtd, &iis, iis_ptr); if (ret < 0) break; + if (ret == 0) + continue; sz += sizeof(struct mtd_partition); sz += strlen(iis.name) + 1; @@ -194,6 +232,8 @@ ret = afs_read_iis(mtd, &iis, iis_ptr); if (ret < 0) break; + if (ret == 0) + continue; strcpy(str, iis.name); size = mtd->erasesize + off - img_ptr; diff -Nru a/drivers/mtd/maps/integrator-flash.c b/drivers/mtd/maps/integrator-flash.c --- a/drivers/mtd/maps/integrator-flash.c Sun Feb 29 12:54:28 2004 +++ b/drivers/mtd/maps/integrator-flash.c Sun Feb 29 12:54:28 2004 @@ -1,8 +1,9 @@ /*====================================================================== - drivers/mtd/maps/armflash.c: ARM Flash Layout/Partitioning + drivers/mtd/maps/integrator-flash.c: ARM Integrator flash map driver Copyright (C) 2000 ARM Limited + Copyright (C) 2003 Deep Blue Solutions Ltd. This program is free software; you can redistribute it and/or modify it under the terms of the GNU General Public License as published by @@ -21,7 +22,7 @@ This is access code for flashes using ARM's flash partitioning standards. - $Id: integrator-flash.c,v 1.12 2003/05/20 20:59:30 dwmw2 Exp $ + $Id: integrator-flash.c,v 1.15 2004/02/27 22:37:39 rmk Exp $ ======================================================================*/ @@ -64,7 +65,7 @@ info->plat->set_vpp(on); } -static const char *probes[] = { "RedBoot", "afs", NULL }; +static const char *probes[] = { "cmdlinepart", "RedBoot", "afs", NULL }; static int armflash_probe(struct device *_dev) { diff -Nru a/drivers/mtd/maps/lubbock-flash.c b/drivers/mtd/maps/lubbock-flash.c --- a/drivers/mtd/maps/lubbock-flash.c Sun Feb 29 12:54:28 2004 +++ b/drivers/mtd/maps/lubbock-flash.c Sun Feb 29 12:54:28 2004 @@ -74,7 +74,7 @@ lubbock_maps[flashboot].name = "Lubbock Boot ROM"; for (i = 0; i < 2; i++) { - lubbock_maps[i].virt = (unsigned long)__ioremap(lubbock_maps[i].phys, WINDOW_SIZE, 0); + lubbock_maps[i].virt = (unsigned long)ioremap(lubbock_maps[i].phys, WINDOW_SIZE); if (!lubbock_maps[i].virt) { printk(KERN_WARNING "Failed to ioremap %s\n", lubbock_maps[i].name); if (!ret) @@ -97,8 +97,8 @@ } mymtds[i]->owner = THIS_MODULE; - int ret = parse_mtd_partitions(mymtds[i], probes, - &parsed_parts[i], 0); + ret = parse_mtd_partitions(mymtds[i], probes, + &parsed_parts[i], 0); if (ret > 0) nr_parsed_parts[i] = ret; diff -Nru a/drivers/pci/hotplug/Kconfig b/drivers/pci/hotplug/Kconfig --- a/drivers/pci/hotplug/Kconfig Sun Feb 29 12:54:28 2004 +++ b/drivers/pci/hotplug/Kconfig Sun Feb 29 12:54:28 2004 @@ -191,7 +191,7 @@ config HOTPLUG_PCI_RPA tristate "RPA PCI Hotplug driver" - depends on HOTPLUG_PCI && PPC_PSERIES && PPC64 + depends on HOTPLUG_PCI && PPC_PSERIES && PPC64 && !HOTPLUG_PCI_FAKE help Say Y here if you have a a RPA system that supports PCI Hotplug. diff -Nru a/drivers/pci/hotplug/Makefile b/drivers/pci/hotplug/Makefile --- a/drivers/pci/hotplug/Makefile Sun Feb 29 12:54:28 2004 +++ b/drivers/pci/hotplug/Makefile Sun Feb 29 12:54:28 2004 @@ -25,6 +25,8 @@ cpqphp_ctrl.o \ cpqphp_sysfs.o \ cpqphp_pci.o +cpqphp-$(CONFIG_HOTPLUG_PCI_COMPAQ_NVRAM) += cpqphp_nvram.o +cpqphp-objs += $(cpqphp-y) ibmphp-objs := ibmphp_core.o \ ibmphp_ebda.o \ @@ -49,37 +51,24 @@ pciehp_sysfs.o \ pciehp_hpc.o -shpchp-objs := shpchp_core.o \ - shpchp_ctrl.o \ - shpchp_pci.o \ - shpchp_sysfs.o \ - shpchp_hpc.o - -ifdef CONFIG_HOTPLUG_PCI_ACPI - EXTRA_CFLAGS += -D_LINUX -I$(TOPDIR)/drivers/acpi - ifdef CONFIG_ACPI_DEBUG - EXTRA_CFLAGS += -DACPI_DEBUG_OUTPUT - endif -endif - -ifeq ($(CONFIG_HOTPLUG_PCI_COMPAQ_NVRAM),y) - cpqphp-objs += cpqphp_nvram.o -endif - ifeq ($(CONFIG_HOTPLUG_PCI_PCIE_PHPRM_NONACPI),y) pciehp-objs += pciehprm_nonacpi.o else pciehp-objs += pciehprm_acpi.o - EXTRA_CFLAGS += -D_LINUX -I$(TOPDIR)/drivers/acpi -I$(TOPDIR)/drivers/acpi/include endif +shpchp-objs := shpchp_core.o \ + shpchp_ctrl.o \ + shpchp_pci.o \ + shpchp_sysfs.o \ + shpchp_hpc.o + ifeq ($(CONFIG_HOTPLUG_PCI_SHPC_PHPRM_LEGACY),y) shpchp-objs += shpchprm_legacy.o else - ifeq ($(CONFIG_HOTPLUG_PCI_SHPC_PHPRM_NONACPI),y) - shpchp-objs += shpchprm_nonacpi.o - else - shpchp-objs += shpchprm_acpi.o - EXTRA_CFLAGS += -D_LINUX -I$(TOPDIR)/drivers/acpi - endif + ifeq ($(CONFIG_HOTPLUG_PCI_SHPC_PHPRM_NONACPI),y) + shpchp-objs += shpchprm_nonacpi.o + else + shpchp-objs += shpchprm_acpi.o + endif endif diff -Nru a/drivers/pci/hotplug/pciehp_ctrl.c b/drivers/pci/hotplug/pciehp_ctrl.c --- a/drivers/pci/hotplug/pciehp_ctrl.c Sun Feb 29 12:54:28 2004 +++ b/drivers/pci/hotplug/pciehp_ctrl.c Sun Feb 29 12:54:28 2004 @@ -188,11 +188,13 @@ /* * Card Present */ + info("Card present on Slot(%d)\n", ctrl->first_slot + hp_slot); taskInfo->event_type = INT_PRESENCE_ON; } else { /* * Not Present */ + info("Card not present on Slot(%d)\n", ctrl->first_slot + hp_slot); taskInfo->event_type = INT_PRESENCE_OFF; } diff -Nru a/drivers/pci/hotplug/shpchp.h b/drivers/pci/hotplug/shpchp.h --- a/drivers/pci/hotplug/shpchp.h Sun Feb 29 12:54:28 2004 +++ b/drivers/pci/hotplug/shpchp.h Sun Feb 29 12:54:28 2004 @@ -390,8 +390,8 @@ /* Sleep for up to 1 second */ schedule_timeout(1*HZ); } else { - /* Sleep for up to 1.5 second */ - schedule_timeout(1.5*HZ); + /* Sleep for up to 2 seconds */ + schedule_timeout(2*HZ); } set_current_state(TASK_RUNNING); remove_wait_queue(&ctrl->queue, &wait); diff -Nru a/drivers/pci/hotplug/shpchp_ctrl.c b/drivers/pci/hotplug/shpchp_ctrl.c --- a/drivers/pci/hotplug/shpchp_ctrl.c Sun Feb 29 12:54:28 2004 +++ b/drivers/pci/hotplug/shpchp_ctrl.c Sun Feb 29 12:54:28 2004 @@ -192,11 +192,13 @@ /* * Card Present */ + info("Card present on Slot(%d)\n", ctrl->first_slot + hp_slot); taskInfo->event_type = INT_PRESENCE_ON; } else { /* * Not Present */ + info("Card not present on Slot(%d)\n", ctrl->first_slot + hp_slot); taskInfo->event_type = INT_PRESENCE_OFF; } diff -Nru a/drivers/pci/hotplug/shpchp_hpc.c b/drivers/pci/hotplug/shpchp_hpc.c --- a/drivers/pci/hotplug/shpchp_hpc.c Sun Feb 29 12:54:28 2004 +++ b/drivers/pci/hotplug/shpchp_hpc.c Sun Feb 29 12:54:28 2004 @@ -1071,9 +1071,14 @@ if (!shpchp_poll_mode) { ctrl = (struct controller *)dev_id; php_ctlr = ctrl->hpc_ctlr_handle; - } else + } else { php_ctlr = (struct php_ctlr_state_s *) dev_id; + ctrl = (struct controller *)php_ctlr->callback_instance_id; + } + if (!ctrl) + return IRQ_NONE; + if (!php_ctlr || !php_ctlr->creg) return IRQ_NONE; @@ -1085,18 +1090,20 @@ dbg("%s: shpc_isr proceeds\n", __FUNCTION__); dbg("%s: intr_loc = %x\n",__FUNCTION__, intr_loc); - /* Mask Global Interrupt Mask - see implementation note on p. 139 */ - /* of SHPC spec rev 1.0*/ - temp_dword = readl(php_ctlr->creg + SERR_INTR_ENABLE); - dbg("%s: Before masking global interrupt, temp_dword = %x\n", - __FUNCTION__, temp_dword); - temp_dword |= 0x00000001; - dbg("%s: After masking global interrupt, temp_dword = %x\n", - __FUNCTION__, temp_dword); - writel(temp_dword, php_ctlr->creg + SERR_INTR_ENABLE); + if(!shpchp_poll_mode) { + /* Mask Global Interrupt Mask - see implementation note on p. 139 */ + /* of SHPC spec rev 1.0*/ + temp_dword = readl(php_ctlr->creg + SERR_INTR_ENABLE); + dbg("%s: Before masking global interrupt, temp_dword = %x\n", + __FUNCTION__, temp_dword); + temp_dword |= 0x00000001; + dbg("%s: After masking global interrupt, temp_dword = %x\n", + __FUNCTION__, temp_dword); + writel(temp_dword, php_ctlr->creg + SERR_INTR_ENABLE); - intr_loc2 = readl(php_ctlr->creg + INTR_LOC); - dbg("%s: intr_loc2 = %x\n",__FUNCTION__, intr_loc2); + intr_loc2 = readl(php_ctlr->creg + INTR_LOC); + dbg("%s: intr_loc2 = %x\n",__FUNCTION__, intr_loc2); + } if (intr_loc & 0x0001) { /* @@ -1159,14 +1166,16 @@ dbg("%s: intr_loc2 = %x\n",__FUNCTION__, intr_loc2); } } - /* Unmask Global Interrupt Mask */ - temp_dword = readl(php_ctlr->creg + SERR_INTR_ENABLE); - dbg("%s: 2-Before unmasking global interrupt, temp_dword = %x\n", - __FUNCTION__, temp_dword); - temp_dword &= 0xfffffffe; - dbg("%s: 2-After unmasking global interrupt, temp_dword = %x\n", - __FUNCTION__, temp_dword); - writel(temp_dword, php_ctlr->creg + SERR_INTR_ENABLE); + if (!shpchp_poll_mode) { + /* Unmask Global Interrupt Mask */ + temp_dword = readl(php_ctlr->creg + SERR_INTR_ENABLE); + dbg("%s: 2-Before unmasking global interrupt, temp_dword = %x\n", + __FUNCTION__, temp_dword); + temp_dword &= 0xfffffffe; + dbg("%s: 2-After unmasking global interrupt, temp_dword = %x\n", + __FUNCTION__, temp_dword); + writel(temp_dword, php_ctlr->creg + SERR_INTR_ENABLE); + } return IRQ_HANDLED; } diff -Nru a/drivers/pci/pci.c b/drivers/pci/pci.c --- a/drivers/pci/pci.c Sun Feb 29 12:54:28 2004 +++ b/drivers/pci/pci.c Sun Feb 29 12:54:28 2004 @@ -535,11 +535,6 @@ return 0; err_out: - printk (KERN_WARNING "PCI: Unable to reserve %s region #%d:%lx@%lx for device %s\n", - pci_resource_flags(pdev, i) & IORESOURCE_IO ? "I/O" : "mem", - i + 1, /* PCI BAR # */ - pci_resource_len(pdev, i), pci_resource_start(pdev, i), - pci_name(pdev)); while(--i >= 0) pci_release_region(pdev, i); diff -Nru a/drivers/pci/probe.c b/drivers/pci/probe.c --- a/drivers/pci/probe.c Sun Feb 29 12:54:28 2004 +++ b/drivers/pci/probe.c Sun Feb 29 12:54:28 2004 @@ -366,6 +366,8 @@ child = pci_alloc_child_bus(bus, dev, busnr); child->primary = buses & 0xFF; child->subordinate = (buses >> 16) & 0xFF; + child->bridge_ctl = bctl; + cmax = pci_scan_child_bus(child); if (cmax > max) max = cmax; } else { @@ -400,6 +402,8 @@ pci_write_config_dword(dev, PCI_PRIMARY_BUS, buses); if (!is_cardbus) { + child->bridge_ctl = PCI_BRIDGE_CTL_NO_ISA; + /* Now we can scan all subordinate buses... */ max = pci_scan_child_bus(child); } else { diff -Nru a/drivers/pci/setup-bus.c b/drivers/pci/setup-bus.c --- a/drivers/pci/setup-bus.c Sun Feb 29 12:54:28 2004 +++ b/drivers/pci/setup-bus.c Sun Feb 29 12:54:28 2004 @@ -43,13 +43,15 @@ #define CARDBUS_IO_SIZE (4096) #define CARDBUS_MEM_SIZE (32*1024*1024) -static int __devinit +static void __devinit pbus_assign_resources_sorted(struct pci_bus *bus) { struct pci_dev *dev; struct resource *res; struct resource_list head, *list, *tmp; - int idx, found_vga = 0; + int idx; + + bus->bridge_ctl &= ~PCI_BRIDGE_CTL_VGA; head.next = NULL; list_for_each_entry(dev, &bus->devices, bus_list) { @@ -57,7 +59,7 @@ if (class == PCI_CLASS_DISPLAY_VGA || class == PCI_CLASS_NOT_DEFINED_VGA) - found_vga = 1; + bus->bridge_ctl |= PCI_BRIDGE_CTL_VGA; pdev_sort_resources(dev, &head); } @@ -70,8 +72,6 @@ list = list->next; kfree(tmp); } - - return found_vga; } static void __devinit @@ -211,10 +211,7 @@ /* Clear out the upper 32 bits of PREF base. */ pci_write_config_dword(bridge, PCI_PREF_BASE_UPPER32, 0); - /* Check if we have VGA behind the bridge. - Enable ISA in either case (FIXME!). */ - l = (bus->resource[0]->flags & IORESOURCE_BUS_HAS_VGA) ? 0x0c : 0x04; - pci_write_config_word(bridge, PCI_BRIDGE_CONTROL, l); + pci_write_config_word(bridge, PCI_BRIDGE_CONTROL, bus->bridge_ctl); } /* Check whether the bridge supports optional I/O and @@ -498,13 +495,14 @@ pci_bus_assign_resources(struct pci_bus *bus) { struct pci_bus *b; - int found_vga = pbus_assign_resources_sorted(bus); struct pci_dev *dev; - if (found_vga) { + pbus_assign_resources_sorted(bus); + + if (bus->bridge_ctl & PCI_BRIDGE_CTL_VGA) { /* Propagate presence of the VGA to upstream bridges */ for (b = bus; b->parent; b = b->parent) { - b->resource[0]->flags |= IORESOURCE_BUS_HAS_VGA; + b->bridge_ctl |= PCI_BRIDGE_CTL_VGA; } } list_for_each_entry(dev, &bus->devices, bus_list) { diff -Nru a/drivers/pci/setup-res.c b/drivers/pci/setup-res.c --- a/drivers/pci/setup-res.c Sun Feb 29 12:54:28 2004 +++ b/drivers/pci/setup-res.c Sun Feb 29 12:54:28 2004 @@ -143,8 +143,9 @@ } if (ret) { - printk(KERN_ERR "PCI: Failed to allocate resource %d(%lx-%lx) for %s\n", - resno, res->start, res->end, pci_name(dev)); + printk(KERN_ERR "PCI: Failed to allocate %s resource #%d:%lx@%lx for %s\n", + res->flags & IORESOURCE_IO ? "I/O" : "mem", + resno, size, res->start, pci_name(dev)); } else if (resno < PCI_BRIDGE_RESOURCES) { pci_update_resource(dev, res, resno); } diff -Nru a/drivers/usb/host/ohci-sa1111.c b/drivers/usb/host/ohci-sa1111.c --- a/drivers/usb/host/ohci-sa1111.c Sun Feb 29 12:54:28 2004 +++ b/drivers/usb/host/ohci-sa1111.c Sun Feb 29 12:54:28 2004 @@ -105,7 +105,7 @@ } #endif -static void usb_hcd_sa1111_hcim_irq (int irq, void *__hcd, struct pt_regs * r) +static irqreturn_t usb_hcd_sa1111_hcim_irq (int irq, void *__hcd, struct pt_regs * r) { struct usb_hcd *hcd = __hcd; // unsigned long status = sa1111_readl(hcd->regs + SA1111_USB_STATUS); @@ -120,7 +120,7 @@ } #endif - usb_hcd_irq(irq, hcd, r); + return usb_hcd_irq(irq, hcd, r); } /*-------------------------------------------------------------------------*/ diff -Nru a/fs/hpfs/buffer.c b/fs/hpfs/buffer.c --- a/fs/hpfs/buffer.c Sun Feb 29 12:54:28 2004 +++ b/fs/hpfs/buffer.c Sun Feb 29 12:54:28 2004 @@ -62,56 +62,28 @@ void hpfs_lock_2inodes(struct inode *i1, struct inode *i2) { - struct hpfs_inode_info *hpfs_i1 = NULL, *hpfs_i2 = NULL; - - if (!i1) { - if (i2) { - hpfs_i2 = hpfs_i(i2); + if (!i2 || i1 == i2) { + hpfs_lock_inode(i1); + } else if (!i1) { + hpfs_lock_inode(i2); + } else { + struct hpfs_inode_info *hpfs_i1 = hpfs_i(i1); + struct hpfs_inode_info *hpfs_i2 = hpfs_i(i2); + if (i1->i_ino < i2->i_ino) { + down(&hpfs_i1->i_sem); + down(&hpfs_i2->i_sem); + } else { down(&hpfs_i2->i_sem); - } - return; - } - if (!i2) { - if (i1) { - hpfs_i1 = hpfs_i(i1); down(&hpfs_i1->i_sem); } - return; } - if (i1->i_ino < i2->i_ino) { - down(&hpfs_i1->i_sem); - down(&hpfs_i2->i_sem); - } else if (i1->i_ino > i2->i_ino) { - down(&hpfs_i2->i_sem); - down(&hpfs_i1->i_sem); - } else down(&hpfs_i1->i_sem); } void hpfs_unlock_2inodes(struct inode *i1, struct inode *i2) { - struct hpfs_inode_info *hpfs_i1 = NULL, *hpfs_i2 = NULL; - - if (!i1) { - if (i2) { - hpfs_i2 = hpfs_i(i2); - up(&hpfs_i2->i_sem); - } - return; - } - if (!i2) { - if (i1) { - hpfs_i1 = hpfs_i(i1); - up(&hpfs_i1->i_sem); - } - return; - } - if (i1->i_ino < i2->i_ino) { - up(&hpfs_i2->i_sem); - up(&hpfs_i1->i_sem); - } else if (i1->i_ino > i2->i_ino) { - up(&hpfs_i1->i_sem); - up(&hpfs_i2->i_sem); - } else up(&hpfs_i1->i_sem); + /* order of up() doesn't matter here */ + hpfs_unlock_inode(i1); + hpfs_unlock_inode(i2); } void hpfs_lock_3inodes(struct inode *i1, struct inode *i2, struct inode *i3) diff -Nru a/fs/locks.c b/fs/locks.c --- a/fs/locks.c Sun Feb 29 12:54:28 2004 +++ b/fs/locks.c Sun Feb 29 12:54:28 2004 @@ -1699,6 +1699,8 @@ unlock_kernel(); } +EXPORT_SYMBOL(locks_remove_posix); + /* * This function is called on the last close of an open file. */ diff -Nru a/include/asm-ia64/iosapic.h b/include/asm-ia64/iosapic.h --- a/include/asm-ia64/iosapic.h Sun Feb 29 12:54:28 2004 +++ b/include/asm-ia64/iosapic.h Sun Feb 29 12:54:28 2004 @@ -45,9 +45,9 @@ /* * Mask bit */ + #define IOSAPIC_MASK_SHIFT 16 -#define IOSAPIC_UNMASK 0 -#define IOSAPIC_MSAK 1 +#define IOSAPIC_MASK (1<, Hewlett-Packard Co */ @@ -15,6 +15,14 @@ unsigned int dma_length; }; -#define ISA_DMA_THRESHOLD (~0UL) +/* + * It used to be that ISA_DMA_THRESHOLD had something to do with the + * DMA-limits of ISA-devices. Nowadays, its only remaining use (apart + * from the aha1542.c driver, which isn't 64-bit clean anyhow) is to + * tell the block-layer (via BLK_BOUNCE_ISA) what the max. physical + * address of a page is that is allocated with GFP_DMA. On IA-64, + * that's 4GB - 1. + */ +#define ISA_DMA_THRESHOLD 0xffffffff #endif /* _ASM_IA64_SCATTERLIST_H */ diff -Nru a/include/linux/pci.h b/include/linux/pci.h --- a/include/linux/pci.h Sun Feb 29 12:54:28 2004 +++ b/include/linux/pci.h Sun Feb 29 12:54:28 2004 @@ -468,6 +468,8 @@ char name[48]; + unsigned short bridge_ctl; /* manage NO_ISA/FBB/et al behaviors */ + unsigned short pad2; struct device *bridge; struct class_device class_dev; }; diff -Nru a/sound/oss/Kconfig b/sound/oss/Kconfig --- a/sound/oss/Kconfig Sun Feb 29 12:54:28 2004 +++ b/sound/oss/Kconfig Sun Feb 29 12:54:28 2004 @@ -1147,7 +1147,7 @@ help Say Y or M if you have a Hammerfall or Hammerfall light multichannel card from RME. If you want to acess advanced - features of the card, read Documentation/sound/rme96xx. + features of the card, read Documentation/sound/oss/rme96xx. config SOUND_AD1980 tristate "AD1980 front/back switch plugin"