All of lore.kernel.org
 help / color / mirror / Atom feed
* empty filter on FORWARD chain with rp_filter means safe right?
From: Scott Mcdermott @ 2010-10-08  4:31 UTC (permalink / raw)
  To: netfilter

Hello,

I encountered a system today with two attached
networks, one public and the other RFC1918.  The box
had ip_foward=1, FORWARD chain empty, policy ACCEPT.
rp_filter was set on both the interfaces.

Now if I were somewhere off the public interface, but
many hops away, there is no possible way to get packets
to the RFC1918 side of the box is there?  Because I
have no way to actually route the packets to the
gateway with destination addresses on the far side.  So
actually this box is safe from malicious activity, even
though there is an ACCEPT policy on FORWARD and it's
set with routing enabled.  Is this correct?

Now if instead I have control of a station on the same
segment as the gateway's public interface, or if I
control routers in-between and can set up routes to get
packets to the box with the internal IPs as
destinations, then it's a different story.  But in the
common case of having ISPs in between (which will drop
my packets with RFC1918 destinations), it's not
possible to get packets to the gateway's internal
network except if they NAT some of them for me.

Please help me to see if my understanding is correct.

Thanks.

^ permalink raw reply

* [Buildroot] buildroot not support c++ compliing
From: olyvine.chen at logiways.com.cn @ 2010-10-08  4:23 UTC (permalink / raw)
  To: buildroot

Dear all,
        
  I now try to add package libmusicbrainz to buildroot, but many errors
happen, such as the following:

*************************************************************************

buildroot/output/build/libmusicbrainz-3.0.2/src/artist.cpp:23:18: error:
string: No such file or directory

*************************************************************************
  it seems indicate that no c++ library available, then how to enable c
++ compiling for buildroot? 
        
  I enabled glibc via:
  Toolchain => Toolchain type (External toolchain) => External toolchain
C library (glibc)
        
Kindest regards!
Olyvine

^ permalink raw reply

* Ok, dumb question time ...
From: Joe Landman @ 2010-10-08  4:20 UTC (permalink / raw)
  To: linux-raid

Not having much luck with this.  Let me explain ...

Imagine we have a RAID1 with 3 elements.  It was originally a RAID1 with 
2 elements, and we added a 3rd using

	mdadm /dev/md0 --add /dev/loop1

What I want to do is conceptually very simple.  I want to permanently 
remove loop1, without having the array become dirty, or degraded.  That 
is, I would like

	mdadm /dev/md0 --fail /dev/loop1 --remove /dev/loop1

to result in a clean array with two members.

It doesn't.  The array is marked as being in the "clean, degraded" 
state.  Which, as it is the root file system array, has the unfortunate 
side effect of not allowing the RAID1 to properly assemble at boot (that 
degraded state).

So ... can I force the array to either remove the extra unneeded loop1 
device, and update its metadata properly ... or force it into a clean, 
active state without the loop1 device, or force the assembly on boot to 
occur regardless of what it thinks it should have?

This is quite disconcerting ... I thought it would be simple.
-- 
Joseph Landman, Ph.D
Founder and CEO
Scalable Informatics, Inc.
email: landman@scalableinformatics.com
web  : http://scalableinformatics.com
        http://scalableinformatics.com/jackrabbit
phone: +1 734 786 8423 x121
fax  : +1 866 888 3112
cell : +1 734 612 4615

^ permalink raw reply

* Re: DRAFT Design Spec for 1st Class Quota Support in Ext4
From: Dmitry @ 2010-10-08  4:19 UTC (permalink / raw)
  To: Theodore Ts'o, Jan Kara; +Cc: linux-ext4
In-Reply-To: <87y6gad45r.fsf@openvz.org>

On Mon, 26 Apr 2010 12:11:28 +0400, Dmitry Monakhov <dmonakhov@openvz.org> wrote:
> "Theodore Ts'o" <tytso@mit.edu> writes:
> 
> > Please comment!
> >
> > 		    1st Class Quota Support in Ext4
> > 		    DRAFT Design Specification, v0.5
> >
> >
> > This proposal promotes quota to being a first class supported feature in
> > ext4.  To do this, we will do the following:
> >
> > 1)  We define the following two new fields to the superblock.  No new
> > COMPAT features are defined; since unused superblock fields are zero, if
> > the fields are not known.
> >   *) A superblock field containing the inode number for the user quota
> >      file.  This inode number will be 3 if the inode is user quota file
> >      is hidden.  If this field is zero, then user quotas will not be tracked.
> >   *) A superblock field containing the inode number for the group quota
> >      file.  This inode number will be 4 if the inode is group quota file
> >      is hidden.  If this field is zero, then group quotas will not be
> >      tracked.
> >
I hope, that it is no too late for new thoughts.

While working on generic quota code i've realized what we can make
journalled quota accounting almost for free.

Today it is painful because
1) each quota modification result in quota write 
   make_quota_dirty
     ->write_quota
       which means
       1A) i_mutex on quota file
       1B) locks for quota-info and buffer on data copy.
       1C) locking in journal internals.

It is relatively easy to solve (1A) and was already discussed,
just skip it if quota already exist on the disk.

But others issues are also solvable. Here is an idea:
1) dquot should contain per_cpu counters 
   {
      per_cpu_ptr b_reserved;
      per_cpu_ptr b_current;
      per_cpu_ptr i_current;
   };
  This allow us to make charge/claim/free path lock-less if we do not
  care about quota_limits. Even with limits we can avoid synchronization
  (i hope) in most cases if consider per_cpu variables as preallocation
  buckets.
  Off course per_cpu vars comes with the cost of memory, but in most cases
  we have hundreds of dquot objects per sb or even less.

2) Change quota mark_dirty policy like follows
   2A) Remember transaction id inside dquot object
       and if transaction is the same as before just exit.
   2B) If transaction not the same do:
         get_write_access(bh)
         /* do not copy quota data yet */
         hanle_dirty_metadata(bh, &quota_copy_callback)
       quota_copy_callback will be attached to journal_head and will
       be called by jbd2 on transaction commit or on starting new
       transaction. That callback will copy data from quota-info,
       and at this moment we do need synchronization with chargers,
       but only once for each transaction.
   Changes in jbd2 doesn't look so scary. And performance gain seems
   promising.

I'll try to come up with the proof of concept path soon.
BTW what are current ETAs for huge ext4-quota changes?
> I now that it is always not right time for ask about this, but still.
> Don't you mind to reserve 5'th inode number for projectID quota?
> > 2) The quota files will use the v2 format only, and updates to the quota
> > files will be protected with the journal if the journal is present.
> Since we are about to starting huge movements let's use new (v3) quota
> format. The only difference with v2 is extended header wider than old
> magic+version.
> 
> struct v3_disk_dqheader {
>         __le32 dqh_magic;        /* Magic number identifying file */
>         __le32 dqh_version;      /* File version */
>         __le32 dqh_state;        /* quota file  state */
>         __u32  dqh_reserved[125];
>  };
> dqh_state is an equivalent of sb's s_state.
> >
> > 3) If e2fsck needs to do a full file system consistency check, it will
> > keep track of the disk space used by each user and/or groups ids, and
> > update the user and/or group quota files at the end of the e2fsck run.
> >
> > 4) If the filesystem appears consistent, but the user and/or group quota
> > fils are not equal to the last superblock write time, e2fsck will do a
> > partical file system consistency check.  This will consist of e2fsck
> > pass #1, and if no errors were detected, e2fsck will update the user and
> > group quota files and exit.  If any errors were detected during pass #1,
> > then e2fsck will  continue to do pass numbers 2-5, and thus do a full
> > file system consistency check before updating the quota files.
> >
> > 5) Mke2fs will take an extended option (quota=user,group) which if
> > present will force the initialization of the quota inodes.  Using the
> > /etc/mke2fs.conf file, the system administrator can also specify a quota
> > option in the [defaults] and [fs_types] section, so that quota files can
> > be enabled by default.
> >
> > 6) Tune2fs will have a facility for adding and removing user and group
> > quotas inodes while the file system is mounted.  The quota usage will
> > not be correct after the quota inodes are newly added, however, so quota
> > will not be enabled by default,  If the quota inodes are removed, quota
> > will be disabled first.
>   Who is responsible for quota enabling in that scenario?
>   Will it enabled by default on mount time?
> 
> Small note: quotacheck -cug /mnt will result in unlink/create
> so we have options exclusive options:
> if inode is already exist
>   replace unlink/create with truncate
> else
>   call tune2fs from quotacheck after inodes was created.
> >
> > 7) There will be a new interface so that bulk quota information can be
> > fetched from the file system.  This needs to be negotiated with Jan
> > Kara.  It can either be a new system call, or a magic file in /proc that
> > can be opened and the repquota data extracted.
> >
> > 8) Traditional style quota will still be supported; that is the
> > appropriate magic flags will be passed through to /proc/mounts so that
> > the old-style init scripts will still function correctly.  This support
> > will be deprecated over an 18 month period after the new-style kernel
> > code and userspace tools have been released.
>   9) Make ext4_orphan_cleanup() more tolerate to quota, if quota is 
>   enabled for given SB, but cleanup procedure is unable to perform
>   ext4_quota_on_mount() mount should fail as it does in case of wrong
>   options.
> 
> The rest is looking very promising.
> > --
> > To unsubscribe from this list: send the line "unsubscribe linux-ext4" in
> > the body of a message to majordomo@vger.kernel.org
> > More majordomo info at  http://vger.kernel.org/majordomo-info.html

^ permalink raw reply

* Re: fatal: BUG: dashless options don't support arguments
From: Jeff King @ 2010-10-08  4:11 UTC (permalink / raw)
  To: Jonathan Nieder; +Cc: Brian Zitzow, git, Christopher Cameron, Henrik Tidefelt
In-Reply-To: <20101008031818.GC992@burratino>

On Thu, Oct 07, 2010 at 10:18:18PM -0500, Jonathan Nieder wrote:

> > Ki:$ git checkout master
> > fatal: BUG: dashless options don't support arguments
> 
> Strange indeed.  Here's what I would suggest:
> 
> 1. For debugging output:
> 
>  $ echo 'prefix=/usr/local' >>config.mak; # or whatever prefix you use
>  $ git describe
>  $ gcc --version
>  $ wget 'http://download.gmane.org/gmane.comp.version-control.git/128067/128068'
>  $ git am -3 128068
>  $ make
>  $ bin-wrappers/git checkout m

Yeah, I would be curious to see the output of that. Interesting, too,
that it seems to happen with multiple commands (it looked like it
happened with "git push foo" in the pastebin from the irc log).

> 2. To track down the issue, if you like to read assembler:
> 
>  $ make builtin/checkout.s
>  $ vi checkout.s

Ugh. I think a better course of action is to find out which option is
being munged (from step 1 above), and then try running it under gdb with
a watch set on that option struct. Assuming it's easily reproducible of
course.

-Peff

^ permalink raw reply

* Tips on debugging suspend/resume failure
From: Man Spaz @ 2010-10-08  4:09 UTC (permalink / raw)
  To: linux-kernel

Hello
I have a machine x86 arch with no serial port, only console. I have a suspend/resume (mem, not hibernate) problem (not sure which one it is, if something fails on the suspend, or the resume fails - but it does seem to go to sleep) that doesn't suspend nor resume at all, using stock standard x86_64 kernel.

I compiled everything as a module and removed all unnecessary ones, so I cannot isolate the problem to a specific driver. This very same machine had no problems with <2.6.34.2 kernels.

But the question remains, how to get debug out? Is there a dmesg buffer that can persist if DRAM is being refreshed perhaps? Is there another way to skin this mongrel, I mean cat?
Spaz


      


      

^ permalink raw reply

* Re: upgrade kvm with running vm
From: Teck Choon Giam @ 2010-10-08  4:07 UTC (permalink / raw)
  To: sofa5000; +Cc: kvm
In-Reply-To: <46949.90.146.57.124.1286466221.squirrel@lavabit.com>

On Thu, Oct 7, 2010 at 11:43 PM,  <sofa5000@lavabit.com> wrote:
> hi everybody,
>
> is it a problem to update kvm (the kvm package (qemu-kvm on debian) with
> the package manager) while some vms are turned on? or should i shutdown
> all vms first?

>From personal experience (install from source), there shouldn't be a
problem to perform upgrade/update of qemu-kvm without shutting down
those running VMs.  However, in order to use the updated version of
the qemu-kvm, you will need to unload those loaded kvm-intel or
kvm-amd and kvm kernel modules.  Such unloading of modules will need
to shutdown all running VMs in order to successfully unload (rmmod)
those kernel modules.  After unloading, you can reload the updated
version by using modprobe or insmod after you have done depmod.

Hope this helps!

Kindest regards,
Giam Teck Choon

^ permalink raw reply

* [PATCH] sdhci: on error print out SD CMD and CAPABILITY_1 Register
From: Philip Rakity @ 2010-10-08  4:05 UTC (permalink / raw)
  To: linux-mmc@vger.kernel.org


More information should be shown when sdhci_dumpregs is called.


Knowing the command is useful for debugging.
Capability 1 is useful for sdio v3

Signed-off-by: Philip Rakity <prakity@marvell.com>
---
 drivers/mmc/host/sdhci.c |    5 ++++-
 drivers/mmc/host/sdhci.h |    2 +-
 2 files changed, 5 insertions(+), 2 deletions(-)

diff --git a/drivers/mmc/host/sdhci.c b/drivers/mmc/host/sdhci.c
index 9cb60ba..ea8472b 100644
--- a/drivers/mmc/host/sdhci.c
+++ b/drivers/mmc/host/sdhci.c
@@ -77,8 +77,11 @@ static void sdhci_dumpregs(struct sdhci_host *host)
 	printk(KERN_DEBUG DRIVER_NAME ": AC12 err: 0x%08x | Slot int: 0x%08x\n",
 		sdhci_readw(host, SDHCI_ACMD12_ERR),
 		sdhci_readw(host, SDHCI_SLOT_INT_STATUS));
