Source-Changes-HG archive

[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index][Old Index]

[src/netbsd-6]: src/sys/arch/x68k/dev Pull up following revision(s) (requeste...



details:   https://anonhg.NetBSD.org/src/rev/b33cb6e161ac
branches:  netbsd-6
changeset: 775445:b33cb6e161ac
user:      riz <riz%NetBSD.org@localhost>
date:      Sun Nov 18 21:56:36 2012 +0000

description:
Pull up following revision(s) (requested by tsutsui in ticket #646):
        sys/arch/x68k/dev/intio_dmac.c: revision 1.34
        sys/arch/x68k/dev/fd.c: revision 1.100
        sys/arch/x68k/dev/fd.c: revision 1.101
        sys/arch/x68k/dev/fd.c: revision 1.102
        sys/arch/x68k/dev/fd.c: revision 1.103
        sys/arch/x68k/dev/fd.c: revision 1.104
        sys/arch/x68k/dev/fd.c: revision 1.105
        sys/arch/x68k/dev/fd.c: revision 1.98
        sys/arch/x68k/dev/fd.c: revision 1.99
        sys/arch/x68k/dev/fdreg.h: revision 1.5
        sys/arch/x68k/dev/fdreg.h: revision 1.6
Explicitly specify a proper FDC data register address for HD63450 DMAC
to avoid confusion.
Previous one (fdc->sc_addr + fddata) wasn't a right address for
the FDC's data register but one for the command register by accident,
but FDC ignores A0 address input (connected to A1 of x68k address bus)
during DMA xfer (i.e. when DACK is asserted) so it happened to work
as expected on the real X680x0 hardware, but caused trouble on emulators.
The inconsistency was found by Y.Sugahara during debugging XM6i emulator
(and it will be fixed in the next release).
FDC behavior during DMA is confirmed by uPD72068 hardware application note.
XXX: There is no proper MI API to specify DMA address for DMA controller
     (like MC68450) to access devices mapped to memory space by bus_space(9).
- use <sys/bus.h> rather than <machine/bus.h>
- no need to include uvm_extern.h
- include "ioconf.h" for struct cfdriver foo_cd
KNF and cosmetics.  No binary change.
- check bus_space_map(9) return value
- use BUS_SPACE_MAP_SHIFTED_ODD for clarify
- define and use proper macro instead of magic
To abort DMA in dmac_abort_xfer(), set DMAC_CCR_SAB (software abort)
rather than DMAC_CCR_HLT (halt operation).
DMAC_CCR_HLT doesn't abort DMA xfers but only suspends DMA ops
(i.e. clearing HLT bit will resume DMA xfers), so previously
DMAC error always occurs on the next DMA xfer ops after
dmac_abort_xfer() is called.
Also suppress DMAC error messages in dmac_error() if it's caused
by software abort command because it can happen during normal
audio play/record DMA ops in vs(4) driver.
Before probing floppy drives, call NE7CMD_SENSEI and fdcresult()
to drain possible pending FDC interrupts.  Taken from sys/dev/isa/fd.c.
Hopefully might fix occasional fd drive probe failure (but not confirmed).
Terminate DMAC and call bus_dmamap_unload(9) properly in all FDC xfer
error paths, as sys/dev/isa/fd.c does.  Fixes unexpected DMAC errors
(and possible VM panic due to un-unloaded dmamap) on the first floppy
access after read/write errors.
Add floppy format support.  Mostly taken from sys/dev/isa/fd.c.
Tested both fdNa (1232KB, 1024bytes/sector, 8sectors/track) and
fdNc (1200KB, 512bytes/sector, 15sectors/track) format on X68030
using fdformat(1).
Finally we can prepare NetBSD/x68k install floppies without Human68k
(except actual initial bootstrap).
KNF and space nits

diffstat:

 sys/arch/x68k/dev/fd.c         |  617 ++++++++++++++++++++++++++++------------
 sys/arch/x68k/dev/fdreg.h      |   52 +++-
 sys/arch/x68k/dev/intio_dmac.c |   20 +-
 3 files changed, 498 insertions(+), 191 deletions(-)

diffs (truncated from 1362 to 300 lines):

diff -r d848adb6c0ba -r b33cb6e161ac sys/arch/x68k/dev/fd.c
--- a/sys/arch/x68k/dev/fd.c    Sun Nov 18 21:49:48 2012 +0000
+++ b/sys/arch/x68k/dev/fd.c    Sun Nov 18 21:56:36 2012 +0000
@@ -1,4 +1,4 @@
-/*     $NetBSD: fd.c,v 1.96.2.1 2012/05/09 20:01:51 riz Exp $  */
+/*     $NetBSD: fd.c,v 1.96.2.2 2012/11/18 21:56:37 riz Exp $  */
 
 /*-
  * Copyright (c) 1998 The NetBSD Foundation, Inc.
@@ -64,13 +64,14 @@
  */
 
 #include <sys/cdefs.h>
-__KERNEL_RCSID(0, "$NetBSD: fd.c,v 1.96.2.1 2012/05/09 20:01:51 riz Exp $");
+__KERNEL_RCSID(0, "$NetBSD: fd.c,v 1.96.2.2 2012/11/18 21:56:37 riz Exp $");
 
 #include "opt_ddb.h"
 #include "opt_m68k_arch.h"
 
 #include <sys/param.h>
 #include <sys/systm.h>
+#include <sys/bus.h>
 #include <sys/callout.h>
 #include <sys/kernel.h>
 #include <sys/conf.h>
@@ -86,14 +87,12 @@
 #include <sys/uio.h>
 #include <sys/syslog.h>
 #include <sys/queue.h>
+#include <sys/proc.h>
 #include <sys/fdio.h>
 #include <sys/rnd.h>
 
-#include <uvm/uvm_extern.h>
-
 #include <dev/cons.h>
 
-#include <machine/bus.h>
 #include <machine/cpu.h>
 
 #include <arch/x68k/dev/intiovar.h>
@@ -102,6 +101,7 @@
 #include <arch/x68k/dev/opmvar.h> /* for CT1 access */
 
 #include "locators.h"
+#include "ioconf.h"
 
 #ifdef FDDEBUG
 #define DPRINTF(x)      if (fddebug) printf x
@@ -113,6 +113,9 @@
 #define FDUNIT(dev)    (minor(dev) / 8)
 #define FDTYPE(dev)    (minor(dev) % 8)
 
+/* (mis)use device use flag to identify format operation */
+#define B_FORMAT B_DEVPRIVATE
+
 enum fdc_state {
        DEVIDLE = 0,
        MOTORWAIT,
@@ -145,7 +148,7 @@
 
        bus_dma_tag_t sc_dmat;          /* intio DMA tag */
        bus_dmamap_t sc_dmamap;         /* DMA map */
-       u_int8_t *sc_addr;                      /* physical address */
+       uint8_t *sc_addr;               /* physical address */
        struct dmac_channel_stat *sc_dmachan; /* intio DMA channel */
        struct dmac_dma_xfer *sc_xfer;  /* DMA transfer */
        int sc_read;
@@ -154,7 +157,7 @@
        TAILQ_HEAD(drivehead, fd_softc) sc_drives;
        enum fdc_state sc_state;
        int sc_errors;                  /* number of retries so far */
-       u_char sc_status[7];            /* copy of registers */
+       uint8_t sc_status[7];           /* copy of registers */
 } fdc_softc;
 
 int fdcintr(void *);
@@ -168,8 +171,6 @@
 CFATTACH_DECL_NEW(fdc, sizeof(struct fdc_softc),
     fdcprobe, fdcattach, NULL, NULL);
 
-extern struct cfdriver fdc_cd;
-
 /*
  * Floppies come in various flavors, e.g., 1.2MB vs 1.44MB; here is how
  * we tell them apart.
@@ -187,19 +188,29 @@
        int     size;           /* size of disk in sectors */
        int     step;           /* steps per cylinder */
        int     rate;           /* transfer speed code */
+       uint8_t fillbyte;       /* format fill byte */
+       uint8_t interleave;     /* interleave factor (formatting) */
        const char *name;
 };
 
 /* The order of entries in the following table is important -- BEWARE! */
 struct fd_type fd_types[] = {
-        {  8,2,16,3,0xff,0xdf,0x35,0x74,77,1232,1,FDC_500KBPS, "1.2MB/[1024bytes/sector]"    }, /* 1.2 MB japanese format */
-        { 18,2,36,2,0xff,0xcf,0x1b,0x6c,80,2880,1,FDC_500KBPS,"1.44MB"    }, /* 1.44MB diskette */
-        { 15,2,30,2,0xff,0xdf,0x1b,0x54,80,2400,1,FDC_500KBPS, "1.2MB"    }, /* 1.2 MB AT-diskettes */
-        {  9,2,18,2,0xff,0xdf,0x23,0x50,40, 720,2,FDC_300KBPS, "360KB/AT" }, /* 360kB in 1.2MB drive */
-        {  9,2,18,2,0xff,0xdf,0x2a,0x50,40, 720,1,FDC_250KBPS, "360KB/PC" }, /* 360kB PC diskettes */
-        {  9,2,18,2,0xff,0xdf,0x2a,0x50,80,1440,1,FDC_250KBPS, "720KB"    }, /* 3.5" 720kB diskette */
-        {  9,2,18,2,0xff,0xdf,0x23,0x50,80,1440,1,FDC_300KBPS, "720KB/x"  }, /* 720kB in 1.2MB drive */
-        {  9,2,18,2,0xff,0xdf,0x2a,0x50,40, 720,2,FDC_250KBPS, "360KB/x"  }, /* 360kB in 720kB drive */
+       {  8,2,16,3,0xff,0xdf,0x35,0x74,77,1232,1,FDC_500KBPS, 0xf6, 1,
+           "1.2MB/[1024bytes/sector]"    }, /* 1.2 MB japanese format */
+       { 18,2,36,2,0xff,0xcf,0x1b,0x6c,80,2880,1,FDC_500KBPS, 0xf6, 1,
+           "1.44MB"    }, /* 1.44MB diskette */
+       { 15,2,30,2,0xff,0xdf,0x1b,0x54,80,2400,1,FDC_500KBPS, 0xf6, 1,
+           "1.2MB"    }, /* 1.2 MB AT-diskettes */
+       {  9,2,18,2,0xff,0xdf,0x23,0x50,40, 720,2,FDC_300KBPS, 0xf6, 1,
+           "360KB/AT" }, /* 360kB in 1.2MB drive */
+       {  9,2,18,2,0xff,0xdf,0x2a,0x50,40, 720,1,FDC_250KBPS, 0xf6, 1,
+           "360KB/PC" }, /* 360kB PC diskettes */
+       {  9,2,18,2,0xff,0xdf,0x2a,0x50,80,1440,1,FDC_250KBPS, 0xf6, 1,
+           "720KB"    }, /* 3.5" 720kB diskette */
+       {  9,2,18,2,0xff,0xdf,0x23,0x50,80,1440,1,FDC_300KBPS, 0xf6, 1,
+           "720KB/x"  }, /* 720kB in 1.2MB drive */
+       {  9,2,18,2,0xff,0xdf,0x2a,0x50,40, 720,2,FDC_250KBPS, 0xf6, 1,
+           "360KB/x"  }, /* 360kB in 720kB drive */
 };
 
 /* software state, per disk (with up to 4 disks per ctlr) */
@@ -236,8 +247,8 @@
        int sc_ops;             /* I/O ops since last switch */
        struct bufq_state *sc_q;/* pending I/O requests */
        int sc_active;          /* number of active I/O operations */
-       u_char *sc_copybuf;     /* for secsize >=3 */
-       u_char sc_part;         /* for secsize >=3 */
+       uint8_t *sc_copybuf;    /* for secsize >=3 */
+       uint8_t sc_part;        /* for secsize >=3 */
 #define        SEC_P10 0x02            /* first part */
 #define        SEC_P01 0x01            /* second part */
 #define        SEC_P11 0x03            /* both part */
@@ -252,8 +263,6 @@
 CFATTACH_DECL_NEW(fd, sizeof(struct fd_softc),
     fdprobe, fdattach, NULL, NULL);
 
-extern struct cfdriver fd_cd;
-
 dev_type_open(fdopen);
 dev_type_close(fdclose);
 dev_type_read(fdread);
@@ -280,7 +289,7 @@
 void fd_motor_on(void *);
 #endif
 int fdcresult(struct fdc_softc *);
-int out_fdc(bus_space_tag_t, bus_space_handle_t, u_char);
+int out_fdc(bus_space_tag_t, bus_space_handle_t, uint8_t);
 void fdcstart(struct fdc_softc *);
 void fdcstatus(device_t, int, const char *);
 void fdctimeout(void *);
@@ -288,6 +297,7 @@
 void fdcretry(struct fdc_softc *);
 void fdfinish(struct fd_softc *, struct buf *);
 inline struct fd_type *fd_dev_to_type(struct fd_softc *, dev_t);
+int fdformat(dev_t, struct ne7_fd_formb *, struct lwp *);
 static int fdcpoll(struct fdc_softc *);
 static int fdgetdisklabel(struct fd_softc *, dev_t);
 static void fd_do_eject(struct fdc_softc *, int);
@@ -296,6 +306,7 @@
 
 /* DMA transfer routines */
 inline static void fdc_dmastart(struct fdc_softc *, int, void *, vsize_t);
+inline static void fdc_dmaabort(struct fdc_softc *);
 static int fdcdmaintr(void *);
 static int fdcdmaerrintr(void *);
 
@@ -305,30 +316,47 @@
        int error;
 
        DPRINTF(("fdc_dmastart: %s, addr = %p, count = %ld\n",
-                read ? "read" : "write", (void *) addr, count));
+           read ? "read" : "write", (void *)addr, count));
 
        error = bus_dmamap_load(fdc->sc_dmat, fdc->sc_dmamap, addr, count,
-                               0, BUS_DMA_NOWAIT);
+           0, BUS_DMA_NOWAIT);
        if (error) {
-               panic ("fdc_dmastart: cannot load dmamap");
+               panic("fdc_dmastart: cannot load dmamap");
        }
 
        bus_dmamap_sync(fdc->sc_dmat, fdc->sc_dmamap, 0, count,
-                       read?BUS_DMASYNC_PREREAD:BUS_DMASYNC_PREWRITE);
+           read ? BUS_DMASYNC_PREREAD : BUS_DMASYNC_PREWRITE);
 
