(Forgot to attach the header/intro portion for the case..)

I am sponsoring this fast-track for James C. McPherson.
Requested release binding is patch, and the timer is set to
03/04/2008.

T.Paul
-------

Tzongyu Paul Lee ??:
> Template Version: @(#)sac_nextcase 1.64 07/13/07 SMI
> This information is Copyright 2008 Sun Microsystems
> 1. Introduction
>     1.1. Project/Component Working Name:
>        Pluggable fwflash(1M)
>     1.2. Name of Document Author/Supplier:
>        Author:  James McPherson
>     1.3  Date of This Document:
>       26 February, 2008
> 4. Technical Description
>
>
> Title
> -----
>
>
> Pluggable fwflash(1M).
>
>
>
>
>
> Problem
> -------
>
>
> PSARC/2005/126 introduced the fwflash(1M) Solaris firmware flashing
> utility, and requested that fwflash(1M) become the preferred interface for
> firmware flashing tools within Solaris. The initial release of fwflash(1M)
> was targeted at InfiniBand (IB) adapters attached via the tavor(7D)
> driver. 
>
> Sun's Systems group has requested that fwflash(1M) be extended to provide
> support for devices attached via ses(7D) - SCSI Enclosure Services. This
> fasttrack addresses that request and in the process extends fwflash(1M) to
> also provide a generic, pluggable interface for other devices for which a
> firmware update mechanism might be required in the future.
>
> Further, we separate out the firmware image verification process into a 
> separate plugin. The reason for this is that we anticipate shipping devices
> which attach to the host using the same driver, but which have different
> identification and firmware verification requires. By keeping the
> identifier separate from the verifier we enable a decrease in the sustaining
> effort over time. 
>
> Separation also allows us to make most of the new fwflash(1M) Open, and
> leave CDA- or NDA-covered knowledge required in the closed part of the
> OpenSolaris source tree. 
>
>
>
> The existing InfiniBand functionality will be re-factored to work within
> the proposed plugin framework.
>
>
>
>
>
> Binding
> -------
>
> We request a Patch binding for this RFE (6616085) since the business
> requirement is for integration into Solaris 10 Update 6.
>
>
>
> Exposure
> --------
>
> This is an Open fasttrack.
>
>
>
>
>
>
> Interfaces
> ----------
>
>
> We propose the following changes to the command line syntax of
> fwflash(1M):
>
>
> 1. Remove the "device number" option to specify a device to be
>    flashed, instead requiring the user to specify a device path.
>
>
>    The option of using a "device number" to specify a device
>    implicitly assumes that the system configuration is static
>    between invocations of fwflash(1M). This assumption is not
>    necessarily valid in a system which supports hotplug operation.
>
>    (This change in the command line options was suggested by 
>    Garrett D'Amore during pre-submission review and is one that
>    I'm more than happy to accept).
>
>
> 2. Add the ability to push multiple firmware images onto a single
>    device. If -f is the last option specified on the command line,
>    then all following arguments will be deemed to be filenames for
>    separate firmware images.
>
>    
>
>    While it is anticipated that the primary use case for multiple
>    firmware images will be in manufacturing environments on a
>    pre-release basis, it is also possible that devices such as
>    WiFi devices might also wish to use these flags. 
>
>
>
>
>
> For the plugin interface, we propose the following structures.
>
> Firstly, the verification plugin:
>
>
> struct vrfyplugin {
>
>       /*
>        * fully-qualified filename in /usr/lib/fwflash/verify,
>        * made up of [drivername]-[vendorname].so
>        *
>        * eg  /usr/lib/fwflash/verify/ses-SUN.so
>        * is the verification plugin for ses-attached devices which
>        * have a vendorname of "SUN".
>        */ 
>       char *filename;
>
>       /*
>        * The vendor name, such as "SUN" or "MELLANOX"
>        */
>       char *vendor;
>
>       /*
>        * An opaque handle for dlopen()/dlclose() to use.
>        */
>       void *handle;
>
>       /*
>        * Firmware image size in bytes, as reported by 
>        * stat().
>        */
>       unsigned int imgsize;
>
>       /*
>        * Flashable devices frequently have different buffers
>        * to use for different image types. We track the buffer
>        * required for this particular image with this variable.
>        *
>        * Once the verifier has figured out what sort of image
>        * it's been passed, it will know what value to use for
>        * this variable.
>        */
>       unsigned int flashbuf;
>
>       /*
>        * Points to the entire firmware image in memory.
>        * We do this so we can avoid multiple open()/close()
>        * operations, and to make it easier for checksum
>        * calculations.
>        */
>       int *fwimage;
>
>       /*
>        * The verification function entry point. The code
>        * in fwflash.c calls this function to verify that
>        * the nominated firmware image file is valid for
>        * the selected devicenode.
>        *
>        * Note that if the verification fails, the image
>        * does _not_ get force-flashed to the device.
>        *
>        * All verification plugins must support this operation.
>        */
>       int (*vendorvrfy)(struct devicelist *devicenode);
> };
>
>
> Verification plugins are delivered in /usr/lib/fwflash/verify.
>
> There is only one verification plugin loaded for any flash
> update operation. The verification plugin must be written so
> that it can correctly identify different levels of firmware
> for a device (eg primary, secondary, tertiary) and verify
> each individually. 
>
>
>
> In the case of the user requesting a firmware update for
> multiple images, these are verified serially, and then flashed
> to the device.
>
>
>
> To provide the common code with a means of both verifying and flashing
> the firmware, we pass that information using
>
>
> struct fwfile {
>        /*
>         * The fully qualified filename. No default location for
>       * for the firmware image file is mandated.
>       */
>       char *filename;
>
>       /* Pointer to the identification plugin required */
>       struct fw_plugin *plugin;
>
>       /* pointer to the identification summary structure */
>       struct vpr *ident;
> };
>
>
>
> The struct vpr allows us to encapsulate device information such as
> the Vendor ID, Product ID and Revision ID returned from a SCSI INQUIRY(6)
> command, and additional information such as might be required for a tavor-
> attached (IB) device.
>
> If any of the fields are space-padded at the end, then the common code
> will do the work to strip those spaces characters off the end of the string
> before making use of the data.
>
>
>
> struct vpr {
>       /* vendor ID, eg "HITACHI " */
>       char *vid;
>
>       /* product ID, eg "DK32EJ36NSUN36G " */
>       char *pid;
>
>       /* revision, eg "PQ08" */
>       char *revid;
>
>       /*
>        * Additional, encapsulated identifying information.
>        * This pointer allows us to add details such as the
>        * IB hba sector size, which command set should be
>        * used or a part number.
>        */
>       void *encap_ident;
> };
>
>
>
>
>
> For the device identification and firmware update plugin:
>
> struct fw_plugin {
>
>       /*
>        * An opaque handle for dlopen()/dlclose() to use.
>        */
>       void *handle;
>
>       /*
>        * fully-qualified filename in /usr/lib/fwflash/identify
>        * made up of [drivername].so
>        *
>        * eg  /usr/lib/fwflash/identify/ses.so
>        * is the identification plugin for devices attached to
>        * the host using the ses(7D) driver.
>        */
>       char *filename;
>
>       /*
>        * The driver name that this plugin will search for in
>        * the device tree snapshot using di_drv_first_node(3DEVINFO)
>        * and di_drv_next_node(3DEVINFO).
>        */
>       char *drvname; /* "ses" or "tavor" or .... */
>
>       /*
>        * Function entry point to support the command-line "-r"
>        * option - read image from device to persistent storage.
>        *
>        * Not all plugins and devices will support this operation.
>        */
>       int (*fw_readfw)(struct devicelist *device, char *filename);
>       
>       /*
>        * Function entry point to support the command-line "-f"
>        * option - writes from persistent storage to device
>        *
>        * All identification plugins must support this operation.
>        */
>       int (*fw_writefw)(struct devicelist *device, char *filename);
>
>
>       /*
>        * Function entry point used to build the list of valid, flashable
>        * devices attached to the system using the loadable module drvname.
>        * (Not all devices attached using drvname will be valid for this
>        * plugin to report.
>        *
>        * start allows us to display flashable devices attached with
>        * different drivers and provide the user with a visual clue
>        * that these devices are different to others that are detected.
>        * 
>        * All identification plugins must support this operation.
>        */
>       int (*fw_identify)(int start);
>
>       /*
>        * Function entry point to support the command-line "-l"
>        * option - list/report flashable devices attached to the system.
>        *
>        * All identification plugins must support this operation.
>        */     
>       int (*fw_devinfo)(struct devicelist *thisdev);
> };
>
>
> Device identification and firmware update plugins are delivered in 
> /usr/lib/fwflash/identify.
>
>
> Once the identification plugin has found an acceptable device, it
> adds a record to the global list fw_devices:
>
>
>
> struct devicelist {
>       /*
>        * fully qualified pathname, with /devices/.... prefix
>        */
>       char *access_devname;
>
>       /*
>        * Which drivername did we find this device attached with
>        * in our device tree walk? Eg, ses or tavor or sgen...
>        */
>       char *drvname;
>
>       /*
>        * What class of device is this? For tavor-attached devices,
>        * we set this to "IB". For other devices, unless there is
>        * a common name to use, just make this the same as the 
>        * drvname field.
>        */      
>       char *classname;
>
>       /* pointer to the VPR structure */
>       struct vpr *ident;
>
>       /*
>        * In the original fwflash(1M), it was possible to select a
>        * device for flashing by using an index number called a 
>        * dev_num. We retain that concept for pluggable fwflash, with
>        * the following change - whenever our identification plugin has
>        * finished and found at least one acceptable device, we bump the
>        * index number by 100. This provides the user with another key
>        * to distinguish the desired device from a potentially very large
>        * list of similar-looking devices.
>        */
>       unsigned int index;
>
>       /*
>        * Contains SAS or FC Port-WWNs, or IB GUIDS. Both SAS and FC only
>        * need one entry in this array since they really only have one
>        * address which we should track. IB devices can have 4 GUIDs
>        * (System Image, Node Image, Port 1 and Port 2).
>        */
>       char *addresses[4];
>
>       /*
>        * Pointer to the plugin needed to flash this device, and
>        * to use for printing appropriate device-specific information
>        * as required by the "-l" option to fwflash(1M).
>        */
>       struct fw_plugin *plugin;
>
>       /* Next entry in the list */
>       TAILQ_ENTRY(devicelist) nextdev;
> };
>
>
>
>
>
> As a way of assisting the common code to easily find an appropriate
> plugin, we also have a pluginlist structure:
>
>
>
> struct pluginlist {
>       /*
>        * fully qualified filename in /usr/lib/fwflash/identify
>        * made up of fwflash-[drivername].so
>        *
>        * eg  /usr/lib/fwflash/identify/ses.so
>        * is the identification plugin for devices attached to
>        * the host using the ses(7D) driver.
>        */
>       char *filename;
>
>       /*
>        * The driver name that this plugin will search for in
>        * the device tree snapshot using di_drv_first_node(3DEVINFO)
>        * and di_drv_next_node(3DEVINFO).
>        */
>       char *drvname; 
>
>       /*
>        * pointer to the actual plugin, so we can access its
>        * function entry points
>        */
>       struct fw_plugin *plugin;
>
>       /* pointer to the next element in the list */    
>       TAILQ_ENTRY(pluginlist) nextplugin;
> };
>
>
>
>
>
> We do not mandate a specific filesystem location for firmware images.
>
>
> In order for the system to add a valid flashable device to the list of 
> devices, the TAILQ family of macros from <sys/queue.h> are used. Each
> device is added to the end of the global list using TAILQ_INSERT_TAIL().
>
> Once the global list of valid devices has been built, we use the
> TAILQ_FOREACH() macro to access a specific device record, check whether
> the device matches our criteria (eg, device class, or /devices path), and
> then invoke the desired function entry point.
>
> We initialise the global variables pluginlist and devicelist as follows:
>
>
> TAILQ_HEAD(PLUGINLIST, pluginlist);
> TAILQ_HEAD(DEVICELIST, devicelist);
> struct PLUGINLIST *fw_pluginlist;
> struct DEVICELIST *fw_devices;
>
>
> The TAILQ_HEAD() macros wrap our variable structure (pluginlist, devicelist)
> and transform them into a list. See <sys/queue.h> for more details, or
> the OpenBSD manpage for QUEUE(3) at 
> http://www.openbsd.org/cgi-bin/man.cgi?query=queue&manpath=OpenBSD+Current&format=html
> (CR 6659566 has been logged requesting a Solaris manpage be delivered).
>
>
>
>
>
> Each function entry point should use the defined success or failure
> return codes of
>
> FWFLASH_SUCCESS
> FWFLASH_FAILURE
>
>
>
> Identification mechanisms
> -------------------------
>
>
> For InfiniBand devices, the identification method has not changed, it has
> merely been refactored from the existing code into the new plugin
> architecture.
>
>
> For ses(7D)-attached devices, we walk the devinfo tree (the common code
> holds the devinfo root node pointer as di_node_t rootnode) looking for
> devices attached using this driver. If we find a ses(7D) device, we query
> using a simple uscsi(7I) GET DIAGNOSTIC(6) command to see whether the
> devices supports the Download Microcode Diagnostic Control Page (0x0e).
> If the device supports that page, then we attach the device to the global
> devicelist and continue our search of the device tree. If the device
> does not support that control page then we resume our search through
> the device tree for nodes which are acceptable.
>
>
>
>
>
> Stability classifications
> -------------------------
>
>
>       /usr/lib/fwflash                Committed
>       /usr/lib/fwflash/identify       Committed
>       /usr/lib/fwflash/verify         Committed
>       
>       struct fw_plugin                Committed
>       struct vrfyplugin               Committed
>
>       struct pluginlist               Committed
>       struct vpr                      Committed
>       struct fwflash                  Committed
>       struct devicelist               Committed
>
>       FWFLASH_SUCCESS                 Committed
>       FWFLASH_FAILURE                 Committed
>
>
>
>
> Manpage changes
> ---------------
>
>
> An updated manpage reflecting the more generic nature of fwflash(1M) will
> be submitted to the case log. This will mention the as-delivered list of
> supported device identification plugins (presently IB and ses only). The
> manpage will also incorporate instructions on how to provide multiple
> firmware images as command line arguments, as well as the device specifier
> that can be passed with the -d option.
>
>
> The "-l" (list) option retains the same format as PSARC/2005/126, though
> naturally each identification plugin will have its own mandatory information.
>
> The plugin for ses(7D)-attached devices will report device information in
> the following fashion:
>
> +----------------------------------------------------------+
> | # /usr/sbin/fwflash -l                                   |
> | List of available devices:                               |
> | Device[0] /devices/pci at 7c0/pci at 0/pci at 2/scsi at 0/ses at 4,0:0  |
> |   Class [ses]                                            |
> |         Target port WWN  : 508002000031ad7d              |
> |         Vendor           : LSILOGIC                      |
> |         Product          : SASX36 A.0                    |
> |         Firmware revision: 2020                          |
> |                                                          |
> | Device[1] /devices/pci at 7c0/pci at 0/pci at 2/scsi at 0/ses at 6,0:0  |
> |   Class [ses]                                            |
> |         Target port WWN  : 50800200006f517d              |
> |         Vendor           : LSILOGIC                      |
> |         Product          : SASX28 A.0                    |
> |         Firmware revision: 2020                          |
> +----------------------------------------------------------+
>
> The above example will be added to the manpage examples section.
>
> An example of multiple image flashing will also be added to the
> manpage.
>
>
>
> References
> ----------
>
> PSARC/2005/126 InfiniBand Flash Update Tool (ibflash)
> PSARC/2002/539 Tavor IB-HCA Driver
>
>
> CR 6616085 fwflash should be generic and pluggable
>
> 6. Resources and Schedule
>     6.4. Steering Committee requested information
>       6.4.1. Consolidation C-team Name:
>               ON
>     6.5. ARC review type: FastTrack
>     6.6. ARC Exposure: open
>
>   


-- 
Tzongyu Paul Lee, Tzongyu.Lee at Sun.Com or Paul.Lee at Sun.COM
BJS05 7225, x84343
http://blogs.sun.com/tpaullee/  Feel the Pulses of China
http://tpaullee.blogspot.com/


Reply via email to