diff options
author | sos <sos@FreeBSD.org> | 2001-03-19 08:04:54 +0000 |
---|---|---|
committer | sos <sos@FreeBSD.org> | 2001-03-19 08:04:54 +0000 |
commit | 892b1c2c27421379e28fb78c620a17b16e2fbf70 (patch) | |
tree | 1a538186b46d9a35aa3aec9bf6fbed2505a63f46 /sys/dev | |
parent | 58cfc0f780e0a2393e0eb653aca52d3f52da0976 (diff) | |
download | FreeBSD-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.
Diffstat (limited to 'sys/dev')
-rw-r--r-- | sys/dev/ata/ata-all.c | 100 | ||||
-rw-r--r-- | sys/dev/ata/ata-all.h | 2 | ||||
-rw-r--r-- | sys/dev/ata/ata-disk.c | 93 | ||||
-rw-r--r-- | sys/dev/ata/ata-disk.h | 11 | ||||
-rw-r--r-- | sys/dev/ata/ata-raid.c | 15 | ||||
-rw-r--r-- | sys/dev/ata/atapi-all.c | 6 |
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) |