+       /*
+        * Note 1:
+        *  uPD72065 ignores A0 input (connected to x68k bus A1)
+        *  during DMA xfer access, but it's better to explicitly
+        *  specify FDC data register address for clarification.
+        * Note 2:
+        *  FDC is connected to LSB 8 bits of X68000 16 bit bus
+        *  (as BUS_SPACE_MAP_SHIFTED_ODD defined in bus.h)
+        *  so each FDC regsiter is mapped at sparse odd address.
+        *
+        * XXX: No proper API to get DMA address of FDC register for DMAC.
+        */
        fdc->sc_xfer = dmac_prepare_xfer(fdc->sc_dmachan, fdc->sc_dmat,
-                                        fdc->sc_dmamap,
-                                        (read?
-                                         DMAC_OCR_DIR_DTM:DMAC_OCR_DIR_MTD),
-                                        (DMAC_SCR_MAC_COUNT_UP|
-                                         DMAC_SCR_DAC_NO_COUNT),
-                                        (u_int8_t*) (fdc->sc_addr +
-                                                     fddata)); /* XXX */
+           fdc->sc_dmamap,
+           read ? DMAC_OCR_DIR_DTM : DMAC_OCR_DIR_MTD,
+           DMAC_SCR_MAC_COUNT_UP | DMAC_SCR_DAC_NO_COUNT,
+           fdc->sc_addr + fddata * 2 + 1);
 
        fdc->sc_read = read;
        dmac_start_xfer(fdc->sc_dmachan->ch_softc, fdc->sc_xfer);
 }
 