-	printk(KERN_DEBUG DRIVER_NAME ": Caps:     0x%08x | Max curr: 0x%08x\n",
+	printk(KERN_DEBUG DRIVER_NAME ": Caps:     0x%08x | Caps_1:   0x%08x\n",
 		sdhci_readl(host, SDHCI_CAPABILITIES),
+		sdhci_readl(host, SDHCI_CAPABILITIES_1));
+	printk(KERN_DEBUG DRIVER_NAME ": Cmd:      0x%08x | Max curr: 0x%08x\n",
+		sdhci_readw(host, SDHCI_COMMAND),
 		sdhci_readl(host, SDHCI_MAX_CURRENT));
 
 	if (host->flags & SDHCI_USE_ADMA)
diff --git a/drivers/mmc/host/sdhci.h b/drivers/mmc/host/sdhci.h
index bfcd611..38ae340 100644
--- a/drivers/mmc/host/sdhci.h
+++ b/drivers/mmc/host/sdhci.h
@@ -161,7 +161,7 @@
 #define  SDHCI_CAN_VDD_180	0x04000000
 #define  SDHCI_CAN_64BIT	0x10000000
 
-/* 44-47 reserved for more caps */
+#define SDHCI_CAPABILITIES_1	0x44
 
 #define SDHCI_MAX_CURRENT	0x48
 
-- 
1.6.0.4


^ permalink raw reply related

* RE: [RFC][QEMU] ATI graphics VBIOS passthru support
From: Huang2, Wei @ 2010-10-08  4:05 UTC (permalink / raw)
  To: Kay, Allen M, Ian Jackson; +Cc: Xen-devel
In-Reply-To: <987664A83D2D224EAE907B061CE93D530163EA96FD@orsmsx505.amr.corp.intel.com>


[-- Attachment #1.1: Type: text/plain, Size: 2085 bytes --]

Hi Allen,

Thanks for testing it out. We have tested this patch with Radeon 4850, 4870, FirePro V5700 and FirePro M5800. Unfortunately we don't have V3750 at hand. It is very possible this patch isn't compatible with V3750. We will try to get hold of one for debugging. For graphics which work with this path, users should be able to get rid of emulated gfx (such as Cirrus). I have successfully installed a Windows guest VM using this patch.

I also want to point out that there is still an issue. Users will see a black screen after installing Catalyst driver. Even though the screen appears to be black, the driver is actually functioning correctly (3DMark can be run with external monitor). Our driver team is currently debugging it and they believe this is easy to fix.

What is your opinion on this patch (and the solution) in general?

-Wei

From: Kay, Allen M [mailto:allen.m.kay@intel.com]
Sent: Thursday, October 07, 2010 6:58 PM
To: Huang2, Wei; Ian Jackson
Cc: Xen-devel
Subject: RE: [RFC][QEMU] ATI graphics VBIOS passthru support

Hi Wei,

This patch did not cause any problems with Intel IGD passthrough for me.  However, the monitor remained blank if I pass through ATI Firepro V3750 either as the primary display device or the secondary device (gfx_passthru=1/0).  Passing it through as the secondary device used to work.

Have you tested the patch with this graphics card?

Allen

From: Huang2, Wei [mailto:Wei.Huang2@amd.com]
Sent: Thursday, October 07, 2010 9:57 AM
To: Ian Jackson
Cc: Xen-devel; Kay, Allen M
Subject: [RFC][QEMU] ATI graphics VBIOS passthru support

Hi Ian,

There have been a lot of interest on gfx passthru recently. This patch enables ATI VBIOS in passthru mode. The guest VM system BIOS (including Windows boot logo) can now show in passthru screen. We have tested with various Windows and Linux guest VMs. Please help review it. We are also looking forward to comments and suggestions from Xen community users.

Signed-off-by: Wei Huang <wei.huang2@amd.com>
Signed-off-by: Wei Wang <wei.wang2@amd.com>



[-- Attachment #1.2: Type: text/html, Size: 6590 bytes --]

[-- Attachment #2: Type: text/plain, Size: 138 bytes --]

_______________________________________________
Xen-devel mailing list
Xen-devel@lists.xensource.com
http://lists.xensource.com/xen-devel

^ permalink raw reply

* Re: [PATCH 2/2] device-assignment: Allow PCI to manage the option ROM
From: Alex Williamson @ 2010-10-08  4:02 UTC (permalink / raw)
  To: Michael S. Tsirkin; +Cc: kvm, ddutile, chrisw
In-Reply-To: <20101007224523.GB20504@redhat.com>

On Fri, 2010-10-08 at 00:45 +0200, Michael S. Tsirkin wrote:
> On Thu, Oct 07, 2010 at 11:34:01AM -0600, Alex Williamson wrote:
> > On Thu, 2010-10-07 at 19:18 +0200, Michael S. Tsirkin wrote:
> > > On Mon, Oct 04, 2010 at 03:26:30PM -0600, Alex Williamson wrote:
> > > > --- a/hw/device-assignment.c
> > > > +++ b/hw/device-assignment.c
> > ...
> > > > @@ -1644,58 +1621,64 @@ void add_assigned_devices(PCIBus *bus, const char **devices, int n_devices)
> > > >   */
> > > >  static void assigned_dev_load_option_rom(AssignedDevice *dev)
> > > >  {
> > > > -    int size, len, ret;
> > > > -    void *buf;
> > > > +    char name[32], rom_file[64];
> > > >      FILE *fp;
> > > > -    uint8_t i = 1;
> > > > -    char rom_file[64];
> > > > +    uint8_t val;
> > > > +    struct stat st;
> > > > +    void *ptr;
> > > > +
> > > > +    /* If loading ROM from file, pci handles it */
> > > > +    if (dev->dev.romfile || !dev->dev.rom_bar)
> > > > +        return;
> > > >  
> > > >      snprintf(rom_file, sizeof(rom_file),
> > > >               "/sys/bus/pci/devices/%04x:%02x:%02x.%01x/rom",
> > > >               dev->host.seg, dev->host.bus, dev->host.dev, dev->host.func);
> > > >  
> > > > -    if (access(rom_file, F_OK))
> > > > +    if (stat(rom_file, &st)) {
> > > >          return;
> > > > +    }
> > > >  
> > > 
> > > Just a note that stat on the ROM sysfs file returns window size,
> > > not the ROM size. So this allocates more ram than really necessary for
> > > ROM. Real size is returned by fread.
> > > 
> > > Do we care?
> > 
> > That was my intention with using stat.  I thought that by default the
> > ROM BAR should match physical hardware, so even if the contents could be
> > rounded down to a smaller size, we maintain the size of the physical
> > device.  To use the minimum size, the contents could be extracted using
> > pci-sysfs and passed with the romfile option, or the ROM could be
> > disabled altogether with the rombar=0 option.  Sound reasonable?
> > Thanks,
> > 
> > Alex
> 
> For BAR size yes, but we do not need the buffer full of 0xff as it is
> never accessed: let's have buffer size match real ROM, avoid wasting
> memory: this can come up to megabytes easily.
> Makes sense?

I tend to doubt that hardware vendors are going to waste money putting
seriously oversized eeproms on devices.  It does seem pretty typical to
find graphics cards with 128K ROM BARs where the actual ROM squeezes
just under 64K, but that's a long way from megabytes of wasted memory.
The only device I have with a ROM BAR in the megabytes is an 82576, but
it comes up as an invalid rom through pci-sysfs, so we skip it.  I
assume that just means someone was lazy and didn't bother to fuse a
transistor that disables the ROM BAR, leaving it at it's maximum
aperture w/ no eeprom to back it.  Anyone know?  Examples to the
contrary welcome.

So I think the question comes down to whether there's any value to
trying to exactly mimic the resource layout of the device.  I'm doubtful
that there is, but at the potential cost of 10-100s of KBs of memory, I
thought it might be worthwhile.  If you feel strongly otherwise, I'll
follow-up with a patch to size it by the actual readable contents.
Thanks,

Alex


^ permalink raw reply

* Re: [1/2] hwmon: uniform the init style of pkgtemp
From: Guenter Roeck @ 2010-10-08  3:52 UTC (permalink / raw)
  To: Chen Gong
  Cc: lm-sensors@lm-sensors.org, JBeulich@novell.com,
	linux-kernel@vger.kernel.org
In-Reply-To: <4CAE930D.2040601@linux.intel.com>

On Thu, Oct 07, 2010 at 11:42:05PM -0400, Chen Gong wrote:
> 于 10/2/2010 11:26 AM, Guenter Roeck 写道:
> > On Sun, Sep 26, 2010 at 05:59:59AM -0000, Chen Gong wrote:
> >> pkgtemp is derived from coretemp, so some reasonable
> >> logics should be applied onto pkgtemp, too. Such as
> >> the init logic here.
> >>
> >> Signed-off-by: Chen Gong<gong.chen@linux.intel.com>
> >> Acked-by: Jan Beulich<jbeulich@novell.com>
> >>
> > Hi,
> >
> > this patch, when applied with CONFIG_HOTPLUG_CPU undefined, causes a compile failure
> > because it tries to access pkgtemp_cpu_notifier which is not defined in this case.
> >
> > For that reason, I have removed the patch from the list of applied patches for -next.
> > Please re-submit a version which compiles for all combinations of HOTPLUG_CPU and SMP
> > defined/undefined.
> >
> > Thanks,
> > Guenter
> >
> Sorry for late. I just come back from my holiday. If only this one patch
> is applied, it is broken, but it will be OK after these 2 patches are
> applied. I tested the patches when CONFIG_SMP is undefined, it does be

Each patch by itself must be compilable, otherwise we break the ability
to bisect. Not a good idea.

> broken again. My suggestion is adding a macro definiton in the pkgtemp.c
> like "#include <asm/smp.h>". If it is doable, I will re-post a new patch
> series

I assume you mean to add the include directive. Yes, that should do it,
but please make sure that it compiles.

Thanks,
Guenter

^ permalink raw reply

* Re: [lm-sensors] [1/2] hwmon: uniform the init style of pkgtemp
From: Guenter Roeck @ 2010-10-08  3:52 UTC (permalink / raw)
  To: Chen Gong
  Cc: lm-sensors@lm-sensors.org, JBeulich@novell.com,
	linux-kernel@vger.kernel.org
In-Reply-To: <4CAE930D.2040601@linux.intel.com>

On Thu, Oct 07, 2010 at 11:42:05PM -0400, Chen Gong wrote:
> 于 10/2/2010 11:26 AM, Guenter Roeck 写道:
> > On Sun, Sep 26, 2010 at 05:59:59AM -0000, Chen Gong wrote:
> >> pkgtemp is derived from coretemp, so some reasonable
> >> logics should be applied onto pkgtemp, too. Such as
> >> the init logic here.
> >>
> >> Signed-off-by: Chen Gong<gong.chen@linux.intel.com>
> >> Acked-by: Jan Beulich<jbeulich@novell.com>
> >>
> > Hi,
> >
> > this patch, when applied with CONFIG_HOTPLUG_CPU undefined, causes a compile failure
> > because it tries to access pkgtemp_cpu_notifier which is not defined in this case.
> >
> > For that reason, I have removed the patch from the list of applied patches for -next.
> > Please re-submit a version which compiles for all combinations of HOTPLUG_CPU and SMP
> > defined/undefined.
> >
> > Thanks,
> > Guenter
> >
> Sorry for late. I just come back from my holiday. If only this one patch
> is applied, it is broken, but it will be OK after these 2 patches are
> applied. I tested the patches when CONFIG_SMP is undefined, it does be

Each patch by itself must be compilable, otherwise we break the ability
to bisect. Not a good idea.

> broken again. My suggestion is adding a macro definiton in the pkgtemp.c
> like "#include <asm/smp.h>". If it is doable, I will re-post a new patch
> series

I assume you mean to add the include directive. Yes, that should do it,
but please make sure that it compiles.

Thanks,
Guenter

_______________________________________________
lm-sensors mailing list
lm-sensors@lm-sensors.org
http://lists.lm-sensors.org/mailman/listinfo/lm-sensors

^ permalink raw reply

* RE: [PATCH] KVM: PPC: e500: Call kvm_vcpu_uninit() before kvmppc_e500_tlb_uninit().
From: Liu Yu-B13201 @ 2010-10-08  3:50 UTC (permalink / raw)
  To: kvm-ppc
In-Reply-To: <20101005192241.GB30970@udp111988uds.am.freescale.net>

 

> -----Original Message-----
> From: Alexander Graf [mailto:agraf@suse.de] 
> Sent: Wednesday, October 06, 2010 3:42 AM
> To: Wood Scott-B07421
> Cc: kvm-ppc@vger.kernel.org; Liu Yu-B13201
> Subject: Re: [PATCH] KVM: PPC: e500: Call kvm_vcpu_uninit() 
> before kvmppc_e500_tlb_uninit().
> 
> 
> On 05.10.2010, at 21:22, Scott Wood wrote:
> 
> > The VCPU uninit calls some TLB functions, and the TLB 
> uninit function
> > frees the memory used by them.
> 
> Liu, this is your code. Please sign it off if you think the 
> change is correct.
> 

Yes. The fix is correct.
Acked-by: Liu Yu <yu.liu@freescale.com>

Thanks,
Yu


^ permalink raw reply

* [U-Boot] Crash in env_relocate_spec() of env_mmc.c
From: Steve Sakoman @ 2010-10-08  3:45 UTC (permalink / raw)
  To: u-boot

I've been attempting to get the OMAP4 boards working post the ARM
relocation changes.

Panda was simple.  The OMAP4430SDP is proving to be more challenging,
as it freezes after printing the DRAM size message.

Adding a few printfs revealed that the crash occurs in env_mmc.c's
env_relocate_spec() routine.

Has anyone else run into this issue?  Any advice?

Steve

^ permalink raw reply

* Re: [lm-sensors] [1/2] hwmon: uniform the init style of pkgtemp
From: Chen Gong @ 2010-10-08  3:42 UTC (permalink / raw)
  To: Guenter Roeck; +Cc: lm-sensors, JBeulich, linux-kernel
In-Reply-To: <20101002032603.GA25998@ericsson.com>

于 10/2/2010 11:26 AM, Guenter Roeck 写道:
> On Sun, Sep 26, 2010 at 05:59:59AM -0000, Chen Gong wrote:
>> pkgtemp is derived from coretemp, so some reasonable
>> logics should be applied onto pkgtemp, too. Such as
>> the init logic here.
>>
>> Signed-off-by: Chen Gong<gong.chen@linux.intel.com>
>> Acked-by: Jan Beulich<jbeulich@novell.com>
>>
> Hi,
>
> this patch, when applied with CONFIG_HOTPLUG_CPU undefined, causes a compile failure
> because it tries to access pkgtemp_cpu_notifier which is not defined in this case.
>
> For that reason, I have removed the patch from the list of applied patches for -next.
> Please re-submit a version which compiles for all combinations of HOTPLUG_CPU and SMP
> defined/undefined.
>
> Thanks,
> Guenter
>
Sorry for late. I just come back from my holiday. If only this one patch
is applied, it is broken, but it will be OK after these 2 patches are
applied. I tested the patches when CONFIG_SMP is undefined, it does be
broken again. My suggestion is adding a macro definiton in the pkgtemp.c
like "#include <asm/smp.h>". If it is doable, I will re-post a new patch
series

_______________________________________________
lm-sensors mailing list
lm-sensors@lm-sensors.org
http://lists.lm-sensors.org/mailman/listinfo/lm-sensors

^ permalink raw reply

* Re: [1/2] hwmon: uniform the init style of pkgtemp
From: Chen Gong @ 2010-10-08  3:42 UTC (permalink / raw)
  To: Guenter Roeck; +Cc: lm-sensors, JBeulich, linux-kernel
In-Reply-To: <20101002032603.GA25998@ericsson.com>

于 10/2/2010 11:26 AM, Guenter Roeck 写道:
> On Sun, Sep 26, 2010 at 05:59:59AM -0000, Chen Gong wrote:
>> pkgtemp is derived from coretemp, so some reasonable
>> logics should be applied onto pkgtemp, too. Such as
>> the init logic here.
>>
>> Signed-off-by: Chen Gong<gong.chen@linux.intel.com>
>> Acked-by: Jan Beulich<jbeulich@novell.com>
>>
> Hi,
>
> this patch, when applied with CONFIG_HOTPLUG_CPU undefined, causes a compile failure
> because it tries to access pkgtemp_cpu_notifier which is not defined in this case.
>
> For that reason, I have removed the patch from the list of applied patches for -next.
> Please re-submit a version which compiles for all combinations of HOTPLUG_CPU and SMP
> defined/undefined.
>
> Thanks,
> Guenter
>
Sorry for late. I just come back from my holiday. If only this one patch
is applied, it is broken, but it will be OK after these 2 patches are
applied. I tested the patches when CONFIG_SMP is undefined, it does be
broken again. My suggestion is adding a macro definiton in the pkgtemp.c
like "#include <asm/smp.h>". If it is doable, I will re-post a new patch
series

^ permalink raw reply

* Problem with Infiniband adapter on IBM p550
From: Patrick Finnegan @ 2010-10-08  3:24 UTC (permalink / raw)
  To: linuxppc-dev@lists.ozlabs.org

I seem to be running into a problem getting a Mellanox Infinihost  
Infiniband adapter working on my IBM p550 (a 9113-550).  I'm using 
Debian squeeze, and tried upgrading to the 2.6.35.7 kernel without any 
help.

I get the following messages in dmesg:
[    4.972548] ib_mthca: Mellanox InfiniBand HCA driver v1.0 (April 4, 
2008)
[    4.972564] ib_mthca: Initializing 0000:c1:00.0
[    4.972674] ib_mthca 0000:c1:00.0: Missing DCS, aborting.


The problem looks the same as a problem I ran into with OpenFirmware on 
a Sun V880, which was fixed with this patch by Dave Miller:
http://ns3.spinics.net/lists/linux-rdma/msg01779.html

I spent some time looking at the equivalent function on powerpc, but 
didn't a block of code that looked similar.

Any suggestions?

I have dmesg, the dev .properties from openfirmware, and lspci -v from 
the machine:

http://ned.rcac.purdue.edu/p550-ib/dmesg
http://ned.rcac.purdue.edu/p550-ib/ib-of-device
http://ned.rcac.purdue.edu/p550-ib/lspci-v

Pat
-- 
Purdue University Research Computing ---  http://www.rcac.purdue.edu/
The Computer Refuge                  ---  http://computer-refuge.org

^ permalink raw reply

* linux-next: manual merge of the hwpoison tree with Linus' tree
From: Stephen Rothwell @ 2010-10-08  3:40 UTC (permalink / raw)
  To: Andi Kleen; +Cc: linux-next, linux-kernel

Hi Andi,

Today's linux-next merge of the hwpoison tree got a conflict in
mm/memory-failure.c between commit
0d9ee6a2d4a6e92c49e6fa9469e5731d21ee203e ("HWPOISON: Report correct
address granuality for AO huge page errors") from Linus' tree and commit
3c5ca5455796841ac3cd706a91ba8dada908c375 ("HWPOISON: Report correct
address granuality for AO huge page errors") from the hwpoison tree.

Slightly different versions of the same patch.  I used the version from
Linus' tree (since it was committed later).  The conflict looked like this:

diff --cc mm/memory-failure.c
index 757f6b0,0966b6a..0000000
--- a/mm/memory-failure.c
+++ b/mm/memory-failure.c
@@@ -198,7 -203,8 +203,12 @@@ static int kill_proc_ao(struct task_str
  #ifdef __ARCH_SI_TRAPNO
  	si.si_trapno = trapno;
  #endif
++<<<<<<< HEAD
 +	si.si_addr_lsb = compound_order(compound_head(page)) + PAGE_SHIFT;
++=======
+ 	order = PageCompound(page) ? huge_page_order(page) : PAGE_SHIFT;
+ 	si.si_addr_lsb = order;
++>>>>>>> hwpoison/hwpoison
  	/*
  	 * Don't use force here, it's convenient if the signal
  	 * can be temporarily blocked.

-- 
Cheers,
Stephen Rothwell                    sfr@canb.auug.org.au
http://www.canb.auug.org.au/~sfr/

^ permalink raw reply

* [U-Boot] [PATCH] board/mpl: Remove mpl-specific memory test command
From: Peter Tyser @ 2010-10-08  3:39 UTC (permalink / raw)
  To: u-boot
In-Reply-To: <20101006202757.4F7A7153A7E@gemini.denx.de>

On Wed, 2010-10-06 at 22:27 +0200, Wolfgang Denk wrote:
> Dear Peter Tyser,
> 
> In message <1286340527-29498-1-git-send-email-ptyser@xes-inc.com> you wrote:
> > The mpl-specfic memory test is only documented for one board, doesn't
> > compile cleanly, uses improper coding style, and overlaps functionality
> > with U-Boot's common 'mtest' command, so lets get rid of it.
> > 
> > Signed-off-by: Peter Tyser <ptyser@xes-inc.com>
> > CC: d.peter at mpl.ch
> > CC: d.mueller at elsoft.ch
> > CC: wdenk at denx.de
> 
> 
> Do you happen to know where this incorrect email address is coming
> from?  I never had any such problems, but in the last few days more
> and more people seem to pick up that bad address?

This was just a typo on my part.  I normally use git email aliases or my
mail client's address book, but this time I manually typed in your
address in the patch, and failed.

> > The few snippets of code I looked at in board/mpl were extremely ugly; I'm
> > assuming these board ports aren't really maintained.  Would anyone
> > complain if I removed them?
> 
> I think you are right.  If you have tiome, please submit patches to
> remove these, then we will see if anybody cares.

Will do.

Regards,
Peter

^ permalink raw reply

* Re: [ath5k-devel] Kernel panic
From: Bruno Randolf @ 2010-10-08  3:38 UTC (permalink / raw)
  To: Jonathan Guerin; +Cc: ath5k-devel, linux-wireless
In-Reply-To: <AANLkTimYvHy8XFkHNFLdLmReY2bvTbTgA2oTeQ4uDByR@mail.gmail.com>

On Fri October 8 2010 12:32:26 Jonathan Guerin wrote:
> I've just looked for changes in ath5k which were submitted after
> 2.6.35 was released and found this patch. I won't pretend to
> understand what's been changed, but could it be causing the panics I'm
> observing?

unless we messed up somewhere, this patch should not have any effect, except 
for reordering code. the generated object file should be the same.

bruno
 
> Thanks,
> 
> Jonathan Guerin
> 
> On Fri, Sep 17, 2010 at 1:45 PM, Bruno Randolf <br1@einfach.org> wrote:
> > From: Bob Copeland <me@bobcopeland.com>
> > 
> > This change reorganizes the main ath5k file in order to re-group
> > related functions and remove most of the forward declarations
> > (from 61 down to 3).  This is, unfortunately, a lot of churn, but
> > there should be no functional changes.
> > 
> > Signed-off-by: Bob Copeland <me@bobcopeland.com>
> > Signed-off-by: Bruno Randolf <br1@einfach.org>
> > 
> > ---
> > Bruno: rebased to wireless-next
> > v2: resent because i lost the subject line before
> > ---
> > 
> >  drivers/net/wireless/ath/ath5k/base.c | 1662
> >  +++++++++++++++------------------ 1 files changed, 764 insertions(+),
> >  898 deletions(-)
> > 
> > diff --git a/drivers/net/wireless/ath/ath5k/base.c
> > b/drivers/net/wireless/ath/ath5k/base.c index f8c699d..9e4636f 100644
> > --- a/drivers/net/wireless/ath/ath5k/base.c
> > +++ b/drivers/net/wireless/ath/ath5k/base.c
> > @@ -70,11 +70,6 @@ static int modparam_all_channels;
> > 
> >  module_param_named(all_channels, modparam_all_channels, bool, S_IRUGO);
> >  MODULE_PARM_DESC(all_channels, "Expose all channels the device can
> >  use.");
> > 
> > -
> > -/******************\
> > -* Internal defines *
> > -\******************/
> > -
> > 
> >  /* Module info */
> >  MODULE_AUTHOR("Jiri Slaby");
> >  MODULE_AUTHOR("Nick Kossifidis");
> > 
> > @@ -83,6 +78,10 @@ MODULE_SUPPORTED_DEVICE("Atheros 5xxx WLAN cards");
> > 
> >  MODULE_LICENSE("Dual BSD/GPL");
> >  MODULE_VERSION("0.6.0 (EXPERIMENTAL)");
> > 
> > +static int ath5k_reset(struct ath5k_softc *sc, struct ieee80211_channel
> > *chan); +static int ath5k_beacon_update(struct ieee80211_hw *hw,
> > +               struct ieee80211_vif *vif);
> > +static void ath5k_beacon_update_timers(struct ath5k_softc *sc, u64
> > bc_tsf);
> > 
> >  /* Known PCI ids */
> >  static DEFINE_PCI_DEVICE_TABLE(ath5k_pci_id_table) = {
> > 
> > @@ -190,129 +189,6 @@ static const struct ieee80211_rate ath5k_rates[] =
> > {
> > 
> >        /* XR missing */
> >  
> >  };
> > 
> > -/*
> > - * Prototypes - PCI stack related functions
> > - */
> > -static int __devinit   ath5k_pci_probe(struct pci_dev *pdev,
> > -                               const struct pci_device_id *id);
> > -static void __devexit  ath5k_pci_remove(struct pci_dev *pdev);
> > -#ifdef CONFIG_PM_SLEEP
> > -static int             ath5k_pci_suspend(struct device *dev);
> > -static int             ath5k_pci_resume(struct device *dev);
> > -
> > -static SIMPLE_DEV_PM_OPS(ath5k_pm_ops, ath5k_pci_suspend,
> > ath5k_pci_resume); -#define ATH5K_PM_OPS   (&ath5k_pm_ops)
> > -#else
> > -#define ATH5K_PM_OPS   NULL
> > -#endif /* CONFIG_PM_SLEEP */
> > -
> > -static struct pci_driver ath5k_pci_driver = {
> > -       .name           = KBUILD_MODNAME,
> > -       .id_table       = ath5k_pci_id_table,
> > -       .probe          = ath5k_pci_probe,
> > -       .remove         = __devexit_p(ath5k_pci_remove),
> > -       .driver.pm      = ATH5K_PM_OPS,
> > -};
> > -
> > -
> > -
> > -/*
> > - * Prototypes - MAC 802.11 stack related functions
> > - */
> > -static int ath5k_tx(struct ieee80211_hw *hw, struct sk_buff *skb);
> > -static int ath5k_tx_queue(struct ieee80211_hw *hw, struct sk_buff *skb,
> > -               struct ath5k_txq *txq);
> > -static int ath5k_reset(struct ath5k_softc *sc, struct ieee80211_channel
> > *chan); -static int ath5k_start(struct ieee80211_hw *hw);
> > -static void ath5k_stop(struct ieee80211_hw *hw);
> > -static int ath5k_add_interface(struct ieee80211_hw *hw,
> > -               struct ieee80211_vif *vif);
> > -static void ath5k_remove_interface(struct ieee80211_hw *hw,
> > -               struct ieee80211_vif *vif);
> > -static int ath5k_config(struct ieee80211_hw *hw, u32 changed);
> > -static u64 ath5k_prepare_multicast(struct ieee80211_hw *hw,
> > -                                  struct netdev_hw_addr_list *mc_list);
> > -static void ath5k_configure_filter(struct ieee80211_hw *hw,
> > -               unsigned int changed_flags,
> > -               unsigned int *new_flags,
> > -               u64 multicast);
> > -static int ath5k_set_key(struct ieee80211_hw *hw,
> > -               enum set_key_cmd cmd,
> > -               struct ieee80211_vif *vif, struct ieee80211_sta *sta,
> > -               struct ieee80211_key_conf *key);
> > -static int ath5k_get_stats(struct ieee80211_hw *hw,
> > -               struct ieee80211_low_level_stats *stats);
> > -static int ath5k_get_survey(struct ieee80211_hw *hw,
> > -               int idx, struct survey_info *survey);
> > -static u64 ath5k_get_tsf(struct ieee80211_hw *hw);
> > -static void ath5k_set_tsf(struct ieee80211_hw *hw, u64 tsf);
> > -static void ath5k_reset_tsf(struct ieee80211_hw *hw);
> > -static int ath5k_beacon_update(struct ieee80211_hw *hw,
> > -               struct ieee80211_vif *vif);
> > -static void ath5k_bss_info_changed(struct ieee80211_hw *hw,
> > -               struct ieee80211_vif *vif,
> > -               struct ieee80211_bss_conf *bss_conf,
> > -               u32 changes);
> > -static void ath5k_sw_scan_start(struct ieee80211_hw *hw);
> > -static void ath5k_sw_scan_complete(struct ieee80211_hw *hw);
> > -static void ath5k_set_coverage_class(struct ieee80211_hw *hw,
> > -               u8 coverage_class);
> > -
> > -static const struct ieee80211_ops ath5k_hw_ops = {
> > -       .tx             = ath5k_tx,
> > -       .start          = ath5k_start,
> > -       .stop           = ath5k_stop,
> > -       .add_interface  = ath5k_add_interface,
> > -       .remove_interface = ath5k_remove_interface,
> > -       .config         = ath5k_config,
> > -       .prepare_multicast = ath5k_prepare_multicast,
> > -       .configure_filter = ath5k_configure_filter,
> > -       .set_key        = ath5k_set_key,
> > -       .get_stats      = ath5k_get_stats,
> > -       .get_survey     = ath5k_get_survey,
> > -       .conf_tx        = NULL,
> > -       .get_tsf        = ath5k_get_tsf,
> > -       .set_tsf        = ath5k_set_tsf,
> > -       .reset_tsf      = ath5k_reset_tsf,
> > -       .bss_info_changed = ath5k_bss_info_changed,
> > -       .sw_scan_start  = ath5k_sw_scan_start,
> > -       .sw_scan_complete = ath5k_sw_scan_complete,
> > -       .set_coverage_class = ath5k_set_coverage_class,
> > -};
> > -
> > -/*
> > - * Prototypes - Internal functions
> > - */
> > -/* Attach detach */
> > -static int     ath5k_attach(struct pci_dev *pdev,
> > -                       struct ieee80211_hw *hw);
> > -static void    ath5k_detach(struct pci_dev *pdev,
> > -                       struct ieee80211_hw *hw);
> > -/* Channel/mode setup */
> > -static inline short ath5k_ieee2mhz(short chan);
> > -static unsigned int ath5k_copy_channels(struct ath5k_hw *ah,
> > -                               struct ieee80211_channel *channels,
> > -                               unsigned int mode,
> > -                               unsigned int max);
> > -static int     ath5k_setup_bands(struct ieee80211_hw *hw);
> > -static int     ath5k_chan_set(struct ath5k_softc *sc,
> > -                               struct ieee80211_channel *chan);
> > -static void    ath5k_setcurmode(struct ath5k_softc *sc,
> > -                               unsigned int mode);
> > -static void    ath5k_mode_setup(struct ath5k_softc *sc);
> > -
> > -/* Descriptor setup */
> > -static int     ath5k_desc_alloc(struct ath5k_softc *sc,
> > -                               struct pci_dev *pdev);
> > -static void    ath5k_desc_free(struct ath5k_softc *sc,
> > -                               struct pci_dev *pdev);
> > -/* Buffers setup */
> > -static int     ath5k_rxbuf_setup(struct ath5k_softc *sc,
> > -                               struct ath5k_buf *bf);
> > -static int     ath5k_txbuf_setup(struct ath5k_softc *sc,
> > -                               struct ath5k_buf *bf,
> > -                               struct ath5k_txq *txq, int padsize);
> > -
> > 
> >  static inline void ath5k_txbuf_free_skb(struct ath5k_softc *sc,
> >  
> >                                struct ath5k_buf *bf)
> >  
> >  {
> > 
> > @@ -345,35 +221,6 @@ static inline void ath5k_rxbuf_free_skb(struct
> > ath5k_softc *sc,
> > 
> >  }
> > 
> > -/* Queues setup */
> > -static struct  ath5k_txq *ath5k_txq_setup(struct ath5k_softc *sc,
> > -                               int qtype, int subtype);
> > -static int     ath5k_beaconq_setup(struct ath5k_hw *ah);
> > -static int     ath5k_beaconq_config(struct ath5k_softc *sc);
> > -static void    ath5k_txq_drainq(struct ath5k_softc *sc,
> > -                               struct ath5k_txq *txq);
> > -static void    ath5k_txq_cleanup(struct ath5k_softc *sc);
> > -static void    ath5k_txq_release(struct ath5k_softc *sc);
> > -/* Rx handling */
> > -static int     ath5k_rx_start(struct ath5k_softc *sc);
> > -static void    ath5k_rx_stop(struct ath5k_softc *sc);
> > -static unsigned int ath5k_rx_decrypted(struct ath5k_softc *sc,
> > -                                       struct sk_buff *skb,
> > -                                       struct ath5k_rx_status *rs);
> > -static void    ath5k_tasklet_rx(unsigned long data);
> > -/* Tx handling */
> > -static void    ath5k_tx_processq(struct ath5k_softc *sc,
> > -                               struct ath5k_txq *txq);
> > -static void    ath5k_tasklet_tx(unsigned long data);
> > -/* Beacon handling */
> > -static int     ath5k_beacon_setup(struct ath5k_softc *sc,
> > -                                       struct ath5k_buf *bf);
> > -static void    ath5k_beacon_send(struct ath5k_softc *sc);
> > -static void    ath5k_beacon_config(struct ath5k_softc *sc);
> > -static void    ath5k_beacon_update_timers(struct ath5k_softc *sc, u64
> > bc_tsf); -static void    ath5k_tasklet_beacon(unsigned long data);
> > -static void    ath5k_tasklet_ani(unsigned long data);
> > -
> > 
> >  static inline u64 ath5k_extend_tsf(struct ath5k_hw *ah, u32 rstamp)
> >  {
> >  
> >        u64 tsf = ath5k_hw_get_tsf64(ah);
> > 
> > @@ -384,50 +231,6 @@ static inline u64 ath5k_extend_tsf(struct ath5k_hw
> > *ah, u32 rstamp)
> > 
> >        return (tsf & ~0x7fff) | rstamp;
> >  
> >  }
> > 
> > -/* Interrupt handling */
> > -static int     ath5k_init(struct ath5k_softc *sc);
> > -static int     ath5k_stop_locked(struct ath5k_softc *sc);
> > -static int     ath5k_stop_hw(struct ath5k_softc *sc);
> > -static irqreturn_t ath5k_intr(int irq, void *dev_id);
> > -static void ath5k_reset_work(struct work_struct *work);
> > -
> > -static void    ath5k_tasklet_calibrate(unsigned long data);
> > -
> > -/*
> > - * Module init/exit functions
> > - */
> > -static int __init
> > -init_ath5k_pci(void)
> > -{
> > -       int ret;
> > -
> > -       ath5k_debug_init();
> > -
> > -       ret = pci_register_driver(&ath5k_pci_driver);
> > -       if (ret) {
> > -               printk(KERN_ERR "ath5k_pci: can't register pci
> > driver\n"); -               return ret;
> > -       }
> > -
> > -       return 0;
> > -}
> > -
> > -static void __exit
> > -exit_ath5k_pci(void)
> > -{
> > -       pci_unregister_driver(&ath5k_pci_driver);
> > -
> > -       ath5k_debug_finish();
> > -}
> > -
> > -module_init(init_ath5k_pci);
> > -module_exit(exit_ath5k_pci);
> > -
> > -
> > -/********************\
> > -* PCI Initialization *
> > -\********************/
> > -
> > 
> >  static const char *
> >  ath5k_chip_name(enum ath5k_srev_type type, u_int16_t val)
> >  {
> > 
> > @@ -466,299 +269,6 @@ static const struct ath_ops ath5k_common_ops = {
> > 
> >        .write = ath5k_iowrite32,
> >  
> >  };
> > 
> > -static int __devinit
> > -ath5k_pci_probe(struct pci_dev *pdev,
> > -               const struct pci_device_id *id)
> > -{
> > -       void __iomem *mem;
> > -       struct ath5k_softc *sc;
> > -       struct ath_common *common;
> > -       struct ieee80211_hw *hw;
> > -       int ret;
> > -       u8 csz;
> > -
> > -       /*
> > -        * L0s needs to be disabled on all ath5k cards.
> > -        *
> > -        * For distributions shipping with CONFIG_PCIEASPM (this will be
> > enabled -        * by default in the future in 2.6.36) this will also
> > mean both L1 and -        * L0s will be disabled when a pre 1.1 PCIe
> > device is detected. We do -        * know L1 works correctly even for
> > all ath5k pre 1.1 PCIe devices -        * though but cannot currently
> > undue the effect of a blacklist, for -        * details you can read
> > pcie_aspm_sanity_check() and see how it adjusts -        * the device
> > link capability.
> > -        *
> > -        * It may be possible in the future to implement some PCI API to
> > allow -        * drivers to override blacklists for pre 1.1 PCIe but for
> > now it is -        * best to accept that both L0s and L1 will be
> > disabled completely for -        * distributions shipping with
> > CONFIG_PCIEASPM rather than having this -        * issue present.
> > Motivation for adding this new API will be to help -        * with power
> > consumption for some of these devices.
> > -        */
> > -       pci_disable_link_state(pdev, PCIE_LINK_STATE_L0S);
> > -
> > -       ret = pci_enable_device(pdev);
> > -       if (ret) {
> > -               dev_err(&pdev->dev, "can't enable device\n");
> > -               goto err;
> > -       }
> > -
> > -       /* XXX 32-bit addressing only */
> > -       ret = pci_set_dma_mask(pdev, DMA_BIT_MASK(32));
> > -       if (ret) {
> > -               dev_err(&pdev->dev, "32-bit DMA not available\n");
> > -               goto err_dis;
> > -       }
> > -
> > -       /*
> > -        * Cache line size is used to size and align various
> > -        * structures used to communicate with the hardware.
> > -        */
> > -       pci_read_config_byte(pdev, PCI_CACHE_LINE_SIZE, &csz);
> > -       if (csz == 0) {
> > -               /*
> > -                * Linux 2.4.18 (at least) writes the cache line size
> > -                * register as a 16-bit wide register which is wrong.
> > -                * We must have this setup properly for rx buffer
> > -                * DMA to work so force a reasonable value here if it
> > -                * comes up zero.
> > -                */
> > -               csz = L1_CACHE_BYTES >> 2;
> > -               pci_write_config_byte(pdev, PCI_CACHE_LINE_SIZE, csz);
> > -       }
> > -       /*
> > -        * The default setting of latency timer yields poor results,
> > -        * set it to the value used by other systems.  It may be worth
> > -        * tweaking this setting more.
> > -        */
> > -       pci_write_config_byte(pdev, PCI_LATENCY_TIMER, 0xa8);
> > -
> > -       /* Enable bus mastering */
> > -       pci_set_master(pdev);
> > -
> > -       /*
> > -        * Disable the RETRY_TIMEOUT register (0x41) to keep
> > -        * PCI Tx retries from interfering with C3 CPU state.
> > -        */
> > -       pci_write_config_byte(pdev, 0x41, 0);
> > -
> > -       ret = pci_request_region(pdev, 0, "ath5k");
> > -       if (ret) {
> > -               dev_err(&pdev->dev, "cannot reserve PCI memory
> > region\n"); -               goto err_dis;
> > -       }
> > -
> > -       mem = pci_iomap(pdev, 0, 0);
> > -       if (!mem) {
> > -               dev_err(&pdev->dev, "cannot remap PCI memory region\n") ;
> > -               ret = -EIO;
> > -               goto err_reg;
> > -       }
> > -
> > -       /*
> > -        * Allocate hw (mac80211 main struct)
> > -        * and hw->priv (driver private data)
> > -        */
> > -       hw = ieee80211_alloc_hw(sizeof(*sc), &ath5k_hw_ops);
> > -       if (hw == NULL) {
> > -               dev_err(&pdev->dev, "cannot allocate ieee80211_hw\n");
> > -               ret = -ENOMEM;
> > -               goto err_map;
> > -       }
> > -
> > -       dev_info(&pdev->dev, "registered as '%s'\n",
> > wiphy_name(hw->wiphy)); -
> > -       /* Initialize driver private data */
> > -       SET_IEEE80211_DEV(hw, &pdev->dev);
> > -       hw->flags = IEEE80211_HW_RX_INCLUDES_FCS |
> > -                   IEEE80211_HW_HOST_BROADCAST_PS_BUFFERING |
> > -                   IEEE80211_HW_SIGNAL_DBM;
> > -
> > -       hw->wiphy->interface_modes =
> > -               BIT(NL80211_IFTYPE_AP) |
> > -               BIT(NL80211_IFTYPE_STATION) |
> > -               BIT(NL80211_IFTYPE_ADHOC) |
> > -               BIT(NL80211_IFTYPE_MESH_POINT);
> > -
> > -       hw->extra_tx_headroom = 2;
> > -       hw->channel_change_time = 5000;
> > -       sc = hw->priv;
> > -       sc->hw = hw;
> > -       sc->pdev = pdev;
> > -
> > -       ath5k_debug_init_device(sc);
> > -
> > -       /*
> > -        * Mark the device as detached to avoid processing
> > -        * interrupts until setup is complete.
> > -        */
> > -       __set_bit(ATH_STAT_INVALID, sc->status);
> > -
> > -       sc->iobase = mem; /* So we can unmap it on detach */
> > -       sc->opmode = NL80211_IFTYPE_STATION;
> > -       sc->bintval = 1000;
> > -       mutex_init(&sc->lock);
> > -       spin_lock_init(&sc->rxbuflock);
> > -       spin_lock_init(&sc->txbuflock);
> > -       spin_lock_init(&sc->block);
> > -
> > -       /* Set private data */
> > -       pci_set_drvdata(pdev, sc);
> > -
> > -       /* Setup interrupt handler */
> > -       ret = request_irq(pdev->irq, ath5k_intr, IRQF_SHARED, "ath", sc);
> > -       if (ret) {
> > -               ATH5K_ERR(sc, "request_irq failed\n");
> > -               goto err_free;
> > -       }
> > -
> > -       /* If we passed the test, malloc an ath5k_hw struct */
> > -       sc->ah = kzalloc(sizeof(struct ath5k_hw), GFP_KERNEL);
> > -       if (!sc->ah) {
> > -               ret = -ENOMEM;
> > -               ATH5K_ERR(sc, "out of memory\n");
> > -               goto err_irq;
> > -       }
> > -
> > -       sc->ah->ah_sc = sc;
> > -       sc->ah->ah_iobase = sc->iobase;
> > -       common = ath5k_hw_common(sc->ah);
> > -       common->ops = &ath5k_common_ops;
> > -       common->ah = sc->ah;
> > -       common->hw = hw;
> > -       common->cachelsz = csz << 2; /* convert to bytes */
> > -
> > -       /* Initialize device */
> > -       ret = ath5k_hw_attach(sc);
> > -       if (ret) {
> > -               goto err_free_ah;
> > -       }
> > -
> > -       /* set up multi-rate retry capabilities */
> > -       if (sc->ah->ah_version == AR5K_AR5212) {
> > -               hw->max_rates = 4;
> > -               hw->max_rate_tries = 11;
> > -       }
> > -
> > -       /* Finish private driver data initialization */
> > -       ret = ath5k_attach(pdev, hw);
> > -       if (ret)
> > -               goto err_ah;
> > -
> > -       ATH5K_INFO(sc, "Atheros AR%s chip found (MAC: 0x%x, PHY:
> > 0x%x)\n", -                       ath5k_chip_name(AR5K_VERSION_MAC,
> > sc->ah->ah_mac_srev), -                                      
> > sc->ah->ah_mac_srev,
> > -                                       sc->ah->ah_phy_revision);
> > -
> > -       if (!sc->ah->ah_single_chip) {
> > -               /* Single chip radio (!RF5111) */
> > -               if (sc->ah->ah_radio_5ghz_revision &&
> > -                       !sc->ah->ah_radio_2ghz_revision) {
> > -                       /* No 5GHz support -> report 2GHz radio */
> > -                       if (!test_bit(AR5K_MODE_11A,
> > -                               sc->ah->ah_capabilities.cap_mode)) {
> > -                               ATH5K_INFO(sc, "RF%s 2GHz radio found
> > (0x%x)\n", -                                      
> > ath5k_chip_name(AR5K_VERSION_RAD, -                                     
> >          sc->ah->ah_radio_5ghz_revision), -                             
> >                  sc->ah->ah_radio_5ghz_revision); -                     
> >  /* No 2GHz support (5110 and some
> > -                        * 5Ghz only cards) -> report 5Ghz radio */
> > -                       } else if (!test_bit(AR5K_MODE_11B,
> > -                               sc->ah->ah_capabilities.cap_mode)) {
> > -                               ATH5K_INFO(sc, "RF%s 5GHz radio found
> > (0x%x)\n", -                                      
> > ath5k_chip_name(AR5K_VERSION_RAD, -                                     
> >          sc->ah->ah_radio_5ghz_revision), -                             
> >                  sc->ah->ah_radio_5ghz_revision); -                     
> >  /* Multiband radio */
> > -                       } else {
> > -                               ATH5K_INFO(sc, "RF%s multiband radio
> > found" -                                       " (0x%x)\n",
> > -                                       ath5k_chip_name(AR5K_VERSION_RAD,
> > -                                              
> > sc->ah->ah_radio_5ghz_revision), -                                      
> >         sc->ah->ah_radio_5ghz_revision); -                       }
> > -               }
> > -               /* Multi chip radio (RF5111 - RF2111) ->
> > -                * report both 2GHz/5GHz radios */
> > -               else if (sc->ah->ah_radio_5ghz_revision &&
> > -                               sc->ah->ah_radio_2ghz_revision){
> > -                       ATH5K_INFO(sc, "RF%s 5GHz radio found (0x%x)\n",
> > -                               ath5k_chip_name(AR5K_VERSION_RAD,
> > -                                       sc->ah->ah_radio_5ghz_revision),
> > -                                       sc->ah->ah_radio_5ghz_revision);
> > -                       ATH5K_INFO(sc, "RF%s 2GHz radio found (0x%x)\n",
> > -                               ath5k_chip_name(AR5K_VERSION_RAD,
> > -                                       sc->ah->ah_radio_2ghz_revision),
> > -                                       sc->ah->ah_radio_2ghz_revision);
> > -               }
> > -       }
> > -
> > -
> > -       /* ready to process interrupts */
> > -       __clear_bit(ATH_STAT_INVALID, sc->status);
> > -
> > -       return 0;
> > -err_ah:
> > -       ath5k_hw_detach(sc->ah);
> > -err_free_ah:
> > -       kfree(sc->ah);
> > -err_irq:
> > -       free_irq(pdev->irq, sc);
> > -err_free:
> > -       ieee80211_free_hw(hw);
> > -err_map:
> > -       pci_iounmap(pdev, mem);
> > -err_reg:
> > -       pci_release_region(pdev, 0);
> > -err_dis:
> > -       pci_disable_device(pdev);
> > -err:
> > -       return ret;
> > -}
> > -
> > -static void __devexit
> > -ath5k_pci_remove(struct pci_dev *pdev)
> > -{
> > -       struct ath5k_softc *sc = pci_get_drvdata(pdev);
> > -
> > -       ath5k_debug_finish_device(sc);
> > -       ath5k_detach(pdev, sc->hw);
> > -       ath5k_hw_detach(sc->ah);
> > -       kfree(sc->ah);
> > -       free_irq(pdev->irq, sc);
> > -       pci_iounmap(pdev, sc->iobase);
> > -       pci_release_region(pdev, 0);
> > -       pci_disable_device(pdev);
> > -       ieee80211_free_hw(sc->hw);
> > -}
> > -
> > -#ifdef CONFIG_PM_SLEEP
> > -static int ath5k_pci_suspend(struct device *dev)
> > -{
> > -       struct ath5k_softc *sc = pci_get_drvdata(to_pci_dev(dev));
> > -
> > -       ath5k_led_off(sc);
> > -       return 0;
> > -}
> > -
> > -static int ath5k_pci_resume(struct device *dev)
> > -{
> > -       struct pci_dev *pdev = to_pci_dev(dev);
> > -       struct ath5k_softc *sc = pci_get_drvdata(pdev);
> > -
> > -       /*
> > -        * Suspend/Resume resets the PCI configuration space, so we have
> > to -        * re-disable the RETRY_TIMEOUT register (0x41) to keep
> > -        * PCI Tx retries from interfering with C3 CPU state
> > -        */
> > -       pci_write_config_byte(pdev, 0x41, 0);
> > -
> > -       ath5k_led_enable(sc);
> > -       return 0;
> > -}
> > -#endif /* CONFIG_PM_SLEEP */
> > -
> > -
> > 
> >  /***********************\
> >  * Driver Initialization *
> >  \***********************/
> > 
> > @@ -772,170 +282,6 @@ static int ath5k_reg_notifier(struct wiphy *wiphy,
> > struct regulatory_request *re
> > 
> >        return ath_reg_notifier_apply(wiphy, request, regulatory);
> >  
> >  }
> > 
> > -static int
> > -ath5k_attach(struct pci_dev *pdev, struct ieee80211_hw *hw)
> > -{
> > -       struct ath5k_softc *sc = hw->priv;
> > -       struct ath5k_hw *ah = sc->ah;
> > -       struct ath_regulatory *regulatory = ath5k_hw_regulatory(ah);
> > -       u8 mac[ETH_ALEN] = {};
> > -       int ret;
> > -
> > -       ATH5K_DBG(sc, ATH5K_DEBUG_ANY, "devid 0x%x\n", pdev->device);
> > -
> > -       /*
> > -        * Check if the MAC has multi-rate retry support.
> > -        * We do this by trying to setup a fake extended
> > -        * descriptor.  MACs that don't have support will
> > -        * return false w/o doing anything.  MACs that do
> > -        * support it will return true w/o doing anything.
> > -        */
> > -       ret = ath5k_hw_setup_mrr_tx_desc(ah, NULL, 0, 0, 0, 0, 0, 0);
> > -
> > -       if (ret < 0)
> > -               goto err;
> > -       if (ret > 0)
> > -               __set_bit(ATH_STAT_MRRETRY, sc->status);
> > -
> > -       /*
> > -        * Collect the channel list.  The 802.11 layer
> > -        * is resposible for filtering this list based
> > -        * on settings like the phy mode and regulatory
> > -        * domain restrictions.
> > -        */
> > -       ret = ath5k_setup_bands(hw);
> > -       if (ret) {
> > -               ATH5K_ERR(sc, "can't get channels\n");
> > -               goto err;
> > -       }
> > -
> > -       /* NB: setup here so ath5k_rate_update is happy */
> > -       if (test_bit(AR5K_MODE_11A, ah->ah_modes))
> > -               ath5k_setcurmode(sc, AR5K_MODE_11A);
> > -       else
> > -               ath5k_setcurmode(sc, AR5K_MODE_11B);
> > -
> > -       /*
> > -        * Allocate tx+rx descriptors and populate the lists.
> > -        */
> > -       ret = ath5k_desc_alloc(sc, pdev);
> > -       if (ret) {
> > -               ATH5K_ERR(sc, "can't allocate descriptors\n");
> > -               goto err;
> > -       }
> > -
> > -       /*
> > -        * Allocate hardware transmit queues: one queue for
> > -        * beacon frames and one data queue for each QoS
> > -        * priority.  Note that hw functions handle resetting
> > -        * these queues at the needed time.
> > -        */
> > -       ret = ath5k_beaconq_setup(ah);
> > -       if (ret < 0) {
> > -               ATH5K_ERR(sc, "can't setup a beacon xmit queue\n");
> > -               goto err_desc;
> > -       }
> > -       sc->bhalq = ret;
> > -       sc->cabq = ath5k_txq_setup(sc, AR5K_TX_QUEUE_CAB, 0);
> > -       if (IS_ERR(sc->cabq)) {
> > -               ATH5K_ERR(sc, "can't setup cab queue\n");
> > -               ret = PTR_ERR(sc->cabq);
> > -               goto err_bhal;
> > -       }
> > -
> > -       sc->txq = ath5k_txq_setup(sc, AR5K_TX_QUEUE_DATA,
> > AR5K_WME_AC_BK); -       if (IS_ERR(sc->txq)) {
> > -               ATH5K_ERR(sc, "can't setup xmit queue\n");
> > -               ret = PTR_ERR(sc->txq);
> > -               goto err_queues;
> > -       }
> > -
> > -       tasklet_init(&sc->rxtq, ath5k_tasklet_rx, (unsigned long)sc);
> > -       tasklet_init(&sc->txtq, ath5k_tasklet_tx, (unsigned long)sc);
> > -       tasklet_init(&sc->calib, ath5k_tasklet_calibrate, (unsigned
> > long)sc); -       tasklet_init(&sc->beacontq, ath5k_tasklet_beacon,
> > (unsigned long)sc); -       tasklet_init(&sc->ani_tasklet,
> > ath5k_tasklet_ani, (unsigned long)sc); -
> > -       INIT_WORK(&sc->reset_work, ath5k_reset_work);
> > -
> > -       ret = ath5k_eeprom_read_mac(ah, mac);
> > -       if (ret) {
> > -               ATH5K_ERR(sc, "unable to read address from EEPROM:
> > 0x%04x\n", -                       sc->pdev->device);
> > -               goto err_queues;
> > -       }
> > -
> > -       SET_IEEE80211_PERM_ADDR(hw, mac);
> > -       /* All MAC address bits matter for ACKs */
> > -       memcpy(sc->bssidmask, ath_bcast_mac, ETH_ALEN);
> > -       ath5k_hw_set_bssid_mask(sc->ah, sc->bssidmask);
> > -
> > -       regulatory->current_rd =
> > ah->ah_capabilities.cap_eeprom.ee_regdomain; -       ret =
> > ath_regd_init(regulatory, hw->wiphy, ath5k_reg_notifier); -       if
> > (ret) {
> > -               ATH5K_ERR(sc, "can't initialize regulatory system\n");
> > -               goto err_queues;
> > -       }
> > -
> > -       ret = ieee80211_register_hw(hw);
> > -       if (ret) {
> > -               ATH5K_ERR(sc, "can't register ieee80211 hw\n");
> > -               goto err_queues;
> > -       }
> > -
> > -       if (!ath_is_world_regd(regulatory))
> > -               regulatory_hint(hw->wiphy, regulatory->alpha2);
> > -
> > -       ath5k_init_leds(sc);
> > -
> > -       ath5k_sysfs_register(sc);
> > -
> > -       return 0;
> > -err_queues:
> > -       ath5k_txq_release(sc);
> > -err_bhal:
> > -       ath5k_hw_release_tx_queue(ah, sc->bhalq);
> > -err_desc:
> > -       ath5k_desc_free(sc, pdev);
> > -err:
> > -       return ret;
> > -}
> > -
> > -static void
> > -ath5k_detach(struct pci_dev *pdev, struct ieee80211_hw *hw)
> > -{
> > -       struct ath5k_softc *sc = hw->priv;
> > -
> > -       /*
> > -        * NB: the order of these is important:
> > -        * o call the 802.11 layer before detaching ath5k_hw to
> > -        *   ensure callbacks into the driver to delete global
> > -        *   key cache entries can be handled
> > -        * o reclaim the tx queue data structures after calling
> > -        *   the 802.11 layer as we'll get called back to reclaim
> > -        *   node state and potentially want to use them
> > -        * o to cleanup the tx queues the hal is called, so detach
> > -        *   it last
> > -        * XXX: ??? detach ath5k_hw ???
> > -        * Other than that, it's straightforward...
> > -        */
> > -       ieee80211_unregister_hw(hw);
> > -       ath5k_desc_free(sc, pdev);
> > -       ath5k_txq_release(sc);
> > -       ath5k_hw_release_tx_queue(sc->ah, sc->bhalq);
> > -       ath5k_unregister_leds(sc);
> > -
> > -       ath5k_sysfs_unregister(sc);
> > -       /*
> > -        * NB: can't reclaim these until after ieee80211_ifdetach
> > -        * returns because we'll get called back to reclaim node
> > -        * state and potentially want to use them.
> > -        */
> > -}
> > -
> > -
> > -
> > -
> > 
> >  /********************\
> >  * Channel/mode setup *
> >  \********************/
> > 
> > @@ -1494,9 +840,6 @@ ath5k_desc_free(struct ath5k_softc *sc, struct
> > pci_dev *pdev)
> > 
> >  }
> > 
> > -
> > -
> > -
> > 
> >  /**************\
> >  * Queues setup *
> >  \**************/
> > 
> > @@ -1696,8 +1039,6 @@ ath5k_txq_release(struct ath5k_softc *sc)
> > 
> >  }
> > 
> > -
> > -
> > 
> >  /*************\
> >  * RX Handling *
> >  \*************/
> > 
> > @@ -2121,6 +1462,59 @@ unlock:
> >  * TX Handling *
> >  \*************/
> > 
> > +static int ath5k_tx_queue(struct ieee80211_hw *hw, struct sk_buff *skb,
> > +                         struct ath5k_txq *txq)
> > +{
> > +       struct ath5k_softc *sc = hw->priv;
> > +       struct ath5k_buf *bf;
> > +       unsigned long flags;
> > +       int padsize;
> > +
> > +       ath5k_debug_dump_skb(sc, skb, "TX  ", 1);
> > +
> > +       /*
> > +        * The hardware expects the header padded to 4 byte boundaries.
> > +        * If this is not the case, we add the padding after the header.
> > +        */
> > +       padsize = ath5k_add_padding(skb);
> > +       if (padsize < 0) {
> > +               ATH5K_ERR(sc, "tx hdrlen not %%4: not enough"
> > +                         " headroom to pad");
> > +               goto drop_packet;
> > +       }
> > +
> > +       spin_lock_irqsave(&sc->txbuflock, flags);
> > +       if (list_empty(&sc->txbuf)) {
> > +               ATH5K_ERR(sc, "no further txbuf available, dropping
> > packet\n"); +               spin_unlock_irqrestore(&sc->txbuflock,
> > flags);
> > +               ieee80211_stop_queue(hw, skb_get_queue_mapping(skb));
> > +               goto drop_packet;
> > +       }
> > +       bf = list_first_entry(&sc->txbuf, struct ath5k_buf, list);
> > +       list_del(&bf->list);
> > +       sc->txbuf_len--;
> > +       if (list_empty(&sc->txbuf))
> > +               ieee80211_stop_queues(hw);
> > +       spin_unlock_irqrestore(&sc->txbuflock, flags);
> > +
> > +       bf->skb = skb;
> > +
> > +       if (ath5k_txbuf_setup(sc, bf, txq, padsize)) {
> > +               bf->skb = NULL;
> > +               spin_lock_irqsave(&sc->txbuflock, flags);
> > +               list_add_tail(&bf->list, &sc->txbuf);
> > +               sc->txbuf_len++;
> > +               spin_unlock_irqrestore(&sc->txbuflock, flags);
> > +               goto drop_packet;
> > +       }
> > +       return NETDEV_TX_OK;
> > +
> > +drop_packet:
> > +       dev_kfree_skb_any(skb);
> > +       return NETDEV_TX_OK;
> > +}
> > +
> > +
> > 
> >  static void
> >  ath5k_tx_processq(struct ath5k_softc *sc, struct ath5k_txq *txq)
> >  {
> > 
> > @@ -2313,6 +1707,43 @@ err_unmap:
> >  }
> >  
> >  /*
> > 
> > + * Updates the beacon that is sent by ath5k_beacon_send.  For adhoc,
> > + * this is called only once at config_bss time, for AP we do it every
> > + * SWBA interrupt so that the TIM will reflect buffered frames.
> > + *
> > + * Called with the beacon lock.
> > + */
> > +static int
> > +ath5k_beacon_update(struct ieee80211_hw *hw, struct ieee80211_vif *vif)
> > +{
> > +       int ret;
> > +       struct ath5k_softc *sc = hw->priv;
> > +       struct sk_buff *skb;
> > +
> > +       if (WARN_ON(!vif)) {
> > +               ret = -EINVAL;
> > +               goto out;
> > +       }
> > +
> > +       skb = ieee80211_beacon_get(hw, vif);
> > +
> > +       if (!skb) {
> > +               ret = -ENOMEM;
> > +               goto out;
> > +       }
> > +
> > +       ath5k_debug_dump_skb(sc, skb, "BC  ", 1);
> > +
> > +       ath5k_txbuf_free_skb(sc, sc->bbuf);
> > +       sc->bbuf->skb = skb;
> > +       ret = ath5k_beacon_setup(sc, sc->bbuf);
> > +       if (ret)
> > +               sc->bbuf->skb = NULL;
> > +out:
> > +       return ret;
> > +}
> > +
> > +/*
> > 
> >  * Transmit a beacon frame at SWBA.  Dynamic updates to the
> >  * frame contents are done as needed and the slot time is
> >  * also adjusted based on current state.
> > 
> > @@ -2389,7 +1820,6 @@ ath5k_beacon_send(struct ath5k_softc *sc)
> > 
> >        sc->bsent++;
> >  
> >  }
> > 
> > -
> > 
> >  /**
> >  * ath5k_beacon_update_timers - update beacon timers
> >  *
> > 
> > @@ -2491,7 +1921,6 @@ ath5k_beacon_update_timers(struct ath5k_softc *sc,
> > u64 bc_tsf)
> > 
> >                intval & AR5K_BEACON_RESET_TSF ? "AR5K_BEACON_RESET_TSF" :
> >                "");
> >  
> >  }
> > 
> > -
> > 
> >  /**
> >  * ath5k_beacon_config - Configure the beacon queues and interrupts
> >  *
> > 
> > @@ -2570,156 +1999,6 @@ static void ath5k_tasklet_beacon(unsigned long
> > data)
> > 
> >  * Interrupt handling *
> >  \********************/
> > 
> > -static int
> > -ath5k_init(struct ath5k_softc *sc)
> > -{
> > -       struct ath5k_hw *ah = sc->ah;
> > -       struct ath_common *common = ath5k_hw_common(ah);
> > -       int ret, i;
> > -
> > -       mutex_lock(&sc->lock);
> > -
> > -       ATH5K_DBG(sc, ATH5K_DEBUG_RESET, "mode %d\n", sc->opmode);
> > -
> > -       /*
> > -        * Stop anything previously setup.  This is safe
> > -        * no matter this is the first time through or not.
> > -        */
> > -       ath5k_stop_locked(sc);
> > -
> > -       /*
> > -        * The basic interface to setting the hardware in a good
> > -        * state is ``reset''.  On return the hardware is known to
> > -        * be powered up and with interrupts disabled.  This must
> > -        * be followed by initialization of the appropriate bits
> > -        * and then setup of the interrupt mask.
> > -        */
> > -       sc->curchan = sc->hw->conf.channel;
> > -       sc->curband = &sc->sbands[sc->curchan->band];
> > -       sc->imask = AR5K_INT_RXOK | AR5K_INT_RXERR | AR5K_INT_RXEOL |
> > -               AR5K_INT_RXORN | AR5K_INT_TXDESC | AR5K_INT_TXEOL |
> > -               AR5K_INT_FATAL | AR5K_INT_GLOBAL | AR5K_INT_MIB;
> > -
> > -       ret = ath5k_reset(sc, NULL);
> > -       if (ret)
> > -               goto done;
> > -
> > -       ath5k_rfkill_hw_start(ah);
> > -
> > -       /*
> > -        * Reset the key cache since some parts do not reset the
> > -        * contents on initial power up or resume from suspend.
> > -        */
> > -       for (i = 0; i < common->keymax; i++)
> > -               ath_hw_keyreset(common, (u16)i);
> > -
> > -       ath5k_hw_set_ack_bitrate_high(ah, true);
> > -       ret = 0;
> > -done:
> > -       mmiowb();
> > -       mutex_unlock(&sc->lock);
> > -       return ret;
> > -}
> > -
> > -static int
> > -ath5k_stop_locked(struct ath5k_softc *sc)
> > -{
> > -       struct ath5k_hw *ah = sc->ah;
> > -
> > -       ATH5K_DBG(sc, ATH5K_DEBUG_RESET, "invalid %u\n",
> > -                       test_bit(ATH_STAT_INVALID, sc->status));
> > -
> > -       /*
> > -        * Shutdown the hardware and driver:
> > -        *    stop output from above
> > -        *    disable interrupts
> > -        *    turn off timers
> > -        *    turn off the radio
> > -        *    clear transmit machinery
> > -        *    clear receive machinery
> > -        *    drain and release tx queues
> > -        *    reclaim beacon resources
> > -        *    power down hardware
> > -        *
> > -        * Note that some of this work is not possible if the
> > -        * hardware is gone (invalid).
> > -        */
> > -       ieee80211_stop_queues(sc->hw);
> > -
> > -       if (!test_bit(ATH_STAT_INVALID, sc->status)) {
> > -               ath5k_led_off(sc);
> > -               ath5k_hw_set_imr(ah, 0);
> > -               synchronize_irq(sc->pdev->irq);
> > -       }
> > -       ath5k_txq_cleanup(sc);
> > -       if (!test_bit(ATH_STAT_INVALID, sc->status)) {
> > -               ath5k_rx_stop(sc);
> > -               ath5k_hw_phy_disable(ah);
> > -       }
> > -
> > -       return 0;
> > -}
> > -
> > -static void stop_tasklets(struct ath5k_softc *sc)
> > -{
> > -       tasklet_kill(&sc->rxtq);
> > -       tasklet_kill(&sc->txtq);
> > -       tasklet_kill(&sc->calib);
> > -       tasklet_kill(&sc->beacontq);
> > -       tasklet_kill(&sc->ani_tasklet);
> > -}
> > -
> > -/*
> > - * Stop the device, grabbing the top-level lock to protect
> > - * against concurrent entry through ath5k_init (which can happen
> > - * if another thread does a system call and the thread doing the
> > - * stop is preempted).
> > - */
> > -static int
> > -ath5k_stop_hw(struct ath5k_softc *sc)
> > -{
> > -       int ret;
> > -
> > -       mutex_lock(&sc->lock);
> > -       ret = ath5k_stop_locked(sc);
> > -       if (ret == 0 && !test_bit(ATH_STAT_INVALID, sc->status)) {
> > -               /*
> > -                * Don't set the card in full sleep mode!
> > -                *
> > -                * a) When the device is in this state it must be
> > carefully -                * woken up or references to registers in the
> > PCI clock -                * domain may freeze the bus (and system). 
> > This varies -                * by chip and is mostly an issue with newer
> > parts -                * (madwifi sources mentioned srev >= 0x78) that
> > go to -                * sleep more quickly.
> > -                *
> > -                * b) On older chips full sleep results a weird behaviour
> > -                * during wakeup. I tested various cards with srev < 0x78
> > -                * and they don't wake up after module reload, a second
> > -                * module reload is needed to bring the card up again.
> > -                *
> > -                * Until we figure out what's going on don't enable
> > -                * full chip reset on any chip (this is what Legacy HAL
> > -                * and Sam's HAL do anyway). Instead Perform a full reset
> > -                * on the device (same as initial state after attach) and
> > -                * leave it idle (keep MAC/BB on warm reset) */
> > -               ret = ath5k_hw_on_hold(sc->ah);
> > -
> > -               ATH5K_DBG(sc, ATH5K_DEBUG_RESET,
> > -                               "putting device to sleep\n");
> > -       }
> > -       ath5k_txbuf_free_skb(sc, sc->bbuf);
> > -
> > -       mmiowb();
> > -       mutex_unlock(&sc->lock);
> > -
> > -       stop_tasklets(sc);
> > -
> > -       ath5k_rfkill_hw_stop(sc->ah);
> > -
> > -       return ret;
> > -}
> > -
> > 
> >  static void
> >  ath5k_intr_calibration_poll(struct ath5k_hw *ah)
> >  {
> > 
> > @@ -2882,68 +2161,158 @@ ath5k_tasklet_ani(unsigned long data)
> > 
> >  }
> > 
> > -/********************\
> > -* Mac80211 functions *
> > -\********************/
> > +/*************************\
> > +* Initialization routines *
> > +\*************************/
> > 
> >  static int
> > 
> > -ath5k_tx(struct ieee80211_hw *hw, struct sk_buff *skb)
> > +ath5k_stop_locked(struct ath5k_softc *sc)
> > 
> >  {
> > 
> > -       struct ath5k_softc *sc = hw->priv;
> > +       struct ath5k_hw *ah = sc->ah;
> > 
> > -       return ath5k_tx_queue(hw, skb, sc->txq);
> > +       ATH5K_DBG(sc, ATH5K_DEBUG_RESET, "invalid %u\n",
> > +                       test_bit(ATH_STAT_INVALID, sc->status));
> > +
> > +       /*
> > +        * Shutdown the hardware and driver:
> > +        *    stop output from above
> > +        *    disable interrupts
> > +        *    turn off timers
> > +        *    turn off the radio
> > +        *    clear transmit machinery
> > +        *    clear receive machinery
> > +        *    drain and release tx queues
> > +        *    reclaim beacon resources
> > +        *    power down hardware
> > +        *
> > +        * Note that some of this work is not possible if the
> > +        * hardware is gone (invalid).
> > +        */
> > +       ieee80211_stop_queues(sc->hw);
> > +
> > +       if (!test_bit(ATH_STAT_INVALID, sc->status)) {
> > +               ath5k_led_off(sc);
> > +               ath5k_hw_set_imr(ah, 0);
> > +               synchronize_irq(sc->pdev->irq);
> > +       }
> > +       ath5k_txq_cleanup(sc);
> > +       if (!test_bit(ATH_STAT_INVALID, sc->status)) {
> > +               ath5k_rx_stop(sc);
> > +               ath5k_hw_phy_disable(ah);
> > +       }
> > +
> > +       return 0;
> > 
> >  }
> > 
> > -static int ath5k_tx_queue(struct ieee80211_hw *hw, struct sk_buff *skb,
> > -                         struct ath5k_txq *txq)
> > +static int
> > +ath5k_init(struct ath5k_softc *sc)
> > 
> >  {
> > 
> > -       struct ath5k_softc *sc = hw->priv;
> > -       struct ath5k_buf *bf;
> > -       unsigned long flags;
> > -       int padsize;
> > +       struct ath5k_hw *ah = sc->ah;
> > +       struct ath_common *common = ath5k_hw_common(ah);
> > +       int ret, i;
> > 
> > -       ath5k_debug_dump_skb(sc, skb, "TX  ", 1);
> > +       mutex_lock(&sc->lock);
> > +
> > +       ATH5K_DBG(sc, ATH5K_DEBUG_RESET, "mode %d\n", sc->opmode);
> > 
> >        /*
> > 
> > -        * The hardware expects the header padded to 4 byte boundaries.
> > -        * If this is not the case, we add the padding after the header.
> > +        * Stop anything previously setup.  This is safe
> > +        * no matter this is the first time through or not.
> > 
> >         */
> > 
> > -       padsize = ath5k_add_padding(skb);
> > -       if (padsize < 0) {
> > -               ATH5K_ERR(sc, "tx hdrlen not %%4: not enough"
> > -                         " headroom to pad");
> > -               goto drop_packet;
> > -       }
> > +       ath5k_stop_locked(sc);
> > 
> > -       spin_lock_irqsave(&sc->txbuflock, flags);
> > -       if (list_empty(&sc->txbuf)) {
> > -               ATH5K_ERR(sc, "no further txbuf available, dropping
> > packet\n"); -               spin_unlock_irqrestore(&sc->txbuflock,
> > flags);
> > -               ieee80211_stop_queue(hw, skb_get_queue_mapping(skb));
> > -               goto drop_packet;
> > -       }
> > -       bf = list_first_entry(&sc->txbuf, struct ath5k_buf, list);
> > -       list_del(&bf->list);
> > -       sc->txbuf_len--;
> > -       if (list_empty(&sc->txbuf))
> > -               ieee80211_stop_queues(hw);
> > -       spin_unlock_irqrestore(&sc->txbuflock, flags);
> > +       /*
> > +        * The basic interface to setting the hardware in a good
> > +        * state is ``reset''.  On return the hardware is known to
> > +        * be powered up and with interrupts disabled.  This must
> > +        * be followed by initialization of the appropriate bits
> > +        * and then setup of the interrupt mask.
> > +        */
> > +       sc->curchan = sc->hw->conf.channel;
> > +       sc->curband = &sc->sbands[sc->curchan->band];
> > +       sc->imask = AR5K_INT_RXOK | AR5K_INT_RXERR | AR5K_INT_RXEOL |
> > +               AR5K_INT_RXORN | AR5K_INT_TXDESC | AR5K_INT_TXEOL |
> > +               AR5K_INT_FATAL | AR5K_INT_GLOBAL | AR5K_INT_MIB;
> > 
> > -       bf->skb = skb;
> > +       ret = ath5k_reset(sc, NULL);
> > +       if (ret)
> > +               goto done;
> > 
> > -       if (ath5k_txbuf_setup(sc, bf, txq, padsize)) {
> > -               bf->skb = NULL;
> > -               spin_lock_irqsave(&sc->txbuflock, flags);
> > -               list_add_tail(&bf->list, &sc->txbuf);
> > -               sc->txbuf_len++;
> > -               spin_unlock_irqrestore(&sc->txbuflock, flags);
> > -               goto drop_packet;
> > +       ath5k_rfkill_hw_start(ah);
> > +
> > +       /*
> > +        * Reset the key cache since some parts do not reset the
> > +        * contents on initial power up or resume from suspend.
> > +        */
> > +       for (i = 0; i < common->keymax; i++)
> > +               ath_hw_keyreset(common, (u16) i);
> > +
> > +       ath5k_hw_set_ack_bitrate_high(ah, true);
> > +       ret = 0;
> > +done:
> > +       mmiowb();
> > +       mutex_unlock(&sc->lock);
> > +       return ret;
> > +}
> > +
> > +static void stop_tasklets(struct ath5k_softc *sc)
> > +{
> > +       tasklet_kill(&sc->rxtq);
> > +       tasklet_kill(&sc->txtq);
> > +       tasklet_kill(&sc->calib);
> > +       tasklet_kill(&sc->beacontq);
> > +       tasklet_kill(&sc->ani_tasklet);
> > +}
> > +
> > +/*
> > + * Stop the device, grabbing the top-level lock to protect
> > + * against concurrent entry through ath5k_init (which can happen
> > + * if another thread does a system call and the thread doing the
> > + * stop is preempted).
> > + */
> > +static int
> > +ath5k_stop_hw(struct ath5k_softc *sc)
> > +{
> > +       int ret;
> > +
> > +       mutex_lock(&sc->lock);
> > +       ret = ath5k_stop_locked(sc);
> > +       if (ret == 0 && !test_bit(ATH_STAT_INVALID, sc->status)) {
> > +               /*
> > +                * Don't set the card in full sleep mode!
> > +                *
> > +                * a) When the device is in this state it must be
> > carefully +                * woken up or references to registers in the
> > PCI clock +                * domain may freeze the bus (and system). 
> > This varies +                * by chip and is mostly an issue with newer
> > parts +                * (madwifi sources mentioned srev >= 0x78) that
> > go to +                * sleep more quickly.
> > +                *
> > +                * b) On older chips full sleep results a weird behaviour
> > +                * during wakeup. I tested various cards with srev < 0x78
> > +                * and they don't wake up after module reload, a second
> > +                * module reload is needed to bring the card up again.
> > +                *
> > +                * Until we figure out what's going on don't enable
> > +                * full chip reset on any chip (this is what Legacy HAL
> > +                * and Sam's HAL do anyway). Instead Perform a full reset
> > +                * on the device (same as initial state after attach) and
> > +                * leave it idle (keep MAC/BB on warm reset) */
> > +               ret = ath5k_hw_on_hold(sc->ah);
> > +
> > +               ATH5K_DBG(sc, ATH5K_DEBUG_RESET,
> > +                               "putting device to sleep\n");
> > 
> >        }
> > 
> > -       return NETDEV_TX_OK;
> > +       ath5k_txbuf_free_skb(sc, sc->bbuf);
> > 
> > -drop_packet:
> > -       dev_kfree_skb_any(skb);
> > -       return NETDEV_TX_OK;
> > +       mmiowb();
> > +       mutex_unlock(&sc->lock);
> > +
> > +       stop_tasklets(sc);
> > +
> > +       ath5k_rfkill_hw_stop(sc->ah);
> > +
> > +       return ret;
> > 
> >  }
> >  
> >  /*
> > 
> > @@ -3020,6 +2389,179 @@ static void ath5k_reset_work(struct work_struct
> > *work)
> > 
> >        mutex_unlock(&sc->lock);
> >  
> >  }
> > 
> > +static int
> > +ath5k_attach(struct pci_dev *pdev, struct ieee80211_hw *hw)
> > +{
> > +       struct ath5k_softc *sc = hw->priv;
> > +       struct ath5k_hw *ah = sc->ah;
> > +       struct ath_regulatory *regulatory = ath5k_hw_regulatory(ah);
> > +       u8 mac[ETH_ALEN] = {};
> > +       int ret;
> > +
> > +       ATH5K_DBG(sc, ATH5K_DEBUG_ANY, "devid 0x%x\n", pdev->device);
> > +
> > +       /*
> > +        * Check if the MAC has multi-rate retry support.
> > +        * We do this by trying to setup a fake extended
> > +        * descriptor.  MACs that don't have support will
> > +        * return false w/o doing anything.  MACs that do
> > +        * support it will return true w/o doing anything.
> > +        */
> > +       ret = ath5k_hw_setup_mrr_tx_desc(ah, NULL, 0, 0, 0, 0, 0, 0);
> > +
> > +       if (ret < 0)
> > +               goto err;
> > +       if (ret > 0)
> > +               __set_bit(ATH_STAT_MRRETRY, sc->status);
> > +
> > +       /*
> > +        * Collect the channel list.  The 802.11 layer
> > +        * is resposible for filtering this list based
> > +        * on settings like the phy mode and regulatory
> > +        * domain restrictions.
> > +        */
> > +       ret = ath5k_setup_bands(hw);
> > +       if (ret) {
> > +               ATH5K_ERR(sc, "can't get channels\n");
> > +               goto err;
> > +       }
> > +
> > +       /* NB: setup here so ath5k_rate_update is happy */
> > +       if (test_bit(AR5K_MODE_11A, ah->ah_modes))
> > +               ath5k_setcurmode(sc, AR5K_MODE_11A);
> > +       else
> > +               ath5k_setcurmode(sc, AR5K_MODE_11B);
> > +
> > +       /*
> > +        * Allocate tx+rx descriptors and populate the lists.
> > +        */
> > +       ret = ath5k_desc_alloc(sc, pdev);
> > +       if (ret) {
> > +               ATH5K_ERR(sc, "can't allocate descriptors\n");
> > +               goto err;
> > +       }
> > +
> > +       /*
> > +        * Allocate hardware transmit queues: one queue for
> > +        * beacon frames and one data queue for each QoS
> > +        * priority.  Note that hw functions handle resetting
> > +        * these queues at the needed time.
> > +        */
> > +       ret = ath5k_beaconq_setup(ah);
> > +       if (ret < 0) {
> > +               ATH5K_ERR(sc, "can't setup a beacon xmit queue\n");
> > +               goto err_desc;
> > +       }
> > +       sc->bhalq = ret;
> > +       sc->cabq = ath5k_txq_setup(sc, AR5K_TX_QUEUE_CAB, 0);
> > +       if (IS_ERR(sc->cabq)) {
> > +               ATH5K_ERR(sc, "can't setup cab queue\n");
> > +               ret = PTR_ERR(sc->cabq);
> > +               goto err_bhal;
> > +       }
> > +
> > +       sc->txq = ath5k_txq_setup(sc, AR5K_TX_QUEUE_DATA,
> > AR5K_WME_AC_BK); +       if (IS_ERR(sc->txq)) {
> > +               ATH5K_ERR(sc, "can't setup xmit queue\n");
> > +               ret = PTR_ERR(sc->txq);
> > +               goto err_queues;
> > +       }
> > +
> > +       tasklet_init(&sc->rxtq, ath5k_tasklet_rx, (unsigned long)sc);
> > +       tasklet_init(&sc->txtq, ath5k_tasklet_tx, (unsigned long)sc);
> > +       tasklet_init(&sc->calib, ath5k_tasklet_calibrate, (unsigned
> > long)sc); +       tasklet_init(&sc->beacontq, ath5k_tasklet_beacon,
> > (unsigned long)sc); +       tasklet_init(&sc->ani_tasklet,
> > ath5k_tasklet_ani, (unsigned long)sc); +
> > +       INIT_WORK(&sc->reset_work, ath5k_reset_work);
> > +
> > +       ret = ath5k_eeprom_read_mac(ah, mac);
> > +       if (ret) {
> > +               ATH5K_ERR(sc, "unable to read address from EEPROM:
> > 0x%04x\n", +                       sc->pdev->device);
> > +               goto err_queues;
> > +       }
> > +
> > +       SET_IEEE80211_PERM_ADDR(hw, mac);
> > +       /* All MAC address bits matter for ACKs */
> > +       memcpy(sc->bssidmask, ath_bcast_mac, ETH_ALEN);
> > +       ath5k_hw_set_bssid_mask(sc->ah, sc->bssidmask);
> > +
> > +       regulatory->current_rd =
> > ah->ah_capabilities.cap_eeprom.ee_regdomain; +       ret =
> > ath_regd_init(regulatory, hw->wiphy, ath5k_reg_notifier); +       if
> > (ret) {
> > +               ATH5K_ERR(sc, "can't initialize regulatory system\n");
> > +               goto err_queues;
> > +       }
> > +
> > +       ret = ieee80211_register_hw(hw);
> > +       if (ret) {
> > +               ATH5K_ERR(sc, "can't register ieee80211 hw\n");
> > +               goto err_queues;
> > +       }
> > +
> > +       if (!ath_is_world_regd(regulatory))
> > +               regulatory_hint(hw->wiphy, regulatory->alpha2);
> > +
> > +       ath5k_init_leds(sc);
> > +
> > +       ath5k_sysfs_register(sc);
> > +
> > +       return 0;
> > +err_queues:
> > +       ath5k_txq_release(sc);
> > +err_bhal:
> > +       ath5k_hw_release_tx_queue(ah, sc->bhalq);
> > +err_desc:
> > +       ath5k_desc_free(sc, pdev);
> > +err:
> > +       return ret;
> > +}
> > +
> > +static void
> > +ath5k_detach(struct pci_dev *pdev, struct ieee80211_hw *hw)
> > +{
> > +       struct ath5k_softc *sc = hw->priv;
> > +
> > +       /*
> > +        * NB: the order of these is important:
> > +        * o call the 802.11 layer before detaching ath5k_hw to
> > +        *   ensure callbacks into the driver to delete global
> > +        *   key cache entries can be handled
> > +        * o reclaim the tx queue data structures after calling
> > +        *   the 802.11 layer as we'll get called back to reclaim
> > +        *   node state and potentially want to use them
> > +        * o to cleanup the tx queues the hal is called, so detach
> > +        *   it last
> > +        * XXX: ??? detach ath5k_hw ???
> > +        * Other than that, it's straightforward...
> > +        */
> > +       ieee80211_unregister_hw(hw);
> > +       ath5k_desc_free(sc, pdev);
> > +       ath5k_txq_release(sc);
> > +       ath5k_hw_release_tx_queue(sc->ah, sc->bhalq);
> > +       ath5k_unregister_leds(sc);
> > +
> > +       ath5k_sysfs_unregister(sc);
> > +       /*
> > +        * NB: can't reclaim these until after ieee80211_ifdetach
> > +        * returns because we'll get called back to reclaim node
> > +        * state and potentially want to use them.
> > +        */
> > +}
> > +
> > +/********************\
> > +* Mac80211 functions *
> > +\********************/
> > +
> > +static int
> > +ath5k_tx(struct ieee80211_hw *hw, struct sk_buff *skb)
> > +{
> > +       struct ath5k_softc *sc = hw->priv;
> > +
> > +       return ath5k_tx_queue(hw, skb, sc->txq);
> > +}
> > +
> > 
> >  static int ath5k_start(struct ieee80211_hw *hw)
> >  {
> >  
> >        return ath5k_init(hw->priv);
> > 
> > @@ -3398,43 +2940,6 @@ ath5k_reset_tsf(struct ieee80211_hw *hw)
> > 
> >                ath5k_hw_reset_tsf(sc->ah);
> >  
> >  }
> > 
> > -/*
> > - * Updates the beacon that is sent by ath5k_beacon_send.  For adhoc,
> > - * this is called only once at config_bss time, for AP we do it every
> > - * SWBA interrupt so that the TIM will reflect buffered frames.
> > - *
> > - * Called with the beacon lock.
> > - */
> > -static int
> > -ath5k_beacon_update(struct ieee80211_hw *hw, struct ieee80211_vif *vif)
> > -{
> > -       int ret;
> > -       struct ath5k_softc *sc = hw->priv;
> > -       struct sk_buff *skb;
> > -
> > -       if (WARN_ON(!vif)) {
> > -               ret = -EINVAL;
> > -               goto out;
> > -       }
> > -
> > -       skb = ieee80211_beacon_get(hw, vif);
> > -
> > -       if (!skb) {
> > -               ret = -ENOMEM;
> > -               goto out;
> > -       }
> > -
> > -       ath5k_debug_dump_skb(sc, skb, "BC  ", 1);
> > -
> > -       ath5k_txbuf_free_skb(sc, sc->bbuf);
> > -       sc->bbuf->skb = skb;
> > -       ret = ath5k_beacon_setup(sc, sc->bbuf);
> > -       if (ret)
> > -               sc->bbuf->skb = NULL;
> > -out:
> > -       return ret;
> > -}
> > -
> > 
> >  static void
> >  set_beacon_filter(struct ieee80211_hw *hw, bool enable)
> >  {
> > 
> > @@ -3540,3 +3045,364 @@ static void ath5k_set_coverage_class(struct
> > ieee80211_hw *hw, u8 coverage_class)
> > 
> >        ath5k_hw_set_coverage_class(sc->ah, coverage_class);
> >        mutex_unlock(&sc->lock);
> >  
> >  }
> > 
> > +
> > +static const struct ieee80211_ops ath5k_hw_ops = {
> > +       .tx             = ath5k_tx,
> > +       .start          = ath5k_start,
> > +       .stop           = ath5k_stop,
> > +       .add_interface  = ath5k_add_interface,
> > +       .remove_interface = ath5k_remove_interface,
> > +       .config         = ath5k_config,
> > +       .prepare_multicast = ath5k_prepare_multicast,
> > +       .configure_filter = ath5k_configure_filter,
> > +       .set_key        = ath5k_set_key,
> > +       .get_stats      = ath5k_get_stats,
> > +       .get_survey     = ath5k_get_survey,
> > +       .conf_tx        = NULL,
> > +       .get_tsf        = ath5k_get_tsf,
> > +       .set_tsf        = ath5k_set_tsf,
> > +       .reset_tsf      = ath5k_reset_tsf,
> > +       .bss_info_changed = ath5k_bss_info_changed,
> > +       .sw_scan_start  = ath5k_sw_scan_start,
> > +       .sw_scan_complete = ath5k_sw_scan_complete,
> > +       .set_coverage_class = ath5k_set_coverage_class,
> > +};
> > +
> > +/********************\
> > +* PCI Initialization *
> > +\********************/
> > +
> > +static int __devinit
> > +ath5k_pci_probe(struct pci_dev *pdev,
> > +               const struct pci_device_id *id)
> > +{
> > +       void __iomem *mem;
> > +       struct ath5k_softc *sc;
> > +       struct ath_common *common;
> > +       struct ieee80211_hw *hw;
> > +       int ret;
> > +       u8 csz;
> > +
> > +       /*
> > +        * L0s needs to be disabled on all ath5k cards.
> > +        *
> > +        * For distributions shipping with CONFIG_PCIEASPM (this will be
> > enabled +        * by default in the future in 2.6.36) this will also
> > mean both L1 and +        * L0s will be disabled when a pre 1.1 PCIe
> > device is detected. We do +        * know L1 works correctly even for
> > all ath5k pre 1.1 PCIe devices +        * though but cannot currently
> > undue the effect of a blacklist, for +        * details you can read
> > pcie_aspm_sanity_check() and see how it adjusts +        * the device
> > link capability.
> > +        *
> > +        * It may be possible in the future to implement some PCI API to
> > allow +        * drivers to override blacklists for pre 1.1 PCIe but for
> > now it is +        * best to accept that both L0s and L1 will be
> > disabled completely for +        * distributions shipping with
> > CONFIG_PCIEASPM rather than having this +        * issue present.
> > Motivation for adding this new API will be to help +        * with power
> > consumption for some of these devices.
> > +        */
> > +       pci_disable_link_state(pdev, PCIE_LINK_STATE_L0S);
> > +
> > +       ret = pci_enable_device(pdev);
> > +       if (ret) {
> > +               dev_err(&pdev->dev, "can't enable device\n");
> > +               goto err;
> > +       }
> > +
> > +       /* XXX 32-bit addressing only */
> > +       ret = pci_set_dma_mask(pdev, DMA_BIT_MASK(32));
> > +       if (ret) {
> > +               dev_err(&pdev->dev, "32-bit DMA not available\n");
> > +               goto err_dis;
> > +       }
> > +
> > +       /*
> > +        * Cache line size is used to size and align various
> > +        * structures used to communicate with the hardware.
> > +        */
> > +       pci_read_config_byte(pdev, PCI_CACHE_LINE_SIZE, &csz);
> > +       if (csz == 0) {
> > +               /*
> > +                * Linux 2.4.18 (at least) writes the cache line size
> > +                * register as a 16-bit wide register which is wrong.
> > +                * We must have this setup properly for rx buffer
> > +                * DMA to work so force a reasonable value here if it
> > +                * comes up zero.
> > +                */
> > +               csz = L1_CACHE_BYTES >> 2;
> > +               pci_write_config_byte(pdev, PCI_CACHE_LINE_SIZE, csz);
> > +       }
> > +       /*
> > +        * The default setting of latency timer yields poor results,
> > +        * set it to the value used by other systems.  It may be worth
> > +        * tweaking this setting more.
> > +        */
> > +       pci_write_config_byte(pdev, PCI_LATENCY_TIMER, 0xa8);
> > +
> > +       /* Enable bus mastering */
> > +       pci_set_master(pdev);
> > +
> > +       /*
> > +        * Disable the RETRY_TIMEOUT register (0x41) to keep
> > +        * PCI Tx retries from interfering with C3 CPU state.
> > +        */
> > +       pci_write_config_byte(pdev, 0x41, 0);
> > +
> > +       ret = pci_request_region(pdev, 0, "ath5k");
> > +       if (ret) {
> > +               dev_err(&pdev->dev, "cannot reserve PCI memory
> > region\n"); +               goto err_dis;
> > +       }
> > +
> > +       mem = pci_iomap(pdev, 0, 0);
> > +       if (!mem) {
> > +               dev_err(&pdev->dev, "cannot remap PCI memory region\n") ;
> > +               ret = -EIO;
> > +               goto err_reg;
> > +       }
> > +
> > +       /*
> > +        * Allocate hw (mac80211 main struct)
> > +        * and hw->priv (driver private data)
> > +        */
> > +       hw = ieee80211_alloc_hw(sizeof(*sc), &ath5k_hw_ops);
> > +       if (hw == NULL) {
> > +               dev_err(&pdev->dev, "cannot allocate ieee80211_hw\n");
> > +               ret = -ENOMEM;
> > +               goto err_map;
> > +       }
> > +
> > +       dev_info(&pdev->dev, "registered as '%s'\n",
> > wiphy_name(hw->wiphy)); +
> > +       /* Initialize driver private data */
> > +       SET_IEEE80211_DEV(hw, &pdev->dev);
> > +       hw->flags = IEEE80211_HW_RX_INCLUDES_FCS |
> > +                   IEEE80211_HW_HOST_BROADCAST_PS_BUFFERING |
> > +                   IEEE80211_HW_SIGNAL_DBM;
> > +
> > +       hw->wiphy->interface_modes =
> > +               BIT(NL80211_IFTYPE_AP) |
> > +               BIT(NL80211_IFTYPE_STATION) |
> > +               BIT(NL80211_IFTYPE_ADHOC) |
> > +               BIT(NL80211_IFTYPE_MESH_POINT);
> > +
> > +       hw->extra_tx_headroom = 2;
> > +       hw->channel_change_time = 5000;
> > +       sc = hw->priv;
> > +       sc->hw = hw;
> > +       sc->pdev = pdev;
> > +
> > +       ath5k_debug_init_device(sc);
> > +
> > +       /*
> > +        * Mark the device as detached to avoid processing
> > +        * interrupts until setup is complete.
> > +        */
> > +       __set_bit(ATH_STAT_INVALID, sc->status);
> > +
> > +       sc->iobase = mem; /* So we can unmap it on detach */
> > +       sc->opmode = NL80211_IFTYPE_STATION;
> > +       sc->bintval = 1000;
> > +       mutex_init(&sc->lock);
> > +       spin_lock_init(&sc->rxbuflock);
> > +       spin_lock_init(&sc->txbuflock);
> > +       spin_lock_init(&sc->block);
> > +
> > +       /* Set private data */
> > +       pci_set_drvdata(pdev, sc);
> > +
> > +       /* Setup interrupt handler */
> > +       ret = request_irq(pdev->irq, ath5k_intr, IRQF_SHARED, "ath", sc);
> > +       if (ret) {
> > +               ATH5K_ERR(sc, "request_irq failed\n");
> > +               goto err_free;
> > +       }
> > +
> > +       /* If we passed the test, malloc an ath5k_hw struct */
> > +       sc->ah = kzalloc(sizeof(struct ath5k_hw), GFP_KERNEL);
> > +       if (!sc->ah) {
> > +               ret = -ENOMEM;
> > +               ATH5K_ERR(sc, "out of memory\n");
> > +               goto err_irq;
> > +       }
> > +
> > +       sc->ah->ah_sc = sc;
> > +       sc->ah->ah_iobase = sc->iobase;
> > +       common = ath5k_hw_common(sc->ah);
> > +       common->ops = &ath5k_common_ops;
> > +       common->ah = sc->ah;
> > +       common->hw = hw;
> > +       common->cachelsz = csz << 2; /* convert to bytes */
> > +
> > +       /* Initialize device */
> > +       ret = ath5k_hw_attach(sc);
> > +       if (ret) {
> > +               goto err_free_ah;
> > +       }
> > +
> > +       /* set up multi-rate retry capabilities */
> > +       if (sc->ah->ah_version == AR5K_AR5212) {
> > +               hw->max_rates = 4;
> > +               hw->max_rate_tries = 11;
> > +       }
> > +
> > +       /* Finish private driver data initialization */
> > +       ret = ath5k_attach(pdev, hw);
> > +       if (ret)
> > +               goto err_ah;
> > +
> > +       ATH5K_INFO(sc, "Atheros AR%s chip found (MAC: 0x%x, PHY:
> > 0x%x)\n", +                       ath5k_chip_name(AR5K_VERSION_MAC,
> > sc->ah->ah_mac_srev), +                                      
> > sc->ah->ah_mac_srev,
> > +                                       sc->ah->ah_phy_revision);
> > +
> > +       if (!sc->ah->ah_single_chip) {
> > +               /* Single chip radio (!RF5111) */
> > +               if (sc->ah->ah_radio_5ghz_revision &&
> > +                       !sc->ah->ah_radio_2ghz_revision) {
> > +                       /* No 5GHz support -> report 2GHz radio */
> > +                       if (!test_bit(AR5K_MODE_11A,
> > +                               sc->ah->ah_capabilities.cap_mode)) {
> > +                               ATH5K_INFO(sc, "RF%s 2GHz radio found
> > (0x%x)\n", +                                      
> > ath5k_chip_name(AR5K_VERSION_RAD, +                                     
> >          sc->ah->ah_radio_5ghz_revision), +                             
> >                  sc->ah->ah_radio_5ghz_revision); +                     
> >  /* No 2GHz support (5110 and some
> > +                        * 5Ghz only cards) -> report 5Ghz radio */
> > +                       } else if (!test_bit(AR5K_MODE_11B,
> > +                               sc->ah->ah_capabilities.cap_mode)) {
> > +                               ATH5K_INFO(sc, "RF%s 5GHz radio found
> > (0x%x)\n", +                                      
> > ath5k_chip_name(AR5K_VERSION_RAD, +                                     
> >          sc->ah->ah_radio_5ghz_revision), +                             
> >                  sc->ah->ah_radio_5ghz_revision); +                     
> >  /* Multiband radio */
> > +                       } else {
> > +                               ATH5K_INFO(sc, "RF%s multiband radio
> > found" +                                       " (0x%x)\n",
> > +                                       ath5k_chip_name(AR5K_VERSION_RAD,
> > +                                              
> > sc->ah->ah_radio_5ghz_revision), +                                      
> >         sc->ah->ah_radio_5ghz_revision); +                       }
> > +               }
> > +               /* Multi chip radio (RF5111 - RF2111) ->
> > +                * report both 2GHz/5GHz radios */
> > +               else if (sc->ah->ah_radio_5ghz_revision &&
> > +                               sc->ah->ah_radio_2ghz_revision){
> > +                       ATH5K_INFO(sc, "RF%s 5GHz radio found (0x%x)\n",
> > +                               ath5k_chip_name(AR5K_VERSION_RAD,
> > +                                       sc->ah->ah_radio_5ghz_revision),
> > +                                       sc->ah->ah_radio_5ghz_revision);
> > +                       ATH5K_INFO(sc, "RF%s 2GHz radio found (0x%x)\n",
> > +                               ath5k_chip_name(AR5K_VERSION_RAD,
> > +                                       sc->ah->ah_radio_2ghz_revision),
> > +                                       sc->ah->ah_radio_2ghz_revision);
> > +               }
> > +       }
> > +
> > +
> > +       /* ready to process interrupts */
> > +       __clear_bit(ATH_STAT_INVALID, sc->status);
> > +
> > +       return 0;
> > +err_ah:
> > +       ath5k_hw_detach(sc->ah);
> > +err_free_ah:
> > +       kfree(sc->ah);
> > +err_irq:
> > +       free_irq(pdev->irq, sc);
> > +err_free:
> > +       ieee80211_free_hw(hw);
> > +err_map:
> > +       pci_iounmap(pdev, mem);
> > +err_reg:
> > +       pci_release_region(pdev, 0);
> > +err_dis:
> > +       pci_disable_device(pdev);
> > +err:
> > +       return ret;
> > +}
> > +
> > +static void __devexit
> > +ath5k_pci_remove(struct pci_dev *pdev)
> > +{
> > +       struct ath5k_softc *sc = pci_get_drvdata(pdev);
> > +
> > +       ath5k_debug_finish_device(sc);
> > +       ath5k_detach(pdev, sc->hw);
> > +       ath5k_hw_detach(sc->ah);
> > +       kfree(sc->ah);
> > +       free_irq(pdev->irq, sc);
> > +       pci_iounmap(pdev, sc->iobase);
> > +       pci_release_region(pdev, 0);
> > +       pci_disable_device(pdev);
> > +       ieee80211_free_hw(sc->hw);
> > +}
> > +
> > +#ifdef CONFIG_PM_SLEEP
> > +static int ath5k_pci_suspend(struct device *dev)
> > +{
> > +       struct ath5k_softc *sc = pci_get_drvdata(to_pci_dev(dev));
> > +
> > +       ath5k_led_off(sc);
> > +       return 0;
> > +}
> > +
> > +static int ath5k_pci_resume(struct device *dev)
> > +{
> > +       struct pci_dev *pdev = to_pci_dev(dev);
> > +       struct ath5k_softc *sc = pci_get_drvdata(pdev);
> > +
> > +       /*
> > +        * Suspend/Resume resets the PCI configuration space, so we have
> > to +        * re-disable the RETRY_TIMEOUT register (0x41) to keep
> > +        * PCI Tx retries from interfering with C3 CPU state
> > +        */
> > +       pci_write_config_byte(pdev, 0x41, 0);
> > +
> > +       ath5k_led_enable(sc);
> > +       return 0;
> > +}
> > +
> > +static SIMPLE_DEV_PM_OPS(ath5k_pm_ops, ath5k_pci_suspend,
> > ath5k_pci_resume); +#define ATH5K_PM_OPS   (&ath5k_pm_ops)
> > +#else
> > +#define ATH5K_PM_OPS   NULL
> > +#endif /* CONFIG_PM_SLEEP */
> > +
> > +static struct pci_driver ath5k_pci_driver = {
> > +       .name           = KBUILD_MODNAME,
> > +       .id_table       = ath5k_pci_id_table,
> > +       .probe          = ath5k_pci_probe,
> > +       .remove         = __devexit_p(ath5k_pci_remove),
> > +       .driver.pm      = ATH5K_PM_OPS,
> > +};
> > +
> > +/*
> > + * Module init/exit functions
> > + */
> > +static int __init
> > +init_ath5k_pci(void)
> > +{
> > +       int ret;
> > +
> > +       ath5k_debug_init();
> > +
> > +       ret = pci_register_driver(&ath5k_pci_driver);
> > +       if (ret) {
> > +               printk(KERN_ERR "ath5k_pci: can't register pci
> > driver\n"); +               return ret;
> > +       }
> > +
> > +       return 0;
> > +}
> > +
> > +static void __exit
> > +exit_ath5k_pci(void)
> > +{
> > +       pci_unregister_driver(&ath5k_pci_driver);
> > +
> > +       ath5k_debug_finish();
> > +}
> > +
> > +module_init(init_ath5k_pci);
> > +module_exit(exit_ath5k_pci);
> > 
> > 
> > 
> > 
> > Thanks,
> > 
> > Jonathan
> > 
> >>> > [   54.501954] skb_under_panic: text:c04e27f2 len:110 put:14 he0
> >>> > [   54.507979] ------------[ cut here ]------------
> >>> > [   54.511864] kernel BUG at net/core/skbuff.c:146!
> >>> > [   54.511864] invalid opcode: 0000 [#1] SMP
> >>> > [   54.511864] last sysfs file:
> >>> > /sys/devices/pci0000:00/0000:00:0c.0/device [   54.511864] Modules
> >>> > linked in: ath5k ath mac80211 led_class nfs lockd nfs_ac] [  
> >>> > 54.511864] [   54.511864] Pid: 0, comm: swapper Not tainted
> >>> > 2.6.36-rc6-wl-wl+ #3 / [   54.511864] EIP: 0060:[<c04c2b90>] EFLAGS:
> >>> > 00010286 CPU: 0 [   54.511864] EIP is at skb_push+0x80/0x90
> >>> > [   54.511864] EAX: 00000087 EBX: c04e27f2 ECX: c079daf4 EDX:
> >>> > 00000000 [   54.511864] ESI: cfd62cc0 EDI: cf468910 EBP: c0791d64
> >>> > ESP: c0791d3c [   54.511864]  DS: 007b ES: 007b FS: 00d8 GS: 00e0
> >>> > SS: 0068 [   54.511864] Process swapper (pid: 0, ti=c0790000
> >>> > task=c07976a0 task.ti=c0790) [   54.511864] Stack:
> >>> > [   54.511864]  c0754518 c04e27f2 0000006e 0000000e cfee8a00 cfee89f2
> >>> > cfee8a60 0 [   54.511864] <0> ce56c000 cfd62cc0 c0791d78 c04e27f2
> >>> > cfd62cc0 cfd62cc0 cf46890 [   54.511864] <0> c04cc866 00000040
> >>> > cf4682c0 cf4682c0 cf4682c0 c0791df8 d0c06a0 [   54.511864] Call
> >>> > Trace: [   54.511864]  [<c04e27f2>] ?
> >>> > skb_defer_rx_timestamp+0x22/0x80 [   54.511864]  [<c04e27f2>] ?
> >>> > skb_defer_rx_timestamp+0x22/0x80 [   54.511864]  [<c04cc866>] ?
> >>> > netif_receive_skb+0x26/0x90
> >>> > [   54.511864]  [<d0c06a83>] ? ieee80211_rx+0x613/0x800 [mac80211]
> >>> > [   54.511864]  [<c04c33dc>] ? __alloc_skb+0x5c/0x110
> >>> > [   54.511864]  [<d0c8badf>] ? ath5k_rx_skb_alloc+0x7f/0x160 [ath5k]
> >>> > [   54.511864]  [<d0c8cfa5>] ? ath5k_tasklet_rx+0x315/0x860 [ath5k]
> >>> > [   54.511864]  [<c0108538>] ? sched_clock+0x8/0x10
> >>> > [   54.511864]  [<c016d885>] ? sched_clock_local+0xa5/0x180
> >>> > [   54.511864]  [<d0c818c0>] ? ath5k_hw_get_isr+0xa0/0x380 [ath5k]
> >>> > [   54.511864]  [<d0c8ca9e>] ? ath5k_intr+0x2ae/0x4a0 [ath5k]
> >>> > [   54.511864]  [<c014fc17>] ? tasklet_action+0xa7/0xb0
> >>> > [   54.511864]  [<c015095c>] ? __do_softirq+0x9c/0x1b0
> >>> > [   54.511864]  [<c012c868>] ? default_spin_lock_flags+0x8/0x10
> >>> > [   54.511864]  [<c05b927f>] ? _raw_spin_lock_irqsave+0x2f/0x50
> >>> > [   54.511864]  [<c0150ab5>] ? do_softirq+0x45/0x50
> >>> > [   54.511864]  [<c0150c25>] ? irq_exit+0x65/0x70
> >>> > [   54.511864]  [<c05c0055>] ? do_IRQ+0x55/0xc0
> >>> > [   54.511864]  [<c017112f>] ? ktime_get+0x6f/0x110
> >>> > [   54.511864]  [<c01035b0>] ? common_interrupt+0x30/0x40
> >>> > [   54.511864]  [<c012bcaa>] ? native_safe_halt+0xa/0x10
> >>> > [   54.511864]  [<c0109f53>] ? default_idle+0x53/0xb0
> >>> > [   54.511864]  [<c0101e4a>] ? cpu_idle+0x8a/0xf0
> >>> > [   54.511864]  [<c05a2ccd>] ? rest_init+0x5d/0x70
> >>> > [   54.511864]  [<c07d297b>] ? start_kernel+0x357/0x35d
> >>> > [   54.511864]  [<c07d2450>] ? unknown_bootoption+0x0/0x19e
> >>> > [   54.511864]  [<c07d20de>] ? i386_start_kernel+0xde/0xe6
> >>> > [   54.511864] Code: 00 00 89 4c 24 14 8b 88 ac 00 00 00 89 54 24 0c
> >>> > 89 4c 24 1 [   54.511864] EIP: [<c04c2b90>] skb_push+0x80/0x90
> >>> > SS:ESP 0068:c0791d3c [   54.511864] ---[ end trace ccaff68ea5123ae2
> >>> > ]--- [   54.513037] Kernel panic - not syncing: Fatal exception in
> >>> > interrupt [   54.520124] Pid: 0, comm: swapper Tainted: G      D
> >>> > 2.6.36-rc6-wl-wl+ #3 [   54.521277] Call Trace:
> >>> > [   54.524656]  [<c05b6936>] ? printk+0x1d/0x1f
> >>> > [   54.529491]  [<c05b6817>] panic+0x5c/0x15e
> >>> > [   54.533818]  [<c05babdd>] oops_end+0xcd/0xd0
> >>> > [   54.538655]  [<c0105ce4>] die+0x54/0x80
> >>> > [   54.542199]  [<c05ba286>] do_trap+0x96/0xc0
> >>> > [   54.546781]  [<c0103d10>] ? do_invalid_op+0x0/0xa0
> >>> > [   54.549181]  [<c0103d9b>] do_invalid_op+0x8b/0xa0
> >>> > [   54.555342]  [<c04c2b90>] ? skb_push+0x80/0x90
> >>> > [   54.556724]  [<c014b041>] ? vprintk+0x191/0x3f0
> >>> > [   54.562339]  [<c04e27f2>] ? skb_defer_rx_timestamp+0x22/0x80
> >>> > [   54.567341]  [<c05ba017>] error_code+0x67/0x70
> >>> > [   54.568699]  [<c04e27f2>] ? skb_defer_rx_timestamp+0x22/0x80
> >>> > [   54.573704]  [<c04c2b90>] ? skb_push+0x80/0x90
> >>> > [   54.579064]  [<c04e27f2>] ? skb_defer_rx_timestamp+0x22/0x80
> >>> > [   54.584082]  [<c04e27f2>] skb_defer_rx_timestamp+0x22/0x80
> >>> > [   54.588612]  [<c04cc866>] netif_receive_skb+0x26/0x90
> >>> > [   54.595838]  [<d0c06a83>] ieee80211_rx+0x613/0x800 [mac80211]
> >>> > [   54.597099]  [<c04c33dc>] ? __alloc_skb+0x5c/0x110
> >>> > [   54.603523]  [<d0c8badf>] ? ath5k_rx_skb_alloc+0x7f/0x160 [ath5k]
> >>> > [   54.605849]  [<d0c8cfa5>] ath5k_tasklet_rx+0x315/0x860 [ath5k]
> >>> > [   54.611392]  [<c0108538>] ? sched_clock+0x8/0x10
> >>> > [   54.613284]  [<c016d885>] ? sched_clock_local+0xa5/0x180
> >>> > [   54.617265]  [<d0c818c0>] ? ath5k_hw_get_isr+0xa0/0x380 [ath5k]
> >>> > [   54.623076]  [<d0c8ca9e>] ? ath5k_intr+0x2ae/0x4a0 [ath5k]
> >>> > [   54.627564]  [<c014fc17>] tasklet_action+0xa7/0xb0
> >>> > [   54.629963]  [<c015095c>] __do_softirq+0x9c/0x1b0
> >>> > [   54.636107]  [<c012c868>] ? default_spin_lock_flags+0x8/0x10
> >>> > [   54.637124]  [<c05b927f>] ? _raw_spin_lock_irqsave+0x2f/0x50
> >>> > [   54.642137]  [<c0150ab5>] do_softirq+0x45/0x50
> >>> > [   54.647499]  [<c0150c25>] irq_exit+0x65/0x70
> >>> > [   54.652340]  [<c05c0055>] do_IRQ+0x55/0xc0
> >>> > [   54.652664]  [<c017112f>] ? ktime_get+0x6f/0x110
> >>> > [   54.658547]  [<c01035b0>] common_interrupt+0x30/0x40
> >>> > [   54.661471]  [<c012bcaa>] ? native_safe_halt+0xa/0x10
> >>> > [   54.664668]  [<c0109f53>] default_idle+0x53/0xb0
> >>> > [   54.670559]  [<c0101e4a>] cpu_idle+0x8a/0xf0
> >>> > [   54.675405]  [<c05a2ccd>] rest_init+0x5d/0x70
> >>> > [   54.680506]  [<c07d297b>] start_kernel+0x357/0x35d
> >>> > [   54.682907]  [<c07d2450>] ? unknown_bootoption+0x0/0x19e
> >>> > [   54.686869]  [<c07d20de>] i386_start_kernel+0xde/0xe6
> >>> > 
> >>> > Branch information:
> >>> > commit 25de059bdad7ce916df6f2cfdfc1c2d2d72abf11
> >>> > Merge: 412d5af 46bf695
> >>> > Author: John W. Linville <linville@tuxdriver.com>
> >>> > Date:   Tue Oct 5 15:09:33 2010 -0400
> >>> > 
> >>> > Thanks,
> >>> > 
> >>> > Jonathan Guerin
> >>> 
> >>> _______________________________________________
> >>> ath5k-devel mailing list
> >>> ath5k-devel@lists.ath5k.org
> >>> https://lists.ath5k.org/mailman/listinfo/ath5k-devel

^ permalink raw reply

* Re: [ath5k-devel] Kernel panic
From: Jonathan Guerin @ 2010-10-08  3:32 UTC (permalink / raw)
  To: Bruno Randolf; +Cc: ath5k-devel, linux-wireless
In-Reply-To: <AANLkTik9aUWu8T4Y7OgpPnTgZEtm3bGQ=Jn2RWx-YNHE@mail.gmail.com>

On Fri, Oct 8, 2010 at 1:12 PM, Jonathan Guerin <jonathan@guerin.id.au> wrote:
> On Thu, Oct 7, 2010 at 4:22 PM, Bruno Randolf <br1@einfach.org> wrote:
>> On Thu October 7 2010 14:41:18 Jonathan Guerin wrote:
>>> > I seem to be getting a kernel panic when creating an IBSS with the
>>> > latest ath5k driver. I remember Bruno submitting patches recently
>>> > which modifies the behaviour of timestamps in ath5k, so I was
>>> > wondering if this was related.
>>
>> did i? ;) i don't remember that.
>>
>>> Correction, this is not when creating an IBSS, but when bringing up an
>>> interface in monitor-mode.
>>
>> hmm... i don't see that with current wireless-testing. how do you create your
>> monitor interface?
>
> iw dev wlan0 interface add mon0 type monitor
> ifconfig mon0 up
>>
>> bruno
>>
>>
>
> I've just tried the latest wireless-testing build (2.6.36-rc7) on two
> different machines with different hardware configurations (but both
> with ath5k). I get the same kernel panic, repeatable every time I
> bring up a monitor mode interface (or not long after, as soon as it
> sees traffic).
>
> I reverted the kernels to 2.6.35 and this crash no longer happens. I'm
> not sure if this is related to the 'rx memory clobbering' post, so I
> haven't gone and tainted it. I'm happy to provide more data if
> necessary.

I've just looked for changes in ath5k which were submitted after
2.6.35 was released and found this patch. I won't pretend to
understand what's been changed, but could it be causing the panics I'm
observing?

Thanks,

Jonathan Guerin



On Fri, Sep 17, 2010 at 1:45 PM, Bruno Randolf <br1@einfach.org> wrote:
> From: Bob Copeland <me@bobcopeland.com>
>
> This change reorganizes the main ath5k file in order to re-group
> related functions and remove most of the forward declarations
> (from 61 down to 3).  This is, unfortunately, a lot of churn, but
> there should be no functional changes.
>
> Signed-off-by: Bob Copeland <me@bobcopeland.com>
> Signed-off-by: Bruno Randolf <br1@einfach.org>
>
> ---
> Bruno: rebased to wireless-next
> v2: resent because i lost the subject line before
> ---
>  drivers/net/wireless/ath/ath5k/base.c | 1662 +++++++++++++++------------------
>  1 files changed, 764 insertions(+), 898 deletions(-)
>
> diff --git a/drivers/net/wireless/ath/ath5k/base.c b/drivers/net/wireless/ath/ath5k/base.c
> index f8c699d..9e4636f 100644
> --- a/drivers/net/wireless/ath/ath5k/base.c
> +++ b/drivers/net/wireless/ath/ath5k/base.c
> @@ -70,11 +70,6 @@ static int modparam_all_channels;
>  module_param_named(all_channels, modparam_all_channels, bool, S_IRUGO);
>  MODULE_PARM_DESC(all_channels, "Expose all channels the device can use.");
>
> -
> -/******************\
> -* Internal defines *
> -\******************/
> -
>  /* Module info */
>  MODULE_AUTHOR("Jiri Slaby");
>  MODULE_AUTHOR("Nick Kossifidis");
> @@ -83,6 +78,10 @@ MODULE_SUPPORTED_DEVICE("Atheros 5xxx WLAN cards");
>  MODULE_LICENSE("Dual BSD/GPL");
>  MODULE_VERSION("0.6.0 (EXPERIMENTAL)");
>
> +static int ath5k_reset(struct ath5k_softc *sc, struct ieee80211_channel *chan);
> +static int ath5k_beacon_update(struct ieee80211_hw *hw,
> +               struct ieee80211_vif *vif);
> +static void ath5k_beacon_update_timers(struct ath5k_softc *sc, u64 bc_tsf);
>
>  /* Known PCI ids */
>  static DEFINE_PCI_DEVICE_TABLE(ath5k_pci_id_table) = {
> @@ -190,129 +189,6 @@ static const struct ieee80211_rate ath5k_rates[] = {
>        /* XR missing */
>  };
>
> -/*
> - * Prototypes - PCI stack related functions
> - */
> -static int __devinit   ath5k_pci_probe(struct pci_dev *pdev,
> -                               const struct pci_device_id *id);
> -static void __devexit  ath5k_pci_remove(struct pci_dev *pdev);
> -#ifdef CONFIG_PM_SLEEP
> -static int             ath5k_pci_suspend(struct device *dev);
> -static int             ath5k_pci_resume(struct device *dev);
> -
> -static SIMPLE_DEV_PM_OPS(ath5k_pm_ops, ath5k_pci_suspend, ath5k_pci_resume);
> -#define ATH5K_PM_OPS   (&ath5k_pm_ops)
> -#else
> -#define ATH5K_PM_OPS   NULL
> -#endif /* CONFIG_PM_SLEEP */
> -
> -static struct pci_driver ath5k_pci_driver = {
> -       .name           = KBUILD_MODNAME,
> -       .id_table       = ath5k_pci_id_table,
> -       .probe          = ath5k_pci_probe,
> -       .remove         = __devexit_p(ath5k_pci_remove),
> -       .driver.pm      = ATH5K_PM_OPS,
> -};
> -
> -
> -
> -/*
> - * Prototypes - MAC 802.11 stack related functions
> - */
> -static int ath5k_tx(struct ieee80211_hw *hw, struct sk_buff *skb);
> -static int ath5k_tx_queue(struct ieee80211_hw *hw, struct sk_buff *skb,
> -               struct ath5k_txq *txq);
> -static int ath5k_reset(struct ath5k_softc *sc, struct ieee80211_channel *chan);
> -static int ath5k_start(struct ieee80211_hw *hw);
> -static void ath5k_stop(struct ieee80211_hw *hw);
> -static int ath5k_add_interface(struct ieee80211_hw *hw,
> -               struct ieee80211_vif *vif);
> -static void ath5k_remove_interface(struct ieee80211_hw *hw,
> -               struct ieee80211_vif *vif);
> -static int ath5k_config(struct ieee80211_hw *hw, u32 changed);
> -static u64 ath5k_prepare_multicast(struct ieee80211_hw *hw,
> -                                  struct netdev_hw_addr_list *mc_list);
> -static void ath5k_configure_filter(struct ieee80211_hw *hw,
> -               unsigned int changed_flags,
> -               unsigned int *new_flags,
> -               u64 multicast);
> -static int ath5k_set_key(struct ieee80211_hw *hw,
> -               enum set_key_cmd cmd,
> -               struct ieee80211_vif *vif, struct ieee80211_sta *sta,
> -               struct ieee80211_key_conf *key);
> -static int ath5k_get_stats(struct ieee80211_hw *hw,
> -               struct ieee80211_low_level_stats *stats);
> -static int ath5k_get_survey(struct ieee80211_hw *hw,
> -               int idx, struct survey_info *survey);
> -static u64 ath5k_get_tsf(struct ieee80211_hw *hw);
> -static void ath5k_set_tsf(struct ieee80211_hw *hw, u64 tsf);
> -static void ath5k_reset_tsf(struct ieee80211_hw *hw);
> -static int ath5k_beacon_update(struct ieee80211_hw *hw,
> -               struct ieee80211_vif *vif);
> -static void ath5k_bss_info_changed(struct ieee80211_hw *hw,
> -               struct ieee80211_vif *vif,
> -               struct ieee80211_bss_conf *bss_conf,
> -               u32 changes);
> -static void ath5k_sw_scan_start(struct ieee80211_hw *hw);
> -static void ath5k_sw_scan_complete(struct ieee80211_hw *hw);
> -static void ath5k_set_coverage_class(struct ieee80211_hw *hw,
> -               u8 coverage_class);
> -
> -static const struct ieee80211_ops ath5k_hw_ops = {
> -       .tx             = ath5k_tx,
> -       .start          = ath5k_start,
> -       .stop           = ath5k_stop,
> -       .add_interface  = ath5k_add_interface,
> -       .remove_interface = ath5k_remove_interface,
> -       .config         = ath5k_config,
> -       .prepare_multicast = ath5k_prepare_multicast,
> -       .configure_filter = ath5k_configure_filter,
> -       .set_key        = ath5k_set_key,
> -       .get_stats      = ath5k_get_stats,
> -       .get_survey     = ath5k_get_survey,
> -       .conf_tx        = NULL,
> -       .get_tsf        = ath5k_get_tsf,
> -       .set_tsf        = ath5k_set_tsf,
> -       .reset_tsf      = ath5k_reset_tsf,
> -       .bss_info_changed = ath5k_bss_info_changed,
> -       .sw_scan_start  = ath5k_sw_scan_start,
> -       .sw_scan_complete = ath5k_sw_scan_complete,
> -       .set_coverage_class = ath5k_set_coverage_class,
> -};
> -
> -/*
> - * Prototypes - Internal functions
> - */
> -/* Attach detach */
> -static int     ath5k_attach(struct pci_dev *pdev,
> -                       struct ieee80211_hw *hw);
> -static void    ath5k_detach(struct pci_dev *pdev,
> -                       struct ieee80211_hw *hw);
> -/* Channel/mode setup */
> -static inline short ath5k_ieee2mhz(short chan);
> -static unsigned int ath5k_copy_channels(struct ath5k_hw *ah,
> -                               struct ieee80211_channel *channels,
> -                               unsigned int mode,
> -                               unsigned int max);
> -static int     ath5k_setup_bands(struct ieee80211_hw *hw);
> -static int     ath5k_chan_set(struct ath5k_softc *sc,
> -                               struct ieee80211_channel *chan);
> -static void    ath5k_setcurmode(struct ath5k_softc *sc,
> -                               unsigned int mode);
> -static void    ath5k_mode_setup(struct ath5k_softc *sc);
> -
> -/* Descriptor setup */
> -static int     ath5k_desc_alloc(struct ath5k_softc *sc,
> -                               struct pci_dev *pdev);
> -static void    ath5k_desc_free(struct ath5k_softc *sc,
> -                               struct pci_dev *pdev);
> -/* Buffers setup */
> -static int     ath5k_rxbuf_setup(struct ath5k_softc *sc,
> -                               struct ath5k_buf *bf);
> -static int     ath5k_txbuf_setup(struct ath5k_softc *sc,
> -                               struct ath5k_buf *bf,
> -                               struct ath5k_txq *txq, int padsize);
> -
>  static inline void ath5k_txbuf_free_skb(struct ath5k_softc *sc,
>                                struct ath5k_buf *bf)
>  {
> @@ -345,35 +221,6 @@ static inline void ath5k_rxbuf_free_skb(struct ath5k_softc *sc,
>  }
>
>
> -/* Queues setup */
> -static struct  ath5k_txq *ath5k_txq_setup(struct ath5k_softc *sc,
> -                               int qtype, int subtype);
> -static int     ath5k_beaconq_setup(struct ath5k_hw *ah);
> -static int     ath5k_beaconq_config(struct ath5k_softc *sc);
> -static void    ath5k_txq_drainq(struct ath5k_softc *sc,
> -                               struct ath5k_txq *txq);
> -static void    ath5k_txq_cleanup(struct ath5k_softc *sc);
> -static void    ath5k_txq_release(struct ath5k_softc *sc);
> -/* Rx handling */
> -static int     ath5k_rx_start(struct ath5k_softc *sc);
> -static void    ath5k_rx_stop(struct ath5k_softc *sc);
> -static unsigned int ath5k_rx_decrypted(struct ath5k_softc *sc,
> -                                       struct sk_buff *skb,
> -                                       struct ath5k_rx_status *rs);
> -static void    ath5k_tasklet_rx(unsigned long data);
> -/* Tx handling */
> -static void    ath5k_tx_processq(struct ath5k_softc *sc,
> -                               struct ath5k_txq *txq);
> -static void    ath5k_tasklet_tx(unsigned long data);
> -/* Beacon handling */
> -static int     ath5k_beacon_setup(struct ath5k_softc *sc,
> -                                       struct ath5k_buf *bf);
> -static void    ath5k_beacon_send(struct ath5k_softc *sc);
> -static void    ath5k_beacon_config(struct ath5k_softc *sc);
> -static void    ath5k_beacon_update_timers(struct ath5k_softc *sc, u64 bc_tsf);
> -static void    ath5k_tasklet_beacon(unsigned long data);
> -static void    ath5k_tasklet_ani(unsigned long data);
> -
>  static inline u64 ath5k_extend_tsf(struct ath5k_hw *ah, u32 rstamp)
>  {
>        u64 tsf = ath5k_hw_get_tsf64(ah);
> @@ -384,50 +231,6 @@ static inline u64 ath5k_extend_tsf(struct ath5k_hw *ah, u32 rstamp)
>        return (tsf & ~0x7fff) | rstamp;
>  }
>
> -/* Interrupt handling */
> -static int     ath5k_init(struct ath5k_softc *sc);
> -static int     ath5k_stop_locked(struct ath5k_softc *sc);
> -static int     ath5k_stop_hw(struct ath5k_softc *sc);
> -static irqreturn_t ath5k_intr(int irq, void *dev_id);
> -static void ath5k_reset_work(struct work_struct *work);
> -
> -static void    ath5k_tasklet_calibrate(unsigned long data);
> -
> -/*
> - * Module init/exit functions
> - */
> -static int __init
> -init_ath5k_pci(void)
> -{
> -       int ret;
> -
> -       ath5k_debug_init();
> -
> -       ret = pci_register_driver(&ath5k_pci_driver);
> -       if (ret) {
> -               printk(KERN_ERR "ath5k_pci: can't register pci driver\n");
> -               return ret;
> -       }
> -
> -       return 0;
> -}
> -
> -static void __exit
> -exit_ath5k_pci(void)
> -{
> -       pci_unregister_driver(&ath5k_pci_driver);
> -
> -       ath5k_debug_finish();
> -}
> -
> -module_init(init_ath5k_pci);
> -module_exit(exit_ath5k_pci);
> -
> -
> -/********************\
> -* PCI Initialization *
> -\********************/
> -
>  static const char *
>  ath5k_chip_name(enum ath5k_srev_type type, u_int16_t val)
>  {
> @@ -466,299 +269,6 @@ static const struct ath_ops ath5k_common_ops = {
>        .write = ath5k_iowrite32,
>  };
>
> -static int __devinit
> -ath5k_pci_probe(struct pci_dev *pdev,
> -               const struct pci_device_id *id)
> -{
> -       void __iomem *mem;
> -       struct ath5k_softc *sc;
> -       struct ath_common *common;
> -       struct ieee80211_hw *hw;
> -       int ret;
> -       u8 csz;
> -
> -       /*
> -        * L0s needs to be disabled on all ath5k cards.
> -        *
> -        * For distributions shipping with CONFIG_PCIEASPM (this will be enabled
> -        * by default in the future in 2.6.36) this will also mean both L1 and
> -        * L0s will be disabled when a pre 1.1 PCIe device is detected. We do
> -        * know L1 works correctly even for all ath5k pre 1.1 PCIe devices
> -        * though but cannot currently undue the effect of a blacklist, for
> -        * details you can read pcie_aspm_sanity_check() and see how it adjusts
> -        * the device link capability.
> -        *
> -        * It may be possible in the future to implement some PCI API to allow
> -        * drivers to override blacklists for pre 1.1 PCIe but for now it is
> -        * best to accept that both L0s and L1 will be disabled completely for
> -        * distributions shipping with CONFIG_PCIEASPM rather than having this
> -        * issue present. Motivation for adding this new API will be to help
> -        * with power consumption for some of these devices.
> -        */
> -       pci_disable_link_state(pdev, PCIE_LINK_STATE_L0S);
> -
> -       ret = pci_enable_device(pdev);
> -       if (ret) {
> -               dev_err(&pdev->dev, "can't enable device\n");
> -               goto err;
> -       }
> -
> -       /* XXX 32-bit addressing only */
> -       ret = pci_set_dma_mask(pdev, DMA_BIT_MASK(32));
> -       if (ret) {
> -               dev_err(&pdev->dev, "32-bit DMA not available\n");
> -               goto err_dis;
> -       }
> -
> -       /*
> -        * Cache line size is used to size and align various
> -        * structures used to communicate with the hardware.
> -        */
> -       pci_read_config_byte(pdev, PCI_CACHE_LINE_SIZE, &csz);
> -       if (csz == 0) {
> -               /*
> -                * Linux 2.4.18 (at least) writes the cache line size
> -                * register as a 16-bit wide register which is wrong.
> -                * We must have this setup properly for rx buffer
> -                * DMA to work so force a reasonable value here if it
> -                * comes up zero.
> -                */
> -               csz = L1_CACHE_BYTES >> 2;
> -               pci_write_config_byte(pdev, PCI_CACHE_LINE_SIZE, csz);
> -       }
> -       /*
> -        * The default setting of latency timer yields poor results,
> -        * set it to the value used by other systems.  It may be worth
> -        * tweaking this setting more.
> -        */
> -       pci_write_config_byte(pdev, PCI_LATENCY_TIMER, 0xa8);
> -
> -       /* Enable bus mastering */
> -       pci_set_master(pdev);
> -
> -       /*
> -        * Disable the RETRY_TIMEOUT register (0x41) to keep
> -        * PCI Tx retries from interfering with C3 CPU state.
> -        */
> -       pci_write_config_byte(pdev, 0x41, 0);
> -
> -       ret = pci_request_region(pdev, 0, "ath5k");
> -       if (ret) {
> -               dev_err(&pdev->dev, "cannot reserve PCI memory region\n");
> -               goto err_dis;
> -       }
> -
> -       mem = pci_iomap(pdev, 0, 0);
> -       if (!mem) {
> -               dev_err(&pdev->dev, "cannot remap PCI memory region\n") ;
> -               ret = -EIO;
> -               goto err_reg;
> -       }
> -
> -       /*
> -        * Allocate hw (mac80211 main struct)
> -        * and hw->priv (driver private data)
> -        */
> -       hw = ieee80211_alloc_hw(sizeof(*sc), &ath5k_hw_ops);
> -       if (hw == NULL) {
> -               dev_err(&pdev->dev, "cannot allocate ieee80211_hw\n");
> -               ret = -ENOMEM;
> -               goto err_map;
> -       }
> -
> -       dev_info(&pdev->dev, "registered as '%s'\n", wiphy_name(hw->wiphy));
> -
> -       /* Initialize driver private data */
> -       SET_IEEE80211_DEV(hw, &pdev->dev);
> -       hw->flags = IEEE80211_HW_RX_INCLUDES_FCS |
> -                   IEEE80211_HW_HOST_BROADCAST_PS_BUFFERING |
> -                   IEEE80211_HW_SIGNAL_DBM;
> -
> -       hw->wiphy->interface_modes =
> -               BIT(NL80211_IFTYPE_AP) |
> -               BIT(NL80211_IFTYPE_STATION) |
> -               BIT(NL80211_IFTYPE_ADHOC) |
> -               BIT(NL80211_IFTYPE_MESH_POINT);
> -
> -       hw->extra_tx_headroom = 2;
> -       hw->channel_change_time = 5000;
> -       sc = hw->priv;
> -       sc->hw = hw;
> -       sc->pdev = pdev;
> -
> -       ath5k_debug_init_device(sc);
> -
> -       /*
> -        * Mark the device as detached to avoid processing
> -        * interrupts until setup is complete.
> -        */
> -       __set_bit(ATH_STAT_INVALID, sc->status);
> -
> -       sc->iobase = mem; /* So we can unmap it on detach */
> -       sc->opmode = NL80211_IFTYPE_STATION;
> -       sc->bintval = 1000;
> -       mutex_init(&sc->lock);
> -       spin_lock_init(&sc->rxbuflock);
> -       spin_lock_init(&sc->txbuflock);
> -       spin_lock_init(&sc->block);
> -
> -       /* Set private data */
> -       pci_set_drvdata(pdev, sc);
> -
> -       /* Setup interrupt handler */
> -       ret = request_irq(pdev->irq, ath5k_intr, IRQF_SHARED, "ath", sc);
> -       if (ret) {
> -               ATH5K_ERR(sc, "request_irq failed\n");
> -               goto err_free;
> -       }
> -
> -       /* If we passed the test, malloc an ath5k_hw struct */
> -       sc->ah = kzalloc(sizeof(struct ath5k_hw), GFP_KERNEL);
> -       if (!sc->ah) {
> -               ret = -ENOMEM;
> -               ATH5K_ERR(sc, "out of memory\n");
> -               goto err_irq;
> -       }
> -
> -       sc->ah->ah_sc = sc;
> -       sc->ah->ah_iobase = sc->iobase;
> -       common = ath5k_hw_common(sc->ah);
> -       common->ops = &ath5k_common_ops;
> -       common->ah = sc->ah;
> -       common->hw = hw;
> -       common->cachelsz = csz << 2; /* convert to bytes */
> -
> -       /* Initialize device */
> -       ret = ath5k_hw_attach(sc);
> -       if (ret) {
> -               goto err_free_ah;
> -       }
> -
> -       /* set up multi-rate retry capabilities */
> -       if (sc->ah->ah_version == AR5K_AR5212) {
> -               hw->max_rates = 4;
> -               hw->max_rate_tries = 11;
> -       }
> -
> -       /* Finish private driver data initialization */
> -       ret = ath5k_attach(pdev, hw);
> -       if (ret)
> -               goto err_ah;
> -
> -       ATH5K_INFO(sc, "Atheros AR%s chip found (MAC: 0x%x, PHY: 0x%x)\n",
> -                       ath5k_chip_name(AR5K_VERSION_MAC, sc->ah->ah_mac_srev),
> -                                       sc->ah->ah_mac_srev,
> -                                       sc->ah->ah_phy_revision);
> -
> -       if (!sc->ah->ah_single_chip) {
> -               /* Single chip radio (!RF5111) */
> -               if (sc->ah->ah_radio_5ghz_revision &&
> -                       !sc->ah->ah_radio_2ghz_revision) {
> -                       /* No 5GHz support -> report 2GHz radio */
> -                       if (!test_bit(AR5K_MODE_11A,
> -                               sc->ah->ah_capabilities.cap_mode)) {
> -                               ATH5K_INFO(sc, "RF%s 2GHz radio found (0x%x)\n",
> -                                       ath5k_chip_name(AR5K_VERSION_RAD,
> -                                               sc->ah->ah_radio_5ghz_revision),
> -                                               sc->ah->ah_radio_5ghz_revision);
> -                       /* No 2GHz support (5110 and some
> -                        * 5Ghz only cards) -> report 5Ghz radio */
> -                       } else if (!test_bit(AR5K_MODE_11B,
> -                               sc->ah->ah_capabilities.cap_mode)) {
> -                               ATH5K_INFO(sc, "RF%s 5GHz radio found (0x%x)\n",
> -                                       ath5k_chip_name(AR5K_VERSION_RAD,
> -                                               sc->ah->ah_radio_5ghz_revision),
> -                                               sc->ah->ah_radio_5ghz_revision);
> -                       /* Multiband radio */
> -                       } else {
> -                               ATH5K_INFO(sc, "RF%s multiband radio found"
> -                                       " (0x%x)\n",
> -                                       ath5k_chip_name(AR5K_VERSION_RAD,
> -                                               sc->ah->ah_radio_5ghz_revision),
> -                                               sc->ah->ah_radio_5ghz_revision);
> -                       }
> -               }
> -               /* Multi chip radio (RF5111 - RF2111) ->
> -                * report both 2GHz/5GHz radios */
> -               else if (sc->ah->ah_radio_5ghz_revision &&
> -                               sc->ah->ah_radio_2ghz_revision){
> -                       ATH5K_INFO(sc, "RF%s 5GHz radio found (0x%x)\n",
> -                               ath5k_chip_name(AR5K_VERSION_RAD,
> -                                       sc->ah->ah_radio_5ghz_revision),
> -                                       sc->ah->ah_radio_5ghz_revision);
> -                       ATH5K_INFO(sc, "RF%s 2GHz radio found (0x%x)\n",
> -                               ath5k_chip_name(AR5K_VERSION_RAD,
> -                                       sc->ah->ah_radio_2ghz_revision),
> -                                       sc->ah->ah_radio_2ghz_revision);
> -               }
> -       }
> -
> -
> -       /* ready to process interrupts */
> -       __clear_bit(ATH_STAT_INVALID, sc->status);
> -
> -       return 0;
> -err_ah:
> -       ath5k_hw_detach(sc->ah);
> -err_free_ah:
> -       kfree(sc->ah);
> -err_irq:
> -       free_irq(pdev->irq, sc);
> -err_free:
> -       ieee80211_free_hw(hw);
> -err_map:
> -       pci_iounmap(pdev, mem);
> -err_reg:
> -       pci_release_region(pdev, 0);
> -err_dis:
> -       pci_disable_device(pdev);
> -err:
> -       return ret;
> -}
> -
> -static void __devexit
> -ath5k_pci_remove(struct pci_dev *pdev)
> -{
> -       struct ath5k_softc *sc = pci_get_drvdata(pdev);
> -
> -       ath5k_debug_finish_device(sc);
> -       ath5k_detach(pdev, sc->hw);
> -       ath5k_hw_detach(sc->ah);
> -       kfree(sc->ah);
> -       free_irq(pdev->irq, sc);
> -       pci_iounmap(pdev, sc->iobase);
> -       pci_release_region(pdev, 0);
> -       pci_disable_device(pdev);
> -       ieee80211_free_hw(sc->hw);
> -}
> -
> -#ifdef CONFIG_PM_SLEEP
> -static int ath5k_pci_suspend(struct device *dev)
> -{
> -       struct ath5k_softc *sc = pci_get_drvdata(to_pci_dev(dev));
> -
> -       ath5k_led_off(sc);
> -       return 0;
> -}
> -
> -static int ath5k_pci_resume(struct device *dev)
> -{
> -       struct pci_dev *pdev = to_pci_dev(dev);
> -       struct ath5k_softc *sc = pci_get_drvdata(pdev);
> -
> -       /*
> -        * Suspend/Resume resets the PCI configuration space, so we have to
> -        * re-disable the RETRY_TIMEOUT register (0x41) to keep
> -        * PCI Tx retries from interfering with C3 CPU state
> -        */
> -       pci_write_config_byte(pdev, 0x41, 0);
> -
> -       ath5k_led_enable(sc);
> -       return 0;
> -}
> -#endif /* CONFIG_PM_SLEEP */
> -
> -
>  /***********************\
>  * Driver Initialization *
>  \***********************/
> @@ -772,170 +282,6 @@ static int ath5k_reg_notifier(struct wiphy *wiphy, struct regulatory_request *re
>        return ath_reg_notifier_apply(wiphy, request, regulatory);
>  }
>
> -static int
> -ath5k_attach(struct pci_dev *pdev, struct ieee80211_hw *hw)
> -{
> -       struct ath5k_softc *sc = hw->priv;
> -       struct ath5k_hw *ah = sc->ah;
> -       struct ath_regulatory *regulatory = ath5k_hw_regulatory(ah);
> -       u8 mac[ETH_ALEN] = {};
> -       int ret;
> -
> -       ATH5K_DBG(sc, ATH5K_DEBUG_ANY, "devid 0x%x\n", pdev->device);
> -
> -       /*
> -        * Check if the MAC has multi-rate retry support.
> -        * We do this by trying to setup a fake extended
> -        * descriptor.  MACs that don't have support will
> -        * return false w/o doing anything.  MACs that do
> -        * support it will return true w/o doing anything.
> -        */
> -       ret = ath5k_hw_setup_mrr_tx_desc(ah, NULL, 0, 0, 0, 0, 0, 0);
> -
> -       if (ret < 0)
> -               goto err;
> -       if (ret > 0)
> -               __set_bit(ATH_STAT_MRRETRY, sc->status);
> -
> -       /*
> -        * Collect the channel list.  The 802.11 layer
> -        * is resposible for filtering this list based
> -        * on settings like the phy mode and regulatory
> -        * domain restrictions.
> -        */
> -       ret = ath5k_setup_bands(hw);
> -       if (ret) {
> -               ATH5K_ERR(sc, "can't get channels\n");
> -               goto err;
> -       }
> -
> -       /* NB: setup here so ath5k_rate_update is happy */
> -       if (test_bit(AR5K_MODE_11A, ah->ah_modes))
> -               ath5k_setcurmode(sc, AR5K_MODE_11A);
> -       else
> -               ath5k_setcurmode(sc, AR5K_MODE_11B);
> -
> -       /*
> -        * Allocate tx+rx descriptors and populate the lists.
> -        */
> -       ret = ath5k_desc_alloc(sc, pdev);
> -       if (ret) {
> -               ATH5K_ERR(sc, "can't allocate descriptors\n");
> -               goto err;
> -       }
> -
> -       /*
> -        * Allocate hardware transmit queues: one queue for
> -        * beacon frames and one data queue for each QoS
> -        * priority.  Note that hw functions handle resetting
> -        * these queues at the needed time.
> -        */
> -       ret = ath5k_beaconq_setup(ah);
> -       if (ret < 0) {
> -               ATH5K_ERR(sc, "can't setup a beacon xmit queue\n");
> -               goto err_desc;
> -       }
> -       sc->bhalq = ret;
> -       sc->cabq = ath5k_txq_setup(sc, AR5K_TX_QUEUE_CAB, 0);
> -       if (IS_ERR(sc->cabq)) {
> -               ATH5K_ERR(sc, "can't setup cab queue\n");
> -               ret = PTR_ERR(sc->cabq);
> -               goto err_bhal;
> -       }
> -
> -       sc->txq = ath5k_txq_setup(sc, AR5K_TX_QUEUE_DATA, AR5K_WME_AC_BK);
> -       if (IS_ERR(sc->txq)) {
> -               ATH5K_ERR(sc, "can't setup xmit queue\n");
> -               ret = PTR_ERR(sc->txq);
> -               goto err_queues;
> -       }
> -
> -       tasklet_init(&sc->rxtq, ath5k_tasklet_rx, (unsigned long)sc);
> -       tasklet_init(&sc->txtq, ath5k_tasklet_tx, (unsigned long)sc);
> -       tasklet_init(&sc->calib, ath5k_tasklet_calibrate, (unsigned long)sc);
> -       tasklet_init(&sc->beacontq, ath5k_tasklet_beacon, (unsigned long)sc);
> -       tasklet_init(&sc->ani_tasklet, ath5k_tasklet_ani, (unsigned long)sc);
> -
> -       INIT_WORK(&sc->reset_work, ath5k_reset_work);
> -
> -       ret = ath5k_eeprom_read_mac(ah, mac);
> -       if (ret) {
> -               ATH5K_ERR(sc, "unable to read address from EEPROM: 0x%04x\n",
> -                       sc->pdev->device);
> -               goto err_queues;
> -       }
> -
> -       SET_IEEE80211_PERM_ADDR(hw, mac);
> -       /* All MAC address bits matter for ACKs */
> -       memcpy(sc->bssidmask, ath_bcast_mac, ETH_ALEN);
> -       ath5k_hw_set_bssid_mask(sc->ah, sc->bssidmask);
> -
> -       regulatory->current_rd = ah->ah_capabilities.cap_eeprom.ee_regdomain;
> -       ret = ath_regd_init(regulatory, hw->wiphy, ath5k_reg_notifier);
> -       if (ret) {
> -               ATH5K_ERR(sc, "can't initialize regulatory system\n");
> -               goto err_queues;
> -       }
> -
> -       ret = ieee80211_register_hw(hw);
> -       if (ret) {
> -               ATH5K_ERR(sc, "can't register ieee80211 hw\n");
> -               goto err_queues;
> -       }
> -
> -       if (!ath_is_world_regd(regulatory))
> -               regulatory_hint(hw->wiphy, regulatory->alpha2);
> -
> -       ath5k_init_leds(sc);
> -
> -       ath5k_sysfs_register(sc);
> -
> -       return 0;
> -err_queues:
> -       ath5k_txq_release(sc);
> -err_bhal:
> -       ath5k_hw_release_tx_queue(ah, sc->bhalq);
> -err_desc:
> -       ath5k_desc_free(sc, pdev);
> -err:
> -       return ret;
> -}
> -
> -static void
> -ath5k_detach(struct pci_dev *pdev, struct ieee80211_hw *hw)
> -{
> -       struct ath5k_softc *sc = hw->priv;
> -
> -       /*
> -        * NB: the order of these is important:
> -        * o call the 802.11 layer before detaching ath5k_hw to
> -        *   ensure callbacks into the driver to delete global
> -        *   key cache entries can be handled
> -        * o reclaim the tx queue data structures after calling
> -        *   the 802.11 layer as we'll get called back to reclaim
> -        *   node state and potentially want to use them
> -        * o to cleanup the tx queues the hal is called, so detach
> -        *   it last
> -        * XXX: ??? detach ath5k_hw ???
> -        * Other than that, it's straightforward...
> -        */
> -       ieee80211_unregister_hw(hw);
> -       ath5k_desc_free(sc, pdev);
> -       ath5k_txq_release(sc);
> -       ath5k_hw_release_tx_queue(sc->ah, sc->bhalq);
> -       ath5k_unregister_leds(sc);
> -
> -       ath5k_sysfs_unregister(sc);
> -       /*
> -        * NB: can't reclaim these until after ieee80211_ifdetach
> -        * returns because we'll get called back to reclaim node
> -        * state and potentially want to use them.
> -        */
> -}
> -
> -
> -
> -
>  /********************\
>  * Channel/mode setup *
>  \********************/
> @@ -1494,9 +840,6 @@ ath5k_desc_free(struct ath5k_softc *sc, struct pci_dev *pdev)
>  }
>
>
> -
> -
> -
>  /**************\
>  * Queues setup *
>  \**************/
> @@ -1696,8 +1039,6 @@ ath5k_txq_release(struct ath5k_softc *sc)
>  }
>
>
> -
> -
>  /*************\
>  * RX Handling *
>  \*************/
> @@ -2121,6 +1462,59 @@ unlock:
>  * TX Handling *
>  \*************/
>
> +static int ath5k_tx_queue(struct ieee80211_hw *hw, struct sk_buff *skb,
> +                         struct ath5k_txq *txq)
> +{
> +       struct ath5k_softc *sc = hw->priv;
> +       struct ath5k_buf *bf;
> +       unsigned long flags;
> +       int padsize;
> +
> +       ath5k_debug_dump_skb(sc, skb, "TX  ", 1);
> +
> +       /*
> +        * The hardware expects the header padded to 4 byte boundaries.
> +        * If this is not the case, we add the padding after the header.
> +        */
> +       padsize = ath5k_add_padding(skb);
> +       if (padsize < 0) {
> +               ATH5K_ERR(sc, "tx hdrlen not %%4: not enough"
> +                         " headroom to pad");
> +               goto drop_packet;
> +       }
> +
> +       spin_lock_irqsave(&sc->txbuflock, flags);
> +       if (list_empty(&sc->txbuf)) {
> +               ATH5K_ERR(sc, "no further txbuf available, dropping packet\n");
> +               spin_unlock_irqrestore(&sc->txbuflock, flags);
> +               ieee80211_stop_queue(hw, skb_get_queue_mapping(skb));
> +               goto drop_packet;
> +       }
> +       bf = list_first_entry(&sc->txbuf, struct ath5k_buf, list);
> +       list_del(&bf->list);
> +       sc->txbuf_len--;
> +       if (list_empty(&sc->txbuf))
> +               ieee80211_stop_queues(hw);
> +       spin_unlock_irqrestore(&sc->txbuflock, flags);
> +
> +       bf->skb = skb;
> +
> +       if (ath5k_txbuf_setup(sc, bf, txq, padsize)) {
> +               bf->skb = NULL;
> +               spin_lock_irqsave(&sc->txbuflock, flags);
> +               list_add_tail(&bf->list, &sc->txbuf);
> +               sc->txbuf_len++;
> +               spin_unlock_irqrestore(&sc->txbuflock, flags);
> +               goto drop_packet;
> +       }
> +       return NETDEV_TX_OK;
> +
> +drop_packet:
> +       dev_kfree_skb_any(skb);
> +       return NETDEV_TX_OK;
> +}
> +
> +
>  static void
>  ath5k_tx_processq(struct ath5k_softc *sc, struct ath5k_txq *txq)
>  {
> @@ -2313,6 +1707,43 @@ err_unmap:
>  }
>
>  /*
> + * Updates the beacon that is sent by ath5k_beacon_send.  For adhoc,
> + * this is called only once at config_bss time, for AP we do it every
> + * SWBA interrupt so that the TIM will reflect buffered frames.
> + *
> + * Called with the beacon lock.
> + */
> +static int
> +ath5k_beacon_update(struct ieee80211_hw *hw, struct ieee80211_vif *vif)
> +{
> +       int ret;
> +       struct ath5k_softc *sc = hw->priv;
> +       struct sk_buff *skb;
> +
> +       if (WARN_ON(!vif)) {
> +               ret = -EINVAL;
> +               goto out;
> +       }
> +
> +       skb = ieee80211_beacon_get(hw, vif);
> +
> +       if (!skb) {
> +               ret = -ENOMEM;
> +               goto out;
> +       }
> +
> +       ath5k_debug_dump_skb(sc, skb, "BC  ", 1);
> +
> +       ath5k_txbuf_free_skb(sc, sc->bbuf);
> +       sc->bbuf->skb = skb;
> +       ret = ath5k_beacon_setup(sc, sc->bbuf);
> +       if (ret)
> +               sc->bbuf->skb = NULL;
> +out:
> +       return ret;
> +}
> +
> +/*
>  * Transmit a beacon frame at SWBA.  Dynamic updates to the
>  * frame contents are done as needed and the slot time is
>  * also adjusted based on current state.
> @@ -2389,7 +1820,6 @@ ath5k_beacon_send(struct ath5k_softc *sc)
>        sc->bsent++;
>  }
>
> -
>  /**
>  * ath5k_beacon_update_timers - update beacon timers
>  *
> @@ -2491,7 +1921,6 @@ ath5k_beacon_update_timers(struct ath5k_softc *sc, u64 bc_tsf)
>                intval & AR5K_BEACON_RESET_TSF ? "AR5K_BEACON_RESET_TSF" : "");
>  }
>
> -
>  /**
>  * ath5k_beacon_config - Configure the beacon queues and interrupts
>  *
> @@ -2570,156 +1999,6 @@ static void ath5k_tasklet_beacon(unsigned long data)
>  * Interrupt handling *
>  \********************/
>
> -static int
> -ath5k_init(struct ath5k_softc *sc)
> -{
> -       struct ath5k_hw *ah = sc->ah;
> -       struct ath_common *common = ath5k_hw_common(ah);
> -       int ret, i;
> -
> -       mutex_lock(&sc->lock);
> -
> -       ATH5K_DBG(sc, ATH5K_DEBUG_RESET, "mode %d\n", sc->opmode);
> -
> -       /*
> -        * Stop anything previously setup.  This is safe
> -        * no matter this is the first time through or not.
> -        */
> -       ath5k_stop_locked(sc);
> -
> -       /*
> -        * The basic interface to setting the hardware in a good
> -        * state is ``reset''.  On return the hardware is known to
> -        * be powered up and with interrupts disabled.  This must
> -        * be followed by initialization of the appropriate bits
> -        * and then setup of the interrupt mask.
> -        */
> -       sc->curchan = sc->hw->conf.channel;
> -       sc->curband = &sc->sbands[sc->curchan->band];
> -       sc->imask = AR5K_INT_RXOK | AR5K_INT_RXERR | AR5K_INT_RXEOL |
> -               AR5K_INT_RXORN | AR5K_INT_TXDESC | AR5K_INT_TXEOL |
> -               AR5K_INT_FATAL | AR5K_INT_GLOBAL | AR5K_INT_MIB;
> -
> -       ret = ath5k_reset(sc, NULL);
> -       if (ret)
> -               goto done;
> -
> -       ath5k_rfkill_hw_start(ah);
> -
> -       /*
> -        * Reset the key cache since some parts do not reset the
> -        * contents on initial power up or resume from suspend.
> -        */
> -       for (i = 0; i < common->keymax; i++)
> -               ath_hw_keyreset(common, (u16)i);
> -
> -       ath5k_hw_set_ack_bitrate_high(ah, true);
> -       ret = 0;
> -done:
> -       mmiowb();
> -       mutex_unlock(&sc->lock);
> -       return ret;
> -}
> -
> -static int
> -ath5k_stop_locked(struct ath5k_softc *sc)
> -{
> -       struct ath5k_hw *ah = sc->ah;
> -
> -       ATH5K_DBG(sc, ATH5K_DEBUG_RESET, "invalid %u\n",
> -                       test_bit(ATH_STAT_INVALID, sc->status));
> -
> -       /*
> -        * Shutdown the hardware and driver:
> -        *    stop output from above
> -        *    disable interrupts
> -        *    turn off timers
> -        *    turn off the radio
> -        *    clear transmit machinery
> -        *    clear receive machinery
> -        *    drain and release tx queues
> -        *    reclaim beacon resources
> -        *    power down hardware
> -        *
> -        * Note that some of this work is not possible if the
> -        * hardware is gone (invalid).
> -        */
> -       ieee80211_stop_queues(sc->hw);
> -
> -       if (!test_bit(ATH_STAT_INVALID, sc->status)) {
> -               ath5k_led_off(sc);
> -               ath5k_hw_set_imr(ah, 0);
> -               synchronize_irq(sc->pdev->irq);
> -       }
> -       ath5k_txq_cleanup(sc);
> -       if (!test_bit(ATH_STAT_INVALID, sc->status)) {
> -               ath5k_rx_stop(sc);
> -               ath5k_hw_phy_disable(ah);
> -       }
> -
> -       return 0;
> -}
> -
> -static void stop_tasklets(struct ath5k_softc *sc)
> -{
> -       tasklet_kill(&sc->rxtq);
> -       tasklet_kill(&sc->txtq);
> -       tasklet_kill(&sc->calib);
> -       tasklet_kill(&sc->beacontq);
> -       tasklet_kill(&sc->ani_tasklet);
> -}
> -
> -/*
> - * Stop the device, grabbing the top-level lock to protect
> - * against concurrent entry through ath5k_init (which can happen
> - * if another thread does a system call and the thread doing the
> - * stop is preempted).
> - */
> -static int
> -ath5k_stop_hw(struct ath5k_softc *sc)
> -{
> -       int ret;
> -
> -       mutex_lock(&sc->lock);
> -       ret = ath5k_stop_locked(sc);
> -       if (ret == 0 && !test_bit(ATH_STAT_INVALID, sc->status)) {
> -               /*
> -                * Don't set the card in full sleep mode!
> -                *
> -                * a) When the device is in this state it must be carefully
> -                * woken up or references to registers in the PCI clock
> -                * domain may freeze the bus (and system).  This varies
> -                * by chip and is mostly an issue with newer parts
> -                * (madwifi sources mentioned srev >= 0x78) that go to
> -                * sleep more quickly.
> -                *
> -                * b) On older chips full sleep results a weird behaviour
> -                * during wakeup. I tested various cards with srev < 0x78
> -                * and they don't wake up after module reload, a second
> -                * module reload is needed to bring the card up again.
> -                *
> -                * Until we figure out what's going on don't enable
> -                * full chip reset on any chip (this is what Legacy HAL
> -                * and Sam's HAL do anyway). Instead Perform a full reset
> -                * on the device (same as initial state after attach) and
> -                * leave it idle (keep MAC/BB on warm reset) */
> -               ret = ath5k_hw_on_hold(sc->ah);
> -
> -               ATH5K_DBG(sc, ATH5K_DEBUG_RESET,
> -                               "putting device to sleep\n");
> -       }
> -       ath5k_txbuf_free_skb(sc, sc->bbuf);
> -
> -       mmiowb();
> -       mutex_unlock(&sc->lock);
> -
> -       stop_tasklets(sc);
> -
> -       ath5k_rfkill_hw_stop(sc->ah);
> -
> -       return ret;
> -}
> -
>  static void
>  ath5k_intr_calibration_poll(struct ath5k_hw *ah)
>  {
> @@ -2882,68 +2161,158 @@ ath5k_tasklet_ani(unsigned long data)
>  }
>
>
> -/********************\
> -* Mac80211 functions *
> -\********************/
> +/*************************\
> +* Initialization routines *
> +\*************************/
>
>  static int
> -ath5k_tx(struct ieee80211_hw *hw, struct sk_buff *skb)
> +ath5k_stop_locked(struct ath5k_softc *sc)
>  {
> -       struct ath5k_softc *sc = hw->priv;
> +       struct ath5k_hw *ah = sc->ah;
>
> -       return ath5k_tx_queue(hw, skb, sc->txq);
> +       ATH5K_DBG(sc, ATH5K_DEBUG_RESET, "invalid %u\n",
> +                       test_bit(ATH_STAT_INVALID, sc->status));
> +
> +       /*
> +        * Shutdown the hardware and driver:
> +        *    stop output from above
> +        *    disable interrupts
> +        *    turn off timers
> +        *    turn off the radio
> +        *    clear transmit machinery
> +        *    clear receive machinery
> +        *    drain and release tx queues
> +        *    reclaim beacon resources
> +        *    power down hardware
> +        *
> +        * Note that some of this work is not possible if the
> +        * hardware is gone (invalid).
> +        */
> +       ieee80211_stop_queues(sc->hw);
> +
> +       if (!test_bit(ATH_STAT_INVALID, sc->status)) {
> +               ath5k_led_off(sc);
> +               ath5k_hw_set_imr(ah, 0);
> +               synchronize_irq(sc->pdev->irq);
> +       }
> +       ath5k_txq_cleanup(sc);
> +       if (!test_bit(ATH_STAT_INVALID, sc->status)) {
> +               ath5k_rx_stop(sc);
> +               ath5k_hw_phy_disable(ah);
> +       }
> +
> +       return 0;
>  }
>
> -static int ath5k_tx_queue(struct ieee80211_hw *hw, struct sk_buff *skb,
> -                         struct ath5k_txq *txq)
> +static int
> +ath5k_init(struct ath5k_softc *sc)
>  {
> -       struct ath5k_softc *sc = hw->priv;
> -       struct ath5k_buf *bf;
> -       unsigned long flags;
> -       int padsize;
> +       struct ath5k_hw *ah = sc->ah;
> +       struct ath_common *common = ath5k_hw_common(ah);
> +       int ret, i;
>
> -       ath5k_debug_dump_skb(sc, skb, "TX  ", 1);
> +       mutex_lock(&sc->lock);
> +
> +       ATH5K_DBG(sc, ATH5K_DEBUG_RESET, "mode %d\n", sc->opmode);
>
>        /*
> -        * The hardware expects the header padded to 4 byte boundaries.
> -        * If this is not the case, we add the padding after the header.
> +        * Stop anything previously setup.  This is safe
> +        * no matter this is the first time through or not.
>         */
> -       padsize = ath5k_add_padding(skb);
> -       if (padsize < 0) {
> -               ATH5K_ERR(sc, "tx hdrlen not %%4: not enough"
> -                         " headroom to pad");
> -               goto drop_packet;
> -       }
> +       ath5k_stop_locked(sc);
>
> -       spin_lock_irqsave(&sc->txbuflock, flags);
> -       if (list_empty(&sc->txbuf)) {
> -               ATH5K_ERR(sc, "no further txbuf available, dropping packet\n");
> -               spin_unlock_irqrestore(&sc->txbuflock, flags);
> -               ieee80211_stop_queue(hw, skb_get_queue_mapping(skb));
> -               goto drop_packet;
> -       }
> -       bf = list_first_entry(&sc->txbuf, struct ath5k_buf, list);
> -       list_del(&bf->list);
> -       sc->txbuf_len--;
> -       if (list_empty(&sc->txbuf))
> -               ieee80211_stop_queues(hw);
> -       spin_unlock_irqrestore(&sc->txbuflock, flags);
> +       /*
> +        * The basic interface to setting the hardware in a good
> +        * state is ``reset''.  On return the hardware is known to
> +        * be powered up and with interrupts disabled.  This must
> +        * be followed by initialization of the appropriate bits
> +        * and then setup of the interrupt mask.
> +        */
> +       sc->curchan = sc->hw->conf.channel;
> +       sc->curband = &sc->sbands[sc->curchan->band];
> +       sc->imask = AR5K_INT_RXOK | AR5K_INT_RXERR | AR5K_INT_RXEOL |
> +               AR5K_INT_RXORN | AR5K_INT_TXDESC | AR5K_INT_TXEOL |
> +               AR5K_INT_FATAL | AR5K_INT_GLOBAL | AR5K_INT_MIB;
>
> -       bf->skb = skb;
> +       ret = ath5k_reset(sc, NULL);
> +       if (ret)
> +               goto done;
>
> -       if (ath5k_txbuf_setup(sc, bf, txq, padsize)) {
> -               bf->skb = NULL;
> -               spin_lock_irqsave(&sc->txbuflock, flags);
> -               list_add_tail(&bf->list, &sc->txbuf);
> -               sc->txbuf_len++;
> -               spin_unlock_irqrestore(&sc->txbuflock, flags);
> -               goto drop_packet;
> +       ath5k_rfkill_hw_start(ah);
> +
> +       /*
> +        * Reset the key cache since some parts do not reset the
> +        * contents on initial power up or resume from suspend.
> +        */
> +       for (i = 0; i < common->keymax; i++)
> +               ath_hw_keyreset(common, (u16) i);
> +
> +       ath5k_hw_set_ack_bitrate_high(ah, true);
> +       ret = 0;
> +done:
> +       mmiowb();
> +       mutex_unlock(&sc->lock);
> +       return ret;
> +}
> +
> +static void stop_tasklets(struct ath5k_softc *sc)
> +{
> +       tasklet_kill(&sc->rxtq);
> +       tasklet_kill(&sc->txtq);
> +       tasklet_kill(&sc->calib);
> +       tasklet_kill(&sc->beacontq);
> +       tasklet_kill(&sc->ani_tasklet);
> +}
> +
> +/*
> + * Stop the device, grabbing the top-level lock to protect
> + * against concurrent entry through ath5k_init (which can happen
> + * if another thread does a system call and the thread doing the
> + * stop is preempted).
> + */
> +static int
> +ath5k_stop_hw(struct ath5k_softc *sc)
> +{
> +       int ret;
> +
> +       mutex_lock(&sc->lock);
> +       ret = ath5k_stop_locked(sc);
> +       if (ret == 0 && !test_bit(ATH_STAT_INVALID, sc->status)) {
> +               /*
> +                * Don't set the card in full sleep mode!
> +                *
> +                * a) When the device is in this state it must be carefully
> +                * woken up or references to registers in the PCI clock
> +                * domain may freeze the bus (and system).  This varies
> +                * by chip and is mostly an issue with newer parts
> +                * (madwifi sources mentioned srev >= 0x78) that go to
> +                * sleep more quickly.
> +                *
> +                * b) On older chips full sleep results a weird behaviour
> +                * during wakeup. I tested various cards with srev < 0x78
> +                * and they don't wake up after module reload, a second
> +                * module reload is needed to bring the card up again.
> +                *
> +                * Until we figure out what's going on don't enable
> +                * full chip reset on any chip (this is what Legacy HAL
> +                * and Sam's HAL do anyway). Instead Perform a full reset
> +                * on the device (same as initial state after attach) and
> +                * leave it idle (keep MAC/BB on warm reset) */
> +               ret = ath5k_hw_on_hold(sc->ah);
> +
> +               ATH5K_DBG(sc, ATH5K_DEBUG_RESET,
> +                               "putting device to sleep\n");
>        }
> -       return NETDEV_TX_OK;
> +       ath5k_txbuf_free_skb(sc, sc->bbuf);
>
> -drop_packet:
> -       dev_kfree_skb_any(skb);
> -       return NETDEV_TX_OK;
> +       mmiowb();
> +       mutex_unlock(&sc->lock);
> +
> +       stop_tasklets(sc);
> +
> +       ath5k_rfkill_hw_stop(sc->ah);
> +
> +       return ret;
>  }
>
>  /*
> @@ -3020,6 +2389,179 @@ static void ath5k_reset_work(struct work_struct *work)
>        mutex_unlock(&sc->lock);
>  }
>
> +static int
> +ath5k_attach(struct pci_dev *pdev, struct ieee80211_hw *hw)
> +{
> +       struct ath5k_softc *sc = hw->priv;
> +       struct ath5k_hw *ah = sc->ah;
> +       struct ath_regulatory *regulatory = ath5k_hw_regulatory(ah);
> +       u8 mac[ETH_ALEN] = {};
> +       int ret;
> +
> +       ATH5K_DBG(sc, ATH5K_DEBUG_ANY, "devid 0x%x\n", pdev->device);
> +
> +       /*
> +        * Check if the MAC has multi-rate retry support.
> +        * We do this by trying to setup a fake extended
> +        * descriptor.  MACs that don't have support will
> +        * return false w/o doing anything.  MACs that do
> +        * support it will return true w/o doing anything.
> +        */
> +       ret = ath5k_hw_setup_mrr_tx_desc(ah, NULL, 0, 0, 0, 0, 0, 0);
> +
> +       if (ret < 0)
> +               goto err;
> +       if (ret > 0)
> +               __set_bit(ATH_STAT_MRRETRY, sc->status);
> +
> +       /*
> +        * Collect the channel list.  The 802.11 layer
> +        * is resposible for filtering this list based
> +        * on settings like the phy mode and regulatory
> +        * domain restrictions.
> +        */
> +       ret = ath5k_setup_bands(hw);
> +       if (ret) {
> +               ATH5K_ERR(sc, "can't get channels\n");
> +               goto err;
> +       }
> +
> +       /* NB: setup here so ath5k_rate_update is happy */
> +       if (test_bit(AR5K_MODE_11A, ah->ah_modes))
> +               ath5k_setcurmode(sc, AR5K_MODE_11A);
> +       else
> +               ath5k_setcurmode(sc, AR5K_MODE_11B);
> +
> +       /*
> +        * Allocate tx+rx descriptors and populate the lists.
> +        */
> +       ret = ath5k_desc_alloc(sc, pdev);
> +       if (ret) {
> +               ATH5K_ERR(sc, "can't allocate descriptors\n");
> +               goto err;
> +       }
> +
> +       /*
> +        * Allocate hardware transmit queues: one queue for
> +        * beacon frames and one data queue for each QoS
> +        * priority.  Note that hw functions handle resetting
> +        * these queues at the needed time.
> +        */
> +       ret = ath5k_beaconq_setup(ah);
> +       if (ret < 0) {
> +               ATH5K_ERR(sc, "can't setup a beacon xmit queue\n");
> +               goto err_desc;
> +       }
> +       sc->bhalq = ret;
> +       sc->cabq = ath5k_txq_setup(sc, AR5K_TX_QUEUE_CAB, 0);
> +       if (IS_ERR(sc->cabq)) {
> +               ATH5K_ERR(sc, "can't setup cab queue\n");
> +               ret = PTR_ERR(sc->cabq);
> +               goto err_bhal;
> +       }
> +
> +       sc->txq = ath5k_txq_setup(sc, AR5K_TX_QUEUE_DATA, AR5K_WME_AC_BK);
> +       if (IS_ERR(sc->txq)) {
> +               ATH5K_ERR(sc, "can't setup xmit queue\n");
> +               ret = PTR_ERR(sc->txq);
> +               goto err_queues;
> +       }
> +
> +       tasklet_init(&sc->rxtq, ath5k_tasklet_rx, (unsigned long)sc);
> +       tasklet_init(&sc->txtq, ath5k_tasklet_tx, (unsigned long)sc);
> +       tasklet_init(&sc->calib, ath5k_tasklet_calibrate, (unsigned long)sc);
> +       tasklet_init(&sc->beacontq, ath5k_tasklet_beacon, (unsigned long)sc);
> +       tasklet_init(&sc->ani_tasklet, ath5k_tasklet_ani, (unsigned long)sc);
> +
> +       INIT_WORK(&sc->reset_work, ath5k_reset_work);
> +
> +       ret = ath5k_eeprom_read_mac(ah, mac);
> +       if (ret) {
> +               ATH5K_ERR(sc, "unable to read address from EEPROM: 0x%04x\n",
> +                       sc->pdev->device);
> +               goto err_queues;
> +       }
> +
> +       SET_IEEE80211_PERM_ADDR(hw, mac);
> +       /* All MAC address bits matter for ACKs */
> +       memcpy(sc->bssidmask, ath_bcast_mac, ETH_ALEN);
> +       ath5k_hw_set_bssid_mask(sc->ah, sc->bssidmask);
> +
> +       regulatory->current_rd = ah->ah_capabilities.cap_eeprom.ee_regdomain;
> +       ret = ath_regd_init(regulatory, hw->wiphy, ath5k_reg_notifier);
> +       if (ret) {
> +               ATH5K_ERR(sc, "can't initialize regulatory system\n");
> +               goto err_queues;
> +       }
> +
> +       ret = ieee80211_register_hw(hw);
> +       if (ret) {
> +               ATH5K_ERR(sc, "can't register ieee80211 hw\n");
> +               goto err_queues;
> +       }
> +
> +       if (!ath_is_world_regd(regulatory))
> +               regulatory_hint(hw->wiphy, regulatory->alpha2);
> +
> +       ath5k_init_leds(sc);
> +
> +       ath5k_sysfs_register(sc);
> +
> +       return 0;
> +err_queues:
> +       ath5k_txq_release(sc);
> +err_bhal:
> +       ath5k_hw_release_tx_queue(ah, sc->bhalq);
> +err_desc:
> +       ath5k_desc_free(sc, pdev);
> +err:
> +       return ret;
> +}
> +
> +static void
> +ath5k_detach(struct pci_dev *pdev, struct ieee80211_hw *hw)
> +{
> +       struct ath5k_softc *sc = hw->priv;
> +
> +       /*
> +        * NB: the order of these is important:
> +        * o call the 802.11 layer before detaching ath5k_hw to
> +        *   ensure callbacks into the driver to delete global
> +        *   key cache entries can be handled
> +        * o reclaim the tx queue data structures after calling
> +        *   the 802.11 layer as we'll get called back to reclaim
> +        *   node state and potentially want to use them
> +        * o to cleanup the tx queues the hal is called, so detach
> +        *   it last
> +        * XXX: ??? detach ath5k_hw ???
> +        * Other than that, it's straightforward...
> +        */
> +       ieee80211_unregister_hw(hw);
> +       ath5k_desc_free(sc, pdev);
> +       ath5k_txq_release(sc);
> +       ath5k_hw_release_tx_queue(sc->ah, sc->bhalq);
> +       ath5k_unregister_leds(sc);
> +
> +       ath5k_sysfs_unregister(sc);
> +       /*
> +        * NB: can't reclaim these until after ieee80211_ifdetach
> +        * returns because we'll get called back to reclaim node
> +        * state and potentially want to use them.
> +        */
> +}
> +
> +/********************\
> +* Mac80211 functions *
> +\********************/
> +
> +static int
> +ath5k_tx(struct ieee80211_hw *hw, struct sk_buff *skb)
> +{
> +       struct ath5k_softc *sc = hw->priv;
> +
> +       return ath5k_tx_queue(hw, skb, sc->txq);
> +}
> +
>  static int ath5k_start(struct ieee80211_hw *hw)
>  {
>        return ath5k_init(hw->priv);
> @@ -3398,43 +2940,6 @@ ath5k_reset_tsf(struct ieee80211_hw *hw)
>                ath5k_hw_reset_tsf(sc->ah);
>  }
>
> -/*
> - * Updates the beacon that is sent by ath5k_beacon_send.  For adhoc,
> - * this is called only once at config_bss time, for AP we do it every
> - * SWBA interrupt so that the TIM will reflect buffered frames.
> - *
> - * Called with the beacon lock.
> - */
> -static int
> -ath5k_beacon_update(struct ieee80211_hw *hw, struct ieee80211_vif *vif)
> -{
> -       int ret;
> -       struct ath5k_softc *sc = hw->priv;
> -       struct sk_buff *skb;
> -
> -       if (WARN_ON(!vif)) {
> -               ret = -EINVAL;
> -               goto out;
> -       }
> -
> -       skb = ieee80211_beacon_get(hw, vif);
> -
> -       if (!skb) {
> -               ret = -ENOMEM;
> -               goto out;
> -       }
> -
> -       ath5k_debug_dump_skb(sc, skb, "BC  ", 1);
> -
> -       ath5k_txbuf_free_skb(sc, sc->bbuf);
> -       sc->bbuf->skb = skb;
> -       ret = ath5k_beacon_setup(sc, sc->bbuf);
> -       if (ret)
> -               sc->bbuf->skb = NULL;
> -out:
> -       return ret;
> -}
> -
>  static void
>  set_beacon_filter(struct ieee80211_hw *hw, bool enable)
>  {
> @@ -3540,3 +3045,364 @@ static void ath5k_set_coverage_class(struct ieee80211_hw *hw, u8 coverage_class)
>        ath5k_hw_set_coverage_class(sc->ah, coverage_class);
>        mutex_unlock(&sc->lock);
>  }
> +
> +static const struct ieee80211_ops ath5k_hw_ops = {
> +       .tx             = ath5k_tx,
> +       .start          = ath5k_start,
> +       .stop           = ath5k_stop,
> +       .add_interface  = ath5k_add_interface,
> +       .remove_interface = ath5k_remove_interface,
> +       .config         = ath5k_config,
> +       .prepare_multicast = ath5k_prepare_multicast,
> +       .configure_filter = ath5k_configure_filter,
> +       .set_key        = ath5k_set_key,
> +       .get_stats      = ath5k_get_stats,
> +       .get_survey     = ath5k_get_survey,
> +       .conf_tx        = NULL,
> +       .get_tsf        = ath5k_get_tsf,
> +       .set_tsf        = ath5k_set_tsf,
> +       .reset_tsf      = ath5k_reset_tsf,
> +       .bss_info_changed = ath5k_bss_info_changed,
> +       .sw_scan_start  = ath5k_sw_scan_start,
> +       .sw_scan_complete = ath5k_sw_scan_complete,
> +       .set_coverage_class = ath5k_set_coverage_class,
> +};
> +
> +/********************\
> +* PCI Initialization *
> +\********************/
> +
> +static int __devinit
> +ath5k_pci_probe(struct pci_dev *pdev,
> +               const struct pci_device_id *id)
> +{
> +       void __iomem *mem;
> +       struct ath5k_softc *sc;
> +       struct ath_common *common;
> +       struct ieee80211_hw *hw;
> +       int ret;
> +       u8 csz;
> +
> +       /*
> +        * L0s needs to be disabled on all ath5k cards.
> +        *
> +        * For distributions shipping with CONFIG_PCIEASPM (this will be enabled
> +        * by default in the future in 2.6.36) this will also mean both L1 and
> +        * L0s will be disabled when a pre 1.1 PCIe device is detected. We do
> +        * know L1 works correctly even for all ath5k pre 1.1 PCIe devices
> +        * though but cannot currently undue the effect of a blacklist, for
> +        * details you can read pcie_aspm_sanity_check() and see how it adjusts
> +        * the device link capability.
> +        *
> +        * It may be possible in the future to implement some PCI API to allow
> +        * drivers to override blacklists for pre 1.1 PCIe but for now it is
> +        * best to accept that both L0s and L1 will be disabled completely for
> +        * distributions shipping with CONFIG_PCIEASPM rather than having this
> +        * issue present. Motivation for adding this new API will be to help
> +        * with power consumption for some of these devices.
> +        */
> +       pci_disable_link_state(pdev, PCIE_LINK_STATE_L0S);
> +
> +       ret = pci_enable_device(pdev);
> +       if (ret) {
> +               dev_err(&pdev->dev, "can't enable device\n");
> +               goto err;
> +       }
> +
> +       /* XXX 32-bit addressing only */
> +       ret = pci_set_dma_mask(pdev, DMA_BIT_MASK(32));
> +       if (ret) {
> +               dev_err(&pdev->dev, "32-bit DMA not available\n");
> +               goto err_dis;
> +       }
> +
> +       /*
> +        * Cache line size is used to size and align various
> +        * structures used to communicate with the hardware.
> +        */
> +       pci_read_config_byte(pdev, PCI_CACHE_LINE_SIZE, &csz);
> +       if (csz == 0) {
> +               /*
> +                * Linux 2.4.18 (at least) writes the cache line size
> +                * register as a 16-bit wide register which is wrong.
> +                * We must have this setup properly for rx buffer
> +                * DMA to work so force a reasonable value here if it
> +                * comes up zero.
> +                */
> +               csz = L1_CACHE_BYTES >> 2;
> +               pci_write_config_byte(pdev, PCI_CACHE_LINE_SIZE, csz);
> +       }
> +       /*
> +        * The default setting of latency timer yields poor results,
> +        * set it to the value used by other systems.  It may be worth
> +        * tweaking this setting more.
> +        */
> +       pci_write_config_byte(pdev, PCI_LATENCY_TIMER, 0xa8);
> +
> +       /* Enable bus mastering */
> +       pci_set_master(pdev);
> +
> +       /*
> +        * Disable the RETRY_TIMEOUT register (0x41) to keep
> +        * PCI Tx retries from interfering with C3 CPU state.
> +        */
> +       pci_write_config_byte(pdev, 0x41, 0);
> +
> +       ret = pci_request_region(pdev, 0, "ath5k");
> +       if (ret) {
> +               dev_err(&pdev->dev, "cannot reserve PCI memory region\n");
> +               goto err_dis;
> +       }
> +
> +       mem = pci_iomap(pdev, 0, 0);
> +       if (!mem) {
> +               dev_err(&pdev->dev, "cannot remap PCI memory region\n") ;
> +               ret = -EIO;
> +               goto err_reg;
> +       }
> +
> +       /*
> +        * Allocate hw (mac80211 main struct)
> +        * and hw->priv (driver private data)
> +        */
> +       hw = ieee80211_alloc_hw(sizeof(*sc), &ath5k_hw_ops);
> +       if (hw == NULL) {
> +               dev_err(&pdev->dev, "cannot allocate ieee80211_hw\n");
> +               ret = -ENOMEM;
> +               goto err_map;
> +       }
> +
> +       dev_info(&pdev->dev, "registered as '%s'\n", wiphy_name(hw->wiphy));
> +
> +       /* Initialize driver private data */
> +       SET_IEEE80211_DEV(hw, &pdev->dev);
> +       hw->flags = IEEE80211_HW_RX_INCLUDES_FCS |
> +                   IEEE80211_HW_HOST_BROADCAST_PS_BUFFERING |
> +                   IEEE80211_HW_SIGNAL_DBM;
> +
> +       hw->wiphy->interface_modes =
> +               BIT(NL80211_IFTYPE_AP) |
> +               BIT(NL80211_IFTYPE_STATION) |
> +               BIT(NL80211_IFTYPE_ADHOC) |
> +               BIT(NL80211_IFTYPE_MESH_POINT);
> +
> +       hw->extra_tx_headroom = 2;
> +       hw->channel_change_time = 5000;
> +       sc = hw->priv;
> +       sc->hw = hw;
> +       sc->pdev = pdev;
> +
> +       ath5k_debug_init_device(sc);
> +
> +       /*
> +        * Mark the device as detached to avoid processing
> +        * interrupts until setup is complete.
> +        */
> +       __set_bit(ATH_STAT_INVALID, sc->status);
> +
> +       sc->iobase = mem; /* So we can unmap it on detach */
> +       sc->opmode = NL80211_IFTYPE_STATION;
> +       sc->bintval = 1000;
> +       mutex_init(&sc->lock);
> +       spin_lock_init(&sc->rxbuflock);
> +       spin_lock_init(&sc->txbuflock);
> +       spin_lock_init(&sc->block);
> +
> +       /* Set private data */
> +       pci_set_drvdata(pdev, sc);
> +
> +       /* Setup interrupt handler */
> +       ret = request_irq(pdev->irq, ath5k_intr, IRQF_SHARED, "ath", sc);
> +       if (ret) {
> +               ATH5K_ERR(sc, "request_irq failed\n");
> +               goto err_free;
> +       }
> +
> +       /* If we passed the test, malloc an ath5k_hw struct */
> +       sc->ah = kzalloc(sizeof(struct ath5k_hw), GFP_KERNEL);
> +       if (!sc->ah) {
> +               ret = -ENOMEM;
> +               ATH5K_ERR(sc, "out of memory\n");
> +               goto err_irq;
> +       }
> +
> +       sc->ah->ah_sc = sc;
> +       sc->ah->ah_iobase = sc->iobase;
> +       common = ath5k_hw_common(sc->ah);
> +       common->ops = &ath5k_common_ops;
> +       common->ah = sc->ah;
> +       common->hw = hw;
> +       common->cachelsz = csz << 2; /* convert to bytes */
> +
> +       /* Initialize device */
> +       ret = ath5k_hw_attach(sc);
> +       if (ret) {
> +               goto err_free_ah;
> +       }
> +
> +       /* set up multi-rate retry capabilities */
> +       if (sc->ah->ah_version == AR5K_AR5212) {
> +               hw->max_rates = 4;
> +               hw->max_rate_tries = 11;
> +       }
> +
> +       /* Finish private driver data initialization */
> +       ret = ath5k_attach(pdev, hw);
> +       if (ret)
> +               goto err_ah;
> +
> +       ATH5K_INFO(sc, "Atheros AR%s chip found (MAC: 0x%x, PHY: 0x%x)\n",
> +                       ath5k_chip_name(AR5K_VERSION_MAC, sc->ah->ah_mac_srev),
> +                                       sc->ah->ah_mac_srev,
> +                                       sc->ah->ah_phy_revision);
> +
> +       if (!sc->ah->ah_single_chip) {
> +               /* Single chip radio (!RF5111) */
> +               if (sc->ah->ah_radio_5ghz_revision &&
> +                       !sc->ah->ah_radio_2ghz_revision) {
> +                       /* No 5GHz support -> report 2GHz radio */
> +                       if (!test_bit(AR5K_MODE_11A,
> +                               sc->ah->ah_capabilities.cap_mode)) {
> +                               ATH5K_INFO(sc, "RF%s 2GHz radio found (0x%x)\n",
> +                                       ath5k_chip_name(AR5K_VERSION_RAD,
> +                                               sc->ah->ah_radio_5ghz_revision),
> +                                               sc->ah->ah_radio_5ghz_revision);
> +                       /* No 2GHz support (5110 and some
> +                        * 5Ghz only cards) -> report 5Ghz radio */
> +                       } else if (!test_bit(AR5K_MODE_11B,
> +                               sc->ah->ah_capabilities.cap_mode)) {
> +                               ATH5K_INFO(sc, "RF%s 5GHz radio found (0x%x)\n",
> +                                       ath5k_chip_name(AR5K_VERSION_RAD,
> +                                               sc->ah->ah_radio_5ghz_revision),
> +                                               sc->ah->ah_radio_5ghz_revision);
> +                       /* Multiband radio */
> +                       } else {
> +                               ATH5K_INFO(sc, "RF%s multiband radio found"
> +                                       " (0x%x)\n",
> +                                       ath5k_chip_name(AR5K_VERSION_RAD,
> +                                               sc->ah->ah_radio_5ghz_revision),
> +                                               sc->ah->ah_radio_5ghz_revision);
> +                       }
> +               }
> +               /* Multi chip radio (RF5111 - RF2111) ->
> +                * report both 2GHz/5GHz radios */
> +               else if (sc->ah->ah_radio_5ghz_revision &&
> +                               sc->ah->ah_radio_2ghz_revision){
> +                       ATH5K_INFO(sc, "RF%s 5GHz radio found (0x%x)\n",
> +                               ath5k_chip_name(AR5K_VERSION_RAD,
> +                                       sc->ah->ah_radio_5ghz_revision),
> +                                       sc->ah->ah_radio_5ghz_revision);
> +                       ATH5K_INFO(sc, "RF%s 2GHz radio found (0x%x)\n",
> +                               ath5k_chip_name(AR5K_VERSION_RAD,
> +                                       sc->ah->ah_radio_2ghz_revision),
> +                                       sc->ah->ah_radio_2ghz_revision);
> +               }
> +       }
> +
> +
> +       /* ready to process interrupts */
> +       __clear_bit(ATH_STAT_INVALID, sc->status);
> +
> +       return 0;
> +err_ah:
> +       ath5k_hw_detach(sc->ah);
> +err_free_ah:
> +       kfree(sc->ah);
> +err_irq:
> +       free_irq(pdev->irq, sc);
> +err_free:
> +       ieee80211_free_hw(hw);
> +err_map:
> +       pci_iounmap(pdev, mem);
> +err_reg:
> +       pci_release_region(pdev, 0);
> +err_dis:
> +       pci_disable_device(pdev);
> +err:
> +       return ret;
> +}
> +
> +static void __devexit
> +ath5k_pci_remove(struct pci_dev *pdev)
> +{
> +       struct ath5k_softc *sc = pci_get_drvdata(pdev);
> +
> +       ath5k_debug_finish_device(sc);
> +       ath5k_detach(pdev, sc->hw);
> +       ath5k_hw_detach(sc->ah);
> +       kfree(sc->ah);
> +       free_irq(pdev->irq, sc);
> +       pci_iounmap(pdev, sc->iobase);
> +       pci_release_region(pdev, 0);
> +       pci_disable_device(pdev);
> +       ieee80211_free_hw(sc->hw);
> +}
> +
> +#ifdef CONFIG_PM_SLEEP
> +static int ath5k_pci_suspend(struct device *dev)
> +{
> +       struct ath5k_softc *sc = pci_get_drvdata(to_pci_dev(dev));
> +
> +       ath5k_led_off(sc);
> +       return 0;
> +}
> +
> +static int ath5k_pci_resume(struct device *dev)
> +{
> +       struct pci_dev *pdev = to_pci_dev(dev);
> +       struct ath5k_softc *sc = pci_get_drvdata(pdev);
> +
> +       /*
> +        * Suspend/Resume resets the PCI configuration space, so we have to
> +        * re-disable the RETRY_TIMEOUT register (0x41) to keep
> +        * PCI Tx retries from interfering with C3 CPU state
> +        */
> +       pci_write_config_byte(pdev, 0x41, 0);
> +
> +       ath5k_led_enable(sc);
> +       return 0;
> +}
> +
> +static SIMPLE_DEV_PM_OPS(ath5k_pm_ops, ath5k_pci_suspend, ath5k_pci_resume);
> +#define ATH5K_PM_OPS   (&ath5k_pm_ops)
> +#else
> +#define ATH5K_PM_OPS   NULL
> +#endif /* CONFIG_PM_SLEEP */
> +
> +static struct pci_driver ath5k_pci_driver = {
> +       .name           = KBUILD_MODNAME,
> +       .id_table       = ath5k_pci_id_table,
> +       .probe          = ath5k_pci_probe,
> +       .remove         = __devexit_p(ath5k_pci_remove),
> +       .driver.pm      = ATH5K_PM_OPS,
> +};
> +
> +/*
> + * Module init/exit functions
> + */
> +static int __init
> +init_ath5k_pci(void)
> +{
> +       int ret;
> +
> +       ath5k_debug_init();
> +
> +       ret = pci_register_driver(&ath5k_pci_driver);
> +       if (ret) {
> +               printk(KERN_ERR "ath5k_pci: can't register pci driver\n");
> +               return ret;
> +       }
> +
> +       return 0;
> +}
> +
> +static void __exit
> +exit_ath5k_pci(void)
> +{
> +       pci_unregister_driver(&ath5k_pci_driver);
> +
> +       ath5k_debug_finish();
> +}
> +
> +module_init(init_ath5k_pci);
> +module_exit(exit_ath5k_pci);
>


>
> Thanks,
>
> Jonathan
>
>>> > [   54.501954] skb_under_panic: text:c04e27f2 len:110 put:14 he0
>>> > [   54.507979] ------------[ cut here ]------------
>>> > [   54.511864] kernel BUG at net/core/skbuff.c:146!
>>> > [   54.511864] invalid opcode: 0000 [#1] SMP
>>> > [   54.511864] last sysfs file:
>>> > /sys/devices/pci0000:00/0000:00:0c.0/device [   54.511864] Modules
>>> > linked in: ath5k ath mac80211 led_class nfs lockd nfs_ac] [   54.511864]
>>> > [   54.511864] Pid: 0, comm: swapper Not tainted 2.6.36-rc6-wl-wl+ #3 /
>>> > [   54.511864] EIP: 0060:[<c04c2b90>] EFLAGS: 00010286 CPU: 0
>>> > [   54.511864] EIP is at skb_push+0x80/0x90
>>> > [   54.511864] EAX: 00000087 EBX: c04e27f2 ECX: c079daf4 EDX: 00000000
>>> > [   54.511864] ESI: cfd62cc0 EDI: cf468910 EBP: c0791d64 ESP: c0791d3c
>>> > [   54.511864]  DS: 007b ES: 007b FS: 00d8 GS: 00e0 SS: 0068
>>> > [   54.511864] Process swapper (pid: 0, ti=c0790000 task=c07976a0
>>> > task.ti=c0790) [   54.511864] Stack:
>>> > [   54.511864]  c0754518 c04e27f2 0000006e 0000000e cfee8a00 cfee89f2
>>> > cfee8a60 0 [   54.511864] <0> ce56c000 cfd62cc0 c0791d78 c04e27f2
>>> > cfd62cc0 cfd62cc0 cf46890 [   54.511864] <0> c04cc866 00000040 cf4682c0
>>> > cf4682c0 cf4682c0 c0791df8 d0c06a0 [   54.511864] Call Trace:
>>> > [   54.511864]  [<c04e27f2>] ? skb_defer_rx_timestamp+0x22/0x80
>>> > [   54.511864]  [<c04e27f2>] ? skb_defer_rx_timestamp+0x22/0x80
>>> > [   54.511864]  [<c04cc866>] ? netif_receive_skb+0x26/0x90
>>> > [   54.511864]  [<d0c06a83>] ? ieee80211_rx+0x613/0x800 [mac80211]
>>> > [   54.511864]  [<c04c33dc>] ? __alloc_skb+0x5c/0x110
>>> > [   54.511864]  [<d0c8badf>] ? ath5k_rx_skb_alloc+0x7f/0x160 [ath5k]
>>> > [   54.511864]  [<d0c8cfa5>] ? ath5k_tasklet_rx+0x315/0x860 [ath5k]
>>> > [   54.511864]  [<c0108538>] ? sched_clock+0x8/0x10
>>> > [   54.511864]  [<c016d885>] ? sched_clock_local+0xa5/0x180
>>> > [   54.511864]  [<d0c818c0>] ? ath5k_hw_get_isr+0xa0/0x380 [ath5k]
>>> > [   54.511864]  [<d0c8ca9e>] ? ath5k_intr+0x2ae/0x4a0 [ath5k]
>>> > [   54.511864]  [<c014fc17>] ? tasklet_action+0xa7/0xb0
>>> > [   54.511864]  [<c015095c>] ? __do_softirq+0x9c/0x1b0
>>> > [   54.511864]  [<c012c868>] ? default_spin_lock_flags+0x8/0x10
>>> > [   54.511864]  [<c05b927f>] ? _raw_spin_lock_irqsave+0x2f/0x50
>>> > [   54.511864]  [<c0150ab5>] ? do_softirq+0x45/0x50
>>> > [   54.511864]  [<c0150c25>] ? irq_exit+0x65/0x70
>>> > [   54.511864]  [<c05c0055>] ? do_IRQ+0x55/0xc0
>>> > [   54.511864]  [<c017112f>] ? ktime_get+0x6f/0x110
>>> > [   54.511864]  [<c01035b0>] ? common_interrupt+0x30/0x40
>>> > [   54.511864]  [<c012bcaa>] ? native_safe_halt+0xa/0x10
>>> > [   54.511864]  [<c0109f53>] ? default_idle+0x53/0xb0
>>> > [   54.511864]  [<c0101e4a>] ? cpu_idle+0x8a/0xf0
>>> > [   54.511864]  [<c05a2ccd>] ? rest_init+0x5d/0x70
>>> > [   54.511864]  [<c07d297b>] ? start_kernel+0x357/0x35d
>>> > [   54.511864]  [<c07d2450>] ? unknown_bootoption+0x0/0x19e
>>> > [   54.511864]  [<c07d20de>] ? i386_start_kernel+0xde/0xe6
>>> > [   54.511864] Code: 00 00 89 4c 24 14 8b 88 ac 00 00 00 89 54 24 0c 89
>>> > 4c 24 1 [   54.511864] EIP: [<c04c2b90>] skb_push+0x80/0x90 SS:ESP
>>> > 0068:c0791d3c [   54.511864] ---[ end trace ccaff68ea5123ae2 ]---
>>> > [   54.513037] Kernel panic - not syncing: Fatal exception in interrupt
>>> > [   54.520124] Pid: 0, comm: swapper Tainted: G      D
>>> > 2.6.36-rc6-wl-wl+ #3 [   54.521277] Call Trace:
>>> > [   54.524656]  [<c05b6936>] ? printk+0x1d/0x1f
>>> > [   54.529491]  [<c05b6817>] panic+0x5c/0x15e
>>> > [   54.533818]  [<c05babdd>] oops_end+0xcd/0xd0
>>> > [   54.538655]  [<c0105ce4>] die+0x54/0x80
>>> > [   54.542199]  [<c05ba286>] do_trap+0x96/0xc0
>>> > [   54.546781]  [<c0103d10>] ? do_invalid_op+0x0/0xa0
>>> > [   54.549181]  [<c0103d9b>] do_invalid_op+0x8b/0xa0
>>> > [   54.555342]  [<c04c2b90>] ? skb_push+0x80/0x90
>>> > [   54.556724]  [<c014b041>] ? vprintk+0x191/0x3f0
>>> > [   54.562339]  [<c04e27f2>] ? skb_defer_rx_timestamp+0x22/0x80
>>> > [   54.567341]  [<c05ba017>] error_code+0x67/0x70
>>> > [   54.568699]  [<c04e27f2>] ? skb_defer_rx_timestamp+0x22/0x80
>>> > [   54.573704]  [<c04c2b90>] ? skb_push+0x80/0x90
>>> > [   54.579064]  [<c04e27f2>] ? skb_defer_rx_timestamp+0x22/0x80
>>> > [   54.584082]  [<c04e27f2>] skb_defer_rx_timestamp+0x22/0x80
>>> > [   54.588612]  [<c04cc866>] netif_receive_skb+0x26/0x90
>>> > [   54.595838]  [<d0c06a83>] ieee80211_rx+0x613/0x800 [mac80211]
>>> > [   54.597099]  [<c04c33dc>] ? __alloc_skb+0x5c/0x110
>>> > [   54.603523]  [<d0c8badf>] ? ath5k_rx_skb_alloc+0x7f/0x160 [ath5k]
>>> > [   54.605849]  [<d0c8cfa5>] ath5k_tasklet_rx+0x315/0x860 [ath5k]
>>> > [   54.611392]  [<c0108538>] ? sched_clock+0x8/0x10
>>> > [   54.613284]  [<c016d885>] ? sched_clock_local+0xa5/0x180
>>> > [   54.617265]  [<d0c818c0>] ? ath5k_hw_get_isr+0xa0/0x380 [ath5k]
>>> > [   54.623076]  [<d0c8ca9e>] ? ath5k_intr+0x2ae/0x4a0 [ath5k]
>>> > [   54.627564]  [<c014fc17>] tasklet_action+0xa7/0xb0
>>> > [   54.629963]  [<c015095c>] __do_softirq+0x9c/0x1b0
>>> > [   54.636107]  [<c012c868>] ? default_spin_lock_flags+0x8/0x10
>>> > [   54.637124]  [<c05b927f>] ? _raw_spin_lock_irqsave+0x2f/0x50
>>> > [   54.642137]  [<c0150ab5>] do_softirq+0x45/0x50
>>> > [   54.647499]  [<c0150c25>] irq_exit+0x65/0x70
>>> > [   54.652340]  [<c05c0055>] do_IRQ+0x55/0xc0
>>> > [   54.652664]  [<c017112f>] ? ktime_get+0x6f/0x110
>>> > [   54.658547]  [<c01035b0>] common_interrupt+0x30/0x40
>>> > [   54.661471]  [<c012bcaa>] ? native_safe_halt+0xa/0x10
>>> > [   54.664668]  [<c0109f53>] default_idle+0x53/0xb0
>>> > [   54.670559]  [<c0101e4a>] cpu_idle+0x8a/0xf0
>>> > [   54.675405]  [<c05a2ccd>] rest_init+0x5d/0x70
>>> > [   54.680506]  [<c07d297b>] start_kernel+0x357/0x35d
>>> > [   54.682907]  [<c07d2450>] ? unknown_bootoption+0x0/0x19e
>>> > [   54.686869]  [<c07d20de>] i386_start_kernel+0xde/0xe6
>>> >
>>> > Branch information:
>>> > commit 25de059bdad7ce916df6f2cfdfc1c2d2d72abf11
>>> > Merge: 412d5af 46bf695
>>> > Author: John W. Linville <linville@tuxdriver.com>
>>> > Date:   Tue Oct 5 15:09:33 2010 -0400
>>> >
>>> > Thanks,
>>> >
>>> > Jonathan Guerin
>>>
>>> _______________________________________________
>>> ath5k-devel mailing list
>>> ath5k-devel@lists.ath5k.org
>>> https://lists.ath5k.org/mailman/listinfo/ath5k-devel
>>
>

^ permalink raw reply

* [U-Boot] [PATCH v2] ppc: Conditionally compile bat_rw.c
From: Peter Tyser @ 2010-10-08  3:32 UTC (permalink / raw)
  To: u-boot
In-Reply-To: <1285873874-26792-1-git-send-email-ptyser@xes-inc.com>

Only a few PPC boards actually use the common BAT manipulation
functions, so only compile it for them.

Signed-off-by: Peter Tyser <ptyser@xes-inc.com>
---
Changes since v1:
- Rebased on current top of tree

 arch/powerpc/lib/Makefile     |    2 +-
 include/configs/Alaska8220.h  |    1 +
 include/configs/MPC8610HPCD.h |    1 +
 include/configs/MPC8641HPCN.h |    1 +
 include/configs/XPEDITE5170.h |    1 +
 include/configs/Yukon8220.h   |    1 +
 include/configs/sbc8641d.h    |    1 +
 7 files changed, 7 insertions(+), 1 deletions(-)

diff --git a/arch/powerpc/lib/Makefile b/arch/powerpc/lib/Makefile
index 2065b6d..cec7666 100644
--- a/arch/powerpc/lib/Makefile
+++ b/arch/powerpc/lib/Makefile
@@ -30,7 +30,7 @@ SOBJS-y	+= ppcstring.o
 SOBJS-y	+= ticks.o
 SOBJS-y	+= reloc.o
 
-COBJS-y	+= bat_rw.o
+COBJS-$(CONFIG_BAT_RW) += bat_rw.o
 COBJS-y	+= board.o
 COBJS-y	+= bootm.o
 COBJS-$(CONFIG_BOOTCOUNT_LIMIT) += bootcount.o
diff --git a/include/configs/Alaska8220.h b/include/configs/Alaska8220.h
index 576aa74..85b68be 100644
--- a/include/configs/Alaska8220.h
+++ b/include/configs/Alaska8220.h
@@ -31,6 +31,7 @@
 #define CONFIG_MPC8220		1
 #define CONFIG_ALASKA8220	1	/* ... on Alaska board	*/
 
+#define CONFIG_BAT_RW		1	/* Use common BAT rw code */
 #define CONFIG_HIGH_BATS	1	/* High BATs supported */
 
 /* Input clock running at 30Mhz, read Hid1 for the CPU multiplier to
diff --git a/include/configs/MPC8610HPCD.h b/include/configs/MPC8610HPCD.h
index 645d947..2b7b8b5 100644
--- a/include/configs/MPC8610HPCD.h
+++ b/include/configs/MPC8610HPCD.h
@@ -53,6 +53,7 @@
 #define CONFIG_ENV_OVERWRITE
 #define CONFIG_INTERRUPTS		/* enable pci, srio, ddr interrupts */
 
+#define CONFIG_BAT_RW		1	/* Use common BAT rw code */
 #define CONFIG_HIGH_BATS	1	/* High BATs supported & enabled */
 #define CONFIG_ALTIVEC		1
 
diff --git a/include/configs/MPC8641HPCN.h b/include/configs/MPC8641HPCN.h
index 3b80d14..d92b12d 100644
--- a/include/configs/MPC8641HPCN.h
+++ b/include/configs/MPC8641HPCN.h
@@ -68,6 +68,7 @@
 #define CONFIG_TSEC_ENET		/* tsec ethernet support */
 #define CONFIG_ENV_OVERWRITE
 
+#define CONFIG_BAT_RW		1	/* Use common BAT rw code */
 #define CONFIG_HIGH_BATS	1	/* High BATs supported and enabled */
 #define CONFIG_SYS_NUM_ADDR_MAP 8	/* Number of addr map slots = 8 dbats */
 
diff --git a/include/configs/XPEDITE5170.h b/include/configs/XPEDITE5170.h
index 8770a8d..306baed 100644
--- a/include/configs/XPEDITE5170.h
+++ b/include/configs/XPEDITE5170.h
@@ -36,6 +36,7 @@
 #define CONFIG_SYS_BOARD_NAME	"XPedite5170"
 #define CONFIG_LINUX_RESET_VEC	0x100	/* Reset vector used by Linux */
 #define CONFIG_BOARD_EARLY_INIT_R	/* Call board_pre_init */
+#define CONFIG_BAT_RW		1	/* Use common BAT rw code */
 #define CONFIG_HIGH_BATS	1	/* High BATs supported and enabled */
 #define CONFIG_ALTIVEC		1
 
diff --git a/include/configs/Yukon8220.h b/include/configs/Yukon8220.h
index c439068..8ec6c84 100644
--- a/include/configs/Yukon8220.h
+++ b/include/configs/Yukon8220.h
@@ -31,6 +31,7 @@
 #define CONFIG_MPC8220		1
 #define CONFIG_YUKON8220	1	/* ... on Yukon board	*/
 
+#define CONFIG_BAT_RW		1	/* Use common BAT rw code */
 #define CONFIG_HIGH_BATS	1	/* High BATs supported */
 
 /* Input clock running at 30Mhz, read Hid1 for the CPU multiplier to
diff --git a/include/configs/sbc8641d.h b/include/configs/sbc8641d.h
index a7831c0..490d4f5 100644
--- a/include/configs/sbc8641d.h
+++ b/include/configs/sbc8641d.h
@@ -64,6 +64,7 @@
 #define CONFIG_TSEC_ENET		/* tsec ethernet support */
 #define CONFIG_ENV_OVERWRITE
 
+#define CONFIG_BAT_RW		1	/* Use common BAT rw code */
 #define CONFIG_HIGH_BATS	1	/* High BATs supported and enabled */
 
 #undef CONFIG_SPD_EEPROM		/* Do not use SPD EEPROM for DDR setup*/
-- 
1.7.1.13.gcfb88

^ permalink raw reply related

* Re: [PATCH] Prio_heap: heap_remove(), heap_maximum(), heap_replace() and heap_cherrypick()
From: Lai Jiangshan @ 2010-10-08  3:36 UTC (permalink / raw)
  To: Mathieu Desnoyers
  Cc: Steven Rostedt, LKML, Linus Torvalds, Andrew Morton,
	Peter Zijlstra, Ingo Molnar, Frederic Weisbecker, Thomas Gleixner,
	Christoph Hellwig, Li Zefan, Johannes Berg, Masami Hiramatsu,
	Arnaldo Carvalho de Melo, Tom Zanussi, KOSAKI Motohiro,
	Andi Kleen, Paul E. McKenney, Paul Menage, David Rientjes,
	Nick Piggin, Balbir Singh, Cedric Le Goater, Eric W. Biederman
In-Reply-To: <20101007190322.GA27054@Krystal>

On 10/08/2010 03:03 AM, Mathieu Desnoyers wrote:
> These added interfaces lets prio_heap users lookup the top of heap item without
> performing any insertion, perform removal of the topmost heap entry, and also
> replacement of topmost heap entry. This is useful if one need to use the result
> of the lookup to determine if the current maximum should simply be removed or if
> it should be replaced.

> 
> This is used by the Generic Ring Buffer to perform timestamp-based fusion-merge
> of per-cpu buffer records into a single stream.
Good!

> 
> Signed-off-by: Mathieu Desnoyers <mathieu.desnoyers@efficios.com>
> Acked-by: Balbir Singh <balbir@in.ibm.com>
> Cc: Paul Menage <menage@google.com>
> Cc: David Rientjes <rientjes@google.com>
> Cc: Cedric Le Goater <clg@fr.ibm.com>
> Cc: "Eric W. Biederman" <ebiederm@xmission.com>
> Cc: Andrew Morton <akpm@linux-foundation.org>
> Cc: Linus Torvalds <torvalds@linux-foundation.org>
> ---
>  include/linux/prio_heap.h |   44 ++++++++++++++++++++++
>  lib/prio_heap.c           |   91 ++++++++++++++++++++++++++++++++++++----------
>  2 files changed, 116 insertions(+), 19 deletions(-)

Comments in the top of prio_heap.h and prio_heap.c.
/*
 * Simple insertion-only static-sized priority heap containing
 * pointers, based on CLR, chapter 7
 */

remove it?

> 
> Index: linux.trees.git/include/linux/prio_heap.h
> ===================================================================
> --- linux.trees.git.orig/include/linux/prio_heap.h	2010-07-06 14:25:29.000000000 -0400
> +++ linux.trees.git/include/linux/prio_heap.h	2010-07-07 10:04:33.000000000 -0400
> @@ -23,6 +23,18 @@ struct ptr_heap {
>  };
>  
>  /**
> + * heap_maximum - return the largest element in the heap
> + * @heap: the heap to be operated on
> + *
> + * Returns the largest element in the heap, without performing any modification
> + * to the heap structure. Returns NULL if the heap is empty.
> + */
> +static inline void *heap_maximum(const struct ptr_heap *heap)
> +{
> +	return heap->size ? heap->ptrs[0] : NULL;
> +}
> +
> +/**
>   * heap_init - initialize an empty heap with a given memory size
>   * @heap: the heap structure to be initialized
>   * @size: amount of memory to use in bytes
> @@ -53,6 +65,38 @@ void heap_free(struct ptr_heap *heap);
>   */
>  extern void *heap_insert(struct ptr_heap *heap, void *p);
>  
> +/**
> + * heap_remove - remove the largest element from the heap
> + * @heap: the heap to be operated on
> + *
> + * Returns the largest element in the heap. It removes this element from the
> + * heap. Returns NULL if the heap is empty.
> + */
> +extern void *heap_remove(struct ptr_heap *heap);
>  
> +/**
> + * heap_cherrypick - remove a given element from the heap
> + * @heap: the heap to be operated on
> + * @p: the element
> + *
> + * Remove the given element from the heap. Return the element if present, else
> + * return NULL. This algorithm has a complexity of O(n), which is higher than
> + * O(log(n)) provided by the rest of this API.
> + */
> +extern void *heap_cherrypick(struct ptr_heap *heap, void *p);
> +
> +/**
> + * heap_replace_max - replace the the largest element from the heap
> + * @heap: the heap to be operated on
> + * @p: the pointer to be inserted as topmost element replacement
> + *
> + * Returns the largest element in the heap. It removes this element from the
> + * heap. The heap is rebalanced only once after the insertion. Returns NULL if
> + * the heap is empty.
> + *
> + * This is the equivalent of calling heap_remove() and then heap_insert(), but
> + * it only rebalances the heap once.
> + */
> +extern void *heap_replace_max(struct ptr_heap *heap, void *p);
>  
>  #endif /* _LINUX_PRIO_HEAP_H */
> Index: linux.trees.git/lib/prio_heap.c
> ===================================================================
> --- linux.trees.git.orig/lib/prio_heap.c	2010-07-06 14:25:29.000000000 -0400
> +++ linux.trees.git/lib/prio_heap.c	2010-07-07 10:18:32.000000000 -0400
> @@ -23,12 +23,49 @@ void heap_free(struct ptr_heap *heap)
>  	kfree(heap->ptrs);
>  }
>  
> -void *heap_insert(struct ptr_heap *heap, void *p)
> +static void heapify(struct ptr_heap *heap, void **ptrs, void *p, int pos)
> +{
> +	while (1) {
> +		int left = 2 * pos + 1;
> +		int right = 2 * pos + 2;
> +		int largest = pos;
> +		if (left < heap->size && heap->gt(ptrs[left], p))
> +			largest = left;
> +		if (right < heap->size && heap->gt(ptrs[right], ptrs[largest]))
> +			largest = right;
> +		if (largest == pos)
> +			break;
> +		/* Push p down the heap one level and bump one up */
> +		ptrs[pos] = ptrs[largest];
> +		ptrs[largest] = p;
> +		pos = largest;
> +	}
> +}

This is "static", no one use it, but someone will read it and be confused.
because it haves/(is required) a precondition: "ptrs[pos] == p", and no comments for it.

PS:
the code is exactly the same as the book CLRS, but in practice, I think we can
save a half assignments and the precondition(and save a line of code which provides
this precondition before call heapify()).

/* just type it in this email, compare the children at first */
/* ptrs[pos] is a hole */
static void heapify(struct ptr_heap *heap, void **ptrs, void *p, int pos)
{
	while (1) {
		int left = 2 * pos + 1;
		int right = 2 * pos + 2;
		int largest = left;
		/* compare the children at first */
		if (right < heap->size && heap->gt(ptrs[right], ptrs[left]))
			largest = right;
		if (!(largest < heap->size) || heap->gt(p, ptrs[largest])) {
			ptrs[pos] = p;
			break;
		}
		/* Push p down the heap one level and bump one up */
		ptrs[pos] = ptrs[largest];
		pos = largest;
	}
}

> +
> +void *heap_replace_max(struct ptr_heap *heap, void *p)
>  {
>  	void *res;
>  	void **ptrs = heap->ptrs;
>  	int pos;
>  
> +	if (!heap->size) {
> +		ptrs[heap->size++] = p;
> +		return NULL;
> +	}
> +
> +	/* Replace the current max and heapify */
> +	res = ptrs[0];
> +	ptrs[0] = p;
> +	pos = 0;
> +	heapify(heap, ptrs, p, pos);
> +	return res;
> +}
> +
> +void *heap_insert(struct ptr_heap *heap, void *p)
> +{
> +	void **ptrs = heap->ptrs;
> +	int pos;
> +
>  	if (heap->size < heap->max) {
>  		/* Heap insertion */
>  		pos = heap->size++;
> @@ -47,24 +84,40 @@ void *heap_insert(struct ptr_heap *heap,
>  		return p;
>  
>  	/* Replace the current max and heapify */
> -	res = ptrs[0];
> -	ptrs[0] = p;
> -	pos = 0;
> +	return heap_replace_max(heap, p);
> +}

Since we have heap_replace_max(), I think we can change the semantic
of heap_insert() to origin: insert a new element and maintain the heap or
return fail when some errors occur(example: the the heap is full).

currently only cgroup use heap_insert(), we can covert it to
new heap_insert() + heap_replace_max().
Or add a new API for it.

Just my think.

>  
> -	while (1) {
> -		int left = 2 * pos + 1;
> -		int right = 2 * pos + 2;
> -		int largest = pos;
> -		if (left < heap->size && heap->gt(ptrs[left], p))
> -			largest = left;
> -		if (right < heap->size && heap->gt(ptrs[right], ptrs[largest]))
> -			largest = right;
> -		if (largest == pos)
> -			break;
> -		/* Push p down the heap one level and bump one up */
> -		ptrs[pos] = ptrs[largest];
> -		ptrs[largest] = p;
> -		pos = largest;
> +void *heap_remove(struct ptr_heap *heap)
> +{
> +	void **ptrs = heap->ptrs;
> +
> +	switch (heap->size) {
> +	case 0:
> +		return NULL;
> +	case 1:
> +		return ptrs[--heap->size];
>  	}
> -	return res;
> +
> +	/* Shrink, replace the current max by previous last entry and heapify */
> +	return heap_replace_max(heap, ptrs[--heap->size]);
> +}
> +
> +void *heap_cherrypick(struct ptr_heap *heap, void *p)
> +{
> +	void **ptrs = heap->ptrs;
> +	size_t pos, size = heap->size;
> +
> +	for (pos = 0; pos < size; pos++)
> +		if (ptrs[pos] == p)
> +			goto found;
> +	return NULL;
> +found:
> +	if (heap->size == 1)
> +		return ptrs[--heap->size];
> +	/*
> +	 * Replace p with previous last entry and heapify.
> +	 */
> +	ptrs[pos] = ptrs[--heap->size];
> +	heapify(heap, ptrs, ptrs[pos], pos);
> +	return p;
>  }
> 

Thanks.
Reviewed-by: Lai Jiangshan <laijs@cn.fujitsu.com>

^ permalink raw reply

* Re: How to modify /etc/network/interfaces file in a OE recipe
From: Khem Raj @ 2010-10-08  3:26 UTC (permalink / raw)
  To: openembedded-devel
In-Reply-To: <4CAE4F92.5080107@mlbassoc.com>

On Thu, Oct 7, 2010 at 3:54 PM, Gary Thomas <gary@mlbassoc.com> wrote:
> On 10/07/2010 03:11 PM, Elvis Dowson wrote:
>>
>> Hi,
>>        Would someone be able to help me with modifying an
>> omap3-console-image recipe, such that in the final image, the
>> /etc/network/interfaces file gets edited as follows
>>
>> #auto eth0                              <- remove # sign ( auto eth0 )
>> #iface eth0 inet dhcp           <- remove # sign ( iface eth0 inet dhcp )
>> #iface eth1 inet dhcp
>>
>> I am using a Gumstix Overo + Chestnut43 expansion board, which has an
>> inbuilt wired ethernet interface. I have to make this modification manually,
>> to enable this interface each time. However, if I can modify the OE recipe
>> somehow to do this it would be great. I know it can be done, but I don't
>> know where to start and which file to modify.
>
> Add the file the way you like it to
> .../openembedded/recipes/netbase/netbase/overo
> and rebuild netbase.  Use the beagleboard as an example.

or use bblayers and bbappend.

>
> --
> ------------------------------------------------------------
> Gary Thomas                 |  Consulting for the
> MLB Associates              |    Embedded world
> ------------------------------------------------------------
>
> _______________________________________________
> Openembedded-devel mailing list
> Openembedded-devel@lists.openembedded.org
> http://lists.linuxtogo.org/cgi-bin/mailman/listinfo/openembedded-devel
>



^ permalink raw reply

* RE: Using ofono HFP
From: Zhang, Zhenhua @ 2010-10-08  3:25 UTC (permalink / raw)
  To: ofono
In-Reply-To: <AANLkTikeRN7CiQNxpdLh9L_EV=ZTACQGDSt7xbzizUDD@mail.gmail.com>

[-- Attachment #1: Type: text/plain, Size: 1693 bytes --]

Hi Silva,

Moises Silva wrote:
> On Tue, Sep 28, 2010 at 10:50 PM, Denis Kenzior
> <denkenz@gmail.com> wrote:
>> The second descriptor (what ipc.c and ipc.h deal with) is used to
>> pass the SCO fd to PulseAudio or gStreamer.  This fd is used for
>> Audio. Marcel or Johan might know better, but I think the reason for
>> ipc.c and ipc.h was that DBus did not support fd-passing at the time
>> BlueZ audio integration work was being done.
> 
> Thanks for the help.
> 
> I have a few more questions. I got my own small app connecting to the
> audio server and I am able to read/write fromt he sco socket.
> 
> However it seems the MTU is hard-coded int audio/unix.c to 48.
> 
> Where does this 48 comes from? I come from the TDM open source world,
> where typical configuration for TDM devices is 160 (160 bytes of
> alaw/ulaw, 160 samples, each 20ms).
> 
> Is there any way to change that socket MTU to 160 or 320 (depending if
> it's either SLN16 or alaw/mulaw?

You might want to raise your question on bluez's IRC or mailing list. oFono takes care of call control logic while BlueZ/PulseAudio takes care of SCO audio packets.

> How can I know the format for the audio?

I think it should be PCM raw data from SCO packets but it could wrong maybe.

> I'll keep digging in pulseaudio to see if I find the answer ...
> 
> Moises Silva
> Senior Software Engineer
> Sangoma Technologies Inc. | 100 Renfrew Drive, Suite 100, Markham ON
> L3R 9R6 Canada t. 1 905 474 1990 x128 | e. moy(a)sangoma.com
> _______________________________________________
> ofono mailing list
> ofono(a)ofono.org
> http://lists.ofono.org/listinfo/ofono

Regards,
Zhenhua


^ permalink raw reply


This is an external index of several public inboxes,
see mirroring instructions on how to clone and mirror
all data and code used by this external index.