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