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
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
342 dev_info_t *dip;
343 int inqrc;
344 int ncompatible = 0;
345 pvscsi_device_t *devnode;
346 struct scsi_inquiry inq;
347
348 ASSERT(DEVI_BUSY_OWNED(pdip));
349
350 /* Inquiry target */
351 inqrc = pvscsi_inquiry_target(pvs, target, &inq);
352
353 /* Find devnode */
354 for (devnode = list_head(&pvs->devnodes); devnode != NULL;
355 devnode = list_next(&pvs->devnodes, devnode)) {
356 if (devnode->target == target)
357 break;
358 }
359
360 if (devnode != NULL) {
361 if (inqrc != 0) {
362 (void) ndi_devi_offline(devnode->pdip,
363 NDI_DEVFS_CLEAN | NDI_DEVI_REMOVE);
364 list_remove(&pvs->devnodes, devnode);
365 kmem_free(devnode, sizeof (*devnode));
366 } else if (childp != NULL) {
367 /* Target exists */
368 *childp = devnode->pdip;
369 }
370 return (NDI_SUCCESS);
371 } else if (inqrc != 0) {
372 /* Target doesn't exist */
373 return (NDI_FAILURE);
374 }
375
376 scsi_hba_nodename_compatible_get(&inq, NULL, inq.inq_dtype, NULL,
377 &nodename, &compatible, &ncompatible);
378 if (nodename == NULL)
379 goto free_nodename;
380
381 if (ndi_devi_alloc(pdip, nodename, DEVI_SID_NODEID,
382 &dip) != NDI_SUCCESS) {
383 dev_err(pvs->dip, CE_WARN, "!failed to alloc device instance");
|