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/twa/twa.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) 2003-04 3ware, Inc.
    3  * Copyright (c) 2000 Michael Smith
    4  * Copyright (c) 2000 BSDi
    5  * All rights reserved.
    6  *
    7  * Redistribution and use in source and binary forms, with or without
    8  * modification, are permitted provided that the following conditions
    9  * are met:
   10  * 1. Redistributions of source code must retain the above copyright
   11  *    notice, this list of conditions and the following disclaimer.
   12  * 2. Redistributions in binary form must reproduce the above copyright
   13  *    notice, this list of conditions and the following disclaimer in the
   14  *    documentation and/or other materials provided with the distribution.
   15  *
   16  * THIS SOFTWARE IS PROVIDED BY THE AUTHOR AND CONTRIBUTORS ``AS IS'' AND
   17  * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
   18  * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
   19  * ARE DISCLAIMED.  IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE
   20  * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
   21  * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
   22  * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
   23  * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
   24  * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
   25  * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
   26  * SUCH DAMAGE.
   27  *
   28  *      $FreeBSD: releng/5.4/sys/dev/twa/twa.h 141821 2005-02-13 18:34:27Z vkashyap $
   29  */
   30 
   31 /*
   32  * 3ware driver for 9000 series storage controllers.
   33  *
   34  * Author: Vinod Kashyap
   35  */
   36 
   37 
   38 #define TWA_DRIVER_VERSION_STRING               "2.50.02.012"
   39 
   40 #define TWA_CDEV_MAJOR                          MAJOR_AUTO
   41 
   42 #define TWA_REQUEST_TIMEOUT_PERIOD              60 /* seconds */
   43 #define TWA_MESSAGE_SOURCE_CONTROLLER_ERROR     3
   44 #define TWA_MESSAGE_SOURCE_CONTROLLER_EVENT     4
   45 #define TWA_MESSAGE_SOURCE_FREEBSD_DRIVER       6
   46 #define TWA_MESSAGE_SOURCE_FREEBSD_OS           9
   47 
   48 #define TWA_MALLOC_CLASS                        M_TWA
   49 
   50 /* Macros for bus-space calls. */
   51 #define TWA_READ_REGISTER(sc, offset)           \
   52         (u_int32_t)bus_space_read_4(sc->twa_bus_tag, sc->twa_bus_handle, offset)
   53 #define TWA_WRITE_REGISTER(sc, offset, val)     \
   54         bus_space_write_4(sc->twa_bus_tag, sc->twa_bus_handle, offset, (u_int32_t)val)
   55 
   56 /* Possible values of tr->tr_status. */
   57 #define TWA_CMD_SETUP           0x0     /* being assembled */
   58 #define TWA_CMD_BUSY            0x1     /* submitted to controller */
   59 #define TWA_CMD_PENDING         0x2     /* in pending queue */
   60 #define TWA_CMD_COMPLETE        0x3     /* completed by controller (maybe with error) */
   61 
   62 /* Possible values of tr->tr_flags. */
   63 #define TWA_CMD_DATA_IN                 (1<<0)  /* read request */
   64 #define TWA_CMD_DATA_OUT                (1<<1)  /* write request */
   65 #define TWA_CMD_DATA_COPY_NEEDED        (1<<2)  /* data in ccb is misaligned, have to copy to/from private buffer */
   66 #define TWA_CMD_SLEEP_ON_REQUEST        (1<<3)  /* owner is sleeping on this command */
   67 #define TWA_CMD_MAPPED                  (1<<4)  /* request has been mapped */
   68 #define TWA_CMD_IN_PROGRESS             (1<<5)  /* bus_dmamap_load returned EINPROGRESS */
   69 #define TWA_CMD_TIMER_SET               (1<<6)  /* request is being timed */
   70 
   71 /* Possible values of tr->tr_cmd_pkt_type. */
   72 #define TWA_CMD_PKT_TYPE_7K             (1<<0)
   73 #define TWA_CMD_PKT_TYPE_9K             (1<<1)
   74 #define TWA_CMD_PKT_TYPE_INTERNAL       (1<<2)
   75 #define TWA_CMD_PKT_TYPE_IOCTL          (1<<3)
   76 #define TWA_CMD_PKT_TYPE_EXTERNAL       (1<<4)
   77 
   78 /* Possible values of sc->twa_state. */
   79 #define TWA_STATE_INTR_ENABLED          (1<<0)  /* interrupts have been enabled */
   80 #define TWA_STATE_SHUTDOWN              (1<<1)  /* controller is shut down */
   81 #define TWA_STATE_OPEN                  (1<<2)  /* control device is open */
   82 #define TWA_STATE_SUSPEND               (1<<3)  /* controller is suspended */
   83 #define TWA_STATE_SIMQ_FROZEN           (1<<4)  /* simq frozen */
   84 
   85 /* Possible values of sc->twa_ioctl_lock.lock. */
   86 #define TWA_LOCK_FREE           0x0     /* lock is free */
   87 #define TWA_LOCK_HELD           0x1     /* lock is held */
   88 
   89 
   90 /* Error/AEN message structure. */
   91 struct twa_message {
   92         u_int32_t       code;
   93         char            *message;
   94 };
   95 
   96 #ifdef TWA_DEBUG
   97 struct twa_q_statistics {
   98         u_int32_t       q_length;
   99         u_int32_t       q_max;
  100 };
  101 
  102 #define TWAQ_FREE       0
  103 #define TWAQ_BUSY       1
  104 #define TWAQ_PENDING    2
  105 #define TWAQ_COMPLETE   3
  106 #define TWAQ_COUNT      4       /* total number of queues */
  107 #endif /* TWA_DEBUG */
  108 
  109 /* Driver's request packet. */
  110 struct twa_request {
  111         struct twa_command_packet *tr_command;  /* ptr to cmd pkt submitted to controller */
  112         u_int32_t               tr_request_id;  /* request id for tracking with firmware */
  113 
  114         void                    *tr_data;       /* ptr to data being passed to firmware */
  115         u_int32_t               tr_length;      /* length of buffer being passed to firmware */
  116 
  117         void                    *tr_real_data;  /* ptr to, and length of data passed */
  118         u_int32_t               tr_real_length; /* to us from above, in case a buffer copy
  119                                                         was done due to non-compliance to 
  120                                                         alignment requirements */
  121 
  122         TAILQ_ENTRY(twa_request) tr_link;       /* to link this request in a list */
  123         struct twa_softc        *tr_sc;         /* controller that owns us */
  124 
  125         u_int32_t               tr_status;      /* command status */
  126         u_int32_t               tr_flags;       /* request flags */
  127         u_int32_t               tr_error;       /* error encountered before request submission */
  128         u_int32_t               tr_cmd_pkt_type;/* type of request */
  129         void                    *tr_private;    /* request specific data to use during callback */
  130         void                    (*tr_callback)(struct twa_request *tr);/* callback handler */
  131         bus_addr_t              tr_cmd_phys;    /* physical address of command in controller space */
  132         bus_dmamap_t            tr_buf_map;     /* DMA map for data */
  133 } __attribute__ ((packed));
  134 
  135 
  136 /* Per-controller structure. */
  137 struct twa_softc {
  138         /* Request queues and arrays. */
  139         TAILQ_HEAD(, twa_request) twa_free;     /* free request packets */
  140         TAILQ_HEAD(, twa_request) twa_busy;     /* requests busy in the controller */
  141         TAILQ_HEAD(, twa_request) twa_pending;  /* internal requests pending */
  142         TAILQ_HEAD(, twa_request) twa_complete; /* requests completed by firmware (not by us) */
  143 
  144         struct twa_request      *twa_lookup[TWA_Q_LENGTH];/* requests indexed by request_id */
  145 
  146         struct twa_request      *twa_req_buf;
  147         struct twa_command_packet *twa_cmd_pkt_buf;
  148 
  149         /* AEN handler fields. */
  150         struct twa_event_packet *twa_aen_queue[TWA_Q_LENGTH];/* circular queue of AENs from firmware */
  151         uint16_t                working_srl;    /* driver & firmware negotiated srl */
  152         uint16_t                working_branch; /* branch # of the firmware that the driver is compatible with */
  153         uint16_t                working_build;  /* build # of the firmware that the driver is compatible with */
  154         u_int32_t               twa_operating_mode; /* base mode/current mode */
  155         u_int32_t               twa_aen_head;   /* AEN queue head */
  156         u_int32_t               twa_aen_tail;   /* AEN queue tail */
  157         u_int32_t               twa_current_sequence_id;/* index of the last event + 1 */
  158         u_int32_t               twa_aen_queue_overflow; /* indicates if unretrieved events were overwritten */
  159         u_int32_t               twa_aen_queue_wrapped;  /* indicates if AEN queue ever wrapped */
  160         u_int32_t               twa_wait_timeout; /* identifier for calling tsleep */
  161 
  162         /* Controller state. */
  163         u_int32_t               twa_state;
  164 #ifdef TWA_DEBUG
  165         struct twa_q_statistics twa_qstats[TWAQ_COUNT]; /* queue statistics */
  166 #endif /* TWA_DEBUG */
  167         struct {
  168                 u_int32_t       lock;   /* lock state */
  169                 u_int32_t       timeout;/* time at which the lock will become available,
  170                                                 even if not released */
  171         } twa_ioctl_lock;       /* lock for use by user applications, for synchronization
  172                                         between ioctl calls */
  173     
  174         device_t                twa_bus_dev;    /* bus device */
  175         struct cdev             *twa_ctrl_dev;  /* control device */
  176         struct resource         *twa_io_res;    /* register interface window */
  177         bus_space_handle_t      twa_bus_handle; /* bus space handle */
  178         bus_space_tag_t         twa_bus_tag;    /* bus space tag */
  179         bus_dma_tag_t           twa_parent_tag; /* parent DMA tag */
  180         bus_dma_tag_t           twa_cmd_tag;    /* cmd DMA tag */
  181         bus_dma_tag_t           twa_buf_tag;    /* data buffer DMA tag */
  182         bus_dmamap_t            twa_cmd_map;    /* DMA map for the array of cmd pkts */
  183         bus_addr_t              twa_cmd_pkt_phys;/* phys addr of first of array of cmd pkts */
  184         struct resource         *twa_irq_res;   /* interrupt resource*/
  185         void                    *twa_intr_handle;/* interrupt handle */
  186         struct intr_config_hook twa_ich;        /* delayed-startup hook */
  187 
  188         struct sysctl_ctx_list  twa_sysctl_ctx;
  189         struct sysctl_oid       *twa_sysctl_tree;
  190 
  191         struct cam_sim          *twa_sim;       /* sim for this controller */
  192         struct cam_path         *twa_path;      /* peripheral, path, tgt, lun
  193                                                 associated with this controller */
  194 };
  195 
  196 
  197 /*
  198  * Queue primitives
  199  */
  200 
  201 #ifdef TWA_DEBUG
  202 
  203 #define TWAQ_INIT(sc, qname)                            \
  204         do {                                            \
  205                 sc->twa_qstats[qname].q_length = 0;     \
  206                 sc->twa_qstats[qname].q_max = 0;        \
  207         } while(0)
  208 
  209 #define TWAQ_ADD(sc, qname)                                     \
  210         do {                                                    \
  211         struct twa_q_statistics *qs = &(sc)->twa_qstats[qname]; \
  212                                                                 \
  213                 qs->q_length++;                                 \
  214                 if (qs->q_length > qs->q_max)                   \
  215                         qs->q_max = qs->q_length;               \
  216         } while(0)
  217 
  218 #define TWAQ_REMOVE(sc, qname)  (sc)->twa_qstats[qname].q_length--
  219 
  220 #else /* TWA_DEBUG */
  221 
  222 #define TWAQ_INIT(sc, qname)
  223 #define TWAQ_ADD(sc, qname)
  224 #define TWAQ_REMOVE(sc, qname)
  225 
  226 #endif /* TWA_DEBUG */
  227 
  228 #define TWAQ_REQUEST_QUEUE(name, index)                                 \
  229 static __inline void twa_initq_ ## name(struct twa_softc *sc)           \
  230 {                                                                       \
  231         TAILQ_INIT(&sc->twa_ ## name);                                  \
  232         TWAQ_INIT(sc, index);                                           \
  233 }                                                                       \
  234 static __inline void twa_enqueue_ ## name(struct twa_request *tr)       \
  235 {                                                                       \
  236         int     s;                                                      \
  237                                                                         \
  238         s = splcam();                                                   \
  239         TAILQ_INSERT_TAIL(&tr->tr_sc->twa_ ## name, tr, tr_link);       \
  240         TWAQ_ADD(tr->tr_sc, index);                                     \
  241         splx(s);                                                        \
  242 }                                                                       \
  243 static __inline void twa_requeue_ ## name(struct twa_request *tr)       \
  244 {                                                                       \
  245         int     s;                                                      \
  246                                                                         \
  247         s = splcam();                                                   \
  248         TAILQ_INSERT_HEAD(&tr->tr_sc->twa_ ## name, tr, tr_link);       \
  249         TWAQ_ADD(tr->tr_sc, index);                                     \
  250         splx(s);                                                        \
  251 }                                                                       \
  252 static __inline struct twa_request *twa_dequeue_ ## name(struct twa_softc *sc)\
  253 {                                                                       \
  254         struct twa_request      *tr;                                    \
  255         int                     s;                                      \
  256                                                                         \
  257         s = splcam();                                                   \
  258         if ((tr = TAILQ_FIRST(&sc->twa_ ## name)) != NULL) {            \
  259                 TAILQ_REMOVE(&sc->twa_ ## name, tr, tr_link);           \
  260                 TWAQ_REMOVE(sc, index);                                 \
  261         }                                                               \
  262         splx(s);                                                        \
  263         return(tr);                                                     \
  264 }                                                                       \
  265 static __inline void twa_remove_ ## name(struct twa_request *tr)        \
  266 {                                                                       \
  267         int     s;                                                      \
  268                                                                         \
  269         s = splcam();                                                   \
  270         TAILQ_REMOVE(&tr->tr_sc->twa_ ## name, tr, tr_link);            \
  271         TWAQ_REMOVE(tr->tr_sc, index);                                  \
  272         splx(s);                                                        \
  273 }
  274 
  275 TWAQ_REQUEST_QUEUE(free, TWAQ_FREE)
  276 TWAQ_REQUEST_QUEUE(busy, TWAQ_BUSY)
  277 TWAQ_REQUEST_QUEUE(pending, TWAQ_PENDING)
  278 TWAQ_REQUEST_QUEUE(complete, TWAQ_COMPLETE)
  279 
  280 
  281 #ifdef TWA_DEBUG
  282 
  283 extern u_int8_t twa_dbg_level;
  284 extern u_int8_t twa_call_dbg_level;
  285 
  286 /* Printf with the bus device in question. */
  287 #define twa_dbg_dprint(dbg_level, sc, fmt, args...)             \
  288         do {                                                    \
  289                 if (dbg_level <= twa_dbg_level)                 \
  290                         device_printf(sc->twa_bus_dev,          \
  291                                 "%s: " fmt "\n", __func__ , ##args);\
  292         } while(0)
  293 
  294 #define twa_dbg_dprint_enter(dbg_level, sc)                     \
  295         do {                                                    \
  296                 if (dbg_level <= twa_call_dbg_level)            \
  297                         device_printf(sc->twa_bus_dev,          \
  298                                 "%s: entered.\n", __func__);    \
  299         } while(0)
  300 
  301 #define twa_dbg_dprint_exit(dbg_level, sc)                      \
  302         do {                                                    \
  303                 if (dbg_level <= twa_call_dbg_level)            \
  304                         device_printf(sc->twa_bus_dev,          \
  305                                 "%s: exiting.\n", __func__);    \
  306         } while(0)
  307 
  308 #define twa_dbg_print(dbg_level, fmt, args...)                  \
  309         do {                                                    \
  310                 if (dbg_level <= twa_dbg_level)                 \
  311                         printf("%s: " fmt "\n", __func__ , ##args);\
  312         } while(0)
  313 
  314 #else
  315 #define twa_dbg_dprint(dbg_level, sc, fmt, args...)
  316 #define twa_dbg_dprint_enter(dbg_level, sc)
  317 #define twa_dbg_dprint_exit(dbg_level, sc)
  318 #define twa_dbg_print(dbg_level, fmt, args...)
  319 #endif
  320 
  321 #define twa_printf(sc, fmt, args...)    \
  322         device_printf(sc->twa_bus_dev, fmt, ##args)

Cache object: 38b222231f0cb604c9f6276e250e2318


[ 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.