Print this page
NEX-16819 loader UEFI support
Includes work by Toomas Soome <tsoome@me.com>
Upstream commits:
    loader: pxe receive cleanup
    9475 libefi: Do not return only if ReceiveFilter
    installboot: should support efi system partition
    8931 boot1.efi: scan all display modes rather than
    loader: spinconsole updates
    loader: gfx experiment to try GOP Blt() function.
    sha1 build test
    loader: add sha1 hash calculation
    common/sha1: update for loader build
    loader: biosdisk rework
    uts: 32-bit kernel FB needs mapping in low memory
    uts: add diag-device
    uts: boot console mirror with diag-device
    uts: enable very early console on ttya
    kmdb: add diag-device as input/output device
    uts: test VGA memory exclusion from mapping
    uts: clear boot mapping and protect boot pages test
    uts: add dboot map debug printf
    uts: need to release FB pages in release_bootstrap()
    uts: add screenmap ioctl
    uts: update sys/queue.h
    loader: add illumos uts/common to include path
    loader: tem/gfx font cleanup
    loader: vbe checks
    uts: gfx_private set KD_TEXT when KD_RESETTEXT is
    uts: gfx 8-bit update
    loader: gfx 8-bit fix
    loader: always set media size from partition.
    uts: MB2 support for 32-bit kernel
    loader: x86 should have tem 80x25
    uts: x86 should have tem 80x25
    uts: font update
    loader: font update
    uts: tem attributes
    loader: tem.c comment added
    uts: use font module
    loader: add font module
    loader: build rules for new font setup
    uts: gfx_private update for new font structure
    uts: early boot update for new font structure
    uts: font update
    uts: font build rules update for new fonts
    uts: tem update to new font structure
    loader: module.c needs to include tem_impl.h
    uts: gfx_private 8x16 font rework
    uts: make font_lookup public
    loader: font rework
    uts: font rework
    9259 libefi: efi_alloc_and_read should check for PMBR
    uts: tem utf-8 support
    loader: implement tem utf-8 support
    loader: tem should be able to display UTF-8
    7784 uts: console input should support utf-8
    7796 uts: ldterm default to utf-8
    uts: do not reset serial console
    uts: set up colors even if tem is not console
    uts: add type for early boot properties
    uts: gfx_private experiment with drm and vga
    uts: gfx_private should use setmode drm callback.
    uts: identify FB types and set up gfx_private based
    loader: replace gop and vesa with framebuffer
    uts: boot needs simple tem to support mdb
    uts: boot_keyboard should emit esc sequences for
    uts: gfx_private FB showuld be written by line
    kmdb: set terminal window size
    uts: gfx_private needs to keep track of early boot FB
    pnglite: move pnglite to usr/src/common
    loader: gfx_fb
    ficl-sys: add gfx primitives
    loader: add illumos.png logo
    ficl: add fb-putimage
    loader: add png support
    loader: add alpha blending for gfx_fb
    loader: use term-drawrect for menu frame
    ficl: add simple gfx words
    uts: provide fb_info via fbgattr dev_specific array.
    uts: gfx_private add alpha blending
    uts: update sys/ascii.h
    uts: tem OSC support (incomplete)
    uts: implement env module support and use data from
    uts: tem get colors from early boot data
    loader: use crc32 from libstand (libz)
    loader: optimize for size
    loader: pass tem info to the environment
    loader: import tem for loader console
    loader: UEFI loader needs to set ISADIR based on
    loader: need UEFI32 support
    8918 loader.efi: add vesa edid support
    uts: tem_safe_pix_clear_prom_output() should only
    uts: tem_safe_pix_clear_entire_screen() should use
    uts: tem_safe_check_first_time() should query cursor
    uts: tem implement cls callback & visual_io v4
    uts: gfx_vgatext use block cursor for vgatext
    uts: gfx_private implement cls callback & visual_io
    uts: gfx_private bitmap framebuffer implementation
    uts: early start frame buffer console support
    uts: font functions should check the input char
    uts: font rendering should support 16/24/32bit depths
    uts: use smallest font as fallback default.
    uts: update terminal dimensions based on selected
    7834 uts: vgatext should use gfx_private
    uts: add spacing property to 8859-1.bdf
    terminfo: add underline for sun-color
    terminfo: sun-color has 16 colors
    uts: add font load callback type
    loader: do not repeat int13 calls with error 0x20 and
    8905 loader: add skein/edonr support
    8904 common/crypto: make skein and edonr loader
