/*
* @file hv_drv_UsbStorageUmass.h
* @brief Header file of usb umass protocol.
*
* @author HiView SoC Software Team
* @version 1.0.0
* @date 2022-06-15
*/

#ifndef __HV_DRV_USB_STORAGE_UMASS_H
#define __HV_DRV_USB_STORAGE_UMASS_H

#include "hv_drv_UsbStorageCommonScsi.h"
#include "hv_drv_UsbCoreCommonUsb.h"

struct us_data;
struct scsi_cmnd;

struct us_unusual_dev {
    const char* vendorName;
    const char* productName;
    u8          useProtocol;
    u8          useTransport;
    int         (*initFunction)(struct us_data *);
};


/* Dynamic bitflag definitions (us->dflags): used in set_bit() etc. */
#define US_FLIDX_URB_ACTIVE         0   /* current_urb is in use    */
#define US_FLIDX_SG_ACTIVE          1   /* current_sg is in use     */
#define US_FLIDX_ABORTING           2   /* abort is in progress     */
#define US_FLIDX_DISCONNECTING      3   /* disconnect in progress   */
#define US_FLIDX_RESETTING          4   /* device reset in progress */
#define US_FLIDX_TIMED_OUT          5   /* SCSI midlayer timed out  */
#define US_FLIDX_SCAN_PENDING       6   /* scanning not yet done    */
#define US_FLIDX_REDO_READ10        7   /* redo READ(10) command    */
#define US_FLIDX_READ10_WORKED      8   /* previous READ(10) succeeded */
#define US_FLIDX_BUG_OVERFOUR       9   /* hardware error, fifo overflow four */
#define US_FLIDX_BUG_FIFOCNTFLH     10  /* hardware error, fifo can not flush */

#define USB_STOR_STRING_LEN 32

/*
 * We provide a DMA-mapped I/O buffer for use with small USB transfers.
 * It turns out that CB[I] needs a 12-byte buffer and Bulk-only needs a
 * 31-byte buffer.  But Freecom needs a 64-byte buffer, so that's the
 * size we'll allocate.
 **/

#define US_IOBUF_SIZE       64  /* Size of the DMA-mapped I/O buffer */
#define US_SENSE_SIZE       18  /* Size of the autosense data buffer */

typedef void (*proto_cmnd)(struct scsi_cmnd*, struct us_data*);
typedef int (*trans_cmnd)(struct scsi_cmnd *, struct us_data*);
typedef int (*trans_reset)(struct us_data*);

#define US_SUSPEND  0
#define US_RESUME   1

/* we allocate one of these for every device that we remember */
struct us_data {
    HANDLE                  dev_mutex;      /* protect pusb_dev */
    struct scsi_device      *scsi;          /* this scsi_device */
    struct usb_device       *pusb_dev;      /* this usb_device */
    struct usb_interface    *pusb_intf;     /* this interface */
    struct us_unusual_dev   *unusual_dev;   /* device-filter entry     */
    unsigned long           fflags;         /* fixed flags from filter */
    unsigned long           dflags;         /* dynamic atomic bitflags */
    unsigned int            send_bulk_pipe; /* cached pipe values */
    unsigned int            recv_bulk_pipe;
    unsigned int            send_ctrl_pipe;
    unsigned int            recv_ctrl_pipe;
    unsigned int            recv_intr_pipe;

    /* information about the device */
    char                    *transport_name;
    char                    *protocol_name;
    u32                     bcs_signature;
    u8                      subclass;
    u8                      protocol;
    u8                      max_lun;

    u8                      ifnum;           /* interface number   */
    u8                      ep_bInterval;    /* interrupt interval */

    /* function pointers for this device */
    trans_cmnd              transport;       /* transport function     */
    trans_reset             transport_reset; /* transport device reset */
    proto_cmnd              proto_handler;   /* protocol handler       */

    /* SCSI interfaces */
    struct scsi_cmnd        *srb;           /* current srb     */
    unsigned int            tag;            /* current dCBWTag */
    char                    scsi_name[32];  /* scsi_host name  */

    /* control and bulk communications data */
    struct urb              *current_urb;   /* USB requests     */
    struct usb_ctrlrequest  cr;             /* control requests */
    dma_addr_t              iobuf_dma;      /* buffer DMA addresses */
    u8                      iobuf[64];      /* I/O buffer       */

    /* subdriver information */
    void                    *extra;         /* Any extra data          */

    /* hacks for READ CAPACITY bug handling */
    int                     use_last_sector_hacks;
    int                     last_sector_retries;
};
#define scsi_dev_to_us(_dev) ((struct us_data *) (_dev)->extra)
#define us_to_scsi_dev(_us)  ((_us)->scsi)

extern void usb_stor_stop_transport(struct us_data *us);

#endif  /* __UMASS_H */
