fdc.c (e25152834cdf3b353892835a4f3b157e066a8ed4) fdc.c (e2c1243f427b7dd387efd42669cc199cbb9b514c)
1/*-
2 * SPDX-License-Identifier: BSD-3-Clause
3 *
4 * Copyright (c) 2004 Poul-Henning Kamp
5 * Copyright (c) 1990 The Regents of the University of California.
6 * All rights reserved.
7 *
8 * This code is derived from software contributed to Berkeley by

--- 247 unchanged lines hidden (view full) ---

256 int track; /* where we think the head is */
257#define FD_NO_TRACK -2
258 int options; /* FDOPT_* */
259 struct callout toffhandle;
260 struct g_geom *fd_geom;
261 struct g_provider *fd_provider;
262 device_t dev;
263 struct bio_queue_head fd_bq;
1/*-
2 * SPDX-License-Identifier: BSD-3-Clause
3 *
4 * Copyright (c) 2004 Poul-Henning Kamp
5 * Copyright (c) 1990 The Regents of the University of California.
6 * All rights reserved.
7 *
8 * This code is derived from software contributed to Berkeley by

--- 247 unchanged lines hidden (view full) ---

256 int track; /* where we think the head is */
257#define FD_NO_TRACK -2
258 int options; /* FDOPT_* */
259 struct callout toffhandle;
260 struct g_geom *fd_geom;
261 struct g_provider *fd_provider;
262 device_t dev;
263 struct bio_queue_head fd_bq;
264 bool gone;
264};
265
266#define FD_NOT_VALID -2
267
268static driver_intr_t fdc_intr;
269static driver_filter_t fdc_intr_fast;
270static void fdc_reset(struct fdc_data *);
271static int fd_probe_disk(struct fd_data *, int *);

--- 1121 unchanged lines hidden (view full) ---

1393
1394/*
1395 * GEOM class implementation
1396 */
1397
1398static g_access_t fd_access;
1399static g_start_t fd_start;
1400static g_ioctl_t fd_ioctl;
265};
266
267#define FD_NOT_VALID -2
268
269static driver_intr_t fdc_intr;
270static driver_filter_t fdc_intr_fast;
271static void fdc_reset(struct fdc_data *);
272static int fd_probe_disk(struct fd_data *, int *);

--- 1121 unchanged lines hidden (view full) ---

1394
1395/*
1396 * GEOM class implementation
1397 */
1398
1399static g_access_t fd_access;
1400static g_start_t fd_start;
1401static g_ioctl_t fd_ioctl;
1402static g_provgone_t fd_providergone;
1401
1402struct g_class g_fd_class = {
1403 .name = "FD",
1404 .version = G_VERSION,
1405 .start = fd_start,
1406 .access = fd_access,
1407 .ioctl = fd_ioctl,
1403
1404struct g_class g_fd_class = {
1405 .name = "FD",
1406 .version = G_VERSION,
1407 .start = fd_start,
1408 .access = fd_access,
1409 .ioctl = fd_ioctl,
1410 .providergone = fd_providergone,
1408};
1409
1410static int
1411fd_access(struct g_provider *pp, int r, int w, int e)
1412{
1413 struct fd_data *fd;
1414 struct fdc_data *fdc;
1415 int ar, aw, ae;
1411};
1412
1413static int
1414fd_access(struct g_provider *pp, int r, int w, int e)
1415{
1416 struct fd_data *fd;
1417 struct fdc_data *fdc;
1418 int ar, aw, ae;
1416 int busy;
1417
1418 fd = pp->geom->softc;
1419 fdc = fd->fdc;
1420
1421 /*
1422 * If our provider is withering, we can only get negative requests
1423 * and we don't want to even see them
1424 */
1425 if (pp->flags & G_PF_WITHER)
1426 return (0);
1427
1428 ar = r + pp->acr;
1429 aw = w + pp->acw;
1430 ae = e + pp->ace;
1431
1432 if (ar == 0 && aw == 0 && ae == 0) {
1433 fd->options &= ~(FDOPT_NORETRY | FDOPT_NOERRLOG | FDOPT_NOERROR);
1419
1420 fd = pp->geom->softc;
1421 fdc = fd->fdc;
1422
1423 /*
1424 * If our provider is withering, we can only get negative requests
1425 * and we don't want to even see them
1426 */
1427 if (pp->flags & G_PF_WITHER)
1428 return (0);
1429
1430 ar = r + pp->acr;
1431 aw = w + pp->acw;
1432 ae = e + pp->ace;
1433
1434 if (ar == 0 && aw == 0 && ae == 0) {
1435 fd->options &= ~(FDOPT_NORETRY | FDOPT_NOERRLOG | FDOPT_NOERROR);
1434 device_unbusy(fd->dev);
1435 return (0);
1436 }
1437
1436 return (0);
1437 }
1438
1438 busy = 0;
1439 if (pp->acr == 0 && pp->acw == 0 && pp->ace == 0) {
1440 if (fdmisccmd(fd, BIO_PROBE, NULL))
1441 return (ENXIO);
1442 if (fd->flags & FD_EMPTY)
1443 return (ENXIO);
1444 if (fd->flags & FD_NEWDISK) {
1445 if (fdautoselect(fd) != 0 &&
1446 (device_get_flags(fd->dev) & FD_NO_CHLINE)) {
1447 mtx_lock(&fdc->fdc_mtx);
1448 fd->flags |= FD_EMPTY;
1449 mtx_unlock(&fdc->fdc_mtx);
1450 return (ENXIO);
1451 }
1452 mtx_lock(&fdc->fdc_mtx);
1453 fd->flags &= ~FD_NEWDISK;
1454 mtx_unlock(&fdc->fdc_mtx);
1455 }
1439 if (pp->acr == 0 && pp->acw == 0 && pp->ace == 0) {
1440 if (fdmisccmd(fd, BIO_PROBE, NULL))
1441 return (ENXIO);
1442 if (fd->flags & FD_EMPTY)
1443 return (ENXIO);
1444 if (fd->flags & FD_NEWDISK) {
1445 if (fdautoselect(fd) != 0 &&
1446 (device_get_flags(fd->dev) & FD_NO_CHLINE)) {
1447 mtx_lock(&fdc->fdc_mtx);
1448 fd->flags |= FD_EMPTY;
1449 mtx_unlock(&fdc->fdc_mtx);
1450 return (ENXIO);
1451 }
1452 mtx_lock(&fdc->fdc_mtx);
1453 fd->flags &= ~FD_NEWDISK;
1454 mtx_unlock(&fdc->fdc_mtx);
1455 }
1456 device_busy(fd->dev);
1457 busy = 1;
1458 }
1459
1460 if (w > 0 && (fd->flags & FD_WP)) {
1456 }
1457
1458 if (w > 0 && (fd->flags & FD_WP)) {
1461 if (busy)
1462 device_unbusy(fd->dev);
1463 return (EROFS);
1464 }
1465
1466 pp->sectorsize = fd->sectorsize;
1467 pp->stripesize = fd->ft->heads * fd->ft->sectrac * fd->sectorsize;
1468 pp->mediasize = pp->stripesize * fd->ft->tracks;
1469 return (0);
1470}

--- 112 unchanged lines hidden (view full) ---

1583 if (debugflags & 0x80)
1584 printf("Unknown ioctl %lx\n", cmd);
1585 error = ENOIOCTL;
1586 break;
1587 }
1588 return (error);
1589};
1590
1459 return (EROFS);
1460 }
1461
1462 pp->sectorsize = fd->sectorsize;
1463 pp->stripesize = fd->ft->heads * fd->ft->sectrac * fd->sectorsize;
1464 pp->mediasize = pp->stripesize * fd->ft->tracks;
1465 return (0);
1466}

