diff options
author | John Baldwin <jhb@FreeBSD.org> | 2016-04-21 18:37:36 +0000 |
---|---|---|
committer | John Baldwin <jhb@FreeBSD.org> | 2016-04-21 18:37:36 +0000 |
commit | fed2c48af44fc086063940a614e985407e481eba (patch) | |
tree | 359e067b8031c1e64bd82089814789128f9d0a4c /sys/dev/fdc | |
parent | f8887b894ce2df14f90cfbd77d239f45d4a91214 (diff) | |
download | src-fed2c48af44fc086063940a614e985407e481eba.tar.gz src-fed2c48af44fc086063940a614e985407e481eba.zip |
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@gmail.com>
Sponsored by: Netflix
Notes
Notes:
svn path=/head/; revision=298426
Diffstat (limited to 'sys/dev/fdc')
-rw-r--r-- | sys/dev/fdc/fdc.c | 23 | ||||
-rw-r--r-- | sys/dev/fdc/fdc_acpi.c | 3 | ||||
-rw-r--r-- | sys/dev/fdc/fdc_cbus.c | 4 | ||||
-rw-r--r-- | sys/dev/fdc/fdc_isa.c | 4 | ||||
-rw-r--r-- | sys/dev/fdc/fdc_pccard.c | 4 | ||||
-rw-r--r-- | sys/dev/fdc/fdcvar.h | 1 |
6 files changed, 28 insertions, 11 deletions
diff --git a/sys/dev/fdc/fdc.c b/sys/dev/fdc/fdc.c index a4abd196a579..e6c2bf4a0e53 100644 --- a/sys/dev/fdc/fdc.c +++ b/sys/dev/fdc/fdc.c @@ -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 */ diff --git a/sys/dev/fdc/fdc_acpi.c b/sys/dev/fdc/fdc_acpi.c index fd5bf90c8ae3..9c6eb358ed61 100644 --- a/sys/dev/fdc/fdc_acpi.c +++ b/sys/dev/fdc/fdc_acpi.c @@ -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); diff --git a/sys/dev/fdc/fdc_cbus.c b/sys/dev/fdc/fdc_cbus.c index ee1598dccb07..b03b370375d8 100644 --- a/sys/dev/fdc/fdc_cbus.c +++ b/sys/dev/fdc/fdc_cbus.c @@ -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); } diff --git a/sys/dev/fdc/fdc_isa.c b/sys/dev/fdc/fdc_isa.c index 9e517e8569d4..a3a0e6167501 100644 --- a/sys/dev/fdc/fdc_isa.c +++ b/sys/dev/fdc/fdc_isa.c @@ -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); } diff --git a/sys/dev/fdc/fdc_pccard.c b/sys/dev/fdc/fdc_pccard.c index e04513f55b31..767a4d157a13 100644 --- a/sys/dev/fdc/fdc_pccard.c +++ b/sys/dev/fdc/fdc_pccard.c @@ -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); } diff --git a/sys/dev/fdc/fdcvar.h b/sys/dev/fdc/fdcvar.h index b09bfa19c405..be4b63814110 100644 --- a/sys/dev/fdc/fdcvar.h +++ b/sys/dev/fdc/fdcvar.h @@ -83,6 +83,7 @@ __BUS_ACCESSOR(fdc, fdtype, FDC, FDTYPE, int); 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); |