svn commit: r298426 - head/sys/dev/fdc

John Baldwin jhb at FreeBSD.org
Thu Apr 21 18:37:38 UTC 2016


Author: jhb
Date: Thu Apr 21 18:37:36 2016
New Revision: 298426
URL: https://svnweb.freebsd.org/changeset/base/298426

Log:
  Adjust the fdc worker thread startup to work when APs are started earlier.
  
  - Enable the commented out locking in fd_probe().  The worker thread
    should not be running yet (even after these changes), but better to be
    safe than sorry.
  - Defer starting the worker thread until after the child drives have been
    probed.  The worker thread startup is moved into a fdc_start_worker()
    thread that the various front ends call at the end of attach.  As a
    side effect this fixes a few edge cases that weren't shutting down the
    worker thread if attach encountered a late failure.
  - When executing the initial reset requested by attach in the worker
    thread, use DELAY() instead of a tsleep() if cold is set.
  
  Tested by:	Howard Su <howard0su at gmail.com>
  Sponsored by:	Netflix

Modified:
  head/sys/dev/fdc/fdc.c
  head/sys/dev/fdc/fdc_acpi.c
  head/sys/dev/fdc/fdc_cbus.c
  head/sys/dev/fdc/fdc_isa.c
  head/sys/dev/fdc/fdc_pccard.c
  head/sys/dev/fdc/fdcvar.h

Modified: head/sys/dev/fdc/fdc.c
==============================================================================
--- head/sys/dev/fdc/fdc.c	Thu Apr 21 18:27:05 2016	(r298425)
+++ head/sys/dev/fdc/fdc.c	Thu Apr 21 18:37:36 2016	(r298426)
@@ -953,7 +953,10 @@ fdc_worker(struct fdc_data *fdc)
 	if (fdc->flags & FDC_NEEDS_RESET) {
 		fdc->flags &= ~FDC_NEEDS_RESET;
 		fdc_reset(fdc);
-		tsleep(fdc, PRIBIO, "fdcrst", hz);
+		if (cold)
+			DELAY(1000000);
+		else
+			tsleep(fdc, PRIBIO, "fdcrst", hz);
 		/* Discard results */
 		for (i = 0; i < 4; i++)
 			fdc_sense_int(fdc, &st0, &cyl);
@@ -2055,14 +2058,21 @@ fdc_attach(device_t dev)
 #endif
 	bioq_init(&fdc->head);
 
-	kproc_create(fdc_thread, fdc, &fdc->fdc_thread, 0, 0,
-	    "fdc%d", device_get_unit(dev));
-
 	settle = hz / 8;
 
 	return (0);
 }
 
+void
+fdc_start_worker(device_t dev)
+{
+	struct	fdc_data *fdc;
+
+	fdc = device_get_softc(dev);
+	kproc_create(fdc_thread, fdc, &fdc->fdc_thread, 0, 0,
+	    "fdc%d", device_get_unit(dev));
+}
+
 int
 fdc_hints_probe(device_t dev)
 {
@@ -2155,9 +2165,8 @@ fd_probe(device_t dev)
 		return (ENXIO);
 
 #ifndef PC98
-/*
 	mtx_lock(&fdc->fdc_mtx);
-*/
+
 	/* select it */
 	fd_select(fd);
 	fd_motor(fd, 1);
@@ -2200,9 +2209,7 @@ fd_probe(device_t dev)
 
 	fd_motor(fd, 0);
 	fdc->fd = NULL;
-/*
 	mtx_unlock(&fdc->fdc_mtx);
-*/
 
 	if ((flags & FD_NO_PROBE) == 0 &&
 	    (st0 & NE7_ST0_EC) != 0) /* no track 0 -> no drive present */

Modified: head/sys/dev/fdc/fdc_acpi.c
==============================================================================
--- head/sys/dev/fdc/fdc_acpi.c	Thu Apr 21 18:27:05 2016	(r298425)
+++ head/sys/dev/fdc/fdc_acpi.c	Thu Apr 21 18:37:36 2016	(r298426)
@@ -135,6 +135,9 @@ fdc_acpi_attach(device_t dev)
 	obj = buf.Pointer;
 	error = fdc_acpi_probe_children(bus, dev, obj->Buffer.Pointer);
 
+	if (error == 0)
+		fdc_start_worker(dev);
+
 out:
 	if (buf.Pointer)
 		free(buf.Pointer, M_TEMP);

Modified: head/sys/dev/fdc/fdc_cbus.c
==============================================================================
--- head/sys/dev/fdc/fdc_cbus.c	Thu Apr 21 18:27:05 2016	(r298425)
+++ head/sys/dev/fdc/fdc_cbus.c	Thu Apr 21 18:37:36 2016	(r298426)
@@ -150,7 +150,9 @@ fdc_cbus_attach(device_t dev)
 		error = fdc_attach(dev);
 	if (error == 0)
 		error = fdc_hints_probe(dev);
-	if (error)
+	if (error == 0)
+		fdc_start_worker(dev);
+	else
 		fdc_release_resources(fdc);
 	return (error);
 }

Modified: head/sys/dev/fdc/fdc_isa.c
==============================================================================
--- head/sys/dev/fdc/fdc_isa.c	Thu Apr 21 18:27:05 2016	(r298425)
+++ head/sys/dev/fdc/fdc_isa.c	Thu Apr 21 18:37:36 2016	(r298426)
@@ -190,7 +190,9 @@ fdc_isa_attach(device_t dev)
 		error = fdc_attach(dev);
 	if (error == 0)
 		error = fdc_hints_probe(dev);
-	if (error)
+	if (error == 0)
+		fdc_start_worker(dev);
+	else
 		fdc_release_resources(fdc);
 	return (error);
 }

Modified: head/sys/dev/fdc/fdc_pccard.c
==============================================================================
--- head/sys/dev/fdc/fdc_pccard.c	Thu Apr 21 18:27:05 2016	(r298425)
+++ head/sys/dev/fdc/fdc_pccard.c	Thu Apr 21 18:37:36 2016	(r298426)
@@ -108,7 +108,9 @@ fdc_pccard_attach(device_t dev)
 		device_set_flags(child, 0x24);
 		error = bus_generic_attach(dev);
 	}
-	if (error)
+	if (error == 0)
+		fdc_start_worker(dev);
+	else
 		fdc_release_resources(fdc);
 	return (error);
 }

Modified: head/sys/dev/fdc/fdcvar.h
==============================================================================
--- head/sys/dev/fdc/fdcvar.h	Thu Apr 21 18:27:05 2016	(r298425)
+++ head/sys/dev/fdc/fdcvar.h	Thu Apr 21 18:37:36 2016	(r298426)
@@ -83,6 +83,7 @@ __BUS_ACCESSOR(fdc, fdtype, FDC, FDTYPE,
 
 void fdc_release_resources(struct fdc_data *);
 int fdc_attach(device_t);
+void fdc_start_worker(device_t);
 int fdc_hints_probe(device_t);
 int fdc_detach(device_t dev);
 device_t fdc_add_child(device_t, const char *, int);


More information about the svn-src-head mailing list