amrvar.h revision 174544
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 174544 2007-12-12 05:55:03Z scottl $
5751974Smsmith */
5851974Smsmith
59148841Sscottl#include <geom/geom_disk.h>
60148841Sscottl#include <sys/lock.h>
61148841Sscottl#include <sys/mutex.h>
6251974Smsmith
63153409Sscottl#define LSI_DESC_PCI "LSILogic MegaRAID 1.53"
64140688Sscottl
6565245Smsmith#ifdef AMR_DEBUG
6687599Sobrien# define debug(level, fmt, args...)	do {if (level <= AMR_DEBUG) printf("%s: " fmt "\n", __func__ , ##args);} while(0)
6787599Sobrien# define debug_called(level)		do {if (level <= AMR_DEBUG) printf("%s: called\n", __func__);} while(0)
6865245Smsmith#else
6965245Smsmith# define debug(level, fmt, args...)
7065245Smsmith# define debug_called(level)
7165245Smsmith#endif
7287599Sobrien#define xdebug(fmt, args...)	printf("%s: " fmt "\n", __func__ , ##args)
7351974Smsmith
7451974Smsmith/*
7551974Smsmith * Per-logical-drive datastructure
7651974Smsmith */
7751974Smsmithstruct amr_logdrive
7851974Smsmith{
7951974Smsmith    u_int32_t	al_size;
8051974Smsmith    int		al_state;
8151974Smsmith    int		al_properties;
8251974Smsmith
8351974Smsmith    /* synthetic geometry */
8451974Smsmith    int		al_cylinders;
8551974Smsmith    int		al_heads;
8651974Smsmith    int		al_sectors;
8751974Smsmith
8851974Smsmith    /* driver */
8951974Smsmith    device_t	al_disk;
9051974Smsmith};
9151974Smsmith
9265245Smsmith/*
9365245Smsmith * Due to the difficulty of using the zone allocator to create a new
9465245Smsmith * zone from within a module, we use our own clustering to reduce
9565245Smsmith * memory wastage due to allocating lots of these small structures.
9665245Smsmith *
9765245Smsmith * 16k gives us a little under 200 command structures, which should
9865245Smsmith * normally be plenty.  We will grab more if we need them.
9965245Smsmith */
10051974Smsmith
10165245Smsmith#define AMR_CMD_CLUSTERSIZE	(16 * 1024)
10265245Smsmith
103174544Sscottlunion amr_ccb {
104174544Sscottl    struct amr_passthrough	ccb_pthru;
105174544Sscottl    struct amr_ext_passthrough	ccb_epthru;
106174544Sscottl    uint8_t			bytes[128];
107174544Sscottl};
108174544Sscottl
10951974Smsmith/*
11051974Smsmith * Per-command control structure.
11151974Smsmith */
11251974Smsmithstruct amr_command
11351974Smsmith{
11460938Sjake    TAILQ_ENTRY(amr_command)	ac_link;
11551974Smsmith
11651974Smsmith    struct amr_softc		*ac_sc;
11751974Smsmith    u_int8_t			ac_slot;
11865245Smsmith    int				ac_status;	/* command completion status */
119153409Sscottl    union {
120153409Sscottl	struct amr_sgentry	*sg32;
121153409Sscottl	struct amr_sg64entry	*sg64;
122153409Sscottl    } ac_sg;
123153409Sscottl    u_int32_t			ac_sgbusaddr;
124153409Sscottl    u_int32_t			ac_sg64_lo;
125153409Sscottl    u_int32_t			ac_sg64_hi;
12651974Smsmith    struct amr_mailbox		ac_mailbox;
12751974Smsmith    int				ac_flags;
12851974Smsmith#define AMR_CMD_DATAIN		(1<<0)
12951974Smsmith#define AMR_CMD_DATAOUT		(1<<1)
130174544Sscottl#define AMR_CMD_CCB		(1<<2)
13165245Smsmith#define AMR_CMD_PRIORITY	(1<<4)
13265245Smsmith#define AMR_CMD_MAPPED		(1<<5)
13365245Smsmith#define AMR_CMD_SLEEP		(1<<6)
13465245Smsmith#define AMR_CMD_BUSY		(1<<7)
135153409Sscottl#define AMR_CMD_SG64		(1<<8)
136153409Sscottl#define AC_IS_SG64(ac)		((ac)->ac_flags & AMR_CMD_SG64)
13751974Smsmith
13865245Smsmith    struct bio			*ac_bio;
139153409Sscottl    void			(* ac_complete)(struct amr_command *ac);
140153409Sscottl    void			*ac_private;
14165245Smsmith
14251974Smsmith    void			*ac_data;
14351974Smsmith    size_t			ac_length;
14451974Smsmith    bus_dmamap_t		ac_dmamap;
145153409Sscottl    bus_dmamap_t		ac_dma64map;
14651974Smsmith
147174544Sscottl    bus_dma_tag_t		ac_tag;
148174544Sscottl    bus_dmamap_t		ac_datamap;
149174544Sscottl    int				ac_nsegments;
150174544Sscottl    uint32_t			ac_mb_physaddr;
15165245Smsmith
152174544Sscottl    union amr_ccb		*ac_ccb;
153174544Sscottl    uint32_t			ac_ccb_busaddr;
15451974Smsmith};
15551974Smsmith
15665245Smsmithstruct amr_command_cluster
15765245Smsmith{
15865245Smsmith    TAILQ_ENTRY(amr_command_cluster)	acc_link;
15965245Smsmith    struct amr_command		acc_command[0];
16065245Smsmith};
16165245Smsmith
16265245Smsmith#define AMR_CMD_CLUSTERCOUNT	((AMR_CMD_CLUSTERSIZE - sizeof(struct amr_command_cluster)) /	\
16365245Smsmith				 sizeof(struct amr_command))
16465245Smsmith
16565245Smsmith/*
16665245Smsmith * Per-controller-instance data
16765245Smsmith */
16851974Smsmithstruct amr_softc
16951974Smsmith{
17051974Smsmith    /* bus attachments */
17151974Smsmith    device_t			amr_dev;
17251974Smsmith    struct resource		*amr_reg;		/* control registers */
17351974Smsmith    bus_space_handle_t		amr_bhandle;
17451974Smsmith    bus_space_tag_t		amr_btag;
17551974Smsmith    bus_dma_tag_t		amr_parent_dmat;	/* parent DMA tag */
17651974Smsmith    bus_dma_tag_t		amr_buffer_dmat;	/* data buffer DMA tag */
177153409Sscottl    bus_dma_tag_t		amr_buffer64_dmat;
17851974Smsmith    struct resource		*amr_irq;		/* interrupt */
17951974Smsmith    void			*amr_intr;
18051974Smsmith
18151974Smsmith    /* mailbox */
18258496Smsmith    volatile struct amr_mailbox		*amr_mailbox;
18358496Smsmith    volatile struct amr_mailbox64	*amr_mailbox64;
18451974Smsmith    u_int32_t			amr_mailboxphys;
18551974Smsmith    bus_dma_tag_t		amr_mailbox_dmat;
18651974Smsmith    bus_dmamap_t		amr_mailbox_dmamap;
18751974Smsmith
18851974Smsmith    /* scatter/gather lists and their controller-visible mappings */
18951974Smsmith    struct amr_sgentry		*amr_sgtable;		/* s/g lists */
190153409Sscottl    struct amr_sg64entry	*amr_sg64table;		/* 64bit s/g lists */
19151974Smsmith    u_int32_t			amr_sgbusaddr;		/* s/g table base address in bus space */
19251974Smsmith    bus_dma_tag_t		amr_sg_dmat;		/* s/g buffer DMA tag */
19351974Smsmith    bus_dmamap_t		amr_sg_dmamap;		/* map for s/g buffers */
19451974Smsmith
195174544Sscottl    union amr_ccb		*amr_ccb;
196174544Sscottl    uint32_t			amr_ccb_busaddr;
197174544Sscottl    bus_dma_tag_t		amr_ccb_dmat;
198174544Sscottl    bus_dmamap_t		amr_ccb_dmamap;
199174544Sscottl
20051974Smsmith    /* controller limits and features */
201140340Sscottl    int				amr_nextslot;		/* Next slot to use for newly allocated commands */
20251974Smsmith    int				amr_maxio;		/* maximum number of I/O transactions */
20351974Smsmith    int				amr_maxdrives;		/* max number of logical drives */
20465245Smsmith    int				amr_maxchan;		/* count of SCSI channels */
20551974Smsmith
20651974Smsmith    /* connected logical drives */
20751974Smsmith    struct amr_logdrive		amr_drive[AMR_MAXLD];
20851974Smsmith
20965245Smsmith    /* controller state */
21051974Smsmith    int				amr_state;
21151974Smsmith#define AMR_STATE_OPEN		(1<<0)
21251974Smsmith#define AMR_STATE_SUSPEND	(1<<1)
21351974Smsmith#define AMR_STATE_INTEN		(1<<2)
21451974Smsmith#define AMR_STATE_SHUTDOWN	(1<<3)
215131394Sps#define AMR_STATE_CRASHDUMP	(1<<4)
216138422Sscottl#define AMR_STATE_QUEUE_FRZN	(1<<5)
217153409Sscottl#define AMR_STATE_LD_DELETE	(1<<6)
218153409Sscottl#define AMR_STATE_REMAP_LD	(1<<7)
21951974Smsmith
22051974Smsmith    /* per-controller queues */
22165245Smsmith    struct bio_queue_head 	amr_bioq;		/* pending I/O with no commands */
22265245Smsmith    TAILQ_HEAD(,amr_command)	amr_ready;		/* commands ready to be submitted */
22351974Smsmith    struct amr_command		*amr_busycmd[AMR_MAXCMD];
22465245Smsmith    int				amr_busyslots;
22565245Smsmith    TAILQ_HEAD(,amr_command)	amr_completed;
22660938Sjake    TAILQ_HEAD(,amr_command)	amr_freecmds;
22765245Smsmith    TAILQ_HEAD(,amr_command_cluster)	amr_cmd_clusters;
22851974Smsmith
22965245Smsmith    /* CAM attachments for passthrough */
23065245Smsmith    struct cam_sim		*amr_cam_sim[AMR_MAX_CHANNELS];
23165245Smsmith    TAILQ_HEAD(, ccb_hdr)	amr_cam_ccbq;
232139952Sdwhite    struct cam_devq		*amr_cam_devq;
23358883Smsmith
23465245Smsmith    /* control device */
235153409Sscottl    struct cdev			*amr_dev_t;
236153409Sscottl    struct mtx			amr_list_lock;
23765245Smsmith
23851974Smsmith    /* controller type-specific support */
23951974Smsmith    int				amr_type;
24065245Smsmith#define AMR_TYPE_QUARTZ		(1<<0)
24165245Smsmith#define AMR_IS_QUARTZ(sc)	((sc)->amr_type & AMR_TYPE_QUARTZ)
24265245Smsmith#define AMR_TYPE_40LD		(1<<1)
24365245Smsmith#define AMR_IS_40LD(sc)		((sc)->amr_type & AMR_TYPE_40LD)
244153409Sscottl#define AMR_TYPE_SG64		(1<<2)
245153409Sscottl#define AMR_IS_SG64(sc)		((sc)->amr_type & AMR_TYPE_SG64)
246155222Sps    int				(* amr_submit_command)(struct amr_command *ac);
24751974Smsmith    int				(* amr_get_work)(struct amr_softc *sc, struct amr_mailbox *mbsave);
248107756Semoore    int				(*amr_poll_command)(struct amr_command *ac);
249138422Sscottl    int				(*amr_poll_command1)(struct amr_softc *sc, struct amr_command *ac);
250107756Semoore    int 			support_ext_cdb;	/* greater than 10 byte cdb support */
25165245Smsmith
25265245Smsmith    /* misc glue */
25365245Smsmith    struct intr_config_hook	amr_ich;		/* wait-for-interrupts probe hook */
25465245Smsmith    struct callout_handle	amr_timeout;		/* periodic status check */
255153409Sscottl    int				amr_allow_vol_config;
256153409Sscottl    int				amr_linux_no_adapters;
257153409Sscottl    int				amr_ld_del_supported;
258153409Sscottl    struct mtx			amr_hw_lock;
25951974Smsmith};
26051974Smsmith
26151974Smsmith/*
26265245Smsmith * Interface between bus connections and driver core.
26358883Smsmith */
26465245Smsmithextern int              amr_attach(struct amr_softc *sc);
26565245Smsmithextern void		amr_free(struct amr_softc *sc);
26665245Smsmithextern int		amr_flush(struct amr_softc *sc);
26765245Smsmithextern int		amr_done(struct amr_softc *sc);
26865245Smsmithextern void		amr_startio(struct amr_softc *sc);
26958883Smsmith
27058883Smsmith/*
27165245Smsmith * Command buffer allocation.
27251974Smsmith */
27365245Smsmithextern struct amr_command	*amr_alloccmd(struct amr_softc *sc);
27465245Smsmithextern void			amr_releasecmd(struct amr_command *ac);
27551974Smsmith
27651974Smsmith/*
27765245Smsmith * CAM interface
27851974Smsmith */
27965245Smsmithextern int		amr_cam_attach(struct amr_softc *sc);
28065245Smsmithextern void		amr_cam_detach(struct amr_softc *sc);
28165245Smsmithextern int		amr_cam_command(struct amr_softc *sc, struct amr_command **acp);
28251974Smsmith
28351974Smsmith/*
28451974Smsmith * MegaRAID logical disk driver
28551974Smsmith */
28651974Smsmithstruct amrd_softc
28751974Smsmith{
28851974Smsmith    device_t		amrd_dev;
28951974Smsmith    struct amr_softc	*amrd_controller;
29051974Smsmith    struct amr_logdrive	*amrd_drive;
291125975Sphk    struct disk		*amrd_disk;
29251974Smsmith    int			amrd_unit;
29351974Smsmith};
29451974Smsmith
29551974Smsmith/*
29651974Smsmith * Interface between driver core and disk driver (should be using a bus?)
29751974Smsmith */
29865245Smsmithextern int	amr_submit_bio(struct amr_softc *sc, struct bio *bio);
299120988Spsextern int 	amr_dump_blocks(struct amr_softc *sc, int unit, u_int32_t lba, void *data, int blks);
30051974Smsmithextern void	amrd_intr(void *data);
30151974Smsmith
30265245Smsmith/********************************************************************************
30365245Smsmith * Enqueue/dequeue functions
30465245Smsmith */
30565245Smsmithstatic __inline void
30665245Smsmithamr_enqueue_bio(struct amr_softc *sc, struct bio *bio)
30765245Smsmith{
30865245Smsmith
30965245Smsmith    bioq_insert_tail(&sc->amr_bioq, bio);
31065245Smsmith}
31165245Smsmith
31265245Smsmithstatic __inline struct bio *
31365245Smsmithamr_dequeue_bio(struct amr_softc *sc)
31465245Smsmith{
31565245Smsmith    struct bio	*bio;
31665245Smsmith
31765245Smsmith    if ((bio = bioq_first(&sc->amr_bioq)) != NULL)
31865245Smsmith	bioq_remove(&sc->amr_bioq, bio);
31965245Smsmith    return(bio);
32065245Smsmith}
32165245Smsmith
32265245Smsmithstatic __inline void
32365245Smsmithamr_enqueue_ready(struct amr_command *ac)
32465245Smsmith{
32565245Smsmith
32665245Smsmith    TAILQ_INSERT_TAIL(&ac->ac_sc->amr_ready, ac, ac_link);
32765245Smsmith}
32865245Smsmith
32965245Smsmithstatic __inline void
33065245Smsmithamr_requeue_ready(struct amr_command *ac)
33165245Smsmith{
33265245Smsmith
33365245Smsmith    TAILQ_INSERT_HEAD(&ac->ac_sc->amr_ready, ac, ac_link);
33465245Smsmith}
33565245Smsmith
33665245Smsmithstatic __inline struct amr_command *
33765245Smsmithamr_dequeue_ready(struct amr_softc *sc)
33865245Smsmith{
33965245Smsmith    struct amr_command	*ac;
34065245Smsmith
34165245Smsmith    if ((ac = TAILQ_FIRST(&sc->amr_ready)) != NULL)
34265245Smsmith	TAILQ_REMOVE(&sc->amr_ready, ac, ac_link);
34365245Smsmith    return(ac);
34465245Smsmith}
34565245Smsmith
34665245Smsmithstatic __inline void
34765245Smsmithamr_enqueue_completed(struct amr_command *ac)
34865245Smsmith{
34965245Smsmith
35065245Smsmith    TAILQ_INSERT_TAIL(&ac->ac_sc->amr_completed, ac, ac_link);
35165245Smsmith}
35265245Smsmith
35365245Smsmithstatic __inline struct amr_command *
35465245Smsmithamr_dequeue_completed(struct amr_softc *sc)
35565245Smsmith{
35665245Smsmith    struct amr_command	*ac;
35765245Smsmith
35865245Smsmith    if ((ac = TAILQ_FIRST(&sc->amr_completed)) != NULL)
35965245Smsmith	TAILQ_REMOVE(&sc->amr_completed, ac, ac_link);
36065245Smsmith    return(ac);
36165245Smsmith}
36265245Smsmith
36365245Smsmithstatic __inline void
36465245Smsmithamr_enqueue_free(struct amr_command *ac)
36565245Smsmith{
36665245Smsmith
36765245Smsmith    TAILQ_INSERT_TAIL(&ac->ac_sc->amr_freecmds, ac, ac_link);
36865245Smsmith}
36965245Smsmith
37065245Smsmithstatic __inline struct amr_command *
37165245Smsmithamr_dequeue_free(struct amr_softc *sc)
37265245Smsmith{
37365245Smsmith    struct amr_command	*ac;
37465245Smsmith
37565245Smsmith    if ((ac = TAILQ_FIRST(&sc->amr_freecmds)) != NULL)
37665245Smsmith	TAILQ_REMOVE(&sc->amr_freecmds, ac, ac_link);
37765245Smsmith    return(ac);
37865245Smsmith}
379