#include <sys/usb/hcd/ehci/ehcid.h>
#include <sys/usb/hcd/ehci/ehci_xfer.h>
#include <sys/usb/hcd/ehci/ehci_util.h>
int ehci_itd_pool_size = EHCI_ITD_POOL_SIZE;
int ehci_allocate_isoc_pools(
ehci_state_t *ehcip);
int ehci_get_itd_pool_size();
ehci_isoc_xwrapper_t *ehci_allocate_itw_resources(
ehci_state_t *ehcip,
ehci_pipe_private_t *pp,
size_t itw_length,
usb_flags_t usb_flags,
size_t pkt_count);
static ehci_isoc_xwrapper_t *ehci_allocate_itw(
ehci_state_t *ehcip,
ehci_pipe_private_t *pp,
size_t length,
usb_flags_t usb_flags);
void ehci_deallocate_itw(
ehci_state_t *ehcip,
ehci_pipe_private_t *pp,
ehci_isoc_xwrapper_t *itw);
static void ehci_free_itw_dma(
ehci_state_t *ehcip,
ehci_pipe_private_t *pp,
ehci_isoc_xwrapper_t *itw);
static ehci_itd_t *ehci_allocate_itd(
ehci_state_t *ehcip);
void ehci_deallocate_itd(
ehci_state_t *ehcip,
ehci_isoc_xwrapper_t *itw,
ehci_itd_t *old_itd);
uint_t ehci_calc_num_itds(
ehci_isoc_xwrapper_t *itw,
size_t pkt_count);
int ehci_allocate_itds_for_itw(
ehci_state_t *ehcip,
ehci_isoc_xwrapper_t *itw,
uint_t itd_count);
static void ehci_deallocate_itds_for_itw(
ehci_state_t *ehcip,
ehci_isoc_xwrapper_t *itw);
void ehci_insert_itd_on_itw(
ehci_state_t *ehcip,
ehci_isoc_xwrapper_t *itw,
ehci_itd_t *itd);
void ehci_insert_itd_into_active_list(
ehci_state_t *ehcip,
ehci_itd_t *itd);
void ehci_remove_itd_from_active_list(
ehci_state_t *ehcip,
ehci_itd_t *itd);
ehci_itd_t *ehci_create_done_itd_list(
ehci_state_t *ehcip);
int ehci_insert_isoc_to_pfl(
ehci_state_t *ehcip,
ehci_pipe_private_t *pp,
ehci_isoc_xwrapper_t *itw);
void ehci_remove_isoc_from_pfl(
ehci_state_t *ehcip,
ehci_itd_t *curr_itd);
int ehci_allocate_isoc_in_resource(
ehci_state_t *ehcip,
ehci_pipe_private_t *pp,
ehci_isoc_xwrapper_t *tw,
usb_flags_t flags);
void ehci_deallocate_isoc_in_resource(
ehci_state_t *ehcip,
ehci_pipe_private_t *pp,
ehci_isoc_xwrapper_t *itw);
uint32_t ehci_itd_cpu_to_iommu(
ehci_state_t *ehcip,
ehci_itd_t *addr);
ehci_itd_t *ehci_itd_iommu_to_cpu(
ehci_state_t *ehcip,
uintptr_t addr);
void ehci_parse_isoc_error(
ehci_state_t *ehcip,
ehci_isoc_xwrapper_t *itw,
ehci_itd_t *itd);
static usb_cr_t ehci_parse_itd_error(
ehci_state_t *ehcip,
ehci_isoc_xwrapper_t *itw,
ehci_itd_t *itd);
static usb_cr_t ehci_parse_sitd_error(
ehci_state_t *ehcip,
ehci_isoc_xwrapper_t *itw,
ehci_itd_t *itd);
void ehci_print_itd(
ehci_state_t *ehcip,
ehci_itd_t *itd);
void ehci_print_sitd(
ehci_state_t *ehcip,
ehci_itd_t *itd);
int
ehci_allocate_isoc_pools(ehci_state_t *ehcip)
{
ddi_device_acc_attr_t dev_attr;
size_t real_length;
int result;
uint_t ccount;
int i;
USB_DPRINTF_L4(PRINT_MASK_ATTA, ehcip->ehci_log_hdl,
"ehci_allocate_isoc_pools:");
ehcip->ehci_dma_attr.dma_attr_align = EHCI_DMA_ATTR_TD_QH_ALIGNMENT;
result = ddi_dma_alloc_handle(ehcip->ehci_dip,
&ehcip->ehci_dma_attr,
DDI_DMA_SLEEP,
0,
&ehcip->ehci_itd_pool_dma_handle);
if (result != DDI_SUCCESS) {
USB_DPRINTF_L2(PRINT_MASK_LISTS, ehcip->ehci_log_hdl,
"ehci_allocate_isoc_pools: Alloc handle failed");
return (DDI_FAILURE);
}
dev_attr.devacc_attr_version = DDI_DEVICE_ATTR_V0;
dev_attr.devacc_attr_endian_flags = DDI_STRUCTURE_LE_ACC;
dev_attr.devacc_attr_dataorder = DDI_STRICTORDER_ACC;
result = ddi_dma_mem_alloc(ehcip->ehci_itd_pool_dma_handle,
ehci_itd_pool_size * sizeof (ehci_itd_t),
&dev_attr,
DDI_DMA_CONSISTENT,
DDI_DMA_SLEEP,
0,
(caddr_t *)&ehcip->ehci_itd_pool_addr,
&real_length,
&ehcip->ehci_itd_pool_mem_handle);
if (result != DDI_SUCCESS) {
USB_DPRINTF_L2(PRINT_MASK_LISTS, ehcip->ehci_log_hdl,
"ehci_allocate_isoc_pools: Alloc memory failed");
return (DDI_FAILURE);
}
result = ddi_dma_addr_bind_handle(
ehcip->ehci_itd_pool_dma_handle,
NULL,
(caddr_t)ehcip->ehci_itd_pool_addr,
real_length,
DDI_DMA_RDWR | DDI_DMA_CONSISTENT,
DDI_DMA_SLEEP,
NULL,
&ehcip->ehci_itd_pool_cookie,
&ccount);
bzero((void *)ehcip->ehci_itd_pool_addr,
ehci_itd_pool_size * sizeof (ehci_itd_t));
if (result == DDI_DMA_MAPPED) {
if (ccount != 1) {
USB_DPRINTF_L2(PRINT_MASK_ATTA, ehcip->ehci_log_hdl,
"ehci_allocate_isoc_pools: More than 1 cookie");
return (DDI_FAILURE);
}
} else {
USB_DPRINTF_L4(PRINT_MASK_ATTA, ehcip->ehci_log_hdl,
"ehci_allocate_isoc_pools: Result = %d", result);
ehci_decode_ddi_dma_addr_bind_handle_result(ehcip, result);
return (DDI_FAILURE);
}
ehcip->ehci_dma_addr_bind_flag |= EHCI_ITD_POOL_BOUND;
for (i = 0; i < ehci_itd_pool_size; i++) {
Set_ITD(ehcip->ehci_itd_pool_addr[i].itd_state,
EHCI_ITD_FREE);
}
return (DDI_SUCCESS);
}
int
ehci_get_itd_pool_size()
{
return (ehci_itd_pool_size);
}
ehci_isoc_xwrapper_t *
ehci_allocate_itw_resources(
ehci_state_t *ehcip,
ehci_pipe_private_t *pp,
size_t itw_length,
usb_flags_t usb_flags,
size_t pkt_count)
{
uint_t itd_count;
ehci_isoc_xwrapper_t *itw;
itw = ehci_allocate_itw(ehcip, pp, itw_length, usb_flags);
if (itw == NULL) {
USB_DPRINTF_L2(PRINT_MASK_LISTS, ehcip->ehci_log_hdl,
"ehci_allocate_itw_resources: Unable to allocate ITW");
} else {
itd_count = ehci_calc_num_itds(itw, pkt_count);
USB_DPRINTF_L3(PRINT_MASK_LISTS, ehcip->ehci_log_hdl,
"ehci_allocate_itw_resources: itd_count = 0x%d", itd_count);
if (ehci_allocate_itds_for_itw(ehcip, itw, itd_count) ==
USB_SUCCESS) {
itw->itw_num_itds = itd_count;
} else {
ehci_deallocate_itw(ehcip, pp, itw);
itw = NULL;
}
}
return (itw);
}
static ehci_isoc_xwrapper_t *
ehci_allocate_itw(
ehci_state_t *ehcip,
ehci_pipe_private_t *pp,
size_t length,
usb_flags_t usb_flags)
{
ddi_device_acc_attr_t dev_attr;
int result;
size_t real_length;
uint_t ccount;
usba_pipe_handle_data_t *ph = pp->pp_pipe_handle;
usba_device_t *usba_device = ph->p_usba_device;
usb_ep_descr_t *endpoint = &ph->p_ep;
ehci_isoc_xwrapper_t *itw;
USB_DPRINTF_L4(PRINT_MASK_LISTS, ehcip->ehci_log_hdl,
"ehci_allocate_itw: length = 0x%lx flags = 0x%x",
length, usb_flags);
ASSERT(mutex_owned(&ehcip->ehci_int_mutex));
itw = kmem_zalloc(sizeof (ehci_isoc_xwrapper_t), KM_NOSLEEP);
if (itw == NULL) {
USB_DPRINTF_L2(PRINT_MASK_LISTS, ehcip->ehci_log_hdl,
"ehci_allocate_itw: kmem_zalloc failed");
return (NULL);
}
ehcip->ehci_dma_attr.dma_attr_align = EHCI_DMA_ATTR_ALIGNMENT;
result = ddi_dma_alloc_handle(ehcip->ehci_dip,
&ehcip->ehci_dma_attr,
DDI_DMA_DONTWAIT,
0,
&itw->itw_dmahandle);
if (result != DDI_SUCCESS) {
USB_DPRINTF_L2(PRINT_MASK_LISTS, ehcip->ehci_log_hdl,
"ehci_create_transfer_wrapper: Alloc handle failed");
kmem_free(itw, sizeof (ehci_isoc_xwrapper_t));
return (NULL);
}
dev_attr.devacc_attr_version = DDI_DEVICE_ATTR_V0;
dev_attr.devacc_attr_endian_flags = DDI_NEVERSWAP_ACC;
dev_attr.devacc_attr_dataorder = DDI_STRICTORDER_ACC;
result = ddi_dma_mem_alloc(itw->itw_dmahandle,
length,
&dev_attr,
DDI_DMA_CONSISTENT,
DDI_DMA_DONTWAIT,
NULL,
(caddr_t *)&itw->itw_buf,
&real_length,
&itw->itw_accesshandle);
if (result != DDI_SUCCESS) {
USB_DPRINTF_L2(PRINT_MASK_LISTS, ehcip->ehci_log_hdl,
"ehci_create_transfer_wrapper: dma_mem_alloc fail");
ddi_dma_free_handle(&itw->itw_dmahandle);
kmem_free(itw, sizeof (ehci_isoc_xwrapper_t));
return (NULL);
}
ASSERT(real_length >= length);
result = ddi_dma_addr_bind_handle(itw->itw_dmahandle,
NULL,
(caddr_t)itw->itw_buf,
real_length,
DDI_DMA_RDWR|DDI_DMA_CONSISTENT,
DDI_DMA_DONTWAIT,
NULL,
&itw->itw_cookie,
&ccount);
if (result == DDI_DMA_MAPPED) {
if (ccount != 1) {
USB_DPRINTF_L2(PRINT_MASK_LISTS, ehcip->ehci_log_hdl,
"ehci_create_transfer_wrapper: More than 1 cookie");
result = ddi_dma_unbind_handle(itw->itw_dmahandle);
ASSERT(result == DDI_SUCCESS);
ddi_dma_mem_free(&itw->itw_accesshandle);
ddi_dma_free_handle(&itw->itw_dmahandle);
kmem_free(itw, sizeof (ehci_isoc_xwrapper_t));
return (NULL);
}
} else {
ehci_decode_ddi_dma_addr_bind_handle_result(ehcip, result);
ddi_dma_mem_free(&itw->itw_accesshandle);
ddi_dma_free_handle(&itw->itw_dmahandle);
kmem_free(itw, sizeof (ehci_isoc_xwrapper_t));
return (NULL);
}
itw->itw_pipe_private = pp;
if (pp->pp_itw_head == NULL) {
pp->pp_itw_head = itw;
pp->pp_itw_tail = itw;
} else {
pp->pp_itw_tail->itw_next = itw;
pp->pp_itw_tail = itw;
}
itw->itw_length = length;
itw->itw_flags = usb_flags;
itw->itw_port_status = usba_device->usb_port_status;
itw->itw_direction = endpoint->bEndpointAddress & USB_EP_DIR_MASK;
mutex_enter(&usba_device->usb_mutex);
itw->itw_hub_addr = usba_device->usb_hs_hub_addr;
itw->itw_hub_port = usba_device->usb_hs_hub_port;
itw->itw_endpoint_num = endpoint->bEndpointAddress & USB_EP_NUM_MASK;
itw->itw_device_addr = usba_device->usb_addr;
mutex_exit(&usba_device->usb_mutex);
itw->itw_id = EHCI_GET_ID((void *)itw);
ASSERT(itw->itw_id != 0);
USB_DPRINTF_L3(PRINT_MASK_ALLOC, ehcip->ehci_log_hdl,
"ehci_create_itw: itw = 0x%p real_length = 0x%lx",
(void *)itw, real_length);
ehcip->ehci_periodic_req_count++;
ehci_toggle_scheduler(ehcip);
return (itw);
}
void
ehci_deallocate_itw(
ehci_state_t *ehcip,
ehci_pipe_private_t *pp,
ehci_isoc_xwrapper_t *itw)
{
ehci_isoc_xwrapper_t *prev, *next;
USB_DPRINTF_L4(PRINT_MASK_ALLOC, ehcip->ehci_log_hdl,
"ehci_deallocate_itw: itw = 0x%p", (void *)itw);
if (itw->itw_itd_head) {
ASSERT(itw->itw_itd_tail != NULL);
return;
}
ASSERT(itw->itw_itd_tail == NULL);
ehci_deallocate_itds_for_itw(ehcip, itw);
if (pp->pp_itw_head == itw) {
if (pp->pp_itw_tail == itw) {
pp->pp_itw_head = NULL;
pp->pp_itw_tail = NULL;
} else {
pp->pp_itw_head = itw->itw_next;
}
} else {
prev = pp->pp_itw_head;
next = prev->itw_next;
while (next && (next != itw)) {
prev = next;
next = next->itw_next;
}
if (next == itw) {
prev->itw_next = next->itw_next;
if (pp->pp_itw_tail == itw) {
pp->pp_itw_tail = prev;
}
}
}
ehci_free_itw_dma(ehcip, pp, itw);
ehcip->ehci_periodic_req_count--;
ehci_toggle_scheduler(ehcip);
}
static void
ehci_free_itw_dma(
ehci_state_t *ehcip,
ehci_pipe_private_t *pp,
ehci_isoc_xwrapper_t *itw)
{
int rval;
USB_DPRINTF_L4(PRINT_MASK_ALLOC, ehcip->ehci_log_hdl,
"ehci_free_itw_dma: itw = 0x%p", (void *)itw);
ASSERT(itw != NULL);
ASSERT(itw->itw_id != 0);
EHCI_FREE_ID((uint32_t)itw->itw_id);
rval = ddi_dma_unbind_handle(itw->itw_dmahandle);
ASSERT(rval == DDI_SUCCESS);
ddi_dma_mem_free(&itw->itw_accesshandle);
ddi_dma_free_handle(&itw->itw_dmahandle);
kmem_free(itw, sizeof (ehci_isoc_xwrapper_t));
}
static ehci_itd_t *
ehci_allocate_itd(ehci_state_t *ehcip)
{
int i, state;
ehci_itd_t *itd;
ASSERT(mutex_owned(&ehcip->ehci_int_mutex));
for (i = 0; i < ehci_itd_pool_size; i ++) {
state = Get_ITD(ehcip->ehci_itd_pool_addr[i].itd_state);
if (state == EHCI_ITD_FREE) {
break;
}
}
if (i >= ehci_itd_pool_size) {
USB_DPRINTF_L2(PRINT_MASK_ALLOC, ehcip->ehci_log_hdl,
"ehci_allocate_itd: ITD exhausted");
return (NULL);
}
USB_DPRINTF_L4(PRINT_MASK_ALLOC, ehcip->ehci_log_hdl,
"ehci_allocate_itd: Allocated %d", i);
itd = &ehcip->ehci_itd_pool_addr[i];
USB_DPRINTF_L3(PRINT_MASK_LISTS, ehcip->ehci_log_hdl,
"ehci_allocate_itd: itd 0x%p", (void *)itd);
Set_ITD(itd->itd_state, EHCI_ITD_DUMMY);
return (itd);
}
void
ehci_deallocate_itd(
ehci_state_t *ehcip,
ehci_isoc_xwrapper_t *itw,
ehci_itd_t *old_itd)
{
ehci_itd_t *itd, *next_itd;
USB_DPRINTF_L4(PRINT_MASK_ALLOC, ehcip->ehci_log_hdl,
"ehci_deallocate_itd: old_itd = 0x%p", (void *)old_itd);
ASSERT(mutex_owned(&ehcip->ehci_int_mutex));
if (Get_ITD(old_itd->itd_state) != EHCI_ITD_RECLAIM) {
ehci_remove_isoc_from_pfl(ehcip, old_itd);
}
ASSERT(Get_ITD_FRAME(old_itd->itd_frame_number) == 0);
itd = itw->itw_itd_head;
if (old_itd != itd) {
next_itd = ehci_itd_iommu_to_cpu(ehcip,
Get_ITD(itd->itd_itw_next_itd));
while (next_itd != old_itd) {
itd = next_itd;
next_itd = ehci_itd_iommu_to_cpu(ehcip,
Get_ITD(itd->itd_itw_next_itd));
}
Set_ITD(itd->itd_itw_next_itd, old_itd->itd_itw_next_itd);
if (itd->itd_itw_next_itd == 0) {
itw->itw_itd_tail = itd;
}
} else {
itw->itw_itd_head = ehci_itd_iommu_to_cpu(
ehcip, Get_ITD(old_itd->itd_itw_next_itd));
if (itw->itw_itd_head == NULL) {
itw->itw_itd_tail = NULL;
}
}
bzero((char *)old_itd, sizeof (ehci_itd_t));
Set_ITD(old_itd->itd_state, EHCI_ITD_FREE);
USB_DPRINTF_L3(PRINT_MASK_LISTS, ehcip->ehci_log_hdl,
"Dealloc_itd: itd 0x%p", (void *)old_itd);
}
uint_t
ehci_calc_num_itds(
ehci_isoc_xwrapper_t *itw,
size_t pkt_count)
{
uint_t multiplier, itd_count;
if (itw->itw_port_status == USBA_HIGH_SPEED_DEV) {
multiplier = 1 * 8;
itd_count = pkt_count / multiplier;
if (pkt_count % multiplier) {
itd_count++;
}
} else {
itd_count = (uint_t)pkt_count;
}
return (itd_count);
}
int
ehci_allocate_itds_for_itw(
ehci_state_t *ehcip,
ehci_isoc_xwrapper_t *itw,
uint_t itd_count)
{
ehci_itd_t *itd;
uint32_t itd_addr;
int i;
int error = USB_SUCCESS;
for (i = 0; i < itd_count; i += 1) {
itd = ehci_allocate_itd(ehcip);
if (itd == NULL) {
error = USB_NO_RESOURCES;
USB_DPRINTF_L2(PRINT_MASK_LISTS, ehcip->ehci_log_hdl,
"ehci_allocate_itds_for_itw: "
"Unable to allocate %d ITDs",
itd_count);
break;
}
if (i > 0) {
itd_addr = ehci_itd_cpu_to_iommu(ehcip,
itw->itw_itd_free_list);
Set_ITD(itd->itd_link_ptr, itd_addr);
}
Set_ITD_INDEX(itd, 0, EHCI_ITD_UNUSED_INDEX);
Set_ITD_INDEX(itd, 1, EHCI_ITD_UNUSED_INDEX);
Set_ITD_INDEX(itd, 2, EHCI_ITD_UNUSED_INDEX);
Set_ITD_INDEX(itd, 3, EHCI_ITD_UNUSED_INDEX);
Set_ITD_INDEX(itd, 4, EHCI_ITD_UNUSED_INDEX);
Set_ITD_INDEX(itd, 5, EHCI_ITD_UNUSED_INDEX);
Set_ITD_INDEX(itd, 6, EHCI_ITD_UNUSED_INDEX);
Set_ITD_INDEX(itd, 7, EHCI_ITD_UNUSED_INDEX);
itw->itw_itd_free_list = itd;
}
return (error);
}
static void
ehci_deallocate_itds_for_itw(
ehci_state_t *ehcip,
ehci_isoc_xwrapper_t *itw)
{
ehci_itd_t *itd = NULL;
ehci_itd_t *temp_itd = NULL;
USB_DPRINTF_L4(PRINT_MASK_ALLOC, ehcip->ehci_log_hdl,
"ehci_free_itw_itd_resources: itw = 0x%p", (void *)itw);
itd = itw->itw_itd_free_list;
while (itd != NULL) {
temp_itd = ehci_itd_iommu_to_cpu(ehcip,
Get_ITD(itd->itd_link_ptr));
ehci_deallocate_itd(ehcip, itw, itd);
itd = temp_itd;
}
itw->itw_itd_free_list = NULL;
}
void ehci_insert_itd_on_itw(
ehci_state_t *ehcip,
ehci_isoc_xwrapper_t *itw,
ehci_itd_t *itd)
{
Set_ITD(itd->itd_itw_next_itd, 0);
if (itw->itw_itd_head == NULL) {
ASSERT(itw->itw_itd_tail == NULL);
itw->itw_itd_head = itd;
itw->itw_itd_tail = itd;
} else {
ehci_itd_t *dummy = (ehci_itd_t *)itw->itw_itd_tail;
ASSERT(dummy != NULL);
ASSERT(Get_ITD(itd->itd_state) == EHCI_ITD_ACTIVE);
Set_ITD(dummy->itd_itw_next_itd,
ehci_itd_cpu_to_iommu(ehcip, itd));
itw->itw_itd_tail = itd;
}
Set_ITD(itd->itd_trans_wrapper, (uint32_t)itw->itw_id);
}
void
ehci_insert_itd_into_active_list(
ehci_state_t *ehcip,
ehci_itd_t *itd)
{
ASSERT(mutex_owned(&ehcip->ehci_int_mutex));
ASSERT(itd != NULL);
Set_ITD(itd->itd_next_active_itd,
ehci_itd_cpu_to_iommu(ehcip, ehcip->ehci_active_itd_list));
ehcip->ehci_active_itd_list = itd;
}
void
ehci_remove_itd_from_active_list(
ehci_state_t *ehcip,
ehci_itd_t *itd)
{
ehci_itd_t *curr_itd, *next_itd;
ASSERT(mutex_owned(&ehcip->ehci_int_mutex));
ASSERT(itd != NULL);
USB_DPRINTF_L4(PRINT_MASK_LISTS, ehcip->ehci_log_hdl,
"ehci_remove_itd_from_active_list: "
"ehci_active_itd_list = 0x%p itd = 0x%p",
(void *)ehcip->ehci_active_itd_list, (void *)itd);
curr_itd = ehcip->ehci_active_itd_list;
if (curr_itd == itd) {
ehcip->ehci_active_itd_list =
ehci_itd_iommu_to_cpu(ehcip, itd->itd_next_active_itd);
itd->itd_next_active_itd = 0;
return;
}
next_itd = ehci_itd_iommu_to_cpu(ehcip, curr_itd->itd_next_active_itd);
while (next_itd != itd) {
curr_itd = next_itd;
if (curr_itd) {
next_itd = ehci_itd_iommu_to_cpu(ehcip,
curr_itd->itd_next_active_itd);
} else {
break;
}
}
if ((curr_itd) && (next_itd == itd)) {
Set_ITD(curr_itd->itd_next_active_itd,
Get_ITD(itd->itd_next_active_itd));
Set_ITD(itd->itd_next_active_itd, 0);
} else {
USB_DPRINTF_L3(PRINT_MASK_LISTS, ehcip->ehci_log_hdl,
"ehci_remove_itd_from_active_list: "
"Unable to find ITD in active_itd_list");
}
}
ehci_itd_t *
ehci_create_done_itd_list(
ehci_state_t *ehcip)
{
usb_frame_number_t current_frame_number;
usb_frame_number_t itd_frame_number, itd_reclaim_number;
ehci_itd_t *curr_itd = NULL, *next_itd = NULL;
ehci_itd_t *done_itd_list = NULL;
uint_t state;
USB_DPRINTF_L4(PRINT_MASK_INTR, ehcip->ehci_log_hdl,
"ehci_create_done_itd_list:");
ASSERT(mutex_owned(&ehcip->ehci_int_mutex));
current_frame_number = ehci_get_current_frame_number(ehcip);
curr_itd = ehcip->ehci_active_itd_list;
while (curr_itd) {
next_itd = ehci_itd_iommu_to_cpu(ehcip,
Get_ITD(curr_itd->itd_next_active_itd));
itd_frame_number = Get_ITD_FRAME(curr_itd->itd_frame_number);
itd_reclaim_number =
Get_ITD_FRAME(curr_itd->itd_reclaim_number);
state = Get_ITD(curr_itd->itd_state);
if (((state == EHCI_ITD_ACTIVE) &&
(itd_frame_number < current_frame_number)) ||
((state == EHCI_ITD_RECLAIM) &&
(itd_reclaim_number < current_frame_number))) {
ehci_remove_itd_from_active_list(ehcip, curr_itd);
Set_ITD(curr_itd->itd_next_active_itd,
ehci_itd_cpu_to_iommu(ehcip, done_itd_list));
done_itd_list = curr_itd;
}
curr_itd = next_itd;
}
return (done_itd_list);
}
int
ehci_insert_isoc_to_pfl(
ehci_state_t *ehcip,
ehci_pipe_private_t *pp,
ehci_isoc_xwrapper_t *itw)
{
usb_isoc_req_t *isoc_reqp = itw->itw_curr_xfer_reqp;
usb_frame_number_t current_frame_number, start_frame_number;
uint_t ddic, pfl_number;
ehci_periodic_frame_list_t *periodic_frame_list =
ehcip->ehci_periodic_frame_list_tablep;
uint32_t addr, port_status;
ehci_itd_t *itd;
USB_DPRINTF_L4(PRINT_MASK_LISTS, ehcip->ehci_log_hdl,
"ehci_insert_isoc_to_pfl: "
"isoc flags 0x%x itw = 0x%p",
isoc_reqp->isoc_attributes, (void *)itw);
ddic = ddi_enter_critical();
current_frame_number = ehci_get_current_frame_number(ehcip);
switch (isoc_reqp->isoc_attributes &
(USB_ATTRS_ISOC_START_FRAME | USB_ATTRS_ISOC_XFER_ASAP)) {
case USB_ATTRS_ISOC_START_FRAME:
if (pp->pp_flag & EHCI_ISOC_XFER_CONTINUE) {
start_frame_number = pp->pp_next_frame_number;
} else {
if ((isoc_reqp->isoc_frame_no == 0) ||
((isoc_reqp->isoc_frame_no +
isoc_reqp->isoc_pkts_count) <
current_frame_number)) {
ddi_exit_critical(ddic);
USB_DPRINTF_L2(PRINT_MASK_LISTS,
ehcip->ehci_log_hdl,
"ehci_insert_isoc_to_pfl:"
"Invalid starting frame number");
return (USB_INVALID_START_FRAME);
}
start_frame_number = isoc_reqp->isoc_frame_no;
pp->pp_next_frame_number = 0;
}
break;
case USB_ATTRS_ISOC_XFER_ASAP:
if ((pp->pp_next_frame_number) &&
(pp->pp_next_frame_number > current_frame_number)) {
start_frame_number = pp->pp_next_frame_number;
} else {
start_frame_number =
current_frame_number + EHCI_FRAME_OFFSET;
}
if (!(pp->pp_flag & EHCI_ISOC_XFER_CONTINUE)) {
isoc_reqp->isoc_frame_no = start_frame_number;
}
break;
default:
ddi_exit_critical(ddic);
USB_DPRINTF_L2(PRINT_MASK_LISTS, ehcip->ehci_log_hdl,
"ehci_insert_isoc_to_pfl: Either starting "
"frame number or ASAP flags are not set, attrs = 0x%x",
isoc_reqp->isoc_attributes);
return (USB_NO_FRAME_NUMBER);
}
if (itw->itw_port_status == USBA_HIGH_SPEED_DEV) {
port_status = EHCI_ITD_LINK_REF_ITD;
} else {
port_status = EHCI_ITD_LINK_REF_SITD;
}
itd = itw->itw_itd_head;
while (itd) {
pfl_number = start_frame_number % EHCI_NUM_PERIODIC_FRAME_LISTS;
addr = Get_PFLT(periodic_frame_list->
ehci_periodic_frame_list_table[pfl_number]);
Set_ITD(itd->itd_link_ptr, addr);
addr = ehci_itd_cpu_to_iommu(ehcip, itd) & EHCI_ITD_LINK_PTR;
addr |= port_status;
Set_PFLT(periodic_frame_list->
ehci_periodic_frame_list_table[pfl_number], addr);
Set_ITD_FRAME(itd->itd_frame_number, start_frame_number);
ehci_insert_itd_into_active_list(ehcip, itd);
itd = ehci_itd_iommu_to_cpu(ehcip,
Get_ITD(itd->itd_itw_next_itd));
start_frame_number++;
}
ddi_exit_critical(ddic);
USB_DPRINTF_L3(PRINT_MASK_LISTS, ehcip->ehci_log_hdl,
"ehci_insert_isoc_to_pfl: "
"current frame number 0x%llx start frame number 0x%llx num itds %d",
(unsigned long long)current_frame_number,
(unsigned long long)start_frame_number, itw->itw_num_itds);
pp->pp_next_frame_number = start_frame_number;
pp->pp_flag |= EHCI_ISOC_XFER_CONTINUE;
return (USB_SUCCESS);
}
void
ehci_remove_isoc_from_pfl(
ehci_state_t *ehcip,
ehci_itd_t *curr_itd)
{
ehci_periodic_frame_list_t *periodic_frame_list;
uint_t pfl_number;
uint32_t next_addr, curr_itd_addr;
uint32_t link_ref;
ehci_itd_t *prev_itd = NULL;
USB_DPRINTF_L4(PRINT_MASK_ALLOC, ehcip->ehci_log_hdl,
"ehci_remove_isoc_from_pfl:");
ASSERT(mutex_owned(&ehcip->ehci_int_mutex));
curr_itd_addr = ehci_itd_cpu_to_iommu(ehcip, curr_itd);
periodic_frame_list = ehcip->ehci_periodic_frame_list_tablep;
pfl_number = Get_ITD_FRAME(curr_itd->itd_frame_number) %
EHCI_NUM_PERIODIC_FRAME_LISTS;
USB_DPRINTF_L4(PRINT_MASK_ALLOC, ehcip->ehci_log_hdl,
"ehci_remove_isoc_from_pfl: itd = 0x%p pfl number 0x%x",
(void *)curr_itd, pfl_number);
next_addr = Get_PFLT(periodic_frame_list->
ehci_periodic_frame_list_table[pfl_number]);
while ((next_addr & EHCI_ITD_LINK_PTR) !=
(curr_itd_addr & EHCI_ITD_LINK_PTR)) {
link_ref = next_addr & EHCI_ITD_LINK_REF;
if ((link_ref == EHCI_ITD_LINK_REF_ITD) ||
(link_ref == EHCI_ITD_LINK_REF_SITD)) {
prev_itd = ehci_itd_iommu_to_cpu(ehcip,
(next_addr & EHCI_ITD_LINK_PTR));
next_addr = Get_ITD(prev_itd->itd_link_ptr);
} else {
break;
}
}
if ((next_addr & EHCI_ITD_LINK_PTR) ==
(curr_itd_addr & EHCI_ITD_LINK_PTR)) {
next_addr = Get_ITD(curr_itd->itd_link_ptr);
if (prev_itd == NULL) {
Set_PFLT(periodic_frame_list->
ehci_periodic_frame_list_table[pfl_number],
next_addr);
} else {
Set_ITD(prev_itd->itd_link_ptr, next_addr);
}
Set_ITD_FRAME(curr_itd->itd_frame_number, 0);
} else {
ASSERT((next_addr & EHCI_ITD_LINK_PTR) ==
(curr_itd_addr & EHCI_ITD_LINK_PTR));
USB_DPRINTF_L3(PRINT_MASK_ALLOC, ehcip->ehci_log_hdl,
"ehci_remove_isoc_from_pfl: Unable to find ITD in PFL");
}
}
int
ehci_allocate_isoc_in_resource(
ehci_state_t *ehcip,
ehci_pipe_private_t *pp,
ehci_isoc_xwrapper_t *itw,
usb_flags_t flags)
{
usba_pipe_handle_data_t *ph = pp->pp_pipe_handle;
usb_isoc_req_t *orig_isoc_reqp, *clone_isoc_reqp;
USB_DPRINTF_L4(PRINT_MASK_LISTS, ehcip->ehci_log_hdl,
"ehci_allocate_isoc_in_resource:"
"pp = 0x%p itw = 0x%p flags = 0x%x", (void *)pp, (void *)itw,
flags);
ASSERT(mutex_owned(&ehcip->ehci_int_mutex));
ASSERT(itw->itw_curr_xfer_reqp == NULL);
orig_isoc_reqp = (usb_isoc_req_t *)(pp->pp_client_periodic_in_reqp);
ASSERT(orig_isoc_reqp != NULL);
clone_isoc_reqp = usba_hcdi_dup_isoc_req(ph->p_dip,
orig_isoc_reqp, flags);
if (clone_isoc_reqp == NULL) {
USB_DPRINTF_L2(PRINT_MASK_LISTS, ehcip->ehci_log_hdl,
"ehci_allocate_isoc_in_resource: Isochronous"
"request structure allocation failed");
return (USB_NO_RESOURCES);
}
itw->itw_curr_xfer_reqp = orig_isoc_reqp;
pp->pp_client_periodic_in_reqp = (usb_opaque_t)clone_isoc_reqp;
mutex_enter(&ph->p_mutex);
ph->p_req_count++;
mutex_exit(&ph->p_mutex);
pp->pp_state = EHCI_PIPE_STATE_ACTIVE;
return (USB_SUCCESS);
}
void
ehci_deallocate_isoc_in_resource(
ehci_state_t *ehcip,
ehci_pipe_private_t *pp,
ehci_isoc_xwrapper_t *itw)
{
usba_pipe_handle_data_t *ph = pp->pp_pipe_handle;
uchar_t ep_attr = ph->p_ep.bmAttributes;
usb_isoc_req_t *isoc_reqp;
USB_DPRINTF_L4(PRINT_MASK_LISTS,
ehcip->ehci_log_hdl,
"ehci_deallocate_isoc_in_resource: "
"pp = 0x%p itw = 0x%p", (void *)pp, (void *)itw);
ASSERT(mutex_owned(&ehcip->ehci_int_mutex));
ASSERT((ep_attr & USB_EP_ATTR_MASK) == USB_EP_ATTR_ISOCH);
isoc_reqp = itw->itw_curr_xfer_reqp;
if (isoc_reqp) {
itw->itw_curr_xfer_reqp = NULL;
itw->itw_curr_isoc_pktp = NULL;
mutex_enter(&ph->p_mutex);
ph->p_req_count--;
mutex_exit(&ph->p_mutex);
usb_free_isoc_req(isoc_reqp);
pp->pp_state = EHCI_PIPE_STATE_IDLE;
}
}
uint32_t
ehci_itd_cpu_to_iommu(
ehci_state_t *ehcip,
ehci_itd_t *addr)
{
uint32_t td;
ASSERT(mutex_owned(&ehcip->ehci_int_mutex));
if (addr == NULL)
return (0);
td = (uint32_t)ehcip->ehci_itd_pool_cookie.dmac_address +
(uint32_t)((uintptr_t)addr -
(uintptr_t)(ehcip->ehci_itd_pool_addr));
ASSERT(((uint32_t) (sizeof (ehci_itd_t) *
(addr - ehcip->ehci_itd_pool_addr))) ==
((uint32_t)((uintptr_t)addr - (uintptr_t)
(ehcip->ehci_itd_pool_addr))));
ASSERT(td >= ehcip->ehci_itd_pool_cookie.dmac_address);
ASSERT(td <= ehcip->ehci_itd_pool_cookie.dmac_address +
sizeof (ehci_itd_t) * ehci_itd_pool_size);
return (td);
}
ehci_itd_t *
ehci_itd_iommu_to_cpu(
ehci_state_t *ehcip,
uintptr_t addr)
{
ehci_itd_t *itd;
ASSERT(mutex_owned(&ehcip->ehci_int_mutex));
if (addr == 0)
return (NULL);
itd = (ehci_itd_t *)((uintptr_t)
(addr - ehcip->ehci_itd_pool_cookie.dmac_address) +
(uintptr_t)ehcip->ehci_itd_pool_addr);
ASSERT(itd >= ehcip->ehci_itd_pool_addr);
ASSERT((uintptr_t)itd <= (uintptr_t)ehcip->ehci_itd_pool_addr +
(uintptr_t)(sizeof (ehci_itd_t) * ehci_itd_pool_size));
return (itd);
}
void ehci_parse_isoc_error(
ehci_state_t *ehcip,
ehci_isoc_xwrapper_t *itw,
ehci_itd_t *itd)
{
usb_isoc_req_t *isoc_reqp;
usb_cr_t error;
ASSERT(mutex_owned(&ehcip->ehci_int_mutex));
isoc_reqp = itw->itw_curr_xfer_reqp;
if (itw->itw_port_status == USBA_HIGH_SPEED_DEV) {
error = ehci_parse_itd_error(ehcip, itw, itd);
} else {
error = ehci_parse_sitd_error(ehcip, itw, itd);
if (error != USB_CR_OK) {
isoc_reqp->isoc_error_count++;
USB_DPRINTF_L2(PRINT_MASK_INTR, ehcip->ehci_log_hdl,
"ehci_parse_sitd_error: Error %d Device Address %d"
" Endpoint number %d", error, itw->itw_device_addr,
itw->itw_endpoint_num);
}
}
}
static usb_cr_t ehci_parse_itd_error(
ehci_state_t *ehcip,
ehci_isoc_xwrapper_t *itw,
ehci_itd_t *itd)
{
uint32_t status, index;
usb_cr_t error = USB_CR_OK;
uint32_t i;
usb_isoc_req_t *isoc_reqp;
isoc_reqp = itw->itw_curr_xfer_reqp;
for (i = 0; i < EHCI_ITD_CTRL_LIST_SIZE; i++) {
index = Get_ITD_INDEX(itd, i);
if (index == 0xffffffff) {
continue;
}
error = USB_CR_OK;
status = Get_ITD_BODY(itd, EHCI_ITD_CTRL0 + i) &
EHCI_ITD_XFER_STATUS_MASK;
if (status & EHCI_ITD_XFER_DATA_BUFFER_ERR) {
if (itw->itw_direction == USB_EP_DIR_OUT) {
USB_DPRINTF_L3(PRINT_MASK_INTR,
ehcip->ehci_log_hdl,
"ehci_parse_itd_error: BUFFER Underrun");
error = USB_CR_BUFFER_UNDERRUN;
} else {
USB_DPRINTF_L3(PRINT_MASK_INTR,
ehcip->ehci_log_hdl,
"ehci_parse_itd_error: BUFFER Overrun");
error = USB_CR_BUFFER_OVERRUN;
}
}
if (status & EHCI_ITD_XFER_BABBLE) {
USB_DPRINTF_L3(PRINT_MASK_INTR, ehcip->ehci_log_hdl,
"ehci_parse_itd_error: BABBLE DETECTED");
error = USB_CR_DATA_OVERRUN;
}
if (status & EHCI_ITD_XFER_ERROR) {
USB_DPRINTF_L3(PRINT_MASK_INTR, ehcip->ehci_log_hdl,
"ehci_parse_itd_error: XACT ERROR");
error = USB_CR_DEV_NOT_RESP;
}
if (status & EHCI_ITD_XFER_ACTIVE) {
USB_DPRINTF_L3(PRINT_MASK_INTR, ehcip->ehci_log_hdl,
"ehci_parse_itd_error: NOT ACCESSED");
error = USB_CR_NOT_ACCESSED;
}
itw->itw_curr_isoc_pktp->isoc_pkt_actual_length = 0;
itw->itw_curr_isoc_pktp->isoc_pkt_status = error;
if (error != USB_CR_OK) {
isoc_reqp->isoc_error_count++;
USB_DPRINTF_L3(PRINT_MASK_INTR, ehcip->ehci_log_hdl,
"ehci_parse_itd_error: Error %d Device Address %d "
"Endpoint number %d", error, itw->itw_device_addr,
itw->itw_endpoint_num);
}
itw->itw_curr_isoc_pktp++;
}
return (error);
}
static usb_cr_t ehci_parse_sitd_error(
ehci_state_t *ehcip,
ehci_isoc_xwrapper_t *itw,
ehci_itd_t *itd)
{
uint32_t status;
usb_cr_t error;
usb_isoc_pkt_descr_t *isoc_pkt_descr;
uint32_t residue;
isoc_pkt_descr = itw->itw_curr_isoc_pktp;
status = Get_ITD_BODY(itd, EHCI_SITD_XFER_STATE) &
EHCI_SITD_XFER_STATUS_MASK;
switch (status) {
case EHCI_SITD_XFER_ACTIVE:
USB_DPRINTF_L4(PRINT_MASK_INTR, ehcip->ehci_log_hdl,
"ehci_check_for_sitd_error: NOT ACCESSED");
error = USB_CR_NOT_ACCESSED;
break;
case EHCI_SITD_XFER_ERROR:
USB_DPRINTF_L4(PRINT_MASK_INTR, ehcip->ehci_log_hdl,
"ehci_check_for_sitd_error: TT ERROR");
error = USB_CR_UNSPECIFIED_ERR;
break;
case EHCI_SITD_XFER_DATA_BUFFER_ERR:
if (itw->itw_direction == USB_EP_DIR_OUT) {
USB_DPRINTF_L4(PRINT_MASK_INTR, ehcip->ehci_log_hdl,
"ehci_check_for_sitd_error: BUFFER Underrun");
error = USB_CR_BUFFER_UNDERRUN;
} else {
USB_DPRINTF_L4(PRINT_MASK_INTR, ehcip->ehci_log_hdl,
"ehci_check_for_sitd_error: BUFFER Overrun");
error = USB_CR_BUFFER_OVERRUN;
}
break;
case EHCI_SITD_XFER_BABBLE:
USB_DPRINTF_L4(PRINT_MASK_INTR, ehcip->ehci_log_hdl,
"ehci_check_for_sitd_error: BABBLE");
error = USB_CR_DATA_OVERRUN;
break;
case EHCI_SITD_XFER_XACT_ERROR:
USB_DPRINTF_L4(PRINT_MASK_INTR, ehcip->ehci_log_hdl,
"ehci_check_for_sitd_error: XACT ERROR");
error = USB_CR_DEV_NOT_RESP;
break;
case EHCI_SITD_XFER_MISSED_UFRAME:
USB_DPRINTF_L4(PRINT_MASK_INTR, ehcip->ehci_log_hdl,
"ehci_check_for_sitd_error: MISSED UFRAME");
error = USB_CR_NOT_ACCESSED;
break;
default:
USB_DPRINTF_L4(PRINT_MASK_INTR, ehcip->ehci_log_hdl,
"ehci_check_for_sitd_error: NO ERROR");
error = USB_CR_OK;
break;
}
residue =
(Get_ITD_BODY(itd, EHCI_SITD_XFER_STATE) &
EHCI_SITD_XFER_TOTAL_MASK) >>
EHCI_SITD_XFER_TOTAL_SHIFT;
isoc_pkt_descr->isoc_pkt_actual_length -= residue;
isoc_pkt_descr->isoc_pkt_status = error;
itw->itw_curr_isoc_pktp++;
return (error);
}
void
ehci_print_itd(
ehci_state_t *ehcip,
ehci_itd_t *itd)
{
USB_DPRINTF_L3(PRINT_MASK_LISTS, ehcip->ehci_log_hdl,
"ehci_print_itd: itd = 0x%p", (void *)itd);
USB_DPRINTF_L3(PRINT_MASK_LISTS, ehcip->ehci_log_hdl,
"\titd_link_ptr: 0x%x ", Get_ITD(itd->itd_link_ptr));
USB_DPRINTF_L3(PRINT_MASK_LISTS, ehcip->ehci_log_hdl,
"\titd_ctrl0: 0x%x ",
Get_ITD(itd->itd_body[EHCI_ITD_CTRL0]));
USB_DPRINTF_L3(PRINT_MASK_LISTS, ehcip->ehci_log_hdl,
"\titd_ctrl1: 0x%x ",
Get_ITD(itd->itd_body[EHCI_ITD_CTRL1]));
USB_DPRINTF_L3(PRINT_MASK_LISTS, ehcip->ehci_log_hdl,
"\titd_ctrl2: 0x%x ",
Get_ITD(itd->itd_body[EHCI_ITD_CTRL2]));
USB_DPRINTF_L3(PRINT_MASK_LISTS, ehcip->ehci_log_hdl,
"\titd_ctrl3: 0x%x ",
Get_ITD(itd->itd_body[EHCI_ITD_CTRL3]));
USB_DPRINTF_L3(PRINT_MASK_LISTS, ehcip->ehci_log_hdl,
"\titd_ctrl4: 0x%x ",
Get_ITD(itd->itd_body[EHCI_ITD_CTRL4]));
USB_DPRINTF_L3(PRINT_MASK_LISTS, ehcip->ehci_log_hdl,
"\titd_ctrl5: 0x%x ",
Get_ITD(itd->itd_body[EHCI_ITD_CTRL5]));
USB_DPRINTF_L3(PRINT_MASK_LISTS, ehcip->ehci_log_hdl,
"\titd_ctrl6: 0x%x ",
Get_ITD(itd->itd_body[EHCI_ITD_CTRL6]));
USB_DPRINTF_L3(PRINT_MASK_LISTS, ehcip->ehci_log_hdl,
"\titd_ctrl7: 0x%x ",
Get_ITD(itd->itd_body[EHCI_ITD_CTRL7]));
USB_DPRINTF_L3(PRINT_MASK_LISTS, ehcip->ehci_log_hdl,
"\titd_buffer0: 0x%x ",
Get_ITD(itd->itd_body[EHCI_ITD_BUFFER0]));
USB_DPRINTF_L3(PRINT_MASK_LISTS, ehcip->ehci_log_hdl,
"\titd_buffer1: 0x%x ",
Get_ITD(itd->itd_body[EHCI_ITD_BUFFER1]));
USB_DPRINTF_L3(PRINT_MASK_LISTS, ehcip->ehci_log_hdl,
"\titd_buffer2: 0x%x ",
Get_ITD(itd->itd_body[EHCI_ITD_BUFFER2]));
USB_DPRINTF_L3(PRINT_MASK_LISTS, ehcip->ehci_log_hdl,
"\titd_buffer3: 0x%x ",
Get_ITD(itd->itd_body[EHCI_ITD_BUFFER3]));
USB_DPRINTF_L3(PRINT_MASK_LISTS, ehcip->ehci_log_hdl,
"\titd_buffer4: 0x%x ",
Get_ITD(itd->itd_body[EHCI_ITD_BUFFER4]));
USB_DPRINTF_L3(PRINT_MASK_LISTS, ehcip->ehci_log_hdl,
"\titd_buffer5: 0x%x ",
Get_ITD(itd->itd_body[EHCI_ITD_BUFFER5]));
USB_DPRINTF_L3(PRINT_MASK_LISTS, ehcip->ehci_log_hdl,
"\titd_buffer6: 0x%x ",
Get_ITD(itd->itd_body[EHCI_ITD_BUFFER6]));
USB_DPRINTF_L3(PRINT_MASK_LISTS, ehcip->ehci_log_hdl,
"\titd_trans_wrapper: 0x%x ",
Get_ITD(itd->itd_trans_wrapper));
USB_DPRINTF_L3(PRINT_MASK_LISTS, ehcip->ehci_log_hdl,
"\titd_itw_next_itd: 0x%x ",
Get_ITD(itd->itd_itw_next_itd));
USB_DPRINTF_L3(PRINT_MASK_LISTS, ehcip->ehci_log_hdl,
"\titd_state: 0x%x ",
Get_ITD(itd->itd_state));
USB_DPRINTF_L3(PRINT_MASK_LISTS, ehcip->ehci_log_hdl,
"\titd_index: 0x%x 0x%x 0x%x 0x%x 0x%x 0x%x 0x%x 0x%x ",
Get_ITD_INDEX(itd, 0), Get_ITD_INDEX(itd, 1),
Get_ITD_INDEX(itd, 2), Get_ITD_INDEX(itd, 3),
Get_ITD_INDEX(itd, 4), Get_ITD_INDEX(itd, 5),
Get_ITD_INDEX(itd, 6), Get_ITD_INDEX(itd, 7));
USB_DPRINTF_L3(PRINT_MASK_LISTS, ehcip->ehci_log_hdl,
"\titd_frame_number: 0x%x ",
Get_ITD(itd->itd_frame_number));
USB_DPRINTF_L3(PRINT_MASK_LISTS, ehcip->ehci_log_hdl,
"\titd_reclaim_number: 0x%x ",
Get_ITD(itd->itd_reclaim_number));
USB_DPRINTF_L3(PRINT_MASK_LISTS, ehcip->ehci_log_hdl,
"\titd_next_active_itd: 0x%x ",
Get_ITD(itd->itd_next_active_itd));
}
void
ehci_print_sitd(
ehci_state_t *ehcip,
ehci_itd_t *itd)
{
USB_DPRINTF_L3(PRINT_MASK_LISTS, ehcip->ehci_log_hdl,
"ehci_print_itd: itd = 0x%p", (void *)itd);
USB_DPRINTF_L3(PRINT_MASK_LISTS, ehcip->ehci_log_hdl,
"\titd_link_ptr: 0x%x ", Get_ITD(itd->itd_link_ptr));
USB_DPRINTF_L3(PRINT_MASK_LISTS, ehcip->ehci_log_hdl,
"\tsitd_ctrl: 0x%x ",
Get_ITD(itd->itd_body[EHCI_SITD_CTRL]));
USB_DPRINTF_L3(PRINT_MASK_LISTS, ehcip->ehci_log_hdl,
"\tsitd_uframe_sched: 0x%x ",
Get_ITD(itd->itd_body[EHCI_SITD_UFRAME_SCHED]));
USB_DPRINTF_L3(PRINT_MASK_LISTS, ehcip->ehci_log_hdl,
"\tsitd_xfer_state: 0x%x ",
Get_ITD(itd->itd_body[EHCI_SITD_XFER_STATE]));
USB_DPRINTF_L3(PRINT_MASK_LISTS, ehcip->ehci_log_hdl,
"\tsitd_buffer0: 0x%x ",
Get_ITD(itd->itd_body[EHCI_SITD_BUFFER0]));
USB_DPRINTF_L3(PRINT_MASK_LISTS, ehcip->ehci_log_hdl,
"\tsitd_buffer1: 0x%x ",
Get_ITD(itd->itd_body[EHCI_SITD_BUFFER1]));
USB_DPRINTF_L3(PRINT_MASK_LISTS, ehcip->ehci_log_hdl,
"\tsitd_prev_sitd: 0x%x ",
Get_ITD(itd->itd_body[EHCI_SITD_PREV_SITD]));
USB_DPRINTF_L3(PRINT_MASK_LISTS, ehcip->ehci_log_hdl,
"\titd_trans_wrapper: 0x%x ",
Get_ITD(itd->itd_trans_wrapper));
USB_DPRINTF_L3(PRINT_MASK_LISTS, ehcip->ehci_log_hdl,
"\titd_itw_next_itd: 0x%x ",
Get_ITD(itd->itd_itw_next_itd));
USB_DPRINTF_L3(PRINT_MASK_LISTS, ehcip->ehci_log_hdl,
"\titd_state: 0x%x ",
Get_ITD(itd->itd_state));
USB_DPRINTF_L3(PRINT_MASK_LISTS, ehcip->ehci_log_hdl,
"\titd_frame_number: 0x%x ",
Get_ITD(itd->itd_frame_number));
USB_DPRINTF_L3(PRINT_MASK_LISTS, ehcip->ehci_log_hdl,
"\titd_reclaim_number: 0x%x ",
Get_ITD(itd->itd_reclaim_number));
USB_DPRINTF_L3(PRINT_MASK_LISTS, ehcip->ehci_log_hdl,
"\titd_next_active_itd: 0x%x ",
Get_ITD(itd->itd_next_active_itd));
}