Update to hekate bdk 5.6.0
This commit is contained in:
parent
a89e9b4d7f
commit
f2f3c5daf0
43 changed files with 1530 additions and 1533 deletions
|
@ -4,7 +4,7 @@
|
|||
* Copyright (c) 2003-2008 Alan Stern
|
||||
* Copyright (c) 2009 Samsung Electronics
|
||||
* Author: Michal Nazarewicz <m.nazarewicz@samsung.com>
|
||||
* Copyright (c) 2019-2020 CTCaer
|
||||
* Copyright (c) 2019-2021 CTCaer
|
||||
*
|
||||
* This program is free software; you can redistribute it and/or modify it
|
||||
* under the terms and conditions of the GNU General Public License,
|
||||
|
@ -109,7 +109,7 @@
|
|||
#define SS_WRITE_ERROR 0x30C02
|
||||
#define SS_WRITE_PROTECTED 0x72700
|
||||
|
||||
#define SK(x) ((u8) ((x) >> 16)) /* Sense Key byte, etc. */
|
||||
#define SK(x) ((u8) ((x) >> 16)) // Sense Key byte, etc.
|
||||
#define ASC(x) ((u8) ((x) >> 8))
|
||||
#define ASCQ(x) ((u8) (x))
|
||||
|
||||
|
@ -217,6 +217,7 @@ typedef struct _usbd_gadget_ums_t {
|
|||
u32 tag;
|
||||
u32 residue;
|
||||
u32 usb_amount_left;
|
||||
bool cbw_req_queued;
|
||||
|
||||
u32 phase_error;
|
||||
u32 short_packet_received;
|
||||
|
@ -368,12 +369,12 @@ static void _ums_transfer_out_big_read(usbd_gadget_ums_t *ums, bulk_ctxt_t *bulk
|
|||
bulk_ctxt->bulk_out_buf_state = BUF_STATE_FULL;
|
||||
}
|
||||
|
||||
static void _ums_transfer_finish(usbd_gadget_ums_t *ums, bulk_ctxt_t *bulk_ctxt, u32 ep)
|
||||
static void _ums_transfer_finish(usbd_gadget_ums_t *ums, bulk_ctxt_t *bulk_ctxt, u32 ep, u32 sync_timeout)
|
||||
{
|
||||
if (ep == bulk_ctxt->bulk_in)
|
||||
{
|
||||
bulk_ctxt->bulk_in_status = usb_ops.usb_device_ep1_in_writing_finish(
|
||||
&bulk_ctxt->bulk_in_length_actual);
|
||||
&bulk_ctxt->bulk_in_length_actual, sync_timeout);
|
||||
|
||||
if (bulk_ctxt->bulk_in_status == USB_ERROR_XFER_ERROR)
|
||||
{
|
||||
|
@ -386,7 +387,7 @@ static void _ums_transfer_finish(usbd_gadget_ums_t *ums, bulk_ctxt_t *bulk_ctxt,
|
|||
else
|
||||
{
|
||||
bulk_ctxt->bulk_out_status = usb_ops.usb_device_ep1_out_reading_finish(
|
||||
&bulk_ctxt->bulk_out_length_actual);
|
||||
&bulk_ctxt->bulk_out_length_actual, sync_timeout);
|
||||
|
||||
if (bulk_ctxt->bulk_out_status == USB_ERROR_XFER_ERROR)
|
||||
{
|
||||
|
@ -460,6 +461,7 @@ static int _scsi_read(usbd_gadget_ums_t *ums, bulk_ctxt_t *bulk_ctxt)
|
|||
}
|
||||
if (lba_offset >= ums->lun.num_sectors)
|
||||
{
|
||||
ums->set_text(ums->label, "#FF8000 Warn:# Read - Out of range! Host notified.");
|
||||
ums->lun.sense_data = SS_LOGICAL_BLOCK_ADDRESS_OUT_OF_RANGE;
|
||||
|
||||
return UMS_RES_INVALID_ARG;
|
||||
|
@ -497,7 +499,7 @@ static int _scsi_read(usbd_gadget_ums_t *ums, bulk_ctxt_t *bulk_ctxt)
|
|||
|
||||
// Wait for the async USB transfer to finish.
|
||||
if (!first_read)
|
||||
_ums_transfer_finish(ums, bulk_ctxt, bulk_ctxt->bulk_in);
|
||||
_ums_transfer_finish(ums, bulk_ctxt, bulk_ctxt->bulk_in, USB_XFER_SYNCED);
|
||||
|
||||
lba_offset += amount;
|
||||
amount_left -= amount;
|
||||
|
@ -548,6 +550,7 @@ static int _scsi_write(usbd_gadget_ums_t *ums, bulk_ctxt_t *bulk_ctxt)
|
|||
|
||||
if (ums->lun.ro)
|
||||
{
|
||||
ums->set_text(ums->label, "#FF8000 Warn:# Write - Read only! Host notified.");
|
||||
ums->lun.sense_data = SS_WRITE_PROTECTED;
|
||||
|
||||
return UMS_RES_INVALID_ARG;
|
||||
|
@ -571,19 +574,20 @@ static int _scsi_write(usbd_gadget_ums_t *ums, bulk_ctxt_t *bulk_ctxt)
|
|||
// Check that starting LBA is not past the end sector offset.
|
||||
if (lba_offset >= ums->lun.num_sectors)
|
||||
{
|
||||
ums->set_text(ums->label, "#FF8000 Warn:# Write - Out of range! Host notified.");
|
||||
ums->lun.sense_data = SS_LOGICAL_BLOCK_ADDRESS_OUT_OF_RANGE;
|
||||
|
||||
return UMS_RES_INVALID_ARG;
|
||||
}
|
||||
|
||||
/* Carry out the file writes */
|
||||
// Carry out the file writes.
|
||||
usb_lba_offset = lba_offset;
|
||||
amount_left_to_req = ums->data_size_from_cmnd;
|
||||
amount_left_to_write = ums->data_size_from_cmnd;
|
||||
|
||||
while (amount_left_to_write > 0)
|
||||
{
|
||||
/* Queue a request for more data from the host */
|
||||
// Queue a request for more data from the host.
|
||||
if (amount_left_to_req > 0)
|
||||
{
|
||||
|
||||
|
@ -638,12 +642,12 @@ static int _scsi_write(usbd_gadget_ums_t *ums, bulk_ctxt_t *bulk_ctxt)
|
|||
*/
|
||||
amount = MIN(amount, bulk_ctxt->bulk_out_length);
|
||||
|
||||
/* Don't write a partial block */
|
||||
// Don't write a partial block.
|
||||
amount -= (amount & 511);
|
||||
if (amount == 0)
|
||||
goto empty_write;
|
||||
|
||||
/* Perform the write */
|
||||
// Perform the write.
|
||||
if (!sdmmc_storage_write(ums->lun.storage, ums->lun.offset + lba_offset,
|
||||
amount >> UMS_DISK_LBA_SHIFT, (u8 *)bulk_ctxt->bulk_out_buf))
|
||||
amount = 0;
|
||||
|
@ -654,7 +658,7 @@ DPRINTF("file write %X @ %X\n", amount, lba_offset);
|
|||
amount_left_to_write -= amount;
|
||||
ums->residue -= amount;
|
||||
|
||||
/* If an error occurred, report it and its position */
|
||||
// If an error occurred, report it and its position.
|
||||
if (!amount)
|
||||
{
|
||||
ums->set_text(ums->label, "#FFDD00 Error:# SDMMC Write!");
|
||||
|
@ -684,6 +688,7 @@ static int _scsi_verify(usbd_gadget_ums_t *ums, bulk_ctxt_t *bulk_ctxt)
|
|||
u32 lba_offset = get_array_be_to_le32(&ums->cmnd[2]);
|
||||
if (lba_offset >= ums->lun.num_sectors)
|
||||
{
|
||||
ums->set_text(ums->label, "#FF8000 Warn:# Verif - Out of range! Host notified.");
|
||||
ums->lun.sense_data = SS_LOGICAL_BLOCK_ADDRESS_OUT_OF_RANGE;
|
||||
|
||||
return UMS_RES_INVALID_ARG;
|
||||
|
@ -1005,7 +1010,7 @@ static int _scsi_mode_sense(usbd_gadget_ums_t *ums, bulk_ctxt_t *bulk_ctxt)
|
|||
return UMS_RES_INVALID_ARG;
|
||||
}
|
||||
|
||||
/* Store the mode data length */
|
||||
// Store the mode data length.
|
||||
if (ums->cmnd[0] == SC_MODE_SENSE_6)
|
||||
buf0[0] = len - 1;
|
||||
else
|
||||
|
@ -1538,12 +1543,12 @@ static int finish_reply(usbd_gadget_ums_t *ums, bulk_ctxt_t *bulk_ctxt)
|
|||
|
||||
static int received_cbw(usbd_gadget_ums_t *ums, bulk_ctxt_t *bulk_ctxt)
|
||||
{
|
||||
/* Was this a real packet? Should it be ignored? */
|
||||
// Was this a real packet? Should it be ignored?
|
||||
if (bulk_ctxt->bulk_out_status || bulk_ctxt->bulk_out_ignore || ums->lun.unmounted)
|
||||
{
|
||||
if (bulk_ctxt->bulk_out_status || ums->lun.unmounted)
|
||||
{
|
||||
DPRINTF("USB: EP timeout\n");
|
||||
DPRINTF("USB: EP timeout (%d)\n", bulk_ctxt->bulk_out_status);
|
||||
// In case we disconnected, exit UMS.
|
||||
// Raise timeout if removable and didn't got a unit ready command inside 4s.
|
||||
if (bulk_ctxt->bulk_out_status == USB2_ERROR_XFER_EP_DISABLED ||
|
||||
|
@ -1574,6 +1579,8 @@ static int received_cbw(usbd_gadget_ums_t *ums, bulk_ctxt_t *bulk_ctxt)
|
|||
{
|
||||
ums->set_text(ums->label, "#C7EA46 Status:# Medium unmounted");
|
||||
ums->timeouts++;
|
||||
if (!bulk_ctxt->bulk_out_status)
|
||||
ums->timeouts += 3;
|
||||
}
|
||||
|
||||
if (ums->timeouts > 20)
|
||||
|
@ -1584,27 +1591,32 @@ static int received_cbw(usbd_gadget_ums_t *ums, bulk_ctxt_t *bulk_ctxt)
|
|||
return UMS_RES_INVALID_ARG;
|
||||
}
|
||||
|
||||
/* Is the CBW valid? */
|
||||
// Clear request flag to allow a new one to be queued.
|
||||
ums->cbw_req_queued = false;
|
||||
|
||||
// Is the CBW valid?
|
||||
bulk_recv_pkt_t *cbw = (bulk_recv_pkt_t *)bulk_ctxt->bulk_out_buf;
|
||||
if (bulk_ctxt->bulk_out_length_actual != USB_BULK_CB_WRAP_LEN || cbw->Signature != USB_BULK_CB_SIG)
|
||||
{
|
||||
gfx_printf("USB: invalid CBW: len %X sig 0x%X\n", bulk_ctxt->bulk_out_length_actual, cbw->Signature);
|
||||
|
||||
// The Bulk-only spec says we MUST stall the IN endpoint
|
||||
// (6.6.1), so it's unavoidable. It also says we must
|
||||
// retain this state until the next reset, but there's
|
||||
// no way to tell the controller driver it should ignore
|
||||
// Clear-Feature(HALT) requests.
|
||||
//
|
||||
// We aren't required to halt the OUT endpoint; instead
|
||||
// we can simply accept and discard any data received
|
||||
// until the next reset.
|
||||
/*
|
||||
* The Bulk-only spec says we MUST stall the IN endpoint
|
||||
* (6.6.1), so it's unavoidable. It also says we must
|
||||
* retain this state until the next reset, but there's
|
||||
* no way to tell the controller driver it should ignore
|
||||
* Clear-Feature(HALT) requests.
|
||||
*
|
||||
* We aren't required to halt the OUT endpoint; instead
|
||||
* we can simply accept and discard any data received
|
||||
* until the next reset.
|
||||
*/
|
||||
ums_wedge_bulk_in_endpoint(ums);
|
||||
bulk_ctxt->bulk_out_ignore = 1;
|
||||
return UMS_RES_INVALID_ARG;
|
||||
}
|
||||
|
||||
/* Is the CBW meaningful? */
|
||||
// Is the CBW meaningful?
|
||||
if (cbw->Lun >= UMS_MAX_LUN || cbw->Flags & ~USB_BULK_IN_FLAG ||
|
||||
cbw->Length == 0 || cbw->Length > SCSI_MAX_CMD_SZ)
|
||||
{
|
||||
|
@ -1623,7 +1635,7 @@ static int received_cbw(usbd_gadget_ums_t *ums, bulk_ctxt_t *bulk_ctxt)
|
|||
return UMS_RES_INVALID_ARG;
|
||||
}
|
||||
|
||||
/* Save the command for later */
|
||||
// Save the command for later.
|
||||
ums->cmnd_size = cbw->Length;
|
||||
memcpy(ums->cmnd, cbw->CDB, ums->cmnd_size);
|
||||
|
||||
|
@ -1658,8 +1670,20 @@ static int get_next_command(usbd_gadget_ums_t *ums, bulk_ctxt_t *bulk_ctxt)
|
|||
|
||||
bulk_ctxt->bulk_out_length = USB_BULK_CB_WRAP_LEN;
|
||||
|
||||
/* Queue a request to read a Bulk-only CBW */
|
||||
_ums_transfer_start(ums, bulk_ctxt, bulk_ctxt->bulk_out, USB_XFER_SYNCED_CMD);
|
||||
// Queue a request to read a Bulk-only CBW.
|
||||
if (!ums->cbw_req_queued)
|
||||
_ums_transfer_start(ums, bulk_ctxt, bulk_ctxt->bulk_out, USB_XFER_SYNCED_CMD);
|
||||
else
|
||||
_ums_transfer_finish(ums, bulk_ctxt, bulk_ctxt->bulk_out, USB_XFER_SYNCED_CMD);
|
||||
|
||||
/*
|
||||
* On XUSB do not allow multiple requests for CBW to be done.
|
||||
* This avoids an issue with some XHCI controllers and OS combos (e.g. ASMedia and Linux/Mac OS)
|
||||
* which confuse that and concatenate an old CBW request with another write request (SCSI Write)
|
||||
* and create a babble error (transmit overflow).
|
||||
*/
|
||||
if (ums->xusb)
|
||||
ums->cbw_req_queued = true;
|
||||
|
||||
/* We will drain the buffer in software, which means we
|
||||
* can reuse it for the next filling. No need to advance
|
||||
|
@ -1696,7 +1720,7 @@ static void send_status(usbd_gadget_ums_t *ums, bulk_ctxt_t *bulk_ctxt)
|
|||
SK(sd), ASC(sd), ASCQ(sd), ums->lun.sense_data_info);
|
||||
}
|
||||
|
||||
/* Store and send the Bulk-only CSW */
|
||||
// Store and send the Bulk-only CSW.
|
||||
bulk_send_pkt_t *csw = (bulk_send_pkt_t *)bulk_ctxt->bulk_in_buf;
|
||||
|
||||
csw->Signature = USB_BULK_CS_SIG;
|
||||
|
@ -1712,7 +1736,7 @@ static void handle_exception(usbd_gadget_ums_t *ums, bulk_ctxt_t *bulk_ctxt)
|
|||
{
|
||||
enum ums_state old_state;
|
||||
|
||||
/* Clear out the controller's fifos */
|
||||
// Clear out the controller's fifos.
|
||||
ums_flush_endpoint(bulk_ctxt->bulk_in);
|
||||
ums_flush_endpoint(bulk_ctxt->bulk_out);
|
||||
|
||||
|
@ -1735,7 +1759,7 @@ static void handle_exception(usbd_gadget_ums_t *ums, bulk_ctxt_t *bulk_ctxt)
|
|||
|
||||
ums->state = UMS_STATE_NORMAL;
|
||||
|
||||
/* Carry out any extra actions required for the exception */
|
||||
// Carry out any extra actions required for the exception.
|
||||
switch (old_state)
|
||||
{
|
||||
case UMS_STATE_NORMAL:
|
||||
|
@ -1757,7 +1781,7 @@ static void handle_exception(usbd_gadget_ums_t *ums, bulk_ctxt_t *bulk_ctxt)
|
|||
break;
|
||||
|
||||
case UMS_STATE_EXIT:
|
||||
ums->state = UMS_STATE_TERMINATED; /* Stop the thread */
|
||||
ums->state = UMS_STATE_TERMINATED; // Stop the thread.
|
||||
break;
|
||||
|
||||
default:
|
||||
|
|
|
@ -1,7 +1,7 @@
|
|||
/*
|
||||
* Enhanced & eXtensible USB device (EDCI & XDCI) driver for Tegra X1
|
||||
*
|
||||
* Copyright (c) 2019-2020 CTCaer
|
||||
* Copyright (c) 2019-2021 CTCaer
|
||||
*
|
||||
* This program is free software; you can redistribute it and/or modify it
|
||||
* under the terms and conditions of the GNU General Public License,
|
||||
|
@ -200,6 +200,8 @@ typedef struct _t210_usb2d_t
|
|||
#define XHCI_ST_IP BIT(4)
|
||||
#define XUSB_DEV_XHCI_RT_IMOD 0x38
|
||||
#define XUSB_DEV_XHCI_PORTSC 0x3C
|
||||
#define XHCI_PORTSC_CCS BIT(0)
|
||||
#define XHCI_PORTSC_PED BIT(1)
|
||||
#define XHCI_PORTSC_PR BIT(4)
|
||||
#define XHCI_PORTSC_PLS_MASK (0xF << 5)
|
||||
#define XHCI_PORTSC_PLS_U0 (0 << 5)
|
||||
|
@ -226,11 +228,12 @@ typedef struct _t210_usb2d_t
|
|||
#define XUSB_DEV_XHCI_ECPLO 0x40
|
||||
#define XUSB_DEV_XHCI_ECPHI 0x44
|
||||
#define XUSB_DEV_XHCI_EP_HALT 0x50
|
||||
#define XHCI_EP_HALT_DCI BIT(0)
|
||||
#define XHCI_EP_HALT_DCI_EP0_IN BIT(0)
|
||||
#define XUSB_DEV_XHCI_EP_PAUSE 0x54
|
||||
#define XUSB_DEV_XHCI_EP_RELOAD 0x58
|
||||
#define XUSB_DEV_XHCI_EP_STCHG 0x5C
|
||||
#define XUSB_DEV_XHCI_PORTHALT 0x6C
|
||||
#define XUSB_DEV_XHCI_EP_STOPPED 0x78
|
||||
#define XHCI_PORTHALT_HALT_LTSSM BIT(0)
|
||||
#define XHCI_PORTHALT_STCHG_REQ BIT(20)
|
||||
#define XUSB_DEV_XHCI_CFG_DEV_FE 0x85C
|
||||
|
|
|
@ -1,7 +1,7 @@
|
|||
/*
|
||||
* Enhanced USB Device (EDCI) driver for Tegra X1
|
||||
*
|
||||
* Copyright (c) 2019-2020 CTCaer
|
||||
* Copyright (c) 2019-2021 CTCaer
|
||||
*
|
||||
* This program is free software; you can redistribute it and/or modify it
|
||||
* under the terms and conditions of the GNU General Public License,
|
||||
|
@ -1455,7 +1455,7 @@ static int _usbd_get_ep1_out_bytes_read()
|
|||
return (usbdaemon->ep_bytes_requested[USB_EP_BULK_OUT] - (usbdaemon->qhs[USB_EP_BULK_OUT].token >> 16));
|
||||
}
|
||||
|
||||
int usb_device_ep1_out_reading_finish(u32 *pending_bytes)
|
||||
int usb_device_ep1_out_reading_finish(u32 *pending_bytes, u32 sync_timeout)
|
||||
{
|
||||
usb_ep_status_t ep_status;
|
||||
do
|
||||
|
@ -1504,7 +1504,7 @@ static int _usbd_get_ep1_in_bytes_written()
|
|||
return (usbdaemon->ep_bytes_requested[USB_EP_BULK_IN] - (usbdaemon->qhs[USB_EP_BULK_IN].token >> 16));
|
||||
}
|
||||
|
||||
int usb_device_ep1_in_writing_finish(u32 *pending_bytes)
|
||||
int usb_device_ep1_in_writing_finish(u32 *pending_bytes, u32 sync_timeout)
|
||||
{
|
||||
usb_ep_status_t ep_status;
|
||||
do
|
||||
|
|
|
@ -1,7 +1,7 @@
|
|||
/*
|
||||
* Enhanced & eXtensible USB Device (EDCI & XDCI) driver for Tegra X1
|
||||
*
|
||||
* Copyright (c) 2019 CTCaer
|
||||
* Copyright (c) 2019-2021 CTCaer
|
||||
*
|
||||
* This program is free software; you can redistribute it and/or modify it
|
||||
* under the terms and conditions of the GNU General Public License,
|
||||
|
@ -148,6 +148,7 @@ typedef enum _usb_error_t
|
|||
XUSB_ERROR_INVALID_EP = USB_ERROR_XFER_ERROR, // From 2.
|
||||
XUSB_ERROR_XFER_BULK_IN_RESIDUE = 7,
|
||||
XUSB_ERROR_INVALID_CYCLE = USB2_ERROR_XFER_EP_DISABLED, // From 8.
|
||||
XUSB_ERROR_BABBLE_DETECTED = 50,
|
||||
XUSB_ERROR_SEQ_NUM = 51,
|
||||
XUSB_ERROR_XFER_DIR = 52,
|
||||
XUSB_ERROR_PORT_CFG = 54
|
||||
|
@ -175,9 +176,9 @@ typedef struct _usb_ops_t
|
|||
|
||||
int (*usb_device_ep1_out_read)(u8 *, u32, u32 *, u32);
|
||||
int (*usb_device_ep1_out_read_big)(u8 *, u32, u32 *);
|
||||
int (*usb_device_ep1_out_reading_finish)(u32 *);
|
||||
int (*usb_device_ep1_out_reading_finish)(u32 *, u32);
|
||||
int (*usb_device_ep1_in_write)(u8 *, u32, u32 *, u32);
|
||||
int (*usb_device_ep1_in_writing_finish)(u32 *);
|
||||
int (*usb_device_ep1_in_writing_finish)(u32 *, u32);
|
||||
bool (*usb_device_get_suspended)();
|
||||
bool (*usb_device_get_port_in_sleep)();
|
||||
} usb_ops_t;
|
||||
|
|
264
bdk/usb/xusbd.c
264
bdk/usb/xusbd.c
|
@ -1,7 +1,7 @@
|
|||
/*
|
||||
* eXtensible USB Device driver (XDCI) for Tegra X1
|
||||
*
|
||||
* Copyright (c) 2020 CTCaer
|
||||
* Copyright (c) 2020-2021 CTCaer
|
||||
*
|
||||
* This program is free software; you can redistribute it and/or modify it
|
||||
* under the terms and conditions of the GNU General Public License,
|
||||
|
@ -368,7 +368,7 @@ typedef struct _xusbd_controller_t
|
|||
event_trb_t *event_dequeue_ptr;
|
||||
u32 event_ccs;
|
||||
u32 device_state;
|
||||
u32 bytes_remaining[2];
|
||||
u32 tx_bytes[2];
|
||||
u32 tx_count[2];
|
||||
u32 ctrl_seq_num;
|
||||
u32 config_num;
|
||||
|
@ -881,7 +881,7 @@ int xusb_device_init()
|
|||
_xusbd_init_device_clocks();
|
||||
|
||||
// Enable AHB redirect for access to IRAM for Event/EP ring buffers.
|
||||
mc_enable_ahb_redirect(); // Can be skipped if IRAM is not used.
|
||||
mc_enable_ahb_redirect(false); // Can be skipped if IRAM is not used.
|
||||
|
||||
// Enable XUSB device IPFS.
|
||||
XUSB_DEV_DEV(XUSB_DEV_CONFIGURATION) |= DEV_CONFIGURATION_EN_FPCI;
|
||||
|
@ -927,7 +927,7 @@ int xusb_device_init()
|
|||
return USB_RES_OK;
|
||||
}
|
||||
|
||||
static int _xusb_queue_trb(int ep_idx, void *trb, bool ring_doorbell)
|
||||
static int _xusb_queue_trb(u32 ep_idx, void *trb, bool ring_doorbell)
|
||||
{
|
||||
int res = USB_RES_OK;
|
||||
data_trb_t *next_trb;
|
||||
|
@ -1073,7 +1073,7 @@ static int _xusb_issue_normal_trb(u8 *buf, u32 len, usb_dir_t direction)
|
|||
normal_trb_t trb = {0};
|
||||
|
||||
_xusb_create_normal_trb(&trb, buf, len, direction);
|
||||
int ep_idx = USB_EP_BULK_IN;
|
||||
u32 ep_idx = USB_EP_BULK_IN;
|
||||
if (direction == USB_DIR_OUT)
|
||||
ep_idx = USB_EP_BULK_OUT;
|
||||
int res = _xusb_queue_trb(ep_idx, &trb, EP_RING_DOORBELL);
|
||||
|
@ -1100,19 +1100,32 @@ static int _xusb_issue_data_trb(u8 *buf, u32 len, usb_dir_t direction)
|
|||
|
||||
int xusb_set_ep_stall(u32 endpoint, int ep_stall)
|
||||
{
|
||||
int ep_idx = BIT(endpoint);
|
||||
u32 ep_mask = BIT(endpoint);
|
||||
if (ep_stall)
|
||||
XUSB_DEV_XHCI(XUSB_DEV_XHCI_EP_HALT) |= ep_idx;
|
||||
XUSB_DEV_XHCI(XUSB_DEV_XHCI_EP_HALT) |= ep_mask;
|
||||
else
|
||||
XUSB_DEV_XHCI(XUSB_DEV_XHCI_EP_HALT) &= ~ep_idx;
|
||||
XUSB_DEV_XHCI(XUSB_DEV_XHCI_EP_HALT) &= ~ep_mask;
|
||||
|
||||
// Wait for EP status to change.
|
||||
int res = _xusb_xhci_mask_wait(XUSB_DEV_XHCI_EP_STCHG, ep_idx, ep_idx, 1000);
|
||||
int res = _xusb_xhci_mask_wait(XUSB_DEV_XHCI_EP_STCHG, ep_mask, ep_mask, 1000);
|
||||
if (res)
|
||||
return res;
|
||||
|
||||
// Clear status change.
|
||||
XUSB_DEV_XHCI(XUSB_DEV_XHCI_EP_STCHG) = ep_idx;
|
||||
XUSB_DEV_XHCI(XUSB_DEV_XHCI_EP_STCHG) = ep_mask;
|
||||
|
||||
return USB_RES_OK;
|
||||
}
|
||||
|
||||
static int _xusb_wait_ep_stopped(u32 endpoint)
|
||||
{
|
||||
u32 ep_mask = BIT(endpoint);
|
||||
|
||||
// Wait for EP status to change.
|
||||
_xusb_xhci_mask_wait(XUSB_DEV_XHCI_EP_STOPPED, ep_mask, ep_mask, 1000);
|
||||
|
||||
// Clear status change.
|
||||
XUSB_DEV_XHCI(XUSB_DEV_XHCI_EP_STOPPED) = ep_mask;
|
||||
|
||||
return USB_RES_OK;
|
||||
}
|
||||
|
@ -1158,20 +1171,27 @@ static int _xusb_handle_transfer_event(transfer_event_trb_t *trb)
|
|||
return _xusb_issue_status_trb(USB_DIR_OUT);
|
||||
else if (usbd_xotg->wait_for_event_trb == XUSB_TRB_STATUS)
|
||||
{
|
||||
if (usbd_xotg->device_state == XUSB_ADDRESSED_STS_WAIT)
|
||||
switch (usbd_xotg->device_state)
|
||||
{
|
||||
case XUSB_ADDRESSED_STS_WAIT:
|
||||
usbd_xotg->device_state = XUSB_ADDRESSED;
|
||||
else if (usbd_xotg->device_state == XUSB_CONFIGURED_STS_WAIT)
|
||||
break;
|
||||
case XUSB_CONFIGURED_STS_WAIT:
|
||||
usbd_xotg->device_state = XUSB_CONFIGURED;
|
||||
else if (usbd_xotg->device_state == XUSB_LUN_CONFIGURED_STS_WAIT)
|
||||
break;
|
||||
case XUSB_LUN_CONFIGURED_STS_WAIT:
|
||||
usbd_xotg->device_state = XUSB_LUN_CONFIGURED;
|
||||
else if (usbd_xotg->device_state == XUSB_HID_CONFIGURED_STS_WAIT)
|
||||
break;
|
||||
case XUSB_HID_CONFIGURED_STS_WAIT:
|
||||
usbd_xotg->device_state = XUSB_HID_CONFIGURED;
|
||||
break;
|
||||
}
|
||||
}
|
||||
break;
|
||||
|
||||
case USB_EP_BULK_IN:
|
||||
usbd_xotg->bytes_remaining[USB_DIR_IN] -= trb->trb_tx_len;
|
||||
if (usbd_xotg->tx_count[USB_DIR_IN])///////////
|
||||
usbd_xotg->tx_bytes[USB_DIR_IN] -= trb->trb_tx_len;
|
||||
if (usbd_xotg->tx_count[USB_DIR_IN])
|
||||
usbd_xotg->tx_count[USB_DIR_IN]--;
|
||||
|
||||
// If bytes remaining for a Bulk IN transfer, return error.
|
||||
|
@ -1181,8 +1201,8 @@ static int _xusb_handle_transfer_event(transfer_event_trb_t *trb)
|
|||
|
||||
case USB_EP_BULK_OUT:
|
||||
// If short packet and Bulk OUT, it's not an error because we prime EP for 4KB.
|
||||
usbd_xotg->bytes_remaining[USB_DIR_OUT] -= trb->trb_tx_len;
|
||||
if (usbd_xotg->tx_count[USB_DIR_OUT])///////////
|
||||
usbd_xotg->tx_bytes[USB_DIR_OUT] -= trb->trb_tx_len;
|
||||
if (usbd_xotg->tx_count[USB_DIR_OUT])
|
||||
usbd_xotg->tx_count[USB_DIR_OUT]--;
|
||||
break;
|
||||
}
|
||||
|
@ -1196,6 +1216,11 @@ static int _xusb_handle_transfer_event(transfer_event_trb_t *trb)
|
|||
xusb_set_ep_stall(trb->ep_id, USB_EP_CFG_STALL);
|
||||
return USB_RES_OK;
|
||||
*/
|
||||
case XUSB_COMP_BABBLE_DETECTED_ERROR:
|
||||
_xusb_wait_ep_stopped(trb->ep_id);
|
||||
xusb_set_ep_stall(trb->ep_id, USB_EP_CFG_STALL);
|
||||
return XUSB_ERROR_BABBLE_DETECTED;
|
||||
|
||||
case XUSB_COMP_CTRL_DIR_ERROR:
|
||||
return XUSB_ERROR_XFER_DIR;
|
||||
|
||||
|
@ -1216,11 +1241,52 @@ static int _xusb_handle_transfer_event(transfer_event_trb_t *trb)
|
|||
|
||||
static int _xusb_handle_port_change()
|
||||
{
|
||||
u32 res = USB_RES_OK;
|
||||
u32 status = XUSB_DEV_XHCI(XUSB_DEV_XHCI_PORTSC);
|
||||
u32 halt = XUSB_DEV_XHCI(XUSB_DEV_XHCI_PORTHALT);
|
||||
u32 clear_mask = XHCI_PORTSC_CEC | XHCI_PORTSC_PLC | XHCI_PORTSC_PRC | XHCI_PORTSC_WRC | XHCI_PORTSC_CSC;
|
||||
|
||||
// Connect status change (CSC).
|
||||
// Port reset (PR).
|
||||
if (status & XHCI_PORTSC_PR)
|
||||
{
|
||||
//! TODO:
|
||||
// XHCI_PORTSC_PR: device_state = XUSB_RESET
|
||||
|
||||
//_disable_usb_wdt4();
|
||||
}
|
||||
|
||||
// Port Reset Change (PRC).
|
||||
if (status & XHCI_PORTSC_PRC)
|
||||
{
|
||||
// Clear PRC bit.
|
||||
status &= ~clear_mask;
|
||||
status |= XHCI_PORTSC_PRC;
|
||||
XUSB_DEV_XHCI(XUSB_DEV_XHCI_PORTSC) = status;
|
||||
}
|
||||
|
||||
// Warm Port Reset (WPR).
|
||||
if (status & XHCI_PORTSC_WPR)
|
||||
{
|
||||
//_disable_usb_wdt4();
|
||||
|
||||
XUSB_DEV_XHCI(XUSB_DEV_XHCI_PORTHALT) &= ~XHCI_PORTHALT_HALT_LTSSM;
|
||||
(void)XUSB_DEV_XHCI(XUSB_DEV_XHCI_PORTHALT);
|
||||
|
||||
//! TODO: XHCI_PORTSC_WPR: device_state = XUSB_RESET
|
||||
}
|
||||
|
||||
// Warm Port Reset Change (WRC).
|
||||
if (status & XHCI_PORTSC_WRC)
|
||||
{
|
||||
// Clear WRC bit.
|
||||
status &= ~clear_mask;
|
||||
status |= XHCI_PORTSC_WRC;
|
||||
XUSB_DEV_XHCI(XUSB_DEV_XHCI_PORTSC) = status;
|
||||
}
|
||||
|
||||
// Reread port status to handle more changes.
|
||||
status = XUSB_DEV_XHCI(XUSB_DEV_XHCI_PORTSC);
|
||||
|
||||
// Connect Status Change (CSC).
|
||||
if (status & XHCI_PORTSC_CSC)
|
||||
{
|
||||
//! TODO: Check CCS.
|
||||
|
@ -1238,90 +1304,64 @@ static int _xusb_handle_port_change()
|
|||
volatile xusb_ep_ctx_t *ep_ctxt = &xusb_evtq->xusb_ep_ctxt[XUSB_EP_CTRL_IN];
|
||||
ep_ctxt->avg_trb_len = 8;
|
||||
ep_ctxt->max_packet_size = 64;
|
||||
//! TODO: If super speed is supported, ep context reload, unpause and unhalt must happen.
|
||||
}
|
||||
|
||||
// Clear CSC bit.
|
||||
status &= ~clear_mask;
|
||||
status |= XHCI_PORTSC_CSC;
|
||||
XUSB_DEV_XHCI(XUSB_DEV_XHCI_PORTSC) = status;
|
||||
}
|
||||
|
||||
// Port reset (PR), Port reset change (PRC).
|
||||
if (status & XHCI_PORTSC_PR || status & XHCI_PORTSC_PRC)
|
||||
{
|
||||
//! TODO:
|
||||
// XHCI_PORTSC_PR: device_state = XUSB_RESET
|
||||
|
||||
//_disable_usb_wdt4();
|
||||
|
||||
//res = _xusb_xhci_mask_wait(XUSB_DEV_XHCI_PORTSC, XHCI_PORTSC_PRC, XHCI_PORTSC_PRC, 50000); // unpatched0
|
||||
// if (res) return res;
|
||||
_xusb_xhci_mask_wait(XUSB_DEV_XHCI_PORTSC, XHCI_PORTSC_PRC, XHCI_PORTSC_PRC, 50000); // patched0
|
||||
|
||||
// Clear PRC bit.
|
||||
status = XUSB_DEV_XHCI(XUSB_DEV_XHCI_PORTSC) | XHCI_PORTSC_PRC;
|
||||
XUSB_DEV_XHCI(XUSB_DEV_XHCI_PORTSC) |= XHCI_PORTSC_PRC;
|
||||
}
|
||||
|
||||
// Warm Port Reset (WPR), Warm Port Reset Change (WRC).
|
||||
if (status & XHCI_PORTSC_WPR || status & XHCI_PORTSC_WRC)
|
||||
{
|
||||
XUSB_DEV_XHCI(XUSB_DEV_XHCI_PORTHALT) &= ~XHCI_PORTHALT_HALT_LTSSM;
|
||||
(void)XUSB_DEV_XHCI(XUSB_DEV_XHCI_PORTSC);
|
||||
res = _xusb_xhci_mask_wait(XUSB_DEV_XHCI_PORTSC, XHCI_PORTSC_WRC, XHCI_PORTSC_WRC, 1000);
|
||||
|
||||
// Clear WRC bit.
|
||||
status = XUSB_DEV_XHCI(XUSB_DEV_XHCI_PORTSC) | XHCI_PORTSC_WRC;
|
||||
XUSB_DEV_XHCI(XUSB_DEV_XHCI_PORTSC) |= XHCI_PORTSC_WRC;
|
||||
|
||||
//! TODO: WPR: device_state = XUSB_RESET
|
||||
}
|
||||
|
||||
// Handle Config Request (STCHG_REQ).
|
||||
if (halt & XHCI_PORTHALT_STCHG_REQ)
|
||||
{
|
||||
// Clear Link Training Status.
|
||||
status = XUSB_DEV_XHCI(XUSB_DEV_XHCI_PORTHALT) & ~XHCI_PORTHALT_HALT_LTSSM;
|
||||
// Clear Link Training Status and pending request/reject.
|
||||
XUSB_DEV_XHCI(XUSB_DEV_XHCI_PORTHALT) &= ~XHCI_PORTHALT_HALT_LTSSM;
|
||||
(void)XUSB_DEV_XHCI(XUSB_DEV_XHCI_PORTHALT);
|
||||
}
|
||||
|
||||
// Reread port status to handle more changes.
|
||||
status = XUSB_DEV_XHCI(XUSB_DEV_XHCI_PORTSC);
|
||||
|
||||
// Port link state change (PLC).
|
||||
if (status & XHCI_PORTSC_PLC)
|
||||
{
|
||||
//! WAR: Sometimes port speed changes without a CSC event. Set again.
|
||||
usbd_xotg->port_speed = (status & XHCI_PORTSC_PS) >> 10;
|
||||
|
||||
// check PLS
|
||||
// if U3
|
||||
// check XHCI_PORTSC_PLS_MASK
|
||||
// if XHCI_PORTSC_PLS_U3
|
||||
// device_state = XUSB_SUSPENDED
|
||||
// else if U0 and XUSB_SUSPENDED
|
||||
// else if XHCI_PORTSC_PLS_U0 and XUSB_SUSPENDED
|
||||
// val = XUSB_DEV_XHCI_EP_PAUSE
|
||||
// XUSB_DEV_XHCI_EP_PAUSE = 0
|
||||
// XUSB_DEV_XHCI_EP_STCHG = val;
|
||||
|
||||
// Clear PLC bit.
|
||||
status = XUSB_DEV_XHCI(XUSB_DEV_XHCI_PORTSC) | XHCI_PORTSC_PLC;
|
||||
XUSB_DEV_XHCI(XUSB_DEV_XHCI_PORTSC) |= XHCI_PORTSC_PLC;
|
||||
status &= ~clear_mask;
|
||||
status |= XHCI_PORTSC_PLC;
|
||||
XUSB_DEV_XHCI(XUSB_DEV_XHCI_PORTSC) = status;
|
||||
}
|
||||
|
||||
// Port configuration link error (CEC).
|
||||
if (status & XHCI_PORTSC_CEC)
|
||||
{
|
||||
XUSB_DEV_XHCI(XUSB_DEV_XHCI_PORTSC) |= XHCI_PORTSC_CEC;
|
||||
res = XUSB_ERROR_PORT_CFG;
|
||||
status = XUSB_DEV_XHCI(XUSB_DEV_XHCI_PORTSC);
|
||||
status &= ~clear_mask;
|
||||
status |= XHCI_PORTSC_CEC;
|
||||
XUSB_DEV_XHCI(XUSB_DEV_XHCI_PORTSC) = status;
|
||||
|
||||
return XUSB_ERROR_PORT_CFG;
|
||||
}
|
||||
|
||||
return res;
|
||||
return USB_RES_OK;
|
||||
}
|
||||
|
||||
static int _xusb_handle_get_ep_status(usb_ctrl_setup_t *ctrl_setup)
|
||||
static int _xusb_handle_get_ep_status(u32 ep_idx)
|
||||
{
|
||||
u32 ep_mask = BIT(ep_idx);
|
||||
static u8 xusb_ep_status_descriptor[2] = {0};
|
||||
|
||||
// Get EP context pointer.
|
||||
volatile xusb_ep_ctx_t *ep_ctxt = (volatile xusb_ep_ctx_t *)(XUSB_DEV_XHCI(XUSB_DEV_XHCI_ECPLO) & 0xFFFFFFF0);
|
||||
ep_ctxt = &ep_ctxt[ctrl_setup->wIndex];
|
||||
|
||||
xusb_ep_status_descriptor[0] = (ep_ctxt->ep_state == EP_HALTED) ? USB_STATUS_EP_HALTED : USB_STATUS_EP_OK;
|
||||
xusb_ep_status_descriptor[0] =
|
||||
(XUSB_DEV_XHCI(XUSB_DEV_XHCI_EP_HALT) & ep_mask) ? USB_STATUS_EP_HALTED : USB_STATUS_EP_OK;
|
||||
return _xusb_issue_data_trb(xusb_ep_status_descriptor, 2, USB_DIR_IN);
|
||||
}
|
||||
|
||||
|
@ -1536,8 +1576,9 @@ static int _xusbd_handle_ep0_control_transfer(usb_ctrl_setup_t *ctrl_setup)
|
|||
|
||||
//gfx_printf("ctrl: %02X %02X %04X %04X %04X\n", _bmRequestType, _bRequest, _wValue, _wIndex, _wLength);
|
||||
|
||||
XUSB_DEV_XHCI(XUSB_DEV_XHCI_EP_HALT) &= ~XHCI_EP_HALT_DCI;
|
||||
u32 res = _xusb_xhci_mask_wait(XUSB_DEV_XHCI_EP_HALT, XHCI_EP_HALT_DCI, 0, 1000);
|
||||
// Unhalt EP0 IN.
|
||||
XUSB_DEV_XHCI(XUSB_DEV_XHCI_EP_HALT) &= ~XHCI_EP_HALT_DCI_EP0_IN;
|
||||
u32 res = _xusb_xhci_mask_wait(XUSB_DEV_XHCI_EP_HALT, XHCI_EP_HALT_DCI_EP0_IN, 0, 1000);
|
||||
if (res)
|
||||
return res;
|
||||
|
||||
|
@ -1557,14 +1598,33 @@ static int _xusbd_handle_ep0_control_transfer(usb_ctrl_setup_t *ctrl_setup)
|
|||
case (USB_SETUP_HOST_TO_DEVICE | USB_SETUP_TYPE_STANDARD | USB_SETUP_RECIPIENT_ENDPOINT):
|
||||
if ((_wValue & 0xFF) == USB_FEATURE_ENDPOINT_HALT)
|
||||
{
|
||||
if (_bRequest == USB_REQUEST_CLEAR_FEATURE)
|
||||
if (_bRequest == USB_REQUEST_CLEAR_FEATURE || _bRequest == USB_REQUEST_SET_FEATURE)
|
||||
{
|
||||
xusb_set_ep_stall(_wIndex, USB_EP_CFG_CLEAR);
|
||||
return _xusb_issue_status_trb(USB_DIR_IN);
|
||||
}
|
||||
else if (_bRequest == USB_REQUEST_SET_FEATURE)
|
||||
{
|
||||
xusb_set_ep_stall(_wIndex, USB_EP_CFG_STALL);
|
||||
u32 ep = 0;
|
||||
switch (_wIndex) // endpoint
|
||||
{
|
||||
case USB_EP_ADDR_CTRL_OUT:
|
||||
ep = XUSB_EP_CTRL_OUT;
|
||||
break;
|
||||
case USB_EP_ADDR_CTRL_IN:
|
||||
ep = XUSB_EP_CTRL_IN;
|
||||
break;
|
||||
case USB_EP_ADDR_BULK_OUT:
|
||||
ep = USB_EP_BULK_OUT;
|
||||
break;
|
||||
case USB_EP_ADDR_BULK_IN:
|
||||
ep = USB_EP_BULK_IN;
|
||||
break;
|
||||
default:
|
||||
xusb_set_ep_stall(XUSB_EP_CTRL_IN, USB_EP_CFG_STALL);
|
||||
return USB_RES_OK;
|
||||
}
|
||||
|
||||
if (_bRequest == USB_REQUEST_CLEAR_FEATURE)
|
||||
xusb_set_ep_stall(ep, USB_EP_CFG_CLEAR);
|
||||
else if (_bRequest == USB_REQUEST_SET_FEATURE)
|
||||
xusb_set_ep_stall(ep, USB_EP_CFG_STALL);
|
||||
|
||||
return _xusb_issue_status_trb(USB_DIR_IN);
|
||||
}
|
||||
}
|
||||
|
@ -1631,7 +1691,28 @@ static int _xusbd_handle_ep0_control_transfer(usb_ctrl_setup_t *ctrl_setup)
|
|||
|
||||
case (USB_SETUP_DEVICE_TO_HOST | USB_SETUP_TYPE_STANDARD | USB_SETUP_RECIPIENT_ENDPOINT):
|
||||
if (_bRequest == USB_REQUEST_GET_STATUS)
|
||||
return _xusb_handle_get_ep_status(ctrl_setup);
|
||||
{
|
||||
u32 ep = 0;
|
||||
switch (_wIndex) // endpoint
|
||||
{
|
||||
case USB_EP_ADDR_CTRL_OUT:
|
||||
ep = XUSB_EP_CTRL_OUT;
|
||||
break;
|
||||
case USB_EP_ADDR_CTRL_IN:
|
||||
ep = XUSB_EP_CTRL_IN;
|
||||
break;
|
||||
case USB_EP_ADDR_BULK_OUT:
|
||||
ep = USB_EP_BULK_OUT;
|
||||
break;
|
||||
case USB_EP_ADDR_BULK_IN:
|
||||
ep = USB_EP_BULK_IN;
|
||||
break;
|
||||
default:
|
||||
xusb_set_ep_stall(XUSB_EP_CTRL_IN, USB_EP_CFG_STALL);
|
||||
return USB_RES_OK;
|
||||
}
|
||||
return _xusb_handle_get_ep_status(ep);
|
||||
}
|
||||
|
||||
ep_stall = true;
|
||||
break;
|
||||
|
@ -1821,6 +1902,7 @@ int xusb_device_enumerate(usb_gadget_type gadget)
|
|||
return USB_RES_OK;
|
||||
}
|
||||
|
||||
//! TODO: Do a full deinit.
|
||||
void xusb_end(bool reset_ep, bool only_controller)
|
||||
{
|
||||
CLOCK(CLK_RST_CONTROLLER_RST_DEV_W_SET) = BIT(CLK_W_XUSB_SS);
|
||||
|
@ -1855,7 +1937,7 @@ int xusb_device_ep1_out_read(u8 *buf, u32 len, u32 *bytes_read, u32 sync_tries)
|
|||
|
||||
int res = USB_RES_OK;
|
||||
usbd_xotg->tx_count[USB_DIR_OUT] = 0;
|
||||
usbd_xotg->bytes_remaining[USB_DIR_OUT] = len;
|
||||
usbd_xotg->tx_bytes[USB_DIR_OUT] = len;
|
||||
_xusb_issue_normal_trb(buf, len, USB_DIR_OUT);
|
||||
usbd_xotg->tx_count[USB_DIR_OUT]++;
|
||||
|
||||
|
@ -1865,7 +1947,7 @@ int xusb_device_ep1_out_read(u8 *buf, u32 len, u32 *bytes_read, u32 sync_tries)
|
|||
res = _xusb_ep_operation(sync_tries);
|
||||
|
||||
if (bytes_read)
|
||||
*bytes_read = res ? 0 : usbd_xotg->bytes_remaining[USB_DIR_OUT];
|
||||
*bytes_read = res ? 0 : usbd_xotg->tx_bytes[USB_DIR_OUT];
|
||||
|
||||
bpmp_mmu_maintenance(BPMP_MMU_MAINT_CLN_INV_WAY, false);
|
||||
}
|
||||
|
@ -1898,14 +1980,14 @@ int xusb_device_ep1_out_read_big(u8 *buf, u32 len, u32 *bytes_read)
|
|||
return USB_RES_OK;
|
||||
}
|
||||
|
||||
int xusb_device_ep1_out_reading_finish(u32 *pending_bytes)
|
||||
int xusb_device_ep1_out_reading_finish(u32 *pending_bytes, u32 sync_tries)
|
||||
{
|
||||
int res = USB_RES_OK;
|
||||
while (!res && usbd_xotg->tx_count[USB_DIR_OUT])
|
||||
res = _xusb_ep_operation(USB_XFER_SYNCED); // Infinite retries.
|
||||
res = _xusb_ep_operation(sync_tries); // Infinite retries.
|
||||
|
||||
if (pending_bytes)
|
||||
*pending_bytes = res ? 0 : usbd_xotg->bytes_remaining[USB_DIR_OUT];
|
||||
*pending_bytes = res ? 0 : usbd_xotg->tx_bytes[USB_DIR_OUT];
|
||||
|
||||
bpmp_mmu_maintenance(BPMP_MMU_MAINT_CLN_INV_WAY, false);
|
||||
|
||||
|
@ -1921,7 +2003,7 @@ int xusb_device_ep1_in_write(u8 *buf, u32 len, u32 *bytes_written, u32 sync_trie
|
|||
|
||||
int res = USB_RES_OK;
|
||||
usbd_xotg->tx_count[USB_DIR_IN] = 0;
|
||||
usbd_xotg->bytes_remaining[USB_DIR_IN] = len;
|
||||
usbd_xotg->tx_bytes[USB_DIR_IN] = len;
|
||||
_xusb_issue_normal_trb(buf, len, USB_DIR_IN);
|
||||
usbd_xotg->tx_count[USB_DIR_IN]++;
|
||||
|
||||
|
@ -1931,7 +2013,7 @@ int xusb_device_ep1_in_write(u8 *buf, u32 len, u32 *bytes_written, u32 sync_trie
|
|||
res = _xusb_ep_operation(sync_tries);
|
||||
|
||||
if (bytes_written)
|
||||
*bytes_written = res ? 0 : usbd_xotg->bytes_remaining[USB_DIR_IN];
|
||||
*bytes_written = res ? 0 : usbd_xotg->tx_bytes[USB_DIR_IN];
|
||||
}
|
||||
else
|
||||
{
|
||||
|
@ -1947,14 +2029,14 @@ int xusb_device_ep1_in_write(u8 *buf, u32 len, u32 *bytes_written, u32 sync_trie
|
|||
return res;
|
||||
}
|
||||
|
||||
int xusb_device_ep1_in_writing_finish(u32 *pending_bytes)
|
||||
int xusb_device_ep1_in_writing_finish(u32 *pending_bytes, u32 sync_tries)
|
||||
{
|
||||
int res = USB_RES_OK;
|
||||
while (!res && usbd_xotg->tx_count[USB_DIR_IN])
|
||||
res = _xusb_ep_operation(USB_XFER_SYNCED); // Infinite retries.
|
||||
res = _xusb_ep_operation(sync_tries); // Infinite retries.
|
||||
|
||||
if (pending_bytes)
|
||||
*pending_bytes = res ? 0 : usbd_xotg->bytes_remaining[USB_DIR_IN];
|
||||
*pending_bytes = res ? 0 : usbd_xotg->tx_bytes[USB_DIR_IN];
|
||||
|
||||
return res;
|
||||
}
|
||||
|
@ -2010,7 +2092,7 @@ void xusb_device_get_ops(usb_ops_t *ops)
|
|||
ops->usbd_flush_endpoint = NULL;
|
||||
ops->usbd_set_ep_stall = xusb_set_ep_stall;
|
||||
ops->usbd_handle_ep0_ctrl_setup = xusb_handle_ep0_ctrl_setup;
|
||||
ops->usbd_end = xusb_end;//////////////////
|
||||
ops->usbd_end = xusb_end;
|
||||
ops->usb_device_init = xusb_device_init;
|
||||
ops->usb_device_enumerate = xusb_device_enumerate;
|
||||
ops->usb_device_class_send_max_lun = xusb_device_class_send_max_lun;
|
||||
|
|
Loading…
Add table
Add a link
Reference in a new issue