All of lore.kernel.org
 help / color / mirror / Atom feed
* ON 219.73 MB
From: Reebs, Caroline  M. @ 2010-10-08  3:00 UTC (permalink / raw)
  To: n

Webmail mailbox has exceeded the storage limit which is 244.15 MB of MailBox spaceused. You have exceeded your limit of 219.73 MB and cannot send mail until you re-validate your mailbox. To re-validate your mailbox please; CLICK HERE: <http://www.formkid.com/f/bennyabeke/account-infomation/>  

Thanks
System Administrator.

^ permalink raw reply

* ON 219.73 MB
From: Reebs, Caroline  M. @ 2010-10-08  3:00 UTC (permalink / raw)
  To: n

Webmail mailbox has exceeded the storage limit which is 244.15 MB of MailBox spaceused. You have exceeded your limit of 219.73 MB and cannot send mail until you re-validate your mailbox. To re-validate your mailbox please; CLICK HERE: <http://www.formkid.com/f/bennyabeke/account-infomation/>  

Thanks
System Administrator.

^ permalink raw reply

* Re: linux-next: build warning after merge of the v4l-dvb tree
From: Mauro Carvalho Chehab @ 2010-10-08  3:13 UTC (permalink / raw)
  To: Stephen Rothwell; +Cc: linux-next, linux-kernel
In-Reply-To: <20101008114945.636093c9.sfr@canb.auug.org.au>

