1230592Sken/*-
2281564Sslm * Copyright (c) 2011-2015 LSI Corp.
3281564Sslm * Copyright (c) 2013-2015 Avago Technologies
4230592Sken * All rights reserved.
5230592Sken *
6230592Sken * Redistribution and use in source and binary forms, with or without
7230592Sken * modification, are permitted provided that the following conditions
8230592Sken * are met:
9230592Sken * 1. Redistributions of source code must retain the above copyright
10230592Sken *    notice, this list of conditions and the following disclaimer.
11230592Sken * 2. Redistributions in binary form must reproduce the above copyright
12230592Sken *    notice, this list of conditions and the following disclaimer in the
13230592Sken *    documentation and/or other materials provided with the distribution.
14230592Sken *
15230592Sken * THIS SOFTWARE IS PROVIDED BY THE AUTHOR AND CONTRIBUTORS ``AS IS'' AND
16230592Sken * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
17230592Sken * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
18230592Sken * ARE DISCLAIMED.  IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE
19230592Sken * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
20230592Sken * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
21230592Sken * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
22230592Sken * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
23230592Sken * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
24230592Sken * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
25230592Sken * SUCH DAMAGE.
26230592Sken *
27281564Sslm * Avago Technologies (LSI) MPT-Fusion Host Adapter FreeBSD
28230592Sken *
29230592Sken * $FreeBSD: releng/10.2/sys/dev/mps/mps_sas.h 281564 2015-04-15 21:47:15Z slm $
30230592Sken */
31230592Sken
32230592Skenstruct mps_fw_event_work;
33230592Sken
34230592Skenstruct mpssas_lun {
35230592Sken	SLIST_ENTRY(mpssas_lun) lun_link;
36230592Sken	lun_id_t	lun_id;
37230592Sken	uint8_t		eedp_formatted;
38230592Sken	uint32_t	eedp_block_size;
39230592Sken};
40230592Sken
41230592Skenstruct mpssas_target {
42230592Sken	uint16_t	handle;
43230592Sken	uint8_t		linkrate;
44230592Sken	uint64_t	devname;
45230592Sken	uint32_t	devinfo;
46230592Sken	uint16_t	encl_handle;
47230592Sken	uint16_t	encl_slot;
48230592Sken	uint8_t		flags;
49230592Sken#define MPSSAS_TARGET_INABORT	(1 << 0)
50230592Sken#define MPSSAS_TARGET_INRESET	(1 << 1)
51230592Sken#define MPSSAS_TARGET_INDIAGRESET (1 << 2)
52230592Sken#define MPSSAS_TARGET_INREMOVAL	(1 << 3)
53231240Sken#define MPS_TARGET_FLAGS_RAID_COMPONENT (1 << 4)
54231240Sken#define MPS_TARGET_FLAGS_VOLUME         (1 << 5)
55281564Sslm#define MPS_TARGET_IS_SATA_SSD	(1 << 6)
56230592Sken#define MPSSAS_TARGET_INRECOVERY (MPSSAS_TARGET_INABORT | \
57230592Sken    MPSSAS_TARGET_INRESET | MPSSAS_TARGET_INCHIPRESET)
58231240Sken
59230592Sken	uint16_t	tid;
60230592Sken	SLIST_HEAD(, mpssas_lun) luns;
61230592Sken	TAILQ_HEAD(, mps_command) commands;
62230592Sken	struct mps_command *tm;
63230592Sken	TAILQ_HEAD(, mps_command) timedout_commands;
64230592Sken	uint16_t        exp_dev_handle;
65230592Sken	uint16_t        phy_num;
66230592Sken	uint64_t	sasaddr;
67230592Sken	uint16_t	parent_handle;
68230592Sken	uint64_t	parent_sasaddr;
69230592Sken	uint32_t	parent_devinfo;
70230592Sken	struct sysctl_ctx_list sysctl_ctx;
71230592Sken	struct sysctl_oid *sysctl_tree;
72230592Sken	TAILQ_ENTRY(mpssas_target) sysctl_link;
73230592Sken	uint64_t        issued;
74230592Sken	uint64_t        completed;
75230592Sken	unsigned int    outstanding;
76230592Sken	unsigned int    timeouts;
77230592Sken	unsigned int    aborts;
78230592Sken	unsigned int    logical_unit_resets;
79230592Sken	unsigned int    target_resets;
80281564Sslm	uint8_t		stop_at_shutdown;
81281564Sslm	uint8_t		supports_SSU;
82230592Sken};
83230592Sken
84230592Skenstruct mpssas_softc {
85230592Sken	struct mps_softc	*sc;
86230592Sken	u_int			flags;
87230592Sken#define MPSSAS_IN_DISCOVERY	(1 << 0)
88230592Sken#define MPSSAS_IN_STARTUP	(1 << 1)
89230592Sken#define MPSSAS_DISCOVERY_TIMEOUT_PENDING	(1 << 2)
90230592Sken#define MPSSAS_QUEUE_FROZEN	(1 << 3)
91230592Sken#define	MPSSAS_SHUTDOWN		(1 << 4)
92264492Sscottl	u_int			maxtargets;
93230592Sken	struct mpssas_target	*targets;
94230592Sken	struct cam_devq		*devq;
95230592Sken	struct cam_sim		*sim;
96230592Sken	struct cam_path		*path;
97230592Sken	struct intr_config_hook	sas_ich;
98230592Sken	struct callout		discovery_callout;
99230592Sken	struct mps_event_handle	*mpssas_eh;
100230592Sken
101230592Sken	u_int                   startup_refcount;
102230592Sken	struct proc             *sysctl_proc;
103230592Sken
104230592Sken	struct taskqueue	*ev_tq;
105230592Sken	struct task		ev_task;
106230592Sken	TAILQ_HEAD(, mps_fw_event_work)	ev_queue;
107230592Sken};
108230592Sken
109230592SkenMALLOC_DECLARE(M_MPSSAS);
110230592Sken
111230592Sken/*
112230592Sken * Abstracted so that the driver can be backwards and forwards compatible
113230592Sken * with future versions of CAM that will provide this functionality.
114230592Sken */
115230592Sken#define MPS_SET_LUN(lun, ccblun)	\
116230592Sken	mpssas_set_lun(lun, ccblun)
117230592Sken
118230592Skenstatic __inline int
119230592Skenmpssas_set_lun(uint8_t *lun, u_int ccblun)
120230592Sken{
121230592Sken	uint64_t *newlun;
122230592Sken
123230592Sken	newlun = (uint64_t *)lun;
124230592Sken	*newlun = 0;
125230592Sken	if (ccblun <= 0xff) {
126230592Sken		/* Peripheral device address method, LUN is 0 to 255 */
127230592Sken		lun[1] = ccblun;
128230592Sken	} else if (ccblun <= 0x3fff) {
129230592Sken		/* Flat space address method, LUN is <= 16383 */
130230592Sken		scsi_ulto2b(ccblun, lun);
131230592Sken		lun[0] |= 0x40;
132230592Sken	} else if (ccblun <= 0xffffff) {
133230592Sken		/* Extended flat space address method, LUN is <= 16777215 */
134230592Sken		scsi_ulto3b(ccblun, &lun[1]);
135230592Sken		/* Extended Flat space address method */
136230592Sken		lun[0] = 0xc0;
137230592Sken		/* Length = 1, i.e. LUN is 3 bytes long */
138230592Sken		lun[0] |= 0x10;
139230592Sken		/* Extended Address Method */
140230592Sken		lun[0] |= 0x02;
141230592Sken	} else {
142230592Sken		return (EINVAL);
143230592Sken	}
144230592Sken
145230592Sken	return (0);
146230592Sken}
147230592Sken
148268197Sscottlstatic __inline void
149268197Sscottlmpssas_set_ccbstatus(union ccb *ccb, int status)
150268197Sscottl{
151268197Sscottl	ccb->ccb_h.status &= ~CAM_STATUS_MASK;
152268197Sscottl	ccb->ccb_h.status |= status;
153268197Sscottl}
154268197Sscottl
155268197Sscottlstatic __inline int
156268197Sscottlmpssas_get_ccbstatus(union ccb *ccb)
157268197Sscottl{
158268197Sscottl	return (ccb->ccb_h.status & CAM_STATUS_MASK);
159268197Sscottl}
160268197Sscottl
161230592Sken#define MPS_SET_SINGLE_LUN(req, lun)	\
162230592Skendo {					\
163230592Sken	bzero((req)->LUN, 8);		\
164230592Sken	(req)->LUN[1] = lun;		\
165230592Sken} while(0)
166230592Sken
167230592Skenvoid mpssas_rescan_target(struct mps_softc *sc, struct mpssas_target *targ);
168230592Skenvoid mpssas_discovery_end(struct mpssas_softc *sassc);
169281564Sslmvoid mpssas_prepare_for_tm(struct mps_softc *sc, struct mps_command *tm,
170281564Sslm    struct mpssas_target *target, lun_id_t lun_id);
171230592Skenvoid mpssas_startup_increment(struct mpssas_softc *sassc);
172230592Skenvoid mpssas_startup_decrement(struct mpssas_softc *sassc);
173230592Sken
174230592Skenvoid mpssas_firmware_event_work(void *arg, int pending);
175254116Sscottlint mpssas_check_id(struct mpssas_softc *sassc, int id);
176