rmmod libertas_sdio and reinsert causes problems with firmware upload.

Dan Williams dcbw at redhat.com
Tue Sep 2 10:08:02 EDT 2008


On Mon, 2008-09-01 at 16:24 +0100, Jonathan Cameron wrote:
> Dear All, 
> 
> I've had a go at following the approach used in if_usb (reset function tried
> when firmware initially fails to load.
> 
> The function I ended up with is below, but the problem is that the device
> seems to end up completely stalled and I can't read the scratch pad without
> getting a time out.
> 
> Anyone have any suggestions on where I'm going wrong.  As I'm not particularly
> familiar with either the libertas code or sdio, it's probably full of bugs!

Hmm, need to get Pierre to weigh in here as to whether this is the right
way to try to reset the card by poking the SD function.

Dan

> Cheers, 
> 
> Jonathan
> 
> 
> static int if_sdio_reset_device(struct if_sdio_card *card)
> {
> 	int ret;
> 	u8 status;
> 	struct cmd_ds_command cmd;
> 	struct if_sdio_packet *packet;
> 	/* number of bytes in command */
> 	int nb = S_DS_GEN;
> 	int size = sdio_align_size(card->func, nb+4);
> 	printk("Trying to reset the device \n");
> 	cmd.command = cpu_to_le16(CMD_802_11_RESET);
> 	cmd.size = cpu_to_le16(S_DS_GEN);
> 	cmd.result = cpu_to_le16(0);
> 	cmd.seqnum = cpu_to_le16(0x5a5a);
> 	//cmd.params.reset.action = cpu_to_le16(CMD_ACT_HALT);
> 
> 	packet = kzalloc(sizeof(struct if_sdio_packet) +  size, GFP_KERNEL);
> 	if (!packet) {
> 		return -ENOMEM;
> 	}
> 	packet->next = NULL;
> 	packet->nb =  size;
> 	packet->buffer[0] = (nb + 4)&0xff;
> 	packet->buffer[1] = ((nb + 4) >> 8) & 0xff;
> 	packet->buffer[2] = MVMS_CMD;
> 	packet->buffer[3] = 0;
> 	memcpy(packet->buffer + 4, &cmd, nb);
> 
> 	sdio_claim_host(card->func);
> 	printk("claimed card\n");
> 	while (1) {
> 		status = sdio_readb(card->func, IF_SDIO_STATUS, &ret);
> 		if (ret)
> 			goto release;
> 		if (status & IF_SDIO_IO_RDY)
> 			break;
> 		mdelay(1);
> 	}
> 	ret = sdio_writesb(card->func, card->ioport,
> 			   packet->buffer, packet->nb);
> 	if (ret)
> 		printk("failed?\n");
> 	printk("I think I've reset the card by here?\n");
> 	sdio_release_host(card->func);
> 	msleep(2000);
> release:
> 
> 	return ret;
> }
> 
> 
> 
> Jonathan Cameron wrote:
> > Dear All,
> > 
> > So procedure is:
> > 
> > Insert the boards spi host driver and libertas_sdio which
> > works fine.
> > 
> > Next remove libertas_sdio.
> > 
> > Reinsert libertas_sdio and watch the firmware load fail.
> > 
> > (using 2.6.27-rc4)
> > 
> > Firstly I'll admit this a fairly odd circumstance to be in, but technically
> > this should be a valid thing to do. 
> > 
> > The problem lies in the fact that the scratch register is used all over
> > the place by the device so unsuprisingly doesn't contain the firmware
> > upload succeeded flag and hence tries to load firmware into a device on
> > which it is already running causing the driver insertion to fail.
> > 
> > So question is, what would be the correct fix? 
> > 
> > I'm not terribly familiar with the sdio subsystem, but I assume it's possible
> > to tell whether a remove is due to driver removal or device removal.  If it's
> > the driver, then issuing a CMD_802_11_RESET will apparently reset to the extent
> > of needing a new firmware load - hence putting our device minus driver back
> > to the state it was in before the driver was loaded.
> > 
> > Another option would be to fudge the test for whether the firmware has already
> > loaded to allow for values other than the correct one, though I guess it's
> > possible the scratch register can contain zero with firmware loaded as well
> > as on startup so that's not ideal.
> > 
> > Please cc me in to replies as I'm not on libertas-dev...
> > --
> > Jonathan Cameron
> 
> 
> 
> 
> _______________________________________________
> libertas-dev mailing list
> libertas-dev at lists.infradead.org
> http://lists.infradead.org/mailman/listinfo/libertas-dev




More information about the libertas-dev mailing list