amrvar.h revision 140688
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 140688 2005-01-23 23:25:41Z scottl $ 5751974Smsmith */ 5851974Smsmith 5965245Smsmith#if __FreeBSD_version >= 500005 60112946Sphk# include <geom/geom_disk.h> 61140340Sscottl# include <sys/lock.h> 62140340Sscottl# include <sys/mutex.h> 6365245Smsmith#endif 6451974Smsmith 65140688Sscottl#define LSI_DESC_PCI "LSILogic MegaRAID 1.51" 66140688Sscottl 6765245Smsmith#ifdef AMR_DEBUG 6887599Sobrien# define debug(level, fmt, args...) do {if (level <= AMR_DEBUG) printf("%s: " fmt "\n", __func__ , ##args);} while(0) 6987599Sobrien# define debug_called(level) do {if (level <= AMR_DEBUG) printf("%s: called\n", __func__);} while(0) 7065245Smsmith#else 7165245Smsmith# define debug(level, fmt, args...) 7265245Smsmith# define debug_called(level) 7365245Smsmith#endif 7487599Sobrien#define xdebug(fmt, args...) printf("%s: " fmt "\n", __func__ , ##args) 7551974Smsmith 7651974Smsmith/* 7751974Smsmith * Per-logical-drive datastructure 7851974Smsmith */ 7951974Smsmithstruct amr_logdrive 8051974Smsmith{ 8151974Smsmith u_int32_t al_size; 8251974Smsmith int al_state; 8351974Smsmith int al_properties; 8451974Smsmith 8551974Smsmith /* synthetic geometry */ 8651974Smsmith int al_cylinders; 8751974Smsmith int al_heads; 8851974Smsmith int al_sectors; 8951974Smsmith 9051974Smsmith /* driver */ 9151974Smsmith device_t al_disk; 9251974Smsmith}; 9351974Smsmith 9465245Smsmith/* 9565245Smsmith * Due to the difficulty of using the zone allocator to create a new 9665245Smsmith * zone from within a module, we use our own clustering to reduce 9765245Smsmith * memory wastage due to allocating lots of these small structures. 9865245Smsmith * 9965245Smsmith * 16k gives us a little under 200 command structures, which should 10065245Smsmith * normally be plenty. We will grab more if we need them. 10165245Smsmith */ 10251974Smsmith 10365245Smsmith#define AMR_CMD_CLUSTERSIZE (16 * 1024) 10465245Smsmith 10551974Smsmith/* 10651974Smsmith * Per-command control structure. 10751974Smsmith */ 10851974Smsmithstruct amr_command 10951974Smsmith{ 11060938Sjake TAILQ_ENTRY(amr_command) ac_link; 11151974Smsmith 11251974Smsmith struct amr_softc *ac_sc; 11351974Smsmith u_int8_t ac_slot; 11465245Smsmith int ac_status; /* command completion status */ 11551974Smsmith struct amr_mailbox ac_mailbox; 11651974Smsmith int ac_flags; 11751974Smsmith#define AMR_CMD_DATAIN (1<<0) 11851974Smsmith#define AMR_CMD_DATAOUT (1<<1) 11965245Smsmith#define AMR_CMD_CCB_DATAIN (1<<2) 12065245Smsmith#define AMR_CMD_CCB_DATAOUT (1<<3) 12165245Smsmith#define AMR_CMD_PRIORITY (1<<4) 12265245Smsmith#define AMR_CMD_MAPPED (1<<5) 12365245Smsmith#define AMR_CMD_SLEEP (1<<6) 12465245Smsmith#define AMR_CMD_BUSY (1<<7) 12551974Smsmith 12665245Smsmith struct bio *ac_bio; 12765245Smsmith 12851974Smsmith void *ac_data; 12951974Smsmith size_t ac_length; 13051974Smsmith bus_dmamap_t ac_dmamap; 13151974Smsmith u_int32_t ac_dataphys; 13251974Smsmith 13365245Smsmith void *ac_ccb_data; 13465245Smsmith size_t ac_ccb_length; 13565245Smsmith bus_dmamap_t ac_ccb_dmamap; 13665245Smsmith u_int32_t ac_ccb_dataphys; 13765245Smsmith 13851974Smsmith void (* ac_complete)(struct amr_command *ac); 139105419Semoore void *ac_private; 14051974Smsmith}; 14151974Smsmith 14265245Smsmithstruct amr_command_cluster 14365245Smsmith{ 14465245Smsmith TAILQ_ENTRY(amr_command_cluster) acc_link; 14565245Smsmith struct amr_command acc_command[0]; 14665245Smsmith}; 14765245Smsmith 14865245Smsmith#define AMR_CMD_CLUSTERCOUNT ((AMR_CMD_CLUSTERSIZE - sizeof(struct amr_command_cluster)) / \ 14965245Smsmith sizeof(struct amr_command)) 15065245Smsmith 15165245Smsmith/* 15265245Smsmith * Per-controller-instance data 15365245Smsmith */ 15451974Smsmithstruct amr_softc 15551974Smsmith{ 15651974Smsmith /* bus attachments */ 15751974Smsmith device_t amr_dev; 15851974Smsmith struct resource *amr_reg; /* control registers */ 15951974Smsmith bus_space_handle_t amr_bhandle; 16051974Smsmith bus_space_tag_t amr_btag; 16151974Smsmith bus_dma_tag_t amr_parent_dmat; /* parent DMA tag */ 16251974Smsmith bus_dma_tag_t amr_buffer_dmat; /* data buffer DMA tag */ 16351974Smsmith struct resource *amr_irq; /* interrupt */ 16451974Smsmith void *amr_intr; 16551974Smsmith 16651974Smsmith /* mailbox */ 16758496Smsmith volatile struct amr_mailbox *amr_mailbox; 16858496Smsmith volatile struct amr_mailbox64 *amr_mailbox64; 16951974Smsmith u_int32_t amr_mailboxphys; 17051974Smsmith bus_dma_tag_t amr_mailbox_dmat; 17151974Smsmith bus_dmamap_t amr_mailbox_dmamap; 17251974Smsmith 17351974Smsmith /* scatter/gather lists and their controller-visible mappings */ 17451974Smsmith struct amr_sgentry *amr_sgtable; /* s/g lists */ 17551974Smsmith u_int32_t amr_sgbusaddr; /* s/g table base address in bus space */ 17651974Smsmith bus_dma_tag_t amr_sg_dmat; /* s/g buffer DMA tag */ 17751974Smsmith bus_dmamap_t amr_sg_dmamap; /* map for s/g buffers */ 17851974Smsmith 17951974Smsmith /* controller limits and features */ 180140340Sscottl int amr_nextslot; /* Next slot to use for newly allocated commands */ 18151974Smsmith int amr_maxio; /* maximum number of I/O transactions */ 18251974Smsmith int amr_maxdrives; /* max number of logical drives */ 18365245Smsmith int amr_maxchan; /* count of SCSI channels */ 18451974Smsmith 18551974Smsmith /* connected logical drives */ 18651974Smsmith struct amr_logdrive amr_drive[AMR_MAXLD]; 18751974Smsmith 18865245Smsmith /* controller state */ 18951974Smsmith int amr_state; 19051974Smsmith#define AMR_STATE_OPEN (1<<0) 19151974Smsmith#define AMR_STATE_SUSPEND (1<<1) 19251974Smsmith#define AMR_STATE_INTEN (1<<2) 19351974Smsmith#define AMR_STATE_SHUTDOWN (1<<3) 194131394Sps#define AMR_STATE_CRASHDUMP (1<<4) 195138422Sscottl#define AMR_STATE_QUEUE_FRZN (1<<5) 19651974Smsmith 19751974Smsmith /* per-controller queues */ 19865245Smsmith struct bio_queue_head amr_bioq; /* pending I/O with no commands */ 19965245Smsmith TAILQ_HEAD(,amr_command) amr_ready; /* commands ready to be submitted */ 20051974Smsmith struct amr_command *amr_busycmd[AMR_MAXCMD]; 20165245Smsmith int amr_busyslots; 20265245Smsmith TAILQ_HEAD(,amr_command) amr_completed; 20360938Sjake TAILQ_HEAD(,amr_command) amr_freecmds; 20465245Smsmith TAILQ_HEAD(,amr_command_cluster) amr_cmd_clusters; 20551974Smsmith 20665245Smsmith /* CAM attachments for passthrough */ 20765245Smsmith struct cam_sim *amr_cam_sim[AMR_MAX_CHANNELS]; 20865245Smsmith TAILQ_HEAD(, ccb_hdr) amr_cam_ccbq; 209139952Sdwhite struct cam_devq *amr_cam_devq; 21058883Smsmith 21165245Smsmith /* control device */ 212130585Sphk struct cdev *amr_dev_t; 21365245Smsmith 21451974Smsmith /* controller type-specific support */ 21551974Smsmith int amr_type; 21665245Smsmith#define AMR_TYPE_QUARTZ (1<<0) 21765245Smsmith#define AMR_IS_QUARTZ(sc) ((sc)->amr_type & AMR_TYPE_QUARTZ) 21865245Smsmith#define AMR_TYPE_40LD (1<<1) 21965245Smsmith#define AMR_IS_40LD(sc) ((sc)->amr_type & AMR_TYPE_40LD) 22065245Smsmith int (* amr_submit_command)(struct amr_softc *sc); 22151974Smsmith int (* amr_get_work)(struct amr_softc *sc, struct amr_mailbox *mbsave); 222107756Semoore int (*amr_poll_command)(struct amr_command *ac); 223138422Sscottl int (*amr_poll_command1)(struct amr_softc *sc, struct amr_command *ac); 224107756Semoore int support_ext_cdb; /* greater than 10 byte cdb support */ 22565245Smsmith 22665245Smsmith /* misc glue */ 22765245Smsmith struct intr_config_hook amr_ich; /* wait-for-interrupts probe hook */ 22865245Smsmith struct callout_handle amr_timeout; /* periodic status check */ 229140340Sscottl struct mtx amr_io_lock; 23051974Smsmith}; 23151974Smsmith 23251974Smsmith/* 23365245Smsmith * Interface between bus connections and driver core. 23458883Smsmith */ 23565245Smsmithextern int amr_attach(struct amr_softc *sc); 23665245Smsmithextern void amr_free(struct amr_softc *sc); 23765245Smsmithextern int amr_flush(struct amr_softc *sc); 23865245Smsmithextern int amr_done(struct amr_softc *sc); 23965245Smsmithextern void amr_startio(struct amr_softc *sc); 24058883Smsmith 24158883Smsmith/* 24265245Smsmith * Command buffer allocation. 24351974Smsmith */ 24465245Smsmithextern struct amr_command *amr_alloccmd(struct amr_softc *sc); 24565245Smsmithextern void amr_releasecmd(struct amr_command *ac); 24651974Smsmith 24751974Smsmith/* 24865245Smsmith * CAM interface 24951974Smsmith */ 25065245Smsmithextern int amr_cam_attach(struct amr_softc *sc); 25165245Smsmithextern void amr_cam_detach(struct amr_softc *sc); 25265245Smsmithextern int amr_cam_command(struct amr_softc *sc, struct amr_command **acp); 25351974Smsmith 25451974Smsmith/* 25551974Smsmith * MegaRAID logical disk driver 25651974Smsmith */ 25751974Smsmithstruct amrd_softc 25851974Smsmith{ 25951974Smsmith device_t amrd_dev; 26051974Smsmith struct amr_softc *amrd_controller; 26151974Smsmith struct amr_logdrive *amrd_drive; 262125975Sphk struct disk *amrd_disk; 26351974Smsmith int amrd_unit; 26451974Smsmith}; 26551974Smsmith 26651974Smsmith/* 26751974Smsmith * Interface between driver core and disk driver (should be using a bus?) 26851974Smsmith */ 26965245Smsmithextern int amr_submit_bio(struct amr_softc *sc, struct bio *bio); 270120988Spsextern int amr_dump_blocks(struct amr_softc *sc, int unit, u_int32_t lba, void *data, int blks); 27151974Smsmithextern void amrd_intr(void *data); 27251974Smsmith 27365245Smsmith/******************************************************************************** 27465245Smsmith * Enqueue/dequeue functions 27565245Smsmith */ 27665245Smsmithstatic __inline void 27765245Smsmithamr_enqueue_bio(struct amr_softc *sc, struct bio *bio) 27865245Smsmith{ 27965245Smsmith int s; 28065245Smsmith 28165245Smsmith s = splbio(); 28265245Smsmith bioq_insert_tail(&sc->amr_bioq, bio); 28365245Smsmith splx(s); 28465245Smsmith} 28565245Smsmith 28665245Smsmithstatic __inline struct bio * 28765245Smsmithamr_dequeue_bio(struct amr_softc *sc) 28865245Smsmith{ 28965245Smsmith struct bio *bio; 29065245Smsmith int s; 29165245Smsmith 29265245Smsmith s = splbio(); 29365245Smsmith if ((bio = bioq_first(&sc->amr_bioq)) != NULL) 29465245Smsmith bioq_remove(&sc->amr_bioq, bio); 29565245Smsmith splx(s); 29665245Smsmith return(bio); 29765245Smsmith} 29865245Smsmith 29965245Smsmithstatic __inline void 30065245Smsmithamr_enqueue_ready(struct amr_command *ac) 30165245Smsmith{ 30265245Smsmith int s; 30365245Smsmith 30465245Smsmith s = splbio(); 30565245Smsmith TAILQ_INSERT_TAIL(&ac->ac_sc->amr_ready, ac, ac_link); 30665245Smsmith splx(s); 30765245Smsmith} 30865245Smsmith 30965245Smsmithstatic __inline void 31065245Smsmithamr_requeue_ready(struct amr_command *ac) 31165245Smsmith{ 31265245Smsmith int s; 31365245Smsmith 31465245Smsmith s = splbio(); 31565245Smsmith TAILQ_INSERT_HEAD(&ac->ac_sc->amr_ready, ac, ac_link); 31665245Smsmith splx(s); 31765245Smsmith} 31865245Smsmith 31965245Smsmithstatic __inline struct amr_command * 32065245Smsmithamr_dequeue_ready(struct amr_softc *sc) 32165245Smsmith{ 32265245Smsmith struct amr_command *ac; 32365245Smsmith int s; 32465245Smsmith 32565245Smsmith s = splbio(); 32665245Smsmith if ((ac = TAILQ_FIRST(&sc->amr_ready)) != NULL) 32765245Smsmith TAILQ_REMOVE(&sc->amr_ready, ac, ac_link); 32865245Smsmith splx(s); 32965245Smsmith return(ac); 33065245Smsmith} 33165245Smsmith 33265245Smsmithstatic __inline void 33365245Smsmithamr_enqueue_completed(struct amr_command *ac) 33465245Smsmith{ 33565245Smsmith int s; 33665245Smsmith 33765245Smsmith s = splbio(); 33865245Smsmith TAILQ_INSERT_TAIL(&ac->ac_sc->amr_completed, ac, ac_link); 33965245Smsmith splx(s); 34065245Smsmith} 34165245Smsmith 34265245Smsmithstatic __inline struct amr_command * 34365245Smsmithamr_dequeue_completed(struct amr_softc *sc) 34465245Smsmith{ 34565245Smsmith struct amr_command *ac; 34665245Smsmith int s; 34765245Smsmith 34865245Smsmith s = splbio(); 34965245Smsmith if ((ac = TAILQ_FIRST(&sc->amr_completed)) != NULL) 35065245Smsmith TAILQ_REMOVE(&sc->amr_completed, ac, ac_link); 35165245Smsmith splx(s); 35265245Smsmith return(ac); 35365245Smsmith} 35465245Smsmith 35565245Smsmithstatic __inline void 35665245Smsmithamr_enqueue_free(struct amr_command *ac) 35765245Smsmith{ 35865245Smsmith int s; 35965245Smsmith 36065245Smsmith s = splbio(); 36165245Smsmith TAILQ_INSERT_TAIL(&ac->ac_sc->amr_freecmds, ac, ac_link); 36265245Smsmith splx(s); 36365245Smsmith} 36465245Smsmith 36565245Smsmithstatic __inline struct amr_command * 36665245Smsmithamr_dequeue_free(struct amr_softc *sc) 36765245Smsmith{ 36865245Smsmith struct amr_command *ac; 36965245Smsmith int s; 37065245Smsmith 37165245Smsmith s = splbio(); 37265245Smsmith if ((ac = TAILQ_FIRST(&sc->amr_freecmds)) != NULL) 37365245Smsmith TAILQ_REMOVE(&sc->amr_freecmds, ac, ac_link); 37465245Smsmith splx(s); 37565245Smsmith return(ac); 37665245Smsmith} 377