1f0cfa1b1SPedro F. Giffuni /*-
24d846d26SWarner Losh * SPDX-License-Identifier: BSD-2-Clause
3f0cfa1b1SPedro F. Giffuni *
4c38b150aSNate Lawson * SCSI Target Emulator
5c38b150aSNate Lawson *
6c38b150aSNate Lawson * Copyright (c) 2002 Nate Lawson.
7c38b150aSNate Lawson * All rights reserved.
8c38b150aSNate Lawson *
9c38b150aSNate Lawson * Redistribution and use in source and binary forms, with or without
10c38b150aSNate Lawson * modification, are permitted provided that the following conditions
11c38b150aSNate Lawson * are met:
12c38b150aSNate Lawson * 1. Redistributions of source code must retain the above copyright
13c38b150aSNate Lawson * notice, this list of conditions, and the following disclaimer,
14c38b150aSNate Lawson * without modification, immediately at the beginning of the file.
15c38b150aSNate Lawson * 2. The name of the author may not be used to endorse or promote products
16c38b150aSNate Lawson * derived from this software without specific prior written permission.
17c38b150aSNate Lawson *
18c38b150aSNate Lawson * THIS SOFTWARE IS PROVIDED BY THE AUTHOR AND CONTRIBUTORS ``AS IS'' AND
19c38b150aSNate Lawson * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
20c38b150aSNate Lawson * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
21c38b150aSNate Lawson * ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE FOR
22c38b150aSNate Lawson * ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
23c38b150aSNate Lawson * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
24c38b150aSNate Lawson * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
25c38b150aSNate Lawson * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
26c38b150aSNate Lawson * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
27c38b150aSNate Lawson * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
28c38b150aSNate Lawson * SUCH DAMAGE.
29c38b150aSNate Lawson */
30c38b150aSNate Lawson
31c38b150aSNate Lawson #ifndef _SCSI_TARGET_H
32c38b150aSNate Lawson #define _SCSI_TARGET_H
33c38b150aSNate Lawson
34c38b150aSNate Lawson /*
35daa66c2cSNate Lawson * Maximum number of parallel commands to accept,
36cd6dedfcSMatt Jacob * 1024 for Fibre Channel (SPI is 16).
37c38b150aSNate Lawson */
38b0d05375SSean Bruno #define MAX_INITIATORS 8
39c38b150aSNate Lawson #define SECTOR_SIZE 512
40c38b150aSNate Lawson #define MAX_EVENTS (MAX_INITIATORS + 5)
41c38b150aSNate Lawson /* kqueue for AIO, signals */
42c38b150aSNate Lawson
43c38b150aSNate Lawson /* Additional SCSI 3 defines for inquiry response */
44c38b150aSNate Lawson #define SID_Addr16 0x0100
45c38b150aSNate Lawson
46c38b150aSNate Lawson TAILQ_HEAD(io_queue, ccb_hdr);
47c38b150aSNate Lawson
48c38b150aSNate Lawson /* Offset into the private CCB area for storing our descriptor */
49c38b150aSNate Lawson #define targ_descr periph_priv.entries[1].ptr
50c38b150aSNate Lawson
51c38b150aSNate Lawson /* Descriptor attached to each ATIO */
52c38b150aSNate Lawson struct atio_descr {
53c38b150aSNate Lawson off_t base_off; /* Base offset for ATIO */
54068d70baSHidetoshi Shimokawa uint total_len; /* Total xfer len for this ATIO */
55068d70baSHidetoshi Shimokawa uint init_req; /* Transfer count requested to/from init */
56068d70baSHidetoshi Shimokawa uint init_ack; /* Data transferred ok to/from init */
57068d70baSHidetoshi Shimokawa uint targ_req; /* Transfer count requested to/from target */
58068d70baSHidetoshi Shimokawa uint targ_ack; /* Data transferred ok to/from target */
59c38b150aSNate Lawson int flags; /* Flags for CTIOs */
60c38b150aSNate Lawson u_int8_t *cdb; /* Pointer to received CDB */
61c38b150aSNate Lawson /* List of completed AIO/CTIOs */
62c38b150aSNate Lawson struct io_queue cmplt_io;
63c38b150aSNate Lawson };
64c38b150aSNate Lawson
65c38b150aSNate Lawson typedef enum {
66c38b150aSNate Lawson ATIO_WORK,
67c38b150aSNate Lawson AIO_DONE,
68c38b150aSNate Lawson CTIO_DONE
69c38b150aSNate Lawson } io_ops;
70c38b150aSNate Lawson
71c38b150aSNate Lawson /* Descriptor attached to each CTIO */
72c38b150aSNate Lawson struct ctio_descr {
73c38b150aSNate Lawson void *buf; /* Backing store */
74c38b150aSNate Lawson off_t offset; /* Position in transfer (for file, */
75c38b150aSNate Lawson /* doesn't start at 0) */
76c38b150aSNate Lawson struct aiocb aiocb; /* AIO descriptor for this CTIO */
77c38b150aSNate Lawson struct ccb_accept_tio *atio;
78c38b150aSNate Lawson /* ATIO we are satisfying */
79c38b150aSNate Lawson io_ops event; /* Event that queued this CTIO */
80c38b150aSNate Lawson };
81c38b150aSNate Lawson
82c38b150aSNate Lawson typedef enum {
83c38b150aSNate Lawson UA_NONE = 0x00,
84c38b150aSNate Lawson UA_POWER_ON = 0x01,
85c38b150aSNate Lawson UA_BUS_RESET = 0x02,
86c38b150aSNate Lawson UA_BDR = 0x04
87c38b150aSNate Lawson } ua_types;
88c38b150aSNate Lawson
89c38b150aSNate Lawson typedef enum {
90c38b150aSNate Lawson CA_NONE = 0x00,
91c38b150aSNate Lawson CA_UNIT_ATTN = 0x01,
92c38b150aSNate Lawson CA_CMD_SENSE = 0x02
93c38b150aSNate Lawson } ca_types;
94c38b150aSNate Lawson
95c38b150aSNate Lawson struct initiator_state {
96c38b150aSNate Lawson ua_types orig_ua;
97c38b150aSNate Lawson ca_types orig_ca;
98c38b150aSNate Lawson ua_types pending_ua;
99c38b150aSNate Lawson ca_types pending_ca;
100c38b150aSNate Lawson struct scsi_sense_data sense_data;
101c38b150aSNate Lawson };
102c38b150aSNate Lawson
103c38b150aSNate Lawson /* Global functions */
104c38b150aSNate Lawson extern cam_status tcmd_init(u_int16_t req_inq_flags,
105c38b150aSNate Lawson u_int16_t sim_inq_flags);
106c38b150aSNate Lawson extern int tcmd_handle(struct ccb_accept_tio *atio,
107c38b150aSNate Lawson struct ccb_scsiio *ctio, io_ops event);
108c38b150aSNate Lawson extern void tcmd_sense(u_int init_id, struct ccb_scsiio *ctio,
109c38b150aSNate Lawson u_int8_t flags,
110c38b150aSNate Lawson u_int8_t asc, u_int8_t ascq);
111c38b150aSNate Lawson extern void tcmd_ua(u_int init_id, ua_types new_ua);
112c38b150aSNate Lawson extern int work_atio(struct ccb_accept_tio *atio);
113c38b150aSNate Lawson extern void send_ccb(union ccb *ccb, int priority);
114c38b150aSNate Lawson extern void free_ccb(union ccb *ccb);
min(u_int a,u_int b)115c38b150aSNate Lawson static __inline u_int min(u_int a, u_int b) { return (a < b ? a : b); }
116c38b150aSNate Lawson
117cd6dedfcSMatt Jacob /* Global Data */
118cd6dedfcSMatt Jacob extern int notaio;
119*873881b7SAlan Somers extern int debug;
120*873881b7SAlan Somers extern off_t volume_size;
121*873881b7SAlan Somers extern u_int sector_size;
122*873881b7SAlan Somers extern size_t buf_size;
123cd6dedfcSMatt Jacob
124cd6dedfcSMatt Jacob /*
125cd6dedfcSMatt Jacob * Compat Defines
126cd6dedfcSMatt Jacob */
127cd6dedfcSMatt Jacob #if __FreeBSD_version >= 500000
128cd6dedfcSMatt Jacob #define OFF_FMT "%ju"
129cd6dedfcSMatt Jacob #else
130cd6dedfcSMatt Jacob #define OFF_FMT "%llu"
131cd6dedfcSMatt Jacob #endif
132cd6dedfcSMatt Jacob
133c38b150aSNate Lawson #endif /* _SCSI_TARGET_H */
134