amrvar.h revision 107756
160812Sps/*-
260786Sps * Copyright (c) 1999,2000 Michael Smith
3170259Sdelphij * Copyright (c) 2000 BSDi
460786Sps * All rights reserved.
560786Sps *
660786Sps * Redistribution and use in source and binary forms, with or without
760786Sps * modification, are permitted provided that the following conditions
860786Sps * are met:
960786Sps * 1. Redistributions of source code must retain the above copyright
1060786Sps *    notice, this list of conditions and the following disclaimer.
1160786Sps * 2. Redistributions in binary form must reproduce the above copyright
1260786Sps *    notice, this list of conditions and the following disclaimer in the
1360786Sps *    documentation and/or other materials provided with the distribution.
1460786Sps *
1560786Sps * THIS SOFTWARE IS PROVIDED BY THE AUTHOR AND CONTRIBUTORS ``AS IS'' AND
1660786Sps * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
1760786Sps * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
1889022Sps * ARE DISCLAIMED.  IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE
1989022Sps * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
2089022Sps * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
2160786Sps * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
2260786Sps * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
2360786Sps * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
2460786Sps * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
2560786Sps * SUCH DAMAGE.
2660786Sps *
2760786Sps * Copyright (c) 2002 Eric Moore
2860786Sps * Copyright (c) 2002 LSI Logic Corporation
2960786Sps * All rights reserved.
3060786Sps *
3160786Sps * Redistribution and use in source and binary forms, with or without
3260786Sps * modification, are permitted provided that the following conditions
3360786Sps * are met:
3460786Sps * 1. Redistributions of source code must retain the above copyright
3560786Sps *    notice, this list of conditions and the following disclaimer.
36170259Sdelphij * 2. Redistributions in binary form must reproduce the above copyright
3760786Sps *    notice, this list of conditions and the following disclaimer in the
3860786Sps *    documentation and/or other materials provided with the distribution.
3960786Sps * 3. The party using or redistributing the source code and binary forms
4060786Sps *    agrees to the disclaimer below and the terms and conditions set forth
4160786Sps *    herein.
4260786Sps *
4360786Sps * THIS SOFTWARE IS PROVIDED BY THE AUTHOR AND CONTRIBUTORS ``AS IS'' AND
4460786Sps * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
4560786Sps * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
4660786Sps * ARE DISCLAIMED.  IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE
4760786Sps * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
4860786Sps * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
4960786Sps * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
5089022Sps * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
5160786Sps * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
5260786Sps * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
5360786Sps * SUCH DAMAGE.
5460786Sps *
5589022Sps *
5689022Sps *      $FreeBSD: head/sys/dev/amr/amrvar.h 107756 2002-12-11 20:59:46Z emoore $
5789022Sps */
5889022Sps
5960786Sps#if __FreeBSD_version >= 500005
6060786Sps# include <sys/taskqueue.h>
61170259Sdelphij#endif
62171009Sdelphij
63170259Sdelphij#ifdef AMR_DEBUG
6460786Sps# define debug(level, fmt, args...)	do {if (level <= AMR_DEBUG) printf("%s: " fmt "\n", __func__ , ##args);} while(0)
6560786Sps# define debug_called(level)		do {if (level <= AMR_DEBUG) printf("%s: called\n", __func__);} while(0)
6660786Sps#else
6760786Sps# define debug(level, fmt, args...)
6860786Sps# define debug_called(level)
6960786Sps#endif
7060786Sps#define xdebug(fmt, args...)	printf("%s: " fmt "\n", __func__ , ##args)
7160786Sps
7260786Sps/*
7360786Sps * Per-logical-drive datastructure
7460786Sps */
7560786Spsstruct amr_logdrive
7660812Sps{
7760786Sps    u_int32_t	al_size;
7860786Sps    int		al_state;
7960786Sps    int		al_properties;
8060786Sps
8160786Sps    /* synthetic geometry */
8260786Sps    int		al_cylinders;
8360786Sps    int		al_heads;
8460786Sps    int		al_sectors;
8560786Sps
8660786Sps    /* driver */
8760786Sps    device_t	al_disk;
8860786Sps};
8960786Sps
9060786Sps/*
9160786Sps * Due to the difficulty of using the zone allocator to create a new
9260786Sps * zone from within a module, we use our own clustering to reduce
9360786Sps * memory wastage due to allocating lots of these small structures.
9460786Sps *
9560786Sps * 16k gives us a little under 200 command structures, which should
9660786Sps * normally be plenty.  We will grab more if we need them.
9760786Sps */
9860786Sps
9960786Sps#define AMR_CMD_CLUSTERSIZE	(16 * 1024)
10060786Sps
10160786Sps/*
10260786Sps * Per-command control structure.
10360786Sps */
10460786Spsstruct amr_command
10560786Sps{
10660786Sps    TAILQ_ENTRY(amr_command)	ac_link;
10760786Sps
10860786Sps    struct amr_softc		*ac_sc;
10960786Sps    u_int8_t			ac_slot;
11089022Sps    int				ac_status;	/* command completion status */
11160786Sps    struct amr_mailbox		ac_mailbox;
11260786Sps    int				ac_flags;
11360786Sps#define AMR_CMD_DATAIN		(1<<0)
11460786Sps#define AMR_CMD_DATAOUT		(1<<1)
11560786Sps#define AMR_CMD_CCB_DATAIN	(1<<2)
11660786Sps#define AMR_CMD_CCB_DATAOUT	(1<<3)
11760786Sps#define AMR_CMD_PRIORITY	(1<<4)
11860786Sps#define AMR_CMD_MAPPED		(1<<5)
11960786Sps#define AMR_CMD_SLEEP		(1<<6)
12060786Sps#define AMR_CMD_BUSY		(1<<7)
12160786Sps
122161478Sdelphij    struct bio			*ac_bio;
12360786Sps
124170259Sdelphij    void			*ac_data;
125170259Sdelphij    size_t			ac_length;
126170259Sdelphij    bus_dmamap_t		ac_dmamap;
127170259Sdelphij    u_int32_t			ac_dataphys;
128170259Sdelphij
129170259Sdelphij    void			*ac_ccb_data;
130170259Sdelphij    size_t			ac_ccb_length;
131170259Sdelphij    bus_dmamap_t		ac_ccb_dmamap;
132170259Sdelphij    u_int32_t			ac_ccb_dataphys;
13360812Sps
134170259Sdelphij    void			(* ac_complete)(struct amr_command *ac);
135170259Sdelphij    void			*ac_private;
136170259Sdelphij};
137170259Sdelphij
138170259Sdelphijstruct amr_command_cluster
139170812Sdelphij{
140170812Sdelphij    TAILQ_ENTRY(amr_command_cluster)	acc_link;
141170812Sdelphij    struct amr_command		acc_command[0];
142170259Sdelphij};
14360786Sps
14460786Sps#define AMR_CMD_CLUSTERCOUNT	((AMR_CMD_CLUSTERSIZE - sizeof(struct amr_command_cluster)) /	\
14560786Sps				 sizeof(struct amr_command))
146170963Sdelphij
147170963Sdelphij/*
14860786Sps * Per-controller-instance data
14960786Sps */
15060786Spsstruct amr_softc
15160786Sps{
15260786Sps    /* bus attachments */
15360786Sps    device_t			amr_dev;
15460786Sps    struct resource		*amr_reg;		/* control registers */
15560786Sps    bus_space_handle_t		amr_bhandle;
15660786Sps    bus_space_tag_t		amr_btag;
15760786Sps    bus_dma_tag_t		amr_parent_dmat;	/* parent DMA tag */
15860786Sps    bus_dma_tag_t		amr_buffer_dmat;	/* data buffer DMA tag */
15960786Sps    struct resource		*amr_irq;		/* interrupt */
16060786Sps    void			*amr_intr;
16160786Sps
16260786Sps    /* mailbox */
16360786Sps    volatile struct amr_mailbox		*amr_mailbox;
16460786Sps    volatile struct amr_mailbox64	*amr_mailbox64;
16560786Sps    u_int32_t			amr_mailboxphys;
16660786Sps    bus_dma_tag_t		amr_mailbox_dmat;
16760786Sps    bus_dmamap_t		amr_mailbox_dmamap;
168170259Sdelphij
169171009Sdelphij    /* scatter/gather lists and their controller-visible mappings */
170170259Sdelphij    struct amr_sgentry		*amr_sgtable;		/* s/g lists */
17160786Sps    u_int32_t			amr_sgbusaddr;		/* s/g table base address in bus space */
17260786Sps    bus_dma_tag_t		amr_sg_dmat;		/* s/g buffer DMA tag */
17360786Sps    bus_dmamap_t		amr_sg_dmamap;		/* map for s/g buffers */
17460786Sps
17560786Sps    /* controller limits and features */
17660786Sps    int				amr_maxio;		/* maximum number of I/O transactions */
17760786Sps    int				amr_maxdrives;		/* max number of logical drives */
17860786Sps    int				amr_maxchan;		/* count of SCSI channels */
17960786Sps
18060786Sps    /* connected logical drives */
18160786Sps    struct amr_logdrive		amr_drive[AMR_MAXLD];
18260786Sps
18360786Sps    /* controller state */
18460786Sps    int				amr_state;
18560786Sps#define AMR_STATE_OPEN		(1<<0)
18660786Sps#define AMR_STATE_SUSPEND	(1<<1)
18760786Sps#define AMR_STATE_INTEN		(1<<2)
18860786Sps#define AMR_STATE_SHUTDOWN	(1<<3)
18960786Sps
19060786Sps    /* per-controller queues */
19160786Sps    struct bio_queue_head 	amr_bioq;		/* pending I/O with no commands */
19260786Sps    TAILQ_HEAD(,amr_command)	amr_ready;		/* commands ready to be submitted */
193128348Stjr    struct amr_command		*amr_busycmd[AMR_MAXCMD];
19489022Sps    int				amr_busyslots;
19560786Sps    TAILQ_HEAD(,amr_command)	amr_completed;
19660786Sps    TAILQ_HEAD(,amr_command)	amr_freecmds;
19760786Sps    TAILQ_HEAD(,amr_command_cluster)	amr_cmd_clusters;
19860786Sps
19960786Sps    /* CAM attachments for passthrough */
20060786Sps    struct cam_sim		*amr_cam_sim[AMR_MAX_CHANNELS];
20160786Sps    TAILQ_HEAD(, ccb_hdr)	amr_cam_ccbq;
20260786Sps
20360786Sps    /* control device */
20460786Sps    dev_t			amr_dev_t;
20560786Sps
20660786Sps    /* controller type-specific support */
20760786Sps    int				amr_type;
208128348Stjr#define AMR_TYPE_QUARTZ		(1<<0)
209128348Stjr#define AMR_IS_QUARTZ(sc)	((sc)->amr_type & AMR_TYPE_QUARTZ)
210128348Stjr#define AMR_TYPE_40LD		(1<<1)
211128348Stjr#define AMR_IS_40LD(sc)		((sc)->amr_type & AMR_TYPE_40LD)
21260786Sps    int				(* amr_submit_command)(struct amr_softc *sc);
21360786Sps    int				(* amr_get_work)(struct amr_softc *sc, struct amr_mailbox *mbsave);
214128348Stjr    int				(*amr_poll_command)(struct amr_command *ac);
215128348Stjr    int 			support_ext_cdb;	/* greater than 10 byte cdb support */
216128348Stjr
217128348Stjr    /* misc glue */
218128348Stjr    struct intr_config_hook	amr_ich;		/* wait-for-interrupts probe hook */
219128348Stjr    struct callout_handle	amr_timeout;		/* periodic status check */
22060786Sps#if __FreeBSD_version >= 500005
22160786Sps    struct task			amr_task_complete;	/* deferred-completion task */
22260786Sps#endif
22360786Sps};
22460786Sps
22560786Sps/*
22660786Sps * Interface between bus connections and driver core.
22760786Sps */
22860786Spsextern int              amr_attach(struct amr_softc *sc);
22960786Spsextern void		amr_free(struct amr_softc *sc);
23060786Spsextern int		amr_flush(struct amr_softc *sc);
23160786Spsextern int		amr_done(struct amr_softc *sc);
23260786Spsextern void		amr_startio(struct amr_softc *sc);
23360786Sps
23460786Sps/*
23560786Sps * Command buffer allocation.
23660786Sps */
23760786Spsextern struct amr_command	*amr_alloccmd(struct amr_softc *sc);
23860786Spsextern void			amr_releasecmd(struct amr_command *ac);
23960786Sps
24060786Sps/*
24160786Sps * CAM interface
24260786Sps */
24360786Spsextern int		amr_cam_attach(struct amr_softc *sc);
24460786Spsextern void		amr_cam_detach(struct amr_softc *sc);
245170259Sdelphijextern int		amr_cam_command(struct amr_softc *sc, struct amr_command **acp);
24660786Sps
24760786Sps/*
248128348Stjr * MegaRAID logical disk driver
24960786Sps */
25060786Spsstruct amrd_softc
25160786Sps{
25260786Sps    device_t		amrd_dev;
25360786Sps    dev_t		amrd_dev_t;
25460786Sps    struct amr_softc	*amrd_controller;
25560786Sps    struct amr_logdrive	*amrd_drive;
25689022Sps    struct disk		amrd_disk;
25760786Sps    struct devstat	amrd_stats;
25860786Sps    int			amrd_unit;
25960786Sps    int			amrd_flags;
26060786Sps#define AMRD_OPEN	(1<<0)		/* drive is open (can't detach) */
26160786Sps};
26260786Sps
26360786Sps/*
26460786Sps * Interface between driver core and disk driver (should be using a bus?)
26560786Sps */
26660786Spsextern int	amr_submit_bio(struct amr_softc *sc, struct bio *bio);
26760786Spsextern void	amrd_intr(void *data);
26860786Sps
26960786Sps/********************************************************************************
27060786Sps * Enqueue/dequeue functions
27160786Sps */
27260786Spsstatic __inline void
27360786Spsamr_enqueue_bio(struct amr_softc *sc, struct bio *bio)
27460786Sps{
27560786Sps    int		s;
27660786Sps
27760786Sps    s = splbio();
27860786Sps    bioq_insert_tail(&sc->amr_bioq, bio);
27960786Sps    splx(s);
28060786Sps}
28160786Sps
28260786Spsstatic __inline struct bio *
28360786Spsamr_dequeue_bio(struct amr_softc *sc)
28460786Sps{
28560786Sps    struct bio	*bio;
28660786Sps    int		s;
28760786Sps
28860786Sps    s = splbio();
28960786Sps    if ((bio = bioq_first(&sc->amr_bioq)) != NULL)
29060786Sps	bioq_remove(&sc->amr_bioq, bio);
29160786Sps    splx(s);
29260786Sps    return(bio);
29360786Sps}
29460786Sps
29560786Spsstatic __inline void
296128348Stjramr_enqueue_ready(struct amr_command *ac)
29760786Sps{
29860786Sps    int		s;
29960786Sps
30060786Sps    s = splbio();
30160786Sps    TAILQ_INSERT_TAIL(&ac->ac_sc->amr_ready, ac, ac_link);
30260786Sps    splx(s);
30360786Sps}
30460786Sps
30560786Spsstatic __inline void
30660786Spsamr_requeue_ready(struct amr_command *ac)
30760786Sps{
30860786Sps    int		s;
30960786Sps
31060786Sps    s = splbio();
31160786Sps    TAILQ_INSERT_HEAD(&ac->ac_sc->amr_ready, ac, ac_link);
31260786Sps    splx(s);
31360786Sps}
31460786Sps
31560786Spsstatic __inline struct amr_command *
31660786Spsamr_dequeue_ready(struct amr_softc *sc)
31760786Sps{
31860786Sps    struct amr_command	*ac;
31960786Sps    int			s;
32060786Sps
32160786Sps    s = splbio();
32260786Sps    if ((ac = TAILQ_FIRST(&sc->amr_ready)) != NULL)
32360786Sps	TAILQ_REMOVE(&sc->amr_ready, ac, ac_link);
32460786Sps    splx(s);
32560786Sps    return(ac);
32660786Sps}
32760786Sps
32860786Spsstatic __inline void
32960786Spsamr_enqueue_completed(struct amr_command *ac)
33060786Sps{
331128348Stjr    int		s;
33260786Sps
33360786Sps    s = splbio();
33460786Sps    TAILQ_INSERT_TAIL(&ac->ac_sc->amr_completed, ac, ac_link);
33560786Sps    splx(s);
33660786Sps}
33760786Sps
33860786Spsstatic __inline struct amr_command *
33960786Spsamr_dequeue_completed(struct amr_softc *sc)
34060786Sps{
34160786Sps    struct amr_command	*ac;
34260786Sps    int			s;
34360786Sps
34460786Sps    s = splbio();
34560786Sps    if ((ac = TAILQ_FIRST(&sc->amr_completed)) != NULL)
34660786Sps	TAILQ_REMOVE(&sc->amr_completed, ac, ac_link);
34760786Sps    splx(s);
34860786Sps    return(ac);
34960786Sps}
35060786Sps
35160786Spsstatic __inline void
35260786Spsamr_enqueue_free(struct amr_command *ac)
35360786Sps{
35460786Sps    int		s;
35560786Sps
35660786Sps    s = splbio();
35760786Sps    TAILQ_INSERT_TAIL(&ac->ac_sc->amr_freecmds, ac, ac_link);
35860786Sps    splx(s);
35960786Sps}
36060786Sps
36160786Spsstatic __inline struct amr_command *
36260786Spsamr_dequeue_free(struct amr_softc *sc)
36360786Sps{
36460786Sps    struct amr_command	*ac;
36560786Sps    int			s;
366161478Sdelphij
36760786Sps    s = splbio();
368161478Sdelphij    if ((ac = TAILQ_FIRST(&sc->amr_freecmds)) != NULL)
369161478Sdelphij	TAILQ_REMOVE(&sc->amr_freecmds, ac, ac_link);
37060786Sps    splx(s);
37160786Sps    return(ac);
372161478Sdelphij}
373161478Sdelphij