summaryrefslogtreecommitdiff
path: root/usr/src/uts/intel/io/dktp/dcdev/dadk.c
diff options
context:
space:
mode:
authormarx <none@none>2006-08-18 17:35:55 -0700
committermarx <none@none>2006-08-18 17:35:55 -0700
commitc6f76c3487b0d7e374ba5897fabad436f221c46e (patch)
tree3fde29241d2e071f6ba1e2b1709ae1b75f862897 /usr/src/uts/intel/io/dktp/dcdev/dadk.c
parent9b684ba4556d68f777e2abc0dfe297235026c0b7 (diff)
downloadillumos-gate-c6f76c3487b0d7e374ba5897fabad436f221c46e.tar.gz
4200341 x86 ide driver doesn't create error kstats
Diffstat (limited to 'usr/src/uts/intel/io/dktp/dcdev/dadk.c')
-rw-r--r--usr/src/uts/intel/io/dktp/dcdev/dadk.c162
1 files changed, 156 insertions, 6 deletions
diff --git a/usr/src/uts/intel/io/dktp/dcdev/dadk.c b/usr/src/uts/intel/io/dktp/dcdev/dadk.c
index 16533cf8d1..efc9a075e3 100644
--- a/usr/src/uts/intel/io/dktp/dcdev/dadk.c
+++ b/usr/src/uts/intel/io/dktp/dcdev/dadk.c
@@ -56,6 +56,8 @@ static void dadk_pktcb(struct cmpkt *pktp);
static void dadk_iodone(struct buf *bp);
static void dadk_polldone(struct buf *bp);
static void dadk_setcap(struct dadk *dadkp);
+static int dadk_create_errstats(struct dadk *dadkp, int instance);
+static int dadk_destroy_errstats(struct dadk *dadkp);
static int dadk_chkerr(struct cmpkt *pktp);
static int dadk_ioprep(struct dadk *dadkp, struct cmpkt *pktp);
@@ -498,6 +500,9 @@ dadk_open(opaque_t objp, int flag)
dadk_setcap(dadkp);
+ (void) dadk_create_errstats(dadkp,
+ ddi_get_instance(CTL_DIP_DEV(dadkp->dad_ctlobjp)));
+
/* start profiling */
FLC_START_KSTAT(dadkp->dad_flcobjp, "disk",
ddi_get_instance(CTL_DIP_DEV(dadkp->dad_ctlobjp)));
@@ -533,6 +538,83 @@ dadk_setcap(struct dadk *dadkp)
}
+static int
+dadk_create_errstats(struct dadk *dadkp, int instance)
+{
+ struct dadk_errstats *dep;
+ char kstatname[KSTAT_STRLEN];
+ dadk_ioc_string_t dadk_ioc_string;
+
+ if (dadkp->dad_errstats)
+ return (1);
+
+ (void) sprintf(kstatname, "cmdk%d,error", instance);
+ dadkp->dad_errstats = kstat_create("cmdkerror", instance,
+ kstatname, "device_error", KSTAT_TYPE_NAMED,
+ sizeof (struct dadk_errstats) / sizeof (kstat_named_t),
+ KSTAT_FLAG_PERSISTENT);
+
+ if (!dadkp->dad_errstats)
+ return (-1);
+
+ dep = dadkp->dad_errstats->ks_data;
+
+ kstat_named_init(&dep->dadk_softerrs,
+ "Soft Errors", KSTAT_DATA_UINT32);
+ kstat_named_init(&dep->dadk_harderrs,
+ "Hard Errors", KSTAT_DATA_UINT32);
+ kstat_named_init(&dep->dadk_transerrs,
+ "Transport Errors", KSTAT_DATA_UINT32);
+ kstat_named_init(&dep->dadk_model,
+ "Model", KSTAT_DATA_CHAR);
+ kstat_named_init(&dep->dadk_revision,
+ "Revision", KSTAT_DATA_CHAR);
+ kstat_named_init(&dep->dadk_serial,
+ "Serial No", KSTAT_DATA_CHAR);
+ kstat_named_init(&dep->dadk_capacity,
+ "Size", KSTAT_DATA_ULONGLONG);
+ kstat_named_init(&dep->dadk_rq_media_err,
+ "Media Error", KSTAT_DATA_UINT32);
+ kstat_named_init(&dep->dadk_rq_ntrdy_err,
+ "Device Not Ready", KSTAT_DATA_UINT32);
+ kstat_named_init(&dep->dadk_rq_nodev_err,
+ "No Device", KSTAT_DATA_UINT32);
+ kstat_named_init(&dep->dadk_rq_recov_err,
+ "Recoverable", KSTAT_DATA_UINT32);
+ kstat_named_init(&dep->dadk_rq_illrq_err,
+ "Illegal Request", KSTAT_DATA_UINT32);
+
+ dadkp->dad_errstats->ks_private = dep;
+ dadkp->dad_errstats->ks_update = nulldev;
+ kstat_install(dadkp->dad_errstats);
+
+ /* get model */
+ dep->dadk_model.value.c[0] = 0;
+ dadk_ioc_string.is_buf = &dep->dadk_model.value.c[0];
+ dadk_ioc_string.is_size = 16;
+ CTL_IOCTL(dadkp->dad_ctlobjp, DIOCTL_GETMODEL,
+ (uintptr_t)&dadk_ioc_string, FKIOCTL);
+
+ /* 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 = 16;
+ CTL_IOCTL(dadkp->dad_ctlobjp, DIOCTL_GETSERIAL,
+ (uintptr_t)&dadk_ioc_string, FKIOCTL);
+
+ /* Get revision */
+ dep->dadk_revision.value.c[0] = 0;
+
+ /* Get capacity */
+
+ dep->dadk_capacity.value.ui64 =
+ (uint64_t)dadkp->dad_logg.g_cap *
+ (uint64_t)dadkp->dad_logg.g_secsiz;
+
+ return (0);
+}
+
+
int
dadk_close(opaque_t objp)
{
@@ -544,9 +626,24 @@ dadk_close(opaque_t objp)
(void) dadk_rmb_ioctl(dadkp, DCMD_UNLOCK, 0, 0, DADK_SILENT);
}
FLC_STOP_KSTAT(dadkp->dad_flcobjp);
+
+ (void) dadk_destroy_errstats(dadkp);
+
return (DDI_SUCCESS);
}
+static int
+dadk_destroy_errstats(struct dadk *dadkp)
+{
+ if (!dadkp->dad_errstats)
+ return (0);
+
+ kstat_delete(dadkp->dad_errstats);
+ dadkp->dad_errstats = NULL;
+ return (1);
+}
+
+
int
dadk_strategy(opaque_t objp, struct buf *bp)
{
@@ -1256,21 +1353,74 @@ static int
dadk_chkerr(struct cmpkt *pktp)
{
int err_blkno;
- struct dadk *dadkp;
- int scb;
+ struct dadk *dadkp = PKT2DADK(pktp);
+ struct dadk_errstats *dep;
+ int scb = *(char *)pktp->cp_scbp;
+ int action;
- if (*(char *)pktp->cp_scbp == DERR_SUCCESS)
+ if (scb == DERR_SUCCESS) {
+ if (pktp->cp_retry != 0 && dadkp->dad_errstats != NULL) {
+ dep = (struct dadk_errstats *)
+ dadkp->dad_errstats->ks_data;
+ dep->dadk_rq_recov_err.value.ui32++;
+ }
return (COMMAND_DONE);
+ }
/* check error code table */
- dadkp = PKT2DADK(pktp);
- scb = (int)(*(char *)pktp->cp_scbp);
+ action = dadk_errtab[scb].d_action;
+
if (pktp->cp_retry) {
err_blkno = pktp->cp_srtsec + ((pktp->cp_bytexfer -
pktp->cp_resid) >> dadkp->dad_secshf);
} else
err_blkno = -1;
+ if (dadkp->dad_errstats != NULL) {
+ dep = (struct dadk_errstats *)dadkp->dad_errstats->ks_data;
+
+ if (action == GDA_RETRYABLE)
+ dep->dadk_softerrs.value.ui32++;
+ else if (action == GDA_FATAL)
+ dep->dadk_harderrs.value.ui32++;
+
+ switch (scb) {
+ case DERR_INVCDB:
+ case DERR_ILI:
+ case DERR_EOM:
+ case DERR_HW:
+ case DERR_ICRC:
+ dep->dadk_transerrs.value.ui32++;
+ break;
+
+ case DERR_AMNF:
+ case DERR_TKONF:
+ case DERR_DWF:
+ case DERR_BBK:
+ case DERR_UNC:
+ case DERR_HARD:
+ case DERR_MEDIUM:
+ case DERR_DATA_PROT:
+ case DERR_MISCOMP:
+ dep->dadk_rq_media_err.value.ui32++;
+ break;
+
+ case DERR_NOTREADY:
+ dep->dadk_rq_ntrdy_err.value.ui32++;
+ break;
+
+ case DERR_IDNF:
+ case DERR_UNIT_ATTN:
+ dep->dadk_rq_nodev_err.value.ui32++;
+ break;
+
+ case DERR_ILL:
+ case DERR_RESV:
+ dep->dadk_rq_illrq_err.value.ui32++;
+ break;
+ }
+ }
+
/* if attempting to read a sector from a cdrom audio disk */
if ((dadkp->dad_cdrom) &&
(*((char *)(pktp->cp_cdbp)) == DCMD_READ) &&
@@ -1287,7 +1437,7 @@ dadk_chkerr(struct cmpkt *pktp)
(void) timeout(dadk_restart, (void *)pktp, DADK_BSY_TIMEOUT);
}
- return (dadk_errtab[scb].d_action);
+ return (action);
}
static void