Diff below cleans up sparc's presto(4) disk driver. Changes:
- Add a prestolookup() alias like many other drivers, and properly
call device_unref() before returning.
- xxsize() methods are supposed to return -1 on error, not 0.
- Use disk_openpart() and disk_closepart() and pass dk_openmask to
setdisklabel().
(Warning: May not even compile...)
Index: presto.c
===================================================================
RCS file: /home/mdempsky/anoncvs/cvs/src/sys/arch/sparc/dev/presto.c,v
retrieving revision 1.22
diff -u -p -r1.22 presto.c
--- presto.c 6 Jul 2011 04:49:35 -0000 1.22
+++ presto.c 6 Jul 2011 08:47:49 -0000
@@ -82,6 +82,8 @@ struct cfdriver presto_cd = {
NULL, "presto", DV_DULL
};
+#define prestolookup(unit) (struct presto_softc *)device_lookup(&presto_cd,
(unit))
+
int
presto_match(struct device *parent, void *vcf, void *aux)
{
@@ -182,29 +184,31 @@ daddr64_t
prestosize(dev_t dev)
{
struct presto_softc *sc;
- int unit, part;
+ daddr64_t size;
+ int part;
- unit = DISKUNIT(dev);
- sc = (struct presto_softc *)device_lookup(&presto_cd, unit);
+ sc = prestolookup(DISKUNIT(dev));
if (sc == NULL)
- return (0);
+ return (-1);
part = DISKPART(dev);
if (part >= sc->sc_dk.dk_label->d_npartitions)
- return (0);
+ size = -1;
else
- return (DL_GETPSIZE(&sc->sc_dk.dk_label->d_partitions[part]) *
- (sc->sc_dk.dk_label->d_secsize / DEV_BSIZE));
+ size = DL_SECTOBLK(sc->sc_dk.dk_label,
+ DL_GETPSIZE(&sc->sc_dk.dk_label->d_partitions[part]));
+
+ device_unref(&sc->sc_dev);
+ return (size);
}
int
prestoopen(dev_t dev, int flag, int fmt, struct proc *proc)
{
- int unit, part;
struct presto_softc *sc;
+ int error;
- unit = DISKUNIT(dev);
- sc = (struct presto_softc *)device_lookup(&presto_cd, unit);
+ sc = prestolookup(DISKUNIT(dev));
if (sc == NULL)
return (ENXIO);
@@ -212,47 +216,24 @@ prestoopen(dev_t dev, int flag, int fmt,
presto_getdisklabel(dev, sc, sc->sc_dk.dk_label, 0);
/* only allow valid partitions */
- part = DISKPART(dev);
- if (part != RAW_PART &&
- (part >= sc->sc_dk.dk_label->d_npartitions ||
- sc->sc_dk.dk_label->d_partitions[part].p_fstype == FS_UNUSED))
- return (ENXIO);
+ error = disk_openpart(&sc->sc_dk, DISKPART(dev), fmt, 1);
- /* update open masks */
- switch (fmt) {
- case S_IFCHR:
- sc->sc_dk.dk_copenmask |= (1 << part);
- break;
- case S_IFBLK:
- sc->sc_dk.dk_bopenmask |= (1 << part);
- break;
- }
- sc->sc_dk.dk_openmask = sc->sc_dk.dk_copenmask | sc->sc_dk.dk_bopenmask;
-
- return (0);
+ device_unref(&sc->sc_dev);
+ return (error);
}
int
prestoclose(dev_t dev, int flag, int fmt, struct proc *proc)
{
- int unit, part;
struct presto_softc *sc;
- unit = DISKUNIT(dev);
- sc = (struct presto_softc *)device_lookup(&presto_cd, unit);
+ sc = prestolookup(DISKUNIT(dev));
+ if (sc == NULL)
+ return (ENXIO);
- /* update open masks */
- part = DISKPART(dev);
- switch (fmt) {
- case S_IFCHR:
- sc->sc_dk.dk_copenmask &= ~(1 << part);
- break;
- case S_IFBLK:
- sc->sc_dk.dk_bopenmask &= ~(1 << part);
- break;
- }
- sc->sc_dk.dk_openmask = sc->sc_dk.dk_copenmask | sc->sc_dk.dk_bopenmask;
+ disk_closepart(&sc->sc_dk, DISKPART(dev), fmt);
+ device_unref(&sc->sc_dev);
return (0);
}
@@ -271,13 +252,11 @@ prestowrite(dev_t dev, struct uio *uio,
void
prestostrategy(struct buf *bp)
{
- int unit;
struct presto_softc *sc;
size_t offset, count;
int s;
- unit = DISKUNIT(bp->b_dev);
- sc = (struct presto_softc *)device_lookup(&presto_cd, unit);
+ sc = prestolookup(DISKUNIT(bp->b_dev));
/* Sort rogue requests out */
if (sc == NULL) {
@@ -290,7 +269,6 @@ prestostrategy(struct buf *bp)
goto done;
/* Bound the request size, then move data between buf and nvram */
- bp->b_resid = bp->b_bcount;
offset = (bp->b_blkno << DEV_BSHIFT) + PSERVE_OFFSET;
count = bp->b_bcount;
if (count > (sc->sc_memsize - offset))
@@ -299,7 +277,7 @@ prestostrategy(struct buf *bp)
bcopy(sc->sc_mem + offset, bp->b_data, count);
else
bcopy(bp->b_data, sc->sc_mem + offset, count);
- bp->b_resid -= count;
+ bp->b_resid = bp->b_bcount - count;
goto done;
bad:
@@ -309,17 +287,17 @@ prestostrategy(struct buf *bp)
s = splbio();
biodone(bp);
splx(s);
+ if (sc != NULL)
+ device_unref(&sc->sc_dev);
}
int
prestoioctl(dev_t dev, u_long cmd, caddr_t data, int flag, struct proc *proc)
{
struct presto_softc *sc;
- int unit;
- int error;
+ int error = 0;
- unit = DISKUNIT(dev);
- sc = (struct presto_softc *)device_lookup(&presto_cd, unit);
+ sc = prestolookup(DISKUNIT(dev));
switch (cmd) {
case DIOCGPDINFO:
@@ -327,26 +305,32 @@ prestoioctl(dev_t dev, u_long cmd, caddr
break;
case DIOCGDINFO:
- bcopy(sc->sc_dk.dk_label, data, sizeof(struct disklabel));
- return (0);
+ *(struct disklabel *)data = *sc->sc_dk.dk_label;
+ break;
case DIOCWDINFO:
case DIOCSDINFO:
- if ((flag & FWRITE) == 0)
- return (EBADF);
+ if ((flag & FWRITE) == 0) {
+ error = EBADF;
+ break;
+ }
error = setdisklabel(sc->sc_dk.dk_label,
- (struct disklabel *)data, /*sd->sc_dk.dk_openmask : */0);
+ (struct disklabel *)data, sc->sc_dk.dk_openmask);
if (error == 0) {
if (cmd == DIOCWDINFO)
error = writedisklabel(DISKLABELDEV(dev),
prestostrategy, sc->sc_dk.dk_label);
}
- return (error);
+ break;
default:
- return (EINVAL);
+ error = EINVAL;
+ break;
}
+
+ device_unref(&sc->sc_dev);
+ return (error);
}
/*