[PATCH] libertas_sdio lockup fix

Dan Williams dcbw at redhat.com
Thu Apr 1 11:23:30 EDT 2010


On Thu, 2010-04-01 at 09:31 +0200, Jes Sorensen wrote:
> On 04/01/10 09:06, Dan Williams wrote:
> > We're trying to kill lbs_prepare_and_send_command() completely though
> > and move most commands to separate handlers.  Any chance you could port
> > the patch to do that instead?  Basically create a function modeled after
> > cmd.c::lbs_get_tx_power()
> 
> Hi Dan,
> 
> Thanks for the feedback. The problem I had was that I know zilch about
> the libertas chips, so I was guessing my way through based on the old
> patch that I found.
> 
> I'll try and setup a build environment and see if I can reproduce it as
> the last test I did was a full rpm build. My test box is a 1.1GHz with
> 16GB SSD so it's not really up for kernel builds.

It should be pretty easy to just grab the kernel SRPM, copy out the
drivers/net/wireless/libertas directory, then inside that directory you
can:

make -C /lib/modules/`uname -r`/build SUBDIRS=`pwd` modules

and then you can insmod the .ko files from that directory.  No need to
do a full kernel build.

> > int lbs_get_log (struct lbs_private *priv, u32 *retries, u32 *code, u32 *misc)
> > {
> > 	struct cmd_ds_802_11_get_log cmd;
> > 	int ret;
> >
> > 	lbs_deb_enter(LBS_DEB_CMD);
> >
> > 	memset(&cmd, 0, sizeof(cmd));
> > 	cmd.hdr.size = cpu_to_le16(sizeof(cmd));
> >
> > 	ret = lbs_cmd_with_response(priv, CMD_802_11_GET_LOG,&cmd);
> > 	if (ret == 0) {
> > 		*retries = get_unaligned_le32(cmd.retry);
> > 		*code = get_unaligned_le32(cmd.code);
> > 		*misc = get_unaligned_le32(cmd.misc);
> > 	}
> >
> > 	lbs_deb_leave(LBS_DEB_CMD);
> > 	return ret;
> > }
> >
> > Then at the bottom of the function call lbs_get_log() and use the
> > returned u32 values to populate priv->wstats.  But really, it looks like
> > the only functional changes here are:
> 
> This part looks easy enough.
> 
> > 1) the cmd size passed to the 8686 is larger with this patch, since you
> > haven't removed the header from struct cmd_ds_802_11_get_log; it could
> > be that we got the size slightly wrong or something when converting it
> > to a "direct" command?
> >     - pad the structure in host.h by another u32 at the bottom and see if
> > this helps
> 
> The size in my patch was pure guessware to be honest. The original patch
> used sizeof(struct cmd_ds_802_11_get_log) + S_DS_GEN and I didn't find
> S_DS_GEN anywhere.
> 
> > 2) calling GET_LOG after RSSI.  Not sure why that would make a
> > difference, but it could
> >     - do the "direct" command thing above but move the lbs_get_log() call
> > after the RSSI call
> 
> I think I can figure this out.
> 
> > 3) not calling GET_LOG through the blocking command path during the WEXT
> > stats requests
> >     - call GET_LOG async and just ignore updating the wstats values to
> > see if the blocking nature of "direct" commands is indeed the issue
> > since the wext stats stuff gets called in different places with
> > different locking semantics
> 
> I am not sure if I follow you here. Is there an easy async path for this
> or do I need to come up with something?

__lbs_cmd_async is the magic function for firing off an async command
and ignoring the result.

> > Any chance you could try these three options and see if they also fix
> > the problem?  I'd like to figure out why this is happing instead of just
> > apply what looks like a partial revert first.
> 
> I am happy to help as much as I can. Main problem is that the libertas
> codebase is pretty unknown to me.

Let me know if you have any more questions!

Dan





More information about the libertas-dev mailing list