summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorsos <sos@FreeBSD.org>2001-03-19 08:04:54 +0000
committersos <sos@FreeBSD.org>2001-03-19 08:04:54 +0000
commit892b1c2c27421379e28fb78c620a17b16e2fbf70 (patch)
tree1a538186b46d9a35aa3aec9bf6fbed2505a63f46
parent58cfc0f780e0a2393e0eb653aca52d3f52da0976 (diff)
downloadFreeBSD-src-892b1c2c27421379e28fb78c620a17b16e2fbf70.zip
FreeBSD-src-892b1c2c27421379e28fb78c620a17b16e2fbf70.tar.gz
Add sysctls for reading the tunables as suggested by des.
Minor cleanups plus checks of the ->active state. Cosmetics.
-rw-r--r--sys/dev/ata/ata-all.c100
-rw-r--r--sys/dev/ata/ata-all.h2
-rw-r--r--sys/dev/ata/ata-disk.c93
-rw-r--r--sys/dev/ata/ata-disk.h11
-rw-r--r--sys/dev/ata/ata-raid.c15
-rw-r--r--sys/dev/ata/atapi-all.c6
6 files changed, 142 insertions, 85 deletions
diff --git a/sys/dev/ata/ata-all.c b/sys/dev/ata/ata-all.c
index d0da258..7cb22c1 100644
--- a/sys/dev/ata/ata-all.c
+++ b/sys/dev/ata/ata-all.c
@@ -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];
-
- 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;
- }
+ static char buf[64];
+
+ 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
diff --git a/sys/dev/ata/ata-all.h b/sys/dev/ata/ata-all.h
index 77e81ab..6be3a54 100644
--- a/sys/dev/ata/ata-all.h
+++ b/sys/dev/ata/ata-all.h
@@ -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 */
diff --git a/sys/dev/ata/ata-disk.c b/sys/dev/ata/ata-disk.c
index 7910e94..c8e3936 100644
--- a/sys/dev/ata/ata-disk.c
+++ b/sys/dev/ata/ata-disk.c
@@ -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)
{
diff --git a/sys/dev/ata/ata-disk.h b/sys/dev/ata/ata-disk.h
index a638de0..2fa1449 100644
--- a/sys/dev/ata/ata-disk.h
+++ b/sys/dev/ata/ata-disk.h
@@ -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 *);
+
diff --git a/sys/dev/ata/ata-raid.c b/sys/dev/ata/ata-raid.c
index 8f876a3..075c91d 100644
--- a/sys/dev/ata/ata-raid.c
+++ b/sys/dev/ata/ata-raid.c
@@ -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;
diff --git a/sys/dev/ata/atapi-all.c b/sys/dev/ata/atapi-all.c
index c19e0d8..05480b2 100644
--- a/sys/dev/ata/atapi-all.c
+++ b/sys/dev/ata/atapi-all.c
@@ -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)
OpenPOWER on IntegriCloud