Reviewed by: Yuri Pankov <yuri.pankov@nexenta.com>
Reviewed by: Sanjay Nadkarni <sanjay.nadkarni@nexenta.com>
Reviewed by: Evan Layton <evan.layton@nexenta.com>
Revert "NEX-16819 loader UEFI support"
This reverts commit ec06b9fc617b99234e538bf2e7e4d02a24993e0c.
Reverting due to failures in the zfs-tests and the sharefs-tests
NEX-16819 loader UEFI support
Includes work by Toomas Soome <tsoome@me.com>
Upstream commits:
    loader: pxe receive cleanup
    9475 libefi: Do not return only if ReceiveFilter
    installboot: should support efi system partition
    8931 boot1.efi: scan all display modes rather than
    loader: spinconsole updates
    loader: gfx experiment to try GOP Blt() function.
    sha1 build test
    loader: add sha1 hash calculation
    common/sha1: update for loader build
    loader: biosdisk rework
    uts: 32-bit kernel FB needs mapping in low memory
    uts: add diag-device
    uts: boot console mirror with diag-device
    uts: enable very early console on ttya
    kmdb: add diag-device as input/output device
    uts: test VGA memory exclusion from mapping
    uts: clear boot mapping and protect boot pages test
    uts: add dboot map debug printf
    uts: need to release FB pages in release_bootstrap()
    uts: add screenmap ioctl
    uts: update sys/queue.h
    loader: add illumos uts/common to include path
    loader: tem/gfx font cleanup
    loader: vbe checks
    uts: gfx_private set KD_TEXT when KD_RESETTEXT is
    uts: gfx 8-bit update
    loader: gfx 8-bit fix
    loader: always set media size from partition.
    uts: MB2 support for 32-bit kernel
    loader: x86 should have tem 80x25
    uts: x86 should have tem 80x25
    uts: font update
    loader: font update
    uts: tem attributes
    loader: tem.c comment added
    uts: use font module
    loader: add font module
    loader: build rules for new font setup
    uts: gfx_private update for new font structure
    uts: early boot update for new font structure
    uts: font update
    uts: font build rules update for new fonts
    uts: tem update to new font structure
    loader: module.c needs to include tem_impl.h
    uts: gfx_private 8x16 font rework
    uts: make font_lookup public
    loader: font rework
    uts: font rework
    libefi: efi_alloc_and_read should check for PMBR
    uts: tem utf-8 support
    loader: implement tem utf-8 support
    loader: tem should be able to display UTF-8
    7784 uts: console input should support utf-8
    7796 uts: ldterm default to utf-8
    uts: do not reset serial console
    uts: set up colors even if tem is not console
    uts: add type for early boot properties
    uts: gfx_private experiment with drm and vga
    uts: gfx_private should use setmode drm callback.
    uts: identify FB types and set up gfx_private based
    loader: replace gop and vesa with framebuffer
    uts: boot needs simple tem to support mdb
    uts: boot_keyboard should emit esc sequences for
    uts: gfx_private FB showuld be written by line
    kmdb: set terminal window size
    uts: gfx_private needs to keep track of early boot FB
    pnglite: move pnglite to usr/src/common
    loader: gfx_fb
    ficl-sys: add gfx primitives
    loader: add illumos.png logo
    ficl: add fb-putimage
    loader: add png support
    loader: add alpha blending for gfx_fb
    loader: use term-drawrect for menu frame
    ficl: add simple gfx words
    uts: provide fb_info via fbgattr dev_specific array.
    uts: gfx_private add alpha blending
    uts: update sys/ascii.h
    uts: tem OSC support (incomplete)
    uts: implement env module support and use data from
    uts: tem get colors from early boot data
    loader: use crc32 from libstand (libz)
    loader: optimize for size
    loader: pass tem info to the environment
    loader: import tem for loader console
    loader: UEFI loader needs to set ISADIR based on
    loader: need UEFI32 support
    8918 loader.efi: add vesa edid support
    uts: tem_safe_pix_clear_prom_output() should only
    uts: tem_safe_pix_clear_entire_screen() should use
    uts: tem_safe_check_first_time() should query cursor
    uts: tem implement cls callback & visual_io v4
    uts: gfx_vgatext use block cursor for vgatext
    uts: gfx_private implement cls callback & visual_io
    uts: gfx_private bitmap framebuffer implementation
    uts: early start frame buffer console support
    uts: font functions should check the input char
    uts: font rendering should support 16/24/32bit depths
    uts: use smallest font as fallback default.
    uts: update terminal dimensions based on selected
    7834 uts: vgatext should use gfx_private
    uts: add spacing property to 8859-1.bdf
    terminfo: add underline for sun-color
    terminfo: sun-color has 16 colors
    uts: add font load callback type
    loader: do not repeat int13 calls with error 0x20 and
    8905 loader: add skein/edonr support
    8904 common/crypto: make skein and edonr loader
Reviewed by: Yuri Pankov <yuri.pankov@nexenta.com>
Reviewed by: Sanjay Nadkarni <sanjay.nadkarni@nexenta.com>
Reviewed by: Evan Layton <evan.layton@nexenta.com>

