amrvar.h revision 65245
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 * 2751974Smsmith * $FreeBSD: head/sys/dev/amr/amrvar.h 65245 2000-08-30 07:52:50Z msmith $ 2851974Smsmith */ 2951974Smsmith 3065245Smsmith#if __FreeBSD_version >= 500005 3165245Smsmith# include <sys/taskqueue.h> 3265245Smsmith#endif 3351974Smsmith 3465245Smsmith#ifdef AMR_DEBUG 3565245Smsmith# define debug(level, fmt, args...) do {if (level <= AMR_DEBUG) printf("%s: " fmt "\n", __FUNCTION__ , ##args);} while(0) 3665245Smsmith# define debug_called(level) do {if (level <= AMR_DEBUG) printf("%s: called\n", __FUNCTION__);} while(0) 3765245Smsmith#else 3865245Smsmith# define debug(level, fmt, args...) 3965245Smsmith# define debug_called(level) 4065245Smsmith#endif 4165245Smsmith#define xdebug(fmt, args...) printf("%s: " fmt "\n", __FUNCTION__ , ##args) 4251974Smsmith 4351974Smsmith/* 4451974Smsmith * Per-logical-drive datastructure 4551974Smsmith */ 4651974Smsmithstruct amr_logdrive 4751974Smsmith{ 4851974Smsmith u_int32_t al_size; 4951974Smsmith int al_state; 5051974Smsmith int al_properties; 5151974Smsmith 5251974Smsmith /* synthetic geometry */ 5351974Smsmith int al_cylinders; 5451974Smsmith int al_heads; 5551974Smsmith int al_sectors; 5651974Smsmith 5751974Smsmith /* driver */ 5851974Smsmith device_t al_disk; 5951974Smsmith}; 6051974Smsmith 6165245Smsmith/* 6265245Smsmith * Due to the difficulty of using the zone allocator to create a new 6365245Smsmith * zone from within a module, we use our own clustering to reduce 6465245Smsmith * memory wastage due to allocating lots of these small structures. 6565245Smsmith * 6665245Smsmith * 16k gives us a little under 200 command structures, which should 6765245Smsmith * normally be plenty. We will grab more if we need them. 6865245Smsmith */ 6951974Smsmith 7065245Smsmith#define AMR_CMD_CLUSTERSIZE (16 * 1024) 7165245Smsmith 7251974Smsmith/* 7351974Smsmith * Per-command control structure. 7451974Smsmith */ 7551974Smsmithstruct amr_command 7651974Smsmith{ 7760938Sjake TAILQ_ENTRY(amr_command) ac_link; 7851974Smsmith 7951974Smsmith struct amr_softc *ac_sc; 8051974Smsmith u_int8_t ac_slot; 8165245Smsmith int ac_status; /* command completion status */ 8251974Smsmith struct amr_mailbox ac_mailbox; 8351974Smsmith int ac_flags; 8451974Smsmith#define AMR_CMD_DATAIN (1<<0) 8551974Smsmith#define AMR_CMD_DATAOUT (1<<1) 8665245Smsmith#define AMR_CMD_CCB_DATAIN (1<<2) 8765245Smsmith#define AMR_CMD_CCB_DATAOUT (1<<3) 8865245Smsmith#define AMR_CMD_PRIORITY (1<<4) 8965245Smsmith#define AMR_CMD_MAPPED (1<<5) 9065245Smsmith#define AMR_CMD_SLEEP (1<<6) 9165245Smsmith#define AMR_CMD_BUSY (1<<7) 9251974Smsmith 9365245Smsmith struct bio *ac_bio; 9465245Smsmith 9551974Smsmith void *ac_data; 9651974Smsmith size_t ac_length; 9751974Smsmith bus_dmamap_t ac_dmamap; 9851974Smsmith u_int32_t ac_dataphys; 9951974Smsmith 10065245Smsmith void *ac_ccb_data; 10165245Smsmith size_t ac_ccb_length; 10265245Smsmith bus_dmamap_t ac_ccb_dmamap; 10365245Smsmith u_int32_t ac_ccb_dataphys; 10465245Smsmith 10551974Smsmith void (* ac_complete)(struct amr_command *ac); 10651974Smsmith}; 10751974Smsmith 10865245Smsmithstruct amr_command_cluster 10965245Smsmith{ 11065245Smsmith TAILQ_ENTRY(amr_command_cluster) acc_link; 11165245Smsmith struct amr_command acc_command[0]; 11265245Smsmith}; 11365245Smsmith 11465245Smsmith#define AMR_CMD_CLUSTERCOUNT ((AMR_CMD_CLUSTERSIZE - sizeof(struct amr_command_cluster)) / \ 11565245Smsmith sizeof(struct amr_command)) 11665245Smsmith 11765245Smsmith/* 11865245Smsmith * Per-controller-instance data 11965245Smsmith */ 12051974Smsmithstruct amr_softc 12151974Smsmith{ 12251974Smsmith /* bus attachments */ 12351974Smsmith device_t amr_dev; 12451974Smsmith struct resource *amr_reg; /* control registers */ 12551974Smsmith bus_space_handle_t amr_bhandle; 12651974Smsmith bus_space_tag_t amr_btag; 12751974Smsmith bus_dma_tag_t amr_parent_dmat; /* parent DMA tag */ 12851974Smsmith bus_dma_tag_t amr_buffer_dmat; /* data buffer DMA tag */ 12951974Smsmith struct resource *amr_irq; /* interrupt */ 13051974Smsmith void *amr_intr; 13151974Smsmith 13251974Smsmith /* mailbox */ 13358496Smsmith volatile struct amr_mailbox *amr_mailbox; 13458496Smsmith volatile struct amr_mailbox64 *amr_mailbox64; 13551974Smsmith u_int32_t amr_mailboxphys; 13651974Smsmith bus_dma_tag_t amr_mailbox_dmat; 13751974Smsmith bus_dmamap_t amr_mailbox_dmamap; 13851974Smsmith 13951974Smsmith /* scatter/gather lists and their controller-visible mappings */ 14051974Smsmith struct amr_sgentry *amr_sgtable; /* s/g lists */ 14151974Smsmith u_int32_t amr_sgbusaddr; /* s/g table base address in bus space */ 14251974Smsmith bus_dma_tag_t amr_sg_dmat; /* s/g buffer DMA tag */ 14351974Smsmith bus_dmamap_t amr_sg_dmamap; /* map for s/g buffers */ 14451974Smsmith 14551974Smsmith /* controller limits and features */ 14651974Smsmith int amr_maxio; /* maximum number of I/O transactions */ 14751974Smsmith int amr_maxdrives; /* max number of logical drives */ 14865245Smsmith int amr_maxchan; /* count of SCSI channels */ 14951974Smsmith 15051974Smsmith /* connected logical drives */ 15151974Smsmith struct amr_logdrive amr_drive[AMR_MAXLD]; 15251974Smsmith 15365245Smsmith /* controller state */ 15451974Smsmith int amr_state; 15551974Smsmith#define AMR_STATE_OPEN (1<<0) 15651974Smsmith#define AMR_STATE_SUSPEND (1<<1) 15751974Smsmith#define AMR_STATE_INTEN (1<<2) 15851974Smsmith#define AMR_STATE_SHUTDOWN (1<<3) 15951974Smsmith 16051974Smsmith /* per-controller queues */ 16165245Smsmith struct bio_queue_head amr_bioq; /* pending I/O with no commands */ 16265245Smsmith TAILQ_HEAD(,amr_command) amr_ready; /* commands ready to be submitted */ 16351974Smsmith struct amr_command *amr_busycmd[AMR_MAXCMD]; 16465245Smsmith int amr_busyslots; 16565245Smsmith TAILQ_HEAD(,amr_command) amr_completed; 16660938Sjake TAILQ_HEAD(,amr_command) amr_freecmds; 16765245Smsmith TAILQ_HEAD(,amr_command_cluster) amr_cmd_clusters; 16851974Smsmith 16965245Smsmith /* CAM attachments for passthrough */ 17065245Smsmith struct cam_sim *amr_cam_sim[AMR_MAX_CHANNELS]; 17165245Smsmith TAILQ_HEAD(, ccb_hdr) amr_cam_ccbq; 17258883Smsmith 17365245Smsmith /* control device */ 17465245Smsmith dev_t amr_dev_t; 17565245Smsmith 17651974Smsmith /* controller type-specific support */ 17751974Smsmith int amr_type; 17865245Smsmith#define AMR_TYPE_QUARTZ (1<<0) 17965245Smsmith#define AMR_IS_QUARTZ(sc) ((sc)->amr_type & AMR_TYPE_QUARTZ) 18065245Smsmith#define AMR_TYPE_40LD (1<<1) 18165245Smsmith#define AMR_IS_40LD(sc) ((sc)->amr_type & AMR_TYPE_40LD) 18265245Smsmith int (* amr_submit_command)(struct amr_softc *sc); 18351974Smsmith int (* amr_get_work)(struct amr_softc *sc, struct amr_mailbox *mbsave); 18465245Smsmith 18565245Smsmith /* misc glue */ 18665245Smsmith struct intr_config_hook amr_ich; /* wait-for-interrupts probe hook */ 18765245Smsmith struct callout_handle amr_timeout; /* periodic status check */ 18865245Smsmith#if __FreeBSD_version >= 500005 18965245Smsmith struct task amr_task_complete; /* deferred-completion task */ 19065245Smsmith#endif 19151974Smsmith}; 19251974Smsmith 19351974Smsmith/* 19465245Smsmith * Interface between bus connections and driver core. 19558883Smsmith */ 19665245Smsmithextern int amr_attach(struct amr_softc *sc); 19765245Smsmithextern void amr_free(struct amr_softc *sc); 19865245Smsmithextern int amr_flush(struct amr_softc *sc); 19965245Smsmithextern int amr_done(struct amr_softc *sc); 20065245Smsmithextern void amr_startio(struct amr_softc *sc); 20158883Smsmith 20265245Smsmithextern devclass_t amr_devclass; 20358883Smsmith 20458883Smsmith/* 20565245Smsmith * Command buffer allocation. 20651974Smsmith */ 20765245Smsmithextern struct amr_command *amr_alloccmd(struct amr_softc *sc); 20865245Smsmithextern void amr_releasecmd(struct amr_command *ac); 20951974Smsmith 21051974Smsmith/* 21165245Smsmith * CAM interface 21251974Smsmith */ 21365245Smsmithextern int amr_cam_attach(struct amr_softc *sc); 21465245Smsmithextern void amr_cam_detach(struct amr_softc *sc); 21565245Smsmithextern int amr_cam_command(struct amr_softc *sc, struct amr_command **acp); 21651974Smsmith 21751974Smsmith/* 21851974Smsmith * MegaRAID logical disk driver 21951974Smsmith */ 22051974Smsmithstruct amrd_softc 22151974Smsmith{ 22251974Smsmith device_t amrd_dev; 22358883Smsmith dev_t amrd_dev_t; 22451974Smsmith struct amr_softc *amrd_controller; 22551974Smsmith struct amr_logdrive *amrd_drive; 22651974Smsmith struct disk amrd_disk; 22751974Smsmith struct devstat amrd_stats; 22851974Smsmith struct disklabel amrd_label; 22951974Smsmith int amrd_unit; 23051974Smsmith int amrd_flags; 23165245Smsmith#define AMRD_OPEN (1<<0) /* drive is open (can't detach) */ 23251974Smsmith}; 23351974Smsmith 23451974Smsmith/* 23551974Smsmith * Interface between driver core and disk driver (should be using a bus?) 23651974Smsmith */ 23765245Smsmithextern int amr_submit_bio(struct amr_softc *sc, struct bio *bio); 23851974Smsmithextern void amrd_intr(void *data); 23951974Smsmith 24065245Smsmith/******************************************************************************** 24165245Smsmith * Enqueue/dequeue functions 24265245Smsmith */ 24365245Smsmithstatic __inline void 24465245Smsmithamr_enqueue_bio(struct amr_softc *sc, struct bio *bio) 24565245Smsmith{ 24665245Smsmith int s; 24765245Smsmith 24865245Smsmith s = splbio(); 24965245Smsmith bioq_insert_tail(&sc->amr_bioq, bio); 25065245Smsmith splx(s); 25165245Smsmith} 25265245Smsmith 25365245Smsmithstatic __inline struct bio * 25465245Smsmithamr_dequeue_bio(struct amr_softc *sc) 25565245Smsmith{ 25665245Smsmith struct bio *bio; 25765245Smsmith int s; 25865245Smsmith 25965245Smsmith s = splbio(); 26065245Smsmith if ((bio = bioq_first(&sc->amr_bioq)) != NULL) 26165245Smsmith bioq_remove(&sc->amr_bioq, bio); 26265245Smsmith splx(s); 26365245Smsmith return(bio); 26465245Smsmith} 26565245Smsmith 26665245Smsmithstatic __inline void 26765245Smsmithamr_enqueue_ready(struct amr_command *ac) 26865245Smsmith{ 26965245Smsmith int s; 27065245Smsmith 27165245Smsmith s = splbio(); 27265245Smsmith TAILQ_INSERT_TAIL(&ac->ac_sc->amr_ready, ac, ac_link); 27365245Smsmith splx(s); 27465245Smsmith} 27565245Smsmith 27665245Smsmithstatic __inline void 27765245Smsmithamr_requeue_ready(struct amr_command *ac) 27865245Smsmith{ 27965245Smsmith int s; 28065245Smsmith 28165245Smsmith s = splbio(); 28265245Smsmith TAILQ_INSERT_HEAD(&ac->ac_sc->amr_ready, ac, ac_link); 28365245Smsmith splx(s); 28465245Smsmith} 28565245Smsmith 28665245Smsmithstatic __inline struct amr_command * 28765245Smsmithamr_dequeue_ready(struct amr_softc *sc) 28865245Smsmith{ 28965245Smsmith struct amr_command *ac; 29065245Smsmith int s; 29165245Smsmith 29265245Smsmith s = splbio(); 29365245Smsmith if ((ac = TAILQ_FIRST(&sc->amr_ready)) != NULL) 29465245Smsmith TAILQ_REMOVE(&sc->amr_ready, ac, ac_link); 29565245Smsmith splx(s); 29665245Smsmith return(ac); 29765245Smsmith} 29865245Smsmith 29965245Smsmithstatic __inline void 30065245Smsmithamr_enqueue_completed(struct amr_command *ac) 30165245Smsmith{ 30265245Smsmith int s; 30365245Smsmith 30465245Smsmith s = splbio(); 30565245Smsmith TAILQ_INSERT_TAIL(&ac->ac_sc->amr_completed, ac, ac_link); 30665245Smsmith splx(s); 30765245Smsmith} 30865245Smsmith 30965245Smsmithstatic __inline struct amr_command * 31065245Smsmithamr_dequeue_completed(struct amr_softc *sc) 31165245Smsmith{ 31265245Smsmith struct amr_command *ac; 31365245Smsmith int s; 31465245Smsmith 31565245Smsmith s = splbio(); 31665245Smsmith if ((ac = TAILQ_FIRST(&sc->amr_completed)) != NULL) 31765245Smsmith TAILQ_REMOVE(&sc->amr_completed, ac, ac_link); 31865245Smsmith splx(s); 31965245Smsmith return(ac); 32065245Smsmith} 32165245Smsmith 32265245Smsmithstatic __inline void 32365245Smsmithamr_enqueue_free(struct amr_command *ac) 32465245Smsmith{ 32565245Smsmith int s; 32665245Smsmith 32765245Smsmith s = splbio(); 32865245Smsmith TAILQ_INSERT_TAIL(&ac->ac_sc->amr_freecmds, ac, ac_link); 32965245Smsmith splx(s); 33065245Smsmith} 33165245Smsmith 33265245Smsmithstatic __inline struct amr_command * 33365245Smsmithamr_dequeue_free(struct amr_softc *sc) 33465245Smsmith{ 33565245Smsmith struct amr_command *ac; 33665245Smsmith int s; 33765245Smsmith 33865245Smsmith s = splbio(); 33965245Smsmith if ((ac = TAILQ_FIRST(&sc->amr_freecmds)) != NULL) 34065245Smsmith TAILQ_REMOVE(&sc->amr_freecmds, ac, ac_link); 34165245Smsmith splx(s); 34265245Smsmith return(ac); 34365245Smsmith} 344