amrvar.h revision 131394
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 *
27106225Semoore * Copyright (c) 2002 Eric Moore
28106225Semoore * Copyright (c) 2002 LSI Logic Corporation
29106225Semoore * All rights reserved.
30106225Semoore *
31106225Semoore * Redistribution and use in source and binary forms, with or without
32106225Semoore * modification, are permitted provided that the following conditions
33106225Semoore * are met:
34106225Semoore * 1. Redistributions of source code must retain the above copyright
35106225Semoore *    notice, this list of conditions and the following disclaimer.
36106225Semoore * 2. Redistributions in binary form must reproduce the above copyright
37106225Semoore *    notice, this list of conditions and the following disclaimer in the
38106225Semoore *    documentation and/or other materials provided with the distribution.
39105419Semoore * 3. The party using or redistributing the source code and binary forms
40106225Semoore *    agrees to the disclaimer below and the terms and conditions set forth
41105419Semoore *    herein.
42105419Semoore *
43106225Semoore * THIS SOFTWARE IS PROVIDED BY THE AUTHOR AND CONTRIBUTORS ``AS IS'' AND
44106225Semoore * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
45106225Semoore * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
46106225Semoore * ARE DISCLAIMED.  IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE
47106225Semoore * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
48106225Semoore * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
49106225Semoore * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
50106225Semoore * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
51106225Semoore * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
52106225Semoore * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
53106225Semoore * SUCH DAMAGE.
54105419Semoore *
55106225Semoore *
5651974Smsmith *      $FreeBSD: head/sys/dev/amr/amrvar.h 131394 2004-07-01 06:56:10Z ps $
5751974Smsmith */
5851974Smsmith
5965245Smsmith#if __FreeBSD_version >= 500005
6065245Smsmith# include <sys/taskqueue.h>
61112946Sphk# include <geom/geom_disk.h>
6265245Smsmith#endif
6351974Smsmith
6465245Smsmith#ifdef AMR_DEBUG
6587599Sobrien# define debug(level, fmt, args...)	do {if (level <= AMR_DEBUG) printf("%s: " fmt "\n", __func__ , ##args);} while(0)
6687599Sobrien# define debug_called(level)		do {if (level <= AMR_DEBUG) printf("%s: called\n", __func__);} while(0)
6765245Smsmith#else
6865245Smsmith# define debug(level, fmt, args...)
6965245Smsmith# define debug_called(level)
7065245Smsmith#endif
7187599Sobrien#define xdebug(fmt, args...)	printf("%s: " fmt "\n", __func__ , ##args)
7251974Smsmith
7351974Smsmith/*
7451974Smsmith * Per-logical-drive datastructure
7551974Smsmith */
7651974Smsmithstruct amr_logdrive
7751974Smsmith{
7851974Smsmith    u_int32_t	al_size;
7951974Smsmith    int		al_state;
8051974Smsmith    int		al_properties;
8151974Smsmith
8251974Smsmith    /* synthetic geometry */
8351974Smsmith    int		al_cylinders;
8451974Smsmith    int		al_heads;
8551974Smsmith    int		al_sectors;
8651974Smsmith
8751974Smsmith    /* driver */
8851974Smsmith    device_t	al_disk;
8951974Smsmith};
9051974Smsmith
9165245Smsmith/*
9265245Smsmith * Due to the difficulty of using the zone allocator to create a new
9365245Smsmith * zone from within a module, we use our own clustering to reduce
9465245Smsmith * memory wastage due to allocating lots of these small structures.
9565245Smsmith *
9665245Smsmith * 16k gives us a little under 200 command structures, which should
9765245Smsmith * normally be plenty.  We will grab more if we need them.
9865245Smsmith */
9951974Smsmith
10065245Smsmith#define AMR_CMD_CLUSTERSIZE	(16 * 1024)
10165245Smsmith
10251974Smsmith/*
10351974Smsmith * Per-command control structure.
10451974Smsmith */
10551974Smsmithstruct amr_command
10651974Smsmith{
10760938Sjake    TAILQ_ENTRY(amr_command)	ac_link;
10851974Smsmith
10951974Smsmith    struct amr_softc		*ac_sc;
11051974Smsmith    u_int8_t			ac_slot;
11165245Smsmith    int				ac_status;	/* command completion status */
11251974Smsmith    struct amr_mailbox		ac_mailbox;
11351974Smsmith    int				ac_flags;
11451974Smsmith#define AMR_CMD_DATAIN		(1<<0)
11551974Smsmith#define AMR_CMD_DATAOUT		(1<<1)
11665245Smsmith#define AMR_CMD_CCB_DATAIN	(1<<2)
11765245Smsmith#define AMR_CMD_CCB_DATAOUT	(1<<3)
11865245Smsmith#define AMR_CMD_PRIORITY	(1<<4)
11965245Smsmith#define AMR_CMD_MAPPED		(1<<5)
12065245Smsmith#define AMR_CMD_SLEEP		(1<<6)
12165245Smsmith#define AMR_CMD_BUSY		(1<<7)
12251974Smsmith
12365245Smsmith    struct bio			*ac_bio;
12465245Smsmith
12551974Smsmith    void			*ac_data;
12651974Smsmith    size_t			ac_length;
12751974Smsmith    bus_dmamap_t		ac_dmamap;
12851974Smsmith    u_int32_t			ac_dataphys;
12951974Smsmith
13065245Smsmith    void			*ac_ccb_data;
13165245Smsmith    size_t			ac_ccb_length;
13265245Smsmith    bus_dmamap_t		ac_ccb_dmamap;
13365245Smsmith    u_int32_t			ac_ccb_dataphys;
13465245Smsmith
13551974Smsmith    void			(* ac_complete)(struct amr_command *ac);
136105419Semoore    void			*ac_private;
13751974Smsmith};
13851974Smsmith
13965245Smsmithstruct amr_command_cluster
14065245Smsmith{
14165245Smsmith    TAILQ_ENTRY(amr_command_cluster)	acc_link;
14265245Smsmith    struct amr_command		acc_command[0];
14365245Smsmith};
14465245Smsmith
14565245Smsmith#define AMR_CMD_CLUSTERCOUNT	((AMR_CMD_CLUSTERSIZE - sizeof(struct amr_command_cluster)) /	\
14665245Smsmith				 sizeof(struct amr_command))
14765245Smsmith
14865245Smsmith/*
14965245Smsmith * Per-controller-instance data
15065245Smsmith */
15151974Smsmithstruct amr_softc
15251974Smsmith{
15351974Smsmith    /* bus attachments */
15451974Smsmith    device_t			amr_dev;
15551974Smsmith    struct resource		*amr_reg;		/* control registers */
15651974Smsmith    bus_space_handle_t		amr_bhandle;
15751974Smsmith    bus_space_tag_t		amr_btag;
15851974Smsmith    bus_dma_tag_t		amr_parent_dmat;	/* parent DMA tag */
15951974Smsmith    bus_dma_tag_t		amr_buffer_dmat;	/* data buffer DMA tag */
16051974Smsmith    struct resource		*amr_irq;		/* interrupt */
16151974Smsmith    void			*amr_intr;
16251974Smsmith
16351974Smsmith    /* mailbox */
16458496Smsmith    volatile struct amr_mailbox		*amr_mailbox;
16558496Smsmith    volatile struct amr_mailbox64	*amr_mailbox64;
16651974Smsmith    u_int32_t			amr_mailboxphys;
16751974Smsmith    bus_dma_tag_t		amr_mailbox_dmat;
16851974Smsmith    bus_dmamap_t		amr_mailbox_dmamap;
16951974Smsmith
17051974Smsmith    /* scatter/gather lists and their controller-visible mappings */
17151974Smsmith    struct amr_sgentry		*amr_sgtable;		/* s/g lists */
17251974Smsmith    u_int32_t			amr_sgbusaddr;		/* s/g table base address in bus space */
17351974Smsmith    bus_dma_tag_t		amr_sg_dmat;		/* s/g buffer DMA tag */
17451974Smsmith    bus_dmamap_t		amr_sg_dmamap;		/* map for s/g buffers */
17551974Smsmith
17651974Smsmith    /* controller limits and features */
17751974Smsmith    int				amr_maxio;		/* maximum number of I/O transactions */
17851974Smsmith    int				amr_maxdrives;		/* max number of logical drives */
17965245Smsmith    int				amr_maxchan;		/* count of SCSI channels */
18051974Smsmith
18151974Smsmith    /* connected logical drives */
18251974Smsmith    struct amr_logdrive		amr_drive[AMR_MAXLD];
18351974Smsmith
18465245Smsmith    /* controller state */
18551974Smsmith    int				amr_state;
18651974Smsmith#define AMR_STATE_OPEN		(1<<0)
18751974Smsmith#define AMR_STATE_SUSPEND	(1<<1)
18851974Smsmith#define AMR_STATE_INTEN		(1<<2)
18951974Smsmith#define AMR_STATE_SHUTDOWN	(1<<3)
190131394Sps#define AMR_STATE_CRASHDUMP	(1<<4)
19151974Smsmith
19251974Smsmith    /* per-controller queues */
19365245Smsmith    struct bio_queue_head 	amr_bioq;		/* pending I/O with no commands */
19465245Smsmith    TAILQ_HEAD(,amr_command)	amr_ready;		/* commands ready to be submitted */
19551974Smsmith    struct amr_command		*amr_busycmd[AMR_MAXCMD];
19665245Smsmith    int				amr_busyslots;
19765245Smsmith    TAILQ_HEAD(,amr_command)	amr_completed;
19860938Sjake    TAILQ_HEAD(,amr_command)	amr_freecmds;
19965245Smsmith    TAILQ_HEAD(,amr_command_cluster)	amr_cmd_clusters;
20051974Smsmith
20165245Smsmith    /* CAM attachments for passthrough */
20265245Smsmith    struct cam_sim		*amr_cam_sim[AMR_MAX_CHANNELS];
20365245Smsmith    TAILQ_HEAD(, ccb_hdr)	amr_cam_ccbq;
20458883Smsmith
20565245Smsmith    /* control device */
206130585Sphk    struct cdev *amr_dev_t;
20765245Smsmith
20851974Smsmith    /* controller type-specific support */
20951974Smsmith    int				amr_type;
21065245Smsmith#define AMR_TYPE_QUARTZ		(1<<0)
21165245Smsmith#define AMR_IS_QUARTZ(sc)	((sc)->amr_type & AMR_TYPE_QUARTZ)
21265245Smsmith#define AMR_TYPE_40LD		(1<<1)
21365245Smsmith#define AMR_IS_40LD(sc)		((sc)->amr_type & AMR_TYPE_40LD)
21465245Smsmith    int				(* amr_submit_command)(struct amr_softc *sc);
21551974Smsmith    int				(* amr_get_work)(struct amr_softc *sc, struct amr_mailbox *mbsave);
216107756Semoore    int				(*amr_poll_command)(struct amr_command *ac);
217107756Semoore    int 			support_ext_cdb;	/* greater than 10 byte cdb support */
21865245Smsmith
21965245Smsmith    /* misc glue */
22065245Smsmith    struct intr_config_hook	amr_ich;		/* wait-for-interrupts probe hook */
22165245Smsmith    struct callout_handle	amr_timeout;		/* periodic status check */
22265245Smsmith#if __FreeBSD_version >= 500005
22365245Smsmith    struct task			amr_task_complete;	/* deferred-completion task */
22465245Smsmith#endif
22551974Smsmith};
22651974Smsmith
22751974Smsmith/*
22865245Smsmith * Interface between bus connections and driver core.
22958883Smsmith */
23065245Smsmithextern int              amr_attach(struct amr_softc *sc);
23165245Smsmithextern void		amr_free(struct amr_softc *sc);
23265245Smsmithextern int		amr_flush(struct amr_softc *sc);
23365245Smsmithextern int		amr_done(struct amr_softc *sc);
23465245Smsmithextern void		amr_startio(struct amr_softc *sc);
23558883Smsmith
23658883Smsmith/*
23765245Smsmith * Command buffer allocation.
23851974Smsmith */
23965245Smsmithextern struct amr_command	*amr_alloccmd(struct amr_softc *sc);
24065245Smsmithextern void			amr_releasecmd(struct amr_command *ac);
24151974Smsmith
24251974Smsmith/*
24365245Smsmith * CAM interface
24451974Smsmith */
24565245Smsmithextern int		amr_cam_attach(struct amr_softc *sc);
24665245Smsmithextern void		amr_cam_detach(struct amr_softc *sc);
24765245Smsmithextern int		amr_cam_command(struct amr_softc *sc, struct amr_command **acp);
24851974Smsmith
24951974Smsmith/*
25051974Smsmith * MegaRAID logical disk driver
25151974Smsmith */
25251974Smsmithstruct amrd_softc
25351974Smsmith{
25451974Smsmith    device_t		amrd_dev;
25551974Smsmith    struct amr_softc	*amrd_controller;
25651974Smsmith    struct amr_logdrive	*amrd_drive;
257125975Sphk    struct disk		*amrd_disk;
25851974Smsmith    int			amrd_unit;
25951974Smsmith};
26051974Smsmith
26151974Smsmith/*
26251974Smsmith * Interface between driver core and disk driver (should be using a bus?)
26351974Smsmith */
26465245Smsmithextern int	amr_submit_bio(struct amr_softc *sc, struct bio *bio);
265120988Spsextern int 	amr_dump_blocks(struct amr_softc *sc, int unit, u_int32_t lba, void *data, int blks);
26651974Smsmithextern void	amrd_intr(void *data);
26751974Smsmith
26865245Smsmith/********************************************************************************
26965245Smsmith * Enqueue/dequeue functions
27065245Smsmith */
27165245Smsmithstatic __inline void
27265245Smsmithamr_enqueue_bio(struct amr_softc *sc, struct bio *bio)
27365245Smsmith{
27465245Smsmith    int		s;
27565245Smsmith
27665245Smsmith    s = splbio();
27765245Smsmith    bioq_insert_tail(&sc->amr_bioq, bio);
27865245Smsmith    splx(s);
27965245Smsmith}
28065245Smsmith
28165245Smsmithstatic __inline struct bio *
28265245Smsmithamr_dequeue_bio(struct amr_softc *sc)
28365245Smsmith{
28465245Smsmith    struct bio	*bio;
28565245Smsmith    int		s;
28665245Smsmith
28765245Smsmith    s = splbio();
28865245Smsmith    if ((bio = bioq_first(&sc->amr_bioq)) != NULL)
28965245Smsmith	bioq_remove(&sc->amr_bioq, bio);
29065245Smsmith    splx(s);
29165245Smsmith    return(bio);
29265245Smsmith}
29365245Smsmith
29465245Smsmithstatic __inline void
29565245Smsmithamr_enqueue_ready(struct amr_command *ac)
29665245Smsmith{
29765245Smsmith    int		s;
29865245Smsmith
29965245Smsmith    s = splbio();
30065245Smsmith    TAILQ_INSERT_TAIL(&ac->ac_sc->amr_ready, ac, ac_link);
30165245Smsmith    splx(s);
30265245Smsmith}
30365245Smsmith
30465245Smsmithstatic __inline void
30565245Smsmithamr_requeue_ready(struct amr_command *ac)
30665245Smsmith{
30765245Smsmith    int		s;
30865245Smsmith
30965245Smsmith    s = splbio();
31065245Smsmith    TAILQ_INSERT_HEAD(&ac->ac_sc->amr_ready, ac, ac_link);
31165245Smsmith    splx(s);
31265245Smsmith}
31365245Smsmith
31465245Smsmithstatic __inline struct amr_command *
31565245Smsmithamr_dequeue_ready(struct amr_softc *sc)
31665245Smsmith{
31765245Smsmith    struct amr_command	*ac;
31865245Smsmith    int			s;
31965245Smsmith
32065245Smsmith    s = splbio();
32165245Smsmith    if ((ac = TAILQ_FIRST(&sc->amr_ready)) != NULL)
32265245Smsmith	TAILQ_REMOVE(&sc->amr_ready, ac, ac_link);
32365245Smsmith    splx(s);
32465245Smsmith    return(ac);
32565245Smsmith}
32665245Smsmith
32765245Smsmithstatic __inline void
32865245Smsmithamr_enqueue_completed(struct amr_command *ac)
32965245Smsmith{
33065245Smsmith    int		s;
33165245Smsmith
33265245Smsmith    s = splbio();
33365245Smsmith    TAILQ_INSERT_TAIL(&ac->ac_sc->amr_completed, ac, ac_link);
33465245Smsmith    splx(s);
33565245Smsmith}
33665245Smsmith
33765245Smsmithstatic __inline struct amr_command *
33865245Smsmithamr_dequeue_completed(struct amr_softc *sc)
33965245Smsmith{
34065245Smsmith    struct amr_command	*ac;
34165245Smsmith    int			s;
34265245Smsmith
34365245Smsmith    s = splbio();
34465245Smsmith    if ((ac = TAILQ_FIRST(&sc->amr_completed)) != NULL)
34565245Smsmith	TAILQ_REMOVE(&sc->amr_completed, ac, ac_link);
34665245Smsmith    splx(s);
34765245Smsmith    return(ac);
34865245Smsmith}
34965245Smsmith
35065245Smsmithstatic __inline void
35165245Smsmithamr_enqueue_free(struct amr_command *ac)
35265245Smsmith{
35365245Smsmith    int		s;
35465245Smsmith
35565245Smsmith    s = splbio();
35665245Smsmith    TAILQ_INSERT_TAIL(&ac->ac_sc->amr_freecmds, ac, ac_link);
35765245Smsmith    splx(s);
35865245Smsmith}
35965245Smsmith
36065245Smsmithstatic __inline struct amr_command *
36165245Smsmithamr_dequeue_free(struct amr_softc *sc)
36265245Smsmith{
36365245Smsmith    struct amr_command	*ac;
36465245Smsmith    int			s;
36565245Smsmith
36665245Smsmith    s = splbio();
36765245Smsmith    if ((ac = TAILQ_FIRST(&sc->amr_freecmds)) != NULL)
36865245Smsmith	TAILQ_REMOVE(&sc->amr_freecmds, ac, ac_link);
36965245Smsmith    splx(s);
37065245Smsmith    return(ac);
37165245Smsmith}
372