Split Close
Expand all
Collapse all
          --- old/usr/src/uts/common/sys/queue.h
          +++ new/usr/src/uts/common/sys/queue.h
   1      -/*      $NetBSD: queue.h,v 1.42 2005/07/13 15:08:24 wiz Exp $   */
   2      -
   3    1  /*
   4    2   * Copyright (c) 1991, 1993
   5    3   *      The Regents of the University of California.  All rights reserved.
   6    4   *
   7    5   * Redistribution and use in source and binary forms, with or without
   8    6   * modification, are permitted provided that the following conditions
   9    7   * are met:
  10    8   * 1. Redistributions of source code must retain the above copyright
  11    9   *    notice, this list of conditions and the following disclaimer.
  12   10   * 2. Redistributions in binary form must reproduce the above copyright
↓ open down ↓ 19 lines elided ↑ open up ↑
  32   30   */
  33   31  /*
  34   32   * Copyright 2009 Sun Microsystems, Inc.  All rights reserved.
  35   33   * Use is subject to license terms.
  36   34   */
  37   35  
  38   36  #ifndef _SYS_QUEUE_H
  39   37  #define _SYS_QUEUE_H
  40   38  
  41   39  #include <sys/note.h>
       40 +#include <sys/stddef.h>
  42   41  
  43   42  #ifdef  __cplusplus
  44   43  extern "C" {
  45   44  #endif
  46   45  
  47   46  /*
  48   47   * This file defines five types of data structures: singly-linked lists,
  49   48   * lists, simple queues, tail queues, and circular queues.
  50   49   *
  51   50   * A singly-linked list is headed by a single forward pointer. The
↓ open down ↓ 49 lines elided ↑ open up ↑
 101  100  #define LIST_HEAD_INITIALIZER(head)                                     \
 102  101          { NULL }
 103  102  
 104  103  #define LIST_ENTRY(type)                                                \
 105  104  struct {                                                                \
 106  105          struct type *le_next;   /* next element */                      \
 107  106          struct type **le_prev;  /* address of previous next element */  \
 108  107  }
 109  108  
 110  109  /*
      110 + * List access methods.
      111 + */
      112 +#define LIST_EMPTY(head)                ((head)->lh_first == NULL)
      113 +#define LIST_FIRST(head)                ((head)->lh_first)
      114 +#define LIST_NEXT(elm, field)           ((elm)->field.le_next)
      115 +#define LIST_PREV(elm, head, type, field)                               \
      116 +        ((elm)->field.le_prev == &LIST_FIRST((head)) ? NULL :           \
      117 +        container_of((elm)->field.le_prev, type, field.le_next))
      118 +
      119 +#define LIST_FOREACH(var, head, field)                                  \
      120 +        for ((var) = LIST_FIRST((head));                                \
      121 +                (var);                                                  \
      122 +                (var) = LIST_NEXT((var), field))
      123 +
      124 +#define LIST_FOREACH_SAFE(var, head, field, tvar)                       \
      125 +        for ((var) = LIST_FIRST((head));                                \
      126 +                (var) && ((tvar) = LIST_NEXT((var), field), 1);         \
      127 +                (var) = (tvar))
      128 +
      129 +/*
 111  130   * List functions.
 112  131   */
 113  132  #if defined(_KERNEL) && defined(QUEUEDEBUG)
 114  133  #define QUEUEDEBUG_LIST_INSERT_HEAD(head, elm, field)                   \
 115  134          if ((head)->lh_first &&                                         \
 116  135              (head)->lh_first->field.le_prev != &(head)->lh_first)       \
 117  136                  panic("LIST_INSERT_HEAD %p %s:%d", (head), __FILE__, __LINE__);
 118  137  #define QUEUEDEBUG_LIST_OP(elm, field)                                  \
 119  138          if ((elm)->field.le_next &&                                     \
 120  139              (elm)->field.le_next->field.le_prev !=                      \
↓ open down ↓ 46 lines elided ↑ open up ↑
 167  186  #define LIST_REMOVE(elm, field) do {                                    \
 168  187          QUEUEDEBUG_LIST_OP((elm), field)                                \
 169  188          if ((elm)->field.le_next != NULL)                               \
 170  189                  (elm)->field.le_next->field.le_prev =                   \
 171  190                      (elm)->field.le_prev;                               \
 172  191          *(elm)->field.le_prev = (elm)->field.le_next;                   \
 173  192          QUEUEDEBUG_LIST_POSTREMOVE((elm), field)                        \
 174  193          _NOTE(CONSTCOND)                                                \
 175  194  } while (0)
 176  195  
 177      -#define LIST_FOREACH(var, head, field)                                  \
 178      -        for ((var) = ((head)->lh_first);                                \
 179      -                (var);                                                  \
 180      -                (var) = ((var)->field.le_next))
 181  196  
 182  197  /*
 183      - * List access methods.
 184      - */
 185      -#define LIST_EMPTY(head)                ((head)->lh_first == NULL)
 186      -#define LIST_FIRST(head)                ((head)->lh_first)
 187      -#define LIST_NEXT(elm, field)           ((elm)->field.le_next)
 188      -
 189      -
 190      -/*
 191  198   * Singly-linked List definitions.
 192  199   */
 193  200  #define SLIST_HEAD(name, type)                                          \
 194  201  struct name {                                                           \
 195  202          struct type *slh_first; /* first element */                     \
 196  203  }
 197  204  
 198  205  #define SLIST_HEAD_INITIALIZER(head)                                    \
 199  206          { NULL }
 200  207  
 201  208  #define SLIST_ENTRY(type)                                               \
 202  209  struct {                                                                \
 203  210          struct type *sle_next;  /* next element */                      \
 204  211  }
 205  212  
 206  213  /*
      214 + * Singly-linked List access methods.
      215 + */
      216 +#define SLIST_EMPTY(head)       ((head)->slh_first == NULL)
      217 +#define SLIST_FIRST(head)       ((head)->slh_first)
      218 +#define SLIST_NEXT(elm, field)  ((elm)->field.sle_next)
      219 +
      220 +#define SLIST_FOREACH(var, head, field)                                 \
      221 +        for ((var) = SLIST_FIRST((head));                               \
      222 +                (var);                                                  \
      223 +                (var) = SLIST_NEXT((var), field))
      224 +
      225 +#define SLIST_FOREACH_SAFE(var, head, field, tvar)                      \
      226 +        for ((var) = SLIST_FIRST((head));                               \
      227 +                (var) && ((tvar) = SLIST_NEXT((var), field), 1);        \
      228 +                (var) = (tvar))
      229 +
      230 +/*
 207  231   * Singly-linked List functions.
 208  232   */
 209  233  #define SLIST_INIT(head) do {                                           \
 210  234          (head)->slh_first = NULL;                                       \
 211  235          _NOTE(CONSTCOND)                                                \
 212  236  } while (0)
 213  237  
 214  238  #define SLIST_INSERT_AFTER(slistelm, elm, field) do {                   \
 215  239          (elm)->field.sle_next = (slistelm)->field.sle_next;             \
 216  240          (slistelm)->field.sle_next = (elm);                             \
