Print this page
    
10687 Service routine cast changes need smatch fixes
    
      
        | Split | 
	Close | 
      
      | Expand all | 
      | Collapse all | 
    
    
          --- old/usr/src/uts/common/io/softmac/softmac_dev.c
          +++ new/usr/src/uts/common/io/softmac/softmac_dev.c
   1    1  /*
   2    2   * CDDL HEADER START
   3    3   *
   4    4   * The contents of this file are subject to the terms of the
   5    5   * Common Development and Distribution License (the "License").
   6    6   * You may not use this file except in compliance with the License.
   7    7   *
   8    8   * You can obtain a copy of the license at usr/src/OPENSOLARIS.LICENSE
   9    9   * or http://www.opensolaris.org/os/licensing.
  10   10   * See the License for the specific language governing permissions
  11   11   * and limitations under the License.
  12   12   *
  13   13   * When distributing Covered Code, include this CDDL HEADER in each
  14   14   * file and include the License file at usr/src/OPENSOLARIS.LICENSE.
  15   15   * If applicable, add the following below this CDDL HEADER, with the
  
    | 
      ↓ open down ↓ | 
    15 lines elided | 
    
      ↑ open up ↑ | 
  
  16   16   * fields enclosed by brackets "[]" replaced with your own identifying
  17   17   * information: Portions Copyright [yyyy] [name of copyright owner]
  18   18   *
  19   19   * CDDL HEADER END
  20   20   */
  21   21  /*
  22   22   * Copyright 2009 Sun Microsystems, Inc.  All rights reserved.
  23   23   * Use is subject to license terms.
  24   24   */
  25   25  
       26 +/*
       27 + * Copyright 2019, Joyent, Inc.
       28 + */
  26   29  
  27   30  #include <sys/types.h>
  28   31  #include <inet/common.h>
  29   32  #include <sys/stropts.h>
  30   33  #include <sys/modctl.h>
  31   34  #include <sys/dld.h>
  32   35  #include <sys/softmac_impl.h>
  33   36  
  34   37  dev_info_t              *softmac_dip = NULL;
  35   38  static kmem_cache_t     *softmac_upper_cachep;
  36   39  
  37   40  /*
  38   41   * This function is a generic open(9E) entry point into the softmac for
  39   42   * both the softmac module and the softmac driver.
  40   43   */
  41   44  static int softmac_cmn_open(queue_t *, dev_t *, int, int, cred_t *);
  42   45  
  43   46  /*
  44   47   * The following softmac_mod_xxx() functions are (9E) entry point functions for
  45   48   * the softmac module.
  46   49   */
  47   50  static int softmac_mod_close(queue_t *, int, cred_t *);
  48   51  static int softmac_mod_rput(queue_t *, mblk_t *);
  49   52  static int softmac_mod_wput(queue_t *, mblk_t *);
  50   53  static int softmac_mod_wsrv(queue_t *);
  51   54  
  52   55  /*
  53   56   * The following softmac_drv_xxx() functions are (9E) entry point functions for
  54   57   * the softmac driver.
  55   58   */
  56   59  static int softmac_drv_open(queue_t *, dev_t *, int, int, cred_t *);
  57   60  static int softmac_drv_close(queue_t *, int, cred_t *);
  58   61  static int softmac_drv_wput(queue_t *, mblk_t *);
  59   62  static int softmac_drv_wsrv(queue_t *);
  60   63  
  61   64  static int softmac_attach(dev_info_t *, ddi_attach_cmd_t);
  62   65  static int softmac_detach(dev_info_t *, ddi_detach_cmd_t);
  63   66  static int softmac_info(dev_info_t *, ddi_info_cmd_t, void *, void **);
  64   67  
  65   68  static struct module_info softmac_modinfo = {
  66   69          0,
  67   70          SOFTMAC_DEV_NAME,
  68   71          0,
  69   72          INFPSZ,
  70   73          65536,
  71   74          1024
  72   75  };
  73   76  
  74   77  /*
  75   78   * hi-water mark is 1 because of the flow control mechanism implemented in
  76   79   * dld.  Refer to the comments in dld_str.c for details.
  77   80   */
  78   81  static struct module_info softmac_dld_modinfo = {
  79   82          0,
  80   83          SOFTMAC_DEV_NAME,
  81   84          0,
  82   85          INFPSZ,
  83   86          1,
  84   87          0
  85   88  };
  86   89  
  87   90  static struct qinit softmac_urinit = {
  88   91          softmac_mod_rput,               /* qi_putp */
  89   92          NULL,                           /* qi_srvp */
  90   93          softmac_cmn_open,               /* qi_qopen */
  91   94          softmac_mod_close,              /* qi_qclose */
  92   95          NULL,                           /* qi_qadmin */
  93   96          &softmac_modinfo                /* qi_minfo */
  94   97  };
  95   98  
  96   99  static struct qinit softmac_uwinit = {
  97  100          softmac_mod_wput,               /* qi_putp */
  98  101          softmac_mod_wsrv,               /* qi_srvp */
  99  102          NULL,                           /* qi_qopen */
 100  103          NULL,                           /* qi_qclose */
 101  104          NULL,                           /* qi_qadmin */
 102  105          &softmac_modinfo                /* qi_minfo */
 103  106  };
 104  107  
 105  108  static struct streamtab softmac_tab = {
 106  109          &softmac_urinit,        /* st_rdinit */
 107  110          &softmac_uwinit         /* st_wrinit */
 108  111  };
 109  112  
 110  113  DDI_DEFINE_STREAM_OPS(softmac_ops, nulldev, nulldev, softmac_attach,
 111  114      softmac_detach, nodev, softmac_info, D_MP, &softmac_tab,
 112  115      ddi_quiesce_not_supported);
 113  116  
 114  117  static struct qinit softmac_dld_r_qinit = {
 115  118          NULL, NULL, softmac_drv_open, softmac_drv_close, NULL,
 116  119          &softmac_dld_modinfo
 117  120  };
 118  121  
 119  122  static struct qinit softmac_dld_w_qinit = {
 120  123          softmac_drv_wput, softmac_drv_wsrv, NULL, NULL, NULL,
 121  124          &softmac_dld_modinfo
 122  125  };
 123  126  
 124  127  static struct fmodsw softmac_fmodsw = {
 125  128          SOFTMAC_DEV_NAME,
 126  129          &softmac_tab,
 127  130          D_MP
 128  131  };
 129  132  
 130  133  static struct modldrv softmac_modldrv = {
 131  134          &mod_driverops,
 132  135          "softmac driver",
 133  136          &softmac_ops
 134  137  };
 135  138  
 136  139  static struct modlstrmod softmac_modlstrmod = {
 137  140          &mod_strmodops,
 138  141          "softmac module",
 139  142          &softmac_fmodsw
 140  143  };
 141  144  
 142  145  static struct modlinkage softmac_modlinkage = {
 143  146          MODREV_1,
 144  147          &softmac_modlstrmod,
 145  148          &softmac_modldrv,
 146  149          NULL
 147  150  };
 148  151  
 149  152  static void softmac_dedicated_rx(void *, mac_resource_handle_t, mblk_t *,
 150  153      mac_header_info_t *);
 151  154  
 152  155  /*ARGSUSED*/
 153  156  static int
 154  157  softmac_upper_constructor(void *buf, void *arg, int kmflag)
 155  158  {
 156  159          softmac_upper_t *sup = buf;
 157  160  
 158  161          bzero(buf, sizeof (softmac_upper_t));
 159  162  
 160  163          mutex_init(&sup->su_mutex, NULL, MUTEX_DEFAULT, NULL);
 161  164          cv_init(&sup->su_cv, NULL, CV_DEFAULT, NULL);
 162  165          mutex_init(&sup->su_disp_mutex, NULL, MUTEX_DEFAULT, NULL);
 163  166          cv_init(&sup->su_disp_cv, NULL, CV_DEFAULT, NULL);
 164  167          list_create(&sup->su_req_list, sizeof (softmac_switch_req_t),
 165  168              offsetof(softmac_switch_req_t, ssq_req_list_node));
 166  169          return (0);
 167  170  }
 168  171  
 169  172  /*ARGSUSED*/
 170  173  static void
 171  174  softmac_upper_destructor(void *buf, void *arg)
 172  175  {
 173  176          softmac_upper_t *sup = buf;
 174  177  
 175  178          ASSERT(sup->su_slp == NULL);
 176  179          ASSERT(sup->su_pending_head == NULL && sup->su_pending_tail == NULL);
 177  180          ASSERT(!sup->su_dlpi_pending);
 178  181          ASSERT(!sup->su_active);
 179  182          ASSERT(!sup->su_closing);
 180  183          ASSERT(sup->su_tx_flow_mp == NULL);
 181  184          ASSERT(sup->su_tx_inprocess == 0);
 182  185          ASSERT(sup->su_mode == SOFTMAC_UNKNOWN);
 183  186          ASSERT(!sup->su_tx_busy);
 184  187          ASSERT(!sup->su_bound);
 185  188          ASSERT(!sup->su_taskq_scheduled);
 186  189          ASSERT(sup->su_tx_notify_func == NULL);
 187  190          ASSERT(sup->su_tx_notify_arg == NULL);
 188  191          ASSERT(list_is_empty(&sup->su_req_list));
 189  192  
 190  193          list_destroy(&sup->su_req_list);
 191  194          mutex_destroy(&sup->su_mutex);
 192  195          cv_destroy(&sup->su_cv);
 193  196          mutex_destroy(&sup->su_disp_mutex);
 194  197          cv_destroy(&sup->su_disp_cv);
 195  198  }
 196  199  
 197  200  int
 198  201  _init(void)
 199  202  {
 200  203          int     err;
 201  204  
 202  205          mac_init_ops(NULL, SOFTMAC_DEV_NAME);
 203  206          softmac_init();
 204  207  
 205  208          softmac_upper_cachep = kmem_cache_create("softmac_upper_cache",
 206  209              sizeof (softmac_upper_t), 0, softmac_upper_constructor,
 207  210              softmac_upper_destructor, NULL, NULL, NULL, 0);
 208  211          ASSERT(softmac_upper_cachep != NULL);
 209  212  
 210  213          if ((err = mod_install(&softmac_modlinkage)) != 0) {
 211  214                  softmac_fini();
 212  215                  return (err);
 213  216          }
 214  217  
 215  218          return (0);
 216  219  }
 217  220  
 218  221  int
 219  222  _fini(void)
 220  223  {
 221  224          int err;
 222  225  
 223  226          if (softmac_busy())
 224  227                  return (EBUSY);
 225  228  
 226  229          if ((err = mod_remove(&softmac_modlinkage)) != 0)
 227  230                  return (err);
 228  231  
 229  232          kmem_cache_destroy(softmac_upper_cachep);
 230  233          softmac_fini();
 231  234  
 232  235          return (0);
 233  236  }
 234  237  
 235  238  int
 236  239  _info(struct modinfo *modinfop)
 237  240  {
 238  241          return (mod_info(&softmac_modlinkage, modinfop));
 239  242  }
 240  243  
 241  244  static int
 242  245  softmac_cmn_open(queue_t *rq, dev_t *devp, int flag, int sflag, cred_t *credp)
 243  246  {
 244  247          softmac_lower_t *slp;
 245  248          /*
 246  249           * This is a self-cloning driver so that each queue should only
 247  250           * get opened once.
 248  251           */
 249  252          if (rq->q_ptr != NULL)
 250  253                  return (EBUSY);
 251  254  
 252  255          if (sflag == MODOPEN) {
 253  256                  /*
 254  257                   * This is the softmac module pushed over an underlying
 255  258                   * legacy device.  Initialize the lower structure.
 256  259                   */
 257  260                  if ((slp = kmem_zalloc(sizeof (*slp), KM_NOSLEEP)) == NULL)
 258  261                          return (ENOMEM);
 259  262  
 260  263                  slp->sl_wq = WR(rq);
 261  264                  cv_init(&slp->sl_cv, NULL, CV_DRIVER, NULL);
 262  265                  mutex_init(&slp->sl_mutex, NULL, MUTEX_DRIVER, NULL);
 263  266                  slp->sl_pending_prim = DL_PRIM_INVAL;
 264  267                  rq->q_ptr = WR(rq)->q_ptr = slp;
 265  268                  qprocson(rq);
 266  269                  return (0);
 267  270          }
 268  271  
 269  272          /*
 270  273           * Regular device open of a softmac DLPI node.  We modify
 271  274           * the queues' q_qinfo pointer such that all future STREAMS
 272  275           * operations will go through another set of entry points
 273  276           */
 274  277          rq->q_qinfo = &softmac_dld_r_qinit;
 275  278          WR(rq)->q_qinfo = &softmac_dld_w_qinit;
 276  279          return (softmac_drv_open(rq, devp, flag, sflag, credp));
 277  280  }
 278  281  
 279  282  /* ARGSUSED */
 280  283  static int
 281  284  softmac_mod_close(queue_t *rq, int flags __unused, cred_t *credp __unused)
 282  285  {
 283  286          softmac_lower_t *slp = rq->q_ptr;
 284  287  
 285  288          /*
 286  289           * Call the appropriate delete routine depending on whether this is
 287  290           * a module or device.
 288  291           */
 289  292          ASSERT(WR(rq)->q_next != NULL);
 290  293  
 291  294          qprocsoff(rq);
 292  295  
 293  296          slp->sl_softmac = NULL;
 294  297          slp->sl_lh = NULL;
 295  298  
 296  299          ASSERT(slp->sl_ack_mp == NULL);
 297  300          ASSERT(slp->sl_pending_prim == DL_PRIM_INVAL);
 298  301          ASSERT(slp->sl_pending_ioctl == B_FALSE);
 299  302  
 300  303          cv_destroy(&slp->sl_cv);
 301  304          mutex_destroy(&slp->sl_mutex);
 302  305  
 303  306          kmem_free(slp, sizeof (*slp));
 304  307          return (0);
 305  308  }
 306  309  
 307  310  static int
 308  311  softmac_mod_rput(queue_t *rq, mblk_t *mp)
 309  312  {
 310  313          softmac_lower_t         *slp = rq->q_ptr;
 311  314          softmac_lower_rxinfo_t  *rxinfo;
 312  315          union DL_primitives     *dlp;
 313  316  
 314  317          /*
 315  318           * This is the softmac module.
 316  319           */
 317  320          ASSERT(WR(rq)->q_next != NULL);
 318  321          ASSERT((mp->b_next == NULL) && (mp->b_prev == NULL));
 319  322  
 320  323          switch (DB_TYPE(mp)) {
 321  324          case M_DATA: {
 322  325  
 323  326                  /*
 324  327                   * If sl_rxinfo is non-NULL. This is dedicated-lower-stream
 325  328                   * created for fastpath. Directly call the rx callback.
 326  329                   */
 327  330                  if ((rxinfo = slp->sl_rxinfo) != NULL) {
 328  331                          rxinfo->slr_rx(rxinfo->slr_arg, NULL, mp, NULL);
 329  332                          break;
 330  333                  }
 331  334  
 332  335                  /*
 333  336                   * A shared-lower-stream. Some driver starts to send up
 334  337                   * packets even it not in the DL_IDLE state, where
 335  338                   * sl_softmac is not set yet. Drop the packet in this case.
 336  339                   */
 337  340                  if (slp->sl_softmac == NULL) {
 338  341                          freemsg(mp);
 339  342                          return (0);
 340  343                  }
 341  344  
 342  345                  /*
 343  346                   * If this message is looped back from the legacy devices,
 344  347                   * drop it as the Nemo framework will be responsible for
 345  348                   * looping it back by the mac_txloop() function.
 346  349                   */
 347  350                  if (mp->b_flag & MSGNOLOOP) {
 348  351                          freemsg(mp);
 349  352                          return (0);
 350  353                  }
 351  354  
 352  355                  /*
 353  356                   * This is the most common case.
 354  357                   */
 355  358                  if (DB_REF(mp) == 1) {
 356  359                          ASSERT(slp->sl_softmac != NULL);
 357  360                          mac_rx(slp->sl_softmac->smac_mh, NULL, mp);
 358  361                          return (0);
 359  362                  } else {
 360  363                          softmac_rput_process_data(slp, mp);
 361  364                  }
 362  365                  break;
 363  366          }
 364  367          case M_PROTO:
 365  368          case M_PCPROTO:
 366  369                  if (MBLKL(mp) < sizeof (dlp->dl_primitive)) {
 367  370                          freemsg(mp);
 368  371                          break;
 369  372                  }
 370  373                  dlp = (union DL_primitives *)mp->b_rptr;
 371  374                  if (dlp->dl_primitive == DL_UNITDATA_IND) {
 372  375  
 373  376                          if ((rxinfo = slp->sl_rxinfo) != NULL) {
 374  377                                  softmac_dedicated_rx(slp->sl_sup, NULL, mp,
 375  378                                      NULL);
 376  379                                  break;
 377  380                          }
 378  381  
 379  382                          cmn_err(CE_WARN, "got unexpected %s message",
 380  383                              dl_primstr(DL_UNITDATA_IND));
 381  384                          freemsg(mp);
 382  385                          break;
 383  386                  }
 384  387                  /*FALLTHROUGH*/
 385  388          default:
 386  389                  softmac_rput_process_notdata(rq, slp->sl_sup, mp);
 387  390                  break;
 388  391          }
 389  392          return (0);
 390  393  }
 391  394  
 392  395  static int
 393  396  softmac_mod_wput(queue_t *wq, mblk_t *mp)
 394  397  {
 395  398          /*
 396  399           * This is the softmac module
 397  400           */
 398  401          ASSERT(wq->q_next != NULL);
 399  402  
 400  403          switch (DB_TYPE(mp)) {
 401  404          case M_IOCTL: {
 402  405                  struct iocblk           *ioc = (struct iocblk *)mp->b_rptr;
 403  406  
 404  407                  switch (ioc->ioc_cmd) {
 405  408                  case SMAC_IOC_START: {
 406  409                          softmac_lower_t         *slp = wq->q_ptr;
 407  410                          smac_ioc_start_t        *arg;
 408  411  
 409  412                          if (ioc->ioc_count != sizeof (*arg)) {
 410  413                                  miocnak(wq, mp, 0, EINVAL);
 411  414                                  break;
 412  415                          }
 413  416  
 414  417                          /*
 415  418                           * Assign the devname and perstream handle of the
 416  419                           * specific lower stream and return it as a part
 417  420                           * of the ioctl.
 418  421                           */
 419  422                          arg = (smac_ioc_start_t *)mp->b_cont->b_rptr;
 420  423                          arg->si_slp = slp;
 421  424                          miocack(wq, mp, sizeof (*arg), 0);
 422  425                          break;
 423  426                  }
 424  427                  default:
 425  428                          miocnak(wq, mp, 0, EINVAL);
 426  429                          break;
 427  430                  }
 428  431                  break;
 429  432          }
 430  433          default:
 431  434                  freemsg(mp);
 432  435                  break;
 433  436          }
 434  437          return (0);
 435  438  }
 436  439  
 437  440  static int
 438  441  softmac_mod_wsrv(queue_t *wq)
 439  442  {
 440  443          softmac_lower_t *slp = wq->q_ptr;
 441  444  
 442  445          /*
 443  446           * This is the softmac module
 444  447           */
 445  448          ASSERT(wq->q_next != NULL);
 446  449  
 447  450          /*
 448  451           * Inform that the tx resource is available; mac_tx_update() will
 449  452           * inform all the upper streams sharing this lower stream.
 450  453           */
 451  454          if (slp->sl_sup != NULL)
 452  455                  qenable(slp->sl_sup->su_wq);
 453  456          else if (slp->sl_softmac != NULL)
 454  457                  mac_tx_update(slp->sl_softmac->smac_mh);
 455  458          return (0);
 456  459  }
 457  460  
 458  461  static int
 459  462  softmac_attach(dev_info_t *dip, ddi_attach_cmd_t cmd)
 460  463  {
 461  464          ASSERT(ddi_get_instance(dip) == 0);
 462  465  
 463  466          if (cmd != DDI_ATTACH)
 464  467                  return (DDI_FAILURE);
 465  468  
 466  469          softmac_dip = dip;
 467  470  
 468  471          return (DDI_SUCCESS);
 469  472  }
 470  473  
 471  474  /* ARGSUSED */
 472  475  static int
 473  476  softmac_detach(dev_info_t *dip, ddi_detach_cmd_t cmd)
 474  477  {
 475  478          if (cmd != DDI_DETACH)
 476  479                  return (DDI_FAILURE);
 477  480  
 478  481          softmac_dip = NULL;
 479  482          return (DDI_SUCCESS);
 480  483  }
 481  484  
 482  485  /* ARGSUSED */
 483  486  static int
 484  487  softmac_info(dev_info_t *dip, ddi_info_cmd_t infocmd, void *arg, void **result)
 485  488  {
 486  489          switch (infocmd) {
 487  490          case DDI_INFO_DEVT2DEVINFO:
 488  491                  if (softmac_dip != NULL) {
 489  492                          *result = softmac_dip;
 490  493                          return (DDI_SUCCESS);
 491  494                  }
 492  495                  break;
 493  496  
 494  497          case DDI_INFO_DEVT2INSTANCE:
 495  498                  *result = NULL;
 496  499                  return (DDI_SUCCESS);
 497  500  
 498  501          }
 499  502  
 500  503          return (DDI_FAILURE);
 501  504  }
 502  505  
 503  506  /*ARGSUSED*/
 504  507  static void
 505  508  softmac_dedicated_rx(void *arg, mac_resource_handle_t mrh, mblk_t *mp,
 506  509      mac_header_info_t *mhip)
 507  510  {
 508  511          queue_t *rq = ((softmac_upper_t *)arg)->su_rq;
 509  512  
 510  513          if (canputnext(rq))
 511  514                  putnext(rq, mp);
 512  515          else
 513  516                  freemsg(mp);
 514  517  }
 515  518  
 516  519  /*ARGSUSED*/
 517  520  static int
 518  521  softmac_drv_open(queue_t *rq, dev_t *devp, int flag, int sflag, cred_t *credp)
 519  522  {
 520  523          softmac_upper_t *sup = NULL;
 521  524          softmac_t       *softmac;
 522  525          int             err = 0;
 523  526  
 524  527          /*
 525  528           * This is a softmac device created for a legacy device, find the
 526  529           * associated softmac and initialize the softmac_upper_t structure.
 527  530           */
 528  531          if ((err = softmac_hold(*devp, &softmac)) != 0)
 529  532                  return (err);
 530  533  
 531  534          sup = kmem_cache_alloc(softmac_upper_cachep, KM_NOSLEEP);
 532  535          if (sup == NULL) {
 533  536                  err = ENOMEM;
 534  537                  goto fail;
 535  538          }
 536  539  
 537  540          ASSERT(list_is_empty(&sup->su_req_list));
 538  541  
 539  542          if ((sup->su_tx_flow_mp = allocb(1, BPRI_HI)) == NULL) {
 540  543                  err = ENOMEM;
 541  544                  goto fail;
 542  545          }
 543  546  
 544  547          sup->su_rq = rq;
 545  548          sup->su_wq = WR(rq);
 546  549          sup->su_softmac = softmac;
 547  550          sup->su_mode = SOFTMAC_UNKNOWN;
 548  551  
 549  552          sup->su_rxinfo.slr_arg = sup;
 550  553          sup->su_rxinfo.slr_rx = softmac_dedicated_rx;
 551  554          sup->su_direct_rxinfo.slr_arg = sup;
 552  555          sup->su_direct_rxinfo.slr_rx = softmac_dedicated_rx;
 553  556  
 554  557          if ((err = dld_str_open(rq, devp, sup)) != 0) {
 555  558                  freeb(sup->su_tx_flow_mp);
 556  559                  sup->su_tx_flow_mp = NULL;
 557  560                  goto fail;
 558  561          }
 559  562  
 560  563          return (0);
 561  564  
 562  565  fail:
 563  566          if (sup != NULL)
 564  567                  kmem_cache_free(softmac_upper_cachep, sup);
 565  568          softmac_rele(softmac);
 566  569          return (err);
 567  570  }
 568  571  
 569  572  /* ARGSUSED */
 570  573  static int
 571  574  softmac_drv_close(queue_t *rq, int flags __unused, cred_t *credp __unused)
 572  575  {
 573  576          softmac_upper_t *sup = dld_str_private(rq);
 574  577          softmac_t       *softmac = sup->su_softmac;
 575  578  
 576  579          ASSERT(WR(rq)->q_next == NULL);
 577  580  
 578  581          qprocsoff(rq);
 579  582  
 580  583          ASSERT(sup->su_tx_inprocess == 0);
 581  584  
 582  585          /*
 583  586           * Wait until the pending request are processed by the worker thread.
 584  587           */
 585  588          mutex_enter(&sup->su_disp_mutex);
 586  589          sup->su_closing = B_TRUE;
 587  590          while (sup->su_dlpi_pending)
 588  591                  cv_wait(&sup->su_disp_cv, &sup->su_disp_mutex);
 589  592          mutex_exit(&sup->su_disp_mutex);
 590  593  
 591  594          softmac_upperstream_close(sup);
 592  595  
 593  596          if (sup->su_tx_flow_mp != NULL) {
 594  597                  freeb(sup->su_tx_flow_mp);
 595  598                  sup->su_tx_flow_mp = NULL;
 596  599          }
 597  600  
 598  601          if (sup->su_active) {
 599  602                  mutex_enter(&softmac->smac_active_mutex);
 600  603                  softmac->smac_nactive--;
 601  604                  mutex_exit(&softmac->smac_active_mutex);
 602  605                  sup->su_active = B_FALSE;
 603  606          }
 604  607  
 605  608          sup->su_bound = B_FALSE;
 606  609          sup->su_softmac = NULL;
 607  610          sup->su_closing = B_FALSE;
 608  611  
 609  612          kmem_cache_free(softmac_upper_cachep, sup);
 610  613  
 611  614          softmac_rele(softmac);
 612  615          return (dld_str_close(rq));
 613  616  }
 614  617  
 615  618  static int
 616  619  softmac_drv_wput(queue_t *wq, mblk_t *mp)
 617  620  {
 618  621          softmac_upper_t *sup = dld_str_private(wq);
 619  622          t_uscalar_t     prim;
 620  623  
 621  624          ASSERT(wq->q_next == NULL);
 622  625  
 623  626          switch (DB_TYPE(mp)) {
 624  627          case M_DATA:
 625  628          case M_MULTIDATA:
 626  629                  softmac_wput_data(sup, mp);
 627  630                  break;
 628  631          case M_PROTO:
 629  632          case M_PCPROTO:
 630  633  
 631  634                  if (MBLKL(mp) < sizeof (t_uscalar_t)) {
 632  635                          freemsg(mp);
 633  636                          return (0);
 634  637                  }
 635  638  
 636  639                  prim = ((union DL_primitives *)mp->b_rptr)->dl_primitive;
 637  640                  if (prim == DL_UNITDATA_REQ) {
 638  641                          softmac_wput_data(sup, mp);
 639  642                          return (0);
 640  643                  }
 641  644  
 642  645                  softmac_wput_nondata(sup, mp);
 643  646                  break;
 644  647          default:
 645  648                  softmac_wput_nondata(sup, mp);
 646  649                  break;
 647  650          }
 648  651          return (0);
 649  652  }
 650  653  
 651  654  static int
 652  655  softmac_drv_wsrv(queue_t *wq)
 653  656  {
 654  657          softmac_upper_t *sup = dld_str_private(wq);
  
    | 
      ↓ open down ↓ | 
    619 lines elided | 
    
      ↑ open up ↑ | 
  
 655  658  
 656  659          ASSERT(wq->q_next == NULL);
 657  660  
 658  661          mutex_enter(&sup->su_mutex);
 659  662          if (sup->su_mode != SOFTMAC_FASTPATH) {
 660  663                  /*
 661  664                   * Bump su_tx_inprocess so that su_mode won't change.
 662  665                   */
 663  666                  sup->su_tx_inprocess++;
 664  667                  mutex_exit(&sup->su_mutex);
 665      -                dld_wsrv(wq);
      668 +                (void) dld_wsrv(wq);
 666  669                  mutex_enter(&sup->su_mutex);
 667  670                  if (--sup->su_tx_inprocess == 0)
 668  671                          cv_signal(&sup->su_cv);
 669  672          } else if (sup->su_tx_busy && SOFTMAC_CANPUTNEXT(sup->su_slp->sl_wq)) {
 670  673                  /*
 671  674                   * The flow-conctol of the dedicated-lower-stream is
 672  675                   * relieved. If DLD_CAPAB_DIRECT is enabled, call tx_notify
 673  676                   * callback to relieve the flow-control of the specific client,
 674  677                   * otherwise relieve the flow-control of all the upper-stream
 675  678                   * using the traditional STREAM mechanism.
 676  679                   */
 677  680                  if (sup->su_tx_notify_func != NULL) {
 678  681                          sup->su_tx_inprocess++;
 679  682                          mutex_exit(&sup->su_mutex);
 680  683                          sup->su_tx_notify_func(sup->su_tx_notify_arg,
 681  684                              (mac_tx_cookie_t)sup);
 682  685                          mutex_enter(&sup->su_mutex);
 683  686                          if (--sup->su_tx_inprocess == 0)
 684  687                                  cv_signal(&sup->su_cv);
 685  688                  }
 686  689                  ASSERT(sup->su_tx_flow_mp == NULL);
 687  690                  VERIFY((sup->su_tx_flow_mp = getq(wq)) != NULL);
 688  691                  sup->su_tx_busy = B_FALSE;
 689  692          }
 690  693          mutex_exit(&sup->su_mutex);
 691  694          return (0);
 692  695  }
  
    | 
      ↓ open down ↓ | 
    17 lines elided | 
    
      ↑ open up ↑ | 
  
XXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXX