Add sysctls for reading the tunables as suggested by des.
Minor cleanups plus checks of the ->active state. Cosmetics.
This commit is contained in:
parent
b5a5e99d51
commit
6eee1a1c12
@ -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
|
||||
|
@ -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 */
|
||||
|
@ -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)
|
||||
{
|
||||
|
@ -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 *);
|
||||
|
||||
|
@ -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;
|
||||
|
@ -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)
|
||||
|
Loading…
Reference in New Issue
Block a user