Home | History | Annotate | Line # | Download | only in ic
      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 (at) 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		ccb_extra_frames;
     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