/** @file
This file contains the definination for host controller schedule routines.

Copyright (c) 2013-2015 Intel Corporation.

SPDX-License-Identifier: BSD-2-Clause-Patent

**/



#ifndef _OHCI_SCHED_H
#define _OHCI_SCHED_H

#include "Descriptor.h"

#define HCCA_MEM_SIZE     256
#define GRID_SIZE         16
#define GRID_SHIFT        4

typedef struct _INTERRUPT_CONTEXT_ENTRY INTERRUPT_CONTEXT_ENTRY;

struct _INTERRUPT_CONTEXT_ENTRY{
  UINT8                               DeviceAddress;
  UINT8                               EndPointAddress;
  ED_DESCRIPTOR                       *Ed;
  TD_DESCRIPTOR                       *DataTd;
  BOOLEAN                             IsSlowDevice;
  UINT8                               MaxPacketLength;
  UINTN                               PollingInterval;
  EFI_ASYNC_USB_TRANSFER_CALLBACK     CallBackFunction;
  VOID                                *Context;
  BOOLEAN                             IsPeriodic;
  VOID                                *Buffer;
  UINTN                               DataLength;
  VOID                                *UCBuffer;
  VOID                                *UCBufferMapping;
  UINT8                               *Toggle;
  INTERRUPT_CONTEXT_ENTRY      *NextEntry;
};


typedef struct {
  UINT32                  ErrorCode;
  UINT8                   NextToggle;
} OHCI_ED_RESULT;

/**

  Add an item of interrupt context

  @param  Ohc                   UHC private data
  @param  NewEntry              New entry to add

  @retval EFI_SUCCESS           Item successfully added

**/
EFI_STATUS
OhciAddInterruptContextEntry (
  IN  USB_OHCI_HC_DEV          *Ohc,
  IN  INTERRUPT_CONTEXT_ENTRY  *NewEntry
  );

/**

  Free a interrupt context entry

  @param  Ohc                   UHC private data
  @param  Entry                 Pointer to an interrupt context entry

  @retval EFI_SUCCESS           Entry freed
  @retval EFI_INVALID_PARAMETER Entry is NULL

**/
EFI_STATUS
OhciFreeInterruptContextEntry (
  IN USB_OHCI_HC_DEV          *Ohc,
  IN INTERRUPT_CONTEXT_ENTRY  *Entry
  );

/**

  Free entries match the device address and endpoint address

  @Param  Ohc                   UHC private date
  @Param  DeviceAddress         Item to free must match this device address
  @Param  EndPointAddress       Item to free must match this end point address
  @Param  DataToggle            DataToggle for output

  @retval  EFI_SUCCESS          Items match the requirement removed

**/
EFI_STATUS
OhciFreeInterruptContext(
  IN  USB_OHCI_HC_DEV     *Ohc,
  IN  UINT8               DeviceAddress,
  IN  UINT8               EndPointAddress,
  OUT UINT8               *DataToggle
  );


/**

  Convert Error code from OHCI format to EFI format

  @Param  ErrorCode             ErrorCode in OHCI format

  @retval                       ErrorCode in EFI format

**/
UINT32
ConvertErrorCode (
  IN  UINT32              ErrorCode
  );


/**

  Check TDs Results

  @Param  Ohc                   UHC private data
  @Param  Td                    TD_DESCRIPTOR
  @Param  Result                Result to return

  @retval TRUE                  means OK
  @retval FLASE                 means Error or Short packet

**/
BOOLEAN
OhciCheckTDsResults (
  IN  USB_OHCI_HC_DEV     *Ohc,
  IN  TD_DESCRIPTOR       *Td,
  OUT UINT32              *Result
  );
/**

  Check the task status on an ED

  @Param  Ed                    Pointer to the ED task that TD hooked on
  @Param  HeadTd                TD header for current transaction

  @retval                       Task Status Code

**/

UINT32
CheckEDStatus (
  IN  ED_DESCRIPTOR       *Ed,
  IN  TD_DESCRIPTOR       *HeadTd,
  OUT OHCI_ED_RESULT      *EdResult
  );
/**

  Check the task status

  @Param  Ohc                   UHC private data
  @Param  ListType              Pipe type
  @Param  Ed                    Pointer to the ED task hooked on
  @Param  HeadTd                Head of TD corresponding to the task
  @Param  ErrorCode             return the ErrorCode

  @retval  EFI_SUCCESS          Task done
  @retval  EFI_NOT_READY        Task on processing
  @retval  EFI_DEVICE_ERROR     Some error occured

**/
EFI_STATUS
CheckIfDone (
  IN  USB_OHCI_HC_DEV       *Ohc,
  IN  DESCRIPTOR_LIST_TYPE  ListType,
  IN  ED_DESCRIPTOR         *Ed,
  IN  TD_DESCRIPTOR         *HeadTd,
  OUT OHCI_ED_RESULT        *EdResult
  );

/**

  Convert TD condition code to Efi Status

  @Param  ConditionCode         Condition code to convert

  @retval  EFI_SUCCESS          No error occured
  @retval  EFI_NOT_READY        TD still on processing
  @retval  EFI_DEVICE_ERROR     Error occured in processing TD

**/

EFI_STATUS
OhciTDConditionCodeToStatus (
  IN  UINT32              ConditionCode
  );

/**

  Invoke callbacks hooked on done TDs

  @Param  Entry                 Interrupt transfer transaction information data structure
  @Param  Context               Ohc private data

**/

VOID
OhciInvokeInterruptCallBack(
  IN  INTERRUPT_CONTEXT_ENTRY  *Entry,
  IN  UINT32                   Result
);


/**

  Timer to submit periodic interrupt transfer, and invoke callbacks hooked on done TDs

  @param  Event                 Event handle
  @param  Context               Device private data

**/

VOID
EFIAPI
OhciHouseKeeper (
  IN  EFI_EVENT           Event,
  IN  VOID                *Context
  );

#endif
