static struct brcmf_usbdev *brcmf_usb_attach(struct brcmf_usbdev_info *devinfo, int nrxq, int ntxq) { brcmf_dbg(USB, "Enter\n"); devinfo->bus_pub.nrxq = nrxq; devinfo->rx_low_watermark = nrxq / 2; devinfo->bus_pub.devinfo = devinfo; devinfo->bus_pub.ntxq = ntxq; devinfo->bus_pub.state = BRCMFMAC_USB_STATE_DOWN; /* flow control when too many tx urbs posted */ devinfo->tx_low_watermark = ntxq / 4; devinfo->tx_high_watermark = devinfo->tx_low_watermark * 3; devinfo->bus_pub.bus_mtu = BRCMF_USB_MAX_PKT_SIZE; /* Initialize other structure content */ init_waitqueue_head(&devinfo->ioctl_resp_wait); /* Initialize the spinlocks */ spin_lock_init(&devinfo->qlock); spin_lock_init(&devinfo->tx_flowblock_lock); INIT_LIST_HEAD(&devinfo->rx_freeq); INIT_LIST_HEAD(&devinfo->rx_postq); INIT_LIST_HEAD(&devinfo->tx_freeq); INIT_LIST_HEAD(&devinfo->tx_postq); devinfo->tx_flowblock = false; devinfo->rx_reqs = brcmf_usbdev_qinit(&devinfo->rx_freeq, nrxq); if (!devinfo->rx_reqs) goto error; devinfo->tx_reqs = brcmf_usbdev_qinit(&devinfo->tx_freeq, ntxq); if (!devinfo->tx_reqs) goto error; devinfo->tx_freecount = ntxq; devinfo->ctl_urb = usb_alloc_urb(0, GFP_ATOMIC); if (!devinfo->ctl_urb) { brcmf_err("usb_alloc_urb (ctl) failed\n"); goto error; } devinfo->bulk_urb = usb_alloc_urb(0, GFP_ATOMIC); if (!devinfo->bulk_urb) { brcmf_err("usb_alloc_urb (bulk) failed\n"); goto error; } return &devinfo->bus_pub; error: brcmf_err("failed!\n"); brcmf_usb_detach(devinfo); return NULL; }
static int brcmf_usb_probe_cb(struct brcmf_usbdev_info *devinfo) { struct brcmf_bus *bus = NULL; struct brcmf_usbdev *bus_pub = NULL; struct device *dev = devinfo->dev; int ret; brcmf_dbg(USB, "Enter\n"); bus_pub = brcmf_usb_attach(devinfo, BRCMF_USB_NRXQ, BRCMF_USB_NTXQ); if (!bus_pub) return -ENODEV; bus = kzalloc(sizeof(struct brcmf_bus), GFP_ATOMIC); if (!bus) { ret = -ENOMEM; goto fail; } bus->dev = dev; bus_pub->bus = bus; bus->bus_priv.usb = bus_pub; dev_set_drvdata(dev, bus); bus->ops = &brcmf_usb_bus_ops; bus->proto_type = BRCMF_PROTO_BCDC; bus->always_use_fws_queue = true; #ifdef CONFIG_PM bus->wowl_supported = true; #endif if (!brcmf_usb_dlneeded(devinfo)) { ret = brcmf_usb_bus_setup(devinfo); if (ret) goto fail; /* we are done */ mutex_unlock(&devinfo->dev_init_lock); return 0; } bus->chip = bus_pub->devid; bus->chiprev = bus_pub->chiprev; /* request firmware here */ ret = brcmf_fw_get_firmwares(dev, 0, brcmf_usb_get_fwname(devinfo), NULL, brcmf_usb_probe_phase2); if (ret) { brcmf_err("firmware request failed: %d\n", ret); goto fail; } return 0; fail: /* Release resources in reverse order */ kfree(bus); brcmf_usb_detach(devinfo); return ret; }
static void brcmf_usb_disconnect_cb(struct brcmf_usbdev_info *devinfo) { if (!devinfo) return; brcmf_dbg(USB, "Enter, bus_pub %p\n", devinfo); brcmf_detach(devinfo->dev); kfree(devinfo->bus_pub.bus); brcmf_usb_detach(devinfo); }
static void brcmf_usb_disconnect_cb(struct brcmf_usbdev *bus_pub) { if (!bus_pub) return; brcmf_dbg(TRACE, "enter: bus_pub %p\n", bus_pub); brcmf_detach(bus_pub->devinfo->dev); kfree(bus_pub->bus); brcmf_usb_detach(bus_pub); }
static int brcmf_usb_probe_cb(struct device *dev, const char *desc, u32 bustype, u32 hdrlen) { struct brcmf_bus *bus = NULL; struct brcmf_usbdev *bus_pub = NULL; int ret; bus_pub = brcmf_usb_attach(BRCMF_USB_NRXQ, BRCMF_USB_NTXQ, dev); if (!bus_pub) { ret = -ENODEV; goto fail; } bus = kzalloc(sizeof(struct brcmf_bus), GFP_ATOMIC); if (!bus) { ret = -ENOMEM; goto fail; } bus_pub->bus = bus; bus->brcmf_bus_txdata = brcmf_usb_tx; bus->brcmf_bus_init = brcmf_usb_up; bus->brcmf_bus_stop = brcmf_usb_down; bus->brcmf_bus_txctl = brcmf_usb_tx_ctlpkt; bus->brcmf_bus_rxctl = brcmf_usb_rx_ctlpkt; bus->type = bustype; bus->bus_priv.usb = bus_pub; dev_set_drvdata(dev, bus); /* Attach to the common driver interface */ ret = brcmf_attach(hdrlen, dev); if (ret) { brcmf_dbg(ERROR, "dhd_attach failed\n"); goto fail; } ret = brcmf_bus_start(dev); if (ret == -ENOLINK) { brcmf_dbg(ERROR, "dongle is not responding\n"); brcmf_detach(dev); goto fail; } return 0; fail: /* Release resources in reverse order */ if (bus_pub) brcmf_usb_detach(bus_pub); kfree(bus); return ret; }
static int brcmf_usb_probe_cb(struct brcmf_usbdev_info *devinfo) { struct brcmf_bus *bus = NULL; struct brcmf_usbdev *bus_pub = NULL; struct device *dev = devinfo->dev; struct brcmf_fw_request *fwreq; int ret; brcmf_dbg(USB, "Enter\n"); bus_pub = brcmf_usb_attach(devinfo, BRCMF_USB_NRXQ, BRCMF_USB_NTXQ); if (!bus_pub) return -ENODEV; bus = kzalloc(sizeof(struct brcmf_bus), GFP_ATOMIC); if (!bus) { ret = -ENOMEM; goto fail; } bus->dev = dev; bus_pub->bus = bus; bus->bus_priv.usb = bus_pub; dev_set_drvdata(dev, bus); bus->ops = &brcmf_usb_bus_ops; bus->proto_type = BRCMF_PROTO_BCDC; bus->always_use_fws_queue = true; #ifdef CONFIG_PM bus->wowl_supported = true; #endif devinfo->settings = brcmf_get_module_param(bus->dev, BRCMF_BUSTYPE_USB, bus_pub->devid, bus_pub->chiprev); if (!devinfo->settings) { ret = -ENOMEM; goto fail; } if (!brcmf_usb_dlneeded(devinfo)) { ret = brcmf_attach(devinfo->dev, devinfo->settings); if (ret) goto fail; /* we are done */ complete(&devinfo->dev_init_done); return 0; } bus->chip = bus_pub->devid; bus->chiprev = bus_pub->chiprev; fwreq = brcmf_usb_prepare_fw_request(devinfo); if (!fwreq) { ret = -ENOMEM; goto fail; } /* request firmware here */ ret = brcmf_fw_get_firmwares(dev, fwreq, brcmf_usb_probe_phase2); if (ret) { brcmf_err("firmware request failed: %d\n", ret); kfree(fwreq); goto fail; } return 0; fail: /* Release resources in reverse order */ kfree(bus); brcmf_usb_detach(devinfo); return ret; }
static struct brcmf_usbdev *brcmf_usb_attach(int nrxq, int ntxq, struct device *dev) { struct brcmf_usbdev_info *devinfo; devinfo = kzalloc(sizeof(struct brcmf_usbdev_info), GFP_ATOMIC); if (devinfo == NULL) return NULL; devinfo->bus_pub.nrxq = nrxq; devinfo->rx_low_watermark = nrxq / 2; devinfo->bus_pub.devinfo = devinfo; devinfo->bus_pub.ntxq = ntxq; /* flow control when too many tx urbs posted */ devinfo->tx_low_watermark = ntxq / 4; devinfo->tx_high_watermark = devinfo->tx_low_watermark * 3; devinfo->dev = dev; devinfo->usbdev = usbdev_probe_info.usb; devinfo->tx_pipe = usbdev_probe_info.tx_pipe; devinfo->rx_pipe = usbdev_probe_info.rx_pipe; devinfo->rx_pipe2 = usbdev_probe_info.rx_pipe2; devinfo->intr_pipe = usbdev_probe_info.intr_pipe; devinfo->interval = usbdev_probe_info.interval; devinfo->intr_size = usbdev_probe_info.intr_size; memcpy(&devinfo->probe_info, &usbdev_probe_info, sizeof(struct brcmf_usb_probe_info)); devinfo->bus_pub.bus_mtu = BRCMF_USB_MAX_PKT_SIZE; /* Initialize other structure content */ init_waitqueue_head(&devinfo->ioctl_resp_wait); /* Initialize the spinlocks */ spin_lock_init(&devinfo->qlock); INIT_LIST_HEAD(&devinfo->rx_freeq); INIT_LIST_HEAD(&devinfo->rx_postq); INIT_LIST_HEAD(&devinfo->tx_freeq); INIT_LIST_HEAD(&devinfo->tx_postq); devinfo->rx_reqs = brcmf_usbdev_qinit(&devinfo->rx_freeq, nrxq); if (!devinfo->rx_reqs) goto error; devinfo->tx_reqs = brcmf_usbdev_qinit(&devinfo->tx_freeq, ntxq); if (!devinfo->tx_reqs) goto error; devinfo->intr_urb = usb_alloc_urb(0, GFP_ATOMIC); if (!devinfo->intr_urb) { brcmf_dbg(ERROR, "usb_alloc_urb (intr) failed\n"); goto error; } devinfo->ctl_urb = usb_alloc_urb(0, GFP_ATOMIC); if (!devinfo->ctl_urb) { brcmf_dbg(ERROR, "usb_alloc_urb (ctl) failed\n"); goto error; } devinfo->rxctl_deferrespok = 0; devinfo->bulk_urb = usb_alloc_urb(0, GFP_ATOMIC); if (!devinfo->bulk_urb) { brcmf_dbg(ERROR, "usb_alloc_urb (bulk) failed\n"); goto error; } init_waitqueue_head(&devinfo->wait); if (!brcmf_usb_dlneeded(devinfo)) return &devinfo->bus_pub; brcmf_dbg(TRACE, "start fw downloading\n"); if (brcmf_usb_get_fw(devinfo)) goto error; if (brcmf_usb_fw_download(devinfo)) goto error; return &devinfo->bus_pub; error: brcmf_dbg(ERROR, "failed!\n"); brcmf_usb_detach(&devinfo->bus_pub); return NULL; }