void fhci_init_ep_registers(struct fhci_usb *usb, struct endpoint *ep, enum fhci_mem_alloc data_mem) { u8 rt; /* set the endpoint registers according to the endpoint */ out_be16(&usb->fhci->regs->usb_ep[0], USB_TRANS_CTR | USB_EP_MF | USB_EP_RTE); out_be16(&usb->fhci->pram->ep_ptr[0], cpm_muram_offset(ep->ep_pram_ptr)); rt = (BUS_MODE_BO_BE | BUS_MODE_GBL); #ifdef MULTI_DATA_BUS if (data_mem == MEM_SECONDARY) rt |= BUS_MODE_DTB; #endif out_8(&ep->ep_pram_ptr->rx_func_code, rt); out_8(&ep->ep_pram_ptr->tx_func_code, rt); out_be16(&ep->ep_pram_ptr->rx_buff_len, 1028); out_be16(&ep->ep_pram_ptr->rx_base, 0); out_be16(&ep->ep_pram_ptr->tx_base, cpm_muram_offset(ep->td_base)); out_be16(&ep->ep_pram_ptr->rx_bd_ptr, 0); out_be16(&ep->ep_pram_ptr->tx_bd_ptr, cpm_muram_offset(ep->td_base)); out_be32(&ep->ep_pram_ptr->tx_state, 0); }
void fhci_host_transmit_actual_frame(struct fhci_usb *usb) { u16 tb_ptr; u16 td_status; struct usb_td __iomem *td; struct endpoint *ep = usb->ep0; tb_ptr = in_be16(&ep->ep_pram_ptr->tx_bd_ptr); td = cpm_muram_addr(tb_ptr); if (in_be32(&td->buf_ptr) == DUMMY_BD_BUFFER) { struct usb_td __iomem *old_td = td; ep->already_pushed_dummy_bd = false; td_status = in_be16(&td->status); /* gets the next TD in the ring */ td = next_bd(ep->td_base, td, td_status); tb_ptr = cpm_muram_offset(td); out_be16(&ep->ep_pram_ptr->tx_bd_ptr, tb_ptr); /* start transmit only if we have something in the TDs */ if (in_be16(&td->status) & TD_R) out_8(&usb->fhci->regs->usb_comm, USB_CMD_STR_FIFO); if (in_be32(&ep->conf_td->buf_ptr) == DUMMY_BD_BUFFER) { out_be32(&old_td->buf_ptr, 0); ep->conf_td = next_bd(ep->td_base, ep->conf_td, td_status); } else { out_be32(&old_td->buf_ptr, DUMMY2_BD_BUFFER); } } }
/* destroy an USB endpoint */ void fhci_ep0_free(struct fhci_usb *usb) { struct endpoint *ep; int size; ep = usb->ep0; if (ep) { if (ep->td_base) cpm_muram_free(cpm_muram_offset(ep->td_base)); if (kfifo_initialized(&ep->conf_frame_Q)) { size = cq_howmany(&ep->conf_frame_Q); for (; size; size--) { struct packet *pkt = cq_get(&ep->conf_frame_Q); kfree(pkt); } cq_delete(&ep->conf_frame_Q); } if (kfifo_initialized(&ep->empty_frame_Q)) { size = cq_howmany(&ep->empty_frame_Q); for (; size; size--) { struct packet *pkt = cq_get(&ep->empty_frame_Q); kfree(pkt); } cq_delete(&ep->empty_frame_Q); } if (kfifo_initialized(&ep->dummy_packets_Q)) { size = cq_howmany(&ep->dummy_packets_Q); for (; size; size--) { u8 *buff = cq_get(&ep->dummy_packets_Q); kfree(buff); } cq_delete(&ep->dummy_packets_Q); } kfree(ep); usb->ep0 = NULL; } }