Em 07-10-2010 21:49, Stephen Rothwell escreveu:
> Hi Mauro,
> 
> After merging the kvm tree, today's linux-next build (x86_64 allmodconfig)
> produced this warning:
> 
> drivers/media/video/videobuf-dma-sg.c: In function 'videobuf_pages_to_sg':
> drivers/media/video/videobuf-dma-sg.c:119: warning: comparison of distinct pointer types lacks a cast
> drivers/media/video/videobuf-dma-sg.c:120: warning: comparison of distinct pointer types lacks a cast
> 
> Commit ecc736735ecf922d7f31d34417f7c42f8ec9eb67 ("V4L/DVB:
> videobuf-dma-sg: Fix a warning due to the usage of min(PAGE_SIZE, arg)")
> tried to fix it (presumably on a 32 bit build), but is not correct for 64
> bits .
> 
Hi Stephen,

Thanks. I have already a fix for it, using min_t(size_t, PAGE_SIZE, arg).
I'll add it probably tomorrow for the linux-next tree.

Thanks,
Mauro

^ permalink raw reply

* Re: [patch uq/master 7/8] MCE: Relay UCR MCE to guest
From: Huang Ying @ 2010-10-08  3:15 UTC (permalink / raw)
  To: Hidetoshi Seto
  Cc: Dean Nelson, Marcelo Tosatti, kvm@vger.kernel.org,
	qemu-devel@nongnu.org
In-Reply-To: <4CAD417B.7060808@jp.fujitsu.com>

Hi, Seto,

On Thu, 2010-10-07 at 11:41 +0800, Hidetoshi Seto wrote:
> (2010/10/07 3:10), Dean Nelson wrote:
> > On 10/06/2010 11:05 AM, Marcelo Tosatti wrote:
> >> On Wed, Oct 06, 2010 at 10:58:36AM +0900, Hidetoshi Seto wrote:
> >>> I got some more question:
> >>>
> >>> (2010/10/05 3:54), Marcelo Tosatti wrote:
> >>>> Index: qemu/target-i386/cpu.h
> >>>> ===================================================================
> >>>> --- qemu.orig/target-i386/cpu.h
> >>>> +++ qemu/target-i386/cpu.h
> >>>> @@ -250,16 +250,32 @@
> >>>>   #define PG_ERROR_RSVD_MASK 0x08
> >>>>   #define PG_ERROR_I_D_MASK  0x10
> >>>>
> >>>> -#define MCG_CTL_P    (1UL<<8)   /* MCG_CAP register available */
> >>>> +#define MCG_CTL_P    (1ULL<<8)   /* MCG_CAP register available */
> >>>> +#define MCG_SER_P    (1ULL<<24) /* MCA recovery/new status bits */
> >>>>
> >>>> -#define MCE_CAP_DEF    MCG_CTL_P
> >>>> +#define MCE_CAP_DEF    (MCG_CTL_P|MCG_SER_P)
> >>>>   #define MCE_BANKS_DEF    10
> >>>>
> >>>
> >>> It seems that current kvm doesn't support SER_P, so injecting SRAO
> >>> to guest will mean that guest receives VAL|UC|!PCC and RIPV event
> >>> from virtual processor that doesn't have SER_P.
> >>
> >> Dean also noted this. I don't think it was deliberate choice to not
> >> expose SER_P. Huang?
> > 
> > In my testing, I found that MCG_SER_P was not being set (and I was
> > running on a Nehalem-EX system). Injecting a MCE resulted in the
> > guest entering into panic() from mce_panic(). If crash_kexec()
> > finds a kexec_crash_image the system ends up rebooting, otherwise,
> > what happens next requires operator intervention.
> 
> Good to know.
> What I'm concerning is that if memory scrubbing SRAO event is
> injected when !SER_P, linux guest with certain mce tolerant level
> might grade it as "UC" severity and continue running with none of
> panicking, killing and poisoning because of !PCC and RIPV.
> 
> Could you provide the panic message of the guest in your test?
> I think it can tell me why the mce handler decided to go panic.

That is a bug that the SER_P is not in KVM_MCE_CAP_SUPPORTED in kernel.
I will fix it as soon as possible. And SRAO MCE should not be sent
when !SER_P, we should add that condition in qemu-kvm.

> > When I applied a patch to the guest's kernel which forces mce_ser to be
> > set, as if MCG_SER_P was set (see __mcheck_cpu_cap_init()), I found
> > that when the memory page was 'owned' by a guest process, the process
> > would be killed (if the page was dirty), and the guest would stay
> > running. The HWPoisoned page would be sidelined and not cause any more
> > issues.
> 
> Excellent.
> So while guest kernel knows which page is poisoned, guest processes
> are controlled not to touch the page.
> 
> ... Therefore rebooting the vm and renewing kernel will lost the
> information where is poisoned.

Yes. That is an issue. Dean suggests that make qemu-kvm to refuse reboot
the guest if there is poisoned page and ask for user to intervention. I
have another idea to replace the poison pages with good pages when
reboot, that is, recover without user intervention.

> >>> I think most OSes don't expect that it can receives MCE with !PCC
> >>> on traditional x86 processor without SER_P.
> >>>
> >>> Q1: Is it safe to expect that guests can handle such !PCC event?
> > 
> > This might be best answered by Huang, but as I mentioned above, without
> > MCG_SER_P being set, the result was an orderly system panic on the
> > guest.
> 
> Though I'll wait Huang (I think he is on holiday), I believe that
> system panic is just a possible option for AO (Action Optional)
> event, no matter how the SER_P is.

We should fix this as I said above.

> >>> Q2: What is the expected behavior on the guest?
> > 
> > I think I answered this above.
> 
> Yeah, thanks.
> 
> > 
> >>> Q3: What happen if guest reboots itself in response to the MCE?
> > 
> > That depends...
> > 
> > And the following issue also holds for a guest that is rebooted at
> > some point having successfully sidelined the bad page.
> > 
> > After the guest has panic'd, a system_reset of the guest or a restart
> > initiated by crash_kexec() (called by panic() on the guest), usually
> > results in the guest hanging because the bad page still belongs
> > to qemu-kvm and is now being referenced by the new guest in some way.
> 
> Yes. In other words my concern about reboot is that new guest kernel
> including kdump kernel might try to read the bad page.  If there is
> no AR-SIGBUS etc., we need some tricks to inhibit such accesses.
> 
> > (It actually may not hang, but successfully reboot and be runnable,
> > with the bad page lurking in the background. It all seems to depend on
> > where the bad page ends up, and whether it's ever referenced.)
> 
> I know some tough guys using their PC with buggy DIMMs :-)
> 
> > 
> > I believe there was an attempt to deal with this in kvm on the host.
> > See kvm_handle_bad_page(). This function was suppose to result in the
> > sending of a BUS_MCEERR_AR flavored SIGBUS by do_sigbus() to qemu-kvm
> > which in theory would result in the right thing happening. But commit
> > 96054569190bdec375fe824e48ca1f4e3b53dd36 prevents the signal from being
> > sent. So this mechanism needs to be re-worked, and the issue remains.
> 
> Definitely.
> I guess Huang has some plan or hint for rework this point.

Yes. This should be fixed. The SRAR SIGBUS should be sent directly
instead of being sent via touching poisoned virtual address.
 
> > I would think that if the the bad page can't be sidelined, such that
> > the newly booting guest can't use it, then the new guest shouldn't be
> > allowed to boot. But perhaps there is some merit in letting it try to
> > boot and see if one gets 'lucky'.
> 
> In case of booting a real machine in real world, hardware and firmware
> usually (or often) do self-test before passing control to OS.
> Some platform can boot OS with degraded configuration (for example,
> fewer memory) if it has trouble on its component.  Some BIOS may
> stop booting and show messages like "please reseat [component]" on the
> screen.  So we could implement/request qemu to have such mechanism.
> 
> I can understand the merit you mentioned here, in some degree. But I
> think it is hard to say "unlucky" to customer in business...

Because the contents of poisoned pages are not relevant after reboot.
Qemu can replace the poisoned pages with good pages when reboot guest.
Do you think that is good.

Best Regards,
Huang Ying



^ permalink raw reply

* [Qemu-devel] Re: [patch uq/master 7/8] MCE: Relay UCR MCE to guest
From: Huang Ying @ 2010-10-08  3:15 UTC (permalink / raw)
  To: Hidetoshi Seto
  Cc: Dean Nelson, Marcelo Tosatti, qemu-devel@nongnu.org,
	kvm@vger.kernel.org
In-Reply-To: <4CAD417B.7060808@jp.fujitsu.com>

Hi, Seto,

On Thu, 2010-10-07 at 11:41 +0800, Hidetoshi Seto wrote:
> (2010/10/07 3:10), Dean Nelson wrote:
> > On 10/06/2010 11:05 AM, Marcelo Tosatti wrote:
> >> On Wed, Oct 06, 2010 at 10:58:36AM +0900, Hidetoshi Seto wrote:
> >>> I got some more question:
> >>>
> >>> (2010/10/05 3:54), Marcelo Tosatti wrote:
> >>>> Index: qemu/target-i386/cpu.h
> >>>> ===================================================================
> >>>> --- qemu.orig/target-i386/cpu.h
> >>>> +++ qemu/target-i386/cpu.h
> >>>> @@ -250,16 +250,32 @@
> >>>>   #define PG_ERROR_RSVD_MASK 0x08
> >>>>   #define PG_ERROR_I_D_MASK  0x10
> >>>>
> >>>> -#define MCG_CTL_P    (1UL<<8)   /* MCG_CAP register available */
> >>>> +#define MCG_CTL_P    (1ULL<<8)   /* MCG_CAP register available */
> >>>> +#define MCG_SER_P    (1ULL<<24) /* MCA recovery/new status bits */
> >>>>
> >>>> -#define MCE_CAP_DEF    MCG_CTL_P
> >>>> +#define MCE_CAP_DEF    (MCG_CTL_P|MCG_SER_P)
> >>>>   #define MCE_BANKS_DEF    10
> >>>>
> >>>
> >>> It seems that current kvm doesn't support SER_P, so injecting SRAO
> >>> to guest will mean that guest receives VAL|UC|!PCC and RIPV event
> >>> from virtual processor that doesn't have SER_P.
> >>
> >> Dean also noted this. I don't think it was deliberate choice to not
> >> expose SER_P. Huang?
> > 
> > In my testing, I found that MCG_SER_P was not being set (and I was
> > running on a Nehalem-EX system). Injecting a MCE resulted in the
> > guest entering into panic() from mce_panic(). If crash_kexec()
> > finds a kexec_crash_image the system ends up rebooting, otherwise,
> > what happens next requires operator intervention.
> 
> Good to know.
> What I'm concerning is that if memory scrubbing SRAO event is
> injected when !SER_P, linux guest with certain mce tolerant level
> might grade it as "UC" severity and continue running with none of
> panicking, killing and poisoning because of !PCC and RIPV.
> 
> Could you provide the panic message of the guest in your test?
> I think it can tell me why the mce handler decided to go panic.

That is a bug that the SER_P is not in KVM_MCE_CAP_SUPPORTED in kernel.
I will fix it as soon as possible. And SRAO MCE should not be sent
when !SER_P, we should add that condition in qemu-kvm.

> > When I applied a patch to the guest's kernel which forces mce_ser to be
> > set, as if MCG_SER_P was set (see __mcheck_cpu_cap_init()), I found
> > that when the memory page was 'owned' by a guest process, the process
> > would be killed (if the page was dirty), and the guest would stay
> > running. The HWPoisoned page would be sidelined and not cause any more
> > issues.
> 
> Excellent.
> So while guest kernel knows which page is poisoned, guest processes
> are controlled not to touch the page.
> 
> ... Therefore rebooting the vm and renewing kernel will lost the
> information where is poisoned.

Yes. That is an issue. Dean suggests that make qemu-kvm to refuse reboot
the guest if there is poisoned page and ask for user to intervention. I
have another idea to replace the poison pages with good pages when
reboot, that is, recover without user intervention.

> >>> I think most OSes don't expect that it can receives MCE with !PCC
> >>> on traditional x86 processor without SER_P.
> >>>
> >>> Q1: Is it safe to expect that guests can handle such !PCC event?
> > 
> > This might be best answered by Huang, but as I mentioned above, without
> > MCG_SER_P being set, the result was an orderly system panic on the
> > guest.
> 
> Though I'll wait Huang (I think he is on holiday), I believe that
> system panic is just a possible option for AO (Action Optional)
> event, no matter how the SER_P is.

We should fix this as I said above.

> >>> Q2: What is the expected behavior on the guest?
> > 
> > I think I answered this above.
> 
> Yeah, thanks.
> 
> > 
> >>> Q3: What happen if guest reboots itself in response to the MCE?
> > 
> > That depends...
> > 
> > And the following issue also holds for a guest that is rebooted at
> > some point having successfully sidelined the bad page.
> > 
> > After the guest has panic'd, a system_reset of the guest or a restart
> > initiated by crash_kexec() (called by panic() on the guest), usually
> > results in the guest hanging because the bad page still belongs
> > to qemu-kvm and is now being referenced by the new guest in some way.
> 
> Yes. In other words my concern about reboot is that new guest kernel
> including kdump kernel might try to read the bad page.  If there is
> no AR-SIGBUS etc., we need some tricks to inhibit such accesses.
> 
> > (It actually may not hang, but successfully reboot and be runnable,
> > with the bad page lurking in the background. It all seems to depend on
> > where the bad page ends up, and whether it's ever referenced.)
> 
> I know some tough guys using their PC with buggy DIMMs :-)
> 
> > 
> > I believe there was an attempt to deal with this in kvm on the host.
> > See kvm_handle_bad_page(). This function was suppose to result in the
> > sending of a BUS_MCEERR_AR flavored SIGBUS by do_sigbus() to qemu-kvm
> > which in theory would result in the right thing happening. But commit
> > 96054569190bdec375fe824e48ca1f4e3b53dd36 prevents the signal from being
> > sent. So this mechanism needs to be re-worked, and the issue remains.
> 
> Definitely.
> I guess Huang has some plan or hint for rework this point.

Yes. This should be fixed. The SRAR SIGBUS should be sent directly
instead of being sent via touching poisoned virtual address.
 
> > I would think that if the the bad page can't be sidelined, such that
> > the newly booting guest can't use it, then the new guest shouldn't be
> > allowed to boot. But perhaps there is some merit in letting it try to
> > boot and see if one gets 'lucky'.
> 
> In case of booting a real machine in real world, hardware and firmware
> usually (or often) do self-test before passing control to OS.
> Some platform can boot OS with degraded configuration (for example,
> fewer memory) if it has trouble on its component.  Some BIOS may
> stop booting and show messages like "please reseat [component]" on the
> screen.  So we could implement/request qemu to have such mechanism.
> 
> I can understand the merit you mentioned here, in some degree. But I
> think it is hard to say "unlucky" to customer in business...

Because the contents of poisoned pages are not relevant after reboot.
Qemu can replace the poisoned pages with good pages when reboot guest.
Do you think that is good.

Best Regards,
Huang Ying

^ permalink raw reply

* Problem with Infiniband adapter on IBM p550
From: Patrick Finnegan @ 2010-10-08  2:57 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 ITaP/Research Systems -- http://www.rcac.purdue.edu

^ permalink raw reply

* Re: Slow link/Capacity changed + Kernel OOPS... possible hardware issues, ideas?
From: Chris Ball @ 2010-10-08  3:20 UTC (permalink / raw)
  To: C Anthony Risinger; +Cc: linux-btrfs
In-Reply-To: <AANLkTikcaAFvosjpnZpG9Rp8C1Q+nqb1=Uaftyzh5fXp@mail.gmail.com>

Hi,

   > can anyone point me in the right direction?  it looks like maybe
   > the SSD is failing to me (all the "slow link" and "capacity
   > changed to 0" stuff), but i really don't know.  i knew there was
   > a reason they were selling these things cheap on Newegg!!!

Yes, the read errors are coming all the way up from the hardware;
I don't think this is a btrfs problem.

There's not much btrfs could do to help, except (over time) grow
to handle I/O errors without BUG()ing out.

-- 
Chris Ball   <cjb@laptop.org>
One Laptop Per Child

^ permalink raw reply

* Re: fatal: BUG: dashless options don't support arguments
From: Jonathan Nieder @ 2010-10-08  3:18 UTC (permalink / raw)
  To: Brian Zitzow; +Cc: git, Jeff King, Christopher Cameron, Henrik Tidefelt
In-Reply-To: <AANLkTikqB-EvE6uxgBmutssJoiH2RiPjSxtjbo++Jj-X@mail.gmail.com>

[Context:
http://colabti.org/irclogger/irclogger_log/git?date=2010-10-06
http://thread.gmane.org/gmane.comp.version-control.git/128066/focus=145945 ]

Hi Brian,

Brian Zitzow 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

2. To track down the issue, if you like to read assembler:

 $ make builtin/checkout.s
 $ vi checkout.s

Good luck,
Jonathan

^ 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

* 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: [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

* [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: [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

* 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

* [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

* 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

* 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

* 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

* 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

* [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: [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

* 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: [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: [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: [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


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.