static int speedtch_find_firmware(struct usbatm_data *usbatm, struct usb_interface *intf, int phase, const struct firmware **fw_p) { struct device *dev = &intf->dev; const u16 bcdDevice = le16_to_cpu(interface_to_usbdev(intf)->descriptor.bcdDevice); const u8 major_revision = bcdDevice >> 8; const u8 minor_revision = bcdDevice & 0xff; char buf[24]; sprintf(buf, "speedtch-%d.bin.%x.%02x", phase, major_revision, minor_revision); usb_dbg(usbatm, "%s: looking for %s\n", __func__, buf); if (request_firmware(fw_p, buf, dev)) { sprintf(buf, "speedtch-%d.bin.%x", phase, major_revision); usb_dbg(usbatm, "%s: looking for %s\n", __func__, buf); if (request_firmware(fw_p, buf, dev)) { sprintf(buf, "speedtch-%d.bin", phase); usb_dbg(usbatm, "%s: looking for %s\n", __func__, buf); if (request_firmware(fw_p, buf, dev)) { usb_err(usbatm, "%s: no stage %d firmware found!\n", __func__, phase); return -ENOENT; } } } usb_info(usbatm, "found stage %d firmware %s\n", phase, buf); return 0; }
void usbd_tx_complete (struct usb_endpoint_instance *endpoint) { if (endpoint) { struct urb *tx_urb = endpoint->tx_urb; usb_info("%s \n", __FUNCTION__); /* if we have a tx_urb advance or reset, finish if complete */ if (tx_urb) { int sent = endpoint->last; endpoint->sent += sent; endpoint->last -= sent; if( (endpoint->tx_urb->actual_length - endpoint->sent) <= 0 ) { usb_info("%s: all send\n", __FUNCTION__); tx_urb->stage = URB_COMPLETE; tx_urb->actual_length = 0; endpoint->sent = 0; endpoint->last = 0; /* Remove from active, save for re-use */ // urb_detach(tx_urb); // urb_append(&endpoint->done, tx_urb); // endpoint->tx_urb = first_urb_detached(&endpoint->tx); // if( endpoint->tx_urb ) { // endpoint->tx_queue--; // usbdbg("got urb from tx list"); // } // if( !endpoint->tx_urb ) { // /*usbdbg("taking urb from done list"); */ // endpoint->tx_urb = first_urb_detached(&endpoint->done); // } // if( !endpoint->tx_urb ) { // usbdbg("allocating new urb for tx_urb"); // endpoint->tx_urb = usbd_alloc_urb(tx_urb->device, endpoint); // } } } } }
static void copy_config (struct urb *urb, void *data, int max_length, int max_buf) { int available; int length; length = max_length; available = /*urb->buffer_length */ max_buf - urb->actual_length; if (available <= 0) return; if (length > available) { length = available; } usb_info("%s : length =%d", __FUNCTION__, length); memcpy (urb->buffer + urb->actual_length, data, length); urb->actual_length += length; }
static int cxacru_find_firmware(struct cxacru_data *instance, char *phase, const struct firmware **fw_p) { struct usbatm_data *usbatm = instance->usbatm; struct device *dev = &usbatm->usb_intf->dev; char buf[16]; sprintf(buf, "cxacru-%s.bin", phase); dbg("cxacru_find_firmware: looking for %s", buf); if (request_firmware(fw_p, buf, dev)) { usb_dbg(usbatm, "no stage %s firmware found\n", phase); return -ENOENT; } usb_info(usbatm, "found firmware %s\n", buf); return 0; }
static void cxacru_upload_firmware(struct cxacru_data *instance, const struct firmware *fw, const struct firmware *bp) { int ret; struct usbatm_data *usbatm = instance->usbatm; struct usb_device *usb_dev = usbatm->usb_dev; __le16 signature[] = { usb_dev->descriptor.idVendor, usb_dev->descriptor.idProduct }; __le32 val; dbg("cxacru_upload_firmware"); /* FirmwarePllFClkValue */ val = cpu_to_le32(instance->modem_type->pll_f_clk); ret = cxacru_fw(usb_dev, FW_WRITE_MEM, 0x2, 0x0, PLLFCLK_ADDR, (u8 *) &val, 4); if (ret) { usb_err(usbatm, "FirmwarePllFClkValue failed: %d\n", ret); return; } /* FirmwarePllBClkValue */ val = cpu_to_le32(instance->modem_type->pll_b_clk); ret = cxacru_fw(usb_dev, FW_WRITE_MEM, 0x2, 0x0, PLLBCLK_ADDR, (u8 *) &val, 4); if (ret) { usb_err(usbatm, "FirmwarePllBClkValue failed: %d\n", ret); return; } /* Enable SDRAM */ val = cpu_to_le32(SDRAM_ENA); ret = cxacru_fw(usb_dev, FW_WRITE_MEM, 0x2, 0x0, SDRAMEN_ADDR, (u8 *) &val, 4); if (ret) { usb_err(usbatm, "Enable SDRAM failed: %d\n", ret); return; } /* Firmware */ usb_info(usbatm, "loading firmware\n"); ret = cxacru_fw(usb_dev, FW_WRITE_MEM, 0x2, 0x0, FW_ADDR, fw->data, fw->size); if (ret) { usb_err(usbatm, "Firmware upload failed: %d\n", ret); return; } /* Boot ROM patch */ if (instance->modem_type->boot_rom_patch) { usb_info(usbatm, "loading boot ROM patch\n"); ret = cxacru_fw(usb_dev, FW_WRITE_MEM, 0x2, 0x0, BR_ADDR, bp->data, bp->size); if (ret) { usb_err(usbatm, "Boot ROM patching failed: %d\n", ret); return; } } /* Signature */ ret = cxacru_fw(usb_dev, FW_WRITE_MEM, 0x2, 0x0, SIG_ADDR, (u8 *) signature, 4); if (ret) { usb_err(usbatm, "Signature storing failed: %d\n", ret); return; } usb_info(usbatm, "starting device\n"); if (instance->modem_type->boot_rom_patch) { val = cpu_to_le32(BR_ADDR); ret = cxacru_fw(usb_dev, FW_WRITE_MEM, 0x2, 0x0, BR_STACK_ADDR, (u8 *) &val, 4); } else { ret = cxacru_fw(usb_dev, FW_GOTO_MEM, 0x0, 0x0, FW_ADDR, NULL, 0); } if (ret) { usb_err(usbatm, "Passing control to firmware failed: %d\n", ret); return; } /* Delay to allow firmware to start up. */ msleep_interruptible(1000); usb_clear_halt(usb_dev, usb_sndbulkpipe(usb_dev, CXACRU_EP_CMD)); usb_clear_halt(usb_dev, usb_rcvbulkpipe(usb_dev, CXACRU_EP_CMD)); usb_clear_halt(usb_dev, usb_sndbulkpipe(usb_dev, CXACRU_EP_DATA)); usb_clear_halt(usb_dev, usb_rcvbulkpipe(usb_dev, CXACRU_EP_DATA)); ret = cxacru_cm(instance, CM_REQUEST_CARD_GET_STATUS, NULL, 0, NULL, 0); if (ret < 0) { usb_err(usbatm, "modem failed to initialize: %d\n", ret); return; } }
static int ep0_get_descriptor (struct usb_device_instance *device, struct urb *urb, int max, int descriptor_type, int index) { char *cp; urb->actual_length = 0; cp = (char*)urb->buffer; switch (descriptor_type) { case USB_DESCRIPTOR_TYPE_DEVICE: { struct usb_device_descriptor *device_descriptor; if (!(device_descriptor = usbd_device_device_descriptor(device))) return -1; copy_config(urb, device_descriptor, sizeof(struct usb_device_descriptor), max); } break; case USB_DESCRIPTOR_TYPE_CONFIGURATION: { struct usb_configuration_descriptor *configuration_descriptor; struct usb_device_descriptor *device_descriptor; usb_info("get configuration, index = %d\n", index); if (!(device_descriptor = usbd_device_device_descriptor (device))) return -1; if (index >= device_descriptor->bNumConfigurations) { return -1; } if (!(configuration_descriptor = usbd_device_configuration_descriptor (device, index))) return -1; copy_config (urb, configuration_descriptor, cpu_to_le16(configuration_descriptor->wTotalLength), max); } break; case USB_DESCRIPTOR_TYPE_STRING: { struct usb_string_descriptor *string_descriptor; usb_info("get string, index = %d, max = %d\n", index, max); string_descriptor = usbd_get_string (index); // if (!(string_descriptor)) // return -1; copy_config (urb, string_descriptor, string_descriptor->bLength, max); } break; case USB_DESCRIPTOR_TYPE_DEVICE_QUALIFIER: //TODO case USB_DESCRIPTOR_TYPE_OTHER_SPEED_CONFIGURATION: //TODO case USB_DESCRIPTOR_TYPE_INTERFACE: //should not see this case USB_DESCRIPTOR_TYPE_ENDPOINT: //should not see this default: return -1; } return 0; }
/** called to indicate URB has been received * @param[in] urb: pointer to struct urb * * Check if this is a setup packet, process the device request, put results * back into the urb and return zero or non-zero to indicate success (DATA) * or failure (STALL). * */ int ep0_recv_setup(struct urb* urb) { struct usb_device_request *request; struct usb_device_instance *device; int address; //sanity check if (!urb || !urb->device) return -1; request = &urb->device_request; device = urb->device; if ((request->bmRequestType & USB_REQ_TYPE_MASK) != USB_REQ_TYPE_STANDARD){ return -1; } /* * handle standard request */ // do some filter switch (device->device_state) { case STATE_CREATED: case STATE_ATTACHED: case STATE_POWERED: break; case STATE_INIT: case STATE_DEFAULT: switch (request->bRequest) { case USB_REQ_GET_STATUS: case USB_REQ_GET_INTERFACE: case USB_REQ_SYNCH_FRAME: case USB_REQ_CLEAR_FEATURE: case USB_REQ_SET_FEATURE: case USB_REQ_SET_DESCRIPTOR: case USB_REQ_SET_INTERFACE: // these request not allowed in DEFAULT state return -1; case USB_REQ_SET_CONFIGURATION: case USB_REQ_SET_ADDRESS: case USB_REQ_GET_DESCRIPTOR: case USB_REQ_GET_CONFIGURATION: break; } case STATE_ADDRESSED: case STATE_CONFIGURED: break; case STATE_UNKNOWN: return -1; } /* handle all requests that return data (direction bit set on bmRequestType) */ if ((request->bmRequestType & USB_REQ_DIRECTION_MASK) == USB_REQ_DEVICE2HOST) { // device to host switch (request->bRequest) { case USB_REQ_GET_DESCRIPTOR: usb_info("USB_REQ_GET_DESCRIPTOR\n"); return ep0_get_descriptor(device, urb, le16_to_cpu(request->wLength), le16_to_cpu(request->wValue) >> 8, le16_to_cpu(request->wValue) & 0xff); case USB_REQ_GET_CONFIGURATION: usb_info("USB_REQ_GET_CONFIGURATION\n"); return ep0_get_one(device, urb, device->configuration); case USB_REQ_GET_INTERFACE: usb_info("USB_REQ_GET_INTERFACE\n"); return ep0_get_one(device, urb, device->alternate); case USB_REQ_GET_STATUS: usb_info("USB_REQ_GET_STATUS\n"); return ep0_get_status(device, urb, request->wIndex, request->bmRequestType & USB_REQ_RECIPIENT_MASK); case USB_REQ_SYNCH_FRAME: return -1; default: return -1; } } else { /* handle the requests that do not return data */ switch (request->bRequest) {