Source-Changes-HG archive

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

[src/trunk]: src/sys Implement an atabus control device, and define some ATA ...



details:   https://anonhg.NetBSD.org/src/rev/0cb67847356c
branches:  trunk
changeset: 568825:0cb67847356c
user:      bouyer <bouyer%NetBSD.org@localhost>
date:      Sun Aug 01 21:40:41 2004 +0000

description:
Implement an atabus control device, and define some ATA bus control
IOCTLS. Implement ATABUSIORESET, which will reset the given ATA bus.

diffstat:

 sys/conf/majors            |   3 +-
 sys/dev/ata/ata.c          |  97 +++++++++++++++++++++++++++++++++++++++++++++-
 sys/dev/ata/ata_wdc.c      |   6 +-
 sys/dev/ata/atavar.h       |   4 +-
 sys/dev/ic/wdc.c           |  29 ++++++++-----
 sys/dev/ic/wdcvar.h        |   5 +-
 sys/dev/scsipi/atapi_wdc.c |   6 +-
 sys/sys/ataio.h            |  19 ++++++++-
 8 files changed, 144 insertions(+), 25 deletions(-)

diffs (truncated from 366 to 300 lines):

diff -r 3cff43b08437 -r 0cb67847356c sys/conf/majors
--- a/sys/conf/majors   Sun Aug 01 19:31:46 2004 +0000
+++ b/sys/conf/majors   Sun Aug 01 21:40:41 2004 +0000
@@ -1,4 +1,4 @@
-# $NetBSD: majors,v 1.9 2004/06/18 15:02:29 christos Exp $
+# $NetBSD: majors,v 1.10 2004/08/01 21:40:41 bouyer Exp $
 #
 # Device majors for Machine-Independent drivers.
 #
@@ -15,3 +15,4 @@
 device-major   fss             char 163 block 163      fss
 device-major   pps             char 164                pps
 device-major   ptm             char 165                pty
+device-major   atabus          char 166                atabus
diff -r 3cff43b08437 -r 0cb67847356c sys/dev/ata/ata.c
--- a/sys/dev/ata/ata.c Sun Aug 01 19:31:46 2004 +0000
+++ b/sys/dev/ata/ata.c Sun Aug 01 21:40:41 2004 +0000
@@ -1,4 +1,4 @@
-/*      $NetBSD: ata.c,v 1.29 2004/05/27 02:23:12 thorpej Exp $      */
+/*      $NetBSD: ata.c,v 1.30 2004/08/01 21:40:41 bouyer Exp $      */
 
 /*
  * Copyright (c) 1998, 2001 Manuel Bouyer.  All rights reserved.
@@ -30,7 +30,7 @@
  */
 
 #include <sys/cdefs.h>
-__KERNEL_RCSID(0, "$NetBSD: ata.c,v 1.29 2004/05/27 02:23:12 thorpej Exp $");
+__KERNEL_RCSID(0, "$NetBSD: ata.c,v 1.30 2004/08/01 21:40:41 bouyer Exp $");
 
 #ifndef WDCDEBUG
 #define WDCDEBUG
@@ -41,9 +41,12 @@
 #include <sys/kernel.h>
 #include <sys/malloc.h>
 #include <sys/device.h>
+#include <sys/conf.h>
+#include <sys/fcntl.h>
 #include <sys/proc.h>
 #include <sys/kthread.h>
 #include <sys/errno.h>
+#include <sys/ataio.h>
 
 #include <machine/intr.h>
 #include <machine/bus.h>
@@ -74,6 +77,18 @@
  * for drives, etc.
  *****************************************************************************/
 
+dev_type_open(atabusopen);
+dev_type_close(atabusclose);
+dev_type_ioctl(atabusioctl);
+
+const struct cdevsw atabus_cdevsw = {
+       atabusopen, atabusclose, noread, nowrite, atabusioctl,
+       nostop, notty, nopoll, nommap, nokqfilter,
+};
+
+extern struct cfdriver atabus_cd;
+
+
 /*
  * atabusprint:
  *
@@ -481,3 +496,81 @@
                drvp->n_xfers = 1; /* restart counting from this error */
        }
 }
