static void brcmf_usb_probe_phase2(struct device *dev, int ret, struct brcmf_fw_request *fwreq) { struct brcmf_bus *bus = dev_get_drvdata(dev); struct brcmf_usbdev_info *devinfo = bus->bus_priv.usb->devinfo; const struct firmware *fw; if (ret) goto error; brcmf_dbg(USB, "Start fw downloading\n"); fw = fwreq->items[BRCMF_USB_FW_CODE].binary; kfree(fwreq); ret = check_file(fw->data); if (ret < 0) { brcmf_err("invalid firmware\n"); release_firmware(fw); goto error; } devinfo->image = fw->data; devinfo->image_len = fw->size; ret = brcmf_usb_fw_download(devinfo); release_firmware(fw); if (ret) goto error; /* Attach to the common driver interface */ ret = brcmf_attach(devinfo->dev, devinfo->settings); if (ret) goto error; complete(&devinfo->dev_init_done); return; error: brcmf_dbg(TRACE, "failed: dev=%s, err=%d\n", dev_name(dev), ret); complete(&devinfo->dev_init_done); device_release_driver(dev); }
static void brcmf_usb_probe_phase2(struct device *dev, const struct firmware *fw, void *nvram, u32 nvlen) { struct brcmf_bus *bus = dev_get_drvdata(dev); struct brcmf_usbdev_info *devinfo; int ret; brcmf_dbg(USB, "Start fw downloading\n"); devinfo = bus->bus_priv.usb->devinfo; ret = check_file(fw->data); if (ret < 0) { brcmf_err("invalid firmware\n"); release_firmware(fw); goto error; } devinfo->image = fw->data; devinfo->image_len = fw->size; ret = brcmf_usb_fw_download(devinfo); release_firmware(fw); if (ret) goto error; ret = brcmf_usb_bus_setup(devinfo); if (ret) goto error; mutex_unlock(&devinfo->dev_init_lock); return; error: brcmf_dbg(TRACE, "failed: dev=%s, err=%d\n", dev_name(dev), ret); mutex_unlock(&devinfo->dev_init_lock); device_release_driver(dev); }
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; }