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 --- |