rmmod libertas_sdio and reinsert causes problems with firmware upload.

Dan Williams dcbw at redhat.com
Tue Sep 2 10:38:15 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!
> 
> Cheers, 
> 
> Jonathan

cc-ing Pierre for feedback.


> 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