diff options
author | marx <none@none> | 2006-08-18 17:35:55 -0700 |
---|---|---|
committer | marx <none@none> | 2006-08-18 17:35:55 -0700 |
commit | c6f76c3487b0d7e374ba5897fabad436f221c46e (patch) | |
tree | 3fde29241d2e071f6ba1e2b1709ae1b75f862897 /usr/src/uts/intel/io/dktp/dcdev/dadk.c | |
parent | 9b684ba4556d68f777e2abc0dfe297235026c0b7 (diff) | |
download | illumos-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.c | 162 |
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 |