amrvar.h revision 140688
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 140688 2005-01-23 23:25:41Z scottl $
5751974Smsmith */
5851974Smsmith
5965245Smsmith#if __FreeBSD_version >= 500005
60112946Sphk# include <geom/geom_disk.h>
61140340Sscottl# include <sys/lock.h>
62140340Sscottl# include <sys/mutex.h>
6365245Smsmith#endif
6451974Smsmith
65140688Sscottl#define LSI_DESC_PCI "LSILogic MegaRAID 1.51"
66140688Sscottl
6765245Smsmith#ifdef AMR_DEBUG
6887599Sobrien# define debug(level, fmt, args...)	do {if (level <= AMR_DEBUG) printf("%s: " fmt "\n", __func__ , ##args);} while(0)
6987599Sobrien# define debug_called(level)		do {if (level <= AMR_DEBUG) printf("%s: called\n", __func__);} while(0)
7065245Smsmith#else
7165245Smsmith# define debug(level, fmt, args...)
7265245Smsmith# define debug_called(level)
7365245Smsmith#endif
7487599Sobrien#define xdebug(fmt, args...)	printf("%s: " fmt "\n", __func__ , ##args)
7551974Smsmith
7651974Smsmith/*
7751974Smsmith * Per-logical-drive datastructure
7851974Smsmith */
7951974Smsmithstruct amr_logdrive
8051974Smsmith{
8151974Smsmith    u_int32_t	al_size;
8251974Smsmith    int		al_state;
8351974Smsmith    int		al_properties;
8451974Smsmith
8551974Smsmith    /* synthetic geometry */
8651974Smsmith    int		al_cylinders;
8751974Smsmith    int		al_heads;
8851974Smsmith    int		al_sectors;
8951974Smsmith
9051974Smsmith    /* driver */
9151974Smsmith    device_t	al_disk;
9251974Smsmith};
9351974Smsmith
9465245Smsmith/*
9565245Smsmith * Due to the difficulty of using the zone allocator to create a new
9665245Smsmith * zone from within a module, we use our own clustering to reduce
9765245Smsmith * memory wastage due to allocating lots of these small structures.
9865245Smsmith *
9965245Smsmith * 16k gives us a little under 200 command structures, which should
10065245Smsmith * normally be plenty.  We will grab more if we need them.
10165245Smsmith */
10251974Smsmith
10365245Smsmith#define AMR_CMD_CLUSTERSIZE	(16 * 1024)
10465245Smsmith
10551974Smsmith/*
10651974Smsmith * Per-command control structure.
10751974Smsmith */
10851974Smsmithstruct amr_command
10951974Smsmith{
11060938Sjake    TAILQ_ENTRY(amr_command)	ac_link;
11151974Smsmith
11251974Smsmith    struct amr_softc		*ac_sc;
11351974Smsmith    u_int8_t			ac_slot;
11465245Smsmith    int				ac_status;	/* command completion status */
11551974Smsmith    struct amr_mailbox		ac_mailbox;
11651974Smsmith    int				ac_flags;
11751974Smsmith#define AMR_CMD_DATAIN		(1<<0)
11851974Smsmith#define AMR_CMD_DATAOUT		(1<<1)
11965245Smsmith#define AMR_CMD_CCB_DATAIN	(1<<2)
12065245Smsmith#define AMR_CMD_CCB_DATAOUT	(1<<3)
12165245Smsmith#define AMR_CMD_PRIORITY	(1<<4)
12265245Smsmith#define AMR_CMD_MAPPED		(1<<5)
12365245Smsmith#define AMR_CMD_SLEEP		(1<<6)
12465245Smsmith#define AMR_CMD_BUSY		(1<<7)
12551974Smsmith
12665245Smsmith    struct bio			*ac_bio;
12765245Smsmith
12851974Smsmith    void			*ac_data;
12951974Smsmith    size_t			ac_length;
13051974Smsmith    bus_dmamap_t		ac_dmamap;
13151974Smsmith    u_int32_t			ac_dataphys;
13251974Smsmith
13365245Smsmith    void			*ac_ccb_data;
13465245Smsmith    size_t			ac_ccb_length;
13565245Smsmith    bus_dmamap_t		ac_ccb_dmamap;
13665245Smsmith    u_int32_t			ac_ccb_dataphys;
13765245Smsmith
13851974Smsmith    void			(* ac_complete)(struct amr_command *ac);
139105419Semoore    void			*ac_private;
14051974Smsmith};
14151974Smsmith
14265245Smsmithstruct amr_command_cluster
14365245Smsmith{
14465245Smsmith    TAILQ_ENTRY(amr_command_cluster)	acc_link;
14565245Smsmith    struct amr_command		acc_command[0];
14665245Smsmith};
14765245Smsmith
14865245Smsmith#define AMR_CMD_CLUSTERCOUNT	((AMR_CMD_CLUSTERSIZE - sizeof(struct amr_command_cluster)) /	\
14965245Smsmith				 sizeof(struct amr_command))
15065245Smsmith
15165245Smsmith/*
15265245Smsmith * Per-controller-instance data
15365245Smsmith */
15451974Smsmithstruct amr_softc
15551974Smsmith{
15651974Smsmith    /* bus attachments */
15751974Smsmith    device_t			amr_dev;
15851974Smsmith    struct resource		*amr_reg;		/* control registers */
15951974Smsmith    bus_space_handle_t		amr_bhandle;
16051974Smsmith    bus_space_tag_t		amr_btag;
16151974Smsmith    bus_dma_tag_t		amr_parent_dmat;	/* parent DMA tag */
16251974Smsmith    bus_dma_tag_t		amr_buffer_dmat;	/* data buffer DMA tag */
16351974Smsmith    struct resource		*amr_irq;		/* interrupt */
16451974Smsmith    void			*amr_intr;
16551974Smsmith
16651974Smsmith    /* mailbox */
16758496Smsmith    volatile struct amr_mailbox		*amr_mailbox;
16858496Smsmith    volatile struct amr_mailbox64	*amr_mailbox64;
16951974Smsmith    u_int32_t			amr_mailboxphys;
17051974Smsmith    bus_dma_tag_t		amr_mailbox_dmat;
17151974Smsmith    bus_dmamap_t		amr_mailbox_dmamap;
17251974Smsmith
17351974Smsmith    /* scatter/gather lists and their controller-visible mappings */
17451974Smsmith    struct amr_sgentry		*amr_sgtable;		/* s/g lists */
17551974Smsmith    u_int32_t			amr_sgbusaddr;		/* s/g table base address in bus space */
17651974Smsmith    bus_dma_tag_t		amr_sg_dmat;		/* s/g buffer DMA tag */
17751974Smsmith    bus_dmamap_t		amr_sg_dmamap;		/* map for s/g buffers */
17851974Smsmith
17951974Smsmith    /* controller limits and features */
180140340Sscottl    int				amr_nextslot;		/* Next slot to use for newly allocated commands */
18151974Smsmith    int				amr_maxio;		/* maximum number of I/O transactions */
18251974Smsmith    int				amr_maxdrives;		/* max number of logical drives */
18365245Smsmith    int				amr_maxchan;		/* count of SCSI channels */
18451974Smsmith
18551974Smsmith    /* connected logical drives */
18651974Smsmith    struct amr_logdrive		amr_drive[AMR_MAXLD];
18751974Smsmith
18865245Smsmith    /* controller state */
18951974Smsmith    int				amr_state;
19051974Smsmith#define AMR_STATE_OPEN		(1<<0)
19151974Smsmith#define AMR_STATE_SUSPEND	(1<<1)
19251974Smsmith#define AMR_STATE_INTEN		(1<<2)
19351974Smsmith#define AMR_STATE_SHUTDOWN	(1<<3)
194131394Sps#define AMR_STATE_CRASHDUMP	(1<<4)
195138422Sscottl#define AMR_STATE_QUEUE_FRZN	(1<<5)
19651974Smsmith
19751974Smsmith    /* per-controller queues */
19865245Smsmith    struct bio_queue_head 	amr_bioq;		/* pending I/O with no commands */
19965245Smsmith    TAILQ_HEAD(,amr_command)	amr_ready;		/* commands ready to be submitted */
20051974Smsmith    struct amr_command		*amr_busycmd[AMR_MAXCMD];
20165245Smsmith    int				amr_busyslots;
20265245Smsmith    TAILQ_HEAD(,amr_command)	amr_completed;
20360938Sjake    TAILQ_HEAD(,amr_command)	amr_freecmds;
20465245Smsmith    TAILQ_HEAD(,amr_command_cluster)	amr_cmd_clusters;
20551974Smsmith
20665245Smsmith    /* CAM attachments for passthrough */
20765245Smsmith    struct cam_sim		*amr_cam_sim[AMR_MAX_CHANNELS];
20865245Smsmith    TAILQ_HEAD(, ccb_hdr)	amr_cam_ccbq;
209139952Sdwhite    struct cam_devq		*amr_cam_devq;
21058883Smsmith
21165245Smsmith    /* control device */
212130585Sphk    struct cdev *amr_dev_t;
21365245Smsmith
21451974Smsmith    /* controller type-specific support */
21551974Smsmith    int				amr_type;
21665245Smsmith#define AMR_TYPE_QUARTZ		(1<<0)
21765245Smsmith#define AMR_IS_QUARTZ(sc)	((sc)->amr_type & AMR_TYPE_QUARTZ)
21865245Smsmith#define AMR_TYPE_40LD		(1<<1)
21965245Smsmith#define AMR_IS_40LD(sc)		((sc)->amr_type & AMR_TYPE_40LD)
22065245Smsmith    int				(* amr_submit_command)(struct amr_softc *sc);
22151974Smsmith    int				(* amr_get_work)(struct amr_softc *sc, struct amr_mailbox *mbsave);
222107756Semoore    int				(*amr_poll_command)(struct amr_command *ac);
223138422Sscottl    int				(*amr_poll_command1)(struct amr_softc *sc, struct amr_command *ac);
224107756Semoore    int 			support_ext_cdb;	/* greater than 10 byte cdb support */
22565245Smsmith
22665245Smsmith    /* misc glue */
22765245Smsmith    struct intr_config_hook	amr_ich;		/* wait-for-interrupts probe hook */
22865245Smsmith    struct callout_handle	amr_timeout;		/* periodic status check */
229140340Sscottl    struct mtx			amr_io_lock;
23051974Smsmith};
23151974Smsmith
23251974Smsmith/*
23365245Smsmith * Interface between bus connections and driver core.
23458883Smsmith */
23565245Smsmithextern int              amr_attach(struct amr_softc *sc);
23665245Smsmithextern void		amr_free(struct amr_softc *sc);
23765245Smsmithextern int		amr_flush(struct amr_softc *sc);
23865245Smsmithextern int		amr_done(struct amr_softc *sc);
23965245Smsmithextern void		amr_startio(struct amr_softc *sc);
24058883Smsmith
24158883Smsmith/*
24265245Smsmith * Command buffer allocation.
24351974Smsmith */
24465245Smsmithextern struct amr_command	*amr_alloccmd(struct amr_softc *sc);
24565245Smsmithextern void			amr_releasecmd(struct amr_command *ac);
24651974Smsmith
24751974Smsmith/*
24865245Smsmith * CAM interface
24951974Smsmith */
25065245Smsmithextern int		amr_cam_attach(struct amr_softc *sc);
25165245Smsmithextern void		amr_cam_detach(struct amr_softc *sc);
25265245Smsmithextern int		amr_cam_command(struct amr_softc *sc, struct amr_command **acp);
25351974Smsmith
25451974Smsmith/*
25551974Smsmith * MegaRAID logical disk driver
25651974Smsmith */
25751974Smsmithstruct amrd_softc
25851974Smsmith{
25951974Smsmith    device_t		amrd_dev;
26051974Smsmith    struct amr_softc	*amrd_controller;
26151974Smsmith    struct amr_logdrive	*amrd_drive;
262125975Sphk    struct disk		*amrd_disk;
26351974Smsmith    int			amrd_unit;
26451974Smsmith};
26551974Smsmith
26651974Smsmith/*
26751974Smsmith * Interface between driver core and disk driver (should be using a bus?)
26851974Smsmith */
26965245Smsmithextern int	amr_submit_bio(struct amr_softc *sc, struct bio *bio);
270120988Spsextern int 	amr_dump_blocks(struct amr_softc *sc, int unit, u_int32_t lba, void *data, int blks);
27151974Smsmithextern void	amrd_intr(void *data);
27251974Smsmith
27365245Smsmith/********************************************************************************
27465245Smsmith * Enqueue/dequeue functions
27565245Smsmith */
27665245Smsmithstatic __inline void
27765245Smsmithamr_enqueue_bio(struct amr_softc *sc, struct bio *bio)
27865245Smsmith{
27965245Smsmith    int		s;
28065245Smsmith
28165245Smsmith    s = splbio();
28265245Smsmith    bioq_insert_tail(&sc->amr_bioq, bio);
28365245Smsmith    splx(s);
28465245Smsmith}
28565245Smsmith
28665245Smsmithstatic __inline struct bio *
28765245Smsmithamr_dequeue_bio(struct amr_softc *sc)
28865245Smsmith{
28965245Smsmith    struct bio	*bio;
29065245Smsmith    int		s;
29165245Smsmith
29265245Smsmith    s = splbio();
29365245Smsmith    if ((bio = bioq_first(&sc->amr_bioq)) != NULL)
29465245Smsmith	bioq_remove(&sc->amr_bioq, bio);
29565245Smsmith    splx(s);
29665245Smsmith    return(bio);
29765245Smsmith}
29865245Smsmith
29965245Smsmithstatic __inline void
30065245Smsmithamr_enqueue_ready(struct amr_command *ac)
30165245Smsmith{
30265245Smsmith    int		s;
30365245Smsmith
30465245Smsmith    s = splbio();
30565245Smsmith    TAILQ_INSERT_TAIL(&ac->ac_sc->amr_ready, ac, ac_link);
30665245Smsmith    splx(s);
30765245Smsmith}
30865245Smsmith
30965245Smsmithstatic __inline void
31065245Smsmithamr_requeue_ready(struct amr_command *ac)
31165245Smsmith{
31265245Smsmith    int		s;
31365245Smsmith
31465245Smsmith    s = splbio();
31565245Smsmith    TAILQ_INSERT_HEAD(&ac->ac_sc->amr_ready, ac, ac_link);
31665245Smsmith    splx(s);
31765245Smsmith}
31865245Smsmith
31965245Smsmithstatic __inline struct amr_command *
32065245Smsmithamr_dequeue_ready(struct amr_softc *sc)
32165245Smsmith{
32265245Smsmith    struct amr_command	*ac;
32365245Smsmith    int			s;
32465245Smsmith
32565245Smsmith    s = splbio();
32665245Smsmith    if ((ac = TAILQ_FIRST(&sc->amr_ready)) != NULL)
32765245Smsmith	TAILQ_REMOVE(&sc->amr_ready, ac, ac_link);
32865245Smsmith    splx(s);
32965245Smsmith    return(ac);
33065245Smsmith}
33165245Smsmith
33265245Smsmithstatic __inline void
33365245Smsmithamr_enqueue_completed(struct amr_command *ac)
33465245Smsmith{
33565245Smsmith    int		s;
33665245Smsmith
33765245Smsmith    s = splbio();
33865245Smsmith    TAILQ_INSERT_TAIL(&ac->ac_sc->amr_completed, ac, ac_link);
33965245Smsmith    splx(s);
34065245Smsmith}
34165245Smsmith
34265245Smsmithstatic __inline struct amr_command *
34365245Smsmithamr_dequeue_completed(struct amr_softc *sc)
34465245Smsmith{
34565245Smsmith    struct amr_command	*ac;
34665245Smsmith    int			s;
34765245Smsmith
34865245Smsmith    s = splbio();
34965245Smsmith    if ((ac = TAILQ_FIRST(&sc->amr_completed)) != NULL)
35065245Smsmith	TAILQ_REMOVE(&sc->amr_completed, ac, ac_link);
35165245Smsmith    splx(s);
35265245Smsmith    return(ac);
35365245Smsmith}
35465245Smsmith
35565245Smsmithstatic __inline void
35665245Smsmithamr_enqueue_free(struct amr_command *ac)
35765245Smsmith{
35865245Smsmith    int		s;
35965245Smsmith
36065245Smsmith    s = splbio();
36165245Smsmith    TAILQ_INSERT_TAIL(&ac->ac_sc->amr_freecmds, ac, ac_link);
36265245Smsmith    splx(s);
36365245Smsmith}
36465245Smsmith
36565245Smsmithstatic __inline struct amr_command *
36665245Smsmithamr_dequeue_free(struct amr_softc *sc)
36765245Smsmith{
36865245Smsmith    struct amr_command	*ac;
36965245Smsmith    int			s;
37065245Smsmith
37165245Smsmith    s = splbio();
37265245Smsmith    if ((ac = TAILQ_FIRST(&sc->amr_freecmds)) != NULL)
37365245Smsmith	TAILQ_REMOVE(&sc->amr_freecmds, ac, ac_link);
37465245Smsmith    splx(s);
37565245Smsmith    return(ac);
37665245Smsmith}
377