--- 112 unchanged lines hidden (view full) ---

1579 if (debugflags & 0x80)
1580 printf("Unknown ioctl %lx\n", cmd);
1581 error = ENOIOCTL;
1582 break;
1583 }
1584 return (error);
1585};
1586
1591
1592
1593/*
1594 * Configuration/initialization stuff, per controller.
1595 */
1596
1597devclass_t fdc_devclass;
1598static devclass_t fd_devclass;
1599
1600struct fdc_ivars {

--- 450 unchanged lines hidden (view full) ---

2051 g_post_event(fd_attach2, fd, M_WAITOK, NULL);
2052 fd->flags |= FD_EMPTY;
2053 bioq_init(&fd->fd_bq);
2054
2055 return (0);
2056}
2057
2058static void
1587/*
1588 * Configuration/initialization stuff, per controller.
1589 */
1590
1591devclass_t fdc_devclass;
1592static devclass_t fd_devclass;
1593
1594struct fdc_ivars {

--- 450 unchanged lines hidden (view full) ---

2045 g_post_event(fd_attach2, fd, M_WAITOK, NULL);
2046 fd->flags |= FD_EMPTY;
2047 bioq_init(&fd->fd_bq);
2048
2049 return (0);
2050}
2051
2052static void
2053fd_providergone(struct g_provider *pp)
2054{
2055 struct fd_data *fd;
2056
2057 fd = pp->geom->softc;
2058 fd->gone = true;
2059 wakeup(fd);
2060}
2061
2062static void
2059fd_detach_geom(void *arg, int flag)
2060{
2061 struct fd_data *fd = arg;
2062
2063 g_topology_assert();
2064 g_wither_geom(fd->fd_geom, ENXIO);
2065}
2066
2067static int
2068fd_detach(device_t dev)
2069{
2070 struct fd_data *fd;
2071
2072 fd = device_get_softc(dev);
2063fd_detach_geom(void *arg, int flag)
2064{
2065 struct fd_data *fd = arg;
2066
2067 g_topology_assert();
2068 g_wither_geom(fd->fd_geom, ENXIO);
2069}
2070
2071static int
2072fd_detach(device_t dev)
2073{
2074 struct fd_data *fd;
2075
2076 fd = device_get_softc(dev);
2077
2073 g_waitfor_event(fd_detach_geom, fd, M_WAITOK, NULL);
2078 g_waitfor_event(fd_detach_geom, fd, M_WAITOK, NULL);
2074 while (device_get_state(dev) == DS_BUSY)
2075 tsleep(fd, PZERO, "fdd", hz/10);
2079 while (!fd->gone) {
2080 tsleep(fd, PZERO, "fdgone", hz/10);
2081 }
2082
2083 /*
2084 * There may be accesses to the floppy while we're waitng, so drain the
2085 * motor callback here. fdc_detach turns off motor if it's still on when
2086 * we get to this point.
2087 */
2076 callout_drain(&fd->toffhandle);
2077
2078 return (0);
2079}
2080
2081static device_method_t fd_methods[] = {
2082 /* Device interface */
2083 DEVMETHOD(device_probe, fd_probe),

--- 22 unchanged lines hidden ---
2088 callout_drain(&fd->toffhandle);
2089
2090 return (0);
2091}
2092
2093static device_method_t fd_methods[] = {
2094 /* Device interface */
2095 DEVMETHOD(device_probe, fd_probe),

--- 22 unchanged lines hidden ---