Print this page
NEX-17944 HBA drivers don't need the redundant devfs_clean step
Reviewed by: Dan Fields <dan.fields@nexenta.com>
Reviewed by: Rick McNeal <rick.mcneal@nexenta.com>
NEX-7908 useless assert in pvscsi_remove_from_queue()
Reviewed by: Dan Fields <dan.fields@nexenta.com>
NEX-6869 pvscsi`pvscsi_bus_config uses wrong base while configuring targets
NEX-6870 pvscsi panics while simultaneously deleting large number of disks
Reviewed by: Hans Rosenfeld <hans.rosenfeld@nexenta.com>
NEX-6382 rework pvscsi
Reviewed by: Hans Rosenfeld <hans.rosenfeld@nexenta.com>
Reviewed by: Kevin Crowe <kevin.crowe@nexenta.com>
re #10804 rb3697 Mem-leaks in libsldap (fix lint)
re #10804 rb3697 Mem-leaks in libsldap
Modifications to clean up gcc4 warnings for both with- and without-
closed nza-kernel builds.
re #10787 rb3347 Integrate pvscsi driver to nza-kernel
   1 /*
   2  * This file and its contents are supplied under the terms of the
   3  * Common Development and Distribution License ("CDDL"), version 1.0.
   4  * You may only use this file in accordance with the terms of version
   5  * 1.0 of the CDDL.
   6  *
   7  * A full copy of the text of the CDDL should have accompanied this
   8  * source.  A copy of the CDDL is also available via the Internet at
   9  * http://www.illumos.org/license/CDDL.
  10  */
  11 
  12 /*
  13  * Copyright 2016 Nexenta Systems, Inc.
  14  */
  15 
  16 #include <sys/atomic.h>
  17 #include <sys/cmn_err.h>
  18 #include <sys/conf.h>
  19 #include <sys/cpuvar.h>
  20 #include <sys/ddi.h>
  21 #include <sys/errno.h>
  22 #include <sys/fs/dv_node.h>
  23 #include <sys/kmem.h>
  24 #include <sys/kmem_impl.h>
  25 #include <sys/list.h>
  26 #include <sys/modctl.h>
  27 #include <sys/pci.h>
  28 #include <sys/scsi/scsi.h>
  29 #include <sys/sunddi.h>
  30 #include <sys/sysmacros.h>
  31 #include <sys/time.h>
  32 #include <sys/types.h>
  33 
  34 #include "pvscsi.h"
  35 #include "pvscsi_var.h"
  36 
  37 int pvscsi_enable_msi = 1;
  38 int pvscsi_ring_pages = PVSCSI_DEFAULT_NUM_PAGES_PER_RING;
  39 int pvscsi_msg_ring_pages = PVSCSI_DEFAULT_NUM_PAGES_MSG_RING;
  40 
  41 static int pvscsi_abort(struct scsi_address *ap, struct scsi_pkt *pkt);
  42 


 107 static void
 108 pvscsi_add_to_queue(pvscsi_cmd_t *cmd)
 109 {
 110         pvscsi_softc_t  *pvs = cmd->cmd_pvs;
 111 
 112         ASSERT(pvs != NULL);
 113         ASSERT(mutex_owned(&pvs->mutex));
 114         ASSERT(!list_link_active(&(cmd)->cmd_queue_node));
 115 
 116         list_insert_tail(&pvs->cmd_queue, cmd);
 117         pvs->cmd_queue_len++;
 118 }
 119 
 120 static void
 121 pvscsi_remove_from_queue(pvscsi_cmd_t *cmd)
 122 {
 123         pvscsi_softc_t  *pvs = cmd->cmd_pvs;
 124 
 125         ASSERT(pvs != NULL);
 126         ASSERT(mutex_owned(&pvs->mutex));
 127         ASSERT(list_link_active(&cmd->cmd_queue_node));
 128         ASSERT(pvs->cmd_queue_len > 0);
 129 
 130         if (list_link_active(&cmd->cmd_queue_node)) {

 131                 list_remove(&pvs->cmd_queue, cmd);
 132                 pvs->cmd_queue_len--;
 133         }
 134 }
 135 
 136 static uint64_t
 137 pvscsi_map_ctx(pvscsi_softc_t *pvs, pvscsi_cmd_ctx_t *io_ctx)
 138 {
 139         return (io_ctx - pvs->cmd_ctx + 1);
 140 }
 141 
 142 static pvscsi_cmd_ctx_t *
 143 pvscsi_lookup_ctx(pvscsi_softc_t *pvs, pvscsi_cmd_t *cmd)
 144 {
 145         pvscsi_cmd_ctx_t *ctx, *end;
 146 
 147         end = &pvs->cmd_ctx[pvs->req_depth];
 148         for (ctx = pvs->cmd_ctx; ctx < end; ctx++) {
 149                 if (ctx->cmd == cmd)
 150                         return (ctx);


 343         dev_info_t      *dip;
 344         int             inqrc;
 345         int             ncompatible = 0;
 346         pvscsi_device_t *devnode;
 347         struct scsi_inquiry inq;
 348 
 349         ASSERT(DEVI_BUSY_OWNED(pdip));
 350 
 351         /* Inquiry target */
 352         inqrc = pvscsi_inquiry_target(pvs, target, &inq);
 353 
 354         /* Find devnode */
 355         for (devnode = list_head(&pvs->devnodes); devnode != NULL;
 356             devnode = list_next(&pvs->devnodes, devnode)) {
 357                 if (devnode->target == target)
 358                         break;
 359         }
 360 
 361         if (devnode != NULL) {
 362                 if (inqrc != 0) {
 363                         /* Target disappeared, drop devnode */
 364                         if (i_ddi_devi_attached(devnode->pdip)) {
 365                                 char    *devname;
 366                                 /* Get full devname */
 367                                 devname = kmem_alloc(MAXPATHLEN, KM_SLEEP);
 368                                 (void) ddi_deviname(devnode->pdip, devname);
 369                                 /* Clean cache and name */
 370                                 (void) devfs_clean(devnode->parent, devname + 1,
 371                                     DV_CLEAN_FORCE);
 372                                 kmem_free(devname, MAXPATHLEN);
 373                         }
 374 
 375                         (void) ndi_devi_offline(devnode->pdip, NDI_DEVI_REMOVE);
 376 
 377                         list_remove(&pvs->devnodes, devnode);
 378                         kmem_free(devnode, sizeof (*devnode));
 379                 } else if (childp != NULL) {
 380                         /* Target exists */
 381                         *childp = devnode->pdip;
 382                 }
 383                 return (NDI_SUCCESS);
 384         } else if (inqrc != 0) {
 385                 /* Target doesn't exist */
 386                 return (NDI_FAILURE);
 387         }
 388 
 389         scsi_hba_nodename_compatible_get(&inq, NULL, inq.inq_dtype, NULL,
 390             &nodename, &compatible, &ncompatible);
 391         if (nodename == NULL)
 392                 goto free_nodename;
 393 
 394         if (ndi_devi_alloc(pdip, nodename, DEVI_SID_NODEID,
 395             &dip) != NDI_SUCCESS) {
 396                 dev_err(pvs->dip, CE_WARN, "!failed to alloc device instance");


   1 /*
   2  * This file and its contents are supplied under the terms of the
   3  * Common Development and Distribution License ("CDDL"), version 1.0.
   4  * You may only use this file in accordance with the terms of version
   5  * 1.0 of the CDDL.
   6  *
   7  * A full copy of the text of the CDDL should have accompanied this
   8  * source.  A copy of the CDDL is also available via the Internet at
   9  * http://www.illumos.org/license/CDDL.
  10  */
  11 
  12 /*
  13  * Copyright 2018 Nexenta Systems, Inc.
  14  */
  15 
  16 #include <sys/atomic.h>
  17 #include <sys/cmn_err.h>
  18 #include <sys/conf.h>
  19 #include <sys/cpuvar.h>
  20 #include <sys/ddi.h>
  21 #include <sys/errno.h>

  22 #include <sys/kmem.h>
  23 #include <sys/kmem_impl.h>
  24 #include <sys/list.h>
  25 #include <sys/modctl.h>
  26 #include <sys/pci.h>
  27 #include <sys/scsi/scsi.h>
  28 #include <sys/sunddi.h>
  29 #include <sys/sysmacros.h>
  30 #include <sys/time.h>
  31 #include <sys/types.h>
  32 
  33 #include "pvscsi.h"
  34 #include "pvscsi_var.h"
  35 
  36 int pvscsi_enable_msi = 1;
  37 int pvscsi_ring_pages = PVSCSI_DEFAULT_NUM_PAGES_PER_RING;
  38 int pvscsi_msg_ring_pages = PVSCSI_DEFAULT_NUM_PAGES_MSG_RING;
  39 
  40 static int pvscsi_abort(struct scsi_address *ap, struct scsi_pkt *pkt);
  41 


 106 static void
 107 pvscsi_add_to_queue(pvscsi_cmd_t *cmd)
 108 {
 109         pvscsi_softc_t  *pvs = cmd->cmd_pvs;
 110 
 111         ASSERT(pvs != NULL);
 112         ASSERT(mutex_owned(&pvs->mutex));
 113         ASSERT(!list_link_active(&(cmd)->cmd_queue_node));
 114 
 115         list_insert_tail(&pvs->cmd_queue, cmd);
 116         pvs->cmd_queue_len++;
 117 }
 118 
 119 static void
 120 pvscsi_remove_from_queue(pvscsi_cmd_t *cmd)
 121 {
 122         pvscsi_softc_t  *pvs = cmd->cmd_pvs;
 123 
 124         ASSERT(pvs != NULL);
 125         ASSERT(mutex_owned(&pvs->mutex));


 126 
 127         if (list_link_active(&cmd->cmd_queue_node)) {
 128                 ASSERT(pvs->cmd_queue_len > 0);
 129                 list_remove(&pvs->cmd_queue, cmd);
 130                 pvs->cmd_queue_len--;
 131         }
 132 }
 133 
 134 static uint64_t
 135 pvscsi_map_ctx(pvscsi_softc_t *pvs, pvscsi_cmd_ctx_t *io_ctx)
 136 {
 137         return (io_ctx - pvs->cmd_ctx + 1);
 138 }
 139 
 140 static pvscsi_cmd_ctx_t *
 141 pvscsi_lookup_ctx(pvscsi_softc_t *pvs, pvscsi_cmd_t *cmd)
 142 {
 143         pvscsi_cmd_ctx_t *ctx, *end;
 144 
 145         end = &pvs->cmd_ctx[pvs->req_depth];
 146         for (ctx = pvs->cmd_ctx; ctx < end; ctx++) {
 147                 if (ctx->cmd == cmd)
 148                         return (ctx);


 341         dev_info_t      *dip;
 342         int             inqrc;
 343         int             ncompatible = 0;
 344         pvscsi_device_t *devnode;
 345         struct scsi_inquiry inq;
 346 
 347         ASSERT(DEVI_BUSY_OWNED(pdip));
 348 
 349         /* Inquiry target */
 350         inqrc = pvscsi_inquiry_target(pvs, target, &inq);
 351 
 352         /* Find devnode */
 353         for (devnode = list_head(&pvs->devnodes); devnode != NULL;
 354             devnode = list_next(&pvs->devnodes, devnode)) {
 355                 if (devnode->target == target)
 356                         break;
 357         }
 358 
 359         if (devnode != NULL) {
 360                 if (inqrc != 0) {
 361                         (void) ndi_devi_offline(devnode->pdip,
 362                             NDI_DEVFS_CLEAN | NDI_DEVI_REMOVE);












 363                         list_remove(&pvs->devnodes, devnode);
 364                         kmem_free(devnode, sizeof (*devnode));
 365                 } else if (childp != NULL) {
 366                         /* Target exists */
 367                         *childp = devnode->pdip;
 368                 }
 369                 return (NDI_SUCCESS);
 370         } else if (inqrc != 0) {
 371                 /* Target doesn't exist */
 372                 return (NDI_FAILURE);
 373         }
 374 
 375         scsi_hba_nodename_compatible_get(&inq, NULL, inq.inq_dtype, NULL,
 376             &nodename, &compatible, &ncompatible);
 377         if (nodename == NULL)
 378                 goto free_nodename;
 379 
 380         if (ndi_devi_alloc(pdip, nodename, DEVI_SID_NODEID,
 381             &dip) != NDI_SUCCESS) {
 382                 dev_err(pvs->dip, CE_WARN, "!failed to alloc device instance");