1139825Simp/*-
236270Swpaul * Copyright 2009 Scott Long
336270Swpaul * All rights reserved.
436270Swpaul *
536270Swpaul * Redistribution and use in source and binary forms, with or without
636270Swpaul * modification, are permitted provided that the following conditions
736270Swpaul * are met:
836270Swpaul * 1. Redistributions of source code must retain the above copyright
936270Swpaul *    notice, this list of conditions, and the following disclaimer,
1036270Swpaul *    without modification, immediately at the beginning of the file.
1136270Swpaul * 2. The name of the author may not be used to endorse or promote products
1236270Swpaul *    derived from this software without specific prior written permission.
1336270Swpaul *
1436270Swpaul * THIS SOFTWARE IS PROVIDED BY THE AUTHOR AND CONTRIBUTORS ``AS IS'' AND
1536270Swpaul * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
1636270Swpaul * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
1736270Swpaul * ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE FOR
1836270Swpaul * ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
1936270Swpaul * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
2036270Swpaul * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
2136270Swpaul * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
2236270Swpaul * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
2336270Swpaul * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
2436270Swpaul * SUCH DAMAGE.
2536270Swpaul *
2636270Swpaul * $FreeBSD: releng/10.3/sys/cam/cam_xpt_internal.h 278974 2015-02-18 23:08:13Z ken $
2736270Swpaul */
2836270Swpaul
2936270Swpaul#ifndef _CAM_CAM_XPT_INTERNAL_H
3036270Swpaul#define _CAM_CAM_XPT_INTERNAL_H 1
3136270Swpaul
3236270Swpaul#include <sys/taskqueue.h>
33122678Sobrien
34122678Sobrien/* Forward Declarations */
35122678Sobrienstruct cam_eb;
3636270Swpaulstruct cam_et;
3736270Swpaulstruct cam_ed;
3836270Swpaul
3936270Swpaultypedef struct cam_ed * (*xpt_alloc_device_func)(struct cam_eb *bus,
4036270Swpaul					         struct cam_et *target,
4136270Swpaul					         lun_id_t lun_id);
4239583Swpaultypedef void (*xpt_release_device_func)(struct cam_ed *device);
4336270Swpaultypedef void (*xpt_action_func)(union ccb *start_ccb);
4436270Swpaultypedef void (*xpt_dev_async_func)(u_int32_t async_code,
4536270Swpaul				   struct cam_eb *bus,
4636270Swpaul				   struct cam_et *target,
4739583Swpaul				   struct cam_ed *device,
4836270Swpaul				   void *async_arg);
4936270Swpaultypedef void (*xpt_announce_periph_func)(struct cam_periph *periph);
5036270Swpaul
5136270Swpaulstruct xpt_xport {
5236270Swpaul	xpt_alloc_device_func	alloc_device;
5336270Swpaul	xpt_release_device_func	reldev;
5436270Swpaul	xpt_action_func		action;
5536270Swpaul	xpt_dev_async_func	async;
5636270Swpaul	xpt_announce_periph_func announce;
5736270Swpaul};
5839583Swpaul
5936270Swpaul/*
6036270Swpaul * The CAM EDT (Existing Device Table) contains the device information for
6136270Swpaul * all devices for all busses in the system.  The table contains a
6236270Swpaul * cam_ed structure for each device on the bus.
6336270Swpaul */
6436270Swpaulstruct cam_ed {
6536270Swpaul	cam_pinfo	 devq_entry;
6639583Swpaul	TAILQ_ENTRY(cam_ed) links;
6739583Swpaul	struct	cam_et	 *target;
6839583Swpaul	struct	cam_sim  *sim;
6939583Swpaul	lun_id_t	 lun_id;
7039583Swpaul	struct	cam_ccbq ccbq;		/* Queue of pending ccbs */
7139583Swpaul	struct	async_list asyncs;	/* Async callback info for this B/T/L */
7239583Swpaul	struct	periph_list periphs;	/* All attached devices */
7339583Swpaul	u_int	generation;		/* Generation number */
7439583Swpaul	void		 *quirk;	/* Oddities about this device */
7536270Swpaul	u_int		 maxtags;
7636270Swpaul	u_int		 mintags;
7739583Swpaul	cam_proto	 protocol;
7836270Swpaul	u_int		 protocol_version;
7936270Swpaul	cam_xport	 transport;
8036270Swpaul	u_int		 transport_version;
8136270Swpaul	struct		 scsi_inquiry_data inq_data;
8236270Swpaul	uint8_t		 *supported_vpds;
8336270Swpaul	uint8_t		 supported_vpds_len;
8436270Swpaul	uint32_t	 device_id_len;
8536270Swpaul	uint8_t		 *device_id;
8636270Swpaul	uint32_t	 ext_inq_len;
8736270Swpaul	uint8_t		 *ext_inq;
8836270Swpaul	uint8_t		 physpath_len;
8936270Swpaul	uint8_t		 *physpath;	/* physical path string form */
9036270Swpaul	uint32_t	 rcap_len;
9136270Swpaul	uint8_t		 *rcap_buf;
9236270Swpaul	struct		 ata_params ident_data;
9336270Swpaul	u_int8_t	 inq_flags;	/*
9436270Swpaul					 * Current settings for inquiry flags.
9536270Swpaul					 * This allows us to override settings
9636270Swpaul					 * like disconnection and tagged
9736270Swpaul					 * queuing for a device.
9836270Swpaul					 */
9936270Swpaul	u_int8_t	 queue_flags;	/* Queue flags from the control page */
10036270Swpaul	u_int8_t	 serial_num_len;
10136270Swpaul	u_int8_t	*serial_num;
10236270Swpaul	u_int32_t	 flags;
10336270Swpaul#define CAM_DEV_UNCONFIGURED	 	0x01
10436270Swpaul#define CAM_DEV_REL_TIMEOUT_PENDING	0x02
10536270Swpaul#define CAM_DEV_REL_ON_COMPLETE		0x04
10636270Swpaul#define CAM_DEV_REL_ON_QUEUE_EMPTY	0x08
10736270Swpaul#define CAM_DEV_TAG_AFTER_COUNT		0x20
10836270Swpaul#define CAM_DEV_INQUIRY_DATA_VALID	0x40
10936270Swpaul#define	CAM_DEV_IN_DV			0x80
11036270Swpaul#define	CAM_DEV_DV_HIT_BOTTOM		0x100
11136270Swpaul#define CAM_DEV_IDENTIFY_DATA_VALID	0x200
11236270Swpaul	u_int32_t	 tag_delay_count;
11336270Swpaul#define	CAM_TAG_DELAY_COUNT		5
11436270Swpaul	u_int32_t	 tag_saved_openings;
11536270Swpaul	u_int32_t	 refcount;
11636270Swpaul	struct callout	 callout;
11736270Swpaul	STAILQ_ENTRY(cam_ed) highpowerq_entry;
11836270Swpaul	struct mtx	 device_mtx;
11936270Swpaul	struct task	 device_destroy_task;
12036270Swpaul};
12136270Swpaul
12236270Swpaul/*
12336270Swpaul * Each target is represented by an ET (Existing Target).  These
12436270Swpaul * entries are created when a target is successfully probed with an
12536270Swpaul * identify, and removed when a device fails to respond after a number
12636270Swpaul * of retries, or a bus rescan finds the device missing.
12736270Swpaul */
12836270Swpaulstruct cam_et {
12936270Swpaul	TAILQ_HEAD(, cam_ed) ed_entries;
13036270Swpaul	TAILQ_ENTRY(cam_et) links;
13136270Swpaul	struct	cam_eb	*bus;
13236270Swpaul	target_id_t	target_id;
13336270Swpaul	u_int32_t	refcount;
13436270Swpaul	u_int		generation;
13536270Swpaul	struct		timeval last_reset;
13636270Swpaul	u_int		rpl_size;
13736270Swpaul	struct scsi_report_luns_data *luns;
13836270Swpaul	struct mtx	luns_mtx;	/* Protection for luns field. */
13936270Swpaul};
14036270Swpaul
14136270Swpaul/*
14236270Swpaul * Each bus is represented by an EB (Existing Bus).  These entries
14336270Swpaul * are created by calls to xpt_bus_register and deleted by calls to
14436270Swpaul * xpt_bus_deregister.
14536270Swpaul */
14636270Swpaulstruct cam_eb {
14736270Swpaul	TAILQ_HEAD(, cam_et) et_entries;
14836270Swpaul	TAILQ_ENTRY(cam_eb)  links;
14936270Swpaul	path_id_t	     path_id;
15036270Swpaul	struct cam_sim	     *sim;
15136270Swpaul	struct timeval	     last_reset;
15236270Swpaul	u_int32_t	     flags;
15336270Swpaul#define	CAM_EB_RUNQ_SCHEDULED	0x01
15436270Swpaul	u_int32_t	     refcount;
15536270Swpaul	u_int		     generation;
15636270Swpaul	device_t	     parent_dev;
15736270Swpaul	struct xpt_xport     *xport;
15836270Swpaul	struct mtx	     eb_mtx;	/* Bus topology mutex. */
15936270Swpaul};
16036270Swpaul
16136270Swpaulstruct cam_path {
16236270Swpaul	struct cam_periph *periph;
16336270Swpaul	struct cam_eb	  *bus;
16436270Swpaul	struct cam_et	  *target;
16536270Swpaul	struct cam_ed	  *device;
16636270Swpaul};
16736270Swpaul
16836270Swpaulstruct xpt_xport *	scsi_get_xport(void);
16936270Swpaulstruct xpt_xport *	ata_get_xport(void);
17036270Swpaul
17136270Swpaulstruct cam_ed *		xpt_alloc_device(struct cam_eb *bus,
17236270Swpaul					 struct cam_et *target,
17336270Swpaul					 lun_id_t lun_id);
17436270Swpaulvoid			xpt_acquire_device(struct cam_ed *device);
17536270Swpaulvoid			xpt_release_device(struct cam_ed *device);
17636270Swpaulu_int32_t		xpt_dev_ccbq_resize(struct cam_path *path, int newopenings);
17736270Swpaulvoid			xpt_start_tags(struct cam_path *path);
17836270Swpaulvoid			xpt_stop_tags(struct cam_path *path);
17936270Swpaul
18036270SwpaulMALLOC_DECLARE(M_CAMXPT);
18136270Swpaul
18236270Swpaul#endif
18336270Swpaul