Add floppy tape driver - fd => fdc
This commit is contained in:
parent
a38943d9a0
commit
b99f0a4a8d
Notes:
svn2git
2020-12-20 02:59:44 +00:00
svn path=/head/; revision=1110
@ -35,36 +35,40 @@
|
||||
* SUCH DAMAGE.
|
||||
*
|
||||
* from: @(#)fd.c 7.4 (Berkeley) 5/25/91
|
||||
* $Id: fd.c,v 1.17 1993/12/19 00:50:33 wollman Exp $
|
||||
* $from: fd.c,v 1.18 1993/12/21 05:09:21 ache Exp $
|
||||
*
|
||||
*/
|
||||
|
||||
#include "ft.h"
|
||||
#if NFT < 1
|
||||
#undef NFDC
|
||||
#endif
|
||||
#include "fd.h"
|
||||
#if NFD > 0
|
||||
|
||||
#include "param.h"
|
||||
#include "dkbad.h"
|
||||
#include "systm.h"
|
||||
#include "kernel.h"
|
||||
#include "conf.h"
|
||||
#include "file.h"
|
||||
#include "ioctl.h"
|
||||
#include "machine/ioctl_fd.h"
|
||||
#include "disklabel.h"
|
||||
#include "buf.h"
|
||||
#include "uio.h"
|
||||
#include "malloc.h"
|
||||
#include "syslog.h"
|
||||
#if NFDC > 0
|
||||
|
||||
#include <sys/param.h>
|
||||
#include <sys/dkbad.h>
|
||||
#include <sys/systm.h>
|
||||
#include <sys/kernel.h>
|
||||
#include <sys/conf.h>
|
||||
#include <sys/file.h>
|
||||
#include <sys/ioctl.h>
|
||||
#include <machine/ioctl_fd.h>
|
||||
#include <sys/disklabel.h>
|
||||
#include <sys/buf.h>
|
||||
#include <sys/uio.h>
|
||||
#include <sys/malloc.h>
|
||||
#include <sys/syslog.h>
|
||||
#include "i386/isa/isa.h"
|
||||
#include "i386/isa/isa_device.h"
|
||||
#include "i386/isa/fdreg.h"
|
||||
#include "i386/isa/icu.h"
|
||||
#include "i386/isa/rtc.h"
|
||||
#undef NFD
|
||||
#define NFD 2
|
||||
|
||||
#define FDUNIT(s) (((s)>>6)&03)
|
||||
#define FDTYPE(s) ((s)&077)
|
||||
#if NFT > 0
|
||||
extern int ftopen(), ftintr(), ftattach(), ftclose(), ftioctl();
|
||||
#endif
|
||||
|
||||
#define b_cylin b_resid
|
||||
#define FDBLK 512
|
||||
@ -75,22 +79,25 @@
|
||||
#define NUMTYPES 14
|
||||
#define NUMDENS (NUMTYPES - 6)
|
||||
|
||||
/* This defines must match fd_types */
|
||||
#define FD_1720 0
|
||||
#define FD_1480 1
|
||||
#define FD_1440 2
|
||||
#define FD_1200 3
|
||||
#define FD_820 4
|
||||
#define FD_800 5
|
||||
#define FD_720 6
|
||||
#define FD_360 7
|
||||
/* This defines (-1) must match index for fd_types */
|
||||
#define F_TAPE_TYPE 0x020 /* bit for fd_types to indicate tape */
|
||||
#define NO_TYPE 0 /* must match NO_TYPE in ft.c */
|
||||
#define FD_1720 1
|
||||
#define FD_1480 2
|
||||
#define FD_1440 3
|
||||
#define FD_1200 4
|
||||
#define FD_820 5
|
||||
#define FD_800 6
|
||||
#define FD_720 7
|
||||
#define FD_360 8
|
||||
|
||||
#define FD_1480in5_25 9
|
||||
#define FD_1440in5_25 10
|
||||
#define FD_820in5_25 11
|
||||
#define FD_800in5_25 12
|
||||
#define FD_720in5_25 13
|
||||
#define FD_360in5_25 14
|
||||
|
||||
#define FD_1480in5_25 8
|
||||
#define FD_1440in5_25 9
|
||||
#define FD_820in5_25 10
|
||||
#define FD_800in5_25 11
|
||||
#define FD_720in5_25 12
|
||||
#define FD_360in5_25 13
|
||||
|
||||
struct fd_type fd_types[NUMTYPES] =
|
||||
{
|
||||
@ -111,33 +118,18 @@ struct fd_type fd_types[NUMTYPES] =
|
||||
{ 9,2,0xFF,0x23,40, 720,2,FDC_300KBPS,2,0x50,1 }, /* 360K in HD 5.25in */
|
||||
};
|
||||
|
||||
#define DRVS_PER_CTLR 2
|
||||
#define DRVS_PER_CTLR 2 /* 2 floppies */
|
||||
/***********************************************************************\
|
||||
* Per controller structure. *
|
||||
\***********************************************************************/
|
||||
struct fdc_data
|
||||
{
|
||||
int fdcu; /* our unit number */
|
||||
int baseport;
|
||||
int dmachan;
|
||||
int flags;
|
||||
#define FDC_ATTACHED 0x01
|
||||
struct fd_data *fd;
|
||||
int fdu; /* the active drive */
|
||||
struct buf head; /* Head of buf chain */
|
||||
struct buf rhead; /* Raw head of buf chain */
|
||||
int state;
|
||||
int retry;
|
||||
int status[7]; /* copy of the registers */
|
||||
}fdc_data[(NFD+1)/DRVS_PER_CTLR];
|
||||
struct fdc_data fdc_data[NFDC];
|
||||
|
||||
/***********************************************************************\
|
||||
* Per drive structure. *
|
||||
* N per controller (presently 2) (DRVS_PER_CTLR) *
|
||||
* N per controller (DRVS_PER_CTLR) *
|
||||
\***********************************************************************/
|
||||
struct fd_data {
|
||||
struct fdc_data *fdc;
|
||||
int fdu; /* this unit number */
|
||||
struct fdc_data *fdc; /* pointer to controller structure */
|
||||
int fdsu; /* this units number on this controller */
|
||||
int type; /* Drive type (HD, DD */
|
||||
struct fd_type *ft; /* pointer to the type descriptor */
|
||||
@ -159,11 +151,9 @@ struct fd_data {
|
||||
* fdcu is the floppy controller unit number *
|
||||
* fdsu is the floppy drive unit number on that controller. (sub-unit) *
|
||||
\***********************************************************************/
|
||||
typedef int fdu_t;
|
||||
typedef int fdcu_t;
|
||||
typedef int fdsu_t;
|
||||
typedef struct fd_data *fd_p;
|
||||
typedef struct fdc_data *fdc_p;
|
||||
|
||||
#define id_physid id_scsiid /* this biotab field doubles as a field */
|
||||
/* for the physical unit number on the controller */
|
||||
|
||||
static int retrier(fdcu_t);
|
||||
|
||||
@ -216,8 +206,8 @@ static void fd_turnoff(caddr_t, int);
|
||||
static int fdprobe(struct isa_device *);
|
||||
static int fdattach(struct isa_device *);
|
||||
|
||||
struct isa_driver fddriver = {
|
||||
fdprobe, fdattach, "fd",
|
||||
struct isa_driver fdcdriver = {
|
||||
fdprobe, fdattach, "fdc",
|
||||
};
|
||||
|
||||
/*
|
||||
@ -266,24 +256,48 @@ fdattach(dev)
|
||||
fdc_p fdc = fdc_data + fdcu;
|
||||
fd_p fd;
|
||||
int fdsu;
|
||||
struct isa_device *fdup;
|
||||
|
||||
fdc->fdcu = fdcu;
|
||||
fdc->flags |= FDC_ATTACHED;
|
||||
fdc->dmachan = dev->id_drq;
|
||||
fdc->state = DEVIDLE;
|
||||
|
||||
fdt = rtcin(RTC_FDISKETTE);
|
||||
hdr = 0;
|
||||
printf("fdc%d:", fdcu);
|
||||
|
||||
/* check for each floppy drive */
|
||||
for (fdu = (fdcu * DRVS_PER_CTLR),fdsu = 0;
|
||||
((fdu < NFD) && (fdsu < DRVS_PER_CTLR));
|
||||
fdu++,fdsu++)
|
||||
{
|
||||
for (fdup = isa_biotab_fdc; fdup->id_driver != 0; fdup++) {
|
||||
if (fdup->id_iobase != dev->id_iobase)
|
||||
continue;
|
||||
fdu = fdup->id_unit;
|
||||
fd = &fd_data[fdu];
|
||||
if (fdu >= (NFD+NFT))
|
||||
continue;
|
||||
fdsu = fdup->id_physid;
|
||||
/* look up what bios thinks we have */
|
||||
switch (fdu) {
|
||||
case 0: fdt = (rtcin(RTC_FDISKETTE) & 0xf0);
|
||||
break;
|
||||
case 1: fdt = ((rtcin(RTC_FDISKETTE) << 4) & 0xf0);
|
||||
break;
|
||||
default: fdt = RTCFDT_NONE;
|
||||
break;
|
||||
}
|
||||
/* is there a unit? */
|
||||
if ((fdt & 0xf0) == RTCFDT_NONE) {
|
||||
#define NO_TYPE NUMTYPES
|
||||
fd_data[fdu].type = NO_TYPE;
|
||||
if ((fdt == RTCFDT_NONE)
|
||||
#if NFT > 0
|
||||
|| (fdsu >= DRVS_PER_CTLR)) {
|
||||
#else
|
||||
) {
|
||||
#endif
|
||||
#if NFT > 0
|
||||
/* If BIOS says no floppy, or > 2nd device */
|
||||
/* Probe for and attach a floppy tape. */
|
||||
if (ftattach(dev, fdup))
|
||||
continue;
|
||||
|
||||
#endif
|
||||
fd->type = NO_TYPE;
|
||||
continue;
|
||||
}
|
||||
|
||||
@ -303,38 +317,38 @@ fdattach(dev)
|
||||
continue;
|
||||
|
||||
#endif
|
||||
fd_data[fdu].track = -2;
|
||||
fd_data[fdu].fdc = fdc;
|
||||
fd_data[fdu].fdsu = fdsu;
|
||||
printf("fd%d: unit %d type ", fdcu, fdu);
|
||||
fd->track = -2;
|
||||
fd->fdc = fdc;
|
||||
fd->fdsu = fdsu;
|
||||
printf(" [%d: fd%d: ", fdsu, fdu);
|
||||
|
||||
switch (fdt & 0xf0) {
|
||||
switch (fdt) {
|
||||
case RTCFDT_12M:
|
||||
printf("1.2MB 5.25in\n");
|
||||
fd_data[fdu].type = FD_1200;
|
||||
printf("1.2MB 5.25in]");
|
||||
fd->type = FD_1200;
|
||||
break;
|
||||
case RTCFDT_144M:
|
||||
printf("1.44MB 3.5in\n");
|
||||
fd_data[fdu].type = FD_1440;
|
||||
printf("1.44MB 3.5in]");
|
||||
fd->type = FD_1440;
|
||||
break;
|
||||
case RTCFDT_360K:
|
||||
printf("360KB 5.25in\n");
|
||||
fd_data[fdu].type = FD_360;
|
||||
printf("360KB 5.25in]");
|
||||
fd->type = FD_360;
|
||||
break;
|
||||
case RTCFDT_720K:
|
||||
printf("720KB 3.5in\n");
|
||||
fd_data[fdu].type = FD_720;
|
||||
printf("720KB 3.5in]");
|
||||
fd->type = FD_720;
|
||||
break;
|
||||
default:
|
||||
printf("unknown\n");
|
||||
fd_data[fdu].type = NO_TYPE;
|
||||
printf("unknown]");
|
||||
fd->type = NO_TYPE;
|
||||
break;
|
||||
}
|
||||
|
||||
fdt <<= 4;
|
||||
fd_turnoff((caddr_t)fdu, 0);
|
||||
hdr = 1;
|
||||
}
|
||||
printf("\n");
|
||||
|
||||
/* Set transfer to 500kbps */
|
||||
outb(fdc->baseport+fdctl,0); /*XXX*/
|
||||
@ -365,9 +379,16 @@ void fdstrategy(struct buf *bp)
|
||||
fd = &fd_data[fdu];
|
||||
fdc = fd->fdc;
|
||||
fdcu = fdc->fdcu;
|
||||
/*type = FDTYPE(minor(bp->b_dev));*/
|
||||
|
||||
if ((fdu >= NFD) || (bp->b_blkno < 0)) {
|
||||
#if NFT > 0
|
||||
/* check for controller already busy with tape */
|
||||
if (fdc->flags & FDC_TAPE_BUSY) {
|
||||
bp->b_error = EBUSY;
|
||||
bp->b_flags |= B_ERROR;
|
||||
return;
|
||||
}
|
||||
#endif
|
||||
if ((fdu >= (NFD+NFT)) || (bp->b_blkno < 0)) {
|
||||
printf("fdstrat: fdu = %d, blkno = %d, bcount = %d\n",
|
||||
fdu, bp->b_blkno, bp->b_bcount);
|
||||
pg("fd:error in fdstrategy");
|
||||
@ -547,16 +568,24 @@ Fdopen(dev, flags)
|
||||
{
|
||||
fdu_t fdu = FDUNIT(minor(dev));
|
||||
int type = FDTYPE(minor(dev));
|
||||
int s;
|
||||
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 || fd_data[fdu].fdc == NULL
|
||||
|| fd_data[fdu].type == NO_TYPE) return(ENXIO);
|
||||
if (type > NUMDENS) return(ENXIO);
|
||||
if (fdu >= NFD)
|
||||
return(ENXIO);
|
||||
fdc = fd_data[fdu].fdc;
|
||||
if ((fdc == NULL) || (fd_data[fdu].type == NO_TYPE))
|
||||
return(ENXIO);
|
||||
if (type > NUMDENS)
|
||||
return(ENXIO);
|
||||
if (type == 0)
|
||||
type = fd_data[fdu].type;
|
||||
else {
|
||||
type--;
|
||||
if (type != fd_data[fdu].type) {
|
||||
switch (fd_data[fdu].type) {
|
||||
case FD_360:
|
||||
@ -604,7 +633,7 @@ Fdopen(dev, flags)
|
||||
}
|
||||
}
|
||||
}
|
||||
fd_data[fdu].ft = fd_types + type;
|
||||
fd_data[fdu].ft = fd_types + type - 1;
|
||||
fd_data[fdu].flags |= FD_OPEN;
|
||||
|
||||
return 0;
|
||||
@ -616,6 +645,12 @@ fdclose(dev, flags)
|
||||
int flags;
|
||||
{
|
||||
fdu_t fdu = FDUNIT(minor(dev));
|
||||
int type = FDTYPE(minor(dev));
|
||||
|
||||
#if NFT > 0
|
||||
if (type & F_TAPE_TYPE)
|
||||
return ftclose(0);
|
||||
#endif
|
||||
fd_data[fdu].flags &= ~FD_OPEN;
|
||||
return(0);
|
||||
}
|
||||
@ -712,6 +747,13 @@ 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))
|
||||
;
|
||||
}
|
||||
@ -829,8 +871,8 @@ fdstate(fdcu, fdc)
|
||||
cyl = in_fdc(fdcu);
|
||||
if (cyl != descyl)
|
||||
{
|
||||
printf("fd%d: Seek to cyl %d failed; am at cyl %d (ST0 = 0x%x)\n", fdu,
|
||||
descyl, cyl, i, NE7_ST0BITS);
|
||||
printf("fd%d: Seek to cyl %d failed; am at cyl %d (ST0 = 0x%x)\n",
|
||||
fdu, descyl, cyl, i, NE7_ST0BITS);
|
||||
return(retrier(fdcu));
|
||||
}
|
||||
}
|
||||
@ -1130,6 +1172,11 @@ fdioctl (dev, cmd, addr, flag, p)
|
||||
char buffer[DEV_BSIZE];
|
||||
int error;
|
||||
|
||||
#if NFT > 0
|
||||
if (fd_data[FDUNIT(minor(dev))].fdc->flags & FDC_TAPE_BUSY)
|
||||
return ftioctl(dev, cmd, addr, flag, p);
|
||||
#endif
|
||||
|
||||
error = 0;
|
||||
|
||||
switch (cmd)
|
||||
|
@ -31,7 +31,7 @@
|
||||
* SUCH DAMAGE.
|
||||
*
|
||||
* from: @(#)fdreg.h 7.1 (Berkeley) 5/9/91
|
||||
* $Id$
|
||||
* $Id: fdreg.h,v 1.2 1993/10/16 13:45:50 rgrimes Exp $
|
||||
*/
|
||||
|
||||
/*
|
||||
@ -63,4 +63,41 @@
|
||||
#define fdin 7 /* Digital Input Register (R) */
|
||||
#define FDI_DCHG 0x80 /* diskette has been changed */
|
||||
|
||||
/***********************************************************************\
|
||||
* Per controller structure. *
|
||||
\***********************************************************************/
|
||||
struct fdc_data
|
||||
{
|
||||
int fdcu; /* our unit number */
|
||||
int baseport;
|
||||
int dmachan;
|
||||
int flags;
|
||||
#define FDC_ATTACHED 0x01
|
||||
#define FDC_HASFTAPE 0x02
|
||||
#define FDC_TAPE_BUSY 0x04
|
||||
struct fd_data *fd;
|
||||
int fdu; /* the active drive */
|
||||
struct buf head; /* Head of buf chain */
|
||||
struct buf rhead; /* Raw head of buf chain */
|
||||
int state;
|
||||
int retry;
|
||||
int status[7]; /* copy of the registers */
|
||||
};
|
||||
|
||||
/***********************************************************************\
|
||||
* Throughout this file the following conventions will be used: *
|
||||
* fd is a pointer to the fd_data struct for the drive in question *
|
||||
* fdc is a pointer to the fdc_data struct for the controller *
|
||||
* fdu is the floppy drive unit number *
|
||||
* fdcu is the floppy controller unit number *
|
||||
* fdsu is the floppy drive unit number on that controller. (sub-unit) *
|
||||
\***********************************************************************/
|
||||
typedef int fdu_t;
|
||||
typedef int fdcu_t;
|
||||
typedef int fdsu_t;
|
||||
typedef struct fd_data *fd_p;
|
||||
typedef struct fdc_data *fdc_p;
|
||||
|
||||
|
||||
#define FDUNIT(s) (((s)>>6)&03)
|
||||
#define FDTYPE(s) ((s)&077)
|
||||
|
@ -35,36 +35,40 @@
|
||||
* SUCH DAMAGE.
|
||||
*
|
||||
* from: @(#)fd.c 7.4 (Berkeley) 5/25/91
|
||||
* $Id: fd.c,v 1.17 1993/12/19 00:50:33 wollman Exp $
|
||||
* $from: fd.c,v 1.18 1993/12/21 05:09:21 ache Exp $
|
||||
*
|
||||
*/
|
||||
|
||||
#include "ft.h"
|
||||
#if NFT < 1
|
||||
#undef NFDC
|
||||
#endif
|
||||
#include "fd.h"
|
||||
#if NFD > 0
|
||||
|
||||
#include "param.h"
|
||||
#include "dkbad.h"
|
||||
#include "systm.h"
|
||||
#include "kernel.h"
|
||||
#include "conf.h"
|
||||
#include "file.h"
|
||||
#include "ioctl.h"
|
||||
#include "machine/ioctl_fd.h"
|
||||
#include "disklabel.h"
|
||||
#include "buf.h"
|
||||
#include "uio.h"
|
||||
#include "malloc.h"
|
||||
#include "syslog.h"
|
||||
#if NFDC > 0
|
||||
|
||||
#include <sys/param.h>
|
||||
#include <sys/dkbad.h>
|
||||
#include <sys/systm.h>
|
||||
#include <sys/kernel.h>
|
||||
#include <sys/conf.h>
|
||||
#include <sys/file.h>
|
||||
#include <sys/ioctl.h>
|
||||
#include <machine/ioctl_fd.h>
|
||||
#include <sys/disklabel.h>
|
||||
#include <sys/buf.h>
|
||||
#include <sys/uio.h>
|
||||
#include <sys/malloc.h>
|
||||
#include <sys/syslog.h>
|
||||
#include "i386/isa/isa.h"
|
||||
#include "i386/isa/isa_device.h"
|
||||
#include "i386/isa/fdreg.h"
|
||||
#include "i386/isa/icu.h"
|
||||
#include "i386/isa/rtc.h"
|
||||
#undef NFD
|
||||
#define NFD 2
|
||||
|
||||
#define FDUNIT(s) (((s)>>6)&03)
|
||||
#define FDTYPE(s) ((s)&077)
|
||||
#if NFT > 0
|
||||
extern int ftopen(), ftintr(), ftattach(), ftclose(), ftioctl();
|
||||
#endif
|
||||
|
||||
#define b_cylin b_resid
|
||||
#define FDBLK 512
|
||||
@ -75,22 +79,25 @@
|
||||
#define NUMTYPES 14
|
||||
#define NUMDENS (NUMTYPES - 6)
|
||||
|
||||
/* This defines must match fd_types */
|
||||
#define FD_1720 0
|
||||
#define FD_1480 1
|
||||
#define FD_1440 2
|
||||
#define FD_1200 3
|
||||
#define FD_820 4
|
||||
#define FD_800 5
|
||||
#define FD_720 6
|
||||
#define FD_360 7
|
||||
/* This defines (-1) must match index for fd_types */
|
||||
#define F_TAPE_TYPE 0x020 /* bit for fd_types to indicate tape */
|
||||
#define NO_TYPE 0 /* must match NO_TYPE in ft.c */
|
||||
#define FD_1720 1
|
||||
#define FD_1480 2
|
||||
#define FD_1440 3
|
||||
#define FD_1200 4
|
||||
#define FD_820 5
|
||||
#define FD_800 6
|
||||
#define FD_720 7
|
||||
#define FD_360 8
|
||||
|
||||
#define FD_1480in5_25 9
|
||||
#define FD_1440in5_25 10
|
||||
#define FD_820in5_25 11
|
||||
#define FD_800in5_25 12
|
||||
#define FD_720in5_25 13
|
||||
#define FD_360in5_25 14
|
||||
|
||||
#define FD_1480in5_25 8
|
||||
#define FD_1440in5_25 9
|
||||
#define FD_820in5_25 10
|
||||
#define FD_800in5_25 11
|
||||
#define FD_720in5_25 12
|
||||
#define FD_360in5_25 13
|
||||
|
||||
struct fd_type fd_types[NUMTYPES] =
|
||||
{
|
||||
@ -111,33 +118,18 @@ struct fd_type fd_types[NUMTYPES] =
|
||||
{ 9,2,0xFF,0x23,40, 720,2,FDC_300KBPS,2,0x50,1 }, /* 360K in HD 5.25in */
|
||||
};
|
||||
|
||||
#define DRVS_PER_CTLR 2
|
||||
#define DRVS_PER_CTLR 2 /* 2 floppies */
|
||||
/***********************************************************************\
|
||||
* Per controller structure. *
|
||||
\***********************************************************************/
|
||||
struct fdc_data
|
||||
{
|
||||
int fdcu; /* our unit number */
|
||||
int baseport;
|
||||
int dmachan;
|
||||
int flags;
|
||||
#define FDC_ATTACHED 0x01
|
||||
struct fd_data *fd;
|
||||
int fdu; /* the active drive */
|
||||
struct buf head; /* Head of buf chain */
|
||||
struct buf rhead; /* Raw head of buf chain */
|
||||
int state;
|
||||
int retry;
|
||||
int status[7]; /* copy of the registers */
|
||||
}fdc_data[(NFD+1)/DRVS_PER_CTLR];
|
||||
struct fdc_data fdc_data[NFDC];
|
||||
|
||||
/***********************************************************************\
|
||||
* Per drive structure. *
|
||||
* N per controller (presently 2) (DRVS_PER_CTLR) *
|
||||
* N per controller (DRVS_PER_CTLR) *
|
||||
\***********************************************************************/
|
||||
struct fd_data {
|
||||
struct fdc_data *fdc;
|
||||
int fdu; /* this unit number */
|
||||
struct fdc_data *fdc; /* pointer to controller structure */
|
||||
int fdsu; /* this units number on this controller */
|
||||
int type; /* Drive type (HD, DD */
|
||||
struct fd_type *ft; /* pointer to the type descriptor */
|
||||
@ -159,11 +151,9 @@ struct fd_data {
|
||||
* fdcu is the floppy controller unit number *
|
||||
* fdsu is the floppy drive unit number on that controller. (sub-unit) *
|
||||
\***********************************************************************/
|
||||
typedef int fdu_t;
|
||||
typedef int fdcu_t;
|
||||
typedef int fdsu_t;
|
||||
typedef struct fd_data *fd_p;
|
||||
typedef struct fdc_data *fdc_p;
|
||||
|
||||
#define id_physid id_scsiid /* this biotab field doubles as a field */
|
||||
/* for the physical unit number on the controller */
|
||||
|
||||
static int retrier(fdcu_t);
|
||||
|
||||
@ -216,8 +206,8 @@ static void fd_turnoff(caddr_t, int);
|
||||
static int fdprobe(struct isa_device *);
|
||||
static int fdattach(struct isa_device *);
|
||||
|
||||
struct isa_driver fddriver = {
|
||||
fdprobe, fdattach, "fd",
|
||||
struct isa_driver fdcdriver = {
|
||||
fdprobe, fdattach, "fdc",
|
||||
};
|
||||
|
||||
/*
|
||||
@ -266,24 +256,48 @@ fdattach(dev)
|
||||
fdc_p fdc = fdc_data + fdcu;
|
||||
fd_p fd;
|
||||
int fdsu;
|
||||
struct isa_device *fdup;
|
||||
|
||||
fdc->fdcu = fdcu;
|
||||
fdc->flags |= FDC_ATTACHED;
|
||||
fdc->dmachan = dev->id_drq;
|
||||
fdc->state = DEVIDLE;
|
||||
|
||||
fdt = rtcin(RTC_FDISKETTE);
|
||||
hdr = 0;
|
||||
printf("fdc%d:", fdcu);
|
||||
|
||||
/* check for each floppy drive */
|
||||
for (fdu = (fdcu * DRVS_PER_CTLR),fdsu = 0;
|
||||
((fdu < NFD) && (fdsu < DRVS_PER_CTLR));
|
||||
fdu++,fdsu++)
|
||||
{
|
||||
for (fdup = isa_biotab_fdc; fdup->id_driver != 0; fdup++) {
|
||||
if (fdup->id_iobase != dev->id_iobase)
|
||||
continue;
|
||||
fdu = fdup->id_unit;
|
||||
fd = &fd_data[fdu];
|
||||
if (fdu >= (NFD+NFT))
|
||||
continue;
|
||||
fdsu = fdup->id_physid;
|
||||
/* look up what bios thinks we have */
|
||||
switch (fdu) {
|
||||
case 0: fdt = (rtcin(RTC_FDISKETTE) & 0xf0);
|
||||
break;
|
||||
case 1: fdt = ((rtcin(RTC_FDISKETTE) << 4) & 0xf0);
|
||||
break;
|
||||
default: fdt = RTCFDT_NONE;
|
||||
break;
|
||||
}
|
||||
/* is there a unit? */
|
||||
if ((fdt & 0xf0) == RTCFDT_NONE) {
|
||||
#define NO_TYPE NUMTYPES
|
||||
fd_data[fdu].type = NO_TYPE;
|
||||
if ((fdt == RTCFDT_NONE)
|
||||
#if NFT > 0
|
||||
|| (fdsu >= DRVS_PER_CTLR)) {
|
||||
#else
|
||||
) {
|
||||
#endif
|
||||
#if NFT > 0
|
||||
/* If BIOS says no floppy, or > 2nd device */
|
||||
/* Probe for and attach a floppy tape. */
|
||||
if (ftattach(dev, fdup))
|
||||
continue;
|
||||
|
||||
#endif
|
||||
fd->type = NO_TYPE;
|
||||
continue;
|
||||
}
|
||||
|
||||
@ -303,38 +317,38 @@ fdattach(dev)
|
||||
continue;
|
||||
|
||||
#endif
|
||||
fd_data[fdu].track = -2;
|
||||
fd_data[fdu].fdc = fdc;
|
||||
fd_data[fdu].fdsu = fdsu;
|
||||
printf("fd%d: unit %d type ", fdcu, fdu);
|
||||
fd->track = -2;
|
||||
fd->fdc = fdc;
|
||||
fd->fdsu = fdsu;
|
||||
printf(" [%d: fd%d: ", fdsu, fdu);
|
||||
|
||||
switch (fdt & 0xf0) {
|
||||
switch (fdt) {
|
||||
case RTCFDT_12M:
|
||||
printf("1.2MB 5.25in\n");
|
||||
fd_data[fdu].type = FD_1200;
|
||||
printf("1.2MB 5.25in]");
|
||||
fd->type = FD_1200;
|
||||
break;
|
||||
case RTCFDT_144M:
|
||||
printf("1.44MB 3.5in\n");
|
||||
fd_data[fdu].type = FD_1440;
|
||||
printf("1.44MB 3.5in]");
|
||||
fd->type = FD_1440;
|
||||
break;
|
||||
case RTCFDT_360K:
|
||||
printf("360KB 5.25in\n");
|
||||
fd_data[fdu].type = FD_360;
|
||||
printf("360KB 5.25in]");
|
||||
fd->type = FD_360;
|
||||
break;
|
||||
case RTCFDT_720K:
|
||||
printf("720KB 3.5in\n");
|
||||
fd_data[fdu].type = FD_720;
|
||||
printf("720KB 3.5in]");
|
||||
fd->type = FD_720;
|
||||
break;
|
||||
default:
|
||||
printf("unknown\n");
|
||||
fd_data[fdu].type = NO_TYPE;
|
||||
printf("unknown]");
|
||||
fd->type = NO_TYPE;
|
||||
break;
|
||||
}
|
||||
|
||||
fdt <<= 4;
|
||||
fd_turnoff((caddr_t)fdu, 0);
|
||||
hdr = 1;
|
||||
}
|
||||
printf("\n");
|
||||
|
||||
/* Set transfer to 500kbps */
|
||||
outb(fdc->baseport+fdctl,0); /*XXX*/
|
||||
@ -365,9 +379,16 @@ void fdstrategy(struct buf *bp)
|
||||
fd = &fd_data[fdu];
|
||||
fdc = fd->fdc;
|
||||
fdcu = fdc->fdcu;
|
||||
/*type = FDTYPE(minor(bp->b_dev));*/
|
||||
|
||||
if ((fdu >= NFD) || (bp->b_blkno < 0)) {
|
||||
#if NFT > 0
|
||||
/* check for controller already busy with tape */
|
||||
if (fdc->flags & FDC_TAPE_BUSY) {
|
||||
bp->b_error = EBUSY;
|
||||
bp->b_flags |= B_ERROR;
|
||||
return;
|
||||
}
|
||||
#endif
|
||||
if ((fdu >= (NFD+NFT)) || (bp->b_blkno < 0)) {
|
||||
printf("fdstrat: fdu = %d, blkno = %d, bcount = %d\n",
|
||||
fdu, bp->b_blkno, bp->b_bcount);
|
||||
pg("fd:error in fdstrategy");
|
||||
@ -547,16 +568,24 @@ Fdopen(dev, flags)
|
||||
{
|
||||
fdu_t fdu = FDUNIT(minor(dev));
|
||||
int type = FDTYPE(minor(dev));
|
||||
int s;
|
||||
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 || fd_data[fdu].fdc == NULL
|
||||
|| fd_data[fdu].type == NO_TYPE) return(ENXIO);
|
||||
if (type > NUMDENS) return(ENXIO);
|
||||
if (fdu >= NFD)
|
||||
return(ENXIO);
|
||||
fdc = fd_data[fdu].fdc;
|
||||
if ((fdc == NULL) || (fd_data[fdu].type == NO_TYPE))
|
||||
return(ENXIO);
|
||||
if (type > NUMDENS)
|
||||
return(ENXIO);
|
||||
if (type == 0)
|
||||
type = fd_data[fdu].type;
|
||||
else {
|
||||
type--;
|
||||
if (type != fd_data[fdu].type) {
|
||||
switch (fd_data[fdu].type) {
|
||||
case FD_360:
|
||||
@ -604,7 +633,7 @@ Fdopen(dev, flags)
|
||||
}
|
||||
}
|
||||
}
|
||||
fd_data[fdu].ft = fd_types + type;
|
||||
fd_data[fdu].ft = fd_types + type - 1;
|
||||
fd_data[fdu].flags |= FD_OPEN;
|
||||
|
||||
return 0;
|
||||
@ -616,6 +645,12 @@ fdclose(dev, flags)
|
||||
int flags;
|
||||
{
|
||||
fdu_t fdu = FDUNIT(minor(dev));
|
||||
int type = FDTYPE(minor(dev));
|
||||
|
||||
#if NFT > 0
|
||||
if (type & F_TAPE_TYPE)
|
||||
return ftclose(0);
|
||||
#endif
|
||||
fd_data[fdu].flags &= ~FD_OPEN;
|
||||
return(0);
|
||||
}
|
||||
@ -712,6 +747,13 @@ 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))
|
||||
;
|
||||
}
|
||||
@ -829,8 +871,8 @@ fdstate(fdcu, fdc)
|
||||
cyl = in_fdc(fdcu);
|
||||
if (cyl != descyl)
|
||||
{
|
||||
printf("fd%d: Seek to cyl %d failed; am at cyl %d (ST0 = 0x%x)\n", fdu,
|
||||
descyl, cyl, i, NE7_ST0BITS);
|
||||
printf("fd%d: Seek to cyl %d failed; am at cyl %d (ST0 = 0x%x)\n",
|
||||
fdu, descyl, cyl, i, NE7_ST0BITS);
|
||||
return(retrier(fdcu));
|
||||
}
|
||||
}
|
||||
@ -1130,6 +1172,11 @@ fdioctl (dev, cmd, addr, flag, p)
|
||||
char buffer[DEV_BSIZE];
|
||||
int error;
|
||||
|
||||
#if NFT > 0
|
||||
if (fd_data[FDUNIT(minor(dev))].fdc->flags & FDC_TAPE_BUSY)
|
||||
return ftioctl(dev, cmd, addr, flag, p);
|
||||
#endif
|
||||
|
||||
error = 0;
|
||||
|
||||
switch (cmd)
|
||||
|
@ -31,7 +31,7 @@
|
||||
* SUCH DAMAGE.
|
||||
*
|
||||
* from: @(#)fdreg.h 7.1 (Berkeley) 5/9/91
|
||||
* $Id$
|
||||
* $Id: fdreg.h,v 1.2 1993/10/16 13:45:50 rgrimes Exp $
|
||||
*/
|
||||
|
||||
/*
|
||||
@ -63,4 +63,41 @@
|
||||
#define fdin 7 /* Digital Input Register (R) */
|
||||
#define FDI_DCHG 0x80 /* diskette has been changed */
|
||||
|
||||
/***********************************************************************\
|
||||
* Per controller structure. *
|
||||
\***********************************************************************/
|
||||
struct fdc_data
|
||||
{
|
||||
int fdcu; /* our unit number */
|
||||
int baseport;
|
||||
int dmachan;
|
||||
int flags;
|
||||
#define FDC_ATTACHED 0x01
|
||||
#define FDC_HASFTAPE 0x02
|
||||
#define FDC_TAPE_BUSY 0x04
|
||||
struct fd_data *fd;
|
||||
int fdu; /* the active drive */
|
||||
struct buf head; /* Head of buf chain */
|
||||
struct buf rhead; /* Raw head of buf chain */
|
||||
int state;
|
||||
int retry;
|
||||
int status[7]; /* copy of the registers */
|
||||
};
|
||||
|
||||
/***********************************************************************\
|
||||
* Throughout this file the following conventions will be used: *
|
||||
* fd is a pointer to the fd_data struct for the drive in question *
|
||||
* fdc is a pointer to the fdc_data struct for the controller *
|
||||
* fdu is the floppy drive unit number *
|
||||
* fdcu is the floppy controller unit number *
|
||||
* fdsu is the floppy drive unit number on that controller. (sub-unit) *
|
||||
\***********************************************************************/
|
||||
typedef int fdu_t;
|
||||
typedef int fdcu_t;
|
||||
typedef int fdsu_t;
|
||||
typedef struct fd_data *fd_p;
|
||||
typedef struct fdc_data *fdc_p;
|
||||
|
||||
|
||||
#define FDUNIT(s) (((s)>>6)&03)
|
||||
#define FDTYPE(s) ((s)&077)
|
||||
|
2113
sys/i386/isa/ft.c
Normal file
2113
sys/i386/isa/ft.c
Normal file
File diff suppressed because it is too large
Load Diff
81
sys/i386/isa/ftreg.h
Normal file
81
sys/i386/isa/ftreg.h
Normal file
@ -0,0 +1,81 @@
|
||||
/*
|
||||
* Copyright (c) 1993 Steve Gerakines
|
||||
*
|
||||
* This is freely redistributable software. You may do anything you
|
||||
* wish with it, so long as the above notice stays intact.
|
||||
*
|
||||
* THIS SOFTWARE IS PROVIDED BY THE AUTHOR(S) ``AS IS'' AND ANY EXPRESS
|
||||
* OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
|
||||
* WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
|
||||
* DISCLAIMED. IN NO EVENT SHALL THE AUTHOR(S) BE LIABLE FOR ANY DIRECT,
|
||||
* INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
|
||||
* (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR
|
||||
* SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
|
||||
* HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT,
|
||||
* STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING
|
||||
* IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
|
||||
* POSSIBILITY OF SUCH DAMAGE.
|
||||
*
|
||||
* ftreg.h - QIC-40/80 floppy tape driver header
|
||||
* 10/30/93 v0.3
|
||||
* More things will end up here. QC_VENDORID and QC_VERSION now used.
|
||||
*
|
||||
* 08/07/93 v0.2 release
|
||||
* Things that should've been here in the first place were moved.
|
||||
* Tape geometry and segment request types were added.
|
||||
*
|
||||
* 06/03/93 v0.1 Alpha release
|
||||
* Initial revision. Many more things should be moved here.
|
||||
*/
|
||||
|
||||
/* QIC-117 command set. */
|
||||
#define QC_RESET 1 /* reset */
|
||||
#define QC_NEXTBIT 2 /* report next bit */
|
||||
#define QC_PAUSE 3 /* pause */
|
||||
#define QC_STPAUSE 4 /* step pause */
|
||||
#define QC_TIMEOUT 5 /* alt timeout */
|
||||
#define QC_STATUS 6 /* report status */
|
||||
#define QC_ERRCODE 7 /* report error code */
|
||||
#define QC_CONFIG 8 /* report config */
|
||||
#define QC_VERSION 9 /* report version */
|
||||
#define QC_FORWARD 10 /* logical forward */
|
||||
#define QC_SEEKSTART 11 /* seek to track start */
|
||||
#define QC_SEEKEND 12 /* seek to track end */
|
||||
#define QC_SEEKTRACK 13 /* seek head to track */
|
||||
#define QC_SEEKLOAD 14 /* seek load point */
|
||||
#define QC_FORMAT 15 /* format mode */
|
||||
#define QC_WRITEREF 16 /* write reference */
|
||||
#define QC_VERIFY 17 /* verify mode */
|
||||
#define QC_STOP 18 /* stop tape */
|
||||
#define QC_STEPUP 21 /* step head up */
|
||||
#define QC_STEPDOWN 22 /* step head down */
|
||||
#define QC_SEEKREV 25 /* seek reverse */
|
||||
#define QC_SEEKFWD 26 /* seek forward */
|
||||
#define QC_RATE 27 /* select data rate */
|
||||
#define QC_DIAG1 28 /* diagnostic mode 1 */
|
||||
#define QC_DIAG2 29 /* diagnostic mode 2 */
|
||||
#define QC_PRIMARY 30 /* primary mode */
|
||||
#define QC_VENDORID 32 /* vendor id */
|
||||
#define QC_TSTATUS 33 /* report tape status */
|
||||
#define QC_EXTREV 34 /* extended skip reverse */
|
||||
#define QC_EXTFWD 35 /* extended skip forward */
|
||||
|
||||
/* Colorado enable/disable. */
|
||||
#define QC_COL_ENABLE1 46 /* enable */
|
||||
#define QC_COL_ENABLE2 2 /* null-op */
|
||||
#define QC_COL_DISABLE 47 /* disable */
|
||||
|
||||
/* Mountain enable/disable. */
|
||||
#define QC_MTN_ENABLE1 23 /* enable 1 */
|
||||
#define QC_MTN_ENABLE2 20 /* enable 2 */
|
||||
#define QC_MTN_DISABLE 24 /* disable */
|
||||
|
||||
/* Segment I/O request. */
|
||||
typedef struct segq {
|
||||
unsigned char buff[QCV_SEGSIZE];/* Segment data; first for alignment */
|
||||
int reqtype; /* Request type */
|
||||
long reqcrc; /* CRC Errors found */
|
||||
long reqbad; /* Bad sector map */
|
||||
long reqblk; /* Block request starts at */
|
||||
int reqcan; /* Cancel read-ahead */
|
||||
} SegReq;
|
237
sys/isa/fd.c
237
sys/isa/fd.c
@ -35,36 +35,40 @@
|
||||
* SUCH DAMAGE.
|
||||
*
|
||||
* from: @(#)fd.c 7.4 (Berkeley) 5/25/91
|
||||
* $Id: fd.c,v 1.17 1993/12/19 00:50:33 wollman Exp $
|
||||
* $from: fd.c,v 1.18 1993/12/21 05:09:21 ache Exp $
|
||||
*
|
||||
*/
|
||||
|
||||
#include "ft.h"
|
||||
#if NFT < 1
|
||||
#undef NFDC
|
||||
#endif
|
||||
#include "fd.h"
|
||||
#if NFD > 0
|
||||
|
||||
#include "param.h"
|
||||
#include "dkbad.h"
|
||||
#include "systm.h"
|
||||
#include "kernel.h"
|
||||
#include "conf.h"
|
||||
#include "file.h"
|
||||
#include "ioctl.h"
|
||||
#include "machine/ioctl_fd.h"
|
||||
#include "disklabel.h"
|
||||
#include "buf.h"
|
||||
#include "uio.h"
|
||||
#include "malloc.h"
|
||||
#include "syslog.h"
|
||||
#if NFDC > 0
|
||||
|
||||
#include <sys/param.h>
|
||||
#include <sys/dkbad.h>
|
||||
#include <sys/systm.h>
|
||||
#include <sys/kernel.h>
|
||||
#include <sys/conf.h>
|
||||
#include <sys/file.h>
|
||||
#include <sys/ioctl.h>
|
||||
#include <machine/ioctl_fd.h>
|
||||
#include <sys/disklabel.h>
|
||||
#include <sys/buf.h>
|
||||
#include <sys/uio.h>
|
||||
#include <sys/malloc.h>
|
||||
#include <sys/syslog.h>
|
||||
#include "i386/isa/isa.h"
|
||||
#include "i386/isa/isa_device.h"
|
||||
#include "i386/isa/fdreg.h"
|
||||
#include "i386/isa/icu.h"
|
||||
#include "i386/isa/rtc.h"
|
||||
#undef NFD
|
||||
#define NFD 2
|
||||
|
||||
#define FDUNIT(s) (((s)>>6)&03)
|
||||
#define FDTYPE(s) ((s)&077)
|
||||
#if NFT > 0
|
||||
extern int ftopen(), ftintr(), ftattach(), ftclose(), ftioctl();
|
||||
#endif
|
||||
|
||||
#define b_cylin b_resid
|
||||
#define FDBLK 512
|
||||
@ -75,22 +79,25 @@
|
||||
#define NUMTYPES 14
|
||||
#define NUMDENS (NUMTYPES - 6)
|
||||
|
||||
/* This defines must match fd_types */
|
||||
#define FD_1720 0
|
||||
#define FD_1480 1
|
||||
#define FD_1440 2
|
||||
#define FD_1200 3
|
||||
#define FD_820 4
|
||||
#define FD_800 5
|
||||
#define FD_720 6
|
||||
#define FD_360 7
|
||||
/* This defines (-1) must match index for fd_types */
|
||||
#define F_TAPE_TYPE 0x020 /* bit for fd_types to indicate tape */
|
||||
#define NO_TYPE 0 /* must match NO_TYPE in ft.c */
|
||||
#define FD_1720 1
|
||||
#define FD_1480 2
|
||||
#define FD_1440 3
|
||||
#define FD_1200 4
|
||||
#define FD_820 5
|
||||
#define FD_800 6
|
||||
#define FD_720 7
|
||||
#define FD_360 8
|
||||
|
||||
#define FD_1480in5_25 9
|
||||
#define FD_1440in5_25 10
|
||||
#define FD_820in5_25 11
|
||||
#define FD_800in5_25 12
|
||||
#define FD_720in5_25 13
|
||||
#define FD_360in5_25 14
|
||||
|
||||
#define FD_1480in5_25 8
|
||||
#define FD_1440in5_25 9
|
||||
#define FD_820in5_25 10
|
||||
#define FD_800in5_25 11
|
||||
#define FD_720in5_25 12
|
||||
#define FD_360in5_25 13
|
||||
|
||||
struct fd_type fd_types[NUMTYPES] =
|
||||
{
|
||||
@ -111,33 +118,18 @@ struct fd_type fd_types[NUMTYPES] =
|
||||
{ 9,2,0xFF,0x23,40, 720,2,FDC_300KBPS,2,0x50,1 }, /* 360K in HD 5.25in */
|
||||
};
|
||||
|
||||
#define DRVS_PER_CTLR 2
|
||||
#define DRVS_PER_CTLR 2 /* 2 floppies */
|
||||
/***********************************************************************\
|
||||
* Per controller structure. *
|
||||
\***********************************************************************/
|
||||
struct fdc_data
|
||||
{
|
||||
int fdcu; /* our unit number */
|
||||
int baseport;
|
||||
int dmachan;
|
||||
int flags;
|
||||
#define FDC_ATTACHED 0x01
|
||||
struct fd_data *fd;
|
||||
int fdu; /* the active drive */
|
||||
struct buf head; /* Head of buf chain */
|
||||
struct buf rhead; /* Raw head of buf chain */
|
||||
int state;
|
||||
int retry;
|
||||
int status[7]; /* copy of the registers */
|
||||
}fdc_data[(NFD+1)/DRVS_PER_CTLR];
|
||||
struct fdc_data fdc_data[NFDC];
|
||||
|
||||
/***********************************************************************\
|
||||
* Per drive structure. *
|
||||
* N per controller (presently 2) (DRVS_PER_CTLR) *
|
||||
* N per controller (DRVS_PER_CTLR) *
|
||||
\***********************************************************************/
|
||||
struct fd_data {
|
||||
struct fdc_data *fdc;
|
||||
int fdu; /* this unit number */
|
||||
struct fdc_data *fdc; /* pointer to controller structure */
|
||||
int fdsu; /* this units number on this controller */
|
||||
int type; /* Drive type (HD, DD */
|
||||
struct fd_type *ft; /* pointer to the type descriptor */
|
||||
@ -159,11 +151,9 @@ struct fd_data {
|
||||
* fdcu is the floppy controller unit number *
|
||||
* fdsu is the floppy drive unit number on that controller. (sub-unit) *
|
||||
\***********************************************************************/
|
||||
typedef int fdu_t;
|
||||
typedef int fdcu_t;
|
||||
typedef int fdsu_t;
|
||||
typedef struct fd_data *fd_p;
|
||||
typedef struct fdc_data *fdc_p;
|
||||
|
||||
#define id_physid id_scsiid /* this biotab field doubles as a field */
|
||||
/* for the physical unit number on the controller */
|
||||
|
||||
static int retrier(fdcu_t);
|
||||
|
||||
@ -216,8 +206,8 @@ static void fd_turnoff(caddr_t, int);
|
||||
static int fdprobe(struct isa_device *);
|
||||
static int fdattach(struct isa_device *);
|
||||
|
||||
struct isa_driver fddriver = {
|
||||
fdprobe, fdattach, "fd",
|
||||
struct isa_driver fdcdriver = {
|
||||
fdprobe, fdattach, "fdc",
|
||||
};
|
||||
|
||||
/*
|
||||
@ -266,24 +256,48 @@ fdattach(dev)
|
||||
fdc_p fdc = fdc_data + fdcu;
|
||||
fd_p fd;
|
||||
int fdsu;
|
||||
struct isa_device *fdup;
|
||||
|
||||
fdc->fdcu = fdcu;
|
||||
fdc->flags |= FDC_ATTACHED;
|
||||
fdc->dmachan = dev->id_drq;
|
||||
fdc->state = DEVIDLE;
|
||||
|
||||
fdt = rtcin(RTC_FDISKETTE);
|
||||
hdr = 0;
|
||||
printf("fdc%d:", fdcu);
|
||||
|
||||
/* check for each floppy drive */
|
||||
for (fdu = (fdcu * DRVS_PER_CTLR),fdsu = 0;
|
||||
((fdu < NFD) && (fdsu < DRVS_PER_CTLR));
|
||||
fdu++,fdsu++)
|
||||
{
|
||||
for (fdup = isa_biotab_fdc; fdup->id_driver != 0; fdup++) {
|
||||
if (fdup->id_iobase != dev->id_iobase)
|
||||
continue;
|
||||
fdu = fdup->id_unit;
|
||||
fd = &fd_data[fdu];
|
||||
if (fdu >= (NFD+NFT))
|
||||
continue;
|
||||
fdsu = fdup->id_physid;
|
||||
/* look up what bios thinks we have */
|
||||
switch (fdu) {
|
||||
case 0: fdt = (rtcin(RTC_FDISKETTE) & 0xf0);
|
||||
break;
|
||||
case 1: fdt = ((rtcin(RTC_FDISKETTE) << 4) & 0xf0);
|
||||
break;
|
||||
default: fdt = RTCFDT_NONE;
|
||||
break;
|
||||
}
|
||||
/* is there a unit? */
|
||||
if ((fdt & 0xf0) == RTCFDT_NONE) {
|
||||
#define NO_TYPE NUMTYPES
|
||||
fd_data[fdu].type = NO_TYPE;
|
||||
if ((fdt == RTCFDT_NONE)
|
||||
#if NFT > 0
|
||||
|| (fdsu >= DRVS_PER_CTLR)) {
|
||||
#else
|
||||
) {
|
||||
#endif
|
||||
#if NFT > 0
|
||||
/* If BIOS says no floppy, or > 2nd device */
|
||||
/* Probe for and attach a floppy tape. */
|
||||
if (ftattach(dev, fdup))
|
||||
continue;
|
||||
|
||||
#endif
|
||||
fd->type = NO_TYPE;
|
||||
continue;
|
||||
}
|
||||
|
||||
@ -303,38 +317,38 @@ fdattach(dev)
|
||||
continue;
|
||||
|
||||
#endif
|
||||
fd_data[fdu].track = -2;
|
||||
fd_data[fdu].fdc = fdc;
|
||||
fd_data[fdu].fdsu = fdsu;
|
||||
printf("fd%d: unit %d type ", fdcu, fdu);
|
||||
fd->track = -2;
|
||||
fd->fdc = fdc;
|
||||
fd->fdsu = fdsu;
|
||||
printf(" [%d: fd%d: ", fdsu, fdu);
|
||||
|
||||
switch (fdt & 0xf0) {
|
||||
switch (fdt) {
|
||||
case RTCFDT_12M:
|
||||
printf("1.2MB 5.25in\n");
|
||||
fd_data[fdu].type = FD_1200;
|
||||
printf("1.2MB 5.25in]");
|
||||
fd->type = FD_1200;
|
||||
break;
|
||||
case RTCFDT_144M:
|
||||
printf("1.44MB 3.5in\n");
|
||||
fd_data[fdu].type = FD_1440;
|
||||
printf("1.44MB 3.5in]");
|
||||
fd->type = FD_1440;
|
||||
break;
|
||||
case RTCFDT_360K:
|
||||
printf("360KB 5.25in\n");
|
||||
fd_data[fdu].type = FD_360;
|
||||
printf("360KB 5.25in]");
|
||||
fd->type = FD_360;
|
||||
break;
|
||||
case RTCFDT_720K:
|
||||
printf("720KB 3.5in\n");
|
||||
fd_data[fdu].type = FD_720;
|
||||
printf("720KB 3.5in]");
|
||||
fd->type = FD_720;
|
||||
break;
|
||||
default:
|
||||
printf("unknown\n");
|
||||
fd_data[fdu].type = NO_TYPE;
|
||||
printf("unknown]");
|
||||
fd->type = NO_TYPE;
|
||||
break;
|
||||
}
|
||||
|
||||
fdt <<= 4;
|
||||
fd_turnoff((caddr_t)fdu, 0);
|
||||
hdr = 1;
|
||||
}
|
||||
printf("\n");
|
||||
|
||||
/* Set transfer to 500kbps */
|
||||
outb(fdc->baseport+fdctl,0); /*XXX*/
|
||||
@ -365,9 +379,16 @@ void fdstrategy(struct buf *bp)
|
||||
fd = &fd_data[fdu];
|
||||
fdc = fd->fdc;
|
||||
fdcu = fdc->fdcu;
|
||||
/*type = FDTYPE(minor(bp->b_dev));*/
|
||||
|
||||
if ((fdu >= NFD) || (bp->b_blkno < 0)) {
|
||||
#if NFT > 0
|
||||
/* check for controller already busy with tape */
|
||||
if (fdc->flags & FDC_TAPE_BUSY) {
|
||||
bp->b_error = EBUSY;
|
||||
bp->b_flags |= B_ERROR;
|
||||
return;
|
||||
}
|
||||
#endif
|
||||
if ((fdu >= (NFD+NFT)) || (bp->b_blkno < 0)) {
|
||||
printf("fdstrat: fdu = %d, blkno = %d, bcount = %d\n",
|
||||
fdu, bp->b_blkno, bp->b_bcount);
|
||||
pg("fd:error in fdstrategy");
|
||||
@ -547,16 +568,24 @@ Fdopen(dev, flags)
|
||||
{
|
||||
fdu_t fdu = FDUNIT(minor(dev));
|
||||
int type = FDTYPE(minor(dev));
|
||||
int s;
|
||||
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 || fd_data[fdu].fdc == NULL
|
||||
|| fd_data[fdu].type == NO_TYPE) return(ENXIO);
|
||||
if (type > NUMDENS) return(ENXIO);
|
||||
if (fdu >= NFD)
|
||||
return(ENXIO);
|
||||
fdc = fd_data[fdu].fdc;
|
||||
if ((fdc == NULL) || (fd_data[fdu].type == NO_TYPE))
|
||||
return(ENXIO);
|
||||
if (type > NUMDENS)
|
||||
return(ENXIO);
|
||||
if (type == 0)
|
||||
type = fd_data[fdu].type;
|
||||
else {
|
||||
type--;
|
||||
if (type != fd_data[fdu].type) {
|
||||
switch (fd_data[fdu].type) {
|
||||
case FD_360:
|
||||
@ -604,7 +633,7 @@ Fdopen(dev, flags)
|
||||
}
|
||||
}
|
||||
}
|
||||
fd_data[fdu].ft = fd_types + type;
|
||||
fd_data[fdu].ft = fd_types + type - 1;
|
||||
fd_data[fdu].flags |= FD_OPEN;
|
||||
|
||||
return 0;
|
||||
@ -616,6 +645,12 @@ fdclose(dev, flags)
|
||||
int flags;
|
||||
{
|
||||
fdu_t fdu = FDUNIT(minor(dev));
|
||||
int type = FDTYPE(minor(dev));
|
||||
|
||||
#if NFT > 0
|
||||
if (type & F_TAPE_TYPE)
|
||||
return ftclose(0);
|
||||
#endif
|
||||
fd_data[fdu].flags &= ~FD_OPEN;
|
||||
return(0);
|
||||
}
|
||||
@ -712,6 +747,13 @@ 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))
|
||||
;
|
||||
}
|
||||
@ -829,8 +871,8 @@ fdstate(fdcu, fdc)
|
||||
cyl = in_fdc(fdcu);
|
||||
if (cyl != descyl)
|
||||
{
|
||||
printf("fd%d: Seek to cyl %d failed; am at cyl %d (ST0 = 0x%x)\n", fdu,
|
||||
descyl, cyl, i, NE7_ST0BITS);
|
||||
printf("fd%d: Seek to cyl %d failed; am at cyl %d (ST0 = 0x%x)\n",
|
||||
fdu, descyl, cyl, i, NE7_ST0BITS);
|
||||
return(retrier(fdcu));
|
||||
}
|
||||
}
|
||||
@ -1130,6 +1172,11 @@ fdioctl (dev, cmd, addr, flag, p)
|
||||
char buffer[DEV_BSIZE];
|
||||
int error;
|
||||
|
||||
#if NFT > 0
|
||||
if (fd_data[FDUNIT(minor(dev))].fdc->flags & FDC_TAPE_BUSY)
|
||||
return ftioctl(dev, cmd, addr, flag, p);
|
||||
#endif
|
||||
|
||||
error = 0;
|
||||
|
||||
switch (cmd)
|
||||
|
@ -31,7 +31,7 @@
|
||||
* SUCH DAMAGE.
|
||||
*
|
||||
* from: @(#)fdreg.h 7.1 (Berkeley) 5/9/91
|
||||
* $Id$
|
||||
* $Id: fdreg.h,v 1.2 1993/10/16 13:45:50 rgrimes Exp $
|
||||
*/
|
||||
|
||||
/*
|
||||
@ -63,4 +63,41 @@
|
||||
#define fdin 7 /* Digital Input Register (R) */
|
||||
#define FDI_DCHG 0x80 /* diskette has been changed */
|
||||
|
||||
/***********************************************************************\
|
||||
* Per controller structure. *
|
||||
\***********************************************************************/
|
||||
struct fdc_data
|
||||
{
|
||||
int fdcu; /* our unit number */
|
||||
int baseport;
|
||||
int dmachan;
|
||||
int flags;
|
||||
#define FDC_ATTACHED 0x01
|
||||
#define FDC_HASFTAPE 0x02
|
||||
#define FDC_TAPE_BUSY 0x04
|
||||
struct fd_data *fd;
|
||||
int fdu; /* the active drive */
|
||||
struct buf head; /* Head of buf chain */
|
||||
struct buf rhead; /* Raw head of buf chain */
|
||||
int state;
|
||||
int retry;
|
||||
int status[7]; /* copy of the registers */
|
||||
};
|
||||
|
||||
/***********************************************************************\
|
||||
* Throughout this file the following conventions will be used: *
|
||||
* fd is a pointer to the fd_data struct for the drive in question *
|
||||
* fdc is a pointer to the fdc_data struct for the controller *
|
||||
* fdu is the floppy drive unit number *
|
||||
* fdcu is the floppy controller unit number *
|
||||
* fdsu is the floppy drive unit number on that controller. (sub-unit) *
|
||||
\***********************************************************************/
|
||||
typedef int fdu_t;
|
||||
typedef int fdcu_t;
|
||||
typedef int fdsu_t;
|
||||
typedef struct fd_data *fd_p;
|
||||
typedef struct fdc_data *fdc_p;
|
||||
|
||||
|
||||
#define FDUNIT(s) (((s)>>6)&03)
|
||||
#define FDTYPE(s) ((s)&077)
|
||||
|
Loading…
Reference in New Issue
Block a user