summaryrefslogtreecommitdiff
path: root/chips/fdc_82077_hdw.c
diff options
context:
space:
mode:
Diffstat (limited to 'chips/fdc_82077_hdw.c')
-rw-r--r--chips/fdc_82077_hdw.c821
1 files changed, 0 insertions, 821 deletions
diff --git a/chips/fdc_82077_hdw.c b/chips/fdc_82077_hdw.c
deleted file mode 100644
index f52da83..0000000
--- a/chips/fdc_82077_hdw.c
+++ /dev/null
@@ -1,821 +0,0 @@
-/*
- * Mach Operating System
- * Copyright (c) 1992 Carnegie Mellon University
- * All Rights Reserved.
- *
- * Permission to use, copy, modify and distribute this software and its
- * documentation is hereby granted, provided that both the copyright
- * notice and this permission notice appear in all copies of the
- * software, derivative works or modified versions, and any portions
- * thereof, and that both notices appear in supporting documentation.
- *
- * CARNEGIE MELLON ALLOWS FREE USE OF THIS SOFTWARE IN ITS "AS IS"
- * CONDITION. CARNEGIE MELLON DISCLAIMS ANY LIABILITY OF ANY KIND FOR
- * ANY DAMAGES WHATSOEVER RESULTING FROM THE USE OF THIS SOFTWARE.
- *
- * Carnegie Mellon requests users of this software to return to
- *
- * Software Distribution Coordinator or Software.Distribution@CS.CMU.EDU
- * School of Computer Science
- * Carnegie Mellon University
- * Pittsburgh PA 15213-3890
- *
- * any improvements or extensions that they make and grant Carnegie Mellon
- * the rights to redistribute these changes.
- */
-/*
- * File: fdi_82077_hdw.c
- * Author: Alessandro Forin, Carnegie Mellon University
- * Date: 1/92
- *
- * Driver for the Intel 82077 Floppy Disk Controller.
- */
-
-#include <fd.h>
-#if NFD > 0
-
-#include <mach/std_types.h>
-#include <machine/machspl.h>
-#include <chips/busses.h>
-
-#include <chips/fdc_82077.h>
-#include <platforms.h>
-
-/* ---- */
-#include <device/param.h>
-#include <device/io_req.h>
-#include <device/device_types.h>
-#include <device/disk_status.h>
-#define UNITNO(d) ((d)>>5)
-#define SLAVENO(d) (((d)>>3)&0x3)
-#define PARAMNO(d) ((d)&0x7)
-/* ---- */
-
-#ifdef MAXINE
-
-/* we can only take one */
-#define MAX_DRIVES 1
-
-#define my_fdc_type fdc_82077aa
-#define the_fdc_type fd->fdc_type
-/* later: #define the_fdc_type my_fdc_type */
-
-/* Registers are read/written as words, byte 0 */
-/* padding is to x40 boundaries */
-typedef struct {
- volatile unsigned int fd_sra; /* r: status register A */
- int pad0[15];
- volatile unsigned int fd_srb; /* r: status register B */
- int pad1[15];
- volatile unsigned int fd_dor; /* rw: digital output reg */
- int pad2[15];
- volatile unsigned int fd_tdr; /* rw: tape drive register */
- int pad3[15];
- volatile unsigned int fd_msr; /* r: main status register */
-/*#define fd_dsr fd_msr; /* w: data rate select reg */
- int pad4[15];
- volatile unsigned int fd_data; /* rw: fifo */
- int pad5[15];
- volatile unsigned int fd_xxx; /* --reserved-- */
- int pad6[15];
- volatile unsigned int fd_dir; /* r: digital input reg */
-/*#define fd_ccr fd_dir; /* w: config control reg */
-} fd_padded_regmap_t;
-
-#define machdep_reset_8272a(f,r)
-
-#else /* MAXINE */
-
-/* Pick your chip and padding */
-#define my_fdc_type fdc_8272a
-#define the_fdc_type my_fdc_type
-
-#define fd_padded_regmap_t fd_8272a_regmap_t
-
-#define machdep_reset_8272a(f,r) 1
-
-#endif /* MAXINE */
-
-
-#ifndef MAX_DRIVES
-#define MAX_DRIVES DRIVES_PER_FDC
-#endif
-
-/*
- * Autoconf info
- */
-
-static vm_offset_t fd_std[NFD] = { 0 };
-static struct bus_device *fd_info[NFD];
-static struct bus_ctlr *fd_minfo[NFD];
-static int fd_probe(), fd_slave(), fd_go();
-static void fd_attach();
-
-struct bus_driver fd_driver =
- { fd_probe, fd_slave, fd_attach, fd_go, fd_std, "fd", fd_info,
- "fdc", fd_minfo, /*BUS_INTR_B4_PROBE*/};
-
-/*
- * Externally visible functions
- */
-int fd_intr(); /* kernel */
-
-/*
- * Media table
- *
- * Cyls,Sec,spc,part,Mtype,RWFpl,FGpl
- */
-typedef struct {
- unsigned char d_cylperunit;
- unsigned char d_secpercyl;
- unsigned short d_secperunit;
- unsigned char d_secpertrk;
- unsigned char d_gpl;
- unsigned char d_fgpl;
- unsigned char d_xfer_rate;
-} fd_params_t;
-
-fd_params_t fd_params[8] = {
- {80, 18, 1440, 9, 0x2a, 0x50, FD_DSR_DD_250}, /* [0] 3.50" 720 Kb */
- {80, 36, 2880, 18, 0x1b, 0x6c, FD_DSR_DD_500}, /* [1] 3.50" 1.44 Meg */
- {40, 18, 720, 9, 0x2a, 0x50, FD_DSR_DD_250}, /* [2] 5.25" 360 Kb */
- {80, 30, 2400, 15, 0x1b, 0x54, FD_DSR_DD_500}, /* [3] 5.25" 1.20 Meg */
-};
-
-/*
- * Software status of chip
- */
-struct fd_softc {
- fd_padded_regmap_t *regs;
- char fdc_type;
- char fdc_mode;
- char messed_up;
- char slave_active;
- struct slave_t {
- io_req_t ior;
- decl_simple_lock_data(,slave_lock)
-
- /* status at end of last command */
- unsigned char st0;
- unsigned char st1;
- unsigned char st2;
- unsigned char c;
- unsigned char h;
- unsigned char r;
- unsigned char n;
- unsigned char st3;
- /* ... */
- unsigned char medium_status;
-# define ST_MEDIUM_PRESENT 1
-# define ST_MEDIUM_KNOWN 2
- char last_command;
- char bytes_expected;
- fd_params_t *params;
-
- } slave_status[DRIVES_PER_FDC];
-} fd_softc_data[NFD];
-
-typedef struct fd_softc *fd_softc_t;
-
-fd_softc_t fd_softc[NFD];
-
-static char *chip_names[4] = { "8272-A", "82072", "82077-AA", 0 };
-static char *mode_names[4] = { "PC AT", "PS/2", "Model 30", 0 };
-
-/*
- * Probe chip to see if it is there
- */
-static fd_probe (reg, ctlr)
- vm_offset_t reg;
- struct bus_ctlr *ctlr;
-{
- int unit = ctlr->unit;
- fd_softc_t fd;
- fd_padded_regmap_t *regs;
-
- /*
- * See if we are here
- */
- if (check_memory(reg, 0)) {
- /* no rides today */
- return 0;
- }
-
- fd = &fd_softc_data[unit];
- fd_softc[unit] = fd;
-
- regs = (fd_padded_regmap_t *)reg;
- fd->regs = regs;
- fd->fdc_type = my_fdc_type;
-
- fd_reset(fd);
-
- if (the_fdc_type == fdc_82077aa) {
- /* See if properly functioning */
- unsigned char temp = FD_CMD_VERSION;
- if (!fd_go(fd, 0, &temp, 1, 1))
- return 0; /* total brxage */
- if (!fd_get_result(fd, &temp, 1, FALSE))
- return 0; /* partial brxage */
- if (temp != FD_VERSION_82077AA)
- printf( "{ %s x%x } ",
- "Accepting non-82077aa version id",
- temp);
- }
-
- printf("%s%d: %s chip controller",
- ctlr->name, ctlr->unit, chip_names[fd->fdc_type]);
- if (the_fdc_type == fdc_82077aa)
- printf(" in %s mode", mode_names[fd->fdc_mode]);
- printf(".\n");
-
- return 1;
-}
-
-/* See if we like this slave */
-static fd_slave(ui, reg)
- struct bus_device *ui;
- vm_offset_t reg;
-{
- int slave = ui->slave;
- fd_softc_t fd;
- unsigned char sns[2];
-
- if (slave >= MAX_DRIVES) return 0;
-
- fd = fd_softc[ui->ctlr];
-
- sns[0] = FD_CMD_SENSE_DRIVE_STATUS;
- sns[1] = slave & 0x3;
- if (the_fdc_type == fdc_82072)
- sns[1] |= FD_CMD_SDS_NO_MOT;
- if (!fd_go(fd, slave, sns, 2, 1)) return 0;
- if (!fd_get_result(fd, sns, 1, FALSE)) return 0;
-
- fd->slave_status[slave].st3 = sns[0];
-
- return 1;
-}
-
-static void
-fd_attach (ui)
- struct bus_device *ui;
-{
- /* Attach a slave */
-}
-
-static boolean_t
-fd_go(fd, slave, cmd, cmdlen, reply_count)
- fd_softc_t fd;
- unsigned char cmd[];
-{
-
- /* XXX check who active, enque ifnot */
-
- fd->slave_active = slave;
- fd->slave_status[slave].bytes_expected = reply_count;
- fd->slave_status[slave].last_command = *cmd;
- return fd_command(fd, cmd, cmdlen);
-}
-
-fd_intr (unit, spllevel)
-{
- fd_softc_t fd;
- fd_padded_regmap_t *regs;
- unsigned char msr;
- register struct slave_t *slv;
-
-
- splx(spllevel);
-
- fd = fd_softc[unit];
- regs = fd->regs;
-
- /* did polling see a media change */
- /* busy bit in msr sez ifasync or not */
-
- msr = regs->fd_msr;
- if ((msr & (FD_MSR_RQM|FD_MSR_DIO)) == (FD_MSR_RQM|FD_MSR_DIO)) {
-
- /* result phase */
-*(unsigned int *)0xbc040100 &= ~0x00600000;
-
- slv = &fd->slave_status[fd->slave_active];
- fd_get_result(fd, &slv->st0, slv->bytes_expected, FALSE);
- fd_start(fd, fd->slave_active, TRUE);
- return;
- }
- /* async interrupt, either seek complete or media change */
- while (1) {
- unsigned char st[2];
- register int slave, m;
-
- *st = FD_CMD_SENSE_INT_STATUS;
- fd_command(fd, st, 1);
-
- fd_get_result(fd, st, 2, FALSE);
-
- slave = *st & FD_ST0_DS;
- slv = &fd->slave_status[slave];
- slv->c = st[1];
-
- switch (*st & FD_ST0_IC_MASK) {
-
- case FD_ST0_IC_OK:
-/* we get an FD_ST0_SE for RECALIBRATE. Wait for it or discard ? */
-
- case FD_ST0_IC_AT:
-
- case FD_ST0_IC_BAD_CMD:
- return;
-
- case FD_ST0_IC_AT_POLL:
- m = slv->medium_status;
- if (m & ST_MEDIUM_PRESENT)
- m &= ~ST_MEDIUM_PRESENT;
- else
- m |= ST_MEDIUM_PRESENT;
- slv->medium_status = m;
- }
- }
-}
-
-/*
- * Non-interface functions and utilities
- */
-
-fd_reset(fd)
- fd_softc_t fd;
-{
- register fd_padded_regmap_t *regs;
-
- regs = fd->regs;
-
- /*
- * Reset the chip
- */
- if (the_fdc_type == fdc_82072)
- /* Fix if your box uses an external PLL */
- regs->fd_dsr = FD_DSR_RESET | FD_DSR_EPLL;
- else if (the_fdc_type == fdc_82077aa)
- regs->fd_dor = 0;
- else
- machdep_reset_8272a(fd, regs);
-
- delay(5); /* 4usecs in specs */
-
- /*
- * Be smart with the smart ones
- */
- if (the_fdc_type == fdc_82077aa) {
-
- /*
- * See in which mood we are (it cannot be changed)
- */
- int temp;
-
- /* Take chip out of hw reset */
- regs->fd_dor = FD_DOR_ENABLE | FD_DOR_DMA_GATE;
- delay(10);
-
- /* what do we readback from the DIR register as datarate ? */
- regs->fd_ccr = FD_DSR_SD_125;
- delay(10);
-
- temp = regs->fd_dir;
- if ((temp & 0x7) == FD_DSR_SD_125)
- fd->fdc_mode = mod30_mode;
- else if ((temp & (FD_DIR_ones | FD_DIR_DR_MASK_PS2)) ==
- ((FD_DSR_SD_125 << FD_DIR_DR_SHIFT_PS2) | FD_DIR_ones))
- fd->fdc_mode = ps2_mode;
- else
- /* this assumes tri-stated bits 1&2 read the same */
- fd->fdc_mode = at_mode;
-
- }
-
- /*
- * Send at least 4 sense interrupt cmds, one per slave
- */
- {
-
- unsigned char sns, st[2];
- int i, nloops;
-
- sns = FD_CMD_SENSE_INT_STATUS;
- i = nloops = 0;
-
- do {
- nloops++;
-
- (void) fd_command(fd, &sns, 1);
-
- st[0] = 0; /* in case bad status */
- (void) fd_get_result(fd, st, 2, TRUE);
-
- if ((st[0] & FD_ST0_IC_MASK) == FD_ST0_IC_AT_POLL) {
- register int slave;
-
- slave = st[0] & FD_ST0_DS;
- fd->slave_status[slave].st0 = st[0];
- fd->slave_status[slave].c = st[1];
- i++;
- }
- } while ( (nloops < 30) &&
- ((i < 4) || (st[0] != FD_ST0_IC_BAD_CMD)) );
-
- /* sanity check */
- if (nloops == 30) {
- (void) fd_messed_up(fd);
- return;
- }
- }
-
- /*
- * Install current parameters
- */
- if (the_fdc_type != fdc_8272a) {
-
- unsigned char cnf[4];
-
- /* send configure command to turn polling off */
- cnf[0] = FD_CMD_CONFIGURE;
- cnf[1] = 0x60; /* moff 110 */
- cnf[2] = 0x48; /* eis, poll, thr=8 */
- cnf[3] = 0;
- if (!fd_command(fd, cnf, 4))
- return;
- /* no status */
- }
-
- /*
- * Send specify to select defaults
- */
- {
- unsigned char sfy[3];
-
- sfy[0] = FD_CMD_SPECIFY;
-#if 0
- sfy[1] = (12 << 4) | 7; /* step 4, hut 112us @500 */
- sfy[2] = 2 << 1; /* hlt 29us @500 */
-#else
- sfy[1] = (13 << 4) | 15;
- sfy[2] = 1 << 1;
-#endif
- (void) fd_command(fd, sfy, 3);
- /* no status */
- }
-}
-
-#define FD_MAX_WAIT 1000
-
-boolean_t
-fd_command(fd, cmd, cmd_len)
- fd_softc_t fd;
- char *cmd;
-{
- register fd_padded_regmap_t *regs;
-
- regs = fd->regs;
-
- while (cmd_len > 0) {
- register int i, s;
-
- /* there might be long delays, so we pay this price */
- s = splhigh();
- for (i = 0; i < FD_MAX_WAIT; i++)
- if ((regs->fd_msr & (FD_MSR_RQM|FD_MSR_DIO)) ==
- FD_MSR_RQM)
- break;
- else
- delay(10);
- if (i == FD_MAX_WAIT) {
- splx(s);
- return fd_messed_up(fd);
- }
- regs->fd_data = *cmd++;
- splx(s);
- if (--cmd_len) delay(12);
- }
-
- return TRUE;
-}
-
-boolean_t
-fd_get_result(fd, st, st_len, ignore_errors)
- fd_softc_t fd;
- char *st;
-{
- register fd_padded_regmap_t *regs;
-
- regs = fd->regs;
-
- while (st_len > 0) {
- register int i, s;
-
- /* there might be long delays, so we pay this price */
- s = splhigh();
- for (i = 0; i < FD_MAX_WAIT; i++)
- if ((regs->fd_msr & (FD_MSR_RQM|FD_MSR_DIO)) ==
- (FD_MSR_RQM|FD_MSR_DIO))
- break;
- else
- delay(10);
- if (i == FD_MAX_WAIT) {
- splx(s);
- return (ignore_errors) ? FALSE : fd_messed_up(fd);
- }
- *st++ = regs->fd_data;
- splx(s);
- st_len--;
- }
-
- return TRUE;
-}
-
-
-boolean_t
-fd_messed_up(fd)
- fd_softc_t fd;
-{
- fd->messed_up++;
- printf("fd%d: messed up, disabling.\n", fd - fd_softc_data);
- /* here code to
- ior->error = ..;
- restart
- */
- return FALSE;
-}
-
-/*
- * Debugging aids
- */
-
-fd_state(unit)
-{
- fd_softc_t fd = fd_softc[unit];
- fd_padded_regmap_t *regs;
-
- if (!fd || !fd->regs) return 0;
- regs = fd->regs;
- if (the_fdc_type == fdc_8272a)
- printf("msr %x\n", regs->fd_msr);
- else
- printf("sra %x srb %x dor %x tdr %x msr %x dir %x\n",
- regs->fd_sra, regs->fd_srb, regs->fd_dor,
- regs->fd_tdr, regs->fd_msr, regs->fd_dir);
-}
-
-#endif
-
-/* to be moved in separate file, or the above modified to live with scsi */
-
-fd_open(dev, mode, ior)
- int dev;
- dev_mode_t mode;
- io_req_t ior;
-{
- unsigned char cmd[2];
- fd_softc_t fd;
- int slave;
-
- fd = fd_softc[UNITNO(dev)];
- slave = SLAVENO(dev);
-
- /* XXX find out what medium we have, automagically XXX */
- /* fornow, set params depending on minor */
- fd->slave_status[slave].params = &fd_params[PARAMNO(dev)];
-
- /* XXXYYYXXXYYY SEND CONFIGURE if params changed */
-
- /* Turn motor on */
- if (the_fdc_type == fdc_82072) {
-
- cmd[0] = FD_CMD_MOTOR_ON_OFF | FD_CMD_MOT_ON |
- ((slave << FD_CMD_MOT_DS_SHIFT) & FD_CMD_MOT_DS);
- (void) fd_go(fd, slave, cmd, 1, 0);
- /* no status */
-
- } else if (the_fdc_type == fdc_82077aa) {
-
- fd->regs->fd_dor |= ((1<<slave)<<4);
- }
-
- /* recalibrate to track 0 */
- cmd[0] = FD_CMD_RECALIBRATE;
- cmd[1] = slave;
- if (!fd_go(fd, slave, cmd, 2, 0))
- return D_DEVICE_DOWN;
- /* will generate a completion interrupt */
-
- /* if not writeable return D_READ_ONLY ? */
-
- return D_SUCCESS;
-}
-
-fd_close(dev)
- int dev;
-{
- fd_softc_t fd;
- register int slave;
- unsigned char cmd[2];
-
- slave = SLAVENO(dev);
- fd = fd_softc[UNITNO(dev)];
-
- /* do not delete media info, do that iff interrupt sez changed */
-
- /* Turn motor off */
- if (the_fdc_type == fdc_82072) {
-
- cmd[0] = FD_CMD_MOTOR_ON_OFF |
- ((slave << FD_CMD_MOT_DS_SHIFT) & FD_CMD_MOT_DS);
- (void) fd_go(fd, 0, cmd, 1, 0);
- /* no status */
-
- } else if (the_fdc_type == fdc_82077aa) {
-
- fd->regs->fd_dor &= ~((1<<slave)<<4);
- }
- return D_SUCCESS;
-}
-
-fd_strategy(ior)
- io_req_t ior;
-{
-#if 0
- if (ior->io_op & IO_READ)
- bzero(ior->io_data, ior->io_count);
- iodone(ior);
-#else
- struct slave_t *slv;
- fd_softc_t fd;
- unsigned int i, rec, max, dev;
- fd_params_t *params;
-
- /* readonly */
-
- dev = ior->io_unit;
-
- /* only one partition */
- fd = fd_softc[UNITNO(dev)];
- slv = &fd->slave_status[SLAVENO(dev)];
- params = slv->params;
- max = params->d_secperunit;
- rec = ior->io_recnum;
- i = btodb(ior->io_count + DEV_BSIZE - 1);
- if (((rec + i) > max) || (ior->io_count < 0)) {
- ior->io_error = D_INVALID_SIZE;
- ior->io_op |= IO_ERROR;
- ior->io_residual = ior->io_count;
- iodone(ior);
- return;
- }
-
- ior->io_residual = rec / params->d_secpercyl;
-
- /*
- * Enqueue operation
- */
- i = splbio();
- simple_lock(&slv->slave_lock);
- if (slv->ior) {
- disksort(slv->ior, ior);
- simple_unlock(&slv->slave_lock);
- } else {
- ior->io_next = 0;
- slv->ior = ior;
- simple_unlock(&slv->slave_lock);
- fd_start(fd, SLAVENO(dev), FALSE);
- }
- splx(i);
-#endif
-}
-
-fd_start(fd, slave, done)
- boolean_t done;
- fd_softc_t fd;
-{
- register io_req_t ior;
- struct slave_t *slv;
-
- slv = &fd->slave_status[slave];
- if ((ior = slv->ior) == 0)
- return;
-
- if (done) {
- /* .. errors .. */
- /* .. partial xfers .. */
-
- /* dequeue next one */
- {
- io_req_t next;
-
- simple_lock(&slv->target_lock);
- next = ior->io_next;
- slv->ior = next;
- simple_unlock(&slv->target_lock);
-
- iodone(ior);
- if (next == 0)
- return;
-
- ior = next;
- }
- }
-
-#ifdef no_eis
- if (slv->c != ior->io_residual) SEEK_it;
-#endif
-
-/* setup dma */
-#if 1
- if (ior->io_op & IO_READ) /* like SCSI */
-#else
- if ((ior->io_op & IO_READ) == 0)
-#endif
- {
- *(unsigned int *)0xbc040100 |= 0x00200000 | 0x00400000;
- } else {
- *(unsigned int *)0xbc040100 &= ~0x00400000;
- *(unsigned int *)0xbc040100 |= 0x00200000;
- }
- *(unsigned int *)0xbc040070 = (((unsigned int)kvtophys(ior->io_data))>>2)<<5;
- *(unsigned int *)0xbc0401a0 = 13;
-
-#ifdef no_eis
- if (slv->c == ior->io_residual) {
-#else
- {
-#endif
- unsigned char cmd[9];
- unsigned char head, sec;
- fd_params_t *params;
-
- params = slv->params;
-
- fd->regs->fd_dsr = params->d_xfer_rate;
-
- sec = ior->io_recnum % params->d_secpercyl;
- head = sec / params->d_secpertrk;
- sec = (sec % params->d_secpertrk);
-
- cmd[0] = (ior->io_op & IO_READ) ?
- FD_CMD_MT | FD_CMD_MFM | FD_CMD_READ_DATA :
- FD_CMD_MT | FD_CMD_MFM | FD_CMD_WRITE_DATA;
- cmd[1] = (head << 2) | slave;
- cmd[2] = ior->io_residual;
- cmd[3] = head;
- cmd[4] = sec + 1; /* 0 starts at 1 :-) */
- cmd[5] = 0x2; /* 512 byte sectors */
- cmd[6] = params->d_secpertrk;
- cmd[7] = params->d_gpl;
- cmd[8] = 0xff;
-
- fd_go( fd, slave, cmd, 9, 7);
-
- }
-}
-
-extern minphys();
-
-fd_read(dev, ior)
- int dev;
- io_req_t ior;
-{
- return block_io(fd_strategy, minphys, ior);
-}
-
-int fdc_write_enable = 1;
-
-fd_write(dev, ior)
- int dev;
- io_req_t ior;
-{
-/* check if writeable */
-
-if (fdc_write_enable)
- return block_io(fd_strategy, minphys, ior);
-else return D_SUCCESS;
-}
-
-fd_set_status(dev, flavor, status, status_count)
- int dev;
- int flavor;
- dev_status_t status;
- unsigned int *status_count;
-{
- printf("fdc_set_status(%x, %x, %x, %x)", dev, flavor, status, status_count);
- return D_SUCCESS;
-}
-
-fd_get_status(dev, flavor, status, status_count)
- int dev;
- int flavor;
- dev_status_t status;
- unsigned int status_count;
-{
- printf("fdc_get_status(%x, %x, %x, %x)", dev, flavor, status, status_count);
- return D_SUCCESS;
-}
-