↓ open down ↓ 18 lines elided ↑ open up ↑
 235  259          else {                                                          \
 236  260                  struct type *curelm = (head)->slh_first;                \
 237  261                  while (curelm->field.sle_next != (elm))                 \
 238  262                          curelm = curelm->field.sle_next;                \
 239  263                  curelm->field.sle_next =                                \
 240  264                      curelm->field.sle_next->field.sle_next;             \
 241  265          }                                                               \
 242  266          _NOTE(CONSTCOND)                                                \
 243  267  } while (0)
 244  268  
 245      -#define SLIST_FOREACH(var, head, field)                                 \
 246      -        for ((var) = (head)->slh_first; (var); (var) = (var)->field.sle_next)
 247  269  
 248  270  /*
 249      - * Singly-linked List access methods.
 250      - */
 251      -#define SLIST_EMPTY(head)       ((head)->slh_first == NULL)
 252      -#define SLIST_FIRST(head)       ((head)->slh_first)
 253      -#define SLIST_NEXT(elm, field)  ((elm)->field.sle_next)
 254      -
 255      -
 256      -/*
 257  271   * Singly-linked Tail queue declarations.
 258  272   */
 259  273  #define STAILQ_HEAD(name, type)                                         \
 260  274  struct name {                                                           \
 261  275          struct type *stqh_first;        /* first element */             \
 262  276          struct type **stqh_last;        /* addr of last next element */ \
 263  277  }
 264  278  
 265  279  #define STAILQ_HEAD_INITIALIZER(head)                                   \
 266  280          { NULL, &(head).stqh_first }
 267  281  
 268  282  #define STAILQ_ENTRY(type)                                              \
 269  283  struct {                                                                \
 270  284          struct type *stqe_next; /* next element */              \
 271  285  }
 272  286  
 273  287  /*
      288 + * Singly-linked Tail queue access methods.
      289 + */
      290 +#define STAILQ_EMPTY(head)      ((head)->stqh_first == NULL)
      291 +#define STAILQ_FIRST(head)      ((head)->stqh_first)
      292 +#define STAILQ_NEXT(elm, field) ((elm)->field.stqe_next)
      293 +
      294 +#define STAILQ_FOREACH(var, head, field)                                \
      295 +        for ((var) = STAILQ_FIRST(head);                                \
      296 +                (var);                                                  \
      297 +                (var) = STAILQ_NEXT((var), field))
      298 +
      299 +#define STAILQ_FOREACH_SAFE(var, head, field, tvar)                     \
      300 +        for ((var) = STAILQ_FIRST(head);                                \
      301 +                (var) && ((tvar) = STAILQ_NEXT((var), field), 1);       \
      302 +                (var) = (tvar))
      303 +
      304 +/*
 274  305   * Singly-linked Tail queue functions.
 275  306   */
 276  307  #define STAILQ_INIT(head) do {                                          \
 277  308          (head)->stqh_first = NULL;                                      \
 278  309          (head)->stqh_last = &(head)->stqh_first;                        \
 279  310          _NOTE(CONSTCOND)                                                \
 280  311  } while (0)
 281  312  
      313 +#define STAILQ_CONCAT(head1, head2) do {                                \
      314 +        if (!STAILQ_EMPTY((head2))) {                                   \
      315 +                *(head1)->stqh_last = (head2)->stqh_first;              \
      316 +                (head1)->stqh_last = (head2)->stqh_last;                \
      317 +                STAILQ_INIT((head2));                                   \
      318 +        }                                                               \
      319 +        _NOTE(CONSTCOND)                                                \
      320 +} while (0)
      321 +
 282  322  #define STAILQ_INSERT_HEAD(head, elm, field) do {                       \
 283  323          if (((elm)->field.stqe_next = (head)->stqh_first) == NULL)      \
 284  324                  (head)->stqh_last = &(elm)->field.stqe_next;            \
 285  325          (head)->stqh_first = (elm);                                     \
 286  326          _NOTE(CONSTCOND)                                                \
 287  327  } while (0)
 288  328  
 289  329  #define STAILQ_INSERT_TAIL(head, elm, field) do {                       \
 290  330          (elm)->field.stqe_next = NULL;                                  \
 291  331          *(head)->stqh_last = (elm);                                     \
↓ open down ↓ 4 lines elided ↑ open up ↑
 296  336  #define STAILQ_INSERT_AFTER(head, listelm, elm, field) do {             \
 297  337          if (((elm)->field.stqe_next = (listelm)->field.stqe_next)       \
 298  338              == NULL)                                                    \
 299  339                  (head)->stqh_last = &(elm)->field.stqe_next;            \
 300  340          (listelm)->field.stqe_next = (elm);                             \
 301  341          _NOTE(CONSTCOND)                                                \
 302  342  } while (0)
 303  343  
 304  344  #define STAILQ_REMOVE_HEAD(head, field) do {                            \
 305  345          if (((head)->stqh_first = (head)->stqh_first->field.stqe_next)  \
 306      -            == NULL)                                                    \
      346 +            == NULL)                                                    \
 307  347                  (head)->stqh_last = &(head)->stqh_first;                \
 308  348          _NOTE(CONSTCOND)                                                \
 309  349  } while (0)
 310  350  
      351 +#define STAILQ_REMOVE_AFTER(head, elm, field) do {                      \
      352 +        if ((STAILQ_NEXT(elm, field) =                                  \
      353 +            STAILQ_NEXT(STAILQ_NEXT(elm, field), field)) == NULL)       \
      354 +                (head)->stqh_last = &STAILQ_NEXT((elm), field);         \
      355 +        _NOTE(CONSTCOND)                                                \
      356 +} while (0)
      357 +
 311  358  #define STAILQ_REMOVE(head, elm, type, field) do {                      \
 312      -        if ((head)->stqh_first == (elm)) {                              \
      359 +        if (STAILQ_FIRST((head)) == (elm)) {                            \
 313  360                  STAILQ_REMOVE_HEAD((head), field);                      \
 314  361          } else {                                                        \
 315      -                struct type *curelm = (head)->stqh_first;               \
 316      -                while (curelm->field.stqe_next != (elm))                \
 317      -                        curelm = curelm->field.stqe_next;               \
 318      -                if ((curelm->field.stqe_next =                          \
 319      -                        curelm->field.stqe_next->field.stqe_next) == NULL) \
 320      -                            (head)->stqh_last = &(curelm)->field.stqe_next; \
      362 +                struct type *curelm = STAILQ_FIRST(head);               \
      363 +                while (STAILQ_NEXT(curelm, field) != (elm))             \
      364 +                        curelm = STAILQ_NEXT(curelm, field);            \
      365 +                STAILQ_REMOVE_AFTER(head, curelm, field);               \
 321  366          }                                                               \
 322  367          _NOTE(CONSTCOND)                                                \
 323  368  } while (0)
 324  369  
 325      -#define STAILQ_FOREACH(var, head, field)                                \
 326      -        for ((var) = ((head)->stqh_first);                              \
 327      -                (var);                                                  \
 328      -                (var) = ((var)->field.stqe_next))
      370 +#define STAILQ_LAST(head, type, field)                                  \
      371 +        (STAILQ_EMPTY((head)) ? NULL :                                  \
      372 +            container_of((head)->stqh_last, struct type, field.stqe_next))
 329  373  
 330  374  /*
 331      - * Singly-linked Tail queue access methods.
 332      - */
 333      -#define STAILQ_EMPTY(head)      ((head)->stqh_first == NULL)
 334      -#define STAILQ_FIRST(head)      ((head)->stqh_first)
 335      -#define STAILQ_NEXT(elm, field) ((elm)->field.stqe_next)
 336      -
 337      -
 338      -/*
 339  375   * Simple queue definitions.
 340  376   */
 341  377  #define SIMPLEQ_HEAD(name, type)                                        \
 342  378  struct name {                                                           \
 343  379          struct type *sqh_first; /* first element */             \
 344  380          struct type **sqh_last; /* addr of last next element */ \
 345  381  }
 346  382  
 347  383  #define SIMPLEQ_HEAD_INITIALIZER(head)                                  \
 348  384          { NULL, &(head).sqh_first }
 349  385  
 350  386  #define SIMPLEQ_ENTRY(type)                                             \
 351  387  struct {                                                                \
 352  388          struct type *sqe_next;  /* next element */                      \
 353  389  }
 354  390  
 355  391  /*
      392 + * Simple queue access methods.
      393 + */
      394 +#define SIMPLEQ_EMPTY(head)             ((head)->sqh_first == NULL)
      395 +#define SIMPLEQ_FIRST(head)             ((head)->sqh_first)
      396 +#define SIMPLEQ_NEXT(elm, field)        ((elm)->field.sqe_next)
      397 +
      398 +#define SIMPLEQ_FOREACH(var, head, field)                               \
      399 +        for ((var) = SIMPLEQ_FIRST((head));                             \
      400 +                (var);                                                  \
      401 +                (var) = SIMPLEQ_NEXT((var), field))
      402 +
      403 +#define SIMPLEQ_FOREACH_SAFE(var, head, field, tvar)                    \
      404 +        for ((var) = SIMPLEQ_FIRST((head));                             \
      405 +                (var) && ((tvar) = SIMPLEQ_NEXT((var), field), 1);      \
      406 +                (var) = (tvar))
      407 +
      408 +/*
 356  409   * Simple queue functions.
 357  410   */
 358  411  #define SIMPLEQ_INIT(head) do {                                         \
 359  412          (head)->sqh_first = NULL;                                       \
 360  413          (head)->sqh_last = &(head)->sqh_first;                          \
 361  414          _NOTE(CONSTCOND)                                                \
 362  415  } while (0)
 363  416  
 364  417  #define SIMPLEQ_INSERT_HEAD(head, elm, field) do {                      \
 365  418          if (((elm)->field.sqe_next = (head)->sqh_first) == NULL)        \
