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/ipmi/ipmi_kcs.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-2-Clause-FreeBSD
    3  *
    4  * Copyright (c) 2006 IronPort Systems Inc. <ambrisko@ironport.com>
    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 
   29 #include <sys/cdefs.h>
   30 __FBSDID("$FreeBSD$");
   31 
   32 #include <sys/param.h>
   33 #include <sys/systm.h>
   34 #include <sys/bus.h>
   35 #include <sys/conf.h>
   36 #include <sys/condvar.h>
   37 #include <sys/eventhandler.h>
   38 #include <sys/kernel.h>
   39 #include <sys/kthread.h>
   40 #include <sys/rman.h>
   41 #include <sys/selinfo.h>
   42 #include <machine/bus.h>
   43 
   44 #ifdef LOCAL_MODULE
   45 #include <ipmi.h>
   46 #include <ipmivars.h>
   47 #else
   48 #include <sys/ipmi.h>
   49 #include <dev/ipmi/ipmivars.h>
   50 #endif
   51 
   52 #define POLLING_DELAY_MIN 4     /* Waits are 2-3 usecs on typical systems */
   53 #define POLLING_DELAY_MAX 256
   54 
   55 static void     kcs_clear_obf(struct ipmi_softc *, int);
   56 static void     kcs_error(struct ipmi_softc *);
   57 static int      kcs_wait_for_ibf(struct ipmi_softc *, bool);
   58 static int      kcs_wait_for_obf(struct ipmi_softc *, bool);
   59 
   60 static int
   61 kcs_wait(struct ipmi_softc *sc, int value, int mask)
   62 {
   63         int status, start = ticks;
   64         int delay_usec = POLLING_DELAY_MIN;
   65 
   66         status = INB(sc, KCS_CTL_STS);
   67         while (ticks - start < MAX_TIMEOUT && (status & mask) != value) {
   68                 /*
   69                  * The wait delay is increased exponentially to avoid putting
   70                  * significant load on I/O bus.
   71                  */
   72                 DELAY(delay_usec);
   73                 status = INB(sc, KCS_CTL_STS);
   74                 if (delay_usec < POLLING_DELAY_MAX)
   75                         delay_usec *= 2;
   76         }
   77         return (status);
   78 }
   79 
   80 static int
   81 kcs_wait_for_ibf(struct ipmi_softc *sc, bool level)
   82 {
   83 
   84         return (kcs_wait(sc, level ? KCS_STATUS_IBF : 0, KCS_STATUS_IBF));
   85 }
   86 
   87 static int
   88 kcs_wait_for_obf(struct ipmi_softc *sc, bool level)
   89 {
   90 
   91         return (kcs_wait(sc, level ? KCS_STATUS_OBF : 0, KCS_STATUS_OBF));
   92 }
   93 
   94 static void
   95 kcs_clear_obf(struct ipmi_softc *sc, int status)
   96 {
   97 
   98         /* Clear OBF */
   99         if (status & KCS_STATUS_OBF) {
  100                 INB(sc, KCS_DATA);
  101         }
  102 }
  103 
  104 static void
  105 kcs_error(struct ipmi_softc *sc)
  106 {
  107         int retry, status;
  108         u_char data;
  109 
  110         for (retry = 0; retry < 2; retry++) {
  111 
  112                 /* Wait for IBF = 0 */
  113                 status = kcs_wait_for_ibf(sc, 0);
  114 
  115                 /* ABORT */
  116                 OUTB(sc, KCS_CTL_STS, KCS_CONTROL_GET_STATUS_ABORT);
  117 
  118                 /* Wait for IBF = 0 */
  119                 status = kcs_wait_for_ibf(sc, 0);
  120 
  121                 /* Clear OBF */
  122                 kcs_clear_obf(sc, status);
  123 
  124                 if (status & KCS_STATUS_OBF) {
  125                         data = INB(sc, KCS_DATA);
  126                         if (data != 0)
  127                                 device_printf(sc->ipmi_dev,
  128                                     "KCS Error Data %02x\n", data);
  129                 }
  130 
  131                 /* 0x00 to DATA_IN */
  132                 OUTB(sc, KCS_DATA, 0x00);
  133 
  134                 /* Wait for IBF = 0 */
  135                 status = kcs_wait_for_ibf(sc, 0);
  136 
  137                 if (KCS_STATUS_STATE(status) == KCS_STATUS_STATE_READ) {
  138 
  139                         /* Wait for OBF = 1 */
  140                         status = kcs_wait_for_obf(sc, 1);
  141 
  142                         /* Read error status */
  143                         data = INB(sc, KCS_DATA);
  144                         if (data != 0 && (data != 0xff || bootverbose))
  145                                 device_printf(sc->ipmi_dev, "KCS error: %02x\n",
  146                                     data);
  147 
  148                         /* Write READ into Data_in */
  149                         OUTB(sc, KCS_DATA, KCS_DATA_IN_READ);
  150 
  151                         /* Wait for IBF = 0 */
  152                         status = kcs_wait_for_ibf(sc, 0);
  153                 }
  154 
  155                 /* IDLE STATE */
  156                 if (KCS_STATUS_STATE(status) == KCS_STATUS_STATE_IDLE) {
  157                         /* Wait for OBF = 1 */
  158                         status = kcs_wait_for_obf(sc, 1);
  159 
  160                         /* Clear OBF */
  161                         kcs_clear_obf(sc, status);
  162                         return;
  163                 }
  164         }
  165         device_printf(sc->ipmi_dev, "KCS: Error retry exhausted\n");
  166 }
  167 
  168 /*
  169  * Start to write a request.  Waits for IBF to clear and then sends the
  170  * WR_START command.
  171  */
  172 static int
  173 kcs_start_write(struct ipmi_softc *sc)
  174 {
  175         int retry, status;
  176 
  177         for (retry = 0; retry < 10; retry++) {
  178                 /* Wait for IBF = 0 */
  179                 status = kcs_wait_for_ibf(sc, 0);
  180                 if (status & KCS_STATUS_IBF)
  181                         return (0);
  182 
  183                 /* Clear OBF */
  184                 kcs_clear_obf(sc, status);
  185 
  186                 /* Write start to command */
  187                 OUTB(sc, KCS_CTL_STS, KCS_CONTROL_WRITE_START);
  188 
  189                 /* Wait for IBF = 0 */
  190                 status = kcs_wait_for_ibf(sc, 0);
  191                 if (status & KCS_STATUS_IBF)
  192                         return (0);
  193 
  194                 if (KCS_STATUS_STATE(status) == KCS_STATUS_STATE_WRITE)
  195                         break;
  196                 DELAY(1000000);
  197         }
  198 
  199         if (KCS_STATUS_STATE(status) != KCS_STATUS_STATE_WRITE)
  200                 /* error state */
  201                 return (0);
  202 
  203         /* Clear OBF */
  204         kcs_clear_obf(sc, status);
  205 
  206         return (1);
  207 }
  208 
  209 /*
  210  * Write a byte of the request message, excluding the last byte of the
  211  * message which requires special handling.
  212  */
  213 static int
  214 kcs_write_byte(struct ipmi_softc *sc, u_char data)
  215 {
  216         int status;
  217 
  218         /* Data to Data */
  219         OUTB(sc, KCS_DATA, data);
  220 
  221         /* Wait for IBF = 0 */
  222         status = kcs_wait_for_ibf(sc, 0);
  223         if (status & KCS_STATUS_IBF)
  224                 return (0);
  225 
  226         if (KCS_STATUS_STATE(status) != KCS_STATUS_STATE_WRITE)
  227                 return (0);
  228 
  229         /* Clear OBF */
  230         kcs_clear_obf(sc, status);
  231         return (1);
  232 }
  233 
  234 /*
  235  * Write the last byte of a request message.
  236  */
  237 static int
  238 kcs_write_last_byte(struct ipmi_softc *sc, u_char data)
  239 {
  240         int status;
  241 
  242         /* Write end to command */
  243         OUTB(sc, KCS_CTL_STS, KCS_CONTROL_WRITE_END);
  244 
  245         /* Wait for IBF = 0 */
  246         status = kcs_wait_for_ibf(sc, 0);
  247         if (status & KCS_STATUS_IBF)
  248                 return (0);
  249 
  250         if (KCS_STATUS_STATE(status) != KCS_STATUS_STATE_WRITE)
  251                 /* error state */
  252                 return (0);
  253 
  254         /* Clear OBF */
  255         kcs_clear_obf(sc, status);
  256 
  257         /* Send data byte to DATA. */
  258         OUTB(sc, KCS_DATA, data);
  259         return (1);
  260 }
  261 
  262 /*
  263  * Read one byte of the reply message.
  264  */
  265 static int
  266 kcs_read_byte(struct ipmi_softc *sc, u_char *data)
  267 {
  268         int status;
  269 
  270         /* Wait for IBF = 0 */
  271         status = kcs_wait_for_ibf(sc, 0);
  272 
  273         /* Read State */
  274         if (KCS_STATUS_STATE(status) == KCS_STATUS_STATE_READ) {
  275 
  276                 /* Wait for OBF = 1 */
  277                 status = kcs_wait_for_obf(sc, 1);
  278                 if ((status & KCS_STATUS_OBF) == 0)
  279                         return (0);
  280 
  281                 /* Read Data_out */
  282                 *data = INB(sc, KCS_DATA);
  283 
  284                 /* Write READ into Data_in */
  285                 OUTB(sc, KCS_DATA, KCS_DATA_IN_READ);
  286                 return (1);
  287         }
  288 
  289         /* Idle State */
  290         if (KCS_STATUS_STATE(status) == KCS_STATUS_STATE_IDLE) {
  291 
  292                 /* Wait for OBF = 1*/
  293                 status = kcs_wait_for_obf(sc, 1);
  294                 if ((status & KCS_STATUS_OBF) == 0)
  295                         return (0);
  296 
  297                 /* Read Dummy */
  298                 INB(sc, KCS_DATA);
  299                 return (2);
  300         }
  301 
  302         /* Error State */
  303         return (0);
  304 }
  305 
  306 /*
  307  * Send a request message and collect the reply.  Returns true if we
  308  * succeed.
  309  */
  310 static int
  311 kcs_polled_request(struct ipmi_softc *sc, struct ipmi_request *req)
  312 {
  313         u_char *cp, data;
  314         int i, state;
  315 
  316         IPMI_IO_LOCK(sc);
  317 
  318         /* Send the request. */
  319         if (!kcs_start_write(sc)) {
  320                 device_printf(sc->ipmi_dev, "KCS: Failed to start write\n");
  321                 goto fail;
  322         }
  323 #ifdef KCS_DEBUG
  324         device_printf(sc->ipmi_dev, "KCS: WRITE_START... ok\n");
  325 #endif
  326 
  327         if (!kcs_write_byte(sc, req->ir_addr)) {
  328                 device_printf(sc->ipmi_dev, "KCS: Failed to write address\n");
  329                 goto fail;
  330         }
  331 #ifdef KCS_DEBUG
  332         device_printf(sc->ipmi_dev, "KCS: Wrote address: %02x\n", req->ir_addr);
  333 #endif
  334 
  335         if (req->ir_requestlen == 0) {
  336                 if (!kcs_write_last_byte(sc, req->ir_command)) {
  337                         device_printf(sc->ipmi_dev,
  338                             "KCS: Failed to write command\n");
  339                         goto fail;
  340                 }
  341 #ifdef KCS_DEBUG
  342                 device_printf(sc->ipmi_dev, "KCS: Wrote command: %02x\n",
  343                     req->ir_command);
  344 #endif
  345         } else {
  346                 if (!kcs_write_byte(sc, req->ir_command)) {
  347                         device_printf(sc->ipmi_dev,
  348                             "KCS: Failed to write command\n");
  349                         goto fail;
  350                 }
  351 #ifdef KCS_DEBUG
  352                 device_printf(sc->ipmi_dev, "KCS: Wrote command: %02x\n",
  353                     req->ir_command);
  354 #endif
  355 
  356                 cp = req->ir_request;
  357                 for (i = 0; i < req->ir_requestlen - 1; i++) {
  358                         if (!kcs_write_byte(sc, *cp++)) {
  359                                 device_printf(sc->ipmi_dev,
  360                                     "KCS: Failed to write data byte %d\n",
  361                                     i + 1);
  362                                 goto fail;
  363                         }
  364 #ifdef KCS_DEBUG
  365                         device_printf(sc->ipmi_dev, "KCS: Wrote data: %02x\n",
  366                             cp[-1]);
  367 #endif
  368                 }
  369 
  370                 if (!kcs_write_last_byte(sc, *cp)) {
  371                         device_printf(sc->ipmi_dev,
  372                             "KCS: Failed to write last dta byte\n");
  373                         goto fail;
  374                 }
  375 #ifdef KCS_DEBUG
  376                 device_printf(sc->ipmi_dev, "KCS: Wrote last data: %02x\n",
  377                     *cp);
  378 #endif
  379         }
  380 
  381         /* Read the reply.  First, read the NetFn/LUN. */
  382         if (kcs_read_byte(sc, &data) != 1) {
  383                 device_printf(sc->ipmi_dev, "KCS: Failed to read address\n");
  384                 goto fail;
  385         }
  386 #ifdef KCS_DEBUG
  387         device_printf(sc->ipmi_dev, "KCS: Read address: %02x\n", data);
  388 #endif
  389         if (data != IPMI_REPLY_ADDR(req->ir_addr)) {
  390                 device_printf(sc->ipmi_dev, "KCS: Reply address mismatch\n");
  391                 goto fail;
  392         }
  393 
  394         /* Next we read the command. */
  395         if (kcs_read_byte(sc, &data) != 1) {
  396                 device_printf(sc->ipmi_dev, "KCS: Failed to read command\n");
  397                 goto fail;
  398         }
  399 #ifdef KCS_DEBUG
  400         device_printf(sc->ipmi_dev, "KCS: Read command: %02x\n", data);
  401 #endif
  402         if (data != req->ir_command) {
  403                 device_printf(sc->ipmi_dev, "KCS: Command mismatch\n");
  404                 goto fail;
  405         }
  406 
  407         /* Next we read the completion code. */
  408         if (kcs_read_byte(sc, &req->ir_compcode) != 1) {
  409                 if (bootverbose) {
  410                         device_printf(sc->ipmi_dev,
  411                             "KCS: Failed to read completion code\n");
  412                 }
  413                 goto fail;
  414         }
  415 #ifdef KCS_DEBUG
  416         device_printf(sc->ipmi_dev, "KCS: Read completion code: %02x\n",
  417             req->ir_compcode);
  418 #endif
  419 
  420         /* Finally, read the reply from the BMC. */
  421         i = 0;
  422         for (;;) {
  423                 state = kcs_read_byte(sc, &data);
  424                 if (state == 0) {
  425                         device_printf(sc->ipmi_dev,
  426                             "KCS: Read failed on byte %d\n", i + 1);
  427                         goto fail;
  428                 }
  429                 if (state == 2)
  430                         break;
  431                 if (i < req->ir_replybuflen) {
  432                         req->ir_reply[i] = data;
  433 #ifdef KCS_DEBUG
  434                         device_printf(sc->ipmi_dev, "KCS: Read data %02x\n",
  435                             data);
  436                 } else {
  437                         device_printf(sc->ipmi_dev,
  438                             "KCS: Read short %02x byte %d\n", data, i + 1);
  439 #endif
  440                 }
  441                 i++;
  442         }
  443         IPMI_IO_UNLOCK(sc);
  444         req->ir_replylen = i;
  445 #ifdef KCS_DEBUG
  446         device_printf(sc->ipmi_dev, "KCS: READ finished (%d bytes)\n", i);
  447         if (req->ir_replybuflen < i)
  448 #else
  449         if (req->ir_replybuflen < i && req->ir_replybuflen != 0)
  450 #endif
  451                 device_printf(sc->ipmi_dev,
  452                     "KCS: Read short: %zd buffer, %d actual\n",
  453                     req->ir_replybuflen, i);
  454         return (1);
  455 fail:
  456         kcs_error(sc);
  457         IPMI_IO_UNLOCK(sc);
  458         return (0);
  459 }
  460 
  461 static void
  462 kcs_loop(void *arg)
  463 {
  464         struct ipmi_softc *sc = arg;
  465         struct ipmi_request *req;
  466         int i, ok;
  467 
  468         IPMI_LOCK(sc);
  469         while ((req = ipmi_dequeue_request(sc)) != NULL) {
  470                 IPMI_UNLOCK(sc);
  471                 ok = 0;
  472                 for (i = 0; i < 3 && !ok; i++)
  473                         ok = kcs_polled_request(sc, req);
  474                 if (ok)
  475                         req->ir_error = 0;
  476                 else
  477                         req->ir_error = EIO;
  478                 IPMI_LOCK(sc);
  479                 ipmi_complete_request(sc, req);
  480         }
  481         IPMI_UNLOCK(sc);
  482         kproc_exit(0);
  483 }
  484 
  485 static int
  486 kcs_startup(struct ipmi_softc *sc)
  487 {
  488 
  489         return (kproc_create(kcs_loop, sc, &sc->ipmi_kthread, 0, 0, "%s: kcs",
  490             device_get_nameunit(sc->ipmi_dev)));
  491 }
  492 
  493 static int
  494 kcs_driver_request_queue(struct ipmi_softc *sc, struct ipmi_request *req, int timo)
  495 {
  496         int error;
  497 
  498         IPMI_LOCK(sc);
  499         ipmi_polled_enqueue_request_highpri(sc, req);
  500         error = msleep(req, &sc->ipmi_requests_lock, 0, "ipmireq", timo);
  501         if (error == 0)
  502                 error = req->ir_error;
  503         IPMI_UNLOCK(sc);
  504         return (error);
  505 }
  506 
  507 static int
  508 kcs_driver_request_poll(struct ipmi_softc *sc, struct ipmi_request *req)
  509 {
  510         int i, ok;
  511 
  512         ok = 0;
  513         for (i = 0; i < 3 && !ok; i++)
  514                 ok = kcs_polled_request(sc, req);
  515         if (ok)
  516                 req->ir_error = 0;
  517         else
  518                 req->ir_error = EIO;
  519         return (req->ir_error);
  520 }
  521 
  522 static int
  523 kcs_driver_request(struct ipmi_softc *sc, struct ipmi_request *req, int timo)
  524 {
  525 
  526         if (KERNEL_PANICKED() || dumping)
  527                 return (kcs_driver_request_poll(sc, req));
  528         else
  529                 return (kcs_driver_request_queue(sc, req, timo));
  530 }
  531 
  532 
  533 int
  534 ipmi_kcs_attach(struct ipmi_softc *sc)
  535 {
  536         int status;
  537 
  538         /* Setup function pointers. */
  539         sc->ipmi_startup = kcs_startup;
  540         sc->ipmi_enqueue_request = ipmi_polled_enqueue_request;
  541         sc->ipmi_driver_request = kcs_driver_request;
  542         sc->ipmi_driver_requests_polled = 1;
  543 
  544         /* See if we can talk to the controller. */
  545         status = INB(sc, KCS_CTL_STS);
  546         if (status == 0xff) {
  547                 device_printf(sc->ipmi_dev, "couldn't find it\n");
  548                 return (ENXIO);
  549         }
  550 
  551 #ifdef KCS_DEBUG
  552         device_printf(sc->ipmi_dev, "KCS: initial state: %02x\n", status);
  553 #endif
  554         if (status & KCS_STATUS_OBF ||
  555             KCS_STATUS_STATE(status) != KCS_STATUS_STATE_IDLE)
  556                 kcs_error(sc);
  557 
  558         return (0);
  559 }
  560 
  561 /*
  562  * Determine the alignment automatically for a PCI attachment.  In this case,
  563  * any unused bytes will return 0x00 when read.  We make use of the C/D bit
  564  * in the CTL_STS register to try to start a GET_STATUS transaction.  When
  565  * we write the command, that bit should be set, so we should get a non-zero
  566  * value back when we read CTL_STS if the offset we are testing is the CTL_STS
  567  * register.
  568  */
  569 int
  570 ipmi_kcs_probe_align(struct ipmi_softc *sc)
  571 {
  572         int status;
  573 
  574         sc->ipmi_io_spacing = 1;
  575 retry:
  576 #ifdef KCS_DEBUG
  577         device_printf(sc->ipmi_dev, "Trying KCS align %d... ", sc->ipmi_io_spacing);
  578 #endif
  579 
  580         /* Wait for IBF = 0 */
  581         status = INB(sc, KCS_CTL_STS);
  582         while (status & KCS_STATUS_IBF) {
  583                 DELAY(100);
  584                 status = INB(sc, KCS_CTL_STS);
  585         }
  586 
  587         OUTB(sc, KCS_CTL_STS, KCS_CONTROL_GET_STATUS_ABORT);
  588 
  589         /* Wait for IBF = 0 */
  590         status = INB(sc, KCS_CTL_STS);
  591         while (status & KCS_STATUS_IBF) {
  592                 DELAY(100);
  593                 status = INB(sc, KCS_CTL_STS);
  594         }
  595 
  596         /* If we got 0x00 back, then this must not be the CTL_STS register. */
  597         if (status == 0) {
  598 #ifdef KCS_DEBUG
  599                 printf("failed\n");
  600 #endif
  601                 sc->ipmi_io_spacing <<= 1;
  602                 if (sc->ipmi_io_spacing > 4)
  603                         return (0);
  604                 goto retry;
  605         }
  606 #ifdef KCS_DEBUG
  607         printf("ok\n");
  608 #endif
  609 
  610         /* Finish out the transaction. */
  611 
  612         /* Clear OBF */
  613         if (status & KCS_STATUS_OBF)
  614                 INB(sc, KCS_DATA);
  615 
  616         /* 0x00 to DATA_IN */
  617         OUTB(sc, KCS_DATA, 0);
  618 
  619         /* Wait for IBF = 0 */
  620         status = INB(sc, KCS_CTL_STS);
  621         while (status & KCS_STATUS_IBF) {
  622                 DELAY(100);
  623                 status = INB(sc, KCS_CTL_STS);
  624         }
  625 
  626         if (KCS_STATUS_STATE(status) == KCS_STATUS_STATE_READ) {
  627                 /* Wait for IBF = 1 */
  628                 while (!(status & KCS_STATUS_OBF)) {
  629                         DELAY(100);
  630                         status = INB(sc, KCS_CTL_STS);
  631                 }
  632 
  633                 /* Read error status. */
  634                 INB(sc, KCS_DATA);
  635 
  636                 /* Write dummy READ to DATA_IN. */
  637                 OUTB(sc, KCS_DATA, KCS_DATA_IN_READ);
  638 
  639                 /* Wait for IBF = 0 */
  640                 status = INB(sc, KCS_CTL_STS);
  641                 while (status & KCS_STATUS_IBF) {
  642                         DELAY(100);
  643                         status = INB(sc, KCS_CTL_STS);
  644                 }
  645         }
  646 
  647         if (KCS_STATUS_STATE(status) == KCS_STATUS_STATE_IDLE) {
  648                 /* Wait for IBF = 1 */
  649                 while (!(status & KCS_STATUS_OBF)) {
  650                         DELAY(100);
  651                         status = INB(sc, KCS_CTL_STS);
  652                 }
  653 
  654                 /* Clear OBF */
  655                 if (status & KCS_STATUS_OBF)
  656                         INB(sc, KCS_DATA);
  657         } else
  658                 device_printf(sc->ipmi_dev, "KCS probe: end state %x\n",
  659                     KCS_STATUS_STATE(status));
  660 
  661         return (1);
  662 }

Cache object: 378a6240160c05f7baf82b94cab5a1b1


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