Add interface to new device configuration table. Also implement

transfer statistics for iostat, vmstat, and systat.
This commit is contained in:
Garrett Wollman 1994-10-16 03:50:36 +00:00
parent 6b4375e296
commit e78014a8dc

View File

@ -37,7 +37,7 @@ static int wdtest = 0;
* SUCH DAMAGE.
*
* from: @(#)wd.c 7.2 (Berkeley) 5/9/91
* $Id: wd.c,v 1.48 1994/10/02 17:41:44 phk Exp $
* $Id: wd.c,v 1.49 1994/10/07 21:17:41 phk Exp $
*/
/* TODO:
@ -76,6 +76,7 @@ static int wdtest = 0;
#include <sys/buf.h>
#include <sys/uio.h>
#include <sys/malloc.h>
#include <sys/devconf.h>
#include <machine/cpu.h>
#include <i386/isa/isa.h>
#include <i386/isa/isa_device.h>
@ -84,6 +85,7 @@ static int wdtest = 0;
#include <machine/apm_bios.h>
#endif
#include <sys/syslog.h>
#include <sys/dkstat.h>
#include <vm/vm.h>
#define TIMEOUT 10000
@ -106,6 +108,57 @@ static int wdtest = 0;
/* Cylinder number for doing IO to. Shares an entry in the buf struct. */
#define b_cylin b_resid
static int wd_goaway(struct kern_devconf *, int);
static int wdc_goaway(struct kern_devconf *, int);
/*
* Templates for the kern_devconf structures used when we attach.
*/
static struct kern_devconf kdc_wd_template = {
0, 0, 0, /* filled in by kern_devconf.c */
"wd", 0, { "wdc0", MDDT_WDC, 0 },
0, 0, 0, wd_goaway
};
static struct kern_devconf kdc_wdc_template = {
0, 0, 0, /* filled in by kern_devconf.c */
"wdc", 0, { "isa0", MDDT_ISA, 0 },
0, 0, 0, wdc_goaway
};
static inline void
wd_registerdev(int ctlr, int unit)
{
struct kern_devconf *kdc;
MALLOC(kdc, struct kern_devconf *, sizeof *kdc, M_TEMP, M_NOWAIT);
if(!kdc) return;
*kdc = kdc_wd_template;
kdc->kdc_unit = unit;
sprintf(kdc->kdc_md.mddc_parent, "wdc%d", ctlr);
dev_attach(kdc);
}
static int
wdc_goaway(struct kern_devconf *kdc, int force)
{
if(force) {
dev_detach(kdc);
FREE(kdc, M_TEMP);
return 0;
} else {
return EBUSY; /* XXX fix */
}
}
static int
wd_goaway(struct kern_devconf *kdc, int force)
{
dev_detach(kdc);
FREE(kdc, M_TEMP);
return 0;
}
/*
* This biotab field doubles as a field for the physical unit number on
* the controller.
@ -149,6 +202,7 @@ struct disk {
#define DKFL_WRITEPROT 0x00040 /* manual unit write protect */
#define DKFL_LABELLING 0x00080 /* readdisklabel() in progress */
struct wdparams dk_params; /* ESDI/IDE drive/controller parameters */
int dk_dkunit; /* number of statistics purposes */
struct disklabel dk_dd; /* device configuration data */
struct disklabel dk_dd2; /* DOS view converted to label */
struct dos_partition
@ -276,10 +330,18 @@ wdattach(struct isa_device *dvp)
int unit, lunit;
struct isa_device *wdup;
struct disk *du;
struct kern_devconf *kdc;
if (dvp->id_unit >= NWDC)
return (0);
MALLOC(kdc, struct kern_devconf *, sizeof *kdc, M_TEMP, M_NOWAIT);
if(!kdc)
return 0;
*kdc = kdc_wdc_template;
kdc->kdc_unit = dvp->id_unit;
dev_attach(kdc);
for (wdup = isa_biotab_wdc; wdup->id_driver != 0; wdup++) {
if (wdup->id_iobase != dvp->id_iobase)
continue;
@ -326,16 +388,23 @@ wdattach(struct isa_device *dvp)
du->dk_dd.d_secperunit
* du->dk_dd.d_secsize / (1024 * 1024),
du->dk_dd.d_secperunit);
printf("%lu cyl, %lu head, %lu sec, bytes/sec %lu\n",
du->dk_dd.d_ncylinders,
du->dk_dd.d_ntracks,
du->dk_dd.d_nsectors,
du->dk_dd.d_secsize);
/*
* Start timeout routine for this drive.
* XXX timeout should be per controller.
*/
wdtimeout((caddr_t)du);
printf("%lu cyl, %lu head, %lu sec, bytes/sec %lu\n",
du->dk_dd.d_ncylinders,
du->dk_dd.d_ntracks,
du->dk_dd.d_nsectors,
du->dk_dd.d_secsize);
/*
* Start timeout routine for this drive.
* XXX timeout should be per controller.
*/
wdtimeout((caddr_t)du);
wd_registerdev(dvp->id_unit, lunit);
if(dk_ndrive < DK_NDRIVE) {
sprintf(dk_names[dk_ndrive], "wd%d", lunit);
du->dk_dkunit = dk_ndrive++;
} else {
du->dk_dkunit = -1;
}
} else {
free(du, M_TEMP);
wddrives[lunit] = NULL;
@ -607,6 +676,9 @@ wdstart(int ctrlr)
wdunwedge(du);
}
}
if(du->dk_dkunit >= 0) {
dk_busy |= 1 << du->dk_dkunit;
}
while (wdcommand(du, cylin, head, sector, count, command)
!= 0) {
wderror(bp, du,
@ -769,6 +841,10 @@ wdintr(int unit)
}
wdxfer[du->dk_lunit]++;
if(du->dk_dkunit >= 0) {
dk_xfer[du->dk_dkunit]++;
}
outt:
if (wdtab[unit].b_active) {
if ((bp->b_flags & B_ERROR) == 0) {
@ -805,6 +881,10 @@ done: ;
biodone(bp);
}
if(du->dk_dkunit >= 0) {
dk_busy &= ~(1 << du->dk_dkunit);
}
/* controller idle */
wdtab[unit].b_active = 0;