#include <sys/param.h>
#include <sys/disklabel.h>
#include <lib/libsa/stand.h>
#include "libx68k.h"
#include "fdvar.h"
#include "iocs.h"
int
fdopen(struct open_file *f, ...)
{
int error;
struct fd_softc *sc;
struct fdfmt fdfmt;
int id;
int part __unused;
va_list ap;
va_start(ap, f);
id = va_arg(ap, int);
part = va_arg(ap, int);
va_end(ap);
if (id < 0 || id > 3)
return ENXIO;
sc = alloc(sizeof (struct fd_softc));
error = IOCS_B_DRVCHK((0x90 + id) << 8, 2);
if ((error & 2) == 0)
return ENXIO;
error = IOCS_B_RECALI((0x90 + id) << 8);
error = fd_check_format(id, 0, &sc->fmt);
if (error < 0) {
IOCS_B_DRVCHK((0x90 + id) << 8, 3);
dealloc(sc, sizeof(struct fd_softc));
return -error;
}
error = fd_check_format(id, 1, &fdfmt);
if (error == 0)
sc->fmt.maxsec.H = fdfmt.maxsec.H;
sc->unit = id;
f->f_devdata = sc;
return 0;
}
int
fdclose(struct open_file *f)
{
struct fd_softc *sc = f->f_devdata;
IOCS_B_DRVCHK((0x90 + sc->unit) << 8, 3);
dealloc(sc, sizeof(struct fd_softc));
return 0;
}
int
fdstrategy(void *arg, int rw, daddr_t dblk, size_t size,
void *buf, size_t *rsize)
{
struct fd_softc *sc = arg;
int cyl, head, sect;
int nhead, nsect;
int error, nbytes;
if (size == 0) {
if (rsize)
*rsize = 0;
return 0;
}
nbytes = howmany(size, 128 << sc->fmt.minsec.N)
* (128 << sc->fmt.minsec.N);
nhead = sc->fmt.maxsec.H - sc->fmt.minsec.H + 1;
nsect = sc->fmt.maxsec.R - sc->fmt.minsec.R + 1;
sect = dblk % nsect + sc->fmt.minsec.R;
head = (dblk / nsect) % nhead + sc->fmt.minsec.H;
cyl = (dblk / nsect) / nhead + sc->fmt.minsec.C;
error = IOCS_B_READ((sc->unit + 0x90) * 256 + 0x70,
((sc->fmt.minsec.N << 24) |
(cyl << 16) |
(head << 8) |
(sect)),
nbytes,
buf);
if (error & 0xf8ffff00) {
nbytes = 0;
error = EIO;
} else {
error = 0;
}
if (rsize)
*rsize = nbytes;
return error;
}