// Call usb_read using a buffer having a multiple of usb_get_max_packet_size() bytes // to avoid overflow. See http://libusb.sourceforge.net/api-1.0/packetoverflow.html. static int UsbReadPayload(usb_handle* h, apacket* p) { D("UsbReadPayload(%d)", p->msg.data_length); if (p->msg.data_length > MAX_PAYLOAD) { return -1; } #if CHECK_PACKET_OVERFLOW size_t usb_packet_size = usb_get_max_packet_size(h); // Round the data length up to the nearest packet size boundary. // The device won't send a zero packet for packet size aligned payloads, // so don't read any more packets than needed. size_t len = p->msg.data_length; size_t rem_size = len % usb_packet_size; if (rem_size) { len += usb_packet_size - rem_size; } p->payload.resize(len); int rc = usb_read(h, &p->payload[0], p->payload.size()); if (rc != static_cast<int>(p->msg.data_length)) { return -1; } p->payload.resize(rc); return rc; #else p->payload.resize(p->msg.data_length); return usb_read(h, &p->payload[0], p->payload.size()); #endif }
void usbd_on_out_readed(EP_CLASS ep, void* param) { USBD* usbd = (USBD*)param; #if (USB_DEBUG_FLOW) printf("USB EP0 OUT RX\n\r"); #endif switch (usbd->setup_state) { case USB_SETUP_STATE_DATA_OUT: usbd->setup_state = USB_SETUP_STATE_STATUS_IN; usb_write(usbd->idx, EP_IN0, NULL, 0); break; case USB_SETUP_STATE_STATUS_OUT: usbd->setup_state = USB_SETUP_STATE_REQUEST; usb_read(USB_1, EP_OUT0, usbd->control.buf, usbd->ep0_size); usbd_request_completed(usbd); break; default: usbd->setup_state = USB_SETUP_STATE_REQUEST; usb_read(USB_1, EP_OUT0, usbd->control.buf, usbd->ep0_size); #if (USB_DEBUG_ERRORS) dbg_invalid_state(USB_SETUP_STATE_DATA_OUT, usbd->setup_state); #endif break; } }
/** Read to request from FIFO (max read == bytes in fifo) * Return: 0 = still running, 1 = completed, negative = errno * NOTE: INDEX register must be set for EP */ static int read_fifo(struct lh7a40x_ep *ep, struct lh7a40x_request *req) { u32 csr; u8 *buf; unsigned bufferspace, count, is_short; volatile u32 *fifo = (volatile u32 *)ep->fifo; /* make sure there's a packet in the FIFO. */ csr = usb_read(ep->csr1); if (!(csr & USB_OUT_CSR1_OUT_PKT_RDY)) { DEBUG("%s: Packet NOT ready!\n", __func__); return -EINVAL; } buf = req->req.buf + req->req.actual; prefetchw(buf); bufferspace = req->req.length - req->req.actual; /* read all bytes from this packet */ count = usb_read(USB_OUT_FIFO_WC1); req->req.actual += min(count, bufferspace); is_short = (count < ep->ep.maxpacket); DEBUG("read %s %02x, %d bytes%s req %p %d/%d\n", ep->ep.name, csr, count, is_short ? "/S" : "", req, req->req.actual, req->req.length); while (likely(count-- != 0)) { u8 byte = (u8) (*fifo & 0xff); if (unlikely(bufferspace == 0)) { /* this happens when the driver's buffer * is smaller than what the host sent. * discard the extra data. */ if (req->req.status != -EOVERFLOW) printk(KERN_WARNING "%s overflow %d\n", ep->ep.name, count); req->req.status = -EOVERFLOW; } else { *buf++ = byte; bufferspace--; } } usb_clear(USB_OUT_CSR1_OUT_PKT_RDY, ep->csr1); /* completion */ if (is_short || req->req.actual == req->req.length) { done(ep, req, 0); usb_set(USB_OUT_CSR1_FIFO_FLUSH, ep->csr1); if (list_empty(&ep->queue)) pio_irq_disable(ep_index(ep)); return 1; } /* finished that packet. the next one may be waiting... */ return 0; }
static int remote_read(apacket *p, atransport *t) { if(usb_read(t->usb, &p->msg, sizeof(amessage))){ D("remote usb: read terminated (message)\n"); return -1; } fix_endians(p); if(check_header(p)) { D("remote usb: check_header failed\n"); return -1; } if(p->msg.data_length) { if(usb_read(t->usb, p->data, p->msg.data_length)){ D("remote usb: terminated (data)\n"); return -1; } } if(check_data(p)) { D("remote usb: check_data failed\n"); return -1; } return 0; }
static u8 read_epcs(struct rt_ep_struct *rt_ep) { int idx = EP_NO(rt_ep); int dir = EP_DIR(rt_ep); if(idx == 0) return usb_read(EP0CS); return (dir == EP_IN ? usb_read(0x7 + idx*8) : usb_read(0x3 + idx*8) ); }
/** Read to request from FIFO (max read == bytes in fifo) * Return: 0 = still running, 1 = completed, negative = errno */ static int read_fifo(struct elfin_ep *ep, struct elfin_request *req) { u32 csr; u8 *buf; unsigned bufferspace, count, is_short; void* fifo = ep->fifo; /* make sure there's a packet in the FIFO. */ csr = usb_read(ep->csr1, ep_index(ep)); if (!(csr & S3C2410_UDC_OCSR1_PKTRDY)) { DPRINTK("%s: Packet NOT ready!\n", __FUNCTION__); return -EINVAL; } buf = req->req.buf + req->req.actual; prefetchw(buf); bufferspace = req->req.length - req->req.actual; /* read all bytes from this packet */ count = (( (usb_read(S3C2410_UDC_OUT_FIFO_CNT2_REG, ep_index(ep)) & 0xff ) << 8) | (usb_read(S3C2410_UDC_OUT_FIFO_CNT1_REG, ep_index(ep)) & 0xff)); req->req.actual += min(count, bufferspace); is_short = (count < ep->ep.maxpacket); DPRINTK("read %s %02x, %d bytes%s req %p %d/%d\n", ep->ep.name, csr, count, is_short ? "/S" : "", req, req->req.actual, req->req.length); while (likely(count-- != 0)) { u8 byte = (u8) __raw_readl(fifo); if (unlikely(bufferspace == 0)) { /* this happens when the driver's buffer * is smaller than what the host sent. * discard the extra data. */ if (req->req.status != -EOVERFLOW) printk("%s overflow %d\n", ep->ep.name, count); req->req.status = -EOVERFLOW; } else { *buf++ = byte; bufferspace--; } } usb_clear(S3C2410_UDC_OCSR1_PKTRDY, ep->csr1, ep_index(ep)); /* completion */ if (is_short || req->req.actual == req->req.length) { done(ep, req, 0); return 1; } /* finished that packet. the next one may be waiting... */ return 0; }
static u16 read_outbc(int epnum) { u16 low, high = 0; if(epnum == 0){ /* EP0 */ low = usb_read(OUT0BC); }else{ low = usb_read(epnum * 8); high = usb_read((epnum * 8)+1); } return (low | (high << 8)); }
static int usb_boot(usb_handle *usb, int fastboot_mode, void *data, unsigned sz, void *data2, unsigned sz2) { uint32_t msg_boot = 0xF0030002; uint32_t msg_size = sz; uint32_t param = 0; fprintf(stderr, "sending 2ndstage to target...\n"); usb_write(usb, &msg_boot, sizeof(msg_boot)); usb_write(usb, &msg_size, sizeof(msg_size)); usb_write(usb, data, sz); if ((data2) || (fastboot_mode > 0)) { fprintf(stderr,"waiting for 2ndstage response...\n"); usb_read(usb, &msg_size, sizeof(msg_size)); if (msg_size != 0xaabbccdd) { fprintf(stderr, "unexpected 2ndstage response\n"); return -1; } if (fastboot_mode > 2) { param = fastboot_mode; usb_write(usb, ¶m, sizeof(param)); } /* In fastboot mode, we stay in SRAM so don't download data2 to the target. Return back from here */ if (fastboot_mode == 1) { fprintf(stderr, "received 2ndstage response...\n"); return 0; } msg_size = sz2; usb_write(usb, &msg_size, sizeof(msg_size)); usb_read(usb, ¶m, sizeof(param)); if (param != 0xaabbccdd) { fprintf(stderr, "unexpected 2ndstage response\n"); return -1; } fprintf(stderr, "sending image to target...size " "(%d-B/%d-KB/%d-MB)\n", msg_size, msg_size/1024, msg_size/(1024 * 1024)); usb_write(usb, data2, sz2); } return 0; }
/* ******************************************************************************* * Data tansfer over USB functions ******************************************************************************* */ static int read_ep0_fifo(struct rt_ep_struct *rt_ep, struct rt_request *req) { u8 *buf; int byte_count, req_bufferspace, count, i; DBG; if(!in_irq()) FATAL_ERROR("not irq context."); byte_count = read_outbc(EP_NO(rt_ep)); req_bufferspace = req->req.length - req->req.actual; buf = req->req.buf + req->req.actual; if(!req_bufferspace) FATAL_ERROR("zlp"); if(byte_count > req_bufferspace) FATAL_ERROR("buffer overflow, byte_count=%d, req->req.length=%d, req->req.actual=%d\n", byte_count, req->req.length ,req->req.actual); count = min(byte_count, req_bufferspace); for (i = 0; i < count; i++){ *buf = usb_read(EP0OUTDAT+i); buf++; } req->req.actual += count; return count; }
u16 cdc_rx(u8 *buf, u16 size){ // The first byte is a control byte. if(cdc_rx_size() <= size){ cdc_rx_need_skip = 1; } return usb_read(buf, size, CDC_DATA_EP_OUT); }
/** * lh7a40x_in_epn - handle IN interrupt */ static void lh7a40x_in_epn(struct lh7a40x_udc *dev, u32 ep_idx, u32 intr) { u32 csr; struct lh7a40x_ep *ep = &dev->ep[ep_idx]; struct lh7a40x_request *req; usb_set_index(ep_idx); csr = usb_read(ep->csr1); DEBUG("%s: %d, csr %x\n", __FUNCTION__, ep_idx, csr); if (csr & USB_IN_CSR1_SENT_STALL) { DEBUG("USB_IN_CSR1_SENT_STALL\n"); usb_set(USB_IN_CSR1_SENT_STALL /*|USB_IN_CSR1_SEND_STALL */ , ep->csr1); return; } if (!ep->desc) { DEBUG("%s: NO EP DESC\n", __FUNCTION__); return; } if (list_empty(&ep->queue)) req = 0; else req = list_entry(ep->queue.next, struct lh7a40x_request, queue); DEBUG("req: %p\n", req); if (!req) return; write_fifo(ep, req); }
/** * elfin_in_epn - handle IN interrupt */ static void elfin_in_epn(struct elfin_udc *dev, u32 ep_idx) { u32 csr; struct elfin_ep *ep = &dev->ep[ep_idx]; struct elfin_request *req; csr = usb_read(ep->csr1, ep_index(ep)); DPRINTK("%s: %d, csr %x\n", __FUNCTION__, ep_idx, csr); if (csr & S3C2410_UDC_ICSR1_SENTSTL) { printk("S3C2410_UDC_ICSR1_SENTSTL\n"); usb_set(S3C2410_UDC_ICSR1_SENTSTL /*| S3C2410_UDC_ICSR1_SENDSTL */ , ep->csr1, ep_index(ep)); return; } if (!ep->desc) { DPRINTK("%s: NO EP DESC\n", __FUNCTION__); return; } if (list_empty(&ep->queue)) req = 0; else req = list_entry(ep->queue.next, struct elfin_request, queue); DPRINTK("req: %p\n", req); if (!req) return; write_fifo(ep, req); }
int getUSBPacket(int id, struct mechanism *mech) { int result, type; unsigned char buffer[MAX_IN_LENGTH]; //Read USB Packet result = usb_read(id,buffer,IN_LENGTH); // -- Check for read errors -- if (result < 0){ return result; } // No data or something. Boo. else if ((result == 0) || (result != IN_LENGTH)) return -EIO; // -- Good packet so process it -- type = buffer[0]; //Load in the data from the USB packet switch (type) { //Handle and Encoder USB packet case ENC: processEncoderPacket(mech, buffer); break; } return 0; }
void on_msc_sent(EP_CLASS ep, void *param) { USB_MSC* msc = (USB_MSC*)param; unsigned int block_size; switch (msc->state) { case MSC_STATE_DATA: queue_release_buffer(msc->queue, msc->current_buf); msc->current_buf = NULL; if (msc->scsi_transferred < msc->scsi_requested) { ASSERT(!queue_is_empty(msc->queue)); msc->current_buf = queue_pull_ms(msc->queue, INFINITE); block_size = msc->scsi_requested - msc->scsi_transferred; if (block_size > msc->block_size) block_size = msc->block_size; msc->scsi_transferred += block_size; usb_write(usbd_get_usb(msc->usbd), EP_IN(msc->ep_num), msc->current_buf, block_size); } else event_set(msc->event); break; case MSC_STATE_CSW: msc->state = MSC_STATE_CSW_SENT; msc_send_csw(msc); break; case MSC_STATE_CSW_SENT: msc->state = MSC_STATE_CBW; //same buffer will be used for next cbw usb_read(usbd_get_usb(msc->usbd), EP_OUT(msc->ep_num), msc->current_buf, CBW_SIZE); break; default: break; } }
static void rt_ep_irq_disable(struct rt_ep_struct *rt_ep) { u8 reg; u8 idx = EP_NO(rt_ep); u8 dir = EP_DIR(rt_ep); if(idx == 0 /* ep0 */){ usb_write(IN07IEN, (usb_read(IN07IEN) & ~(0x1)) ); usb_write(OUT07IEN, (usb_read(OUT07IEN) & ~(0x1)) ); }else{ reg = usb_read(dir ? IN07IEN : OUT07IEN); reg = reg & ~(0x1 << idx); usb_write(dir == EP_IN ? IN07IEN : OUT07IEN, reg); reg = usb_read(dir ? IN07IEN : OUT07IEN); } }
static bool hfa_get_header(struct cgpu_info *hashfast, struct hf_header *h, uint8_t *computed_crc) { int amount, ret, orig_len, len, ofs = 0; cgtimer_t ts_start; char buf[512]; char *header; orig_len = len = sizeof(*h); /* Read for up to 200ms till we find the first occurrence of HF_PREAMBLE * though it should be the first byte unless we get woefully out of * sync. */ cgtimer_time(&ts_start); do { cgtimer_t ts_now, ts_diff; cgtimer_time(&ts_now); cgtimer_sub(&ts_now, &ts_start, &ts_diff); if (cgtimer_to_ms(&ts_diff) > 200) return false; ret = usb_read(hashfast, buf + ofs, len, &amount, C_HF_GETHEADER); if (unlikely(ret && ret != LIBUSB_ERROR_TIMEOUT)) return false; ofs += amount; header = memchr(buf, HF_PREAMBLE, ofs); if (header) len -= ofs - (header - buf); } while (len); memcpy(h, header, orig_len); *computed_crc = hfa_crc8((uint8_t *)h); return true; }
/* * done - retire a request; caller blocked irqs * INDEX register is preserved to keep same */ static void done(struct lh7a40x_ep *ep, struct lh7a40x_request *req, int status) { unsigned int stopped = ep->stopped; u32 index; DEBUG("%s, %p\n", __FUNCTION__, ep); list_del_init(&req->queue); if (likely(req->req.status == -EINPROGRESS)) req->req.status = status; else status = req->req.status; if (status && status != -ESHUTDOWN) DEBUG("complete %s req %p stat %d len %u/%u\n", ep->ep.name, &req->req, status, req->req.actual, req->req.length); /* don't modify queue heads during completion callback */ ep->stopped = 1; /* Read current index (completion may modify it) */ index = usb_read(USB_INDEX); spin_unlock(&ep->dev->lock); req->req.complete(&ep->ep, &req->req); spin_lock(&ep->dev->lock); /* Restore index */ usb_set_index(index); ep->stopped = stopped; }
int main(int argc, char **argv) { //Pass Interrupt Signal to our handler signal(SIGINT, sighandler); libusb_init(&ctx); libusb_set_debug(ctx, 3); //Open Device with VendorID and ProductID handle = libusb_open_device_with_vid_pid(ctx, USB_VENDOR_ID, USB_PRODUCT_ID); if (!handle) { perror("device not found"); return 1; } int r = 1; //Claim Interface 0 from the device r = libusb_claim_interface(handle, 0); if (r < 0) { fprintf(stderr, "usb_claim_interface error %d\n", r); return 2; } printf("Interface claimed\n"); while (1){ usb_read(); // usb_write(); } //never reached libusb_close(handle); libusb_exit(NULL); return 0; }
static void lh7a40x_out_epn(struct lh7a40x_udc *dev, u32 ep_idx, u32 intr) { struct lh7a40x_ep *ep = &dev->ep[ep_idx]; struct lh7a40x_request *req; DEBUG("%s: %d\n", __func__, ep_idx); usb_set_index(ep_idx); if (ep->desc) { u32 csr; csr = usb_read(ep->csr1); while ((csr = usb_read(ep-> csr1)) & (USB_OUT_CSR1_OUT_PKT_RDY | USB_OUT_CSR1_SENT_STALL)) { DEBUG("%s: %x\n", __func__, csr); if (csr & USB_OUT_CSR1_SENT_STALL) { DEBUG("%s: stall sent, flush fifo\n", __func__); /* usb_set(USB_OUT_CSR1_FIFO_FLUSH, ep->csr1); */ flush(ep); } else if (csr & USB_OUT_CSR1_OUT_PKT_RDY) { if (list_empty(&ep->queue)) req = 0; else req = list_entry(ep->queue.next, struct lh7a40x_request, queue); if (!req) { printk(KERN_WARNING "%s: NULL REQ %d\n", __func__, ep_idx); flush(ep); break; } else { read_fifo(ep, req); } } } } else {
static void fastboot_command_loop(void) { struct fastboot_cmd *cmd; int r; dprintf(ALWAYS,"fastboot: processing commands\n"); again: while (fastboot_state != STATE_ERROR) { memset(buffer, 0, sizeof(buffer)); r = usb_read(buffer, MAX_RSP_SIZE); if (r < 0) break; //no input command buffer[r] = 0; dprintf(ALWAYS,"[fastboot: command buf]-[%s]-[len=%d]\n", buffer, r); dprintf(ALWAYS,"[fastboot]-[download_base:0x%x]-[download_size:0x%x]\n",(unsigned int)download_base,(unsigned int)download_size); /*Pick up matched command and handle it*/ for (cmd = cmdlist; cmd; cmd = cmd->next) { fastboot_state = STATE_COMMAND; if (memcmp(buffer, cmd->prefix, cmd->prefix_len)) { continue; } dprintf(ALWAYS,"[Cmd process]-[buf:%s]-[lenBuf:%s]\n", buffer, buffer + cmd->prefix_len); #ifdef MTK_SECURITY_SW_SUPPORT if( !sec_usbdl_enabled() || cmd->sec_support ) #endif { cmd->handle((const char*) buffer + cmd->prefix_len, (void*) download_base, download_size); } if (fastboot_state == STATE_COMMAND) { #ifdef MTK_SECURITY_SW_SUPPORT if( sec_usbdl_enabled() && !cmd->sec_support ) { fastboot_fail("not support on security"); } else #endif { fastboot_fail("unknown reason"); } } goto again; } dprintf(ALWAYS,"[unknown command]*[%s]*\n", buffer); fastboot_fail("unknown command"); } fastboot_state = STATE_OFFLINE; dprintf(ALWAYS,"fastboot: oops!\n"); }
static int check_response(usb_handle *usb, unsigned int size, char *response) { unsigned char status[65]; int r; for(;;) { r = usb_read(usb, status, 64); if(r < 0) { sprintf(ERROR, "status read failed (%s)", strerror(errno)); usb_close(usb); return -1; } status[r] = 0; if(r < 4) { sprintf(ERROR, "status malformed (%d bytes)", r); usb_close(usb); return -1; } if(!memcmp(status, "INFO", 4)) { fprintf(stderr,"(bootloader) %s\n", status + 4); continue; } if(!memcmp(status, "OKAY", 4)) { if(response) { strcpy(response, (char*) status + 4); } return 0; } if(!memcmp(status, "FAIL", 4)) { if(r > 4) { sprintf(ERROR, "remote: %s", status + 4); } else { strcpy(ERROR, "remote failure"); } return -1; } if(!memcmp(status, "DATA", 4) && size > 0){ unsigned dsize = strtoul((char*) status + 4, 0, 16); if(dsize > size) { strcpy(ERROR, "data size too large"); usb_close(usb); return -1; } return dsize; } strcpy(ERROR,"unknown status code"); usb_close(usb); break; } return -1; }
static inline int hashratio_gets(struct cgpu_info *hashratio, uint8_t *buf) { int i; int read_amount = HRTO_READ_SIZE; uint8_t buf_tmp[HRTO_READ_SIZE]; uint8_t buf_copy[2 * HRTO_READ_SIZE]; uint8_t *buf_back = buf; int ret = 0; while (true) { int err; do { memset(buf, 0, read_amount); err = usb_read(hashratio, (char *)buf, read_amount, &ret, C_HRO_READ); if (unlikely(err < 0 || ret != read_amount)) { applog(LOG_ERR, "hashratio: Error on read in hashratio_gets got %d", ret); return HRTO_GETS_ERROR; } if (likely(ret >= read_amount)) { for (i = 1; i < read_amount; i++) { if (buf_back[i - 1] == HRTO_H1 && buf_back[i] == HRTO_H2) break; } i -= 1; if (i) { err = usb_read(hashratio, (char *)buf, read_amount, &ret, C_HRO_READ); if (unlikely(err < 0 || ret != read_amount)) { applog(LOG_ERR, "hashratio: Error on 2nd read in hashratio_gets got %d", ret); return HRTO_GETS_ERROR; } memcpy(buf_copy, buf_back + i, HRTO_READ_SIZE - i); memcpy(buf_copy + HRTO_READ_SIZE - i, buf_tmp, i); memcpy(buf_back, buf_copy, HRTO_READ_SIZE); } return HRTO_GETS_OK; } buf += ret; read_amount -= ret; continue; } while (ret > 0); return HRTO_GETS_TIMEOUT; } }
static void hfa_clear_readbuf(struct cgpu_info *hashfast) { int amount, ret; char buf[512]; do { ret = usb_read(hashfast, buf, 512, &amount, C_HF_CLEAR_READ); } while (!ret || amount); }
void rt_ep_stall(struct rt_ep_struct *rt_ep) { u8 tmp; u32 addr; int idx = EP_NO(rt_ep); int dir = EP_DIR(rt_ep); if(idx == 0){ tmp = usb_read(EP0CS); tmp |= 0x1; usb_write(EP0CS, tmp); }else{ addr = (dir == EP_IN ? 0x006 : 0x002) + idx * 8; tmp = usb_read(addr); tmp |= 0x40; usb_write(addr, tmp); } return; }
int usb_boot( struct usb_handle *usb, void *data, unsigned sz, const char *rootfs) { const uint32_t msg_boot = 0xF0030002; uint32_t msg_size = sz; int i; pthread_t thread; struct thread_vars vars; struct termios tn; struct file_data fd_vector[MAX_OPEN_FILES]; if (read_asic_id(usb)) return -1; printf("sending xload to target...\n"); usleep(1000); usb_write(usb, &msg_boot, sizeof(msg_boot)); usleep(1000); usb_write(usb, &msg_size, sizeof(msg_size)); usleep(1000); usb_write(usb, data, sz); usleep(100000); munmap(data, msg_size); for (i = 0; i < MAX_OPEN_FILES; i++) fd_vector[i].data = NULL; vars.usb = usb; pthread_mutex_init(&vars.usb_mutex, NULL); tcgetattr(STDIN_FILENO, &vars.t_restore); tn = vars.t_restore; tn.c_lflag &= ~(ICANON | ECHO); printf(TFORMAT, TARGET_FORMAT); tcsetattr(STDIN_FILENO, TCSANOW, &tn); if (pthread_create(&thread, NULL, listenerTask, &vars)) host_print("listenerTask failed\n"); for (;;) { usleep(100); if (usb_read(usb, &i, 4) != 4) break; if (i == USBBOOT_FS_MAGIC) { usleep(100); pthread_mutex_lock(&vars.usb_mutex); process_file(usb, rootfs, fd_vector, &vars.t_restore); pthread_mutex_unlock(&vars.usb_mutex); continue; } printf("%c", i); fflush(stdout); } usb_close(usb); pthread_mutex_destroy(&vars.usb_mutex); tcsetattr(STDIN_FILENO, TCSANOW, &vars.t_restore); printf(HFORMAT, HOST_FORMAT); return 0; }
// Call usb_read using a buffer having a multiple of usb_get_max_packet_size() bytes // to avoid overflow. See http://libusb.sourceforge.net/api-1.0/packetoverflow.html. static int UsbReadMessage(usb_handle* h, amessage* msg) { D("UsbReadMessage"); #if CHECK_PACKET_OVERFLOW size_t usb_packet_size = usb_get_max_packet_size(h); CHECK_GE(usb_packet_size, sizeof(*msg)); CHECK_LT(usb_packet_size, 4096ULL); char buffer[4096]; int n = usb_read(h, buffer, usb_packet_size); if (n != sizeof(*msg)) { D("usb_read returned unexpected length %d (expected %zu)", n, sizeof(*msg)); return -1; } memcpy(msg, buffer, sizeof(*msg)); return n; #else return usb_read(h, msg, sizeof(*msg)); #endif }
static u32 rt_fifo_bcount(struct rt_ep_struct *rt_ep) { u8 low, high; u32 rc; int idx = EP_NO(rt_ep); int dir = EP_DIR(rt_ep); if(idx == 0) return 0; if(dir /* IN */){ low = usb_read(0x004 + idx*8); high = usb_read( (0x004 + idx*8)+1 ); }else{ /* OUT */ low = usb_read(0x000 + idx*8); high = usb_read( (0x000 + idx*8)+1 ); } rc = high | low; return rc; }
// On Android devices, we rely on the kernel to provide buffered read. // So we can recover automatically from EOVERFLOW. static int remote_read(apacket* p, usb_handle* usb) { if (usb_read(usb, &p->msg, sizeof(amessage)) != sizeof(amessage)) { PLOG(ERROR) << "remote usb: read terminated (message)"; return -1; } if (p->msg.data_length) { if (p->msg.data_length > MAX_PAYLOAD) { PLOG(ERROR) << "remote usb: read overflow (data length = " << p->msg.data_length << ")"; return -1; } p->payload.resize(p->msg.data_length); if (usb_read(usb, &p->payload[0], p->payload.size()) != static_cast<int>(p->payload.size())) { PLOG(ERROR) << "remote usb: terminated (data)"; return -1; } } return 0; }
static bool hfa_get_data(struct cgpu_info *hashfast, char *buf, int len4) { int amount, ret, len = len4 * 4; ret = usb_read(hashfast, buf, len, &amount, C_HF_GETDATA); if (ret) return false; if (amount != len) { applog(LOG_WARNING, "HFA %d: get_data: Strange amount returned %d vs. expected %d", hashfast->device_id, amount, len); return false; } return true; }
bool cmd_receive(UsbCommand* cmd) { // Check if there is a usb packet available if (!usb_poll()) return false; // Try to retrieve the available command frame size_t rxlen = usb_read((byte_t*)cmd,sizeof(UsbCommand)); // Check if the transfer was complete if (rxlen != sizeof(UsbCommand)) return false; // Received command successfully return true; }