/*                               -*- Mode: C -*- 
 * cwif.h -- Clockwise interface file.
 * 
 * Author          : 
 * Created On      : Sun Jan 31 13:05:53 1999
 * Last Modified By: 
 * Last Modified On: Mon Oct  4 10:37:56 1999
 * Status          : Unknown, Use with caution!
 * 
 * Unless other notices are present in any part of this file
 * explicitly claiming copyrights for other people and/or 
 * organizations, the contents of this file is fully copyright 
 * (C) 1999 Peter Bosch, all rights reserved.
 */
#define PRINT_DEBUG(x) x
#ifdef __KERNEL__
#define PRINT(format, a...)  printk(format, ## a)
#else
#define PRINT(format, a...)  printf(format, ## a)
#endif


#ifndef _CWIF_H_
#define _CWIF_H_

#ifndef __KERNEL__
#ifndef _UINT8_T
typedef unsigned char uint8_t;
#endif
#ifndef _UINT16_T
typedef unsigned short uint16_t;
#endif
#ifndef _UINT32_T
typedef unsigned long uint32_t;
#endif
#ifndef _UINT64_T
typedef unsigned long long uint64_t;
#endif
#define __KERNEL__
#endif

#include <linux/kdev_t.h>

typedef long long Time_t;

#define CWDCONFIG 	"config"
#define CWGEOMETRY	"geometry"
#define CLOCKWISE 	"/dev/clockwise"
#define NUMDISKS	64

#define CW_IOCTL(r, a)	(('c' << 24) | ('w' << 16) | (((r) & 0xFF) << 8) | \
                         ((a) & 0xFF))
#define CW_IOCTLMASK	0xFFFFFF00
#define CW_ADDDISK	CW_IOCTL(0, 0)
#define CW_GO		CW_IOCTL(1, 0)
#define CW_NEWDP	CW_IOCTL(2, 0)
#define CW_DIE		CW_IOCTL(3, 0)
#define CW_QOS		CW_IOCTL(4, 0)
#define CW_GEOMETRY	CW_IOCTL(5, 0)
#define CW_SEEKTIME	CW_IOCTL(6, 0)
#define CW_IORTIME	CW_IOCTL(7, 0)
#define CW_IOWTIME	CW_IOCTL(8, 0)
#define CW_INODE(dp)	CW_IOCTL(9, (dp))
#define CW_INODEMASK	0xFF
#define CW_RELEASE	CW_IOCTL(10, 0)
#define CW_BSIZE	CW_IOCTL(11, 0)
#define CW_RMDP(dp)	CW_IOCTL(12, (dp))
#define CW_GETINFO	CW_IOCTL(13, 0)
#define CW_MOVE		CW_IOCTL(14, 0)
#define CW_GETFTAB	CW_IOCTL(15, 0)
#define CW_TRUNCATE	CW_IOCTL(16, 0)

#define CW_MAXDTYPE	16		/* Length of a dtype string */
typedef struct {
  char		add_dtype[CW_MAXDTYPE];	/* Disk type */
  kdev_t	add_rdev;		/* Device number */
} cwadddisk_t;
  
typedef struct {
  uint32_t	io_bs;			/* Block size */
  Time_t	io_t;			/* Service time */
} cwiotime_t;

typedef struct {
  uint32_t	se_nt;			/* Number of tracks */
  Time_t	se_t;			/* Service time */
} cwsetime_t;

typedef struct {
  char		st_dtype[CW_MAXDTYPE];
  int		st_ne;			/* Number of entries */
  cwsetime_t	st_e[1];		/* At least one entry */
} cwseektimes_t;

typedef struct {
  char		iot_dtype[CW_MAXDTYPE];
  int		iot_zone;		/* Which zone? */
  int		iot_ne;			/* Number of read entries */
  cwiotime_t	iot_e[1];		/* At least one entry */
} cwiotimes_t;

#define NUMZONES	20

typedef struct {
  char		ge_dtype[CW_MAXDTYPE];	/* Disk type */
  uint32_t	ge_rpm;			/* Rotations per minute */
  uint32_t	ge_nheads;		/* Number of heads */
  uint32_t	ge_ncyls;		/* Number of cylinders */
  int		ge_nzones;		/* Number of zones */
  struct {
    uint32_t	gez_start;		/* Zone start address */
    uint32_t	gez_spt;		/* Zone sectors per track */
    uint32_t	gez_ntracks;		/* Zone number of tracks */
  } ge_zones[NUMZONES];
} cwgeometry_t;

