Add sysctls for reading the tunables as suggested by des.

Minor cleanups plus checks of the ->active state.
Cosmetics.
This commit is contained in:
Søren Schmidt 2001-03-19 08:04:54 +00:00
parent b5a5e99d51
commit 6eee1a1c12
Notes: svn2git 2020-12-20 02:59:44 +00:00
svn path=/head/; revision=74450
6 changed files with 141 additions and 84 deletions

View file

@ -83,6 +83,9 @@ static void btrim(int8_t *, int);
static void bpack(int8_t *, int8_t *, int);
static void ata_change_mode(struct ata_softc *, int, int);
/* sysctl vars */
SYSCTL_NODE(_hw, OID_AUTO, ata, CTLFLAG_RD, 0, "ATA driver parameters");
/* global vars */
devclass_t ata_devclass;
@ -103,8 +106,10 @@ ata_probe(device_t dev)
if (!dev)
return ENXIO;
scp = device_get_softc(dev);
if (!scp || scp->devices)
if (!scp)
return ENXIO;
if (scp->r_io || scp->r_altio || scp->r_irq)
return EEXIST;
/* initialize the softc basics */
scp->active = ATA_IDLE;
@ -125,7 +130,6 @@ ata_probe(device_t dev)
rid = ATA_BMADDR_RID;
scp->r_bmio = bus_alloc_resource(dev, SYS_RES_IOPORT, &rid, 0, ~0,
ATA_BMIOSIZE, RF_ACTIVE);
if (bootverbose)
ata_printf(scp, -1, "iobase=0x%04x altiobase=0x%04x bmaddr=0x%04x\n",
(int)rman_get_start(scp->r_io),
@ -221,7 +225,7 @@ ata_detach(device_t dev)
/* make sure channel is not busy SOS XXX */
s = splbio();
while (!atomic_cmpset_int(&scp->active, ATA_IDLE, ATA_ACTIVE))
while (!atomic_cmpset_int(&scp->active, ATA_IDLE, ATA_CONTROL))
tsleep((caddr_t)&s, PRIBIO, "atachm", hz/4);
splx(s);
@ -324,8 +328,8 @@ ataioctl(dev_t dev, u_long cmd, caddr_t addr, int32_t flag, struct proc *p)
s = splbio();
while (!atomic_cmpset_int(&scp->active, ATA_IDLE, ATA_ACTIVE))
tsleep((caddr_t)&s, PRIBIO, "atachm", hz/4);
splx(s);
error = ata_reinit(scp);
splx(s);
break;
}
@ -520,8 +524,11 @@ ata_intr(void *data)
return;
/* if drive is busy it didn't interrupt */
if (ATA_INB(scp->r_altio, ATA_ALTSTAT) & ATA_S_BUSY)
return;
if (ATA_INB(scp->r_altio, ATA_ALTSTAT) & ATA_S_BUSY) {
DELAY(100);
if (!(ATA_INB(scp->r_altio, ATA_ALTSTAT) & ATA_S_DRQ))
return;
}
/* clear interrupt and get status */
scp->status = ATA_INB(scp->r_io, ATA_STATUS);
@ -544,12 +551,12 @@ ata_intr(void *data)
break;
#endif
case ATA_WAIT_INTR:
case ATA_WAIT_INTR | ATA_REINITING:
case ATA_WAIT_INTR | ATA_CONTROL:
wakeup((caddr_t)scp);
break;
case ATA_WAIT_READY:
case ATA_WAIT_READY | ATA_REINITING:
case ATA_WAIT_READY | ATA_CONTROL:
break;
case ATA_IDLE:
@ -566,13 +573,13 @@ ata_intr(void *data)
static int intr_count = 0;
if (intr_count++ < 10)
ata_printf(scp, -1, "unwanted interrupt %d status = %02x\n",
intr_count, scp->status);
ata_printf(scp, -1, "unwanted interrupt %d %sstatus = %02x\n",
intr_count, active2str(scp->active), scp->status);
}
#endif
}
scp->active &= ATA_REINITING;
if (scp->active & ATA_REINITING)
scp->active &= ATA_CONTROL;
if (scp->active & ATA_CONTROL)
return;
scp->running = NULL;
ata_start(scp);
@ -757,7 +764,7 @@ ata_reinit(struct ata_softc *scp)
if (!scp->r_io || !scp->r_altio || !scp->r_irq)
return ENXIO;
scp->active = ATA_REINITING;
scp->active = ATA_CONTROL;
scp->running = NULL;
devices = scp->devices;
ata_printf(scp, -1, "resetting devices .. ");
@ -801,7 +808,6 @@ ata_reinit(struct ata_softc *scp)
if (ata_getparam(scp, ATA_SLAVE, ATA_C_ATAPI_IDENTIFY))
newdev &= ~ATA_ATAPI_SLAVE;
}
scp->active = ATA_IDLE;
if (!misdev && newdev)
printf("\n");
#ifdef DEV_ATADISK
@ -825,6 +831,7 @@ ata_reinit(struct ata_softc *scp)
atapi_reinit((struct atapi_softc *)scp->dev_softc[SLAVE]);
#endif
printf("done\n");
scp->active = ATA_IDLE;
ata_start(scp);
return 0;
}
@ -914,6 +921,28 @@ ata_command(struct ata_softc *scp, int device, u_int8_t command,
"c=%d, h=%d, s=%d, count=%d, feature=%d, flags=%02x\n",
rman_get_start(scp->r_io), command, cylinder, head, sector,
count, feature, flags);
/* sanity checks */
switch(scp->active) {
case ATA_IDLE:
break;
case ATA_CONTROL:
if (flags == ATA_WAIT_INTR || flags == ATA_WAIT_READY)
break;
goto out;
case ATA_ACTIVE_ATA:
case ATA_ACTIVE_ATAPI:
if (flags == ATA_IMMEDIATE)
break;
default:
out:
printf("ata_command called %s flags=%s cmd=%02x\n",
active2str(scp->active), active2str(flags), command);
break;
}
#endif
/* disable interrupt from device */
@ -1123,29 +1152,26 @@ ata_umode(struct ata_params *ap)
static char *
active2str(int active)
{
static char buf[8];
static char buf[64];
switch (active) {
case ATA_IDLE:
return("ATA_IDLE");
case ATA_IMMEDIATE:
return("ATA_IMMEDIATE");
case ATA_WAIT_INTR:
return("ATA_WAIT_INTR");
case ATA_WAIT_READY:
return("ATA_WAIT_READY");
case ATA_ACTIVE:
return("ATA_ACTIVE");
case ATA_ACTIVE_ATA:
return("ATA_ACTIVE_ATA");
case ATA_ACTIVE_ATAPI:
return("ATA_ACTIVE_ATAPI");
case ATA_REINITING:
return("ATA_REINITING");
default:
sprintf(buf, "0x%02x", active);
return buf;
}
bzero(buf, sizeof(buf));
if (active & ATA_IDLE)
strcat(buf, "ATA_IDLE ");
if (active & ATA_IMMEDIATE)
strcat(buf, "ATA_IMMEDIATE ");
if (active & ATA_WAIT_INTR)
strcat(buf, "ATA_WAIT_INTR ");
if (active & ATA_WAIT_READY)
strcat(buf, "ATA_WAIT_READY ");
if (active & ATA_ACTIVE)
strcat(buf, "ATA_ACTIVE ");
if (active & ATA_ACTIVE_ATA)
strcat(buf, "ATA_ACTIVE_ATA ");
if (active & ATA_ACTIVE_ATAPI)
strcat(buf, "ATA_ACTIVE_ATAPI ");
if (active & ATA_CONTROL)
strcat(buf, "ATA_CONTROL ");
return buf;
}
static void

