amrvar.h revision 120988
119878Swollman/*- 22742Swollman * Copyright (c) 1999,2000 Michael Smith 32742Swollman * Copyright (c) 2000 BSDi 42742Swollman * All rights reserved. 52742Swollman * 62742Swollman * Redistribution and use in source and binary forms, with or without 72742Swollman * modification, are permitted provided that the following conditions 82742Swollman * are met: 92742Swollman * 1. Redistributions of source code must retain the above copyright 102742Swollman * notice, this list of conditions and the following disclaimer. 112742Swollman * 2. Redistributions in binary form must reproduce the above copyright 122742Swollman * notice, this list of conditions and the following disclaimer in the 132742Swollman * documentation and/or other materials provided with the distribution. 142742Swollman * 152742Swollman * THIS SOFTWARE IS PROVIDED BY THE AUTHOR AND CONTRIBUTORS ``AS IS'' AND 162742Swollman * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE 172742Swollman * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE 182742Swollman * ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE 192742Swollman * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL 202742Swollman * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS 212742Swollman * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) 222742Swollman * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT 239908Swollman * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY 242742Swollman * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF 252742Swollman * SUCH DAMAGE. 262742Swollman * 279908Swollman * Copyright (c) 2002 Eric Moore 282742Swollman * Copyright (c) 2002 LSI Logic Corporation 292742Swollman * All rights reserved. 3014343Swollman * 3114343Swollman * Redistribution and use in source and binary forms, with or without 3214343Swollman * modification, are permitted provided that the following conditions 3314343Swollman * are met: 3414343Swollman * 1. Redistributions of source code must retain the above copyright 3514343Swollman * notice, this list of conditions and the following disclaimer. 362742Swollman * 2. Redistributions in binary form must reproduce the above copyright 379908Swollman * notice, this list of conditions and the following disclaimer in the 382742Swollman * documentation and/or other materials provided with the distribution. 392742Swollman * 3. The party using or redistributing the source code and binary forms 4014343Swollman * agrees to the disclaimer below and the terms and conditions set forth 4114343Swollman * herein. 4214343Swollman * 4314343Swollman * THIS SOFTWARE IS PROVIDED BY THE AUTHOR AND CONTRIBUTORS ``AS IS'' AND 4414343Swollman * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE 4514343Swollman * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE 4614343Swollman * ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE 4714343Swollman * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL 482742Swollman * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS 492742Swollman * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) 509908Swollman * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT 512742Swollman * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY 5214343Swollman * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF 5314343Swollman * SUCH DAMAGE. 5414343Swollman * 5514343Swollman * 5614343Swollman * $FreeBSD: head/sys/dev/amr/amrvar.h 120988 2003-10-10 22:49:40Z ps $ 5714343Swollman */ 5814343Swollman 5914343Swollman#if __FreeBSD_version >= 500005 6014343Swollman# include <sys/taskqueue.h> 612742Swollman# include <geom/geom_disk.h> 622742Swollman#endif 632742Swollman 642742Swollman#ifdef AMR_DEBUG 6514343Swollman# define debug(level, fmt, args...) do {if (level <= AMR_DEBUG) printf("%s: " fmt "\n", __func__ , ##args);} while(0) 662742Swollman# define debug_called(level) do {if (level <= AMR_DEBUG) printf("%s: called\n", __func__);} while(0) 672742Swollman#else 689908Swollman# define debug(level, fmt, args...) 692742Swollman# define debug_called(level) 7014343Swollman#endif 7114343Swollman#define xdebug(fmt, args...) printf("%s: " fmt "\n", __func__ , ##args) 7214343Swollman 7314343Swollman/* 7414343Swollman * Per-logical-drive datastructure 7514343Swollman */ 7614343Swollmanstruct amr_logdrive 7714343Swollman{ 7814343Swollman u_int32_t al_size; 7914343Swollman int al_state; 8014343Swollman int al_properties; 8114343Swollman 8214343Swollman /* synthetic geometry */ 832742Swollman int al_cylinders; 842742Swollman int al_heads; 852742Swollman int al_sectors; 8614343Swollman 872742Swollman /* driver */ 882742Swollman device_t al_disk; 899908Swollman}; 902742Swollman 9114343Swollman/* 9214343Swollman * Due to the difficulty of using the zone allocator to create a new 9314343Swollman * zone from within a module, we use our own clustering to reduce 9414343Swollman * memory wastage due to allocating lots of these small structures. 9514343Swollman * 9614343Swollman * 16k gives us a little under 200 command structures, which should 9714343Swollman * normally be plenty. We will grab more if we need them. 9814343Swollman */ 992742Swollman 1002742Swollman#define AMR_CMD_CLUSTERSIZE (16 * 1024) 1012742Swollman 10214343Swollman/* 1032742Swollman * Per-command control structure. 1042742Swollman */ 1059908Swollmanstruct amr_command 1062742Swollman{ 10714343Swollman TAILQ_ENTRY(amr_command) ac_link; 10814343Swollman 10914343Swollman struct amr_softc *ac_sc; 11014343Swollman u_int8_t ac_slot; 11114343Swollman int ac_status; /* command completion status */ 11214343Swollman struct amr_mailbox ac_mailbox; 11314343Swollman int ac_flags; 11414343Swollman#define AMR_CMD_DATAIN (1<<0) 11514343Swollman#define AMR_CMD_DATAOUT (1<<1) 11614343Swollman#define AMR_CMD_CCB_DATAIN (1<<2) 1172742Swollman#define AMR_CMD_CCB_DATAOUT (1<<3) 1182742Swollman#define AMR_CMD_PRIORITY (1<<4) 1192742Swollman#define AMR_CMD_MAPPED (1<<5) 12014343Swollman#define AMR_CMD_SLEEP (1<<6) 1212742Swollman#define AMR_CMD_BUSY (1<<7) 1222742Swollman 1232742Swollman struct bio *ac_bio; 1242742Swollman 1252742Swollman void *ac_data; 12614343Swollman size_t ac_length; 1272742Swollman bus_dmamap_t ac_dmamap; 1288029Swollman u_int32_t ac_dataphys; 12914343Swollman 13014343Swollman void *ac_ccb_data; 13114343Swollman size_t ac_ccb_length; 13214343Swollman bus_dmamap_t ac_ccb_dmamap; 13314343Swollman u_int32_t ac_ccb_dataphys; 13414343Swollman 13514343Swollman void (* ac_complete)(struct amr_command *ac); 13614343Swollman void *ac_private; 13714343Swollman}; 13814343Swollman 1392742Swollmanstruct amr_command_cluster 1402742Swollman{ 14114343Swollman TAILQ_ENTRY(amr_command_cluster) acc_link; 1428029Swollman struct amr_command acc_command[0]; 14314343Swollman}; 14414343Swollman 1452742Swollman#define AMR_CMD_CLUSTERCOUNT ((AMR_CMD_CLUSTERSIZE - sizeof(struct amr_command_cluster)) / \ 14619878Swollman sizeof(struct amr_command)) 1472742Swollman 1482742Swollman/* 14914343Swollman * Per-controller-instance data 1502742Swollman */ 1512742Swollmanstruct amr_softc 15214343Swollman{ 15314343Swollman /* bus attachments */ 15414343Swollman device_t amr_dev; 15514343Swollman struct resource *amr_reg; /* control registers */ 1562742Swollman bus_space_handle_t amr_bhandle; 1572742Swollman bus_space_tag_t amr_btag; 1582742Swollman bus_dma_tag_t amr_parent_dmat; /* parent DMA tag */ 1592742Swollman bus_dma_tag_t amr_buffer_dmat; /* data buffer DMA tag */ 1602742Swollman struct resource *amr_irq; /* interrupt */ 1612742Swollman void *amr_intr; 16219878Swollman 16319878Swollman /* mailbox */ 16419878Swollman volatile struct amr_mailbox *amr_mailbox; 1652742Swollman volatile struct amr_mailbox64 *amr_mailbox64; 1662742Swollman u_int32_t amr_mailboxphys; 16719878Swollman bus_dma_tag_t amr_mailbox_dmat; 16819878Swollman bus_dmamap_t amr_mailbox_dmamap; 1692742Swollman 1702742Swollman /* scatter/gather lists and their controller-visible mappings */ 1712742Swollman struct amr_sgentry *amr_sgtable; /* s/g lists */ 1722742Swollman u_int32_t amr_sgbusaddr; /* s/g table base address in bus space */ 17319878Swollman bus_dma_tag_t amr_sg_dmat; /* s/g buffer DMA tag */ 1742742Swollman bus_dmamap_t amr_sg_dmamap; /* map for s/g buffers */ 1752742Swollman 1762742Swollman /* controller limits and features */ 1772742Swollman int amr_maxio; /* maximum number of I/O transactions */ 17819878Swollman int amr_maxdrives; /* max number of logical drives */ 1792742Swollman int amr_maxchan; /* count of SCSI channels */ 1802742Swollman 1812742Swollman /* connected logical drives */ 1822742Swollman struct amr_logdrive amr_drive[AMR_MAXLD]; 18319878Swollman 1842742Swollman /* controller state */ 18519878Swollman int amr_state; 1862742Swollman#define AMR_STATE_OPEN (1<<0) 18719878Swollman#define AMR_STATE_SUSPEND (1<<1) 1882742Swollman#define AMR_STATE_INTEN (1<<2) 1892742Swollman#define AMR_STATE_SHUTDOWN (1<<3) 1902742Swollman 1912742Swollman /* per-controller queues */ 1922742Swollman struct bio_queue_head amr_bioq; /* pending I/O with no commands */ 1932742Swollman TAILQ_HEAD(,amr_command) amr_ready; /* commands ready to be submitted */ 1942742Swollman struct amr_command *amr_busycmd[AMR_MAXCMD]; 19514343Swollman int amr_busyslots; 19614343Swollman TAILQ_HEAD(,amr_command) amr_completed; 1972742Swollman TAILQ_HEAD(,amr_command) amr_freecmds; 1982742Swollman TAILQ_HEAD(,amr_command_cluster) amr_cmd_clusters; 19914343Swollman 20014343Swollman /* CAM attachments for passthrough */ 2012742Swollman struct cam_sim *amr_cam_sim[AMR_MAX_CHANNELS]; 2022742Swollman TAILQ_HEAD(, ccb_hdr) amr_cam_ccbq; 20314343Swollman 20414343Swollman /* control device */ 2052742Swollman dev_t amr_dev_t; 20614343Swollman 20714343Swollman /* controller type-specific support */ 20814343Swollman int amr_type; 2092742Swollman#define AMR_TYPE_QUARTZ (1<<0) 2102742Swollman#define AMR_IS_QUARTZ(sc) ((sc)->amr_type & AMR_TYPE_QUARTZ) 2112742Swollman#define AMR_TYPE_40LD (1<<1) 21219878Swollman#define AMR_IS_40LD(sc) ((sc)->amr_type & AMR_TYPE_40LD) 2132742Swollman int (* amr_submit_command)(struct amr_softc *sc); 21419878Swollman int (* amr_get_work)(struct amr_softc *sc, struct amr_mailbox *mbsave); 21519878Swollman int (*amr_poll_command)(struct amr_command *ac); 21619878Swollman int support_ext_cdb; /* greater than 10 byte cdb support */ 2172742Swollman 21819878Swollman /* misc glue */ 21919878Swollman struct intr_config_hook amr_ich; /* wait-for-interrupts probe hook */ 22019878Swollman struct callout_handle amr_timeout; /* periodic status check */ 2212742Swollman#if __FreeBSD_version >= 500005 22214343Swollman struct task amr_task_complete; /* deferred-completion task */ 22314343Swollman#endif 22414343Swollman}; 22519878Swollman 22619878Swollman/* 22714343Swollman * Interface between bus connections and driver core. 22814343Swollman */ 22914343Swollmanextern int amr_attach(struct amr_softc *sc); 23014343Swollmanextern void amr_free(struct amr_softc *sc); 23119878Swollmanextern int amr_flush(struct amr_softc *sc); 23219878Swollmanextern int amr_done(struct amr_softc *sc); 23314343Swollmanextern void amr_startio(struct amr_softc *sc); 23419878Swollman 23519878Swollman/* 23619878Swollman * Command buffer allocation. 23714343Swollman */ 23814343Swollmanextern struct amr_command *amr_alloccmd(struct amr_softc *sc); 23914343Swollmanextern void amr_releasecmd(struct amr_command *ac); 24014343Swollman 24119878Swollman/* 24219878Swollman * CAM interface 24314343Swollman */ 24419878Swollmanextern int amr_cam_attach(struct amr_softc *sc); 24514343Swollmanextern void amr_cam_detach(struct amr_softc *sc); 24619878Swollmanextern int amr_cam_command(struct amr_softc *sc, struct amr_command **acp); 24714343Swollman 24819878Swollman/* 24919878Swollman * MegaRAID logical disk driver 25014343Swollman */ 2512742Swollmanstruct amrd_softc 2522742Swollman{ 2532742Swollman device_t amrd_dev; 25419878Swollman struct amr_softc *amrd_controller; 2552742Swollman struct amr_logdrive *amrd_drive; 25619878Swollman struct disk amrd_disk; 25719878Swollman int amrd_unit; 2582742Swollman}; 2592742Swollman 2602742Swollman/* 26119878Swollman * Interface between driver core and disk driver (should be using a bus?) 26219878Swollman */ 2632742Swollmanextern int amr_submit_bio(struct amr_softc *sc, struct bio *bio); 2642742Swollmanextern int amr_dump_blocks(struct amr_softc *sc, int unit, u_int32_t lba, void *data, int blks); 2652742Swollmanextern void amrd_intr(void *data); 2662742Swollman 2672742Swollman/******************************************************************************** 2682742Swollman * Enqueue/dequeue functions 2692742Swollman */ 2702742Swollmanstatic __inline void 2712742Swollmanamr_enqueue_bio(struct amr_softc *sc, struct bio *bio) 2722742Swollman{ 2732742Swollman int s; 2742742Swollman 27514343Swollman s = splbio(); 2762742Swollman bioq_insert_tail(&sc->amr_bioq, bio); 27714343Swollman splx(s); 27814343Swollman} 2792742Swollman 28014343Swollmanstatic __inline struct bio * 28114343Swollmanamr_dequeue_bio(struct amr_softc *sc) 28214343Swollman{ 28314343Swollman struct bio *bio; 28414343Swollman int s; 2859908Swollman 2869908Swollman s = splbio(); 2879908Swollman if ((bio = bioq_first(&sc->amr_bioq)) != NULL) 2889908Swollman bioq_remove(&sc->amr_bioq, bio); 2899908Swollman splx(s); 2909908Swollman return(bio); 2919908Swollman} 2922742Swollman 2932742Swollmanstatic __inline void 29414343Swollmanamr_enqueue_ready(struct amr_command *ac) 2952742Swollman{ 29619878Swollman int s; 2972742Swollman 2988029Swollman s = splbio(); 2992742Swollman TAILQ_INSERT_TAIL(&ac->ac_sc->amr_ready, ac, ac_link); 30019878Swollman splx(s); 3012742Swollman} 3022742Swollman 3032742Swollmanstatic __inline void 3042742Swollmanamr_requeue_ready(struct amr_command *ac) 3052742Swollman{ 3062742Swollman int s; 3072742Swollman 30819878Swollman s = splbio(); 30919878Swollman TAILQ_INSERT_HEAD(&ac->ac_sc->amr_ready, ac, ac_link); 31019878Swollman splx(s); 3112742Swollman} 3122742Swollman 3132742Swollmanstatic __inline struct amr_command * 3142742Swollmanamr_dequeue_ready(struct amr_softc *sc) 31519878Swollman{ 31619878Swollman struct amr_command *ac; 3172742Swollman int s; 3189908Swollman 3199908Swollman s = splbio(); 3209908Swollman if ((ac = TAILQ_FIRST(&sc->amr_ready)) != NULL) 32119878Swollman TAILQ_REMOVE(&sc->amr_ready, ac, ac_link); 3229908Swollman splx(s); 3232742Swollman return(ac); 32414343Swollman} 3252742Swollman 3262742Swollmanstatic __inline void 3272742Swollmanamr_enqueue_completed(struct amr_command *ac) 3282742Swollman{ 32919878Swollman int s; 33019878Swollman 3312742Swollman s = splbio(); 3322742Swollman TAILQ_INSERT_TAIL(&ac->ac_sc->amr_completed, ac, ac_link); 3332742Swollman splx(s); 3342742Swollman} 33519878Swollman 3362742Swollmanstatic __inline struct amr_command * 33714343Swollmanamr_dequeue_completed(struct amr_softc *sc) 33814343Swollman{ 33914343Swollman struct amr_command *ac; 34019878Swollman int s; 34114343Swollman 34214343Swollman s = splbio(); 34314343Swollman if ((ac = TAILQ_FIRST(&sc->amr_completed)) != NULL) 34414343Swollman TAILQ_REMOVE(&sc->amr_completed, ac, ac_link); 34514343Swollman splx(s); 34614343Swollman return(ac); 34714343Swollman} 34819878Swollman 34919878Swollmanstatic __inline void 35014343Swollmanamr_enqueue_free(struct amr_command *ac) 3512742Swollman{ 3522742Swollman int s; 3532742Swollman 3542742Swollman s = splbio(); 35519878Swollman TAILQ_INSERT_TAIL(&ac->ac_sc->amr_freecmds, ac, ac_link); 3562742Swollman splx(s); 3572742Swollman} 3582742Swollman 3592742Swollmanstatic __inline struct amr_command * 36019878Swollmanamr_dequeue_free(struct amr_softc *sc) 3612742Swollman{ 3622742Swollman struct amr_command *ac; 3632742Swollman int s; 3642742Swollman 36519878Swollman s = splbio(); 36619878Swollman if ((ac = TAILQ_FIRST(&sc->amr_freecmds)) != NULL) 3672742Swollman TAILQ_REMOVE(&sc->amr_freecmds, ac, ac_link); 3682742Swollman splx(s); 3692742Swollman return(ac); 3702742Swollman} 37119878Swollman