summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorJoshua M. Clulow <jmc@joyent.com>2016-03-05 00:51:17 +0000
committerJoshua M. Clulow <jmc@joyent.com>2016-07-06 16:25:30 +0000
commit2c69012cbf226e220799b4aa07d7fab389678f29 (patch)
treeefb25fdb1a4421a50edf504768a4d398c467425a
parentad2c07638e56f3d636b2e94258bbfcec387c34b8 (diff)
downloadillumos-joyent-2c69012cbf226e220799b4aa07d7fab389678f29.tar.gz
XXX passing around kmflags, fixed diskinfo hang, now working again
-rw-r--r--usr/src/uts/common/io/cpqary3/cpqary3.c2
-rw-r--r--usr/src/uts/common/io/cpqary3/cpqary3.h18
-rw-r--r--usr/src/uts/common/io/cpqary3/cpqary3_ciss.h2
-rw-r--r--usr/src/uts/common/io/cpqary3/cpqary3_commands.c18
-rw-r--r--usr/src/uts/common/io/cpqary3/cpqary3_hba.c64
-rw-r--r--usr/src/uts/common/io/cpqary3/cpqary3_logvol.c2
-rw-r--r--usr/src/uts/common/io/cpqary3/cpqary3_mem.c12
-rw-r--r--usr/src/uts/common/io/cpqary3/cpqary3_scsi.c4
-rw-r--r--usr/src/uts/common/io/cpqary3/cpqary3_transport.c23
-rw-r--r--usr/src/uts/common/io/cpqary3/cpqary3_util.c8
10 files changed, 102 insertions, 51 deletions
diff --git a/usr/src/uts/common/io/cpqary3/cpqary3.c b/usr/src/uts/common/io/cpqary3/cpqary3.c
index f37d02b371..c97361fab1 100644
--- a/usr/src/uts/common/io/cpqary3/cpqary3.c
+++ b/usr/src/uts/common/io/cpqary3/cpqary3.c
@@ -250,6 +250,8 @@ cpqary3_attach(dev_info_t *dip, ddi_attach_cmd_t attach_cmd)
offsetof(cpqary3_command_t, cpcm_link_finish));
list_create(&cpq->cpq_volumes, sizeof (cpqary3_volume_t),
offsetof(cpqary3_volume_t, cplv_link));
+ list_create(&cpq->cpq_targets, sizeof (cpqary3_target_t),
+ offsetof(cpqary3_target_t, cptg_link_ctlr));
avl_create(&cpq->cpq_inflight, cpqary3_command_comparator,
sizeof (cpqary3_command_t), offsetof(cpqary3_command_t,
cpcm_node));
diff --git a/usr/src/uts/common/io/cpqary3/cpqary3.h b/usr/src/uts/common/io/cpqary3/cpqary3.h
index 3b3ad208a9..421709a60f 100644
--- a/usr/src/uts/common/io/cpqary3/cpqary3.h
+++ b/usr/src/uts/common/io/cpqary3/cpqary3.h
@@ -305,6 +305,7 @@ struct cpqary3 {
kcondvar_t cpq_cv_finishq;
list_t cpq_volumes;
+ list_t cpq_targets;
/*
* Controller Heartbeat Tracking
@@ -373,12 +374,19 @@ typedef struct cpqary3_volume {
*/
typedef struct cpqary3_target {
struct scsi_device *cptg_scsi_dev;
+ boolean_t cptg_controller_target;
/*
* Linkage back to the Logical Volume that this target represents:
*/
cpqary3_volume_t *cptg_volume;
list_node_t cptg_link_volume;
+
+ /*
+ * Linkage back to the controller:
+ */
+ cpqary3_t *cptg_ctlr;
+ list_node_t cptg_link_ctlr;
} cpqary3_target_t;
@@ -521,13 +529,13 @@ void cpqary3_poll_for(cpqary3_t *, cpqary3_command_t *);
* Memory management.
*/
caddr_t cpqary3_alloc_phyctgs_mem(cpqary3_t *, size_t, uint32_t *,
- cpqary3_phyctg_t *);
+ cpqary3_phyctg_t *, int);
void cpqary3_free_phyctgs_mem(cpqary3_phyctg_t *, uint8_t);
/*
* Synchronous command routines.
*/
-cpqary3_command_t *cpqary3_synccmd_alloc(cpqary3_t *, size_t);
+cpqary3_command_t *cpqary3_synccmd_alloc(cpqary3_t *, size_t, int);
void cpqary3_synccmd_free(cpqary3_t *, cpqary3_command_t *);
int cpqary3_synccmd_send(cpqary3_t *, cpqary3_command_t *, clock_t, int);
@@ -578,8 +586,10 @@ void cpqary3_process_finishq(cpqary3_t *);
/*
* Command object management.
*/
-cpqary3_command_t *cpqary3_command_alloc(cpqary3_t *, cpqary3_command_type_t);
-cpqary3_command_internal_t *cpqary3_command_internal_alloc(cpqary3_t *, size_t);
+cpqary3_command_t *cpqary3_command_alloc(cpqary3_t *, cpqary3_command_type_t,
+ int);
+cpqary3_command_internal_t *cpqary3_command_internal_alloc(cpqary3_t *,
+ size_t, int);
void cpqary3_command_free(cpqary3_command_t *);
cpqary3_command_t *cpqary3_lookup_inflight(cpqary3_t *, uint32_t);
void cpqary3_command_reuse(cpqary3_command_t *);
diff --git a/usr/src/uts/common/io/cpqary3/cpqary3_ciss.h b/usr/src/uts/common/io/cpqary3/cpqary3_ciss.h
index 855a0a03da..e33680df9b 100644
--- a/usr/src/uts/common/io/cpqary3/cpqary3_ciss.h
+++ b/usr/src/uts/common/io/cpqary3/cpqary3_ciss.h
@@ -25,7 +25,7 @@ extern "C" {
#define CISS_INIT_TIME 90 /* Driver Defined Value */
/* Duration to Wait for the */
/* controller initialization */
-#define CISS_SENSEINFOBYTES 256 /* Note that this value may vary */
+#define CISS_SENSEINFOBYTES 384 /* Note that this value may vary */
/* between host implementations */
#define CISS_MAXSGENTRIES 64
#define CISS_MAXREPLYQS 256
diff --git a/usr/src/uts/common/io/cpqary3/cpqary3_commands.c b/usr/src/uts/common/io/cpqary3/cpqary3_commands.c
index bf8376fa04..23658c652e 100644
--- a/usr/src/uts/common/io/cpqary3/cpqary3_commands.c
+++ b/usr/src/uts/common/io/cpqary3/cpqary3_commands.c
@@ -38,11 +38,14 @@ cpqary3_set_new_tag(cpqary3_t *cpq, cpqary3_command_t *cpcm)
}
cpqary3_command_t *
-cpqary3_command_alloc(cpqary3_t *cpq, cpqary3_command_type_t type)
+cpqary3_command_alloc(cpqary3_t *cpq, cpqary3_command_type_t type,
+ int kmflags)
{
cpqary3_command_t *cpcm;
- if ((cpcm = kmem_zalloc(sizeof (*cpcm), KM_NOSLEEP)) == NULL) {
+ VERIFY(kmflags == KM_SLEEP || kmflags == KM_NOSLEEP);
+
+ if ((cpcm = kmem_zalloc(sizeof (*cpcm), kmflags)) == NULL) {
return (NULL);
}
@@ -84,7 +87,8 @@ cpqary3_command_alloc(cpqary3_t *cpq, cpqary3_command_type_t type)
*/
if ((cpcm->cpcm_va_cmd = (void *)cpqary3_alloc_phyctgs_mem(cpq,
- contig_size, &cpcm->cpcm_pa_cmd, &cpcm->cpcm_phyctg)) == NULL) {
+ contig_size, &cpcm->cpcm_pa_cmd, &cpcm->cpcm_phyctg,
+ kmflags)) == NULL) {
kmem_free(cpcm, sizeof (*cpcm));
return (NULL);
}
@@ -117,16 +121,18 @@ cpqary3_command_alloc(cpqary3_t *cpq, cpqary3_command_type_t type)
}
cpqary3_command_internal_t *
-cpqary3_command_internal_alloc(cpqary3_t *cpq, size_t len)
+cpqary3_command_internal_alloc(cpqary3_t *cpq, size_t len, int kmflags)
{
cpqary3_command_internal_t *cpcmi;
- if ((cpcmi = kmem_zalloc(sizeof (*cpcmi), KM_NOSLEEP)) == NULL) {
+ VERIFY(kmflags == KM_SLEEP || kmflags == KM_NOSLEEP);
+
+ if ((cpcmi = kmem_zalloc(sizeof (*cpcmi), kmflags)) == NULL) {
return (NULL);
}
if ((cpcmi->cpcmi_va = (void *)cpqary3_alloc_phyctgs_mem(cpq, len,
- &cpcmi->cpcmi_pa, &cpcmi->cpcmi_phyctg)) == NULL) {
+ &cpcmi->cpcmi_pa, &cpcmi->cpcmi_phyctg, kmflags)) == NULL) {
kmem_free(cpcmi, sizeof (*cpcmi));
return (NULL);
}
diff --git a/usr/src/uts/common/io/cpqary3/cpqary3_hba.c b/usr/src/uts/common/io/cpqary3/cpqary3_hba.c
index 39c5526eee..e3d4c81aaf 100644
--- a/usr/src/uts/common/io/cpqary3/cpqary3_hba.c
+++ b/usr/src/uts/common/io/cpqary3/cpqary3_hba.c
@@ -38,6 +38,16 @@ cpqary3_tran_tgt_init(dev_info_t *hba_dip, dev_info_t *tgt_dip,
}
/*
+ * XXX Expose the controller as a target... SIGH
+ */
+ if (sd->sd_address.a_target == 7 && sd->sd_address.a_lun == 0) {
+ cptg->cptg_controller_target = B_TRUE;
+ mutex_enter(&cpq->cpq_mutex);
+ list_insert_tail(&cpq->cpq_targets, cptg);
+ goto skip;
+ }
+
+ /*
* Look for a logical volume for the SCSI address of this target.
*/
mutex_enter(&cpq->cpq_mutex);
@@ -48,12 +58,13 @@ cpqary3_tran_tgt_init(dev_info_t *hba_dip, dev_info_t *tgt_dip,
return (DDI_FAILURE);
}
- cptg->cptg_scsi_dev = sd;
- VERIFY(sd->sd_dev == tgt_dip); /* XXX */
-
cptg->cptg_volume = cplv;
list_insert_tail(&cplv->cplv_targets, cptg);
+skip:
+ cptg->cptg_scsi_dev = sd;
+ VERIFY(sd->sd_dev == tgt_dip); /* XXX */
+
/*
* We passed SCSI_HBA_TRAN_CLONE to scsi_hba_attach(9F), so
* we can stash our target-specific data structure on the
@@ -91,7 +102,14 @@ cpqary3_tran_tgt_free(dev_info_t *hba_dip, dev_info_t *tgt_dip,
*/
mutex_enter(&cpq->cpq_mutex);
- list_remove(&cplv->cplv_targets, cptg);
+ if (cptg->cptg_controller_target) {
+ /*
+ * XXX
+ */
+ list_remove(&cpq->cpq_targets, cptg);
+ } else {
+ list_remove(&cplv->cplv_targets, cptg);
+ }
mutex_exit(&cpq->cpq_mutex);
kmem_free(cptg, sizeof (*cptg));
@@ -118,6 +136,7 @@ cpqary3_tran_setup_pkt(struct scsi_pkt *pkt, int (*callback)(caddr_t),
cpqary3_command_scsa_t *cpcms = (cpqary3_command_scsa_t *)
pkt->pkt_ha_private;
cpqary3_command_t *cpcm;
+ int kmflags = callback == SLEEP_FUNC ? KM_SLEEP : KM_NOSLEEP;
/*
* The SCSI framework has allocated a packet, and our private
@@ -137,6 +156,8 @@ cpqary3_tran_setup_pkt(struct scsi_pkt *pkt, int (*callback)(caddr_t),
* The CDB member of the Request Block of a controller
* command is fixed at 16 bytes.
*/
+ dev_err(cpq->dip, CE_WARN, "oversize CDB: had %u, needed %u",
+ 16, pkt->pkt_cdblen);
return (-1);
}
if (pkt->pkt_scblen > CISS_SENSEINFOBYTES) {
@@ -144,15 +165,16 @@ cpqary3_tran_setup_pkt(struct scsi_pkt *pkt, int (*callback)(caddr_t),
* The SCB is the "SenseInfo[]" member of the "ErrorInfo_t".
* This is statically allocated; make sure it is big enough.
*/
+ dev_err(cpq->dip, CE_WARN, "oversize SENSE BYTES: had %u, "
+ "needed %u", CISS_SENSEINFOBYTES, pkt->pkt_scblen);
return (-1);
}
/*
* Allocate our command block:
- * XXX should be passing through the SLEEP_FUCN/NULL_FUNC here
- * as kmflags...
*/
- if ((cpcm = cpqary3_command_alloc(cpq, CPQARY3_CMDTYPE_OS)) == NULL) {
+ if ((cpcm = cpqary3_command_alloc(cpq, CPQARY3_CMDTYPE_OS, kmflags)) ==
+ NULL) {
return (-1);
}
cpcm->cpcm_scsa = cpcms;
@@ -283,11 +305,24 @@ cpqary3_tran_start(struct scsi_address *sa, struct scsi_pkt *pkt)
pkt->pkt_cookies[i].dmac_size;
}
- /*
- * Copy logical volume address from the target object:
- */
- cpcm->cpcm_va_cmd->Header.LUN.LogDev = cpcm->cpcm_target->
- cptg_volume->cplv_addr;
+ if (cpcm->cpcm_target->cptg_controller_target) {
+ /*
+ * XXX use cpqary3_write_lun_addr_phys()
+ */
+ LUNAddr_t *lun = &cpcm->cpcm_va_cmd->Header.LUN;
+
+ lun->PhysDev.Mode = MASK_PERIPHERIAL_DEV_ADDR;
+ lun->PhysDev.TargetId = 0;
+ lun->PhysDev.Bus = 0;
+
+ bzero(&lun->PhysDev.Target, sizeof (lun->PhysDev.Target));
+ } else {
+ /*
+ * Copy logical volume address from the target object:
+ */
+ cpcm->cpcm_va_cmd->Header.LUN.LogDev = cpcm->cpcm_target->
+ cptg_volume->cplv_addr;
+ }
/*
* Initialise the command block.
@@ -362,11 +397,6 @@ cpqary3_tran_start(struct scsi_address *sa, struct scsi_pkt *pkt)
return (r == EAGAIN ? TRAN_BUSY : TRAN_FATAL_ERROR);
}
- dev_err(cpq->dip, CE_WARN, "SCSI OUT targ %3x opcode %x len %u",
- cpcm->cpcm_target->cptg_scsi_dev->sd_address.a_target,
- (unsigned)cpcm->cpcm_va_cmd->Request.CDB[0],
- pkt->pkt_cdblen);
-
/*
* Update the SCSI packet to reflect submission of the command.
*/
diff --git a/usr/src/uts/common/io/cpqary3/cpqary3_logvol.c b/usr/src/uts/common/io/cpqary3/cpqary3_logvol.c
index 6c008d6a10..b1d121e1f0 100644
--- a/usr/src/uts/common/io/cpqary3/cpqary3_logvol.c
+++ b/usr/src/uts/common/io/cpqary3/cpqary3_logvol.c
@@ -191,7 +191,7 @@ cpqary3_discover_logical_volumes(cpqary3_t *cpq, int timeout)
* for the returned list of Logical Volumes.
*/
if ((cpcm = cpqary3_synccmd_alloc(cpq,
- sizeof (cpqary3_report_logical_lun_t))) == NULL) {
+ sizeof (cpqary3_report_logical_lun_t), KM_NOSLEEP)) == NULL) {
return (ENOMEM);
}
cprll = cpcm->cpcm_internal->cpcmi_va;
diff --git a/usr/src/uts/common/io/cpqary3/cpqary3_mem.c b/usr/src/uts/common/io/cpqary3/cpqary3_mem.c
index d50ee0a386..d176310f0c 100644
--- a/usr/src/uts/common/io/cpqary3/cpqary3_mem.c
+++ b/usr/src/uts/common/io/cpqary3/cpqary3_mem.c
@@ -41,13 +41,17 @@ extern ddi_device_acc_attr_t cpqary3_dev_attributes;
caddr_t
cpqary3_alloc_phyctgs_mem(cpqary3_t *ctlr, size_t size_mempool,
- uint32_t *phyaddr, cpqary3_phyctg_t *phyctgp)
+ uint32_t *phyaddr, cpqary3_phyctg_t *phyctgp, int kmflags)
{
size_t real_len;
int32_t retvalue;
caddr_t mempool = NULL;
uint8_t cleanstat = 0;
uint32_t cookiecnt;
+ int (*dma_wait)(caddr_t) = (kmflags == KM_SLEEP) ? DDI_DMA_SLEEP :
+ DDI_DMA_DONTWAIT;
+
+ VERIFY(kmflags == KM_SLEEP || kmflags == KM_NOSLEEP);
/*
* Allocation of Physical Contigous Memory follws:
@@ -62,7 +66,7 @@ cpqary3_alloc_phyctgs_mem(cpqary3_t *ctlr, size_t size_mempool,
if (DDI_SUCCESS !=
(retvalue = ddi_dma_alloc_handle((dev_info_t *)ctlr->dip,
- &cpqary3_ctlr_dma_attr, DDI_DMA_DONTWAIT, 0,
+ &cpqary3_ctlr_dma_attr, dma_wait, 0,
&phyctgp->cpqary3_dmahandle))) {
switch (retvalue) {
case DDI_DMA_NORESOURCES:
@@ -86,7 +90,7 @@ cpqary3_alloc_phyctgs_mem(cpqary3_t *ctlr, size_t size_mempool,
retvalue = ddi_dma_mem_alloc(phyctgp->cpqary3_dmahandle,
size_mempool, &cpqary3_dev_attributes,
- DDI_DMA_CONSISTENT, DDI_DMA_DONTWAIT, 0, &mempool, &real_len,
+ DDI_DMA_CONSISTENT, dma_wait, 0, &mempool, &real_len,
&phyctgp->cpqary3_acchandle);
if (DDI_SUCCESS != retvalue) {
@@ -102,7 +106,7 @@ cpqary3_alloc_phyctgs_mem(cpqary3_t *ctlr, size_t size_mempool,
retvalue = ddi_dma_addr_bind_handle(phyctgp->cpqary3_dmahandle,
NULL, mempool, real_len,
- DDI_DMA_CONSISTENT | DDI_DMA_RDWR, DDI_DMA_DONTWAIT, 0,
+ DDI_DMA_CONSISTENT | DDI_DMA_RDWR, dma_wait, 0,
&phyctgp->cpqary3_dmacookie, &cookiecnt);
if (DDI_DMA_MAPPED == retvalue) {
diff --git a/usr/src/uts/common/io/cpqary3/cpqary3_scsi.c b/usr/src/uts/common/io/cpqary3/cpqary3_scsi.c
index 933ec085da..7b967c9423 100644
--- a/usr/src/uts/common/io/cpqary3/cpqary3_scsi.c
+++ b/usr/src/uts/common/io/cpqary3/cpqary3_scsi.c
@@ -80,7 +80,7 @@ cpqary3_send_abortcmd(cpqary3_t *cpq, cpqary3_target_t *tgtp,
* Update the Command List accordingly
* Submit the command and wait for a signal
*/
- if ((cpcm = cpqary3_synccmd_alloc(cpq, 0)) == NULL) {
+ if ((cpcm = cpqary3_synccmd_alloc(cpq, 0, KM_NOSLEEP)) == NULL) {
return (ENOMEM);
}
@@ -150,7 +150,7 @@ cpqary3_flush_cache(cpqary3_t *cpqary3p)
/* grab a command and allocate a dma buffer */
if ((cpcm = cpqary3_synccmd_alloc(cpqary3p,
- sizeof (flushcache_buf_t))) == NULL) {
+ sizeof (flushcache_buf_t), KM_NOSLEEP)) == NULL) {
dev_err(cpqary3p->dip, CE_WARN, "flush cache failed: memory");
return (ENOMEM);
}
diff --git a/usr/src/uts/common/io/cpqary3/cpqary3_transport.c b/usr/src/uts/common/io/cpqary3/cpqary3_transport.c
index 39a4a41dc5..4739aaf33d 100644
--- a/usr/src/uts/common/io/cpqary3/cpqary3_transport.c
+++ b/usr/src/uts/common/io/cpqary3/cpqary3_transport.c
@@ -85,8 +85,15 @@ cpqary3_getcap(struct scsi_address *sa, char *capstr, int tgtonly)
DTRACE_PROBE1(getcap_index, int, index);
switch (index) {
+ case SCSI_CAP_CDB_LEN:
+ return (16);
case SCSI_CAP_DMA_MAX:
return ((int)cpqary3_dma_attr.dma_attr_maxxfer);
+ case SCSI_CAP_DISCONNECT:
+ case SCSI_CAP_SYNCHRONOUS:
+ case SCSI_CAP_WIDE_XFER:
+ case SCSI_CAP_ARQ:
+ return (1);
#if 0
case SCSI_CAP_DISCONNECT:
return (tgtp->ctlr_flags & CPQARY3_CAP_DISCON_ENABLED);
@@ -96,9 +103,9 @@ cpqary3_getcap(struct scsi_address *sa, char *capstr, int tgtonly)
return (tgtp->ctlr_flags & CPQARY3_CAP_WIDE_XFER_ENABLED);
case SCSI_CAP_ARQ:
return ((tgtp->ctlr_flags & CPQARY3_CAP_ARQ_ENABLED) ? 1 : 0);
- case SCSI_CAP_INITIATOR_ID:
- return (CTLR_SCSI_ID);
#endif
+ case SCSI_CAP_INITIATOR_ID:
+ return (7); /* XXX */
case SCSI_CAP_UNTAGGED_QING:
return (1);
case SCSI_CAP_TAGGED_QING:
@@ -155,28 +162,20 @@ cpqary3_setcap(struct scsi_address *sa, char *capstr, int value, int tgtonly)
DTRACE_PROBE1(setcap_index, int, index);
switch (index) {
+ case SCSI_CAP_CDB_LEN:
case SCSI_CAP_DMA_MAX:
- return (CAP_CHG_NOT_ALLOWED);
case SCSI_CAP_DISCONNECT:
- return (CAP_CHG_NOT_ALLOWED);
case SCSI_CAP_SYNCHRONOUS:
- return (CAP_CHG_NOT_ALLOWED);
case SCSI_CAP_WIDE_XFER:
return (CAP_CHG_NOT_ALLOWED);
case SCSI_CAP_ARQ:
- return (1);
- case SCSI_CAP_INITIATOR_ID:
- return (CAP_CHG_NOT_ALLOWED);
case SCSI_CAP_UNTAGGED_QING:
- return (1);
case SCSI_CAP_TAGGED_QING:
return (1);
+ case SCSI_CAP_INITIATOR_ID:
case SCSI_CAP_SECTOR_SIZE:
- return (CAP_CHG_NOT_ALLOWED);
case SCSI_CAP_TOTAL_SECTORS:
- return (CAP_CHG_NOT_ALLOWED);
case SCSI_CAP_GEOMETRY:
- return (CAP_CHG_NOT_ALLOWED);
case SCSI_CAP_RESET_NOTIFICATION:
return (CAP_CHG_NOT_ALLOWED);
default:
diff --git a/usr/src/uts/common/io/cpqary3/cpqary3_util.c b/usr/src/uts/common/io/cpqary3/cpqary3_util.c
index 351735c2da..d2dd4da52a 100644
--- a/usr/src/uts/common/io/cpqary3/cpqary3_util.c
+++ b/usr/src/uts/common/io/cpqary3/cpqary3_util.c
@@ -135,12 +135,12 @@ cpqary3_target_geometry(struct scsi_address *sa)
* Return Values: memp
*/
cpqary3_command_t *
-cpqary3_synccmd_alloc(cpqary3_t *cpq, size_t bufsz)
+cpqary3_synccmd_alloc(cpqary3_t *cpq, size_t bufsz, int kmflags)
{
cpqary3_command_t *cpcm;
- if ((cpcm = cpqary3_command_alloc(cpq, CPQARY3_CMDTYPE_SYNCCMD)) ==
- NULL) {
+ if ((cpcm = cpqary3_command_alloc(cpq, CPQARY3_CMDTYPE_SYNCCMD,
+ kmflags)) == NULL) {
return (NULL);
}
@@ -149,7 +149,7 @@ cpqary3_synccmd_alloc(cpqary3_t *cpq, size_t bufsz)
}
if ((cpcm->cpcm_internal = cpqary3_command_internal_alloc(cpq,
- bufsz)) == NULL) {
+ bufsz, kmflags)) == NULL) {
cpqary3_command_free(cpcm);
return (NULL);
}