/* IBM_PROLOG_BEGIN_TAG                                                   */
/* This is an automatically generated prolog.                             */
/*                                                                        */
/* bos720 src/bos/kernext/usb/common/hcdi.h 1.5.2.3                       */
/*                                                                        */
/* Licensed Materials - Property of IBM                                   */
/*                                                                        */
/* Restricted Materials of IBM                                            */
/*                                                                        */
/* COPYRIGHT International Business Machines Corp. 2003,2013              */
/* All Rights Reserved                                                    */
/*                                                                        */
/* US Government Users Restricted Rights - Use, duplication or            */
/* disclosure restricted by GSA ADP Schedule Contract with IBM Corp.      */
/*                                                                        */
/* IBM_PROLOG_END_TAG                                                     */
/* @(#)03	1.5.2.3  src/bos/kernext/usb/common/hcdi.h, sysxusb, bos720 12/17/13 08:11:53 */
#ifndef _H_HCDI
#define _H_HCDI

#include <sys/types.h>
#include <sys/dma.h>
#include <sys/intr.h>
#include <sys/stdint.h>
#include <usbdi.h>


/*
 * bus map structure
 * note: actual size of structure is sizeof(BUSMAP) +
 *       sizeof(struct d_iovec) * (num_of_mapped_pages - 1)
 */
typedef struct _BUSMAP {

   caddr_t           vaddr;           /* virtual address of area             */
   int               size;            /* number of bytes                     */
   struct dio        mapPhys;         /* bus vector descriptor               */
   struct d_iovec    phys;            /* bus vector                          */

} BUSMAP, *PBUSMAP;

/*
 *  I/O block
 */
typedef struct _IOB {
  struct  _IOB  *pNext;               /* pointer to next IOB                 */
  USBhandle     hpipe;                /* pipe handle                         */
  caddr_t       pBuffer;              /* pointer to buffer or NULL           */
  uint64_t      busAddr;              /* bus address                         */
  uint          length;               /* length of transaction or 0          */
  struct {                            /* flags:                              */
    unsigned      shortOK:1;          /*  short transfer from device ok      */
    unsigned      pid:2;              /*  packet identification              */
#define PID_SETUP  0            
#define PID_IN     1
#define PID_OUT    2
  }             flags;
  volatile USBstatus status;          /* completion status                   */
/* ---------------- difference between versions 1 and 2 -------------------- */
  volatile USBstatus xstatus;         /* extended completion status          */
  uint16_t      frame;                /* requested frame number              */
} IOB, *PIOB;

/*
 * pipe descriptor structure 
 *
 * note: see usb.h for ep descriptor definition
 */
typedef struct _PIPEDESCRIPTOR {
  uint       devAddr;                 /* device address                      */
  uint       epAddress;               /* endpoint addr (ep descriptor + 2)   */
  uint       hub;                     /* USB physical device address of      */
                                      /*    first hub upstream               */
  int        port;                    /* port number on first hub upstream   */
  uint       maxIOBs;                 /* max number of outstanding iob's     */
  uint       packetSize;              /* MaxPacketSize (ep descriptor + 4)   */
  uint8_t    attribute;               /* Attributes (ep descriptor + 3)      */
  uint8_t    bandWidth;               /* Interval (ep descriptor + 6)        */
  uint8_t    speed;                   /* USB bus speed or Is Roothub         */
#define lowSpeed        0x1
#define fullSpeed       0x2
#define highSpeed       0x4
#define splitSpeed      0x8
#define splitLowSpeed   (splitSpeed | lowSpeed)
#define splitfullSpeed  (splitSpeed | fullSpeed)
#define superSpeed      0x10

  uint8_t    split_hub_addr;          /* device address of hub with TT       */
  uint8_t    split_hub_port;          /* port number on hub with TT          */

  uint8_t    flags;                   /* flags to pass info to HC driver     */
#define IS_ROOTHUB      0x01          /* Flag set for root hub emulation     */

  uint       slot_id;                 /* Slot ID of the Device               */
  uchar      mult;                    /* Max No of Bursts/Interval -SS Isoch */
  uchar      burst_size;              /* Max Burst Size - SS Endpoints       */
} PIPEDESCRIPTOR, *PPIPEDESCRIPTOR;

/*
 * Logical Device Information Structure.
 * This structure is exchanged between Bus driver
 * and XHCI Adapter driver for sharing the Device
 * Context related Information
 *
 */
