amrvar.h revision 65245
151974Smsmith/*-
265245Smsmith * Copyright (c) 1999,2000 Michael Smith
365245Smsmith * Copyright (c) 2000 BSDi
451974Smsmith * All rights reserved.
551974Smsmith *
651974Smsmith * Redistribution and use in source and binary forms, with or without
751974Smsmith * modification, are permitted provided that the following conditions
851974Smsmith * are met:
951974Smsmith * 1. Redistributions of source code must retain the above copyright
1051974Smsmith *    notice, this list of conditions and the following disclaimer.
1151974Smsmith * 2. Redistributions in binary form must reproduce the above copyright
1251974Smsmith *    notice, this list of conditions and the following disclaimer in the
1351974Smsmith *    documentation and/or other materials provided with the distribution.
1451974Smsmith *
1551974Smsmith * THIS SOFTWARE IS PROVIDED BY THE AUTHOR AND CONTRIBUTORS ``AS IS'' AND
1651974Smsmith * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
1751974Smsmith * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
1851974Smsmith * ARE DISCLAIMED.  IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE
1951974Smsmith * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
2051974Smsmith * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
2151974Smsmith * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
2251974Smsmith * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
2351974Smsmith * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
2451974Smsmith * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
2551974Smsmith * SUCH DAMAGE.
2651974Smsmith *
2751974Smsmith *      $FreeBSD: head/sys/dev/amr/amrvar.h 65245 2000-08-30 07:52:50Z msmith $
2851974Smsmith */
2951974Smsmith
3065245Smsmith#if __FreeBSD_version >= 500005
3165245Smsmith# include <sys/taskqueue.h>
3265245Smsmith#endif
3351974Smsmith
3465245Smsmith#ifdef AMR_DEBUG
3565245Smsmith# define debug(level, fmt, args...)	do {if (level <= AMR_DEBUG) printf("%s: " fmt "\n", __FUNCTION__ , ##args);} while(0)
3665245Smsmith# define debug_called(level)		do {if (level <= AMR_DEBUG) printf("%s: called\n", __FUNCTION__);} while(0)
3765245Smsmith#else
3865245Smsmith# define debug(level, fmt, args...)
3965245Smsmith# define debug_called(level)
4065245Smsmith#endif
4165245Smsmith#define xdebug(fmt, args...)	printf("%s: " fmt "\n", __FUNCTION__ , ##args)
4251974Smsmith
4351974Smsmith/*
4451974Smsmith * Per-logical-drive datastructure
4551974Smsmith */
4651974Smsmithstruct amr_logdrive
4751974Smsmith{
4851974Smsmith    u_int32_t	al_size;
4951974Smsmith    int		al_state;
5051974Smsmith    int		al_properties;
5151974Smsmith
5251974Smsmith    /* synthetic geometry */
5351974Smsmith    int		al_cylinders;
5451974Smsmith    int		al_heads;
5551974Smsmith    int		al_sectors;
5651974Smsmith
5751974Smsmith    /* driver */
5851974Smsmith    device_t	al_disk;
5951974Smsmith};
6051974Smsmith
6165245Smsmith/*
6265245Smsmith * Due to the difficulty of using the zone allocator to create a new
6365245Smsmith * zone from within a module, we use our own clustering to reduce
6465245Smsmith * memory wastage due to allocating lots of these small structures.
6565245Smsmith *
6665245Smsmith * 16k gives us a little under 200 command structures, which should
6765245Smsmith * normally be plenty.  We will grab more if we need them.
6865245Smsmith */
6951974Smsmith
7065245Smsmith#define AMR_CMD_CLUSTERSIZE	(16 * 1024)
7165245Smsmith
7251974Smsmith/*
7351974Smsmith * Per-command control structure.
7451974Smsmith */
7551974Smsmithstruct amr_command
7651974Smsmith{
7760938Sjake    TAILQ_ENTRY(amr_command)	ac_link;
7851974Smsmith
7951974Smsmith    struct amr_softc		*ac_sc;
8051974Smsmith    u_int8_t			ac_slot;
8165245Smsmith    int				ac_status;	/* command completion status */
8251974Smsmith    struct amr_mailbox		ac_mailbox;
8351974Smsmith    int				ac_flags;
8451974Smsmith#define AMR_CMD_DATAIN		(1<<0)
8551974Smsmith#define AMR_CMD_DATAOUT		(1<<1)
8665245Smsmith#define AMR_CMD_CCB_DATAIN	(1<<2)
8765245Smsmith#define AMR_CMD_CCB_DATAOUT	(1<<3)
8865245Smsmith#define AMR_CMD_PRIORITY	(1<<4)
8965245Smsmith#define AMR_CMD_MAPPED		(1<<5)
9065245Smsmith#define AMR_CMD_SLEEP		(1<<6)
9165245Smsmith#define AMR_CMD_BUSY		(1<<7)
9251974Smsmith
9365245Smsmith    struct bio			*ac_bio;
9465245Smsmith
9551974Smsmith    void			*ac_data;
9651974Smsmith    size_t			ac_length;
9751974Smsmith    bus_dmamap_t		ac_dmamap;
9851974Smsmith    u_int32_t			ac_dataphys;
9951974Smsmith
10065245Smsmith    void			*ac_ccb_data;
10165245Smsmith    size_t			ac_ccb_length;
10265245Smsmith    bus_dmamap_t		ac_ccb_dmamap;
10365245Smsmith    u_int32_t			ac_ccb_dataphys;
10465245Smsmith
10551974Smsmith    void			(* ac_complete)(struct amr_command *ac);
10651974Smsmith};
10751974Smsmith
10865245Smsmithstruct amr_command_cluster
10965245Smsmith{
11065245Smsmith    TAILQ_ENTRY(amr_command_cluster)	acc_link;
11165245Smsmith    struct amr_command		acc_command[0];
11265245Smsmith};
11365245Smsmith
11465245Smsmith#define AMR_CMD_CLUSTERCOUNT	((AMR_CMD_CLUSTERSIZE - sizeof(struct amr_command_cluster)) /	\
11565245Smsmith				 sizeof(struct amr_command))
11665245Smsmith
11765245Smsmith/*
11865245Smsmith * Per-controller-instance data
11965245Smsmith */
12051974Smsmithstruct amr_softc
12151974Smsmith{
12251974Smsmith    /* bus attachments */
12351974Smsmith    device_t			amr_dev;
12451974Smsmith    struct resource		*amr_reg;		/* control registers */
12551974Smsmith    bus_space_handle_t		amr_bhandle;
12651974Smsmith    bus_space_tag_t		amr_btag;
12751974Smsmith    bus_dma_tag_t		amr_parent_dmat;	/* parent DMA tag */
12851974Smsmith    bus_dma_tag_t		amr_buffer_dmat;	/* data buffer DMA tag */
12951974Smsmith    struct resource		*amr_irq;		/* interrupt */
13051974Smsmith    void			*amr_intr;
13151974Smsmith
13251974Smsmith    /* mailbox */
13358496Smsmith    volatile struct amr_mailbox		*amr_mailbox;
13458496Smsmith    volatile struct amr_mailbox64	*amr_mailbox64;
13551974Smsmith    u_int32_t			amr_mailboxphys;
13651974Smsmith    bus_dma_tag_t		amr_mailbox_dmat;
13751974Smsmith    bus_dmamap_t		amr_mailbox_dmamap;
13851974Smsmith
13951974Smsmith    /* scatter/gather lists and their controller-visible mappings */
14051974Smsmith    struct amr_sgentry		*amr_sgtable;		/* s/g lists */
14151974Smsmith    u_int32_t			amr_sgbusaddr;		/* s/g table base address in bus space */
14251974Smsmith    bus_dma_tag_t		amr_sg_dmat;		/* s/g buffer DMA tag */
14351974Smsmith    bus_dmamap_t		amr_sg_dmamap;		/* map for s/g buffers */
14451974Smsmith
14551974Smsmith    /* controller limits and features */
14651974Smsmith    int				amr_maxio;		/* maximum number of I/O transactions */
14751974Smsmith    int				amr_maxdrives;		/* max number of logical drives */
14865245Smsmith    int				amr_maxchan;		/* count of SCSI channels */
14951974Smsmith
15051974Smsmith    /* connected logical drives */
15151974Smsmith    struct amr_logdrive		amr_drive[AMR_MAXLD];
15251974Smsmith
15365245Smsmith    /* controller state */
15451974Smsmith    int				amr_state;
15551974Smsmith#define AMR_STATE_OPEN		(1<<0)
15651974Smsmith#define AMR_STATE_SUSPEND	(1<<1)
15751974Smsmith#define AMR_STATE_INTEN		(1<<2)
15851974Smsmith#define AMR_STATE_SHUTDOWN	(1<<3)
15951974Smsmith
16051974Smsmith    /* per-controller queues */
16165245Smsmith    struct bio_queue_head 	amr_bioq;		/* pending I/O with no commands */
16265245Smsmith    TAILQ_HEAD(,amr_command)	amr_ready;		/* commands ready to be submitted */
16351974Smsmith    struct amr_command		*amr_busycmd[AMR_MAXCMD];
16465245Smsmith    int				amr_busyslots;
16565245Smsmith    TAILQ_HEAD(,amr_command)	amr_completed;
16660938Sjake    TAILQ_HEAD(,amr_command)	amr_freecmds;
16765245Smsmith    TAILQ_HEAD(,amr_command_cluster)	amr_cmd_clusters;
16851974Smsmith
16965245Smsmith    /* CAM attachments for passthrough */
17065245Smsmith    struct cam_sim		*amr_cam_sim[AMR_MAX_CHANNELS];
17165245Smsmith    TAILQ_HEAD(, ccb_hdr)	amr_cam_ccbq;
17258883Smsmith
17365245Smsmith    /* control device */
17465245Smsmith    dev_t			amr_dev_t;
17565245Smsmith
17651974Smsmith    /* controller type-specific support */
17751974Smsmith    int				amr_type;
17865245Smsmith#define AMR_TYPE_QUARTZ		(1<<0)
17965245Smsmith#define AMR_IS_QUARTZ(sc)	((sc)->amr_type & AMR_TYPE_QUARTZ)
18065245Smsmith#define AMR_TYPE_40LD		(1<<1)
18165245Smsmith#define AMR_IS_40LD(sc)		((sc)->amr_type & AMR_TYPE_40LD)
18265245Smsmith    int				(* amr_submit_command)(struct amr_softc *sc);
18351974Smsmith    int				(* amr_get_work)(struct amr_softc *sc, struct amr_mailbox *mbsave);
18465245Smsmith
18565245Smsmith    /* misc glue */
18665245Smsmith    struct intr_config_hook	amr_ich;		/* wait-for-interrupts probe hook */
18765245Smsmith    struct callout_handle	amr_timeout;		/* periodic status check */
18865245Smsmith#if __FreeBSD_version >= 500005
18965245Smsmith    struct task			amr_task_complete;	/* deferred-completion task */
19065245Smsmith#endif
19151974Smsmith};
19251974Smsmith
19351974Smsmith/*
19465245Smsmith * Interface between bus connections and driver core.
19558883Smsmith */
19665245Smsmithextern int              amr_attach(struct amr_softc *sc);
19765245Smsmithextern void		amr_free(struct amr_softc *sc);
19865245Smsmithextern int		amr_flush(struct amr_softc *sc);
19965245Smsmithextern int		amr_done(struct amr_softc *sc);
20065245Smsmithextern void		amr_startio(struct amr_softc *sc);
20158883Smsmith
20265245Smsmithextern devclass_t	amr_devclass;
20358883Smsmith
20458883Smsmith/*
20565245Smsmith * Command buffer allocation.
20651974Smsmith */
20765245Smsmithextern struct amr_command	*amr_alloccmd(struct amr_softc *sc);
20865245Smsmithextern void			amr_releasecmd(struct amr_command *ac);
20951974Smsmith
21051974Smsmith/*
21165245Smsmith * CAM interface
21251974Smsmith */
21365245Smsmithextern int		amr_cam_attach(struct amr_softc *sc);
21465245Smsmithextern void		amr_cam_detach(struct amr_softc *sc);
21565245Smsmithextern int		amr_cam_command(struct amr_softc *sc, struct amr_command **acp);
21651974Smsmith
21751974Smsmith/*
21851974Smsmith * MegaRAID logical disk driver
21951974Smsmith */
22051974Smsmithstruct amrd_softc
22151974Smsmith{
22251974Smsmith    device_t		amrd_dev;
22358883Smsmith    dev_t		amrd_dev_t;
22451974Smsmith    struct amr_softc	*amrd_controller;
22551974Smsmith    struct amr_logdrive	*amrd_drive;
22651974Smsmith    struct disk		amrd_disk;
22751974Smsmith    struct devstat	amrd_stats;
22851974Smsmith    struct disklabel	amrd_label;
22951974Smsmith    int			amrd_unit;
23051974Smsmith    int			amrd_flags;
23165245Smsmith#define AMRD_OPEN	(1<<0)		/* drive is open (can't detach) */
23251974Smsmith};
23351974Smsmith
23451974Smsmith/*
23551974Smsmith * Interface between driver core and disk driver (should be using a bus?)
23651974Smsmith */
23765245Smsmithextern int	amr_submit_bio(struct amr_softc *sc, struct bio *bio);
23851974Smsmithextern void	amrd_intr(void *data);
23951974Smsmith
24065245Smsmith/********************************************************************************
24165245Smsmith * Enqueue/dequeue functions
24265245Smsmith */
24365245Smsmithstatic __inline void
24465245Smsmithamr_enqueue_bio(struct amr_softc *sc, struct bio *bio)
24565245Smsmith{
24665245Smsmith    int		s;
24765245Smsmith
24865245Smsmith    s = splbio();
24965245Smsmith    bioq_insert_tail(&sc->amr_bioq, bio);
25065245Smsmith    splx(s);
25165245Smsmith}
25265245Smsmith
25365245Smsmithstatic __inline struct bio *
25465245Smsmithamr_dequeue_bio(struct amr_softc *sc)
25565245Smsmith{
25665245Smsmith    struct bio	*bio;
25765245Smsmith    int		s;
25865245Smsmith
25965245Smsmith    s = splbio();
26065245Smsmith    if ((bio = bioq_first(&sc->amr_bioq)) != NULL)
26165245Smsmith	bioq_remove(&sc->amr_bioq, bio);
26265245Smsmith    splx(s);
26365245Smsmith    return(bio);
26465245Smsmith}
26565245Smsmith
26665245Smsmithstatic __inline void
26765245Smsmithamr_enqueue_ready(struct amr_command *ac)
26865245Smsmith{
26965245Smsmith    int		s;
27065245Smsmith
27165245Smsmith    s = splbio();
27265245Smsmith    TAILQ_INSERT_TAIL(&ac->ac_sc->amr_ready, ac, ac_link);
27365245Smsmith    splx(s);
27465245Smsmith}
27565245Smsmith
27665245Smsmithstatic __inline void
27765245Smsmithamr_requeue_ready(struct amr_command *ac)
27865245Smsmith{
27965245Smsmith    int		s;
28065245Smsmith
28165245Smsmith    s = splbio();
28265245Smsmith    TAILQ_INSERT_HEAD(&ac->ac_sc->amr_ready, ac, ac_link);
28365245Smsmith    splx(s);
28465245Smsmith}
28565245Smsmith
28665245Smsmithstatic __inline struct amr_command *
28765245Smsmithamr_dequeue_ready(struct amr_softc *sc)
28865245Smsmith{
28965245Smsmith    struct amr_command	*ac;
29065245Smsmith    int			s;
29165245Smsmith
29265245Smsmith    s = splbio();
29365245Smsmith    if ((ac = TAILQ_FIRST(&sc->amr_ready)) != NULL)
29465245Smsmith	TAILQ_REMOVE(&sc->amr_ready, ac, ac_link);
29565245Smsmith    splx(s);
29665245Smsmith    return(ac);
29765245Smsmith}
29865245Smsmith
29965245Smsmithstatic __inline void
30065245Smsmithamr_enqueue_completed(struct amr_command *ac)
30165245Smsmith{
30265245Smsmith    int		s;
30365245Smsmith
30465245Smsmith    s = splbio();
30565245Smsmith    TAILQ_INSERT_TAIL(&ac->ac_sc->amr_completed, ac, ac_link);
30665245Smsmith    splx(s);
30765245Smsmith}
30865245Smsmith
30965245Smsmithstatic __inline struct amr_command *
31065245Smsmithamr_dequeue_completed(struct amr_softc *sc)
31165245Smsmith{
31265245Smsmith    struct amr_command	*ac;
31365245Smsmith    int			s;
31465245Smsmith
31565245Smsmith    s = splbio();
31665245Smsmith    if ((ac = TAILQ_FIRST(&sc->amr_completed)) != NULL)
31765245Smsmith	TAILQ_REMOVE(&sc->amr_completed, ac, ac_link);
31865245Smsmith    splx(s);
31965245Smsmith    return(ac);
32065245Smsmith}
32165245Smsmith
32265245Smsmithstatic __inline void
32365245Smsmithamr_enqueue_free(struct amr_command *ac)
32465245Smsmith{
32565245Smsmith    int		s;
32665245Smsmith
32765245Smsmith    s = splbio();
32865245Smsmith    TAILQ_INSERT_TAIL(&ac->ac_sc->amr_freecmds, ac, ac_link);
32965245Smsmith    splx(s);
33065245Smsmith}
33165245Smsmith
33265245Smsmithstatic __inline struct amr_command *
33365245Smsmithamr_dequeue_free(struct amr_softc *sc)
33465245Smsmith{
33565245Smsmith    struct amr_command	*ac;
33665245Smsmith    int			s;
33765245Smsmith
33865245Smsmith    s = splbio();
33965245Smsmith    if ((ac = TAILQ_FIRST(&sc->amr_freecmds)) != NULL)
34065245Smsmith	TAILQ_REMOVE(&sc->amr_freecmds, ac, ac_link);
34165245Smsmith    splx(s);
34265245Smsmith    return(ac);
34365245Smsmith}
344