Deleted Added
full compact
fdc.c (58934) fdc.c (59249)
1/*
2 * Copyright (c) 1990 The Regents of the University of California.
3 * All rights reserved.
4 *
5 * This code is derived from software contributed to Berkeley by
6 * Don Ahn.
7 *
8 * Libretto PCMCIA floppy support by David Horwitt (dhorwitt@ucsd.edu)

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

42 * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
43 * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
44 * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
45 * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
46 * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
47 * SUCH DAMAGE.
48 *
49 * from: @(#)fd.c 7.4 (Berkeley) 5/25/91
1/*
2 * Copyright (c) 1990 The Regents of the University of California.
3 * All rights reserved.
4 *
5 * This code is derived from software contributed to Berkeley by
6 * Don Ahn.
7 *
8 * Libretto PCMCIA floppy support by David Horwitt (dhorwitt@ucsd.edu)

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

42 * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
43 * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
44 * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
45 * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
46 * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
47 * SUCH DAMAGE.
48 *
49 * from: @(#)fd.c 7.4 (Berkeley) 5/25/91
50 * $FreeBSD: head/sys/dev/fdc/fdc.c 58934 2000-04-02 15:24:56Z phk $
50 * $FreeBSD: head/sys/dev/fdc/fdc.c 59249 2000-04-15 05:54:02Z phk $
51 *
52 */
53
54#include "opt_fdc.h"
55#include "card.h"
56
57#include <sys/param.h>
58#include <sys/systm.h>

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

79
80#include <isa/isavar.h>
81#include <isa/isareg.h>
82#include <isa/fdreg.h>
83#include <isa/fdc.h>
84#include <isa/rtc.h>
85
86/* misuse a flag to identify format operation */
51 *
52 */
53
54#include "opt_fdc.h"
55#include "card.h"
56
57#include <sys/param.h>
58#include <sys/systm.h>

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

79
80#include <isa/isavar.h>
81#include <isa/isareg.h>
82#include <isa/fdreg.h>
83#include <isa/fdc.h>
84#include <isa/rtc.h>
85
86/* misuse a flag to identify format operation */
87#define B_FORMAT B_XXX
88
89/* configuration flags */
90#define FDC_PRETEND_D0 (1 << 0) /* pretend drive 0 to be there */
91#define FDC_NO_FIFO (1 << 2) /* do not enable FIFO */
92
93/* internally used only, not really from CMOS: */
94#define RTCFDT_144M_PRETENDED 0x1000
95

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

858 /* XXX should integrate with rman */
859 isa_dma_acquire(fdc->dmachan);
860 isa_dmainit(fdc->dmachan, 128 << 3 /* XXX max secsize */);
861 }
862 fdc->state = DEVIDLE;
863
864 /* reset controller, turn motor off, clear fdout mirror reg */
865 fdout_wr(fdc, ((fdc->fdout = 0)));
87
88/* configuration flags */
89#define FDC_PRETEND_D0 (1 << 0) /* pretend drive 0 to be there */
90#define FDC_NO_FIFO (1 << 2) /* do not enable FIFO */
91
92/* internally used only, not really from CMOS: */
93#define RTCFDT_144M_PRETENDED 0x1000
94

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

857 /* XXX should integrate with rman */
858 isa_dma_acquire(fdc->dmachan);
859 isa_dmainit(fdc->dmachan, 128 << 3 /* XXX max secsize */);
860 }
861 fdc->state = DEVIDLE;
862
863 /* reset controller, turn motor off, clear fdout mirror reg */
864 fdout_wr(fdc, ((fdc->fdout = 0)));
866 bufq_init(&fdc->head);
865 bioq_init(&fdc->head);
867
868 /*
869 * Probe and attach any children. We should probably detect
870 * devices from the BIOS unless overridden.
871 */
872 for (i = resource_query_string(-1, "at", device_get_nameunit(dev));
873 i != -1;
874 i = resource_query_string(i, "at", device_get_nameunit(dev)))

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

1442
1443 return (0);
1444}
1445
1446/****************************************************************************/
1447/* fdstrategy */
1448/****************************************************************************/
1449void
866
867 /*
868 * Probe and attach any children. We should probably detect
869 * devices from the BIOS unless overridden.
870 */
871 for (i = resource_query_string(-1, "at", device_get_nameunit(dev));
872 i != -1;
873 i = resource_query_string(i, "at", device_get_nameunit(dev)))

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