View file

@ -188,7 +188,7 @@ struct ata_softc {
#define ATA_ACTIVE 0x0008
#define ATA_ACTIVE_ATA 0x0010
#define ATA_ACTIVE_ATAPI 0x0020
#define ATA_REINITING 0x0040
#define ATA_CONTROL 0x0040
TAILQ_HEAD(, ad_request) ata_queue; /* head of ATA queue */
TAILQ_HEAD(, atapi_request) atapi_queue; /* head of ATAPI queue */

View file

@ -41,6 +41,7 @@
#include <sys/disk.h>
#include <sys/devicestat.h>
#include <sys/cons.h>
#include <sys/sysctl.h>
#include <vm/vm.h>
#include <vm/pmap.h>
#include <machine/md_var.h>
@ -87,6 +88,15 @@ TUNABLE_INT_DECL("hw.ata.ata_dma", 1, ata_dma);
TUNABLE_INT_DECL("hw.ata.wc", 0, ata_wc);
TUNABLE_INT_DECL("hw.ata.tags", 0, ata_tags);
/* sysctl vars */
SYSCTL_DECL(_hw_ata);
SYSCTL_INT(_hw_ata, OID_AUTO, ata_dma, CTLFLAG_RD, &ata_dma, 0,
"ATA disk DMA mode control");
SYSCTL_INT(_hw_ata, OID_AUTO, ata_wc, CTLFLAG_RD, &ata_wc, 0,
"ATA disk write caching");
SYSCTL_INT(_hw_ata, OID_AUTO, ata_tags, CTLFLAG_RD, &ata_tags, 0,
"ATA disk tagged queuing support");
/* defines */
#define AD_MAX_RETRIES 3
#define AD_PARAM ATA_PARAM(adp->controller, adp->unit)
@ -183,37 +193,11 @@ ad_attach(struct ata_softc *scp, int device)
adp->dev = dev;
bioq_init(&adp->queue);
if (bootverbose) {
ata_printf(scp, device, "<%.40s/%.8s> ATA-%d disk at ata%d-%s\n",
AD_PARAM->model, AD_PARAM->revision,
ad_version(AD_PARAM->versmajor), device_get_unit(scp->dev),
(adp->unit == ATA_MASTER) ? "master" : "slave");
ata_printf(scp, device, "%luMB (%u sectors), %u C, %u H, %u S, %u B\n",
adp->total_secs / ((1024L*1024L)/DEV_BSIZE), adp->total_secs,
adp->total_secs / (adp->heads * adp->sectors),
adp->heads, adp->sectors, DEV_BSIZE);
ata_printf(scp, device, "%d secs/int, %d depth queue, %s%s\n",
adp->transfersize / DEV_BSIZE, adp->num_tags + 1,
(adp->flags & AD_F_TAG_ENABLED) ? "tagged " : "",
ata_mode2str(adp->controller->mode[ATA_DEV(adp->unit)]));
ata_printf(scp, device, "piomode=%d dmamode=%d udmamode=%d cblid=%d\n",
ata_pmode(AD_PARAM), ata_wmode(AD_PARAM),
ata_umode(AD_PARAM), AD_PARAM->cblid);
}
/* if this disk belongs to an ATA RAID dont print the probe */
if (ar_probe(adp))
ata_printf(scp, device, "%luMB <%.40s> [%d/%d/%d] at ata%d-%s %s%s\n",
adp->total_secs / ((1024L * 1024L) / DEV_BSIZE),
AD_PARAM->model, adp->total_secs / (adp->heads * adp->sectors),
adp->heads, adp->sectors, device_get_unit(scp->dev),
(adp->unit == ATA_MASTER) ? "master" : "slave",
(adp->flags & AD_F_TAG_ENABLED) ? "tagged " : "",
ata_mode2str(adp->controller->mode[ATA_DEV(adp->unit)]));
if (!ar_probe(adp))
adp->flags |= AD_F_RAID_SUBDISK;
else
ad_print(adp, "");
/* store our softc signalling we are ready to go */
scp->dev_softc[ATA_DEV(device)] = adp;
@ -226,6 +210,10 @@ ad_detach(struct ad_softc *adp, int flush)
struct bio *bp;
adp->flags |= AD_F_DETACHING;
if (adp->flags & AD_F_RAID_SUBDISK)
printf("WARNING! detaching RAID subdisk, danger ahead\n");
ata_printf(adp->controller, adp->unit, "removed from configuration\n");
TAILQ_FOREACH(request, &adp->controller->ata_queue, chain) {
if (request->device != adp)
@ -261,6 +249,8 @@ adopen(dev_t dev, int flags, int fmt, struct proc *p)
struct ad_softc *adp = dev->si_drv1;
struct disklabel *dl;
if (adp->flags & AD_F_RAID_SUBDISK)
return EBUSY;
dl = &adp->disk.d_label;
bzero(dl, sizeof *dl);
dl->d_secsize = DEV_BSIZE;
@ -943,6 +933,49 @@ ad_reinit(struct ad_softc *adp)
ata_dmainit(adp->controller, adp->unit, ata_pmode(AD_PARAM), -1, -1);
}
void
ad_print(struct ad_softc *adp, char *prepend)
{
if (prepend)
printf("%s", prepend);
if (bootverbose) {
ata_printf(adp->controller, adp->unit,
"<%.40s/%.8s> ATA-%d disk at ata%d-%s\n",
AD_PARAM->model, AD_PARAM->revision,
ad_version(AD_PARAM->versmajor),
device_get_unit(adp->controller->dev),
(adp->unit == ATA_MASTER) ? "master" : "slave");
ata_printf(adp->controller, adp->unit,
"%luMB (%u sectors), %u C, %u H, %u S, %u B\n",
adp->total_secs / ((1024L*1024L)/DEV_BSIZE), adp->total_secs,
adp->total_secs / (adp->heads * adp->sectors),
adp->heads, adp->sectors, DEV_BSIZE);
ata_printf(adp->controller, adp->unit,
"%d secs/int, %d depth queue, %s%s\n",
adp->transfersize / DEV_BSIZE, adp->num_tags + 1,
(adp->flags & AD_F_TAG_ENABLED) ? "tagged " : "",
ata_mode2str(adp->controller->mode[ATA_DEV(adp->unit)]));
ata_printf(adp->controller, adp->unit,
"piomode=%d dmamode=%d udmamode=%d cblid=%d\n",
ata_pmode(AD_PARAM), ata_wmode(AD_PARAM),
ata_umode(AD_PARAM), AD_PARAM->cblid);
}
else
ata_printf(adp->controller, adp->unit,
"%luMB <%.40s> [%d/%d/%d] at ata%d-%s %s%s\n",
adp->total_secs / ((1024L * 1024L) / DEV_BSIZE),
AD_PARAM->model, adp->total_secs / (adp->heads*adp->sectors),
adp->heads, adp->sectors,
device_get_unit(adp->controller->dev),
(adp->unit == ATA_MASTER) ? "master" : "slave",
(adp->flags & AD_F_TAG_ENABLED) ? "tagged " : "",
ata_mode2str(adp->controller->mode[ATA_DEV(adp->unit)]));
}
static int
ad_version(u_int16_t version)
{

View file

@ -65,10 +65,11 @@ struct ad_softc {
int num_tags; /* number of tags supported */
int flags; /* drive flags */
#define AD_F_LABELLING 0x0001
#define AD_F_LBA_ENABLED 0x0002
#define AD_F_32B_ENABLED 0x0004
#define AD_F_TAG_ENABLED 0x0008
#define AD_F_DETACHING 0x0010
#define AD_F_DETACHING 0x0002
#define AD_F_LBA_ENABLED 0x0004
#define AD_F_32B_ENABLED 0x0008
#define AD_F_TAG_ENABLED 0x0010
#define AD_F_RAID_SUBDISK 0x0020
struct ad_request *tags[32]; /* tag array of requests */
int outstanding; /* tags not serviced yet */
@ -85,3 +86,5 @@ int ad_transfer(struct ad_request *);
int ad_interrupt(struct ad_request *);
int ad_service(struct ad_softc *, int);
void ad_reinit(struct ad_softc *);
void ad_print(struct ad_softc *, char *);

View file

@ -80,17 +80,6 @@ static int ar_init = 0;
static struct ar_softc *ar_table[8];
static MALLOC_DEFINE(M_AR, "AR driver", "ATA RAID driver");
/* defines */
#define PRINT_AD(adp) \
printf(" ad%d: %luMB <%.40s> [%d/%d/%d] at ata%d-%s %s%s\n", \
adp->lun, adp->total_secs / ((1024L * 1024L) / DEV_BSIZE), \
adp->controller->dev_param[ATA_DEV(adp->unit)]->model, \
adp->total_secs / (adp->heads * adp->sectors), \
adp->heads, adp->sectors, device_get_unit(adp->controller->dev),\
(adp->unit == ATA_MASTER) ? "master" : "slave", \
(adp->flags & AD_F_TAG_ENABLED) ? "tagged " : "", \
ata_mode2str(adp->controller->mode[ATA_DEV(adp->unit)]))
int
ar_probe(struct ad_softc *adp)
{
@ -136,9 +125,9 @@ ar_attach(struct ar_softc *raid)
printf("array> [%d/%d/%d] subdisks:\n",
raid->cylinders, raid->heads, raid->sectors);
for (i = 0; i < raid->num_subdisks; i++)
PRINT_AD(raid->subdisk[i]);
ad_print(raid->subdisk[i], " ");
for (i = 0; i < raid->num_mirrordisks; i++)
PRINT_AD(raid->mirrordisk[i]);
ad_print(raid->mirrordisk[i], " ");
dev = disk_create(raid->lun, &raid->disk, 0, &ar_cdevsw, &ardisk_cdevsw);
dev->si_drv1 = raid;

View file

@ -37,6 +37,7 @@
#include <sys/bus.h>
#include <sys/malloc.h>
#include <sys/bio.h>
#include <sys/sysctl.h>
#include <machine/bus.h>
#include <sys/rman.h>
#include <dev/ata/ata-all.h>
@ -55,6 +56,11 @@ static MALLOC_DEFINE(M_ATAPI, "ATAPI generic", "ATAPI driver generic layer");
static int atapi_dma;
TUNABLE_INT_DECL("hw.ata.atapi_dma", 0, atapi_dma);
/* systcl vars */
SYSCTL_DECL(_hw_ata);
SYSCTL_INT(_hw_ata, OID_AUTO, atapi_dma, CTLFLAG_RD, &atapi_dma, 0,
"ATAPI device DMA mode control");
/* defines */
#define ATAPI_MAX_RETRIES 3
#define ATP_PARAM ATA_PARAM(atp->controller, atp->unit)