Lines Matching +full:motor +full:- +full:driver

1 /*-
2 * SPDX-License-Identifier: BSD-3-Clause
4 * Copyright (c) 2004 Poul-Henning Kamp
12 * aided by the Linux floppy driver modifications from David Bateman
190 #define FDO_MOEN0 0x10 /* motor enable drive 0 */
191 #define FDO_MOEN1 0x20 /* motor enable drive 1 */
192 #define FDO_MOEN2 0x40 /* motor enable drive 2 */
193 #define FDO_MOEN3 0x80 /* motor enable drive 3 */
201 * The YE-DATA PC Card floppies use PIO to read in the data rather
204 * 7.2 of the standard, but that post-dates the YE-DATA devices by many
222 /* requires drive and motor being selected */
247 #define FD_MOTOR (1<<1) /* motor should be on */
248 #define FD_MOTORWAIT (1<<2) /* motor should be on */
253 #define FD_NO_TRACK -2
263 #define FD_NOT_VALID -2
271 "fdc driver");
287 "Specification byte one (step-rate + head unload)");
291 "Specification byte two (head load time + no-dma)");
302 ft->sectrac, ft->secsize, ft->datalen, ft->gap, ft->tracks,
303 ft->size, ft->trans, ft->heads, ft->f_gap, ft->f_inter,
304 ft->offset_side2, ft->flags);
310 fd->ft = ft;
311 ft->size = ft->sectrac * ft->heads * ft->tracks;
312 fd->sectorsize = 128 << fd->ft->secsize;
316 * Bus space handling (access to low-level IO).
322 bus_space_write_1(fdc->iot, fdc->ioh[reg], fdc->ioff[reg], v);
329 return bus_space_read_1(fdc->iot, fdc->ioh[reg], fdc->ioff[reg]);
382 * Magic pseudo-DMA initialization for YE FDC. Sets count and
388 fdregwr(fdc, FDBCDR, (count - 1) & 0xff);
390 (iswrite ? 0x80 : 0) | (((count - 1) >> 8) & 0x7f));
396 fdc->fdc_errs++;
398 if (fdc->fdc_errs < FDC_ERRMAX)
399 device_printf(fdc->fdc_dev, "%s", s);
400 else if (fdc->fdc_errs == FDC_ERRMAX)
401 device_printf(fdc->fdc_dev, "too many errors, not "
484 fdc->flags |= FDC_NEEDS_RESET;
497 fdc->flags |= FDC_NEEDS_RESET;
511 if (fdc->fdct == FDC_ENHANCED) {
515 /* Try a hardware reset, keep motor on */
516 fdout_wr(fdc, fdc->fdout & ~(FDO_FRST|FDO_FDMAEN));
519 fdout_wr(fdc, fdc->fdout & ~FDO_FDMAEN);
522 fdout_wr(fdc, fdc->fdout);
526 device_printf(fdc->fdc_dev, " SPECIFY failed in reset\n");
528 if (fdc->fdct == FDC_ENHANCED) {
532 /* 0x40 | */ /* Enable Implied Seek -
535 (fifo_threshold - 1), /* Fifo threshold */
538 device_printf(fdc->fdc_dev,
545 device_printf(fdc->fdc_dev,
559 if (fdc_cmd(fdc, 2, NE7CMD_SENSED, fdc->fd->fdsu, 1, &st3))
603 fdc->status[i] = status;
609 fdc->flags |= FDC_STAT_VALID;
611 fdc->flags &= ~FDC_STAT_VALID;
625 fdc = fd->fdc;
626 fdc->fdout &= ~FDO_FDSEL;
627 fdc->fdout |= FDO_FDMAEN | FDO_FRST | fd->fdsu;
628 fdout_wr(fdc, fdc->fdout);
639 mtx_assert(&fd->fdc->fdc_mtx, MA_OWNED);
640 fd->flags &= ~FD_MOTORWAIT;
641 fd->flags |= FD_MOTOR;
644 bp = bioq_takefirst(&fd->fd_bq);
647 bioq_disksort(&fd->fdc->head, bp);
651 wakeup(&fd->fdc->head);
659 fdc = fd->fdc;
661 mtx_assert(&fdc->fdc_mtx, MA_OWNED);
664 fd->flags |= FD_MOTORWAIT;
665 fdc->fdout |= (FDO_MOEN0 << fd->fdsu);
666 callout_reset(&fd->toffhandle, hz, fd_turnon, fd);
668 callout_stop(&fd->toffhandle);
669 fd->flags &= ~(FD_MOTOR|FD_MOTORWAIT);
670 fdc->fdout &= ~(FDO_MOEN0 << fd->fdsu);
672 fdout_wr(fdc, fdc->fdout);
680 mtx_assert(&fd->fdc->fdc_mtx, MA_OWNED);
685 * fdc_intr - wake up the worker thread.
713 bp = fdc->bp;
714 cptr = fdc->fd->fd_ioptr;
715 count = fdc->fd->fd_iosize;
717 if (bp->bio_cmd == BIO_READ) {
719 bus_space_read_multi_1(fdc->iot, fdc->ioh[FD_YE_DATAPORT],
720 fdc->ioff[FD_YE_DATAPORT], cptr, count);
722 bus_space_write_multi_1(fdc->iot, fdc->ioh[FD_YE_DATAPORT],
723 fdc->ioff[FD_YE_DATAPORT], cptr, count);
734 fd = fdc->fd;
735 bp = fdc->bp;
737 mtx_lock(&fdc->fdc_mtx);
738 if (--fd->fd_iocount == 0)
739 callout_reset(&fd->toffhandle, 4 * hz, fd_turnoff, fd);
740 fdc->bp = NULL;
741 fdc->fd = NULL;
742 mtx_unlock(&fdc->fdc_mtx);
743 if (bp->bio_to != NULL) {
744 if ((debugflags & 2) && fd->fdc->retry > 0)
745 printf("retries: %d\n", fd->fdc->retry);
749 bp->bio_error = error;
750 bp->bio_flags |= BIO_DONE;
773 bp = fdc->bp;
774 fd = fdc->fd;
776 (fdc->retry >= retries || (fd->options & FDOPT_NORETRY))) {
779 if (fdc->flags & FDC_NEEDS_RESET) {
780 mtx_lock(&fdc->fdc_mtx);
781 fd->flags |= FD_EMPTY;
782 mtx_unlock(&fdc->fdc_mtx);
788 if (fd != NULL && (fd->flags & FD_ISADMA)) {
790 bp->bio_cmd == BIO_READ ? ISADMA_READ : ISADMA_WRITE,
791 fd->fd_ioptr, fd->fd_iosize, fdc->dmachan);
792 mtx_lock(&fdc->fdc_mtx);
793 fd->flags &= ~FD_ISADMA;
794 mtx_unlock(&fdc->fdc_mtx);
798 if (fdc->flags & FDC_NEEDS_RESET) {
799 fdc->flags &= ~FDC_NEEDS_RESET;
813 if (fdc->bp == NULL) {
814 mtx_lock(&fdc->fdc_mtx);
816 fdc->bp = bioq_takefirst(&fdc->head);
817 if (fdc->bp == NULL)
818 msleep(&fdc->head, &fdc->fdc_mtx,
819 PRIBIO, "-", 0);
820 } while (fdc->bp == NULL &&
821 (fdc->flags & FDC_KTHREAD_EXIT) == 0);
822 mtx_unlock(&fdc->fdc_mtx);
824 if (fdc->bp == NULL)
831 bp = fdc->bp;
832 fd = fdc->fd = bp->bio_driver1;
833 fdc->retry = 0;
834 fd->fd_ioptr = bp->bio_data;
835 if (bp->bio_cmd == BIO_FMT) {
837 fd->fd_ioptr += i;
838 fd->fd_iosize = bp->bio_length - i;
844 if (fdc->fdct == FDC_ENHANCED)
845 fddsr_wr(fdc, fd->ft->trans);
847 fdctl_wr(fdc, fd->ft->trans);
849 if (bp->bio_cmd == BIO_PROBE) {
850 if ((!(device_get_flags(fd->dev) & FD_NO_CHLINE) &&
852 !(fd->flags & FD_EMPTY)) ||
861 if (fd->flags & FD_EMPTY)
868 mtx_lock(&fdc->fdc_mtx);
869 fd->flags |= FD_EMPTY;
870 fd->flags |= FD_NEWDISK;
871 mtx_unlock(&fdc->fdc_mtx);
873 g_orphan_provider(fd->fd_provider, ENXIO);
874 fd->fd_provider->flags |= G_PF_WITHER;
875 fd->fd_provider =
876 g_new_providerf(fd->fd_geom, "%s", fd->fd_geom->name);
877 g_error_provider(fd->fd_provider, 0);
882 /* Check if the floppy is write-protected */
883 if (bp->bio_cmd == BIO_FMT || bp->bio_cmd == BIO_WRITE) {
891 mfm = (fd->ft->flags & FL_MFM)? NE7CMD_MFM: 0;
892 steptrac = (fd->ft->flags & FL_2STEP)? 2: 1;
893 i = fd->ft->sectrac * fd->ft->heads;
894 cylinder = bp->bio_pblkno / i;
896 sec = bp->bio_pblkno % i;
897 nsect = i - sec;
898 head = sec / fd->ft->sectrac;
899 sec = sec % fd->ft->sectrac + 1;
902 if (fdc->retry == 0 &&
903 (bp->bio_cmd == BIO_READ || bp->bio_cmd == BIO_WRITE)) {
904 fd->fd_iosize = imin(nsect * fd->sectorsize, bp->bio_resid);
905 nsect = fd->fd_iosize / fd->sectorsize;
906 } else if (bp->bio_cmd == BIO_READ || bp->bio_cmd == BIO_WRITE) {
907 fd->fd_iosize = fd->sectorsize;
912 if ((need_recal & (1 << fd->fdsu)) ||
913 (cylinder == 0 && fd->track != 0) ||
914 fdc->retry > 2) {
916 if (fdc_cmd(fdc, 2, NE7CMD_RECAL, fd->fdsu, 0))
925 need_recal &= ~(1 << fd->fdsu);
926 fd->track = 0;
929 tsleep(fdc->fd, PRIBIO, "fdhdstl", settle);
935 if (cylinder != fd->track) {
937 if (fdc_cmd(fdc, 3, NE7CMD_SEEK, fd->fdsu, descyl, 0))
945 need_recal |= (1 << fd->fdsu);
950 tsleep(fdc->fd, PRIBIO, "fdhdstl", settle);
952 fd->track = cylinder;
956 bp->bio_cmd, bp->bio_pblkno, fd->fd_iosize,
957 fd->fd_ioptr, fdc->retry);
960 if ((bp->bio_cmd == BIO_READ ||
961 bp->bio_cmd == BIO_WRITE ||
962 bp->bio_cmd == BIO_FMT)
963 && !(fdc->flags & FDC_NODMA)) {
965 bp->bio_cmd == BIO_READ ? ISADMA_READ : ISADMA_WRITE,
966 fd->fd_ioptr, fd->fd_iosize, fdc->dmachan);
967 mtx_lock(&fdc->fdc_mtx);
968 fd->flags |= FD_ISADMA;
969 mtx_unlock(&fdc->fdc_mtx);
973 if (fdc->flags & FDC_NODMA) {
974 if (bp->bio_cmd == BIO_READ ||
975 bp->bio_cmd == BIO_WRITE ||
976 bp->bio_cmd == BIO_FMT)
977 fdbcdr_wr(fdc, 1, fd->fd_iosize);
978 if (bp->bio_cmd == BIO_WRITE ||
979 bp->bio_cmd == BIO_FMT)
983 switch(bp->bio_cmd) {
986 finfo = (struct fd_formb *)bp->bio_data;
990 head << 2 | fd->fdsu,
991 finfo->fd_formb_secshift,
992 finfo->fd_formb_nsecs,
993 finfo->fd_formb_gaplen,
994 finfo->fd_formb_fillbyte, 0))
1001 head << 2 | fd->fdsu, 0))
1008 head << 2 | fd->fdsu, /* head & unit */
1009 fd->track, /* track */
1012 fd->ft->secsize, /* sector size */
1013 fd->ft->sectrac, /* sectors/track */
1014 fd->ft->gap, /* gap size */
1015 fd->ft->datalen, /* data length */
1023 head << 2 | fd->fdsu, /* head & unit */
1024 fd->track, /* track */
1027 fd->ft->secsize, /* sector size */
1028 fd->ft->sectrac, /* sectors/track */
1029 fd->ft->gap, /* gap size */
1030 fd->ft->datalen, /* data length */
1035 KASSERT(0 == 1, ("Wrong bio_cmd %x\n", bp->bio_cmd));
1042 if (i == 0 && (fdc->flags & FDC_NODMA) && (bp->bio_cmd == BIO_READ))
1046 if (fd->flags & FD_ISADMA) {
1048 bp->bio_cmd == BIO_READ ? ISADMA_READ : ISADMA_WRITE,
1049 fd->fd_ioptr, fd->fd_iosize, fdc->dmachan);
1050 mtx_lock(&fdc->fdc_mtx);
1051 fd->flags &= ~FD_ISADMA;
1052 mtx_unlock(&fdc->fdc_mtx);
1059 * Due to IBM's brain-dead design, the FDC has a faked ready
1066 fdc->flags |= FDC_NEEDS_RESET;
1075 printf(" -> %x %x %x %x\n",
1076 fdc->status[0], fdc->status[1],
1077 fdc->status[2], fdc->status[3]);
1079 st0 = fdc->status[0] & NE7_ST0_IC;
1082 if (st0 == NE7_ST0_IC_AT && fdc->status[1] & NE7_ST1_OR) {
1092 fdc->flags |= FDC_NEEDS_RESET;
1096 if(st0 == NE7_ST0_IC_AT && fdc->status[2] & NE7_ST2_WC) {
1097 need_recal |= (1 << fd->fdsu);
1102 fdc->status[0], fdc->status[1], fdc->status[2],
1103 fdc->status[3], fdc->status[4], fdc->status[5]);
1106 if (fd->options & FDOPT_NOERROR)
1112 switch(bp->bio_cmd) {
1115 idp = (struct fdc_readid *)bp->bio_data;
1116 idp->cyl = fdc->status[3];
1117 idp->head = fdc->status[4];
1118 idp->sec = fdc->status[5];
1119 idp->secshift = fdc->status[6];
1122 idp->cyl, idp->head, idp->sec, idp->secshift);
1126 bp->bio_pblkno += nsect;
1127 bp->bio_resid -= fd->fd_iosize;
1128 bp->bio_completed += fd->fd_iosize;
1129 fd->fd_ioptr += fd->fd_iosize;
1136 fdc->retry = 0;
1137 if (bp->bio_resid > 0)
1155 mtx_lock(&fdc->fdc_mtx);
1156 fdc->flags |= FDC_KTHREAD_ALIVE;
1157 while ((fdc->flags & FDC_KTHREAD_EXIT) == 0) {
1158 mtx_unlock(&fdc->fdc_mtx);
1161 if (fdc->bp != NULL)
1162 g_print_bio("", fdc->bp, "");
1165 fdc->retry += i;
1166 mtx_lock(&fdc->fdc_mtx);
1168 fdc->flags &= ~(FDC_KTHREAD_EXIT | FDC_KTHREAD_ALIVE);
1169 mtx_unlock(&fdc->fdc_mtx);
1182 fdc = fd->fdc;
1183 mtx_lock(&fdc->fdc_mtx);
1184 /* If we go from idle, cancel motor turnoff */
1185 if (fd->fd_iocount++ == 0)
1186 callout_stop(&fd->toffhandle);
1187 if (fd->flags & FD_MOTOR) {
1188 /* The motor is on, send it directly to the controller */
1189 bioq_disksort(&fdc->head, bp);
1190 wakeup(&fdc->head);
1192 /* Queue it on the drive until the motor has started */
1193 bioq_insert_tail(&fd->fd_bq, bp);
1194 if (!(fd->flags & FD_MOTORWAIT))
1197 mtx_unlock(&fdc->fdc_mtx);
1210 fdc = fd->fdc;
1211 oopts = fd->options;
1212 fd->options |= FDOPT_NOERRLOG | FDOPT_NORETRY;
1221 mtx_lock(&fdc->fdc_mtx);
1222 fd->flags |= FD_NEWDISK;
1223 mtx_unlock(&fdc->fdc_mtx);
1224 if (fdc_cmd(fdc, 2, NE7CMD_RECAL, fd->fdsu, 0))
1233 if (fdc_cmd(fdc, 3, NE7CMD_SEEK, fd->fdsu, 1, 0))
1238 *recal |= (1 << fd->fdsu);
1242 mtx_lock(&fdc->fdc_mtx);
1243 fd->flags |= FD_EMPTY;
1244 mtx_unlock(&fdc->fdc_mtx);
1250 mtx_lock(&fdc->fdc_mtx);
1251 fd->flags &= ~FD_EMPTY;
1253 fd->flags |= FD_WP;
1255 fd->flags &= ~FD_WP;
1256 mtx_unlock(&fdc->fdc_mtx);
1261 fd->options = oopts;
1280 bp->bio_cmd = cmd;
1283 bp->bio_pblkno =
1284 (finfo->cyl * fd->ft->heads + finfo->head) *
1285 fd->ft->sectrac;
1286 bp->bio_length = sizeof *finfo;
1289 bp->bio_pblkno =
1290 (idfield->cyl * fd->ft->heads + idfield->head) *
1291 fd->ft->sectrac;
1292 bp->bio_length = sizeof(struct fdc_readid);
1297 bp->bio_offset = bp->bio_pblkno * fd->sectorsize;
1298 bp->bio_data = data;
1299 bp->bio_driver1 = fd;
1300 bp->bio_flags = 0;
1306 } while (!(bp->bio_flags & BIO_DONE));
1307 error = bp->bio_error;
1323 if (!(fd->ft->flags & FL_AUTO))
1326 fdtp = fd_native_types[fd->type];
1328 if (!(fd->ft->flags & FL_AUTO))
1336 * two-sided media, the second probe always goes to head 1, so
1337 * we can tell them apart from single-sided media. As a
1338 * side-effect this means that single-sided media should be
1339 * mentioned in the search list after two-sided media of an
1348 * Stepping to cylinder 2 has the side-effect of clearing the
1351 oopts = fd->options;
1352 fd->options |= FDOPT_NOERRLOG | FDOPT_NORETRY;
1353 for (; fdtp->heads; fdtp++) {
1360 if (id.cyl != 0 || id.head != 0 || id.secshift != fdtp->secsize)
1363 id.head = fd->ft->heads - 1;
1365 if (id.cyl != 2 || id.head != fdtp->heads - 1 ||
1366 id.secshift != fdtp->secsize)
1372 fd->options = oopts;
1373 if (fdtp->heads == 0) {
1375 device_printf(fd->dev, "autoselection failed\n");
1376 fdsettype(fd, fd_native_types[fd->type]);
1377 return (-1);
1380 device_printf(fd->dev,
1382 fd->ft->size / 2);
1383 fdprinttype(fd->ft);
1414 fd = pp->geom->softc;
1415 fdc = fd->fdc;
1421 if (pp->flags & G_PF_WITHER)
1424 ar = r + pp->acr;
1425 aw = w + pp->acw;
1426 ae = e + pp->ace;
1429 fd->options &= ~(FDOPT_NORETRY | FDOPT_NOERRLOG | FDOPT_NOERROR);
1433 if (pp->acr == 0 && pp->acw == 0 && pp->ace == 0) {
1436 if (fd->flags & FD_EMPTY)
1438 if (fd->flags & FD_NEWDISK) {
1440 (device_get_flags(fd->dev) & FD_NO_CHLINE)) {
1441 mtx_lock(&fdc->fdc_mtx);
1442 fd->flags |= FD_EMPTY;
1443 mtx_unlock(&fdc->fdc_mtx);
1446 mtx_lock(&fdc->fdc_mtx);
1447 fd->flags &= ~FD_NEWDISK;
1448 mtx_unlock(&fdc->fdc_mtx);
1452 if (w > 0 && (fd->flags & FD_WP)) {
1456 pp->sectorsize = fd->sectorsize;
1457 pp->stripesize = fd->ft->heads * fd->ft->sectrac * fd->sectorsize;
1458 pp->mediasize = pp->stripesize * fd->ft->tracks;
1467 fd = bp->bio_to->geom->softc;
1468 bp->bio_driver1 = fd;
1469 if (bp->bio_cmd == BIO_GETATTR) {
1470 if (g_handleattr_int(bp, "GEOM::fwsectors", fd->ft->sectrac))
1472 if (g_handleattr_int(bp, "GEOM::fwheads", fd->ft->heads))
1477 if (!(bp->bio_cmd == BIO_READ || bp->bio_cmd == BIO_WRITE)) {
1481 bp->bio_pblkno = bp->bio_offset / fd->sectorsize;
1482 bp->bio_resid = bp->bio_length;
1495 fd = pp->geom->softc;
1499 *(struct fd_type *)data = *fd->ft;
1508 fd->fts = *(struct fd_type *)data;
1509 if (fd->fts.sectrac) {
1511 fdsettype(fd, &fd->fts);
1513 fdsettype(fd, fd_native_types[fd->type]);
1516 fdprinttype(fd->ft);
1520 *(int *)data = fd->options;
1524 fd->options = *(int *)data;
1531 fd->fdc->fdc_errs = 0;
1536 if ((fd->fdc->flags & FDC_STAT_VALID) == 0)
1538 memcpy(fsp->status, fd->fdc->status, 7 * sizeof(u_int));
1542 *(enum fd_drivetype *)data = fd->type;
1548 if (((struct fd_formb *)data)->format_version !=
1552 mtx_lock(&fd->fdc->fdc_mtx);
1553 fd->flags |= FD_NEWDISK;
1554 mtx_unlock(&fd->fdc->fdc_mtx);
1559 if (rid->cyl > 85 || rid->head > 1)
1594 dev = fdc->fdc_dev;
1595 if (fdc->fdc_intr)
1596 bus_teardown_intr(dev, fdc->res_irq, fdc->fdc_intr);
1597 fdc->fdc_intr = NULL;
1598 if (fdc->res_irq != NULL)
1599 bus_release_resource(dev, SYS_RES_IRQ, fdc->rid_irq,
1600 fdc->res_irq);
1601 fdc->res_irq = NULL;
1604 if (fdc->resio[i] != NULL && fdc->resio[i] != last) {
1606 fdc->ridio[i], fdc->resio[i]);
1607 last = fdc->resio[i];
1608 fdc->resio[i] = NULL;
1611 if (fdc->res_drq != NULL)
1612 bus_release_resource(dev, SYS_RES_DRQ, fdc->rid_drq,
1613 fdc->res_drq);
1614 fdc->res_drq = NULL;
1624 *result = ivars->fdunit;
1627 *result = ivars->fdtype;
1642 ivars->fdunit = value;
1645 ivars->fdtype = value;
1706 fdc->fdct = FDC_NE765;
1712 fdc->fdct = FDC_ENHANCED;
1716 fdc->fdct = FDC_UNKNOWN;
1734 if (fdc->fdc_intr)
1735 bus_teardown_intr(dev, fdc->res_irq, fdc->fdc_intr);
1736 fdc->fdc_intr = NULL;
1739 mtx_lock(&fdc->fdc_mtx);
1740 fdc->flags |= FDC_KTHREAD_EXIT;
1741 wakeup(&fdc->head);
1742 while ((fdc->flags & FDC_KTHREAD_ALIVE) != 0)
1743 msleep(fdc->fdc_thread, &fdc->fdc_mtx, PRIBIO, "fdcdet", 0);
1744 mtx_unlock(&fdc->fdc_mtx);
1746 /* reset controller, turn motor off */
1749 if (!(fdc->flags & FDC_NODMA))
1750 isa_dma_release(fdc->dmachan);
1752 mtx_destroy(&fdc->fdc_mtx);
1774 ivar->fdunit = unit;
1775 ivar->fdtype = FDT_NONE;
1788 fdc->fdc_dev = dev;
1794 error = bus_setup_intr(dev, fdc->res_irq,
1796 ((fdc->flags & FDC_NOFAST) ? INTR_MPSAFE : 0),
1797 ((fdc->flags & FDC_NOFAST) ? NULL : fdc_intr_fast),
1798 ((fdc->flags & FDC_NOFAST) ? fdc_intr : NULL),
1799 fdc, &fdc->fdc_intr);
1804 if (!(fdc->flags & FDC_NODMA)) {
1805 error = isa_dma_acquire(fdc->dmachan);
1807 error = isa_dma_init(fdc->dmachan,
1810 isa_dma_release(fdc->dmachan);
1815 fdc->fdcu = device_get_unit(dev);
1816 fdc->flags |= FDC_NEEDS_RESET;
1818 mtx_init(&fdc->fdc_mtx, "fdc lock", NULL, MTX_DEF);
1820 /* reset controller, turn motor off, clear fdout mirror reg */
1821 fdout_wr(fdc, fdc->fdout = 0);
1822 bioq_init(&fdc->head);
1835 kproc_create(fdc_thread, fdc, &fdc->fdc_thread, 0, 0,
1896 fd->dev = dev;
1897 fd->fdc = fdc;
1898 fd->fdsu = fdsu;
1900 /* Auto-probe if fdinfo is present, but always allow override. */
1903 fd->type = type;
1907 fd->flags = FD_EMPTY;
1908 fd->type = type;
1913 if (fd->type == FDT_NONE && (unit == 0 || unit == 1)) {
1916 fd->type = (rtcin(RTC_FDISKETTE) & 0xf0) >> 4;
1918 fd->type = rtcin(RTC_FDISKETTE) & 0x0f;
1919 if (fd->type == FDT_288M_1)
1920 fd->type = FDT_288M;
1924 if (fd->type == FDT_NONE)
1927 mtx_lock(&fdc->fdc_mtx);
1932 fdc->fd = fd;
1970 fdc->fd = NULL;
1971 mtx_unlock(&fdc->fdc_mtx);
1974 (st0 & NE7_ST0_EC) != 0) /* no track 0 -> no drive present */
1979 switch (fd->type) {
1981 device_set_desc(dev, "1200-KB 5.25\" drive");
1984 device_set_desc(dev, "1440-KB 3.5\" drive");
1987 device_set_desc(dev, "2880-KB 3.5\" drive (in 1440-KB mode)");
1990 device_set_desc(dev, "360-KB 5.25\" drive");
1993 device_set_desc(dev, "720-KB 3.5\" drive");
1998 fd->track = FD_NO_TRACK;
1999 fd->fdc = fdc;
2000 fd->fdsu = fdsu;
2001 fd->options = 0;
2002 callout_init_mtx(&fd->toffhandle, &fd->fdc->fdc_mtx, 0);
2005 fdsettype(fd, fd_native_types[fd->type]);
2021 fd->fd_geom = g_new_geomf(&g_fd_class,
2022 "fd%d", device_get_unit(fd->dev));
2023 fd->fd_provider = g_new_providerf(fd->fd_geom, "%s", fd->fd_geom->name);
2024 fd->fd_geom->softc = fd;
2025 g_error_provider(fd->fd_provider, 0);
2035 fd->flags |= FD_EMPTY;
2036 bioq_init(&fd->fd_bq);
2046 fd = pp->geom->softc;
2047 fd->gone = true;
2057 g_wither_geom(fd->fd_geom, ENXIO);
2068 while (!fd->gone) {
2074 * motor callback here. fdc_detach turns off motor if it's still on when
2077 callout_drain(&fd->toffhandle);