↓ open down ↓ 29 lines elided ↑ open up ↑
 395  448                  struct type *curelm = (head)->sqh_first;                \
 396  449                  while (curelm->field.sqe_next != (elm))                 \
 397  450                          curelm = curelm->field.sqe_next;                \
 398  451                  if ((curelm->field.sqe_next =                           \
 399  452                          curelm->field.sqe_next->field.sqe_next) == NULL) \
 400  453                              (head)->sqh_last = &(curelm)->field.sqe_next; \
 401  454          }                                                               \
 402  455          _NOTE(CONSTCOND)                                                \
 403  456  } while (0)
 404  457  
 405      -#define SIMPLEQ_FOREACH(var, head, field)                               \
 406      -        for ((var) = ((head)->sqh_first);                               \
 407      -                (var);                                                  \
 408      -                (var) = ((var)->field.sqe_next))
 409  458  
 410  459  /*
 411      - * Simple queue access methods.
 412      - */
 413      -#define SIMPLEQ_EMPTY(head)             ((head)->sqh_first == NULL)
 414      -#define SIMPLEQ_FIRST(head)             ((head)->sqh_first)
 415      -#define SIMPLEQ_NEXT(elm, field)        ((elm)->field.sqe_next)
 416      -
 417      -
 418      -/*
 419  460   * Tail queue definitions.
 420  461   */
 421  462  #define _TAILQ_HEAD(name, type)                                         \
 422  463  struct name {                                                           \
 423  464          type *tqh_first;                /* first element */             \
 424  465          type **tqh_last;        /* addr of last next element */         \
 425  466  }
 426  467  #define TAILQ_HEAD(name, type)  _TAILQ_HEAD(name, struct type)
 427  468  
 428  469  #define TAILQ_HEAD_INITIALIZER(head)                                    \
 429  470          { NULL, &(head).tqh_first }
 430  471  
 431  472  #define _TAILQ_ENTRY(type)                                              \
 432  473  struct {                                                                \
 433  474          type *tqe_next;         /* next element */                      \
 434  475          type **tqe_prev;        /* address of previous next element */\
 435  476  }
 436  477  #define TAILQ_ENTRY(type)       _TAILQ_ENTRY(struct type)
 437  478  
 438  479  /*
      480 + * Tail queue access methods.
      481 + */
      482 +#define TAILQ_EMPTY(head)               ((head)->tqh_first == NULL)
      483 +#define TAILQ_FIRST(head)               ((head)->tqh_first)
      484 +#define TAILQ_NEXT(elm, field)          ((elm)->field.tqe_next)
      485 +#define TAILQ_LAST(head, headname) \
      486 +        (*(((struct headname *)((head)->tqh_last))->tqh_last))
      487 +#define TAILQ_PREV(elm, headname, field) \
      488 +        (*(((struct headname *)((elm)->field.tqe_prev))->tqh_last))
      489 +
      490 +
      491 +#define TAILQ_FOREACH(var, head, field)                                 \
      492 +        for ((var) = TAILQ_FIRST((head));                               \
      493 +                (var);                                                  \
      494 +                (var) = TAILQ_NEXT((var), field))
      495 +
      496 +#define TAILQ_FOREACH_SAFE(var, head, field, tvar)                      \
      497 +        for ((var) = TAILQ_FIRST((head));                               \
      498 +                (var) && ((tvar) = TAILQ_NEXT((var), field), 1);        \
      499 +                (var) = (tvar))
      500 +
      501 +#define TAILQ_FOREACH_REVERSE(var, head, headname, field)               \
      502 +        for ((var) = TAILQ_LAST((head), headname);                      \
      503 +                (var);                                                  \
      504 +                (var) = TAILQ_PREV((var), headname, field))
      505 +
      506 +#define TAILQ_FOREACH_REVERSE_SAFE(var, head, headname, field, tvar)    \
      507 +        for ((var) = TAILQ_LAST((head), headname);                      \
      508 +                (var) && ((tvar) = TAILQ_PREV((var), headname, field), 1); \
      509 +                (var) = (tvar))
      510 +
      511 +/*
 439  512   * Tail queue functions.
 440  513   */
 441  514  #if defined(_KERNEL) && defined(QUEUEDEBUG)
 442  515  #define QUEUEDEBUG_TAILQ_INSERT_HEAD(head, elm, field)                  \
 443  516          if ((head)->tqh_first &&                                        \
 444  517              (head)->tqh_first->field.tqe_prev != &(head)->tqh_first)    \
 445  518                  panic("TAILQ_INSERT_HEAD %p %s:%d", (void *)(head),     \
 446  519                      __FILE__, __LINE__);
 447  520  #define QUEUEDEBUG_TAILQ_INSERT_TAIL(head, elm, field)                  \
 448  521          if (*(head)->tqh_last != NULL)                                  \
