/* 
 *   Creation Date: <2003/07/09 23:42:40 samuel>
 *   Time-stamp: <2003/07/31 12:28:07 samuel>
 *   
 *	<scsi-client.h>
 *	
 *	SCSI client interface
 *   
 *   Copyright (C) 2003, 2004 Samuel Rydh (samuel@ibrium.se)
 *   
 *   This program is free software; you can redistribute it and/or
 *   modify it under the terms of the GNU General Public License
 *   version 2
 *   
 */

#ifndef _H_SCSI_CLIENT
#define _H_SCSI_CLIENT

#include <sys/uio.h>

typedef struct scsi_dev scsi_dev_t;

typedef struct scsi_ureq  {
	struct scsi_ureq	*next;			/* may be used by client */
	void			*pdata;			/* private client data */
	
	unsigned char		is_write;
	unsigned char		scsi_status;		/* [O] SCSI status */
	unsigned char		filler;
	unsigned char		cdb_len;

	char			cdb[16];

	int			sb_actlen;		/* returned sense */
	char			sb[252];		/* sense buffer */

	int			size;			/* data size */
	int			act_size;		/* bytes transfered */
	int			n_sg;
	struct iovec		iovec[0];
} scsi_ureq_t;

typedef struct {
	void		(*execute)( scsi_ureq_t *r, void *refcon );
} scsi_ops_t;

extern scsi_dev_t 	*register_scsidev( scsi_ops_t *ops, int priv_size, void *refcon );
extern void	 	unregister_scsidev( scsi_dev_t *dev );
extern void		complete_scsi_req( scsi_dev_t *dev, scsi_ureq_t *r );


#ifdef __linux__
extern void		scsidev_init( void );
extern void		scsidev_cleanup( void );
#else
static inline void	scsidev_init( void ) {}
static inline void	scsidev_cleanup( void ) {}
#endif

/* careful! linux uses dowshifted variants of these... */
#define SCSI_STATUS_GOOD			0x00
#define SCSI_STATUS_CHECK_CONDITION		0x02
#define SCSI_STATUS_CONDITION_GOOD		0x04
#define SCSI_STATUS_BUSY			0x08
#define SCSI_STATUS_INTERMEDIATE_GOOD		0x10
#define SCSI_STATUS_INTERMEDIATE_C_GOOD		0x14
#define SCSI_STATUS_RESERVATION_CONFLICT	0x18
#define SCSI_STATUS_COMMAND_TERMINATED		0x22
#define SCSI_STATUS_QUEUE_FULL			0x28

#endif   /* _H_SCSI_CLIENT */


