| 1 | /* $NetBSD: mfivar.h,v 1.20 2012/09/19 21:24:29 bouyer Exp $ */ |
| 2 | /* $OpenBSD: mfivar.h,v 1.28 2006/08/31 18:18:46 marco Exp $ */ |
| 3 | /* |
| 4 | * Copyright (c) 2006 Marco Peereboom <marco@peereboom.us> |
| 5 | * |
| 6 | * Permission to use, copy, modify, and distribute this software for any |
| 7 | * purpose with or without fee is hereby granted, provided that the above |
| 8 | * copyright notice and this permission notice appear in all copies. |
| 9 | * |
| 10 | * THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES |
| 11 | * WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF |
| 12 | * MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR |
| 13 | * ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES |
| 14 | * WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN |
| 15 | * ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF |
| 16 | * OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE. |
| 17 | */ |
| 18 | |
| 19 | #include <dev/sysmon/sysmonvar.h> |
| 20 | #include <sys/envsys.h> |
| 21 | #include <sys/workqueue.h> |
| 22 | |
| 23 | #define DEVNAME(_s) (device_xname((_s)->sc_dev)) |
| 24 | |
| 25 | /* #define MFI_DEBUG */ |
| 26 | #ifdef MFI_DEBUG |
| 27 | extern uint32_t mfi_debug; |
| 28 | #define DPRINTF(x...) do { if (mfi_debug) printf(x); } while(0) |
| 29 | #define DNPRINTF(n,x...) do { if (mfi_debug & n) printf(x); } while(0) |
| 30 | #define MFI_D_CMD 0x0001 |
| 31 | #define MFI_D_INTR 0x0002 |
| 32 | #define MFI_D_MISC 0x0004 |
| 33 | #define MFI_D_DMA 0x0008 |
| 34 | #define MFI_D_IOCTL 0x0010 |
| 35 | #define MFI_D_RW 0x0020 |
| 36 | #define MFI_D_MEM 0x0040 |
| 37 | #define MFI_D_CCB 0x0080 |
| 38 | #define MFI_D_SYNC 0x0100 |
| 39 | #else |
| 40 | #define DPRINTF(x, ...) |
| 41 | #define DNPRINTF(n, x, ...) |
| 42 | #endif |
| 43 | |
| 44 | struct mfi_mem { |
| 45 | bus_dmamap_t am_map; |
| 46 | bus_dma_segment_t am_seg; |
| 47 | size_t am_size; |
| 48 | void * am_kva; |
| 49 | }; |
| 50 | |
| 51 | #define MFIMEM_MAP(_am) ((_am)->am_map) |
| 52 | #define MFIMEM_DVA(_am) ((_am)->am_map->dm_segs[0].ds_addr) |
| 53 | #define MFIMEM_KVA(_am) ((void *)(_am)->am_kva) |
| 54 | |
| 55 | struct mfi_prod_cons { |
| 56 | uint32_t mpc_producer; |
| 57 | uint32_t mpc_consumer; |
| 58 | uint32_t mpc_reply_q[1]; /* compensate for 1 extra reply per spec */ |
| 59 | }; |
| 60 | |
| 61 | struct mfi_ccb { |
| 62 | struct mfi_softc *ccb_sc; |
| 63 | |
| 64 | union mfi_frame *ccb_frame; |
| 65 | paddr_t ccb_pframe; |
| 66 | uint32_t ccb_frame_size; |
| 67 | uint32_t ; |
| 68 | |
| 69 | struct mfi_sense *ccb_sense; |
| 70 | paddr_t ccb_psense; |
| 71 | |
| 72 | bus_dmamap_t ccb_dmamap; |
| 73 | |
| 74 | union mfi_sgl *ccb_sgl; |
| 75 | |
| 76 | /* data for sgl */ |
| 77 | void *ccb_data; |
| 78 | uint32_t ccb_len; |
| 79 | |
| 80 | uint32_t ccb_direction; |
| 81 | #define MFI_DATA_NONE 0 |
| 82 | #define MFI_DATA_IN 1 |
| 83 | #define MFI_DATA_OUT 2 |
| 84 | |
| 85 | /* |
| 86 | * memory structure used by ThunderBolt controller. |
| 87 | * The legacy structures above are used too, depending on |
| 88 | * the command type. |
| 89 | */ |
| 90 | union mfi_mpi2_request_descriptor ccb_tb_request_desc; |
| 91 | struct mfi_mpi2_request_raid_scsi_io *ccb_tb_io_request; |
| 92 | bus_addr_t ccb_tb_pio_request; |
| 93 | mpi2_sge_io_union *ccb_tb_sg_frame; |
| 94 | bus_addr_t ccb_tb_psg_frame; |
| 95 | |
| 96 | struct scsipi_xfer *ccb_xs; |
| 97 | |
| 98 | void (*ccb_done)(struct mfi_ccb *); |
| 99 | |
| 100 | volatile enum { |
| 101 | MFI_CCB_FREE, |
| 102 | MFI_CCB_READY, |
| 103 | MFI_CCB_RUNNING, |
| 104 | MFI_CCB_DONE |
| 105 | } ccb_state; |
| 106 | uint32_t ccb_flags; |
| 107 | #define MFI_CCB_F_ERR (1<<0) |
| 108 | #define MFI_CCB_F_TBOLT (1<<1) /* Thunderbolt descriptor */ |
| 109 | #define MFI_CCB_F_TBOLT_IO (1<<2) /* Thunderbolt I/O descriptor */ |
| 110 | TAILQ_ENTRY(mfi_ccb) ccb_link; |
| 111 | }; |
| 112 | |
| 113 | TAILQ_HEAD(mfi_ccb_list, mfi_ccb); |
| 114 | |
| 115 | enum mfi_iop { |
| 116 | MFI_IOP_XSCALE, |
| 117 | MFI_IOP_PPC, |
| 118 | MFI_IOP_GEN2, |
| 119 | MFI_IOP_SKINNY, |
| 120 | MFI_IOP_TBOLT |
| 121 | }; |
| 122 | |
| 123 | struct mfi_iop_ops { |
| 124 | uint32_t (*mio_fw_state)(struct mfi_softc *); |
| 125 | void (*mio_intr_dis)(struct mfi_softc *); |
| 126 | void (*mio_intr_ena)(struct mfi_softc *); |
| 127 | int (*mio_intr)(struct mfi_softc *); |
| 128 | void (*mio_post)(struct mfi_softc *, |
| 129 | struct mfi_ccb *); |
| 130 | int (*mio_ld_io)(struct mfi_ccb *, |
| 131 | struct scsipi_xfer *, uint64_t, uint32_t); |
| 132 | }; |
| 133 | |
| 134 | struct mfi_softc { |
| 135 | device_t sc_dev; |
| 136 | struct scsipi_channel sc_chan; |
| 137 | struct scsipi_adapter sc_adapt; |
| 138 | |
| 139 | const struct mfi_iop_ops *sc_iop; |
| 140 | enum mfi_iop sc_ioptype; |
| 141 | |
| 142 | void *sc_ih; |
| 143 | |
| 144 | bool sc_64bit_dma; |
| 145 | |
| 146 | bus_space_tag_t sc_iot; |
| 147 | bus_space_handle_t sc_ioh; |
| 148 | bus_size_t sc_size; |
| 149 | bus_dma_tag_t sc_dmat; |
| 150 | bus_dma_tag_t sc_datadmat; |
| 151 | |
| 152 | /* save some useful information for logical drives that is missing |
| 153 | * in sc_ld_list |
| 154 | */ |
| 155 | struct { |
| 156 | uint32_t ld_present; |
| 157 | char ld_dev[16]; /* device name sd? */ |
| 158 | } sc_ld[MFI_MAX_LD]; |
| 159 | |
| 160 | /* firmware determined max, totals and other information*/ |
| 161 | uint32_t sc_max_cmds; |
| 162 | uint32_t sc_max_sgl; |
| 163 | uint32_t sc_sgl_size; |
| 164 | uint32_t sc_max_ld; |
| 165 | uint32_t sc_ld_cnt; |
| 166 | /* XXX these struct should be local to mgmt function */ |
| 167 | struct mfi_ctrl_info sc_info; |
| 168 | struct mfi_ld_list sc_ld_list; |
| 169 | struct mfi_ld_details sc_ld_details; |
| 170 | |
| 171 | /* all commands */ |
| 172 | struct mfi_ccb *sc_ccb; |
| 173 | |
| 174 | /* producer/consumer pointers and reply queue */ |
| 175 | struct mfi_mem *sc_pcq; |
| 176 | |
| 177 | /* frame memory */ |
| 178 | struct mfi_mem *sc_frames; |
| 179 | uint32_t sc_frames_size; |
| 180 | |
| 181 | /* thunderbolt memory */ |
| 182 | struct mfi_mem *sc_tbolt_reqmsgpool; |
| 183 | |
| 184 | struct mfi_mem *sc_tbolt_ioc_init; |
| 185 | /* Virtual address of reply Frame Pool, part of sc_tbolt_reqmsgpool */ |
| 186 | int sc_reply_pool_size; |
| 187 | struct mfi_mpi2_reply_header* sc_reply_frame_pool; |
| 188 | bus_addr_t sc_reply_frame_busaddr; |
| 189 | uint8_t *sc_reply_pool_limit; |
| 190 | bus_addr_t sc_sg_frame_busaddr; |
| 191 | int sc_last_reply_idx; |
| 192 | |
| 193 | struct mfi_mem *sc_tbolt_verbuf; |
| 194 | |
| 195 | bool sc_MFA_enabled; |
| 196 | |
| 197 | /* workqueue for the ld sync command */ |
| 198 | struct workqueue *sc_ldsync_wq; |
| 199 | struct work sc_ldsync_wk; |
| 200 | struct mfi_ccb *sc_ldsync_ccb; |
| 201 | |
| 202 | /* sense memory */ |
| 203 | struct mfi_mem *sc_sense; |
| 204 | |
| 205 | struct mfi_ccb_list sc_ccb_freeq; |
| 206 | |
| 207 | struct sysmon_envsys *sc_sme; |
| 208 | envsys_data_t *sc_sensor; |
| 209 | bool sc_bbuok; |
| 210 | bool sc_running; |
| 211 | |
| 212 | device_t sc_child; |
| 213 | |
| 214 | /* for ioctl interface */ |
| 215 | bool sc_opened; |
| 216 | }; |
| 217 | |
| 218 | int mfi_rescan(device_t, const char *, const int *); |
| 219 | void mfi_childdetached(device_t, device_t); |
| 220 | int mfi_attach(struct mfi_softc *, enum mfi_iop); |
| 221 | int mfi_detach(struct mfi_softc *, int); |
| 222 | int mfi_intr(void *); |
| 223 | int mfi_tbolt_intrh(void *); |
| 224 | |