↓ open down ↓ 78 lines elided ↑ open up ↑
 527  600          if (((elm)->field.tqe_next) != NULL)                            \
 528  601                  (elm)->field.tqe_next->field.tqe_prev =                 \
 529  602                      (elm)->field.tqe_prev;                              \
 530  603          else                                                            \
 531  604                  (head)->tqh_last = (elm)->field.tqe_prev;               \
 532  605          *(elm)->field.tqe_prev = (elm)->field.tqe_next;                 \
 533  606          QUEUEDEBUG_TAILQ_POSTREMOVE((elm), field);                      \
 534  607          _NOTE(CONSTCOND)                                                \
 535  608  } while (0)
 536  609  
 537      -#define TAILQ_FOREACH(var, head, field)                                 \
 538      -        for ((var) = ((head)->tqh_first);                               \
 539      -                (var);                                                  \
 540      -                (var) = ((var)->field.tqe_next))
 541  610  
 542      -#define TAILQ_FOREACH_REVERSE(var, head, headname, field)               \
 543      -        for ((var) = (*(((struct headname *)((head)->tqh_last))->tqh_last));\
 544      -                (var);                                                  \
 545      -                (var) =                                                 \
 546      -                    (*(((struct headname *)((var)->field.tqe_prev))->tqh_last)))
 547      -
 548  611  /*
 549      - * Tail queue access methods.
 550      - */
 551      -#define TAILQ_EMPTY(head)               ((head)->tqh_first == NULL)
 552      -#define TAILQ_FIRST(head)               ((head)->tqh_first)
 553      -#define TAILQ_NEXT(elm, field)          ((elm)->field.tqe_next)
 554      -
 555      -#define TAILQ_LAST(head, headname) \
 556      -        (*(((struct headname *)((head)->tqh_last))->tqh_last))
 557      -#define TAILQ_PREV(elm, headname, field) \
 558      -        (*(((struct headname *)((elm)->field.tqe_prev))->tqh_last))
 559      -
 560      -
 561      -/*
 562  612   * Circular queue definitions.
 563  613   */
 564  614  #define CIRCLEQ_HEAD(name, type)                                        \
 565  615  struct name {                                                           \
 566  616          struct type *cqh_first;         /* first element */     \
 567  617          struct type *cqh_last;          /* last element */              \
 568  618  }
 569  619  
 570  620  #define CIRCLEQ_HEAD_INITIALIZER(head)                                  \
 571  621          { (void *)&head, (void *)&head }
 572  622  
 573  623  #define CIRCLEQ_ENTRY(type)                                             \
 574  624  struct {                                                                \
 575  625          struct type *cqe_next;          /* next element */              \
 576  626          struct type *cqe_prev;          /* previous element */          \
 577  627  }
 578  628  
 579  629  /*
      630 + * Circular queue access methods.
      631 + */
      632 +#define CIRCLEQ_EMPTY(head)             ((head)->cqh_first == (void *)(head))
      633 +#define CIRCLEQ_FIRST(head)             ((head)->cqh_first)
      634 +#define CIRCLEQ_LAST(head)              ((head)->cqh_last)
      635 +#define CIRCLEQ_NEXT(elm, field)        ((elm)->field.cqe_next)
      636 +#define CIRCLEQ_PREV(elm, field)        ((elm)->field.cqe_prev)
      637 +
      638 +#define CIRCLEQ_LOOP_NEXT(head, elm, field)                             \
      639 +        (((elm)->field.cqe_next == (void *)(head))                      \
      640 +            ? ((head)->cqh_first)                                       \
      641 +            : (elm->field.cqe_next))
      642 +#define CIRCLEQ_LOOP_PREV(head, elm, field)                             \
      643 +        (((elm)->field.cqe_prev == (void *)(head))                      \
      644 +            ? ((head)->cqh_last)                                        \
      645 +            : (elm->field.cqe_prev))
      646 +
      647 +#define CIRCLEQ_FOREACH(var, head, field)                               \
      648 +        for ((var) = CIRCLEQ_FIRST((head));                             \
      649 +                (var) != (void *)(head);                                \
      650 +                (var) = CIRCLEQ_NEXT((var), field))
      651 +
      652 +#define CIRCLEQ_FOREACH_REVERSE(var, head, field)                       \
      653 +        for ((var) = CIRCLEQ_LAST((head));                              \
      654 +                (var) != (void *)(head);                                \
      655 +                (var) = CIRCLEQ_PREV((var), field))
      656 +
      657 +/*
 580  658   * Circular queue functions.
 581  659   */
 582  660  #define CIRCLEQ_INIT(head) do {                                         \
 583  661          (head)->cqh_first = (void *)(head);                             \
 584  662          (head)->cqh_last = (void *)(head);                              \
 585  663          _NOTE(CONSTCOND)                                                \
 586  664  } while (0)
 587  665  
 588  666  #define CIRCLEQ_INSERT_AFTER(head, listelm, elm, field) do {            \
 589  667          (elm)->field.cqe_next = (listelm)->field.cqe_next;              \
