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

Cache object: 82646a1f023de7b96b1da18ab9ff4adc


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