1441
1442 return (0);
1443}
1444
1445/****************************************************************************/
1446/* fdstrategy */
1447/****************************************************************************/
1448void
1450fdstrategy(struct buf *bp)
1449fdstrategy(struct bio *bp)
1451{
1452 unsigned nblocks, blknum, cando;
1453 int s;
1454 fdu_t fdu;
1455 fdc_p fdc;
1456 fd_p fd;
1457 size_t fdblk;
1458
1450{
1451 unsigned nblocks, blknum, cando;
1452 int s;
1453 fdu_t fdu;
1454 fdc_p fdc;
1455 fd_p fd;
1456 size_t fdblk;
1457
1459 fdu = FDUNIT(minor(bp->b_dev));
1458 fdu = FDUNIT(minor(bp->bio_dev));
1460 fd = devclass_get_softc(fd_devclass, fdu);
1461 if (fd == 0)
1462 panic("fdstrategy: buf for nonexistent device (%#lx, %#lx)",
1459 fd = devclass_get_softc(fd_devclass, fdu);
1460 if (fd == 0)
1461 panic("fdstrategy: buf for nonexistent device (%#lx, %#lx)",
1463 (u_long)major(bp->b_dev), (u_long)minor(bp->b_dev));
1462 (u_long)major(bp->bio_dev), (u_long)minor(bp->bio_dev));
1464 fdc = fd->fdc;
1465 if (fd->type == NO_TYPE) {
1463 fdc = fd->fdc;
1464 if (fd->type == NO_TYPE) {
1466 bp->b_error = ENXIO;
1467 bp->b_ioflags |= BIO_ERROR;
1465 bp->bio_error = ENXIO;
1466 bp->bio_flags |= BIO_ERROR;
1468 goto bad;
1469 };
1470
1471 fdblk = 128 << (fd->ft->secsize);
1467 goto bad;
1468 };
1469
1470 fdblk = 128 << (fd->ft->secsize);
1472 if (!(bp->b_flags & B_FORMAT)) {
1473 if (bp->b_blkno < 0) {
1471 if (!(bp->bio_cmd & BIO_FORMAT)) {
1472 if (bp->bio_blkno < 0) {
1474 printf(
1475 "fd%d: fdstrat: bad request blkno = %lu, bcount = %ld\n",
1473 printf(
1474 "fd%d: fdstrat: bad request blkno = %lu, bcount = %ld\n",
1476 fdu, (u_long)bp->b_blkno, bp->b_bcount);
1477 bp->b_error = EINVAL;
1478 bp->b_ioflags |= BIO_ERROR;
1475 fdu, (u_long)bp->bio_blkno, bp->bio_bcount);
1476 bp->bio_error = EINVAL;
1477 bp->bio_flags |= BIO_ERROR;
1479 goto bad;
1480 }
1478 goto bad;
1479 }
1481 if ((bp->b_bcount % fdblk) != 0) {
1482 bp->b_error = EINVAL;
1483 bp->b_ioflags |= BIO_ERROR;
1480 if ((bp->bio_bcount % fdblk) != 0) {
1481 bp->bio_error = EINVAL;
1482 bp->bio_flags |= BIO_ERROR;
1484 goto bad;
1485 }
1486 }
1487
1488 /*
1489 * Set up block calculations.
1490 */
1483 goto bad;
1484 }
1485 }
1486
1487 /*
1488 * Set up block calculations.
1489 */
1491 if (bp->b_blkno > 20000000) {
1490 if (bp->bio_blkno > 20000000) {
1492 /*
1493 * Reject unreasonably high block number, prevent the
1494 * multiplication below from overflowing.
1495 */
1491 /*
1492 * Reject unreasonably high block number, prevent the
1493 * multiplication below from overflowing.
1494 */
1496 bp->b_error = EINVAL;
1497 bp->b_ioflags |= BIO_ERROR;
1495 bp->bio_error = EINVAL;
1496 bp->bio_flags |= BIO_ERROR;
1498 goto bad;
1499 }
1497 goto bad;
1498 }
1500 blknum = (unsigned) bp->b_blkno * DEV_BSIZE/fdblk;
1499 blknum = (unsigned) bp->bio_blkno * DEV_BSIZE/fdblk;
1501 nblocks = fd->ft->size;
1500 nblocks = fd->ft->size;
1502 bp->b_resid = 0;
1503 if (blknum + (bp->b_bcount / fdblk) > nblocks) {
1501 bp->bio_resid = 0;
1502 if (blknum + (bp->bio_bcount / fdblk) > nblocks) {
1504 if (blknum <= nblocks) {
1505 cando = (nblocks - blknum) * fdblk;
1503 if (blknum <= nblocks) {
1504 cando = (nblocks - blknum) * fdblk;
1506 bp->b_resid = bp->b_bcount - cando;
1505 bp->bio_resid = bp->bio_bcount - cando;
1507 if (cando == 0)
1508 goto bad; /* not actually bad but EOF */
1509 } else {
1506 if (cando == 0)
1507 goto bad; /* not actually bad but EOF */
1508 } else {
1510 bp->b_error = EINVAL;
1511 bp->b_ioflags |= BIO_ERROR;
1509 bp->bio_error = EINVAL;
1510 bp->bio_flags |= BIO_ERROR;
1512 goto bad;
1513 }
1514 }
1511 goto bad;
1512 }
1513 }
1515 bp->b_pblkno = bp->b_blkno;
1514 bp->bio_pblkno = bp->bio_blkno;
1516 s = splbio();
1515 s = splbio();
1517 bufqdisksort(&fdc->head, bp);
1516 bioqdisksort(&fdc->head, bp);
1518 untimeout(fd_turnoff, fd, fd->toffhandle); /* a good idea */
1519
1520 /* Tell devstat we are starting on the transaction */
1521 devstat_start_transaction(&fd->device_stats);
1522 device_busy(fd->dev);
1523
1524 fdstart(fdc);
1525 splx(s);

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

1642\***********************************************************************/
1643static int
1644fdstate(fdc_p fdc)
1645{
1646 int read, format, head, i, sec = 0, sectrac, st0, cyl, st3, idf;
1647 unsigned blknum = 0, b_cylinder = 0;
1648 fdu_t fdu = fdc->fdu;
1649 fd_p fd;
1517 untimeout(fd_turnoff, fd, fd->toffhandle); /* a good idea */
1518
1519 /* Tell devstat we are starting on the transaction */
1520 devstat_start_transaction(&fd->device_stats);
1521 device_busy(fd->dev);
1522
1523 fdstart(fdc);
1524 splx(s);

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

1641\***********************************************************************/
1642static int
1643fdstate(fdc_p fdc)
1644{
1645 int read, format, head, i, sec = 0, sectrac, st0, cyl, st3, idf;
1646 unsigned blknum = 0, b_cylinder = 0;
1647 fdu_t fdu = fdc->fdu;
1648 fd_p fd;
1650 register struct buf *bp;
1649 register struct bio *bp;
1651 struct fd_formb *finfo = NULL;
1652 size_t fdblk;
1653
1654 bp = fdc->bp;
1655 if (bp == NULL) {
1650 struct fd_formb *finfo = NULL;
1651 size_t fdblk;
1652
1653 bp = fdc->bp;
1654 if (bp == NULL) {
1656 bp = bufq_first(&fdc->head);
1655 bp = bioq_first(&fdc->head);
1657 if (bp != NULL) {
1656 if (bp != NULL) {
1658 bufq_remove(&fdc->head, bp);
1657 bioq_remove(&fdc->head, bp);
1659 fdc->bp = bp;
1660 }
1661 }
1662 if (bp == NULL) {
1663 /***********************************************\
1664 * nothing left for this controller to do *
1665 * Force into the IDLE state, *
1666 \***********************************************/
1667 fdc->state = DEVIDLE;
1668 if (fdc->fd) {
1669 device_printf(fdc->fdc_dev,
1670 "unexpected valid fd pointer\n");
1671 fdc->fd = (fd_p) 0;
1672 fdc->fdu = -1;
1673 }
1674 TRACE1("[fdc%d IDLE]", fdc->fdcu);
1675 return (0);
1676 }
1658 fdc->bp = bp;
1659 }
1660 }
1661 if (bp == NULL) {
1662 /***********************************************\
1663 * nothing left for this controller to do *
1664 * Force into the IDLE state, *
1665 \***********************************************/
1666 fdc->state = DEVIDLE;
1667 if (fdc->fd) {
1668 device_printf(fdc->fdc_dev,
1669 "unexpected valid fd pointer\n");
1670 fdc->fd = (fd_p) 0;
1671 fdc->fdu = -1;
1672 }
1673 TRACE1("[fdc%d IDLE]", fdc->fdcu);
1674 return (0);
1675 }
1677 fdu = FDUNIT(minor(bp->b_dev));
1676 fdu = FDUNIT(minor(bp->bio_dev));
1678 fd = devclass_get_softc(fd_devclass, fdu);
1679 fdblk = 128 << fd->ft->secsize;
1680 if (fdc->fd && (fd != fdc->fd))
1681 device_printf(fd->dev, "confused fd pointers\n");
1677 fd = devclass_get_softc(fd_devclass, fdu);
1678 fdblk = 128 << fd->ft->secsize;
1679 if (fdc->fd && (fd != fdc->fd))
1680 device_printf(fd->dev, "confused fd pointers\n");
1682 read = bp->b_iocmd == BIO_READ;
1681 read = bp->bio_cmd == BIO_READ;
1683 if (read)
1684 idf = ISADMA_READ;
1685 else
1686 idf = ISADMA_WRITE;
1682 if (read)
1683 idf = ISADMA_READ;
1684 else
1685 idf = ISADMA_WRITE;
1687 format = bp->b_flags & B_FORMAT;
1686 format = bp->bio_cmd & BIO_FORMAT;
1688 if (format) {
1687 if (format) {
1689 finfo = (struct fd_formb *)bp->b_data;
1688 finfo = (struct fd_formb *)bp->bio_data;
1690 fd->skip = (char *)&(finfo->fd_formb_cylno(0))
1691 - (char *)finfo;
1692 }
1693 if (fdc->state == DOSEEK || fdc->state == SEEKCOMPLETE) {
1689 fd->skip = (char *)&(finfo->fd_formb_cylno(0))
1690 - (char *)finfo;
1691 }
1692 if (fdc->state == DOSEEK || fdc->state == SEEKCOMPLETE) {
1694 blknum = (unsigned) bp->b_pblkno * DEV_BSIZE/fdblk +
1693 blknum = (unsigned) bp->bio_pblkno * DEV_BSIZE/fdblk +
1695 fd->skip/fdblk;
1696 b_cylinder = blknum / (fd->ft->sectrac * fd->ft->heads);
1697 }
1698 TRACE1("fd%d", fdu);
1699 TRACE1("[%s]", fdstates[fdc->state]);
1700 TRACE1("(0x%x)", fd->flags);
1701 untimeout(fd_turnoff, fd, fd->toffhandle);
1702 fd->toffhandle = timeout(fd_turnoff, fd, 4 * hz);

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

1825 if (fdc->retry < 3)
1826 fdc->retry = 3;
1827 return (retrier(fdc));
1828 }
1829 }
1830
1831 fd->track = b_cylinder;
1832 if (!(fdc->flags & FDC_NODMA))
1694 fd->skip/fdblk;
1695 b_cylinder = blknum / (fd->ft->sectrac * fd->ft->heads);
1696 }
1697 TRACE1("fd%d", fdu);
1698 TRACE1("[%s]", fdstates[fdc->state]);
1699 TRACE1("(0x%x)", fd->flags);
1700 untimeout(fd_turnoff, fd, fd->toffhandle);
1701 fd->toffhandle = timeout(fd_turnoff, fd, 4 * hz);

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

1824 if (fdc->retry < 3)
1825 fdc->retry = 3;
1826 return (retrier(fdc));
1827 }
1828 }
1829
1830 fd->track = b_cylinder;
1831 if (!(fdc->flags & FDC_NODMA))
1833 isa_dmastart(idf, bp->b_data+fd->skip,
1834 format ? bp->b_bcount : fdblk, fdc->dmachan);
1832 isa_dmastart(idf, bp->bio_data+fd->skip,
1833 format ? bp->bio_bcount : fdblk, fdc->dmachan);
1835 sectrac = fd->ft->sectrac;
1836 sec = blknum % (sectrac * fd->ft->heads);
1837 head = sec / sectrac;
1838 sec = sec % sectrac + 1;
1839 fd->hddrv = ((head&1)<<2)+fdu;
1840
1841 if(format || !read)
1842 {
1843 /* make sure the drive is writable */
1844 if(fd_sense_drive_status(fdc, &st3) != 0)
1845 {
1846 /* stuck controller? */
1847 if (!(fdc->flags & FDC_NODMA))
1848 isa_dmadone(idf,
1834 sectrac = fd->ft->sectrac;
1835 sec = blknum % (sectrac * fd->ft->heads);
1836 head = sec / sectrac;
1837 sec = sec % sectrac + 1;
1838 fd->hddrv = ((head&1)<<2)+fdu;
1839
1840 if(format || !read)
1841 {
1842 /* make sure the drive is writable */
1843 if(fd_sense_drive_status(fdc, &st3) != 0)
1844 {
1845 /* stuck controller? */
1846 if (!(fdc->flags & FDC_NODMA))
1847 isa_dmadone(idf,
1849 bp->b_data + fd->skip,
1850 format ? bp->b_bcount : fdblk,
1848 bp->bio_data + fd->skip,
1849 format ? bp->bio_bcount : fdblk,
1851 fdc->dmachan);
1852 fdc->retry = 6; /* reset the beast */
1853 return (retrier(fdc));
1854 }
1855 if(st3 & NE7_ST3_WP)
1856 {
1857 /*
1858 * XXX YES! this is ugly.

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

1882 * fields of the newly formatted track
1883 * entirely with garbage, causing
1884 * `wrong cylinder' errors all over
1885 * the place when trying to read them
1886 * back.
1887 *
1888 * Umpf.
1889 */
1850 fdc->dmachan);
1851 fdc->retry = 6; /* reset the beast */
1852 return (retrier(fdc));
1853 }
1854 if(st3 & NE7_ST3_WP)
1855 {
1856 /*
1857 * XXX YES! this is ugly.

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

1881 * fields of the newly formatted track
1882 * entirely with garbage, causing
1883 * `wrong cylinder' errors all over
1884 * the place when trying to read them
1885 * back.
1886 *
1887 * Umpf.
1888 */
1890 SET_BCDR(fdc, 1, bp->b_bcount, 0);
1889 SET_BCDR(fdc, 1, bp->bio_bcount, 0);
1891
1890
1892 (void)fdcpio(fdc,bp->b_iocmd,
1893 bp->b_data+fd->skip,
1894 bp->b_bcount);
1891 (void)fdcpio(fdc,bp->bio_cmd,
1892 bp->bio_data+fd->skip,
1893 bp->bio_bcount);
1895
1896 }
1897 /* formatting */
1898 if(fd_cmd(fdc, 6, NE7CMD_FORMAT, head << 2 | fdu,
1899 finfo->fd_formb_secshift,
1900 finfo->fd_formb_nsecs,
1901 finfo->fd_formb_gaplen,
1902 finfo->fd_formb_fillbyte, 0)) {
1903 /* controller fell over */
1904 if (!(fdc->flags & FDC_NODMA))
1905 isa_dmadone(idf,
1894
1895 }
1896 /* formatting */
1897 if(fd_cmd(fdc, 6, NE7CMD_FORMAT, head << 2 | fdu,
1898 finfo->fd_formb_secshift,
1899 finfo->fd_formb_nsecs,
1900 finfo->fd_formb_gaplen,
1901 finfo->fd_formb_fillbyte, 0)) {
1902 /* controller fell over */
1903 if (!(fdc->flags & FDC_NODMA))
1904 isa_dmadone(idf,
1906 bp->b_data + fd->skip,
1907 format ? bp->b_bcount : fdblk,
1905 bp->bio_data + fd->skip,
1906 format ? bp->bio_bcount : fdblk,
1908 fdc->dmachan);
1909 fdc->retry = 6;
1910 return (retrier(fdc));
1911 }
1912 } else {
1913 if (fdc->flags & FDC_NODMA) {
1914 /*
1915 * this seems to be necessary even when
1916 * reading data
1917 */
1918 SET_BCDR(fdc, 1, fdblk, 0);
1919
1920 /*
1921 * perform the write pseudo-DMA before
1922 * the WRITE command is sent
1923 */
1924 if (!read)
1907 fdc->dmachan);
1908 fdc->retry = 6;
1909 return (retrier(fdc));
1910 }
1911 } else {
1912 if (fdc->flags & FDC_NODMA) {
1913 /*
1914 * this seems to be necessary even when
1915 * reading data
1916 */
1917 SET_BCDR(fdc, 1, fdblk, 0);
1918
1919 /*
1920 * perform the write pseudo-DMA before
1921 * the WRITE command is sent
1922 */
1923 if (!read)
1925 (void)fdcpio(fdc,bp->b_iocmd,
1926 bp->b_data+fd->skip,
1924 (void)fdcpio(fdc,bp->bio_cmd,
1925 bp->bio_data+fd->skip,
1927 fdblk);
1928 }
1929 if (fd_cmd(fdc, 9,
1930 (read ? NE7CMD_READ : NE7CMD_WRITE),
1931 head << 2 | fdu, /* head & unit */
1932 fd->track, /* track */
1933 head,
1934 sec, /* sector + 1 */
1935 fd->ft->secsize, /* sector size */
1936 sectrac, /* sectors/track */
1937 fd->ft->gap, /* gap size */
1938 fd->ft->datalen, /* data length */
1939 0)) {
1940 /* the beast is sleeping again */
1941 if (!(fdc->flags & FDC_NODMA))
1942 isa_dmadone(idf,
1926 fdblk);
1927 }
1928 if (fd_cmd(fdc, 9,
1929 (read ? NE7CMD_READ : NE7CMD_WRITE),
1930 head << 2 | fdu, /* head & unit */
1931 fd->track, /* track */
1932 head,
1933 sec, /* sector + 1 */
1934 fd->ft->secsize, /* sector size */
1935 sectrac, /* sectors/track */
1936 fd->ft->gap, /* gap size */
1937 fd->ft->datalen, /* data length */
1938 0)) {
1939 /* the beast is sleeping again */
1940 if (!(fdc->flags & FDC_NODMA))
1941 isa_dmadone(idf,
1943 bp->b_data + fd->skip,
1944 format ? bp->b_bcount : fdblk,
1942 bp->bio_data + fd->skip,
1943 format ? bp->bio_bcount : fdblk,
1945 fdc->dmachan);
1946 fdc->retry = 6;
1947 return (retrier(fdc));
1948 }
1949 }
1950 if (fdc->flags & FDC_NODMA)
1951 /*
1952 * if this is a read, then simply await interrupt
1953 * before performing PIO
1954 */
1944 fdc->dmachan);
1945 fdc->retry = 6;
1946 return (retrier(fdc));
1947 }
1948 }
1949 if (fdc->flags & FDC_NODMA)
1950 /*
1951 * if this is a read, then simply await interrupt
1952 * before performing PIO
1953 */
1955 if (read && !fdcpio(fdc,bp->b_iocmd,
1956 bp->b_data+fd->skip,fdblk)) {
1954 if (read && !fdcpio(fdc,bp->bio_cmd,
1955 bp->bio_data+fd->skip,fdblk)) {
1957 fd->tohandle = timeout(fd_iotimeout, fdc, hz);
1958 return(0); /* will return later */
1959 };
1960
1961 /*
1962 * write (or format) operation will fall through and
1963 * await completion interrupt
1964 */
1965 fdc->state = IOCOMPLETE;
1966 fd->tohandle = timeout(fd_iotimeout, fdc, hz);
1967 return (0); /* will return later */
1968 case PIOREAD:
1969 /*
1970 * actually perform the PIO read. The IOCOMPLETE case
1971 * removes the timeout for us.
1972 */
1956 fd->tohandle = timeout(fd_iotimeout, fdc, hz);
1957 return(0); /* will return later */
1958 };
1959
1960 /*
1961 * write (or format) operation will fall through and
1962 * await completion interrupt
1963 */
1964 fdc->state = IOCOMPLETE;
1965 fd->tohandle = timeout(fd_iotimeout, fdc, hz);
1966 return (0); /* will return later */
1967 case PIOREAD:
1968 /*
1969 * actually perform the PIO read. The IOCOMPLETE case
1970 * removes the timeout for us.
1971 */
1973 (void)fdcpio(fdc,bp->b_iocmd,bp->b_data+fd->skip,fdblk);
1972 (void)fdcpio(fdc,bp->bio_cmd,bp->bio_data+fd->skip,fdblk);
1974 fdc->state = IOCOMPLETE;
1975 /* FALLTHROUGH */
1976 case IOCOMPLETE: /* IO DONE, post-analyze */
1977 untimeout(fd_iotimeout, fdc, fd->tohandle);
1978
1979 if (fd_read_status(fdc, fd->fdsu)) {
1980 if (!(fdc->flags & FDC_NODMA))
1973 fdc->state = IOCOMPLETE;
1974 /* FALLTHROUGH */
1975 case IOCOMPLETE: /* IO DONE, post-analyze */
1976 untimeout(fd_iotimeout, fdc, fd->tohandle);
1977
1978 if (fd_read_status(fdc, fd->fdsu)) {
1979 if (!(fdc->flags & FDC_NODMA))
1981 isa_dmadone(idf, bp->b_data + fd->skip,
1982 format ? bp->b_bcount : fdblk,
1980 isa_dmadone(idf, bp->bio_data + fd->skip,
1981 format ? bp->bio_bcount : fdblk,
1983 fdc->dmachan);
1984 if (fdc->retry < 6)
1985 fdc->retry = 6; /* force a reset */
1986 return (retrier(fdc));
1987 }
1988
1989 fdc->state = IOTIMEDOUT;
1990
1991 /* FALLTHROUGH */
1992
1993 case IOTIMEDOUT:
1994 if (!(fdc->flags & FDC_NODMA))
1982 fdc->dmachan);
1983 if (fdc->retry < 6)
1984 fdc->retry = 6; /* force a reset */
1985 return (retrier(fdc));
1986 }
1987
1988 fdc->state = IOTIMEDOUT;
1989
1990 /* FALLTHROUGH */
1991
1992 case IOTIMEDOUT:
1993 if (!(fdc->flags & FDC_NODMA))
1995 isa_dmadone(idf, bp->b_data + fd->skip,
1996 format ? bp->b_bcount : fdblk, fdc->dmachan);
1994 isa_dmadone(idf, bp->bio_data + fd->skip,
1995 format ? bp->bio_bcount : fdblk, fdc->dmachan);
1997 if (fdc->status[0] & NE7_ST0_IC) {
1998 if ((fdc->status[0] & NE7_ST0_IC) == NE7_ST0_IC_AT
1999 && fdc->status[1] & NE7_ST1_OR) {
2000 /*
2001 * DMA overrun. Someone hogged the bus
2002 * and didn't release it in time for the
2003 * next FDC transfer.
2004 * Just restart it, don't increment retry

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

2013 else if((fdc->status[0] & NE7_ST0_IC) == NE7_ST0_IC_AT
2014 && fdc->status[2] & NE7_ST2_WC
2015 && fdc->retry < 3)
2016 fdc->retry = 3; /* force recalibrate */
2017 return (retrier(fdc));
2018 }
2019 /* All OK */
2020 fd->skip += fdblk;
1996 if (fdc->status[0] & NE7_ST0_IC) {
1997 if ((fdc->status[0] & NE7_ST0_IC) == NE7_ST0_IC_AT
1998 && fdc->status[1] & NE7_ST1_OR) {
1999 /*
2000 * DMA overrun. Someone hogged the bus
2001 * and didn't release it in time for the
2002 * next FDC transfer.
2003 * Just restart it, don't increment retry

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

2012 else if((fdc->status[0] & NE7_ST0_IC) == NE7_ST0_IC_AT
2013 && fdc->status[2] & NE7_ST2_WC
2014 && fdc->retry < 3)
2015 fdc->retry = 3; /* force recalibrate */
2016 return (retrier(fdc));
2017 }
2018 /* All OK */
2019 fd->skip += fdblk;
2021 if (!format && fd->skip < bp->b_bcount - bp->b_resid) {
2020 if (!format && fd->skip < bp->bio_bcount - bp->bio_resid) {
2022 /* set up next transfer */
2023 fdc->state = DOSEEK;
2024 } else {
2025 /* ALL DONE */
2026 fd->skip = 0;
2027 fdc->bp = NULL;
2028 device_unbusy(fd->dev);
2021 /* set up next transfer */
2022 fdc->state = DOSEEK;
2023 } else {
2024 /* ALL DONE */
2025 fd->skip = 0;
2026 fdc->bp = NULL;
2027 device_unbusy(fd->dev);
2029 devstat_end_transaction_buf(&fd->device_stats, bp);
2028 devstat_end_transaction_bio(&fd->device_stats, bp);
2030 biodone(bp);
2031 fdc->fd = (fd_p) 0;
2032 fdc->fdu = -1;
2033 fdc->state = FINDWORK;
2034 }
2035 return (1);
2036 case RESETCTLR:
2037 fdc_reset(fdc);

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

2132 }
2133 /*XXX confusing: some branches return immediately, others end up here*/
2134 return (1); /* Come back immediatly to new state */
2135}
2136
2137static int
2138retrier(struct fdc_data *fdc)
2139{
2029 biodone(bp);
2030 fdc->fd = (fd_p) 0;
2031 fdc->fdu = -1;
2032 fdc->state = FINDWORK;
2033 }
2034 return (1);
2035 case RESETCTLR:
2036 fdc_reset(fdc);

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

2131 }
2132 /*XXX confusing: some branches return immediately, others end up here*/
2133 return (1); /* Come back immediatly to new state */
2134}
2135
2136static int
2137retrier(struct fdc_data *fdc)
2138{
2140 register struct buf *bp;
2139 struct bio *bp;
2141 struct fd_data *fd;
2142 int fdu;
2143
2144 bp = fdc->bp;
2145
2146 /* XXX shouldn't this be cached somewhere? */
2140 struct fd_data *fd;
2141 int fdu;
2142
2143 bp = fdc->bp;
2144
2145 /* XXX shouldn't this be cached somewhere? */
2147 fdu = FDUNIT(minor(bp->b_dev));
2146 fdu = FDUNIT(minor(bp->bio_dev));
2148 fd = devclass_get_softc(fd_devclass, fdu);
2149 if (fd->options & FDOPT_NORETRY)
2150 goto fail;
2151
2152 switch (fdc->retry) {
2153 case 0: case 1: case 2:
2154 fdc->state = SEEKCOMPLETE;
2155 break;
2156 case 3: case 4: case 5:
2157 fdc->state = STARTRECAL;
2158 break;
2159 case 6:
2160 fdc->state = RESETCTLR;
2161 break;
2162 case 7:
2163 break;
2164 default:
2165 fail:
2166 {
2147 fd = devclass_get_softc(fd_devclass, fdu);
2148 if (fd->options & FDOPT_NORETRY)
2149 goto fail;
2150
2151 switch (fdc->retry) {
2152 case 0: case 1: case 2:
2153 fdc->state = SEEKCOMPLETE;
2154 break;
2155 case 3: case 4: case 5:
2156 fdc->state = STARTRECAL;
2157 break;
2158 case 6:
2159 fdc->state = RESETCTLR;
2160 break;
2161 case 7:
2162 break;
2163 default:
2164 fail:
2165 {
2167 dev_t sav_b_dev = bp->b_dev;
2166 dev_t sav_bio_dev = bp->bio_dev;
2168 /* Trick diskerr */
2167 /* Trick diskerr */
2169 bp->b_dev = makedev(major(bp->b_dev),
2170 (FDUNIT(minor(bp->b_dev))<<3)|RAW_PART);
2168 bp->bio_dev = makedev(major(bp->bio_dev),
2169 (FDUNIT(minor(bp->bio_dev))<<3)|RAW_PART);
2171 diskerr(bp, "hard error", LOG_PRINTF,
2172 fdc->fd->skip / DEV_BSIZE,
2173 (struct disklabel *)NULL);
2170 diskerr(bp, "hard error", LOG_PRINTF,
2171 fdc->fd->skip / DEV_BSIZE,
2172 (struct disklabel *)NULL);
2174 bp->b_dev = sav_b_dev;
2173 bp->bio_dev = sav_bio_dev;
2175 if (fdc->flags & FDC_STAT_VALID)
2176 {
2177 printf(
2178 " (ST0 %b ST1 %b ST2 %b cyl %u hd %u sec %u)\n",
2179 fdc->status[0], NE7_ST0BITS,
2180 fdc->status[1], NE7_ST1BITS,
2181 fdc->status[2], NE7_ST2BITS,
2182 fdc->status[3], fdc->status[4],
2183 fdc->status[5]);
2184 }
2185 else
2186 printf(" (No status)\n");
2187 }
2174 if (fdc->flags & FDC_STAT_VALID)
2175 {
2176 printf(
2177 " (ST0 %b ST1 %b ST2 %b cyl %u hd %u sec %u)\n",
2178 fdc->status[0], NE7_ST0BITS,
2179 fdc->status[1], NE7_ST1BITS,
2180 fdc->status[2], NE7_ST2BITS,
2181 fdc->status[3], fdc->status[4],
2182 fdc->status[5]);
2183 }
2184 else
2185 printf(" (No status)\n");
2186 }
2188 bp->b_ioflags |= BIO_ERROR;
2189 bp->b_error = EIO;
2190 bp->b_resid += bp->b_bcount - fdc->fd->skip;
2187 bp->bio_flags |= BIO_ERROR;
2188 bp->bio_error = EIO;
2189 bp->bio_resid += bp->bio_bcount - fdc->fd->skip;
2191 fdc->bp = NULL;
2192 fdc->fd->skip = 0;
2193 device_unbusy(fd->dev);
2190 fdc->bp = NULL;
2191 fdc->fd->skip = 0;
2192 device_unbusy(fd->dev);
2194 devstat_end_transaction_buf(&fdc->fd->device_stats, bp);
2193 devstat_end_transaction_bio(&fdc->fd->device_stats, bp);
2195 biodone(bp);
2196 fdc->state = FINDWORK;
2197 fdc->flags |= FDC_NEEDS_RESET;
2198 fdc->fd = (fd_p) 0;
2199 fdc->fdu = -1;
2200 return (1);
2201 }
2202 fdc->retry++;

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

2226 return ENOBUFS;
2227 /*
2228 * keep the process from being swapped
2229 */
2230 PHOLD(p);
2231 bzero((void *)bp, sizeof(struct buf));
2232 BUF_LOCKINIT(bp);
2233 BUF_LOCK(bp, LK_EXCLUSIVE);
2194 biodone(bp);
2195 fdc->state = FINDWORK;
2196 fdc->flags |= FDC_NEEDS_RESET;
2197 fdc->fd = (fd_p) 0;
2198 fdc->fdu = -1;
2199 return (1);
2200 }
2201 fdc->retry++;

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

2225 return ENOBUFS;
2226 /*
2227 * keep the process from being swapped
2228 */
2229 PHOLD(p);
2230 bzero((void *)bp, sizeof(struct buf));
2231 BUF_LOCKINIT(bp);
2232 BUF_LOCK(bp, LK_EXCLUSIVE);
2234 bp->b_flags = B_PHYS | B_FORMAT;
2235 bp->b_iocmd = BIO_WRITE;
2233 bp->b_flags = B_PHYS;
2234 bp->b_iocmd = BIO_FORMAT;
2236
2237 /*
2238 * calculate a fake blkno, so fdstrategy() would initiate a
2239 * seek to the requested cylinder
2240 */
2241 bp->b_blkno = (finfo->cyl * (fd->ft->sectrac * fd->ft->heads)
2242 + finfo->head * fd->ft->sectrac) * fdblk / DEV_BSIZE;
2243

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

2256 break;
2257 }
2258 splx(s);
2259
2260 if (rv == EWOULDBLOCK) {
2261 /* timed out */
2262 rv = EIO;
2263 device_unbusy(fd->dev);
2235
2236 /*
2237 * calculate a fake blkno, so fdstrategy() would initiate a
2238 * seek to the requested cylinder
2239 */
2240 bp->b_blkno = (finfo->cyl * (fd->ft->sectrac * fd->ft->heads)
2241 + finfo->head * fd->ft->sectrac) * fdblk / DEV_BSIZE;
2242

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

2255 break;
2256 }
2257 splx(s);
2258
2259 if (rv == EWOULDBLOCK) {
2260 /* timed out */
2261 rv = EIO;
2262 device_unbusy(fd->dev);
2264 biodone(bp);
2263 biodone(&bp->b_io); /* XXX: HUH ? */
2265 }
2266 if (bp->b_ioflags & BIO_ERROR)
2267 rv = bp->b_error;
2268 /*
2269 * allow the process to be swapped
2270 */
2271 PRELE(p);
2272 BUF_UNLOCK(bp);

--- 122 unchanged lines hidden ---
2264 }
2265 if (bp->b_ioflags & BIO_ERROR)
2266 rv = bp->b_error;
2267 /*
2268 * allow the process to be swapped
2269 */
2270 PRELE(p);
2271 BUF_UNLOCK(bp);

--- 122 unchanged lines hidden ---