↓ open down ↓ 46 lines elided ↑ open up ↑
 636  714                  (elm)->field.cqe_next->field.cqe_prev =                 \
 637  715                      (elm)->field.cqe_prev;                              \
 638  716          if ((elm)->field.cqe_prev == (void *)(head))                    \
 639  717                  (head)->cqh_first = (elm)->field.cqe_next;              \
 640  718          else                                                            \
 641  719                  (elm)->field.cqe_prev->field.cqe_next =                 \
 642  720                      (elm)->field.cqe_next;                              \
 643  721          _NOTE(CONSTCOND)                                                \
 644  722  } while (0)
 645  723  
 646      -#define CIRCLEQ_FOREACH(var, head, field)                               \
 647      -        for ((var) = ((head)->cqh_first);                               \
 648      -                (var) != (void *)(head);                                \
 649      -                (var) = ((var)->field.cqe_next))
 650  724  
 651      -#define CIRCLEQ_FOREACH_REVERSE(var, head, field)                       \
 652      -        for ((var) = ((head)->cqh_last);                                \
 653      -                (var) != (void *)(head);                                \
 654      -                (var) = ((var)->field.cqe_prev))
 655      -
 656      -/*
 657      - * Circular queue access methods.
 658      - */
 659      -#define CIRCLEQ_EMPTY(head)             ((head)->cqh_first == (void *)(head))
 660      -#define CIRCLEQ_FIRST(head)             ((head)->cqh_first)
 661      -#define CIRCLEQ_LAST(head)              ((head)->cqh_last)
 662      -#define CIRCLEQ_NEXT(elm, field)        ((elm)->field.cqe_next)
 663      -#define CIRCLEQ_PREV(elm, field)        ((elm)->field.cqe_prev)
 664      -
 665      -#define CIRCLEQ_LOOP_NEXT(head, elm, field)                             \
 666      -        (((elm)->field.cqe_next == (void *)(head))                      \
 667      -            ? ((head)->cqh_first)                                       \
 668      -            : (elm->field.cqe_next))
 669      -#define CIRCLEQ_LOOP_PREV(head, elm, field)                             \
 670      -        (((elm)->field.cqe_prev == (void *)(head))                      \
 671      -            ? ((head)->cqh_last)                                        \
 672      -            : (elm->field.cqe_prev))
 673      -
 674  725  #ifdef  __cplusplus
 675  726  }
 676  727  #endif
 677  728  
 678  729  #endif  /* !_SYS_QUEUE_H */
    
XXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXX