amrvar.h revision 138422
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 138422 2004-12-05 23:48:17Z scottl $
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)
191138422Sscottl#define AMR_STATE_QUEUE_FRZN	(1<<5)
19251974Smsmith
19351974Smsmith    /* per-controller queues */
19465245Smsmith    struct bio_queue_head 	amr_bioq;		/* pending I/O with no commands */
19565245Smsmith    TAILQ_HEAD(,amr_command)	amr_ready;		/* commands ready to be submitted */
19651974Smsmith    struct amr_command		*amr_busycmd[AMR_MAXCMD];
19765245Smsmith    int				amr_busyslots;
19865245Smsmith    TAILQ_HEAD(,amr_command)	amr_completed;
19960938Sjake    TAILQ_HEAD(,amr_command)	amr_freecmds;
20065245Smsmith    TAILQ_HEAD(,amr_command_cluster)	amr_cmd_clusters;
20151974Smsmith
20265245Smsmith    /* CAM attachments for passthrough */
20365245Smsmith    struct cam_sim		*amr_cam_sim[AMR_MAX_CHANNELS];
20465245Smsmith    TAILQ_HEAD(, ccb_hdr)	amr_cam_ccbq;
20558883Smsmith
20665245Smsmith    /* control device */
207130585Sphk    struct cdev *amr_dev_t;
20865245Smsmith
20951974Smsmith    /* controller type-specific support */
21051974Smsmith    int				amr_type;
21165245Smsmith#define AMR_TYPE_QUARTZ		(1<<0)
21265245Smsmith#define AMR_IS_QUARTZ(sc)	((sc)->amr_type & AMR_TYPE_QUARTZ)
21365245Smsmith#define AMR_TYPE_40LD		(1<<1)
21465245Smsmith#define AMR_IS_40LD(sc)		((sc)->amr_type & AMR_TYPE_40LD)
21565245Smsmith    int				(* amr_submit_command)(struct amr_softc *sc);
21651974Smsmith    int				(* amr_get_work)(struct amr_softc *sc, struct amr_mailbox *mbsave);
217107756Semoore    int				(*amr_poll_command)(struct amr_command *ac);
218138422Sscottl    int				(*amr_poll_command1)(struct amr_softc *sc, struct amr_command *ac);
219107756Semoore    int 			support_ext_cdb;	/* greater than 10 byte cdb support */
22065245Smsmith
22165245Smsmith    /* misc glue */
22265245Smsmith    struct intr_config_hook	amr_ich;		/* wait-for-interrupts probe hook */
22365245Smsmith    struct callout_handle	amr_timeout;		/* periodic status check */
22465245Smsmith#if __FreeBSD_version >= 500005
22565245Smsmith    struct task			amr_task_complete;	/* deferred-completion task */
22665245Smsmith#endif
22751974Smsmith};
22851974Smsmith
22951974Smsmith/*
23065245Smsmith * Interface between bus connections and driver core.
23158883Smsmith */
23265245Smsmithextern int              amr_attach(struct amr_softc *sc);
23365245Smsmithextern void		amr_free(struct amr_softc *sc);
23465245Smsmithextern int		amr_flush(struct amr_softc *sc);
23565245Smsmithextern int		amr_done(struct amr_softc *sc);
23665245Smsmithextern void		amr_startio(struct amr_softc *sc);
23758883Smsmith
23858883Smsmith/*
23965245Smsmith * Command buffer allocation.
24051974Smsmith */
24165245Smsmithextern struct amr_command	*amr_alloccmd(struct amr_softc *sc);
24265245Smsmithextern void			amr_releasecmd(struct amr_command *ac);
24351974Smsmith
24451974Smsmith/*
24565245Smsmith * CAM interface
24651974Smsmith */
24765245Smsmithextern int		amr_cam_attach(struct amr_softc *sc);
24865245Smsmithextern void		amr_cam_detach(struct amr_softc *sc);
24965245Smsmithextern int		amr_cam_command(struct amr_softc *sc, struct amr_command **acp);
25051974Smsmith
25151974Smsmith/*
25251974Smsmith * MegaRAID logical disk driver
25351974Smsmith */
25451974Smsmithstruct amrd_softc
25551974Smsmith{
25651974Smsmith    device_t		amrd_dev;
25751974Smsmith    struct amr_softc	*amrd_controller;
25851974Smsmith    struct amr_logdrive	*amrd_drive;
259125975Sphk    struct disk		*amrd_disk;
26051974Smsmith    int			amrd_unit;
26151974Smsmith};
26251974Smsmith
26351974Smsmith/*
26451974Smsmith * Interface between driver core and disk driver (should be using a bus?)
26551974Smsmith */
26665245Smsmithextern int	amr_submit_bio(struct amr_softc *sc, struct bio *bio);
267120988Spsextern int 	amr_dump_blocks(struct amr_softc *sc, int unit, u_int32_t lba, void *data, int blks);
26851974Smsmithextern void	amrd_intr(void *data);
26951974Smsmith
27065245Smsmith/********************************************************************************
27165245Smsmith * Enqueue/dequeue functions
27265245Smsmith */
27365245Smsmithstatic __inline void
27465245Smsmithamr_enqueue_bio(struct amr_softc *sc, struct bio *bio)
27565245Smsmith{
27665245Smsmith    int		s;
27765245Smsmith
27865245Smsmith    s = splbio();
27965245Smsmith    bioq_insert_tail(&sc->amr_bioq, bio);
28065245Smsmith    splx(s);
28165245Smsmith}
28265245Smsmith
28365245Smsmithstatic __inline struct bio *
28465245Smsmithamr_dequeue_bio(struct amr_softc *sc)
28565245Smsmith{
28665245Smsmith    struct bio	*bio;
28765245Smsmith    int		s;
28865245Smsmith
28965245Smsmith    s = splbio();
29065245Smsmith    if ((bio = bioq_first(&sc->amr_bioq)) != NULL)
29165245Smsmith	bioq_remove(&sc->amr_bioq, bio);
29265245Smsmith    splx(s);
29365245Smsmith    return(bio);
29465245Smsmith}
29565245Smsmith
29665245Smsmithstatic __inline void
29765245Smsmithamr_enqueue_ready(struct amr_command *ac)
29865245Smsmith{
29965245Smsmith    int		s;
30065245Smsmith
30165245Smsmith    s = splbio();
30265245Smsmith    TAILQ_INSERT_TAIL(&ac->ac_sc->amr_ready, ac, ac_link);
30365245Smsmith    splx(s);
30465245Smsmith}
30565245Smsmith
30665245Smsmithstatic __inline void
30765245Smsmithamr_requeue_ready(struct amr_command *ac)
30865245Smsmith{
30965245Smsmith    int		s;
31065245Smsmith
31165245Smsmith    s = splbio();
31265245Smsmith    TAILQ_INSERT_HEAD(&ac->ac_sc->amr_ready, ac, ac_link);
31365245Smsmith    splx(s);
31465245Smsmith}
31565245Smsmith
31665245Smsmithstatic __inline struct amr_command *
31765245Smsmithamr_dequeue_ready(struct amr_softc *sc)
31865245Smsmith{
31965245Smsmith    struct amr_command	*ac;
32065245Smsmith    int			s;
32165245Smsmith
32265245Smsmith    s = splbio();
32365245Smsmith    if ((ac = TAILQ_FIRST(&sc->amr_ready)) != NULL)
32465245Smsmith	TAILQ_REMOVE(&sc->amr_ready, ac, ac_link);
32565245Smsmith    splx(s);
32665245Smsmith    return(ac);
32765245Smsmith}
32865245Smsmith
32965245Smsmithstatic __inline void
33065245Smsmithamr_enqueue_completed(struct amr_command *ac)
33165245Smsmith{
33265245Smsmith    int		s;
33365245Smsmith
33465245Smsmith    s = splbio();
33565245Smsmith    TAILQ_INSERT_TAIL(&ac->ac_sc->amr_completed, ac, ac_link);
33665245Smsmith    splx(s);
33765245Smsmith}
33865245Smsmith
33965245Smsmithstatic __inline struct amr_command *
34065245Smsmithamr_dequeue_completed(struct amr_softc *sc)
34165245Smsmith{
34265245Smsmith    struct amr_command	*ac;
34365245Smsmith    int			s;
34465245Smsmith
34565245Smsmith    s = splbio();
34665245Smsmith    if ((ac = TAILQ_FIRST(&sc->amr_completed)) != NULL)
34765245Smsmith	TAILQ_REMOVE(&sc->amr_completed, ac, ac_link);
34865245Smsmith    splx(s);
34965245Smsmith    return(ac);
35065245Smsmith}
35165245Smsmith
35265245Smsmithstatic __inline void
35365245Smsmithamr_enqueue_free(struct amr_command *ac)
35465245Smsmith{
35565245Smsmith    int		s;
35665245Smsmith
35765245Smsmith    s = splbio();
35865245Smsmith    TAILQ_INSERT_TAIL(&ac->ac_sc->amr_freecmds, ac, ac_link);
35965245Smsmith    splx(s);
36065245Smsmith}
36165245Smsmith
36265245Smsmithstatic __inline struct amr_command *
36365245Smsmithamr_dequeue_free(struct amr_softc *sc)
36465245Smsmith{
36565245Smsmith    struct amr_command	*ac;
36665245Smsmith    int			s;
36765245Smsmith
36865245Smsmith    s = splbio();
36965245Smsmith    if ((ac = TAILQ_FIRST(&sc->amr_freecmds)) != NULL)
37065245Smsmith	TAILQ_REMOVE(&sc->amr_freecmds, ac, ac_link);
37165245Smsmith    splx(s);
37265245Smsmith    return(ac);
37365245Smsmith}
374