Example #1
0
/** 
 * @brief makes a buffer of TDs and returs the top TD
 * @param host struct uhci_host 
 * @param buf_phys phys32_t 
 * @param size size_t 
 * @param deviceaddress u8 
 * @param epdesc struct usb_endpoint_descriptor
 * @param maxpktsz size_t
 * @param status u32 
 */		
static struct uhci_td_meta *
prepare_buffer_tds(struct uhci_host *host, phys32_t buf_phys, size_t size, 
		   u8 deviceaddress, struct usb_endpoint_descriptor *epdesc,
		   size_t maxpktsz, u32 status)
{
	struct uhci_td_meta *tdm = NULL, *next_tdm = NULL;
	int                  n_td, i;
	size_t pktsz;

	n_td = size / maxpktsz;
	pktsz = size % maxpktsz;
	/* rounding them for the final one */
	if (pktsz == 0) {
		pktsz = maxpktsz;
	} else {
		n_td += 1;
	}
	if (size == 0) {
		/* for ZERO OUT */
		n_td += 1;
		pktsz = 0;
	}
	/* create TDs in reverse (from the final to the 1st) */
	buf_phys += maxpktsz * n_td;
	for (i = n_td; i > 0; i--) {
		tdm = uhci_new_td_meta(host, NULL);
		if (!tdm)
			return 0ULL;
		tdm->td->link = 
			(next_tdm) ? next_tdm->td_phys : UHCI_TD_LINK_TE;
		tdm->next = next_tdm;
		tdm->td->status = tdm->status_copy = status;
		tdm->td->token = tdm->token_copy =
			uhci_td_explen(pktsz) |
			UHCI_TD_TOKEN_ENDPOINT(epdesc->bEndpointAddress) | 
			UHCI_TD_TOKEN_DEVADDRESS(deviceaddress) |
			uhci_pid_from_ep(epdesc);
		buf_phys = tdm->td->buffer = buf_phys - maxpktsz;

		next_tdm = tdm;
		pktsz = maxpktsz; /* for other packets, 
				     except for the final */
	}

	return tdm;
}
Example #2
0
/** 
 * @brief makes a buffer of TDs and returs the top TD
 * @param host struct uhci_host 
 * @param buf_phys phys32_t 
 * @param size size_t 
 * @param deviceaddress u8 
 * @param epdesc struct usb_endpoint_descriptor
 * @param status u32 
 */		
static struct uhci_td_meta *
prepare_buffer_tds(struct uhci_host *host, phys32_t buf_phys, size_t size, 
		   u8 deviceaddress, struct usb_endpoint_descriptor *epdesc,
		   u32 status)
{
	struct uhci_td_meta *tdm = NULL, *next_tdm = NULL;
	int                  n_td, i;
	size_t               pktsize, maxlen;

	pktsize = epdesc->wMaxPacketSize;
	n_td = (size + (pktsize - 1)) / pktsize;
	maxlen = (size % pktsize) ? (size % pktsize) : pktsize;
	if (!size) {
		/* for ZERO OUT */
		n_td += 1; 
		maxlen = 0;
	}
	buf_phys += pktsize * n_td;
	for (i=n_td; i>0; i--) {
		tdm = uhci_new_td_meta(host, NULL);
		if (!tdm)
			return 0ULL;
		tdm->td->link = 
			(next_tdm) ? next_tdm->td_phys : UHCI_TD_LINK_TE;
		tdm->next = next_tdm; 
		tdm->td->status = tdm->status_copy = status;
		tdm->td->token = tdm->token_copy =
			uhci_td_explen(maxlen) |
			UHCI_TD_TOKEN_ENDPOINT(epdesc->bEndpointAddress) | 
			UHCI_TD_TOKEN_DEVADDRESS(deviceaddress) |
			uhci_pid_from_ep(epdesc);
		buf_phys = tdm->td->buffer = buf_phys - pktsize;

		next_tdm = tdm;
		maxlen = pktsize;
	}

	return tdm;
}