typedef struct {
#define CWMAGIC 0x23050002
  uint32_t 		sb_magic;	/* Super block magic. */
  uint32_t 		sb_fdisk;	/* Logical disk id of FTAB. */
  uint32_t 		sb_ftab;	/* Address of FTAB. */
  uint32_t 		sb_did;		/* Disk ID */
  uint32_t 		sb_blocksz;	/* Number of sectors per block */
  uint32_t 		sb_nblocks;	/* Number of blocks. */
  uint32_t		sb_dbmhi;	/* Bitmap of disks */
  uint32_t		sb_dbmlo;
} cwsb_t;

typedef struct {
  uint32_t		info_fdisk;	/* Logical disk ID of FTAB */
  uint32_t		info_ftab;	/* Address of FTAB */
  struct {
    char		ipd_dtype[CW_MAXDTYPE];	/* Disk type */
    uint32_t		ipd_blocksz;	/* Number of sectors per block */
    uint32_t		ipd_nblocks;	/* Number of blocks per disk */
    kdev_t		ipd_kdev;	/* Kernel device */
    uint32_t		ipd_ldisk;	/* Logical disk */
  } info_pd[NUMDISKS];
} cwinfo_t;
    
typedef struct {
#define CWMAXDPNAME		256
  char			re_dpname[CWMAXDPNAME];
  uint32_t		re_nb;		/* Number of DP blocks to allocate */
  uint32_t		re_bpd;		/* Blocks per disk */
  uint32_t		re_dbmhi;	/* Bitmap of disks to use */
  uint32_t		re_dbmlo;	/* ditto */
  uint32_t		re_bnum;	/* Base block number */
} cwreserve_t;

typedef struct {
  uint32_t		qos_bw;		/* Requested bandwidth in bps */
  uint32_t		qos_bs;		/* User block size */
  uint32_t		qos_bnum;	/* Start block number */
  uint32_t		qos_nb;		/* Number of blocks */
  Time_t		qos_start;	/* When do we want the reservation */
  Time_t		qos_duration;	/* And for how long */
} cwqos_t;

typedef struct {
  loff_t		mv_offs;	/* Which offset */
  uint32_t		mv_size;	/* Size of block */
  uint32_t		mv_ldisk;	/* Destination disk */
  uint32_t		mv_daddr;	/* Destination disk address */
} cwmove_t;

typedef enum { CWRead, CWWrite } cwcmd_t;

typedef struct {
  cwcmd_t		rel_rw;		/* Read or write */
  uint8_t		*rel_buf;	/* Buffer to use */
  size_t		rel_size;	/* Buffer size */
  loff_t		rel_offs;	/* Where to transfer */
} cwrelease_t;

#define CW_SBADDR	16		/* Super block offset */
#define CW_SBSIZE	512		/* Size of a super block */
#define CW_SSIZE	512		/* Assumed block size for Clockwise */
#define CW_FSADDR	(CW_SBADDR + 1)	/* Logical start of disk */

#ifndef NS
#define NS(x)	((Time_t)(x))
#define US(x)	(NS(x) * 1000LL)
#define MS(x)	(US(x) * 1000LL)
#define S(x)	(MS(x) * 1000LL)
#endif

typedef struct {
  uint32_t		i_ldisk;	/* Which logical device */
  uint32_t		i_daddr;	/* Where on disk */
} cwdinode_t;

typedef struct {
  char		      	ft_name[CWMAXDPNAME];	/* What's the file's name */
  uint64_t	      	ft_fsize;		/* In-band file size */
  uint32_t            	ft_iaddr;		/* Disk address of inode */
  uint32_t	      	ft_isize;		/* Size of the inode */
#define CW_FTMAGIC	0x03031988
#define CW_FTBUSY	0x23051996
  uint32_t	      	ft_magic;		/* Magic */
  uint32_t	      	ft_idisk;		/* Disk ID of inode disk */
  uint32_t 	      	ft_type;		/* Type of the file */
} cwftabentry_t;

#ifndef CW_B_MAJOR
#define CW_B_MAJOR 60
#endif
#ifndef CW_C_MAJOR
#define CW_C_MAJOR 60
#endif
#define MAJOR_NR CW_B_MAJOR

#ifndef K
#define K	1024
#endif
#ifndef M
#define M	(K*K)
#endif

#ifndef numblocks
#define numblocks(a, b)	(((a) + (b) - 1) / (b))
#endif
#ifndef roundup
#define roundup(a, b)	(numblocks((a), (b)) * (b))
#endif
#ifndef rounddown
#define rounddown(a, b)	(((a) / (b)) * (b))
#endif
#ifndef max
#define max(a, b)	(((a) > (b))? (a): (b))
#endif

#endif

