1/*-
2 * SPDX-License-Identifier: BSD-2-Clause
3 *
4 * Copyright 2009 Scott Long
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
29#ifndef _CAM_CAM_XPT_INTERNAL_H
30#define _CAM_CAM_XPT_INTERNAL_H 1
31
32#include <sys/taskqueue.h>
33
34/* Forward Declarations */
35struct cam_eb;
36struct cam_et;
37struct cam_ed;
38
39typedef struct cam_ed * (*xpt_alloc_device_func)(struct cam_eb *bus,
40					         struct cam_et *target,
41					         lun_id_t lun_id);
42typedef void (*xpt_release_device_func)(struct cam_ed *device);
43typedef void (*xpt_action_func)(union ccb *start_ccb);
44typedef void (*xpt_dev_async_func)(uint32_t async_code,
45				   struct cam_eb *bus,
46				   struct cam_et *target,
47				   struct cam_ed *device,
48				   void *async_arg);
49typedef void (*xpt_announce_periph_func)(struct cam_periph *periph);
50typedef void (*xpt_announce_periph_sbuf_func)(struct cam_periph *periph, struct sbuf *sbuf);
51
52struct xpt_xport_ops {
53	xpt_alloc_device_func	alloc_device;
54	xpt_release_device_func	reldev;
55	xpt_action_func		action;
56	xpt_dev_async_func	async;
57	xpt_announce_periph_sbuf_func announce_sbuf;
58};
59
60struct xpt_xport {
61	cam_xport		xport;
62	const char		*name;
63	struct xpt_xport_ops	*ops;
64};
65
66SET_DECLARE(cam_xpt_xport_set, struct xpt_xport);
67#define CAM_XPT_XPORT(data) 				\
68	DATA_SET(cam_xpt_xport_set, data)
69
70typedef void (*xpt_proto_announce_func)(struct cam_ed *);
71typedef void (*xpt_proto_announce_sbuf_func)(struct cam_ed *, struct sbuf *);
72typedef void (*xpt_proto_debug_out_func)(union ccb *);
73
74struct xpt_proto_ops {
75	xpt_proto_announce_sbuf_func	announce_sbuf;
76	xpt_proto_announce_sbuf_func	denounce_sbuf;
77	xpt_proto_debug_out_func debug_out;
78};
79
80struct xpt_proto {
81	cam_proto		proto;
82	const char		*name;
83	struct xpt_proto_ops	*ops;
84};
85
86SET_DECLARE(cam_xpt_proto_set, struct xpt_proto);
87#define CAM_XPT_PROTO(data) 				\
88	DATA_SET(cam_xpt_proto_set, data)
89
90/*
91 * The CAM EDT (Existing Device Table) contains the device information for
92 * all devices for all buses in the system.  The table contains a
93 * cam_ed structure for each device on the bus.
94 */
95struct cam_ed {
96	cam_pinfo	 devq_entry;
97	TAILQ_ENTRY(cam_ed) links;
98	struct	cam_et	 *target;
99	struct	cam_sim  *sim;
100	lun_id_t	 lun_id;
101	struct	cam_ccbq ccbq;		/* Queue of pending ccbs */
102	struct	async_list asyncs;	/* Async callback info for this B/T/L */
103	struct	periph_list periphs;	/* All attached devices */
104	u_int		 generation;	/* Generation number */
105	void		 *quirk;	/* Oddities about this device */
106	u_int		 maxtags;
107	u_int		 mintags;
108	cam_proto	 protocol;
109	u_int		 protocol_version;
110	cam_xport	 transport;
111	u_int		 transport_version;
112	struct		 scsi_inquiry_data inq_data;
113	uint8_t		 *supported_vpds;
114	uint8_t		 supported_vpds_len;
115	uint32_t	 device_id_len;
116	uint8_t		 *device_id;
117	uint32_t	 ext_inq_len;
118	uint8_t		 *ext_inq;
119	uint8_t		 physpath_len;
120	uint8_t		 *physpath;	/* physical path string form */
121	uint32_t	 rcap_len;
122	uint8_t		 *rcap_buf;
123	struct		 ata_params ident_data;
124        struct		 mmc_params mmc_ident_data;
125	uint8_t	 inq_flags;	/*
126					 * Current settings for inquiry flags.
127					 * This allows us to override settings
128					 * like disconnection and tagged
129					 * queuing for a device.
130					 */
131	uint8_t	 queue_flags;	/* Queue flags from the control page */
132	uint8_t	 serial_num_len;
133	uint8_t	*serial_num;
134	uint32_t	 flags;
135#define CAM_DEV_UNCONFIGURED	 	0x01
136#define CAM_DEV_REL_TIMEOUT_PENDING	0x02
137#define CAM_DEV_REL_ON_COMPLETE		0x04
138#define CAM_DEV_REL_ON_QUEUE_EMPTY	0x08
139#define CAM_DEV_TAG_AFTER_COUNT		0x20
140#define CAM_DEV_INQUIRY_DATA_VALID	0x40
141#define	CAM_DEV_IN_DV			0x80
142#define	CAM_DEV_DV_HIT_BOTTOM		0x100
143#define CAM_DEV_IDENTIFY_DATA_VALID	0x200
144	uint32_t	 tag_delay_count;
145#define	CAM_TAG_DELAY_COUNT		5
146	uint32_t	 tag_saved_openings;
147	uint32_t	 refcount;
148	struct callout	 callout;
149	STAILQ_ENTRY(cam_ed) highpowerq_entry;
150	struct mtx	 device_mtx;
151	struct task	 device_destroy_task;
152	struct nvme_controller_data *nvme_cdata;
153	struct nvme_namespace_data *nvme_data;
154};
155
156/*
157 * Each target is represented by an ET (Existing Target).  These
158 * entries are created when a target is successfully probed with an
159 * identify, and removed when a device fails to respond after a number
160 * of retries, or a bus rescan finds the device missing.
161 */
162struct cam_et {
163	TAILQ_HEAD(, cam_ed) ed_entries;
164	TAILQ_ENTRY(cam_et) links;
165	struct	cam_eb	*bus;
166	target_id_t	target_id;
167	uint32_t	refcount;
168	u_int		generation;
169	struct		timeval last_reset;
170	u_int		rpl_size;
171	struct scsi_report_luns_data *luns;
172	struct mtx	luns_mtx;	/* Protection for luns field. */
173};
174
175/*
176 * Each bus is represented by an EB (Existing Bus).  These entries
177 * are created by calls to xpt_bus_register and deleted by calls to
178 * xpt_bus_deregister.
179 */
180struct cam_eb {
181	TAILQ_HEAD(, cam_et) et_entries;
182	TAILQ_ENTRY(cam_eb)  links;
183	path_id_t	     path_id;
184	struct cam_sim	     *sim;
185	struct timeval	     last_reset;
186	uint32_t	     flags;
187#define	CAM_EB_RUNQ_SCHEDULED	0x01
188	uint32_t	     refcount;
189	u_int		     generation;
190	device_t	     parent_dev;
191	struct xpt_xport     *xport;
192	struct mtx	     eb_mtx;	/* Bus topology mutex. */
193};
194
195struct cam_path {
196	struct cam_periph *periph;
197	struct cam_eb	  *bus;
198	struct cam_et	  *target;
199	struct cam_ed	  *device;
200};
201
202struct cam_ed *		xpt_alloc_device(struct cam_eb *bus,
203					 struct cam_et *target,
204					 lun_id_t lun_id);
205void			xpt_acquire_device(struct cam_ed *device);
206void			xpt_release_device(struct cam_ed *device);
207uint32_t		xpt_dev_ccbq_resize(struct cam_path *path, int newopenings);
208void			xpt_start_tags(struct cam_path *path);
209void			xpt_stop_tags(struct cam_path *path);
210
211MALLOC_DECLARE(M_CAMXPT);
212
213#endif
214