Index: firmware/export/usb_core.h =================================================================== --- firmware/export/usb_core.h (revision 20783) +++ firmware/export/usb_core.h (working copy) @@ -36,6 +36,17 @@ /* endpoints */ #define EP_CONTROL 0 + +#define DIR_OUT 0 +#define DIR_IN 1 + +/* The USB core is a device, and OUT is RX from that P.O.V */ +#define DIR_RX DIR_OUT +#define DIR_TX DIR_IN + +#define EP_DIR(ep) (((ep) & USB_ENDPOINT_DIR_MASK) ? DIR_IN : DIR_OUT) +#define EP_NUM(ep) ((ep) & USB_ENDPOINT_NUMBER_MASK) + extern int usb_max_pkt_size; struct usb_class_driver; Index: firmware/export/usb.h =================================================================== --- firmware/export/usb.h (revision 20783) +++ firmware/export/usb.h (working copy) @@ -105,7 +105,7 @@ int length; void* data; }; -#endif +#endif /* HAVE_USBSTACK */ void usb_init(void); void usb_enable(bool on); Index: firmware/usb.c =================================================================== --- firmware/usb.c (revision 20783) +++ firmware/usb.c (working copy) @@ -273,6 +273,9 @@ #ifdef USB_STORAGE usb_core_enable_driver(USB_DRIVER_MASS_STORAGE, false); #endif +#ifdef USB_HID + usb_core_enable_driver(USB_DRIVER_HID, false); +#endif #ifdef USB_CHARGING_ONLY usb_core_enable_driver(USB_DRIVER_CHARGING_ONLY, true); #endif @@ -291,6 +294,9 @@ #ifdef USB_STORAGE usb_core_enable_driver(USB_DRIVER_MASS_STORAGE, true); #endif +#ifdef USB_HID + usb_core_enable_driver(USB_DRIVER_HID, false); +#endif #ifdef USB_CHARGING_ONLY usb_core_enable_driver(USB_DRIVER_CHARGING_ONLY, false); #endif @@ -562,9 +568,8 @@ queue_init(&usb_queue, true); - usb_thread_entry = create_thread(usb_thread, usb_stack, - sizeof(usb_stack), 0, usb_thread_name - IF_PRIO(, PRIORITY_SYSTEM) IF_COP(, CPU)); + usb_thread_entry = create_thread(usb_thread, usb_stack, sizeof(usb_stack), + 0, usb_thread_name IF_PRIO(, PRIORITY_SYSTEM) IF_COP(, CPU)); #ifndef USB_STATUS_BY_EVENT countdown = -1; Index: firmware/usbstack/usb_core.c =================================================================== --- firmware/usbstack/usb_core.c (revision 20783) +++ firmware/usbstack/usb_core.c (working copy) @@ -397,7 +397,7 @@ (struct usb_ctrlrequest*)event->data); break; default: - handler = ep_data[ep].completion_handler[event->dir>>7]; + handler = ep_data[ep].completion_handler[EP_DIR(event->dir)]; if(handler != NULL) handler(ep,event->dir,event->status,event->length); break; @@ -460,8 +460,8 @@ if (ret==-1) return -1; - ep = ret & 0x7f; - dir = ret >> 7; + dir = EP_DIR(ret); + ep = EP_NUM(ret); ep_data[ep].completion_handler[dir] = drv->transfer_complete; ep_data[ep].control_handler[dir] = drv->control_request; @@ -475,8 +475,8 @@ usb_drv_release_endpoint(ep); - dir = ep >> 7; - ep &= 0x7f; + dir = EP_DIR(ep); + ep = EP_NUM(ep); ep_data[ep].completion_handler[dir] = NULL; ep_data[ep].control_handler[dir] = NULL; @@ -528,7 +528,7 @@ if(!handled) { /* nope. flag error */ logf("bad req:desc %d:%d", req->bRequest, req->wValue>>8); - usb_drv_stall(EP_CONTROL, true,true); + usb_drv_stall(EP_CONTROL, true, true); usb_core_ack_control(req); } } @@ -730,15 +730,13 @@ switch (req->bRequest) { case USB_REQ_CLEAR_FEATURE: if (req->wValue==USB_ENDPOINT_HALT) { - usb_drv_stall(req->wIndex & 0xf, false, - (req->wIndex & USB_DIR_IN)!=0); + usb_drv_stall(EP_NUM(req->wIndex), false, EP_DIR(req->wIndex)); } usb_core_ack_control(req); break; case USB_REQ_SET_FEATURE: if (req->wValue==USB_ENDPOINT_HALT) { - usb_drv_stall(req->wIndex & 0xf,true, - (req->wIndex & USB_DIR_IN)!=0); + usb_drv_stall(EP_NUM(req->wIndex), true, EP_DIR(req->wIndex)); } usb_core_ack_control(req); break; @@ -747,8 +745,8 @@ response_data[1]=0; logf("usb_core: GET_STATUS"); if(req->wIndex>0) { - response_data[0]=usb_drv_stalled(req->wIndex & 0xf, - (req->wIndex & USB_DIR_IN)!=0); + response_data[0]=usb_drv_stalled(EP_NUM(req->wIndex), + EP_DIR(req->wIndex)); } if(!usb_drv_send(EP_CONTROL,response_data,2)) usb_core_ack_control(req); @@ -757,7 +755,8 @@ bool handled; control_handler_t control_handler; - control_handler=ep_data[req->wIndex & 0xf].control_handler[0]; + control_handler= + ep_data[EP_NUM(req->wIndex)].control_handler[EP_CONTROL]; if (!control_handler) break; @@ -835,9 +834,9 @@ void usb_core_control_request(struct usb_ctrlrequest* req) { struct usb_transfer_completion_event_data* completion_event = - &ep_data[0].completion_event; + &ep_data[EP_CONTROL].completion_event; - completion_event->endpoint=0; + completion_event->endpoint=EP_CONTROL; completion_event->dir=0; completion_event->data=(void*)req; completion_event->status=0; Index: firmware/target/arm/usb-drv-arc.c =================================================================== --- firmware/target/arm/usb-drv-arc.c (revision 20783) +++ firmware/target/arm/usb-drv-arc.c (working copy) @@ -248,10 +248,6 @@ #define EPCTRL_RX_EP_STALL (0x00000001) /* bit 19-18 and 3-2 are endpoint type */ -#define EPCTRL_EP_TYPE_CONTROL (0) -#define EPCTRL_EP_TYPE_ISO (1) -#define EPCTRL_EP_TYPE_BULK (2) -#define EPCTRL_EP_TYPE_INTERRUPT (3) #define EPCTRL_TX_EP_TYPE_SHIFT (18) #define EPCTRL_RX_EP_TYPE_SHIFT (2) @@ -361,11 +357,9 @@ /*-------------------------------------------------------------------------*/ static void transfer_completed(void); static void control_received(void); -static int prime_transfer(int endpoint, void* ptr, - int len, bool send, bool wait); +static int prime_transfer(int ep_num, void* ptr, int len, bool send, bool wait); static void prepare_td(struct transfer_descriptor* td, - struct transfer_descriptor* previous_td, - void *ptr, int len,int pipe); + struct transfer_descriptor* previous_td, void *ptr, int len,int pipe); static void bus_reset(void); static void init_control_queue_heads(void); static void init_bulk_queue_heads(void); @@ -394,7 +388,7 @@ while (REG_USBCMD & USBCMD_CTRL_RESET); #if CONFIG_CPU == PP5022 || CONFIG_CPU == PP5024 - /* On a CPU which identifies as a PP5022, this + /* On a CPU which identifies as a PP5022, this initialization must be done after USB is reset. */ outl(inl(0x70000060) | 0xF, 0x70000060); @@ -423,7 +417,7 @@ { /* Initialize all the signal objects once */ int i; - for(i=0;i EP_CONTROL) { + if (send && ep_num > EP_CONTROL) { logf("usb: sent %d bytes", len); } */ qh->status = 0; - qh->wait = wait; + qh->wait = wait; - new_td=&td_array[pipe*NUM_TDS_PER_EP]; - cur_td=new_td; - prev_td=0; + new_td = &td_array[pipe * NUM_TDS_PER_EP]; + cur_td = new_td; + prev_td = 0; int tdlen; do { - tdlen=MIN(len,16384); + tdlen = MIN(len, 16384); prepare_td(cur_td, prev_td, ptr, tdlen,pipe); - ptr+=tdlen; - prev_td=cur_td; + ptr += tdlen; + prev_td = cur_td; cur_td++; - len-=tdlen; + len -= tdlen; } - while(len>0 ); - //logf("starting ep %d %s",endpoint,send?"send":"receive"); + while(len>0); + //logf("starting ep %d %s",ep_num,send?"send":"receive"); qh->dtd.next_td_ptr = (unsigned int)new_td; qh->dtd.size_ioc_sts &= ~(QH_STATUS_HALT | QH_STATUS_ACTIVE); REG_ENDPTPRIME |= mask; - if(endpoint == EP_CONTROL && (REG_ENDPTSETUPSTAT & EPSETUP_STATUS_EP0)) { + if(ep_num == EP_CONTROL && (REG_ENDPTSETUPSTAT & EPSETUP_STATUS_EP0)) { /* 32.14.3.2.2 */ logf("new setup arrived"); rc = -4; @@ -724,11 +732,11 @@ } if (!(REG_ENDPTSTATUS & mask)) { - logf("no prime! %d %d %x", endpoint, pipe, qh->dtd.size_ioc_sts & 0xff ); + logf("no prime! %d %d %x", ep_num, pipe, qh->dtd.size_ioc_sts & 0xff); rc = -3; goto pt_error; } - if(endpoint == EP_CONTROL && (REG_ENDPTSETUPSTAT & EPSETUP_STATUS_EP0)) { + if(ep_num == EP_CONTROL && (REG_ENDPTSETUPSTAT & EPSETUP_STATUS_EP0)) { /* 32.14.3.2.2 */ logf("new setup arrived"); rc = -4; @@ -771,7 +779,7 @@ while (REG_ENDPTFLUSH); memset(td_array, 0, sizeof td_array); - for(i=0;ireserved & DTD_RESERVED_LENGTH_MASK) - + length += ((td->reserved & DTD_RESERVED_LENGTH_MASK) - ((td->size_ioc_sts & DTD_PACKET_SIZE) >> DTD_LENGTH_BIT_POS)); td=(struct transfer_descriptor*) td->next_td_ptr; } - usb_core_transfer_complete(ep, dir?USB_DIR_IN:USB_DIR_OUT, qh->status, length); + usb_core_transfer_complete(ep, dir?USB_DIR_IN:USB_DIR_OUT, + qh->status, length); } } } @@ -906,7 +915,7 @@ } usb_drv_cancel_all_transfers(); - + if (!(REG_PORTSC1 & PORTSCX_PORT_RESET)) { logf("usb: slow reset!"); } @@ -926,25 +935,16 @@ /* manual: 32.14.4.1 Queue Head Initialization */ static void init_bulk_queue_heads(void) { - int tx_packetsize; - int rx_packetsize; + int packetsize = (usb_drv_port_speed() ? 512 : 64); int i; - if (usb_drv_port_speed()) { - rx_packetsize = 512; - tx_packetsize = 512; - } - else { - rx_packetsize = 64; - tx_packetsize = 64; - } /* TODO: this should take ep_allocation into account */ - - /*** bulk ***/ - for(i=1;ihalt[epidx_dir(idx)] = 0; @@ -146,7 +143,7 @@ /* Enable endpoint */ ISP1583_DFLOW_EPTYPE |= DFLOW_EPTYPE_ENABLE; } - + endpoints[epidx_n(idx)].enabled[epidx_dir(idx)] = 1; } /* @@ -155,7 +152,7 @@ usb_select_endpoint(idx); ISP1583_DFLOW_EPTYPE &= ~DFLOW_EPTYPE_ENABLE; bc_int_value(&ISP1583_INIT_INTEN_A, &ISP1583_INIT_INTEN_B, ISP1583_INIT_INTEN_READ, 1 << (10 + idx)); - + if(set_struct) endpoints[epidx_n(idx)].enabled[epidx_dir(idx)] = 0; } @@ -188,9 +185,9 @@ int len; if (endpoints[n].halt[DIR_RX] - || !endpoints[n].enabled[DIR_RX] - || endpoints[n].in_min_len < 0 - || !endpoints[n].in_ack) + || !endpoints[n].enabled[DIR_RX] + || endpoints[n].in_min_len < 0 + || !endpoints[n].in_ack) return -1; endpoints[n].in_ack = 0; @@ -198,15 +195,16 @@ usb_select_endpoint(ep_index(n, DIR_RX)); len = usb_get_packet(endpoints[n].in_buf + endpoints[n].in_ptr, - endpoints[n].in_max_len - endpoints[n].in_ptr); + endpoints[n].in_max_len - endpoints[n].in_ptr); endpoints[n].in_ptr += len; - + if (endpoints[n].in_ptr >= endpoints[n].in_min_len) { endpoints[n].in_min_len = -1; - if (endpoints[n].in_done) + if (endpoints[n].in_done) { (*(endpoints[n].in_done))(n, endpoints[n].in_buf, - endpoints[n].in_ptr); + endpoints[n].in_ptr); + } } logf("receive_end"); return 0; @@ -229,8 +227,8 @@ unsigned char *p; if (endpoints[n].halt[DIR_TX] - || !endpoints[n].enabled[DIR_TX] - || !endpoints[n].out_in_progress) + || !endpoints[n].enabled[DIR_TX] + || !endpoints[n].out_in_progress) { logf("NOT SEND TO EP!"); return -1; @@ -241,26 +239,26 @@ endpoints[n].out_in_progress = 0; if (endpoints[n].out_done) (*(endpoints[n].out_done))(n, endpoints[n].out_buf, - endpoints[n].out_len); + endpoints[n].out_len); logf("ALREADY SENT TO EP!"); return -1; } - + if (usb_out_buffer_full(n)) { logf("BUFFER FULL!"); return -1; } - + usb_select_endpoint(ep_index(n, DIR_TX)); max_pkt_size = endpoints[n].max_pkt_size[DIR_TX]; len = endpoints[n].out_len - endpoints[n].out_ptr; if (len > max_pkt_size) len = max_pkt_size; - + if(len < max_pkt_size) ISP1583_DFLOW_BUFLEN = len; - + p = endpoints[n].out_buf + endpoints[n].out_ptr; i = 0; while (len - i >= 2) @@ -279,7 +277,7 @@ */ if (endpoints[n].out_ptr == endpoints[n].out_len) endpoints[n].out_ptr = -1; - + logf("send_end"); return 0; } @@ -315,7 +313,7 @@ usb_select_setup_endpoint(); else usb_select_endpoint(ep_index(ep, dir)); - + ISP1583_DFLOW_CTRLFUN |= DFLOW_CTRLFUN_STATUS; } @@ -344,7 +342,7 @@ logf("usb_handle_setup_rx() failed"); return; } - + logf("usb_handle_setup_rx(): %02x %02x %02x %02x %02x %02x %02x %02x", setup_pkt_buf[0], setup_pkt_buf[1], setup_pkt_buf[2], setup_pkt_buf[3], setup_pkt_buf[4], setup_pkt_buf[5], setup_pkt_buf[6], setup_pkt_buf[7]); } @@ -372,25 +370,31 @@ static void setup_endpoints(void) { - usb_setup_endpoint(ep_index(0, DIR_RX), 64, 0); - usb_setup_endpoint(ep_index(0, DIR_TX), 64, 0); - int i; + int max_pkt_size = (high_speed_mode ? 512 : 64); + + usb_setup_endpoint(ep_index(EP_CONTROL, DIR_RX), 64, + USB_ENDPOINT_XFER_CONTROL); + usb_setup_endpoint(ep_index(EP_CONTROL, DIR_TX), 64, + USB_ENDPOINT_XFER_CONTROL); + for(i = 1; i < USB_NUM_ENDPOINTS-1; i++) { - usb_setup_endpoint(ep_index(i, DIR_RX), (high_speed_mode ? 512 : 64), 2); /* 2 = TYPE_BULK */ - usb_setup_endpoint(ep_index(i, DIR_TX), (high_speed_mode ? 512 : 64), 2); + usb_setup_endpoint(ep_index(i, DIR_RX), max_pkt_size, + USB_ENDPOINT_XFER_BULK); + usb_setup_endpoint(ep_index(i, DIR_TX), max_pkt_size, + USB_ENDPOINT_XFER_BULK); } - + usb_enable_endpoint(ep_index(0, DIR_RX)); usb_enable_endpoint(ep_index(0, DIR_TX)); - + for (i = 1; i < USB_NUM_ENDPOINTS-1; i++) { usb_enable_endpoint(ep_index(i, DIR_RX)); usb_enable_endpoint(ep_index(i, DIR_TX)); } - + ZVM_SPECIFIC; } @@ -417,45 +421,45 @@ sleep(10); /* Enable CLKAON & GLINTENA */ ISP1583_INIT_MODE = STANDARD_INIT_MODE; - + /* Disable all OTG functions */ ISP1583_INIT_OTG = 0; - #ifdef DEBUG +#ifdef DEBUG logf("BUS_CONF/DA0:%d MODE0/DA1: %d MODE1: %d", (bool)(ISP1583_INIT_MODE & INIT_MODE_TEST0), (bool)(ISP1583_INIT_MODE & INIT_MODE_TEST1), (bool)(ISP1583_INIT_MODE & INIT_MODE_TEST2)); logf("Chip ID: 0x%x", ISP1583_GEN_CHIPID); //logf("INV0: 0x% IRQEDGE: 0x%x IRQPORT: 0x%x", IO_GIO_INV0, IO_GIO_IRQEDGE, IO_GIO_IRQPORT); - #endif +#endif /*Set interrupt generation to target-specific mode + - * Set the control pipe to ACK only interrupt + - * Set the IN pipe to ACK only interrupt + - * Set OUT pipe to ACK and NYET interrupt - */ - + * Set the control pipe to ACK only interrupt + + * Set the IN pipe to ACK only interrupt + + * Set OUT pipe to ACK and NYET interrupt + */ + ISP1583_INIT_INTCONF = 0x54 | INT_CONF_TARGET; /* Clear all interrupts */ set_int_value(ISP1583_GEN_INT_A, ISP1583_GEN_INT_B, 0xFFFFFFFF); /* Enable USB interrupts */ set_int_value(ISP1583_INIT_INTEN_A, ISP1583_INIT_INTEN_B, STANDARD_INTEN); - + ZVM_SPECIFIC; - + /* Enable interrupt at CPU level */ EN_INT_CPU_TARGET; - + setup_endpoints(); - + /* Clear device address and disable it */ ISP1583_INIT_ADDRESS = 0; - + /* Turn SoftConnect on */ ISP1583_INIT_MODE |= INIT_MODE_SOFTCT; - + ZVM_SPECIFIC; - + //tick_add_task(usb_helper); - + logf("usb_init_device() finished"); } @@ -463,7 +467,7 @@ { return (int)high_speed_mode; } - + void usb_drv_exit(void) { logf("usb_drv_exit()"); @@ -471,7 +475,7 @@ /* Disable device */ ISP1583_INIT_MODE &= ~INIT_MODE_SOFTCT; ISP1583_INIT_ADDRESS = 0; - + /* Disable interrupts */ set_int_value(ISP1583_INIT_INTEN_A, ISP1583_INIT_INTEN_B, 0); /* and the CPU's one... */ @@ -481,9 +485,9 @@ /* Send usb controller to suspend mode */ ISP1583_INIT_MODE = INIT_MODE_GOSUSP; ISP1583_INIT_MODE = 0; - + //tick_remove_task(usb_helper); - + ZVM_SPECIFIC; } @@ -631,13 +635,13 @@ /* Enable USB interrupts */ ISP1583_INIT_INTCONF = 0x54 | INT_CONF_TARGET; set_int_value(ISP1583_INIT_INTEN_A, ISP1583_INIT_INTEN_B, STANDARD_INTEN); - + /* Disable all OTG functions */ ISP1583_INIT_OTG = 0; - + /* Clear device address and enable it */ ISP1583_INIT_ADDRESS = INIT_ADDRESS_DEVEN; - + ZVM_SPECIFIC; /* Reset endpoints to default */ @@ -651,13 +655,13 @@ { unsigned long ints; ints = ISP1583_GEN_INT_READ & ISP1583_INIT_INTEN_READ; - + if(!ints) return; - + /* Unlock the device's registers */ ISP1583_GEN_UNLCKDEV = ISP1583_UNLOCK_CODE; - + //logf(" handling int [0x%lx & 0x%lx = 0x%x]", ISP1583_GEN_INT_READ, ISP1583_INIT_INTEN_READ, (int)ints); if(ints & INT_IEBRST) /* Bus reset */ @@ -690,7 +694,7 @@ { if(i>25) break; - + if(ep_event & (1 << i)) { logf("EP%d %s interrupt", (i - 10) / 2, i % 2 ? "RX" : "TX"); @@ -718,7 +722,7 @@ } /* Mask all (enabled) interrupts */ set_int_value(ISP1583_GEN_INT_A, ISP1583_GEN_INT_B, ints); - + ZVM_SPECIFIC; } @@ -726,7 +730,7 @@ { logf("usb_drv_set_address(0x%x)", address); ISP1583_INIT_ADDRESS = (address & 0x7F) | INIT_ADDRESS_DEVEN; - + ZVM_SPECIFIC; } Index: firmware/ifp_usb_serial.c =================================================================== --- firmware/ifp_usb_serial.c (revision 20783) +++ firmware/ifp_usb_serial.c (working copy) @@ -63,9 +63,6 @@ #define ISP1582_UNLOCK_CODE 0xaa37 -#define DIR_RX 0 -#define DIR_TX 1 - #define TYPE_BULK 2 #define STATE_DEFAULT 0