Home | History | Annotate | Line # | Download | only in pci
mlyvar.h revision 1.1
      1 /*	$NetBSD: mlyvar.h,v 1.1 2001/07/30 19:59:07 ad Exp $	*/
      2 
      3 /*-
      4  * Copyright (c) 2001 The NetBSD Foundation, Inc.
      5  * All rights reserved.
      6  *
      7  * This code is derived from software contributed to The NetBSD Foundation
      8  * by Andrew Doran, Thor Lancelot Simon, and Eric Haszlakiewicz.
      9  *
     10  * Redistribution and use in source and binary forms, with or without
     11  * modification, are permitted provided that the following conditions
     12  * are met:
     13  * 1. Redistributions of source code must retain the above copyright
     14  *    notice, this list of conditions and the following disclaimer.
     15  * 2. Redistributions in binary form must reproduce the above copyright
     16  *    notice, this list of conditions and the following disclaimer in the
     17  *    documentation and/or other materials provided with the distribution.
     18  * 3. All advertising materials mentioning features or use of this software
     19  *    must display the following acknowledgement:
     20  *        This product includes software developed by the NetBSD
     21  *        Foundation, Inc. and its contributors.
     22  * 4. Neither the name of The NetBSD Foundation nor the names of its
     23  *    contributors may be used to endorse or promote products derived
     24  *    from this software without specific prior written permission.
     25  *
     26  * THIS SOFTWARE IS PROVIDED BY THE NETBSD FOUNDATION, INC. AND CONTRIBUTORS
     27  * ``AS IS'' AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED
     28  * TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
     29  * PURPOSE ARE DISCLAIMED.  IN NO EVENT SHALL THE FOUNDATION OR CONTRIBUTORS
     30  * BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
     31  * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
     32  * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
     33  * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
     34  * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
     35  * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
     36  * POSSIBILITY OF SUCH DAMAGE.
     37  */
     38 
     39 /*-
     40  * Copyright (c) 2000, 2001 Michael Smith
     41  * Copyright (c) 2000 BSDi
     42  * All rights reserved.
     43  *
     44  * Redistribution and use in source and binary forms, with or without
     45  * modification, are permitted provided that the following conditions
     46  * are met:
     47  * 1. Redistributions of source code must retain the above copyright
     48  *    notice, this list of conditions and the following disclaimer.
     49  * 2. Redistributions in binary form must reproduce the above copyright
     50  *    notice, this list of conditions and the following disclaimer in the
     51  *    documentation and/or other materials provided with the distribution.
     52  *
     53  * THIS SOFTWARE IS PROVIDED BY THE AUTHOR AND CONTRIBUTORS ``AS IS'' AND
     54  * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
     55  * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
     56  * ARE DISCLAIMED.  IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE
     57  * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
     58  * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
     59  * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
     60  * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
     61  * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
     62  * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
     63  * SUCH DAMAGE.
     64  *
     65  * from FreeBSD: mlyvar.h,v 1.3 2001/07/14 00:12:22 msmith Exp
     66  */
     67 
     68 #ifndef _PCI_MLYVAR_H_
     69 #define	_PCI_MLYVAR_H_
     70 
     71 /*
     72  * The firmware interface allows for a 16-bit command identifier.  We cap
     73  * ourselves at a reasonable limit.  Note that we reserve a small number of
     74  * CCBs for control operations.
     75  */
     76 #define	MLY_MAX_CCBS	256
     77 #define	MLY_CCBS_RESV	4
     78 
     79 /*
     80  * The firmware interface allows for a 16-bit s/g list length.  We limit
     81  * ourselves to a reasonable maximum.
     82  */
     83 #define	MLY_MAX_SEGS	17
     84 #define	MLY_SGL_SIZE	(MLY_MAX_SEGS * sizeof(struct mly_sg_entry))
     85 
     86 #define	MLY_MAX_XFER	((MLY_MAX_SEGS - 1) * PAGE_SIZE)
     87 
     88 /*
     89  * The interval at which we poke the controller for status updates (in
     90  * seconds).
     91  */
     92 #define	MLY_PERIODIC_INTERVAL	5
     93 
     94 /*
     95  * Command slot regulation.  We can't use slot 0 due to the memory mailbox
     96  * implementation.
     97  */
     98 #define	MLY_SLOT_START		1
     99 #define	MLY_SLOT_MAX		(MLY_SLOT_START + MLY_MAX_CCBS)
    100 
    101 /*
    102  * Per-device structure, used to save persistent state on devices.
    103  *
    104  * Note that this isn't really Bus/Target/Lun since we don't support lun !=
    105  * 0 at this time.
    106  */
    107 struct mly_btl {
    108 	int	mb_flags;
    109 	int	mb_state;		/* See 8.1 */
    110 	int	mb_type;		/* See 8.2 */
    111 
    112 	/* Physical devices only. */
    113 	int	mb_speed;		/* Interface transfer rate */
    114 	int	mb_width;		/* Interface width */
    115 };
    116 #define	MLY_BTL_PHYSICAL	0x01	/* physical device */
    117 #define	MLY_BTL_LOGICAL		0x02	/* logical device */
    118 #define	MLY_BTL_PROTECTED	0x04	/* I/O not allowed */
    119 #define	MLY_BTL_TQING		0x08	/* tagged queueing */
    120 #define	MLY_BTL_SCANNING	0x10	/* scan in progress */
    121 #define	MLY_BTL_RESCAN		0x20	/* need to re-scan */
    122 
    123 /*
    124  * Per-command context.
    125  */
    126 struct mly_softc;
    127 
    128 struct mly_ccb {
    129 	union {
    130 		SLIST_ENTRY(mly_ccb)	slist;
    131 		SIMPLEQ_ENTRY(mly_ccb)	simpleq;
    132 	} mc_link;			/* list linkage */
    133 
    134 	u_int		mc_slot;	/* command slot we occupy */
    135 	u_int		mc_flags;	/* status flags */
    136 	u_int		mc_status;	/* command completion status */
    137 	u_int		mc_sense;	/* sense data length */
    138 	int32_t		mc_resid;	/* I/O residual count */
    139 
    140 	union mly_cmd_packet *mc_packet;/* our controller command */
    141 	bus_addr_t	mc_packetphys;	/* physical address of the mapped packet */
    142 
    143 	void		*mc_data;	/* data buffer */
    144 	size_t		mc_length;	/* data length */
    145 	bus_dmamap_t	mc_datamap;	/* DMA map for data */
    146 	u_int		mc_sgoff;	/* S/G list offset */
    147 
    148 	void		(*mc_complete)(struct mly_softc *, struct mly_ccb *);
    149 	void		*mc_private;
    150 };
    151 #define	MLY_CCB_DATAIN		0x01
    152 #define	MLY_CCB_DATAOUT		0x02
    153 #define	MLY_CCB_MAPPED		0x04
    154 #define	MLY_CCB_COMPLETE	0x08
    155 
    156 /*
    157  * Per-controller context.
    158  */
    159 struct mly_softc {
    160 	/* Generic device info. */
    161 	struct device		mly_dv;
    162 	bus_space_handle_t	mly_ioh;
    163 	bus_space_tag_t		mly_iot;
    164 	bus_dma_tag_t		mly_dmat;
    165 	void			*mly_ih;
    166 
    167 	/* Scatter-gather lists. */
    168 	struct mly_sg_entry	*mly_sg;
    169 	bus_addr_t		mly_sg_busaddr;
    170 	bus_dma_tag_t		mly_sg_dmat;
    171 	bus_dmamap_t		mly_sg_dmamap;
    172 	bus_dma_segment_t	mly_sg_seg;
    173 
    174 	/* Memory mailbox. */
    175 	struct mly_mmbox	*mly_mmbox;
    176 	bus_addr_t		mly_mmbox_busaddr;
    177 	bus_dma_tag_t		mly_mmbox_dmat;
    178 	bus_dmamap_t		mly_mmbox_dmamap;
    179 	bus_dma_segment_t	mly_mmbox_seg;
    180 	u_int			mly_mmbox_cmd_idx;
    181 	u_int			mly_mmbox_sts_idx;
    182 
    183 	/* Command packets. */
    184 	union mly_cmd_packet	*mly_pkt;
    185 	bus_addr_t		mly_pkt_busaddr;
    186 	bus_dma_tag_t		mly_pkt_dmat;
    187 	bus_dmamap_t		mly_pkt_dmamap;
    188 	bus_dma_segment_t	mly_pkt_seg;
    189 
    190 	/* Command management. */
    191 	struct mly_ccb		*mly_ccbs;
    192 	SLIST_HEAD(,mly_ccb)	mly_ccb_free;
    193 	SIMPLEQ_HEAD(,mly_ccb)	mly_ccb_queue;
    194 	u_int			mly_ncmds;
    195 
    196 	/* Controller hardware interface. */
    197 	u_int			mly_hwif;
    198 	u_int			mly_doorbell_true;
    199 	u_int			mly_cmd_mailbox;
    200 	u_int			mly_status_mailbox;
    201 	u_int			mly_idbr;
    202 	u_int			mly_odbr;
    203 	u_int			mly_error_status;
    204 	u_int			mly_interrupt_status;
    205 	u_int			mly_interrupt_mask;
    206 
    207 	/* Controller features, limits and status. */
    208 	u_int			mly_state;
    209 	struct mly_ioctl_getcontrollerinfo *mly_controllerinfo;
    210 	struct mly_param_controller *mly_controllerparam;
    211 	struct mly_btl		mly_btl[MLY_MAX_CHANNELS][MLY_MAX_TARGETS];
    212 
    213 	/* Health monitoring. */
    214 	u_int			mly_event_change;
    215 	u_int			mly_event_counter;
    216 	u_int			mly_event_waiting;
    217 	struct proc		*mly_thread;
    218 
    219 	/* SCSI mid-layer connection. */
    220 	struct scsipi_adapter	mly_adapt;
    221 	struct scsipi_channel	mly_chans[MLY_MAX_CHANNELS];
    222 	u_int			mly_nchans;
    223 };
    224 #define	MLY_HWIF_I960RX		0
    225 #define	MLY_HWIF_STRONGARM	1
    226 
    227 #define	MLY_STATE_OPEN		0x01
    228 #define	MLY_STATE_MMBOX_ACTIVE	0x02
    229 #define	MLY_STATE_INITOK	0x04
    230 
    231 /*
    232  * Register access helpers.
    233  */
    234 
    235 static __inline__ u_int8_t	mly_inb(struct mly_softc *, int);
    236 static __inline__ u_int16_t	mly_inw(struct mly_softc *, int);
    237 static __inline__ u_int32_t	mly_inl(struct mly_softc *, int);
    238 static __inline__ void		mly_outb(struct mly_softc *, int, u_int8_t);
    239 static __inline__ void		mly_outw(struct mly_softc *, int, u_int16_t);
    240 static __inline__ void		mly_outl(struct mly_softc *, int, u_int32_t);
    241 static __inline__ int		mly_idbr_true(struct mly_softc *, u_int8_t);
    242 static __inline__ int		mly_odbr_true(struct mly_softc *, u_int8_t);
    243 static __inline__ int		mly_error_valid(struct mly_softc *);
    244 
    245 static __inline__ u_int8_t
    246 mly_inb(struct mly_softc *mly, int off)
    247 {
    248 
    249 	bus_space_barrier(mly->mly_iot, mly->mly_ioh, off, 1,
    250 	    BUS_SPACE_BARRIER_WRITE | BUS_SPACE_BARRIER_READ);
    251 	return (bus_space_read_1(mly->mly_iot, mly->mly_ioh, off));
    252 }
    253 
    254 static __inline__ u_int16_t
    255 mly_inw(struct mly_softc *mly, int off)
    256 {
    257 
    258 	bus_space_barrier(mly->mly_iot, mly->mly_ioh, off, 2,
    259 	    BUS_SPACE_BARRIER_WRITE | BUS_SPACE_BARRIER_READ);
    260 	return (bus_space_read_2(mly->mly_iot, mly->mly_ioh, off));
    261 }
    262 
    263 static __inline__ u_int32_t
    264 mly_inl(struct mly_softc *mly, int off)
    265 {
    266 
    267 	bus_space_barrier(mly->mly_iot, mly->mly_ioh, off, 4,
    268 	    BUS_SPACE_BARRIER_WRITE | BUS_SPACE_BARRIER_READ);
    269 	return (bus_space_read_4(mly->mly_iot, mly->mly_ioh, off));
    270 }
    271 
    272 static __inline__ void
    273 mly_outb(struct mly_softc *mly, int off, u_int8_t val)
    274 {
    275 
    276 	bus_space_write_1(mly->mly_iot, mly->mly_ioh, off, val);
    277 	bus_space_barrier(mly->mly_iot, mly->mly_ioh, off, 1,
    278 	    BUS_SPACE_BARRIER_WRITE);
    279 }
    280 
    281 static __inline__ void
    282 mly_outw(struct mly_softc *mly, int off, u_int16_t val)
    283 {
    284 
    285 	bus_space_write_2(mly->mly_iot, mly->mly_ioh, off, val);
    286 	bus_space_barrier(mly->mly_iot, mly->mly_ioh, off, 2,
    287 	    BUS_SPACE_BARRIER_WRITE);
    288 }
    289 
    290 static __inline__ void
    291 mly_outl(struct mly_softc *mly, int off, u_int32_t val)
    292 {
    293 
    294 	bus_space_write_4(mly->mly_iot, mly->mly_ioh, off, val);
    295 	bus_space_barrier(mly->mly_iot, mly->mly_ioh, off, 4,
    296 	    BUS_SPACE_BARRIER_WRITE);
    297 }
    298 
    299 static __inline__ int
    300 mly_idbr_true(struct mly_softc *mly, u_int8_t mask)
    301 {
    302 	u_int8_t val;
    303 
    304 	val = mly_inb(mly, mly->mly_idbr) ^ mly->mly_doorbell_true;
    305 	return ((val & mask) == mask);
    306 }
    307 
    308 static __inline__ int
    309 mly_odbr_true(struct mly_softc *mly, u_int8_t mask)
    310 {
    311 
    312 	return ((mly_inb(mly, mly->mly_odbr) & mask) == mask);
    313 }
    314 
    315 static __inline__ int
    316 mly_error_valid(struct mly_softc *mly)
    317 {
    318 	u_int8_t val;
    319 
    320 	val = mly_inb(mly, mly->mly_error_status) ^ mly->mly_doorbell_true;
    321 	return ((val & MLY_MSG_EMPTY) == 0);
    322 }
    323 
    324 /*
    325  * Bus/target/logical ID-related macros.
    326  */
    327 
    328 #define	MLY_LOGDEV_ID(mly, bus, target)					\
    329     (((bus) - (mly)->mly_controllerinfo->physical_channels_present) *	\
    330     MLY_MAX_TARGETS + (target))
    331 
    332 #define	MLY_LOGDEV_BUS(mly, logdev)					\
    333     (((logdev) / MLY_MAX_TARGETS) +					\
    334     (mly)->mly_controllerinfo->physical_channels_present)
    335 
    336 #define	MLY_LOGDEV_TARGET(mly, logdev)					\
    337     ((logdev) % MLY_MAX_TARGETS)
    338 
    339 #define	MLY_BUS_IS_VIRTUAL(mly, bus)					\
    340     ((bus) >= (mly)->mly_controllerinfo->physical_channels_present)
    341 
    342 #define	MLY_BUS_IS_VALID(mly, bus)					\
    343     (((bus) < (mly)->mly_nchans))
    344 
    345 #endif	/* !defined _PCI_MLYVAR_H_ */
    346