Module Name: src Committed By: martin Date: Sun Jan 10 13:52:06 UTC 2010
Modified Files: src/sys/arch/sparc/include: types.h src/sys/arch/sparc64/sparc64: autoconf.c Log Message: 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) To generate a diff of this commit: cvs rdiff -u -r1.51 -r1.52 src/sys/arch/sparc/include/types.h cvs rdiff -u -r1.162 -r1.163 src/sys/arch/sparc64/sparc64/autoconf.c Please note that diffs are not public domain; they are subject to the copyright notices on the relevant files.
Modified files: Index: src/sys/arch/sparc/include/types.h diff -u src/sys/arch/sparc/include/types.h:1.51 src/sys/arch/sparc/include/types.h:1.52 --- src/sys/arch/sparc/include/types.h:1.51 Fri Dec 11 05:52:04 2009 +++ src/sys/arch/sparc/include/types.h Sun Jan 10 13:52:06 2010 @@ -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) Index: src/sys/arch/sparc64/sparc64/autoconf.c diff -u src/sys/arch/sparc64/sparc64/autoconf.c:1.162 src/sys/arch/sparc64/sparc64/autoconf.c:1.163 --- src/sys/arch/sparc64/sparc64/autoconf.c:1.162 Sat Dec 5 01:11:18 2009 +++ src/sys/arch/sparc64/sparc64/autoconf.c Sun Jan 10 13:52:06 2010 @@ -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, "%...@%d,%d", prom_getpropstring(child, "name"), - target, lun); + if (wwn) + sprintf(buf, "%...@w%016" PRIx64 ",%d", name, wwn, + lun); + else + sprintf(buf, "%...@%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,q...@4/f...@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) {