1/*-
2 * SPDX-License-Identifier: BSD-2-Clause
3 *
4 * Copyright (c) 2003 Silicon Graphics International Corp.
5 * Copyright (c) 2014-2017 Alexander Motin <mav@FreeBSD.org>
6 * All rights reserved.
7 *
8 * Redistribution and use in source and binary forms, with or without
9 * modification, are permitted provided that the following conditions
10 * are met:
11 * 1. Redistributions of source code must retain the above copyright
12 *    notice, this list of conditions, and the following disclaimer,
13 *    without modification.
14 * 2. Redistributions in binary form must reproduce at minimum a disclaimer
15 *    substantially similar to the "NO WARRANTY" disclaimer below
16 *    ("Disclaimer") and any redistribution must be conditioned upon
17 *    including a substantially similar Disclaimer requirement for further
18 *    binary redistribution.
19 *
20 * NO WARRANTY
21 * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
22 * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
23 * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTIBILITY AND FITNESS FOR
24 * A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
25 * HOLDERS OR CONTRIBUTORS BE LIABLE FOR SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
26 * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
27 * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
28 * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT,
29 * STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING
30 * IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
31 * POSSIBILITY OF SUCH DAMAGES.
32 *
33 * $Id: //depot/users/kenm/FreeBSD-test2/sys/cam/ctl/ctl_backend.h#2 $
34 */
35/*
36 * CTL backend driver definitions
37 *
38 * Author: Ken Merry <ken@FreeBSD.org>
39 */
40
41#ifndef	_CTL_BACKEND_H_
42#define	_CTL_BACKEND_H_
43
44#include <cam/ctl/ctl_ioctl.h>
45#include <sys/nv.h>
46
47typedef enum {
48	CTL_LUN_SERSEQ_OFF,
49	CTL_LUN_SERSEQ_SOFT,
50	CTL_LUN_SERSEQ_READ,
51	CTL_LUN_SERSEQ_ON
52} ctl_lun_serseq;
53
54#ifdef _KERNEL
55
56#define CTL_BACKEND_DECLARE(name, driver) \
57	static int name ## _modevent(module_t mod, int type, void *data) \
58	{ \
59		switch (type) { \
60		case MOD_LOAD: \
61			return (ctl_backend_register( \
62				(struct ctl_backend_driver *)data)); \
63			break; \
64		case MOD_UNLOAD: \
65			return (ctl_backend_deregister( \
66				(struct ctl_backend_driver *)data)); \
67			break; \
68		default: \
69			return EOPNOTSUPP; \
70		} \
71		return 0; \
72	} \
73	static moduledata_t name ## _mod = { \
74		#name, \
75		name ## _modevent, \
76		(void *)&driver \
77	}; \
78	DECLARE_MODULE(name, name ## _mod, SI_SUB_CONFIGURE, SI_ORDER_FOURTH); \
79	MODULE_DEPEND(name, ctl, 1, 1, 1); \
80	MODULE_DEPEND(name, cam, 1, 1, 1)
81
82struct ctl_be_lun;
83typedef void (*be_callback_t)(struct ctl_be_lun *be_lun);
84
85/*
86 * The lun_type field is the SCSI device type of this particular LUN.  In
87 * general, this should be T_DIRECT, although backends will want to create
88 * a processor LUN, typically at LUN 0.  See scsi_all.h for the defines for
89 * the various SCSI device types.
90 *
91 * The flags are described above.
92 *
93 * The be_lun field is the backend driver's own context that will get
94 * passsed back so that it can tell which LUN CTL is referencing.
95 *
96 * maxlba is the maximum accessible LBA on the LUN.  Note that this is
97 * different from the capacity of the array.  capacity = maxlba + 1
98 *
99 * blocksize is the size, in bytes, of each LBA on the LUN.  In general
100 * this should be 512.  In theory CTL should be able to handle other block
101 * sizes.  Host application software may not deal with it very well, though.
102 *
103 * pblockexp is the log2() of number of LBAs on the LUN per physical sector.
104 *
105 * pblockoff is the lowest LBA on the LUN aligned to physical sector.
106 *
107 * ublockexp is the log2() of number of LBAs on the LUN per UNMAP block.
108 *
109 * ublockoff is the lowest LBA on the LUN aligned to UNMAP block.
110 *
111 * atomicblock is the number of blocks that can be written atomically.
112 *
113 * opttxferlen is the number of blocks that can be written in one operation.
114 *
115 * req_lun_id is the requested LUN ID.  CTL only pays attention to this
116 * field if the CTL_LUN_FLAG_ID_REQ flag is set.  If the requested LUN ID is
117 * not available, the LUN addition will fail.  If a particular LUN ID isn't
118 * requested, the first available LUN ID will be allocated.
119 *
120 * serial_num is the device serial number returned in the SCSI INQUIRY VPD
121 * page 0x80.  This should be a unique, per-shelf value.  The data inside
122 * this field should be ASCII only, left aligned, and any unused space
123 * should be padded out with ASCII spaces.  This field should NOT be NULL
124 * terminated.
125 *
126 * device_id is the T10 device identifier returned in the SCSI INQUIRY VPD
127 * page 0x83.  This should be a unique, per-LUN value.  The data inside
128 * this field should be ASCII only, left aligned, and any unused space
129 * should be padded with ASCII spaces.  This field should NOT be NULL
130 * terminated.
131 *
132 * The lun_shutdown() method is the callback for the ctl_remove_lun()
133 * call.  It is called when all outstanding I/O for that LUN has been
134 * completed and CTL has deleted the resources for that LUN.  When the CTL
135 * backend gets this call, it can safely free its per-LUN resources.
136 *
137 * The be field is a pointer to the ctl_backend_driver structure, which
138 * contains the backend methods to be called by CTL.
139 *
140 * The ctl_lun field is for CTL internal use only, and should not be used
141 * by the backend.
142 *
143 * The links field is for CTL internal use only, and should not be used by
144 * the backend.
145 */
146struct ctl_be_lun {
147	uint8_t			lun_type;	/* passed to CTL */
148	ctl_backend_lun_flags	flags;		/* passed to CTL */
149	ctl_lun_serseq		serseq;		/* passed to CTL */
150	uint64_t		maxlba;		/* passed to CTL */
151	uint32_t		blocksize;	/* passed to CTL */
152	uint16_t		pblockexp;	/* passed to CTL */
153	uint16_t		pblockoff;	/* passed to CTL */
154	uint16_t		ublockexp;	/* passed to CTL */
155	uint16_t		ublockoff;	/* passed to CTL */
156	uint32_t		atomicblock;	/* passed to CTL */
157	uint32_t		opttxferlen;	/* passed to CTL */
158	uint32_t		req_lun_id;	/* passed to CTL */
159	uint32_t		lun_id;		/* returned from CTL */
160	uint8_t			serial_num[CTL_SN_LEN];	 /* passed to CTL */
161	uint8_t			device_id[CTL_DEVID_LEN];/* passed to CTL */
162	be_callback_t		lun_shutdown;	/* passed to CTL */
163	struct ctl_backend_driver *be;		/* passed to CTL */
164	void			*ctl_lun;	/* used by CTL */
165	nvlist_t	 	*options;	/* passed to CTL */
166	STAILQ_ENTRY(ctl_be_lun) links;		/* used by CTL */
167};
168
169typedef enum {
170	CTL_BE_FLAG_NONE	= 0x00,	/* no flags */
171	CTL_BE_FLAG_HAS_CONFIG	= 0x01,	/* can do config reads, writes */
172} ctl_backend_flags;
173
174typedef int (*be_init_t)(void);
175typedef int (*be_shutdown_t)(void);
176typedef int (*be_func_t)(union ctl_io *io);
177typedef void (*be_vfunc_t)(union ctl_io *io);
178typedef int (*be_ioctl_t)(struct cdev *dev, u_long cmd, caddr_t addr, int flag,
179			  struct thread *td);
180typedef int (*be_luninfo_t)(struct ctl_be_lun *be_lun, struct sbuf *sb);
181typedef uint64_t (*be_lunattr_t)(struct ctl_be_lun *be_lun, const char *attrname);
182
183struct ctl_backend_driver {
184	char		  name[CTL_BE_NAME_LEN]; /* passed to CTL */
185	ctl_backend_flags flags;	         /* passed to CTL */
186	be_init_t	  init;			 /* passed to CTL */
187	be_shutdown_t	  shutdown;		 /* passed to CTL */
188	be_func_t	  data_submit;		 /* passed to CTL */
189	be_func_t	  config_read;		 /* passed to CTL */
190	be_func_t	  config_write;		 /* passed to CTL */
191	be_ioctl_t	  ioctl;		 /* passed to CTL */
192	be_luninfo_t	  lun_info;		 /* passed to CTL */
193	be_lunattr_t	  lun_attr;		 /* passed to CTL */
194#ifdef CS_BE_CONFIG_MOVE_DONE_IS_NOT_USED
195	be_func_t	  config_move_done;	 /* passed to backend */
196#endif
197#if 0
198	be_vfunc_t	  config_write_done;	 /* passed to backend */
199#endif
200	STAILQ_ENTRY(ctl_backend_driver) links;	 /* used by CTL */
201};
202
203int ctl_backend_register(struct ctl_backend_driver *be);
204int ctl_backend_deregister(struct ctl_backend_driver *be);
205struct ctl_backend_driver *ctl_backend_find(char *backend_name);
206
207/*
208 * To add a LUN, call ctl_add_lun().
209 */
210int ctl_add_lun(struct ctl_be_lun *be_lun);
211
212/*
213 * To remove a LUN, first call ctl_remove_lun().
214 * You will get the lun_shutdown() callback when all
215 * I/O to the LUN has completed and the LUN has been deleted.
216 */
217int ctl_remove_lun(struct ctl_be_lun *be_lun);
218
219/*
220 * To start a LUN (transition from powered off to powered on state) call
221 * ctl_start_lun().  To stop a LUN (transition from powered on to powered
222 * off state) call ctl_stop_lun().
223 */
224int ctl_start_lun(struct ctl_be_lun *be_lun);
225int ctl_stop_lun(struct ctl_be_lun *be_lun);
226
227/*
228 * Methods to notify about media and tray status changes.
229 */
230int ctl_lun_no_media(struct ctl_be_lun *be_lun);
231int ctl_lun_has_media(struct ctl_be_lun *be_lun);
232int ctl_lun_ejected(struct ctl_be_lun *be_lun);
233
234/*
235 * Called on LUN HA role change.
236 */
237int ctl_lun_primary(struct ctl_be_lun *be_lun);
238int ctl_lun_secondary(struct ctl_be_lun *be_lun);
239
240/*
241 * Let the backend notify the initiators about changes.
242 */
243void ctl_lun_capacity_changed(struct ctl_be_lun *be_lun);
244
245/*
246 * Populate unique ID fields in NVMe namespace data for a LUN.
247 */
248void ctl_lun_nsdata_ids(struct ctl_be_lun *be_lun,
249    struct nvme_namespace_data *nsdata);
250
251/*
252 * Populate the NVMe namespace identification descriptor list for a LUN.
253 */
254void ctl_lun_nvme_ids(struct ctl_be_lun *be_lun, void *data);
255
256#endif /* _KERNEL */
257#endif /* _CTL_BACKEND_H_ */
258
259/*
260 * vim: ts=8
261 */
262