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