+
+/* management of the /dev/atabus* devices */
+int atabusopen(dev, flag, fmt, p)
+       dev_t dev;
+       int flag, fmt;
+       struct proc *p;
+{
+        struct atabus_softc *sc;
+        int error, unit = minor(dev);
+   
+        if (unit >= atabus_cd.cd_ndevs ||
+            (sc = atabus_cd.cd_devs[unit]) == NULL)
+                return (ENXIO);
+ 
+        if (sc->sc_flags & ATABUSCF_OPEN)
+                return (EBUSY);
+
+        if ((error = wdc_addref(sc->sc_chan)) != 0)
+                return (error);
+
+        sc->sc_flags |= ATABUSCF_OPEN;
+
+        return (0);
+}
+
+
+int
+atabusclose(dev, flag, fmt, p)
+        dev_t dev;
+        int flag, fmt;
+        struct proc *p;
+{
+        struct atabus_softc *sc = atabus_cd.cd_devs[minor(dev)];
+
+        wdc_delref(sc->sc_chan);
+
+        sc->sc_flags &= ~ATABUSCF_OPEN;
+
+        return (0);
+}
+
+int
+atabusioctl(dev, cmd, addr, flag, p)
+        dev_t dev;
+        u_long cmd;
+        caddr_t addr;
+        int flag;
+        struct proc *p;
+{
+        struct atabus_softc *sc = atabus_cd.cd_devs[minor(dev)];
+        int error;
+       int s;
+
+        /*
+         * Enforce write permission for ioctls that change the
+         * state of the bus.  Host adapter specific ioctls must
+         * be checked by the adapter driver.
+         */
+        switch (cmd) {
+        case ATABUSIOSCAN:
+        case ATABUSIODETACH:
+        case ATABUSIORESET:
+                if ((flag & FWRITE) == 0)
+                        return (EBADF);
+        }
+
+        switch (cmd) {
+        case ATABUSIORESET:
+               s = splbio();
+               wdc_reset_channel(sc->sc_chan, AT_WAIT | AT_POLL);
+               splx(s);
+               error = 0;
+               break;
+       default:
+               error = ENOTTY;
+       }
+       return (error);
+};
diff -r 3cff43b08437 -r 0cb67847356c sys/dev/ata/ata_wdc.c
--- a/sys/dev/ata/ata_wdc.c     Sun Aug 01 19:31:46 2004 +0000
+++ b/sys/dev/ata/ata_wdc.c     Sun Aug 01 21:40:41 2004 +0000
@@ -1,4 +1,4 @@
-/*     $NetBSD: ata_wdc.c,v 1.58 2004/07/31 21:26:43 bouyer Exp $      */
+/*     $NetBSD: ata_wdc.c,v 1.59 2004/08/01 21:40:41 bouyer Exp $      */
 
 /*
  * Copyright (c) 1998, 2001, 2003 Manuel Bouyer.
@@ -66,7 +66,7 @@
  */
 
 #include <sys/cdefs.h>
-__KERNEL_RCSID(0, "$NetBSD: ata_wdc.c,v 1.58 2004/07/31 21:26:43 bouyer Exp $");
+__KERNEL_RCSID(0, "$NetBSD: ata_wdc.c,v 1.59 2004/08/01 21:40:41 bouyer Exp $");
 
 #ifndef WDCDEBUG
 #define WDCDEBUG
@@ -133,7 +133,7 @@
 const struct ata_bustype wdc_ata_bustype = {
        SCSIPI_BUSTYPE_ATA,
        wdc_ata_bio,
-       wdc_reset_channel,
+       wdc_reset_drive,
        wdc_exec_command,
        ata_get_params,
        wdc_ata_addref,
diff -r 3cff43b08437 -r 0cb67847356c sys/dev/ata/atavar.h
--- a/sys/dev/ata/atavar.h      Sun Aug 01 19:31:46 2004 +0000
+++ b/sys/dev/ata/atavar.h      Sun Aug 01 21:40:41 2004 +0000
@@ -1,4 +1,4 @@
-/*     $NetBSD: atavar.h,v 1.44 2004/07/31 21:26:43 bouyer Exp $       */
+/*     $NetBSD: atavar.h,v 1.45 2004/08/01 21:40:41 bouyer Exp $       */
 
 /*
  * Copyright (c) 1998, 2001 Manuel Bouyer.
@@ -81,6 +81,8 @@
 struct atabus_softc {
        struct device sc_dev;
        struct wdc_channel *sc_chan;    /* XXXwdc */
+       int sc_flags;
+#define ATABUSCF_OPEN  0x01
 };
 
 /*
diff -r 3cff43b08437 -r 0cb67847356c sys/dev/ic/wdc.c
--- a/sys/dev/ic/wdc.c  Sun Aug 01 19:31:46 2004 +0000
+++ b/sys/dev/ic/wdc.c  Sun Aug 01 21:40:41 2004 +0000
@@ -1,4 +1,4 @@
-/*     $NetBSD: wdc.c,v 1.182 2004/07/31 21:26:42 bouyer Exp $ */
+/*     $NetBSD: wdc.c,v 1.183 2004/08/01 21:40:41 bouyer Exp $ */
 
 /*
  * Copyright (c) 1998, 2001, 2003 Manuel Bouyer.  All rights reserved.
@@ -70,7 +70,7 @@
  */
 
 #include <sys/cdefs.h>
