1265236Sken/*- 2265236Sken * Copyright (c) 2011-2014 LSI Corp. 3265236Sken * All rights reserved. 4265236Sken * 5265236Sken * Redistribution and use in source and binary forms, with or without 6265236Sken * modification, are permitted provided that the following conditions 7265236Sken * are met: 8265236Sken * 1. Redistributions of source code must retain the above copyright 9265236Sken * notice, this list of conditions and the following disclaimer. 10265236Sken * 2. Redistributions in binary form must reproduce the above copyright 11265236Sken * notice, this list of conditions and the following disclaimer in the 12265236Sken * documentation and/or other materials provided with the distribution. 13265236Sken * 14265236Sken * THIS SOFTWARE IS PROVIDED BY THE AUTHOR AND CONTRIBUTORS ``AS IS'' AND 15265236Sken * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE 16265236Sken * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE 17265236Sken * ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE 18265236Sken * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL 19265236Sken * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS 20265236Sken * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) 21265236Sken * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT 22265236Sken * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY 23265236Sken * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF 24265236Sken * SUCH DAMAGE. 25265236Sken * 26265236Sken * LSI MPT-Fusion Host Adapter FreeBSD 27265236Sken * 28265236Sken * $FreeBSD$ 29265236Sken */ 30265236Sken 31265236Skenstruct mpr_fw_event_work; 32265236Sken 33265236Skenstruct mprsas_lun { 34265236Sken SLIST_ENTRY(mprsas_lun) lun_link; 35265236Sken lun_id_t lun_id; 36265236Sken uint8_t eedp_formatted; 37265236Sken uint32_t eedp_block_size; 38265236Sken uint8_t stop_at_shutdown; 39265236Sken}; 40265236Sken 41265236Skenstruct mprsas_target { 42265236Sken uint16_t handle; 43265236Sken uint8_t linkrate; 44265236Sken uint8_t encl_level_valid; 45265236Sken uint8_t encl_level; 46265236Sken char connector_name[4]; 47265236Sken uint64_t devname; 48265236Sken uint32_t devinfo; 49265236Sken uint16_t encl_handle; 50265236Sken uint16_t encl_slot; 51265236Sken uint8_t flags; 52265236Sken#define MPRSAS_TARGET_INABORT (1 << 0) 53265236Sken#define MPRSAS_TARGET_INRESET (1 << 1) 54265236Sken#define MPRSAS_TARGET_INDIAGRESET (1 << 2) 55265236Sken#define MPRSAS_TARGET_INREMOVAL (1 << 3) 56265236Sken#define MPR_TARGET_FLAGS_RAID_COMPONENT (1 << 4) 57265236Sken#define MPR_TARGET_FLAGS_VOLUME (1 << 5) 58265236Sken#define MPRSAS_TARGET_INRECOVERY (MPRSAS_TARGET_INABORT | \ 59265236Sken MPRSAS_TARGET_INRESET | MPRSAS_TARGET_INCHIPRESET) 60265236Sken 61265236Sken#define MPRSAS_TARGET_ADD (1 << 29) 62265236Sken#define MPRSAS_TARGET_REMOVE (1 << 30) 63265236Sken uint16_t tid; 64265236Sken SLIST_HEAD(, mprsas_lun) luns; 65265236Sken TAILQ_HEAD(, mpr_command) commands; 66265236Sken struct mpr_command *tm; 67265236Sken TAILQ_HEAD(, mpr_command) timedout_commands; 68265236Sken uint16_t exp_dev_handle; 69265236Sken uint16_t phy_num; 70265236Sken uint64_t sasaddr; 71265236Sken uint16_t parent_handle; 72265236Sken uint64_t parent_sasaddr; 73265236Sken uint32_t parent_devinfo; 74265236Sken struct sysctl_ctx_list sysctl_ctx; 75265236Sken struct sysctl_oid *sysctl_tree; 76265236Sken TAILQ_ENTRY(mprsas_target) sysctl_link; 77265236Sken uint64_t issued; 78265236Sken uint64_t completed; 79265236Sken unsigned int outstanding; 80265236Sken unsigned int timeouts; 81265236Sken unsigned int aborts; 82265236Sken unsigned int logical_unit_resets; 83265236Sken unsigned int target_resets; 84265236Sken uint8_t scsi_req_desc_type; 85265236Sken}; 86265236Sken 87265236Skenstruct mprsas_softc { 88265236Sken struct mpr_softc *sc; 89265236Sken u_int flags; 90265236Sken#define MPRSAS_IN_DISCOVERY (1 << 0) 91265236Sken#define MPRSAS_IN_STARTUP (1 << 1) 92265236Sken#define MPRSAS_DISCOVERY_TIMEOUT_PENDING (1 << 2) 93265236Sken#define MPRSAS_QUEUE_FROZEN (1 << 3) 94265236Sken#define MPRSAS_SHUTDOWN (1 << 4) 95265236Sken#define MPRSAS_SCANTHREAD (1 << 5) 96265236Sken u_int maxtargets; 97265236Sken struct mprsas_target *targets; 98265236Sken struct cam_devq *devq; 99265236Sken struct cam_sim *sim; 100265236Sken struct cam_path *path; 101265236Sken struct intr_config_hook sas_ich; 102265236Sken struct callout discovery_callout; 103265236Sken struct mpr_event_handle *mprsas_eh; 104265236Sken 105265236Sken u_int startup_refcount; 106265236Sken u_int tm_count; 107265236Sken struct proc *sysctl_proc; 108265236Sken 109265236Sken struct taskqueue *ev_tq; 110265236Sken struct task ev_task; 111265236Sken TAILQ_HEAD(, mpr_fw_event_work) ev_queue; 112265236Sken}; 113265236Sken 114265236SkenMALLOC_DECLARE(M_MPRSAS); 115265236Sken 116265236Sken/* 117265236Sken * Abstracted so that the driver can be backwards and forwards compatible 118265236Sken * with future versions of CAM that will provide this functionality. 119265236Sken */ 120265236Sken#define MPR_SET_LUN(lun, ccblun) \ 121265236Sken mprsas_set_lun(lun, ccblun) 122265236Sken 123265236Skenstatic __inline int 124265236Skenmprsas_set_lun(uint8_t *lun, u_int ccblun) 125265236Sken{ 126265236Sken uint64_t *newlun; 127265236Sken 128265236Sken newlun = (uint64_t *)lun; 129265236Sken *newlun = 0; 130265236Sken if (ccblun <= 0xff) { 131265236Sken /* Peripheral device address method, LUN is 0 to 255 */ 132265236Sken lun[1] = ccblun; 133265236Sken } else if (ccblun <= 0x3fff) { 134265236Sken /* Flat space address method, LUN is <= 16383 */ 135265236Sken scsi_ulto2b(ccblun, lun); 136265236Sken lun[0] |= 0x40; 137265236Sken } else if (ccblun <= 0xffffff) { 138265236Sken /* Extended flat space address method, LUN is <= 16777215 */ 139265236Sken scsi_ulto3b(ccblun, &lun[1]); 140265236Sken /* Extended Flat space address method */ 141265236Sken lun[0] = 0xc0; 142265236Sken /* Length = 1, i.e. LUN is 3 bytes long */ 143265236Sken lun[0] |= 0x10; 144265236Sken /* Extended Address Method */ 145265236Sken lun[0] |= 0x02; 146265236Sken } else { 147265236Sken return (EINVAL); 148265236Sken } 149265236Sken 150265236Sken return (0); 151265236Sken} 152265236Sken 153265236Sken#define MPR_SET_SINGLE_LUN(req, lun) \ 154265236Skendo { \ 155265236Sken bzero((req)->LUN, 8); \ 156265236Sken (req)->LUN[1] = lun; \ 157265236Sken} while(0) 158265236Sken 159265236Skenvoid mprsas_rescan_target(struct mpr_softc *sc, struct mprsas_target *targ); 160265236Skenvoid mprsas_discovery_end(struct mprsas_softc *sassc); 161265236Skenvoid mprsas_startup_increment(struct mprsas_softc *sassc); 162265236Skenvoid mprsas_startup_decrement(struct mprsas_softc *sassc); 163265236Skenvoid mprsas_release_simq_reinit(struct mprsas_softc *sassc); 164265236Sken 165265236Skenstruct mpr_command * mprsas_alloc_tm(struct mpr_softc *sc); 166265236Skenvoid mprsas_free_tm(struct mpr_softc *sc, struct mpr_command *tm); 167265236Skenvoid mprsas_firmware_event_work(void *arg, int pending); 168265236Skenint mprsas_check_id(struct mprsas_softc *sassc, int id); 169