1*71ed46bdSbouyer /* $NetBSD: mfivar.h,v 1.20 2012/09/19 21:24:29 bouyer Exp $ */ 2462dc620Sbouyer /* $OpenBSD: mfivar.h,v 1.28 2006/08/31 18:18:46 marco Exp $ */ 3462dc620Sbouyer /* 4462dc620Sbouyer * Copyright (c) 2006 Marco Peereboom <marco@peereboom.us> 5462dc620Sbouyer * 6462dc620Sbouyer * Permission to use, copy, modify, and distribute this software for any 7462dc620Sbouyer * purpose with or without fee is hereby granted, provided that the above 8462dc620Sbouyer * copyright notice and this permission notice appear in all copies. 9462dc620Sbouyer * 10462dc620Sbouyer * THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES 11462dc620Sbouyer * WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF 12462dc620Sbouyer * MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR 13462dc620Sbouyer * ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES 14462dc620Sbouyer * WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN 15462dc620Sbouyer * ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF 16462dc620Sbouyer * OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE. 17462dc620Sbouyer */ 18462dc620Sbouyer 19982bad25Sbouyer #include <dev/sysmon/sysmonvar.h> 20982bad25Sbouyer #include <sys/envsys.h> 21c3ae851bSbouyer #include <sys/workqueue.h> 22982bad25Sbouyer 23ebab3c38Sdyoung #define DEVNAME(_s) (device_xname((_s)->sc_dev)) 24462dc620Sbouyer 2554880c4fSxtraeme /* #define MFI_DEBUG */ 26462dc620Sbouyer #ifdef MFI_DEBUG 27462dc620Sbouyer extern uint32_t mfi_debug; 28462dc620Sbouyer #define DPRINTF(x...) do { if (mfi_debug) printf(x); } while(0) 29462dc620Sbouyer #define DNPRINTF(n,x...) do { if (mfi_debug & n) printf(x); } while(0) 30462dc620Sbouyer #define MFI_D_CMD 0x0001 31462dc620Sbouyer #define MFI_D_INTR 0x0002 32462dc620Sbouyer #define MFI_D_MISC 0x0004 33462dc620Sbouyer #define MFI_D_DMA 0x0008 34462dc620Sbouyer #define MFI_D_IOCTL 0x0010 35462dc620Sbouyer #define MFI_D_RW 0x0020 36462dc620Sbouyer #define MFI_D_MEM 0x0040 37462dc620Sbouyer #define MFI_D_CCB 0x0080 38c3ae851bSbouyer #define MFI_D_SYNC 0x0100 39462dc620Sbouyer #else 40cb3e0547Sgmcgarry #define DPRINTF(x, ...) 41cb3e0547Sgmcgarry #define DNPRINTF(n, x, ...) 42462dc620Sbouyer #endif 43462dc620Sbouyer 44462dc620Sbouyer struct mfi_mem { 45462dc620Sbouyer bus_dmamap_t am_map; 46462dc620Sbouyer bus_dma_segment_t am_seg; 47462dc620Sbouyer size_t am_size; 4853524e44Schristos void * am_kva; 49462dc620Sbouyer }; 50462dc620Sbouyer 51462dc620Sbouyer #define MFIMEM_MAP(_am) ((_am)->am_map) 52462dc620Sbouyer #define MFIMEM_DVA(_am) ((_am)->am_map->dm_segs[0].ds_addr) 53462dc620Sbouyer #define MFIMEM_KVA(_am) ((void *)(_am)->am_kva) 54462dc620Sbouyer 55462dc620Sbouyer struct mfi_prod_cons { 56462dc620Sbouyer uint32_t mpc_producer; 57462dc620Sbouyer uint32_t mpc_consumer; 58462dc620Sbouyer uint32_t mpc_reply_q[1]; /* compensate for 1 extra reply per spec */ 59462dc620Sbouyer }; 60462dc620Sbouyer 61462dc620Sbouyer struct mfi_ccb { 62462dc620Sbouyer struct mfi_softc *ccb_sc; 63462dc620Sbouyer 64462dc620Sbouyer union mfi_frame *ccb_frame; 65462dc620Sbouyer paddr_t ccb_pframe; 66462dc620Sbouyer uint32_t ccb_frame_size; 67462dc620Sbouyer uint32_t ccb_extra_frames; 68462dc620Sbouyer 69462dc620Sbouyer struct mfi_sense *ccb_sense; 70462dc620Sbouyer paddr_t ccb_psense; 71462dc620Sbouyer 72462dc620Sbouyer bus_dmamap_t ccb_dmamap; 73462dc620Sbouyer 74462dc620Sbouyer union mfi_sgl *ccb_sgl; 75462dc620Sbouyer 76462dc620Sbouyer /* data for sgl */ 77462dc620Sbouyer void *ccb_data; 78462dc620Sbouyer uint32_t ccb_len; 79462dc620Sbouyer 80462dc620Sbouyer uint32_t ccb_direction; 81462dc620Sbouyer #define MFI_DATA_NONE 0 82462dc620Sbouyer #define MFI_DATA_IN 1 83462dc620Sbouyer #define MFI_DATA_OUT 2 84462dc620Sbouyer 85c3ae851bSbouyer /* 86c3ae851bSbouyer * memory structure used by ThunderBolt controller. 87c3ae851bSbouyer * The legacy structures above are used too, depending on 88c3ae851bSbouyer * the command type. 89c3ae851bSbouyer */ 90c3ae851bSbouyer union mfi_mpi2_request_descriptor ccb_tb_request_desc; 91c3ae851bSbouyer struct mfi_mpi2_request_raid_scsi_io *ccb_tb_io_request; 92c3ae851bSbouyer bus_addr_t ccb_tb_pio_request; 93c3ae851bSbouyer mpi2_sge_io_union *ccb_tb_sg_frame; 94c3ae851bSbouyer bus_addr_t ccb_tb_psg_frame; 95c3ae851bSbouyer 96462dc620Sbouyer struct scsipi_xfer *ccb_xs; 97462dc620Sbouyer 98462dc620Sbouyer void (*ccb_done)(struct mfi_ccb *); 99462dc620Sbouyer 100462dc620Sbouyer volatile enum { 101462dc620Sbouyer MFI_CCB_FREE, 102462dc620Sbouyer MFI_CCB_READY, 103c3ae851bSbouyer MFI_CCB_RUNNING, 104462dc620Sbouyer MFI_CCB_DONE 105462dc620Sbouyer } ccb_state; 106462dc620Sbouyer uint32_t ccb_flags; 107462dc620Sbouyer #define MFI_CCB_F_ERR (1<<0) 108c3ae851bSbouyer #define MFI_CCB_F_TBOLT (1<<1) /* Thunderbolt descriptor */ 109c3ae851bSbouyer #define MFI_CCB_F_TBOLT_IO (1<<2) /* Thunderbolt I/O descriptor */ 110462dc620Sbouyer TAILQ_ENTRY(mfi_ccb) ccb_link; 111462dc620Sbouyer }; 112462dc620Sbouyer 113462dc620Sbouyer TAILQ_HEAD(mfi_ccb_list, mfi_ccb); 114462dc620Sbouyer 11554880c4fSxtraeme enum mfi_iop { 11654880c4fSxtraeme MFI_IOP_XSCALE, 11738a7bbf8Smsaitoh MFI_IOP_PPC, 118d81c9f45Ssborrill MFI_IOP_GEN2, 119c3ae851bSbouyer MFI_IOP_SKINNY, 120c3ae851bSbouyer MFI_IOP_TBOLT 12154880c4fSxtraeme }; 12254880c4fSxtraeme 12354880c4fSxtraeme struct mfi_iop_ops { 12454880c4fSxtraeme uint32_t (*mio_fw_state)(struct mfi_softc *); 12578500bdfSdyoung void (*mio_intr_dis)(struct mfi_softc *); 12654880c4fSxtraeme void (*mio_intr_ena)(struct mfi_softc *); 12754880c4fSxtraeme int (*mio_intr)(struct mfi_softc *); 128c3ae851bSbouyer void (*mio_post)(struct mfi_softc *, 129c3ae851bSbouyer struct mfi_ccb *); 130c3ae851bSbouyer int (*mio_ld_io)(struct mfi_ccb *, 131c3ae851bSbouyer struct scsipi_xfer *, uint64_t, uint32_t); 13254880c4fSxtraeme }; 13354880c4fSxtraeme 134462dc620Sbouyer struct mfi_softc { 135ebab3c38Sdyoung device_t sc_dev; 136462dc620Sbouyer struct scsipi_channel sc_chan; 137462dc620Sbouyer struct scsipi_adapter sc_adapt; 138462dc620Sbouyer 13954880c4fSxtraeme const struct mfi_iop_ops *sc_iop; 140fccabacaSbouyer enum mfi_iop sc_ioptype; 14154880c4fSxtraeme 142462dc620Sbouyer void *sc_ih; 143462dc620Sbouyer 144596e3d87Sbouyer bool sc_64bit_dma; 145462dc620Sbouyer 146462dc620Sbouyer bus_space_tag_t sc_iot; 147462dc620Sbouyer bus_space_handle_t sc_ioh; 14878500bdfSdyoung bus_size_t sc_size; 149c3ae851bSbouyer bus_dma_tag_t sc_dmat; 150c3ae851bSbouyer bus_dma_tag_t sc_datadmat; 151462dc620Sbouyer 152462dc620Sbouyer /* save some useful information for logical drives that is missing 153462dc620Sbouyer * in sc_ld_list 154462dc620Sbouyer */ 155462dc620Sbouyer struct { 156462dc620Sbouyer uint32_t ld_present; 157462dc620Sbouyer char ld_dev[16]; /* device name sd? */ 158462dc620Sbouyer } sc_ld[MFI_MAX_LD]; 159462dc620Sbouyer 160462dc620Sbouyer /* firmware determined max, totals and other information*/ 161462dc620Sbouyer uint32_t sc_max_cmds; 162462dc620Sbouyer uint32_t sc_max_sgl; 163596e3d87Sbouyer uint32_t sc_sgl_size; 164462dc620Sbouyer uint32_t sc_max_ld; 165462dc620Sbouyer uint32_t sc_ld_cnt; 166462dc620Sbouyer /* XXX these struct should be local to mgmt function */ 167462dc620Sbouyer struct mfi_ctrl_info sc_info; 168462dc620Sbouyer struct mfi_ld_list sc_ld_list; 169462dc620Sbouyer struct mfi_ld_details sc_ld_details; 170462dc620Sbouyer 171462dc620Sbouyer /* all commands */ 172462dc620Sbouyer struct mfi_ccb *sc_ccb; 173462dc620Sbouyer 174462dc620Sbouyer /* producer/consumer pointers and reply queue */ 175462dc620Sbouyer struct mfi_mem *sc_pcq; 176462dc620Sbouyer 177462dc620Sbouyer /* frame memory */ 178462dc620Sbouyer struct mfi_mem *sc_frames; 179462dc620Sbouyer uint32_t sc_frames_size; 180462dc620Sbouyer 181c3ae851bSbouyer /* thunderbolt memory */ 182c3ae851bSbouyer struct mfi_mem *sc_tbolt_reqmsgpool; 183c3ae851bSbouyer 184c3ae851bSbouyer struct mfi_mem *sc_tbolt_ioc_init; 185c3ae851bSbouyer /* Virtual address of reply Frame Pool, part of sc_tbolt_reqmsgpool */ 186c3ae851bSbouyer int sc_reply_pool_size; 187c3ae851bSbouyer struct mfi_mpi2_reply_header* sc_reply_frame_pool; 188c3ae851bSbouyer bus_addr_t sc_reply_frame_busaddr; 189c3ae851bSbouyer uint8_t *sc_reply_pool_limit; 190c3ae851bSbouyer bus_addr_t sc_sg_frame_busaddr; 191c3ae851bSbouyer int sc_last_reply_idx; 192c3ae851bSbouyer 193c3ae851bSbouyer struct mfi_mem *sc_tbolt_verbuf; 194c3ae851bSbouyer 195c3ae851bSbouyer bool sc_MFA_enabled; 196c3ae851bSbouyer 197c3ae851bSbouyer /* workqueue for the ld sync command */ 198c3ae851bSbouyer struct workqueue *sc_ldsync_wq; 199c3ae851bSbouyer struct work sc_ldsync_wk; 200c3ae851bSbouyer struct mfi_ccb *sc_ldsync_ccb; 201c3ae851bSbouyer 202462dc620Sbouyer /* sense memory */ 203462dc620Sbouyer struct mfi_mem *sc_sense; 204462dc620Sbouyer 205462dc620Sbouyer struct mfi_ccb_list sc_ccb_freeq; 206462dc620Sbouyer 20731962fc6Sxtraeme struct sysmon_envsys *sc_sme; 20831962fc6Sxtraeme envsys_data_t *sc_sensor; 209ec936865Sbouyer bool sc_bbuok; 210ec936865Sbouyer bool sc_running; 211982bad25Sbouyer 212bbc238f2Sdyoung device_t sc_child; 213*71ed46bdSbouyer 214*71ed46bdSbouyer /* for ioctl interface */ 215*71ed46bdSbouyer bool sc_opened; 216462dc620Sbouyer }; 217462dc620Sbouyer 218bbc238f2Sdyoung int mfi_rescan(device_t, const char *, const int *); 219bbc238f2Sdyoung void mfi_childdetached(device_t, device_t); 22078500bdfSdyoung int mfi_attach(struct mfi_softc *, enum mfi_iop); 22178500bdfSdyoung int mfi_detach(struct mfi_softc *, int); 222462dc620Sbouyer int mfi_intr(void *); 223c3ae851bSbouyer int mfi_tbolt_intrh(void *); 224