-__KERNEL_RCSID(0, "$NetBSD: wdc.c,v 1.182 2004/07/31 21:26:42 bouyer Exp $");
+__KERNEL_RCSID(0, "$NetBSD: wdc.c,v 1.183 2004/08/01 21:40:41 bouyer Exp $");
 
 #ifndef WDCDEBUG
 #define WDCDEBUG
@@ -146,7 +146,6 @@
 static int     wdcprobe1(struct wdc_channel*, int);
 static void    __wdcerror(struct wdc_channel*, char *);
 static int     __wdcwait_reset(struct wdc_channel *, int, int);
-static void    __wdc_reset_channel(struct wdc_channel *, int);
 static void    __wdccommand_done(struct wdc_channel *, struct ata_xfer *);
 static void    __wdccommand_done_end(struct wdc_channel *, struct ata_xfer *);
 static void    __wdccommand_kill_xfer(struct wdc_channel *,
@@ -965,7 +964,7 @@
 
 /* Put all disk in RESET state */
 void
-wdc_reset_channel(struct ata_drive_datas *drvp, int flags)
+wdc_reset_drive(struct ata_drive_datas *drvp, int flags)
 {
        struct wdc_channel *chp = drvp->chnl_softc;
        struct wdc_softc *wdc = chp->ch_wdc;
@@ -974,13 +973,13 @@
            DEBUG_FUNCS);
 
 
-       __wdc_reset_channel(chp, flags);
+       wdc_reset_channel(chp, flags);
 }
 
-static void
-__wdc_reset_channel(struct wdc_channel *chp, int flags)
+void
+wdc_reset_channel(struct wdc_channel *chp, int flags)
 {
-       struct ata_xfer *xfer;
+       struct ata_xfer *xfer, *next_xfer;
        int drive;
 
        /*
@@ -994,15 +993,17 @@
        if ((flags & AT_RST_NOCMD) == 0) {
                xfer = TAILQ_FIRST(&chp->ch_queue->queue_xfer);
                if (xfer && xfer->c_chp != chp)
-                       __wdc_reset_channel(xfer->c_chp, flags);
+                       wdc_reset_channel(xfer->c_chp, flags);
                for (xfer = TAILQ_FIRST(&chp->ch_queue->queue_xfer);
-                   xfer != 0; ) {
+                   xfer != NULL; xfer = next_xfer) {
+                       next_xfer = TAILQ_NEXT(xfer, c_xferchain);
                        if (xfer->c_chp != chp)
                                continue;
                        if ((flags & AT_RST_EMERG) == 0)
                                xfer->c_kill_xfer(chp, xfer, KILL_RESET);
                }
        }
+       chp->ch_flags &= ~(WDCF_IRQ_WAIT|WDCF_DMA_WAIT);
        if ((flags & AT_POLL) == 0) {
                if (chp->ch_flags & WDCF_TH_RESET) {
                        /* no need to schedule a reset more than one time */
@@ -1012,7 +1013,11 @@
                wakeup(&chp->ch_thread);
                return;
        }
-       (void) wdcreset(chp, RESET_POLL);
+       if ((flags & AT_WAIT) == 0) {
+               (void) wdcreset(chp, RESET_POLL);
+       } else {
+               (void) wdcreset(chp, RESET_SLEEP);
+       }
        for (drive = 0; drive < 2; drive++) {
                chp->ch_drive[drive].state = 0;
        }
@@ -1604,7 +1609,7 @@
        wdc->set_modes(chp);
        wdc_print_modes(chp);
        /* reset the channel, which will shedule all drives for setup */
-       wdc_reset_channel(drvp, flags | AT_RST_NOCMD);
+       wdc_reset_channel(chp, flags | AT_RST_NOCMD);
        return 1;
 }
 
diff -r 3cff43b08437 -r 0cb67847356c sys/dev/ic/wdcvar.h
--- a/sys/dev/ic/wdcvar.h       Sun Aug 01 19:31:46 2004 +0000
+++ b/sys/dev/ic/wdcvar.h       Sun Aug 01 21:40:41 2004 +0000
@@ -1,4 +1,4 @@
-/*     $NetBSD: wdcvar.h,v 1.57 2004/05/25 20:42:41 thorpej Exp $      */
+/*     $NetBSD: wdcvar.h,v 1.58 2004/08/01 21:40:41 bouyer Exp $       */
 
 /*-
  * Copyright (c) 1998, 2003 The NetBSD Foundation, Inc.
@@ -209,7 +209,8 @@
                      u_int16_t);
 void   wdccommandshort(struct wdc_channel *, int, int);
 void   wdctimeout(void *arg);
-void   wdc_reset_channel(struct ata_drive_datas *, int);



Home | Main Index | Thread Index | Old Index