+inline static void
+fdc_dmaabort(struct fdc_softc *fdc)
+{
+
+       dmac_abort_xfer(fdc->sc_dmachan->ch_softc, fdc->sc_xfer);
+       bus_dmamap_unload(fdc->sc_dmat, fdc->sc_dmamap);
+}
+
 static int
 fdcdmaintr(void *arg)
 {
@@ -346,6 +374,7 @@
 static int
 fdcdmaerrintr(void *dummy)
 {
+
        DPRINTF(("fdcdmaerrintr\n"));
 
        return 0;
@@ -372,8 +401,8 @@
        if ((ia->ia_intr & 0x03) != 0)
                return 0;
 
-       ia->ia_size = 0x2000;
-       if (intio_map_allocate_region (parent, ia, INTIO_MAP_TESTONLY))
+       ia->ia_size = FDC_MAPSIZE;
+       if (intio_map_allocate_region(parent, ia, INTIO_MAP_TESTONLY))
                return 0;
 
        /* builtin device; always there */
@@ -400,7 +429,7 @@
 {
        struct fdc_attach_args *fa = aux;
 
-       if (!fdc)
+       if (fdc == NULL)
                aprint_normal(" drive %d", fa->fa_drive);
        return QUIET;
 }
@@ -418,12 +447,16 @@
 
        aprint_normal("\n");
 
+       /* Re-map the I/O space. */
+       if (bus_space_map(iot, ia->ia_addr, ia->ia_size,
+           BUS_SPACE_MAP_SHIFTED_ODD, &ioh) != 0) {
+               aprint_error_dev(self, "unable to map I/O space\n");
+               return;
+       }
+
        callout_init(&fdc->sc_timo_ch, 0);
        callout_init(&fdc->sc_intr_ch, 0);
 
-       /* Re-map the I/O space. */
-       bus_space_map(iot, ia->ia_addr, 0x2000, BUS_SPACE_MAP_SHIFTED, &ioh);
-
        fdc->sc_iot = iot;
        fdc->sc_ioh = ioh;
        fdc->sc_addr = (void *)ia->ia_addr;
@@ -434,18 +467,16 @@
 
        /* Initialize DMAC channel */
        fdc->sc_dmachan = dmac_alloc_channel(parent, ia->ia_dma, "fdc",
-                                            ia->ia_dmaintr, fdcdmaintr, fdc,
-                                            ia->ia_dmaintr+1, fdcdmaerrintr,
-                                            fdc);
+           ia->ia_dmaintr, fdcdmaintr, fdc,
+           ia->ia_dmaintr + 1, fdcdmaerrintr, fdc);
        if (bus_dmamap_create(fdc->sc_dmat, FDC_MAXIOSIZE, 1, DMAC_MAXSEGSZ,
-                             0, BUS_DMA_NOWAIT|BUS_DMA_ALLOCNOW,
-                             &fdc->sc_dmamap)) {
+           0, BUS_DMA_NOWAIT | BUS_DMA_ALLOCNOW, &fdc->sc_dmamap)) {
                aprint_error_dev(self, "can't set up intio DMA map\n");
                return;
        }
 
-       if (intio_intr_establish(ia->ia_intr, "fdc", fdcintr, fdc))
-               panic ("Could not establish interrupt (duplicated vector?).");
+       if (intio_intr_establish(ia->ia_intr, "fdc", fdcintr, fdc) != 0)
+               panic("Could not establish interrupt (duplicated vector?).");
        intio_set_ivec(ia->ia_intr);
 
        /* reset */



Home | Main Index | Thread Index | Old Index