Source-Changes-HG archive
[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index][Old Index]
[src/trunk]: src/sys/dev/pci Add support for dynamically attaching and detach...
details: https://anonhg.NetBSD.org/src/rev/075a43482bc7
branches: trunk
changeset: 552274:075a43482bc7
user: thorpej <thorpej%NetBSD.org@localhost>
date: Mon Sep 22 18:31:10 2003 +0000
description:
Add support for dynamically attaching and detaching RAID array units.
diffstat:
sys/dev/pci/ld_twe.c | 36 ++++++-
sys/dev/pci/twe.c | 244 ++++++++++++++++++++++++++++++++++++--------------
sys/dev/pci/twevar.h | 12 ++-
3 files changed, 217 insertions(+), 75 deletions(-)
diffs (truncated from 441 to 300 lines):
diff -r feff2c522f5a -r 075a43482bc7 sys/dev/pci/ld_twe.c
--- a/sys/dev/pci/ld_twe.c Mon Sep 22 18:29:05 2003 +0000
+++ b/sys/dev/pci/ld_twe.c Mon Sep 22 18:31:10 2003 +0000
@@ -1,4 +1,4 @@
-/* $NetBSD: ld_twe.c,v 1.15 2003/09/21 19:33:10 thorpej Exp $ */
+/* $NetBSD: ld_twe.c,v 1.16 2003/09/22 18:31:10 thorpej Exp $ */
/*-
* Copyright (c) 2000, 2001, 2002, 2003 The NetBSD Foundation, Inc.
@@ -41,7 +41,7 @@
*/
#include <sys/cdefs.h>
-__KERNEL_RCSID(0, "$NetBSD: ld_twe.c,v 1.15 2003/09/21 19:33:10 thorpej Exp $");
+__KERNEL_RCSID(0, "$NetBSD: ld_twe.c,v 1.16 2003/09/22 18:31:10 thorpej Exp $");
#include "rnd.h"
@@ -72,6 +72,7 @@
};
static void ld_twe_attach(struct device *, struct device *, void *);
+static int ld_twe_detach(struct device *, int);
static int ld_twe_dobio(struct ld_twe_softc *, void *, int, int, int,
struct buf *);
static int ld_twe_dump(struct ld_softc *, void *, int, int);
@@ -79,8 +80,14 @@
static int ld_twe_match(struct device *, struct cfdata *, void *);
static int ld_twe_start(struct ld_softc *, struct buf *);
+static void ld_twe_adjqparam(struct device *, int);
+
CFATTACH_DECL(ld_twe, sizeof(struct ld_twe_softc),
- ld_twe_match, ld_twe_attach, NULL, NULL);
+ ld_twe_match, ld_twe_attach, ld_twe_detach, NULL);
+
+static const struct twe_callbacks ld_twe_callbacks = {
+ ld_twe_adjqparam,
+};
static int
ld_twe_match(struct device *parent, struct cfdata *match, void *aux)
@@ -108,12 +115,14 @@
twea = aux;
td = &twe->sc_units[twea->twea_unit];
+ twe_register_callbacks(twe, twea->twea_unit, &ld_twe_callbacks);
+
sc->sc_hwunit = twea->twea_unit;
ld->sc_flags = LDF_ENABLED;
ld->sc_maxxfer = twe_get_maxxfer(twe_get_maxsegs());
ld->sc_secperunit = td->td_size;
ld->sc_secsize = TWE_SECTOR_SIZE;
- ld->sc_maxqueuecnt = (TWE_MAX_QUEUECNT - 1) / twe->sc_nunits;
+ ld->sc_maxqueuecnt = twe->sc_openings;
ld->sc_start = ld_twe_start;
ld->sc_dump = ld_twe_dump;
@@ -156,6 +165,18 @@
}
static int
+ld_twe_detach(struct device *self, int flags)
+{
+ int rv;
+
+ if ((rv = ldbegindetach((struct ld_softc *)self, flags)) != 0)
+ return (rv);
+ ldenddetach((struct ld_softc *)self);
+
+ return (0);
+}
+
+static int
ld_twe_dobio(struct ld_twe_softc *sc, void *data, int datasize, int blkno,
int dowrite, struct buf *bp)
{
@@ -253,3 +274,10 @@
return (ld_twe_dobio((struct ld_twe_softc *)ld, data,
blkcnt * ld->sc_secsize, blkno, 1, NULL));
}
+
+static void
+ld_twe_adjqparam(struct device *self, int openings)
+{
+
+ ldadjqparam((struct ld_softc *)self, openings);
+}
diff -r feff2c522f5a -r 075a43482bc7 sys/dev/pci/twe.c
--- a/sys/dev/pci/twe.c Mon Sep 22 18:29:05 2003 +0000
+++ b/sys/dev/pci/twe.c Mon Sep 22 18:31:10 2003 +0000
@@ -1,4 +1,4 @@
-/* $NetBSD: twe.c,v 1.45 2003/09/22 01:13:02 thorpej Exp $ */
+/* $NetBSD: twe.c,v 1.46 2003/09/22 18:31:11 thorpej Exp $ */
/*-
* Copyright (c) 2000, 2001, 2002, 2003 The NetBSD Foundation, Inc.
@@ -70,7 +70,7 @@
*/
#include <sys/cdefs.h>
-__KERNEL_RCSID(0, "$NetBSD: twe.c,v 1.45 2003/09/22 01:13:02 thorpej Exp $");
+__KERNEL_RCSID(0, "$NetBSD: twe.c,v 1.46 2003/09/22 18:31:11 thorpej Exp $");
#include <sys/param.h>
#include <sys/systm.h>
@@ -115,6 +115,9 @@
static int twe_status_wait(struct twe_softc *, u_int, int);
static void twe_describe_controller(struct twe_softc *);
+static int twe_add_unit(struct twe_softc *, int);
+static int twe_del_unit(struct twe_softc *, int);
+
static inline u_int32_t twe_inl(struct twe_softc *, int);
static inline void twe_outl(struct twe_softc *, int, u_int32_t);
@@ -302,14 +305,9 @@
const char *intrstr;
int size, i, rv, rseg;
size_t max_segs, max_xfer;
- struct twe_param *dtp, *atp;
- struct twe_array_descriptor *ad;
- struct twe_drive *td;
bus_dma_segment_t seg;
struct twe_cmd *tc;
- struct twe_attach_args twea;
struct twe_ccb *ccb;
- uint16_t dsize;
sc = (struct twe_softc *)self;
pa = aux;
@@ -435,86 +433,184 @@
return;
}
+ /* Initialise connection with controller. */
+ twe_init_connection(sc);
+
+ twe_describe_controller(sc);
+
+ /* Find and attach RAID array units. */
+ sc->sc_nunits = 0;
+ for (i = 0; i < TWE_MAX_UNITS; i++)
+ (void) twe_add_unit(sc, i);
+
+ /* ...and finally, enable interrupts. */
+ twe_outl(sc, TWE_REG_CTL, TWE_CTL_CLEAR_ATTN_INTR |
+ TWE_CTL_UNMASK_RESP_INTR |
+ TWE_CTL_ENABLE_INTRS);
+}
+
+void
+twe_register_callbacks(struct twe_softc *sc, int unit,
+ const struct twe_callbacks *tcb)
+{
+
+ sc->sc_units[unit].td_callbacks = tcb;
+}
+
+static void
+twe_recompute_openings(struct twe_softc *sc)
+{
+ struct twe_drive *td;
+ int unit, openings;
+
+ if (sc->sc_nunits != 0)
+ openings = (TWE_MAX_QUEUECNT - 1) / sc->sc_nunits;
+ else
+ openings = 0;
+ if (openings == sc->sc_openings)
+ return;
+ sc->sc_openings = openings;
+
+#ifdef TWE_DEBUG
+ printf("%s: %d array%s, %d openings per array\n",
+ sc->sc_dv.dv_xname, sc->sc_nunits,
+ sc->sc_nunits == 1 ? "" : "s", sc->sc_openings);
+#endif
+
+ for (unit = 0; unit < TWE_MAX_UNITS; unit++) {
+ td = &sc->sc_units[unit];
+ if (td->td_dev != NULL)
+ (*td->td_callbacks->tcb_openings)(td->td_dev,
+ sc->sc_openings);
+ }
+}
+
+static int
+twe_add_unit(struct twe_softc *sc, int unit)
+{
+ struct twe_param *dtp, *atp;
+ struct twe_array_descriptor *ad;
+ struct twe_drive *td;
+ struct twe_attach_args twea;
+ uint32_t newsize;
+ int rv;
+ uint16_t dsize;
+ uint8_t newtype, newstripe;
+
+ if (unit < 0 || unit >= TWE_MAX_UNITS)
+ return (EINVAL);
+
/* Find attached units. */
rv = twe_param_get(sc, TWE_PARAM_UNITSUMMARY,
TWE_PARAM_UNITSUMMARY_Status, TWE_MAX_UNITS, NULL, &dtp);
if (rv != 0) {
- aprint_error("%s: can't detect attached units (%d)\n",
+ aprint_error("%s: error %d fetching unit summary\n",
sc->sc_dv.dv_xname, rv);
- return;
+ return (rv);
}
/* For each detected unit, collect size and store in an array. */
- for (i = 0, sc->sc_nunits = 0; i < TWE_MAX_UNITS; i++) {
- td = &sc->sc_units[i];
+ td = &sc->sc_units[unit];
- /* Unit present? */
- if ((dtp->tp_data[i] & TWE_PARAM_UNITSTATUS_Online) == 0) {
- td->td_size = 0;
- td->td_type = 0;
- td->td_stripe = 0;
- continue;
- }
+ /* Unit present? */
+ if ((dtp->tp_data[unit] & TWE_PARAM_UNITSTATUS_Online) == 0) {
+ /*
+ * XXX Should we check to see if a device has been
+ * XXX attached at this index and detach it if it
+ * XXX has? ("rescan" semantics)
+ */
+ rv = 0;
+ goto out;
+ }
+
+ rv = twe_param_get_2(sc, TWE_PARAM_UNITINFO + unit,
+ TWE_PARAM_UNITINFO_DescriptorSize, &dsize);
+ if (rv != 0) {
+ aprint_error("%s: error %d fetching descriptor size "
+ "for unit %d\n", sc->sc_dv.dv_xname, rv, unit);
+ goto out;
+ }
- rv = twe_param_get_2(sc, TWE_PARAM_UNITINFO + i,
- TWE_PARAM_UNITINFO_DescriptorSize, &dsize);
- if (rv != 0) {
- aprint_error("%s: error %d fetching descriptor size "
- "for unit %d\n", sc->sc_dv.dv_xname, rv, i);
- td->td_size = 0;
- td->td_type = 0;
- td->td_stripe = 0;
- continue;
- }
+ rv = twe_param_get(sc, TWE_PARAM_UNITINFO + unit,
+ TWE_PARAM_UNITINFO_Descriptor, dsize - 3, NULL, &atp);
+ if (rv != 0) {
+ aprint_error("%s: error %d fetching array descriptor "
+ "for unit %d\n", sc->sc_dv.dv_xname, rv, unit);
+ goto out;
+ }
+
+ ad = (struct twe_array_descriptor *)atp->tp_data;
+ newtype = ad->configuration;
+ newstripe = ad->stripe_size;
+ free(atp, M_DEVBUF);
+
+ rv = twe_param_get_4(sc, TWE_PARAM_UNITINFO + unit,
+ TWE_PARAM_UNITINFO_Capacity, &newsize);
+ if (rv != 0) {
+ aprint_error(
+ "%s: error %d fetching capacity for unit %d\n",
+ sc->sc_dv.dv_xname, rv, unit);
+ goto out;
+ }
- rv = twe_param_get(sc, TWE_PARAM_UNITINFO + i,
- TWE_PARAM_UNITINFO_Descriptor, dsize - 3, NULL, &atp);
- if (rv != 0) {
- aprint_error("%s: error %d fetching array descriptor "
- "for unit %d\n", sc->sc_dv.dv_xname, rv, i);
- td->td_size = 0;
- td->td_type = 0;
- td->td_stripe = 0;
- continue;
- }
- ad = (struct twe_array_descriptor *)atp->tp_data;
- td->td_type = ad->configuration;
- td->td_stripe = ad->stripe_size;
- free(atp, M_DEVBUF);
+ /*
+ * Have a device, so we need to attach it. If there is currently
+ * something sitting at the slot, and the parameters are different,
+ * then we detach the old device before attaching the new one.
+ */
+ if (td->td_dev != NULL &&
+ td->td_size == newsize &&
+ td->td_type == newtype &&
+ td->td_stripe == newstripe) {
+ /* Same as the old device; just keep using it. */
Home |
Main Index |
Thread Index |
Old Index