1107178Snjl/*
2107178Snjl * SCSI Target Emulator
3107178Snjl *
4107178Snjl * Copyright (c) 2002 Nate Lawson.
5107178Snjl * All rights reserved.
6107178Snjl *
7107178Snjl * Redistribution and use in source and binary forms, with or without
8107178Snjl * modification, are permitted provided that the following conditions
9107178Snjl * are met:
10107178Snjl * 1. Redistributions of source code must retain the above copyright
11107178Snjl *    notice, this list of conditions, and the following disclaimer,
12107178Snjl *    without modification, immediately at the beginning of the file.
13107178Snjl * 2. The name of the author may not be used to endorse or promote products
14107178Snjl *    derived from this software without specific prior written permission.
15107178Snjl *
16107178Snjl * THIS SOFTWARE IS PROVIDED BY THE AUTHOR AND CONTRIBUTORS ``AS IS'' AND
17107178Snjl * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
18107178Snjl * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
19107178Snjl * ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE FOR
20107178Snjl * ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
21107178Snjl * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
22107178Snjl * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
23107178Snjl * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
24107178Snjl * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
25107178Snjl * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
26107178Snjl * SUCH DAMAGE.
27107178Snjl *
28107178Snjl * $FreeBSD$
29107178Snjl */
30107178Snjl
31107178Snjl#ifndef _SCSI_TARGET_H
32107178Snjl#define _SCSI_TARGET_H
33107178Snjl
34107178Snjl/*
35124307Snjl * Maximum number of parallel commands to accept,
36162704Smjacob * 1024 for Fibre Channel (SPI is 16).
37107178Snjl */
38196955Ssbruno#define MAX_INITIATORS		8
39107178Snjl#define	SECTOR_SIZE		512
40107178Snjl#define MAX_EVENTS		(MAX_INITIATORS + 5)
41107178Snjl				/* kqueue for AIO, signals */
42107178Snjl
43107178Snjl/* Additional SCSI 3 defines for inquiry response */
44107178Snjl#define SID_Addr16	0x0100
45107178Snjl
46107178SnjlTAILQ_HEAD(io_queue, ccb_hdr);
47107178Snjl
48107178Snjl/* Offset into the private CCB area for storing our descriptor */
49107178Snjl#define targ_descr	periph_priv.entries[1].ptr
50107178Snjl
51107178Snjl/* Descriptor attached to each ATIO */
52107178Snjlstruct atio_descr {
53107178Snjl	off_t	  base_off;	/* Base offset for ATIO */
54121184Ssimokawa	uint	  total_len;	/* Total xfer len for this ATIO */
55121184Ssimokawa	uint	  init_req;	/* Transfer count requested to/from init */
56121184Ssimokawa	uint	  init_ack;	/* Data transferred ok to/from init */
57121184Ssimokawa	uint	  targ_req;	/* Transfer count requested to/from target */
58121184Ssimokawa	uint	  targ_ack;	/* Data transferred ok to/from target */
59107178Snjl	int	  flags;	/* Flags for CTIOs */
60107178Snjl	u_int8_t *cdb;		/* Pointer to received CDB */
61107178Snjl		  		/* List of completed AIO/CTIOs */
62107178Snjl	struct	  io_queue cmplt_io;
63107178Snjl};
64107178Snjl
65107178Snjltypedef enum {
66107178Snjl	ATIO_WORK,
67107178Snjl	AIO_DONE,
68107178Snjl	CTIO_DONE
69107178Snjl} io_ops;
70107178Snjl
71107178Snjl/* Descriptor attached to each CTIO */
72107178Snjlstruct ctio_descr {
73107178Snjl	void	*buf;		/* Backing store */
74107178Snjl	off_t	 offset;	/* Position in transfer (for file, */
75107178Snjl				/* doesn't start at 0) */
76107178Snjl	struct	 aiocb aiocb;	/* AIO descriptor for this CTIO */
77107178Snjl	struct	 ccb_accept_tio *atio;
78107178Snjl				/* ATIO we are satisfying */
79107178Snjl	io_ops	 event;		/* Event that queued this CTIO */
80107178Snjl};
81107178Snjl
82107178Snjltypedef enum {
83107178Snjl        UA_NONE         = 0x00,
84107178Snjl        UA_POWER_ON     = 0x01,
85107178Snjl        UA_BUS_RESET    = 0x02,
86107178Snjl        UA_BDR          = 0x04
87107178Snjl} ua_types;
88107178Snjl
89107178Snjltypedef enum {
90107178Snjl        CA_NONE         = 0x00,
91107178Snjl        CA_UNIT_ATTN    = 0x01,
92107178Snjl        CA_CMD_SENSE    = 0x02
93107178Snjl} ca_types;
94107178Snjl
95107178Snjlstruct initiator_state {
96107178Snjl        ua_types   orig_ua;
97107178Snjl        ca_types   orig_ca;
98107178Snjl        ua_types   pending_ua;
99107178Snjl        ca_types   pending_ca;
100107178Snjl        struct     scsi_sense_data sense_data;
101107178Snjl};
102107178Snjl
103107178Snjl/* Global functions */
104107178Snjlextern cam_status	tcmd_init(u_int16_t req_inq_flags,
105107178Snjl				  u_int16_t sim_inq_flags);
106107178Snjlextern int		tcmd_handle(struct ccb_accept_tio *atio,
107107178Snjl				    struct ccb_scsiio *ctio, io_ops event);
108107178Snjlextern void		tcmd_sense(u_int init_id, struct ccb_scsiio *ctio,
109107178Snjl				   u_int8_t flags,
110107178Snjl				   u_int8_t asc, u_int8_t ascq);
111107178Snjlextern void		tcmd_ua(u_int init_id, ua_types new_ua);
112107178Snjlextern int		work_atio(struct ccb_accept_tio *atio);
113107178Snjlextern void		send_ccb(union ccb *ccb, int priority);
114107178Snjlextern void		free_ccb(union ccb *ccb);
115107178Snjlstatic __inline u_int	min(u_int a, u_int b) { return (a < b ? a : b); }
116107178Snjl
117162704Smjacob/* Global Data */
118162704Smjacobextern int notaio;
119162704Smjacob
120162704Smjacob/*
121162704Smjacob * Compat Defines
122162704Smjacob */
123162704Smjacob#if __FreeBSD_version >= 500000
124162704Smjacob#define	OFF_FMT	"%ju"
125162704Smjacob#else
126162704Smjacob#define	OFF_FMT "%llu"
127162704Smjacob#endif
128162704Smjacob
129107178Snjl#endif /* _SCSI_TARGET_H */
130