summaryrefslogtreecommitdiff
path: root/usr/src/uts/intel/io/dktp/dcdev
diff options
context:
space:
mode:
Diffstat (limited to 'usr/src/uts/intel/io/dktp/dcdev')
-rw-r--r--usr/src/uts/intel/io/dktp/dcdev/dadk.c162
1 files changed, 115 insertions, 47 deletions
diff --git a/usr/src/uts/intel/io/dktp/dcdev/dadk.c b/usr/src/uts/intel/io/dktp/dcdev/dadk.c
index eaf5c28db0..5b99559cc3 100644
--- a/usr/src/uts/intel/io/dktp/dcdev/dadk.c
+++ b/usr/src/uts/intel/io/dktp/dcdev/dadk.c
@@ -73,6 +73,7 @@ static struct cmpkt *dadk_pktprep(struct dadk *dadkp, struct cmpkt *in_pktp,
static int dadk_pkt(opaque_t com_data, struct buf *bp, int (*func)(caddr_t),
caddr_t arg);
static void dadk_transport(opaque_t com_data, struct buf *bp);
+static int dadk_ctl_ioctl(struct dadk *, uint32_t, uintptr_t, int);
struct tgcom_objops dadk_com_ops = {
nodev,
@@ -336,6 +337,8 @@ dadk_init(opaque_t objp, opaque_t devp, opaque_t flcobjp, opaque_t queobjp,
BBH_INIT(bbhobjp);
dadkp->dad_flcobjp = flcobjp;
+ mutex_init(&dadkp->dad_cmd_mutex, NULL, MUTEX_DRIVER, NULL);
+ dadkp->dad_cmd_count = 0;
return (FLC_INIT(flcobjp, &(dadkp->dad_com), queobjp, lkarg));
}
@@ -364,6 +367,7 @@ dadk_cleanup(struct tgdk_obj *dkobjp)
FLC_FREE(dadkp->dad_flcobjp);
dadkp->dad_flcobjp = NULL;
}
+ mutex_destroy(&dadkp->dad_cmd_mutex);
}
/* ARGSUSED */
@@ -376,7 +380,7 @@ dadk_probe(opaque_t objp, int kmsflg)
devp = dadkp->dad_sd;
if (!devp->sd_inq || (devp->sd_inq->inq_dtype == DTYPE_NOTPRESENT) ||
- (devp->sd_inq->inq_dtype == DTYPE_UNKNOWN)) {
+ (devp->sd_inq->inq_dtype == DTYPE_UNKNOWN)) {
return (DDI_PROBE_FAILURE);
}
@@ -454,21 +458,23 @@ dadk_open(opaque_t objp, int flag)
return (DDI_SUCCESS);
}
} else {
- mutex_enter(&dadkp->dad_mutex);
- dadkp->dad_iostate = DKIO_NONE;
- cv_broadcast(&dadkp->dad_state_cv);
- mutex_exit(&dadkp->dad_mutex);
-
- if (dadk_rmb_ioctl(dadkp, DCMD_START_MOTOR, 0, 0, DADK_SILENT) ||
- dadk_rmb_ioctl(dadkp, DCMD_LOCK, 0, 0, DADK_SILENT) ||
- dadk_rmb_ioctl(dadkp, DCMD_UPDATE_GEOM, 0, 0, DADK_SILENT)) {
- return (DDI_FAILURE);
- }
-
- mutex_enter(&dadkp->dad_mutex);
- dadkp->dad_iostate = DKIO_INSERTED;
- cv_broadcast(&dadkp->dad_state_cv);
- mutex_exit(&dadkp->dad_mutex);
+ mutex_enter(&dadkp->dad_mutex);
+ dadkp->dad_iostate = DKIO_NONE;
+ cv_broadcast(&dadkp->dad_state_cv);
+ mutex_exit(&dadkp->dad_mutex);
+
+ if (dadk_rmb_ioctl(dadkp, DCMD_START_MOTOR, 0, 0,
+ DADK_SILENT) ||
+ dadk_rmb_ioctl(dadkp, DCMD_LOCK, 0, 0, DADK_SILENT) ||
+ dadk_rmb_ioctl(dadkp, DCMD_UPDATE_GEOM, 0, 0,
+ DADK_SILENT)) {
+ return (DDI_FAILURE);
+ }
+
+ mutex_enter(&dadkp->dad_mutex);
+ dadkp->dad_iostate = DKIO_INSERTED;
+ cv_broadcast(&dadkp->dad_state_cv);
+ mutex_exit(&dadkp->dad_mutex);
}
/*
@@ -482,20 +488,20 @@ dadk_open(opaque_t objp, int flag)
* is added to the driver to change WCE, dad_wce
* must be updated appropriately.
*/
- error = CTL_IOCTL(dadkp->dad_ctlobjp, DIOCTL_GETWCE,
+ error = dadk_ctl_ioctl(dadkp, DIOCTL_GETWCE,
(uintptr_t)&wce, FKIOCTL | FNATIVE);
mutex_enter(&dadkp->dad_mutex);
dadkp->dad_wce = (error != 0) || (wce != 0);
mutex_exit(&dadkp->dad_mutex);
/* logical disk geometry */
- CTL_IOCTL(dadkp->dad_ctlobjp, DIOCTL_GETGEOM,
+ (void) dadk_ctl_ioctl(dadkp, DIOCTL_GETGEOM,
(uintptr_t)&dadkp->dad_logg, FKIOCTL | FNATIVE);
if (dadkp->dad_logg.g_cap == 0)
return (DDI_FAILURE);
/* get physical disk geometry */
- CTL_IOCTL(dadkp->dad_ctlobjp, DIOCTL_GETPHYGEOM,
+ (void) dadk_ctl_ioctl(dadkp, DIOCTL_GETPHYGEOM,
(uintptr_t)&dadkp->dad_phyg, FKIOCTL | FNATIVE);
if (dadkp->dad_phyg.g_cap == 0)
return (DDI_FAILURE);
@@ -507,7 +513,7 @@ dadk_open(opaque_t objp, int flag)
/* start profiling */
FLC_START_KSTAT(dadkp->dad_flcobjp, "disk",
- ddi_get_instance(CTL_DIP_DEV(dadkp->dad_ctlobjp)));
+ ddi_get_instance(CTL_DIP_DEV(dadkp->dad_ctlobjp)));
return (DDI_SUCCESS);
}
@@ -534,7 +540,8 @@ dadk_setcap(struct dadk *dadkp)
/* set sec,block shift factor - (512->0, 1024->1, 2048->2, etc.) */
totsize >>= SCTRSHFT;
- for (i = 0; totsize != 1; i++, totsize >>= 1);
+ for (i = 0; totsize != 1; i++, totsize >>= 1)
+ ;
dadkp->dad_blkshf = i;
dadkp->dad_secshf = i + SCTRSHFT;
}
@@ -594,14 +601,14 @@ dadk_create_errstats(struct dadk *dadkp, int instance)
dep->dadk_model.value.c[0] = 0;
dadk_ioc_string.is_buf = &dep->dadk_model.value.c[0];
dadk_ioc_string.is_size = sizeof (dep->dadk_model.value.c);
- CTL_IOCTL(dadkp->dad_ctlobjp, DIOCTL_GETMODEL,
+ (void) dadk_ctl_ioctl(dadkp, DIOCTL_GETMODEL,
(uintptr_t)&dadk_ioc_string, FKIOCTL | FNATIVE);
/* get serial */
dep->dadk_serial.value.c[0] = 0;
dadk_ioc_string.is_buf = &dep->dadk_serial.value.c[0];
dadk_ioc_string.is_size = sizeof (dep->dadk_serial.value.c);
- CTL_IOCTL(dadkp->dad_ctlobjp, DIOCTL_GETSERIAL,
+ (void) dadk_ctl_ioctl(dadkp, DIOCTL_GETSERIAL,
(uintptr_t)&dadk_ioc_string, FKIOCTL | FNATIVE);
/* Get revision */
@@ -659,6 +666,9 @@ dadk_strategy(opaque_t objp, struct buf *bp)
}
SET_BP_SEC(bp, (LBLK2SEC(GET_BP_SEC(bp), dadkp->dad_blkshf)));
+ mutex_enter(&dadkp->dad_cmd_mutex);
+ dadkp->dad_cmd_count++;
+ mutex_exit(&dadkp->dad_cmd_mutex);
FLC_ENQUE(dadkp->dad_flcobjp, bp);
return (DDI_SUCCESS);
@@ -715,7 +725,7 @@ dadk_ioctl(opaque_t objp, dev_t dev, int cmd, intptr_t arg, int flag,
switch (cmd) {
case DKIOCGETDEF:
- {
+ {
struct buf *bp;
int err, head;
unsigned char *secbuf;
@@ -752,6 +762,9 @@ dadk_ioctl(opaque_t objp, dev_t dev, int cmd, intptr_t arg, int flag,
bp->b_forw = (struct buf *)dadkp;
bp->b_back = (struct buf *)DCMD_GETDEF;
+ mutex_enter(&dadkp->dad_cmd_mutex);
+ dadkp->dad_cmd_count++;
+ mutex_exit(&dadkp->dad_cmd_mutex);
FLC_ENQUE(dadkp->dad_flcobjp, bp);
err = biowait(bp);
if (!err) {
@@ -762,9 +775,9 @@ dadk_ioctl(opaque_t objp, dev_t dev, int cmd, intptr_t arg, int flag,
kmem_free(secbuf, NBPSCTR);
freerbuf(bp);
return (err);
- }
+ }
case DIOCTL_RWCMD:
- {
+ {
struct dadkio_rwcmd *rwcmdp;
int status, rw;
@@ -794,8 +807,8 @@ dadk_ioctl(opaque_t objp, dev_t dev, int cmd, intptr_t arg, int flag,
return (status);
default:
return (EINVAL);
+ }
}
- }
case DKIOC_UPDATEFW:
/*
@@ -805,7 +818,7 @@ dadk_ioctl(opaque_t objp, dev_t dev, int cmd, intptr_t arg, int flag,
if (PRIV_POLICY(cred_p, PRIV_ALL, B_FALSE, EPERM, NULL) != 0)
return (EPERM);
else
- return (CTL_IOCTL(dadkp->dad_ctlobjp, cmd, arg, flag));
+ return (dadk_ctl_ioctl(dadkp, cmd, arg, flag));
case DKIOCFLUSHWRITECACHE:
{
@@ -884,6 +897,9 @@ dadk_ioctl(opaque_t objp, dev_t dev, int cmd, intptr_t arg, int flag,
CTL_IOSETUP(dadkp->dad_ctlobjp, pktp);
+ mutex_enter(&dadkp->dad_cmd_mutex);
+ dadkp->dad_cmd_count++;
+ mutex_exit(&dadkp->dad_cmd_mutex);
FLC_ENQUE(dadkp->dad_flcobjp, bp);
if (is_sync) {
@@ -894,16 +910,16 @@ dadk_ioctl(opaque_t objp, dev_t dev, int cmd, intptr_t arg, int flag,
}
default:
if (!dadkp->dad_rmb)
- return (CTL_IOCTL(dadkp->dad_ctlobjp, cmd, arg, flag));
+ return (dadk_ctl_ioctl(dadkp, cmd, arg, flag));
}
switch (cmd) {
case CDROMSTOP:
return (dadk_rmb_ioctl(dadkp, DCMD_STOP_MOTOR, 0,
- 0, DADK_SILENT));
+ 0, DADK_SILENT));
case CDROMSTART:
return (dadk_rmb_ioctl(dadkp, DCMD_START_MOTOR, 0,
- 0, DADK_SILENT));
+ 0, DADK_SILENT));
case DKIOCLOCK:
return (dadk_rmb_ioctl(dadkp, DCMD_LOCK, 0, 0, DADK_SILENT));
case DKIOCUNLOCK:
@@ -914,11 +930,11 @@ dadk_ioctl(opaque_t objp, dev_t dev, int cmd, intptr_t arg, int flag,
int ret;
if (ret = dadk_rmb_ioctl(dadkp, DCMD_UNLOCK, 0, 0,
- DADK_SILENT)) {
+ DADK_SILENT)) {
return (ret);
}
if (ret = dadk_rmb_ioctl(dadkp, DCMD_EJECT, 0, 0,
- DADK_SILENT)) {
+ DADK_SILENT)) {
return (ret);
}
mutex_enter(&dadkp->dad_mutex);
@@ -1036,7 +1052,7 @@ dadk_iob_alloc(opaque_t objp, daddr_t blkno, ssize_t xfer, int kmsflg)
iobp->b_psec = LBLK2SEC(blkno, dadkp->dad_blkshf);
iobp->b_pbyteoff = (blkno & ((1<<dadkp->dad_blkshf) - 1)) << SCTRSHFT;
iobp->b_pbytecnt = ((iobp->b_pbyteoff + xfer + dadkp->DAD_SECSIZ - 1)
- >> dadkp->dad_secshf) << dadkp->dad_secshf;
+ >> dadkp->dad_secshf) << dadkp->dad_secshf;
bp->b_un.b_addr = 0;
/*
@@ -1107,6 +1123,9 @@ dadk_iob_xfer(opaque_t objp, struct tgdk_iob *iobp, int rw)
bp->b_resid = 0;
/* call flow control */
+ mutex_enter(&dadkp->dad_cmd_mutex);
+ dadkp->dad_cmd_count++;
+ mutex_exit(&dadkp->dad_cmd_mutex);
FLC_ENQUE(dadkp->dad_flcobjp, bp);
err = biowait(bp);
@@ -1253,16 +1272,15 @@ dadk_ioretry(struct cmpkt *pktp, int action)
if (pktp->cp_retry++ < DADK_RETRY_COUNT) {
CTL_IOSETUP(dadkp->dad_ctlobjp, pktp);
if (CTL_TRANSPORT(dadkp->dad_ctlobjp, pktp) ==
- CTL_SEND_SUCCESS) {
+ CTL_SEND_SUCCESS) {
return (JUST_RETURN);
}
gda_log(dadkp->dad_sd->sd_dev, dadk_name,
- CE_WARN,
- "transport of command fails\n");
+ CE_WARN, "transport of command fails\n");
} else
gda_log(dadkp->dad_sd->sd_dev,
- dadk_name, CE_WARN,
- "exceeds maximum number of retries\n");
+ dadk_name, CE_WARN,
+ "exceeds maximum number of retries\n");
bioerror(pktp->cp_bp, ENXIO);
/*FALLTHROUGH*/
case COMMAND_DONE_ERROR:
@@ -1378,7 +1396,7 @@ dadk_chkerr(struct cmpkt *pktp)
if (pktp->cp_retry) {
err_blkno = pktp->cp_srtsec + ((pktp->cp_bytexfer -
- pktp->cp_resid) >> dadkp->dad_secshf);
+ pktp->cp_resid) >> dadkp->dad_secshf);
} else
err_blkno = -1;
@@ -1468,11 +1486,10 @@ dadk_recorderr(struct cmpkt *pktp, struct dadkio_rwcmd *rwcmdp)
rwcmdp->status.failed_blk = rwcmdp->blkaddr +
- ((pktp->cp_bytexfer -
- pktp->cp_resid) >> dadkp->dad_secshf);
+ ((pktp->cp_bytexfer - pktp->cp_resid) >> dadkp->dad_secshf);
rwcmdp->status.resid = pktp->cp_bp->b_resid +
- pktp->cp_byteleft - pktp->cp_bytexfer + pktp->cp_resid;
+ pktp->cp_byteleft - pktp->cp_bytexfer + pktp->cp_resid;
switch ((int)(* (char *)pktp->cp_scbp)) {
case DERR_AMNF:
case DERR_ABORT:
@@ -1504,14 +1521,22 @@ dadk_recorderr(struct cmpkt *pktp, struct dadkio_rwcmd *rwcmdp)
if (rwcmdp->flags & DADKIO_FLAG_SILENT)
return;
gda_errmsg(dadkp->dad_sd, pktp, dadk_name, dadk_errtab[scb].d_severity,
- rwcmdp->blkaddr, rwcmdp->status.failed_blk,
- dadk_cmds, dadk_sense);
+ rwcmdp->blkaddr, rwcmdp->status.failed_blk,
+ dadk_cmds, dadk_sense);
}
/*ARGSUSED*/
static void
dadk_polldone(struct buf *bp)
{
+ struct cmpkt *pktp;
+ struct dadk *dadkp;
+
+ pktp = GDA_BP_PKT(bp);
+ dadkp = PKT2DADK(pktp);
+ mutex_enter(&dadkp->dad_cmd_mutex);
+ dadkp->dad_cmd_count--;
+ mutex_exit(&dadkp->dad_cmd_mutex);
}
static void
@@ -1544,6 +1569,9 @@ dadk_iodone(struct buf *bp)
if (pktp->cp_private)
BBH_FREEHANDLE(dadkp->dad_bbhobjp, pktp->cp_private);
gda_free(dadkp->dad_ctlobjp, pktp, NULL);
+ mutex_enter(&dadkp->dad_cmd_mutex);
+ dadkp->dad_cmd_count--;
+ mutex_exit(&dadkp->dad_cmd_mutex);
biodone(bp);
}
@@ -1558,7 +1586,7 @@ dadk_check_media(opaque_t objp, int *state)
#ifdef DADK_DEBUG
if (dadk_debug & DSTATE)
PRF("dadk_check_media: user state %x disk state %x\n",
- *state, dadkp->dad_iostate);
+ *state, dadkp->dad_iostate);
#endif
/*
* If state already changed just return
@@ -1676,7 +1704,7 @@ dadk_rmb_ioctl(struct dadk *dadkp, int cmd, intptr_t arg, int flags, int silent)
bp->b_forw = (struct buf *)dadkp->dad_flcobjp;
pktp->cp_passthru = (opaque_t)(intptr_t)silent;
- err = CTL_IOCTL(dadkp->dad_ctlobjp, cmd, (uintptr_t)pktp, flags);
+ err = dadk_ctl_ioctl(dadkp, cmd, (uintptr_t)pktp, flags);
freerbuf(bp);
gda_free(dadkp->dad_ctlobjp, pktp, NULL);
return (err);
@@ -1698,6 +1726,9 @@ dadk_rmb_iodone(struct buf *bp)
/* Start next one */
FLC_DEQUE(dadkp->dad_flcobjp, bp);
+ mutex_enter(&dadkp->dad_cmd_mutex);
+ dadkp->dad_cmd_count--;
+ mutex_exit(&dadkp->dad_cmd_mutex);
biodone(bp);
}
@@ -1769,5 +1800,42 @@ dadk_dk(struct dadk *dadkp, struct dadkio_rwcmd *rwcmdp, struct buf *bp)
(void) dadk_ioprep(dadkp, pktp);
+ mutex_enter(&dadkp->dad_cmd_mutex);
+ dadkp->dad_cmd_count++;
+ mutex_exit(&dadkp->dad_cmd_mutex);
FLC_ENQUE(dadkp->dad_flcobjp, bp);
}
+
+/*
+ * There is no existing way to notify cmdk module
+ * when the command completed, so add this function
+ * to calculate how many on-going commands.
+ */
+int
+dadk_getcmds(opaque_t objp)
+{
+ struct dadk *dadkp = (struct dadk *)objp;
+ int count;
+
+ mutex_enter(&dadkp->dad_cmd_mutex);
+ count = dadkp->dad_cmd_count;
+ mutex_exit(&dadkp->dad_cmd_mutex);
+ return (count);
+}
+
+/*
+ * this function was used to calc the cmd for CTL_IOCTL
+ */
+static int
+dadk_ctl_ioctl(struct dadk *dadkp, uint32_t cmd, uintptr_t arg, int flag)
+{
+ int error;
+ mutex_enter(&dadkp->dad_cmd_mutex);
+ dadkp->dad_cmd_count++;
+ mutex_exit(&dadkp->dad_cmd_mutex);
+ error = CTL_IOCTL(dadkp->dad_ctlobjp, cmd, arg, flag);
+ mutex_enter(&dadkp->dad_cmd_mutex);
+ dadkp->dad_cmd_count--;
+ mutex_exit(&dadkp->dad_cmd_mutex);
+ return (error);
+}