1c12c399aSSascha Wildner /*-
2c12c399aSSascha Wildner * Copyright (c) 2011 LSI Corp.
3c12c399aSSascha Wildner * All rights reserved.
4c12c399aSSascha Wildner *
5c12c399aSSascha Wildner * Redistribution and use in source and binary forms, with or without
6c12c399aSSascha Wildner * modification, are permitted provided that the following conditions
7c12c399aSSascha Wildner * are met:
8c12c399aSSascha Wildner * 1. Redistributions of source code must retain the above copyright
9c12c399aSSascha Wildner * notice, this list of conditions and the following disclaimer.
10c12c399aSSascha Wildner * 2. Redistributions in binary form must reproduce the above copyright
11c12c399aSSascha Wildner * notice, this list of conditions and the following disclaimer in the
12c12c399aSSascha Wildner * documentation and/or other materials provided with the distribution.
13c12c399aSSascha Wildner *
14c12c399aSSascha Wildner * THIS SOFTWARE IS PROVIDED BY THE AUTHOR AND CONTRIBUTORS ``AS IS'' AND
15c12c399aSSascha Wildner * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
16c12c399aSSascha Wildner * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
17c12c399aSSascha Wildner * ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE
18c12c399aSSascha Wildner * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
19c12c399aSSascha Wildner * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
20c12c399aSSascha Wildner * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
21c12c399aSSascha Wildner * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
22c12c399aSSascha Wildner * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
23c12c399aSSascha Wildner * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
24c12c399aSSascha Wildner * SUCH DAMAGE.
25c12c399aSSascha Wildner *
26c12c399aSSascha Wildner * LSI MPT-Fusion Host Adapter FreeBSD
27c12c399aSSascha Wildner *
28c12c399aSSascha Wildner * $FreeBSD: src/sys/dev/mps/mps_sas.h,v 1.1 2012/01/26 18:17:21 ken Exp $
29c12c399aSSascha Wildner */
30c12c399aSSascha Wildner
31c12c399aSSascha Wildner struct mps_fw_event_work;
32c12c399aSSascha Wildner
33c12c399aSSascha Wildner struct mpssas_lun {
34c12c399aSSascha Wildner SLIST_ENTRY(mpssas_lun) lun_link;
35c12c399aSSascha Wildner lun_id_t lun_id;
36c12c399aSSascha Wildner uint8_t eedp_formatted;
37c12c399aSSascha Wildner uint32_t eedp_block_size;
38c12c399aSSascha Wildner };
39c12c399aSSascha Wildner
40c12c399aSSascha Wildner struct mpssas_target {
41c12c399aSSascha Wildner uint16_t handle;
42c12c399aSSascha Wildner uint8_t linkrate;
43c12c399aSSascha Wildner uint64_t devname;
44c12c399aSSascha Wildner uint32_t devinfo;
45c12c399aSSascha Wildner uint16_t encl_handle;
46c12c399aSSascha Wildner uint16_t encl_slot;
47c12c399aSSascha Wildner uint8_t flags;
48c12c399aSSascha Wildner #define MPSSAS_TARGET_INABORT (1 << 0)
49c12c399aSSascha Wildner #define MPSSAS_TARGET_INRESET (1 << 1)
50c12c399aSSascha Wildner #define MPSSAS_TARGET_INDIAGRESET (1 << 2)
51c12c399aSSascha Wildner #define MPSSAS_TARGET_INREMOVAL (1 << 3)
52*43f7c553SMatthew Dillon #define MPS_TARGET_FLAGS_RAID_COMPONENT (1 << 4)
53*43f7c553SMatthew Dillon #define MPS_TARGET_FLAGS_VOLUME (1 << 5)
54c12c399aSSascha Wildner #define MPSSAS_TARGET_INRECOVERY (MPSSAS_TARGET_INABORT | \
55c12c399aSSascha Wildner MPSSAS_TARGET_INRESET | MPSSAS_TARGET_INCHIPRESET)
56c12c399aSSascha Wildner #define MPSSAS_TARGET_ADD (1 << 29)
57c12c399aSSascha Wildner #define MPSSAS_TARGET_REMOVE (1 << 30)
58c12c399aSSascha Wildner uint16_t tid;
59c12c399aSSascha Wildner SLIST_HEAD(, mpssas_lun) luns;
60c12c399aSSascha Wildner TAILQ_HEAD(, mps_command) commands;
61c12c399aSSascha Wildner struct mps_command *tm;
62c12c399aSSascha Wildner TAILQ_HEAD(, mps_command) timedout_commands;
63c12c399aSSascha Wildner uint16_t exp_dev_handle;
64c12c399aSSascha Wildner uint16_t phy_num;
65c12c399aSSascha Wildner uint64_t sasaddr;
66c12c399aSSascha Wildner uint16_t parent_handle;
67c12c399aSSascha Wildner uint64_t parent_sasaddr;
68c12c399aSSascha Wildner uint32_t parent_devinfo;
69c12c399aSSascha Wildner struct sysctl_ctx_list sysctl_ctx;
70c12c399aSSascha Wildner struct sysctl_oid *sysctl_tree;
71c12c399aSSascha Wildner TAILQ_ENTRY(mpssas_target) sysctl_link;
72c12c399aSSascha Wildner uint64_t issued;
73c12c399aSSascha Wildner uint64_t completed;
74c12c399aSSascha Wildner unsigned int outstanding;
75c12c399aSSascha Wildner unsigned int timeouts;
76c12c399aSSascha Wildner unsigned int aborts;
77c12c399aSSascha Wildner unsigned int logical_unit_resets;
78c12c399aSSascha Wildner unsigned int target_resets;
79c12c399aSSascha Wildner };
80c12c399aSSascha Wildner
81c12c399aSSascha Wildner struct mpssas_softc {
82c12c399aSSascha Wildner struct mps_softc *sc;
83c12c399aSSascha Wildner u_int flags;
84c12c399aSSascha Wildner #define MPSSAS_IN_DISCOVERY (1 << 0)
85c12c399aSSascha Wildner #define MPSSAS_IN_STARTUP (1 << 1)
86c12c399aSSascha Wildner #define MPSSAS_DISCOVERY_TIMEOUT_PENDING (1 << 2)
87c12c399aSSascha Wildner #define MPSSAS_QUEUE_FROZEN (1 << 3)
88c12c399aSSascha Wildner #define MPSSAS_SHUTDOWN (1 << 4)
89c12c399aSSascha Wildner #define MPSSAS_SCANTHREAD (1 << 5)
90c12c399aSSascha Wildner struct mpssas_target *targets;
91c12c399aSSascha Wildner struct cam_devq *devq;
92c12c399aSSascha Wildner struct cam_sim *sim;
93c12c399aSSascha Wildner struct cam_path *path;
94c12c399aSSascha Wildner struct intr_config_hook sas_ich;
95c12c399aSSascha Wildner struct callout discovery_callout;
96c12c399aSSascha Wildner u_int discovery_timeouts;
97c12c399aSSascha Wildner struct mps_event_handle *mpssas_eh;
98c12c399aSSascha Wildner
99c12c399aSSascha Wildner u_int startup_refcount;
100c12c399aSSascha Wildner u_int tm_count;
101c12c399aSSascha Wildner struct proc *sysctl_proc;
102c12c399aSSascha Wildner
103c12c399aSSascha Wildner TAILQ_HEAD(, ccb_hdr) ccb_scanq;
104c12c399aSSascha Wildner struct thread *rescan_thread;
105c12c399aSSascha Wildner
106c12c399aSSascha Wildner struct taskqueue *ev_tq;
107c12c399aSSascha Wildner struct task ev_task;
108c12c399aSSascha Wildner TAILQ_HEAD(, mps_fw_event_work) ev_queue;
109c12c399aSSascha Wildner };
110c12c399aSSascha Wildner
111c12c399aSSascha Wildner /*
112c12c399aSSascha Wildner * Abstracted so that the driver can be backwards and forwards compatible
113c12c399aSSascha Wildner * with future versions of CAM that will provide this functionality.
114c12c399aSSascha Wildner */
115c12c399aSSascha Wildner #define MPS_SET_LUN(lun, ccblun) \
116c12c399aSSascha Wildner mpssas_set_lun(lun, ccblun)
117c12c399aSSascha Wildner
118c12c399aSSascha Wildner static __inline int
mpssas_set_lun(uint8_t * lun,u_int ccblun)119c12c399aSSascha Wildner mpssas_set_lun(uint8_t *lun, u_int ccblun)
120c12c399aSSascha Wildner {
121c12c399aSSascha Wildner uint64_t *newlun;
122c12c399aSSascha Wildner
123c12c399aSSascha Wildner newlun = (uint64_t *)lun;
124c12c399aSSascha Wildner *newlun = 0;
125c12c399aSSascha Wildner if (ccblun <= 0xff) {
126c12c399aSSascha Wildner /* Peripheral device address method, LUN is 0 to 255 */
127c12c399aSSascha Wildner lun[1] = ccblun;
128c12c399aSSascha Wildner } else if (ccblun <= 0x3fff) {
129c12c399aSSascha Wildner /* Flat space address method, LUN is <= 16383 */
130c12c399aSSascha Wildner scsi_ulto2b(ccblun, lun);
131c12c399aSSascha Wildner lun[0] |= 0x40;
132c12c399aSSascha Wildner } else if (ccblun <= 0xffffff) {
133c12c399aSSascha Wildner /* Extended flat space address method, LUN is <= 16777215 */
134c12c399aSSascha Wildner scsi_ulto3b(ccblun, &lun[1]);
135c12c399aSSascha Wildner /* Extended Flat space address method */
136c12c399aSSascha Wildner lun[0] = 0xc0;
137c12c399aSSascha Wildner /* Length = 1, i.e. LUN is 3 bytes long */
138c12c399aSSascha Wildner lun[0] |= 0x10;
139c12c399aSSascha Wildner /* Extended Address Method */
140c12c399aSSascha Wildner lun[0] |= 0x02;
141c12c399aSSascha Wildner } else {
142c12c399aSSascha Wildner return (EINVAL);
143c12c399aSSascha Wildner }
144c12c399aSSascha Wildner
145c12c399aSSascha Wildner return (0);
146c12c399aSSascha Wildner }
147c12c399aSSascha Wildner
148c12c399aSSascha Wildner #define MPS_SET_SINGLE_LUN(req, lun) \
149c12c399aSSascha Wildner do { \
150c12c399aSSascha Wildner bzero((req)->LUN, 8); \
151c12c399aSSascha Wildner (req)->LUN[1] = lun; \
152c12c399aSSascha Wildner } while(0)
153c12c399aSSascha Wildner
154c12c399aSSascha Wildner void mpssas_rescan_target(struct mps_softc *sc, struct mpssas_target *targ);
155c12c399aSSascha Wildner void mpssas_discovery_end(struct mpssas_softc *sassc);
156c12c399aSSascha Wildner void mpssas_startup_increment(struct mpssas_softc *sassc);
157c12c399aSSascha Wildner void mpssas_startup_decrement(struct mpssas_softc *sassc);
158c12c399aSSascha Wildner
159c12c399aSSascha Wildner struct mps_command * mpssas_alloc_tm(struct mps_softc *sc);
160c12c399aSSascha Wildner void mpssas_free_tm(struct mps_softc *sc, struct mps_command *tm);
161c12c399aSSascha Wildner void mpssas_firmware_event_work(void *arg, int pending);
162