summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authormycroft <mycroft@NetBSD.org>1994-04-05 23:05:09 +0000
committermycroft <mycroft@NetBSD.org>1994-04-05 23:05:09 +0000
commit671bcb4e22c3937a0fe039204970247ece5bb129 (patch)
tree74c5b894d863427cb4c7bee7be6d6d4fdb938fc8
parentbdb52e02f8a36d9bd2fbe358a665f95f81908584 (diff)
Clean up deleted files.
-rw-r--r--sys/arch/amiga/dev/fp.c1436
1 files changed, 0 insertions, 1436 deletions
diff --git a/sys/arch/amiga/dev/fp.c b/sys/arch/amiga/dev/fp.c
deleted file mode 100644
index 830840488d7..00000000000
--- a/sys/arch/amiga/dev/fp.c
+++ /dev/null
@@ -1,1436 +0,0 @@
-/*
- * Copyright (c) 1994 Brad Pepers
- * All rights reserved.
- *
- * This code is derived from software contributed to Berkeley by
- * Brad Pepers.
- *
- * Redistribution and use in source and binary forms, with or without
- * modification, are permitted provided that the following conditions
- * are met:
- * 1. Redistributions of source code must retain the above copyright
- * notice, this list of conditions and the following disclaimer.
- * 2. Redistributions in binary form must reproduce the above copyright
- * notice, this list of conditions and the following disclaimer in the
- * documentation and/or other materials provided with the distribution.
- * 3. All advertising materials mentioning features or use of this software
- * must display the following acknowledgement:
- * This product includes software developed by the University of
- * California, Berkeley and its contributors.
- * 4. Neither the name of the University nor the names of its contributors
- * may be used to endorse or promote products derived from this software
- * without specific prior written permission.
- *
- * THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS ``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 REGENTS OR CONTRIBUTORS 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.
- *
- */
-
-/*
- * floppy interface
- */
-
-#include "fp.h"
-#if NFP > 0
-
-#include <sys/param.h>
-#include <sys/systm.h>
-#include <sys/buf.h>
-#include <sys/dkstat.h>
-#include <sys/disklabel.h>
-#include <sys/malloc.h>
-#include <sys/proc.h>
-#include <sys/reboot.h>
-#include <sys/file.h>
-#include <sys/ioctl.h>
-
-#include <amiga/dev/device.h>
-#include <amiga/amiga/cia.h>
-#include <amiga/amiga/custom.h>
-
-#define UNIT(x) (minor(x) & 3)
-#define b_cylin b_resid
-#define FDBLK 512
-#define MAX_SECTS 22
-#define IMMED_WRITE 0
-
-int fpattach();
-struct driver fpdriver = {
- fpattach, "fp",
-};
-
-/* defines */
-#define MFM_SYNC 0x4489
-#define DSKLEN_DMAEN (1<<15)
-#define DSKLEN_WRITE (1<<14)
-
-/* drive type values */
-#define FP_NONE 0x00000000
-#define FP_DD_3 0xffffffff /* double-density 3.5" (880K) */
-#define FP_HD_3 0x55555555 /* high-density 3.5" (1760K) */
-
-struct fp_type {
- int id;
- char *name;
- int tracks;
- int heads;
- int read_size;
- int write_size;
- int sect_mult;
- int precomp1;
- int precomp2;
- int step_delay;
- int side_time;
- int settle_time;
-};
-
-struct fp_type drive_types[] = {
-/* id name tr he rdsz wrsz sm pc1 pc2 sd st st */
- { FP_DD_3, "DD 3.5", 80, 2, 14716, 13630, 1, 80, 161, 3, 18, 1 },
- { FP_HD_3, "HD 3.5", 80, 2, 29432, 27260, 2, 80, 161, 3, 18, 1 },
- { FP_NONE, "No Drive", 0, }
-};
-int num_dr_types = sizeof(drive_types) / sizeof(drive_types[0]);
-
-/*
- * Per drive structure.
- * N per controller (presently 4) (DRVS_PER_CTLR)
- */
-#define DRVS_PER_CTLR 4
-struct fp_data {
- int fpu; /* This unit number */
- struct buf head; /* Head of buf chain */
- struct buf rhead; /* Raw head of buf chain */
- int type; /* Drive type */
- struct fp_type *ft; /* Pointer to type descriptor */
- int flags;
-#define FPF_OPEN 0x01 /* it's open */
- int skip;
- int sects; /* number of sectors in a track */
- int size; /* size of disk in sectors */
- int side; /* current side disk is on */
- int dir; /* current direction of stepping */
- int cyl; /* current cylinder disk is on */
- int buf_track;
- int buf_dirty;
- char *buf_data;
- char *buf_labels;
- int write_cnt;
-};
-
-/*
- * Per controller structure.
- */
-struct fpc_data
-{
- int fpcu; /* our unit number */
- struct fp_data *fp; /* drive we are currently doing work for */
- int motor_fpu; /* drive that has its motor on */
- int state;
- int saved;
- int retry;
- struct fp_data fp_data[DRVS_PER_CTLR];
-};
-struct fpc_data fpc_data[NFP];
-
-/*
- * Throughout this file the following conventions will be used:
- *
- * fp is a pointer to the fp_data struct for the drive in question
- * fpc is a pointer to the fdc_data struct for the controller
- * fpu is the floppy drive unit number
- * fpcu is the floppy controller unit number
- * fpsu is the floppy drive unit number on that controller. (sub-unit)
- */
-typedef int fpu_t;
-typedef int fpcu_t;
-typedef int fpsu_t;
-typedef struct fp_data *fp_p;
-typedef struct fpc_data *fpc_p;
-
-/*
- * protos.
- */
-static int delay __P((int));
-void encode __P((u_long, u_long *, u_long *));
-void fp_step __P((void));
-void fp_seek __P((fp_p, int));
-void correct __P((u_long *));
-void fp_probe __P((fp_p));
-void fp_turnon __P((fpc_p, fpu_t));
-void fp_turnoff __P((fpc_p));
-void track_read __P((fpc_p, fp_p, int));
-void fp_timeout __P((fpc_p));
-void fp_motor_to __P((fpcu_t));
-void fp_motor_on __P((fpc_p, fpu_t));
-void track_write __P((fpc_p, fp_p));
-void amiga_write __P((fp_p));
-void fp_calibrate __P((fp_p));
-void encode_block __P((u_long *, u_char *, int, u_long *));
-void fp_select_dir __P((fp_p, int));
-void fp_pseudointr __P((fpc_p));
-void fp_select_side __P((fp_p, int));
-
-u_long scan_sync __P((u_long, u_long, int));
-u_long encode_long __P((u_long, u_long *));
-u_long loop_read_id __P((int));
-u_long get_drive_id __P((int));
-
-int fpstate __P((fpc_p));
-int retrier __P((fpc_p));
-int amiga_read __P((fp_p));
-int get_drive_type __P((u_long));
-
-/* device routines */
-int fpopen __P((dev_t, int));
-int fpsize __P((dev_t));
-int fpioctl __P((dev_t, int, caddr_t, int, struct proc *));
-int fpclose __P((dev_t, int));
-int fpattach __P((struct amiga_device *));
-
-void fpintr __P((fpcu_t));
-void fpstart __P((fpc_p));
-void fpstrategy __P((struct buf *bp));
-
-#define DEVIDLE 0
-#define FINDWORK 1
-#define DOSEEK 2
-#define DO_IO 3
-#define DONE_IO 4
-#define WAIT_READ 5
-#define WAIT_WRITE 6
-#define DELAY_WRITE 7
-#define RECALCOMPLETE 8
-#define STARTRECAL 9
-#define RESETCTLR 10
-#define SEEKWAIT 11
-#define RECALWAIT 12
-#define MOTORWAIT 13
-
-#undef DEBUG
-
-#ifdef DEBUG
-
-char *fpstates[] =
-{
-"DEVIDLE",
-"FINDWORK",
-"DOSEEK",
-"DO_IO",
-"DONE_IO",
-"WAIT_READ",
-"WAIT_WRITE",
-"DELAY_WRITE",
-"RECALCOMPLETE",
-"STARTRECAL",
-"RESETCTLR",
-"SEEKWAIT",
-"RECALWAIT",
-"MOTORWAIT",
-};
-
-#define TRACE0(arg) if (fd_debug == 1) printf(arg)
-#define TRACE1(arg1,arg2) if (fd_debug == 1) printf(arg1,arg2)
-
-#else /* !DEBUG */
-
-#define TRACE0(arg)
-#define TRACE1(arg1,arg2)
-
-#endif /* !DEBUG */
-
-extern int hz;
-
-unsigned char *raw_buf = NULL;
-#ifdef DEBUG
-int fd_debug = 1;
-#else
-int fd_debug = 0;
-#endif
-
-/*
- * Floppy Support Routines
- */
-#define MOTOR_ON (ciab.prb &= ~CIAB_PRB_MTR)
-#define MOTOR_OFF (ciab.prb |= CIAB_PRB_MTR)
-#define SELECT(mask) (ciab.prb &= ~mask)
-#define DESELECT(mask) (ciab.prb |= mask)
-#define SELMASK(drive) (1 << (3 + (drive & 3)))
-
-/*
- * Delay for a number of milliseconds
- * - tried ciab.tod but seems to miss values and screw up
- * - stupid busy loop for now
- */
-static int
-delay(delay_ms)
- int delay_ms;
-{
- long cnt, inner;
- int val;
-
- for (cnt = 0; cnt < delay_ms; cnt++)
- for (inner = 0; inner < 500; inner++)
- val += inner * cnt;
- return(val);
-}
-
-/*
- * motor control stuff
- */
-void
-fp_motor_to(fpcu)
- fpcu_t fpcu;
-{
- printf("timeout starting motor\n"); /* XXXX */
- fpc_data[fpcu].motor_fpu = -2;
-}
-
-void
-fp_motor_on(fpc, fpu)
- fpc_p fpc;
- fpu_t fpu;
-{
- int i;
- int cnt; /* XXXX not used? */
-
- cnt = 0; /* XXXX not used? */
-
- /* deselect all drives */
- for (i = 0; i < DRVS_PER_CTLR; i++)
- DESELECT(SELMASK(i));
-
- /* turn on the unit's motor */
- MOTOR_ON;
- SELECT(SELMASK(fpu));
-
- timeout((timeout_t)fp_motor_to, (caddr_t)fpc->fpcu, hz);
- while (ciaa.pra & CIAA_PRA_RDY)
- ;
- untimeout((timeout_t)fp_motor_to, (caddr_t)fpc->fpcu);
- fpc->motor_fpu = fpu;
-}
-
-void
-fp_turnoff(fpc)
- fpc_p fpc;
-{
- int i;
-
- if (fpc->motor_fpu != -1) {
- /* deselect all drives */
- for (i = 0; i < DRVS_PER_CTLR; i++)
- DESELECT(SELMASK(i));
-
- /* turn off the unit's motor */
- MOTOR_OFF;
- SELECT(SELMASK(fpc->motor_fpu));
- MOTOR_ON;
- DESELECT(SELMASK(fpc->motor_fpu));
- }
-
- fpc->motor_fpu = -1;
-}
-
-void
-fp_turnon(fpc, fpu)
- fpc_p fpc;
- fpu_t fpu;
-{
- if (fpc->motor_fpu == fpu)
- return;
-
- fp_turnoff(fpc);
- fp_motor_on(fpc, fpu);
-}
-
-/*
- * Step the drive once in its current direction
- */
-void
-fp_step()
-{
- ciab.prb &= ~CIAB_PRB_STEP;
- ciab.prb |= CIAB_PRB_STEP;
-}
-
-/*
- * Select the side to use for a particular drive.
- * The drive must have been calibrated at some point before this.
- * The drive must also be active and the motor must be running.
- */
-void
-fp_select_side(fp, side)
- fp_p fp;
- int side;
-{
- if (fp->side == side)
- return;
-
- /* select the requested side */
- if (side == 0)
- ciab.prb &= ~CIAB_PRB_SIDE;
- else
- ciab.prb |= CIAB_PRB_SIDE;
- delay(fp->ft->side_time);
- fp->side = side;
-}
-
-/*
- * Select the direction to use for the current particular drive.
- */
-void
-fp_select_dir(fp, dir)
- fp_p fp;
- int dir;
-{
- if (fp->dir == dir)
- return;
-
- /* select the requested direction */
- if (dir == 0)
- ciab.prb &= ~CIAB_PRB_DIR;
- else
- ciab.prb |= CIAB_PRB_DIR;
- delay(fp->ft->settle_time);
- fp->dir = dir;
-}
-
-/*
- * Seek the drive to track 0.
- * The drive must be active and the motor must be running.
- * Returns standard floppy error code. /* XXXX doesn't return anything
- */
-void
-fp_calibrate(fp)
- fp_p fp;
-{
- fp_select_dir(fp, 1);
-
- /* loop until we hit track 0 */
- while (ciaa.pra & CIAA_PRA_TK0) {
- fp_step();
- delay(4);
- }
-
- /* set known values */
- fp->cyl = 0;
-}
-
-/*
- * Seek the drive to the requested track.
- * The drive must be active and the motor must be running.
- */
-void
-fp_seek(fp, track)
- fp_p fp;
- int track;
-{
- int cyl, side;
- int dir, cnt;
- int delay_time;
-
- cyl = track >> 1;
- side = (track % 2) ^ 1;
-
- if (fp->cyl == -1)
- fp_calibrate(fp);
-
- fp_select_side(fp, side);
-
- if (cyl < fp->cyl) {
- dir = 1;
- cnt = fp->cyl - cyl;
- } else {
- dir = 0;
- cnt = cyl - fp->cyl;
- }
-
- fp_select_dir(fp, dir);
-
- if (cnt) {
- while (cnt) {
- delay_time = fp->ft->step_delay;
- if (dir != fp->dir)
- delay_time += fp->ft->settle_time;
- fp_step();
- delay(delay_time);
- --cnt;
- }
- delay(fp->ft->settle_time);
- }
-
- fp->cyl = cyl;
-}
-
-void
-encode(data, dest, csum)
- u_long data;
- u_long *dest, *csum;
-{
- u_long data2;
-
- data &= 0x55555555;
- data2 = data ^ 0x55555555;
- data |= ((data2 >> 1) | 0x80000000) & (data2 << 1);
-
- if (*(dest - 1) & 0x00000001)
- data &= 0x7FFFFFFF;
-
- *csum ^= data;
- *dest = data;
-}
-
-u_long
-encode_long(data, dest)
- u_long data;
- u_long *dest;
-{
- u_long csum;
-
- csum = 0;
-
- encode(data >> 1, dest, &csum);
- encode(data, dest + 1, &csum);
-
- return(csum & 0x55555555);
-}
-
-void
-encode_block(dest, from, len, csum)
- u_long *dest, *csum;
- u_char *from;
- int len;
-{
- int cnt, to_cnt = 0;
- u_long data, *src;
-
- to_cnt = 0;
- src = (u_long *)from;
-
- /* odd bits */
- for (cnt = 0; cnt < len / 4; cnt++) {
- data = src[cnt] >> 1;
- encode(data, dest + to_cnt++, csum);
- }
-
- /* even bits */
- for (cnt = 0; cnt < len / 4; cnt++) {
- data = src[cnt];
- encode(data, dest + to_cnt++, csum);
- }
-
- *csum &= 0x55555555;
-}
-
-void
-correct(raw)
- u_long *raw;
-{
- u_char data, *ptr;
-
- ptr = (u_char *)raw;
-
- data = *ptr;
- if (*(ptr - 1) & 0x01) { /* XXXX will choke on old GVP's */
- *ptr = data & 0x7f;
- return;
- }
-
- if (data & 0x40)
- return;
-
- *ptr |= 0x80;
-}
-
-/*
- * amiga_write converts track/labels data to raw track data
- */
-void
-amiga_write(fp)
- fp_p fp;
-{
- u_long *raw, csum, format;
- u_char *data, *labels;
- int cnt, track;
-
- raw = (u_long *)raw_buf; /* XXXX never used while intr? */
- /* XXXX never waits after here? */
- data = fp->buf_data;
- labels = fp->buf_labels;
- track = fp->buf_track;
-
- /* gap space */
- for (cnt = 0; cnt < 414; cnt++)
- *raw++ = 0xaaaaaaaa;
-
- /* sectors */
- for (cnt = 0; cnt < 11; cnt++) {
- *raw = 0xaaaaaaaa;
- correct(raw);
- ++raw;
-
- *raw++ = 0x44894489;
-
- format = 0xff000000 | (track << 16) | (cnt << 8) | (11 - cnt);
- csum = encode_long(format,raw);
- raw += 2;
-
- encode_block(raw, labels + cnt * 16, 16, &csum);
- raw += 8;
- csum = encode_long(csum, raw);
- raw += 2;
-
- csum = 0;
- encode_block(raw+2, data + cnt * 512, 512, &csum);
- csum = encode_long(csum, raw);
- raw += 256 + 2;
- }
-}
-
-#define get_word(raw) (*(u_short *)(raw))
-#define get_long(raw) (*(u_long *)(raw))
-
-#define decode_long(raw) \
- (((get_long(raw) & 0x55555555) << 1) | \
- (get_long((raw)+4) & 0x55555555))
-
-#define MFM_NOSYNC 1
-#define MFM_HEADER 2
-#define MFM_DATA 3
-#define MFM_TRACK 4
-
-/*
- * scan_sync - looks for the next start of sector marked by a sync. When
- * sector = 10, can't be certain of a starting sync.
- */
-u_long
-scan_sync(raw, end, sect)
- u_long raw, end;
- int sect;
-{
- u_short data;
-
- if (sect != 10) {
- while (raw < end) {
- data = get_word(raw);
- if (data == 0x4489)
- break;
- raw += 2;
- }
- if (raw > end)
- return(0);
- }
-
- while (raw < end) {
- data = get_word(raw);
- if (data != 0x4489)
- break;
- raw += 2;
- }
- if (raw > end)
- return(0);
- return(raw);
-}
-
-/*
- * amiga_read reads a raw track of data into a track buffer
- */
-int
-amiga_read(fp)
- fp_p fp;
-{
- u_char *track_data, *label_data;
- u_long raw, end, val1, val2, csum, data_csum;
- u_long *data, *labels;
- int scnt, cnt, format, tnum, sect, snext;
-
- track_data = fp->buf_data;
- label_data = fp->buf_labels;
- raw = (u_long)raw_buf; /* XXXX see above about glb */
-
- end = raw + fp->ft->read_size;
-
- for (scnt = fp->sects-1; scnt >= 0; scnt--) {
- if ((raw = scan_sync(raw, end, scnt)) == 0) {
- /* XXXX */
- printf("can't find sync for sector %d\n", scnt);
- return(1);
- }
-
- val1 = decode_long(raw);
-
- format = (val1 >> 24) & 0xFF;
- tnum = (val1 >> 16) & 0xFF;
- sect = (val1 >> 8) & 0xFF;
- snext = (val1) & 0xFF;
-
- labels = (u_long *)(label_data + (sect << 4));
-
- csum = 0;
- val1 = get_long(raw);
- raw += 4;
- csum ^= val1;
- val1 = get_long(raw);
- raw += 4;
- csum ^= val1;
-
- for (cnt = 0; cnt < 4; cnt++) {
- val1 = get_long(raw+16);
- csum ^= val1;
- val1 &= 0x55555555;
- val2 = get_long(raw);
- raw += 4;
- csum ^= val2;
- val2 &= 0x55555555;
- val2 = val2 << 1;
- val1 |= val2;
- *labels++ = val1;
- }
-
- csum &= 0x55555555;
- raw += 16;
- val1 = decode_long(raw);
- raw += 8;
- if (val1 != csum) {
- /* XXXX */
- printf("MFM_HEADER %d: %08x,%08x\n", scnt,
- val1, csum);
- return(MFM_HEADER);
- }
-
- /* verify track */
- if (tnum != fp->buf_track) {
- /* XXXX */
- printf("MFM_TRACK %d: %d, %d\n", scnt, tnum,
- fp->buf_track);
- return(MFM_TRACK);
- }
-
- data_csum = decode_long(raw);
- raw += 8;
- data = (u_long *)(track_data + (sect << 9));
-
- csum = 0;
- for (cnt = 0; cnt < 128; cnt++) {
- val1 = get_long(raw + 512);
- csum ^= val1;
- val1 &= 0x55555555;
- val2 = get_long(raw);
- raw += 4;
- csum ^= val2;
- val2 &= 0x55555555;
- val2 = val2 << 1;
- val1 |= val2;
- *data++ = val1;
- }
-
- csum &= 0x55555555;
- raw += 512;
-
- if (data_csum != csum) {
- printf(
- "MFM_DATA: f=%d t=%d s=%d sn=%d sc=%d %ld, %ld\n",
- format, tnum, sect, snext, scnt, data_csum, csum);
- return(MFM_DATA);
- }
- }
- return(0);
-}
-
-/*
- * Return unit ID number of given disk
- * XXXX This function doesn't return anything.
- */
-u_long
-loop_read_id(unit)
- int unit;
-{
- u_long id;
- int i;
-
- id = 0;
-
- /* loop and read disk ID */
- for (i = 0; i < 32; i++) {
- SELECT(SELMASK(unit));
-
- /* read and store value of DSKRDY */
- id <<= 1; /* XXXX 0 << 1? */
- id |= (ciaa.pra & CIAA_PRA_RDY) ? 0 : 1;
-
- DESELECT(SELMASK(unit));
- }
-}
-
-u_long
-get_drive_id(unit)
- int unit;
-{
- int i, t;
- u_long id;
- u_char mask1, mask2;
- volatile u_char *a_ptr;
- volatile u_char *b_ptr;
-
- id = 0;
- a_ptr = &ciaa.pra;
- b_ptr = &ciab.prb;
- mask1 = ~(1 << (3 + unit));
- mask2 = 1 << (3 + unit);
-
- *b_ptr &= ~CIAB_PRB_MTR;
- *b_ptr &= mask1;
- *b_ptr |= mask2;
- *b_ptr |= CIAB_PRB_MTR;
- *b_ptr &= mask1;
- *b_ptr |= mask2;
-
- for (i = 0; i < 32; i++) {
- *b_ptr &= mask1;
- t = (*a_ptr) & CIAA_PRA_RDY;
- id = (id << 1) | (t ? 0 : 1);
- *b_ptr |= mask2;
- }
- return(id);
-#if 0
- /* set up for ID */
- MOTOR_ON;
- SELECT(SELMASK(unit));
- DESELECT(SELMASK(unit));
- MOTOR_OFF;
- SELECT(SELMASK(unit));
- DESELECT(SELMASK(unit));
-
- return loop_read_id(unit); /* XXXX gotta fix loop_read_id() if use */
-#endif
-}
-
-int
-get_drive_type(u_long id)
-{
- int type;
-
- for (type = 0; type < num_dr_types; type++)
- if (drive_types[type].id == id)
- return(type);
- return(-1);
-}
-
-void
-fp_probe(fp)
- fp_p fp;
-{
- u_long id;
- int type, data;
-
- fp->ft = NULL;
-
- id = get_drive_id(fp->fpu);
- type = get_drive_type(id);
-
- if (type == -1) {
- /* XXXX */
- printf("fp_probe: unsupported drive type %08x found\n", id);
- return;
- }
-
- fp->type = type;
- fp->ft = &drive_types[type];
- if (fp->ft->tracks == 0) {
- /* XXXX */
- printf("no drive type %d\n", type);
- }
- fp->side = -1;
- fp->dir = -1;
- fp->cyl = -1;
-
- fp->sects = 11 * drive_types[type].sect_mult;
- fp->size = fp->sects *
- drive_types[type].tracks *
- drive_types[type].heads;
- fp->flags = 0;
-}
-
-void
-track_read(fpc, fp, track)
- fpc_p fpc;
- fp_p fp;
- int track;
-{
- u_long len;
-
- fp->buf_track = track;
- fpc->state = WAIT_READ;
- timeout((timeout_t)fp_timeout, (caddr_t)fpc, 2 * hz);
-
- fp_seek(fp, track);
-
- len = fp->ft->read_size >> 1;
-
- /* setup adkcon bits correctly */
- custom.adkcon = ADKF_MSBSYNC;
- custom.adkcon = ADKF_SETCLR | ADKF_WORDSYNC | ADKF_FAST;
-
- custom.dsksync = MFM_SYNC;
-
- custom.dsklen = 0;
- delay(fp->ft->side_time);
-
- custom.dskpt = (u_char *)kvtop(raw_buf);
- custom.dsklen = len | DSKLEN_DMAEN;
- custom.dsklen = len | DSKLEN_DMAEN;
-}
-
-void
-track_write(fpc, fp)
- fpc_p fpc;
- fp_p fp;
-{
- int track;
- u_long len;
- u_short adk;
-
- amiga_write(fp);
-
- track = fp->buf_track;
- fp->write_cnt += 1;
-
- fpc->saved = fpc->state;
- fpc->state = WAIT_WRITE;
- timeout((timeout_t)fp_timeout, (caddr_t)fpc, 2 * hz);
-
- fp_seek(fp, track);
-
- len = fp->ft->write_size >> 1;
-
- if ((ciaa.pra & CIAA_PRA_WPRO) == 0)
- return;
-
- /* clear adkcon bits */
- custom.adkcon = ADKF_PRECOMP1 | ADKF_PRECOMP0 | ADKF_WORDSYNC |
- ADKF_MSBSYNC;
-
- /* set appropriate adkcon bits */
- adk = ADKF_SETCLR | ADKF_FAST;
- if (track >= fp->ft->precomp2)
- adk |= ADKF_PRECOMP1;
- else if (track >= fp->ft->precomp1)
- adk |= ADKF_PRECOMP0;
- custom.adkcon = adk;
-
- custom.dsklen = DSKLEN_WRITE;
- delay(fp->ft->side_time);
-
- custom.dskpt = (u_char *)kvtop(raw_buf); /* XXXX again raw */
- custom.dsklen = len | DSKLEN_DMAEN | DSKLEN_WRITE;
- custom.dsklen = len | DSKLEN_DMAEN | DSKLEN_WRITE;
-}
-
-/*
- * Floppy Device Code
- */
-int
-fpattach(ad)
- struct amiga_device *ad;
-{
- int fpcu = 0;
- fpc_p fpc = fpc_data + fpcu;
- int i;
- unsigned long id;
- int type;
-
- fpc->fpcu = fpcu;
- fpc->state = FINDWORK;
- fpc->fp = NULL;
- fpc->motor_fpu = -1;
-
- for (i = 0; i < DRVS_PER_CTLR; i++) {
- fpc->fp_data[i].fpu = i;
- fpc->fp_data[i].flags = 0;
-
- fpc->fp_data[i].buf_track = -1;
- fpc->fp_data[i].buf_dirty = 0;
- fpc->fp_data[i].buf_data =
- malloc(MAX_SECTS * 512, M_DEVBUF, 0);
- fpc->fp_data[i].buf_labels =
- malloc(MAX_SECTS * 16, M_DEVBUF, 0);
-
- if (fpc->fp_data[i].buf_data == NULL ||
- fpc->fp_data[i].buf_labels == NULL) {
- printf("Cannot alloc buffer memory for fp device\n");
- return(0);
- }
-
- id = get_drive_id(i);
- type = get_drive_type(id);
-
- if (type != -1 && drive_types[type].tracks != 0) {
- printf("floppy drive %d: %s\n", i,
- drive_types[type].name);
- }
- }
-
- raw_buf = (char *)alloc_chipmem(30000);
- if (raw_buf == NULL) {
- printf("Cannot alloc chipmem for fp device\n");
- return 0;
- }
-
- /* enable disk DMA */
- custom.dmacon = DMAF_SETCLR | DMAF_DISK;
-
- /* enable interrupts for IRQ_DSKBLK */
- ciaa.icr = CIA_ICR_IR_SC | CIA_ICR_FLG;
- custom.intena = INTF_SETCLR | INTF_SOFTINT;
-
- /* enable disk block interrupts */
- custom.intena = INTF_SETCLR | INTF_DSKBLK;
-
- return(1);
-}
-
-int
-fpopen(dev, flags)
- dev_t dev;
- int flags;
-{
- fpcu_t fpcu;
- fpc_p fpc;
- fpu_t fpu;
- fp_p fp;
-
- fpcu = 0;
- fpc = fpc_data + fpcu;
- fpu = UNIT(dev);
- fp = fpc->fp_data + fpu;
-
- /* check bounds */
- if (fpu >= DRVS_PER_CTLR)
- return(ENXIO);
-
- fp_probe(fp);
- if (fp->ft == NULL || fp->ft->tracks == 0)
- return(ENXIO);
-
- fp->flags |= FPF_OPEN;
- fp->write_cnt = 0;
-
- return(0);
-}
-
-int
-fpclose(dev, flags)
- dev_t dev;
- int flags;
-{
- struct buf *dp,*bp;
- fpcu_t fpcu;
- fpc_p fpc;
- fpu_t fpu;
- fp_p fp;
-
- fpcu = 0;
- fpc = fpc_data + fpcu;
- fpu = UNIT(dev);
- fp = fpc->fp_data + fpu;
-
-
- /* wait until activity is done for this drive */
- /* XXXX ACK! sleep.. */
- do {
- dp = &(fp->head);
- bp = dp->b_actf;
- } while (bp);
-
- /* XXXX */
- printf("wrote %d tracks (%d)\n", fp->write_cnt, fp->buf_dirty);
-
- fp->buf_track = -1;
- fp->buf_dirty = 0;
- fp->flags &= ~FPF_OPEN;
-
- return(0);
-}
-
-int
-fpioctl(dev, cmd, data, flag, p)
- dev_t dev;
- int cmd, flag;
- caddr_t data;
- struct proc *p;
-{
- struct disklabel *fp_label;
- fpcu_t fpcu;
- fpc_p fpc;
- fpu_t fpu;
- fp_p fp;
- int error;
-
- fpcu = 0;
- fpc = fpc_data + fpcu;
- fpu = UNIT(dev);
- fp = fpc->fp_data + fpu;
- error = 0;
-
- if (cmd != DIOCGDINFO)
- return (EINVAL);
-
- fp_label = (struct disklabel *)data;
-
- bzero(fp_label, sizeof(fp_label));
- fp_label->d_magic = DISKMAGIC;
- fp_label->d_type = DTYPE_FLOPPY;
- strncpy(fp_label->d_typename, "fp", sizeof(fp_label->d_typename) - 1);
- strcpy(fp_label->d_packname, "some pack");
-
- fp_label->d_secsize = 512;
- fp_label->d_nsectors = 11;
- fp_label->d_ntracks = 2;
- fp_label->d_ncylinders = 80;
- fp_label->d_secpercyl = fp_label->d_nsectors * fp_label->d_ntracks;
- fp_label->d_secperunit= fp_label->d_ncylinders * fp_label->d_secpercyl;
-
- fp_label->d_magic2 = DISKMAGIC;
- fp_label->d_partitions[0].p_offset = 0;
- fp_label->d_partitions[0].p_size = fp_label->d_secperunit;
- fp_label->d_partitions[0].p_fstype = FS_UNUSED;
- fp_label->d_npartitions = 1;
-
- fp_label->d_checksum = 0;
- fp_label->d_checksum = dkcksum(fp_label);
-
- return(0);
-}
-
-int
-fpsize(dev)
- dev_t dev;
-{
- /* check UNIT? */
- return((fpc_data + 0)->fp_data[UNIT(dev)].size);
-}
-
-void
-fpstrategy(bp)
- struct buf *bp;
-{
- fpcu_t fpcu;
- fpc_p fpc;
- fpu_t fpu;
- fp_p fp;
- long nblocks, blknum;
- struct buf *dp;
- int s;
-
- fpcu = 0;
- fpc = fpc_data + fpcu;
- fpu = UNIT(bp->b_dev);
- fp = fpc->fp_data + fpu;
-
- if (bp->b_blkno < 0) {
- /* XXXX */
- printf("fpstrat error: fpu = %d, blkno = %d, bcount = %d\n",
- fpu, bp->b_blkno, bp->b_bcount);
- bp->b_error = EINVAL;
- bp->b_flags |= B_ERROR;
- biodone(bp);
- return;
- }
-
- /*
- * Set up block calculations.
- */
- blknum = (unsigned long) bp->b_blkno * DEV_BSIZE / FDBLK;
- nblocks = fp->sects * fp->ft->tracks * fp->ft->heads;
- if (blknum + (bp->b_bcount / FDBLK) > nblocks) {
- /* XXXX */
- printf("at end of disk\n");
- bp->b_error = ENOSPC;
- bp->b_flags |= B_ERROR;
- biodone(bp);
- return;
- }
-
- bp->b_cylin = blknum; /* set here for disksort */
- dp = &(fp->head);
-
- s = splbio();
- disksort(dp, bp);
- untimeout((timeout_t)fp_turnoff, (caddr_t)fpc); /* a good idea */
- fpstart(fpc);
- splx(s);
-}
-
-/*
- * We have just queued something.. if the controller is not busy
- * then simulate the case where it has just finished a command
- * So that it (the interrupt routine) looks on the queue for more
- * work to do and picks up what we just added.
- * If the controller is already busy, we need do nothing, as it
- * will pick up our work when the present work completes
- */
-void
-fpstart(fpc)
- fpc_p fpc;
-{
- int s;
-
- s = splbio();
- if (fpc->state == FINDWORK)
- fpintr(fpc->fpcu);
- splx(s);
-}
-
-/*
- * just ensure it has the right spl
- */
-void
-fp_pseudointr(fpc)
- fpc_p fpc;
-{
- int s;
-
- s = splbio();
- fpintr(fpc->fpcu);
- splx(s);
-}
-
-void
-fp_timeout(fpc)
- fpc_p fpc;
-{
- struct buf *dp,*bp;
- fp_p fp;
-
- fp = fpc->fp;
- dp = &fp->head;
- bp = dp->b_actf;
-
- /* XXXX */
- printf("fp%d: Operation timeout\n", fp->fpu);
- if (bp) {
- retrier(fpc);
- fpc->state = DONE_IO;
- if (fpc->retry < 6)
- fpc->retry = 6;
- } else {
- fpc->fp = NULL;
- fpc->state = FINDWORK;
- }
-
- fp_pseudointr(fpc);
-}
-
-/*
- * keep calling the state machine until it returns a 0
- * ALWAYS called at SPLBIO
- */
-void
-fpintr(fpcu)
- fpcu_t fpcu;
-{
- fpc_p fpc;
-
- fpc = fpc_data + fpcu;
- while (fpstate(fpc))
- ;
-}
-
-/*
- * The controller state machine.
- * if it returns a non zero value, it should be called again immediatly
- */
-int
-fpstate(fpc)
- fpc_p fpc;
-{
- struct buf *dp,*bp;
- int track, read, sec, i;
- u_long blknum;
- fp_p fp;
-
- fp = fpc->fp;
-
- if (fp == NULL) {
- /* search for a unit do work with */
- for (i = 0; i < DRVS_PER_CTLR; i++) {
- fp = fpc->fp_data + i;
- dp = &(fp->head);
- bp = dp->b_actf;
- if (bp) {
- fpc->fp = fp;
- break;
- }
- }
-
- if (fpc->fp)
- return(1);
-
- fpc->state = FINDWORK;
- TRACE1("[fpc%d IDLE]\n", fpc->fpcu);
- return(0);
- }
-
- dp = &(fp->head);
- bp = dp->b_actf;
-
- blknum = (u_long)bp->b_blkno * DEV_BSIZE / FDBLK + fp->skip / FDBLK;
- track = blknum / fp->sects;
- sec = blknum % fp->sects;
-
- read = bp->b_flags & B_READ;
- TRACE1("fp%d", fp->fpu);
- TRACE1("[%s]", fpstates[fpc->state]);
- TRACE1("(0x%x) ", fp->flags);
- TRACE1("%d\n", fp->buf_track);
-
- untimeout((timeout_t)fp_turnoff, (caddr_t)fpc);
- timeout((timeout_t)fp_turnoff, (caddr_t)fpc, 4 * hz);
-
- switch (fpc->state) {
- case FINDWORK:
- if (!bp) {
- if (fp->buf_dirty) {
- track_write(fpc, fp);
- return(0);
- }
- fpc->fp = NULL;
- return(1);
- }
-
- fpc->state = DOSEEK;
- fpc->retry = 0;
- fp->skip = 0;
- return(1);
- case DOSEEK:
- fp_turnon(fpc, fp->fpu);
-
- /*
- * If not started, error starting it
- */
- if (fpc->motor_fpu != fp->fpu) {
- /* XXXX */
- printf("motor not on!\n");
- }
-
- /*
- * If track not in buffer, read it in
- */
- if (fp->buf_track != track) {
- TRACE1("do track %d\n", track);
-
- if (fp->buf_dirty)
- track_write(fpc, fp);
- else
- track_read(fpc, fp, track);
- return(0);
- }
-
- fpc->state = DO_IO;
- return(1);
- case DO_IO:
- if (read)
- bcopy(&fp->buf_data[sec * FDBLK],
- bp->b_un.b_addr + fp->skip, FDBLK);
- else {
- bcopy(bp->b_un.b_addr + fp->skip,
- &fp->buf_data[sec * FDBLK], FDBLK);
- fp->buf_dirty = 1;
- if (IMMED_WRITE) {
- fpc->state = DONE_IO;
- track_write(fpc, fp);
- return(0);
- }
- }
- case DONE_IO:
- fp->skip += FDBLK;
- if (fp->skip < bp->b_bcount)
- fpc->state = DOSEEK;
- else {
- fp->skip = 0;
- bp->b_resid = 0;
- dp->b_actf = bp->b_actf;
- biodone(bp);
- fpc->state = FINDWORK;
- }
- return(1);
- case WAIT_READ:
- untimeout((timeout_t)fp_timeout, (caddr_t)fpc);
- custom.dsklen = 0;
- amiga_read(fp);
- fpc->state = DO_IO;
- return(1);
- case WAIT_WRITE:
- untimeout((timeout_t)fp_timeout, (caddr_t)fpc);
- custom.dsklen = 0;
- fpc->state = fpc->saved;
- fp->buf_dirty = 0;
- return(1);
- default:
- /* XXXX */
- printf("Unexpected FP int->%d\n", fpc->state);
- return 0;
- }
-
- /* Come back immediatly to new state */
- return(1);
-}
-
-int
-retrier(fpc)
- fpc_p fpc;
-{
- struct buf *dp,*bp;
- fp_p fp;
-
- fp = fpc->fp;
- dp = &(fp->head);
- bp = dp->b_actf;
-
-#if 0
- switch(fpc->retry) {
- case 0:
- case 1:
- case 2:
- fpc->state = SEEKCOMPLETE;
- break;
- case 3:
- case 4:
- case 5:
- fpc->state = STARTRECAL;
- break;
- case 6:
- fpc->state = RESETCTLR;
- break;
- case 7:
- break;
- default:
-#endif
- /* XXXX */
- printf("fp%d: hard error\n", fp->fpu);
-
- bp->b_flags |= B_ERROR;
- bp->b_error = EIO;
- bp->b_resid = bp->b_bcount - fp->skip;
- dp->b_actf = bp->b_actf;
- fp->skip = 0;
- biodone(bp);
- fpc->state = FINDWORK;
- return(1);
-#if 0
- fpc->retry++;
- return(1);
-#endif
-}
-
-#endif