1 /* 2 * SPDX-License-Identifier: BSD-2-Clause 3 * 4 * Copyright (c) 2020-2023, Broadcom Inc. All rights reserved. 5 * Support: <fbsd-storage-driver.pdl@broadcom.com> 6 * 7 * Authors: Sumit Saxena <sumit.saxena@broadcom.com> 8 * Chandrakanth Patil <chandrakanth.patil@broadcom.com> 9 * 10 * Redistribution and use in source and binary forms, with or without 11 * modification, are permitted provided that the following conditions are 12 * met: 13 * 14 * 1. Redistributions of source code must retain the above copyright notice, 15 * this list of conditions and the following disclaimer. 16 * 2. Redistributions in binary form must reproduce the above copyright notice, 17 * this list of conditions and the following disclaimer in the documentation and/or other 18 * materials provided with the distribution. 19 * 3. Neither the name of the Broadcom Inc. nor the names of its contributors 20 * may be used to endorse or promote products derived from this software without 21 * specific prior written permission. 22 * 23 * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" 24 * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE 25 * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE 26 * ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE 27 * LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR 28 * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF 29 * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS 30 * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN 31 * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) 32 * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE 33 * POSSIBILITY OF SUCH DAMAGE. 34 * 35 * The views and conclusions contained in the software and documentation are 36 * those of the authors and should not be interpreted as representing 37 * official policies,either expressed or implied, of the FreeBSD Project. 38 * 39 * Mail to: Broadcom Inc 1320 Ridder Park Dr, San Jose, CA 95131 40 * 41 * Broadcom Inc. (Broadcom) MPI3MR Adapter FreeBSD 42 */ 43 #include "mpi3mr.h" 44 45 struct mpi3mr_fw_event_work; 46 47 struct mpi3mr_throttle_group_info { 48 U8 io_divert; 49 U16 fw_qd; 50 U16 modified_qd; 51 U16 id; 52 U32 high; 53 U32 low; 54 mpi3mr_atomic_t pend_large_data_sz; 55 }; 56 57 struct mpi3mr_tgt_dev_sassata { 58 U64 sas_address; 59 U16 dev_info; 60 }; 61 62 struct mpi3mr_tgt_dev_pcie { 63 U32 mdts; 64 U16 capb; 65 U8 pgsz; 66 U8 abort_to; 67 U8 reset_to; 68 U16 dev_info; 69 }; 70 71 struct mpi3mr_tgt_dev_volume { 72 U8 state; 73 U16 tg_id; 74 U32 tg_high; 75 U32 tg_low; 76 struct mpi3mr_throttle_group_info *tg; 77 }; 78 79 typedef union _mpi3mr_form_spec_inf { 80 struct mpi3mr_tgt_dev_sassata sassata_inf; 81 struct mpi3mr_tgt_dev_pcie pcie_inf; 82 struct mpi3mr_tgt_dev_volume vol_inf; 83 } mpi3mr_form_spec_inf; 84 85 struct mpi3mr_target { 86 uint16_t dev_handle; 87 uint16_t slot; 88 uint16_t per_id; 89 uint8_t dev_type; 90 volatile uint8_t is_hidden; 91 volatile uint8_t dev_removed; 92 U8 dev_removedelay; 93 mpi3mr_atomic_t block_io; 94 uint8_t exposed_to_os; 95 uint16_t qdepth; 96 uint64_t wwid; 97 mpi3mr_form_spec_inf dev_spec; 98 uint16_t tid; 99 uint16_t exp_dev_handle; 100 uint16_t phy_num; 101 uint64_t sasaddr; 102 uint16_t parent_handle; 103 uint64_t parent_sasaddr; 104 uint32_t parent_devinfo; 105 mpi3mr_atomic_t outstanding; 106 uint8_t scsi_req_desc_type; 107 TAILQ_ENTRY(mpi3mr_target) tgt_next; 108 uint16_t handle; 109 uint8_t link_rate; 110 uint8_t encl_level_valid; 111 uint8_t encl_level; 112 char connector_name[4]; 113 uint64_t devname; 114 uint32_t devinfo; 115 uint16_t encl_handle; 116 uint16_t encl_slot; 117 uint8_t flags; 118 #define MPI3MRSAS_TARGET_INREMOVAL (1 << 3) 119 uint8_t io_throttle_enabled; 120 uint8_t io_divert; 121 struct mpi3mr_throttle_group_info *throttle_group; 122 uint64_t q_depth; 123 enum mpi3mr_target_state state; 124 }; 125 126 struct mpi3mr_cam_softc { 127 struct mpi3mr_softc *sc; 128 u_int flags; 129 #define MPI3MRSAS_IN_DISCOVERY (1 << 0) 130 #define MPI3MRSAS_IN_STARTUP (1 << 1) 131 #define MPI3MRSAS_DISCOVERY_TIMEOUT_PENDING (1 << 2) 132 #define MPI3MRSAS_QUEUE_FROZEN (1 << 3) 133 #define MPI3MRSAS_SHUTDOWN (1 << 4) 134 u_int maxtargets; 135 struct cam_devq *devq; 136 struct cam_sim *sim; 137 struct cam_path *path; 138 struct intr_config_hook sas_ich; 139 struct callout discovery_callout; 140 struct mpi3mr_event_handle *mpi3mr_eh; 141 142 u_int startup_refcount; 143 struct proc *sysctl_proc; 144 struct taskqueue *ev_tq; 145 struct task ev_task; 146 TAILQ_HEAD(, mpi3mr_fw_event_work) ev_queue; 147 TAILQ_HEAD(, mpi3mr_target) tgt_list; 148 }; 149 150 MALLOC_DECLARE(M_MPI3MRSAS); 151 152 static __inline void 153 mpi3mr_set_ccbstatus(union ccb *ccb, int status) 154 { 155 ccb->ccb_h.status &= ~CAM_STATUS_MASK; 156 ccb->ccb_h.status |= status; 157 } 158 159 static __inline int 160 mpi3mr_get_ccbstatus(union ccb *ccb) 161 { 162 return (ccb->ccb_h.status & CAM_STATUS_MASK); 163 } 164 165 static __inline void mpi3mr_print_cdb(union ccb *ccb) 166 { 167 struct ccb_scsiio *csio; 168 struct mpi3mr_cam_softc *cam_sc; 169 struct cam_sim *sim; 170 int i; 171 172 sim = xpt_path_sim(ccb->ccb_h.path); 173 cam_sc = cam_sim_softc(sim); 174 175 csio = &ccb->csio; 176 177 mpi3mr_dprint(cam_sc->sc, MPI3MR_INFO, "tgtID: %d CDB: ", csio->ccb_h.target_id); 178 for (i = 0; i < csio->cdb_len; i++) 179 printf("%x ", csio->cdb_io.cdb_bytes[i]); 180 181 printf("\n"); 182 } 183 184 void mpi3mr_rescan_target(struct mpi3mr_softc *sc, struct mpi3mr_target *targ); 185 void mpi3mr_discovery_end(struct mpi3mr_cam_softc *sassc); 186 void mpi3mr_prepare_for_tm(struct mpi3mr_softc *sc, struct mpi3mr_cmd *tm, 187 struct mpi3mr_target *target, lun_id_t lun_id); 188 void mpi3mr_startup_increment(struct mpi3mr_cam_softc *sassc); 189 void mpi3mr_startup_decrement(struct mpi3mr_cam_softc *sassc); 190 191 void mpi3mr_firmware_event_work(void *arg, int pending); 192 int mpi3mr_check_id(struct mpi3mr_cam_softc *sassc, int id); 193 int 194 mpi3mr_cam_attach(struct mpi3mr_softc *sc); 195 int 196 mpi3mr_cam_detach(struct mpi3mr_softc *sc); 197 void 198 mpi3mr_evt_handler(struct mpi3mr_softc *sc, uintptr_t data, 199 MPI3_EVENT_NOTIFICATION_REPLY *event); 200