Source-Changes-HG archive
[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index][Old Index]
[src/trunk]: src/sys/arch Better support for FC-AL controllers/boot disks:
details: https://anonhg.NetBSD.org/src/rev/d79879e503b7
branches: trunk
changeset: 750674:d79879e503b7
user: martin <martin%NetBSD.org@localhost>
date: Sun Jan 10 13:52:06 2010 +0000
description:
Better support for FC-AL controllers/boot disks:
- on FC-AL disks, use wwn instead of target index to match a particular drive
- use the new device_register_post_config() to match "sd" device against
the bootpath after they have gained their wwn device property
- supply firmwares notion of port and node wwn for FC controllers
as device properties (the builtin ones don't see to have a separate nvram)
diffstat:
sys/arch/sparc/include/types.h | 3 +-
sys/arch/sparc64/sparc64/autoconf.c | 91 +++++++++++++++++++++++++++++++++---
2 files changed, 85 insertions(+), 9 deletions(-)
diffs (177 lines):
diff -r 68a26e0d02e2 -r d79879e503b7 sys/arch/sparc/include/types.h
--- a/sys/arch/sparc/include/types.h Sun Jan 10 13:42:34 2010 +0000
+++ b/sys/arch/sparc/include/types.h Sun Jan 10 13:52:06 2010 +0000
@@ -1,4 +1,4 @@
-/* $NetBSD: types.h,v 1.51 2009/12/11 05:52:04 matt Exp $ */
+/* $NetBSD: types.h,v 1.52 2010/01/10 13:52:06 martin Exp $ */
/*
* Copyright (c) 1992, 1993
@@ -118,6 +118,7 @@
#define __GENERIC_SOFT_INTERRUPTS_ALL_LEVELS
#ifdef SUN4U
+#define __HAVE_DEVICE_REGISTER_POSTCONFIG
#define __HAVE_ATOMIC64_OPS
#define __HAVE_CPU_COUNTER /* sparc v9 CPUs have %tick */
#if defined(_KERNEL)
diff -r 68a26e0d02e2 -r d79879e503b7 sys/arch/sparc64/sparc64/autoconf.c
--- a/sys/arch/sparc64/sparc64/autoconf.c Sun Jan 10 13:42:34 2010 +0000
+++ b/sys/arch/sparc64/sparc64/autoconf.c Sun Jan 10 13:52:06 2010 +0000
@@ -1,4 +1,4 @@
-/* $NetBSD: autoconf.c,v 1.162 2009/12/05 01:11:18 martin Exp $ */
+/* $NetBSD: autoconf.c,v 1.163 2010/01/10 13:52:06 martin Exp $ */
/*
* Copyright (c) 1996
@@ -48,7 +48,7 @@
*/
#include <sys/cdefs.h>
-__KERNEL_RCSID(0, "$NetBSD: autoconf.c,v 1.162 2009/12/05 01:11:18 martin Exp $");
+__KERNEL_RCSID(0, "$NetBSD: autoconf.c,v 1.163 2010/01/10 13:52:06 martin Exp $");
#include "opt_ddb.h"
#include "opt_kgdb.h"
@@ -740,13 +740,15 @@
* the bootpath remainder.
*/
static void
-dev_path_drive_match(struct device *dev, int ctrlnode, int target, int lun)
+dev_path_drive_match(struct device *dev, int ctrlnode, int target,
+ uint64_t wwn, int lun)
{
int child = 0;
char buf[OFPATHLEN];
DPRINTF(ACDB_BOOTDEV, ("dev_path_drive_match: %s, controller %x, "
- "target %d lun %d\n", device_xname(dev), ctrlnode, target, lun));
+ "target %d wwn %016" PRIx64 " lun %d\n", device_xname(dev),
+ ctrlnode, target, wwn, lun));
/*
* The ofbootpackage points to a disk on this controller, so
@@ -758,15 +760,21 @@
break;
if (child == ofbootpackage) {
+ const char * name = prom_getpropstring(child, "name");
+
/* boot device is on this controller */
DPRINTF(ACDB_BOOTDEV, ("found controller of bootdevice\n"));
+
/*
* Note: "child" here is == ofbootpackage (s.a.), which
* may be completely wrong for the device we are checking,
* what we realy do here is to match "target" and "lun".
*/
- sprintf(buf, "%s@%d,%d", prom_getpropstring(child, "name"),
- target, lun);
+ if (wwn)
+ sprintf(buf, "%s@w%016" PRIx64 ",%d", name, wwn,
+ lun);
+ else
+ sprintf(buf, "%s@%d,%d", name, target, lun);
if (ofboottarget && strcmp(buf, ofboottarget) == 0) {
booted_device = dev;
if (ofbootpartition)
@@ -883,14 +891,14 @@
}
ofnode = device_ofnode(device_parent(busdev));
dev_path_drive_match(dev, ofnode, periph->periph_target + off,
- periph->periph_lun);
+ 0, periph->periph_lun);
return;
} else if (device_is_a(dev, "wd")) {
struct ata_device *adev = aux;
ofnode = device_ofnode(device_parent(busdev));
dev_path_drive_match(dev, ofnode, adev->adev_channel*2+
- adev->adev_drv_data->drive, 0);
+ adev->adev_drv_data->drive, 0, 0);
return;
}
@@ -898,8 +906,36 @@
return;
if (ofnode != 0) {
+ char devtype[32];
+ uint64_t nwwn = 0, pwwn = 0;
+ prop_dictionary_t dict;
+ prop_number_t pwwnd = NULL, nwwnd = NULL;
+
device_setofnode(dev, ofnode);
dev_path_exact_match(dev, ofnode);
+
+ /* is this a FC node? */
+ if (OF_getprop(ofnode, "device_type", devtype,
+ sizeof(devtype)) > 0 && strcmp(devtype, "scsi-fcp") == 0) {
+
+ dict = device_properties(dev);
+
+ if (OF_getprop(ofnode, "port-wwn", &pwwn, sizeof(pwwn))
+ == sizeof(pwwn)) {
+ pwwnd =
+ prop_number_create_unsigned_integer(pwwn);
+ prop_dictionary_set(dict, "port-wwn", pwwnd);
+ prop_object_release(pwwnd);
+ }
+
+ if (OF_getprop(ofnode, "node-wwn", &nwwn, sizeof(nwwn))
+ == sizeof(nwwn)) {
+ nwwnd =
+ prop_number_create_unsigned_integer(nwwn);
+ prop_dictionary_set(dict, "node-wwn", nwwnd);
+ prop_object_release(nwwnd);
+ }
+ }
}
/* set properties for PCI framebuffers */
@@ -950,6 +986,45 @@
}
}
+/*
+ * Called back after autoconfiguration of a device is done
+ */
+void
+device_register_post_config(struct device *dev, void *aux)
+{
+ if (booted_device == NULL && device_is_a(dev, "sd")) {
+ struct scsipibus_attach_args *sa = aux;
+ struct scsipi_periph *periph = sa->sa_periph;
+ uint64_t wwn = 0;
+ int ofnode;
+
+ /*
+ * If this is a FC-AL drive it will have
+ * aquired it's WWN device property by now,
+ * so we can properly match it.
+ */
+ if (prop_dictionary_get_uint64(device_properties(dev),
+ "port-wwn", &wwn)) {
+ /*
+ * Different to what we do in device_register,
+ * we do not pass the "controller" ofnode,
+ * because FC-AL devices attach below a "fp" node,
+ * E.g.: /pci/SUNW,qlc@4/fp@0,0/disk
+ * and we need the parent of "disk" here.
+ */
+ ofnode = device_ofnode(
+ device_parent(device_parent(dev)));
+ for (ofnode = OF_child(ofnode);
+ ofnode != 0 && booted_device == NULL;
+ ofnode = OF_peer(ofnode)) {
+ dev_path_drive_match(dev, ofnode,
+ periph->periph_target,
+ wwn, periph->periph_lun);
+ }
+ }
+ }
+}
+
static void
copyprops(struct device *busdev, int node, prop_dictionary_t dict)
{
Home |
Main Index |
Thread Index |
Old Index