amrvar.h revision 175622
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 175622 2008-01-24 07:26:53Z 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
103175622Sscottltypedef STAILQ_HEAD(, amr_command)	ac_qhead_t;
104175622Sscottltypedef STAILQ_ENTRY(amr_command)	ac_link_t;
105175622Sscottl
106174544Sscottlunion amr_ccb {
107174544Sscottl    struct amr_passthrough	ccb_pthru;
108174544Sscottl    struct amr_ext_passthrough	ccb_epthru;
109174544Sscottl    uint8_t			bytes[128];
110174544Sscottl};
111174544Sscottl
11251974Smsmith/*
11351974Smsmith * Per-command control structure.
11451974Smsmith */
11551974Smsmithstruct amr_command
11651974Smsmith{
117175622Sscottl    ac_link_t			ac_link;
11851974Smsmith
11951974Smsmith    struct amr_softc		*ac_sc;
12051974Smsmith    u_int8_t			ac_slot;
12165245Smsmith    int				ac_status;	/* command completion status */
122153409Sscottl    union {
123153409Sscottl	struct amr_sgentry	*sg32;
124153409Sscottl	struct amr_sg64entry	*sg64;
125153409Sscottl    } ac_sg;
126153409Sscottl    u_int32_t			ac_sgbusaddr;
127153409Sscottl    u_int32_t			ac_sg64_lo;
128153409Sscottl    u_int32_t			ac_sg64_hi;
12951974Smsmith    struct amr_mailbox		ac_mailbox;
13051974Smsmith    int				ac_flags;
13151974Smsmith#define AMR_CMD_DATAIN		(1<<0)
13251974Smsmith#define AMR_CMD_DATAOUT		(1<<1)
133174544Sscottl#define AMR_CMD_CCB		(1<<2)
13465245Smsmith#define AMR_CMD_PRIORITY	(1<<4)
13565245Smsmith#define AMR_CMD_MAPPED		(1<<5)
13665245Smsmith#define AMR_CMD_SLEEP		(1<<6)
13765245Smsmith#define AMR_CMD_BUSY		(1<<7)
138153409Sscottl#define AMR_CMD_SG64		(1<<8)
139153409Sscottl#define AC_IS_SG64(ac)		((ac)->ac_flags & AMR_CMD_SG64)
140175622Sscottl    u_int			ac_retries;
14151974Smsmith
14265245Smsmith    struct bio			*ac_bio;
143153409Sscottl    void			(* ac_complete)(struct amr_command *ac);
144153409Sscottl    void			*ac_private;
14565245Smsmith
14651974Smsmith    void			*ac_data;
14751974Smsmith    size_t			ac_length;
14851974Smsmith    bus_dmamap_t		ac_dmamap;
149153409Sscottl    bus_dmamap_t		ac_dma64map;
15051974Smsmith
151174544Sscottl    bus_dma_tag_t		ac_tag;
152174544Sscottl    bus_dmamap_t		ac_datamap;
153174544Sscottl    int				ac_nsegments;
154174544Sscottl    uint32_t			ac_mb_physaddr;
15565245Smsmith
156174544Sscottl    union amr_ccb		*ac_ccb;
157174544Sscottl    uint32_t			ac_ccb_busaddr;
15851974Smsmith};
15951974Smsmith
16065245Smsmithstruct amr_command_cluster
16165245Smsmith{
16265245Smsmith    TAILQ_ENTRY(amr_command_cluster)	acc_link;
16365245Smsmith    struct amr_command		acc_command[0];
16465245Smsmith};
16565245Smsmith
16665245Smsmith#define AMR_CMD_CLUSTERCOUNT	((AMR_CMD_CLUSTERSIZE - sizeof(struct amr_command_cluster)) /	\
16765245Smsmith				 sizeof(struct amr_command))
16865245Smsmith
16965245Smsmith/*
17065245Smsmith * Per-controller-instance data
17165245Smsmith */
17251974Smsmithstruct amr_softc
17351974Smsmith{
17451974Smsmith    /* bus attachments */
17551974Smsmith    device_t			amr_dev;
17651974Smsmith    struct resource		*amr_reg;		/* control registers */
17751974Smsmith    bus_space_handle_t		amr_bhandle;
17851974Smsmith    bus_space_tag_t		amr_btag;
17951974Smsmith    bus_dma_tag_t		amr_parent_dmat;	/* parent DMA tag */
18051974Smsmith    bus_dma_tag_t		amr_buffer_dmat;	/* data buffer DMA tag */
181153409Sscottl    bus_dma_tag_t		amr_buffer64_dmat;
18251974Smsmith    struct resource		*amr_irq;		/* interrupt */
18351974Smsmith    void			*amr_intr;
18451974Smsmith
18551974Smsmith    /* mailbox */
18658496Smsmith    volatile struct amr_mailbox		*amr_mailbox;
18758496Smsmith    volatile struct amr_mailbox64	*amr_mailbox64;
18851974Smsmith    u_int32_t			amr_mailboxphys;
18951974Smsmith    bus_dma_tag_t		amr_mailbox_dmat;
19051974Smsmith    bus_dmamap_t		amr_mailbox_dmamap;
19151974Smsmith
19251974Smsmith    /* scatter/gather lists and their controller-visible mappings */
19351974Smsmith    struct amr_sgentry		*amr_sgtable;		/* s/g lists */
194153409Sscottl    struct amr_sg64entry	*amr_sg64table;		/* 64bit s/g lists */
19551974Smsmith    u_int32_t			amr_sgbusaddr;		/* s/g table base address in bus space */
19651974Smsmith    bus_dma_tag_t		amr_sg_dmat;		/* s/g buffer DMA tag */
19751974Smsmith    bus_dmamap_t		amr_sg_dmamap;		/* map for s/g buffers */
19851974Smsmith
199174544Sscottl    union amr_ccb		*amr_ccb;
200174544Sscottl    uint32_t			amr_ccb_busaddr;
201174544Sscottl    bus_dma_tag_t		amr_ccb_dmat;
202174544Sscottl    bus_dmamap_t		amr_ccb_dmamap;
203174544Sscottl
20451974Smsmith    /* controller limits and features */
205140340Sscottl    int				amr_nextslot;		/* Next slot to use for newly allocated commands */
20651974Smsmith    int				amr_maxio;		/* maximum number of I/O transactions */
20751974Smsmith    int				amr_maxdrives;		/* max number of logical drives */
20865245Smsmith    int				amr_maxchan;		/* count of SCSI channels */
20951974Smsmith
21051974Smsmith    /* connected logical drives */
21151974Smsmith    struct amr_logdrive		amr_drive[AMR_MAXLD];
21251974Smsmith
21365245Smsmith    /* controller state */
21451974Smsmith    int				amr_state;
21551974Smsmith#define AMR_STATE_OPEN		(1<<0)
21651974Smsmith#define AMR_STATE_SUSPEND	(1<<1)
21751974Smsmith#define AMR_STATE_INTEN		(1<<2)
21851974Smsmith#define AMR_STATE_SHUTDOWN	(1<<3)
219131394Sps#define AMR_STATE_CRASHDUMP	(1<<4)
220138422Sscottl#define AMR_STATE_QUEUE_FRZN	(1<<5)
221153409Sscottl#define AMR_STATE_LD_DELETE	(1<<6)
222153409Sscottl#define AMR_STATE_REMAP_LD	(1<<7)
22351974Smsmith
22451974Smsmith    /* per-controller queues */
22565245Smsmith    struct bio_queue_head 	amr_bioq;		/* pending I/O with no commands */
226175622Sscottl    ac_qhead_t			amr_ready;		/* commands ready to be submitted */
22751974Smsmith    struct amr_command		*amr_busycmd[AMR_MAXCMD];
22865245Smsmith    int				amr_busyslots;
229175622Sscottl    ac_qhead_t			amr_freecmds;
23065245Smsmith    TAILQ_HEAD(,amr_command_cluster)	amr_cmd_clusters;
23151974Smsmith
23265245Smsmith    /* CAM attachments for passthrough */
23365245Smsmith    struct cam_sim		*amr_cam_sim[AMR_MAX_CHANNELS];
23465245Smsmith    TAILQ_HEAD(, ccb_hdr)	amr_cam_ccbq;
235139952Sdwhite    struct cam_devq		*amr_cam_devq;
23658883Smsmith
23765245Smsmith    /* control device */
238153409Sscottl    struct cdev			*amr_dev_t;
239153409Sscottl    struct mtx			amr_list_lock;
24065245Smsmith
24151974Smsmith    /* controller type-specific support */
24251974Smsmith    int				amr_type;
24365245Smsmith#define AMR_TYPE_QUARTZ		(1<<0)
24465245Smsmith#define AMR_IS_QUARTZ(sc)	((sc)->amr_type & AMR_TYPE_QUARTZ)
24565245Smsmith#define AMR_TYPE_40LD		(1<<1)
24665245Smsmith#define AMR_IS_40LD(sc)		((sc)->amr_type & AMR_TYPE_40LD)
247153409Sscottl#define AMR_TYPE_SG64		(1<<2)
248153409Sscottl#define AMR_IS_SG64(sc)		((sc)->amr_type & AMR_TYPE_SG64)
249155222Sps    int				(* amr_submit_command)(struct amr_command *ac);
25051974Smsmith    int				(* amr_get_work)(struct amr_softc *sc, struct amr_mailbox *mbsave);
251107756Semoore    int				(*amr_poll_command)(struct amr_command *ac);
252138422Sscottl    int				(*amr_poll_command1)(struct amr_softc *sc, struct amr_command *ac);
253107756Semoore    int 			support_ext_cdb;	/* greater than 10 byte cdb support */
25465245Smsmith
25565245Smsmith    /* misc glue */
25665245Smsmith    struct intr_config_hook	amr_ich;		/* wait-for-interrupts probe hook */
25765245Smsmith    struct callout_handle	amr_timeout;		/* periodic status check */
258153409Sscottl    int				amr_allow_vol_config;
259153409Sscottl    int				amr_linux_no_adapters;
260153409Sscottl    int				amr_ld_del_supported;
261153409Sscottl    struct mtx			amr_hw_lock;
26251974Smsmith};
26351974Smsmith
26451974Smsmith/*
26565245Smsmith * Interface between bus connections and driver core.
26658883Smsmith */
26765245Smsmithextern int              amr_attach(struct amr_softc *sc);
26865245Smsmithextern void		amr_free(struct amr_softc *sc);
26965245Smsmithextern int		amr_flush(struct amr_softc *sc);
27065245Smsmithextern int		amr_done(struct amr_softc *sc);
27165245Smsmithextern void		amr_startio(struct amr_softc *sc);
27258883Smsmith
27358883Smsmith/*
27465245Smsmith * Command buffer allocation.
27551974Smsmith */
27665245Smsmithextern struct amr_command	*amr_alloccmd(struct amr_softc *sc);
27765245Smsmithextern void			amr_releasecmd(struct amr_command *ac);
27851974Smsmith
27951974Smsmith/*
28065245Smsmith * CAM interface
28151974Smsmith */
28265245Smsmithextern int		amr_cam_attach(struct amr_softc *sc);
28365245Smsmithextern void		amr_cam_detach(struct amr_softc *sc);
28465245Smsmithextern int		amr_cam_command(struct amr_softc *sc, struct amr_command **acp);
28551974Smsmith
28651974Smsmith/*
28751974Smsmith * MegaRAID logical disk driver
28851974Smsmith */
28951974Smsmithstruct amrd_softc
29051974Smsmith{
29151974Smsmith    device_t		amrd_dev;
29251974Smsmith    struct amr_softc	*amrd_controller;
29351974Smsmith    struct amr_logdrive	*amrd_drive;
294125975Sphk    struct disk		*amrd_disk;
29551974Smsmith    int			amrd_unit;
29651974Smsmith};
29751974Smsmith
29851974Smsmith/*
29951974Smsmith * Interface between driver core and disk driver (should be using a bus?)
30051974Smsmith */
30165245Smsmithextern int	amr_submit_bio(struct amr_softc *sc, struct bio *bio);
302120988Spsextern int 	amr_dump_blocks(struct amr_softc *sc, int unit, u_int32_t lba, void *data, int blks);
30351974Smsmithextern void	amrd_intr(void *data);
30451974Smsmith
30565245Smsmith/********************************************************************************
30665245Smsmith * Enqueue/dequeue functions
30765245Smsmith */
30865245Smsmithstatic __inline void
30965245Smsmithamr_enqueue_bio(struct amr_softc *sc, struct bio *bio)
31065245Smsmith{
31165245Smsmith
31265245Smsmith    bioq_insert_tail(&sc->amr_bioq, bio);
31365245Smsmith}
31465245Smsmith
31565245Smsmithstatic __inline struct bio *
31665245Smsmithamr_dequeue_bio(struct amr_softc *sc)
31765245Smsmith{
31865245Smsmith    struct bio	*bio;
31965245Smsmith
32065245Smsmith    if ((bio = bioq_first(&sc->amr_bioq)) != NULL)
32165245Smsmith	bioq_remove(&sc->amr_bioq, bio);
32265245Smsmith    return(bio);
32365245Smsmith}
32465245Smsmith
32565245Smsmithstatic __inline void
326175622Sscottlamr_init_qhead(ac_qhead_t *head)
327175622Sscottl{
328175622Sscottl
329175622Sscottl	STAILQ_INIT(head);
330175622Sscottl}
331175622Sscottl
332175622Sscottlstatic __inline void
33365245Smsmithamr_enqueue_ready(struct amr_command *ac)
33465245Smsmith{
33565245Smsmith
336175622Sscottl    STAILQ_INSERT_TAIL(&ac->ac_sc->amr_ready, ac, ac_link);
33765245Smsmith}
33865245Smsmith
33965245Smsmithstatic __inline void
34065245Smsmithamr_requeue_ready(struct amr_command *ac)
34165245Smsmith{
34265245Smsmith
343175622Sscottl    STAILQ_INSERT_HEAD(&ac->ac_sc->amr_ready, ac, ac_link);
34465245Smsmith}
34565245Smsmith
34665245Smsmithstatic __inline struct amr_command *
34765245Smsmithamr_dequeue_ready(struct amr_softc *sc)
34865245Smsmith{
34965245Smsmith    struct amr_command	*ac;
35065245Smsmith
351175622Sscottl    if ((ac = STAILQ_FIRST(&sc->amr_ready)) != NULL)
352175622Sscottl	STAILQ_REMOVE_HEAD(&sc->amr_ready, ac_link);
35365245Smsmith    return(ac);
35465245Smsmith}
35565245Smsmith
35665245Smsmithstatic __inline void
357175622Sscottlamr_enqueue_completed(struct amr_command *ac, ac_qhead_t *head)
35865245Smsmith{
35965245Smsmith
360175622Sscottl    STAILQ_INSERT_TAIL(head, ac, ac_link);
36165245Smsmith}
36265245Smsmith
36365245Smsmithstatic __inline struct amr_command *
364175622Sscottlamr_dequeue_completed(struct amr_softc *sc, ac_qhead_t *head)
36565245Smsmith{
36665245Smsmith    struct amr_command	*ac;
36765245Smsmith
368175622Sscottl    if ((ac = STAILQ_FIRST(head)) != NULL)
369175622Sscottl	STAILQ_REMOVE_HEAD(head, ac_link);
37065245Smsmith    return(ac);
37165245Smsmith}
37265245Smsmith
37365245Smsmithstatic __inline void
37465245Smsmithamr_enqueue_free(struct amr_command *ac)
37565245Smsmith{
37665245Smsmith
377175622Sscottl    STAILQ_INSERT_HEAD(&ac->ac_sc->amr_freecmds, ac, ac_link);
37865245Smsmith}
37965245Smsmith
38065245Smsmithstatic __inline struct amr_command *
38165245Smsmithamr_dequeue_free(struct amr_softc *sc)
38265245Smsmith{
38365245Smsmith    struct amr_command	*ac;
38465245Smsmith
385175622Sscottl    if ((ac = STAILQ_FIRST(&sc->amr_freecmds)) != NULL)
386175622Sscottl	STAILQ_REMOVE_HEAD(&sc->amr_freecmds, ac_link);
38765245Smsmith    return(ac);
38865245Smsmith}
389