typedef struct _DEVINFO {
  uint       devAddr;                 /* HW allotted USB Device Address      */
  uint       slot_id;                 /* Adapter assigned Slot ID            */
  uint       route_string;            /* USB 3.0 Protocol Route String       */
  uint       hub;                     /* USB physical device address of      */
                                      /* First Hub Upstream                  */
  uchar      port;                    /* Port Number on first hub upstream   */
  uchar      no_ports;                /* No of Ports if HUB device           */
  uchar      rh_port;                 /* Roothub port used to access device  */
  struct _DEVINFO  *parent;           /* parent of the device                */
  uchar      speed;                   /* USB Device Speed                    */
#define USB_FULLSPEED       0x1
#define USB_LOWSPEED        0x2
#define USB_HIGHSPEED       0x3
#define USB_SUPERSPEED      0x4

  ushort     max_exit_lat;            /* Maximum Exit Latency in Microsec    */

  uint8_t    split_hub_addr;          /* Device address of hub with TT       */
  uint8_t    split_hub_port;          /* Port number on hub with TT          */

  uchar      TT_think_time;           /* TT Think Time                       */
#define USB_TTT_8FS     0x0           /* 8  FS Bit times                     */
#define USB_TTT_16FS    0x1           /* 16 FS Bit times                     */
#define USB_TTT_24FS    0x2           /* 24 FS Bit times                     */
#define USB_TTT_32FS    0x3           /* 32 FS Bit times                     */

  uint8_t    flags;                   /* Flags to pass info to HC driver     */
#define IS_HUB          0x01          /* Flag set if HUB Device              */
#define IS_MULTI_TT     0x02          /* Flag set if Multi-TT Support Hub    */
  
 USBhandle    hHCDEVCB;              /* Host Controller Device Handle(XHCI) */
} DEVINFO, *PDEVINFO;

/*
 * ioctl's
 */
#define HCD_REGISTER_HC          0x72656769    /* register a hardware controller      */
#define HCD_REQUEST_COMPANIONS   (HCD_REGISTER_HC+1)

/*
 * Host Controller driver interface (HCDI) vectors
 */

typedef struct _HCDI {

  /*
   * handles and flags
   */
  USBhandle    hHCCB;                 /* HCCB handle  (USBD)                 */
  USBhandle    hHCD;                  /* HCD handle   (HCD)                  */
  d_handle_t   hDMA;                  /* DMA handle   (HCD)                  */
  uint         USBversion;            /* USB version  (HCD)                   */
  uint         flags;     /* bit 0 is 1 for version 2 */
                          /* bit 1 is 1 for high-speed, 0 full-speed */
                          /* bits are 2-31 reserved */

#define HCDI_FLAGS_has_size_and_version          (0x00000001)
#define HCDI_FLAGS_hc_is_highspeed               (0x00000002)
#define HCDI_FLAGS_hc_is_superspeed              (0x00000004)

  /*
   * HCD provided functions 
   * note: do not use directly, use macros below
   */
  USBstatus   (*unregisterHC)(struct _HCDI *);
  USBstatus   (*pipeConnect)(struct _HCDI *, PPIPEDESCRIPTOR,
                  USBhandle *);
  USBstatus   (*pipeDisconnect)(struct _HCDI *, USBhandle);
  USBstatus   (*pipeIO)(struct _HCDI *, PIOB);
  USBstatus   (*pipeStatus)(struct _HCDI *, USBhandle);
  USBstatus   (*pipeAbort)(struct _HCDI *, PIOB);
  USBstatus   (*pipeHalt)(struct _HCDI *, USBhandle);
  USBstatus   (*pipeClear)(struct _HCDI *, USBhandle);
  USBstatus   (*pipeResetToggle)(struct _HCDI *, USBhandle);
  USBstatus   (*pipeAddIOB)(struct _HCDI *, USBhandle, int);
  USBstatus   (*shutdownComplete)(struct _HCDI *);
  /*
   * USBD provided functions 
   */
  USBstatus   (*busMap)(struct _HCDI *, caddr_t, int, PBUSMAP *);
  USBstatus   (*unBusMap)(struct _HCDI *, PBUSMAP);
  USBstatus   (*reqHCunregister)(struct _HCDI *);
  USBstatus   (*postIOB)(struct _HCDI *, PIOB);
  USBstatus   (*reqHCshutdown)(struct _HCDI *);
  USBstatus   (*reqHCrestart)(struct _HCDI *);

/* ---------------- difference between versions 1 and 2 -------------------- */
  uint32_t    structure_size;
  uint16_t    structure_version;
                /* getFrame is provided by HCD */
  USBstatus   (*getFrame)(struct _HCDI *h, uint8_t speed, uint16_t *pFrame);

  /*
   * USB SuperSpeed Support functions
   */
/* ---------------- difference between versions 2 and 3 -------------------- */
  USBstatus   (*devAlloc)(struct _HCDI *, USBhandle *);
  USBstatus   (*devFree)(struct _HCDI *, USBhandle);
  USBstatus   (*configPipes)(struct _HCDI *, USBhandle, PDESCIDX);
  USBstatus   (*unconfigPipes)(struct _HCDI *, USBhandle);
} HCDI, *PHCDI;

