From dbf91c827d39d04dccb93ffcb9146c3034e0d75a Mon Sep 17 00:00:00 2001 From: jdolecek Date: Thu, 19 Apr 2001 17:17:28 +0000 Subject: Use "edc" instead of "dasd". As pointed out by Soren, dasd doesn't mean anything special in IBM-talk. And edc better matches prior art, too. --- sys/dev/DEVNAMES | 4 +- sys/dev/mca/dasd_mca.c | 810 ------------------------------------------------- sys/dev/mca/dasdreg.h | 131 -------- sys/dev/mca/dasdvar.h | 43 --- sys/dev/mca/ed_mca.c | 26 +- sys/dev/mca/edc_mca.c | 810 +++++++++++++++++++++++++++++++++++++++++++++++++ sys/dev/mca/edcreg.h | 131 ++++++++ sys/dev/mca/edcvar.h | 43 +++ sys/dev/mca/edvar.h | 6 +- sys/dev/mca/files.mca | 10 +- 10 files changed, 1007 insertions(+), 1007 deletions(-) delete mode 100644 sys/dev/mca/dasd_mca.c delete mode 100644 sys/dev/mca/dasdreg.h delete mode 100644 sys/dev/mca/dasdvar.h create mode 100644 sys/dev/mca/edc_mca.c create mode 100644 sys/dev/mca/edcreg.h create mode 100644 sys/dev/mca/edcvar.h (limited to 'sys/dev') diff --git a/sys/dev/DEVNAMES b/sys/dev/DEVNAMES index 1f0776e689d..639c6ca561b 100644 --- a/sys/dev/DEVNAMES +++ b/sys/dev/DEVNAMES @@ -1,4 +1,4 @@ -# $NetBSD: DEVNAMES,v 1.47 2001/04/19 07:47:50 jdolecek Exp $ +# $NetBSD: DEVNAMES,v 1.48 2001/04/19 17:17:28 jdolecek Exp $ # # This file contains all used device names and defined attributes in # alphabetical order. New devices added to the system somewhere should first @@ -213,7 +213,6 @@ cy MI cy82c693 MI cz MI daic MI -dasd MI (MCA) dc pmax dca hp300 dcm hp300 @@ -255,6 +254,7 @@ eccmemctl sparc ed amiga ed amigappc ed MI (MCA) +edc MI (MCA) eeprom sparc eeprom sparc64 eeprom sun3 diff --git a/sys/dev/mca/dasd_mca.c b/sys/dev/mca/dasd_mca.c deleted file mode 100644 index 560ed4fd0f9..00000000000 --- a/sys/dev/mca/dasd_mca.c +++ /dev/null @@ -1,810 +0,0 @@ -/* $NetBSD: dasd_mca.c,v 1.1 2001/04/19 07:30:24 jdolecek Exp $ */ - -/* - * Copyright (c) 2001 The NetBSD Foundation, Inc. - * - * This code is derived from software contributed to The NetBSD Foundation - * by Jaromir Dolecek. - * - * 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 NetBSD - * Foundation, Inc. and its contributors. - * 4. The name of the author may not be used to endorse or promote products - * derived from this software without specific prior written permission. - * - * THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``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 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. - */ - -/* - * Driver for MCA ESDI controllers and disks conforming to IBM DASD - * spec. - * - * The driver was written with DASD Storage Interface Specification - * for MCA rev. 2.2 in hands, thanks to Scott Telford . - * - * TODO: - * - move the MCA DMA controller (dasd_setup_dma()) goo to device driver - * independant location - * - improve error recovery - * add any soft resets when anything gets stuck? - * - test with > 1 disk (this is supported by some controllers), eliminate - * any remaining devno=0 assumptions if there are any still - * - test with > 1 ESDI controller in machine; shared interrupts - * necessary for this to work should be supported - dasd_intr() specifically - * checks if the interrupt is for this controller - */ - -#include "rnd.h" - -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#if NRND > 0 -#include -#endif - -#include -#include - -#include -#include -#include - -#include -#include -#include - -#define DASD_MAXDEVS 7 -struct dasd_mca_softc { - struct device sc_dev; - - bus_space_tag_t sc_iot; - bus_space_handle_t sc_ioh; - - bus_dma_tag_t sc_dmat; /* DMA tag as passed by parent */ - bus_space_handle_t sc_dmaextcmdh; - bus_space_handle_t sc_dmaexech; - - void *sc_ih; /* interrupt handle */ - int sc_drq; /* DRQ number */ - int sc_cmd_async; /* asynchronous cmd pending */ - - int sc_flags; -#define DASD_QUIET 0x01 /* don't dump cmd error info */ - struct ed_softc *sc_ed[DASD_MAXDEVS]; - - int sc_maxdevs; /* maximum # of devs supported by - * controller */ -}; - -int dasd_mca_probe __P((struct device *, struct cfdata *, void *)); -void dasd_mca_attach __P((struct device *, struct device *, void *)); - -struct cfattach dasd_mca_ca = { - sizeof(struct dasd_mca_softc), dasd_mca_probe, dasd_mca_attach -}; - -#define DMA_EXTCMD 0x18 -#define DMA_EXEC 0x1A - -static int dasd_intr __P((void *)); -static void dasd_attach_ed __P((struct device *)); -static void dasd_dump_status_block __P((struct dasd_mca_softc *, int, int, - int)); -static int dasd_setup_dma __P((struct dasd_mca_softc *, struct buf *, - bus_addr_t, bus_size_t)); -static int dasd_do_attn __P((struct dasd_mca_softc *, int, int, int)); -static int dasd_cmd_wait __P((struct dasd_mca_softc *, int, int, int)); - -int -dasd_mca_probe(parent, match, aux) - struct device *parent; - struct cfdata *match; - void *aux; -{ - struct mca_attach_args *ma = aux; - - switch (ma->ma_id) { - case MCA_PRODUCT_IBM_ESDIC: - case MCA_PRODUCT_IBM_ESDIC_IG: - return (1); - default: - return (0); - } -} - -void -dasd_mca_attach(parent, self, aux) - struct device *parent, *self; - void *aux; -{ - struct dasd_mca_softc *sc = (void *) self; - struct mca_attach_args *ma = aux; - int pos2, pos3, pos4; - int irq, drq, iobase; - const char *typestr; - - pos2 = mca_conf_read(ma->ma_mc, ma->ma_slot, 2); - pos3 = mca_conf_read(ma->ma_mc, ma->ma_slot, 3); - pos4 = mca_conf_read(ma->ma_mc, ma->ma_slot, 4); - - /* - * POS register 2: (adf pos0) - * - * 7 6 5 4 3 2 1 0 - * \ \____/ \ \__ enable: 0=adapter disabled, 1=adapter enabled - * \ \ \___ Primary/Alternate Port Adresses: - * \ \ 0=0x3510-3517 1=0x3518-0x351f - * \ \_____ DMA Arbitration Level: 0101=5 0110=6 0111=7 - * \ 0000=0 0001=1 0011=3 0100=4 - * \_________ Fairness On/Off: 1=On 0=Off - * - * POS register 3: (adf pos1) - * - * 7 6 5 4 3 2 1 0 - * 0 0 \_/ - * \__________ DMA Burst Pacing Interval: 10=24ms 11=31ms - * 01=16ms 00=Burst Disabled - * - * POS register 4: (adf pos2) - * - * 7 6 5 4 3 2 1 0 - * \_/ \__ DMA Pacing Control: 1=Disabled 0=Enabled - * \____ Time to Release: 1X=6ms 01=3ms 00=Immediate - * - * IRQ is fixed to 14 (0x0e). - */ - - switch (ma->ma_id) { - case MCA_PRODUCT_IBM_ESDIC: - typestr = "IBM ESDI Fixed Disk Controller"; - break; - case MCA_PRODUCT_IBM_ESDIC_IG: - typestr = "IBM Integ. ESDI Fixed Disk & Controller"; - break; - default: - /* never reached */ - } - - printf(" slot %d: %s\n", ma->ma_slot+1, typestr); - - irq = ESDIC_IRQ; - iobase = (pos2 & IO_IS_ALT) ? ESDIC_IOALT : ESDIC_IOPRM; - drq = (pos2 & DRQ_MASK) >> 2; - -#ifdef DIAGNOSTIC - /* - * It's not strictly necessary to check this, machine configuration - * utility uses only valid adresses. - */ - if (drq == 2 || drq >= 8) { - printf("%s: invalid DMA Arbitration Level %d\n", - sc->sc_dev.dv_xname, drq); - return; - } -#endif - - printf("%s: Fairness %s, Release %s, DRQ %d, ", - sc->sc_dev.dv_xname, - (pos2 & FAIRNESS_ENABLE) ? "On" : "Off", - (pos4 & RELEASE_1) ? "6ms" - : ((pos4 & RELEASE_2) ? "3ms" : "Immediate"), - drq); - if ((pos4 & PACING_CTRL_DISABLE) == 0) { - static const char * const pacint[] = - { "disabled", "16ms", "24ms", "31ms"}; - printf("DMA burst pacing interval %s\n", - pacint[(pos3 & PACING_INT_MASK) >> 4]); - } else - printf("DMA pacing control disabled\n"); - - sc->sc_iot = ma->ma_iot; - sc->sc_drq = drq; - - if (bus_space_map(sc->sc_iot, iobase, - ESDIC_REG_NPORTS, 0, &sc->sc_ioh)) { - printf("%s: couldn't map registers\n", - sc->sc_dev.dv_xname); - return; - } - - if (bus_space_map(sc->sc_iot, DMA_EXTCMD, 1, 0, &sc->sc_dmaextcmdh)) { - printf("%s: couldn't map registers\n", - sc->sc_dev.dv_xname); - return; - } - if (bus_space_map(sc->sc_iot, DMA_EXEC, 1, 0, &sc->sc_dmaexech)) { - printf("%s: couldn't map registers\n", - sc->sc_dev.dv_xname); - return; - } - - sc->sc_dmat = ma->ma_dmat; - - sc->sc_ih = mca_intr_establish(ma->ma_mc, irq, IPL_BIO, dasd_intr, sc); - if (sc->sc_ih == NULL) { - printf("%s: couldn't establish interrupt handler\n", - sc->sc_dev.dv_xname); - return; - } - printf("%s: interrupting at irq %d\n", sc->sc_dev.dv_xname, irq); - - /* - * Integrated ESDI controller supports only one disk, other - * controllers support two disks. - */ - if (ma->ma_id == MCA_PRODUCT_IBM_ESDIC_IG) - sc->sc_maxdevs = 1; - else - sc->sc_maxdevs = 2; - - /* Defer probe for individual disks until interrupts are enabled. */ - config_interrupts(self, dasd_attach_ed); -} - -/* - * Try to attach ed* at dasd? if any configured and installed now - * that interrupts are enabled. - */ -static void -dasd_attach_ed(self) - struct device *self; -{ - struct dasd_mca_softc *sc = (void *) self; - struct ed_softc *ed; - struct ed_attach_args eda; - int devno; - - /* Do a reset to ensure sane state after warm boot. */ - if (bus_space_read_1(sc->sc_iot, sc->sc_ioh, BSR) & BSR_BUSY) { - /* hard reset */ - printf("%s: controller busy, performing hardware reset ...\n", - sc->sc_dev.dv_xname); - bus_space_write_1(sc->sc_iot, sc->sc_ioh, BCR, - BCR_INT_ENABLE|BCR_RESET); - } else { - /* "SOFT" reset */ - dasd_do_attn(sc, ATN_RESET_ATTACHMENT, DASD_DEVNO_CONTROLLER,0); - } - - /* Wait until the reset completes. */ - while(bus_space_read_1(sc->sc_iot, sc->sc_ioh, BSR) & BSR_BUSY) - delay(1); - - /* - * Get dummy ed_softc to be used during probe. Once a disk is - * found, ed_mca_attach() calls dasd_add_disk() to insert the - * right pointer into sc->sc_ed[] array. - */ - MALLOC(ed, struct ed_softc *, sizeof(struct ed_softc), - M_TEMP, M_WAITOK); - - /* be quiet duting probes */ - sc->sc_flags |= DASD_QUIET; - - /* check for attached disks */ - for(devno=0; devno < sc->sc_maxdevs; devno++) { - eda.sc_devno = devno; - eda.sc_dmat = sc->sc_dmat; - sc->sc_ed[devno] = ed; - sc->sc_ed[devno] = - (void *) config_found_sm(self, &eda, NULL, NULL); - } - - /* enable full error dumps again */ - sc->sc_flags &= ~DASD_QUIET; - - /* cleanup */ - FREE(ed, M_TEMP); - - /* XXX disestablish interrupt if no disks found ? */ -} - -void -dasd_add_disk(sc, ed, devno) - struct dasd_mca_softc *sc; - struct ed_softc *ed; - int devno; -{ - sc->sc_ed[devno] = ed; -} - -static int -dasd_intr(arg) - void *arg; -{ - struct dasd_mca_softc *sc = arg; - u_int8_t isr, intr_id; - u_int16_t sifr; - int cmd, devno, bioerror; - struct ed_softc *ed=NULL; - - /* - * Check if the interrupt was for us. - */ - if ((bus_space_read_1(sc->sc_iot, sc->sc_ioh, BSR) & BSR_INTR) == 0) - return (0); - - /* - * Read ISR to find out interrupt type. This also clears the interrupt - * condition and BSR_INTR flag. Accordings to docs interrupt ID of 0, 2 - * and 4 are reserved and not used. - */ - isr = bus_space_read_1(sc->sc_iot, sc->sc_ioh, ISR); - intr_id = isr & ISR_INTR_ID_MASK; - -#ifdef DEBUG - if (intr_id == 0 || intr_id == 2 || intr_id == 4) { - printf("%s: bogus interrupt id %d\n", sc->sc_dev.dv_xname, - (int) intr_id); - return (0); - } -#endif - - /* Get number of device whose intr this was */ - devno = (isr & 0xe0) >> 5; - - /* - * Get Status block. Higher byte always says how long the status - * block is, rest is device number and command code. - * Check the status block length against our supported maximum length - * and fetch the data. - */ - if (bus_space_read_1(sc->sc_iot, sc->sc_ioh,BSR) & BSR_SIFR_FULL - && intr_id != ISR_RESET_COMPLETED) { - size_t len; - int i; - - sifr = le16toh(bus_space_read_2(sc->sc_iot, sc->sc_ioh, SIFR)); - len = (sifr & 0xff00) >> 8; - if (len > DASD_MAX_CMD_RES_LEN) { - printf("%s: maximum Status Length exceeded: %d > %d\n", - sc->sc_dev.dv_xname, - len, DASD_MAX_CMD_RES_LEN); - goto attn_eoi; - } - - /* Get command code */ - cmd = sifr & SIFR_CMD_MASK; - - /* Read whole status block */ - ed = sc->sc_ed[devno]; - ed->sc_status_block[0] = sifr; - for(i=1; i < len; i++) { - while((bus_space_read_1(sc->sc_iot, sc->sc_ioh, BSR) - & BSR_SIFR_FULL) == 0) - delay(1); - - ed->sc_status_block[i] = le16toh( - bus_space_read_2(sc->sc_iot, sc->sc_ioh, SIFR)); - } - } - - switch (intr_id) { - case ISR_DATA_TRANSFER_RDY: - /* - * Ready to do DMA, setup DMA controller and kick DASD - * controller to do the transfer. - */ - ed = sc->sc_ed[devno]; - if (!dasd_setup_dma(sc, ed->sc_bp, - ed->dmamap_xfer->dm_segs[0].ds_addr, - ed->dmamap_xfer->dm_segs[0].ds_len)) { - /* error XXX bail out? */ - bus_space_write_1(sc->sc_iot, sc->sc_ioh, BCR, - BCR_INT_ENABLE); - } else { - /* OK, proceed with DMA */ - bus_space_write_1(sc->sc_iot, sc->sc_ioh, BCR, - BCR_INT_ENABLE|BCR_DMA_ENABLE); - } - break; - case ISR_COMPLETED: - case ISR_COMPLETED_WITH_ECC: - case ISR_COMPLETED_RETRIES: - case ISR_COMPLETED_WARNING: - bioerror = 0; - break; - case ISR_RESET_COMPLETED: - case ISR_ABORT_COMPLETED: - /* nothing to do */ - break; - default: - if ((sc->sc_flags & DASD_QUIET) == 0) - dasd_dump_status_block(sc, devno, cmd, intr_id); - - bioerror = EIO; - break; - } - - attn_eoi: - /* - * Unless the interrupt is for Data Transfer Ready or - * Attention Error, finish by assertion EOI. This makes - * attachment aware the interrupt is processed and system - * is ready to accept another one. - */ - if (intr_id != ISR_DATA_TRANSFER_RDY && intr_id != ISR_ATTN_ERROR) - dasd_do_attn(sc, ATN_END_INT, devno, intr_id); - - /* If Read or Write Data, wakeup worker thread to finish it */ - if (intr_id != ISR_DATA_TRANSFER_RDY - && (cmd == CMD_READ_DATA || cmd == CMD_WRITE_DATA)) { - sc->sc_ed[devno]->sc_error = bioerror; - wakeup_one(&sc->sc_ed[devno]->dasd_softc); - } - - return (1); -} - -/* - * This follows the exact order for Attention Request as - * written in DASD Storage Interface Specification MC (Rev 2.2). - */ -static int -dasd_do_attn(sc, attn_type, devno, intr_id) - struct dasd_mca_softc *sc; - int attn_type, devno, intr_id; -{ - int tries; - - /* 1. Disable interrupts in BCR. */ - bus_space_write_1(sc->sc_iot, sc->sc_ioh, BCR, 0); - - /* 2. Assure NOT BUSY and NO INTERRUPT PENDING, unless acknowledging - * a RESET COMPLETED interrupt. */ - if (intr_id != ISR_RESET_COMPLETED) { - for(tries=0; tries < 1000; tries++) { - if ((bus_space_read_1(sc->sc_iot, sc->sc_ioh, BSR) - & (BSR_INT_PENDING|BSR_BUSY)) == 0) - break; - } - - if (tries == 1000) { - printf("%s: dasd_do_attn: timeout waiting for attachment to become available\n", - (devno == DASD_DEVNO_CONTROLLER) - ? sc->sc_dev.dv_xname - : sc->sc_ed[devno]->sc_dev.dv_xname); - return (EAGAIN); - } - } - - /* - * 3. Write proper DEVICE NUMBER and Attention number to ATN. - */ - bus_space_write_1(sc->sc_iot, sc->sc_ioh, ATN, - attn_type | (devno << 5)); - - /* - * 4. Enable interrupts via BCR. - */ - bus_space_write_1(sc->sc_iot, sc->sc_ioh, BCR, BCR_INT_ENABLE); - - return (0); -} - -/* - * Wait until command is processed, timeout after 'secs' seconds. - * We use mono_time, since we don't need actual RTC, just time - * interval. - */ -static int -dasd_cmd_wait(sc, devno, cmd, secs) - struct dasd_mca_softc *sc; - int devno, cmd, secs; -{ - struct timeval start, now; - int s; - - s = splclock(); - start = mono_time; - splx(s); - - while((bus_space_read_1(sc->sc_iot,sc->sc_ioh,BSR)&BSR_CMD_INPROGRESS)){ - s = splclock(); - now = mono_time; - splx(s); - if (now.tv_sec - start.tv_sec > secs) - break; - - delay(1); - } - - if (now.tv_sec - start.tv_sec >= secs && - bus_space_read_1(sc->sc_iot, sc->sc_ioh, BSR) & BSR_CMD_INPROGRESS){ - printf("%s: timed out waiting for previous cmd to finish, command %d not executed\n", - sc->sc_ed[devno]->sc_dev.dv_xname, cmd); - return (EAGAIN); - } - - return (0); -} - -int -dasd_run_cmd(sc, cmd, devno, cmd_args, cmd_len, async) - struct dasd_mca_softc *sc; - int cmd; - int devno; - u_int16_t cmd_args[]; - int cmd_len; - int async; -{ - int i, error; - u_int16_t cmd0; - - /* - * If there has been an asynchronous command executed, first wait for it - * to finish. - */ - if (sc->sc_cmd_async) { - /* Wait maximum 15s */ - if (dasd_cmd_wait(sc, devno, cmd, 15)) - return (EAGAIN); /* Busy */ - - sc->sc_cmd_async = 0; - } - - /* Do Attention Request for Command Request. */ - if ((error = dasd_do_attn(sc, ATN_CMD_REQ, devno, 0))) - return (error); - - /* - * Construct the command. The bits are like this: - * - * 15 14 13 12 11 10 9 8 7 6 5 4 3 2 1 0 - * \_/ 0 0 1 0 \__/ \_____/ - * \ \__________/ \ \_ Command Code (see CMD_*) - * \ \ \__ Device: 0 common, 7 controller - * \ \__ Options: reserved, bit 10=cache bypass bit - * \_ Type: 00=2B, 01=4B, 10 and 11 reserved - * - * We always use device 0 or 1, so difference is made only by Command - * Code, Command Options and command length. - */ - cmd0 = ((cmd_len == 4) ? (CIFR_LONG_CMD) : 0) - | (devno << 5) - | (cmd_args[0] << 8) | cmd; - cmd_args[0] = cmd0; - - /* - * Write word of CMD to the CIFR. This sets "Command - * Interface Register Full (CMD IN)" in BSR. Once the attachment - * detects it, it reads the word and clears CMD IN. - */ - for(i=0; i < cmd_len; i++) { - bus_space_write_2(sc->sc_iot, sc->sc_ioh, CIFR, - htole16(cmd_args[i])); - - /* wait until CMD IN is cleared */ - while(bus_space_read_1(sc->sc_iot, sc->sc_ioh, BSR) & BSR_CIFR_FULL) - delay(1); - } - - /* - * Attachment is now executing the command. Unless we are executing - * command asynchronously, wait until it finishes. - */ - if (async) { - sc->sc_cmd_async = 1; - return (0); - } - - /* Wait for command to complete, but maximum 15 seconds. */ - if (dasd_cmd_wait(sc, devno, cmd, 15)) - return (EAGAIN); - - /* Check if the command completed successfully; if not, return error */ - switch(SB_GET_CMD_STATUS(sc->sc_ed[devno]->sc_status_block)) { - case ISR_COMPLETED: - case ISR_COMPLETED_WITH_ECC: - case ISR_COMPLETED_RETRIES: - case ISR_COMPLETED_WARNING: - return (0); - default: - return (EIO); - } -} - -static int -dasd_setup_dma(sc, bp, phys, cnt) - struct dasd_mca_softc *sc; - struct buf *bp; - bus_addr_t phys; - bus_size_t cnt; -{ - /* XXX magic constants, should be moved to device-independant location*/ - /* The exact sequence to setup MCA DMA controller is taken from Minix */ - - bus_space_write_1(sc->sc_iot, sc->sc_dmaextcmdh, 0, - 0x90 + sc->sc_drq); - /* Disable access to dma channel */ - bus_space_write_1(sc->sc_iot, sc->sc_dmaextcmdh, 0, - 0x20 + sc->sc_drq); - /* Clear the address byte pointer */ - bus_space_write_1(sc->sc_iot, sc->sc_dmaexech, 0, - (phys >> 0) & 0xff); /* address bits 0..7 */ - bus_space_write_1(sc->sc_iot, sc->sc_dmaexech, 0, - (phys >> 8) & 0xff); /* address bits 8..15 */ - bus_space_write_1(sc->sc_iot, sc->sc_dmaexech, 0, - (phys >> 16) & 0xff); /* address bits 16..23 */ - bus_space_write_1(sc->sc_iot, sc->sc_dmaextcmdh, 0, - 0x40 + sc->sc_drq); - /* Clear the count byte pointer */ - bus_space_write_1(sc->sc_iot, sc->sc_dmaexech, 0, - ((cnt - 1) >> 0) & 0xff); /* count bits 0..7 */ - bus_space_write_1(sc->sc_iot, sc->sc_dmaexech, 0, - ((cnt - 1) >> 8) & 0xff); /* count bits 8..15 */ - bus_space_write_1(sc->sc_iot, sc->sc_dmaextcmdh, 0, - 0x70 + sc->sc_drq); - /* Set the transfer mode */ - bus_space_write_1(sc->sc_iot, sc->sc_dmaexech, 0, - (bp->b_flags & B_READ) ? 0x4C : 0x44); - bus_space_write_1(sc->sc_iot, sc->sc_dmaextcmdh, 0, - 0xA0 + sc->sc_drq); - /* Enable access to dma channel */ - - return (1); -} - -static const char * const dasd_commands[] = { - "Invalid Command", - "Read Data", - "Write Data", - "Read Verify", - "Write with Verify", - "Seek", - "Park Head", - "Get Command Complete Status", - "Get Device Status", - "Get Device Configuration", - "Get POS Information", - "Translate RBA", - "Write Attachment Buffer", - "Read Attachment Buffer", - "Run Diagnostic Test", - "Get Diagnostic Status Block", - "Get MFG Header", - "Format Unit", - "Format Prepare", - "Set MAX RBA", - "Set Power Saving Mode", - "Power Conservation Command", -}; - -static const char * const dasd_cmd_status[256] = { - "Reserved", - "Command completed successfully", - "Reserved", - "Command completed successfully with ECC applied", - "Reserved", - "Command completed successfully with retries", - "Format Command partially completed", /* Status available */ - "Command completed successfully with ECC and retries", - "Command completed with Warning", /* Command Error is available */ - "Aborted", - "Reset completed", - "Data Transfer Ready", /* No Status Block available */ - "Command terminated with failure", /* Device Error is available */ - "DMA Error", /* Retry entire command as recovery */ - "Command Block Error", - "Attention Error (Illegal Attention Code)", - /* 0x14 - 0xff reserved */ -}; - -static const char * const dasd_cmd_error[256] = { - "No Error", - "Invalid parameter in the command block", - "Reserved", - "Command not supported", - "Command Aborted per request", - "Reserved", - "Command rejected", /* Attachment diagnostic failure */ - "Format Rejected", /* Prepare Format command is required */ - "Format Error (Primary Map is not readable)", - "Format Error (Secondary map is not readable)", - "Format Error (Diagnostic Failure)", - "Format Warning (Secondary Map Overflow)", - "Reserved" - "Format Error (Host Checksum Error)", - "Reserved", - "Format Warning (Push table overflow)", - "Format Warning (More pushes than allowed)", - "Reserved", - "Format Warning (Error during verifying)", - "Invalid device number for the command", - /* 0x14-0xff reserved */ -}; - -static const char * const dasd_dev_status[] = { - "Seek or Command complete", - "Track 0 Flag (emulated)", - "Write Fault (emulated)", - "Selected", - "Ready", - "Reserved (0)", - "STANDBY", - "Reserved (0)", -}; - -static const char * const dasd_dev_errors[] = { - "No Error", - "Seek Fault", /* Device report */ - "Interface Fault (Parity, Attn, or Cmd Complete Error)", - "Block not found (ID not found)", - "Block not found (AM not found)", - "Data ECC Error (hard error)", - "ID CRC Error", - "RBA Out of Range", - "Reserved", - "Defective Block", - "Reserved", - "Selection Error", - "Reserved", - "Write Fault", - "No index or sector pulse", - "Device Not Ready", - "Seek Error", /* Attachment report */ - "Bad Format", - "Volume Overflow", - "No Data AM Found", - "(Block not found) No ID AM or ID CRC error occured", - "Reserved", - "Reserved", - "No ID found on track (ID search)", - /* 0x19 - 0xff reserved */ -}; - -static void -dasd_dump_status_block(sc, devno, cmd, intr_id) - struct dasd_mca_softc *sc; - int devno, cmd, intr_id; -{ - struct ed_softc *ed = sc->sc_ed[devno]; - printf("%s: Command: %s, Status: %s\n", - ed->sc_dev.dv_xname, - dasd_commands[ed->sc_status_block[0] & 0x1f], - dasd_cmd_status[SB_GET_CMD_STATUS(ed->sc_status_block)] - ); - printf("%s: IntrId: %s\n", ed->sc_dev.dv_xname, - dasd_cmd_status[intr_id]); - - if (cmd == ISR_COMPLETED_WARNING) { - printf("%s: Command Error Code: %s\n", - ed->sc_dev.dv_xname, - dasd_cmd_error[ed->sc_status_block[1] & 0xff]); - } - - if (cmd == ISR_CMD_FAILED) { - printf("%s: Device: Status: %s, Error Code: %s\n", - ed->sc_dev.dv_xname, - dasd_dev_status[(ed->sc_status_block[2] & 0xff00) >> 8], - dasd_dev_errors[ed->sc_status_block[2] & 0xff]); - } -} diff --git a/sys/dev/mca/dasdreg.h b/sys/dev/mca/dasdreg.h deleted file mode 100644 index 1e352daa83d..00000000000 --- a/sys/dev/mca/dasdreg.h +++ /dev/null @@ -1,131 +0,0 @@ -/* $NetBSD: dasdreg.h,v 1.1 2001/04/19 07:30:24 jdolecek Exp $ */ - -/* - * Copyright (c) 2001 The NetBSD Foundation, Inc. - * - * This code is derived from software contributed to The NetBSD Foundation - * by Jaromir Dolecek. - * - * 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 NetBSD - * Foundation, Inc. and its contributors. - * 4. The name of the author may not be used to endorse or promote products - * derived from this software without specific prior written permission. - * - * THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``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 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. - */ - -/* - * Driver for MCA ESDI controllers and disks. - */ - -#define ESDIC_IOPRM 0x3510 -#define ESDIC_IOALT 0x3518 -#define ESDIC_REG_NPORTS 8 -#define ESDIC_IRQ 14 /* this is fixed */ - -/* pos2 */ -#define IO_IS_ALT 0x02 -#define DRQ_MASK 0x3c -#define FAIRNESS_ENABLE 0x40 - -/* pos3 */ -#define PACING_INT_MASK 0x30 - -/* pos4 */ -#define PACING_CTRL_DISABLE 0x01 -#define RELEASE_2 0x02 /* lower bit of Time to Release */ -#define RELEASE_1 0x04 /* higher bit of Time to Release */ - -/* controller registers */ -#define SIFR 0 /* read Status Interface Register, - 2 bytes, little endian */ -#define SIFR_CMD_MASK 0x2f - -#define CIFR 0 /* write - Command Interface Reg, - 2 bytes, little endian */ -#define CIFR_LONG_CMD (1<<14) /* 4 word command */ - -/* Command Codes */ -#define CMD_READ_DATA 0x01 /* uses DMA */ -#define CMD_WRITE_DATA 0x02 /* uses DMA */ -#define CMD_READ_VERIFY 0x03 -#define CMD_WRITE_VERIFY 0x04 /* uses DMA */ -#define CMD_SEEK 0x05 -#define CMD_PARK_HEAD 0x06 -#define CMD_GET_CMD_COMP_STATUS 0x07 -#define CMD_GET_DEV_STATUS 0x08 -#define CMD_GET_DEV_CONF 0x09 -#define CMD_GET_POS_INFO 0x0A -#define CMD_TRANSLATE_RBA 0x0B -#define CMD_WRITE_ATTACH_BUFF 0x10 /* uses DMA */ -#define CMD_READ_ATTACH_BUFF 0x11 /* uses DMA */ -#define CMD_RUN_DIAG_TEST 0x12 -#define CMD_GET_DIAG_STAT_BLOCK 0x14 -#define CMD_GET_MFG_HEADER 0x15 /* uses DMA */ -#define CMD_FORMAT_UNIT 0x16 /* uses DMA */ -#define CMD_FORMAT_PREPARE 0x17 -#define CMD_SET_MAX_RBA 0x1A -#define CMD_SET_PWR_SAV_MODE 0x1B /* optional */ -#define CMD_POWER_CONS_CMD 0x1C /* optional */ - -#define BCR 2 /* write */ -#define BCR_INT_ENABLE 0x01 -#define BCR_DMA_ENABLE 0x02 -#define BCR_RESET 0x80 - -#define BSR 2 /* read */ -#define BSR_DMA_ENABLED 0x80 -#define BSR_INT_PENDING 0x40 -#define BSR_CMD_INPROGRESS 0x20 -#define BSR_BUSY 0x10 -#define BSR_SIFR_FULL 0x08 /* also called STATUS OUT */ -#define BSR_CIFR_FULL 0x04 -#define BSR_TRANSFER_REQ 0x02 -#define BSR_INTR 0x01 - -#define ISR 3 /* read, Interrupt Status Register */ -#define ISR_DEV_SELECT_MASK 0xE0 -#define ISR_ATTACH_ERR 0x10 -#define ISR_INTR_ID_MASK 0x0F -#define ISR_COMPLETED 0x01 -#define ISR_COMPLETED_WITH_ECC 0x03 -#define ISR_COMPLETED_RETRIES 0x05 -#define ISR_PARTIAL_FORMAT 0x06 /* Status available */ -#define ISR_COMPLETED_WARNING 0x08 -#define ISR_ABORT_COMPLETED 0x09 -#define ISR_RESET_COMPLETED 0x0A -#define ISR_DATA_TRANSFER_RDY 0x0B /* No Status Block */ -#define ISR_CMD_FAILED 0x0C -#define ISR_DMA_ERROR 0x0D -#define ISR_CMD_BLOCK_ERROR 0x0E -#define ISR_ATTN_ERROR 0x0F - -/* Macros to get info from command status block */ -#define SB_GET_CMD_STATUS(sb) (((sb)[1] & 0xff00) >> 8) - -#define ATN 3 /* write, Attention register */ -#define ATN_CMD_REQ 1 -#define ATN_END_INT 2 /* End of Interrupt (EOI) */ -#define ATN_ABORT_CMD 3 -#define ATN_RESET_ATTACHMENT 4 - -#define DASD_DEVNO_CONTROLLER 7 /* Device number for controller */ diff --git a/sys/dev/mca/dasdvar.h b/sys/dev/mca/dasdvar.h deleted file mode 100644 index 199b38b9e96..00000000000 --- a/sys/dev/mca/dasdvar.h +++ /dev/null @@ -1,43 +0,0 @@ -/* $NetBSD: dasdvar.h,v 1.1 2001/04/19 07:30:24 jdolecek Exp $ */ - -/* - * Copyright (c) 2001 The NetBSD Foundation, Inc. - * - * This code is derived from software contributed to The NetBSD Foundation - * by Jaromir Dolecek. - * - * 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 NetBSD - * Foundation, Inc. and its contributors. - * 4. The name of the author may not be used to endorse or promote products - * derived from this software without specific prior written permission. - * - * THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``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 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. - */ - -struct ed_attach_args { - int sc_devno; - bus_dma_tag_t sc_dmat; /* DMA tag as passed by parent */ -}; - -int dasd_run_cmd __P((struct dasd_mca_softc *, int, - int, u_int16_t [], int, int)); -void dasd_add_disk __P((struct dasd_mca_softc *, struct ed_softc *, int)); diff --git a/sys/dev/mca/ed_mca.c b/sys/dev/mca/ed_mca.c index 2338f23ba63..5b07798a251 100644 --- a/sys/dev/mca/ed_mca.c +++ b/sys/dev/mca/ed_mca.c @@ -1,4 +1,4 @@ -/* $NetBSD: ed_mca.c,v 1.1 2001/04/19 07:30:24 jdolecek Exp $ */ +/* $NetBSD: ed_mca.c,v 1.2 2001/04/19 17:17:29 jdolecek Exp $ */ /* * Copyright (c) 2001 The NetBSD Foundation, Inc. @@ -63,9 +63,9 @@ #include #include -#include +#include #include -#include +#include /* #define WDCDEBUG */ @@ -117,7 +117,7 @@ ed_mca_probe(parent, match, aux) void *aux; { u_int16_t cmd_args[2]; - struct dasd_mca_softc *sc = (void *) parent; + struct edc_mca_softc *sc = (void *) parent; struct ed_attach_args *eda = (void *) aux; /* @@ -125,7 +125,7 @@ ed_mca_probe(parent, match, aux) */ cmd_args[0] = 6; /* Options: 00s110, s: 0=Physical 1=Pseudo */ cmd_args[1] = 0; - if (dasd_run_cmd(sc, CMD_GET_DEV_CONF, eda->sc_devno, cmd_args, 2, 0)) + if (edc_run_cmd(sc, CMD_GET_DEV_CONF, eda->sc_devno, cmd_args, 2, 0)) return (0); return (1); @@ -137,15 +137,15 @@ ed_mca_attach(parent, self, aux) void *aux; { struct ed_softc *ed = (void *) self; - struct dasd_mca_softc *sc = (void *) parent; + struct edc_mca_softc *sc = (void *) parent; struct ed_attach_args *eda = (void *) aux; char pbuf[8]; int error, nsegs; - ed->dasd_softc = sc; + ed->edc_softc = sc; ed->sc_dmat = eda->sc_dmat; ed->sc_devno = eda->sc_devno; - dasd_add_disk(sc, ed, eda->sc_devno); + edc_add_disk(sc, ed, eda->sc_devno); BUFQ_INIT(&ed->sc_q); spinlockinit(&ed->sc_q_lock, "edbqlock", 0); @@ -419,7 +419,7 @@ __edstart(ed, bp) cmd_args[1] = bp->b_bcount / DEV_BSIZE; cmd_args[2] = ((cyl & 0x1f) << 11) | (head << 5) | sector; cmd_args[3] = ((cyl & 0x3E0) >> 5); - if (dasd_run_cmd(ed->dasd_softc, + if (edc_run_cmd(ed->edc_softc, (bp->b_flags & B_READ) ? CMD_READ_DATA : CMD_WRITE_DATA, ed->sc_devno, cmd_args, 4, 1)) { printf("%s: data i/o command failed\n", ed->sc_dev.dv_xname); @@ -1092,7 +1092,7 @@ ed_get_params(ed) */ cmd_args[0] = 6; /* Options: 00s110, s: 0=Physical 1=Pseudo */ cmd_args[1] = 0; - if (dasd_run_cmd(ed->dasd_softc, CMD_GET_DEV_CONF, ed->sc_devno, cmd_args, 2, 0)) + if (edc_run_cmd(ed->edc_softc, CMD_GET_DEV_CONF, ed->sc_devno, cmd_args, 2, 0)) return (1); ed->spares = ed->sc_status_block[1] >> 8; @@ -1129,7 +1129,7 @@ ed_shutdown(arg) /* Issue Park Head command */ cmd_args[0] = 6; /* Options: 000110 */ cmd_args[1] = 0; - (void) dasd_run_cmd(ed->dasd_softc, CMD_PARK_HEAD, ed->sc_devno, + (void) edc_run_cmd(ed->edc_softc, CMD_PARK_HEAD, ed->sc_devno, cmd_args, 2, 0); #endif } @@ -1171,10 +1171,10 @@ edworker(arg) splx(s); /* - * Wait until the command executes; dasd_intr() wakes + * Wait until the command executes; edc_intr() wakes * as up. */ - (void) tsleep(&ed->dasd_softc, PRIBIO, "edwrk", 0); + (void) tsleep(&ed->edc_softc, PRIBIO, "edwrk", 0); /* Handle i/o results */ s = splbio(); diff --git a/sys/dev/mca/edc_mca.c b/sys/dev/mca/edc_mca.c new file mode 100644 index 00000000000..da9c38ff36f --- /dev/null +++ b/sys/dev/mca/edc_mca.c @@ -0,0 +1,810 @@ +/* $NetBSD: edc_mca.c,v 1.1 2001/04/19 17:17:29 jdolecek Exp $ */ + +/* + * Copyright (c) 2001 The NetBSD Foundation, Inc. + * + * This code is derived from software contributed to The NetBSD Foundation + * by Jaromir Dolecek. + * + * 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 NetBSD + * Foundation, Inc. and its contributors. + * 4. The name of the author may not be used to endorse or promote products + * derived from this software without specific prior written permission. + * + * THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``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 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. + */ + +/* + * Driver for MCA ESDI controllers and disks conforming to IBM DASD + * spec. + * + * The driver was written with DASD Storage Interface Specification + * for MCA rev. 2.2 in hands, thanks to Scott Telford . + * + * TODO: + * - move the MCA DMA controller (edc_setup_dma()) goo to device driver + * independant location + * - improve error recovery + * add any soft resets when anything gets stuck? + * - test with > 1 disk (this is supported by some controllers), eliminate + * any remaining devno=0 assumptions if there are any still + * - test with > 1 ESDI controller in machine; shared interrupts + * necessary for this to work should be supported - edc_intr() specifically + * checks if the interrupt is for this controller + */ + +#include "rnd.h" + +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#if NRND > 0 +#include +#endif + +#include +#include + +#include +#include +#include + +#include +#include +#include + +#define DASD_MAXDEVS 7 +struct edc_mca_softc { + struct device sc_dev; + + bus_space_tag_t sc_iot; + bus_space_handle_t sc_ioh; + + bus_dma_tag_t sc_dmat; /* DMA tag as passed by parent */ + bus_space_handle_t sc_dmaextcmdh; + bus_space_handle_t sc_dmaexech; + + void *sc_ih; /* interrupt handle */ + int sc_drq; /* DRQ number */ + int sc_cmd_async; /* asynchronous cmd pending */ + + int sc_flags; +#define DASD_QUIET 0x01 /* don't dump cmd error info */ + struct ed_softc *sc_ed[DASD_MAXDEVS]; + + int sc_maxdevs; /* maximum # of devs supported by + * controller */ +}; + +int edc_mca_probe __P((struct device *, struct cfdata *, void *)); +void edc_mca_attach __P((struct device *, struct device *, void *)); + +struct cfattach edc_mca_ca = { + sizeof(struct edc_mca_softc), edc_mca_probe, edc_mca_attach +}; + +#define DMA_EXTCMD 0x18 +#define DMA_EXEC 0x1A + +static int edc_intr __P((void *)); +static void edc_attach_ed __P((struct device *)); +static void edc_dump_status_block __P((struct edc_mca_softc *, int, int, + int)); +static int edc_setup_dma __P((struct edc_mca_softc *, struct buf *, + bus_addr_t, bus_size_t)); +static int edc_do_attn __P((struct edc_mca_softc *, int, int, int)); +static int edc_cmd_wait __P((struct edc_mca_softc *, int, int, int)); + +int +edc_mca_probe(parent, match, aux) + struct device *parent; + struct cfdata *match; + void *aux; +{ + struct mca_attach_args *ma = aux; + + switch (ma->ma_id) { + case MCA_PRODUCT_IBM_ESDIC: + case MCA_PRODUCT_IBM_ESDIC_IG: + return (1); + default: + return (0); + } +} + +void +edc_mca_attach(parent, self, aux) + struct device *parent, *self; + void *aux; +{ + struct edc_mca_softc *sc = (void *) self; + struct mca_attach_args *ma = aux; + int pos2, pos3, pos4; + int irq, drq, iobase; + const char *typestr; + + pos2 = mca_conf_read(ma->ma_mc, ma->ma_slot, 2); + pos3 = mca_conf_read(ma->ma_mc, ma->ma_slot, 3); + pos4 = mca_conf_read(ma->ma_mc, ma->ma_slot, 4); + + /* + * POS register 2: (adf pos0) + * + * 7 6 5 4 3 2 1 0 + * \ \____/ \ \__ enable: 0=adapter disabled, 1=adapter enabled + * \ \ \___ Primary/Alternate Port Adresses: + * \ \ 0=0x3510-3517 1=0x3518-0x351f + * \ \_____ DMA Arbitration Level: 0101=5 0110=6 0111=7 + * \ 0000=0 0001=1 0011=3 0100=4 + * \_________ Fairness On/Off: 1=On 0=Off + * + * POS register 3: (adf pos1) + * + * 7 6 5 4 3 2 1 0 + * 0 0 \_/ + * \__________ DMA Burst Pacing Interval: 10=24ms 11=31ms + * 01=16ms 00=Burst Disabled + * + * POS register 4: (adf pos2) + * + * 7 6 5 4 3 2 1 0 + * \_/ \__ DMA Pacing Control: 1=Disabled 0=Enabled + * \____ Time to Release: 1X=6ms 01=3ms 00=Immediate + * + * IRQ is fixed to 14 (0x0e). + */ + + switch (ma->ma_id) { + case MCA_PRODUCT_IBM_ESDIC: + typestr = "IBM ESDI Fixed Disk Controller"; + break; + case MCA_PRODUCT_IBM_ESDIC_IG: + typestr = "IBM Integ. ESDI Fixed Disk & Controller"; + break; + default: + /* never reached */ + } + + printf(" slot %d: %s\n", ma->ma_slot+1, typestr); + + irq = ESDIC_IRQ; + iobase = (pos2 & IO_IS_ALT) ? ESDIC_IOALT : ESDIC_IOPRM; + drq = (pos2 & DRQ_MASK) >> 2; + +#ifdef DIAGNOSTIC + /* + * It's not strictly necessary to check this, machine configuration + * utility uses only valid adresses. + */ + if (drq == 2 || drq >= 8) { + printf("%s: invalid DMA Arbitration Level %d\n", + sc->sc_dev.dv_xname, drq); + return; + } +#endif + + printf("%s: Fairness %s, Release %s, DRQ %d, ", + sc->sc_dev.dv_xname, + (pos2 & FAIRNESS_ENABLE) ? "On" : "Off", + (pos4 & RELEASE_1) ? "6ms" + : ((pos4 & RELEASE_2) ? "3ms" : "Immediate"), + drq); + if ((pos4 & PACING_CTRL_DISABLE) == 0) { + static const char * const pacint[] = + { "disabled", "16ms", "24ms", "31ms"}; + printf("DMA burst pacing interval %s\n", + pacint[(pos3 & PACING_INT_MASK) >> 4]); + } else + printf("DMA pacing control disabled\n"); + + sc->sc_iot = ma->ma_iot; + sc->sc_drq = drq; + + if (bus_space_map(sc->sc_iot, iobase, + ESDIC_REG_NPORTS, 0, &sc->sc_ioh)) { + printf("%s: couldn't map registers\n", + sc->sc_dev.dv_xname); + return; + } + + if (bus_space_map(sc->sc_iot, DMA_EXTCMD, 1, 0, &sc->sc_dmaextcmdh)) { + printf("%s: couldn't map registers\n", + sc->sc_dev.dv_xname); + return; + } + if (bus_space_map(sc->sc_iot, DMA_EXEC, 1, 0, &sc->sc_dmaexech)) { + printf("%s: couldn't map registers\n", + sc->sc_dev.dv_xname); + return; + } + + sc->sc_dmat = ma->ma_dmat; + + sc->sc_ih = mca_intr_establish(ma->ma_mc, irq, IPL_BIO, edc_intr, sc); + if (sc->sc_ih == NULL) { + printf("%s: couldn't establish interrupt handler\n", + sc->sc_dev.dv_xname); + return; + } + printf("%s: interrupting at irq %d\n", sc->sc_dev.dv_xname, irq); + + /* + * Integrated ESDI controller supports only one disk, other + * controllers support two disks. + */ + if (ma->ma_id == MCA_PRODUCT_IBM_ESDIC_IG) + sc->sc_maxdevs = 1; + else + sc->sc_maxdevs = 2; + + /* Defer probe for individual disks until interrupts are enabled. */ + config_interrupts(self, edc_attach_ed); +} + +/* + * Try to attach ed* at edc? if any configured and installed now + * that interrupts are enabled. + */ +static void +edc_attach_ed(self) + struct device *self; +{ + struct edc_mca_softc *sc = (void *) self; + struct ed_softc *ed; + struct ed_attach_args eda; + int devno; + + /* Do a reset to ensure sane state after warm boot. */ + if (bus_space_read_1(sc->sc_iot, sc->sc_ioh, BSR) & BSR_BUSY) { + /* hard reset */ + printf("%s: controller busy, performing hardware reset ...\n", + sc->sc_dev.dv_xname); + bus_space_write_1(sc->sc_iot, sc->sc_ioh, BCR, + BCR_INT_ENABLE|BCR_RESET); + } else { + /* "SOFT" reset */ + edc_do_attn(sc, ATN_RESET_ATTACHMENT, DASD_DEVNO_CONTROLLER,0); + } + + /* Wait until the reset completes. */ + while(bus_space_read_1(sc->sc_iot, sc->sc_ioh, BSR) & BSR_BUSY) + delay(1); + + /* + * Get dummy ed_softc to be used during probe. Once a disk is + * found, ed_mca_attach() calls edc_add_disk() to insert the + * right pointer into sc->sc_ed[] array. + */ + MALLOC(ed, struct ed_softc *, sizeof(struct ed_softc), + M_TEMP, M_WAITOK); + + /* be quiet duting probes */ + sc->sc_flags |= DASD_QUIET; + + /* check for attached disks */ + for(devno=0; devno < sc->sc_maxdevs; devno++) { + eda.sc_devno = devno; + eda.sc_dmat = sc->sc_dmat; + sc->sc_ed[devno] = ed; + sc->sc_ed[devno] = + (void *) config_found_sm(self, &eda, NULL, NULL); + } + + /* enable full error dumps again */ + sc->sc_flags &= ~DASD_QUIET; + + /* cleanup */ + FREE(ed, M_TEMP); + + /* XXX disestablish interrupt if no disks found ? */ +} + +void +edc_add_disk(sc, ed, devno) + struct edc_mca_softc *sc; + struct ed_softc *ed; + int devno; +{ + sc->sc_ed[devno] = ed; +} + +static int +edc_intr(arg) + void *arg; +{ + struct edc_mca_softc *sc = arg; + u_int8_t isr, intr_id; + u_int16_t sifr; + int cmd, devno, bioerror; + struct ed_softc *ed=NULL; + + /* + * Check if the interrupt was for us. + */ + if ((bus_space_read_1(sc->sc_iot, sc->sc_ioh, BSR) & BSR_INTR) == 0) + return (0); + + /* + * Read ISR to find out interrupt type. This also clears the interrupt + * condition and BSR_INTR flag. Accordings to docs interrupt ID of 0, 2 + * and 4 are reserved and not used. + */ + isr = bus_space_read_1(sc->sc_iot, sc->sc_ioh, ISR); + intr_id = isr & ISR_INTR_ID_MASK; + +#ifdef DEBUG + if (intr_id == 0 || intr_id == 2 || intr_id == 4) { + printf("%s: bogus interrupt id %d\n", sc->sc_dev.dv_xname, + (int) intr_id); + return (0); + } +#endif + + /* Get number of device whose intr this was */ + devno = (isr & 0xe0) >> 5; + + /* + * Get Status block. Higher byte always says how long the status + * block is, rest is device number and command code. + * Check the status block length against our supported maximum length + * and fetch the data. + */ + if (bus_space_read_1(sc->sc_iot, sc->sc_ioh,BSR) & BSR_SIFR_FULL + && intr_id != ISR_RESET_COMPLETED) { + size_t len; + int i; + + sifr = le16toh(bus_space_read_2(sc->sc_iot, sc->sc_ioh, SIFR)); + len = (sifr & 0xff00) >> 8; + if (len > DASD_MAX_CMD_RES_LEN) { + printf("%s: maximum Status Length exceeded: %d > %d\n", + sc->sc_dev.dv_xname, + len, DASD_MAX_CMD_RES_LEN); + goto attn_eoi; + } + + /* Get command code */ + cmd = sifr & SIFR_CMD_MASK; + + /* Read whole status block */ + ed = sc->sc_ed[devno]; + ed->sc_status_block[0] = sifr; + for(i=1; i < len; i++) { + while((bus_space_read_1(sc->sc_iot, sc->sc_ioh, BSR) + & BSR_SIFR_FULL) == 0) + delay(1); + + ed->sc_status_block[i] = le16toh( + bus_space_read_2(sc->sc_iot, sc->sc_ioh, SIFR)); + } + } + + switch (intr_id) { + case ISR_DATA_TRANSFER_RDY: + /* + * Ready to do DMA, setup DMA controller and kick DASD + * controller to do the transfer. + */ + ed = sc->sc_ed[devno]; + if (!edc_setup_dma(sc, ed->sc_bp, + ed->dmamap_xfer->dm_segs[0].ds_addr, + ed->dmamap_xfer->dm_segs[0].ds_len)) { + /* error XXX bail out? */ + bus_space_write_1(sc->sc_iot, sc->sc_ioh, BCR, + BCR_INT_ENABLE); + } else { + /* OK, proceed with DMA */ + bus_space_write_1(sc->sc_iot, sc->sc_ioh, BCR, + BCR_INT_ENABLE|BCR_DMA_ENABLE); + } + break; + case ISR_COMPLETED: + case ISR_COMPLETED_WITH_ECC: + case ISR_COMPLETED_RETRIES: + case ISR_COMPLETED_WARNING: + bioerror = 0; + break; + case ISR_RESET_COMPLETED: + case ISR_ABORT_COMPLETED: + /* nothing to do */ + break; + default: + if ((sc->sc_flags & DASD_QUIET) == 0) + edc_dump_status_block(sc, devno, cmd, intr_id); + + bioerror = EIO; + break; + } + + attn_eoi: + /* + * Unless the interrupt is for Data Transfer Ready or + * Attention Error, finish by assertion EOI. This makes + * attachment aware the interrupt is processed and system + * is ready to accept another one. + */ + if (intr_id != ISR_DATA_TRANSFER_RDY && intr_id != ISR_ATTN_ERROR) + edc_do_attn(sc, ATN_END_INT, devno, intr_id); + + /* If Read or Write Data, wakeup worker thread to finish it */ + if (intr_id != ISR_DATA_TRANSFER_RDY + && (cmd == CMD_READ_DATA || cmd == CMD_WRITE_DATA)) { + sc->sc_ed[devno]->sc_error = bioerror; + wakeup_one(&sc->sc_ed[devno]->edc_softc); + } + + return (1); +} + +/* + * This follows the exact order for Attention Request as + * written in DASD Storage Interface Specification MC (Rev 2.2). + */ +static int +edc_do_attn(sc, attn_type, devno, intr_id) + struct edc_mca_softc *sc; + int attn_type, devno, intr_id; +{ + int tries; + + /* 1. Disable interrupts in BCR. */ + bus_space_write_1(sc->sc_iot, sc->sc_ioh, BCR, 0); + + /* 2. Assure NOT BUSY and NO INTERRUPT PENDING, unless acknowledging + * a RESET COMPLETED interrupt. */ + if (intr_id != ISR_RESET_COMPLETED) { + for(tries=0; tries < 1000; tries++) { + if ((bus_space_read_1(sc->sc_iot, sc->sc_ioh, BSR) + & (BSR_INT_PENDING|BSR_BUSY)) == 0) + break; + } + + if (tries == 1000) { + printf("%s: edc_do_attn: timeout waiting for attachment to become available\n", + (devno == DASD_DEVNO_CONTROLLER) + ? sc->sc_dev.dv_xname + : sc->sc_ed[devno]->sc_dev.dv_xname); + return (EAGAIN); + } + } + + /* + * 3. Write proper DEVICE NUMBER and Attention number to ATN. + */ + bus_space_write_1(sc->sc_iot, sc->sc_ioh, ATN, + attn_type | (devno << 5)); + + /* + * 4. Enable interrupts via BCR. + */ + bus_space_write_1(sc->sc_iot, sc->sc_ioh, BCR, BCR_INT_ENABLE); + + return (0); +} + +/* + * Wait until command is processed, timeout after 'secs' seconds. + * We use mono_time, since we don't need actual RTC, just time + * interval. + */ +static int +edc_cmd_wait(sc, devno, cmd, secs) + struct edc_mca_softc *sc; + int devno, cmd, secs; +{ + struct timeval start, now; + int s; + + s = splclock(); + start = mono_time; + splx(s); + + while((bus_space_read_1(sc->sc_iot,sc->sc_ioh,BSR)&BSR_CMD_INPROGRESS)){ + s = splclock(); + now = mono_time; + splx(s); + if (now.tv_sec - start.tv_sec > secs) + break; + + delay(1); + } + + if (now.tv_sec - start.tv_sec >= secs && + bus_space_read_1(sc->sc_iot, sc->sc_ioh, BSR) & BSR_CMD_INPROGRESS){ + printf("%s: timed out waiting for previous cmd to finish, command %d not executed\n", + sc->sc_ed[devno]->sc_dev.dv_xname, cmd); + return (EAGAIN); + } + + return (0); +} + +int +edc_run_cmd(sc, cmd, devno, cmd_args, cmd_len, async) + struct edc_mca_softc *sc; + int cmd; + int devno; + u_int16_t cmd_args[]; + int cmd_len; + int async; +{ + int i, error; + u_int16_t cmd0; + + /* + * If there has been an asynchronous command executed, first wait for it + * to finish. + */ + if (sc->sc_cmd_async) { + /* Wait maximum 15s */ + if (edc_cmd_wait(sc, devno, cmd, 15)) + return (EAGAIN); /* Busy */ + + sc->sc_cmd_async = 0; + } + + /* Do Attention Request for Command Request. */ + if ((error = edc_do_attn(sc, ATN_CMD_REQ, devno, 0))) + return (error); + + /* + * Construct the command. The bits are like this: + * + * 15 14 13 12 11 10 9 8 7 6 5 4 3 2 1 0 + * \_/ 0 0 1 0 \__/ \_____/ + * \ \__________/ \ \_ Command Code (see CMD_*) + * \ \ \__ Device: 0 common, 7 controller + * \ \__ Options: reserved, bit 10=cache bypass bit + * \_ Type: 00=2B, 01=4B, 10 and 11 reserved + * + * We always use device 0 or 1, so difference is made only by Command + * Code, Command Options and command length. + */ + cmd0 = ((cmd_len == 4) ? (CIFR_LONG_CMD) : 0) + | (devno << 5) + | (cmd_args[0] << 8) | cmd; + cmd_args[0] = cmd0; + + /* + * Write word of CMD to the CIFR. This sets "Command + * Interface Register Full (CMD IN)" in BSR. Once the attachment + * detects it, it reads the word and clears CMD IN. + */ + for(i=0; i < cmd_len; i++) { + bus_space_write_2(sc->sc_iot, sc->sc_ioh, CIFR, + htole16(cmd_args[i])); + + /* wait until CMD IN is cleared */ + while(bus_space_read_1(sc->sc_iot, sc->sc_ioh, BSR) & BSR_CIFR_FULL) + delay(1); + } + + /* + * Attachment is now executing the command. Unless we are executing + * command asynchronously, wait until it finishes. + */ + if (async) { + sc->sc_cmd_async = 1; + return (0); + } + + /* Wait for command to complete, but maximum 15 seconds. */ + if (edc_cmd_wait(sc, devno, cmd, 15)) + return (EAGAIN); + + /* Check if the command completed successfully; if not, return error */ + switch(SB_GET_CMD_STATUS(sc->sc_ed[devno]->sc_status_block)) { + case ISR_COMPLETED: + case ISR_COMPLETED_WITH_ECC: + case ISR_COMPLETED_RETRIES: + case ISR_COMPLETED_WARNING: + return (0); + default: + return (EIO); + } +} + +static int +edc_setup_dma(sc, bp, phys, cnt) + struct edc_mca_softc *sc; + struct buf *bp; + bus_addr_t phys; + bus_size_t cnt; +{ + /* XXX magic constants, should be moved to device-independant location*/ + /* The exact sequence to setup MCA DMA controller is taken from Minix */ + + bus_space_write_1(sc->sc_iot, sc->sc_dmaextcmdh, 0, + 0x90 + sc->sc_drq); + /* Disable access to dma channel */ + bus_space_write_1(sc->sc_iot, sc->sc_dmaextcmdh, 0, + 0x20 + sc->sc_drq); + /* Clear the address byte pointer */ + bus_space_write_1(sc->sc_iot, sc->sc_dmaexech, 0, + (phys >> 0) & 0xff); /* address bits 0..7 */ + bus_space_write_1(sc->sc_iot, sc->sc_dmaexech, 0, + (phys >> 8) & 0xff); /* address bits 8..15 */ + bus_space_write_1(sc->sc_iot, sc->sc_dmaexech, 0, + (phys >> 16) & 0xff); /* address bits 16..23 */ + bus_space_write_1(sc->sc_iot, sc->sc_dmaextcmdh, 0, + 0x40 + sc->sc_drq); + /* Clear the count byte pointer */ + bus_space_write_1(sc->sc_iot, sc->sc_dmaexech, 0, + ((cnt - 1) >> 0) & 0xff); /* count bits 0..7 */ + bus_space_write_1(sc->sc_iot, sc->sc_dmaexech, 0, + ((cnt - 1) >> 8) & 0xff); /* count bits 8..15 */ + bus_space_write_1(sc->sc_iot, sc->sc_dmaextcmdh, 0, + 0x70 + sc->sc_drq); + /* Set the transfer mode */ + bus_space_write_1(sc->sc_iot, sc->sc_dmaexech, 0, + (bp->b_flags & B_READ) ? 0x4C : 0x44); + bus_space_write_1(sc->sc_iot, sc->sc_dmaextcmdh, 0, + 0xA0 + sc->sc_drq); + /* Enable access to dma channel */ + + return (1); +} + +static const char * const edc_commands[] = { + "Invalid Command", + "Read Data", + "Write Data", + "Read Verify", + "Write with Verify", + "Seek", + "Park Head", + "Get Command Complete Status", + "Get Device Status", + "Get Device Configuration", + "Get POS Information", + "Translate RBA", + "Write Attachment Buffer", + "Read Attachment Buffer", + "Run Diagnostic Test", + "Get Diagnostic Status Block", + "Get MFG Header", + "Format Unit", + "Format Prepare", + "Set MAX RBA", + "Set Power Saving Mode", + "Power Conservation Command", +}; + +static const char * const edc_cmd_status[256] = { + "Reserved", + "Command completed successfully", + "Reserved", + "Command completed successfully with ECC applied", + "Reserved", + "Command completed successfully with retries", + "Format Command partially completed", /* Status available */ + "Command completed successfully with ECC and retries", + "Command completed with Warning", /* Command Error is available */ + "Aborted", + "Reset completed", + "Data Transfer Ready", /* No Status Block available */ + "Command terminated with failure", /* Device Error is available */ + "DMA Error", /* Retry entire command as recovery */ + "Command Block Error", + "Attention Error (Illegal Attention Code)", + /* 0x14 - 0xff reserved */ +}; + +static const char * const edc_cmd_error[256] = { + "No Error", + "Invalid parameter in the command block", + "Reserved", + "Command not supported", + "Command Aborted per request", + "Reserved", + "Command rejected", /* Attachment diagnostic failure */ + "Format Rejected", /* Prepare Format command is required */ + "Format Error (Primary Map is not readable)", + "Format Error (Secondary map is not readable)", + "Format Error (Diagnostic Failure)", + "Format Warning (Secondary Map Overflow)", + "Reserved" + "Format Error (Host Checksum Error)", + "Reserved", + "Format Warning (Push table overflow)", + "Format Warning (More pushes than allowed)", + "Reserved", + "Format Warning (Error during verifying)", + "Invalid device number for the command", + /* 0x14-0xff reserved */ +}; + +static const char * const edc_dev_status[] = { + "Seek or Command complete", + "Track 0 Flag (emulated)", + "Write Fault (emulated)", + "Selected", + "Ready", + "Reserved (0)", + "STANDBY", + "Reserved (0)", +}; + +static const char * const edc_dev_errors[] = { + "No Error", + "Seek Fault", /* Device report */ + "Interface Fault (Parity, Attn, or Cmd Complete Error)", + "Block not found (ID not found)", + "Block not found (AM not found)", + "Data ECC Error (hard error)", + "ID CRC Error", + "RBA Out of Range", + "Reserved", + "Defective Block", + "Reserved", + "Selection Error", + "Reserved", + "Write Fault", + "No index or sector pulse", + "Device Not Ready", + "Seek Error", /* Attachment report */ + "Bad Format", + "Volume Overflow", + "No Data AM Found", + "(Block not found) No ID AM or ID CRC error occured", + "Reserved", + "Reserved", + "No ID found on track (ID search)", + /* 0x19 - 0xff reserved */ +}; + +static void +edc_dump_status_block(sc, devno, cmd, intr_id) + struct edc_mca_softc *sc; + int devno, cmd, intr_id; +{ + struct ed_softc *ed = sc->sc_ed[devno]; + printf("%s: Command: %s, Status: %s\n", + ed->sc_dev.dv_xname, + edc_commands[ed->sc_status_block[0] & 0x1f], + edc_cmd_status[SB_GET_CMD_STATUS(ed->sc_status_block)] + ); + printf("%s: IntrId: %s\n", ed->sc_dev.dv_xname, + edc_cmd_status[intr_id]); + + if (cmd == ISR_COMPLETED_WARNING) { + printf("%s: Command Error Code: %s\n", + ed->sc_dev.dv_xname, + edc_cmd_error[ed->sc_status_block[1] & 0xff]); + } + + if (cmd == ISR_CMD_FAILED) { + printf("%s: Device: Status: %s, Error Code: %s\n", + ed->sc_dev.dv_xname, + edc_dev_status[(ed->sc_status_block[2] & 0xff00) >> 8], + edc_dev_errors[ed->sc_status_block[2] & 0xff]); + } +} diff --git a/sys/dev/mca/edcreg.h b/sys/dev/mca/edcreg.h new file mode 100644 index 00000000000..ff7edc64aec --- /dev/null +++ b/sys/dev/mca/edcreg.h @@ -0,0 +1,131 @@ +/* $NetBSD: edcreg.h,v 1.1 2001/04/19 17:17:29 jdolecek Exp $ */ + +/* + * Copyright (c) 2001 The NetBSD Foundation, Inc. + * + * This code is derived from software contributed to The NetBSD Foundation + * by Jaromir Dolecek. + * + * 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 NetBSD + * Foundation, Inc. and its contributors. + * 4. The name of the author may not be used to endorse or promote products + * derived from this software without specific prior written permission. + * + * THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``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 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. + */ + +/* + * Driver for MCA ESDI controllers and disks. + */ + +#define ESDIC_IOPRM 0x3510 +#define ESDIC_IOALT 0x3518 +#define ESDIC_REG_NPORTS 8 +#define ESDIC_IRQ 14 /* this is fixed */ + +/* pos2 */ +#define IO_IS_ALT 0x02 +#define DRQ_MASK 0x3c +#define FAIRNESS_ENABLE 0x40 + +/* pos3 */ +#define PACING_INT_MASK 0x30 + +/* pos4 */ +#define PACING_CTRL_DISABLE 0x01 +#define RELEASE_2 0x02 /* lower bit of Time to Release */ +#define RELEASE_1 0x04 /* higher bit of Time to Release */ + +/* controller registers */ +#define SIFR 0 /* read Status Interface Register, + 2 bytes, little endian */ +#define SIFR_CMD_MASK 0x2f + +#define CIFR 0 /* write - Command Interface Reg, + 2 bytes, little endian */ +#define CIFR_LONG_CMD (1<<14) /* 4 word command */ + +/* Command Codes */ +#define CMD_READ_DATA 0x01 /* uses DMA */ +#define CMD_WRITE_DATA 0x02 /* uses DMA */ +#define CMD_READ_VERIFY 0x03 +#define CMD_WRITE_VERIFY 0x04 /* uses DMA */ +#define CMD_SEEK 0x05 +#define CMD_PARK_HEAD 0x06 +#define CMD_GET_CMD_COMP_STATUS 0x07 +#define CMD_GET_DEV_STATUS 0x08 +#define CMD_GET_DEV_CONF 0x09 +#define CMD_GET_POS_INFO 0x0A +#define CMD_TRANSLATE_RBA 0x0B +#define CMD_WRITE_ATTACH_BUFF 0x10 /* uses DMA */ +#define CMD_READ_ATTACH_BUFF 0x11 /* uses DMA */ +#define CMD_RUN_DIAG_TEST 0x12 +#define CMD_GET_DIAG_STAT_BLOCK 0x14 +#define CMD_GET_MFG_HEADER 0x15 /* uses DMA */ +#define CMD_FORMAT_UNIT 0x16 /* uses DMA */ +#define CMD_FORMAT_PREPARE 0x17 +#define CMD_SET_MAX_RBA 0x1A +#define CMD_SET_PWR_SAV_MODE 0x1B /* optional */ +#define CMD_POWER_CONS_CMD 0x1C /* optional */ + +#define BCR 2 /* write */ +#define BCR_INT_ENABLE 0x01 +#define BCR_DMA_ENABLE 0x02 +#define BCR_RESET 0x80 + +#define BSR 2 /* read */ +#define BSR_DMA_ENABLED 0x80 +#define BSR_INT_PENDING 0x40 +#define BSR_CMD_INPROGRESS 0x20 +#define BSR_BUSY 0x10 +#define BSR_SIFR_FULL 0x08 /* also called STATUS OUT */ +#define BSR_CIFR_FULL 0x04 +#define BSR_TRANSFER_REQ 0x02 +#define BSR_INTR 0x01 + +#define ISR 3 /* read, Interrupt Status Register */ +#define ISR_DEV_SELECT_MASK 0xE0 +#define ISR_ATTACH_ERR 0x10 +#define ISR_INTR_ID_MASK 0x0F +#define ISR_COMPLETED 0x01 +#define ISR_COMPLETED_WITH_ECC 0x03 +#define ISR_COMPLETED_RETRIES 0x05 +#define ISR_PARTIAL_FORMAT 0x06 /* Status available */ +#define ISR_COMPLETED_WARNING 0x08 +#define ISR_ABORT_COMPLETED 0x09 +#define ISR_RESET_COMPLETED 0x0A +#define ISR_DATA_TRANSFER_RDY 0x0B /* No Status Block */ +#define ISR_CMD_FAILED 0x0C +#define ISR_DMA_ERROR 0x0D +#define ISR_CMD_BLOCK_ERROR 0x0E +#define ISR_ATTN_ERROR 0x0F + +/* Macros to get info from command status block */ +#define SB_GET_CMD_STATUS(sb) (((sb)[1] & 0xff00) >> 8) + +#define ATN 3 /* write, Attention register */ +#define ATN_CMD_REQ 1 +#define ATN_END_INT 2 /* End of Interrupt (EOI) */ +#define ATN_ABORT_CMD 3 +#define ATN_RESET_ATTACHMENT 4 + +#define DASD_DEVNO_CONTROLLER 7 /* Device number for controller */ diff --git a/sys/dev/mca/edcvar.h b/sys/dev/mca/edcvar.h new file mode 100644 index 00000000000..3c7339d17e2 --- /dev/null +++ b/sys/dev/mca/edcvar.h @@ -0,0 +1,43 @@ +/* $NetBSD: edcvar.h,v 1.1 2001/04/19 17:17:29 jdolecek Exp $ */ + +/* + * Copyright (c) 2001 The NetBSD Foundation, Inc. + * + * This code is derived from software contributed to The NetBSD Foundation + * by Jaromir Dolecek. + * + * 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 NetBSD + * Foundation, Inc. and its contributors. + * 4. The name of the author may not be used to endorse or promote products + * derived from this software without specific prior written permission. + * + * THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``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 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. + */ + +struct ed_attach_args { + int sc_devno; + bus_dma_tag_t sc_dmat; /* DMA tag as passed by parent */ +}; + +int edc_run_cmd __P((struct edc_mca_softc *, int, + int, u_int16_t [], int, int)); +void edc_add_disk __P((struct edc_mca_softc *, struct ed_softc *, int)); diff --git a/sys/dev/mca/edvar.h b/sys/dev/mca/edvar.h index 40bef4e245e..3d6ad3e0417 100644 --- a/sys/dev/mca/edvar.h +++ b/sys/dev/mca/edvar.h @@ -1,4 +1,4 @@ -/* $NetBSD: edvar.h,v 1.1 2001/04/19 07:30:24 jdolecek Exp $ */ +/* $NetBSD: edvar.h,v 1.2 2001/04/19 17:17:29 jdolecek Exp $ */ /* * Copyright (c) 2001 The NetBSD Foundation, Inc. @@ -33,7 +33,7 @@ * THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. */ -struct dasd_mca_softc; +struct edc_mca_softc; #define DASD_MAX_CMD_RES_LEN 8 struct ed_softc { @@ -46,7 +46,7 @@ struct ed_softc { struct callout sc_edstart; struct buf *sc_bp; /* buf being transfered */ - struct dasd_mca_softc *dasd_softc; /* pointer to our parent */ + struct edc_mca_softc *edc_softc; /* pointer to our parent */ int sc_flags; #define WDF_LOCKED 0x001 diff --git a/sys/dev/mca/files.mca b/sys/dev/mca/files.mca index 6aa4faa8c98..efda3740dac 100644 --- a/sys/dev/mca/files.mca +++ b/sys/dev/mca/files.mca @@ -1,4 +1,4 @@ -# $NetBSD: files.mca,v 1.9 2001/04/19 07:30:25 jdolecek Exp $ +# $NetBSD: files.mca,v 1.10 2001/04/19 17:17:29 jdolecek Exp $ # # Config.new file and device description for machine-independent MCA code. # Included by ports that need it. @@ -41,10 +41,10 @@ attach ate at mca with ate_mca file dev/mca/if_ate_mca.c ate_mca # ESDI controllers & disks -device dasd { } -attach dasd at mca with dasd_mca -file dev/mca/dasd_mca.c dasd_mca +device edc { } +attach edc at mca with edc_mca +file dev/mca/edc_mca.c edc_mca device ed: disk -attach ed at dasd with ed_mca +attach ed at edc with ed_mca file dev/mca/ed_mca.c ed_mca needs-flag -- cgit