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/tws/tws_services.c

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) 2010, LSI Corp.
    3  * All rights reserved.
    4  * Author : Manjunath Ranganathaiah
    5  * Support: freebsdraid@lsi.com
    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  *
   11  * 1. Redistributions of source code must retain the above copyright
   12  *    notice, this list of conditions and the following disclaimer.
   13  * 2. Redistributions in binary form must reproduce the above copyright
   14  *    notice, this list of conditions and the following disclaimer in
   15  *    the documentation and/or other materials provided with the
   16  *    distribution.
   17  * 3. Neither the name of the <ORGANIZATION> nor the names of its
   18  *    contributors may be used to endorse or promote products derived
   19  *    from this software without specific prior written permission.
   20  *
   21  * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
   22  * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
   23  * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS
   24  * FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE
   25  * COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT,
   26  * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING,
   27  * BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
   28  * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER
   29  * CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
   30  * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN
   31  * ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
   32  * POSSIBILITY OF SUCH DAMAGE.
   33  *
   34  * $FreeBSD: releng/11.2/sys/dev/tws/tws_services.c 331722 2018-03-29 02:50:57Z eadler $
   35  */
   36 
   37 #include <dev/tws/tws.h>
   38 #include <dev/tws/tws_hdm.h>
   39 #include <dev/tws/tws_services.h>
   40 #include <sys/time.h>
   41 
   42 void tws_q_insert_tail(struct tws_softc *sc, struct tws_request *req, 
   43                                 u_int8_t q_type );
   44 struct tws_request * tws_q_remove_request(struct tws_softc *sc, 
   45                                 struct tws_request *req, u_int8_t q_type );
   46 struct tws_request *tws_q_remove_head(struct tws_softc *sc, u_int8_t q_type );
   47 void tws_q_insert_head(struct tws_softc *sc, struct tws_request *req,
   48                                 u_int8_t q_type );
   49 struct tws_request * tws_q_remove_tail(struct tws_softc *sc, u_int8_t q_type );
   50 void tws_print_stats(void *arg);
   51 
   52 struct tws_sense *tws_find_sense_from_mfa(struct tws_softc *sc, u_int64_t mfa);
   53 
   54 
   55 
   56 static struct error_desc array[] = {
   57     { "Cannot add sysctl tree node", 0x2000, ERROR,
   58        "%s: (0x%02X: 0x%04X): %s:\n", "ERROR" },
   59     { "Register window not available", 0x2001, ERROR,
   60        "%s: (0x%02X: 0x%04X): %s:\n", "ERROR" },
   61     { "Can't allocate register window", 0x2002, ERROR,
   62        "%s: (0x%02X: 0x%04X): %s:\n", "ERROR" },
   63     { "Can't allocate interrupt", 0x2003, ERROR,
   64        "%s: (0x%02X: 0x%04X): %s:\n", "ERROR" },
   65     { "Can't set up interrupt", 0x2004, ERROR,
   66        "%s: (0x%02X: 0x%04X): %s:\n", "ERROR" },
   67     { "Couldn't intialize CAM", 0x2007, ERROR,
   68        "%s: (0x%02X: 0x%04X): %s:\n", "ERROR" },
   69     { "Couldn't create SIM device queue", 0x2100, ENOMEM,
   70        "%s: (0x%02X: 0x%04X): %s:\n", "ERROR" },
   71     { "Unable to  create SIM entry", 0x2101, ENOMEM,
   72        "%s: (0x%02X: 0x%04X): %s:\n", "ERROR" },
   73     { "Unable to  register the bus", 0x2102, ENXIO,
   74        "%s: (0x%02X: 0x%04X): %s:\n", "ERROR" },
   75     { "Unable to  create the path", 0x2103, ENXIO,
   76        "%s: (0x%02X: 0x%04X): %s:\n", "ERROR" },
   77     { "Bus scan request to CAM failed", 0x2104, ENXIO,
   78        "%s: (0x%02X: 0x%04X): %s:\n", "ERROR" },
   79     { "Unable to intialize the driver", 0x2008, ENXIO,
   80        "%s: (0x%02X: 0x%04X): %s:\n", "ERROR" },
   81     { "Unable to intialize the controller", 0x2009, ENXIO,
   82        "%s: (0x%02X: 0x%04X): %s:\n", "ERROR" },
   83 };
   84 
   85 void
   86 tws_trace(const char *file, const char *fun, int linenum,
   87           struct tws_softc *sc, char *desc, u_int64_t val1, u_int64_t val2)
   88 { 
   89 
   90 
   91     struct tws_trace_rec *rec = (struct tws_trace_rec *)sc->trace_q.q;
   92     volatile u_int16_t head, tail;
   93     char fmt[256];
   94 
   95     head = sc->trace_q.head;
   96     tail = sc->trace_q.tail;
   97 /*
   98     getnanotime(&rec[tail].ts);
   99 */
  100     strncpy(rec[tail].fname, file, TWS_TRACE_FNAME_LEN);
  101     strncpy(rec[tail].func, fun, TWS_TRACE_FUNC_LEN);
  102     rec[tail].linenum = linenum;
  103     strncpy(rec[tail].desc, desc, TWS_TRACE_DESC_LEN);
  104     rec[tail].val1 = val1;
  105     rec[tail].val2 = val2;
  106 
  107     tail = (tail+1) % sc->trace_q.depth;
  108 
  109     if ( head == tail ) { 
  110         sc->trace_q.overflow = 1;
  111         sc->trace_q.head = (head+1) % sc->trace_q.depth;
  112     }
  113     sc->trace_q.tail = tail;
  114 
  115 /*
  116     tws_circular_q_insert(sc, &sc->trace_q, 
  117                               &rec, sizeof(struct tws_trace_rec));
  118 */
  119     if ( sc->is64bit )
  120         strcpy(fmt, "%05d:%s::%s :%s: 0x%016lx : 0x%016lx \n");
  121     else
  122         strcpy(fmt, "%05d:%s::%s :%s: 0x%016llx : 0x%016llx \n");
  123 
  124 /*  
  125     printf("%05d:%s::%s :%s: 0x%016llx : 0x%016llx \n", 
  126             linenum, file, fun, desc, val1, val2);
  127 */
  128     printf(fmt, linenum, file, fun, desc, val1, val2);
  129 }
  130 
  131 void
  132 tws_log(struct tws_softc *sc, int index)
  133 {
  134     device_printf((sc)->tws_dev, array[index].fmt,
  135                     array[index].error_str,
  136                     array[index].error_code,
  137                     array[index].severity_level,
  138                     array[index].desc );
  139 }
  140 
  141 /* ----------- swap functions ----------- */
  142 
  143 
  144 u_int16_t 
  145 tws_swap16(u_int16_t val)
  146 {
  147     return((val << 8) | (val >> 8));
  148 }
  149 
  150 u_int32_t 
  151 tws_swap32(u_int32_t val)
  152 {
  153     return(((val << 24) | ((val << 8) & (0xFF0000)) | 
  154            ((val >> 8) & (0xFF00)) | (val >> 24)));
  155 }
  156 
  157 
  158 u_int64_t 
  159 tws_swap64(u_int64_t val)
  160 {
  161     return((((u_int64_t)(tws_swap32(((u_int32_t *)(&(val)))[1]))) << 32) |
  162            ((u_int32_t)(tws_swap32(((u_int32_t *)(&(val)))[0]))));
  163 }
  164 
  165 
  166 /* ----------- reg access ----------- */
  167 
  168 
  169 void
  170 tws_write_reg(struct tws_softc *sc, int offset, 
  171                   u_int32_t value, int size)
  172 {
  173     bus_space_tag_t         bus_tag = sc->bus_tag;
  174     bus_space_handle_t      bus_handle = sc->bus_handle;
  175 
  176     if (size == 4)
  177         bus_space_write_4(bus_tag, bus_handle, offset, value);
  178     else 
  179         if (size == 2)
  180             bus_space_write_2(bus_tag, bus_handle, offset, 
  181                                      (u_int16_t)value);
  182         else
  183             bus_space_write_1(bus_tag, bus_handle, offset, (u_int8_t)value);
  184 }
  185 
  186 u_int32_t
  187 tws_read_reg(struct tws_softc *sc, int offset, int size)
  188 {
  189     bus_space_tag_t bus_tag = sc->bus_tag;
  190     bus_space_handle_t bus_handle = sc->bus_handle;
  191 
  192     if (size == 4)
  193         return((u_int32_t)bus_space_read_4(bus_tag, bus_handle, offset));
  194     else if (size == 2)
  195             return((u_int32_t)bus_space_read_2(bus_tag, bus_handle, offset));
  196          else
  197             return((u_int32_t)bus_space_read_1(bus_tag, bus_handle, offset));
  198 }
  199 
  200 /* --------------------- Q service --------------------- */
  201 
  202 /* 
  203  * intialize q  pointers with null.
  204  */
  205 void
  206 tws_init_qs(struct tws_softc *sc)
  207 {
  208 
  209     mtx_lock(&sc->q_lock);
  210     for(int i=0;i<TWS_MAX_QS;i++) {
  211         sc->q_head[i] = NULL;
  212         sc->q_tail[i] = NULL;
  213     }
  214     mtx_unlock(&sc->q_lock);
  215 
  216 }
  217 
  218 /* called with lock held */
  219 static void
  220 tws_insert2_empty_q(struct tws_softc *sc, struct tws_request *req, 
  221                                 u_int8_t q_type )
  222 {
  223 
  224     mtx_assert(&sc->q_lock, MA_OWNED);
  225     req->next = req->prev = NULL;
  226     sc->q_head[q_type] = sc->q_tail[q_type] = req;
  227 
  228 }
  229 
  230 /* called with lock held */
  231 void
  232 tws_q_insert_head(struct tws_softc *sc, struct tws_request *req, 
  233                                 u_int8_t q_type )
  234 {
  235 
  236     mtx_assert(&sc->q_lock, MA_OWNED);
  237     if ( sc->q_head[q_type] == NULL ) {
  238         tws_insert2_empty_q(sc, req, q_type);
  239     } else {
  240         req->next = sc->q_head[q_type];
  241         req->prev = NULL;
  242         sc->q_head[q_type]->prev = req;
  243         sc->q_head[q_type] = req;
  244     }
  245 
  246 }
  247 
  248 /* called with lock held */
  249 void
  250 tws_q_insert_tail(struct tws_softc *sc, struct tws_request *req, 
  251                                 u_int8_t q_type )
  252 {
  253 
  254     mtx_assert(&sc->q_lock, MA_OWNED);
  255     if ( sc->q_tail[q_type] == NULL ) {
  256         tws_insert2_empty_q(sc, req, q_type);
  257     } else {
  258         req->prev = sc->q_tail[q_type];
  259         req->next = NULL;
  260         sc->q_tail[q_type]->next = req;
  261         sc->q_tail[q_type] = req;
  262     }
  263 
  264 }
  265 
  266 /* called with lock held */
  267 struct tws_request *
  268 tws_q_remove_head(struct tws_softc *sc, u_int8_t q_type )
  269 {
  270 
  271     struct tws_request *r;
  272 
  273     mtx_assert(&sc->q_lock, MA_OWNED);
  274     r = sc->q_head[q_type];
  275     if ( !r ) 
  276         return(NULL);
  277     if ( r->next == NULL &&  r->prev == NULL ) {
  278         /* last element  */
  279         sc->q_head[q_type] = sc->q_tail[q_type] = NULL;
  280     } else {
  281         sc->q_head[q_type] = r->next;
  282         r->next->prev = NULL;
  283         r->next = NULL;
  284         r->prev = NULL;
  285     }
  286     return(r);
  287 }
  288 
  289 /* called with lock held */
  290 struct tws_request *
  291 tws_q_remove_tail(struct tws_softc *sc, u_int8_t q_type )
  292 {
  293 
  294     struct tws_request *r;
  295 
  296     mtx_assert(&sc->q_lock, MA_OWNED);
  297     r = sc->q_tail[q_type];
  298     if ( !r ) 
  299         return(NULL);
  300     if ( r->next == NULL &&  r->prev == NULL ) {
  301         /* last element  */
  302         sc->q_head[q_type] = sc->q_tail[q_type] = NULL;
  303     } else {
  304         sc->q_tail[q_type] = r->prev;
  305         r->prev->next = NULL;
  306         r->next = NULL;
  307         r->prev = NULL;
  308     }
  309     return(r);
  310 }
  311 
  312 /* returns removed request if successful. return NULL otherwise */ 
  313 /* called with lock held */
  314 struct tws_request *
  315 tws_q_remove_request(struct tws_softc *sc, struct tws_request *req,
  316                                  u_int8_t q_type )
  317 {
  318 
  319     struct tws_request *r;
  320 
  321     mtx_assert(&sc->q_lock, MA_OWNED);
  322     if ( req == NULL ) {
  323         TWS_TRACE_DEBUG(sc, "null req", 0, q_type);
  324         return(NULL);
  325     }
  326 
  327     if ( req == sc->q_head[q_type] )
  328         return(tws_q_remove_head(sc, q_type));
  329     if ( req == sc->q_tail[q_type] )
  330         return(tws_q_remove_tail(sc, q_type));
  331 
  332 
  333     /* The given node is not at head or tail.
  334      * It's in the middle and there are more than
  335      * 2 elements on the q.
  336      */
  337 
  338     if ( req->next == NULL || req->prev == NULL ) {
  339         TWS_TRACE_DEBUG(sc, "invalid req", 0, q_type);
  340         return(NULL);
  341     }
  342 
  343 /* debug only */
  344     r = sc->q_head[q_type];
  345     while ( r ) {
  346         if ( req == r )
  347             break;
  348         r = r->next;
  349     } 
  350 
  351     if ( !r ) {
  352         TWS_TRACE_DEBUG(sc, "req not in q", 0, req->request_id);
  353         return(NULL);
  354     }
  355 /* debug end */
  356 
  357     req->prev->next = r->next;
  358     req->next->prev = r->prev;
  359     req->next = NULL;
  360     req->prev = NULL;
  361     return(req);
  362 }
  363 
  364 struct tws_sense *
  365 tws_find_sense_from_mfa(struct tws_softc *sc, u_int64_t mfa)
  366 {
  367     struct tws_sense *s;
  368     int i;
  369     TWS_TRACE_DEBUG(sc, "entry",sc,mfa);
  370 
  371     i = (mfa - sc->dma_mem_phys) / sizeof(struct tws_command_packet);
  372     if ( i>= 0 && i<tws_queue_depth) {
  373         s = &sc->sense_bufs[i];
  374         if ( mfa == s->hdr_pkt_phy )
  375             return(s);
  376     }
  377 
  378     TWS_TRACE_DEBUG(sc, "return null",0,mfa);
  379     return(NULL);
  380 
  381 }
  382 
  383 /* --------------------- Q service end --------------------- */
  384 /* --------------------- misc service start --------------------- */
  385 
  386 
  387 void
  388 tws_print_stats(void *arg)
  389 {
  390 
  391     struct tws_softc *sc = (struct tws_softc *)arg;
  392      
  393     TWS_TRACE(sc, "reqs(in, out)", sc->stats.reqs_in, sc->stats.reqs_out);
  394     TWS_TRACE(sc, "reqs(err, intrs)", sc->stats.reqs_errored
  395                                       , sc->stats.num_intrs);
  396     TWS_TRACE(sc, "reqs(ioctls, scsi)", sc->stats.ioctls
  397                                       , sc->stats.scsi_ios);
  398     callout_reset(&sc->stats_timer, 300 * hz, tws_print_stats, sc);
  399 }
  400 /* --------------------- misc service end --------------------- */

Cache object: 187f181952f243177007c66a3f763594


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