#define HCDI_VERSION_1          1
#define HCDI_VERSION_2          2
#define HCDI_VERSION_3          3

#define HCDI_structure_version  HCDI_VERSION_3

/*
 * highest interrupt priority caller may have when calling HCD
 * from interrupt environment 
 */
#define HCD_OFFLEVEL  USBDINTRLEVEL

/*
 * Host Controller driver interface (HCDI) macros
 */

/* Unregister Host Controller                                                */
/*   call: pointer to HCDI struct                                            */
/*   return: status                                                          */
/*   note: "register" done via IOCTL to HCD                                  */
#define hcdUnregisterHC(_a) \
            ((PHCDI)(_a))->unregisterHC(_a)

/* connect to device pipe (endpoint)                                         */
/*   call: pointer to HCDI struct,                                           */
/*         pointer to PIPEDESCRIPTOR struct,                                 */
/*         location to return pipe handle                                    */
/*   return: status                                                          */
#define hcdPipeConnect(_a,_b,_c) \
            ((PHCDI)(_a))->pipeConnect(_a,_b,_c)

/* disconnect from device pipe (endpoint)                                    */
/*   call: pointer to HCDI struct, pipe handle                               */
/*   return: status                                                          */
#define hcdPipeDisconnect(_a,_b) \
            ((PHCDI)(_a))->pipeDisconnect(_a,_b)

/* start I/O on pipe                                                         */
/*   call: pointer to HCDI struct, pointer to IOB chain                      */
/*   return: status                                                          */
#define hcdPipeIO(_a,_b) \
            ((PHCDI)(_a))->pipeIO(_a,_b)

/* get pipe status                                                           */
/*   call: pointer to HCDI struct, pipe handle                               */
/*   return: status                                                          */
#define hcdPipeStatus(_a,_b) \
            ((PHCDI)(_a))->pipeStatus(_a,_b)

/* cancel previously started I/O                                             */
/*   call: pointer to HCDI struct, pointer to IOB struct                     */
/*         used to start the I/O                                             */
/*   return: status                                                          */
#define hcdPipeAbort(_a,_b) \
            ((PHCDI)(_a))->pipeAbort(_a,_b)

/* halt a pipe                                                               */
/*   call: pointer to HCDI struct, pipe handle                               */
/*   return: status                                                          */
#define hcdPipeHalt(_a,_b) \
            ((PHCDI)(_a))->pipeHalt(_a,_b)

/* resume a halted pipe                                                      */
/*   call: pointer to HCDI struct, pipe handle                               */
/*   return: status                                                          */
#define hcdPipeClear(_a,_b) \
            ((PHCDI)(_a))->pipeClear(_a,_b)

/* reset data toggle to DATA0                                                */
/*   call: pointer to HCDI struct, pipe handle                               */
/*   return: status                                                          */
#define hcdPipeResetToggle(_a,_b) \
            ((PHCDI)(_a))->pipeResetToggle(_a,_b)

/* add IOBs to connected pipe                                                */
/*   call: pointer to HCDI struct, pipe handle, number                       */
/*   return: status                                                          */
#define hcdPipeAddIOB(_a,_b,_c) \
            ((PHCDI)(_a))->pipeAddIOB(_a,_b,_c)

/* USBD HC shutdown complete                                                 */
/*   call: pointer to HCDI struct                                            */
/*   return: status                                                          */
#define hcdShutdownComplete(_a) \
            ((PHCDI)(_a))->shutdownComplete(_a)

