The branch main has been updated by imp:

URL: 
https://cgit.FreeBSD.org/src/commit/?id=e2c1243f427b7dd387efd42669cc199cbb9b514c

commit e2c1243f427b7dd387efd42669cc199cbb9b514c
Author:     Warner Losh <[email protected]>
AuthorDate: 2021-09-30 02:18:28 +0000
Commit:     Warner Losh <[email protected]>
CommitDate: 2021-09-30 02:18:28 +0000

    fd: Move from using device_busy to a refcount
    
    Use refcounting to delay the detach rather than device_busy and/or
    device_unbusy. fd/fdc is one of the few consumers of device_busy in the
    tree for that, and it's not a good fit. Also, nothing is waking 'fd' and
    other drivers don't loop like this. Return EBUSY if we still have active
    users.
    
    Sponsored by:           Netflix
    Reviewed by:            mav
    Differential Revision:  https://reviews.freebsd.org/D31830
---
 sys/dev/fdc/fdc.c | 34 +++++++++++++++++++++++-----------
 1 file changed, 23 insertions(+), 11 deletions(-)

diff --git a/sys/dev/fdc/fdc.c b/sys/dev/fdc/fdc.c
index 11262231c3b2..6f035e9689f1 100644
--- a/sys/dev/fdc/fdc.c
+++ b/sys/dev/fdc/fdc.c
@@ -261,6 +261,7 @@ struct fd_data {
        struct g_provider *fd_provider;
        device_t dev;
        struct bio_queue_head fd_bq;
+       bool    gone;
 };
 
 #define FD_NOT_VALID -2
@@ -1398,6 +1399,7 @@ fdautoselect(struct fd_data *fd)
 static g_access_t      fd_access;
 static g_start_t       fd_start;
 static g_ioctl_t       fd_ioctl;
+static g_provgone_t    fd_providergone;
 
 struct g_class g_fd_class = {
        .name =         "FD",
@@ -1405,6 +1407,7 @@ struct g_class g_fd_class = {
        .start =        fd_start,
        .access =       fd_access,
        .ioctl =        fd_ioctl,
+       .providergone = fd_providergone,
 };
 
 static int
@@ -1413,7 +1416,6 @@ fd_access(struct g_provider *pp, int r, int w, int e)
        struct fd_data *fd;
        struct fdc_data *fdc;
        int ar, aw, ae;
-       int busy;
 
        fd = pp->geom->softc;
        fdc = fd->fdc;
@@ -1431,11 +1433,9 @@ fd_access(struct g_provider *pp, int r, int w, int e)
 
        if (ar == 0 && aw == 0 && ae == 0) {
                fd->options &= ~(FDOPT_NORETRY | FDOPT_NOERRLOG | 
FDOPT_NOERROR);
-               device_unbusy(fd->dev);
                return (0);
        }
 
-       busy = 0;
        if (pp->acr == 0 && pp->acw == 0 && pp->ace == 0) {
                if (fdmisccmd(fd, BIO_PROBE, NULL))
                        return (ENXIO);
@@ -1453,13 +1453,9 @@ fd_access(struct g_provider *pp, int r, int w, int e)
                        fd->flags &= ~FD_NEWDISK;
                        mtx_unlock(&fdc->fdc_mtx);
                }
-               device_busy(fd->dev);
-               busy = 1;
        }
 
        if (w > 0 && (fd->flags & FD_WP)) {
-               if (busy)
-                       device_unbusy(fd->dev);
                return (EROFS);
        }
 
@@ -1588,8 +1584,6 @@ fd_ioctl(struct g_provider *pp, u_long cmd, void *data, 
int fflag, struct thread
        return (error);
 };
 
-
-
 /*
  * Configuration/initialization stuff, per controller.
  */
@@ -2055,6 +2049,16 @@ fd_attach(device_t dev)
        return (0);
 }
 
+static void
+fd_providergone(struct g_provider *pp)
+{
+       struct fd_data *fd;
+
+       fd = pp->geom->softc;
+       fd->gone = true;
+       wakeup(fd);
+}
+
 static void
 fd_detach_geom(void *arg, int flag)
 {
@@ -2070,9 +2074,17 @@ fd_detach(device_t dev)
        struct  fd_data *fd;
 
        fd = device_get_softc(dev);
+
        g_waitfor_event(fd_detach_geom, fd, M_WAITOK, NULL);
-       while (device_get_state(dev) == DS_BUSY)
-               tsleep(fd, PZERO, "fdd", hz/10);
+       while (!fd->gone) {
+               tsleep(fd, PZERO, "fdgone", hz/10);
+       }
+
+       /*
+        * There may be accesses to the floppy while we're waitng, so drain the
+        * motor callback here. fdc_detach turns off motor if it's still on when
+        * we get to this point.
+        */
        callout_drain(&fd->toffhandle);
 
        return (0);
_______________________________________________
[email protected] mailing list
https://lists.freebsd.org/mailman/listinfo/dev-commits-src-all
To unsubscribe, send any mail to "[email protected]"

Reply via email to