summaryrefslogtreecommitdiff
path: root/sys/i386/isa/fd.c
diff options
context:
space:
mode:
Diffstat (limited to 'sys/i386/isa/fd.c')
-rw-r--r--sys/i386/isa/fd.c467
1 files changed, 98 insertions, 369 deletions
diff --git a/sys/i386/isa/fd.c b/sys/i386/isa/fd.c
index 9972a38f5c358..d04f98a1f388c 100644
--- a/sys/i386/isa/fd.c
+++ b/sys/i386/isa/fd.c
@@ -5,10 +5,6 @@
* This code is derived from software contributed to Berkeley by
* Don Ahn.
*
- * Libretto PCMCIA floppy support by David Horwitt (dhorwitt@ucsd.edu)
- * aided by the Linux floppy driver modifications from David Bateman
- * (dbateman@eng.uts.edu.au).
- *
* Copyright (c) 1993, 1994 by
* jc@irbs.UUCP (John Capo)
* vak@zebub.msk.su (Serge Vakulenko)
@@ -47,10 +43,14 @@
* SUCH DAMAGE.
*
* from: @(#)fd.c 7.4 (Berkeley) 5/25/91
- * $Id: fd.c,v 1.131 1999/01/15 09:15:27 bde Exp $
+ * $Id: fd.c,v 1.122 1998/09/15 08:15:28 gibbs Exp $
*
*/
+#include "ft.h"
+#if NFT < 1
+#undef NFDC
+#endif
#include "fd.h"
#include "opt_devfs.h"
#include "opt_fdc.h"
@@ -76,6 +76,10 @@
#include <i386/isa/fdc.h>
#include <i386/isa/rtc.h>
#include <machine/stdarg.h>
+#if NFT > 0
+#include <sys/ftape.h>
+#include <i386/isa/ftreg.h>
+#endif
#ifdef DEVFS
#include <sys/devfsext.h>
#endif /* DEVFS */
@@ -85,10 +89,6 @@
/* configuration flags */
#define FDC_PRETEND_D0 (1 << 0) /* pretend drive 0 to be there */
-#ifdef FDC_YE
-#define FDC_IS_PCMCIA (1 << 1) /* if successful probe, then it's
- a PCMCIA device */
-#endif
/* internally used only, not really from CMOS: */
#define RTCFDT_144M_PRETENDED 0x1000
@@ -190,9 +190,15 @@ static struct fd_data {
* fdsu is the floppy drive unit number on that controller. (sub-unit) *
\***********************************************************************/
-#ifdef FDC_YE
-#include "card.h"
-static int yeattach(struct isa_device *);
+#if NFT > 0
+int ftopen(dev_t, int);
+int ftintr(ftu_t ftu);
+int ftclose(dev_t, int);
+void ftstrategy(struct buf *);
+int ftioctl(dev_t, unsigned long, caddr_t, int, struct proc *);
+int ftdump(dev_t);
+int ftsize(dev_t);
+int ftattach(struct isa_device *, struct isa_device *, int);
#endif
/* autoconfig functions */
@@ -215,7 +221,6 @@ static int fd_in(fdcu_t, int *);
static void fdstart(fdcu_t);
static timeout_t fd_iotimeout;
static timeout_t fd_pseudointr;
-static ointhand2_t fdintr;
static int fdstate(fdcu_t, fdc_p);
static int retrier(fdcu_t);
static int fdformat(dev_t, struct fd_formb *, struct proc *);
@@ -238,9 +243,6 @@ static int fifo_threshold = 8; /* XXX: should be accessible via sysctl */
#define MOTORWAIT 10
#define IOTIMEDOUT 11
#define RESETCOMPLETE 12
-#ifdef FDC_YE
-#define PIOREAD 13
-#endif
#ifdef FDC_DEBUG
static char const * const fdstates[] =
@@ -258,9 +260,6 @@ static char const * const fdstates[] =
"MOTORWAIT",
"IOTIMEDOUT",
"RESETCOMPLETE",
-#ifdef FDC_YE
-"PIOREAD",
-#endif
};
/* CAUTION: fd_debug causes huge amounts of logging output */
@@ -272,91 +271,6 @@ static int volatile fd_debug = 0;
#define TRACE1(arg1, arg2)
#endif /* FDC_DEBUG */
-#ifdef FDC_YE
-#if NCARD > 0
-#include <sys/select.h>
-#include <sys/module.h>
-#include <pccard/cardinfo.h>
-#include <pccard/driver.h>
-#include <pccard/slot.h>
-
-/*
- * PC-Card (PCMCIA) specific code.
- */
-static int yeinit(struct pccard_devinfo *); /* init device */
-static void yeunload(struct pccard_devinfo *); /* Disable driver */
-static int yeintr(struct pccard_devinfo *); /* Interrupt handler */
-
-PCCARD_MODULE(fdc, yeinit, yeunload, yeintr, 0, bio_imask);
-
-/*
- * this is the secret PIO data port (offset from base)
- */
-#define FDC_YE_DATAPORT 6
-
-/*
- * Initialize the device - called from Slot manager.
- */
-static int yeinit(struct pccard_devinfo *devi)
-{
- fdc_p fdc = &fdc_data[devi->isahd.id_unit];
-
- /* validate unit number. */
- if (devi->isahd.id_unit >= NFDC)
- return(ENODEV);
- fdc->baseport = devi->isahd.id_iobase;
- /*
- * reset controller
- */
- outb(fdc->baseport+FDOUT, 0);
- DELAY(100);
- outb(fdc->baseport+FDOUT, FDO_FRST);
-
- /*
- * wire into system
- */
- if (yeattach(&devi->isahd) == 0)
- return(ENXIO);
-
- return(0);
-}
-
-/*
- * yeunload - unload the driver and clear the table.
- * XXX TODO:
- * This is usually called when the card is ejected, but
- * can be caused by a modunload of a controller driver.
- * The idea is to reset the driver's view of the device
- * and ensure that any driver entry points such as
- * read and write do not hang.
- */
-static void yeunload(struct pccard_devinfo *devi)
-{
- if (fd_data[devi->isahd.id_unit].type == NO_TYPE)
- return;
-
- /*
- * this prevents Fdopen() and fdstrategy() from attempting
- * to access unloaded controller
- */
- fd_data[devi->isahd.id_unit].type = NO_TYPE;
-
- printf("fdc%d: unload\n", devi->isahd.id_unit);
-}
-
-/*
- * yeintr - Shared interrupt called from
- * front end of PC-Card handler.
- */
-static int yeintr(struct pccard_devinfo *devi)
-{
- fdintr((fdcu_t)devi->isahd.id_unit);
- return(1);
-}
-#endif /* NCARD > 0 */
-#endif /* FDC_YE */
-
-
/* autoconfig structure */
struct isa_driver fdcdriver = {
@@ -395,7 +309,7 @@ fdc_err(fdcu_t fdcu, const char *s)
printf("fdc%d: %s", fdcu, s);
else if(fdc_data[fdcu].fdc_errs == FDC_ERRMAX)
printf("fdc%d: too many errors, not logging any more\n",
- fdcu);
+ fdcu);
}
return FD_FAILED;
@@ -425,7 +339,7 @@ fd_cmd(fdcu_t fdcu, int n_out, ...)
if (out_fdc(fdcu, va_arg(ap, int)) < 0)
{
char msg[50];
- snprintf(msg, sizeof(msg),
+ sprintf(msg,
"cmd %x failed at out byte %d of %d\n",
cmd, n + 1, n_out);
return fdc_err(fdcu, msg);
@@ -438,7 +352,7 @@ fd_cmd(fdcu_t fdcu, int n_out, ...)
if (fd_in(fdcu, ptr) < 0)
{
char msg[50];
- snprintf(msg, sizeof(msg),
+ sprintf(msg,
"cmd %02x failed at in byte %d of %d\n",
cmd, n + 1, n_in);
return fdc_err(fdcu, msg);
@@ -600,14 +514,6 @@ fdprobe(struct isa_device *dev)
{
return(0);
}
-#ifdef FDC_YE
- /*
- * don't succeed on probe; wait
- * for PCCARD subsystem to do it
- */
- if (dev->id_flags & FDC_IS_PCMCIA)
- return(0);
-#endif
return (IO_FDCSIZE);
}
@@ -623,6 +529,9 @@ fdattach(struct isa_device *dev)
fdc_p fdc = fdc_data + fdcu;
fd_p fd;
int fdsu, st0, st3, i;
+#if NFT > 0
+ int unithasfd;
+#endif
struct isa_device *fdup;
int ic_type = 0;
#ifdef DEVFS
@@ -631,7 +540,6 @@ fdattach(struct isa_device *dev)
int typesize;
#endif
- dev->id_ointr = fdintr;
fdc->fdcu = fdcu;
fdc->flags |= FDC_ATTACHED;
fdc->dmachan = dev->id_drq;
@@ -649,7 +557,7 @@ fdattach(struct isa_device *dev)
continue;
fdu = fdup->id_unit;
fd = &fd_data[fdu];
- if (fdu >= (NFD))
+ if (fdu >= (NFD+NFT))
continue;
fdsu = fdup->id_physid;
/* look up what bios thinks we have */
@@ -666,8 +574,26 @@ fdattach(struct isa_device *dev)
}
/* is there a unit? */
if ((fdt == RTCFDT_NONE)
+#if NFT > 0
+ || (fdsu >= DRVS_PER_CTLR)) {
+#else
) {
fd->type = NO_TYPE;
+#endif
+#if NFT > 0
+ /* If BIOS says no floppy, or > 2nd device */
+ /* Probe for and attach a floppy tape. */
+ /* Tell FT if there was already a disk */
+ /* with this unit number found. */
+
+ unithasfd = 0;
+ if (fdu < NFD && fd->type != NO_TYPE)
+ unithasfd = 1;
+ if (ftattach(dev, fdup, unithasfd))
+ continue;
+ if (fdsu < DRVS_PER_CTLR)
+ fd->type = NO_TYPE;
+#endif
continue;
}
@@ -713,7 +639,7 @@ fdattach(struct isa_device *dev)
enable_fifo(fdc) == 0) {
printf("fdc%d: FIFO enabled", fdcu);
printf(", %d bytes threshold\n",
- fifo_threshold);
+ fifo_threshold);
}
}
if ((fd_cmd(fdcu, 2, NE7CMD_SENSED, fdsu, 1, &st3) == 0) &&
@@ -856,10 +782,10 @@ fdattach(struct isa_device *dev)
}
for (i = 0; i < MAXPARTITIONS; i++) {
- fd->bdevs[1 + NUMDENS + i] = devfs_makelink(fd->bdevs[0],
+ fd->bdevs[1 + NUMDENS + i] = devfs_link(fd->bdevs[0],
"fd%d%c", fdu, 'a' + i);
fd->cdevs[1 + NUMDENS + i] =
- devfs_makelink(fd->cdevs[0],
+ devfs_link(fd->cdevs[0],
"rfd%d%c", fdu, 'a' + i);
}
#endif /* DEVFS */
@@ -878,138 +804,6 @@ fdattach(struct isa_device *dev)
-#ifdef FDC_YE
-/*
- * this is a subset of fdattach() optimized for the Y-E Data
- * PCMCIA floppy drive.
- */
-static int yeattach(struct isa_device *dev)
-{
- fdcu_t fdcu = dev->id_unit;
- fdc_p fdc = fdc_data + fdcu;
- fdsu_t fdsu = 0; /* assume 1 drive per YE controller */
- fdu_t fdu;
- fd_p fd;
- int st0, st3, i;
-#ifdef DEVFS
- int mynor;
- int typemynor;
- int typesize;
-#endif
- fdc->fdcu = fdcu;
- /*
- * the FDC_PCMCIA flag is used to to indicate special PIO is used
- * instead of DMA
- */
- fdc->flags = FDC_ATTACHED|FDC_PCMCIA;
- fdc->state = DEVIDLE;
- /* reset controller, turn motor off, clear fdout mirror reg */
- outb(fdc->baseport + FDOUT, ((fdc->fdout = 0)));
- bufq_init(&fdc->head);
- /*
- * assume 2 drives/ "normal" controller
- */
- fdu = fdcu * 2;
- if (fdu >= NFD) {
- printf("fdu %d >= NFD\n",fdu);
- return(0);
- };
- fd = &fd_data[fdu];
-
- set_motor(fdcu, fdsu, TURNON);
- DELAY(1000000); /* 1 sec */
- fdc->fdct = FDC_NE765;
-
- if ((fd_cmd(fdcu, 2, NE7CMD_SENSED, fdsu, 1, &st3) == 0) &&
- (st3 & NE7_ST3_T0)) {
- /* if at track 0, first seek inwards */
- /* seek some steps: */
- (void)fd_cmd(fdcu, 3, NE7CMD_SEEK, fdsu, 10, 0);
- DELAY(300000); /* ...wait a moment... */
- (void)fd_sense_int(fdc, 0, 0); /* make ctrlr happy */
- }
-
- /* If we're at track 0 first seek inwards. */
- if ((fd_sense_drive_status(fdc, &st3) == 0) && (st3 & NE7_ST3_T0)) {
- /* Seek some steps... */
- if (fd_cmd(fdcu, 3, NE7CMD_SEEK, fdsu, 10, 0) == 0) {
- /* ...wait a moment... */
- DELAY(300000);
- /* make ctrlr happy: */
- (void)fd_sense_int(fdc, 0, 0);
- }
- }
-
- for(i = 0; i < 2; i++) {
- /*
- * we must recalibrate twice, just in case the
- * heads have been beyond cylinder 76, since most
- * FDCs still barf when attempting to recalibrate
- * more than 77 steps
- */
- /* go back to 0: */
- if (fd_cmd(fdcu, 2, NE7CMD_RECAL, fdsu, 0) == 0) {
- /* a second being enough for full stroke seek*/
- DELAY(i == 0? 1000000: 300000);
-
- /* anything responding? */
- if (fd_sense_int(fdc, &st0, 0) == 0 &&
- (st0 & NE7_ST0_EC) == 0)
- break; /* already probed succesfully */
- }
- }
-
- set_motor(fdcu, fdsu, TURNOFF);
-
- if (st0 & NE7_ST0_EC) /* no track 0 -> no drive present */
- return(0);
-
- fd->track = FD_NO_TRACK;
- fd->fdc = fdc;
- fd->fdsu = fdsu;
- fd->options = 0;
- printf("fdc%d: 1.44MB 3.5in PCMCIA\n", fdcu);
- fd->type = FD_1440;
-
-#ifdef DEVFS
- mynor = fdcu << 6;
- fd->bdevs[0] = devfs_add_devswf(&fd_cdevsw, mynor, DV_BLK,
- UID_ROOT, GID_OPERATOR, 0640,
- "fd%d", fdu);
- fd->cdevs[0] = devfs_add_devswf(&fd_cdevsw, mynor, DV_CHR,
- UID_ROOT, GID_OPERATOR, 0640,
- "rfd%d", fdu);
- /*
- * XXX this and the lookup in Fdopen() should be
- * data driven.
- */
- typemynor = mynor | FD_1440;
- typesize = fd_types[FD_1440 - 1].size / 2;
- /*
- * XXX all these conversions give bloated code and
- * confusing names.
- */
- if (typesize == 1476)
- typesize = 1480;
- if (typesize == 1722)
- typesize = 1720;
- fd->bdevs[FD_1440] = devfs_add_devswf(&fd_cdevsw, typemynor,
- DV_BLK, UID_ROOT, GID_OPERATOR,
- 0640, "fd%d.%d", fdu, typesize);
- fd->cdevs[FD_1440] = devfs_add_devswf(&fd_cdevsw, typemynor,
- DV_CHR, UID_ROOT, GID_OPERATOR,
- 0640,"rfd%d.%d", fdu, typesize);
- for (i = 0; i < MAXPARTITIONS; i++) {
- fd->bdevs[1 + NUMDENS + i] = devfs_makelink(fd->bdevs[0],
- "fd%d%c", fdu, 'a' + i);
- fd->cdevs[1 + NUMDENS + i] = devfs_makelink(fd->cdevs[0],
- "rfd%d%c", fdu, 'a' + i);
- }
-#endif /* DEVFS */
- return (1);
-}
-#endif
-
/****************************************************************************/
/* motor control stuff */
/* remember to not deselect the drive we're working on */
@@ -1216,6 +1010,11 @@ Fdopen(dev_t dev, int flags, int mode, struct proc *p)
int type = FDTYPE(minor(dev));
fdc_p fdc;
+#if NFT > 0
+ /* check for a tape open */
+ if (type & F_TAPE_TYPE)
+ return(ftopen(dev, flags));
+#endif
/* check bounds */
if (fdu >= NFD)
return(ENXIO);
@@ -1289,6 +1088,12 @@ fdclose(dev_t dev, int flags, int mode, struct proc *p)
{
fdu_t fdu = FDUNIT(minor(dev));
+#if NFT > 0
+ int type = FDTYPE(minor(dev));
+
+ if (type & F_TAPE_TYPE)
+ return ftclose(dev, flags);
+#endif
fd_data[fdu].flags &= ~FD_OPEN;
fd_data[fdu].options &= ~FDOPT_NORETRY;
@@ -1326,18 +1131,21 @@ fdstrategy(struct buf *bp)
fd = &fd_data[fdu];
fdc = fd->fdc;
fdcu = fdc->fdcu;
-#ifdef FDC_YE
- if (fd->type == NO_TYPE) {
- bp->b_error = ENXIO;
+
+#if NFT > 0
+ if (FDTYPE(minor(bp->b_dev)) & F_TAPE_TYPE) {
+ /* ft tapes do not (yet) support strategy i/o */
+ bp->b_error = ENODEV;
bp->b_flags |= B_ERROR;
- /*
- * I _refuse_ to use a goto
- */
- biodone(bp);
- return;
- };
+ goto bad;
+ }
+ /* check for controller already busy with tape */
+ if (fdc->flags & FDC_TAPE_BUSY) {
+ bp->b_error = EBUSY;
+ bp->b_flags |= B_ERROR;
+ goto bad;
+ }
#endif
-
fdblk = 128 << (fd->ft->secsize);
if (!(bp->b_flags & B_FORMAT)) {
if ((fdu >= NFD) || (bp->b_blkno < 0)) {
@@ -1467,46 +1275,21 @@ fd_pseudointr(void *arg1)
* keep calling the state machine until it returns a 0 *
* ALWAYS called at SPLBIO *
\***********************************************************************/
-static void
+void
fdintr(fdcu_t fdcu)
{
fdc_p fdc = fdc_data + fdcu;
+#if NFT > 0
+ fdu_t fdu = fdc->fdu;
+
+ if (fdc->flags & FDC_TAPE_BUSY)
+ (ftintr(fdu));
+ else
+#endif
while(fdstate(fdcu, fdc))
;
}
-#ifdef FDC_YE
-/*
- * magic pseudo-DMA initialization for YE FDC. Sets count and
- * direction
- */
-#define SET_BCDR(wr,cnt,port) outb(port,(((cnt)-1) & 0xff)); \
- outb(port+1,((wr ? 0x80 : 0) | ((((cnt)-1) >> 8) & 0x7f)))
-
-/*
- * fdcpio(): perform programmed IO read/write for YE PCMCIA floppy
- */
-static int fdcpio(fdcu_t fdcu, long flags, caddr_t addr, u_int count)
-{
- u_char *cptr = (u_char *)addr;
- fdc_p fdc = &fdc_data[fdcu];
- int io = fdc->baseport;
-
- if (flags & B_READ) {
- if (fdc->state != PIOREAD) {
- fdc->state = PIOREAD;
- return(0);
- };
- SET_BCDR(0,count,io);
- insb(io+FDC_YE_DATAPORT,cptr,count);
- } else {
- outsb(io+FDC_YE_DATAPORT,cptr,count);
- SET_BCDR(0,count,io);
- };
- return(1);
-}
-#endif /* FDC_YE */
-
/***********************************************************************\
* The controller state machine. *
* if it returns a non zero value, it should be called again immediatly *
@@ -1514,6 +1297,7 @@ static int fdcpio(fdcu_t fdcu, long flags, caddr_t addr, u_int count)
static int
fdstate(fdcu_t fdcu, fdc_p fdc)
{
+ struct subdev *sd;
int read, format, head, i, sec = 0, sectrac, st0, cyl, st3;
unsigned blknum = 0, b_cylinder = 0;
fdu_t fdu = fdc->fdu;
@@ -1522,15 +1306,8 @@ fdstate(fdcu_t fdcu, fdc_p fdc)
struct fd_formb *finfo = NULL;
size_t fdblk;
- bp = fdc->bp;
- if (bp == NULL) {
- bp = bufq_first(&fdc->head);
- if (bp != NULL) {
- bufq_remove(&fdc->head, bp);
- fdc->bp = bp;
- }
- }
- if (bp == NULL) {
+ bp = bufq_first(&fdc->head);
+ if(!bp) {
/***********************************************\
* nothing left for this controller to do *
* Force into the IDLE state, *
@@ -1704,11 +1481,8 @@ fdstate(fdcu_t fdcu, fdc_p fdc)
}
fd->track = b_cylinder;
-#ifdef FDC_YE
- if (!(fdc->flags & FDC_PCMCIA))
-#endif
- isa_dmastart(bp->b_flags, bp->b_data+fd->skip,
- format ? bp->b_bcount : fdblk, fdc->dmachan);
+ isa_dmastart(bp->b_flags, bp->b_data+fd->skip,
+ format ? bp->b_bcount : fdblk, fdc->dmachan);
sectrac = fd->ft->sectrac;
sec = blknum % (sectrac * fd->ft->heads);
head = sec / sectrac;
@@ -1750,12 +1524,6 @@ fdstate(fdcu_t fdcu, fdc_p fdc)
if(format)
{
-#ifdef FDC_YE
- if (fdc->flags & FDC_PCMCIA)
- (void)fdcpio(fdcu,bp->b_flags,
- bp->b_data+fd->skip,
- bp->b_bcount);
-#endif
/* formatting */
if(fd_cmd(fdcu, 6,
NE7CMD_FORMAT,
@@ -1776,24 +1544,6 @@ fdstate(fdcu_t fdcu, fdc_p fdc)
}
else
{
-#ifdef FDC_YE
- if (fdc->flags & FDC_PCMCIA) {
- /*
- * this seems to be necessary even when
- * reading data
- */
- SET_BCDR(1,fdblk,fdc->baseport);
-
- /*
- * perform the write pseudo-DMA before
- * the WRITE command is sent
- */
- if (!read)
- (void)fdcpio(fdcu,bp->b_flags,
- bp->b_data+fd->skip,
- fdblk);
- }
-#endif
if (fd_cmd(fdcu, 9,
(read ? NE7CMD_READ : NE7CMD_WRITE),
head << 2 | fdu, /* head & unit */
@@ -1814,37 +1564,9 @@ fdstate(fdcu_t fdcu, fdc_p fdc)
return(retrier(fdcu));
}
}
-#ifdef FDC_YE
- if (fdc->flags & FDC_PCMCIA)
- /*
- * if this is a read, then simply await interrupt
- * before performing PIO
- */
- if (read && !fdcpio(fdcu,bp->b_flags,
- bp->b_data+fd->skip,fdblk)) {
- fd->tohandle = timeout(fd_iotimeout,
- (caddr_t)fdcu, hz);
- return(0); /* will return later */
- };
-
- /*
- * write (or format) operation will fall through and
- * await completion interrupt
- */
-#endif
fdc->state = IOCOMPLETE;
fd->tohandle = timeout(fd_iotimeout, (caddr_t)fdcu, hz);
return(0); /* will return later */
-#ifdef FDC_YE
- case PIOREAD:
- /*
- * actually perform the PIO read. The IOCOMPLETE case
- * removes the timeout for us.
- */
- (void)fdcpio(fdcu,bp->b_flags,bp->b_data+fd->skip,fdblk);
- fdc->state = IOCOMPLETE;
- /* FALLTHROUGH */
-#endif
case IOCOMPLETE: /* IO DONE, post-analyze */
untimeout(fd_iotimeout, (caddr_t)fdcu, fd->tohandle);
@@ -1863,11 +1585,8 @@ fdstate(fdcu_t fdcu, fdc_p fdc)
/* FALLTHROUGH */
case IOTIMEDOUT:
-#ifdef FDC_YE
- if (!(fdc->flags & FDC_PCMCIA))
-#endif
- isa_dmadone(bp->b_flags, bp->b_data + fd->skip,
- format ? bp->b_bcount : fdblk, fdc->dmachan);
+ isa_dmadone(bp->b_flags, bp->b_data + fd->skip,
+ format ? bp->b_bcount : fdblk, fdc->dmachan);
if (fdc->status[0] & NE7_ST0_IC)
{
if ((fdc->status[0] & NE7_ST0_IC) == NE7_ST0_IC_AT
@@ -1902,7 +1621,7 @@ fdstate(fdcu_t fdcu, fdc_p fdc)
{
/* ALL DONE */
fd->skip = 0;
- fdc->bp = NULL;
+ bufq_remove(&fdc->head, bp);
/* Tell devstat we have finished with the transaction */
devstat_end_transaction(&fd->device_stats,
bp->b_bcount - bp->b_resid,
@@ -2022,10 +1741,12 @@ static int
retrier(fdcu)
fdcu_t fdcu;
{
+ struct subdev *sd;
fdc_p fdc = fdc_data + fdcu;
register struct buf *bp;
+ int fdu;
- bp = fdc->bp;
+ bp = bufq_first(&fdc->head);
if(fd_data[FDUNIT(minor(bp->b_dev))].options & FDOPT_NORETRY)
goto fail;
@@ -2069,7 +1790,7 @@ retrier(fdcu)
bp->b_flags |= B_ERROR;
bp->b_error = EIO;
bp->b_resid += bp->b_bcount - fdc->fd->skip;
- fdc->bp = NULL;
+ bufq_remove(&fdc->head, bp);
/* Tell devstat we have finished with the transaction */
devstat_end_transaction(&fdc->fd->device_stats,
@@ -2178,6 +1899,14 @@ fdioctl(dev, cmd, addr, flag, p)
char buffer[DEV_BSIZE];
int error = 0;
+#if NFT > 0
+ int type = FDTYPE(minor(dev));
+
+ /* check for a tape ioctl */
+ if (type & F_TAPE_TYPE)
+ return ftioctl(dev, cmd, addr, flag, p);
+#endif
+
fdblk = 128 << fd->ft->secsize;
switch (cmd)