/* condition pinned kernel memory for bus mastered I/O                       */
/*   call:  pointer to HCDI struct, virtual address, size in bytes,          */
/*         location to return address of map structure                       */
/*   return: status                                                          */
#define usbdBusMap(_a,_b,_c,_d) \
            ((PHCDI)(_a))->busMap(_a,_b,_c,_d)

/* free up resources used to condition memory for bus mastered I/O           */
/*   call: pointer to HCDI struct, pointer to map structure                  */
/*   return: status                                                          */
#define usbdunBusMap(_a,_b) \
            ((PHCDI)(_a))->unBusMap(_a,_b)

/* unregister HC connection                                                  */
/*   call: pointer to HCDI struct                                            */
/*   return: N/A                                                             */
#define usbdReqHCunregister(_a) \
            ((PHCDI)(_a))->reqHCunregister(_a)

/* post IOB                                                                  */
/*   call: pointer to HCDI struct, pointer to IOB struct                     */
/*   return: N/A                                                             */
#define usbdPostIOB(_a,_b) \
            ((PHCDI)(_a))->postIOB(_a,_b)

/* request HC shutdown                                                       */
/*   call: pointer to HCDI struct                                            */
/*   return: N/A                                                             */
#define usbdReqHCshutdown(_a) \
            ((PHCDI)(_a))->reqHCshutdown(_a)

/* request HC restart                                                        */
/*   call: pointer to HCDI struct                                            */
/*   return: N/A                                                             */
#define usbdReqHCrestart(_a) \
            ((PHCDI)(_a))->reqHCrestart(_a)

/* get the HCDI structure size                                               */
/*   call: pointer to HCDI structure                                         */
/*   return: the structure size                                              */
#define hcdGetSize(_a) \
            (((PHCDI)(_a))->structure_size)

/* get the HCDI structure version                                            */
/*   call: pointer to HCDI structure                                         */
/*   return: the structure version                                           */
#define hcdGetVersion(_a) \
            (((PHCDI)(_a))->structure_version)

/* compare HCDI structure size and version                                   */
/*   call: pointer to HCDI structure                                         */
/*   return: true if the HCDI structure can be used, false otherwise         */
#define hcdCompareSizeAndVersion(_a) \
            ( (((PHCDI)(_a))->flags!=0) \
                && (hcdGetSize(_a)>=sizeof(HCDI)) \
                && (hcdGetVersion(_a)>=HCDI_structure_version))

/* get the current frame number                                              */
/*   call: pointer to HCDI structure, speed, pointer to frame number         */
/*   return: status                                                          */
#define hcdGetFrame(_a,_b,_c) \
    ((PHCDI)(_a))->getFrame(_a,_b,_c)

/******************* USB SuperSpeed support funtions *************************/

/* Allocate the device context(logical device) at adapter                    */
/*   call: pointer to HCDI struct,                                           */
/*         location to return device context handle                          */
/*         port no at which device connected                                 */ 
/*   return: status                                                          */
#define hcdDevAlloc(_a,_b) \
            ((PHCDI)(_a))->devAlloc(_a,_b)

/* Free the device context(logical device) at adapter                        */
/*   call: pointer to HCDI struct, device context handle                     */
/*   return: status                                                          */
#define hcdDevFree(_a,_b) \
            ((PHCDI)(_a))->devFree(_a,_b)

/* Open the device context(logical device) at adapter                        */
/*   call: pointer to HCDI struct, device context handle                     */
/*         Device Descriptor list                                            */
/*   return: status                                                          */
#define hcdConfigPipes(_a,_b,_c) \
            ((PHCDI)(_a))->configPipes(_a,_b,_c)

/* Close the device context(logical device) at adapter                       */
/*   call: pointer to HCDI struct, device context handle                     */
/*   return: status                                                          */
#define hcdUnconfigPipes(_a,_b) \
            ((PHCDI)(_a))->unconfigPipes(_a,_b)

/* This is the structure used by the HCD_REQUEST_COMPANIONS ioctl. */
typedef struct companion_info_t
{
    uint8_t n_ports;      /* HCSPARAMS.N_PORTS */
    uint8_t prr;          /* Port Routing Rules */
    uint8_t n_pcc;        /* HCSPARAMS.N_PCC */
    uint8_t n_cc;         /* HCSPARAMS.N_CC */
    uint32_t reserved0;
    uint64_t portroute;   /* HCSP_PORTROUTE */
}
companion_info_t;

#endif /* _H_HCDI */