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