The Design and Implementation of the FreeBSD Operating System, Second Edition
Now available: The Design and Implementation of the FreeBSD Operating System (Second Edition)


[ source navigation ] [ diff markup ] [ identifier search ] [ freetext search ] [ file search ] [ list types ] [ track identifier ]

FreeBSD/Linux Kernel Cross Reference
sys/dev/amr/amrvar.h

Version: -  FREEBSD  -  FREEBSD-13-STABLE  -  FREEBSD-13-0  -  FREEBSD-12-STABLE  -  FREEBSD-12-0  -  FREEBSD-11-STABLE  -  FREEBSD-11-0  -  FREEBSD-10-STABLE  -  FREEBSD-10-0  -  FREEBSD-9-STABLE  -  FREEBSD-9-0  -  FREEBSD-8-STABLE  -  FREEBSD-8-0  -  FREEBSD-7-STABLE  -  FREEBSD-7-0  -  FREEBSD-6-STABLE  -  FREEBSD-6-0  -  FREEBSD-5-STABLE  -  FREEBSD-5-0  -  FREEBSD-4-STABLE  -  FREEBSD-3-STABLE  -  FREEBSD22  -  l41  -  OPENBSD  -  linux-2.6  -  MK84  -  PLAN9  -  xnu-8792 
SearchContext: -  none  -  3  -  10 

    1 /*-
    2  * Copyright (c) 1999,2000 Michael Smith
    3  * Copyright (c) 2000 BSDi
    4  * All rights reserved.
    5  *
    6  * Redistribution and use in source and binary forms, with or without
    7  * modification, are permitted provided that the following conditions
    8  * are met:
    9  * 1. Redistributions of source code must retain the above copyright
   10  *    notice, this list of conditions and the following disclaimer.
   11  * 2. Redistributions in binary form must reproduce the above copyright
   12  *    notice, this list of conditions and the following disclaimer in the
   13  *    documentation and/or other materials provided with the distribution.
   14  *
   15  * THIS SOFTWARE IS PROVIDED BY THE AUTHOR AND CONTRIBUTORS ``AS IS'' AND
   16  * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
   17  * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
   18  * ARE DISCLAIMED.  IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE
   19  * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
   20  * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
   21  * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
   22  * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
   23  * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
   24  * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
   25  * SUCH DAMAGE.
   26  *
   27  * Copyright (c) 2002 Eric Moore
   28  * Copyright (c) 2002 LSI Logic Corporation
   29  * All rights reserved.
   30  *
   31  * Redistribution and use in source and binary forms, with or without
   32  * modification, are permitted provided that the following conditions
   33  * are met:
   34  * 1. Redistributions of source code must retain the above copyright
   35  *    notice, this list of conditions and the following disclaimer.
   36  * 2. Redistributions in binary form must reproduce the above copyright
   37  *    notice, this list of conditions and the following disclaimer in the
   38  *    documentation and/or other materials provided with the distribution.
   39  * 3. The party using or redistributing the source code and binary forms
   40  *    agrees to the disclaimer below and the terms and conditions set forth
   41  *    herein.
   42  *
   43  * THIS SOFTWARE IS PROVIDED BY THE AUTHOR AND CONTRIBUTORS ``AS IS'' AND
   44  * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
   45  * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
   46  * ARE DISCLAIMED.  IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE
   47  * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
   48  * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
   49  * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
   50  * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
   51  * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
   52  * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
   53  * SUCH DAMAGE.
   54  *
   55  *
   56  *      $FreeBSD: releng/9.0/sys/dev/amr/amrvar.h 210570 2010-07-28 16:24:11Z mdf $
   57  */
   58 
   59 #include <geom/geom_disk.h>
   60 #include <sys/lock.h>
   61 #include <sys/mutex.h>
   62 
   63 #define LSI_DESC_PCI "LSILogic MegaRAID 1.53"
   64 
   65 #ifdef AMR_DEBUG
   66 # define debug(level, fmt, args...)     do {if (level <= AMR_DEBUG) printf("%s: " fmt "\n", __func__ , ##args);} while(0)
   67 # define debug_called(level)            do {if (level <= AMR_DEBUG) printf("%s: called\n", __func__);} while(0)
   68 #else
   69 # define debug(level, fmt, args...)     do {} while (0)
   70 # define debug_called(level)            do {} while (0)
   71 #endif
   72 #define xdebug(fmt, args...)    printf("%s: " fmt "\n", __func__ , ##args)
   73 
   74 /*
   75  * Per-logical-drive datastructure
   76  */
   77 struct amr_logdrive
   78 {
   79     u_int32_t   al_size;
   80     int         al_state;
   81     int         al_properties;
   82     
   83     /* synthetic geometry */
   84     int         al_cylinders;
   85     int         al_heads;
   86     int         al_sectors;
   87     
   88     /* driver */
   89     device_t    al_disk;
   90 };
   91 
   92 /*
   93  * Due to the difficulty of using the zone allocator to create a new
   94  * zone from within a module, we use our own clustering to reduce 
   95  * memory wastage due to allocating lots of these small structures.
   96  *
   97  * 16k gives us a little under 200 command structures, which should
   98  * normally be plenty.  We will grab more if we need them.
   99  */
  100 
  101 #define AMR_CMD_CLUSTERSIZE     (16 * 1024)
  102 
  103 typedef STAILQ_HEAD(, amr_command)      ac_qhead_t;
  104 typedef STAILQ_ENTRY(amr_command)       ac_link_t;
  105 
  106 union amr_ccb {
  107     struct amr_passthrough      ccb_pthru;
  108     struct amr_ext_passthrough  ccb_epthru;
  109     uint8_t                     bytes[128];
  110 };
  111 
  112 /*
  113  * Per-command control structure.
  114  */
  115 struct amr_command
  116 {
  117     ac_link_t                   ac_link;
  118 
  119     struct amr_softc            *ac_sc;
  120     u_int8_t                    ac_slot;
  121     int                         ac_status;      /* command completion status */
  122     union {
  123         struct amr_sgentry      *sg32;
  124         struct amr_sg64entry    *sg64;
  125     } ac_sg;
  126     u_int32_t                   ac_sgbusaddr;
  127     u_int32_t                   ac_sg64_lo;
  128     u_int32_t                   ac_sg64_hi;
  129     struct amr_mailbox          ac_mailbox;
  130     int                         ac_flags;
  131 #define AMR_CMD_DATAIN          (1<<0)
  132 #define AMR_CMD_DATAOUT         (1<<1)
  133 #define AMR_CMD_CCB             (1<<2)
  134 #define AMR_CMD_PRIORITY        (1<<4)
  135 #define AMR_CMD_MAPPED          (1<<5)
  136 #define AMR_CMD_SLEEP           (1<<6)
  137 #define AMR_CMD_BUSY            (1<<7)
  138 #define AMR_CMD_SG64            (1<<8)
  139 #define AC_IS_SG64(ac)          ((ac)->ac_flags & AMR_CMD_SG64)
  140     u_int                       ac_retries;
  141 
  142     struct bio                  *ac_bio;
  143     void                        (* ac_complete)(struct amr_command *ac);
  144     void                        *ac_private;
  145 
  146     void                        *ac_data;
  147     size_t                      ac_length;
  148     bus_dmamap_t                ac_dmamap;
  149     bus_dmamap_t                ac_dma64map;
  150 
  151     bus_dma_tag_t               ac_tag;
  152     bus_dmamap_t                ac_datamap;
  153     int                         ac_nsegments;
  154     uint32_t                    ac_mb_physaddr;
  155 
  156     union amr_ccb               *ac_ccb;
  157     uint32_t                    ac_ccb_busaddr;
  158 };
  159 
  160 struct amr_command_cluster
  161 {
  162     TAILQ_ENTRY(amr_command_cluster)    acc_link;
  163     struct amr_command          acc_command[0];
  164 };
  165 
  166 #define AMR_CMD_CLUSTERCOUNT    ((AMR_CMD_CLUSTERSIZE - sizeof(struct amr_command_cluster)) /   \
  167                                  sizeof(struct amr_command))
  168 
  169 /*
  170  * Per-controller-instance data
  171  */
  172 struct amr_softc 
  173 {
  174     /* bus attachments */
  175     device_t                    amr_dev;
  176     struct resource             *amr_reg;               /* control registers */
  177     bus_space_handle_t          amr_bhandle;
  178     bus_space_tag_t             amr_btag;
  179     bus_dma_tag_t               amr_parent_dmat;        /* parent DMA tag */
  180     bus_dma_tag_t               amr_buffer_dmat;        /* data buffer DMA tag */
  181     bus_dma_tag_t               amr_buffer64_dmat;
  182     struct resource             *amr_irq;               /* interrupt */
  183     void                        *amr_intr;
  184 
  185     /* mailbox */
  186     volatile struct amr_mailbox         *amr_mailbox;
  187     volatile struct amr_mailbox64       *amr_mailbox64;
  188     u_int32_t                   amr_mailboxphys;
  189     bus_dma_tag_t               amr_mailbox_dmat;
  190     bus_dmamap_t                amr_mailbox_dmamap;
  191 
  192     /* scatter/gather lists and their controller-visible mappings */
  193     struct amr_sgentry          *amr_sgtable;           /* s/g lists */
  194     struct amr_sg64entry        *amr_sg64table;         /* 64bit s/g lists */
  195     u_int32_t                   amr_sgbusaddr;          /* s/g table base address in bus space */
  196     bus_dma_tag_t               amr_sg_dmat;            /* s/g buffer DMA tag */
  197     bus_dmamap_t                amr_sg_dmamap;          /* map for s/g buffers */
  198 
  199     union amr_ccb               *amr_ccb;
  200     uint32_t                    amr_ccb_busaddr;
  201     bus_dma_tag_t               amr_ccb_dmat;
  202     bus_dmamap_t                amr_ccb_dmamap;
  203 
  204     /* controller limits and features */
  205     int                         amr_nextslot;           /* Next slot to use for newly allocated commands */
  206     int                         amr_maxio;              /* maximum number of I/O transactions */
  207     int                         amr_maxdrives;          /* max number of logical drives */
  208     int                         amr_maxchan;            /* count of SCSI channels */
  209     
  210     /* connected logical drives */
  211     struct amr_logdrive         amr_drive[AMR_MAXLD];
  212 
  213     /* controller state */
  214     int                         amr_state;
  215 #define AMR_STATE_OPEN          (1<<0)
  216 #define AMR_STATE_SUSPEND       (1<<1)
  217 #define AMR_STATE_INTEN         (1<<2)
  218 #define AMR_STATE_SHUTDOWN      (1<<3)
  219 #define AMR_STATE_CRASHDUMP     (1<<4)
  220 #define AMR_STATE_QUEUE_FRZN    (1<<5)
  221 #define AMR_STATE_LD_DELETE     (1<<6)
  222 #define AMR_STATE_REMAP_LD      (1<<7)
  223 
  224     /* per-controller queues */
  225     struct bio_queue_head       amr_bioq;               /* pending I/O with no commands */
  226     ac_qhead_t                  amr_ready;              /* commands ready to be submitted */
  227     struct amr_command          *amr_busycmd[AMR_MAXCMD];
  228     int                         amr_busyslots;
  229     ac_qhead_t                  amr_freecmds;
  230     TAILQ_HEAD(,amr_command_cluster)    amr_cmd_clusters;
  231 
  232     /* CAM attachments for passthrough */
  233     struct cam_sim              *amr_cam_sim[AMR_MAX_CHANNELS];
  234     TAILQ_HEAD(, ccb_hdr)       amr_cam_ccbq;
  235     struct cam_devq             *amr_cam_devq;
  236 
  237     /* control device */
  238     struct cdev                 *amr_dev_t;
  239     struct mtx                  amr_list_lock;
  240 
  241     /* controller type-specific support */
  242     int                         amr_type;
  243 #define AMR_TYPE_QUARTZ         (1<<0)
  244 #define AMR_IS_QUARTZ(sc)       ((sc)->amr_type & AMR_TYPE_QUARTZ)
  245 #define AMR_TYPE_40LD           (1<<1)
  246 #define AMR_IS_40LD(sc)         ((sc)->amr_type & AMR_TYPE_40LD)
  247 #define AMR_TYPE_SG64           (1<<2)
  248 #define AMR_IS_SG64(sc)         ((sc)->amr_type & AMR_TYPE_SG64)
  249     int                         (* amr_submit_command)(struct amr_command *ac);
  250     int                         (* amr_get_work)(struct amr_softc *sc, struct amr_mailbox *mbsave);
  251     int                         (*amr_poll_command)(struct amr_command *ac);
  252     int                         (*amr_poll_command1)(struct amr_softc *sc, struct amr_command *ac);
  253     int                         support_ext_cdb;        /* greater than 10 byte cdb support */
  254 
  255     /* misc glue */
  256     device_t                    amr_pass;
  257     int                         (*amr_cam_command)(struct amr_softc *sc, struct amr_command **acp);
  258     struct intr_config_hook     amr_ich;                /* wait-for-interrupts probe hook */
  259     struct callout_handle       amr_timeout;            /* periodic status check */
  260     int                         amr_allow_vol_config;
  261     int                         amr_linux_no_adapters;
  262     int                         amr_ld_del_supported;
  263     struct mtx                  amr_hw_lock;
  264 };
  265 
  266 /*
  267  * Interface between bus connections and driver core.
  268  */
  269 extern int              amr_attach(struct amr_softc *sc);
  270 extern void             amr_free(struct amr_softc *sc);
  271 extern int              amr_flush(struct amr_softc *sc);
  272 extern int              amr_done(struct amr_softc *sc);
  273 extern void             amr_startio(struct amr_softc *sc);
  274 
  275 /*
  276  * Command buffer allocation.
  277  */
  278 extern struct amr_command       *amr_alloccmd(struct amr_softc *sc);
  279 extern void                     amr_releasecmd(struct amr_command *ac);
  280 
  281 /*
  282  * MegaRAID logical disk driver
  283  */
  284 struct amrd_softc 
  285 {
  286     device_t            amrd_dev;
  287     struct amr_softc    *amrd_controller;
  288     struct amr_logdrive *amrd_drive;
  289     struct disk         *amrd_disk;
  290     int                 amrd_unit;
  291 };
  292 
  293 /*
  294  * Interface between driver core and disk driver (should be using a bus?)
  295  */
  296 extern int      amr_submit_bio(struct amr_softc *sc, struct bio *bio);
  297 extern int      amr_dump_blocks(struct amr_softc *sc, int unit, u_int32_t lba, void *data, int blks);
  298 extern void     amrd_intr(void *data);
  299 
  300 /********************************************************************************
  301  * Enqueue/dequeue functions
  302  */
  303 static __inline void
  304 amr_enqueue_bio(struct amr_softc *sc, struct bio *bio)
  305 {
  306 
  307     bioq_insert_tail(&sc->amr_bioq, bio);
  308 }
  309 
  310 static __inline struct bio *
  311 amr_dequeue_bio(struct amr_softc *sc)
  312 {
  313     struct bio  *bio;
  314 
  315     if ((bio = bioq_first(&sc->amr_bioq)) != NULL)
  316         bioq_remove(&sc->amr_bioq, bio);
  317     return(bio);
  318 }
  319 
  320 static __inline void
  321 amr_init_qhead(ac_qhead_t *head)
  322 {
  323 
  324         STAILQ_INIT(head);
  325 }
  326 
  327 static __inline void
  328 amr_enqueue_ready(struct amr_command *ac)
  329 {
  330 
  331     STAILQ_INSERT_TAIL(&ac->ac_sc->amr_ready, ac, ac_link);
  332 }
  333 
  334 static __inline void
  335 amr_requeue_ready(struct amr_command *ac)
  336 {
  337 
  338     STAILQ_INSERT_HEAD(&ac->ac_sc->amr_ready, ac, ac_link);
  339 }
  340 
  341 static __inline struct amr_command *
  342 amr_dequeue_ready(struct amr_softc *sc)
  343 {
  344     struct amr_command  *ac;
  345 
  346     if ((ac = STAILQ_FIRST(&sc->amr_ready)) != NULL)
  347         STAILQ_REMOVE_HEAD(&sc->amr_ready, ac_link);
  348     return(ac);
  349 }
  350 
  351 static __inline void
  352 amr_enqueue_completed(struct amr_command *ac, ac_qhead_t *head)
  353 {
  354 
  355     STAILQ_INSERT_TAIL(head, ac, ac_link);
  356 }
  357 
  358 static __inline struct amr_command *
  359 amr_dequeue_completed(struct amr_softc *sc, ac_qhead_t *head)
  360 {
  361     struct amr_command  *ac;
  362 
  363     if ((ac = STAILQ_FIRST(head)) != NULL)
  364         STAILQ_REMOVE_HEAD(head, ac_link);
  365     return(ac);
  366 }
  367 
  368 static __inline void
  369 amr_enqueue_free(struct amr_command *ac)
  370 {
  371 
  372     STAILQ_INSERT_HEAD(&ac->ac_sc->amr_freecmds, ac, ac_link);
  373 }
  374 
  375 static __inline struct amr_command *
  376 amr_dequeue_free(struct amr_softc *sc)
  377 {
  378     struct amr_command  *ac;
  379 
  380     if ((ac = STAILQ_FIRST(&sc->amr_freecmds)) != NULL)
  381         STAILQ_REMOVE_HEAD(&sc->amr_freecmds, ac_link);
  382     return(ac);
  383 }

Cache object: 378149bbb2edcad9f7ff2a496dfb0a15


[ source navigation ] [ diff markup ] [ identifier search ] [ freetext search ] [ file search ] [ list types ] [ track identifier ]


This page is part of the FreeBSD/Linux Linux Kernel Cross-Reference, and was automatically generated using a modified version of the LXR engine.