예제 #1
0
int
xhci_cmd_disable_slot(xhci_t *const xhci, const int slot_id)
{
	trb_t *const cmd = xhci_next_command_trb(xhci);
	TRB_SET(TT, cmd, TRB_CMD_DISABLE_SLOT);
	TRB_SET(ID, cmd, slot_id);
	xhci_post_command(xhci);

	return xhci_wait_for_command(xhci, cmd, 1);
}
예제 #2
0
int
xhci_cmd_stop_endpoint(xhci_t *const xhci, const int slot_id, const int ep)
{
	trb_t *const cmd = xhci_next_command_trb(xhci);
	TRB_SET(TT, cmd, TRB_CMD_STOP_EP);
	TRB_SET(ID, cmd, slot_id);
	TRB_SET(EP, cmd, ep);
	xhci_post_command(xhci);

	return xhci_wait_for_command(xhci, cmd, 1);
}
예제 #3
0
int
xhci_cmd_set_tr_dq(xhci_t *const xhci, const int slot_id, const int ep,
		   trb_t *const dq_trb, const int dcs)
{
	trb_t *const cmd = xhci_next_command_trb(xhci);
	TRB_SET(TT, cmd, TRB_CMD_SET_TR_DQ);
	TRB_SET(ID, cmd, slot_id);
	TRB_SET(EP, cmd, ep);
	cmd->ptr_low = virt_to_phys(dq_trb) | dcs;
	xhci_post_command(xhci);

	return xhci_wait_for_command(xhci, cmd, 1);
}
예제 #4
0
int
xhci_cmd_evaluate_context(xhci_t *const xhci,
			  const int slot_id,
			  inputctx_t *const ic)
{
	trb_t *const cmd = xhci_next_command_trb(xhci);
	TRB_SET(TT, cmd, TRB_CMD_EVAL_CTX);
	TRB_SET(ID, cmd, slot_id);
	cmd->ptr_low = virt_to_phys(ic->raw);
	xhci_post_command(xhci);

	return xhci_wait_for_command(xhci, cmd, 1);
}
예제 #5
0
int
xhci_cmd_address_device(xhci_t *const xhci,
			const int slot_id,
			inputctx_t *const ic)
{
	trb_t *const cmd = xhci_next_command_trb(xhci);
	TRB_SET(TT, cmd, TRB_CMD_ADDRESS_DEV);
	TRB_SET(ID, cmd, slot_id);
	cmd->ptr_low = virt_to_phys(ic->raw);
	xhci_post_command(xhci);

	return xhci_wait_for_command(xhci, cmd, 1);
}
예제 #6
0
int
xhci_cmd_configure_endpoint(xhci_t *const xhci,
			    const int slot_id,
			    const int config_id,
			    inputctx_t *const ic)
{
	trb_t *const cmd = xhci_next_command_trb(xhci);
	TRB_SET(TT, cmd, TRB_CMD_CONFIGURE_EP);
	TRB_SET(ID, cmd, slot_id);
	cmd->ptr_low = virt_to_phys(ic->raw);
	if (config_id == 0)
		TRB_SET(DC, cmd, 1);
	xhci_post_command(xhci);

	return xhci_wait_for_command(xhci, cmd, 1);
}
예제 #7
0
int
xhci_cmd_enable_slot(xhci_t *const xhci, int *const slot_id)
{
	trb_t *const cmd = xhci_next_command_trb(xhci);
	TRB_SET(TT, cmd, TRB_CMD_ENABLE_SLOT);
	xhci_post_command(xhci);

	int cc = xhci_wait_for_command(xhci, cmd, 0);
	if (cc >= 0) {
		if (cc == CC_SUCCESS) {
			*slot_id = TRB_GET(ID, xhci->er.cur);
			if (*slot_id > xhci->max_slots_en)
				cc = CONTROLLER_ERROR;
		}
		xhci_advance_event_ring(xhci);
		xhci_handle_events(xhci);
	}
	return cc;
}
예제 #8
0
static void
xhci_reinit (hci_t *controller)
{
	xhci_t *const xhci = XHCI_INST(controller);

	if (xhci_wait_ready(xhci))
		return;

	/* Enable all available slots */
	xhci->opreg->config = xhci->max_slots_en;

	/* Set DCBAA */
	xhci->opreg->dcbaap_lo = virt_to_phys(xhci->dcbaa);
	xhci->opreg->dcbaap_hi = 0;

	/* Initialize command ring */
	xhci_init_cycle_ring(&xhci->cr, COMMAND_RING_SIZE);
	xhci_debug("command ring @%p (0x%08x)\n",
		   xhci->cr.ring, virt_to_phys(xhci->cr.ring));
	xhci->opreg->crcr_lo = virt_to_phys(xhci->cr.ring) | CRCR_RCS;
	xhci->opreg->crcr_hi = 0;

	/* Make sure interrupts are disabled */
	xhci->opreg->usbcmd &= ~USBCMD_INTE;

	/* Initialize event ring */
	xhci_reset_event_ring(&xhci->er);
	xhci_debug("event ring @%p (0x%08x)\n",
		   xhci->er.ring, virt_to_phys(xhci->er.ring));
	xhci_debug("ERST Max: 0x%lx ->  0x%lx entries\n",
		   xhci->capreg->ERST_Max, 1 << xhci->capreg->ERST_Max);
	memset((void*)xhci->ev_ring_table, 0x00, sizeof(erst_entry_t));
	xhci->ev_ring_table[0].seg_base_lo = virt_to_phys(xhci->er.ring);
	xhci->ev_ring_table[0].seg_base_hi = 0;
	xhci->ev_ring_table[0].seg_size = EVENT_RING_SIZE;

	/* Initialize primary interrupter */
	xhci->hcrreg->intrrs[0].erstsz = 1;
	xhci_update_event_dq(xhci);
	/* erstba has to be written at last */
	xhci->hcrreg->intrrs[0].erstba_lo = virt_to_phys(xhci->ev_ring_table);
	xhci->hcrreg->intrrs[0].erstba_hi = 0;

	xhci_start(controller);

#ifdef USB_DEBUG
	int i;
	for (i = 0; i < 32; ++i) {
		xhci_debug("NOOP run #%d\n", i);
		trb_t *const cmd = xhci_next_command_trb(xhci);
		TRB_SET(TT, cmd, TRB_CMD_NOOP);

		xhci_post_command(xhci);

		/* Wait for result in event ring */
		xhci_wait_for_command_done(xhci, cmd, 1);
		xhci_debug("Command ring is %srunning\n",
			   (xhci->opreg->crcr_lo & CRCR_CRR) ? "" : "not ");
	}
#endif
}