amrvar.h revision 107756
160812Sps/*- 260786Sps * Copyright (c) 1999,2000 Michael Smith 3170259Sdelphij * Copyright (c) 2000 BSDi 460786Sps * All rights reserved. 560786Sps * 660786Sps * Redistribution and use in source and binary forms, with or without 760786Sps * modification, are permitted provided that the following conditions 860786Sps * are met: 960786Sps * 1. Redistributions of source code must retain the above copyright 1060786Sps * notice, this list of conditions and the following disclaimer. 1160786Sps * 2. Redistributions in binary form must reproduce the above copyright 1260786Sps * notice, this list of conditions and the following disclaimer in the 1360786Sps * documentation and/or other materials provided with the distribution. 1460786Sps * 1560786Sps * THIS SOFTWARE IS PROVIDED BY THE AUTHOR AND CONTRIBUTORS ``AS IS'' AND 1660786Sps * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE 1760786Sps * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE 1889022Sps * ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE 1989022Sps * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL 2089022Sps * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS 2160786Sps * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) 2260786Sps * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT 2360786Sps * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY 2460786Sps * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF 2560786Sps * SUCH DAMAGE. 2660786Sps * 2760786Sps * Copyright (c) 2002 Eric Moore 2860786Sps * Copyright (c) 2002 LSI Logic Corporation 2960786Sps * All rights reserved. 3060786Sps * 3160786Sps * Redistribution and use in source and binary forms, with or without 3260786Sps * modification, are permitted provided that the following conditions 3360786Sps * are met: 3460786Sps * 1. Redistributions of source code must retain the above copyright 3560786Sps * notice, this list of conditions and the following disclaimer. 36170259Sdelphij * 2. Redistributions in binary form must reproduce the above copyright 3760786Sps * notice, this list of conditions and the following disclaimer in the 3860786Sps * documentation and/or other materials provided with the distribution. 3960786Sps * 3. The party using or redistributing the source code and binary forms 4060786Sps * agrees to the disclaimer below and the terms and conditions set forth 4160786Sps * herein. 4260786Sps * 4360786Sps * THIS SOFTWARE IS PROVIDED BY THE AUTHOR AND CONTRIBUTORS ``AS IS'' AND 4460786Sps * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE 4560786Sps * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE 4660786Sps * ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE 4760786Sps * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL 4860786Sps * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS 4960786Sps * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) 5089022Sps * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT 5160786Sps * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY 5260786Sps * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF 5360786Sps * SUCH DAMAGE. 5460786Sps * 5589022Sps * 5689022Sps * $FreeBSD: head/sys/dev/amr/amrvar.h 107756 2002-12-11 20:59:46Z emoore $ 5789022Sps */ 5889022Sps 5960786Sps#if __FreeBSD_version >= 500005 6060786Sps# include <sys/taskqueue.h> 61170259Sdelphij#endif 62171009Sdelphij 63170259Sdelphij#ifdef AMR_DEBUG 6460786Sps# define debug(level, fmt, args...) do {if (level <= AMR_DEBUG) printf("%s: " fmt "\n", __func__ , ##args);} while(0) 6560786Sps# define debug_called(level) do {if (level <= AMR_DEBUG) printf("%s: called\n", __func__);} while(0) 6660786Sps#else 6760786Sps# define debug(level, fmt, args...) 6860786Sps# define debug_called(level) 6960786Sps#endif 7060786Sps#define xdebug(fmt, args...) printf("%s: " fmt "\n", __func__ , ##args) 7160786Sps 7260786Sps/* 7360786Sps * Per-logical-drive datastructure 7460786Sps */ 7560786Spsstruct amr_logdrive 7660812Sps{ 7760786Sps u_int32_t al_size; 7860786Sps int al_state; 7960786Sps int al_properties; 8060786Sps 8160786Sps /* synthetic geometry */ 8260786Sps int al_cylinders; 8360786Sps int al_heads; 8460786Sps int al_sectors; 8560786Sps 8660786Sps /* driver */ 8760786Sps device_t al_disk; 8860786Sps}; 8960786Sps 9060786Sps/* 9160786Sps * Due to the difficulty of using the zone allocator to create a new 9260786Sps * zone from within a module, we use our own clustering to reduce 9360786Sps * memory wastage due to allocating lots of these small structures. 9460786Sps * 9560786Sps * 16k gives us a little under 200 command structures, which should 9660786Sps * normally be plenty. We will grab more if we need them. 9760786Sps */ 9860786Sps 9960786Sps#define AMR_CMD_CLUSTERSIZE (16 * 1024) 10060786Sps 10160786Sps/* 10260786Sps * Per-command control structure. 10360786Sps */ 10460786Spsstruct amr_command 10560786Sps{ 10660786Sps TAILQ_ENTRY(amr_command) ac_link; 10760786Sps 10860786Sps struct amr_softc *ac_sc; 10960786Sps u_int8_t ac_slot; 11089022Sps int ac_status; /* command completion status */ 11160786Sps struct amr_mailbox ac_mailbox; 11260786Sps int ac_flags; 11360786Sps#define AMR_CMD_DATAIN (1<<0) 11460786Sps#define AMR_CMD_DATAOUT (1<<1) 11560786Sps#define AMR_CMD_CCB_DATAIN (1<<2) 11660786Sps#define AMR_CMD_CCB_DATAOUT (1<<3) 11760786Sps#define AMR_CMD_PRIORITY (1<<4) 11860786Sps#define AMR_CMD_MAPPED (1<<5) 11960786Sps#define AMR_CMD_SLEEP (1<<6) 12060786Sps#define AMR_CMD_BUSY (1<<7) 12160786Sps 122161478Sdelphij struct bio *ac_bio; 12360786Sps 124170259Sdelphij void *ac_data; 125170259Sdelphij size_t ac_length; 126170259Sdelphij bus_dmamap_t ac_dmamap; 127170259Sdelphij u_int32_t ac_dataphys; 128170259Sdelphij 129170259Sdelphij void *ac_ccb_data; 130170259Sdelphij size_t ac_ccb_length; 131170259Sdelphij bus_dmamap_t ac_ccb_dmamap; 132170259Sdelphij u_int32_t ac_ccb_dataphys; 13360812Sps 134170259Sdelphij void (* ac_complete)(struct amr_command *ac); 135170259Sdelphij void *ac_private; 136170259Sdelphij}; 137170259Sdelphij 138170259Sdelphijstruct amr_command_cluster 139170812Sdelphij{ 140170812Sdelphij TAILQ_ENTRY(amr_command_cluster) acc_link; 141170812Sdelphij struct amr_command acc_command[0]; 142170259Sdelphij}; 14360786Sps 14460786Sps#define AMR_CMD_CLUSTERCOUNT ((AMR_CMD_CLUSTERSIZE - sizeof(struct amr_command_cluster)) / \ 14560786Sps sizeof(struct amr_command)) 146170963Sdelphij 147170963Sdelphij/* 14860786Sps * Per-controller-instance data 14960786Sps */ 15060786Spsstruct amr_softc 15160786Sps{ 15260786Sps /* bus attachments */ 15360786Sps device_t amr_dev; 15460786Sps struct resource *amr_reg; /* control registers */ 15560786Sps bus_space_handle_t amr_bhandle; 15660786Sps bus_space_tag_t amr_btag; 15760786Sps bus_dma_tag_t amr_parent_dmat; /* parent DMA tag */ 15860786Sps bus_dma_tag_t amr_buffer_dmat; /* data buffer DMA tag */ 15960786Sps struct resource *amr_irq; /* interrupt */ 16060786Sps void *amr_intr; 16160786Sps 16260786Sps /* mailbox */ 16360786Sps volatile struct amr_mailbox *amr_mailbox; 16460786Sps volatile struct amr_mailbox64 *amr_mailbox64; 16560786Sps u_int32_t amr_mailboxphys; 16660786Sps bus_dma_tag_t amr_mailbox_dmat; 16760786Sps bus_dmamap_t amr_mailbox_dmamap; 168170259Sdelphij 169171009Sdelphij /* scatter/gather lists and their controller-visible mappings */ 170170259Sdelphij struct amr_sgentry *amr_sgtable; /* s/g lists */ 17160786Sps u_int32_t amr_sgbusaddr; /* s/g table base address in bus space */ 17260786Sps bus_dma_tag_t amr_sg_dmat; /* s/g buffer DMA tag */ 17360786Sps bus_dmamap_t amr_sg_dmamap; /* map for s/g buffers */ 17460786Sps 17560786Sps /* controller limits and features */ 17660786Sps int amr_maxio; /* maximum number of I/O transactions */ 17760786Sps int amr_maxdrives; /* max number of logical drives */ 17860786Sps int amr_maxchan; /* count of SCSI channels */ 17960786Sps 18060786Sps /* connected logical drives */ 18160786Sps struct amr_logdrive amr_drive[AMR_MAXLD]; 18260786Sps 18360786Sps /* controller state */ 18460786Sps int amr_state; 18560786Sps#define AMR_STATE_OPEN (1<<0) 18660786Sps#define AMR_STATE_SUSPEND (1<<1) 18760786Sps#define AMR_STATE_INTEN (1<<2) 18860786Sps#define AMR_STATE_SHUTDOWN (1<<3) 18960786Sps 19060786Sps /* per-controller queues */ 19160786Sps struct bio_queue_head amr_bioq; /* pending I/O with no commands */ 19260786Sps TAILQ_HEAD(,amr_command) amr_ready; /* commands ready to be submitted */ 193128348Stjr struct amr_command *amr_busycmd[AMR_MAXCMD]; 19489022Sps int amr_busyslots; 19560786Sps TAILQ_HEAD(,amr_command) amr_completed; 19660786Sps TAILQ_HEAD(,amr_command) amr_freecmds; 19760786Sps TAILQ_HEAD(,amr_command_cluster) amr_cmd_clusters; 19860786Sps 19960786Sps /* CAM attachments for passthrough */ 20060786Sps struct cam_sim *amr_cam_sim[AMR_MAX_CHANNELS]; 20160786Sps TAILQ_HEAD(, ccb_hdr) amr_cam_ccbq; 20260786Sps 20360786Sps /* control device */ 20460786Sps dev_t amr_dev_t; 20560786Sps 20660786Sps /* controller type-specific support */ 20760786Sps int amr_type; 208128348Stjr#define AMR_TYPE_QUARTZ (1<<0) 209128348Stjr#define AMR_IS_QUARTZ(sc) ((sc)->amr_type & AMR_TYPE_QUARTZ) 210128348Stjr#define AMR_TYPE_40LD (1<<1) 211128348Stjr#define AMR_IS_40LD(sc) ((sc)->amr_type & AMR_TYPE_40LD) 21260786Sps int (* amr_submit_command)(struct amr_softc *sc); 21360786Sps int (* amr_get_work)(struct amr_softc *sc, struct amr_mailbox *mbsave); 214128348Stjr int (*amr_poll_command)(struct amr_command *ac); 215128348Stjr int support_ext_cdb; /* greater than 10 byte cdb support */ 216128348Stjr 217128348Stjr /* misc glue */ 218128348Stjr struct intr_config_hook amr_ich; /* wait-for-interrupts probe hook */ 219128348Stjr struct callout_handle amr_timeout; /* periodic status check */ 22060786Sps#if __FreeBSD_version >= 500005 22160786Sps struct task amr_task_complete; /* deferred-completion task */ 22260786Sps#endif 22360786Sps}; 22460786Sps 22560786Sps/* 22660786Sps * Interface between bus connections and driver core. 22760786Sps */ 22860786Spsextern int amr_attach(struct amr_softc *sc); 22960786Spsextern void amr_free(struct amr_softc *sc); 23060786Spsextern int amr_flush(struct amr_softc *sc); 23160786Spsextern int amr_done(struct amr_softc *sc); 23260786Spsextern void amr_startio(struct amr_softc *sc); 23360786Sps 23460786Sps/* 23560786Sps * Command buffer allocation. 23660786Sps */ 23760786Spsextern struct amr_command *amr_alloccmd(struct amr_softc *sc); 23860786Spsextern void amr_releasecmd(struct amr_command *ac); 23960786Sps 24060786Sps/* 24160786Sps * CAM interface 24260786Sps */ 24360786Spsextern int amr_cam_attach(struct amr_softc *sc); 24460786Spsextern void amr_cam_detach(struct amr_softc *sc); 245170259Sdelphijextern int amr_cam_command(struct amr_softc *sc, struct amr_command **acp); 24660786Sps 24760786Sps/* 248128348Stjr * MegaRAID logical disk driver 24960786Sps */ 25060786Spsstruct amrd_softc 25160786Sps{ 25260786Sps device_t amrd_dev; 25360786Sps dev_t amrd_dev_t; 25460786Sps struct amr_softc *amrd_controller; 25560786Sps struct amr_logdrive *amrd_drive; 25689022Sps struct disk amrd_disk; 25760786Sps struct devstat amrd_stats; 25860786Sps int amrd_unit; 25960786Sps int amrd_flags; 26060786Sps#define AMRD_OPEN (1<<0) /* drive is open (can't detach) */ 26160786Sps}; 26260786Sps 26360786Sps/* 26460786Sps * Interface between driver core and disk driver (should be using a bus?) 26560786Sps */ 26660786Spsextern int amr_submit_bio(struct amr_softc *sc, struct bio *bio); 26760786Spsextern void amrd_intr(void *data); 26860786Sps 26960786Sps/******************************************************************************** 27060786Sps * Enqueue/dequeue functions 27160786Sps */ 27260786Spsstatic __inline void 27360786Spsamr_enqueue_bio(struct amr_softc *sc, struct bio *bio) 27460786Sps{ 27560786Sps int s; 27660786Sps 27760786Sps s = splbio(); 27860786Sps bioq_insert_tail(&sc->amr_bioq, bio); 27960786Sps splx(s); 28060786Sps} 28160786Sps 28260786Spsstatic __inline struct bio * 28360786Spsamr_dequeue_bio(struct amr_softc *sc) 28460786Sps{ 28560786Sps struct bio *bio; 28660786Sps int s; 28760786Sps 28860786Sps s = splbio(); 28960786Sps if ((bio = bioq_first(&sc->amr_bioq)) != NULL) 29060786Sps bioq_remove(&sc->amr_bioq, bio); 29160786Sps splx(s); 29260786Sps return(bio); 29360786Sps} 29460786Sps 29560786Spsstatic __inline void 296128348Stjramr_enqueue_ready(struct amr_command *ac) 29760786Sps{ 29860786Sps int s; 29960786Sps 30060786Sps s = splbio(); 30160786Sps TAILQ_INSERT_TAIL(&ac->ac_sc->amr_ready, ac, ac_link); 30260786Sps splx(s); 30360786Sps} 30460786Sps 30560786Spsstatic __inline void 30660786Spsamr_requeue_ready(struct amr_command *ac) 30760786Sps{ 30860786Sps int s; 30960786Sps 31060786Sps s = splbio(); 31160786Sps TAILQ_INSERT_HEAD(&ac->ac_sc->amr_ready, ac, ac_link); 31260786Sps splx(s); 31360786Sps} 31460786Sps 31560786Spsstatic __inline struct amr_command * 31660786Spsamr_dequeue_ready(struct amr_softc *sc) 31760786Sps{ 31860786Sps struct amr_command *ac; 31960786Sps int s; 32060786Sps 32160786Sps s = splbio(); 32260786Sps if ((ac = TAILQ_FIRST(&sc->amr_ready)) != NULL) 32360786Sps TAILQ_REMOVE(&sc->amr_ready, ac, ac_link); 32460786Sps splx(s); 32560786Sps return(ac); 32660786Sps} 32760786Sps 32860786Spsstatic __inline void 32960786Spsamr_enqueue_completed(struct amr_command *ac) 33060786Sps{ 331128348Stjr int s; 33260786Sps 33360786Sps s = splbio(); 33460786Sps TAILQ_INSERT_TAIL(&ac->ac_sc->amr_completed, ac, ac_link); 33560786Sps splx(s); 33660786Sps} 33760786Sps 33860786Spsstatic __inline struct amr_command * 33960786Spsamr_dequeue_completed(struct amr_softc *sc) 34060786Sps{ 34160786Sps struct amr_command *ac; 34260786Sps int s; 34360786Sps 34460786Sps s = splbio(); 34560786Sps if ((ac = TAILQ_FIRST(&sc->amr_completed)) != NULL) 34660786Sps TAILQ_REMOVE(&sc->amr_completed, ac, ac_link); 34760786Sps splx(s); 34860786Sps return(ac); 34960786Sps} 35060786Sps 35160786Spsstatic __inline void 35260786Spsamr_enqueue_free(struct amr_command *ac) 35360786Sps{ 35460786Sps int s; 35560786Sps 35660786Sps s = splbio(); 35760786Sps TAILQ_INSERT_TAIL(&ac->ac_sc->amr_freecmds, ac, ac_link); 35860786Sps splx(s); 35960786Sps} 36060786Sps 36160786Spsstatic __inline struct amr_command * 36260786Spsamr_dequeue_free(struct amr_softc *sc) 36360786Sps{ 36460786Sps struct amr_command *ac; 36560786Sps int s; 366161478Sdelphij 36760786Sps s = splbio(); 368161478Sdelphij if ((ac = TAILQ_FIRST(&sc->amr_freecmds)) != NULL) 369161478Sdelphij TAILQ_REMOVE(&sc->amr_freecmds, ac, ac_link); 37060786Sps splx(s); 37160786Sps return(ac); 372161478Sdelphij} 373161478Sdelphij