diff -purN -X /home/mbligh/.diff.exclude 350-autoswap/drivers/scsi/Kconfig 370-emulex/drivers/scsi/Kconfig --- 350-autoswap/drivers/scsi/Kconfig 2004-02-18 14:57:08.000000000 -0800 +++ 370-emulex/drivers/scsi/Kconfig 2004-02-28 11:20:03.000000000 -0800 @@ -1440,6 +1440,13 @@ config SCSI_MAC53C94 source "drivers/scsi/arm/Kconfig" +config SCSI_LPFC + tristate "Emulex LP support" + depends on PCI && SCSI + ---help--- + This driver supports the Emulex LP hardware (fibre channel + adapter cards). + config JAZZ_ESP bool "MIPS JAZZ FAS216 SCSI support" depends on MIPS_JAZZ && SCSI diff -purN -X /home/mbligh/.diff.exclude 350-autoswap/drivers/scsi/Makefile 370-emulex/drivers/scsi/Makefile --- 350-autoswap/drivers/scsi/Makefile 2004-02-18 14:57:08.000000000 -0800 +++ 370-emulex/drivers/scsi/Makefile 2004-02-28 11:20:03.000000000 -0800 @@ -116,6 +116,7 @@ obj-$(CONFIG_SCSI_SATA_SIL) += libata.o obj-$(CONFIG_SCSI_SATA_VIA) += libata.o sata_via.o obj-$(CONFIG_ARM) += arm/ +obj-$(CONFIG_SCSI_LPFC) += lpfc/ obj-$(CONFIG_CHR_DEV_ST) += st.o obj-$(CONFIG_CHR_DEV_OSST) += osst.o diff -purN -X /home/mbligh/.diff.exclude 350-autoswap/drivers/scsi/lpfc/COPYING 370-emulex/drivers/scsi/lpfc/COPYING --- 350-autoswap/drivers/scsi/lpfc/COPYING 1969-12-31 16:00:00.000000000 -0800 +++ 370-emulex/drivers/scsi/lpfc/COPYING 2004-02-28 11:20:03.000000000 -0800 @@ -0,0 +1,342 @@ + GNU GENERAL PUBLIC LICENSE + Version 2, June 1991 + + Copyright (C) 1989, 1991 Free Software Foundation, Inc. + 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA + Everyone is permitted to copy and distribute verbatim copies + of this license document, but changing it is not allowed. + + Preamble + + The licenses for most software are designed to take away your +freedom to share and change it. By contrast, the GNU General Public +License is intended to guarantee your freedom to share and change free +software--to make sure the software is free for all its users. This +General Public License applies to most of the Free Software +Foundation's software and to any other program whose authors commit to +using it. (Some other Free Software Foundation software is covered by +the GNU Library General Public License instead.) You can apply it to +your programs, too. + + When we speak of free software, we are referring to freedom, not +price. Our General Public Licenses are designed to make sure that you +have the freedom to distribute copies of free software (and charge for +this service if you wish), that you receive source code or can get it +if you want it, that you can change the software or use pieces of it +in new free programs; and that you know you can do these things. + + To protect your rights, we need to make restrictions that forbid +anyone to deny you these rights or to ask you to surrender the rights. +These restrictions translate to certain responsibilities for you if you +distribute copies of the software, or if you modify it. + + For example, if you distribute copies of such a program, whether +gratis or for a fee, you must give the recipients all the rights that +you have. You must make sure that they, too, receive or can get the +source code. And you must show them these terms so they know their +rights. + + We protect your rights with two steps: (1) copyright the software, and +(2) offer you this license which gives you legal permission to copy, +distribute and/or modify the software. + + Also, for each author's protection and ours, we want to make certain +that everyone understands that there is no warranty for this free +software. If the software is modified by someone else and passed on, we +want its recipients to know that what they have is not the original, so +that any problems introduced by others will not reflect on the original +authors' reputations. + + Finally, any free program is threatened constantly by software +patents. We wish to avoid the danger that redistributors of a free +program will individually obtain patent licenses, in effect making the +program proprietary. To prevent this, we have made it clear that any +patent must be licensed for everyone's free use or not licensed at all. + + The precise terms and conditions for copying, distribution and +modification follow. + + GNU GENERAL PUBLIC LICENSE + TERMS AND CONDITIONS FOR COPYING, DISTRIBUTION AND MODIFICATION + + 0. This License applies to any program or other work which contains +a notice placed by the copyright holder saying it may be distributed +under the terms of this General Public License. The "Program", below, +refers to any such program or work, and a "work based on the Program" +means either the Program or any derivative work under copyright law: +that is to say, a work containing the Program or a portion of it, +either verbatim or with modifications and/or translated into another +language. (Hereinafter, translation is included without limitation in +the term "modification".) Each licensee is addressed as "you". + +Activities other than copying, distribution and modification are not +covered by this License; they are outside its scope. The act of +running the Program is not restricted, and the output from the Program +is covered only if its contents constitute a work based on the +Program (independent of having been made by running the Program). +Whether that is true depends on what the Program does. + + 1. You may copy and distribute verbatim copies of the Program's +source code as you receive it, in any medium, provided that you +conspicuously and appropriately publish on each copy an appropriate +copyright notice and disclaimer of warranty; keep intact all the +notices that refer to this License and to the absence of any warranty; +and give any other recipients of the Program a copy of this License +along with the Program. + +You may charge a fee for the physical act of transferring a copy, and +you may at your option offer warranty protection in exchange for a fee. + + 2. You may modify your copy or copies of the Program or any portion +of it, thus forming a work based on the Program, and copy and +distribute such modifications or work under the terms of Section 1 +above, provided that you also meet all of these conditions: + + a) You must cause the modified files to carry prominent notices + stating that you changed the files and the date of any change. + + b) You must cause any work that you distribute or publish, that in + whole or in part contains or is derived from the Program or any + part thereof, to be licensed as a whole at no charge to all third + parties under the terms of this License. + + c) If the modified program normally reads commands interactively + when run, you must cause it, when started running for such + interactive use in the most ordinary way, to print or display an + announcement including an appropriate copyright notice and a + notice that there is no warranty (or else, saying that you provide + a warranty) and that users may redistribute the program under + these conditions, and telling the user how to view a copy of this + License. (Exception: if the Program itself is interactive but + does not normally print such an announcement, your work based on + the Program is not required to print an announcement.) + +These requirements apply to the modified work as a whole. If +identifiable sections of that work are not derived from the Program, +and can be reasonably considered independent and separate works in +themselves, then this License, and its terms, do not apply to those +sections when you distribute them as separate works. But when you +distribute the same sections as part of a whole which is a work based +on the Program, the distribution of the whole must be on the terms of +this License, whose permissions for other licensees extend to the +entire whole, and thus to each and every part regardless of who wrote it. + +Thus, it is not the intent of this section to claim rights or contest +your rights to work written entirely by you; rather, the intent is to +exercise the right to control the distribution of derivative or +collective works based on the Program. + +In addition, mere aggregation of another work not based on the Program +with the Program (or with a work based on the Program) on a volume of +a storage or distribution medium does not bring the other work under +the scope of this License. + + 3. You may copy and distribute the Program (or a work based on it, +under Section 2) in object code or executable form under the terms of +Sections 1 and 2 above provided that you also do one of the following: + + a) Accompany it with the complete corresponding machine-readable + source code, which must be distributed under the terms of Sections + 1 and 2 above on a medium customarily used for software interchange; or, + + b) Accompany it with a written offer, valid for at least three + years, to give any third party, for a charge no more than your + cost of physically performing source distribution, a complete + machine-readable copy of the corresponding source code, to be + distributed under the terms of Sections 1 and 2 above on a medium + customarily used for software interchange; or, + + c) Accompany it with the information you received as to the offer + to distribute corresponding source code. (This alternative is + allowed only for noncommercial distribution and only if you + received the program in object code or executable form with such + an offer, in accord with Subsection b above.) + +The source code for a work means the preferred form of the work for +making modifications to it. For an executable work, complete source +code means all the source code for all modules it contains, plus any +associated interface definition files, plus the scripts used to +control compilation and installation of the executable. However, as a +special exception, the source code distributed need not include +anything that is normally distributed (in either source or binary +form) with the major components (compiler, kernel, and so on) of the +operating system on which the executable runs, unless that component +itself accompanies the executable. + +If distribution of executable or object code is made by offering +access to copy from a designated place, then offering equivalent +access to copy the source code from the same place counts as +distribution of the source code, even though third parties are not +compelled to copy the source along with the object code. + + 4. You may not copy, modify, sublicense, or distribute the Program +except as expressly provided under this License. Any attempt +otherwise to copy, modify, sublicense or distribute the Program is +void, and will automatically terminate your rights under this License. +However, parties who have received copies, or rights, from you under +this License will not have their licenses terminated so long as such +parties remain in full compliance. + + 5. You are not required to accept this License, since you have not +signed it. However, nothing else grants you permission to modify or +distribute the Program or its derivative works. These actions are +prohibited by law if you do not accept this License. Therefore, by +modifying or distributing the Program (or any work based on the +Program), you indicate your acceptance of this License to do so, and +all its terms and conditions for copying, distributing or modifying +the Program or works based on it. + + 6. Each time you redistribute the Program (or any work based on the +Program), the recipient automatically receives a license from the +original licensor to copy, distribute or modify the Program subject to +these terms and conditions. You may not impose any further +restrictions on the recipients' exercise of the rights granted herein. +You are not responsible for enforcing compliance by third parties to +this License. + + 7. If, as a consequence of a court judgment or allegation of patent +infringement or for any other reason (not limited to patent issues), +conditions are imposed on you (whether by court order, agreement or +otherwise) that contradict the conditions of this License, they do not +excuse you from the conditions of this License. If you cannot +distribute so as to satisfy simultaneously your obligations under this +License and any other pertinent obligations, then as a consequence you +may not distribute the Program at all. For example, if a patent +license would not permit royalty-free redistribution of the Program by +all those who receive copies directly or indirectly through you, then +the only way you could satisfy both it and this License would be to +refrain entirely from distribution of the Program. + +If any portion of this section is held invalid or unenforceable under +any particular circumstance, the balance of the section is intended to +apply and the section as a whole is intended to apply in other +circumstances. + +It is not the purpose of this section to induce you to infringe any +patents or other property right claims or to contest validity of any +such claims; this section has the sole purpose of protecting the +integrity of the free software distribution system, which is +implemented by public license practices. Many people have made +generous contributions to the wide range of software distributed +through that system in reliance on consistent application of that +system; it is up to the author/donor to decide if he or she is willing +to distribute software through any other system and a licensee cannot +impose that choice. + +This section is intended to make thoroughly clear what is believed to +be a consequence of the rest of this License. + + 8. If the distribution and/or use of the Program is restricted in +certain countries either by patents or by copyrighted interfaces, the +original copyright holder who places the Program under this License +may add an explicit geographical distribution limitation excluding +those countries, so that distribution is permitted only in or among +countries not thus excluded. In such case, this License incorporates +the limitation as if written in the body of this License. + + 9. The Free Software Foundation may publish revised and/or new versions +of the General Public License from time to time. Such new versions will +be similar in spirit to the present version, but may differ in detail to +address new problems or concerns. + +Each version is given a distinguishing version number. If the Program +specifies a version number of this License which applies to it and "any +later version", you have the option of following the terms and conditions +either of that version or of any later version published by the Free +Software Foundation. If the Program does not specify a version number of +this License, you may choose any version ever published by the Free Software +Foundation. + + 10. If you wish to incorporate parts of the Program into other free +programs whose distribution conditions are different, write to the author +to ask for permission. For software which is copyrighted by the Free +Software Foundation, write to the Free Software Foundation; we sometimes +make exceptions for this. Our decision will be guided by the two goals +of preserving the free status of all derivatives of our free software and +of promoting the sharing and reuse of software generally. + + NO WARRANTY + + 11. BECAUSE THE PROGRAM IS LICENSED FREE OF CHARGE, THERE IS NO WARRANTY +FOR THE PROGRAM, TO THE EXTENT PERMITTED BY APPLICABLE LAW. EXCEPT WHEN +OTHERWISE STATED IN WRITING THE COPYRIGHT HOLDERS AND/OR OTHER PARTIES +PROVIDE THE PROGRAM "AS IS" WITHOUT WARRANTY OF ANY KIND, EITHER EXPRESSED +OR IMPLIED, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF +MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE. THE ENTIRE RISK AS +TO THE QUALITY AND PERFORMANCE OF THE PROGRAM IS WITH YOU. SHOULD THE +PROGRAM PROVE DEFECTIVE, YOU ASSUME THE COST OF ALL NECESSARY SERVICING, +REPAIR OR CORRECTION. + + 12. IN NO EVENT UNLESS REQUIRED BY APPLICABLE LAW OR AGREED TO IN WRITING +WILL ANY COPYRIGHT HOLDER, OR ANY OTHER PARTY WHO MAY MODIFY AND/OR +REDISTRIBUTE THE PROGRAM AS PERMITTED ABOVE, BE LIABLE TO YOU FOR DAMAGES, +INCLUDING ANY GENERAL, SPECIAL, INCIDENTAL OR CONSEQUENTIAL DAMAGES ARISING +OUT OF THE USE OR INABILITY TO USE THE PROGRAM (INCLUDING BUT NOT LIMITED +TO LOSS OF DATA OR DATA BEING RENDERED INACCURATE OR LOSSES SUSTAINED BY +YOU OR THIRD PARTIES OR A FAILURE OF THE PROGRAM TO OPERATE WITH ANY OTHER +PROGRAMS), EVEN IF SUCH HOLDER OR OTHER PARTY HAS BEEN ADVISED OF THE +POSSIBILITY OF SUCH DAMAGES. + + END OF TERMS AND CONDITIONS + + How to Apply These Terms to Your New Programs + + If you develop a new program, and you want it to be of the greatest +possible use to the public, the best way to achieve this is to make it +free software which everyone can redistribute and change under these terms. + + To do so, attach the following notices to the program. It is safest +to attach them to the start of each source file to most effectively +convey the exclusion of warranty; and each file should have at least +the "copyright" line and a pointer to where the full notice is found. + + + Copyright (C) + + This program is free software; you can redistribute it and/or modify + it under the terms of the GNU General Public License as published by + the Free Software Foundation; either version 2 of the License, or + (at your option) any later version. + + This program is distributed in the hope that it will be useful, + but WITHOUT ANY WARRANTY; without even the implied warranty of + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + GNU General Public License for more details. + + You should have received a copy of the GNU General Public License + along with this program; if not, write to the Free Software + Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA + + +Also add information on how to contact you by electronic and paper mail. + +If the program is interactive, make it output a short notice like this +when it starts in an interactive mode: + + Gnomovision version 69, Copyright (C) year name of author + Gnomovision comes with ABSOLUTELY NO WARRANTY; for details type `show w'. + This is free software, and you are welcome to redistribute it + under certain conditions; type `show c' for details. + +The hypothetical commands `show w' and `show c' should show the appropriate +parts of the General Public License. Of course, the commands you use may +be called something other than `show w' and `show c'; they could even be +mouse-clicks or menu items--whatever suits your program. + +You should also get your employer (if you work as a programmer) or your +school, if any, to sign a "copyright disclaimer" for the program, if +necessary. Here is a sample; alter the names: + + Yoyodyne, Inc., hereby disclaims all copyright interest in the program + `Gnomovision' (which makes passes at compilers) written by James Hacker. + + , 1 April 1989 + Ty Coon, President of Vice + +This General Public License does not permit incorporating your program into +proprietary programs. If your program is a subroutine library, you may +consider it more useful to permit linking proprietary applications with the +library. If this is what you want to do, use the GNU Library General +Public License instead of this License. + + diff -purN -X /home/mbligh/.diff.exclude 350-autoswap/drivers/scsi/lpfc/Makefile 370-emulex/drivers/scsi/lpfc/Makefile --- 350-autoswap/drivers/scsi/lpfc/Makefile 1969-12-31 16:00:00.000000000 -0800 +++ 370-emulex/drivers/scsi/lpfc/Makefile 2004-02-28 11:20:03.000000000 -0800 @@ -0,0 +1,6 @@ +obj-$(CONFIG_SCSI_LPFC) += lpfcdd.o + +EXTRA_CFLAGS += -DLP6000 -D_LINUX -Idrivers/scsi + +lpfcdd-objs := fcscsib.o fcmboxb.o fcmemb.o fcelsb.o fcstratb.o \ + fcxmitb.o fcrpib.o fcclockb.o fcLINUXfcp.o lpfc.conf.o diff -purN -X /home/mbligh/.diff.exclude 350-autoswap/drivers/scsi/lpfc/README 370-emulex/drivers/scsi/lpfc/README --- 350-autoswap/drivers/scsi/lpfc/README 1969-12-31 16:00:00.000000000 -0800 +++ 370-emulex/drivers/scsi/lpfc/README 2004-02-28 11:20:03.000000000 -0800 @@ -0,0 +1,43 @@ +************************************************************************ +Emulex Corporation + +README for the Driver kit 1.23a for Emulex Fibre Channel Host Adapters + +September 12, 2003 +************************************************************************ + +This Application kit has been designed for the following environment: + +- Supported Hardware architecture platforms: + - 32-bit Intel platforms (IA-32) + - 64-bit Intel platforms (IA-64) + - Power PC 64 bits (PPC) + +- Supported Linux OS (note that testing has been conducted only with the kernels in parenthesis): + - Red Hat Pro 7.3 (kernel 2.4.18-27) + - Red Hat Pro 8.0 (kernel 2.4.18-27) + - Red Hat Advanced Server 2.1 x86 (kernel 2.4.9-e.16) + - SLES 7 x86 (kernel 2.4.16) + - SLES 8 x86 (kernel 2.4.19) + - Red Hat Advanced Server 2.1 IA-64 (kernel 2.4.18-e.25) + - SuSE 8.0 ppc64 (kernel 2.4.19-u11-ppc64) + +- Supported Emulex enterprise adapters: + - LP8000 + - LP9000 + - LP9002L + - LP9002DC + - LP9402DC + - LP9802 + - LP10000 + - LP9802 + - LP10000 + +- This driver supports any mix of the above Emulex adapters within a single host system. + +Main driver features: +1. Full fabric support, discovery, FCP and fibre channel device/error and exception handling +2. Concurrent multi-protocol (FCP and IP) support +3. Supports INT13 (EDD 2.1/3.0) fabric boot. +4. This driver is entirely self-contained and intended for configuration using lpfc. No external utility is required or supported. +5. This driver will not be dependent on any non-open source program for its execution. It will not taint an open source kernel. diff -purN -X /home/mbligh/.diff.exclude 350-autoswap/drivers/scsi/lpfc/dfc.h 370-emulex/drivers/scsi/lpfc/dfc.h --- 350-autoswap/drivers/scsi/lpfc/dfc.h 1969-12-31 16:00:00.000000000 -0800 +++ 370-emulex/drivers/scsi/lpfc/dfc.h 2004-02-28 11:20:03.000000000 -0800 @@ -0,0 +1,199 @@ +/******************************************************************* + * This file is part of the Emulex Linux Device Driver for * + * Enterprise Fibre Channel Host Bus Adapters. * + * Refer to the README file included with this package for * + * driver version and adapter support. * + * Copyright (C) 2003 Emulex Corporation. * + * www.emulex.com * + * * + * This program is free software; you can redistribute it and/or * + * modify it under the terms of the GNU General Public License * + * as published by the Free Software Foundation; either version 2 * + * of the License, or (at your option) any later version. * + * * + * This program is distributed in the hope that it will be useful, * + * but WITHOUT ANY WARRANTY; without even the implied warranty of * + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * + * GNU General Public License for more details, a copy of which * + * can be found in the file COPYING included with this package. * + *******************************************************************/ +#if !defined(_KERNEL) && !defined(__KERNEL__) +#endif + + +#define _DFC_64BIT 1 + +#ifdef BITS_PER_LONG +#if BITS_PER_LONG < 64 +#undef _DFC_64BIT +#endif +#endif + +#ifdef i386 +#undef _DFC_64BIT +#endif + +#ifdef powerpc +#ifndef CONFIG_PPC64 +#undef _DFC_64BIT +#endif +#endif + + +struct dfccmdinfo { +#ifdef _DFC_64BIT + char *c_datain; + char *c_dataout; + unsigned short c_cmd; + unsigned short c_insz; + uint32 c_outsz; +#else + void *c_filler1; + char *c_datain; + void *c_filler2; + char *c_dataout; + unsigned short c_cmd; + unsigned short c_insz; + uint32 c_outsz; +#endif +}; + +struct cmd_input { +#ifdef _DFC_64BIT + short c_brd; + short c_ring; + short c_iocb; + short c_flag; + void *c_arg1; + void *c_arg2; + void *c_arg3; + char c_string[16]; +#else + short c_brd; + short c_ring; + short c_iocb; + short c_flag; + void *c_filler1; + void *c_arg1; + void *c_filler2; + void *c_arg2; + void *c_filler3; + void *c_arg3; + char c_string[16]; +#endif +}; + + + +struct cmdinfo { + int c_cmd; + char *c_string; + int (*c_routine)(struct cmdinfo *cp, void *p); + char *c_datain; + char *c_dataout; + unsigned short c_insz; + unsigned short c_outsz; +}; + +#define C_INVAL 0x0 +#define C_DISPLAY_PCI_ALL 0x1 +#define C_WRITE_PCI 0x2 +#define C_WRITE_HC 0x3 +#define C_WRITE_HS 0x4 +#define C_WRITE_HA 0x5 +#define C_WRITE_CA 0x6 +#define C_READ_PCI 0x7 +#define C_READ_HC 0x8 +#define C_READ_HS 0x9 +#define C_READ_HA 0xa +#define C_READ_CA 0xb +#define C_READ_MB 0xc +#define C_EXIT 0xd +#define C_SET 0xe +#define C_READ_RING 0xf +#define C_READ_MEM 0x10 +#define C_READ_IOCB 0x11 +#define C_READ_RPILIST 0x12 +#define C_READ_BPLIST 0x13 +#define C_READ_MEMSEG 0x14 +#define C_MBOX 0x15 +#define C_RESET 0x16 +#define C_READ_BINFO 0x17 +#define C_NDD_STAT 0x18 +#define C_FC_STAT 0x19 +#define C_WRITE_MEM 0x1a +#define C_WRITE_CTLREG 0x1b +#define C_READ_CTLREG 0x1c +#define C_INITBRDS 0x1d +#define C_SETDIAG 0x1e +#define C_DBG 0x1f +#define C_GET_PHYSADDR 0x20 +#define C_PUT_PHYSADDR 0x21 +#define C_NODE 0x22 +#define C_DEVP 0x23 +#define C_INST 0x24 +#define C_LIP 0x25 +#define C_LINKINFO 0x26 +#define C_IOINFO 0x27 +#define C_NODEINFO 0x28 +#define C_GETCFG 0x29 +#define C_SETCFG 0x2a +#define C_FAILIO 0x2b +#define C_OUTFCPIO 0x2c +#define C_RSTQDEPTH 0x2d +#define C_CT 0x2e +#define C_HBA_ADAPTERATRIBUTES 0x33 +#define C_HBA_PORTATRIBUTES 0x34 +#define C_HBA_PORTSTATISTICS 0x35 +#define C_HBA_DISCPORTATRIBUTES 0x36 +#define C_HBA_WWPNPORTATRIBUTES 0x37 +#define C_HBA_INDEXPORTATRIBUTES 0x38 +#define C_HBA_FCPTARGETMAPPING 0x39 +#define C_HBA_FCPBINDING 0x3a +#define C_HBA_SETMGMTINFO 0x3b +#define C_HBA_GETMGMTINFO 0x3c +#define C_HBA_RNID 0x3d +#define C_HBA_GETEVENT 0x3e +#define C_HBA_RESETSTAT 0x3f +#define C_HBA_SEND_SCSI 0x40 +#define C_HBA_REFRESHINFO 0x41 +#define C_SEND_ELS 0x42 +#define C_LISTN 0x45 +#define C_TRACE 0x46 +#define C_HELP 0x47 +#define C_HBA_SEND_FCP 0x48 +#define C_SET_EVENT 0x49 +#define C_GET_EVENT 0x4a +#define C_SEND_MGMT_CMD 0x4b +#define C_SEND_MGMT_RSP 0x4c +#define C_LISTEVT 0x59 +#define C_MAX_CMDS 0x5a + +#define DFC_MBX_MAX_CMDS 29 + +/* Structure for OUTFCPIO command */ +struct out_fcp_io { + ushort tx_count; + ushort txp_count; + ushort timeout_count; + ushort devp_count; + void * tx_head; + void * tx_tail; + void * txp_head; + void * txp_tail; + void * timeout_head; +}; + +struct out_fcp_devp { + ushort target; + ushort lun; + uint32 standby_count; + uint32 pend_count; + uint32 clear_count; + void *standby_queue_head; + void *standby_queue_tail; + void *pend_head; + void *pend_tail; + void *clear_head; +}; + diff -purN -X /home/mbligh/.diff.exclude 350-autoswap/drivers/scsi/lpfc/dfcdd.c 370-emulex/drivers/scsi/lpfc/dfcdd.c --- 350-autoswap/drivers/scsi/lpfc/dfcdd.c 1969-12-31 16:00:00.000000000 -0800 +++ 370-emulex/drivers/scsi/lpfc/dfcdd.c 2004-02-28 11:20:03.000000000 -0800 @@ -0,0 +1,4595 @@ + +/******************************************************************* + * This file is part of the Emulex Linux Device Driver for * + * Enterprise Fibre Channel Host Bus Adapters. * + * Refer to the README file included with this package for * + * driver version and adapter support. * + * Copyright (C) 2003 Emulex Corporation. * + * www.emulex.com * + * * + * This program is free software; you can redistribute it and/or * + * modify it under the terms of the GNU General Public License * + * as published by the Free Software Foundation; either version 2 * + * of the License, or (at your option) any later version. * + * * + * This program is distributed in the hope that it will be useful, * + * but WITHOUT ANY WARRANTY; without even the implied warranty of * + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * + * GNU General Public License for more details, a copy of which * + * can be found in the file COPYING included with this package. * + *******************************************************************/ + +#include "dfc.h" + +/*************************************************************************/ +/* Global data structures */ +/*************************************************************************/ + + int rc = 0; + int do_cp = 0; + +#ifdef DFC_SUBSYSTEM + +struct dfc { + uint32 dfc_init; + uint32 dfc_pad; + uchar dfc_buffer[4096]; + struct dfc_info dfc_info[MAX_FC_BRDS]; +}; + +_static_ struct dfc dfc; + +struct dfc_mem { + uint32 fc_outsz; + uint32 fc_filler; + void * fc_dataout; +}; + +extern uint32 fc_dbg_flag; +uint32 fc_out_event = 4; + +/* Routine Declaration - Local */ +_local_ fc_dev_ctl_t * dfc_getpdev(struct cmd_input *ci); +_local_ int dfc_msdelay(fc_dev_ctl_t *p, ulong ms); +_local_ int dfc_issue_mbox( fc_dev_ctl_t *p, MAILBOX * mb, ulong *ipri); +_local_ DMATCHMAP * dfc_cmd_data_alloc(fc_dev_ctl_t *p, uchar *inp, ULP_BDE64 *bpl, uint32 size); +_local_ int dfc_cmd_data_free(fc_dev_ctl_t *p, DMATCHMAP *mlist); +_local_ int dfc_rsp_data_copy(fc_dev_ctl_t *p, uchar * op, DMATCHMAP *mlist, uint32 size); +_local_ DMATCHMAP * dfc_fcp_data_alloc(fc_dev_ctl_t *p, ULP_BDE64 *bpl); +_local_ int dfc_fcp_data_free(fc_dev_ctl_t *p, DMATCHMAP *fcpmp); +_forward_ int dfc_data_alloc(fc_dev_ctl_t * p_dev_ctl, struct dfc_mem *dm, uint32 size); +_forward_ int dfc_hba_rnid(fc_dev_ctl_t * p_dev_ctl, struct dfc_mem *dm, struct cmd_input *cip, struct dfccmdinfo *infop, MBUF_INFO *buf_info, ulong ipri); +_forward_ int dfc_hba_sendmgmt_ct(fc_dev_ctl_t * p_dev_ctl, struct dfc_mem *dm, struct cmd_input *cip, struct dfccmdinfo *infop, ulong ipri); +_forward_ int dfc_hba_fcpbind(fc_dev_ctl_t * p_dev_ctl, struct dfc_mem *dm, struct cmd_input *cip, struct dfccmdinfo *infop, ulong ipri); +_forward_ int dfc_hba_targetmapping(fc_dev_ctl_t * p_dev_ctl, struct dfc_mem *dm, struct cmd_input *cip, struct dfccmdinfo *infop, ulong ipri); +_forward_ int dfc_hba_sendscsi_fcp(fc_dev_ctl_t * p_dev_ctl, struct dfc_mem *dm, struct cmd_input *cip, struct dfccmdinfo *infop, ulong ipri); +_forward_ int dfc_hba_set_event(fc_dev_ctl_t * p_dev_ctl, struct dfc_mem *dm, struct cmd_input *cip, struct dfccmdinfo *infop, ulong ipri); +_forward_ int dfc_data_free(fc_dev_ctl_t * p_dev_ctl, struct dfc_mem *dm); +_forward_ uint32 dfc_getLunId(node_t *nodep, uint32 lunIndex); +/* End Routine Declaration - Local */ + +/*****************************************************************************/ +/* + * NAME: dfc_ioctl + * + * FUNCTION: diagnostic ioctl interface + * + * EXECUTION ENVIRONMENT: process only + * + * NOTES: + * + * CALLED FROM: + * dfc_config + * + * RETURNS: + * 0 - successful + * EINVAL - invalid parameter was passed + * + */ +/*****************************************************************************/ +_static_ int +dfc_ioctl( +struct dfccmdinfo *infop, +struct cmd_input *cip) +{ + uint32 outshift; + int i, j; /* loop index */ + ulong ipri; + int max; + FC_BRD_INFO * binfo; + uint32 * lptr; + MBUF_INFO * buf_info; + MBUF_INFO * dmdata_info; + MBUF_INFO * mbox_info; + uchar * bp; + uint32 incr; + uint32 size; + uint32 buf1sz; + int total_mem; + uint32 offset; + uint32 cnt; + NODELIST * nlp; + node_t * nodep; + dvi_t * dev_ptr; + void * ioa; + fc_dev_ctl_t * p_dev_ctl; + iCfgParam * clp; + RING * rp; + MAILBOX * mb; + MATCHMAP * mm; + node_t * node_ptr; + fcipbuf_t * fbp; + struct out_fcp_io * fp; + struct out_fcp_devp * dp; + struct dfc_info * di; + struct dfc_mem * dm; + HBA_PORTATTRIBUTES * hp; + fc_vpd_t * vp; + MAILBOX * mbox; + MBUF_INFO bufinfo; + + if ((p_dev_ctl = dfc_getpdev(cip)) == 0) { + return(EINVAL); + } + + binfo = &BINFO; + cnt = binfo->fc_brd_no; + clp = DD_CTL.p_config[cnt]; + di = &dfc.dfc_info[cip->c_brd]; + buf_info = &bufinfo; + + dmdata_info = &bufinfo; + dmdata_info->virt = 0; + dmdata_info->phys = 0; + dmdata_info->flags = (FC_MBUF_IOCTL | FC_MBUF_UNLOCK); + dmdata_info->align = sizeof(void *); + dmdata_info->size = sizeof(* dm); + dmdata_info->dma_handle = 0; + fc_malloc(p_dev_ctl, dmdata_info); + if (buf_info->virt == NULL) { + return (ENOMEM); + } + dm = (struct dfc_mem *)dmdata_info->virt; + fc_bzero((void *)dm, sizeof(struct dfc_mem)); + + mbox_info = &bufinfo; + mbox_info->virt = 0; + mbox_info->phys = 0; + mbox_info->flags = (FC_MBUF_IOCTL | FC_MBUF_UNLOCK); + mbox_info->align = sizeof(void *); + mbox_info->size = sizeof(* mbox); + mbox_info->dma_handle = 0; + fc_malloc(p_dev_ctl, mbox_info); + if (mbox_info->virt == NULL) { + return (ENOMEM); + } + mbox = (MAILBOX *)mbox_info->virt; + + + /* dfc_ioctl entry */ + + fc_log_printf_msg_vargs( binfo->fc_brd_no, + &fc_msgBlk0400, /* ptr to msg structure */ + fc_mes0400, /* ptr to msg */ + fc_msgBlk0400.msgPreambleStr, /* begin varargs */ + infop->c_cmd, + (uint32)((ulong)cip->c_arg1), + (uint32)((ulong)cip->c_arg2), + infop->c_outsz); /* end varargs */ + + outshift = 0; + if(infop->c_outsz) { + if(infop->c_outsz <= (64 * 1024)) + total_mem = infop->c_outsz; + else + total_mem = 64 * 1024; + if(dfc_data_alloc(p_dev_ctl, dm, total_mem)) { + return(ENOMEM); + } + } + else { + /* Allocate memory for ioctl data */ + if(dfc_data_alloc(p_dev_ctl, dm, 4096)) { + return(ENOMEM); + } + total_mem = 4096; + } + + /* Make sure driver instance is attached */ + if(p_dev_ctl != DD_CTL.p_dev[cnt]) { + return(ENODEV); + } + ipri = dfc_disable_lock(FC_LVL, &CMD_LOCK); + di->fc_refcnt++; + + + switch (infop->c_cmd) { + /* Diagnostic Interface Library Support */ + + case C_WRITE_PCI: + offset = (uint32)((ulong)cip->c_arg1); + if (!(binfo->fc_flag & FC_OFFLINE_MODE)) { + rc = EPERM; + break; + } + if (offset > 255) { + rc = ERANGE; + break; + } + cnt = (uint32)((ulong)cip->c_arg2); + if ((cnt + offset) > 256) { + rc = ERANGE; + break; + } + + dfc_unlock_enable(ipri, &CMD_LOCK); + if (fc_copyin((uchar *)infop->c_dataout, (uchar *)dfc.dfc_buffer, (ulong)cnt)) { + ipri = dfc_disable_lock(FC_LVL, &CMD_LOCK); + rc = EIO; + break; + } + ipri = dfc_disable_lock(FC_LVL, &CMD_LOCK); + rc = fc_writepci(di, offset, (char *)dfc.dfc_buffer, (cnt >> 2)); + break; + + case C_READ_PCI: + offset = (uint32)((ulong)cip->c_arg1); + if (offset > 255) { + rc = ERANGE; + break; + } + cnt = (uint32)((ulong)cip->c_arg2); + if ((cnt + offset) > 256) { + rc = ERANGE; + break; + } + rc = fc_readpci(di, offset, (char *)dm->fc_dataout, (cnt >> 2)); + break; + + case C_WRITE_MEM: + offset = (uint32)((ulong)cip->c_arg1); + if (!(binfo->fc_flag & FC_OFFLINE_MODE)) { + if (offset != 256) { + rc = EPERM; + break; + } + if (cnt > 128) { + rc = EPERM; + break; + } + } + if (offset >= 4096) { + rc = ERANGE; + break; + } + cnt = (uint32)((ulong)cip->c_arg2); + if ((cnt + offset) > 4096) { + rc = ERANGE; + break; + } + + dfc_unlock_enable(ipri, &CMD_LOCK); + if (fc_copyin((uchar *)infop->c_dataout, (uchar *)dfc.dfc_buffer, (ulong)cnt)) { + ipri = dfc_disable_lock(FC_LVL, &CMD_LOCK); + rc = EIO; + break; + } + ipri = dfc_disable_lock(FC_LVL, &CMD_LOCK); + + binfo = &BINFO; + if ((binfo->fc_flag & FC_SLI2) && (!(binfo->fc_flag & FC_OFFLINE_MODE))) { + fc_pcimem_bcopy((uint32 * )dfc.dfc_buffer, + (uint32 * )(((char *)(binfo->fc_slim2.virt)) + offset), cnt); + } else { + ioa = (void *)FC_MAP_MEM(&di->fc_iomap_mem); /* map in slim */ + WRITE_SLIM_COPY(binfo, (uint32 * )dfc.dfc_buffer, + (volatile uint32 * )((volatile char *)ioa + offset), + (cnt / sizeof(uint32))); + FC_UNMAP_MEMIO(ioa); + } + + break; + + case C_READ_MEM: + offset = (uint32)((ulong)cip->c_arg1); + if (offset >= 4096) { + rc = ERANGE; + break; + } + cnt = (uint32)((ulong)cip->c_arg2); + if ((cnt + offset) > 4096) { + rc = ERANGE; + break; + } + + binfo = &BINFO; + if ((binfo->fc_flag & FC_SLI2) && (!(binfo->fc_flag & FC_OFFLINE_MODE))) { + fc_pcimem_bcopy((uint32 * )(((char *)(binfo->fc_slim2.virt)) + offset), + (uint32 * )dm->fc_dataout, cnt); + } else { + ioa = (void *)FC_MAP_MEM(&di->fc_iomap_mem); /* map in slim */ + READ_SLIM_COPY(binfo, (uint32 * )dm->fc_dataout, + (volatile uint32 * )((volatile char *)ioa + offset), + (cnt / sizeof(uint32))); + FC_UNMAP_MEMIO(ioa); + } + break; + + case C_WRITE_CTLREG: + offset = (uint32)((ulong)cip->c_arg1); + if (!(binfo->fc_flag & FC_OFFLINE_MODE)) { + rc = EPERM; + break; + } + if (offset > 255) { + rc = ERANGE; + break; + } + incr = (uint32)((ulong)cip->c_arg2); + ioa = (void *)FC_MAP_IO(&di->fc_iomap_io); /* map in io registers */ + WRITE_CSR_REG(binfo, + ((volatile uint32 * )((volatile char *)ioa + (offset))), incr); + FC_UNMAP_MEMIO(ioa); + + break; + + case C_READ_CTLREG: + offset = (uint32)((ulong)cip->c_arg1); + if (offset > 255) { + rc = ERANGE; + break; + } + ioa = (void *)FC_MAP_IO(&di->fc_iomap_io); /* map in io registers */ + incr = READ_CSR_REG(binfo, + ((volatile uint32 * )((volatile char *)ioa + (offset)))); + FC_UNMAP_MEMIO(ioa); + *((uint32 * )dm->fc_dataout) = incr; + break; + + case C_INITBRDS: + dfc_unlock_enable(ipri, &CMD_LOCK); + if (fc_copyin((uchar*)infop->c_dataout, (uchar*)&di->fc_ba, sizeof(brdinfo))) { + ipri = dfc_disable_lock(FC_LVL, &CMD_LOCK); + rc = EIO; + break; + } + ipri = dfc_disable_lock(FC_LVL, &CMD_LOCK); + + if (fc_initpci(di, p_dev_ctl)) { + rc = EIO; + break; + } + if (binfo->fc_flag & FC_OFFLINE_MODE) + di->fc_ba.a_offmask |= OFFDI_OFFLINE; + + fc_bcopy((uchar * ) & di->fc_ba, dm->fc_dataout, sizeof(brdinfo)); + infop->c_outsz = sizeof(brdinfo); + break; + + case C_SETDIAG: + dfc_unlock_enable(ipri, &CMD_LOCK); + offset = (uint32)((ulong)cip->c_arg1); + switch (offset) { + case DDI_ONDI: + if (fc_diag_state == DDI_OFFDI) { + fc_online(0); + } + *((uint32 * )(dm->fc_dataout)) = fc_diag_state; + break; + case DDI_OFFDI: + if (fc_diag_state == DDI_ONDI) { + fc_offline(0); + } + *((uint32 * )(dm->fc_dataout)) = fc_diag_state; + break; + case DDI_SHOW: + *((uint32 * )(dm->fc_dataout)) = fc_diag_state; + break; + case DDI_BRD_ONDI: + if (binfo->fc_flag & FC_OFFLINE_MODE) { + fc_online(p_dev_ctl); + } + *((uint32 * )(dm->fc_dataout)) = DDI_ONDI; + break; + case DDI_BRD_OFFDI: + if (!(binfo->fc_flag & FC_OFFLINE_MODE)) { + fc_offline(p_dev_ctl); + } + *((uint32 * )(dm->fc_dataout)) = DDI_OFFDI; + break; + case DDI_BRD_SHOW: + if (binfo->fc_flag & FC_OFFLINE_MODE) { + *((uint32 * )(dm->fc_dataout)) = DDI_OFFDI; + } + else { + *((uint32 * )(dm->fc_dataout)) = DDI_ONDI; + } + break; + default: + rc = ERANGE; + break; + } + ipri = dfc_disable_lock(FC_LVL, &CMD_LOCK); + break; + + case C_LIP: + binfo = &BINFO; + mb = (MAILBOX * )mbox; + fc_bzero((void *)mb, sizeof(MAILBOX)); + + if ((binfo->fc_ffstate == FC_READY) && (binfo->fc_process_LA)) { + /* Turn off link attentions */ + binfo->fc_process_LA = 0; + ioa = (void *)FC_MAP_IO(&binfo->fc_iomap_io); /* map in io registers */ + offset = READ_CSR_REG(binfo, FC_HC_REG(binfo, ioa)); + offset &= ~HC_LAINT_ENA; + WRITE_CSR_REG(binfo, FC_HC_REG(binfo, ioa), offset); + FC_UNMAP_MEMIO(ioa); + + switch (clp[CFG_TOPOLOGY].a_current) { + case FLAGS_TOPOLOGY_MODE_LOOP_PT: + mb->un.varInitLnk.link_flags = FLAGS_TOPOLOGY_MODE_LOOP; + mb->un.varInitLnk.link_flags |= FLAGS_TOPOLOGY_FAILOVER; + break; + case FLAGS_TOPOLOGY_MODE_PT_PT: + mb->un.varInitLnk.link_flags = FLAGS_TOPOLOGY_MODE_PT_PT; + break; + case FLAGS_TOPOLOGY_MODE_LOOP: + mb->un.varInitLnk.link_flags = FLAGS_TOPOLOGY_MODE_LOOP; + break; + case FLAGS_TOPOLOGY_MODE_PT_LOOP: + mb->un.varInitLnk.link_flags = FLAGS_TOPOLOGY_MODE_PT_PT; + mb->un.varInitLnk.link_flags |= FLAGS_TOPOLOGY_FAILOVER; + break; + } + + vp = &VPD; + if (binfo->fc_flag & FC_2G_CAPABLE) { + if ((vp->rev.feaLevelHigh >= 0x02) && + (clp[CFG_LINK_SPEED].a_current > 0)) { + mb->un.varInitLnk.link_flags |= FLAGS_LINK_SPEED; + mb->un.varInitLnk.link_speed = clp[CFG_LINK_SPEED].a_current; + } + } + mb->mbxCommand = MBX_INIT_LINK; + mb->mbxOwner = OWN_HOST; + goto mbxbegin; + } + mb->mbxStatus = MBXERR_ERROR; + fc_bcopy((char *) & mb->mbxStatus, dm->fc_dataout, sizeof(ushort)); + break; + + case C_FAILIO: + { + uint32 tgt; + uint32 lun; + uint32 dev_index; + + binfo = &BINFO; + i = (uint32)((ulong)cip->c_arg1); + tgt = (uint32)((ulong)cip->c_arg2); + lun = (uint32)((ulong)cip->c_arg3); + switch(i) { + case 1: + fc_failio(p_dev_ctl); + break; + case 2: /* stop */ + dev_index = INDEX(0, tgt); + dev_ptr = fc_find_lun(binfo, dev_index, lun); + if(dev_ptr == 0) { + rc = ERANGE; + goto out; + } + dev_ptr->stop_send_io = 1; + break; + case 3: /* start */ + dev_index = INDEX(0, tgt); + dev_ptr = fc_find_lun(binfo, dev_index, lun); + if(dev_ptr == 0) { + rc = ERANGE; + goto out; + } + if(dev_ptr->stop_send_io == 1) { + dev_ptr->stop_send_io = 0; + fc_restart_device(dev_ptr); + } + break; + } + break; + } + + case C_RSTQDEPTH: + fc_reset_dev_q_depth(p_dev_ctl); + break; + + case C_OUTFCPIO: + { + max = (infop->c_outsz / sizeof(struct out_fcp_devp)) - 1; + + binfo = &BINFO; + fp = (struct out_fcp_io *)dm->fc_dataout; + dp = (struct out_fcp_devp *)((uchar *)fp + sizeof(struct out_fcp_io)); + rp = &binfo->fc_ring[FC_FCP_RING]; + fp->tx_head = rp->fc_tx.q_first; + fp->tx_tail = rp->fc_tx.q_last; + fp->txp_head = rp->fc_txp.q_first; + fp->txp_tail = rp->fc_txp.q_last; + fp->tx_count = rp->fc_tx.q_cnt; + fp->txp_count = rp->fc_txp.q_cnt; + fp->timeout_head = p_dev_ctl->timeout_head; + fp->timeout_count = p_dev_ctl->timeout_count; + fp->devp_count = 0; + for (i = 0; i < MAX_FC_TARGETS; i++) { + if ((node_ptr = binfo->device_queue_hash[i].node_ptr) != NULL) { + for (dev_ptr = node_ptr->lunlist; dev_ptr != NULL; + dev_ptr = dev_ptr->next) { + if(fp->devp_count++ >= max) + goto outio; + dp->target = dev_ptr->nodep->scsi_id; + dp->lun = (ushort)(dev_ptr->lun_id); + dp->standby_queue_head = dev_ptr->standby_queue_head; + dp->standby_queue_tail = dev_ptr->standby_queue_tail; + dp->standby_count = dev_ptr->standby_count; + dp->pend_head = dev_ptr->pend_head; + dp->pend_tail = dev_ptr->pend_tail; + dp->pend_count = dev_ptr->pend_count; + dp->clear_head = dev_ptr->clear_head; + dp->clear_count = dev_ptr->clear_count; + dp++; + } + } + } +outio: + infop->c_outsz = (sizeof(struct out_fcp_io) + + (fp->devp_count * sizeof(struct out_fcp_devp))); + } + break; + + case C_HBA_SEND_SCSI: + case C_HBA_SEND_FCP: + ipri = dfc_hba_sendscsi_fcp(p_dev_ctl, dm, cip, infop, ipri); + break; + + case C_SEND_ELS: + { + uint32 did; + uint32 opcode; + + binfo = &BINFO; + did = (uint32)((ulong)cip->c_arg1); + opcode = (uint32)((ulong)cip->c_arg2); + did = (did & Mask_DID); + + if(((nlp = fc_findnode_odid(binfo, NLP_SEARCH_ALL, did))) == 0) { + if((nlp = (NODELIST *)fc_mem_get(binfo, MEM_NLP))) { + fc_bzero((void *)nlp, sizeof(NODELIST)); + nlp->sync = binfo->fc_sync; + nlp->capabilities = binfo->fc_capabilities; + nlp->nlp_DID = did; + nlp->nlp_state = NLP_LIMBO; + fc_nlp_bind(binfo, nlp); + } + else { + rc = ENOMEM; + break; + } + } + + fc_els_cmd(binfo, opcode, (void *)((ulong)did), (uint32)0, (ushort)0, nlp); + } + break; + + case C_SEND_MGMT_RSP: + { + ULP_BDE64 * bpl; + MATCHMAP * bmp; + DMATCHMAP * indmp; + uint32 tag; + + tag = (uint32)cip->c_flag; /* XRI for XMIT_SEQUENCE */ + buf1sz = (uint32)((ulong)cip->c_arg2); + + if((buf1sz == 0) || + (buf1sz > (80 * 4096))) { + rc = ERANGE; + goto out; + } + + /* Allocate buffer for Buffer ptr list */ + if ((bmp = (MATCHMAP * )fc_mem_get(binfo, MEM_BPL)) == 0) { + rc = ENOMEM; + goto out; + } + bpl = (ULP_BDE64 * )bmp->virt; + dfc_unlock_enable(ipri, &CMD_LOCK); + + if((indmp = dfc_cmd_data_alloc(p_dev_ctl, (uchar *)cip->c_arg1, bpl, buf1sz)) == 0) { + ipri = dfc_disable_lock(FC_LVL, &CMD_LOCK); + fc_mem_put(binfo, MEM_BPL, (uchar * )bmp); + rc = ENOMEM; + goto out; + } + ipri = dfc_disable_lock(FC_LVL, &CMD_LOCK); + if((rc=fc_issue_ct_rsp(binfo, tag, bmp, indmp))) { + if(rc == ENODEV) + rc = EACCES; + goto xmout1; + } + + j = 0; + dfc_unlock_enable(ipri, &CMD_LOCK); + dfc_msdelay(p_dev_ctl, 1); + ipri = dfc_disable_lock(FC_LVL, &CMD_LOCK); + + /* Wait for CT request to complete or timeout */ + while(indmp->dfc_flag == 0) { + dfc_unlock_enable(ipri, &CMD_LOCK); + dfc_msdelay(p_dev_ctl, 50); + ipri = dfc_disable_lock(FC_LVL, &CMD_LOCK); + if(j >= 600) { + indmp->dfc_flag = -1; + break; + } + j++; + } + + j = indmp->dfc_flag; + if(j == -1) { + rc = ETIMEDOUT; + } + +xmout1: + dfc_unlock_enable(ipri, &CMD_LOCK); + dfc_cmd_data_free(p_dev_ctl, indmp); + ipri = dfc_disable_lock(FC_LVL, &CMD_LOCK); + fc_mem_put(binfo, MEM_BPL, (uchar * )bmp); + } + break; + + case C_SEND_MGMT_CMD: + case C_CT: + ipri = dfc_hba_sendmgmt_ct(p_dev_ctl, dm, cip, infop, ipri); + break; + + case C_MBOX: + binfo = &BINFO; + mb = (MAILBOX * )mbox; + + dfc_unlock_enable(ipri, &CMD_LOCK); + if (fc_copyin((uchar *)cip->c_arg1, (uchar *)mb, + MAILBOX_CMD_WSIZE * sizeof(uint32))) { + ipri = dfc_disable_lock(FC_LVL, &CMD_LOCK); + rc = EIO; + goto out; + } + ipri = dfc_disable_lock(FC_LVL, &CMD_LOCK); + +mbxbegin: + + cnt = 0; + while ((binfo->fc_mbox_active) || (di->fc_flag & DFC_MBOX_ACTIVE)) { + dfc_unlock_enable(ipri, &CMD_LOCK); + dfc_msdelay(p_dev_ctl, 5); + ipri = dfc_disable_lock(FC_LVL, &CMD_LOCK); + if(cnt++ == 200) + break; + } + + if (cnt >= 200) { + mb->mbxStatus = MBXERR_ERROR; + } + else { + binfo->fc_mbox_active = 2; +#ifdef _LP64 + if((mb->mbxCommand == MBX_READ_SPARM) || + (mb->mbxCommand == MBX_READ_RPI) || + (mb->mbxCommand == MBX_REG_LOGIN) || + (mb->mbxCommand == MBX_READ_LA)) { + mb->mbxStatus = MBXERR_ERROR; + rc = ENODEV; + binfo->fc_mbox_active = 0; + goto mbout; + } +#endif + lptr = 0; + size = 0; + switch (mb->mbxCommand) { + /* Offline only */ + case MBX_WRITE_NV: + case MBX_INIT_LINK: + case MBX_DOWN_LINK: + case MBX_CONFIG_LINK: + case MBX_PART_SLIM: + case MBX_CONFIG_RING: + case MBX_RESET_RING: + case MBX_UNREG_LOGIN: + case MBX_CLEAR_LA: + case MBX_DUMP_CONTEXT: + case MBX_RUN_DIAGS: + case MBX_RESTART: + case MBX_FLASH_WR_ULA: + case MBX_SET_MASK: + case MBX_SET_SLIM: + case MBX_SET_DEBUG: + if (!(binfo->fc_flag & FC_OFFLINE_MODE)) { + if (infop->c_cmd != C_LIP) { + mb->mbxStatus = MBXERR_ERROR; + binfo->fc_mbox_active = 0; + goto mbout; + } + } + break; + + /* Online / Offline */ + case MBX_LOAD_SM: + case MBX_READ_NV: + case MBX_READ_CONFIG: + case MBX_READ_RCONFIG: + case MBX_READ_STATUS: + case MBX_READ_XRI: + case MBX_READ_REV: + case MBX_READ_LNK_STAT: + case MBX_DUMP_MEMORY: + case MBX_DOWN_LOAD: + case MBX_UPDATE_CFG: + case MBX_LOAD_AREA: + case MBX_LOAD_EXP_ROM: + break; + + /* Offline only - with DMA */ + case MBX_REG_LOGIN: + if (!(binfo->fc_flag & FC_OFFLINE_MODE)) { + mb->mbxStatus = MBXERR_ERROR; + binfo->fc_mbox_active = 0; + goto mbout; + } + lptr = (uint32 * )((ulong)mb->un.varRegLogin.un.sp.bdeAddress); + size = (int)mb->un.varRegLogin.un.sp.bdeSize; + if (lptr) { + buf_info->virt = (void * )dfc.dfc_buffer; + buf_info->flags = (FC_MBUF_PHYSONLY | FC_MBUF_DMA | + FC_MBUF_IOCTL | FC_MBUF_UNLOCK); + buf_info->align = DMA_READ; + buf_info->size = sizeof(SERV_PARM); + buf_info->dma_handle = 0; + + dfc_unlock_enable(ipri, &CMD_LOCK); + fc_malloc(p_dev_ctl, buf_info); + ipri = dfc_disable_lock(FC_LVL, &CMD_LOCK); + + if (buf_info->phys == NULL) { + mb->mbxStatus = MBXERR_ERROR; + binfo->fc_mbox_active = 0; + goto mbout; + } + mb->un.varRegLogin.un.sp.bdeAddress = + (uint32)putPaddrLow(buf_info->phys); + } + break; + case MBX_RUN_BIU_DIAG: + if (!(binfo->fc_flag & FC_OFFLINE_MODE)) { + mb->mbxStatus = MBXERR_ERROR; + binfo->fc_mbox_active = 0; + goto mbout; + } + mb->mbxStatus = MBXERR_ERROR; + binfo->fc_mbox_active = 0; + goto mbout; + + /* Online / Offline - with DMA */ + case MBX_READ_SPARM64: + if (!((binfo->fc_flag & FC_SLI2) && (!(binfo->fc_flag & FC_OFFLINE_MODE)))) { + mb->mbxStatus = MBXERR_ERROR; + binfo->fc_mbox_active = 0; + goto mbout; + } + case MBX_READ_SPARM: + if ((binfo->fc_flag & FC_SLI2) && (!(binfo->fc_flag & FC_OFFLINE_MODE))) { + if (mb->mbxCommand == MBX_READ_SPARM) { + mb->mbxStatus = MBXERR_ERROR; + binfo->fc_mbox_active = 0; + goto mbout; + } + lptr = (uint32 * )getPaddr(mb->un.varRdSparm.un.sp64.addrHigh, + mb->un.varRdSparm.un.sp64.addrLow); + size = (int)mb->un.varRdSparm.un.sp64.tus.f.bdeSize; + } else { + lptr = (uint32 * )((ulong)mb->un.varRdSparm.un.sp.bdeAddress); + size = (int)mb->un.varRdSparm.un.sp.bdeSize; + } + if (lptr) { + buf_info->virt = (void * )dfc.dfc_buffer; + buf_info->flags = (FC_MBUF_PHYSONLY | FC_MBUF_DMA | + FC_MBUF_IOCTL | FC_MBUF_UNLOCK); + buf_info->align = DMA_READ; + buf_info->size = sizeof(SERV_PARM); + buf_info->dma_handle = 0; + buf_info->phys = 0; + + dfc_unlock_enable(ipri, &CMD_LOCK); + fc_malloc(p_dev_ctl, buf_info); + ipri = dfc_disable_lock(FC_LVL, &CMD_LOCK); + + if (buf_info->phys == NULL) { + mb->mbxStatus = MBXERR_ERROR; + binfo->fc_mbox_active = 0; + goto mbout; + } + if ((binfo->fc_flag & FC_SLI2) && (!(binfo->fc_flag & FC_OFFLINE_MODE))) { + mb->un.varRdSparm.un.sp64.addrHigh = + (uint32)putPaddrHigh(buf_info->phys); + mb->un.varRdSparm.un.sp64.addrLow = + (uint32)putPaddrLow(buf_info->phys); + } + else + mb->un.varRdSparm.un.sp.bdeAddress = + (uint32)putPaddrLow(buf_info->phys); + } + break; + case MBX_READ_RPI64: + if (!((binfo->fc_flag & FC_SLI2) && (!(binfo->fc_flag & FC_OFFLINE_MODE)))) { + mb->mbxStatus = MBXERR_ERROR; + binfo->fc_mbox_active = 0; + goto mbout; + } + case MBX_READ_RPI: + if ((binfo->fc_flag & FC_SLI2) && (!(binfo->fc_flag & FC_OFFLINE_MODE))) { + if (mb->mbxCommand == MBX_READ_RPI) { + mb->mbxStatus = MBXERR_ERROR; + binfo->fc_mbox_active = 0; + goto mbout; + } + lptr = (uint32 * )getPaddr(mb->un.varRdRPI.un.sp64.addrHigh, + mb->un.varRdRPI.un.sp64.addrLow); + size = (int)mb->un.varRdRPI.un.sp64.tus.f.bdeSize; + } else { + lptr = (uint32 * )((ulong)mb->un.varRdRPI.un.sp.bdeAddress); + size = (int)mb->un.varRdRPI.un.sp.bdeSize; + } + if (lptr) { + buf_info->virt = (void * )dfc.dfc_buffer; + buf_info->flags = (FC_MBUF_PHYSONLY | FC_MBUF_DMA | + FC_MBUF_IOCTL | FC_MBUF_UNLOCK); + buf_info->align = DMA_READ; + buf_info->size = sizeof(SERV_PARM); + buf_info->dma_handle = 0; + + dfc_unlock_enable(ipri, &CMD_LOCK); + fc_malloc(p_dev_ctl, buf_info); + ipri = dfc_disable_lock(FC_LVL, &CMD_LOCK); + + if (buf_info->phys == NULL) { + mb->mbxStatus = MBXERR_ERROR; + binfo->fc_mbox_active = 0; + goto mbout; + } + if ((binfo->fc_flag & FC_SLI2) && (!(binfo->fc_flag & FC_OFFLINE_MODE))) { + mb->un.varRdRPI.un.sp64.addrHigh = + (uint32)putPaddrHigh(buf_info->phys); + mb->un.varRdRPI.un.sp64.addrLow = + (uint32)putPaddrLow(buf_info->phys); + } + else + mb->un.varRdRPI.un.sp.bdeAddress = + (uint32)putPaddrLow(buf_info->phys); + } + break; + case MBX_READ_LA: + if (!(binfo->fc_flag & FC_OFFLINE_MODE)) { + mb->mbxStatus = MBXERR_ERROR; + binfo->fc_mbox_active = 0; + goto mbout; + } + lptr = (uint32 * )((ulong)mb->un.varReadLA.un.lilpBde.bdeAddress); + size = (int)mb->un.varReadLA.un.lilpBde.bdeSize; + if (lptr) { + buf_info->virt = (void * )dfc.dfc_buffer; + buf_info->flags = (FC_MBUF_PHYSONLY | FC_MBUF_DMA | + FC_MBUF_IOCTL | FC_MBUF_UNLOCK); + buf_info->align = DMA_READ; + buf_info->size = 128; + buf_info->dma_handle = 0; + + dfc_unlock_enable(ipri, &CMD_LOCK); + fc_malloc(p_dev_ctl, buf_info); + ipri = dfc_disable_lock(FC_LVL, &CMD_LOCK); + + if (buf_info->phys == NULL) { + mb->mbxStatus = MBXERR_ERROR; + binfo->fc_mbox_active = 0; + goto mbout; + } + mb->un.varReadLA.un.lilpBde.bdeAddress = + (uint32)putPaddrLow(buf_info->phys); + } + break; + + case MBX_CONFIG_PORT: + case MBX_REG_LOGIN64: + case MBX_READ_LA64: + mb->mbxStatus = MBXERR_ERROR; + binfo->fc_mbox_active = 0; + goto mbout; + + default: + if (!(binfo->fc_flag & FC_OFFLINE_MODE)) { + mb->mbxStatus = MBXERR_ERROR; + binfo->fc_mbox_active = 0; + goto mbout; + } + break; + } + + binfo->fc_mbox_active = 0; + if(dfc_issue_mbox(p_dev_ctl, mb, &ipri)) + goto mbout; + + if (lptr) { + buf_info->virt = 0; + buf_info->flags = (FC_MBUF_PHYSONLY | FC_MBUF_DMA | + FC_MBUF_IOCTL | FC_MBUF_UNLOCK); + buf_info->dma_handle = 0; + switch (mb->mbxCommand) { + case MBX_REG_LOGIN: + buf_info->phys = (uint32 * ) + ((ulong)mb->un.varRegLogin.un.sp.bdeAddress); + buf_info->size = sizeof(SERV_PARM); + break; + + case MBX_READ_SPARM: + buf_info->phys = (uint32 * ) + ((ulong)mb->un.varRdSparm.un.sp.bdeAddress); + buf_info->size = sizeof(SERV_PARM); + break; + + case MBX_READ_RPI: + buf_info->phys = (uint32 * ) + ((ulong)mb->un.varRdRPI.un.sp.bdeAddress); + buf_info->size = sizeof(SERV_PARM); + break; + + case MBX_READ_LA: + buf_info->phys = (uint32 * ) + ((ulong)mb->un.varReadLA.un.lilpBde.bdeAddress); + buf_info->size = 128; + break; + } + + dfc_unlock_enable(ipri, &CMD_LOCK); + fc_free(p_dev_ctl, buf_info); + + if ((fc_copyout((uchar *)dfc.dfc_buffer, (uchar *)lptr, (ulong)size))) { + rc = EIO; + } + ipri = dfc_disable_lock(FC_LVL, &CMD_LOCK); + } + } + +mbout: + if (infop->c_cmd == C_LIP) { + /* Turn on Link Attention interrupts */ + binfo->fc_process_LA = 1; + ioa = (void *)FC_MAP_IO(&binfo->fc_iomap_io); /* map in io registers */ + offset = READ_CSR_REG(binfo, FC_HC_REG(binfo, ioa)); + offset |= HC_LAINT_ENA; + WRITE_CSR_REG(binfo, FC_HC_REG(binfo, ioa), offset); + FC_UNMAP_MEMIO(ioa); + } + + if (infop->c_cmd == C_LIP) + fc_bcopy((char *) & mb->mbxStatus, dm->fc_dataout, sizeof(ushort)); + else + fc_bcopy((char *)mb, dm->fc_dataout, MAILBOX_CMD_WSIZE * sizeof(uint32)); + break; + + + case C_DISPLAY_PCI_ALL: + + if ((rc = fc_readpci(di, 0, (char *)dm->fc_dataout, 64))) + break; + break; + + case C_SET: + if(cip->c_iocb == 0) { + bp = binfo->fc_portname.IEEE; + } + else { + cnt = 0; + bp = 0; + nlp = binfo->fc_nlpunmap_start; + if(nlp == (NODELIST *)&binfo->fc_nlpunmap_start) + nlp = binfo->fc_nlpmap_start; + while(nlp != (NODELIST *)&binfo->fc_nlpmap_start) { + if((int)cnt == cip->c_iocb-1) { + if ((nlp->nlp_type & NLP_IP_NODE) && (nlp->nlp_Rpi) && + (nlp->nlp_Xri)) { + bp = nlp->nlp_nodename.IEEE; + } + else { + bp = binfo->fc_portname.IEEE; + } + break; + } + cnt++; + nlp = (NODELIST *)nlp->nlp_listp_next; + if(nlp == (NODELIST *)&binfo->fc_nlpunmap_start) + nlp = binfo->fc_nlpmap_start; + } + } + break; + + case C_WRITE_HC: + incr = (uint32)((ulong)cip->c_arg1); + ioa = (void *)FC_MAP_IO(&di->fc_iomap_io); /* map in io registers */ + WRITE_CSR_REG(binfo, + ((volatile uint32 * )((volatile char *)ioa + (sizeof(uint32) * HC_REG_OFFSET))), incr); + FC_UNMAP_MEMIO(ioa); + case C_READ_HC: + ioa = (void *)FC_MAP_IO(&di->fc_iomap_io); /* map in io registers */ + offset = READ_CSR_REG(binfo, FC_HC_REG(binfo, ioa)); + FC_UNMAP_MEMIO(ioa); + + *((uint32 * )dm->fc_dataout) = offset; + break; + + case C_WRITE_HS: + incr = (uint32)((ulong)cip->c_arg1); + ioa = (void *)FC_MAP_IO(&di->fc_iomap_io); /* map in io registers */ + WRITE_CSR_REG(binfo, + ((volatile uint32 * )((volatile char *)ioa + (sizeof(uint32) * HS_REG_OFFSET))), incr); + FC_UNMAP_MEMIO(ioa); + case C_READ_HS: + ioa = (void *)FC_MAP_IO(&di->fc_iomap_io); /* map in io registers */ + offset = READ_CSR_REG(binfo, FC_STAT_REG(binfo, ioa)); + FC_UNMAP_MEMIO(ioa); + + *((uint32 * )dm->fc_dataout) = offset; + break; + + case C_WRITE_HA: + incr = (uint32)((ulong)cip->c_arg1); + ioa = (void *)FC_MAP_IO(&di->fc_iomap_io); /* map in io registers */ + WRITE_CSR_REG(binfo, + ((volatile uint32 * )((volatile char *)ioa + (sizeof(uint32) * HA_REG_OFFSET))), incr); + FC_UNMAP_MEMIO(ioa); + case C_READ_HA: + ioa = (void *)FC_MAP_IO(&di->fc_iomap_io); /* map in io registers */ + offset = READ_CSR_REG(binfo, FC_HA_REG(binfo, ioa)); + FC_UNMAP_MEMIO(ioa); + + *((uint32 * )dm->fc_dataout) = offset; + break; + + case C_WRITE_CA: + incr = (uint32)((ulong)cip->c_arg1); + ioa = (void *)FC_MAP_IO(&di->fc_iomap_io); /* map in io registers */ + WRITE_CSR_REG(binfo, + ((volatile uint32 * )((volatile char *)ioa + (sizeof(uint32) * CA_REG_OFFSET))), incr); + FC_UNMAP_MEMIO(ioa); + case C_READ_CA: + ioa = (void *)FC_MAP_IO(&di->fc_iomap_io); /* map in io registers */ + offset = READ_CSR_REG(binfo, FC_FF_REG(binfo, ioa)); + FC_UNMAP_MEMIO(ioa); + + *((uint32 * )dm->fc_dataout) = offset; + break; + + case C_READ_MB: + binfo = &BINFO; + if ((binfo->fc_flag & FC_SLI2) && (!(binfo->fc_flag & FC_OFFLINE_MODE))) { + mb = FC_SLI2_MAILBOX(binfo); + fc_pcimem_bcopy((uint32 * )mb, (uint32 * )dm->fc_dataout, 128); + } else { + ioa = (void *)FC_MAP_MEM(&di->fc_iomap_mem); /* map in slim */ + READ_SLIM_COPY(binfo, (uint32 * )dm->fc_dataout, (uint32 * )ioa, + MAILBOX_CMD_WSIZE); + FC_UNMAP_MEMIO(ioa); + } + break; + + case C_DBG: + offset = (uint32)((ulong)cip->c_arg1); + switch (offset) { + case 0xffffffff: + break; + default: + fc_dbg_flag = offset; + break; + } + + fc_bcopy((uchar * ) & fc_dbg_flag , dm->fc_dataout, sizeof(uint32)); + break; + + case C_INST: + fc_bcopy((uchar * ) &fcinstcnt, dm->fc_dataout, sizeof(int)); + fc_bcopy((uchar * ) fcinstance, ((uchar *)dm->fc_dataout) + sizeof(int), sizeof(int) * MAX_FC_BRDS); + break; + + case C_READ_RING: + fc_bcopy(&binfo->fc_ring[cip->c_ring], dm->fc_dataout, sizeof(RING)); + break; + + case C_LISTN: + { + NODELIST *npp; + ulong lcnt; + ulong *lcntp; + + offset = (uint32)((ulong)cip->c_arg1); + total_mem -= sizeof(NODELIST); + lcnt = 0; + switch (offset) { + case 1: /* bind */ + lcntp = dm->fc_dataout; + fc_bcopy((uchar * ) &lcnt , dm->fc_dataout, sizeof(ulong)); + npp = (NODELIST *)((char *)(dm->fc_dataout) + sizeof(ulong)); + nlp = binfo->fc_nlpbind_start; + while((nlp != (NODELIST *)&binfo->fc_nlpbind_start) && (total_mem > 0)) { + fc_bcopy((char *)nlp, npp, (sizeof(NODELIST))); + total_mem -= sizeof(NODELIST); + npp++; + lcnt++; + nlp = (NODELIST *)nlp->nlp_listp_next; + } + *lcntp = lcnt; + break; + case 2: /* unmap */ + lcntp = dm->fc_dataout; + fc_bcopy((uchar * ) &lcnt , dm->fc_dataout, sizeof(ulong)); + npp = (NODELIST *)((char *)(dm->fc_dataout) + sizeof(ulong)); + nlp = binfo->fc_nlpunmap_start; + while((nlp != (NODELIST *)&binfo->fc_nlpunmap_start) && (total_mem > 0)) { + fc_bcopy((char *)nlp, npp, (sizeof(NODELIST))); + total_mem -= sizeof(NODELIST); + npp++; + lcnt++; + nlp = (NODELIST *)nlp->nlp_listp_next; + } + *lcntp = lcnt; + break; + case 3: /* map */ + lcntp = dm->fc_dataout; + fc_bcopy((uchar * ) &lcnt , dm->fc_dataout, sizeof(ulong)); + npp = (NODELIST *)((char *)(dm->fc_dataout) + sizeof(ulong)); + nlp = binfo->fc_nlpmap_start; + while((nlp != (NODELIST *)&binfo->fc_nlpmap_start) && (total_mem > 0)) { + fc_bcopy((char *)nlp, npp, (sizeof(NODELIST))); + total_mem -= sizeof(NODELIST); + npp++; + lcnt++; + nlp = (NODELIST *)nlp->nlp_listp_next; + } + *lcntp = lcnt; + break; + case 4: /* all */ + lcntp = dm->fc_dataout; + fc_bcopy((uchar * ) &lcnt , dm->fc_dataout, sizeof(ulong)); + npp = (NODELIST *)((char *)(dm->fc_dataout) + sizeof(ulong)); + nlp = binfo->fc_nlpbind_start; + while((nlp != (NODELIST *)&binfo->fc_nlpbind_start) && (total_mem > 0)) { + fc_bcopy((char *)nlp, npp, (sizeof(NODELIST))); + total_mem -= sizeof(NODELIST); + npp++; + lcnt++; + nlp = (NODELIST *)nlp->nlp_listp_next; + } + nlp = binfo->fc_nlpunmap_start; + while((nlp != (NODELIST *)&binfo->fc_nlpunmap_start) && (total_mem > 0)) { + fc_bcopy((char *)nlp, npp, (sizeof(NODELIST))); + total_mem -= sizeof(NODELIST); + npp++; + lcnt++; + nlp = (NODELIST *)nlp->nlp_listp_next; + } + nlp = binfo->fc_nlpmap_start; + while((nlp != (NODELIST *)&binfo->fc_nlpmap_start) && (total_mem > 0)) { + fc_bcopy((char *)nlp, npp, (sizeof(NODELIST))); + total_mem -= sizeof(NODELIST); + npp++; + lcnt++; + nlp = (NODELIST *)nlp->nlp_listp_next; + } + *lcntp = lcnt; + break; + default: + rc = ERANGE; + break; + } + infop->c_outsz = (sizeof(ulong) + (lcnt * sizeof(NODELIST))); + break; + } + + case C_LISTEVT: + { + uint32 ehdcnt; + uint32 ecnt; + uint32 *ehdcntp; + uint32 *ecntp; + fcEvent *ep; + fcEvent_header *ehp; + + offset = (uint32)((ulong)cip->c_arg1); + total_mem -= sizeof(uint32); + infop->c_outsz = sizeof(uint32); + ehdcnt = 0; + ehdcntp = (uint32 *)dm->fc_dataout; + bp = (uchar *)((char *)(dm->fc_dataout) + sizeof(uint32)); + switch (offset) { + case 1: /* link */ + offset = FC_REG_LINK_EVENT; + break; + case 2: /* rscn */ + offset = FC_REG_RSCN_EVENT; + break; + case 3: /* ct */ + offset = FC_REG_CT_EVENT; + break; + case 7: /* all */ + offset = 0; + break; + default: + rc = ERANGE; + goto out; + } + ehp = (fcEvent_header *)p_dev_ctl->fc_evt_head; + while (ehp) { + if ((offset == 0) || (ehp->e_mask == offset)) { + ehdcnt++; + fc_bcopy((char *)ehp, bp, (sizeof(fcEvent_header))); + bp += (sizeof(fcEvent_header)); + total_mem -= sizeof(fcEvent_header); + if(total_mem <= 0) { + rc = ENOMEM; + goto out; + } + infop->c_outsz += sizeof(fcEvent_header); + ecnt = 0; + ecntp = (uint32 *)bp; + bp += (sizeof(uint32)); + total_mem -= sizeof(uint32); + infop->c_outsz += sizeof(uint32); + ep = ehp->e_head; + while(ep) { + ecnt++; + fc_bcopy((char *)ehp, bp, (sizeof(fcEvent))); + bp += (sizeof(fcEvent)); + total_mem -= sizeof(fcEvent); + if(total_mem <= 0) { + rc = ENOMEM; + goto out; + } + infop->c_outsz += sizeof(fcEvent); + ep = ep->evt_next; + } + *ecntp = ecnt; + } + ehp = (fcEvent_header *)ehp->e_next_header; + } + + *ehdcntp = ehdcnt; + break; + } + + case C_READ_RPILIST: + { + NODELIST *npp; + + cnt = 0; + npp = (NODELIST *)(dm->fc_dataout); + nlp = binfo->fc_nlpbind_start; + if(nlp == (NODELIST *)&binfo->fc_nlpbind_start) + nlp = binfo->fc_nlpunmap_start; + if(nlp == (NODELIST *)&binfo->fc_nlpunmap_start) + nlp = binfo->fc_nlpmap_start; + while((nlp != (NODELIST *)&binfo->fc_nlpmap_start) && (total_mem > 0)) { + fc_bcopy((char *)nlp, (char *)npp, sizeof(NODELIST)); + npp++; + cnt++; + nlp = (NODELIST *)nlp->nlp_listp_next; + if(nlp == (NODELIST *)&binfo->fc_nlpbind_start) + nlp = binfo->fc_nlpunmap_start; + if(nlp == (NODELIST *)&binfo->fc_nlpunmap_start) + nlp = binfo->fc_nlpmap_start; + } + if(cnt) { + infop->c_outsz = (uint32)(cnt * sizeof(NODELIST)); + } + } + break; + + case C_READ_BPLIST: + rp = &binfo->fc_ring[cip->c_ring]; + lptr = (uint32 * )dm->fc_dataout; + + mm = (MATCHMAP * )rp->fc_mpoff; + total_mem -= (3*sizeof(ulong)); + while ((mm) && (total_mem > 0)) { + if (cip->c_ring == FC_ELS_RING) { + *lptr++ = (uint32)((ulong)mm); + *lptr++ = (uint32)((ulong)mm->virt); + *lptr++ = (uint32)((ulong)mm->phys); + mm = (MATCHMAP * )mm->fc_mptr; + } + if (cip->c_ring == FC_IP_RING) { + fbp = (fcipbuf_t * )mm; + *lptr++ = (uint32)((ulong)fbp); + *lptr++ = (uint32)((ulong)fcdata(fbp)); + *lptr++ = (uint32)((ulong)fcnextpkt(fbp)); + mm = (MATCHMAP * )fcnextdata(fbp); + } + total_mem -= (3 * sizeof(ulong)); + } + *lptr++ = 0; + *lptr++ = (uint32)((ulong)rp->fc_mpon); + + infop->c_outsz = ((uchar * )lptr - (uchar *)(dm->fc_dataout)); + break; + + case C_READ_MEMSEG: + fc_bcopy(&binfo->fc_memseg, dm->fc_dataout, (sizeof(MEMSEG) * FC_MAX_SEG)); + break; + + case C_RESET: + offset = (uint32)((ulong)cip->c_arg1); + switch (offset) { + case 1: /* hba */ + fc_brdreset(p_dev_ctl); + break; + case 2: /* link */ + fc_rlip(p_dev_ctl); + break; + case 3: /* target */ + fc_fcp_abort(p_dev_ctl, TARGET_RESET, (int)((ulong)cip->c_arg2), -1); + break; + case 4: /* lun */ + fc_fcp_abort(p_dev_ctl, LUN_RESET, (int)((ulong)cip->c_arg2), + (int)((ulong)cip->c_arg3)); + break; + case 5: /* task set */ + fc_fcp_abort(p_dev_ctl, ABORT_TASK_SET, (int)((ulong)cip->c_arg2), + (int)((ulong)cip->c_arg3)); + break; + case 6: /* bus */ + fc_fcp_abort(p_dev_ctl, TARGET_RESET, -1, -1); + break; + default: + rc = ERANGE; + break; + } + break; + + case C_READ_BINFO: + case C_FC_STAT: + fc_bcopy(binfo, dm->fc_dataout, sizeof(FC_BRD_INFO)); + break; + + case C_NODE: + break; + + case C_DEVP: + offset = (uint32)((ulong)cip->c_arg1); + cnt = (uint32)((ulong)cip->c_arg2); + if ((offset >= (MAX_FC_TARGETS)) || (cnt >= 128)) { + rc = ERANGE; + break; + } + fc_bzero(dm->fc_dataout, (sizeof(dvi_t))+(sizeof(nodeh_t))+(sizeof(node_t))); + fc_bcopy((char *)&binfo->device_queue_hash[offset], (uchar *)dm->fc_dataout, (sizeof(nodeh_t))); + + nodep = binfo->device_queue_hash[offset].node_ptr; + if (nodep == 0) { + break; + } + dev_ptr = nodep->lunlist; + while ((dev_ptr != 0)) { + if(dev_ptr->lun_id == cnt) + break; + dev_ptr = dev_ptr->next; + } + if (dev_ptr == 0) { + break; + } + + fc_bcopy((char *)&binfo->device_queue_hash[offset], (uchar *)dm->fc_dataout, + (sizeof(nodeh_t))); + fc_bcopy((char *)nodep, ((uchar *)dm->fc_dataout + sizeof(nodeh_t)), + (sizeof(node_t))); + fc_bcopy((char *)dev_ptr, + ((uchar *)dm->fc_dataout + sizeof(nodeh_t) + sizeof(node_t)), + (sizeof(dvi_t))); + break; + + case C_NDD_STAT: + fc_bcopy(&NDDSTAT, dm->fc_dataout, sizeof(ndd_genstats_t)); + break; + + case C_LINKINFO: +linfo: + { + LinkInfo *linkinfo; + + linkinfo = (LinkInfo *)dm->fc_dataout; + linkinfo->a_linkEventTag = binfo->fc_eventTag; + linkinfo->a_linkUp = FCSTATCTR.LinkUp; + linkinfo->a_linkDown = FCSTATCTR.LinkDown; + linkinfo->a_linkMulti = FCSTATCTR.LinkMultiEvent; + linkinfo->a_DID = binfo->fc_myDID; + if (binfo->fc_topology == TOPOLOGY_LOOP) { + if(binfo->fc_flag & FC_PUBLIC_LOOP) { + linkinfo->a_topology = LNK_PUBLIC_LOOP; + fc_bcopy((uchar * )binfo->alpa_map, + (uchar *)linkinfo->a_alpaMap, 128); + linkinfo->a_alpaCnt = binfo->alpa_map[0]; + } + else { + linkinfo->a_topology = LNK_LOOP; + fc_bcopy((uchar * )binfo->alpa_map, + (uchar *)linkinfo->a_alpaMap, 128); + linkinfo->a_alpaCnt = binfo->alpa_map[0]; + } + } + else { + fc_bzero((uchar *)linkinfo->a_alpaMap, 128); + linkinfo->a_alpaCnt = 0; + if(binfo->fc_flag & FC_FABRIC) { + linkinfo->a_topology = LNK_FABRIC; + } + else { + linkinfo->a_topology = LNK_PT2PT; + } + } + linkinfo->a_linkState = 0; + switch (binfo->fc_ffstate) { + case FC_INIT_START: + case FC_INIT_NVPARAMS: + case FC_INIT_REV: + case FC_INIT_PARTSLIM: + case FC_INIT_CFGRING: + case FC_INIT_INITLINK: + case FC_LINK_DOWN: + linkinfo->a_linkState = LNK_DOWN; + fc_bzero((uchar *)linkinfo->a_alpaMap, 128); + linkinfo->a_alpaCnt = 0; + break; + case FC_LINK_UP: + case FC_INIT_SPARAM: + case FC_CFG_LINK: + linkinfo->a_linkState = LNK_UP; + break; + case FC_FLOGI: + linkinfo->a_linkState = LNK_FLOGI; + break; + case FC_LOOP_DISC: + case FC_NS_REG: + case FC_NS_QRY: + case FC_NODE_DISC: + case FC_REG_LOGIN: + case FC_CLEAR_LA: + linkinfo->a_linkState = LNK_DISCOVERY; + break; + case FC_READY: + linkinfo->a_linkState = LNK_READY; + break; + } + linkinfo->a_alpa = (uchar)(binfo->fc_myDID & 0xff); + fc_bcopy((uchar * )&binfo->fc_portname, (uchar *)linkinfo->a_wwpName, 8); + fc_bcopy((uchar * )&binfo->fc_nodename, (uchar *)linkinfo->a_wwnName, 8); + } + break; + + case C_IOINFO: + { + IOinfo *ioinfo; + + ioinfo = (IOinfo *)dm->fc_dataout; + ioinfo->a_mbxCmd = FCSTATCTR.issueMboxCmd; + ioinfo->a_mboxCmpl = FCSTATCTR.mboxEvent; + ioinfo->a_mboxErr = FCSTATCTR.mboxStatErr; + ioinfo->a_iocbCmd = FCSTATCTR.IssueIocb; + ioinfo->a_iocbRsp = FCSTATCTR.iocbRsp; + ioinfo->a_adapterIntr = (FCSTATCTR.linkEvent + FCSTATCTR.iocbRsp + + FCSTATCTR.mboxEvent); + ioinfo->a_fcpCmd = FCSTATCTR.fcpCmd; + ioinfo->a_fcpCmpl = FCSTATCTR.fcpCmpl; + ioinfo->a_fcpErr = FCSTATCTR.fcpRspErr + FCSTATCTR.fcpRemoteStop + + FCSTATCTR.fcpPortRjt + FCSTATCTR.fcpPortBusy + FCSTATCTR.fcpError + + FCSTATCTR.fcpLocalErr; + ioinfo->a_seqXmit = NDDSTAT.ndd_ifOutUcastPkts_lsw; + ioinfo->a_seqRcv = NDDSTAT.ndd_recvintr_lsw; + ioinfo->a_bcastXmit = NDDSTAT.ndd_ifOutBcastPkts_lsw + + NDDSTAT.ndd_ifOutMcastPkts_lsw; + ioinfo->a_bcastRcv = FCSTATCTR.frameRcvBcast; + ioinfo->a_elsXmit = FCSTATCTR.elsXmitFrame; + ioinfo->a_elsRcv = FCSTATCTR.elsRcvFrame; + ioinfo->a_RSCNRcv = FCSTATCTR.elsRcvRSCN; + ioinfo->a_seqXmitErr = NDDSTAT.ndd_oerrors; + ioinfo->a_elsXmitErr = FCSTATCTR.elsXmitErr; + ioinfo->a_elsBufPost = binfo->fc_ring[FC_ELS_RING].fc_bufcnt; + ioinfo->a_ipBufPost = binfo->fc_ring[FC_IP_RING].fc_bufcnt; + ioinfo->a_cnt1 = 0; + ioinfo->a_cnt2 = 0; + ioinfo->a_cnt3 = 0; + ioinfo->a_cnt4 = 0; + } + break; + + case C_NODEINFO: + { + NodeInfo * np; + + /* First uint32 word will be count */ + np = (NodeInfo *)dm->fc_dataout; + cnt = 0; + total_mem -= sizeof(NODELIST); + + nlp = binfo->fc_nlpbind_start; + if(nlp == (NODELIST *)&binfo->fc_nlpbind_start) + nlp = binfo->fc_nlpunmap_start; + if(nlp == (NODELIST *)&binfo->fc_nlpunmap_start) + nlp = binfo->fc_nlpmap_start; + while((nlp != (NODELIST *)&binfo->fc_nlpmap_start) && (total_mem > 0)) { + fc_bzero((uchar *)np, sizeof(NODELIST)); + if(nlp->nlp_flag & NLP_NS_REMOVED) + np->a_flag |= NODE_NS_REMOVED; + if(nlp->nlp_flag & NLP_RPI_XRI) + np->a_flag |= NODE_RPI_XRI; + if(nlp->nlp_flag & NLP_REQ_SND) + np->a_flag |= NODE_REQ_SND; + if(nlp->nlp_flag & NLP_RM_ENTRY) + np->a_flag |= NODE_RM_ENTRY; + if(nlp->nlp_flag & NLP_FARP_SND) + np->a_flag |= NODE_FARP_SND; + if(nlp->nlp_type & NLP_FABRIC) + np->a_flag |= NODE_FABRIC; + if(nlp->nlp_type & NLP_FCP_TARGET) + np->a_flag |= NODE_FCP_TARGET; + if(nlp->nlp_type & NLP_IP_NODE) + np->a_flag |= NODE_IP_NODE; + if(nlp->nlp_type & NLP_SEED_WWPN) + np->a_flag |= NODE_SEED_WWPN; + if(nlp->nlp_type & NLP_SEED_WWNN) + np->a_flag |= NODE_SEED_WWNN; + if(nlp->nlp_type & NLP_SEED_DID) + np->a_flag |= NODE_SEED_DID; + if(nlp->nlp_type & NLP_AUTOMAP) + np->a_flag |= NODE_AUTOMAP; + if(nlp->nlp_action & NLP_DO_DISC_START) + np->a_flag |= NODE_DISC_START; + if(nlp->nlp_action & NLP_DO_ADDR_AUTH) + np->a_flag |= NODE_ADDR_AUTH; + np->a_state = nlp->nlp_state; + np->a_did = nlp->nlp_DID; + np->a_targetid = FC_SCSID(nlp->id.nlp_pan, nlp->id.nlp_sid); + fc_bcopy(&nlp->nlp_portname, np->a_wwpn, 8); + fc_bcopy(&nlp->nlp_nodename, np->a_wwnn, 8); + total_mem -= sizeof(NODELIST); + np++; + cnt++; + nlp = (NODELIST *)nlp->nlp_listp_next; + if(nlp == (NODELIST *)&binfo->fc_nlpbind_start) + nlp = binfo->fc_nlpunmap_start; + if(nlp == (NODELIST *)&binfo->fc_nlpunmap_start) + nlp = binfo->fc_nlpmap_start; + } + if(cnt) { + infop->c_outsz = (uint32)(cnt * sizeof(NodeInfo)); + } + } + break; + + case C_HBA_ADAPTERATRIBUTES: + { + HBA_ADAPTERATTRIBUTES * ha; + + vp = &VPD; + ha = (HBA_ADAPTERATTRIBUTES *)dm->fc_dataout; + fc_bzero(dm->fc_dataout, (sizeof(HBA_ADAPTERATTRIBUTES))); + ha->NumberOfPorts = 1; + ha->VendorSpecificID = di->fc_ba.a_pci; + fc_bcopy(di->fc_ba.a_drvrid, ha->DriverVersion, 16); + fc_bcopy(di->fc_ba.a_fwname, ha->FirmwareVersion, 32); + fc_bcopy((uchar * )&binfo->fc_sparam.nodeName, (uchar * )&ha->NodeWWN, + sizeof(HBA_WWN)); + fc_bcopy("Emulex Corporation", ha->Manufacturer, 20); + + switch(((SWAP_LONG(ha->VendorSpecificID))>>16) & 0xffff) { + case PCI_DEVICE_ID_SUPERFLY: + if((vp->rev.biuRev == 1) || + (vp->rev.biuRev == 2) || (vp->rev.biuRev == 3)) { + fc_bcopy("LP7000", ha->Model, 8); + fc_bcopy("Emulex LightPulse LP7000 1 Gigabit PCI Fibre Channel Adapter", ha->ModelDescription, 62); + } + else { + fc_bcopy("LP7000E", ha->Model, 9); + fc_bcopy("Emulex LightPulse LP7000E 1 Gigabit PCI Fibre Channel Adapter", ha->ModelDescription, 62); + } + break; + case PCI_DEVICE_ID_DRAGONFLY: + fc_bcopy("LP8000", ha->Model, 8); + fc_bcopy("Emulex LightPulse LP8000 1 Gigabit PCI Fibre Channel Adapter", ha->ModelDescription, 62); + break; + case PCI_DEVICE_ID_CENTAUR: + if(FC_JEDEC_ID(vp->rev.biuRev) == CENTAUR_2G_JEDEC_ID) { + fc_bcopy("LP9002", ha->Model, 8); + fc_bcopy("Emulex LightPulse LP9002 2 Gigabit PCI Fibre Channel Adapter", ha->ModelDescription, 62); + } + else { + fc_bcopy("LP9000", ha->Model, 8); + fc_bcopy("Emulex LightPulse LP9000 1 Gigabit PCI Fibre Channel Adapter", ha->ModelDescription, 62); + } + break; + case PCI_DEVICE_ID_PEGASUS: + fc_bcopy("LP9802", ha->Model, 8); + fc_bcopy("Emulex LightPulse LP9802 2 Gigabit PCI Fibre Channel Adapter", ha->ModelDescription, 62); + break; + case PCI_DEVICE_ID_THOR: + fc_bcopy("LP10000", ha->Model, 9); + fc_bcopy("Emulex LightPulse LP10000 2 Gigabit PCI Fibre Channel Adapter", ha->ModelDescription, 63); + break; + case PCI_DEVICE_ID_PFLY: + fc_bcopy("LP982", ha->Model, 7); + fc_bcopy("Emulex LightPulse LP982 2 Gigabit PCI Fibre Channel Adapter", ha->ModelDescription, 62); + break; + case PCI_DEVICE_ID_TFLY: + fc_bcopy("LP1050", ha->Model, 8); + fc_bcopy("Emulex LightPulse LP1050 2 Gigabit PCI Fibre Channel Adapter", ha->ModelDescription, 63); + break; + } + fc_bcopy("lpfcdd", ha->DriverName, 7); + fc_bcopy(binfo->fc_SerialNumber, ha->SerialNumber, 32); + fc_bcopy(binfo->fc_OptionROMVersion, ha->OptionROMVersion, 32); + + /* Convert JEDEC ID to ascii for hardware version */ + incr = vp->rev.biuRev; + for(i=0;i<8;i++) { + j = (incr & 0xf); + if(j <= 9) + ha->HardwareVersion[7-i] = (char)((uchar)0x30 + (uchar)j); + else + ha->HardwareVersion[7-i] = (char)((uchar)0x61 + (uchar)(j-10)); + incr = (incr >> 4); + } + ha->HardwareVersion[8] = 0; + + } + break; + + case C_HBA_PORTATRIBUTES: + { + SERV_PARM * hsp; + HBA_OSDN * osdn; + +localport: + vp = &VPD; + hsp = (SERV_PARM *)&binfo->fc_sparam; + hp = (HBA_PORTATTRIBUTES *)dm->fc_dataout; + fc_bzero(dm->fc_dataout, (sizeof(HBA_PORTATTRIBUTES))); + fc_bcopy((uchar * )&binfo->fc_sparam.nodeName, (uchar * )&hp->NodeWWN, + sizeof(HBA_WWN)); + fc_bcopy((uchar * )&binfo->fc_sparam.portName, (uchar * )&hp->PortWWN, + sizeof(HBA_WWN)); + + if( binfo->fc_linkspeed == LA_2GHZ_LINK) + hp->PortSpeed = HBA_PORTSPEED_2GBIT; + else + hp->PortSpeed = HBA_PORTSPEED_1GBIT; + + if(FC_JEDEC_ID(vp->rev.biuRev) == CENTAUR_2G_JEDEC_ID) + hp->PortSupportedSpeed = HBA_PORTSPEED_2GBIT; + else + hp->PortSupportedSpeed = HBA_PORTSPEED_1GBIT; + + hp->PortFcId = binfo->fc_myDID; + hp->PortType = HBA_PORTTYPE_UNKNOWN; + if (binfo->fc_topology == TOPOLOGY_LOOP) { + if(binfo->fc_flag & FC_PUBLIC_LOOP) { + hp->PortType = HBA_PORTTYPE_NLPORT; + fc_bcopy((uchar * )&binfo->fc_fabparam.nodeName, + (uchar * )&hp->FabricName, sizeof(HBA_WWN)); + } + else { + hp->PortType = HBA_PORTTYPE_LPORT; + } + } + else { + if(binfo->fc_flag & FC_FABRIC) { + hp->PortType = HBA_PORTTYPE_NPORT; + fc_bcopy((uchar * )&binfo->fc_fabparam.nodeName, + (uchar * )&hp->FabricName, sizeof(HBA_WWN)); + } + else { + hp->PortType = HBA_PORTTYPE_PTP; + } + } + + if (binfo->fc_flag & FC_BYPASSED_MODE) { + hp->PortState = HBA_PORTSTATE_BYPASSED; + } + else if (binfo->fc_flag & FC_OFFLINE_MODE) { + hp->PortState = HBA_PORTSTATE_DIAGNOSTICS; + } + else { + switch (binfo->fc_ffstate) { + case FC_INIT_START: + case FC_INIT_NVPARAMS: + case FC_INIT_REV: + case FC_INIT_PARTSLIM: + case FC_INIT_CFGRING: + case FC_INIT_INITLINK: + hp->PortState = HBA_PORTSTATE_UNKNOWN; + case FC_LINK_DOWN: + case FC_LINK_UP: + case FC_INIT_SPARAM: + case FC_CFG_LINK: + case FC_FLOGI: + case FC_LOOP_DISC: + case FC_NS_REG: + case FC_NS_QRY: + case FC_NODE_DISC: + case FC_REG_LOGIN: + case FC_CLEAR_LA: + hp->PortState = HBA_PORTSTATE_LINKDOWN; + break; + case FC_READY: + hp->PortState = HBA_PORTSTATE_ONLINE; + break; + default: + hp->PortState = HBA_PORTSTATE_ERROR; + break; + } + } + cnt = binfo->fc_map_cnt + binfo->fc_unmap_cnt; + hp->NumberofDiscoveredPorts = cnt; + if (hsp->cls1.classValid) { + hp->PortSupportedClassofService |= 1; /* bit 1 */ + } + if (hsp->cls2.classValid) { + hp->PortSupportedClassofService |= 2; /* bit 2 */ + } + if (hsp->cls3.classValid) { + hp->PortSupportedClassofService |= 4; /* bit 3 */ + } + hp->PortMaxFrameSize = (((uint32)hsp->cmn.bbRcvSizeMsb) << 8) | + (uint32)hsp->cmn.bbRcvSizeLsb; + + hp->PortSupportedFc4Types.bits[2] = 0x1; + hp->PortSupportedFc4Types.bits[3] = 0x20; + hp->PortSupportedFc4Types.bits[7] = 0x1; + if(clp[CFG_FCP_ON].a_current) { + hp->PortActiveFc4Types.bits[2] = 0x1; + } + if(clp[CFG_NETWORK_ON].a_current) { + hp->PortActiveFc4Types.bits[3] = 0x20; + } + hp->PortActiveFc4Types.bits[7] = 0x1; + + + /* OSDeviceName is the device info filled into the HBA_OSDN structure */ + osdn = (HBA_OSDN *)&hp->OSDeviceName[0]; + fc_bcopy("lpfc", osdn->drvname, 4); + osdn->instance = fc_brd_to_inst(binfo->fc_brd_no); + osdn->target = (HBA_UINT32)(-1); + osdn->lun = (HBA_UINT32)(-1); + + } + break; + + case C_HBA_PORTSTATISTICS: + { + HBA_PORTSTATISTICS * hs; + FCCLOCK_INFO * clock_info; + + hs = (HBA_PORTSTATISTICS *)dm->fc_dataout; + fc_bzero(dm->fc_dataout, (sizeof(HBA_PORTSTATISTICS))); + + mb = (MAILBOX * )mbox; + fc_read_status(binfo, mb); + mb->un.varRdStatus.clrCounters = 0; + if(dfc_issue_mbox(p_dev_ctl, mb, &ipri)) { + rc = ENODEV; + break; + } + hs->TxFrames = mb->un.varRdStatus.xmitFrameCnt; + hs->RxFrames = mb->un.varRdStatus.rcvFrameCnt; + /* Convert KBytes to words */ + hs->TxWords = (mb->un.varRdStatus.xmitByteCnt * 256); + hs->RxWords = (mb->un.varRdStatus.rcvbyteCnt * 256); + fc_read_lnk_stat(binfo, mb); + if(dfc_issue_mbox(p_dev_ctl, mb, &ipri)) { + rc = ENODEV; + break; + } + hs->LinkFailureCount = mb->un.varRdLnk.linkFailureCnt; + hs->LossOfSyncCount = mb->un.varRdLnk.lossSyncCnt; + hs->LossOfSignalCount = mb->un.varRdLnk.lossSignalCnt; + hs->PrimitiveSeqProtocolErrCount = mb->un.varRdLnk.primSeqErrCnt; + hs->InvalidTxWordCount = mb->un.varRdLnk.invalidXmitWord; + hs->InvalidCRCCount = mb->un.varRdLnk.crcCnt; + hs->ErrorFrames = mb->un.varRdLnk.crcCnt; + + if (binfo->fc_topology == TOPOLOGY_LOOP) { + hs->LIPCount = (binfo->fc_eventTag >> 1); + hs->NOSCount = -1; + } + else { + hs->LIPCount = -1; + hs->NOSCount = (binfo->fc_eventTag >> 1); + } + + hs->DumpedFrames = -1; + clock_info = &DD_CTL.fc_clock_info; + hs->SecondsSinceLastReset = clock_info->ticks; + + } + break; + + case C_HBA_WWPNPORTATRIBUTES: + { + HBA_WWN findwwn; + + hp = (HBA_PORTATTRIBUTES *)dm->fc_dataout; + vp = &VPD; + fc_bzero(dm->fc_dataout, (sizeof(HBA_PORTATTRIBUTES))); + + dfc_unlock_enable(ipri, &CMD_LOCK); + if (fc_copyin((uchar *)cip->c_arg1, (uchar *)&findwwn, (ulong)(sizeof(HBA_WWN)))) { + ipri = dfc_disable_lock(FC_LVL, &CMD_LOCK); + rc = EIO; + break; + } + ipri = dfc_disable_lock(FC_LVL, &CMD_LOCK); + + /* First Mapped ports, then unMapped ports */ + nlp = binfo->fc_nlpmap_start; + if(nlp == (NODELIST *)&binfo->fc_nlpmap_start) + nlp = binfo->fc_nlpunmap_start; + while(nlp != (NODELIST *)&binfo->fc_nlpunmap_start) { + if (fc_geportname(&nlp->nlp_portname, (NAME_TYPE *)&findwwn) == 2) + goto foundit; + nlp = (NODELIST *)nlp->nlp_listp_next; + if(nlp == (NODELIST *)&binfo->fc_nlpmap_start) + nlp = binfo->fc_nlpunmap_start; + } + rc = ERANGE; + break; + } + + case C_HBA_DISCPORTATRIBUTES: + { + SERV_PARM * hsp; + MATCHMAP * mp; + HBA_OSDN * osdn; + uint32 refresh; + + vp = &VPD; + hp = (HBA_PORTATTRIBUTES *)dm->fc_dataout; + fc_bzero(dm->fc_dataout, (sizeof(HBA_PORTATTRIBUTES))); + offset = (uint32)((ulong)cip->c_arg2); + refresh = (uint32)((ulong)cip->c_arg3); + if(refresh != binfo->nlptimer) { + hp->PortFcId = 0xffffffff; + break; + } + cnt = 0; + /* First Mapped ports, then unMapped ports */ + nlp = binfo->fc_nlpmap_start; + if(nlp == (NODELIST *)&binfo->fc_nlpmap_start) + nlp = binfo->fc_nlpunmap_start; + while(nlp != (NODELIST *)&binfo->fc_nlpunmap_start) { + if(cnt == offset) + goto foundit; + cnt++; + nlp = (NODELIST *)nlp->nlp_listp_next; + if(nlp == (NODELIST *)&binfo->fc_nlpmap_start) + nlp = binfo->fc_nlpunmap_start; + } + rc = ERANGE; + break; + +foundit: + /* Check if its the local port */ + if(binfo->fc_myDID == nlp->nlp_DID) { + goto localport; + } + + mb = (MAILBOX * )mbox; + fc_read_rpi(binfo, (uint32)nlp->nlp_Rpi, + (MAILBOX * )mb, (uint32)0); + + if ((mp = (MATCHMAP * )fc_mem_get(binfo, MEM_BUF)) == 0) { + rc = ENOMEM; + break; + } + hsp = (SERV_PARM *)mp->virt; + if (binfo->fc_flag & FC_SLI2) { + mb->un.varRdRPI.un.sp64.addrHigh = + (uint32)putPaddrHigh(mp->phys); + mb->un.varRdRPI.un.sp64.addrLow = + (uint32)putPaddrLow(mp->phys); + mb->un.varRdRPI.un.sp64.tus.f.bdeSize = sizeof(SERV_PARM); + } + else { + mb->un.varRdRPI.un.sp.bdeAddress = + (uint32)putPaddrLow(mp->phys); + mb->un.varRdRPI.un.sp.bdeSize = sizeof(SERV_PARM); + } + + if(dfc_issue_mbox(p_dev_ctl, mb, &ipri)) { + rc = ENODEV; + break; + } + + if (hsp->cls1.classValid) { + hp->PortSupportedClassofService |= 1; /* bit 1 */ + } + if (hsp->cls2.classValid) { + hp->PortSupportedClassofService |= 2; /* bit 2 */ + } + if (hsp->cls3.classValid) { + hp->PortSupportedClassofService |= 4; /* bit 3 */ + } + hp->PortMaxFrameSize = (((uint32)hsp->cmn.bbRcvSizeMsb) << 8) | + (uint32)hsp->cmn.bbRcvSizeLsb; + + fc_mem_put(binfo, MEM_BUF, (uchar * )mp); + + fc_bcopy((uchar * )&nlp->nlp_nodename, (uchar * )&hp->NodeWWN, + sizeof(HBA_WWN)); + fc_bcopy((uchar * )&nlp->nlp_portname, (uchar * )&hp->PortWWN, + sizeof(HBA_WWN)); + + hp->PortSpeed = 0; + if(((binfo->fc_myDID & 0xffff00) == (nlp->nlp_DID & 0xffff00)) && + (binfo->fc_topology == TOPOLOGY_LOOP)) { + if( binfo->fc_linkspeed == LA_2GHZ_LINK) + hp->PortSpeed = HBA_PORTSPEED_2GBIT; + else + hp->PortSpeed = HBA_PORTSPEED_1GBIT; + } + + hp->PortFcId = nlp->nlp_DID; + if((binfo->fc_flag & FC_FABRIC) && + ((binfo->fc_myDID & 0xff0000) == (nlp->nlp_DID & 0xff0000))) { + fc_bcopy((uchar * )&binfo->fc_fabparam.nodeName, + (uchar * )&hp->FabricName, sizeof(HBA_WWN)); + } + hp->PortState = HBA_PORTSTATE_ONLINE; + if (nlp->nlp_type & NLP_FCP_TARGET) { + hp->PortActiveFc4Types.bits[2] = 0x1; + } + if (nlp->nlp_type & NLP_IP_NODE) { + hp->PortActiveFc4Types.bits[3] = 0x20; + } + hp->PortActiveFc4Types.bits[7] = 0x1; + + hp->PortType = HBA_PORTTYPE_UNKNOWN; + if (binfo->fc_topology == TOPOLOGY_LOOP) { + if(binfo->fc_flag & FC_PUBLIC_LOOP) { + /* Check if Fabric port */ + if (fc_geportname(&nlp->nlp_nodename, (NAME_TYPE *)&(binfo->fc_fabparam.nodeName)) == 2) { + hp->PortType = HBA_PORTTYPE_FLPORT; + } + else { + /* Based on DID */ + if((nlp->nlp_DID & 0xff) == 0) { + hp->PortType = HBA_PORTTYPE_NPORT; + } + else { + if((nlp->nlp_DID & 0xff0000) != 0xff0000) { + hp->PortType = HBA_PORTTYPE_NLPORT; + } + } + } + } + else { + hp->PortType = HBA_PORTTYPE_LPORT; + } + } + else { + if(binfo->fc_flag & FC_FABRIC) { + /* Check if Fabric port */ + if (fc_geportname(&nlp->nlp_nodename, (NAME_TYPE *)&(binfo->fc_fabparam.nodeName)) == 2) { + hp->PortType = HBA_PORTTYPE_FPORT; + } + else { + /* Based on DID */ + if((nlp->nlp_DID & 0xff) == 0) { + hp->PortType = HBA_PORTTYPE_NPORT; + } + else { + if((nlp->nlp_DID & 0xff0000) != 0xff0000) { + hp->PortType = HBA_PORTTYPE_NLPORT; + } + } + } + } + else { + hp->PortType = HBA_PORTTYPE_PTP; + } + } + + /* for mapped devices OSDeviceName is device info filled into HBA_OSDN structure */ + if(nlp->nlp_flag & NLP_MAPPED) { + osdn = (HBA_OSDN *)&hp->OSDeviceName[0]; + fc_bcopy("lpfc", osdn->drvname, 4); + osdn->instance = fc_brd_to_inst(binfo->fc_brd_no); + osdn->target = FC_SCSID(nlp->id.nlp_pan, nlp->id.nlp_sid); + osdn->lun = (HBA_UINT32)(-1); + } + + } + break; + + case C_HBA_INDEXPORTATRIBUTES: + { + uint32 refresh; + + vp = &VPD; + hp = (HBA_PORTATTRIBUTES *)dm->fc_dataout; + fc_bzero(dm->fc_dataout, (sizeof(HBA_PORTATTRIBUTES))); + offset = (uint32)((ulong)cip->c_arg2); + refresh = (uint32)((ulong)cip->c_arg3); + if(refresh != binfo->nlptimer) { + hp->PortFcId = 0xffffffff; + break; + } + cnt = 0; + /* Mapped NPorts only */ + nlp = binfo->fc_nlpmap_start; + while(nlp != (NODELIST *)&binfo->fc_nlpmap_start) { + if(cnt == offset) + goto foundit; + cnt++; + nlp = (NODELIST *)nlp->nlp_listp_next; + } + rc = ERANGE; + } + break; + + case C_HBA_SETMGMTINFO: + { + HBA_MGMTINFO *mgmtinfo; + + mgmtinfo = (HBA_MGMTINFO *)dfc.dfc_buffer; + + dfc_unlock_enable(ipri, &CMD_LOCK); + if (fc_copyin((uchar *)cip->c_arg1, (uchar *)mgmtinfo, sizeof(HBA_MGMTINFO))) { + ipri = dfc_disable_lock(FC_LVL, &CMD_LOCK); + rc = EIO; + break; + } + ipri = dfc_disable_lock(FC_LVL, &CMD_LOCK); + + binfo->ipVersion = mgmtinfo->IPVersion; + binfo->UDPport = mgmtinfo->UDPPort; + if(binfo->ipVersion == RNID_IPV4) { + fc_bcopy((uchar *)&mgmtinfo->IPAddress[0], + (uchar * )&binfo->ipAddr[0], 4); + } + else { + fc_bcopy((uchar *)&mgmtinfo->IPAddress[0], + (uchar * )&binfo->ipAddr[0], 16); + } + } + break; + + case C_HBA_GETMGMTINFO: + { + HBA_MGMTINFO *mgmtinfo; + + mgmtinfo = (HBA_MGMTINFO *)dm->fc_dataout; + fc_bcopy((uchar * )&binfo->fc_nodename, (uchar *)&mgmtinfo->wwn, 8); + mgmtinfo->unittype = RNID_HBA; + mgmtinfo->PortId = binfo->fc_myDID; + mgmtinfo->NumberOfAttachedNodes = 0; + mgmtinfo->TopologyDiscoveryFlags = 0; + mgmtinfo->IPVersion = binfo->ipVersion; + mgmtinfo->UDPPort = binfo->UDPport; + if(binfo->ipVersion == RNID_IPV4) { + fc_bcopy((void *) & binfo->ipAddr[0], + (void *) & mgmtinfo->IPAddress[0], 4); + } + else { + fc_bcopy((void *) & binfo->ipAddr[0], + (void *) & mgmtinfo->IPAddress[0], 16); + } + } + break; + + case C_HBA_REFRESHINFO: + { + lptr = (uint32 *)dm->fc_dataout; + *lptr = binfo->nlptimer; + } + break; + + case C_HBA_RNID: + ipri = dfc_hba_rnid( p_dev_ctl, dm, cip, infop, buf_info, ipri); + break; + + case C_HBA_GETEVENT: + { + HBA_UINT32 outsize; + HBAEVENT *rec; + HBAEVENT *recout; + + size = (uint32)((ulong)cip->c_arg1); /* size is number of event entries */ + + recout = (HBAEVENT * )dm->fc_dataout; + for(j=0;jhba_event_get == p_dev_ctl->hba_event_put)) + break; + rec = &p_dev_ctl->hbaevent[p_dev_ctl->hba_event_get]; + fc_bcopy((uchar * )rec, (uchar *)recout, sizeof(HBAEVENT)); + recout++; + p_dev_ctl->hba_event_get++; + if(p_dev_ctl->hba_event_get >= MAX_HBAEVENT) { + p_dev_ctl->hba_event_get = 0; + } + } + outsize = j; + + /* copy back size of response */ + dfc_unlock_enable(ipri, &CMD_LOCK); + if (fc_copyout((uchar *)&outsize, (uchar *)cip->c_arg2, sizeof(HBA_UINT32))) { + ipri = dfc_disable_lock(FC_LVL, &CMD_LOCK); + rc = EIO; + break; + } + /* copy back number of missed records */ + if (fc_copyout((uchar *)&p_dev_ctl->hba_event_missed, (uchar *)cip->c_arg3, sizeof(HBA_UINT32))) { + ipri = dfc_disable_lock(FC_LVL, &CMD_LOCK); + rc = EIO; + break; + } + ipri = dfc_disable_lock(FC_LVL, &CMD_LOCK); + + p_dev_ctl->hba_event_missed = 0; + infop->c_outsz = (uint32)(outsize * sizeof(HBA_EVENTINFO)); + } + + break; + + case C_HBA_FCPTARGETMAPPING: + ipri = dfc_hba_targetmapping(p_dev_ctl, dm, cip, infop, ipri); + break; + + case C_HBA_FCPBINDING: + ipri = dfc_hba_fcpbind(p_dev_ctl, dm, cip, infop, ipri); + break; + + case C_GETCFG: + { + CfgParam * cp; + iCfgParam * icp; + + /* First uint32 word will be count */ + cp = (CfgParam *)dm->fc_dataout; + cnt = 0; + for (i = 0; i < NUM_CFG_PARAM; i++) { + icp = &clp[i]; + cp->a_low = icp->a_low; + cp->a_hi = icp->a_hi; + cp->a_flag = icp->a_flag; + cp->a_default = icp->a_default; + cp->a_current = icp->a_current; + cp->a_changestate = icp->a_changestate; + fc_bcopy(icp->a_string, cp->a_string, 32); + fc_bcopy(icp->a_help, cp->a_help, 80); + cp++; + cnt++; + } + if(cnt) { + infop->c_outsz = (uint32)(cnt * sizeof(CfgParam)); + } + } + break; + + case C_SETCFG: + { + RING * rp; + iCfgParam * icp; + + offset = (uint32)((ulong)cip->c_arg1); + cnt = (uint32)((ulong)cip->c_arg2); + if (offset >= NUM_CFG_PARAM) { + rc = ERANGE; + break; + } + icp = &clp[offset]; + if(icp->a_changestate != CFG_DYNAMIC) { + rc = EPERM; + break; + } + if (((icp->a_low != 0) && (cnt < icp->a_low)) || (cnt > icp->a_hi)) { + rc = ERANGE; + break; + } + switch(offset) { + case CFG_FCP_CLASS: + switch (cnt) { + case 1: + clp[CFG_FCP_CLASS].a_current = CLASS1; + break; + case 2: + clp[CFG_FCP_CLASS].a_current = CLASS2; + break; + case 3: + clp[CFG_FCP_CLASS].a_current = CLASS3; + break; + } + icp->a_current = cnt; + break; + + case CFG_IP_CLASS: + switch (cnt) { + case 1: + clp[CFG_IP_CLASS].a_current = CLASS1; + break; + case 2: + clp[CFG_IP_CLASS].a_current = CLASS2; + break; + case 3: + clp[CFG_IP_CLASS].a_current = CLASS3; + break; + } + icp->a_current = cnt; + break; + + case CFG_LINKDOWN_TMO: + icp->a_current = cnt; + rp = &binfo->fc_ring[FC_FCP_RING]; + if(clp[CFG_LINKDOWN_TMO].a_current) { + rp->fc_ringtmo = clp[CFG_LINKDOWN_TMO].a_current; + } + break; + + default: + icp->a_current = cnt; + } + } + break; + + case C_GET_EVENT: + { + fcEvent *ep; + fcEvent *oep; + fcEvent_header *ehp; + uchar *cp; + MATCHMAP *omm; + int no_more; + + no_more = 1; + + offset = ((uint32)((ulong)cip->c_arg3) & FC_REG_EVENT_MASK); /* event mask */ + incr = (uint32)cip->c_flag; /* event id */ + size = (uint32)cip->c_iocb; /* process requesting event */ + ehp = (fcEvent_header *)p_dev_ctl->fc_evt_head; + while (ehp) { + if (ehp->e_mask == offset) + break; + ehp = (fcEvent_header *)ehp->e_next_header; + } + + if (!ehp) { + rc = ENOENT; + break; + } + + ep = ehp->e_head; + oep = 0; + while(ep) { + /* Find an event that matches the event mask */ + if(ep->evt_sleep == 0) { + /* dequeue event from event list */ + if(oep == 0) { + ehp->e_head = ep->evt_next; + } else { + oep->evt_next = ep->evt_next; + } + if(ehp->e_tail == ep) + ehp->e_tail = oep; + + switch(offset) { + case FC_REG_LINK_EVENT: + break; + case FC_REG_RSCN_EVENT: + /* Return data length */ + cnt = sizeof(uint32); + + dfc_unlock_enable(ipri, &CMD_LOCK); + if (fc_copyout((uchar *)&cnt, (uchar *)cip->c_arg1, sizeof(uint32))) { + ipri = dfc_disable_lock(FC_LVL, &CMD_LOCK); + rc = EIO; + } + ipri = dfc_disable_lock(FC_LVL, &CMD_LOCK); + + fc_bcopy((char *)&ep->evt_data0, dm->fc_dataout, cnt); + infop->c_outsz = (uint32)cnt; + break; + case FC_REG_CT_EVENT: + /* Return data length */ + cnt = (ulong)(ep->evt_data2); + + dfc_unlock_enable(ipri, &CMD_LOCK); + if (fc_copyout((uchar *)&cnt, (uchar *)cip->c_arg1, sizeof(uint32))) { + rc = EIO; + } + else { + if (fc_copyout((uchar *)&ep->evt_data0, (uchar *)cip->c_arg2, + sizeof(uint32))) { + rc = EIO; + } + } + ipri = dfc_disable_lock(FC_LVL, &CMD_LOCK); + + infop->c_outsz = (uint32)cnt; + i = cnt; + mm = (MATCHMAP * )ep->evt_data1; + cp = (uchar *)dm->fc_dataout; + while(mm) { + + if(cnt > FCELSSIZE) + i = FCELSSIZE; + else + i = cnt; + + if(total_mem > 0) { + fc_bcopy((char *)mm->virt, cp, i); + total_mem -= i; + } + + omm = mm; + mm = (MATCHMAP *)mm->fc_mptr; + cp += i; + fc_mem_put(binfo, MEM_BUF, (uchar * )omm); + } + break; + } + + if((offset == FC_REG_CT_EVENT) && (ep->evt_next) && + (((fcEvent *)(ep->evt_next))->evt_sleep == 0)) { + ep->evt_data0 |= 0x80000000; /* More event is waiting */ + if (fc_copyout((uchar *)&ep->evt_data0, (uchar *)cip->c_arg2, + sizeof(uint32))) { + rc = EIO; + } + no_more = 0; + } + + /* Requeue event entry */ + ep->evt_next = 0; + ep->evt_data0 = 0; + ep->evt_data1 = 0; + ep->evt_data2 = 0; + ep->evt_sleep = 1; + ep->evt_flags = 0; + + if(ehp->e_head == 0) { + ehp->e_head = ep; + ehp->e_tail = ep; + } + else { + ehp->e_tail->evt_next = ep; + ehp->e_tail = ep; + } + + if(offset == FC_REG_LINK_EVENT) { + ehp->e_flag &= ~E_GET_EVENT_ACTIVE; + goto linfo; + } + + dfc_unlock_enable(ipri, &CMD_LOCK); + if (fc_copyout((char *)dm->fc_dataout, infop->c_dataout, (int)infop->c_outsz)) { + rc = EIO; + } + dfc_data_free(p_dev_ctl, dm); + + ipri = dfc_disable_lock(FC_LVL, &CMD_LOCK); + if (no_more) + ehp->e_flag &= ~E_GET_EVENT_ACTIVE; + di->fc_refcnt--; + dfc_unlock_enable(ipri, &CMD_LOCK); + + return (rc); + } + oep = ep; + ep = ep->evt_next; + } + if(ep == 0) { + /* No event found */ + rc = ENOENT; + } + } + break; + + case C_SET_EVENT: + ipri = dfc_hba_set_event(p_dev_ctl, dm, cip, infop, ipri); + break; + + default: + rc = EINVAL; + break; + } + +out: + /* dfc_ioctl exit */ + fc_log_printf_msg_vargs( binfo->fc_brd_no, + &fc_msgBlk0401, /* ptr to msg structure */ + fc_mes0401, /* ptr to msg */ + fc_msgBlk0401.msgPreambleStr, /* begin varargs */ + rc, + infop->c_outsz, + (uint32)((ulong)infop->c_dataout)); /* end varargs */ + + di->fc_refcnt--; + dfc_unlock_enable(ipri, &CMD_LOCK); + + /* Copy data to user space config method */ + if ((rc == 0) || (do_cp == 1)) { + if (infop->c_outsz) { + if (fc_copyout((char *)dm->fc_dataout, infop->c_dataout, (int)infop->c_outsz)) { + rc = EIO; + } + } + } + + /* Now free the space for these structures */ + dmdata_info->virt = (struct dfc_mem *)dm; + dmdata_info->phys = 0; + dmdata_info->flags = (FC_MBUF_IOCTL | FC_MBUF_UNLOCK); + dmdata_info->size = sizeof(* dm); + dmdata_info->dma_handle = 0; + dmdata_info->data_handle = 0; + fc_free(p_dev_ctl, dmdata_info); + + mbox_info->virt = (char *)mbox; + mbox_info->phys = 0; + mbox_info->flags = (FC_MBUF_IOCTL | FC_MBUF_UNLOCK); + mbox_info->size = sizeof(* mbox); + mbox_info->dma_handle = 0; + mbox_info->data_handle = 0; + fc_free(p_dev_ctl, mbox_info); + + dfc_data_free(p_dev_ctl, dm); + return (rc); +} + + +uint32 +dfc_getLunId( +node_t *nodep, uint32 lunIndex) +{ + static uint32 lun; + static int i; + static dvi_t *dev_ptr; + static FCP_CMND *tmp; + + tmp = (FCP_CMND *)nodep->virtRptLunData; + + if(tmp == 0) { + dev_ptr = nodep->lunlist; + lun = dev_ptr->lun_id; + } else { + i = (lunIndex + 1) * 8; + tmp = (FCP_CMND *)(((uchar *)nodep->virtRptLunData) + i); + lun = ((tmp->fcpLunMsl >> FC_LUN_SHIFT) & 0xff); + } + return lun; +} + +_static_ int +dfc_bcopy( +uint32 *lsrc, +uint32 *ldest, +int cnt, +int incr) +{ + static ushort * ssrc; + static ushort * sdest; + static uchar * csrc; + static uchar * cdest; + static int i; + + csrc = (uchar * )lsrc; + cdest = (uchar * )ldest; + ssrc = (ushort * )lsrc; + sdest = (ushort * )ldest; + + for (i = 0; i < cnt; i += incr) { + if (incr == sizeof(char)) { + *cdest++ = *csrc++; + } else if (incr == sizeof(short)) { + *sdest++ = *ssrc++; + } else { + *ldest++ = *lsrc++; + } + } + return(0); +} + + +_static_ fc_dev_ctl_t * +dfc_getpdev( +struct cmd_input *ci) +{ + static fc_dev_ctl_t * p_dev_ctl;/* pointer to dev_ctl area */ + static FC_BRD_INFO * binfo; + + p_dev_ctl = DD_CTL.p_dev[ci->c_brd]; + binfo = &BINFO; + + if (p_dev_ctl == 0) { + return(0); + } + + /* Make sure command specified ring is within range */ + if (ci->c_ring >= binfo->fc_ffnumrings) { + return(0); + } + + return(p_dev_ctl); +} + + +_static_ int +fc_inst_to_brd( +int ddiinst) +{ + int i; + + for (i = 0; i < fcinstcnt; i++) + if (fcinstance[i] == ddiinst) + return(i); + + return(MAX_FC_BRDS); +} + + +_static_ int +dfc_msdelay( +fc_dev_ctl_t * p_dev_ctl, +ulong ms) +{ + DELAYMSctx(ms); + return(0); +} + +_local_ int +dfc_issue_mbox( +fc_dev_ctl_t * p_dev_ctl, +MAILBOX * mb, +ulong * ipri) +{ + static int j; + static MAILBOX * mbslim; + static FC_BRD_INFO * binfo; + static iCfgParam * clp; + struct dfc_info * di; + static volatile uint32 word0, ldata; + static uint32 ha_copy; + static void * ioa; + + binfo = &BINFO; + clp = DD_CTL.p_config[binfo->fc_brd_no]; + di = &dfc.dfc_info[binfo->fc_brd_no]; + if (binfo->fc_ffstate == FC_ERROR) { + mb->mbxStatus = MBXERR_ERROR; + return(1); + } + j = 0; + while((binfo->fc_mbox_active) || (di->fc_flag & DFC_MBOX_ACTIVE)) { + dfc_unlock_enable(*ipri, &CMD_LOCK); + + if (j < 10) { + dfc_msdelay(p_dev_ctl, 1); + } else { + dfc_msdelay(p_dev_ctl, 50); + } + + *ipri = dfc_disable_lock(FC_LVL, &CMD_LOCK); + if (j++ >= 600) { + mb->mbxStatus = MBXERR_ERROR; + return(1); + } + } + binfo->fc_mbox_active = 2; + di->fc_flag |= DFC_MBOX_ACTIVE; + +retrycmd: + /* next set own bit for the adapter and copy over command word */ + mb->mbxOwner = OWN_CHIP; + + if ((binfo->fc_flag & FC_SLI2) && (!(binfo->fc_flag & FC_OFFLINE_MODE))) { + /* First copy command data */ + mbslim = FC_SLI2_MAILBOX(binfo); + fc_pcimem_bcopy((uint32 * )mb, (uint32 * )mbslim, + (sizeof(uint32) * (MAILBOX_CMD_WSIZE))); + } else { + /* First copy command data */ + ioa = (void *)FC_MAP_MEM(&di->fc_iomap_mem); /* map in SLIM */ + mbslim = FC_MAILBOX(binfo, ioa); + WRITE_SLIM_COPY(binfo, &mb->un.varWords, &mbslim->un.varWords, + (MAILBOX_CMD_WSIZE - 1)); + + /* copy over last word, with mbxOwner set */ + ldata = *((volatile uint32 * )mb); + + + WRITE_SLIM_ADDR(binfo, ((volatile uint32 * )mbslim), ldata); + FC_UNMAP_MEMIO(ioa); + } + + fc_bcopy((char *)(mb), (char *)&p_dev_ctl->dfcmb[0], + (sizeof(uint32) * (MAILBOX_CMD_WSIZE))); + + /* interrupt board to doit right away */ + ioa = (void *)FC_MAP_IO(&di->fc_iomap_io); /* map in io registers */ + WRITE_CSR_REG(binfo, FC_FF_REG(binfo, ioa), CA_MBATT); + FC_UNMAP_MEMIO(ioa); + + FCSTATCTR.issueMboxCmd++; + + if ((binfo->fc_flag & FC_SLI2) && (!(binfo->fc_flag & FC_OFFLINE_MODE))) { + /* First copy command data */ + word0 = p_dev_ctl->dfcmb[0]; + } else { + /* First copy command data */ + ioa = (void *)FC_MAP_MEM(&di->fc_iomap_mem); /* map in SLIM */ + mbslim = FC_MAILBOX(binfo, ioa); + word0 = READ_SLIM_ADDR(binfo, ((volatile uint32 * )mbslim)); + FC_UNMAP_MEMIO(ioa); + } + + ioa = (void *)FC_MAP_IO(&di->fc_iomap_io); /* map in io registers */ + ha_copy = READ_CSR_REG(binfo, FC_HA_REG(binfo, ioa)); + FC_UNMAP_MEMIO(ioa); + + /* Wait for command to complete */ + while (((word0 & OWN_CHIP) == OWN_CHIP) || !(ha_copy & HA_MBATT)) { + dfc_unlock_enable(*ipri, &CMD_LOCK); + + if ((j < 20) && (mb->mbxCommand != MBX_INIT_LINK)) { + dfc_msdelay(p_dev_ctl, 1); + } else { + dfc_msdelay(p_dev_ctl, 50); + } + + *ipri = dfc_disable_lock(FC_LVL, &CMD_LOCK); + if (j++ >= 600) { + mb->mbxStatus = MBXERR_ERROR; + binfo->fc_mbox_active = 0; + di->fc_flag &= ~DFC_MBOX_ACTIVE; + return(1); + } + + if ((binfo->fc_flag & FC_SLI2) && (!(binfo->fc_flag & FC_OFFLINE_MODE))) { + /* First copy command data */ + word0 = p_dev_ctl->dfcmb[0]; + } else { + /* First copy command data */ + ioa = (void *)FC_MAP_MEM(&di->fc_iomap_mem); /* map in SLIM */ + mbslim = FC_MAILBOX(binfo, ioa); + word0 = READ_SLIM_ADDR(binfo, ((volatile uint32 * )mbslim)); + FC_UNMAP_MEMIO(ioa); + } + ha_copy = HA_MBATT; + } + + mbslim = (MAILBOX * ) & word0; + if (mbslim->mbxCommand != mb->mbxCommand) { + j++; + if(mb->mbxCommand == MBX_INIT_LINK) { + /* Do not retry init_link's */ + mb->mbxStatus = 0; + binfo->fc_mbox_active = 0; + di->fc_flag &= ~DFC_MBOX_ACTIVE; + return(1); + } + goto retrycmd; + } + + /* copy results back to user */ + if ((binfo->fc_flag & FC_SLI2) && (!(binfo->fc_flag & FC_OFFLINE_MODE))) { + /* First copy command data */ + fc_bcopy((char *)&p_dev_ctl->dfcmb[0], (char *)mb, + (sizeof(uint32) * (MAILBOX_CMD_WSIZE))); + } else { + /* First copy command data */ + ioa = (void *)FC_MAP_MEM(&di->fc_iomap_mem); /* map in SLIM */ + mbslim = FC_MAILBOX(binfo, ioa); + /* copy results back to user */ + READ_SLIM_COPY(binfo, (uint32 * )mb, (uint32 * )mbslim, + MAILBOX_CMD_WSIZE); + FC_UNMAP_MEMIO(ioa); + } + + ioa = (void *)FC_MAP_IO(&di->fc_iomap_io); /* map in io registers */ + WRITE_CSR_REG(binfo, FC_HA_REG(binfo, ioa), HA_MBATT); + FC_UNMAP_MEMIO(ioa); + + + binfo->fc_mbox_active = 0; + di->fc_flag &= ~DFC_MBOX_ACTIVE; + + return(0); +} + +int +dfc_put_event( +fc_dev_ctl_t * p_dev_ctl, +uint32 evcode, +uint32 evdata0, +void * evdata1, +void * evdata2) +{ + static fcEvent *ep; + static fcEvent *oep; + static fcEvent_header *ehp = NULL; + static int found; + static MATCHMAP *mp; + static uint32 fstype; + static SLI_CT_REQUEST * ctp; + + ehp = (fcEvent_header *)p_dev_ctl->fc_evt_head; + + while (ehp) { + if (ehp->e_mask == evcode) + break; + ehp = (fcEvent_header *)ehp->e_next_header; + } + + if (!ehp) { + return (0); + } + + ep = ehp->e_head; + oep = 0; + found = 0; + + while(ep && (!found)) { + if(ep->evt_sleep) { + switch(evcode) { + case FC_REG_CT_EVENT: + mp = (MATCHMAP *)evdata1; + ctp = (SLI_CT_REQUEST *)mp->virt; + fstype = (uint32)(ctp->FsType); + if((ep->evt_type == FC_FSTYPE_ALL) || + (ep->evt_type == fstype)) { + found++; + ep->evt_data0 = evdata0; /* tag */ + ep->evt_data1 = evdata1; /* buffer ptr */ + ep->evt_data2 = evdata2; /* count */ + ep->evt_sleep = 0; + if ((ehp->e_mode & E_SLEEPING_MODE) && !(ehp->e_flag & E_GET_EVENT_ACTIVE)) { + ehp->e_flag |= E_GET_EVENT_ACTIVE; + dfc_wakeup(p_dev_ctl, ehp); + } + + } + break; + default: + found++; + ep->evt_data0 = evdata0; + ep->evt_data1 = evdata1; + ep->evt_data2 = evdata2; + ep->evt_sleep = 0; + if ((ehp->e_mode & E_SLEEPING_MODE) && !(ehp->e_flag & E_GET_EVENT_ACTIVE)) { + ehp->e_flag |= E_GET_EVENT_ACTIVE; + dfc_wakeup(p_dev_ctl, ehp); + } + break; + } + } + oep = ep; + ep = ep->evt_next; + } + return(found); +} + +int +dfc_wakeupall( +fc_dev_ctl_t * p_dev_ctl, +int flag) +{ + static fcEvent *ep; + static fcEvent *oep; + static fcEvent_header *ehp = NULL; + static int found; + + ehp = (fcEvent_header *)p_dev_ctl->fc_evt_head; + found = 0; + + while (ehp) { + ep = ehp->e_head; + oep = 0; + while(ep) { + ep->evt_sleep = 0; + if(flag) { + dfc_wakeup(p_dev_ctl, ehp); + } + else if (!(ehp->e_flag & E_GET_EVENT_ACTIVE)) { + found++; + ehp->e_flag |= E_GET_EVENT_ACTIVE; + dfc_wakeup(p_dev_ctl, ehp); + } + oep = ep; + ep = ep->evt_next; + } + ehp = (fcEvent_header *)ehp->e_next_header; + } + return(found); +} + +int +dfc_hba_put_event( +fc_dev_ctl_t * p_dev_ctl, +uint32 evcode, +uint32 evdata1, +uint32 evdata2, +uint32 evdata3, +uint32 evdata4) +{ + static HBAEVENT *rec; + static FC_BRD_INFO * binfo; + + binfo = &BINFO; + rec = &p_dev_ctl->hbaevent[p_dev_ctl->hba_event_put]; + rec->fc_eventcode = evcode; + + rec->fc_evdata1 = evdata1; + rec->fc_evdata2 = evdata2; + rec->fc_evdata3 = evdata3; + rec->fc_evdata4 = evdata4; + p_dev_ctl->hba_event_put++; + if(p_dev_ctl->hba_event_put >= MAX_HBAEVENT) { + p_dev_ctl->hba_event_put = 0; + } + if(p_dev_ctl->hba_event_put == p_dev_ctl->hba_event_get) { + p_dev_ctl->hba_event_missed++; + p_dev_ctl->hba_event_get++; + if(p_dev_ctl->hba_event_get >= MAX_HBAEVENT) { + p_dev_ctl->hba_event_get = 0; + } + } + + return(0); +} /* End dfc_hba_put_event */ + +int +dfc_hba_set_event( +fc_dev_ctl_t * p_dev_ctl, +struct dfc_mem *dm, +struct cmd_input *cip, +struct dfccmdinfo *infop, +ulong ipri) +{ + static fcEvent *evp; + static fcEvent *ep; + static fcEvent *oep; + static fcEvent_header *ehp; + static fcEvent_header *oehp; + static int found; + static MBUF_INFO * buf_info; + static MBUF_INFO bufinfo; + static uint32 offset; + static uint32 incr; + + offset = ((uint32)((ulong)cip->c_arg3) & FC_REG_EVENT_MASK); + incr = (uint32)cip->c_flag; + + switch(offset) { + case FC_REG_CT_EVENT: + found = fc_out_event; + break; + case FC_REG_RSCN_EVENT: + found = fc_out_event; + break; + case FC_REG_LINK_EVENT: + found = 2; + break; + default: + found = 0; + rc = EINTR; + return(ipri); + } + + oehp = 0; + ehp = (fcEvent_header *)p_dev_ctl->fc_evt_head; + while (ehp) { + if (ehp->e_mask == offset) { + found = 0; + break; + } + oehp = ehp; + ehp = (fcEvent_header *)ehp->e_next_header; + } + + if (!ehp) { + buf_info = &bufinfo; + buf_info->virt = 0; + buf_info->phys = 0; + buf_info->flags = (FC_MBUF_IOCTL | FC_MBUF_UNLOCK); + buf_info->align = sizeof(void *); + buf_info->size = sizeof(fcEvent_header); + buf_info->dma_handle = 0; + + dfc_unlock_enable(ipri, &CMD_LOCK); + fc_malloc(p_dev_ctl, buf_info); + ipri = dfc_disable_lock(FC_LVL, &CMD_LOCK); + if (buf_info->virt == NULL) { + rc = EINTR; + return(ipri); + } + ehp = (fcEvent_header *)(buf_info->virt); + fc_bzero((char *)ehp, sizeof(fcEvent_header)); + if(p_dev_ctl->fc_evt_head == 0) { + p_dev_ctl->fc_evt_head = ehp; + p_dev_ctl->fc_evt_tail = ehp; + } else { + ((fcEvent_header *)(p_dev_ctl->fc_evt_tail))->e_next_header = ehp; + p_dev_ctl->fc_evt_tail = (void *)ehp; + } + ehp->e_handle = incr; + ehp->e_mask = offset; + + } + + while(found) { + /* Save event id for C_GET_EVENT */ + buf_info = &bufinfo; + buf_info->virt = 0; + buf_info->phys = 0; + buf_info->flags = (FC_MBUF_IOCTL | FC_MBUF_UNLOCK); + buf_info->align = sizeof(void *); + buf_info->size = sizeof(fcEvent); + buf_info->dma_handle = 0; + + dfc_unlock_enable(ipri, &CMD_LOCK); + fc_malloc(p_dev_ctl, buf_info); + ipri = dfc_disable_lock(FC_LVL, &CMD_LOCK); + if (buf_info->virt == NULL) { + rc = EINTR; + break; + } + oep = (fcEvent *)(buf_info->virt); + fc_bzero((char *)oep, sizeof(fcEvent)); + + oep->evt_sleep = 1; + oep->evt_handle = incr; + oep->evt_mask = offset; + switch(offset) { + case FC_REG_CT_EVENT: + oep->evt_type = (uint32)((ulong)cip->c_arg2); /* fstype for CT */ + break; + default: + oep->evt_type = 0; + } + + if(ehp->e_head == 0) { + ehp->e_head = oep; + ehp->e_tail = oep; + } else { + ehp->e_tail->evt_next = (void *)oep; + ehp->e_tail = oep; + } + oep->evt_next = 0; + found--; + } + + switch(offset) { + case FC_REG_CT_EVENT: + case FC_REG_RSCN_EVENT: + case FC_REG_LINK_EVENT: + if(dfc_sleep(p_dev_ctl, ehp)) { + ipri = dfc_disable_lock(FC_LVL, &CMD_LOCK); + rc = EINTR; + /* Remove all eventIds from queue */ + ep = ehp->e_head; + oep = 0; + found = 0; + while(ep) { + if(ep->evt_handle == incr) { + /* dequeue event from event list */ + if(oep == 0) { + ehp->e_head = ep->evt_next; + } + else { + oep->evt_next = ep->evt_next; + } + if(ehp->e_tail == ep) + ehp->e_tail = oep; + evp = ep; + ep = ep->evt_next; + dfc_unlock_enable(ipri, &CMD_LOCK); + buf_info = &bufinfo; + buf_info->virt = (uchar *)evp; + buf_info->size = sizeof(fcEvent); + buf_info->phys = 0; + buf_info->flags = (FC_MBUF_IOCTL | FC_MBUF_UNLOCK); + buf_info->align = 0; + buf_info->dma_handle = 0; + fc_free(p_dev_ctl, buf_info); + ipri = dfc_disable_lock(FC_LVL, &CMD_LOCK); + } else { + oep = ep; + ep = ep->evt_next; + } + } + if (ehp->e_head == 0) { + + if (oehp == 0) { + p_dev_ctl->fc_evt_head = ehp->e_next_header; + } else { + oehp->e_next_header = ehp->e_next_header; + } + if (p_dev_ctl->fc_evt_tail == ehp) + p_dev_ctl->fc_evt_tail = oehp; + + dfc_unlock_enable(ipri, &CMD_LOCK); + buf_info = &bufinfo; + buf_info->virt = (uchar *)ehp; + buf_info->size = sizeof(fcEvent_header); + buf_info->phys = 0; + buf_info->flags = (FC_MBUF_IOCTL | FC_MBUF_UNLOCK); + buf_info->align = 0; + buf_info->dma_handle = 0; + fc_free(p_dev_ctl, buf_info); + ipri = dfc_disable_lock(FC_LVL, &CMD_LOCK); + } + return(ipri); + } + return(ipri); + } + return(ipri); +} + +int +dfc_hba_sendscsi_fcp( +fc_dev_ctl_t * p_dev_ctl, +struct dfc_mem *dm, +struct cmd_input *cip, +struct dfccmdinfo *infop, +ulong ipri) +{ + static HBA_WWN findwwn; + static DMATCHMAP * fcpmp; + static RING * rp; + static fc_buf_t * fcptr; + static FCP_CMND * fcpCmnd; + static FCP_RSP * fcpRsp; + static ULP_BDE64 * bpl; + static MATCHMAP * bmp; + static DMATCHMAP * outdmp; + static MBUF_INFO * buf_info; + static MBUF_INFO bufinfo; + static uint32 buf1sz; + static uint32 buf2sz; + static uint32 j; + static uint32 * lptr; + static char * bp; + static uint32 max; + static struct { + uint32 rspcnt; + uint32 snscnt; + } count; + static struct dev_info *dev_info; + static FC_BRD_INFO * binfo; + + binfo = &BINFO; + lptr = (uint32 *)&cip->c_string[0]; + buf1sz = *lptr++; /* Request data size */ + buf2sz = *lptr; /* Sns / rsp buffer size */ + if((buf1sz + infop->c_outsz) > (80 * 4096)) { + rc = ERANGE; + return(ipri); + } + + dfc_unlock_enable(ipri, &CMD_LOCK); + if (fc_copyin((uchar *)cip->c_arg3, (uchar *)&findwwn, (ulong)(sizeof(HBA_WWN)))) { + ipri = dfc_disable_lock(FC_LVL, &CMD_LOCK); + rc = EIO; + return(ipri); + } + + buf_info = &bufinfo; + buf_info->virt = 0; + buf_info->phys = 0; + buf_info->flags = (FC_MBUF_IOCTL | FC_MBUF_UNLOCK); + buf_info->align = sizeof(void *); + buf_info->size = sizeof(struct dev_info); + buf_info->dma_handle = 0; + + fc_malloc(p_dev_ctl, buf_info); + if (buf_info->virt == NULL) { + ipri = dfc_disable_lock(FC_LVL, &CMD_LOCK); + rc = ENOMEM; + return(ipri); + } + dev_info = (struct dev_info *)buf_info->virt; + + ipri = dfc_disable_lock(FC_LVL, &CMD_LOCK); + /* Allocate buffer for Buffer ptr list */ + if ((bmp = (MATCHMAP * )fc_mem_get(binfo, MEM_BPL)) == 0) { + rc = ENOMEM; + goto ssout3; + } + bpl = (ULP_BDE64 * )bmp->virt; + dfc_unlock_enable(ipri, &CMD_LOCK); + + if((fcpmp = dfc_fcp_data_alloc(p_dev_ctl, bpl)) == 0) { + ipri = dfc_disable_lock(FC_LVL, &CMD_LOCK); + fc_mem_put(binfo, MEM_BUF, (uchar * )bmp); + rc = ENOMEM; + goto ssout3; + } + bpl += 2; /* Cmnd and Rsp ptrs */ + fcpCmnd = (FCP_CMND *)fcpmp->dfc.virt; + fcpRsp = (FCP_RSP *)((uchar *)fcpCmnd + sizeof(FCP_CMND)); + +{ +lptr = (uint32 *)bmp->virt; +} + if (fc_copyin((uchar *)cip->c_arg1, (uchar *)fcpCmnd, (ulong)(buf1sz))) { + dfc_fcp_data_free(p_dev_ctl, fcpmp); + ipri = dfc_disable_lock(FC_LVL, &CMD_LOCK); + fc_mem_put(binfo, MEM_BUF, (uchar * )bmp); + rc = ENOMEM; + goto ssout3; + } +{ +lptr = (uint32 *)fcpCmnd; +} + fc_mpdata_sync(fcpmp->dfc.dma_handle, 0, 0, DDI_DMA_SYNC_FORDEV); + + if(fcpCmnd->fcpCntl3 == WRITE_DATA) { + bp = (uchar *)infop->c_dataout; + } + else { + bp = 0; + } + + if(infop->c_outsz == 0) + outdmp = dfc_cmd_data_alloc(p_dev_ctl, bp, bpl, 512); + else + outdmp = dfc_cmd_data_alloc(p_dev_ctl, bp, bpl, infop->c_outsz); + + if(!(outdmp)) { + dfc_fcp_data_free(p_dev_ctl, fcpmp); + ipri = dfc_disable_lock(FC_LVL, &CMD_LOCK); + fc_mem_put(binfo, MEM_BUF, (uchar * )bmp); + rc = ENOMEM; + goto ssout3; + } + + ipri = dfc_disable_lock(FC_LVL, &CMD_LOCK); + + max = 0; +redoss: +{ +lptr = (uint32 *)bmp->virt; +} + + if((rc=fc_snd_scsi_req(p_dev_ctl, (NAME_TYPE *)&findwwn, bmp, fcpmp, outdmp, infop->c_outsz, dev_info))) + { + if((rc == ENODEV) && (max < 4)) { + max++; + dfc_unlock_enable(ipri, &CMD_LOCK); + dfc_msdelay(p_dev_ctl, 500); + ipri = dfc_disable_lock(FC_LVL, &CMD_LOCK); + goto redoss; + } + if(rc == ENODEV) + rc = EACCES; + dfc_unlock_enable(ipri, &CMD_LOCK); + dfc_cmd_data_free(p_dev_ctl, outdmp); + dfc_fcp_data_free(p_dev_ctl, fcpmp); + ipri = dfc_disable_lock(FC_LVL, &CMD_LOCK); + fc_mem_put(binfo, MEM_BUF, (uchar * )bmp); + rc = ENOMEM; + goto ssout3; + } + + rp = &binfo->fc_ring[FC_FCP_RING]; + fcptr = (fc_buf_t *)fcpmp->dfc.virt; + + j = 0; + dfc_unlock_enable(ipri, &CMD_LOCK); + dfc_msdelay(p_dev_ctl, 1); + ipri = dfc_disable_lock(FC_LVL, &CMD_LOCK); + + /* Wait for FCP I/O to complete or timeout */ + while(dev_info->queue_state == ACTIVE_PASSTHRU) { + dfc_unlock_enable(ipri, &CMD_LOCK); + dfc_msdelay(p_dev_ctl, 50); + ipri = dfc_disable_lock(FC_LVL, &CMD_LOCK); + if(j >= 600) { + break; + } + j++; + } + + /* Check for timeout conditions */ + if(dev_info->queue_state == ACTIVE_PASSTHRU) { + /* Free resources */ + fc_deq_fcbuf_active(rp, fcptr->iotag); + rc = ETIMEDOUT; + dfc_unlock_enable(ipri, &CMD_LOCK); + dfc_cmd_data_free(p_dev_ctl, outdmp); + dfc_fcp_data_free(p_dev_ctl, fcpmp); + ipri = dfc_disable_lock(FC_LVL, &CMD_LOCK); + goto ssout3; + } + if ((infop->c_cmd == C_HBA_SEND_FCP) && + (dev_info->ioctl_event != IOSTAT_LOCAL_REJECT)) { + if(buf2sz < sizeof(FCP_RSP)) + count.snscnt = buf2sz; + else + count.snscnt = sizeof(FCP_RSP); +{ +lptr = (uint32 *)fcpRsp; +} + dfc_unlock_enable(ipri, &CMD_LOCK); + if (fc_copyout((uchar *)fcpRsp, (uchar *)cip->c_arg2, count.snscnt)) { + ipri = dfc_disable_lock(FC_LVL, &CMD_LOCK); + rc = EIO; + goto ssout0; + } + ipri = dfc_disable_lock(FC_LVL, &CMD_LOCK); + } + + switch(dev_info->ioctl_event) { + case IOSTAT_SUCCESS: +cpdata: + /* copy back response data */ + if(infop->c_outsz < dev_info->clear_count) { + infop->c_outsz = 0; + rc = ERANGE; + goto ssout0; + } + infop->c_outsz = dev_info->clear_count; + + if (infop->c_cmd == C_HBA_SEND_SCSI) { + count.rspcnt = infop->c_outsz; + count.snscnt = 0; + } else { + /* For C_HBA_SEND_FCP, snscnt is already set */ + count.rspcnt = infop->c_outsz; + } + + /* Return data length */ + dfc_unlock_enable(ipri, &CMD_LOCK); + if (fc_copyout((uchar *)&count, (uchar *)cip->c_arg3, (2*sizeof(uint32)))) { + ipri = dfc_disable_lock(FC_LVL, &CMD_LOCK); + rc = EIO; + goto ssout0; + } + + infop->c_outsz = 0; + if(count.rspcnt) { + if(dfc_rsp_data_copy(p_dev_ctl, (uchar *)infop->c_dataout, outdmp, count.rspcnt)) { + ipri = dfc_disable_lock(FC_LVL, &CMD_LOCK); + rc = EIO; + goto ssout0; + } + } + ipri = dfc_disable_lock(FC_LVL, &CMD_LOCK); + break; + case IOSTAT_LOCAL_REJECT: + infop->c_outsz = 0; + if(dev_info->ioctl_errno == IOERR_SEQUENCE_TIMEOUT) { + rc = ETIMEDOUT; + goto ssout0; + } + rc = EFAULT; + goto ssout0; + case IOSTAT_FCP_RSP_ERROR: + j = 0; + + if(fcpCmnd->fcpCntl3 == READ_DATA) { + dev_info->clear_count = infop->c_outsz - dev_info->clear_count; + if ((fcpRsp->rspStatus2 & RESID_UNDER) && + (dev_info->clear_count)) { + goto cpdata; + } + } + else + dev_info->clear_count = 0; + + count.rspcnt = (uint32)dev_info->clear_count; + infop->c_outsz = 0; + + if (fcpRsp->rspStatus2 & RSP_LEN_VALID) { + j = SWAP_DATA(fcpRsp->rspRspLen); + } + if (fcpRsp->rspStatus2 & SNS_LEN_VALID) { + if (infop->c_cmd == C_HBA_SEND_SCSI) { + if(buf2sz < (int)dev_info->sense_length) + count.snscnt = buf2sz; + else + count.snscnt = dev_info->sense_length; + + /* Return sense info from rsp packet */ + dfc_unlock_enable(ipri, &CMD_LOCK); + if (fc_copyout(((uchar *)&fcpRsp->rspInfo0) + j, + (uchar *)cip->c_arg2, count.snscnt)) { + ipri = dfc_disable_lock(FC_LVL, &CMD_LOCK); + rc = EIO; + goto ssout0; + } + ipri = dfc_disable_lock(FC_LVL, &CMD_LOCK); + } + } + else { + rc = EFAULT; + goto ssout0; + } + + /* Return data length */ + dfc_unlock_enable(ipri, &CMD_LOCK); + if (fc_copyout((uchar *)&count, (uchar *)cip->c_arg3, (2*sizeof(uint32)))) { + ipri = dfc_disable_lock(FC_LVL, &CMD_LOCK); + rc = EIO; + goto ssout0; + } + + /* return data for read */ + if(count.rspcnt) { + if(dfc_rsp_data_copy(p_dev_ctl, (uchar *)infop->c_dataout, outdmp, count.rspcnt)) { + ipri = dfc_disable_lock(FC_LVL, &CMD_LOCK); + rc = EIO; + goto ssout0; + } + } + ipri = dfc_disable_lock(FC_LVL, &CMD_LOCK); + break; + + default: + infop->c_outsz = 0; + rc = EFAULT; + goto ssout0; + } + +ssout0: + dfc_unlock_enable(ipri, &CMD_LOCK); + dfc_cmd_data_free(p_dev_ctl, outdmp); + dfc_fcp_data_free(p_dev_ctl, fcpmp); + ipri = dfc_disable_lock(FC_LVL, &CMD_LOCK); +ssout3: + dfc_unlock_enable(ipri, &CMD_LOCK); + buf_info->size = sizeof(struct dev_info); + buf_info->virt = (uint32 * )dev_info; + buf_info->phys = 0; + buf_info->flags = (FC_MBUF_IOCTL | FC_MBUF_UNLOCK); + + fc_free(p_dev_ctl, buf_info); + ipri = dfc_disable_lock(FC_LVL, &CMD_LOCK); + return(ipri); +} + +int +dfc_hba_fcpbind( +fc_dev_ctl_t * p_dev_ctl, +struct dfc_mem *dm, +struct cmd_input *cip, +struct dfccmdinfo *infop, +ulong ipri) +{ + static HBA_FCPBINDING * hb; + static HBA_FCPBINDINGENTRY *ep; + static uint32 room; + static uint32 total; + static uint32 lunIndex, totalLuns; /* these 2 vars are per target id */ + static uint32 lunId; /* what we get back at lunIndex in virtRptLunData */ + static int memsz, mapList; + static char *appPtr; + static uint32 cnt; + static node_t * nodep; + static dvi_t * dev_ptr; + static uint32 total_mem; + static uint32 offset, j; + static NODELIST * nlp; + static FC_BRD_INFO * binfo; + + binfo = &BINFO; + hb = (HBA_FCPBINDING *)dm->fc_dataout; + ep = &hb->entry[0]; + room = (uint32)((ulong)cip->c_arg1); + cnt = 0; + total = 0; + memsz = 0; + lunIndex = 0; + totalLuns = 0; + appPtr = ((char *)infop->c_dataout) + sizeof(ulong); + mapList = 1; + + /* First Mapped ports, then unMapped ports, then binding list */ + nlp = binfo->fc_nlpmap_start; + if(nlp == (NODELIST *)&binfo->fc_nlpmap_start) { + nlp = binfo->fc_nlpunmap_start; + mapList = 0; + } + if(nlp == (NODELIST *)&binfo->fc_nlpunmap_start) + nlp = binfo->fc_nlpbind_start; + while(nlp != (NODELIST *)&binfo->fc_nlpbind_start) { + + if (nlp->nlp_type & NLP_SEED_MASK) { + offset = FC_SCSID(nlp->id.nlp_pan, nlp->id.nlp_sid); + if(offset > MAX_FC_TARGETS) { + goto nextbind; + } + nodep = binfo->device_queue_hash[offset].node_ptr; + if(nodep) + dev_ptr = nodep->lunlist; + else + dev_ptr = 0; + + if((!nodep) || (!dev_ptr)) { + dev_ptr=fc_alloc_devp(p_dev_ctl, offset, 0); + nodep = dev_ptr->nodep; + } + + if(mapList) { + /* For devices on the map list, we need to issue REPORT_LUN + * in case the device's config has changed */ + nodep->rptlunstate = REPORT_LUN_ONGOING; + issue_report_lun(p_dev_ctl, dev_ptr, 0); + + j = 0; + dfc_unlock_enable(ipri, &CMD_LOCK); + dfc_msdelay(p_dev_ctl, 1); + ipri = dfc_disable_lock(FC_LVL, &CMD_LOCK); + + /* Wait for ReportLun request to complete or timeout */ + while(nodep->rptlunstate == REPORT_LUN_ONGOING) { + dfc_unlock_enable(ipri, &CMD_LOCK); + dfc_msdelay(p_dev_ctl, 50); + ipri = dfc_disable_lock(FC_LVL, &CMD_LOCK); + if(j >= 600) { + break; + } + j++; + } + if(nodep->rptlunstate == REPORT_LUN_ONGOING) { + break; + } + /* + * If nodep->virtRptLunData is null, then we just report 1 lun. + * If not null, we will report luns from virtRptLunData buffer. + */ + lunIndex = 0; + totalLuns = 1; + dev_ptr = 0; + if (nodep->virtRptLunData) { + uint32 *tmp; + tmp = (uint32*)nodep->virtRptLunData; + totalLuns = SWAP_DATA(*tmp) / 8; + } + } + + while(((mapList) && (lunIndex < totalLuns)) || + (dev_ptr)) { + if(mapList) { + lunId = dfc_getLunId(nodep, lunIndex); + dev_ptr = fc_find_lun(binfo, offset, lunId); + } else + lunId = dev_ptr->lun_id; + + if((mapList) || + ((dev_ptr) && (dev_ptr->opened))) + { + if(cnt < room) { + HBA_OSDN *osdn; + HBA_UINT32 fcpLun[2]; + if(total_mem - memsz < sizeof(HBA_FCPBINDINGENTRY)) { + dfc_unlock_enable(ipri, &CMD_LOCK); + fc_copyout((char *)(&hb->entry[0]), appPtr, memsz); + ipri = dfc_disable_lock(FC_LVL, &CMD_LOCK); + + appPtr = appPtr + memsz; + ep = &hb->entry[0]; + memsz = 0; + } + fc_bzero((void *)ep->ScsiId.OSDeviceName, 256); + if(nlp->nlp_flag & NLP_MAPPED) { + osdn = (HBA_OSDN *)&ep->ScsiId.OSDeviceName[0]; + fc_bcopy("lpfc", osdn->drvname, 4); + osdn->instance = fc_brd_to_inst(binfo->fc_brd_no); + osdn->target = FC_SCSID(nlp->id.nlp_pan, nlp->id.nlp_sid); + osdn->lun = (HBA_UINT32)(lunId); + } + + ep->ScsiId.ScsiTargetNumber = + FC_SCSID(nlp->id.nlp_pan, nlp->id.nlp_sid); + ep->ScsiId.ScsiOSLun = (HBA_UINT32)(lunId); + ep->ScsiId.ScsiBusNumber = 0; + + fc_bzero((char *)fcpLun, sizeof(HBA_UINT64)); + fcpLun[0] = (lunId << FC_LUN_SHIFT); + if (nodep->addr_mode == VOLUME_SET_ADDRESSING) { + fcpLun[0] |= SWAP_DATA(0x40000000); + } + fc_bcopy((char *)&fcpLun[0], (char *)&ep->FcpId.FcpLun, sizeof(HBA_UINT64)); + if (nlp->nlp_type & NLP_SEED_DID) { + ep->type = TO_D_ID; + ep->FcpId.FcId = nlp->nlp_DID; + ep->FcId = nlp->nlp_DID; + fc_bzero((uchar *)&ep->FcpId.PortWWN, sizeof(HBA_WWN)); + fc_bzero((uchar *)&ep->FcpId.NodeWWN, sizeof(HBA_WWN)); + } + else { + ep->type = TO_WWN; + ep->FcId = 0; + ep->FcpId.FcId = 0; + if (nlp->nlp_type & NLP_SEED_WWPN) + fc_bcopy(&nlp->nlp_portname, (uchar *)&ep->FcpId.PortWWN, sizeof(HBA_WWN)); + else + fc_bcopy(&nlp->nlp_nodename, (uchar *)&ep->FcpId.NodeWWN, sizeof(HBA_WWN)); + } + if (nlp->nlp_state == NLP_ALLOC) { + ep->FcpId.FcId = nlp->nlp_DID; + fc_bcopy(&nlp->nlp_portname, (uchar *)&ep->FcpId.PortWWN, sizeof(HBA_WWN)); + fc_bcopy(&nlp->nlp_nodename, (uchar *)&ep->FcpId.NodeWWN, sizeof(HBA_WWN)); + } + ep++; + cnt++; + memsz = memsz + sizeof(HBA_FCPBINDINGENTRY); + total++; + } + } + if(mapList) { + /* for map list, we want the while loop to go stricly + * based on lunIndex and totalLuns. */ + lunIndex++; + dev_ptr = 0; + } else + dev_ptr = dev_ptr->next; + } /* while loop */ + } + +nextbind: + nlp = (NODELIST *)nlp->nlp_listp_next; + if(nlp == (NODELIST *)&binfo->fc_nlpmap_start) { + nlp = binfo->fc_nlpunmap_start; + mapList = 0; + } + if(nlp == (NODELIST *)&binfo->fc_nlpunmap_start) + nlp = binfo->fc_nlpbind_start; + } + + dfc_unlock_enable(ipri, &CMD_LOCK); + fc_copyout((char *)(&hb->entry[0]), appPtr, memsz); + ipri = dfc_disable_lock(FC_LVL, &CMD_LOCK); + + hb->NumberOfEntries = (HBA_UINT32)total; + dfc_unlock_enable(ipri, &CMD_LOCK); + fc_copyout((char *)(&hb->NumberOfEntries), infop->c_dataout, sizeof(ulong)); + ipri = dfc_disable_lock(FC_LVL, &CMD_LOCK); + + infop->c_outsz = 0; + if (total > room) { + rc = ERANGE; + do_cp = 1; + } + return (ipri); +} + +int +dfc_hba_sendmgmt_ct( +fc_dev_ctl_t * p_dev_ctl, +struct dfc_mem *dm, +struct cmd_input *cip, +struct dfccmdinfo *infop, +ulong ipri) + +{ + static ULP_BDE64 * bpl; + static MATCHMAP * bmp; + static DMATCHMAP * indmp; + static DMATCHMAP * outdmp; + static uint32 portid; + static HBA_WWN findwwn; + static uint32 buf1sz; + static uint32 buf2sz; + static int j; + static uint32 max; + static uint32 incr; + static uint32 * lptr; + static NODELIST * nlp; + static FC_BRD_INFO * binfo; + + binfo = &BINFO; + incr = (uint32)cip->c_flag; /* timeout for CT request */ + lptr = (uint32 *)&cip->c_string[0]; + buf1sz = *lptr++; + buf2sz = *lptr; + + if((buf1sz == 0) || + (buf2sz == 0) || + (buf1sz + buf2sz > (80 * 4096))) { + rc = ERANGE; + return(ipri); + } + + dfc_unlock_enable(ipri, &CMD_LOCK); + + if(infop->c_cmd == C_SEND_MGMT_CMD) { + if (fc_copyin((uchar *)cip->c_arg3, (uchar *)&findwwn, (ulong)(sizeof(HBA_WWN)))) { + ipri = dfc_disable_lock(FC_LVL, &CMD_LOCK); + rc = EIO; + return(ipri); + } + ipri = dfc_disable_lock(FC_LVL, &CMD_LOCK); + + /* First Mapped ports, then unMapped ports */ + nlp = binfo->fc_nlpmap_start; + if(nlp == (NODELIST *)&binfo->fc_nlpmap_start) + nlp = binfo->fc_nlpunmap_start; + while(nlp != (NODELIST *)&binfo->fc_nlpunmap_start) { + if (fc_geportname(&nlp->nlp_portname, (NAME_TYPE *)&findwwn) == 2) + goto gotit; + nlp = (NODELIST *)nlp->nlp_listp_next; + if(nlp == (NODELIST *)&binfo->fc_nlpmap_start) + nlp = binfo->fc_nlpunmap_start; + } + rc = ERANGE; + return(ipri); +gotit: + portid = nlp->nlp_DID; + dfc_unlock_enable(ipri, &CMD_LOCK); + } + else { + portid = (uint32)((ulong)cip->c_arg3); + } + + ipri = dfc_disable_lock(FC_LVL, &CMD_LOCK); + /* Allocate buffer for Buffer ptr list */ + if ((bmp = (MATCHMAP * )fc_mem_get(binfo, MEM_BPL)) == 0) { + rc = ENOMEM; + return(ipri); + } + bpl = (ULP_BDE64 * )bmp->virt; + dfc_unlock_enable(ipri, &CMD_LOCK); + + if((indmp = dfc_cmd_data_alloc(p_dev_ctl, (uchar *)cip->c_arg1, bpl, buf1sz)) == 0) { + ipri = dfc_disable_lock(FC_LVL, &CMD_LOCK); + fc_mem_put(binfo, MEM_BPL, (uchar * )bmp); + rc = ENOMEM; + return(ipri); + } + bpl += indmp->dfc_flag; + + if((outdmp = dfc_cmd_data_alloc(p_dev_ctl, 0, bpl, buf2sz)) == 0) { + dfc_cmd_data_free(p_dev_ctl, indmp); + ipri = dfc_disable_lock(FC_LVL, &CMD_LOCK); + fc_mem_put(binfo, MEM_BPL, (uchar * )bmp); + rc = ENOMEM; + return(ipri); + } + + ipri = dfc_disable_lock(FC_LVL, &CMD_LOCK); + max = 0; +redoct: + if((rc=fc_issue_ct_req(binfo, portid, bmp, indmp, outdmp, incr))) { + if((rc == ENODEV) && (max < 4)) { + max++; + dfc_unlock_enable(ipri, &CMD_LOCK); + dfc_msdelay(p_dev_ctl, 500); + ipri = dfc_disable_lock(FC_LVL, &CMD_LOCK); + goto redoct; + } + if(rc == ENODEV) + rc = EACCES; + goto ctout1; + } + + j = 0; + dfc_unlock_enable(ipri, &CMD_LOCK); + dfc_msdelay(p_dev_ctl, 1); + ipri = dfc_disable_lock(FC_LVL, &CMD_LOCK); + + /* Wait for CT request to complete or timeout */ + while(outdmp->dfc_flag == 0) { + dfc_unlock_enable(ipri, &CMD_LOCK); + dfc_msdelay(p_dev_ctl, 50); + ipri = dfc_disable_lock(FC_LVL, &CMD_LOCK); + if(j >= 600) { + outdmp->dfc_flag = -1; + break; + } + j++; + } + + j = outdmp->dfc_flag; + if(j == -1) { + rc = ETIMEDOUT; + goto ctout1; + } + + if(j == -2) { + rc = EFAULT; + goto ctout1; + } + + /* copy back response data */ + if(j > buf2sz) { + rc = ERANGE; + /* C_CT Request error */ + fc_log_printf_msg_vargs( binfo->fc_brd_no, + &fc_msgBlk1208, /* ptr to msg structure */ + fc_mes1208, /* ptr to msg */ + fc_msgBlk1208.msgPreambleStr, /* begin varargs */ + outdmp->dfc_flag, + 4096); /* end varargs */ + goto ctout1; + } + fc_bcopy((char *)&j, dm->fc_dataout, sizeof(int)); + + /* copy back data */ + dfc_unlock_enable(ipri, &CMD_LOCK); + if(dfc_rsp_data_copy(p_dev_ctl, (uchar *)cip->c_arg2, outdmp, j)) + rc = EIO; + ipri = dfc_disable_lock(FC_LVL, &CMD_LOCK); + +ctout1: + dfc_unlock_enable(ipri, &CMD_LOCK); + dfc_cmd_data_free(p_dev_ctl, indmp); + dfc_cmd_data_free(p_dev_ctl, outdmp); + ipri = dfc_disable_lock(FC_LVL, &CMD_LOCK); + fc_mem_put(binfo, MEM_BPL, (uchar * )bmp); + return(ipri); +} + +int +dfc_hba_rnid( +fc_dev_ctl_t * p_dev_ctl, +struct dfc_mem *dm, +struct cmd_input *cip, +struct dfccmdinfo *infop, +MBUF_INFO *buf_info, +ulong ipri) +{ + static HBA_WWN findwwn; + static ELS_PKT * ep; + static DMATCHMAP inmatp; + static DMATCHMAP outmatp; + static MATCHMAP * bmptr; + static uint32 * lptr; + static NODELIST * nlp; + static int j; + static uint32 size, incr; + static uint32 max; + static FC_BRD_INFO * binfo; + + binfo = &BINFO; + dfc_unlock_enable(ipri, &CMD_LOCK); + if (fc_copyin((uchar *)cip->c_arg1, (uchar *)&findwwn, (ulong)(sizeof(HBA_WWN)))) { + ipri = dfc_disable_lock(FC_LVL, &CMD_LOCK); + rc = EIO; + return(ipri); + } + ipri = dfc_disable_lock(FC_LVL, &CMD_LOCK); + + size = NLP_ALLOC; + incr = 0; +nlpchk: + nlp = binfo->fc_nlpbind_start; + if(nlp == (NODELIST *)&binfo->fc_nlpbind_start) + nlp = binfo->fc_nlpunmap_start; + if(nlp == (NODELIST *)&binfo->fc_nlpunmap_start) + nlp = binfo->fc_nlpmap_start; + while(nlp != (NODELIST *)&binfo->fc_nlpmap_start) { + if(cip->c_flag == NODE_WWN) { + if (fc_geportname(&nlp->nlp_nodename, (NAME_TYPE *)&findwwn) == 2) + goto foundrnid; + } + else { + if (fc_geportname(&nlp->nlp_portname, (NAME_TYPE *)&findwwn) == 2) + goto foundrnid; + } + nlp = (NODELIST *)nlp->nlp_listp_next; + if(nlp == (NODELIST *)&binfo->fc_nlpbind_start) + nlp = binfo->fc_nlpunmap_start; + if(nlp == (NODELIST *)&binfo->fc_nlpunmap_start) + nlp = binfo->fc_nlpmap_start; + } + rc = ERANGE; + return(ipri); + +foundrnid: + if(nlp->nlp_action & NLP_DO_RNID) + goto waitloop; + + if(nlp->nlp_Rpi == 0) { + int wait_sec; + + size = nlp->nlp_DID; + if(size == 0) { + size = nlp->nlp_oldDID; + } + if((size == 0) || (size == 0xffffffff) || (size == 0xffffff) || + (incr == 3)) { + rc = ERANGE; + return(ipri); + } + incr++; + nlp->nlp_action |= NLP_DO_RNID; + fc_els_cmd(binfo, ELS_CMD_PLOGI, (void *)((ulong)size), + (uint32)0, (ushort)0, nlp); +waitloop: + wait_sec = 0; + while(nlp->nlp_action & NLP_DO_RNID) { + dfc_unlock_enable(ipri, &CMD_LOCK); + dfc_msdelay(p_dev_ctl, 1000); + ipri = dfc_disable_lock(FC_LVL, &CMD_LOCK); + if(wait_sec++ == 10) + return(ipri); + } + nlp->nlp_action &= ~NLP_DO_RNID; + goto nlpchk; + } + + buf_info->virt = 0; + buf_info->phys = 0; + buf_info->flags = (FC_MBUF_DMA | FC_MBUF_IOCTL | FC_MBUF_UNLOCK); + buf_info->align = (int)FCELSSIZE; + buf_info->size = (int)FCELSSIZE; + buf_info->dma_handle = 0; + + dfc_unlock_enable(ipri, &CMD_LOCK); + fc_malloc(p_dev_ctl, buf_info); + ipri = dfc_disable_lock(FC_LVL, &CMD_LOCK); + + if (buf_info->phys == NULL) { + rc = ENOMEM; + return(ipri); + } + inmatp.dfc.virt = buf_info->virt; + if (buf_info->dma_handle) { + inmatp.dfc.dma_handle = buf_info->dma_handle; + inmatp.dfc.data_handle = buf_info->data_handle; + } + inmatp.dfc.phys = (uchar * )buf_info->phys; + + /* Save size of RNID request in this field */ + inmatp.dfc.fc_mptr = (uchar *)((ulong)(2*sizeof(uint32))); + fc_bzero((void *)inmatp.dfc.virt, (2 * sizeof(uint32))); + + buf_info->virt = 0; + buf_info->phys = 0; + buf_info->flags = (FC_MBUF_DMA | FC_MBUF_IOCTL | FC_MBUF_UNLOCK); + buf_info->align = 4096; + buf_info->size = infop->c_outsz + sizeof(uint32); + buf_info->dma_handle = 0; + + dfc_unlock_enable(ipri, &CMD_LOCK); + fc_malloc(p_dev_ctl, buf_info); + ipri = dfc_disable_lock(FC_LVL, &CMD_LOCK); + + if (buf_info->phys == NULL) { + rc = ENOMEM; + goto rnidout2; + } + outmatp.dfc.virt = buf_info->virt; + if (buf_info->dma_handle) { + outmatp.dfc.dma_handle = buf_info->dma_handle; + outmatp.dfc.data_handle = buf_info->data_handle; + } + outmatp.dfc.phys = (uchar * )buf_info->phys; + + /* Save size in this field */ + outmatp.dfc.fc_mptr = (uchar *)((ulong)(infop->c_outsz + sizeof(uint32))); + + /* Setup RNID command */ + lptr = (uint32 *)inmatp.dfc.virt; + *lptr = ELS_CMD_RNID; + ep = (ELS_PKT * )lptr; + ep->un.rnid.Format = RNID_TOPOLOGY_DISC; + + max = 0; + bmptr = 0; +redornid: + outmatp.dfc_flag = 0; + if((rc=fc_rnid_req( binfo, &inmatp, &outmatp, &bmptr, nlp->nlp_Rpi))) { + if(bmptr) + fc_mem_put(binfo, MEM_BPL, (uchar * )bmptr); + + if((rc == ENODEV) && (max < 4)) { + max++; + dfc_unlock_enable(ipri, &CMD_LOCK); + dfc_msdelay(p_dev_ctl, 500); + ipri = dfc_disable_lock(FC_LVL, &CMD_LOCK); + goto redornid; + } + if(rc == ENODEV) + rc = EACCES; + goto rnidout1; + } + + j = 0; + dfc_unlock_enable(ipri, &CMD_LOCK); + dfc_msdelay(p_dev_ctl, 1); + ipri = dfc_disable_lock(FC_LVL, &CMD_LOCK); + + /* Wait for RNID request to complete or timeout */ + while(outmatp.dfc_flag == 0) { + dfc_unlock_enable(ipri, &CMD_LOCK); + dfc_msdelay(p_dev_ctl, 50); + ipri = dfc_disable_lock(FC_LVL, &CMD_LOCK); + if(j >= 600) { + outmatp.dfc_flag = -1; + return(ipri); + } + j++; + } + + if(bmptr) + fc_mem_put(binfo, MEM_BPL, (uchar * )bmptr); + + j = (int)((ulong)outmatp.dfc_flag); + if(outmatp.dfc_flag == -1) { + + rc = ETIMEDOUT; + goto rnidout1; + } + + if(outmatp.dfc_flag == -2) { + + rc = EFAULT; + goto rnidout1; + } + + /* copy back response data */ + if(j > 4096) { + rc = ERANGE; + /* RNID Request error */ + fc_log_printf_msg_vargs( binfo->fc_brd_no, + &fc_msgBlk1209, /* ptr to msg structure */ + fc_mes1209, /* ptr to msg */ + fc_msgBlk1209.msgPreambleStr, /* begin varargs */ + (int)((ulong)outmatp.dfc.fc_mptr), + 4096); /* end varargs */ + goto rnidout1; + } + lptr = (uint32 *)outmatp.dfc.virt; + if(*lptr != ELS_CMD_ACC) { + rc = EFAULT; + goto rnidout1; + } + lptr++; + j -= sizeof(uint32); + fc_bcopy((char *)lptr, dm->fc_dataout, j); + + /* copy back size of response */ + dfc_unlock_enable(ipri, &CMD_LOCK); + if (fc_copyout((uchar *)&j, (uchar *)cip->c_arg2, sizeof(int))) { + ipri = dfc_disable_lock(FC_LVL, &CMD_LOCK); + rc = EIO; + goto rnidout1; + } + ipri = dfc_disable_lock(FC_LVL, &CMD_LOCK); + + infop->c_outsz = (uint32)((ulong)outmatp.dfc.fc_mptr); + +rnidout1: + buf_info->size = (int)((ulong)outmatp.dfc.fc_mptr); + buf_info->virt = (uint32 * )outmatp.dfc.virt; + buf_info->phys = (uint32 * )outmatp.dfc.phys; + buf_info->flags = (FC_MBUF_DMA | FC_MBUF_IOCTL | FC_MBUF_UNLOCK); + if (outmatp.dfc.dma_handle) { + buf_info->dma_handle = outmatp.dfc.dma_handle; + buf_info->data_handle = outmatp.dfc.data_handle; + } + dfc_unlock_enable(ipri, &CMD_LOCK); + fc_free(p_dev_ctl, buf_info); + ipri = dfc_disable_lock(FC_LVL, &CMD_LOCK); + +rnidout2: + buf_info->size = (int)((ulong)inmatp.dfc.fc_mptr); + buf_info->virt = (uint32 * )inmatp.dfc.virt; + buf_info->phys = (uint32 * )inmatp.dfc.phys; + buf_info->flags = (FC_MBUF_DMA | FC_MBUF_IOCTL | FC_MBUF_UNLOCK); + if (inmatp.dfc.dma_handle) { + buf_info->dma_handle = inmatp.dfc.dma_handle; + buf_info->data_handle = inmatp.dfc.data_handle; + } + dfc_unlock_enable(ipri, &CMD_LOCK); + fc_free(p_dev_ctl, buf_info); + ipri = dfc_disable_lock(FC_LVL, &CMD_LOCK); + return(ipri); +} + +int +dfc_hba_targetmapping( +fc_dev_ctl_t * p_dev_ctl, +struct dfc_mem *dm, +struct cmd_input *cip, +struct dfccmdinfo *infop, +ulong ipri) +{ + static HBA_FCPTARGETMAPPING * hf; + static HBA_FCPSCSIENTRY *ep; + static uint32 room; + static uint32 total; + static uint32 lunIndex, totalLuns; /* these 2 vars are per target id */ + static uint32 lunId; /* what we get back at lunIndex in virtRptLunData */ + static int memsz; + static char *appPtr; + static NODELIST * nlp; + static node_t * nodep; + static dvi_t * dev_ptr; + static FC_BRD_INFO * binfo; + static uint32 offset; + static uint32 total_mem; + static uint32 j; + static uint32 cnt; + + binfo = &BINFO; + hf = (HBA_FCPTARGETMAPPING *)dm->fc_dataout; + ep = &hf->entry[0]; + room = (uint32)((ulong)cip->c_arg1); + cnt = 0; + total = 0; + memsz = 0; + appPtr = ((char *)infop->c_dataout) + sizeof(ulong); + + /* Mapped ports only */ + nlp = binfo->fc_nlpmap_start; + while(nlp != (NODELIST *)&binfo->fc_nlpmap_start) { + offset = FC_SCSID(nlp->id.nlp_pan, nlp->id.nlp_sid); + if(offset > MAX_FC_TARGETS) { + nlp = (NODELIST *)nlp->nlp_listp_next; + continue; + } + nodep = binfo->device_queue_hash[offset].node_ptr; + if(nodep) + dev_ptr = nodep->lunlist; + else + dev_ptr = 0; + + if((!nodep) || (!dev_ptr)) { + dev_ptr=fc_alloc_devp(p_dev_ctl, offset, 0); + nodep = dev_ptr->nodep; + } + + /* we need to issue REPORT_LUN here in case the device's + * config has changed */ + nodep->rptlunstate = REPORT_LUN_ONGOING; + issue_report_lun(p_dev_ctl, dev_ptr, 0); + + j = 0; + dfc_unlock_enable(ipri, &CMD_LOCK); + dfc_msdelay(p_dev_ctl, 1); + ipri = dfc_disable_lock(FC_LVL, &CMD_LOCK); + + /* Wait for ReportLun request to complete or timeout */ + while(nodep->rptlunstate == REPORT_LUN_ONGOING) { + dfc_unlock_enable(ipri, &CMD_LOCK); + dfc_msdelay(p_dev_ctl, 50); + ipri = dfc_disable_lock(FC_LVL, &CMD_LOCK); + if(j >= 600) { + break; + } + j++; + } + if(nodep->rptlunstate == REPORT_LUN_ONGOING) { + break; + } + + lunIndex = 0; + totalLuns = 1; + if (nodep->virtRptLunData) { + uint32 *tmp; + tmp = (uint32*)nodep->virtRptLunData; + totalLuns = SWAP_DATA(*tmp) / 8; + } + + while(lunIndex < totalLuns) { + lunId = dfc_getLunId(nodep, lunIndex); + dev_ptr = fc_find_lun(binfo, offset, lunId); + + if((!dev_ptr) || + ((dev_ptr) && (dev_ptr->opened) && (dev_ptr->queue_state == ACTIVE))) { + if(cnt < room) { + HBA_OSDN *osdn; + HBA_UINT32 fcpLun[2]; + + if(total_mem - memsz < sizeof(HBA_FCPSCSIENTRY)) { + dfc_unlock_enable(ipri, &CMD_LOCK); + fc_copyout((char *)(&hf->entry[0]), appPtr,memsz); + ipri = dfc_disable_lock(FC_LVL, &CMD_LOCK); + + appPtr = appPtr + memsz; + ep = &hf->entry[0]; + memsz = 0; + } + + fc_bzero((void *)ep->ScsiId.OSDeviceName, 256); + osdn = (HBA_OSDN *)&ep->ScsiId.OSDeviceName[0]; + fc_bcopy("lpfc", osdn->drvname, 4); + osdn->instance = fc_brd_to_inst(binfo->fc_brd_no); + osdn->target = FC_SCSID(nlp->id.nlp_pan, nlp->id.nlp_sid); + osdn->lun = (HBA_UINT32)(lunId); + osdn->flags = 0; + ep->ScsiId.ScsiTargetNumber = + FC_SCSID(nlp->id.nlp_pan, nlp->id.nlp_sid); + ep->ScsiId.ScsiOSLun = (HBA_UINT32)(lunId); + ep->ScsiId.ScsiBusNumber = 0; + ep->FcpId.FcId = nlp->nlp_DID; + fc_bzero((char *)fcpLun, sizeof(HBA_UINT64)); + + fcpLun[0] = (lunId << FC_LUN_SHIFT); + if (nodep->addr_mode == VOLUME_SET_ADDRESSING) { + fcpLun[0] |= SWAP_DATA(0x40000000); + } + fc_bcopy((char *)&fcpLun[0], (char *)&ep->FcpId.FcpLun, sizeof(HBA_UINT64)); + fc_bcopy(&nlp->nlp_portname, (uchar *)&ep->FcpId.PortWWN, sizeof(HBA_WWN)); + fc_bcopy(&nlp->nlp_nodename, (uchar *)&ep->FcpId.NodeWWN, sizeof(HBA_WWN)); + cnt++; + ep++; + memsz = memsz + sizeof(HBA_FCPSCSIENTRY); + } + total++; + } + lunIndex++; + } + nlp = (NODELIST *)nlp->nlp_listp_next; + } + dfc_unlock_enable(ipri, &CMD_LOCK); + fc_copyout((char *)(&hf->entry[0]), appPtr,memsz); + ipri = dfc_disable_lock(FC_LVL, &CMD_LOCK); + + hf->NumberOfEntries = (HBA_UINT32)total; + dfc_unlock_enable(ipri, &CMD_LOCK); + fc_copyout((char *)(&hf->NumberOfEntries), infop->c_dataout, sizeof(ulong)); + ipri = dfc_disable_lock(FC_LVL, &CMD_LOCK); + + infop->c_outsz = 0; /* no more copy needed */ + if (total > room) { + rc = ERANGE; + do_cp = 1; + } + return(ipri); +} + +int +dfc_data_alloc( +fc_dev_ctl_t * p_dev_ctl, +struct dfc_mem *dm, +uint32 size) +{ + static FC_BRD_INFO * binfo; +#ifndef powerpc + static MBUF_INFO * buf_info; + static MBUF_INFO bufinfo; +#endif + + binfo = &BINFO; + + if(dm->fc_dataout) + return(EACCES); + +#ifdef powerpc + dm->fc_dataout = p_dev_ctl->dfc_kernel_buf; + dm->fc_outsz = size; +#else + size = ((size + 0xfff) & 0xfffff000); + buf_info = &bufinfo; + buf_info->virt = 0; + buf_info->phys = 0; + buf_info->flags = (FC_MBUF_IOCTL | FC_MBUF_UNLOCK); + buf_info->align = sizeof(void *); + buf_info->size = (int)size; + buf_info->dma_handle = 0; + + fc_malloc(p_dev_ctl, buf_info); + if (buf_info->virt == NULL) { + return(ENOMEM); + } + dm->fc_dataout = buf_info->virt; + dm->fc_outsz = size; + /* dfc_data_alloc */ + fc_log_printf_msg_vargs( binfo->fc_brd_no, + &fc_msgBlk0402, /* ptr to msg structure */ + fc_mes0402, /* ptr to msg */ + fc_msgBlk0402.msgPreambleStr, /* begin varargs */ + (uint32)((ulong)dm->fc_dataout), + dm->fc_outsz); /* end varargs */ +#endif + + return(0); +} + +int +dfc_data_free( +fc_dev_ctl_t * p_dev_ctl, +struct dfc_mem *dm) +{ + static FC_BRD_INFO * binfo; +#ifndef powerpc + static MBUF_INFO * buf_info; + static MBUF_INFO bufinfo; +#endif + + binfo = &BINFO; + + /* dfc_data_free */ + fc_log_printf_msg_vargs( binfo->fc_brd_no, + &fc_msgBlk0403, /* ptr to msg structure */ + fc_mes0403, /* ptr to msg */ + fc_msgBlk0403.msgPreambleStr, /* begin varargs */ + (uint32)((ulong)dm->fc_dataout), + dm->fc_outsz); /* end varargs */ + if(dm->fc_dataout == 0) + return(EACCES); + +#ifdef powerpc + dm->fc_dataout = 0; + dm->fc_outsz = 0; +#else + buf_info = &bufinfo; + buf_info->virt = dm->fc_dataout; + buf_info->size = dm->fc_outsz; + buf_info->phys = 0; + buf_info->flags = (FC_MBUF_IOCTL | FC_MBUF_UNLOCK); + buf_info->align = 0; + buf_info->dma_handle = 0; + fc_free(p_dev_ctl, buf_info); + dm->fc_dataout = 0; + dm->fc_outsz = 0; +#endif + return(0); +} + +DMATCHMAP * +dfc_cmd_data_alloc( +fc_dev_ctl_t * p_dev_ctl, +uchar * indataptr, +ULP_BDE64 * bpl, +uint32 size) +{ + static FC_BRD_INFO * binfo; + static MBUF_INFO * buf_info; + static MBUF_INFO bufinfo; + static DMATCHMAP * mlist; + static DMATCHMAP * mlast; + static DMATCHMAP * dmp; + static int cnt, offset, i; + + binfo = &BINFO; + buf_info = &bufinfo; + mlist = 0; + mlast = 0; + i = 0; + offset = 0; + + while(size) { + + if(size > 4096) + cnt = 4096; + else + cnt = size; + + /* allocate DMATCHMAP buffer header */ + buf_info->virt = 0; + buf_info->phys = 0; + buf_info->flags = (FC_MBUF_IOCTL | FC_MBUF_UNLOCK); + buf_info->align = (int)sizeof(long); + buf_info->size = (int)sizeof(DMATCHMAP); + buf_info->dma_handle = 0; + + fc_malloc(p_dev_ctl, buf_info); + + if (buf_info->virt == NULL) { + goto out; + } + dmp = buf_info->virt; + dmp->dfc.fc_mptr = 0; + dmp->dfc.virt = 0; + + /* Queue it to a linked list */ + if(mlast == 0) { + mlist = dmp; + mlast = dmp; + } + else { + mlast->dfc.fc_mptr = (uchar *)dmp; + mlast = dmp; + } + dmp->dfc.fc_mptr = 0; + + /* allocate buffer */ + buf_info->virt = 0; + buf_info->phys = 0; + buf_info->flags = (FC_MBUF_DMA | FC_MBUF_IOCTL | FC_MBUF_UNLOCK); + buf_info->align = (int)4096; + buf_info->size = (int)cnt; + buf_info->dma_handle = 0; + + fc_malloc(p_dev_ctl, buf_info); + + if (buf_info->phys == NULL) { + goto out; + } + dmp->dfc.virt = buf_info->virt; + if (buf_info->dma_handle) { + dmp->dfc.dma_handle = buf_info->dma_handle; + dmp->dfc.data_handle = buf_info->data_handle; + } + dmp->dfc.phys = (uchar * )buf_info->phys; + dmp->dfc_size = cnt; + + if(indataptr) { + /* Copy data from user space in */ + if (fc_copyin((indataptr+offset), (uchar *)dmp->dfc.virt, (ulong)cnt)) { + goto out; + } + bpl->tus.f.bdeFlags = 0; + fc_mpdata_sync(dmp->dfc.dma_handle, 0, 0, DDI_DMA_SYNC_FORDEV); + } + else { + bpl->tus.f.bdeFlags = BUFF_USE_RCV; + } + + /* build buffer ptr list for IOCB */ + bpl->addrLow = PCIMEM_LONG(putPaddrLow((ulong)dmp->dfc.phys)); + bpl->addrHigh = PCIMEM_LONG(putPaddrHigh((ulong)dmp->dfc.phys)); + bpl->tus.f.bdeSize = (ushort)cnt; + bpl->tus.w = PCIMEM_LONG(bpl->tus.w); + bpl++; + + i++; + offset += cnt; + size -= cnt; + } + + mlist->dfc_flag = i; + return(mlist); +out: + dfc_cmd_data_free(p_dev_ctl, mlist); + return(0); +} + +DMATCHMAP * +dfc_fcp_data_alloc( +fc_dev_ctl_t * p_dev_ctl, +ULP_BDE64 * bpl) +{ + static DMATCHMAP * fcpmp; + static fc_buf_t * fcptr; + static FC_BRD_INFO * binfo; + static MBUF_INFO * buf_info; + static MBUF_INFO bufinfo; + + binfo = &BINFO; + buf_info = &bufinfo; + + /* allocate DMATCHMAP buffer header */ + buf_info->virt = 0; + buf_info->phys = 0; + buf_info->flags = (FC_MBUF_IOCTL | FC_MBUF_UNLOCK); + buf_info->align = (int)sizeof(long); + buf_info->size = (int)sizeof(DMATCHMAP); + buf_info->dma_handle = 0; + + fc_malloc(p_dev_ctl, buf_info); + + if (buf_info->virt == NULL) { + return(0); + } + fcpmp = buf_info->virt; + fc_bzero((char *)fcpmp, sizeof(DMATCHMAP)); + + /* allocate buffer */ + buf_info->virt = 0; + buf_info->phys = 0; + buf_info->flags = (FC_MBUF_DMA | FC_MBUF_IOCTL | FC_MBUF_UNLOCK); + buf_info->align = (int)4096; + buf_info->size = (int)4096; + buf_info->dma_handle = 0; + + fc_malloc(p_dev_ctl, buf_info); + + if (buf_info->phys == NULL) { + buf_info->flags = (FC_MBUF_IOCTL | FC_MBUF_UNLOCK); + buf_info->size = (int)sizeof(DMATCHMAP); + buf_info->virt = (uint32 * )fcpmp; + buf_info->phys = (uint32 * )0; + buf_info->dma_handle = 0; + buf_info->data_handle = 0; + fc_free(p_dev_ctl, buf_info); + return(0); + } + fcpmp->dfc.virt = buf_info->virt; + if (buf_info->dma_handle) { + fcpmp->dfc.dma_handle = buf_info->dma_handle; + fcpmp->dfc.data_handle = buf_info->data_handle; + } + fcpmp->dfc.phys = (uchar * )buf_info->phys; + fcpmp->dfc_size = 4096; + fc_bzero((char *)fcpmp->dfc.virt, 4096); + + fcptr = (fc_buf_t *)fcpmp->dfc.virt; + fcptr->phys_adr = (char *)fcpmp->dfc.phys; + + bpl->addrHigh = PCIMEM_LONG((uint32)putPaddrHigh(GET_PAYLOAD_PHYS_ADDR(fcptr))); + bpl->addrLow = PCIMEM_LONG((uint32)putPaddrLow(GET_PAYLOAD_PHYS_ADDR(fcptr))); + bpl->tus.f.bdeSize = sizeof(FCP_CMND); + bpl->tus.f.bdeFlags = BUFF_USE_CMND; + bpl->tus.w = PCIMEM_LONG(bpl->tus.w); + bpl++; + bpl->addrHigh = PCIMEM_LONG((uint32)putPaddrHigh(GET_PAYLOAD_PHYS_ADDR(fcptr)+sizeof(FCP_CMND))); + bpl->addrLow = PCIMEM_LONG((uint32)putPaddrLow(GET_PAYLOAD_PHYS_ADDR(fcptr)+sizeof(FCP_CMND))); + bpl->tus.f.bdeSize = sizeof(FCP_RSP); + bpl->tus.f.bdeFlags = (BUFF_USE_CMND | BUFF_USE_RCV); + bpl->tus.w = PCIMEM_LONG(bpl->tus.w); + return(fcpmp); +} + +int +dfc_fcp_data_free( +fc_dev_ctl_t * p_dev_ctl, +DMATCHMAP * fcpmp) +{ + static FC_BRD_INFO * binfo; + static MBUF_INFO * buf_info; + static MBUF_INFO bufinfo; + + binfo = &BINFO; + buf_info = &bufinfo; + + if(fcpmp->dfc.virt) { + buf_info->size = fcpmp->dfc_size; + buf_info->virt = (uint32 * )fcpmp->dfc.virt; + buf_info->phys = (uint32 * )fcpmp->dfc.phys; + buf_info->flags = (FC_MBUF_DMA | FC_MBUF_IOCTL | FC_MBUF_UNLOCK); + if (fcpmp->dfc.dma_handle) { + buf_info->dma_handle = fcpmp->dfc.dma_handle; + buf_info->data_handle = fcpmp->dfc.data_handle; + } + fc_free(p_dev_ctl, buf_info); + } + buf_info->flags = (FC_MBUF_IOCTL | FC_MBUF_UNLOCK); + buf_info->size = (int)sizeof(DMATCHMAP); + buf_info->virt = (uint32 * )fcpmp; + buf_info->phys = (uint32 * )0; + buf_info->dma_handle = 0; + buf_info->data_handle = 0; + fc_free(p_dev_ctl, buf_info); + + return(0); +} + +int +dfc_rsp_data_copy( +fc_dev_ctl_t * p_dev_ctl, +uchar * outdataptr, +DMATCHMAP * mlist, +uint32 size) +{ + static FC_BRD_INFO * binfo; + static DMATCHMAP * mlast; + static int cnt, offset; + + binfo = &BINFO; + mlast = 0; + offset = 0; + + while(mlist && size) { + if(size > 4096) + cnt = 4096; + else + cnt = size; + + mlast = mlist; + mlist = (DMATCHMAP *)mlist->dfc.fc_mptr; + + if(outdataptr) { + fc_mpdata_sync(mlast->dfc.dma_handle, 0, 0, DDI_DMA_SYNC_FORKERNEL); + /* Copy data to user space */ + if (fc_copyout((uchar *)mlast->dfc.virt, (outdataptr+offset), (ulong)cnt)) { + return(1); + } + } + offset += cnt; + size -= cnt; + } + return(0); +} + +int +dfc_cmd_data_free( +fc_dev_ctl_t * p_dev_ctl, +DMATCHMAP * mlist) +{ + static FC_BRD_INFO * binfo; + static MBUF_INFO * buf_info; + static MBUF_INFO bufinfo; + static DMATCHMAP * mlast; + + binfo = &BINFO; + buf_info = &bufinfo; + while(mlist) { + mlast = mlist; + mlist = (DMATCHMAP *)mlist->dfc.fc_mptr; + if(mlast->dfc.virt) { + buf_info->size = mlast->dfc_size; + buf_info->virt = (uint32 * )mlast->dfc.virt; + buf_info->phys = (uint32 * )mlast->dfc.phys; + buf_info->flags = (FC_MBUF_DMA | FC_MBUF_IOCTL | FC_MBUF_UNLOCK); + if (mlast->dfc.dma_handle) { + buf_info->dma_handle = mlast->dfc.dma_handle; + buf_info->data_handle = mlast->dfc.data_handle; + } + fc_free(p_dev_ctl, buf_info); + } + buf_info->flags = (FC_MBUF_IOCTL | FC_MBUF_UNLOCK); + buf_info->size = (int)sizeof(DMATCHMAP); + buf_info->virt = (uint32 * )mlast; + buf_info->phys = (uint32 * )0; + buf_info->dma_handle = 0; + buf_info->data_handle = 0; + fc_free(p_dev_ctl, buf_info); + } + return(0); +} + + +_static_ int +dfc_fmw_rev( +fc_dev_ctl_t * p_dev_ctl) +{ + FC_BRD_INFO * binfo; + struct dfc_info * di; + + binfo = &BINFO; + di = &dfc.dfc_info[binfo->fc_brd_no]; + decode_firmware_rev( binfo, &VPD); + fc_bcopy((uchar *)fwrevision, di->fc_ba.a_fwname, 32); + return(0); +} + + +#else /* DFC_SUBSYSTEM */ + +_static_ int +dfc_ioctl( +struct dfccmdinfo *infop, +struct cmd_input *cip) +{ + return (ENODEV); +} + +int +dfc_put_event( +fc_dev_ctl_t * p_dev_ctl, +uint32 evcode, +uint32 evdata0, +void * evdata1, +void * evdata2) +{ + return(0); +} + +int +dfc_hba_put_event( +fc_dev_ctl_t * p_dev_ctl, +uint32 evcode, +uint32 evdata1, +uint32 evdata2, +uint32 evdata3, +uint32 evdata4) +{ + return(0); +} /* End dfc_hba_put_event */ + +_static_ int +dfc_fmw_rev( +fc_dev_ctl_t * p_dev_ctl) +{ + return(0); +} + +#endif /* DFC_SUBSYSTEM */ + diff -purN -X /home/mbligh/.diff.exclude 350-autoswap/drivers/scsi/lpfc/fc.h 370-emulex/drivers/scsi/lpfc/fc.h --- 350-autoswap/drivers/scsi/lpfc/fc.h 1969-12-31 16:00:00.000000000 -0800 +++ 370-emulex/drivers/scsi/lpfc/fc.h 2004-02-28 11:20:03.000000000 -0800 @@ -0,0 +1,1264 @@ +/******************************************************************* + * This file is part of the Emulex Linux Device Driver for * + * Enterprise Fibre Channel Host Bus Adapters. * + * Refer to the README file included with this package for * + * driver version and adapter support. * + * Copyright (C) 2003 Emulex Corporation. * + * www.emulex.com * + * * + * This program is free software; you can redistribute it and/or * + * modify it under the terms of the GNU General Public License * + * as published by the Free Software Foundation; either version 2 * + * of the License, or (at your option) any later version. * + * * + * This program is distributed in the hope that it will be useful, * + * but WITHOUT ANY WARRANTY; without even the implied warranty of * + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * + * GNU General Public License for more details, a copy of which * + * can be found in the file COPYING included with this package. * + *******************************************************************/ + +#ifndef _H_FC +#define _H_FC + +/* Open Source defines */ +#define DFC_SUBSYSTEM 1 /* Include dfc subsystem */ + +#include "fcdiag.h" +#include "fcdds.h" + +#define LONGW_ALIGN 2 /* longword align for xmalloc */ +#define FC_MAX_SEQUENCE 65536 /* maximum fc sequence size */ +#define FC_MIN_SEQUENCE 0 /* minimum fc sequence size */ +#define FC_MAX_IP_VECS 16 /* Max scatter list for mapping */ +#define RING_TMO_DFT 30 /* default cmd timeout for IOCB rings */ +#define MBOX_TMO_DFT 30 /* dft mailbox timeout for mbox cmds */ +#define FC_CAP_AUTOSENSE 0x0400 /* SCSI capability for autosense */ +#define FC_MAX_HOLD_RSCN 32 /* max number of deferred RSCNs */ +#define FC_MAX_NS_RSP 65536 /* max size NameServer rsp */ + +/* Definitions for Binding Entry Type for fc_parse_binding_entry() */ +#define FC_BIND_WW_NN_PN 0 +#define FC_BIND_DID 1 + +#define FC_DMX_ID 0x100 +#define FL_DMX_ID 0x101 + +/* + * Debug printf event ids. + */ + +/* Check if WWN is 0 */ +#define isWWNzero(wwn) ((wwn.nameType == 0) && (wwn.IEEE[0] == 0) && (wwn.IEEE[1] == 0) && (wwn.IEEE[2] == 0) && (wwn.IEEE[3] == 0) && (wwn.IEEE[4] == 0) && (wwn.IEEE[5] == 0)) + +#define ERRID_NOTICE 0x100 +#define ERRID_ERROR 0x200 +#define ERRID_PANIC 0x400 +#define ERRID_MASK 0xf00 + +#define ERRID_VERBOSE 0x10ff + +/* These are verbose logging masks and debug printf masks */ +#define DBG_ELS 0x1 /* ELS events */ +#define DBG_DISCOVERY 0x2 /* Link discovery events */ +#define DBG_MBOX 0x4 /* Mailbox events */ +#define DBG_INIT 0x8 /* Initialization events */ +#define DBG_LINK_EVENT 0x10 /* link events */ +#define DBG_IP 0x20 /* IP traffic history */ +#define DBG_FCP 0x40 /* FCP traffic history */ +#define DBG_NODE 0x80 /* Node Table events */ +#define DBG_CHK_COND 0x1000 /* FCP Check condition flag */ + +/* These are debug printf masks */ +#define DBG_XRI 0x1000 /* Exchange events */ +#define DBG_IP_DATA 0x2000 /* IP traffic history */ +#define DBG_INTR 0x4000 /* Interrupts */ +#define DBG_IOCB_RSP 0x8000 /* IOCB Response ring events */ +#define DBG_IOCB_RSP_DATA 0x10000 /* IOCB Response ring events */ +#define DBG_IOCB_CMD 0x20000 /* IOCB Command ring events */ +#define DBG_IOCB_CMD_DATA 0x40000 /* IOCB Command ring events */ +#define DBG_FCP_DATA 0x100000/* FCP traffic history */ +#define DBG_ERROR 0x800000/* ERROR events */ + + +/* + * These definitions define SYNTAX errors that occur during the parsing + * of binding config lines. + */ +#define FC_SYNTAX_OK 0 +#define FC_SYNTAX_OK_BUT_NOT_THIS_BRD 1 +#define FC_SYNTAX_ERR_ASC_CONVERT 2 +#define FC_SYNTAX_ERR_EXP_COLON 3 +#define FC_SYNTAX_ERR_EXP_LPFC 4 +#define FC_SYNTAX_ERR_INV_LPFC_NUM 5 +#define FC_SYNTAX_ERR_EXP_T 6 +#define FC_SYNTAX_ERR_INV_TARGET_NUM 7 +#define FC_SYNTAX_ERR_EXP_D 8 +#define FC_SYNTAX_ERR_INV_DEVICE_NUM 9 +#define FC_SYNTAX_ERR_EXP_NULL_TERM 13 + +/*****************************************************************************/ +/* device states */ +/*****************************************************************************/ + +#define CLOSED 0 /* initial device state */ +#define DEAD 1 /* fatal hardware error encountered */ +#define LIMBO 2 /* error recovery period */ +#define OPEN_PENDING 3 /* open initiated */ +#define OPENED 4 /* opened successfully, functioning */ +#define CLOSE_PENDING 5 /* close initiated */ + +#define NORMAL_OPEN 0x0 /* opened in normal mode */ +#define DIAG_OPEN 0x1 /* opened in diagnostics mode */ + +/*****************************************************************************/ +/* This is the board information structure for the fc device */ +/*****************************************************************************/ + +struct fc_q { + uchar *q_first; /* queue first element */ + uchar *q_last; /* queue last element */ + ushort q_cnt; /* current length of queue */ + ushort q_max; /* max length queue can get */ +}; +typedef struct fc_q Q; + +typedef struct fclink { + struct fclink *_f; + struct fclink *_b; +} FCLINK; + +/* +*** fc_enque - enqueue element 'x' after element 'p' in +*** a queue without protection for critical sections. +*/ +#define fc_enque(x,p) {(((FCLINK *)x)->_f = ((FCLINK *)p)->_f, \ + ((FCLINK *)x)->_b = ((FCLINK *)p), \ + ((FCLINK *)p)->_f->_b = ((FCLINK *)x), \ + ((FCLINK *)p)->_f = ((FCLINK *)x));} + +/* +*** fc_deque - dequeue element 'x' (the user must make +*** sure its not the queue header +*/ +#define fc_deque(x) {(((FCLINK *)x)->_b->_f = ((FCLINK *)x)->_f, \ + ((FCLINK *)x)->_f->_b = ((FCLINK *)x)->_b, \ + ((FCLINK *)x)->_b = 0, \ + ((FCLINK *)x)->_f = 0);} + +/* This structure is used when allocating a buffer pool. + */ +typedef struct mbuf_info { + int size; /* Specifies the number of bytes to allocate. */ + int align; /* The desired address boundary. */ + + int flags; +#define FC_MBUF_DMA 0x1 /* blocks are for DMA */ +#define FC_MBUF_PHYSONLY 0x2 /* For malloc - map a given virtual address + * to physical (skip the malloc). For free - + * just unmap the given physical address + * (skip the free). + */ +#define FC_MBUF_IOCTL 0x4 /* called from dfc_ioctl */ +#define FC_MBUF_UNLOCK 0x8 /* called with driver unlocked */ + void * virt; /* specifies the virtual buffer pointer */ + void * phys; /* specifies the physical buffer pointer */ + ulong * data_handle; + ulong * dma_handle; +} MBUF_INFO; + + +struct fc_match { + uchar * fc_mptr; + uchar * virt; /* virtual address ptr */ + uchar * phys; /* mapped address */ + ulong * data_handle; + ulong * dma_handle; +}; +typedef struct fc_match MATCHMAP; + +struct dfc_match { + MATCHMAP dfc; + uint32 dfc_size; + int dfc_flag; +}; +typedef struct dfc_match DMATCHMAP; + +/* Kernel level Event structure */ +struct fcEvent { + uint32 evt_handle; + uint32 evt_mask; + uint32 evt_type; + uint32 evt_data0; + ushort evt_sleep; + ushort evt_flags; + void *evt_next; + void *evt_data1; + void *evt_data2; +}; +typedef struct fcEvent fcEvent; + +/* Define for e_mode */ +#define E_SLEEPING_MODE 0x0001 + +/* Define for e_flag */ +#define E_GET_EVENT_ACTIVE 0x0001 + +/* Kernel level Event Header */ +struct fcEvent_header { + uint32 e_handle; + uint32 e_mask; + ushort e_mode; + ushort e_flag; + fcEvent * e_head; + fcEvent * e_tail; + void * e_next_header; +/* Add something here */ +}; +typedef struct fcEvent_header fcEvent_header; + +/* Structures using for clock / timeout handling */ +typedef struct fcclock { + struct fcclock *cl_fw; /* forward linkage */ + union { + struct { + ushort cl_soft_arg; + ushort cl_soft_cmd; + } c1; + struct fcclock *cl_bw; /* backward linkage */ + } un; + uint32 cl_tix; /* differential number of clock ticks */ + void (*cl_func)(void *, void *, void *); + void * cl_p_dev_ctl; + void * cl_arg1; /* argument 1 to function */ + void * cl_arg2; /* argument 2 to function */ +} FCCLOCK; + +#define cl_bw un.cl_bw + +typedef struct clkhdr { + FCCLOCK *cl_f; + FCCLOCK * cl_b; + uint32 count; /* number of clock blocks in list */ +} CLKHDR; + +#define FC_NUM_GLBL_CLK 4 /* number of global clock blocks */ + +typedef struct fcclock_info { + CLKHDR fc_clkhdr; /* fc_clock queue head */ + uint32 ticks; /* elapsed time since initialization */ + uint32 Tmr_ct; /* Timer expired count */ + uint32 timestamp[2]; /* SMT 64 bit timestamp */ + void * clktimer; /* used for scheduling clock routine */ + Simple_lock clk_slock; /* clock routine lock */ + FCCLOCK clk_block[FC_NUM_GLBL_CLK]; /* global clock blocks */ +} FCCLOCK_INFO; + + +/* Structure used to access adapter rings */ +struct fc_ring { + IOCBQ * fc_iocbhd; /* ptr to head iocb rsp list for ring */ + IOCBQ * fc_iocbtl; /* ptr to tail iocb rsp list for ring */ + uchar fc_numCiocb; /* number of command iocb's per ring */ + uchar fc_numRiocb; /* number of rsp iocb's per ring */ + uchar fc_rspidx; /* current index in response ring */ + uchar fc_cmdidx; /* current index in command ring */ + uchar fc_ringno; /* ring number */ + uchar fc_xmitstate; /* state needed for xmit */ + void * fc_cmdringaddr; /* virtual offset for cmd rings */ + void * fc_rspringaddr; /* virtual offset for rsp rings */ + ushort fc_iotag; /* used to identify I/Os */ + + ushort fc_missbufcnt; /* buf cnt we need to repost */ + ushort fc_wdt_inited; /* timer is inited */ + ushort fc_bufcnt; /* cnt of buffers posted */ + uchar * fc_mpon; /* index ptr for match structure */ + uchar * fc_mpoff; /* index ptr for match structure */ + uchar * fc_binfo; /* ptr to FC_BRD_INFO for ring */ + Q fc_tx; /* iocb command queue */ + Q fc_txp; /* iocb pending queue */ + FCCLOCK * fc_wdt; /* timer for ring activity */ + int fc_ringtmo; /* timer timeout value */ +}; +typedef struct fc_ring RING; + +/* Defines for nlp_state (uchar) */ +#define NLP_UNUSED 0 /* unused NL_PORT entry */ +#define NLP_LIMBO 0x1 /* entry needs to hang around for wwpn / sid */ +#define NLP_LOGOUT 0x2 /* NL_PORT is not logged in - entry is cached */ +#define NLP_PLOGI 0x3 /* PLOGI was sent to NL_PORT */ +#define NLP_LOGIN 0x4 /* NL_PORT is logged in / login REG_LOGINed */ +#define NLP_PRLI 0x5 /* PRLI was sent to NL_PORT */ +#define NLP_ALLOC 0x6 /* NL_PORT is ready to initiate adapter I/O */ +#define NLP_SEED 0x7 /* seed scsi id bind in table */ + +/* Defines for nlp_flag (uint32) */ +#define NLP_RPI_XRI 0x1 /* creating xri for entry */ +#define NLP_REQ_SND 0x2 /* sent ELS request for this entry */ +#define NLP_RM_ENTRY 0x4 /* Remove this entry */ +#define NLP_FARP_SND 0x8 /* sent FARP request for this entry */ +#define NLP_NS_NODE 0x10 /* Authenticated entry by NameServer */ +#define NLP_NODEV_TMO 0x20 /* nodev timeout is running for node */ +#define NLP_REG_INP 0x40 /* Reglogin in progress for node */ +#define NLP_UNREG_LOGO 0x80 /* Perform LOGO after unreglogin */ +#define NLP_RCV_PLOGI 0x100 /* Rcv'ed PLOGI from remote system */ +#define NLP_MAPPED 0x200 /* Node is now mapped */ +#define NLP_UNMAPPED 0x400 /* Node is now unmapped */ +#define NLP_BIND 0x800 /* Node is now bound */ +#define NLP_LIST_MASK 0xe00 /* mask to see what list node is on */ +#define NLP_SND_PLOGI 0x1000 /* Flg to indicate send PLOGI */ +#define NLP_REQ_SND_PRLI 0x2000 /* Send PRLI ELS command */ +#define NLP_REQ_SND_ADISC 0x2000 /* Send ADISC ELS command */ +#define NLP_REQ_SND_PDISC 0x2000 /* Send PDISC ELS command */ +#define NLP_NS_REMOVED 0x4000 /* Node removed from NameServer */ + +/* Defines for nlp_action (uchar) */ +#define NLP_DO_ADDR_AUTH 0x1 /* Authenticating addr for entry */ +#define NLP_DO_DISC_START 0x2 /* start discovery on this entry */ +#define NLP_DO_RSCN 0x4 /* Authenticate entry for by RSCN */ +#define NLP_DO_RNID 0x8 /* Authenticate entry for by RSCN */ +#define NLP_DO_SCSICMD 0x10 /* Authenticate entry for by RSCN */ +#define NLP_DO_CT_USR 0x20 /* Authenticate entry for by RSCN */ +#define NLP_DO_CT_DRVR 0x40 /* Authenticate entry for by RSCN */ + +/* Defines for nlp_type (uchar) */ +#define NLP_FABRIC 0x1 /* this entry represents the Fabric */ +#define NLP_FCP_TARGET 0x2 /* this entry is an FCP target */ +#define NLP_IP_NODE 0x4 /* this entry is an IP node */ +#define NLP_SEED_WWPN 0x10 /* Entry scsi id is seeded for WWPN */ +#define NLP_SEED_WWNN 0x20 /* Entry scsi id is seeded for WWNN */ +#define NLP_SEED_DID 0x40 /* Entry scsi id is seeded for DID */ +#define NLP_SEED_MASK 0x70 /* mask for seeded flags */ +#define NLP_AUTOMAP 0x80 /* Entry was automap'ed */ + +/* Defines for list searchs */ +#define NLP_SEARCH_MAPPED 0x1 /* search mapped */ +#define NLP_SEARCH_UNMAPPED 0x2 /* search unmapped */ +#define NLP_SEARCH_BIND 0x4 /* search bind */ +#define NLP_SEARCH_ALL 0x7 /* search all lists */ + +/* Defines for nlp_fcp_info */ +#define NLP_FCP_2_DEVICE 0x10 /* FCP-2 device */ + +struct nlp_nodeList { /* NOTE: any changes to this structure + * must be dup'ed in fcdds.h, cnode_t. + */ + void * nlp_listp_next; /* Node table ptr bind / map / unmap list */ + void * nlp_listp_prev; /* Node table ptr bind / map / unmap list */ + uchar nlp_state; /* state transition indicator */ + uchar nlp_action; /* Action being performed on node */ + uchar nlp_type; /* node type identifier */ + uchar nlp_alpa; /* SCSI device AL_PA */ + ushort nlp_Rpi; /* login id returned by REG_LOGIN */ + ushort nlp_Xri; /* output exchange id for RPI */ + ushort capabilities; + ushort sync; + uint32 target_scsi_options; + uint32 nlp_flag; /* entry flags */ + uint32 nlp_DID; /* fibre channel D_ID of entry */ + uint32 nlp_time; /* timestamp */ + uint32 nlp_oldDID; + NAME_TYPE nlp_portname; /* port name */ + NAME_TYPE nlp_nodename; /* node name */ + struct { /* device id - for FCP */ + uchar nlp_pan; /* pseudo adapter number */ + uchar nlp_sid; /* scsi id */ + uchar nlp_fcp_info; /* Remote class info */ + uchar nlp_ip_info; /* Remote class info */ + } id; + uchar * nlp_bp; /* save buffer ptr - for IP */ + uchar * nlp_targetp; /* Node table ptr for target */ +}; +typedef struct nlp_nodeList NODELIST; + +/* For now stick fc_lun_t in here, + * should move to fc_os.h eventually. + */ +typedef uint32 fc_lun_t; + +#define mapLun(di) ((di)->lun_id) + +#define NLP_MAXREQ 32 /* max num of outstanding NODELIST requests */ +#define NLP_MAXSID 16 /* max number of scsi devices / adapter */ +#define NLP_MAXPAN 32 /* max number of pseudo adapters */ +#define PA_MASK 0x1f /* mask devno to get pseudo adapter number */ +#define DABS 5 /* convert devno to adapter number bit shift */ +#define FC_MIN_QFULL 1 /* lowest we can decrement throttle + to on qfull */ + +#define FC_SCSID(pan, sid) ((uint32)((pan << 16) | sid)) /* For logging */ + +/* Max number of fibre channel devices supported in network */ +#define NLP_MAXRPI 512 /* firmware supports 512 rpis [0-511] */ + +#define FC_MAXLOOP 126 /* max devices supported on a single fc loop */ +#define FC_MAX_MCAST 16 /* max number of multicast addresses */ +#define MULTI_BIT_MASK (0x01) /* Multicast Bit Mask */ +#define FC_MAX_ADPTMSG (8*28) /* max size of a msg from adapter */ +#define FC_INIT_RING_BUF 12 + +struct fc_networkhdr { + NAME_TYPE fc_destname; /* destination port name */ + NAME_TYPE fc_srcname; /* source port name */ +}; +typedef struct fc_networkhdr NETHDR; + +#define MEM_NLP 0 /* memory segment to hold node list entries */ +#define MEM_IOCB 1 /* memory segment to hold iocb commands */ +#define MEM_CLOCK 1 /* memory segment to hold clock blocks */ +#define MEM_MBOX 2 /* memory segment to hold mailbox cmds */ +#define MEM_BUF 3 /* memory segment to hold buffer data */ +#define MEM_BPL 3 /* and to hold buffer ptr lists - SLI2 */ +#define FC_MAX_SEG 4 + +#define MEM_SEG_MASK 0xff /* mask used to mask off the priority bit */ +#define MEM_PRI 0x100 /* Priority bit: set to exceed low water */ + +#define MIN_CLK_BLKS 256 + +struct fc_memseg { + uchar *fc_memptr; /* ptr to memory blocks */ + uchar *fc_endmemptr; /* ptr to last memory block */ + uchar *fc_memhi; /* highest address in pool */ + uchar *fc_memlo; /* lowest address in pool */ + ushort fc_memsize; /* size of memory blocks */ + ushort fc_numblks; /* number of memory blocks */ + ushort fc_free; /* number of free memory blocks */ + ushort fc_memflag; /* what to do when list is exhausted */ + ushort fc_lowmem; /* low water mark, used w/MEM_PRI flag */ +}; +typedef struct fc_memseg MEMSEG; + +#define FC_MEM_ERR 1 /* return error memflag */ +#define FC_MEM_GETMORE 2 /* get more memory memflag */ +#define FC_MEM_DMA 4 /* blocks are for DMA */ +#define FC_MEM_LOWHIT 8 /* low water mark was hit */ + +#define FC_MEMPAD 16 /* offset used for a FC_MEM_DMA buffer */ + +/* + * Board stat counters + */ +struct fc_stats { + uint32 chipRingFree; + uint32 cmdCreateXri; + uint32 cmdQbuf; + uint32 elsCmdIocbInval; + uint32 elsCmdPktInval; + uint32 elsLogiCol; + uint32 elsRetryExceeded; + uint32 elsStrayXmitCmpl; + uint32 elsXmitCmpl; + uint32 elsXmitErr; + uint32 elsXmitFrame; + uint32 elsXmitRetry; + uint32 elsRcvDrop; + uint32 elsRcvFrame; + uint32 elsRcvRSCN; + uint32 elsRcvFARP; + uint32 elsRcvFARPR; + uint32 elsRcvFLOGI; + uint32 elsRcvPLOGI; + uint32 elsRcvADISC; + uint32 elsRcvPDISC; + uint32 elsRcvFAN; + uint32 elsRcvLOGO; + uint32 elsRcvPRLO; + uint32 elsRcvRRQ; + uint32 frameRcvBcast; + uint32 frameRcvMulti; + uint32 hostRingFree; + uint32 iocbCmdInval; + uint32 iocbRingBusy; + uint32 IssueIocb; + uint32 iocbRsp; + uint32 issueMboxCmd; + uint32 linkEvent; + uint32 xmitnoroom; + uint32 NoIssueIocb; + uint32 mapPageErr; + uint32 mboxCmdBusy; + uint32 mboxCmdInval; + uint32 mboxEvent; + uint32 mboxStatErr; + uint32 memAllocErr; + uint32 noRpiList; + uint32 noVirtPtr; + uint32 ringEvent; + uint32 strayXmitCmpl; + uint32 frameXmitDelay; + uint32 xriCmdCmpl; + uint32 xriStatErr; + uint32 mbufcopy; + uint32 LinkUp; + uint32 LinkDown; + uint32 LinkMultiEvent; + uint32 NoRcvBuf; + uint32 fcpCmd; + uint32 fcpCmpl; + uint32 fcpStrayCmpl; + uint32 fcpFirstCheck; + uint32 fcpGood; + uint32 fcpRspErr; + uint32 fcpRemoteStop; + uint32 fcpLocalErr; + uint32 fcpLocalTmo; + uint32 fcpLocalNores; + uint32 fcpLocalBufShort; + uint32 fcpLocalSfw; + uint32 fcpLocalTxDMA; + uint32 fcpLocalRxDMA; + uint32 fcpLocalinternal; + uint32 fcpLocalCorrupt; + uint32 fcpLocalIllFrm; + uint32 fcpLocalDupFrm; + uint32 fcpLocalLnkCtlFrm; + uint32 fcpLocalLoopOpen; + uint32 fcpLocalInvalRpi; + uint32 fcpLocalLinkDown; + uint32 fcpLocalOOO; + uint32 fcpLocalAbtInp; + uint32 fcpLocalAbtReq; + uint32 fcpLocal; + uint32 fcpPortRjt; + uint32 fcpPortBusy; + uint32 fcpError; + uint32 fcpScsiTmo; + uint32 fcpSense; + uint32 fcpNoDevice; + uint32 fcMallocCnt; + uint32 fcMallocByte; + uint32 fcFreeCnt; + uint32 fcFreeByte; + uint32 fcMapCnt; + uint32 fcUnMapCnt; + uint32 fcpRsvd0; + uint32 fcpRsvd1; + uint32 fcpRsvd2; + uint32 fcpRsvd3; + uint32 fcpRsvd4; + uint32 fcpRsvd5; + uint32 fcpRsvd6; + uint32 fcpRsvd7; + uint32 fcpRsvd8; +}; +typedef struct fc_stats fc_stat_t; + + +/* Defines / Structures used to support IP profile */ + +#define FC_MIN_MTU 0 /* minimum size FC message */ +#define FC_MAX_MTU 65280 /* maximum size FC message */ + +/* structure for MAC header */ +typedef struct { + uchar dest_addr[MACADDR_LEN]; /* 48 bit unique address */ + uchar src_addr[MACADDR_LEN]; /* 48 bit unique address */ + ushort llc_len; /* length of LLC data */ +} emac_t; +#define HDR_LEN 14 /* MAC header size */ + +/* structure for LLC/SNAP header */ +typedef struct { + unsigned char dsap; /* DSAP */ + unsigned char ssap; /* SSAP */ + unsigned char ctrl; /* control field */ + unsigned char prot_id[3]; /* protocol id */ + unsigned short type; /* type field */ +} snaphdr_t; + +struct fc_hdr { + emac_t mac; + snaphdr_t llc; +}; + +struct fc_nethdr { + NETHDR fcnet; + snaphdr_t llc; +}; + +#define FC_LLC_SSAP 0xaa /* specifies LLC SNAP header */ +#define FC_LLC_DSAP 0xaa /* specifies LLC SNAP header */ +#define FC_LLC_CTRL 3 /* UI */ + + +/* + * The fc_buf structure is used to communicate SCSI commands to the adapter + */ +typedef struct sc_buf T_SCSIBUF; +#define SET_ADAPTER_STATUS(bp, val) bp->general_card_status = val; + +#define P_DEPTH ((FC_MAX_TRANSFER/PAGESIZE) + 2) + +typedef struct fc_buf { + FCP_CMND fcp_cmd; /* FCP command - This MUST be first */ + FCP_RSP fcp_rsp; /* FCP response - This MUST be next */ + struct fc_buf *fc_fwd; /* forward list pointer */ + struct fc_buf *fc_bkwd; /* backward list pointer */ + char *phys_adr; /* physical address of this fc_buf */ + T_SCSIBUF *sc_bufp; /* pointer to sc_buf for this cmd */ + struct dev_info *dev_ptr; /* pointer to SCSI device structure */ + uint32 timeout; /* Fill in how OS represents a time stamp */ + /* Fill in any OS specific members */ + int offset; + ulong * fc_cmd_dma_handle; + ushort iotag; /* iotag for this cmd */ + ushort flags; /* flags for this cmd */ +#define DATA_MAPPED 0x0001 /* data buffer has been D_MAPed */ +#define FCBUF_ABTS 0x0002 /* ABTS has been sent for this cmd */ +#define FCBUF_ABTS2 0x0004 /* ABTS has been sent twice */ +#define FCBUF_INTERNAL 0x0008 /* Internal generated driver command */ + + /* + * Save the buffer pointer list for later use. + * In SLI2, the fc_deq_fcbuf_active uses this pointer to + * free up MEM_BPL buffer + */ + MATCHMAP *bmp; +} fc_buf_t; + +#define FCP_CONTINUE 0x01 /* flag for issue_fcp_cmd */ +#define FCP_REQUEUE 0x02 /* flag for issue_fcp_cmd */ +#define FCP_EXIT 0x04 /* flag for issue_fcp_cmd */ + +/* + * The fcp_table structure is used to relate FCP iotags to an fc_buf + */ + +typedef struct fcp_table { + fc_buf_t *fcp_array[MAX_FCP_CMDS];/* fc_buf pointers indexed by iotag */ +} FCPTBL; + + +/* + * SCSI node structure for each open Fibre Channel node + */ + +typedef struct scsi_node { + struct fc_dev_ctl * ap; /* adapter structure ptr */ + struct dev_info * lunlist; /* LUN structure list for this node */ + NODELIST * nlp; /* nlp structure ptr */ + struct dev_info * last_dev; /* The last device had an I/O */ + FCCLOCK * nodev_tmr; /* Timer for nodev-tmo */ + int devno; /* pseudo adapter major/minor number */ + int max_lun; /* max number of luns */ + ushort tgt_queue_depth; /* Max throttle of this node */ + ushort num_active_io; /* Total number of active I/O */ + ushort rpi; /* Device rpi */ + ushort last_good_rpi; /* Last known good device rpi */ + ushort scsi_id; /* SCSI ID of this device */ + ushort flags; +#define FC_NODEV_TMO 0x1 /* nodev-tmo tmr started and expired */ +#define FC_FCP2_RECOVERY 0x2 /* set FCP2 Recovery for commands */ +#define RETRY_RPTLUN 0x4 /* Report Lun has been retried */ + ushort addr_mode; /* SCSI address method */ +#define PERIPHERAL_DEVICE_ADDRESSING 0 +#define VOLUME_SET_ADDRESSING 1 +#define LOGICAL_UNIT_ADDRESSING 2 + ushort rptlunstate; /* For report lun SCSI command */ +#define REPORT_LUN_REQUIRED 0 +#define REPORT_LUN_ONGOING 1 +#define REPORT_LUN_COMPLETE 2 + void *virtRptLunData; + void *physRptLunData; +} node_t; + +/* Values for node_flag and fcp_mapping are in fcdds.h */ + +/* + * SCSI device structure for each open LUN + */ + +#define MAX_FCBUF_PAGES 6 /* This value may need to change when + * lun-queue-depth > 256 in lpfc.conf + */ + +typedef struct dev_info { + node_t *nodep; /* Pointer to the node structure */ + struct dev_info *next; /* Used for list of LUNs on this node */ + fc_lun_t lun_id; /* LUN ID of this device */ + uchar first_check; /* flag for first check condition */ +#define FIRST_CHECK_COND 0x1 +#define FIRST_IO 0x2 + + uchar opened; + uchar ioctl_wakeup; /* wakeup sleeping ioctl call */ + int ioctl_event; + int ioctl_errno; + int stop_event; + int active_io_count; + + struct dev_info *DEVICE_WAITING_fwd; + struct dev_info *ABORT_BDR_fwd; + struct dev_info *ABORT_BDR_bkwd; + + long qfullcnt; + /* Fill in any OS specific members */ + T_SCSIBUF *scp; + void *scsi_dev; + long scpcnt; + long qcmdcnt; + long iodonecnt; + long errorcnt; + /* + * A command lives in a pending queue until it is sent to the HBA. + * Throttling constraints apply: + * No more than N commands total to a single target + * No more than M commands total to a single LUN on that target + * + * A command that has left the pending queue and been sent to the HBA + * is an "underway" command. We count underway commands, per-LUN, + * to obey the LUN throttling constraint. + * + * Because we only allocate enough fc_buf_t structures to handle N + * commands, per target, we implicitly obey the target throttling + * constraint by being unable to send a command when we run out of + * free fc_buf_t structures. + * + * We count the number of pending commands to determine whether the + * target has I/O to be issued at all. + * + * We use next_pending to rotor through the LUNs, issuing one I/O at + * a time for each LUN. This mechanism guarantees a fair distribution + * of I/Os across LUNs in the face of a target queue_depth lower than + * #LUNs*fcp_lun_queue_depth. + */ + T_SCSIBUF *standby_queue_head; /* ptr to retry command queue */ + T_SCSIBUF *standby_queue_tail; /* ptr to retry command queue */ + uint32 standby_count; /* # of I/Os on standby queue */ + /* END: added by andy kong for SCSI */ + + ushort fcp_cur_queue_depth; /* Current maximum # cmds outstanding + * to dev; */ + ushort fcp_lun_queue_depth; /* maximum # cmds to each lun */ + T_SCSIBUF *pend_head; /* ptr to pending cmd queue */ + T_SCSIBUF *pend_tail; /* ptr to pending cmd queue */ + uint32 pend_count; +#define QUEUE_HEAD 1 +#define QUEUE_TAIL 0 + struct buf *clear_head; /* ptr to bufs to iodone after clear */ + uint32 clear_count; + + uchar numfcbufs; /* number of free fc_bufs */ + uchar stop_send_io; /* stop sending any io to this dev */ + + +#define ACTIVE 0 +#define STOPPING 1 +#define HALTED 2 +#define RESTART_WHEN_READY 3 +#define ACTIVE_PASSTHRU 4 +#define WAIT_RESUME 8 +#define WAIT_INFO 10 +#define WAIT_ACA 11 +#define WAIT_FLUSH 12 +#define WAIT_HEAD_RESUME 13 + uchar queue_state; /* device general queue state */ + /* ACTIVE, STOPPING, or HALTED */ + +#define SCSI_TQ_HALTED 0x0001 /* The transaction Q is halted */ +#define SCSI_TQ_CLEARING 0x0002 /* The transaction Q is clearing */ +#define SCSI_TQ_CLEAR_ACA 0x0004 /* a CLEAR_ACA is PENDING */ +#define SCSI_LUN_RESET 0x0008 /* sent LUN_RESET not of TARGET_RESET */ +#define SCSI_ABORT_TSET 0x0010 /* BDR requested but not yet sent */ +#define SCSI_TARGET_RESET 0x0020 /* a SCSI BDR is active for device */ +#define CHK_SCSI_ABDR 0x0038 /* value used to check tm flags */ +#define QUEUED_FOR_ABDR 0x0040 /* dev_ptr is on ABORT_BDR queue */ +#define NORPI_RESET_DONE 0x0100 /* BOGUS_RPI Bus Reset attempted */ +#define DONT_LOG_INVALID_RPI 0x0200 /* if flag is set, the I/O issuing */ + /* to an invalid RPI won't be logged */ +#define SCSI_IOCTL_INPROGRESS 0x0400 /* An ioctl is in progress */ +#define SCSI_SEND_INQUIRY_SN 0x1000 /* Serial number inq should be sent */ +#define SCSI_INQUIRY_SN 0x2000 /* Serial number inq has been sent */ +#define SCSI_INQUIRY_P0 0x4000 /* Page 0 inq has been sent */ +#define SCSI_INQUIRY_CMD 0x6000 /* Serial number or Page 0 inq sent */ +#define SCSI_DEV_RESET 0x8000 /* device is in process of resetting */ + ushort flags; /* flags for the drive */ + + struct dio vlist; /* virtual address of fc_bufs */ + struct dio blist; /* physical addresses of fc_bufs */ + fc_buf_t * fcbuf_head; /* head ptr to list of free fc_bufs */ + fc_buf_t * fcbuf_tail; /* tail ptr to list of free fc_bufs */ + + uchar sense[MAX_FCP_SNS]; /* Temporary request sense buffer */ + uchar sense_valid; /* flag to indicate new sense data */ + uchar sizeSN; /* size of InquirySN */ + uint32 sense_length; /* new sense data length */ + +#define MAX_QFULL_RETRIES 255 +#define MAX_QFULL_RETRY_INTERVAL 1000 /* 1000 (ms) */ + short qfull_retries; /* number of retries on a qfull condition */ + short qfull_retry_interval; /* the interval for qfull retry */ + void * qfull_tmo_id; + T_SCSIBUF scbuf; /* sc_buf for task management cmds */ + +} dvi_t; + + +typedef struct node_info_hash { + node_t *node_ptr; /* SCSI device node pointer */ + uint32 node_flag; /* match node on WWPN WWNN or DID */ + union { + NAME_TYPE dev_nodename; /* SCSI node name */ + NAME_TYPE dev_portname; /* SCSI port name */ + uint32 dev_did; /* SCSI did */ + } un; +} nodeh_t; + +/* + * LONGWAIT is used to define a default scsi_timeout value in seconds. + */ +#define LONGWAIT 30 + + +/* +*** Board Information Data Structure +*/ + +struct fc_brd_info { + /* Configuration Parameters */ + int fc_ffnumrings; /* number of FF rings being used */ + NAME_TYPE fc_nodename; /* fc nodename */ + NAME_TYPE fc_portname; /* fc portname */ + uint32 fc_pref_DID; /* preferred D_ID */ + uchar fc_pref_ALPA; /* preferred AL_PA */ + uchar fc_deferip; /* defer IP processing */ + uchar fc_nummask[4]; /* number of masks/rings being used */ + uchar fc_rval[6]; /* rctl for ring assume mask is 0xff */ + uchar fc_tval[6]; /* type for ring assume mask is 0xff */ + uchar ipAddr[16]; /* For RNID support */ + ushort ipVersion; /* For RNID support */ + ushort UDPport; /* For RNID support */ + uint32 fc_edtov; /* E_D_TOV timer value */ + uint32 fc_arbtov; /* ARB_TOV timer value */ + uint32 fc_ratov; /* R_A_TOV timer value */ + uint32 fc_rttov; /* R_T_TOV timer value */ + uint32 fc_altov; /* AL_TOV timer value */ + uint32 fc_crtov; /* C_R_TOV timer value */ + uint32 fc_citov; /* C_I_TOV timer value */ + uint32 fc_myDID; /* fibre channel S_ID */ + uint32 fc_prevDID; /* previous fibre channel S_ID */ + + /* The next three structures get DMA'ed directly into, + * so they must be in the first page of the adapter structure! + */ + volatile SERV_PARM fc_sparam; /* buffer for our service parameters */ + volatile SERV_PARM fc_fabparam; /* fabric service parameters buffer */ + volatile uchar alpa_map[128]; /* AL_PA map from READ_LA */ + + uchar fc_mbox_active; /* flag for mailbox in use */ + uchar fc_process_LA; /* flag to process Link Attention */ + uchar fc_ns_retry; /* retries for fabric nameserver */ + uchar fc_sli; /* configured SLI, 1 or 2 */ + int fc_nlp_cnt; /* cnt outstanding NODELIST requests */ + int fc_open_count; /* count of devices opened */ + int fc_rscn_id_cnt; /* count of RSCNs dids in list */ + uint32 fc_rscn_id_list[FC_MAX_HOLD_RSCN]; + Q fc_plogi; /* ELS PLOGI cmd queue */ + Q fc_mbox; /* mailbox cmd queue */ + Q fc_rscn; /* RSCN cmd queue */ + Q fc_defer_rscn; /* deferred RSCN cmd queue */ + uchar * fc_mbbp; /* buffer pointer for mbox command */ + uchar * fc_p_dev_ctl; /* pointer to driver device ctl */ + + /* Board dependent variables */ + int fc_flag; /* FC flags */ + int fc_brd_no; /* FC board number */ + int fc_ints_disabled; /* DEBUG: interrupts disabled */ + volatile int fc_ffstate; /* Current state of FF init process */ + int fc_interrupts; /* number of fc interrupts */ + int fc_cnt; /* generic counter for board */ + int fc_topology; /* link topology, from LINK INIT */ + int fc_firstopen; /* First open to driver flag */ + int fc_msgidx; /* current index to adapter msg buf */ + uint32 fc_eventTag; /* event tag for link attention */ + ulong fc_fabrictmo; /* timeout for fabric timer */ + uchar fc_multi; /* number of multicast addresses */ + uchar fc_linkspeed; /* Link speed after last READ_LA */ + uchar fc_max_data_rate; /* max_data_rate */ + + void * physaddr[FC_MAX_IP_VECS]; /* used in mbuf_to_iocb for */ + uint32 cntaddr[FC_MAX_IP_VECS]; /* phys mapping */ + + uchar fc_busflag; /* bus access flags */ +#define FC_HOSTPTR 2 /* Default is ring pointers in SLIM */ + + volatile uint32 * fc_mboxaddr; /* virtual offset for mailbox/SLIM */ + volatile uint32 fc_BCregaddr; /* virtual offset for BIU config reg */ + volatile uint32 fc_HAregaddr; /* virtual offset for host attn reg */ + volatile uint32 fc_HCregaddr; /* virtual offset for host ctl reg */ + volatile uint32 fc_FFregaddr; /* virtual offset for FF attn reg */ + volatile uint32 fc_STATregaddr; /* virtual offset for status reg */ + + + MATCHMAP fc_slim2; /* pointers to slim for SLI-2 */ + + void *fc_iomap_io; /* starting address for registers */ + void *fc_iomap_mem; /* starting address for SLIM */ + /* Fill in any OS specific members */ + /* dma handle, mem map, pci config access */ + + + + + + FCCLOCK * fc_mbox_wdt; /* timer for mailbox */ + FCCLOCK * fc_fabric_wdt; /* timer for fabric */ + FCCLOCK * fc_rscn_disc_wdt; /* timer for RSCN discovery */ + fc_stat_t fc_stats; /* fc driver generic statistics */ + + NAME_TYPE fc_multiaddr[FC_MAX_MCAST];/* multicast adrs for interface */ + NODELIST * fc_nlpbind_start; /* ptr to bind list */ + NODELIST * fc_nlpbind_end; /* ptr to bind list */ + NODELIST * fc_nlpunmap_start; /* ptr to unmap list */ + NODELIST * fc_nlpunmap_end; /* ptr to unmap list */ + NODELIST * fc_nlpmap_start; /* ptr to map list */ + NODELIST * fc_nlpmap_end; /* ptr to map list */ + ushort fc_bind_cnt; + ushort fc_unmap_cnt; + ushort fc_map_cnt; + ushort fc_rpi_used; + NODELIST * fc_nlplookup[NLP_MAXRPI]; /* ptr to active D_ID / RPIs */ + NODELIST fc_fcpnodev; /* nodelist entry for no device */ + uint32 nlptimer; /* timestamp for nlplist entry */ + ushort fc_capabilities; /* default value for NODELIST caps */ + ushort fc_sync; /* default value for NODELIST sync */ + + nodeh_t device_queue_hash[MAX_FC_TARGETS]; /* SCSI node pointers */ + FCPTBL * fc_table; /* FCP iotag table pointer */ + IOCBQ * fc_delayxmit; /* List of IOCBs for delayed xmit */ + + + char fc_adaptermsg[FC_MAX_ADPTMSG]; /* adapter printf messages */ + char fc_SerialNumber[32]; /* adapter Serial Number */ + char fc_OptionROMVersion[32]; /* adapter BIOS / Fcode version */ + MEMSEG fc_memseg[FC_MAX_SEG]; /* memory for buffers / structures */ + RING fc_ring[MAX_RINGS]; +}; + +typedef struct fc_brd_info FC_BRD_INFO; + + +/* Host Attn reg */ +#define FC_HA_REG(binfo,sa) ((volatile uint32 *)((volatile char *)sa + (binfo->fc_HAregaddr))) +#define FC_FF_REG(binfo,sa) ((volatile uint32 *)((volatile char *)sa + (binfo->fc_FFregaddr))) + +/* Host Status reg */ +#define FC_STAT_REG(binfo,sa) ((volatile uint32 *)((volatile char *)sa +(binfo->fc_STATregaddr))) + +/* Host Cntl reg */ +#define FC_HC_REG(binfo,sa) ((volatile uint32 *)((volatile char *)sa + (binfo->fc_HCregaddr))) + +/* BIU Configuration reg */ +#define FC_BC_REG(binfo,sa) ((volatile uint32 *)((volatile char *)sa + (binfo->fc_BCregaddr))) + +/* SLIM defines for SLI-1 */ +#define FC_MAILBOX(binfo,sa) ((MAILBOX *)((volatile char *)sa + ((uint32)((ulong)binfo->fc_mboxaddr)))) + +/* SLIM defines for SLI-2 */ +#define FC_SLI2_MAILBOX(binfo) ((MAILBOX *)(binfo->fc_mboxaddr)) + +#define FC_IOCB(binfo,sa) ((volatile uchar *)((volatile char *)sa + ((uint32)binfo->fc_mboxaddr + 0x100))) + +#define FC_RING(ringoff,sa) ((volatile uchar *)((volatile char *)sa + (ulong)(ringoff))) + + + +/* Write 32-bit value to CSR register pointed to by regp */ +#define WRITE_CSR_REG(binfo, regp, val) fc_writel((uint32 *)(regp), (uint32)val) + +/* Write 32-bit value to SLIM address pointed to by regp */ +#define WRITE_SLIM_ADDR(binfo, regp, val) fc_writel((uint32 *)(regp), (uint32)val) + +/* Read 32-bit value from CSR register pointed to by regp */ +#define READ_CSR_REG(binfo, regp) fc_readl((uint32 *)(regp)) + +/* Read 32-bit value from SLIM address pointed to by regp */ +#define READ_SLIM_ADDR(binfo, regp) fc_readl((uint32 *)(regp)) + +/* Write wcnt 32-bit words to SLIM address pointed to by slimp */ +#define WRITE_SLIM_COPY(binfo, bufp, slimp, wcnt) \ + fc_write_toio((uint32*)bufp, (uint32*)slimp, (sizeof(uint32)*(wcnt))) + +/* Read wcnt 32-bit words from SLIM address pointed to by slimp */ +#define READ_SLIM_COPY(binfo, bufp, slimp, wcnt) \ + fc_read_fromio((uint32*)slimp, (uint32*)bufp, (sizeof(uint32)*(wcnt)));\ + +#define WRITE_FLASH_COPY(binfo, bufp, flashp, wcnt) \ + fc_write_toio(bufp, flashp ,(sizeof(uint32)*(wcnt))) + +#define READ_FLASH_COPY(binfo, bufp, flashp, wcnt) \ + fc_read_fromio(flashp, bufp, (sizeof(uint32)*(wcnt))) + + + + + +/* defines for fc_open_count */ +#define FC_LAN_OPEN 0x1 /* LAN open completed */ +#define FC_FCP_OPEN 0x2 /* FCP open completed */ + +/* defines for fc_flag */ +#define FC_FCP_WWNN 0x0 /* Match FCP targets on WWNN */ +#define FC_FCP_WWPN 0x1 /* Match FCP targets on WWPN */ +#define FC_FCP_DID 0x2 /* Match FCP targets on DID */ +#define FC_FCP_MATCH 0x3 /* Mask for match FCP targets */ +#define FC_PENDING_RING0 0x4 /* Defer ring 0 IOCB processing */ +#define FC_LNK_DOWN 0x8 /* Link is down */ +#define FC_PT2PT 0x10 /* pt2pt with no fabric */ +#define FC_PT2PT_PLOGI 0x20 /* pt2pt initiate PLOGI */ +#define FC_DELAY_DISC 0x40 /* Delay discovery till after cfglnk */ +#define FC_PUBLIC_LOOP 0x80 /* Public loop */ +#define FC_INTR_THREAD 0x100 /* In interrupt code */ +#define FC_LBIT 0x200 /* LOGIN bit in loopinit set */ +#define FC_RSCN_MODE 0x400 /* RSCN cmd rcv'ed */ +#define FC_RSCN_DISC_TMR 0x800 /* wait edtov before processing RSCN */ +#define FC_NLP_MORE 0x1000 /* More node to process in node tbl */ +#define FC_OFFLINE_MODE 0x2000 /* Interface is offline for diag */ +#define FC_LD_TIMER 0x4000 /* Linkdown timer has been started */ +#define FC_LD_TIMEOUT 0x8000 /* Linkdown timeout has occurred */ +#define FC_FABRIC 0x10000 /* We are fabric attached */ +#define FC_DELAY_PLOGI 0x20000 /* Delay login till unreglogin */ +#define FC_SLI2 0x40000 /* SLI-2 CONFIG_PORT cmd completed */ +#define FC_INTR_WORK 0x80000 /* Was there work last intr */ +#define FC_NO_ROOM_IP 0x100000 /* No room on IP xmit queue */ +#define FC_NO_RCV_BUF 0x200000 /* No Rcv Buffers posted IP ring */ +#define FC_BUS_RESET 0x400000 /* SCSI BUS RESET */ +#define FC_ESTABLISH_LINK 0x800000 /* Reestablish Link */ +#define FC_SCSI_RLIP 0x1000000 /* SCSI rlip routine called */ +#define FC_DELAY_NSLOGI 0x2000000 /* Delay NameServer till ureglogin */ +#define FC_NSLOGI_TMR 0x4000000 /* NameServer in process of logout */ +#define FC_DELAY_RSCN 0x8000000 /* Delay RSCN till ureg/reg login */ +#define FC_RSCN_DISCOVERY 0x10000000 /* Authenticate all devices after RSCN */ +#define FC_2G_CAPABLE 0x20000000 /* HBA is 2 Gig capable */ +#define FC_POLL_MODE 0x40000000 /* [SYNC] I/O is in the polling mode */ +#define FC_BYPASSED_MODE 0x80000000 /* Interface is offline for diag */ + +/* defines for fc_ffstate */ +#define FC_INIT_START 1 +#define FC_INIT_NVPARAMS 2 +#define FC_INIT_REV 3 +#define FC_INIT_PARTSLIM 4 +#define FC_INIT_CFGRING 5 +#define FC_INIT_INITLINK 6 +#define FC_LINK_DOWN 7 +#define FC_LINK_UP 8 +#define FC_INIT_SPARAM 9 +#define FC_CFG_LINK 10 +#define FC_FLOGI 11 +#define FC_LOOP_DISC 12 +#define FC_NS_REG 13 +#define FC_NS_QRY 14 +#define FC_NODE_DISC 15 +#define FC_REG_LOGIN 16 +#define FC_CLEAR_LA 17 +#define FC_READY 32 +#define FC_ERROR 0xff + +#define NADDR_LEN 6 /* MAC network address length */ + +/* This should correspond with the HBA API event structure */ +struct fc_hba_event { + uint32 fc_eventcode; + uint32 fc_evdata1; + uint32 fc_evdata2; + uint32 fc_evdata3; + uint32 fc_evdata4; +}; + +typedef struct fc_hba_event HBAEVENT; +#define MAX_HBAEVENT 32 + +/***************************************************************************/ +/* + * This is the whole device control area for the adapter + */ +/***************************************************************************/ + +struct fc_dev_ctl { /* NOTE: struct intr must be FIRST */ + struct intr ihs; /* interrupt handler control struct */ + ndd_t ndd; /* ndd for NS ndd chain */ + struct fc_dev_ctl *next; /* point to the next device */ + uchar phys_addr[NADDR_LEN]; /* actual network address in use */ + Simple_lock cmd_slock; /* adapter command lock */ + void * ctl_correlator;/* point to the dd_ctl table */ + uchar device_state; /* main state of the device */ + uchar open_state; /* open state of the device */ + uchar intr_inited; /* flag for interrupt registration */ + uchar fcp_mapping; /* Map FCP devices based on WWNN WWPN or DID */ + ulong fc_ipri; /* save priority */ + int power_up; + uint32 dev_flag; /* device flags */ +#define FC_SCHED_CFG_INIT 2 /* schedule a call to fc_cfg_init() */ +#define FC_FULL_INFO_CALL 4 /* set if fc_info() can return full info */ +#define FC_NEEDS_DPC 0x10 + + uchar * devinfo; /* point to the device info */ + uchar * dip; /* point to device information */ + uchar * tran; /* point to device information */ + FCCLOCK * fc_estabtmo; /* link establishment timer */ + FCCLOCK * fc_waitflogi; /* link establishment timer */ + fc_dds_t dds; /* device dependent structure */ + fc_vpd_t vpd; /* vital product data */ + FC_BRD_INFO info; /* device specific info */ + uchar * mbufl_head; /* mbuf for offlevel intr handler */ + uchar * mbufl_tail; /* mbuf for offlevel intr handler */ + void * fc_evt_head; /* waiting for event queue */ + void * fc_evt_tail; /* waiting for event queue */ + + dvi_t * DEVICE_WAITING_head; + dvi_t * DEVICE_WAITING_tail; + dvi_t * ABORT_BDR_head; + dvi_t * ABORT_BDR_tail; + struct buf * timeout_head; /* bufs to iodone after RLIP done */ + + ushort timeout_count; + ushort init_eventTag; /* initial READ_LA eventtag from cfg */ + ushort hba_event_put; /* hbaevent event put word anchor */ + ushort hba_event_get; /* hbaevent event get word anchor */ + int hba_event_missed;/* hbaevent missed event word anchor */ + uchar pan_cnt; /* pseudo adapter number counter */ + uchar sid_cnt; /* SCSI ID counter */ + uchar adapter_state[NLP_MAXPAN]; + /* open/close state for pseudo adapters */ + + Simple_lock iostrat_lock; /* lock for ioctl IOSTRAT */ + int iostrat_event; /* iostrat event word anchor */ + struct buf * iostrat_head; /* head ptr to list of returned bufs */ + struct buf * iostrat_tail; /* tail ptr to list of returned bufs */ + HBAEVENT hbaevent[MAX_HBAEVENT]; + uint32 vendor_flag; + uint32 dfcmb[MAILBOX_CMD_WSIZE]; + /* Fill in any OS specific members */ + struct Scsi_Host *host; + struct pci_dev *pcidev; + struct buf *iodone_head; + struct buf *iodone_list; + void *dfc_kernel_buf; + void *abort_head; + void *abort_list; + void *rdev_head; + void *rdev_list; + void *rbus_head; + void *rbus_list; + void *rhst_head; + void *rhst_list; + void *qcmd_head; + void *qcmd_list; + void *qclk_head; + void *qclk_list; + uint32 dpc_ha_copy; /* copy of Host Attention Reg for DPC */ + uint32 dpc_hstatus; /* copy of Host Status Reg for DPC */ + uint32 dpc_cnt; + uint32 save_dpc_cnt; + ulong iflg; + ulong siflg; + WAIT_QUEUE linkwq; + WAIT_QUEUE rscnwq; + WAIT_QUEUE ctwq; +}; + +typedef struct fc_dev_ctl fc_dev_ctl_t; + + +/***************************************************************************/ +/* + * This is the global device driver control structure + */ +/***************************************************************************/ + +struct fc_dd_ctl { + FCCLOCK_INFO fc_clock_info; /* clock setup */ + FCCLOCK * fc_scsitmo; /* scsi timeout timer */ + fc_dev_ctl_t * p_dev[MAX_FC_BRDS]; /* device array */ + void * p_config[MAX_FC_BRDS]; + ushort num_devs; /* count of devices configed */ + + spinlock_t smp_lock; /* keep this at end */ +}; + +typedef struct fc_dd_ctl fc_dd_ctl_t; + +/* + * Macros for accessing device control area. The pointer to this area has to + * be named p_dev_ctl for using these macros. + */ + +#define DD_CTL fc_dd_ctl +#define CMD_LOCK p_dev_ctl->cmd_slock +#define IOCTL_SLP_LOCK ioctl_slp_lock +#define CLOCK_LOCK clock_info->clk_slock +#define IOSTRAT_LOCK p_dev_ctl->iostrat_lock +#define SCSI_TMO DD_CTL.fc_scsitmo +#define CLOCKWDT clock_info->clktimer + +#define IHS p_dev_ctl->ihs +#define NDD p_dev_ctl->ndd +#define NDDSTAT p_dev_ctl->ndd.ndd_genstats +#define VPD p_dev_ctl->vpd +#define DDS p_dev_ctl->dds +#define BINFO p_dev_ctl->info +#define RINGTMO rp->fc_wdt +#define MBOXTMO binfo->fc_mbox_wdt +#define FABRICTMO binfo->fc_fabric_wdt +#define FCSTATCTR binfo->fc_stats + +/* + * Lock class registration number for lock instrumentation. + * These numbers should be unique on the system and they should be + * controlled by the lock registration procedure set up for the lock + * instrumentations. + */ +#define FC_CMD_LOCK 47 +#define FC_IOSTRAT_LOCK 48 +#define FC_CFG_LOCK 49 +#define FC_CLOCK_LOCK 50 +#define FC_IOCTL_SLP_LOCK 51 + +#ifndef LITTLE_ENDIAN_HOST +#if defined(i386) +#define LITTLE_ENDIAN_HOST 1 +#endif + +#endif +#if LITTLE_ENDIAN_HOST +#define SWAP_SHORT(x) (x) +#define SWAP_LONG(x) (x) +#define SWAP_DATA(x) ((((x) & 0xFF)<<24) | (((x) & 0xFF00)<<8) | \ + (((x) & 0xFF0000)>>8) | (((x) & 0xFF000000)>>24)) +#define SWAP_DATA16(x) ((((x) & 0xFF) << 8) | ((x) >> 8)) +#define PCIMEM_SHORT(x) SWAP_SHORT(x) +#define PCIMEM_LONG(x) SWAP_LONG(x) +#define PCIMEM_DATA(x) SWAP_DATA(x) + +#else /* BIG_ENDIAN_HOST */ + +#define SWAP_SHORT(x) ((((x) & 0xFF) << 8) | ((x) >> 8)) +#define SWAP_LONG(x) ((((x) & 0xFF)<<24) | (((x) & 0xFF00)<<8) | \ + (((x) & 0xFF0000)>>8) | (((x) & 0xFF000000)>>24)) +#define SWAP_DATA(x) (x) +#define SWAP_DATA16(x) (x) + +#ifdef BIU_BSE /* This feature only makes sense for Big Endian */ +#define PCIMEM_SHORT(x) (x) +#define PCIMEM_LONG(x) (x) +#define PCIMEM_DATA(x) ((((x) & 0xFF)<<24) | (((x) & 0xFF00)<<8) | \ + (((x) & 0xFF0000)>>8) | (((x) & 0xFF000000)>>24)) +#else +#define PCIMEM_SHORT(x) SWAP_SHORT(x) +#define PCIMEM_LONG(x) SWAP_LONG(x) +#define PCIMEM_DATA(x) SWAP_DATA(x) +#endif +#endif + +#define SWAP_ALWAYS(x) ((((x) & 0xFF)<<24) | (((x) & 0xFF00)<<8) | \ + (((x) & 0xFF0000)>>8) | (((x) & 0xFF000000)>>24)) +#define SWAP_ALWAYS16(x) ((((x) & 0xFF) << 8) | ((x) >> 8)) + +/* + * For PCI configuration + */ +#define ADDR_LO(addr) ((int)(addr) & 0xffff) /* low 16 bits */ +#define ADDR_HI(addr) (((int)(addr) >> 16) & 0xffff) /* high 16 bits */ + +#endif /* _H_FC */ diff -purN -X /home/mbligh/.diff.exclude 350-autoswap/drivers/scsi/lpfc/fcLINUXfcp.c 370-emulex/drivers/scsi/lpfc/fcLINUXfcp.c --- 350-autoswap/drivers/scsi/lpfc/fcLINUXfcp.c 1969-12-31 16:00:00.000000000 -0800 +++ 370-emulex/drivers/scsi/lpfc/fcLINUXfcp.c 2004-02-28 11:20:03.000000000 -0800 @@ -0,0 +1,6949 @@ +/******************************************************************* + * This file is part of the Emulex Linux Device Driver for * + * Enterprise Fibre Channel Host Bus Adapters. * + * Refer to the README file included with this package for * + * driver version and adapter support. * + * Copyright (C) 2003 Emulex Corporation. * + * www.emulex.com * + * * + * This program is free software; you can redistribute it and/or * + * modify it under the terms of the GNU General Public License * + * as published by the Free Software Foundation; either version 2 * + * of the License, or (at your option) any later version. * + * * + * This program is distributed in the hope that it will be useful, * + * but WITHOUT ANY WARRANTY; without even the implied warranty of * + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * + * GNU General Public License for more details, a copy of which * + * can be found in the file COPYING included with this package. * + *******************************************************************/ + +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#if LINUX_VERSION_CODE >= KERNEL_VERSION(2,4,4) +#include +#else +#include +#endif +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include + +#include "fc_os.h" +#include "fc_hw.h" +#include "fc.h" +#include "dfc.h" +#include "fcdiag.h" +#include "fcmsg.h" +#include "fc_crtn.h" +#include "fc_ertn.h" + + +#if LINUX_VERSION_CODE >= LinuxVersionCode(2,4,0) +#include +#include +#else +#include +#endif +#include +#include +#include +#include + +#ifdef powerpc +#include + +#ifdef NO_TCE +#define INVALID_PHYS NO_TCE +#else +#define INVALID_PHYS 0 +#endif + +#else +#define INVALID_PHYS 0 +#endif + +#define is_invalid_phys(addr) ((addr) == (void *)((ulong)INVALID_PHYS)) + +static long IOcnt = 0; +static long lpfcdiag_cnt = 0; + +#define LPFC_DRIVER_VERSION "1.23a-2.6-3" +_static_ char *lpfc_release_version = LPFC_DRIVER_VERSION; + +/* Declare memory for global structure that is used to access + * per adapter specific info.c + */ +_static_ fc_dd_ctl_t DD_CTL; +_static_ spinlock_t lpfc_smp_lock; +_static_ struct watchdog lpfc_clktimer; +_static_ int lpfc_initTimer = 0; +_static_ int lpfc_one_cpu = 1; /* Just bind DPC to CPU 0 */ +_static_ int lpfc_use_hostptr = 0; + +_static_ spinlock_t lpfc_q_lock[MAX_FC_BRDS]; +_static_ spinlock_t lpfc_mempool_lock[MAX_FC_BRDS]; + +struct lpfc_dpc { + struct task_struct *dpc_handler; /* kernel thread */ + struct semaphore *dpc_wait; /* DPC waits on this semaphore */ + struct semaphore *dpc_notify; /* requester waits for DPC on sem */ + int dpc_active; /* DPC routine is active */ + int dpc_ticks; /* DPC routine current tick count */ + struct semaphore dpc_sem; +} lpfc_dpc[MAX_FC_BRDS]; + +_static_ int lpfc_dpc_timer = 0; + +_forward_ void lpfc_timer(void *p); +_forward_ int do_fc_timer(fc_dev_ctl_t *p_dev_ctl); +_forward_ void lpfc_do_dpc(void *p); +_forward_ int fc_dpc_lstchk(fc_dev_ctl_t *p_dev_ctl, struct scsi_cmnd *Cmnd); + +/* Binding Definitions: Max string size */ +#define FC_MAX_DID_STRING 6 +#define FC_MAX_WW_NN_PN_STRING 16 + +int lpfcMallocCnt = 0; +int lpfcMallocByte = 0; +int lpfcFreeCnt = 0; +int lpfcFreeByte = 0; + +/* This defines memory for the common configuration parameters */ +#define DEF_ICFG 1 +#include "fcfgparm.h" + +#define SHUTDOWN_SIGS (sigmask(SIGKILL)|sigmask(SIGINT)|sigmask(SIGTERM)) + +#ifdef MODULE + +#ifndef EXPORT_SYMTAB +#define EXPORT_SYMTAB +#endif + +#include + +MODULE_PARM(lpfc_vendor, "i"); +MODULE_PARM(lpfc_bind_entries, "i"); +MODULE_PARM(lpfc_fcp_bind_WWPN, "1-" __MODULE_STRING(MAX_FC_BINDINGS) "s"); +MODULE_PARM(lpfc_fcp_bind_WWNN, "1-" __MODULE_STRING(MAX_FC_BINDINGS) "s"); +MODULE_PARM(lpfc_fcp_bind_DID, "1-" __MODULE_STRING(MAX_FC_BINDINGS) "s"); + +MODULE_PARM(lpfc_lun0_missing, "i"); +MODULE_PARM(lpfc_lun_skip, "i"); +MODULE_PARM(lpfc_use_removable, "i"); +MODULE_PARM(lpfc_max_lun, "i"); +MODULE_PARM(lpfc_use_data_direction, "i"); + + +#ifndef FC_NEW_EH +int lpfc_reset(struct scsi_cmnd *, unsigned int); +int fc_proc_info( char *, char **, off_t, int, int, int); +#endif +int fc_abort(struct scsi_cmnd *); +int fc_reset_device(struct scsi_cmnd *); +int fc_reset_bus(struct scsi_cmnd *); +int fc_reset_host(struct scsi_cmnd *); +int fc_queuecommand(struct scsi_cmnd *, void (*done)(struct scsi_cmnd *)); +void fc_queue_done_cmd(fc_dev_ctl_t * , struct buf *); +void fc_flush_done_cmds(fc_dev_ctl_t *, ulong); +void lpfc_nodev(unsigned long); +void local_timeout(unsigned long data); +irqreturn_t do_fc_intr_handler(int , void *, struct pt_regs *); +int do_fc_intr(struct intr *); +void * lpfc_kmalloc( unsigned int, unsigned int, void **, fc_dev_ctl_t *); +void lpfc_kfree( unsigned int, void *, void *, fc_dev_ctl_t *); + +EXPORT_SYMBOL(fc_abort); +EXPORT_SYMBOL(fc_reset_device); +EXPORT_SYMBOL(fc_reset_bus); +EXPORT_SYMBOL(fc_reset_host); +EXPORT_SYMBOL(local_timeout); +EXPORT_SYMBOL(do_fc_intr_handler); +EXPORT_SYMBOL(fc_queuecommand); +EXPORT_SYMBOL(fc_queue_done_cmd); +EXPORT_SYMBOL(fc_flush_done_cmds); +EXPORT_SYMBOL(do_fc_intr); +#else /* MODULE */ +#ifndef FC_NEW_EH +int fc_reset_device(struct scsi_cmnd *); +int fc_reset_bus(struct scsi_cmnd *); +int fc_reset_host(struct scsi_cmnd *); +#endif +void local_timeout(unsigned long data); +irqreturn_t do_fc_intr_handler(int , void *, struct pt_regs *); +int do_fc_intr(struct intr *); +void * lpfc_kmalloc( unsigned int, unsigned int, void **, fc_dev_ctl_t *); +void lpfc_kfree( unsigned int, void *, void *, fc_dev_ctl_t *); +extern int lpfn_probe(void); +static int lpfc_detect_called = 0; +#endif /* MODULE */ +int do_fc_abort(fc_dev_ctl_t *); +int do_fc_reset_device(fc_dev_ctl_t *); +int do_fc_reset_bus(fc_dev_ctl_t *); +int do_fc_reset_host(fc_dev_ctl_t *); +int do_fc_queuecommand(fc_dev_ctl_t *, ulong); +void fc_select_queue_depth(struct Scsi_Host *, struct scsi_device *); +int fc_device_queue_depth(fc_dev_ctl_t *, struct scsi_device *); +int fc_DetectInstance(int, struct pci_dev *pdev, uint, struct scsi_host_template *); + +#include "lpfc.conf.defs" + +#if LINUX_VERSION_CODE < LinuxVersionCode(2,4,0) +#ifdef MODULE +struct scsi_host_template driver_template = EMULEXFC; +#include "scsi_module.c" +#endif +#else /* new kernel scsi initialization scheme */ +static struct scsi_host_template driver_template = EMULEXFC; +#include "scsi_module.c" +#endif + +#ifndef __GENKSYMS__ +#include "fcmsgcom.c" +extern char fwrevision[32]; + +_local_ int lpfcdfc_init(void); +_local_ int fc_rtalloc(fc_dev_ctl_t *, struct dev_info *); +_local_ int fc_bind_wwpn(fc_dev_ctl_t *, char **, u_int ); +_local_ int fc_bind_wwnn(fc_dev_ctl_t *, char **, u_int ); +_local_ int fc_bind_did(fc_dev_ctl_t *, char **, u_int ); +_local_ dvi_t *fc_getDVI(fc_dev_ctl_t *, int, fc_lun_t); +_local_ ulong fc_po2(ulong); +_local_ int linux_attach(int, struct scsi_host_template *, struct pci_dev *); +_local_ int lpfc_find_cmd( fc_dev_ctl_t *p_dev_ctl, struct scsi_cmnd *cmnd); +_local_ void deviFree(fc_dev_ctl_t *, dvi_t *, node_t *); +_local_ int linux_detach(int ); +_local_ void *fc_kmem_zalloc(unsigned int ); + +extern int dfc_ioctl( struct dfccmdinfo *infop, struct cmd_input *cip); + +int lpfcdiag_ioctl(struct inode * inode, struct file * file, + unsigned int cmd, unsigned long arg); +int lpfcdiag_open(struct inode * inode, struct file * file); +int lpfcdiag_release(struct inode * inode, struct file * file); +int fc_ioctl(int , void *); + +static struct file_operations lpfc_fops = { + ioctl: lpfcdiag_ioctl, + open: lpfcdiag_open, + release: lpfcdiag_release, +}; + +static int lpfc_major = 0; + +/* If we want to define a new entry for Emulex boards*/ +/* #define PROC_SCSI_EMULEXFC PROC_SCSI_FILE+1 */ +/* For now we use the FC entry */ +#define NAMEEMULEX "lpfc" +#if LINUX_VERSION_CODE < LinuxVersionCode(2,4,0) +static struct proc_dir_entry proc_scsi_emulex = { + PROC_SCSI_FCAL , 4, "lpfc", + S_IFDIR | S_IRUGO | S_IXUGO, 2 +}; +#endif + +struct dfc { + uint32 dfc_init; + uint32 filler; + uchar bufout[sizeof(FC_BRD_INFO)]; + struct dfc_info dfc_info[MAX_FC_BRDS]; +}; +extern struct dfc dfc; + +/*Extra configuration parameters as defined in lpfc.conf.c*/ +extern int lpfc_vendor; +extern int lpfc_bind_entries; +extern char *lpfc_fcp_bind_WWPN[]; +extern char *lpfc_fcp_bind_WWNN[]; +extern char *lpfc_fcp_bind_DID[]; +extern int lpfc_lun0_missing; +extern int lpfc_lun_skip; +extern int lpfc_use_removable; +extern int lpfc_max_lun; +extern int lpfc_use_data_direction; + +/*Other configuration parameters, not available to user*/ +static int lpfc_pci_latency_clocks =0; +static int lpfc_pci_cache_line =0; + +/*Other configuration parameters, not available to user*/ +static int lpfc_mtu = 4032; /* define IP max MTU size */ +static int lpfc_intr_ack = 1; +static int lpfc_first_check = 1; +static int lpfc_zone_rscn = 1; +static int lpfc_qfull_retry = 5; + +int lpfc_nethdr = 1; +int lpfc_driver_unloading = 0; + +/* The size of a physical memory page */ +uint32 fcPAGESIZE = 4096; /*PAGE_SIZE;*/ + +/* Can be used to map driver instance number and hardware adapter number */ +int fcinstance[MAX_FC_BRDS]; +int fcinstcnt = 0; + +/* Current driver state for diagnostic mode, online / offline, see fcdiag.h */ +uint32 fc_diag_state; +uint32 fc_dbg_flag = 0; +#define FC_MAX_SEGSZ 4096 + +#define FC_MAX_POOL 1024 +struct fc_mem_pool { + void *p_virt; + void *p_phys; + ushort p_refcnt; + ushort p_left; +}; +struct fc_mem_pool *fc_mem_dmapool[MAX_FC_BRDS]; +int fc_idx_dmapool[MAX_FC_BRDS]; +int fc_size_dmapool[MAX_FC_BRDS]; + +#define ScsiResult(host_code, scsi_code) (((host_code) << 16) | scsi_code) + +#define ZERO_PAN 0 + +_static_ unsigned int lpfc_page_mask; + +/* Used in generating timeouts for timers */ +_static_ uint32 fc_scsi_abort_timeout_ticks; +_static_ uint32 fc_ticks_per_second; + +/* Can be used to map driver instance number and hardware adapter number */ +extern int fcinstance[]; +extern int fcinstcnt; + +/* Current driver state for diagnostic mode, online / offline, see fcdiag.h */ +extern uint32 fc_diag_state; + +extern int fc_check_for_vpd; +extern int fc_reset_on_attach; +extern int fc_max_ns_retry; +extern int fc_fdmi_on; +extern int fc_max_els_sent; + + + +void lpfc_scsi_add_timer(struct scsi_cmnd *, int); +int lpfc_scsi_delete_timer(struct scsi_cmnd *); + +#ifdef powerpc +#if LINUX_VERSION_CODE > LinuxVersionCode(2,4,14) +#define NO_BCOPY 1 +#endif +#endif + +#ifndef FC_NEW_EH +/****************************************************************************** +* Function name : fc_proc_info +* +* Description : +* +******************************************************************************/ +int fc_proc_info(char *buffer, + char **start, + off_t offset, + int length, + int hostno, + int inout) +{ + return(0); +} +#endif + +#if LINUX_VERSION_CODE < LinuxVersionCode(2,4,0) +/****************************************************************************** +* Function name : fc_pci_alloc_consistent +* +* Description : +* +******************************************************************************/ +void * fc_pci_alloc_consistent(struct pci_dev *hwdev, + size_t size, + dma_addr_t *dma_handle) +{ + void *virt_ptr; + u_long a_size; + int order; + + if ((size % PAGE_SIZE) == 0) { + for (order = 0, a_size = PAGE_SIZE; + a_size < size; order++, a_size <<= 1); + virt_ptr = (void *) __get_free_pages(GFP_ATOMIC, order); + } + else{ + a_size = fc_po2(size); + if(a_size == 256) + a_size = 512; + virt_ptr = kmalloc(a_size, GFP_KERNEL); + } + *dma_handle = virt_to_bus(virt_ptr); + return virt_ptr; +} + +/****************************************************************************** +* Function name : fc_pci_free_consistent +* +* Description : +* +******************************************************************************/ +void fc_pci_free_consistent(struct pci_dev *hwdev, + size_t size, + void *virt_ptr, + dma_addr_t dma_handle) +{ + u_long a_size; + int order; + + if(!virt_ptr) + return; + + /* + * Check which method was used to allocate the memory + */ + if ((size % PAGE_SIZE) == 0) { + for (order = 0, a_size = PAGE_SIZE; + a_size < size; order++, a_size <<= 1) + ; + free_pages((unsigned long)virt_ptr, order); + } + else{ + kfree(virt_ptr); + } +} +#else +/****************************************************************************** +* Function name : fc_pci_dma_sync_single +* +* Description : +* +******************************************************************************/ +void fc_pci_dma_sync_single(struct pci_dev *hwdev, + dma_addr_t h, + size_t size, + int c) +{ + pci_dma_sync_single(hwdev, h, 4096, c); +} +#endif + +#if defined (MODULE) || defined (NO_BCOPY) +/****************************************************************************** +* Function name : bcopy +* +* Description : kernel-space to kernel-space copy +* +******************************************************************************/ +_static_ void bcopy(void *src, + void *dest, + size_t n) +{ + memcpy(dest, src, n); +} +#else +/****************************************************************************** +* Function name : bcopy +* +* Description : kernel-space to kernel-space copy +* +******************************************************************************/ +_static_ void bcopy(void *src, void *dest, size_t n); + +#endif /* MODULE or NO_BCOPY */ + +/****************************************************************************** +* Function name : lpfc_DELAYMS +* +* Description : Called to delay cnt ms +* +******************************************************************************/ +_static_ int lpfc_DELAYMS(fc_dev_ctl_t *new_dev_ctl, + int cnt) +{ + int i; + fc_dev_ctl_t *p_dev_ctl; + FC_BRD_INFO *binfo; + struct lpfc_dpc *ldp; + + for (i = 0; i < MAX_FC_BRDS; i++) { + if((p_dev_ctl = (fc_dev_ctl_t *)DD_CTL.p_dev[i])) { + if(new_dev_ctl == p_dev_ctl) + continue; + binfo = &BINFO; + ldp = &lpfc_dpc[binfo->fc_brd_no]; + if ((ldp->dpc_active == 0) && ldp->dpc_wait) + up(ldp->dpc_wait); + } + } + if(new_dev_ctl->info.fc_ffstate != FC_INIT_START) { + barrier(); + schedule(); + } + mdelay(cnt); + for (i = 0; i < MAX_FC_BRDS; i++) { + if((p_dev_ctl = (fc_dev_ctl_t *)DD_CTL.p_dev[i])) { + if(new_dev_ctl == p_dev_ctl) + continue; + binfo = &BINFO; + ldp = &lpfc_dpc[binfo->fc_brd_no]; + if ((ldp->dpc_active == 0) && ldp->dpc_wait) + up(ldp->dpc_wait); + } + } + if(new_dev_ctl->info.fc_ffstate != FC_INIT_START) { + barrier(); + schedule(); + } + return(0); +} + +/****************************************************************************** +* Function name : kmem_alloc +* +* Description : Kernel memory alloc and free +* +******************************************************************************/ +_static_ void *fc_kmem_alloc(unsigned int size) +{ + void *ptr; + lpfcMallocCnt++; + lpfcMallocByte += size; + ptr = lpfc_kmalloc(size, GFP_ATOMIC, 0, 0); + return ptr; + +} + +/****************************************************************************** +* Function name : fc_kmem_free +* +* Description : +* +******************************************************************************/ +_static_ void fc_kmem_free(void *obj, + unsigned int size) +{ + lpfcFreeCnt++; + lpfcFreeByte += size; + if(obj) + lpfc_kfree(size, obj, (void *)((ulong)INVALID_PHYS), 0); +} + +/****************************************************************************** +* Function name : fc_kmem_zalloc +* +* Description : allocate memory and initialize to zeros +* +******************************************************************************/ +_static_ void *fc_kmem_zalloc(unsigned int size) +{ + void *ptr = fc_kmem_alloc(size); + if(ptr) + fc_bzero(ptr,size); + return ptr; +} + +/****************************************************************************** +* Function name : dfc_disable_lock +* +* Description : +* +******************************************************************************/ +_static_ ulong dfc_disable_lock(ulong p1, + Simple_lock *p2) + +{ + ulong iflg; + + iflg = 0; + spin_lock_irqsave(&lpfc_smp_lock, iflg); + return(iflg); +} + +/****************************************************************************** +* Function name : dfc_unlock_enable +* +* Description : +* +******************************************************************************/ +_static_ void dfc_unlock_enable(ulong p1, + Simple_lock *p2) +{ + ulong iflg; + + iflg = p1; + spin_unlock_irqrestore(&lpfc_smp_lock, iflg); + return; +} + +_static_ ulong lpfc_q_disable_lock(fc_dev_ctl_t *p_dev_ctl) +{ + ulong iflg; + + iflg = 0; + spin_lock_irqsave(&lpfc_q_lock[p_dev_ctl->info.fc_brd_no], iflg); + return(iflg); +} + + +_static_ void lpfc_q_unlock_enable(fc_dev_ctl_t *p_dev_ctl, ulong p1) +{ + ulong iflg; + + iflg = p1; + spin_unlock_irqrestore(&lpfc_q_lock[p_dev_ctl->info.fc_brd_no], iflg); + return; +} + +_static_ ulong lpfc_mempool_disable_lock(fc_dev_ctl_t *p_dev_ctl) +{ + ulong iflg; + + iflg = 0; + spin_lock_irqsave(&lpfc_mempool_lock[p_dev_ctl->info.fc_brd_no], iflg); + return(iflg); +} + + +_static_ void lpfc_mempool_unlock_enable(fc_dev_ctl_t *p_dev_ctl, ulong p1) +{ + ulong iflg; + + iflg = p1; + spin_unlock_irqrestore(&lpfc_mempool_lock[p_dev_ctl->info.fc_brd_no], iflg); + return; +} + +/****************************************************************************** +* Function name : fc_flush_done_cmds +* +* Description : flush all done commands at once +* +******************************************************************************/ +void fc_flush_done_cmds(fc_dev_ctl_t *p_dev_ctl, + ulong siflg) +{ + int count, first_inq; + struct scsi_cmnd *cmd; + struct buf * head; + FC_BRD_INFO *binfo; + struct dev_info *devp; + struct sc_buf *sp; + uint32 *iptr; + ulong iflg; + + iflg = 0; + LPFC_LOCK_DRIVER(1); + + head = p_dev_ctl->iodone_head; + binfo = &BINFO; + count = 0; + while(head) { + count++; + cmd = head->cmnd; + devp = ((struct sc_buf *)head)->current_devp; + head=head->av_forw; + + if(devp) + devp->iodonecnt++; + else + panic("NULL devp in flush_done\n"); + + if(cmd && (cmd->scsi_done != NULL)) { + sp = (struct sc_buf *)cmd->host_scribble; + if (!sp) { + /* NULL sp in flush_done */ + fc_log_printf_msg_vargs( binfo->fc_brd_no, + &fc_msgBlk0708, /* ptr to msg structure */ + fc_mes0708, /* ptr to msg */ + fc_msgBlk0708.msgPreambleStr, /* begin varargs */ + cmd->cmnd[0], + cmd->serial_number, + cmd->retries, + cmd->result); /* end varargs */ + continue; + } + + FCSTATCTR.fcpRsvd1++; + + if(devp->scp) { + sp->bufstruct.av_forw = devp->scp; + devp->scp = sp; + } + else { + devp->scp = sp; + devp->scp->bufstruct.av_forw = 0; + } + devp->scpcnt++; + cmd->host_scribble = 0; + + first_inq = 0; + if(devp->first_check & FIRST_IO) { + uchar *buf; + if(cmd->cmnd[0] == FCP_SCSI_INQUIRY) { + buf = (uchar *)cmd->request_buffer; + if((cmd->result) || + ((*buf & 0x70) != 0)) { /* lun not there */ +#ifdef FREE_LUN + deviFree(p_dev_ctl, devp, devp->nodep); +#else + devp->first_check &= ~FIRST_IO; +#endif + } else { + devp->first_check &= ~FIRST_IO; + } + first_inq = 1; + } + } + + + LPFC_UNLOCK_DRIVER; + iptr = (uint32 *)&cmd->sense_buffer[0]; + if((cmd->result) || *iptr) { + devp->errorcnt++; + /* iodone error return */ + fc_log_printf_msg_vargs( binfo->fc_brd_no, + &fc_msgBlk0710, /* ptr to msg structure */ + fc_mes0710, /* ptr to msg */ + fc_msgBlk0710.msgPreambleStr, /* begin varargs */ + (uint32)((cmd->device->id << 16) | cmd->device->lun), + (uint32)((cmd->retries << 16 ) | cmd->cmnd[0]), + cmd->result, + *iptr); /* end varargs */ + } + + lpfc_scsi_add_timer(cmd, cmd->timeout_per_command); + cmd->scsi_done(cmd); + iflg = 0; + LPFC_LOCK_DRIVER(2); + } + else + panic("Cmnd in done queue without scsi_done\n"); + } + p_dev_ctl->iodone_head = 0; + p_dev_ctl->iodone_list = 0; + LPFC_UNLOCK_DRIVER; + return; +} + +/****************************************************************************** +* Function name : fc_queue_done_cmd +* +* Description : add done command to a queue to be flushed later +* +******************************************************************************/ +void fc_queue_done_cmd(fc_dev_ctl_t *p_dev_ctl, + struct buf *sb) +{ + struct sc_buf *sp; + + if(p_dev_ctl->iodone_head == NULL) { + p_dev_ctl->iodone_head = sb; + p_dev_ctl->iodone_list = sb; + } else { + p_dev_ctl->iodone_list->av_forw = sb; + p_dev_ctl->iodone_list = sb; + } + sb->av_forw = NULL; + + sp = (struct sc_buf *)sb; + if (sp->cmd_flag & FLAG_ABORT) + sp->cmd_flag &= ~FLAG_ABORT; +} + +/****************************************************************************** +* Function name : remap_pci_mem +* +* Description : remap pci memory, makes sure mapped memory is page-aligned +* +******************************************************************************/ +_local_ void * remap_pci_mem(u_long base, + u_long size) +{ +#ifdef powerpc + return (ioremap (base, size)); +#else + u_long page_base = ((u_long) base)& PAGE_MASK; + u_long page_offs = ((u_long) base) - page_base; + u_long page_remapped = (u_long) ioremap(page_base, page_offs+size); + return (void *) (page_remapped? (page_remapped + page_offs) : ((ulong)-1)); +#endif +} + +/****************************************************************************** +* Function name : unmap_pci_mem +* +* Description : unmap pci memory +* +******************************************************************************/ +_local_ void unmap_pci_mem(u_long vaddr) +{ + if (vaddr) { + } +} + +#if LINUX_VERSION_CODE >= LinuxVersionCode(2,4,0) +/****************************************************************************** +* Function name : pci_getadd +* +* Description : get address from a pci register, accounts for 64 bit addresses +* returns next register +* +******************************************************************************/ +_local_ int pci_getadd(struct pci_dev *pdev, + int reg, + u_long *base) + +{ + *base = pci_resource_start(pdev, reg); + reg++; + return ++reg; +} +#else +/****************************************************************************** +* Function name : pci_getadd +* +* Description : get address from a pci register, accounts for 64 bit addresses +* returns next register +* +******************************************************************************/ +_local_ int pci_getadd(struct pci_dev *pdev, + int reg, + u_long *base) +{ + *base = pdev->base_address[reg++]; + if ((*base & 0x7) == 0x4) { +#if BITS_PER_LONG > 32 + *base |= (((u_long)pdev->base_address[reg]) << 32); +#endif + ++reg; + } + return reg; +} +#endif + +/****************************************************************************** +* Function name : fc_DetectInstance +* +* Description : +* +******************************************************************************/ +int fc_DetectInstance( int instance, + struct pci_dev *pdev, + uint type, + struct scsi_host_template *tmpt) +{ + +#if LINUX_VERSION_CODE >= KERNEL_VERSION(2,4,0) + /* PCI_SUBSYSTEM_IDS supported */ + while ((pdev = pci_find_subsys(PCI_VENDOR_ID_EMULEX, type, + PCI_ANY_ID, PCI_ANY_ID, pdev) )) + { + if (pci_enable_device(pdev)) continue; +#else + while ((pdev = pci_find_device(PCI_VENDOR_ID_EMULEX, type, + pdev))) + { +#endif + if(linux_attach(instance, tmpt, pdev) ) + continue; + instance++; + } + + return(instance); +} + +/****************************************************************************** +* Function name : fc_detect +* +* Description : Mid-level driver entry function for detecting the boards +* Also provides some initialization +* +******************************************************************************/ +int fc_detect(struct scsi_host_template *tmpt) +{ +#define WAIT_4_FC_READY 200 /* Thats 200 * 25 ms = 5 sec */ +#define MSEC_25_DELAY 25 +#define PRE_FC_READY_DELAY 40 +#define POST_FC_READY_DELAY 60 + + int instance = 0; + struct pci_dev *pdev = NULL; + fc_dev_ctl_t *p_dev_ctl; + FC_BRD_INFO *binfo; + int i, j, cnt; + /* To add another, add 1 to number of elements, add a line + * sType[x] = id, leave last sType[x+1] = 0; + */ + uint sType [8]; + + sType[0] = PCI_DEVICE_ID_THOR; + sType[1] = PCI_DEVICE_ID_SUPERFLY; + sType[2] = PCI_DEVICE_ID_PEGASUS; + sType[3] = PCI_DEVICE_ID_PFLY; + sType[4] = PCI_DEVICE_ID_CENTAUR; + sType[5] = PCI_DEVICE_ID_DRAGONFLY; + sType[6] = PCI_DEVICE_ID_TFLY; + /* sType[x] = PCI_DEVICE_ID_XXX; */ + sType[7] = 0; + + /* + * Intialization + */ + lpfc_page_mask = ((unsigned int) ~(fcPAGESIZE - 1)); + fc_ticks_per_second = HZ; + fc_scsi_abort_timeout_ticks = 300 * HZ /*CLOCK_TICK_RATE*/ ; + fc_bzero(&DD_CTL, sizeof(fc_dd_ctl_t)); + for (i = 0; i < MAX_FC_BRDS; i++) { + DD_CTL.p_dev[i] = NULL; + DD_CTL.p_config[i] = NULL; + fcinstance[i] = -1; + } + DD_CTL.num_devs = 0; + + fc_check_for_vpd = 1; /* issue dump mbox command during HBA initialization + * to check VPD data (if any) for a Serial Number */ + fc_reset_on_attach = 0; /* Always reset HBA before initialization in attach */ + fc_fdmi_on = 0; /* Enable FDMI */ + fc_max_ns_retry = 3; /* max number of retries for NameServer CT requests + * during discovery. */ + + fc_max_els_sent = 1; + if(fc_max_els_sent > NLP_MAXREQ) + fc_max_els_sent = NLP_MAXREQ; + +#if LINUX_VERSION_CODE < LinuxVersionCode(2,4,0) + tmpt->proc_dir = &proc_scsi_emulex; +#else + tmpt->proc_name = NAMEEMULEX; +#endif + + printk("Emulex LightPulse FC SCSI/IP %s\n", lpfc_release_version); + /* + * the mid-level clears interrupts + * no need to re-intialize pdev + */ + i = 0; + while(sType[i]) + { + instance = fc_DetectInstance(instance, pdev, sType[i], tmpt); + i++; + } + + if(instance) { + lpfcdfc_init(); /* Initialize diagnostic interface */ + } + + p_dev_ctl = (fc_dev_ctl_t *)NULL; /* Prevent compiler warning */ + if( (PRE_FC_READY_DELAY > 0) && + (instance > 0) && + (p_dev_ctl = (fc_dev_ctl_t *)DD_CTL.p_dev[0])) { + binfo = &BINFO; + for( i=0; ifc_ffstate >= FC_LINK_UP) && (binfo->fc_ffstate != FC_READY)) { + cnt++; + } + } + } + if(cnt) { + /* HBA(s) not FC_READY yet */ + lpfc_DELAYMS( p_dev_ctl, MSEC_25_DELAY); /* 25 millisec */ + continue; + } + break; + } + + /* There are cases where the HBAs are FC_READY but not all FC nodes + * have completed their FC PLOGI/PRLI sequence due to collisions. The + * following delay loop provides a chance for these noded to complete + * their FC PLOGI/PRLI sequence prior to allowing the SCSI layer to + * start up upon the return from this routine. + */ + + if( (POST_FC_READY_DELAY > 0) && + (instance > 0) && + (p_dev_ctl = (fc_dev_ctl_t *)DD_CTL.p_dev[0])) { + binfo = &BINFO; + for( i=0; ipcidev; + if(!pdev) + return(INTR_FAIL); + if (request_irq(pdev->irq, do_fc_intr_handler, SA_INTERRUPT | SA_SHIRQ, + "lpfcdd", (void *)ihs)) + return(INTR_FAIL); + return(INTR_SUCC); +} + +/****************************************************************************** +* Function name : i_clear +* +* Description : Called from fc_detach to remove interrupt vector for adapter +* +******************************************************************************/ +_static_ int i_clear(struct intr *ihs) +{ + struct pci_dev *pdev; + fc_dev_ctl_t *p_dev_ctl; + + p_dev_ctl = (fc_dev_ctl_t * )ihs; /* Since struct intr is at beginning */ + + /* + * Get PCI for this board + */ + pdev = p_dev_ctl->pcidev; + if(!pdev) + return(1); + free_irq(pdev->irq, p_dev_ctl); + p_dev_ctl->intr_inited=0; + return(0); +} + +/****************************************************************************** +* Function name : linux_attach +* +* Description : LINUX initialization entry point, called from environment +* to attach to / initialize a specific adapter. +* +******************************************************************************/ +_local_ int linux_attach(int instance, + struct scsi_host_template *tmpt, + struct pci_dev *pdev) +{ + struct Scsi_Host *host; + fc_dev_ctl_t *p_dev_ctl=NULL; + FC_BRD_INFO *binfo; + FCCLOCK_INFO *clock_info; + iCfgParam *clp=NULL; + int initTimer = 0; + ulong iflg; + + /* + * must have a valid pci_dev + */ + if(!pdev) + return (1); + + /* Allocate memory to manage HBA dma pool */ + fc_mem_dmapool[instance] = kmalloc((sizeof(struct fc_mem_pool) * FC_MAX_POOL), + GFP_ATOMIC); + if(fc_mem_dmapool[instance] == 0) + return(1); + + fc_bzero((void *)fc_mem_dmapool[instance], + (sizeof(struct fc_mem_pool) * FC_MAX_POOL)); + fc_idx_dmapool[instance] = 0; + fc_size_dmapool[instance] = FC_MAX_POOL; + + /* + * Allocate space for adapter info structure + */ + if (!(p_dev_ctl = (fc_dev_ctl_t *)fc_kmem_zalloc(sizeof(fc_dev_ctl_t)))) { + return (1); + } + /* + * Allocate space for configuration parameters + */ + if (!(clp = (iCfgParam *)fc_kmem_zalloc(sizeof(icfgparam)))) { + goto fail1; + } + + p_dev_ctl->pcidev = pdev; + p_dev_ctl->sid_cnt = 0; /* Start scsid assignment at 1 */ + binfo = &BINFO; + binfo->fc_brd_no = instance; + spin_lock_init(&lpfc_q_lock[instance]); + spin_lock_init(&lpfc_mempool_lock[instance]); + + if(lpfc_use_hostptr) + binfo->fc_busflag = FC_HOSTPTR; +#ifdef powerpc + binfo->fc_busflag = FC_HOSTPTR; +#endif + + binfo->fc_p_dev_ctl = (uchar * )p_dev_ctl; + DD_CTL.p_dev[instance] = p_dev_ctl; + DD_CTL.p_config[instance] = clp; + fcinstance[instance] = instance; + + /* + * Initialize config parameters + */ + bcopy((void * )&icfgparam, (void *)clp, sizeof(icfgparam)); + + /* + * Initialize locks, and timeout functions + */ + clock_info = &DD_CTL.fc_clock_info; + CLOCKWDT = (void *)&lpfc_clktimer; +#if LINUX_VERSION_CODE >= LinuxVersionCode(2,4,0) + init_waitqueue_head(&p_dev_ctl->linkwq); + init_waitqueue_head(&p_dev_ctl->rscnwq); + init_waitqueue_head(&p_dev_ctl->ctwq); +#endif + + + initTimer = 0; + if(lpfc_initTimer == 0) { + LPFC_INIT_LOCK_DRIVER; /* Just one global lock for driver */ + fc_clock_init(); + ((struct watchdog *)(CLOCKWDT))->func = fc_timer; + ((struct watchdog *)(CLOCKWDT))->restart = 1; + ((struct watchdog *)(CLOCKWDT))->count = 0; + ((struct watchdog *)(CLOCKWDT))->stopping = 0; + ((struct watchdog *)(CLOCKWDT))->timeout_id = 1; + /* + * add our watchdog timer routine to kernel's list + */ + ((struct watchdog *)(CLOCKWDT))->timer.expires = HZ + jiffies; + ((struct watchdog *)(CLOCKWDT))->timer.function = local_timeout; + ((struct watchdog *)(CLOCKWDT))->timer.data = (unsigned long)(CLOCKWDT); + init_timer(&((struct watchdog *)(CLOCKWDT))->timer); + add_timer(&((struct watchdog *)(CLOCKWDT))->timer); + lpfc_initTimer = 1; + initTimer = 1; + } + + { + struct lpfc_dpc *ldp; +#if LINUX_VERSION_CODE < KERNEL_VERSION(2,4,0) + struct semaphore sem = MUTEX_LOCKED; +#else + DECLARE_MUTEX_LOCKED(sem); +#endif + + ldp = &lpfc_dpc[instance]; + ldp->dpc_notify = &sem; + kernel_thread((int (*)(void *))lpfc_do_dpc, (void *) p_dev_ctl, 0); + /* + * Now wait for the kernel dpc thread to initialize and go to sleep. + */ + down(&sem); + ldp->dpc_notify = NULL; + } + + p_dev_ctl->intr_inited = 0; + fcinstcnt++; + if (fc_attach(instance, (uint32 * )((ulong)instance))) { + /* + * lower level routine will log error + */ + fcinstcnt--; + goto fail; + } + + /* + * Register this board + */ + host = scsi_register(tmpt, sizeof(unsigned long)); + + /* + * Adjust the number of id's + * Although max_id is an int, target id's are unsined chars + * Do not exceed 255, otherwise the device scan will wrap around + */ + host->max_id = MAX_FCP_TARGET; + if(!lpfc_max_lun) { + host->max_lun = MAX_FCP_LUN+1; + lpfc_max_lun = MAX_FCP_LUN+1; + } + else { + host->max_lun = lpfc_max_lun; + } + host->unique_id = instance; + + /* Adapter ID */ + host->this_id = MAX_FCP_TARGET - 1; + + /* + * Starting with 2.4.0 kernel, Linux can support commands longer + * than 12 bytes. However, scsi_register() always sets it to 12. + * For it to be useful to the midlayer, we have to set it here. + */ +#if LINUX_VERSION_CODE >= KERNEL_VERSION(2,4,0) + host->max_cmd_len = 16; +#endif + + /* + * Queue depths per lun + */ + host->cmd_per_lun = 1; + + /* + * Save a pointer to device control in host and increment board + */ + host->hostdata[0] = (unsigned long)p_dev_ctl; + p_dev_ctl->host = host; + DD_CTL.num_devs++; + + iflg = 0; + LPFC_LOCK_DRIVER(23); + /* + * Need to start scsi timeout if FCP is turned on + * The SCSI timeout watch dog is for all adaptors, so do it once only + */ + + if((SCSI_TMO == 0) && clp[CFG_FCP_ON].a_current) { + SCSI_TMO = fc_clk_set(0, 5, fc_scsi_timeout, 0, 0); + } + + /* DQFULL */ + if ((clp[CFG_DQFULL_THROTTLE].a_current) && + (clp[CFG_DFT_LUN_Q_DEPTH].a_current > FC_MIN_QFULL)) { + if ((clp[CFG_DQFULL_THROTTLE_UP_TIME].a_current) && + (clp[CFG_DQFULL_THROTTLE_UP_INC].a_current)) { + fc_clk_set(p_dev_ctl, clp[CFG_DQFULL_THROTTLE_UP_TIME].a_current, + fc_q_depth_up, 0, 0); + } + } + LPFC_UNLOCK_DRIVER; + return(0); + +fail: + if(initTimer) { + if(SCSI_TMO) { + fc_clk_can(0, SCSI_TMO); + SCSI_TMO = 0; + } + clock_info = &DD_CTL.fc_clock_info; + ((struct watchdog *)(CLOCKWDT))->stopping = 1; + if (((struct watchdog *)(CLOCKWDT))->timer.function) + del_timer(&((struct watchdog *)(CLOCKWDT))->timer); + ((struct watchdog *)(CLOCKWDT))->timer.function=NULL; + ((struct watchdog *)(CLOCKWDT))->timeout_id=0; + } + + { + struct lpfc_dpc *ldp; + ldp = &lpfc_dpc[instance]; + if(ldp->dpc_handler != NULL ) { +#if LINUX_VERSION_CODE < KERNEL_VERSION(2,4,0) + struct semaphore sem = MUTEX_LOCKED; +#else + DECLARE_MUTEX_LOCKED(sem); +#endif + + ldp->dpc_notify = &sem; + send_sig(SIGKILL, ldp->dpc_handler, 1); + down(&sem); + ldp->dpc_notify = NULL; + } + } + /* + * Free up any allocated resources + */ + fc_kmem_free(clp, sizeof(icfgparam)); + fail1: + /* + * Just in case the interrupt is still on + */ + if(p_dev_ctl->intr_inited) + i_clear((struct intr *)p_dev_ctl); + fc_kmem_free(p_dev_ctl, sizeof(fc_dev_ctl_t)); + + return(1); +} + +/****************************************************************************** +* Function name : fc_device_queue_depth +* +* Description : Determines the queue depth for a given device. +* There are two ways +* a queue depth can be obtained for a tagged queueing device. +* One way is the default queue depth which is determined by +* whether if it is defined, then it is used as the default +* queue depth. +* Otherwise, we use either 4 or 8 as the default queue depth +* (dependent on the number of hardware SCBs). +******************************************************************************/ +int fc_device_queue_depth(fc_dev_ctl_t *p_dev_ctl, + struct scsi_device *device) +{ + iCfgParam * clp; + FC_BRD_INFO *binfo; + + binfo = &p_dev_ctl->info; + clp = DD_CTL.p_config[binfo->fc_brd_no]; + if( device->tagged_supported ) { +#ifdef NEEDS_CHECKING + /* + * XXX double check that we can remove this. + */ + device->tagged_queue = 1; +#endif + device->current_tag = 0; + device->queue_depth = clp[CFG_DFT_LUN_Q_DEPTH].a_current; + } else { + device->queue_depth = 16; + } + return(device->queue_depth); +} + +/****************************************************************************** +* Function name : lpfc_do_dpc +* +* Description : +* +******************************************************************************/ +void lpfc_do_dpc(void *p) +{ + fc_dev_ctl_t * p_dev_ctl=(fc_dev_ctl_t*)p; + FC_BRD_INFO * binfo; + FCCLOCK_INFO * clock_info; + iCfgParam * clp; + struct lpfc_dpc * ldp; + void * ioa; + unsigned long secs; + int instance, ev; + ulong iflg; + ulong siflg; +#if LINUX_VERSION_CODE < KERNEL_VERSION(2,4,0) + struct fs_struct *fs; + struct semaphore sem = MUTEX_LOCKED; +#else + DECLARE_MUTEX_LOCKED(sem); +#endif + + lock_kernel(); + secs = 0; + + /* + * If we were started as result of loading a module, close all of the + * user space pages. We don't need them, and if we didn't close them + * they would be locked into memory. + */ + exit_mm(current); + + binfo = &BINFO; + clock_info = &DD_CTL.fc_clock_info; + instance = binfo->fc_brd_no ; + + daemonize("lpfc_do_dpc_%d", instance); + + clp = DD_CTL.p_config[instance]; + ldp = &lpfc_dpc[instance]; + + /* Since this is a kernel process, lets be nice to it! */ +#if LINUX_VERSION_CODE >= KERNEL_VERSION(2,4,0) +#ifdef DEF_NICE + current->nice = -20; + current->processor = smp_processor_id(); +#endif /* DEF_NICE */ + current->cpus_allowed = lpfc_one_cpu; + + +#else + { + int niceval; + uint32 priority; + + niceval = -20; + priority = niceval; + if (niceval < 0) + priority = -niceval; + if (priority > 20) + priority = 20; + priority = (priority * DEF_PRIORITY + 10) / 20 + DEF_PRIORITY; + + if (niceval >= 0) { + priority = 2*DEF_PRIORITY - priority; + if (!priority) + priority = 1; + } + current->priority = priority; + } + current->session = 1; + current->pgrp = 1; +#endif + +#if LINUX_VERSION_CODE < KERNEL_VERSION(2,4,0) + siginitsetinv(¤t->blocked, SHUTDOWN_SIGS); +#else + siginitsetinv(¤t->blocked, sigmask(SIGKILL)); +#endif + + ldp->dpc_wait = &sem; + ldp->dpc_handler = current; + + unlock_kernel(); + + /* + * Wake up the thread that created us. + */ + if( ldp->dpc_notify != NULL ) + up(ldp->dpc_notify); + ev = 0; + + while( 1 ) { + /* + * If we get a signal, it means we are supposed to go + * away and die. This typically happens if the user is + * trying to unload a module. + */ + if(ev == 0) { + ldp->dpc_ticks = clock_info->ticks; + + if(clp[CFG_NETWORK_ON].a_current) { + } + + /* Only wait if we go thru KP once with no work */ + down_interruptible(&sem); + if( signal_pending(current) ) { + + iflg = 0; + flush_signals(current); + + /* Only allow our driver unload to kill the KP */ + if( ldp->dpc_notify != NULL ) + break; /* get out */ + } + ldp->dpc_ticks = clock_info->ticks; + if(clp[CFG_NETWORK_ON].a_current) { + } + + } + ev = 0; + + siflg = 0; + iflg = 0; + LPFC_LOCK_DRIVER(22); + ldp->dpc_active = 1; + + p_dev_ctl->dpc_cnt++; + p_dev_ctl->dev_flag &= ~FC_NEEDS_DPC; + + /* Handle timer interrupts */ + if(p_dev_ctl->qclk_head) { + ev++; + do_fc_timer(p_dev_ctl); + } + + /* Handle adapter interrupts */ + if(p_dev_ctl->dpc_ha_copy) { + ev++; + do_fc_intr((struct intr *)p_dev_ctl); + } + + if(p_dev_ctl->qcmd_head) { + ev++; + if(clp[CFG_CR_DELAY].a_current != 0) { + ioa = FC_MAP_MEM(&binfo->fc_iomap_mem); /* map in io registers */ + if ((uchar)READ_SLIM_ADDR(binfo, ((volatile uint32 *)ioa + (SLIMOFF+(FC_ELS_RING*2)+1))) != + ((SLI2_SLIM * )binfo->fc_slim2.virt)->mbx.us.s2.port[FC_ELS_RING].rspPutInx) { + handle_ring_event(p_dev_ctl, FC_ELS_RING, HA_R0CE_RSP); + } + if ((uchar)READ_SLIM_ADDR(binfo, ((volatile uint32 *)ioa + (SLIMOFF+(FC_FCP_RING*2)+1))) != + ((SLI2_SLIM * )binfo->fc_slim2.virt)->mbx.us.s2.port[FC_FCP_RING].rspPutInx) { + handle_ring_event(p_dev_ctl, FC_FCP_RING, HA_R2CE_RSP); + } + FC_UNMAP_MEMIO(ioa); + } + do_fc_queuecommand(p_dev_ctl, siflg); + } + + /* Handle SCSI layer aborts */ + if(p_dev_ctl->abort_head) { + ev++; + do_fc_abort(p_dev_ctl); + } + + /* Handle SCSI layer device resets */ + if(p_dev_ctl->rdev_head) { + ev++; + do_fc_reset_device(p_dev_ctl); + } + + /* Handle SCSI layer bus resets */ + if(p_dev_ctl->rbus_head) { + ev++; + do_fc_reset_bus(p_dev_ctl); + } + + /* Handle SCSI layer host resets */ + if(p_dev_ctl->rhst_head) { + ev++; + do_fc_reset_host(p_dev_ctl); + } + + /* Handle iodone processing */ + if(p_dev_ctl->iodone_head) { + int count, first_inq; + struct scsi_cmnd *cmd; + struct buf * head; + struct dev_info *devp; + struct sc_buf *sp; + uint32 *iptr; + + ev++; + ldp->dpc_active = 0; + + head = p_dev_ctl->iodone_head; + count = 0; + while(head) { + count++; + cmd = head->cmnd; + devp = ((struct sc_buf *)head)->current_devp; + head=head->av_forw; + + if(devp) + devp->iodonecnt++; + else + panic("NULL devp in flush_done\n"); + + if(cmd && (cmd->scsi_done != NULL)) { + sp = (struct sc_buf *)cmd->host_scribble; + if (!sp) { + /* NULL sp in DPC flush_done */ + fc_log_printf_msg_vargs( binfo->fc_brd_no, + &fc_msgBlk0709, /* ptr to msg structure */ + fc_mes0709, /* ptr to msg */ + fc_msgBlk0709.msgPreambleStr, /* begin varargs */ + cmd->cmnd[0], + cmd->serial_number, + cmd->retries, + cmd->result); /* end varargs */ + continue; + } + + FCSTATCTR.fcpRsvd1++; + + if(devp->scp) { + sp->bufstruct.av_forw = devp->scp; + devp->scp = sp; + } + else { + devp->scp = sp; + devp->scp->bufstruct.av_forw = 0; + } + devp->scpcnt++; + cmd->host_scribble = 0; + + iptr = (uint32 *)&cmd->sense_buffer[0]; + if((cmd->result) || *iptr) { + devp->errorcnt++; + /* iodone error return */ + fc_log_printf_msg_vargs( binfo->fc_brd_no, + &fc_msgBlk0711, /* ptr to msg structure */ + fc_mes0711, /* ptr to msg */ + fc_msgBlk0711.msgPreambleStr, /* begin varargs */ + (uint32)((cmd->device->id << 16) | cmd->device->lun), + (uint32)((cmd->retries << 16 ) | cmd->cmnd[0]), + cmd->result, + *iptr); /* end varargs */ + } + + first_inq = 0; + if(devp->first_check & FIRST_IO) { + uchar *buf; + if(cmd->cmnd[0] == FCP_SCSI_INQUIRY) { + buf = (uchar *)cmd->request_buffer; + if((cmd->result) || + ((*buf & 0x70) != 0)) { /* lun not there */ +#ifdef FREE_LUN + deviFree(p_dev_ctl, devp, devp->nodep); +#else + devp->first_check &= ~FIRST_IO; +#endif + } else { + devp->first_check &= ~FIRST_IO; + } + first_inq = 1; + } + } + + LPFC_UNLOCK_DRIVER; + lpfc_scsi_add_timer(cmd, cmd->timeout_per_command); + cmd->scsi_done(cmd); + iflg = 0; + LPFC_LOCK_DRIVER(2); + } + else + panic("Cmnd in done queue without scsi_done\n"); + } + p_dev_ctl->iodone_head = 0; + p_dev_ctl->iodone_list = 0; + LPFC_UNLOCK_DRIVER; + } + else { + ldp->dpc_active = 0; + LPFC_UNLOCK_DRIVER; + } + + if(p_dev_ctl->dev_flag & FC_SCHED_CFG_INIT) { + p_dev_ctl->dev_flag &= ~FC_SCHED_CFG_INIT; + fc_cfg_init(p_dev_ctl); + + LPFC_LOCK_DRIVER(27); + if(p_dev_ctl->fc_estabtmo) { + fc_clk_can(p_dev_ctl, p_dev_ctl->fc_estabtmo); + } + if (binfo->fc_ffstate != FC_READY) { + p_dev_ctl->fc_estabtmo = + fc_clk_set(p_dev_ctl, 60, fc_establish_link_tmo, 0, 0); + } + LPFC_UNLOCK_DRIVER; + } + } + + /* + * Make sure that nobody tries to wake us up again. + */ + ldp->dpc_wait = NULL; + ldp->dpc_handler = NULL; + ldp->dpc_active = 0; + + /* + * If anyone is waiting for us to exit (i.e. someone trying to unload + * a driver), then wake up that process to let them know we are on + * the way out the door. This may be overkill - I *think* that we + * could probably just unload the driver and send the signal, and when + * the error handling thread wakes up that it would just exit without + * needing to touch any memory associated with the driver itself. + */ + if( ldp->dpc_notify != NULL ) + up(ldp->dpc_notify); +} + +/****************************************************************************** +* Function name : fc_release +* +* Description : +* +******************************************************************************/ +int fc_release(struct Scsi_Host *host) +{ + fc_dev_ctl_t *p_dev_ctl; + FC_BRD_INFO *binfo; + node_t *node_ptr; + struct dev_info *dev_ptr; + struct lpfc_dpc *ldp; + int instance; + int dev_index,target; + fc_lun_t lun; + ulong iflg; + + /* + * Indicate driver unloading so our interrupt handler can stop + * accepting interrupts. + */ + lpfc_driver_unloading = 1; + + /* + * get dev control from host + */ + p_dev_ctl = (fc_dev_ctl_t *)host->hostdata[0]; + binfo = &BINFO; + instance = binfo->fc_brd_no ; + + if(lpfcdiag_cnt) { + /* Cannot unload driver while lpfcdiag Interface is active */ + fc_log_printf_msg_vargs( binfo->fc_brd_no, + &fc_msgBlk1200, /* ptr to msg structure */ + fc_mes1200, /* ptr to msg */ + fc_msgBlk1200.msgPreambleStr, /* begin varargs */ + lpfcdiag_cnt, + (uint32)instance); /* end varargs */ + } + + iflg = 0; + LPFC_LOCK_DRIVER(24); + linux_detach(instance); + /* + *Clear all devi's + *Although host_queue has all devices, its not a good idea to touch it! + *instead we will loop on all possible targets and luns + */ + for(target=0; target < host->max_id; target++) { + dev_index = INDEX(ZERO_PAN, target); + node_ptr = binfo->device_queue_hash[dev_index].node_ptr; + if(!node_ptr) + continue; + for(lun=0; lun <= host->max_lun; lun++){ + dev_ptr = fc_find_lun(binfo, dev_index, lun); + if(!dev_ptr) + continue; + /* + * Free this device + */ + deviFree(p_dev_ctl, dev_ptr, node_ptr); + } + fc_kmem_free(node_ptr, sizeof(node_t)); + binfo->device_queue_hash[dev_index].node_ptr = 0; + } + + fcinstcnt--; + DD_CTL.num_devs--; + LPFC_UNLOCK_DRIVER; + + if(lpfc_major) + unregister_chrdev(lpfc_major, "lpfcdfc"); + + ldp = &lpfc_dpc[instance]; + if(ldp->dpc_handler != NULL ) { +#if LINUX_VERSION_CODE < KERNEL_VERSION(2,4,0) + struct semaphore sem = MUTEX_LOCKED; +#else + DECLARE_MUTEX_LOCKED(sem); +#endif + + ldp->dpc_notify = &sem; + send_sig(SIGKILL, ldp->dpc_handler, 1); + down(&sem); + ldp->dpc_notify = NULL; + } + scsi_unregister(host); + + return 0; +} + +/****************************************************************************** +* Function name : linux_detach +* +* Description : LINUX deinitialization entry point, called from environment +* to detach from / free resources for a specific adapter. +******************************************************************************/ +_local_ int linux_detach( int instance) +{ + FC_BRD_INFO * binfo; + iCfgParam * clp; + fc_dev_ctl_t * p_dev_ctl = (fc_dev_ctl_t * ) NULL; + + p_dev_ctl = DD_CTL.p_dev[instance]; + if (p_dev_ctl == NULL) { + return(0); + } + binfo = &BINFO; + clp = DD_CTL.p_config[instance]; + if (clp == NULL) { + return(0); + } + + /* + * Stop and free resources associated with scsi timeout timer + */ + if(DD_CTL.num_devs == 1) { + FCCLOCK_INFO * clock_info; + + if(SCSI_TMO) { + fc_clk_can(0, SCSI_TMO); + SCSI_TMO = 0; + } + clock_info = &DD_CTL.fc_clock_info; + ((struct watchdog *)(CLOCKWDT))->stopping = 1; + if (((struct watchdog *)(CLOCKWDT))->timer.function) + del_timer(&((struct watchdog *)(CLOCKWDT))->timer); + ((struct watchdog *)(CLOCKWDT))->timer.function=NULL; + ((struct watchdog *)(CLOCKWDT))->timeout_id=0; + } + fc_detach(instance); + + fc_kmem_free(DD_CTL.p_dev[instance], sizeof(fc_dev_ctl_t)); + DD_CTL.p_dev[instance] = 0; + fc_kmem_free(DD_CTL.p_config[instance], sizeof(icfgparam)); + DD_CTL.p_config[instance] = 0; + + kfree(fc_mem_dmapool[instance]); + return(0); +} + +/****************************************************************************** +* Function name : fc_abort +* +* Description : Linux mid-level command abort entry +* Note we are using the new error handling routines +******************************************************************************/ +int fc_abort(struct scsi_cmnd *Cmnd) +{ + struct Scsi_Host *host; + fc_dev_ctl_t *p_dev_ctl; + FC_BRD_INFO * binfo; + ulong iflg; + struct lpfc_dpc *ldp; + + + host = Cmnd->device->host; + if(!host) { +#ifdef FC_NEW_EH + return FAILED ; +#else + return SCSI_ABORT_NOT_RUNNING ; +#endif + } + p_dev_ctl = (fc_dev_ctl_t *)host->hostdata[0]; + if(!p_dev_ctl) { +#if FC_NEW_EH + return FAILED ; +#else + return SCSI_ABORT_NOT_RUNNING ; +#endif + } + binfo = &BINFO; + + iflg = 0; + LPFC_LOCK_DRIVER(5); + ldp = &lpfc_dpc[binfo->fc_brd_no]; + if (ldp->dpc_wait == NULL) { + LPFC_UNLOCK_DRIVER; +#if FC_NEW_EH + return SUCCESS; +#else + return SCSI_ABORT_SUCCESS ; +#endif + } + + fc_dpc_lstchk(p_dev_ctl, Cmnd); + if(p_dev_ctl->abort_head == NULL) { + p_dev_ctl->abort_head = (void *)Cmnd; + p_dev_ctl->abort_list = (void *)Cmnd; + } else { + SCMD_NEXT((struct scsi_cmnd *)(p_dev_ctl->abort_list)) = Cmnd; + p_dev_ctl->abort_list = (void *)Cmnd; + } + SCMD_NEXT(Cmnd) = NULL; + + + if (ldp->dpc_active == 0) { + LPFC_UNLOCK_DRIVER; + up(ldp->dpc_wait); + } + else { + LPFC_UNLOCK_DRIVER; + } + +#if FC_NEW_EH + return SUCCESS; +#else + return SCSI_ABORT_SUCCESS ; +#endif +} + +/****************************************************************************** +* Function name : do_fc_abort +* +* Description : +* +******************************************************************************/ +int do_fc_abort(fc_dev_ctl_t *p_dev_ctl) +{ + struct scsi_cmnd * Cmnd; + struct scsi_cmnd * oCmnd; + FC_BRD_INFO * binfo; + dvi_t * dev_ptr; + struct sc_buf * sp; + int dev_index,target; + fc_lun_t lun; + + binfo = &BINFO; + Cmnd = (struct scsi_cmnd *)p_dev_ctl->abort_head; + while(Cmnd) { + target = (int)Cmnd->device->id; + lun = (fc_lun_t)Cmnd->device->lun; + dev_index = INDEX(ZERO_PAN, target); + + dev_ptr = fc_find_lun(binfo, dev_index, lun); + /* SCSI layer issued abort device */ + fc_log_printf_msg_vargs( binfo->fc_brd_no, + &fc_msgBlk0712, /* ptr to msg structure */ + fc_mes0712, /* ptr to msg */ + fc_msgBlk0712.msgPreambleStr, /* begin varargs */ + target, + (uint32)lun, + Cmnd->cmnd[0], + Cmnd->serial_number); /* end varargs */ + if(!dev_ptr || !(dev_ptr->nodep)) { + goto done; + } + + if (dev_ptr->flags & CHK_SCSI_ABDR) { + goto done; + } + + sp = (struct sc_buf *)Cmnd->host_scribble; + if (lpfc_find_cmd(p_dev_ctl, Cmnd)) { + FCSTATCTR.fcpRsvd2++; + } else { + if (fc_abort_clk_blk(p_dev_ctl, lpfc_scsi_selto_timeout, sp, 0)) { + FCSTATCTR.fcpRsvd2++; + } + } +done: + oCmnd = Cmnd; + Cmnd = SCMD_NEXT(Cmnd); + SCMD_NEXT(oCmnd) = 0; + } + p_dev_ctl->abort_head = 0; + p_dev_ctl->abort_list = 0; + + return(0); +} + +#ifndef FC_NEW_EH +/****************************************************************************** +* Function name : lpfc_reset +* +* Description : +* +******************************************************************************/ +int lpfc_reset(struct scsi_cmnd *Cmnd, + unsigned int flags) +{ + int action; + + if( flags & SCSI_RESET_SUGGEST_HOST_RESET ) { + if((action = fc_reset_host(Cmnd)) == FAILED) + return(SCSI_RESET_ERROR); + action = SCSI_RESET_SUCCESS | SCSI_RESET_HOST_RESET; + } + else if( flags & SCSI_RESET_SUGGEST_BUS_RESET ) { + if((action = fc_reset_bus(Cmnd)) == FAILED) + return(SCSI_RESET_ERROR); + action = SCSI_RESET_SUCCESS | SCSI_RESET_BUS_RESET; + } + else { + if((action = fc_reset_device(Cmnd)) == FAILED) + return(SCSI_RESET_ERROR); + action = SCSI_RESET_SUCCESS; + } + return(action); +} +#endif + +/****************************************************************************** +* Function name : fc_reset_device +* +* Description : Linux mid-level reset device entry +* Note we are using the new error handling routines +* In the old handlers there is only one reset entry which has +* two arguments +******************************************************************************/ +int fc_reset_device(struct scsi_cmnd *Cmnd) +{ + struct Scsi_Host *host; + fc_dev_ctl_t *p_dev_ctl; + FC_BRD_INFO *binfo; + ulong iflg; + struct lpfc_dpc *ldp; + + host = Cmnd->device->host; + if(!host) { + return FAILED ; + } + p_dev_ctl = (fc_dev_ctl_t *)host->hostdata[0]; + if(!p_dev_ctl) { + return FAILED; + } + binfo = &BINFO; + + iflg = 0; + LPFC_LOCK_DRIVER(6); + ldp = &lpfc_dpc[binfo->fc_brd_no]; + if (ldp->dpc_wait == NULL) { + LPFC_UNLOCK_DRIVER; + return SUCCESS; + } + + fc_dpc_lstchk(p_dev_ctl, Cmnd); + if(p_dev_ctl->rdev_head == NULL) { + p_dev_ctl->rdev_head = (void *)Cmnd; + p_dev_ctl->rdev_list = (void *)Cmnd; + } else { + SCMD_NEXT((struct scsi_cmnd *)(p_dev_ctl->rdev_list)) = Cmnd; + p_dev_ctl->rdev_list = (void *)Cmnd; + } + SCMD_NEXT(Cmnd) = NULL; + + if (ldp->dpc_active == 0) { + LPFC_UNLOCK_DRIVER; + up(ldp->dpc_wait); + } + else { + LPFC_UNLOCK_DRIVER; + } + + return SUCCESS; +} + +/****************************************************************************** +* Function name : do_fc_reset_device +* +* Description : +* +******************************************************************************/ +int do_fc_reset_device(fc_dev_ctl_t *p_dev_ctl) +{ + struct scsi_cmnd * Cmnd; + struct scsi_cmnd * oCmnd; + struct dev_info * dev_ptr; + FC_BRD_INFO * binfo; + int dev_index, target, j; + fc_lun_t lun; + + binfo = &BINFO; + Cmnd = (struct scsi_cmnd *)p_dev_ctl->rdev_head; + while(Cmnd) { + target = (int)Cmnd->device->id; + lun = (fc_lun_t)Cmnd->device->lun; + dev_index = INDEX(ZERO_PAN, target); + + dev_ptr = fc_find_lun(binfo, dev_index, lun); + j = 0; + /* SCSI layer issued target reset */ + fc_log_printf_msg_vargs( binfo->fc_brd_no, + &fc_msgBlk0713, /* ptr to msg structure */ + fc_mes0713, /* ptr to msg */ + fc_msgBlk0713.msgPreambleStr, /* begin varargs */ + target, + (uint32)lun, + dev_index); /* end varargs */ + if(dev_ptr == 0) { + goto done; + } + if ((binfo->fc_ffstate != FC_READY) || + (!(dev_ptr->nodep)) || + (dev_ptr->nodep->rpi == 0xfffe)) { + goto done; + } + fc_fcp_abort(p_dev_ctl, TARGET_RESET, dev_index, -1); + + +done: + oCmnd = Cmnd; + Cmnd = SCMD_NEXT(Cmnd); + SCMD_NEXT(oCmnd) = 0; + } + p_dev_ctl->rdev_head = 0; + p_dev_ctl->rdev_list = 0; + + return(0); +} + +/****************************************************************************** +* Function name : fc_reset_bus +* +* Description : Linux mid-level reset host/bus entry +* +******************************************************************************/ +int fc_reset_bus(struct scsi_cmnd *Cmnd) +{ + struct Scsi_Host *host; + fc_dev_ctl_t *p_dev_ctl; + FC_BRD_INFO *binfo; + ulong iflg; + struct lpfc_dpc *ldp; + + host = Cmnd->device->host; + if(!host) { + return FAILED; + } + p_dev_ctl = (fc_dev_ctl_t *)host->hostdata[0]; + if(!p_dev_ctl) { + return FAILED; + } + binfo = &p_dev_ctl->info; + + iflg = 0; + LPFC_LOCK_DRIVER(8); + ldp = &lpfc_dpc[binfo->fc_brd_no]; + if (ldp->dpc_wait == NULL) { + LPFC_UNLOCK_DRIVER; + return SUCCESS; + } + + fc_dpc_lstchk(p_dev_ctl, Cmnd); + if(p_dev_ctl->rbus_head == NULL) { + p_dev_ctl->rbus_head = (void *)Cmnd; + p_dev_ctl->rbus_list = (void *)Cmnd; + } else { + SCMD_NEXT((struct scsi_cmnd *)(p_dev_ctl->rbus_list)) = Cmnd; + p_dev_ctl->rbus_list = (void *)Cmnd; + } + SCMD_NEXT(Cmnd) = NULL; + + if (ldp->dpc_active == 0) { + LPFC_UNLOCK_DRIVER; + up(ldp->dpc_wait); + } + else { + LPFC_UNLOCK_DRIVER; + } + + return SUCCESS; +} + +/****************************************************************************** +* Function name : do_fc_reset_bus +* +* Description : +* +******************************************************************************/ +int do_fc_reset_bus(fc_dev_ctl_t *p_dev_ctl) +{ + struct scsi_cmnd * Cmnd; + struct scsi_cmnd * oCmnd; + FC_BRD_INFO *binfo; + node_t * node_ptr; + struct dev_info * dev_ptr; + NODELIST * nlp; + NODELIST * new_nlp; + iCfgParam *clp; + int rets = FAILED; + + binfo = &p_dev_ctl->info; + clp = DD_CTL.p_config[binfo->fc_brd_no]; + Cmnd = (struct scsi_cmnd *)p_dev_ctl->rbus_head; + while(Cmnd) { + /* SCSI layer issued Bus Reset */ + fc_log_printf_msg_vargs( binfo->fc_brd_no, + &fc_msgBlk0714, /* ptr to msg structure */ + fc_mes0714, /* ptr to msg */ + fc_msgBlk0714.msgPreambleStr, /* begin varargs */ + Cmnd->device->id, + (uint32)Cmnd->device->lun); /* end varargs */ + /* + * Tell them + */ + if (binfo->fc_ffstate == FC_READY) { + rets = SUCCESS; + fc_fcp_abort(p_dev_ctl, TARGET_RESET, -1, -1); + } + else { + /* + * Check to see if we should wait for FC_READY + */ + if ((binfo->fc_ffstate < FC_LINK_DOWN) || + (binfo->fc_ffstate == FC_ERROR)) { + rets = FAILED; + } + else { + rets = SUCCESS; + } + } + + /* Reset first_check */ + nlp = binfo->fc_nlpmap_start; + while(nlp != (NODELIST *)&binfo->fc_nlpmap_start) { + new_nlp = (NODELIST *)nlp->nlp_listp_next; + if (nlp->nlp_type & NLP_FCP_TARGET) { + if(clp[CFG_FIRST_CHECK].a_current) { + /* If we are an FCP node, update first_check flag for all LUNs */ + if ((node_ptr = (node_t * )nlp->nlp_targetp) != NULL) { + for (dev_ptr = node_ptr->lunlist; dev_ptr != NULL; + dev_ptr = dev_ptr->next) { + dev_ptr->first_check = FIRST_CHECK_COND; + } + } + } + } + nlp = new_nlp; + } + oCmnd = Cmnd; + Cmnd = SCMD_NEXT(Cmnd); + SCMD_NEXT(oCmnd) = 0; + } + p_dev_ctl->rbus_head = 0; + p_dev_ctl->rbus_list = 0; + + return rets; +} + +/****************************************************************************** +* Function name : fc_reset_host +* +* Description : +* +******************************************************************************/ +int fc_reset_host(struct scsi_cmnd *Cmnd) +{ + struct Scsi_Host *host; + fc_dev_ctl_t *p_dev_ctl; + FC_BRD_INFO *binfo; + ulong iflg; + struct lpfc_dpc *ldp; + + host = Cmnd->device->host; + if(!host) { + return FAILED; + } + p_dev_ctl = (fc_dev_ctl_t *)host->hostdata[0]; + if(!p_dev_ctl) { + return FAILED; + } + binfo = &p_dev_ctl->info; + + iflg = 0; + LPFC_LOCK_DRIVER(10); + ldp = &lpfc_dpc[binfo->fc_brd_no]; + if (ldp->dpc_wait == NULL) { + LPFC_UNLOCK_DRIVER; + return SUCCESS; + } + + fc_dpc_lstchk(p_dev_ctl, Cmnd); + if(p_dev_ctl->rhst_head == NULL) { + p_dev_ctl->rhst_head = (void *)Cmnd; + p_dev_ctl->rhst_list = (void *)Cmnd; + } else { + SCMD_NEXT((struct scsi_cmnd *)(p_dev_ctl->rhst_list)) = Cmnd; + p_dev_ctl->rhst_list = (void *)Cmnd; + } + SCMD_NEXT(Cmnd) = NULL; + + if (ldp->dpc_active == 0) { + LPFC_UNLOCK_DRIVER; + up(ldp->dpc_wait); + } + else { + LPFC_UNLOCK_DRIVER; + } + + return SUCCESS; +} + +/****************************************************************************** +* Function name : do_fc_reset_host +* +* Description : +* +******************************************************************************/ +int do_fc_reset_host(fc_dev_ctl_t *p_dev_ctl) +{ + struct scsi_cmnd * Cmnd; + struct scsi_cmnd * oCmnd; + FC_BRD_INFO *binfo; + int rets = FAILED; + + binfo = &p_dev_ctl->info; + Cmnd = (struct scsi_cmnd *)p_dev_ctl->rhst_head; + while(Cmnd) { + /* SCSI layer issued Host Reset */ + fc_log_printf_msg_vargs( binfo->fc_brd_no, + &fc_msgBlk0715, /* ptr to msg structure */ + fc_mes0715, /* ptr to msg */ + fc_msgBlk0715.msgPreambleStr, /* begin varargs */ + Cmnd->device->id, + (uint32)Cmnd->device->lun); /* end varargs */ + /* + * Check to see if we should wait for FC_READY + */ + if ((binfo->fc_ffstate < FC_LINK_DOWN) || (binfo->fc_ffstate == FC_ERROR)) { + rets = FAILED; + } + else { + rets = SUCCESS; + } + oCmnd = Cmnd; + Cmnd = SCMD_NEXT(Cmnd); + SCMD_NEXT(oCmnd) = 0; + } + p_dev_ctl->rhst_head = 0; + p_dev_ctl->rhst_list = 0; + + return(rets); +} + + +static char addrStr[18]; + +/****************************************************************************** +* Function name : addr_sprintf +* +* Description : Used by fc_info for displaying WWNN / WWPNs +* +******************************************************************************/ +_static_ char * addr_sprintf(register uchar *ap) +{ + register int i; + register char *cp = addrStr; + static char digits[] = "0123456789abcdef"; + + for (i = 0; i < 8; i++) { + *cp++ = digits[*ap >> 4]; + *cp++ = digits[*ap++ & 0xf]; + *cp++ = ':'; + } + *--cp = 0; + return(addrStr); +} /* End addr_sprintf */ + +/****************************************************************************** +* Function name : fc_info +* +* Description : Prepare host information for mid-level +* +******************************************************************************/ +const char *fc_info(struct Scsi_Host *host) +{ + static char buf[4096]; + fc_dev_ctl_t *p_dev_ctl; + FC_BRD_INFO * binfo; + struct pci_dev *pdev; + char *multip; + int idx, i, j, incr; + char hdw[9]; + NODELIST *nlp; + + buf[0]='\0'; + p_dev_ctl = (fc_dev_ctl_t *)host->hostdata[0]; + if(!p_dev_ctl) + return buf; + binfo = &BINFO; + pdev = p_dev_ctl->pcidev ; + + for(idx=0; idx < MAX_FC_BRDS; idx++) { + if(p_dev_ctl == DD_CTL.p_dev[idx]) + break; + } + + multip = "LPFC"; + + if (!(p_dev_ctl->dev_flag & FC_FULL_INFO_CALL)) { + if(pdev != NULL) { + switch(pdev->device){ + case PCI_DEVICE_ID_CENTAUR: + if(FC_JEDEC_ID(VPD.rev.biuRev) == CENTAUR_2G_JEDEC_ID) { + sprintf(&buf[strlen(buf)], + "HBA: Emulex LightPulse LP9002 on PCI bus %02x device %02x irq %d", + p_dev_ctl->pcidev->bus->number, p_dev_ctl->pcidev->devfn, + p_dev_ctl->pcidev->irq); + } else { + sprintf(&buf[strlen(buf)], + "HBA: Emulex LightPulse LP9000 on PCI bus %02x device %02x irq %d", + p_dev_ctl->pcidev->bus->number, p_dev_ctl->pcidev->devfn, + p_dev_ctl->pcidev->irq); + } + break; + case PCI_DEVICE_ID_DRAGONFLY: + sprintf(&buf[strlen(buf)], + "HBA: Emulex LightPulse LP8000 on PCI bus %02x device %02x irq %d", + p_dev_ctl->pcidev->bus->number, p_dev_ctl->pcidev->devfn, + p_dev_ctl->pcidev->irq); + break; + case PCI_DEVICE_ID_PEGASUS: + sprintf(&buf[strlen(buf)], + "HBA: Emulex LightPulse LP9802 on PCI bus %02x device %02x irq %d", + p_dev_ctl->pcidev->bus->number, p_dev_ctl->pcidev->devfn, + p_dev_ctl->pcidev->irq); + break; + case PCI_DEVICE_ID_PFLY: + sprintf(&buf[strlen(buf)], + "HBA: Emulex LightPulse LP982 on PCI bus %02x device %02x irq %d", + p_dev_ctl->pcidev->bus->number, p_dev_ctl->pcidev->devfn, + p_dev_ctl->pcidev->irq); + break; + case PCI_DEVICE_ID_THOR: + sprintf(&buf[strlen(buf)], + "HBA: Emulex LightPulse LP10000 on PCI bus %02x device %02x irq %d", + p_dev_ctl->pcidev->bus->number, p_dev_ctl->pcidev->devfn, + p_dev_ctl->pcidev->irq); + break; + case PCI_DEVICE_ID_TFLY: + sprintf(&buf[strlen(buf)], + "HBA: Emulex LightPulse LP1050 on PCI bus %02x device %02x irq %d", + p_dev_ctl->pcidev->bus->number, p_dev_ctl->pcidev->devfn, + p_dev_ctl->pcidev->irq); + break; + default: + sprintf(&buf[strlen(buf)], + "HBA: Emulex LightPulse on PCI bus %02x device %02x irq %d", + p_dev_ctl->pcidev->bus->number, p_dev_ctl->pcidev->devfn, + p_dev_ctl->pcidev->irq); + } + } + p_dev_ctl->dev_flag |= FC_FULL_INFO_CALL; + return(buf); + } + + sprintf(buf, "Emulex LightPulse %s Driver Version: %s\n", + multip, lpfc_release_version); + + if(pdev != NULL) { + switch(pdev->device){ + case PCI_DEVICE_ID_CENTAUR: + if(FC_JEDEC_ID(VPD.rev.biuRev) == CENTAUR_2G_JEDEC_ID) { + sprintf(&buf[strlen(buf)], + "HBA: Emulex LightPulse LP9002 2 Gigabit PCI Fibre Channel Adapter\n"); + } else { + sprintf(&buf[strlen(buf)], + "HBA: Emulex LightPulse LP9000 1 Gigabit PCI Fibre Channel Adapter\n"); + } + break; + case PCI_DEVICE_ID_DRAGONFLY: + sprintf(&buf[strlen(buf)], + "HBA: Emulex LightPulse LP8000 1 Gigabit PCI Fibre Channel Adapter\n"); + break; + case PCI_DEVICE_ID_PEGASUS: + sprintf(&buf[strlen(buf)], + "HBA: Emulex LightPulse LP9802 2 Gigabit PCI Fibre Channel Adapter\n"); + break; + case PCI_DEVICE_ID_PFLY: + sprintf(&buf[strlen(buf)], + "HBA: Emulex LightPulse LP982 2 Gigabit PCI Fibre Channel Adapter\n"); + break; + case PCI_DEVICE_ID_THOR: + sprintf(&buf[strlen(buf)], + "HBA: Emulex LightPulse LP10000 2 Gigabit PCI Fibre Channel Adapter\n"); + break; + case PCI_DEVICE_ID_TFLY: + sprintf(&buf[strlen(buf)], + "HBA: Emulex LightPulse LP1050 2 Gigabit PCI Fibre Channel Adapter\n"); + break; + default: + sprintf(&buf[strlen(buf)], + "HBA: Emulex LightPulse PCI Fibre Channel Adapter\n"); + } + } + + sprintf(&buf[strlen(buf)], "SerialNum: %s\n", binfo->fc_SerialNumber); + + decode_firmware_rev(binfo, &VPD); + sprintf(&buf[strlen(buf)], "Firmware Version: %s\n", fwrevision); + + sprintf(&buf[strlen(buf)], "Hdw: "); + /* Convert JEDEC ID to ascii for hardware version */ + incr = VPD.rev.biuRev; + for(i=0;i<8;i++) { + j = (incr & 0xf); + if(j <= 9) + hdw[7-i] = (char)((uchar)0x30 + (uchar)j); + else + hdw[7-i] = (char)((uchar)0x61 + (uchar)(j-10)); + incr = (incr >> 4); + } + hdw[8] = 0; + strcat(buf, hdw); + + sprintf(&buf[strlen(buf)], "\nVendorId: 0x%x\n", + ((((uint32)pdev->device) << 16) | (uint32)(pdev->vendor))); + + sprintf(&buf[strlen(buf)], "Portname: "); + strcat(buf, addr_sprintf((uchar *)&binfo->fc_portname)); + + sprintf(&buf[strlen(buf)], " Nodename: "); + strcat(buf, addr_sprintf((uchar *)&binfo->fc_nodename)); + + switch (binfo->fc_ffstate) { + case FC_INIT_START: + case FC_INIT_NVPARAMS: + case FC_INIT_REV: + case FC_INIT_PARTSLIM: + case FC_INIT_CFGRING: + case FC_INIT_INITLINK: + case FC_LINK_DOWN: + sprintf(&buf[strlen(buf)], "\n\nLink Down\n"); + break; + case FC_LINK_UP: + case FC_INIT_SPARAM: + case FC_CFG_LINK: + sprintf(&buf[strlen(buf)], "\n\nLink Up\n"); + break; + case FC_FLOGI: + case FC_LOOP_DISC: + case FC_NS_REG: + case FC_NS_QRY: + case FC_NODE_DISC: + case FC_REG_LOGIN: + case FC_CLEAR_LA: + sprintf(&buf[strlen(buf)], "\n\nLink Up - Discovery\n"); + break; + case FC_READY: + sprintf(&buf[strlen(buf)], "\n\nLink Up - Ready:\n"); + sprintf(&buf[strlen(buf)], " PortID 0x%x\n", binfo->fc_myDID); + if (binfo->fc_topology == TOPOLOGY_LOOP) { + if(binfo->fc_flag & FC_PUBLIC_LOOP) + sprintf(&buf[strlen(buf)], " Public Loop\n"); + else + sprintf(&buf[strlen(buf)], " Private Loop\n"); + } else { + if(binfo->fc_flag & FC_FABRIC) + sprintf(&buf[strlen(buf)], " Fabric\n"); + else + sprintf(&buf[strlen(buf)], " Point-2-Point\n"); + } + + if(binfo->fc_linkspeed == LA_2GHZ_LINK) + sprintf(&buf[strlen(buf)], " Current speed 2G\n"); + else + sprintf(&buf[strlen(buf)], " Current speed 1G\n"); + + nlp = binfo->fc_nlpmap_start; + while(nlp != (NODELIST *)&binfo->fc_nlpmap_start) { + if (nlp->nlp_state == NLP_ALLOC) { + sprintf(&buf[strlen(buf)], "\nlpfc%dt%02x DID %06x WWPN ", + idx, FC_SCSID(nlp->id.nlp_pan, nlp->id.nlp_sid), nlp->nlp_DID); + strcat(buf, addr_sprintf((uchar *)&nlp->nlp_portname)); + strcat(buf, " WWNN "); + strcat(buf, addr_sprintf((uchar *)&nlp->nlp_nodename)); + } + if ((4096 - strlen(buf)) < 90) + break; + nlp = (NODELIST *)nlp->nlp_listp_next; + } + if(nlp != (NODELIST *)&binfo->fc_nlpmap_start) + strcat(buf,"\n....\n"); + } + + return (buf); +} + +/****************************************************************************** +* Function name : fc_data_direction +* +* Description : If we do not relay on Cmnd->sc_data_direction call this +* routine to determine if we are doing a read or write. +* +******************************************************************************/ +int fc_data_direction(struct scsi_cmnd *Cmnd) +{ + int ret_code; + + switch (Cmnd->cmnd[0]) { + case WRITE_6: + case WRITE_10: + case WRITE_12: + case CHANGE_DEFINITION: + case LOG_SELECT: + case MODE_SELECT: + case MODE_SELECT_10: + case WRITE_BUFFER: + case VERIFY: + case WRITE_VERIFY: + case WRITE_VERIFY_12: + case WRITE_LONG: + case WRITE_LONG_2: + case WRITE_SAME: + case SEND_DIAGNOSTIC: + case FORMAT_UNIT: + case REASSIGN_BLOCKS: + case FCP_SCSI_RELEASE_LUNR: + case FCP_SCSI_RELEASE_LUNV: + case HPVA_SETPASSTHROUGHMODE: + case HPVA_EXECUTEPASSTHROUGH: + case HPVA_CREATELUN: + case HPVA_SETLUNSECURITYLIST: + case HPVA_SETCLOCK: + case HPVA_RECOVER: + case HPVA_GENERICSERVICEOUT: + case DMEP_EXPORT_OUT: + ret_code = B_WRITE; + break; + case MDACIOCTL_DIRECT_CMD: + switch (Cmnd->cmnd[2]) { + case MDACIOCTL_STOREIMAGE: + case MDACIOCTL_WRITESIGNATURE: + case MDACIOCTL_SETREALTIMECLOCK: + case MDACIOCTL_PASS_THRU_CDB: + case MDACIOCTL_CREATENEWCONF: + case MDACIOCTL_ADDNEWCONF: + case MDACIOCTL_MORE: + case MDACIOCTL_SETPHYSDEVPARAMETER: + case MDACIOCTL_SETLOGDEVPARAMETER: + case MDACIOCTL_SETCONTROLLERPARAMETER: + case MDACIOCTL_WRITESANMAP: + case MDACIOCTL_SETMACADDRESS: + ret_code = B_WRITE; + break; + case MDACIOCTL_PASS_THRU_INITIATE: + if (Cmnd->cmnd[3] & 0x80) { + ret_code = B_WRITE; + } + else { + ret_code = B_READ; + } + break; + default: + ret_code = B_READ; + } + break; + default: +#if LINUX_VERSION_CODE >= LinuxVersionCode(2,4,0) + if (Cmnd->sc_data_direction == SCSI_DATA_WRITE) + ret_code = B_WRITE; + else +#endif + ret_code = B_READ; + } +#if LINUX_VERSION_CODE >= LinuxVersionCode(2,4,0) + if(ret_code == B_WRITE) + Cmnd->sc_data_direction = SCSI_DATA_WRITE; + else + Cmnd->sc_data_direction = SCSI_DATA_READ; +#endif + return ret_code; +} + +int +chkLun( +node_t *node_ptr, +fc_lun_t lun) +{ + uint32 rptLunLen; + uint32 *datap32; + uint32 lunvalue, i; + + if(node_ptr->virtRptLunData) { + datap32 = (uint32 *)node_ptr->virtRptLunData; + rptLunLen = SWAP_DATA(*datap32); + for(i=0; i < rptLunLen; i+=8) { + datap32 += 2; + lunvalue = (((* datap32) >> FC_LUN_SHIFT) & 0xff); + if (lunvalue == (uint32)lun) + return 1; + } + return 0; + } + else { + return 1; + } +} +/****************************************************************************** +* Function name : fc_queuecommand +* +* Description : Linux queue command entry +* +******************************************************************************/ +int fc_queuecommand(struct scsi_cmnd *Cmnd, + void (*done)(struct scsi_cmnd *)) +{ + FC_BRD_INFO * binfo; + struct Scsi_Host *host; + fc_dev_ctl_t *p_dev_ctl; + iCfgParam *clp; + struct dev_info *dev_ptr; + node_t *node_ptr; + struct sc_buf *sp; + int dev_index,target,retcod; + fc_lun_t lun; + ulong iflg; + struct lpfc_dpc *ldp; + + + host = Cmnd->device->host; + fc_bzero(Cmnd->sense_buffer, 16); + if(!host){ + retcod=DID_BAD_TARGET; + Cmnd->result = ScsiResult(retcod, 0); + done(Cmnd); + return(0); + } + Cmnd->scsi_done = done; /* Save done routine for this command */ + + p_dev_ctl = (fc_dev_ctl_t *)host->hostdata[0]; + if(p_dev_ctl == 0) { + retcod=DID_BAD_TARGET; + Cmnd->result = ScsiResult(retcod, 0); + done(Cmnd); + return(0); + } + + + retcod = 0; + binfo = &BINFO; + clp = DD_CTL.p_config[binfo->fc_brd_no]; + + LPFC_LOCK_DRIVER(12); + ldp = &lpfc_dpc[binfo->fc_brd_no]; + if (ldp->dpc_wait == NULL) { + retcod=DID_NO_CONNECT; +#if LINUX_VERSION_CODE >= LinuxVersionCode(2,4,0) + if(lpfc_use_removable) { + Cmnd->sense_buffer[0] = 0x70; + Cmnd->sense_buffer[2] = UNIT_ATTENTION; + Cmnd->device->removable = 1; + } +#endif + Cmnd->result = ScsiResult(retcod, 0); + FCSTATCTR.fcpRsvd8++; + done(Cmnd); + LPFC_UNLOCK_DRIVER; + return(0); + } + + target = (int)Cmnd->device->id; + lun = (fc_lun_t)Cmnd->device->lun; + + if(lun > MAX_FCP_LUN) { + retcod=DID_BAD_TARGET; + Cmnd->result = ScsiResult(retcod, 0); + LPFC_UNLOCK_DRIVER; + done(Cmnd); + return(0); + } + + /* + * Device for target/lun + */ + dev_index = INDEX(ZERO_PAN, target); + if (!(dev_ptr = fc_find_lun(binfo, dev_index, lun))) { + if(!(dev_ptr=fc_getDVI(p_dev_ctl, target, lun))){ + retcod=DID_NO_CONNECT; + Cmnd->result = ScsiResult(retcod, 0); + FCSTATCTR.fcpRsvd3++; + LPFC_UNLOCK_DRIVER; + done(Cmnd); + return(0); + } + } + + node_ptr = binfo->device_queue_hash[dev_index].node_ptr; + if((node_ptr) && + ((node_ptr->flags & FC_NODEV_TMO) || (lun >= node_ptr->max_lun))) { + retcod=DID_NO_CONNECT; + Cmnd->result = ScsiResult(retcod, 0); + LPFC_UNLOCK_DRIVER; + done(Cmnd); + return(0); + } + + if((node_ptr) && (Cmnd->cmnd[0] == 0x12) && (!chkLun(node_ptr, lun))) { + retcod=DID_NO_CONNECT; + Cmnd->result = ScsiResult(retcod, 0); + LPFC_UNLOCK_DRIVER; + done(Cmnd); + return(0); + } + + if(binfo->fc_flag & FC_LD_TIMEOUT) { + retcod=DID_NO_CONNECT; + Cmnd->result = ScsiResult(retcod, 0); + LPFC_UNLOCK_DRIVER; + done(Cmnd); + return(0); + } + + dev_ptr->qcmdcnt++; + + sp = dev_ptr->scp; + if(!sp){ + retcod=DID_NO_CONNECT; + Cmnd->result = ScsiResult(retcod, 0); + dev_ptr->iodonecnt++; + dev_ptr->errorcnt++; + FCSTATCTR.fcpRsvd5++; + LPFC_UNLOCK_DRIVER; + done(Cmnd); + return(0); + } + + Cmnd->host_scribble = (void *)sp; + dev_ptr->scp = sp->bufstruct.av_forw; + dev_ptr->scpcnt--; + fc_bzero(sp,sizeof(struct sc_buf)); + sp->bufstruct.cmnd = Cmnd; + sp->current_devp = dev_ptr; + FCSTATCTR.fcpRsvd0++; + lpfc_scsi_delete_timer(Cmnd); + + /* Since we delete active timers, we can use eh_timeout.data as a linked + * list ptr internally within the driver. + */ + if(p_dev_ctl->qcmd_head == NULL) { + p_dev_ctl->qcmd_head = (void *)Cmnd; + p_dev_ctl->qcmd_list = (void *)Cmnd; + } else { + ((struct scsi_cmnd *)(p_dev_ctl->qcmd_list))->eh_timeout.data = (ulong)Cmnd; + p_dev_ctl->qcmd_list = (void *)Cmnd; + } + Cmnd->eh_timeout.data = (unsigned long) NULL; + + if (ldp->dpc_active == 0) { + LPFC_UNLOCK_DRIVER; + up(ldp->dpc_wait); + } + else { + LPFC_UNLOCK_DRIVER; + } + return 0; +} + +/****************************************************************************** +* Function name : do_fc_queuecommand +* +* Description : +* +******************************************************************************/ +int do_fc_queuecommand(fc_dev_ctl_t *p_dev_ctl, + ulong siflg) +{ + FC_BRD_INFO * binfo; + iCfgParam * clp; + struct dev_info * dev_ptr; + struct sc_buf * sp; + struct buf * bp; + struct scsi_cmnd * Cmnd; + struct scsi_cmnd * oCmnd; + int i, retcod, firstin; + + binfo = &BINFO; + clp = DD_CTL.p_config[binfo->fc_brd_no]; + Cmnd = (struct scsi_cmnd *)p_dev_ctl->qcmd_head; + firstin = 1; + + + while(Cmnd) { + sp = (struct sc_buf *)(Cmnd->host_scribble); + dev_ptr = sp->current_devp; + + sp->flags = SC_RESUME; + + + IOcnt++; + /* + * Buffer count depends on whether scatter-gather is used or not + */ + if(!Cmnd->use_sg){ + sp->bufstruct.b_bcount = (int)Cmnd->request_bufflen; + } + else { + struct scatterlist *scatter = (struct scatterlist *)Cmnd->buffer; + sp->bufstruct.b_bcount = 0; + + for(i=0; i < Cmnd->use_sg; i++) + sp->bufstruct.b_bcount += scatter[i].length; + } + + /* + * Set read/write flag + */ +#if LINUX_VERSION_CODE > LinuxVersionCode(2,4,4) + if(lpfc_use_data_direction) { + if(Cmnd->sc_data_direction == SCSI_DATA_WRITE) + sp->bufstruct.b_flags = B_WRITE; + else + sp->bufstruct.b_flags = B_READ; + } + else { + sp->bufstruct.b_flags = fc_data_direction(Cmnd); + } +#else + sp->bufstruct.b_flags = fc_data_direction(Cmnd); +#endif + + if (Cmnd->cmnd[0] == TEST_UNIT_READY) + sp->bufstruct.b_bcount = 0; + + /* + * Fill in the sp struct + */ + bcopy((void *)Cmnd->cmnd, (void *)&sp->scsi_command.scsi_cmd, 16); + + sp->scsi_command.scsi_length=Cmnd->cmd_len; + sp->scsi_command.scsi_id=Cmnd->device->id; + sp->scsi_command.scsi_lun=Cmnd->device->lun; + if (Cmnd->device->tagged_supported) { + switch (Cmnd->tag) { + case HEAD_OF_QUEUE_TAG: + sp->scsi_command.flags = HEAD_OF_Q; + break; + case ORDERED_QUEUE_TAG: + sp->scsi_command.flags = ORDERED_Q; + break; + default: + sp->scsi_command.flags = SIMPLE_Q; + break; + } + } + else + sp->scsi_command.flags = 0; + + sp->timeout_value = Cmnd->timeout_per_command / fc_ticks_per_second; + sp->adap_q_status = 0; + sp->bufstruct.av_forw = NULL; + + retcod = 0; + if(p_dev_ctl->device_state == DEAD) { + retcod=DID_NO_CONNECT; + Cmnd->result = ScsiResult(retcod, 0); + FCSTATCTR.fcpRsvd8++; + goto done; + } + + /* + * Is it a valid target? + */ + if((dev_ptr == 0) || (dev_ptr->nodep == 0)) { + retcod=DID_NO_CONNECT; + Cmnd->result = ScsiResult(retcod, 0); + FCSTATCTR.fcpRsvd4++; + goto done; + } + + if(dev_ptr->nodep == 0) { + FCSTATCTR.fcpRsvd6++; + retcod=DID_SOFT_ERROR; + } + else { + if((clp[CFG_LINKDOWN_TMO].a_current == 0) || clp[CFG_HOLDIO].a_current) { + retcod=0; + } + else { + retcod=0; + if (binfo->fc_flag & FC_LD_TIMEOUT) { + if(clp[CFG_NODEV_TMO].a_current == 0) { + retcod=DID_SOFT_ERROR; + FCSTATCTR.fcpRsvd7++; + } + else { + if(dev_ptr->nodep->flags & FC_NODEV_TMO) { + retcod=DID_SOFT_ERROR; + FCSTATCTR.fcpRsvd7++; + } + } + } + } + } + if(retcod) + goto done; + retcod=DID_OK; + + + if (dev_ptr->pend_head == NULL) { + dev_ptr->pend_head = sp; + dev_ptr->pend_tail = sp; + } else { + dev_ptr->pend_tail->bufstruct.av_forw = (struct buf *)sp; + dev_ptr->pend_tail = sp; + } + dev_ptr->pend_count++; + + /* + * put on the DEVICE_WAITING_head + */ + fc_enq_wait(dev_ptr); + + /* + * Send out the SCSI REPORT LUN command before sending the very + * first SCSI command to that device. + */ + if (dev_ptr->nodep->rptlunstate == REPORT_LUN_REQUIRED) { + dev_ptr->nodep->rptlunstate = REPORT_LUN_ONGOING; + issue_report_lun(p_dev_ctl, dev_ptr, 0); + } else { + if ( (dev_ptr->nodep->rptlunstate == REPORT_LUN_COMPLETE) && + !(dev_ptr->flags & CHK_SCSI_ABDR) && dev_ptr->numfcbufs) + fc_issue_cmd(p_dev_ctl); + } + + /* + * Done + */ +done: + if(retcod!=DID_OK) { + dev_ptr->iodonecnt++; + dev_ptr->errorcnt++; + bp = (struct buf *) sp; + bp->b_error = EIO; + bp->b_flags |= B_ERROR; + sp->status_validity = SC_ADAPTER_ERROR; + sp->general_card_status = SC_SCSI_BUS_RESET; + fc_delay_iodone(p_dev_ctl, sp); + } + oCmnd = Cmnd; + Cmnd = (struct scsi_cmnd *)Cmnd->eh_timeout.data; + oCmnd->eh_timeout.data = 0; + } + p_dev_ctl->qcmd_head = 0; + p_dev_ctl->qcmd_list = 0; + + return 0; +} + +/****************************************************************************** +* Function name : fc_rtalloc +* +* Description : +* +******************************************************************************/ +_local_ int fc_rtalloc(fc_dev_ctl_t *p_dev_ctl, + struct dev_info *dev_ptr) +{ + int i; + unsigned int size; + fc_buf_t *fcptr; + struct sc_buf *sp; + dma_addr_t phys; + FC_BRD_INFO * binfo; + MBUF_INFO * buf_info; + MBUF_INFO bufinfo; + + binfo = &p_dev_ctl->info; + for (i = 0; i < dev_ptr->fcp_lun_queue_depth+1 ; i++) { + + size = fc_po2(sizeof(fc_buf_t)); + phys = (dma_addr_t)((ulong)INVALID_PHYS); + + buf_info = &bufinfo; + buf_info->size = size; + buf_info->flags = FC_MBUF_DMA; + buf_info->align = size; + buf_info->phys = 0; + buf_info->dma_handle = 0; + buf_info->data_handle = 0; + fc_malloc(p_dev_ctl, buf_info); + fcptr = buf_info->virt; + phys = (dma_addr_t)((ulong)buf_info->phys); + if (!fcptr || is_invalid_phys((void *)((ulong)phys))) { + return(0); + } + + fc_bzero(fcptr, sizeof(fc_buf_t)); + + fcptr->dev_ptr = dev_ptr; + fcptr->phys_adr = (void *)((ulong)phys); + +#if LINUX_VERSION_CODE >= LinuxVersionCode(2,4,0) + fcptr->fc_cmd_dma_handle = (ulong *)fcptr->phys_adr; +#endif + fc_enq_fcbuf(fcptr); + + sp = (struct sc_buf *)fc_kmem_zalloc(sizeof(struct sc_buf)); + if (!sp) { + return(0); + } + if(dev_ptr->scp) { + sp->bufstruct.av_forw = dev_ptr->scp; + dev_ptr->scp = sp; + } + else { + dev_ptr->scp = sp; + dev_ptr->scp->bufstruct.av_forw = 0; + } + dev_ptr->scpcnt++; + } /* end for loop */ + return(1); +} /* end of fc_rtalloc */ + +/****************************************************************************** +* Function name : do_fc_intr_handler +* +* Description : Local interupt handler +* +******************************************************************************/ +irqreturn_t do_fc_intr_handler(int irq, + void *dev_id, + struct pt_regs *regs) +{ + struct intr *ihs; + FC_BRD_INFO * binfo; + fc_dev_ctl_t * p_dev_ctl; + void *ioa; + volatile uint32 ha_copy; + uint32 i; + ulong siflg; + ulong iflg; + + /* + * If driver is unloading, we can stop processing interrupt. + */ + if (lpfc_driver_unloading) + return IRQ_HANDLED; + + ihs = (struct intr *)dev_id; + p_dev_ctl = (fc_dev_ctl_t * )ihs; + if(!p_dev_ctl){ + return IRQ_HANDLED; + } + + for(i=0;iinfo; + /* Ignore all interrupts during initialization. */ + if(binfo->fc_ffstate < FC_LINK_DOWN) { + LPFC_UNLOCK_DRIVER; + return IRQ_HANDLED; + } + + ioa = FC_MAP_IO(&binfo->fc_iomap_io); /* map in io registers */ + + /* Read host attention register to determine interrupt source */ + ha_copy = READ_CSR_REG(binfo, FC_HA_REG(binfo, ioa)); + + /* Clear Attention Sources, except ERROR (to preserve status) & LATT + * (ha_copy & ~HA_ERATT & ~HA_LATT); + */ + WRITE_CSR_REG(binfo, FC_HA_REG(binfo,ioa), (ha_copy & ~(HA_LATT | HA_ERATT))); + + if (ha_copy & HA_ERATT) { /* Link / board error */ + volatile uint32 status; + + /* do what needs to be done, get error from STATUS REGISTER */ + status = READ_CSR_REG(binfo, FC_STAT_REG(binfo, ioa)); + /* Clear Chip error bit */ + WRITE_CSR_REG(binfo, FC_HA_REG(binfo, ioa), HA_ERATT); + if(p_dev_ctl->dpc_hstatus == 0) + p_dev_ctl->dpc_hstatus = status; + } + + if (ha_copy & HA_LATT) { /* Link Attention interrupt */ + volatile uint32 control; + + if (binfo->fc_process_LA) { + control = READ_CSR_REG(binfo, FC_HC_REG(binfo, ioa)); + control &= ~HC_LAINT_ENA; + WRITE_CSR_REG(binfo, FC_HC_REG(binfo, ioa), control); + /* Clear Link Attention in HA REG */ + WRITE_CSR_REG(binfo, FC_HA_REG(binfo,ioa), (volatile uint32)(HA_LATT)); + } + } + + FC_UNMAP_MEMIO(ioa); + + + p_dev_ctl->dpc_ha_copy |= ha_copy; + + { + struct lpfc_dpc *ldp; + ldp = &lpfc_dpc[binfo->fc_brd_no]; + if ((p_dev_ctl->power_up == 0) || (ldp->dpc_wait == NULL)) { + do_fc_intr((struct intr *)p_dev_ctl); + LPFC_UNLOCK_DRIVER; + fc_flush_done_cmds(p_dev_ctl, siflg); + } + else { + if (ldp->dpc_active == 0) { + LPFC_UNLOCK_DRIVER; + up(ldp->dpc_wait); + } + else { + LPFC_UNLOCK_DRIVER; + fc_flush_done_cmds(p_dev_ctl, siflg); + } + } + } + return IRQ_HANDLED; +} + +/****************************************************************************** +* Function name : do_fc_intr +* +* Description : +* p_ihs also points to device control area +******************************************************************************/ +int do_fc_intr(struct intr *p_ihs) +{ + fc_dev_ctl_t * p_dev_ctl = (fc_dev_ctl_t * )p_ihs; + volatile uint32 ha_copy; + FC_BRD_INFO * binfo; + iCfgParam * clp; + fcipbuf_t * mbp; + MAILBOXQ * mb; + IOCBQ * delayiocb; + IOCBQ * temp; + IOCBQ * processiocb; + IOCBQ * endiocb; + int ipri, rc; + + binfo = &BINFO; + ipri = disable_lock(FC_LVL, &CMD_LOCK); + binfo->fc_flag |= FC_INTR_THREAD; + + /* Read host attention register to determine interrupt source */ + ha_copy = p_dev_ctl->dpc_ha_copy; + p_dev_ctl->dpc_ha_copy = 0; + + if (ha_copy) { + rc = INTR_SUCC; + binfo->fc_flag |= FC_INTR_WORK; + } else { + clp = DD_CTL.p_config[binfo->fc_brd_no]; + if (clp[CFG_INTR_ACK].a_current && (binfo->fc_flag&FC_INTR_WORK)) { + rc = INTR_SUCC; /* Just claim the first non-working interrupt */ + binfo->fc_flag &= ~FC_INTR_WORK; + } else { + if (clp[CFG_INTR_ACK].a_current == 2) + rc = INTR_SUCC; /* Always claim the interrupt */ + else + rc = INTR_FAIL; + } + } + + if (binfo->fc_flag & FC_OFFLINE_MODE) { + binfo->fc_flag &= ~FC_INTR_THREAD; + unlock_enable(ipri, &CMD_LOCK); + return(INTR_FAIL); + } + processiocb = 0; + if(binfo->fc_delayxmit) { + delayiocb = binfo->fc_delayxmit; + binfo->fc_delayxmit = 0; + endiocb = 0; + while(delayiocb) { + temp = delayiocb; + delayiocb = (IOCBQ *)temp->q; + temp->rsvd2--; + /* If retry == 0, process IOCB */ + if(temp->rsvd2 == 0) { + if(processiocb == 0) { + processiocb = temp; + } + else { + endiocb->q = (uchar *)temp; + } + endiocb = temp; + temp->q = 0; + } + else { + /* Make delayxmit point to first non-zero retry */ + if(binfo->fc_delayxmit == 0) + binfo->fc_delayxmit = temp; + } + } + if(processiocb) { + /* Handle any delayed IOCBs */ + endiocb = processiocb; + while(endiocb) { + temp = endiocb; + endiocb = (IOCBQ *)temp->q; + temp->q = 0; + issue_iocb_cmd(binfo, &binfo->fc_ring[FC_ELS_RING], temp); + } + } + } + + if (ha_copy & HA_ERATT) { /* Link / board error */ + unlock_enable(ipri, &CMD_LOCK); + handle_ff_error(p_dev_ctl); + return(rc); + } else { + if (ha_copy & HA_MBATT) { /* Mailbox interrupt */ + handle_mb_event(p_dev_ctl); + if(binfo->fc_flag & FC_PENDING_RING0) { + binfo->fc_flag &= ~FC_PENDING_RING0; + ha_copy |= HA_R0ATT; /* event on ring 0 */ + } + } + + if (ha_copy & HA_LATT) { /* Link Attention interrupt */ + if (binfo->fc_process_LA) { + handle_link_event(p_dev_ctl); + } + } + + if (ha_copy & HA_R0ATT) { /* event on ring 0 */ + if(binfo->fc_mbox_active == 0) + handle_ring_event(p_dev_ctl, 0, (ha_copy & 0x0000000F)); + else + binfo->fc_flag |= FC_PENDING_RING0; + } + + if (ha_copy & HA_R1ATT) { /* event on ring 1 */ + /* This ring handles IP. Defer processing anything on this ring + * till all FCP ELS traffic settles down. + */ + if (binfo->fc_ffstate <= FC_NODE_DISC) + binfo->fc_deferip |= (uchar)((ha_copy >> 4) & 0x0000000F); + else + handle_ring_event(p_dev_ctl, 1, ((ha_copy >> 4) & 0x0000000F)); + } + + if (ha_copy & HA_R2ATT) { /* event on ring 2 */ + handle_ring_event(p_dev_ctl, 2, ((ha_copy >> 8) & 0x0000000F)); + } + + if (ha_copy & HA_R3ATT) { /* event on ring 3 */ + handle_ring_event(p_dev_ctl, 3, ((ha_copy >> 12) & 0x0000000F)); + } + } + + if((processiocb == 0) && (binfo->fc_delayxmit) && + (binfo->fc_mbox_active == 0)) { + if ((mb = (MAILBOXQ * )fc_mem_get(binfo, MEM_MBOX))) { + fc_read_rpi(binfo, (uint32)1, (MAILBOX * )mb, (uint32)0); + if (issue_mb_cmd(binfo, (MAILBOX * )mb, MBX_NOWAIT) != MBX_BUSY) { + fc_mem_put(binfo, MEM_MBOX, (uchar * )mb); + } + } + } + + binfo->fc_flag &= ~FC_INTR_THREAD; + + while (p_dev_ctl->mbufl_head != 0) { + binfo->fc_flag |= FC_INTR_WORK; + mbp = (fcipbuf_t * )p_dev_ctl->mbufl_head; + p_dev_ctl->mbufl_head = (uchar * )fcnextpkt(mbp); + fcnextpkt(mbp) = 0; + fc_xmit(p_dev_ctl, mbp); + } + p_dev_ctl->mbufl_tail = 0; + unlock_enable(ipri, &CMD_LOCK); + return(rc); +} /* End do_fc_intr */ + +/****************************************************************************** +* Function name : fc_memmap +* +* Description : Called from fc_attach to map shared memory (SLIM and CSRs) +* for adapter and to setup memory for SLI2 interface. +******************************************************************************/ +int fc_memmap(fc_dev_ctl_t *p_dev_ctl) +{ + FC_BRD_INFO *binfo; + struct pci_dev *pdev; + int reg; + ulong base; + + binfo = &BINFO; + + /* + * Get PCI for board + */ + pdev = p_dev_ctl->pcidev; + if(!pdev){ + panic("no dev in pcimap\n"); + return(1); + } +#if LINUX_VERSION_CODE >= LinuxVersionCode(2,4,3) + /* Configure DMA attributes. */ +#if BITS_PER_LONG > 32 + if (pci_set_dma_mask(pdev, (uint64_t) 0xffffffffffffffff)) { + printk("Cannot set dma mask\n"); + return(1); + } +#else + if (pci_set_dma_mask(pdev, (uint64_t) 0xffffffff)) { + printk("Cannot set dma mask\n"); + return(1); + } +#endif +#else +#if BITS_PER_LONG > 32 + pdev->dma_mask = 0xffffffffffffffff; +#endif +#endif + + /* + * address in first register + */ + reg = 0; + reg = pci_getadd(pdev, reg, &base); + + /* + * need to mask the value to get the physical address + */ + base &= PCI_BASE_ADDRESS_MEM_MASK; + DDS.bus_mem_addr = base; + + /* + * next two registers are the control, get the first one, if doing direct io + * if i/o port is to be used get the second + * Note that pci_getadd returns the correct next register + */ + reg = pci_getadd(pdev, reg, &base); + base &= PCI_BASE_ADDRESS_MEM_MASK; + DDS.bus_io_addr = base; + /* + * Map adapter SLIM and Control Registers + */ + binfo->fc_iomap_mem = remap_pci_mem((ulong)DDS.bus_mem_addr,FF_SLIM_SIZE); + if(binfo->fc_iomap_mem == ((void *)(-1))){ + return (ENOMEM); + } + + binfo->fc_iomap_io =remap_pci_mem((ulong)DDS.bus_io_addr,FF_REG_AREA_SIZE); + if(binfo->fc_iomap_io == ((void *)(-1))){ + unmap_pci_mem((ulong)binfo->fc_iomap_mem); + return (ENOMEM); + } + + + /* + * Setup SLI2 interface + */ + if ((binfo->fc_sli == 2) && (binfo->fc_slim2.virt == 0)) { + MBUF_INFO * buf_info; + MBUF_INFO bufinfo; + + buf_info = &bufinfo; + + /* + * Allocate memory for SLI-2 structures + */ + buf_info->size = sizeof(SLI2_SLIM); + buf_info->flags = FC_MBUF_DMA; + buf_info->align = fcPAGESIZE; + buf_info->dma_handle = 0; + buf_info->data_handle = 0; + fc_malloc(p_dev_ctl, buf_info); + if (buf_info->virt == NULL) { + + /* + * unmap adapter SLIM and Control Registers + */ + unmap_pci_mem((ulong)binfo->fc_iomap_mem); + unmap_pci_mem((ulong)binfo->fc_iomap_io); + + return (ENOMEM); + } + + binfo->fc_slim2.virt = (uchar * )buf_info->virt; + binfo->fc_slim2.phys = (uchar * )buf_info->phys; + binfo->fc_slim2.data_handle = buf_info->data_handle; + binfo->fc_slim2.dma_handle = buf_info->dma_handle; + fc_bzero((char *)binfo->fc_slim2.virt, sizeof(SLI2_SLIM)); + } + return(0); +} + +/****************************************************************************** +* Function name : fc_unmemmap +* +* Description : Called from fc_detach to unmap shared memory (SLIM and CSRs) +* for adapter +* +******************************************************************************/ +int fc_unmemmap(fc_dev_ctl_t *p_dev_ctl) +{ + FC_BRD_INFO *binfo; + + binfo = &BINFO; + + /* + * unmap adapter SLIM and Control Registers + */ + unmap_pci_mem((ulong)binfo->fc_iomap_mem); + unmap_pci_mem((ulong)binfo->fc_iomap_io); + /* + * Free resources associated with SLI2 interface + */ + if (binfo->fc_slim2.virt) { + MBUF_INFO * buf_info; + MBUF_INFO bufinfo; + + buf_info = &bufinfo; + buf_info->phys = (uint32 * )binfo->fc_slim2.phys; + buf_info->data_handle = binfo->fc_slim2.data_handle; + buf_info->dma_handle = binfo->fc_slim2.dma_handle; + buf_info->flags = FC_MBUF_DMA; + + buf_info->virt = (uint32 * )binfo->fc_slim2.virt; + buf_info->size = sizeof(SLI2_SLIM); + fc_free(p_dev_ctl, buf_info); + binfo->fc_slim2.virt = 0; + binfo->fc_slim2.phys = 0; + binfo->fc_slim2.dma_handle = 0; + binfo->fc_slim2.data_handle = 0; + } + return(0); +} + +/****************************************************************************** +* Function name : fc_pcimap +* +* Description : Called from fc_attach to setup PCI configuration registers +* +******************************************************************************/ +int fc_pcimap(fc_dev_ctl_t *p_dev_ctl) +{ + FC_BRD_INFO *binfo; + iCfgParam *clp; + struct pci_dev *pdev; + u16 cmd; + + binfo = &BINFO; + clp = DD_CTL.p_config[binfo->fc_brd_no]; + + /* + * PCI for board + */ + pdev = p_dev_ctl->pcidev; + if(!pdev) + return(1); + + /* + * bus mastering and parity checking enabled + */ + pci_read_config_word(pdev, PCI_COMMAND, &cmd); + if(cmd & CMD_PARITY_CHK) + cmd = CMD_CFG_VALUE ; + else + cmd = (CMD_CFG_VALUE & ~(CMD_PARITY_CHK)); + + + pci_write_config_word(pdev, PCI_COMMAND, cmd); + + if(lpfc_pci_latency_clocks) + pci_write_config_byte(pdev, PCI_LATENCY_TMR_REGISTER,(uchar)lpfc_pci_latency_clocks); + + if(lpfc_pci_cache_line) + pci_write_config_byte(pdev, PCI_CACHE_LINE_REGISTER,(uchar)lpfc_pci_cache_line); + + /* + * Get the irq from the pdev structure + */ + DDS.bus_intr_lvl = (int)pdev->irq; + + return(0); +} + +/****************************************************************************** +* Function name : lpfc_cfg_init +* +* Description : Called from handle_ff_error() to bring link back up +* +******************************************************************************/ +int lpfc_cfg_init(fc_dev_ctl_t *p_dev_ctl) +{ + FC_BRD_INFO * binfo; + struct lpfc_dpc *ldp; + + binfo = &BINFO; + p_dev_ctl->dev_flag |= FC_SCHED_CFG_INIT; + ldp = &lpfc_dpc[binfo->fc_brd_no]; + if ((ldp->dpc_active == 0) && ldp->dpc_wait) + up(ldp->dpc_wait); + return(0); +} + +/****************************************************************************** +* Function name : lpfc_kfree_skb +* +* Description : This routine is only called by the IP portion of the driver +* and the Fabric NameServer portion of the driver. It should +* free a fcipbuf chain. +******************************************************************************/ +int lpfc_kfree_skb(struct sk_buff *skb) +{ + struct sk_buff *sskb; + + while(skb->next) { + sskb = skb; + skb = skb->next; + sskb->next = 0; +#if LINUX_VERSION_CODE >= LinuxVersionCode(2,4,0) + if(in_interrupt()) { + dev_kfree_skb_irq(sskb); + } + else { + dev_kfree_skb(sskb); + } +#else + dev_kfree_skb(sskb); +#endif + } +#if LINUX_VERSION_CODE >= LinuxVersionCode(2,4,0) + if(in_interrupt()) { + dev_kfree_skb_irq(skb); + } + else { + dev_kfree_skb(skb); + } +#else + dev_kfree_skb(skb); +#endif + return(0); +} + +/****************************************************************************** +* Function name : lpfc_alloc_skb +* +* Description : +* +******************************************************************************/ +struct sk_buff *lpfc_alloc_skb(unsigned int size) +{ + return(alloc_skb(size, GFP_ATOMIC)); +} + +/****************************************************************************** +* Function name : fc_malloc +* +* Description : fc_malloc environment specific routine for memory +* allocation / mapping +* The buf_info->flags field describes the memory operation requested. +* +* FC_MBUF_PHYSONLY set requests a supplied virtual address be mapped for DMA +* Virtual address is supplied in buf_info->virt +* DMA mapping flag is in buf_info->align (DMA_READ, DMA_WRITE_ONLY, both) +* The mapped physical address is returned buf_info->phys +* +* FC_MBUF_PHYSONLY cleared requests memory be allocated for driver use and +* if FC_MBUF_DMA is set the memory is also mapped for DMA +* The byte alignment of the memory request is supplied in buf_info->align +* The byte size of the memory request is supplied in buf_info->size +* The virtual address is returned buf_info->virt +* The mapped physical address is returned buf_info->phys (for FC_MBUF_DMA) +* +******************************************************************************/ +uchar *fc_malloc(fc_dev_ctl_t *p_dev_ctl, + MBUF_INFO *buf_info) +{ + FC_BRD_INFO * binfo; + unsigned int size; + + binfo = &BINFO; + buf_info->phys = (void *)((ulong)INVALID_PHYS); + buf_info->dma_handle = 0; + if (buf_info->flags & FC_MBUF_PHYSONLY) { + if(buf_info->virt == NULL) + return NULL; +#if LINUX_VERSION_CODE <= LinuxVersionCode(2,4,12) + buf_info->phys = (void *)((ulong)pci_map_single(p_dev_ctl->pcidev, + buf_info->virt, buf_info->size, PCI_DMA_BIDIRECTIONAL)); +#else + { + struct page *page = virt_to_page((ulong)(buf_info->virt)); + unsigned long offset = ((unsigned long)buf_info->virt & ~PAGE_MASK); + + buf_info->phys = (void *)((ulong)pci_map_page(p_dev_ctl->pcidev, + page, offset, buf_info->size, PCI_DMA_BIDIRECTIONAL)); + } +#endif + +#if LINUX_VERSION_CODE >= LinuxVersionCode(2,4,0) + buf_info->dma_handle = buf_info->phys; +#endif + FCSTATCTR.fcMapCnt++; + return((uchar * )buf_info->virt); + } + if((buf_info->flags & FC_MBUF_DMA)) { + size = fc_po2(buf_info->size); + buf_info->phys = (void *)((ulong)INVALID_PHYS); + buf_info->virt = lpfc_kmalloc(size, GFP_ATOMIC, &buf_info->phys, p_dev_ctl); + if (buf_info->virt) { + if(is_invalid_phys(buf_info->phys)) { + lpfc_kfree((unsigned int)buf_info->size, (void *)buf_info->virt, (void *)buf_info->phys, p_dev_ctl); + buf_info->virt = 0; + } + } +#if LINUX_VERSION_CODE >= LinuxVersionCode(2,4,0) + buf_info->dma_handle = buf_info->phys; +#endif + if(buf_info->virt == 0) { + buf_info->phys = (void *)((ulong)INVALID_PHYS); + buf_info->dma_handle = 0; + } + } + else { + buf_info->size = ((buf_info->size + 7) & 0xfffffff8); + buf_info->virt = (uint32 * )lpfc_kmalloc((unsigned int)buf_info->size, GFP_ATOMIC, 0, 0); + if(buf_info->virt) + fc_bzero(buf_info->virt, buf_info->size); + buf_info->phys = (void *)((ulong)INVALID_PHYS); + } + FCSTATCTR.fcMallocCnt++; + FCSTATCTR.fcMallocByte += buf_info->size; + return((uchar * )buf_info->virt); +} + +/****************************************************************************** +* Function name : fc_po2 +* +* Description : Convert size to next highest power of 2 +* +******************************************************************************/ +ulong fc_po2(ulong size) +{ + ulong order; + + for (order = 1; order < size; order <<= 1); + return(order); +} + +void *lpfc_last_dma_page = 0; +int lpfc_dma_page_offset = 0; + +/****************************************************************************** +* Function name : fc_free +* +* Description : Environment specific routine for memory de-allocation/unmapping +* The buf_info->flags field describes the memory operation requested. +* FC_MBUF_PHYSONLY set requests a supplied virtual address be unmapped +* for DMA, but not freed. +* The mapped physical address to be unmapped is in buf_info->phys +* FC_MBUF_PHYSONLY cleared requests memory be freed and unmapped for DMA +* only if FC_MBUF_DMA is set. +* The mapped physical address to be unmapped is in buf_info->phys +* The virtual address to be freed is in buf_info->virt +******************************************************************************/ +void fc_free(fc_dev_ctl_t *p_dev_ctl, + MBUF_INFO *buf_info) +{ + FC_BRD_INFO * binfo; + unsigned int size; + + binfo = &BINFO; + + if (buf_info->flags & FC_MBUF_PHYSONLY) { +#if LINUX_VERSION_CODE <= LinuxVersionCode(2,4,12) + pci_unmap_single(p_dev_ctl->pcidev, + (ulong)(buf_info->phys), buf_info->size, PCI_DMA_BIDIRECTIONAL); +#else + pci_unmap_page(p_dev_ctl->pcidev, + (ulong)(buf_info->phys), buf_info->size, PCI_DMA_BIDIRECTIONAL); +#endif + FCSTATCTR.fcUnMapCnt++; + } + else { + if((buf_info->flags & FC_MBUF_DMA)) { + size = fc_po2(buf_info->size); + lpfc_kfree((unsigned int)buf_info->size, (void *)buf_info->virt, (void *)buf_info->phys, p_dev_ctl); + } + else { + buf_info->size = ((buf_info->size + 7) & 0xfffffff8); + lpfc_kfree((unsigned int)buf_info->size, (void *)buf_info->virt, (void *)((ulong)INVALID_PHYS), 0); + } + FCSTATCTR.fcFreeCnt++; + FCSTATCTR.fcFreeByte += buf_info->size; + } +} + +/****************************************************************************** +* Function name : fc_rdpci_cmd +* +******************************************************************************/ +ushort fc_rdpci_cmd(fc_dev_ctl_t *p_dev_ctl) +{ + u16 cmd; + struct pci_dev *pdev; + + /* + * PCI device + */ + pdev = p_dev_ctl->pcidev; + if(!pdev){ + panic("no dev in fc_rdpci_cmd\n"); + return((ushort)0); + } + pci_read_config_word(pdev, PCI_COMMAND, &cmd); + return((ushort)cmd); +} + +/****************************************************************************** +* Function name : fc_rdpci_32 +* +******************************************************************************/ +uint32 fc_rdpci_32(fc_dev_ctl_t *p_dev_ctl, + uint32 offset) +{ + uint32 cmd; + struct pci_dev *pdev; + + /* + * PCI device + */ + pdev = p_dev_ctl->pcidev; + if(!pdev){ + panic("no dev in fc_rdpci_32\n"); + return((ushort)0); + } + pci_read_config_dword(pdev, offset, &cmd); + return(cmd); +} + +/****************************************************************************** +* Function name : fc_wrpci_cmd +* +******************************************************************************/ +void fc_wrpci_cmd(fc_dev_ctl_t *p_dev_ctl, + ushort cfg_value) +{ + struct pci_dev *pdev; + + /* + * PCI device + */ + pdev = p_dev_ctl->pcidev; + if(!pdev){ + panic("no dev in fc_wrpci_cmd\n"); + return; + } + pci_write_config_word(pdev, PCI_COMMAND, cfg_value); +} +/****************************************************************************** +* +* Function name : lpfc_fcp_error() +* +* Description : Handle an FCP response error +* +* Context : called from handle_fcp_event +* Can be called by interrupt thread. +******************************************************************************/ +_static_ void lpfc_fcp_error(fc_buf_t * fcptr, + IOCB * cmd) +{ + FCP_RSP *fcpRsp = &fcptr->fcp_rsp; + struct sc_buf *sp = fcptr->sc_bufp; + struct buf *bp; + struct scsi_cmnd *Cmnd; + + bp = (struct buf *)sp; + Cmnd = bp->cmnd; + + if (fcpRsp->rspStatus2 & RESID_UNDER) { + uint32 len, resid, brd; + + if((fcptr->dev_ptr) && (fcptr->dev_ptr->nodep)) + brd = fcptr->dev_ptr->nodep->ap->info.fc_brd_no; + else + brd = 0; + + len = SWAP_DATA(fcptr->fcp_cmd.fcpDl); + resid = SWAP_DATA(fcpRsp->rspResId); + + /* FCP residual underrun, expected , residual */ + fc_log_printf_msg_vargs( brd, + &fc_msgBlk0716, /* ptr to msg structure */ + fc_mes0716, /* ptr to msg */ + fc_msgBlk0716.msgPreambleStr, /* begin varargs */ + len, + resid, + Cmnd->cmnd[0], + Cmnd->underflow); /* end varargs */ + + switch (Cmnd->cmnd[0]) { + case TEST_UNIT_READY: + case REQUEST_SENSE: + case INQUIRY: + case RECEIVE_DIAGNOSTIC: + case READ_CAPACITY: + case FCP_SCSI_READ_DEFECT_LIST: + case MDACIOCTL_DIRECT_CMD: + break; + default: + if((!(fcpRsp->rspStatus2 & SNS_LEN_VALID)) && + (len - resid < Cmnd->underflow)) { + /* FCP command residual underrun converted to error */ + fc_log_printf_msg_vargs( brd, + &fc_msgBlk0717, /* ptr to msg structure */ + fc_mes0717, /* ptr to msg */ + fc_msgBlk0717.msgPreambleStr, /* begin varargs */ + Cmnd->cmnd[0], + Cmnd->underflow, + len, + resid); /* end varargs */ + fcpRsp->rspStatus3 = SC_COMMAND_TERMINATED; + fcpRsp->rspStatus2 &= ~RESID_UNDER; + sp->scsi_status = 0; + } + break; + } + } +} +/****************************************************************************** +* Function name : fc_do_iodone +* +* Description : Return a SCSI initiated I/O to above layer +* when the I/O completes. +******************************************************************************/ +int fc_do_iodone(struct buf *bp) +{ + struct scsi_cmnd *Cmnd; + struct sc_buf * sp = (struct sc_buf *) bp; + FC_BRD_INFO * binfo; + iCfgParam * clp; + fc_dev_ctl_t * p_dev_ctl; + NODELIST * nlp; + node_t * node_ptr; + struct Scsi_Host *host; + struct dev_info * dev_ptr; + int dev_index; + int host_status = DID_OK; + + IOcnt--; + + if(!bp) { + return(1); + } + /* + * Linux command from our buffer + */ + Cmnd = bp->cmnd; + + /* + * must have Cmnd and Linux completion functions + */ + if(!Cmnd || !Cmnd->scsi_done){ + return (0); + } + + /* + * retrieve host adapter and device control + */ + host = Cmnd->device->host; + if(!host){ + return (0); + } + p_dev_ctl = (fc_dev_ctl_t *)host->hostdata[0]; + if(!p_dev_ctl){ + return (0); + } + + fc_fcp_bufunmap(p_dev_ctl, sp); + + dev_index = INDEX(ZERO_PAN, Cmnd->device->id); + binfo = &BINFO; + clp = DD_CTL.p_config[binfo->fc_brd_no]; + dev_ptr = sp->current_devp; + + if (!dev_ptr) { + node_ptr = binfo->device_queue_hash[dev_index].node_ptr; + goto qf; + } + + if((node_ptr = dev_ptr->nodep) == 0) { + node_ptr = binfo->device_queue_hash[dev_index].node_ptr; + if(!node_ptr) { + dev_ptr = 0; + goto qf; + } + } + + if(node_ptr->rpi == 0xfffe) { +qf: + if ((binfo->fc_ffstate > FC_LINK_DOWN) && (binfo->fc_ffstate < FC_READY)) + goto force_retry; + + if(node_ptr) + nlp = node_ptr->nlp; + else + nlp = 0; + if (nlp && + (binfo->fc_flag & FC_RSCN_MODE) && (binfo->fc_ffstate == FC_READY) && + (nlp->nlp_action & (NLP_DO_ADDR_AUTH | NLP_DO_DISC_START | NLP_DO_RSCN))) + goto force_retry; + + if ((node_ptr) && (clp[CFG_NODEV_TMO].a_current)) { + if(node_ptr->flags & FC_NODEV_TMO) { +#ifdef FC_NEW_EH + Cmnd->retries = Cmnd->allowed; /* no more retries */ +#endif + host_status = DID_NO_CONNECT; +#if LINUX_VERSION_CODE >= LinuxVersionCode(2,4,0) + if(lpfc_use_removable) { + Cmnd->sense_buffer[0] = 0x70; + Cmnd->sense_buffer[2] = UNIT_ATTENTION; + Cmnd->device->removable = 1; + } +#endif + if(dev_ptr) + dev_ptr->scsi_dev = (void *)Cmnd->device; + } + else { +#ifdef FC_NEW_EH + Cmnd->retries = 0; /* Force retry */ +#endif + host_status = DID_BUS_BUSY; + } + Cmnd->result = ScsiResult(host_status, 0); + } + else { + if((clp[CFG_LINKDOWN_TMO].a_current)&&(binfo->fc_flag & FC_LD_TIMEOUT)) { +#ifdef FC_NEW_EH + Cmnd->retries = Cmnd->allowed; /* no more retries */ +#endif + host_status = DID_NO_CONNECT; +#if LINUX_VERSION_CODE >= LinuxVersionCode(2,4,0) + if(lpfc_use_removable) { + Cmnd->sense_buffer[0] = 0x70; + Cmnd->sense_buffer[2] = UNIT_ATTENTION; + Cmnd->device->removable = 1; + } +#endif + if(dev_ptr) + dev_ptr->scsi_dev = (void *)Cmnd->device; + } + else { +force_retry: +#ifdef FC_NEW_EH + Cmnd->retries = 0; /* Force retry */ +#endif + host_status = DID_BUS_BUSY; + } + Cmnd->result = ScsiResult(host_status, 0); + } + fc_queue_done_cmd(p_dev_ctl, bp); + return (0); + } + + /* + * mark it as done, no longer required, but will leave for now + */ + bp->isdone=1; +#if LINUX_VERSION_CODE >= LinuxVersionCode(2,4,0) + Cmnd->resid = bp->b_resid; +#endif + + /* + * First check if a scsi error, mid-level handles these only if DID_OK + */ + if(sp->status_validity == SC_SCSI_ERROR){ + if(sp->scsi_status==SC_CHECK_CONDITION){ + lpfc_copy_sense(dev_ptr, bp); + } + else if (sp->scsi_status == SC_RESERVATION_CONFLICT) { + host_status = DID_ERROR; + } + else if (sp->scsi_status == SC_BUSY_STATUS) { +#ifdef FC_NEW_EH + Cmnd->retries = 0; /* Force retry */ +#endif + host_status = DID_BUS_BUSY; + } + else { + host_status = DID_ERROR; + } + + if((bp->b_flags & B_ERROR)) { + if (bp->b_error == EBUSY){ + host_status = DID_OK; + sp->scsi_status = SC_QUEUE_FULL; + } else if (bp->b_error == EINVAL){ +#ifdef FC_NEW_EH + Cmnd->retries = 0; /* Force retry */ +#endif + host_status = DID_BUS_BUSY; + sp->scsi_status = 0; + } + } + + Cmnd->result = ScsiResult(host_status,sp->scsi_status); + fc_queue_done_cmd(p_dev_ctl, bp); + return (0); + } + + /* + * check error flag + */ + if((bp->b_flags & B_ERROR)) + { + switch(bp->b_error){ + case 0: + host_status = DID_OK; + sp->scsi_status = 0; + break; + case EBUSY: + host_status = DID_BUS_BUSY; + sp->scsi_status = 0; + break; + case EINVAL: +#ifdef FC_NEW_EH + Cmnd->retries = 0; /* Force retry */ +#endif + host_status = DID_BUS_BUSY; + sp->scsi_status = 0; + break; + default: +#ifdef FC_NEW_EH + host_status = DID_ERROR; +#else + host_status = DID_BUS_BUSY; +#endif + break; + } + } + + /* + * next hardware errors + */ + if(sp->status_validity == SC_ADAPTER_ERROR){ +#ifdef FC_NEW_EH + host_status = DID_ERROR; +#else + host_status = DID_BUS_BUSY; +#endif + Cmnd->result = ScsiResult(host_status,0); + fc_queue_done_cmd(p_dev_ctl, bp); + return (0); + } + + /* + * if lun0_missing feature is turned on and it's inquiry to a missing + * lun 0, then we will fake out LINUX scsi layer to allow scanning + * of other luns. + */ + if (lpfc_lun0_missing) { + if ((Cmnd->cmnd[0] == FCP_SCSI_INQUIRY) && (Cmnd->device->lun == 0)) { + uchar *buf; + buf = (uchar *)Cmnd->request_buffer; + if( *buf == 0x7f) { + /* Make lun unassigned and wrong type */ + *buf = 0x3; + } + } + } + + if(lpfc_lun_skip) { + /* If a LINUX OS patch to support, LUN skipping / no LUN 0, is not present, + * this code will fake out the LINUX scsi layer to allow it to detect + * all LUNs if there are LUN holes on a device. + */ + if (Cmnd->cmnd[0] == FCP_SCSI_INQUIRY) { + uchar *buf; + buf = (uchar *)Cmnd->request_buffer; + if(( *buf == 0x7f) || ((*buf & 0xE0) == 0x20)) { + /* Make lun unassigned and wrong type */ + *buf = 0x3; + } + } + } + + Cmnd->result = ScsiResult(host_status,sp->scsi_status); + fc_queue_done_cmd(p_dev_ctl, bp); + + return(0); +} + +/****************************************************************************** +* Function name : fc_fcp_bufunmap +* +* Description : +* +******************************************************************************/ +int fc_fcp_bufunmap(fc_dev_ctl_t * p_dev_ctl, + struct sc_buf * sp) +{ + struct buf *bp; + struct scsi_cmnd * Cmnd; + FC_BRD_INFO * binfo; + + binfo = &BINFO; + bp = (struct buf *)sp; + Cmnd = bp->cmnd; + /* unmap DMA resources used */ + if(!(sp->flags & SC_MAPPED)) + return(0); +#if LINUX_VERSION_CODE >= LinuxVersionCode(2,4,0) + { + int rwflg; + + rwflg = Cmnd->sc_data_direction; + + if (Cmnd->use_sg) { + pci_unmap_sg(p_dev_ctl->pcidev, Cmnd->request_buffer, Cmnd->use_sg, rwflg); + } + else if ((Cmnd->request_bufflen) && (bp->av_back)) { +#if LINUX_VERSION_CODE <= LinuxVersionCode(2,4,12) + pci_unmap_single(p_dev_ctl->pcidev, (uint64_t)((ulong)(bp->av_back)), Cmnd->request_bufflen, rwflg); +#else + pci_unmap_page(p_dev_ctl->pcidev, (uint64_t)((ulong)(bp->av_back)), Cmnd->request_bufflen, rwflg); +#endif + } + } + +#endif + FCSTATCTR.fcUnMapCnt++; + sp->flags &= ~SC_MAPPED; + return(0); +} + +/****************************************************************************** +* Function name : fc_fcp_bufmap +* +* Description : Called from issue_fcp_cmd, used to map addresses in sbp to +* physical addresses for the I/O. +******************************************************************************/ +int fc_fcp_bufmap(fc_dev_ctl_t * p_dev_ctl, + struct sc_buf * sbp, + fc_buf_t * fcptr, + IOCBQ * temp, + ULP_BDE64 * bpl, + dvi_t * dev_ptr, + int pend) +{ + uint32 seg_cnt, cnt, num_bmps, i, num_bde; + int rwflg; + FC_BRD_INFO * binfo = &BINFO; + iCfgParam * clp; + struct buf * bp; + RING * rp; + IOCB * cmd; + struct scsi_cmnd * cmnd; + ULP_BDE64 * topbpl; + MATCHMAP * bmp; + MATCHMAP * last_bmp; + void * physaddr; + struct scatterlist *sgel_p; +#ifdef powerpc + struct scatterlist *sgel_p_t0; +#endif /* endif powerpc */ + + bp = (struct buf *)sbp; + /* + Linux command */ + cmnd = bp->cmnd; + if(!cmnd) + return(FCP_EXIT); + rp = &binfo->fc_ring[FC_FCP_RING]; + clp = DD_CTL.p_config[binfo->fc_brd_no]; + cmd = &temp->iocb; + + last_bmp = fcptr->bmp; + num_bmps = 1; + num_bde = 0; + topbpl = 0; + sgel_p = 0; + + fcptr->flags |= DATA_MAPPED; + if (cmnd->use_sg) { + sbp->bufstruct.av_back = 0; + sgel_p = (struct scatterlist *)cmnd->request_buffer; +#if LINUX_VERSION_CODE < LinuxVersionCode(2,4,0) + seg_cnt = cmnd->use_sg; + rwflg = 0; +#else + rwflg = cmnd->sc_data_direction; + #ifdef powerpc /* remap to get a different set of fysadds that xclud zro */ + remapsgl: + #endif /* end if powerpc */ + seg_cnt = pci_map_sg(p_dev_ctl->pcidev, sgel_p, cmnd->use_sg, rwflg); + #ifdef powerpc /* check 4 zro phys address, then remap to get a diff 1 */ + for (sgel_p_t0=sgel_p, i=0; ibufstruct.b_bcount = cnt; + break; + } + /* Fill in continuation entry to next bpl */ + bpl->addrHigh = (uint32)putPaddrHigh(bmp->phys); + bpl->addrHigh = PCIMEM_LONG(bpl->addrHigh); + bpl->addrLow = (uint32)putPaddrLow(bmp->phys); + bpl->addrLow = PCIMEM_LONG(bpl->addrLow); + bpl->tus.f.bdeFlags = BPL64_SIZE_WORD; + num_bde++; + if (num_bmps == 1) { + cmd->un.fcpi64.bdl.bdeSize += (num_bde * sizeof(ULP_BDE64)); + } else { + topbpl->tus.f.bdeSize = (num_bde * sizeof(ULP_BDE64)); + topbpl->tus.w = PCIMEM_LONG(topbpl->tus.w); + } + topbpl = bpl; + bpl = (ULP_BDE64 * )bmp->virt; + last_bmp->fc_mptr = (void *)bmp; + last_bmp = bmp; + num_bde = 0; + num_bmps++; + } +#if LINUX_VERSION_CODE < LinuxVersionCode(2,4,0) + rwflg = 0; +#else + if(rwflg == B_WRITE) + rwflg = SCSI_DATA_WRITE; + else + rwflg = SCSI_DATA_READ; +#endif + + physaddr = (void *)((ulong)scsi_sg_dma_address(sgel_p)); + + bpl->addrLow = PCIMEM_LONG(putPaddrLow(physaddr)); + bpl->addrHigh = PCIMEM_LONG(putPaddrHigh(physaddr)); + bpl->tus.f.bdeSize = scsi_sg_dma_len(sgel_p); + cnt += bpl->tus.f.bdeSize; + if (cmd->ulpCommand == CMD_FCP_IREAD64_CR) + bpl->tus.f.bdeFlags = BUFF_USE_RCV; + else + bpl->tus.f.bdeFlags = 0; + bpl->tus.w = PCIMEM_LONG(bpl->tus.w); + bpl++; + sgel_p++; + num_bde++; + } /* end for loop */ + + } + else { + +#if LINUX_VERSION_CODE < LinuxVersionCode(2,4,0) + rwflg = 0; +#else + rwflg = cmnd->sc_data_direction; +#endif + +#if LINUX_VERSION_CODE <= LinuxVersionCode(2,4,12) + physaddr = (void *)((ulong)pci_map_single(p_dev_ctl->pcidev, + cmnd->request_buffer, cmnd->request_bufflen, rwflg)); +#else + { + struct page *page = virt_to_page((ulong)(cmnd->request_buffer)); + unsigned long offset = ((unsigned long)cmnd->request_buffer & ~PAGE_MASK); + + #ifdef powerpc + remapnsg: + #endif /* endif powerpc */ + physaddr = (void *)((ulong)pci_map_page(p_dev_ctl->pcidev, + page, offset, cmnd->request_bufflen, rwflg)); + #ifdef powerpc + if (!physaddr) { + goto remapnsg; + } + #endif /* endif remapnsg */ + } +#endif + FCSTATCTR.fcMapCnt++; + sbp->bufstruct.av_back = (void *)physaddr; + /* no scatter-gather list case */ + bpl->addrLow = PCIMEM_LONG(putPaddrLow(physaddr)); + bpl->addrHigh = PCIMEM_LONG(putPaddrHigh(physaddr)); + bpl->tus.f.bdeSize = sbp->bufstruct.b_bcount; + if (cmd->ulpCommand == CMD_FCP_IREAD64_CR) + bpl->tus.f.bdeFlags = BUFF_USE_RCV; + else + bpl->tus.f.bdeFlags = 0; + bpl->tus.w = PCIMEM_LONG(bpl->tus.w); + num_bde = 1; + bpl++; + + } + + bpl->addrHigh = 0; + bpl->addrLow = 0; + bpl->tus.w = 0; + last_bmp->fc_mptr = 0; + if (num_bmps == 1) { + cmd->un.fcpi64.bdl.bdeSize += (num_bde * sizeof(ULP_BDE64)); + } else { + topbpl->tus.f.bdeSize = (num_bde * sizeof(ULP_BDE64)); + topbpl->tus.w = PCIMEM_LONG(topbpl->tus.w); + } + cmd->ulpBdeCount = 1; + cmd->ulpLe = 1; /* Set the LE bit in the last iocb */ + + /* Queue cmd chain to last iocb entry in xmit queue */ + if (rp->fc_tx.q_first == NULL) { + rp->fc_tx.q_first = (uchar * )temp; + } else { + ((IOCBQ * )(rp->fc_tx.q_last))->q = (uchar * )temp; + } + rp->fc_tx.q_last = (uchar * )temp; + rp->fc_tx.q_cnt++; + + sbp->flags |= SC_MAPPED; + return(0); +} + +/****************************************************************************** +* Function name : local_timeout +* +* Description : Local handler for watchdog timeouts +******************************************************************************/ +void local_timeout(unsigned long data) +{ + struct watchdog *wdt = (struct watchdog *)data; + fc_dev_ctl_t * p_dev_ctl; + FC_BRD_INFO * binfo; + int skip_intr, i; + ulong siflg; + ulong iflg; + struct lpfc_dpc *ldp; + + siflg = 0; + skip_intr = 0; + iflg = 0; + LPFC_LOCK_DRIVER0; + for (i = 0; i < MAX_FC_BRDS; i++) { + if((p_dev_ctl = (fc_dev_ctl_t *)DD_CTL.p_dev[i])) { + if(p_dev_ctl->fc_ipri != 0) { + printk("LOCK 14 failure %x %x\n",(uint32)p_dev_ctl->fc_ipri, (uint32)iflg); + } + p_dev_ctl->fc_ipri = 14; + + /* Check to see if the DPC was scheduled since the last clock interrupt */ + if(p_dev_ctl->dpc_cnt == p_dev_ctl->save_dpc_cnt) { + volatile uint32 ha_copy; + void * ioa; + + binfo = &BINFO; + ioa = FC_MAP_IO(&binfo->fc_iomap_io); /* map in io registers */ + /* Read host attention register to determine interrupt source */ + ha_copy = READ_CSR_REG(binfo, FC_HA_REG(binfo, ioa)); + FC_UNMAP_MEMIO(ioa); + /* If there are any hardware interrupts to process, they better + * get done before the next clock interrupt. + */ + if(p_dev_ctl->dpc_ha_copy || (ha_copy & ~HA_LATT)) { + if(p_dev_ctl->dev_flag & FC_NEEDS_DPC) { + skip_intr = 1; + /* Local_timeout Skipping clock tick */ + fc_log_printf_msg_vargs( binfo->fc_brd_no, + &fc_msgBlk0756, /* ptr to msg structure */ + fc_mes0756, /* ptr to msg */ + fc_msgBlk0756.msgPreambleStr, /* begin varargs */ + p_dev_ctl->dpc_ha_copy, + ha_copy, + p_dev_ctl->dpc_cnt, + binfo->fc_ffstate); /* end varargs */ + if(wdt) + del_timer(&wdt->timer); + } + else { + p_dev_ctl->dev_flag |= FC_NEEDS_DPC; + } + } + } + p_dev_ctl->save_dpc_cnt = p_dev_ctl->dpc_cnt; + } + } + + if(skip_intr || !wdt || !wdt->timeout_id) { + fc_reset_timer(); + goto out; + } + del_timer(&wdt->timer); + + ldp = &lpfc_dpc[0]; + if (ldp->dpc_wait == NULL) { + if(wdt->func) + wdt->func(wdt); + } + else { + lpfc_timer(0); + } + +out: + for (i = 0; i < MAX_FC_BRDS; i++) { + if((p_dev_ctl = (fc_dev_ctl_t *)DD_CTL.p_dev[i])) { + p_dev_ctl->fc_ipri = 0; + } + } + LPFC_UNLOCK_DRIVER0; + + for (i = 0; i < MAX_FC_BRDS; i++) { + if((p_dev_ctl = (fc_dev_ctl_t *)DD_CTL.p_dev[i])) { + binfo = &BINFO; + ldp = &lpfc_dpc[binfo->fc_brd_no]; + if ((ldp->dpc_active == 0) && ldp->dpc_wait) + up(ldp->dpc_wait); + } + } +} + +/****************************************************************************** +* Function name : fc_reset_timer +* +* Description : +* +******************************************************************************/ +void fc_reset_timer(void) +{ + FCCLOCK_INFO * clock_info; + + clock_info = &DD_CTL.fc_clock_info; + ((struct watchdog *)(CLOCKWDT))->func = fc_timer; + ((struct watchdog *)(CLOCKWDT))->restart = 1; + ((struct watchdog *)(CLOCKWDT))->count = 0; + ((struct watchdog *)(CLOCKWDT))->stopping = 0; + /* + * add our watchdog timer routine to kernel's list + */ + ((struct watchdog *)(CLOCKWDT))->timer.expires = HZ + jiffies; + ((struct watchdog *)(CLOCKWDT))->timer.function = local_timeout; + ((struct watchdog *)(CLOCKWDT))->timer.data = (unsigned long)(CLOCKWDT); + init_timer(&((struct watchdog *)(CLOCKWDT))->timer); + add_timer(&((struct watchdog *)(CLOCKWDT))->timer); + return; +} + +/****************************************************************************** +* Function name : curtime +* +* Description : Set memory pointed to by time, with the current time (LBOLT) +* +******************************************************************************/ +void curtime(uint32 *time) +{ + *time = jiffies; +} + +/****************************************************************************** +* Function name : fc_initpci +* +* Description : Called by driver diagnostic interface to initialize dfc_info +* +******************************************************************************/ +int fc_initpci(struct dfc_info *di, + fc_dev_ctl_t *p_dev_ctl) +{ + FC_BRD_INFO * binfo; /* point to the binfo area */ + struct pci_dev *pdev; + + pdev = p_dev_ctl->pcidev; + /* + must have the pci struct + */ + if(!pdev) + return(1); + binfo = &BINFO; + + di->fc_ba.a_onmask = (ONDI_MBOX | ONDI_RMEM | ONDI_RPCI | ONDI_RCTLREG | + ONDI_IOINFO | ONDI_LNKINFO | ONDI_NODEINFO | ONDI_CFGPARAM | + ONDI_CT | ONDI_HBAAPI); + di->fc_ba.a_offmask = (OFFDI_MBOX | OFFDI_RMEM | OFFDI_WMEM | OFFDI_RPCI | + OFFDI_WPCI | OFFDI_RCTLREG | OFFDI_WCTLREG); + + if ((binfo->fc_flag & FC_SLI2) && (fc_diag_state == DDI_ONDI)) + di->fc_ba.a_onmask |= ONDI_SLI2; + else + di->fc_ba.a_onmask |= ONDI_SLI1; +#ifdef powerpc + di->fc_ba.a_onmask |= ONDI_BIG_ENDIAN; +#else + di->fc_ba.a_onmask |= ONDI_LTL_ENDIAN; +#endif + di->fc_ba.a_pci=((((uint32)pdev->device) << 16) | (uint32)(pdev->vendor)); + di->fc_ba.a_pci = SWAP_LONG(di->fc_ba.a_pci); + di->fc_ba.a_ddi = fcinstance[binfo->fc_brd_no]; + if(pdev->bus) + di->fc_ba.a_busid = (uint32)(pdev->bus->number); + else + di->fc_ba.a_busid = 0; + di->fc_ba.a_devid = (uint32)(pdev->devfn); + + bcopy((void *)lpfc_release_version, di->fc_ba.a_drvrid, 8); + decode_firmware_rev(binfo, &VPD); + bcopy((void *)fwrevision, di->fc_ba.a_fwname, 32); + + + /* setup structures for I/O mapping */ + di->fc_iomap_io = binfo->fc_iomap_io; + di->fc_iomap_mem = binfo->fc_iomap_mem; + di->fc_hmap = (char *)pdev; + return(0); +} + +/****************************************************************************** +* Function name : fc_readpci +* +* Description : Called by driver diagnostic interface to copy cnt bytes from +* PCI configuration registers, at offset, into buf. +******************************************************************************/ +int fc_readpci(struct dfc_info *di, + uint32 offset, + char *buf, + uint32 cnt) +{ + struct pci_dev *pdev; + int i; + uint32 *lp; + uint32 ldata; + + if(!di->fc_hmap) return(1); + pdev = (struct pci_dev *)di->fc_hmap; + for(i=0; i < cnt; i++){ + lp = (uint32 *)buf; + pci_read_config_dword(pdev,(u8)offset, (u32 *)buf); + ldata = *lp; + *lp = SWAP_LONG(ldata); + buf+=4; + offset+=4; + } + return(0); +} + +/****************************************************************************** +* Function name : fc_writepci +* +* Description : Called by driver diagnostic interface to write cnt bytes from +* buf into PCI configuration registers, starting at offset. +******************************************************************************/ +int fc_writepci(struct dfc_info *di, + uint32 offset, + char *buf, + uint32 cnt) +{ + struct pci_dev *pdev; + int i; + uint32 *lp; + uint32 ldata; + + if(!di->fc_hmap) return(1); + pdev = (struct pci_dev *)di->fc_hmap; + for(i=0; i < cnt; i++){ + lp = (uint32 *)buf; + ldata = *lp; + *lp = SWAP_LONG(ldata); + pci_write_config_dword(pdev,(u8)offset, *buf); + buf+=4; + offset+=4; + } + return(0); +} + +/****************************************************************************** +* Function name : copyout +* +* Description : copy from kernel-space to a user-space +* +******************************************************************************/ +int copyout(uchar *src, + uchar *dst, + unsigned long size) +{ + copy_to_user(dst,src,size); + return(0); +} + +/****************************************************************************** +* Function name : copyin +* +* Description : copy from user-space to kernel-space +* +******************************************************************************/ +int copyin(uchar *src, + uchar *dst, + unsigned long size) +{ + copy_from_user(dst,src,size); + return(0); +} + +/****************************************************************************** +* Function name : fc_getDVI +* +* Description : get a dvi ptr from a Linux scsi cmnd +* +******************************************************************************/ +_local_ dvi_t *fc_getDVI(fc_dev_ctl_t * p_dev_ctl, + int target, + fc_lun_t lun) +{ + FC_BRD_INFO * binfo; + iCfgParam * clp; + struct dev_info * dev_ptr; + struct dev_info * save_ptr; + node_t * node_ptr; + NODELIST * nlp; + int dev_index; + int report_device = 1; + + binfo = &p_dev_ctl->info; + clp = DD_CTL.p_config[binfo->fc_brd_no]; + dev_index = INDEX(ZERO_PAN, target); + + if (dev_index >= MAX_FC_TARGETS){ + return (0); + } + + if (lun < 0) { + /* LUN address out of range */ + fc_log_printf_msg_vargs( binfo->fc_brd_no, + &fc_msgBlk0718, /* ptr to msg structure */ + fc_mes0718, /* ptr to msg */ + fc_msgBlk0718.msgPreambleStr, /* begin varargs */ + target, + (uint32)lun); /* end varargs */ + return (0); + } + + /* + * Find the target from the nlplist based on SCSI ID + */ + if((nlp = fc_findnode_scsid(binfo, NLP_SEARCH_MAPPED, target)) == 0) { + /* + * Device SCSI ID is not a valid FCP target + */ + + return (0); + } + + /* Allocate SCSI node structure for each open FC node */ + node_ptr = binfo->device_queue_hash[dev_index].node_ptr; + if (node_ptr == NULL) { + if (!(node_ptr = (node_t * ) fc_kmem_zalloc(sizeof(node_t)))) { + return (0); + } + + /* Initialize the node ptr structure */ + node_ptr->ap = p_dev_ctl; /* point back to adapter struct */ + node_ptr->devno = target; + node_ptr->lunlist = NULL; + node_ptr->max_lun = lpfc_max_lun; + + node_ptr->last_dev = NULL; + node_ptr->num_active_io = 0; + node_ptr->virtRptLunData = 0; + node_ptr->physRptLunData = 0; + + node_ptr->tgt_queue_depth = (u_int)clp[CFG_DFT_TGT_Q_DEPTH].a_current; + + node_ptr->nlp = nlp; + node_ptr->rpi = nlp->nlp_Rpi; + node_ptr->last_good_rpi = nlp->nlp_Rpi; + node_ptr->scsi_id = target; + nlp->nlp_targetp = (uchar * )node_ptr; + binfo->device_queue_hash[dev_index].node_ptr = node_ptr; + } + + dev_ptr = fc_find_lun(binfo, dev_index, lun); + /* device queue structure doesn't exist yet */ + if ( dev_ptr == NULL ) { + if (!(dev_ptr = (dvi_t * ) fc_kmem_zalloc(sizeof(dvi_t)))) { + return (0); + } + + /* Initialize the dev_info structure */ + dev_ptr->nodep = node_ptr; + dev_ptr->lun_id = lun; + dev_ptr->flags = 0; + dev_ptr->sense_valid = FALSE; + + /* Initialize device queues */ + dev_ptr->ABORT_BDR_fwd = NULL; + dev_ptr->ABORT_BDR_bkwd = NULL; + dev_ptr->DEVICE_WAITING_fwd = NULL; + dev_ptr->pend_head = NULL; + dev_ptr->pend_tail = NULL; + dev_ptr->pend_count = 0; + dev_ptr->clear_head = NULL; + dev_ptr->clear_count = 0; + dev_ptr->active_io_count = 0; + dev_ptr->stop_send_io = 0; + dev_ptr->ioctl_wakeup = 0; + dev_ptr->qfull_retries = lpfc_qfull_retry; + dev_ptr->first_check = FIRST_CHECK_COND | FIRST_IO; + + dev_ptr->fcp_lun_queue_depth = (u_int)clp[CFG_DFT_LUN_Q_DEPTH].a_current; + if (dev_ptr->fcp_lun_queue_depth < 1) + dev_ptr->fcp_lun_queue_depth = 1; + + dev_ptr->fcp_cur_queue_depth = dev_ptr->fcp_lun_queue_depth; + + /* init command state flags */ + dev_ptr->queue_state = ACTIVE; + dev_ptr->opened = TRUE; + dev_ptr->ioctl_wakeup = FALSE; + dev_ptr->ioctl_event = EVENT_NULL; + dev_ptr->stop_event = FALSE; + + /* + * Create fc_bufs - allocate virtual and bus lists for use with FCP + */ + if(fc_rtalloc(p_dev_ctl, dev_ptr) == 0) { + fc_kmem_free(dev_ptr, sizeof(dvi_t)); + return (0); + } + + /* Add dev_ptr to lunlist */ + if (node_ptr->lunlist == NULL) { + node_ptr->lunlist = dev_ptr; + } else { + save_ptr = node_ptr->lunlist; + while (save_ptr->next != NULL ) { + save_ptr = save_ptr->next; + } + save_ptr->next = dev_ptr; + } + dev_ptr->next = NULL; + } + + if(clp[CFG_DEVICE_REPORT].a_current + && dev_ptr!=NULL && report_device && + (dev_ptr->nodep->nlp->nlp_type & NLP_FCP_TARGET)) { + nlp = dev_ptr->nodep->nlp; + printk(KERN_INFO"!lpfc%d: Acquired FCP/SCSI Target 0x%lx LUN 0x%lx , D_ID is (0x%lx)\n", + binfo->fc_brd_no, + (ulong)target, + (ulong)lun, + (ulong)(nlp->nlp_DID)); + } + + return (dev_ptr); +} + +dvi_t * +fc_alloc_devp( +fc_dev_ctl_t * p_dev_ctl, +int target, +fc_lun_t lun) +{ + return fc_getDVI(p_dev_ctl, target, lun); +} + +/****************************************************************************** +* Function name : deviFree +* +* Description : Free a dvi_t pointer +* +******************************************************************************/ +_local_ void deviFree(fc_dev_ctl_t *p_dev_ctl, + dvi_t *dev_ptr, + node_t *node_ptr) +{ + struct dev_info *curDev, *prevDev; + fc_buf_t *curFcBuf, *tmpFcBuf; + struct sc_buf *sp; + dma_addr_t phys; + unsigned int size; + MBUF_INFO * buf_info; + MBUF_INFO bufinfo; + + /* + * First, we free up all fcbuf for this device. + */ + curFcBuf = dev_ptr->fcbuf_head; + while (curFcBuf != NULL) { + tmpFcBuf = curFcBuf->fc_fwd; + phys = (dma_addr_t)((ulong)curFcBuf->phys_adr); + size = fc_po2(sizeof(fc_buf_t)); + + buf_info = &bufinfo; + buf_info->phys = (void *)((ulong)phys); + buf_info->data_handle = 0; + buf_info->dma_handle = 0; + buf_info->flags = FC_MBUF_DMA; + buf_info->virt = (uint32 * )curFcBuf; + buf_info->size = size; + fc_free(p_dev_ctl, buf_info); + curFcBuf = tmpFcBuf; + } /* end while loop */ + while (dev_ptr->scp != NULL) { + sp = dev_ptr->scp; + dev_ptr->scp = sp->bufstruct.av_forw; + dev_ptr->scpcnt--; + fc_kmem_free((void *)sp, sizeof(struct sc_buf)); + } + + /* + * Next, we are going to remove this device-lun combination. + * But we need to make sure the link list where this dev_ptr + * belongs is not broken. + */ + + curDev = node_ptr->lunlist; + prevDev = curDev; + while (curDev != NULL) { + if (curDev == dev_ptr) + break; + else { + prevDev = curDev; + curDev = curDev->next; + } + } + + if (curDev == dev_ptr) { /* This should always pass */ + if (curDev == node_ptr->lunlist) + node_ptr->lunlist = curDev->next; + else + prevDev->next = curDev->next; + } + fc_kmem_free((void *)dev_ptr, sizeof(dvi_t)); +} +/****************************************************************************** +* Function name : fc_print +* +* Description : +* +******************************************************************************/ +int fc_print( char *str, + void *a1, + void *a2) +{ + printk((const char *)str, a1, a2); + return(1); +} /* fc_print */ + +/****************************************************************************** +* Function name : log_printf_msgblk +* +* Description : Called from common code function fc_log_printf_msg_vargs +* Note : Input string 'str' is formatted (sprintf) by caller. +******************************************************************************/ +int log_printf_msgblk(int brdno, + msgLogDef * msg, + char * str, /* String formatted by caller */ + int log_only) +{ + int ddiinst; + char * mod; + + ddiinst = fcinstance[brdno]; + mod = "lpfc"; + if (log_only) { + /* system buffer only */ + switch(msg->msgType) { + case FC_LOG_MSG_TYPE_INFO: + case FC_LOG_MSG_TYPE_WARN: + /* These LOG messages appear in LOG file only */ + printk(KERN_INFO"!%s%d:%04d:%s\n", mod, ddiinst, msg->msgNum, str); + break; + case FC_LOG_MSG_TYPE_ERR_CFG: + case FC_LOG_MSG_TYPE_ERR: + /* These LOG messages appear on the monitor and in the LOG file */ + printk(KERN_WARNING"!%s%d:%04d:%s\n", mod, ddiinst, msg->msgNum, str); + break; + case FC_LOG_MSG_TYPE_PANIC: + panic("!%s%d:%04d:%s\n", mod, ddiinst, msg->msgNum, str); + break; + default: + return(0); + } + } + else { + switch(msg->msgType) { + case FC_LOG_MSG_TYPE_INFO: + case FC_LOG_MSG_TYPE_WARN: + printk(KERN_INFO"!%s%d:%04d:%s\n", mod, ddiinst, msg->msgNum, str); + break; + case FC_LOG_MSG_TYPE_ERR_CFG: + case FC_LOG_MSG_TYPE_ERR: + printk(KERN_WARNING"!%s%d:%04d:%s\n", mod, ddiinst, msg->msgNum, str); + break; + case FC_LOG_MSG_TYPE_PANIC: + panic("!%s%d:%04d:%s\n", mod, ddiinst, msg->msgNum, str); + break; + default: + return(0); + } + } + return(1); +} /* log_printf_msgblk */ + +/****************************************************************************** +* Function name : fc_write_toio +* +******************************************************************************/ +_static_ void fc_write_toio(uint32 *src, + uint32 *dest_io, + uint32 cnt) +{ + uint32 ldata; + int i; + + for (i = 0; i < (int)cnt; i += sizeof(uint32)) { + ldata = *src++; + writel(ldata, dest_io); + dest_io++; + } + return; +} + +/****************************************************************************** +* Function name : fc_read_fromio +* +* Description : +* +******************************************************************************/ +_static_ void fc_read_fromio( uint32 *src_io, + uint32 *dest, + uint32 cnt) +{ + uint32 ldata; + int i; + + for (i = 0; i < (int)cnt; i += sizeof(uint32)) { + ldata = readl(src_io); + src_io++; + *dest++ = ldata; + } + return; +} + +/****************************************************************************** +* Function name : fc_writel +* +* Description : +* +******************************************************************************/ +_static_ void fc_writel(uint32 * src_io, + uint32 ldata) +{ + writel(ldata, src_io); + return; +} + +/****************************************************************************** +* Function name : fc_readl +* +* Description : +* +******************************************************************************/ +_static_ uint32 fc_readl(uint32 *src_io) +{ + uint32 ldata; + + ldata = readl(src_io); + return(ldata); +} + + + +#ifdef MODULE +/* + * XXX: patman I don't know why this is needed. Maybe for out of tree + * builds? +#include "lpfc.ver" + */ +#endif /* MODULE */ + +#endif /* __GENKSYMS__ */ + +#ifdef MODULE + +#ifndef EXPORT_SYMTAB +#define EXPORT_SYMTAB +#endif + +int lpfc_xmit(fc_dev_ctl_t *p_dev_ctl, struct sk_buff *skb); +int lpfc_ioctl(int cmd, void *s); + +EXPORT_SYMBOL(lpfc_xmit); +EXPORT_SYMBOL(lpfc_ioctl); + +#endif /* MODULE */ + +/****************************************************************************** +* Function name : fc_ioctl +* +* Description : ioctl interface to diagnostic utilities +* called by a special character device driver (fcLINUXdiag.c) +* fd is the board number (instance), and s is a cmninfo pointer +* +******************************************************************************/ +int fc_ioctl(int cmd, + void *s) +{ + int rc, fd; + fc_dev_ctl_t *p_dev_ctl; + struct dfccmdinfo *cp = (struct dfccmdinfo *)s; + struct cmd_input *ci = (struct cmd_input *)cp->c_datain; + + if(!cp || !ci) + return EINVAL; + fd = ci->c_brd; + if(fd > DD_CTL.num_devs) + return EINVAL; + if(!(p_dev_ctl = (fc_dev_ctl_t *)DD_CTL.p_dev[fd])) + return EINVAL; + + rc = dfc_ioctl(cp, ci); + + return(rc); +} + +/****************************************************************************** +* Function name : dfc_sleep +* +* Description : +* +******************************************************************************/ +int dfc_sleep(fc_dev_ctl_t *p_dev_ctl, + fcEvent_header *ep) +{ + switch(ep->e_mask) { + case FC_REG_LINK_EVENT: + ep->e_mode |= E_SLEEPING_MODE; + interruptible_sleep_on(&p_dev_ctl->linkwq); + if (signal_pending (current)) + return(1); + break; + case FC_REG_RSCN_EVENT: + ep->e_mode |= E_SLEEPING_MODE; + interruptible_sleep_on(&p_dev_ctl->rscnwq); + if (signal_pending (current)) + return(1); + break; + case FC_REG_CT_EVENT: + ep->e_mode |= E_SLEEPING_MODE; + interruptible_sleep_on(&p_dev_ctl->ctwq); + if (signal_pending (current)) + return(1); + break; + } + return(0); +} + +/****************************************************************************** +* Function name : dfc_wakeup +* +* Description : +* +******************************************************************************/ +int dfc_wakeup(fc_dev_ctl_t *p_dev_ctl, + fcEvent_header *ep) +{ + switch(ep->e_mask) { + case FC_REG_LINK_EVENT: + ep->e_mode &= ~E_SLEEPING_MODE; + wake_up_interruptible(&p_dev_ctl->linkwq); + break; + case FC_REG_RSCN_EVENT: + ep->e_mode &= ~E_SLEEPING_MODE; + wake_up_interruptible(&p_dev_ctl->rscnwq); + break; + case FC_REG_CT_EVENT: + ep->e_mode &= ~E_SLEEPING_MODE; + wake_up_interruptible(&p_dev_ctl->ctwq); + break; + } + return(0); +} + +/****************************************************************************** +* Function name : lpfc_xmit +* +* Description : +* +******************************************************************************/ +int lpfc_xmit(fc_dev_ctl_t *p_dev_ctl, + struct sk_buff *skb) +{ + int rc; + ulong siflg, iflg; + + siflg = 0; + LPFC_LOCK_SCSI_DONE(p_dev_ctl->host); + iflg = 0; + LPFC_LOCK_DRIVER(15); + rc = fc_xmit(p_dev_ctl, skb); + LPFC_UNLOCK_DRIVER; + LPFC_UNLOCK_SCSI_DONE(p_dev_ctl->host); + return(rc); +} + +/****************************************************************************** +* Function name : lpfc_ioctl +* +* Description : +* +******************************************************************************/ +int lpfc_ioctl(int cmd, + void *s) +{ + int i, cnt, ipri; + NETDEVICE *dev; + fc_dev_ctl_t *p_dev_ctl; + FC_BRD_INFO * binfo; + iCfgParam * clp; + struct lpfn_probe *lp; + ndd_t * p_ndd; + + cnt = 0; + switch(cmd) { + case LPFN_PROBE: +#ifndef MODULE + if(lpfc_detect_called != 1) { + lpfc_detect_called = 2; /* defer calling this till after fc_detect */ + return(1); + } +#endif /* MODULE */ + + for (i = 0; i < MAX_FC_BRDS; i++) { + if((p_dev_ctl = (fc_dev_ctl_t *)DD_CTL.p_dev[i])) { + clp = DD_CTL.p_config[i]; + binfo = &BINFO; + if(clp[CFG_NETWORK_ON].a_current == 0) + continue; + ipri = disable_lock(FC_LVL, &CMD_LOCK); + if(p_dev_ctl->ihs.lpfn_dev == 0) { + unsigned int alloc_size; + + /* ensure 32-byte alignment of the private area */ + alloc_size = sizeof(NETDEVICE) + 31; + + dev = (NETDEVICE *) lpfc_kmalloc (alloc_size, GFP_KERNEL, 0, 0); + if (dev == NULL) { + unlock_enable(ipri, &CMD_LOCK); + continue; + } + memset(dev, 0, alloc_size); +#if LINUX_VERSION_CODE < LinuxVersionCode(2,4,0) + dev->name = (char *)(dev + 1); + sprintf(dev->name, "lpfn%d", binfo->fc_brd_no); + +#else + rtnl_lock(); + strcpy(dev->name, "lpfn%d"); + if (dev_alloc_name(dev, "lpfn%d")<0) { + rtnl_unlock(); + lpfc_kfree(alloc_size, (void *)dev, (void *)((ulong)INVALID_PHYS), 0); + unlock_enable(ipri, &CMD_LOCK); + continue; + } + +#endif + dev->priv = (void *)p_dev_ctl; + p_dev_ctl->ihs.lpfn_dev = dev; + + lp = (struct lpfn_probe *)s; + p_ndd = (ndd_t * ) & (NDD); + /* Initialize the device structure. */ + dev->hard_start_xmit = lp->hard_start_xmit; + dev->get_stats = lp->get_stats; + dev->open = lp->open; + dev->stop = lp->stop; + dev->hard_header = lp->hard_header; + dev->rebuild_header = lp->rebuild_header; + dev->change_mtu = lp->change_mtu; + p_ndd->nd_receive = + (void (*)(void *, struct sk_buff *, void *))(lp->receive); + + /* Assume fc header + LLC/SNAP 24 bytes */ + dev->hard_header_len = 24; + dev->type = ARPHRD_ETHER; + dev->mtu = p_dev_ctl->ihs.lpfn_mtu; + dev->addr_len = 6; + dev->tx_queue_len = 100; + + memset(dev->broadcast, 0xFF, 6); + bcopy(p_dev_ctl->phys_addr, dev->dev_addr, 6); + + /* New-style flags */ + dev->flags = IFF_BROADCAST; + register_netdevice(dev); +#if LINUX_VERSION_CODE >= LinuxVersionCode(2,4,0) + rtnl_unlock(); +#endif + + cnt++; + } + unlock_enable(ipri, &CMD_LOCK); + } + } + break; + case LPFN_DETACH: + for (i = 0; i < MAX_FC_BRDS; i++) { + if((p_dev_ctl = (fc_dev_ctl_t *)DD_CTL.p_dev[i])) { + clp = DD_CTL.p_config[i]; + if(clp[CFG_NETWORK_ON].a_current == 0) + continue; + ipri = disable_lock(FC_LVL, &CMD_LOCK); + if((dev=p_dev_ctl->ihs.lpfn_dev)) { + unregister_netdev(dev); + dev->priv = NULL; + p_dev_ctl->ihs.lpfn_dev = 0; + cnt++; + } + unlock_enable(ipri, &CMD_LOCK); + } + } + break; + case LPFN_DFC: + break; + default: + return(0); + } + return(cnt); +} + + +/****************************************************************************** +* Function name : lpfcdfc_init +* +* Description : Register your major, and accept a dynamic number +* +******************************************************************************/ +int lpfcdfc_init(void) +{ + int result; +#ifdef powerpc + fc_dev_ctl_t *p_dev_ctl; + MBUF_INFO *buf_info; + MBUF_INFO bufinfo; + int i; +#endif + + result = register_chrdev(lpfc_major, "lpfcdfc", &lpfc_fops); + if (result < 0) { + printk(KERN_WARNING "lpfcdfc: can't get major %d\n",lpfc_major); + return result; + } + if (lpfc_major == 0) lpfc_major = result; /* dynamic */ + +#ifdef powerpc + for(i=0; i < MAX_FC_BRDS; i++) { + p_dev_ctl = (fc_dev_ctl_t *)DD_CTL.p_dev[i]; + if(p_dev_ctl) { + buf_info = &bufinfo; + buf_info->virt = 0; + buf_info->phys = 0; + buf_info->flags = (FC_MBUF_IOCTL | FC_MBUF_UNLOCK); + buf_info->align = sizeof(void *); + buf_info->size = 64 * 1024; + buf_info->dma_handle = 0; + + fc_malloc(p_dev_ctl, buf_info); + p_dev_ctl->dfc_kernel_buf = buf_info->virt; + } + } +#endif + + return 0; +} + +/****************************************************************************** +* Function name : lpfcdiag_ioctl +* +* Description : caller must insure that cmd is the board number and arg is +* the cmdinfo pointer +* +******************************************************************************/ +int lpfcdiag_ioctl(struct inode * inode, + struct file * file, + unsigned int cmd, + unsigned long arg) +{ + return -fc_ioctl(cmd, (void *)arg); +} + +/****************************************************************************** +* Function name : lpfcdiag_open +* +* Description : +* +******************************************************************************/ +int lpfcdiag_open(struct inode * inode, + struct file * file) +{ + fc_dev_ctl_t *p_dev_ctl; + struct Scsi_Host *host; + + if(((p_dev_ctl = DD_CTL.p_dev[0])) && + ((host = p_dev_ctl->host))) { + lpfcdiag_cnt++; + } + return(0); +} + +/****************************************************************************** +* Function name : lpfcdiag_release +* +* Description : +* +******************************************************************************/ +int lpfcdiag_release(struct inode * inode, + struct file * file) +{ + fc_dev_ctl_t *p_dev_ctl; + struct Scsi_Host *host; + + if(((p_dev_ctl = DD_CTL.p_dev[0])) && + ((host = p_dev_ctl->host))) { + lpfcdiag_cnt--; + } + return(0); +} + +/****************************************************************************** +* Function name : fc_get_dds_bind +* +* Description : Called from fc_attach to setup binding parameters for adapter +******************************************************************************/ +int fc_get_dds_bind(fc_dev_ctl_t *p_dev_ctl) +{ + FC_BRD_INFO *binfo; + iCfgParam *clp; + char **arrayp; + u_int cnt; + + /* + * Check if there are any WWNN / scsid bindings + */ + binfo = &BINFO; + clp = DD_CTL.p_config[binfo->fc_brd_no]; + cnt = lpfc_bind_entries; + arrayp = lpfc_fcp_bind_WWNN; + if(cnt && (*arrayp != 0)) { + fc_bind_wwnn(p_dev_ctl, arrayp, cnt); + } else { + + /* + * Check if there are any WWPN / scsid bindings + */ + arrayp = lpfc_fcp_bind_WWPN; + if(cnt && (*arrayp != 0)) { + fc_bind_wwpn(p_dev_ctl, arrayp, cnt); + } else { + + /* + * Check if there are any NPortID / scsid bindings + */ + arrayp = lpfc_fcp_bind_DID; + if(cnt && (*arrayp != 0)) { + fc_bind_did(p_dev_ctl, arrayp, cnt); + } else { + switch(clp[CFG_AUTOMAP].a_current) { + case 2: + p_dev_ctl->fcp_mapping = FCP_SEED_WWPN; + break; + case 3: + p_dev_ctl->fcp_mapping = FCP_SEED_DID; + break; + default: + p_dev_ctl->fcp_mapping = FCP_SEED_WWNN; + } + } + } + } + + clp[CFG_SCAN_DOWN].a_current = (uint32)lpfc_scandown; + if(cnt && (*arrayp != 0) && (clp[CFG_SCAN_DOWN].a_current == 2)) { + /* Scan-down is 2 with Persistent binding - ignoring scan-down */ + fc_log_printf_msg_vargs( binfo->fc_brd_no, + &fc_msgBlk0411, /* ptr to msg structure */ + fc_mes0411, /* ptr to msg */ + fc_msgBlk0411.msgPreambleStr, /* begin varargs */ + clp[CFG_SCAN_DOWN].a_current, + p_dev_ctl->fcp_mapping); /* end varargs */ + clp[CFG_SCAN_DOWN].a_current = 0; + } + if(clp[CFG_SCAN_DOWN].a_current > 2) { + /* Scan-down is out of range - ignoring scan-down */ + fc_log_printf_msg_vargs( binfo->fc_brd_no, + &fc_msgBlk0412, /* ptr to msg structure */ + fc_mes0412, /* ptr to msg */ + fc_msgBlk0412.msgPreambleStr, /* begin varargs */ + clp[CFG_SCAN_DOWN].a_current, + p_dev_ctl->fcp_mapping); /* end varargs */ + clp[CFG_SCAN_DOWN].a_current = 0; + } + return(0); +} + +/****************************************************************************** +* Function name : fc_get_dds +* +* Description : Called from fc_attach to setup configuration parameters for +* adapter +* The goal of this routine is to fill in all the a_current +* members of the CfgParam structure for all configuration +* parameters. +* Example: +* clp[CFG_XXX].a_current = (uint32)value; +* value might be a define, a global variable, clp[CFG_XXX].a_default, +* or some other enviroment specific way of initializing config parameters. +******************************************************************************/ +int fc_get_dds(fc_dev_ctl_t *p_dev_ctl, + uint32 *pio) +{ + FC_BRD_INFO *binfo; + iCfgParam *clp; + int i; + int brd; + + binfo = &BINFO; + brd = binfo->fc_brd_no; + clp = DD_CTL.p_config[brd]; + + p_dev_ctl->open_state = NORMAL_OPEN; + + /* + * Set everything to the defaults + */ + for(i=0; i < NUM_CFG_PARAM; i++) + clp[i].a_current = clp[i].a_default; + + /* Default values for I/O colaesing */ + clp[CFG_CR_DELAY].a_current = + (uint32)((ulong)fc_get_cfg_param(brd, CFG_CR_DELAY)); + clp[CFG_CR_COUNT].a_current = + (uint32)((ulong)fc_get_cfg_param(brd, CFG_CR_COUNT)); + + clp[CFG_AUTOMAP].a_current = + (uint32)((ulong)fc_get_cfg_param(brd, CFG_AUTOMAP)); + + clp[CFG_LINK_SPEED].a_current = + (uint32)((ulong)fc_get_cfg_param(brd, CFG_LINK_SPEED)); + + bcopy((uchar * )"lpfc0", (uchar *)DDS.logical_name, 6); + DDS.logical_name[4] += binfo->fc_brd_no; + DDS.logical_name[5] = 0; + + clp[CFG_INTR_ACK].a_current = (uint32)lpfc_intr_ack; + clp[CFG_IDENTIFY_SELF].a_current = 0; + clp[CFG_DEVICE_REPORT].a_current = 0; + + clp[CFG_LOG_VERBOSE].a_current = + (uint32)((ulong)fc_get_cfg_param(brd, CFG_LOG_VERBOSE)); + clp[CFG_LOG_ONLY].a_current = + (uint32)((ulong)fc_get_cfg_param(brd, CFG_LOG_ONLY)); + + /* Can NOT log verbose messages until you read VERBOSE config param */ + if((binfo->fc_flag & FC_2G_CAPABLE) == 0) { + /* This HBA is NOT 2G_CAPABLE */ + if( clp[CFG_LINK_SPEED].a_current > 1) { + /* Reset link speed to auto. 1G HBA cfg'd for 2G. */ + fc_log_printf_msg_vargs( binfo->fc_brd_no, + &fc_msgBlk1303, /* ptr to msg structure */ + fc_mes1303, /* ptr to msg */ + fc_msgBlk1303.msgPreambleStr); /* begin & end varargs */ + clp[CFG_LINK_SPEED].a_current = LINK_SPEED_AUTO; + } + } + + clp[CFG_NUM_IOCBS].a_current = + (uint32)((ulong)fc_get_cfg_param(brd, CFG_NUM_IOCBS)); + + if (clp[CFG_NUM_IOCBS].a_current < LPFC_MIN_NUM_IOCBS) { + /* Num-iocbs too low, resetting */ + fc_log_printf_msg_vargs( binfo->fc_brd_no, + &fc_msgBlk0413, /* ptr to msg structure */ + fc_mes0413, /* ptr to msg */ + fc_msgBlk0413.msgPreambleStr, /* begin varargs */ + clp[CFG_NUM_IOCBS].a_current, + LPFC_MIN_NUM_IOCBS); /* end varargs */ + clp[CFG_NUM_IOCBS].a_current = LPFC_MIN_NUM_IOCBS; + } + if (clp[CFG_NUM_IOCBS].a_current > LPFC_MAX_NUM_IOCBS) { + /* Num-iocbs too high, resetting */ + fc_log_printf_msg_vargs( binfo->fc_brd_no, + &fc_msgBlk0414, /* ptr to msg structure */ + fc_mes0414, /* ptr to msg */ + fc_msgBlk0414.msgPreambleStr, /* begin varargs */ + clp[CFG_NUM_IOCBS].a_current, + LPFC_MAX_NUM_IOCBS); /* end varargs */ + clp[CFG_NUM_IOCBS].a_current = LPFC_MAX_NUM_IOCBS; + } + + clp[CFG_NUM_BUFS].a_current = + (uint32)((ulong)fc_get_cfg_param(brd, CFG_NUM_BUFS)); + + if (clp[CFG_NUM_BUFS].a_current < LPFC_MIN_NUM_BUFS) { + /* Num-bufs too low, resetting */ + fc_log_printf_msg_vargs( binfo->fc_brd_no, + &fc_msgBlk0415, /* ptr to msg structure */ + fc_mes0415, /* ptr to msg */ + fc_msgBlk0415.msgPreambleStr, /* begin varargs */ + clp[CFG_NUM_BUFS].a_current, + LPFC_MIN_NUM_BUFS); /* end varargs */ + clp[CFG_NUM_BUFS].a_current = LPFC_MIN_NUM_BUFS; + } + if (clp[CFG_NUM_BUFS].a_current > LPFC_MAX_NUM_BUFS) { + /* Num-bufs too high, resetting */ + fc_log_printf_msg_vargs( binfo->fc_brd_no, + &fc_msgBlk0416, /* ptr to msg structure */ + fc_mes0416, /* ptr to msg */ + fc_msgBlk0416.msgPreambleStr, /* begin varargs */ + clp[CFG_NUM_BUFS].a_current, + LPFC_MAX_NUM_BUFS); /* end varargs */ + clp[CFG_NUM_BUFS].a_current = LPFC_MAX_NUM_BUFS; + } + + clp[CFG_FCP_ON].a_current = 1; + clp[CFG_DFT_TGT_Q_DEPTH].a_current = + (uint32)((ulong)fc_get_cfg_param(brd, CFG_DFT_TGT_Q_DEPTH)); + clp[CFG_DFT_LUN_Q_DEPTH].a_current = + (uint32)((ulong)fc_get_cfg_param(brd, CFG_DFT_LUN_Q_DEPTH)); + if (clp[CFG_DFT_TGT_Q_DEPTH].a_current > LPFC_MAX_TGT_Q_DEPTH ) { + /* Target qdepth too high, resetting to max */ + fc_log_printf_msg_vargs( binfo->fc_brd_no, + &fc_msgBlk0417, /* ptr to msg structure */ + fc_mes0417, /* ptr to msg */ + fc_msgBlk0417.msgPreambleStr, /* begin varargs */ + clp[CFG_DFT_TGT_Q_DEPTH].a_current, + LPFC_MAX_TGT_Q_DEPTH); /* end varargs */ + clp[CFG_DFT_TGT_Q_DEPTH].a_current = LPFC_MAX_TGT_Q_DEPTH; + } + if (clp[CFG_DFT_LUN_Q_DEPTH].a_current > LPFC_MAX_LUN_Q_DEPTH ) { + /* Lun qdepth too high, resetting to max */ + fc_log_printf_msg_vargs( binfo->fc_brd_no, + &fc_msgBlk0418, /* ptr to msg structure */ + fc_mes0418, /* ptr to msg */ + fc_msgBlk0418.msgPreambleStr, /* begin varargs */ + clp[CFG_DFT_LUN_Q_DEPTH].a_current, + LPFC_MAX_LUN_Q_DEPTH); /* end varargs */ + clp[CFG_DFT_LUN_Q_DEPTH].a_current = LPFC_MAX_LUN_Q_DEPTH; + } + if (clp[CFG_DFT_LUN_Q_DEPTH].a_current == 0 ) { + /* Lun qdepth cannot be , resetting to 1 */ + fc_log_printf_msg_vargs( binfo->fc_brd_no, + &fc_msgBlk0419, /* ptr to msg structure */ + fc_mes0419, /* ptr to msg */ + fc_msgBlk0419.msgPreambleStr, /* begin varargs */ + clp[CFG_DFT_LUN_Q_DEPTH].a_current ); /* end varargs */ + clp[CFG_DFT_LUN_Q_DEPTH].a_current = 1; + } + + clp[CFG_DQFULL_THROTTLE_UP_TIME].a_current = + (uint32)((ulong)fc_get_cfg_param(brd, CFG_DQFULL_THROTTLE_UP_TIME)); + clp[CFG_DQFULL_THROTTLE_UP_INC].a_current = + (uint32)((ulong)fc_get_cfg_param(brd, CFG_DQFULL_THROTTLE_UP_INC)); + + clp[CFG_FIRST_CHECK].a_current = (uint32)lpfc_first_check; + clp[CFG_FCPFABRIC_TMO].a_current = + (uint32)((ulong)fc_get_cfg_param(brd, CFG_FCPFABRIC_TMO)); + if (clp[CFG_FCPFABRIC_TMO].a_current > LPFC_MAX_FABRIC_TIMEOUT) { + /* Fcpfabric_tmo too high, resetting */ + fc_log_printf_msg_vargs( binfo->fc_brd_no, + &fc_msgBlk0420, /* ptr to msg structure */ + fc_mes0420, /* ptr to msg */ + fc_msgBlk0420.msgPreambleStr, /* begin varargs */ + clp[CFG_FCPFABRIC_TMO].a_current, + LPFC_MAX_FABRIC_TIMEOUT); /* end varargs */ + clp[CFG_FCPFABRIC_TMO].a_current = LPFC_MAX_FABRIC_TIMEOUT; + } + + clp[CFG_FCP_CLASS].a_current = + (uint32)((ulong)fc_get_cfg_param(brd, CFG_FCP_CLASS)); + switch (clp[CFG_FCP_CLASS].a_current) { + case 2: + clp[CFG_FCP_CLASS].a_current = CLASS2; + break; + case 3: + clp[CFG_FCP_CLASS].a_current = CLASS3; + break; + default: + /* Fcp-class is illegal, resetting to default */ + fc_log_printf_msg_vargs( binfo->fc_brd_no, + &fc_msgBlk0421, /* ptr to msg structure */ + fc_mes0421, /* ptr to msg */ + fc_msgBlk0421.msgPreambleStr, /* begin varargs */ + clp[CFG_FCP_CLASS].a_current, + CLASS3); /* end varargs */ + clp[CFG_FCP_CLASS].a_current = CLASS3; + break; + } + + clp[CFG_USE_ADISC].a_current = + (uint32)((ulong)fc_get_cfg_param(brd, CFG_USE_ADISC)); + + clp[CFG_NO_DEVICE_DELAY].a_current = + (uint32)((ulong)fc_get_cfg_param(brd, CFG_NO_DEVICE_DELAY)); + if (clp[CFG_NO_DEVICE_DELAY].a_current > LPFC_MAX_NO_DEVICE_DELAY) { + /* No-device-delay too high, resetting to max */ + fc_log_printf_msg_vargs( binfo->fc_brd_no, + &fc_msgBlk0422, /* ptr to msg structure */ + fc_mes0422, /* ptr to msg */ + fc_msgBlk0422.msgPreambleStr, /* begin varargs */ + clp[CFG_NO_DEVICE_DELAY].a_current, + LPFC_MAX_NO_DEVICE_DELAY); /* end varargs */ + clp[CFG_NO_DEVICE_DELAY].a_current = LPFC_MAX_NO_DEVICE_DELAY; + } + + clp[CFG_NETWORK_ON].a_current = + (uint32)((ulong)fc_get_cfg_param(brd, CFG_NETWORK_ON)); + clp[CFG_POST_IP_BUF].a_current = + (uint32)((ulong)fc_get_cfg_param(brd, CFG_POST_IP_BUF)); + + if (clp[CFG_POST_IP_BUF].a_current < LPFC_MIN_POST_IP_BUF) { + /* Post_ip_buf too low, resetting */ + fc_log_printf_msg_vargs( binfo->fc_brd_no, + &fc_msgBlk0423, /* ptr to msg structure */ + fc_mes0423, /* ptr to msg */ + fc_msgBlk0423.msgPreambleStr, /* begin varargs */ + clp[CFG_POST_IP_BUF].a_current, + LPFC_MIN_POST_IP_BUF); /* end varargs */ + clp[CFG_POST_IP_BUF].a_current = LPFC_MIN_POST_IP_BUF; + } + if (clp[CFG_POST_IP_BUF].a_current > LPFC_MAX_POST_IP_BUF) { + /* Post_ip_buf too high, resetting */ + fc_log_printf_msg_vargs( binfo->fc_brd_no, + &fc_msgBlk0424, /* ptr to msg structure */ + fc_mes0424, /* ptr to msg */ + fc_msgBlk0424.msgPreambleStr, /* begin varargs */ + clp[CFG_POST_IP_BUF].a_current, + LPFC_MAX_POST_IP_BUF); /* end varargs */ + clp[CFG_POST_IP_BUF].a_current = LPFC_MAX_POST_IP_BUF; + } + + clp[CFG_XMT_Q_SIZE].a_current = + (uint32)((ulong)fc_get_cfg_param(brd, CFG_XMT_Q_SIZE)); + if (clp[CFG_XMT_Q_SIZE].a_current < LPFC_MIN_XMT_QUE_SIZE) { + /* Xmt-que_size too low, resetting */ + fc_log_printf_msg_vargs( binfo->fc_brd_no, + &fc_msgBlk0425, /* ptr to msg structure */ + fc_mes0425, /* ptr to msg */ + fc_msgBlk0425.msgPreambleStr, /* begin varargs */ + clp[CFG_XMT_Q_SIZE].a_current, + LPFC_MIN_XMT_QUE_SIZE); /* end varargs */ + clp[CFG_XMT_Q_SIZE].a_current = LPFC_MIN_XMT_QUE_SIZE; + } + if (clp[CFG_XMT_Q_SIZE].a_current > LPFC_MAX_XMT_QUE_SIZE) { + /* Xmt-que_size too high, resetting */ + fc_log_printf_msg_vargs( binfo->fc_brd_no, + &fc_msgBlk0426, /* ptr to msg structure */ + fc_mes0426, /* ptr to msg */ + fc_msgBlk0426.msgPreambleStr, /* begin varargs */ + clp[CFG_XMT_Q_SIZE].a_current, + LPFC_MAX_XMT_QUE_SIZE); /* end varargs */ + clp[CFG_XMT_Q_SIZE].a_current = LPFC_MAX_XMT_QUE_SIZE; + } + binfo->fc_ring[FC_IP_RING].fc_tx.q_max = clp[CFG_XMT_Q_SIZE].a_current; + + clp[CFG_IP_CLASS].a_current = (uint32)((ulong)fc_get_cfg_param(brd, CFG_IP_CLASS)); + switch (clp[CFG_IP_CLASS].a_current) { + case 2: + clp[CFG_IP_CLASS].a_current = CLASS2; + break; + case 3: + clp[CFG_IP_CLASS].a_current = CLASS3; + break; + default: + /* Ip-class is illegal, resetting */ + fc_log_printf_msg_vargs( binfo->fc_brd_no, + &fc_msgBlk0427, /* ptr to msg structure */ + fc_mes0427, /* ptr to msg */ + fc_msgBlk0427.msgPreambleStr, /* begin varargs */ + clp[CFG_IP_CLASS].a_current, + CLASS3); /* end varargs */ + clp[CFG_IP_CLASS].a_current = CLASS3; + break; + } + + clp[CFG_ZONE_RSCN].a_current = (uint32)lpfc_zone_rscn; + p_dev_ctl->vendor_flag = (uint32)lpfc_vendor; + + clp[CFG_HOLDIO].a_current = (uint32)((ulong)fc_get_cfg_param(brd, CFG_HOLDIO)); + clp[CFG_ACK0].a_current = (uint32)((ulong)fc_get_cfg_param(brd, CFG_ACK0)); + clp[CFG_TOPOLOGY].a_current = (uint32)((ulong)fc_get_cfg_param(brd, CFG_TOPOLOGY)); + + switch (clp[CFG_TOPOLOGY].a_current) { + case 0: + case 1: + case 2: + case 4: + case 6: + /* topology is a valid choice */ + break; + default: + /* Topology is illegal, resetting */ + fc_log_printf_msg_vargs( binfo->fc_brd_no, + &fc_msgBlk0428, /* ptr to msg structure */ + fc_mes0428, /* ptr to msg */ + fc_msgBlk0428.msgPreambleStr, /* begin varargs */ + clp[CFG_TOPOLOGY].a_current, + LPFC_DFT_TOPOLOGY); /* end varargs */ + clp[CFG_TOPOLOGY].a_current = LPFC_DFT_TOPOLOGY; + break; + } + + clp[CFG_NODEV_TMO].a_current = + (uint32)((ulong)fc_get_cfg_param(brd, CFG_NODEV_TMO)); + clp[CFG_DELAY_RSP_ERR].a_current = + (uint32)((ulong)fc_get_cfg_param(brd, CFG_DELAY_RSP_ERR)); + clp[CFG_CHK_COND_ERR].a_current = + (uint32)((ulong)fc_get_cfg_param(brd, CFG_CHK_COND_ERR)); + + clp[CFG_LINKDOWN_TMO].a_current = + (uint32)((ulong)fc_get_cfg_param(brd, CFG_LINKDOWN_TMO)); + if (clp[CFG_LINKDOWN_TMO].a_current > LPFC_MAX_LNKDWN_TIMEOUT) { + /* Linkdown_tmo too high, resetting */ + fc_log_printf_msg_vargs( binfo->fc_brd_no, + &fc_msgBlk0429, /* ptr to msg structure */ + fc_mes0429, /* ptr to msg */ + fc_msgBlk0429.msgPreambleStr, /* begin varargs */ + clp[CFG_LINKDOWN_TMO].a_current, + LPFC_MAX_LNKDWN_TIMEOUT); /* end varargs */ + clp[CFG_LINKDOWN_TMO].a_current = LPFC_MAX_LNKDWN_TIMEOUT; + } + + clp[CFG_LINK_SPEED].a_current = + (uint32)((ulong)fc_get_cfg_param(brd, CFG_LINK_SPEED)); + + p_dev_ctl->ihs.lpfn_mtu = lpfc_mtu; + if((lpfc_mtu % PAGE_SIZE) == 0) + p_dev_ctl->ihs.lpfn_rcv_buf_size = lpfc_mtu; + else { + p_dev_ctl->ihs.lpfn_rcv_buf_size = ((lpfc_mtu + PAGE_SIZE) & (PAGE_MASK)); + p_dev_ctl->ihs.lpfn_rcv_buf_size -= 16; + } + clp[CFG_NUM_NODES].a_current = clp[CFG_NUM_NODES].a_default; + + return(0); +} /* fc_get_dds */ + +/****************************************************************************** +* Function name : fc_bind_wwpn +* +******************************************************************************/ +_local_ int fc_bind_wwpn(fc_dev_ctl_t *p_dev_ctl, + char **arrayp, + u_int cnt) +{ + uchar *datap, *np; + NODELIST *nlp; + nodeh_t *hp; + NAME_TYPE pn; + int i, dev_index, entry, lpfc_num, rstatus; + unsigned int sum; + + FC_BRD_INFO * binfo = &BINFO; + + p_dev_ctl->fcp_mapping = FCP_SEED_WWPN; + np = (uchar *)&pn; + + for(entry = 0; entry < cnt; entry++) { + datap = (uchar *)arrayp[entry]; + if(datap == 0) + break; + /* Determined the number of ASC hex chars in WWNN & WWPN */ + for( i = 0; i < FC_MAX_WW_NN_PN_STRING; i++) { + if( fc_asc_to_hex( datap[i]) < 0) + break; + } + if((rstatus = fc_parse_binding_entry( p_dev_ctl, datap, np, + i, sizeof( NAME_TYPE), + FC_BIND_WW_NN_PN, &sum, entry, &lpfc_num)) > 0) { + if( rstatus == FC_SYNTAX_OK_BUT_NOT_THIS_BRD) + continue; + + /* WWPN binding entry : Syntax error code */ + fc_log_printf_msg_vargs( binfo->fc_brd_no, + &fc_msgBlk0430, /* ptr to msg structure */ + fc_mes0430, /* ptr to msg */ + fc_msgBlk0430.msgPreambleStr, /* begin varargs */ + entry, + rstatus); /* end varargs */ + goto out; + } + + /* Loop through all NODELIST entries and find + * the next available entry. + */ + if((nlp = (NODELIST *)fc_mem_get(binfo, MEM_NLP)) == 0) { + /* WWPN binding entry: node table full */ + fc_log_printf_msg_vargs( binfo->fc_brd_no, + &fc_msgBlk0432, /* ptr to msg structure */ + fc_mes0432, /* ptr to msg */ + fc_msgBlk0432.msgPreambleStr); /* begin & end varargs */ + goto out; + } + fc_bzero((void *)nlp, sizeof(NODELIST)); + nlp->sync = binfo->fc_sync; + nlp->capabilities = binfo->fc_capabilities; + + nlp->nlp_state = NLP_SEED; + nlp->nlp_type = NLP_SEED_WWPN | NLP_FCP_TARGET; + + nlp->id.nlp_sid = DEV_SID(sum); + nlp->id.nlp_pan = DEV_PAN(sum); + bcopy((uchar * )&pn, &nlp->nlp_portname, sizeof(NAME_TYPE)); + + dev_index = INDEX(nlp->id.nlp_pan, nlp->id.nlp_sid); + hp = &binfo->device_queue_hash[dev_index]; + + /* Claim SCSI ID by copying bind parameter to + * proper index in device_queue_hash. + */ + bcopy(&nlp->nlp_portname, &hp->un.dev_portname, sizeof(NAME_TYPE)); + hp->node_flag = FCP_SEED_WWPN; + + fc_nlp_bind(binfo, nlp); + + out: + np = (uchar *)&pn; + } + return (0); +} /* fc_bind_wwpn */ + +/****************************************************************************** +* Function name : fc_bind_wwnn +* +* Description : p_dev_ctl, pointer to the device control area +* +******************************************************************************/ +_local_ int fc_bind_wwnn(fc_dev_ctl_t *p_dev_ctl, + char **arrayp, + u_int cnt) +{ + uchar *datap, *np; + NODELIST *nlp; + nodeh_t *hp; + NAME_TYPE pn; + int i, dev_index, entry, lpfc_num, rstatus; + unsigned int sum; + + FC_BRD_INFO * binfo = &BINFO; + + p_dev_ctl->fcp_mapping = FCP_SEED_WWNN; + np = (uchar *)&pn; + + for(entry = 0; entry < cnt; entry++) { + datap = (uchar *)arrayp[entry]; + if(datap == 0) + break; + /* Determined the number of ASC hex chars in WWNN & WWPN */ + for( i = 0; i < FC_MAX_WW_NN_PN_STRING; i++) { + if( fc_asc_to_hex( datap[i]) < 0) + break; + } + if((rstatus = fc_parse_binding_entry( p_dev_ctl, datap, np, + i, sizeof( NAME_TYPE), + FC_BIND_WW_NN_PN, &sum, entry, &lpfc_num)) > 0) { + if( rstatus == FC_SYNTAX_OK_BUT_NOT_THIS_BRD) + continue; + + /* WWNN binding entry : Syntax error code */ + fc_log_printf_msg_vargs( binfo->fc_brd_no, + &fc_msgBlk0431, /* ptr to msg structure */ + fc_mes0431, /* ptr to msg */ + fc_msgBlk0431.msgPreambleStr, /* begin varargs */ + entry, + rstatus); /* end varargs */ + goto out; + } + + /* Loop through all NODELIST entries and find + * the next available entry. + */ + if((nlp = (NODELIST *)fc_mem_get(binfo, MEM_NLP)) == 0) { + /* WWNN binding entry: node table full */ + fc_log_printf_msg_vargs( binfo->fc_brd_no, + &fc_msgBlk0433, /* ptr to msg structure */ + fc_mes0433, /* ptr to msg */ + fc_msgBlk0433.msgPreambleStr); /* begin & end varargs */ + goto out; + } + fc_bzero((void *)nlp, sizeof(NODELIST)); + nlp->sync = binfo->fc_sync; + nlp->capabilities = binfo->fc_capabilities; + + nlp->nlp_state = NLP_SEED; + nlp->nlp_type = NLP_SEED_WWNN | NLP_FCP_TARGET; + nlp->id.nlp_sid = DEV_SID(sum); + nlp->id.nlp_pan = DEV_PAN(sum); + bcopy((uchar * )&pn, &nlp->nlp_nodename, sizeof(NAME_TYPE)); + + dev_index = INDEX(nlp->id.nlp_pan, nlp->id.nlp_sid); + hp = &binfo->device_queue_hash[dev_index]; + + /* Claim SCSI ID by copying bind parameter to + * proper index in device_queue_hash. + */ + bcopy(&nlp->nlp_nodename, &hp->un.dev_nodename, sizeof(NAME_TYPE)); + hp->node_flag = FCP_SEED_WWNN; + + fc_nlp_bind(binfo, nlp); + + out: + np = (uchar *)&pn; + } /* for loop */ + return (0); +} /* fc_bind_wwnn */ + +/****************************************************************************** +* Function name : fc_bind_did +* +* Description : p_dev_ctl, pointer to the device control area +* +******************************************************************************/ +_local_ int fc_bind_did(fc_dev_ctl_t *p_dev_ctl, + char **arrayp, + u_int cnt) +{ + uchar *datap, *np; + NODELIST *nlp; + nodeh_t *hp; + FC_BRD_INFO *binfo = &BINFO; + D_ID ndid; + int i, dev_index, entry, lpfc_num, rstatus; + unsigned int sum; + + p_dev_ctl->fcp_mapping = FCP_SEED_DID; + ndid.un.word = 0; + np = (uchar *)&ndid.un.word; + + for(entry = 0; entry < cnt; entry++) { + datap = (uchar *)arrayp[entry]; + if(datap == 0) + break; + /* Determined the number of ASC hex chars in DID */ + for( i = 0; i < FC_MAX_DID_STRING; i++) { + if( fc_asc_to_hex( datap[i]) < 0) + break; + } + if((rstatus = fc_parse_binding_entry( p_dev_ctl, datap, np, + i, sizeof(D_ID), + FC_BIND_DID, &sum, entry, &lpfc_num)) > 0) { + if( rstatus == FC_SYNTAX_OK_BUT_NOT_THIS_BRD) + continue; + + /* DID binding entry : Syntax error code */ + fc_log_printf_msg_vargs( binfo->fc_brd_no, + &fc_msgBlk0434, /* ptr to msg structure */ + fc_mes0434, /* ptr to msg */ + fc_msgBlk0434.msgPreambleStr, /* begin varargs */ + entry, + rstatus); /* end varargs */ + goto out; + } + + /* Loop through all NODELIST entries and find + * the next available entry. + */ + if((nlp = (NODELIST *)fc_mem_get(binfo, MEM_NLP)) == 0) { + /* DID binding entry: node table full */ + fc_log_printf_msg_vargs( binfo->fc_brd_no, + &fc_msgBlk0435, /* ptr to msg structure */ + fc_mes0435, /* ptr to msg */ + fc_msgBlk0435.msgPreambleStr); /* begin & end varargs */ + goto out; + } + fc_bzero((void *)nlp, sizeof(NODELIST)); + nlp->sync = binfo->fc_sync; + nlp->capabilities = binfo->fc_capabilities; + + nlp->nlp_state = NLP_SEED; + nlp->nlp_type = NLP_SEED_DID | NLP_FCP_TARGET; + nlp->id.nlp_sid = DEV_SID(sum); + nlp->id.nlp_pan = DEV_PAN(sum); + nlp->nlp_DID = SWAP_DATA(ndid.un.word); + + dev_index = INDEX(nlp->id.nlp_pan, nlp->id.nlp_sid); + hp = &binfo->device_queue_hash[dev_index]; + + /* Claim SCSI ID by copying bind parameter to + * proper index in device_queue_hash. + */ + hp->un.dev_did = nlp->nlp_DID; + hp->node_flag = FCP_SEED_DID; + + fc_nlp_bind(binfo, nlp); + + out: + + np = (uchar *)&ndid.un.word; + } + return (0); +} + +/****************************************************************************** +* Function name : fc_bufmap +* +* Description : Maps in the specified chunk of memory, bp + len, and returns +* the number of mapped segments in the scatter list. Upon return +* phys will point to a list of physical addresses and cnt will +* point to a corresponding list of sizes. Handle will point to a +* dma handle for the I/O, if needed. +* This routine is only called by the IP portion of the driver to +* get a scatter / gather list for a specific IP packet before +* starting the I/O. +******************************************************************************/ +int fc_bufmap(fc_dev_ctl_t *p_dev_ctl, + uchar *bp, + uint32 len, + void **phys, + uint32 *cnt, + void **handle) +{ + MBUF_INFO * buf_info; + MBUF_INFO bufinfo; + + buf_info = &bufinfo; + *handle = 0; + buf_info->phys = (void *)((ulong)INVALID_PHYS); + buf_info->virt = bp; + buf_info->size = len; + buf_info->flags = (FC_MBUF_PHYSONLY | FC_MBUF_DMA); + fc_malloc(p_dev_ctl, buf_info); + + if(is_invalid_phys(buf_info->phys)) + return(0); + + phys[0] = (void *) buf_info->phys; + cnt[0] = (uint32) len; + return(1); +} + +/****************************************************************************** +* Function name : fc_bufunmap +* +* Description : This is called to unmap a piece of memory, mapped by fc_bufmap, +* and to free the asociated DMA handle, if needed. +******************************************************************************/ +void fc_bufunmap(fc_dev_ctl_t *p_dev_ctl, + uchar *addr, + uchar *dmahandle, + uint32 len) +{ + MBUF_INFO * buf_info; + MBUF_INFO bufinfo; + + buf_info = &bufinfo; + buf_info->phys = (uint32 * )addr; + buf_info->flags = (FC_MBUF_PHYSONLY | FC_MBUF_DMA); + buf_info->size = len; + fc_free(p_dev_ctl, buf_info); +} + +/****************************************************************************** +* Function name : lpfc_scsi_selto_timeout +* +* Description : call back function for scsi timeout +******************************************************************************/ +void lpfc_scsi_selto_timeout(fc_dev_ctl_t *p_dev_ctl, + void *l1, + void *l2) +{ + struct buf *bp; + + bp = (struct buf *)l1; + /* Set any necessary flags for buf error */ + if((bp->b_error != EBUSY) && (bp->b_error != EINVAL)) + bp->b_error = EIO; + bp->b_flags |= B_ERROR; + fc_do_iodone(bp); +} + +/****************************************************************************** +* Function name : lpfc_copy_sense +* +* Description : call back function for scsi timeout +******************************************************************************/ +int lpfc_copy_sense(dvi_t * dev_ptr, + struct buf * bp) +{ + struct scsi_cmnd *cmnd; + int sense_cnt; + + cmnd = bp->cmnd; + if (dev_ptr->sense_length > SCSI_SENSE_BUFFERSIZE) { + sense_cnt = SCSI_SENSE_BUFFERSIZE; + } + else { + sense_cnt = dev_ptr->sense_length; + } + /* Copy sense data into SCSI buffer */ + bcopy(dev_ptr->sense, cmnd->sense_buffer, sense_cnt); + dev_ptr->sense_valid = 0; + return(0); +} + +/****************************************************************************** +* Function name : get_cmd_off_txq +* +* Description : +* +******************************************************************************/ +IOCBQ *get_cmd_off_txq(fc_dev_ctl_t *p_dev_ctl, + ushort iotag) +{ + FC_BRD_INFO * binfo = &BINFO; + IOCBQ * iocbq, *save; + RING * rp; + unsigned long iflag; + + iflag = lpfc_q_disable_lock(p_dev_ctl); + rp = &binfo->fc_ring[FC_FCP_RING]; + iocbq = (IOCBQ * )(rp->fc_tx.q_first); + save = 0; + while (iocbq) { + if(iocbq->iocb.ulpIoTag == iotag) { + if(save) + save->q = iocbq->q; + else + rp->fc_tx.q_first = (uchar *)iocbq->q; + + if(rp->fc_tx.q_last == (uchar *)iocbq) + rp->fc_tx.q_last = (uchar *)save; + + rp->fc_tx.q_cnt--; + lpfc_q_unlock_enable(p_dev_ctl, iflag); + return iocbq; + } + save = iocbq; + iocbq = (IOCBQ * )iocbq->q; + } + + lpfc_q_unlock_enable(p_dev_ctl, iflag); + return 0; +} + +/****************************************************************************** +* Function name : find_cmd_in_txpq +* +* Description : +* +******************************************************************************/ +int find_cmd_in_txpq(fc_dev_ctl_t *p_dev_ctl, + struct scsi_cmnd *cmnd) +{ + FC_BRD_INFO * binfo = &BINFO; + struct fc_buf *fcptr, *savefc; + dvi_t * dev_ptr; + IOCBQ *iocb_cmd, *iocb_cn_cmd; + struct buf *bp; + RING * rp; + struct sc_buf *sp; + int abort_stat; + unsigned long iflag; + + iflag = lpfc_q_disable_lock(p_dev_ctl); + rp = &binfo->fc_ring[FC_FCP_RING]; + fcptr = (struct fc_buf *)(rp->fc_txp.q_first); + savefc = 0; + while (fcptr) { + if(((struct buf *)(fcptr->sc_bufp))->cmnd == cmnd) { + dev_ptr = fcptr->dev_ptr; + lpfc_q_unlock_enable(p_dev_ctl, iflag); + iocb_cmd = get_cmd_off_txq(p_dev_ctl, fcptr->iotag); + iflag = lpfc_q_disable_lock(p_dev_ctl); + if (iocb_cmd) { + fc_mem_put(binfo, MEM_IOCB, (uchar * )iocb_cmd); + + lpfc_q_unlock_enable(p_dev_ctl, iflag); + while ((iocb_cn_cmd = get_cmd_off_txq(p_dev_ctl, fcptr->iotag))) { + fc_mem_put(binfo, MEM_IOCB, (uchar * )iocb_cn_cmd); + } + iflag = lpfc_q_disable_lock(p_dev_ctl); + + bp = (struct buf *)fcptr->sc_bufp; + bp->b_error = ETIMEDOUT; + bp->b_flags |= B_ERROR; + lpfc_q_unlock_enable(p_dev_ctl, iflag); + fc_do_iodone(bp); + iflag = lpfc_q_disable_lock(p_dev_ctl); + + if(savefc) { + savefc->fc_fwd = fcptr->fc_fwd; + if (fcptr->fc_fwd) + fcptr->fc_fwd->fc_bkwd = savefc; + } else { + rp->fc_txp.q_first = (uchar *)(fcptr->fc_fwd); + if (fcptr->fc_fwd) + fcptr->fc_fwd->fc_bkwd = 0; + } + + if(rp->fc_txp.q_last == (uchar *)fcptr) { + rp->fc_txp.q_last = (uchar *)savefc; + } + + rp->fc_txp.q_cnt--; + lpfc_q_unlock_enable(p_dev_ctl, iflag); + fc_enq_fcbuf(fcptr); + iflag = lpfc_q_disable_lock(p_dev_ctl); + dev_ptr->active_io_count--; + if (dev_ptr->nodep) + dev_ptr->nodep->num_active_io--; + else + panic ("abort in txp: dev_ptr->nodep is NULL\n"); + } else { + sp = (struct sc_buf *)(fcptr->sc_bufp); + sp->cmd_flag |= FLAG_ABORT; + lpfc_q_unlock_enable(p_dev_ctl, iflag); + abort_stat = fc_abort_xri(binfo, fcptr->dev_ptr, + fcptr->iotag, ABORT_TYPE_ABTS); + iflag = lpfc_q_disable_lock(p_dev_ctl); + } + lpfc_q_unlock_enable(p_dev_ctl, iflag); + return 1; + } else { + savefc = fcptr; + fcptr = (struct fc_buf *)fcptr->fc_fwd; + } + } + lpfc_q_unlock_enable(p_dev_ctl, iflag); + return 0; +} + +/****************************************************************************** +* Function name : find_cmd_in_tmolist +* +* Description : +* +******************************************************************************/ +int find_cmd_in_tmolist(fc_dev_ctl_t *p_dev_ctl, + struct scsi_cmnd *cmnd) +{ + struct buf *bp, *savebp; + + savebp = 0; + for (bp = p_dev_ctl->timeout_head; bp != NULL; ) { + if (bp->cmnd == cmnd) { + if(savebp) + savebp->av_forw = bp->av_forw; + else + p_dev_ctl->timeout_head = bp->av_forw; + + p_dev_ctl->timeout_count--; + bp->b_error = ETIMEDOUT; + bp->b_flags |= B_ERROR; + fc_do_iodone(bp); + return 1; + } else { + savebp = bp; + bp = bp->av_forw; + } + } + + return 0; +} + +/****************************************************************************** +* Function name : find_cmd_in_pendlist +* +* Description : +* +******************************************************************************/ +int find_cmd_in_pendlist(dvi_t *dev_ptr, + struct scsi_cmnd *cmnd) +{ + struct buf *bp, *savebp; + node_t * nodep; + + bp = (struct buf *)dev_ptr->pend_head; + savebp = 0; + while (bp) { + if (bp->cmnd == cmnd) { + nodep = dev_ptr->nodep; + if(savebp) + savebp->av_forw = bp->av_forw; + else + dev_ptr->pend_head = (struct sc_buf *)(bp->av_forw); + + if (dev_ptr->pend_tail == (struct sc_buf *)bp) + dev_ptr->pend_tail = (struct sc_buf *)savebp; + + dev_ptr->pend_count--; + bp->b_error = ETIMEDOUT; + bp->b_flags |= B_ERROR; + fc_do_iodone(bp); + return 1; + } else { + savebp = bp; + bp = bp->av_forw; + } + } + + return 0; +} + +/****************************************************************************** +* Function name : lpfc_find_cmd +* +* Description : +* +******************************************************************************/ +_local_ int lpfc_find_cmd(fc_dev_ctl_t *p_dev_ctl, + struct scsi_cmnd *cmnd) +{ + dvi_t * dev_ptr; + struct sc_buf * sp; + + sp = (struct sc_buf *)cmnd->host_scribble; + if(sp == 0) + return 1; + dev_ptr = sp->current_devp; + if(dev_ptr) { + if (find_cmd_in_pendlist(dev_ptr, cmnd)) + goto err1; + } + + if (find_cmd_in_txpq(p_dev_ctl, cmnd)) + goto err1; + if (find_cmd_in_tmolist(p_dev_ctl, cmnd)) + goto err1; + + return 0; + +err1: + return 1; +} + +/****************************************************************************** +* Function name : lpfc_nodev +* +* Description : +* +******************************************************************************/ +void lpfc_nodev(unsigned long l) +{ + return; +} + +/****************************************************************************** +* Function name : lpfc_scsi_add_timer +* +* Description : Copied from scsi_add_timer +******************************************************************************/ +void lpfc_scsi_add_timer(struct scsi_cmnd * SCset, + int timeout) +{ + + if( SCset->eh_timeout.function != NULL ) + { + del_timer(&SCset->eh_timeout); + } + + if(SCset->eh_timeout.data != (unsigned long) SCset) { + SCset->eh_timeout.data = (unsigned long) SCset; + SCset->eh_timeout.function = (void (*)(unsigned long))lpfc_nodev; + } + SCset->eh_timeout.expires = jiffies + timeout; + + add_timer(&SCset->eh_timeout); +} + +/****************************************************************************** +* Function name : lpfc_scsi_delete_timer() +* +* Purpose: Delete/cancel timer for a given function. +* Copied from scsi_delete_timer() +* +* Arguments: SCset - command that we are canceling timer for. +* +* Returns: Amount of time remaining before command would have timed out. +******************************************************************************/ +int lpfc_scsi_delete_timer(struct scsi_cmnd * SCset) +{ + int rtn; + + rtn = jiffies - SCset->eh_timeout.expires; + del_timer(&SCset->eh_timeout); + SCset->eh_timeout.data = (unsigned long) NULL; + SCset->eh_timeout.function = NULL; + return rtn; +} + +/****************************************************************************** +* Function name : fc_device_changed +* +* Description : +* +******************************************************************************/ +int fc_device_changed(fc_dev_ctl_t *p_dev_ctl, + struct dev_info *dev_ptr) +{ + struct scsi_device *sd; + + if(lpfc_use_removable) { + sd = (struct scsi_device *)dev_ptr->scsi_dev; + if(sd) { +#if LINUX_VERSION_CODE >= LinuxVersionCode(2,4,0) + sd->changed = 0; + sd->removable = 0; +#else + sd->online = 1; +#endif + } + } + return(0); +} +/****************************************************************************** +* Function name : fc_bcopy +* +* Description : +* +******************************************************************************/ +void fc_bcopy(void *from, + void *to, + ulong cnt) +{ + bcopy(from, to, cnt); +} + +/****************************************************************************** +* Function name : fc_bzero +* +* Description : +* +******************************************************************************/ +void fc_bzero(void *from, + ulong cnt) +{ + memset(from,0,(size_t)cnt); +} + +/****************************************************************************** +* Function name : fc_copyout +* +* Description : +* +******************************************************************************/ +int fc_copyout(uchar *from, + uchar *to, + ulong cnt) +{ + return(copyout(from, to, cnt)); +} + +/****************************************************************************** +* Function name : fc_copyin +* +* Description : +* +******************************************************************************/ +int fc_copyin(uchar *from, + uchar *to, + ulong cnt) +{ + return(copyin(from, to, cnt)); +} + +/****************************************************************************** +* Function name : lpfc_mpdata_sync +* +* Description : +* +******************************************************************************/ +void lpfc_mpdata_sync(fc_dev_ctl_t *p_dev_ctl, + void *h, + int a, + int b, + int c) +{ +#if LINUX_VERSION_CODE >= LinuxVersionCode(2,4,0) + if(c == 1) + c = PCI_DMA_FROMDEVICE; + else + c = PCI_DMA_TODEVICE; + if(b) + fc_pci_dma_sync_single(p_dev_ctl->pcidev, (dma_addr_t)((ulong)h), b, c); + else + fc_pci_dma_sync_single(p_dev_ctl->pcidev, (dma_addr_t)((ulong)h), 4096, c); +#endif +} + +/****************************************************************************** +* Function name : lpfc_ip_rcvsz +* +* Description : +* +******************************************************************************/ +int lpfc_ip_rcvsz(fc_dev_ctl_t *p_dev_ctl) +{ + return(p_dev_ctl->ihs.lpfn_rcv_buf_size); +} + +/****************************************************************************** +* Function name : fc_dpc_lstchk +* +* Description : Since abort, device reset, bus reset, and host reset dpc lists +* all use SCp.ptr for linking, double check to make sure +* LINUX doesn't use the same Cmnd for multiple resets / aborts. +* +* XXX patman check that this still works +******************************************************************************/ +int fc_dpc_lstchk(fc_dev_ctl_t * p_dev_ctl, + struct scsi_cmnd * Cmnd) +{ + struct scsi_cmnd * aCmnd; + struct scsi_cmnd * bCmnd; + + aCmnd = (struct scsi_cmnd *)p_dev_ctl->abort_head; + bCmnd = 0; + while(aCmnd) { + /* Check for duplicate on abort list */ + if(aCmnd == Cmnd) { + if(bCmnd == 0) { + p_dev_ctl->abort_head = (void *)SCMD_NEXT(Cmnd); + } + else { + SCMD_NEXT(bCmnd) = SCMD_NEXT(Cmnd); + } + if(Cmnd == (struct scsi_cmnd *)p_dev_ctl->abort_list) + p_dev_ctl->abort_list = (void *)bCmnd; + SCMD_NEXT(Cmnd) = 0; + return(1); + } + bCmnd = aCmnd; + aCmnd = SCMD_NEXT(aCmnd); + } + aCmnd = (struct scsi_cmnd *)p_dev_ctl->rdev_head; + bCmnd = 0; + while(aCmnd) { + /* Check for duplicate on device reset list */ + if(aCmnd == Cmnd) { + if(bCmnd == 0) { + p_dev_ctl->rdev_head = (void *)SCMD_NEXT(Cmnd); + } + else { + SCMD_NEXT(bCmnd) = SCMD_NEXT(Cmnd); + } + if(Cmnd == (struct scsi_cmnd *)p_dev_ctl->rdev_list) + p_dev_ctl->rdev_list = (void *)bCmnd; + SCMD_NEXT(Cmnd) = 0; + return(2); + } + bCmnd = aCmnd; + aCmnd = SCMD_NEXT(aCmnd); + } + aCmnd = (struct scsi_cmnd *)p_dev_ctl->rbus_head; + bCmnd = 0; + while(aCmnd) { + /* Check for duplicate on bus reset list */ + if(aCmnd == Cmnd) { + if(bCmnd == 0) { + p_dev_ctl->rbus_head = (void *)SCMD_NEXT(Cmnd); + } + else { + SCMD_NEXT(bCmnd) = SCMD_NEXT(Cmnd); + } + if(Cmnd == (struct scsi_cmnd *)p_dev_ctl->rbus_list) + p_dev_ctl->rbus_list = (void *)bCmnd; + SCMD_NEXT(Cmnd) = 0; + return(3); + } + bCmnd = aCmnd; + aCmnd = SCMD_NEXT(aCmnd); + } + aCmnd = (struct scsi_cmnd *)p_dev_ctl->rhst_head; + bCmnd = 0; + while(aCmnd) { + /* Check for duplicate on host reset list */ + if(aCmnd == Cmnd) { + if(bCmnd == 0) { + p_dev_ctl->rhst_head = (void *)SCMD_NEXT(Cmnd); + } + else { + SCMD_NEXT(bCmnd) = SCMD_NEXT(Cmnd); + } + if(Cmnd == (struct scsi_cmnd *)p_dev_ctl->rhst_list) + p_dev_ctl->rhst_list = (void *)bCmnd; + SCMD_NEXT(Cmnd) = 0; + return(4); + } + bCmnd = aCmnd; + aCmnd = SCMD_NEXT(aCmnd); + } + return(0); +} + +/****************************************************************************** +* Function name : fc_timer +* +* Description : This function will be called by the driver every second. +******************************************************************************/ +_static_ void lpfc_timer(void *p) +{ + fc_dev_ctl_t * p_dev_ctl; + FCCLOCK_INFO * clock_info; + ulong tix; + FCCLOCK * x; + int ipri; + + clock_info = &DD_CTL.fc_clock_info; + ipri = disable_lock(CLK_LVL, &CLOCK_LOCK); + + /* + *** Increment time_sample value + */ + clock_info->ticks++; + + x = clock_info->fc_clkhdr.cl_f; + + /* counter for propagating negative values */ + tix = 0; + /* If there are expired clocks */ + if (x != (FCCLOCK * ) & clock_info->fc_clkhdr) { + x->cl_tix = x->cl_tix - 1; + if (x->cl_tix <= 0) { + /* Loop thru all clock blocks */ + while (x != (FCCLOCK * ) & clock_info->fc_clkhdr) { + x->cl_tix += tix; + /* If # of ticks left > 0, break out of loop */ + if (x->cl_tix > 0) + break; + tix = x->cl_tix; + + fc_deque(x); + /* Decrement count of unexpired clocks */ + clock_info->fc_clkhdr.count--; + + unlock_enable(ipri, &CLOCK_LOCK); + + p_dev_ctl = x->cl_p_dev_ctl; + + if(p_dev_ctl) { + /* Queue clock blk to appropriate dpc to be processed */ + if(p_dev_ctl->qclk_head == NULL) { + p_dev_ctl->qclk_head = (void *)x; + p_dev_ctl->qclk_list = (void *)x; + } else { + ((FCCLOCK *)(p_dev_ctl->qclk_list))->cl_fw = x; + p_dev_ctl->qclk_list = (void *)x; + } + x->cl_fw = NULL; + } + else { + /* Call timeout routine */ + (*x->cl_func) (p_dev_ctl, x->cl_arg1, x->cl_arg2); + /* Release clock block */ + fc_clkrelb(p_dev_ctl, x); + } + + ipri = disable_lock(CLK_LVL, &CLOCK_LOCK); + + x = clock_info->fc_clkhdr.cl_f; + } + } + } + unlock_enable(ipri, &CLOCK_LOCK); + fc_reset_timer(); +} + +/****************************************************************************** +* Function name : do_fc_timer +* +* Description : +* +******************************************************************************/ +int do_fc_timer(fc_dev_ctl_t *p_dev_ctl) +{ + FCCLOCK *x; + FCCLOCK *cb; + + cb = (FCCLOCK *)p_dev_ctl->qclk_head; + while(cb) { + x = cb; + cb = cb->cl_fw; + /* Call timeout routine */ + (*x->cl_func) (p_dev_ctl, x->cl_arg1, x->cl_arg2); + /* Release clock block */ + fc_clkrelb(p_dev_ctl, x); + } + p_dev_ctl->qclk_head = 0; + p_dev_ctl->qclk_list = 0; + return(0); +} + +/****************************************************************************** +* Function name : lpfc_kmalloc +* +* Description : +* +******************************************************************************/ +void * lpfc_kmalloc(unsigned int size, + unsigned int type, + void **pphys, + fc_dev_ctl_t *p_dev_ctl) +{ + FC_BRD_INFO * binfo; + void * pcidev; + void * virt; + struct fc_mem_pool * fmp; + dma_addr_t phys; + int i, instance; + +/* printk("lpfc_kmalloc: %d %d %lx %lx\n", size, type, pphys, p_dev_ctl); +*/ + if(pphys == 0) { + virt = (void *)kmalloc(size, type); + return(virt); + } + if(p_dev_ctl == 0) { + /* lpfc_kmalloc: Bad p_dev_ctl */ + fc_log_printf_msg_vargs( 0, /* force brd 0, no p_dev_ctl */ + &fc_msgBlk1201, /* ptr to msg structure */ + fc_mes1201, /* ptr to msg */ + fc_msgBlk1201.msgPreambleStr, /* begin varargs */ + size, + type, + fc_idx_dmapool[0]); /* end varargs */ + return(0); + } + instance = p_dev_ctl->info.fc_brd_no; + pcidev = p_dev_ctl->pcidev; + binfo = &BINFO; + + if(size > FC_MAX_SEGSZ) { + /* lpfc_kmalloc: Bad size */ + fc_log_printf_msg_vargs( binfo->fc_brd_no, + &fc_msgBlk1202, /* ptr to msg structure */ + fc_mes1202, /* ptr to msg */ + fc_msgBlk1202.msgPreambleStr, /* begin varargs */ + size, + type, + fc_idx_dmapool[instance]); /* end varargs */ + return(0); + } +top: + fmp = fc_mem_dmapool[instance]; + for(i=0;i<=fc_idx_dmapool[instance];i++) { + fmp = (fc_mem_dmapool[instance] + i); + if((fmp->p_virt == 0) || (fmp->p_left >= size)) + break; + } + if(i == (fc_size_dmapool[instance] - 2)) { + /* Lets make it bigger */ + fc_size_dmapool[instance] += FC_MAX_POOL; + fmp = kmalloc((sizeof(struct fc_mem_pool) * fc_size_dmapool[instance]), + GFP_ATOMIC); + if(fmp) { + fc_bzero((void *)fmp, + (sizeof(struct fc_mem_pool) * fc_size_dmapool[instance])); + fc_bcopy((void *)fc_mem_dmapool[instance], fmp, + (sizeof(struct fc_mem_pool) * (fc_size_dmapool[instance]-FC_MAX_POOL))); + kfree(fc_mem_dmapool[instance]); + fc_mem_dmapool[instance] = fmp; + goto top; + } + goto out; + } + + if(fmp->p_virt == 0) { + virt = pci_alloc_consistent(pcidev, FC_MAX_SEGSZ, &phys); + if(virt) { + fmp->p_phys = (void *)((ulong)phys); + fmp->p_virt = virt; + fmp->p_refcnt = 0; + fmp->p_left = (ushort)FC_MAX_SEGSZ; + if(i == fc_idx_dmapool[instance]) + if(i < (fc_size_dmapool[instance] - 2)) + fc_idx_dmapool[instance]++; + } + else { + /* lpfc_kmalloc: Bad virtual addr */ + fc_log_printf_msg_vargs( binfo->fc_brd_no, + &fc_msgBlk1204, /* ptr to msg structure */ + fc_mes1204, /* ptr to msg */ + fc_msgBlk1204.msgPreambleStr, /* begin varargs */ + i, + size, + type, + fc_idx_dmapool[instance]); /* end varargs */ + return(0); + } + } + + if(fmp->p_left >= size) { + fmp->p_refcnt++; + virt = (void *)((uchar *)fmp->p_virt + FC_MAX_SEGSZ - fmp->p_left); + phys = (dma_addr_t)(ulong)((uchar *)fmp->p_phys + FC_MAX_SEGSZ - fmp->p_left); + *pphys = (void *)((ulong)phys); + fmp->p_left -= size; + return(virt); + } +out: + /* lpfc_kmalloc: dmapool FULL */ + fc_log_printf_msg_vargs( binfo->fc_brd_no, + &fc_msgBlk1205, /* ptr to msg structure */ + fc_mes1205, /* ptr to msg */ + fc_msgBlk1205.msgPreambleStr, /* begin varargs */ + i, + size, + type, + fc_idx_dmapool[instance]); /* end varargs */ + return(0); +} + +/****************************************************************************** +* Function name : lpfc_kfree +* +* Description : +* +******************************************************************************/ +void lpfc_kfree(unsigned int size, + void *virt, + void *phys, + fc_dev_ctl_t *p_dev_ctl) +{ + FC_BRD_INFO * binfo; + struct fc_mem_pool * fmp; + void * pcidev; + int i, instance; + + if(is_invalid_phys(phys)) { + kfree(virt); + return; + } + + if(p_dev_ctl == 0) { + /* lpfc_kfree: Bad p_dev_ctl */ + fc_log_printf_msg_vargs( 0, /* force brd 0, no p_dev_ctl */ + &fc_msgBlk1206, /* ptr to msg structure */ + fc_mes1206, /* ptr to msg */ + fc_msgBlk1206.msgPreambleStr, /* begin varargs */ + size, + fc_idx_dmapool[0]); /* end varargs */ + return; + } + + instance = p_dev_ctl->info.fc_brd_no; + pcidev = p_dev_ctl->pcidev; + binfo = &BINFO; + + + for(i=0;i= fmp->p_virt) && + (virt < (void *)((uchar *)fmp->p_virt + FC_MAX_SEGSZ))) { + fmp->p_refcnt--; + if(fmp->p_refcnt == 0) { + pci_free_consistent(pcidev, FC_MAX_SEGSZ, + fmp->p_virt, (dma_addr_t)((ulong)fmp->p_phys)); + fc_bzero((void *)fmp, sizeof(struct fc_mem_pool)); + } + return; + } + } + /* lpfc_kfree: NOT in dmapool */ + fc_log_printf_msg_vargs( binfo->fc_brd_no, + &fc_msgBlk1207, /* ptr to msg structure */ + fc_mes1207, /* ptr to msg */ + fc_msgBlk1207.msgPreambleStr, /* begin varargs */ + (uint32)((ulong)virt), + size, + fc_idx_dmapool[instance]); /* end varargs */ + return; +} /* lpfc_kfree */ + +MODULE_LICENSE("GPL"); diff -purN -X /home/mbligh/.diff.exclude 350-autoswap/drivers/scsi/lpfc/fcLINUXlan.c 370-emulex/drivers/scsi/lpfc/fcLINUXlan.c --- 350-autoswap/drivers/scsi/lpfc/fcLINUXlan.c 1969-12-31 16:00:00.000000000 -0800 +++ 370-emulex/drivers/scsi/lpfc/fcLINUXlan.c 2004-02-28 11:20:03.000000000 -0800 @@ -0,0 +1,376 @@ +/******************************************************************* + * This file is part of the Emulex Linux Device Driver for * + * Enterprise Fibre Channel Host Bus Adapters. * + * Refer to the README file included with this package for * + * driver version and adapter support. * + * Copyright (C) 2003 Emulex Corporation. * + * www.emulex.com * + * * + * This program is free software; you can redistribute it and/or * + * modify it under the terms of the GNU General Public License * + * as published by the Free Software Foundation; either version 2 * + * of the License, or (at your option) any later version. * + * * + * This program is distributed in the hope that it will be useful, * + * but WITHOUT ANY WARRANTY; without even the implied warranty of * + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * + * GNU General Public License for more details, a copy of which * + * can be found in the file COPYING included with this package. * + *******************************************************************/ + +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#if LINUX_VERSION_CODE >= KERNEL_VERSION(2,4,4) +#include +#else +#include +#endif +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#define LinuxVersionCode(v, p, s) (((v)<<16)+((p)<<8)+(s)) +#if LINUX_VERSION_CODE >= LinuxVersionCode(2,3,17) +#include +#else +#include +#endif +#include +#include +#include + +#ifdef MODULE +#include +#include "lpfc.ver" +#else +extern int lpfn_probe(void); +#endif /* MODULE */ + +/* fcLINUXlan.c IP interface network driver */ +#include "fc_os.h" +#include "fc_hw.h" +#include "fc.h" + +static int lpfn_xmit(struct sk_buff *skb, NETDEVICE *dev); +static struct enet_statistics *lpfn_get_stats(NETDEVICE *dev); + +extern int arp_find(unsigned char *haddr, struct sk_buff *skb); +extern int lpfc_xmit(fc_dev_ctl_t *p_dev_ctl, struct sk_buff *skb); +extern int lpfc_ioctl(int cmd, void *s); + +/****************************************************************************** +* Function name : lpfn_open +* +* Description : +* +******************************************************************************/ +static int lpfn_open(NETDEVICE *dev) +{ + fc_dev_ctl_t *p_dev_ctl; + FC_BRD_INFO * binfo; + + if((p_dev_ctl = (fc_dev_ctl_t *)(dev->priv)) == 0) + return(-ENODEV); + binfo = &BINFO; + p_dev_ctl->device_state = OPENED; + binfo->fc_open_count |= FC_LAN_OPEN; + + netdevice_start(dev); + netif_start_queue(dev); +#ifdef MODULE + MOD_INC_USE_COUNT; +#endif /* MODULE */ + return 0; +} + +/****************************************************************************** +* Function name : lpfn_close +* +* Description : +* +******************************************************************************/ +static int lpfn_close(NETDEVICE *dev) +{ + fc_dev_ctl_t *p_dev_ctl; + FC_BRD_INFO * binfo; + + if((p_dev_ctl = (fc_dev_ctl_t *)(dev->priv)) == 0) + return(-ENODEV); + binfo = &BINFO; + p_dev_ctl->device_state = 0; + binfo->fc_open_count &= ~FC_LAN_OPEN; + + netdevice_stop(dev); + netif_stop_queue(dev); +#ifdef MODULE + MOD_DEC_USE_COUNT; +#endif /* MODULE */ + return 0; +} + +/****************************************************************************** +* Function name : lpfn_change_mtu +* +* Description : +* +******************************************************************************/ +int lpfn_change_mtu(NETDEVICE *dev, + int new_mtu) +{ + fc_dev_ctl_t *p_dev_ctl; + + if((p_dev_ctl = (fc_dev_ctl_t *)(dev->priv)) == 0) + return(-ENODEV); + if ((new_mtu < FC_MIN_MTU) || (new_mtu > p_dev_ctl->ihs.lpfn_mtu)) + return -EINVAL; + dev->mtu = new_mtu; + return(0); +} + + +/****************************************************************************** +* Function name : lpfn_header +* +* Description : Create the FC MAC/LLC/SNAP header for an arbitrary protocol +* layer +* saddr=NULL means use device source address +* daddr=NULL means leave destination address (eg unresolved arp) +* +******************************************************************************/ +int lpfn_header(struct sk_buff *skb, + NETDEVICE *dev, + unsigned short type, + void *daddr, + void *saddr, + unsigned len) +{ + struct fc_nethdr *fchdr; + int rc; + + if (type == ETH_P_IP || type == ETH_P_ARP) { + fchdr = (struct fc_nethdr *)skb_push(skb, sizeof(struct fc_nethdr)); + + fchdr->llc.dsap = FC_LLC_DSAP; /* DSAP */ + fchdr->llc.ssap = FC_LLC_SSAP; /* SSAP */ + fchdr->llc.ctrl = FC_LLC_CTRL; /* control field */ + fchdr->llc.prot_id[0] = 0; /* protocol id */ + fchdr->llc.prot_id[1] = 0; /* protocol id */ + fchdr->llc.prot_id[2] = 0; /* protocol id */ + fchdr->llc.type = htons(type); /* type field */ + rc = sizeof(struct fc_nethdr); + } + else { +printk("lpfn_header:Not IP or ARP: %x\n",type); + + fchdr = (struct fc_nethdr *)skb_push(skb, sizeof(struct fc_nethdr)); + rc = sizeof(struct fc_nethdr); + } + + /* Set the source and destination hardware addresses */ + if (saddr != NULL) + memcpy(fchdr->fcnet.fc_srcname.IEEE, saddr, dev->addr_len); + else + memcpy(fchdr->fcnet.fc_srcname.IEEE, dev->dev_addr, dev->addr_len); + + fchdr->fcnet.fc_srcname.nameType = NAME_IEEE; /* IEEE name */ + fchdr->fcnet.fc_srcname.IEEEextMsn = 0; + fchdr->fcnet.fc_srcname.IEEEextLsb = 0; + + + if (daddr != NULL) + { + memcpy(fchdr->fcnet.fc_destname.IEEE, daddr, dev->addr_len); + fchdr->fcnet.fc_destname.nameType = NAME_IEEE; /* IEEE name */ + fchdr->fcnet.fc_destname.IEEEextMsn = 0; + fchdr->fcnet.fc_destname.IEEEextLsb = 0; + return(rc); + } + + return(-rc); +} + +/****************************************************************************** +* Function name : lpfn_rebuild_header +* +* Description : Rebuild the FC MAC/LLC/SNAP header. +* This is called after an ARP (or in future other address +* resolution) has completed on this sk_buff. +* We now let ARP fill in the other fields. +******************************************************************************/ +int lpfn_rebuild_header(struct sk_buff *skb) +{ + struct fc_nethdr *fchdr = (struct fc_nethdr *)skb->data; + NETDEVICE *dev = skb->dev; + + if (fchdr->llc.type == htons(ETH_P_IP)) { + return arp_find(fchdr->fcnet.fc_destname.IEEE, skb); + } + + printk("%s: unable to resolve type %X addresses.\n", + dev->name, (int)fchdr->llc.type); + + memcpy(fchdr->fcnet.fc_srcname.IEEE, dev->dev_addr, dev->addr_len); + fchdr->fcnet.fc_srcname.nameType = NAME_IEEE; /* IEEE name */ + fchdr->fcnet.fc_srcname.IEEEextMsn = 0; + fchdr->fcnet.fc_srcname.IEEEextLsb = 0; + + return 0; +} + +/****************************************************************************** +* Function name : lpfn_xmit +* +* Description : +* +******************************************************************************/ +static int lpfn_xmit(struct sk_buff *skb, + NETDEVICE *dev) +{ + fc_dev_ctl_t *p_dev_ctl; + int rc; + + + p_dev_ctl = (fc_dev_ctl_t *)dev->priv; + rc=lpfc_xmit(p_dev_ctl, skb); + return rc; +} + +/****************************************************************************** +* Function name : lpfn_receive +* +* Description : +* +******************************************************************************/ +_static_ void lpfn_receive(ndd_t *p_ndd, + struct sk_buff *skb, + void *p) +{ + fc_dev_ctl_t *p_dev_ctl; + NETDEVICE *dev; + struct fc_nethdr *fchdr = (struct fc_nethdr *)skb->data; + struct ethhdr *eth; + unsigned short *sp; + + p_dev_ctl = (fc_dev_ctl_t *)p; + dev = p_dev_ctl->ihs.lpfn_dev; + skb->dev = dev; + + skb->mac.raw=fchdr->fcnet.fc_destname.IEEE; + sp = (unsigned short *)fchdr->fcnet.fc_srcname.IEEE; + *(sp - 1) = *sp; + sp++; + *(sp - 1) = *sp; + sp++; + *(sp - 1) = *sp; + + skb_pull(skb, dev->hard_header_len); + eth= skb->mac.ethernet; + + if(*eth->h_dest&1) { + if(memcmp(eth->h_dest,dev->broadcast, ETH_ALEN)==0) + skb->pkt_type=PACKET_BROADCAST; + else + skb->pkt_type=PACKET_MULTICAST; + } + + else if(dev->flags&(IFF_PROMISC)) { + if(memcmp(eth->h_dest,dev->dev_addr, ETH_ALEN)) + skb->pkt_type=PACKET_OTHERHOST; + } + + skb->protocol = fchdr->llc.type; + + if (skb->protocol == ntohs(ETH_P_ARP)) + skb->data[1] = 0x06; + + + netif_rx(skb); +} + +/****************************************************************************** +* Function name : lpfn_get_stats +* +* Description : +* +******************************************************************************/ +static struct enet_statistics *lpfn_get_stats(NETDEVICE *dev) +{ + fc_dev_ctl_t *p_dev_ctl; + struct enet_statistics *stats; + + p_dev_ctl = (fc_dev_ctl_t *)dev->priv; + stats = &NDDSTAT.ndd_enet; + return stats; +} + +#ifdef MODULE +/****************************************************************************** +* Function name : init_module +* +* Description : +* +******************************************************************************/ +int init_module(void) +#else +/****************************************************************************** +* Function name : lpfn_probe +* +* Description : +* +******************************************************************************/ +int lpfn_probe(void) +#endif /* MODULE */ +{ + struct lpfn_probe lp; + + lp.hard_start_xmit = &lpfn_xmit; + lp.receive = &lpfn_receive; + lp.get_stats = &lpfn_get_stats; + lp.open = &lpfn_open; + lp.stop = &lpfn_close; + lp.hard_header = &lpfn_header; + lp.rebuild_header = &lpfn_rebuild_header; + lp.change_mtu = &lpfn_change_mtu; + if(lpfc_ioctl(LPFN_PROBE,(void *)&lp) == 0) + return -ENODEV; + + return 0; +} + +#ifdef MODULE +/****************************************************************************** +* Function name : cleanup_module +* +* Description : +* +******************************************************************************/ +void cleanup_module(void) +{ + lpfc_ioctl(LPFN_DETACH,0); +} +MODULE_LICENSE("GPL"); +#endif /* MODULE */ diff -purN -X /home/mbligh/.diff.exclude 350-autoswap/drivers/scsi/lpfc/fc_crtn.h 370-emulex/drivers/scsi/lpfc/fc_crtn.h --- 350-autoswap/drivers/scsi/lpfc/fc_crtn.h 1969-12-31 16:00:00.000000000 -0800 +++ 370-emulex/drivers/scsi/lpfc/fc_crtn.h 2004-02-28 11:20:03.000000000 -0800 @@ -0,0 +1,254 @@ +/******************************************************************* + * This file is part of the Emulex Linux Device Driver for * + * Enterprise Fibre Channel Host Bus Adapters. * + * Refer to the README file included with this package for * + * driver version and adapter support. * + * Copyright (C) 2003 Emulex Corporation. * + * www.emulex.com * + * * + * This program is free software; you can redistribute it and/or * + * modify it under the terms of the GNU General Public License * + * as published by the Free Software Foundation; either version 2 * + * of the License, or (at your option) any later version. * + * * + * This program is distributed in the hope that it will be useful, * + * but WITHOUT ANY WARRANTY; without even the implied warranty of * + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * + * GNU General Public License for more details, a copy of which * + * can be found in the file COPYING included with this package. * + *******************************************************************/ + +/* Module fcxmitb.c External Routine Declarations */ +_forward_ int fc_create_xri(FC_BRD_INFO *binfo, RING *rp, NODELIST *nlp); +_forward_ void fc_restartio(fc_dev_ctl_t *p_dev_ctl, NODELIST *nlp); +_forward_ IOCBQ *fc_ringtx_drain(RING *rp); +_forward_ IOCBQ *fc_ringtx_get(RING *rp); +_forward_ void fc_ringtx_put(RING *rp, IOCBQ *iocbq); +_forward_ IOCBQ *fc_ringtxp_get(RING *rp, ushort iotag); +_forward_ void fc_ringtxp_put(RING *rp, IOCBQ *iocbq); +_forward_ int fc_xmit(fc_dev_ctl_t *p_dev_ctl, fcipbuf_t *p_mbuf); +_forward_ int handle_create_xri(fc_dev_ctl_t *p_dev_ctl, RING *rp,IOCBQ *tmp); +_forward_ int handle_xmit_cmpl(fc_dev_ctl_t *p_dev_ctl, RING *rp, IOCBQ *tmp); + + + +/* Module fcelsb.c External Routine Declarations */ +_forward_ int fc_chkpadisc(FC_BRD_INFO *binfo, NODELIST *nlp, + volatile NAME_TYPE *nn, volatile NAME_TYPE *pn); +_forward_ int fc_els_cmd(FC_BRD_INFO *binfo, uint32 type, void *arg, + uint32 class, ushort iotag, NODELIST *nlp); +_forward_ int fc_els_rsp(FC_BRD_INFO *binfo, uint32 type, uint32 Xri, + uint32 class, void *iocbp, uint32 flag, NODELIST *nlp); +_forward_ void fc_snd_flogi(fc_dev_ctl_t *p_dev_ctl, void *a1, void *a2); +_forward_ int fc_initial_flogi(fc_dev_ctl_t * p_dev_ctl); +_forward_ int handle_els_event(fc_dev_ctl_t *p_dev_ctl, RING *rp, IOCBQ *temp); +_forward_ int handle_rcv_els_req(fc_dev_ctl_t *p_dev_ctl, RING *rp, IOCBQ *temp); +_forward_ int fc_process_rscn(fc_dev_ctl_t *p_dev_ctl, IOCBQ *temp, MATCHMAP *mp); +_forward_ int fc_handle_rscn(fc_dev_ctl_t *p_dev_ctl, D_ID *didp); +_forward_ int fc_issue_ct_req(FC_BRD_INFO *binfo, uint32 portid, MATCHMAP *bmp, DMATCHMAP *inmp, DMATCHMAP *outmp, uint32 tmo); +_forward_ int fc_gen_req(FC_BRD_INFO *binfo, MATCHMAP *bmp, MATCHMAP *inmp, MATCHMAP *outmp, uint32 rpi, uint32 flag, uint32 cnt, uint32 tmo); +_forward_ int fc_issue_ct_rsp(FC_BRD_INFO *binfo, uint32 tag, MATCHMAP *bmp, DMATCHMAP *inp); +_forward_ int fc_rnid_req(FC_BRD_INFO *binfo, DMATCHMAP *inp, DMATCHMAP *outp, + MATCHMAP **bmp, uint32 rpi); +_forward_ void fc_issue_ns_query(fc_dev_ctl_t *p, void *a1, void *a2); +_forward_ int fc_flush_rscn_defer(fc_dev_ctl_t *p_dev_ctl); +_forward_ int fc_abort_discovery( fc_dev_ctl_t *p_dev_ctl); +/* FDMI */ +_forward_ int fc_fdmi_cmd(fc_dev_ctl_t *p_dev_ctl, NODELIST *ndlp, int cmdcode); +_forward_ void fc_fdmi_rsp(fc_dev_ctl_t *p_dev_ctl, MATCHMAP *mp, MATCHMAP *rsp_mp); +_forward_ void fc_plogi_put(FC_BRD_INFO *binfo, IOCBQ *iocbq); +_forward_ IOCBQ * fc_plogi_get(FC_BRD_INFO *binfo); + + + +/* Module fcmboxb.c External Routine Declarations */ +_forward_ void fc_clear_la(FC_BRD_INFO *binfo, MAILBOX *mb); +_forward_ void fc_read_status(FC_BRD_INFO *binfo, MAILBOX *mb); +_forward_ void fc_read_lnk_stat(FC_BRD_INFO *binfo, MAILBOX *mb); +_forward_ void fc_config_link(fc_dev_ctl_t *p_dev_ctl, MAILBOX *mb); +_forward_ int fc_config_port(FC_BRD_INFO *binfo, MAILBOX *mb, uint32 *hbainit); +_forward_ void fc_config_ring(FC_BRD_INFO *binfo, int ring, int profile, + MAILBOX *mb); +_forward_ void fc_init_link(FC_BRD_INFO *binfo, MAILBOX *mb, + uint32 topology, uint32 linkspeed); +_forward_ MAILBOXQ *fc_mbox_get(FC_BRD_INFO *binfo); +_forward_ int fc_read_la(fc_dev_ctl_t *p_dev_ctl, MAILBOX *mb); +_forward_ void fc_mbox_put(FC_BRD_INFO *binfo, MAILBOXQ *mbq); +_forward_ void fc_read_rev(FC_BRD_INFO *binfo, MAILBOX *mb); +_forward_ int fc_read_rpi(FC_BRD_INFO *binfo, uint32 rpi,MAILBOX *mb,uint32 flg); +_forward_ int fc_read_sparam(fc_dev_ctl_t *p_dev_ctl, MAILBOX *mb); +_forward_ int fc_reg_login(FC_BRD_INFO *binfo, uint32 did, uchar *param, + MAILBOX *mb, uint32 flag); +_forward_ void fc_set_slim(FC_BRD_INFO *binfo, MAILBOX *mb, uint32 addr, + uint32 value); +_forward_ void fc_unreg_login(FC_BRD_INFO *binfo, uint32 rpi, MAILBOX *mb); +_forward_ void fc_unreg_did(FC_BRD_INFO *binfo, uint32 did, MAILBOX *mb); +_forward_ void fc_dump_mem(FC_BRD_INFO *binfo, MAILBOX *mb); + +_forward_ void fc_config_farp(FC_BRD_INFO *binfo, MAILBOX *mb); +_forward_ void fc_read_config(FC_BRD_INFO *binfo, MAILBOX *mb); + +/* Module fcmemb.c External Routine Declarations */ +_forward_ void fc_disable_tc(FC_BRD_INFO *binfo, MAILBOX *mb); +_forward_ MATCHMAP *fc_getvaddr(fc_dev_ctl_t *p_dev_ctl, RING *rp, uchar *mapbp); +_forward_ uchar *fc_mem_get(FC_BRD_INFO *binfo, uint32 seg); +_forward_ uchar *fc_mem_put(FC_BRD_INFO *binfo, uint32 seg, uchar *bp); +_forward_ int fc_free_buffer(fc_dev_ctl_t *p_dev_ctl); +_forward_ int fc_malloc_buffer(fc_dev_ctl_t *p_dev_ctl); +_forward_ void fc_mapvaddr(FC_BRD_INFO *binfo, RING *rp, MATCHMAP *mp, + uint32 *haddr, uint32 *laddr); +_forward_ int fc_runBIUdiag(FC_BRD_INFO *binfo, MAILBOX *mb, uchar *in, + uchar *out); + + +/* Module fcclockb.c External Routine Declarations */ +_forward_ void fc_clkrelb(fc_dev_ctl_t *p_dev_ctl, FCCLOCK *cb); +_forward_ int fc_clk_can(fc_dev_ctl_t *p_dev_ctl, FCCLOCK *cb); +_forward_ FCCLOCK *fc_clk_set(fc_dev_ctl_t *p_dev_ctl, ulong tix, + void (*func)(fc_dev_ctl_t*, void*, void*), void *arg1, void *arg2); +_forward_ ulong fc_clk_res(fc_dev_ctl_t *p_dev_ctl, ulong tix, FCCLOCK *cb); +_forward_ void fc_timer(void *); +_forward_ void fc_clock_deque(FCCLOCK *cb); +_forward_ void fc_clock_init(void); +_forward_ void fc_flush_clk_set(fc_dev_ctl_t *p_dev_ctl, + void (*func)(fc_dev_ctl_t*, void*, void*)); +_forward_ int fc_abort_clk_blk(fc_dev_ctl_t *p_dev_ctl, + void (*func)(fc_dev_ctl_t*, void*, void*), void *a1, void *a2); +_forward_ int fc_abort_delay_els_cmd( fc_dev_ctl_t *p_dev_ctl, uint32 did); +_forward_ void fc_q_depth_up(fc_dev_ctl_t *p_dev_ctl, void *, void *); +_forward_ void fc_establish_link_tmo(fc_dev_ctl_t *p_dev_ctl, void *, void *); +/* QFULL_RETRY */ +_forward_ void fc_qfull_retry(void *); +_forward_ void fc_reset_timer(void); + +/* Module fcrpib.c External Routine Declarations */ +_forward_ int fc_discovery(fc_dev_ctl_t *p_dev_ctl); +_forward_ ushort fc_emac_lookup(FC_BRD_INFO *binfo, uchar *addr, + NODELIST **nlpp); +_forward_ int fc_fanovery(fc_dev_ctl_t *p_dev_ctl); +_forward_ NODELIST *fc_findnode_rpi(FC_BRD_INFO *binfo, uint32 rpi); +_forward_ int fc_free_rpilist(fc_dev_ctl_t *p_dev_ctl, int keeprpi); +_forward_ void fc_freebufq(fc_dev_ctl_t *p_dev_ctl, RING *rp, IOCBQ *xmitiq); +_forward_ int fc_freenode(FC_BRD_INFO *binfo, NODELIST *nlp, int rm); +_forward_ int fc_freenode_did(FC_BRD_INFO *binfo, uint32 did, int rm); +_forward_ int fc_nlpadjust(FC_BRD_INFO *binfo); +_forward_ int fc_rpi_abortxri(FC_BRD_INFO *binfo, ushort xri); +_forward_ int fc_nlp_bind(FC_BRD_INFO *binfo, NODELIST *nlp); +_forward_ int fc_nlp_unmap(FC_BRD_INFO *binfo, NODELIST *nlp); +_forward_ int fc_nlp_map(FC_BRD_INFO *binfo, NODELIST *nlp); +_forward_ NODELIST *fc_findnode_odid(FC_BRD_INFO *binfo, uint32 order, uint32 did); +_forward_ NODELIST *fc_findnode_scsid(FC_BRD_INFO *binfo, uint32 order, uint32 scid); +_forward_ NODELIST *fc_findnode_wwpn(FC_BRD_INFO *binfo, uint32 odr, NAME_TYPE *wwp); +_forward_ NODELIST *fc_findnode_wwnn(FC_BRD_INFO *binfo, uint32 odr, NAME_TYPE *wwn); +_forward_ NODELIST *fc_findnode_oxri(FC_BRD_INFO *binfo, uint32 order, uint32 xri); +_forward_ int fc_nlp_logi(FC_BRD_INFO *binfo, NODELIST *nlp, NAME_TYPE *wwpnp, + NAME_TYPE *wwnnp); +_forward_ int fc_nlp_swapinfo(FC_BRD_INFO *binfo, NODELIST *onlp, NODELIST *nnlp); + + +/* Module fcstratb.c External Routine Declarations */ +_forward_ dvi_t *fc_fcp_abort(fc_dev_ctl_t *p, int flg, int tgt, int lun); +_forward_ int fc_assign_scsid(fc_dev_ctl_t *ap, NODELIST *nlp); +_forward_ fc_buf_t *fc_deq_fcbuf_active(RING *rp, ushort iotag); +_forward_ fc_buf_t *fc_deq_fcbuf(dvi_t *di); +_forward_ void fc_enq_abort_bdr(dvi_t *dev_ptr); +_forward_ void fc_enq_fcbuf(fc_buf_t *fcptr); +_forward_ void fc_enq_fcbuf_active(RING *rp, fc_buf_t *fcptr); +_forward_ int issue_fcp_cmd(fc_dev_ctl_t *p_dev_ctl, dvi_t *dev_ptr, + T_SCSIBUF *sbp, int pend); +_forward_ void fc_enq_wait(dvi_t *dev_ptr); +_forward_ void fc_fail_cmd(dvi_t *dev_ptr, char error, uint32 statistic); +_forward_ void fc_fail_pendq(dvi_t *dev_ptr, char error, uint32 statistic); +_forward_ int fc_failio(fc_dev_ctl_t * p_dev_ctl); +_forward_ dvi_t *fc_find_lun( FC_BRD_INFO * binfo, int hash_index, fc_lun_t lun); +_forward_ void fc_issue_cmd(fc_dev_ctl_t *ap); +_forward_ int fc_reset_dev_q_depth( fc_dev_ctl_t * p_dev_ctl); +_forward_ int fc_restart_all_devices(fc_dev_ctl_t * p_dev_ctl); +_forward_ int fc_restart_device(dvi_t * dev_ptr); +_forward_ void fc_return_standby_queue(dvi_t *dev_ptr, uchar status, + uint32 statistic); +_forward_ void re_issue_fcp_cmd(dvi_t *dev_ptr); +_forward_ void fc_polling(FC_BRD_INFO *binfo, uint32 att_bit); +_forward_ void fc_fcp_fix_txq(fc_dev_ctl_t *p_dev_ctl); + + + +/* Module fcscsib.c External Routine Declarations */ +_forward_ int fc_abort_fcp_txpq(FC_BRD_INFO *binfo, dvi_t *dev_ptr); +_forward_ int fc_abort_xri(FC_BRD_INFO *binfo, dvi_t *dev_ptr, ushort iotag, int flag); +_forward_ int fc_abort_ixri_cx(FC_BRD_INFO *binfo, ushort xri, uint32 cmd, RING *rp); +_forward_ int fc_attach(int index, uint32 *p_uio); +_forward_ int fc_cfg_init(fc_dev_ctl_t *p_dev_ctl); +_forward_ void fc_cfg_remove(fc_dev_ctl_t *p_dev_ctl); +_forward_ void fc_cmdring_timeout(fc_dev_ctl_t *p, void *a1, void *a2); +_forward_ int fc_delay_iodone(fc_dev_ctl_t *p_dev_ctl, + T_SCSIBUF * sbp); +_forward_ void fc_delay_timeout(fc_dev_ctl_t *p, void *l1, void *l2); +_forward_ void fc_nodev_timeout(fc_dev_ctl_t *p, void *l1, void *l2); +_forward_ int fc_detach(int index); +_forward_ void fc_ffcleanup(fc_dev_ctl_t *p_dev_ctl); +_forward_ void fc_free_clearq(dvi_t *dev_ptr); +_forward_ int fc_geportname(NAME_TYPE *pn1, NAME_TYPE *pn2); +_forward_ int fc_linkdown(fc_dev_ctl_t *p_dev_ctl); +_forward_ void fc_linkdown_timeout(fc_dev_ctl_t *p, void *a1, void *a2); +_forward_ void fc_mbox_timeout(fc_dev_ctl_t *p, void *a1, void *a2); +_forward_ void fc_fabric_timeout(fc_dev_ctl_t *p, void *a1, void *a2); +_forward_ int fc_nextauth(fc_dev_ctl_t *p_dev_ctl, int sndcnt); +_forward_ int fc_nextdisc(fc_dev_ctl_t *p_dev_ctl, int sndcnt); +_forward_ int fc_nextnode(fc_dev_ctl_t *p_dev_ctl, NODELIST *nlp); +_forward_ int fc_nextrscn(fc_dev_ctl_t *p_dev_ctl, int sndcnt); +_forward_ int fc_free_ct_rsp(fc_dev_ctl_t *p_dev_ctl, MATCHMAP *mlist); +_forward_ int fc_ns_cmd(fc_dev_ctl_t *p_dev_ctl, NODELIST *nlp, int cc); +_forward_ int fc_ns_rsp(fc_dev_ctl_t *p_dev_ctl, NODELIST *nslp, MATCHMAP *mp, uint32 sz); +_forward_ int fc_ct_cmd(fc_dev_ctl_t *p_dev_ctl, MATCHMAP *mp, + MATCHMAP *bmp, NODELIST *nlp); +_forward_ int fc_offline(fc_dev_ctl_t *p_dev_ctl); +_forward_ int fc_online(fc_dev_ctl_t *p_dev_ctl); +_forward_ void fc_pcimem_bcopy(uint32 *src, uint32 *dest, uint32 cnt); +_forward_ int fc_post_buffer(fc_dev_ctl_t *p_dev_ctl, RING *rp, int cnt); +_forward_ int fc_post_mbuf(fc_dev_ctl_t *p_dev_ctl, RING *rp, int cnt); +_forward_ int fc_rlip(fc_dev_ctl_t *p_dev_ctl); +_forward_ void fc_scsi_timeout(fc_dev_ctl_t *p, void *l1, void *l2); +_forward_ void fc_start(fc_dev_ctl_t *p_dev_ctl); +_forward_ void handle_fcp_event(fc_dev_ctl_t *p_dev_ctl, RING *rp,IOCBQ *temp); +_forward_ int handle_mb_cmd(fc_dev_ctl_t *p_dev_ctl, MAILBOX *mb, uint32 cmd); +_forward_ int fc_free_iocb_buf(fc_dev_ctl_t *p_dev_ctl, RING *rp, IOCBQ *tmp); +_forward_ int handle_iprcv_seq(fc_dev_ctl_t *p_dev_ctl, RING *rp, IOCBQ *temp); +_forward_ int handle_elsrcv_seq(fc_dev_ctl_t *p_dev_ctl, RING *rp, IOCBQ *temp); +_forward_ void fc_process_reglogin(fc_dev_ctl_t *p_dev_ctl, NODELIST *nlp); +_forward_ int fc_snd_scsi_req(fc_dev_ctl_t *p_dev_ctl, NAME_TYPE *wwn, + MATCHMAP *bmp, DMATCHMAP *fcpmp, DMATCHMAP *omatp, + uint32 cnt, struct dev_info *devp); +_forward_ void issue_report_lun(fc_dev_ctl_t *p_dev_ctl, void *l1, void *l2); +_forward_ int fc_parse_binding_entry( fc_dev_ctl_t *p_dev_ctl, uchar *inbuf, + uchar *outbuf, int in_size, int out_size, int bind_type, + unsigned int *sum, int entry, int *lpfc_num); + +/* + * External Routine Declarations for local print statement formatting + */ + +_forward_ int fc_asc_seq_to_hex( fc_dev_ctl_t *p_dev_ctl, + int input_bc, int output_bc, char *inp, char *outp); +_forward_ int fc_asc_to_hex( uchar c); +_forward_ int fc_is_digit( int chr); +_forward_ int fc_log_printf_msg_vargs( + int brdno, msgLogDef *msg, + void *control, ...); +_forward_ int fc_check_this_log_msg_disabled( + int brdno, msgLogDef *msg, int *log_only); + +_forward_ void fc_brdreset(fc_dev_ctl_t *p_dev_ctl); +_forward_ int fc_ffinit(fc_dev_ctl_t *p_dev_ctl); +_forward_ int issue_mb_cmd(FC_BRD_INFO *binfo, MAILBOX *mb, int flag); +_forward_ uint32 issue_iocb_cmd(FC_BRD_INFO *binfo, RING *rp, IOCBQ *iocb_cmd); +_forward_ char *decode_firmware_rev(FC_BRD_INFO *binfo, fc_vpd_t *vp); +_forward_ int dfc_fmw_rev( fc_dev_ctl_t * p_dev_ctl); +_forward_ int dfc_hba_put_event( fc_dev_ctl_t * p_dev_ctl, uint32 evcode, + uint32 evdata1, uint32 evdata2, uint32 evdata3, uint32 evdata4); +_forward_ int dfc_put_event( fc_dev_ctl_t * p_dev_ctl, uint32 evcode, + uint32 evdata0, void *evdata1, void *evdata2); +_forward_ void handle_ff_error(fc_dev_ctl_t *p_dev_ctl); +_forward_ int handle_mb_event(fc_dev_ctl_t *p_dev_ctl); +_forward_ void handle_link_event(fc_dev_ctl_t *p_dev_ctl); +_forward_ void handle_ring_event(fc_dev_ctl_t *p_dev_ctl, int ring,uint32 reg); diff -purN -X /home/mbligh/.diff.exclude 350-autoswap/drivers/scsi/lpfc/fc_ertn.h 370-emulex/drivers/scsi/lpfc/fc_ertn.h --- 350-autoswap/drivers/scsi/lpfc/fc_ertn.h 1969-12-31 16:00:00.000000000 -0800 +++ 370-emulex/drivers/scsi/lpfc/fc_ertn.h 2004-02-28 11:20:03.000000000 -0800 @@ -0,0 +1,89 @@ +/******************************************************************* + * This file is part of the Emulex Linux Device Driver for * + * Enterprise Fibre Channel Host Bus Adapters. * + * Refer to the README file included with this package for * + * driver version and adapter support. * + * Copyright (C) 2003 Emulex Corporation. * + * www.emulex.com * + * * + * This program is free software; you can redistribute it and/or * + * modify it under the terms of the GNU General Public License * + * as published by the Free Software Foundation; either version 2 * + * of the License, or (at your option) any later version. * + * * + * This program is distributed in the hope that it will be useful, * + * but WITHOUT ANY WARRANTY; without even the implied warranty of * + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * + * GNU General Public License for more details, a copy of which * + * can be found in the file COPYING included with this package. * + *******************************************************************/ + +/* + * Begin Global Function Definitions + */ +_forward_ void fc_bcopy(void *src, void *dest, unsigned long n); +_forward_ void fc_bzero(void *src, unsigned long size ); +_forward_ int fc_copyin(uchar *src, uchar *dst, unsigned long); +_forward_ int fc_copyout(uchar *, uchar *, unsigned long); +_forward_ void lpfc_mpdata_sync(fc_dev_ctl_t *p_dev_ctl, void *h, int a, int b, int c); +_forward_ void *fc_kmem_alloc(unsigned int size); +_forward_ void fc_kmem_free(void *obj, unsigned int size); +_forward_ void curtime(uint32 *time); +_forward_ ulong dfc_disable_lock(ulong p1, Simple_lock *p2); +_forward_ void dfc_unlock_enable(ulong p1, Simple_lock *p2); +_forward_ ulong lpfc_q_disable_lock(fc_dev_ctl_t *p_dev_ctl); +_forward_ void lpfc_q_unlock_enable(fc_dev_ctl_t *p_dev_ctl, ulong p1); +_forward_ ulong lpfc_mempool_disable_lock(fc_dev_ctl_t *p_dev_ctl); +_forward_ void lpfc_mempool_unlock_enable(fc_dev_ctl_t *p_dev_ctl, ulong p1); +_forward_ int dfc_sleep(fc_dev_ctl_t *p_dev_ctl, fcEvent_header *ep); +_forward_ int dfc_wakeup(fc_dev_ctl_t *p_dev_ctl, fcEvent_header *ep); +_forward_ int lpfc_DELAYMS(fc_dev_ctl_t *p_dev_ctl, int cnt); +_forward_ int fc_fcp_bufunmap(fc_dev_ctl_t *pdev, struct sc_buf *sp); +_forward_ int fc_bufmap(fc_dev_ctl_t *p_dev_ctl, uchar *bp, uint32 len, + void **phys, uint32 *cnt, void **handle); +_forward_ void fc_bufunmap(fc_dev_ctl_t *p_dev_ctl, uchar *addr, + uchar *dmahandle, uint32 size); +_forward_ int fc_fcp_bufmap(fc_dev_ctl_t *p_dev_ctl, struct sc_buf *sbp, + fc_buf_t *fcptr, IOCBQ *temp, ULP_BDE64 *bpl, + dvi_t * dev_ptr, int pend); +_forward_ void fc_free(fc_dev_ctl_t *p_dev_ctl, MBUF_INFO *buf_info); +_forward_ int fc_get_dds(fc_dev_ctl_t *p_dev_ctl, uint32 *p_uio); +_forward_ int fc_get_dds_bind(fc_dev_ctl_t *p_dev_ctl); +_forward_ int fc_get_dds(fc_dev_ctl_t *p_dev_ctl, uint32 *p_uio); +_forward_ void lpfc_scsi_selto_timeout(fc_dev_ctl_t *p, void *l1, void *l2); +_forward_ int lpfc_copy_sense(dvi_t * dev_ptr, struct buf * bp); +_forward_ int fc_intr(struct intr *p_ihs); +_forward_ int fc_pcimap(fc_dev_ctl_t *p_dev_ctl); +_forward_ ushort fc_rdpci_cmd( fc_dev_ctl_t *p_dev_ctl); +_forward_ uint32 fc_rdpci_32( fc_dev_ctl_t *p_dev_ctl, uint32 offset); +_forward_ int fc_initpci(struct dfc_info *di, fc_dev_ctl_t *p_dev_ctl); +_forward_ int fc_readpci(struct dfc_info *di, uint32 offset, char *buf, uint32 cnt); +_forward_ int fc_writepci(struct dfc_info *di, uint32 offset, char *buf, uint32 cnt); +_forward_ uchar *fc_malloc(fc_dev_ctl_t *p_dev_ctl, MBUF_INFO *buf_info); +_forward_ int fc_memmap(fc_dev_ctl_t *p_dev_ctl); +_forward_ int fc_unmemmap(fc_dev_ctl_t *p_dev_ctl); +_forward_ int lpfc_cfg_init(fc_dev_ctl_t *p_dev_ctl); +_forward_ void fc_wrpci_cmd( fc_dev_ctl_t *p_dev_ctl, ushort cfg_value); +_forward_ int i_clear(struct intr *ihs); +_forward_ int i_init(struct intr *ihs); +_forward_ void lpfc_fcp_error( fc_buf_t * fcptr, IOCB * cmd); +_forward_ dvi_t *fc_alloc_devp(fc_dev_ctl_t *, int target, fc_lun_t lun); +_forward_ int fc_do_iodone( struct buf *bp); +_forward_ int fc_device_changed(fc_dev_ctl_t *p, struct dev_info *dp); +_forward_ int log_printf(int f, int type, int num, char *str, int brdno, + uint32 a1, uint32 a2, uint32 a3, uint32 a4); +_forward_ int log_printf_msgblk( int brdno, msgLogDef * msg, char *str, int log_only); + + +_forward_ uint32 timeout(void (*func)(ulong), struct timer_list * , uint32 ); +_forward_ int lpfc_ip_rcvsz(fc_dev_ctl_t *p_dev_ctl); +_forward_ int lpfc_kfree_skb(struct sk_buff *skb); +_forward_ struct sk_buff * lpfc_alloc_skb(unsigned int sz); +_forward_ void fc_pci_dma_sync_single(struct pci_dev *hwdev, dma_addr_t h, + size_t size, int c); +_forward_ void fc_write_toio(uint32 *src, uint32 *dest_io, uint32 cnt); +_forward_ void fc_read_fromio(uint32 *src_io, uint32 *dest, uint32 cnt); +_forward_ uint32 fc_readl(uint32 *src); +_forward_ void fc_writel(uint32 *src, uint32 value); +_forward_ int fc_print( char * str, void * arg1, void * arg2); + diff -purN -X /home/mbligh/.diff.exclude 350-autoswap/drivers/scsi/lpfc/fc_hw.h 370-emulex/drivers/scsi/lpfc/fc_hw.h --- 350-autoswap/drivers/scsi/lpfc/fc_hw.h 1969-12-31 16:00:00.000000000 -0800 +++ 370-emulex/drivers/scsi/lpfc/fc_hw.h 2004-02-28 11:20:03.000000000 -0800 @@ -0,0 +1,3073 @@ +/******************************************************************* + * This file is part of the Emulex Linux Device Driver for * + * Enterprise Fibre Channel Host Bus Adapters. * + * Refer to the README file included with this package for * + * driver version and adapter support. * + * Copyright (C) 2003 Emulex Corporation. * + * www.emulex.com * + * * + * This program is free software; you can redistribute it and/or * + * modify it under the terms of the GNU General Public License * + * as published by the Free Software Foundation; either version 2 * + * of the License, or (at your option) any later version. * + * * + * This program is distributed in the hope that it will be useful, * + * but WITHOUT ANY WARRANTY; without even the implied warranty of * + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * + * GNU General Public License for more details, a copy of which * + * can be found in the file COPYING included with this package. * + *******************************************************************/ + +#ifndef _H_FC_HW +#define _H_FC_HW + +typedef unsigned u32bit; +typedef unsigned u16bit; +typedef unsigned u8bit; + +#define FC_MAX_TRANSFER 0x40000 /* Maximum transfer size per operation */ + +#define MAX_CONFIGURED_RINGS 4 /* # rings currently used */ + +#define IOCB_CMD_R0_ENTRIES 5 /* ELS command ring entries */ +#define IOCB_RSP_R0_ENTRIES 5 /* ELS response ring entries */ +#define IOCB_CMD_R1_ENTRIES 27 /* IP command ring entries */ +#define IOCB_RSP_R1_ENTRIES 28 /* IP response ring entries */ +#define IOCB_CMD_R2_ENTRIES 45 /* FCP command ring entries */ +#define IOCB_RSP_R2_ENTRIES 10 /* FCP response ring entries */ +#define MAX_BIOCB 120 /* max# of BIU IOCBs in shared memory */ + +#define SLI2_IOCB_CMD_R0_ENTRIES 6 /* SLI-2 ELS command ring entries */ +#define SLI2_IOCB_RSP_R0_ENTRIES 6 /* SLI-2 ELS response ring entries */ +#define SLI2_IOCB_CMD_R1_ENTRIES 24 /* SLI-2 IP command ring entries */ +#define SLI2_IOCB_RSP_R1_ENTRIES 30 /* SLI-2 IP response ring entries */ +#define SLI2_IOCB_CMD_R1XTRA_ENTRIES 18 /* SLI-2 extra FCP cmd ring entries */ +#define SLI2_IOCB_RSP_R1XTRA_ENTRIES 24 /* SLI-2 extra FCP rsp ring entries */ +#define SLI2_IOCB_CMD_R2_ENTRIES 30 /* SLI-2 FCP command ring entries */ +#define SLI2_IOCB_RSP_R2_ENTRIES 20 /* SLI-2 FCP response ring entries */ +#define SLI2_IOCB_CMD_R2XTRA_ENTRIES 22 /* SLI-2 extra FCP cmd ring entries */ +#define SLI2_IOCB_RSP_R2XTRA_ENTRIES 20 /* SLI-2 extra FCP rsp ring entries */ +#define SLI2_IOCB_CMD_R3_ENTRIES 0 /* SLI-2 FCP command ring entries */ +#define SLI2_IOCB_RSP_R3_ENTRIES 0 /* SLI-2 FCP response ring entries */ +#define MAX_SLI2_IOCB SLI2_IOCB_CMD_R0_ENTRIES + \ + SLI2_IOCB_RSP_R0_ENTRIES + \ + SLI2_IOCB_CMD_R1_ENTRIES + \ + SLI2_IOCB_RSP_R1_ENTRIES + \ + SLI2_IOCB_CMD_R2_ENTRIES + \ + SLI2_IOCB_RSP_R2_ENTRIES + \ + SLI2_IOCB_CMD_R3_ENTRIES + \ + SLI2_IOCB_RSP_R3_ENTRIES + +#define FCELSSIZE 1024 /* maximum ELS transfer size */ + +#define FC_MAXRETRY 3 /* max retries for ELS commands */ +#define FC_ELS_RING 0 /* use ring 0 for ELS commands */ +#define FC_IP_RING 1 /* use ring 1 for IP commands */ +#define FC_FCP_RING 2 /* use ring 2 for FCP initiator commands */ + +#define FF_DEF_EDTOV 2000 /* Default E_D_TOV (2000ms) */ +#define FF_DEF_ALTOV 15 /* Default AL_TIME (15ms) */ +#define FF_DEF_RATOV 2 /* Default RA_TOV (2s) */ +#define FF_DEF_ARBTOV 1900 /* Default ARB_TOV (1900ms) */ +#define MB_WAIT_PERIOD 500 /* Wait period in usec inbetween MB polls */ +#define MAX_MB_COMPLETION 1000 /* # MB_WAIT_PERIODs to wait for MB cmplt */ +#define MAX_MSG_DATA 28 /* max msg data in CMD_ADAPTER_MSG iocb */ + +#define FF_REG_AREA_SIZE 256 /* size, in bytes, of i/o register area */ +#define FF_SLIM_SIZE 4096 /* size, in bytes, of SLIM */ + +/* + * Miscellaneous stuff.... + */ +/* HBA Mgmt */ +#define FDMI_DID ((uint32)0xfffffa) +#define NameServer_DID ((uint32)0xfffffc) +#define SCR_DID ((uint32)0xfffffd) +#define Fabric_DID ((uint32)0xfffffe) +#define Bcast_DID ((uint32)0xffffff) +#define Mask_DID ((uint32)0xffffff) +#define CT_DID_MASK ((uint32)0xffff00) +#define Fabric_DID_MASK ((uint32)0xfff000) + +#define PT2PT_LocalID ((uint32)1) +#define PT2PT_RemoteID ((uint32)2) + +#define OWN_CHIP 1 /* IOCB / Mailbox is owned by Hba */ +#define OWN_HOST 0 /* IOCB / Mailbox is owned by Host */ +#define END_OF_CHAIN 0 +#define IOCB_WORD_SZ 8 /* # of words in ULP BIU XCB */ +#define MAX_RINGS 3 /* Max # of supported rings */ + +/* defines for type field in fc header */ +#define FC_ELS_DATA 0x1 +#define FC_LLC_SNAP 0x5 +#define FC_FCP_DATA 0x8 +#define FC_COMMON_TRANSPORT_ULP 0x20 + +/* defines for rctl field in fc header */ +#define FC_DEV_DATA 0x0 +#define FC_UNSOL_CTL 0x2 +#define FC_SOL_CTL 0x3 +#define FC_UNSOL_DATA 0x4 +#define FC_FCP_CMND 0x6 +#define FC_ELS_REQ 0x22 +#define FC_ELS_RSP 0x23 +#define FC_NET_HDR 0x20 /* network headers for Dfctl field */ + +/* + * Common Transport structures and definitions + * + */ + +union CtRevisionId { + /* Structure is in Big Endian format */ + struct { + u32bit Revision: 8; + u32bit InId: 24; + } bits; + uint32 word; +}; + +union CtCommandResponse { + /* Structure is in Big Endian format */ + struct { + u32bit CmdRsp: 16; + u32bit Size: 16; + } bits; + uint32 word; +}; + +typedef struct SliCtRequest { + /* Structure is in Big Endian format */ + union CtRevisionId RevisionId; + uchar FsType; + uchar FsSubType; + uchar Options; + uchar Rsrvd1; + union CtCommandResponse CommandResponse; + uchar Rsrvd2; + uchar ReasonCode; + uchar Explanation; + uchar VendorUnique; + + union { + uint32 PortID; + struct gid { + uchar PortType; /* for GID_PT requests */ + uchar DomainScope; + uchar AreaScope; + uchar Fc4Type; /* for GID_FT requests */ + } gid; + struct rft { + uint32 PortId; /* For RFT_ID requests */ +#if BIG_ENDIAN_HW + u32bit rsvd0: 16; + u32bit rsvd1: 7; + u32bit fcpReg: 1; /* Type 8 */ + u32bit rsvd2: 2; + u32bit ipReg: 1; /* Type 5 */ + u32bit rsvd3: 5; +#endif +#if LITTLE_ENDIAN_HW + u32bit rsvd0: 16; + u32bit fcpReg: 1; /* Type 8 */ + u32bit rsvd1: 7; + u32bit rsvd3: 5; + u32bit ipReg: 1; /* Type 5 */ + u32bit rsvd2: 2; +#endif + uint32 rsvd[7]; + } rft; + } un; +} SLI_CT_REQUEST, *PSLI_CT_REQUEST; + +#define SLI_CT_REVISION 1 +#define GID_REQUEST_SZ (sizeof(SLI_CT_REQUEST) - 32) +#define RFT_REQUEST_SZ (sizeof(SLI_CT_REQUEST)) + + +/* + * FsType Definitions + */ + +#define SLI_CT_MANAGEMENT_SERVICE 0xFA +#define SLI_CT_TIME_SERVICE 0xFB +#define SLI_CT_DIRECTORY_SERVICE 0xFC +#define SLI_CT_FABRIC_CONTROLLER_SERVICE 0xFD + +/* + * Directory Service Subtypes + */ + +#define SLI_CT_DIRECTORY_NAME_SERVER 0x02 + +/* + * Response Codes + */ + +#define SLI_CT_RESPONSE_FS_RJT 0x8001 +#define SLI_CT_RESPONSE_FS_ACC 0x8002 + +/* + * Reason Codes + */ + +#define SLI_CT_NO_ADDITIONAL_EXPL 0x0 +#define SLI_CT_INVALID_COMMAND 0x01 +#define SLI_CT_INVALID_VERSION 0x02 +#define SLI_CT_LOGICAL_ERROR 0x03 +#define SLI_CT_INVALID_IU_SIZE 0x04 +#define SLI_CT_LOGICAL_BUSY 0x05 +#define SLI_CT_PROTOCOL_ERROR 0x07 +#define SLI_CT_UNABLE_TO_PERFORM_REQ 0x09 +#define SLI_CT_REQ_NOT_SUPPORTED 0x0b +#define SLI_CT_HBA_INFO_NOT_REGISTERED 0x10 +#define SLI_CT_MULTIPLE_HBA_ATTR_OF_SAME_TYPE 0x11 +#define SLI_CT_INVALID_HBA_ATTR_BLOCK_LEN 0x12 +#define SLI_CT_HBA_ATTR_NOT_PRESENT 0x13 +#define SLI_CT_PORT_INFO_NOT_REGISTERED 0x20 +#define SLI_CT_MULTIPLE_PORT_ATTR_OF_SAME_TYPE 0x21 +#define SLI_CT_INVALID_PORT_ATTR_BLOCK_LEN 0x22 +#define SLI_CT_VENDOR_UNIQUE 0xff + +/* + * Name Server SLI_CT_UNABLE_TO_PERFORM_REQ Explanations + */ + +#define SLI_CT_NO_PORT_ID 0x01 +#define SLI_CT_NO_PORT_NAME 0x02 +#define SLI_CT_NO_NODE_NAME 0x03 +#define SLI_CT_NO_CLASS_OF_SERVICE 0x04 +#define SLI_CT_NO_IP_ADDRESS 0x05 +#define SLI_CT_NO_IPA 0x06 +#define SLI_CT_NO_FC4_TYPES 0x07 +#define SLI_CT_NO_SYMBOLIC_PORT_NAME 0x08 +#define SLI_CT_NO_SYMBOLIC_NODE_NAME 0x09 +#define SLI_CT_NO_PORT_TYPE 0x0A +#define SLI_CT_ACCESS_DENIED 0x10 +#define SLI_CT_INVALID_PORT_ID 0x11 +#define SLI_CT_DATABASE_EMPTY 0x12 + + + +/* + * Name Server Command Codes + */ + +#define SLI_CTNS_GA_NXT 0x0100 +#define SLI_CTNS_GPN_ID 0x0112 +#define SLI_CTNS_GNN_ID 0x0113 +#define SLI_CTNS_GCS_ID 0x0114 +#define SLI_CTNS_GFT_ID 0x0117 +#define SLI_CTNS_GSPN_ID 0x0118 +#define SLI_CTNS_GPT_ID 0x011A +#define SLI_CTNS_GID_PN 0x0121 +#define SLI_CTNS_GID_NN 0x0131 +#define SLI_CTNS_GIP_NN 0x0135 +#define SLI_CTNS_GIPA_NN 0x0136 +#define SLI_CTNS_GSNN_NN 0x0139 +#define SLI_CTNS_GNN_IP 0x0153 +#define SLI_CTNS_GIPA_IP 0x0156 +#define SLI_CTNS_GID_FT 0x0171 +#define SLI_CTNS_GID_PT 0x01A1 +#define SLI_CTNS_RPN_ID 0x0212 +#define SLI_CTNS_RNN_ID 0x0213 +#define SLI_CTNS_RCS_ID 0x0214 +#define SLI_CTNS_RFT_ID 0x0217 +#define SLI_CTNS_RSPN_ID 0x0218 +#define SLI_CTNS_RPT_ID 0x021A +#define SLI_CTNS_RIP_NN 0x0235 +#define SLI_CTNS_RIPA_NN 0x0236 +#define SLI_CTNS_RSNN_NN 0x0239 +#define SLI_CTNS_DA_ID 0x0300 + +/* + * Port Types + */ + +#define SLI_CTPT_N_PORT 0x01 +#define SLI_CTPT_NL_PORT 0x02 +#define SLI_CTPT_FNL_PORT 0x03 +#define SLI_CTPT_IP 0x04 +#define SLI_CTPT_FCP 0x08 +#define SLI_CTPT_NX_PORT 0x7F +#define SLI_CTPT_F_PORT 0x81 +#define SLI_CTPT_FL_PORT 0x82 +#define SLI_CTPT_E_PORT 0x84 + +#define SLI_CT_LAST_ENTRY 0x80000000 + +/*=====================================================================*/ + +#ifdef LP6000 +/* PCI register offsets */ +#define MEM_ADDR_OFFSET 0x10 /* SLIM base memory address */ +#define MEMH_OFFSET 0x14 /* SLIM base memory high address */ +#define REG_ADDR_OFFSET 0x18 /* REGISTER base memory address */ +#define REGH_OFFSET 0x1c /* REGISTER base memory high address */ +#define IO_ADDR_OFFSET 0x20 /* BIU I/O registers */ +#define REGIOH_OFFSET 0x24 /* REGISTER base io high address */ +#endif + +#define CMD_REG_OFFSET 0x4 /* PCI command configuration */ + +/* General PCI Register Definitions */ +/* Refer To The PCI Specification For Detailed Explanations */ + +/* Register Offsets in little endian format */ +#define PCI_VENDOR_ID_REGISTER 0x00 /* PCI Vendor ID Register*/ +#define PCI_DEVICE_ID_REGISTER 0x02 /* PCI Device ID Register*/ +#define PCI_CONFIG_ID_REGISTER 0x00 /* PCI Configuration ID Register*/ +#define PCI_COMMAND_REGISTER 0x04 /* PCI Command Register*/ +#define PCI_STATUS_REGISTER 0x06 /* PCI Status Register*/ +#define PCI_REV_ID_REGISTER 0x08 /* PCI Revision ID Register*/ +#define PCI_CLASS_CODE_REGISTER 0x09 /* PCI Class Code Register*/ +#define PCI_CACHE_LINE_REGISTER 0x0C /* PCI Cache Line Register*/ +#define PCI_LATENCY_TMR_REGISTER 0x0D /* PCI Latency Timer Register*/ +#define PCI_HEADER_TYPE_REGISTER 0x0E /* PCI Header Type Register*/ +#define PCI_BIST_REGISTER 0x0F /* PCI Built-In SelfTest Register*/ +#define PCI_BAR_0_REGISTER 0x10 /* PCI Base Address Register 0*/ +#define PCI_BAR_1_REGISTER 0x14 /* PCI Base Address Register 1*/ +#define PCI_BAR_2_REGISTER 0x18 /* PCI Base Address Register 2*/ +#define PCI_BAR_3_REGISTER 0x1C /* PCI Base Address Register 3*/ +#define PCI_BAR_4_REGISTER 0x20 /* PCI Base Address Register 4*/ +#define PCI_BAR_5_REGISTER 0x24 /* PCI Base Address Register 5*/ +#define PCI_EXPANSION_ROM 0x30 /* PCI Expansion ROM Base Register*/ +#define PCI_INTR_LINE_REGISTER 0x3C /* PCI Interrupt Line Register*/ +#define PCI_INTR_PIN_REGISTER 0x3D /* PCI Interrupt Pin Register*/ +#define PCI_MIN_GNT_REGISTER 0x3E /* PCI Min-Gnt Register*/ +#define PCI_MAX_LAT_REGISTER 0x3F /* PCI Max_Lat Register*/ +#define PCI_NODE_ADDR_REGISTER 0x40 /* PCI Node Address Register*/ + +/* PCI access methods */ +#define P_CONF_T1 1 +#define P_CONF_T2 2 + +/* max number of pci buses */ +#define MAX_PCI_BUSES 0xFF + +/* number of PCI config bytes to access */ +#define PCI_BYTE 1 +#define PCI_WORD 2 +#define PCI_DWORD 4 + +/* PCI related constants */ +#define CMD_IO_ENBL 0x0001 +#define CMD_MEM_ENBL 0x0002 +#define CMD_BUS_MASTER 0x0004 +#define CMD_MWI 0x0010 +#define CMD_PARITY_CHK 0x0040 +#define CMD_SERR_ENBL 0x0100 + +#define CMD_CFG_VALUE 0x156 /* mem enable, master, MWI, SERR, PERR */ + +/* PCI addresses */ +#define PCI_SPACE_ENABLE 0x0CF8 +#define CF1_CONFIG_ADDR_REGISTER 0x0CF8 +#define CF1_CONFIG_DATA_REGISTER 0x0CFC +#define CF2_FORWARD_REGISTER 0x0CFA +#define CF2_BASE_ADDRESS 0xC000 + +#define PCI_VENDOR_ID_EMULEX 0x10df + +#define PCI_DEVICE_ID_SUPERFLY 0xf700 +#define PCI_DEVICE_ID_DRAGONFLY 0xf800 +#define PCI_DEVICE_ID_CENTAUR 0xf900 +#define PCI_DEVICE_ID_PFLY 0xf098 +#define PCI_DEVICE_ID_PEGASUS 0xf980 +#define PCI_DEVICE_ID_TFLY 0xf0a5 +#define PCI_DEVICE_ID_THOR 0xfa00 + +#define JEDEC_ID_ADDRESS 0x0080001c +#define SUPERFLY_JEDEC_ID 0x0020 +#define DRAGONFLY_JEDEC_ID 0x0021 +#define DRAGONFLY_V2_JEDEC_ID 0x0025 +#define CENTAUR_2G_JEDEC_ID 0x0026 +#define CENTAUR_1G_JEDEC_ID 0x0028 +#define JEDEC_ID_MASK 0x0FFFF000 +#define JEDEC_ID_SHIFT 12 +#define FC_JEDEC_ID(id) ((id & JEDEC_ID_MASK) >> JEDEC_ID_SHIFT) + +#define DEFAULT_PCI_LATENCY_CLOCKS 0xf8 /* 0xF8 is a special value for + * FF11.1N6 firmware. Use + * 0x80 for pre-FF11.1N6 &N7, etc + */ +#define PCI_LATENCY_VALUE 0xf8 + +#ifdef LP6000 +typedef struct { /* BIU registers */ + uint32 hostAtt; /* See definitions for Host Attention register */ + uint32 chipAtt; /* See definitions for Chip Attention register */ + uint32 hostStatus; /* See definitions for Host Status register */ + uint32 hostControl; /* See definitions for Host Control register */ + uint32 buiConfig; /* See definitions for BIU configuration register*/ +} FF_REGS, *PFF_REGS; + +/* Host Attention Register */ + +#define HA_REG_OFFSET 0 /* Word offset from register base address */ + +#define HA_R0RE_REQ 0x00000001 /* Bit 0 */ +#define HA_R0CE_RSP 0x00000002 /* Bit 1 */ +#define HA_R0ATT 0x00000008 /* Bit 3 */ +#define HA_R1RE_REQ 0x00000010 /* Bit 4 */ +#define HA_R1CE_RSP 0x00000020 /* Bit 5 */ +#define HA_R1ATT 0x00000080 /* Bit 7 */ +#define HA_R2RE_REQ 0x00000100 /* Bit 8 */ +#define HA_R2CE_RSP 0x00000200 /* Bit 9 */ +#define HA_R2ATT 0x00000800 /* Bit 11 */ +#define HA_R3RE_REQ 0x00001000 /* Bit 12 */ +#define HA_R3CE_RSP 0x00002000 /* Bit 13 */ +#define HA_R3ATT 0x00008000 /* Bit 15 */ +#define HA_LATT 0x20000000 /* Bit 29 */ +#define HA_MBATT 0x40000000 /* Bit 30 */ +#define HA_ERATT 0x80000000 /* Bit 31 */ + + +/* Chip Attention Register */ + +#define CA_REG_OFFSET 1 /* Word offset from register base address */ + +#define CA_R0CE_REQ 0x00000001 /* Bit 0 */ +#define CA_R0RE_RSP 0x00000002 /* Bit 1 */ +#define CA_R0ATT 0x00000008 /* Bit 3 */ +#define CA_R1CE_REQ 0x00000010 /* Bit 4 */ +#define CA_R1RE_RSP 0x00000020 /* Bit 5 */ +#define CA_R1ATT 0x00000080 /* Bit 7 */ +#define CA_R2CE_REQ 0x00000100 /* Bit 8 */ +#define CA_R2RE_RSP 0x00000200 /* Bit 9 */ +#define CA_R2ATT 0x00000800 /* Bit 11 */ +#define CA_R3CE_REQ 0x00001000 /* Bit 12 */ +#define CA_R3RE_RSP 0x00002000 /* Bit 13 */ +#define CA_R3ATT 0x00008000 /* Bit 15 */ +#define CA_MBATT 0x40000000 /* Bit 30 */ + + +/* Host Status Register */ + +#define HS_REG_OFFSET 2 /* Word offset from register base address */ + +#define HS_MBRDY 0x00400000 /* Bit 22 */ +#define HS_FFRDY 0x00800000 /* Bit 23 */ +#define HS_FFER8 0x01000000 /* Bit 24 */ +#define HS_FFER7 0x02000000 /* Bit 25 */ +#define HS_FFER6 0x04000000 /* Bit 26 */ +#define HS_FFER5 0x08000000 /* Bit 27 */ +#define HS_FFER4 0x10000000 /* Bit 28 */ +#define HS_FFER3 0x20000000 /* Bit 29 */ +#define HS_FFER2 0x40000000 /* Bit 30 */ +#define HS_FFER1 0x80000000 /* Bit 31 */ +#define HS_FFERM 0xFF000000 /* Mask for error bits 31:24 */ + + +/* Host Control Register */ + +#define HC_REG_OFFSET 3 /* Word offset from register base address */ + +#define HC_MBINT_ENA 0x00000001 /* Bit 0 */ +#define HC_R0INT_ENA 0x00000002 /* Bit 1 */ +#define HC_R1INT_ENA 0x00000004 /* Bit 2 */ +#define HC_R2INT_ENA 0x00000008 /* Bit 3 */ +#define HC_R3INT_ENA 0x00000010 /* Bit 4 */ +#define HC_INITHBI 0x02000000 /* Bit 25 */ +#define HC_INITMB 0x04000000 /* Bit 26 */ +#define HC_INITFF 0x08000000 /* Bit 27 */ +#define HC_LAINT_ENA 0x20000000 /* Bit 29 */ +#define HC_ERINT_ENA 0x80000000 /* Bit 31 */ + +/* BIU Configuration Register */ + +#define BC_REG_OFFSET 4 /* Word offset from register base address */ + +#define BC_BSE 0x00000001 /* Bit 0 */ +#define BC_BSE_SWAP 0x01000000 /* Bit 0 - swapped */ + +#endif /* LP6000 */ + +/*=====================================================================*/ + +/* + * Start of FCP specific structures + */ + +/* + * Definition of FCP_RSP Packet + */ + +typedef struct _FCP_RSP { + uint32 rspRsvd1; /* FC Word 0, byte 0:3 */ + uint32 rspRsvd2; /* FC Word 1, byte 0:3 */ + + uchar rspStatus0; /* FCP_STATUS byte 0 (reserved) */ + uchar rspStatus1; /* FCP_STATUS byte 1 (reserved) */ + uchar rspStatus2; /* FCP_STATUS byte 2 field validity */ +#define RSP_LEN_VALID 0x01 /* bit 0 */ +#define SNS_LEN_VALID 0x02 /* bit 1 */ +#define RESID_OVER 0x04 /* bit 2 */ +#define RESID_UNDER 0x08 /* bit 3 */ + uchar rspStatus3; /* FCP_STATUS byte 3 SCSI status byte */ +#define SCSI_STAT_GOOD 0x00 +#define SCSI_STAT_CHECK_COND 0x02 +#define SCSI_STAT_COND_MET 0x04 +#define SCSI_STAT_BUSY 0x08 +#define SCSI_STAT_INTERMED 0x10 +#define SCSI_STAT_INTERMED_CM 0x14 +#define SCSI_STAT_RES_CNFLCT 0x18 +#define SCSI_STAT_CMD_TERM 0x22 +#define SCSI_STAT_QUE_FULL 0x28 + + uint32 rspResId; /* Residual xfer if RESID_xxxx set in fcpStatus2 */ + /* Received in Big Endian format */ + uint32 rspSnsLen; /* Length of sense data in fcpSnsInfo */ + /* Received in Big Endian format */ + uint32 rspRspLen; /* Length of FCP response data in fcpRspInfo */ + /* Received in Big Endian format */ + + uchar rspInfo0; /* FCP_RSP_INFO byte 0 (reserved) */ + uchar rspInfo1; /* FCP_RSP_INFO byte 1 (reserved) */ + uchar rspInfo2; /* FCP_RSP_INFO byte 2 (reserved) */ + uchar rspInfo3; /* FCP_RSP_INFO RSP_CODE byte 3 */ + +#define RSP_NO_FAILURE 0x00 +#define RSP_DATA_BURST_ERR 0x01 +#define RSP_CMD_FIELD_ERR 0x02 +#define RSP_RO_MISMATCH_ERR 0x03 +#define RSP_TM_NOT_SUPPORTED 0x04 /* Task mgmt function not supported */ +#define RSP_TM_NOT_COMPLETED 0x05 /* Task mgmt function not performed */ + + uint32 rspInfoRsvd; /* FCP_RSP_INFO bytes 4-7 (reserved) */ + +#define MAX_FCP_SNS 128 + uchar rspSnsInfo[MAX_FCP_SNS]; +} FCP_RSP, *PFCP_RSP; + +/* + * Definition of FCP_CMND Packet + */ + +typedef struct _FCP_CMND { + uint32 fcpLunMsl; /* most significant lun word (32 bits) */ + uint32 fcpLunLsl; /* least significant lun word (32 bits) */ + /* # of bits to shift lun id to end up in right + * payload word, little endian = 8, big = 16. + */ +#if LITTLE_ENDIAN_HW +#define FC_LUN_SHIFT 8 +#define FC_ADDR_MODE_SHIFT 0 +#endif +#if BIG_ENDIAN_HW +#define FC_LUN_SHIFT 16 +#define FC_ADDR_MODE_SHIFT 24 +#endif + + uchar fcpCntl0; /* FCP_CNTL byte 0 (reserved) */ + uchar fcpCntl1; /* FCP_CNTL byte 1 task codes */ +#define SIMPLE_Q 0x00 +#define HEAD_OF_Q 0x01 +#define ORDERED_Q 0x02 +#define ACA_Q 0x04 +#define UNTAGGED 0x05 + uchar fcpCntl2; /* FCP_CTL byte 2 task management codes */ +#define ABORT_TASK_SET 0x02 /* Bit 1 */ +#define CLEAR_TASK_SET 0x04 /* bit 2 */ +#define LUN_RESET 0x10 /* bit 4 */ +#define TARGET_RESET 0x20 /* bit 5 */ +#define CLEAR_ACA 0x40 /* bit 6 */ +#define TERMINATE_TASK 0x80 /* bit 7 */ + uchar fcpCntl3; +#define WRITE_DATA 0x01 /* Bit 0 */ +#define READ_DATA 0x02 /* Bit 1 */ + + uchar fcpCdb[16]; /* SRB cdb field is copied here */ + uint32 fcpDl; /* Total transfer length */ + +} FCP_CMND, *PFCP_CMND; + +/* SCSI INQUIRY Command Structure */ + +typedef struct inquiryDataType { + u8bit DeviceType : 5; + u8bit DeviceTypeQualifier : 3; + + u8bit DeviceTypeModifier : 7; + u8bit RemovableMedia : 1; + + uchar Versions; + uchar ResponseDataFormat; + uchar AdditionalLength; + uchar Reserved[2]; + + u8bit SoftReset : 1; + u8bit CommandQueue : 1; + u8bit Reserved2 : 1; + u8bit LinkedCommands : 1; + u8bit Synchronous : 1; + u8bit Wide16Bit : 1; + u8bit Wide32Bit : 1; + u8bit RelativeAddressing : 1; + + uchar VendorId[8]; + uchar ProductId[16]; + uchar ProductRevisionLevel[4]; + uchar VendorSpecific[20]; + uchar Reserved3[40]; +} INQUIRY_DATA_DEF; + +typedef struct _READ_CAPACITY_DATA { + ulong LogicalBlockAddress; + ulong BytesPerBlock; +} READ_CAPACITY_DATA_DEF; + +typedef struct _REPORT_LUNS_DATA { + union { + uchar cB[8]; + uint32 cL[2]; + } control; + union { + uchar eB[8]; + uint32 eL[2]; + } entry [1]; +} REPORT_LUNS_DATA_DEF; + +/* SCSI CDB command codes */ +#define FCP_SCSI_FORMAT_UNIT 0x04 +#define FCP_SCSI_INQUIRY 0x12 +#define FCP_SCSI_MODE_SELECT 0x15 +#define FCP_SCSI_MODE_SENSE 0x1A +#define FCP_SCSI_PAUSE_RESUME 0x4B +#define FCP_SCSI_PLAY_AUDIO 0x45 +#define FCP_SCSI_PLAY_AUDIO_EXT 0xA5 +#define FCP_SCSI_PLAY_AUDIO_MSF 0x47 +#define FCP_SCSI_PLAY_AUDIO_TRK_INDX 0x48 +#define FCP_SCSI_PREVENT_ALLOW_REMOVAL 0x1E +#define FCP_SCSI_READ 0x08 +#define FCP_SCSI_READ_BUFFER 0x3C +#define FCP_SCSI_READ_CAPACITY 0x25 +#define FCP_SCSI_READ_DEFECT_LIST 0x37 +#define FCP_SCSI_READ_EXTENDED 0x28 +#define FCP_SCSI_READ_HEADER 0x44 +#define FCP_SCSI_READ_LONG 0xE8 +#define FCP_SCSI_READ_SUB_CHANNEL 0x42 +#define FCP_SCSI_READ_TOC 0x43 +#define FCP_SCSI_REASSIGN_BLOCK 0x07 +#define FCP_SCSI_RECEIVE_DIAGNOSTIC_RESULTS 0x1C +#define FCP_SCSI_RELEASE_UNIT 0x17 +#define FCP_SCSI_REPORT_LUNS 0xa0 +#define FCP_SCSI_REQUEST_SENSE 0x03 +#define FCP_SCSI_RESERVE_UNIT 0x16 +#define FCP_SCSI_REZERO_UNIT 0x01 +#define FCP_SCSI_SEEK 0x0B +#define FCP_SCSI_SEEK_EXTENDED 0x2B +#define FCP_SCSI_SEND_DIAGNOSTIC 0x1D +#define FCP_SCSI_START_STOP_UNIT 0x1B +#define FCP_SCSI_TEST_UNIT_READY 0x00 +#define FCP_SCSI_VERIFY 0x2F +#define FCP_SCSI_WRITE 0x0A +#define FCP_SCSI_WRITE_AND_VERIFY 0x2E +#define FCP_SCSI_WRITE_BUFFER 0x3B +#define FCP_SCSI_WRITE_EXTENDED 0x2A +#define FCP_SCSI_WRITE_LONG 0xEA +#define FCP_SCSI_RELEASE_LUNR 0xBB +#define FCP_SCSI_RELEASE_LUNV 0xBF + +#define HPVA_SETPASSTHROUGHMODE 0x27 +#define HPVA_EXECUTEPASSTHROUGH 0x29 +#define HPVA_CREATELUN 0xE2 +#define HPVA_SETLUNSECURITYLIST 0xED +#define HPVA_SETCLOCK 0xF9 +#define HPVA_RECOVER 0xFA +#define HPVA_GENERICSERVICEOUT 0xFD + +#define DMEP_EXPORT_IN 0x85 +#define DMEP_EXPORT_OUT 0x89 + +#define MDACIOCTL_DIRECT_CMD 0x22 +#define MDACIOCTL_STOREIMAGE 0x2C +#define MDACIOCTL_WRITESIGNATURE 0xA6 +#define MDACIOCTL_SETREALTIMECLOCK 0xAC +#define MDACIOCTL_PASS_THRU_CDB 0xAD +#define MDACIOCTL_PASS_THRU_INITIATE 0xAE +#define MDACIOCTL_CREATENEWCONF 0xC0 +#define MDACIOCTL_ADDNEWCONF 0xC4 +#define MDACIOCTL_MORE 0xC6 +#define MDACIOCTL_SETPHYSDEVPARAMETER 0xC8 +#define MDACIOCTL_SETLOGDEVPARAMETER 0xCF +#define MDACIOCTL_SETCONTROLLERPARAMETER 0xD1 +#define MDACIOCTL_WRITESANMAP 0xD4 +#define MDACIOCTL_SETMACADDRESS 0xD5 + +/* + * End of FCP specific structures + */ + +#define FL_ALPA 0x00 /* AL_PA of FL_Port */ + +/* Fibre Channel Service Parameter definitions */ + +#define FC_PH_4_0 6 /* FC-PH version 4.0 */ +#define FC_PH_4_1 7 /* FC-PH version 4.1 */ +#define FC_PH_4_2 8 /* FC-PH version 4.2 */ +#define FC_PH_4_3 9 /* FC-PH version 4.3 */ + +#define FC_PH_LOW 8 /* Lowest supported FC-PH version */ +#define FC_PH_HIGH 9 /* Highest supported FC-PH version */ +#define FC_PH3 0x20 /* FC-PH-3 version */ + +#define FF_FRAME_SIZE 2048 + + +/* ==== Mailbox Commands ==== */ +#define MBX_SHUTDOWN 0x00 /* terminate testing */ +#define MBX_LOAD_SM 0x01 +#define MBX_READ_NV 0x02 +#define MBX_WRITE_NV 0x03 +#define MBX_RUN_BIU_DIAG 0x04 +#define MBX_INIT_LINK 0x05 +#define MBX_DOWN_LINK 0x06 +#define MBX_CONFIG_LINK 0x07 +#define MBX_PART_SLIM 0x08 +#define MBX_CONFIG_RING 0x09 +#define MBX_RESET_RING 0x0A +#define MBX_READ_CONFIG 0x0B +#define MBX_READ_RCONFIG 0x0C +#define MBX_READ_SPARM 0x0D +#define MBX_READ_STATUS 0x0E +#define MBX_READ_RPI 0x0F +#define MBX_READ_XRI 0x10 +#define MBX_READ_REV 0x11 +#define MBX_READ_LNK_STAT 0x12 +#define MBX_REG_LOGIN 0x13 +#define MBX_UNREG_LOGIN 0x14 +#define MBX_READ_LA 0x15 +#define MBX_CLEAR_LA 0x16 +#define MBX_DUMP_MEMORY 0x17 +#define MBX_DUMP_CONTEXT 0x18 +#define MBX_RUN_DIAGS 0x19 +#define MBX_RESTART 0x1A +#define MBX_UPDATE_CFG 0x1B +#define MBX_DOWN_LOAD 0x1C +#define MBX_DEL_LD_ENTRY 0x1D +#define MBX_RUN_PROGRAM 0x1E +#define MBX_SET_MASK 0x20 +#define MBX_SET_SLIM 0x21 +#define MBX_UNREG_D_ID 0x23 +#define MBX_CONFIG_FARP 0x25 + +#define MBX_LOAD_AREA 0x81 +#define MBX_RUN_BIU_DIAG64 0x84 +#define MBX_CONFIG_PORT 0x88 +#define MBX_READ_SPARM64 0x8D +#define MBX_READ_RPI64 0x8F +#define MBX_REG_LOGIN64 0x93 +#define MBX_READ_LA64 0x95 + +#define MBX_FLASH_WR_ULA 0x98 +#define MBX_SET_DEBUG 0x99 +#define MBX_LOAD_EXP_ROM 0x9C + +#define MBX_MAX_CMDS 0x9D +#define MBX_SLI2_CMD_MASK 0x80 + + +/* ==== IOCB Commands ==== */ + +#define CMD_RCV_SEQUENCE_CX 0x01 +#define CMD_XMIT_SEQUENCE_CR 0x02 +#define CMD_XMIT_SEQUENCE_CX 0x03 +#define CMD_XMIT_BCAST_CN 0x04 +#define CMD_XMIT_BCAST_CX 0x05 +#define CMD_QUE_RING_BUF_CN 0x06 +#define CMD_QUE_XRI_BUF_CX 0x07 +#define CMD_IOCB_CONTINUE_CN 0x08 +#define CMD_RET_XRI_BUF_CX 0x09 +#define CMD_ELS_REQUEST_CR 0x0A +#define CMD_ELS_REQUEST_CX 0x0B +#define CMD_RCV_ELS_REQ_CX 0x0D +#define CMD_ABORT_XRI_CN 0x0E +#define CMD_ABORT_XRI_CX 0x0F +#define CMD_CLOSE_XRI_CR 0x10 +#define CMD_CLOSE_XRI_CX 0x11 +#define CMD_CREATE_XRI_CR 0x12 +#define CMD_CREATE_XRI_CX 0x13 +#define CMD_GET_RPI_CN 0x14 +#define CMD_XMIT_ELS_RSP_CX 0x15 +#define CMD_GET_RPI_CR 0x16 +#define CMD_XRI_ABORTED_CX 0x17 +#define CMD_FCP_IWRITE_CR 0x18 +#define CMD_FCP_IWRITE_CX 0x19 +#define CMD_FCP_IREAD_CR 0x1A +#define CMD_FCP_IREAD_CX 0x1B +#define CMD_FCP_ICMND_CR 0x1C +#define CMD_FCP_ICMND_CX 0x1D +#define CMD_ADAPTER_MSG 0x20 +#define CMD_ADAPTER_DUMP 0x22 +#define CMD_BPL_IWRITE_CR 0x48 +#define CMD_BPL_IWRITE_CX 0x49 +#define CMD_BPL_IREAD_CR 0x4A +#define CMD_BPL_IREAD_CX 0x4B +#define CMD_BPL_ICMND_CR 0x4C +#define CMD_BPL_ICMND_CX 0x4D + +/* SLI_2 IOCB Command Set */ + +#define CMD_RCV_SEQUENCE64_CX 0x81 +#define CMD_XMIT_SEQUENCE64_CR 0x82 +#define CMD_XMIT_SEQUENCE64_CX 0x83 +#define CMD_XMIT_BCAST64_CN 0x84 +#define CMD_XMIT_BCAST64_CX 0x85 +#define CMD_QUE_RING_BUF64_CN 0x86 +#define CMD_QUE_XRI_BUF64_CX 0x87 +#define CMD_IOCB_CONTINUE64_CN 0x88 +#define CMD_RET_XRI_BUF64_CX 0x89 +#define CMD_ELS_REQUEST64_CR 0x8A +#define CMD_ELS_REQUEST64_CX 0x8B +#define CMD_RCV_ELS_REQ64_CX 0x8D +#define CMD_XMIT_ELS_RSP64_CX 0x95 +#define CMD_FCP_IWRITE64_CR 0x98 +#define CMD_FCP_IWRITE64_CX 0x99 +#define CMD_FCP_IREAD64_CR 0x9A +#define CMD_FCP_IREAD64_CX 0x9B +#define CMD_FCP_ICMND64_CR 0x9C +#define CMD_FCP_ICMND64_CX 0x9D +#define CMD_GEN_REQUEST64_CR 0xC2 +#define CMD_GEN_REQUEST64_CX 0xC3 + + +/* + * Define Status + */ +#define MBX_SUCCESS 0 +#define MBXERR_NUM_RINGS 1 +#define MBXERR_NUM_IOCBS 2 +#define MBXERR_IOCBS_EXCEEDED 3 +#define MBXERR_BAD_RING_NUMBER 4 +#define MBXERR_MASK_ENTRIES_RANGE 5 +#define MBXERR_MASKS_EXCEEDED 6 +#define MBXERR_BAD_PROFILE 7 +#define MBXERR_BAD_DEF_CLASS 8 +#define MBXERR_BAD_MAX_RESPONDER 9 +#define MBXERR_BAD_MAX_ORIGINATOR 10 +#define MBXERR_RPI_REGISTERED 11 +#define MBXERR_RPI_FULL 12 +#define MBXERR_NO_RESOURCES 13 +#define MBXERR_BAD_RCV_LENGTH 14 +#define MBXERR_DMA_ERROR 15 +#define MBXERR_ERROR 16 +#define MBX_NOT_FINISHED 255 +/* + * Error codes returned by issue_mb_cmd() + */ +#define MBX_BUSY 0xffffff /* Attempted cmd to a busy Mailbox */ +#define MBX_TIMEOUT 0xfffffe /* Max time-out expired waiting for */ +/* synch. Mailbox operation */ +/* + * flags for issue_mb_cmd() + */ +#define MBX_POLL 1 /* poll mailbox till command done, then return */ +#define MBX_SLEEP 2 /* sleep till mailbox intr cmpl wakes thread up */ +#define MBX_NOWAIT 3 /* issue command then return immediately */ + +typedef struct { +#if BIG_ENDIAN_HW + u32bit crReserved :16; + u32bit crBegin : 8; + u32bit crEnd : 8; /* Low order bit first word */ + u32bit rrReserved :16; + u32bit rrBegin : 8; + u32bit rrEnd : 8; /* Low order bit second word */ +#endif +#if LITTLE_ENDIAN_HW + u32bit crEnd : 8; /* Low order bit first word */ + u32bit crBegin : 8; + u32bit crReserved :16; + u32bit rrEnd : 8; /* Low order bit second word */ + u32bit rrBegin : 8; + u32bit rrReserved :16; +#endif +} RINGS; + + +typedef struct { +#if BIG_ENDIAN_HW + ushort offCiocb; + ushort numCiocb; + ushort offRiocb; + ushort numRiocb; +#endif +#if LITTLE_ENDIAN_HW + ushort numCiocb; + ushort offCiocb; + ushort numRiocb; + ushort offRiocb; +#endif +} RING_DEF; + + +/* + * The following F.C. frame stuctures are defined in Big Endian format. + */ + +typedef struct _NAME_TYPE { +#if BIG_ENDIAN_HW + u8bit nameType : 4; /* FC Word 0, bit 28:31 */ + u8bit IEEEextMsn : 4; /* FC Word 0, bit 24:27, bit 8:11 of IEEE ext */ +#endif +#if LITTLE_ENDIAN_HW + u8bit IEEEextMsn : 4; /* FC Word 0, bit 24:27, bit 8:11 of IEEE ext */ + u8bit nameType : 4; /* FC Word 0, bit 28:31 */ +#endif +#define NAME_IEEE 0x1 /* IEEE name - nameType */ +#define NAME_IEEE_EXT 0x2 /* IEEE extended name */ +#define NAME_FC_TYPE 0x3 /* FC native name type */ +#define NAME_IP_TYPE 0x4 /* IP address */ +#define NAME_CCITT_TYPE 0xC +#define NAME_CCITT_GR_TYPE 0xE + uchar IEEEextLsb; /* FC Word 0, bit 16:23, IEEE extended Lsb */ + uchar IEEE[6]; /* FC IEEE address */ +} NAME_TYPE; + + +typedef struct _CSP { + uchar fcphHigh; /* FC Word 0, byte 0 */ + uchar fcphLow; + uchar bbCreditMsb; + uchar bbCreditlsb; /* FC Word 0, byte 3 */ +#if BIG_ENDIAN_HW + u16bit increasingOffset : 1; /* FC Word 1, bit 31 */ + u16bit randomOffset : 1; /* FC Word 1, bit 30 */ + u16bit word1Reserved2 : 1; /* FC Word 1, bit 29 */ + u16bit fPort : 1; /* FC Word 1, bit 28 */ + u16bit altBbCredit : 1; /* FC Word 1, bit 27 */ + u16bit edtovResolution : 1; /* FC Word 1, bit 26 */ + u16bit multicast : 1; /* FC Word 1, bit 25 */ + u16bit broadcast : 1; /* FC Word 1, bit 24 */ + + u16bit huntgroup : 1; /* FC Word 1, bit 23 */ + u16bit simplex : 1; /* FC Word 1, bit 22 */ + u16bit word1Reserved1 : 3; /* FC Word 1, bit 21:19 */ + u16bit dhd : 1; /* FC Word 1, bit 18 */ + u16bit contIncSeqCnt : 1; /* FC Word 1, bit 17 */ + u16bit payloadlength : 1; /* FC Word 1, bit 16 */ +#endif +#if LITTLE_ENDIAN_HW + u16bit broadcast : 1; /* FC Word 1, bit 24 */ + u16bit multicast : 1; /* FC Word 1, bit 25 */ + u16bit edtovResolution : 1; /* FC Word 1, bit 26 */ + u16bit altBbCredit : 1; /* FC Word 1, bit 27 */ + u16bit fPort : 1; /* FC Word 1, bit 28 */ + u16bit word1Reserved2 : 1; /* FC Word 1, bit 29 */ + u16bit randomOffset : 1; /* FC Word 1, bit 30 */ + u16bit increasingOffset : 1; /* FC Word 1, bit 31 */ + + u16bit payloadlength : 1; /* FC Word 1, bit 16 */ + u16bit contIncSeqCnt : 1; /* FC Word 1, bit 17 */ + u16bit dhd : 1; /* FC Word 1, bit 18 */ + u16bit word1Reserved1 : 3; /* FC Word 1, bit 21:19 */ + u16bit simplex : 1; /* FC Word 1, bit 22 */ + u16bit huntgroup : 1; /* FC Word 1, bit 23 */ +#endif + uchar bbRcvSizeMsb; /* Upper nibble is reserved */ + + uchar bbRcvSizeLsb; /* FC Word 1, byte 3 */ + union { + struct { + uchar word2Reserved1; /* FC Word 2 byte 0 */ + + uchar totalConcurrSeq; /* FC Word 2 byte 1 */ + uchar roByCategoryMsb; /* FC Word 2 byte 2 */ + + uchar roByCategoryLsb; /* FC Word 2 byte 3 */ + } nPort; + uint32 r_a_tov; /* R_A_TOV must be in B.E. format */ + } w2; + + uint32 e_d_tov; /* E_D_TOV must be in B.E. format */ +} CSP; + + +typedef struct _CLASS_PARMS { +#if BIG_ENDIAN_HW + u8bit classValid : 1; /* FC Word 0, bit 31 */ + u8bit intermix : 1; /* FC Word 0, bit 30 */ + u8bit stackedXparent : 1; /* FC Word 0, bit 29 */ + u8bit stackedLockDown : 1; /* FC Word 0, bit 28 */ + u8bit seqDelivery : 1; /* FC Word 0, bit 27 */ + u8bit word0Reserved1 : 3; /* FC Word 0, bit 24:26 */ +#endif +#if LITTLE_ENDIAN_HW + u8bit word0Reserved1 : 3; /* FC Word 0, bit 24:26 */ + u8bit seqDelivery : 1; /* FC Word 0, bit 27 */ + u8bit stackedLockDown : 1; /* FC Word 0, bit 28 */ + u8bit stackedXparent : 1; /* FC Word 0, bit 29 */ + u8bit intermix : 1; /* FC Word 0, bit 30 */ + u8bit classValid : 1; /* FC Word 0, bit 31 */ + +#endif + uchar word0Reserved2; /* FC Word 0, bit 16:23 */ +#if BIG_ENDIAN_HW + u8bit iCtlXidReAssgn : 2; /* FC Word 0, Bit 14:15 */ + u8bit iCtlInitialPa : 2; /* FC Word 0, bit 12:13 */ + u8bit iCtlAck0capable : 1; /* FC Word 0, bit 11 */ + u8bit iCtlAckNcapable : 1; /* FC Word 0, bit 10 */ + u8bit word0Reserved3 : 2; /* FC Word 0, bit 8: 9 */ +#endif +#if LITTLE_ENDIAN_HW + u8bit word0Reserved3 : 2; /* FC Word 0, bit 8: 9 */ + u8bit iCtlAckNcapable : 1; /* FC Word 0, bit 10 */ + u8bit iCtlAck0capable : 1; /* FC Word 0, bit 11 */ + u8bit iCtlInitialPa : 2; /* FC Word 0, bit 12:13 */ + u8bit iCtlXidReAssgn : 2; /* FC Word 0, Bit 14:15 */ +#endif + uchar word0Reserved4; /* FC Word 0, bit 0: 7 */ +#if BIG_ENDIAN_HW + u8bit rCtlAck0capable : 1; /* FC Word 1, bit 31 */ + u8bit rCtlAckNcapable : 1; /* FC Word 1, bit 30 */ + u8bit rCtlXidInterlck : 1; /* FC Word 1, bit 29 */ + u8bit rCtlErrorPolicy : 2; /* FC Word 1, bit 27:28 */ + u8bit word1Reserved1 : 1; /* FC Word 1, bit 26 */ + u8bit rCtlCatPerSeq : 2; /* FC Word 1, bit 24:25 */ +#endif +#if LITTLE_ENDIAN_HW + u8bit rCtlCatPerSeq : 2; /* FC Word 1, bit 24:25 */ + u8bit word1Reserved1 : 1; /* FC Word 1, bit 26 */ + u8bit rCtlErrorPolicy : 2; /* FC Word 1, bit 27:28 */ + u8bit rCtlXidInterlck : 1; /* FC Word 1, bit 29 */ + u8bit rCtlAckNcapable : 1; /* FC Word 1, bit 30 */ + u8bit rCtlAck0capable : 1; /* FC Word 1, bit 31 */ +#endif + uchar word1Reserved2; /* FC Word 1, bit 16:23 */ + uchar rcvDataSizeMsb; /* FC Word 1, bit 8:15 */ + uchar rcvDataSizeLsb; /* FC Word 1, bit 0: 7 */ + + uchar concurrentSeqMsb; /* FC Word 2, bit 24:31 */ + uchar concurrentSeqLsb; /* FC Word 2, bit 16:23 */ + uchar EeCreditSeqMsb; /* FC Word 2, bit 8:15 */ + uchar EeCreditSeqLsb; /* FC Word 2, bit 0: 7 */ + + uchar openSeqPerXchgMsb; /* FC Word 3, bit 24:31 */ + uchar openSeqPerXchgLsb; /* FC Word 3, bit 16:23 */ + uchar word3Reserved1; /* Fc Word 3, bit 8:15 */ + uchar word3Reserved2; /* Fc Word 3, bit 0: 7 */ +} CLASS_PARMS; + + +typedef struct _SERV_PARM { /* Structure is in Big Endian format */ + CSP cmn; + NAME_TYPE portName; + NAME_TYPE nodeName; + CLASS_PARMS cls1; + CLASS_PARMS cls2; + CLASS_PARMS cls3; + CLASS_PARMS cls4; + uchar vendorVersion[16]; +} SERV_PARM, *PSERV_PARM; + + +/* + * Extended Link Service LS_COMMAND codes (Payload Word 0) + */ +#if BIG_ENDIAN_HW +#define ELS_CMD_MASK 0xffff0000 +#define ELS_RSP_MASK 0xff000000 +#define ELS_CMD_LS_RJT 0x01000000 +#define ELS_CMD_ACC 0x02000000 +#define ELS_CMD_PLOGI 0x03000000 +#define ELS_CMD_FLOGI 0x04000000 +#define ELS_CMD_LOGO 0x05000000 +#define ELS_CMD_ABTX 0x06000000 +#define ELS_CMD_RCS 0x07000000 +#define ELS_CMD_RES 0x08000000 +#define ELS_CMD_RSS 0x09000000 +#define ELS_CMD_RSI 0x0A000000 +#define ELS_CMD_ESTS 0x0B000000 +#define ELS_CMD_ESTC 0x0C000000 +#define ELS_CMD_ADVC 0x0D000000 +#define ELS_CMD_RTV 0x0E000000 +#define ELS_CMD_RLS 0x0F000000 +#define ELS_CMD_ECHO 0x10000000 +#define ELS_CMD_TEST 0x11000000 +#define ELS_CMD_RRQ 0x12000000 +#define ELS_CMD_PRLI 0x20100014 +#define ELS_CMD_PRLO 0x21100014 +#define ELS_CMD_PDISC 0x50000000 +#define ELS_CMD_FDISC 0x51000000 +#define ELS_CMD_ADISC 0x52000000 +#define ELS_CMD_FARP 0x54000000 +#define ELS_CMD_FARPR 0x55000000 +#define ELS_CMD_FAN 0x60000000 +#define ELS_CMD_RSCN 0x61040000 +#define ELS_CMD_SCR 0x62000000 +#define ELS_CMD_RNID 0x78000000 +#endif +#if LITTLE_ENDIAN_HW +#define ELS_CMD_MASK 0xffff +#define ELS_RSP_MASK 0xff +#define ELS_CMD_LS_RJT 0x01 +#define ELS_CMD_ACC 0x02 +#define ELS_CMD_PLOGI 0x03 +#define ELS_CMD_FLOGI 0x04 +#define ELS_CMD_LOGO 0x05 +#define ELS_CMD_ABTX 0x06 +#define ELS_CMD_RCS 0x07 +#define ELS_CMD_RES 0x08 +#define ELS_CMD_RSS 0x09 +#define ELS_CMD_RSI 0x0A +#define ELS_CMD_ESTS 0x0B +#define ELS_CMD_ESTC 0x0C +#define ELS_CMD_ADVC 0x0D +#define ELS_CMD_RTV 0x0E +#define ELS_CMD_RLS 0x0F +#define ELS_CMD_ECHO 0x10 +#define ELS_CMD_TEST 0x11 +#define ELS_CMD_RRQ 0x12 +#define ELS_CMD_PRLI 0x14001020 +#define ELS_CMD_PRLO 0x14001021 +#define ELS_CMD_PDISC 0x50 +#define ELS_CMD_FDISC 0x51 +#define ELS_CMD_ADISC 0x52 +#define ELS_CMD_FARP 0x54 +#define ELS_CMD_FARPR 0x55 +#define ELS_CMD_FAN 0x60 +#define ELS_CMD_RSCN 0x0461 +#define ELS_CMD_SCR 0x62 +#define ELS_CMD_RNID 0x78 +#endif + + +/* + * LS_RJT Payload Definition + */ + +typedef struct _LS_RJT { /* Structure is in Big Endian format */ + union { + uint32 lsRjtError; + struct { + uchar lsRjtRsvd0; /* FC Word 0, bit 24:31 */ + + uchar lsRjtRsnCode; /* FC Word 0, bit 16:23 */ + /* LS_RJT reason codes */ +#define LSRJT_INVALID_CMD 0x01 +#define LSRJT_LOGICAL_ERR 0x03 +#define LSRJT_LOGICAL_BSY 0x05 +#define LSRJT_PROTOCOL_ERR 0x07 +#define LSRJT_UNABLE_TPC 0x09 /* Unable to perform command */ +#define LSRJT_CMD_UNSUPPORTED 0x0B +#define LSRJT_VENDOR_UNIQUE 0xFF /* See Byte 3 */ + + uchar lsRjtRsnCodeExp; /* FC Word 0, bit 8:15 */ + /* LS_RJT reason explanation */ +#define LSEXP_NOTHING_MORE 0x00 +#define LSEXP_SPARM_OPTIONS 0x01 +#define LSEXP_SPARM_ICTL 0x03 +#define LSEXP_SPARM_RCTL 0x05 +#define LSEXP_SPARM_RCV_SIZE 0x07 +#define LSEXP_SPARM_CONCUR_SEQ 0x09 +#define LSEXP_SPARM_CREDIT 0x0B +#define LSEXP_INVALID_PNAME 0x0D +#define LSEXP_INVALID_NNAME 0x0E +#define LSEXP_INVALID_CSP 0x0F +#define LSEXP_INVALID_ASSOC_HDR 0x11 +#define LSEXP_ASSOC_HDR_REQ 0x13 +#define LSEXP_INVALID_O_SID 0x15 +#define LSEXP_INVALID_OX_RX 0x17 +#define LSEXP_CMD_IN_PROGRESS 0x19 +#define LSEXP_INVALID_NPORT_ID 0x1F +#define LSEXP_INVALID_SEQ_ID 0x21 +#define LSEXP_INVALID_XCHG 0x23 +#define LSEXP_INACTIVE_XCHG 0x25 +#define LSEXP_RQ_REQUIRED 0x27 +#define LSEXP_OUT_OF_RESOURCE 0x29 +#define LSEXP_CANT_GIVE_DATA 0x2A +#define LSEXP_REQ_UNSUPPORTED 0x2C + uchar vendorUnique; /* FC Word 0, bit 0: 7 */ + } b; + } un; +} LS_RJT; + + +/* + * N_Port Login (FLOGO/PLOGO Request) Payload Definition + */ + +typedef struct _LOGO { /* Structure is in Big Endian format */ + union { + uint32 nPortId32; /* Access nPortId as a word */ + struct { + uchar word1Reserved1; /* FC Word 1, bit 31:24 */ + uchar nPortIdByte0; /* N_port ID bit 16:23 */ + uchar nPortIdByte1; /* N_port ID bit 8:15 */ + uchar nPortIdByte2; /* N_port ID bit 0: 7 */ + } b; + } un; + NAME_TYPE portName; /* N_port name field */ +} LOGO; + + +/* + * FCP Login (PRLI Request / ACC) Payload Definition + */ + +#define PRLX_PAGE_LEN 0x10 +#define TPRLO_PAGE_LEN 0x14 + +typedef struct _PRLI { /* Structure is in Big Endian format */ + uchar prliType; /* FC Parm Word 0, bit 24:31 */ + +#define PRLI_FCP_TYPE 0x08 + uchar word0Reserved1; /* FC Parm Word 0, bit 16:23 */ + +#if BIG_ENDIAN_HW + u8bit origProcAssocV : 1; /* FC Parm Word 0, bit 15 */ + u8bit respProcAssocV : 1; /* FC Parm Word 0, bit 14 */ + u8bit estabImagePair : 1; /* FC Parm Word 0, bit 13 */ + + u8bit word0Reserved2 : 1; /* FC Parm Word 0, bit 12 */ + u8bit acceptRspCode : 4; /* FC Parm Word 0, bit 8:11, ACC ONLY */ +#endif +#if LITTLE_ENDIAN_HW + u8bit acceptRspCode : 4; /* FC Parm Word 0, bit 8:11, ACC ONLY */ + u8bit word0Reserved2 : 1; /* FC Parm Word 0, bit 12 */ + u8bit estabImagePair : 1; /* FC Parm Word 0, bit 13 */ + u8bit respProcAssocV : 1; /* FC Parm Word 0, bit 14 */ + u8bit origProcAssocV : 1; /* FC Parm Word 0, bit 15 */ +#endif +#define PRLI_REQ_EXECUTED 0x1 /* acceptRspCode */ +#define PRLI_NO_RESOURCES 0x2 +#define PRLI_INIT_INCOMPLETE 0x3 +#define PRLI_NO_SUCH_PA 0x4 +#define PRLI_PREDEF_CONFIG 0x5 +#define PRLI_PARTIAL_SUCCESS 0x6 +#define PRLI_INVALID_PAGE_CNT 0x7 + uchar word0Reserved3; /* FC Parm Word 0, bit 0:7 */ + + uint32 origProcAssoc; /* FC Parm Word 1, bit 0:31 */ + + uint32 respProcAssoc; /* FC Parm Word 2, bit 0:31 */ + + uchar word3Reserved1; /* FC Parm Word 3, bit 24:31 */ + uchar word3Reserved2; /* FC Parm Word 3, bit 16:23 */ +#if BIG_ENDIAN_HW + u16bit Word3bit15Resved : 1; /* FC Parm Word 3, bit 15 */ + u16bit Word3bit14Resved : 1; /* FC Parm Word 3, bit 14 */ + u16bit Word3bit13Resved : 1; /* FC Parm Word 3, bit 13 */ + u16bit Word3bit12Resved : 1; /* FC Parm Word 3, bit 12 */ + u16bit Word3bit11Resved : 1; /* FC Parm Word 3, bit 11 */ + u16bit Word3bit10Resved : 1; /* FC Parm Word 3, bit 10 */ + u16bit TaskRetryIdReq : 1; /* FC Parm Word 3, bit 9 */ + u16bit Retry : 1; /* FC Parm Word 3, bit 8 */ + u16bit ConfmComplAllowed : 1; /* FC Parm Word 3, bit 7 */ + u16bit dataOverLay : 1; /* FC Parm Word 3, bit 6 */ + u16bit initiatorFunc : 1; /* FC Parm Word 3, bit 5 */ + u16bit targetFunc : 1; /* FC Parm Word 3, bit 4 */ + u16bit cmdDataMixEna : 1; /* FC Parm Word 3, bit 3 */ + u16bit dataRspMixEna : 1; /* FC Parm Word 3, bit 2 */ + u16bit readXferRdyDis : 1; /* FC Parm Word 3, bit 1 */ + u16bit writeXferRdyDis : 1; /* FC Parm Word 3, bit 0 */ +#endif +#if LITTLE_ENDIAN_HW + u16bit Retry : 1; /* FC Parm Word 3, bit 8 */ + u16bit TaskRetryIdReq : 1; /* FC Parm Word 3, bit 9 */ + u16bit Word3bit10Resved : 1; /* FC Parm Word 3, bit 10 */ + u16bit Word3bit11Resved : 1; /* FC Parm Word 3, bit 11 */ + u16bit Word3bit12Resved : 1; /* FC Parm Word 3, bit 12 */ + u16bit Word3bit13Resved : 1; /* FC Parm Word 3, bit 13 */ + u16bit Word3bit14Resved : 1; /* FC Parm Word 3, bit 14 */ + u16bit Word3bit15Resved : 1; /* FC Parm Word 3, bit 15 */ + u16bit writeXferRdyDis : 1; /* FC Parm Word 3, bit 0 */ + u16bit readXferRdyDis : 1; /* FC Parm Word 3, bit 1 */ + u16bit dataRspMixEna : 1; /* FC Parm Word 3, bit 2 */ + u16bit cmdDataMixEna : 1; /* FC Parm Word 3, bit 3 */ + u16bit targetFunc : 1; /* FC Parm Word 3, bit 4 */ + u16bit initiatorFunc : 1; /* FC Parm Word 3, bit 5 */ + u16bit dataOverLay : 1; /* FC Parm Word 3, bit 6 */ + u16bit ConfmComplAllowed : 1; /* FC Parm Word 3, bit 7 */ +#endif +} PRLI; + +/* + * FCP Logout (PRLO Request / ACC) Payload Definition + */ + +typedef struct _PRLO { /* Structure is in Big Endian format */ + uchar prloType; /* FC Parm Word 0, bit 24:31 */ + +#define PRLO_FCP_TYPE 0x08 + uchar word0Reserved1; /* FC Parm Word 0, bit 16:23 */ + +#if BIG_ENDIAN_HW + u8bit origProcAssocV : 1; /* FC Parm Word 0, bit 15 */ + u8bit respProcAssocV : 1; /* FC Parm Word 0, bit 14 */ + u8bit word0Reserved2 : 2; /* FC Parm Word 0, bit 12:13 */ + u8bit acceptRspCode : 4; /* FC Parm Word 0, bit 8:11, ACC ONLY */ +#endif +#if LITTLE_ENDIAN_HW + u8bit acceptRspCode : 4; /* FC Parm Word 0, bit 8:11, ACC ONLY */ + u8bit word0Reserved2 : 2; /* FC Parm Word 0, bit 12:13 */ + u8bit respProcAssocV : 1; /* FC Parm Word 0, bit 14 */ + u8bit origProcAssocV : 1; /* FC Parm Word 0, bit 15 */ +#endif +#define PRLO_REQ_EXECUTED 0x1 /* acceptRspCode */ +#define PRLO_NO_SUCH_IMAGE 0x4 +#define PRLO_INVALID_PAGE_CNT 0x7 + + uchar word0Reserved3; /* FC Parm Word 0, bit 0:7 */ + + uint32 origProcAssoc; /* FC Parm Word 1, bit 0:31 */ + + uint32 respProcAssoc; /* FC Parm Word 2, bit 0:31 */ + + uint32 word3Reserved1; /* FC Parm Word 3, bit 0:31 */ +} PRLO; + + +typedef struct _ADISC { /* Structure is in Big Endian format */ + uint32 hardAL_PA; + NAME_TYPE portName; + NAME_TYPE nodeName; + uint32 DID; +} ADISC; + + +typedef struct _FARP { /* Structure is in Big Endian format */ + u32bit Mflags : 8; + u32bit Odid : 24; +#define FARP_NO_ACTION 0 /* FARP information enclosed, no action */ +#define FARP_MATCH_PORT 0x1 /* Match on Responder Port Name */ +#define FARP_MATCH_NODE 0x2 /* Match on Responder Node Name */ +#define FARP_MATCH_IP 0x4 /* Match on IP address, not supported */ +#define FARP_MATCH_IPV4 0x5 /* Match on IPV4 address, not supported */ +#define FARP_MATCH_IPV6 0x6 /* Match on IPV6 address, not supported */ + u32bit Rflags : 8; + u32bit Rdid : 24; +#define FARP_REQUEST_PLOGI 0x1 /* Request for PLOGI */ +#define FARP_REQUEST_FARPR 0x2 /* Request for FARP Response */ + NAME_TYPE OportName; + NAME_TYPE OnodeName; + NAME_TYPE RportName; + NAME_TYPE RnodeName; + uchar Oipaddr[16]; + uchar Ripaddr[16]; +} FARP; + +typedef struct _FAN { /* Structure is in Big Endian format */ + uint32 Fdid; + NAME_TYPE FportName; + NAME_TYPE FnodeName; +} FAN; + +typedef struct _SCR { /* Structure is in Big Endian format */ + uchar resvd1; + uchar resvd2; + uchar resvd3; + uchar Function; +#define SCR_FUNC_FABRIC 0x01 +#define SCR_FUNC_NPORT 0x02 +#define SCR_FUNC_FULL 0x03 +#define SCR_CLEAR 0xff +} SCR; + +typedef struct _RNID_TOP_DISC { + NAME_TYPE portName; + uchar resvd[8]; + uint32 unitType; +#define RNID_HBA 0x7 +#define RNID_HOST 0xa +#define RNID_DRIVER 0xd + uint32 physPort; + uint32 attachedNodes; + ushort ipVersion; +#define RNID_IPV4 0x1 +#define RNID_IPV6 0x2 + ushort UDPport; + uchar ipAddr[16]; + ushort resvd1; + ushort flags; +#define RNID_TD_SUPPORT 0x1 +#define RNID_LP_VALID 0x2 +} RNID_TOP_DISC; + +typedef struct _RNID { /* Structure is in Big Endian format */ + uchar Format; +#define RNID_TOPOLOGY_DISC 0xdf + uchar CommonLen; + uchar resvd1; + uchar SpecificLen; + NAME_TYPE portName; + NAME_TYPE nodeName; + union { + RNID_TOP_DISC topologyDisc; /* topology disc (0xdf) */ + } un; +} RNID; + +typedef struct _RRQ { /* Structure is in Big Endian format */ + uint32 SID; + ushort Oxid; + ushort Rxid; + uchar resv[32]; /* optional association hdr */ +} RRQ; + + +/* This is used for RSCN command */ +typedef struct _D_ID { /* Structure is in Big Endian format */ + union { + uint32 word; + struct { +#if BIG_ENDIAN_HW + uchar resv; + uchar domain; + uchar area; + uchar id; +#endif +#if LITTLE_ENDIAN_HW + uchar id; + uchar area; + uchar domain; + uchar resv; +#endif + } b; + } un; +} D_ID; + +/* + * Structure to define all ELS Payload types + */ + +typedef struct _ELS_PKT { /* Structure is in Big Endian format */ + uchar elsCode; /* FC Word 0, bit 24:31 */ + uchar elsByte1; + uchar elsByte2; + uchar elsByte3; + union { + LS_RJT lsRjt; /* Payload for LS_RJT ELS response */ + SERV_PARM logi; /* Payload for PLOGI/FLOGI/PDISC/ACC */ + LOGO logo; /* Payload for PLOGO/FLOGO/ACC */ + PRLI prli; /* Payload for PRLI/ACC */ + PRLO prlo; /* Payload for PRLO/ACC */ + ADISC adisc; /* Payload for ADISC/ACC */ + FARP farp; /* Payload for FARP/ACC */ + FAN fan; /* Payload for FAN */ + SCR scr; /* Payload for SCR/ACC */ + RRQ rrq; /* Payload for RRQ */ + RNID rnid; /* Payload for RNID */ + uchar pad[128-4]; /* Pad out to payload of 128 bytes */ + } un; +} ELS_PKT; + + +/* + * Begin Structure Definitions for Mailbox Commands + */ + +typedef struct { +#if BIG_ENDIAN_HW + uchar tval; + uchar tmask; + uchar rval; + uchar rmask; +#endif +#if LITTLE_ENDIAN_HW + uchar rmask; + uchar rval; + uchar tmask; + uchar tval; +#endif +} RR_REG; + +typedef struct { + uint32 bdeAddress; +#if BIG_ENDIAN_HW + u32bit bdeReserved : 4; + u32bit bdeAddrHigh : 4; + u32bit bdeSize : 24; +#endif +#if LITTLE_ENDIAN_HW + u32bit bdeSize : 24; + u32bit bdeAddrHigh : 4; + u32bit bdeReserved : 4; +#endif +} ULP_BDE; + +typedef struct ULP_BDE_64 { /* SLI-2 */ + union ULP_BDE_TUS { + uint32 w; + struct { +#if BIG_ENDIAN_HW + u32bit bdeFlags : 8; + u32bit bdeSize : 24; /* Size of buffer (in bytes) */ +#endif +#if LITTLE_ENDIAN_HW + u32bit bdeSize : 24; /* Size of buffer (in bytes) */ + u32bit bdeFlags : 8; +#endif +#define BUFF_USE_RSVD 0x01 /* bdeFlags */ +#define BUFF_USE_INTRPT 0x02 +#define BUFF_USE_CMND 0x04 /* Optional, 1=cmd/rsp 0=data buffer */ +#define BUFF_USE_RCV 0x08 /* "" "", 1=rcv buffer, 0=xmit buffer */ +#define BUFF_TYPE_32BIT 0x10 /* "" "", 1=32 bit addr 0=64 bit addr */ +#define BUFF_TYPE_SPECIAL 0x20 +#define BUFF_TYPE_BDL 0x40 /* Optional, may be set in BDL */ +#define BUFF_TYPE_INVALID 0x80 /* "" "" */ + } f; + } tus; + uint32 addrLow; + uint32 addrHigh; +} ULP_BDE64; +#define BDE64_SIZE_WORD 0 +#define BPL64_SIZE_WORD 0x40 + +typedef struct ULP_BDL { /* SLI-2 */ +#if BIG_ENDIAN_HW + u32bit bdeFlags : 8; /* BDL Flags */ + u32bit bdeSize : 24; /* Size of BDL array in host memory (bytes) */ +#endif +#if LITTLE_ENDIAN_HW + u32bit bdeSize : 24; /* Size of BDL array in host memory (bytes) */ + u32bit bdeFlags : 8; /* BDL Flags */ +#endif + uint32 addrLow; /* Address 0:31 */ + uint32 addrHigh; /* Address 32:63 */ + uint32 ulpIoTag32; /* Can be used for 32 bit I/O Tag */ +} ULP_BDL; + + +/* Structure for MB Command LOAD_SM and DOWN_LOAD */ + +typedef struct { +#if BIG_ENDIAN_HW + u32bit rsvd2 :25; + u32bit acknowledgment : 1; + u32bit version : 1; + u32bit erase_or_prog : 1; + u32bit update_flash : 1; + u32bit update_ram : 1; + u32bit method : 1; + u32bit load_cmplt : 1; +#endif +#if LITTLE_ENDIAN_HW + u32bit load_cmplt : 1; + u32bit method : 1; + u32bit update_ram : 1; + u32bit update_flash : 1; + u32bit erase_or_prog : 1; + u32bit version : 1; + u32bit acknowledgment : 1; + u32bit rsvd2 :25; +#endif + +#define DL_FROM_BDE 0 /* method */ +#define DL_FROM_SLIM 1 + + uint32 dl_to_adr_low; + uint32 dl_to_adr_high; + uint32 dl_len; + union { + uint32 dl_from_mbx_offset; + ULP_BDE dl_from_bde; + ULP_BDE64 dl_from_bde64; + } un; + +} LOAD_SM_VAR; + + +/* Structure for MB Command READ_NVPARM (02) */ + +typedef struct { + uint32 rsvd1[3]; /* Read as all one's */ + uint32 rsvd2; /* Read as all zero's */ + uint32 portname[2]; /* N_PORT name */ + uint32 nodename[2]; /* NODE name */ +#if BIG_ENDIAN_HW + u32bit pref_DID : 24; + u32bit hardAL_PA : 8; +#endif +#if LITTLE_ENDIAN_HW + u32bit hardAL_PA : 8; + u32bit pref_DID : 24; +#endif + uint32 rsvd3[21]; /* Read as all one's */ +} READ_NV_VAR; + + +/* Structure for MB Command WRITE_NVPARMS (03) */ + +typedef struct { + uint32 rsvd1[3]; /* Must be all one's */ + uint32 rsvd2; /* Must be all zero's */ + uint32 portname[2]; /* N_PORT name */ + uint32 nodename[2]; /* NODE name */ +#if BIG_ENDIAN_HW + u32bit pref_DID : 24; + u32bit hardAL_PA : 8; +#endif +#if LITTLE_ENDIAN_HW + u32bit hardAL_PA : 8; + u32bit pref_DID : 24; +#endif + uint32 rsvd3[21]; /* Must be all one's */ +} WRITE_NV_VAR; + + +/* Structure for MB Command RUN_BIU_DIAG (04) */ +/* Structure for MB Command RUN_BIU_DIAG64 (0x84) */ + +typedef struct { + uint32 rsvd1; + union { + struct { + ULP_BDE xmit_bde; + ULP_BDE rcv_bde; + } s1; + struct { + ULP_BDE64 xmit_bde64; + ULP_BDE64 rcv_bde64; + } s2; + } un; +} BIU_DIAG_VAR; + + +/* Structure for MB Command INIT_LINK (05) */ + +typedef struct { +#if BIG_ENDIAN_HW + u32bit rsvd1 : 24; + u32bit lipsr_AL_PA : 8; /* AL_PA to issue Lip Selective Reset to */ +#endif +#if LITTLE_ENDIAN_HW + u32bit lipsr_AL_PA : 8; /* AL_PA to issue Lip Selective Reset to */ + u32bit rsvd1 : 24; +#endif + +#if BIG_ENDIAN_HW + uchar fabric_AL_PA; /* If using a Fabric Assigned AL_PA */ + uchar rsvd2; + ushort link_flags; +#endif +#if LITTLE_ENDIAN_HW + ushort link_flags; + uchar rsvd2; + uchar fabric_AL_PA; /* If using a Fabric Assigned AL_PA */ +#endif +#define FLAGS_LOCAL_LB 0x01 /* link_flags (=1) ENDEC loopback */ +#define FLAGS_TOPOLOGY_MODE_LOOP_PT 0x00 /* Attempt loop then pt-pt */ +#define FLAGS_TOPOLOGY_MODE_PT_PT 0x02 /* Attempt pt-pt only */ +#define FLAGS_TOPOLOGY_MODE_LOOP 0x04 /* Attempt loop only */ +#define FLAGS_TOPOLOGY_MODE_PT_LOOP 0x06 /* Attempt pt-pt then loop */ +#define FLAGS_LIRP_LILP 0x80 /* LIRP / LILP is disabled */ + +#define FLAGS_TOPOLOGY_FAILOVER 0x0400 /* Bit 10 */ +#define FLAGS_LINK_SPEED 0x0800 /* Bit 11 */ + + uint32 link_speed; +#define LINK_SPEED_AUTO 0 /* Auto selection */ +#define LINK_SPEED_1G 1 /* 1 Gigabaud */ +#define LINK_SPEED_2G 2 /* 2 Gigabaud */ + +} INIT_LINK_VAR; + + +/* Structure for MB Command DOWN_LINK (06) */ + +typedef struct { + uint32 rsvd1; +} DOWN_LINK_VAR; + + +/* Structure for MB Command CONFIG_LINK (07) */ + +typedef struct { +#if BIG_ENDIAN_HW + u32bit cr : 1; + u32bit ci : 1; + u32bit cr_delay : 6; + u32bit cr_count : 8; + u32bit rsvd1 : 8; + u32bit MaxBBC : 8; +#endif +#if LITTLE_ENDIAN_HW + u32bit MaxBBC : 8; + u32bit rsvd1 : 8; + u32bit cr_count : 8; + u32bit cr_delay : 6; + u32bit ci : 1; + u32bit cr : 1; +#endif + uint32 myId; + uint32 rsvd2; + uint32 edtov; + uint32 arbtov; + uint32 ratov; + uint32 rttov; + uint32 altov; + uint32 crtov; + uint32 citov; +#if BIG_ENDIAN_HW + u32bit rrq_enable : 1; + u32bit rrq_immed : 1; + u32bit rsvd4 : 29; + u32bit ack0_enable : 1; +#endif +#if LITTLE_ENDIAN_HW + u32bit ack0_enable : 1; + u32bit rsvd4 : 29; + u32bit rrq_immed : 1; + u32bit rrq_enable : 1; +#endif +} CONFIG_LINK; + + +/* Structure for MB Command PART_SLIM (08) */ + +typedef struct { +#if BIG_ENDIAN_HW + u32bit unused1 : 24; + u32bit numRing : 8; +#endif +#if LITTLE_ENDIAN_HW + u32bit numRing : 8; + u32bit unused1 : 24; +#endif + RING_DEF ringdef[4]; + u32bit hbainit; +} PART_SLIM_VAR; + + +/* Structure for MB Command CONFIG_RING (09) */ + +typedef struct { +#if BIG_ENDIAN_HW + u32bit unused2 : 6; + u32bit recvSeq : 1; + u32bit recvNotify: 1; + u32bit numMask : 8; + u32bit profile : 8; + u32bit unused1 : 4; + u32bit ring : 4; +#endif +#if LITTLE_ENDIAN_HW + u32bit ring : 4; + u32bit unused1 : 4; + u32bit profile : 8; + u32bit numMask : 8; + u32bit recvNotify: 1; + u32bit recvSeq : 1; + u32bit unused2 : 6; +#endif +#if BIG_ENDIAN_HW + ushort maxRespXchg; + ushort maxOrigXchg; +#endif +#if LITTLE_ENDIAN_HW + ushort maxOrigXchg; + ushort maxRespXchg; +#endif + RR_REG rrRegs[6]; +} CONFIG_RING_VAR; + + +/* Structure for MB Command RESET_RING (10) */ + +typedef struct { + uint32 ring_no; +} RESET_RING_VAR; + + +/* Structure for MB Command READ_CONFIG (11) */ + +typedef struct { +#if BIG_ENDIAN_HW + u32bit cr : 1; + u32bit ci : 1; + u32bit cr_delay : 6; + u32bit cr_count : 8; + u32bit InitBBC : 8; + u32bit MaxBBC : 8; +#endif +#if LITTLE_ENDIAN_HW + u32bit MaxBBC : 8; + u32bit InitBBC : 8; + u32bit cr_count : 8; + u32bit cr_delay : 6; + u32bit ci : 1; + u32bit cr : 1; +#endif +#if BIG_ENDIAN_HW + u32bit topology : 8; + u32bit myDid : 24; +#endif +#if LITTLE_ENDIAN_HW + u32bit myDid : 24; + u32bit topology : 8; +#endif + /* Defines for topology (defined previously) */ +#if BIG_ENDIAN_HW + u32bit AR : 1; + u32bit IR : 1; + u32bit rsvd1 : 29; + u32bit ack0 : 1; +#endif +#if LITTLE_ENDIAN_HW + u32bit ack0 : 1; + u32bit rsvd1 : 29; + u32bit IR : 1; + u32bit AR : 1; +#endif + uint32 edtov; + uint32 arbtov; + uint32 ratov; + uint32 rttov; + uint32 altov; + uint32 lmt; +#define LMT_RESERVED 0x0 /* Not used */ +#define LMT_266_10bit 0x1 /* 265.625 Mbaud 10 bit iface */ +#define LMT_532_10bit 0x2 /* 531.25 Mbaud 10 bit iface */ +#define LMT_1063_10bit 0x3 /* 1062.5 Mbaud 20 bit iface */ +#define LMT_2125_10bit 0x8 /* 2125 Mbaud 10 bit iface */ + + uint32 rsvd2; + uint32 rsvd3; + uint32 max_xri; + uint32 max_iocb; + uint32 max_rpi; + uint32 avail_xri; + uint32 avail_iocb; + uint32 avail_rpi; + uint32 default_rpi; +} READ_CONFIG_VAR; + + +/* Structure for MB Command READ_RCONFIG (12) */ + +typedef struct { +#if BIG_ENDIAN_HW + u32bit rsvd2 : 7; + u32bit recvNotify : 1; + u32bit numMask : 8; + u32bit profile : 8; + u32bit rsvd1 : 4; + u32bit ring : 4; +#endif +#if LITTLE_ENDIAN_HW + u32bit ring : 4; + u32bit rsvd1 : 4; + u32bit profile : 8; + u32bit numMask : 8; + u32bit recvNotify : 1; + u32bit rsvd2 : 7; +#endif +#if BIG_ENDIAN_HW + ushort maxResp; + ushort maxOrig; +#endif +#if LITTLE_ENDIAN_HW + ushort maxOrig; + ushort maxResp; +#endif + RR_REG rrRegs[6]; +#if BIG_ENDIAN_HW + ushort cmdRingOffset; + ushort cmdEntryCnt; + ushort rspRingOffset; + ushort rspEntryCnt; + ushort nextCmdOffset; + ushort rsvd3; + ushort nextRspOffset; + ushort rsvd4; +#endif +#if LITTLE_ENDIAN_HW + ushort cmdEntryCnt; + ushort cmdRingOffset; + ushort rspEntryCnt; + ushort rspRingOffset; + ushort rsvd3; + ushort nextCmdOffset; + ushort rsvd4; + ushort nextRspOffset; +#endif +} READ_RCONF_VAR; + + +/* Structure for MB Command READ_SPARM (13) */ +/* Structure for MB Command READ_SPARM64 (0x8D) */ + +typedef struct { + uint32 rsvd1; + uint32 rsvd2; + union { + ULP_BDE sp; /* This BDE points to SERV_PARM structure */ + ULP_BDE64 sp64; + } un; +} READ_SPARM_VAR; + + +/* Structure for MB Command READ_STATUS (14) */ + +typedef struct { +#if BIG_ENDIAN_HW + u32bit rsvd1 : 31; + u32bit clrCounters : 1; + ushort activeXriCnt; + ushort activeRpiCnt; +#endif +#if LITTLE_ENDIAN_HW + u32bit clrCounters : 1; + u32bit rsvd1 : 31; + ushort activeRpiCnt; + ushort activeXriCnt; +#endif + uint32 xmitByteCnt; + uint32 rcvbyteCnt; + uint32 xmitFrameCnt; + uint32 rcvFrameCnt; + uint32 xmitSeqCnt; + uint32 rcvSeqCnt; + uint32 totalOrigExchanges; + uint32 totalRespExchanges; + uint32 rcvPbsyCnt; + uint32 rcvFbsyCnt; +} READ_STATUS_VAR; + + +/* Structure for MB Command READ_RPI (15) */ +/* Structure for MB Command READ_RPI64 (0x8F) */ + +typedef struct { +#if BIG_ENDIAN_HW + ushort nextRpi; + ushort reqRpi; + u32bit rsvd2 : 8; + u32bit DID : 24; +#endif +#if LITTLE_ENDIAN_HW + ushort reqRpi; + ushort nextRpi; + u32bit DID : 24; + u32bit rsvd2 : 8; +#endif + union { + ULP_BDE sp; + ULP_BDE64 sp64; + } un; + +} READ_RPI_VAR; + + +/* Structure for MB Command READ_XRI (16) */ + +typedef struct { +#if BIG_ENDIAN_HW + ushort nextXri; + ushort reqXri; + ushort rsvd1; + ushort rpi; + u32bit rsvd2 : 8; + u32bit DID : 24; + u32bit rsvd3 : 8; + u32bit SID : 24; + uint32 rsvd4; + uchar seqId; + uchar rsvd5; + ushort seqCount; + ushort oxId; + ushort rxId; + u32bit rsvd6 : 30; + u32bit si : 1; + u32bit exchOrig : 1; +#endif +#if LITTLE_ENDIAN_HW + ushort reqXri; + ushort nextXri; + ushort rpi; + ushort rsvd1; + u32bit DID : 24; + u32bit rsvd2 : 8; + u32bit SID : 24; + u32bit rsvd3 : 8; + uint32 rsvd4; + ushort seqCount; + uchar rsvd5; + uchar seqId; + ushort rxId; + ushort oxId; + u32bit exchOrig : 1; + u32bit si : 1; + u32bit rsvd6 : 30; +#endif +} READ_XRI_VAR; + + +/* Structure for MB Command READ_REV (17) */ + +typedef struct { +#if BIG_ENDIAN_HW + u32bit cv : 1; + u32bit rr : 1; + u32bit rsvd1 : 29; + u32bit rv : 1; +#endif +#if LITTLE_ENDIAN_HW + u32bit rv : 1; + u32bit rsvd1 : 29; + u32bit rr : 1; + u32bit cv : 1; +#endif + uint32 biuRev; + uint32 smRev; + union { + uint32 smFwRev; + struct { +#if BIG_ENDIAN_HW + uchar ProgType; + uchar ProgId; + u16bit ProgVer : 4; + u16bit ProgRev : 4; + u16bit ProgFixLvl : 2; + u16bit ProgDistType : 2; + u16bit DistCnt : 4; +#endif +#if LITTLE_ENDIAN_HW + u16bit DistCnt : 4; + u16bit ProgDistType : 2; + u16bit ProgFixLvl : 2; + u16bit ProgRev : 4; + u16bit ProgVer : 4; + uchar ProgId; + uchar ProgType; +#endif + } b; + } un; + uint32 endecRev; +#if BIG_ENDIAN_HW + uchar feaLevelHigh; + uchar feaLevelLow; + uchar fcphHigh; + uchar fcphLow; +#endif +#if LITTLE_ENDIAN_HW + uchar fcphLow; + uchar fcphHigh; + uchar feaLevelLow; + uchar feaLevelHigh; +#endif + uint32 postKernRev; + uint32 opFwRev; + uchar opFwName[16]; + uint32 sli1FwRev; + uchar sli1FwName[16]; + uint32 sli2FwRev; + uchar sli2FwName[16]; + uint32 rsvd2; + uint32 RandomData[7]; +} READ_REV_VAR; + +#define rxSeqRev postKernRev +#define txSeqRev opFwRev + +/* Structure for MB Command READ_LINK_STAT (18) */ + +typedef struct { + uint32 rsvd1; + uint32 linkFailureCnt; + uint32 lossSyncCnt; + + uint32 lossSignalCnt; + uint32 primSeqErrCnt; + uint32 invalidXmitWord; + uint32 crcCnt; + uint32 primSeqTimeout; + uint32 elasticOverrun; + uint32 arbTimeout; +} READ_LNK_VAR; + + +/* Structure for MB Command REG_LOGIN (19) */ +/* Structure for MB Command REG_LOGIN64 (0x93) */ + +typedef struct { +#if BIG_ENDIAN_HW + ushort rsvd1; + ushort rpi; + u32bit rsvd2 : 8; + u32bit did : 24; +#endif +#if LITTLE_ENDIAN_HW + ushort rpi; + ushort rsvd1; + u32bit did : 24; + u32bit rsvd2 : 8; +#endif + union { + ULP_BDE sp; + ULP_BDE64 sp64; + } un; + +} REG_LOGIN_VAR; + +/* Word 30 contents for REG_LOGIN */ +typedef union { + struct { +#if BIG_ENDIAN_HW + u16bit rsvd1 : 12; + u16bit class : 4; + ushort xri; +#endif +#if LITTLE_ENDIAN_HW + ushort xri; + u16bit class : 4; + u16bit rsvd1 : 12; +#endif + } f; + uint32 word; +} REG_WD30; + + +/* Structure for MB Command UNREG_LOGIN (20) */ + +typedef struct { +#if BIG_ENDIAN_HW + ushort rsvd1; + ushort rpi; +#endif +#if LITTLE_ENDIAN_HW + ushort rpi; + ushort rsvd1; +#endif +} UNREG_LOGIN_VAR; + + +/* Structure for MB Command UNREG_D_ID (0x23) */ + +typedef struct { + uint32 did; +} UNREG_D_ID_VAR; + + +/* Structure for MB Command READ_LA (21) */ +/* Structure for MB Command READ_LA64 (0x95) */ + +typedef struct { + uint32 eventTag; /* Event tag */ +#if BIG_ENDIAN_HW + u32bit rsvd1 : 22; + u32bit pb : 1; + u32bit il : 1; + u32bit attType : 8; +#endif +#if LITTLE_ENDIAN_HW + u32bit attType : 8; + u32bit il : 1; + u32bit pb : 1; + u32bit rsvd1 : 22; +#endif +#define AT_RESERVED 0x00 /* Reserved - attType */ +#define AT_LINK_UP 0x01 /* Link is up */ +#define AT_LINK_DOWN 0x02 /* Link is down */ +#if BIG_ENDIAN_HW + uchar granted_AL_PA; + uchar lipAlPs; + uchar lipType; + uchar topology; +#endif +#if LITTLE_ENDIAN_HW + uchar topology; + uchar lipType; + uchar lipAlPs; + uchar granted_AL_PA; +#endif +#define LT_PORT_INIT 0x00 /* An L_PORT initing (F7, AL_PS) - lipType */ +#define LT_PORT_ERR 0x01 /* Err @L_PORT rcv'er (F8, AL_PS) */ +#define LT_RESET_APORT 0x02 /* Lip Reset of some other port */ +#define LT_RESET_MYPORT 0x03 /* Lip Reset of my port */ +#define TOPOLOGY_PT_PT 0x01 /* Topology is pt-pt / pt-fabric */ +#define TOPOLOGY_LOOP 0x02 /* Topology is FC-AL */ + + union { + ULP_BDE lilpBde; /* This BDE points to a 128 byte buffer to */ + /* store the LILP AL_PA position map into */ + ULP_BDE64 lilpBde64; + } un; +#if BIG_ENDIAN_HW + u32bit Dlu : 1; + u32bit Dtf : 1; + u32bit Drsvd2 : 14; + u32bit DlnkSpeed : 8; + u32bit DnlPort : 4; + u32bit Dtx : 2; + u32bit Drx : 2; +#endif +#if LITTLE_ENDIAN_HW + u32bit Drx : 2; + u32bit Dtx : 2; + u32bit DnlPort : 4; + u32bit DlnkSpeed : 8; + u32bit Drsvd2 : 14; + u32bit Dtf : 1; + u32bit Dlu : 1; +#endif +#if BIG_ENDIAN_HW + u32bit Ulu : 1; + u32bit Utf : 1; + u32bit Ursvd2 : 14; + u32bit UlnkSpeed : 8; + u32bit UnlPort : 4; + u32bit Utx : 2; + u32bit Urx : 2; +#endif +#if LITTLE_ENDIAN_HW + u32bit Urx : 2; + u32bit Utx : 2; + u32bit UnlPort : 4; + u32bit UlnkSpeed : 8; + u32bit Ursvd2 : 14; + u32bit Utf : 1; + u32bit Ulu : 1; +#endif +#define LA_1GHZ_LINK 4 /* lnkSpeed */ +#define LA_2GHZ_LINK 8 /* lnkSpeed */ + +} READ_LA_VAR; + + +/* Structure for MB Command CLEAR_LA (22) */ + +typedef struct { + uint32 eventTag; /* Event tag */ + uint32 rsvd1; +} CLEAR_LA_VAR; + +/* Structure for MB Command DUMP */ + +typedef struct { +#if BIG_ENDIAN_HW + u32bit rsvd : 25 ; + u32bit ra : 1 ; + u32bit co : 1 ; + u32bit cv : 1 ; + u32bit type : 4 ; + u32bit entry_index : 16 ; + u32bit region_id : 16 ; +#endif +#if LITTLE_ENDIAN_HW + u32bit type : 4 ; + u32bit cv : 1 ; + u32bit co : 1 ; + u32bit ra : 1 ; + u32bit rsvd : 25 ; + u32bit region_id : 16 ; + u32bit entry_index : 16 ; +#endif + uint32 rsvd1; + uint32 word_cnt ; + uint32 resp_offset ; +} DUMP_VAR ; + +#define DMP_MEM_REG 0x1 +#define DMP_NV_PARAMS 0x2 + +#define DMP_REGION_VPD 0xe +#define DMP_VPD_SIZE 0x100 + +/* Structure for MB Command CONFIG_PORT (0x88) */ + +typedef struct { + uint32 pcbLen; + uint32 pcbLow; /* bit 31:0 of memory based port config block */ + uint32 pcbHigh; /* bit 63:32 of memory based port config block */ + uint32 hbainit[5]; +} CONFIG_PORT_VAR; + + +/* SLI-2 Port Control Block */ + +/* SLIM POINTER */ +#define SLIMOFF 0x30 /* WORD */ + +typedef struct _SLI2_RDSC { + uint32 cmdEntries; + uint32 cmdAddrLow; + uint32 cmdAddrHigh; + + uint32 rspEntries; + uint32 rspAddrLow; + uint32 rspAddrHigh; +} SLI2_RDSC; + +typedef struct _PCB { +#if BIG_ENDIAN_HW + u32bit type : 8; +#define TYPE_NATIVE_SLI2 0x01; + u32bit feature : 8; +#define FEATURE_INITIAL_SLI2 0x01; + u32bit rsvd : 12; + u32bit maxRing : 4; +#endif +#if LITTLE_ENDIAN_HW + u32bit maxRing : 4; + u32bit rsvd : 12; + u32bit feature : 8; +#define FEATURE_INITIAL_SLI2 0x01; + u32bit type : 8; +#define TYPE_NATIVE_SLI2 0x01; +#endif + + uint32 mailBoxSize; + uint32 mbAddrLow; + uint32 mbAddrHigh; + + uint32 hgpAddrLow; + uint32 hgpAddrHigh; + + uint32 pgpAddrLow; + uint32 pgpAddrHigh; + SLI2_RDSC rdsc[ MAX_RINGS]; +} PCB; + +typedef struct { +#if BIG_ENDIAN_HW + u32bit rsvd0 : 27; + u32bit discardFarp : 1; + u32bit IPEnable : 1; + u32bit nodeName : 1; + u32bit portName : 1; + u32bit filterEnable : 1; +#endif +#if LITTLE_ENDIAN_HW + u32bit filterEnable : 1; + u32bit portName : 1; + u32bit nodeName : 1; + u32bit IPEnable : 1; + u32bit discardFarp : 1; + u32bit rsvd : 27; +#endif + NAME_TYPE portname; + NAME_TYPE nodename; + uint32 rsvd1; + uint32 rsvd2; + uint32 rsvd3; + uint32 IPAddress; +} CONFIG_FARP_VAR; + + +/* Union of all Mailbox Command types */ + +typedef union { + uint32 varWords[31]; + LOAD_SM_VAR varLdSM; /* cmd = 1 (LOAD_SM) */ + READ_NV_VAR varRDnvp; /* cmd = 2 (READ_NVPARMS) */ + WRITE_NV_VAR varWTnvp; /* cmd = 3 (WRITE_NVPARMS) */ + BIU_DIAG_VAR varBIUdiag; /* cmd = 4 (RUN_BIU_DIAG) */ + INIT_LINK_VAR varInitLnk; /* cmd = 5 (INIT_LINK) */ + DOWN_LINK_VAR varDwnLnk; /* cmd = 6 (DOWN_LINK) */ + CONFIG_LINK varCfgLnk; /* cmd = 7 (CONFIG_LINK) */ + PART_SLIM_VAR varSlim; /* cmd = 8 (PART_SLIM) */ + CONFIG_RING_VAR varCfgRing; /* cmd = 9 (CONFIG_RING) */ + RESET_RING_VAR varRstRing; /* cmd = 10 (RESET_RING) */ + READ_CONFIG_VAR varRdConfig; /* cmd = 11 (READ_CONFIG) */ + READ_RCONF_VAR varRdRConfig; /* cmd = 12 (READ_RCONFIG) */ + READ_SPARM_VAR varRdSparm; /* cmd = 13 (READ_SPARM(64)) */ + READ_STATUS_VAR varRdStatus; /* cmd = 14 (READ_STATUS) */ + READ_RPI_VAR varRdRPI; /* cmd = 15 (READ_RPI(64)) */ + READ_XRI_VAR varRdXRI; /* cmd = 16 (READ_XRI) */ + READ_REV_VAR varRdRev; /* cmd = 17 (READ_REV) */ + READ_LNK_VAR varRdLnk; /* cmd = 18 (READ_LNK_STAT) */ + REG_LOGIN_VAR varRegLogin; /* cmd = 19 (REG_LOGIN(64)) */ + UNREG_LOGIN_VAR varUnregLogin; /* cmd = 20 (UNREG_LOGIN) */ + READ_LA_VAR varReadLA; /* cmd = 21 (READ_LA(64)) */ + CLEAR_LA_VAR varClearLA; /* cmd = 22 (CLEAR_LA) */ + DUMP_VAR varDmp ; /* Warm Start DUMP mbx cmd */ + UNREG_D_ID_VAR varUnregDID; /* cmd = 0x23 (UNREG_D_ID) */ + CONFIG_PORT_VAR varCfgPort; /* cmd = 0x88 (CONFIG_PORT) */ + CONFIG_FARP_VAR varCfgFarp; /* cmd = 0x25 (CONFIG_FARP) */ +} MAILVARIANTS; + +#define MAILBOX_CMD_WSIZE 32 + +/* + * SLI-2 specific structures + */ + +typedef struct _SLI1_DESC { + RINGS mbxCring[ 4]; + uint32 mbxUnused[ 24]; +} SLI1_DESC; + +typedef struct { + uint32 cmdPutInx; + uint32 rspGetInx; +} HGP; + +typedef struct { + uint32 cmdGetInx; + uint32 rspPutInx; +} PGP; + +typedef struct _SLI2_DESC { + HGP host[ MAX_RINGS]; + uint32 unused[ 16]; + PGP port[ MAX_RINGS]; +} SLI2_DESC; + +typedef union { + SLI1_DESC s1; + SLI2_DESC s2; +} SLI_VAR; + +typedef volatile struct { +#if BIG_ENDIAN_HW + ushort mbxStatus; + uchar mbxCommand; + u8bit mbxReserved : 6; + u8bit mbxHc : 1; + u8bit mbxOwner : 1; /* Low order bit first word */ +#endif +#if LITTLE_ENDIAN_HW + u8bit mbxOwner : 1; /* Low order bit first word */ + u8bit mbxHc : 1; + u8bit mbxReserved : 6; + uchar mbxCommand; + ushort mbxStatus; +#endif + MAILVARIANTS un; + SLI_VAR us; +} MAILBOX, *PMAILBOX; + +/* + * End Structure Definitions for Mailbox Commands + */ + + +/* + * Begin Structure Definitions for IOCB Commands + */ + +typedef struct { +#if BIG_ENDIAN_HW + uchar statAction; + uchar statRsn; + uchar statBaExp; + uchar statLocalError; +#endif +#if LITTLE_ENDIAN_HW + uchar statLocalError; + uchar statBaExp; + uchar statRsn; + uchar statAction; +#endif + /* statAction FBSY reason codes */ +#define FBSY_RSN_MASK 0xF0 /* Rsn stored in upper nibble */ +#define FBSY_FABRIC_BSY 0x10 /* F_bsy due to Fabric BSY */ +#define FBSY_NPORT_BSY 0x30 /* F_bsy due to N_port BSY */ + + /* statAction PBSY action codes */ +#define PBSY_ACTION1 0x01 /* Sequence terminated - retry */ +#define PBSY_ACTION2 0x02 /* Sequence active - retry */ + + /* statAction P/FRJT action codes */ +#define RJT_RETRYABLE 0x01 /* Retryable class of error */ +#define RJT_NO_RETRY 0x02 /* Non-Retryable class of error */ + + /* statRsn LS_RJT reason codes defined in LS_RJT structure */ + + /* statRsn P_BSY reason codes */ +#define PBSY_NPORT_BSY 0x01 /* Physical N_port BSY */ +#define PBSY_RESRCE_BSY 0x03 /* N_port resource BSY */ +#define PBSY_VU_BSY 0xFF /* See VU field for rsn */ + + /* statRsn P/F_RJT reason codes */ +#define RJT_BAD_D_ID 0x01 /* Invalid D_ID field */ +#define RJT_BAD_S_ID 0x02 /* Invalid S_ID field */ +#define RJT_UNAVAIL_TEMP 0x03 /* N_Port unavailable temp. */ +#define RJT_UNAVAIL_PERM 0x04 /* N_Port unavailable perm. */ +#define RJT_UNSUP_CLASS 0x05 /* Class not supported */ +#define RJT_DELIM_ERR 0x06 /* Delimiter usage error */ +#define RJT_UNSUP_TYPE 0x07 /* Type not supported */ +#define RJT_BAD_CONTROL 0x08 /* Invalid link conrtol */ +#define RJT_BAD_RCTL 0x09 /* R_CTL invalid */ +#define RJT_BAD_FCTL 0x0A /* F_CTL invalid */ +#define RJT_BAD_OXID 0x0B /* OX_ID invalid */ +#define RJT_BAD_RXID 0x0C /* RX_ID invalid */ +#define RJT_BAD_SEQID 0x0D /* SEQ_ID invalid */ +#define RJT_BAD_DFCTL 0x0E /* DF_CTL invalid */ +#define RJT_BAD_SEQCNT 0x0F /* SEQ_CNT invalid */ +#define RJT_BAD_PARM 0x10 /* Param. field invalid */ +#define RJT_XCHG_ERR 0x11 /* Exchange error */ +#define RJT_PROT_ERR 0x12 /* Protocol error */ +#define RJT_BAD_LENGTH 0x13 /* Invalid Length */ +#define RJT_UNEXPECTED_ACK 0x14 /* Unexpected ACK */ +#define RJT_LOGIN_REQUIRED 0x16 /* Login required */ +#define RJT_TOO_MANY_SEQ 0x17 /* Excessive sequences */ +#define RJT_XCHG_NOT_STRT 0x18 /* Exchange not started */ +#define RJT_UNSUP_SEC_HDR 0x19 /* Security hdr not supported */ +#define RJT_UNAVAIL_PATH 0x1A /* Fabric Path not available */ +#define RJT_VENDOR_UNIQUE 0xFF /* Vendor unique error */ + + /* statRsn BA_RJT reason codes */ +#define BARJT_BAD_CMD_CODE 0x01 /* Invalid command code */ +#define BARJT_LOGICAL_ERR 0x03 /* Logical error */ +#define BARJT_LOGICAL_BSY 0x05 /* Logical busy */ +#define BARJT_PROTOCOL_ERR 0x07 /* Protocol error */ +#define BARJT_VU_ERR 0xFF /* Vendor unique error */ + + /* LS_RJT reason explanation defined in LS_RJT structure */ + + /* BA_RJT reason explanation */ +#define BARJT_EXP_INVALID_ID 0x01 /* Invalid OX_ID/RX_ID */ +#define BARJT_EXP_ABORT_SEQ 0x05 /* Abort SEQ, no more info */ + + /* Localy detected errors */ +#define IOERR_SUCCESS 0x00 /* statLocalError */ +#define IOERR_MISSING_CONTINUE 0x01 +#define IOERR_SEQUENCE_TIMEOUT 0x02 +#define IOERR_INTERNAL_ERROR 0x03 +#define IOERR_INVALID_RPI 0x04 +#define IOERR_NO_XRI 0x05 +#define IOERR_ILLEGAL_COMMAND 0x06 +#define IOERR_XCHG_DROPPED 0x07 +#define IOERR_ILLEGAL_FIELD 0x08 +#define IOERR_BAD_CONTINUE 0x09 +#define IOERR_TOO_MANY_BUFFERS 0x0A +#define IOERR_RCV_BUFFER_WAITING 0x0B +#define IOERR_NO_CONNECTION 0x0C +#define IOERR_TX_DMA_FAILED 0x0D +#define IOERR_RX_DMA_FAILED 0x0E +#define IOERR_ILLEGAL_FRAME 0x0F +#define IOERR_EXTRA_DATA 0x10 +#define IOERR_NO_RESOURCES 0x11 +#define IOERR_RESERVED 0x12 +#define IOERR_ILLEGAL_LENGTH 0x13 +#define IOERR_UNSUPPORTED_FEATURE 0x14 +#define IOERR_ABORT_IN_PROGRESS 0x15 +#define IOERR_ABORT_REQUESTED 0x16 +#define IOERR_RECEIVE_BUFFER_TIMEOUT 0x17 +#define IOERR_LOOP_OPEN_FAILURE 0x18 +#define IOERR_RING_RESET 0x19 +#define IOERR_LINK_DOWN 0x1A +#define IOERR_CORRUPTED_DATA 0x1B +#define IOERR_CORRUPTED_RPI 0x1C +#define IOERR_OUT_OF_ORDER_DATA 0x1D +#define IOERR_OUT_OF_ORDER_ACK 0x1E +#define IOERR_DUP_FRAME 0x1F +#define IOERR_LINK_CONTROL_FRAME 0x20 /* ACK_N received */ +#define IOERR_BAD_HOST_ADDRESS 0x21 +#define IOERR_RCV_HDRBUF_WAITING 0x22 +#define IOERR_MISSING_HDR_BUFFER 0x23 +#define IOERR_MSEQ_CHAIN_CORRUPTED 0x24 +#define IOERR_ABORTMULT_REQUESTED 0x25 +#define IOERR_BUFFER_SHORTAGE 0x28 +} PARM_ERR; + +typedef union { + struct { +#if BIG_ENDIAN_HW + uchar Rctl; /* R_CTL field */ + uchar Type; /* TYPE field */ + uchar Dfctl; /* DF_CTL field */ + uchar Fctl; /* Bits 0-7 of IOCB word 5 */ +#endif +#if LITTLE_ENDIAN_HW + uchar Fctl; /* Bits 0-7 of IOCB word 5 */ + uchar Dfctl; /* DF_CTL field */ + uchar Type; /* TYPE field */ + uchar Rctl; /* R_CTL field */ +#endif + +#define BC 0x02 /* Broadcast Received - Fctl */ +#define SI 0x04 /* Sequence Initiative */ +#define LA 0x08 /* Ignore Link Attention state */ +#define LS 0x80 /* Last Sequence */ + } hcsw; + uint32 reserved; +} WORD5; + + +/* IOCB Command template for a generic response */ +typedef struct { + uint32 reserved[4]; + PARM_ERR perr; +} GENERIC_RSP; + + +/* IOCB Command template for XMIT / XMIT_BCAST / RCV_SEQUENCE / XMIT_ELS */ +typedef struct { + ULP_BDE xrsqbde[2]; + uint32 xrsqRo; /* Starting Relative Offset */ + WORD5 w5; /* Header control/status word */ +} XR_SEQ_FIELDS; + +/* IOCB Command template for ELS_REQUEST */ +typedef struct { + ULP_BDE elsReq; + ULP_BDE elsRsp; +#if BIG_ENDIAN_HW + u32bit word4Rsvd : 7; + u32bit fl : 1; + u32bit myID : 24; + u32bit word5Rsvd : 8; + u32bit remoteID : 24; +#endif +#if LITTLE_ENDIAN_HW + u32bit myID : 24; + u32bit fl : 1; + u32bit word4Rsvd : 7; + u32bit remoteID : 24; + u32bit word5Rsvd : 8; +#endif +} ELS_REQUEST; + +/* IOCB Command template for RCV_ELS_REQ */ +typedef struct { + ULP_BDE elsReq[2]; + uint32 parmRo; +#if BIG_ENDIAN_HW + u32bit word5Rsvd : 8; + u32bit remoteID : 24; +#endif +#if LITTLE_ENDIAN_HW + u32bit remoteID : 24; + u32bit word5Rsvd : 8; +#endif +} RCV_ELS_REQ; + +/* IOCB Command template for ABORT / CLOSE_XRI */ +typedef struct { + uint32 rsvd[3]; + uint32 abortType; +#define ABORT_TYPE_ABTX 0x00000000 +#define ABORT_TYPE_ABTS 0x00000001 + uint32 parm; +#if BIG_ENDIAN_HW + ushort abortContextTag; /* ulpContext from command to abort/close */ + ushort abortIoTag; /* ulpIoTag from command to abort/close */ +#endif +#if LITTLE_ENDIAN_HW + ushort abortIoTag; /* ulpIoTag from command to abort/close */ + ushort abortContextTag; /* ulpContext from command to abort/close */ +#endif +} AC_XRI; + +/* IOCB Command template for GET_RPI */ +typedef struct { + uint32 rsvd[4]; + uint32 parmRo; +#if BIG_ENDIAN_HW + u32bit word5Rsvd : 8; + u32bit remoteID : 24; +#endif +#if LITTLE_ENDIAN_HW + u32bit remoteID : 24; + u32bit word5Rsvd : 8; +#endif +} GET_RPI; + +/* IOCB Command template for all FCPI commands */ +typedef struct { + ULP_BDE fcpi_cmnd; /* FCP_CMND payload descriptor */ + ULP_BDE fcpi_rsp; /* Rcv buffer */ + uint32 fcpi_parm; + uint32 fcpi_XRdy; /* transfer ready for IWRITE */ +} FCPI_FIELDS; + +/* IOCB Command template for all FCPT commands */ +typedef struct { + ULP_BDE fcpt_Buffer[2]; /* FCP_CMND payload descriptor */ + uint32 fcpt_Offset; + uint32 fcpt_Length; /* transfer ready for IWRITE */ +} FCPT_FIELDS; + +/* SLI-2 IOCB structure definitions */ + +/* IOCB Command template for 64 bit XMIT / XMIT_BCAST / XMIT_ELS */ +typedef struct { + ULP_BDL bdl; + uint32 xrsqRo; /* Starting Relative Offset */ + WORD5 w5; /* Header control/status word */ +} XMT_SEQ_FIELDS64; + +/* IOCB Command template for 64 bit RCV_SEQUENCE64 */ +typedef struct { + ULP_BDE64 rcvBde; + uint32 rsvd1; + uint32 xrsqRo; /* Starting Relative Offset */ + WORD5 w5; /* Header control/status word */ +} RCV_SEQ_FIELDS64; + +/* IOCB Command template for ELS_REQUEST64 */ +typedef struct { + ULP_BDL bdl; +#if BIG_ENDIAN_HW + u32bit word4Rsvd : 7; + u32bit fl : 1; + u32bit myID : 24; + u32bit word5Rsvd : 8; + u32bit remoteID : 24; +#endif +#if LITTLE_ENDIAN_HW + u32bit myID : 24; + u32bit fl : 1; + u32bit word4Rsvd : 7; + u32bit remoteID : 24; + u32bit word5Rsvd : 8; +#endif +} ELS_REQUEST64; + +/* IOCB Command template for GEN_REQUEST64 */ +typedef struct { + ULP_BDL bdl; + uint32 xrsqRo; /* Starting Relative Offset */ + WORD5 w5; /* Header control/status word */ +} GEN_REQUEST64; + +/* IOCB Command template for RCV_ELS_REQ64 */ +typedef struct { + ULP_BDE64 elsReq; + uint32 rcvd1; + uint32 parmRo; +#if BIG_ENDIAN_HW + u32bit word5Rsvd : 8; + u32bit remoteID : 24; +#endif +#if LITTLE_ENDIAN_HW + u32bit remoteID : 24; + u32bit word5Rsvd : 8; +#endif +} RCV_ELS_REQ64; + +/* IOCB Command template for all 64 bit FCPI commands */ +typedef struct { + ULP_BDL bdl; + uint32 fcpi_parm; + uint32 fcpi_XRdy; /* transfer ready for IWRITE */ +} FCPI_FIELDS64; + +/* IOCB Command template for all 64 bit FCPT commands */ +typedef struct { + ULP_BDL bdl; + uint32 fcpt_Offset; + uint32 fcpt_Length; /* transfer ready for IWRITE */ +} FCPT_FIELDS64; + +typedef volatile struct _IOCB { /* IOCB structure */ + union { + GENERIC_RSP grsp; /* Generic response */ + XR_SEQ_FIELDS xrseq; /* XMIT / BCAST / RCV_SEQUENCE cmd */ + ULP_BDE cont[3]; /* up to 3 continuation bdes */ + ELS_REQUEST elsreq; /* ELS_REQUEST template */ + RCV_ELS_REQ rcvels; /* RCV_ELS_REQ template */ + AC_XRI acxri; /* ABORT / CLOSE_XRI template */ + GET_RPI getrpi; /* GET_RPI template */ + FCPI_FIELDS fcpi; /* FCPI template */ + FCPT_FIELDS fcpt; /* FCPT template */ + + /* SLI-2 structures */ + + ULP_BDE64 cont64[ 2]; /* up to 2 64 bit continuation bde_64s */ + ELS_REQUEST64 elsreq64; /* ELS_REQUEST template */ + GEN_REQUEST64 genreq64; /* GEN_REQUEST template */ + RCV_ELS_REQ64 rcvels64; /* RCV_ELS_REQ template */ + XMT_SEQ_FIELDS64 xseq64; /* XMIT / BCAST cmd */ + FCPI_FIELDS64 fcpi64; /* FCPI 64 bit template */ + FCPT_FIELDS64 fcpt64; /* FCPT 64 bit template */ + + uint32 ulpWord[IOCB_WORD_SZ-2]; /* generic 6 'words' */ + } un; + union { + struct { +#if BIG_ENDIAN_HW + ushort ulpContext; /* High order bits word 6 */ + ushort ulpIoTag; /* Low order bits word 6 */ +#endif +#if LITTLE_ENDIAN_HW + ushort ulpIoTag; /* Low order bits word 6 */ + ushort ulpContext; /* High order bits word 6 */ +#endif + } t1; + struct { +#if BIG_ENDIAN_HW + ushort ulpContext; /* High order bits word 6 */ + u16bit ulpIoTag1 : 2; /* Low order bits word 6 */ + u16bit ulpIoTag0 : 14; /* Low order bits word 6 */ +#endif +#if LITTLE_ENDIAN_HW + u16bit ulpIoTag0 : 14; /* Low order bits word 6 */ + u16bit ulpIoTag1 : 2; /* Low order bits word 6 */ + ushort ulpContext; /* High order bits word 6 */ +#endif + } t2; + } un1; +#define ulpContext un1.t1.ulpContext +#define ulpIoTag un1.t1.ulpIoTag +#define ulpIoTag0 un1.t2.ulpIoTag0 +#define ulpDelayXmit un1.t2.ulpIoTag1 +#define IOCB_DELAYXMIT_MSK 0x3000 +#if BIG_ENDIAN_HW + u32bit ulpRsvdByte : 8; + u32bit ulpXS : 1; + u32bit ulpFCP2Rcvy : 1; + u32bit ulpPU : 2; + u32bit ulpIr : 1; + u32bit ulpClass : 3; + u32bit ulpCommand : 8; + u32bit ulpStatus : 4; + u32bit ulpBdeCount : 2; + u32bit ulpLe : 1; + u32bit ulpOwner : 1; /* Low order bit word 7 */ +#endif +#if LITTLE_ENDIAN_HW + u32bit ulpOwner : 1; /* Low order bit word 7 */ + u32bit ulpLe : 1; + u32bit ulpBdeCount : 2; + u32bit ulpStatus : 4; + u32bit ulpCommand : 8; + u32bit ulpClass : 3; + u32bit ulpIr : 1; + u32bit ulpPU : 2; + u32bit ulpFCP2Rcvy : 1; + u32bit ulpXS : 1; + u32bit ulpRsvdByte : 8; +#endif + +#define ulpTimeout ulpRsvdByte + +#define IOCB_FCP 1 /* IOCB is used for FCP ELS cmds - ulpRsvByte */ +#define IOCB_IP 2 /* IOCB is used for IP ELS cmds */ +#define PARM_UNUSED 0 /* PU field (Word 4) not used */ +#define PARM_REL_OFF 1 /* PU field (Word 4) = R. O. */ +#define PARM_READ_CHECK 2 /* PU field (Word 4) = Data Transfer Length */ +#define CLASS1 0 /* Class 1 */ +#define CLASS2 1 /* Class 2 */ +#define CLASS3 2 /* Class 3 */ +#define CLASS_FCP_INTERMIX 7 /* FCP Data->Cls 1, all else->Cls 2 */ + +#define IOSTAT_SUCCESS 0x0 /* ulpStatus */ +#define IOSTAT_FCP_RSP_ERROR 0x1 +#define IOSTAT_REMOTE_STOP 0x2 +#define IOSTAT_LOCAL_REJECT 0x3 +#define IOSTAT_NPORT_RJT 0x4 +#define IOSTAT_FABRIC_RJT 0x5 +#define IOSTAT_NPORT_BSY 0x6 +#define IOSTAT_FABRIC_BSY 0x7 +#define IOSTAT_INTERMED_RSP 0x8 +#define IOSTAT_LS_RJT 0x9 +#define IOSTAT_BA_RJT 0xA + +} IOCB, *PIOCB; + +typedef struct { + IOCB iocb; /* iocb entry */ + uchar * q; /* ptr to next iocb entry */ + uchar * bp; /* ptr to data buffer structure */ + uchar * info; /* ptr to data information structure */ + uchar * bpl; /* ptr to data BPL structure */ + uchar * ndlp; /* ptr to the ndlp structure */ + uchar retry; /* retry counter for IOCB cmd - if needed */ + uchar rsvd1; + ushort rsvd2; +} IOCBQ; + +typedef struct { + volatile uint32 mb[MAILBOX_CMD_WSIZE]; + uchar * q; + uchar * bp; /* ptr to data buffer structure */ +} MAILBOXQ; + +/* Given a pointer to the start of the ring, and the slot number of + * the desired iocb entry, calc a pointer to that entry. + */ +#define IOCB_ENTRY(ring,slot) ((IOCB *)(((uchar *)((ulong)ring)) + (((uint32)((ulong)slot))<< 5))) + +/* + * End Structure Definitions for IOCB Commands + */ + +typedef struct { + MAILBOX mbx; + IOCB IOCBs[MAX_BIOCB]; +} SLIM; + +typedef struct { + MAILBOX mbx; + PCB pcb; + IOCB IOCBs[MAX_SLI2_IOCB]; +} SLI2_SLIM; + +/* +* FDMI +* HBA MAnagement Operations Command Codes +*/ +#define SLI_MGMT_GRHL 0x100 /* Get registered HBA list */ +#define SLI_MGMT_GHAT 0x101 /* Get HBA attributes */ +#define SLI_MGMT_GRPL 0x102 /* Get registered Port list */ +#define SLI_MGMT_GPAT 0x110 /* Get Port attributes */ +#define SLI_MGMT_RHBA 0x200 /* Register HBA */ +#define SLI_MGMT_RHAT 0x201 /* Register HBA atttributes */ +#define SLI_MGMT_RPRT 0x210 /* Register Port */ +#define SLI_MGMT_RPA 0x211 /* Register Port attributes */ +#define SLI_MGMT_DHBA 0x300 /* De-register HBA */ +#define SLI_MGMT_DPRT 0x310 /* De-register Port */ + +/* + * Management Service Subtypes + */ +#define SLI_CT_FDMI_Subtypes 0x10 + +/* + * HBA Management Service Reject Code + */ +#define REJECT_CODE 0x9 /* Unable to perform command request */ +/* + * HBA Management Service Reject Reason Code + * Please refer to the Reason Codes above + */ + +/* + * HBA Attribute Types + */ +#define NODE_NAME 0x1 +#define MANUFACTURER 0x2 +#define SERIAL_NUMBER 0x3 +#define MODEL 0x4 +#define MODEL_DESCRIPTION 0x5 +#define HARDWARE_VERSION 0x6 +#define DRIVER_VERSION 0x7 +#define OPTION_ROM_VERSION 0x8 +#define FIRMWARE_VERSION 0x9 +#define VENDOR_SPECIFIC 0xa +#define DRIVER_NAME 0xb +#define OS_NAME_VERSION 0xc +#define MAX_CT_PAYLOAD_LEN 0xd + +/* + * Port Attrubute Types + */ +#define SUPPORTED_FC4_TYPES 0x1 +#define SUPPORTED_SPEED 0x2 +#define PORT_SPEED 0x3 +#define MAX_FRAME_SIZE 0x4 +#define OS_DEVICE_NAME 0x5 + +union AttributesDef { + /* Structure is in Big Endian format */ + struct { + u32bit AttrType: 16; + u32bit AttrLen: 16; + } bits; + uint32 word; +}; + +/* + * HBA Attribute Entry (8 - 260 bytes) + */ +typedef struct +{ + union AttributesDef ad; + union { + uint32 VendorSpecific; + uint32 SupportSpeed; + uint32 PortSpeed; + uint32 MaxFrameSize; + uint32 MaxCTPayloadLen; + uchar SupportFC4Types[32]; + uchar OsDeviceName[256]; + uchar Manufacturer[64]; + uchar SerialNumber[64]; + uchar Model[256]; + uchar ModelDescription[256]; + uchar HardwareVersion[256]; + uchar DriverVersion[256]; + uchar OptionROMVersion[256]; + uchar FirmwareVersion[256]; + uchar DriverName[256]; + NAME_TYPE NodeName; + } un; +} ATTRIBUTE_ENTRY, *PATTRIBUTE_ENTRY; + + +/* + * HBA Attribute Block + */ +typedef struct +{ + uint32 EntryCnt; /* Number of HBA attribute entries */ + ATTRIBUTE_ENTRY Entry; /* Variable-length array */ +} ATTRIBUTE_BLOCK, *PATTRIBUTE_BLOCK; + + +/* + * Port Entry + */ +typedef struct +{ + NAME_TYPE PortName; +} PORT_ENTRY, *PPORT_ENTRY; + +/* + * HBA Identifier + */ +typedef struct +{ + NAME_TYPE PortName; +} HBA_IDENTIFIER, *PHBA_IDENTIFIER; + +/* + * Registered Port List Format + */ +typedef struct +{ + uint32 EntryCnt; + PORT_ENTRY pe; /* Variable-length array */ +} REG_PORT_LIST, *PREG_PORT_LIST; + +/* + * Register HBA(RHBA) + */ +typedef struct +{ + HBA_IDENTIFIER hi; + REG_PORT_LIST rpl; /* variable-length array */ +} REG_HBA, *PREG_HBA; + +/* + * Register HBA Attributes (RHAT) + */ +typedef struct +{ + NAME_TYPE HBA_PortName; + ATTRIBUTE_BLOCK ab; +} REG_HBA_ATTRIBUTE, *PREG_HBA_ATTRIBUTE; + +/* + * Register Port Attributes (RPA) + */ +typedef struct +{ + NAME_TYPE HBA_PortName; + NAME_TYPE PortName; + ATTRIBUTE_BLOCK ab; +} REG_PORT_ATTRIBUTE, *PREG_PORT_ATTRIBUTE; + +/* + * Get Registered HBA List (GRHL) Accept Payload Format + */ +typedef struct +{ + uint32 HBA__Entry_Cnt; /* Number of Registered HBA Identifiers */ + NAME_TYPE HBA_PortName; /* Variable-length array */ +} GRHL_ACC_PAYLOAD, *PGRHL_ACC_PAYLOAD; + +/* + * Get Registered Port List (GRPL) Accept Payload Format + */ +typedef struct +{ + uint32 RPL_Entry_Cnt; /* Number of Registered Port Entries */ + PORT_ENTRY Reg_Port_Entry[1]; /* Variable-length array */ +} GRPL_ACC_PAYLOAD, *PGRPL_ACC_PAYLOAD; + +/* + * Get Port Attributes (GPAT) Accept Payload Format + */ + +typedef struct +{ + ATTRIBUTE_BLOCK pab; +} GPAT_ACC_PAYLOAD, *PGPAT_ACC_PAYLOAD; +#endif /* _H_FC_HW */ diff -purN -X /home/mbligh/.diff.exclude 350-autoswap/drivers/scsi/lpfc/fc_os.h 370-emulex/drivers/scsi/lpfc/fc_os.h --- 350-autoswap/drivers/scsi/lpfc/fc_os.h 1969-12-31 16:00:00.000000000 -0800 +++ 370-emulex/drivers/scsi/lpfc/fc_os.h 2004-02-28 11:20:03.000000000 -0800 @@ -0,0 +1,633 @@ +/******************************************************************* + * This file is part of the Emulex Linux Device Driver for * + * Enterprise Fibre Channel Host Bus Adapters. * + * Refer to the README file included with this package for * + * driver version and adapter support. * + * Copyright (C) 2003 Emulex Corporation. * + * www.emulex.com * + * * + * This program is free software; you can redistribute it and/or * + * modify it under the terms of the GNU General Public License * + * as published by the Free Software Foundation; either version 2 * + * of the License, or (at your option) any later version. * + * * + * This program is distributed in the hope that it will be useful, * + * but WITHOUT ANY WARRANTY; without even the implied warranty of * + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * + * GNU General Public License for more details, a copy of which * + * can be found in the file COPYING included with this package. * + *******************************************************************/ + +#ifndef _H_FCOS +#define _H_FCOS + +#ifdef __KERNEL__ +#include +#include +#include +#include +#include +#include +#include +#include +#include +#define LinuxVersionCode(v, p, s) (((v)<<16)+((p)<<8)+(s)) +#endif /* __KERNEL__ */ + + +#ifdef LP6000 +#ifdef __KERNEL__ +/* From drivers/scsi */ +#include "hosts.h" + +/* The driver is comditionally compiled to utilize the old scsi error + * handling logic, or the make use of the new scsi logic (use_new_eh_code). + * To use the old error handling logic, delete the line "#define FC_NEW_EH 1". + * To use the new error handling logic, add the line "#define FC_NEW_EH 1". + * + * #define FC_NEW_EH 1 + */ + +/* Turn on new error handling for 2.4 kernel base and on */ +#if LINUX_VERSION_CODE >= LinuxVersionCode(2,3,43) +#define FC_NEW_EH 1 +#endif + +#endif /* __KERNEL__ */ + +#ifndef __KERNEL__ +struct net_device_stats +{ + unsigned long rx_packets; /* total packets received */ + unsigned long tx_packets; /* total packets transmitted */ + unsigned long rx_bytes; /* total bytes received */ + unsigned long tx_bytes; /* total bytes transmitted */ + unsigned long rx_errors; /* bad packets received */ + unsigned long tx_errors; /* packet transmit problems */ + unsigned long rx_dropped; /* no space in linux buffers */ + unsigned long tx_dropped; /* no space available in linux */ + unsigned long multicast; /* multicast packets received */ + unsigned long collisions; + + /* detailed rx_errors: */ + unsigned long rx_length_errors; + unsigned long rx_over_errors; /* receiver ring buff overflow */ + unsigned long rx_crc_errors; /* recved pkt with crc error */ + unsigned long rx_frame_errors; /* recv'd frame alignment error */ + unsigned long rx_fifo_errors; /* recv'r fifo overrun */ + unsigned long rx_missed_errors; /* receiver missed packet */ + + /* detailed tx_errors */ + unsigned long tx_aborted_errors; + unsigned long tx_carrier_errors; + unsigned long tx_fifo_errors; + unsigned long tx_heartbeat_errors; + unsigned long tx_window_errors; + + /* for cslip etc */ + unsigned long rx_compressed; + unsigned long tx_compressed; +}; +#define enet_statistics net_device_stats +#endif /* __KERNEL__ */ + +typedef unsigned char uchar; +/* both ushort and ulong may be defined*/ + +#ifndef __KERNEL__ +#ifndef _SYS_TYPES_H +typedef unsigned short ushort; +typedef unsigned long ulong; +#endif +#endif /* __KERNEL__ */ + + +#define SELTO_TIMEOUT p_dev_ctl->selto_timeout + +#define _local_ static +#define _static_ +#define _forward_ extern + +typedef unsigned short uint16; +typedef unsigned int uint32; +typedef long long uint64; +#ifdef __KERNEL__ +#if LINUX_VERSION_CODE < LinuxVersionCode(2,2,18) +typedef unsigned long dma_addr_t; +#endif +#endif + +#if BITS_PER_LONG > 32 +/* These macros are for 64 bit support */ +#define putPaddrLow(addr) ((uint32) \ +(0xffffffff & (unsigned long)(addr))) +#define putPaddrHigh(addr) ((uint32) \ + (0xffffffff & (((unsigned long)(addr))>>32))) +#define getPaddr(high, low) ((unsigned long) \ + ((((unsigned long) (high)) << 32)|((unsigned long)(low)))) + +#else +/* Macro's to support 32 bit addressing */ +#define putPaddrLow(addr) ((uint32)(addr)) +#define putPaddrHigh(addr) 0 +#define getPaddr(high, low) ((uint32)(low)) +#endif + +/* Macro to get from adapter number to ddi instance */ +#define fc_brd_to_inst(brd) fcinstance[brd] + +#define DELAYMS(ms) lpfc_DELAYMS(p_dev_ctl, ms) +#define DELAYMSctx(ms) lpfc_DELAYMS(p_dev_ctl, ms) + +#define EXPORT_LINUX 1 + +#ifdef CONFIG_PPC64 +#define powerpc +#endif + +#ifdef powerpc +#define LITTLE_ENDIAN_HOST 0 /* For fc.h */ +#define BIG_ENDIAN_HW 1 /* For fc_hw.h */ +#else +#define LITTLE_ENDIAN_HOST 1 /* For fc.h */ +#define LITTLE_ENDIAN_HW 1 /* For fc_hw.h */ +#endif /* powerpc */ + +#define MACADDR_LEN 6 /* MAC network address length */ +#define FC_LVL 0 +#define CLK_LVL 0 +#define EVENT_NULL (-1) +#define DMA_READ 1 /* flag argument to D_MAP_LIST */ +#ifndef NULL /* define NULL if not defined*/ +#define NULL (0) +#endif +#define FALSE 0 +#define TRUE 1 +#define DFC_IOCTL 1 + +/* Return value for PCI interrupt routine */ +#define INTR_SUCC 1 /* Claimed interrupt, detected work to do */ +#define INTR_FAIL 0 /* Doesn't claim interrupt */ + + +#define con_print(s, a, b) \ + fc_print(s, (void *)((ulong)a), (void *)((ulong)b)) + + +/* These calls are used before, and after, access to a shared memory + * access to the adapter. + */ +#define FC_MAP_MEM(p1) (void *) (*(p1)) /* sigh */ +#define FC_MAP_IO(p1) (void *) (*(p1)) /* sigh */ +#define FC_UNMAP_MEMIO(p1) /* groan */ + +#define fc_mpdata_outcopy(p, m, d, c) fc_bcopy((m)->virt, d, c) +#define fc_mpdata_incopy(p, m, s, c) fc_bcopy(s, (m)->virt, c) +#define fc_mpdata_sync(h, a, b, c) lpfc_mpdata_sync(p_dev_ctl, h, a, b, c) + +#define DDI_DMA_SYNC_FORKERNEL 1 +#define DDI_DMA_SYNC_FORCPU 1 +#define DDI_DMA_SYNC_FORDEV 2 + +/* This call is used to wakeup someone waiting to send a SCSI + * administrative command to the drive, only one outstanding + * command can be sent to each device. + */ +#define fc_admin_wakeup(p, d, bp) + +#define lpfc_restart_device(dev_ptr) +#define lpfc_handle_fcp_error(p_pkt, p_fcptr, p_cmd) \ + lpfc_fcp_error(p_fcptr, p_cmd) +#define STAT_ABORTED 0 + +struct watchdog { + void (*func)(void *); /* completion handler */ + uint32 restart; /* restart time (in seconds) */ + uint32 count; /* time remaining */ + ulong timeout_id; + struct timer_list timer; + int stopping; +}; + +#define ntimerisset(p1) (*(p1)) +#define ntimerclear(p1) (*(p1) = 0) +#define ntimercmp(p1, p2, cmp) ((p1) cmp (p2)) + + +/* This is the dio and d_iovec structures for the d_map_* services */ +typedef struct d_iovec { + void *stub; +} *d_iovec_t; + +struct dio { + void *stub; +}; +typedef struct dio * dio_t; + +#ifdef __KERNEL__ +#if LINUX_VERSION_CODE < LinuxVersionCode(2,3,43) +#define pci_map_single(dev, address, size, direction) virt_to_bus(address) +#define pci_unmap_single(dev, address, size, direction) +#define pci_alloc_consistent(dev, s, h) fc_pci_alloc_consistent(dev, s, h) +#define pci_free_consistent(dev, s, v, h) fc_pci_free_consistent(dev, s, v, h) +#define scsi_sg_dma_address(sc) virt_to_bus((sc)->address) +#define scsi_sg_dma_len(sc) ((sc)->length) +typedef struct wait_queue *WAIT_QUEUE; +#else +#define scsi_sg_dma_address(sc) sg_dma_address(sc) +#define scsi_sg_dma_len(sc) sg_dma_len(sc) +typedef wait_queue_head_t WAIT_QUEUE; +#endif + +#if LINUX_VERSION_CODE >= LinuxVersionCode(2,3,17) +#define NETDEVICE struct net_device +#else +#define NETDEVICE struct device +#endif + +#if LINUX_VERSION_CODE < LinuxVersionCode(2,3,43) +#define netif_start_queue(dev) clear_bit(0, (void*)&dev->tbusy) +#define netif_stop_queue(dev) set_bit(0, (void*)&dev->tbusy) +#define netdevice_start(dev) dev->start = 1 +#define netdevice_stop(dev) dev->start = 0 +#define dev_kfree_skb_irq(a) dev_kfree_skb(a) +#else +#define netdevice_start(dev) +#define netdevice_stop(dev) +#endif + +#else +#define NETDEVICE void +#endif + +struct intr { + int (*handler) (struct intr *); + NETDEVICE * lpfn_dev; + int (*lpfn_handler) (void); + int lpfn_mtu; + int lpfn_rcv_buf_size; +}; +typedef struct sk_buff fcipbuf_t; + +#define fcnextpkt(x) ((x)->prev) /* FOR Now */ +#define fcnextdata(x) ((x)->next) +#define fcpktlen(x) ((x)->len) /* Assume 1 skbuff per packet */ +#define fcdata(x) ((x)->data) +#define fcdatalen(x) ((x)->len) +#define fcgethandle(x) 0 + +#define fcsetdatalen(x, l) (((x)->len) = l) +#define fcincdatalen(x, l) (((x)->len) += l) +#define fcsethandle(x, h) +#define fcfreehandle(p,x) + +#define m_getclust(a,b) lpfc_alloc_skb(p_dev_ctl->ihs.lpfn_rcv_buf_size) +#define m_getclustm(a,b,c) lpfc_alloc_skb(c) +#define m_freem(x) lpfc_kfree_skb(x); + +#define FC_RCV_BUF_SIZE lpfc_ip_rcvsz(p_dev_ctl) /* rcv buf size for IP */ + +#define enet_statistics net_device_stats +/* Structure for generic statistics */ +typedef struct ndd_genstats { + struct enet_statistics ndd_enet; + uint32 ndd_elapsed_time; /* time in seconds since last reset */ + uint32 ndd_ipackets_msw; /* packets received on interface(msw) */ + uint32 ndd_ibytes_msw; /* total # of octets received(msw) */ + uint32 ndd_recvintr_msw; /* number of receive interrupts(msw) */ + uint32 ndd_recvintr_lsw; /* number of receive interrupts(lsw) */ + uint32 ndd_opackets_msw; /* packets sent on interface(msw) */ + uint32 ndd_obytes_msw; /* total number of octets sent(msw) */ + uint32 ndd_xmitintr_msw; /* number of transmit interrupts(msw) */ + uint32 ndd_xmitintr_lsw; /* number of transmit interrupts(lsw) */ + uint32 ndd_nobufs; /* no buffers available */ + uint32 ndd_xmitque_max; /* max transmits ever queued */ + uint32 ndd_xmitque_ovf; /* number of transmit queue overflows */ + uint32 ndd_ibadpackets; /* # of bad pkts recv'd from adapter */ + uint32 ndd_xmitque_cur; /* sum of driver+adapter xmit queues */ + uint32 ndd_ifOutUcastPkts_msw; /* outbound unicast pkts requested */ + uint32 ndd_ifOutUcastPkts_lsw; /* on interface (msw and lsw) */ + uint32 ndd_ifOutMcastPkts_msw; /* outbound multicast pkts requested */ + uint32 ndd_ifOutMcastPkts_lsw; /* on interface (msw and lsw) */ + uint32 ndd_ifOutBcastPkts_msw; /* outbound broadcast pkts requested */ + uint32 ndd_ifOutBcastPkts_lsw; /* on interface (msw and lsw) */ + uint32 ndd_ifInBcastPkts_msw; /* rcv'ed broadcast pkts requested */ + uint32 ndd_ifInBcastPkts_lsw; /* on interface (msw and lsw) */ +} ndd_genstats_t; + +#define ndd_ipackets_lsw ndd_enet.rx_packets +#define ndd_opackets_lsw ndd_enet.tx_packets +#define ndd_ibytes_lsw ndd_enet.rx_bytes +#define ndd_obytes_lsw ndd_enet.tx_bytes +#define ndd_ipackets_drop ndd_enet.rx_dropped +#define ndd_opackets_drop ndd_enet.tx_dropped +#define ndd_ierrors ndd_enet.rx_errors +#define ndd_oerrors ndd_enet.tx_errors + +typedef struct ndd { + char *ndd_name; /* name, e.g. ``en0'' or ``tr0'' */ + char *ndd_alias; /* alternate name */ + uint32 ndd_flags; /* up/down, broadcast, etc. */ +#define NDD_UP (0x00000001) /* NDD is opened */ +#define NDD_BROADCAST (0x00000002) /* broadcast address valid */ +#define NDD_RUNNING (0x00000008) /* NDD is operational */ +#define NDD_SIMPLEX (0x00000010) /* can't hear own transmissions */ +#define NDD_MULTICAST (0x00000200) /* receiving all multicasts */ + void (*nd_receive)(void *, struct sk_buff *, void *); /* DLPI streams receive function */ + struct ndd_genstats ndd_genstats; /* generic network stats */ +} ndd_t; + +struct lpfn_probe { + int (*open)(NETDEVICE *dev); + int (*stop)(NETDEVICE *dev); + int (*hard_start_xmit) (struct sk_buff *skb, NETDEVICE *dev); + int (*hard_header) (struct sk_buff *skb, + NETDEVICE *dev, + unsigned short type, + void *daddr, + void *saddr, + unsigned len); + int (*rebuild_header)(struct sk_buff *skb); + void (*receive)(ndd_t *p_ndd, struct sk_buff *skb, void *p_dev_ctl); + struct net_device_stats* (*get_stats)(NETDEVICE *dev); + int (*change_mtu)(NETDEVICE *dev, int new_mtu); +}; +#define LPFN_PROBE 1 +#define LPFN_DETACH 2 +#define LPFN_DFC 3 + +struct buf { + void *av_forw; + void *av_back; + int b_bcount; /* transfer count */ + int b_error; /* expanded error field */ + int b_resid; /* words not transferred after error */ + int b_flags; /* see defines below */ +#define B_ERROR 0x0004 /* transaction aborted */ +#define B_READ 0x0040 /* read when I/O occurs */ +#define B_WRITE 0x0100 /* non-read pseudo-flag */ + struct scsi_cmnd *cmnd; + int isdone; +}; + +/* refer to the SCSI ANSI X3.131-1986 standard for information */ +struct sc_cmd { /* structure of the SCSI cmd block */ + uchar scsi_op_code; /* first byte of SCSI cmd block */ + uchar lun; /* second byte of SCSI cmd block */ + uchar scsi_bytes[14]; /* other bytes of SCSI cmd block */ +}; +#define SCSI_RELEASE_UNIT 0x17 +#define SCSI_REQUEST_SENSE 0x03 +#define SCSI_RESERVE_UNIT 0x16 + +struct scsi { + uchar scsi_length; /* byte length of scsi cmd (6,10, or 12) */ + uchar scsi_id; /* the target SCSI ID */ + uchar scsi_lun; /* which LUN on the target */ + uchar flags; /* flags for use with the physical scsi command */ +#define SC_NODISC 0x80 /* don't allow disconnections */ +#define SC_ASYNC 0x08 /* asynchronous data xfer */ + struct sc_cmd scsi_cmd; /* the actual SCSI cmd */ +}; + +struct sc_buf { + struct buf bufstruct; /* buffer structure containing request + for device -- MUST BE FIRST! */ + struct scsi scsi_command; /* the information relating strictly + to the scsi command itself */ + uint32 timeout_value; /* timeout value for the command, + in units of seconds */ + uint32 cmd_flag; +#define FLAG_ABORT 0x01 + + uchar status_validity; /* least significant bit - scsi_status + * valid, next least significant bit - + * card status valid */ + +#define SC_SCSI_ERROR 1 /* scsi status reflects error */ +#define SC_ADAPTER_ERROR 2 /* general card status reflects err */ + uchar scsi_status; /* returned SCSI Bus status */ +#define SCSI_STATUS_MASK 0x3e /* mask for useful bits */ +#define SC_GOOD_STATUS 0x00 /* target completed successfully */ +#define SC_CHECK_CONDITION 0x02 /* target is reporting an error, + * exception, or abnormal condition */ +#define SC_BUSY_STATUS 0x08 /* target is busy and cannot accept + * a command from initiator */ +#define SC_INTMD_GOOD 0x10 /* intermediate status good when using + * linked commands */ +#define SC_RESERVATION_CONFLICT 0x18 /* attempted to access a LUN which is + * reserved by another initiator */ +#define SC_COMMAND_TERMINATED 0x22 /* Command has been terminated by + * the device. */ +#define SC_QUEUE_FULL 0x28 /* Device's command queue is full */ + + uchar general_card_status; /* SCSI adapter card status byte */ +#define SC_HOST_IO_BUS_ERR 0x01 /* Host I/O Bus error condition */ +#define SC_SCSI_BUS_FAULT 0x02 /* failure of the SCSI Bus */ +#define SC_CMD_TIMEOUT 0x04 /* cmd didn't complete before timeout */ +#define SC_NO_DEVICE_RESPONSE 0x08 /* target device did not respond */ +#define SC_ADAPTER_HDW_FAILURE 0x10 /* indicating a hardware failure */ +#define SC_ADAPTER_SFW_FAILURE 0x20 /* indicating a microcode failure */ +#define SC_FUSE_OR_TERMINAL_PWR 0x40 /* indicating bad fuse or termination */ +#define SC_SCSI_BUS_RESET 0x80 /* detected external SCSI bus reset */ + + uchar adap_q_status; /* adapter's device queue status. This*/ +#define SC_DID_NOT_CLEAR_Q 0x1 /* SCSI adapter device driver has not */ + + uchar flags; /* flags to SCSI adapter driver */ +#define SC_RESUME 0x01 /* resume transaction queueing for this + * id/lun beginning with this sc_buf */ +#define SC_MAPPED 0x02 /* buffer is mapped */ + + uint32 qfull_retry_count; +struct dev_info *current_devp; +}; +#define STAT_DEV_RESET 0x0 + +#define MAX_FCP_TARGET 0xff /* max num of FCP targets supported */ +#define MAX_FCP_LUN 0xff /* max num of FCP LUNs supported */ +/* When on, if a lun is detected to be not present, or + * not ready ... device structures related to that lun + * will be freed to save memory. Remove this define + * to turn off the feature */ +#define FREE_LUN 1 + +#define INDEX(pan, target) (ushort)(((pan)<<8) | ((target) & 0x1ff)) +#define DEV_SID(x) (uchar)(x & 0xff) /* extract sid from device id */ +#define DEV_PAN(x) (uchar)((x>>8) & 0x01) /* extract pan from device id */ + +#define GET_PAYLOAD_PHYS_ADDR(x) (x->phys_adr) + +#define MAX_FCP_CMDS 4096 /* Max # of outstanding FCP cmds */ +#define MAX_FC_BRDS 16 /* Max # boards per system */ +#define MAX_FC_TARGETS 512 /* Max scsi target # per adapter */ +#define MAX_FC_BINDINGS 64 /* Max # of persistent bindings */ + +#define LPFC_LOCK_UNOWNED ((void *) -1) +#ifdef __KERNEL__ +#define cpuid smp_processor_id() +#define maxCPU NR_CPUS +#else +#define cpuid 0 +#define maxCPU 1 +#endif /* __KERNEL__ */ + +typedef struct Simple_lock { + spinlock_t *sl_lock; + int owner; +} Simple_lock; + +#define disable_lock(p1, p2) 0 +#define unlock_enable(p1, p2) + +#define LPFC_INIT_LOCK_DRIVER spin_lock_init(&lpfc_smp_lock) +#define LPFC_INIT_LOCK_DPCQ spin_lock_init(&lpfc_dpc_request_lock) + +#define LPFC_LOCK_DRIVER0 spin_lock_irqsave(&lpfc_smp_lock, iflg) +#define LPFC_LOCK_DRIVER(num) spin_lock_irqsave(&lpfc_smp_lock, iflg); \ + if(p_dev_ctl->fc_ipri != 0) { \ + printk("LOCK %d failure %x %x\n",num, \ + (uint32)p_dev_ctl->fc_ipri, (uint32)iflg); \ + } \ + p_dev_ctl->fc_ipri = num + +#define LPFC_UNLOCK_DRIVER0 spin_unlock_irqrestore(&lpfc_smp_lock, iflg) +#define LPFC_UNLOCK_DRIVER if(p_dev_ctl) p_dev_ctl->fc_ipri = 0; \ + spin_unlock_irqrestore(&lpfc_smp_lock, iflg) + +#define LPFC_LOCK_SCSI_DONE(shost) \ + spin_lock_irqsave(shost->host_lock, siflg) +#define LPFC_UNLOCK_SCSI_DONE(shost) \ + spin_unlock_irqrestore(shost->host_lock, siflg) + +#define LPFC_DPC_LOCK_Q spin_lock_irqsave(&lpfc_dpc_request_lock, siflg) +#define LPFC_DPC_UNLOCK_Q spin_unlock_irqrestore(&lpfc_dpc_request_lock, siflg) + +#define EPERM 1 /* Not super-user */ +#define ENOENT 2 /* No such file or directory */ +#define ESRCH 3 /* No such process */ +#define EINTR 4 /* interrupted system call */ +#define EIO 5 /* I/O error */ +#define ENXIO 6 /* No such device or address */ +#define E2BIG 7 /* Arg list too long */ +#define ENOEXEC 8 /* Exec format error */ +#define EBADF 9 /* Bad file number */ +#define ECHILD 10 /* No children */ +#ifndef EAGAIN +#define EAGAIN 11 /* Resource temporarily unavailable */ +#endif +#define ENOMEM 12 /* Not enough core */ +#define EACCES 13 /* Permission denied */ +#define EFAULT 14 /* Bad address */ +#define ENOTBLK 15 /* Block device required */ +#define EBUSY 16 /* Mount device busy */ +#define EEXIST 17 /* File exists */ +#define EXDEV 18 /* Cross-device link */ +#define ENODEV 19 /* No such device */ +#define ENOTDIR 20 /* Not a directory */ +#define EISDIR 21 /* Is a directory */ +#define EINVAL 22 /* Invalid argument */ +#define ENFILE 23 /* File table overflow */ +#define EMFILE 24 /* Too many open files */ +#define ENOTTY 25 /* Inappropriate ioctl for device */ +#define ETXTBSY 26 /* Text file busy */ +#define EFBIG 27 /* File too large */ +#define ENOSPC 28 /* No space left on device */ +#define ESPIPE 29 /* Illegal seek */ +#define EROFS 30 /* Read only file system */ +#define EMLINK 31 /* Too many links */ +#define EPIPE 32 /* Broken pipe */ +#define EDOM 33 /* Math arg out of domain of func */ +#define ERANGE 34 /* Math result not representable */ +#ifndef ECONNABORTED +#define ECONNABORTED 103 /* Software caused connection abort */ +#endif +#ifndef ETIMEDOUT +#define ETIMEDOUT 110 /* Connection timed out */ +#endif + +#endif /* LP6000 */ + +#ifdef __KERNEL__ +#define EMULEX_REQ_QUEUE_LEN 2048 +#define EMULEX_MAX_SG(ql) (4 + ((ql) > 0) ? 7*((ql) - 1) : 0) + +#define SCMD_NEXT(scmd) ((struct scsi_cmnd *)(scmd)->SCp.ptr) + +int fc_detect(struct scsi_host_template *); +int fc_release(struct Scsi_Host *); +const char * fc_info(struct Scsi_Host *); +int fc_queuecommand(struct scsi_cmnd *, void (* done)(struct scsi_cmnd *)); +#define FC_EXTEND_TRANS_A 1 +int fc_abort(struct scsi_cmnd *); +#ifdef FC_NEW_EH +int fc_reset_bus(struct scsi_cmnd *); +int fc_reset_host(struct scsi_cmnd *); +int fc_reset_device(struct scsi_cmnd *); +#else +int lpfc_reset(struct scsi_cmnd *, unsigned int); +int fc_proc_info( char *, char **, off_t, int, int, int); +#endif + +#ifdef USE_HIMEM +#define HIGHMEM_ENTRY highmem_io:1 +#else +#define HIGHMEM_ENTRY +#endif + +#ifdef FC_NEW_EH +#define LPFC_SG_SEGMENT 64 +#define EMULEXFC { \ + name: "lpfc", \ + detect: fc_detect, \ + release: fc_release, \ + info: fc_info, \ + queuecommand: fc_queuecommand, \ + eh_abort_handler: fc_abort, \ + eh_device_reset_handler: fc_reset_device, \ + eh_bus_reset_handler: fc_reset_bus, \ + eh_host_reset_handler: fc_reset_host, \ + can_queue: EMULEX_REQ_QUEUE_LEN, \ + this_id: -1, \ + sg_tablesize: LPFC_SG_SEGMENT, \ + cmd_per_lun: 30, \ + use_clustering: DISABLE_CLUSTERING, \ + HIGHMEM_ENTRY \ +} + +#else +#define LPFC_SG_SEGMENT 32 +#define EMULEXFC { \ + next: NULL, \ + module: NULL, \ + proc_dir: NULL, \ + proc_info: fc_proc_info, \ + name: "lpfc", \ + detect: fc_detect, \ + release: fc_release, \ + info: fc_info, \ + ioctl: NULL, \ + command: NULL, \ + queuecommand: fc_queuecommand, \ + eh_strategy_handler: NULL, \ + eh_abort_handler: NULL, \ + eh_device_reset_handler:NULL, \ + eh_bus_reset_handler: NULL, \ + eh_host_reset_handler: NULL, \ + abort: fc_abort, \ + reset: lpfc_reset, \ + slave_attach: NULL, \ + can_queue: EMULEX_REQ_QUEUE_LEN, \ + sg_tablesize: LPFC_SG_SEGMENT, \ + cmd_per_lun: 30, \ + present: 0, \ + unchecked_isa_dma: 0, \ + use_clustering: DISABLE_CLUSTERING, \ + use_new_eh_code: 0, \ + emulated: 0 \ +} +#endif +#endif /* __KERNEL */ + +#endif /* _H_FCOS */ + diff -purN -X /home/mbligh/.diff.exclude 350-autoswap/drivers/scsi/lpfc/fcclockb.c 370-emulex/drivers/scsi/lpfc/fcclockb.c --- 350-autoswap/drivers/scsi/lpfc/fcclockb.c 1969-12-31 16:00:00.000000000 -0800 +++ 370-emulex/drivers/scsi/lpfc/fcclockb.c 2004-02-28 11:20:03.000000000 -0800 @@ -0,0 +1,832 @@ +/******************************************************************* + * This file is part of the Emulex Linux Device Driver for * + * Enterprise Fibre Channel Host Bus Adapters. * + * Refer to the README file included with this package for * + * driver version and adapter support. * + * Copyright (C) 2003 Emulex Corporation. * + * www.emulex.com * + * * + * This program is free software; you can redistribute it and/or * + * modify it under the terms of the GNU General Public License * + * as published by the Free Software Foundation; either version 2 * + * of the License, or (at your option) any later version. * + * * + * This program is distributed in the hope that it will be useful, * + * but WITHOUT ANY WARRANTY; without even the implied warranty of * + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * + * GNU General Public License for more details, a copy of which * + * can be found in the file COPYING included with this package. * + *******************************************************************/ + +#include "fc_os.h" + +#include +#include +#include "fc_hw.h" +#include "fc.h" + +#include "fcdiag.h" +#include "hbaapi.h" + +#include "fc_hw.h" +#include "fc.h" + +#include "fcdiag.h" +#include "fcfgparm.h" +#include "fcmsg.h" +#include "fc_crtn.h" +#include "fc_ertn.h" + +extern fc_dd_ctl_t DD_CTL; +extern iCfgParam icfgparam[]; +/* Can be used to map driver instance number and hardware adapter number */ +extern int fcinstance[MAX_FC_BRDS]; +extern int fcinstcnt; + +_static_ FCCLOCK *fc_clkgetb(fc_dev_ctl_t *p_dev_ctl); +_static_ ulong fc_clk_rem(fc_dev_ctl_t *p_dev_ctl, FCCLOCK *cb); +_static_ int que_tin(FCLINK *blk, FCLINK *hdr); + +#include "lp6000.c" +#include "dfcdd.c" +/* +*** boolean to test if block is linked into specific queue +*** (intended for assertions) +*/ +#define inque(x,hdr) que_tin( (FCLINK *)(x), (FCLINK *)(hdr) ) + +#define FC_MAX_CLK_TIMEOUT 0xfffffff + +/***************************************************************** +*** fc_clkgetb() Get a clock block +*****************************************************************/ +_static_ FCCLOCK * +fc_clkgetb(fc_dev_ctl_t *p_dev_ctl) +{ + FC_BRD_INFO * binfo; + FCCLOCK_INFO * clock_info; + FCCLOCK * cb; + int i; + + clock_info = &DD_CTL.fc_clock_info; + + if(p_dev_ctl) { + binfo = &BINFO; + cb = (FCCLOCK * ) fc_mem_get(binfo, MEM_CLOCK); + } + else { + for(i=0;iclk_block[i]; + if(cb->cl_tix == -1) + break; + cb = 0; + } + } + + if(cb) + cb->cl_p_dev_ctl = (void *)p_dev_ctl; + + return (cb); +} + + +/***************************************************************** +*** fc_clkrelb() Release a clock block +*****************************************************************/ +_static_ void +fc_clkrelb(fc_dev_ctl_t *p_dev_ctl, FCCLOCK *cb) +{ + FC_BRD_INFO * binfo; + FCCLOCK_INFO * clock_info; + + clock_info = &DD_CTL.fc_clock_info; + + if(p_dev_ctl) { + binfo = &BINFO; + fc_mem_put(binfo, MEM_CLOCK, (uchar * )cb); + } + else { + cb->cl_tix = (uint32)-1; + } +} + + +/***************************************************************** +*** fc_clk_can() Cancel a clock request +*** fc_clk_can will cancel a previous request to fc_clk_set or +*** fc_clk_res. +*** The request must not have expired so far. A request that has been +*** cancelled cannot be reset. +*****************************************************************/ +_static_ int +fc_clk_can(fc_dev_ctl_t *p_dev_ctl, FCCLOCK *cb) +{ + FCCLOCK_INFO * clock_info; + int ipri; + + clock_info = &DD_CTL.fc_clock_info; + ipri = disable_lock(CLK_LVL, &CLOCK_LOCK); + + /* Make sure timer has not expired */ + if (!inque(cb, &clock_info->fc_clkhdr)) { + unlock_enable(ipri, &CLOCK_LOCK); + return(0); + } + + fc_clock_deque(cb); + + /* Release clock block */ + fc_clkrelb(p_dev_ctl, cb); + unlock_enable(ipri, &CLOCK_LOCK); + + return(1); +} + + +/***************************************************************** +*** fc_clk_rem() get amount of time remaining in a clock request +*** fc_clk_rem() returns the number of tix remaining in +*** a clock request generated by fc_clk_set or fc_clk_res. The timer must +*** not have expired or be cancelled. +*****************************************************************/ +_static_ ulong +fc_clk_rem(fc_dev_ctl_t *p_dev_ctl, FCCLOCK *cb) +{ + FCCLOCK_INFO * clock_info; + FCCLOCK * x; + ulong tix; + int ipri; + + clock_info = &DD_CTL.fc_clock_info; + ipri = disable_lock(CLK_LVL, &CLOCK_LOCK); + + tix = 0; + /* get top of clock queue */ + x = (FCCLOCK * ) & clock_info->fc_clkhdr; + /* + *** Add up ticks in blocks upto specified request + */ + do { + x = x->cl_fw; + if (x == (FCCLOCK * ) & clock_info->fc_clkhdr) { + unlock_enable(ipri, &CLOCK_LOCK); + return(0); + } + tix += x->cl_tix; + } while (x != cb); + + unlock_enable(ipri, &CLOCK_LOCK); + return(tix); +} + + +/***************************************************************** +*** fc_clk_res() clock reset +*** fc_clk_res() resets a clock previously assigned by fc_clk_set(). +*** That clock must not have expired. The new sec time is +*** used, measured from now. The original function/argument +*** are not changed. +*** Note: code parrallels fc_clk_can() and fc_clk_set(). +*****************************************************************/ +_static_ ulong +fc_clk_res(fc_dev_ctl_t *p_dev_ctl, ulong tix, FCCLOCK *cb) +{ + FCCLOCK_INFO * clock_info; + FCCLOCK * x; + int ipri; + + clock_info = &DD_CTL.fc_clock_info; + ipri = disable_lock(CLK_LVL, &CLOCK_LOCK); + + /* Make sure timer has not expired */ + if (!inque(cb, &clock_info->fc_clkhdr)) { + unlock_enable(ipri, &CLOCK_LOCK); + return(0); + } + if (tix <= 0) { + unlock_enable(ipri, &CLOCK_LOCK); + return(0); + } + tix++; /* round up 1 sec to account for partial first tick */ + + fc_clock_deque(cb); + + /* + *** Insert block into queue by order of amount of clock ticks, + *** each block contains difference in ticks between itself and + *** its predacessor. + */ + + /* get top of list */ + x = clock_info->fc_clkhdr.cl_f; + while (x != (FCCLOCK * ) & clock_info->fc_clkhdr) { + if (x->cl_tix >= tix) { + /* if inserting in middle of que, adjust next tix */ + x->cl_tix -= tix; + break; + } + tix -= x->cl_tix; + x = x->cl_fw; + } + + /* back up one in que */ + x = x->cl_bw; + fc_enque(cb, x); + clock_info->fc_clkhdr.count++; + cb->cl_tix = tix; + + unlock_enable(ipri, &CLOCK_LOCK); + return((ulong)1); +} + + +/***************************************************************** +*** fc_clk_set() request a clock service +*** fc_clk_set will cause specific functions to be executed at a fixed +*** time into the future. At a duration guaranteed to not be less +*** than, but potentially is longer than the given number of secs, +*** the given function is called with the given single argument. +*** Interlock is performed at a processor status level not lower +*** than the given value. The returned value is needed if the request +*** is to be cancelled or reset. +*****************************************************************/ +_static_ FCCLOCK * +fc_clk_set(fc_dev_ctl_t *p_dev_ctl, ulong tix, +void (*func)(fc_dev_ctl_t*, void*, void*), void *arg1, void *arg2) +{ + FCCLOCK_INFO * clock_info; + FCCLOCK * x; + FCCLOCK * cb; + int ipri; + + clock_info = &DD_CTL.fc_clock_info; + ipri = disable_lock(CLK_LVL, &CLOCK_LOCK); + + if (tix > FC_MAX_CLK_TIMEOUT) { + return(0); + } + tix++; /* round up 1 sec to account for partial first tick */ + + /* + *** Allocate a CLOCK block + */ + if ((cb = fc_clkgetb(p_dev_ctl)) == 0) { + unlock_enable(ipri, &CLOCK_LOCK); + return(0); + } + + /* + *** Insert block into queue by order of amount of clock ticks, + *** each block contains difference in ticks between itself and + *** its predecessor. + */ + + /* get top of list */ + x = clock_info->fc_clkhdr.cl_f; + while (x != (FCCLOCK * ) & clock_info->fc_clkhdr) { + if (x->cl_tix >= tix) { + /* if inserting in middle of que, adjust next tix */ + if (x->cl_tix > tix) { + x->cl_tix -= tix; + break; + } + /* + *** Another clock expires at same time. + *** Maintain the order of requests. + */ + for (x = x->cl_fw; + x != (FCCLOCK * ) & clock_info->fc_clkhdr; + x = x->cl_fw) { + if (x->cl_tix != 0) + break; + } + + /* I'm at end of list */ + tix = 0; + break; + } + + tix -= x->cl_tix; + x = x->cl_fw; + } + + /* back up one in que */ + x = x->cl_bw; + + /* Count the current number of unexpired clocks */ + clock_info->fc_clkhdr.count++; + fc_enque(cb, x); + cb->cl_func = (void(*)(void*, void*, void*))func; + cb->cl_arg1 = arg1; + cb->cl_arg2 = arg2; + cb->cl_tix = tix; + unlock_enable(ipri, &CLOCK_LOCK); + + return((FCCLOCK * ) cb); +} + + +/***************************************************************** +*** fc_timer +*** This function will be called by the driver every second. +*****************************************************************/ +_static_ void +fc_timer(void *p) +{ + fc_dev_ctl_t * p_dev_ctl; + FCCLOCK_INFO * clock_info; + ulong tix; + FCCLOCK * x; + int ipri; + + clock_info = &DD_CTL.fc_clock_info; + ipri = disable_lock(CLK_LVL, &CLOCK_LOCK); + + /* + *** Increment time_sample value + */ + clock_info->ticks++; + + x = clock_info->fc_clkhdr.cl_f; + + /* counter for propagating negative values */ + tix = 0; + /* If there are expired clocks */ + if (x != (FCCLOCK * ) & clock_info->fc_clkhdr) { + x->cl_tix = x->cl_tix - 1; + if (x->cl_tix <= 0) { + /* Loop thru all clock blocks */ + while (x != (FCCLOCK * ) & clock_info->fc_clkhdr) { + x->cl_tix += tix; + /* If # of ticks left > 0, break out of loop */ + if (x->cl_tix > 0) + break; + tix = x->cl_tix; + + /* Deque expired clock */ + fc_deque(x); + /* Decrement count of unexpired clocks */ + clock_info->fc_clkhdr.count--; + + unlock_enable(ipri, &CLOCK_LOCK); + + p_dev_ctl = x->cl_p_dev_ctl; + + if(p_dev_ctl) { + ipri = disable_lock(FC_LVL, &CMD_LOCK); + + /* Call timeout routine */ + (*x->cl_func) (p_dev_ctl, x->cl_arg1, x->cl_arg2); + /* Release clock block */ + fc_clkrelb(p_dev_ctl, x); + + unlock_enable(ipri, &CMD_LOCK); + } + else { + /* Call timeout routine */ + (*x->cl_func) (p_dev_ctl, x->cl_arg1, x->cl_arg2); + /* Release clock block */ + fc_clkrelb(p_dev_ctl, x); + } + + ipri = disable_lock(CLK_LVL, &CLOCK_LOCK); + + /* start over */ + x = clock_info->fc_clkhdr.cl_f; + } + } + } + unlock_enable(ipri, &CLOCK_LOCK); + fc_reset_timer(); +} + + +/***************************************************************** +*** fc_clock_deque() +*****************************************************************/ +_static_ void +fc_clock_deque(FCCLOCK *cb) +{ + FCCLOCK_INFO * clock_info; + FCCLOCK * x; + + clock_info = &DD_CTL.fc_clock_info; + /* + *** Remove the block from its present spot, but first adjust + *** tix field of any successor. + */ + if (cb->cl_fw != (FCCLOCK * ) & clock_info->fc_clkhdr) { + x = cb->cl_fw; + x->cl_tix += cb->cl_tix; + } + + /* Decrement count of unexpired clocks */ + clock_info->fc_clkhdr.count--; + + fc_deque(cb); +} + + +/***************************************************************** +*** fc_clock_init() +*****************************************************************/ +_static_ void +fc_clock_init() +{ + FCCLOCK_INFO * clock_info; + FCCLOCK * cb; + int i; + + clock_info = &DD_CTL.fc_clock_info; + + /* Initialize clock queue */ + clock_info->fc_clkhdr.cl_f = + clock_info->fc_clkhdr.cl_b = (FCCLOCK * ) & clock_info->fc_clkhdr; + clock_info->fc_clkhdr.count = 0; + + /* Initialize clock globals */ + clock_info->ticks = 0; + clock_info->Tmr_ct = 0; + + for(i=0;iclk_block[i]; + cb->cl_tix = (uint32)-1; + } +} + + +_static_ int +que_tin(FCLINK *blk, FCLINK *hdr) +{ + FCLINK * x; + + x = hdr->_f; + while (x != hdr) { + if (x == blk) { + return (1); + } + x = x->_f; + } + return(0); +} + + +_static_ void +fc_flush_clk_set( +fc_dev_ctl_t *p_dev_ctl, +void (*func)(fc_dev_ctl_t*, void*, void*)) +{ + FC_BRD_INFO * binfo; + FCCLOCK_INFO * clock_info; + FCCLOCK * x, * xmatch; + IOCBQ *iocbq; + int ipri; + + binfo = &BINFO; + clock_info = &DD_CTL.fc_clock_info; + ipri = disable_lock(CLK_LVL, &CLOCK_LOCK); + + x = clock_info->fc_clkhdr.cl_f; + + /* If there are clocks */ + while (x != (FCCLOCK * ) & clock_info->fc_clkhdr) { + if((p_dev_ctl == x->cl_p_dev_ctl) && ((void *)func == (void *)(*x->cl_func))) { + xmatch = x; + x = x->cl_fw; + + /* + *** Remove the block from its present spot, but first adjust + *** tix field of any successor. + */ + if (xmatch->cl_fw != (FCCLOCK * ) & clock_info->fc_clkhdr) { + x->cl_tix += xmatch->cl_tix; + } + + clock_info->fc_clkhdr.count--; + fc_deque(xmatch); + + if((void *)func == (void *)lpfc_scsi_selto_timeout) { + (*xmatch->cl_func) (p_dev_ctl, xmatch->cl_arg1, xmatch->cl_arg2); + } + if(func == fc_delay_timeout) { + iocbq = (IOCBQ *)xmatch->cl_arg1; + if(iocbq->bp) { + fc_mem_put(binfo, MEM_BUF, (uchar * )iocbq->bp); + } + if(iocbq->info) { + fc_mem_put(binfo, MEM_BUF, (uchar * )iocbq->info); + } + if(iocbq->bpl) { + fc_mem_put(binfo, MEM_BPL, (uchar * )iocbq->bpl); + } + fc_mem_put(binfo, MEM_IOCB, (uchar * )iocbq); + } + fc_clkrelb(p_dev_ctl, xmatch); + } + else { + x = x->cl_fw; + } + } + unlock_enable(ipri, &CLOCK_LOCK); + return; +} + +_static_ int +fc_abort_clk_blk( +fc_dev_ctl_t *p_dev_ctl, +void (*func)(fc_dev_ctl_t*, void*, void*), +void *arg1, +void *arg2) +{ + FC_BRD_INFO * binfo; + FCCLOCK_INFO * clock_info; + FCCLOCK * x, * xmatch; + IOCBQ *iocbq; + int ipri; + + binfo = &BINFO; + clock_info = &DD_CTL.fc_clock_info; + ipri = disable_lock(CLK_LVL, &CLOCK_LOCK); + + x = clock_info->fc_clkhdr.cl_f; + + /* If there are clocks */ + while (x != (FCCLOCK * ) & clock_info->fc_clkhdr) { + if((p_dev_ctl == x->cl_p_dev_ctl) && + ((void *)func == (void *)(*x->cl_func)) && + (arg1 == x->cl_arg1) && + (arg2 == x->cl_arg2)) { + xmatch = x; + x = x->cl_fw; + + /* + *** Remove the block from its present spot, but first adjust + *** tix field of any successor. + */ + if (xmatch->cl_fw != (FCCLOCK * ) & clock_info->fc_clkhdr) { + x->cl_tix += xmatch->cl_tix; + } + + clock_info->fc_clkhdr.count--; + fc_deque(xmatch); + if((void *)func == (void *)lpfc_scsi_selto_timeout) { + (*xmatch->cl_func) (p_dev_ctl, xmatch->cl_arg1, xmatch->cl_arg2); + } + if(func == fc_delay_timeout) { + iocbq = (IOCBQ *)xmatch->cl_arg1; + if(iocbq->bp) { + fc_mem_put(binfo, MEM_BUF, (uchar * )iocbq->bp); + } + if(iocbq->info) { + fc_mem_put(binfo, MEM_BUF, (uchar * )iocbq->info); + } + if(iocbq->bpl) { + fc_mem_put(binfo, MEM_BPL, (uchar * )iocbq->bpl); + } + fc_mem_put(binfo, MEM_IOCB, (uchar * )iocbq); + } + fc_clkrelb(p_dev_ctl, xmatch); + unlock_enable(ipri, &CLOCK_LOCK); + return(1); + } + else { + x = x->cl_fw; + } + } + unlock_enable(ipri, &CLOCK_LOCK); + return(0); +} + +_static_ int +fc_abort_delay_els_cmd( +fc_dev_ctl_t *p_dev_ctl, +uint32 did) +{ + FC_BRD_INFO * binfo; + FCCLOCK_INFO * clock_info; + FCCLOCK * x, * xmatch; + IOCBQ *iocbq, *saveiocbq, *next_iocbq; + int ipri; + + binfo = &BINFO; + clock_info = &DD_CTL.fc_clock_info; + ipri = disable_lock(CLK_LVL, &CLOCK_LOCK); + + x = clock_info->fc_clkhdr.cl_f; + + /* If there are clocks */ + while (x != (FCCLOCK * ) & clock_info->fc_clkhdr) { + if((p_dev_ctl == x->cl_p_dev_ctl) && + ((void *)(x->cl_func) == (void *)fc_delay_timeout)) { + xmatch = x; + x = x->cl_fw; + iocbq = (IOCBQ *)xmatch->cl_arg1; + + if((iocbq->iocb.un.elsreq.remoteID != did) && + (did != 0xffffffff)) + continue; + /* Abort delay xmit clock */ + fc_log_printf_msg_vargs( binfo->fc_brd_no, + &fc_msgBlk0100, /* ptr to msg structure */ + fc_mes0100, /* ptr to msg */ + fc_msgBlk0100.msgPreambleStr, /* begin varargs */ + did, + iocbq->iocb.un.elsreq.remoteID, + iocbq->iocb.ulpIoTag); /* end varargs */ + /* + *** Remove the block from its present spot, but first adjust + *** tix field of any successor. + */ + if (xmatch->cl_fw != (FCCLOCK * ) & clock_info->fc_clkhdr) { + x->cl_tix += xmatch->cl_tix; + } + + clock_info->fc_clkhdr.count--; + fc_deque(xmatch); + if(iocbq->bp) { + fc_mem_put(binfo, MEM_BUF, (uchar * )iocbq->bp); + } + if(iocbq->info) { + fc_mem_put(binfo, MEM_BUF, (uchar * )iocbq->info); + } + if(iocbq->bpl) { + fc_mem_put(binfo, MEM_BPL, (uchar * )iocbq->bpl); + } + fc_mem_put(binfo, MEM_IOCB, (uchar * )iocbq); + + fc_clkrelb(p_dev_ctl, xmatch); + + if(did != 0xffffffff) + break; + } + else { + x = x->cl_fw; + } + } + unlock_enable(ipri, &CLOCK_LOCK); + + if(binfo->fc_delayxmit) { + iocbq = binfo->fc_delayxmit; + saveiocbq = 0; + while(iocbq) { + + if((iocbq->iocb.un.elsreq.remoteID == did) || + (did == 0xffffffff)) { + + next_iocbq = (IOCBQ *)iocbq->q; + /* Abort delay xmit context */ + fc_log_printf_msg_vargs( binfo->fc_brd_no, + &fc_msgBlk0101, /* ptr to msg structure */ + fc_mes0101, /* ptr to msg */ + fc_msgBlk0101.msgPreambleStr, /* begin varargs */ + did, + iocbq->iocb.un.elsreq.remoteID, + iocbq->iocb.ulpIoTag); /* end varargs */ + if(saveiocbq) { + saveiocbq->q = iocbq->q; + } + else { + binfo->fc_delayxmit = (IOCBQ *)iocbq->q; + } + if(iocbq->bp) { + fc_mem_put(binfo, MEM_BUF, (uchar * )iocbq->bp); + } + if(iocbq->info) { + fc_mem_put(binfo, MEM_BUF, (uchar * )iocbq->info); + } + if(iocbq->bpl) { + fc_mem_put(binfo, MEM_BPL, (uchar * )iocbq->bpl); + } + fc_mem_put(binfo, MEM_IOCB, (uchar * )iocbq); + + if(did != 0xffffffff) + break; + iocbq = next_iocbq; + } + else { + saveiocbq = iocbq; + iocbq = (IOCBQ *)iocbq->q; + } + } + } + return(0); +} +/* DQFULL */ +/***************************************************************************** + * + * NAME: fc_q_depth_up + * FUNCTION: Increment current Q depth for LUNs + * + *****************************************************************************/ + +_static_ void +fc_q_depth_up( +fc_dev_ctl_t * p_dev_ctl, +void *n1, +void *n2) +{ + node_t *nodep; + NODELIST * ndlp; + iCfgParam * clp; + FC_BRD_INFO *binfo; + struct dev_info * dev_ptr; + + binfo = &BINFO; + clp = DD_CTL.p_config[binfo->fc_brd_no]; + + if (clp[CFG_DFT_LUN_Q_DEPTH].a_current <= FC_MIN_QFULL) { + return; + } + + if(binfo->fc_ffstate != FC_READY) + goto out; + + /* + * Find the target from the nlplist based on SCSI ID + */ + ndlp = binfo->fc_nlpmap_start; + while(ndlp != (NODELIST *)&binfo->fc_nlpmap_start) { + nodep = (node_t *)ndlp->nlp_targetp; + if (nodep) { + for (dev_ptr = nodep->lunlist; dev_ptr != NULL; + dev_ptr = dev_ptr->next) { + if ((dev_ptr->stop_send_io == 0) && + (dev_ptr->fcp_cur_queue_depth < clp[CFG_DFT_LUN_Q_DEPTH].a_current)) { + dev_ptr->fcp_cur_queue_depth += (ushort)clp[CFG_DQFULL_THROTTLE_UP_INC].a_current; + if (dev_ptr->fcp_cur_queue_depth > clp[CFG_DFT_LUN_Q_DEPTH].a_current) + dev_ptr->fcp_cur_queue_depth = clp[CFG_DFT_LUN_Q_DEPTH].a_current; + } else { + /* + * Try to reset stop_send_io + */ + if (dev_ptr->stop_send_io) + dev_ptr->stop_send_io--; + } + } + } + ndlp = (NODELIST *)ndlp->nlp_listp_next; + } + +out: + fc_clk_set(p_dev_ctl, clp[CFG_DQFULL_THROTTLE_UP_TIME].a_current, fc_q_depth_up, + 0, 0); + + return; +} + +/* QFULL_RETRY */ +_static_ void +fc_qfull_retry( +void *n1) +{ + fc_buf_t * fcptr; + dvi_t * dev_ptr; + T_SCSIBUF * sbp; + struct buf * bp; + fc_dev_ctl_t * p_dev_ctl; + + fcptr = (fc_buf_t *)n1; + sbp = fcptr->sc_bufp; + dev_ptr = fcptr->dev_ptr; + bp = (struct buf *) sbp; + + if(dev_ptr->nodep) { + p_dev_ctl = dev_ptr->nodep->ap; + fc_fcp_bufunmap(p_dev_ctl, sbp); + } + /* + * Queue this command to the head of the device's + * pending queue for processing by fc_issue_cmd. + */ + if (dev_ptr->pend_head == NULL) { /* Is queue empty? */ + dev_ptr->pend_head = sbp; + dev_ptr->pend_tail = sbp; + bp->av_forw = NULL; + fc_enq_wait(dev_ptr); + } else { /* Queue not empty */ + bp->av_forw = (struct buf *) dev_ptr->pend_head; + dev_ptr->pend_head = sbp; + } + dev_ptr->pend_count++; +} + +_static_ void +fc_establish_link_tmo( +fc_dev_ctl_t * p_dev_ctl, +void *n1, +void *n2) +{ + FC_BRD_INFO * binfo; + iCfgParam * clp; + + binfo = &BINFO; + clp = DD_CTL.p_config[binfo->fc_brd_no]; + /* Re-establishing Link, timer expired */ + fc_log_printf_msg_vargs( binfo->fc_brd_no, + &fc_msgBlk1300, /* ptr to msg structure */ + fc_mes1300, /* ptr to msg */ + fc_msgBlk1300.msgPreambleStr, /* begin varargs */ + binfo->fc_flag, + binfo->fc_ffstate); /* end varargs */ + binfo->fc_flag &= ~FC_ESTABLISH_LINK; +} diff -purN -X /home/mbligh/.diff.exclude 350-autoswap/drivers/scsi/lpfc/fcdds.h 370-emulex/drivers/scsi/lpfc/fcdds.h --- 350-autoswap/drivers/scsi/lpfc/fcdds.h 1969-12-31 16:00:00.000000000 -0800 +++ 370-emulex/drivers/scsi/lpfc/fcdds.h 2004-02-28 11:20:03.000000000 -0800 @@ -0,0 +1,175 @@ +/******************************************************************* + * This file is part of the Emulex Linux Device Driver for * + * Enterprise Fibre Channel Host Bus Adapters. * + * Refer to the README file included with this package for * + * driver version and adapter support. * + * Copyright (C) 2003 Emulex Corporation. * + * www.emulex.com * + * * + * This program is free software; you can redistribute it and/or * + * modify it under the terms of the GNU General Public License * + * as published by the Free Software Foundation; either version 2 * + * of the License, or (at your option) any later version. * + * * + * This program is distributed in the hope that it will be useful, * + * but WITHOUT ANY WARRANTY; without even the implied warranty of * + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * + * GNU General Public License for more details, a copy of which * + * can be found in the file COPYING included with this package. * + *******************************************************************/ + +#ifndef _H_FCDDS +#define _H_FCDDS + +#include "fc_hw.h" + +#define LNAMESIZE 16 + +#ifndef DMA_MAXMIN_16M +#define DMA_MAXMIN_16M 0x8 +#define DMA_MAXMIN_32M 0x9 +#define DMA_MAXMIN_64M 0xa +#define DMA_MAXMIN_128M 0xb +#define DMA_MAXMIN_256M 0xc +#define DMA_MAXMIN_512M 0xd +#define DMA_MAXMIN_1G 0xe +#define DMA_MAXMIN_2G 0xf +#endif + +/****************************************************************************/ +/* This is the DDS structure for the FC device */ +/****************************************************************************/ + +typedef struct { + char logical_name[LNAMESIZE]; /* logical name in ASCII characters */ + char dev_alias[LNAMESIZE]; /* logical name in ASCII characters */ + uint32 devno; /* major/minor device number */ + + /* PCI parameters */ + int bus_id; /* for use with i_init and bus io */ + int sla; /* for use with pci_cfgrw and bus io */ + int bus_intr_lvl; /* interrupt level */ + uint64 bus_mem_addr; /* bus memory base address */ + uint64 bus_io_addr; /* I/O reg base address */ + + uint32 xmt_que_size; /* size of xmit queue for mbufs */ + uint32 num_iocbs; /* number of iocb buffers to allocate */ + uint32 num_bufs; /* number of ELS/IP buffers to allocate */ + uint32 fcpfabric_tmo; /* Extra FCP timeout for fabrics (in secs) */ + + ushort topology; /* link topology for init link */ + ushort post_ip_buf; /* number of IP buffers to post to ring 1 */ + + ushort rsvd1; + uchar ipclass; /* class to use for transmitting IP data */ + uchar fcpclass; /* class to use for transmitting FCP data */ + + uchar network_on; /* true if networking is enabled */ + uchar fcp_on; /* true if FCP access is enabled */ + uchar frame_512; /* true if 512 byte framesize is required */ + uchar use_adisc; /* Use ADISC results in FCP rediscovery */ + + uchar first_check; /* Ignore 0x2900 check condition after PLOGI */ + uchar sli; /* Service Level Interface supported */ + uchar ffnumrings; /* number of FF rings being used */ + + uchar scandown; + uchar linkdown_tmo; /* linkdown timer, seconds */ + uchar nodev_tmo; + uchar fabric_reg; /* perform RFT_ID with NameServer */ + + uchar nummask[4]; /* number of masks/rings being used */ + uchar rval[6]; /* rctl for ring, assume mask is 0xff */ + uchar tval[6]; /* type for ring, assume mask is 0xff */ + + uchar verbose; /* how much to hurl onto the console */ + uchar ack0support; /* Run with ACK0 for CLASS2 sequences */ + uchar log_only; /* console messages just logged to log file */ + uchar automap; /* assign scsi ids to all FCP devices */ + + uint32 default_tgt_queue_depth; /* max # cmds outstanding to a target */ + + uchar dds1_os; /* system dependent variable */ + uchar default_lun_queue_depth; /* max # cmds outstanding to a lun */ + uchar nodev_holdio; /* Hold I/O errors if device disappears */ + uchar zone_rscn; /* system dependent variable */ + + uchar check_cond_err; + uchar delay_rsp_err; + uchar rscn_adisc; + uchar filler1; + uchar filler2; + uchar filler3; + + uint32 dds5_os; /* system dependent variable */ +} fc_dds_t; + +/* Values for seed_base and fcp_mapping */ +#define FCP_SEED_WWPN 0x1 /* Entry scsi id is seeded for WWPN */ +#define FCP_SEED_WWNN 0x2 /* Entry scsi id is seeded for WWNN */ +#define FCP_SEED_DID 0x4 /* Entry scsi id is seeded for DID */ +#define FCP_SEED_MASK 0x7 /* mask for seeded flags */ + + + +/* Allocate space for any environment specific dds parameters */ + + + + + +/****************************************************************************/ +/* Device VPD save area */ +/****************************************************************************/ + +typedef struct fc_vpd { + uint32 status; /* vpd status value */ + uint32 length; /* number of bytes actually returned */ + struct { + uint32 rsvd1; /* Revision numbers */ + uint32 biuRev; + uint32 smRev; + uint32 smFwRev; + uint32 endecRev; + ushort rBit; + uchar fcphHigh; + uchar fcphLow; + uchar feaLevelHigh; + uchar feaLevelLow; + uint32 postKernRev; + uint32 opFwRev; + uchar opFwName[16]; + uint32 sli1FwRev; + uchar sli1FwName[16]; + uint32 sli2FwRev; + uchar sli2FwName[16]; + } rev; +} fc_vpd_t; + +/****************************************************************************/ +/* Node table information that the config routine needs */ +/****************************************************************************/ + + +/****************************************************************************/ +/* SCIOCOMPLETE results buffer structure */ +/****************************************************************************/ + +struct iorslt { + struct buf *buf_struct_ptr; + uint32 b_flags; + uint32 b_resid; + char b_error; +}; + +/****************************************************************************/ +/* Special ioctl calls for the Fibre Channel SCSI LAN device driver */ +/****************************************************************************/ + +#define SCIONODES 0x47 /* ioctl to get node table */ +#define SCIOSTRAT 0x48 /* strategy ioctl */ +#define SCIOCOMPLETE 0x49 /* I/O completion ioctl */ +#define SCIORESUMEQ 0x4a /* device resume Q ioctl */ + + +#endif /* _H_FCDDS */ diff -purN -X /home/mbligh/.diff.exclude 350-autoswap/drivers/scsi/lpfc/fcdiag.h 370-emulex/drivers/scsi/lpfc/fcdiag.h --- 350-autoswap/drivers/scsi/lpfc/fcdiag.h 1969-12-31 16:00:00.000000000 -0800 +++ 370-emulex/drivers/scsi/lpfc/fcdiag.h 2004-02-28 11:20:03.000000000 -0800 @@ -0,0 +1,353 @@ +/******************************************************************* + * This file is part of the Emulex Linux Device Driver for * + * Enterprise Fibre Channel Host Bus Adapters. * + * Refer to the README file included with this package for * + * driver version and adapter support. * + * Copyright (C) 2003 Emulex Corporation. * + * www.emulex.com * + * * + * This program is free software; you can redistribute it and/or * + * modify it under the terms of the GNU General Public License * + * as published by the Free Software Foundation; either version 2 * + * of the License, or (at your option) any later version. * + * * + * This program is distributed in the hope that it will be useful, * + * but WITHOUT ANY WARRANTY; without even the implied warranty of * + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * + * GNU General Public License for more details, a copy of which * + * can be found in the file COPYING included with this package. * + *******************************************************************/ + +#ifndef _H_FCDIAG +#define _H_FCDIAG + +#ifndef LP6000 +/* Applications using this header file should typedef the following */ +typedef unsigned int uint32; +typedef unsigned char uchar; +typedef unsigned short ushort; +typedef void* MAILBOX; +#endif + +/* the brdinfo structure */ +typedef struct BRDINFO { + uint32 a_mem_hi; /* memory identifier for adapter access */ + uint32 a_mem_low; /* memory identifier for adapter access */ + uint32 a_flash_hi; /* memory identifier for adapter access */ + uint32 a_flash_low; /* memory identifier for adapter access */ + uint32 a_ctlreg_hi; /* memory identifier for adapter access */ + uint32 a_ctlreg_low; /* memory identifier for adapter access */ + uint32 a_intrlvl; /* interrupt level for adapter */ + uint32 a_pci; /* PCI identifier (device / vendor id) */ + uint32 a_busid; /* identifier of PCI bus adapter is on */ + uint32 a_devid; /* identifier of PCI device number */ + uchar a_rsvd1; /* reserved for future use */ + uchar a_rsvd2; /* reserved for future use */ + uchar a_siglvl; /* signal handler used by library */ + uchar a_ddi; /* identifier device driver instance number */ + uint32 a_onmask; /* mask of ONDI primatives supported */ + uint32 a_offmask; /* mask of OFFDI primatives supported */ + uchar a_drvrid[16]; /* driver version */ + uchar a_fwname[32]; /* firmware version */ +} brdinfo; + +/* bits in a_onmask */ +#define ONDI_MBOX 0x1 /* allows non-destructive mailbox commands */ +#define ONDI_IOINFO 0x2 /* supports retrieval of I/O info */ +#define ONDI_LNKINFO 0x4 /* supports retrieval of link info */ +#define ONDI_NODEINFO 0x8 /* supports retrieval of node info */ +#define ONDI_TRACEINFO 0x10 /* supports retrieval of trace info */ +#define ONDI_SETTRACE 0x20 /* supports configuration of trace info */ +#define ONDI_SLI1 0x40 /* hardware supports SLI-1 interface */ +#define ONDI_SLI2 0x80 /* hardware supports SLI-2 interface */ +#define ONDI_BIG_ENDIAN 0x100 /* DDI interface is BIG Endian */ +#define ONDI_LTL_ENDIAN 0x200 /* DDI interface is LITTLE Endian */ +#define ONDI_RMEM 0x400 /* allows reading of adapter shared memory */ +#define ONDI_RFLASH 0x800 /* allows reading of adapter flash */ +#define ONDI_RPCI 0x1000 /* allows reading of adapter pci registers */ +#define ONDI_RCTLREG 0x2000 /* allows reading of adapter cntrol registers */ +#define ONDI_CFGPARAM 0x4000 /* supports get/set configuration parameters */ +#define ONDI_CT 0x8000 /* supports passthru CT interface */ +#define ONDI_HBAAPI 0x10000 /* supports HBA API interface */ + +/* bits in a_offmask */ +#define OFFDI_MBOX 0x1 /* allows all mailbox commands */ +#define OFFDI_RMEM 0x2 /* allows reading of adapter shared memory */ +#define OFFDI_WMEM 0x4 /* allows writing of adapter shared memory */ +#define OFFDI_RFLASH 0x8 /* allows reading of adapter flash */ +#define OFFDI_WFLASH 0x10 /* allows writing of adapter flash */ +#define OFFDI_RPCI 0x20 /* allows reading of adapter pci registers */ +#define OFFDI_WPCI 0x40 /* allows writing of adapter pci registers */ +#define OFFDI_RCTLREG 0x80 /* allows reading of adapter cntrol registers */ +#define OFFDI_WCTLREG 0x100 /* allows writing of adapter cntrol registers */ +#define OFFDI_OFFLINE 0x80000000 /* if set, adapter is in offline state */ + +/* values for flag in SetDiagEnv */ +#define DDI_SHOW 0x0 +#define DDI_ONDI 0x1 +#define DDI_OFFDI 0x2 + +#define DDI_BRD_SHOW 0x10 +#define DDI_BRD_ONDI 0x11 +#define DDI_BRD_OFFDI 0x12 + +/* unused field */ +#define DDI_UNUSED 0xFFFFFFFFL /* indicate unused field of brdinfo */ + +/* the ioinfo structure */ +typedef struct IOINFO { + uint32 a_mbxCmd; /* mailbox commands issued */ + uint32 a_mboxCmpl; /* mailbox commands completed */ + uint32 a_mboxErr; /* mailbox commands completed, error status */ + uint32 a_iocbCmd; /* iocb command ring issued */ + uint32 a_iocbRsp; /* iocb rsp ring recieved */ + uint32 a_adapterIntr; /* adapter interrupt events */ + uint32 a_fcpCmd; /* FCP commands issued */ + uint32 a_fcpCmpl; /* FCP command completions recieved */ + uint32 a_fcpErr; /* FCP command completions errors */ + uint32 a_seqXmit; /* IP xmit sequences sent */ + uint32 a_seqRcv; /* IP sequences recieved */ + uint32 a_bcastXmit; /* cnt of successful xmit broadcast commands issued */ + uint32 a_bcastRcv; /* cnt of receive broadcast commands received */ + uint32 a_elsXmit; /* cnt of successful ELS request commands issued */ + uint32 a_elsRcv; /* cnt of ELS request commands received */ + uint32 a_RSCNRcv; /* cnt of RSCN commands recieved */ + uint32 a_seqXmitErr; /* cnt of unsuccessful xmit broadcast cmds issued */ + uint32 a_elsXmitErr; /* cnt of unsuccessful ELS request commands issued */ + uint32 a_elsBufPost; /* cnt of ELS buffers posted to adapter */ + uint32 a_ipBufPost; /* cnt of IP buffers posted to adapter */ + uint32 a_cnt1; /* generic counter */ + uint32 a_cnt2; /* generic counter */ + uint32 a_cnt3; /* generic counter */ + uint32 a_cnt4; /* generic counter */ + +} IOinfo; + +/* the linkinfo structure */ +typedef struct LINKINFO { + uint32 a_linkEventTag; + uint32 a_linkUp; + uint32 a_linkDown; + uint32 a_linkMulti; + uint32 a_DID; + uchar a_topology; + uchar a_linkState; + uchar a_alpa; + uchar a_alpaCnt; + uchar a_alpaMap[128]; + uchar a_wwpName[8]; + uchar a_wwnName[8]; +} LinkInfo; + +/* values for a_topology */ +#define LNK_LOOP 0x1 +#define LNK_PUBLIC_LOOP 0x2 +#define LNK_FABRIC 0x3 +#define LNK_PT2PT 0x4 + +/* values for a_linkState */ +#define LNK_DOWN 0x1 +#define LNK_UP 0x2 +#define LNK_FLOGI 0x3 +#define LNK_DISCOVERY 0x4 +#define LNK_REDISCOVERY 0x5 +#define LNK_READY 0x6 + +/* the traceinfo structure */ +typedef struct TRACEINFO { + uchar a_event; + uchar a_cmd; + ushort a_status; + uint32 a_information; +} TraceInfo; + +/* values for flag */ +#define TRC_SHOW 0x0 +#define TRC_MBOX 0x1 +#define TRC_IOCB 0x2 +#define TRC_INTR 0x4 +#define TRC_EVENT 0x8 + +/* values for a_event */ +#define TRC_MBOX_CMD 0x1 +#define TRC_MBOX_CMPL 0x2 +#define TRC_IOCB_CMD 0x3 +#define TRC_IOCB_RSP 0x4 +#define TRC_INTR_RCV 0x5 +#define TRC_EVENT1 0x6 +#define TRC_EVENT2 0x7 +#define TRC_EVENT_MASK 0x7 +#define TRC_RING0 0x0 +#define TRC_RING1 0x40 +#define TRC_RING2 0x80 +#define TRC_RING3 0xC0 +#define TRC_RING_MASK 0xC0 + +/* the cfgparam structure */ +typedef struct CFGPARAM { + uchar a_string[32]; + uint32 a_low; + uint32 a_hi; + uint32 a_default; + uint32 a_current; + ushort a_flag; + ushort a_changestate; + uchar a_help[80]; +} CfgParam; + +#define MAX_CFG_PARAM 64 + +/* values for a_flag */ +#define CFG_EXPORT 0x1 /* Export this parameter to the end user */ +#define CFG_IGNORE 0x2 /* Ignore this parameter */ +#define CFG_DEFAULT 0x8000 /* Reestablishing Link */ + +/* values for a_changestate */ +#define CFG_REBOOT 0x0 /* Changes effective after ystem reboot */ +#define CFG_DYNAMIC 0x1 /* Changes effective immediately */ +#define CFG_RESTART 0x2 /* Changes effective after driver restart */ + +/* the icfgparam structure - internal use only */ +typedef struct ICFGPARAM { + char *a_string; + uint32 a_low; + uint32 a_hi; + uint32 a_default; + uint32 a_current; + ushort a_flag; + ushort a_changestate; + char *a_help; +} iCfgParam; + + +/* the nodeinfo structure */ +typedef struct NODEINFO { + ushort a_flag; + ushort a_state; + uint32 a_did; + uchar a_wwpn[8]; + uchar a_wwnn[8]; + uint32 a_targetid; +} NodeInfo; + +#define MAX_NODES 512 + +/* Defines for a_state */ +#define NODE_UNUSED 0 /* unused NL_PORT entry */ +#define NODE_LIMBO 0x1 /* entry needs to hang around for wwpn / sid */ +#define NODE_LOGOUT 0x2 /* NL_PORT is not logged in - entry is cached */ +#define NODE_PLOGI 0x3 /* PLOGI was sent to NL_PORT */ +#define NODE_LOGIN 0x4 /* NL_PORT is logged in / login REG_LOGINed */ +#define NODE_PRLI 0x5 /* PRLI was sent to NL_PORT */ +#define NODE_ALLOC 0x6 /* NL_PORT is ready to initiate adapter I/O */ +#define NODE_SEED 0x7 /* seed scsi id bind in table */ + +/* Defines for a_flag */ +#define NODE_RPI_XRI 0x1 /* creating xri for entry */ +#define NODE_REQ_SND 0x2 /* sent ELS request for this entry */ +#define NODE_ADDR_AUTH 0x4 /* Authenticating addr for this entry */ +#define NODE_RM_ENTRY 0x8 /* Remove this entry */ +#define NODE_FARP_SND 0x10 /* sent FARP request for this entry */ +#define NODE_FABRIC 0x20 /* this entry represents the Fabric */ +#define NODE_FCP_TARGET 0x40 /* this entry is an FCP target */ +#define NODE_IP_NODE 0x80 /* this entry is an IP node */ +#define NODE_DISC_START 0x100 /* start discovery on this entry */ +#define NODE_SEED_WWPN 0x200 /* Entry scsi id is seeded for WWPN */ +#define NODE_SEED_WWNN 0x400 /* Entry scsi id is seeded for WWNN */ +#define NODE_SEED_DID 0x800 /* Entry scsi id is seeded for DID */ +#define NODE_SEED_MASK 0xe00 /* mask for seeded flags */ +#define NODE_AUTOMAP 0x1000 /* This entry was automap'ed */ +#define NODE_NS_REMOVED 0x2000 /* This entry removed from NameServer */ + +/* Defines for RegisterForEvent mask */ +#define FC_REG_LINK_EVENT 0x1 /* Register for link up / down events */ +#define FC_REG_RSCN_EVENT 0x2 /* Register for RSCN events */ +#define FC_REG_CT_EVENT 0x4 /* Register for CT request events */ +#define FC_REG_EVENT_MASK 0x3f /* event mask */ +#define FC_REG_ALL_PORTS 0x80 /* Register for all ports */ + +#define MAX_FC_EVENTS 8 /* max events user process can wait for per HBA */ +#define FC_FSTYPE_ALL 0xffff /* match on all fsTypes */ + +/* Defines for error codes */ +#define FC_ERROR_BUFFER_OVERFLOW 0xff +#define FC_ERROR_RESPONSE_TIMEOUT 0xfe +#define FC_ERROR_LINK_UNAVAILABLE 0xfd +#define FC_ERROR_INSUFFICIENT_RESOURCES 0xfc +#define FC_ERROR_EXISTING_REGISTRATION 0xfb +#define FC_ERROR_INVALID_TAG 0xfa + +/* User Library level Event structure */ +typedef struct reg_evt { + uint32 e_mask; + uint32 e_gstype; + uint32 e_pid; + uint32 e_outsz; + void (*e_func)(uint32, ...); + void * e_ctx; + void * e_out; +} RegEvent; + +/* Defines for portid for CT interface */ +#define CT_FabricCntlServer ((uint32)0xfffffd) +#define CT_NameServer ((uint32)0xfffffc) +#define CT_TimeServer ((uint32)0xfffffb) +#define CT_MgmtServer ((uint32)0xfffffa) + + +/* functions from diagnostic specification */ +uint32 InitDiagEnv(brdinfo *bi); +uint32 FreeDiagEnv(void); +uint32 SetDiagEnv(uint32 flag); +uint32 SetBrdEnv(uint32 board, uint32 flag); +uint32 GetIOinfo(uint32 board, IOinfo *ioinfo); +uint32 GetLinkInfo(uint32 board, LinkInfo *linkinfo); +uint32 GetCfgParam(uint32 board, CfgParam *cfgparam); +uint32 SetCfgParam(uint32 board, uint32 index, uint32 value); +uint32 GetNodeInfo(uint32 board, NodeInfo *nodeinfo); +int GetCTInfo(uint32 board, uint32 portid, uchar *inbuf, uint32 incnt, + uchar *outbuf, uint32 outcnt); +uint32 GetTraceInfo(uint32 board, TraceInfo *traceinfo); +uint32 SetTraceInfo(uint32 board, uint32 flag, uint32 depth); +uint32 IssueMbox(uint32 board, MAILBOX *mb, uint32 insize, uint32 outsize); +uint32 ReadMem(uint32 board, uchar *buffer, uint32 offset, uint32 count); +uint32 WriteMem(uint32 board, uchar *buffer, uint32 offset, uint32 count); +uint32 ReadFlash(uint32 board, uchar *buffer, uint32 offset, uint32 count); +uint32 WriteFlash(uint32 board, uchar *buffer, uint32 offset, uint32 count); +uint32 ReadCtlReg(uint32 board, uint32 *buffer, uint32 offset); +uint32 WriteCtlReg(uint32 board, uint32 *buffer, uint32 offset); +uint32 ReadPciCfg(uint32 board, uchar *buffer, uint32 offset, uint32 count); +uint32 WritePciCfg(uint32 board, uchar *buffer, uint32 offset, uint32 count); +uint32 ReadFcodeFlash(uint32 board, uchar *buffer, uint32 offset, uint32 count); +uint32 WriteFcodeFlash(uint32 board, uchar *buffer, uint32 offset, uint32 count); +uint32 SendElsCmd(uint32 board, uint32 opcode, uint32 did); +uint32 SendScsiCmd(uint32 board, void *wwn, void *req, uint32 sz, void *rsp, + uint32 *rsz, void *sns, uint32 *snssz); +uint32 SendScsiRead(uint32 board, void *PortWWN, uint64 l, uint32 s, + void *rsp, uint32 *rspCount, void *sns, uint32 *snsCount); +uint32 SendScsiWrite(uint32 board, void *PortWWN, uint64 l, uint32 s, + void *rsp, uint32 *rspCount, void *sns, uint32 *snsCount); +uint32 SendFcpCmd(uint32 board, void *wwn, void *req, uint32 sz, void *data, + uint32 *datasz, void *fcpRsp, uint32 *fcpRspsz); +void * RegisterForCTEvents(uint32 board, ushort type, void (*func)(uint32, ...), void *ctx, uint32 *pstat); +uint32 unRegisterForCTEvent(uint32 board, void *eventid); +uint32 RegisterForEvent(uint32 board, uint32 mask, void *type, uint32 outsz, void (*func)(uint32, ...), void *ctx); +uint32 unRegisterForEvent(uint32 board, uint32 eventid); + +#if defined(_KERNEL) || defined(__KERNEL__) +struct dfc_info { + brdinfo fc_ba; + char * fc_iomap_io; /* starting address for registers */ + char * fc_iomap_mem; /* starting address for SLIM */ + uchar * fc_hmap; /* handle for mapping memory */ + uint32 fc_refcnt; + uint32 fc_flag; +}; + +/* Define for fc_flag */ +#define DFC_STOP_IOCTL 1 /* Stop processing dfc ioctls */ +#define DFC_MBOX_ACTIVE 2 /* mailbox is active thru dfc */ + +#endif + +#endif /* _H_FCDIAG */ diff -purN -X /home/mbligh/.diff.exclude 350-autoswap/drivers/scsi/lpfc/fcelsb.c 370-emulex/drivers/scsi/lpfc/fcelsb.c --- 350-autoswap/drivers/scsi/lpfc/fcelsb.c 1969-12-31 16:00:00.000000000 -0800 +++ 370-emulex/drivers/scsi/lpfc/fcelsb.c 2004-02-28 11:20:03.000000000 -0800 @@ -0,0 +1,4792 @@ +/******************************************************************* + * This file is part of the Emulex Linux Device Driver for * + * Enterprise Fibre Channel Host Bus Adapters. * + * Refer to the README file included with this package for * + * driver version and adapter support. * + * Copyright (C) 2003 Emulex Corporation. * + * www.emulex.com * + * * + * This program is free software; you can redistribute it and/or * + * modify it under the terms of the GNU General Public License * + * as published by the Free Software Foundation; either version 2 * + * of the License, or (at your option) any later version. * + * * + * This program is distributed in the hope that it will be useful, * + * but WITHOUT ANY WARRANTY; without even the implied warranty of * + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * + * GNU General Public License for more details, a copy of which * + * can be found in the file COPYING included with this package. * + *******************************************************************/ + +#include "fc_os.h" + +#include "fc_hw.h" +#include "fc.h" + +#include "fcdiag.h" +#include "hbaapi.h" +#include "fcfgparm.h" +#include "fcmsg.h" +#include "fc_crtn.h" +#include "fc_ertn.h" /* Environment - external routine definitions */ + +extern fc_dd_ctl_t DD_CTL; +extern iCfgParam icfgparam[]; +extern char *lpfc_release_version; +extern int fc_max_els_sent; + +/* Routine Declaration - Local */ +_local_ int fc_chksparm(FC_BRD_INFO *binfo,volatile SERV_PARM *sp, uint32 cls); +_local_ int fc_els_retry(FC_BRD_INFO *binfo, RING *rp, IOCBQ *iocb, uint32 cmd, + NODELIST *nlp); +_local_ int fc_status_action(FC_BRD_INFO *binfo, IOCBQ *iocb, uint32 cmd, + NODELIST *nlp); +/* End Routine Declaration - Local */ + +/******************************************************/ +/** handle_els_event **/ +/** **/ +/** Description: Process an ELS Response Ring cmpl. **/ +/** **/ +/******************************************************/ +_static_ int +handle_els_event( +fc_dev_ctl_t *p_dev_ctl, +RING *rp, +IOCBQ *temp) +{ + IOCB * cmd; + FC_BRD_INFO * binfo; + IOCBQ * xmitiq; + volatile SERV_PARM * sp; + uint32 * lp0, * lp1; + MATCHMAP * mp, * rmp; + DMATCHMAP * drmp; + NODELIST * ndlp; + MAILBOXQ * mb; + ELS_PKT * ep; + iCfgParam * clp; + ADISC * ap; + void * ioa; + int rc; + uint32 command; + uint32 did, bumpcnt; + volatile uint32 ha_copy; + + /* Called from host_interrupt() to process ELS R0ATT */ + rc = 0; + ndlp = 0; + binfo = &BINFO; + cmd = &temp->iocb; + + /* look up xmit complete by IoTag */ + if ((xmitiq = fc_ringtxp_get(rp, cmd->ulpIoTag)) == 0) { + /* completion with missing xmit command */ + FCSTATCTR.elsStrayXmitCmpl++; + + /* Stray ELS completion */ + fc_log_printf_msg_vargs( binfo->fc_brd_no, + &fc_msgBlk0102, /* ptr to msg structure */ + fc_mes0102, /* ptr to msg */ + fc_msgBlk0102.msgPreambleStr, /* begin varargs */ + cmd->ulpCommand, + cmd->ulpIoTag); /* end varargs */ + + return(EIO); + } + temp->retry = xmitiq->retry; + + if(binfo->fc_ffstate < FC_READY) { + /* If we are in discovery, and a Link Event is pending, abandon + * discovery, clean up pending actions, and take the Link Event. + */ + ioa = FC_MAP_IO(&binfo->fc_iomap_io); /* map in io registers */ + /* Read host attention register to determine interrupt source */ + ha_copy = READ_CSR_REG(binfo, FC_HA_REG(binfo, ioa)); + FC_UNMAP_MEMIO(ioa); + + if(ha_copy & HA_LATT) { + /* Pending Link Event during Discovery */ + fc_log_printf_msg_vargs( binfo->fc_brd_no, + &fc_msgBlk0250, /* ptr to msg structure */ + fc_mes0250, /* ptr to msg */ + fc_msgBlk0250.msgPreambleStr, /* begin varargs */ + (uint32)cmd->ulpCommand, + (uint32)cmd->ulpIoTag, + (uint32)cmd->ulpStatus, + cmd->un.ulpWord[4]); /* end varargs */ + fc_abort_discovery(p_dev_ctl); + temp->retry = 0xff; + } + } + + /* Check for aborted ELS command */ + if(temp->retry == 0xff) { + + /* Aborted ELS IOCB */ + fc_log_printf_msg_vargs( binfo->fc_brd_no, + &fc_msgBlk0104, /* ptr to msg structure */ + fc_mes0104, /* ptr to msg */ + fc_msgBlk0104.msgPreambleStr, /* begin varargs */ + cmd->ulpCommand, + cmd->ulpIoTag); /* end varargs */ + switch (cmd->ulpCommand) { + case CMD_ELS_REQUEST_CR: + case CMD_ELS_REQUEST64_CR: + case CMD_ELS_REQUEST_CX: + case CMD_ELS_REQUEST64_CX: + mp = (MATCHMAP * )xmitiq->bp; + rmp = (MATCHMAP * )xmitiq->info; + lp0 = (uint32 * )mp->virt; + ndlp = 0; + command = *lp0; + switch (command) { + case ELS_CMD_PLOGI: + case ELS_CMD_LOGO: + case ELS_CMD_PRLI: + case ELS_CMD_PDISC: + case ELS_CMD_ADISC: + rmp->fc_mptr = (uchar *)0; + break; + } + break; + case CMD_XMIT_ELS_RSP_CX: /* Normal ELS response completion */ + case CMD_XMIT_ELS_RSP64_CX: /* Normal ELS response completion */ + mp = (MATCHMAP * )xmitiq->bp; + ndlp = (NODELIST * )xmitiq->ndlp; + break; + case CMD_GEN_REQUEST64_CX: + case CMD_GEN_REQUEST64_CR: + if(xmitiq->bpl == 0) { + /* User initiated request */ + drmp = (DMATCHMAP * )xmitiq->info; + drmp->dfc_flag = -1; + fc_mem_put(binfo, MEM_IOCB, (uchar * )xmitiq); + } + else { + /* Driver initiated request */ + /* Just free resources and let timer timeout */ + fc_mem_put(binfo, MEM_BPL, (uchar * )xmitiq->bpl); + if(xmitiq->bp) { + fc_mem_put(binfo, MEM_BUF, (uchar * )xmitiq->bp); + } + if(xmitiq->info) + fc_free_ct_rsp(p_dev_ctl, (MATCHMAP *)xmitiq->info); + fc_mem_put(binfo, MEM_IOCB, (uchar * )xmitiq); + } + return(0); + } + goto out2; + } + + /* ELS completion */ + fc_log_printf_msg_vargs( binfo->fc_brd_no, + &fc_msgBlk0105, /* ptr to msg structure */ + fc_mes0105, /* ptr to msg */ + fc_msgBlk0105.msgPreambleStr, /* begin varargs */ + (uint32)cmd->ulpCommand, + (uint32)cmd->ulpIoTag, + (uint32)cmd->ulpStatus, + cmd->un.ulpWord[4]); /* end varargs */ + + switch (cmd->ulpCommand) { + + case CMD_GEN_REQUEST64_CR: + if(xmitiq->bpl == 0) { + /* User initiated request */ + drmp = (DMATCHMAP * )xmitiq->info; + drmp->dfc_flag = -2; + } + else { + /* Driver initiated request */ + /* Just free resources and let timer timeout */ + fc_mem_put(binfo, MEM_BPL, (uchar * )xmitiq->bpl); + if(xmitiq->bp) { + fc_mem_put(binfo, MEM_BUF, (uchar * )xmitiq->bp); + } + if(xmitiq->info) + fc_free_ct_rsp(p_dev_ctl, (MATCHMAP *)xmitiq->info); + } + + break; + + case CMD_ELS_REQUEST_CR: /* Local error in ELS command */ + case CMD_ELS_REQUEST64_CR: /* Local error in ELS command */ + + FCSTATCTR.elsXmitErr++; + + /* Find out which command failed */ + mp = (MATCHMAP * )xmitiq->bp; + rmp = (MATCHMAP * )xmitiq->info; + ndlp = (NODELIST *)rmp->fc_mptr; + rmp->fc_mptr = (uchar *)0; + + lp0 = (uint32 * )mp->virt; + command = *lp0; + + if (fc_els_retry(binfo, rp, temp, command, ndlp) == 0) { + /* retry of ELS command failed */ + switch (command) { + case ELS_CMD_FLOGI: /* Fabric login */ + if (ndlp) + ndlp->nlp_flag &= ~NLP_REQ_SND; + fc_freenode_did(binfo, Fabric_DID, 1); + if (binfo->fc_ffstate == FC_FLOGI) { + binfo->fc_flag &= ~(FC_FABRIC | FC_PUBLIC_LOOP); + if (binfo->fc_topology == TOPOLOGY_LOOP) { + binfo->fc_edtov = FF_DEF_EDTOV; + binfo->fc_ratov = FF_DEF_RATOV; + if ((mb=(MAILBOXQ * )fc_mem_get(binfo, MEM_MBOX | MEM_PRI))) { + fc_config_link(p_dev_ctl, (MAILBOX * )mb); + if (issue_mb_cmd(binfo, (MAILBOX * )mb, MBX_NOWAIT) != MBX_BUSY) { + fc_mem_put(binfo, MEM_MBOX, (uchar * )mb); + } + } + binfo->fc_flag |= FC_DELAY_DISC; + } else { + /* Device Discovery completion error */ + fc_log_printf_msg_vargs( binfo->fc_brd_no, + &fc_msgBlk0206, /* ptr to msg structure */ + fc_mes0206, /* ptr to msg */ + fc_msgBlk0206.msgPreambleStr, /* begin varargs */ + cmd->ulpStatus, + cmd->un.ulpWord[4], + cmd->un.ulpWord[5]); /* end varargs */ + binfo->fc_ffstate = FC_ERROR; + if ((mb=(MAILBOXQ * )fc_mem_get(binfo, MEM_MBOX | MEM_PRI))) { + fc_clear_la(binfo, (MAILBOX * )mb); + if (issue_mb_cmd(binfo, (MAILBOX * )mb, MBX_NOWAIT) != MBX_BUSY) { + fc_mem_put(binfo, MEM_MBOX, (uchar * )mb); + } + } + } + } + break; + + case ELS_CMD_PLOGI: /* NPort login */ + if ((ndlp == 0) && ((ndlp = fc_findnode_odid(binfo, NLP_SEARCH_ALL, (uint32)cmd->un.elsreq.remoteID)) == 0)) { + break; + } + + /* If we are in the middle of Discovery */ + if (ndlp->nlp_action & (NLP_DO_ADDR_AUTH | NLP_DO_DISC_START | NLP_DO_RSCN)) { + /* Goto next entry */ + fc_nextnode(p_dev_ctl, ndlp); + } + + ndlp->nlp_action &= ~NLP_DO_RNID; + ndlp->nlp_flag &= ~NLP_REQ_SND; + + if((ndlp->nlp_type & (NLP_AUTOMAP | NLP_SEED_MASK)) == 0) { + fc_freenode(binfo, ndlp, 1); + } + else { + fc_freenode(binfo, ndlp, 0); + ndlp->nlp_state = NLP_LIMBO; + fc_nlp_bind(binfo, ndlp); + } + break; + + case ELS_CMD_PRLI: /* Process Log In */ + if ((ndlp == 0) && ((ndlp = fc_findnode_odid(binfo, NLP_SEARCH_ALL, (uint32)cmd->un.elsreq.remoteID)) == 0)) { + break; + } + + /* If we are in the middle of Discovery */ + if (ndlp->nlp_action & (NLP_DO_DISC_START | NLP_DO_RSCN)) { + /* Goto next entry */ + fc_nextnode(p_dev_ctl, ndlp); + } + ndlp->nlp_flag &= ~NLP_REQ_SND; + ndlp->nlp_state = NLP_LOGIN; + fc_nlp_unmap(binfo, ndlp); + break; + + case ELS_CMD_PDISC: /* Pdisc */ + case ELS_CMD_ADISC: /* Adisc */ + if ((ndlp == 0) && ((ndlp = fc_findnode_odid(binfo, NLP_SEARCH_ALL, + (uint32)cmd->un.elsreq.remoteID)) == 0)) { + break; + } + + fc_freenode(binfo, ndlp, 0); + ndlp->nlp_state = NLP_LIMBO; + fc_nlp_bind(binfo, ndlp); + + ndlp->nlp_action |= NLP_DO_DISC_START; + binfo->fc_nlp_cnt++; + fc_els_cmd(binfo, ELS_CMD_PLOGI, (void *)((ulong)cmd->un.elsreq.remoteID), (uint32)0, (ushort)0, ndlp); + break; + + case ELS_CMD_LOGO: /* Logout */ + if ((ndlp = fc_findnode_odid(binfo, NLP_SEARCH_ALL, (uint32)cmd->un.elsreq.remoteID)) == 0) { + break; + } + + /* If we are in the middle of Discovery */ + if (ndlp->nlp_action & (NLP_DO_ADDR_AUTH | NLP_DO_DISC_START | NLP_DO_RSCN)) { + /* Goto next entry */ + fc_nextnode(p_dev_ctl, ndlp); + } + + fc_freenode(binfo, ndlp, 0); + ndlp->nlp_state = NLP_LIMBO; + fc_nlp_bind(binfo, ndlp); + break; + + case ELS_CMD_FARPR: /* Farp-res */ + ep = (ELS_PKT * )lp0; + if((ndlp = fc_findnode_wwpn(binfo, NLP_SEARCH_ALL, + &ep->un.farp.RportName)) == 0) + break; + + /* If we are in the middle of Discovery */ + if (ndlp->nlp_action & NLP_DO_DISC_START) { + /* Goto next entry */ + fc_nextnode(p_dev_ctl, ndlp); + } + + fc_freenode(binfo, ndlp, 0); + ndlp->nlp_state = NLP_LIMBO; + fc_nlp_bind(binfo, ndlp); + break; + + case ELS_CMD_FARP: /* Farp-req */ + ep = (ELS_PKT * )lp0; + + if((ndlp = fc_findnode_wwpn(binfo, NLP_SEARCH_ALL, + &ep->un.farp.RportName)) == 0) + break; + + ndlp->nlp_flag &= ~NLP_FARP_SND; + ndlp->nlp_action &= ~NLP_DO_ADDR_AUTH; + break; + + case ELS_CMD_SCR: /* State Change Registration */ + break; + + case ELS_CMD_RNID: /* Receive Node Identification */ + break; + + default: + /* Unknown ELS command */ + fc_log_printf_msg_vargs( binfo->fc_brd_no, + &fc_msgBlk0106, /* ptr to msg structure */ + fc_mes0106, /* ptr to msg */ + fc_msgBlk0106.msgPreambleStr, /* begin varargs */ + command); /* end varargs */ + FCSTATCTR.elsCmdPktInval++; + break; + } + /* ELS command completion error */ + fc_log_printf_msg_vargs( binfo->fc_brd_no, + &fc_msgBlk0107, /* ptr to msg structure */ + fc_mes0107, /* ptr to msg */ + fc_msgBlk0107.msgPreambleStr, /* begin varargs */ + cmd->ulpCommand, + cmd->ulpStatus, + cmd->un.ulpWord[4], + cmd->un.ulpWord[5]); /* end varargs */ + } + else { + /* Retry in progress */ + if ((command == ELS_CMD_PLOGI) && + ((cmd->un.ulpWord[4] & 0xff) == IOERR_LOOP_OPEN_FAILURE)) { + if (ndlp->nlp_action & (NLP_DO_ADDR_AUTH | NLP_DO_DISC_START | NLP_DO_RSCN)) { + /* Goto next entry */ + fc_nextnode(p_dev_ctl, ndlp); + } + } + } + + if (xmitiq->bpl) { + fc_mem_put(binfo, MEM_BPL, (uchar * )xmitiq->bpl); + } + fc_mem_put(binfo, MEM_BUF, (uchar * )mp); + fc_mem_put(binfo, MEM_BUF, (uchar * )xmitiq->info); + break; + + case CMD_XMIT_ELS_RSP_CX: /* Normal ELS response completion */ + case CMD_XMIT_ELS_RSP64_CX: /* Normal ELS response completion */ + + ndlp = (NODELIST * )xmitiq->ndlp; + did = 0; + bumpcnt = 0; + if ((ndlp) && (ndlp->nlp_flag & NLP_SND_PLOGI)) { + ndlp->nlp_flag &= ~NLP_SND_PLOGI; + did = ndlp->nlp_DID; + if((binfo->fc_flag & FC_RSCN_MODE) || + (binfo->fc_ffstate < FC_READY)) { + binfo->fc_nlp_cnt++; + bumpcnt = 1; + } + } + mp = (MATCHMAP * )xmitiq->bp; + lp0 = (uint32 * )mp->virt; + /* get command that errored */ + command = *lp0++; + sp = (volatile SERV_PARM * )lp0; + if (cmd->ulpStatus) { + /* Error occurred sending ELS response */ + /* check to see if we should retry */ + /* ELS response completion error */ + fc_log_printf_msg_vargs( binfo->fc_brd_no, + &fc_msgBlk0108, /* ptr to msg structure */ + fc_mes0108, /* ptr to msg */ + fc_msgBlk0108.msgPreambleStr, /* begin varargs */ + cmd->ulpCommand, + cmd->ulpStatus, + cmd->un.ulpWord[4], + cmd->un.ulpWord[5]); /* end varargs */ + FCSTATCTR.elsXmitErr++; + + if (fc_els_retry(binfo, rp, temp, command, ndlp) == 0) { + /* No retries */ + if ((ndlp) && (ndlp->nlp_flag & NLP_RM_ENTRY) && + !(ndlp->nlp_flag & NLP_REQ_SND)) { + if (ndlp->nlp_type & NLP_FCP_TARGET) { + ndlp->nlp_flag &= ~NLP_RM_ENTRY; + ndlp->nlp_action &= ~NLP_DO_ADDR_AUTH; + if(binfo->fc_ffstate == FC_READY) { + if(!(binfo->fc_flag & FC_RSCN_MODE)) { + binfo->fc_flag |= FC_RSCN_MODE; + ndlp->nlp_action |= NLP_DO_RSCN; + ndlp->nlp_flag &= ~NLP_NODEV_TMO; + fc_nextrscn(p_dev_ctl, 1); + } + } + else { + ndlp->nlp_action |= NLP_DO_DISC_START; + fc_nextdisc(p_dev_ctl, 1); + } + } else { + fc_freenode(binfo, ndlp, 0); + ndlp->nlp_state = NLP_LIMBO; + fc_nlp_bind(binfo, ndlp); + } + } + else { + if (ndlp) { + if(!(ndlp->nlp_flag & NLP_REQ_SND)) { + fc_freenode(binfo, ndlp, 0); + ndlp->nlp_state = NLP_LIMBO; + fc_nlp_bind(binfo, ndlp); + } + } + } + } + } else { + FCSTATCTR.elsXmitCmpl++; + if(ndlp) { + /* ELS response completion */ + fc_log_printf_msg_vargs( binfo->fc_brd_no, + &fc_msgBlk0109, /* ptr to msg structure */ + fc_mes0109, /* ptr to msg */ + fc_msgBlk0109.msgPreambleStr, /* begin varargs */ + ndlp->nlp_DID, + ndlp->nlp_type, + ndlp->nlp_flag, + ndlp->nlp_state); /* end varargs */ + if ((ndlp->nlp_flag & NLP_REG_INP)) { + uint32 size; + MATCHMAP * bmp; + ULP_BDE64 * bpl; + + bmp = (MATCHMAP *)(xmitiq->bpl); + bpl = (ULP_BDE64 * )bmp->virt; + bpl->tus.w = PCIMEM_LONG(bpl->tus.w); + size = (uint32)bpl->tus.f.bdeSize; + if(size == (sizeof(SERV_PARM) + sizeof(uint32))) { + fc_process_reglogin(p_dev_ctl, ndlp); + } + } + + if ((ndlp->nlp_flag & NLP_RM_ENTRY) && + !(ndlp->nlp_flag & NLP_REQ_SND)) { + if (ndlp->nlp_type & NLP_FCP_TARGET) { + ndlp->nlp_flag &= ~NLP_RM_ENTRY; + ndlp->nlp_action &= ~NLP_DO_ADDR_AUTH; + if(binfo->fc_ffstate == FC_READY) { + fc_freenode(binfo, ndlp, 0); + ndlp->nlp_state = NLP_LIMBO; + fc_nlp_bind(binfo, ndlp); + if(!(binfo->fc_flag & FC_RSCN_MODE)) { + did = 0; + if(bumpcnt) + binfo->fc_nlp_cnt--; + + binfo->fc_flag |= FC_RSCN_MODE; + ndlp->nlp_action |= NLP_DO_RSCN; + ndlp->nlp_flag &= ~NLP_NODEV_TMO; + fc_nextrscn(p_dev_ctl, 1); + } + } + else { + did = 0; + if(bumpcnt) + binfo->fc_nlp_cnt--; + + ndlp->nlp_action |= NLP_DO_DISC_START; + fc_nextdisc(p_dev_ctl, 1); + } + } else { + if (ndlp->nlp_type & NLP_IP_NODE) { + fc_freenode(binfo, ndlp, 0); + ndlp->nlp_state = NLP_LIMBO; + fc_nlp_bind(binfo, ndlp); + } + else { + fc_freenode(binfo, ndlp, 1); + } + } + } + } + } + + if (xmitiq->bpl) { + fc_mem_put(binfo, MEM_BPL, (uchar * )xmitiq->bpl); + } + fc_mem_put(binfo, MEM_BUF, (uchar * )mp); + if(did && (!(ndlp->nlp_flag & NLP_NS_REMOVED))) { + fc_els_cmd(binfo, ELS_CMD_PLOGI, (void *)((ulong)did), + (uint32)0, (ushort)0, ndlp); + } + break; + + case CMD_GEN_REQUEST64_CX: + if(xmitiq->bpl == 0) { + /* User initiated request */ + drmp = (DMATCHMAP * )xmitiq->info; + fc_mpdata_sync(drmp->dfc.dma_handle, 0, 0, DDI_DMA_SYNC_FORKERNEL); + + if (cmd->ulpStatus) { + /* Error occurred sending ELS command */ + if ((cmd->un.ulpWord[4] & 0xff) == IOERR_SEQUENCE_TIMEOUT) + drmp->dfc_flag = -1; + else + drmp->dfc_flag = -2; + } + else { + drmp->dfc_flag = (int)(cmd->un.genreq64.bdl.bdeSize); + } + } + else { + /* Driver initiated request */ + if (cmd->ulpStatus == 0) { + mp = (MATCHMAP * )xmitiq->bp; + ndlp = (NODELIST *)mp->fc_mptr; + if(ndlp && (ndlp->nlp_DID == NameServer_DID)) { + fc_ns_rsp(p_dev_ctl, (NODELIST *)mp->fc_mptr, + (MATCHMAP *)xmitiq->info, + (uint32)(cmd->un.genreq64.bdl.bdeSize)); + } + /* FDMI */ + if(ndlp && (ndlp->nlp_DID == FDMI_DID)) { + fc_fdmi_rsp(p_dev_ctl, (MATCHMAP *)mp, (MATCHMAP *)xmitiq->info); + } + } + if(xmitiq->info) + fc_free_ct_rsp(p_dev_ctl, (MATCHMAP *)xmitiq->info); + fc_mem_put(binfo, MEM_BPL, (uchar * )xmitiq->bpl); + if(xmitiq->bp) { + fc_mem_put(binfo, MEM_BUF, (uchar * )xmitiq->bp); + } + } + break; + + + case CMD_ELS_REQUEST_CX: /* Normal ELS command completion */ + case CMD_ELS_REQUEST64_CX: /* Normal ELS command completion */ + + /* get command that was accepted */ + mp = (MATCHMAP * )xmitiq->bp; + lp0 = (uint32 * )mp->virt; + command = *lp0; + + /* ELS command successful, get ptr to service params */ + rmp = (MATCHMAP * )xmitiq->info; + ndlp = (NODELIST *)rmp->fc_mptr; + rmp->fc_mptr = (uchar *)0; + + lp1 = (uint32 * )rmp->virt; + fc_mpdata_sync(rmp->dma_handle, 0, 0, DDI_DMA_SYNC_FORKERNEL); + + sp = (volatile SERV_PARM * )((char *)lp1 + sizeof(uint32)); + + if (cmd->ulpStatus) { + /* Error occurred sending ELS command */ + FCSTATCTR.elsXmitErr++; + /* ELS command completion error */ + fc_log_printf_msg_vargs( binfo->fc_brd_no, + &fc_msgBlk0110, /* ptr to msg structure */ + fc_mes0110, /* ptr to msg */ + fc_msgBlk0110.msgPreambleStr, /* begin varargs */ + command, + cmd->ulpStatus, + cmd->un.ulpWord[4], + cmd->un.ulpWord[5]); /* end varargs */ + if ((command == ELS_CMD_FARP) || + (command == ELS_CMD_FARPR)) { + ep = (ELS_PKT * )lp0; + if((ndlp=fc_findnode_wwpn(binfo, NLP_SEARCH_ALL, &ep->un.farp.RportName))) { + ndlp->nlp_flag &= ~NLP_FARP_SND; + ndlp->nlp_action &= ~NLP_DO_ADDR_AUTH; + } + } + + /* If error occurred on ADISC/PDISC, check to see if address + * still needs to be authenticated. + */ + if ((command == ELS_CMD_ADISC) || (command == ELS_CMD_PDISC)) { + if(ndlp == 0) { + ndlp = fc_findnode_odid(binfo, NLP_SEARCH_ALL, + (uint32)cmd->un.elsreq.remoteID); + } + } + else { + if (command == ELS_CMD_PLOGI) { + if(ndlp == 0) { + ndlp = fc_findnode_odid(binfo, NLP_SEARCH_ALL, + (uint32)cmd->un.elsreq.remoteID); + } + } + } + + /* check to see if we should retry */ + if (fc_els_retry(binfo, rp, temp, command, ndlp) == 0) { + /* retry of ELS command failed */ + switch (command) { + case ELS_CMD_FLOGI: + if (ndlp) + ndlp->nlp_flag &= ~NLP_REQ_SND; + if (binfo->fc_ffstate == FC_FLOGI) { + binfo->fc_flag &= ~(FC_FABRIC | FC_PUBLIC_LOOP); + fc_freenode_did(binfo, Fabric_DID, 1); + if (binfo->fc_topology == TOPOLOGY_LOOP) { + binfo->fc_edtov = FF_DEF_EDTOV; + binfo->fc_ratov = FF_DEF_RATOV; + if ((mb = (MAILBOXQ * )fc_mem_get(binfo, MEM_MBOX | MEM_PRI))) { + fc_config_link(p_dev_ctl, (MAILBOX * )mb); + if (issue_mb_cmd(binfo, (MAILBOX * )mb, MBX_NOWAIT) + != MBX_BUSY) { + fc_mem_put(binfo, MEM_MBOX, (uchar * )mb); + } + } + binfo->fc_flag |= FC_DELAY_DISC; + } else { + /* Device Discovery completion error */ + fc_log_printf_msg_vargs( binfo->fc_brd_no, + &fc_msgBlk0207, /* ptr to msg structure */ + fc_mes0207, /* ptr to msg */ + fc_msgBlk0207.msgPreambleStr); /* begin & end varargs */ + binfo->fc_ffstate = FC_ERROR; + if ((mb = (MAILBOXQ * )fc_mem_get(binfo, + MEM_MBOX | MEM_PRI))) { + fc_clear_la(binfo, (MAILBOX * )mb); + if (issue_mb_cmd(binfo, (MAILBOX * )mb, MBX_NOWAIT) + != MBX_BUSY) { + fc_mem_put(binfo, MEM_MBOX, (uchar * )mb); + } + } + } + } + break; + + case ELS_CMD_PLOGI: + /* Cache entry in case we are in a + * LOGI collision. + */ + if ((ndlp == 0) && ((ndlp = fc_findnode_odid(binfo, NLP_SEARCH_ALL, + (uint32)cmd->un.elsreq.remoteID)) == 0)) { + break; + } + + /* If we are in the middle of Discovery */ + if (ndlp->nlp_action & (NLP_DO_ADDR_AUTH | NLP_DO_DISC_START | NLP_DO_RSCN)) { + if((ndlp->nlp_state < NLP_LOGIN) && + !(ndlp->nlp_flag & NLP_REG_INP)) { + /* Goto next entry */ + fc_nextnode(p_dev_ctl, ndlp); + } + } + + ndlp->nlp_action &= ~NLP_DO_RNID; + ndlp->nlp_flag &= ~NLP_REQ_SND; + + if((ndlp->nlp_type & (NLP_AUTOMAP | NLP_SEED_MASK)) == 0) { + fc_freenode(binfo, ndlp, 1); + } + else { + fc_freenode(binfo, ndlp, 0); + ndlp->nlp_state = NLP_LIMBO; + fc_nlp_bind(binfo, ndlp); + } + break; + + case ELS_CMD_PRLI: + if ((ndlp == 0) && ((ndlp = fc_findnode_odid(binfo, NLP_SEARCH_ALL, + (uint32)cmd->un.elsreq.remoteID)) == 0)) { + break; + } + + /* If we are in the middle of Discovery */ + if (ndlp->nlp_action & (NLP_DO_DISC_START | NLP_DO_RSCN)) { + /* Goto next entry */ + fc_nextnode(p_dev_ctl, ndlp); + } + ndlp->nlp_flag &= ~NLP_REQ_SND; + ndlp->nlp_state = NLP_LOGIN; + fc_nlp_unmap(binfo, ndlp); + break; + + case ELS_CMD_PDISC: + case ELS_CMD_ADISC: + if ((ndlp == 0) && ((ndlp = fc_findnode_odid(binfo, NLP_SEARCH_ALL, + (uint32)cmd->un.elsreq.remoteID)) == 0)) { + break; + } + + fc_freenode(binfo, ndlp, 0); + ndlp->nlp_state = NLP_LIMBO; + fc_nlp_bind(binfo, ndlp); + + ndlp->nlp_action |= NLP_DO_DISC_START; + binfo->fc_nlp_cnt++; + fc_els_cmd(binfo, ELS_CMD_PLOGI, + (void *)((ulong)cmd->un.elsreq.remoteID), + (uint32)0, (ushort)0, ndlp); + break; + + case ELS_CMD_LOGO: + if ((ndlp == 0) && ((ndlp = fc_findnode_odid(binfo, NLP_SEARCH_ALL, + (uint32)cmd->un.elsreq.remoteID)) == 0)) { + break; + } + + /* If we are in the middle of Discovery */ + if (ndlp->nlp_action & (NLP_DO_ADDR_AUTH | NLP_DO_DISC_START | NLP_DO_RSCN)) { + /* Goto next entry */ + fc_nextnode(p_dev_ctl, ndlp); + } + + fc_freenode(binfo, ndlp, 0); + ndlp->nlp_state = NLP_LIMBO; + fc_nlp_bind(binfo, ndlp); + break; + + case ELS_CMD_FARP: /* Farp-req */ + if (ndlp == 0) + break; + + ndlp->nlp_flag &= ~NLP_FARP_SND; + ndlp->nlp_action &= ~NLP_DO_ADDR_AUTH; + break; + + case ELS_CMD_FARPR: /* Farp-res */ + if (ndlp == 0) + break; + + ndlp->nlp_flag &= ~NLP_FARP_SND; + ndlp->nlp_action &= ~NLP_DO_ADDR_AUTH; + fc_freenode(binfo, ndlp, 0); + ndlp->nlp_state = NLP_LIMBO; + fc_nlp_bind(binfo, ndlp); + break; + + case ELS_CMD_SCR: /* State Change Registration */ + break; + + case ELS_CMD_RNID: /* Node Identification */ + break; + + default: + FCSTATCTR.elsCmdPktInval++; + + /* Unknown ELS command */ + fc_log_printf_msg_vargs( binfo->fc_brd_no, + &fc_msgBlk0111, /* ptr to msg structure */ + fc_mes0111, /* ptr to msg */ + fc_msgBlk0111.msgPreambleStr, /* begin varargs */ + command); /* end varargs */ + break; + } + } + else { + /* Retry in progress */ + if ((command == ELS_CMD_PLOGI) && + ((cmd->un.ulpWord[4] & 0xff) == IOERR_LOOP_OPEN_FAILURE)) { + if (ndlp->nlp_action & (NLP_DO_ADDR_AUTH | NLP_DO_DISC_START | NLP_DO_RSCN)) { + /* Goto next entry */ + fc_nextnode(p_dev_ctl, ndlp); + } + } + } + } else { + FCSTATCTR.elsXmitCmpl++; + + /* Process successful command completion */ + switch (command) { + case ELS_CMD_FLOGI: + /* FLOGI completes successfully */ + fc_log_printf_msg_vargs( binfo->fc_brd_no, + &fc_msgBlk0208, /* ptr to msg structure */ + fc_mes0208, /* ptr to msg */ + fc_msgBlk0208.msgPreambleStr, /* begin varargs */ + cmd->un.ulpWord[4], + sp->cmn.e_d_tov, + sp->cmn.w2.r_a_tov, + sp->cmn.edtovResolution); /* end varargs */ + if (ndlp) + ndlp->nlp_flag &= ~NLP_REQ_SND; + + /* register the login, REG_LOGIN */ + if (binfo->fc_ffstate == FC_FLOGI) { + /* If Common Service Parameters indicate Nport + * we are point to point, if Fport we are Fabric. + */ + if (sp->cmn.fPort) { + binfo->fc_flag |= FC_FABRIC; + if (sp->cmn.edtovResolution) { + /* E_D_TOV ticks are in nanoseconds */ + binfo->fc_edtov = (SWAP_DATA(sp->cmn.e_d_tov) + 999999) / 1000000; + } else { + /* E_D_TOV ticks are in milliseconds */ + binfo->fc_edtov = SWAP_DATA(sp->cmn.e_d_tov); + } + binfo->fc_ratov = (SWAP_DATA(sp->cmn.w2.r_a_tov) + 999) / 1000; + + if (binfo->fc_topology == TOPOLOGY_LOOP) { + binfo->fc_flag |= FC_PUBLIC_LOOP; + } else { + /* If we are a N-port connected to a Fabric, + * fixup sparam's so logins to devices on + * remote loops work. + */ + binfo->fc_sparam.cmn.altBbCredit = 1; + } + + binfo->fc_myDID = cmd->un.ulpWord[4] & Mask_DID; + + if ((ndlp == 0) && ((ndlp = fc_findnode_odid(binfo, NLP_SEARCH_ALL, + (uint32)cmd->un.elsreq.remoteID)) == 0)) { + break; + } + ndlp->nlp_type |= NLP_FABRIC; + ndlp->nlp_flag &= ~NLP_REQ_SND; + + fc_nlp_logi(binfo, ndlp, + (NAME_TYPE *)&sp->portName, (NAME_TYPE *)&sp->nodeName); + + if ((mb=(MAILBOXQ * )fc_mem_get(binfo, MEM_MBOX | MEM_PRI))) { + fc_config_link(p_dev_ctl, (MAILBOX * )mb); + if (issue_mb_cmd(binfo, (MAILBOX * )mb, MBX_NOWAIT) + != MBX_BUSY) { + fc_mem_put(binfo, MEM_MBOX, (uchar * )mb); + } + } + + /* register the login with adapter */ + if (ndlp->nlp_Rpi == 0) { + fc_bcopy((void *)sp, (void *) & binfo->fc_fabparam, + sizeof(SERV_PARM)); + + if ((mb = (MAILBOXQ * )fc_mem_get(binfo, + MEM_MBOX | MEM_PRI))) { + fc_reg_login(binfo, cmd->un.elsreq.remoteID, + (uchar * )sp, (MAILBOX * )mb, 0); + if (issue_mb_cmd(binfo, (MAILBOX * )mb, MBX_NOWAIT) + != MBX_BUSY) { + fc_mem_put(binfo, MEM_MBOX, (uchar * )mb); + } + } + } + + binfo->fc_flag |= FC_DELAY_DISC; + } else { + binfo->fc_flag &= ~(FC_FABRIC | FC_PUBLIC_LOOP); + binfo->fc_edtov = FF_DEF_EDTOV; + binfo->fc_ratov = FF_DEF_RATOV; + if ((rc = fc_geportname((NAME_TYPE * ) & binfo->fc_portname, + (NAME_TYPE * ) & sp->portName))) { + /* This side will initiate the PLOGI */ + binfo->fc_flag |= FC_PT2PT_PLOGI; + + /* N_Port ID cannot be 0, set our to LocalID the + * other side will be RemoteID. + */ + fc_freenode_did(binfo, 0, 1); + + /* not equal */ + if (rc == 1) + binfo->fc_myDID = PT2PT_LocalID; + rc = 0; + + if ((mb = (MAILBOXQ * )fc_mem_get(binfo, + MEM_MBOX | MEM_PRI))) { + fc_config_link(p_dev_ctl, (MAILBOX * )mb); + if (issue_mb_cmd(binfo, (MAILBOX * )mb, MBX_NOWAIT) + != MBX_BUSY) { + fc_mem_put(binfo, MEM_MBOX, (uchar * )mb); + } + } + if ((ndlp = fc_findnode_odid(binfo, NLP_SEARCH_ALL, (uint32)binfo->fc_myDID)) == 0) { + if((ndlp = (NODELIST *)fc_mem_get(binfo, MEM_NLP))) { + fc_bzero((void *)ndlp, sizeof(NODELIST)); + ndlp->sync = binfo->fc_sync; + ndlp->capabilities = binfo->fc_capabilities; + ndlp->nlp_DID = binfo->fc_myDID; + ndlp->nlp_state = NLP_LIMBO; + fc_nlp_bind(binfo, ndlp); + } + else + break; + } + ndlp->nlp_DID = binfo->fc_myDID; + fc_nlp_logi(binfo, ndlp, + (NAME_TYPE *)&sp->portName, (NAME_TYPE *)&sp->nodeName); + } else { + if ((mb = (MAILBOXQ * )fc_mem_get(binfo, + MEM_MBOX | MEM_PRI))) { + fc_config_link(p_dev_ctl, (MAILBOX * )mb); + if (issue_mb_cmd(binfo, (MAILBOX * )mb, MBX_NOWAIT) + != MBX_BUSY) { + fc_mem_put(binfo, MEM_MBOX, (uchar * )mb); + } + } + } + binfo->fc_flag |= FC_PT2PT; + /* Use Fabric timer as pt2pt link up timer */ + binfo->fc_fabrictmo = (2 * binfo->fc_ratov) + + ((4 * binfo->fc_edtov) / 1000) + 1; + if(FABRICTMO) { + fc_clk_res(p_dev_ctl, binfo->fc_fabrictmo, FABRICTMO); + } + else { + FABRICTMO = fc_clk_set(p_dev_ctl, binfo->fc_fabrictmo, + fc_fabric_timeout, 0, 0); + } + fc_freenode_did(binfo, Fabric_DID, 1); + + /* This is Login at init, clear la */ + if ((mb=(MAILBOXQ * )fc_mem_get(binfo, MEM_MBOX | MEM_PRI))) { + binfo->fc_ffstate = FC_CLEAR_LA; + fc_clear_la(binfo, (MAILBOX * )mb); + if (issue_mb_cmd(binfo, (MAILBOX * )mb, MBX_NOWAIT) + != MBX_BUSY) { + fc_mem_put(binfo, MEM_MBOX, (uchar * )mb); + } + } + } + } else { + FCSTATCTR.elsRcvDrop++; + fc_freenode_did(binfo, Fabric_DID, 1); + } + break; + + case ELS_CMD_PLOGI: + /* PLOGI completes successfully */ + fc_log_printf_msg_vargs( binfo->fc_brd_no, + &fc_msgBlk0112, /* ptr to msg structure */ + fc_mes0112, /* ptr to msg */ + fc_msgBlk0112.msgPreambleStr, /* begin varargs */ + cmd->un.elsreq.remoteID, + cmd->un.ulpWord[4], + cmd->un.ulpWord[5], + binfo->fc_ffstate); /* end varargs */ + if ((ndlp == 0) && ((ndlp = fc_findnode_odid(binfo, NLP_SEARCH_ALL, + (uint32)cmd->un.elsreq.remoteID)) == 0)) { + break; + } + fc_nlp_logi(binfo, ndlp, + (NAME_TYPE *)&sp->portName, (NAME_TYPE *)&sp->nodeName); + + if (ndlp->nlp_DID != NameServer_DID) + ndlp->nlp_action &= ~NLP_DO_ADDR_AUTH; + + + ndlp->nlp_action &= ~NLP_DO_RNID; + + if (binfo->fc_flag & FC_PT2PT) { + /* Device Discovery completes */ + fc_log_printf_msg_vargs( binfo->fc_brd_no, + &fc_msgBlk0209, /* ptr to msg structure */ + fc_mes0209, /* ptr to msg */ + fc_msgBlk0209.msgPreambleStr); /* begin & end varargs */ + /* Fix up any changed RPIs in FCP IOCBs queued up a txq */ + fc_fcp_fix_txq(p_dev_ctl); + + binfo->fc_ffstate = FC_READY; + + binfo->fc_firstopen = 0; + if(FABRICTMO) { + fc_clk_can(p_dev_ctl, FABRICTMO); + FABRICTMO = 0; + } + ndlp->nlp_Rpi = 0; /* Keep the same rpi */ + } + + if (ndlp->nlp_Rpi) { + /* must explicitly unregister the login, UREG_LOGIN */ + /* This is so pending I/Os get returned with NO_RPI */ + if ((mb = (MAILBOXQ * )fc_mem_get(binfo, MEM_MBOX | MEM_PRI))) { + fc_unreg_login(binfo, ndlp->nlp_Rpi, (MAILBOX * )mb); + if (issue_mb_cmd(binfo,(MAILBOX * )mb,MBX_NOWAIT) != MBX_BUSY) { + fc_mem_put(binfo, MEM_MBOX, (uchar * )mb); + } + } + binfo->fc_nlplookup[ndlp->nlp_Rpi] = 0; + ndlp->nlp_Rpi = 0; + } + + /* register the login, REG_LOGIN */ + if ((mb = (MAILBOXQ * )fc_mem_get(binfo, MEM_MBOX | MEM_PRI))) { + fc_reg_login(binfo, cmd->un.elsreq.remoteID, (uchar * )sp, + (MAILBOX * )mb, 0); + if (issue_mb_cmd(binfo,(MAILBOX * )mb,MBX_NOWAIT) != MBX_BUSY) { + fc_mem_put(binfo, MEM_MBOX, (uchar * )mb); + } + } + + /* Fill in the FCP/IP class */ + { + clp = DD_CTL.p_config[binfo->fc_brd_no]; + if ( (clp[CFG_FCP_CLASS].a_current == CLASS2) && + (sp->cls2.classValid) ) { + ndlp->id.nlp_fcp_info |= CLASS2; + } else { + ndlp->id.nlp_fcp_info |= CLASS3; + } + + if ( (clp[CFG_IP_CLASS].a_current == CLASS2) && + (sp->cls2.classValid) ) { + ndlp->id.nlp_ip_info = CLASS2; + } else { + ndlp->id.nlp_ip_info = CLASS3; + } + } + + /* REG_LOGIN cmpl will goto nextnode */ + ndlp->nlp_flag &= ~NLP_REQ_SND; + ndlp->nlp_flag |= NLP_REG_INP; + break; + + case ELS_CMD_PRLI: + /* PRLI completes successfully */ + fc_log_printf_msg_vargs( binfo->fc_brd_no, + &fc_msgBlk0113, /* ptr to msg structure */ + fc_mes0113, /* ptr to msg */ + fc_msgBlk0113.msgPreambleStr, /* begin varargs */ + cmd->un.elsreq.remoteID, + cmd->un.ulpWord[4], + cmd->un.ulpWord[5], + binfo->fc_ffstate); /* end varargs */ + if ((ndlp == 0) && ((ndlp = fc_findnode_odid(binfo, NLP_SEARCH_ALL, + cmd->un.elsreq.remoteID)) == 0)) + break; + + ndlp->nlp_flag &= ~NLP_REQ_SND; + + /* If we are in the middle of Discovery or in pt2pt mode */ + if ((ndlp->nlp_action & (NLP_DO_DISC_START | NLP_DO_RSCN)) || + (binfo->fc_flag & FC_PT2PT)) { + int index; + node_t * node_ptr; + PRLI * npr; + + npr = (PRLI * )sp; + clp = DD_CTL.p_config[binfo->fc_brd_no]; + if ((npr->acceptRspCode == PRLI_REQ_EXECUTED) && + (npr->prliType == PRLI_FCP_TYPE) && + (npr->targetFunc == 1)) { + + if(clp[CFG_FCP_ON].a_current) { + if (!(fc_assign_scsid(p_dev_ctl, ndlp))) { + /* No more SCSI ids available */ + fc_nextnode(p_dev_ctl, ndlp); + ndlp->nlp_state = NLP_PRLI; + fc_nlp_unmap(binfo, ndlp); + ndlp->nlp_action &= ~NLP_DO_SCSICMD; + break; + } + + if ((node_ptr = (node_t * )ndlp->nlp_targetp) == NULL) { + index = INDEX(ndlp->id.nlp_pan, ndlp->id.nlp_sid); + node_ptr = binfo->device_queue_hash[index].node_ptr; + } + /* PRLI target assigned */ + fc_log_printf_msg_vargs( binfo->fc_brd_no, + &fc_msgBlk0210, /* ptr to msg structure */ + fc_mes0210, /* ptr to msg */ + fc_msgBlk0210.msgPreambleStr, /* begin varargs */ + cmd->un.ulpWord[5], /* did */ + ndlp->id.nlp_pan, + ndlp->id.nlp_sid); /* end varargs */ + /* Now check for FCP-2 support */ + if(node_ptr) { + if(npr->Retry && npr->TaskRetryIdReq) + node_ptr->flags |= FC_FCP2_RECOVERY; + else + node_ptr->flags &= ~FC_FCP2_RECOVERY; + } + + } + else { + goto prlierr; + } + + /* If PRLI is successful, we have a FCP target device */ + if (((PRLI * )sp)->Retry == 1) { + ndlp->id.nlp_fcp_info |= NLP_FCP_2_DEVICE; + } + ndlp->nlp_type |= NLP_FCP_TARGET; + if((ndlp->nlp_type & NLP_SEED_MASK) == 0) { + switch(p_dev_ctl->fcp_mapping) { + case FCP_SEED_DID: + ndlp->nlp_type |= NLP_SEED_DID; + break; + case FCP_SEED_WWPN: + ndlp->nlp_type |= NLP_SEED_WWPN; + break; + case FCP_SEED_WWNN: + default: + ndlp->nlp_type |= NLP_SEED_WWNN; + break; + } + if(clp[CFG_AUTOMAP].a_current) + ndlp->nlp_type |= NLP_AUTOMAP; + } + ndlp->nlp_state = NLP_ALLOC; + fc_nlp_map(binfo, ndlp); + + /* Fix up any changed RPIs in FCP IOCBs queued up a txq */ + fc_fcp_fix_txq(p_dev_ctl); + + fc_nextnode(p_dev_ctl, ndlp); + } else { +prlierr: + ndlp->nlp_state = NLP_LOGIN; + fc_nlp_unmap(binfo, ndlp); + fc_nextnode(p_dev_ctl, ndlp); + } + } + else { + PRLI * npr; + + npr = (PRLI * )sp; + if ((npr->acceptRspCode == PRLI_REQ_EXECUTED) && + (npr->prliType == PRLI_FCP_TYPE) && + (npr->targetFunc == 1)) { + if(ndlp->nlp_type & NLP_FCP_TARGET) { + ndlp->nlp_state = NLP_ALLOC; + fc_nlp_map(binfo, ndlp); + } + else { + ndlp->nlp_state = NLP_PRLI; + fc_nlp_unmap(binfo, ndlp); + } + } + else { + ndlp->nlp_state = NLP_LOGIN; + fc_nlp_unmap(binfo, ndlp); + } + } + + ndlp->nlp_action &= ~NLP_DO_SCSICMD; + break; + + case ELS_CMD_PRLO: + /* PRLO completes successfully */ + fc_log_printf_msg_vargs( binfo->fc_brd_no, + &fc_msgBlk0114, /* ptr to msg structure */ + fc_mes0114, /* ptr to msg */ + fc_msgBlk0114.msgPreambleStr, /* begin varargs */ + cmd->un.elsreq.remoteID, + cmd->un.ulpWord[4], + cmd->un.ulpWord[5], + binfo->fc_ffstate); /* end varargs */ + break; + + case ELS_CMD_LOGO: + /* LOGO completes successfully */ + fc_log_printf_msg_vargs( binfo->fc_brd_no, + &fc_msgBlk0115, /* ptr to msg structure */ + fc_mes0115, /* ptr to msg */ + fc_msgBlk0115.msgPreambleStr, /* begin varargs */ + cmd->un.elsreq.remoteID, + cmd->un.ulpWord[4], + cmd->un.ulpWord[5], + binfo->fc_ffstate); /* end varargs */ + if ((ndlp == 0) && ((ndlp = fc_findnode_odid(binfo, NLP_SEARCH_ALL, + (uint32)cmd->un.elsreq.remoteID)) == 0)) { + break; + } + + /* If we are in the middle of Discovery */ + if (ndlp->nlp_action & (NLP_DO_ADDR_AUTH | NLP_DO_DISC_START | NLP_DO_RSCN)) { + /* Goto next entry */ + fc_nextnode(p_dev_ctl, ndlp); + } + + fc_freenode(binfo, ndlp, 0); + ndlp->nlp_state = NLP_LIMBO; + fc_nlp_bind(binfo, ndlp); + break; + + case ELS_CMD_PDISC: + /* PDISC completes successfully */ + fc_log_printf_msg_vargs( binfo->fc_brd_no, + &fc_msgBlk0116, /* ptr to msg structure */ + fc_mes0116, /* ptr to msg */ + fc_msgBlk0116.msgPreambleStr, /* begin varargs */ + cmd->un.elsreq.remoteID, + cmd->un.ulpWord[4], + cmd->un.ulpWord[5], + binfo->fc_ffstate); /* end varargs */ + if ((ndlp == 0) && ((ndlp = fc_findnode_odid(binfo, NLP_SEARCH_ALL, + (uint32)cmd->un.elsreq.remoteID)) == 0)) { + break; + } + + /* If we are in the middle of Address Authentication */ + if (ndlp->nlp_action & (NLP_DO_ADDR_AUTH)) { + if (fc_chkpadisc(binfo, ndlp, &sp->nodeName, + &sp->portName) == 0) { + fc_freenode(binfo, ndlp, 0); + ndlp->nlp_state = NLP_LIMBO; + fc_nlp_bind(binfo, ndlp); + ndlp->nlp_action |= NLP_DO_DISC_START; + } + /* Goto next entry */ + fc_nextnode(p_dev_ctl, ndlp); + } + ndlp->nlp_flag &= ~NLP_REQ_SND_PDISC; + break; + + case ELS_CMD_ADISC: + /* ADISC completes successfully */ + fc_log_printf_msg_vargs( binfo->fc_brd_no, + &fc_msgBlk0117, /* ptr to msg structure */ + fc_mes0117, /* ptr to msg */ + fc_msgBlk0117.msgPreambleStr, /* begin varargs */ + cmd->un.elsreq.remoteID, + cmd->un.ulpWord[4], + cmd->un.ulpWord[5], + binfo->fc_ffstate); /* end varargs */ + if ((ndlp == 0) && ((ndlp = fc_findnode_odid(binfo, NLP_SEARCH_ALL, + (uint32)cmd->un.elsreq.remoteID)) == 0)) { + break; + } + ndlp->nlp_flag &= ~NLP_REQ_SND_ADISC; + + /* If we are in the middle of Address Authentication */ + if (ndlp->nlp_action & (NLP_DO_ADDR_AUTH | NLP_DO_RSCN)) { + + ap = (ADISC * )sp; + if(fc_chkpadisc(binfo, ndlp, &ap->nodeName,&ap->portName) == 0) { + ndlp->nlp_action &= ~(NLP_DO_ADDR_AUTH | NLP_DO_DISC_START); + fc_freenode(binfo, ndlp, 0); + ndlp->nlp_state = NLP_LIMBO; + fc_nlp_bind(binfo, ndlp); + + + if((binfo->fc_flag & FC_RSCN_MODE) || + (binfo->fc_ffstate < FC_READY)) { + ndlp->nlp_DID = (uint32)cmd->un.elsreq.remoteID; + + + if(binfo->fc_flag & FC_RSCN_MODE) { + ndlp->nlp_action |= NLP_DO_RSCN; + binfo->fc_nlp_cnt--; + if (binfo->fc_nlp_cnt <= 0) { + binfo->fc_nlp_cnt = 0; + fc_nextrscn(p_dev_ctl, fc_max_els_sent); + } + } + else { + ndlp->nlp_action |= NLP_DO_DISC_START; + binfo->fc_nlp_cnt--; + if (binfo->fc_nlp_cnt <= 0) { + binfo->fc_nlp_cnt = 0; + fc_nextdisc(p_dev_ctl, fc_max_els_sent); + } + } + } + } + else { + fc_nextnode(p_dev_ctl, ndlp); + } + } + break; + + case ELS_CMD_FARP: + case ELS_CMD_FARPR: + /* FARP completes successfully */ + fc_log_printf_msg_vargs( binfo->fc_brd_no, + &fc_msgBlk0118, /* ptr to msg structure */ + fc_mes0118, /* ptr to msg */ + fc_msgBlk0118.msgPreambleStr, /* begin varargs */ + cmd->un.elsreq.remoteID, + cmd->un.ulpWord[4], + cmd->un.ulpWord[5], + command ); /* end varargs */ + ep = (ELS_PKT * )lp0; + if((ndlp = fc_findnode_wwpn(binfo, NLP_SEARCH_ALL, + &ep->un.farp.RportName)) == 0) + break; + + ndlp->nlp_flag &= ~NLP_FARP_SND; + ndlp->nlp_action &= ~NLP_DO_ADDR_AUTH; + break; + + case ELS_CMD_SCR: /* State Change Registration */ + /* SCR completes successfully */ + fc_log_printf_msg_vargs( binfo->fc_brd_no, + &fc_msgBlk0119, /* ptr to msg structure */ + fc_mes0119, /* ptr to msg */ + fc_msgBlk0119.msgPreambleStr, /* begin varargs */ + cmd->un.elsreq.remoteID, + cmd->un.ulpWord[4], + cmd->un.ulpWord[5], + binfo->fc_ffstate); /* end varargs */ + break; + + case ELS_CMD_RNID: /* Node Identification */ + /* RNID completes successfully */ + fc_log_printf_msg_vargs( binfo->fc_brd_no, + &fc_msgBlk0120, /* ptr to msg structure */ + fc_mes0120, /* ptr to msg */ + fc_msgBlk0120.msgPreambleStr, /* begin varargs */ + cmd->un.elsreq.remoteID, + cmd->un.ulpWord[4], + cmd->un.ulpWord[5], + binfo->fc_ffstate); /* end varargs */ + break; + + default: + FCSTATCTR.elsCmdPktInval++; + + /* Unknown ELS command completed */ + fc_log_printf_msg_vargs( binfo->fc_brd_no, + &fc_msgBlk0121, /* ptr to msg structure */ + fc_mes0121, /* ptr to msg */ + fc_msgBlk0121.msgPreambleStr, /* begin varargs */ + command); /* end varargs */ + break; + } + } + if (xmitiq->bpl) { + fc_mem_put(binfo, MEM_BPL, (uchar * )xmitiq->bpl); + } + fc_mem_put(binfo, MEM_BUF, (uchar * )mp); + fc_mem_put(binfo, MEM_BUF, (uchar * )rmp); + break; + + default: + FCSTATCTR.elsCmdIocbInval++; + + /* Unknown ELS IOCB */ + fc_log_printf_msg_vargs( binfo->fc_brd_no, + &fc_msgBlk0122, /* ptr to msg structure */ + fc_mes0122, /* ptr to msg */ + fc_msgBlk0122.msgPreambleStr, /* begin varargs */ + cmd->ulpCommand ); /* end varargs */ + +out2: + rc = EINVAL; + + if(xmitiq->bp) { + fc_mem_put(binfo, MEM_BUF, (uchar * )xmitiq->bp); + } + if(xmitiq->info) { + fc_mem_put(binfo, MEM_BUF, (uchar * )xmitiq->info); + } + if(xmitiq->bpl) { + fc_mem_put(binfo, MEM_BPL, (uchar * )xmitiq->bpl); + } + + break; + } /* switch(cmd->ulpCommand) */ + + fc_mem_put(binfo, MEM_IOCB, (uchar * )xmitiq); + + return(rc); +} /* End handle_els_event */ + + +/**********************************************/ +/** handle_rcv_els_req **/ +/** **/ +/** Process an incoming ELS request **/ +/**********************************************/ +_static_ int +handle_rcv_els_req( +fc_dev_ctl_t *p_dev_ctl, +RING *rp, +IOCBQ *temp) +{ + IOCB * iocb; + FC_BRD_INFO * binfo; + uint32 * lp; + NODELIST * ndlp; + volatile SERV_PARM * sp; + NAME_TYPE * np; + ELS_PKT * ep; + MAILBOXQ * mb; + MATCHMAP * mp; + IOCBQ * saveq; + IOCBQ * iocbq; + uchar * bp; + uchar * bdeAddr; + iCfgParam * clp; + int i, cnt; + uint32 cmd; + uint32 did; + LS_RJT stat; + REG_WD30 wd30; + + iocb = &temp->iocb; + binfo = &BINFO; + clp = DD_CTL.p_config[binfo->fc_brd_no]; + + if (binfo->fc_flag & FC_SLI2) { + /* type of ELS cmd is first 32bit word in packet */ + mp = fc_getvaddr(p_dev_ctl, rp, + (uchar * )getPaddr(iocb->un.cont64[0].addrHigh, + iocb->un.cont64[0].addrLow)); + } else { + /* type of ELS cmd is first 32bit word in packet */ + mp = fc_getvaddr(p_dev_ctl, rp, (uchar * )((ulong)iocb->un.cont[0].bdeAddress)); + } + + if (mp == 0) { + + if (binfo->fc_flag & FC_SLI2) { + bdeAddr = (uchar *)getPaddr(iocb->un.cont64[0].addrHigh, + iocb->un.cont64[0].addrLow); + } + else { + bdeAddr = (uchar *)((ulong)iocb->un.cont[0].bdeAddress); + } + FCSTATCTR.elsRcvDrop++; + + goto out; + } + + bp = mp->virt; + lp = (uint32 * )bp; + cmd = *lp++; + + /* Received ELS command */ + fc_log_printf_msg_vargs( binfo->fc_brd_no, + &fc_msgBlk0123, /* ptr to msg structure */ + fc_mes0123, /* ptr to msg */ + fc_msgBlk0123.msgPreambleStr, /* begin varargs */ + cmd, + iocb->un.ulpWord[5], + iocb->ulpStatus, + binfo->fc_ffstate); /* end varargs */ + if ((iocb->ulpStatus) || + ((binfo->fc_ffstate <= FC_FLOGI) && + ((cmd != ELS_CMD_FLOGI) && (cmd != ELS_CMD_ADISC) && + (cmd != ELS_CMD_FAN)))) { + if ((iocb->ulpStatus == 0) && (cmd == ELS_CMD_PLOGI)) { + /* Do this for pt2pt as well, testing with miniport driver */ + + /* Reject this request because we are in process of discovery */ + stat.un.b.lsRjtRsvd0 = 0; + stat.un.b.lsRjtRsnCode = LSRJT_UNABLE_TPC; + stat.un.b.lsRjtRsnCodeExp = LSEXP_NOTHING_MORE; + stat.un.b.vendorUnique = 0; + fc_els_rsp(binfo, ELS_CMD_LS_RJT, (uint32)iocb->ulpContext, + (uint32)iocb->ulpClass, (void *)0, (uint32)stat.un.lsRjtError, 0); + } + + fc_mem_put(binfo, MEM_BUF, (uchar * )mp); + + i = 1; + /* free resources associated with iocb and repost the ring buffers */ + if (!(binfo->fc_flag & FC_SLI2)) { + for (i = 1; i < (int)iocb->ulpBdeCount; i++) { + mp = fc_getvaddr(p_dev_ctl, rp, (uchar * )((ulong)iocb->un.cont[i].bdeAddress)); + if (mp) { + fc_mem_put(binfo, MEM_BUF, (uchar * )mp); + } + } + } + fc_post_buffer(p_dev_ctl, rp, i); + /* Drop frame if there is an error */ + FCSTATCTR.elsRcvDrop++; + return(0); + } + + /* Special case RSCN cause 2 byte payload length field is variable */ + if ((cmd & ELS_CMD_MASK) == ELS_CMD_RSCN) { + /* Received RSCN command */ + fc_log_printf_msg_vargs( binfo->fc_brd_no, + &fc_msgBlk0211, /* ptr to msg structure */ + fc_mes0211, /* ptr to msg */ + fc_msgBlk0211.msgPreambleStr, /* begin varargs */ + binfo->fc_flag, + binfo->fc_defer_rscn.q_cnt, + binfo->fc_rscn.q_cnt, + binfo->fc_mbox_active ); /* end varargs */ + /* ACCEPT the rscn request */ + fc_els_rsp(binfo, ELS_CMD_ACC, (uint32)iocb->ulpContext, + (uint32)iocb->ulpClass, (void *)0, (uint32)(sizeof(uint32)), 0); + + if ((binfo->fc_flag & FC_RSCN_DISCOVERY) || + ((binfo->fc_flag & FC_RSCN_MODE) && !(binfo->fc_flag & FC_NSLOGI_TMR)) || + (binfo->fc_ffstate != FC_READY)) { + if(binfo->fc_defer_rscn.q_cnt > FC_MAX_HOLD_RSCN) { + binfo->fc_flag |= (FC_RSCN_DISCOVERY | FC_RSCN_MODE); + fc_flush_rscn_defer(p_dev_ctl); + goto dropit; + } + if(binfo->fc_flag & FC_RSCN_DISCOVERY) { + goto dropit; + } + else { + /* get an iocb buffer to copy entry into */ + if ((saveq = (IOCBQ * )fc_mem_get(binfo, MEM_IOCB | MEM_PRI)) != NULL) { + fc_bcopy((uchar *)temp, (uchar *)saveq, sizeof(IOCBQ)); + if (binfo->fc_defer_rscn.q_first) { + /* queue command to end of list */ + ((IOCBQ * )binfo->fc_defer_rscn.q_last)->q = (uchar * )saveq; + binfo->fc_defer_rscn.q_last = (uchar * )saveq; + } else { + /* add command to empty list */ + binfo->fc_defer_rscn.q_first = (uchar * )saveq; + binfo->fc_defer_rscn.q_last = (uchar * )saveq; + } + saveq->q = NULL; + *((MATCHMAP **)&saveq->iocb) = mp; + binfo->fc_defer_rscn.q_cnt++; + binfo->fc_flag |= FC_RSCN_MODE; + if (!(binfo->fc_flag & FC_SLI2)) { + i = (int)iocb->ulpBdeCount; + } + else { + i = 1; + } + fc_post_buffer(p_dev_ctl, rp, i); + return(0); + } + else + goto dropit; + } + } + + /* Make sure all outstanding Mailbox cmds (reg/unreg login) are processed + * before processing RSCN. + */ + if (binfo->fc_mbox_active) { + /* get an iocb buffer to copy entry into */ + if ((saveq = (IOCBQ * )fc_mem_get(binfo, MEM_IOCB | MEM_PRI)) != NULL) { + fc_bcopy((uchar *)temp, (uchar *)saveq, sizeof(IOCBQ)); + binfo->fc_flag |= (FC_DELAY_RSCN | FC_RSCN_MODE); + if (binfo->fc_rscn.q_first) { + /* queue command to end of list */ + ((IOCBQ * )binfo->fc_rscn.q_last)->q = (uchar * )saveq; + binfo->fc_rscn.q_last = (uchar * )saveq; + } else { + /* add command to empty list */ + binfo->fc_rscn.q_first = (uchar * )saveq; + binfo->fc_rscn.q_last = (uchar * )saveq; + } + + saveq->q = NULL; + *((MATCHMAP **)&saveq->iocb) = mp; + binfo->fc_rscn.q_cnt++; + if (!(binfo->fc_flag & FC_SLI2)) { + i = (int)iocb->ulpBdeCount; + } + else { + i = 1; + } + fc_post_buffer(p_dev_ctl, rp, i); + return(0); + } + else + goto dropit; + } + cmd &= ELS_CMD_MASK; + } + + switch (cmd) { + case ELS_CMD_PLOGI: + case ELS_CMD_FLOGI: + sp = (volatile SERV_PARM * )lp; + did = iocb->un.elsreq.remoteID; + if (cmd == ELS_CMD_FLOGI) { + FCSTATCTR.elsRcvFLOGI++; + if (binfo->fc_topology == TOPOLOGY_LOOP) { + /* We should never recieve a FLOGI in loop mode, ignore it */ + /* An FLOGI ELS command was received from DID in Loop Mode */ + fc_log_printf_msg_vargs( binfo->fc_brd_no, + &fc_msgBlk0124, /* ptr to msg structure */ + fc_mes0124, /* ptr to msg */ + fc_msgBlk0124.msgPreambleStr, /* begin varargs */ + cmd, + did); /* end varargs */ + break; + } + did = Fabric_DID; + if (fc_chksparm(binfo, sp, CLASS3)) { + /* For a FLOGI we accept, then if our portname is greater + * then the remote portname we initiate Nport login. + */ + int rc; + MAILBOX *tmpmb; + + rc = fc_geportname((NAME_TYPE * ) & binfo->fc_portname, + (NAME_TYPE * ) & sp->portName); + + if (rc == 2) { /* ourselves */ + /* It's ourselves, so we will just reset link */ + if ((tmpmb = (MAILBOX * )fc_mem_get(binfo, MEM_MBOX | MEM_PRI)) == NULL) { + binfo->fc_ffstate = FC_ERROR; + return(1); + } + + binfo->fc_flag |= FC_SCSI_RLIP; + clp = DD_CTL.p_config[binfo->fc_brd_no]; + + /* Setup and issue mailbox INITIALIZE LINK command */ + fc_linkdown(p_dev_ctl); + fc_init_link(binfo, (MAILBOX * )tmpmb, clp[CFG_TOPOLOGY].a_current, clp[CFG_LINK_SPEED].a_current); + tmpmb->un.varInitLnk.lipsr_AL_PA = 0; + if (issue_mb_cmd(binfo, (MAILBOX * )tmpmb, MBX_NOWAIT) != MBX_BUSY) + fc_mem_put(binfo, MEM_MBOX, (uchar * )tmpmb); + break; + } + + if (p_dev_ctl->fc_waitflogi) { + if (p_dev_ctl->fc_waitflogi != (FCCLOCK *)1) + fc_clk_can(p_dev_ctl, p_dev_ctl->fc_waitflogi); + p_dev_ctl->fc_waitflogi = 0; + p_dev_ctl->power_up = 1; + fc_snd_flogi(p_dev_ctl, 0, 0); + } + + fc_els_rsp(binfo, ELS_CMD_ACC, (uint32)iocb->ulpContext, + (uint32)iocb->ulpClass, (void *)0, (uint32)sizeof(SERV_PARM), 0); + if (rc == 1) { /* greater than */ + binfo->fc_flag |= FC_PT2PT_PLOGI; + } + binfo->fc_flag |= FC_PT2PT; + /* Use Fabric timer as pt2pt link up timer */ + binfo->fc_fabrictmo = (2 * binfo->fc_ratov) + + ((4 * binfo->fc_edtov) / 1000) + 1; + if(FABRICTMO) { + fc_clk_res(p_dev_ctl, binfo->fc_fabrictmo, FABRICTMO); + } + else { + FABRICTMO = fc_clk_set(p_dev_ctl, binfo->fc_fabrictmo, + fc_fabric_timeout, 0, 0); + } + binfo->fc_flag &= ~(FC_FABRIC | FC_PUBLIC_LOOP); + } else { + /* Reject this request because invalid parameters */ + stat.un.b.lsRjtRsvd0 = 0; + stat.un.b.lsRjtRsnCode = LSRJT_UNABLE_TPC; + stat.un.b.lsRjtRsnCodeExp = LSEXP_SPARM_OPTIONS; + stat.un.b.vendorUnique = 0; + fc_els_rsp(binfo, ELS_CMD_LS_RJT, (uint32)iocb->ulpContext, + (uint32)iocb->ulpClass, (void *)0, (uint32)stat.un.lsRjtError, + 0); + } + break; + } + FCSTATCTR.elsRcvPLOGI++; + + if (!(binfo->fc_flag & FC_PT2PT) && (binfo->fc_ffstate <= FC_FLOGI)) { + /* Reject this PLOGI because we are in rediscovery */ + stat.un.b.lsRjtRsvd0 = 0; + stat.un.b.lsRjtRsnCode = LSRJT_UNABLE_TPC; + stat.un.b.lsRjtRsnCodeExp = LSEXP_NOTHING_MORE; + stat.un.b.vendorUnique = 0; + fc_els_rsp(binfo, ELS_CMD_LS_RJT, (uint32)iocb->ulpContext, + (uint32)iocb->ulpClass, (void *)0, (uint32)stat.un.lsRjtError, 0); + break; + } + + if(did == NameServer_DID) + break; + + if((did & Fabric_DID_MASK) != Fabric_DID_MASK) { + /* Check to see if an existing cached entry is bad */ + ndlp = fc_findnode_wwpn(binfo, NLP_SEARCH_ALL, (NAME_TYPE *)&sp->portName); + if (ndlp && ndlp->nlp_DID && (ndlp->nlp_DID != did)) { + /* Check for a FARP generated nlplist entry */ + if (ndlp->nlp_DID == Bcast_DID) + ndlp->nlp_DID = did; + else { + fc_freenode(binfo, ndlp, 0); + ndlp->nlp_state = NLP_LIMBO; + fc_nlp_bind(binfo, ndlp); + } + } + } + + if ((ndlp = fc_findnode_odid(binfo, NLP_SEARCH_ALL, did)) == 0) { + /* This is a new node so allocate an nlplist entry and accept + * the LOGI request. + */ + if((ndlp = (NODELIST *)fc_mem_get(binfo, MEM_NLP))) { + fc_bzero((void *)ndlp, sizeof(NODELIST)); + ndlp->sync = binfo->fc_sync; + ndlp->capabilities = binfo->fc_capabilities; + ndlp->nlp_DID = did; + ndlp->nlp_state = NLP_LIMBO; + fc_nlp_bind(binfo, ndlp); + fc_nlp_logi(binfo, ndlp, + (NAME_TYPE *)&sp->portName, (NAME_TYPE *)&sp->nodeName); + } + else + break; + } + /* Received PLOGI command */ + fc_log_printf_msg_vargs( binfo->fc_brd_no, + &fc_msgBlk0125, /* ptr to msg structure */ + fc_mes0125, /* ptr to msg */ + fc_msgBlk0125.msgPreambleStr, /* begin varargs */ + ndlp->nlp_DID, + ndlp->nlp_state, + ndlp->nlp_flag, + ndlp->nlp_Rpi); /* end varargs */ + /* If we are pt2pt and this is the first PLOGI rcv'ed */ + if ((binfo->fc_flag & FC_PT2PT) && (binfo->fc_myDID == 0)) { + if(!(fc_chksparm(binfo, sp, CLASS3))) { + /* Reject this request because invalid parameters */ + stat.un.b.lsRjtRsvd0 = 0; + stat.un.b.lsRjtRsnCode = LSRJT_UNABLE_TPC; + stat.un.b.lsRjtRsnCodeExp = LSEXP_SPARM_OPTIONS; + stat.un.b.vendorUnique = 0; + fc_els_rsp(binfo, ELS_CMD_LS_RJT, (uint32)iocb->ulpContext, + (uint32)iocb->ulpClass, (void *)0, (uint32)stat.un.lsRjtError, + ndlp); + break; + } + wd30.word = 0; + wd30.f.xri = iocb->ulpContext; + wd30.f.class = iocb->ulpClass; + + fc_freenode_did(binfo, 0, 1); + binfo->fc_myDID = iocb->un.ulpWord[4] & Mask_DID; + + if ((mb = (MAILBOXQ * )fc_mem_get(binfo, MEM_MBOX | MEM_PRI))) { + fc_config_link(p_dev_ctl, (MAILBOX * )mb); + if (issue_mb_cmd(binfo, (MAILBOX * )mb, MBX_NOWAIT) + != MBX_BUSY) { + fc_mem_put(binfo, MEM_MBOX, (uchar * )mb); + } + } + if ((ndlp = fc_findnode_odid(binfo, NLP_SEARCH_ALL, binfo->fc_myDID)) == 0) { + if((ndlp = (NODELIST *)fc_mem_get(binfo, MEM_NLP))) { + fc_bzero((void *)ndlp, sizeof(NODELIST)); + ndlp->sync = binfo->fc_sync; + ndlp->capabilities = binfo->fc_capabilities; + ndlp->nlp_DID = binfo->fc_myDID; + ndlp->nlp_state = NLP_LIMBO; + fc_nlp_bind(binfo, ndlp); + } + } + if(ndlp) { + ndlp->nlp_DID = binfo->fc_myDID; + fc_nlp_logi(binfo, ndlp, &binfo->fc_portname, &binfo->fc_nodename); + if ((mb=(MAILBOXQ * )fc_mem_get(binfo, MEM_MBOX | MEM_PRI))) { + fc_reg_login(binfo, binfo->fc_myDID, + (uchar * ) & binfo->fc_sparam, (MAILBOX * )mb, 0); + if (issue_mb_cmd(binfo, (MAILBOX * )mb, MBX_NOWAIT) + != MBX_BUSY) { + fc_mem_put(binfo, MEM_MBOX, (uchar * )mb); + } + } + } + /* Device Discovery completes */ + fc_log_printf_msg_vargs( binfo->fc_brd_no, + &fc_msgBlk0212, /* ptr to msg structure */ + fc_mes0212, /* ptr to msg */ + fc_msgBlk0212.msgPreambleStr); /* begin & end varargs */ + binfo->fc_ffstate = FC_READY; + + binfo->fc_firstopen = 0; + if(FABRICTMO) { + fc_clk_can(p_dev_ctl, FABRICTMO); + FABRICTMO = 0; + } + + /* issue mailbox command to register login with the adapter */ + if ((mb = (MAILBOXQ * )fc_mem_get(binfo, MEM_MBOX | MEM_PRI))) { + fc_reg_login(binfo,did,(uchar * )sp, (MAILBOX * )mb, wd30.word); + if (issue_mb_cmd(binfo,(MAILBOX * )mb,MBX_NOWAIT) != MBX_BUSY) { + fc_mem_put(binfo, MEM_MBOX, (uchar * )mb); + } + } + break; + } + + cnt = 1; + switch(ndlp->nlp_state) { + case NLP_PLOGI: + cnt = 0; + break; + + case NLP_LIMBO: + if (ndlp->nlp_flag & NLP_REQ_SND) { + cnt = 0; + break; + } + + case NLP_LOGOUT: + fc_nlp_logi(binfo, ndlp, + (NAME_TYPE *)&sp->portName, (NAME_TYPE *)&sp->nodeName); + + case NLP_LOGIN: + case NLP_PRLI: + case NLP_ALLOC: + ndlp->nlp_flag &= ~NLP_FARP_SND; + ndlp->nlp_action &= ~NLP_DO_ADDR_AUTH; + /* Keep the rpi we have and send ACC / LS_RJT */ + if (fc_chksparm(binfo, sp, CLASS3)) { + + if (ndlp->nlp_Rpi) { + fc_els_rsp(binfo, ELS_CMD_ACC, (uint32)iocb->ulpContext, + (uint32)iocb->ulpClass, (void *)0, (uint32)(sizeof(SERV_PARM)), ndlp); + break; + } + /* no rpi so we must reglogin */ + ndlp->nlp_flag |= NLP_RCV_PLOGI; + wd30.word = 0; + wd30.f.xri = iocb->ulpContext; + wd30.f.class = iocb->ulpClass; + /* issue mailbox command to register login with the adapter */ + if ((mb = (MAILBOXQ * )fc_mem_get(binfo, MEM_MBOX | MEM_PRI))) { + fc_reg_login(binfo,did,(uchar * )sp, (MAILBOX * )mb, wd30.word); + if (issue_mb_cmd(binfo,(MAILBOX * )mb,MBX_NOWAIT) != MBX_BUSY) { + fc_mem_put(binfo, MEM_MBOX, (uchar * )mb); + } + } + } else { + /* Reject this request because invalid parameters */ + stat.un.b.lsRjtRsvd0 = 0; + stat.un.b.lsRjtRsnCode = LSRJT_UNABLE_TPC; + stat.un.b.lsRjtRsnCodeExp = LSEXP_SPARM_OPTIONS; + stat.un.b.vendorUnique = 0; + fc_els_rsp(binfo, ELS_CMD_LS_RJT, (uint32)iocb->ulpContext, + (uint32)iocb->ulpClass, (void *)0, (uint32)stat.un.lsRjtError, + ndlp); + + if ((ndlp->nlp_state == NLP_ALLOC) && (binfo->fc_ffstate == FC_READY)) { + /* unregister existing login first */ + ndlp->nlp_flag |= NLP_UNREG_LOGO; + fc_freenode(binfo, ndlp, 0); + ndlp->nlp_state = NLP_LIMBO; + fc_nlp_bind(binfo, ndlp); + } + } + break; + } + + if(cnt) + break; + + + did = iocb->un.elsreq.remoteID; + + /* If a nlplist entry already exists, we potentially have + * a PLOGI collision. + */ + + if (!(ndlp->nlp_flag & NLP_REQ_SND)) { + /* In this case we are already logged in */ + ndlp->nlp_flag &= ~NLP_FARP_SND; + ndlp->nlp_action &= ~NLP_DO_ADDR_AUTH; + goto chkparm; + } + + FCSTATCTR.elsLogiCol++; + + /* For a PLOGI, we only accept if our portname is less + * than the remote portname. + */ + if (!(fc_geportname((NAME_TYPE * ) & binfo->fc_portname, + (NAME_TYPE * ) & sp->portName))) { +chkparm: + fc_nlp_logi(binfo, ndlp, + (NAME_TYPE *)&sp->portName, (NAME_TYPE *)&sp->nodeName); + if (fc_chksparm(binfo, sp, CLASS3)) { + /* PLOGI chkparm OK */ + fc_log_printf_msg_vargs( binfo->fc_brd_no, + &fc_msgBlk0126, /* ptr to msg structure */ + fc_mes0126, /* ptr to msg */ + fc_msgBlk0126.msgPreambleStr, /* begin varargs */ + ndlp->nlp_DID, + ndlp->nlp_state, + ndlp->nlp_flag, + ndlp->nlp_Rpi ); /* end varargs */ + if (ndlp->nlp_Rpi == 0) { + if (ndlp->nlp_flag & NLP_REQ_SND) { + /* Abort the current outstanding PLOGI */ + unsigned long iflag; + + iflag = lpfc_q_disable_lock(p_dev_ctl); + iocbq = (IOCBQ * )(rp->fc_txp.q_first); + while (iocbq) { + if(iocbq->iocb.un.elsreq.remoteID == ndlp->nlp_DID) { + iocbq->retry = 0xff; + } + iocbq = (IOCBQ * )iocbq->q; + } + lpfc_q_unlock_enable(p_dev_ctl, iflag); + /* In case its on fc_delay_timeout list */ + fc_abort_delay_els_cmd(p_dev_ctl, ndlp->nlp_DID); + + ndlp->nlp_flag &= ~NLP_REQ_SND; + /* The following reg_login acts as if original PLOGI cmpl */ + } + else + ndlp->nlp_flag |= NLP_RCV_PLOGI; + + wd30.word = 0; + wd30.f.xri = iocb->ulpContext; + wd30.f.class = iocb->ulpClass; + ndlp->nlp_flag |= NLP_REG_INP; + + /* issue mailbox command to register login with the adapter */ + if ((mb = (MAILBOXQ * )fc_mem_get(binfo, MEM_MBOX | MEM_PRI))) { + fc_reg_login(binfo, did, (uchar * )sp, (MAILBOX * )mb, + wd30.word); + if (issue_mb_cmd(binfo, (MAILBOX * )mb, MBX_NOWAIT) + != MBX_BUSY) { + fc_mem_put(binfo, MEM_MBOX, (uchar * )mb); + } + } + } else { + fc_els_rsp(binfo, ELS_CMD_ACC, (uint32)iocb->ulpContext, + (uint32)iocb->ulpClass, (void *)0, (uint32)(sizeof(SERV_PARM)), ndlp); + } + } else { + /* Reject this request because invalid parameters */ + stat.un.b.lsRjtRsvd0 = 0; + stat.un.b.lsRjtRsnCode = LSRJT_UNABLE_TPC; + stat.un.b.lsRjtRsnCodeExp = LSEXP_SPARM_OPTIONS; + stat.un.b.vendorUnique = 0; + fc_els_rsp(binfo, ELS_CMD_LS_RJT, (uint32)iocb->ulpContext, + (uint32)iocb->ulpClass, (void *)0, (uint32)stat.un.lsRjtError, + ndlp); + + if (binfo->fc_ffstate == FC_READY) { + /* unregister existing login first */ + ndlp->nlp_flag |= NLP_UNREG_LOGO; + fc_freenode(binfo, ndlp, 0); + ndlp->nlp_state = NLP_LIMBO; + fc_nlp_bind(binfo, ndlp); + } + } + } else { + /* Reject this request because the remote node will accept ours */ + stat.un.b.lsRjtRsvd0 = 0; + stat.un.b.lsRjtRsnCode = LSRJT_UNABLE_TPC; + stat.un.b.lsRjtRsnCodeExp = LSEXP_CMD_IN_PROGRESS; + stat.un.b.vendorUnique = 0; + fc_els_rsp(binfo, ELS_CMD_LS_RJT, (uint32)iocb->ulpContext, + (uint32)iocb->ulpClass, (void *)0, (uint32)stat.un.lsRjtError, ndlp); + } + break; + + case ELS_CMD_LOGO: + FCSTATCTR.elsRcvLOGO++; + goto skip1; + case ELS_CMD_PRLO: + FCSTATCTR.elsRcvPRLO++; +skip1: + lp++; /* lp now points to portname */ + np = (NAME_TYPE * )lp; + did = iocb->un.elsreq.remoteID; + + if ((ndlp = fc_findnode_odid(binfo, NLP_SEARCH_ALL, did)) == 0) { + if(((ndlp = fc_findnode_wwpn(binfo, NLP_SEARCH_ALL, np)) == 0) || + (ndlp->nlp_DID == 0)) + /* ACCEPT the logout request */ + fc_els_rsp(binfo, ELS_CMD_ACC, (uint32)iocb->ulpContext, + (uint32)iocb->ulpClass, (void *)0, (uint32)(sizeof(uint32)), 0); + break; + } + + + if (ndlp) { + if((ndlp->nlp_state >= NLP_LOGIN) || + ((!(ndlp->nlp_flag & (NLP_FARP_SND | NLP_RM_ENTRY))) && + (!(ndlp->nlp_action & (NLP_DO_ADDR_AUTH | NLP_DO_DISC_START | NLP_DO_RSCN))))) { + /* ACCEPT the logout request */ + unsigned long iflag; + + fc_els_rsp(binfo, ELS_CMD_ACC, (uint32)iocb->ulpContext, + (uint32)iocb->ulpClass, (void *)0, (uint32)(sizeof(uint32)), ndlp); + ndlp->nlp_flag &= ~NLP_REQ_SND; + ndlp->nlp_flag |= NLP_RM_ENTRY; + + iflag = lpfc_q_disable_lock(p_dev_ctl); + iocbq = (IOCBQ * )(rp->fc_txp.q_first); + while (iocbq) { + if(iocbq->iocb.un.elsreq.remoteID == ndlp->nlp_DID) { + if(ndlp->nlp_action & (NLP_DO_ADDR_AUTH | NLP_DO_DISC_START | NLP_DO_RSCN)) { + ndlp->nlp_flag &= ~(NLP_REQ_SND_ADISC | NLP_REQ_SND_PDISC | NLP_REQ_SND); + } + iocbq->retry = 0xff; + if((binfo->fc_flag & FC_RSCN_MODE) || + (binfo->fc_ffstate < FC_READY)) { + if((ndlp->nlp_state >= NLP_PLOGI) && + (ndlp->nlp_state <= NLP_ALLOC)) { + binfo->fc_nlp_cnt--; + } + if (binfo->fc_nlp_cnt <= 0) { + binfo->fc_nlp_cnt = 0; + } + } + } + iocbq = (IOCBQ * )iocbq->q; + } + lpfc_q_unlock_enable(p_dev_ctl, iflag); + /* In case its on fc_delay_timeout list */ + fc_abort_delay_els_cmd(p_dev_ctl, ndlp->nlp_DID); + + if ((ndlp->nlp_type & NLP_FCP_TARGET) && + (ndlp->nlp_state >= NLP_LOGIN)) { + ndlp->nlp_flag |= NLP_SND_PLOGI; + } + if (ndlp->nlp_action & (NLP_DO_ADDR_AUTH | NLP_DO_DISC_START | NLP_DO_RSCN)) { + fc_nextnode(p_dev_ctl, ndlp); + } + } + else { + /* ACCEPT the logout request */ + fc_els_rsp(binfo, ELS_CMD_ACC, (uint32)iocb->ulpContext, + (uint32)iocb->ulpClass, (void *)0, (uint32)(sizeof(uint32)), 0); + } + } + else { + /* ACCEPT the logout request */ + fc_els_rsp(binfo, ELS_CMD_ACC, (uint32)iocb->ulpContext, + (uint32)iocb->ulpClass, (void *)0, (uint32)(sizeof(uint32)), 0); + } + break; + + case ELS_CMD_FAN: + FCSTATCTR.elsRcvFAN++; + /* FAN received */ + fc_log_printf_msg_vargs( binfo->fc_brd_no, + &fc_msgBlk0213, /* ptr to msg structure */ + fc_mes0213, /* ptr to msg */ + fc_msgBlk0213.msgPreambleStr, /* begin varargs */ + iocb->un.ulpWord[4], + binfo->fc_ffstate); /* end varargs */ + /* Check to see if we were waiting for FAN */ + if ((binfo->fc_ffstate != FC_FLOGI) || + (binfo->fc_topology != TOPOLOGY_LOOP) || + (!(binfo->fc_flag & FC_PUBLIC_LOOP))) + break; + + ep = (ELS_PKT * )bp; + + /* Check to make sure we haven't switched fabrics */ + if ((fc_geportname((NAME_TYPE * ) & ep->un.fan.FportName, + (NAME_TYPE * ) & binfo->fc_fabparam.portName) != 2) || + (fc_geportname((NAME_TYPE * ) & ep->un.fan.FnodeName, + (NAME_TYPE * ) & binfo->fc_fabparam.nodeName) != 2)) { + /* We switched, so we need to FLOGI again after timeout */ + break; + } + + if(FABRICTMO) { + fc_clk_can(p_dev_ctl, FABRICTMO); + FABRICTMO = 0; + } + + binfo->fc_myDID = iocb->un.ulpWord[4] & Mask_DID; + + if ((ndlp = fc_findnode_odid(binfo, NLP_SEARCH_ALL, Fabric_DID)) == 0) { + if ((ndlp = fc_findnode_odid(binfo, NLP_SEARCH_ALL, (uint32)iocb->un.elsreq.remoteID)) == 0) { + break; + } + fc_nlp_logi(binfo, ndlp, &ep->un.fan.FportName, &ep->un.fan.FnodeName); + } + ndlp->nlp_type |= NLP_FABRIC; + + if ((mb = (MAILBOXQ * )fc_mem_get(binfo, MEM_MBOX | MEM_PRI))) { + fc_config_link(p_dev_ctl, (MAILBOX * )mb); + if (issue_mb_cmd(binfo, (MAILBOX * )mb, MBX_NOWAIT) != MBX_BUSY) { + fc_mem_put(binfo, MEM_MBOX, (uchar * )mb); + } + } + + /* register the login with adapter */ + if (ndlp->nlp_Rpi == 0) { + if ((mb = (MAILBOXQ * )fc_mem_get(binfo, MEM_MBOX | MEM_PRI))) { + fc_reg_login(binfo, iocb->un.elsreq.remoteID, + (uchar * ) & binfo->fc_fabparam, (MAILBOX * )mb, 0); + if (issue_mb_cmd(binfo, (MAILBOX * )mb, MBX_NOWAIT) != MBX_BUSY) { + fc_mem_put(binfo, MEM_MBOX, (uchar * )mb); + } + } + } + + /* Since this is a FAN, we don't need to do any discovery stuff */ + fc_fanovery(p_dev_ctl); + break; + + case ELS_CMD_RSCN: + FCSTATCTR.elsRcvRSCN++; + fc_process_rscn(p_dev_ctl, temp, mp); + break; + + case ELS_CMD_ADISC: + FCSTATCTR.elsRcvADISC++; + ep = (ELS_PKT * )bp; + did = iocb->un.elsreq.remoteID; + if (((ndlp = fc_findnode_odid(binfo, NLP_SEARCH_ALL, did)) != 0) && + (ndlp->nlp_state >= NLP_LOGIN)) { + if (fc_chkpadisc(binfo, ndlp, &ep->un.adisc.nodeName, + &ep->un.adisc.portName)) { + fc_els_rsp(binfo, ELS_CMD_ADISC, (uint32)iocb->ulpContext, + (uint32)iocb->ulpClass, (void *)0, (uint32)sizeof(SERV_PARM), + ndlp); + } else { + /* Reject this request because invalid parameters */ + stat.un.b.lsRjtRsvd0 = 0; + stat.un.b.lsRjtRsnCode = LSRJT_UNABLE_TPC; + stat.un.b.lsRjtRsnCodeExp = LSEXP_SPARM_OPTIONS; + stat.un.b.vendorUnique = 0; + fc_els_rsp(binfo, ELS_CMD_LS_RJT, (uint32)iocb->ulpContext, + (uint32)iocb->ulpClass, (void *)0, (uint32)stat.un.lsRjtError, + ndlp); + if (!(ndlp->nlp_flag & NLP_REQ_SND)) { + ndlp->nlp_flag |= NLP_UNREG_LOGO; + fc_freenode_did(binfo, did, 0); + } + } + } else { + /* Reject this request because not logged in */ + stat.un.b.lsRjtRsvd0 = 0; + stat.un.b.lsRjtRsnCode = LSRJT_UNABLE_TPC; + stat.un.b.lsRjtRsnCodeExp = LSEXP_CANT_GIVE_DATA; + stat.un.b.vendorUnique = 0; + fc_els_rsp(binfo, ELS_CMD_LS_RJT, (uint32)iocb->ulpContext, + (uint32)iocb->ulpClass, (void *)0, (uint32)stat.un.lsRjtError, ndlp); + if ((ndlp == 0) || (!(ndlp->nlp_flag & NLP_REQ_SND))) + fc_freenode_did(binfo, did, 0); + } + break; + + case ELS_CMD_PDISC: + FCSTATCTR.elsRcvPDISC++; + sp = (volatile SERV_PARM * )lp; + did = iocb->un.elsreq.remoteID; + if (((ndlp = fc_findnode_odid(binfo, NLP_SEARCH_ALL, did)) != 0) && + (ndlp->nlp_state >= NLP_LOGIN)) { + if (fc_chkpadisc(binfo, ndlp, &sp->nodeName, &sp->portName)) { + fc_els_rsp(binfo, ELS_CMD_ACC, (uint32)iocb->ulpContext, + (uint32)iocb->ulpClass, (void *)0, (uint32)sizeof(SERV_PARM), + ndlp); + } else { + /* Reject this request because invalid parameters */ + stat.un.b.lsRjtRsvd0 = 0; + stat.un.b.lsRjtRsnCode = LSRJT_UNABLE_TPC; + stat.un.b.lsRjtRsnCodeExp = LSEXP_SPARM_OPTIONS; + stat.un.b.vendorUnique = 0; + fc_els_rsp(binfo, ELS_CMD_LS_RJT, (uint32)iocb->ulpContext, + (uint32)iocb->ulpClass, (void *)0, (uint32)stat.un.lsRjtError, + ndlp); + if (!(ndlp->nlp_flag & NLP_REQ_SND)) { + ndlp->nlp_flag |= NLP_UNREG_LOGO; + fc_freenode_did(binfo, did, 0); + } + } + } else { + /* Reject this request because not logged in */ + stat.un.b.lsRjtRsvd0 = 0; + stat.un.b.lsRjtRsnCode = LSRJT_UNABLE_TPC; + stat.un.b.lsRjtRsnCodeExp = LSEXP_CANT_GIVE_DATA; + stat.un.b.vendorUnique = 0; + fc_els_rsp(binfo, ELS_CMD_LS_RJT, (uint32)iocb->ulpContext, + (uint32)iocb->ulpClass, (void *)0, (uint32)stat.un.lsRjtError, ndlp); + if ((ndlp == 0) || (!(ndlp->nlp_flag & NLP_REQ_SND))) + fc_freenode_did(binfo, did, 0); + } + break; + + case ELS_CMD_FARPR: + FCSTATCTR.elsRcvFARPR++; + ep = (ELS_PKT * )bp; + did = iocb->un.elsreq.remoteID; + /* FARP-RSP received from DID */ + fc_log_printf_msg_vargs( binfo->fc_brd_no, + &fc_msgBlk0600, /* ptr to msg structure */ + fc_mes0600, /* ptr to msg */ + fc_msgBlk0600.msgPreambleStr, /* begin varargs */ + did ); /* end varargs */ + /* ACCEPT the Farp resp request */ + fc_els_rsp(binfo, ELS_CMD_ACC, (uint32)iocb->ulpContext, + (uint32)iocb->ulpClass, (void *)0, (uint32)(sizeof(uint32)), 0); + break; + + case ELS_CMD_FARP: + FCSTATCTR.elsRcvFARP++; + ep = (ELS_PKT * )bp; + did = iocb->un.elsreq.remoteID; + /* FARP-REQ received from DID */ + fc_log_printf_msg_vargs( binfo->fc_brd_no, + &fc_msgBlk0601, /* ptr to msg structure */ + fc_mes0601, /* ptr to msg */ + fc_msgBlk0601.msgPreambleStr, /* begin varargs */ + did ); /* end varargs */ + if ((ndlp = fc_findnode_odid(binfo, NLP_SEARCH_ALL, did)) == 0) { + if((ndlp = (NODELIST *)fc_mem_get(binfo, MEM_NLP))) { + fc_bzero((void *)ndlp, sizeof(NODELIST)); + ndlp->sync = binfo->fc_sync; + ndlp->capabilities = binfo->fc_capabilities; + ndlp->nlp_DID = did; + fc_nlp_logi(binfo,ndlp, &ep->un.farp.OportName, &ep->un.farp.OnodeName); + ndlp->nlp_state = NLP_LIMBO; + } + else + break; + } + + /* We will only support match on WWPN or WWNN */ + if (ep->un.farp.Mflags & ~(FARP_MATCH_NODE | FARP_MATCH_PORT)) + break; + + cnt = 0; + /* If this FARP command is searching for my portname */ + if (ep->un.farp.Mflags & FARP_MATCH_PORT) { + if (fc_geportname(&ep->un.farp.RportName, &binfo->fc_portname) == 2) + cnt = 1; + else + cnt = 0; + } + + /* If this FARP command is searching for my nodename */ + if (ep->un.farp.Mflags & FARP_MATCH_NODE) { + if (fc_geportname(&ep->un.farp.RnodeName, &binfo->fc_nodename) == 2) + cnt = 1; + else + cnt = 0; + } + + if (cnt) { + if (!(binfo->fc_flag & FC_LNK_DOWN) && + (binfo->fc_ffstate >= rp->fc_xmitstate) && + !(ndlp->nlp_flag & NLP_REQ_SND) && + !(ndlp->nlp_action & NLP_DO_ADDR_AUTH)) { + /* We need to re-login to that node */ + if ((ep->un.farp.Rflags & FARP_REQUEST_PLOGI) && + !(ndlp->nlp_flag & NLP_REQ_SND)) { + fc_freenode(binfo, ndlp, 0); + ndlp->nlp_state = NLP_LIMBO; + fc_nlp_bind(binfo, ndlp); + fc_els_cmd(binfo, ELS_CMD_PLOGI, (void *)((ulong)ndlp->nlp_DID), + (uint32)0, (ushort)0, ndlp); + } + + /* We need to send FARP response to that node */ + if (ep->un.farp.Rflags & FARP_REQUEST_FARPR) { + fc_els_cmd(binfo, ELS_CMD_FARPR, (void *)((ulong)ndlp->nlp_DID), + (uint32)0, (ushort)0, ndlp); + } + } + } + break; + + case ELS_CMD_RRQ: + FCSTATCTR.elsRcvRRQ++; + ep = (ELS_PKT * )bp; + /* Get oxid / rxid from payload and internally abort it */ + if ((ep->un.rrq.SID == SWAP_DATA(binfo->fc_myDID))) { + fc_abort_ixri_cx(binfo, ep->un.rrq.Oxid, CMD_CLOSE_XRI_CX, rp); + } else { + fc_abort_ixri_cx(binfo, ep->un.rrq.Rxid, CMD_CLOSE_XRI_CX, rp); + } + /* ACCEPT the rrq request */ + fc_els_rsp(binfo, ELS_CMD_ACC, (uint32)iocb->ulpContext, + (uint32)iocb->ulpClass, (void *)0, (uint32)(sizeof(uint32)), 0); + break; + + case ELS_CMD_PRLI: + /* ACCEPT the prli request */ + did = iocb->un.elsreq.remoteID; + if ((ndlp = fc_findnode_odid(binfo, NLP_SEARCH_ALL, did))) { + fc_els_rsp(binfo, ELS_CMD_PRLI, (uint32)iocb->ulpContext, + (uint32)iocb->ulpClass, (void *)0, (uint32)(sizeof(uint32)), ndlp); + } + else { + stat.un.b.lsRjtRsvd0 = 0; + stat.un.b.lsRjtRsnCode = LSRJT_UNABLE_TPC; + stat.un.b.lsRjtRsnCodeExp = LSEXP_CANT_GIVE_DATA; + stat.un.b.vendorUnique = 0; + fc_els_rsp(binfo, ELS_CMD_LS_RJT, (uint32)iocb->ulpContext, + (uint32)iocb->ulpClass, (void *)0, (uint32)stat.un.lsRjtError, 0); + } + break; + + case ELS_CMD_RNID: + did = iocb->un.elsreq.remoteID; + ep = (ELS_PKT * )bp; + switch(ep->un.rnid.Format) { + case 0: + case RNID_TOPOLOGY_DISC: + fc_els_rsp(binfo, ELS_CMD_RNID, (uint32)iocb->ulpContext, + (uint32)iocb->ulpClass, (void *)0, (uint32)ep->un.rnid.Format, 0); + break; + default: + /* Reject this request because format not supported */ + stat.un.b.lsRjtRsvd0 = 0; + stat.un.b.lsRjtRsnCode = LSRJT_UNABLE_TPC; + stat.un.b.lsRjtRsnCodeExp = LSEXP_CANT_GIVE_DATA; + stat.un.b.vendorUnique = 0; + fc_els_rsp(binfo, ELS_CMD_LS_RJT, (uint32)iocb->ulpContext, + (uint32)iocb->ulpClass, (void *)0, (uint32)stat.un.lsRjtError, 0); + } + break; + + default: + /* Unsupported ELS command, reject */ + stat.un.b.lsRjtRsvd0 = 0; + stat.un.b.lsRjtRsnCode = LSRJT_CMD_UNSUPPORTED; + stat.un.b.lsRjtRsnCodeExp = LSEXP_NOTHING_MORE; + stat.un.b.vendorUnique = 0; + fc_els_rsp(binfo, ELS_CMD_LS_RJT, (uint32)iocb->ulpContext, + (uint32)iocb->ulpClass, (void *)0, (uint32)stat.un.lsRjtError, 0); + FCSTATCTR.elsCmdPktInval++; + + did = iocb->un.elsreq.remoteID; + /* Unknown ELS command received from NPORT */ + fc_log_printf_msg_vargs( binfo->fc_brd_no, + &fc_msgBlk0127, /* ptr to msg structure */ + fc_mes0127, /* ptr to msg */ + fc_msgBlk0127.msgPreambleStr, /* begin varargs */ + cmd, + did); /* end varargs */ + break; + } + +dropit: + + FCSTATCTR.elsRcvFrame++; + fc_mem_put(binfo, MEM_BUF, (uchar * )mp); + +out: + + i = 1; + /* free resources associated with this iocb and repost the ring buffers */ + if (!(binfo->fc_flag & FC_SLI2)) { + for (i = 1; i < (int)iocb->ulpBdeCount; i++) { + mp = fc_getvaddr(p_dev_ctl, rp, (uchar * )((ulong)iocb->un.cont[i].bdeAddress)); + if (mp) { + fc_mem_put(binfo, MEM_BUF, (uchar * )mp); + } + } + } + + fc_post_buffer(p_dev_ctl, rp, i); + + return(1); +} /* End handle_rcv_els_req */ + + +/***************************************/ +/** fc_process_rscn Process ELS **/ +/** RSCN command **/ +/***************************************/ +_static_ int +fc_process_rscn( +fc_dev_ctl_t *p_dev_ctl, +IOCBQ *temp, +MATCHMAP *mp) +{ + FC_BRD_INFO * binfo; + IOCB * iocb; + uchar * bp; + uint32 * lp; + D_ID rdid; + uint32 cmd; + int i, j, cnt; + + binfo = &BINFO; + iocb = &temp->iocb; + bp = mp->virt; + lp = (uint32 * )bp; + cmd = *lp++; + i = SWAP_DATA(cmd) & 0xffff; /* payload length */ + i -= sizeof(uint32); /* take off word 0 */ + cmd &= ELS_CMD_MASK; + + /* RSCN received */ + fc_log_printf_msg_vargs( binfo->fc_brd_no, + &fc_msgBlk0214, /* ptr to msg structure */ + fc_mes0214, /* ptr to msg */ + fc_msgBlk0214.msgPreambleStr, /* begin varargs */ + binfo->fc_flag, + i, + *lp, + binfo->fc_rscn_id_cnt); /* end varargs */ + cnt = 0; /* cnt will determine if we need to access NameServer */ + + /* Loop through all DIDs in the payload */ + binfo->fc_flag |= FC_RSCN_MODE; + + while (i) { + rdid.un.word = *lp++; + rdid.un.word = SWAP_DATA(rdid.un.word); + if(binfo->fc_rscn_id_cnt < FC_MAX_HOLD_RSCN) { + for(j=0;jfc_rscn_id_cnt;j++) { + if(binfo->fc_rscn_id_list[j] == rdid.un.word) { + goto skip_id; + } + } + binfo->fc_rscn_id_list[binfo->fc_rscn_id_cnt++] = rdid.un.word; + } + else { + binfo->fc_flag |= FC_RSCN_DISCOVERY; + fc_flush_rscn_defer(p_dev_ctl); + cnt = 0; + break; + } +skip_id: + cnt += (fc_handle_rscn(p_dev_ctl, &rdid)); + i -= sizeof(uint32); + } + + /* RSCN processed */ + fc_log_printf_msg_vargs( binfo->fc_brd_no, + &fc_msgBlk0215, /* ptr to msg structure */ + fc_mes0215, /* ptr to msg */ + fc_msgBlk0215.msgPreambleStr, /* begin varargs */ + binfo->fc_flag, + cnt, + binfo->fc_rscn_id_cnt, + binfo->fc_ffstate ); /* end varargs */ + if (cnt == 0) { + /* no need for nameserver login */ + fc_nextrscn(p_dev_ctl, fc_max_els_sent); + } + else { + if(!(binfo->fc_flag & FC_NSLOGI_TMR)) + fc_clk_set(p_dev_ctl, 1, fc_issue_ns_query, 0, 0); + binfo->fc_flag |= FC_NSLOGI_TMR; + } + return(0); +} + + +/***************************************/ +/** fc_handle_rscn Handle ELS **/ +/** RSCN command **/ +/***************************************/ +_static_ int +fc_handle_rscn( +fc_dev_ctl_t *p_dev_ctl, +D_ID *didp) +{ + FC_BRD_INFO * binfo; + NODELIST * ndlp; + NODELIST * new_ndlp; + NODELIST * callnextnode; + iCfgParam * clp; + D_ID did; + int change; + int numchange; + int ns; + + binfo = &BINFO; + clp = DD_CTL.p_config[binfo->fc_brd_no]; + callnextnode = 0; + + dfc_hba_put_event(p_dev_ctl, HBA_EVENT_RSCN, binfo->fc_myDID, didp->un.word, 0, 0); + dfc_put_event(p_dev_ctl, FC_REG_RSCN_EVENT, didp->un.word, 0, 0); + + /* Is this an RSCN for me? */ + if (didp->un.word == binfo->fc_myDID) + return(0); + + /* Always query nameserver on RSCN (zoning) if CFG_ZONE_RSCN it set */ + ns = (int)clp[CFG_ZONE_RSCN].a_current; + numchange = 0; + + ndlp = binfo->fc_nlpbind_start; + if(ndlp == (NODELIST *)&binfo->fc_nlpbind_start) + ndlp = binfo->fc_nlpunmap_start; + if(ndlp == (NODELIST *)&binfo->fc_nlpunmap_start) + ndlp = binfo->fc_nlpmap_start; + new_ndlp = 0; + while(ndlp != (NODELIST *)&binfo->fc_nlpmap_start) { + new_ndlp = (NODELIST *)ndlp->nlp_listp_next; + + /* Skip over FABRIC nodes and myself */ + if ((ndlp->nlp_DID == binfo->fc_myDID) || + (ndlp->nlp_type & NLP_FABRIC)) { + + ndlp = new_ndlp; + if(ndlp == (NODELIST *)&binfo->fc_nlpunmap_start) + ndlp = binfo->fc_nlpmap_start; + continue; + } + + did.un.word = ndlp->nlp_DID; + change = 0; + + switch (didp->un.b.resv) { + case 0: /* Single N_Port ID effected */ + if (did.un.word == didp->un.word) { + change = 1; + } + break; + + case 1: /* Whole N_Port Area effected */ + if ((did.un.b.domain == didp->un.b.domain) && + (did.un.b.area == didp->un.b.area)) { + ns = 1; + change = 1; + } + break; + + case 2: /* Whole N_Port Domain effected */ + if (did.un.b.domain == didp->un.b.domain) { + ns = 1; + change = 1; + } + break; + + case 3: /* Whole Fabric effected */ + binfo->fc_flag |= FC_RSCN_DISCOVERY; + fc_flush_rscn_defer(p_dev_ctl); + return(0); + + default: + /* Unknown Identifier in RSCN payload */ + fc_log_printf_msg_vargs( binfo->fc_brd_no, + &fc_msgBlk0216, /* ptr to msg structure */ + fc_mes0216, /* ptr to msg */ + fc_msgBlk0216.msgPreambleStr, /* begin varargs */ + didp->un.word ); /* end varargs */ + break; + + } + + if (change) { + numchange++; + if((ndlp->nlp_state == NLP_ALLOC) || + (ndlp->nlp_state == NLP_LOGIN)) { + + if (ndlp->nlp_flag & NLP_REQ_SND) { + RING * rp; + IOCBQ * iocbq; + unsigned long iflag; + + /* Look through ELS ring and remove any ELS cmds in progress */ + iflag = lpfc_q_disable_lock(p_dev_ctl); + rp = &binfo->fc_ring[FC_ELS_RING]; + iocbq = (IOCBQ * )(rp->fc_txp.q_first); + while (iocbq) { + if (iocbq->iocb.un.elsreq.remoteID == ndlp->nlp_DID) { + iocbq->retry = 0xff; /* Mark for abort */ + } + iocbq = (IOCBQ * )iocbq->q; + } + lpfc_q_unlock_enable(p_dev_ctl, iflag); + /* In case its on fc_delay_timeout list */ + fc_abort_delay_els_cmd(p_dev_ctl, ndlp->nlp_DID); + + ndlp->nlp_flag &= ~NLP_REQ_SND; + } + + /* We are always using ADISC for RSCN validation */ + /* IF we are using ADISC, leave ndlp on mapped or unmapped q */ + + ndlp->nlp_flag &= ~NLP_NODEV_TMO; + + /* Mark node for authentication */ + ndlp->nlp_action |= NLP_DO_RSCN; + + } else { + + if (ndlp->nlp_flag & NLP_REQ_SND) { + if((callnextnode == 0) && (ndlp->nlp_action & NLP_DO_RSCN)) + callnextnode = ndlp; + } + fc_freenode(binfo, ndlp, 0); + ndlp->nlp_flag &= ~NLP_NODEV_TMO; + ndlp->nlp_state = NLP_LIMBO; + fc_nlp_bind(binfo, ndlp); + + /* Mark node for authentication */ + ndlp->nlp_action |= NLP_DO_RSCN; + } + } + ndlp = new_ndlp; + if(ndlp == (NODELIST *)&binfo->fc_nlpbind_start) + ndlp = binfo->fc_nlpunmap_start; + if(ndlp == (NODELIST *)&binfo->fc_nlpunmap_start) + ndlp = binfo->fc_nlpmap_start; + } + + /* If nothing in our node table is effected, + * we need to goto the Nameserver. + */ + if (numchange == 0) { + /* Is this a single N_Port that wasn't in our table */ + if (didp->un.b.resv == 0) { + if ((ndlp = fc_findnode_odid(binfo, NLP_SEARCH_ALL, didp->un.word)) == 0) { + if((ndlp = (NODELIST *)fc_mem_get(binfo, MEM_NLP))) { + fc_bzero((void *)ndlp, sizeof(NODELIST)); + ndlp->sync = binfo->fc_sync; + ndlp->capabilities = binfo->fc_capabilities; + ndlp->nlp_DID = didp->un.word; + } + else + return(ns); + } + ndlp->nlp_action |= NLP_DO_RSCN; + ndlp->nlp_flag &= ~NLP_NODEV_TMO; + ndlp->nlp_state = NLP_LIMBO; + fc_nlp_bind(binfo, ndlp); + } + else { + ns = 1; + } + } + + /* Is this an area or domain N_Port */ + if (didp->un.b.resv != 0) { + ns = 1; + } + + if((ns == 0) && (callnextnode)) + fc_nextnode(p_dev_ctl, callnextnode); + + /* Tell calling routine if NameServer access is required + * and return number of nodes presently being authenticated. + */ + return(ns); +} /* End fc_handle_rscn */ + + +/*************************************************/ +/** fc_chksparm Check service parameters **/ +/*************************************************/ +_local_ int +fc_chksparm( +FC_BRD_INFO *binfo, +volatile SERV_PARM *sp, +uint32 class) +{ + volatile SERV_PARM *hsp; + + hsp = &binfo->fc_sparam; + /* First check for supported version */ + + /* Next check for class validity */ + if (sp->cls1.classValid) { + if (sp->cls1.rcvDataSizeMsb > hsp->cls1.rcvDataSizeMsb) + sp->cls1.rcvDataSizeMsb = hsp->cls1.rcvDataSizeMsb; + if (sp->cls1.rcvDataSizeLsb > hsp->cls1.rcvDataSizeLsb) + sp->cls1.rcvDataSizeLsb = hsp->cls1.rcvDataSizeLsb; + } else if (class == CLASS1) { + return(0); + } + + if (sp->cls2.classValid) { + if (sp->cls2.rcvDataSizeMsb > hsp->cls2.rcvDataSizeMsb) + sp->cls2.rcvDataSizeMsb = hsp->cls2.rcvDataSizeMsb; + if (sp->cls2.rcvDataSizeLsb > hsp->cls2.rcvDataSizeLsb) + sp->cls2.rcvDataSizeLsb = hsp->cls2.rcvDataSizeLsb; + } else if (class == CLASS2) { + return(0); + } + + if (sp->cls3.classValid) { + if (sp->cls3.rcvDataSizeMsb > hsp->cls3.rcvDataSizeMsb) + sp->cls3.rcvDataSizeMsb = hsp->cls3.rcvDataSizeMsb; + if (sp->cls3.rcvDataSizeLsb > hsp->cls3.rcvDataSizeLsb) + sp->cls3.rcvDataSizeLsb = hsp->cls3.rcvDataSizeLsb; + } else if (class == CLASS3) { + return(0); + } + + if (sp->cmn.bbRcvSizeMsb > hsp->cmn.bbRcvSizeMsb) + sp->cmn.bbRcvSizeMsb = hsp->cmn.bbRcvSizeMsb; + if (sp->cmn.bbRcvSizeLsb > hsp->cmn.bbRcvSizeLsb) + sp->cmn.bbRcvSizeLsb = hsp->cmn.bbRcvSizeLsb; + + return(1); +} /* End fc_chksparm */ + + +/***************************************/ +/** fc_chkpadisc Check **/ +/** P/ADISC parameters **/ +/***************************************/ +_static_ int +fc_chkpadisc( +FC_BRD_INFO *binfo, +NODELIST *ndlp, +volatile NAME_TYPE *nn, +volatile NAME_TYPE *pn) +{ + if (fc_geportname((NAME_TYPE * )nn, &ndlp->nlp_nodename) != 2) { + return(0); + } + + if (fc_geportname((NAME_TYPE * )pn, &ndlp->nlp_portname) != 2) { + return(0); + } + + return(1); +} /* End fc_chkpadisc */ + + +/***************************************/ +/** fc_els_cmd Issue an **/ +/** ELS command **/ +/***************************************/ +_static_ int +fc_els_cmd( +FC_BRD_INFO *binfo, +uint32 elscmd, +void *arg, +uint32 retry, +ushort iotag, +NODELIST *ndlp) +{ + IOCB * icmd; + IOCBQ * temp; + RING * rp; + uchar * bp; + ULP_BDE64 * bpl; + MATCHMAP * mp, * rmp, * bmp; + MAILBOXQ * mb; + iCfgParam * clp; + union { + SERV_PARM * sp; + ADISC * ap; + FARP * fp; + fc_vpd_t * vpd; + PRLI * npr; + } un; + uint32 * lp; + ushort size; + ulong setdelay; + fc_dev_ctl_t * p_dev_ctl; + + clp = DD_CTL.p_config[binfo->fc_brd_no]; + rp = &binfo->fc_ring[FC_ELS_RING]; + p_dev_ctl = (fc_dev_ctl_t *)(binfo->fc_p_dev_ctl); + + if ((elscmd == ELS_CMD_LOGO) && (iotag == 0)) { + /* First do unreglogin for did before sending ELS LOGO request */ + if ((ndlp = fc_findnode_odid(binfo, NLP_SEARCH_ALL, (uint32)((ulong)arg))) && ndlp->nlp_Rpi) { + /* If we are in the middle of Discovery */ + if (ndlp->nlp_action & (NLP_DO_ADDR_AUTH | NLP_DO_DISC_START | NLP_DO_RSCN)) { + /* Goto next entry */ + fc_nextnode(p_dev_ctl, ndlp); + } + ndlp->nlp_flag |= NLP_UNREG_LOGO; + fc_freenode(binfo, ndlp, 0); + ndlp->nlp_state = NLP_LIMBO; + fc_nlp_bind(binfo, ndlp); + return(0); + } + } + /* Allocate buffer for command iocb */ + if ((temp = (IOCBQ * )fc_mem_get(binfo, MEM_IOCB | MEM_PRI)) == 0) { + return(1); + } + fc_bzero((void *)temp, sizeof(IOCBQ)); + icmd = &temp->iocb; + setdelay = 0; + + /* fill in BDEs for command */ + /* Allocate buffer for command payload */ + if ((mp = (MATCHMAP * )fc_mem_get(binfo, MEM_BUF | MEM_PRI)) == 0) { + fc_mem_put(binfo, MEM_IOCB, (uchar * )temp); + return(1); + } + + /* Allocate buffer for response payload */ + if ((rmp = (MATCHMAP * )fc_mem_get(binfo, MEM_BUF | MEM_PRI)) == 0) { + fc_mem_put(binfo, MEM_IOCB, (uchar * )temp); + fc_mem_put(binfo, MEM_BUF, (uchar * )mp); + return(1); + } + fc_bzero((void *)rmp->virt, sizeof(ELS_PKT)); + + if (binfo->fc_flag & FC_SLI2) { + /* Allocate buffer for Buffer ptr list */ + if ((bmp = (MATCHMAP * )fc_mem_get(binfo, MEM_BPL | MEM_PRI)) == 0) { + fc_mem_put(binfo, MEM_IOCB, (uchar * )temp); + fc_mem_put(binfo, MEM_BUF, (uchar * )mp); + fc_mem_put(binfo, MEM_BUF, (uchar * )rmp); + return(1); + } + bpl = (ULP_BDE64 * )bmp->virt; + bpl->addrLow = PCIMEM_LONG(putPaddrLow((ulong)mp->phys)); + bpl->addrHigh = PCIMEM_LONG(putPaddrHigh((ulong)mp->phys)); + bpl->tus.f.bdeFlags = 0; + bpl++; + bpl->addrLow = PCIMEM_LONG(putPaddrLow((ulong)rmp->phys)); + bpl->addrHigh = PCIMEM_LONG(putPaddrHigh((ulong)rmp->phys)); + bpl->tus.f.bdeSize = FCELSSIZE; + bpl->tus.f.bdeFlags = BUFF_USE_RCV; + bpl->tus.w = PCIMEM_LONG(bpl->tus.w); + + bpl--; /* so we can fill in size later */ + + icmd->un.elsreq64.bdl.ulpIoTag32 = (uint32)0; + icmd->un.elsreq64.bdl.addrHigh = (uint32)putPaddrHigh(bmp->phys); + icmd->un.elsreq64.bdl.addrLow = (uint32)putPaddrLow(bmp->phys); + icmd->un.elsreq64.bdl.bdeSize = (2 * sizeof(ULP_BDE64)); + icmd->un.elsreq64.bdl.bdeFlags = BUFF_TYPE_BDL; + temp->bpl = (uchar *)bmp; + } else { + bpl = 0; + bmp = 0; + icmd->un.cont[0].bdeAddress = (uint32)putPaddrLow(mp->phys); + icmd->un.cont[1].bdeAddress = (uint32)putPaddrLow(rmp->phys); + icmd->un.cont[1].bdeSize = FCELSSIZE; + temp->bpl = 0; + } + + bp = mp->virt; + /* Save for completion so we can release these resources */ + temp->bp = (uchar * )mp; + temp->info = (uchar * )rmp; + + /* Fill in command field in payload */ + *((uint32 * )(bp)) = elscmd; /* FLOGI, PLOGI or LOGO */ + bp += sizeof(uint32); + + switch (elscmd) { + case ELS_CMD_PLOGI: /* NPort login */ + case ELS_CMD_PDISC: /* exchange parameters */ + if(ndlp && (ndlp->nlp_DID == 0)) { + ndlp->nlp_DID = (uint32)((ulong)arg); + } + case ELS_CMD_FLOGI: /* Fabric login */ + /* For LOGI request, remainder of payload is service parameters */ + fc_bcopy((void *) & binfo->fc_sparam, (void *)bp, sizeof(SERV_PARM)); + un.sp = (SERV_PARM * )bp; + + if (elscmd == ELS_CMD_FLOGI) { + un.sp->cmn.e_d_tov = 0; + un.sp->cmn.w2.r_a_tov = 0; + un.sp->cls1.classValid = 0; + un.sp->cls2.seqDelivery = 1; + un.sp->cls3.seqDelivery = 1; + if (un.sp->cmn.fcphLow < FC_PH3) + un.sp->cmn.fcphLow = FC_PH3; + if(FABRICTMO) { + fc_clk_res(p_dev_ctl, binfo->fc_fabrictmo, FABRICTMO); + } + } else { + /* Seagate drives can't handle FC_PH3 value! */ + if (un.sp->cmn.fcphLow < FC_PH_4_3) + un.sp->cmn.fcphLow = FC_PH_4_3; + } + + if (un.sp->cmn.fcphHigh < FC_PH3) + un.sp->cmn.fcphHigh = FC_PH3; + + icmd->un.elsreq.remoteID = (uint32)((ulong)arg); /* DID */ + size = (sizeof(uint32) + sizeof(SERV_PARM)); + + if (elscmd != ELS_CMD_PDISC) { + /* Allocate a nlplist entry, ELS cmpl will fill it in */ + if ((ndlp == 0) && + ((ndlp = fc_findnode_odid(binfo, NLP_SEARCH_ALL, (uint32)((ulong)arg))) == 0)) { + if((ndlp = (NODELIST *)fc_mem_get(binfo, MEM_NLP))) { + fc_bzero((void *)ndlp, sizeof(NODELIST)); + ndlp->sync = binfo->fc_sync; + ndlp->capabilities = binfo->fc_capabilities; + ndlp->nlp_DID = (uint32)((ulong)arg); + } + else { + fc_mem_put(binfo, MEM_IOCB, (uchar * )temp); + fc_mem_put(binfo, MEM_BUF, (uchar * )mp); + fc_mem_put(binfo, MEM_BUF, (uchar * )rmp); + if (bmp) { + fc_mem_put(binfo, MEM_BPL, (uchar * )bmp); + } + return(1); + } + ndlp->nlp_state = NLP_LIMBO; + fc_nlp_bind(binfo, ndlp); + } + ndlp->nlp_flag &= ~NLP_RM_ENTRY; + ndlp->nlp_flag |= NLP_REQ_SND; + + if (elscmd == ELS_CMD_PLOGI) { + + ndlp->nlp_flag &= ~NLP_SND_PLOGI; + if (ndlp->nlp_Rpi) { + /* must explicitly unregister the login, UREG_LOGIN */ + if ((mb = (MAILBOXQ * )fc_mem_get(binfo, MEM_MBOX | MEM_PRI))) { + fc_unreg_login(binfo, ndlp->nlp_Rpi, (MAILBOX * )mb); + if (issue_mb_cmd(binfo,(MAILBOX * )mb,MBX_NOWAIT) != MBX_BUSY) { + fc_mem_put(binfo, MEM_MBOX, (uchar * )mb); + } + } + binfo->fc_nlplookup[ndlp->nlp_Rpi] = 0; + ndlp->nlp_Rpi = 0; + } + + /* For PLOGI requests, must make sure all outstanding Mailbox + * commands have been processed. This is to ensure UNREG_LOGINs + * complete before we try to login. + */ + if (binfo->fc_mbox_active) { + fc_mem_put(binfo, MEM_BUF, (uchar * )mp); + fc_mem_put(binfo, MEM_BUF, (uchar * )rmp); + if (bmp) { + fc_mem_put(binfo, MEM_BPL, (uchar * )bmp); + } + temp->info = (uchar *)0; + temp->bp = (uchar *)0; + temp->bpl = (uchar *)0; + fc_plogi_put(binfo, temp); + return(1); + } + + if ((ulong)arg == NameServer_DID) { + if (binfo->fc_ffstate == FC_READY) { + if(binfo->fc_flag & FC_RSCN_MODE) + ndlp->nlp_action |= NLP_DO_RSCN; + else + ndlp->nlp_action |= NLP_DO_ADDR_AUTH; + } + else + ndlp->nlp_action |= NLP_DO_ADDR_AUTH; + } + } + } + break; + + case ELS_CMD_LOGO: /* Logout */ + icmd->un.elsreq.remoteID = (uint32)((ulong)arg); /* DID */ + + *((uint32 * )(bp)) = SWAP_DATA(binfo->fc_myDID); + bp += sizeof(uint32); + + /* Last field in payload is our portname */ + fc_bcopy((void *) & binfo->fc_portname, (void *)bp, sizeof(NAME_TYPE)); + size = sizeof(uint32) + sizeof(uint32) + sizeof(NAME_TYPE); + break; + + case ELS_CMD_ADISC: + icmd->un.elsreq.remoteID = (uint32)((ulong)arg); /* DID */ + + if ((ndlp == 0) && + ((ndlp = fc_findnode_odid(binfo, NLP_SEARCH_ALL, (uint32)((ulong)arg))) == 0)) { + fc_mem_put(binfo, MEM_IOCB, (uchar * )temp); + fc_mem_put(binfo, MEM_BUF, (uchar * )mp); + fc_mem_put(binfo, MEM_BUF, (uchar * )rmp); + if (bmp) { + fc_mem_put(binfo, MEM_BPL, (uchar * )bmp); + } + return(1); + } + ndlp->nlp_DID = (uint32)((ulong)arg); + ndlp->nlp_flag |= NLP_REQ_SND_ADISC; + un.ap = (ADISC * )(bp); + un.ap->hardAL_PA = binfo->fc_pref_ALPA; + fc_bcopy((void *) & binfo->fc_portname, (void *) & un.ap->portName, + sizeof(NAME_TYPE)); + fc_bcopy((void *) & binfo->fc_nodename, (void *) & un.ap->nodeName, + sizeof(NAME_TYPE)); + un.ap->DID = SWAP_DATA(binfo->fc_myDID); + + size = sizeof(uint32) + sizeof(ADISC); + break; + + case ELS_CMD_PRLI: /* Process login */ + icmd->un.elsreq.remoteID = (uint32)((ulong)arg); /* DID */ + if ((ndlp == 0) && + ((ndlp = fc_findnode_odid(binfo, NLP_SEARCH_ALL, (uint32)((ulong)arg))) == 0)) { + fc_mem_put(binfo, MEM_IOCB, (uchar * )temp); + fc_mem_put(binfo, MEM_BUF, (uchar * )mp); + fc_mem_put(binfo, MEM_BUF, (uchar * )rmp); + if (bmp) { + fc_mem_put(binfo, MEM_BPL, (uchar * )bmp); + } + return(1); + } + ndlp->nlp_flag |= NLP_REQ_SND; + + /* For PRLI, remainder of payload is PRLI parameter page */ + fc_bzero((void *)bp, sizeof(PRLI)); + un.npr = (PRLI *)bp; + + /* + * If our firmware version is 3.20 or later, + * set the following bits for FC-TAPE support. + */ + if ( p_dev_ctl->vpd.rev.feaLevelHigh >= 0x02 ) { + un.npr->ConfmComplAllowed = 1; + un.npr->Retry = 1; + un.npr->TaskRetryIdReq = 1; + } + + un.npr->estabImagePair = 1; + un.npr->readXferRdyDis = 1; + if(clp[CFG_FCP_ON].a_current) { + un.npr->prliType = PRLI_FCP_TYPE; + un.npr->initiatorFunc = 1; + } + + size = sizeof(uint32) + sizeof(PRLI); + break; + + case ELS_CMD_PRLO: /* Process logout */ + /* For PRLO, remainder of payload is PRLO parameter page */ + fc_bzero((void *)bp, sizeof(PRLO)); + + icmd->un.elsreq.remoteID = (uint32)((ulong)arg); /* DID */ + size = sizeof(uint32) + sizeof(PRLO); + break; + + case ELS_CMD_SCR: /* State Change Registration */ + /* For SCR, remainder of payload is SCR parameter page */ + fc_bzero((void *)bp, sizeof(SCR)); + ((SCR * )bp)->Function = SCR_FUNC_FULL; + + icmd->un.elsreq.remoteID = (uint32)((ulong)arg); /* DID */ + size = sizeof(uint32) + sizeof(SCR); + break; + + case ELS_CMD_RNID: /* Node Identification */ + fc_bzero((void *)bp, sizeof(RNID)); + ((RNID * )bp)->Format = 0; + + icmd->un.elsreq.remoteID = (uint32)((ulong)arg); /* DID */ + size = sizeof(uint32) + sizeof(uint32); + break; + + case ELS_CMD_FARP: /* Farp */ + { + un.fp = (FARP * )(bp); + fc_bzero((void *)un.fp, sizeof(FARP)); + lp = (uint32 *)bp; + *lp++ = SWAP_DATA(binfo->fc_myDID); + un.fp->Mflags = FARP_MATCH_PORT; + un.fp->Rflags = FARP_REQUEST_PLOGI; + fc_bcopy((void *) & binfo->fc_portname, (void *) & un.fp->OportName, + sizeof(NAME_TYPE)); + fc_bcopy((void *) & binfo->fc_nodename, (void *) & un.fp->OnodeName, + sizeof(NAME_TYPE)); + switch(retry) { + case 0: + un.fp->Mflags = FARP_MATCH_PORT; + un.fp->RportName.nameType = NAME_IEEE; /* IEEE name */ + un.fp->RportName.IEEEextMsn = 0; + un.fp->RportName.IEEEextLsb = 0; + fc_bcopy(arg, (void *)un.fp->RportName.IEEE, 6); + un.fp->RnodeName.nameType = NAME_IEEE; /* IEEE name */ + un.fp->RnodeName.IEEEextMsn = 0; + un.fp->RnodeName.IEEEextLsb = 0; + fc_bcopy(arg, (void *)un.fp->RnodeName.IEEE, 6); + break; + case 1: + un.fp->Mflags = FARP_MATCH_PORT; + fc_bcopy(arg, (void *)&un.fp->RportName, sizeof(NAME_TYPE)); + retry = 0; + break; + case 2: + un.fp->Mflags = FARP_MATCH_NODE; + fc_bcopy(arg, (void *)&un.fp->RnodeName, sizeof(NAME_TYPE)); + retry = 0; + break; + } + + if((ndlp = fc_findnode_wwpn(binfo, NLP_SEARCH_ALL, &un.fp->RportName))) { + ndlp->nlp_flag |= NLP_FARP_SND; + ndlp->nlp_flag &= ~NLP_RM_ENTRY; + } + size = sizeof(uint32) + sizeof(FARP); + iotag = 0; + } + break; + + case ELS_CMD_FARPR: /* Farp response */ + { + icmd->un.elsreq.remoteID = (uint32)((ulong)arg); /* DID */ + un.fp = (FARP * )(bp); + lp = (uint32 *)bp; + *lp++ = SWAP_DATA((uint32)((ulong)arg)); + *lp++ = SWAP_DATA(binfo->fc_myDID); + un.fp->Rflags = 0; + un.fp->Mflags = (FARP_MATCH_PORT | FARP_MATCH_NODE); + + fc_bcopy((void *) & binfo->fc_portname, (void *) & un.fp->RportName, + sizeof(NAME_TYPE)); + fc_bcopy((void *) & binfo->fc_nodename, (void *) & un.fp->RnodeName, + sizeof(NAME_TYPE)); + if ((ndlp = fc_findnode_odid(binfo, NLP_SEARCH_ALL, (uint32)((ulong)arg)))) { + fc_bcopy((void *) & ndlp->nlp_portname, (void *) & un.fp->OportName, + sizeof(NAME_TYPE)); + fc_bcopy((void *) & ndlp->nlp_nodename, (void *) & un.fp->OnodeName, + sizeof(NAME_TYPE)); + } + + size = sizeof(uint32) + sizeof(FARP); + iotag = 0; + } + break; + + default: + fc_mem_put(binfo, MEM_IOCB, (uchar * )temp); + fc_mem_put(binfo, MEM_BUF, (uchar * )mp); + fc_mem_put(binfo, MEM_BUF, (uchar * )rmp); + if (bmp) { + fc_mem_put(binfo, MEM_BPL, (uchar * )bmp); + } + /* Xmit unknown ELS command */ + fc_log_printf_msg_vargs( binfo->fc_brd_no, + &fc_msgBlk0128, /* ptr to msg structure */ + fc_mes0128, /* ptr to msg */ + fc_msgBlk0128.msgPreambleStr, /* begin varargs */ + elscmd); /* end varargs */ + return(1); + } + + if (binfo->fc_flag & FC_SLI2) { + icmd->ulpCommand = CMD_ELS_REQUEST64_CR; + bpl->tus.f.bdeSize = size; + bpl->tus.w = PCIMEM_LONG(bpl->tus.w); + + fc_mpdata_sync(bmp->dma_handle, 0, 0, DDI_DMA_SYNC_FORDEV); + } else { + icmd->ulpCommand = CMD_ELS_REQUEST_CR; + icmd->un.cont[0].bdeSize = size; + } + + fc_mpdata_sync(mp->dma_handle, 0, 0, DDI_DMA_SYNC_FORDEV); + + if (iotag) { + icmd->ulpIoTag = iotag; + } + icmd->ulpIoTag0 = (unsigned)rp->fc_iotag++; + if ((rp->fc_iotag & 0x3fff) == 0) { + rp->fc_iotag = 1; + } + + /* Fill in rest of iocb */ + icmd->ulpBdeCount = 1; + icmd->ulpLe = 1; + icmd->ulpClass = CLASS3; + icmd->ulpOwner = OWN_CHIP; + temp->retry = (uchar)retry; /* retry = uint32 */ + rmp->fc_mptr = (uchar *)ndlp; + /* Xmit ELS command to remote NPORT */ + fc_log_printf_msg_vargs( binfo->fc_brd_no, + &fc_msgBlk0129, /* ptr to msg structure */ + fc_mes0129, /* ptr to msg */ + fc_msgBlk0129.msgPreambleStr, /* begin varargs */ + elscmd, + icmd->un.ulpWord[5], /* did */ + icmd->ulpIoTag, + binfo->fc_ffstate); /* end varargs */ + /* + * For handleing Dump command when system panic, + * the FC_BUS_RESET needs to be checked. If FC_BUS_RESET is set, + * there is no delay for issuing ELS command. + * FC_BUS_RESET is set by the lpfc_scsi_reset(). + */ + if(icmd->ulpDelayXmit) + { + if(icmd->ulpDelayXmit == 2) { + /* Delay issue of iocb 2048 interrupt latencies */ + if(binfo->fc_delayxmit) { + IOCBQ *iop; + iop = binfo->fc_delayxmit; + while(iop->q) + iop = (IOCBQ *)iop->q; + iop->q = (uchar *)temp; + } + else { + binfo->fc_delayxmit = temp; + } + temp->q = 0; + temp->rsvd2 = 2048; + } + else { + /* Delay issue of iocb for 1 to 2 seconds */ + temp->q = 0; + + setdelay = 1; /* seconds */ + fc_clk_set(p_dev_ctl, setdelay, fc_delay_timeout, (void *)temp, ndlp); + } + } + else { + issue_iocb_cmd(binfo, rp, temp); + } + + FCSTATCTR.elsXmitFrame++; + return(0); +} /* End fc_els_cmd */ + + +/***************************************/ +/** fc_els_rsp Issue an **/ +/** ELS response **/ +/***************************************/ +_static_ int +fc_els_rsp( +FC_BRD_INFO *binfo, +uint32 elscmd, +uint32 Xri, +uint32 class, +void *iocbp, +uint32 flag, +NODELIST *ndlp) +{ + IOCB * icmd; + IOCBQ * temp; + RING * rp; + uchar * bp; + MATCHMAP * mp, * bmp; + ULP_BDE64 * bpl; + ADISC * ap; + RNID * rn; + fc_vpd_t * vpd; + PRLI * npr; + iCfgParam * clp; + fc_dev_ctl_t * p_dev_ctl; + ushort size; + + rp = &binfo->fc_ring[FC_ELS_RING]; + clp = DD_CTL.p_config[binfo->fc_brd_no]; + p_dev_ctl = (fc_dev_ctl_t *)(binfo->fc_p_dev_ctl); + + /* Allocate buffer for command iocb */ + if ((temp = (IOCBQ * )fc_mem_get(binfo, MEM_IOCB)) == 0) { + return(1); + } + fc_bzero((void *)temp, sizeof(IOCBQ)); + icmd = &temp->iocb; + + /* fill in BDEs for command */ + /* Allocate buffer for response payload */ + if ((mp = (MATCHMAP * )fc_mem_get(binfo, MEM_BUF)) == 0) { + fc_mem_put(binfo, MEM_IOCB, (uchar * )temp); + return(1); + } + + if (binfo->fc_flag & FC_SLI2) { + /* Allocate buffer for Buffer ptr list */ + if ((bmp = (MATCHMAP * )fc_mem_get(binfo, MEM_BPL)) == 0) { + fc_mem_put(binfo, MEM_IOCB, (uchar * )temp); + fc_mem_put(binfo, MEM_BUF, (uchar * )mp); + return(1); + } + bpl = (ULP_BDE64 * )bmp->virt; + bpl->addrLow = PCIMEM_LONG(putPaddrLow((ulong)mp->phys)); + bpl->addrHigh = PCIMEM_LONG(putPaddrHigh((ulong)mp->phys)); + bpl->tus.f.bdeFlags = 0; + + icmd->un.elsreq64.bdl.ulpIoTag32 = (uint32)0; + icmd->un.elsreq64.bdl.addrHigh = (uint32)putPaddrHigh(bmp->phys); + icmd->un.elsreq64.bdl.addrLow = (uint32)putPaddrLow(bmp->phys); + icmd->un.elsreq64.bdl.bdeSize = sizeof(ULP_BDE64); + icmd->un.elsreq64.bdl.bdeFlags = BUFF_TYPE_BDL; + temp->bpl = (uchar *)bmp; + } else { + bpl = 0; + bmp = 0; + icmd->un.cont[0].bdeAddress = (uint32)putPaddrLow(mp->phys); + temp->bpl = 0; + } + + bp = mp->virt; + + /* Save for completion so we can release these resources */ + temp->bp = (uchar * )mp; + temp->ndlp = (uchar * )ndlp; + + /* Fill in command field in payload */ + *((uint32 * )(bp)) = elscmd; /* ACC or LS_RJT */ + + switch (elscmd) { + case ELS_CMD_ACC: /* Accept Response */ + /* ACCEPT will optionally contain service parameters, + * depending on flag. + */ + bp += sizeof(uint32); + if (flag >= sizeof(SERV_PARM)) { + fc_bcopy((void *) & binfo->fc_sparam, (void *)bp, sizeof(SERV_PARM)); + size = (sizeof(SERV_PARM) + sizeof(uint32)); + } else { + size = sizeof(uint32); + } + break; + + case ELS_CMD_LS_RJT: /* reject response */ + bp += sizeof(uint32); + *((uint32 * )(bp)) = flag; /* fill in error code */ + size = sizeof(uint32) + sizeof(uint32); + break; + + case ELS_CMD_ADISC: + *((uint32 * )(bp)) = ELS_CMD_ACC; + bp += sizeof(uint32); + if(ndlp) + icmd->un.elsreq.remoteID = ndlp->nlp_DID; /* DID */ + + ap = (ADISC * )(bp); + ap->hardAL_PA = binfo->fc_pref_ALPA; + fc_bcopy((void *) & binfo->fc_portname, (void *) & ap->portName, + sizeof(NAME_TYPE)); + fc_bcopy((void *) & binfo->fc_nodename, (void *) & ap->nodeName, + sizeof(NAME_TYPE)); + ap->DID = SWAP_DATA(binfo->fc_myDID); + + size = sizeof(uint32) + sizeof(ADISC); + break; + + case ELS_CMD_PRLI: + *((uint32 * )(bp)) = (ELS_CMD_ACC | (ELS_CMD_PRLI & ~ELS_RSP_MASK)); + bp += sizeof(uint32); + npr = (PRLI *)bp; + if(ndlp) + icmd->un.elsreq.remoteID = ndlp->nlp_DID; /* DID */ + + /* For PRLI, remainder of payload is PRLI parameter page */ + fc_bzero((void *)bp, sizeof(PRLI)); + + vpd = &p_dev_ctl->vpd; + /* + * If our firmware version is 3.20 or later, + * set the following bits for FC-TAPE support. + */ + if ( vpd->rev.feaLevelHigh >= 0x02 ) { + npr->ConfmComplAllowed = 1; + npr->Retry = 1; + npr->TaskRetryIdReq = 1; + } + + npr->acceptRspCode = PRLI_REQ_EXECUTED; + npr->estabImagePair = 1; + npr->readXferRdyDis = 1; + npr->ConfmComplAllowed = 1; + if(clp[CFG_FCP_ON].a_current) { + npr->prliType = PRLI_FCP_TYPE; + npr->initiatorFunc = 1; + } + + size = sizeof(uint32) + sizeof(PRLI); + break; + + case ELS_CMD_RNID: + *((uint32 * )(bp)) = ELS_CMD_ACC; + bp += sizeof(uint32); + + rn = (RNID * )(bp); + fc_bzero((void *)bp, sizeof(RNID)); + rn->Format = (uchar)flag; + rn->CommonLen = (2 * sizeof(NAME_TYPE)); + fc_bcopy((void *) & binfo->fc_portname, (void *) & rn->portName, + sizeof(NAME_TYPE)); + fc_bcopy((void *) & binfo->fc_nodename, (void *) & rn->nodeName, + sizeof(NAME_TYPE)); + switch(flag) { + case 0: + rn->SpecificLen = 0; + break; + case RNID_TOPOLOGY_DISC: + rn->SpecificLen = sizeof(RNID_TOP_DISC); + fc_bcopy((void *) & binfo->fc_portname, + (void *) & rn->un.topologyDisc.portName, sizeof(NAME_TYPE)); + rn->un.topologyDisc.unitType = RNID_HBA; + rn->un.topologyDisc.physPort = 0; + rn->un.topologyDisc.attachedNodes = 0; + if(clp[CFG_NETWORK_ON].a_current) { + rn->un.topologyDisc.ipVersion = binfo->ipVersion; + rn->un.topologyDisc.UDPport = binfo->UDPport; + fc_bcopy((void *) & binfo->ipAddr[0], + (void *) & rn->un.topologyDisc.ipAddr[0], 16); + } + break; + default: + rn->CommonLen = 0; + rn->SpecificLen = 0; + break; + } + size = sizeof(uint32) + sizeof(uint32) + rn->CommonLen + rn->SpecificLen; + break; + + default: + fc_mem_put(binfo, MEM_IOCB, (uchar * )temp); + fc_mem_put(binfo, MEM_BUF, (uchar * )mp); + if (bmp) { + fc_mem_put(binfo, MEM_BPL, (uchar * )bmp); + } + /* Xmit unknown ELS response (elsCmd> */ + fc_log_printf_msg_vargs( binfo->fc_brd_no, + &fc_msgBlk0130, /* ptr to msg structure */ + fc_mes0130, /* ptr to msg */ + fc_msgBlk0130.msgPreambleStr, /* begin varargs */ + elscmd ); /* end varargs */ + return(1); + } + + if (binfo->fc_flag & FC_SLI2) { + icmd->ulpCommand = CMD_XMIT_ELS_RSP64_CX; + bpl->tus.f.bdeSize = size; + bpl->tus.w = PCIMEM_LONG(bpl->tus.w); + + fc_mpdata_sync(bmp->dma_handle, 0, 0, DDI_DMA_SYNC_FORDEV); + } else { + icmd->ulpCommand = CMD_XMIT_ELS_RSP_CX; + icmd->un.cont[0].bdeSize = size; + } + + fc_mpdata_sync(mp->dma_handle, 0, 0, DDI_DMA_SYNC_FORDEV); + + /* If iotag is zero, assign one from global counter for board */ + if (iocbp == 0) { + temp->retry = 0; + } else { + icmd->ulpIoTag = ((IOCB *)iocbp)->ulpIoTag; + temp->retry = ((IOCBQ *)iocbp)->retry; + } + icmd->ulpIoTag0 = (unsigned)rp->fc_iotag++; + if ((rp->fc_iotag & 0x3fff) == 0) { + rp->fc_iotag = 1; + } + + /* fill in rest of iocb */ + icmd->ulpContext = (volatile ushort)Xri; + icmd->ulpBdeCount = 1; + icmd->ulpLe = 1; + icmd->ulpClass = class; + icmd->ulpOwner = OWN_CHIP; + /* Xmit ELS response to remote NPORT */ + fc_log_printf_msg_vargs( binfo->fc_brd_no, + &fc_msgBlk0131, /* ptr to msg structure */ + fc_mes0131, /* ptr to msg */ + fc_msgBlk0131.msgPreambleStr, /* begin varargs */ + elscmd, + icmd->un.ulpWord[5], /* did */ + icmd->ulpIoTag, + size); /* end varargs */ + issue_iocb_cmd(binfo, rp, temp); + + FCSTATCTR.elsXmitFrame++; + return(0); +} /* End fc_els_rsp */ + + +/* Retries the appropriate ELS command if necessary */ +_local_ int +fc_els_retry( +FC_BRD_INFO *binfo, +RING *rp, +IOCBQ *iocbq, +uint32 cmd, +NODELIST *ndlp) +{ + IOCB *iocb; + MATCHMAP *bmp; + + if (((binfo->fc_flag & FC_RSCN_MODE) && (binfo->fc_ffstate == FC_READY)) || + (binfo->fc_ffstate == FC_LOOP_DISC) || + (binfo->fc_ffstate == FC_NODE_DISC)) { + binfo->fc_fabrictmo = (2 * binfo->fc_ratov) + + ((4 * binfo->fc_edtov) / 1000) + 1; + if(FABRICTMO) { + fc_clk_res((fc_dev_ctl_t *)(binfo->fc_p_dev_ctl), + binfo->fc_fabrictmo, FABRICTMO); + } + else { + FABRICTMO = fc_clk_set((fc_dev_ctl_t *)(binfo->fc_p_dev_ctl), + binfo->fc_fabrictmo, fc_fabric_timeout, 0, 0); + } + } + + iocb = &iocbq->iocb; + /* Do not retry FARP/ADISC/PDISC */ + if ((cmd == ELS_CMD_FARP) || + (cmd == ELS_CMD_FARPR) || + (cmd == ELS_CMD_ADISC) || + (cmd == ELS_CMD_PDISC)) { + goto out; + } + + if (fc_status_action(binfo, iocbq, cmd, ndlp)) { + /* Indicates iocb should be retried */ + /* Retry ELS response/command */ + FCSTATCTR.elsXmitRetry++; + switch (iocb->ulpCommand) { + case CMD_ELS_REQUEST_CR: + case CMD_ELS_REQUEST64_CR: + case CMD_ELS_REQUEST_CX: + case CMD_ELS_REQUEST64_CX: + fc_els_cmd(binfo, cmd, (void *)((ulong)iocb->un.elsreq.remoteID), + (uint32)iocbq->retry, (ushort)iocb->ulpIoTag, ndlp); + break; + case CMD_XMIT_ELS_RSP_CX: + fc_els_rsp(binfo,cmd,(uint32)iocb->ulpContext, (uint32)iocb->ulpClass, + (void *)iocbq, (uint32)iocb->un.cont[0].bdeSize, ndlp); + break; + case CMD_XMIT_ELS_RSP64_CX: + bmp = (MATCHMAP *)iocbq->bpl; + if(bmp && bmp->virt) { + fc_els_rsp(binfo,cmd,(uint32)iocb->ulpContext, + (uint32)iocb->ulpClass, (void *)iocbq, + (uint32)(((ULP_BDE64 * )bmp->virt)->tus.f.bdeSize), ndlp); + } + break; + default: + goto out; + } + return(1); + } + +out: + /* ELS Retry failed */ + fc_log_printf_msg_vargs( binfo->fc_brd_no, + &fc_msgBlk0132, /* ptr to msg structure */ + fc_mes0132, /* ptr to msg */ + fc_msgBlk0132.msgPreambleStr, /* begin varargs */ + cmd, + iocb->un.ulpWord[4] ); /* end varargs */ + return(0); +} /* End fc_els_retry */ + + +/* Determines what action to take as result of the status + * field in the iocb. If the status indicates a retry, the iocb + * will be setup for retry and a 1 will be returned. If the status + * indicates error with no action, a 0 will be returned. + * The retry count is kept in the ls byte of the iotag. + */ +_local_ int +fc_status_action( +FC_BRD_INFO *binfo, +IOCBQ *iocbq, +uint32 cmd, +NODELIST *ndlp) +{ + uint32 class; + uchar tag; + int maxretry; + LS_RJT stat; + IOCB *iocb; + + maxretry = FC_MAXRETRY; + iocb = &iocbq->iocb; + iocb->ulpDelayXmit = 0; + + if(ndlp) { + if(ndlp->nlp_action & NLP_DO_RNID) + return(0); + if((ndlp->nlp_DID == 0) && (ndlp->nlp_type == 0)) + return(0); + } + + switch (iocb->ulpStatus) { + case IOSTAT_FCP_RSP_ERROR: + case IOSTAT_REMOTE_STOP: + break; + + case IOSTAT_LOCAL_REJECT: + if ((iocb->un.ulpWord[4] & 0xff) == IOERR_LINK_DOWN) + return(0); + + if ((iocb->un.ulpWord[4] & 0xff) == IOERR_LOOP_OPEN_FAILURE) { + if(cmd == ELS_CMD_PLOGI) { + if (iocbq->retry == 0) + iocb->ulpDelayXmit = 2; + } + goto elsretry; + } + if ((iocb->un.ulpWord[4] & 0xff) == IOERR_SEQUENCE_TIMEOUT) { + goto elsretry; + } + if ((iocb->un.ulpWord[4] & 0xff) == IOERR_NO_RESOURCES) { + if(cmd == ELS_CMD_PLOGI) + iocb->ulpDelayXmit = 1; + goto elsretry; + } + if ((iocb->un.ulpWord[4] & 0xff) == IOERR_INVALID_RPI) { + goto elsretry; + } + break; + + case IOSTAT_NPORT_RJT: + case IOSTAT_FABRIC_RJT: + /* iotag is retry count */ + if ((tag = (iocbq->retry + 1)) >= maxretry) { + FCSTATCTR.elsRetryExceeded++; + break; + } + + iocbq->retry = tag; + if (iocb->un.ulpWord[4] & RJT_UNAVAIL_TEMP) { + /* not avail temporary */ + /* Retry ELS command */ + return(1); + } + if (iocb->un.ulpWord[4] & RJT_UNSUP_CLASS) { + /* class not supported */ + if (cmd == ELS_CMD_FARP) + return(0); + if (binfo->fc_topology == TOPOLOGY_LOOP) { + /* for FC-AL retry logic goes class 3 - 2 - 1 */ + if (iocb->ulpClass == CLASS3) { + class = CLASS2; + } else { + break; + } + } else { + /* for non FC-AL retry logic goes class 1 - 2 */ + if (iocb->ulpClass == CLASS1) { + class = CLASS2; + } else { + break; + } + } + iocb->ulpClass = class; + /* Retry ELS command */ + return(1); + } + break; + + case IOSTAT_NPORT_BSY: + case IOSTAT_FABRIC_BSY: +elsretry: + tag = (iocbq->retry + 1); + /* iotag is retry count */ + if(ndlp) { + if(cmd == ELS_CMD_PLOGI) { + if((ndlp->nlp_state >= NLP_LOGIN) || + (ndlp->nlp_flag & NLP_REG_INP)) { + return(0); /* Don't retry */ + } + } + if(ndlp->nlp_flag & NLP_NODEV_TMO) { + iocbq->retry = tag; + /* Retry ELS command */ + return(1); + } + } + if(tag >= maxretry) { + FCSTATCTR.elsRetryExceeded++; + break; + } + iocbq->retry = tag; + /* Retry ELS command */ + return(1); + + case IOSTAT_LS_RJT: + stat.un.lsRjtError = SWAP_DATA(iocb->un.ulpWord[4]); + switch(stat.un.b.lsRjtRsnCode) { + case LSRJT_UNABLE_TPC: + if(stat.un.b.lsRjtRsnCodeExp == LSEXP_CMD_IN_PROGRESS) { + if(cmd == ELS_CMD_PLOGI) { + iocb->ulpDelayXmit = 1; + maxretry = 48; + } + goto elsretry; + } + if(cmd == ELS_CMD_PLOGI) { + iocb->ulpDelayXmit = 1; + + /* allow for 1sec FLOGI delay */ + maxretry = FC_MAXRETRY + 1; + goto elsretry; + } + break; + + case LSRJT_LOGICAL_BSY: + if(cmd == ELS_CMD_PLOGI) { + iocb->ulpDelayXmit = 1; + maxretry = 48; + } + goto elsretry; + } + + break; + + case IOSTAT_INTERMED_RSP: + case IOSTAT_BA_RJT: + break; + + default: + break; + } + + if((cmd == ELS_CMD_FLOGI) && (binfo->fc_topology != TOPOLOGY_LOOP)) { + iocb->ulpDelayXmit = 1; + maxretry = 48; + if ((tag = (iocbq->retry + 1)) >= maxretry) + return(0); + iocbq->retry = tag; + return(1); + } + return(0); +} /* End fc_status_action */ + + +_static_ void +fc_snd_flogi( +fc_dev_ctl_t * p_dev_ctl, +void *p1, +void *p2) +{ + FC_BRD_INFO * binfo; + RING * rp; + + binfo = &BINFO; + /* Stop the link down watchdog timer */ + rp = &binfo->fc_ring[FC_FCP_RING]; + if(RINGTMO) { + fc_clk_can(p_dev_ctl, RINGTMO); + RINGTMO = 0; + } + binfo->fc_flag &= ~(FC_LD_TIMEOUT | FC_LD_TIMER); + + /* We are either private or public loop topology */ + /* We are either Fabric or point-to-point topology */ + /* Now build FLOGI payload and issue ELS command to find out */ + fc_els_cmd(binfo, ELS_CMD_FLOGI, (void *)Fabric_DID, + (uint32)0, (ushort)0, (NODELIST *)0); + + /* + * Cancel the establish reset timer + * If we come to this point, we don't need tht timer to + * clear the FC_ESTABLISH_LINK flag. + */ + if (p_dev_ctl->fc_estabtmo) { + fc_clk_can(p_dev_ctl, p_dev_ctl->fc_estabtmo); + p_dev_ctl->fc_estabtmo = 0; + } + return; +} + +/* Wait < a second before sending intial FLOGI to start discovery */ +int +fc_initial_flogi( +fc_dev_ctl_t * p_dev_ctl) /* point to dev_ctl area */ +{ + if((p_dev_ctl->fc_waitflogi = fc_clk_set(p_dev_ctl, 0, fc_snd_flogi, 0, 0)) == 0) + fc_snd_flogi(p_dev_ctl, 0, 0); + return(0); +} + +/***************************************/ +/** fc_issue_ct_rsp Issue an **/ +/** CT rsp **/ +/***************************************/ +_static_ int +fc_issue_ct_rsp( +FC_BRD_INFO * binfo, +uint32 tag, +MATCHMAP * bmp, +DMATCHMAP * inp) +{ + IOCB * icmd; + IOCBQ * temp; + RING * rp; + fc_dev_ctl_t * p_dev_ctl; + uint32 num_entry; + + rp = &binfo->fc_ring[FC_ELS_RING]; + num_entry = (uint32)inp->dfc_flag; + inp->dfc_flag = 0; + + /* Allocate buffer for command iocb */ + if ((temp = (IOCBQ * )fc_mem_get(binfo, MEM_IOCB)) == 0) { + return(1); + } + fc_bzero((void *)temp, sizeof(IOCBQ)); + icmd = &temp->iocb; + + icmd->un.xseq64.bdl.ulpIoTag32 = (uint32)0; + icmd->un.xseq64.bdl.addrHigh = (uint32)putPaddrHigh(bmp->phys); + icmd->un.xseq64.bdl.addrLow = (uint32)putPaddrLow(bmp->phys); + icmd->un.xseq64.bdl.bdeFlags = BUFF_TYPE_BDL; + icmd->un.xseq64.bdl.bdeSize = (num_entry * sizeof(ULP_BDE64)); + + /* Save for completion so we can release these resources */ + temp->bp = (uchar * )inp; + + icmd->un.xseq64.w5.hcsw.Fctl = (LS | LA); + icmd->un.xseq64.w5.hcsw.Dfctl = 0; + icmd->un.xseq64.w5.hcsw.Rctl = FC_SOL_CTL; + icmd->un.xseq64.w5.hcsw.Type = FC_COMMON_TRANSPORT_ULP; + + p_dev_ctl = (fc_dev_ctl_t *)(binfo->fc_p_dev_ctl); + fc_mpdata_sync(bmp->dma_handle, 0, 0, DDI_DMA_SYNC_FORDEV); + + /* If iotag is zero, assign one from global counter for board */ + icmd->ulpIoTag0 = (unsigned)rp->fc_iotag++; + if ((rp->fc_iotag & 0x3fff) == 0) { + rp->fc_iotag = 1; + } + + /* Fill in rest of iocb */ + icmd->ulpCommand = CMD_XMIT_SEQUENCE64_CX; + icmd->ulpBdeCount = 1; + icmd->ulpLe = 1; + icmd->ulpClass = CLASS3; + icmd->ulpContext = (ushort)tag; + icmd->ulpOwner = OWN_CHIP; + /* Xmit CT response on exchange */ + fc_log_printf_msg_vargs( binfo->fc_brd_no, + &fc_msgBlk0133, /* ptr to msg structure */ + fc_mes0133, /* ptr to msg */ + fc_msgBlk0133.msgPreambleStr, /* begin varargs */ + icmd->ulpContext, /* xid */ + icmd->ulpIoTag, + binfo->fc_ffstate ); /* end varargs */ + issue_iocb_cmd(binfo, rp, temp); + return(0); +} /* fc_issue_ct_rsp */ + +/***************************************/ +/** fc_gen_req Issue an **/ +/** GEN_REQUEST cmd **/ +/***************************************/ +_static_ int +fc_gen_req( +FC_BRD_INFO * binfo, +MATCHMAP * bmp, +MATCHMAP * inp, +MATCHMAP * outp, +uint32 rpi, +uint32 usr_flg, +uint32 num_entry, +uint32 tmo) +{ + IOCB * icmd; + IOCBQ * temp; + RING * rp; + fc_dev_ctl_t * p_dev_ctl; + + + rp = &binfo->fc_ring[FC_ELS_RING]; + + /* Allocate buffer for command iocb */ + if ((temp = (IOCBQ * )fc_mem_get(binfo, MEM_IOCB | MEM_PRI)) == 0) { + return(1); + } + fc_bzero((void *)temp, sizeof(IOCBQ)); + icmd = &temp->iocb; + + icmd->un.genreq64.bdl.ulpIoTag32 = (uint32)0; + icmd->un.genreq64.bdl.addrHigh = (uint32)putPaddrHigh(bmp->phys); + icmd->un.genreq64.bdl.addrLow = (uint32)putPaddrLow(bmp->phys); + icmd->un.genreq64.bdl.bdeFlags = BUFF_TYPE_BDL; + icmd->un.genreq64.bdl.bdeSize = (num_entry * sizeof(ULP_BDE64)); + + if(usr_flg) + temp->bpl = 0; + else + temp->bpl = (uchar *)bmp; + + /* Save for completion so we can release these resources */ + temp->bp = (uchar * )inp; + temp->info = (uchar * )outp; + + /* Fill in payload, bp points to frame payload */ + icmd->ulpCommand = CMD_GEN_REQUEST64_CR; + + p_dev_ctl = (fc_dev_ctl_t *)(binfo->fc_p_dev_ctl); + fc_mpdata_sync(bmp->dma_handle, 0, 0, DDI_DMA_SYNC_FORDEV); + + /* If iotag is zero, assign one from global counter for board */ + icmd->ulpIoTag0 = (unsigned)rp->fc_iotag++; + if ((rp->fc_iotag & 0x3fff) == 0) { + rp->fc_iotag = 1; + } + + /* Fill in rest of iocb */ + icmd->un.genreq64.w5.hcsw.Fctl = (SI | LA); + icmd->un.genreq64.w5.hcsw.Dfctl = 0; + icmd->un.genreq64.w5.hcsw.Rctl = FC_UNSOL_CTL; + icmd->un.genreq64.w5.hcsw.Type = FC_COMMON_TRANSPORT_ULP; + + if(tmo == 0) + tmo = (2 * binfo->fc_ratov); + icmd->ulpTimeout = tmo; + icmd->ulpBdeCount = 1; + icmd->ulpLe = 1; + icmd->ulpClass = CLASS3; + icmd->ulpContext = (volatile ushort)rpi; + icmd->ulpOwner = OWN_CHIP; + /* Issue GEN REQ IOCB for NPORT */ + fc_log_printf_msg_vargs( binfo->fc_brd_no, + &fc_msgBlk0134, /* ptr to msg structure */ + fc_mes0134, /* ptr to msg */ + fc_msgBlk0134.msgPreambleStr, /* begin varargs */ + icmd->un.ulpWord[5], /* did */ + icmd->ulpIoTag, + binfo->fc_ffstate ); /* end varargs */ + issue_iocb_cmd(binfo, rp, temp); + + FCSTATCTR.elsXmitFrame++; + return(0); +} /* End fc_gen_req */ + + +/***************************************/ +/** fc_rnid_req Issue an **/ +/** RNID REQUEST cmd **/ +/***************************************/ +_static_ int +fc_rnid_req( +FC_BRD_INFO * binfo, +DMATCHMAP * inp, +DMATCHMAP * outp, +MATCHMAP ** bmpp, +uint32 rpi) +{ + IOCB * icmd; + IOCBQ * temp; + RING * rp; + ULP_BDE64 * bpl; + MATCHMAP * bmp; + fc_dev_ctl_t * p_dev_ctl; + + + rp = &binfo->fc_ring[FC_ELS_RING]; + + /* Allocate buffer for command iocb */ + if ((temp = (IOCBQ * )fc_mem_get(binfo, MEM_IOCB | MEM_PRI)) == 0) { + return(1); + } + fc_bzero((void *)temp, sizeof(IOCBQ)); + icmd = &temp->iocb; + + if (binfo->fc_flag & FC_SLI2) { + /* Allocate buffer for Buffer ptr list */ + if ((bmp = (MATCHMAP * )fc_mem_get(binfo, MEM_BPL | MEM_PRI)) == 0) { + fc_mem_put(binfo, MEM_IOCB, (uchar * )temp); + return(1); + } + *bmpp = bmp; /* to free BPL on compl */ + bpl = (ULP_BDE64 * )bmp->virt; + bpl->addrLow = PCIMEM_LONG(putPaddrLow((ulong)inp->dfc.phys)); + bpl->addrHigh = PCIMEM_LONG(putPaddrHigh((ulong)inp->dfc.phys)); + bpl->tus.f.bdeFlags = 0; + bpl++; + bpl->addrLow = PCIMEM_LONG(putPaddrLow((ulong)outp->dfc.phys)); + bpl->addrHigh = PCIMEM_LONG(putPaddrHigh((ulong)outp->dfc.phys)); + bpl->tus.f.bdeSize = (ushort)((ulong)(outp->dfc.fc_mptr)); + bpl->tus.f.bdeFlags = BUFF_USE_RCV; + bpl->tus.w = PCIMEM_LONG(bpl->tus.w); + + bpl--; /* so we can fill in size later */ + + icmd->un.genreq64.bdl.ulpIoTag32 = (uint32)0; + icmd->un.genreq64.bdl.addrHigh = (uint32)putPaddrHigh(bmp->phys); + icmd->un.genreq64.bdl.addrLow = (uint32)putPaddrLow(bmp->phys); + icmd->un.genreq64.bdl.bdeSize = (2 * sizeof(ULP_BDE64)); + icmd->un.genreq64.bdl.bdeFlags = BUFF_TYPE_BDL; + temp->bpl = 0; + } else { + fc_mem_put(binfo, MEM_IOCB, (uchar * )temp); + return(1); + } + + /* Save for completion so we can release these resources */ + temp->info = (uchar * )outp; + + /* Fill in payload, bp points to frame payload */ + icmd->ulpCommand = CMD_GEN_REQUEST64_CR; + bpl->tus.f.bdeSize = (ushort)((ulong)(inp->dfc.fc_mptr)); + bpl->tus.w = PCIMEM_LONG(bpl->tus.w); + + p_dev_ctl = (fc_dev_ctl_t *)(binfo->fc_p_dev_ctl); + fc_mpdata_sync(bmp->dma_handle, 0, 0, DDI_DMA_SYNC_FORDEV); + fc_mpdata_sync(inp->dfc.dma_handle, 0, 0, DDI_DMA_SYNC_FORDEV); + + /* If iotag is zero, assign one from global counter for board */ + icmd->ulpIoTag0 = (unsigned)rp->fc_iotag++; + if ((rp->fc_iotag & 0x3fff) == 0) { + rp->fc_iotag = 1; + } + + /* Fill in rest of iocb */ + icmd->un.genreq64.w5.hcsw.Fctl = (SI | LA); + icmd->un.genreq64.w5.hcsw.Dfctl = 0; + icmd->un.genreq64.w5.hcsw.Rctl = FC_ELS_REQ; + icmd->un.genreq64.w5.hcsw.Type = FC_ELS_DATA; + + icmd->ulpBdeCount = 1; + icmd->ulpLe = 1; + icmd->ulpClass = CLASS3; + icmd->ulpTimeout = (uchar)(rp->fc_ringtmo - 2); + icmd->ulpContext = (volatile ushort)rpi; + icmd->ulpOwner = OWN_CHIP; + /* Issue GEN REQ IOCB for RNID */ + fc_log_printf_msg_vargs( binfo->fc_brd_no, + &fc_msgBlk0135, /* ptr to msg structure */ + fc_mes0135, /* ptr to msg */ + fc_msgBlk0135.msgPreambleStr, /* begin varargs */ + icmd->un.ulpWord[5], /* did */ + icmd->ulpIoTag, + binfo->fc_ffstate ); /* end varargs */ + issue_iocb_cmd(binfo, rp, temp); + outp->dfc.fc_mptr = 0; + + FCSTATCTR.elsXmitFrame++; + return(0); +} /* End fc_rnid_req */ + + +/***************************************/ +/** fc_issue_ct_req Issue a **/ +/** CT request to nameserver **/ +/***************************************/ +_static_ int +fc_issue_ct_req( +FC_BRD_INFO * binfo, +uint32 portid, +MATCHMAP * bmp, +DMATCHMAP * inmp, +DMATCHMAP * outmp, +uint32 tmo) +{ + uint32 size; + NODELIST * ndlp; + + size = (uint32)outmp->dfc_flag; + /* Find nameserver entry */ + if((((ndlp = fc_findnode_odid(binfo, NLP_SEARCH_ALL, portid))) == 0) || + (ndlp->nlp_Rpi == 0) || + (binfo->fc_flag & FC_RSCN_MODE)) { + + if ((binfo->fc_flag & FC_FABRIC) && (binfo->fc_ffstate == FC_READY)) { + if ((ndlp == 0) || ((ndlp->nlp_state < NLP_PLOGI) && !(ndlp->nlp_flag & NLP_NS_REMOVED))) { + /* We can LOGIN to the port first */ + fc_els_cmd(binfo, ELS_CMD_PLOGI, (void *)((ulong)portid), + (uint32)0, (ushort)0, ndlp); + } + return(ENODEV); + } + return(EACCES); + } + + if((fc_gen_req(binfo, bmp, (MATCHMAP *)inmp, (MATCHMAP *)outmp, + ndlp->nlp_Rpi, 1, (inmp->dfc_flag + outmp->dfc_flag), tmo))) + return(ENOMEM); + + outmp->dfc_flag = 0; + return(0); +} + +/**************************************************/ +/** **/ +/** Free any deferred RSCNs **/ +/** **/ +/**************************************************/ +_static_ int +fc_flush_rscn_defer( +fc_dev_ctl_t *p_dev_ctl) +{ + FC_BRD_INFO * binfo; + RING * rp; + IOCBQ * xmitiq; + IOCB * iocb; + MATCHMAP * mp; + int i; + + binfo = &BINFO; + rp = &binfo->fc_ring[FC_ELS_RING]; + while (binfo->fc_defer_rscn.q_first) { + xmitiq = (IOCBQ * )binfo->fc_defer_rscn.q_first; + if ((binfo->fc_defer_rscn.q_first = xmitiq->q) == 0) { + binfo->fc_defer_rscn.q_last = 0; + } + binfo->fc_defer_rscn.q_cnt--; + iocb = &xmitiq->iocb; + mp = *((MATCHMAP **)iocb); + *((MATCHMAP **)iocb) = 0; + xmitiq->q = NULL; + fc_mem_put(binfo, MEM_BUF, (uchar * )mp); + + i = 1; + /* free resources associated with this iocb and repost the ring buffers */ + if (!(binfo->fc_flag & FC_SLI2)) { + for (i = 1; i < (int)iocb->ulpBdeCount; i++) { + mp = fc_getvaddr(p_dev_ctl, rp, (uchar * )((ulong)iocb->un.cont[i].bdeAddress)); + if (mp) { + fc_mem_put(binfo, MEM_BUF, (uchar * )mp); + } + } + } + fc_mem_put(binfo, MEM_IOCB, (uchar * )xmitiq); + } + return(0); +} + +/**************************************************/ +/** **/ +/** Issue a NameServer query for RSCN processing **/ +/** **/ +/**************************************************/ +_static_ void +fc_issue_ns_query( +fc_dev_ctl_t *p_dev_ctl, +void *a1, +void *a2) +{ + FC_BRD_INFO * binfo; + NODELIST * ndlp; + + binfo = &BINFO; + binfo->fc_flag &= ~FC_NSLOGI_TMR; + /* Now check with NameServer */ + if ((ndlp = fc_findnode_odid(binfo, NLP_SEARCH_ALL, NameServer_DID)) == 0) { + /* We can LOGIN to the NameServer now */ + fc_els_cmd(binfo, ELS_CMD_PLOGI, (void *)NameServer_DID, + (uint32)0, (ushort)0, ndlp); + } + else { + /* Issue GID_FT to Nameserver */ + if (fc_ns_cmd(p_dev_ctl, ndlp, SLI_CTNS_GID_FT)) { + /* error so start discovery */ + /* Done with NameServer for now, but keep logged in */ + ndlp->nlp_action &= ~NLP_DO_RSCN; + + /* Fire out PLOGIs on nodes marked for discovery */ + if ((binfo->fc_nlp_cnt <= 0) && + !(binfo->fc_flag & FC_NLP_MORE)) { + binfo->fc_nlp_cnt = 0; + fc_nextrscn(p_dev_ctl, fc_max_els_sent); + } + else { + fc_nextnode(p_dev_ctl, ndlp); + } + ndlp->nlp_action &= ~NLP_DO_ADDR_AUTH; + } + } + return; +} + +_static_ int +fc_abort_discovery( +fc_dev_ctl_t *p_dev_ctl) +{ + FC_BRD_INFO * binfo; + MAILBOXQ * mb; + + binfo = &BINFO; + + fc_linkdown(p_dev_ctl); + + /* This should turn off DELAYED ABTS for ELS timeouts */ + if ((mb = (MAILBOXQ * )fc_mem_get(binfo, MEM_MBOX))) { + fc_set_slim(binfo, (MAILBOX * )mb, 0x052198, 0); + if (issue_mb_cmd(binfo, (MAILBOX * )mb, MBX_NOWAIT) != MBX_BUSY) { + fc_mem_put(binfo, MEM_MBOX, (uchar * )mb); + } + } + + /* This is at init, clear la */ + if ((mb = (MAILBOXQ * )fc_mem_get(binfo, MEM_MBOX | MEM_PRI))) { + fc_clear_la(binfo, (MAILBOX * )mb); + if (issue_mb_cmd(binfo, (MAILBOX * )mb, MBX_NOWAIT) != MBX_BUSY) { + fc_mem_put(binfo, MEM_MBOX, (uchar * )mb); + } + } else { + binfo->fc_ffstate = FC_ERROR; + /* Device Discovery completion error */ + fc_log_printf_msg_vargs( binfo->fc_brd_no, + &fc_msgBlk0217, /* ptr to msg structure */ + fc_mes0217, /* ptr to msg */ + fc_msgBlk0217.msgPreambleStr); /* begin & end varargs */ + } + if(FABRICTMO) { + fc_clk_can(p_dev_ctl, FABRICTMO); + FABRICTMO = 0; + } + return(0); +} + +#define FOURBYTES 4 + +/**************************************************/ +/** fc_fdmi_cmd **/ +/** **/ +/** Description: **/ +/** Issue Cmd to HBA Management Server **/ +/** SLI_MGMT_RHBA **/ +/** SLI_MGMT_RPRT **/ +/** SLI_MGMT_DHBA **/ +/** SLI_MGMT_DPRT **/ +/** **/ +/** Accept Payload for those 4 commands **/ +/** is 0 **/ +/** **/ +/** Returns: **/ +/** **/ +/**************************************************/ +_static_ int +fc_fdmi_cmd( +fc_dev_ctl_t *p_dev_ctl, +NODELIST *ndlp, +int cmdcode) +{ + FC_BRD_INFO * binfo; + MATCHMAP * mp, *bmp; + SLI_CT_REQUEST * CtReq; + ULP_BDE64 * bpl; + u32bit size; + PREG_HBA rh; + PPORT_ENTRY pe; + PREG_PORT_ATTRIBUTE pab; + PATTRIBUTE_BLOCK ab; + PATTRIBUTE_ENTRY ae; + uint32 id; + + binfo = &BINFO; + + /* fill in BDEs for command */ + /* Allocate buffer for command payload */ + if ((mp = (MATCHMAP * )fc_mem_get(binfo, MEM_BUF)) == 0) { + return(1); + } + + bmp = 0; + + /* Allocate buffer for Buffer ptr list */ + if ((bmp = (MATCHMAP * )fc_mem_get(binfo, MEM_BPL)) == 0) { + fc_mem_put(binfo, MEM_BUF, (uchar * )mp); + return(1); + } + /* FDMI Req */ + fc_log_printf_msg_vargs( binfo->fc_brd_no, + &fc_msgBlk0218, /* ptr to msg structure */ + fc_mes0218, /* ptr to msg */ + fc_msgBlk0218.msgPreambleStr, /* begin varargs */ + cmdcode, + binfo->fc_flag ); /* end varargs */ + CtReq = (SLI_CT_REQUEST * )mp->virt; + /* + * Initialize mp, 1024 bytes + */ + fc_bzero((void *)CtReq, FCELSSIZE); + + CtReq->RevisionId.bits.Revision = SLI_CT_REVISION; + CtReq->RevisionId.bits.InId = 0; + + CtReq->FsType = SLI_CT_MANAGEMENT_SERVICE; + CtReq->FsSubType = SLI_CT_FDMI_Subtypes; + size = 0; + + switch (cmdcode) { + case SLI_MGMT_RHBA : + { + fc_vpd_t * vp; + char * str; + uint32 i, j, incr; + uchar HWrev[8]; + + vp = &VPD; + + CtReq->CommandResponse.bits.CmdRsp = SWAP_DATA16(SLI_MGMT_RHBA); + CtReq->CommandResponse.bits.Size = 0; + rh = (PREG_HBA)&CtReq->un.PortID; + fc_bcopy((uchar * )&binfo->fc_sparam.portName, (uchar * )&rh->hi.PortName, + sizeof(NAME_TYPE)); + rh->rpl.EntryCnt = SWAP_DATA(1); /* One entry (port) per adapter */ + fc_bcopy((uchar * )&binfo->fc_sparam.portName, (uchar * )&rh->rpl.pe, + sizeof(NAME_TYPE)); + + /* point to the HBA attribute block */ + size = sizeof(NAME_TYPE) + FOURBYTES + sizeof(NAME_TYPE); + ab = (PATTRIBUTE_BLOCK)((uchar *)rh + size); + ab->EntryCnt = 0; + + /* Point to the begin of the first HBA attribute entry */ + /* #1 HBA attribute entry */ + size += FOURBYTES; + ae = (PATTRIBUTE_ENTRY)((uchar *)rh + size); + ae->ad.bits.AttrType = SWAP_DATA16(NODE_NAME); + ae->ad.bits.AttrLen = SWAP_DATA16(sizeof(NAME_TYPE)); + fc_bcopy((uchar * )&binfo->fc_sparam.nodeName, (uchar * )&ae->un.NodeName, + sizeof(NAME_TYPE)); + ab->EntryCnt++; + size += FOURBYTES + sizeof(NAME_TYPE); + + /* #2 HBA attribute entry */ + ae = (PATTRIBUTE_ENTRY)((uchar *)rh + size); + ae->ad.bits.AttrType = SWAP_DATA16(MANUFACTURER); + ae->ad.bits.AttrLen = SWAP_DATA16(24); + fc_bcopy("Emulex Network Systems", ae->un.Manufacturer, 22); + ab->EntryCnt++; + size += FOURBYTES + 24; + + /* #3 HBA attribute entry */ + ae = (PATTRIBUTE_ENTRY)((uchar *)rh + size); + ae->ad.bits.AttrType = SWAP_DATA16(SERIAL_NUMBER); + ae->ad.bits.AttrLen = SWAP_DATA16(32); + fc_bcopy(binfo->fc_SerialNumber, ae->un.SerialNumber, 32); + ab->EntryCnt++; + size += FOURBYTES + 32; + + /* #4 HBA attribute entry */ + id = fc_rdpci_32(p_dev_ctl, PCI_VENDOR_ID_REGISTER); + switch((id >> 16) & 0xffff) { + case PCI_DEVICE_ID_SUPERFLY: + if((vp->rev.biuRev == 1) || (vp->rev.biuRev == 2) || + (vp->rev.biuRev == 3)) { + ae = (PATTRIBUTE_ENTRY)((uchar *)rh + size); + ae->ad.bits.AttrType = SWAP_DATA16(MODEL); + ae->ad.bits.AttrLen = SWAP_DATA16(8); + fc_bcopy("LP7000", ae->un.Model, 6); + ab->EntryCnt++; + size += FOURBYTES + 8; + + /* #5 HBA attribute entry */ + ae = (PATTRIBUTE_ENTRY)((uchar *)rh + size); + ae->ad.bits.AttrType = SWAP_DATA16(MODEL_DESCRIPTION); + ae->ad.bits.AttrLen = SWAP_DATA16(64); + fc_bcopy("Emulex LightPulse LP7000 1 Gigabit PCI Fibre Channel Adapter", + ae->un.ModelDescription, 62); + ab->EntryCnt++; + size += FOURBYTES + 64; + } else { + ae = (PATTRIBUTE_ENTRY)((uchar *)rh + size); + ae->ad.bits.AttrType = SWAP_DATA16(MODEL); + ae->ad.bits.AttrLen = SWAP_DATA16(8); + fc_bcopy("LP7000E", ae->un.Model, 7); + ab->EntryCnt++; + size += FOURBYTES + 8; + + /* #5 HBA attribute entry */ + ae = (PATTRIBUTE_ENTRY)((uchar *)rh + size); + ae->ad.bits.AttrType = SWAP_DATA16(MODEL_DESCRIPTION); + ae->ad.bits.AttrLen = SWAP_DATA16(64); + fc_bcopy("Emulex LightPulse LP7000E 1 Gigabit PCI Fibre Channel Adapter", + ae->un.ModelDescription, 62); + ab->EntryCnt++; + size += FOURBYTES + 64; + } + break; + case PCI_DEVICE_ID_DRAGONFLY: + ae = (PATTRIBUTE_ENTRY)((uchar *)rh + size); + ae->ad.bits.AttrType = SWAP_DATA16(MODEL); + ae->ad.bits.AttrLen = SWAP_DATA16(8); + fc_bcopy("LP8000", ae->un.Model, 6); + ab->EntryCnt++; + size += FOURBYTES + 8; + + /* #5 HBA attribute entry */ + ae = (PATTRIBUTE_ENTRY)((uchar *)rh + size); + ae->ad.bits.AttrType = SWAP_DATA16(MODEL_DESCRIPTION); + ae->ad.bits.AttrLen = SWAP_DATA16(64); + fc_bcopy("Emulex LightPulse LP8000 1 Gigabit PCI Fibre Channel Adapter", + ae->un.ModelDescription, 62); + ab->EntryCnt++; + size += FOURBYTES + 64; + break; + case PCI_DEVICE_ID_CENTAUR: + if(FC_JEDEC_ID(vp->rev.biuRev) == CENTAUR_2G_JEDEC_ID) { + ae = (PATTRIBUTE_ENTRY)((uchar *)rh + size); + ae->ad.bits.AttrType = SWAP_DATA16(MODEL); + ae->ad.bits.AttrLen = SWAP_DATA16(8); + fc_bcopy("LP9002", ae->un.Model, 6); + ab->EntryCnt++; + size += FOURBYTES + 8; + + /* #5 HBA attribute entry */ + ae = (PATTRIBUTE_ENTRY)((uchar *)rh + size); + ae->ad.bits.AttrType = SWAP_DATA16(MODEL_DESCRIPTION); + ae->ad.bits.AttrLen = SWAP_DATA16(64); + fc_bcopy("Emulex LightPulse LP9002 2 Gigabit PCI Fibre Channel Adapter", + ae->un.ModelDescription, 62); + ab->EntryCnt++; + size += FOURBYTES + 64; + } else { + ae = (PATTRIBUTE_ENTRY)((uchar *)rh + size); + ae->ad.bits.AttrType = SWAP_DATA16(MODEL); + ae->ad.bits.AttrLen = SWAP_DATA16(8); + fc_bcopy("LP9000", ae->un.Model, 6); + ab->EntryCnt++; + size += FOURBYTES + 8; + + /* #5 HBA attribute entry */ + ae = (PATTRIBUTE_ENTRY)((uchar *)rh + size); + ae->ad.bits.AttrType = SWAP_DATA16(MODEL_DESCRIPTION); + ae->ad.bits.AttrLen = SWAP_DATA16(64); + fc_bcopy("Emulex LightPulse LP9000 1 Gigabit PCI Fibre Channel Adapter", + ae->un.ModelDescription, 62); + ab->EntryCnt++; + size += FOURBYTES + 64; + } + break; + case PCI_DEVICE_ID_PEGASUS: + ae = (PATTRIBUTE_ENTRY)((uchar *)rh + size); + ae->ad.bits.AttrType = SWAP_DATA16(MODEL); + ae->ad.bits.AttrLen = SWAP_DATA16(8); + fc_bcopy("LP9802", ae->un.Model, 6); + ab->EntryCnt++; + size += FOURBYTES + 8; + + /* #5 HBA attribute entry */ + ae = (PATTRIBUTE_ENTRY)((uchar *)rh + size); + ae->ad.bits.AttrType = SWAP_DATA16(MODEL_DESCRIPTION); + ae->ad.bits.AttrLen = SWAP_DATA16(64); + fc_bcopy("Emulex LightPulse LP9802 2 Gigabit PCI Fibre Channel Adapter", + ae->un.ModelDescription, 62); + ab->EntryCnt++; + size += FOURBYTES + 64; + break; + case PCI_DEVICE_ID_PFLY: + ae = (PATTRIBUTE_ENTRY)((uchar *)rh + size); + ae->ad.bits.AttrType = SWAP_DATA16(MODEL); + ae->ad.bits.AttrLen = SWAP_DATA16(8); + fc_bcopy("LP982", ae->un.Model, 5); + ab->EntryCnt++; + size += FOURBYTES + 8; + + /* #5 HBA attribute entry */ + ae = (PATTRIBUTE_ENTRY)((uchar *)rh + size); + ae->ad.bits.AttrType = SWAP_DATA16(MODEL_DESCRIPTION); + ae->ad.bits.AttrLen = SWAP_DATA16(64); + fc_bcopy("Emulex LightPulse LP982 2 Gigabit PCI Fibre Channel Adapter", + ae->un.ModelDescription, 62); + ab->EntryCnt++; + size += FOURBYTES + 64; + break; + } + + /* #6 HBA attribute entry */ + ae = (PATTRIBUTE_ENTRY)((uchar *)rh + size); + ae->ad.bits.AttrType = SWAP_DATA16(HARDWARE_VERSION); + ae->ad.bits.AttrLen = SWAP_DATA16(8); + /* Convert JEDEC ID to ascii for hardware version */ + incr = vp->rev.biuRev; + for(i=0;i<8;i++) { + j = (incr & 0xf); + if(j <= 9) + HWrev[7-i] = (char)((uchar)0x30 + (uchar)j); + else + HWrev[7-i] = (char)((uchar)0x61 + (uchar)(j-10)); + incr = (incr >> 4); + } + fc_bcopy((uchar *)HWrev, ae->un.HardwareVersion, 8); + ab->EntryCnt++; + size += FOURBYTES + 8; + + /* #7 HBA attribute entry */ + ae = (PATTRIBUTE_ENTRY)((uchar *)rh + size); + ae->ad.bits.AttrType = SWAP_DATA16(DRIVER_VERSION); + ae->ad.bits.AttrLen = SWAP_DATA16(16); + for (i=0; lpfc_release_version[i]; i++); + fc_bcopy((uchar *)lpfc_release_version, ae->un.DriverVersion, i); + ab->EntryCnt++; + size += FOURBYTES + 16; + + /* #8 HBA attribute entry */ + ae = (PATTRIBUTE_ENTRY)((uchar *)rh + size); + ae->ad.bits.AttrType = SWAP_DATA16(OPTION_ROM_VERSION); + ae->ad.bits.AttrLen = SWAP_DATA16(32); + fc_bcopy(binfo->fc_OptionROMVersion, ae->un.OptionROMVersion, 32); + ab->EntryCnt++; + size += FOURBYTES + 32; + + /* #9 HBA attribute entry */ + ae = (PATTRIBUTE_ENTRY)((uchar *)rh + size); + ae->ad.bits.AttrType = SWAP_DATA16(FIRMWARE_VERSION); + ae->ad.bits.AttrLen = SWAP_DATA16(32); + str = decode_firmware_rev(binfo, vp); + fc_bcopy((uchar *)str, ae->un.FirmwareVersion, 32); + ab->EntryCnt++; + size += FOURBYTES + 32; + + /* #10 HBA attribute entry */ + ae = (PATTRIBUTE_ENTRY)((uchar *)rh + size); + ae->ad.bits.AttrType = SWAP_DATA16(VENDOR_SPECIFIC); + ae->ad.bits.AttrLen = SWAP_DATA16(4); + id = SWAP_LONG(id); + id = (((SWAP_ALWAYS16(id >> 16)) << 16) | SWAP_ALWAYS16(id)); + ae->un.VendorSpecific = id; + ab->EntryCnt++; + size += FOURBYTES + 4; + + /* #11 HBA attribute entry */ + ae = (PATTRIBUTE_ENTRY)((uchar *)rh + size); + ae->ad.bits.AttrType = SWAP_DATA16(DRIVER_NAME); + ae->ad.bits.AttrLen = SWAP_DATA16(4); + fc_bcopy("lpfc", ae->un.DriverName, 4); + ab->EntryCnt++; + size += FOURBYTES + 4; + + + + ab->EntryCnt = SWAP_DATA(ab->EntryCnt); + /* Total size */ + size = GID_REQUEST_SZ - 4 + size; + } + break; + + case SLI_MGMT_RPRT : + { + fc_vpd_t * vp; + SERV_PARM * hsp; + + vp = &VPD; + + CtReq->CommandResponse.bits.CmdRsp = SWAP_DATA16(SLI_MGMT_RPRT); + CtReq->CommandResponse.bits.Size = 0; + pab = (PREG_PORT_ATTRIBUTE)&CtReq->un.PortID; + size = sizeof(NAME_TYPE) + sizeof(NAME_TYPE) + FOURBYTES; + fc_bcopy((uchar * )&binfo->fc_sparam.portName, (uchar * )&pab->HBA_PortName, + sizeof(NAME_TYPE)); + fc_bcopy((uchar * )&binfo->fc_sparam.portName, (uchar * )&pab->PortName, + sizeof(NAME_TYPE)); + pab->ab.EntryCnt = 0; + + /* #1 Port attribute entry */ + ae = (PATTRIBUTE_ENTRY)((uchar *)pab + size); + ae->ad.bits.AttrType = SWAP_DATA16(SUPPORTED_FC4_TYPES); + ae->ad.bits.AttrLen = SWAP_DATA16(8); + ae->un.SupportFC4Types[4] = 1; + pab->ab.EntryCnt++; + size += FOURBYTES + 8; + + /* #2 Port attribute entry */ + ae = (PATTRIBUTE_ENTRY)((uchar *)pab + size); + ae->ad.bits.AttrType = SWAP_DATA16(SUPPORTED_SPEED); + ae->ad.bits.AttrLen = SWAP_DATA16(4); + if(FC_JEDEC_ID(vp->rev.biuRev) == CENTAUR_2G_JEDEC_ID) + ae->un.SupportSpeed = HBA_PORTSPEED_2GBIT; + else + ae->un.SupportSpeed = HBA_PORTSPEED_1GBIT; + pab->ab.EntryCnt++; + size += FOURBYTES + 4; + + /* #3 Port attribute entry */ + ae = (PATTRIBUTE_ENTRY)((uchar *)pab + size); + ae->ad.bits.AttrType = SWAP_DATA16(PORT_SPEED); + ae->ad.bits.AttrLen = SWAP_DATA16(4); + if( binfo->fc_linkspeed == LA_2GHZ_LINK) + ae->un.PortSpeed = HBA_PORTSPEED_2GBIT; + else + ae->un.PortSpeed = HBA_PORTSPEED_1GBIT; + pab->ab.EntryCnt++; + size += FOURBYTES + 4; + + /* #4 Port attribute entry */ + ae = (PATTRIBUTE_ENTRY)((uchar *)pab + size); + ae->ad.bits.AttrType = SWAP_DATA16(MAX_FRAME_SIZE); + ae->ad.bits.AttrLen = SWAP_DATA16(4); + hsp = (SERV_PARM *)&binfo->fc_sparam; + ae->un.MaxFrameSize = (((uint32)hsp->cmn.bbRcvSizeMsb) << 8) | + (uint32)hsp->cmn.bbRcvSizeLsb; + pab->ab.EntryCnt++; + size += FOURBYTES + 4; + + /* #5 Port attribute entry */ + ae = (PATTRIBUTE_ENTRY)((uchar *)pab + size); + ae->ad.bits.AttrType = SWAP_DATA16(OS_DEVICE_NAME); + ae->ad.bits.AttrLen = SWAP_DATA16(4); + fc_bcopy("lpfc", (uchar * )&ae->un.DriverName, 4); + pab->ab.EntryCnt++; + size += FOURBYTES + 4; + + pab->ab.EntryCnt = SWAP_DATA(pab->ab.EntryCnt); + /* Total size */ + size = GID_REQUEST_SZ - 4 + size; + } + break; + + case SLI_MGMT_DHBA : + CtReq->CommandResponse.bits.CmdRsp = SWAP_DATA16(SLI_MGMT_DHBA); + CtReq->CommandResponse.bits.Size = 0; + pe = (PPORT_ENTRY)&CtReq->un.PortID; + fc_bcopy((uchar * )&binfo->fc_sparam.portName, (uchar * )&pe->PortName, + sizeof(NAME_TYPE)); + size = GID_REQUEST_SZ - 4 + sizeof(NAME_TYPE); + break; + + case SLI_MGMT_DPRT : + CtReq->CommandResponse.bits.CmdRsp = SWAP_DATA16(SLI_MGMT_DPRT); + CtReq->CommandResponse.bits.Size = 0; + pe = (PPORT_ENTRY)&CtReq->un.PortID; + fc_bcopy((uchar * )&binfo->fc_sparam.portName, (uchar * )&pe->PortName, + sizeof(NAME_TYPE)); + size = GID_REQUEST_SZ - 4 + sizeof(NAME_TYPE); + break; + } + + bpl = (ULP_BDE64 * )bmp->virt; + bpl->addrHigh = PCIMEM_LONG((uint32)putPaddrHigh(mp->phys)); + bpl->addrLow = PCIMEM_LONG((uint32)putPaddrLow(mp->phys)); + bpl->tus.f.bdeFlags = 0; + bpl->tus.f.bdeSize = size; + bpl->tus.w = PCIMEM_LONG(bpl->tus.w); + + + if(fc_ct_cmd(p_dev_ctl, mp, bmp, ndlp)) { + fc_mem_put(binfo, MEM_BUF, (uchar * )mp); + fc_mem_put(binfo, MEM_BPL, (uchar * )bmp); + } + return(0); +} /* End fc_ns_cmd */ + +/**************************************************/ +/** fc_fdmi_rsp **/ +/** **/ +/** Description: **/ +/** Process Rsp from HBA Management Server **/ +/** SLI_MGMT_RHBA **/ +/** SLI_MGMT_RPRT **/ +/** SLI_MGMT_DHBA **/ +/** SLI_MGMT_DPRT **/ +/** **/ +/** Returns: **/ +/** **/ +/**************************************************/ +_static_ void +fc_fdmi_rsp( +fc_dev_ctl_t *p_dev_ctl, +MATCHMAP *mp, +MATCHMAP *rsp_mp) + +{ + FC_BRD_INFO * binfo; + SLI_CT_REQUEST * Cmd; + SLI_CT_REQUEST * Rsp; + NODELIST * ndlp; + ushort fdmi_cmd; + ushort fdmi_rsp; + int rc; + + binfo = &BINFO; + + ndlp = (NODELIST *)mp->fc_mptr; + Cmd = (SLI_CT_REQUEST *)mp->virt; + Rsp = (SLI_CT_REQUEST *)rsp_mp->virt; + + fdmi_rsp = Rsp->CommandResponse.bits.CmdRsp; + + fdmi_cmd = Cmd->CommandResponse.bits.CmdRsp; + rc = 1; + + switch (SWAP_DATA16(fdmi_cmd)) { + case SLI_MGMT_RHBA : + rc = fc_fdmi_cmd(p_dev_ctl, ndlp, SLI_MGMT_RPRT); + break; + + case SLI_MGMT_RPRT : + break; + + case SLI_MGMT_DHBA : + rc = fc_fdmi_cmd(p_dev_ctl, ndlp, SLI_MGMT_RHBA); + break; + + case SLI_MGMT_DPRT : + rc = fc_fdmi_cmd(p_dev_ctl, ndlp, SLI_MGMT_DHBA); + break; + } + + if (rc) { + /* FDMI rsp failed */ + fc_log_printf_msg_vargs( binfo->fc_brd_no, + &fc_msgBlk0251, /* ptr to msg structure */ + fc_mes0251, /* ptr to msg */ + fc_msgBlk0251.msgPreambleStr, /* begin varargs */ + SWAP_DATA16(fdmi_cmd) ); /* end varargs */ + } +} /* fc_fdmi_rsp */ + + +/*****************************************************************************/ +/* + * NAME: fc_plogi_put + * + * FUNCTION: put iocb cmd onto the iocb plogi queue. + * + * EXECUTION ENVIRONMENT: process and interrupt level. + * + * NOTES: + * + * CALLED FROM: + * issue_els_cmd + * + * INPUT: + * binfo - pointer to the device info area + * iocbq - pointer to iocb queue entry + * + * RETURNS: + * NULL - command queued + */ +/*****************************************************************************/ +_static_ void +fc_plogi_put( +FC_BRD_INFO *binfo, +IOCBQ *iocbq) /* pointer to iocbq entry */ +{ + if (binfo->fc_plogi.q_first) { + /* queue command to end of list */ + ((IOCBQ * )binfo->fc_plogi.q_last)->q = (uchar * )iocbq; + binfo->fc_plogi.q_last = (uchar * )iocbq; + } else { + /* add command to empty list */ + binfo->fc_plogi.q_first = (uchar * )iocbq; + binfo->fc_plogi.q_last = (uchar * )iocbq; + } + + iocbq->q = NULL; + binfo->fc_plogi.q_cnt++; + binfo->fc_flag |= FC_DELAY_NSLOGI; + return; + +} /* End fc_plogi_put */ + + +/*****************************************************************************/ +/* + * NAME: fc_plogi_get + * + * FUNCTION: get a iocb command from iocb plogi command queue + * + * EXECUTION ENVIRONMENT: interrupt level. + * + * NOTES: + * + * CALLED FROM: + * handle_mb_event + * + * INPUT: + * binfo - pointer to the device info area + * + * RETURNS: + * NULL - no match found + * iocb pointer - pointer to a iocb command + */ +/*****************************************************************************/ +_static_ IOCBQ * +fc_plogi_get( +FC_BRD_INFO *binfo) +{ + IOCBQ * p_first = NULL; + + if (binfo->fc_plogi.q_first) { + p_first = (IOCBQ * )binfo->fc_plogi.q_first; + if ((binfo->fc_plogi.q_first = p_first->q) == 0) { + binfo->fc_plogi.q_last = 0; + binfo->fc_flag &= ~FC_DELAY_NSLOGI; + } + p_first->q = NULL; + binfo->fc_plogi.q_cnt--; + } + return(p_first); + +} /* End fc_plogi_get */ + diff -purN -X /home/mbligh/.diff.exclude 350-autoswap/drivers/scsi/lpfc/fcfgparm.h 370-emulex/drivers/scsi/lpfc/fcfgparm.h --- 350-autoswap/drivers/scsi/lpfc/fcfgparm.h 1969-12-31 16:00:00.000000000 -0800 +++ 370-emulex/drivers/scsi/lpfc/fcfgparm.h 2004-02-28 11:20:03.000000000 -0800 @@ -0,0 +1,341 @@ +/******************************************************************* + * This file is part of the Emulex Linux Device Driver for * + * Enterprise Fibre Channel Host Bus Adapters. * + * Refer to the README file included with this package for * + * driver version and adapter support. * + * Copyright (C) 2003 Emulex Corporation. * + * www.emulex.com * + * * + * This program is free software; you can redistribute it and/or * + * modify it under the terms of the GNU General Public License * + * as published by the Free Software Foundation; either version 2 * + * of the License, or (at your option) any later version. * + * * + * This program is distributed in the hope that it will be useful, * + * but WITHOUT ANY WARRANTY; without even the implied warranty of * + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * + * GNU General Public License for more details, a copy of which * + * can be found in the file COPYING included with this package. * + *******************************************************************/ + +#ifndef _H_CFGPARAM +#define _H_CFGPARAM + +#define LPFC_DFT_POST_IP_BUF 128 +#define LPFC_MIN_POST_IP_BUF 64 +#define LPFC_MAX_POST_IP_BUF 1024 +#define LPFC_DFT_XMT_QUE_SIZE 256 +#define LPFC_MIN_XMT_QUE_SIZE 128 +#define LPFC_MAX_XMT_QUE_SIZE 10240 +#define LPFC_DFT_NUM_IOCBS 1024 +#define LPFC_MIN_NUM_IOCBS 128 +#define LPFC_MAX_NUM_IOCBS 10240 +#define LPFC_DFT_NUM_BUFS 1024 +#define LPFC_MIN_NUM_BUFS 64 +#define LPFC_MAX_NUM_BUFS 4096 +#define LPFC_DFT_NUM_NODES 510 +#define LPFC_MIN_NUM_NODES 64 +#define LPFC_MAX_NUM_NODES 4096 +#define LPFC_DFT_TOPOLOGY 0 +#define LPFC_DFT_FC_CLASS 3 + +#define LPFC_DFT_NO_DEVICE_DELAY 1 /* 1 sec */ +#define LPFC_MAX_NO_DEVICE_DELAY 30 /* 30 sec */ +#define LPFC_DFT_FABRIC_TIMEOUT 0 +#define LPFC_MAX_FABRIC_TIMEOUT 255 /* 255 sec */ +#define LPFC_DFT_LNKDWN_TIMEOUT 30 +#define LPFC_MAX_LNKDWN_TIMEOUT 255 /* 255 sec */ +#define LPFC_DFT_NODEV_TIMEOUT 0 +#define LPFC_MAX_NODEV_TIMEOUT 255 /* 255 sec */ +#define LPFC_DFT_RSCN_NS_DELAY 0 +#define LPFC_MAX_RSCN_NS_DELAY 255 /* 255 sec */ + +#define LPFC_MAX_TGT_Q_DEPTH 10240 /* max cmds allowed per tgt */ +#define LPFC_DFT_TGT_Q_DEPTH 0 /* default max cmds per tgt */ + +#define LPFC_MAX_LUN_Q_DEPTH 128 /* max cmds to allow per lun */ +#define LPFC_DFT_LUN_Q_DEPTH 30 /* default max cmds per lun */ + +#define LPFC_MAX_DQFULL_THROTTLE 1 /* Boolean (max value) */ + +#define CFG_INTR_ACK 0 /* intr-ack */ +#define CFG_LOG_VERBOSE 1 /* log-verbose */ +#define CFG_LOG_ONLY 2 /* log-only */ +#define CFG_IDENTIFY_SELF 3 /* identify-self */ +#define CFG_NUM_IOCBS 4 /* num-iocbs */ +#define CFG_NUM_BUFS 5 /* num-bufs */ +#define CFG_FCP_ON 6 /* fcp-on */ +#define CFG_DEVICE_REPORT 7 /* device-report */ +#define CFG_AUTOMAP 8 /* automap */ +#define CFG_DFT_TGT_Q_DEPTH 9 /* tgt_queue_depth */ +#define CFG_DFT_LUN_Q_DEPTH 10 /* lun_queue_depth */ +#define CFG_FIRST_CHECK 11 /* first-check */ +#define CFG_FCPFABRIC_TMO 12 /* fcpfabric-tmo */ +#define CFG_FCP_CLASS 13 /* fcp-class */ +#define CFG_USE_ADISC 14 /* use-adisc */ +#define CFG_NO_DEVICE_DELAY 15 /* no-device-delay */ +#define CFG_NETWORK_ON 16 /* network-on */ +#define CFG_POST_IP_BUF 17 /* post-ip-buf */ +#define CFG_XMT_Q_SIZE 18 /* xmt-que-size */ +#define CFG_IP_CLASS 19 /* ip-class */ +#define CFG_ACK0 20 /* ack0 */ +#define CFG_TOPOLOGY 21 /* topology */ +#define CFG_SCAN_DOWN 22 /* scan-down */ +#define CFG_LINKDOWN_TMO 23 /* linkdown-tmo */ +#define CFG_USE_LOMEM 24 /* use-lomempages */ +#define CFG_ZONE_RSCN 25 /* zone-rscn */ +#define CFG_HOLDIO 26 /* nodev-holdio */ +#define CFG_DELAY_RSP_ERR 27 /* delay-rsp-err */ +#define CFG_CHK_COND_ERR 28 /* check-cond-err */ +#define CFG_NODEV_TMO 29 /* nodev-tmo */ +#define CFG_DQFULL_THROTTLE 30 /* dqfull-throttle */ +#define CFG_LINK_SPEED 31 /* link-speed NEW_FETURE */ +#define CFG_QFULL_RSP_ERR 32 /* qfull-rsp-err */ +#define CFG_DQFULL_THROTTLE_UP_TIME 33 /* dqfull-throttle-up-time */ +#define CFG_DQFULL_THROTTLE_UP_INC 34 /* dqfull-throttle-up-inc */ +#define CFG_NUM_NODES 35 /* num-nodes */ +#define CFG_CR_DELAY 36 /* cr-delay */ +#define CFG_CR_COUNT 37 /* cr-count */ +#define NUM_CFG_PARAM 38 + +#ifdef DEF_ICFG +_static_ iCfgParam icfgparam[NUM_CFG_PARAM] = { + + /* general driver parameters */ + { "intr-ack", + 0, 1, TRUE, 0, + (ushort)0, + (ushort)CFG_DYNAMIC, + "Claim interrupt even if no work discovered" }, + + { "log-verbose", + 0, 0xffff, FALSE, 0, + (ushort)0, + (ushort)CFG_DYNAMIC, + "Verbose logging mask" }, + + { "log-only", + 0, 2, TRUE, 0, + (ushort)0, + (ushort)CFG_DYNAMIC, + "Log messages only go to system logger, not console" }, + + { "identify-self", + 0, 2, TRUE, 0, + (ushort)0, + (ushort)CFG_REBOOT, + "Driver startup will report driver version and release information" }, + + { "num-iocbs", + LPFC_MIN_NUM_IOCBS, LPFC_MAX_NUM_IOCBS, LPFC_DFT_NUM_IOCBS, 0, + (ushort)0, + (ushort)CFG_RESTART, + "Number of outstanding IOCBs driver can queue to adapter" }, + + { "num-bufs", + LPFC_MIN_NUM_BUFS, LPFC_MAX_NUM_BUFS, LPFC_DFT_NUM_BUFS, 0, + (ushort)0, + (ushort)CFG_RESTART, + "Number of buffers driver uses for ELS commands and Buffer Pointer Lists." }, + + /* FCP specific parameters */ + { "fcp-on", + 0, 1, TRUE, 0, + (ushort)0, + (ushort)CFG_REBOOT, + "Enable FCP processing" }, + + { "device-report", + 0, 1, TRUE, 0, + (ushort)0, + (ushort)CFG_RESTART, + "Driver will report FCP devices as it finds them" }, + + { "automap", + 0, 3, 2, 0, + (ushort)0, + (ushort)CFG_RESTART, + "Automatically bind FCP devices as they are discovered" }, + + { "tgt-queue-depth", + 0, LPFC_MAX_TGT_Q_DEPTH, LPFC_DFT_TGT_Q_DEPTH, 0, + (ushort)0, + (ushort)CFG_RESTART, + "Max number of FCP commands we can queue to a specific target" }, + + { "lun-queue-depth", + 0, LPFC_MAX_LUN_Q_DEPTH, LPFC_DFT_LUN_Q_DEPTH, 0, + (ushort)0, + (ushort)CFG_RESTART, + "Max number of FCP commands we can queue to a specific LUN" }, + + { "first-check", + 0, 1, + FALSE, + 0, + (ushort)0, + (ushort)CFG_DYNAMIC, + "Retry the first 29xx check condition for FCP devices during discovery" }, + + { "fcpfabric-tmo", + 0, LPFC_MAX_FABRIC_TIMEOUT, LPFC_DFT_FABRIC_TIMEOUT, 0, + (ushort)0, + (ushort)CFG_DYNAMIC, + "Extra FCP command timeout when connected to a fabric" }, + + { "fcp-class", + 2, 3, LPFC_DFT_FC_CLASS, 0, + (ushort)0, + (ushort)CFG_DYNAMIC, + "Select Fibre Channel class of service for FCP sequences" }, + + { "use-adisc", + 0, 1, FALSE, 0, + (ushort)0, + (ushort)CFG_DYNAMIC, + "Use ADISC on rediscovery to authenticate FCP devices" }, + + { "no-device-delay", + 0, LPFC_MAX_NO_DEVICE_DELAY, LPFC_DFT_NO_DEVICE_DELAY, 0, + (ushort)0, + (ushort)CFG_DYNAMIC, + "No FCP device failed I/O sec delay" }, + + /* IP specific parameters */ + { "network-on", + 0, 1, FALSE, 0, + (ushort)0, + (ushort)CFG_REBOOT, + "Enable IP processing" }, + + { "post-ip-buf", + LPFC_MIN_POST_IP_BUF, LPFC_MAX_POST_IP_BUF, LPFC_DFT_POST_IP_BUF, 0, + (ushort)0, + (ushort)CFG_RESTART, + "Number of IP buffers to post to adapter" }, + + { "xmt-que-size", + LPFC_MIN_XMT_QUE_SIZE, LPFC_MAX_XMT_QUE_SIZE, LPFC_DFT_XMT_QUE_SIZE, 0, + (ushort)0, + (ushort)CFG_RESTART, + "Number of outstanding IP cmds for an adapter" }, + + { "ip-class", + 2, 3, LPFC_DFT_FC_CLASS, 0, + (ushort)0, + (ushort)CFG_DYNAMIC, + "Select Fibre Channel class of service for IP sequences" }, + + /* Fibre Channel specific parameters */ + { "ack0", + 0, 1, FALSE, 0, + (ushort)0, + (ushort)CFG_RESTART, + "Enable ACK0 support" }, + + { "topology", + 0, 6, LPFC_DFT_TOPOLOGY, 0, + (ushort)0, + (ushort)CFG_RESTART, + "Select Fibre Channel topology" }, + + { "scan-down", + 0, 2, 2, 0, + (ushort)0, + (ushort)CFG_DYNAMIC, + "Start scanning for devices from highest ALPA to lowest" }, + + { "linkdown-tmo", + 0, LPFC_MAX_LNKDWN_TIMEOUT, LPFC_DFT_LNKDWN_TIMEOUT, 0, + (ushort)0, + (ushort)CFG_DYNAMIC, + "Seconds driver will wait before deciding link is really down" }, + + { "use-lomempages", + 0, 1, FALSE, 0, + (ushort)0, + (ushort)CFG_RESTART, + "Use low memory for adapter DMA buffers" }, + + { "zone-rscn", + 0, 1, FALSE, 0, + (ushort)0, + (ushort)CFG_DYNAMIC, + "Force RSCNs to always check NameServer for N_Port IDs" }, + + { "nodev-holdio", + 0, 1, FALSE, 0, + (ushort)0, + (ushort)CFG_DYNAMIC, + "Hold I/O errors if device disappears " }, + + { "delay-rsp-err", + 0, 1, FALSE, 0, + (ushort)0, + (ushort)CFG_DYNAMIC, + "Delay FCP error return for FCP RSP error and Check Condition" }, + + { "check-cond-err", + 0, 1, FALSE, 0, + (ushort)0, + (ushort)CFG_DYNAMIC, + "Treat special Check Conditions as a FCP error" }, + + { "nodev-tmo", + 0, LPFC_MAX_NODEV_TIMEOUT, LPFC_DFT_NODEV_TIMEOUT, 0, + (ushort)0, + (ushort)CFG_DYNAMIC, + "Seconds driver will hold I/O waiting for a device to come back" }, + + { "dqfull-throttle", + 0, 1, 1, 0, + (ushort)0, + (ushort)CFG_DYNAMIC, + "Decrement LUN throttle on a queue full condition" }, + + { "link-speed", + 0, 2, 0, 0, + (ushort)0, + (ushort)CFG_RESTART, + "Select link speed" }, + + { "qfull-rsp-err", + 0, 1, FALSE, 0, + (ushort)0, + (ushort)CFG_DYNAMIC, + "Return BUSY (default) or TERMINATED as SCSI status on a queue full condition" }, + + { "dqfull-throttle-up-time", + 0, 30, 1, 0, + (ushort)0, + (ushort)CFG_RESTART, + "When to increment the current Q depth " }, + + { "dqfull-throttle-up-inc", + 0, LPFC_MAX_LUN_Q_DEPTH, 1, 0, + (ushort)0, + (ushort)CFG_RESTART, + "Increment the current Q depth by dqfull-throttle-up-inc" }, + + { "num-nodes", + LPFC_MIN_NUM_NODES, LPFC_MAX_NUM_NODES, LPFC_DFT_NUM_NODES, 0, + (ushort)0, + (ushort)CFG_RESTART, + "Number of fibre channel nodes (NPorts) the driver will support." }, + + { "cr-delay", + 0, 63, 0, 0, + (ushort)0, + (ushort)CFG_RESTART, + "A count of milliseconds after which an interrupt response is generated" }, + + { "cr-count", + 1, 255, 0, 0, + (ushort)0, + (ushort)CFG_RESTART, + "A count of I/O completions after which an interrupt response is generated" }, + + }; +#endif /* DEF_ICFG */ + +#endif /* _H_CFGPARAM */ diff -purN -X /home/mbligh/.diff.exclude 350-autoswap/drivers/scsi/lpfc/fcmboxb.c 370-emulex/drivers/scsi/lpfc/fcmboxb.c --- 350-autoswap/drivers/scsi/lpfc/fcmboxb.c 1969-12-31 16:00:00.000000000 -0800 +++ 370-emulex/drivers/scsi/lpfc/fcmboxb.c 2004-02-28 11:20:03.000000000 -0800 @@ -0,0 +1,1013 @@ +/******************************************************************* + * This file is part of the Emulex Linux Device Driver for * + * Enterprise Fibre Channel Host Bus Adapters. * + * Refer to the README file included with this package for * + * driver version and adapter support. * + * Copyright (C) 2003 Emulex Corporation. * + * www.emulex.com * + * * + * This program is free software; you can redistribute it and/or * + * modify it under the terms of the GNU General Public License * + * as published by the Free Software Foundation; either version 2 * + * of the License, or (at your option) any later version. * + * * + * This program is distributed in the hope that it will be useful, * + * but WITHOUT ANY WARRANTY; without even the implied warranty of * + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * + * GNU General Public License for more details, a copy of which * + * can be found in the file COPYING included with this package. * + *******************************************************************/ + +#include "fc_os.h" + +#include "fc_hw.h" +#include "fc.h" + +#include "fcdiag.h" +#include "fcfgparm.h" +#include "fcmsg.h" +#include "fc_crtn.h" +#include "fc_ertn.h" + +extern fc_dd_ctl_t DD_CTL; +extern iCfgParam icfgparam[]; + +/* Routine Declaration - Local */ +/* There currently are no local routine declarations */ +/* End Routine Declaration - Local */ + + +/**********************************************/ +/** fc_restart Issue a RESTART **/ +/** mailbox command **/ +/**********************************************/ +_static_ void +fc_restart( +FC_BRD_INFO *binfo, +MAILBOX *mb, +int doit) +{ + void *ioa; + MAILBOX * mbox; + fc_dev_ctl_t *p_dev_ctl; + + fc_bzero((void *)mb, sizeof(MAILBOXQ)); + mb->mbxCommand = MBX_RESTART; + mb->mbxHc = OWN_CHIP; + mb->mbxOwner = OWN_HOST; + + if (doit) { + /* use REAL SLIM !!! */ + p_dev_ctl = (fc_dev_ctl_t *)(binfo->fc_p_dev_ctl); + binfo->fc_mboxaddr = 0; + binfo->fc_flag &= ~FC_SLI2; + + ioa = (void *)FC_MAP_MEM(&binfo->fc_iomap_mem); /* map in SLIM */ + mbox = FC_MAILBOX(binfo, ioa); + WRITE_SLIM_COPY(binfo, (uint32 *)&mb->un.varWords, (uint32 *)&mbox->un.varWords, + (MAILBOX_CMD_WSIZE - 1)); + FC_UNMAP_MEMIO(ioa); + } + return; +} /* End fc_restart */ + + +/**********************************************/ +/** fc_dump_mem Issue a DUMP MEMORY **/ +/** mailbox command **/ +/**********************************************/ +_static_ void +fc_dump_mem( +FC_BRD_INFO *binfo, +MAILBOX *mb) +{ + /* Setup to dump VPD region */ + fc_bzero((void *)mb, sizeof(MAILBOXQ)); + mb->mbxCommand = MBX_DUMP_MEMORY; + mb->un.varDmp.cv = 1; + mb->un.varDmp.type = DMP_NV_PARAMS; + mb->un.varDmp.region_id = DMP_REGION_VPD; + mb->un.varDmp.word_cnt = (DMP_VPD_SIZE / sizeof(uint32)); + + mb->un.varDmp.co = 0; + mb->un.varDmp.resp_offset = 0; + mb->mbxOwner = OWN_HOST; + return; +} /* End fc_dump_mem */ + + +/**********************************************/ +/** fc_read_nv Issue a READ NVPARAM **/ +/** mailbox command **/ +/**********************************************/ +_static_ void +fc_read_nv( +FC_BRD_INFO *binfo, +MAILBOX *mb) +{ + fc_bzero((void *)mb, sizeof(MAILBOXQ)); + mb->mbxCommand = MBX_READ_NV; + mb->mbxOwner = OWN_HOST; + return; +} /* End fc_read_nv */ + +/**********************************************/ +/** fc_read_rev Issue a READ REV **/ +/** mailbox command **/ +/**********************************************/ +_static_ void +fc_read_rev( +FC_BRD_INFO *binfo, +MAILBOX *mb) +{ + fc_bzero((void *)mb, sizeof(MAILBOXQ)); + mb->un.varRdRev.cv = 1; + mb->mbxCommand = MBX_READ_REV; + mb->mbxOwner = OWN_HOST; + return; +} /* End fc_read_rev */ + +/**********************************************/ +/** fc_runBIUdiag Issue a RUN_BIU_DIAG **/ +/** mailbox command **/ +/**********************************************/ +_static_ int +fc_runBIUdiag( +FC_BRD_INFO *binfo, +MAILBOX *mb, +uchar *in, +uchar *out) +{ + fc_bzero((void *)mb, sizeof(MAILBOXQ)); + + if (binfo->fc_flag & FC_SLI2) { + mb->mbxCommand = MBX_RUN_BIU_DIAG64; + mb->un.varBIUdiag.un.s2.xmit_bde64.tus.f.bdeSize = FCELSSIZE; + mb->un.varBIUdiag.un.s2.xmit_bde64.addrHigh = (uint32)putPaddrHigh(in); + mb->un.varBIUdiag.un.s2.xmit_bde64.addrLow = (uint32)putPaddrLow(in); + mb->un.varBIUdiag.un.s2.rcv_bde64.tus.f.bdeSize = FCELSSIZE; + mb->un.varBIUdiag.un.s2.rcv_bde64.addrHigh = (uint32)putPaddrHigh(out); + mb->un.varBIUdiag.un.s2.rcv_bde64.addrLow = (uint32)putPaddrLow(out); + } else { + mb->mbxCommand = MBX_RUN_BIU_DIAG; + mb->un.varBIUdiag.un.s1.xmit_bde.bdeSize = FCELSSIZE; + mb->un.varBIUdiag.un.s1.xmit_bde.bdeAddress = (uint32)putPaddrLow(in); + mb->un.varBIUdiag.un.s1.rcv_bde.bdeSize = FCELSSIZE; + mb->un.varBIUdiag.un.s1.rcv_bde.bdeAddress = (uint32)putPaddrLow(out); + } + + mb->mbxOwner = OWN_HOST; + return(0); +} /* End fc_runBIUdiag */ + + +/**********************************************/ +/** fc_read_la Issue a READ LA **/ +/** mailbox command **/ +/**********************************************/ +_static_ int +fc_read_la( +fc_dev_ctl_t *p_dev_ctl, +MAILBOX *mb) +{ + FC_BRD_INFO * binfo; + MATCHMAP * mp; + + binfo = &BINFO; + fc_bzero((void *)mb, sizeof(MAILBOXQ)); + + if ((mp = (MATCHMAP * )fc_mem_get(binfo, MEM_BUF)) == 0) { + + if (binfo->fc_flag & FC_SLI2) + mb->mbxCommand = MBX_READ_LA64; + else + mb->mbxCommand = MBX_READ_LA; + /* READ_LA: no buffers */ + fc_log_printf_msg_vargs( binfo->fc_brd_no, + &fc_msgBlk0300, /* ptr to msg structure */ + fc_mes0300, /* ptr to msg */ + fc_msgBlk0300.msgPreambleStr); /* begin & end varargs */ + return(1); + } + + if (binfo->fc_flag & FC_SLI2) { + mb->mbxCommand = MBX_READ_LA64; + mb->un.varReadLA.un.lilpBde64.tus.f.bdeSize = 128; + mb->un.varReadLA.un.lilpBde64.addrHigh = (uint32)putPaddrHigh(mp->phys); + mb->un.varReadLA.un.lilpBde64.addrLow = (uint32)putPaddrLow(mp->phys); + } else { + mb->mbxCommand = MBX_READ_LA; + mb->un.varReadLA.un.lilpBde.bdeSize = 128; + mb->un.varReadLA.un.lilpBde.bdeAddress = (uint32)putPaddrLow(mp->phys); + } + + /* save address for completion */ + ((MAILBOXQ * )mb)->bp = (uchar * )mp; + + mb->mbxOwner = OWN_HOST; + return(0); +} /* End fc_read_la */ + + +/**********************************************/ +/** fc_clear_la Issue a CLEAR LA **/ +/** mailbox command **/ +/**********************************************/ +_static_ void +fc_clear_la( +FC_BRD_INFO *binfo, +MAILBOX *mb) +{ + fc_bzero((void *)mb, sizeof(MAILBOXQ)); + mb->un.varClearLA.eventTag = binfo->fc_eventTag; + mb->mbxCommand = MBX_CLEAR_LA; + mb->mbxOwner = OWN_HOST; + return; +} /* End fc_clear_la */ + + +/**********************************************/ +/** fc_read_status Issue a READ STATUS **/ +/** mailbox command **/ +/**********************************************/ +_static_ void +fc_read_status( +FC_BRD_INFO *binfo, +MAILBOX *mb) +{ + fc_bzero((void *)mb, sizeof(MAILBOXQ)); + mb->mbxCommand = MBX_READ_STATUS; + mb->mbxOwner = OWN_HOST; + return; +} /* End fc_read_status */ + +/**********************************************/ +/** fc_read_lnk_stat Issue a LINK STATUS **/ +/** mailbox command **/ +/**********************************************/ +_static_ void +fc_read_lnk_stat( +FC_BRD_INFO *binfo, +MAILBOX *mb) +{ + fc_bzero((void *)mb, sizeof(MAILBOXQ)); + mb->mbxCommand = MBX_READ_LNK_STAT; + mb->mbxOwner = OWN_HOST; + return; +} /* End fc_read_lnk_stat */ + + +/**************************************************/ +/** fc_config_ring Issue a CONFIG RING **/ +/** mailbox command **/ +/**************************************************/ +_static_ void +fc_config_ring( +FC_BRD_INFO *binfo, +int ring, +int profile, +MAILBOX *mb) +{ + int i; + int j; + + fc_bzero((void *)mb, sizeof(MAILBOXQ)); + mb->un.varCfgRing.ring = ring; + mb->un.varCfgRing.profile = profile; + mb->un.varCfgRing.maxOrigXchg = 0; + mb->un.varCfgRing.maxRespXchg = 0; + mb->un.varCfgRing.recvNotify = 1; + mb->un.varCfgRing.numMask = binfo->fc_nummask[ring]; + + j = 0; + for (i = 0; i < ring; i++) + j += binfo->fc_nummask[i]; + + for (i = 0; i < binfo->fc_nummask[ring]; i++) { + mb->un.varCfgRing.rrRegs[i].rval = binfo->fc_rval[j + i]; + if (mb->un.varCfgRing.rrRegs[i].rval != FC_ELS_REQ) /* ELS request */ + mb->un.varCfgRing.rrRegs[i].rmask = 0xff; + else + mb->un.varCfgRing.rrRegs[i].rmask = 0xfe; + mb->un.varCfgRing.rrRegs[i].tval = binfo->fc_tval[j + i]; + mb->un.varCfgRing.rrRegs[i].tmask = 0xff; + } + + mb->mbxCommand = MBX_CONFIG_RING; + mb->mbxOwner = OWN_HOST; + return; +} /* End fc_config_ring */ + + +/**************************************************/ +/** fc_config_link Issue a CONFIG LINK **/ +/** mailbox command **/ +/**************************************************/ +_static_ void +fc_config_link( +fc_dev_ctl_t *p_dev_ctl, +MAILBOX *mb) +{ + FC_BRD_INFO * binfo; + iCfgParam * clp; + + binfo = &BINFO; + clp = DD_CTL.p_config[binfo->fc_brd_no]; + fc_bzero((void *)mb, sizeof(MAILBOXQ)); + + if(clp[CFG_CR_DELAY].a_current) { + mb->un.varCfgLnk.cr = 1; + mb->un.varCfgLnk.ci = 1; + mb->un.varCfgLnk.cr_delay = clp[CFG_CR_DELAY].a_current; + mb->un.varCfgLnk.cr_count = clp[CFG_CR_COUNT].a_current; + } + + mb->un.varCfgLnk.myId = binfo->fc_myDID; + mb->un.varCfgLnk.edtov = binfo->fc_edtov; + mb->un.varCfgLnk.arbtov = binfo->fc_arbtov; + mb->un.varCfgLnk.ratov = binfo->fc_ratov; + mb->un.varCfgLnk.rttov = binfo->fc_rttov; + mb->un.varCfgLnk.altov = binfo->fc_altov; + mb->un.varCfgLnk.crtov = binfo->fc_crtov; + mb->un.varCfgLnk.citov = binfo->fc_citov; + if(clp[CFG_ACK0].a_current) + mb->un.varCfgLnk.ack0_enable = 1; + + mb->mbxCommand = MBX_CONFIG_LINK; + mb->mbxOwner = OWN_HOST; + return; +} /* End fc_config_link */ + + +/**********************************************/ +/** fc_init_link Issue an INIT LINK **/ +/** mailbox command **/ +/**********************************************/ +_static_ void +fc_init_link( +FC_BRD_INFO *binfo, +MAILBOX *mb, +uint32 topology, +uint32 linkspeed) +{ + iCfgParam * clp; + fc_vpd_t * vpd; + + clp = DD_CTL.p_config[binfo->fc_brd_no]; + fc_bzero((void *)mb, sizeof(MAILBOXQ)); + + switch (topology) { + case FLAGS_TOPOLOGY_MODE_LOOP_PT: + mb->un.varInitLnk.link_flags = FLAGS_TOPOLOGY_MODE_LOOP; + mb->un.varInitLnk.link_flags |= FLAGS_TOPOLOGY_FAILOVER; + break; + case FLAGS_TOPOLOGY_MODE_PT_PT: + mb->un.varInitLnk.link_flags = FLAGS_TOPOLOGY_MODE_PT_PT; + break; + case FLAGS_TOPOLOGY_MODE_LOOP: + mb->un.varInitLnk.link_flags = FLAGS_TOPOLOGY_MODE_LOOP; + break; + case FLAGS_TOPOLOGY_MODE_PT_LOOP: + mb->un.varInitLnk.link_flags = FLAGS_TOPOLOGY_MODE_PT_PT; + mb->un.varInitLnk.link_flags |= FLAGS_TOPOLOGY_FAILOVER; + break; + } + + vpd = &((fc_dev_ctl_t *)(binfo->fc_p_dev_ctl))->vpd; + if (binfo->fc_flag & FC_2G_CAPABLE) { + if ((vpd->rev.feaLevelHigh >= 0x02) && (linkspeed > 0)) { + mb->un.varInitLnk.link_flags |= FLAGS_LINK_SPEED; + mb->un.varInitLnk.link_speed = linkspeed; + } + } + + mb->mbxCommand = (volatile uchar)MBX_INIT_LINK; + mb->mbxOwner = OWN_HOST; + mb->un.varInitLnk.fabric_AL_PA = binfo->fc_pref_ALPA; + return; +} /* End fc_init_link */ + + +/**********************************************/ +/** fc_down_link Issue a DOWN LINK **/ +/** mailbox command **/ +/**********************************************/ +_static_ void +fc_down_link( +FC_BRD_INFO *binfo, +MAILBOX *mb) +{ + fc_bzero((void *)mb, sizeof(MAILBOXQ)); + + mb->mbxCommand = MBX_DOWN_LINK; + mb->mbxOwner = OWN_HOST; + return; +} + + +/**********************************************/ +/** fc_read_sparam Issue a READ SPARAM **/ +/** mailbox command **/ +/**********************************************/ +_static_ int +fc_read_sparam( +fc_dev_ctl_t *p_dev_ctl, +MAILBOX *mb) +{ + FC_BRD_INFO * binfo; + MATCHMAP * mp; + + binfo = &BINFO; + fc_bzero((void *)mb, sizeof(MAILBOXQ)); + + mb->mbxOwner = OWN_HOST; + + if ((mp = (MATCHMAP * )fc_mem_get(binfo, MEM_BUF)) == 0) { + + if (binfo->fc_flag & FC_SLI2) + mb->mbxCommand = MBX_READ_SPARM64; + else + mb->mbxCommand = MBX_READ_SPARM; + /* READ_SPARAM: no buffers */ + fc_log_printf_msg_vargs( binfo->fc_brd_no, + &fc_msgBlk0301, /* ptr to msg structure */ + fc_mes0301, /* ptr to msg */ + fc_msgBlk0301.msgPreambleStr); /* begin & end varargs */ + return(1); + } + + if (binfo->fc_flag & FC_SLI2) { + mb->mbxCommand = MBX_READ_SPARM64; + mb->un.varRdSparm.un.sp64.tus.f.bdeSize = sizeof(SERV_PARM); + mb->un.varRdSparm.un.sp64.addrHigh = (uint32)putPaddrHigh(mp->phys); + mb->un.varRdSparm.un.sp64.addrLow = (uint32)putPaddrLow(mp->phys); + } else { + mb->mbxCommand = MBX_READ_SPARM; + mb->un.varRdSparm.un.sp.bdeSize = sizeof(SERV_PARM); + mb->un.varRdSparm.un.sp.bdeAddress = (uint32)putPaddrLow(mp->phys); + } + + /* save address for completion */ + ((MAILBOXQ * )mb)->bp = (uchar * )mp; + + return(0); +} /* End fc_read_sparam */ + + +/**********************************************/ +/** fc_read_rpi Issue a READ RPI **/ +/** mailbox command **/ +/**********************************************/ +_static_ int +fc_read_rpi( +FC_BRD_INFO *binfo, +uint32 rpi, +MAILBOX *mb, +uint32 flag) +{ + fc_bzero((void *)mb, sizeof(MAILBOXQ)); + + mb->un.varRdRPI.reqRpi = (volatile ushort)rpi; + + if (binfo->fc_flag & FC_SLI2) { + mb->mbxCommand = MBX_READ_RPI64; + } else { + mb->mbxCommand = MBX_READ_RPI; + } + + mb->mbxOwner = OWN_HOST; + + mb->un.varWords[30] = flag; /* Set flag to issue action on cmpl */ + + return(0); +} /* End fc_read_rpi */ + + +/**********************************************/ +/** fc_read_xri Issue a READ XRI **/ +/** mailbox command **/ +/**********************************************/ +_static_ int +fc_read_xri( +FC_BRD_INFO *binfo, +uint32 xri, +MAILBOX *mb, +uint32 flag) +{ + fc_bzero((void *)mb, sizeof(MAILBOXQ)); + + mb->un.varRdXRI.reqXri = (volatile ushort)xri; + + mb->mbxCommand = MBX_READ_XRI; + mb->mbxOwner = OWN_HOST; + + mb->un.varWords[30] = flag; /* Set flag to issue action on cmpl */ + + return(0); +} /* End fc_read_xri */ + + +/**********************************************/ +/** fc_reg_login Issue a REG_LOGIN **/ +/** mailbox command **/ +/**********************************************/ +_static_ int +fc_reg_login( +FC_BRD_INFO *binfo, +uint32 did, +uchar *param, +MAILBOX *mb, +uint32 flag) +{ + uchar * sparam; + MATCHMAP * mp; + fc_dev_ctl_t *p_dev_ctl; + + fc_bzero((void *)mb, sizeof(MAILBOXQ)); + + mb->un.varRegLogin.rpi = 0; + mb->un.varRegLogin.did = did; + mb->un.varWords[30] = flag; /* Set flag to issue action on cmpl */ + + mb->mbxOwner = OWN_HOST; + + if ((mp = (MATCHMAP * )fc_mem_get(binfo, MEM_BUF)) == 0) { + + if (binfo->fc_flag & FC_SLI2) + mb->mbxCommand = MBX_REG_LOGIN64; + else + mb->mbxCommand = MBX_REG_LOGIN; + /* REG_LOGIN: no buffers */ + fc_log_printf_msg_vargs( binfo->fc_brd_no, + &fc_msgBlk0302, /* ptr to msg structure */ + fc_mes0302, /* ptr to msg */ + fc_msgBlk0302.msgPreambleStr, /* begin varargs */ + (uint32)did, + (uint32)flag); /* end varargs */ + return(1); + } + + sparam = mp->virt; + + /* Copy param's into a new buffer */ + fc_bcopy((void *)param, (void *)sparam, sizeof(SERV_PARM)); + + p_dev_ctl = (fc_dev_ctl_t *)(binfo->fc_p_dev_ctl); + fc_mpdata_sync(mp->dma_handle, 0, 0, DDI_DMA_SYNC_FORDEV); + + /* save address for completion */ + ((MAILBOXQ * )mb)->bp = (uchar * )mp; + + if (binfo->fc_flag & FC_SLI2) { + mb->mbxCommand = MBX_REG_LOGIN64; + mb->un.varRegLogin.un.sp64.tus.f.bdeSize = sizeof(SERV_PARM); + mb->un.varRegLogin.un.sp64.addrHigh = (uint32)putPaddrHigh(mp->phys); + mb->un.varRegLogin.un.sp64.addrLow = (uint32)putPaddrLow(mp->phys); + } else { + mb->mbxCommand = MBX_REG_LOGIN; + mb->un.varRegLogin.un.sp.bdeSize = sizeof(SERV_PARM); + mb->un.varRegLogin.un.sp.bdeAddress = (uint32)putPaddrLow(mp->phys); + } + + return(0); +} /* End fc_reg_login */ + + +/**********************************************/ +/** fc_unreg_login Issue a UNREG_LOGIN **/ +/** mailbox command **/ +/**********************************************/ +_static_ void +fc_unreg_login( +FC_BRD_INFO *binfo, +uint32 rpi, +MAILBOX *mb) +{ + fc_bzero((void *)mb, sizeof(MAILBOXQ)); + + mb->un.varUnregLogin.rpi = (ushort)rpi; + mb->un.varUnregLogin.rsvd1 = 0; + + mb->mbxCommand = MBX_UNREG_LOGIN; + mb->mbxOwner = OWN_HOST; + return; +} /* End fc_unreg_login */ + + +/**********************************************/ +/** fc_unreg_did Issue a UNREG_DID **/ +/** mailbox command **/ +/**********************************************/ +_static_ void +fc_unreg_did( +FC_BRD_INFO *binfo, +uint32 did, +MAILBOX *mb) +{ + fc_bzero((void *)mb, sizeof(MAILBOXQ)); + + mb->un.varUnregDID.did = did; + + mb->mbxCommand = MBX_UNREG_D_ID; + mb->mbxOwner = OWN_HOST; + return; +} /* End fc_unreg_did */ + + +/**********************************************/ +/** fc_set_slim Issue a special debug mbox */ +/** command to write slim */ +/**********************************************/ +_static_ void +fc_set_slim( +FC_BRD_INFO *binfo, +MAILBOX *mb, +uint32 addr, +uint32 value) +{ + fc_bzero((void *)mb, sizeof(MAILBOXQ)); + + /* addr = 0x090597 is AUTO ABTS disable for ELS commands */ + /* addr = 0x052198 is DELAYED ABTS enable for ELS commands */ + + /* + * Always turn on DELAYED ABTS for ELS timeouts + */ + if ((addr == 0x052198) && (value == 0)) + value = 1; + + mb->un.varWords[0] = addr; + mb->un.varWords[1] = value; + + mb->mbxCommand = MBX_SET_SLIM; + mb->mbxOwner = OWN_HOST; + return; +} /* End fc_set_slim */ + + +/* Disable Traffic Cop */ +_static_ void +fc_disable_tc( +FC_BRD_INFO *binfo, +MAILBOX *mb) +{ + fc_bzero((void *)mb, sizeof(MAILBOXQ)); + mb->un.varWords[0] = 0x50797; + mb->un.varWords[1] = 0; + mb->un.varWords[2] = 0xfffffffe; + + mb->mbxCommand = MBX_SET_SLIM; + mb->mbxOwner = OWN_HOST; +} /* End fc_set_tc */ + + +/**********************************************/ +/** fc_config_port Issue a CONFIG_PORT **/ +/** mailbox command **/ +/**********************************************/ +_static_ int +fc_config_port( +FC_BRD_INFO *binfo, +MAILBOX *mb, +uint32 *hbainit) +{ + RING * rp; + fc_dev_ctl_t * p_dev_ctl; + iCfgParam * clp; + int ring_3_active; /* 4th ring */ + struct pci_dev *pdev; + + p_dev_ctl = (fc_dev_ctl_t *)(binfo->fc_p_dev_ctl); + pdev = p_dev_ctl->pcidev ; + + clp = DD_CTL.p_config[binfo->fc_brd_no]; + fc_bzero((void *)mb, sizeof(MAILBOXQ)); + + mb->mbxCommand = MBX_CONFIG_PORT; + mb->mbxOwner = OWN_HOST; + + ring_3_active = 0; /* Preset to inactive */ + + mb->un.varCfgPort.pcbLen = sizeof(PCB); + mb->un.varCfgPort.pcbLow = + (uint32)putPaddrLow( & ((SLI2_SLIM * )binfo->fc_slim2.phys)->pcb); + mb->un.varCfgPort.pcbHigh = + (uint32)putPaddrHigh( & ((SLI2_SLIM * )binfo->fc_slim2.phys)->pcb); + if((pdev->device == PCI_DEVICE_ID_TFLY)|| + (pdev->device == PCI_DEVICE_ID_PFLY)) + fc_bcopy((uchar*) hbainit, (uchar*) mb->un.varCfgPort.hbainit, 20); + else + fc_bcopy((uchar*) hbainit, (uchar*) mb->un.varCfgPort.hbainit, 4); + + /* Now setup pcb */ + ((SLI2_SLIM * )binfo->fc_slim2.virt)->pcb.type = TYPE_NATIVE_SLI2; + ((SLI2_SLIM * )binfo->fc_slim2.virt)->pcb.feature = FEATURE_INITIAL_SLI2; + ((SLI2_SLIM * )binfo->fc_slim2.virt)->pcb.maxRing = (binfo->fc_ffnumrings-1); + ((SLI2_SLIM * )binfo->fc_slim2.virt)->pcb.mailBoxSize = sizeof(MAILBOX); + ((SLI2_SLIM * )binfo->fc_slim2.virt)->pcb.mbAddrHigh = (uint32) + putPaddrHigh( & ((SLI2_SLIM * )binfo->fc_slim2.phys)->mbx); + ((SLI2_SLIM * )binfo->fc_slim2.virt)->pcb.mbAddrLow = (uint32) + putPaddrLow( & ((SLI2_SLIM * )binfo->fc_slim2.phys)->mbx); + + /* SLIM POINTER */ + if (binfo->fc_busflag & FC_HOSTPTR) { + ((SLI2_SLIM * )binfo->fc_slim2.virt)->pcb.hgpAddrHigh = (uint32) + putPaddrHigh( & ((SLI2_SLIM * )binfo->fc_slim2.phys)->mbx.us.s2.host); + ((SLI2_SLIM * )binfo->fc_slim2.virt)->pcb.hgpAddrLow = (uint32) + putPaddrLow( & ((SLI2_SLIM * )binfo->fc_slim2.phys)->mbx.us.s2.host); + } else { + uint32 Laddr; + + ((SLI2_SLIM * )binfo->fc_slim2.virt)->pcb.hgpAddrHigh = (uint32) + fc_rdpci_32((fc_dev_ctl_t *)binfo->fc_p_dev_ctl, PCI_BAR_1_REGISTER); + Laddr = fc_rdpci_32((fc_dev_ctl_t *)binfo->fc_p_dev_ctl, PCI_BAR_0_REGISTER); + Laddr &= ~0x4; + ((SLI2_SLIM * )binfo->fc_slim2.virt)->pcb.hgpAddrLow = (uint32)(Laddr + (SLIMOFF*4)); + } + + ((SLI2_SLIM * )binfo->fc_slim2.virt)->pcb.pgpAddrHigh = (uint32) + putPaddrHigh( & ((SLI2_SLIM * )binfo->fc_slim2.phys)->mbx.us.s2.port); + ((SLI2_SLIM * )binfo->fc_slim2.virt)->pcb.pgpAddrLow = (uint32) + putPaddrLow( & ((SLI2_SLIM * )binfo->fc_slim2.phys)->mbx.us.s2.port); + + ((SLI2_SLIM * )binfo->fc_slim2.virt)->pcb.rdsc[0].cmdEntries = SLI2_IOCB_CMD_R0_ENTRIES; + ((SLI2_SLIM * )binfo->fc_slim2.virt)->pcb.rdsc[0].rspEntries = SLI2_IOCB_RSP_R0_ENTRIES; + if(clp[CFG_NETWORK_ON].a_current == 0) { + ((SLI2_SLIM * )binfo->fc_slim2.virt)->pcb.rdsc[1].cmdEntries = + (SLI2_IOCB_CMD_R1_ENTRIES - SLI2_IOCB_CMD_R1XTRA_ENTRIES); + ((SLI2_SLIM * )binfo->fc_slim2.virt)->pcb.rdsc[1].rspEntries = + (SLI2_IOCB_RSP_R1_ENTRIES - SLI2_IOCB_RSP_R1XTRA_ENTRIES); + ((SLI2_SLIM * )binfo->fc_slim2.virt)->pcb.rdsc[2].cmdEntries = + (SLI2_IOCB_CMD_R2_ENTRIES + SLI2_IOCB_CMD_R2XTRA_ENTRIES); + ((SLI2_SLIM * )binfo->fc_slim2.virt)->pcb.rdsc[2].rspEntries = + (SLI2_IOCB_RSP_R2_ENTRIES + SLI2_IOCB_RSP_R2XTRA_ENTRIES); + } + else { + ((SLI2_SLIM * )binfo->fc_slim2.virt)->pcb.rdsc[1].cmdEntries = SLI2_IOCB_CMD_R1_ENTRIES; + ((SLI2_SLIM * )binfo->fc_slim2.virt)->pcb.rdsc[1].rspEntries = SLI2_IOCB_RSP_R1_ENTRIES; + ((SLI2_SLIM * )binfo->fc_slim2.virt)->pcb.rdsc[2].cmdEntries = SLI2_IOCB_CMD_R2_ENTRIES; + ((SLI2_SLIM * )binfo->fc_slim2.virt)->pcb.rdsc[2].rspEntries = SLI2_IOCB_RSP_R2_ENTRIES; + } + if( ring_3_active == 0) { + ((SLI2_SLIM * )binfo->fc_slim2.virt)->pcb.rdsc[3].cmdEntries = 0; + ((SLI2_SLIM * )binfo->fc_slim2.virt)->pcb.rdsc[3].rspEntries = 0; + } + + ((SLI2_SLIM * )binfo->fc_slim2.virt)->pcb.rdsc[0].cmdAddrHigh = (uint32) + putPaddrHigh( & ((SLI2_SLIM * )binfo->fc_slim2.phys)->IOCBs[0]); + ((SLI2_SLIM * )binfo->fc_slim2.virt)->pcb.rdsc[0].cmdAddrLow = (uint32) + putPaddrLow( & ((SLI2_SLIM * )binfo->fc_slim2.phys)->IOCBs[0]); + ((SLI2_SLIM * )binfo->fc_slim2.virt)->pcb.rdsc[0].rspAddrHigh = (uint32) + putPaddrHigh( & ((SLI2_SLIM * )binfo->fc_slim2.phys)->IOCBs[ + SLI2_IOCB_CMD_R0_ENTRIES]); + ((SLI2_SLIM * )binfo->fc_slim2.virt)->pcb.rdsc[0].rspAddrLow = (uint32) + putPaddrLow( & ((SLI2_SLIM * )binfo->fc_slim2.phys)->IOCBs[ + SLI2_IOCB_CMD_R0_ENTRIES]); + rp = &binfo->fc_ring[0]; + rp->fc_cmdringaddr = (void *) & ((SLI2_SLIM * )binfo->fc_slim2.virt)->IOCBs[0]; + rp->fc_rspringaddr = (void *) & ((SLI2_SLIM * )binfo->fc_slim2.virt)->IOCBs[ + SLI2_IOCB_CMD_R0_ENTRIES]; + + ((SLI2_SLIM * )binfo->fc_slim2.virt)->pcb.rdsc[1].cmdAddrHigh = (uint32) + putPaddrHigh( & ((SLI2_SLIM * )binfo->fc_slim2.phys)->IOCBs[ + SLI2_IOCB_CMD_R0_ENTRIES + SLI2_IOCB_RSP_R0_ENTRIES]); + ((SLI2_SLIM * )binfo->fc_slim2.virt)->pcb.rdsc[1].cmdAddrLow = (uint32) + putPaddrLow( & ((SLI2_SLIM * )binfo->fc_slim2.phys)->IOCBs[ + SLI2_IOCB_CMD_R0_ENTRIES + SLI2_IOCB_RSP_R0_ENTRIES]); + if(clp[CFG_NETWORK_ON].a_current == 0) { + ((SLI2_SLIM * )binfo->fc_slim2.virt)->pcb.rdsc[1].rspAddrHigh = (uint32) + putPaddrHigh( & ((SLI2_SLIM * )binfo->fc_slim2.phys)->IOCBs[ + SLI2_IOCB_CMD_R0_ENTRIES + SLI2_IOCB_RSP_R0_ENTRIES + + SLI2_IOCB_CMD_R1_ENTRIES - SLI2_IOCB_CMD_R1XTRA_ENTRIES]); + ((SLI2_SLIM * )binfo->fc_slim2.virt)->pcb.rdsc[1].rspAddrLow = (uint32) + putPaddrLow( & ((SLI2_SLIM * )binfo->fc_slim2.phys)->IOCBs[ + SLI2_IOCB_CMD_R0_ENTRIES + SLI2_IOCB_RSP_R0_ENTRIES + + SLI2_IOCB_CMD_R1_ENTRIES - SLI2_IOCB_CMD_R1XTRA_ENTRIES]); + rp = &binfo->fc_ring[1]; + rp->fc_cmdringaddr = (void *) & ((SLI2_SLIM * )binfo->fc_slim2.virt)->IOCBs[ + SLI2_IOCB_CMD_R0_ENTRIES + SLI2_IOCB_RSP_R0_ENTRIES]; + rp->fc_rspringaddr = (void *) & ((SLI2_SLIM * )binfo->fc_slim2.virt)->IOCBs[ + SLI2_IOCB_CMD_R0_ENTRIES + SLI2_IOCB_RSP_R0_ENTRIES + + SLI2_IOCB_CMD_R1_ENTRIES - SLI2_IOCB_CMD_R1XTRA_ENTRIES]; + + ((SLI2_SLIM * )binfo->fc_slim2.virt)->pcb.rdsc[2].cmdAddrHigh = (uint32) + putPaddrHigh( & ((SLI2_SLIM * )binfo->fc_slim2.phys)->IOCBs[ + SLI2_IOCB_CMD_R0_ENTRIES + SLI2_IOCB_RSP_R0_ENTRIES + + SLI2_IOCB_CMD_R1_ENTRIES + SLI2_IOCB_RSP_R1_ENTRIES - + SLI2_IOCB_CMD_R1XTRA_ENTRIES - SLI2_IOCB_RSP_R1XTRA_ENTRIES]); + ((SLI2_SLIM * )binfo->fc_slim2.virt)->pcb.rdsc[2].cmdAddrLow = (uint32) + putPaddrLow( & ((SLI2_SLIM * )binfo->fc_slim2.phys)->IOCBs[ + SLI2_IOCB_CMD_R0_ENTRIES + SLI2_IOCB_RSP_R0_ENTRIES + + SLI2_IOCB_CMD_R1_ENTRIES + SLI2_IOCB_RSP_R1_ENTRIES - + SLI2_IOCB_CMD_R1XTRA_ENTRIES - SLI2_IOCB_RSP_R1XTRA_ENTRIES]); + ((SLI2_SLIM * )binfo->fc_slim2.virt)->pcb.rdsc[2].rspAddrHigh = (uint32) + putPaddrHigh( & ((SLI2_SLIM * )binfo->fc_slim2.phys)->IOCBs[ + SLI2_IOCB_CMD_R0_ENTRIES + SLI2_IOCB_RSP_R0_ENTRIES + + SLI2_IOCB_CMD_R1_ENTRIES + SLI2_IOCB_RSP_R1_ENTRIES + + SLI2_IOCB_CMD_R2_ENTRIES + SLI2_IOCB_CMD_R2XTRA_ENTRIES - + SLI2_IOCB_CMD_R1XTRA_ENTRIES - SLI2_IOCB_RSP_R1XTRA_ENTRIES]); + ((SLI2_SLIM * )binfo->fc_slim2.virt)->pcb.rdsc[2].rspAddrLow = (uint32) + putPaddrLow( & ((SLI2_SLIM * )binfo->fc_slim2.phys)->IOCBs[ + SLI2_IOCB_CMD_R0_ENTRIES + SLI2_IOCB_RSP_R0_ENTRIES + + SLI2_IOCB_CMD_R1_ENTRIES + SLI2_IOCB_RSP_R1_ENTRIES + + SLI2_IOCB_CMD_R2_ENTRIES + SLI2_IOCB_CMD_R2XTRA_ENTRIES - + SLI2_IOCB_CMD_R1XTRA_ENTRIES - SLI2_IOCB_RSP_R1XTRA_ENTRIES]); + rp = &binfo->fc_ring[2]; + rp->fc_cmdringaddr = (void *) & ((SLI2_SLIM * )binfo->fc_slim2.virt)->IOCBs[ + SLI2_IOCB_CMD_R0_ENTRIES + SLI2_IOCB_RSP_R0_ENTRIES + + SLI2_IOCB_CMD_R1_ENTRIES + SLI2_IOCB_RSP_R1_ENTRIES - + SLI2_IOCB_CMD_R1XTRA_ENTRIES - SLI2_IOCB_RSP_R1XTRA_ENTRIES]; + rp->fc_rspringaddr = (void *) & ((SLI2_SLIM * )binfo->fc_slim2.virt)->IOCBs[ + SLI2_IOCB_CMD_R0_ENTRIES + SLI2_IOCB_RSP_R0_ENTRIES + + SLI2_IOCB_CMD_R1_ENTRIES + SLI2_IOCB_RSP_R1_ENTRIES + + SLI2_IOCB_CMD_R2_ENTRIES + SLI2_IOCB_CMD_R2XTRA_ENTRIES - + SLI2_IOCB_CMD_R1XTRA_ENTRIES - SLI2_IOCB_RSP_R1XTRA_ENTRIES]; + } + else { + ((SLI2_SLIM * )binfo->fc_slim2.virt)->pcb.rdsc[1].rspAddrHigh = (uint32) + putPaddrHigh( & ((SLI2_SLIM * )binfo->fc_slim2.phys)->IOCBs[ + SLI2_IOCB_CMD_R0_ENTRIES + SLI2_IOCB_RSP_R0_ENTRIES + + SLI2_IOCB_CMD_R1_ENTRIES]); + ((SLI2_SLIM * )binfo->fc_slim2.virt)->pcb.rdsc[1].rspAddrLow = (uint32) + putPaddrLow( & ((SLI2_SLIM * )binfo->fc_slim2.phys)->IOCBs[ + SLI2_IOCB_CMD_R0_ENTRIES + SLI2_IOCB_RSP_R0_ENTRIES + + SLI2_IOCB_CMD_R1_ENTRIES]); + rp = &binfo->fc_ring[1]; + rp->fc_cmdringaddr = (void *) & ((SLI2_SLIM * )binfo->fc_slim2.virt)->IOCBs[ + SLI2_IOCB_CMD_R0_ENTRIES + SLI2_IOCB_RSP_R0_ENTRIES]; + rp->fc_rspringaddr = (void *) & ((SLI2_SLIM * )binfo->fc_slim2.virt)->IOCBs[ + SLI2_IOCB_CMD_R0_ENTRIES + SLI2_IOCB_RSP_R0_ENTRIES + + SLI2_IOCB_CMD_R1_ENTRIES]; + + ((SLI2_SLIM * )binfo->fc_slim2.virt)->pcb.rdsc[2].cmdAddrHigh = (uint32) + putPaddrHigh( & ((SLI2_SLIM * )binfo->fc_slim2.phys)->IOCBs[ + SLI2_IOCB_CMD_R0_ENTRIES + SLI2_IOCB_RSP_R0_ENTRIES + + SLI2_IOCB_CMD_R1_ENTRIES + SLI2_IOCB_RSP_R1_ENTRIES]); + ((SLI2_SLIM * )binfo->fc_slim2.virt)->pcb.rdsc[2].cmdAddrLow = (uint32) + putPaddrLow( & ((SLI2_SLIM * )binfo->fc_slim2.phys)->IOCBs[ + SLI2_IOCB_CMD_R0_ENTRIES + SLI2_IOCB_RSP_R0_ENTRIES + + SLI2_IOCB_CMD_R1_ENTRIES + SLI2_IOCB_RSP_R1_ENTRIES]); + ((SLI2_SLIM * )binfo->fc_slim2.virt)->pcb.rdsc[2].rspAddrHigh = (uint32) + putPaddrHigh( & ((SLI2_SLIM * )binfo->fc_slim2.phys)->IOCBs[ + SLI2_IOCB_CMD_R0_ENTRIES + SLI2_IOCB_RSP_R0_ENTRIES + + SLI2_IOCB_CMD_R1_ENTRIES + SLI2_IOCB_RSP_R1_ENTRIES + + SLI2_IOCB_CMD_R2_ENTRIES]); + ((SLI2_SLIM * )binfo->fc_slim2.virt)->pcb.rdsc[2].rspAddrLow = (uint32) + putPaddrLow( & ((SLI2_SLIM * )binfo->fc_slim2.phys)->IOCBs[ + SLI2_IOCB_CMD_R0_ENTRIES + SLI2_IOCB_RSP_R0_ENTRIES + + SLI2_IOCB_CMD_R1_ENTRIES + SLI2_IOCB_RSP_R1_ENTRIES + + SLI2_IOCB_CMD_R2_ENTRIES]); + rp = &binfo->fc_ring[2]; + rp->fc_cmdringaddr = (void *) & ((SLI2_SLIM * )binfo->fc_slim2.virt)->IOCBs[ + SLI2_IOCB_CMD_R0_ENTRIES + SLI2_IOCB_RSP_R0_ENTRIES + + SLI2_IOCB_CMD_R1_ENTRIES + SLI2_IOCB_RSP_R1_ENTRIES]; + rp->fc_rspringaddr = (void *) & ((SLI2_SLIM * )binfo->fc_slim2.virt)->IOCBs[ + SLI2_IOCB_CMD_R0_ENTRIES + SLI2_IOCB_RSP_R0_ENTRIES + + SLI2_IOCB_CMD_R1_ENTRIES + SLI2_IOCB_RSP_R1_ENTRIES + + SLI2_IOCB_CMD_R2_ENTRIES]; + } + + if( ring_3_active == 0) { + ((SLI2_SLIM * )binfo->fc_slim2.virt)->pcb.rdsc[3].cmdAddrHigh = 0; + ((SLI2_SLIM * )binfo->fc_slim2.virt)->pcb.rdsc[3].rspAddrHigh = 0; + ((SLI2_SLIM * )binfo->fc_slim2.virt)->pcb.rdsc[3].cmdAddrLow = 0; + ((SLI2_SLIM * )binfo->fc_slim2.virt)->pcb.rdsc[3].rspAddrLow = 0; + } + + fc_pcimem_bcopy((uint32 * )(&((SLI2_SLIM * )binfo->fc_slim2.virt)->pcb), + (uint32 * )(&((SLI2_SLIM * )binfo->fc_slim2.virt)->pcb), sizeof(PCB)); + + fc_mpdata_sync(binfo->fc_slim2.dma_handle, (off_t)0, (size_t)0, + DDI_DMA_SYNC_FORDEV); + /* Service Level Interface (SLI) 2 selected */ + fc_log_printf_msg_vargs( binfo->fc_brd_no, + &fc_msgBlk0405, /* ptr to msg structure */ + fc_mes0405, /* ptr to msg */ + fc_msgBlk0405.msgPreambleStr); /* begin & end varargs */ + return(0); +} /* End fc_config_port */ + +/**********************************************/ +/** fc_config_farp Issue a CONFIG FARP **/ +/** mailbox command **/ +/**********************************************/ +_static_ void +fc_config_farp( +FC_BRD_INFO *binfo, +MAILBOX *mb) +{ + fc_bzero((void *)mb, sizeof(MAILBOXQ)); + + mb->un.varCfgFarp.filterEnable = 1; + mb->un.varCfgFarp.portName = 1; + mb->un.varCfgFarp.nodeName = 1; + + fc_bcopy((uchar * )&binfo->fc_portname, (uchar *)&mb->un.varCfgFarp.portname, sizeof(NAME_TYPE)); + fc_bcopy((uchar * )&binfo->fc_portname, (uchar *)&mb->un.varCfgFarp.nodename, sizeof(NAME_TYPE)); + + mb->mbxCommand = MBX_CONFIG_FARP; + mb->mbxOwner = OWN_HOST; + return; +} + + +/**********************************************/ +/** fc_read_nv Issue a READ CONFIG **/ +/** mailbox command **/ +/**********************************************/ +_static_ void +fc_read_config( +FC_BRD_INFO *binfo, +MAILBOX *mb) +{ + fc_bzero((void *)mb, sizeof(MAILBOXQ)); + mb->mbxCommand = MBX_READ_CONFIG; + mb->mbxOwner = OWN_HOST; + return; +} /* End fc_read_config */ + +/*****************************************************************************/ +/* + * NAME: fc_mbox_put + * + * FUNCTION: put mailbox cmd onto the mailbox queue. + * + * EXECUTION ENVIRONMENT: process and interrupt level. + * + * NOTES: + * + * CALLED FROM: + * issue_mb_cmd + * + * INPUT: + * binfo - pointer to the device info area + * mbp - pointer to mailbox queue entry of mailbox cmd + * + * RETURNS: + * NULL - command queued + */ +/*****************************************************************************/ +_static_ void +fc_mbox_put( +FC_BRD_INFO *binfo, +MAILBOXQ *mbq) /* pointer to mbq entry */ +{ + if (binfo->fc_mbox.q_first) { + /* queue command to end of list */ + ((MAILBOXQ * )binfo->fc_mbox.q_last)->q = (uchar * )mbq; + binfo->fc_mbox.q_last = (uchar * )mbq; + } else { + /* add command to empty list */ + binfo->fc_mbox.q_first = (uchar * )mbq; + binfo->fc_mbox.q_last = (uchar * )mbq; + } + + mbq->q = NULL; + binfo->fc_mbox.q_cnt++; + + return; + +} /* End fc_mbox_put */ + + +/*****************************************************************************/ +/* + * NAME: fc_mbox_get + * + * FUNCTION: get a mailbox command from mailbox command queue + * + * EXECUTION ENVIRONMENT: interrupt level. + * + * NOTES: + * + * CALLED FROM: + * handle_mb_event + * + * INPUT: + * binfo - pointer to the device info area + * + * RETURNS: + * NULL - no match found + * mb pointer - pointer to a mailbox command + */ +/*****************************************************************************/ +_static_ MAILBOXQ * +fc_mbox_get( +FC_BRD_INFO *binfo) +{ + MAILBOXQ * p_first = NULL; + + if (binfo->fc_mbox.q_first) { + p_first = (MAILBOXQ * )binfo->fc_mbox.q_first; + if ((binfo->fc_mbox.q_first = p_first->q) == 0) { + binfo->fc_mbox.q_last = 0; + } + p_first->q = NULL; + binfo->fc_mbox.q_cnt--; + } + + return(p_first); + +} /* End fc_mbox_get */ + + diff -purN -X /home/mbligh/.diff.exclude 350-autoswap/drivers/scsi/lpfc/fcmemb.c 370-emulex/drivers/scsi/lpfc/fcmemb.c --- 350-autoswap/drivers/scsi/lpfc/fcmemb.c 1969-12-31 16:00:00.000000000 -0800 +++ 370-emulex/drivers/scsi/lpfc/fcmemb.c 2004-02-28 11:20:03.000000000 -0800 @@ -0,0 +1,810 @@ +/******************************************************************* + * This file is part of the Emulex Linux Device Driver for * + * Enterprise Fibre Channel Host Bus Adapters. * + * Refer to the README file included with this package for * + * driver version and adapter support. * + * Copyright (C) 2003 Emulex Corporation. * + * www.emulex.com * + * * + * This program is free software; you can redistribute it and/or * + * modify it under the terms of the GNU General Public License * + * as published by the Free Software Foundation; either version 2 * + * of the License, or (at your option) any later version. * + * * + * This program is distributed in the hope that it will be useful, * + * but WITHOUT ANY WARRANTY; without even the implied warranty of * + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * + * GNU General Public License for more details, a copy of which * + * can be found in the file COPYING included with this package. * + *******************************************************************/ + +#include "fc_os.h" + +#include "fc_hw.h" +#include "fc.h" + +#include "fcdiag.h" +#include "fcfgparm.h" +#include "fcmsg.h" +#include "fc_crtn.h" /* Core - external routine definitions */ +#include "fc_ertn.h" /* Environment - external routine definitions */ + +extern uint32 fcPAGESIZE; +extern fc_dd_ctl_t DD_CTL; +extern iCfgParam icfgparam[]; +extern int fc_max_els_sent; + + +/* + * Define the following to Enable SANITY check logic in routines + * fc_getvaddr() and fc_mapvaddr(). + * #define FC_DBG_VADDR_SANITY_CHK + */ + +/* Routine Declaration - Local */ +/* There currently are no local routine declarations */ +/* End Routine Declaration - Local */ + +/***************************************************/ +/** fc_malloc_buffer **/ +/** **/ +/** This routine will allocate iocb/data buffer **/ +/** space and setup the buffers for all rings on **/ +/** the specified board to use. The data buffers **/ +/** can be posted to the ring with the **/ +/** fc_post_buffer routine. The iocb buffers **/ +/** are used to make a temp copy of the response **/ +/** ring iocbs. Returns 0 if not enough memory, **/ +/** Returns 1 if successful. **/ +/***************************************************/ +_static_ int +fc_malloc_buffer( +fc_dev_ctl_t *p_dev_ctl) +{ + FC_BRD_INFO * binfo = &BINFO; + iCfgParam * clp; + int i, j; + uchar * bp; + uchar * oldbp; + RING * rp; + MEMSEG * mp; + MATCHMAP * matp; + MBUF_INFO * buf_info; + MBUF_INFO bufinfo; + unsigned long iflag; + + buf_info = &bufinfo; + clp = DD_CTL.p_config[binfo->fc_brd_no]; + + + for (i = 0; i < binfo->fc_ffnumrings; i++) { + rp = &binfo->fc_ring[i]; + rp->fc_mpon = 0; + rp->fc_mpoff = 0; + } + + if(clp[CFG_FCP_ON].a_current) { + buf_info->size = (MAX_FCP_CMDS * sizeof(void *)); + buf_info->flags = 0; + buf_info->align = sizeof(void *); + buf_info->dma_handle = 0; + + /* Create a table to relate FCP iotags to fc_buf addresses */ + fc_malloc(p_dev_ctl, buf_info); + if (buf_info->virt == NULL) { + fc_free_buffer(p_dev_ctl); + return(0); + } + binfo->fc_table = (FCPTBL * )buf_info->virt; + fc_bzero((char *)binfo->fc_table, MAX_FCP_CMDS * sizeof(void *)); + } + + /* Initialize xmit/receive buffer structure */ + /* Three buffers per response entry will initially be posted to ELS ring */ + iflag = lpfc_mempool_disable_lock(p_dev_ctl); + mp = &binfo->fc_memseg[MEM_BUF]; + mp->fc_memsize = FCELSSIZE; + if(clp[CFG_NUM_BUFS].a_current < 50) + mp->fc_numblks = 50; + else + mp->fc_numblks = (ushort)clp[CFG_NUM_BUFS].a_current; + + /* MEM_BUF is same pool as MEM_BPL */ + if (binfo->fc_sli == 2) + mp->fc_numblks += MAX_SLI2_IOCB; + + mp->fc_memflag = FC_MEM_DMA; + mp->fc_lowmem = (3 * fc_max_els_sent) + 8; + + if((2*mp->fc_lowmem) > mp->fc_numblks) + mp->fc_lowmem = (mp->fc_numblks / 2); + + /* Initialize mailbox cmd buffer structure */ + mp = &binfo->fc_memseg[MEM_MBOX]; + mp->fc_memsize = sizeof(MAILBOXQ); + mp->fc_numblks = (short)clp[CFG_NUM_NODES].a_current + 32; + mp->fc_memflag = 0; + mp->fc_lowmem = (2 * fc_max_els_sent) + 8; + + /* Initialize iocb buffer structure */ + mp = &binfo->fc_memseg[MEM_IOCB]; + mp->fc_memsize = sizeof(IOCBQ); + mp->fc_numblks = (ushort)clp[CFG_NUM_IOCBS].a_current + MIN_CLK_BLKS; + mp->fc_memflag = 0; + mp->fc_lowmem = (2 * fc_max_els_sent) + 8; + + /* Initialize iocb buffer structure */ + mp = &binfo->fc_memseg[MEM_NLP]; + mp->fc_memsize = sizeof(NODELIST); + mp->fc_numblks = (short)clp[CFG_NUM_NODES].a_current + 2; + mp->fc_memflag = 0; + mp->fc_lowmem = 0; + + + /* Allocate buffer pools for above buffer structures */ + for (j = 0; j < FC_MAX_SEG; j++) { + mp = &binfo->fc_memseg[j]; + + + mp->fc_memptr = 0; + mp->fc_endmemptr = 0; + mp->fc_memhi = 0; + mp->fc_memlo = 0; + + for (i = 0; i < mp->fc_numblks; i++) { + /* If this is a DMA buffer we need alignment on a page so we don't + * want to worry about buffers spanning page boundries when mapping + * memory for the adapter. + */ + if (mp->fc_memflag & FC_MEM_DMA) { + buf_info->size = sizeof(MATCHMAP); + buf_info->flags = 0; + buf_info->align = sizeof(void *); + buf_info->dma_handle = 0; + + fc_malloc(p_dev_ctl, buf_info); + if (buf_info->virt == NULL) { + lpfc_mempool_unlock_enable(p_dev_ctl, iflag); + fc_free_buffer(p_dev_ctl); + return(0); + } + + matp = (MATCHMAP * )buf_info->virt; + fc_bzero(matp, sizeof(MATCHMAP)); + if((ulong)matp > (ulong)(mp->fc_memhi)) + mp->fc_memhi = (uchar *)matp; + if(mp->fc_memlo == 0) + mp->fc_memlo = (uchar *)matp; + else { + if((ulong)matp < (ulong)(mp->fc_memlo)) + mp->fc_memlo = (uchar *)matp; + } + + buf_info->size = mp->fc_memsize; + buf_info->flags = FC_MBUF_DMA; + buf_info->dma_handle = 0; + + switch (mp->fc_memsize) { + case sizeof(FCP_CMND): + buf_info->align = sizeof(FCP_CMND); + break; + + case 1024: + buf_info->align = 1024; + break; + + case 2048: + buf_info->align = 2048; + break; + + case 4096: + buf_info->align = 4096; + break; + + default: + buf_info->align = sizeof(void *); + break; + } + + fc_malloc(p_dev_ctl, buf_info); + if (buf_info->virt == NULL) { + fc_free_buffer(p_dev_ctl); + return(0); + } + bp = (uchar * )buf_info->virt; + fc_bzero(bp, mp->fc_memsize); + + /* Link buffer into beginning of list. The first pointer in + * each buffer is a forward pointer to the next buffer. + */ + oldbp = mp->fc_memptr; + if(oldbp == 0) + mp->fc_endmemptr = (uchar *)matp; + mp->fc_memptr = (uchar * )matp; + matp->fc_mptr = oldbp; + matp->virt = bp; + if (buf_info->dma_handle) { + matp->dma_handle = buf_info->dma_handle; + matp->data_handle = buf_info->data_handle; + } + matp->phys = (uchar * )buf_info->phys; + } else { + buf_info->size = mp->fc_memsize; + buf_info->flags = 0; + buf_info->align = sizeof(void *); + buf_info->dma_handle = 0; + + fc_malloc(p_dev_ctl, buf_info); + if (buf_info->virt == NULL) { + lpfc_mempool_unlock_enable(p_dev_ctl, iflag); + fc_free_buffer(p_dev_ctl); + return(0); + } + bp = (uchar * )buf_info->virt; + fc_bzero(bp, mp->fc_memsize); + if((ulong)bp > (ulong)(mp->fc_memhi)) + mp->fc_memhi = (uchar *)bp; + if(mp->fc_memlo == 0) + mp->fc_memlo = (uchar *)bp; + else { + if((ulong)bp < (ulong)(mp->fc_memlo)) + mp->fc_memlo = (uchar *)bp; + } + + /* Link buffer into beginning of list. The first pointer in + * each buffer is a forward pointer to the next buffer. + */ + oldbp = mp->fc_memptr; + if(oldbp == 0) + mp->fc_endmemptr = bp; + mp->fc_memptr = bp; + *((uchar * *)bp) = oldbp; + } + } + + /* free blocks = total blocks right now */ + mp->fc_free = i; + } + + lpfc_mempool_unlock_enable(p_dev_ctl, iflag); + return(1); +} /* End fc_malloc_buffer */ + + +/***************************************************/ +/** fc_free_buffer **/ +/** **/ +/** This routine will free iocb/data buffer space */ +/***************************************************/ +_static_ int +fc_free_buffer( +fc_dev_ctl_t *p_dev_ctl) +{ + FC_BRD_INFO * binfo = &BINFO; + int j, ipri; + uchar * bp; + MEMSEG * mp; + MATCHMAP * mm; + NODELIST * ndlp; + NODELIST * ondlp; + RING * rp; + IOCBQ * iocbq, *save; + MAILBOXQ * mbox, *mbsave; + MBUF_INFO * buf_info; + MBUF_INFO bufinfo; + FCCLOCK_INFO * clock_info; + FCCLOCK * cb; + FCCLOCK * nextcb; + unsigned long iflag; + + buf_info = &bufinfo; + + /* free the mapped address match area for each ring */ + for (j = 0; j < binfo->fc_ffnumrings; j++) { + rp = &binfo->fc_ring[j]; + + /* Free everything on tx queue */ + iocbq = (IOCBQ * )(rp->fc_tx.q_first); + while (iocbq) { + save = iocbq; + iocbq = (IOCBQ * )iocbq->q; + fc_mem_put(binfo, MEM_IOCB, (uchar * )save); + } + + if (j != FC_FCP_RING) { + /* Free everything on txp queue */ + unsigned long iflag; + + iflag = lpfc_q_disable_lock(p_dev_ctl); + iocbq = (IOCBQ * )(rp->fc_txp.q_first); + while (iocbq) { + save = iocbq; + iocbq = (IOCBQ * )iocbq->q; + fc_mem_put(binfo, MEM_IOCB, (uchar * )save); + } + lpfc_q_unlock_enable(p_dev_ctl, iflag); + + while (rp->fc_mpoff) { + uchar * addr; + + addr = 0; + mm = (MATCHMAP * )(rp->fc_mpoff); + if (j == FC_IP_RING) + addr = (uchar * )(fcnextpkt((fcipbuf_t * )mm)); + else if (j == FC_ELS_RING) + addr = mm->phys; + if ((mm = fc_getvaddr(p_dev_ctl, rp, addr))) { + if (j == FC_ELS_RING) { + fc_mem_put(binfo, MEM_BUF, (uchar * )mm); + } + else if (j == FC_IP_RING) { + fcipbuf_t * mbuf; + + mbuf = (fcipbuf_t * )mm; + fcnextdata(mbuf) = 0; + fcnextpkt(mbuf) = 0; + m_freem(mbuf); + } + } + } + } + } + + /* Free any delayed ELS xmits */ + if(binfo->fc_delayxmit) { + iocbq = binfo->fc_delayxmit; + binfo->fc_delayxmit = 0; + while(iocbq) { + mm = (MATCHMAP * )iocbq->bp; + if (binfo->fc_flag & FC_SLI2) { + fc_mem_put(binfo, MEM_BPL, (uchar * )iocbq->bpl); + } + fc_mem_put(binfo, MEM_BUF, (uchar * )mm); + fc_mem_put(binfo, MEM_BUF, (uchar * )iocbq->info); + save = iocbq; + iocbq = (IOCBQ *)save->q; + fc_mem_put(binfo, MEM_IOCB, (uchar * )save); + } + } + + if (binfo->fc_table) { + buf_info->size = (MAX_FCP_CMDS * sizeof(void *)); + buf_info->virt = (uint32 * )binfo->fc_table; + buf_info->phys = 0; + buf_info->flags = 0; + buf_info->dma_handle = 0; + fc_free(p_dev_ctl, buf_info); + binfo->fc_table = 0; + } + + /* Free everything on mbox queue */ + mbox = (MAILBOXQ * )(binfo->fc_mbox.q_first); + while (mbox) { + mbsave = mbox; + mbox = (MAILBOXQ * )mbox->q; + fc_mem_put(binfo, MEM_MBOX, (uchar * )mbsave); + } + binfo->fc_mbox.q_first = 0; + binfo->fc_mbox.q_last = 0; + binfo->fc_mbox_active = 0; + + /* Free everything on iocb plogi queue */ + iocbq = (IOCBQ * )(binfo->fc_plogi.q_first); + while (iocbq) { + save = iocbq; + iocbq = (IOCBQ * )iocbq->q; + fc_mem_put(binfo, MEM_IOCB, (uchar * )save); + } + binfo->fc_plogi.q_first = 0; + binfo->fc_plogi.q_last = 0; + + /* Now cleanup unexpired clock blocks */ + clock_info = &DD_CTL.fc_clock_info; + ipri = disable_lock(FC_LVL, &CLOCK_LOCK); + + cb = clock_info->fc_clkhdr.cl_f; + while (cb != (FCCLOCK * ) & clock_info->fc_clkhdr) { + nextcb = cb->cl_fw; + if(cb->cl_p_dev_ctl == (void *)p_dev_ctl) { + fc_clock_deque(cb); + /* Release clock block */ + fc_clkrelb(p_dev_ctl, cb); + /* start over */ + } + cb = nextcb; + } + unlock_enable(ipri, &CLOCK_LOCK); + + /* Free all node table entries */ + ndlp = binfo->fc_nlpbind_start; + if(ndlp == (NODELIST *)&binfo->fc_nlpbind_start) + ndlp = binfo->fc_nlpunmap_start; + if(ndlp == (NODELIST *)&binfo->fc_nlpunmap_start) + ndlp = binfo->fc_nlpmap_start; + while(ndlp != (NODELIST *)&binfo->fc_nlpmap_start) { + ondlp = ndlp; + ndlp = (NODELIST *)ndlp->nlp_listp_next; + if(ndlp == (NODELIST *)&binfo->fc_nlpbind_start) + ndlp = binfo->fc_nlpunmap_start; + if(ndlp == (NODELIST *)&binfo->fc_nlpunmap_start) + ndlp = binfo->fc_nlpmap_start; + fc_mem_put(binfo, MEM_NLP, (uchar * )ondlp); + } + binfo->fc_nlpbind_start = (NODELIST *)&binfo->fc_nlpbind_start; + binfo->fc_nlpbind_end = (NODELIST *)&binfo->fc_nlpbind_start; + binfo->fc_nlpmap_start = (NODELIST *)&binfo->fc_nlpmap_start; + binfo->fc_nlpmap_end = (NODELIST *)&binfo->fc_nlpmap_start; + binfo->fc_nlpunmap_start = (NODELIST *)&binfo->fc_nlpunmap_start; + binfo->fc_nlpunmap_end = (NODELIST *)&binfo->fc_nlpunmap_start; + + iflag = lpfc_mempool_disable_lock(p_dev_ctl); + /* Loop through all memory buffer pools */ + for (j = 0; j < FC_MAX_SEG; j++) { + mp = &binfo->fc_memseg[j]; + /* Free memory associated with all buffers on free buffer pool */ + while ((bp = mp->fc_memptr) != NULL) { + mp->fc_memptr = *((uchar * *)bp); + if (mp->fc_memflag & FC_MEM_DMA) { + mm = (MATCHMAP * )bp; + bp = mm->virt; + buf_info->size = mp->fc_memsize; + buf_info->virt = (uint32 * )bp; + buf_info->phys = (uint32 * )mm->phys; + buf_info->flags = FC_MBUF_DMA; + if (mm->dma_handle) { + buf_info->dma_handle = mm->dma_handle; + buf_info->data_handle = mm->data_handle; + } + fc_free(p_dev_ctl, buf_info); + + buf_info->size = sizeof(MATCHMAP); + buf_info->virt = (uint32 * )mm; + buf_info->phys = 0; + buf_info->flags = 0; + buf_info->dma_handle = 0; + fc_free(p_dev_ctl, buf_info); + } else { + buf_info->size = mp->fc_memsize; + buf_info->virt = (uint32 * )bp; + buf_info->phys = 0; + buf_info->flags = 0; + buf_info->dma_handle = 0; + fc_free(p_dev_ctl, buf_info); + } + } + mp->fc_endmemptr = NULL; + mp->fc_free = 0; + } + lpfc_mempool_unlock_enable(p_dev_ctl, iflag); + return(0); +} /* End fc_free_buffer */ + + + +/**************************************************/ +/** fc_mem_get **/ +/** **/ +/** This routine will get a free memory buffer. **/ +/** seg identifies which buffer pool to use. **/ +/** Returns the free buffer ptr or 0 for no buf **/ +/**************************************************/ +_static_ uchar * +fc_mem_get( +FC_BRD_INFO *binfo, +uint32 arg) +{ + uchar * bp; + MEMSEG * mp; + uint32 seg = arg & MEM_SEG_MASK; + int low; + fc_dev_ctl_t *p_dev_ctl; + unsigned long iflag; + + /* range check on seg argument */ + if (seg >= FC_MAX_SEG) + return((uchar * )0); + + p_dev_ctl = (fc_dev_ctl_t *)binfo->fc_p_dev_ctl; + iflag = lpfc_mempool_disable_lock(p_dev_ctl); + mp = &binfo->fc_memseg[seg]; + + if ((low = (!(arg & MEM_PRI) && (mp->fc_free <= mp->fc_lowmem)))) { + /* Memory Buffer Pool is below low water mark */ + fc_log_printf_msg_vargs( binfo->fc_brd_no, + &fc_msgBlk0406, /* ptr to msg structure */ + fc_mes0406, /* ptr to msg */ + fc_msgBlk0406.msgPreambleStr, /* begin varargs */ + seg, + mp->fc_lowmem, + low); /* end varargs */ + /* Low priority request and not enough buffers, so fail */ + lpfc_mempool_unlock_enable(p_dev_ctl, iflag); + return((uchar * )0); + } + + bp = mp->fc_memptr; + + if (bp) { + if(((ulong)bp > (ulong)(mp->fc_memhi)) || ((ulong)bp < (ulong)(mp->fc_memlo))) { + /* Memory Buffer Pool is corrupted */ + fc_log_printf_msg_vargs( binfo->fc_brd_no, + &fc_msgBlk0407, /* ptr to msg structure */ + fc_mes0407, /* ptr to msg */ + fc_msgBlk0407.msgPreambleStr, /* begin varargs */ + seg, + (ulong)bp, + (ulong)mp->fc_memhi, + (ulong)mp->fc_memlo); /* end varargs */ + mp->fc_memptr = 0; + lpfc_mempool_unlock_enable(p_dev_ctl, iflag); + return((uchar * )0); + } + + /* If a memory block exists, take it off freelist + * and return it to the user. + */ + if(mp->fc_endmemptr == bp) { + mp->fc_endmemptr = 0; + } + mp->fc_memptr = *((uchar * *)bp); + *((uchar * *)bp) = 0; + mp->fc_free--; + } else { + /* Memory Buffer Pool is out of buffers */ + fc_log_printf_msg_vargs( binfo->fc_brd_no, + &fc_msgBlk0409, /* ptr to msg structure */ + fc_mes0409, /* ptr to msg */ + fc_msgBlk0409.msgPreambleStr, /* begin varargs */ + seg, + mp->fc_free, + binfo->fc_mbox.q_cnt, + (ulong)(mp->fc_memhi)); /* end varargs */ + FCSTATCTR.memAllocErr++; + } + + if (seg == MEM_NLP) { + /* GET nodelist */ + fc_log_printf_msg_vargs( binfo->fc_brd_no, + &fc_msgBlk0927, /* ptr to msg structure */ + fc_mes0927, /* ptr to msg */ + fc_msgBlk0927.msgPreambleStr, /* begin varargs */ + (ulong)bp, + mp->fc_free); /* end varargs */ + } + + lpfc_mempool_unlock_enable(p_dev_ctl, iflag); + return(bp); +} /* End fc_mem_get */ + + +/**************************************************/ +/** fc_mem_put **/ +/** **/ +/** This routine will put a memory buffer back **/ +/** on the freelist. **/ +/** seg identifies which buffer pool to use. **/ +/**************************************************/ +_static_ uchar * +fc_mem_put( +FC_BRD_INFO *binfo, +uint32 seg, +uchar *bp) +{ + MEMSEG * mp; + uchar * oldbp; + fc_dev_ctl_t *p_dev_ctl; + unsigned long iflag; + /* range check on seg argument */ + if (seg >= FC_MAX_SEG) + return((uchar * )0); + + p_dev_ctl = (fc_dev_ctl_t *)binfo->fc_p_dev_ctl; + iflag = lpfc_mempool_disable_lock(p_dev_ctl); + mp = &binfo->fc_memseg[seg]; + + if (bp) { + + if(((ulong)bp > (ulong)(mp->fc_memhi)) || ((ulong)bp < (ulong)(mp->fc_memlo))) { + /* Memory Buffer Pool is corrupted */ + fc_log_printf_msg_vargs( binfo->fc_brd_no, + &fc_msgBlk0408, /* ptr to msg structure */ + fc_mes0408, /* ptr to msg */ + fc_msgBlk0408.msgPreambleStr, /* begin varargs */ + seg, + (ulong)bp, + (ulong)mp->fc_memhi, + (ulong)mp->fc_memlo); /* end varargs */ + lpfc_mempool_unlock_enable(p_dev_ctl, iflag); + return((uchar * )0); + } + /* If a memory block exists, put it on freelist + * and return it to the user. + */ + oldbp = mp->fc_memptr; + mp->fc_memptr = bp; + *((uchar * *)bp) = oldbp; + if(oldbp == 0) + mp->fc_endmemptr = bp; + mp->fc_free++; + } + + if (seg == MEM_NLP) { + /* PUT nodelist */ + fc_log_printf_msg_vargs( binfo->fc_brd_no, + &fc_msgBlk0928, /* ptr to msg structure */ + fc_mes0928, /* ptr to msg */ + fc_msgBlk0928.msgPreambleStr, /* begin varargs */ + (ulong)bp, + mp->fc_free); /* end varargs */ + } + + lpfc_mempool_unlock_enable(p_dev_ctl, iflag); + return(bp); +} /* End fc_mem_put */ + + +/* Look up the virtual address given a mapped address */ +_static_ MATCHMAP * +fc_getvaddr( +fc_dev_ctl_t *p_dev_ctl, +RING *rp, +uchar *mapbp) +{ + FC_BRD_INFO * binfo; + + binfo = &BINFO; + /* While there are available slots in the list */ + if (rp->fc_ringno == FC_ELS_RING) { + MATCHMAP * mp; + MATCHMAP * mpoff; + + mpoff = (MATCHMAP * )rp->fc_mpoff; + mp = 0; + + while (mpoff) { + /* Check for a match */ + if (mpoff->phys == mapbp) { + /* If we matched on the first slot */ + if (mp == 0) { + rp->fc_mpoff = mpoff->fc_mptr; + } else { + mp->fc_mptr = mpoff->fc_mptr; + } + + if (rp->fc_mpon == (uchar * )mpoff) { + rp->fc_mpon = (uchar * )mp; + } + rp->fc_bufcnt--; + mpoff->fc_mptr = 0; + + fc_mpdata_sync(mpoff->dma_handle, 0, 0, DDI_DMA_SYNC_FORKERNEL); + + /* Return entry */ + return(mpoff); + } + mp = mpoff; + mpoff = (MATCHMAP * )mpoff->fc_mptr; + } + } + + if (rp->fc_ringno == FC_IP_RING) { + fcipbuf_t * mb; + fcipbuf_t * mboff; + + mboff = (fcipbuf_t * )rp->fc_mpoff; + mb = 0; + + while (mboff) { + /* Check for a match */ + if (fcnextpkt(mboff) == (fcipbuf_t * )mapbp) { + /* If we matched on the first slot */ + if (mb == 0) { + rp->fc_mpoff = (uchar * )fcnextdata(mboff); + } else { + fcnextdata(mb) = fcnextdata(mboff); + } + + if (rp->fc_mpon == (uchar * )mboff) { + rp->fc_mpon = (uchar * )mb; + } + rp->fc_bufcnt--; + + if (fcnextpkt(mboff)) { + MBUF_INFO * buf_info; + MBUF_INFO bufinfo; + + buf_info = &bufinfo; + buf_info->dma_handle = (ulong * )fcgethandle(mboff); + if (buf_info->dma_handle) { + fc_mpdata_sync(buf_info->dma_handle, 0, 0, + DDI_DMA_SYNC_FORKERNEL); + } + buf_info->virt = 0; + buf_info->flags = (FC_MBUF_PHYSONLY | FC_MBUF_DMA); + buf_info->phys = (uint32 * )fcnextpkt(mboff); + buf_info->size = fcPAGESIZE; + fc_free(p_dev_ctl, buf_info); + } + + fcsethandle(mboff, 0); + fcnextpkt(mboff) = 0; + fcnextdata(mboff) = 0; + /* Return entry */ + return((MATCHMAP * )mboff); + } + mb = mboff; + mboff = (fcipbuf_t * )fcnextdata(mboff); + } + } + /* Cannot find virtual addr for mapped buf on ring (num) */ + fc_log_printf_msg_vargs( binfo->fc_brd_no, + &fc_msgBlk0410, /* ptr to msg structure */ + fc_mes0410, /* ptr to msg */ + fc_msgBlk0410.msgPreambleStr, /* begin varargs */ + rp->fc_ringno, + (ulong)mapbp, + (ulong)rp->fc_mpoff, + (ulong)rp->fc_mpon); /* end varargs */ + FCSTATCTR.noVirtPtr++; + return(0); +} /* End fc_getvaddr */ + + +/* Given a virtual address, bp, generate the physical mapped address + * and place it where addr points to. Save the address pair for lookup later. + */ +_static_ void +fc_mapvaddr( +FC_BRD_INFO *binfo, +RING *rp, +MATCHMAP *mp, +uint32 *haddr, +uint32 *laddr) +{ + fcipbuf_t * mbuf; + + switch (rp->fc_ringno) { + case FC_ELS_RING: + mp->fc_mptr = 0; + /* Update slot fc_mpon points to then bump it */ + if (rp->fc_mpoff == 0) { + rp->fc_mpoff = (uchar * )mp; + rp->fc_mpon = (uchar * )mp; + } else { + ((MATCHMAP * )(rp->fc_mpon))->fc_mptr = (uchar * )mp; + rp->fc_mpon = (uchar * )mp; + } + if (binfo->fc_flag & FC_SLI2) { + *haddr = (uint32)putPaddrHigh(mp->phys); /* return mapped address */ + *laddr = (uint32)putPaddrLow(mp->phys); /* return mapped address */ + } else { + *laddr = (uint32)putPaddrLow(mp->phys); /* return mapped address */ + } + break; + + case FC_IP_RING: + mbuf = (fcipbuf_t * )mp; + fcnextdata(mbuf) = 0; + /* Update slot fc_mpon points to then bump it */ + if (rp->fc_mpoff == 0) { + rp->fc_mpoff = (uchar * )mbuf; + rp->fc_mpon = (uchar * )mbuf; + } else { + fcnextdata((fcipbuf_t * )(rp->fc_mpon)) = mbuf; + rp->fc_mpon = (uchar * )mbuf; + } + if (binfo->fc_flag & FC_SLI2) { + *haddr = (uint32)putPaddrHigh(fcnextpkt(mbuf)); + *laddr = (uint32)putPaddrLow(fcnextpkt(mbuf)); + } else { + *laddr = (uint32)putPaddrLow(fcnextpkt(mbuf)); + } + break; + } + + rp->fc_bufcnt++; + return; +} /* End fc_mapvaddr */ + + + diff -purN -X /home/mbligh/.diff.exclude 350-autoswap/drivers/scsi/lpfc/fcmsg.h 370-emulex/drivers/scsi/lpfc/fcmsg.h --- 350-autoswap/drivers/scsi/lpfc/fcmsg.h 1969-12-31 16:00:00.000000000 -0800 +++ 370-emulex/drivers/scsi/lpfc/fcmsg.h 2004-02-28 11:20:03.000000000 -0800 @@ -0,0 +1,1082 @@ +/******************************************************************* + * This file is part of the Emulex Linux Device Driver for * + * Enterprise Fibre Channel Host Bus Adapters. * + * Refer to the README file included with this package for * + * driver version and adapter support. * + * Copyright (C) 2003 Emulex Corporation. * + * www.emulex.com * + * * + * This program is free software; you can redistribute it and/or * + * modify it under the terms of the GNU General Public License * + * as published by the Free Software Foundation; either version 2 * + * of the License, or (at your option) any later version. * + * * + * This program is distributed in the hope that it will be useful, * + * but WITHOUT ANY WARRANTY; without even the implied warranty of * + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * + * GNU General Public License for more details, a copy of which * + * can be found in the file COPYING included with this package. * + *******************************************************************/ + +#ifndef _H_FCMSG +#define _H_FCMSG + +/* + * LOG Message Group Numbering Sequence + * + * Message Group Preamble From To + * String + * + * ELS ELx 100 199 + * DISCOVERY DIx 200 299 + * MBOX MBx 300 399 + * INIT INx 400 499 + * Unused 500 599 + * IP IPx 600 699 + * FCP FPx 700 799 + * Unused 800 899 + * NODE NDx 900 999 + * MISC MIx 1200 1299 + * LINK LKx 1300 1399 + * SLI SLx 1400 1499 + * CHK_CONDITION CKx 1500 1599 + */ + +/* + * Log Message Structure + * + * The following structure supports LOG messages only. + * Every LOG message is associated to a msgBlkLogDef structure of the + * following type. + */ + +typedef struct msgLogType { + int msgNum; /* Message number */ + char * msgStr; /* Ptr to log message */ + char * msgPreambleStr; /* Ptr to log message preamble */ + int msgOutput; /* Message output target - bitmap */ + /* + * This member controls message OUTPUT. + * + * The phase 'global controls' refers to user configurable parameters + * such as LOG_VERBOSE that control message output on a global basis. + */ + +#define FC_MSG_OPUT_GLOB_CTRL 0x0 /* Use global control */ +#define FC_MSG_OPUT_DISA 0x1 /* Override global control */ +#define FC_MSG_OPUT_FORCE 0x2 /* Override global control */ + int msgType; /* Message LOG type - bitmap */ +#define FC_LOG_MSG_TYPE_INFO 0x1 /* Maskable */ +#define FC_LOG_MSG_TYPE_WARN 0x2 /* Non-Maskable */ +#define FC_LOG_MSG_TYPE_ERR_CFG 0x4 /* Non-Maskable */ +#define FC_LOG_MSG_TYPE_ERR 0x8 /* Non-Maskable */ +#define FC_LOG_MSG_TYPE_PANIC 0x10 /* Non-Maskable */ + int msgMask; /* Message LOG mask - bitmap */ + /* + * NOTE: Only LOG messages of types MSG_TYPE_WARN & MSG_TYPE_INFO are + * maskable at the GLOBAL level. + * + * Any LOG message regardless of message type can be disabled (override verbose) + * at the msgBlkLogDef struct level my setting member msgOutput = FC_MSG_OPUT_DISA. + * The message will never be displayed regardless of verbose mask. + * + * Any LOG message regardless of message type can be enable (override verbose) + * at the msgBlkLogDef struct level my setting member msgOutput = FC_MSG_OPUT_FORCE. + * The message will always be displayed regardless of verbose mask. + */ +#define LOG_ELS 0x1 /* ELS events */ +#define LOG_DISCOVERY 0x2 /* Link discovery events */ +#define LOG_MBOX 0x4 /* Mailbox events */ +#define LOG_INIT 0x8 /* Initialization events */ +#define LOG_LINK_EVENT 0x10 /* Link events */ +#define LOG_IP 0x20 /* IP traffic history */ +#define LOG_FCP 0x40 /* FCP traffic history */ +#define LOG_NODE 0x80 /* Node table events */ +#define LOG_MISC 0x400 /* Miscellaneous events */ +#define LOG_SLI 0x800 /* SLI events */ +#define LOG_CHK_COND 0x1000 /* FCP Check condition flag */ +#define LOG_ALL_MSG 0x1fff /* LOG all messages */ + unsigned int msgLogID; /* Message LOG ID */ +#define ERRID_LOG_TIMEOUT 0xfdefefa7 /* Fibre Channel timeout */ +#define ERRID_LOG_HDW_ERR 0x1ae4fffc /* Fibre Channel hardware failure */ +#define ERRID_LOG_UNEXPECT_EVENT 0xbdb7e728 /* Fibre Channel unexpected event */ +#define ERRID_LOG_INIT 0xbe1043b8 /* Fibre Channel init failure */ +#define ERRID_LOG_NO_RESOURCE 0x474c1775 /* Fibre Channel no resources */ + } msgLogDef; + +/* + * External Declarations for LOG Messages + */ + +/* ELS LOG Messages */ +extern char fc_mes0100[]; +extern char fc_mes0101[]; +extern char fc_mes0102[]; +extern char fc_mes0103[]; +extern char fc_mes0104[]; +extern char fc_mes0105[]; +extern char fc_mes0106[]; +extern char fc_mes0107[]; +extern char fc_mes0108[]; +extern char fc_mes0109[]; +extern char fc_mes0110[]; +extern char fc_mes0111[]; +extern char fc_mes0112[]; +extern char fc_mes0113[]; +extern char fc_mes0114[]; +extern char fc_mes0115[]; +extern char fc_mes0116[]; +extern char fc_mes0117[]; +extern char fc_mes0118[]; +extern char fc_mes0119[]; +extern char fc_mes0120[]; +extern char fc_mes0121[]; +extern char fc_mes0122[]; +extern char fc_mes0123[]; +extern char fc_mes0124[]; +extern char fc_mes0125[]; +extern char fc_mes0126[]; +extern char fc_mes0127[]; +extern char fc_mes0128[]; +extern char fc_mes0129[]; +extern char fc_mes0130[]; +extern char fc_mes0131[]; +extern char fc_mes0132[]; +extern char fc_mes0133[]; +extern char fc_mes0134[]; +extern char fc_mes0135[]; +extern char fc_mes0136[]; + +/* DISCOVERY LOG Messages */ +extern char fc_mes0200[]; +extern char fc_mes0201[]; +extern char fc_mes0202[]; +extern char fc_mes0203[]; +extern char fc_mes0204[]; +extern char fc_mes0205[]; +extern char fc_mes0206[]; +extern char fc_mes0207[]; +extern char fc_mes0208[]; +extern char fc_mes0209[]; +extern char fc_mes0210[]; +extern char fc_mes0211[]; +extern char fc_mes0212[]; +extern char fc_mes0213[]; +extern char fc_mes0214[]; +extern char fc_mes0215[]; +extern char fc_mes0216[]; +extern char fc_mes0217[]; +extern char fc_mes0218[]; +extern char fc_mes0219[]; +extern char fc_mes0220[]; +extern char fc_mes0221[]; +extern char fc_mes0222[]; +extern char fc_mes0223[]; +extern char fc_mes0224[]; +extern char fc_mes0225[]; +extern char fc_mes0226[]; +extern char fc_mes0227[]; +extern char fc_mes0228[]; +extern char fc_mes0229[]; +extern char fc_mes0230[]; +extern char fc_mes0231[]; +extern char fc_mes0232[]; +extern char fc_mes0233[]; +extern char fc_mes0234[]; +extern char fc_mes0235[]; +extern char fc_mes0236[]; +extern char fc_mes0237[]; +extern char fc_mes0238[]; +extern char fc_mes0239[]; +extern char fc_mes0240[]; +extern char fc_mes0241[]; +extern char fc_mes0242[]; +extern char fc_mes0243[]; +extern char fc_mes0244[]; +extern char fc_mes0245[]; +extern char fc_mes0246[]; +extern char fc_mes0247[]; +extern char fc_mes0248[]; +extern char fc_mes0249[]; +extern char fc_mes0250[]; +extern char fc_mes0251[]; +extern char fc_mes0252[]; + +/* MAILBOX LOG Messages */ +extern char fc_mes0300[]; +extern char fc_mes0301[]; +extern char fc_mes0302[]; +extern char fc_mes0303[]; +extern char fc_mes0304[]; +extern char fc_mes0305[]; +extern char fc_mes0306[]; +extern char fc_mes0307[]; +extern char fc_mes0308[]; +extern char fc_mes0309[]; +extern char fc_mes0310[]; +extern char fc_mes0311[]; +extern char fc_mes0312[]; + +/* INIT LOG Messages */ +extern char fc_mes0400[]; +extern char fc_mes0401[]; +extern char fc_mes0402[]; +extern char fc_mes0403[]; +extern char fc_mes0404[]; +extern char fc_mes0405[]; +extern char fc_mes0406[]; +extern char fc_mes0407[]; +extern char fc_mes0408[]; +extern char fc_mes0409[]; +extern char fc_mes0410[]; +extern char fc_mes0411[]; +extern char fc_mes0412[]; +extern char fc_mes0413[]; +extern char fc_mes0414[]; +extern char fc_mes0415[]; +extern char fc_mes0416[]; +extern char fc_mes0417[]; +extern char fc_mes0418[]; +extern char fc_mes0419[]; +extern char fc_mes0420[]; +extern char fc_mes0421[]; +extern char fc_mes0422[]; +extern char fc_mes0423[]; +extern char fc_mes0424[]; +extern char fc_mes0425[]; +extern char fc_mes0426[]; +extern char fc_mes0427[]; +extern char fc_mes0428[]; +extern char fc_mes0429[]; +extern char fc_mes0430[]; +extern char fc_mes0431[]; +extern char fc_mes0432[]; +extern char fc_mes0433[]; +extern char fc_mes0434[]; +extern char fc_mes0435[]; +extern char fc_mes0436[]; +extern char fc_mes0437[]; +extern char fc_mes0438[]; +extern char fc_mes0439[]; +extern char fc_mes0440[]; +extern char fc_mes0440[]; +extern char fc_mes0441[]; +extern char fc_mes0442[]; +extern char fc_mes0443[]; +extern char fc_mes0444[]; +extern char fc_mes0445[]; +extern char fc_mes0446[]; +extern char fc_mes0447[]; +extern char fc_mes0448[]; +extern char fc_mes0449[]; +extern char fc_mes0450[]; +extern char fc_mes0451[]; +extern char fc_mes0452[]; +extern char fc_mes0453[]; +extern char fc_mes0454[]; +extern char fc_mes0455[]; +extern char fc_mes0456[]; +extern char fc_mes0457[]; +extern char fc_mes0458[]; +extern char fc_mes0459[]; +extern char fc_mes0460[]; +extern char fc_mes0461[]; + +/* UNUSED */ +/* +extern char fc_mes0500[]; +*/ + +/* IP LOG Messages */ +extern char fc_mes0600[]; +extern char fc_mes0601[]; +extern char fc_mes0602[]; +extern char fc_mes0603[]; +extern char fc_mes0604[]; +extern char fc_mes0605[]; +extern char fc_mes0606[]; +extern char fc_mes0607[]; +extern char fc_mes0608[]; + +/* FCP LOG Messages */ +extern char fc_mes0700[]; +extern char fc_mes0701[]; +extern char fc_mes0702[]; +extern char fc_mes0703[]; +extern char fc_mes0704[]; +extern char fc_mes0705[]; +extern char fc_mes0706[]; +extern char fc_mes0707[]; +extern char fc_mes0708[]; +extern char fc_mes0709[]; +extern char fc_mes0710[]; +extern char fc_mes0711[]; +extern char fc_mes0712[]; +extern char fc_mes0713[]; +extern char fc_mes0714[]; +extern char fc_mes0715[]; +extern char fc_mes0716[]; +extern char fc_mes0717[]; +extern char fc_mes0718[]; +extern char fc_mes0719[]; +extern char fc_mes0720[]; +extern char fc_mes0721[]; +extern char fc_mes0722[]; +extern char fc_mes0723[]; +extern char fc_mes0724[]; +extern char fc_mes0725[]; +extern char fc_mes0726[]; +extern char fc_mes0727[]; +extern char fc_mes0728[]; +extern char fc_mes0729[]; +extern char fc_mes0730[]; +extern char fc_mes0731[]; +extern char fc_mes0732[]; +extern char fc_mes0733[]; +extern char fc_mes0734[]; +extern char fc_mes0735[]; +extern char fc_mes0736[]; +extern char fc_mes0737[]; +extern char fc_mes0738[]; +extern char fc_mes0739[]; +extern char fc_mes0740[]; +extern char fc_mes0741[]; +extern char fc_mes0742[]; +extern char fc_mes0743[]; +extern char fc_mes0744[]; +extern char fc_mes0745[]; +extern char fc_mes0746[]; +extern char fc_mes0747[]; +extern char fc_mes0748[]; +extern char fc_mes0749[]; +extern char fc_mes0750[]; +extern char fc_mes0751[]; +extern char fc_mes0752[]; +extern char fc_mes0753[]; +extern char fc_mes0754[]; +extern char fc_mes0756[]; + +/* UNUSED */ +/* +extern char fc_mes0800[]; +*/ + +/* NODE LOG Messages */ +extern char fc_mes0900[]; +extern char fc_mes0901[]; +extern char fc_mes0902[]; +extern char fc_mes0903[]; +extern char fc_mes0904[]; +extern char fc_mes0905[]; +extern char fc_mes0906[]; +extern char fc_mes0907[]; +extern char fc_mes0908[]; +extern char fc_mes0909[]; +extern char fc_mes0910[]; +extern char fc_mes0911[]; +extern char fc_mes0912[]; +extern char fc_mes0913[]; +extern char fc_mes0914[]; +extern char fc_mes0915[]; +extern char fc_mes0916[]; +extern char fc_mes0917[]; +extern char fc_mes0918[]; +extern char fc_mes0919[]; +extern char fc_mes0920[]; +extern char fc_mes0921[]; +extern char fc_mes0922[]; +extern char fc_mes0923[]; +extern char fc_mes0924[]; +extern char fc_mes0925[]; +extern char fc_mes0926[]; +extern char fc_mes0927[]; +extern char fc_mes0928[]; + + + +/* MISC LOG messages */ +extern char fc_mes1200[]; +extern char fc_mes1201[]; +extern char fc_mes1202[]; +extern char fc_mes1203[]; +extern char fc_mes1204[]; +extern char fc_mes1205[]; +extern char fc_mes1206[]; +extern char fc_mes1207[]; +extern char fc_mes1208[]; +extern char fc_mes1209[]; +extern char fc_mes1210[]; +extern char fc_mes1211[]; +extern char fc_mes1212[]; +extern char fc_mes1213[]; + +/* LINK LOG Messages */ +extern char fc_mes1300[]; +extern char fc_mes1301[]; +extern char fc_mes1302[]; +extern char fc_mes1303[]; +extern char fc_mes1304[]; +extern char fc_mes1305[]; +extern char fc_mes1306[]; +extern char fc_mes1307[]; + +/* SLI LOG Messages */ +extern char fc_mes1400[]; +extern char fc_mes1401[]; +extern char fc_mes1402[]; + +/* CHK CONDITION LOG Messages */ +/* +extern char fc_mes1500[]; +*/ + +/* + * External Declarations for LOG Message Structure msgBlkLogDef + */ + +/* ELS LOG Message Structures */ +extern msgLogDef fc_msgBlk0100; +extern msgLogDef fc_msgBlk0101; +extern msgLogDef fc_msgBlk0102; +extern msgLogDef fc_msgBlk0103; +extern msgLogDef fc_msgBlk0104; +extern msgLogDef fc_msgBlk0105; +extern msgLogDef fc_msgBlk0106; +extern msgLogDef fc_msgBlk0107; +extern msgLogDef fc_msgBlk0108; +extern msgLogDef fc_msgBlk0109; +extern msgLogDef fc_msgBlk0110; +extern msgLogDef fc_msgBlk0111; +extern msgLogDef fc_msgBlk0112; +extern msgLogDef fc_msgBlk0113; +extern msgLogDef fc_msgBlk0114; +extern msgLogDef fc_msgBlk0115; +extern msgLogDef fc_msgBlk0116; +extern msgLogDef fc_msgBlk0117; +extern msgLogDef fc_msgBlk0118; +extern msgLogDef fc_msgBlk0119; +extern msgLogDef fc_msgBlk0120; +extern msgLogDef fc_msgBlk0121; +extern msgLogDef fc_msgBlk0122; +extern msgLogDef fc_msgBlk0123; +extern msgLogDef fc_msgBlk0124; +extern msgLogDef fc_msgBlk0125; +extern msgLogDef fc_msgBlk0126; +extern msgLogDef fc_msgBlk0127; +extern msgLogDef fc_msgBlk0128; +extern msgLogDef fc_msgBlk0129; +extern msgLogDef fc_msgBlk0130; +extern msgLogDef fc_msgBlk0131; +extern msgLogDef fc_msgBlk0132; +extern msgLogDef fc_msgBlk0133; +extern msgLogDef fc_msgBlk0134; +extern msgLogDef fc_msgBlk0135; +extern msgLogDef fc_msgBlk0136; + +/* DISCOVERY LOG Message Structures */ +extern msgLogDef fc_msgBlk0200; +extern msgLogDef fc_msgBlk0201; +extern msgLogDef fc_msgBlk0202; +extern msgLogDef fc_msgBlk0203; +extern msgLogDef fc_msgBlk0204; +extern msgLogDef fc_msgBlk0205; +extern msgLogDef fc_msgBlk0206; +extern msgLogDef fc_msgBlk0207; +extern msgLogDef fc_msgBlk0208; +extern msgLogDef fc_msgBlk0209; +extern msgLogDef fc_msgBlk0210; +extern msgLogDef fc_msgBlk0211; +extern msgLogDef fc_msgBlk0212; +extern msgLogDef fc_msgBlk0213; +extern msgLogDef fc_msgBlk0214; +extern msgLogDef fc_msgBlk0215; +extern msgLogDef fc_msgBlk0216; +extern msgLogDef fc_msgBlk0217; +extern msgLogDef fc_msgBlk0218; +extern msgLogDef fc_msgBlk0219; +extern msgLogDef fc_msgBlk0220; +extern msgLogDef fc_msgBlk0221; +extern msgLogDef fc_msgBlk0222; +extern msgLogDef fc_msgBlk0223; +extern msgLogDef fc_msgBlk0224; +extern msgLogDef fc_msgBlk0225; +extern msgLogDef fc_msgBlk0226; +extern msgLogDef fc_msgBlk0227; +extern msgLogDef fc_msgBlk0228; +extern msgLogDef fc_msgBlk0229; +extern msgLogDef fc_msgBlk0230; +extern msgLogDef fc_msgBlk0231; +extern msgLogDef fc_msgBlk0232; +extern msgLogDef fc_msgBlk0233; +extern msgLogDef fc_msgBlk0234; +extern msgLogDef fc_msgBlk0235; +extern msgLogDef fc_msgBlk0236; +extern msgLogDef fc_msgBlk0237; +extern msgLogDef fc_msgBlk0238; +extern msgLogDef fc_msgBlk0239; +extern msgLogDef fc_msgBlk0240; +extern msgLogDef fc_msgBlk0241; +extern msgLogDef fc_msgBlk0242; +extern msgLogDef fc_msgBlk0243; +extern msgLogDef fc_msgBlk0244; +extern msgLogDef fc_msgBlk0245; +extern msgLogDef fc_msgBlk0246; +extern msgLogDef fc_msgBlk0247; +extern msgLogDef fc_msgBlk0248; +extern msgLogDef fc_msgBlk0249; +extern msgLogDef fc_msgBlk0250; +extern msgLogDef fc_msgBlk0251; +extern msgLogDef fc_msgBlk0252; + +/* MAILBOX LOG Message Structures */ +extern msgLogDef fc_msgBlk0300; +extern msgLogDef fc_msgBlk0301; +extern msgLogDef fc_msgBlk0302; +extern msgLogDef fc_msgBlk0303; +extern msgLogDef fc_msgBlk0304; +extern msgLogDef fc_msgBlk0305; +extern msgLogDef fc_msgBlk0306; +extern msgLogDef fc_msgBlk0307; +extern msgLogDef fc_msgBlk0308; +extern msgLogDef fc_msgBlk0309; +extern msgLogDef fc_msgBlk0310; +extern msgLogDef fc_msgBlk0311; +extern msgLogDef fc_msgBlk0312; + +/* INIT LOG Message Structures */ +extern msgLogDef fc_msgBlk0400; +extern msgLogDef fc_msgBlk0401; +extern msgLogDef fc_msgBlk0402; +extern msgLogDef fc_msgBlk0403; +extern msgLogDef fc_msgBlk0404; +extern msgLogDef fc_msgBlk0405; +extern msgLogDef fc_msgBlk0406; +extern msgLogDef fc_msgBlk0407; +extern msgLogDef fc_msgBlk0408; +extern msgLogDef fc_msgBlk0409; +extern msgLogDef fc_msgBlk0410; +extern msgLogDef fc_msgBlk0411; +extern msgLogDef fc_msgBlk0412; +extern msgLogDef fc_msgBlk0413; +extern msgLogDef fc_msgBlk0414; +extern msgLogDef fc_msgBlk0415; +extern msgLogDef fc_msgBlk0416; +extern msgLogDef fc_msgBlk0417; +extern msgLogDef fc_msgBlk0418; +extern msgLogDef fc_msgBlk0419; +extern msgLogDef fc_msgBlk0420; +extern msgLogDef fc_msgBlk0421; +extern msgLogDef fc_msgBlk0422; +extern msgLogDef fc_msgBlk0423; +extern msgLogDef fc_msgBlk0424; +extern msgLogDef fc_msgBlk0425; +extern msgLogDef fc_msgBlk0426; +extern msgLogDef fc_msgBlk0427; +extern msgLogDef fc_msgBlk0428; +extern msgLogDef fc_msgBlk0429; +extern msgLogDef fc_msgBlk0430; +extern msgLogDef fc_msgBlk0431; +extern msgLogDef fc_msgBlk0432; +extern msgLogDef fc_msgBlk0433; +extern msgLogDef fc_msgBlk0434; +extern msgLogDef fc_msgBlk0435; +extern msgLogDef fc_msgBlk0436; +extern msgLogDef fc_msgBlk0437; +extern msgLogDef fc_msgBlk0438; +extern msgLogDef fc_msgBlk0439; +extern msgLogDef fc_msgBlk0440; +extern msgLogDef fc_msgBlk0441; +extern msgLogDef fc_msgBlk0442; +extern msgLogDef fc_msgBlk0443; +extern msgLogDef fc_msgBlk0444; +extern msgLogDef fc_msgBlk0445; +extern msgLogDef fc_msgBlk0446; +extern msgLogDef fc_msgBlk0447; +extern msgLogDef fc_msgBlk0448; +extern msgLogDef fc_msgBlk0449; +extern msgLogDef fc_msgBlk0450; +extern msgLogDef fc_msgBlk0451; +extern msgLogDef fc_msgBlk0452; +extern msgLogDef fc_msgBlk0453; +extern msgLogDef fc_msgBlk0454; +extern msgLogDef fc_msgBlk0455; +extern msgLogDef fc_msgBlk0456; +extern msgLogDef fc_msgBlk0457; +extern msgLogDef fc_msgBlk0458; +extern msgLogDef fc_msgBlk0459; +extern msgLogDef fc_msgBlk0460; +extern msgLogDef fc_msgBlk0461; + +/* UNUSED */ +/* +extern msgLogDef fc_msgBlk0500; +*/ + +/* IP LOG Message Structures */ +extern msgLogDef fc_msgBlk0600; +extern msgLogDef fc_msgBlk0601; +extern msgLogDef fc_msgBlk0602; +extern msgLogDef fc_msgBlk0603; +extern msgLogDef fc_msgBlk0604; +extern msgLogDef fc_msgBlk0605; +extern msgLogDef fc_msgBlk0606; +extern msgLogDef fc_msgBlk0607; +extern msgLogDef fc_msgBlk0608; + +/* FCP LOG Message Structures */ +extern msgLogDef fc_msgBlk0700; +extern msgLogDef fc_msgBlk0701; +extern msgLogDef fc_msgBlk0702; +extern msgLogDef fc_msgBlk0703; +extern msgLogDef fc_msgBlk0704; +extern msgLogDef fc_msgBlk0705; +extern msgLogDef fc_msgBlk0706; +extern msgLogDef fc_msgBlk0707; +extern msgLogDef fc_msgBlk0708; +extern msgLogDef fc_msgBlk0709; +extern msgLogDef fc_msgBlk0710; +extern msgLogDef fc_msgBlk0711; +extern msgLogDef fc_msgBlk0712; +extern msgLogDef fc_msgBlk0713; +extern msgLogDef fc_msgBlk0714; +extern msgLogDef fc_msgBlk0715; +extern msgLogDef fc_msgBlk0716; +extern msgLogDef fc_msgBlk0717; +extern msgLogDef fc_msgBlk0718; +extern msgLogDef fc_msgBlk0719; +extern msgLogDef fc_msgBlk0720; +extern msgLogDef fc_msgBlk0721; +extern msgLogDef fc_msgBlk0722; +extern msgLogDef fc_msgBlk0723; +extern msgLogDef fc_msgBlk0724; +extern msgLogDef fc_msgBlk0725; +extern msgLogDef fc_msgBlk0726; +extern msgLogDef fc_msgBlk0727; +extern msgLogDef fc_msgBlk0728; +extern msgLogDef fc_msgBlk0729; +extern msgLogDef fc_msgBlk0730; +extern msgLogDef fc_msgBlk0731; +extern msgLogDef fc_msgBlk0732; +extern msgLogDef fc_msgBlk0733; +extern msgLogDef fc_msgBlk0734; +extern msgLogDef fc_msgBlk0735; +extern msgLogDef fc_msgBlk0736; +extern msgLogDef fc_msgBlk0737; +extern msgLogDef fc_msgBlk0738; +extern msgLogDef fc_msgBlk0739; +extern msgLogDef fc_msgBlk0740; +extern msgLogDef fc_msgBlk0741; +extern msgLogDef fc_msgBlk0742; +extern msgLogDef fc_msgBlk0743; +extern msgLogDef fc_msgBlk0744; +extern msgLogDef fc_msgBlk0745; +extern msgLogDef fc_msgBlk0746; +extern msgLogDef fc_msgBlk0747; +extern msgLogDef fc_msgBlk0748; +extern msgLogDef fc_msgBlk0749; +extern msgLogDef fc_msgBlk0750; +extern msgLogDef fc_msgBlk0751; +extern msgLogDef fc_msgBlk0752; +extern msgLogDef fc_msgBlk0753; +extern msgLogDef fc_msgBlk0754; +extern msgLogDef fc_msgBlk0756; + +/* UNUSED */ +/* +extern msgLogDef fc_msgBlk0800; +*/ + +/* NODE LOG Message Structures */ +extern msgLogDef fc_msgBlk0900; +extern msgLogDef fc_msgBlk0901; +extern msgLogDef fc_msgBlk0902; +extern msgLogDef fc_msgBlk0903; +extern msgLogDef fc_msgBlk0904; +extern msgLogDef fc_msgBlk0905; +extern msgLogDef fc_msgBlk0906; +extern msgLogDef fc_msgBlk0907; +extern msgLogDef fc_msgBlk0908; +extern msgLogDef fc_msgBlk0909; +extern msgLogDef fc_msgBlk0910; +extern msgLogDef fc_msgBlk0911; +extern msgLogDef fc_msgBlk0912; +extern msgLogDef fc_msgBlk0913; +extern msgLogDef fc_msgBlk0914; +extern msgLogDef fc_msgBlk0915; +extern msgLogDef fc_msgBlk0916; +extern msgLogDef fc_msgBlk0917; +extern msgLogDef fc_msgBlk0918; +extern msgLogDef fc_msgBlk0919; +extern msgLogDef fc_msgBlk0920; +extern msgLogDef fc_msgBlk0921; +extern msgLogDef fc_msgBlk0922; +extern msgLogDef fc_msgBlk0923; +extern msgLogDef fc_msgBlk0924; +extern msgLogDef fc_msgBlk0925; +extern msgLogDef fc_msgBlk0926; +extern msgLogDef fc_msgBlk0927; +extern msgLogDef fc_msgBlk0928; + + + +/* MISC LOG Message Structures */ +extern msgLogDef fc_msgBlk1200; +extern msgLogDef fc_msgBlk1201; +extern msgLogDef fc_msgBlk1202; +extern msgLogDef fc_msgBlk1203; +extern msgLogDef fc_msgBlk1204; +extern msgLogDef fc_msgBlk1205; +extern msgLogDef fc_msgBlk1206; +extern msgLogDef fc_msgBlk1207; +extern msgLogDef fc_msgBlk1208; +extern msgLogDef fc_msgBlk1209; +extern msgLogDef fc_msgBlk1210; +extern msgLogDef fc_msgBlk1211; +extern msgLogDef fc_msgBlk1212; +extern msgLogDef fc_msgBlk1213; + +/* LINK LOG Message Structures */ +extern msgLogDef fc_msgBlk1300; +extern msgLogDef fc_msgBlk1301; +extern msgLogDef fc_msgBlk1302; +extern msgLogDef fc_msgBlk1303; +extern msgLogDef fc_msgBlk1304; +extern msgLogDef fc_msgBlk1305; +extern msgLogDef fc_msgBlk1306; +extern msgLogDef fc_msgBlk1307; + +/* SLI LOG Message Structures */ +extern msgLogDef fc_msgBlk1400; +extern msgLogDef fc_msgBlk1401; +extern msgLogDef fc_msgBlk1402; + +/* CHK CONDITION LOG Message Structures */ +/* +extern msgLogDef fc_msgBlk1500; +*/ + +/* + * LOG Messages Numbers + */ + +/* ELS LOG Message Numbers */ +#define FC_LOG_MSG_EL_0100 100 +#define FC_LOG_MSG_EL_0101 101 +#define FC_LOG_MSG_EL_0102 102 +#define FC_LOG_MSG_EL_0103 103 +#define FC_LOG_MSG_EL_0104 104 +#define FC_LOG_MSG_EL_0105 105 +#define FC_LOG_MSG_EL_0106 106 +#define FC_LOG_MSG_EL_0107 107 +#define FC_LOG_MSG_EL_0108 108 +#define FC_LOG_MSG_EL_0109 109 +#define FC_LOG_MSG_EL_0110 110 +#define FC_LOG_MSG_EL_0111 111 +#define FC_LOG_MSG_EL_0112 112 +#define FC_LOG_MSG_EL_0113 113 +#define FC_LOG_MSG_EL_0114 114 +#define FC_LOG_MSG_EL_0115 115 +#define FC_LOG_MSG_EL_0116 116 +#define FC_LOG_MSG_EL_0117 117 +#define FC_LOG_MSG_EL_0118 118 +#define FC_LOG_MSG_EL_0119 119 +#define FC_LOG_MSG_EL_0120 120 +#define FC_LOG_MSG_EL_0121 121 +#define FC_LOG_MSG_EL_0122 122 +#define FC_LOG_MSG_EL_0123 123 +#define FC_LOG_MSG_EL_0124 124 +#define FC_LOG_MSG_EL_0125 125 +#define FC_LOG_MSG_EL_0126 126 +#define FC_LOG_MSG_EL_0127 127 +#define FC_LOG_MSG_EL_0128 128 +#define FC_LOG_MSG_EL_0129 129 +#define FC_LOG_MSG_EL_0130 130 +#define FC_LOG_MSG_EL_0131 131 +#define FC_LOG_MSG_EL_0132 132 +#define FC_LOG_MSG_EL_0133 133 +#define FC_LOG_MSG_EL_0134 134 +#define FC_LOG_MSG_EL_0135 135 +#define FC_LOG_MSG_EL_0136 136 + +/* DISCOVERY LOG Message Numbers */ +#define FC_LOG_MSG_DI_0200 200 +#define FC_LOG_MSG_DI_0201 201 +#define FC_LOG_MSG_DI_0202 202 +#define FC_LOG_MSG_DI_0203 203 +#define FC_LOG_MSG_DI_0204 204 +#define FC_LOG_MSG_DI_0205 205 +#define FC_LOG_MSG_DI_0206 206 +#define FC_LOG_MSG_DI_0207 207 +#define FC_LOG_MSG_DI_0208 208 +#define FC_LOG_MSG_DI_0209 209 +#define FC_LOG_MSG_DI_0210 210 +#define FC_LOG_MSG_DI_0211 211 +#define FC_LOG_MSG_DI_0212 212 +#define FC_LOG_MSG_DI_0213 213 +#define FC_LOG_MSG_DI_0214 214 +#define FC_LOG_MSG_DI_0215 215 +#define FC_LOG_MSG_DI_0216 216 +#define FC_LOG_MSG_DI_0217 217 +#define FC_LOG_MSG_DI_0218 218 +#define FC_LOG_MSG_DI_0219 219 +#define FC_LOG_MSG_DI_0220 220 +#define FC_LOG_MSG_DI_0221 221 +#define FC_LOG_MSG_DI_0222 222 +#define FC_LOG_MSG_DI_0223 223 +#define FC_LOG_MSG_DI_0224 224 +#define FC_LOG_MSG_DI_0225 225 +#define FC_LOG_MSG_DI_0226 226 +#define FC_LOG_MSG_DI_0227 227 +#define FC_LOG_MSG_DI_0228 228 +#define FC_LOG_MSG_DI_0229 229 +#define FC_LOG_MSG_DI_0230 230 +#define FC_LOG_MSG_DI_0231 231 +#define FC_LOG_MSG_DI_0232 232 +#define FC_LOG_MSG_DI_0233 233 +#define FC_LOG_MSG_DI_0234 234 +#define FC_LOG_MSG_DI_0235 235 +#define FC_LOG_MSG_DI_0236 236 +#define FC_LOG_MSG_DI_0237 237 +#define FC_LOG_MSG_DI_0238 238 +#define FC_LOG_MSG_DI_0239 239 +#define FC_LOG_MSG_DI_0240 240 +#define FC_LOG_MSG_DI_0241 241 +#define FC_LOG_MSG_DI_0242 242 +#define FC_LOG_MSG_DI_0243 243 +#define FC_LOG_MSG_DI_0244 244 +#define FC_LOG_MSG_DI_0245 245 +#define FC_LOG_MSG_DI_0246 246 +#define FC_LOG_MSG_DI_0247 247 +#define FC_LOG_MSG_DI_0248 248 +#define FC_LOG_MSG_DI_0249 249 +#define FC_LOG_MSG_DI_0250 250 +#define FC_LOG_MSG_DI_0251 251 +#define FC_LOG_MSG_DI_0252 252 + +/* MAILBOX LOG Message Numbers */ +#define FC_LOG_MSG_MB_0300 300 +#define FC_LOG_MSG_MB_0301 301 +#define FC_LOG_MSG_MB_0302 302 +#define FC_LOG_MSG_MB_0303 303 +#define FC_LOG_MSG_MB_0304 304 +#define FC_LOG_MSG_MB_0305 305 +#define FC_LOG_MSG_MB_0306 306 +#define FC_LOG_MSG_MB_0307 307 +#define FC_LOG_MSG_MB_0308 308 +#define FC_LOG_MSG_MB_0309 309 +#define FC_LOG_MSG_MB_0310 310 +#define FC_LOG_MSG_MB_0311 311 +#define FC_LOG_MSG_MB_0312 312 + +/* INIT LOG Message Numbers */ +#define FC_LOG_MSG_IN_0400 400 +#define FC_LOG_MSG_IN_0401 401 +#define FC_LOG_MSG_IN_0402 402 +#define FC_LOG_MSG_IN_0403 403 +#define FC_LOG_MSG_IN_0404 404 +#define FC_LOG_MSG_IN_0405 405 +#define FC_LOG_MSG_IN_0406 406 +#define FC_LOG_MSG_IN_0407 407 +#define FC_LOG_MSG_IN_0408 408 +#define FC_LOG_MSG_IN_0409 409 +#define FC_LOG_MSG_IN_0410 410 +#define FC_LOG_MSG_IN_0411 411 +#define FC_LOG_MSG_IN_0412 412 +#define FC_LOG_MSG_IN_0413 413 +#define FC_LOG_MSG_IN_0414 414 +#define FC_LOG_MSG_IN_0415 415 +#define FC_LOG_MSG_IN_0416 416 +#define FC_LOG_MSG_IN_0417 417 +#define FC_LOG_MSG_IN_0418 418 +#define FC_LOG_MSG_IN_0419 419 +#define FC_LOG_MSG_IN_0420 420 +#define FC_LOG_MSG_IN_0421 421 +#define FC_LOG_MSG_IN_0422 422 +#define FC_LOG_MSG_IN_0423 423 +#define FC_LOG_MSG_IN_0424 424 +#define FC_LOG_MSG_IN_0425 425 +#define FC_LOG_MSG_IN_0426 426 +#define FC_LOG_MSG_IN_0427 427 +#define FC_LOG_MSG_IN_0428 428 +#define FC_LOG_MSG_IN_0429 429 +#define FC_LOG_MSG_IN_0430 430 +#define FC_LOG_MSG_IN_0431 431 +#define FC_LOG_MSG_IN_0432 432 +#define FC_LOG_MSG_IN_0433 433 +#define FC_LOG_MSG_IN_0434 434 +#define FC_LOG_MSG_IN_0435 435 +#define FC_LOG_MSG_IN_0436 436 +#define FC_LOG_MSG_IN_0437 437 +#define FC_LOG_MSG_IN_0438 438 +#define FC_LOG_MSG_IN_0439 439 +#define FC_LOG_MSG_IN_0440 440 +#define FC_LOG_MSG_IN_0441 441 +#define FC_LOG_MSG_IN_0442 442 +#define FC_LOG_MSG_IN_0443 443 +#define FC_LOG_MSG_IN_0444 444 +#define FC_LOG_MSG_IN_0445 445 +#define FC_LOG_MSG_IN_0446 446 +#define FC_LOG_MSG_IN_0447 447 +#define FC_LOG_MSG_IN_0448 448 +#define FC_LOG_MSG_IN_0449 449 +#define FC_LOG_MSG_IN_0450 450 +#define FC_LOG_MSG_IN_0451 451 +#define FC_LOG_MSG_IN_0452 452 +#define FC_LOG_MSG_IN_0453 453 +#define FC_LOG_MSG_IN_0454 454 +#define FC_LOG_MSG_IN_0455 455 +#define FC_LOG_MSG_IN_0456 456 +#define FC_LOG_MSG_IN_0457 457 +#define FC_LOG_MSG_IN_0458 458 +#define FC_LOG_MSG_IN_0459 459 +#define FC_LOG_MSG_IN_0460 460 +#define FC_LOG_MSG_IN_0461 461 + +/* UNUSED */ +/* +#define FC_LOG_MSG_IN_0500 500 +*/ + +/* IP LOG Message Numbers */ +#define FC_LOG_MSG_IP_0600 600 +#define FC_LOG_MSG_IP_0601 601 +#define FC_LOG_MSG_IP_0602 602 +#define FC_LOG_MSG_IP_0603 603 +#define FC_LOG_MSG_IP_0604 604 +#define FC_LOG_MSG_IP_0605 605 +#define FC_LOG_MSG_IP_0606 606 +#define FC_LOG_MSG_IP_0607 607 +#define FC_LOG_MSG_IP_0608 608 + +/* FCP LOG Message Numbers */ +#define FC_LOG_MSG_FP_0700 700 +#define FC_LOG_MSG_FP_0701 701 +#define FC_LOG_MSG_FP_0702 702 +#define FC_LOG_MSG_FP_0703 703 +#define FC_LOG_MSG_FP_0704 704 +#define FC_LOG_MSG_FP_0705 705 +#define FC_LOG_MSG_FP_0706 706 +#define FC_LOG_MSG_FP_0707 707 +#define FC_LOG_MSG_FP_0708 708 +#define FC_LOG_MSG_FP_0709 709 +#define FC_LOG_MSG_FP_0710 710 +#define FC_LOG_MSG_FP_0711 711 +#define FC_LOG_MSG_FP_0712 712 +#define FC_LOG_MSG_FP_0713 713 +#define FC_LOG_MSG_FP_0714 714 +#define FC_LOG_MSG_FP_0715 715 +#define FC_LOG_MSG_FP_0716 716 +#define FC_LOG_MSG_FP_0717 717 +#define FC_LOG_MSG_FP_0718 718 +#define FC_LOG_MSG_FP_0719 719 +#define FC_LOG_MSG_FP_0720 720 +#define FC_LOG_MSG_FP_0721 721 +#define FC_LOG_MSG_FP_0722 722 +#define FC_LOG_MSG_FP_0723 723 +#define FC_LOG_MSG_FP_0724 724 +#define FC_LOG_MSG_FP_0725 725 +#define FC_LOG_MSG_FP_0726 726 +#define FC_LOG_MSG_FP_0727 727 +#define FC_LOG_MSG_FP_0728 728 +#define FC_LOG_MSG_FP_0729 729 +#define FC_LOG_MSG_FP_0730 730 +#define FC_LOG_MSG_FP_0731 731 +#define FC_LOG_MSG_FP_0732 732 +#define FC_LOG_MSG_FP_0733 733 +#define FC_LOG_MSG_FP_0734 734 +#define FC_LOG_MSG_FP_0735 735 +#define FC_LOG_MSG_FP_0736 736 +#define FC_LOG_MSG_FP_0737 737 +#define FC_LOG_MSG_FP_0738 738 +#define FC_LOG_MSG_FP_0739 739 +#define FC_LOG_MSG_FP_0740 740 +#define FC_LOG_MSG_FP_0741 741 +#define FC_LOG_MSG_FP_0742 742 +#define FC_LOG_MSG_FP_0743 743 +#define FC_LOG_MSG_FP_0744 744 +#define FC_LOG_MSG_FP_0745 745 +#define FC_LOG_MSG_FP_0746 746 +#define FC_LOG_MSG_FP_0747 747 +#define FC_LOG_MSG_FP_0748 748 +#define FC_LOG_MSG_FP_0749 749 +#define FC_LOG_MSG_FP_0750 750 +#define FC_LOG_MSG_FP_0751 751 +#define FC_LOG_MSG_FP_0752 752 +#define FC_LOG_MSG_FP_0753 753 +#define FC_LOG_MSG_FP_0754 754 +#define FC_LOG_MSG_FP_0756 756 + +/* UNUSED */ +/* +#define FC_LOG_MSG_FP_0800 800 +*/ + +/* NODE LOG Message Numbers */ +#define FC_LOG_MSG_ND_0900 900 +#define FC_LOG_MSG_ND_0901 901 +#define FC_LOG_MSG_ND_0902 902 +#define FC_LOG_MSG_ND_0903 903 +#define FC_LOG_MSG_ND_0904 904 +#define FC_LOG_MSG_ND_0905 905 +#define FC_LOG_MSG_ND_0906 906 +#define FC_LOG_MSG_ND_0907 907 +#define FC_LOG_MSG_ND_0908 908 +#define FC_LOG_MSG_ND_0909 909 +#define FC_LOG_MSG_ND_0910 910 +#define FC_LOG_MSG_ND_0911 911 +#define FC_LOG_MSG_ND_0912 912 +#define FC_LOG_MSG_ND_0913 913 +#define FC_LOG_MSG_ND_0914 914 +#define FC_LOG_MSG_ND_0915 915 +#define FC_LOG_MSG_ND_0916 916 +#define FC_LOG_MSG_ND_0917 917 +#define FC_LOG_MSG_ND_0918 918 +#define FC_LOG_MSG_ND_0919 919 +#define FC_LOG_MSG_ND_0920 920 +#define FC_LOG_MSG_ND_0921 921 +#define FC_LOG_MSG_ND_0922 922 +#define FC_LOG_MSG_ND_0923 923 +#define FC_LOG_MSG_ND_0924 924 +#define FC_LOG_MSG_ND_0925 925 +#define FC_LOG_MSG_ND_0926 926 +#define FC_LOG_MSG_ND_0927 927 +#define FC_LOG_MSG_ND_0928 928 + + + +/* MISC LOG Message Numbers */ +#define FC_LOG_MSG_MI_1200 1200 +#define FC_LOG_MSG_MI_1201 1201 +#define FC_LOG_MSG_MI_1202 1202 +#define FC_LOG_MSG_MI_1203 1203 +#define FC_LOG_MSG_MI_1204 1204 +#define FC_LOG_MSG_MI_1205 1205 +#define FC_LOG_MSG_MI_1206 1206 +#define FC_LOG_MSG_MI_1207 1207 +#define FC_LOG_MSG_MI_1208 1208 +#define FC_LOG_MSG_MI_1209 1209 +#define FC_LOG_MSG_MI_1210 1210 +#define FC_LOG_MSG_MI_1211 1211 +#define FC_LOG_MSG_MI_1212 1212 +#define FC_LOG_MSG_MI_1213 1213 + +/* LINK LOG Message Numbers */ +#define FC_LOG_MSG_LK_1300 1300 +#define FC_LOG_MSG_LK_1301 1301 +#define FC_LOG_MSG_LK_1302 1302 +#define FC_LOG_MSG_LK_1303 1303 +#define FC_LOG_MSG_LK_1304 1304 +#define FC_LOG_MSG_LK_1305 1305 +#define FC_LOG_MSG_LK_1306 1306 +#define FC_LOG_MSG_LK_1307 1307 + +/* SLI LOG Message Numbers */ +#define FC_LOG_MSG_LK_1400 1400 +#define FC_LOG_MSG_LK_1401 1401 +#define FC_LOG_MSG_LK_1402 1402 + +/* CHK COMDITION LOG Message Numbers */ +/* +#define FC_LOG_MSG_LK_1500 1500 +*/ +#endif /* _H_FCMSG */ diff -purN -X /home/mbligh/.diff.exclude 350-autoswap/drivers/scsi/lpfc/fcmsgcom.c 370-emulex/drivers/scsi/lpfc/fcmsgcom.c --- 350-autoswap/drivers/scsi/lpfc/fcmsgcom.c 1969-12-31 16:00:00.000000000 -0800 +++ 370-emulex/drivers/scsi/lpfc/fcmsgcom.c 2004-02-28 11:20:04.000000000 -0800 @@ -0,0 +1,6231 @@ +/******************************************************************* + * This file is part of the Emulex Linux Device Driver for * + * Enterprise Fibre Channel Host Bus Adapters. * + * Refer to the README file included with this package for * + * driver version and adapter support. * + * Copyright (C) 2003 Emulex Corporation. * + * www.emulex.com * + * * + * This program is free software; you can redistribute it and/or * + * modify it under the terms of the GNU General Public License * + * as published by the Free Software Foundation; either version 2 * + * of the License, or (at your option) any later version. * + * * + * This program is distributed in the hope that it will be useful, * + * but WITHOUT ANY WARRANTY; without even the implied warranty of * + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * + * GNU General Public License for more details, a copy of which * + * can be found in the file COPYING included with this package. * + *******************************************************************/ + +/* +LOG Message Preamble Strings + +Preamble strings are displayed at the start of LOG messages. +The 3rd letter of the preamble string identifies the +message type as follows: + +i = Information fc_msgPreamble??i where i = Information +w = Warning fc_msgPreamble??w where w = Warning +c = Error config fc_msgPreamble??c where c = Error config +e = Error fc_msgPreamble??e where e = Error +p = Panic fc_msgPreamble??p where p = Panic +*/ + +/* ELS Log Message Preamble Strings - 100 */ +char fc_msgPreambleELi[] = "ELi:"; /* ELS Information */ +char fc_msgPreambleELw[] = "ELw:"; /* ELS Warning */ +char fc_msgPreambleELe[] = "ELe:"; /* ELS Error */ +char fc_msgPreambleELp[] = "ELp:"; /* ELS Panic */ + +/* DISCOVERY Log Message Preamble Strings - 200 */ +char fc_msgPreambleDIi[] = "DIi:"; /* Discovery Information */ +char fc_msgPreambleDIw[] = "DIw:"; /* Discovery Warning */ +char fc_msgPreambleDIe[] = "DIe:"; /* Discovery Error */ +char fc_msgPreambleDIp[] = "DIp:"; /* Discovery Panic */ + +/* MAIBOX Log Message Preamble Strings - 300 */ +char fc_msgPreambleMBi[] = "MBi:"; /* Mailbox Information */ +char fc_msgPreambleMBw[] = "MBw:"; /* Mailbox Warning */ +char fc_msgPreambleMBe[] = "MBe:"; /* Mailbox Error */ +char fc_msgPreambleMBp[] = "MBp:"; /* Mailbox Panic */ + +/* INIT Log Message Preamble Strings - 400, 500 */ +char fc_msgPreambleINi[] = "INi:"; /* INIT Information */ +char fc_msgPreambleINw[] = "INw:"; /* INIT Warning */ +char fc_msgPreambleINc[] = "INc:"; /* INIT Error Config*/ +char fc_msgPreambleINe[] = "INe:"; /* INIT Error */ +char fc_msgPreambleINp[] = "INp:"; /* INIT Panic */ + +/* IP Log Message Preamble Strings - 600 */ +char fc_msgPreambleIPi[] = "IPi:"; /* IP Information */ +char fc_msgPreambleIPw[] = "IPw:"; /* IP Warning */ +char fc_msgPreambleIPe[] = "IPe:"; /* IP Error */ +char fc_msgPreambleIPp[] = "IPp:"; /* IP Panic */ + +/* FCP Log Message Preamble Strings - 700, 800 */ +char fc_msgPreambleFPi[] = "FPi:"; /* FP Information */ +char fc_msgPreambleFPw[] = "FPw:"; /* FP Warning */ +char fc_msgPreambleFPe[] = "FPe:"; /* FP Error */ +char fc_msgPreambleFPp[] = "FPp:"; /* FP Panic */ + +/* NODE Log Message Preamble Strings - 900 */ +char fc_msgPreambleNDi[] = "NDi:"; /* Node Information */ +char fc_msgPreambleNDe[] = "NDe:"; /* Node Error */ +char fc_msgPreambleNDp[] = "NDp:"; /* Node Panic */ + + + +/* MISC Log Message Preamble Strings - 1200 */ +char fc_msgPreambleMIi[] = "MIi:"; /* MISC Information */ +char fc_msgPreambleMIw[] = "MIw:"; /* MISC Warning */ +char fc_msgPreambleMIc[] = "MIc:"; /* MISC Error Config */ +char fc_msgPreambleMIe[] = "MIe:"; /* MISC Error */ +char fc_msgPreambleMIp[] = "MIp:"; /* MISC Panic */ + +/* Link Log Message Preamble Strings - 1300 */ +char fc_msgPreambleLKi[] = "LKi:"; /* Link Information */ +char fc_msgPreambleLKw[] = "LKw:"; /* Link Warning */ +char fc_msgPreambleLKe[] = "LKe:"; /* Link Error */ +char fc_msgPreambleLKp[] = "Lkp:"; /* Link Panic */ + +/* SLI Log Message Preamble Strings - 1400 */ +char fc_msgPreambleSLe[] = "SLe:"; /* SLI Error */ + +/* CHECK CONDITION Log Message Preamble Strings - 1500 */ +char fc_msgPreambleCKi[] = "CKi:"; /* Check Condition Information */ +char fc_msgPreambleCKe[] = "CKe:"; /* Check Condition Error */ +char fc_msgPreambleCKp[] = "CKp:"; /* Check Condition Panic */ + + +/* + * Begin ELS LOG message structures + */ + +/* +msgName: fc_mes0100 +message: Abort delay xmit clock +descript: The driver is canceling the delay timer for sending an ELS + command. +data: (1) did (2) remoteID (3) ulpIoTag +severity: Warning +log: LOG_ELS verbose +module: fcclockb.c +action: None required +*/ +char fc_mes0100[] = "%sAbort delay xmit clock Data: x%x x%x x%x"; +msgLogDef fc_msgBlk0100 = { + FC_LOG_MSG_EL_0100, /* LOG message number */ + fc_mes0100, /* LOG message pointer */ + fc_msgPreambleELw, /* LOG message preamble pointer */ + FC_MSG_OPUT_GLOB_CTRL, /* LOG message output control */ + FC_LOG_MSG_TYPE_WARN, /* LOG message type */ + LOG_ELS, /* LOG message mask & group */ + ERRID_LOG_UNEXPECT_EVENT }; /* LOG message error ID */ + +/* +msgName: fc_mes0101 +message: Abort delay xmit context +descript: The driver is canceling the delay timer for sending an ELS + command. +data: (1) did (2) remoteID (3) ulpIoTag +severity: Warning +log: LOG_ELS verbose +module: fcclockb.c +action: None required +*/ +char fc_mes0101[] = "%sAbort delay xmit context Data: x%x x%x x%x"; +msgLogDef fc_msgBlk0101 = { + FC_LOG_MSG_EL_0101, + fc_mes0101, + fc_msgPreambleELw, + FC_MSG_OPUT_GLOB_CTRL, + FC_LOG_MSG_TYPE_WARN, + LOG_ELS, + ERRID_LOG_UNEXPECT_EVENT }; + +/* +msgName: fc_mes0102 +message: Stray ELS completion +descript: Received an ELS command completion without issuing a + corresponding ELS Command (based on the IOTAG field + in the CMD_ELS_REQUEST_CR IOCB). +data: (1) ulpCommand (2) ulpIoTag +severity: Error +log: Always +module: fcelsb.c +action: This error could indicate a software driver or firmware + problem. If problems persist report these errors to + Technical Support. +*/ +char fc_mes0102[] = "%sStray ELS completion Data: x%x x%x"; +msgLogDef fc_msgBlk0102 = { + FC_LOG_MSG_EL_0102, + fc_mes0102, + fc_msgPreambleELe, + FC_MSG_OPUT_GLOB_CTRL, + FC_LOG_MSG_TYPE_ERR, + LOG_ELS, + ERRID_LOG_UNEXPECT_EVENT }; + +/* +msgName: fc_mes0103 +message: Dropping ELS rsp +descript: Dropping ELS response because there is no node table entry. +data: (1) ldata (2) ldid +severity: Error +log: Always +module: fcscsib.c +action: This error could indicate a software driver or firmware + problem. If problems persist report these errors to + Technical Support. +*/ +char fc_mes0103[] = "%sDropping ELS rsp Data: x%x x%x"; +msgLogDef fc_msgBlk0103 = { + FC_LOG_MSG_EL_0103, + fc_mes0103, + fc_msgPreambleELe, + FC_MSG_OPUT_GLOB_CTRL, + FC_LOG_MSG_TYPE_ERR, + LOG_ELS, + ERRID_LOG_UNEXPECT_EVENT }; + +/* +msgName: fc_mes0104 +message: Aborted ELS IOCB +descript: Driver decided to abort any action taken as a result of this ELS + command completing. +data: (1) ulpCommand (2) ulpIoTag +severity: Information +log: LOG_ELS verbose +module: fcelsb.c +action: None required. +*/ +char fc_mes0104[] = "%sAborted ELS IOCB Data: x%x x%x"; +msgLogDef fc_msgBlk0104 = { + FC_LOG_MSG_EL_0104, + fc_mes0104, + fc_msgPreambleELi, + FC_MSG_OPUT_GLOB_CTRL, + FC_LOG_MSG_TYPE_INFO, + LOG_ELS, + ERRID_LOG_UNEXPECT_EVENT }; + +/* +msgName: fc_mes0105 +message: ELS completion +descript: Adapter has notified the driver of ELS command completion. +data: (1) ulpCommand (2) ulpIoTag (3) ulpStatus (4) ulpWord[4] +severity: Information +log: LOG_ELS verbose +module: fcelsb.c +action: None required. +*/ +char fc_mes0105[] = "%sELS completion Data: x%x x%x x%x x%x"; +msgLogDef fc_msgBlk0105 = { + FC_LOG_MSG_EL_0105, + fc_mes0105, + fc_msgPreambleELi, + FC_MSG_OPUT_GLOB_CTRL, + FC_LOG_MSG_TYPE_INFO, + LOG_ELS, + ERRID_LOG_UNEXPECT_EVENT }; + +/* +msgName: fc_mes0106 +message: Unknown ELS command +descript: Received an unknown ELS command completion. +data: None +severity: Error +log: Always +module: fcelsb.c +action: This error could indicate a software driver or firmware + problem. If problems persist report these errors to + Technical Support. +*/ +char fc_mes0106[] = "%sUnknown ELS command x%x"; +msgLogDef fc_msgBlk0106 = { + FC_LOG_MSG_EL_0106, + fc_mes0106, + fc_msgPreambleELe, + FC_MSG_OPUT_GLOB_CTRL, + FC_LOG_MSG_TYPE_ERR, + LOG_ELS, + ERRID_LOG_UNEXPECT_EVENT }; + +/* +msgName: fc_mes0107 +message: ELS command completion error +descript: A driver initiated ELS command completed with an error status. +data: (1) ulpCommand (2) ulpStatus (3) ulpWord[4] (4) ulpWord[5] +severity: Information +log: LOG_ELS verbose +module: fcelsb.c +action: None required +*/ +char fc_mes0107[] = "%sELS command completion error Data: x%x x%x x%x x%x"; +msgLogDef fc_msgBlk0107 = { + FC_LOG_MSG_EL_0107, + fc_mes0107, + fc_msgPreambleELi, + FC_MSG_OPUT_GLOB_CTRL, + FC_LOG_MSG_TYPE_INFO, + LOG_ELS, + ERRID_LOG_UNEXPECT_EVENT }; + +/* +msgName: fc_mes0108 +message: ELS response completion error +descript: An ELS response sent in response to a received ELS command + completed with an error status. +data: (1) ulpCommand (2) ulpStatus (3) ulpWord[4] (4) ulpWord[5] +severity: Information +log: LOG_ELS verbose +module: fcelsb.c +action: None required. +*/ +char fc_mes0108[] = "%sELS response completion error Data: x%x x%x x%x x%x"; +msgLogDef fc_msgBlk0108 = { + FC_LOG_MSG_EL_0108, + fc_mes0108, + fc_msgPreambleELi, + FC_MSG_OPUT_GLOB_CTRL, + FC_LOG_MSG_TYPE_INFO, + LOG_ELS, + ERRID_LOG_UNEXPECT_EVENT }; + +/* +msgName: fc_mes0109 +message: ELS response completion +descript: An ELS response sent in response to a received ELS command + completed successfully. +data: (1) nlp_DID (2) nlp_type (3) nlp_flag (4) nlp_state +severity: Information +log: LOG_ELS verbose +module: fcelsb.c +action: None required +*/ +char fc_mes0109[] = "%sELS response completion Data: x%x x%x x%x x%x"; +msgLogDef fc_msgBlk0109 = { + FC_LOG_MSG_EL_0109, + fc_mes0109, + fc_msgPreambleELi, + FC_MSG_OPUT_GLOB_CTRL, + FC_LOG_MSG_TYPE_INFO, + LOG_ELS, + ERRID_LOG_UNEXPECT_EVENT }; + +/* +msgName: fc_mes0110 +message: ELS command completion error +descript: Adapter has notified the driver of ELS command completion. +data: (1) command (2) ulpStatus (3) ulpWord[4] (4) ulpWord[5] +severity: Information +log: LOG_ELS verbose +module: fcelsb.c +action: None required +*/ +char fc_mes0110[] = "%sELS command completion error Data: x%x x%x x%x x%x"; +msgLogDef fc_msgBlk0110 = { + FC_LOG_MSG_EL_0110, + fc_mes0110, + fc_msgPreambleELi, + FC_MSG_OPUT_GLOB_CTRL, + FC_LOG_MSG_TYPE_INFO, + LOG_ELS, + ERRID_LOG_UNEXPECT_EVENT }; + +/* +msgName: fc_mes0111 +message: Unknown ELS command +descript: Received an unknown ELS command completion. +data: None +severity: Error +log: Always +module: fcelsb.c +action: This error could indicate a software driver or firmware + problem. If problems persist report these errors to + Technical Support. +*/ +char fc_mes0111[] = "%sUnknown ELS command x%x"; +msgLogDef fc_msgBlk0111 = { + FC_LOG_MSG_EL_0111, + fc_mes0111, + fc_msgPreambleELe, + FC_MSG_OPUT_GLOB_CTRL, + FC_LOG_MSG_TYPE_ERR, + LOG_ELS, + ERRID_LOG_UNEXPECT_EVENT }; + +/* +msgName: fc_mes0112 +message: PLOGI completes successfully +descript: A PLOGI to a Fibre Channel NPORT completed successfully +data: (1) remoteID (2) ulpWord[4] (3) ulpWord[5] (4) fc_ffstate +severity: Information +log: LOG_ELS verbose +module: fcelsb.c +action: None required +*/ +char fc_mes0112[] = "%sPLOGI completes successfully Data: x%x x%x x%x x%x"; +msgLogDef fc_msgBlk0112 = { + FC_LOG_MSG_EL_0112, + fc_mes0112, + fc_msgPreambleELi, + FC_MSG_OPUT_GLOB_CTRL, + FC_LOG_MSG_TYPE_INFO, + LOG_ELS, + ERRID_LOG_UNEXPECT_EVENT }; + +/* +msgName: fc_mes0113 +message: PRLI completes successfully +descript: A PRLI to a FCP target completed successfully. +data: (1) remoteID (2) ulpWord[4] (3) ulpWord[5] (4) fc_ffstate +severity: Information +log: LOG_ELS & LOG_DISCOVERY verbose +module: fcelsb.c +action: None required. +*/ +char fc_mes0113[] = "%sPRLI completes successfully Data: x%x x%x x%x x%x"; +msgLogDef fc_msgBlk0113 = { + FC_LOG_MSG_EL_0113, + fc_mes0113, + fc_msgPreambleELi, + FC_MSG_OPUT_GLOB_CTRL, + FC_LOG_MSG_TYPE_INFO, + LOG_ELS | LOG_DISCOVERY, + ERRID_LOG_UNEXPECT_EVENT }; + +/* +msgName: fc_mes0114 +message: PRLO completes successfully +descript: A PRLO to a FCP target completed successfully. +data: (1) remoteID (2) ulpWord[4] (3) ulpWord[5] (4) fc_ffstate +severity: Information +severity: Information +log: LOG_ELS ELS & LOG_DISCOVERY verbose +module: fcelsb.c +action: None required. +*/ +char fc_mes0114[] = "%sPRLO completes successfully Data: x%x x%x x%x x%x"; +msgLogDef fc_msgBlk0114 = { + FC_LOG_MSG_EL_0114, + fc_mes0114, + fc_msgPreambleELi, + FC_MSG_OPUT_GLOB_CTRL, + FC_LOG_MSG_TYPE_INFO, + LOG_ELS, + ERRID_LOG_UNEXPECT_EVENT }; + +/* +msgName: fc_mes0115 +message: LOGO completes successfully +descript: A LOGO to a FCP target completed successfully. +data: (1) remoteID (2) ulpWord[4] (3) ulpWord[5] (4) fc_ffstate +severity: Information +log: LOG_ELS ELS & LOG_DISCOVERY verbose +module: fcelsb.c +action: None required. +*/ +char fc_mes0115[] = "%sLOGO completes successfully Data: x%x x%x x%x x%x"; +msgLogDef fc_msgBlk0115 = { + FC_LOG_MSG_EL_0115, + fc_mes0115, + fc_msgPreambleELi, + FC_MSG_OPUT_GLOB_CTRL, + FC_LOG_MSG_TYPE_INFO, + LOG_ELS, + ERRID_LOG_UNEXPECT_EVENT }; + +/* +msgName: fc_mes0116 +message: PDISC completes successfully +descript: A PDISC to a FCP target completed successfully. +data: (1) remoteID (2) ulpWord[4] (3) ulpWord[5] (4) fc_ffstate +severity: Information +log: LOG_ELS ELS & LOG_DISCOVERY verbose +module: fcelsb.c +action: None required. +*/ +char fc_mes0116[] = "%sPDISC completes successfully Data: x%x x%x x%x x%x"; +msgLogDef fc_msgBlk0116 = { + FC_LOG_MSG_EL_0116, + fc_mes0116, + fc_msgPreambleELi, + FC_MSG_OPUT_GLOB_CTRL, + FC_LOG_MSG_TYPE_INFO, + LOG_ELS, + ERRID_LOG_UNEXPECT_EVENT }; + +/* +msgName: fc_mes0117 +message: ADISC completes successfully +descript: A ADISC to a FCP target completed successfully. +data: (1) remoteID (2) ulpWord[4] (3) ulpWord[5] (4) fc_ffstate +severity: Information +log: ELS or LOG_DISCOVERY verbose +module: fcelsb.c +action: None required. +*/ +char fc_mes0117[] = "%sADISC completes successfully Data: x%x x%x x%x x%x"; +msgLogDef fc_msgBlk0117 = { + FC_LOG_MSG_EL_0117, + fc_mes0117, + fc_msgPreambleELi, + FC_MSG_OPUT_GLOB_CTRL, + FC_LOG_MSG_TYPE_INFO, + LOG_ELS, + ERRID_LOG_UNEXPECT_EVENT }; + +/* +msgName: fc_mes0118 +message: FARP completes successfully +descript: A FARP completed successfully. +data: (1) remoteID (2) ulpWord[4] (3) ulpWord[5] (4) command +severity: Information +log: LOG_ELS verbose +module: fcelsb.c +action: None required. +*/ +char fc_mes0118[] = "%sFARP completes successfully Data: x%x x%x x%x x%x"; +msgLogDef fc_msgBlk0118 = { + FC_LOG_MSG_EL_0118, + fc_mes0118, + fc_msgPreambleELi, + FC_MSG_OPUT_GLOB_CTRL, + FC_LOG_MSG_TYPE_INFO, + LOG_ELS, + ERRID_LOG_UNEXPECT_EVENT }; + +/* +msgName: fc_mes0119 +message: SCR completes successfully +descript: A SCR completed successfully. +data: (1) remoteID (2) ulpWord[4] (3) ulpWord[5] (4) fc_ffstate +severity: Information +log: LOG_ELS verbose +module: fcelsb.c +action: None required. +*/ +char fc_mes0119[] = "%sSCR completes successfully Data: x%x x%x x%x x%x"; +msgLogDef fc_msgBlk0119 = { + FC_LOG_MSG_EL_0119, + fc_mes0119, + fc_msgPreambleELi, + FC_MSG_OPUT_GLOB_CTRL, + FC_LOG_MSG_TYPE_INFO, + LOG_ELS, + ERRID_LOG_UNEXPECT_EVENT }; + +/* +msgName: fc_mes0120 +message: RNID completes successfully +descript: A RNID completed successfully. +data: (1) remoteID (2) ulpWord[4] (3) ulpWord[5] (4) fc_ffstate +severity: Information +log: LOG_ELS verbose +module: fcelsb.c +action: None required. +*/ +char fc_mes0120[] = "%sRNID completes successfully Data: x%x x%x x%x x%x"; +msgLogDef fc_msgBlk0120 = { + FC_LOG_MSG_EL_0120, + fc_mes0120, + fc_msgPreambleELi, + FC_MSG_OPUT_GLOB_CTRL, + FC_LOG_MSG_TYPE_INFO, + LOG_ELS, + ERRID_LOG_UNEXPECT_EVENT }; + +/* +msgName: fc_mes0121 +message: Unknown ELS command completed +descript: Received an unknown ELS command completion. +data: None +severity: Error +log: Always +module: fcelsb.c +action: This error could indicate a software driver or firmware + problem. If problems persist report these errors to + Technical Support. +*/ +char fc_mes0121[] = "%sUnknown ELS command x%x completed"; +msgLogDef fc_msgBlk0121 = { + FC_LOG_MSG_EL_0121, + fc_mes0121, + fc_msgPreambleELe, + FC_MSG_OPUT_GLOB_CTRL, + FC_LOG_MSG_TYPE_ERR, + LOG_ELS, + ERRID_LOG_UNEXPECT_EVENT }; + +/* +msgName: fc_mes0122 +message: Unknown ELS IOCB +descript: An unknown IOCB command completed in the ELS ring +data: (1) ulpCommand +severity: Error +log: Always +module: fcelsb.c +action: This error could indicate a software driver or firmware + problem. If problems persist report these errors to + Technical Support. +*/ +char fc_mes0122[] = "%sUnknown ELS IOCB Data: x%x"; +msgLogDef fc_msgBlk0122 = { + FC_LOG_MSG_EL_0122, + fc_mes0122, + fc_msgPreambleELe, + FC_MSG_OPUT_GLOB_CTRL, + FC_LOG_MSG_TYPE_ERR, + LOG_ELS, + ERRID_LOG_UNEXPECT_EVENT }; + +/* +msgName: fc_mes0123 +message: Received ELS command +descript: An ELS command was received. +data: (1) ulpWord[5] (2) ulpStatus (3) fc_ffstate +severity: Information +log: LOG_ELS verbose +module: fcelsb.c +action: None required +*/ +char fc_mes0123[] = "%sReceived ELS command x%x Data: x%x x%x x%x"; +msgLogDef fc_msgBlk0123 = { + FC_LOG_MSG_EL_0123, + fc_mes0123, + fc_msgPreambleELi, + FC_MSG_OPUT_GLOB_CTRL, + FC_LOG_MSG_TYPE_INFO, + LOG_ELS, + ERRID_LOG_UNEXPECT_EVENT }; + +/* +msgName: fc_mes0124 +message: An FLOGI ELS command was received from DID in Loop Mode +descript: While in Loop Mode an unknown or unsupported ELS commnad + was received. +data: None +severity: Error +log: Always +module: fcelsb.c +action: Check device DID +*/ +char fc_mes0124[] = "%sAn FLOGI ELS command x%x was received from DID x%x in Loop Mode"; +msgLogDef fc_msgBlk0124 = { + FC_LOG_MSG_EL_0124, + fc_mes0124, + fc_msgPreambleELe, + FC_MSG_OPUT_GLOB_CTRL, + FC_LOG_MSG_TYPE_ERR, + LOG_ELS, + ERRID_LOG_UNEXPECT_EVENT }; + +/* +msgName: fc_mes0125 +message: Received PLOGI command +descript: A PLOGI command was received. +data: (1) nlp_DID (2) nlp_state (3) nlp_flag (4) nlp_Rpi +severity: Information +log: LOG_ELS verbose +module: fcelsb.c +action: None required +*/ +char fc_mes0125[] = "%sReceived PLOGI command Data: x%x x%x x%x x%x"; +msgLogDef fc_msgBlk0125 = { + FC_LOG_MSG_EL_0125, + fc_mes0125, + fc_msgPreambleELi, + FC_MSG_OPUT_GLOB_CTRL, + FC_LOG_MSG_TYPE_INFO, + LOG_ELS, + ERRID_LOG_UNEXPECT_EVENT }; + +/* +msgName: fc_mes0126 +message: PLOGI chkparm OK +descript: Received a PLOGI from a remote NPORT and its Fibre Channel service + parameters match this HBA. Request can be accepted. +data: (1) nlp_DID (2) nlp_state (3) nlp_flag (4) nlp_Rpi +severity: Information +log: LOG_ELS verbose +module: fcelsb.c +action: None required +*/ +char fc_mes0126[] = "%sPLOGI chkparm OK Data: x%x x%x x%x x%x"; +msgLogDef fc_msgBlk0126 = { + FC_LOG_MSG_EL_0126, + fc_mes0126, + fc_msgPreambleELi, + FC_MSG_OPUT_GLOB_CTRL, + FC_LOG_MSG_TYPE_INFO, + LOG_ELS, + ERRID_LOG_UNEXPECT_EVENT }; + +/* +msgName: fc_mes0127 +message: Unknown ELS command received from NPORT +descript: Received an unsupported ELS command from a remote NPORT. +data: None +severity: Error +log: Always +module: fcelsb.c +action: Check remote NPORT for potential problem. +*/ +char fc_mes0127[] = "%sUnknown ELS command x%x received from NPORT x%x"; +msgLogDef fc_msgBlk0127 = { + FC_LOG_MSG_EL_0127, + fc_mes0127, + fc_msgPreambleELe, + FC_MSG_OPUT_GLOB_CTRL, + FC_LOG_MSG_TYPE_ERR, + LOG_ELS, + ERRID_LOG_UNEXPECT_EVENT }; + +/* +msgName: fc_mes0128 +message: Xmit unknown ELS command +descript: The Fibre Channel driver is attempting to send an + unsupported or unknown ELS command. +data: None +severity: Error +log: Always +module: fcelsb.c +action: This error could indicate a software driver or firmware + problem. If problems persist report these errors to + Technical Support. +*/ +char fc_mes0128[] = "%sXmit unknown ELS command x%x"; +msgLogDef fc_msgBlk0128 = { + FC_LOG_MSG_EL_0128, + fc_mes0128, + fc_msgPreambleELe, + FC_MSG_OPUT_GLOB_CTRL, + FC_LOG_MSG_TYPE_ERR, + LOG_ELS, + ERRID_LOG_UNEXPECT_EVENT }; + +/* +msgName: fc_mes0129 +message: Xmit ELS command to remote NPORT +descript: Xmit ELS command to remote NPORT +data: (1) icmd->ulpIoTag (2) binfo->fc_ffstate +severity: Information +log: LOG_ELS verbose +module: fcelsb.c +action: None required +*/ +char fc_mes0129[] = "%sXmit ELS command x%x to remote NPORT x%x Data: x%x x%x"; +msgLogDef fc_msgBlk0129 = { + FC_LOG_MSG_EL_0129, + fc_mes0129, + fc_msgPreambleELi, + FC_MSG_OPUT_GLOB_CTRL, + FC_LOG_MSG_TYPE_INFO, + LOG_ELS, + ERRID_LOG_UNEXPECT_EVENT }; + +/* +msgName: fc_mes0130 +message: Xmit unknown ELS response (elsCmd> +descript: The Fibre Channel driver is attempting to send an + unsupported or unknown ELS response. +data: None +severity: Error +log: Always +module: fcelsb.c +action: This error could indicate a software driver or firmware + problem. If problems persist report these errors to + Technical Support. +*/ +char fc_mes0130[] = "%sXmit unknown ELS response x%x"; +msgLogDef fc_msgBlk0130 = { + FC_LOG_MSG_EL_0130, + fc_mes0130, + fc_msgPreambleELe, + FC_MSG_OPUT_GLOB_CTRL, + FC_LOG_MSG_TYPE_ERR, + LOG_ELS, + ERRID_LOG_UNEXPECT_EVENT }; + +/* +msgName: fc_mes0131 +message: Xmit ELS response to remote NPORT +descript: Xmit ELS response to remote NPORT +data: (1) icmd->ulpIoTag (2) size +severity: Information +log: LOG_ELS verbose +module: fcelsb.c +action: None required +*/ +char fc_mes0131[] = "%sXmit ELS response x%x to remote NPORT x%x Data: x%x x%x"; +msgLogDef fc_msgBlk0131 = { + FC_LOG_MSG_EL_0131, + fc_mes0131, + fc_msgPreambleELi, + FC_MSG_OPUT_GLOB_CTRL, + FC_LOG_MSG_TYPE_INFO, + LOG_ELS, + ERRID_LOG_UNEXPECT_EVENT }; + +/* +msgName: fc_mes0132 +message: ELS Retry failed +descript: If an ELS command fails, it may be retried up + to 3 times. This message will be recorded if + the driver gives up retrying a specific ELS + command. +data: (1) ELS command, (2) remote PortID +severity: Information +log: LOG_ELS verbose +module: fcelsb.c +action: If the ELS command is a PRLI, and the destination + PortID is not an FCP Target, no action is required. + Otherwise, check physical connections to Fibre + Channel network and the state of the remote PortID. +*/ +char fc_mes0132[] = "%sELS Retry failed Data: x%x x%x"; +msgLogDef fc_msgBlk0132 = { + FC_LOG_MSG_EL_0132, + fc_mes0132, + fc_msgPreambleELi, + FC_MSG_OPUT_GLOB_CTRL, + FC_LOG_MSG_TYPE_INFO, + LOG_ELS, + ERRID_LOG_UNEXPECT_EVENT }; + +/* +msgName: fc_mes0133 +message: Xmit CT response on exchange +descript: Xmit a CT response on the appropriate exchange. +data: (1) ulpIoTag (2) fc_ffstate +severity: Information +log: LOG_ELS verbose +module: fcelsb.c +action: None required +*/ +char fc_mes0133[] = "%sXmit CT response on exchange x%x Data: x%x x%x"; +msgLogDef fc_msgBlk0133 = { + FC_LOG_MSG_EL_0133, + fc_mes0133, + fc_msgPreambleELi, + FC_MSG_OPUT_GLOB_CTRL, + FC_LOG_MSG_TYPE_INFO, + LOG_ELS, + ERRID_LOG_UNEXPECT_EVENT }; + +/* +msgName: fc_mes0134 +message: Issue GEN REQ IOCB for NPORT +descript: Issue a GEN REQ IOCB for remote NPORT. These are typically + used for CT request. +data: (1) ulpIoTag (2) fc_ffstate +severity: Information +log: LOG_ELS verbose +module: fcelsb.c +action: None required +*/ +char fc_mes0134[] = "%sIssue GEN REQ IOCB for NPORT x%x Data: x%x x%x"; +msgLogDef fc_msgBlk0134 = { + FC_LOG_MSG_EL_0134, + fc_mes0134, + fc_msgPreambleELi, + FC_MSG_OPUT_GLOB_CTRL, + FC_LOG_MSG_TYPE_INFO, + LOG_ELS, + ERRID_LOG_UNEXPECT_EVENT }; + +/* +msgName: fc_mes0135 +message: Issue GEN REQ IOCB for RNID +descript: Issue a GEN REQ IOCB to support an ELS RNID command +data: (1) ulpWord[5] (2) ulpIoTag (3) fc_ffstate +severity: Information +log: LOG_ELS verbose +module: fcelsb.c +action: None required +*/ +char fc_mes0135[] = "%sIssue GEN REQ IOCB for RNID Data: x%x x%x x%x"; +msgLogDef fc_msgBlk0135 = { + FC_LOG_MSG_EL_0135, + fc_mes0135, + fc_msgPreambleELi, + FC_MSG_OPUT_GLOB_CTRL, + FC_LOG_MSG_TYPE_INFO, + LOG_ELS, + ERRID_LOG_UNEXPECT_EVENT }; + +/* +msgName: fc_mes0136 +message: Delayxmit ELS command timeout +descript: The delay for issuing an ELS command has expired. The ELS + command is queued to HBA to be xmitted. +data: (1) ulpIoTag (2) retry (3) remoteID +severity: Information +log: LOG_ELS verbose +module: fcscsib.c +action: None required +*/ +char fc_mes0136[] = "%sDelayxmit ELS command x%x timeout Data: x%x x%x x%x"; +msgLogDef fc_msgBlk0136 = { + FC_LOG_MSG_EL_0136, + fc_mes0136, + fc_msgPreambleELi, + FC_MSG_OPUT_GLOB_CTRL, + FC_LOG_MSG_TYPE_INFO, + LOG_ELS, + ERRID_LOG_TIMEOUT }; + +/* + * Begin DSCOVERY LOG Message Structures + */ + +/* +msgName: fc_mes0200 +message: Device Discovery Started +descript: Device discovery / rediscovery after FLOGI or FAN has started. +data: None +severity: Information +log: LOG_DISCOVERY verbose +module: fcrpib.c +action: None required +*/ +char fc_mes0200[] = "%sDevice Discovery Started"; +msgLogDef fc_msgBlk0200 = { + FC_LOG_MSG_DI_0200, + fc_mes0200, + fc_msgPreambleDIi, + FC_MSG_OPUT_GLOB_CTRL, + FC_LOG_MSG_TYPE_INFO, + LOG_DISCOVERY, + ERRID_LOG_UNEXPECT_EVENT }; + +/* +msgName: fc_mes0201 +message: Device Discovery completion error +descript: This indicates an uncorrectable error was encountered + during device (re)discovery after a link up. Fibre + Channel devices will not be accessible if this message + is displayed. +data: None +severity: Error +log: Always +module: fcrpib.c +action: Reboot system. If problem persists, contact Technical + Support. Run with verbose mode on for more details. +*/ +char fc_mes0201[] = "%sDevice Discovery completion error"; +msgLogDef fc_msgBlk0201 = { + FC_LOG_MSG_DI_0201, + fc_mes0201, + fc_msgPreambleDIe, + FC_MSG_OPUT_GLOB_CTRL, + FC_LOG_MSG_TYPE_ERR, + LOG_DISCOVERY, + ERRID_LOG_UNEXPECT_EVENT }; + +/* +msgName: fc_mes0202 +message: Device Discovery Started +descript: Device discovery / rediscovery after FLOGI or FAN has started. +data: None +severity: Information +log: LOG_DISCOVERY verbose +module: fcrpib.c +action: None required +*/ +char fc_mes0202[] = "%sDevice Discovery Started"; +msgLogDef fc_msgBlk0202 = { + FC_LOG_MSG_DI_0202, + fc_mes0202, + fc_msgPreambleDIi, + FC_MSG_OPUT_GLOB_CTRL, + FC_LOG_MSG_TYPE_INFO, + LOG_DISCOVERY, + ERRID_LOG_UNEXPECT_EVENT }; + +/* +msgName: fc_mes0203 +message: Device Discovery continues +descript: Device discovery in process +data: (1) firstndlp (2) fc_ffstate +severity: Information +log: LOG_DISCOVERY verbose +module: fcrpib.c +action: None required +*/ +char fc_mes0203[] = "%sDevice Discovery continues Data: x%x x%x"; +msgLogDef fc_msgBlk0203 = { + FC_LOG_MSG_DI_0203, + fc_mes0203, + fc_msgPreambleDIi, + FC_MSG_OPUT_GLOB_CTRL, + FC_LOG_MSG_TYPE_INFO, + LOG_DISCOVERY, + ERRID_LOG_UNEXPECT_EVENT }; + +/* +msgName: fc_mes0204 +message: Device Discovery completion error +descript: This indicates an uncorrectable error was encountered + during device (re)discovery after a link up. Fibre + Channel devices will not be accessible if this message + is displayed. +data: None +severity: Error +log: Always +module: fcrpib.c +action: Reboot system. If problem persists, contact Technical + Support. Run with verbose mode on for more details. +*/ +char fc_mes0204[] = "%sDevice Discovery completion error"; +msgLogDef fc_msgBlk0204 = { + FC_LOG_MSG_DI_0204, + fc_mes0204, + fc_msgPreambleDIe, + FC_MSG_OPUT_GLOB_CTRL, + FC_LOG_MSG_TYPE_ERR, + LOG_DISCOVERY, + ERRID_LOG_UNEXPECT_EVENT }; + +/* +msgName: fc_mes0205 +message: Device Discovery authentication +descript: The driver has marked NPORTs in its none table that require ADISC + for authentication. +data: (1) cnt (2) cnt1 (3) cnt2 +severity: Information +log: LOG_DISCOVERY verbose +module: fcrpib.c +action: None required +*/ +char fc_mes0205[] = "%sDevice Discovery authentication Data: x%x x%x x%x"; +msgLogDef fc_msgBlk0205 = { + FC_LOG_MSG_DI_0205, + fc_mes0205, + fc_msgPreambleDIi, + FC_MSG_OPUT_GLOB_CTRL, + FC_LOG_MSG_TYPE_INFO, + LOG_DISCOVERY, + ERRID_LOG_UNEXPECT_EVENT }; + +/* +msgName: fc_mes0206 +message: Device Discovery completion error +descript: This indicates an uncorrectable error was encountered + during device (re)discovery after a link up. Fibre + Channel devices will not be accessible if this message + is displayed. +data: (1) ulpStatus (2) ulpWord[4] (3) ulpWord[5] +severity: Error +log: Always +module: fcelsb.c +action: Reboot system. If problem persists, contact Technical + Support. Run with verbose mode on for more details. +*/ +char fc_mes0206[] = "%sDevice Discovery completion error Data: x%x x%x x%x"; +msgLogDef fc_msgBlk0206 = { + FC_LOG_MSG_DI_0206, + fc_mes0206, + fc_msgPreambleDIe, + FC_MSG_OPUT_GLOB_CTRL, + FC_LOG_MSG_TYPE_ERR, + LOG_DISCOVERY, + ERRID_LOG_UNEXPECT_EVENT }; + +/* +msgName: fc_mes0207 +message: Device Discovery completion error +descript: This indicates an uncorrectable error was encountered + during device (re)discovery after a link up. Fibre + Channel devices will not be accessible if this message + is displayed. +data: None +severity: Error +log: Always +module: fcelsb.c +action: Reboot system. If problem persists, contact Technical + Support. Run with verbose mode on for more details. +*/ +char fc_mes0207[] = "%sDevice Discovery completion error"; +msgLogDef fc_msgBlk0207 = { + FC_LOG_MSG_DI_0207, + fc_mes0207, + fc_msgPreambleDIe, + FC_MSG_OPUT_GLOB_CTRL, + FC_LOG_MSG_TYPE_ERR, + LOG_DISCOVERY, + ERRID_LOG_UNEXPECT_EVENT }; + +/* +msgName: fc_mes0208 +message: FLOGI completes successfully +descript: Fabric Login completed successfully. +data: (1) ulpWord[4] (2) e_d_tov (3) r_a_tov (4) edtovResolution +severity: Information +log: LOG_DISCOVERY verbose +module: fcelsb.c +action: None required. +*/ +char fc_mes0208[] = "%sFLOGI completes successfully Data: x%x x%x x%x x%x"; +msgLogDef fc_msgBlk0208 = { + FC_LOG_MSG_DI_0208, + fc_mes0208, + fc_msgPreambleDIi, + FC_MSG_OPUT_GLOB_CTRL, + FC_LOG_MSG_TYPE_INFO, + LOG_DISCOVERY, + ERRID_LOG_UNEXPECT_EVENT }; + +/* +msgName: fc_mes0209 +message: Device Discovery completes +descript: This indicates successful completion of device + (re)discovery after a link up. +data: None +severity: Information +log: LOG_DISCOVERY verbose +module: fcelsb.c +action: None required +*/ +char fc_mes0209[] = "%sDevice Discovery completes"; +msgLogDef fc_msgBlk0209 = { + FC_LOG_MSG_DI_0209, + fc_mes0209, + fc_msgPreambleDIi, + FC_MSG_OPUT_GLOB_CTRL, + FC_LOG_MSG_TYPE_INFO, + LOG_DISCOVERY, + ERRID_LOG_UNEXPECT_EVENT }; + +/* +msgName: fc_mes0210 +message: PRLI target assigned +descript: The driver has assigned a SCSI ID to the FCP target. +data: (1) ulpWord[5] (2) nlp_pan (3) nlp_sid +severity: Information +log: LOG_DISCOVERY verbose +module: fcelsb.c +action: None required +*/ +char fc_mes0210[] = "%sPRLI target assigned Data: x%x x%x x%x"; +msgLogDef fc_msgBlk0210 = { + FC_LOG_MSG_DI_0210, + fc_mes0210, + fc_msgPreambleDIi, + FC_MSG_OPUT_GLOB_CTRL, + FC_LOG_MSG_TYPE_INFO, + LOG_DISCOVERY, + ERRID_LOG_UNEXPECT_EVENT }; + +/* +msgName: fc_mes0211 +message: Received RSCN command +descript: The driver has received an RSCN command from the fabric. This + indicates a device was potentially added or removed from the + Fibre Channel network. +data: (1) fc_flag (2) defer_rscn.q_cnt (3) fc_rscn.q_cnt (4) fc_mbox_active +severity: Information +log: LOG_DISCOVERY verbose +module: fcelsb.c +action: None required +*/ +char fc_mes0211[] = "%sReceived RSCN command Data: x%x x%x x%x x%x"; +msgLogDef fc_msgBlk0211 = { + FC_LOG_MSG_DI_0211, + fc_mes0211, + fc_msgPreambleDIi, + FC_MSG_OPUT_GLOB_CTRL, + FC_LOG_MSG_TYPE_INFO, + LOG_DISCOVERY, + ERRID_LOG_UNEXPECT_EVENT }; + +/* +msgName: fc_mes0212 +message: Device Discovery completes +descript: This indicates successful completion of device + (re)discovery after a link up. +data: None +severity: Information +log: LOG_DISCOVERY verbose +module: fcelsb.c +action: None required +*/ +char fc_mes0212[] = "%sDevice Discovery completes"; +msgLogDef fc_msgBlk0212 = { + FC_LOG_MSG_DI_0212, + fc_mes0212, + fc_msgPreambleDIi, + FC_MSG_OPUT_GLOB_CTRL, + FC_LOG_MSG_TYPE_INFO, + LOG_DISCOVERY, + ERRID_LOG_UNEXPECT_EVENT }; + +/* +msgName: fc_mes0213 +message: FAN received +descript: A FAN ELS command was received from a Fabric. +data: (1) ulpWord[4] (2) fc_ffstate +severity: Information +log: LOG_DISCOVERY verbose +module: fcelsb.c +action: None required. +*/ +char fc_mes0213[] = "%sFAN received Data: x%x x%x"; +msgLogDef fc_msgBlk0213 = { + FC_LOG_MSG_DI_0213, + fc_mes0213, + fc_msgPreambleDIi, + FC_MSG_OPUT_GLOB_CTRL, + FC_LOG_MSG_TYPE_INFO, + LOG_DISCOVERY, + ERRID_LOG_UNEXPECT_EVENT }; + +/* +msgName: fc_mes0214 +message: RSCN received +descript: A RSCN ELS command was received from a Fabric. +data: (1) fc_flag (2) i (3) *lp (4) fc_rscn_id_cnt +severity: Information +log: LOG_DISCOVERY verbose +module: fcelsb.c +action: None required. +*/ +char fc_mes0214[] = "%sRSCN received Data: x%x x%x x%x x%x"; +msgLogDef fc_msgBlk0214 = { + FC_LOG_MSG_DI_0214, + fc_mes0214, + fc_msgPreambleDIi, + FC_MSG_OPUT_GLOB_CTRL, + FC_LOG_MSG_TYPE_INFO, + LOG_DISCOVERY, + ERRID_LOG_UNEXPECT_EVENT }; + +/* +msgName: fc_mes0215 +message: RSCN processed +descript: A RSCN ELS command was received from a Fabric and processed. +data: (1) fc_flag (2) cnt (3) fc_rscn_id_cnt (4) fc_ffstate +severity: Information +log: LOG_DISCOVERY verbose +module: fcelsb.c +action: None required. +*/ +char fc_mes0215[] = "%sRSCN processed Data: x%x x%x x%x x%x"; +msgLogDef fc_msgBlk0215 = { + FC_LOG_MSG_DI_0215, + fc_mes0215, + fc_msgPreambleDIi, + FC_MSG_OPUT_GLOB_CTRL, + FC_LOG_MSG_TYPE_INFO, + LOG_DISCOVERY, + ERRID_LOG_UNEXPECT_EVENT }; + +/* +msgName: fc_mes0216 +message: Unknown Identifier in RSCN payload +descript: Typically the identifier in the RSCN payload specifies + a domain, area or a specific NportID. If neither of + these are specified, a warning will be recorded. +data: (1) didp->un.word +severity: Error +log: Always +module: fcelsb.c +action: Potential problem with Fabric. Check with Fabric vendor. +*/ +char fc_mes0216[] = "%sUnknown Identifier in RSCN payload Data: x%x"; +msgLogDef fc_msgBlk0216 = { + FC_LOG_MSG_DI_0216, + fc_mes0216, + fc_msgPreambleDIe, + FC_MSG_OPUT_GLOB_CTRL, + FC_LOG_MSG_TYPE_ERR, + LOG_DISCOVERY, + ERRID_LOG_UNEXPECT_EVENT }; + +/* +msgName: fc_mes0217 +message: Device Discovery completion error +descript: This indicates an uncorrectable error was encountered + during device (re)discovery after a link up. Fibre + Channel devices will not be accessible if this message + is displayed. +data: None +severity: Error +log: Always +module: fcelsb.c +action: Reboot system. If problem persists, contact Technical + Support. Run with verbose mode on for more details. +*/ +char fc_mes0217[] = "%sDevice Discovery completion error"; +msgLogDef fc_msgBlk0217 = { + FC_LOG_MSG_DI_0217, + fc_mes0217, + fc_msgPreambleDIe, + FC_MSG_OPUT_GLOB_CTRL, + FC_LOG_MSG_TYPE_ERR, + LOG_DISCOVERY, + ERRID_LOG_UNEXPECT_EVENT }; + +/* +msgName: fc_mes0218 +message: FDMI Request +descript: The driver is sending an FDMI request to the fabric. +data: (1) cmdcode (2) fc_flag +severity: Information +log: LOG_DISCOVERY verbose +module: fcelsb.c +action: None required. +*/ +char fc_mes0218[] = "%sFDMI Req Data: x%x x%x"; +msgLogDef fc_msgBlk0218 = { + FC_LOG_MSG_DI_0218, + fc_mes0218, + fc_msgPreambleDIi, + FC_MSG_OPUT_GLOB_CTRL, + FC_LOG_MSG_TYPE_INFO, + LOG_DISCOVERY, + ERRID_LOG_UNEXPECT_EVENT }; + + +/* +msgName: fc_mes0219 +message: Issue FDMI request failed +descript: Cannot issue FDMI request to HBA. +data: (1) SLI_MGMT_DPRT +severity: Information +log: LOG_DISCOVERY verbose +module: fcscsib.c +action: None required +*/ +char fc_mes0219[] = "%sIssue FDMI request failed Data: x%x"; +msgLogDef fc_msgBlk0219 = { + FC_LOG_MSG_DI_0219, + fc_mes0219, + fc_msgPreambleDIi, + FC_MSG_OPUT_GLOB_CTRL, + FC_LOG_MSG_TYPE_INFO, + LOG_DISCOVERY, + ERRID_LOG_UNEXPECT_EVENT }; + +/* +msgName: fc_mes0220 +message: Device Discovery completion error +descript: This indicates an uncorrectable error was encountered + during device (re)discovery after a link up. Fibre + Channel devices will not be accessible if this message + is displayed. +data: None +severity: Error +log: Always +module: fcscsib.c +action: Reboot system. If problem persists, contact Technical + Support. Run with verbose mode on for more details. +*/ +char fc_mes0220[] = "%sDevice Discovery completion error"; +msgLogDef fc_msgBlk0220 = { + FC_LOG_MSG_DI_0220, + fc_mes0220, + fc_msgPreambleDIe, + FC_MSG_OPUT_GLOB_CTRL, + FC_LOG_MSG_TYPE_ERR, + LOG_DISCOVERY, + ERRID_LOG_UNEXPECT_EVENT }; + +/* +msgName: fc_mes0221 +message: FAN timeout +descript: A link up event was received without the login bit set, + so the driver waits E_D_TOV for the Fabric to send a FAN. + If no FAN if received, a FLOGI will be sent after the timeout. +data: None +severity: Warning +log: LOG_DISCOVERY verbose +module: fcscsib.c +action: None required. The driver recovers from this condition by + issuing a FLOGI to the Fabric. +*/ +char fc_mes0221[] = "%sFAN timeout"; +msgLogDef fc_msgBlk0221 = { + FC_LOG_MSG_DI_0221, + fc_mes0221, + fc_msgPreambleDIw, + FC_MSG_OPUT_GLOB_CTRL, + FC_LOG_MSG_TYPE_WARN, + LOG_DISCOVERY, + ERRID_LOG_TIMEOUT }; + +/* +msgName: fc_mes0222 +message: Initial FLOGI timeout +descript: The driver is sending initial FLOGI to fabric. +data: None +severity: Error +log: Always +module: fcscsib.c +action: Check Fabric configuration. The driver recovers from this and + continues with device discovery. +*/ +char fc_mes0222[] = "%sInitial FLOGI timeout"; +msgLogDef fc_msgBlk0222 = { + FC_LOG_MSG_DI_0222, + fc_mes0222, + fc_msgPreambleDIe, + FC_MSG_OPUT_GLOB_CTRL, + FC_LOG_MSG_TYPE_ERR, + LOG_DISCOVERY, + ERRID_LOG_TIMEOUT }; + +/* +msgName: fc_mes0223 +message: NameServer Registration timeout +descript: Our registration request to the Fabric was not acknowledged + within RATOV. +data: (1) fc_ns_retry (2) fc_max_ns_retry +severity: Error +log: Always +module: fcscsib.c +action: Check Fabric configuration. The driver recovers from this and + continues with device discovery. +*/ +char fc_mes0223[] = "%sNameServer Registration timeout Data: x%x x%x"; +msgLogDef fc_msgBlk0223 = { + FC_LOG_MSG_DI_0223, + fc_mes0223, + fc_msgPreambleDIe, + FC_MSG_OPUT_GLOB_CTRL, + FC_LOG_MSG_TYPE_ERR, + LOG_DISCOVERY, + ERRID_LOG_TIMEOUT }; + +/* +msgName: fc_mes0224 +message: NameServer Query timeout +descript: Node authentication timeout, node Discovery timeout. A NameServer + Query to the Fabric or discovery of reported remote NPorts is not + acknowledged within R_A_TOV. +data: (1) fc_ns_retry (2) fc_max_ns_retry +severity: Error +log: Always +module: fcscsib.c +action: Check Fabric configuration. The driver recovers from this and + continues with device discovery. +*/ +char fc_mes0224[] = "%sNameServer Query timeout Data: x%x x%x"; +msgLogDef fc_msgBlk0224 = { + FC_LOG_MSG_DI_0224, + fc_mes0224, + fc_msgPreambleDIe, + FC_MSG_OPUT_GLOB_CTRL, + FC_LOG_MSG_TYPE_ERR, + LOG_DISCOVERY, + ERRID_LOG_TIMEOUT }; + +/* +msgName: fc_mes0225 +message: Device Discovery completes +descript: This indicates successful completion of device + (re)discovery after a link up. +data: None +severity: Information +log: LOG_DISCOVERY verbose +module: fcscsib.c +action: None required +*/ +char fc_mes0225[] = "%sDevice Discovery completes"; +msgLogDef fc_msgBlk0225 = { + FC_LOG_MSG_DI_0225, + fc_mes0225, + fc_msgPreambleDIi, + FC_MSG_OPUT_GLOB_CTRL, + FC_LOG_MSG_TYPE_INFO, + LOG_DISCOVERY, + ERRID_LOG_UNEXPECT_EVENT }; + +/* +msgName: fc_mes0226 +message: Device Discovery completion error +descript: This indicates an uncorrectable error was encountered + during device (re)discovery after a link up. Fibre + Channel devices will not be accessible if this message + is displayed. +data: None +severity: Error +log: Always +module: fcscsib.c +action: Reboot system. If problem persists, contact Technical + Support. Run with verbose mode on for more details. +*/ +char fc_mes0226[] = "%sDevice Discovery completion error"; +msgLogDef fc_msgBlk0226 = { + FC_LOG_MSG_DI_0226, + fc_mes0226, + fc_msgPreambleDIe, + FC_MSG_OPUT_GLOB_CTRL, + FC_LOG_MSG_TYPE_ERR, + LOG_DISCOVERY, + ERRID_LOG_UNEXPECT_EVENT }; + +/* +msgName: fc_mes0227 +message: Node Authentication timeout +descript: The driver has lost track of what NPORTs are being authenticated. +data: None +severity: Error +log: Always +module: fcscsib.c +action: None required. Driver should recover from this event. +*/ +char fc_mes0227[] = "%sNode Authentication timeout"; +msgLogDef fc_msgBlk0227 = { + FC_LOG_MSG_DI_0227, + fc_mes0227, + fc_msgPreambleDIe, + FC_MSG_OPUT_GLOB_CTRL, + FC_LOG_MSG_TYPE_ERR, + LOG_DISCOVERY, + ERRID_LOG_TIMEOUT }; + +/* +msgName: fc_mes0228 +message: Node Discovery timeout +descript: The driver has lost track of what NPORTs are being discovered. +data: None +severity: Error +log: Always +module: fcscsib.c +action: None required. Driver should recover from this event. +*/ +char fc_mes0228[] = "%sNode Discovery timeout"; +msgLogDef fc_msgBlk0228 = { + FC_LOG_MSG_DI_0228, + fc_mes0228, + fc_msgPreambleDIe, + FC_MSG_OPUT_GLOB_CTRL, + FC_LOG_MSG_TYPE_ERR, + LOG_DISCOVERY, + ERRID_LOG_TIMEOUT }; + +/* +msgName: fc_mes0229 +message: Node Discovery timeout +descript: The driver has lost track of what NPORTs are being discovered. +data: (1) nlp_DID (2) nlp_flag (3) nlp_state (4) nlp_type +severity: Error +log: Always +module: fcscsib.c +action: None required. Driver should recover from this event. +*/ +char fc_mes0229[] = "%sNode Discovery timeout Data: x%x x%x x%x x%x"; +msgLogDef fc_msgBlk0229 = { + FC_LOG_MSG_DI_0229, + fc_mes0229, + fc_msgPreambleDIe, + FC_MSG_OPUT_GLOB_CTRL, + FC_LOG_MSG_TYPE_ERR, + LOG_DISCOVERY, + ERRID_LOG_TIMEOUT }; + +/* +msgName: fc_mes0230 +message: Device Discovery completion error +descript: This indicates an uncorrectable error was encountered + during device (re)discovery after a link up. Fibre + Channel devices will not be accessible if this message + is displayed. +data: None +severity: Error +log: Always +module: fcscsib.c +action: Reboot system. If problem persists, contact Technical + Support. Run with verbose mode on for more details. +*/ +char fc_mes0230[] = "%sDevice Discovery completion error"; +msgLogDef fc_msgBlk0230 = { + FC_LOG_MSG_DI_0230, + fc_mes0230, + fc_msgPreambleDIe, + FC_MSG_OPUT_GLOB_CTRL, + FC_LOG_MSG_TYPE_ERR, + LOG_DISCOVERY, + ERRID_LOG_UNEXPECT_EVENT }; + +/* +msgName: fc_mes0231 +message: RSCN timeout +descript: The driver has lost track of what NPORTs have RSCNs pending. +data: (1) fc_ns_retry (2) fc_max_ns_retry +severity: Error +log: Always +module: fcscsib.c +action: None required. Driver should recover from this event. +*/ +char fc_mes0231[] = "%sRSCN timeout Data: x%x x%x"; +msgLogDef fc_msgBlk0231 = { + FC_LOG_MSG_DI_0231, + fc_mes0231, + fc_msgPreambleDIe, + FC_MSG_OPUT_GLOB_CTRL, + FC_LOG_MSG_TYPE_ERR, + LOG_DISCOVERY, + ERRID_LOG_TIMEOUT }; + +/* +msgName: fc_mes0232 +message: Node RSCN timeout +descript: The driver is cleaning up the node table entry for a node + that had a pending RSCN. +data: (1) nlp_DID (2) nlp_flag (3) nlp_state (4) nlp_type +severity: Error +log: Always +module: fcscsib.c +action: None required. Driver should recover from this event. +*/ +char fc_mes0232[] = "%sNode RSCN timeout Data: x%x x%x x%x x%x"; +msgLogDef fc_msgBlk0232 = { + FC_LOG_MSG_DI_0232, + fc_mes0232, + fc_msgPreambleDIe, + FC_MSG_OPUT_GLOB_CTRL, + FC_LOG_MSG_TYPE_ERR, + LOG_DISCOVERY, + ERRID_LOG_TIMEOUT }; + +/* +msgName: fc_mes0233 +message: PT2PT link up timeout +descript: A PLOGI has not been received, within R_A_TOV, after a + successful FLOGI, which indicates our topology is + point-to-point with another NPort. Typically this PLOGI + is used to assign a NPortID. +data: None +severity: Warning +log: LOG_DISCOVERY verbose +module: fcscsib.c +action: None required. Driver will recover by configuring NPortID as 0. +*/ +char fc_mes0233[] = "%sPT2PT link up timeout"; +msgLogDef fc_msgBlk0233 = { + FC_LOG_MSG_DI_0233, + fc_mes0233, + fc_msgPreambleDIw, + FC_MSG_OPUT_GLOB_CTRL, + FC_LOG_MSG_TYPE_WARN, + LOG_DISCOVERY, + ERRID_LOG_TIMEOUT }; + +/* +msgName: fc_mes0234 +message: Device Discovery completes +descript: This indicates successful completion of device + (re)discovery after a link up. +data: None +severity: Information +log: LOG_DISCOVERY verbose +module: fcscsib.c +action: None required +*/ +char fc_mes0234[] = "%sDevice Discovery completes"; +msgLogDef fc_msgBlk0234 = { + FC_LOG_MSG_DI_0234, + fc_mes0234, + fc_msgPreambleDIi, + FC_MSG_OPUT_GLOB_CTRL, + FC_LOG_MSG_TYPE_INFO, + LOG_DISCOVERY, + ERRID_LOG_UNEXPECT_EVENT }; + +/* +msgName: fc_mes0235 +message: Device Discovery completion error +descript: This indicates an uncorrectable error was encountered + during device (re)discovery after a link up. Fibre + Channel devices will not be accessible if this message + is displayed. +data: None +severity: Error +log: Always +module: fcscsib.c +action: Reboot system. If problem persists, contact Technical + Support. Run with verbose mode on for more details. +*/ +char fc_mes0235[] = "%sDevice Discovery completion error"; +msgLogDef fc_msgBlk0235 = { + FC_LOG_MSG_DI_0235, + fc_mes0235, + fc_msgPreambleDIe, + FC_MSG_OPUT_GLOB_CTRL, + FC_LOG_MSG_TYPE_ERR, + LOG_DISCOVERY, + ERRID_LOG_UNEXPECT_EVENT }; + +/* +msgName: fc_mes0236 +message: NameServer Req +descript: The driver is issuing a nameserver request to the fabric. +data: (1) cmdcode (2) fc_flag (3) fc_rscn_id_cnt +severity: Information +log: LOG_DISCOVERY verbose +module: fcscsib.c +action: None required +*/ +char fc_mes0236[] = "%sNameServer Req Data: x%x x%x x%x"; +msgLogDef fc_msgBlk0236 = { + FC_LOG_MSG_DI_0236, + fc_mes0236, + fc_msgPreambleDIi, + FC_MSG_OPUT_GLOB_CTRL, + FC_LOG_MSG_TYPE_INFO, + LOG_DISCOVERY, + ERRID_LOG_UNEXPECT_EVENT }; + +/* +msgName: fc_mes0237 +message: Unknown Identifier in RSCN list +descript: A RSCN list entry contains an unknown identifier. +data: (1) rscn_did.un.word +severity: Error +log: Always +module: fcscsib.c +action: Potential problem with Fabric. Check with Fabric vendor. +*/ +char fc_mes0237[] = "%sUnknown Identifier in RSCN list Data: x%x"; +msgLogDef fc_msgBlk0237 = { + FC_LOG_MSG_DI_0237, + fc_mes0237, + fc_msgPreambleDIe, + FC_MSG_OPUT_GLOB_CTRL, + FC_LOG_MSG_TYPE_ERR, + LOG_DISCOVERY, + ERRID_LOG_UNEXPECT_EVENT }; + +/* +msgName: fc_mes0238 +message: NameServer Rsp +descript: The driver received a nameserver response. +data: (1) Did (2) nlp_flag (3) fc_flag (4) fc_rscn_id_cnt +severity: Information +log: LOG_DISCOVERY verbose +module: fcscsib.c +action: None required +*/ +char fc_mes0238[] = "%sNameServer Rsp Data: x%x x%x x%x x%x"; +msgLogDef fc_msgBlk0238 = { + FC_LOG_MSG_DI_0238, + fc_mes0238, + fc_msgPreambleDIi, + FC_MSG_OPUT_GLOB_CTRL, + FC_LOG_MSG_TYPE_INFO, + LOG_DISCOVERY, + ERRID_LOG_UNEXPECT_EVENT }; + +/* +msgName: fc_mes0239 +message: NameServer Rsp +descript: The driver received a nameserver response. +data: (1) Did (2) ndlp (3) fc_flag (4) fc_rscn_id_cnt +severity: Information +log: LOG_DISCOVERY verbose +module: fcscsib.c +action: None required +*/ +char fc_mes0239[] = "%sNameServer Rsp Data: x%x x%x x%x x%x"; +msgLogDef fc_msgBlk0239 = { + FC_LOG_MSG_DI_0239, + fc_mes0239, + fc_msgPreambleDIi, + FC_MSG_OPUT_GLOB_CTRL, + FC_LOG_MSG_TYPE_INFO, + LOG_DISCOVERY, + ERRID_LOG_UNEXPECT_EVENT }; + +/* +msgName: fc_mes0240 +message: NameServer Rsp Error +descript: The driver received a nameserver response containig a status error. +data: (1) CommandResponse.bits.CmdRsp (2) ReasonCode (3) Explanation + (4) fc_flag +severity: Information +log: LOG_DISCOVERY verbose +module: fcscsib.c +action: Check Fabric configuration. The driver recovers from this and + continues with device discovery. +*/ +char fc_mes0240[] = "%sNameServer Rsp Error Data: x%x x%x x%x x%x"; +msgLogDef fc_msgBlk0240 = { + FC_LOG_MSG_DI_0240, + fc_mes0240, + fc_msgPreambleDIi, + FC_MSG_OPUT_GLOB_CTRL, + FC_LOG_MSG_TYPE_INFO, + LOG_DISCOVERY, + ERRID_LOG_UNEXPECT_EVENT }; + +/* +msgName: fc_mes0241 +message: NameServer Rsp Error +descript: The driver received a nameserver response containing a status error. +data: (1) CommandResponse.bits.CmdRsp (2) ReasonCode (3) Explanation + (4) fc_flag +severity: Information +log: LOG_DISCOVERY verbose +module: fcscsib.c +action: Check Fabric configuration. The driver recovers from this and + continues with device discovery. +*/ +char fc_mes0241[] = "%sNameServer Rsp Error Data: x%x x%x x%x x%x"; +msgLogDef fc_msgBlk0241 = { + FC_LOG_MSG_DI_0241, + fc_mes0241, + fc_msgPreambleDIi, + FC_MSG_OPUT_GLOB_CTRL, + FC_LOG_MSG_TYPE_INFO, + LOG_DISCOVERY, + ERRID_LOG_UNEXPECT_EVENT }; + +/* +msgName: fc_mes0242 +message: Device Discovery nextnode +descript: The driver continuing with discovery. +data: (1) nlp_state (2) nlp_DID (3) nlp_flag (4) fc_ffstate +severity: Information +log: LOG_DISCOVERY verbose +module: fcscsib.c +action: None required +*/ +char fc_mes0242[] = "%sDevice Discovery nextnode Data: x%x x%x x%x x%x"; +msgLogDef fc_msgBlk0242 = { + FC_LOG_MSG_DI_0242, + fc_mes0242, + fc_msgPreambleDIi, + FC_MSG_OPUT_GLOB_CTRL, + FC_LOG_MSG_TYPE_INFO, + LOG_DISCOVERY, + ERRID_LOG_UNEXPECT_EVENT }; + +/* +msgName: fc_mes0243 +message: Device Discovery nextdisc +descript: The driver continuing with NPORT discovery. +data: (1) fc_nlp_cnt (2) sndcnt (3) fc_mbox_active +severity: Information +log: LOG_DISCOVERY verbose +module: fcscsib.c +action: None required +*/ +char fc_mes0243[] = "%sDevice Discovery nextdisc Data: x%x x%x x%x"; +msgLogDef fc_msgBlk0243 = { + FC_LOG_MSG_DI_0243, + fc_mes0243, + fc_msgPreambleDIi, + FC_MSG_OPUT_GLOB_CTRL, + FC_LOG_MSG_TYPE_INFO, + LOG_DISCOVERY, + ERRID_LOG_UNEXPECT_EVENT }; + +/* +msgName: fc_mes0244 +message: Device Discovery completion error +descript: This indicates an uncorrectable error was encountered + during device (re)discovery after a link up. Fibre + Channel devices will not be accessible if this message + is displayed. +data: None +severity: Error +log: Always +module: fcscsib.c +action: Reboot system. If problem persists, contact Technical + Support. Run with verbose mode on for more details. +*/ +char fc_mes0244[] = "%sDevice Discovery completion error"; +msgLogDef fc_msgBlk0244 = { + FC_LOG_MSG_DI_0244, + fc_mes0244, + fc_msgPreambleDIe, + FC_MSG_OPUT_GLOB_CTRL, + FC_LOG_MSG_TYPE_ERR, + LOG_DISCOVERY, + ERRID_LOG_UNEXPECT_EVENT }; + +/* +msgName: fc_mes0245 +message: Device Discovery next authentication +descript: The driver is continuing with NPORT authentication. +data: (1) fc_nlp_cnt (2) sndcnt (3) fc_mbox_active +severity: Information +log: LOG_DISCOVERY verbose +module: fcscsib.c +action: None required +*/ +char fc_mes0245[] = "%sDevice Discovery next authentication Data: x%x x%x x%x"; +msgLogDef fc_msgBlk0245 = { + FC_LOG_MSG_DI_0245, + fc_mes0245, + fc_msgPreambleDIi, + FC_MSG_OPUT_GLOB_CTRL, + FC_LOG_MSG_TYPE_INFO, + LOG_DISCOVERY, + ERRID_LOG_UNEXPECT_EVENT }; + +/* +msgName: fc_mes0246 +message: Device Discovery next RSCN +descript: The driver is continuing with RSCN processing. +data: (1) fc_nlp_cnt (2) sndcnt (3) fc_mbox_active (4) fc_flag +severity: Information +log: LOG_DISCOVERY verbose +module: fcscsib.c +action: None required +*/ +char fc_mes0246[] = "%sDevice Discovery next RSCN Data: x%x x%x x%x x%x"; +msgLogDef fc_msgBlk0246 = { + FC_LOG_MSG_DI_0246, + fc_mes0246, + fc_msgPreambleDIi, + FC_MSG_OPUT_GLOB_CTRL, + FC_LOG_MSG_TYPE_INFO, + LOG_DISCOVERY, + ERRID_LOG_UNEXPECT_EVENT }; + +/* +msgName: fc_mes0247 +message: Discovery RSCN +descript: The number / type of RSCNs has forced the driver to go to + the nameserver and re-discover all NPORTs. +data: (1) fc_defer_rscn.q_cnt (2) fc_flag (3) fc_rscn_disc_wdt +severity: Information +log: LOG_DISCOVERY verbose +module: fcscsib.c +action: None required +*/ +char fc_mes0247[] = "%sDiscovery RSCN Data: x%x x%x x%x"; +msgLogDef fc_msgBlk0247 = { + FC_LOG_MSG_DI_0247, + fc_mes0247, + fc_msgPreambleDIi, + FC_MSG_OPUT_GLOB_CTRL, + FC_LOG_MSG_TYPE_INFO, + LOG_DISCOVERY, + ERRID_LOG_UNEXPECT_EVENT }; + +/* +msgName: fc_mes0248 +message: Deferred RSCN +descript: The driver has received multiple RSCNs and has deferred the + processing of the most recent RSCN. +data: (1) fc_defer_rscn.q_cnt (2) fc_flag +severity: Information +log: LOG_DISCOVERY verbose +module: fcscsib.c +action: None required +*/ +char fc_mes0248[] = "%sDeferred RSCN Data: x%x x%x"; +msgLogDef fc_msgBlk0248 = { + FC_LOG_MSG_DI_0248, + fc_mes0248, + fc_msgPreambleDIi, + FC_MSG_OPUT_GLOB_CTRL, + FC_LOG_MSG_TYPE_INFO, + LOG_DISCOVERY, + ERRID_LOG_UNEXPECT_EVENT }; + +/* +msgName: fc_mes0249 +message: Device Discovery completes +descript: This indicates successful completion of device + (re)discovery after a link up. +data: (1) fc_flag +severity: Information +log: LOG_DISCOVERY verbose +module: fcscsib.c +action: None required +*/ +char fc_mes0249[] = "%sDevice Discovery completes Data: x%x"; +msgLogDef fc_msgBlk0249 = { + FC_LOG_MSG_DI_0249, + fc_mes0249, + fc_msgPreambleDIi, + FC_MSG_OPUT_GLOB_CTRL, + FC_LOG_MSG_TYPE_INFO, + LOG_DISCOVERY, + ERRID_LOG_UNEXPECT_EVENT }; + +/* +msgName: fc_mes0250 +message: Pending Link Event during Discovery +descript: Received link event during discovery. Causes discovery restart. +data: (1) ulpCommand (2) ulpIoTag (3) ulpStatus (4) ulpWord[4] +severity: Warning +log: LOG_DISCOVERY verbose +module: fcelsb.c +action: None required unless problem persist. If problems persist, check + cabling. +*/ +char fc_mes0250[] = "%sPending Link Event during Discovery Data: x%x x%x x%x x%x"; +msgLogDef fc_msgBlk0250 = { + FC_LOG_MSG_DI_0250, + fc_mes0250, + fc_msgPreambleDIw, + FC_MSG_OPUT_GLOB_CTRL, + FC_LOG_MSG_TYPE_WARN, + LOG_DISCOVERY, + ERRID_LOG_UNEXPECT_EVENT }; + +/* +msgName: fc_mes0251 +message: FDMI rsp failed +descript: An error response was received to FDMI request +data: (1) SWAP_DATA16(fdmi_cmd) +severity: Information +log: LOG_DISCOVERY verbose +module: fcelsb.c +action: The fabric does not support FDMI, check fabric configuration. +*/ +char fc_mes0251[] = "%sFDMI rsp failed Data: x%x"; +msgLogDef fc_msgBlk0251 = { + FC_LOG_MSG_DI_0251, + fc_mes0251, + fc_msgPreambleDIi, + FC_MSG_OPUT_GLOB_CTRL, + FC_LOG_MSG_TYPE_INFO, + LOG_DISCOVERY, + ERRID_LOG_UNEXPECT_EVENT }; + +/* +msgName: fc_mes0252 +message: EXPIRED RSCN disc timer +descript: The driver timed out when processing an RSCN command from the + fabric. +data: (1) fc_flag +severity: Information +log: LOG_DISCOVERY | LOG_ELS verbose +module: fcscsib.c +action: This error could indicate a software driver or firmware + problem. If problems persist report these errors to + Technical Support. +*/ +char fc_mes0252[] = "%sEXPIRED RSCN disc timer Data: x%x"; +msgLogDef fc_msgBlk0252 = { + FC_LOG_MSG_DI_0252, + fc_mes0252, + fc_msgPreambleDIi, + FC_MSG_OPUT_GLOB_CTRL, + FC_LOG_MSG_TYPE_INFO, + LOG_DISCOVERY | LOG_ELS, + ERRID_LOG_UNEXPECT_EVENT }; + +/* + * Begin MAILBOX LOG Message Structures + */ + +/* +msgName: fc_mes0300 +message: READ_LA: no buffers +descript: The driver attempted to issue READ_LA mailbox command to the HBA + but there were no buffer available. +data: None +severity: Warning +log: LOG_MBOX verbose +module: fcmboxb.c +action: This message indicates (1) a possible lack of memory resources. Try + increasing the lpfc 'num_bufs' configuration parameter to allocate + more buffers. (2) A possble driver buffer management problem. If + this problem persists, report these errors to Technical Support. +*/ +char fc_mes0300[] = "%sREAD_LA: no buffers"; +msgLogDef fc_msgBlk0300 = { + FC_LOG_MSG_MB_0300, + fc_mes0300, + fc_msgPreambleMBw, + FC_MSG_OPUT_GLOB_CTRL, + FC_LOG_MSG_TYPE_WARN, + LOG_MBOX, + ERRID_LOG_UNEXPECT_EVENT }; + +/* +msgName: fc_mes0301 +message: READ_SPARAM: no buffers +descript: The driver attempted to issue READ_SPARAM mailbox command to the + HBA but there were no buffer available. +data: None +severity: Warning +log: LOG_MBOX verbose +module: fcmboxb.c +action: This message indicates (1) a possible lack of memory resources. Try + increasing the lpfc 'num_bufs' configuration parameter to allocate + more buffers. (2) A possble driver buffer management problem. If + this problem persists, report these errors to Technical Support. +*/ +char fc_mes0301[] = "%sREAD_SPARAM: no buffers"; +msgLogDef fc_msgBlk0301 = { + FC_LOG_MSG_MB_0301, + fc_mes0301, + fc_msgPreambleMBw, + FC_MSG_OPUT_GLOB_CTRL, + FC_LOG_MSG_TYPE_WARN, + LOG_MBOX, + ERRID_LOG_UNEXPECT_EVENT }; + +/* +msgName: fc_mes0302 +message: REG_LOGIN: no buffers +descript: The driver attempted to issue REG_LOGIN mailbox command to the HBA + but there were no buffer available. +data: None +severity: Warning +log: LOG_MBOX verbose +module: fcmboxb.c +action: This message indicates (1) a possible lack of memory resources. Try + increasing the lpfc 'num_bufs' configuration parameter to allocate + more buffers. (2) A possble driver buffer management problem. If + this problem persists, report these errors to Technical Support. +*/ +char fc_mes0302[] = "%sREG_LOGIN: no buffers Data x%x x%x"; +msgLogDef fc_msgBlk0302 = { + FC_LOG_MSG_MB_0302, + fc_mes0302, + fc_msgPreambleMBw, + FC_MSG_OPUT_GLOB_CTRL, + FC_LOG_MSG_TYPE_WARN, + LOG_MBOX, + ERRID_LOG_UNEXPECT_EVENT }; + +/* +msgName: fc_mes0303 +message: Adapter initialization error, mbxCmd READ_NVPARM, + mbxStatus +descript: A mailbox command failed during initialization. +data: None +severity: Error +log: Always +module: fcLINUX.c +action: This error could indicate a hardware or firmware problem. If + problems persist report these errors to Technical Support. +*/ +char fc_mes0303[] = "%sAdapter init error, mbxCmd x%x READ_NVPARM, mbxStatus x%x"; +msgLogDef fc_msgBlk0303 = { + FC_LOG_MSG_MB_0303, + fc_mes0303, + fc_msgPreambleINe, + FC_MSG_OPUT_GLOB_CTRL, + FC_LOG_MSG_TYPE_ERR, + LOG_INIT, + ERRID_LOG_UNEXPECT_EVENT }; + +/* +msgName: fc_mes0304 +message: Stray Mailbox Interrupt, mbxCommand mbxStatus . +descript: Received a mailbox completion interrupt and there are no + outstanding mailbox commands. +data: None +severity: Error +log: Always +module: lp6000.c +action: This error could indicate a hardware or firmware problem. If + problems persist report these errors to Technical Support. +*/ +char fc_mes0304[] = "%sStray Mailbox Interrupt mbxCommand x%x mbxStatus x%x"; +msgLogDef fc_msgBlk0304 = { + FC_LOG_MSG_MB_0304, + fc_mes0304, + fc_msgPreambleMBe, + FC_MSG_OPUT_GLOB_CTRL, + FC_LOG_MSG_TYPE_ERR, + LOG_MBOX, + ERRID_LOG_UNEXPECT_EVENT }; + +/* +msgName: fc_mes0305 +message: Mbox cmd cmpl error - RETRYing +descript: A mailbox command completed with an error status that causes the + driver to reissue the mailbox command. +data: (1) mbxCommand (2) word0 (3) fc_ffstate (4) fc_flag +severity: Information +log: LOG_MBOX verbose +module: lp6000.c +action: None required +*/ +char fc_mes0305[] = "%sMbox cmd cmpl error - RETRYing Data: x%x x%x x%x x%x"; +msgLogDef fc_msgBlk0305 = { + FC_LOG_MSG_MB_0305, + fc_mes0305, + fc_msgPreambleMBi, + FC_MSG_OPUT_GLOB_CTRL, + FC_LOG_MSG_TYPE_INFO, + LOG_MBOX, + ERRID_LOG_UNEXPECT_EVENT }; + +/* +msgName: fc_mes0306 +message: Mbox cmd cmpl error +descript: A mailbox command completed with an error status. +data: (1) mbxCommand (2) word0 (3) ff_state (4) fc_flag +severity: Information +log: LOG_MBOX verbose +module: lp6000.c +action: None required +*/ +char fc_mes0306[] = "%sMbox cmd cmpl error Data: x%x x%x x%x x%x"; +msgLogDef fc_msgBlk0306 = { + FC_LOG_MSG_MB_0306, + fc_mes0306, + fc_msgPreambleMBi, + FC_MSG_OPUT_GLOB_CTRL, + FC_LOG_MSG_TYPE_INFO, + LOG_MBOX, + ERRID_LOG_UNEXPECT_EVENT }; + +/* +msgName: fc_mes0307 +message: Mbox cmd cmpl +descript: A mailbox command completed.. +data: (1) mbxCommand (2) word0 (3) ff_state (4) fc_flag +severity: Information +log: LOG_MBOX verbose +module: lp6000.c +action: None required +*/ +char fc_mes0307[] = "%sMbox cmd cmpl Data: x%x x%x x%x x%x"; +msgLogDef fc_msgBlk0307 = { + FC_LOG_MSG_MB_0307, + fc_mes0307, + fc_msgPreambleMBi, + FC_MSG_OPUT_GLOB_CTRL, + FC_LOG_MSG_TYPE_INFO, + LOG_MBOX, + ERRID_LOG_UNEXPECT_EVENT }; + +/* +msgName: fc_mes0308 +message: Mbox cmd issue - BUSY +descript: The driver attempted to issue a mailbox command while the mailbox + was busy processing the previous command. The processing of the + new command will be deferred until the mailbox becomes available. +data: (1) mbxCommand (2) ff_state (3) fc_flag (4) flag +severity: Information +log: LOG_MBOX verbose +module: lp6000.c +action: None required +*/ +char fc_mes0308[] = "%sMbox cmd issue - BUSY Data: x%x x%x x%x x%x"; +msgLogDef fc_msgBlk0308 = { + FC_LOG_MSG_MB_0308, + fc_mes0308, + fc_msgPreambleMBi, + FC_MSG_OPUT_GLOB_CTRL, + FC_LOG_MSG_TYPE_INFO, + LOG_MBOX, + ERRID_LOG_UNEXPECT_EVENT }; + +/* +msgName: fc_mes0309 +message: Mailbox cmd issue +descript: The driver is in the process of issuing a mailbox command. +data: (1) ff_state (2) fc_flag (3) flag +severity: Information +log: LOG_MBOX verbose +module: lp6000.c +action: None required +*/ +char fc_mes0309[] = "%sMailbox cmd x%x issue Data: x%x x%x x%x"; +msgLogDef fc_msgBlk0309 = { + FC_LOG_MSG_MB_0309, + fc_mes0309, + fc_msgPreambleMBi, + FC_MSG_OPUT_GLOB_CTRL, + FC_LOG_MSG_TYPE_INFO, + LOG_MBOX, + ERRID_LOG_UNEXPECT_EVENT }; + +/* +msgName: fc_mes0310 +message: Mailbox command timeout, status +descript: A Mailbox command was posted to the adapter and did + not complete within 30 seconds. +data: None +severity: Error +log: Always +module: fcscsib.c +action: This error could indicate a software driver or firmware + problem. If no I/O is going through the adapter, reboot + the system. If these problems persist, report these + errors to Technical Support. +*/ +char fc_mes0310[] = "%sMailbox command x%x timeout, status x%x"; +msgLogDef fc_msgBlk0310 = { + FC_LOG_MSG_MB_0310, + fc_mes0310, + fc_msgPreambleMBe, + FC_MSG_OPUT_GLOB_CTRL, + FC_LOG_MSG_TYPE_ERR, + LOG_MBOX, + ERRID_LOG_TIMEOUT }; + +/* +msgName: fc_mes0311 +message: REG_LOGIN cmpl +descript: REG LOGIN mailbox command completed successfully. +data: (1) nlp_DID (2) nlp_state (3) nlp_flag (4) nlp_Rpi +severity: Information +log: LOG_MBOX verbose +module: fcscsib.c +action: None required +*/ +char fc_mes0311[] = "%sREG_LOGIN cmpl Data: x%x x%x x%x x%x"; +msgLogDef fc_msgBlk0311 = { + FC_LOG_MSG_MB_0311, + fc_mes0311, + fc_msgPreambleMBi, + FC_MSG_OPUT_GLOB_CTRL, + FC_LOG_MSG_TYPE_INFO, + LOG_MBOX, + ERRID_LOG_UNEXPECT_EVENT }; + +/* +msgName: fc_mes0312 +message: Unknown Mailbox command completion +descript: An unsupported or illegal Mailbox command completed. +data: None +severity: Error +log: Always +module: fcscsib.c +action: This error could indicate a software driver or firmware + problem. If problems persist report these errors to + Technical Support. +*/ +char fc_mes0312[] = "%sUnknown Mailbox command x%x completion"; +msgLogDef fc_msgBlk0312 = { + FC_LOG_MSG_MB_0312, + fc_mes0312, + fc_msgPreambleMBe, + FC_MSG_OPUT_GLOB_CTRL, + FC_LOG_MSG_TYPE_ERR, + LOG_MBOX, + ERRID_LOG_UNEXPECT_EVENT }; + +/* + * Begin INIT LOG Message Structures + */ + +/* +msgName: fc_mes0400 +message: dfc_ioctl entry +descript: Entry point for processing diagnostic ioctl. +data: (1) c_cmd (2) c_arg1 (3) c_arg2 (4) c_outsz +severity: Information +log: LOG_INIT verbose +module: dfcdd.c +action: None required +*/ +char fc_mes0400[] = "%sdfc_ioctl entry Data: x%x x%x x%x x%x"; +msgLogDef fc_msgBlk0400 = { + FC_LOG_MSG_IN_0400, + fc_mes0400, + fc_msgPreambleINi, + FC_MSG_OPUT_GLOB_CTRL, + FC_LOG_MSG_TYPE_INFO, + LOG_INIT, + ERRID_LOG_UNEXPECT_EVENT }; + +/* +msgName: fc_mes0401 +message: dfc_ioctl exit +descript: Exit point for processing diagnostic ioctl. +data: (1) rc (2) c_outsz (3) c_dataout +severity: Information +log: LOG_INIT verbose +module: dfcdd.c +action: None required +*/ +char fc_mes0401[] = "%sdfc_ioctl exit Data: x%x x%x x%x"; +msgLogDef fc_msgBlk0401 = { + FC_LOG_MSG_IN_0401, + fc_mes0401, + fc_msgPreambleINi, + FC_MSG_OPUT_GLOB_CTRL, + FC_LOG_MSG_TYPE_INFO, + LOG_INIT, + ERRID_LOG_UNEXPECT_EVENT }; + +/* +msgName: fc_mes0402 +message: dfc_data_alloc +descript: Allocating data buffer to process dfc ioct. +data: (1) fc_dataout (2) fc_outsz +severity: Iniformation +log: LOG_INIT verbose +module: dfcdd.c +action: None required +*/ +char fc_mes0402[] = "%sdfc_data_alloc Data: x%x x%x"; +msgLogDef fc_msgBlk0402 = { + FC_LOG_MSG_IN_0402, + fc_mes0402, + fc_msgPreambleINi, + FC_MSG_OPUT_GLOB_CTRL, + FC_LOG_MSG_TYPE_INFO, + LOG_INIT, + ERRID_LOG_UNEXPECT_EVENT }; + +/* +msgName: fc_mes0403 +message: dfc_data_free +descript: Freeing data buffer to process dfc ioct. +data: (1) fc_dataout (2) fc_outsz +severity: Information +log: LOG_INIT verbose +module: dfcdd.c +action: None required +*/ +char fc_mes0403[] = "%sdfc_data_free Data: x%x x%x"; +msgLogDef fc_msgBlk0403 = { + FC_LOG_MSG_IN_0403, + fc_mes0403, + fc_msgPreambleINi, + FC_MSG_OPUT_GLOB_CTRL, + FC_LOG_MSG_TYPE_INFO, + LOG_INIT, + ERRID_LOG_UNEXPECT_EVENT }; + +/* +msgName: fc_mes0404 +message: Service Level Interface (SLI) 1 selected +descript: A PART_SLIM (SLI1) mailbox command was issued. +data: None +severity: Information +log: LOG_INIT verbose +module: fcmboxb.c +action: None required. +*/ +char fc_mes0404[] = "%sService Level Interface (SLI) 1 selected"; +msgLogDef fc_msgBlk0404 = { + FC_LOG_MSG_IN_0404, + fc_mes0404, + fc_msgPreambleINi, + FC_MSG_OPUT_GLOB_CTRL, + FC_LOG_MSG_TYPE_INFO, + LOG_INIT, + ERRID_LOG_UNEXPECT_EVENT }; + +/* +msgName: fc_mes0405 +message: Service Level Interface (SLI) 2 selected +descript: A CONFIG_PORT (SLI2) mailbox command was issued. +data: None +severity: Information +log: LOG_INIT verbose +module: fcmboxb.c +action: None required. +*/ +char fc_mes0405[] = "%sService Level Interface (SLI) 2 selected"; +msgLogDef fc_msgBlk0405 = { + FC_LOG_MSG_IN_0405, + fc_mes0405, + fc_msgPreambleINi, + FC_MSG_OPUT_GLOB_CTRL, + FC_LOG_MSG_TYPE_INFO, + LOG_INIT, + ERRID_LOG_UNEXPECT_EVENT }; + +/* +msgName: fc_mes0406 +message: Memory Buffer Pool is below low water mark +descript: A driver memory buffer pool is low on buffers. +data: (1) seg (2) fc_lowmem (3) low +severity: Warning +log: LOG_INIT verbose +module: fcmemb.c +action: None required. Driver will recover as buffers are returned to pool. +*/ +char fc_mes0406[] = "%sMem Buf Pool is below low water mark Data: x%x x%x x%x"; +msgLogDef fc_msgBlk0406 = { + FC_LOG_MSG_IN_0406, + fc_mes0406, + fc_msgPreambleINw, + FC_MSG_OPUT_GLOB_CTRL, + FC_LOG_MSG_TYPE_WARN, + LOG_INIT, + ERRID_LOG_NO_RESOURCE }; + +/* +msgName: fc_mes0407 +message: Memory Buffer Pool is corrupted +descript: The buffer address received from the pool is outside + the range of the pool and is therefore corrupt. +data: (1) seg (2) bp (3) fc_memhi (4) fc_memlo +severity: Error +log: Always +module: fcmemb.c +action: This error could indicate a software driver or firmware + problem. If problems persist report these errors to + Technical Support. +*/ +char fc_mes0407[] = "%sMemory Buffer Pool is corrupted Data x%x x%x x%x x%x"; +msgLogDef fc_msgBlk0407 = { + FC_LOG_MSG_IN_0407, + fc_mes0407, + fc_msgPreambleINe, + FC_MSG_OPUT_GLOB_CTRL, + FC_LOG_MSG_TYPE_ERR, + LOG_INIT, + ERRID_LOG_NO_RESOURCE }; + +/* +msgName: fc_mes0408 +message: Memory Buffer Pool is corrupted +descript: The buffer address returned to the pool is outside + the range of the pool and is therefore corrupt. +data: (1) seg (2) bp (3) fc_memhi (4) fc_memlo +severity: Error +log: Always +module: fcmemb.c +action: This error could indicate a software driver or firmware + problem. If problems persist report these errors to + Technical Support. +*/ +char fc_mes0408[] = "%sMemory Buffer Pool is corrupted Data x%x x%x x%x x%x"; +msgLogDef fc_msgBlk0408 = { + FC_LOG_MSG_IN_0408, + fc_mes0408, + fc_msgPreambleINe, + FC_MSG_OPUT_GLOB_CTRL, + FC_LOG_MSG_TYPE_ERR, + LOG_INIT, + ERRID_LOG_NO_RESOURCE }; + +/* +msgName: fc_mes0409 +message: Memory Buffer Pool is out of buffers +descript: A driver memory buffer pool is exhausted. +data: (1) seg (2) fc_free (3) fc_mbox.q_cnt (4) fc_memhi +severity: Error +log: Always +module: fcmemb.c +action: Configure more resources for that buffer pool. If + problems persist report these errors to Technical + Support. +*/ +char fc_mes0409[] = "%sMemory Buffer Pool is out of buffers Data x%x x%x x%x x%x"; +msgLogDef fc_msgBlk0409 = { + FC_LOG_MSG_IN_0409, + fc_mes0409, + fc_msgPreambleINe, + FC_MSG_OPUT_GLOB_CTRL, + FC_LOG_MSG_TYPE_ERR, + LOG_INIT, + ERRID_LOG_NO_RESOURCE }; + +/* +msgName: fc_mes0410 +message: Cannot find virtual addr for mapped buf on ring +descript: The driver cannot find the specified buffer in its + mapping table. Thus it cannot find the virtual address + needed to access the data. +data: (1) mapbp (2) fc_mpoff (3) fc_mpon +severity: Error +log: Always +module: fcmemb.c +action: This error could indicate a software driver or firmware + problem. If problems persist report these errors to + Technical Support. +*/ +char fc_mes0410[] = "%sCannot find virtual addr for mapped buf on ring %d Data x%x x%x x%x"; +msgLogDef fc_msgBlk0410 = { + FC_LOG_MSG_IN_0410, + fc_mes0410, + fc_msgPreambleINe, + FC_MSG_OPUT_GLOB_CTRL, + FC_LOG_MSG_TYPE_ERR, + LOG_INIT, + ERRID_LOG_NO_RESOURCE }; + +/* +msgName: fc_mes0411 +message: Scan-down is 2 with Persistent binding - ignoring scan-down +descript: The configuration parameter for Scan-down conflicts with + Persistent binding parameter. +data: (1) a_current (2) fcp_mapping +severity: Error config +log: Always +module: fcLINUXfcp.c +action: Make neccessary changes to lpfc configuration file. +*/ +char fc_mes0411[] = "%sScan-down is 2 with Persistent binding - ignoring scan-down Data: x%x x%x"; +msgLogDef fc_msgBlk0411 = { + FC_LOG_MSG_IN_0411, + fc_mes0411, + fc_msgPreambleINc, + FC_MSG_OPUT_GLOB_CTRL, + FC_LOG_MSG_TYPE_ERR_CFG, + LOG_INIT, + ERRID_LOG_INIT }; + +/* +msgName: fc_mes0412 +message: Scan-down is out of range - ignoring scan-down +descript: The configuration parameter for Scan-down is out of range. +data: (1) clp[CFG_SCAN_DOWN].a_current (2) fcp_mapping +severity: Error +log: Always +module: fcLINUXfcp.c +action: Make neccessary changes to lpfc configuration file. +*/ +char fc_mes0412[] = "%sScan-down is out of range - ignoring scan-down Data: x%x x%x"; +msgLogDef fc_msgBlk0412 = { + FC_LOG_MSG_IN_0412, + fc_mes0412, + fc_msgPreambleINe, + FC_MSG_OPUT_GLOB_CTRL, + FC_LOG_MSG_TYPE_ERR, + LOG_INIT, + ERRID_LOG_INIT }; + +/* +msgName: fc_mes0413 +message: Num-iocbs too low, resetting +descript: The configuration parameter for Num-iocs is too low, resetting + parameter to default value. +data: (1) a_current (2) LPFC_MIN_NUM_IOCBS +severity: Error config +log: Always +module: fcLINUXfcp.c +action: Make neccessary changes to lpfc configuration file. +*/ +char fc_mes0413[] = "%sNum-iocbs too low, resetting Data: x%x x%x"; +msgLogDef fc_msgBlk0413 = { + FC_LOG_MSG_IN_0413, + fc_mes0413, + fc_msgPreambleINc, + FC_MSG_OPUT_GLOB_CTRL, + FC_LOG_MSG_TYPE_ERR_CFG, + LOG_INIT, + ERRID_LOG_INIT }; + +/* +msgName: fc_mes0414 +message: Num-iocbs too high, resetting +descript: The configuration parameter for Num-iocs is too high, resetting + parameter to default value. +data: (1) clp[CFG_NUM_IOCBS].a_current (2) LPFC_MAX_NUM_IOCBS +severity: Error config +log: Always +module: fcLINUXfcp.c +action: Make neccessary changes to lpfc configuration file. +*/ +char fc_mes0414[] = "%sNum-iocbs too high, resetting Data: x%x x%x"; +msgLogDef fc_msgBlk0414 = { + FC_LOG_MSG_IN_0414, + fc_mes0414, + fc_msgPreambleINc, + FC_MSG_OPUT_GLOB_CTRL, + FC_LOG_MSG_TYPE_ERR_CFG, + LOG_INIT, + ERRID_LOG_INIT }; + +/* +msgName: fc_mes0415 +message: Num-bufs too low, resetting +descript: The configuration parameter for Num-bufs is too low, resetting + parameter to default value. +data: (1) a_current (2) LPFC_MIN_NUM_BUFS +severity: Error config +log: Always +module: fcLINUXfcp.c +action: Make neccessary changes to lpfc configuration file. +*/ +char fc_mes0415[] = "%sNum-bufs too low, resetting Data: x%x x%x"; +msgLogDef fc_msgBlk0415 = { + FC_LOG_MSG_IN_0415, + fc_mes0415, + fc_msgPreambleINc, + FC_MSG_OPUT_GLOB_CTRL, + FC_LOG_MSG_TYPE_ERR_CFG, + LOG_INIT, + ERRID_LOG_INIT }; + +/* +msgName: fc_mes0416 +message: Num-bufs too high, resetting +descript: The configuration parameter for Num-bufs is too high, resetting + parameter to default value. +data: (1) a_current (2) LPFC_MAX_NUM_BUFS +severity: Error config +log: Always +module: fcLINUXfcp.c +action: Make neccessary changes to lpfc configuration file. +*/ +char fc_mes0416[] = "%sNum-bufs too high, resetting Data: x%x x%x"; +msgLogDef fc_msgBlk0416 = { + FC_LOG_MSG_IN_0416, + fc_mes0416, + fc_msgPreambleINc, + FC_MSG_OPUT_GLOB_CTRL, + FC_LOG_MSG_TYPE_ERR_CFG, + LOG_INIT, + ERRID_LOG_INIT }; + +/* +msgName: fc_mes0417 +message: Target qdepth too high, resetting to max +descript: The configuration parameter for Target queue depth is too high, + resetting parameter to default value. +data: (1) a_current (2) LPFC_MAX_TGT_Q_DEPTH +severity: Error config +log: Always +module: fcLINUXfcp.c +action: Make neccessary changes to lpfc configuration file. +*/ +char fc_mes0417[] = "%sTarget qdepth too high, resetting to max Data: x%x x%x"; +msgLogDef fc_msgBlk0417 = { + FC_LOG_MSG_IN_0417, + fc_mes0417, + fc_msgPreambleINc, + FC_MSG_OPUT_GLOB_CTRL, + FC_LOG_MSG_TYPE_ERR_CFG, + LOG_INIT, + ERRID_LOG_INIT }; + +/* +msgName: fc_mes0418 +message: LUN qdepth too high, resetting to max +descript: The configuration parameter for LUN queue depth is too high, + resetting parameter to maximum default value. +data: (1) a_current (2) LPFC_MAX_LUN_Q_DEPTH +severity: Error config +log: Always +module: fcLINUXfcp.c +action: Make neccessary changes to lpfc configuration file. +*/ +char fc_mes0418[] = "%sLUN qdepth too high, resetting to max Data: x%x x%x"; +msgLogDef fc_msgBlk0418 = { + FC_LOG_MSG_IN_0418, + fc_mes0418, + fc_msgPreambleINc, + FC_MSG_OPUT_GLOB_CTRL, + FC_LOG_MSG_TYPE_ERR_CFG, + LOG_INIT, + ERRID_LOG_INIT }; + +/* +msgName: fc_mes0419 +message: LUN qdepth cannot be , resetting to 1 +descript: The configuration parameter for LUN queue depth is set to 0. + Resetting parameter to default value of 1. +data: (1) a_current +severity: Error config +log: Always +module: fcLINUXfcp.c +action: Make neccessary changes to lpfc configuration file. +*/ +char fc_mes0419[] = "%sLUN qdepth cannot be %d, resetting to 1"; +msgLogDef fc_msgBlk0419 = { + FC_LOG_MSG_IN_0419, + fc_mes0419, + fc_msgPreambleINc, + FC_MSG_OPUT_GLOB_CTRL, + FC_LOG_MSG_TYPE_ERR_CFG, + LOG_INIT, + ERRID_LOG_INIT }; + +/* +msgName: fc_mes0420 +message: Fcpfabric_tmo too high, resetting +descript: The configuration parameter for Fcpfabric_tmo is too high, + resetting parameter to default value. +data: (1) a_current (2) LPFC_MAX_FABRIC_TIMEOUT +severity: Error config +log: Always +module: fcLINUXfcp.c +action: Make neccessary changes to lpfc configuration file. +*/ +char fc_mes0420[] = "%sFcpfabric_tmo too high, resetting Data: x%x x%x"; +msgLogDef fc_msgBlk0420 = { + FC_LOG_MSG_IN_0420, + fc_mes0420, + fc_msgPreambleINc, + FC_MSG_OPUT_GLOB_CTRL, + FC_LOG_MSG_TYPE_ERR_CFG, + LOG_INIT, + ERRID_LOG_INIT }; + +/* +msgName: fc_mes0421 +message: Fcp-class is illegal, resetting to default +descript: The configuration parameter for Fcp-class is illegal, resetting + parameter to default value. +data: (1) a_current (2) CLASS3 +severity: Error config +log: Always +module: fcLINUXfcp.c +action: Make neccessary changes to lpfc configuration file. +*/ +char fc_mes0421[] = "%sFcp-class is illegal, resetting Data: x%x x%x"; +msgLogDef fc_msgBlk0421 = { + FC_LOG_MSG_IN_0421, + fc_mes0421, + fc_msgPreambleINc, + FC_MSG_OPUT_GLOB_CTRL, + FC_LOG_MSG_TYPE_ERR_CFG, + LOG_INIT, + ERRID_LOG_INIT }; + +/* +msgName: fc_mes0422 +message: No-device-delay too high, resetting to max +descript: The configuration parameter for No-device-delay is too high, + resetting parameter to maximum default value. +data: (1) a_current (2) LPFC_MAX_NO_DEVICE_DELAY +severity: Error config +log: Always +module: fcLINUXfcp.c +action: Make neccessary changes to lpfc configuration file. +*/ +char fc_mes0422[] = "%sNo-device-delay too high, resetting to max Data: x%x x%x"; +msgLogDef fc_msgBlk0422 = { + FC_LOG_MSG_IN_0422, + fc_mes0422, + fc_msgPreambleINc, + FC_MSG_OPUT_GLOB_CTRL, + FC_LOG_MSG_TYPE_ERR_CFG, + LOG_INIT, + ERRID_LOG_INIT }; + +/* +msgName: fc_mes0423 +message: Post_ip_buf too low, resetting +descript: The configuration parameter for Post_ip_buf is too low, resetting + parameter to default value. +data: (1) a_current (2) LPFC_MIN_POST_IP_BUF +severity: Error config +log: Always +module: fcLINUXfcp.c +action: Make neccessary changes to lpfc configuration file. +*/ +char fc_mes0423[] = "%sPost_ip_buf too low, resetting Data: x%x x%x"; +msgLogDef fc_msgBlk0423 = { + FC_LOG_MSG_IN_0423, + fc_mes0423, + fc_msgPreambleINc, + FC_MSG_OPUT_GLOB_CTRL, + FC_LOG_MSG_TYPE_ERR_CFG, + LOG_INIT, + ERRID_LOG_INIT }; + +/* +msgName: fc_mes0424 +message: Post_ip_buf too high, resetting +descript: The configuration parameter for Post_ip_buf is too high, resetting + parameter to default value. +data: (1) a_current (2) LPFC_MAX_POST_IP_BUF +severity: Error config +log: Always +module: fcLINUXfcp.c +action: Make neccessary changes to lpfc configuration file. +*/ +char fc_mes0424[] = "%sPost_ip_buf too high, resetting Data: x%x x%x"; +msgLogDef fc_msgBlk0424 = { + FC_LOG_MSG_IN_0424, + fc_mes0424, + fc_msgPreambleINc, + FC_MSG_OPUT_GLOB_CTRL, + FC_LOG_MSG_TYPE_ERR_CFG, + LOG_INIT, + ERRID_LOG_INIT }; + +/* +msgName: fc_mes0425 +message: Xmt-que_size too low, resetting +descript: The configuration parameter for Xmt-que_size is too low, resetting + parameter to default value. +data: (1) a_current (2) LPFC_MIN_XMT_QUE_SIZE +severity: Error config +log: Always +module: fcLINUXcp.c +action: Make neccessary changes to lpfc configuration file. +*/ +char fc_mes0425[] = "%sXmt-que_size too low, resetting Data: x%x x%x"; +msgLogDef fc_msgBlk0425 = { + FC_LOG_MSG_IN_0425, + fc_mes0425, + fc_msgPreambleINc, + FC_MSG_OPUT_GLOB_CTRL, + FC_LOG_MSG_TYPE_ERR_CFG, + LOG_INIT, + ERRID_LOG_INIT }; + +/* +msgName: fc_mes0426 +message: Xmt-que_size too high, resetting +descript: The configuration parameter for Xmt-que_size is too high, resetting + parameter to default value. +data: (1) a_current (2) LPFC_MAX_XMT_QUE_SIZE +severity: Error config +log: Always +module: fcLINUXfcp.c +action: Make neccessary changes to lpfc configuration file. +*/ +char fc_mes0426[] = "%sXmt-que_size too high, resetting Data: x%x x%x"; +msgLogDef fc_msgBlk0426 = { + FC_LOG_MSG_IN_0426, + fc_mes0426, + fc_msgPreambleINc, + FC_MSG_OPUT_GLOB_CTRL, + FC_LOG_MSG_TYPE_ERR_CFG, + LOG_INIT, + ERRID_LOG_INIT }; + +/* +msgName: fc_mes0427 +message: Ip-class is illegal, resetting +descript: The configuration parameter for Ip-class is illegal, resetting + parameter to default value. +data: (1) a_current (2) CLASS3 +severity: Error config +log: Always +module: fcLINUXfcp.c +action: Make neccessary changes to lpfc configuration file. +*/ +char fc_mes0427[] = "%sIp-class is illegal, resetting Data: x%x x%x"; +msgLogDef fc_msgBlk0427 = { + FC_LOG_MSG_IN_0427, + fc_mes0427, + fc_msgPreambleINc, + FC_MSG_OPUT_GLOB_CTRL, + FC_LOG_MSG_TYPE_ERR_CFG, + LOG_INIT, + ERRID_LOG_INIT }; + +/* +msgName: fc_mes0428 +message: Topology is illegal, resetting +descript: The configuration parameter for Topology is illegal, resetting + parameter to default value. +data: (1) a_current (2) LPFC_DFT_TOPOLOGY +severity: Error config +log: Always +module: fcLINUXfcp.c +action: Make neccessary changes to lpfc configuration file. +*/ +char fc_mes0428[] = "%sTopology is illegal, resetting Data: x%x x%x"; +msgLogDef fc_msgBlk0428 = { + FC_LOG_MSG_IN_0428, + fc_mes0428, + fc_msgPreambleINc, + FC_MSG_OPUT_GLOB_CTRL, + FC_LOG_MSG_TYPE_ERR_CFG, + LOG_INIT, + ERRID_LOG_INIT }; + +/* +msgName: fc_mes0429 +message: Linkdown_tmo too high, resetting +descript: The configuration parameter for Linkdown_tmo is too high, resetting + parameter to default value. +data: (1) a_current (2) LPFC_MAX_LNKDWN_TIMEOUT +severity: Error config +log: Always +module: fcLINUXfcp.c +action: Make neccessary changes to lpfc configuration file. +*/ +char fc_mes0429[] = "%sLinkdown_tmo too high, resetting Data: x%x x%x"; +msgLogDef fc_msgBlk0429 = { + FC_LOG_MSG_IN_0429, + fc_mes0429, + fc_msgPreambleINc, + FC_MSG_OPUT_GLOB_CTRL, + FC_LOG_MSG_TYPE_ERR_CFG, + LOG_INIT, + ERRID_LOG_INIT }; + +/* +msgName: fc_mes0430 +message: WWPN binding entry : Syntax error code +descript: A syntax error occured while parsing WWPN binding + configuraion information. +data: None +detail: Binding syntax error codes + 0 FC_SYNTAX_OK + 1 FC_SYNTAX_OK_BUT_NOT_THIS_BRD + 2 FC_SYNTAX_ERR_ASC_CONVERT + 3 FC_SYNTAX_ERR_EXP_COLON + 4 FC_SYNTAX_ERR_EXP_LPFC + 5 FC_SYNTAX_ERR_INV_LPFC_NUM + 6 FC_SYNTAX_ERR_EXP_T + 7 FC_SYNTAX_ERR_INV_TARGET_NUM + 8 FC_SYNTAX_ERR_EXP_D + 9 FC_SYNTAX_ERR_INV_DEVICE_NUM + 10 FC_SYNTAX_ERR_INV_RRATIO_NUM + 11 FC_SYNTAX_ERR_EXP_NULL_TERM +severity: Error config +log: Always +module: fcLINUXfcp.c +action: Make neccessary changes to lpfc configuration file. +*/ +char fc_mes0430[] = "%sWWPN binding entry %d: Syntax error code %d"; +msgLogDef fc_msgBlk0430 = { + FC_LOG_MSG_IN_0430, + fc_mes0430, + fc_msgPreambleINc, + FC_MSG_OPUT_GLOB_CTRL, + FC_LOG_MSG_TYPE_ERR_CFG, + LOG_INIT, + ERRID_LOG_INIT }; + +/* +msgName: fc_mes0431 +message: WWNN binding entry : Syntax error code +descript: A syntax error occured while parsing WWNN binding + configuraion information. +data: None +detail: Binding syntax error codes + 0 FC_SYNTAX_OK + 1 FC_SYNTAX_OK_BUT_NOT_THIS_BRD + 2 FC_SYNTAX_ERR_ASC_CONVERT + 3 FC_SYNTAX_ERR_EXP_COLON + 4 FC_SYNTAX_ERR_EXP_LPFC + 5 FC_SYNTAX_ERR_INV_LPFC_NUM + 6 FC_SYNTAX_ERR_EXP_T + 7 FC_SYNTAX_ERR_INV_TARGET_NUM + 8 FC_SYNTAX_ERR_EXP_D + 9 FC_SYNTAX_ERR_INV_DEVICE_NUM + 10 FC_SYNTAX_ERR_INV_RRATIO_NUM + 11 FC_SYNTAX_ERR_EXP_NULL_TERM +severity: Error config +log: Always +module: fcLINUXfcp.c +action: Make neccessary changes to lpfc configuration file. +*/ +char fc_mes0431[] = "%sWWNN binding entry %d: Syntax error code %d"; +msgLogDef fc_msgBlk0431 = { + FC_LOG_MSG_IN_0431, + fc_mes0431, + fc_msgPreambleINc, + FC_MSG_OPUT_GLOB_CTRL, + FC_LOG_MSG_TYPE_ERR_CFG, + LOG_INIT, + ERRID_LOG_INIT }; + +/* +msgName: fc_mes0432 +message: WWPN binding entry: node table full +descript: More bindings entries were configured than the driver can handle. +data: None +severity: Error config +log: Always +module: fcLINUXfcp.c +action: Make neccessary changes to lpfc configuration file such that + fewer bindings are configured. +*/ +char fc_mes0432[] = "%sWWPN binding entry: node table full"; +msgLogDef fc_msgBlk0432 = { + FC_LOG_MSG_IN_0432, + fc_mes0432, + fc_msgPreambleINc, + FC_MSG_OPUT_GLOB_CTRL, + FC_LOG_MSG_TYPE_ERR_CFG, + LOG_INIT, + ERRID_LOG_INIT }; + +/* +msgName: fc_mes0433 +message: WWNN binding entry: node table full +descript: More bindings entries were configured than the driver can handle. +data: None +severity: Error config +log: Always +module: fcLINUXfcp.c +action: Make neccessary changes to lpfc configuration file such that + fewer bindings are configured. +*/ +char fc_mes0433[] = "%sWWNN binding entry: node table full"; +msgLogDef fc_msgBlk0433 = { + FC_LOG_MSG_IN_0433, + fc_mes0433, + fc_msgPreambleINc, + FC_MSG_OPUT_GLOB_CTRL, + FC_LOG_MSG_TYPE_ERR_CFG, + LOG_INIT, + ERRID_LOG_INIT }; + +/* +msgName: fc_mes0434 +message: DID binding entry : Syntax error code +descript: A syntax error occured while parsing DID binding + configuraion information. +data: None +detail: Binding syntax error codes + 0 FC_SYNTAX_OK + 1 FC_SYNTAX_OK_BUT_NOT_THIS_BRD + 2 FC_SYNTAX_ERR_ASC_CONVERT + 3 FC_SYNTAX_ERR_EXP_COLON + 4 FC_SYNTAX_ERR_EXP_LPFC + 5 FC_SYNTAX_ERR_INV_LPFC_NUM + 6 FC_SYNTAX_ERR_EXP_T + 7 FC_SYNTAX_ERR_INV_TARGET_NUM + 8 FC_SYNTAX_ERR_EXP_D + 9 FC_SYNTAX_ERR_INV_DEVICE_NUM + 10 FC_SYNTAX_ERR_INV_RRATIO_NUM + 11 FC_SYNTAX_ERR_EXP_NULL_TERM +severity: Error config +log: Always +module: fcLINUXfcp.c +action: Make neccessary changes to lpfc configuration file. +*/ +char fc_mes0434[] = "%sDID binding entry %d: Syntax error code %d"; +msgLogDef fc_msgBlk0434 = { + FC_LOG_MSG_IN_0434, + fc_mes0434, + fc_msgPreambleINc, + FC_MSG_OPUT_GLOB_CTRL, + FC_LOG_MSG_TYPE_ERR_CFG, + LOG_INIT, + ERRID_LOG_INIT }; + +/* +msgName: fc_mes0435 +message: DID binding entry: node table full +descript: More bindings entries were configured than the driver can handle. +data: None +severity: Error config +log: Always +module: fcLINUXfcp.c +action: Make neccessary changes to lpfc configuration file such that + fewer bindings are configured. +*/ +char fc_mes0435[] = "%sDID binding entry: node table full"; +msgLogDef fc_msgBlk0435 = { + FC_LOG_MSG_IN_0435, + fc_mes0435, + fc_msgPreambleINc, + FC_MSG_OPUT_GLOB_CTRL, + FC_LOG_MSG_TYPE_ERR_CFG, + LOG_INIT, + ERRID_LOG_INIT }; +/* +msgName: fc_mes0436 +message: Adapter failed to init, timeout, status reg +descript: The adapter failed during powerup diagnostics after it was reset. +data: None +severity: Error +log: Always +module: lp6000.c +action: This error could indicate a hardware or firmware problem. If + problems persist report these errors to Technical Support. +*/ +char fc_mes0436[] = "%sAdapter failed to init, timeout, status reg x%x"; +msgLogDef fc_msgBlk0436 = { + FC_LOG_MSG_IN_0436, + fc_mes0436, + fc_msgPreambleINe, + FC_MSG_OPUT_GLOB_CTRL, + FC_LOG_MSG_TYPE_ERR, + LOG_INIT, + ERRID_LOG_INIT }; + +/* +msgName: fc_mes0437 +message: Adapter failed to init, chipset, status reg +descript: The adapter failed during powerup diagnostics after it was reset. +data: None +severity: Error +log: Always +module: lp6000.c +action: This error could indicate a hardware or firmware problem. If + problems persist report these errors to Technical Support. +*/ +char fc_mes0437[] = "%sAdapter failed to init, chipset, status reg x%x"; +msgLogDef fc_msgBlk0437 = { + FC_LOG_MSG_IN_0437, + fc_mes0437, + fc_msgPreambleINe, + FC_MSG_OPUT_GLOB_CTRL, + FC_LOG_MSG_TYPE_ERR, + LOG_INIT, + ERRID_LOG_INIT }; + +/* +msgName: fc_mes0438 +message: Adapter failed to init, chipset, status reg +descript: The adapter failed during powerup diagnostics after it was reset. +data: None +severity: Error +log: Always +module: lp6000.c +action: This error could indicate a hardware or firmware problem. If + problems persist report these errors to Technical Support. +*/ +char fc_mes0438[] = "%sAdapter failed to init, chipset, status reg x%x"; +msgLogDef fc_msgBlk0438 = { + FC_LOG_MSG_IN_0438, + fc_mes0438, + fc_msgPreambleINe, + FC_MSG_OPUT_GLOB_CTRL, + FC_LOG_MSG_TYPE_ERR, + LOG_INIT, + ERRID_LOG_INIT }; + +/* +msgName: fc_mes0439 +message: Adapter failed to init, mbxCmd READ_REV, mbxStatus +descript: Adapter initialization failed when issuing READ_REV mailbox command. +data: None +severity: Error +log: Always +module: lp6000.c +action: This error could indicate a hardware or firmware problem. If + problems persist report these errors to Technical Support. +*/ +char fc_mes0439[] = "%sAdapter failed to init, mbxCmd x%x READ_REV, mbxStatus x%x"; +msgLogDef fc_msgBlk0439 = { + FC_LOG_MSG_IN_0439, + fc_mes0439, + fc_msgPreambleINe, + FC_MSG_OPUT_GLOB_CTRL, + FC_LOG_MSG_TYPE_ERR, + LOG_INIT, + ERRID_LOG_INIT }; + +/* +msgName: fc_mes0440 +message: Adapter failed to init, mbxCmd READ_REV detected outdated firmware +descript: Outdated firmware was detected during initialization. +data: (1) read_rev_reset +severity: Error +log: Always +module: lp6000.c +action: This error could indicate a hardware or firmware problem. Update + firmware. If problems persist report these errors to Technical + Support. +*/ +char fc_mes0440[] = "%sAdapter failed to init, mbxCmd x%x READ_REV detected outdated firmware Data: x%x"; +msgLogDef fc_msgBlk0440 = { + FC_LOG_MSG_IN_0440, + fc_mes0440, + fc_msgPreambleINe, + FC_MSG_OPUT_GLOB_CTRL, + FC_LOG_MSG_TYPE_ERR, + LOG_INIT, + ERRID_LOG_INIT }; + +/* +msgName: fc_mes0441 +message: Adapter failed to init, mbxCmd DUMP VPD, mbxStatus +descript: Adapter initialization failed when issuing DUMP_VPD mailbox command. +data: None +severity: Error +log: Always +module: lp6000.c +action: This error could indicate a hardware or firmware problem. If + problems persist report these errors to Technical Support. +*/ +char fc_mes0441[] = "%sAdapter failed to init, mbxCmd x%x DUMP VPD, mbxStatus x%x"; +msgLogDef fc_msgBlk0441 = { + FC_LOG_MSG_IN_0441, + fc_mes0441, + fc_msgPreambleINw, + FC_MSG_OPUT_GLOB_CTRL, + FC_LOG_MSG_TYPE_WARN, + LOG_INIT, + ERRID_LOG_INIT }; + +/* +msgName: fc_mes0442 +message: Adapter failed to init, mbxCmd CONFIG_PORT, mbxStatus +descript: Adapter initialization failed when issuing CONFIG_PORT mailbox + command. +data: 0 +severity: Error +log: Always +module: lp6000.c +action: This error could indicate a hardware or firmware problem. If + problems persist report these errors to Technical Support. +*/ +char fc_mes0442[] = "%sAdapter failed to init, mbxCmd x%x CONFIG_PORT, mbxStatus x%x Data: x%x"; +msgLogDef fc_msgBlk0442 = { + FC_LOG_MSG_IN_0442, + fc_mes0442, + fc_msgPreambleINe, + FC_MSG_OPUT_GLOB_CTRL, + FC_LOG_MSG_TYPE_ERR, + LOG_INIT, + ERRID_LOG_INIT }; + +/* +msgName: fc_mes0443 +message: SLI1 not supported, mbxCmd , mbxStatus +descript: The driver no longer support SLI-1 mode. +data: 0 +severity: Error +log: Always +module: lp6000.c +action: This error could indicate a driver problem. If problems persist + report these errors to Technical Support. +*/ +char fc_mes0443[] = "%sSLI1 not supported, mbxCmd x%x, mbxStatus x%x Data: x%x"; +msgLogDef fc_msgBlk0443 = { + FC_LOG_MSG_IN_0443, + fc_mes0443, + fc_msgPreambleINe, + FC_MSG_OPUT_GLOB_CTRL, + FC_LOG_MSG_TYPE_ERR, + LOG_INIT, + ERRID_LOG_INIT }; + +/* +msgName: fc_mes0444 +message: Adapter failed to init, no buffers for RUN_BIU_DIAG +descript: The driver attempted to issue RUN_BIU_DIAG mailbox command to + the HBA but there were no buffer available. +data: None +severity: Error +log: Always +module: lp6000.c +action: This message indicates (1) a possible lack of memory resources. + Try increasing the lpfc 'num_bufs' configuration parameter to + allocate more buffers. (2) A possble driver buffer management + problem. If this problem persists, report these errors to + Technical Support. +*/ +char fc_mes0444[] = "%sAdapter failed to init, no buffers for RUN_BIU_DIAG"; +msgLogDef fc_msgBlk0444 = { + FC_LOG_MSG_IN_0444, + fc_mes0444, + fc_msgPreambleINe, + FC_MSG_OPUT_GLOB_CTRL, + FC_LOG_MSG_TYPE_ERR, + LOG_INIT, + ERRID_LOG_INIT }; + +/* +msgName: fc_mes0445 +message: RUN_BIU_DIAG failed +descript: Adapter failed to init properly because a PCI bus DMA + test failed. +data: None +severity: Error +log: Always +module: lp6000.c +action: This error usually indicates a hardware problem with the + adapter. Run diagnostics. +*/ +char fc_mes0445[] = "%sRUN_BIU_DIAG failed"; +msgLogDef fc_msgBlk0445 = { + FC_LOG_MSG_IN_0445, + fc_mes0445, + fc_msgPreambleINe, + FC_MSG_OPUT_GLOB_CTRL, + FC_LOG_MSG_TYPE_ERR, + LOG_INIT, + ERRID_LOG_INIT }; + +/* +msgName: fc_mes0446 +message: Adapter failed to init, mbxCmd CFG_RING, mbxStatus , ring +descript: Adapter initialization failed when issuing CFG_RING mailbox command. +data: None +severity: Error +log: Always +module: lp6000.c +action: This error could indicate a hardware or firmware problem. If + problems persist report these errors to Technical Support. +*/ +char fc_mes0446[] = "%sAdapter failed to init, mbxCmd x%x CFG_RING, mbxStatus x%x, ring %d"; +msgLogDef fc_msgBlk0446 = { + FC_LOG_MSG_IN_0446, + fc_mes0446, + fc_msgPreambleINe, + FC_MSG_OPUT_GLOB_CTRL, + FC_LOG_MSG_TYPE_ERR, + LOG_INIT, + ERRID_LOG_INIT }; + +/* +msgName: fc_mes0447 +message: Adapter failed init, mbxCmd rubBIUdiag mbxStatus +descript: Adapter initialization failed when issuing runBIUdiag mailbox + command. +data: None +severity: Error +log: Always +module: lp6000.c +action: This error could indicate a hardware or firmware problem. If + problems persist report these errors to Technical Support. +*/ +char fc_mes0447[] = "%sAdapter failed init, mbxCmd x%x CONFIG_LINK mbxStatus x%x"; +msgLogDef fc_msgBlk0447 = { + FC_LOG_MSG_IN_0447, + fc_mes0447, + fc_msgPreambleINe, + FC_MSG_OPUT_GLOB_CTRL, + FC_LOG_MSG_TYPE_ERR, + LOG_INIT, + ERRID_LOG_INIT }; + +/* +msgName: fc_mes0448 +message: Adapter failed to init, mbxCmd READ_SPARM, mbxStatus +descript: Adapter initialization failed when issuing READ_SPARM mailbox + command. +data: None +severity: Error +log: Always +module: lp6000.c +action: This error could indicate a hardware or firmware problem. If + problems persist report these errors to Technical Support. +*/ +char fc_mes0448[] = "%sAdapter failed init, mbxCmd x%x READ_SPARM mbxStatus x%x"; +msgLogDef fc_msgBlk0448 = { + FC_LOG_MSG_IN_0448, + fc_mes0448, + fc_msgPreambleINe, + FC_MSG_OPUT_GLOB_CTRL, + FC_LOG_MSG_TYPE_ERR, + LOG_INIT, + ERRID_LOG_INIT }; + +/* +msgName: fc_mes0449 +message: WorldWide PortName Type doesn't conform to IP Profile +descript: In order to run IP, the WorldWide PortName must be of type + IEEE (NAA = 1). This message displays if the adapter WWPN + doesn't conform with the standard. +data: None +severity: Error +log: Always +module: lp6000.c +action: Turn off the network-on configuration parameter or configure + a different WWPN. +*/ +char fc_mes0449[] = "%sWorldWide PortName Type x%x doesn't conform to IP Profile"; +msgLogDef fc_msgBlk0449 = { + FC_LOG_MSG_IN_0449, + fc_mes0449, + fc_msgPreambleINe, + FC_MSG_OPUT_GLOB_CTRL, + FC_LOG_MSG_TYPE_ERR, + LOG_INIT, + ERRID_LOG_INIT }; + +/* +msgName: fc_mes0450 +message: Adapter failed to init, mbxCmd FARP, mbxStatus +descript: Adapter initialization failed when issuing FARP mailbox command. +data: None +severity: Warning +log: LOG_INIT verbose +module: lp6000.c +action: None required +*/ +char fc_mes0450[] = "%sAdapter failed to init, mbxCmd x%x FARP, mbxStatus x%x"; +msgLogDef fc_msgBlk0450 = { + FC_LOG_MSG_IN_0450, + fc_mes0450, + fc_msgPreambleINw, + FC_MSG_OPUT_GLOB_CTRL, + FC_LOG_MSG_TYPE_WARN, + LOG_INIT, + ERRID_LOG_INIT }; + +/* +msgName: fc_mes0451 +message: Enable interrupt handler failed +descript: The driver attempted to register the HBA interrupt service + routine with the host operating system but failed. +data: None +severity: Error +log: Always +module: lp6000.c +action: This error could indicate a hardware or driver problem. If + problems persist report these errors to Technical Support. +*/ +char fc_mes0451[] = "%sEnable interrupt handler failed"; +msgLogDef fc_msgBlk0451 = { + FC_LOG_MSG_IN_0451, + fc_mes0451, + fc_msgPreambleINe, + FC_MSG_OPUT_GLOB_CTRL, + FC_LOG_MSG_TYPE_ERR, + LOG_INIT, + ERRID_LOG_INIT }; + +/* +msgName: fc_mes0452 +message: Bring Adapter offline +descript: The FC driver has received a request to bring the adapter + offline. This may occur when running lputil. +data: None +severity: Warning +log: LOG_INIT verbose +module: fcscsib.c +action: None required +*/ +char fc_mes0452[] = "%sBring Adapter offline"; +msgLogDef fc_msgBlk0452 = { + FC_LOG_MSG_IN_0452, + fc_mes0452, + fc_msgPreambleINw, + FC_MSG_OPUT_GLOB_CTRL, + FC_LOG_MSG_TYPE_WARN, + LOG_INIT, + ERRID_LOG_UNEXPECT_EVENT }; + +/* +msgName: fc_mes0453 +message: Adapter failed to init, mbxCmd READ_CONFIG, mbxStatus +descript: Adapter initialization failed when issuing READ_CONFIG mailbox + command. +data: None +severity: Error +log: Always +module: lp6000.c +action: This error could indicate a hardware or firmware problem. If + problems persist report these errors to Technical Support. +*/ +char fc_mes0453[] = "%sAdapter failed to init, mbxCmd x%x READ_CONFIG, mbxStatus x%x"; +msgLogDef fc_msgBlk0453 = { + FC_LOG_MSG_IN_0453, + fc_mes0453, + fc_msgPreambleINe, + FC_MSG_OPUT_GLOB_CTRL, + FC_LOG_MSG_TYPE_ERR, + LOG_INIT, + ERRID_LOG_INIT }; + +/* +msgName: fc_mes0454 +message: Adapter failed to init, mbxCmd INIT_LINK, mbxStatus +descript: Adapter initialization failed when issuing INIT_LINK mailbox command. +data: None +severity: Error +log: Always +module: lp6000.c +action: This error could indicate a hardware or firmware problem. If + problems persist report these errors to Technical Support. +*/ +char fc_mes0454[] = "%sAdapter failed to init, mbxCmd x%x INIT_LINK, mbxStatus x%x"; +msgLogDef fc_msgBlk0454 = { + FC_LOG_MSG_IN_0454, + fc_mes0454, + fc_msgPreambleINe, + FC_MSG_OPUT_GLOB_CTRL, + FC_LOG_MSG_TYPE_ERR, + LOG_INIT, + ERRID_LOG_INIT }; + +/* +msgName: fc_mes0455 +message: Vital Product +descript: Vital Product Data (VPD) contained in HBA flash. +data: (1) vpd[0] (2) vpd[1] (3) vpd[2] (4) vpd[3] +severity: Information +log: LOG_INIT verbose +module: lp6000.c +action: None required +*/ +char fc_mes0455[] = "%sVital Product Data: x%x x%x x%x x%x"; +msgLogDef fc_msgBlk0455 = { + FC_LOG_MSG_IN_0455, + fc_mes0455, + fc_msgPreambleINi, + FC_MSG_OPUT_GLOB_CTRL, + FC_LOG_MSG_TYPE_INFO, + LOG_INIT, + ERRID_LOG_INIT }; + +/* +msgName: fc_mes0457 +message: Adapter Hardware Error +descript: The driver received an interrupt indicting a possible hardware + problem. +data: (1) status (2) status1 (3) status2 +severity: Error +log: Always +module: lp6000.c +action: This error could indicate a hardware or firmware problem. If + problems persist report these errors to Technical Support. +*/ +char fc_mes0457[] = "%sAdapter Hardware Error Data: x%x x%x x%x"; +msgLogDef fc_msgBlk0457 = { + FC_LOG_MSG_IN_0457, + fc_mes0457, + fc_msgPreambleINe, + FC_MSG_OPUT_GLOB_CTRL, + FC_LOG_MSG_TYPE_ERR, + LOG_INIT, + ERRID_LOG_INIT }; + +/* +msgName: fc_mes0458 +message: Bring Adapter online +descript: The FC driver has received a request to bring the adapter + online. This may occur when running lputil. +data: None +severity: Warning +log: LOG_INIT verbose +module: fcscsib.c +action: None required +*/ +char fc_mes0458[] = "%sBring Adapter online"; +msgLogDef fc_msgBlk0458 = { + FC_LOG_MSG_IN_0458, + fc_mes0458, + fc_msgPreambleINw, + FC_MSG_OPUT_GLOB_CTRL, + FC_LOG_MSG_TYPE_WARN, + LOG_INIT, + ERRID_LOG_UNEXPECT_EVENT }; + +/* +msgName: fc_mes0459 +message: Bring Adapter online +descript: The FC driver has received a request to bring the adapter + online. This may occur when running lputil. +data: None +severity: Warning +log: LOG_INIT verbose +module: fcscsib.c +action: None required +*/ +char fc_mes0459[] = "%sBring Adapter online"; +msgLogDef fc_msgBlk0459 = { + FC_LOG_MSG_IN_0459, + fc_mes0459, + fc_msgPreambleINw, + FC_MSG_OPUT_GLOB_CTRL, + FC_LOG_MSG_TYPE_WARN, + LOG_INIT, + ERRID_LOG_UNEXPECT_EVENT }; + +/* +msgName: fc_mes0460 +message: Bring Adapter offline +descript: The FC driver has received a request to bring the adapter + offline. This may occur when running lputil. +data: None +severity: Warning +log: LOG_INIT verbose +module: fcscsib.c +action: None required +*/ +char fc_mes0460[] = "%sBring Adapter offline"; +msgLogDef fc_msgBlk0460 = { + FC_LOG_MSG_IN_0460, + fc_mes0460, + fc_msgPreambleINw, + FC_MSG_OPUT_GLOB_CTRL, + FC_LOG_MSG_TYPE_WARN, + LOG_INIT, + ERRID_LOG_UNEXPECT_EVENT }; + +/* +msgName: fc_mes0461 +message: Adapter failed init, mbxCmd CONFIG_LINK mbxStatus +descript: Adapter initialization failed when issuing CONFIG_LINK mailbox + command. +data: None +severity: Error +log: Always +module: lp6000.c +action: This error could indicate a hardware or firmware problem. If + problems persist report these errors to Technical Support. +*/ +char fc_mes0461[] = "%sAdapter failed init, mbxCmd x%x CONFIG_LINK mbxStatus x%x"; +msgLogDef fc_msgBlk0461 = { + FC_LOG_MSG_IN_0461, + fc_mes0461, + fc_msgPreambleINe, + FC_MSG_OPUT_GLOB_CTRL, + FC_LOG_MSG_TYPE_ERR, + LOG_INIT, + ERRID_LOG_INIT }; + +/* + * UNUSED 0500 + */ + +/* + * Begin IP LOG Message Structures + */ + +/* +msgName: fc_mes0600 +message: FARP-RSP received from DID . +descript: A FARP ELS command response was received. +data: None +severity: Information +log: LOG_IP verbose +module: fcelsb.c +action: None required +*/ +char fc_mes0600[] = "%sFARP-RSP received from DID x%x"; +msgLogDef fc_msgBlk0600 = { + FC_LOG_MSG_IP_0600, + fc_mes0600, + fc_msgPreambleIPi, + FC_MSG_OPUT_GLOB_CTRL, + FC_LOG_MSG_TYPE_INFO, + LOG_IP, + ERRID_LOG_UNEXPECT_EVENT }; + +/* +msgName: fc_mes0601 +message: FARP-REQ received fron DID +descript: A FARP ELS command request was received. . +data: None +severity: Information +log: LOG_IP verbose +module: fcelsb.c +action: None required +*/ +char fc_mes0601[] = "%sFARP-REQ received from DID x%x"; +msgLogDef fc_msgBlk0601 = { + FC_LOG_MSG_IP_0601, + fc_mes0601, + fc_msgPreambleIPi, + FC_MSG_OPUT_GLOB_CTRL, + FC_LOG_MSG_TYPE_INFO, + LOG_IP, + ERRID_LOG_UNEXPECT_EVENT }; + +/* +msgName: fc_mes0602 +message: IP Response Ring out of posted buffers +descript: The IP ring returned all posted buffers to the driver + and is waiting for the driver to post new buffers. This + could mean the host system is out of TCP/IP buffers. +data: (1) fc_missbufcnt (2) NoRcvBuf +severity: Warning +log: LOG_IP verbose +module: fcscsib.c +action: Try allocating more IP buffers (STREAMS buffers or mbufs) + of size 4096 and/or increasing the post-ip-buf lpfc + configuration parameter. Reboot the system. +*/ +char fc_mes0602[] = "%sIP Response Ring %d out of posted buffers Data: x%x x%x"; +msgLogDef fc_msgBlk0602 = { + FC_LOG_MSG_IP_0602, + fc_mes0602, + fc_msgPreambleIPw, + FC_MSG_OPUT_GLOB_CTRL, + FC_LOG_MSG_TYPE_WARN, + LOG_IP, + ERRID_LOG_NO_RESOURCE }; + +/* +msgName: fc_mes0603 +message: Rcv Ring out of posted buffers +descript: The ring returned all posted buffers to the driver + and is waiting for the driver to post new buffers. This + could mean the host system is out of ELS or CT buffers. +data: (1) fc_missbufcnt (2) NoRcvBuf +severity: Error +log: Always +module: fcscsib.c +action: Try allocating more buffers by increasing the num-buf lpfc + configuration parameter. Reboot the system. +*/ +char fc_mes0603[] = "%sRcv Ring %d out of posted buffers Data: x%x x%x"; +msgLogDef fc_msgBlk0603 = { + FC_LOG_MSG_IP_0603, + fc_mes0603, + fc_msgPreambleIPe, + FC_MSG_OPUT_GLOB_CTRL, + FC_LOG_MSG_TYPE_ERR, + LOG_IP, + ERRID_LOG_NO_RESOURCE }; + +/* +msgName: fc_mes0604 +message: Post buffer for IP ring failed +descript: The driver cannot allocate a buffer to post to the IP ring. + This usually means the host system is out of TCP/IP buffers. +data: (1) missbufcnt +severity: Error +log: Always +module: fcscsib.c +action: Try allocating more IP buffers (STREAMS buffers or mbufs) + of size 4096. Reboot the system. +*/ +char fc_mes0604[] = "%sPost buffer for IP ring %d failed Data: x%x"; +msgLogDef fc_msgBlk0604 = { + FC_LOG_MSG_IP_0604, + fc_mes0604, + fc_msgPreambleIPe, + FC_MSG_OPUT_GLOB_CTRL, + FC_LOG_MSG_TYPE_ERR, + LOG_IP, + ERRID_LOG_NO_RESOURCE }; + +/* +msgName: fc_mes0605 +message: No room on IP xmit queue +descript: The system is generating IOCB commands to be processed + faster than the adapter can process them. +data: (1) xmitnoroom +severity: Warning +log: LOG_IP verbose +module: fcxmitb.c +action: Check the state of the link. If the link is up and running, + reconfigure the xmit queue size to be larger. Note, a larger + queue size may require more system IP buffers. If the link + is down, check physical connections to Fibre Channel network. +*/ +char fc_mes0605[] = "%sNo room on IP xmit queue Data: x%x"; +msgLogDef fc_msgBlk0605 = { + FC_LOG_MSG_IP_0605, + fc_mes0605, + fc_msgPreambleIPw, + FC_MSG_OPUT_GLOB_CTRL, + FC_LOG_MSG_TYPE_WARN, + LOG_IP, + ERRID_LOG_UNEXPECT_EVENT }; + +/* +msgName: fc_mes0606 +message: Stray XmitSequence completion +descript: Received an XMIT_SEQUENCE IOCB completion without issuing + a corresponding XMIT_SEQUENCE Command (based on the IOTAG + field in the XMIT_SEQUENCE_CR iocb). +data: (1) ulpCommand (2) ulpIoTag +severity: Error +log: Always +module: fcxmitb.c +action: This error could indicate a software driver or firmware + problem. If problems persist report these errors to + Technical Support. +*/ +char fc_mes0606[] = "%sStray XmitSequence completion Data: x%x x%x"; +msgLogDef fc_msgBlk0606 = { + FC_LOG_MSG_IP_0606, + fc_mes0606, + fc_msgPreambleIPe, + FC_MSG_OPUT_GLOB_CTRL, + FC_LOG_MSG_TYPE_ERR, + LOG_IP, + ERRID_LOG_UNEXPECT_EVENT }; + +/* +msgName: fc_mes0607 +message: Xmit Sequence completion error +descript: A XMIT_SEQUENCE command completed with a status error + in the IOCB. +data: (1) ulpStatus (2) ulpToTag (3) ulpWord[4] (4) did +severity: Warning +log: LOG_IP verbose +module: fcxmitb.c +action: If there are many errors to one device, check physical + connections to Fibre Channel network and the state of + the remote PortID. The driver attempts to recover by + creating a new exchange to the remote device. +*/ +char fc_mes0607[] = "%sXmit Sequence completion error Data: x%x x%x x%x x%x"; +msgLogDef fc_msgBlk0607 = { + FC_LOG_MSG_IP_0607, + fc_mes0607, + fc_msgPreambleIPw, + FC_MSG_OPUT_GLOB_CTRL, + FC_LOG_MSG_TYPE_WARN, + LOG_IP, + ERRID_LOG_UNEXPECT_EVENT }; + +/* +msgName: fc_mes0608 +message: Stray CreateXRI completion +descript: Received a CREATE_XRI command completion without + issuing a corresponding CREATE_XRI Command (based + on the IOTAG field in the CREATE_XRI_CR iocb). +data: (1) ulpCommad (2) ulpToTag +severity: Error +log: Always +module: fcxmitb.c +action: This error could indicate a software driver or + firmware problem. If problems persist report these + errors to Technical Support. +*/ +char fc_mes0608[] = "%sStray CreateXRI completion Data: x%x x%x"; +msgLogDef fc_msgBlk0608 = { + FC_LOG_MSG_IP_0608, + fc_mes0608, + fc_msgPreambleIPe, + FC_MSG_OPUT_GLOB_CTRL, + FC_LOG_MSG_TYPE_ERR, + LOG_IP, + ERRID_LOG_UNEXPECT_EVENT }; + +/* + * Begin FCP LOG Message Structures + */ + +/* +msgName: fc_mes0700 +message: Start nodev timer +descript: A target disappeared from the Fibre Channel network. If the + target does not return within nodev-tmo timeout all I/O to + the target will fail. +data: (1) nlp (2) nlp_flag (3) nlp_state (4) nlp_DID +severity: Information +log: LOG_FCP verbose +module: fcrpib.c +action: None required +*/ +char fc_mes0700[] = "%sSTART nodev timer Data: x%x x%x x%x x%x"; +msgLogDef fc_msgBlk0700 = { + FC_LOG_MSG_FP_0700, + fc_mes0700, + fc_msgPreambleFPi, + FC_MSG_OPUT_GLOB_CTRL, + FC_LOG_MSG_TYPE_INFO, + LOG_FCP, + ERRID_LOG_UNEXPECT_EVENT }; + +/* +msgName: fc_mes0701 +message: Issue Abort Task Set I/O for LUN +descript: The SCSI layer detected that it needs to abort all I/O + to a specific device. This results in an FCP Task + Management command to abort the I/O in progress. +data: (1) did (2) sid (3) flags +severity: Information +log: LOG_FCP verbose +module: fcstratb.c +action: Check state of device in question. +*/ +char fc_mes0701[] = "%sIssue Abort Task Set I/O for LUN %d Data: x%x x%x x%x"; +msgLogDef fc_msgBlk0701 = { + FC_LOG_MSG_FP_0701, + fc_mes0701, + fc_msgPreambleFPi, + FC_MSG_OPUT_GLOB_CTRL, + FC_LOG_MSG_TYPE_INFO, + LOG_FCP, + ERRID_LOG_UNEXPECT_EVENT }; + +/* +msgName: fc_mes0702 +message: Issue Target Reset I/O +descript: The SCSI layer detected that it needs to abort all I/O + to a specific target. This results in an FCP Task + Management command to abort the I/O in progress. +data: (1) lun (2) did (3) sid (4) flags +severity: Information +log: LOG_FCP verbose +module: fcstratb.c +action: Check state of target in question. +*/ +char fc_mes0702[] = "%sIssue Target Reset I/O Data: x%x x%x x%x x%x"; +msgLogDef fc_msgBlk0702 = { + FC_LOG_MSG_FP_0702, + fc_mes0702, + fc_msgPreambleFPi, + FC_MSG_OPUT_GLOB_CTRL, + FC_LOG_MSG_TYPE_INFO, + LOG_FCP, + ERRID_LOG_UNEXPECT_EVENT }; + +/* +msgName: fc_mes0703 +message: Issue LUN Reset I/O for LUN +descript: The SCSI layer detected that it needs to abort all I/O + to a specific device. This results in an FCP Task + Management command to abort the I/O in progress. +data: (1) did (2) sid (3) flags +severity: Information +log: LOG_FCP verbose +module: fcstratb.c +action: Check state of device in question. +*/ +char fc_mes0703[] = "%sIssue LUN Reset I/O for LUN %d Data: x%x x%x x%x"; +msgLogDef fc_msgBlk0703 = { + FC_LOG_MSG_FP_0703, + fc_mes0703, + fc_msgPreambleFPi, + FC_MSG_OPUT_GLOB_CTRL, + FC_LOG_MSG_TYPE_INFO, + LOG_FCP, + ERRID_LOG_UNEXPECT_EVENT }; + +/* +msgName: fc_mes0704 +message: STOP nodev timer +descript: The FCP target was rediscovered and I/O can be resumed. +data: (1) ndlp (2) nlp_flag (3) nlp_state (4) nlp_DID +severity: Information +log: LOG_FCP verbose +module: fcstratb.c +action: None required +*/ +char fc_mes0704[] = "%sSTOP nodev timer Data: x%x x%x x%x x%x"; +msgLogDef fc_msgBlk0704 = { + FC_LOG_MSG_FP_0704, + fc_mes0704, + fc_msgPreambleFPi, + FC_MSG_OPUT_GLOB_CTRL, + FC_LOG_MSG_TYPE_INFO, + LOG_FCP, + ERRID_LOG_UNEXPECT_EVENT }; + +/* +msgName: fc_mes0705 +message: STOP nodev timer +descript: The FCP target was rediscovered and I/O can be resumed. +data: (1) ndlp (2) nlp_flag (3) nlp_state (4) nlp_DID +severity: Information +log: LOG_FCP verbose +module: fcstratb.c +action: None required +*/ +char fc_mes0705[] = "%sSTOP nodev timer Data: x%x x%x x%x x%x"; +msgLogDef fc_msgBlk0705 = { + FC_LOG_MSG_FP_0705, + fc_mes0705, + fc_msgPreambleFPi, + FC_MSG_OPUT_GLOB_CTRL, + FC_LOG_MSG_TYPE_INFO, + LOG_FCP, + ERRID_LOG_UNEXPECT_EVENT }; + +/* +msgName: fc_mes0706 +message: Cannot issue FCP command +descript: A valid ELS login with the FCP target no longer exists. +data: (1) did (2) sid +severity: Warning +log: LOG_FCP verbose +module: fcstratb.c +action: Check the state of the target in question. +*/ +char fc_mes0706[] = "%sCannot issue FCP command Data: x%x x%x"; +msgLogDef fc_msgBlk0706 = { + FC_LOG_MSG_FP_0706, + fc_mes0706, + fc_msgPreambleFPw, + FC_MSG_OPUT_GLOB_CTRL, + FC_LOG_MSG_TYPE_WARN, + LOG_FCP, + ERRID_LOG_UNEXPECT_EVENT }; + +/* +msgName: fc_mes0707 +message: Bad SCSI CDB length for LUN DID +descript: This error indicates a SCSI command sent to the + FC driver from the SCSI layer has an invalid length. +data: (1) cmd_cdblen (2) fcpCdb +severity: Error +log: Always +module: fcstratb.c +action: This error could indicate a host operating system SCSI + layer problem. If problems persist report these errors + to Technical Support. +*/ +char fc_mes0707[] = "%sBad SCSI CDB length for LUN %d DID x%x Data: x%x x%x"; +msgLogDef fc_msgBlk0707 = { + FC_LOG_MSG_FP_0707, + fc_mes0707, + fc_msgPreambleFPe, + FC_MSG_OPUT_GLOB_CTRL, + FC_LOG_MSG_TYPE_ERR, + LOG_FCP, + ERRID_LOG_UNEXPECT_EVENT }; + +/* +msgName: fc_mes0708 +message: NULL sp in flush_done +descript: This error indicates a potential FC driver problem + related to a FCP command iodone +data: (1) cmnd[0] (2) serial_number (3) retries (4) result +severity: Error +log: Always +module: fcLINUXfcp.c +action: This error could indicate a driver problem. If problems + persist report these errors to Technical Support. +*/ +char fc_mes0708[] = "%sNULL sp in flush_done Data: x%x x%x x%x x%x"; +msgLogDef fc_msgBlk0708 = { + FC_LOG_MSG_FP_0708, + fc_mes0708, + fc_msgPreambleFPe, + FC_MSG_OPUT_GLOB_CTRL, + FC_LOG_MSG_TYPE_ERR, + LOG_FCP, + ERRID_LOG_UNEXPECT_EVENT }; + +/* +msgName: fc_mes0709 +message: NULL sp in DPC flush_done +descript: This error indicates a potential FC driver problem + related to a FCP command iodone +data: (1) cmnd[0] (2) serial_number (3) retries (4) result +severity: Error +log: Always +module: fcLINUXfcp.c +action: This error could indicate a driver problem. If problems + persist report these errors to Technical Support. +*/ +char fc_mes0709[] = "%sNULL sp in DPC flush_done Data: x%x x%x x%x x%x"; +msgLogDef fc_msgBlk0709 = { + FC_LOG_MSG_FP_0709, + fc_mes0709, + fc_msgPreambleFPe, + FC_MSG_OPUT_GLOB_CTRL, + FC_LOG_MSG_TYPE_ERR, + LOG_FCP, + ERRID_LOG_UNEXPECT_EVENT }; + +/* +msgName: fc_mes0710 +message: iodone error return +descript: This error indicates the FC driver is returning SCSI + command to the SCSI layer in error or with sense data. +data: (1) target (2) retries (3) result (4) *iptr +severity: Information +log: LOG_FCP verbose +module: fcLINUXfcp.c +action: None required +*/ +char fc_mes0710[] = "%siodone error return Data: x%x x%x x%x x%x"; +msgLogDef fc_msgBlk0710 = { + FC_LOG_MSG_FP_0710, + fc_mes0710, + fc_msgPreambleFPi, + FC_MSG_OPUT_GLOB_CTRL, + FC_LOG_MSG_TYPE_INFO, + LOG_FCP, + ERRID_LOG_UNEXPECT_EVENT }; + +/* +msgName: fc_mes0711 +message: iodone error return +descript: This error indicates the FC driver is returning SCSI + command to the SCSI layer in error or with sense data. +data: (1) target (2) retries (3) result (4) *iptr +severity: Information +log: LOG_FCP verbose +module: fcLINUXfcp.c +action: None required +*/ +char fc_mes0711[] = "%siodone error return Data: x%x x%x x%x x%x"; +msgLogDef fc_msgBlk0711 = { + FC_LOG_MSG_FP_0711, + fc_mes0711, + fc_msgPreambleFPi, + FC_MSG_OPUT_GLOB_CTRL, + FC_LOG_MSG_TYPE_INFO, + LOG_FCP, + ERRID_LOG_UNEXPECT_EVENT }; + +/* +msgName: fc_mes0712 +message: SCSI layer issued abort device +descript: The SCSI layer is requesting the driver to abort + I/O to a specific device. +data: (1) target (2) lun (3) cmnd[0] (4) serial_number +severity: Error +log: Always +module: fcLINUXfcp.c +action: Check state of device in question. +*/ +char fc_mes0712[] = "%sSCSI layer issued abort device Data: x%x x%x x%x x%x"; +msgLogDef fc_msgBlk0712 = { + FC_LOG_MSG_FP_0712, + fc_mes0712, + fc_msgPreambleFPe, + FC_MSG_OPUT_GLOB_CTRL, + FC_LOG_MSG_TYPE_ERR, + LOG_FCP, + ERRID_LOG_UNEXPECT_EVENT }; + +/* +msgName: fc_mes0713 +message: SCSI layer issued target reset +descript: The SCSI layer is requesting the driver to abort + I/O to a specific target. +data: (1) target (2) lun (3) dev_index +severity: Error +log: Always +module: fcLINUXfcp.c +action: Check state of target in question. +*/ +char fc_mes0713[] = "%sSCSI layer issued target reset Data: x%x x%x x%x"; +msgLogDef fc_msgBlk0713 = { + FC_LOG_MSG_FP_0713, + fc_mes0713, + fc_msgPreambleFPe, + FC_MSG_OPUT_GLOB_CTRL, + FC_LOG_MSG_TYPE_ERR, + LOG_FCP, + ERRID_LOG_UNEXPECT_EVENT }; + +/* +msgName: fc_mes0714 +message: SCSI layer issued Bus Reset +descript: The SCSI layer is requesting the driver to abort + all I/Os to all targets on this HBA. +data: (1) target (2) lun +severity: Error +log: Always +module: fcLINUXfcp.c +action: Check state of targets in question. +*/ +char fc_mes0714[] = "%sSCSI layer issued Bus Reset Data: x%x x%x"; +msgLogDef fc_msgBlk0714 = { + FC_LOG_MSG_FP_0714, + fc_mes0714, + fc_msgPreambleFPe, + FC_MSG_OPUT_GLOB_CTRL, + FC_LOG_MSG_TYPE_ERR, + LOG_FCP, + ERRID_LOG_UNEXPECT_EVENT }; + +/* +msgName: fc_mes0715 +message: SCSI layer issued Host Reset +descript: The SCSI layer is requesting the driver to reset the link + on this HBA. +data: (1) target (2) lun +severity: Error +log: Always +module: fcLINUXfcp.c +action: Check state of HBA link. +*/ +char fc_mes0715[] = "%sSCSI layer issued Host Reset Data: x%x x%x"; +msgLogDef fc_msgBlk0715 = { + FC_LOG_MSG_FP_0715, + fc_mes0715, + fc_msgPreambleFPe, + FC_MSG_OPUT_GLOB_CTRL, + FC_LOG_MSG_TYPE_ERR, + LOG_FCP, + ERRID_LOG_UNEXPECT_EVENT }; + +/* +msgName: fc_mes0716 +message: FCP residual underrun, expected , residual +descript: FCP device provided less data than was requested. +data: (1) cmnd[0] (2) underflow +severity: Information +log: LOG_FCP verbose +module: fcLINUXfcp.c +action: None required +*/ +char fc_mes0716[] = "%sFCP residual underrun, expected %d, residual %d Data: x%x x%x"; +msgLogDef fc_msgBlk0716 = { + FC_LOG_MSG_FP_0716, + fc_mes0716, + fc_msgPreambleFPi, + FC_MSG_OPUT_GLOB_CTRL, + FC_LOG_MSG_TYPE_INFO, + LOG_FCP, + ERRID_LOG_UNEXPECT_EVENT }; + +/* +msgName: fc_mes0717 +message: FCP command residual underrun converted to error +descript: The driver converts this underrun condition to an error based + on the underflow field in the SCSI cmnd. +data: (1) underflow (2) len (3) resid +severity: Information +log: LOG_FCP verbose +module: fcLINUXfcp.c +action: None required +*/ +char fc_mes0717[] = "%sFCP cmd x%x resid urun convrt'd to err Data: x%x x%x x%x"; +msgLogDef fc_msgBlk0717 = { + FC_LOG_MSG_FP_0717, + fc_mes0717, + fc_msgPreambleFPi, + FC_MSG_OPUT_GLOB_CTRL, + FC_LOG_MSG_TYPE_INFO, + LOG_FCP, + ERRID_LOG_UNEXPECT_EVENT }; + +/* +msgName: fc_mes0718 +message: LUN address out of range +descript: Invalid LUN number in the SCSI command passed to the driver. +data: (1) target (2) lun +severity: Error +log: Always +module: fcLINUXfcp.c +action: This error could indicate a host operating system SCSI + layer problem. If problems persist report these errors + to Technical Support. +*/ +char fc_mes0718[] = "%sLUN address out of range Data: x%x x%x"; +msgLogDef fc_msgBlk0718 = { + FC_LOG_MSG_FP_0718, + fc_mes0718, + fc_msgPreambleFPe, + FC_MSG_OPUT_GLOB_CTRL, + FC_LOG_MSG_TYPE_ERR, + LOG_FCP, + ERRID_LOG_UNEXPECT_EVENT }; + +/* +msgName: fc_mes0719 +message: Waiting for REPORT LUN cmpl before issuing INQUIRY SN +descript: Waiting for REPORT LUN completion before issuing INQUIRY SN +data: (1) scsi_id (2) lun_id (3) flags +severity: Information +log: LOG_FCP verbose +module: fcscsib.c +action: None required +*/ +char fc_mes0719[] = "%sWaiting for REPORT LUN cmpl before issuing INQUIRY SN Data: x%x x%x x%x"; +msgLogDef fc_msgBlk0719 = { + FC_LOG_MSG_FP_0719, + fc_mes0719, + fc_msgPreambleFPi, + FC_MSG_OPUT_GLOB_CTRL, + FC_LOG_MSG_TYPE_INFO, + LOG_FCP, + ERRID_LOG_UNEXPECT_EVENT }; + +/* +msgName: fc_mes0720 +message: Stray FCP completion +descript: Received an FCP command completion without issuing a + corresponding FCP Command (based on the IOTAG field + in the FCP IOCB). +data: (1) ulpCommand (2) ulpIoTag (3) ulpStatus (4) ulpWord[4] +severity: Error +log: Always +module: fcscsib.c +action: This error could indicate a software driver or firmware + problem. If problems persist report these errors to + Technical Support. +*/ +char fc_mes0720[] = "%sStray FCP completion Data: x%x x%x x%x x%x"; +msgLogDef fc_msgBlk0720 = { + FC_LOG_MSG_FP_0720, + fc_mes0720, + fc_msgPreambleFPe, + FC_MSG_OPUT_GLOB_CTRL, + FC_LOG_MSG_TYPE_ERR, + LOG_FCP, + ERRID_LOG_UNEXPECT_EVENT }; + +/* +msgName: fc_mes0721 +message: INQUIRY SN cmpl +descript: An INQUIRY Serial Number (page x83) completed. This information + is saved by the driver. +data: (1) scsi_id (2) lun_id (3) statLocalError (4) cmd + WD7 +severity: Information +log: LOG_FCP verbose +module: fcscsib.c +action: None required +*/ +char fc_mes0721[] = "%sINQUIRY SN cmpl Data: x%x x%x x%x x%x"; +msgLogDef fc_msgBlk0721 = { + FC_LOG_MSG_FP_0721, + fc_mes0721, + fc_msgPreambleFPi, + FC_MSG_OPUT_GLOB_CTRL, + FC_LOG_MSG_TYPE_INFO, + LOG_FCP, + ERRID_LOG_UNEXPECT_EVENT }; + +/* +msgName: fc_mes0722 +message: INQUIRY SN info +descript: This is the serial number of the device that will be saved. +data: (1) *datap (2) *datap + 3 (3) datap + 7 (4) rspResId +severity: Information +log: LOG_FCP verbose +module: fcscsib.c +action: None required +*/ +char fc_mes0722[] = "%sINQUIRY SN info Data: x%x x%x x%x x%x"; +msgLogDef fc_msgBlk0722 = { + FC_LOG_MSG_FP_0722, + fc_mes0722, + fc_msgPreambleFPi, + FC_MSG_OPUT_GLOB_CTRL, + FC_LOG_MSG_TYPE_INFO, + LOG_FCP, + ERRID_LOG_UNEXPECT_EVENT }; + +/* +msgName: fc_mes0723 +message: Issue INQUIRY SN +descript: Issuing an INQUIRY Serial Number (page x83) FCP command. +data: (1) scsi_id (2) lun_id +severity: Information +log: LOG_FCP verbose +module: fcscsib.c +action: None required +*/ +char fc_mes0723[] = "%sIssue INQUIRY SN Data: x%x x%x"; +msgLogDef fc_msgBlk0723 = { + FC_LOG_MSG_FP_0723, + fc_mes0723, + fc_msgPreambleFPi, + FC_MSG_OPUT_GLOB_CTRL, + FC_LOG_MSG_TYPE_INFO, + LOG_FCP, + ERRID_LOG_UNEXPECT_EVENT }; + +/* +msgName: fc_mes0724 +message: Issue INQUIRY Page 0 +descript: Issuing an INQUIRY (page x0) FCP command. +data: (1) scsi_id (2) lun_id +severity: Information +log: LOG_FCP verbose +module: fcscsib.c +action: None required +*/ +char fc_mes0724[] = "%sIssue INQUIRY Page 0 Data: x%x x%x"; +msgLogDef fc_msgBlk0724 = { + FC_LOG_MSG_FP_0724, + fc_mes0724, + fc_msgPreambleFPi, + FC_MSG_OPUT_GLOB_CTRL, + FC_LOG_MSG_TYPE_INFO, + LOG_FCP, + ERRID_LOG_UNEXPECT_EVENT }; + +/* +msgName: fc_mes0725 +message: Inquiry Serial Number: invalid length +descript: An INQUIRY SN command completed with an invalid serial number length. +data: (1) sizeSN (2) j (3) scsi_id (4) lun_id +severity: Error +log: Always +module: fcscsib.c +action: Check remote NPORT for potential problem. +*/ +char fc_mes0725[] = "%sINQ Serial Number: invalid length Data: x%x x%x x%x x%x"; +msgLogDef fc_msgBlk0725= { + FC_LOG_MSG_FP_0725, + fc_mes0725, + fc_msgPreambleFPe, + FC_MSG_OPUT_GLOB_CTRL, + FC_LOG_MSG_TYPE_ERR, + LOG_FCP, + ERRID_LOG_HDW_ERR }; + +/* +msgName: fc_mes0726 +message: INQUIRY SN cmd failed +descript: The INQUIRY Serial Number (page x83) failed. +data: (1) ulpStatus (2) fcpi_parm (3) m_target (4) m_lun +severity: Error +log: Always +module: fcscsib.c +action: Check if target device supports this command +*/ +char fc_mes0726[] = "%sINQUIRY SN cmd failed Data: x%x x%x x%x x%x"; +msgLogDef fc_msgBlk0726= { + FC_LOG_MSG_FP_0726, + fc_mes0726, + fc_msgPreambleFPe, + FC_MSG_OPUT_GLOB_CTRL, + FC_LOG_MSG_TYPE_ERR, + LOG_FCP, + ERRID_LOG_HDW_ERR }; + +/* +msgName: fc_mes0727 +message: INQUIRY Page 0 cmpl +descript: An INQUIRY (page 0) completed. This information is saved by + the driver. +data: (1) scsi_id (2) lun_id (3) statLocalError (4) cmd + WD7 +severity: Information +log: LOG_FCP verbose +module: fcscsib.c +action: None required +*/ +char fc_mes0727[] = "%sINQUIRY Page 0 cmpl Data: x%x x%x x%x x%x"; +msgLogDef fc_msgBlk0727 = { + FC_LOG_MSG_FP_0727, + fc_mes0727, + fc_msgPreambleFPi, + FC_MSG_OPUT_GLOB_CTRL, + FC_LOG_MSG_TYPE_INFO, + LOG_FCP, + ERRID_LOG_UNEXPECT_EVENT }; + +/* +msgName: fc_mes0728 +message: INQUIRY Page 0 cmd failed +descript: The INQUIRY (page 0) failed. +data: (1) ulpStatus (2) fcpi_parm (3) scsi_id (4) lun_id +severity: Error +log: Always +module: fcscsib.c +action: Check if target device supports this command +*/ +char fc_mes0728[] = "%sINQUIRY Page 0 cmd failed Data: x%x x%x x%x x%x"; +msgLogDef fc_msgBlk0728= { + FC_LOG_MSG_FP_0728, + fc_mes0728, + fc_msgPreambleFPe, + FC_MSG_OPUT_GLOB_CTRL, + FC_LOG_MSG_TYPE_ERR, + LOG_FCP, + ERRID_LOG_HDW_ERR }; + +/* +msgName: fc_mes0729 +message: FCP cmd failed on device (, ) DID +descript: The specifed device failed an FCP command. +data: (1) rspInfo3 (2) statLocalError (3) *cmd + WD6 (4) *cmd + WD7 +severity: Warning +log: LOG_FCP verbose +module: fcscsib.c +action: Check the state of the target in question. +*/ +char fc_mes0729[] = "%sFCP cmd x%x failed on device (%d, %d), DID x%x Data: x%x x%x x%x x%x"; +msgLogDef fc_msgBlk0729= { + FC_LOG_MSG_FP_0729, + fc_mes0729, + fc_msgPreambleFPw, + FC_MSG_OPUT_GLOB_CTRL, + FC_LOG_MSG_TYPE_WARN, + LOG_FCP, + ERRID_LOG_UNEXPECT_EVENT }; + +/* +msgName: fc_mes0730 +message: FCP command failed: RSP +descript: The FCP command failed with a response error. +data: (1) lp[2] (2) lp[3] (3) lp[4] (4) lp[5] +severity: Warning +log: LOG_FCP verbose +module: fcscsib.c +action: Check the state of the target in question. +*/ +char fc_mes0730[] = "%sFCP command failed: RSP Data: x%x x%x x%x x%x"; +msgLogDef fc_msgBlk0730= { + FC_LOG_MSG_FP_0730, + fc_mes0730, + fc_msgPreambleFPw, + FC_MSG_OPUT_GLOB_CTRL, + FC_LOG_MSG_TYPE_WARN, + LOG_FCP, + ERRID_LOG_UNEXPECT_EVENT }; + +/* +msgName: fc_mes0731 +message: FCP command failed: SNS +descript: The FCP command failed with sense information. +data: (1) lp[0] (2) lp[1] (3) lp[2] (4) lp[3] + (5) lp[4] (6) lp[5] (7) lp6[6] (8) lp[7] +severity: Warning +log: LOG_FCP verbose +module: fcscsib.c +action: Check the state of the target in question. +*/ +char fc_mes0731[] = "%sFCP command failed: SNS Data: x%x x%x x%x x%x x%x x%x x%x x%x"; +msgLogDef fc_msgBlk0731= { + FC_LOG_MSG_FP_0731, + fc_mes0731, + fc_msgPreambleFPw, + FC_MSG_OPUT_GLOB_CTRL, + FC_LOG_MSG_TYPE_WARN, + LOG_FCP, + ERRID_LOG_UNEXPECT_EVENT }; + +/* +msgName: fc_mes0732 +message: Retry FCP command due to 29,00 check condition +descript: The issued FCP command got a 29,00 check condition and will + be retried by the driver. +data: (1) *lp (2) *lp+1 (3) *lp+2 (4) *lp+3 +severity: Information +log: LOG_FCP verbose +module: fcscsib.c +action: None required +*/ +char fc_mes0732[] = "%sRetry FCP command due to 29,00 check condition Data: x%x x%x x%x x%x"; +msgLogDef fc_msgBlk0732 = { + FC_LOG_MSG_FP_0732, + fc_mes0732, + fc_msgPreambleFPi, + FC_MSG_OPUT_GLOB_CTRL, + FC_LOG_MSG_TYPE_INFO, + LOG_FCP, + ERRID_LOG_UNEXPECT_EVENT }; + +/* +msgName: fc_mes0733 +message: FCP Read Underrun +descript: The issued FCP command returned a Read Underrun +data: (1) *cmd + WD7 (2) ulpContext (3) rspResId (4) fcpi_parm +severity: Information +log: LOG_FCP verbose +module: fcscsib.c +action: None required +*/ +char fc_mes0733[] = "%sFCP Read Underrun Data: x%x x%x x%x x%x"; +msgLogDef fc_msgBlk0733 = { + FC_LOG_MSG_FP_0733, + fc_mes0733, + fc_msgPreambleFPi, + FC_MSG_OPUT_GLOB_CTRL, + FC_LOG_MSG_TYPE_INFO, + LOG_FCP, + ERRID_LOG_UNEXPECT_EVENT }; + +/* +msgName: fc_mes0734 +message: FCP Read Check Error +descript: The issued FCP command returned a Read Check Error +data: (1) *cmd + WD7 (2) ulpContext (3) rspResId (4) fcpi_parm +severity: Error +log: Always +module: fcscsib.c +action: Check the state of the target in question. +*/ +char fc_mes0734[] = "%sFCP Read Check Error Data: x%x x%x x%x x%x"; +msgLogDef fc_msgBlk0734= { + FC_LOG_MSG_FP_0734, + fc_mes0734, + fc_msgPreambleFPe, + FC_MSG_OPUT_GLOB_CTRL, + FC_LOG_MSG_TYPE_ERR, + LOG_FCP, + ERRID_LOG_HDW_ERR }; + +/* +msgName: fc_mes0735 +message: FCP Read Check Error with Check Condition +descript: The issued FCP command returned a Read Check Error and a + Check condition. +data: (1) *cmd + WD7 (2) ulpContext (3) rspResId (4) fcpi_parm +severity: Error +log: Always +module: fcscsib.c +action: Check the state of the target in question. +*/ +char fc_mes0735[] = "%sFCP Read Check Error with Check Condition Data: x%x x%x x%x x%x"; +msgLogDef fc_msgBlk0735= { + FC_LOG_MSG_FP_0735, + fc_mes0735, + fc_msgPreambleFPe, + FC_MSG_OPUT_GLOB_CTRL, + FC_LOG_MSG_TYPE_ERR, + LOG_FCP | LOG_CHK_COND, + ERRID_LOG_HDW_ERR }; + +/* +msgName: fc_mes0736 +message: FCP QUEUE Full +descript: Received a Queue Full status from the FCP device. +data: (1) fcp_cur_queue_depth (2) active_io_count (3) flags (4) a_current +severity: Information +log: LOG_FCP verbose +module: fcscsib.c +action: None required +*/ +char fc_mes0736[] = "%sFCP QUEUE Full Data: x%x x%x x%x x%x"; +msgLogDef fc_msgBlk0736 = { + FC_LOG_MSG_FP_0736, + fc_mes0736, + fc_msgPreambleFPi, + FC_MSG_OPUT_GLOB_CTRL, + FC_LOG_MSG_TYPE_INFO, + LOG_FCP, + ERRID_LOG_UNEXPECT_EVENT }; + +/* +msgName: fc_mes0737 +message: FCP error: Check condition +descript: The issued FCP command resulted in a Check Condition. +data: (1) *cmd + WD7 (2) ulpIoTag (3) ulpContext (4) statLocalError +severity: Information +log: LOG_FCP | LOG_CHK_COND verbose +module: fcscsib.c +action: None required +*/ +char fc_mes0737[] = "%sFCP error: Check condition Data: x%x x%x x%x x%x"; +msgLogDef fc_msgBlk0737 = { + FC_LOG_MSG_FP_0737, + fc_mes0737, + fc_msgPreambleFPi, + FC_MSG_OPUT_GLOB_CTRL, + FC_LOG_MSG_TYPE_INFO, + LOG_FCP | LOG_CHK_COND, + ERRID_LOG_UNEXPECT_EVENT }; + +/* +msgName: fc_mes0738 +message: 29,00 Check condition received +descript: The received check condition indicates the device was powered + on or reset. +data: (1) lp[0] (2) lp[1] (3) lp[2] (4) lp[3] +severity: Information +log: LOG_FCP | LOG_CHK_COND verbose +module: fcscsib.c +action: None required +*/ +char fc_mes0738[] = "%s29,00 Check condition received Data: x%x x%x x%x x%x"; +msgLogDef fc_msgBlk0738 = { + FC_LOG_MSG_FP_0738, + fc_mes0738, + fc_msgPreambleFPi, + FC_MSG_OPUT_GLOB_CTRL, + FC_LOG_MSG_TYPE_INFO, + LOG_FCP | LOG_CHK_COND, + ERRID_LOG_UNEXPECT_EVENT }; + +/* +msgName: fc_mes0739 +message: Check condition received ERR1 +descript: The command SCSI3_PERSISTENT_RESERVE_IN resulted in a Invalid + Command operation code check condition. +data: (1) lp[0] (2) lp[1] (3) lp[2] (4) lp[3] +severity: Information +log: LOG_FCP | LOG_CHK_COND verbose +module: fcscsib.c +action: None required +*/ +char fc_mes0739[] = "%sCheck condition received ERR1 Data: x%x x%x x%x x%x"; +msgLogDef fc_msgBlk0739 = { + FC_LOG_MSG_FP_0739, + fc_mes0739, + fc_msgPreambleFPi, + FC_MSG_OPUT_GLOB_CTRL, + FC_LOG_MSG_TYPE_INFO, + LOG_FCP | LOG_CHK_COND, + ERRID_LOG_UNEXPECT_EVENT }; + +/* +msgName: fc_mes0740 +message: Check condition received ERR2 +descript: The check condition meets the criteria for the configuration + parameters lpfc_check_cond_err and lpfc_delay_rsp_err. +data: (1) lp[0] (2) lp[1] (3) lp[2] (4) lp[3] +severity: Information +log: LOG_FCP | LOG_CHK_COND verbose +module: fcscsib.c +action: None required +*/ +char fc_mes0740[] = "%sCheck condition received ERR2 Data: x%x x%x x%x x%x"; +msgLogDef fc_msgBlk0740 = { + FC_LOG_MSG_FP_0740, + fc_mes0740, + fc_msgPreambleFPi, + FC_MSG_OPUT_GLOB_CTRL, + FC_LOG_MSG_TYPE_INFO, + LOG_FCP | LOG_CHK_COND, + ERRID_LOG_UNEXPECT_EVENT }; + +/* +msgName: fc_mes0741 +message: Check condition received +descript: The issued FCP command resulted in a Check Condition. +data: (1) lp[0] (2) lp[1] (3) lp[2] (4) lp[3] +severity: Information +log: LOG_FCP | LOG_CHK_COND verbose +module: fcscsib.c +action: None required +*/ +char fc_mes0741[] = "%sCheck condition received Data: x%x x%x x%x x%x"; +msgLogDef fc_msgBlk0741 = { + FC_LOG_MSG_FP_0741, + fc_mes0741, + fc_msgPreambleFPi, + FC_MSG_OPUT_GLOB_CTRL, + FC_LOG_MSG_TYPE_INFO, + LOG_FCP | LOG_CHK_COND, + ERRID_LOG_UNEXPECT_EVENT }; + +/* +msgName: fc_mes0742 +message: FCP completion error +descript: An FCP command completed with a status error in the IOCB. +data: (1) ulpStatus (2) ulpWord[4] (3) did. +severity: Information +log: LOG_FCP verbose +module: fcscsib.c +action: If there are many errors to one device, check physical + connections to Fibre Channel network and the state of the + remote PortID. +*/ +char fc_mes0742[] = "%sFCP completion error Data: x%x x%x x%x"; +msgLogDef fc_msgBlk0742 = { + FC_LOG_MSG_FP_0742, + fc_mes0742, + fc_msgPreambleFPi, + FC_MSG_OPUT_GLOB_CTRL, + FC_LOG_MSG_TYPE_INFO, + LOG_FCP, + ERRID_LOG_UNEXPECT_EVENT }; + +/* +msgName: fc_mes0743 +message: FCP completion error +descript: An FCP command completed with a status error in the IOCB. +data: (1) ulpStatus (2) ulpWord[4] (3) did. +severity: Information +log: LOG_FCP verbose +module: fcscsib.c +action: If there are many errors to one device, check physical + connections to Fibre Channel network and the state of the + remote PortID. +*/ +char fc_mes0743[] = "%sFCP completion error Data: x%x x%x x%x"; +msgLogDef fc_msgBlk0743 = { + FC_LOG_MSG_FP_0743, + fc_mes0743, + fc_msgPreambleFPi, + FC_MSG_OPUT_GLOB_CTRL, + FC_LOG_MSG_TYPE_INFO, + LOG_FCP, + ERRID_LOG_HDW_ERR }; + +/* +msgName: fc_mes0744 +message: FCP completion error +descript: An FCP command completed with a status error in the IOCB. +data: (1) did (2) *lp (3) *(lp+2) (4) *(lp+3) +severity: Information +log: LOG_FCP verbose +module: fcscsib.c +action: If there are many errors to one device, check physical + connections to Fibre Channel network and the state of the + remote PortID. +*/ +char fc_mes0744[] = "%sFCP completion error Data: x%x x%x x%x x%x"; +msgLogDef fc_msgBlk0744 = { + FC_LOG_MSG_FP_0744, + fc_mes0744, + fc_msgPreambleFPi, + FC_MSG_OPUT_GLOB_CTRL, + FC_LOG_MSG_TYPE_INFO, + LOG_FCP, + ERRID_LOG_UNEXPECT_EVENT }; + +/* +msgName: fc_mes0745 +message: FCP completion error +descript: An FCP command completed with a status error in the IOCB. +data: (1) ulpStatus (2) ulpWord[4] (3) did. +severity: Information +log: LOG_FCP verbose +module: fcscsib.c +action: If there are many errors to one device, check physical + connections to Fibre Channel network and the state of the + remote PortID. +*/ +char fc_mes0745[] = "%sFCP completion error Data: x%x x%x x%x"; +msgLogDef fc_msgBlk0745 = { + FC_LOG_MSG_FP_0745, + fc_mes0745, + fc_msgPreambleFPi, + FC_MSG_OPUT_GLOB_CTRL, + FC_LOG_MSG_TYPE_INFO, + LOG_FCP, + ERRID_LOG_HDW_ERR }; + +/* +msgName: fc_mes0746 +message: FCP completion error +descript: An FCP command completed with a status error in the IOCB. +data: (1) ulpStatus (2) ulpWord[4] (3) did. +severity: Information +log: LOG_FCP verbose +module: fcscsib.c +action: If there are many errors to one device, check physical + connections to Fibre Channel network and the state of the + remote PortID. +*/ +char fc_mes0746[] = "%sFCP completion error Data: x%x x%x x%x"; +msgLogDef fc_msgBlk0746 = { + FC_LOG_MSG_FP_0746, + fc_mes0746, + fc_msgPreambleFPi, + FC_MSG_OPUT_GLOB_CTRL, + FC_LOG_MSG_TYPE_INFO, + LOG_FCP, + ERRID_LOG_UNEXPECT_EVENT }; + +/* +msgName: fc_mes0747 +message: Cmpl Target Reset +descript: A driver initiated Target Reset completed. +data: (1) scsi_id (2) lun_id (3) statLocalError (4) *cmd + WD7 +severity: Information +log: LOG_FCP verbose +module: fcscsib.c +action: None required +*/ +char fc_mes0747[] = "%sCmpl Target Reset Data: x%x x%x x%x x%x"; +msgLogDef fc_msgBlk0747 = { + FC_LOG_MSG_FP_0747, + fc_mes0747, + fc_msgPreambleFPi, + FC_MSG_OPUT_GLOB_CTRL, + FC_LOG_MSG_TYPE_INFO, + LOG_FCP, + ERRID_LOG_UNEXPECT_EVENT }; + +/* +msgName: fc_mes0748 +message: Cmpl LUN Reset +descript: A driver initiated LUN Reset completed. +data: (1) scsi_id (2) lun_id (3) statLocalError (4) *cmd + WD7 +severity: Information +log: LOG_FCP verbose +module: fcscsib.c +action: None required +*/ +char fc_mes0748[] = "%sCmpl LUN Reset Data: x%x x%x x%x x%x"; +msgLogDef fc_msgBlk0748 = { + FC_LOG_MSG_FP_0748, + fc_mes0748, + fc_msgPreambleFPi, + FC_MSG_OPUT_GLOB_CTRL, + FC_LOG_MSG_TYPE_INFO, + LOG_FCP, + ERRID_LOG_UNEXPECT_EVENT }; + +/* +msgName: fc_mes0749 +message: Cmpl Abort Task Set +descript: A driver initiated Abort Task Set completed. +data: (1) scsi_id (2) lun_id (3) statLocalError (4) *cmd + WD7 +severity: Information +log: LOG_FCP verbose +module: fcscsib.c +action: None required +*/ +char fc_mes0749[] = "%sCmpl Abort Task Set Data: x%x x%x x%x x%x"; +msgLogDef fc_msgBlk0749 = { + FC_LOG_MSG_FP_0749, + fc_mes0749, + fc_msgPreambleFPi, + FC_MSG_OPUT_GLOB_CTRL, + FC_LOG_MSG_TYPE_INFO, + LOG_FCP, + ERRID_LOG_UNEXPECT_EVENT }; + +/* +msgName: fc_mes0750 +message: EXPIRED linkdown timer +descript: The link was down for greater than the configuration parameter + (lpfc_linkdown_tmo) seconds. All I/O associated with the devices + on this link will be failed. +data: (1) fc_ffstate +severity: Information +log: LOG_FCP | LOG_LINK_EVENT verbose +module: fcscsib.c +action: Check HBA cable/connection to Fibre Channel network. +*/ +char fc_mes0750[] = "%sEXPIRED linkdown timer Data: x%x"; +msgLogDef fc_msgBlk0750 = { + FC_LOG_MSG_FP_0750, + fc_mes0750, + fc_msgPreambleFPi, + FC_MSG_OPUT_GLOB_CTRL, + FC_LOG_MSG_TYPE_INFO, + LOG_FCP | LOG_LINK_EVENT, + ERRID_LOG_UNEXPECT_EVENT }; + +/* +msgName: fc_mes0751 +message: EXPIRED nodev timer +descript: A device disappeared for greater than the configuration parameter + (lpfc_nodev_tmo) seconds. All I/O associated with this device + will be failed. +data: (1) ndlp (2) nlp_flag (3) nlp_state (4) nlp_DID +severity: Information +log: LOG_FCP verbose +module: fcscsib.c +action: Check physical connections to Fibre Channel network and the + state of the remote PortID. +*/ +char fc_mes0751[] = "%sEXPIRED nodev timer Data: x%x x%x x%x x%x"; +msgLogDef fc_msgBlk0751 = { + FC_LOG_MSG_FP_0751, + fc_mes0751, + fc_msgPreambleFPi, + FC_MSG_OPUT_GLOB_CTRL, + FC_LOG_MSG_TYPE_INFO, + LOG_FCP, + ERRID_LOG_UNEXPECT_EVENT }; + +/* +msgName: fc_mes0752 +message: Device disappeared, nodev timeout +descript: A device disappeared for greater than the configuration + parameter (lpfc_nodev_tmo) seconds. All I/O associated with + this device will be failed. +data: (1) did (2) sid (3) pan (4) a_current +severity: Information +log: LOG_FCP verbose +module: fcscsib.c +action: Check physical connections to Fibre Channel network and the + state of the remote PortID. +*/ +char fc_mes0752[] = "%sDevice disappeared, nodev timeout Data: x%x x%x x%x x%x"; +msgLogDef fc_msgBlk0752 = { + FC_LOG_MSG_FP_0752, + fc_mes0752, + fc_msgPreambleFPi, + FC_MSG_OPUT_GLOB_CTRL, + FC_LOG_MSG_TYPE_INFO, + LOG_FCP, + ERRID_LOG_UNEXPECT_EVENT }; + +/* +msgName: fc_mes0753 +message: Inquiry Serial Number: invalid length +descript: An INQUIRY SN command completed with an invalid serial number length. +data: (1) sizeSN (2) j (3) scsi_id (4) lun_id +severity: Error +log: Always +module: fcscsib.c +action: Check state of target in question. +*/ +char fc_mes0753[] = "%sInquiry Serial Number: invalid length Data: x%x x%x x%x x%x"; +msgLogDef fc_msgBlk0753= { + FC_LOG_MSG_FP_0753, + fc_mes0753, + fc_msgPreambleFPe, + FC_MSG_OPUT_GLOB_CTRL, + FC_LOG_MSG_TYPE_ERR, + LOG_FCP, + ERRID_LOG_HDW_ERR }; + +/* +msgName: fc_mes0754 +message: SCSI timeout +descript: An FCP IOCB command was posted to a ring and did not complete + within ULP timeout seconds. +data: (1) did (2) sid +severity: Warning +log: LOG_FCP verbose +module: fcscsib.c +action: If no I/O is going through the adapter, reboot the system; + otherwise check the state of the target in question. +*/ +char fc_mes0754[] = "%sSCSI timeout Data: x%x x%x"; +msgLogDef fc_msgBlk0754 = { + FC_LOG_MSG_FP_0754, + fc_mes0754, + fc_msgPreambleFPw, + FC_MSG_OPUT_GLOB_CTRL, + FC_LOG_MSG_TYPE_WARN, + LOG_FCP, + ERRID_LOG_TIMEOUT }; + +/* +msgName: fc_mes0756 +message: Local_timeout Skipping clock tick +descript: The DPC thread has not been scheduled within several seconds +data: (1) dpc_ha_copy (2) ha_copy (3) dpc_cnt (4) fc_ffstate +severity: Warning +log: LOG_FCP verbose +module: fcLINUXfcp.c +action: Check the state of the target in question. +*/ +char fc_mes0756[] = "%sLocal_timeout Skipping clock tick Data: x%x x%x x%x x%x"; +msgLogDef fc_msgBlk0756= { + FC_LOG_MSG_FP_0756, + fc_mes0756, + fc_msgPreambleFPw, + FC_MSG_OPUT_GLOB_CTRL, + FC_LOG_MSG_TYPE_WARN, + LOG_FCP, + ERRID_LOG_UNEXPECT_EVENT }; + +/* + * UNUSED 0800 + */ + +/* + * Begin NODE LOG Message Structures + */ + +/* +msgName: fc_mes0900 +message: FIND node rpi +descript: The driver is looking up the node table entry for a remote + NPORT based on its RPI. +data: (1) ndlp (2) rpi +severity: Information +log: LOG_NODE verbose +module: fcrpib.c +action: None requird +*/ +char fc_mes0900[] = "%sFIND node rpi Data: x%x x%x"; +msgLogDef fc_msgBlk0900 = { + FC_LOG_MSG_ND_0900, + fc_mes0900, + fc_msgPreambleNDi, + FC_MSG_OPUT_GLOB_CTRL, + FC_LOG_MSG_TYPE_INFO, + LOG_NODE, + ERRID_LOG_UNEXPECT_EVENT }; + +/* +msgName: fc_mes0901 +message: Free node tbl +descript: The driver is freeing a node table entry. +data: (1) nlp_DID (2) nlp_flag (3) nlp_Rpi (4) data1 +severity: Information +log: LOG_NODE verbose +module: fcrpib.c +action: None required +*/ +char fc_mes0901[] = "%sFree node tbl Data: x%x x%x x%x x%x"; +msgLogDef fc_msgBlk0901 = { + FC_LOG_MSG_ND_0901, + fc_mes0901, + fc_msgPreambleNDi, + FC_MSG_OPUT_GLOB_CTRL, + FC_LOG_MSG_TYPE_INFO, + LOG_NODE, + ERRID_LOG_UNEXPECT_EVENT }; + +/* +msgName: fc_mes0902 +message: Free node IEEE +descript: The driver freeing a node table entry. +data: (1) IEEE[2] (2) IEEE[3] (3) IEEE[4] (4) IEEE[5] +severity: Information +log: LOG_NODE verbose +module: fcrpib.c +action: None required +*/ +char fc_mes0902[] = "%sFree node IEEE Data: x%x x%x x%x x%x"; +msgLogDef fc_msgBlk0902 = { + FC_LOG_MSG_ND_0902, + fc_mes0902, + fc_msgPreambleNDi, + FC_MSG_OPUT_GLOB_CTRL, + FC_LOG_MSG_TYPE_INFO, + LOG_NODE, + ERRID_LOG_UNEXPECT_EVENT }; + +/* +msgName: fc_mes0903 +message: BIND node tbl +descript: The driver is putting the node table entry on the binding list. +data: (1) nlp (2) nlp_DID (3) nlp_flag (4) data1 +severity: Information +log: LOG_NODE verbose +module: fcrpib.c +action: None required +*/ +char fc_mes0903[] = "%sBIND node tbl Data: x%x x%x x%x x%x"; +msgLogDef fc_msgBlk0903= { + FC_LOG_MSG_ND_0903, + fc_mes0903, + fc_msgPreambleNDi, + FC_MSG_OPUT_GLOB_CTRL, + FC_LOG_MSG_TYPE_INFO, + LOG_NODE, + ERRID_LOG_UNEXPECT_EVENT }; + +/* +msgName: fc_mes0904 +message: UNMAP node tbl +descript: The driver is putting the node table entry on the unmapped node list. +data: (1) nlp (2) nlp_DID (3) nlp_flag (4) data1 +severity: Information +log: LOG_NODE verbose +module: fcrpib.c +action: None required +*/ +char fc_mes0904[] = "%sUNMAP node tbl Data: x%x x%x x%x x%x"; +msgLogDef fc_msgBlk0904 = { + FC_LOG_MSG_ND_0904, + fc_mes0904, + fc_msgPreambleNDi, + FC_MSG_OPUT_GLOB_CTRL, + FC_LOG_MSG_TYPE_INFO, + LOG_NODE, + ERRID_LOG_UNEXPECT_EVENT }; + +/* +msgName: fc_mes0905 +message: MAP node tbl +descript: The driver is putting the node table entry on the mapped node list. +data: (1) nlp (2) nlp_DID (3) nlp_flag (4) data1 +severity: Information +log: LOG_NODE verbose +module: fcrpib.c +action: None required +*/ +char fc_mes0905[] = "%sMAP node tbl Data: x%x x%x x%x x%x"; +msgLogDef fc_msgBlk0905 = { + FC_LOG_MSG_ND_0905, + fc_mes0905, + fc_msgPreambleNDi, + FC_MSG_OPUT_GLOB_CTRL, + FC_LOG_MSG_TYPE_INFO, + LOG_NODE, + ERRID_LOG_UNEXPECT_EVENT }; + +/* +msgName: fc_mes0906 +message: FIND node DID unmapped +descript: The driver is searching for a node table entry, on the + unmapped node list, based on DID. +data: (1) nlp (2) nlp_DID (3) nlp_flag (4) data1 +severity: Information +log: LOG_NODE verbose +module: fcrpib.c +action: None required +*/ +char fc_mes0906[] = "%sFIND node DID unmapped Data: x%x x%x x%x x%x"; +msgLogDef fc_msgBlk0906 = { + FC_LOG_MSG_ND_0906, + fc_mes0906, + fc_msgPreambleNDi, + FC_MSG_OPUT_GLOB_CTRL, + FC_LOG_MSG_TYPE_INFO, + LOG_NODE, + ERRID_LOG_UNEXPECT_EVENT }; + +/* +msgName: fc_mes0907 +message: FIND node DID mapped +descript: The driver is searching for a node table entry, on the + mapped node list, based on DID. +data: (1) nlp (2) nlp_DID (3) nlp_flag (4) data1 +severity: Information +log: LOG_NODE verbose +module: fcrpib.c +action: None required +*/ +char fc_mes0907[] = "%sFIND node DID mapped Data: x%x x%x x%x x%x"; +msgLogDef fc_msgBlk0907 = { + FC_LOG_MSG_ND_0907, + fc_mes0907, + fc_msgPreambleNDi, + FC_MSG_OPUT_GLOB_CTRL, + FC_LOG_MSG_TYPE_INFO, + LOG_NODE, + ERRID_LOG_UNEXPECT_EVENT }; + +/* +msgName: fc_mes0908 +message: FIND node DID bind +descript: The driver is searching for a node table entry, on the + binding list, based on DID. +data: (1) nlp (2) nlp_DID (3) nlp_flag (4) data1 +severity: Information +log: LOG_NODE verbose +module: fcrpib.c +action: None required +*/ +char fc_mes0908[] = "%sFIND node DID bind Data: x%x x%x x%x x%x"; +msgLogDef fc_msgBlk0908 = { + FC_LOG_MSG_ND_0908, + fc_mes0908, + fc_msgPreambleNDi, + FC_MSG_OPUT_GLOB_CTRL, + FC_LOG_MSG_TYPE_INFO, + LOG_NODE, + ERRID_LOG_UNEXPECT_EVENT }; + +/* +msgName: fc_mes0909 +message: FIND node did NOT FOUND +descript: The driver was searching for a node table entry based on DID + and the entry was not found. +data: (1) order +severity: Information +log: LOG_NODE verbose +module: fcrpib.c +action: None required +*/ +char fc_mes0909[] = "%sFIND node did x%x NOT FOUND Data: x%x"; +msgLogDef fc_msgBlk0909 = { + FC_LOG_MSG_ND_0909, + fc_mes0909, + fc_msgPreambleNDi, + FC_MSG_OPUT_GLOB_CTRL, + FC_LOG_MSG_TYPE_INFO, + LOG_NODE, + ERRID_LOG_UNEXPECT_EVENT }; + +/* +msgName: fc_mes0910 +message: FIND node scsi_id unmapped +descript: The driver is searching for a node table entry, on the + unmapped node list, based on the SCSI ID. +data: (1) nlp (2) nlp_DID (3) nlp_flag (4) data1 +severity: Information +log: LOG_NODE verbose +module: fcrpib.c +action: None required +*/ +char fc_mes0910[] = "%sFIND node scsi_id unmapped Data: x%x x%x x%x x%x"; +msgLogDef fc_msgBlk0910 = { + FC_LOG_MSG_ND_0910, + fc_mes0910, + fc_msgPreambleNDi, + FC_MSG_OPUT_GLOB_CTRL, + FC_LOG_MSG_TYPE_INFO, + LOG_NODE, + ERRID_LOG_UNEXPECT_EVENT }; + +/* +msgName: fc_mes0911 +message: FIND node scsi_id mapped +descript: The driver is searching for a node table entry, on the + mapped node list, based on the SCSI ID. +data: (1) nlp (2) nlp_DID (3) nlp_flag (4) data1 +severity: Information +log: LOG_NODE verbose +module: fcrpib.c +action: None required +*/ +char fc_mes0911[] = "%sFIND node scsi_id mapped Data: x%x x%x x%x x%x"; +msgLogDef fc_msgBlk0911 = { + FC_LOG_MSG_ND_0911, + fc_mes0911, + fc_msgPreambleNDi, + FC_MSG_OPUT_GLOB_CTRL, + FC_LOG_MSG_TYPE_INFO, + LOG_NODE, + ERRID_LOG_UNEXPECT_EVENT }; + +/* +msgName: fc_mes0912 +message: FIND node scsi_id bind +descript: The driver is searching for a node table entry, on the + binding list, based on the SCSI ID. +data: (1) nlp (2) nlp_DID (3) nlp_flag (4) data1 +severity: Information +log: LOG_NODE verbose +module: fcrpib.c +action: None required +*/ +char fc_mes0912[] = "%sFIND node scsi_id bind Data: x%x x%x x%x x%x"; +msgLogDef fc_msgBlk0912 = { + FC_LOG_MSG_ND_0912, + fc_mes0912, + fc_msgPreambleNDi, + FC_MSG_OPUT_GLOB_CTRL, + FC_LOG_MSG_TYPE_INFO, + LOG_NODE, + ERRID_LOG_UNEXPECT_EVENT }; + +/* +msgName: fc_mes0913 +message: FIND node scsi_id NOT FOUND +descript: The driver was searching for a node table entry based on SCSI ID + and the entry was not found. +data: (1) scsid (2) order +severity: Information +log: LOG_NODE verbose +module: fcrpib.c +action: None required +*/ +char fc_mes0913[] = "%sFIND node scsi_id NOT FOUND Data: x%x x%x"; +msgLogDef fc_msgBlk0913 = { + FC_LOG_MSG_ND_0913, + fc_mes0913, + fc_msgPreambleNDi, + FC_MSG_OPUT_GLOB_CTRL, + FC_LOG_MSG_TYPE_INFO, + LOG_NODE, + ERRID_LOG_UNEXPECT_EVENT }; + +/* +msgName: fc_mes0914 +message: FIND node wwnn unmapped +descript: The driver is searching for a node table entry, on the + unmapped port list, based on the WWNN. +data: (1) nlp (2) nlp_DID (3) nlp_flag (4) data1 +severity: Information +log: LOG_NODE verbose +module: fcrpib.c +action: None required +*/ +char fc_mes0914[] = "%sFIND node wwnn unmapped Data: x%x x%x x%x x%x"; +msgLogDef fc_msgBlk0914 = { + FC_LOG_MSG_ND_0914, + fc_mes0914, + fc_msgPreambleNDi, + FC_MSG_OPUT_GLOB_CTRL, + FC_LOG_MSG_TYPE_INFO, + LOG_NODE, + ERRID_LOG_UNEXPECT_EVENT }; + +/* +msgName: fc_mes0915 +message: FIND node wwnn mapped +descript: The driver is searching for a node table entry, on the + mapped port list, based on the WWNN. +data: (1) nlp (2) nlp_DID (3) nlp_flag (4) data1 +severity: Information +log: LOG_NODE verbose +module: fcrpib.c +action: None required +*/ +char fc_mes0915[] = "%sFIND node wwnn mapped Data: x%x x%x x%x x%x"; +msgLogDef fc_msgBlk0915 = { + FC_LOG_MSG_ND_0915, + fc_mes0915, + fc_msgPreambleNDi, + FC_MSG_OPUT_GLOB_CTRL, + FC_LOG_MSG_TYPE_INFO, + LOG_NODE, + ERRID_LOG_UNEXPECT_EVENT }; + +/* +msgName: fc_mes0916 +message: FIND node wwnn bind +descript: The driver is searching for a node table entry, on the + binding list, based on the WWNN. +data: (1) nlp (2) nlp_DID (3) nlp_flag (4) data1 +severity: Information +log: LOG_NODE verbose +module: fcrpib.c +action: None required +*/ +char fc_mes0916[] = "%sFIND node wwnn bind Data: x%x x%x x%x x%x"; +msgLogDef fc_msgBlk0916 = { + FC_LOG_MSG_ND_0916, + fc_mes0916, + fc_msgPreambleNDi, + FC_MSG_OPUT_GLOB_CTRL, + FC_LOG_MSG_TYPE_INFO, + LOG_NODE, + ERRID_LOG_UNEXPECT_EVENT }; + +/* +msgName: fc_mes0917 +message: PUT END nodelist +descript: The driver is freeing a node table entry buffer. +data: (1) bp (2) fc_free +severity: Information +log: LOG_NODE verbose +module: fcmemb.c +action: None required +*/ +char fc_mes0917[] = "%sPUT END nodelist Data: x%x x%x"; +msgLogDef fc_msgBlk0917 = { + FC_LOG_MSG_ND_0917, + fc_mes0917, + fc_msgPreambleNDi, + FC_MSG_OPUT_GLOB_CTRL, + FC_LOG_MSG_TYPE_INFO, + LOG_NODE, + ERRID_LOG_UNEXPECT_EVENT }; + +/* +msgName: fc_mes0918 +message: FIND node wwnn NOT FOUND +descript: The driver was searching for a node table entry based on WWNN + and the entry was not found. +data: (1) order +severity: Information +log: LOG_NODE verbose +module: fcrpib.c +action: None required +*/ +char fc_mes0918[] = "%sFIND node wwnn NOT FOUND Data: x%x"; +msgLogDef fc_msgBlk0918 = { + FC_LOG_MSG_ND_0918, + fc_mes0918, + fc_msgPreambleNDi, + FC_MSG_OPUT_GLOB_CTRL, + FC_LOG_MSG_TYPE_INFO, + LOG_NODE, + ERRID_LOG_UNEXPECT_EVENT }; + +/* +msgName: fc_mes0919 +message: FIND node wwpn unmapped +descript: The driver is searching for a node table entry, on the + unmapped port list, based on the WWPN. +data: (1) nlp (2) nlp_DID (3) nlp_flag (4) data1 +severity: Information +log: LOG_NODE verbose +module: fcrpib.c +action: None required +*/ +char fc_mes0919[] = "%sFIND node wwpn unmapped Data: x%x x%x x%x x%x"; +msgLogDef fc_msgBlk0919 = { + FC_LOG_MSG_ND_0919, + fc_mes0919, + fc_msgPreambleNDi, + FC_MSG_OPUT_GLOB_CTRL, + FC_LOG_MSG_TYPE_INFO, + LOG_NODE, + ERRID_LOG_UNEXPECT_EVENT }; + +/* +msgName: fc_mes0920 +message: FIND node wwpn mapped +descript: The driver is searching for a node table entry, on the + mapped port list, based on the WWPN. +data: (1) nlp (2) nlp_DID (3) nlp_flag (4) data1 +severity: Information +log: LOG_NODE verbose +module: fcrpib.c +action: None required +*/ +char fc_mes0920[] = "%sFIND node wwpn mapped Data: x%x x%x x%x x%x"; +msgLogDef fc_msgBlk0920 = { + FC_LOG_MSG_ND_0920, + fc_mes0920, + fc_msgPreambleNDi, + FC_MSG_OPUT_GLOB_CTRL, + FC_LOG_MSG_TYPE_INFO, + LOG_NODE, + ERRID_LOG_UNEXPECT_EVENT }; + +/* +msgName: fc_mes0921 +message: FIND node wwpn bind +descript: The driver is searching for a node table entry, on the + binding list, based on the WWPN. +data: (1) nlp (2) nlp_DID (3) nlp_flag (4) data1 +severity: Information +log: LOG_NODE verbose +module: fcrpib.c +action: None required +*/ +char fc_mes0921[] = "%sFIND node wwpn bind Data: x%x x%x x%x x%x"; +msgLogDef fc_msgBlk0921 = { + FC_LOG_MSG_ND_0921, + fc_mes0921, + fc_msgPreambleNDi, + FC_MSG_OPUT_GLOB_CTRL, + FC_LOG_MSG_TYPE_INFO, + LOG_NODE, + ERRID_LOG_UNEXPECT_EVENT }; + +/* +msgName: fc_mes0922 +message: FIND node wwpn NOT FOUND +descript: The driver was searching for a node table entry based on WWPN + and the entry was not found. +data: (1) order +severity: Information +log: LOG_NODE verbose +module: fcrpib.c +action: None required +*/ +char fc_mes0922[] = "%sFIND node wwpn NOT FOUND Data: x%x"; +msgLogDef fc_msgBlk0922 = { + FC_LOG_MSG_ND_0922, + fc_mes0922, + fc_msgPreambleNDi, + FC_MSG_OPUT_GLOB_CTRL, + FC_LOG_MSG_TYPE_INFO, + LOG_NODE, + ERRID_LOG_UNEXPECT_EVENT }; + +/* +msgName: fc_mes0923 +message: FIND node xri unmapped +descript: The driver is searching for a node table entry, on the + unmapped port list, based on the XRI. +data: (1) nlp (2) nlp_Xri (3) nlp_flag (4) data1 +severity: Information +log: LOG_NODE verbose +module: fcrpib.c +action: None required +*/ +char fc_mes0923[] = "%sFIND node xri unmapped Data: x%x x%x x%x x%x"; +msgLogDef fc_msgBlk0923 = { + FC_LOG_MSG_ND_0923, + fc_mes0923, + fc_msgPreambleNDi, + FC_MSG_OPUT_GLOB_CTRL, + FC_LOG_MSG_TYPE_INFO, + LOG_NODE, + ERRID_LOG_UNEXPECT_EVENT }; + +/* +msgName: fc_mes0924 +message: FIND node xri mapped +descript: The driver is searching for a node table entry, on the + mapped port list, based on the XRI. +data: (1) nlp (2) nlp_Xri (3) nlp_flag (4) data1 +severity: Information +log: LOG_NODE verbose +module: fcrpib.c +action: None required +*/ +char fc_mes0924[] = "%sFIND node xri mapped Data: x%x x%x x%x x%x"; +msgLogDef fc_msgBlk0924 = { + FC_LOG_MSG_ND_0924, + fc_mes0924, + fc_msgPreambleNDi, + FC_MSG_OPUT_GLOB_CTRL, + FC_LOG_MSG_TYPE_INFO, + LOG_NODE, + ERRID_LOG_UNEXPECT_EVENT }; + +/* +msgName: fc_mes0925 +message: FIND node xri bind +descript: The driver is searching for a node table entry, on the + binding list, based on the XRI. +data: (1) nlp (2) nlp_Xri (3) nlp_flag (4) data1 +severity: Information +log: LOG_NODE verbose +module: fcrpib.c +action: None required +*/ +char fc_mes0925[] = "%sFIND node xri bind Data: x%x x%x x%x x%x"; +msgLogDef fc_msgBlk0925 = { + FC_LOG_MSG_ND_0925, + fc_mes0925, + fc_msgPreambleNDi, + FC_MSG_OPUT_GLOB_CTRL, + FC_LOG_MSG_TYPE_INFO, + LOG_NODE, + ERRID_LOG_UNEXPECT_EVENT }; + +/* +msgName: fc_mes0926 +message: FIND node xri NOT FOUND +descript: The driver was searching for a node table entry based on the + XRI and the entry was not found. +data: (1) xri (2) order +severity: Information +log: LOG_NODE verbose +module: fcrpib.c +action: None required +*/ +char fc_mes0926[] = "%sFIND node xri NOT FOUND Data: x%x x%x"; +msgLogDef fc_msgBlk0926 = { + FC_LOG_MSG_ND_0926, + fc_mes0926, + fc_msgPreambleNDi, + FC_MSG_OPUT_GLOB_CTRL, + FC_LOG_MSG_TYPE_INFO, + LOG_NODE, + ERRID_LOG_UNEXPECT_EVENT }; + +/* +msgName: fc_mes0927 +message: GET nodelist +descript: The driver is allocating a buffer to hold a node table entry. +data: (1) bp (2) fc_free +severity: Information +log: LOG_NODE verbose +module: fcmemb.c +action: None required +*/ +char fc_mes0927[] = "%sGET nodelist Data: x%x x%x"; +msgLogDef fc_msgBlk0927 = { + FC_LOG_MSG_ND_0927, + fc_mes0927, + fc_msgPreambleNDi, + FC_MSG_OPUT_GLOB_CTRL, + FC_LOG_MSG_TYPE_INFO, + LOG_NODE, + ERRID_LOG_UNEXPECT_EVENT }; + +/* +msgName: fc_mes0928 +message: PUT nodelist +descript: The driver is freeing a node table entry buffer. +data: (1) bp (2) fc_free +severity: Information +log: LOG_NODE verbose +module: fcmemb.c +action: None required +*/ +char fc_mes0928[] = "%sPUT nodelist Data: x%x x%x"; +msgLogDef fc_msgBlk0928 = { + FC_LOG_MSG_ND_0928, + fc_mes0928, + fc_msgPreambleNDi, + FC_MSG_OPUT_GLOB_CTRL, + FC_LOG_MSG_TYPE_INFO, + LOG_NODE, + ERRID_LOG_UNEXPECT_EVENT }; + + + +/* + * Begin MISC LOG message structures + */ + +/* +msgName: fc_mes1200 +message: Cannot unload driver while lpfcdiag Interface is active Data +descript: An attempt was made to unload the driver while the DFC + interface was active. +data: (1) lpfcdiag_cnt (2) instance +severity: Error +log: Always +module: fcLINUXfcp.c +action: Exit any application that uses the DFC diagnostic interface + before attempting to unload the driver. +*/ +char fc_mes1200[] = "%sCannot unload driver while lpfcdiag Interface is active Data: x%x x%x"; +msgLogDef fc_msgBlk1200 = { + FC_LOG_MSG_MI_1200, + fc_mes1200, + fc_msgPreambleMIe, + FC_MSG_OPUT_GLOB_CTRL, + FC_LOG_MSG_TYPE_ERR, + LOG_MISC, + ERRID_LOG_UNEXPECT_EVENT }; + +/* +msgName: fc_mes1201 +message: lpfc_kmalloc: Bad p_dev_ctl +descript: The driver manages its own memory for internal usage. This + error indicates a problem occurred in the driver memory + management routines. This error could also indicate the host + system in low on memory resources. +data: (1) size (2) type (3) fc_idx_dmapool +severity: Error +log: Always +module: fcLINUXfcp.c +action: This error could indicate a driver or host operating system + problem. If problems persist report these errors to Technical + Support. +*/ +char fc_mes1201[] = "%slpfc_kmalloc: Bad p_dev_ctl Data: x%x x%x x%x"; +msgLogDef fc_msgBlk1201 = { + FC_LOG_MSG_MI_1201, + fc_mes1201, + fc_msgPreambleMIe, + FC_MSG_OPUT_GLOB_CTRL, + FC_LOG_MSG_TYPE_ERR, + LOG_MISC, + ERRID_LOG_UNEXPECT_EVENT }; + +/* +msgName: fc_mes1202 +message: lpfc_kmalloc: Bad size +descript: The driver manages its own memory for internal usage. This + error indicates a problem occurred in the driver memory + management routines. This error could also indicate the host + system in low on memory resources. +data: (1) size (2) type (3) fc_idx_dmapool +severity: Error +log: Always +module: fcLINUXfcp.c +action: This error could indicate a driver or host operating system + problem. If problems persist report these errors to Technical + Support. +*/ +char fc_mes1202[] = "%slpfc_kmalloc: Bad size Data: x%x x%x x%x"; +msgLogDef fc_msgBlk1202 = { + FC_LOG_MSG_MI_1202, + fc_mes1202, + fc_msgPreambleMIe, + FC_MSG_OPUT_GLOB_CTRL, + FC_LOG_MSG_TYPE_ERR, + LOG_MISC, + ERRID_LOG_UNEXPECT_EVENT }; + +/* +msgName: fc_mes1203 +message: lpfc_kmalloc: Virt addr failed to alloc +descript: The driver manages its own memory for internal usage. This + error indicates a problem occurred in the driver memory + management routines. This error could also indicate the host + system in low on memory resources. +data: (1) size (2) type +severity: Error +log: Always +module: fcLINUXfcp.c +action: This error could indicate a driver or host operating system + problem. If problems persist report these errors to Technical + Support. +*/ +char fc_mes1203[] = "%slpfc_kmalloc: Virt addr failed to alloc Data: x%x x%x"; +msgLogDef fc_msgBlk1203 = { + FC_LOG_MSG_MI_1203, + fc_mes1203, + fc_msgPreambleMIe, + FC_MSG_OPUT_GLOB_CTRL, + FC_LOG_MSG_TYPE_ERR, + LOG_MISC, + ERRID_LOG_UNEXPECT_EVENT }; + +/* +msgName: fc_mes1204 +message: lpfc_kmalloc: Bad virtual addr +descript: The driver manages its own memory for internal usage. This + error indicates a problem occurred in the driver memory + management routines. This error could also indicate the host + system in low on memory resources. +data: (1) i (2) size ( 3) type (4) fc_idx_dmapool +severity: Error +log: Always +module: fcLINUXfcp.c +action: This error could indicate a driver or host operating system + problem. If problems persist report these errors to Technical + Support. +*/ +char fc_mes1204[] = "%slpfc_kmalloc: Bad virtual addr Data: x%x x%x x%x x%x"; +msgLogDef fc_msgBlk1204 = { + FC_LOG_MSG_MI_1204, + fc_mes1204, + fc_msgPreambleMIe, + FC_MSG_OPUT_GLOB_CTRL, + FC_LOG_MSG_TYPE_ERR, + LOG_MISC, + ERRID_LOG_UNEXPECT_EVENT }; + +/* +msgName: fc_mes1205 +message: lpfc_kmalloc: dmapool FULL +descript: The driver manages its own memory for internal usage. This + error indicates a problem occurred in the driver memory + management routines. This error could also indicate the host + system in low on memory resources. +data: (1) i (2) size (3) type (4) fc_idx_dmapool +severity: Error +log: Always +module: fcLINUXfcp.c +action: This error could indicate a driver or host operating system + problem. If problems persist report these errors to Technical + Support. +*/ +char fc_mes1205[] = "%slpfc_kmalloc: dmapool FULL Data: x%x x%x x%x x%x"; +msgLogDef fc_msgBlk1205 = { + FC_LOG_MSG_MI_1205, + fc_mes1205, + fc_msgPreambleMIe, + FC_MSG_OPUT_GLOB_CTRL, + FC_LOG_MSG_TYPE_ERR, + LOG_MISC, + ERRID_LOG_UNEXPECT_EVENT }; + +/* +msgName: fc_mes1206 +message: lpfc_kfree: Bad p_dev_ctl +descript: The driver manages its own memory for internal usage. This + error indicates a problem occurred in the driver memory + management routines. This error could also indicate the host + system in low on memory resources. +data: (1) size (2) fc_idx_dmapool +severity: Error +log: Always +module: fcLINUXfcp.c +action: This error could indicate a driver or host operating system + problem. If problems persist report these errors to Technical + Support. +*/ +char fc_mes1206[] = "%slpfc_kfree: Bad p_dev_ctl Data: x%x x%x"; +msgLogDef fc_msgBlk1206 = { + FC_LOG_MSG_MI_1206, + fc_mes1206, + fc_msgPreambleMIe, + FC_MSG_OPUT_GLOB_CTRL, + FC_LOG_MSG_TYPE_ERR, + LOG_MISC, + ERRID_LOG_UNEXPECT_EVENT }; + +/* +msgName: fc_mes1207 +message: lpfc_kfree: NOT in dmapool +descript: The driver manages its own memory for internal usage. This + error indicates a problem occurred in the driver memory + management routines. This error could also indicate the host + system in low on memory resources. +data: (1) virt (2) size (3) fc_idx_dmapool +severity: Error +log: Always +module: fcLINUXfcp.c +action: This error could indicate a driver or host operating system + problem. If problems persist report these errors to Technical + Support. +*/ +char fc_mes1207[] = "%slpfc_kfree: NOT in dmapool Data: x%x x%x x%x"; +msgLogDef fc_msgBlk1207 = { + FC_LOG_MSG_MI_1207, + fc_mes1207, + fc_msgPreambleMIe, + FC_MSG_OPUT_GLOB_CTRL, + FC_LOG_MSG_TYPE_ERR, + LOG_MISC, + ERRID_LOG_UNEXPECT_EVENT }; + +/* +msgName: fc_mes1208 +descript: The CT response returned more data than the user buffer could hold. +message: C_CT Request error +data: (1) dfc_flag (2) 4096 +severity: Information +log: LOG_MISC verbose +module: dfcdd.c +action: Modify user application issuing CT request to allow for a larger + response buffer. +*/ +char fc_mes1208[] = "%sC_CT Request error Data: x%x x%x"; +msgLogDef fc_msgBlk1208 = { + FC_LOG_MSG_MI_1208, + fc_mes1208, + fc_msgPreambleMIi, + FC_MSG_OPUT_GLOB_CTRL, + FC_LOG_MSG_TYPE_INFO, + LOG_MISC, + ERRID_LOG_UNEXPECT_EVENT }; + +/* +msgName: fc_mes1209 +message: RNID Request error +descript: RNID sent back a response that was larger than the driver supports. +data: (1) fc_mptr (2) 4096 +severity: Information +log: LOG_MISC verbose +module: dfcdd.c +action: None required +*/ +char fc_mes1209[] = "%sRNID Request error Data: x%x x%x"; +msgLogDef fc_msgBlk1209 = { + FC_LOG_MSG_MI_1209, + fc_mes1209, + fc_msgPreambleMIi, + FC_MSG_OPUT_GLOB_CTRL, + FC_LOG_MSG_TYPE_INFO, + LOG_MISC, + ERRID_LOG_UNEXPECT_EVENT }; + +/* +msgName: fc_mes1210 +message: Convert ASC to hex. Input byte cnt < 1 +descript: ASCII string to hex conversion failed. Input byte count < 1. +data: none +severity: Error +log: Always +action: This error could indicate a software driver problem. + If problems persist report these errors to Technical Support. +*/ +char fc_mes1210[] = "%sConvert ASC to hex. Input byte cnt < 1"; +msgLogDef fc_msgBlk1210 = { + FC_LOG_MSG_MI_1210, + fc_mes1210, + fc_msgPreambleMIe, + FC_MSG_OPUT_GLOB_CTRL, + FC_LOG_MSG_TYPE_ERR, + LOG_MISC, + ERRID_LOG_UNEXPECT_EVENT }; + +/* +msgName: fc_mes1211 +message: Convert ASC to hex. Input byte cnt > max +descript: ASCII string to hex conversion failed. Input byte count > max . +data: none +severity: Error +log: Always +action: This error could indicate a software driver problem. + If problems persist report these errors to Technical Support. +*/ +char fc_mes1211[] = "%sConvert ASC to hex. Input byte cnt > max %d"; +msgLogDef fc_msgBlk1211 = { + FC_LOG_MSG_MI_1211, + fc_mes1211, + fc_msgPreambleMIe, + FC_MSG_OPUT_GLOB_CTRL, + FC_LOG_MSG_TYPE_ERR, + LOG_MISC, + ERRID_LOG_UNEXPECT_EVENT }; + +/* +msgName: fc_mes1212 +message: Convert ASC to hex. Output buffer to small +descript: ASCII string to hex conversion failed. The output buffer byte + size is less than 1/2 of input byte count. Every 2 input chars + (bytes) require 1 output byte. +data: none +severity: Error +log: Always +action: This error could indicate a software driver problem. + If problems persist report these errors to Technical Support. +*/ +char fc_mes1212[] = "%sConvert ASC to hex. Output buffer too small"; +msgLogDef fc_msgBlk1212 = { + FC_LOG_MSG_MI_1212, + fc_mes1212, + fc_msgPreambleMIe, + FC_MSG_OPUT_GLOB_CTRL, + FC_LOG_MSG_TYPE_ERR, + LOG_MISC, + ERRID_LOG_UNEXPECT_EVENT }; + +/* +msgName: fc_mes1213 +message: Convert ASC to hex. Input char seq not ASC hex. +descript: The ASCII hex input string contains a non-ASCII hex characters +data: none +severity: Error configuration +log: Always +action: Make neccessary changes to lpfc configuration file. +*/ +char fc_mes1213[] = "%sConvert ASC to hex. Input char seq not ASC hex."; +msgLogDef fc_msgBlk1213 = { + FC_LOG_MSG_MI_1213, + fc_mes1213, + fc_msgPreambleMIc, + FC_MSG_OPUT_GLOB_CTRL, + FC_LOG_MSG_TYPE_ERR_CFG, + LOG_MISC, + ERRID_LOG_UNEXPECT_EVENT }; + +/* + * Begin LINK LOG Message Structures + */ + +/* +msgName: fc_mes1300 +message: Re-establishing Link, timer expired +descript: The driver detected a condition where it had to re-initialize + the link. +data: (1) fc_flag (2) fc_ffstate +severity: Error +log: Always +module: fcclockb.c +action: If numerous link events are occurring, check physical + connections to Fibre Channel network. +*/ +char fc_mes1300[] = "%sRe-establishing Link, timer expired Data: x%x x%x"; +msgLogDef fc_msgBlk1300 = { + FC_LOG_MSG_LK_1300, + fc_mes1300, + fc_msgPreambleLKe, + FC_MSG_OPUT_GLOB_CTRL, + FC_LOG_MSG_TYPE_ERR, + LOG_LINK_EVENT, + ERRID_LOG_UNEXPECT_EVENT }; + +/* +msgName: fc_mes1301 +message: Re-establishing Link +descript: The driver detected a condition where it had to re-initialize + the link. +data: (1) status (2) status1 (3) status2 +severity: Information +log: LOG_LINK_EVENT verbose +module: lp6000.c +action: If numerous link events are occurring, check physical + connections to Fibre Channel network. +*/ +char fc_mes1301[] = "%sRe-establishing Link Data: x%x x%x x%x"; +msgLogDef fc_msgBlk1301 = { + FC_LOG_MSG_LK_1301, + fc_mes1301, + fc_msgPreambleLKi, + FC_MSG_OPUT_GLOB_CTRL, + FC_LOG_MSG_TYPE_INFO, + LOG_LINK_EVENT, + ERRID_LOG_UNEXPECT_EVENT }; + +/* +msgName: fc_mes1302 +message: Reset link speed to auto. 1G node detected in loop. +descript: The driver is reinitializing the link speed to auto-detect. + This acton results if a 2G HBA is configured for a link + speed of 2G and the HBA detects a node that does NOT + support 2G link speed. All nodes on that loop will come + up with a link speed equal to 1G. +data: none +severity: Warning +log: LOG_LINK_EVENT verbose +module: lp6000.c +action: None required +*/ +char fc_mes1302[] = "%sReset link speed to auto. 1G node detected in loop."; +msgLogDef fc_msgBlk1302 = { + FC_LOG_MSG_LK_1302, + fc_mes1302, + fc_msgPreambleLKw, + FC_MSG_OPUT_GLOB_CTRL, + FC_LOG_MSG_TYPE_WARN, + LOG_LINK_EVENT, + ERRID_LOG_UNEXPECT_EVENT }; + +/* +msgName: fc_mes1303 +message: Reset link speed to auto. 1G HBA cfg'd for 2G. +descript: The driver is reinitializing the link speed to auto-detect. + This acton results if a 1G HBA is configured for 2G + link speed operation. All nodes on that loop will come + up with a link speed equal to 1G. +data: none +severity: Warning +log: LOG_LINK_EVENT verbose +module: fcfcp.c +action: None required +*/ +char fc_mes1303[] = "%sReset link speed to auto. 1G HBA cfg'd for 2G"; +msgLogDef fc_msgBlk1303 = { + FC_LOG_MSG_LK_1303, + fc_mes1303, + fc_msgPreambleLKw, + FC_MSG_OPUT_GLOB_CTRL, + FC_LOG_MSG_TYPE_WARN, + LOG_LINK_EVENT, + ERRID_LOG_UNEXPECT_EVENT }; + +/* +msgName: fc_mes1304 +message: Link Up Event received +descript: A link up event was received. It is also possible for + multiple link events to be received together. +data: (1) eventTag (2) fc_eventTag (3) granted_AL_PA (4) alpa_map[0] +detail: If multiple link events received, log (1) current event + number, (2) last event number received, (3) ALPA granted, + (4) number of entries in the loop init LILP ALPA map. + An ALPA map message is also recorded if LINK_EVENT + verbose mode is set. Each ALPA map message contains + 16 ALPAs. +severity: Error +log: Always +module: fcscsib.c +action: If numerous link events are occurring, check physical + connections to Fibre Channel network. +*/ +char fc_mes1304[] = "%sLink Up Event received Data: x%x x%x x%x x%x"; +msgLogDef fc_msgBlk1304 = { + FC_LOG_MSG_LK_1304, + fc_mes1304, + fc_msgPreambleLKe, + FC_MSG_OPUT_GLOB_CTRL, + FC_LOG_MSG_TYPE_ERR, + LOG_LINK_EVENT, + ERRID_LOG_UNEXPECT_EVENT }; + +/* +msgName: fc_mes1305 +message: Link Up Event ALPA map +descript: A link up event was received. +data: (1) wd1 (2) wd2 (3) wd3 (4) wd4 +severity: Warning +log: LOG_LINK_EVENT verbose +module: fcscsib.c +action: If numerous link events are occurring, check physical + connections to Fibre Channel network. +*/ +char fc_mes1305[] = "%sLink Up Event ALPA map Data: x%x x%x x%x x%x"; +msgLogDef fc_msgBlk1305 = { + FC_LOG_MSG_LK_1305, + fc_mes1305, + fc_msgPreambleLKw, + FC_MSG_OPUT_GLOB_CTRL, + FC_LOG_MSG_TYPE_WARN, + LOG_LINK_EVENT, + ERRID_LOG_UNEXPECT_EVENT }; + +/* +msgName: fc_mes1306 +message: Link Down Event received +descript: A link down event was received. +data: (1) eventTag (2) fc_eventTag (3) granted_AL_PA (4) alpa_map[0] +severity: Error +log: Always +module: fcscsib.c +action: If numerous link events are occurring, check physical + connections to Fibre Channel network. +*/ +char fc_mes1306[] = "%sLink Down Event received Data: x%x x%x x%x x%x"; +msgLogDef fc_msgBlk1306 = { + FC_LOG_MSG_LK_1306, + fc_mes1306, + fc_msgPreambleLKe, + FC_MSG_OPUT_GLOB_CTRL, + FC_LOG_MSG_TYPE_ERR, + LOG_LINK_EVENT, + ERRID_LOG_UNEXPECT_EVENT }; + +/* +msgName: fc_mes1307 +message: SCSI Link Reset +descript: The SCSI layer has determined the link needs to be reset. + A LIP is sent to restart loop initialization. +data: None +severity: Error +log: Always +module: fcscsib.c +action: None required +*/ +char fc_mes1307[] = "%sSCSI Link Reset"; +msgLogDef fc_msgBlk1307 = { + FC_LOG_MSG_LK_1307, + fc_mes1307, + fc_msgPreambleLKe, + FC_MSG_OPUT_GLOB_CTRL, + FC_LOG_MSG_TYPE_ERR, + LOG_LINK_EVENT, + ERRID_LOG_UNEXPECT_EVENT }; + +/* + * Begin SLI LOG Message Structures + */ + +/* +msgName: fc_mes1400 +message: Unknown IOCB command +descript: Received an unknown IOCB command completion. +data: (1) ulpCommand (2) ulpStatus (3) ulpIoTag (4) ulpContext) +severity: Error +log: Always +module: lp6000.c +action: This error could indicate a software driver or firmware + problem. If these problems persist, report these errors + to Technical Support. +*/ +char fc_mes1400[] = "%sUnknown IOCB command Data: x%x x%x x%x x%x"; +msgLogDef fc_msgBlk1400 = { + FC_LOG_MSG_LK_1400, + fc_mes1400, + fc_msgPreambleSLe, + FC_MSG_OPUT_GLOB_CTRL, + FC_LOG_MSG_TYPE_ERR, + LOG_SLI, + ERRID_LOG_UNEXPECT_EVENT }; + +/* +msgName: fc_mes1401 +message: Command ring timeout +descript: An IOCB command was posted to a ring and did not complete + within a timeout based on RATOV. +data: (1) IOCB command (2) ulpCommand +severity: Error +log: Always +module: fcscsib.c +action: This error could indicate a software driver or firmware + problem. If no I/O is going through the adapter, reboot + the system. If these problems persist, report these errors + to Technical Support. +*/ +char fc_mes1401[] = "%sCommand ring %d timeout Data: x%x"; +msgLogDef fc_msgBlk1401 = { + FC_LOG_MSG_LK_1401, + fc_mes1401, + fc_msgPreambleSLe, + FC_MSG_OPUT_GLOB_CTRL, + FC_LOG_MSG_TYPE_ERR, + LOG_SLI, + ERRID_LOG_TIMEOUT }; + +/* +msgName: fc_mes1402 +message: Command ring timeout +descript: An IOCB command was posted to a ring and did not complete + within a timeout based on RATOV. +data: None +severity: Error +log: Always +module: fcscsib.c +action: This error could indicate a software driver or firmware + problem. If no I/O is going through the adapter, reboot + the system. If these problems persist, report these errors + to Technical Support. +*/ +char fc_mes1402[] = "%sCommand ring %d timeout"; +msgLogDef fc_msgBlk1402 = { + FC_LOG_MSG_LK_1402, + fc_mes1402, + fc_msgPreambleSLe, + FC_MSG_OPUT_GLOB_CTRL, + FC_LOG_MSG_TYPE_ERR, + LOG_SLI, + ERRID_LOG_TIMEOUT }; + + diff -purN -X /home/mbligh/.diff.exclude 350-autoswap/drivers/scsi/lpfc/fcrpib.c 370-emulex/drivers/scsi/lpfc/fcrpib.c --- 350-autoswap/drivers/scsi/lpfc/fcrpib.c 1969-12-31 16:00:00.000000000 -0800 +++ 370-emulex/drivers/scsi/lpfc/fcrpib.c 2004-02-28 11:20:04.000000000 -0800 @@ -0,0 +1,2675 @@ +/******************************************************************* + * This file is part of the Emulex Linux Device Driver for * + * Enterprise Fibre Channel Host Bus Adapters. * + * Refer to the README file included with this package for * + * driver version and adapter support. * + * Copyright (C) 2003 Emulex Corporation. * + * www.emulex.com * + * * + * This program is free software; you can redistribute it and/or * + * modify it under the terms of the GNU General Public License * + * as published by the Free Software Foundation; either version 2 * + * of the License, or (at your option) any later version. * + * * + * This program is distributed in the hope that it will be useful, * + * but WITHOUT ANY WARRANTY; without even the implied warranty of * + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * + * GNU General Public License for more details, a copy of which * + * can be found in the file COPYING included with this package. * + *******************************************************************/ + +#include "fc_os.h" + +#include "fc_hw.h" +#include "fc.h" + +#include "fcdiag.h" +#include "fcfgparm.h" +#include "fcmsg.h" +#include "fc_crtn.h" +#include "fc_ertn.h" + +extern fc_dd_ctl_t DD_CTL; +extern iCfgParam icfgparam[]; +extern int fc_max_els_sent; + +/* Routine Declaration - Local */ +_local_ int fc_addrauth(fc_dev_ctl_t *p_dev_ctl); +_local_ void fc_clear_fcp_iocbq(fc_dev_ctl_t *p_dev_ctl, NODELIST *nlp); +_local_ void fc_clear_ip_iocbq(fc_dev_ctl_t *p_dev_ctl, NODELIST *nlp); +_local_ int fc_matchdid(FC_BRD_INFO *binfo, NODELIST *nlp, uint32 did); +/* End Routine Declaration - Local */ + +/* + * Array of all 126 valid AL_PA's (excluding FL_PORT AL_PA 0) + */ + +static uchar staticAlpaArray[] = +{ + 0x01, 0x02, 0x04, 0x08, 0x0F, 0x10, 0x17, 0x18, 0x1B, 0x1D, + 0x1E, 0x1F, 0x23, 0x25, 0x26, 0x27, 0x29, 0x2A, 0x2B, 0x2C, + 0x2D, 0x2E, 0x31, 0x32, 0x33, 0x34, 0x35, 0x36, 0x39, 0x3A, + 0x3C, 0x43, 0x45, 0x46, 0x47, 0x49, 0x4A, 0x4B, 0x4C, 0x4D, + 0x4E, 0x51, 0x52, 0x53, 0x54, 0x55, 0x56, 0x59, 0x5A, 0x5C, + 0x63, 0x65, 0x66, 0x67, 0x69, 0x6A, 0x6B, 0x6C, 0x6D, 0x6E, + 0x71, 0x72, 0x73, 0x74, 0x75, 0x76, 0x79, 0x7A, 0x7C, 0x80, + 0x81, 0x82, 0x84, 0x88, 0x8F, 0x90, 0x97, 0x98, 0x9B, 0x9D, + 0x9E, 0x9F, 0xA3, 0xA5, 0xA6, 0xA7, 0xA9, 0xAA, 0xAB, 0xAC, + 0xAD, 0xAE, 0xB1, 0xB2, 0xB3, 0xB4, 0xB5, 0xB6, 0xB9, 0xBA, + 0xBC, 0xC3, 0xC5, 0xC6, 0xC7, 0xC9, 0xCA, 0xCB, 0xCC, 0xCD, + 0xCE, 0xD1, 0xD2, 0xD3, 0xD4, 0xD5, 0xD6, 0xD9, 0xDA, 0xDC, + 0xE0, 0xE1, 0xE2, 0xE4, 0xE8, 0xEF +}; + +int fc_fdmi_on = 0; + +_local_ int +fc_matchdid( +FC_BRD_INFO *binfo, +NODELIST *ndlp, +uint32 did) +{ + D_ID mydid; + D_ID odid; + D_ID ndid; + int zero_did; + + if (did == Bcast_DID) + return(0); + + zero_did = 0; + if (ndlp->nlp_DID == 0) { + ndlp->nlp_DID = ndlp->nlp_oldDID; + zero_did = 1; + } + + /* First check for Direct match */ + if (ndlp->nlp_DID == did) + return(1); + + /* Next check for area/domain == 0 match */ + mydid.un.word = binfo->fc_myDID; + if ((mydid.un.b.domain == 0) && (mydid.un.b.area == 0)) { + goto out; + } + + ndid.un.word = did; + odid.un.word = ndlp->nlp_DID; + if (ndid.un.b.id == odid.un.b.id) { + if ((mydid.un.b.domain == ndid.un.b.domain) && + (mydid.un.b.area == ndid.un.b.area)) { + ndid.un.word = ndlp->nlp_DID; + odid.un.word = did; + if ((ndid.un.b.domain == 0) && + (ndid.un.b.area == 0)) { + if (ndid.un.b.id) + return(1); + } + goto out; + } + + ndid.un.word = ndlp->nlp_DID; + if ((mydid.un.b.domain == ndid.un.b.domain) && + (mydid.un.b.area == ndid.un.b.area)) { + odid.un.word = ndlp->nlp_DID; + ndid.un.word = did; + if ((ndid.un.b.domain == 0) && + (ndid.un.b.area == 0)) { + if (ndid.un.b.id) + return(1); + } + } + } +out: + if(zero_did) + ndlp->nlp_DID = 0; + return(0); +} /* End fc_matchdid */ + + +/**************************************************/ +/** fc_nlpadjust **/ +/** **/ +/** This routine adjusts the timestamp in the **/ +/** nlplist when the counter wraps **/ +/**************************************************/ +_static_ int +fc_nlpadjust( +FC_BRD_INFO *binfo) +{ + NODELIST * ndlp; + NODELIST * nlphi, *nlpprev; + uint32 rpts; + + nlphi = 0; + nlpprev = 0; + rpts = 0; + ndlp = binfo->fc_nlpbind_start; + if(ndlp == (NODELIST *)&binfo->fc_nlpbind_start) + ndlp = binfo->fc_nlpunmap_start; + if(ndlp == (NODELIST *)&binfo->fc_nlpunmap_start) + ndlp = binfo->fc_nlpmap_start; + while(ndlp != (NODELIST *)&binfo->fc_nlpmap_start) { + if (ndlp->nlp_time > rpts) { + rpts = ndlp->nlp_time; + nlpprev = nlphi; + nlphi = ndlp; + } + + switch (ndlp->nlp_state) { + case NLP_LIMBO: + case NLP_LOGOUT: + ndlp->nlp_time = 1; + break; + + case NLP_ALLOC: + ndlp->nlp_time = 3; + break; + + default: + ndlp->nlp_time = 2; + break; + } + ndlp = (NODELIST *)ndlp->nlp_listp_next; + if(ndlp == (NODELIST *)&binfo->fc_nlpbind_start) + ndlp = binfo->fc_nlpunmap_start; + if(ndlp == (NODELIST *)&binfo->fc_nlpunmap_start) + ndlp = binfo->fc_nlpmap_start; + } + + if (nlpprev) + nlpprev->nlp_time = 4; + if (nlphi) + nlphi->nlp_time = 5; + binfo->nlptimer = 6; + return(0); +} /* End fc_nlpadjust */ + + +/**************************************************/ +/** fc_findnode_rpi **/ +/** **/ +/** This routine find a node by rpi **/ +/**************************************************/ +_static_ NODELIST * +fc_findnode_rpi( +FC_BRD_INFO *binfo, +uint32 rpi) +{ + NODELIST * ndlp = 0; + + if (rpi < NLP_MAXRPI) + ndlp = binfo->fc_nlplookup[rpi]; + /* FIND node rpi */ + fc_log_printf_msg_vargs( binfo->fc_brd_no, + &fc_msgBlk0900, /* ptr to msg structure */ + fc_mes0900, /* ptr to msg */ + fc_msgBlk0900.msgPreambleStr, /* begin varargs */ + (ulong)ndlp, + rpi); /* end varargs */ + return(ndlp); +} /* End fc_findnode_rpi */ + + +/**************************************************/ +/** fc_freenode_did **/ +/** **/ +/** This routine will free an NODELIST entry **/ +/** associated with did. **/ +/**************************************************/ +_static_ int +fc_freenode_did( +FC_BRD_INFO *binfo, +uint32 did, +int rm) +{ + NODELIST * ndlp; + + + if(((ndlp = fc_findnode_odid(binfo, NLP_SEARCH_ALL, did)) == 0) || + (ndlp->nlp_state == NLP_SEED)) { + /* no match found */ + return(0); + } + + fc_freenode(binfo, ndlp, rm); + if(rm == 0) { + ndlp->nlp_state = NLP_LIMBO; + fc_nlp_bind(binfo, ndlp); + } + return(1); +} /* End fc_freenode_did */ + + +/**************************************************/ +/** fc_free_rpilist **/ +/** **/ +/** This routine will free all NODELIST entries **/ +/** and associated buffers. **/ +/**************************************************/ +_static_ int +fc_free_rpilist( +fc_dev_ctl_t *p_dev_ctl, +int keeprpi) +{ + FC_BRD_INFO * binfo; + NODELIST * ndlp; + NODELIST * new_ndlp; + RING * rp; + IOCBQ * xmitiq; + iCfgParam * clp; + struct buf * bp; + T_SCSIBUF * sbp; + dvi_t * dev_ptr; + fc_buf_t * fcptr; + node_t * node_ptr; + + binfo = &BINFO; + clp = DD_CTL.p_config[binfo->fc_brd_no]; + + /* if keeprpi == 0, toss everything on ELS xmitq and xmit pending queue */ + if (keeprpi == 0) { + rp = &binfo->fc_ring[FC_ELS_RING]; + /* get next command from ring xmit queue */ + while ((xmitiq = fc_ringtx_drain(rp)) != 0) { + fc_freebufq(p_dev_ctl, rp, xmitiq); + } + + /* look up xmit next compl */ + while ((xmitiq = fc_ringtxp_get(rp, 0)) != 0) { + fc_freebufq(p_dev_ctl, rp, xmitiq); + } + } + + /* Toss everything on LAN xmitq and xmit pending queue */ + rp = &binfo->fc_ring[FC_IP_RING]; + /* get next command from ring xmit queue */ + while ((xmitiq = fc_ringtx_drain(rp)) != 0) { + fc_freebufq(p_dev_ctl, rp, xmitiq); + } + + /* look up xmit next compl */ + while ((xmitiq = fc_ringtxp_get(rp, 0)) != 0) { + fc_freebufq(p_dev_ctl, rp, xmitiq); + } + + NDDSTAT.ndd_xmitque_cur = 0; + + if(clp[CFG_FCP_ON].a_current) { + int i; + + rp = &binfo->fc_ring[FC_FCP_RING]; + + for(i=0;ifc_table->fcp_array[i]) && + (fcptr = fc_deq_fcbuf_active(rp, (ushort)i))) { + dev_ptr = fcptr->dev_ptr; + + if(dev_ptr->queue_state == ACTIVE_PASSTHRU) { + node_t * map_node_ptr; + struct dev_info * map_dev_ptr; + + map_node_ptr = (node_t *)dev_ptr->pend_head; + map_dev_ptr = (struct dev_info *)dev_ptr->pend_tail; + dev_ptr->pend_head = 0; + dev_ptr->pend_tail = 0; + dev_ptr->queue_state = HALTED; + dev_ptr->active_io_count--; + if(map_dev_ptr) + map_dev_ptr->active_io_count--; + if(map_node_ptr) + map_node_ptr->num_active_io--; + + dev_ptr->ioctl_event = IOSTAT_LOCAL_REJECT; + + dev_ptr->ioctl_errno = IOERR_SEQUENCE_TIMEOUT; + dev_ptr->sense_length = 0; + dev_ptr->clear_count = 0; + continue; + } /* end ACTIVE_PASSTHRU management */ + + sbp = fcptr->sc_bufp; + bp = (struct buf *) sbp; + + + /* E_D_TOV timeout */ + bp->b_error = ETIMEDOUT; + + sbp->adap_q_status = SC_DID_NOT_CLEAR_Q; + bp->b_flags |= B_ERROR; + bp->b_resid = bp->b_bcount; + sbp->status_validity = SC_ADAPTER_ERROR; + SET_ADAPTER_STATUS(sbp, SC_CMD_TIMEOUT) + + if (fcptr->fcp_cmd.fcpCntl2) { + /* This is a task management command */ + if (bp->b_flags & B_ERROR) + dev_ptr->ioctl_errno = bp->b_error; + else + dev_ptr->ioctl_errno = 0; + + if (fcptr->fcp_cmd.fcpCntl2 == ABORT_TASK_SET) + dev_ptr->flags &= ~SCSI_ABORT_TSET; + + if (fcptr->fcp_cmd.fcpCntl2 & TARGET_RESET) + dev_ptr->flags &= ~SCSI_TARGET_RESET; + + if (fcptr->fcp_cmd.fcpCntl2 & LUN_RESET) + dev_ptr->flags &= ~SCSI_LUN_RESET; + + if (dev_ptr->ioctl_wakeup == 1) { + dev_ptr->ioctl_wakeup = 0; + + fc_admin_wakeup(p_dev_ctl, dev_ptr, sbp); + } else { + fc_do_iodone(bp); + } + } else { + fc_do_iodone(bp); + } + dev_ptr->active_io_count--; + dev_ptr->nodep->num_active_io--; + fc_enq_fcbuf(fcptr); + } + } + + fc_failio(p_dev_ctl); + + ndlp = binfo->fc_nlpmap_start; + while(ndlp != (NODELIST *)&binfo->fc_nlpmap_start) { + fc_freenode(binfo, ndlp, 0); + ndlp->nlp_state = NLP_LIMBO; + fc_nlp_bind(binfo, ndlp); + + /* Make sure pendq is empty */ + i = INDEX(ndlp->id.nlp_pan, ndlp->id.nlp_sid); + if ((node_ptr = binfo->device_queue_hash[i].node_ptr) != NULL) { + for (dev_ptr = node_ptr->lunlist; dev_ptr != NULL; + dev_ptr = dev_ptr->next) { + while ((sbp = dev_ptr->pend_head) != NULL) { + dev_ptr->pend_count--; + dev_ptr->pend_head = (T_SCSIBUF *) sbp->bufstruct.av_forw; + if (dev_ptr->pend_head == NULL) + dev_ptr->pend_tail = NULL; + else + dev_ptr->pend_head->bufstruct.av_back = NULL; + + sbp->bufstruct.b_flags |= B_ERROR; + sbp->bufstruct.b_error = EIO; + sbp->bufstruct.b_resid = sbp->bufstruct.b_bcount; + sbp->status_validity = SC_ADAPTER_ERROR; + SET_ADAPTER_STATUS(sbp, SC_NO_DEVICE_RESPONSE) + + sbp->bufstruct.av_forw = 0; + fc_do_iodone((struct buf *) sbp); + } + } + } + ndlp = binfo->fc_nlpmap_start; + } + } + + /* Put all Mapped and unmapped nodes on the bind list */ + ndlp = binfo->fc_nlpunmap_start; + if(ndlp == (NODELIST *)&binfo->fc_nlpunmap_start) + ndlp = binfo->fc_nlpmap_start; + while(ndlp != (NODELIST *)&binfo->fc_nlpmap_start) { + new_ndlp = (NODELIST *)ndlp->nlp_listp_next; + + fc_freenode(binfo, ndlp, 0); + ndlp->nlp_state = NLP_LIMBO; + fc_nlp_bind(binfo, ndlp); + + ndlp = new_ndlp; + if(ndlp == (NODELIST *)&binfo->fc_nlpunmap_start) + ndlp = binfo->fc_nlpmap_start; + } + + /* Put adapter into an error state and return all outstanding I/Os */ + fc_linkdown(p_dev_ctl); + + return(0); +} /* End fc_free_rpilist */ + + +/* + * Issue an ABORT_XRI_CX iocb command to abort an exchange + */ +_static_ int +fc_rpi_abortxri( +FC_BRD_INFO *binfo, +ushort xri) +{ + IOCB * icmd; + IOCBQ * temp; + RING * rp; + + /* Use IP ring so ABTS comes out after CLEAR_LA */ + rp = &binfo->fc_ring[FC_IP_RING]; + + /* Get an iocb buffer */ + if ((temp = (IOCBQ * )fc_mem_get(binfo, MEM_IOCB)) == 0) { + return(1); + } + fc_bzero((void *)temp, sizeof(IOCBQ)); + icmd = &temp->iocb; + + icmd->un.acxri.abortType = ABORT_TYPE_ABTS; + icmd->ulpContext = xri; + + /* set up an iotag */ + icmd->ulpIoTag = rp->fc_iotag++; + if (rp->fc_iotag == 0) { + rp->fc_iotag = 1; + } + + icmd->ulpLe = 1; + icmd->ulpClass = CLASS3; + icmd->ulpCommand = CMD_ABORT_XRI_CX; + icmd->ulpOwner = OWN_CHIP; + + issue_iocb_cmd(binfo, rp, temp); + + return(0); +} /* End fc_rpi_abortxri */ + + +/**************************************************/ +/** fc_freenode **/ +/** **/ +/** This routine will remove NODELIST entries **/ +/** rm determines state to leave entry at, **/ +/** either NLP_UNUSED or NLP_LOGOUT **/ +/**************************************************/ +_static_ int +fc_freenode( +FC_BRD_INFO *binfo, +NODELIST *nlp, +int rm) +{ + MAILBOXQ * mbox; + node_t * node_ptr; + uint32 data1; + + data1 = ( ((uint32)nlp->nlp_state << 24) | + ((uint32)nlp->nlp_action << 16) | + ((uint32)nlp->nlp_type << 8) | + rm ); + + /* Free node tbl */ + fc_log_printf_msg_vargs( binfo->fc_brd_no, + &fc_msgBlk0901, /* ptr to msg structure */ + fc_mes0901, /* ptr to msg */ + fc_msgBlk0901.msgPreambleStr, /* begin varargs */ + nlp->nlp_DID, + nlp->nlp_flag, + nlp->nlp_Rpi, + data1); /* end varargs */ + /* FREE node IEEE */ + fc_log_printf_msg_vargs( binfo->fc_brd_no, + &fc_msgBlk0902, /* ptr to msg structure */ + fc_mes0902, /* ptr to msg */ + fc_msgBlk0902.msgPreambleStr, /* begin varargs */ + nlp->nlp_nodename.IEEE[2], + nlp->nlp_nodename.IEEE[3], + nlp->nlp_nodename.IEEE[4], + nlp->nlp_nodename.IEEE[5]); /* end varargs */ + + + if(nlp == &binfo->fc_fcpnodev) + return(1); + + if(nlp->nlp_listp_next) { + if (nlp->nlp_flag & NLP_MAPPED) { + nlp->nlp_time = binfo->nlptimer++; + if (nlp->nlp_time == 0) { + fc_nlpadjust(binfo); + } + nlp->nlp_flag &= ~NLP_MAPPED; + binfo->fc_map_cnt--; + fc_deque(nlp); + } + else if (nlp->nlp_flag & NLP_UNMAPPED) { + nlp->nlp_time = binfo->nlptimer++; + if (nlp->nlp_time == 0) { + fc_nlpadjust(binfo); + } + nlp->nlp_flag &= ~NLP_UNMAPPED; + binfo->fc_unmap_cnt--; + fc_deque(nlp); + } + else if (nlp->nlp_flag & NLP_BIND) { + nlp->nlp_flag &= ~NLP_BIND; + binfo->fc_bind_cnt--; + fc_deque(nlp); + } + } + + /* Unregister login with firmware for this node */ + if (nlp->nlp_Rpi) { + /* Unregister login */ + if ((mbox = (MAILBOXQ * )fc_mem_get(binfo, MEM_MBOX | MEM_PRI))) { + fc_unreg_login(binfo, nlp->nlp_Rpi, (MAILBOX * )mbox); + if (nlp->nlp_flag & NLP_UNREG_LOGO) { + ((MAILBOX *)mbox)->un.varWords[30] = nlp->nlp_DID; + } + if (issue_mb_cmd(binfo, (MAILBOX * )mbox, MBX_NOWAIT) != MBX_BUSY) { + fc_mem_put(binfo, MEM_MBOX, (uchar * )mbox); + } + } + binfo->fc_nlplookup[nlp->nlp_Rpi] = 0; + nlp->nlp_Rpi = 0; + } + + if (nlp->nlp_DID) { + RING * rp; + IOCBQ * iocbq; + unsigned long iflag; + fc_dev_ctl_t *p_dev_ctl; + + /* Look through ELS ring and remove any ELS cmds in progress */ + p_dev_ctl = (fc_dev_ctl_t *)binfo->fc_p_dev_ctl; + iflag = lpfc_q_disable_lock(p_dev_ctl); + rp = &binfo->fc_ring[FC_ELS_RING]; + iocbq = (IOCBQ * )(rp->fc_txp.q_first); + while (iocbq) { + if (iocbq->iocb.un.elsreq.remoteID == nlp->nlp_DID) { + iocbq->retry = 0xff; /* Mark for abort */ + if((binfo->fc_flag & FC_RSCN_MODE) || + (binfo->fc_ffstate < FC_READY)) { + if((nlp->nlp_state >= NLP_PLOGI) && + (nlp->nlp_state <= NLP_PRLI)) { + nlp->nlp_action &= ~NLP_DO_RSCN; + binfo->fc_nlp_cnt--; + if ((nlp->nlp_type & NLP_IP_NODE) && nlp->nlp_bp) { + m_freem((fcipbuf_t *)nlp->nlp_bp); + nlp->nlp_bp = (uchar * )0; + } + } + } + } + iocbq = (IOCBQ * )iocbq->q; + } + lpfc_q_unlock_enable(p_dev_ctl, iflag); + /* In case its on fc_delay_timeout list */ + fc_abort_delay_els_cmd((fc_dev_ctl_t *)binfo->fc_p_dev_ctl, nlp->nlp_DID); + + nlp->nlp_oldDID = nlp->nlp_DID; /* save the old DID */ + } + + if (nlp->nlp_flag & (NLP_REQ_SND | NLP_REQ_SND_ADISC)) { + nlp->nlp_flag &= ~(NLP_REQ_SND | NLP_REQ_SND_ADISC); + /* Goto next entry */ + fc_nextnode((fc_dev_ctl_t * )(binfo->fc_p_dev_ctl), nlp); + } + + + if (nlp->nlp_type & NLP_IP_NODE) { + if (nlp->nlp_bp) { + m_freem((fcipbuf_t * )nlp->nlp_bp); + nlp->nlp_bp = 0; + } + + /* Go remove all entries for this node from the IP IOCBQ */ + fc_clear_ip_iocbq((fc_dev_ctl_t * )(binfo->fc_p_dev_ctl), nlp); + } + + if (nlp->nlp_type & NLP_FCP_TARGET) { + iCfgParam * clp; + + clp = DD_CTL.p_config[binfo->fc_brd_no]; + + /* Go remove all entries for this RPI from the FCP IOCBQ */ + fc_clear_fcp_iocbq((fc_dev_ctl_t *)binfo->fc_p_dev_ctl, nlp); + + if ((node_ptr = (node_t * )(nlp->nlp_targetp)) != NULL) { + dvi_t * dev_ptr; + + node_ptr->rpi = 0xfffe; + node_ptr->flags &= ~FC_FCP2_RECOVERY; + for (dev_ptr = node_ptr->lunlist; dev_ptr != NULL; + dev_ptr = dev_ptr->next) { + if(binfo->fc_ffstate == FC_READY){ + /* + * Cause the standby queue to drain. + */ + fc_return_standby_queue(dev_ptr, + (uchar)((binfo->fc_flag & FC_BUS_RESET) ? EIO : EFAULT), 0); + + fc_fail_pendq(dev_ptr, + (uchar)((binfo->fc_flag & FC_BUS_RESET) ? EIO : EFAULT), 0); + /* UNREG_LOGIN from freenode should abort txp I/Os */ + fc_fail_cmd(dev_ptr, (char)((binfo->fc_flag & FC_BUS_RESET) ? + EIO : EFAULT), 0); + + /* Call iodone for all the CLEARQ error bufs */ + fc_free_clearq(dev_ptr); + } + dev_ptr->queue_state = HALTED; + } + } + + /* Is this node, automapped or seeded */ + if(nlp->nlp_type & (NLP_AUTOMAP | NLP_SEED_MASK)) { + /* If FCP we need to keep entry around for the wwpn - sid mapping */ + nlp->nlp_type = (NLP_FCP_TARGET | + (nlp->nlp_type & (NLP_AUTOMAP | NLP_SEED_MASK))); + if(nlp->nlp_type & NLP_SEED_DID) { + fc_bzero((void *)&nlp->nlp_portname, sizeof(NAME_TYPE)); + fc_bzero((void *)&nlp->nlp_nodename, sizeof(NAME_TYPE)); + } + else { + nlp->nlp_DID = 0; + } + } + else { + nlp->nlp_flag = 0; + nlp->nlp_action = 0; + nlp->nlp_type = 0; + nlp->nlp_targetp = 0; + nlp->id.nlp_pan = 0; + nlp->id.nlp_sid = 0; + } + + if(node_ptr && (clp[CFG_NODEV_TMO].a_current) && + ((node_ptr->flags & FC_NODEV_TMO) == 0)) { + if(node_ptr->nodev_tmr == 0) { + /* START nodev timer */ + fc_log_printf_msg_vargs( binfo->fc_brd_no, + &fc_msgBlk0700, /* ptr to msg structure */ + fc_mes0700, /* ptr to msg */ + fc_msgBlk0700.msgPreambleStr, /* begin varargs */ + (ulong)nlp, + nlp->nlp_flag, + nlp->nlp_state, + nlp->nlp_DID); /* end varargs */ + + if(binfo->fc_ffstate != FC_LINK_DOWN) { + node_ptr->nodev_tmr = + fc_clk_set((fc_dev_ctl_t * )(binfo->fc_p_dev_ctl), + clp[CFG_NODEV_TMO].a_current, fc_nodev_timeout, + (void *)node_ptr, 0); + } + else { + node_ptr->nodev_tmr = + fc_clk_set((fc_dev_ctl_t * )(binfo->fc_p_dev_ctl), + (clp[CFG_NODEV_TMO].a_current + clp[CFG_LINKDOWN_TMO].a_current), + fc_nodev_timeout, (void *)node_ptr, 0); + } + } + } + } + else { + nlp->nlp_targetp = 0; + nlp->id.nlp_pan = 0; + nlp->id.nlp_sid = 0; + nlp->nlp_type = 0; + } + + nlp->nlp_Xri = 0; + nlp->nlp_action = 0; + + if (rm) { + fc_bzero((void *)nlp, sizeof(NODELIST)); + fc_mem_put(binfo, MEM_NLP, (uchar *)nlp); + } else { + if(nlp->nlp_flag & NLP_NS_REMOVED) + nlp->nlp_flag = NLP_NS_REMOVED; + else + nlp->nlp_flag = 0; + + /* Keep the entry cached */ + nlp->nlp_state = NLP_LIMBO; + /* Let the caller put it on the appropriate q at the appropriate time */ + } + return(1); +} /* End fc_freenode */ + + +/************************************************************************/ +/* */ +/* NAME: fc_clear_fcp_iocbq */ +/* */ +/* FUNCTION: Fail All FCP Commands in IOCBQ for one RPI */ +/* */ +/* This routine is called to clear out all FCP commands */ +/* in the IOCBQ for a specific SCSI FCP device RPI. */ +/* */ +/* EXECUTION ENVIRONMENT: */ +/* This routine can only be called on priority levels */ +/* equal to that of the interrupt handler. */ +/* */ +/* DATA STRUCTURES: */ +/* sc_buf - input/output request struct used between the adapter */ +/* driver and the calling SCSI device driver */ +/* */ +/* INPUTS: */ +/* NODELIST structure - pointer to device node structure */ +/* */ +/* RETURN VALUE DESCRIPTION: */ +/* none */ +/* */ +/************************************************************************/ +_local_ void +fc_clear_fcp_iocbq( +fc_dev_ctl_t *p_dev_ctl, +NODELIST *ndlp) +{ + FC_BRD_INFO * binfo; + T_SCSIBUF * sbp; + RING * rp; + IOCBQ * iocb_cmd, *next; + IOCB * icmd; + dvi_t * dev_ptr; + fc_buf_t * fcptr; + struct buf * bp; + Q tmpq; + + binfo = &BINFO; + + /* Clear out all fc_buf structures in the iocb queue for this RPI */ + rp = &binfo->fc_ring[FC_FCP_RING]; + tmpq.q_first = NULL; + + /* Get next command from ring xmit queue */ + iocb_cmd = fc_ringtx_get(rp); + + while (iocb_cmd) { + icmd = &iocb_cmd->iocb; + if ((icmd->ulpCommand != CMD_IOCB_CONTINUE_CN) && + (icmd->ulpContext == ndlp->nlp_Rpi)) { + + if ((fcptr = fc_deq_fcbuf_active(rp, icmd->ulpIoTag)) != NULL) { + dev_ptr = fcptr->dev_ptr; + /* Reject this command with error */ + if(dev_ptr && (dev_ptr->queue_state == ACTIVE_PASSTHRU)) { + node_t * map_node_ptr; + struct dev_info * map_dev_ptr; + + map_node_ptr = (node_t *)dev_ptr->pend_head; + map_dev_ptr = (struct dev_info *)dev_ptr->pend_tail; + dev_ptr->pend_head = 0; + dev_ptr->pend_tail = 0; + dev_ptr->queue_state = HALTED; + dev_ptr->active_io_count--; + if(map_dev_ptr) + map_dev_ptr->active_io_count--; + if(map_node_ptr) + map_node_ptr->num_active_io--; + + dev_ptr->ioctl_event = IOSTAT_LOCAL_REJECT; + + dev_ptr->ioctl_errno = IOERR_SEQUENCE_TIMEOUT; + dev_ptr->sense_length = 0; + dev_ptr->clear_count = 0; + while ((iocb_cmd = fc_ringtx_get(rp)) != NULL) { + icmd = &iocb_cmd->iocb; + if (icmd->ulpCommand != CMD_IOCB_CONTINUE_CN) + break; + fc_mem_put(binfo, MEM_IOCB, (uchar * )iocb_cmd); + } + continue; + } /* end ACTIVE_PASSTHRU management */ + + if (fcptr->fcp_cmd.fcpCntl2) { + + bp = (struct buf *)fcptr->sc_bufp; + + if(dev_ptr) { + /* This is a task management command */ + dev_ptr->ioctl_errno = ENXIO; + dev_ptr->active_io_count--; + dev_ptr->nodep->num_active_io--; + + if (fcptr->fcp_cmd.fcpCntl2 == ABORT_TASK_SET) + dev_ptr->flags &= ~SCSI_ABORT_TSET; + + if (fcptr->fcp_cmd.fcpCntl2 & TARGET_RESET) + dev_ptr->flags &= ~SCSI_TARGET_RESET; + + if (fcptr->fcp_cmd.fcpCntl2 & LUN_RESET) + dev_ptr->flags &= ~SCSI_LUN_RESET; + + if (fcptr->dev_ptr->ioctl_wakeup) { + fcptr->dev_ptr->ioctl_wakeup = 0; + fc_admin_wakeup(((fc_dev_ctl_t *)(binfo->fc_p_dev_ctl)), + fcptr->dev_ptr, fcptr->sc_bufp); + } + } + } else { + /* This is a regular FCP command */ + + bp = (struct buf *)fcptr->sc_bufp; + bp->b_error = ENXIO; + bp->b_resid = bp->b_bcount; + bp->b_flags |= B_ERROR; + + sbp = (T_SCSIBUF *)bp; + sbp->status_validity = SC_ADAPTER_ERROR; + SET_ADAPTER_STATUS(sbp, SC_NO_DEVICE_RESPONSE) + + dev_ptr = fcptr->dev_ptr; + if(dev_ptr) { + dev_ptr->active_io_count--; + dev_ptr->nodep->num_active_io--; + } + + fc_delay_iodone(p_dev_ctl, sbp); + } + fc_enq_fcbuf(fcptr); + } + + fc_mem_put(binfo, MEM_IOCB, (uchar * )iocb_cmd); + + while ((iocb_cmd = fc_ringtx_get(rp)) != NULL) { + icmd = &iocb_cmd->iocb; + if (icmd->ulpCommand != CMD_IOCB_CONTINUE_CN) + break; + fc_mem_put(binfo, MEM_IOCB, (uchar * )iocb_cmd); + } + } else { + /* Queue this iocb to the temporary queue */ + if (tmpq.q_first) { + ((IOCBQ * )tmpq.q_last)->q = (uchar * )iocb_cmd; + tmpq.q_last = (uchar * )iocb_cmd; + } else { + tmpq.q_first = (uchar * )iocb_cmd; + tmpq.q_last = (uchar * )iocb_cmd; + } + iocb_cmd->q = NULL; + + iocb_cmd = fc_ringtx_get(rp); + } + } + + /* Put the temporary queue back in the FCP iocb queue */ + iocb_cmd = (IOCBQ * )tmpq.q_first; + while (iocb_cmd) { + next = (IOCBQ * )iocb_cmd->q; + fc_ringtx_put(rp, iocb_cmd); + iocb_cmd = next; + } + + return; +} /* End fc_clear_fcp_iocbq */ + + +/************************************************************************/ +/* */ +/* NAME: fc_clear_ip_iocbq */ +/* */ +/* FUNCTION: Fail All IP Commands in IOCBQ for one RPI */ +/* */ +/* This routine is called to clear out all IP commands */ +/* in the IOCBQ for a specific IP device RPI. */ +/* */ +/* EXECUTION ENVIRONMENT: */ +/* This routine can only be called on priority levels */ +/* equal to that of the interrupt handler. */ +/* */ +/* INPUTS: */ +/* NODELIST structure - pointer to device node structure */ +/* */ +/* RETURN VALUE DESCRIPTION: */ +/* none */ +/* */ +/************************************************************************/ +_local_ void +fc_clear_ip_iocbq( +fc_dev_ctl_t *p_dev_ctl, +NODELIST *ndlp) +{ + FC_BRD_INFO * binfo; + RING * rp; + IOCBQ * xmitiq, *next; + IOCB * icmd; + Q tmpq; + fcipbuf_t * p_mbuf; + fcipbuf_t * m_net; + int i; + ULP_BDE64 * bpl; + MATCHMAP * bmp; + + binfo = &BINFO; + /* Clear out all commands in the iocb queue for this RPI */ + rp = &binfo->fc_ring[FC_IP_RING]; + tmpq.q_first = NULL; + + /* Get next command from ring xmit queue */ + xmitiq = fc_ringtx_drain(rp); + + while (xmitiq) { + icmd = &xmitiq->iocb; + if (((icmd->ulpCommand == CMD_XMIT_SEQUENCE_CX) || + (icmd->ulpCommand == CMD_XMIT_SEQUENCE64_CX) || + (icmd->ulpCommand == 0)) && + (ndlp == (NODELIST * )xmitiq->info)) { + + /* get mbuf ptr for xmit */ + m_net = (fcipbuf_t * )xmitiq->bp; + if (ndlp->nlp_DID == NameServer_DID) { + if (binfo->fc_flag & FC_SLI2) { + fc_mem_put(binfo, MEM_BPL, (uchar * )xmitiq->bpl); + } + fc_mem_put(binfo, MEM_IOCB, (uchar * )xmitiq); + fc_mem_put(binfo, MEM_BUF, (uchar * )m_net); + goto out; + } + + /* Loop thru BDEs and unmap memory pages associated with mbuf */ + if (binfo->fc_flag & FC_SLI2) { + bmp = (MATCHMAP * )xmitiq->bpl; + bpl = (ULP_BDE64 * )bmp->virt; + while (bpl && xmitiq->iocb.un.xseq64.bdl.bdeSize) { + fc_bufunmap(p_dev_ctl, (uchar *)getPaddr(bpl->addrHigh, bpl->addrLow), 0, bpl->tus.f.bdeSize); + bpl++; + xmitiq->iocb.un.xseq64.bdl.bdeSize -= sizeof(ULP_BDE64); + } + fc_mem_put(binfo, MEM_BPL, (uchar * )bmp); + fc_mem_put(binfo, MEM_IOCB, (uchar * )xmitiq); + } else { + for (i = 0; i < (int)xmitiq->iocb.ulpBdeCount; i++) { + fc_bufunmap(p_dev_ctl, (uchar *)((ulong)xmitiq->iocb.un.cont[i].bdeAddress), 0, (uint32)xmitiq->iocb.un.cont[i].bdeSize); + } + fc_mem_put(binfo, MEM_IOCB, (uchar * )xmitiq); + } + + /* Take care of Continuation IOCBs for this mbuf */ + while ((xmitiq = fc_ringtx_drain(rp)) != NULL) { + icmd = &xmitiq->iocb; + if ((icmd->ulpCommand != CMD_IOCB_CONTINUE_CN) && + (icmd->ulpCommand != CMD_IOCB_CONTINUE64_CN)) + break; + /* Loop thru BDEs and unmap memory pages associated with IOCB */ + for (i = 0; i < (int)xmitiq->iocb.ulpBdeCount; i++) { + if (binfo->fc_flag & FC_SLI2) + fc_bufunmap(p_dev_ctl, (uchar *)getPaddr(xmitiq->iocb.un.cont64[i].addrHigh, xmitiq->iocb.un.cont64[i].addrLow), 0, xmitiq->iocb.un.cont64[i].tus.f.bdeSize); + else + fc_bufunmap(p_dev_ctl, (uchar *) ((ulong)xmitiq->iocb.un.cont[i].bdeAddress), 0, (uint32)xmitiq->iocb.un.cont[i].bdeSize); + } + fc_mem_put(binfo, MEM_IOCB, (uchar * )xmitiq); + } + + p_mbuf = fcnextdata(m_net); + fcnextdata(m_net) = 0; + fcfreehandle(p_dev_ctl, m_net); + m_freem(m_net); + + if (p_mbuf) { + /* free mbuf */ + fcfreehandle(p_dev_ctl, p_mbuf); + m_freem(p_mbuf); + } + + } else { + /* Queue this iocb to the temporary queue */ + if (tmpq.q_first) { + ((IOCBQ * )tmpq.q_last)->q = (uchar * )xmitiq; + tmpq.q_last = (uchar * )xmitiq; + } else { + tmpq.q_first = (uchar * )xmitiq; + tmpq.q_last = (uchar * )xmitiq; + } + xmitiq->q = NULL; + + xmitiq = fc_ringtx_drain(rp); + } + } + +out: + /* Put the temporary queue back in the IP iocb queue */ + xmitiq = (IOCBQ * )tmpq.q_first; + while (xmitiq) { + next = (IOCBQ * )xmitiq->q; + fc_ringtx_put(rp, xmitiq); + xmitiq = next; + } + + return; +} /* End fc_clear_ip_iocbq */ + + +/**************************************************/ +/** fc_fanovery **/ +/** **/ +/** This routine will recover after a FAN rcvd **/ +/**************************************************/ +_static_ int +fc_fanovery( +fc_dev_ctl_t *p_dev_ctl) +{ + FC_BRD_INFO * binfo; + iCfgParam * clp; + NODELIST * ndlp; + NODELIST * firstndlp; + MAILBOXQ * mb; + int j, addrauth; + D_ID did; + + binfo = &BINFO; + clp = DD_CTL.p_config[binfo->fc_brd_no]; + /* Device Discovery Started */ + fc_log_printf_msg_vargs( binfo->fc_brd_no, + &fc_msgBlk0200, /* ptr to msg structure */ + fc_mes0200, /* ptr to msg */ + fc_msgBlk0200.msgPreambleStr); /* begin & end varargs */ + binfo->fc_ffstate = FC_LOOP_DISC; + binfo->fc_nlp_cnt = 0; + binfo->fc_flag &= ~(FC_NLP_MORE | FC_DELAY_PLOGI); + + firstndlp = 0; + addrauth = 0; + /* Next, lets seed the nodeList with our ALPAmap */ + if (binfo->fc_topology == TOPOLOGY_LOOP) { + if (binfo->alpa_map[0]) { + for (j = 1; j <= binfo->alpa_map[0]; j++) { + if (((binfo->fc_myDID & 0xff) == binfo->alpa_map[j]) || + (binfo->alpa_map[j] == 0)) + continue; + /* Skip if the node is already in the node table */ + if ((ndlp = fc_findnode_odid(binfo, NLP_SEARCH_ALL, binfo->alpa_map[j]))) { + ndlp->nlp_DID = binfo->alpa_map[j]; + /* Mark slot for address authentication */ + ndlp->nlp_action |= NLP_DO_ADDR_AUTH; + addrauth++; + continue; + } + if((ndlp = (NODELIST *)fc_mem_get(binfo, MEM_NLP))) { + fc_bzero((void *)ndlp, sizeof(NODELIST)); + ndlp->sync = binfo->fc_sync; + ndlp->capabilities = binfo->fc_capabilities; + ndlp->nlp_DID = binfo->alpa_map[j]; + ndlp->nlp_state = NLP_LIMBO; + fc_nlp_bind(binfo, ndlp); + } + else + continue; + + ndlp->nlp_action |= NLP_DO_DISC_START; + if (firstndlp == 0) + firstndlp = ndlp; + } + } else { + /* No alpamap, so try all alpa's */ + for (j = 0; j < FC_MAXLOOP; j++) { + int index; + + if (clp[CFG_SCAN_DOWN].a_current) + index = FC_MAXLOOP - j - 1; + else + index = j; + if ((binfo->fc_myDID & 0xff) == staticAlpaArray[index]) + continue; + /* Skip if the node is already in the node table */ + if ((ndlp = fc_findnode_odid(binfo, NLP_SEARCH_ALL, staticAlpaArray[index]))) { + /* Mark slot for address authentication */ + ndlp->nlp_action |= NLP_DO_ADDR_AUTH; + ndlp->nlp_DID = staticAlpaArray[index]; + addrauth++; + continue; + } + if((ndlp = (NODELIST *)fc_mem_get(binfo, MEM_NLP))) { + fc_bzero((void *)ndlp, sizeof(NODELIST)); + ndlp->sync = binfo->fc_sync; + ndlp->capabilities = binfo->fc_capabilities; + ndlp->nlp_DID = staticAlpaArray[index]; + ndlp->nlp_state = NLP_LIMBO; + fc_nlp_bind(binfo, ndlp); + } + else + continue; + ndlp->nlp_action |= NLP_DO_DISC_START; + if (firstndlp == 0) + firstndlp = ndlp; + } + } + + /* Next mark ALL unmarked local nodes for Authentication */ + ndlp = binfo->fc_nlpunmap_start; + if(ndlp == (NODELIST *)&binfo->fc_nlpunmap_start) + ndlp = binfo->fc_nlpmap_start; + while(ndlp != (NODELIST *)&binfo->fc_nlpmap_start) { + + /* Skip over Fabric nodes, myself, and nodes partially logged in */ + if ((ndlp->nlp_DID == binfo->fc_myDID) || + (ndlp->nlp_type & NLP_FABRIC) || + (ndlp->nlp_action & (NLP_DO_DISC_START | NLP_DO_ADDR_AUTH))) { + ndlp = (NODELIST *)ndlp->nlp_listp_next; + if(ndlp == (NODELIST *)&binfo->fc_nlpunmap_start) + ndlp = binfo->fc_nlpmap_start; + continue; + } + + /* If it is a local node */ + did.un.word = ndlp->nlp_DID; + did.un.b.domain = 0; + did.un.b.area = 0; + if (fc_matchdid(binfo, ndlp, did.un.word)) { + /* Mark slot for address authentication */ + ndlp->nlp_action |= NLP_DO_ADDR_AUTH; + addrauth++; + } + ndlp = (NODELIST *)ndlp->nlp_listp_next; + if(ndlp == (NODELIST *)&binfo->fc_nlpunmap_start) + ndlp = binfo->fc_nlpmap_start; + } + + if (addrauth) { + fc_nextauth(p_dev_ctl, fc_max_els_sent); + return(0); + } else { + if (firstndlp) { + /* We can start discovery right now */ + fc_nextdisc(p_dev_ctl, fc_max_els_sent); + return(0); + } + } + } + + /* This should turn off DELAYED ABTS for ELS timeouts */ + if ((mb = (MAILBOXQ * )fc_mem_get(binfo, MEM_MBOX))) { + fc_set_slim(binfo, (MAILBOX * )mb, 0x052198, 0); + if (issue_mb_cmd(binfo, (MAILBOX * )mb, MBX_NOWAIT) != MBX_BUSY) { + fc_mem_put(binfo, MEM_MBOX, (uchar * )mb); + } + } + + /* This is at init, clear la */ + if ((mb = (MAILBOXQ * )fc_mem_get(binfo, MEM_MBOX | MEM_PRI))) { + binfo->fc_ffstate = FC_CLEAR_LA; + fc_clear_la(binfo, (MAILBOX * )mb); + if (issue_mb_cmd(binfo, (MAILBOX * )mb, MBX_NOWAIT) != MBX_BUSY) { + fc_mem_put(binfo, MEM_MBOX, (uchar * )mb); + } + } else { + binfo->fc_ffstate = FC_ERROR; + /* Device Discovery completion error */ + fc_log_printf_msg_vargs( binfo->fc_brd_no, + &fc_msgBlk0201, /* ptr to msg structure */ + fc_mes0201, /* ptr to msg */ + fc_msgBlk0201.msgPreambleStr); /* begin & end varargs */ + } + + if(FABRICTMO) { + fc_clk_can(p_dev_ctl, FABRICTMO); + FABRICTMO = 0; + } + return(0); +} /* End fc_fanovery */ + + +/**************************************************/ +/** fc_discovery **/ +/** **/ +/** This routine will find devices in network **/ +/**************************************************/ +_static_ int +fc_discovery( +fc_dev_ctl_t *p_dev_ctl) +{ + FC_BRD_INFO * binfo; + iCfgParam * clp; + NODELIST * ndlp; + NODELIST * new_ndlp; + NODELIST * firstndlp; + MAILBOXQ * mb; + int j, addrauth; + + binfo = &BINFO; + clp = DD_CTL.p_config[binfo->fc_brd_no]; + /* Device Discovery Started */ + fc_log_printf_msg_vargs( binfo->fc_brd_no, + &fc_msgBlk0202, /* ptr to msg structure */ + fc_mes0202, /* ptr to msg */ + fc_msgBlk0202.msgPreambleStr); /* begin & end varargs */ + + binfo->fc_ffstate = FC_LOOP_DISC; + binfo->fc_nlp_cnt = 0; + binfo->fc_flag &= ~(FC_NLP_MORE | FC_DELAY_PLOGI); + + /* If this is not our first time doing discovery and we don't have + * a new myDID, then rediscovery (address authentication) is appropriate. + */ + if ((p_dev_ctl->init_eventTag) && (binfo->fc_prevDID == binfo->fc_myDID)) { + /* do rediscovery on the loop */ + addrauth = fc_addrauth(p_dev_ctl); + } else { + addrauth = 0; + p_dev_ctl->init_eventTag = 1; + /* First make sure all nodes in nlplist are free */ + ndlp = binfo->fc_nlpunmap_start; + if(ndlp == (NODELIST *)&binfo->fc_nlpunmap_start) + ndlp = binfo->fc_nlpmap_start; + while(ndlp != (NODELIST *)&binfo->fc_nlpmap_start) { + new_ndlp = (NODELIST *)ndlp->nlp_listp_next; + + /* Skip over FABRIC nodes and myself */ + if ((ndlp->nlp_DID == binfo->fc_myDID) || + (ndlp->nlp_type & NLP_FABRIC)) { + ndlp = new_ndlp; + if(ndlp == (NODELIST *)&binfo->fc_nlpunmap_start) + ndlp = binfo->fc_nlpmap_start; + continue; + } + + fc_freenode(binfo, ndlp, 0); + ndlp->nlp_state = NLP_LIMBO; + fc_nlp_bind(binfo, ndlp); + ndlp->nlp_action |= NLP_DO_DISC_START; + + ndlp = new_ndlp; + if(ndlp == (NODELIST *)&binfo->fc_nlpunmap_start) + ndlp = binfo->fc_nlpmap_start; + } + } + binfo->fc_flag &= ~FC_SCSI_RLIP; + + /* If FCP is not enabled, go right to CLEAR_LA */ + if(!(clp[CFG_FCP_ON].a_current)) { + if (addrauth) { + /* Start authentication */ + fc_nextauth(p_dev_ctl, fc_max_els_sent); + return(0); + } + /* Nothing to discover, so goto CLEAR_LA */ + goto cla; + } + + firstndlp = 0; + + /* If FC_FABRIC is set, we need to do some NameServer stuff + * to seed the nodeList with additional entries. + */ + if (binfo->fc_flag & FC_FABRIC) { + /* We can LOGIN to the NameServer first */ + fc_els_cmd(binfo, ELS_CMD_PLOGI, (void *)NameServer_DID, + (uint32)0, (ushort)0, (NODELIST *)0); + if(fc_fdmi_on) { + /* HBA Mgmt */ + fc_els_cmd(binfo, ELS_CMD_PLOGI, (void *)FDMI_DID, + (uint32)0, (ushort)0, (NODELIST *)0); + } + return(0); + } + + /* No Fabric, just seed the nodeList with our ALPAmap */ + if (binfo->fc_topology == TOPOLOGY_LOOP) { + if (binfo->alpa_map[0]) { + for (j = 1; j <= binfo->alpa_map[0]; j++) { + if (((binfo->fc_myDID & 0xff) == binfo->alpa_map[j]) || + (binfo->alpa_map[j] == 0)) + continue; + /* Skip if the node is already marked address authentication */ + if((ndlp = fc_findnode_odid(binfo, NLP_SEARCH_ALL, binfo->alpa_map[j]))) { + if(ndlp->nlp_action & (NLP_DO_ADDR_AUTH | NLP_DO_DISC_START)) { + ndlp->nlp_DID = binfo->alpa_map[j]; + if (firstndlp == 0) + firstndlp = ndlp; + continue; + } + } + else { + if((ndlp = (NODELIST *)fc_mem_get(binfo, MEM_NLP))) { + fc_bzero((void *)ndlp, sizeof(NODELIST)); + ndlp->sync = binfo->fc_sync; + ndlp->capabilities = binfo->fc_capabilities; + ndlp->nlp_DID = binfo->alpa_map[j]; + ndlp->nlp_state = NLP_LIMBO; + fc_nlp_bind(binfo, ndlp); + } + else + continue; + } + ndlp->nlp_action |= NLP_DO_DISC_START; + if (firstndlp == 0) + firstndlp = ndlp; + } + } else { + /* No alpamap, so try all alpa's */ + for (j = 0; j < FC_MAXLOOP; j++) { + int index; + + if (clp[CFG_SCAN_DOWN].a_current) + index = FC_MAXLOOP - j - 1; + else + index = j; + if ((binfo->fc_myDID & 0xff) == staticAlpaArray[index]) + continue; + /* Skip if the node is already marked address authentication */ + if((ndlp = fc_findnode_odid(binfo, NLP_SEARCH_ALL, staticAlpaArray[index]))) { + if(ndlp->nlp_action & (NLP_DO_ADDR_AUTH | NLP_DO_DISC_START)) { + ndlp->nlp_DID = staticAlpaArray[index]; + if (firstndlp == 0) + firstndlp = ndlp; + continue; + } + } + else { + if((ndlp = (NODELIST *)fc_mem_get(binfo, MEM_NLP))) { + fc_bzero((void *)ndlp, sizeof(NODELIST)); + ndlp->sync = binfo->fc_sync; + ndlp->capabilities = binfo->fc_capabilities; + ndlp->nlp_DID = staticAlpaArray[index]; + ndlp->nlp_state = NLP_LIMBO; + fc_nlp_bind(binfo, ndlp); + } + else + continue; + } + ndlp->nlp_action |= NLP_DO_DISC_START; + if (firstndlp == 0) + firstndlp = ndlp; + } + } + } + /* Device Discovery continues */ + fc_log_printf_msg_vargs( binfo->fc_brd_no, + &fc_msgBlk0203, /* ptr to msg structure */ + fc_mes0203, /* ptr to msg */ + fc_msgBlk0203.msgPreambleStr, /* begin varargs */ + (ulong)firstndlp, + binfo->fc_ffstate); /* end varargs */ + if (addrauth) { + /* Start authentication */ + if(fc_nextauth(p_dev_ctl, fc_max_els_sent)) + return(0); + } + + if (firstndlp) { + /* We can start discovery right now */ + fc_nextdisc(p_dev_ctl, fc_max_els_sent); + return(0); + } + else { + /* Make sure no nodes are marked for discovery */ + /* go through all nodes in nlplist */ + ndlp = binfo->fc_nlpbind_start; + if(ndlp == (NODELIST *)&binfo->fc_nlpbind_start) + ndlp = binfo->fc_nlpunmap_start; + if(ndlp == (NODELIST *)&binfo->fc_nlpunmap_start) + ndlp = binfo->fc_nlpmap_start; + while(ndlp != (NODELIST *)&binfo->fc_nlpmap_start) { + if (ndlp->nlp_action & (NLP_DO_ADDR_AUTH | NLP_DO_DISC_START)) + ndlp->nlp_action &= ~(NLP_DO_ADDR_AUTH | NLP_DO_DISC_START); + ndlp = (NODELIST *)ndlp->nlp_listp_next; + if(ndlp == (NODELIST *)&binfo->fc_nlpbind_start) + ndlp = binfo->fc_nlpunmap_start; + if(ndlp == (NODELIST *)&binfo->fc_nlpunmap_start) + ndlp = binfo->fc_nlpmap_start; + } + } + +cla: + /* This should turn off DELAYED ABTS for ELS timeouts */ + if ((mb = (MAILBOXQ * )fc_mem_get(binfo, MEM_MBOX))) { + fc_set_slim(binfo, (MAILBOX * )mb, 0x052198, 0); + if (issue_mb_cmd(binfo, (MAILBOX * )mb, MBX_NOWAIT) != MBX_BUSY) { + fc_mem_put(binfo, MEM_MBOX, (uchar * )mb); + } + } + + /* This is at init, clear la */ + if ((mb = (MAILBOXQ * )fc_mem_get(binfo, MEM_MBOX | MEM_PRI))) { + binfo->fc_ffstate = FC_CLEAR_LA; + fc_clear_la(binfo, (MAILBOX * )mb); + if (issue_mb_cmd(binfo, (MAILBOX * )mb, MBX_NOWAIT) != MBX_BUSY) { + fc_mem_put(binfo, MEM_MBOX, (uchar * )mb); + } + } else { + binfo->fc_ffstate = FC_ERROR; + /* Device Discovery completion error */ + fc_log_printf_msg_vargs( binfo->fc_brd_no, + &fc_msgBlk0204, /* ptr to msg structure */ + fc_mes0204, /* ptr to msg */ + fc_msgBlk0204.msgPreambleStr); /* begin & end varargs */ + } + if(FABRICTMO) { + fc_clk_can(p_dev_ctl, FABRICTMO); + FABRICTMO = 0; + } + return(0); +} /* End fc_discovery */ + + +/**************************************************/ +/** fc_addrauth **/ +/** **/ +/** This routine will validate NODELIST entries **/ +/**************************************************/ +_local_ int +fc_addrauth( +fc_dev_ctl_t *p_dev_ctl) +{ + FC_BRD_INFO * binfo; + iCfgParam * clp; + NODELIST * ndlp; + NODELIST * new_ndlp; + int cnt; + int cnt1, cnt2; + + binfo = &BINFO; + clp = DD_CTL.p_config[binfo->fc_brd_no]; + + binfo->fc_nlp_cnt = 0; + binfo->fc_flag &= ~FC_NLP_MORE; + cnt = 0; + cnt1 = 0; + cnt2 = 0; + + /* go through all nodes in nlplist */ + ndlp = binfo->fc_nlpunmap_start; + if(ndlp == (NODELIST *)&binfo->fc_nlpunmap_start) + ndlp = binfo->fc_nlpmap_start; + while(ndlp != (NODELIST *)&binfo->fc_nlpmap_start) { + new_ndlp = (NODELIST *)ndlp->nlp_listp_next; + + /* Skip over Fabric nodes, myself, and nodes partially logged in */ + if ((ndlp->nlp_DID == binfo->fc_myDID) || + (ndlp->nlp_type & NLP_FABRIC)) { + ndlp = new_ndlp; + if(ndlp == (NODELIST *)&binfo->fc_nlpunmap_start) + ndlp = binfo->fc_nlpmap_start; + continue; + } + + if ((ndlp->nlp_type & NLP_FCP_TARGET) && + ((!clp[CFG_USE_ADISC].a_current) || (ndlp->nlp_Rpi == 0) || + (binfo->fc_flag & FC_SCSI_RLIP))) { + /* Force regular discovery on this node */ + fc_freenode(binfo, ndlp, 0); + ndlp->nlp_state = NLP_LIMBO; + fc_nlp_bind(binfo, ndlp); + ndlp->nlp_action &= ~NLP_DO_ADDR_AUTH; + ndlp->nlp_action |= NLP_DO_DISC_START; + cnt1++; + } else { + if ((ndlp->nlp_type & NLP_IP_NODE) && (ndlp->nlp_Rpi == 0)) { + /* Force regular discovery on this node */ + fc_freenode(binfo, ndlp, 0); + ndlp->nlp_state = NLP_LIMBO; + fc_nlp_bind(binfo, ndlp); + ndlp->nlp_action &= ~NLP_DO_ADDR_AUTH; + ndlp->nlp_action |= NLP_DO_DISC_START; + cnt2++; + } else { + /* Mark slot for address authentication */ + ndlp->nlp_action |= NLP_DO_ADDR_AUTH; + cnt++; + } + } + ndlp = new_ndlp; + if(ndlp == (NODELIST *)&binfo->fc_nlpunmap_start) + ndlp = binfo->fc_nlpmap_start; + } + + /* Device Discovery authentication */ + fc_log_printf_msg_vargs( binfo->fc_brd_no, + &fc_msgBlk0205, /* ptr to msg structure */ + fc_mes0205, /* ptr to msg */ + fc_msgBlk0205.msgPreambleStr, /* begin varargs */ + cnt, + cnt1, + cnt2); /* end varargs */ + return(cnt); +} /* End fc_addrauth */ + + +/**************************************************/ +/** fc_freebufq **/ +/** **/ +/** This routine will free a iocb cmd block and **/ +/** all associated memory. **/ +/**************************************************/ +_static_ void +fc_freebufq( +fc_dev_ctl_t *p_dev_ctl, +RING *rp, +IOCBQ *xmitiq) +{ + FC_BRD_INFO * binfo; + fcipbuf_t * p_mbuf; + fcipbuf_t * m_net; + NODELIST * ndlp; + ULP_BDE64 * bpl; + MATCHMAP * bmp; + int i; + + binfo = &BINFO; + switch (xmitiq->iocb.ulpCommand) { + case 0: + case CMD_XMIT_BCAST_CN: /* process xmit completion */ + case CMD_XMIT_BCAST_CX: + case CMD_XMIT_SEQUENCE_CX: + case CMD_XMIT_BCAST64_CN: /* process xmit completion */ + case CMD_XMIT_BCAST64_CX: + case CMD_XMIT_SEQUENCE64_CX: + /* get mbuf ptr for xmit */ + m_net = (fcipbuf_t * )xmitiq->bp; + ndlp = (NODELIST * ) xmitiq->info; + + /* Loop thru BDEs and unmap memory pages associated with mbuf */ + if (binfo->fc_flag & FC_SLI2) { + bmp = (MATCHMAP * )xmitiq->bpl; + if(bmp) { + bpl = (ULP_BDE64 * )bmp->virt; + while (bpl && xmitiq->iocb.un.xseq64.bdl.bdeSize) { + fc_bufunmap(p_dev_ctl, (uchar *)getPaddr(bpl->addrHigh, bpl->addrLow), 0, bpl->tus.f.bdeSize); + bpl++; + xmitiq->iocb.un.xseq64.bdl.bdeSize -= sizeof(ULP_BDE64); + } + fc_mem_put(binfo, MEM_BPL, (uchar * )bmp); + } + fc_mem_put(binfo, MEM_IOCB, (uchar * )xmitiq); + } else { + for (i = 0; i < (int)xmitiq->iocb.ulpBdeCount; i++) { + fc_bufunmap(p_dev_ctl, (uchar *)((ulong)xmitiq->iocb.un.cont[i].bdeAddress), 0, (uint32)xmitiq->iocb.un.cont[i].bdeSize); + } + fc_mem_put(binfo, MEM_IOCB, (uchar * )xmitiq); + } + + if (ndlp && (ndlp->nlp_DID == NameServer_DID)) { + fc_mem_put(binfo, MEM_BUF, (uchar * )m_net); + } else { + /* free mbuf */ + p_mbuf = fcnextdata(m_net); + fcnextdata(m_net) = 0; + fcfreehandle(p_dev_ctl, m_net); + m_freem(m_net); + if (p_mbuf) { + fcfreehandle(p_dev_ctl, p_mbuf); + m_freem(p_mbuf); + } + } + break; + + case CMD_IOCB_CONTINUE_CN: + case CMD_IOCB_CONTINUE64_CN: + /* This is valid only for the IP ring, not the ELS ring */ + if (rp->fc_ringno == FC_ELS_RING) + break; + /* Loop thru BDEs and unmap memory pages associated with IOCB */ + for (i = 0; i < (int)xmitiq->iocb.ulpBdeCount; i++) { + if (binfo->fc_flag & FC_SLI2) + fc_bufunmap(p_dev_ctl, (uchar *)getPaddr(xmitiq->iocb.un.cont64[i].addrHigh, xmitiq->iocb.un.cont64[i].addrLow), 0, xmitiq->iocb.un.cont64[i].tus.f.bdeSize); + else + fc_bufunmap(p_dev_ctl, (uchar *)((ulong)xmitiq->iocb.un.cont[i].bdeAddress), 0, (uint32)xmitiq->iocb.un.cont[i].bdeSize); + } + fc_mem_put(binfo, MEM_IOCB, (uchar * )xmitiq); + break; + + case CMD_XMIT_ELS_RSP_CX: + case CMD_XMIT_ELS_RSP64_CX: + if (xmitiq->bp) { + fc_mem_put(binfo, MEM_BUF, (uchar * )xmitiq->bp); + } + if (binfo->fc_flag & FC_SLI2) { + fc_mem_put(binfo, MEM_BPL, (uchar * )xmitiq->bpl); + } + fc_mem_put(binfo, MEM_IOCB, (uchar * )xmitiq); + break; + + case CMD_ELS_REQUEST_CR: + case CMD_ELS_REQUEST64_CR: + if (xmitiq->bp) { + fc_mem_put(binfo, MEM_BUF, (uchar * )xmitiq->bp); + } + if (xmitiq->info) { + fc_mem_put(binfo, MEM_BUF, (uchar * )xmitiq->info); + } + if (binfo->fc_flag & FC_SLI2) { + fc_mem_put(binfo, MEM_BPL, (uchar * )xmitiq->bpl); + } + fc_mem_put(binfo, MEM_IOCB, (uchar * )xmitiq); + break; + + case CMD_QUE_RING_BUF_CN: + case CMD_QUE_RING_BUF64_CN: + /* Loop thru BDEs and return MEM_BUFs associated with IOCB */ + for (i = 0; i < (int)xmitiq->iocb.ulpBdeCount; i++) { + MATCHMAP * matp; + + if (binfo->fc_flag & FC_SLI2) + matp = fc_getvaddr(p_dev_ctl, rp, + (uchar * )getPaddr(xmitiq->iocb.un.cont64[i].addrHigh, xmitiq->iocb.un.cont64[i].addrLow)); + else + matp = fc_getvaddr(p_dev_ctl, rp, + (uchar * )((ulong)xmitiq->iocb.un.cont[i].bdeAddress)); + if (matp) { + if (rp->fc_ringno == FC_ELS_RING) { + fc_mem_put(binfo, MEM_BUF, (uchar * )matp); + } + if (rp->fc_ringno == FC_IP_RING) { + p_mbuf = (fcipbuf_t * )matp; + fcnextdata(p_mbuf) = 0; + fcnextpkt(p_mbuf) = 0; + m_freem(p_mbuf); + } + } + } + fc_mem_put(binfo, MEM_IOCB, (uchar * )xmitiq); + break; + + case CMD_CREATE_XRI_CX: + case CMD_CREATE_XRI_CR: + default: + fc_mem_put(binfo, MEM_IOCB, (uchar * )xmitiq); + break; + } +} /* End fc_freebufq */ + + +/**************************************************/ +/** fc_emac_lookup **/ +/** **/ +/** This routine will find an NODELIST entry **/ +/** that matches the destination MAC address. **/ +/** The XID for that entry is returned and rpi **/ +/** is updated with a ptr to the NODELIST entry. **/ +/**************************************************/ +_static_ ushort +fc_emac_lookup( +FC_BRD_INFO *binfo, +uchar *addr, +NODELIST **ndlpp) +{ + int j; + NODELIST * ndlp; + + ndlp = binfo->fc_nlpbind_start; + if(ndlp == (NODELIST *)&binfo->fc_nlpbind_start) + ndlp = binfo->fc_nlpunmap_start; + if(ndlp == (NODELIST *)&binfo->fc_nlpunmap_start) + ndlp = binfo->fc_nlpmap_start; + while(ndlp != (NODELIST *)&binfo->fc_nlpmap_start) { + + /* IF portname matches IEEE address, return NODELIST entry */ + if ((ndlp->nlp_portname.IEEE[0] == addr[0])) { + if((ndlp->nlp_state == NLP_SEED) || + ((ndlp->nlp_DID != Bcast_DID) && + ((ndlp->nlp_DID & CT_DID_MASK) == CT_DID_MASK))) { + ndlp = (NODELIST *)ndlp->nlp_listp_next; + if(ndlp == (NODELIST *)&binfo->fc_nlpbind_start) + ndlp = binfo->fc_nlpunmap_start; + if(ndlp == (NODELIST *)&binfo->fc_nlpunmap_start) + ndlp = binfo->fc_nlpmap_start; + continue; + } + + /* check rest of bytes in address / portname */ + for (j = 1; j < NADDR_LEN; j++) { + if (ndlp->nlp_portname.IEEE[j] != addr[j]) + break; + } + /* do all NADDR_LEN bytes match? */ + if (j == NADDR_LEN) { + if ((ndlp->nlp_portname.nameType == NAME_IEEE) && + (ndlp->nlp_portname.IEEEextMsn == 0) && + (ndlp->nlp_portname.IEEEextLsb == 0)) { + *ndlpp = ndlp; + return(ndlp->nlp_Xri); + } + } + } + ndlp = (NODELIST *)ndlp->nlp_listp_next; + if(ndlp == (NODELIST *)&binfo->fc_nlpbind_start) + ndlp = binfo->fc_nlpunmap_start; + if(ndlp == (NODELIST *)&binfo->fc_nlpunmap_start) + ndlp = binfo->fc_nlpmap_start; + } + + /* no match so return 0 */ + + *ndlpp = 0; + return(0); +} /* End fc_emac_lookup */ + + + +/* Put nlp on bind list */ +_static_ int +fc_nlp_bind( +FC_BRD_INFO *binfo, +NODELIST *nlp) +{ + NODELIST *end_nlp; + uint32 data1; + + data1 = ( ((uint32)nlp->nlp_state << 24) | + ((uint32)nlp->nlp_action << 16) | + ((uint32)nlp->nlp_type << 8) | + ((uint32)nlp->nlp_Rpi & 0xff) ); + /* BIND node tbl */ + fc_log_printf_msg_vargs( binfo->fc_brd_no, + &fc_msgBlk0903, /* ptr to msg structure */ + fc_mes0903, /* ptr to msg */ + fc_msgBlk0903.msgPreambleStr, /* begin varargs */ + (ulong)nlp, + nlp->nlp_DID, + nlp->nlp_flag, + data1); /* end varargs */ + /* First take it off any list its on */ + if(nlp->nlp_listp_next) { + if (nlp->nlp_flag & NLP_MAPPED) { + nlp->nlp_time = binfo->nlptimer++; + if (nlp->nlp_time == 0) { + fc_nlpadjust(binfo); + } + nlp->nlp_flag &= ~NLP_MAPPED; + binfo->fc_map_cnt--; + fc_deque(nlp); + } + else if (nlp->nlp_flag & NLP_UNMAPPED) { + nlp->nlp_time = binfo->nlptimer++; + if (nlp->nlp_time == 0) { + fc_nlpadjust(binfo); + } + nlp->nlp_flag &= ~NLP_UNMAPPED; + binfo->fc_unmap_cnt--; + fc_deque(nlp); + } + else if (nlp->nlp_flag & NLP_BIND) { + return(0); /* Already on bind list */ + } + } + + /* Put it at the begining of the bind list */ + binfo->fc_bind_cnt++; + + if(binfo->fc_nlpbind_start == (NODELIST *)&binfo->fc_nlpbind_start) { + nlp->nlp_listp_next = &binfo->fc_nlpbind_start; + binfo->fc_nlpbind_end = nlp; + } + else { + end_nlp = binfo->fc_nlpbind_start; + nlp->nlp_listp_next = end_nlp; + end_nlp->nlp_listp_prev = nlp; + } + binfo->fc_nlpbind_start = nlp;; + nlp->nlp_listp_prev = &binfo->fc_nlpbind_start; + + nlp->nlp_flag |= NLP_BIND; + + return(0); +} + +/* Put nlp on unmap list */ +_static_ int +fc_nlp_unmap( +FC_BRD_INFO *binfo, +NODELIST *nlp) +{ + NODELIST * end_nlp; + RING * rp; + IOCBQ * iocbq; + uint32 data1; + fc_dev_ctl_t * p_dev_ctl; + + data1 = ( ((uint32)nlp->nlp_state << 24) | + ((uint32)nlp->nlp_action << 16) | + ((uint32)nlp->nlp_type << 8) | + ((uint32)nlp->nlp_Rpi & 0xff) ); + /* UNMAP node tbl */ + fc_log_printf_msg_vargs( binfo->fc_brd_no, + &fc_msgBlk0904, /* ptr to msg structure */ + fc_mes0904, /* ptr to msg */ + fc_msgBlk0904.msgPreambleStr, /* begin varargs */ + (ulong)nlp, + nlp->nlp_DID, + nlp->nlp_flag, + data1); /* end varargs */ + /* First take it off any list its on */ + if(nlp->nlp_listp_next) { + if (nlp->nlp_flag & NLP_MAPPED) { + nlp->nlp_time = binfo->nlptimer++; + if (nlp->nlp_time == 0) { + fc_nlpadjust(binfo); + } + nlp->nlp_flag &= ~NLP_MAPPED; + binfo->fc_map_cnt--; + fc_deque(nlp); + } + else if (nlp->nlp_flag & NLP_BIND) { + nlp->nlp_time = binfo->nlptimer++; + if (nlp->nlp_time == 0) { + fc_nlpadjust(binfo); + } + nlp->nlp_flag &= ~NLP_BIND; + binfo->fc_bind_cnt--; + fc_deque(nlp); + /* If we are going from bind to unmapped, check for duplicate + * WWNN on bind list. + */ + /* Missing SP */ + p_dev_ctl = (fc_dev_ctl_t * )(binfo->fc_p_dev_ctl); + + /* Fabric nodes are always mapped by DID only */ + if((nlp->nlp_DID & Fabric_DID_MASK) == Fabric_DID_MASK) + goto out; + + switch(p_dev_ctl->fcp_mapping) { + + case FCP_SEED_DID: + break; + + case FCP_SEED_WWNN: + if((end_nlp = fc_findnode_wwnn(binfo, NLP_SEARCH_BIND, &nlp->nlp_nodename))) { + /* Found one so remove it */ + unsigned long iflag; + end_nlp->nlp_flag &= ~NLP_BIND; + binfo->fc_bind_cnt--; + fc_deque(end_nlp); + /* Look through ELS ring and remove any ELS cmds in progress for rnlp */ + iflag = lpfc_q_disable_lock(p_dev_ctl); + rp = &binfo->fc_ring[FC_ELS_RING]; + iocbq = (IOCBQ * )(rp->fc_txp.q_first); + while (iocbq) { + if ((iocbq->iocb.un.elsreq.remoteID == end_nlp->nlp_DID) || + ((end_nlp->nlp_DID == 0) && + (iocbq->iocb.un.elsreq.remoteID == end_nlp->nlp_oldDID))) { + iocbq->retry = 0xff; /* Mark for abort */ + if((binfo->fc_flag & FC_RSCN_MODE) || + (binfo->fc_ffstate < FC_READY)) { + if((end_nlp->nlp_state >= NLP_PLOGI) && + (end_nlp->nlp_state <= NLP_PRLI)) { + end_nlp->nlp_action &= ~NLP_DO_RSCN; + binfo->fc_nlp_cnt--; + if ((end_nlp->nlp_type & NLP_IP_NODE) && end_nlp->nlp_bp) { + m_freem((fcipbuf_t *)end_nlp->nlp_bp); + end_nlp->nlp_bp = (uchar * )0; + } + } + } + } + iocbq = (IOCBQ * )iocbq->q; + } + lpfc_q_unlock_enable(p_dev_ctl, iflag); + /* In case its on fc_delay_timeout list */ + fc_abort_delay_els_cmd(p_dev_ctl, end_nlp->nlp_DID); + fc_bzero((void *)end_nlp, sizeof(NODELIST)); + fc_mem_put(binfo, MEM_NLP, (uchar *)end_nlp); + } + break; + + case FCP_SEED_WWPN: + if((end_nlp = fc_findnode_wwpn(binfo, NLP_SEARCH_BIND, &nlp->nlp_portname))) { + /* Found one so remove it */ + unsigned long iflag; + end_nlp->nlp_flag &= ~NLP_BIND; + binfo->fc_bind_cnt--; + fc_deque(end_nlp); + /* Look through ELS ring and remove any ELS cmds in progress for rnlp */ + iflag = lpfc_q_disable_lock(p_dev_ctl); + rp = &binfo->fc_ring[FC_ELS_RING]; + iocbq = (IOCBQ * )(rp->fc_txp.q_first); + while (iocbq) { + if ((iocbq->iocb.un.elsreq.remoteID == end_nlp->nlp_DID) || + ((end_nlp->nlp_DID == 0) && (iocbq->iocb.un.elsreq.remoteID == end_nlp->nlp_oldDID))) { + iocbq->retry = 0xff; /* Mark for abort */ + if((binfo->fc_flag & FC_RSCN_MODE) || + (binfo->fc_ffstate < FC_READY)) { + if((end_nlp->nlp_state >= NLP_PLOGI) && + (end_nlp->nlp_state <= NLP_PRLI)) { + end_nlp->nlp_action &= ~NLP_DO_RSCN; + binfo->fc_nlp_cnt--; + if ((end_nlp->nlp_type & NLP_IP_NODE) && end_nlp->nlp_bp) { + m_freem((fcipbuf_t *)end_nlp->nlp_bp); + end_nlp->nlp_bp = (uchar * )0; + } + } + } + } + iocbq = (IOCBQ * )iocbq->q; + } + lpfc_q_unlock_enable(p_dev_ctl, iflag); + /* In case its on fc_delay_timeout list */ + fc_abort_delay_els_cmd(p_dev_ctl, end_nlp->nlp_DID); + fc_bzero((void *)end_nlp, sizeof(NODELIST)); + fc_mem_put(binfo, MEM_NLP, (uchar *)end_nlp); + } + break; + } /* switch */ + } + else if (nlp->nlp_flag & NLP_UNMAPPED) { + return(0); /* Already on unmap list */ + } + } + +out: + /* Put it on the end of the unmapped list */ + binfo->fc_unmap_cnt++; + end_nlp = binfo->fc_nlpunmap_end; + fc_enque(nlp, end_nlp); + nlp->nlp_flag |= NLP_UNMAPPED; + return(0); +} + +/* Put nlp on map list */ +_static_ int +fc_nlp_map( +FC_BRD_INFO *binfo, +NODELIST *nlp) +{ + NODELIST *end_nlp; + uint32 data1; + + data1 = ( ((uint32)nlp->nlp_state << 24) | + ((uint32)nlp->nlp_action << 16) | + ((uint32)nlp->nlp_type << 8) | + ((uint32)nlp->nlp_Rpi & 0xff) ); + /* MAP node tbl */ + fc_log_printf_msg_vargs( binfo->fc_brd_no, + &fc_msgBlk0905, /* ptr to msg structure */ + fc_mes0905, /* ptr to msg */ + fc_msgBlk0905.msgPreambleStr, /* begin varargs */ + (ulong)nlp, + nlp->nlp_DID, + nlp->nlp_flag, + data1); /* end varargs */ + /* First take it off any list its on */ + if(nlp->nlp_listp_next) { + if (nlp->nlp_flag & NLP_UNMAPPED) { + nlp->nlp_time = binfo->nlptimer++; + if (nlp->nlp_time == 0) { + fc_nlpadjust(binfo); + } + nlp->nlp_flag &= ~NLP_UNMAPPED; + binfo->fc_unmap_cnt--; + fc_deque(nlp); + } + else if (nlp->nlp_flag & NLP_BIND) { + nlp->nlp_time = binfo->nlptimer++; + if (nlp->nlp_time == 0) { + fc_nlpadjust(binfo); + } + nlp->nlp_flag &= ~NLP_BIND; + binfo->fc_bind_cnt--; + fc_deque(nlp); + } + else if (nlp->nlp_flag & NLP_MAPPED) { + return(0); /* Already on map list */ + } + } + + /* Put it on the end of the mapped list */ + binfo->fc_map_cnt++; + end_nlp = binfo->fc_nlpmap_end; + fc_enque(nlp, end_nlp); + nlp->nlp_flag |= NLP_MAPPED; + return(0); +} + +/**************************************************/ +/** fc_findnode_odid **/ +/** **/ +/** This routine find a node by did **/ +/**************************************************/ +_static_ NODELIST * +fc_findnode_odid( +FC_BRD_INFO *binfo, +uint32 order, +uint32 did) +{ + NODELIST * nlp; + uint32 data1; + + if(order & NLP_SEARCH_UNMAPPED) { + nlp = binfo->fc_nlpunmap_start; + while(nlp != (NODELIST *)&binfo->fc_nlpunmap_start) { + if (fc_matchdid(binfo, nlp, did)) { + + data1 = ( ((uint32)nlp->nlp_state << 24) | + ((uint32)nlp->nlp_action << 16) | + ((uint32)nlp->nlp_type << 8) | + ((uint32)nlp->nlp_Rpi & 0xff) ); + /* FIND node DID unmapped */ + fc_log_printf_msg_vargs( binfo->fc_brd_no, + &fc_msgBlk0906, /* ptr to msg structure */ + fc_mes0906, /* ptr to msg */ + fc_msgBlk0906.msgPreambleStr, /* begin varargs */ + (ulong)nlp, + nlp->nlp_DID, + nlp->nlp_flag, + data1); /* end varargs */ + return(nlp); + } + nlp = (NODELIST *)nlp->nlp_listp_next; + } + } + if(order & NLP_SEARCH_MAPPED) { + nlp = binfo->fc_nlpmap_start; + while(nlp != (NODELIST *)&binfo->fc_nlpmap_start) { + if (fc_matchdid(binfo, nlp, did)) { + + data1 = ( ((uint32)nlp->nlp_state << 24) | + ((uint32)nlp->nlp_action << 16) | + ((uint32)nlp->nlp_type << 8) | + ((uint32)nlp->nlp_Rpi & 0xff) ); + /* FIND node did mapped */ + fc_log_printf_msg_vargs( binfo->fc_brd_no, + &fc_msgBlk0907, /* ptr to msg structure */ + fc_mes0907, /* ptr to msg */ + fc_msgBlk0907.msgPreambleStr, /* begin varargs */ + (ulong)nlp, + nlp->nlp_DID, + nlp->nlp_flag, + data1); /* end varargs */ + return(nlp); + } + nlp = (NODELIST *)nlp->nlp_listp_next; + } + } + if(order & NLP_SEARCH_BIND) { + nlp = binfo->fc_nlpbind_start; + while(nlp != (NODELIST *)&binfo->fc_nlpbind_start) { + if (fc_matchdid(binfo, nlp, did)) { + + data1 = ( ((uint32)nlp->nlp_state << 24) | + ((uint32)nlp->nlp_action << 16) | + ((uint32)nlp->nlp_type << 8) | + ((uint32)nlp->nlp_Rpi & 0xff) ); + /* FIND node DID bind */ + fc_log_printf_msg_vargs( binfo->fc_brd_no, + &fc_msgBlk0908, /* ptr to msg structure */ + fc_mes0908, /* ptr to msg */ + fc_msgBlk0908.msgPreambleStr, /* begin varargs */ + (ulong)nlp, + nlp->nlp_DID, + nlp->nlp_flag, + data1); /* end varargs */ + return(nlp); + } + nlp = (NODELIST *)nlp->nlp_listp_next; + } + } + /* FIND node did NOT FOUND */ + fc_log_printf_msg_vargs( binfo->fc_brd_no, + &fc_msgBlk0909, /* ptr to msg structure */ + fc_mes0909, /* ptr to msg */ + fc_msgBlk0909.msgPreambleStr, /* begin varargs */ + did, + order); /* end varargs */ + /* no match found */ + return((NODELIST * )0); +} /* End fc_findnode_odid */ + + +/**************************************************/ +/** fc_findnode_scsid **/ +/** **/ +/** This routine find a node by scsid **/ +/**************************************************/ +_static_ NODELIST * +fc_findnode_scsid( +FC_BRD_INFO *binfo, +uint32 order, +uint32 scsid) +{ + NODELIST * nlp; + uint32 data1; + + if(order & NLP_SEARCH_UNMAPPED) { + nlp = binfo->fc_nlpunmap_start; + if(nlp == 0) { + return(0); + } + while(nlp != (NODELIST *)&binfo->fc_nlpunmap_start) { + if ((nlp->nlp_type & NLP_FCP_TARGET) && + (INDEX(nlp->id.nlp_pan, nlp->id.nlp_sid) == scsid)) { + + data1 = ( ((uint32)nlp->nlp_state << 24) | + ((uint32)nlp->nlp_action << 16) | + ((uint32)nlp->nlp_type << 8) | + ((uint32)scsid & 0xff) ); + /* FIND node scsi_id unmapped */ + fc_log_printf_msg_vargs( binfo->fc_brd_no, + &fc_msgBlk0910, /* ptr to msg structure */ + fc_mes0910, /* ptr to msg */ + fc_msgBlk0910.msgPreambleStr, /* begin varargs */ + (ulong)nlp, + nlp->nlp_DID, + nlp->nlp_flag, + data1); /* end varargs */ + return(nlp); + } + nlp = (NODELIST *)nlp->nlp_listp_next; + if(nlp == 0) { + return(0); + } + } + } + if(order & NLP_SEARCH_MAPPED) { + nlp = binfo->fc_nlpmap_start; + if(nlp == 0) { + return(0); + } + while(nlp != (NODELIST *)&binfo->fc_nlpmap_start) { + if ((nlp->nlp_type & NLP_FCP_TARGET) && + (INDEX(nlp->id.nlp_pan, nlp->id.nlp_sid) == scsid)) { + + data1 = ( ((uint32)nlp->nlp_state << 24) | + ((uint32)nlp->nlp_action << 16) | + ((uint32)nlp->nlp_type << 8) | + ((uint32)scsid & 0xff) ); + /* FIND node scsi_id mapped */ + fc_log_printf_msg_vargs( binfo->fc_brd_no, + &fc_msgBlk0911, /* ptr to msg structure */ + fc_mes0911, /* ptr to msg */ + fc_msgBlk0911.msgPreambleStr, /* begin varargs */ + (ulong)nlp, + nlp->nlp_DID, + nlp->nlp_flag, + data1); /* end varargs */ + return(nlp); + } + nlp = (NODELIST *)nlp->nlp_listp_next; + if(nlp == 0) { + return(0); + } + } + } + if(order & NLP_SEARCH_BIND) { + nlp = binfo->fc_nlpbind_start; + if(nlp == 0) { + return(0); + } + while(nlp != (NODELIST *)&binfo->fc_nlpbind_start) { + if ((nlp->nlp_type & NLP_FCP_TARGET) && + (INDEX(nlp->id.nlp_pan, nlp->id.nlp_sid) == scsid)) { + + data1 = ( ((uint32)nlp->nlp_state << 24) | + ((uint32)nlp->nlp_action << 16) | + ((uint32)nlp->nlp_type << 8) | + ((uint32)scsid & 0xff) ); + /* FIND node scsi_id bind */ + fc_log_printf_msg_vargs( binfo->fc_brd_no, + &fc_msgBlk0912, /* ptr to msg structure */ + fc_mes0912, /* ptr to msg */ + fc_msgBlk0912.msgPreambleStr, /* begin varargs */ + (ulong)nlp, + nlp->nlp_DID, + nlp->nlp_flag, + data1); /* end varargs */ + return(nlp); + } + nlp = (NODELIST *)nlp->nlp_listp_next; + if(nlp == 0) { + return(0); + } + } + } + /* FIND node scsi_id NOT FOUND */ + fc_log_printf_msg_vargs( binfo->fc_brd_no, + &fc_msgBlk0913, /* ptr to msg structure */ + fc_mes0913, /* ptr to msg */ + fc_msgBlk0913.msgPreambleStr, /* begin varargs */ + scsid, + order); /* end varargs */ + /* no match found */ + return((NODELIST * )0); +} /* End fc_findnode_scsid */ + + +/**************************************************/ +/** fc_findnode_wwnn **/ +/** **/ +/** This routine find a node by WWNN **/ +/**************************************************/ +_static_ NODELIST * +fc_findnode_wwnn( +FC_BRD_INFO *binfo, +uint32 order, +NAME_TYPE * wwnn) +{ + NODELIST * nlp; + uint32 data1; + + if(order & NLP_SEARCH_UNMAPPED) { + nlp = binfo->fc_nlpunmap_start; + while(nlp != (NODELIST *)&binfo->fc_nlpunmap_start) { + if(fc_geportname(&nlp->nlp_nodename, wwnn) == 2) { + + data1 = ( ((uint32)nlp->nlp_state << 24) | + ((uint32)nlp->nlp_action << 16) | + ((uint32)nlp->nlp_type << 8) | + ((uint32)nlp->nlp_Rpi & 0xff) ); + /* FIND node wwnn unmapped */ + fc_log_printf_msg_vargs( binfo->fc_brd_no, + &fc_msgBlk0914, /* ptr to msg structure */ + fc_mes0914, /* ptr to msg */ + fc_msgBlk0914.msgPreambleStr, /* begin varargs */ + (ulong)nlp, + nlp->nlp_DID, + nlp->nlp_flag, + data1); /* end varargs */ + return(nlp); + } + nlp = (NODELIST *)nlp->nlp_listp_next; + } + } + if(order & NLP_SEARCH_MAPPED) { + nlp = binfo->fc_nlpmap_start; + while(nlp != (NODELIST *)&binfo->fc_nlpmap_start) { + if(fc_geportname(&nlp->nlp_nodename, wwnn) == 2) { + + data1 = ( ((uint32)nlp->nlp_state << 24) | + ((uint32)nlp->nlp_action << 16) | + ((uint32)nlp->nlp_type << 8) | + ((uint32)nlp->nlp_Rpi & 0xff) ); + /* FIND node wwnn mapped */ + fc_log_printf_msg_vargs( binfo->fc_brd_no, + &fc_msgBlk0915, /* ptr to msg structure */ + fc_mes0915, /* ptr to msg */ + fc_msgBlk0915.msgPreambleStr, /* begin varargs */ + (ulong)nlp, + nlp->nlp_DID, + nlp->nlp_flag, + data1); /* end varargs */ + return(nlp); + } + nlp = (NODELIST *)nlp->nlp_listp_next; + } + } + if(order & NLP_SEARCH_BIND) { + nlp = binfo->fc_nlpbind_start; + while(nlp != (NODELIST *)&binfo->fc_nlpbind_start) { + if(fc_geportname(&nlp->nlp_nodename, wwnn) == 2) { + + data1 = ( ((uint32)nlp->nlp_state << 24) | + ((uint32)nlp->nlp_action << 16) | + ((uint32)nlp->nlp_type << 8) | + ((uint32)nlp->nlp_Rpi & 0xff) ); + /* FIND node wwnn bind */ + fc_log_printf_msg_vargs( binfo->fc_brd_no, + &fc_msgBlk0916, /* ptr to msg structure */ + fc_mes0916, /* ptr to msg */ + fc_msgBlk0916.msgPreambleStr, /* begin varargs */ + (ulong)nlp, + nlp->nlp_DID, + nlp->nlp_flag, + data1); /* end varargs */ + return(nlp); + } + nlp = (NODELIST *)nlp->nlp_listp_next; + } + } + /* FIND node wwnn NOT FOUND */ + fc_log_printf_msg_vargs( binfo->fc_brd_no, + &fc_msgBlk0918, /* ptr to msg structure */ + fc_mes0918, /* ptr to msg */ + fc_msgBlk0918.msgPreambleStr, /* begin varargs */ + order); /* end varargs */ + /* no match found */ + return((NODELIST * )0); +} /* End fc_findnode_wwnn */ + + + +/**************************************************/ +/** fc_findnode_wwpn **/ +/** **/ +/** This routine find a node by WWPN **/ +/**************************************************/ +_static_ NODELIST * +fc_findnode_wwpn( +FC_BRD_INFO *binfo, +uint32 order, +NAME_TYPE * wwpn) +{ + NODELIST * nlp; + uint32 data1; + + if(order & NLP_SEARCH_UNMAPPED) { + nlp = binfo->fc_nlpunmap_start; + while(nlp != (NODELIST *)&binfo->fc_nlpunmap_start) { + if(fc_geportname(&nlp->nlp_portname, wwpn) == 2) { + + data1 = ( ((uint32)nlp->nlp_state << 24) | + ((uint32)nlp->nlp_action << 16) | + ((uint32)nlp->nlp_type << 8) | + ((uint32)nlp->nlp_Rpi & 0xff) ); + /* FIND node wwpn unmapped */ + fc_log_printf_msg_vargs( binfo->fc_brd_no, + &fc_msgBlk0919, /* ptr to msg structure */ + fc_mes0919, /* ptr to msg */ + fc_msgBlk0919.msgPreambleStr, /* begin varargs */ + (ulong)nlp, + nlp->nlp_DID, + nlp->nlp_flag, + data1); /* end varargs */ + return(nlp); + } + nlp = (NODELIST *)nlp->nlp_listp_next; + } + } + if(order & NLP_SEARCH_MAPPED) { + nlp = binfo->fc_nlpmap_start; + while(nlp != (NODELIST *)&binfo->fc_nlpmap_start) { + if(fc_geportname(&nlp->nlp_portname, wwpn) == 2) { + + data1 = ( ((uint32)nlp->nlp_state << 24) | + ((uint32)nlp->nlp_action << 16) | + ((uint32)nlp->nlp_type << 8) | + ((uint32)nlp->nlp_Rpi & 0xff) ); + /* FIND node wwpn mapped */ + fc_log_printf_msg_vargs( binfo->fc_brd_no, + &fc_msgBlk0920, /* ptr to msg structure */ + fc_mes0920, /* ptr to msg */ + fc_msgBlk0920.msgPreambleStr, /* begin varargs */ + (ulong)nlp, + nlp->nlp_DID, + nlp->nlp_flag, + data1); /* end varargs */ + return(nlp); + } + nlp = (NODELIST *)nlp->nlp_listp_next; + } + } + if(order & NLP_SEARCH_BIND) { + nlp = binfo->fc_nlpbind_start; + while(nlp != (NODELIST *)&binfo->fc_nlpbind_start) { + if(fc_geportname(&nlp->nlp_portname, wwpn) == 2) { + + data1 = ( ((uint32)nlp->nlp_state << 24) | + ((uint32)nlp->nlp_action << 16) | + ((uint32)nlp->nlp_type << 8) | + ((uint32)nlp->nlp_Rpi & 0xff) ); + /* FIND node wwpn bind */ + fc_log_printf_msg_vargs( binfo->fc_brd_no, + &fc_msgBlk0921, /* ptr to msg structure */ + fc_mes0921, /* ptr to msg */ + fc_msgBlk0921.msgPreambleStr, /* begin varargs */ + (ulong)nlp, + nlp->nlp_DID, + nlp->nlp_flag, + data1); /* end varargs */ + return(nlp); + } + nlp = (NODELIST *)nlp->nlp_listp_next; + } + } + /* FIND node wwpn NOT FOUND */ + fc_log_printf_msg_vargs( binfo->fc_brd_no, + &fc_msgBlk0922, /* ptr to msg structure */ + fc_mes0922, /* ptr to msg */ + fc_msgBlk0922.msgPreambleStr, /* begin varargs */ + order); /* end varargs */ + /* no match found */ + return((NODELIST * )0); +} /* End fc_findnode_wwpn */ + + +/**************************************************/ +/** fc_findnode_oxri **/ +/** **/ +/** This routine find a node by OXri **/ +/**************************************************/ +_static_ NODELIST * +fc_findnode_oxri( +FC_BRD_INFO *binfo, +uint32 order, +uint32 xri) +{ + NODELIST * nlp; + uint32 data1; + + if(order & NLP_SEARCH_UNMAPPED) { + nlp = binfo->fc_nlpunmap_start; + while(nlp != (NODELIST *)&binfo->fc_nlpunmap_start) { + if (nlp->nlp_Xri == xri) { + + data1 = ( ((uint32)nlp->nlp_state << 24) | + ((uint32)nlp->nlp_action << 16) | + ((uint32)nlp->nlp_type << 8) | + ((uint32)nlp->nlp_Rpi & 0xff) ); + /* FIND node xri unmapped */ + fc_log_printf_msg_vargs( binfo->fc_brd_no, + &fc_msgBlk0923, /* ptr to msg structure */ + fc_mes0923, /* ptr to msg */ + fc_msgBlk0923.msgPreambleStr, /* begin varargs */ + (ulong)nlp, + nlp->nlp_Xri, + nlp->nlp_flag, + data1); /* end varargs */ + return(nlp); + } + nlp = (NODELIST *)nlp->nlp_listp_next; + } + } + if(order & NLP_SEARCH_MAPPED) { + nlp = binfo->fc_nlpmap_start; + while(nlp != (NODELIST *)&binfo->fc_nlpmap_start) { + if (nlp->nlp_Xri == xri) { + + data1 = ( ((uint32)nlp->nlp_state << 24) | + ((uint32)nlp->nlp_action << 16) | + ((uint32)nlp->nlp_type << 8) | + ((uint32)nlp->nlp_Rpi & 0xff) ); + /* FIND node xri mapped */ + fc_log_printf_msg_vargs( binfo->fc_brd_no, + &fc_msgBlk0924, /* ptr to msg structure */ + fc_mes0924, /* ptr to msg */ + fc_msgBlk0924.msgPreambleStr, /* begin varargs */ + (ulong)nlp, + nlp->nlp_Xri, + nlp->nlp_flag, + data1); /* end varargs */ + return(nlp); + } + nlp = (NODELIST *)nlp->nlp_listp_next; + } + } + if(order & NLP_SEARCH_BIND) { + nlp = binfo->fc_nlpbind_start; + while(nlp != (NODELIST *)&binfo->fc_nlpbind_start) { + if (nlp->nlp_Xri == xri) { + + data1 = ( ((uint32)nlp->nlp_state << 24) | + ((uint32)nlp->nlp_action << 16) | + ((uint32)nlp->nlp_type << 8) | + ((uint32)nlp->nlp_Rpi & 0xff) ); + /* FIND node xri bind */ + fc_log_printf_msg_vargs( binfo->fc_brd_no, + &fc_msgBlk0925, /* ptr to msg structure */ + fc_mes0925, /* ptr to msg */ + fc_msgBlk0925.msgPreambleStr, /* begin varargs */ + (ulong)nlp, + nlp->nlp_Xri, + nlp->nlp_flag, + data1); /* end varargs */ + return(nlp); + } + nlp = (NODELIST *)nlp->nlp_listp_next; + } + } + /* FIND node xri NOT FOUND */ + fc_log_printf_msg_vargs( binfo->fc_brd_no, + &fc_msgBlk0926, /* ptr to msg structure */ + fc_mes0926, /* ptr to msg */ + fc_msgBlk0926.msgPreambleStr, /* begin varargs */ + xri, + order); /* end varargs */ + /* no match found */ + return((NODELIST * )0); +} /* End fc_findnode_oxri */ + +/* Put nlp in PLOGI state */ +_static_ int +fc_nlp_logi( +FC_BRD_INFO *binfo, +NODELIST *nlp, +NAME_TYPE *wwpnp, +NAME_TYPE *wwnnp) +{ + fc_dev_ctl_t * p_dev_ctl; + NODELIST * rnlp; + + if (nlp->nlp_flag & NLP_UNMAPPED) { + nlp->nlp_flag &= ~NLP_UNMAPPED; + binfo->fc_unmap_cnt--; + fc_deque(nlp); + } + else if (nlp->nlp_flag & NLP_BIND) { + nlp->nlp_flag &= ~NLP_BIND; + binfo->fc_bind_cnt--; + fc_deque(nlp); + } + else if (nlp->nlp_flag & NLP_MAPPED) { + nlp->nlp_flag &= ~NLP_MAPPED; + binfo->fc_map_cnt--; + fc_deque(nlp); + } + + p_dev_ctl = (fc_dev_ctl_t * )(binfo->fc_p_dev_ctl); + + /* Fabric nodes are always mapped by DID only */ + if((nlp->nlp_DID & Fabric_DID_MASK) == Fabric_DID_MASK) + goto out; + + switch(p_dev_ctl->fcp_mapping) { + case FCP_SEED_DID: + fc_bcopy(wwpnp, &nlp->nlp_portname, sizeof(NAME_TYPE)); + fc_bcopy(wwnnp, &nlp->nlp_nodename, sizeof(NAME_TYPE)); + break; + case FCP_SEED_WWNN: + /* Check to see if this WWNN already has a binding setup */ + if(fc_geportname(&nlp->nlp_nodename, wwnnp) != 2) { + if (nlp->nlp_type & NLP_SEED_WWNN) { + /* Get a new entry to save old binding info */ + if((rnlp = (NODELIST *)fc_mem_get(binfo, MEM_NLP))) { + fc_bzero((void *)rnlp, sizeof(NODELIST)); + rnlp->nlp_state = NLP_LIMBO; + fc_nlp_swapinfo(binfo, nlp, rnlp); + fc_nlp_bind(binfo, rnlp); + } + } + /* Search for existing entry with that binding */ + if((rnlp = fc_findnode_wwnn(binfo, NLP_SEARCH_ALL, wwnnp)) && + (rnlp->nlp_type & NLP_SEED_WWNN)) { + + if (rnlp->nlp_flag & NLP_MAPPED) { + rnlp->nlp_flag &= ~NLP_MAPPED; + binfo->fc_map_cnt--; + fc_deque(rnlp); + } + else if (rnlp->nlp_flag & NLP_UNMAPPED) { + rnlp->nlp_flag &= ~NLP_UNMAPPED; + binfo->fc_unmap_cnt--; + fc_deque(rnlp); + } + else if (rnlp->nlp_flag & NLP_BIND) { + rnlp->nlp_flag &= ~NLP_BIND; + binfo->fc_bind_cnt--; + fc_deque(rnlp); + } + + /* found, so copy binding info into nlp */ + fc_nlp_swapinfo(binfo, rnlp, nlp); + if(rnlp->nlp_action || (rnlp->nlp_flag & NLP_REQ_SND)) { + fc_nlp_bind(binfo, rnlp); + } + else { + fc_freenode(binfo, rnlp, 1); + } + } + fc_bcopy(wwpnp, &nlp->nlp_portname, sizeof(NAME_TYPE)); + fc_bcopy(wwnnp, &nlp->nlp_nodename, sizeof(NAME_TYPE)); + } + else { + /* DID and WWNN match existing entry */ + fc_bcopy(wwpnp, &nlp->nlp_portname, sizeof(NAME_TYPE)); + } + break; + case FCP_SEED_WWPN: + /* Check to see if this WWPN already has a binding setup */ + if(fc_geportname(&nlp->nlp_portname, wwpnp) != 2) { + if (nlp->nlp_type & NLP_SEED_WWPN) { + /* Get a new entry to save old binding info */ + if((rnlp = (NODELIST *)fc_mem_get(binfo, MEM_NLP))) { + fc_bzero((void *)rnlp, sizeof(NODELIST)); + rnlp->nlp_state = NLP_LIMBO; + fc_nlp_swapinfo(binfo, nlp, rnlp); + fc_nlp_bind(binfo, rnlp); + } + } + /* Search for existing entry with that binding */ + if((rnlp = fc_findnode_wwpn(binfo, NLP_SEARCH_ALL, wwpnp)) && + (rnlp->nlp_type & NLP_SEED_WWPN)) { + + if (rnlp->nlp_flag & NLP_MAPPED) { + rnlp->nlp_flag &= ~NLP_MAPPED; + binfo->fc_map_cnt--; + fc_deque(rnlp); + } + else if (rnlp->nlp_flag & NLP_UNMAPPED) { + rnlp->nlp_flag &= ~NLP_UNMAPPED; + binfo->fc_unmap_cnt--; + fc_deque(rnlp); + } + else if (rnlp->nlp_flag & NLP_BIND) { + rnlp->nlp_flag &= ~NLP_BIND; + binfo->fc_bind_cnt--; + fc_deque(rnlp); + } + /* found, so copy binding info into nlp */ + fc_nlp_swapinfo(binfo, rnlp, nlp); + if(rnlp->nlp_action || (rnlp->nlp_flag & NLP_REQ_SND)) { + fc_nlp_bind(binfo, rnlp); + } + else { + fc_freenode(binfo, rnlp, 1); + } + } +out: + fc_bcopy(wwpnp, &nlp->nlp_portname, sizeof(NAME_TYPE)); + fc_bcopy(wwnnp, &nlp->nlp_nodename, sizeof(NAME_TYPE)); + } + else { + /* DID and WWPN match existing entry */ + fc_bcopy(wwnnp, &nlp->nlp_nodename, sizeof(NAME_TYPE)); + } + break; + } + + nlp->nlp_state = NLP_PLOGI; + fc_nlp_bind(binfo, nlp); + return(0); +} + +_static_ int +fc_nlp_swapinfo( +FC_BRD_INFO *binfo, +NODELIST *old_nlp, +NODELIST *new_nlp) +{ + int index; + + fc_bcopy(&old_nlp->nlp_nodename, &new_nlp->nlp_nodename, sizeof(NAME_TYPE)); + fc_bcopy(&old_nlp->nlp_portname, &new_nlp->nlp_portname, sizeof(NAME_TYPE)); + new_nlp->nlp_type = old_nlp->nlp_type; + new_nlp->id.nlp_pan = old_nlp->id.nlp_pan; + new_nlp->id.nlp_sid = old_nlp->id.nlp_sid; + new_nlp->nlp_targetp = old_nlp->nlp_targetp; + new_nlp->target_scsi_options = old_nlp->target_scsi_options; + new_nlp->capabilities = old_nlp->capabilities; + new_nlp->sync = old_nlp->sync; + + if((old_nlp->nlp_type & NLP_FCP_TARGET) && old_nlp->nlp_targetp != NULL) { + index = INDEX(new_nlp->id.nlp_pan, new_nlp->id.nlp_sid); + if(binfo->device_queue_hash[index].node_ptr && + binfo->device_queue_hash[index].node_ptr->nlp == old_nlp) { + binfo->device_queue_hash[index].node_ptr->nlp = new_nlp; + new_nlp->nlp_targetp = (uchar *)binfo->device_queue_hash[index].node_ptr; + } + } + + old_nlp->nlp_type = 0; + old_nlp->id.nlp_pan = 0; + old_nlp->id.nlp_sid = 0; + old_nlp->nlp_targetp = 0; + old_nlp->sync = binfo->fc_sync; + old_nlp->capabilities = binfo->fc_capabilities; + fc_bzero(&old_nlp->nlp_nodename, sizeof(NAME_TYPE)); + fc_bzero(&old_nlp->nlp_portname, sizeof(NAME_TYPE)); + return(0); +} + diff -purN -X /home/mbligh/.diff.exclude 350-autoswap/drivers/scsi/lpfc/fcscsib.c 370-emulex/drivers/scsi/lpfc/fcscsib.c --- 350-autoswap/drivers/scsi/lpfc/fcscsib.c 1969-12-31 16:00:00.000000000 -0800 +++ 370-emulex/drivers/scsi/lpfc/fcscsib.c 2004-02-28 11:20:05.000000000 -0800 @@ -0,0 +1,7611 @@ +/******************************************************************* + * This file is part of the Emulex Linux Device Driver for * + * Enterprise Fibre Channel Host Bus Adapters. * + * Refer to the README file included with this package for * + * driver version and adapter support. * + * Copyright (C) 2003 Emulex Corporation. * + * www.emulex.com * + * * + * This program is free software; you can redistribute it and/or * + * modify it under the terms of the GNU General Public License * + * as published by the Free Software Foundation; either version 2 * + * of the License, or (at your option) any later version. * + * * + * This program is distributed in the hope that it will be useful, * + * but WITHOUT ANY WARRANTY; without even the implied warranty of * + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * + * GNU General Public License for more details, a copy of which * + * can be found in the file COPYING included with this package. * + *******************************************************************/ + +#include "fc_os.h" + +#include "fc_hw.h" +#include "fc.h" + +#include "fcdiag.h" +#include "hbaapi.h" +#include "fcfgparm.h" +#include "fcmsg.h" +#include "fc_crtn.h" +#include "fc_ertn.h" /* Environment - external routine definitions */ + +extern clock_t fc_ticks_per_second; +extern fc_dd_ctl_t DD_CTL; +extern iCfgParam icfgparam[]; +extern int lpfc_nethdr; +extern uint32 fcPAGESIZE; +extern uint32 fc_diag_state; +extern int fcinstance[]; + +/* Routine Declaration - Local */ +_local_ void fc_rscndisc_timeout(fc_dev_ctl_t *p_dev_ctl, void *l1, void *l2); +_local_ int fc_ring_txcnt(FC_BRD_INFO *binfo, int flag); +_local_ int fc_ring_txpcnt(FC_BRD_INFO *binfo, int flag); +/* End Routine Declaration - Local */ + +static uchar fcbroadcastaddr[MACADDR_LEN] = +{ + 0xff, 0xff, 0xff, 0xff, 0xff, 0xff +}; + +_static_ int fc_max_ns_retry = 3; +_static_ int fc_inq_hbeat_tmo = 60; +_static_ int fc_inq_sn_tmo = 30; +_static_ int fc_offline_stop_io = 1; +_static_ int fc_max_els_sent = 32; + +#define INQ_LEN 0x100 + +#define RPTLUN_MIN_LEN 0x1000 +#define WD6 (IOCB_WORD_SZ-2) /* IOCB wd 6 */ +#define WD7 (IOCB_WORD_SZ-1) /* IOCB wd 7 */ +/********************************************/ +/** fc_strncmp **/ +/** **/ +/** Compare string 1 to string 2. **/ +/** Compare terminates on count N **/ +/** **/ +/** Return value: **/ +/** Less than 0 = str1 < str2 **/ +/** Zero = str1 egual str2 **/ +/** Greater than 0 = str1 > str2 **/ +/********************************************/ +_forward_ int +fc_strncmp( char *str1, + char *str2, + int cnt) +{ + int c1, c2; + int dif; + + while( cnt--) { + c1 = (int)*str1++ & 0xff; + c2 = (int)*str2++ & 0xff; + if( (c1 | c2) == 0) + return(0); /* strings equal */ + if( (dif = c1 - c2) == 0) + continue; /* chars are equal */ + if( c1 == 0) + return(-1); /* str1 < str2 */ + if( c2 == 0) + return(1); /* str1 > str2 */ + return(dif); + } + return(0); /* strings equal */ +} /* fc_strncmp */ + +/********************************************/ +/* fc_strcpy */ +/* */ +/* Copy str2 to str1. . */ +/* Str2 must be a pointer to a null */ +/* terminated string. It is the caller's */ +/* responsibility to insure that str1 is */ +/* large enough to hold str2. */ +/* */ +/* Return value: */ +/* pointer to str1 */ +/********************************************/ +_static_ char * +fc_strcpy( char *str1, /* dest */ + char *str2) /* src */ +{ + char *temp; + temp = str1; + + while( (*str1++ = *str2++) != '\0') { + continue; + } + return(temp); +} /* fc_strcpy */ + +/************************************************/ +/** fc_setup_ring **/ +/** **/ +/** After ring has been configured, this **/ +/** routine is called to initialize the ring **/ +/************************************************/ +_static_ void +fc_setup_ring( +fc_dev_ctl_t *p_dev_ctl, /* point to dev_ctl area */ +int ring) +{ + FC_BRD_INFO * binfo; + iCfgParam * clp; + RING * rp; + + binfo = &BINFO; + rp = &binfo->fc_ring[ring]; + clp = DD_CTL.p_config[binfo->fc_brd_no]; + + /* set up the watchdog timer control structure section */ + if (!rp->fc_wdt_inited) { + if (ring == FC_FCP_RING) { + if(clp[CFG_LINKDOWN_TMO].a_current) { + rp->fc_ringtmo = clp[CFG_LINKDOWN_TMO].a_current; + } + else { + rp->fc_ringtmo = clp[CFG_LINKDOWN_TMO].a_default; + } + } else { + rp->fc_ringtmo = RING_TMO_DFT; + } + RINGTMO = 0; + rp->fc_wdt_inited = 1; + } +} /* End fc_setup_ring */ + +/************************************************************************/ +/* */ +/* NAME: fc_closewait */ +/* */ +/* FUNCTION: Adapter Driver Wait for Close Routine */ +/* This routine waits for the adapter to finish all requests */ +/* */ +/* EXECUTION ENVIRONMENT: */ +/* This routine can be called by a process. */ +/* */ +/* INPUTS: */ +/* fc_dev_ctl_t - adapter unique data structure (one per adapter) */ +/* */ +/* RETURN VALUE DESCRIPTION: none */ +/* */ +/* EXTERNAL PROCEDURES CALLED: */ +/* disable_lock lock_enable */ +/* */ +/************************************************************************/ +_static_ void +fc_closewait( +fc_dev_ctl_t *p_dev_ctl) /* point to dev_ctl area */ +{ + FC_BRD_INFO * binfo; + int ipri; + struct buf *bp, *nextbp; + + binfo = &BINFO; + + ipri = disable_lock(FC_LVL, &CMD_LOCK); + + /* wait for all operations to complete */ + while ((fc_ring_txcnt(binfo, FC_FCP_RING) + || fc_ring_txpcnt(binfo, FC_FCP_RING) + || binfo->fc_mbox.q_cnt)) { + unlock_enable(ipri, &CMD_LOCK); + DELAYMSctx(1000); /* delay 1 second */ + ipri = disable_lock(FC_LVL, &CMD_LOCK); + } + + /* Clear out timeout queue */ + for (bp = p_dev_ctl->timeout_head; bp != NULL; ) { + nextbp = bp->av_forw; + bp->b_error = ETIMEDOUT; + bp->b_flags |= B_ERROR; + bp->b_resid = bp->b_bcount; + FCSTATCTR.fcpScsiTmo++; + fc_do_iodone(bp); + bp = nextbp; + } + p_dev_ctl->timeout_head = NULL; + p_dev_ctl->timeout_count = 0; + + /* update the device state */ + binfo->fc_open_count &= ~FC_FCP_OPEN; + if (binfo->fc_open_count == 0) + p_dev_ctl->device_state = CLOSED; + + unlock_enable(ipri, &CMD_LOCK); + return; + +} /* End fc_closewait */ + + +/* + * This routine copies data from src + * then potentially swaps the destination to big endian. + * Assumes cnt is a multiple of sizeof(uint32). + */ +_static_ void +fc_pcimem_bcopy( +uint32 *src, +uint32 *dest, +uint32 cnt) +{ + uint32 ldata; + int i; + + for (i = 0; i < (int)cnt; i += sizeof(uint32)) { + ldata = *src++; + ldata = PCIMEM_LONG(ldata); + *dest++ = ldata; + } +} /* End fc_pcimem_bcopy */ + + +#define SCSI3_PERSISTENT_RESERVE_IN 0x5e + +/******************************************************/ +/** handle_fcp_event **/ +/** **/ +/** Description: Process an FCP Rsp Ring completion **/ +/** **/ +/******************************************************/ +_static_ void +handle_fcp_event( +fc_dev_ctl_t *p_dev_ctl, +RING *rp, +IOCBQ *temp) +{ + FC_BRD_INFO * binfo; + iCfgParam * clp; + IOCB * cmd; + fc_buf_t * fcptr; + struct buf * bp; + T_SCSIBUF * sbp; + FCP_RSP * fcpRsp; + uint32 * lp, i, qfull; + dvi_t * dev_ptr, * next_dev_ptr; + NODELIST * ndlp; + + /* called from host_interrupt() to process R2ATT */ + binfo = &BINFO; + cmd = &temp->iocb; + qfull = 0; + ndlp = 0; + + /* look up FCP complete by IoTag */ + if ((fcptr = fc_deq_fcbuf_active(rp, cmd->ulpIoTag)) == NULL) { + /* ERROR: completion with missing FCP command */ + if (!((cmd->ulpStatus == IOSTAT_LOCAL_REJECT) && + ((cmd->un.grsp.perr.statLocalError == IOERR_INVALID_RPI) || + (cmd->un.grsp.perr.statLocalError == IOERR_ABORT_IN_PROGRESS) || + (cmd->un.grsp.perr.statLocalError == IOERR_SEQUENCE_TIMEOUT) || + (cmd->un.grsp.perr.statLocalError == IOERR_ABORT_REQUESTED)))) { + /* Stray FCP completion */ + fc_log_printf_msg_vargs( binfo->fc_brd_no, + &fc_msgBlk0720, /* ptr to msg structure */ + fc_mes0720, /* ptr to msg */ + fc_msgBlk0720.msgPreambleStr, /* begin varargs */ + cmd->ulpCommand, + cmd->ulpIoTag, + cmd->ulpStatus, + cmd->un.ulpWord[4]); /* end varargs */ + } + + FCSTATCTR.fcpStrayCmpl++; + return; + } + FCSTATCTR.fcpCmpl++; + + dev_ptr = fcptr->dev_ptr; + dev_ptr->stop_send_io = 0; + + + if(dev_ptr->queue_state == ACTIVE_PASSTHRU) { + node_t * map_node_ptr; + struct dev_info * map_dev_ptr; + + map_node_ptr = (node_t *)dev_ptr->pend_head; + map_dev_ptr = (struct dev_info *)dev_ptr->pend_tail; + dev_ptr->pend_head = 0; + dev_ptr->pend_tail = 0; + dev_ptr->queue_state = HALTED; + dev_ptr->active_io_count--; + if(map_dev_ptr) + map_dev_ptr->active_io_count--; + if(map_node_ptr) + map_node_ptr->num_active_io--; + + dev_ptr->ioctl_event = cmd->ulpStatus; + dev_ptr->ioctl_errno = (uint32)cmd->un.grsp.perr.statLocalError; + fcpRsp = &fcptr->fcp_rsp; + dev_ptr->sense_length = SWAP_DATA(fcpRsp->rspSnsLen); + if(cmd->ulpCommand == CMD_FCP_IWRITE64_CX) { + if (cmd->ulpStatus == IOSTAT_SUCCESS) { + dev_ptr->clear_count = 1; + } + else { + dev_ptr->clear_count = 0; + } + } + else { + dev_ptr->clear_count = cmd->un.fcpi.fcpi_parm; + } + return; + } + + /* + * Is it a SCSI Report Lun command ? + */ + if ((fcptr->fcp_cmd.fcpCdb[0] == FCP_SCSI_REPORT_LUNS) && + (fcptr->flags & FCBUF_INTERNAL)) { + uchar *datap; + MBUF_INFO *mbufp; + node_t *nodep; + uint32 rptLunLen; + uint32 *datap32; + uint32 max, lun; + + mbufp = (MBUF_INFO *)fcptr->sc_bufp; + fcptr->sc_bufp = 0; + mbufp->size = 4096; + nodep = dev_ptr->nodep; + if(nodep == 0) { + fc_mem_put(binfo, MEM_IOCB, (uchar * )mbufp); + dev_ptr->active_io_count--; + fc_enq_fcbuf(fcptr); + return; + } + if ((cmd->ulpStatus == IOSTAT_SUCCESS) || + ((cmd->ulpStatus == IOSTAT_FCP_RSP_ERROR) && + (fcptr->fcp_rsp.rspStatus2 & RESID_UNDER) && + (fcptr->fcp_rsp.rspStatus3 == SCSI_STAT_GOOD))) { + + datap = (uchar *)mbufp->virt; + /* + * if Lun0 uses VSA, we assume others use too. + */ + if ((datap[8] & 0xc0) == 0x40) { + nodep->addr_mode = VOLUME_SET_ADDRESSING; + } + /* + * Skip retry + */ + datap32 = (uint32 *)mbufp->virt; + rptLunLen = SWAP_DATA(*datap32); + /* search for the max lun */ + max = 0; + for(i=0; i < rptLunLen; i+=8) { + datap32 += 2; + lun = (((* datap32) >> FC_LUN_SHIFT) & 0xff); + if(lun > max) + max = lun; + } + if(i) { + nodep->max_lun = max + 1; + } + + if(nodep->virtRptLunData == 0) { + if(rptLunLen > 8) { /* more than 1 lun */ + nodep->virtRptLunData = mbufp->virt; + nodep->physRptLunData = mbufp->phys; + } else { + fc_free(p_dev_ctl, mbufp); + } + } + } else { + datap = 0; + fc_free(p_dev_ctl, mbufp); + nodep->virtRptLunData = 0; + nodep->physRptLunData = 0; + } + + fc_mem_put(binfo, MEM_IOCB, (uchar * )mbufp); + + dev_ptr->active_io_count--; + nodep->num_active_io--; + fc_enq_fcbuf(fcptr); + + if ((datap == 0) && (!(nodep->flags & RETRY_RPTLUN))) { + nodep->flags |= RETRY_RPTLUN; + /* Wait a little bit for ABTSs to settle down */ + fc_clk_set(p_dev_ctl, 1, issue_report_lun, (void *)dev_ptr, 0); + } + else { + nodep->flags &= ~RETRY_RPTLUN; + nodep->rptlunstate = REPORT_LUN_COMPLETE; + } + return; + } + + + sbp = fcptr->sc_bufp; + bp = (struct buf *) sbp; + + + if (cmd->ulpStatus) { + fcpRsp = &fcptr->fcp_rsp; + { + uint32 did; + uint32 pan; + uint32 sid; + + if ((dev_ptr->nodep) && (dev_ptr->nodep->nlp)) { + ndlp = dev_ptr->nodep->nlp; + did = ndlp->nlp_DID; + pan = ndlp->id.nlp_pan; + sid = ndlp->id.nlp_sid; + if(ndlp->nlp_action & NLP_DO_RSCN) + qfull = 1; + } else { + did = 0; + pan = 0; + sid = 0; + } + /* FCP cmd failed on device (, ) DID */ + fc_log_printf_msg_vargs( binfo->fc_brd_no, + &fc_msgBlk0729, /* ptr to msg structure */ + fc_mes0729, /* ptr to msg */ + fc_msgBlk0729.msgPreambleStr, /* begin varargs */ + fcptr->fcp_cmd.fcpCdb[0], + FC_SCSID(pan, sid), + (uint32)(dev_ptr->lun_id), + did, + (uint32)fcpRsp->rspInfo3, + (uint32)cmd->un.grsp.perr.statLocalError, + *((uint32 *)(((uint32 *)cmd) + WD6)), /* IOCB wd 6 */ + *((uint32 *)(((uint32 *)cmd) + WD7))); /* IOCB wd 7, end varargs */ + + } + lp = (uint32 * )fcpRsp; + i = 0; + /* FCP command failed: RSP */ + fc_log_printf_msg_vargs( binfo->fc_brd_no, + &fc_msgBlk0730, /* ptr to msg structure */ + fc_mes0730, /* ptr to msg */ + fc_msgBlk0730.msgPreambleStr, /* begin varargs */ + lp[2], + lp[3], + lp[4], + lp[5]); /* end varargs */ + if (fcpRsp->rspStatus2 & RSP_LEN_VALID) { + i = SWAP_DATA(fcpRsp->rspRspLen); + } + if (fcpRsp->rspStatus2 & SNS_LEN_VALID) { + lp = (uint32 * )(((uchar * ) & fcpRsp->rspInfo0) + i); + /* FCP command failed: SNS */ + fc_log_printf_msg_vargs( binfo->fc_brd_no, + &fc_msgBlk0731, /* ptr to msg structure */ + fc_mes0731, /* ptr to msg */ + fc_msgBlk0731.msgPreambleStr, /* begin varargs */ + lp[0], + lp[1], + lp[2], + lp[3], + lp[4], + lp[5], + lp[6], + lp[7]); /* end varargs */ + if (i > sizeof(FCP_RSP)) { + cmd->ulpStatus = IOSTAT_REMOTE_STOP; + goto handle_iocb; + } + + if(binfo->fc_process_LA == 0) + goto skip4; /* link down processing */ + if (dev_ptr->first_check & FIRST_CHECK_COND) { + clp = DD_CTL.p_config[binfo->fc_brd_no]; + dev_ptr->first_check &= ~FIRST_CHECK_COND; + if((clp[CFG_FIRST_CHECK].a_current) && + (SWAP_DATA((lp[3]) & SWAP_DATA(0xFF000000)) == 0x29000000)) { + FCSTATCTR.fcpFirstCheck++; + + lp = (uint32 *)&cmd->un.ulpWord[4]; + /* Retry FCP command due to 29,00 check condition */ + fc_log_printf_msg_vargs( binfo->fc_brd_no, + &fc_msgBlk0732, /* ptr to msg structure */ + fc_mes0732, /* ptr to msg */ + fc_msgBlk0732.msgPreambleStr, /* begin varargs */ + *lp, + *(lp+1), + *(lp+2), + *(lp+3)); /* end varargs */ + fc_fcp_bufunmap(p_dev_ctl, sbp); + + + /* + * Queue this command to the head of the device's + * pending queue for processing by fc_issue_cmd. + */ + if (dev_ptr->pend_head == NULL) { /* Is queue empty? */ + dev_ptr->pend_head = sbp; + dev_ptr->pend_tail = sbp; + bp->av_forw = NULL; + fc_enq_wait(dev_ptr); + } else { /* Queue not empty */ + bp->av_forw = (struct buf *) dev_ptr->pend_head; + dev_ptr->pend_head = sbp; + } + dev_ptr->pend_count++; + dev_ptr->active_io_count--; + dev_ptr->nodep->num_active_io--; + fc_enq_fcbuf(fcptr); + return; + } + } + + fc_bcopy(((uchar * ) & fcpRsp->rspInfo0) + i, dev_ptr->sense, + MAX_FCP_SNS); + dev_ptr->sense_valid = 1; + dev_ptr->sense_length = SWAP_DATA(fcpRsp->rspSnsLen); + + } else { + if ((cmd->ulpStatus == IOSTAT_FCP_RSP_ERROR) && + ((((uchar)fcpRsp->rspStatus3) & SCSI_STATUS_MASK) == SCSI_STAT_QUE_FULL) && + (dev_ptr->qfull_retries > 0) && + (sbp->qfull_retry_count < dev_ptr->qfull_retries)) { + clp = DD_CTL.p_config[binfo->fc_brd_no]; + if (clp[CFG_DQFULL_THROTTLE].a_current) { + if (dev_ptr->fcp_cur_queue_depth > FC_MIN_QFULL) { + if(dev_ptr->active_io_count > FC_MIN_QFULL) + dev_ptr->fcp_cur_queue_depth = dev_ptr->active_io_count - 1; + else + dev_ptr->fcp_cur_queue_depth = FC_MIN_QFULL; + } + } + + fc_qfull_retry((void *)fcptr); + + sbp->qfull_retry_count++; + + dev_ptr->qfullcnt++; + dev_ptr->active_io_count--; + dev_ptr->nodep->num_active_io--; + fc_enq_fcbuf(fcptr); + return; + } + } + } else { + fcpRsp = &fcptr->fcp_rsp; + } + +handle_iocb: + + switch (cmd->ulpStatus) { + case IOSTAT_SUCCESS: + FCSTATCTR.fcpGood++; + break; + + case IOSTAT_FCP_RSP_ERROR: + /* ERROR: all is not well with the FCP Response */ + bp->b_error = EIO; + bp->b_flags |= B_ERROR; + + bp->b_resid = 0; + clp = DD_CTL.p_config[binfo->fc_brd_no]; + FCSTATCTR.fcpRspErr++; + + if(binfo->fc_process_LA == 0) + goto skip4; /* link down processing */ + + + if ((fcpRsp->rspStatus2 & RESID_UNDER) || + (fcpRsp->rspStatus2 & RESID_OVER)) { + if (fcpRsp->rspStatus2 & RESID_UNDER) { + /* This is not an error! */ + bp->b_resid = SWAP_DATA(fcpRsp->rspResId); + + bp->b_error = 0; + bp->b_flags &= ~B_ERROR; + /* FCP Read Underrun */ + fc_log_printf_msg_vargs( binfo->fc_brd_no, + &fc_msgBlk0733, /* ptr to msg structure */ + fc_mes0733, /* ptr to msg */ + fc_msgBlk0733.msgPreambleStr, /* begin varargs */ + *((uint32 *)(((uint32 *)cmd) + WD7)), /* IOCB wd 7 */ + (uint32)cmd->ulpContext, + SWAP_DATA(fcpRsp->rspResId), + cmd->un.fcpi.fcpi_parm); /* end varargs */ + } + /* Overrun already has error set */ + } + else { + if ((bp->b_flags & B_READ) && cmd->un.fcpi.fcpi_parm) { + /* This is ALWAYS a readcheck error!! */ + + /* Give Check Condition priority over Read Check */ + if (fcpRsp->rspStatus3 != SCSI_STAT_CHECK_COND) { + bp->b_error = EIO; + bp->b_flags |= B_ERROR; + bp->b_resid = bp->b_bcount; + /* FCP Read Check Error */ + fc_log_printf_msg_vargs( binfo->fc_brd_no, + &fc_msgBlk0734, /* ptr to msg structure */ + fc_mes0734, /* ptr to msg */ + fc_msgBlk0734.msgPreambleStr, /* begin varargs */ + *((uint32 *)(((uint32 *)cmd) + WD7)), /* IOCB wd 7 */ + (uint32)cmd->ulpContext, + SWAP_DATA(fcpRsp->rspResId), + cmd->un.fcpi.fcpi_parm); /* end varargs */ + } + else { + /* FCP Read Check Error with Check Condition */ + fc_log_printf_msg_vargs( binfo->fc_brd_no, + &fc_msgBlk0735, /* ptr to msg structure */ + fc_mes0735, /* ptr to msg */ + fc_msgBlk0735.msgPreambleStr, /* begin varargs */ + *((uint32 *)(((uint32 *)cmd) + WD7)), /* IOCB wd 7 */ + (uint32)cmd->ulpContext, + SWAP_DATA(fcpRsp->rspResId), + cmd->un.fcpi.fcpi_parm); /* end varargs */ + } + } + } + + /* For QUE_FULL we will delay the iodone */ + if((((uchar) fcpRsp->rspStatus3) & SCSI_STATUS_MASK) == SCSI_STAT_QUE_FULL) { + dev_ptr->qfullcnt++; + if (clp[CFG_DQFULL_THROTTLE].a_current) { + if (dev_ptr->fcp_cur_queue_depth > FC_MIN_QFULL) { + if(dev_ptr->active_io_count > 1) + dev_ptr->fcp_cur_queue_depth = dev_ptr->active_io_count - 1; + else + dev_ptr->fcp_cur_queue_depth = 1; + } + if (dev_ptr->active_io_count > FC_MIN_QFULL) { + /* + * Try out + * stop_send_io will be decreament by 1 in fc_q_depth_up(); + */ + dev_ptr->stop_send_io = clp[CFG_NO_DEVICE_DELAY].a_current; + } + } + /* FCP QUEUE Full */ + fc_log_printf_msg_vargs( binfo->fc_brd_no, + &fc_msgBlk0736, /* ptr to msg structure */ + fc_mes0736, /* ptr to msg */ + fc_msgBlk0736.msgPreambleStr, /* begin varargs */ + dev_ptr->fcp_cur_queue_depth, + dev_ptr->active_io_count, + dev_ptr->flags, + clp[CFG_DQFULL_THROTTLE].a_current); /* end varargs */ + qfull = 1; + /* Set any necessary flags for buf error */ + bp->b_error = EBUSY; + bp->b_flags |= B_ERROR; + bp->b_resid = bp->b_bcount; + } + lpfc_handle_fcp_error(pkt, fcptr, cmd); + + if ((fcpRsp->rspStatus2 & RSP_LEN_VALID) && + (fcpRsp->rspInfo3 != RSP_NO_FAILURE)) { + + /* Error detected in the FCP layer */ + sbp->status_validity = SC_ADAPTER_ERROR; + + if(clp[CFG_DELAY_RSP_ERR].a_current) + qfull = clp[CFG_DELAY_RSP_ERR].a_current; + + switch (fcpRsp->rspInfo3) { + case RSP_TM_NOT_SUPPORTED: + SET_ADAPTER_STATUS(sbp, SC_NO_DEVICE_RESPONSE) + break; + + case RSP_DATA_BURST_ERR: + case RSP_CMD_FIELD_ERR: + case RSP_RO_MISMATCH_ERR: + if (fcpRsp->rspStatus3 != SCSI_STAT_GOOD) { + sbp->status_validity = SC_SCSI_ERROR; + sbp->scsi_status = fcpRsp->rspStatus3; + if ((fcpRsp->rspStatus3 == SC_CHECK_CONDITION) || + (fcpRsp->rspStatus3 == SC_COMMAND_TERMINATED)) { + sbp->adap_q_status = SC_DID_NOT_CLEAR_Q; + } + + + break; + } + + case RSP_TM_NOT_COMPLETED: + default: + SET_ADAPTER_STATUS(sbp, SC_ADAPTER_HDW_FAILURE) + break; + } + } else if (fcpRsp->rspStatus3 != SCSI_STAT_GOOD) { + /* SCSI layer detected error */ + if (fcpRsp->rspStatus3 == SCSI_STAT_CHECK_COND) { + uint32 cc; + /* FCP error: Check condition */ + fc_log_printf_msg_vargs( binfo->fc_brd_no, + &fc_msgBlk0737, /* ptr to msg structure */ + fc_mes0737, /* ptr to msg */ + fc_msgBlk0737.msgPreambleStr, /* begin varargs */ + *((uint32 *)(((uint32 *)cmd) + WD7)), /* IOCB wd 7 */ + (uint32)cmd->ulpIoTag, + (uint32)cmd->ulpContext, + (uint32)cmd->un.grsp.perr.statLocalError); /* end varargs */ + i = SWAP_DATA(fcpRsp->rspRspLen); + lp = (uint32 * )(((uchar * ) & fcpRsp->rspInfo0) + i); + + cc = (SWAP_DATA((lp[3]) & SWAP_DATA(0xFF000000))); + switch(cc) { + case 0x29000000: /* Power on / reset */ + i = 0; + /* 29,00 Check condition received */ + fc_log_printf_msg_vargs( binfo->fc_brd_no, + &fc_msgBlk0738, /* ptr to msg structure */ + fc_mes0738, /* ptr to msg */ + fc_msgBlk0738.msgPreambleStr, /* begin varargs */ + lp[0], + lp[1], + lp[2], + lp[3]); /* end varargs */ + break; + case 0x0: /* No additional sense info */ + if((lp[3]) & SWAP_DATA(0x00FF0000)) /* if ASCQ != 0 */ + goto default_chk; + case 0x44000000: /* Internal Target failure */ + case 0x25000000: /* Login Unit Not Support */ + case 0x20000000: /* Invalid Command operation code */ + if ((cc == 0x20000000) && (fcptr->fcp_cmd.fcpCdb[0] == SCSI3_PERSISTENT_RESERVE_IN)) { + /* Check condition received ERR1 */ + fc_log_printf_msg_vargs( binfo->fc_brd_no, + &fc_msgBlk0739, /* ptr to msg structure */ + fc_mes0739, /* ptr to msg */ + fc_msgBlk0739.msgPreambleStr, /* begin varargs */ + lp[0], + lp[1], + lp[2], + lp[3]); /* end varargs */ + goto out; + } + if(clp[CFG_CHK_COND_ERR].a_current) { + /* We want to return check cond on TUR cmd */ + if (fcptr->fcp_cmd.fcpCdb[0] == FCP_SCSI_TEST_UNIT_READY) + goto default_chk; + fc_bzero((void * )dev_ptr->sense, MAX_FCP_SNS); + dev_ptr->sense_valid = 0; + dev_ptr->sense_length = 0; + fcpRsp->rspStatus3 = SC_COMMAND_TERMINATED; + bp->b_error = EIO; + bp->b_flags |= B_ERROR; + bp->b_resid = bp->b_bcount; + sbp->status_validity = SC_ADAPTER_ERROR; + SET_ADAPTER_STATUS(sbp, SC_SCSI_BUS_RESET) + i = 0; + if(clp[CFG_DELAY_RSP_ERR].a_current) + qfull = clp[CFG_DELAY_RSP_ERR].a_current; + /* Check condition received ERR2 */ + fc_log_printf_msg_vargs( binfo->fc_brd_no, + &fc_msgBlk0740, /* ptr to msg structure */ + fc_mes0740, /* ptr to msg */ + fc_msgBlk0740.msgPreambleStr, /* begin varargs */ + lp[0], + lp[1], + lp[2], + lp[3]); /* end varargs */ + goto out; + } + default: + if(clp[CFG_DELAY_RSP_ERR].a_current) + qfull = clp[CFG_DELAY_RSP_ERR].a_current; +default_chk: + i = 0; + /* Check condition received */ + fc_log_printf_msg_vargs( binfo->fc_brd_no, + &fc_msgBlk0741, /* ptr to msg structure */ + fc_mes0741, /* ptr to msg */ + fc_msgBlk0741.msgPreambleStr, /* begin varargs */ + lp[0], + lp[1], + lp[2], + lp[3]); /* end varargs */ + break; + } + } + else { + if(clp[CFG_DELAY_RSP_ERR].a_current) + qfull = clp[CFG_DELAY_RSP_ERR].a_current; + } + + sbp->status_validity = SC_SCSI_ERROR; + sbp->scsi_status = fcpRsp->rspStatus3; + if ((fcpRsp->rspStatus3 == SC_CHECK_CONDITION) || + (fcpRsp->rspStatus3 == SC_COMMAND_TERMINATED)) { + sbp->adap_q_status = SC_DID_NOT_CLEAR_Q; + + } + } + break; + + case IOSTAT_REMOTE_STOP: + /* ERROR: ABTS/ABTX by remote N_PORT */ + FCSTATCTR.fcpRemoteStop++; + bp->b_error = EIO; + bp->b_flags |= B_ERROR; + bp->b_resid = bp->b_bcount; + sbp->status_validity = SC_SCSI_ERROR; + sbp->scsi_status = SC_COMMAND_TERMINATED; + sbp->adap_q_status = SC_DID_NOT_CLEAR_Q; + + break; + + case IOSTAT_LOCAL_REJECT: + FCSTATCTR.fcpLocalErr++; + switch (cmd->un.grsp.perr.statLocalError) { + case IOERR_SEQUENCE_TIMEOUT: + FCSTATCTR.fcpLocalTmo++; + /* E_D_TOV timeout */ + bp->b_error = ETIMEDOUT; + sbp->adap_q_status = SC_DID_NOT_CLEAR_Q; + bp->b_flags |= B_ERROR; + bp->b_resid = bp->b_bcount; + sbp->status_validity = SC_ADAPTER_ERROR; + SET_ADAPTER_STATUS(sbp, SC_CMD_TIMEOUT) + break; + + case IOERR_NO_RESOURCES: + FCSTATCTR.fcpLocalNores++; + fc_qfull_retry((void *)fcptr); + dev_ptr->active_io_count--; + dev_ptr->nodep->num_active_io--; + fc_enq_fcbuf(fcptr); + return; + case IOERR_BUFFER_SHORTAGE: + FCSTATCTR.fcpLocalBufShort++; + /* The adapter is too busy to deal with this command */ + bp->b_error = EBUSY; + bp->b_flags |= B_ERROR; + bp->b_resid = bp->b_bcount; + sbp->status_validity = 0; + break; + + case IOERR_MISSING_CONTINUE: + case IOERR_ILLEGAL_COMMAND: + case IOERR_ILLEGAL_FIELD: + case IOERR_BAD_CONTINUE: + case IOERR_TOO_MANY_BUFFERS: + case IOERR_EXTRA_DATA: + case IOERR_ILLEGAL_LENGTH: + case IOERR_UNSUPPORTED_FEATURE: + /* Let's call these driver software errors */ + qfull = 1; + FCSTATCTR.fcpLocalSfw++; + bp->b_error = EINVAL; + bp->b_flags |= B_ERROR; + bp->b_resid = bp->b_bcount; + sbp->status_validity = 0; + + { + uint32 did; + + did = 0; + if ((dev_ptr->nodep) && (dev_ptr->nodep->nlp)) + did = dev_ptr->nodep->nlp->nlp_DID; + /* FCP completion error */ + fc_log_printf_msg_vargs( binfo->fc_brd_no, + &fc_msgBlk0742, /* ptr to msg structure */ + fc_mes0742, /* ptr to msg */ + fc_msgBlk0742.msgPreambleStr, /* begin varargs */ + cmd->ulpStatus, + cmd->un.ulpWord[4], + did ); /* end varargs */ + } + break; + + case IOERR_TX_DMA_FAILED: + FCSTATCTR.fcpLocalTxDMA++; + goto skip2; + case IOERR_RX_DMA_FAILED: + FCSTATCTR.fcpLocalRxDMA++; + goto skip2; + case IOERR_INTERNAL_ERROR: + FCSTATCTR.fcpLocalinternal++; + goto skip2; + case IOERR_CORRUPTED_DATA: + case IOERR_CORRUPTED_RPI: + FCSTATCTR.fcpLocalCorrupt++; +skip2: + /* Let's call these adapter hardware errors */ + bp->b_error = EIO; + bp->b_flags |= B_ERROR; + bp->b_resid = bp->b_bcount; + sbp->status_validity = SC_ADAPTER_ERROR; + SET_ADAPTER_STATUS(sbp, SC_ADAPTER_HDW_FAILURE) + + { + uint32 did; + + did = 0; + if ((dev_ptr->nodep) && (dev_ptr->nodep->nlp)) + did = dev_ptr->nodep->nlp->nlp_DID; + /* FCP completion error */ + fc_log_printf_msg_vargs( binfo->fc_brd_no, + &fc_msgBlk0743, /* ptr to msg structure */ + fc_mes0743, /* ptr to msg */ + fc_msgBlk0743.msgPreambleStr, /* begin varargs */ + cmd->ulpStatus, + cmd->un.ulpWord[4], + did ); /* end varargs */ + } + + break; + + case IOERR_ILLEGAL_FRAME: + FCSTATCTR.fcpLocalIllFrm++; + goto skip3; + case IOERR_DUP_FRAME: + FCSTATCTR.fcpLocalDupFrm++; + goto skip3; + case IOERR_LINK_CONTROL_FRAME: + FCSTATCTR.fcpLocalLnkCtlFrm++; +skip3: + qfull = 1; + /* Let's call these device hardware errors */ + bp->b_error = EINVAL; + bp->b_flags |= B_ERROR; + bp->b_resid = bp->b_bcount; + sbp->status_validity = 0; + + { + uint32 did; + + did = 0; + if ((dev_ptr->nodep) && (dev_ptr->nodep->nlp)) + did = dev_ptr->nodep->nlp->nlp_DID; + + lp = (uint32 *)&cmd->un.ulpWord[4]; + /* FCP completion error */ + fc_log_printf_msg_vargs( binfo->fc_brd_no, + &fc_msgBlk0744, /* ptr to msg structure */ + fc_mes0744, /* ptr to msg */ + fc_msgBlk0744.msgPreambleStr, /* begin varargs */ + did, + *lp, + *(lp+2), + *(lp+3) ); /* end varargs */ + } + + break; + + case IOERR_LOOP_OPEN_FAILURE: + FCSTATCTR.fcpLocalLoopOpen++; + /* The device disappeared from the loop! */ + qfull = 1; + bp->b_error = EIO; + bp->b_flags |= B_ERROR; + bp->b_resid = bp->b_bcount; + sbp->status_validity = SC_ADAPTER_ERROR; + SET_ADAPTER_STATUS(sbp, SC_NO_DEVICE_RESPONSE) + if(dev_ptr->nodep && (dev_ptr->nodep->flags & FC_NODEV_TMO)) { + break; + } + if(binfo->fc_ffstate != FC_READY) { + break; + } + /* Will HALT, CLEARQ, and kick off discovery, below */ + /* Try to relogin, and if unsuccessful reject future cmds */ + if((ndlp == 0) && dev_ptr->nodep) + ndlp = fc_findnode_rpi(binfo, (uint32)dev_ptr->nodep->rpi); + + if ((ndlp) && !(ndlp->nlp_flag & (NLP_NODEV_TMO | NLP_REQ_SND))) { + ndlp->nlp_flag &= ~NLP_RM_ENTRY; + /* We are in FC_READY state */ + if (!(ndlp->nlp_action & NLP_DO_RSCN)) { + binfo->fc_flag |= FC_RSCN_MODE; + ndlp->nlp_action |= NLP_DO_RSCN; + fc_nextrscn(p_dev_ctl, 1); + } + } + break; + + case IOERR_INVALID_RPI: + FCSTATCTR.fcpLocalInvalRpi++; + goto skip4; + case IOERR_LINK_DOWN: + FCSTATCTR.fcpLocalLinkDown++; +skip4: + /* Retry these failures */ + qfull=1; + bp->b_error = EIO; + bp->b_flags |= B_ERROR; + bp->b_resid = bp->b_bcount; + sbp->status_validity = SC_ADAPTER_ERROR; + SET_ADAPTER_STATUS(sbp, SC_SCSI_BUS_RESET) + break; + + case IOERR_OUT_OF_ORDER_DATA: + case IOERR_OUT_OF_ORDER_ACK: + FCSTATCTR.fcpLocalOOO++; + /* Retry these failures */ + bp->b_error = ENXIO; + bp->b_flags |= B_ERROR; + bp->b_resid = bp->b_bcount; + sbp->status_validity = 0; + break; + + case IOERR_ABORT_IN_PROGRESS: + FCSTATCTR.fcpLocalAbtInp++; + goto skip5; + case IOERR_ABORT_REQUESTED: + FCSTATCTR.fcpLocalAbtReq++; +skip5: + /* Abort requested by us */ + if (fcptr->flags & FCBUF_ABTS) { + /* ABTS sent because of operation timeout */ + bp->b_error = ETIMEDOUT; + sbp->status_validity = SC_ADAPTER_ERROR; + SET_ADAPTER_STATUS(sbp, SC_CMD_TIMEOUT) + } else { + bp->b_error = ENXIO; + sbp->status_validity = 0; + } + bp->b_flags |= B_ERROR; + bp->b_resid = bp->b_bcount; + break; + + case IOERR_SUCCESS: + case IOERR_NO_XRI: + case IOERR_XCHG_DROPPED: + case IOERR_RCV_BUFFER_WAITING: + case IOERR_RECEIVE_BUFFER_TIMEOUT: + case IOERR_RING_RESET: + case IOERR_BAD_HOST_ADDRESS: + case IOERR_RCV_HDRBUF_WAITING: + case IOERR_MISSING_HDR_BUFFER: + case IOERR_MSEQ_CHAIN_CORRUPTED: + case IOERR_ABORTMULT_REQUESTED: + default: + FCSTATCTR.fcpLocal++; + bp->b_error = EIO; + bp->b_flags |= B_ERROR; + bp->b_resid = bp->b_bcount; + sbp->status_validity = SC_ADAPTER_ERROR; + SET_ADAPTER_STATUS(sbp, SC_NO_DEVICE_RESPONSE) + + { + uint32 did; + + did = 0; + if ((dev_ptr->nodep) && (dev_ptr->nodep->nlp)) + did = dev_ptr->nodep->nlp->nlp_DID; + /* FCP completion error */ + fc_log_printf_msg_vargs( binfo->fc_brd_no, + &fc_msgBlk0745, /* ptr to msg structure */ + fc_mes0745, /* ptr to msg */ + fc_msgBlk0745.msgPreambleStr, /* begin varargs */ + cmd->ulpStatus, + cmd->un.ulpWord[4], + did ); /* end varargs */ + } + break; + } + break; + + case IOSTAT_NPORT_RJT: + case IOSTAT_FABRIC_RJT: + FCSTATCTR.fcpPortRjt++; + /* The fabric or port rejected this command */ + if (cmd->un.grsp.perr.statAction == RJT_RETRYABLE) { + bp->b_error = ENXIO; + sbp->status_validity = SC_SCSI_ERROR; + sbp->scsi_status = SC_BUSY_STATUS; + } else { + bp->b_error = EIO; + sbp->status_validity = 0; + } + bp->b_flags |= B_ERROR; + bp->b_resid = bp->b_bcount; + break; + + case IOSTAT_NPORT_BSY: + case IOSTAT_FABRIC_BSY: + FCSTATCTR.fcpPortBusy++; + /* The fabric or port is too busy to deal with this command */ + bp->b_error = ENXIO; + bp->b_flags |= B_ERROR; + bp->b_resid = bp->b_bcount; + sbp->status_validity = SC_SCSI_ERROR; + sbp->scsi_status = SC_BUSY_STATUS; + break; + + case IOSTAT_INTERMED_RSP: + case IOSTAT_LS_RJT: + case IOSTAT_BA_RJT: + default: + FCSTATCTR.fcpError++; + /* ERROR: None of these errors should occur! */ + bp->b_error = EIO; + bp->b_flags |= B_ERROR; + bp->b_resid = bp->b_bcount; + sbp->status_validity = SC_ADAPTER_ERROR; + SET_ADAPTER_STATUS(sbp, SC_NO_DEVICE_RESPONSE) + + { + uint32 did; + + did = 0; + if ((dev_ptr->nodep) && (dev_ptr->nodep->nlp)) + did = dev_ptr->nodep->nlp->nlp_DID; + /* FCP completion error */ + fc_log_printf_msg_vargs( binfo->fc_brd_no, + &fc_msgBlk0746, /* ptr to msg structure */ + fc_mes0746, /* ptr to msg */ + fc_msgBlk0746.msgPreambleStr, /* begin varargs */ + cmd->ulpStatus, + cmd->un.ulpWord[4], + did ); /* end varargs */ + } + break; + } +out: + + if (fcptr->fcp_cmd.fcpCntl2) + { + /* This is a task management command */ + if (bp->b_flags & B_ERROR) + dev_ptr->ioctl_errno = bp->b_error; + else + dev_ptr->ioctl_errno = 0; + + + + if (fcptr->fcp_cmd.fcpCntl2 & TARGET_RESET) { + /* Cmpl Target Reset */ + fc_log_printf_msg_vargs( binfo->fc_brd_no, + &fc_msgBlk0747, /* ptr to msg structure */ + fc_mes0747, /* ptr to msg */ + fc_msgBlk0747.msgPreambleStr, /* begin varargs */ + (uint32)dev_ptr->nodep->scsi_id, + (uint32)dev_ptr->lun_id, + (uint32)cmd->un.grsp.perr.statLocalError, + *((uint32 *)(((uint32 *)cmd) + WD7))); /* end varargs */ + clp = DD_CTL.p_config[binfo->fc_brd_no]; + dev_ptr->flags &= ~SCSI_TARGET_RESET; + for (next_dev_ptr = dev_ptr->nodep->lunlist; next_dev_ptr != NULL; + next_dev_ptr = next_dev_ptr->next) { + + next_dev_ptr->flags &= ~SCSI_TARGET_RESET; + /* First send ABTS on any outstanding I/O in txp queue */ + fc_abort_fcp_txpq(binfo, next_dev_ptr); + fc_fail_cmd(next_dev_ptr, ENXIO, STAT_DEV_RESET); + next_dev_ptr->fcp_cur_queue_depth = + (ushort)clp[CFG_DFT_LUN_Q_DEPTH].a_current; + if (next_dev_ptr->ioctl_wakeup == 0) + fc_restart_device(next_dev_ptr); + } + } + + if (fcptr->fcp_cmd.fcpCntl2 & LUN_RESET) { + /* Cmpl LUN Reset */ + fc_log_printf_msg_vargs( binfo->fc_brd_no, + &fc_msgBlk0748, /* ptr to msg structure */ + fc_mes0748, /* ptr to msg */ + fc_msgBlk0748.msgPreambleStr, /* begin varargs */ + (uint32)dev_ptr->nodep->scsi_id, + (uint32)dev_ptr->lun_id, + (uint32)cmd->un.grsp.perr.statLocalError, + *((uint32 *)(((uint32 *)cmd) + WD7))); /* end varargs */ + dev_ptr->flags &= ~SCSI_LUN_RESET; + /* First send ABTS on any outstanding I/O in txp queue */ + fc_abort_fcp_txpq(binfo, dev_ptr); + fc_fail_cmd(dev_ptr, ENXIO, STAT_DEV_RESET); + if (dev_ptr->ioctl_wakeup == 0) + fc_restart_device(dev_ptr); + } + + if (fcptr->fcp_cmd.fcpCntl2 & ABORT_TASK_SET) { + /* Cmpl Abort Task Set */ + fc_log_printf_msg_vargs( binfo->fc_brd_no, + &fc_msgBlk0749, /* ptr to msg structure */ + fc_mes0749, /* ptr to msg */ + fc_msgBlk0749.msgPreambleStr, /* begin varargs */ + (uint32)dev_ptr->nodep->scsi_id, + (uint32)dev_ptr->lun_id, + (uint32)cmd->un.grsp.perr.statLocalError, + *((uint32 *)(((uint32 *)cmd) + WD7))); /* end varargs */ + dev_ptr->flags &= ~SCSI_ABORT_TSET; + /* First send ABTS on any outstanding I/O in txp queue */ + fc_abort_fcp_txpq(binfo, dev_ptr); + fc_fail_cmd(dev_ptr, ENXIO, STAT_DEV_RESET); + if (dev_ptr->ioctl_wakeup == 0) + fc_restart_device(dev_ptr); + } + + if (dev_ptr->ioctl_wakeup == 1) { + dev_ptr->ioctl_wakeup = 0; + fc_admin_wakeup(p_dev_ctl, dev_ptr, sbp); + } + } else { + if ((bp->b_flags & B_ERROR) && + (dev_ptr->queue_state != STOPPING)) { + /* An error has occurred, so halt the queues */ + sbp->adap_q_status = SC_DID_NOT_CLEAR_Q; + if(qfull) + fc_delay_iodone(p_dev_ctl, sbp); + else + fc_do_iodone(bp); + } else { + if(qfull) + fc_delay_iodone(p_dev_ctl, sbp); + else + fc_do_iodone(bp); + } + } + + + dev_ptr->active_io_count--; + dev_ptr->nodep->num_active_io--; + fc_enq_fcbuf(fcptr); + + + if ((dev_ptr->nodep->tgt_queue_depth) && + (dev_ptr->nodep->tgt_queue_depth == dev_ptr->nodep->num_active_io)) { + re_issue_fcp_cmd(dev_ptr->nodep->last_dev); + } + return; +} /* End handle_fcp_event */ + + +int +fc_delay_iodone( +fc_dev_ctl_t *p_dev_ctl, +T_SCSIBUF * sbp) +{ + FC_BRD_INFO * binfo; + iCfgParam * clp; + uint32 tmout; + + binfo = &BINFO; + clp = DD_CTL.p_config[binfo->fc_brd_no]; + + if(clp[CFG_NO_DEVICE_DELAY].a_current) { + /* Need to set a timer so iodone can be called + * for buffer upon expiration. + */ + tmout = clp[CFG_NO_DEVICE_DELAY].a_current; + + if(fc_clk_set(p_dev_ctl, tmout, + lpfc_scsi_selto_timeout, (void *)sbp, 0) != 0) + return(1); + } + fc_do_iodone((struct buf *)sbp); + return(0); +} /* End fc_delay_iodone */ + + +/**********************************************/ +/** handle_iprcv_seq **/ +/** **/ +/**********************************************/ +_static_ int +handle_iprcv_seq( +fc_dev_ctl_t *p_dev_ctl, +RING *rp, +IOCBQ *temp) +{ + MAILBOXQ * mb; + FC_BRD_INFO * binfo; + IOCB * cmd = 0; + IOCB * savecmd; + IOCBQ * savetemp; + NETHDR * nh; + fcipbuf_t * p_mbuf, *mp, *last_mp; + ndd_t * p_ndd; + NODELIST * ndlp; + MATCHMAP * matp; + uchar * daddr; + uchar * saddr; + int count, i, la; + + binfo = &BINFO; + p_ndd = (ndd_t * ) & (NDD); + + p_mbuf = 0; + matp = (MATCHMAP *)0; /* prevent compiler warning */ + + if (++NDDSTAT.ndd_recvintr_lsw == 0) { + NDDSTAT.ndd_recvintr_msw++; + } + + mp = 0; + last_mp = 0; + count = 0; + la = 0; + + savetemp = temp; + if (binfo->fc_ffstate < FC_READY) { + if (binfo->fc_ffstate < rp->fc_xmitstate) { + goto dropout; + } + la = 1; + } + + savecmd = &temp->iocb; + while (temp) { + cmd = &temp->iocb; + if (cmd->ulpStatus) { + if ((cmd->ulpStatus == IOSTAT_LOCAL_REJECT) && + ((cmd->un.ulpWord[4] & 0xff) == IOERR_RCV_BUFFER_WAITING)) { + FCSTATCTR.NoRcvBuf++; + if(!(binfo->fc_flag & FC_NO_RCV_BUF)) { + /* IP Response Ring out of posted buffers */ + fc_log_printf_msg_vargs( binfo->fc_brd_no, + &fc_msgBlk0602, /* ptr to msg structure */ + fc_mes0602, /* ptr to msg */ + fc_msgBlk0602.msgPreambleStr, /* begin varargs */ + rp->fc_ringno, + rp->fc_missbufcnt, + FCSTATCTR.NoRcvBuf); /* end varargs */ + } + binfo->fc_flag |= FC_NO_RCV_BUF; + + fc_post_mbuf(p_dev_ctl, rp, 0); + } + else + NDDSTAT.ndd_ierrors++; +dropout: + NDDSTAT.ndd_ipackets_drop++; + fc_free_iocb_buf(p_dev_ctl, rp, savetemp); + if (p_mbuf) { + m_freem(p_mbuf); + } + return(0); + } + + if (cmd->ulpBdeCount == 0) { + temp = (IOCBQ * )temp->q; + continue; + } + for (i = 0; i < (int)cmd->ulpBdeCount; i++) { + matp = fc_getvaddr(p_dev_ctl, rp, (uchar *) + getPaddr(cmd->un.cont64[i].addrHigh, cmd->un.cont64[i].addrLow)); + if (matp == 0) { + uchar *bdeAddr; + + bdeAddr = (uchar *)getPaddr(cmd->un.cont64[0].addrHigh, + cmd->un.cont64[0].addrLow); + goto dropout; + } + + mp = (fcipbuf_t * )matp; + if (last_mp) { + fcnextdata(last_mp) = mp; + } else { + p_mbuf = mp; + } + last_mp = mp; + fcnextdata(mp) = 0; + fcsetdatalen(mp, cmd->un.cont64[i].tus.f.bdeSize); + count += cmd->un.cont64[i].tus.f.bdeSize; + } + + fc_post_mbuf(p_dev_ctl, rp, i); + cmd->ulpBdeCount = 0; + temp = (IOCBQ * )temp->q; + } + + if (p_mbuf == 0) { + goto dropout; + } + + binfo->fc_flag &= ~FC_NO_RCV_BUF; + + /* Set any IP buffer flags to indicate a recieve buffer, if needed */ + + if (++NDDSTAT.ndd_ipackets_lsw == 0) + NDDSTAT.ndd_ipackets_msw++; + + NDDSTAT.ndd_ibytes_lsw += count; + if ((int)NDDSTAT.ndd_ibytes_lsw < count) + NDDSTAT.ndd_ibytes_msw++; + nh = (NETHDR * )fcdata(p_mbuf); + + if(lpfc_nethdr == 0) { + emac_t * ep; + + /* Adjust mbuf count now */ + count -= 2; + + fcpktlen(p_mbuf) = count; /* total data in mbuf */ + fcincdatalen(p_mbuf, -2); + + fcdata(p_mbuf) += 2; + ep = (emac_t * )(fcdata(p_mbuf)); + daddr = (uchar *)ep->dest_addr; + saddr = (uchar *)ep->src_addr; + ep->llc_len = (count - sizeof(emac_t)); + } + else { + NETHDR * np; + + np = (NETHDR * )(fcdata(p_mbuf)); + daddr = np->fc_destname.IEEE; + saddr = np->fc_srcname.IEEE; + fcpktlen(p_mbuf) = count; /* total data in mbuf */ + } + + if (count < (HDR_LEN + sizeof(snaphdr_t))) + goto dropout; + + /* If this is first broadcast received from that address */ + if (savecmd->un.xrseq.w5.hcsw.Fctl & BC) { +bcst: + FCSTATCTR.frameRcvBcast++; + if (++NDDSTAT.ndd_ifInBcastPkts_lsw == 0) + NDDSTAT.ndd_ifInBcastPkts_msw++; + + fc_bcopy((char *)fcbroadcastaddr, (char *)daddr, MACADDR_LEN); + + if ((ndlp = fc_findnode_odid(binfo, NLP_SEARCH_ALL, + (uint32)savecmd->un.xrseq.xrsqRo)) == 0) { + + /* Need to cache the did / portname */ + if((ndlp = (NODELIST *)fc_mem_get(binfo, MEM_NLP))) { + fc_bzero((void *)ndlp, sizeof(NODELIST)); + ndlp->sync = binfo->fc_sync; + ndlp->capabilities = binfo->fc_capabilities; + ndlp->nlp_DID = savecmd->un.xrseq.xrsqRo; + fc_bcopy(&nh->fc_srcname, &ndlp->nlp_portname, sizeof(NAME_TYPE)); + ndlp->nlp_state = NLP_LIMBO; + fc_nlp_bind(binfo, ndlp); + } + else { + goto dropout; + } + } + } else { + if ((ndlp = binfo->fc_nlplookup[savecmd->ulpIoTag]) == 0) { + if(nh->fc_destname.IEEE[0] == 0xff) { + if((nh->fc_destname.IEEE[1] == 0xff) && + (nh->fc_destname.IEEE[2] == 0xff) && + (nh->fc_destname.IEEE[3] == 0xff) && + (nh->fc_destname.IEEE[4] == 0xff) && + (nh->fc_destname.IEEE[5] == 0xff)) { + goto bcst; + } + } + /* Need to send LOGOUT for this RPI */ + if ((mb = (MAILBOXQ * )fc_mem_get(binfo, MEM_MBOX))) { + fc_read_rpi(binfo, (uint32)savecmd->ulpIoTag, + (MAILBOX * )mb, (uint32)ELS_CMD_LOGO); + if (issue_mb_cmd(binfo, (MAILBOX * )mb, MBX_NOWAIT) != MBX_BUSY) { + fc_mem_put(binfo, MEM_MBOX, (uchar * )mb); + } + } + goto dropout; + } + } + + + if(lpfc_nethdr == 0) { + fc_bcopy(ndlp->nlp_portname.IEEE, (char *)saddr, MACADDR_LEN); + } + if ((p_dev_ctl->device_state != OPENED) || + (p_ndd->nd_receive == 0)) { + goto dropout; + } + ndlp->nlp_type |= NLP_IP_NODE; + + unlock_enable(FC_LVL, &CMD_LOCK); + (*(p_ndd->nd_receive))(p_ndd, p_mbuf, p_dev_ctl); + i = disable_lock(FC_LVL, &CMD_LOCK); + + return(1); +} /* End handle_iprcv_seq */ + +/**********************************************/ +/** handle_elsrcv_seq **/ +/** **/ +/**********************************************/ +_static_ int +handle_elsrcv_seq( +fc_dev_ctl_t *p_dev_ctl, +RING *rp, +IOCBQ *temp) +{ + FC_BRD_INFO * binfo; + IOCB * cmd = 0; + IOCB * savecmd; + IOCBQ * savetemp; + MATCHMAP * p_mbuf, *last_mp; + ndd_t * p_ndd; + MATCHMAP * matp; + uint32 ctx; + int count, i, la; + + binfo = &BINFO; + p_ndd = (ndd_t * ) & (NDD); + + p_mbuf = 0; + matp = (MATCHMAP *)0; /* prevent compiler warning */ + + last_mp = 0; + count = 0; + la = 0; + + savetemp = temp; + if (binfo->fc_ffstate < FC_READY) { + goto dropout; + } + + ctx = 0; + savecmd = &temp->iocb; + while (temp) { + cmd = &temp->iocb; + if(ctx == 0) + ctx = (uint32)(cmd->ulpContext); + if (cmd->ulpStatus) { + if ((cmd->ulpStatus == IOSTAT_LOCAL_REJECT) && + ((cmd->un.ulpWord[4] & 0xff) == IOERR_RCV_BUFFER_WAITING)) { + FCSTATCTR.NoRcvBuf++; + if(!(binfo->fc_flag & FC_NO_RCV_BUF)) { + /* Rcv Ring out of posted buffers */ + fc_log_printf_msg_vargs( binfo->fc_brd_no, + &fc_msgBlk0603, /* ptr to msg structure */ + fc_mes0603, /* ptr to msg */ + fc_msgBlk0603.msgPreambleStr, /* begin varargs */ + rp->fc_ringno, + rp->fc_missbufcnt, + FCSTATCTR.NoRcvBuf); /* end varargs */ + } + binfo->fc_flag |= FC_NO_RCV_BUF; + + fc_post_buffer(p_dev_ctl, rp, 0); + } + goto dropout; + } + + if (cmd->ulpBdeCount == 0) { + temp = (IOCBQ * )temp->q; + continue; + } + for (i = 0; i < (int)cmd->ulpBdeCount; i++) { + matp = fc_getvaddr(p_dev_ctl, rp, (uchar *) + getPaddr(cmd->un.cont64[i].addrHigh, cmd->un.cont64[i].addrLow)); + if (matp == 0) { + uchar *bdeAddr; + + bdeAddr = (uchar *)getPaddr(cmd->un.cont64[0].addrHigh, + cmd->un.cont64[0].addrLow); + + goto dropout; + } + + /* Typically for Unsolicited CT requests */ + + if (last_mp) { + last_mp->fc_mptr = (void *)matp; + } else { + p_mbuf = matp; + } + last_mp = matp; + matp->fc_mptr = 0; + count += cmd->un.cont64[i].tus.f.bdeSize; + } + + fc_post_buffer(p_dev_ctl, rp, i); + cmd->ulpBdeCount = 0; + temp = (IOCBQ * )temp->q; + } + + if (p_mbuf == 0) { + goto dropout; + } + binfo->fc_flag &= ~FC_NO_RCV_BUF; + if(dfc_put_event(p_dev_ctl, FC_REG_CT_EVENT, ctx, (void *)p_mbuf, (void *)((ulong)count))) { + fc_free_iocb_buf(p_dev_ctl, rp, savetemp); + return(0); + } + +dropout: + fc_free_iocb_buf(p_dev_ctl, rp, savetemp); + while (p_mbuf) { + matp = p_mbuf; + p_mbuf = (MATCHMAP *)matp->fc_mptr; + fc_mem_put(binfo, MEM_BUF, (uchar * )matp); + } + return(0); +} /* End handle_elsrcv_seq */ + + +/**************************************************/ +/** fc_post_buffer **/ +/** **/ +/** This routine will post count buffers to the **/ +/** ring with the QUE_RING_BUF_CN command. This **/ +/** allows 3 buffers / command to be posted. **/ +/** Returns the number of buffers NOT posted. **/ +/**************************************************/ +_static_ int +fc_post_buffer( +fc_dev_ctl_t *p_dev_ctl, +RING *rp, +int cnt) +{ + IOCB * icmd; + IOCBQ * temp; + int i, j; + ushort tag; + ushort maxqbuf; + MATCHMAP * mp; + FC_BRD_INFO * binfo; + + binfo = &BINFO; + mp = 0; + if (binfo->fc_flag & FC_SLI2) + maxqbuf = 2; + else + maxqbuf = 3; + + tag = (ushort)cnt; + cnt += rp->fc_missbufcnt; + /* While there are buffers to post */ + while (cnt) { + if ((temp = (IOCBQ * )fc_mem_get(binfo, MEM_IOCB)) == 0) { + rp->fc_missbufcnt = cnt; + return(cnt); + } + fc_bzero((void *)temp, sizeof(IOCBQ)); + icmd = &temp->iocb; + + /* Max buffers can be posted per command */ + for (i = 0; i < maxqbuf; i++) { + if (cnt <= 0) + break; + + /* fill in BDEs for command */ + if ((mp = (MATCHMAP * )fc_mem_get(binfo, MEM_BUF)) == 0) { + icmd->ulpBdeCount = i; + for (j = 0; j < i; j++) { + if (binfo->fc_flag & FC_SLI2) { + mp = fc_getvaddr(p_dev_ctl, rp, + (uchar * )getPaddr(icmd->un.cont64[j].addrHigh, + icmd->un.cont64[j].addrLow)); + } + else { + mp = fc_getvaddr(p_dev_ctl, rp, + (uchar * )((ulong)icmd->un.cont[j].bdeAddress)); + } + if (mp) { + fc_mem_put(binfo, MEM_BUF, (uchar * )mp); + } + } + + rp->fc_missbufcnt = cnt + i; + fc_mem_put(binfo, MEM_IOCB, (uchar * )temp); + return(cnt + i); + } + + /* map that page and save the address pair for lookup later */ + if (binfo->fc_flag & FC_SLI2) { + fc_mapvaddr(binfo, rp, mp, + (uint32 *) & icmd->un.cont64[i].addrHigh, + (uint32 *) & icmd->un.cont64[i].addrLow); + icmd->un.cont64[i].tus.f.bdeSize = FCELSSIZE; + icmd->ulpCommand = CMD_QUE_RING_BUF64_CN; + } else { + fc_mapvaddr(binfo, rp, mp, + 0, (uint32 *) & icmd->un.cont[i].bdeAddress); + icmd->un.cont[i].bdeSize = FCELSSIZE; + icmd->ulpCommand = CMD_QUE_RING_BUF_CN; + } + cnt--; + } + + icmd->ulpIoTag = tag; + icmd->ulpBdeCount = i; + icmd->ulpLe = 1; + + icmd->ulpOwner = OWN_CHIP; + + temp->bp = (uchar * )mp; /* used for delimiter between commands */ + + + FCSTATCTR.cmdQbuf++; + issue_iocb_cmd(binfo, rp, temp); + } + + rp->fc_missbufcnt = 0; + return(0); +} /* End fc_post_buffer */ + + +/**************************************************/ +/** fc_post_mbuf **/ +/** **/ +/** This routine will post count buffers to the **/ +/** ring with the QUE_RING_BUF_CN command. This **/ +/** allows 3 buffers / command to be posted. **/ +/** Returns the number of buffers NOT posted. **/ +/**************************************************/ +_static_ int +fc_post_mbuf( +fc_dev_ctl_t *p_dev_ctl, +RING *rp, +int cnt) +{ + FC_BRD_INFO * binfo; + IOCB * icmd; + IOCBQ * temp; + int i, j; + ushort tag; + ushort maxqbuf; + fcipbuf_t * mp; + + binfo = &BINFO; + mp = 0; + if (binfo->fc_flag & FC_SLI2) + maxqbuf = 2; + else + maxqbuf = 3; + + tag = (ushort)cnt; + cnt += rp->fc_missbufcnt; + /* While there are buffers to post */ + while (cnt) { + if ((temp = (IOCBQ * )fc_mem_get(binfo, MEM_IOCB)) == 0) { + rp->fc_missbufcnt = cnt; + return(cnt); + } + fc_bzero((void *)temp, sizeof(IOCBQ)); + icmd = &temp->iocb; + + /* Max buffers can be posted per command */ + for (i = 0; i < maxqbuf; i++) { + if (cnt <= 0) + break; + + /* fill in BDEs for command */ + if ((mp = (fcipbuf_t * )m_getclust(M_DONTWAIT, MT_DATA)) == 0) { + +out: + /* Post buffer for IP ring failed */ + fc_log_printf_msg_vargs( binfo->fc_brd_no, + &fc_msgBlk0604, /* ptr to msg structure */ + fc_mes0604, /* ptr to msg */ + fc_msgBlk0604.msgPreambleStr, /* begin varargs */ + rp->fc_ringno, + rp->fc_missbufcnt); /* end varargs */ + icmd->ulpBdeCount = i; + for (j = 0; j < i; j++) { + if (binfo->fc_flag & FC_SLI2) { + mp = (fcipbuf_t * )fc_getvaddr(p_dev_ctl, rp, + (uchar * )getPaddr(icmd->un.cont64[j].addrHigh, + icmd->un.cont64[j].addrLow)); + } + else { + mp = (fcipbuf_t * )fc_getvaddr(p_dev_ctl, rp, + (uchar * )((ulong)icmd->un.cont[j].bdeAddress)); + } + if (mp) { + fcnextdata(mp) = 0; + fcnextpkt(mp) = 0; + m_freem(mp); + } + } + + rp->fc_missbufcnt = cnt + i; + fc_mem_put(binfo, MEM_IOCB, (uchar * )temp); + return(cnt + i); + } + { + MBUF_INFO * buf_info; + MBUF_INFO bufinfo; + + buf_info = &bufinfo; + buf_info->virt = (uint32 * )fcdata(mp); + buf_info->size = fcPAGESIZE; + buf_info->flags = (FC_MBUF_PHYSONLY | FC_MBUF_DMA); + buf_info->align = 0; + buf_info->dma_handle = 0; + + /* Map page of memory associated with m_data for read/write */ + fc_malloc(p_dev_ctl, buf_info); + if (buf_info->phys == NULL) { + /* mapping that page failed */ + goto out; + } + fcnextpkt(mp) = (fcipbuf_t * )buf_info->phys; + fcsethandle(mp, buf_info->dma_handle); + } + /* map that page and save the address pair for lookup later */ + if (binfo->fc_flag & FC_SLI2) { + fc_mapvaddr(binfo, rp, (MATCHMAP * )mp, + (uint32 *) & icmd->un.cont64[i].addrHigh, + (uint32 *) & icmd->un.cont64[i].addrLow); + icmd->un.cont64[i].tus.f.bdeSize = FC_RCV_BUF_SIZE; + icmd->ulpCommand = CMD_QUE_RING_BUF64_CN; + } else { + fc_mapvaddr(binfo, rp, (MATCHMAP * )mp, + 0, (uint32 *) & icmd->un.cont[i].bdeAddress); + icmd->un.cont[i].bdeSize = FC_RCV_BUF_SIZE; + icmd->ulpCommand = CMD_QUE_RING_BUF_CN; + } + cnt--; + } + + icmd->ulpIoTag = tag; + icmd->ulpBdeCount = i; + icmd->ulpLe = 1; + + icmd->ulpOwner = OWN_CHIP; + + temp->bp = (uchar * )mp; /* used for delimiter between commands */ + + FCSTATCTR.cmdQbuf++; + issue_iocb_cmd(binfo, rp, temp); + } + + rp->fc_missbufcnt = 0; + return(0); +} /* End fc_post_mbuf */ + + +_static_ int +fc_free_iocb_buf( +fc_dev_ctl_t *p_dev_ctl, +RING *rp, +IOCBQ *temp) +{ + FC_BRD_INFO * binfo; + IOCB * cmd; + int i; + MATCHMAP * mp; + + binfo = &BINFO; + while (temp) { + cmd = &temp->iocb; + for (i = 0; i < (int)cmd->ulpBdeCount; i++) { + if (binfo->fc_flag & FC_SLI2) { + mp = fc_getvaddr(p_dev_ctl, rp, (uchar * ) + getPaddr(cmd->un.cont64[i].addrHigh, cmd->un.cont64[i].addrLow)); + } + else { + mp = fc_getvaddr(p_dev_ctl, rp, (uchar * )((ulong)cmd->un.cont[i].bdeAddress)); + } + + if (mp) { + if (rp->fc_ringno == FC_ELS_RING) { + fc_mem_put(binfo, MEM_BUF, (uchar * )mp); + } + else if (rp->fc_ringno == FC_IP_RING) { + fcipbuf_t * mbuf; + + mbuf = (fcipbuf_t * )mp; + fcnextdata(mbuf) = 0; + fcnextpkt(mbuf) = 0; + m_freem(mbuf); + } + } + } + switch (rp->fc_ringno) { + case FC_ELS_RING: + fc_post_buffer(p_dev_ctl, rp, i); + break; + case FC_IP_RING: + fc_post_mbuf(p_dev_ctl, rp, i); + break; + } + temp = (IOCBQ * )temp->q; + } + return(0); +} /* End fc_free_iocb_buf */ + + +/* + * Returns 0 if pn1 < pn2 + * Returns 1 if pn1 > pn2 + * Returns 2 if pn1 = pn2 + */ +_static_ int +fc_geportname( +NAME_TYPE *pn1, +NAME_TYPE *pn2) +{ + int i; + uchar * cp1, *cp2; + + i = sizeof(NAME_TYPE); + cp1 = (uchar * )pn1; + cp2 = (uchar * )pn2; + while (i--) { + if (*cp1 < *cp2) { + return(0); + } + if (*cp1 > *cp2) { + return(1); + } + cp1++; + cp2++; + } + + return(2); /* equal */ +} /* End fc_geportname */ + + +_local_ int +fc_ring_txcnt( +FC_BRD_INFO *binfo, +int flag) +{ + int sum = 0; + + if ((binfo->fc_flag & FC_SLI2) && (FCSTATCTR.linkEvent == 0)) + return(0); + + switch (flag) { + case FC_IP_RING: + sum += binfo->fc_ring[FC_IP_RING].fc_tx.q_cnt; + sum += binfo->fc_ring[FC_ELS_RING].fc_tx.q_cnt; + break; + case FC_FCP_RING: + sum += binfo->fc_ring[FC_FCP_RING].fc_tx.q_cnt; + sum += binfo->fc_ring[FC_ELS_RING].fc_tx.q_cnt; + break; + default: + sum = 1; + break; + } + return(sum); +} /* End fc_ring_txcnt */ + + +_local_ int +fc_ring_txpcnt( +FC_BRD_INFO *binfo, +int flag) +{ + int sum = 0; + + switch (flag) { + case FC_IP_RING: + sum += binfo->fc_ring[FC_IP_RING].fc_txp.q_cnt; + sum += binfo->fc_ring[FC_ELS_RING].fc_txp.q_cnt; + break; + case FC_FCP_RING: + sum += binfo->fc_ring[FC_FCP_RING].fc_txp.q_cnt; + sum += binfo->fc_ring[FC_ELS_RING].fc_txp.q_cnt; + break; + default: + sum = 1; + break; + } + return(sum); +} /* End fc_ring_txpcnt */ + + +/*****************************************************************************/ +/* + * NAME: fc_cmdring_timeout + * + * FUNCTION: Fibre Channel driver cmd ring watchdog timer timeout routine. + * + * EXECUTION ENVIRONMENT: interrupt only + * + * CALLED FROM: + * Timer function + * + * RETURNS: + * none + */ +/*****************************************************************************/ +_static_ void +fc_cmdring_timeout( +fc_dev_ctl_t * p_dev_ctl, +void *l1, +void *l2) +{ + FC_BRD_INFO * binfo; + RING * rp; + int i; + uint32 command; + uint32 * lp0; + IOCBQ * xmitiq; + IOCBQ * save; + IOCB * icmd; + MAILBOXQ * mb; + MATCHMAP * mp; + NODELIST * ndlp; + ELS_PKT * ep; + fcipbuf_t * p_mbuf; + fcipbuf_t * m_net; + + if (!p_dev_ctl) { + return; + } + rp = (RING *)l1; + RINGTMO = 0; + + binfo = &BINFO; + if ((xmitiq = fc_ringtxp_get(rp, 0)) != NULL) { + icmd = &xmitiq->iocb; + switch (icmd->ulpCommand) { + case CMD_ELS_REQUEST_CR: + case CMD_ELS_REQUEST64_CR: + mp = (MATCHMAP * )xmitiq->bp; + lp0 = (uint32 * )mp->virt; + command = *lp0; + switch (command) { + case ELS_CMD_FLOGI: /* Fabric login */ + fc_freenode_did(binfo, Fabric_DID, 1); + if (binfo->fc_ffstate == FC_FLOGI) { + binfo->fc_flag &= ~FC_FABRIC; + if (binfo->fc_topology == TOPOLOGY_LOOP) { + binfo->fc_edtov = FF_DEF_EDTOV; + binfo->fc_ratov = FF_DEF_RATOV; + if ((mb=(MAILBOXQ * )fc_mem_get(binfo, MEM_MBOX | MEM_PRI))) { + fc_config_link(p_dev_ctl, (MAILBOX * )mb); + if (issue_mb_cmd(binfo, (MAILBOX * )mb, MBX_NOWAIT) + != MBX_BUSY) { + fc_mem_put(binfo, MEM_MBOX, (uchar * )mb); + } + } + binfo->fc_flag |= FC_DELAY_DISC; + } else { + /* Device Discovery completion error */ + fc_log_printf_msg_vargs( binfo->fc_brd_no, + &fc_msgBlk0220, /* ptr to msg structure */ + fc_mes0220, /* ptr to msg */ + fc_msgBlk0220.msgPreambleStr); /* begin & end varargs */ + binfo->fc_ffstate = FC_ERROR; + if ((mb=(MAILBOXQ * )fc_mem_get(binfo, MEM_MBOX | MEM_PRI))) { + fc_clear_la(binfo, (MAILBOX * )mb); + if (issue_mb_cmd(binfo, (MAILBOX * )mb, MBX_NOWAIT) + != MBX_BUSY) { + fc_mem_put(binfo, MEM_MBOX, (uchar * )mb); + } + } + } + } + break; + + case ELS_CMD_PLOGI: /* NPort login */ + if ((ndlp = fc_findnode_odid(binfo, NLP_SEARCH_ALL, + icmd->un.elsreq.remoteID)) == 0) + break; + + /* If we are in the middle of Discovery */ + if (ndlp->nlp_action & NLP_DO_DISC_START) { + /* Goto next entry */ + fc_nextnode(p_dev_ctl, ndlp); + } + ndlp->nlp_flag &= ~NLP_REQ_SND; + + fc_freenode(binfo, ndlp, 0); + ndlp->nlp_state = NLP_LIMBO; + fc_nlp_bind(binfo, ndlp); + break; + + case ELS_CMD_PRLI: /* Process Log In */ + if ((ndlp = fc_findnode_odid(binfo, NLP_SEARCH_ALL, + icmd->un.elsreq.remoteID)) == 0) + break; + + /* If we are in the middle of Discovery */ + if (ndlp->nlp_action & NLP_DO_DISC_START) { + /* Goto next entry */ + fc_nextnode(p_dev_ctl, ndlp); + } + ndlp->nlp_flag &= ~NLP_REQ_SND; + ndlp->nlp_state = NLP_LOGIN; + fc_nlp_unmap(binfo, ndlp); + break; + + case ELS_CMD_PDISC: /* Pdisc */ + case ELS_CMD_ADISC: /* Adisc */ + if ((ndlp = fc_findnode_odid(binfo, NLP_SEARCH_ALL, + icmd->un.elsreq.remoteID)) == 0) + break; + + /* If we are in the middle of Address Authentication */ + if (ndlp->nlp_action & (NLP_DO_ADDR_AUTH)) { + ndlp->nlp_action &= ~NLP_DO_ADDR_AUTH; + fc_freenode(binfo, ndlp, 0); + ndlp->nlp_state = NLP_LIMBO; + fc_nlp_bind(binfo, ndlp); + + ndlp->nlp_action |= NLP_DO_DISC_START; + /* Goto next entry */ + fc_nextnode(p_dev_ctl, ndlp); + } else { + fc_freenode(binfo, ndlp, 0); + ndlp->nlp_state = NLP_LIMBO; + fc_nlp_bind(binfo, ndlp); + } + break; + + case ELS_CMD_LOGO: /* Logout */ + if ((ndlp = fc_findnode_odid(binfo, NLP_SEARCH_ALL, + icmd->un.elsreq.remoteID)) == 0) + break; + + /* If we are in the middle of Discovery */ + if (ndlp->nlp_action & NLP_DO_DISC_START) { + /* Goto next entry */ + fc_nextnode(p_dev_ctl, ndlp); + } + + fc_freenode(binfo, ndlp, 0); + ndlp->nlp_state = NLP_LIMBO; + fc_nlp_bind(binfo, ndlp); + break; + + case ELS_CMD_FARP: /* Farp-req */ + case ELS_CMD_FARPR: /* Farp-res */ + ep = (ELS_PKT * )lp0; + if((ndlp = fc_findnode_wwpn(binfo, NLP_SEARCH_ALL, + &ep->un.farp.RportName)) == 0) + break; + ndlp->nlp_flag &= ~NLP_FARP_SND; + ndlp->nlp_action &= ~NLP_DO_ADDR_AUTH; + + /* Check for a FARP generated nlplist entry */ + if (ndlp->nlp_DID == Bcast_DID) { + fc_freenode(binfo, ndlp, 1); + } + break; + + case ELS_CMD_SCR: /* State Change Registration */ + break; + + default: + FCSTATCTR.elsCmdPktInval++; + break; + } + if (xmitiq->bp) { + fc_mem_put(binfo, MEM_BUF, (uchar * )xmitiq->bp); + } + if (xmitiq->info) { + fc_mem_put(binfo, MEM_BUF, (uchar * )xmitiq->info); + } + if ((binfo->fc_flag & FC_SLI2) && (xmitiq->bpl)) { + fc_mem_put(binfo, MEM_BPL, (uchar * )xmitiq->bpl); + } + break; + + case CMD_XMIT_ELS_RSP_CX: + case CMD_XMIT_ELS_RSP64_CX: + ndlp = (NODELIST * )xmitiq->ndlp; + /* No retries */ + if ((ndlp) && (ndlp->nlp_flag & NLP_RM_ENTRY) && + !(ndlp->nlp_flag & NLP_REQ_SND)) { + if (ndlp->nlp_type & NLP_FCP_TARGET) { + ndlp->nlp_flag &= ~NLP_RM_ENTRY; + ndlp->nlp_action &= ~NLP_DO_ADDR_AUTH; + if(binfo->fc_ffstate == FC_READY) { + if ((ndlp->nlp_flag & NLP_NODEV_TMO) && + (ndlp->nlp_DID != (uint32)0)) { + ndlp->nlp_flag |= NLP_NODEV_TMO; + if(!(ndlp->nlp_flag & NLP_NS_REMOVED)) { + fc_els_cmd(binfo, ELS_CMD_PLOGI, + (void *)((ulong)ndlp->nlp_DID), (uint32)0, (ushort)0, ndlp); + } + } + if(!(binfo->fc_flag & FC_RSCN_MODE)) { + binfo->fc_flag |= FC_RSCN_MODE; + ndlp->nlp_action |= NLP_DO_RSCN; + ndlp->nlp_flag &= ~NLP_NODEV_TMO; + fc_nextrscn(p_dev_ctl, 1); + } + } + else { + ndlp->nlp_action |= NLP_DO_DISC_START; + fc_nextdisc(p_dev_ctl, 1); + } + } else + fc_freenode_did(binfo, ndlp->nlp_DID, 0); + } + if (xmitiq->bp) { + fc_mem_put(binfo, MEM_BUF, (uchar * )xmitiq->bp); + } + if ((binfo->fc_flag & FC_SLI2) && (xmitiq->bpl)) { + fc_mem_put(binfo, MEM_BPL, (uchar * )xmitiq->bpl); + } + break; + + case CMD_ABORT_XRI_CN: + break; + + case CMD_CREATE_XRI_CR: + break; + + case CMD_XMIT_SEQUENCE_CX: + case CMD_XMIT_BCAST_CN: + case CMD_XMIT_SEQUENCE64_CX: + case CMD_XMIT_BCAST64_CN: + if (rp->fc_ringno != FC_IP_RING) { + break; + } + NDDSTAT.ndd_xmitque_cur--; + /* get mbuf ptr for completed xmit */ + m_net = (fcipbuf_t * )xmitiq->bp; + /* Loop through iocb chain unmap memory pages associated with mbuf */ + if (binfo->fc_flag & FC_SLI2) { + ULP_BDE64 * bpl; + MATCHMAP * bmp; + + bmp = (MATCHMAP * )xmitiq->bpl; + bpl = (ULP_BDE64 * )bmp->virt; + while (bpl && xmitiq->iocb.un.xseq64.bdl.bdeSize) { + fc_bufunmap(p_dev_ctl, (uchar *)getPaddr(bpl->addrHigh, bpl->addrLow), 0, bpl->tus.f.bdeSize); + bpl++; + xmitiq->iocb.un.xseq64.bdl.bdeSize -= sizeof(ULP_BDE64); + } + fc_mem_put(binfo, MEM_BPL, (uchar * )bmp); + fc_mem_put(binfo, MEM_IOCB, (uchar * )xmitiq); + xmitiq = 0; + } else { + while (xmitiq) { + for (i = 0; i < (int)xmitiq->iocb.ulpBdeCount; i++) { + fc_bufunmap(p_dev_ctl, (uchar *)((ulong)xmitiq->iocb.un.cont[i].bdeAddress), 0, (uint32)xmitiq->iocb.un.cont[i].bdeSize); + } + save = (IOCBQ * )xmitiq->q; + fc_mem_put(binfo, MEM_IOCB, (uchar * )xmitiq); + xmitiq = save; + } + } + + /* free mbuf */ + if (m_net) { + p_mbuf = fcnextdata(m_net); + fcnextdata(m_net) = 0; + fcfreehandle(p_dev_ctl, m_net); + m_freem(m_net); + if (p_mbuf) { + fcfreehandle(p_dev_ctl, p_mbuf); + m_freem(p_mbuf); + } + } + break; + + default: + break; + } + if (xmitiq) + fc_mem_put(binfo, MEM_IOCB, (uchar * )xmitiq); + /* Command ring timeout */ + fc_log_printf_msg_vargs( binfo->fc_brd_no, + &fc_msgBlk1401, /* ptr to msg structure */ + fc_mes1401, /* ptr to msg */ + fc_msgBlk1401.msgPreambleStr, /* begin varargs */ + rp->fc_ringno, + icmd->ulpCommand ); /* end varargs */ + } else { + /* Command ring timeout */ + fc_log_printf_msg_vargs( binfo->fc_brd_no, + &fc_msgBlk1402, /* ptr to msg structure */ + fc_mes1402, /* ptr to msg */ + fc_msgBlk1402.msgPreambleStr, /* begin varargs */ + rp->fc_ringno ); /* end varargs */ + } + + if ((rp->fc_ringno == FC_IP_RING) && + (binfo->fc_flag & FC_LNK_DOWN)) { + IOCBQ * xmitiq; + + /* If linkdown, flush out tx and txp queues */ + /* get next command from ring xmit queue */ + while ((xmitiq = fc_ringtx_drain(rp)) != 0) { + fc_freebufq(p_dev_ctl, rp, xmitiq); + } + + /* look up xmit next compl */ + while ((xmitiq = fc_ringtxp_get(rp, 0)) != 0) { + fc_freebufq(p_dev_ctl, rp, xmitiq); + } + NDDSTAT.ndd_xmitque_cur = 0; + } + + return; +} /* End fc_cmdring_timeout */ + + +/*****************************************************************************/ +/* + * NAME: fc_linkdown_timeout + * + * FUNCTION: Fibre Channel driver link down watchdog timer timeout routine. + * + * EXECUTION ENVIRONMENT: interrupt only + * + * CALLED FROM: + * Timer function + * + * RETURNS: + * none + */ +/*****************************************************************************/ +_static_ void +fc_linkdown_timeout( +fc_dev_ctl_t * p_dev_ctl, +void *l1, +void *l2) +{ + FC_BRD_INFO * binfo; + iCfgParam * clp; + RING * rp; + NODELIST * ndlp; + NODELIST * new_ndlp; + + if (!p_dev_ctl) { + return; + } + + binfo = &BINFO; + clp = DD_CTL.p_config[binfo->fc_brd_no]; + rp = &binfo->fc_ring[FC_FCP_RING]; + RINGTMO = 0; + + /* EXPIRED linkdown timer */ + fc_log_printf_msg_vargs( binfo->fc_brd_no, + &fc_msgBlk0750, /* ptr to msg structure */ + fc_mes0750, /* ptr to msg */ + fc_msgBlk0750.msgPreambleStr, /* begin varargs */ + (ulong)binfo->fc_ffstate ); /* end varargs */ + if (binfo->fc_ffstate == FC_READY) { + return; + } + + if ((binfo->fc_ffstate > FC_LINK_DOWN) && + (binfo->fc_ffstate < FC_READY)) { + + /* Set the link down watchdog timer expired flag */ + binfo->fc_flag |= FC_LD_TIMEOUT; + goto out; + } + + /* Since the link has been down for so long, call fc_freenode for all + * SCSI device and clear out all SCSI queues + */ + ndlp = binfo->fc_nlpmap_start; + while(ndlp != (NODELIST *)&binfo->fc_nlpmap_start) { + new_ndlp = (NODELIST *)ndlp->nlp_listp_next; + fc_freenode(binfo, ndlp, 0); + ndlp->nlp_state = NLP_LIMBO; + fc_nlp_bind(binfo, ndlp); + ndlp = new_ndlp; + } + + /* Set the link down watchdog timer expired flag */ + binfo->fc_flag |= FC_LD_TIMEOUT; + + if((clp[CFG_LINKDOWN_TMO].a_current) && (clp[CFG_HOLDIO].a_current == 0)) { + fc_failio(p_dev_ctl); + } + +out: + + return; +} /* End fc_linkdown_timeout */ + + +/*****************************************************************************/ +/* + * NAME: fc_mbox_timeout + * + * FUNCTION: Fibre Channel driver mailbox watchdog timer timeout routine. + * + * EXECUTION ENVIRONMENT: interrupt only + * + * CALLED FROM: + * Timer function + * + * RETURNS: + * none + */ +/*****************************************************************************/ +_static_ void +fc_mbox_timeout( +fc_dev_ctl_t * p_dev_ctl, +void *l1, +void *l2) +{ + FC_BRD_INFO * binfo; + MAILBOXQ * mbox; + MAILBOX * swpmb, *mb; + void *ioa; + volatile uint32 word0; + + if (!p_dev_ctl) { + return; + } + + binfo = &BINFO; + MBOXTMO = 0; + + binfo->fc_mbox_active = 0; + + if (binfo->fc_flag & FC_SLI2) { + fc_mpdata_sync(binfo->fc_slim2.dma_handle, 0, 0, + DDI_DMA_SYNC_FORKERNEL); + /* First copy command data */ + mb = FC_SLI2_MAILBOX(binfo); + word0 = *((volatile uint32 * )mb); + word0 = PCIMEM_LONG(word0); + } else { + /* First copy command data */ + ioa = (void *)FC_MAP_MEM(&binfo->fc_iomap_mem); /* map in SLIM */ + mb = FC_MAILBOX(binfo, ioa); + word0 = READ_SLIM_ADDR(binfo, ((volatile uint32 * )mb)); + FC_UNMAP_MEMIO(ioa); + } + swpmb = (MAILBOX * ) & word0; + + /* Mailbox command timeout, status fc_brd_no, + &fc_msgBlk0310, /* ptr to msg structure */ + fc_mes0310, /* ptr to msg */ + fc_msgBlk0310.msgPreambleStr, /* begin varargs */ + swpmb->mbxCommand, + swpmb->mbxStatus); /* end varargs */ + if ((mbox = fc_mbox_get(binfo))) { + if (issue_mb_cmd(binfo, (MAILBOX * )mbox, MBX_NOWAIT) != MBX_BUSY) { + fc_mem_put(binfo, MEM_MBOX, (uchar * )mbox); + } + } + + return; +} /* End fc_mbox_timeout */ + + + +/*****************************************************************************/ +/* + * NAME: fc_fabric_timeout + * + * FUNCTION: Fibre Channel driver fabric watchdog timer timeout routine. + * + * EXECUTION ENVIRONMENT: interrupt only + * + * CALLED FROM: + * Timer function + * + * RETURNS: + * none + */ +/*****************************************************************************/ +_static_ void +fc_fabric_timeout( +fc_dev_ctl_t * p_dev_ctl, +void *l1, +void *l2) +{ + FC_BRD_INFO * binfo; + NODELIST * ndlp; + NODELIST * new_ndlp; + MAILBOXQ * mb; + iCfgParam * clp; + + if (!p_dev_ctl) { + return; + } + + binfo = &BINFO; + FABRICTMO = 0; + + /* Check for wait for FAN timeout */ + if (binfo->fc_ffstate == FC_FLOGI) { + if((binfo->fc_topology == TOPOLOGY_LOOP) && + (binfo->fc_flag & FC_PUBLIC_LOOP)) { + /* FAN timeout */ + fc_log_printf_msg_vargs( binfo->fc_brd_no, + &fc_msgBlk0221, /* ptr to msg structure */ + fc_mes0221, /* ptr to msg */ + fc_msgBlk0221.msgPreambleStr); /* begin & end varargs */ + } + else { + /* Initial FLOGI timeout */ + fc_log_printf_msg_vargs( binfo->fc_brd_no, + &fc_msgBlk0222, /* ptr to msg structure */ + fc_mes0222, /* ptr to msg */ + fc_msgBlk0222.msgPreambleStr); /* begin & end varargs */ + } + + fc_freenode_did(binfo, Fabric_DID, 1); + /* FAN timeout, so just do FLOGI instead */ + /* Now build FLOGI payload and issue ELS command */ + fc_els_cmd(binfo, ELS_CMD_FLOGI, (void *)Fabric_DID, + (uint32)0, (ushort)0, (NODELIST *)0); + goto out; + } + + /* Check for wait for NameServer Rsp timeout */ + if (binfo->fc_ffstate == FC_NS_REG) { + /* NameServer Registration timeout */ + fc_log_printf_msg_vargs( binfo->fc_brd_no, + &fc_msgBlk0223, /* ptr to msg structure */ + fc_mes0223, /* ptr to msg */ + fc_msgBlk0223.msgPreambleStr, /* begin varargs */ + binfo->fc_ns_retry, + fc_max_ns_retry); /* end varargs */ + if ((ndlp = fc_findnode_odid(binfo, NLP_SEARCH_ALL, NameServer_DID))) { + if(binfo->fc_ns_retry) { + if(binfo->fc_ns_retry < fc_max_ns_retry) { + /* Try it one more time */ + if (fc_ns_cmd(p_dev_ctl, ndlp, SLI_CTNS_RFT_ID) == 0) { + goto out; + } + } + binfo->fc_ns_retry = 0; + } + /* Complete discovery, then issue an INIT_LINK */ + goto ns_tmout; + } + goto out; + } + + /* Check for wait for NameServer Rsp timeout */ + if (binfo->fc_ffstate == FC_NS_QRY) { + /* NameServer Query timeout */ + fc_log_printf_msg_vargs( binfo->fc_brd_no, + &fc_msgBlk0224, /* ptr to msg structure */ + fc_mes0224, /* ptr to msg */ + fc_msgBlk0224.msgPreambleStr, /* begin varargs */ + binfo->fc_ns_retry, + fc_max_ns_retry); /* end varargs */ + if ((ndlp = fc_findnode_odid(binfo, NLP_SEARCH_ALL, NameServer_DID))) { + if(binfo->fc_ns_retry) { + if(binfo->fc_ns_retry < fc_max_ns_retry) { + /* Try it one more time */ + if (fc_ns_cmd(p_dev_ctl, ndlp, SLI_CTNS_GID_FT) == 0) { + goto out; + } + } + binfo->fc_ns_retry = 0; + } + +ns_tmout: + /* Complete discovery, then issue an INIT_LINK */ + /* This should turn off DELAYED ABTS for ELS timeouts */ + if ((mb = (MAILBOXQ * )fc_mem_get(binfo, MEM_MBOX))) { + fc_set_slim(binfo, (MAILBOX * )mb, 0x052198, 0); + if (issue_mb_cmd(binfo, (MAILBOX * )mb, MBX_NOWAIT) != MBX_BUSY) { + fc_mem_put(binfo, MEM_MBOX, (uchar * )mb); + } + } + + /* Nothing to authenticate, so CLEAR_LA right now */ + if ((mb = (MAILBOXQ * )fc_mem_get(binfo, MEM_MBOX | MEM_PRI))) { + binfo->fc_ffstate = FC_CLEAR_LA; + fc_clear_la(binfo, (MAILBOX * )mb); + if (issue_mb_cmd(binfo, (MAILBOX * )mb, MBX_NOWAIT) != MBX_BUSY) { + fc_mem_put(binfo, MEM_MBOX, (uchar * )mb); + } + /* Device Discovery completes */ + fc_log_printf_msg_vargs( binfo->fc_brd_no, + &fc_msgBlk0225, /* ptr to msg structure */ + fc_mes0225, /* ptr to msg */ + fc_msgBlk0225.msgPreambleStr); /* begin & end varargs */ + } else { + /* Device Discovery completion error */ + fc_log_printf_msg_vargs( binfo->fc_brd_no, + &fc_msgBlk0226, /* ptr to msg structure */ + fc_mes0226, /* ptr to msg */ + fc_msgBlk0226.msgPreambleStr); /* begin & end varargs */ + binfo->fc_ffstate = FC_ERROR; + } + + binfo->fc_firstopen++; + if(binfo->fc_firstopen >= fc_max_ns_retry) { + goto out; + } + + /* Get a buffer to use for the mailbox command */ + if ((mb = (MAILBOXQ * )fc_mem_get(binfo, MEM_MBOX | MEM_PRI))) { + clp = DD_CTL.p_config[binfo->fc_brd_no]; + + /* Setup and issue mailbox INITIALIZE LINK command */ + fc_linkdown(p_dev_ctl); + fc_init_link(binfo, (MAILBOX * )mb, clp[CFG_TOPOLOGY].a_current, + clp[CFG_LINK_SPEED].a_current); + ((MAILBOX *)mb)->un.varInitLnk.lipsr_AL_PA = 0; + if (issue_mb_cmd(binfo, (MAILBOX * )mb, MBX_NOWAIT) != MBX_BUSY) + fc_mem_put(binfo, MEM_MBOX, (uchar * )mb); + } + } + goto out; + } + + /* Check for Node Authentication timeout */ + if (binfo->fc_ffstate == FC_LOOP_DISC) { + int disc; + + disc = 0; + /* Node Authentication timeout */ + fc_log_printf_msg_vargs( binfo->fc_brd_no, + &fc_msgBlk0227, /* ptr to msg structure */ + fc_mes0227, /* ptr to msg */ + fc_msgBlk0227.msgPreambleStr); /* begin & end varargs */ + ndlp = binfo->fc_nlpbind_start; + if(ndlp == (NODELIST *)&binfo->fc_nlpbind_start) + ndlp = binfo->fc_nlpunmap_start; + if(ndlp == (NODELIST *)&binfo->fc_nlpunmap_start) + ndlp = binfo->fc_nlpmap_start; + while(ndlp != (NODELIST *)&binfo->fc_nlpmap_start) { + new_ndlp = (NODELIST *)ndlp->nlp_listp_next; + + /* Clean up all nodes marked for authentication */ + if (ndlp->nlp_action & NLP_DO_ADDR_AUTH) { + ndlp->nlp_action &= ~NLP_DO_ADDR_AUTH; + fc_freenode(binfo, ndlp, 0); + ndlp->nlp_state = NLP_LIMBO; + fc_nlp_bind(binfo, ndlp); + if (ndlp->nlp_DID != NameServer_DID) { + ndlp->nlp_action |= NLP_DO_DISC_START; + disc++; + } + } + else if (ndlp->nlp_action & NLP_DO_DISC_START) { + if (ndlp->nlp_DID != NameServer_DID) { + disc++; + } + } + ndlp = new_ndlp; + if(ndlp == (NODELIST *)&binfo->fc_nlpbind_start) + ndlp = binfo->fc_nlpunmap_start; + if(ndlp == (NODELIST *)&binfo->fc_nlpunmap_start) + ndlp = binfo->fc_nlpmap_start; + } + if(disc) { + fc_nextdisc(p_dev_ctl, fc_max_els_sent); + } + else { + goto ns_tmout; + } + goto out; + } + + /* Check for Node Discovery timeout */ + if (binfo->fc_ffstate == FC_NODE_DISC) { + /* Node Discovery timeout */ + fc_log_printf_msg_vargs( binfo->fc_brd_no, + &fc_msgBlk0228, /* ptr to msg structure */ + fc_mes0228, /* ptr to msg */ + fc_msgBlk0228.msgPreambleStr); /* begin & end varargs */ + ndlp = binfo->fc_nlpbind_start; + if(ndlp == (NODELIST *)&binfo->fc_nlpbind_start) + ndlp = binfo->fc_nlpunmap_start; + if(ndlp == (NODELIST *)&binfo->fc_nlpunmap_start) + ndlp = binfo->fc_nlpmap_start; + while(ndlp != (NODELIST *)&binfo->fc_nlpmap_start) { + new_ndlp = (NODELIST *)ndlp->nlp_listp_next; + + /* Clean up all nodes marked for discovery/authentication */ + if (ndlp->nlp_action & (NLP_DO_ADDR_AUTH | NLP_DO_DISC_START)) { + /* Node Discovery timeout */ + fc_log_printf_msg_vargs( binfo->fc_brd_no, + &fc_msgBlk0229, /* ptr to msg structure */ + fc_mes0229, /* ptr to msg */ + fc_msgBlk0229.msgPreambleStr, /* begin varargs */ + ndlp->nlp_DID, + ndlp->nlp_flag, + ndlp->nlp_state, + ndlp->nlp_type); /* end varargs */ + ndlp->nlp_flag &= ~(NLP_REQ_SND | NLP_REG_INP | NLP_REQ_SND_ADISC); + fc_freenode(binfo, ndlp, 0); + ndlp->nlp_state = NLP_LIMBO; + fc_nlp_bind(binfo, ndlp); + } + ndlp = new_ndlp; + if(ndlp == (NODELIST *)&binfo->fc_nlpbind_start) + ndlp = binfo->fc_nlpunmap_start; + if(ndlp == (NODELIST *)&binfo->fc_nlpunmap_start) + ndlp = binfo->fc_nlpmap_start; + } + /* Nothing to discover, so CLEAR_LA right now */ + if ((mb = (MAILBOXQ * )fc_mem_get(binfo, MEM_MBOX | MEM_PRI))) { + binfo->fc_ffstate = FC_CLEAR_LA; + fc_clear_la(binfo, (MAILBOX * )mb); + if (issue_mb_cmd(binfo, (MAILBOX * )mb,MBX_NOWAIT) != MBX_BUSY) { + fc_mem_put(binfo, MEM_MBOX, (uchar * )mb); + } + } else { + /* Device Discovery completion error */ + fc_log_printf_msg_vargs( binfo->fc_brd_no, + &fc_msgBlk0230, /* ptr to msg structure */ + fc_mes0230, /* ptr to msg */ + fc_msgBlk0230.msgPreambleStr); /* begin & end varargs */ + binfo->fc_ffstate = FC_ERROR; + } + goto out; + } + + /* Check for RSCN timeout */ + if ((binfo->fc_flag & FC_RSCN_MODE) && (binfo->fc_ffstate == FC_READY)) { + + if(binfo->fc_ns_retry) { + if ((ndlp = fc_findnode_odid(binfo, NLP_SEARCH_ALL, NameServer_DID))) { + if(binfo->fc_ns_retry < fc_max_ns_retry) { + /* Try it one more time */ + if (fc_ns_cmd(p_dev_ctl, ndlp, SLI_CTNS_GID_FT) == 0) { + goto out; + } + } + } + } + /* RSCN timeout */ + fc_log_printf_msg_vargs( binfo->fc_brd_no, + &fc_msgBlk0231, /* ptr to msg structure */ + fc_mes0231, /* ptr to msg */ + fc_msgBlk0231.msgPreambleStr, /* begin varargs */ + binfo->fc_ns_retry, + fc_max_ns_retry ); /* end varargs */ + ndlp = binfo->fc_nlpbind_start; + if(ndlp == (NODELIST *)&binfo->fc_nlpbind_start) + ndlp = binfo->fc_nlpunmap_start; + if(ndlp == (NODELIST *)&binfo->fc_nlpunmap_start) + ndlp = binfo->fc_nlpmap_start; + while(ndlp != (NODELIST *)&binfo->fc_nlpmap_start) { + new_ndlp = (NODELIST *)ndlp->nlp_listp_next; + + /* Clean up all nodes marked for rscn */ + if (ndlp->nlp_action & NLP_DO_RSCN) { + /* Node RSCN timeout */ + fc_log_printf_msg_vargs( binfo->fc_brd_no, + &fc_msgBlk0232, /* ptr to msg structure */ + fc_mes0232, /* ptr to msg */ + fc_msgBlk0232.msgPreambleStr, /* begin varargs */ + ndlp->nlp_DID, + ndlp->nlp_flag, + ndlp->nlp_state, + ndlp->nlp_type); /* end varargs */ + ndlp->nlp_flag &= ~(NLP_REQ_SND | NLP_REG_INP | NLP_REQ_SND_ADISC); + fc_freenode(binfo, ndlp, 0); + ndlp->nlp_state = NLP_LIMBO; + fc_nlp_bind(binfo, ndlp); + } + ndlp = new_ndlp; + if(ndlp == (NODELIST *)&binfo->fc_nlpbind_start) + ndlp = binfo->fc_nlpunmap_start; + if(ndlp == (NODELIST *)&binfo->fc_nlpunmap_start) + ndlp = binfo->fc_nlpmap_start; + } + + binfo->fc_flag &= ~FC_NLP_MORE; + binfo->fc_nlp_cnt = 0; + binfo->fc_ns_retry = 0; + /* fc_nextrscn(p_dev_ctl, fc_max_els_sent); */ + fc_rlip(p_dev_ctl); + goto out; + } + + /* Check for pt2pt link up timeout */ + if ((binfo->fc_flag & FC_PT2PT) && (binfo->fc_ffstate != FC_READY)) { + /* PT2PT link up timeout */ + fc_log_printf_msg_vargs( binfo->fc_brd_no, + &fc_msgBlk0233, /* ptr to msg structure */ + fc_mes0233, /* ptr to msg */ + fc_msgBlk0233.msgPreambleStr); /* begin & end varargs */ + binfo->fc_ffstate = FC_LINK_UP; + binfo->fc_flag &= ~(FC_LNK_DOWN | FC_PT2PT | FC_PT2PT_PLOGI | + FC_LBIT | FC_RSCN_MODE | FC_NLP_MORE | + FC_RSCN_DISC_TMR | FC_RSCN_DISCOVERY); + + binfo->fc_myDID = 0; + if ((mb = (MAILBOXQ * )fc_mem_get(binfo, MEM_MBOX | MEM_PRI))) { + binfo->fc_ffstate = FC_CFG_LINK; + fc_config_link(p_dev_ctl, (MAILBOX * )mb); + if (issue_mb_cmd(binfo, (MAILBOX * )mb, MBX_NOWAIT) != MBX_BUSY) { + fc_mem_put(binfo, MEM_MBOX, (uchar * )mb); + } + } + goto out; + } + +out: + return; +} /* End fc_fabric_timeout */ + + +/*****************************************************************************/ +/* + * NAME: fc_delay_timeout + * + * FUNCTION: Fibre Channel driver delay watchdog timer timeout routine. + * + * EXECUTION ENVIRONMENT: interrupt only + * + * CALLED FROM: + * Timer function + * + * RETURNS: + * none + */ +/*****************************************************************************/ +_static_ void +fc_delay_timeout( +fc_dev_ctl_t * p_dev_ctl, +void *l1, +void *l2) +{ + FC_BRD_INFO * binfo; + IOCBQ * iocbq; + RING * rp; + MATCHMAP * rmp; + NODELIST * ndlp; + + binfo = &BINFO; + rp = &binfo->fc_ring[FC_ELS_RING]; + iocbq = (IOCBQ *)l1; + + if(((rmp = (MATCHMAP *)iocbq->info) != 0) && + ((ndlp = (NODELIST *)rmp->fc_mptr) != 0)) { + /* Don't send PLOGI if we are already logged in! */ + if(ndlp->nlp_state >= NLP_LOGIN) { + if(iocbq->bp) { + fc_mem_put(binfo, MEM_BUF, (uchar * )iocbq->bp); + } + if (iocbq->info) { + fc_mem_put(binfo, MEM_BUF, (uchar * )iocbq->info); + } + if (iocbq->bpl) { + fc_mem_put(binfo, MEM_BPL, (uchar * )iocbq->bpl); + } + + fc_mem_put(binfo, MEM_IOCB, (uchar * )iocbq); + return; + } + } + /* Delayxmit ELS command timeout */ + fc_log_printf_msg_vargs( binfo->fc_brd_no, + &fc_msgBlk0136, /* ptr to msg structure */ + fc_mes0136, /* ptr to msg */ + fc_msgBlk0136.msgPreambleStr, /* begin varargs */ + iocbq->iocb.ulpCommand, + iocbq->iocb.ulpIoTag, + iocbq->retry, + iocbq->iocb.un.elsreq.remoteID); /* end varargs */ + issue_iocb_cmd(binfo, rp, iocbq); + + if (((binfo->fc_flag & FC_RSCN_MODE) && (binfo->fc_ffstate == FC_READY)) || + (binfo->fc_ffstate == FC_LOOP_DISC) || + (binfo->fc_ffstate == FC_NODE_DISC)) { + binfo->fc_fabrictmo = (2 * binfo->fc_ratov) + + ((4 * binfo->fc_edtov) / 1000) + 1; + if(FABRICTMO) { + fc_clk_res(p_dev_ctl, binfo->fc_fabrictmo, FABRICTMO); + } + else { + FABRICTMO = fc_clk_set(p_dev_ctl, binfo->fc_fabrictmo, + fc_fabric_timeout, 0, 0); + } + } + + return; +} + +/*****************************************************************************/ +/* + * NAME: fc_nodev_timeout + * + * FUNCTION: Fibre Channel driver FCP device disappearing timeout routine. + * + * EXECUTION ENVIRONMENT: interrupt only + * + * CALLED FROM: + * Timer interrupt + * + * INPUT: + * tp - pointer to the timer structure + * + * RETURNS: + * none + */ +/*****************************************************************************/ +_static_ void +fc_nodev_timeout( +fc_dev_ctl_t * p_dev_ctl, +void * np, +void *l2) +{ + node_t * nodep; + dvi_t * dev_ptr; + FC_BRD_INFO * binfo; + iCfgParam * clp; + NODELIST * ndlp; + RING * rp; + IOCBQ * temp; + IOCBQ * nexttemp, *prevtemp; + IOCB * cmd; + unsigned long iflag; + + nodep = (node_t *)np; + binfo = &BINFO; + rp = &binfo->fc_ring[FC_FCP_RING]; + if(nodep) { + uint32 did; + uint32 pan; + uint32 sid; + uint32 rpi; + + clp = DD_CTL.p_config[p_dev_ctl->info.fc_brd_no]; + if(nodep->rpi != 0xfffe) + rpi = nodep->rpi; + else + rpi = 0; + + if((ndlp = nodep->nlp) == 0) { + /* + * Find the target from the nlplist based on SCSI ID + */ + ndlp = fc_findnode_scsid(binfo, NLP_SEARCH_MAPPED, nodep->scsi_id); + } + + if (ndlp) { + RING * rp; + IOCBQ * iocbq; + + /* EXPIRED nodev timer */ + fc_log_printf_msg_vargs( binfo->fc_brd_no, + &fc_msgBlk0751, /* ptr to msg structure */ + fc_mes0751, /* ptr to msg */ + fc_msgBlk0751.msgPreambleStr, /* begin varargs */ + (ulong)ndlp, + ndlp->nlp_flag, + ndlp->nlp_state, + ndlp->nlp_DID); /* end varargs */ + pan = ndlp->id.nlp_pan; + sid = ndlp->id.nlp_sid; + ndlp->nlp_flag &= ~NLP_NODEV_TMO; + did = ndlp->nlp_DID; + if(ndlp->nlp_Rpi) + rpi = ndlp->nlp_Rpi; + if(did == 0) { + if((ndlp->nlp_type & (NLP_AUTOMAP | NLP_SEED_MASK)) && + (ndlp->nlp_state == NLP_LIMBO) && ndlp->nlp_oldDID) + did = ndlp->nlp_oldDID; + + if (ndlp->nlp_flag & NLP_REQ_SND) { + /* Look through ELS ring and abort ELS cmd */ + rp = &binfo->fc_ring[FC_ELS_RING]; + iocbq = (IOCBQ * )(rp->fc_txp.q_first); + while (iocbq) { + if(iocbq->iocb.un.elsreq.remoteID == did) { + iocbq->retry = 0xff; + if((binfo->fc_flag & FC_RSCN_MODE) || + (binfo->fc_ffstate < FC_READY)) { + if((ndlp->nlp_state >= NLP_PLOGI) && + (ndlp->nlp_state <= NLP_PRLI)) { + ndlp->nlp_action &= ~NLP_DO_RSCN; + binfo->fc_nlp_cnt--; + if ((ndlp->nlp_type & NLP_IP_NODE) && ndlp->nlp_bp) { + m_freem((fcipbuf_t *)ndlp->nlp_bp); + ndlp->nlp_bp = (uchar * )0; + } + } + } + } + iocbq = (IOCBQ * )iocbq->q; + } + /* In case its on fc_delay_timeout list */ + fc_abort_delay_els_cmd(p_dev_ctl, ndlp->nlp_DID); + } + } + fc_freenode(binfo, ndlp, 0); + ndlp->nlp_state = NLP_LIMBO; + fc_nlp_bind(binfo, ndlp); + } else { + did = 0; + pan = 0; + sid = 0; + } + /* Device disappeared, nodev timeout */ + fc_log_printf_msg_vargs( binfo->fc_brd_no, + &fc_msgBlk0752, /* ptr to msg structure */ + fc_mes0752, /* ptr to msg */ + fc_msgBlk0752.msgPreambleStr, /* begin varargs */ + did, + sid, + pan, + clp[CFG_NODEV_TMO].a_current); /* end varargs */ + nodep->flags |= FC_NODEV_TMO; + nodep->flags &= ~FC_FCP2_RECOVERY; + nodep->nodev_tmr = 0; + for (dev_ptr = nodep->lunlist; dev_ptr != NULL; + dev_ptr = dev_ptr->next) { + + /* UNREG_LOGIN from freenode should abort txp I/Os */ + if(ndlp == 0) { + /* First send ABTS on outstanding I/Os in txp queue */ + fc_abort_fcp_txpq(binfo, dev_ptr); + } + + fc_fail_pendq(dev_ptr, ENXIO, STAT_ABORTED); + fc_fail_cmd(dev_ptr, ENXIO, STAT_ABORTED); + fc_return_standby_queue(dev_ptr, ENXIO, STAT_ABORTED); + + /* Call iodone for all the CLEARQ error bufs */ + fc_free_clearq(dev_ptr); + } + /* fail everything on txq that matches rpi */ + iflag = lpfc_q_disable_lock(p_dev_ctl); + prevtemp = 0; + temp = (IOCBQ *)rp->fc_tx.q_first; + while (temp != NULL) { + nexttemp = (IOCBQ *)temp->q; + cmd = &temp->iocb; + if(cmd->ulpContext == rpi) { + if(prevtemp) + prevtemp->q = (uchar *)nexttemp; + else + rp->fc_tx.q_first = (uchar *)nexttemp; + if(rp->fc_tx.q_last == (uchar * )temp) { + rp->fc_tx.q_last =0; + break; + } + cmd->ulpStatus = IOSTAT_LOCAL_REJECT; + cmd->un.grsp.perr.statLocalError = IOERR_INVALID_RPI; + + lpfc_q_unlock_enable(p_dev_ctl, iflag); + handle_fcp_event(p_dev_ctl, rp, temp); + iflag = lpfc_q_disable_lock(p_dev_ctl); + + fc_mem_put(binfo, MEM_IOCB, (uchar * )temp); + } + else + prevtemp = temp; + + if(rp->fc_tx.q_last == (uchar * )temp) + break; + temp = nexttemp; + } + lpfc_q_unlock_enable(p_dev_ctl, iflag); + } +} + +/*****************************************************************************/ +/* + * NAME: fc_rscndisc_timeout + * + * FUNCTION: Fibre Channel driver RSCN timer timeout routine. + * + * EXECUTION ENVIRONMENT: interrupt only + * + * CALLED FROM: + * Timer function + * + * RETURNS: + * none + */ +/*****************************************************************************/ +_local_ void +fc_rscndisc_timeout( +fc_dev_ctl_t * p_dev_ctl, +void *l1, +void *l2) +{ + FC_BRD_INFO * binfo; + + binfo = &BINFO; + binfo->fc_flag |= (FC_RSCN_DISC_TMR | FC_RSCN_DISCOVERY); + /* EXPIRED RSCN disc timer */ + fc_log_printf_msg_vargs( binfo->fc_brd_no, + &fc_msgBlk0252, /* ptr to msg structure */ + fc_mes0252, /* ptr to msg */ + fc_msgBlk0252.msgPreambleStr, /* begin varargs */ + (ulong)binfo->fc_flag ); /* end varargs */ + fc_nextrscn(p_dev_ctl, fc_max_els_sent); +} + +_static_ int +fc_free_fcp_txq( +fc_dev_ctl_t * p_dev_ctl, +uint32 iotag) +{ + FC_BRD_INFO * binfo; + RING * rp; + IOCBQ * temp; + IOCBQ * prev_temp; + IOCB * cmd; + unsigned long iflag; + + iflag = lpfc_q_disable_lock(p_dev_ctl); + binfo = &BINFO; + rp = &binfo->fc_ring[FC_FCP_RING]; + + /* Check to see if iotag is still queued on txq */ + prev_temp = 0; + temp = (IOCBQ *)(rp->fc_tx.q_first); + while(temp) { + cmd = &temp->iocb; + if(iotag == cmd->ulpIoTag) { + /* A match so dequeue it */ + if(prev_temp) { + prev_temp->q = temp->q; + } + else { + rp->fc_tx.q_first = (uchar *)(temp->q); + } + if(rp->fc_tx.q_last == (uchar * )temp) + rp->fc_tx.q_last = (uchar * )prev_temp; + rp->fc_tx.q_cnt--; + prev_temp = temp; + temp = (IOCBQ *)(temp->q); + fc_mem_put(binfo, MEM_IOCB, (uchar * )prev_temp); + lpfc_q_unlock_enable(p_dev_ctl, iflag); + return(1); + } + prev_temp = temp; + temp = (IOCBQ *)(temp->q); + } + lpfc_q_unlock_enable(p_dev_ctl, iflag); + return(0); +} /* End fc_free_fcp_txq */ + +/*****************************************************************************/ +/* + * NAME: fc_scsi_timeout + * + * FUNCTION: Fibre Channel driver SCSI FCP timeout routine. + * + * EXECUTION ENVIRONMENT: interrupt only + * + * CALLED FROM: + * Timer interrupt + * + * INPUT: + * tp - pointer to the timer structure + * + * RETURNS: + * none + */ +/*****************************************************************************/ +_static_ void +fc_scsi_timeout( +fc_dev_ctl_t * p, +void *l1, +void *l2) +{ + fc_dev_ctl_t * p_dev_ctl; + FC_BRD_INFO * binfo; + iCfgParam * clp; + RING * rp; + fc_buf_t * fcptr, *next_fcptr; + T_SCSIBUF * sbp; + struct buf * clrptr; + dvi_t * dev_ptr; + int j, ipri, do_rlip; + uint32 now; + + curtime(&now); + + /* + * Search through all outstanding SCSI commands for any that timed out + */ + for (j = 0; j < MAX_FC_BRDS; j++) { + p_dev_ctl = DD_CTL.p_dev[j]; + if (p_dev_ctl) { + do_rlip = 0; + binfo = &BINFO; + if(binfo->fc_flag & FC_ESTABLISH_LINK) { + continue; + } + clp = DD_CTL.p_config[binfo->fc_brd_no]; + if (clp[CFG_FCP_ON].a_current) { + rp = &binfo->fc_ring[FC_FCP_RING]; + + if(((clp[CFG_LINKDOWN_TMO].a_current == 0) || + clp[CFG_HOLDIO].a_current) && (binfo->fc_ffstate != FC_READY)) { + continue; + } + + ipri = disable_lock(FC_LVL, &CMD_LOCK); + fcptr = (fc_buf_t * ) rp->fc_txp.q_first; + while (fcptr != NULL) { + next_fcptr = fcptr->fc_fwd; + + if(fcptr->dev_ptr->queue_state == ACTIVE_PASSTHRU) { + /* Don't manage PASSTRU CMD HERE */ + fc_free_fcp_txq(p_dev_ctl, fcptr->iotag); + fcptr = next_fcptr; + continue; + } /* end ACTIVE_PASSTHRU management */ + + if(ntimercmp(fcptr->timeout, now, < ) && + ntimerisset(&fcptr->timeout)) { + + { + uint32 did; + uint32 pan; + uint32 sid; + + dev_ptr = fcptr->dev_ptr; + if ((dev_ptr->nodep) && (dev_ptr->nodep->nlp)) { + did = dev_ptr->nodep->nlp->nlp_DID; + pan = dev_ptr->nodep->nlp->id.nlp_pan; + sid = dev_ptr->nodep->nlp->id.nlp_sid; + } else { + did = 0; + pan = 0; + sid = 0; + } + /* SCSI timeout */ + fc_log_printf_msg_vargs( binfo->fc_brd_no, + &fc_msgBlk0754, /* ptr to msg structure */ + fc_mes0754, /* ptr to msg */ + fc_msgBlk0754.msgPreambleStr, /* begin varargs */ + did, + FC_SCSID(pan, sid) ); /* end varargs */ + } + if (!(fcptr->flags & FCBUF_ABTS2)) { + /* Operation timeout, send ABTS for this exchange */ + if (fc_abort_xri(binfo, fcptr->dev_ptr, + fcptr->iotag, ABORT_TYPE_ABTS)) { + /* ABTS not sent this time, out of IOCBs */ + goto skip_rlip; + } else { + if (fcptr->flags & FCBUF_ABTS) { + /* Second ABTS sent for this command */ + fcptr->flags |= FCBUF_ABTS2; + } else { + /* First ABTS sent for this command */ + fcptr->flags |= FCBUF_ABTS; + } + } + fcptr = next_fcptr; + continue; + } + + /* Operation timeout, start loop initialization (LIP) */ + if (dev_ptr->queue_state != STOPPING) { + dev_ptr->queue_state = HALTED; + } + + do_rlip = 1; + +skip_rlip: + sbp = fcptr->sc_bufp; + fc_deq_fcbuf_active(rp, fcptr->iotag); + + sbp->bufstruct.b_error = ETIMEDOUT; + sbp->bufstruct.b_flags |= B_ERROR; + sbp->bufstruct.b_resid = sbp->bufstruct.b_bcount; + sbp->status_validity = SC_ADAPTER_ERROR; + SET_ADAPTER_STATUS(sbp, SC_CMD_TIMEOUT) + + if (fcptr->fcp_cmd.fcpCntl2) { + /* This is a task management command */ + dev_ptr->ioctl_errno = ETIMEDOUT; + + if (dev_ptr->ioctl_wakeup == 1) { + dev_ptr->ioctl_wakeup = 0; + + fc_admin_wakeup(p_dev_ctl, dev_ptr, sbp); + } + } else { + /* Don't iodone this buf until adapter cleared out */ + if(fcptr->flags & FCBUF_INTERNAL) { + if(fcptr->fcp_cmd.fcpCdb[0] != FCP_SCSI_REPORT_LUNS) { + fc_free(p_dev_ctl, (MBUF_INFO *)sbp); + } + fc_mem_put(binfo, MEM_IOCB, (uchar * )sbp); + + if((fcptr->fcp_cmd.fcpCdb[0] == FCP_SCSI_REPORT_LUNS) && + (dev_ptr->nodep) && + (dev_ptr->nodep->rptlunstate == REPORT_LUN_ONGOING)) { + dev_ptr->nodep->flags &= ~RETRY_RPTLUN; + dev_ptr->nodep->rptlunstate = REPORT_LUN_REQUIRED; + } + } + else { + if (p_dev_ctl->timeout_head == NULL) + p_dev_ctl->timeout_head = (struct buf *)sbp; + else { + clrptr = p_dev_ctl->timeout_head; + while (clrptr->av_forw) + clrptr = clrptr->av_forw; + clrptr->av_forw = (struct buf *)sbp; + } + p_dev_ctl->timeout_count++; + } + dev_ptr->active_io_count--; + dev_ptr->nodep->num_active_io--; + sbp->bufstruct.av_forw = NULL; + } + + fc_free_fcp_txq(p_dev_ctl, fcptr->iotag); + fc_enq_fcbuf(fcptr); + } + fcptr = next_fcptr; + } + unlock_enable(ipri, &CMD_LOCK); + } + + /* fix multiple init_link problem */ + if(do_rlip) { + ipri = disable_lock(FC_LVL, &CMD_LOCK); + fc_rlip(p_dev_ctl); + unlock_enable(ipri, &CMD_LOCK); + } + continue; + } + } + + SCSI_TMO = fc_clk_set(0, 5, fc_scsi_timeout, 0, 0); + return; +} /* End fc_scsi_timeout */ + +_static_ int +fc_abort_fcp_txpq( +FC_BRD_INFO *binfo, +dvi_t *dev_ptr) +{ + fc_buf_t * fcptr1, * next_fcptr; + RING * rp; + int cnt; + fc_dev_ctl_t * p_dev_ctl; + unsigned long iflag; + + p_dev_ctl = (fc_dev_ctl_t *)binfo->fc_p_dev_ctl; + iflag = lpfc_q_disable_lock(p_dev_ctl); + rp = &binfo->fc_ring[FC_FCP_RING]; + cnt = 0; + + /* send ABTS on any outstanding I/O in txp queue */ + fcptr1 = (fc_buf_t *)rp->fc_txp.q_first; + while (fcptr1 != NULL) { + next_fcptr = fcptr1->fc_fwd; + if (fcptr1->dev_ptr == dev_ptr) { + lpfc_q_unlock_enable(p_dev_ctl, iflag); + fc_abort_xri(binfo, fcptr1->dev_ptr, fcptr1->iotag, ABORT_TYPE_ABTS); + iflag = lpfc_q_disable_lock(p_dev_ctl); + cnt++; + } + fcptr1 = next_fcptr; + } + lpfc_q_unlock_enable(p_dev_ctl, iflag); + return(cnt); +} + +/* + * Issue an ABORT_XRI_CN iocb command to abort an FCP command already issued. + */ +_static_ int +fc_abort_xri( +FC_BRD_INFO *binfo, +dvi_t *dev_ptr, +ushort iotag, +int flag) +{ + IOCB * icmd; + IOCBQ * temp; + RING * rp; + + rp = &binfo->fc_ring[FC_FCP_RING]; + + if ((binfo->fc_ffstate != FC_READY) || + (dev_ptr->nodep->rpi == 0xfffe)) { + return(1); + } + + /* Get an iocb buffer */ + if ((temp = (IOCBQ * )fc_mem_get(binfo, MEM_IOCB)) == 0) { + return(1); + } + fc_bzero((void *)temp, sizeof(IOCBQ)); + icmd = &temp->iocb; + + icmd->un.acxri.abortType = flag; + icmd->un.acxri.abortContextTag = dev_ptr->nodep->rpi; + icmd->un.acxri.abortIoTag = iotag; + + /* set up an iotag using special ABTS iotags */ + icmd->ulpIoTag = (unsigned)rp->fc_bufcnt++; + if (rp->fc_bufcnt == 0) { + rp->fc_bufcnt = MAX_FCP_CMDS; + } + + icmd->ulpLe = 1; + icmd->ulpClass = (dev_ptr->nodep->nlp->id.nlp_fcp_info & 0x0f); + icmd->ulpCommand = CMD_ABORT_XRI_CN; + icmd->ulpOwner = OWN_CHIP; + + issue_iocb_cmd(binfo, rp, temp); + + return(0); +} /* End fc_abort_xri */ + + +/* + * Issue an ABORT_XRI_CX iocb command to abort an IXri. + */ +_static_ int +fc_abort_ixri_cx( +FC_BRD_INFO *binfo, +ushort xri, +uint32 cmd, +RING *rp) +{ + IOCB * icmd; + IOCBQ * temp; + NODELIST * ndlp; + + /* Get an iocb buffer */ + if ((temp = (IOCBQ * )fc_mem_get(binfo, MEM_IOCB)) == 0) { + return(1); + } + + if( (ndlp = fc_findnode_oxri(binfo, NLP_SEARCH_MAPPED | NLP_SEARCH_UNMAPPED, xri)) == 0 ) { + fc_mem_put(binfo, MEM_IOCB, (uchar * )temp); + return (1); + } + + fc_bzero((void *)temp, sizeof(IOCBQ)); + icmd = &temp->iocb; + + icmd->un.acxri.abortType = ABORT_TYPE_ABTS; + icmd->ulpContext = xri; + + /* set up an iotag */ + icmd->ulpIoTag0 = (unsigned)rp->fc_iotag++; + if ((rp->fc_iotag & 0x3fff) == 0) { + rp->fc_iotag = 1; + } + + icmd->ulpLe = 1; + icmd->ulpClass = ndlp->id.nlp_ip_info; + icmd->ulpCommand = cmd; + icmd->ulpOwner = OWN_CHIP; + + issue_iocb_cmd(binfo, rp, temp); + + return(0); +} /* End fc_abort_ixri_cx */ + + +/**************************************************/ +/** handle_mb_cmd **/ +/** **/ +/** Description: Process a Mailbox Command. **/ +/** Called from host_interrupt to process MBATT **/ +/** **/ +/** Returns: **/ +/** **/ +/**************************************************/ +_static_ int +handle_mb_cmd( +fc_dev_ctl_t *p_dev_ctl, +MAILBOX *mb, +uint32 cmd) +{ + FC_BRD_INFO * binfo; + iCfgParam * clp; + MAILBOXQ * mbox; + NODELIST * ndlp; + NODELIST * new_ndlp; + struct buf *bp, *nextbp; + RING * rp; + int i; + void *ioa; + uint32 control, ldid, lrpi, ldata; + node_t * node_ptr; + + binfo = &BINFO; + clp = DD_CTL.p_config[binfo->fc_brd_no]; + + /* Mailbox command completed successfully, process completion */ + switch (cmd) { + case MBX_LOAD_SM: + case MBX_READ_NV: /* a READ NVPARAMS command completed */ + case MBX_WRITE_NV: /* a WRITE NVPARAMS command completed */ + case MBX_RUN_BIU_DIAG: + case MBX_INIT_LINK: /* a LINK INIT command completed */ + case MBX_SET_SLIM: + case MBX_SET_DEBUG: + case MBX_PART_SLIM: /* a PARTITION SLIM command completed */ + case MBX_CONFIG_RING: /* a CONFIGURE RING command completed */ + case MBX_RESET_RING: + case MBX_READ_CONFIG: + case MBX_READ_RCONFIG: + case MBX_READ_STATUS: + case MBX_READ_XRI: + case MBX_READ_REV: + case MBX_UNREG_D_ID: + case MBX_READ_LNK_STAT: + case MBX_DUMP_MEMORY: + case MBX_LOAD_AREA: + break; + + case MBX_CONFIG_LINK: /* a CONFIGURE LINK command completed */ + /* Change the cmdring_timeout value for IP and ELS commands */ + rp = &binfo->fc_ring[FC_ELS_RING]; + rp->fc_ringtmo = (2 * binfo->fc_ratov) + ((4 * binfo->fc_edtov) / 1000) + 1; + rp = &binfo->fc_ring[FC_IP_RING]; + rp->fc_ringtmo = (2 * binfo->fc_ratov) + ((4 * binfo->fc_edtov) / 1000) + 1; + binfo->fc_fabrictmo = (2 * binfo->fc_ratov) + ((4 * binfo->fc_edtov) / 1000) + 1; + + if (binfo->fc_ffstate == FC_CFG_LINK) { + binfo->fc_ffstate = FC_FLOGI; + if (binfo->fc_topology == TOPOLOGY_LOOP) { + /* If we are public loop and L bit was set */ + if ((binfo->fc_flag & FC_PUBLIC_LOOP) && + !(binfo->fc_flag & FC_LBIT)) { + /* Need to wait for FAN - use fabric timer for timeout. + */ + binfo->fc_fabrictmo = ((binfo->fc_edtov) / 1000) + 1; + if(FABRICTMO) { + fc_clk_res(p_dev_ctl, binfo->fc_fabrictmo, FABRICTMO); + } + else { + FABRICTMO = fc_clk_set(p_dev_ctl, binfo->fc_fabrictmo, + fc_fabric_timeout, 0, 0); + } + break; + } + + binfo->fc_fabrictmo = (2*(binfo->fc_edtov) / 1000) + 1; + if(FABRICTMO) { + fc_clk_res(p_dev_ctl, binfo->fc_fabrictmo, FABRICTMO); + } + else { + FABRICTMO = fc_clk_set(p_dev_ctl, binfo->fc_fabrictmo, + fc_fabric_timeout, 0, 0); + } + /* For power_up == 0 see fc_ffinit */ + if(p_dev_ctl->power_up) + fc_initial_flogi(p_dev_ctl); + } + else { /* pt2pt */ + /* For power_up == 0 see fc_ffinit */ + if(p_dev_ctl->power_up) + fc_initial_flogi(p_dev_ctl); + } + } else { + if (binfo->fc_flag & FC_DELAY_DISC) { + /* Config_link is done, so start discovery */ + binfo->fc_flag &= ~FC_DELAY_DISC; + fc_discovery(p_dev_ctl); + if (binfo->fc_flag & FC_FABRIC) { + /* Register with Fabric for receiving RSCNs */ + fc_els_cmd(binfo, ELS_CMD_SCR, (void *)SCR_DID, + (uint32)0, (ushort)0, (NODELIST *)0); + } + } + } + break; + + case MBX_READ_SPARM: /* a READ SPARAM command completed */ + case MBX_READ_SPARM64: /* a READ SPARAM command completed */ + { + MATCHMAP * mp; + + mp = (MATCHMAP * )binfo->fc_mbbp; + + if(mp) { + fc_mpdata_sync(mp->dma_handle, 0, sizeof(SERV_PARM), + DDI_DMA_SYNC_FORKERNEL); + fc_mpdata_outcopy(p_dev_ctl, mp, (uchar * ) & binfo->fc_sparam, + sizeof(SERV_PARM)); + + fc_mem_put(binfo, MEM_BUF, (uchar * )mp); + + binfo->fc_mbbp = 0; + + + fc_bcopy((uchar * ) & binfo->fc_sparam.nodeName, (uchar * ) & binfo->fc_nodename, + sizeof(NAME_TYPE)); + fc_bcopy((uchar * ) & binfo->fc_sparam.portName, (uchar * ) & binfo->fc_portname, + sizeof(NAME_TYPE)); + fc_bcopy(binfo->fc_portname.IEEE, p_dev_ctl->phys_addr, 6); + } + break; + } + + case MBX_READ_RPI: + case MBX_READ_RPI64: + if (binfo->fc_flag & FC_SLI2) { + /* First copy command data */ + mb = FC_SLI2_MAILBOX(binfo); + ldata = mb->un.varWords[0]; /* get rpi */ + ldata = PCIMEM_LONG(ldata); + lrpi = ldata & 0xffff; + ldata = mb->un.varWords[1]; /* get did */ + ldata = PCIMEM_LONG(ldata); + ldid = ldata & Mask_DID; + ldata = mb->un.varWords[30]; + ldata = PCIMEM_LONG(ldata); + } else { + /* First copy command data */ + ioa = (void *)FC_MAP_MEM(&binfo->fc_iomap_mem); /* map in SLIM */ + mb = FC_MAILBOX(binfo, ioa); + ldata = READ_SLIM_ADDR(binfo, (uint32 * ) & mb->un.varWords[0]); + lrpi = ldata & 0xffff; + ldata = READ_SLIM_ADDR(binfo, (uint32 * ) & mb->un.varWords[1]); + ldid = ldata & Mask_DID; + ldata = READ_SLIM_ADDR(binfo, (uint32 * ) & mb->un.varWords[30]); + FC_UNMAP_MEMIO(ioa); + } + + if (ldata == ELS_CMD_LOGO) { + if (((ndlp = fc_findnode_odid(binfo, NLP_SEARCH_ALL, ldid)) == 0) || + (!(ndlp->nlp_action & NLP_DO_ADDR_AUTH) && + !(ndlp->nlp_flag & (NLP_FARP_SND | NLP_REQ_SND)))) { + + if (ndlp) { + if (ndlp->nlp_Rpi) + break; /* Now we have an rpi so don't logout */ + } + fc_els_cmd(binfo, ELS_CMD_LOGO, (void *)((ulong)ldid), + (uint32)0, (ushort)0, ndlp); + } + } + break; + + case MBX_REG_LOGIN: + case MBX_REG_LOGIN64: + if (binfo->fc_mbbp) { + fc_mem_put(binfo, MEM_BUF, (uchar * )binfo->fc_mbbp); + binfo->fc_mbbp = 0; + } + + if (binfo->fc_flag & FC_SLI2) { + /* First copy command data */ + mb = FC_SLI2_MAILBOX(binfo); + ldata = mb->un.varWords[0]; /* get rpi */ + ldata = PCIMEM_LONG(ldata); + lrpi = ldata & 0xffff; + ldata = mb->un.varWords[1]; /* get did */ + ldata = PCIMEM_LONG(ldata); + ldid = ldata & Mask_DID; + ldata = mb->un.varWords[30]; + ldata = PCIMEM_LONG(ldata); + } else { + /* First copy command data */ + ioa = (void *)FC_MAP_MEM(&binfo->fc_iomap_mem); /* map in SLIM */ + mb = FC_MAILBOX(binfo, ioa); + ldata = READ_SLIM_ADDR(binfo, (uint32 * ) & mb->un.varWords[0]); + lrpi = ldata & 0xffff; + ldata = READ_SLIM_ADDR(binfo, (uint32 * ) & mb->un.varWords[1]); + ldid = ldata & Mask_DID; + ldata = READ_SLIM_ADDR(binfo, (uint32 * ) & mb->un.varWords[30]); + FC_UNMAP_MEMIO(ioa); + } + + /* Register RPI, will fill in XRI later */ + if ((ndlp=fc_findnode_odid(binfo, NLP_SEARCH_ALL, ldid))) { + ndlp->nlp_Rpi = (short)lrpi; + binfo->fc_nlplookup[lrpi] = ndlp; + ndlp->nlp_state = NLP_LOGIN; + /* REG_LOGIN cmpl */ + fc_log_printf_msg_vargs( binfo->fc_brd_no, + &fc_msgBlk0311, /* ptr to msg structure */ + fc_mes0311, /* ptr to msg */ + fc_msgBlk0311.msgPreambleStr, /* begin varargs */ + ndlp->nlp_DID, + ndlp->nlp_state, + ndlp->nlp_flag, + ndlp->nlp_Rpi ); /* end varargs */ + fc_nlp_unmap(binfo, ndlp); + + /* If word30 is set, send back ACC */ + if (ldata) { + REG_WD30 wd30; + + wd30.word = ldata; + + /* Wait for ACC to complete before issuing PRLI */ + fc_els_rsp(binfo, ELS_CMD_ACC, (uint32)wd30.f.xri, + (uint32)wd30.f.class, (void *)0, (uint32)sizeof(SERV_PARM), ndlp); + ndlp->nlp_flag |= NLP_REG_INP; + break; + } + + if (ndlp->nlp_DID == binfo->fc_myDID) { + ndlp->nlp_state = NLP_LOGIN; + } else { + fc_process_reglogin(p_dev_ctl, ndlp); + } + } else { + if (ldata) { + /* Dropping ELS rsp */ + fc_log_printf_msg_vargs( binfo->fc_brd_no, + &fc_msgBlk0103, /* ptr to msg structure */ + fc_mes0103, /* ptr to msg */ + fc_msgBlk0103.msgPreambleStr, /* begin varargs */ + ldata, + ldid ); /* end varargs */ + } + + /* Can't find NODELIST entry for this login, so unregister it */ + if ((mbox = (MAILBOXQ * )fc_mem_get(binfo, MEM_MBOX))) { + fc_unreg_login(binfo, lrpi, (MAILBOX * )mbox); + if (issue_mb_cmd(binfo, (MAILBOX * )mbox, MBX_NOWAIT) != MBX_BUSY) { + fc_mem_put(binfo, MEM_MBOX, (uchar * )mbox); + } + } + } + + break; + + case MBX_UNREG_LOGIN: + if (binfo->fc_flag & FC_SLI2) { + /* First copy command data */ + mb = FC_SLI2_MAILBOX(binfo); + ldata = mb->un.varWords[0]; /* get rpi */ + ldata = PCIMEM_LONG(ldata); + lrpi = ldata & 0xffff; + ldata = mb->un.varWords[30]; + ldata = PCIMEM_LONG(ldata); + } else { + /* First copy command data */ + ioa = (void *)FC_MAP_MEM(&binfo->fc_iomap_mem); /* map in SLIM */ + mb = FC_MAILBOX(binfo, ioa); + ldata = READ_SLIM_ADDR(binfo, (uint32 * ) & mb->un.varWords[0]); + lrpi = ldata & 0xffff; + ldata = READ_SLIM_ADDR(binfo, (uint32 * ) & mb->un.varWords[30]); + FC_UNMAP_MEMIO(ioa); + } + + /* If word30 is set, send back LOGO */ + if (ldata) { + fc_els_cmd(binfo, ELS_CMD_LOGO, (void *)((ulong)ldata), (uint32)0, (ushort)1, (NODELIST *)0); + } + break; + + case MBX_READ_LA: + case MBX_READ_LA64: + { + READ_LA_VAR la; + MATCHMAP * mp; + + if (binfo->fc_flag & FC_SLI2) { + /* First copy command data */ + mb = FC_SLI2_MAILBOX(binfo); + fc_pcimem_bcopy((uint32 * )((char *)mb + sizeof(uint32)), (uint32 * ) & la, + sizeof(READ_LA_VAR)); + } else { + /* First copy command data */ + ioa = (void *)FC_MAP_MEM(&binfo->fc_iomap_mem); /* map in SLIM */ + mb = FC_MAILBOX(binfo, ioa); + READ_SLIM_COPY(binfo, (uint32 * ) & la, + (uint32 * )((char *)mb + sizeof(uint32)), + (sizeof(READ_LA_VAR) / sizeof(uint32))); + FC_UNMAP_MEMIO(ioa); + } + + mp = (MATCHMAP * )binfo->fc_mbbp; + if(mp) { + fc_mpdata_sync(mp->dma_handle, 0, 128, DDI_DMA_SYNC_FORKERNEL); + fc_mpdata_outcopy(p_dev_ctl, mp, (uchar * )binfo->alpa_map, 128); + + binfo->fc_mbbp = 0; + fc_mem_put(binfo, MEM_BUF, (uchar * )mp); + } + + if (la.pb) + binfo->fc_flag |= FC_BYPASSED_MODE; + else + binfo->fc_flag &= ~FC_BYPASSED_MODE; + + if (((binfo->fc_eventTag + 1) < la.eventTag) || + (binfo->fc_eventTag == la.eventTag)) { + FCSTATCTR.LinkMultiEvent++; + if (la.attType == AT_LINK_UP) { + if (binfo->fc_eventTag != 0) { /* Pegasus */ + fc_linkdown(p_dev_ctl); + if (!(binfo->fc_flag & FC_LD_TIMER)) { + /* Start the link down watchdog timer until CLA done */ + rp = &binfo->fc_ring[FC_FCP_RING]; + RINGTMO = fc_clk_set(p_dev_ctl, rp->fc_ringtmo, + fc_linkdown_timeout, 0, 0); + if((clp[CFG_LINKDOWN_TMO].a_current == 0) || + clp[CFG_HOLDIO].a_current) { + binfo->fc_flag |= FC_LD_TIMEOUT; + } + binfo->fc_flag |= FC_LD_TIMER; + } + } + } + } + + binfo->fc_eventTag = la.eventTag; + + if (la.attType == AT_LINK_UP) { + FCSTATCTR.LinkUp++; + /* Link Up Event received */ + fc_log_printf_msg_vargs( binfo->fc_brd_no, + &fc_msgBlk1304, /* ptr to msg structure */ + fc_mes1304, /* ptr to msg */ + fc_msgBlk1304.msgPreambleStr, /* begin varargs */ + la.eventTag, + binfo->fc_eventTag, + la.granted_AL_PA, + binfo->alpa_map[0] ); /* end varargs */ + if(clp[CFG_NETWORK_ON].a_current) { + /* Stop the link down watchdog timer */ + rp = &binfo->fc_ring[FC_IP_RING]; + if(RINGTMO) { + fc_clk_can(p_dev_ctl, RINGTMO); + RINGTMO = 0; + } + } + binfo->fc_ffstate = FC_LINK_UP; + binfo->fc_flag &= ~(FC_LNK_DOWN | FC_PT2PT | FC_PT2PT_PLOGI | + FC_LBIT | FC_RSCN_MODE | FC_NLP_MORE | FC_DELAY_DISC | + FC_RSCN_DISC_TMR | FC_RSCN_DISCOVERY); + binfo->fc_ns_retry = 0; + + if( la.UlnkSpeed == LA_2GHZ_LINK) + binfo->fc_linkspeed = LA_2GHZ_LINK; + else + binfo->fc_linkspeed = 0; + + if ((binfo->fc_topology = la.topology) == TOPOLOGY_LOOP) { + + if (la.il) { + binfo->fc_flag |= FC_LBIT; + fc_freenode_did(binfo, Fabric_DID, 1); + } + + binfo->fc_myDID = la.granted_AL_PA; + + dfc_hba_put_event(p_dev_ctl, HBA_EVENT_LINK_UP, binfo->fc_myDID, + la.topology, la.lipType, la.UlnkSpeed); + dfc_put_event(p_dev_ctl, FC_REG_LINK_EVENT, 0, 0, 0); + + if (binfo->fc_flag & FC_SLI2) { + i = la.un.lilpBde64.tus.f.bdeSize; + } else { + i = la.un.lilpBde.bdeSize; + } + if (i == 0) { + binfo->alpa_map[0] = 0; + } else { + if(clp[CFG_LOG_VERBOSE].a_current & DBG_LINK_EVENT) { + int numalpa, j, k; + union { + uchar pamap[16]; + struct { + uint32 wd1; + uint32 wd2; + uint32 wd3; + uint32 wd4; + } pa; + } un; + + numalpa = binfo->alpa_map[0]; + j = 0; + while (j < numalpa) { + fc_bzero(un.pamap, 16); + for (k = 1; j < numalpa; k++) { + un.pamap[k-1] = binfo->alpa_map[j+1]; + j++; + if (k == 16) + break; + } + /* Link Up Event ALPA map */ + fc_log_printf_msg_vargs( binfo->fc_brd_no, + &fc_msgBlk1305, /* ptr to msg structure */ + fc_mes1305, /* ptr to msg */ + fc_msgBlk1305.msgPreambleStr, /* begin varargs */ + un.pa.wd1, + un.pa.wd2, + un.pa.wd3, + un.pa.wd4 ); /* end varargs */ + } + } + } + } else { + fc_freenode_did(binfo, Fabric_DID, 1); + + binfo->fc_myDID = binfo->fc_pref_DID; + + dfc_hba_put_event(p_dev_ctl, HBA_EVENT_LINK_UP, binfo->fc_myDID, + la.topology, la.lipType, la.UlnkSpeed); + dfc_put_event(p_dev_ctl, FC_REG_LINK_EVENT, 0, 0, 0); + } + + if ((mbox = (MAILBOXQ * )fc_mem_get(binfo, MEM_MBOX | MEM_PRI))) { + /* This should turn on DELAYED ABTS for ELS timeouts */ + fc_set_slim(binfo, (MAILBOX * )mbox, 0x052198, 0x1); + /* unreg_login mailbox command could be executing, + * queue this command to be processed later. + */ + fc_mbox_put(binfo, mbox); + } + + if ((mbox = (MAILBOXQ * )fc_mem_get(binfo, MEM_MBOX | MEM_PRI))) { + if(fc_read_sparam(p_dev_ctl, (MAILBOX * )mbox) == 0) { + /* set_slim mailbox command needs to execute first, + * queue this command to be processed later. + */ + fc_mbox_put(binfo, mbox); + } else { + fc_mem_put(binfo, MEM_MBOX, (uchar * )mbox); + } + } + if ((mbox = (MAILBOXQ * )fc_mem_get(binfo, MEM_MBOX | MEM_PRI))) { + binfo->fc_ffstate = FC_CFG_LINK; + fc_config_link(p_dev_ctl, (MAILBOX * )mbox); + /* read_sparam mailbox command needs to execute first, + * queue this command to be processed later. + */ + fc_mbox_put(binfo, mbox); + } + + + } /* end if link up */ + else { + FCSTATCTR.LinkDown++; + dfc_hba_put_event(p_dev_ctl, HBA_EVENT_LINK_DOWN, binfo->fc_myDID, + la.topology, la.lipType, la.UlnkSpeed); + dfc_put_event(p_dev_ctl, FC_REG_LINK_EVENT, 0, 0, 0); + /* Link Down Event received */ + fc_log_printf_msg_vargs( binfo->fc_brd_no, + &fc_msgBlk1306, /* ptr to msg structure */ + fc_mes1306, /* ptr to msg */ + fc_msgBlk1306.msgPreambleStr, /* begin varargs */ + la.eventTag, + binfo->fc_eventTag, + la.granted_AL_PA, + binfo->alpa_map[0] ); /* end varargs */ + fc_linkdown(p_dev_ctl); + + if (!(binfo->fc_flag & FC_LD_TIMER)) { + /* Start the link down watchdog timer until CLA done */ + rp = &binfo->fc_ring[FC_FCP_RING]; + RINGTMO = fc_clk_set(p_dev_ctl, rp->fc_ringtmo, + fc_linkdown_timeout, 0, 0); + if((clp[CFG_LINKDOWN_TMO].a_current == 0) || + clp[CFG_HOLDIO].a_current) { + binfo->fc_flag |= FC_LD_TIMEOUT; + } + binfo->fc_flag |= FC_LD_TIMER; + } + + /* turn on Link Attention interrupts - no CLEAR_LA needed */ + binfo->fc_process_LA = 1; + ioa = (void *)FC_MAP_IO(&binfo->fc_iomap_io); /* map in io registers */ + control = READ_CSR_REG(binfo, FC_HC_REG(binfo, ioa)); + control |= HC_LAINT_ENA; + WRITE_CSR_REG(binfo, FC_HC_REG(binfo, ioa), control); + FC_UNMAP_MEMIO(ioa); + } + break; + } + + case MBX_CLEAR_LA: + /* Turn on Link Attention interrupts */ + binfo->fc_process_LA = 1; + + ioa = (void *)FC_MAP_IO(&binfo->fc_iomap_io); /* map in io registers */ + control = READ_CSR_REG(binfo, FC_HC_REG(binfo, ioa)); + control |= HC_LAINT_ENA; + WRITE_CSR_REG(binfo, FC_HC_REG(binfo, ioa), control); + FC_UNMAP_MEMIO(ioa); + + if ((!(binfo->fc_flag & FC_LNK_DOWN)) && + (binfo->fc_ffstate != FC_ERROR) && + (mb->mbxStatus != 0x1601)) { /* Link is Up */ + + if (!(binfo->fc_flag & FC_PT2PT)) { + /* Device Discovery completes */ + fc_log_printf_msg_vargs( binfo->fc_brd_no, + &fc_msgBlk0234, /* ptr to msg structure */ + fc_mes0234, /* ptr to msg */ + fc_msgBlk0234.msgPreambleStr); /* begin & end varargs */ + binfo->fc_nlp_cnt = 0; /* In case we need to do RSCNs */ + binfo->fc_firstopen = 0; + + /* Fix up any changed RPIs in FCP IOCBs queued up a txq */ + fc_fcp_fix_txq(p_dev_ctl); + + binfo->fc_ffstate = FC_READY; + + /* Check to see if we need to process an RSCN */ + if(binfo->fc_flag & FC_RSCN_MODE) { + fc_nextrscn(p_dev_ctl, fc_max_els_sent); + } + } + + /* Do FDMI to Register HBA and port */ + if ((ndlp = fc_findnode_odid(binfo, NLP_SEARCH_ALL, FDMI_DID))) { + if (fc_fdmi_cmd(p_dev_ctl, ndlp, SLI_MGMT_DPRT)) { + /* Issue FDMI request failed */ + fc_log_printf_msg_vargs( binfo->fc_brd_no, + &fc_msgBlk0219, /* ptr to msg structure */ + fc_mes0219, /* ptr to msg */ + fc_msgBlk0219.msgPreambleStr, /* begin varargs */ + SLI_MGMT_DPRT ); /* end varargs */ + } + } + + ndlp = binfo->fc_nlpunmap_start; + if(ndlp == (NODELIST *)&binfo->fc_nlpunmap_start) + ndlp = binfo->fc_nlpmap_start; + while(ndlp != (NODELIST *)&binfo->fc_nlpmap_start) { + new_ndlp = (NODELIST *)ndlp->nlp_listp_next; + + /* skip myself, fabric nodes and partially logged in nodes */ + if ((ndlp->nlp_DID == binfo->fc_myDID) || + (ndlp->nlp_type & NLP_FABRIC) || + (ndlp->nlp_state != NLP_ALLOC)) + goto loop1; + + /* Allocate exchanges for all IP (non-FCP) nodes */ + if ((ndlp->nlp_Rpi) && + (ndlp->nlp_Xri == 0) && + ((ndlp->nlp_DID & CT_DID_MASK) != CT_DID_MASK) && + !(ndlp->nlp_flag & NLP_RPI_XRI) && + !(ndlp->nlp_type & NLP_FCP_TARGET)) { + ndlp->nlp_flag |= NLP_RPI_XRI; + fc_create_xri(binfo, &binfo->fc_ring[FC_ELS_RING], ndlp); + } + + if (ndlp->nlp_type & NLP_FCP_TARGET) { + int dev_index; + + dev_index = INDEX(ndlp->id.nlp_pan, ndlp->id.nlp_sid); + node_ptr = binfo->device_queue_hash[dev_index].node_ptr; + if(node_ptr) { + /* This is a new device that entered the loop */ + node_ptr->nlp = ndlp; + node_ptr->rpi = ndlp->nlp_Rpi; + node_ptr->last_good_rpi = ndlp->nlp_Rpi; + node_ptr->scsi_id = dev_index; + ndlp->nlp_targetp = (uchar *)node_ptr; + node_ptr->flags &= ~FC_NODEV_TMO; + ndlp->nlp_flag &= ~NLP_NODEV_TMO; + } + } + + if (ndlp->nlp_type & NLP_IP_NODE) { + fc_restartio(p_dev_ctl, ndlp); + } +loop1: + ndlp = new_ndlp; + if(ndlp == (NODELIST *)&binfo->fc_nlpunmap_start) + ndlp = binfo->fc_nlpmap_start; + } + + /* If we are not point to point, reglogin to ourself */ + if (!(binfo->fc_flag & FC_PT2PT)) { + /* Build nlplist entry and Register login to ourself */ + if ((ndlp = fc_findnode_odid(binfo, NLP_SEARCH_ALL, binfo->fc_myDID))) { + ndlp->nlp_DID = binfo->fc_myDID; + fc_nlp_logi(binfo, ndlp, &(binfo->fc_portname), &(binfo->fc_nodename)); + } + else { + if((ndlp = (NODELIST *)fc_mem_get(binfo, MEM_NLP))) { + fc_bzero((void *)ndlp, sizeof(NODELIST)); + ndlp->sync = binfo->fc_sync; + ndlp->capabilities = binfo->fc_capabilities; + ndlp->nlp_DID = binfo->fc_myDID; + ndlp->nlp_state = NLP_LIMBO; + fc_nlp_bind(binfo, ndlp); + fc_nlp_logi(binfo, ndlp, &(binfo->fc_portname), &(binfo->fc_nodename)); + } + } + if(ndlp) { + if ((mbox = (MAILBOXQ * )fc_mem_get(binfo, MEM_MBOX | MEM_PRI))){ + fc_reg_login(binfo, binfo->fc_myDID, + (uchar * ) & binfo->fc_sparam, (MAILBOX * )mbox, 0); + if (issue_mb_cmd(binfo, (MAILBOX * )mbox, MBX_NOWAIT) != MBX_BUSY) { + fc_mem_put(binfo, MEM_MBOX, (uchar * )mbox); + } + } + } + } else { + /* We are pt2pt no fabric */ + if (binfo->fc_flag & FC_PT2PT_PLOGI) { + /* Build nlplist entry and Register login to ourself */ + if ((ndlp = fc_findnode_odid(binfo, NLP_SEARCH_ALL, binfo->fc_myDID))) { + ndlp->nlp_DID = binfo->fc_myDID; + fc_nlp_logi(binfo, ndlp, &(binfo->fc_portname), &(binfo->fc_nodename)); + } + else { + if((ndlp = (NODELIST *)fc_mem_get(binfo, MEM_NLP))) { + fc_bzero((void *)ndlp, sizeof(NODELIST)); + ndlp->sync = binfo->fc_sync; + ndlp->capabilities = binfo->fc_capabilities; + ndlp->nlp_DID = binfo->fc_myDID; + ndlp->nlp_state = NLP_LIMBO; + fc_nlp_bind(binfo, ndlp); + fc_nlp_logi(binfo, ndlp, &(binfo->fc_portname), &(binfo->fc_nodename)); + } + } + if(ndlp) { + if ((mbox = (MAILBOXQ * )fc_mem_get(binfo, MEM_MBOX | MEM_PRI))){ + fc_reg_login(binfo, binfo->fc_myDID, + (uchar * ) & binfo->fc_sparam, (MAILBOX * )mbox, 0); + if (issue_mb_cmd(binfo, (MAILBOX * )mbox, MBX_NOWAIT) != MBX_BUSY) { + fc_mem_put(binfo, MEM_MBOX, (uchar * )mbox); + } + } + fc_els_cmd(binfo, ELS_CMD_PLOGI, (void *)PT2PT_RemoteID, + (uint32)0, (ushort)0, (NODELIST *)0); + } + } + } + + if(binfo->fc_flag & FC_ESTABLISH_LINK) { + binfo->fc_flag &= ~FC_ESTABLISH_LINK; + } + + if(p_dev_ctl->fc_estabtmo) { + fc_clk_can(p_dev_ctl, p_dev_ctl->fc_estabtmo); + p_dev_ctl->fc_estabtmo = 0; + } + + if(((clp[CFG_LINKDOWN_TMO].a_current == 0) || + clp[CFG_HOLDIO].a_current) && + (binfo->fc_flag & FC_LD_TIMEOUT)) { + fc_failio(p_dev_ctl); + } + + /* Stop the link down watchdog timer */ + rp = &binfo->fc_ring[FC_FCP_RING]; + if(RINGTMO) { + fc_clk_can(p_dev_ctl, RINGTMO); + RINGTMO = 0; + } + binfo->fc_flag &= ~(FC_LD_TIMEOUT | FC_LD_TIMER); + + if(clp[CFG_FCP_ON].a_current) { + fc_restart_all_devices(p_dev_ctl); + + /* Call iodone for any commands that timed out previously */ + for (bp = p_dev_ctl->timeout_head; bp != NULL; ) { + nextbp = bp->av_forw; + bp->b_error = ETIMEDOUT; + bp->b_flags |= B_ERROR; + bp->b_resid = bp->b_bcount; + FCSTATCTR.fcpScsiTmo++; + fc_do_iodone(bp); + bp = nextbp; + } + p_dev_ctl->timeout_count = 0; + p_dev_ctl->timeout_head = NULL; + + /* Send down any saved FCP commands */ + fc_issue_cmd(p_dev_ctl); + } + + if (binfo->fc_deferip) { + handle_ring_event(p_dev_ctl, FC_IP_RING, + (uint32)binfo->fc_deferip); + binfo->fc_deferip = 0; + } + } + break; + + default: + /* Unknown Mailbox command completion */ + fc_log_printf_msg_vargs( binfo->fc_brd_no, + &fc_msgBlk0312, /* ptr to msg structure */ + fc_mes0312, /* ptr to msg */ + fc_msgBlk0312.msgPreambleStr, /* begin varargs */ + cmd ); /* end varargs */ + FCSTATCTR.mboxCmdInval++; + break; + } + + binfo->fc_mbbp = 0; + return(0); +} /* End handle_mb_cmd */ + + +/**************************************************/ +/** fc_linkdown **/ +/** **/ +/** Description: Process a Link Down event. **/ +/** Called from host_intupt to process LinkDown **/ +/** **/ +/** Returns: **/ +/** **/ +/**************************************************/ +_static_ int +fc_linkdown( +fc_dev_ctl_t *p_dev_ctl) +{ + FC_BRD_INFO * binfo; + iCfgParam * clp; + RING * rp; + NODELIST * ndlp; + NODELIST * new_ndlp; + MAILBOXQ * mb; + IOCBQ * xmitiq; + IOCBQ * iocbq; + MATCHMAP * mp; + ULP_BDE64 * addr; + + binfo = &BINFO; + binfo->fc_prevDID = binfo->fc_myDID; + binfo->fc_ffstate = FC_LINK_DOWN; + binfo->fc_flag |= FC_LNK_DOWN; + binfo->fc_flag &= ~FC_DELAY_PLOGI; + + + if ((mb = (MAILBOXQ * )fc_mem_get(binfo, MEM_MBOX | MEM_PRI))) { + fc_unreg_did(binfo, 0xffffffff, (MAILBOX * )mb); + if (issue_mb_cmd(binfo, (MAILBOX * )mb, MBX_NOWAIT) != MBX_BUSY) { + fc_mem_put(binfo, MEM_MBOX, (uchar * )mb); + } + } + + /* Free all nodes in nlplist */ + ndlp = binfo->fc_nlpbind_start; + if(ndlp == (NODELIST *)&binfo->fc_nlpbind_start) + ndlp = binfo->fc_nlpunmap_start; + if(ndlp == (NODELIST *)&binfo->fc_nlpunmap_start) + ndlp = binfo->fc_nlpmap_start; + while(ndlp != (NODELIST *)&binfo->fc_nlpmap_start) { + new_ndlp = (NODELIST *)ndlp->nlp_listp_next; + + /* Any RSCNs in progress don't matter at this point */ + ndlp->nlp_action &= ~NLP_DO_RSCN; + + if ((ndlp->nlp_type & NLP_IP_NODE) && ndlp->nlp_bp) { + m_freem((fcipbuf_t *)ndlp->nlp_bp); + ndlp->nlp_bp = (uchar * )0; + } + + /* Need to abort all exchanges, used only on IP */ + if (ndlp->nlp_Xri) { + fc_rpi_abortxri(binfo, ndlp->nlp_Xri); + ndlp->nlp_Xri = 0; + } + + /* Need to free all nodes in the process of login / registration + * as well as all Fabric nodes and myself. + */ + if ((ndlp->nlp_DID == binfo->fc_myDID) || + (!(ndlp->nlp_type & NLP_FABRIC) && ((ndlp->nlp_DID & CT_DID_MASK) == CT_DID_MASK)) || + (binfo->fc_flag & FC_PT2PT) || + (ndlp->nlp_state < NLP_ALLOC)) { + NAME_TYPE zero_pn; + + fc_bzero((void *)&zero_pn, sizeof(NAME_TYPE)); + if ((fc_geportname(&ndlp->nlp_portname, &zero_pn) == 2) && + (ndlp->nlp_state < NLP_LOGIN) && + ((ndlp->nlp_type & (NLP_AUTOMAP | NLP_SEED_MASK)) == 0)) { + fc_freenode(binfo, ndlp, 1); + } + else { + fc_freenode(binfo, ndlp, 0); + ndlp->nlp_state = NLP_LIMBO; + fc_nlp_bind(binfo, ndlp); + } + } + + /* If we are not using ADISC, free fcp nodes here to avoid excessive + * actitivity when during PLOGIs when link comes back up. + */ + clp = DD_CTL.p_config[binfo->fc_brd_no]; + if((ndlp->nlp_state == NLP_ALLOC) && + (ndlp->nlp_type & NLP_FCP_TARGET) && + ((!clp[CFG_USE_ADISC].a_current))) { + fc_freenode(binfo, ndlp, 0); + ndlp->nlp_state = NLP_LIMBO; + fc_nlp_bind(binfo, ndlp); + } + + /* Any Discovery in progress doesn't matter at this point */ + ndlp->nlp_action &= ~(NLP_DO_ADDR_AUTH | NLP_DO_DISC_START); + + ndlp = new_ndlp; + if(ndlp == (NODELIST *)&binfo->fc_nlpbind_start) + ndlp = binfo->fc_nlpunmap_start; + if(ndlp == (NODELIST *)&binfo->fc_nlpunmap_start) + ndlp = binfo->fc_nlpmap_start; + } + + if (binfo->fc_flag & FC_PT2PT) { + binfo->fc_myDID = 0; + if ((mb = (MAILBOXQ * )fc_mem_get(binfo, MEM_MBOX | MEM_PRI))) { + fc_config_link(p_dev_ctl, (MAILBOX * )mb); + if (issue_mb_cmd(binfo, (MAILBOX * )mb, MBX_NOWAIT) != MBX_BUSY) { + fc_mem_put(binfo, MEM_MBOX, (uchar * )mb); + } + } + binfo->fc_flag &= ~(FC_PT2PT | FC_PT2PT_PLOGI); + } + + clp = DD_CTL.p_config[binfo->fc_brd_no]; + if(clp[CFG_NETWORK_ON].a_current) { + rp = &binfo->fc_ring[FC_IP_RING]; + /* flush all xmit compls */ + while ((xmitiq = fc_ringtxp_get(rp, 0)) != 0) { + fc_freebufq(p_dev_ctl, rp, xmitiq); + } + NDDSTAT.ndd_xmitque_cur = 0; + } + + + fc_flush_clk_set(p_dev_ctl, fc_delay_timeout); + + if(FABRICTMO) { + fc_clk_can(p_dev_ctl, FABRICTMO); + FABRICTMO = 0; + } + + if(binfo->fc_rscn_disc_wdt) { + fc_clk_can(p_dev_ctl, binfo->fc_rscn_disc_wdt); + binfo->fc_rscn_disc_wdt = 0; + } + binfo->fc_flag &= ~(FC_RSCN_MODE | FC_RSCN_DISC_TMR | FC_RSCN_DISCOVERY); + binfo->fc_rscn_id_cnt = 0; + + /* Free any deferred RSCNs */ + fc_flush_rscn_defer(p_dev_ctl); + + /* Free any delayed ELS xmits */ + fc_abort_delay_els_cmd(p_dev_ctl, 0xffffffff); + + /* Look through ELS ring and remove any ELS cmds in progress */ + rp = &binfo->fc_ring[FC_ELS_RING]; + iocbq = (IOCBQ * )(rp->fc_txp.q_first); + while (iocbq) { + iocbq->retry = 0xff; /* Mark for abort */ + iocbq = (IOCBQ * )iocbq->q; + } + + if (rp->fc_tx.q_cnt) { + IOCB * icmd; + /* get next command from ring xmit queue */ + xmitiq = fc_ringtx_get(rp); + + while (xmitiq) { + icmd = &xmitiq->iocb; + if (icmd->ulpCommand == CMD_IOCB_CONTINUE_CN) { + fc_mem_put(binfo, MEM_IOCB, (uchar * )xmitiq); + xmitiq = fc_ringtx_get(rp); + continue; + } + + if(xmitiq->bp) { + fc_mem_put(binfo, MEM_BUF, (uchar * )xmitiq->bp); + } + + if (binfo->fc_flag & FC_SLI2) { + + mp = (MATCHMAP *)xmitiq->bpl; + if(mp) { + addr = (ULP_BDE64 * )mp->virt; + addr++; /* goto the next one */ + + switch (icmd->ulpCommand) { + case CMD_ELS_REQUEST_CR: + case CMD_ELS_REQUEST64_CR: + case CMD_ELS_REQUEST_CX: + case CMD_ELS_REQUEST64_CX: + fc_mem_put(binfo, MEM_BUF, (uchar * )xmitiq->info); + break; + default: + if(xmitiq->info) + fc_mem_put(binfo, MEM_BUF, (uchar * )xmitiq->info); + } + fc_mem_put(binfo, MEM_BPL, (uchar * )mp); + } + } + else { + if (icmd->un.cont[1].bdeAddress) { + fc_mem_put(binfo, MEM_BUF, (uchar * )xmitiq->info); + } + } + fc_mem_put(binfo, MEM_IOCB, (uchar * )xmitiq); + xmitiq = fc_ringtx_get(rp); + } + } + + return(0); +} /* End fc_linkdown */ + +/**************************************************/ +/** fc_rlip **/ +/** **/ +/** Description: **/ +/** Called to reset the link with an init_link **/ +/** **/ +/** Returns: **/ +/** **/ +/**************************************************/ +_static_ int +fc_rlip( +fc_dev_ctl_t *p_dev_ctl) +{ + FC_BRD_INFO * binfo; + iCfgParam * clp; + MAILBOX * mb; + + binfo = &BINFO; + + /* Start the Fibre Channel reset LIP process */ + if (binfo->fc_ffstate == FC_READY) { + /* Get a buffer to use for the mailbox command */ + if ((mb = (MAILBOX * )fc_mem_get(binfo, MEM_MBOX | MEM_PRI)) == NULL) { + /* Device Discovery completion error */ + fc_log_printf_msg_vargs( binfo->fc_brd_no, + &fc_msgBlk0235, /* ptr to msg structure */ + fc_mes0235, /* ptr to msg */ + fc_msgBlk0235.msgPreambleStr); /* begin & end varargs */ + binfo->fc_ffstate = FC_ERROR; + return(1); + } + + binfo->fc_flag |= FC_SCSI_RLIP; + clp = DD_CTL.p_config[binfo->fc_brd_no]; + + /* Setup and issue mailbox INITIALIZE LINK command */ + fc_linkdown(p_dev_ctl); + fc_init_link(binfo, (MAILBOX * )mb, clp[CFG_TOPOLOGY].a_current, clp[CFG_LINK_SPEED].a_current); + mb->un.varInitLnk.lipsr_AL_PA = 0; + if (issue_mb_cmd(binfo, (MAILBOX * )mb, MBX_NOWAIT) != MBX_BUSY) + fc_mem_put(binfo, MEM_MBOX, (uchar * )mb); + /* SCSI Link Reset */ + fc_log_printf_msg_vargs( binfo->fc_brd_no, + &fc_msgBlk1307, /* ptr to msg structure */ + fc_mes1307, /* ptr to msg */ + fc_msgBlk1307.msgPreambleStr); /* begin & end varargs */ + } + return(0); +} /* End fc_rlip */ + +/**************************************************/ +/** fc_ns_cmd **/ +/** **/ +/** Description: **/ +/** Issue Cmd to NameServer **/ +/** SLI_CTNS_GID_FT **/ +/** SLI_CTNS_RFT_ID **/ +/** **/ +/** Returns: **/ +/** **/ +/**************************************************/ +_static_ int +fc_ns_cmd( +fc_dev_ctl_t *p_dev_ctl, +NODELIST *ndlp, +int cmdcode) +{ + FC_BRD_INFO * binfo; + iCfgParam * clp; + MATCHMAP * mp, *bmp; + SLI_CT_REQUEST * CtReq; + ULP_BDE64 * bpl; + + binfo = &BINFO; + + /* fill in BDEs for command */ + /* Allocate buffer for command payload */ + if ((mp = (MATCHMAP * )fc_mem_get(binfo, MEM_BUF)) == 0) { + return(1); + } + + bmp = 0; + + /* Allocate buffer for Buffer ptr list */ + if ((bmp = (MATCHMAP * )fc_mem_get(binfo, MEM_BPL)) == 0) { + fc_mem_put(binfo, MEM_BUF, (uchar * )mp); + return(1); + } + bpl = (ULP_BDE64 * )bmp->virt; + bpl->addrHigh = PCIMEM_LONG((uint32)putPaddrHigh(mp->phys)); + bpl->addrLow = PCIMEM_LONG((uint32)putPaddrLow(mp->phys)); + bpl->tus.f.bdeFlags = 0; + if (cmdcode == SLI_CTNS_GID_FT) + bpl->tus.f.bdeSize = GID_REQUEST_SZ; + else if (cmdcode == SLI_CTNS_RFT_ID) + bpl->tus.f.bdeSize = RFT_REQUEST_SZ; + else + bpl->tus.f.bdeSize = 0; + bpl->tus.w = PCIMEM_LONG(bpl->tus.w); + + CtReq = (SLI_CT_REQUEST * )mp->virt; + /* NameServer Req */ + fc_log_printf_msg_vargs( binfo->fc_brd_no, + &fc_msgBlk0236, /* ptr to msg structure */ + fc_mes0236, /* ptr to msg */ + fc_msgBlk0236.msgPreambleStr, /* begin varargs */ + cmdcode, + binfo->fc_flag, + binfo->fc_rscn_id_cnt); /* end varargs */ + fc_bzero((void *)CtReq, sizeof(SLI_CT_REQUEST)); + + CtReq->RevisionId.bits.Revision = SLI_CT_REVISION; + CtReq->RevisionId.bits.InId = 0; + + CtReq->FsType = SLI_CT_DIRECTORY_SERVICE; + CtReq->FsSubType = SLI_CT_DIRECTORY_NAME_SERVER; + + CtReq->CommandResponse.bits.Size = 0; + switch (cmdcode) { + case SLI_CTNS_GID_FT: + CtReq->CommandResponse.bits.CmdRsp = SWAP_DATA16(SLI_CTNS_GID_FT); + CtReq->un.gid.Fc4Type = SLI_CTPT_FCP; + if(binfo->fc_ffstate != FC_READY) + binfo->fc_ffstate = FC_NS_QRY; + break; + case SLI_CTNS_RFT_ID: + clp = DD_CTL.p_config[binfo->fc_brd_no]; + CtReq->CommandResponse.bits.CmdRsp = SWAP_DATA16(SLI_CTNS_RFT_ID); + CtReq->un.rft.PortId = SWAP_DATA(binfo->fc_myDID); + if(clp[CFG_FCP_ON].a_current) { + CtReq->un.rft.fcpReg = 1; + } + if(clp[CFG_NETWORK_ON].a_current) { + CtReq->un.rft.ipReg = 1; + } + if(binfo->fc_ffstate != FC_READY) + binfo->fc_ffstate = FC_NS_REG; + break; + } + + binfo->fc_ns_retry++; + if(FABRICTMO) { + fc_clk_can(p_dev_ctl, FABRICTMO); + } + FABRICTMO = fc_clk_set(p_dev_ctl, binfo->fc_ratov, + fc_fabric_timeout, 0, 0); + + if(fc_ct_cmd(p_dev_ctl, mp, bmp, ndlp)) { + fc_mem_put(binfo, MEM_BUF, (uchar * )mp); + fc_mem_put(binfo, MEM_BPL, (uchar * )bmp); + } + return(0); +} /* End fc_ns_cmd */ + +_static_ int +fc_free_ct_rsp( +fc_dev_ctl_t * p_dev_ctl, +MATCHMAP * mlist) +{ + FC_BRD_INFO * binfo; + MATCHMAP * mlast; + + binfo = &BINFO; + while(mlist) { + mlast = mlist; + mlist = (MATCHMAP *)mlist->fc_mptr; + + fc_mem_put(binfo, MEM_BUF, (uchar * )mlast); + } + return(0); +} + +_local_ MATCHMAP * +fc_alloc_ct_rsp( +fc_dev_ctl_t * p_dev_ctl, +ULP_BDE64 * bpl, +uint32 size, +int * entries) +{ + FC_BRD_INFO * binfo; + MATCHMAP * mlist; + MATCHMAP * mlast; + MATCHMAP * mp; + int cnt, i; + + binfo = &BINFO; + mlist = 0; + mlast = 0; + i = 0; + + while(size) { + + /* We get chucks of FCELSSIZE */ + if(size > FCELSSIZE) + cnt = FCELSSIZE; + else + cnt = size; + + /* Allocate buffer for rsp payload */ + if ((mp = (MATCHMAP * )fc_mem_get(binfo, MEM_BUF)) == 0) { + fc_free_ct_rsp(p_dev_ctl, mlist); + return(0); + } + + /* Queue it to a linked list */ + if(mlast == 0) { + mlist = mp; + mlast = mp; + } + else { + mlast->fc_mptr = (uchar *)mp; + mlast = mp; + } + mp->fc_mptr = 0; + + bpl->tus.f.bdeFlags = BUFF_USE_RCV; + + /* build buffer ptr list for IOCB */ + bpl->addrLow = PCIMEM_LONG(putPaddrLow((ulong)mp->phys)); + bpl->addrHigh = PCIMEM_LONG(putPaddrHigh((ulong)mp->phys)); + bpl->tus.f.bdeSize = (ushort)cnt; + bpl->tus.w = PCIMEM_LONG(bpl->tus.w); + bpl++; + + i++; + size -= cnt; + } + + *entries = i; + return(mlist); +} + +_static_ int +fc_ct_cmd( +fc_dev_ctl_t *p_dev_ctl, +MATCHMAP *inmp, +MATCHMAP *bmp, +NODELIST *ndlp) +{ + FC_BRD_INFO * binfo; + ULP_BDE64 * bpl; + MATCHMAP * outmp; + int cnt; + + binfo = &BINFO; + bpl = (ULP_BDE64 * )bmp->virt; + bpl++; /* Skip past ct request */ + + cnt = 0; + /* Put buffer(s) for ct rsp in bpl */ + if((outmp = fc_alloc_ct_rsp(p_dev_ctl, bpl, FC_MAX_NS_RSP, &cnt)) == 0) { + return(ENOMEM); + } + + /* save ndlp for cmpl */ + inmp->fc_mptr = (uchar *)ndlp; + + if((fc_gen_req(binfo, bmp, inmp, outmp, ndlp->nlp_Rpi, 0, (cnt+1), 0))) { + fc_free_ct_rsp(p_dev_ctl, outmp); + return(ENOMEM); + } + return(0); +} /* End fc_ct_cmd */ + + +/**************************************************/ +/** fc_ns_rsp **/ +/** **/ +/** Description: **/ +/** Process NameServer response **/ +/** **/ +/** Returns: **/ +/** **/ +/**************************************************/ +_static_ int +fc_ns_rsp( +fc_dev_ctl_t *p_dev_ctl, +NODELIST *nslp, +MATCHMAP *mp, +uint32 Size) +{ + FC_BRD_INFO * binfo; + SLI_CT_REQUEST * Response; + NODELIST * ndlp; + NODELIST * new_ndlp; + MATCHMAP * mlast; + D_ID rscn_did; + D_ID ns_did; + uint32 * tptr; + uint32 Did; + uint32 Temp; + int j, Cnt, match, new_node; + + binfo = &BINFO; + ndlp = 0; + binfo->fc_ns_retry = 0; + + binfo->fc_fabrictmo = (2 * binfo->fc_ratov) + + ((4 * binfo->fc_edtov) / 1000) + 1; + if(FABRICTMO) { + fc_clk_can(p_dev_ctl, FABRICTMO); + FABRICTMO = 0; + } + + Response = (SLI_CT_REQUEST * )mp->virt; + + if ((Response->CommandResponse.bits.CmdRsp == SWAP_DATA16(SLI_CT_RESPONSE_FS_ACC)) && + ((binfo->fc_ffstate == FC_NS_QRY) || + ((binfo->fc_ffstate == FC_READY) && (binfo->fc_flag & FC_RSCN_MODE)))) { + + tptr = (uint32 * ) & Response->un.gid.PortType; + while(mp) { + mlast = mp; + mp = (MATCHMAP *)mp->fc_mptr; + fc_mpdata_sync(mlast->dma_handle, 0, 0, DDI_DMA_SYNC_FORKERNEL); + + if(Size > FCELSSIZE) + Cnt = FCELSSIZE; + else + Cnt = Size; + Size -= Cnt; + + if(tptr == 0) + tptr = (uint32 * )mlast->virt; + else + Cnt -= 16; /* subtract length of CT header */ + + while(Cnt) { + /* Loop through entire NameServer list of DIDs */ + + /* Get next DID from NameServer List */ + Temp = *tptr++; + Did = (SWAP_DATA(Temp) & Mask_DID); + + ndlp = 0; + if ((Did) && (Did != binfo->fc_myDID)) { + new_node = 0; + ndlp = fc_findnode_odid(binfo, NLP_SEARCH_ALL, Did); + if(ndlp) { + ndlp->nlp_DID = Did; + /* Skip nodes already marked for discovery / rscn */ + if(ndlp->nlp_action & + (NLP_DO_ADDR_AUTH | NLP_DO_DISC_START | NLP_DO_RSCN)) + goto nsout; + } + else { + new_node = 1; + if((ndlp = (NODELIST *)fc_mem_get(binfo, MEM_NLP))) { + fc_bzero((void *)ndlp, sizeof(NODELIST)); + ndlp->sync = binfo->fc_sync; + ndlp->capabilities = binfo->fc_capabilities; + ndlp->nlp_DID = Did; + fc_nlp_bind(binfo, ndlp); + } + else + goto nsout; + } + + if ((new_node) || + (!(ndlp->nlp_flag & NLP_REQ_SND) && + (ndlp->nlp_state < NLP_ALLOC)) ) { + + if ((binfo->fc_ffstate == FC_READY) && + (binfo->fc_flag & FC_RSCN_MODE)) { + /* we are in RSCN node, so match Did from NameServer with + * with list recieved from previous RSCN commands. + * Do NOT add it to our RSCN discovery list unless we have + * a match. + */ + match = 0; + for(j=0;jfc_rscn_id_cnt;j++) { + + rscn_did.un.word = binfo->fc_rscn_id_list[j]; + ns_did.un.word = Did; + + switch (rscn_did.un.b.resv) { + case 0: /* Single N_Port ID effected */ + if (ns_did.un.word == rscn_did.un.word) { + match = 1; + } + break; + + case 1: /* Whole N_Port Area effected */ + if ((ns_did.un.b.domain == rscn_did.un.b.domain) && + (ns_did.un.b.area == rscn_did.un.b.area)) { + match = 1; + } + break; + + case 2: /* Whole N_Port Domain effected */ + if (ns_did.un.b.domain == rscn_did.un.b.domain) { + match = 1; + } + break; + + case 3: /* Whole Fabric effected */ + match = 1; + break; + + default: + /* Unknown Identifier in RSCN list */ + fc_log_printf_msg_vargs( binfo->fc_brd_no, + &fc_msgBlk0237, /* ptr to msg structure */ + fc_mes0237, /* ptr to msg */ + fc_msgBlk0237.msgPreambleStr, /* begin varargs */ + rscn_did.un.word); /* end varargs */ + break; + + } + if(match) + break; + } + if(match == 0) /* Skip it */ + goto nsout; + } + + /* Add it to our discovery list */ + ndlp->nlp_state = NLP_LIMBO; + fc_nlp_bind(binfo, ndlp); + if ((binfo->fc_ffstate == FC_READY) && + (binfo->fc_flag & FC_RSCN_MODE)) { + ndlp->nlp_action |= NLP_DO_RSCN; + ndlp->nlp_flag &= ~NLP_NODEV_TMO; + } + else { + ndlp->nlp_action |= NLP_DO_DISC_START; + } + } + else { + if (binfo->fc_ffstate < FC_READY) { + /* Add it to our discovery list */ + ndlp->nlp_state = NLP_LIMBO; + fc_nlp_bind(binfo, ndlp); + ndlp->nlp_action |= NLP_DO_DISC_START; + } + } + } +nsout: + + /* Mark all node table entries that are in the Nameserver */ + if(ndlp) { + ndlp->nlp_flag |= NLP_NS_NODE; + ndlp->nlp_flag &= ~NLP_NS_REMOVED; + /* NameServer Rsp */ + fc_log_printf_msg_vargs( binfo->fc_brd_no, + &fc_msgBlk0238, /* ptr to msg structure */ + fc_mes0238, /* ptr to msg */ + fc_msgBlk0238.msgPreambleStr, /* begin varargs */ + Did, + ndlp->nlp_flag, + binfo->fc_flag, + binfo->fc_rscn_id_cnt); /* end varargs */ + } + else { + /* NameServer Rsp */ + fc_log_printf_msg_vargs( binfo->fc_brd_no, + &fc_msgBlk0239, /* ptr to msg structure */ + fc_mes0239, /* ptr to msg */ + fc_msgBlk0239.msgPreambleStr, /* begin varargs */ + Did, + (ulong)ndlp, + binfo->fc_flag, + binfo->fc_rscn_id_cnt); /* end varargs */ + } + + if (Temp & SWAP_DATA(SLI_CT_LAST_ENTRY)) + goto nsout1; + Cnt -= sizeof(uint32); + } + tptr = 0; + } + +nsout1: + /* Take out all node table entries that are not in the NameServer */ + ndlp = binfo->fc_nlpbind_start; + if(ndlp == (NODELIST *)&binfo->fc_nlpbind_start) + ndlp = binfo->fc_nlpunmap_start; + if(ndlp == (NODELIST *)&binfo->fc_nlpunmap_start) + ndlp = binfo->fc_nlpmap_start; + while(ndlp != (NODELIST *)&binfo->fc_nlpmap_start) { + new_ndlp = (NODELIST *)ndlp->nlp_listp_next; + if ( (ndlp->nlp_state == NLP_LIMBO) || + (ndlp->nlp_state == NLP_SEED) || + (ndlp->nlp_DID == binfo->fc_myDID) || + (ndlp->nlp_DID == NameServer_DID) || + (ndlp->nlp_DID == FDMI_DID) || + (ndlp->nlp_type & NLP_FABRIC) || + (ndlp->nlp_flag & NLP_NS_NODE)) { + if(ndlp->nlp_flag & NLP_NS_NODE) { + ndlp->nlp_flag &= ~NLP_NS_NODE; + } else { + if(ndlp->nlp_DID != NameServer_DID) + ndlp->nlp_action &= ~(NLP_DO_ADDR_AUTH | NLP_DO_DISC_START | NLP_DO_RSCN); + } + goto loop1; + } + if ((binfo->fc_ffstate == FC_READY) && + (binfo->fc_flag & FC_RSCN_MODE) && + !(ndlp->nlp_action & NLP_DO_RSCN)) + goto loop1; + + if ((ndlp->nlp_DID != 0) && !(ndlp->nlp_flag & NLP_NODEV_TMO)) { + RING * rp; + IOCBQ * iocbq; + /* Look through ELS ring and remove any ELS cmds in progress */ + rp = &binfo->fc_ring[FC_ELS_RING]; + iocbq = (IOCBQ * )(rp->fc_txp.q_first); + while (iocbq) { + if(iocbq->iocb.un.elsreq.remoteID == ndlp->nlp_DID) { + iocbq->retry = 0xff; /* Mark for abort */ + } + iocbq = (IOCBQ * )iocbq->q; + } + /* In case its on fc_delay_timeout list */ + fc_abort_delay_els_cmd(p_dev_ctl, ndlp->nlp_DID); + + ndlp->nlp_flag &= ~(NLP_REQ_SND | NLP_REQ_SND_ADISC); + } + + ndlp->nlp_action &= ~(NLP_DO_ADDR_AUTH | NLP_DO_DISC_START | NLP_DO_RSCN); + fc_freenode(binfo, ndlp, 0); + ndlp->nlp_state = NLP_LIMBO; + fc_nlp_bind(binfo, ndlp); + ndlp->nlp_flag |= NLP_NS_REMOVED; + ndlp->nlp_type &= ~(NLP_FABRIC | NLP_IP_NODE); +loop1: + ndlp = new_ndlp; + if(ndlp == (NODELIST *)&binfo->fc_nlpbind_start) + ndlp = binfo->fc_nlpunmap_start; + if(ndlp == (NODELIST *)&binfo->fc_nlpunmap_start) + ndlp = binfo->fc_nlpmap_start; + } + + } else if ((Response->CommandResponse.bits.CmdRsp == SWAP_DATA16(SLI_CT_RESPONSE_FS_RJT)) && + ((binfo->fc_ffstate == FC_NS_QRY) || + ((binfo->fc_ffstate == FC_READY) && (binfo->fc_flag & FC_RSCN_MODE)))) { + /* NameServer Rsp Error */ + fc_log_printf_msg_vargs( binfo->fc_brd_no, + &fc_msgBlk0240, /* ptr to msg structure */ + fc_mes0240, /* ptr to msg */ + fc_msgBlk0240.msgPreambleStr, /* begin varargs */ + Response->CommandResponse.bits.CmdRsp, + (uint32)Response->ReasonCode, + (uint32)Response->Explanation, + binfo->fc_flag); /* end varargs */ + goto nsout1; + + } else { + /* NameServer Rsp Error */ + fc_log_printf_msg_vargs( binfo->fc_brd_no, + &fc_msgBlk0241, /* ptr to msg structure */ + fc_mes0241, /* ptr to msg */ + fc_msgBlk0241.msgPreambleStr, /* begin varargs */ + Response->CommandResponse.bits.CmdRsp, + (uint32)Response->ReasonCode, + (uint32)Response->Explanation, + binfo->fc_flag); /* end varargs */ + } + + if (binfo->fc_ffstate == FC_NS_REG) { + /* Issue GID_FT to Nameserver */ + if (fc_ns_cmd(p_dev_ctl, nslp, SLI_CTNS_GID_FT)) + goto out; + } else { +out: + /* Done with NameServer for now, but leave logged in */ + + /* We can start discovery right now */ + /* Fire out PLOGIs on all nodes marked for discovery */ + binfo->fc_rscn_id_cnt = 0; + if ((binfo->fc_nlp_cnt <= 0) && !(binfo->fc_flag & FC_NLP_MORE)) { + binfo->fc_nlp_cnt = 0; + if ((binfo->fc_ffstate == FC_READY) && + (binfo->fc_flag & FC_RSCN_MODE)) { + nslp->nlp_action &= ~(NLP_DO_ADDR_AUTH | NLP_DO_RSCN); + fc_nextrscn(p_dev_ctl, fc_max_els_sent); + } + else { + nslp->nlp_action |= NLP_DO_ADDR_AUTH; + fc_nextnode(p_dev_ctl, nslp); + } + } + else { + nslp->nlp_action |= NLP_DO_ADDR_AUTH; + fc_nextnode(p_dev_ctl, nslp); + } + } + return(0); +} /* End fc_ns_rsp */ + +/**************************************************/ +/** fc_free_clearq **/ +/** **/ +/** Description: **/ +/** Called to free all clearq bufs for a device **/ +/** **/ +/** Returns: **/ +/** **/ +/**************************************************/ +_static_ void +fc_free_clearq( +dvi_t *dev_ptr) +{ + struct buf *bp, *nextbp; + FC_BRD_INFO * binfo; + + binfo = &dev_ptr->nodep->ap->info; + + /* Call iodone for all the CLEARQ error bufs */ + for (bp = dev_ptr->clear_head; bp != NULL; ) { + dev_ptr->clear_count--; + nextbp = bp->av_forw; + FCSTATCTR.fcpScsiTmo++; + fc_do_iodone(bp); + bp = nextbp; + } + dev_ptr->clear_head = NULL; + dev_ptr->flags &= ~SCSI_TQ_HALTED & ~SCSI_TQ_CLEARING; + + fc_restart_device(dev_ptr); + return; +} /* End fc_free_clearq */ + + +/****************************************************/ +/** fc_nextnode **/ +/** **/ +/** Description: **/ +/** Called during discovery or rediscovery **/ +/** **/ +/** Returns: **/ +/** **/ +/****************************************************/ +_static_ int +fc_nextnode( +fc_dev_ctl_t *p_dev_ctl, +NODELIST *ndlp) +{ + FC_BRD_INFO * binfo; + node_t * node_ptr; + dvi_t * dev_ptr; + iCfgParam * clp; + + binfo = &BINFO; + binfo->fc_fabrictmo = (2 * binfo->fc_ratov) + + ((4 * binfo->fc_edtov) / 1000) + 1; + + clp = DD_CTL.p_config[binfo->fc_brd_no]; + + /* Device Discovery nextnode */ + fc_log_printf_msg_vargs( binfo->fc_brd_no, + &fc_msgBlk0242, /* ptr to msg structure */ + fc_mes0242, /* ptr to msg */ + fc_msgBlk0242.msgPreambleStr, /* begin varargs */ + (uint32)ndlp->nlp_state, + ndlp->nlp_DID, + (uint32)ndlp->nlp_flag, + binfo->fc_ffstate); /* end varargs */ + if (binfo->fc_flag & FC_FABRIC) { + if (binfo->fc_ffstate < FC_NS_QRY) { + return(0); + } + if ((binfo->fc_ffstate < FC_NODE_DISC) && binfo->fc_ns_retry) { + return(0); + } + } + + if(FABRICTMO) { + fc_clk_res(p_dev_ctl, binfo->fc_fabrictmo, FABRICTMO); + } + else { + FABRICTMO = fc_clk_set(p_dev_ctl, binfo->fc_fabrictmo, + fc_fabric_timeout, 0, 0); + } + + if ((ndlp->nlp_type & NLP_FCP_TARGET) && (ndlp->nlp_state == NLP_ALLOC)) { + if(clp[CFG_FIRST_CHECK].a_current) { + /* If we are an FCP node, update first_check flag for all LUNs */ + if ((node_ptr = (node_t * )ndlp->nlp_targetp) != NULL) { + for (dev_ptr = node_ptr->lunlist; dev_ptr != NULL; + dev_ptr = dev_ptr->next) { + dev_ptr->first_check = FIRST_CHECK_COND; + fc_device_changed(p_dev_ctl, dev_ptr); + } + } + } + } + + /* Check for ADISC Address Authentication */ + if (ndlp->nlp_action & NLP_DO_ADDR_AUTH) { + ndlp->nlp_flag &= ~(NLP_REQ_SND | NLP_REQ_SND_ADISC); + ndlp->nlp_action &= ~NLP_DO_ADDR_AUTH; + + if(ndlp->nlp_DID != NameServer_DID) + binfo->fc_nlp_cnt--; + + if (binfo->fc_nlp_cnt <= 0) { + /* If no nodes left to authenticate, redo discovery on any + * new nodes. + */ + if (fc_nextauth(p_dev_ctl, fc_max_els_sent) == 0) { + binfo->fc_nlp_cnt = 0; + fc_nextdisc(p_dev_ctl, fc_max_els_sent); + } + } else { + fc_nextauth(p_dev_ctl, 1); + } + + return(0); + } + + /* Check for RSCN Discovery */ + if (ndlp->nlp_action & NLP_DO_RSCN) { + ndlp->nlp_flag &= ~(NLP_REQ_SND | NLP_REQ_SND_ADISC); + ndlp->nlp_action &= ~NLP_DO_RSCN; + binfo->fc_nlp_cnt--; + if ((ndlp->nlp_type & NLP_IP_NODE) && ndlp->nlp_bp) { + m_freem((fcipbuf_t *)ndlp->nlp_bp); + ndlp->nlp_bp = (uchar * )0; + } + + if (ndlp->nlp_type & NLP_FCP_TARGET) { + node_t * node_ptr; + dvi_t * dev_ptr; + + if ((node_ptr = (node_t * )ndlp->nlp_targetp) != NULL) { + /* restart any I/Os on this node */ + for (dev_ptr = node_ptr->lunlist; + dev_ptr != NULL; dev_ptr = dev_ptr->next) { + dev_ptr->queue_state = HALTED; + } + } + } + + if (binfo->fc_nlp_cnt <= 0) { + binfo->fc_nlp_cnt = 0; + fc_nextrscn(p_dev_ctl, fc_max_els_sent); + } else { + fc_nextrscn(p_dev_ctl, 1); + } + } + + /* Check for Address Discovery */ + if ((ndlp->nlp_action & NLP_DO_DISC_START) || + (ndlp->nlp_flag & NLP_REQ_SND)) { + ndlp->nlp_flag &= ~NLP_REQ_SND; + ndlp->nlp_action &= ~NLP_DO_DISC_START; + binfo->fc_nlp_cnt--; + + if (binfo->fc_nlp_cnt <= 0) { + binfo->fc_nlp_cnt = 0; + fc_nextdisc(p_dev_ctl, fc_max_els_sent); + } else { + fc_nextdisc(p_dev_ctl, 1); + } + } + + return(0); +} /* End fc_nextnode */ + + +/****************************************************/ +/** fc_nextdisc **/ +/** **/ +/** Description: **/ +/** Called during discovery or rediscovery **/ +/** **/ +/** Returns: **/ +/** **/ +/****************************************************/ +_static_ int +fc_nextdisc( +fc_dev_ctl_t *p_dev_ctl, +int sndcnt) +{ + FC_BRD_INFO * binfo; + MAILBOXQ * mb; + NODELIST * ndlp; + NODELIST * new_ndlp; + int cnt, skip; + uint32 did; + + binfo = &BINFO; + /* Device Discovery nextdisc */ + fc_log_printf_msg_vargs( binfo->fc_brd_no, + &fc_msgBlk0243, /* ptr to msg structure */ + fc_mes0243, /* ptr to msg */ + fc_msgBlk0243.msgPreambleStr, /* begin varargs */ + binfo->fc_nlp_cnt, + sndcnt, + binfo->fc_mbox_active); /* end varargs */ + binfo->fc_ffstate = FC_NODE_DISC; + binfo->fc_fabrictmo = (2 * binfo->fc_ratov) + + ((4 * binfo->fc_edtov) / 1000) + 1; + if(FABRICTMO) { + fc_clk_res(p_dev_ctl, binfo->fc_fabrictmo, FABRICTMO); + } + else { + FABRICTMO = fc_clk_set(p_dev_ctl, binfo->fc_fabrictmo, + fc_fabric_timeout, 0, 0); + } + + /* For MAXREQ requests, we must make sure all outstanding Mailbox + * commands have been processed. This is to ensure UNREG_LOGINs + * complete before we try to relogin. + */ + if (sndcnt == fc_max_els_sent) { + if (binfo->fc_mbox_active) { + binfo->fc_flag |= FC_DELAY_PLOGI; + return(fc_max_els_sent); + } + } + + cnt = 0; + skip = 0; + binfo->fc_flag &= ~FC_NLP_MORE; + + /* We can start discovery right now */ + /* Fire out PLOGIs on all nodes marked for discovery */ + ndlp = binfo->fc_nlpbind_start; + if(ndlp == (NODELIST *)&binfo->fc_nlpbind_start) + ndlp = binfo->fc_nlpunmap_start; + if(ndlp == (NODELIST *)&binfo->fc_nlpunmap_start) + ndlp = binfo->fc_nlpmap_start; + while(ndlp != (NODELIST *)&binfo->fc_nlpmap_start) { + new_ndlp = (NODELIST *)ndlp->nlp_listp_next; + + if ((ndlp->nlp_action & NLP_DO_DISC_START) && + (ndlp->nlp_DID != NameServer_DID)) { + if(!(ndlp->nlp_flag & (NLP_REQ_SND | NLP_REG_INP | NLP_RM_ENTRY))) { + binfo->fc_nlp_cnt++; + did = ndlp->nlp_DID; + if(did == 0) + did = ndlp->nlp_oldDID; + /* Start discovery for this node */ + fc_els_cmd(binfo, ELS_CMD_PLOGI, (void *)((ulong)did), + (uint32)0, (ushort)0, ndlp); + cnt++; + + if ((binfo->fc_nlp_cnt >= fc_max_els_sent) || + (cnt == sndcnt)) { + binfo->fc_flag |= FC_NLP_MORE; + return(cnt); + } + } + else + skip++; + } + ndlp = new_ndlp; + if(ndlp == (NODELIST *)&binfo->fc_nlpbind_start) + ndlp = binfo->fc_nlpunmap_start; + if(ndlp == (NODELIST *)&binfo->fc_nlpunmap_start) + ndlp = binfo->fc_nlpmap_start; + } + + if ((binfo->fc_nlp_cnt) || skip) + return(binfo->fc_nlp_cnt); + + /* This should turn off DELAYED ABTS for ELS timeouts */ + if ((mb = (MAILBOXQ * )fc_mem_get(binfo, MEM_MBOX))) { + fc_set_slim(binfo, (MAILBOX * )mb, 0x052198, 0); + if (issue_mb_cmd(binfo, (MAILBOX * )mb, MBX_NOWAIT) != MBX_BUSY) { + fc_mem_put(binfo, MEM_MBOX, (uchar * )mb); + } + } + + /* Nothing to authenticate, so CLEAR_LA right now */ + if ((mb = (MAILBOXQ * )fc_mem_get(binfo, MEM_MBOX | MEM_PRI))) { + binfo->fc_ffstate = FC_CLEAR_LA; + fc_clear_la(binfo, (MAILBOX * )mb); + if (issue_mb_cmd(binfo, (MAILBOX * )mb, MBX_NOWAIT) != MBX_BUSY) { + fc_mem_put(binfo, MEM_MBOX, (uchar * )mb); + } + } else { + /* Device Discovery completion error */ + fc_log_printf_msg_vargs( binfo->fc_brd_no, + &fc_msgBlk0244, /* ptr to msg structure */ + fc_mes0244, /* ptr to msg */ + fc_msgBlk0244.msgPreambleStr); /* begin & end varargs */ + binfo->fc_ffstate = FC_ERROR; + } + + if(FABRICTMO) { + fc_clk_can(p_dev_ctl, FABRICTMO); + FABRICTMO = 0; + } + return(0); +} /* End fc_nextdisc */ + + +/****************************************************/ +/** fc_nextauth **/ +/** **/ +/** Description: **/ +/** Called during rediscovery **/ +/** **/ +/** Returns: **/ +/** **/ +/****************************************************/ +_static_ int +fc_nextauth( +fc_dev_ctl_t *p_dev_ctl, +int sndcnt) +{ + FC_BRD_INFO * binfo; + iCfgParam * clp; + NODELIST * ndlp; + NODELIST * new_ndlp; + int cnt; + + binfo = &BINFO; + clp = DD_CTL.p_config[binfo->fc_brd_no]; + /* Device Discovery next authentication */ + fc_log_printf_msg_vargs( binfo->fc_brd_no, + &fc_msgBlk0245, /* ptr to msg structure */ + fc_mes0245, /* ptr to msg */ + fc_msgBlk0245.msgPreambleStr, /* begin varargs */ + binfo->fc_nlp_cnt, + sndcnt, + binfo->fc_mbox_active); /* end varargs */ + cnt = 0; + binfo->fc_flag &= ~FC_NLP_MORE; + binfo->fc_fabrictmo = (2 * binfo->fc_ratov) + + ((4 * binfo->fc_edtov) / 1000) + 1; + if(FABRICTMO) { + fc_clk_res(p_dev_ctl, binfo->fc_fabrictmo, FABRICTMO); + } + else { + FABRICTMO = fc_clk_set(p_dev_ctl, binfo->fc_fabrictmo, + fc_fabric_timeout, 0, 0); + } + + /* We can start rediscovery right now */ + /* Fire out ADISC on all nodes marked for addr_auth */ + + ndlp = binfo->fc_nlpbind_start; + if(ndlp == (NODELIST *)&binfo->fc_nlpbind_start) + ndlp = binfo->fc_nlpunmap_start; + if(ndlp == (NODELIST *)&binfo->fc_nlpunmap_start) + ndlp = binfo->fc_nlpmap_start; + while(ndlp != (NODELIST *)&binfo->fc_nlpmap_start) { + new_ndlp = (NODELIST *)ndlp->nlp_listp_next; + + if (ndlp->nlp_action & NLP_DO_ADDR_AUTH) { + if (ndlp->nlp_flag & (NLP_RM_ENTRY | NLP_REQ_SND_ADISC | + NLP_REQ_SND | NLP_REG_INP)) + goto loop1; + + if ((ndlp->nlp_type & NLP_FCP_TARGET) && + ((!clp[CFG_USE_ADISC].a_current) || (ndlp->nlp_Rpi == 0))) { + /* Force regular discovery on this node */ + ndlp->nlp_action &= ~NLP_DO_ADDR_AUTH; + fc_freenode(binfo, ndlp, 0); + ndlp->nlp_state = NLP_LIMBO; + fc_nlp_bind(binfo, ndlp); + ndlp->nlp_action |= NLP_DO_DISC_START; + goto loop1; + } else { + if ((ndlp->nlp_type & NLP_IP_NODE) && (ndlp->nlp_Rpi == 0)) { + /* Force regular discovery on this node */ + ndlp->nlp_action &= ~NLP_DO_ADDR_AUTH; + fc_freenode(binfo, ndlp, 0); + ndlp->nlp_state = NLP_LIMBO; + fc_nlp_bind(binfo, ndlp); + goto loop1; + } + } + + if((ndlp->nlp_type & (NLP_FCP_TARGET | NLP_IP_NODE)) == 0) { + /* Force regular discovery on this node */ + ndlp->nlp_action &= ~NLP_DO_ADDR_AUTH; + fc_freenode(binfo, ndlp, 0); + ndlp->nlp_state = NLP_LIMBO; + fc_nlp_bind(binfo, ndlp); + ndlp->nlp_action |= NLP_DO_DISC_START; + goto loop1; + } + + binfo->fc_nlp_cnt++; + /* Start authentication */ + fc_els_cmd(binfo, ELS_CMD_ADISC, (void *)((ulong)ndlp->nlp_DID), + (uint32)0, (ushort)0, ndlp); + cnt++; + if ((binfo->fc_nlp_cnt >= fc_max_els_sent) || + (cnt == sndcnt)) { + binfo->fc_flag |= FC_NLP_MORE; + return(cnt); + } + } +loop1: + ndlp = new_ndlp; + if(ndlp == (NODELIST *)&binfo->fc_nlpbind_start) + ndlp = binfo->fc_nlpunmap_start; + if(ndlp == (NODELIST *)&binfo->fc_nlpunmap_start) + ndlp = binfo->fc_nlpmap_start; + } + + return(binfo->fc_nlp_cnt); +} /* End fc_nextauth */ + +/****************************************************/ +/** fc_nextrscn **/ +/** **/ +/** Description: **/ +/** Called during RSCN processing **/ +/** **/ +/** Returns: **/ +/** **/ +/****************************************************/ +_static_ int +fc_nextrscn( +fc_dev_ctl_t *p_dev_ctl, +int sndcnt) +{ + FC_BRD_INFO * binfo; + iCfgParam * clp; + NODELIST * ndlp; + NODELIST * new_ndlp; + MAILBOXQ * mb; + struct buf * bp, * nextbp; + RING * rp; + IOCBQ * xmitiq; + IOCB * iocb; + MATCHMAP * mp; + int i, j, cnt; + uint32 did; + + binfo = &BINFO; + clp = DD_CTL.p_config[binfo->fc_brd_no]; + /* Device Discovery next RSCN */ + fc_log_printf_msg_vargs( binfo->fc_brd_no, + &fc_msgBlk0246, /* ptr to msg structure */ + fc_mes0246, /* ptr to msg */ + fc_msgBlk0246.msgPreambleStr, /* begin varargs */ + binfo->fc_nlp_cnt, + sndcnt, + binfo->fc_mbox_active, + binfo->fc_flag); /* end varargs */ + cnt = 0; + if (binfo->fc_flag & FC_RSCN_DISC_TMR) + goto out; + + /* Are we waiting for a NameServer Query to complete */ + if (binfo->fc_flag & FC_NSLOGI_TMR) + return(1); + + if (binfo->fc_mbox_active) { + binfo->fc_flag |= FC_DELAY_PLOGI; + return(1); + } + + binfo->fc_flag &= ~FC_NLP_MORE; + + if(FABRICTMO) { + fc_clk_res(p_dev_ctl, binfo->fc_fabrictmo, FABRICTMO); + } + else { + FABRICTMO = fc_clk_set(p_dev_ctl, binfo->fc_fabrictmo, + fc_fabric_timeout, 0, 0); + } + + /* We can start rediscovery right now */ + /* Fire out PLOGI on all nodes marked for rscn */ + ndlp = binfo->fc_nlpbind_start; + if(ndlp == (NODELIST *)&binfo->fc_nlpbind_start) + ndlp = binfo->fc_nlpunmap_start; + if(ndlp == (NODELIST *)&binfo->fc_nlpunmap_start) + ndlp = binfo->fc_nlpmap_start; + while(ndlp != (NODELIST *)&binfo->fc_nlpmap_start) { + new_ndlp = (NODELIST *)ndlp->nlp_listp_next; + + if (ndlp->nlp_action & NLP_DO_RSCN) { + if (ndlp->nlp_flag & (NLP_RM_ENTRY | NLP_REQ_SND_ADISC | + NLP_REQ_SND | NLP_REG_INP)) + goto loop2; + + did = ndlp->nlp_DID; + if(did == 0) { + did = ndlp->nlp_oldDID; + if(did == 0) + goto loop2; + } + + binfo->fc_nlp_cnt++; + + /* We are always using ADISC for RSCN validation */ + if ((ndlp->nlp_type & NLP_FCP_TARGET) && (ndlp->nlp_Rpi == 0)) { + /* Force regular discovery on this node */ + fc_els_cmd(binfo, ELS_CMD_PLOGI, (void *)((ulong)did), + (uint32)0, (ushort)0, ndlp); + } else { + if (((ndlp->nlp_type & NLP_IP_NODE) && (ndlp->nlp_Rpi == 0)) || + ((ndlp->nlp_type & (NLP_FCP_TARGET | NLP_IP_NODE)) == 0)) { + /* Force regular discovery on this node */ + fc_els_cmd(binfo, ELS_CMD_PLOGI, (void *)((ulong)did), + (uint32)0, (ushort)0, ndlp); + } + else { + fc_els_cmd(binfo, ELS_CMD_ADISC,(void *)((ulong)did), + (uint32)0, (ushort)0, ndlp); + } + } + cnt++; + if ((binfo->fc_nlp_cnt >= fc_max_els_sent) || + (cnt == sndcnt)) { + binfo->fc_flag |= FC_NLP_MORE; + return(cnt); + } + } +loop2: + ndlp = new_ndlp; + if(ndlp == (NODELIST *)&binfo->fc_nlpbind_start) + ndlp = binfo->fc_nlpunmap_start; + if(ndlp == (NODELIST *)&binfo->fc_nlpunmap_start) + ndlp = binfo->fc_nlpmap_start; + } + + if (binfo->fc_nlp_cnt) + return(binfo->fc_nlp_cnt); + +out: + if (binfo->fc_flag & FC_RSCN_DISCOVERY) { + /* Discovery RSCN */ + fc_log_printf_msg_vargs( binfo->fc_brd_no, + &fc_msgBlk0247, /* ptr to msg structure */ + fc_mes0247, /* ptr to msg */ + fc_msgBlk0247.msgPreambleStr, /* begin varargs */ + binfo->fc_defer_rscn.q_cnt, + binfo->fc_flag, + (ulong)(binfo->fc_rscn_disc_wdt)); /* end varargs */ + if(binfo->fc_rscn_disc_wdt == 0) { + binfo->fc_rscn_disc_wdt = fc_clk_set(p_dev_ctl, + ((binfo->fc_edtov / 1000) + 1), fc_rscndisc_timeout, 0, 0); + /* Free any deferred RSCNs */ + fc_flush_rscn_defer(p_dev_ctl); + return(0); + } + + if(!(binfo->fc_flag & FC_RSCN_DISC_TMR)) + return(0); + + binfo->fc_flag &= ~(FC_RSCN_DISC_TMR | FC_RSCN_DISCOVERY); + binfo->fc_rscn_disc_wdt = 0; + + /* RSCN match on all DIDs in NameServer */ + binfo->fc_rscn_id_list[0] = 0x03000000; + binfo->fc_rscn_id_cnt = 1; + + /* Free any deferred RSCNs */ + fc_flush_rscn_defer(p_dev_ctl); + + /* Authenticate all nodes in nlplist */ + ndlp = binfo->fc_nlpbind_start; + if(ndlp == (NODELIST *)&binfo->fc_nlpbind_start) + ndlp = binfo->fc_nlpunmap_start; + if(ndlp == (NODELIST *)&binfo->fc_nlpunmap_start) + ndlp = binfo->fc_nlpmap_start; + while(ndlp != (NODELIST *)&binfo->fc_nlpmap_start) { + new_ndlp = (NODELIST *)ndlp->nlp_listp_next; + + /* Skip over FABRIC nodes and myself */ + if ((ndlp->nlp_DID == binfo->fc_myDID) || + (ndlp->nlp_type & NLP_FABRIC) || + ((ndlp->nlp_DID & CT_DID_MASK) == CT_DID_MASK)) + goto loop3; + + if (ndlp->nlp_state == NLP_ALLOC) { + /* Mark node for authentication */ + ndlp->nlp_action |= NLP_DO_RSCN; + ndlp->nlp_flag &= ~NLP_NODEV_TMO; + + /* We are always using ADISC for RSCN validation */ + } +loop3: + ndlp = new_ndlp; + if(ndlp == (NODELIST *)&binfo->fc_nlpbind_start) + ndlp = binfo->fc_nlpunmap_start; + if(ndlp == (NODELIST *)&binfo->fc_nlpunmap_start) + ndlp = binfo->fc_nlpmap_start; + } + + fc_issue_ns_query(p_dev_ctl, (void *)0, (void *)0); + return(0); + } + + if (binfo->fc_defer_rscn.q_first) { + uint32 * lp; + D_ID rdid; + uint32 cmd; + + /* process any deferred RSCNs */ + /* Deferred RSCN */ + fc_log_printf_msg_vargs( binfo->fc_brd_no, + &fc_msgBlk0248, /* ptr to msg structure */ + fc_mes0248, /* ptr to msg */ + fc_msgBlk0248.msgPreambleStr, /* begin varargs */ + binfo->fc_defer_rscn.q_cnt, + binfo->fc_flag); /* end varargs */ + binfo->fc_rscn_id_cnt = 0; + rp = &binfo->fc_ring[FC_ELS_RING]; + while (binfo->fc_defer_rscn.q_first) { + xmitiq = (IOCBQ * )binfo->fc_defer_rscn.q_first; + if ((binfo->fc_defer_rscn.q_first = xmitiq->q) == 0) { + binfo->fc_defer_rscn.q_last = 0; + } + binfo->fc_defer_rscn.q_cnt--; + iocb = &xmitiq->iocb; + mp = *((MATCHMAP **)iocb); + *((MATCHMAP **)iocb) = 0; + xmitiq->q = NULL; + + lp = (uint32 * )mp->virt; + cmd = *lp++; + i = SWAP_DATA(cmd) & 0xffff; /* payload length */ + i -= sizeof(uint32); /* take off word 0 */ + while (i) { + rdid.un.word = *lp++; + rdid.un.word = SWAP_DATA(rdid.un.word); + if(binfo->fc_rscn_id_cnt < FC_MAX_HOLD_RSCN) { + for(j=0;jfc_rscn_id_cnt;j++) { + if(binfo->fc_rscn_id_list[j] == rdid.un.word) { + goto skip_id; + } + } + binfo->fc_rscn_id_list[binfo->fc_rscn_id_cnt++] = rdid.un.word; + } + else { + binfo->fc_flag |= FC_RSCN_DISCOVERY; + goto out1; + } +skip_id: + cnt += (fc_handle_rscn(p_dev_ctl, &rdid)); + i -= sizeof(uint32); + } + +out1: + fc_mem_put(binfo, MEM_BUF, (uchar * )mp); + + i = 1; + /* free resources associated with this iocb and repost the ring buffers */ + if (!(binfo->fc_flag & FC_SLI2)) { + for (i = 1; i < (int)iocb->ulpBdeCount; i++) { + mp = fc_getvaddr(p_dev_ctl, rp, (uchar * )((ulong)iocb->un.cont[i].bdeAddress)); + if (mp) { + fc_mem_put(binfo, MEM_BUF, (uchar * )mp); + } + } + } + fc_mem_put(binfo, MEM_IOCB, (uchar * )xmitiq); + if (binfo->fc_flag & FC_RSCN_DISCOVERY) + goto out; + } + if (cnt == 0) { + /* no need for nameserver login */ + fc_nextrscn(p_dev_ctl, fc_max_els_sent); + } + else + fc_issue_ns_query(p_dev_ctl, (void *)0, (void *)0); + + return(0); + } + + binfo->fc_flag &= ~FC_RSCN_MODE; + binfo->fc_rscn_id_cnt = 0; + + /* This should turn off DELAYED ABTS for ELS timeouts */ + if ((mb = (MAILBOXQ * )fc_mem_get(binfo, MEM_MBOX))) { + fc_set_slim(binfo, (MAILBOX * )mb, 0x052198, 0); + if (issue_mb_cmd(binfo, (MAILBOX * )mb, MBX_NOWAIT) != MBX_BUSY) { + fc_mem_put(binfo, MEM_MBOX, (uchar * )mb); + } + } + /* Device Discovery completes */ + fc_log_printf_msg_vargs( binfo->fc_brd_no, + &fc_msgBlk0249, /* ptr to msg structure */ + fc_mes0249, /* ptr to msg */ + fc_msgBlk0249.msgPreambleStr, /* begin varargs */ + binfo->fc_flag); /* end varargs */ + /* Fix up any changed RPIs in FCP IOCBs queued up a txq */ + fc_fcp_fix_txq(p_dev_ctl); + + + if(FABRICTMO) { + fc_clk_can(p_dev_ctl, FABRICTMO); + FABRICTMO = 0; + } + + if(clp[CFG_FCP_ON].a_current) { + + fc_restart_all_devices(p_dev_ctl); + + /* Call iodone for any commands that timed out previously */ + for (bp = p_dev_ctl->timeout_head; bp != NULL; ) { + nextbp = bp->av_forw; + bp->b_error = ETIMEDOUT; + bp->b_flags |= B_ERROR; + bp->b_resid = bp->b_bcount; + FCSTATCTR.fcpScsiTmo++; + fc_do_iodone(bp); + bp = nextbp; + } + p_dev_ctl->timeout_count = 0; + p_dev_ctl->timeout_head = NULL; + /* Send down any saved FCP commands */ + fc_issue_cmd(p_dev_ctl); + } + return(0); +} /* End fc_nextrscn */ + + +_static_ int +fc_online( +fc_dev_ctl_t * p_dev_ctl) +{ + FC_BRD_INFO * binfo; + int ipri; + int j; + + if(p_dev_ctl) { + ipri = disable_lock(FC_LVL, &CMD_LOCK); + binfo = &BINFO; + if (!(binfo->fc_flag & FC_OFFLINE_MODE)) { + unlock_enable(ipri, &CMD_LOCK); + return(0); + } + /* Bring Adapter online */ + fc_log_printf_msg_vargs( binfo->fc_brd_no, + &fc_msgBlk0458, /* ptr to msg structure */ + fc_mes0458, /* ptr to msg */ + fc_msgBlk0458.msgPreambleStr); /* begin & end varargs */ + binfo->fc_flag &= ~FC_OFFLINE_MODE; + + fc_brdreset(p_dev_ctl); + unlock_enable(ipri, &CMD_LOCK); + fc_cfg_init(p_dev_ctl); + return(0); + } + + fc_diag_state = DDI_ONDI; + + /* + * find the device in the dev_array if it is there + */ + for (j = 0; j < MAX_FC_BRDS; j++) { + p_dev_ctl = DD_CTL.p_dev[j]; + if (p_dev_ctl) { + ipri = disable_lock(FC_LVL, &CMD_LOCK); + binfo = &BINFO; + if (!(binfo->fc_flag & FC_OFFLINE_MODE)) + continue; + /* Bring Adapter online */ + fc_log_printf_msg_vargs( binfo->fc_brd_no, + &fc_msgBlk0459, /* ptr to msg structure */ + fc_mes0459, /* ptr to msg */ + fc_msgBlk0459.msgPreambleStr); /* begin & end varargs */ + binfo->fc_flag &= ~FC_OFFLINE_MODE; + + fc_brdreset(p_dev_ctl); + unlock_enable(ipri, &CMD_LOCK); + fc_cfg_init(p_dev_ctl); + continue; + } + } + return(0); +} /* End fc_online */ + + +_static_ int +fc_offline( +fc_dev_ctl_t * p_dev_ctl) +{ + FC_BRD_INFO * binfo; + int ipri; + int j; + + if(p_dev_ctl) { + ipri = disable_lock(FC_LVL, &CMD_LOCK); + binfo = &BINFO; + if (binfo->fc_flag & FC_OFFLINE_MODE) { + unlock_enable(ipri, &CMD_LOCK); + return(0); + } + /* Bring Adapter offline */ + fc_log_printf_msg_vargs( binfo->fc_brd_no, + &fc_msgBlk0460, /* ptr to msg structure */ + fc_mes0460, /* ptr to msg */ + fc_msgBlk0460.msgPreambleStr); /* begin & end varargs */ + + fc_cfg_remove(p_dev_ctl); + binfo->fc_flag |= FC_OFFLINE_MODE; + + unlock_enable(ipri, &CMD_LOCK); + return(0); + } + fc_diag_state = DDI_OFFDI; + + /* + * find the device in the dev_array if it is there + */ + for (j = 0; j < MAX_FC_BRDS; j++) { + p_dev_ctl = DD_CTL.p_dev[j]; + if (p_dev_ctl) { + ipri = disable_lock(FC_LVL, &CMD_LOCK); + binfo = &BINFO; + if (binfo->fc_flag & FC_OFFLINE_MODE) { + unlock_enable(ipri, &CMD_LOCK); + continue; + } + /* Bring Adapter offline */ + fc_log_printf_msg_vargs( binfo->fc_brd_no, + &fc_msgBlk0452, /* ptr to msg structure */ + fc_mes0452, /* ptr to msg */ + fc_msgBlk0452.msgPreambleStr); /* begin & end varargs */ + + fc_cfg_remove(p_dev_ctl); + binfo->fc_flag |= FC_OFFLINE_MODE; + unlock_enable(ipri, &CMD_LOCK); + continue; + } + } + return(0); +} /* End fc_offline */ + + +_static_ int +fc_attach( +int index, +uint32 *p_uio) /* pointer to driver specific structure */ +{ + fc_dev_ctl_t * p_dev_ctl; + FC_BRD_INFO * binfo; + iCfgParam * clp; + int rc, i; + + if ((p_dev_ctl = DD_CTL.p_dev[index]) == NULL) { + rc = ENOMEM; + return(rc); + } + + binfo = &BINFO; + fc_diag_state = DDI_ONDI; + + binfo->fc_brd_no = index; /* FC board number */ + binfo->fc_p_dev_ctl = (uchar * )p_dev_ctl; + binfo->nlptimer = 1; + binfo->fc_fcpnodev.nlp_Rpi = 0xfffe; + binfo->fc_nlpbind_start = (NODELIST *)&binfo->fc_nlpbind_start; + binfo->fc_nlpbind_end = (NODELIST *)&binfo->fc_nlpbind_start; + binfo->fc_nlpmap_start = (NODELIST *)&binfo->fc_nlpmap_start; + binfo->fc_nlpmap_end = (NODELIST *)&binfo->fc_nlpmap_start; + binfo->fc_nlpunmap_start = (NODELIST *)&binfo->fc_nlpunmap_start; + binfo->fc_nlpunmap_end = (NODELIST *)&binfo->fc_nlpunmap_start; + + /* Initialize current value of config parameters from default */ + clp = DD_CTL.p_config[binfo->fc_brd_no]; + for(i=0;ifc_sli = (uchar)2; + clp[CFG_ZONE_RSCN].a_current = 1; /* ALWAYS force NS login on RSCN */ + + /* config the device */ + if ((rc = fc_cfg_init(p_dev_ctl))) { + return(rc); + } + return(0); +} + + +_static_ int +fc_detach( +int index) /* device unit number */ +{ + fc_dev_ctl_t * p_dev_ctl; + FC_BRD_INFO * binfo; + + p_dev_ctl = DD_CTL.p_dev[index]; + binfo = &BINFO; + if (p_dev_ctl == 0) + return(0); + + + if (!(binfo->fc_flag & FC_OFFLINE_MODE)) { + /* Free the device resources */ + fc_cfg_remove(p_dev_ctl); + } + + /* De-register the interrupt handler */ + if (p_dev_ctl->intr_inited) { + i_clear(&IHS); + p_dev_ctl->intr_inited = 0; + } + + fc_unmemmap(p_dev_ctl); + return(0); +} + + +/*****************************************************************************/ +/* + * NAME: fc_cfg_init + * + * FUNCTION: perform CFG_INIT function. Initialize the device control + * structure and get the adapter VPD data. + * + * EXECUTION ENVIRONMENT: process only + * + * CALLED FROM: + * fc_config + * + * INPUT: + * p_dev_ctl - pointer to the dev_ctl area + * + * RETURNS: + * 0 - OK + * EEXIST - device name in use (from ns_attach) + * EINVAL - invalid parameter was passed + * EIO - permanent I/O error + */ +/*****************************************************************************/ +_static_ int +fc_cfg_init( +fc_dev_ctl_t *p_dev_ctl) /* pointer to the device control area */ +{ + int rc; /* return code */ + int i; + FC_BRD_INFO * binfo; + iCfgParam * clp; + + binfo = &BINFO; + clp = DD_CTL.p_config[binfo->fc_brd_no]; + p_dev_ctl->ctl_correlator = (void * ) & DD_CTL; + + for (i = 0; i < NLP_MAXPAN; i++) { + p_dev_ctl->adapter_state[i] = CLOSED; + } + + if ((rc = fc_pcimap(p_dev_ctl))) { + return(rc); + } + + if ((rc = fc_memmap(p_dev_ctl))) { + return(rc); + } + + /* offset from beginning of SLIM */ + BINFO.fc_mboxaddr = 0; + + BINFO.fc_mbox_active = 0; + BINFO.fc_ns_retry = 0; + BINFO.fc_process_LA = 0; + BINFO.fc_edtov = FF_DEF_EDTOV; + BINFO.fc_ratov = FF_DEF_RATOV; + BINFO.fc_altov = FF_DEF_ALTOV; + BINFO.fc_arbtov = FF_DEF_ARBTOV; + + /* offset from beginning of register space */ + BINFO.fc_HAregaddr = (sizeof(uint32) * HA_REG_OFFSET); + BINFO.fc_FFregaddr = (sizeof(uint32) * CA_REG_OFFSET); + BINFO.fc_STATregaddr = (sizeof(uint32) * HS_REG_OFFSET); + BINFO.fc_HCregaddr = (sizeof(uint32) * HC_REG_OFFSET); + BINFO.fc_BCregaddr = (sizeof(uint32) * BC_REG_OFFSET); + + + /* save the dev_ctl address in the NDD correlator field */ + NDD.ndd_name = DDS.logical_name;/* point to the name contained in the dds */ + NDD.ndd_alias = DDS.dev_alias; /* point to the name contained in the dds */ + + + + binfo->fc_ring[FC_IP_RING].fc_tx.q_max = + (ushort)clp[CFG_XMT_Q_SIZE].a_current; + + p_dev_ctl->iostrat_event = EVENT_NULL; + p_dev_ctl->iostrat_head = NULL; + p_dev_ctl->iostrat_tail = NULL; + + /* + * Perform any device-specific initialization necessary at the + * CFG_INIT time. If there is any error during the device initialization, + * the CFG_INIT will fail. Also get VPD data. + */ + if ((rc = fc_ffinit(p_dev_ctl))) { + return(rc); + } + + /* Now setup physical address */ + fc_bcopy(binfo->fc_portname.IEEE, p_dev_ctl->phys_addr, 6); + + return(0); +} /* End fc_cfg_init */ + + +/*****************************************************************************/ +/* + * NAME: fc_cfg_remove + * + * FUNCTION: Remove the device resources that have been allocated during + * CFG_INIT configuration time. + * + * EXECUTION ENVIRONMENT: process only + * + * NOTES: + * + * CALLED FROM: + * fc_config + * + * INPUT: + * p_dev_ctl - address of a pointer to the dev control structure + * + * RETURNS: + * none. + */ +/*****************************************************************************/ +_static_ void +fc_cfg_remove( +fc_dev_ctl_t *p_dev_ctl) /* point to the dev_ctl area */ +{ + fc_free_rpilist(p_dev_ctl, 0); + + /* Release the watchdog timers and disable board interrupts */ + fc_ffcleanup(p_dev_ctl); + + fc_free_buffer(p_dev_ctl); /* free device buffers */ + + fc_brdreset(p_dev_ctl); + +} /* End fc_cfg_remove */ + + +/*****************************************************************************/ +/* + * NAME: fc_ffcleanup + * + * EXECUTION ENVIRONMENT: process only + * + * CALLED FROM: + * CFG_TERM + * + * INPUT: + * p_dev_ctl - pointer to the dev_ctl area. + * + * RETURNS: + * none + */ +/*****************************************************************************/ +_static_ void +fc_ffcleanup( +fc_dev_ctl_t *p_dev_ctl) /* pointer to the dev_ctl area */ +{ + int i; + RING * rp; + FC_BRD_INFO * binfo; + void *ioa; + MAILBOX * mb; + + binfo = &BINFO; + binfo->fc_process_LA = 0; + + /* Disable all but the mailbox interrupt */ + ioa = (void *)FC_MAP_IO(&binfo->fc_iomap_io); /* map in io registers */ + WRITE_CSR_REG(binfo, FC_HC_REG(binfo, ioa), HC_MBINT_ENA); + FC_UNMAP_MEMIO(ioa); + + /* Issue unreg_login command to logout all nodes */ + if (p_dev_ctl->init_eventTag) { + /* Get a buffer for mailbox command */ + if ((mb = (MAILBOX * )fc_mem_get(binfo, MEM_MBOX)) == NULL) { + } else { + fc_unreg_login(binfo, 0xffff, (MAILBOX * )mb); + if (issue_mb_cmd(binfo, (MAILBOX * )mb, MBX_NOWAIT) != MBX_BUSY) + fc_mem_put(binfo, MEM_MBOX, (uchar * )mb); + } + } + + ioa = (void *)FC_MAP_IO(&binfo->fc_iomap_io); /* map in io registers */ + /* Clear all interrupt enable conditions */ + WRITE_CSR_REG(binfo, FC_HC_REG(binfo, ioa), 0); + FC_UNMAP_MEMIO(ioa); + + for (i = 0; i < binfo->fc_ffnumrings; i++) { + rp = &binfo->fc_ring[i]; + /* Clear the transmit watchdog timer */ + if (rp->fc_wdt_inited) { + if(RINGTMO) { + fc_clk_can(p_dev_ctl, RINGTMO); + RINGTMO = 0; + } + rp->fc_wdt_inited = 0; + } + } + + if(MBOXTMO) { + fc_clk_can(p_dev_ctl, MBOXTMO); + MBOXTMO = 0; + } + if(FABRICTMO) { + fc_clk_can(p_dev_ctl, FABRICTMO); + FABRICTMO = 0; + } + + fc_flush_rscn_defer(p_dev_ctl); + + fc_flush_clk_set(p_dev_ctl, fc_delay_timeout); + + fc_flush_clk_set(p_dev_ctl, lpfc_scsi_selto_timeout); + +} /* End fc_ffcleanup */ + + +/*****************************************************************************/ +/* + * NAME: fc_start + * + * FUNCTION: Initialize and activate the adapter. + * + * EXECUTION ENVIRONMENT: process or interrupt + * + * CALLED FROM: + * fc_config + * + * INPUT: + * p_dev_ctl - pointer to the dev_ctl area. + * + * RETURNS: + * NONE + */ +/*****************************************************************************/ + +_static_ void +fc_start( +fc_dev_ctl_t *p_dev_ctl) /* pointer to the dev_ctl area */ +{ + uint32 i, j; + FC_BRD_INFO * binfo; + iCfgParam * clp; + void * ioa; + RING * rp; + + /* Activate the adapter and allocate all the resources needed */ + + binfo = &BINFO; + clp = DD_CTL.p_config[binfo->fc_brd_no]; + + /* Enable appropriate host interrupts */ + i = (uint32) (HC_MBINT_ENA | HC_ERINT_ENA); + if (binfo->fc_ffnumrings > 0) + i |= HC_R0INT_ENA; + if (binfo->fc_ffnumrings > 1) + i |= HC_R1INT_ENA; + if (binfo->fc_ffnumrings > 2) + i |= HC_R2INT_ENA; + if (binfo->fc_ffnumrings > 3) + i |= HC_R3INT_ENA; + + ioa = (void *)FC_MAP_IO(&binfo->fc_iomap_io); /* map in io registers */ + WRITE_CSR_REG(binfo, FC_HC_REG(binfo, ioa), i); + FC_UNMAP_MEMIO(ioa); + + for (i = 0; i < (uint32)binfo->fc_ffnumrings; i++) { + /* Initialize / post buffers to ring */ + fc_setup_ring(p_dev_ctl, i); + + if (i == FC_ELS_RING) { + /* Now post receive buffers to the ring */ + rp = &binfo->fc_ring[i]; + for (j = 0; j < 64; j++) + fc_post_buffer(p_dev_ctl, rp, 2); + } + } + + clp = DD_CTL.p_config[binfo->fc_brd_no]; + if(clp[CFG_NETWORK_ON].a_current) { + rp = &binfo->fc_ring[FC_IP_RING]; + i = clp[CFG_POST_IP_BUF].a_current; + while(i) { + fc_post_mbuf(p_dev_ctl, rp, 2); + i -= 2; + } + } + + /* set up the watchdog timer control structure section */ + binfo->fc_fabrictmo = FF_DEF_RATOV + 1; + +} /* End fc_start */ + + +_static_ void +fc_process_reglogin( +fc_dev_ctl_t *p_dev_ctl, /* pointer to the dev_ctl area */ +NODELIST *ndlp) +{ + node_t * node_ptr; + RING * rp; + FC_BRD_INFO * binfo; + iCfgParam * clp; + + binfo = &BINFO; + clp = DD_CTL.p_config[binfo->fc_brd_no]; + + ndlp->nlp_flag &= ~NLP_REG_INP; + if (ndlp->nlp_DID == Fabric_DID) { + ndlp->nlp_flag &= ~NLP_FARP_SND; + ndlp->nlp_action &= ~NLP_DO_ADDR_AUTH; + } else { + /* If we are an FCP node, update the rpi */ + if (ndlp->nlp_type & NLP_FCP_TARGET) { + if ((node_ptr = (node_t * )ndlp->nlp_targetp) != NULL) { + node_ptr->rpi = (ushort)ndlp->nlp_Rpi; + node_ptr->last_good_rpi = (ushort)ndlp->nlp_Rpi; + node_ptr->nlp = ndlp; + node_ptr->flags &= ~FC_NODEV_TMO; + ndlp->nlp_flag &= ~NLP_NODEV_TMO; + } + else { + int dev_index; + + dev_index = INDEX(ndlp->id.nlp_pan, ndlp->id.nlp_sid); + node_ptr = binfo->device_queue_hash[dev_index].node_ptr; + if(node_ptr) { + /* This is a new device that entered the loop */ + node_ptr->nlp = ndlp; + node_ptr->rpi = (ushort)ndlp->nlp_Rpi; + node_ptr->last_good_rpi = (ushort)ndlp->nlp_Rpi; + node_ptr->scsi_id = dev_index; + ndlp->nlp_targetp = (uchar *)node_ptr; + node_ptr->flags &= ~FC_NODEV_TMO; + ndlp->nlp_flag &= ~NLP_NODEV_TMO; + } + } + } + + if((ndlp->nlp_DID & CT_DID_MASK) == CT_DID_MASK) + ndlp->nlp_state = NLP_LOGIN; + + /* HBA Mgmt */ + if(ndlp->nlp_DID == FDMI_DID) { + ndlp->nlp_state = NLP_LOGIN; + return; + } + + /* If we are a NameServer, go to next phase */ + if (ndlp->nlp_DID == NameServer_DID) { + int fabcmd; + + ndlp->nlp_state = NLP_LOGIN; + + if(binfo->fc_ffstate == FC_READY) { + fabcmd = SLI_CTNS_GID_FT; + } + else { + fabcmd = SLI_CTNS_RFT_ID; + } + + /* Issue RFT_ID / GID_FT to Nameserver */ + if (fc_ns_cmd(p_dev_ctl, ndlp, fabcmd)) { + /* error so start discovery */ + /* Done with NameServer for now, but keep logged in */ + ndlp->nlp_action &= ~NLP_DO_RSCN; + + /* Fire out PLOGIs on nodes marked for discovery */ + if ((binfo->fc_nlp_cnt <= 0) && + !(binfo->fc_flag & FC_NLP_MORE)) { + binfo->fc_nlp_cnt = 0; + if ((binfo->fc_ffstate == FC_READY) && + (binfo->fc_flag & FC_RSCN_MODE)) { + fc_nextrscn(p_dev_ctl, fc_max_els_sent); + } + else { + fc_nextnode(p_dev_ctl, ndlp); + } + } + else { + fc_nextnode(p_dev_ctl, ndlp); + } + ndlp->nlp_action &= ~NLP_DO_ADDR_AUTH; + } + return; + } + + /* If we are in the middle of Discovery */ + if ((ndlp->nlp_type & NLP_FCP_TARGET) || + (ndlp->nlp_action & NLP_DO_DISC_START) || + (ndlp->nlp_action & NLP_DO_ADDR_AUTH) || + (ndlp->nlp_action & NLP_DO_RSCN) || + (ndlp->nlp_action & NLP_DO_SCSICMD) || + (binfo->fc_flag & FC_PT2PT) || + (ndlp->nlp_portname.nameType != NAME_IEEE)) { + + ndlp->nlp_flag &= ~NLP_FARP_SND; + ndlp->nlp_action &= ~NLP_DO_ADDR_AUTH; + if((!(binfo->fc_flag & FC_PT2PT)) && (ndlp->nlp_action == 0)) { + if(binfo->fc_ffstate == FC_READY) { + ndlp->nlp_action |= NLP_DO_RSCN; + } + else { + ndlp->nlp_action |= NLP_DO_DISC_START; + } + } + if(clp[CFG_FCP_ON].a_current) { + ndlp->nlp_state = NLP_PRLI; + if((ndlp->nlp_flag & NLP_RCV_PLOGI) && + (!(ndlp->nlp_action) || (ndlp->nlp_flag & NLP_REQ_SND)) && + !(binfo->fc_flag & FC_PT2PT)) { + ndlp->nlp_state = NLP_LOGIN; + } + else { + if((ndlp->nlp_DID & Fabric_DID_MASK) != Fabric_DID_MASK) { + fc_els_cmd(binfo, ELS_CMD_PRLI, + (void *)((ulong)ndlp->nlp_DID), (uint32)0, (ushort)0, ndlp); + } + else + fc_nextnode(p_dev_ctl, ndlp); + } + } else { + /* establish a new exchange for login registration */ + if ((ndlp->nlp_Xri == 0) && + (ndlp->nlp_type & NLP_IP_NODE) && + ((ndlp->nlp_DID & CT_DID_MASK) != CT_DID_MASK) && + !(ndlp->nlp_flag & NLP_RPI_XRI)) { + ndlp->nlp_flag |= NLP_RPI_XRI; + rp = &binfo->fc_ring[FC_ELS_RING]; + fc_create_xri(binfo, rp, ndlp); + } + if(!(ndlp->nlp_flag & NLP_RCV_PLOGI)) + fc_nextnode(p_dev_ctl, ndlp); + } + } else { + ndlp->nlp_flag &= ~NLP_FARP_SND; + ndlp->nlp_action &= ~NLP_DO_ADDR_AUTH; + /* establish a new exchange for Nport login registration */ + if ((ndlp->nlp_Xri == 0) && + ((ndlp->nlp_DID & CT_DID_MASK) != CT_DID_MASK) && + !(ndlp->nlp_flag & NLP_RPI_XRI)) { + ndlp->nlp_flag |= NLP_RPI_XRI; + rp = &binfo->fc_ring[FC_ELS_RING]; + fc_create_xri(binfo, rp, ndlp); /* IP ONLY */ + } + } + ndlp->nlp_flag &= ~NLP_RCV_PLOGI; + } + return; +} + +_static_ int +fc_snd_scsi_req( +fc_dev_ctl_t *p_dev_ctl, +NAME_TYPE *wwn, +MATCHMAP *bmp, +DMATCHMAP *fcpmp, +DMATCHMAP *omatp, +uint32 count, +struct dev_info *dev_ptr) +{ + FC_BRD_INFO *binfo; + NODELIST * ndlp; + RING * rp; + IOCBQ * temp; + IOCB * cmd; + ULP_BDE64 * bpl; + FCP_CMND * inqcmnd; + fc_buf_t * fcptr; + node_t * map_node_ptr; + struct dev_info * map_dev_ptr; + uint32 did; + fc_lun_t lun; + int i; + + binfo = &BINFO; + if(((ndlp = fc_findnode_wwpn(binfo, NLP_SEARCH_ALL, wwn)) == 0) || + (!(binfo->fc_flag & FC_SLI2))) { /* MUST be SLI2 */ + return(EACCES); + } + + if(ndlp->nlp_flag & NLP_REQ_SND) { + return(ENODEV); + } + + if(ndlp->nlp_state <= NLP_LOGIN) { + if ((ndlp->nlp_DID == binfo->fc_myDID) || + (ndlp->nlp_DID & Fabric_DID_MASK)) { + return(ENODEV); + } + ndlp->nlp_action |= NLP_DO_SCSICMD; + if((ndlp->nlp_state == NLP_LOGIN) && ndlp->nlp_Rpi) { + /* Need to send PRLI */ + fc_els_cmd(binfo, ELS_CMD_PRLI, + (void *)((ulong)ndlp->nlp_DID), (uint32)0, (ushort)0, ndlp); + } + else { + /* Need to send PLOGI */ + did = ndlp->nlp_DID; + if(did == 0) { + did = ndlp->nlp_oldDID; + } + if(!(ndlp->nlp_flag & NLP_NS_REMOVED)) { + fc_els_cmd(binfo, ELS_CMD_PLOGI, + (void *)((ulong)did), (uint32)0, (ushort)0, ndlp); + } + } + return(ENODEV); + } + + inqcmnd = (FCP_CMND *)fcpmp->dfc.virt; + lun = ((inqcmnd->fcpLunMsl >> FC_LUN_SHIFT) & 0xff); + + map_node_ptr = 0; + map_dev_ptr = 0; + + if (ndlp->nlp_type & NLP_SEED_MASK) { + /* If this is a mapped target, check qdepth limits */ + i = INDEX(ndlp->id.nlp_pan, ndlp->id.nlp_sid); + if ((map_node_ptr = binfo->device_queue_hash[i].node_ptr) != NULL) { + + if (map_node_ptr->tgt_queue_depth && + (map_node_ptr->tgt_queue_depth == map_node_ptr->num_active_io)) + return(ENODEV); + + if ((map_dev_ptr = fc_find_lun(binfo, i, lun))) { + if ((map_dev_ptr->active_io_count >= map_dev_ptr->fcp_cur_queue_depth) || + (map_dev_ptr->stop_send_io)) + return(ENODEV); + } + } + } + + rp = &binfo->fc_ring[FC_FCP_RING]; + if ((temp = (IOCBQ * )fc_mem_get(binfo, MEM_IOCB)) == NULL) { + return(EACCES); + } + + fc_bzero((void *)dev_ptr, sizeof(dev_ptr)); + dev_ptr->lun_id = lun; + dev_ptr->opened = TRUE; + dev_ptr->fcp_lun_queue_depth = 1; + dev_ptr->fcp_cur_queue_depth = 1; + dev_ptr->queue_state = ACTIVE_PASSTHRU; + dev_ptr->pend_head = (T_SCSIBUF *)map_node_ptr; + dev_ptr->pend_tail = (T_SCSIBUF *)map_dev_ptr; + + fcptr = (fc_buf_t *)fcpmp->dfc.virt; + fcptr->dev_ptr = dev_ptr; + fcptr->phys_adr = (char *)fcpmp->dfc.phys; + fcptr->sc_bufp = (T_SCSIBUF *)omatp; + fcptr->flags = 0; + /* set up an iotag so we can match the completion iocb */ + for (i = 0; i < MAX_FCP_CMDS; i++) { + fcptr->iotag = rp->fc_iotag++; + if (rp->fc_iotag >= MAX_FCP_CMDS) + rp->fc_iotag = 1; + if (binfo->fc_table->fcp_array[fcptr->iotag] == 0) + break; + } + if (i >= MAX_FCP_CMDS) { + /* No more command slots available, retry later */ + fc_mem_put(binfo, MEM_IOCB, (uchar * )temp); + return(EACCES); + } + + fc_bzero((void *)temp, sizeof(IOCBQ)); + cmd = &temp->iocb; + + bpl = (ULP_BDE64 * )bmp->virt; + + cmd->un.fcpi64.bdl.ulpIoTag32 = (uint32)0; + cmd->un.fcpi64.bdl.addrHigh = (uint32)putPaddrHigh(bmp->phys); + cmd->un.fcpi64.bdl.addrLow = (uint32)putPaddrLow(bmp->phys); + cmd->un.fcpi64.bdl.bdeFlags = BUFF_TYPE_BDL; + cmd->ulpBdeCount = 1; + fcptr->bmp = bmp; + temp->bpl = (uchar *)0; + + cmd->ulpContext = ndlp->nlp_Rpi; + cmd->ulpIoTag = fcptr->iotag; + /* + * if device is FCP-2 device, set the following bit that says + * to run the FC-TAPE protocol. + */ + if (ndlp->id.nlp_fcp_info & NLP_FCP_2_DEVICE) { + cmd->ulpFCP2Rcvy = 1; + } + cmd->ulpClass = (ndlp->id.nlp_fcp_info & 0x0f); + cmd->ulpOwner = OWN_CHIP; + + /* Hardcode 30 second timeout for I/O to complete */ + curtime(&fcptr->timeout); + cmd->ulpRsvdByte = fc_inq_sn_tmo; + fcptr->timeout = ((ulong)fcptr->timeout + (31 * fc_ticks_per_second)); + + switch(fcptr->fcp_cmd.fcpCntl3) { + case READ_DATA: + /* Set up for SCSI read */ + cmd->ulpCommand = CMD_FCP_IREAD64_CR; + cmd->ulpPU = PARM_READ_CHECK; + cmd->un.fcpi.fcpi_parm = count; + cmd->un.fcpi64.bdl.bdeSize = ((omatp->dfc_flag+2) * sizeof(ULP_BDE64)); + cmd->ulpBdeCount = 1; + break; + + case WRITE_DATA: + /* Set up for SCSI write */ + cmd->ulpCommand = CMD_FCP_IWRITE64_CR; + cmd->un.fcpi64.bdl.bdeSize = ((omatp->dfc_flag+2) * sizeof(ULP_BDE64)); + cmd->ulpBdeCount = 1; + break; + default: + /* Set up for SCSI command */ + cmd->ulpCommand = CMD_FCP_ICMND64_CR; + cmd->un.fcpi64.bdl.bdeSize = (2 * sizeof(ULP_BDE64)); + cmd->ulpBdeCount = 1; + break; + } + + cmd->ulpLe = 1; + /* Queue cmd chain to last iocb entry in xmit queue */ + if (rp->fc_tx.q_first == NULL) { + rp->fc_tx.q_first = (uchar * )temp; + } else { + ((IOCBQ * )(rp->fc_tx.q_last))->q = (uchar * )temp; + } + rp->fc_tx.q_last = (uchar * )temp; + rp->fc_tx.q_cnt++; + + fc_enq_fcbuf_active(rp, fcptr); + + if(map_dev_ptr) + map_dev_ptr->active_io_count++; + if(map_node_ptr) + map_node_ptr->num_active_io++; + dev_ptr->active_io_count++; + FCSTATCTR.fcpCmd++; + + issue_iocb_cmd(binfo, rp, 0); + return(0); +} + + +/****************************************************************************** +* Function name : fc_parse_binding_entry +* +* Description : Parse binding entry for WWNN & WWPN +* +* ASCII Input string example: 2000123456789abc:lpfc1t0 +* +* Return : 0 = Success +* Greater than 0 = Binding entry syntax error. SEE defs +* FC_SYNTAX_ERR_XXXXXX. +******************************************************************************/ +_static_ int +fc_parse_binding_entry( fc_dev_ctl_t *p_dev_ctl, + uchar *inbuf, uchar *outbuf, + int in_size, int out_size, + int bind_type, + unsigned int *sum, int entry, int *lpfc_num) +{ + int brd; + int c1, cvert_cnt, sumtmp; + + FC_BRD_INFO * binfo = &BINFO; + + char ds_lpfc[] = "lpfc"; + + *lpfc_num = -1; + + /* Parse 16 digit ASC hex address */ + if( bind_type == FC_BIND_DID) outbuf++; + cvert_cnt = fc_asc_seq_to_hex( p_dev_ctl, in_size, out_size, (char *)inbuf, (char *)outbuf); + if(cvert_cnt < 0) + return(FC_SYNTAX_ERR_ASC_CONVERT); + inbuf += (ulong)cvert_cnt; + + /* Parse colon */ + if(*inbuf++ != ':') + return(FC_SYNTAX_ERR_EXP_COLON); + + /* Parse lpfc */ + if(fc_strncmp( (char *)inbuf, ds_lpfc, (sizeof(ds_lpfc)-1))) + return(FC_SYNTAX_ERR_EXP_LPFC); + inbuf += sizeof(ds_lpfc)-1; + + /* Parse lpfc number */ + /* Get 1st lpfc digit */ + c1 = *inbuf++; + if(fc_is_digit(c1) == 0) + goto err_lpfc_num; + sumtmp = c1 - 0x30; + + /* Get 2nd lpfc digit */ + c1 = *inbuf; + if(fc_is_digit(c1) == 0) + goto convert_instance; + inbuf++; + sumtmp = (sumtmp * 10) + c1 - 0x30; + if((sumtmp < 0) || (sumtmp > 15)) + goto err_lpfc_num; + goto convert_instance; + +err_lpfc_num: + + return(FC_SYNTAX_ERR_INV_LPFC_NUM); + + /* Convert from ddi instance number to adapter number */ +convert_instance: + + for(brd = 0; brd < MAX_FC_BRDS; brd++) { + if(fcinstance[brd] == sumtmp) + break; + } + if(binfo->fc_brd_no != brd) { + /* Skip this entry */ + return(FC_SYNTAX_OK_BUT_NOT_THIS_BRD); + } + + + /* Parse 't' */ + if(*inbuf++ != 't') + return(FC_SYNTAX_ERR_EXP_T); + + /* Parse target number */ + /* Get 1st target digit */ + c1 = *inbuf++; + if(fc_is_digit(c1) == 0) + goto err_target_num; + sumtmp = c1 - 0x30; + + /* Get 2nd target digit */ + c1 = *inbuf; + if(fc_is_digit(c1) == 0) + goto check_for_term; + inbuf++; + sumtmp = (sumtmp * 10) + c1 - 0x30; + + /* Get 3nd target digit */ + c1 = *inbuf; + if(fc_is_digit(c1) == 0) + goto check_for_term; + inbuf++; + sumtmp = (sumtmp * 10) + c1 - 0x30; + if((sumtmp < 0) || (sumtmp > 999)) + goto err_target_num; + goto check_for_term; + +err_target_num: + return(FC_SYNTAX_ERR_INV_TARGET_NUM); + + /* Test that input string in NULL terminated - End of input */ +check_for_term: + + if(*inbuf != 0) + return(FC_SYNTAX_ERR_EXP_NULL_TERM); + + + *sum = sumtmp; + return(FC_SYNTAX_OK); /* Success */ +} /* fc_parse_binding_entry */ + +void +issue_report_lun( +fc_dev_ctl_t *pd, +void *l1, +void *l2) +{ + FC_BRD_INFO * binfo = &pd->info; + dvi_t * di = (dvi_t *)l1; + RING * rp; + fc_buf_t * fcptr; + IOCBQ * temp; + IOCB * cmd; + ULP_BDE64 * bpl; + MATCHMAP * bmp; + MBUF_INFO * mbufp; + node_t * nodep; + int i, tmo; + + rp = &binfo->fc_ring[FC_FCP_RING]; + nodep = di->nodep; + + mbufp = (MBUF_INFO * )fc_mem_get(binfo, MEM_IOCB); + if (mbufp == NULL) { + nodep->rptlunstate = REPORT_LUN_COMPLETE; + return; + } + mbufp->virt = 0; + mbufp->phys = 0; + mbufp->flags = FC_MBUF_DMA; + mbufp->align = (int)4096; + mbufp->size = 4096; + + if (nodep->virtRptLunData == 0) { + fc_malloc(pd, mbufp); + if (mbufp->phys == NULL) { + fc_mem_put(binfo, MEM_IOCB, (uchar * )mbufp); + nodep->rptlunstate = REPORT_LUN_COMPLETE; + return; + } + } else { + mbufp->phys = nodep->physRptLunData; + mbufp->virt = nodep->virtRptLunData; + } + + if ((fcptr = fc_deq_fcbuf(di)) == NULL) { + if (nodep->virtRptLunData == 0) + fc_free(pd, mbufp); + fc_mem_put(binfo, MEM_IOCB, (uchar * )mbufp); + nodep->rptlunstate = REPORT_LUN_COMPLETE; + return; + } + + if ((temp = (IOCBQ * )fc_mem_get(binfo, MEM_IOCB)) == NULL) { + if (nodep->virtRptLunData == 0) + fc_free(pd, mbufp); + fc_mem_put(binfo, MEM_IOCB, (uchar * )mbufp); + fc_enq_fcbuf(fcptr); + nodep->rptlunstate = REPORT_LUN_COMPLETE; + return; + } + + fc_bzero((void *)fcptr, sizeof(FCP_CMND) + sizeof(FCP_RSP)); + + /* + * Save the MBUF pointer. + * Buffer will be freed by handle_fcp_event(). + */ + fcptr->sc_bufp = (void *)mbufp; + + /* + * Setup SCSI command block in FCP payload + */ + fcptr->fcp_cmd.fcpCdb[0]= 0xA0; /* SCSI Report Lun Command */ + + fcptr->fcp_cmd.fcpCdb[8]= 0x10; + fcptr->fcp_cmd.fcpCntl3 = READ_DATA; + fcptr->fcp_cmd.fcpDl = SWAP_DATA(RPTLUN_MIN_LEN); + + /* + * set up an iotag so we can match the completion iocb + */ + for (i = 0; i < MAX_FCP_CMDS; i++) { + fcptr->iotag = rp->fc_iotag++; + if (rp->fc_iotag >= MAX_FCP_CMDS) + rp->fc_iotag = 1; + if (binfo->fc_table->fcp_array[fcptr->iotag] == 0) + break; + } + if (i >= MAX_FCP_CMDS) { + /* + * No more command slots available + */ + if (nodep->virtRptLunData == 0) + fc_free(pd, mbufp); + fc_mem_put(binfo, MEM_IOCB, (uchar * )mbufp); + fc_mem_put(binfo, MEM_IOCB, (uchar * )temp); + fc_enq_fcbuf(fcptr); + nodep->rptlunstate = REPORT_LUN_COMPLETE; + return; + } + + fc_bzero((void *)temp, sizeof(IOCBQ)); + cmd = &temp->iocb; + temp->q = NULL; + + /* + * Allocate buffer for Buffer ptr list + */ + if ((bmp = (MATCHMAP * )fc_mem_get(binfo, MEM_BPL)) == 0) { + if (nodep->virtRptLunData == 0) + fc_free(pd, mbufp); + fc_mem_put(binfo, MEM_IOCB, (uchar * )mbufp); + fc_mem_put(binfo, MEM_IOCB, (uchar * )temp); + fc_enq_fcbuf(fcptr); + nodep->rptlunstate = REPORT_LUN_COMPLETE; + return; + } + + bpl = (ULP_BDE64 * )bmp->virt; + bpl->addrHigh = PCIMEM_LONG((uint32)putPaddrHigh(GET_PAYLOAD_PHYS_ADDR(fcptr))); + bpl->addrLow = PCIMEM_LONG((uint32)putPaddrLow(GET_PAYLOAD_PHYS_ADDR(fcptr))); + bpl->tus.f.bdeSize = sizeof(FCP_CMND); + bpl->tus.f.bdeFlags = BUFF_USE_CMND; + bpl->tus.w = PCIMEM_LONG(bpl->tus.w); + bpl++; + bpl->addrHigh = PCIMEM_LONG((uint32)putPaddrHigh(GET_PAYLOAD_PHYS_ADDR(fcptr)+sizeof(FCP_CMND))); + bpl->addrLow = PCIMEM_LONG((uint32)putPaddrLow(GET_PAYLOAD_PHYS_ADDR(fcptr)+sizeof(FCP_CMND))); + bpl->tus.f.bdeSize = sizeof(FCP_RSP); + bpl->tus.f.bdeFlags = (BUFF_USE_CMND | BUFF_USE_RCV); + bpl->tus.w = PCIMEM_LONG(bpl->tus.w); + bpl++; + + cmd->un.fcpi64.bdl.ulpIoTag32 = (uint32)0; + cmd->un.fcpi64.bdl.addrHigh = (uint32)putPaddrHigh(bmp->phys); + cmd->un.fcpi64.bdl.addrLow = (uint32)putPaddrLow(bmp->phys); + cmd->un.fcpi64.bdl.bdeSize = (2 * sizeof(ULP_BDE64)); + cmd->un.fcpi64.bdl.bdeFlags = BUFF_TYPE_BDL; + cmd->ulpBdeCount = 1; + fcptr->bmp = bmp; + temp->bpl = (uchar *)0; + + cmd->ulpContext = nodep->rpi; + cmd->ulpIoTag = fcptr->iotag; + + /* + * if device is FCP-2 device, set the following bit that says + * to run the FC-TAPE protocol. + */ + if (nodep->nlp->id.nlp_fcp_info & NLP_FCP_2_DEVICE) { + cmd->ulpFCP2Rcvy = 1; + } + cmd->ulpClass = (nodep->nlp->id.nlp_fcp_info & 0x0f); + cmd->ulpOwner = OWN_CHIP; + + /* + * Hardcode 2*RATOV second timeout for I/O to complete + */ + tmo = (2 * binfo->fc_ratov); + curtime(&fcptr->timeout); + cmd->ulpRsvdByte = tmo; + tmo++; /* Make scsi timeout longer then cmd tmo */ + fcptr->timeout = ((ulong)fcptr->timeout + (tmo * fc_ticks_per_second)); + + /* + * Read Data + */ + cmd->ulpCommand = CMD_FCP_IREAD64_CR; + cmd->ulpPU = PARM_READ_CHECK; + cmd->un.fcpi.fcpi_parm = RPTLUN_MIN_LEN; + + bpl->addrHigh = PCIMEM_LONG((uint32)putPaddrHigh(mbufp->phys)); + bpl->addrLow = PCIMEM_LONG((uint32)putPaddrLow(mbufp->phys)); + bpl->tus.f.bdeSize = RPTLUN_MIN_LEN; + bpl->tus.f.bdeFlags = BUFF_USE_RCV; + bpl->tus.w = PCIMEM_LONG(bpl->tus.w); + bpl++; + + cmd->un.fcpi64.bdl.bdeSize += sizeof(ULP_BDE64); + cmd->ulpBdeCount = 1; + + cmd->ulpLe = 1; + + /* + * Queue cmd chain to last iocb entry in xmit queue + */ + if (rp->fc_tx.q_first == NULL) { + rp->fc_tx.q_first = (uchar * )temp; + } else { + ((IOCBQ * )(rp->fc_tx.q_last))->q = (uchar * )temp; + } + rp->fc_tx.q_last = (uchar * )temp; + rp->fc_tx.q_cnt++; + + fc_enq_fcbuf_active(rp, fcptr); + fcptr->flags |= FCBUF_INTERNAL; + + di->active_io_count++; + nodep->num_active_io++; + FCSTATCTR.fcpCmd++; + + issue_iocb_cmd(binfo, rp, 0); + return; +} +/****************************************/ +/* Print Format Declarations Start Here */ +/****************************************/ +_local_ int fc_sprintf_fargs( uchar *string, void *control, char *fixArgs); + +#define LENGTH_LINE 71 +#define MAX_IO_SIZE 32 * 2 /* iobuf cache size */ +#define MAX_TBUFF 18 * 2 /* temp buffer size */ + +typedef union { /* Pointer to table of arguments. */ + ulong *ip; + ulong *lip; + ulong *uip; + ulong *luip; + ulong **luipp; + uchar *cp; + uchar **csp; +} ARGLIST; + +typedef struct { + uchar *string; + long index; + int count; + uchar buf[MAX_IO_SIZE + MAX_TBUFF]; /* extra room to convert numbers */ +} PRINTBLK; + +/* + * ASCII string declarations + */ +static char dig[] = {"0123456789ABCDEF"}; +static char ds_disabled[] = "disabled"; +static char ds_enabled[] = "enabled"; +static char ds_none[] = "none"; +static char ds_null_string[] = ""; +static char ds_unknown[] = "unknown"; + +/* + * Function Declarations + */ +_local_ int add_char( PRINTBLK * io, uchar ch); +_local_ int add_string( PRINTBLK * io, uchar * string); +_local_ int fmtout( uchar *ostr, uchar *control, va_list inarg); +_local_ void print_string( PRINTBLK * io); +_local_ int long_itos( long val, uchar * cp, long base); + + +/**********************************************************/ +/** expanded_len */ +/** determine the length of the string after expanding */ +/**********************************************************/ +_local_ +int expanded_len( +uchar *sp) +{ + register int i; + uchar c; + + i = 0; + while ((c = *sp++) != 0) { + if (c < 0x1b) { + if ((c == '\r') || (c == '\n')) + break; /* stop at cr or lf */ + i++; /* double it */ + } + i++; + } + return (i); +} /* expanded_len */ + +/*************************************************/ +/** long_itos **/ +/** Convert long integer to decimal string. **/ +/** Returns the string length. **/ +/*************************************************/ +_local_ +int long_itos( +long val, /* Number to convert. */ +uchar * cp, /* Store the string here. */ +long base) /* Conversion base. */ +{ + uchar tempc[16]; + uchar *tcp; + int n=0; /* number of characters in result */ + ulong uval; /* unsigned value */ + + *(tcp=(tempc+15))=0; + if (base<0) { + /* needs signed conversion */ + base= -base; + if (val<0) { + n=1; + val = -val; + } + do { + *(--tcp)=dig[ (int)(val%base)]; + val /= base; + } while (val); + } + else { + uval=val; + do { + *(--tcp)=dig[ (int)(uval%base)]; + uval/=base; + } while(uval); + } + if (n) + *(--tcp)='-'; + n=(int)((long)&tempc[15] - (long)tcp); + fc_bcopy( tcp, cp, n+1); /* from, to, cnt */ + return(n); +} /* long_itos */ + +/****************************************/ +/** add_char **/ +/****************************************/ +_local_ +int add_char( +PRINTBLK * io, +uchar ch) +{ + int index; + + if (ch < 0x1b) { + switch (ch) { + case 0xd: /* carriage return */ + io->count = -1; /* will be incremented to 0, below */ + break; + case 0x8: /* back space */ + io->count -= 2; /* will be incremented to 1 less, below */ + break; + case 0xa: /* line feed */ + case 0x7: /* bell */ + case 0x9: /* hortizontal tab */ + case 0xe: /* shift out */ + case 0xf: /* shift in */ + io->count--; /* will be incremented to same, below */ + break; + default: + add_char(io, '^'); + ch |= 0x40; + break; + } + } + io->count++; + if (io->string != NULL) { + *io->string = ch; + *++io->string = '\0'; + return (0); + } + + index = io->index; + if( index < (MAX_IO_SIZE + MAX_TBUFF -2)) { + io->buf[index] = ch; + io->buf[++index] = '\0'; + } + return (++io->index); +} /* add_char */ + +/****************************************/ +/** add_string **/ +/****************************************/ +_local_ +int add_string( +PRINTBLK * io, +uchar * string) +{ + if (io->string != NULL) { + io->string = + (uchar *)fc_strcpy( (char *)io->string, (char *)string); /* dst, src */ + return (0); + } + return (io->index = ((long)(fc_strcpy( (char *)&io->buf[io->index], + (char *)string))) - ((long)((char *)io->buf))); /* dst, src */ +} /* add_string */ + +/*****************************************************/ +/** print_string **/ +/** takes print defn, prints data, zeroes index **/ +/*****************************************************/ +_local_ +void print_string( +PRINTBLK * io) +{ + io->index = 0; + fc_print( (char *)&io->buf[0],0,0); +} /* print_string */ + +/*VARARGS*/ +/*****************************************/ +/** fmtout **/ +/** Low-level string print routines. **/ +/*****************************************/ +_local_ +int fmtout ( +uchar *ostr, /* Output buffer, or NULL if temp */ +uchar *control, /* Control string */ +va_list inarg) /* Argument list */ +{ + short temp; /* Output channel number if string NULL. */ + int leftadj; /* Negative pararameter width specified. */ + int longflag; /* Integer is long. */ + int box = FALSE; /* not from body */ + int chr; /* control string character */ + uchar padchar; /* Pad character, typically space. */ + int width; /* Width of subfield. */ + int length; /* Length of subfield. */ + uchar *altctl; /* temp control string */ + ARGLIST altarg; + ARGLIST arg; + PRINTBLK io; + + union { /* Accumulate parameter value here. */ + uint16 tlong; + uint16 tulong; + long ltlong; + ulong ltulong; + uchar str[4]; + uint16 twds[2]; + } lw; + + union { /* Used by case %c */ + int intchar; + uchar chr[2]; + } ichar; + + arg.uip = (ulong *)inarg; + io.index = 0; + io.count = 0; + + if( (io.string = ostr) != (uchar *)NULL) + *ostr = 0; /* initialize output string to null */ + control--; + + mainloop: + altctl = NULL; + + while ((length = *++control) != 0) + { /* while more in control string */ + if (length !='%') { /* format control */ + if ((length == '\n') && box) { + fc_print( (char *)&io.buf[0],0,0); + continue; + } + if (add_char( &io, (uchar) length) >= MAX_IO_SIZE) + print_string(&io); /* write it */ + continue; + } + leftadj = (*++control == '-'); + if (leftadj) + ++control; + padchar = ' '; + width = 0; + if ((uint16)(length = (*control - '0')) <= 9) { + if (length == 0) + padchar = '0'; + width = length; + while ((uint16)(length = (*++control - '0')) <= 9 ) + width = width*10+length; + } + longflag = ( *control == 'l'); + if ( longflag) + ++control; + + chr = (int)(*control); + if( chr != 'E') { + chr |= 0x20; + } + + switch (chr) { + case 'a': + longflag = 1; + temp=16; + padchar = '0'; + length = width = 8; + goto nosign; + case 'b': + temp=2; + goto nosign; + case 'o': + temp=8; + goto nosign; + case 'u': + temp=10; + goto nosign; + case 'x': + temp=16; + goto nosign; + + case 'e': + ostr = (uchar *)va_arg(inarg, char *); + if ((chr == 'e') && + ((*(long *)ostr) == (long)NULL) && + ((*(uint16 *)&ostr[4]) == (uint16)0)) { + ostr = (uchar *)ds_unknown; + length = 7; + break; + } + temp = -1; + length = MAX_IO_SIZE -1; + fc_strcpy((char *)&io.buf[MAX_IO_SIZE], + "00-00-00-00-00-00"); /* dst, src */ + do { + long_itos((long)( ostr[++temp] + 256), lw.str, 16); + io.buf[++length] = lw.str[1]; + io.buf[++length] = lw.str[2]; + } while (++length < MAX_IO_SIZE+17); + ostr = &io.buf[MAX_IO_SIZE]; + length = 17; + break; + + case 'E': + ostr = (uchar *)va_arg(inarg, char *); + if ((chr == 'E') && + ((*(long *)ostr) == (long)NULL) && + ((*(long *)&ostr[4]) == (long)NULL)) { + ostr = (uchar *)ds_unknown; + length = 7; + break; + } + temp = -1; + length = MAX_IO_SIZE -1; + fc_strcpy( (char *)&io.buf[MAX_IO_SIZE], + "00-00-00-00-00-00-00-00"); /* dst, src */ + do { + long_itos((long)( ostr[++temp] + 256), lw.str, 16); + io.buf[++length] = lw.str[1]; + io.buf[++length] = lw.str[2]; + } while (++length < MAX_IO_SIZE+23); + ostr = &io.buf[MAX_IO_SIZE]; + length = 23; + break; + + case 'f': /* flags */ + ostr = (uchar *)ds_disabled; + length = 8; + if (va_arg(inarg, char *) != 0) { /* test value */ + ostr = (uchar *)ds_enabled; + length = 7; + } + if (chr == 'F') { + length -= 7; + ostr = (uchar *)"-"; + } + break; + + case 'i': + ostr = (uchar *)va_arg(inarg, char *); + if ((chr == 'i') && *(long *)ostr == (long)NULL) + goto putnone; + temp = 0; + length = MAX_IO_SIZE; + do { + length += long_itos((long) ostr[temp], &io.buf[length], 10); + if ( ++temp >= 4) + break; + io.buf[length] = '.'; + length++; + } while (TRUE); + ostr = &io.buf[MAX_IO_SIZE]; + length -= MAX_IO_SIZE; + break; + + case 'y': /* flags */ + if ( va_arg(inarg, char *) != 0) { /* test value */ + ostr = (uchar*)"yes"; + length = 3; + } + else { + ostr = (uchar*)"no"; + length = 2; + } + break; + + case 'c': + if (chr == 'C') { /* normal, control, or none */ + if ((length = va_arg(inarg, int)) < ' ') { + if (length == 0) { + ostr = (uchar *)ds_none; + length = 4; + } + else { + io.buf[MAX_IO_SIZE] = '^'; + io.buf[MAX_IO_SIZE+1] = ((uchar)length) + '@'; + io.buf[MAX_IO_SIZE+2] = 0; + ostr = &io.buf[MAX_IO_SIZE]; + length = 2; + } + arg.ip++; + break; + } + } /* normal, control, or none */ + + ichar.intchar = va_arg(inarg, int); + ostr = &ichar.chr[0]; + length=1; + break; + + case 'd': + temp = -10; + nosign: + if (longflag) + lw.ltulong = va_arg(inarg, ulong); + else if (temp < 0) + lw.ltlong = va_arg(inarg, long); + else + lw.ltulong = va_arg(inarg, ulong); +/* + nosign2: +*/ + length = long_itos( lw.ltlong, ostr = &io.buf[MAX_IO_SIZE], temp); + break; + + case 's': + ostr = (uchar *)va_arg(inarg, char *); /* string */ + if ((chr == 's') || (*ostr != '\0')) { + length = expanded_len(ostr); + break; + } + putnone: + ostr = (uchar *)ds_none; + length = 4; + break; + + case 't': /* tabbing */ + if ((width -= io.count) < 0) /* Spaces required to get to column. */ + width = 0; + length = 0; /* nothing other than width padding. */ + ostr = (uchar *)ds_null_string; + break; + case ' ': + width = va_arg(inarg, int); + length = 0; /* nothing other than width padding. */ + ostr = (uchar *)ds_null_string; + break; + + default: + ostr=control; + length=1; + break; + } /* switch on control */ + + if (length < 0) { /* non printing */ + if (add_string( &io, ostr) >= MAX_IO_SIZE) + print_string(&io); /* no more room, dump current buffer */ + continue; + } /* non printing */ + + + if (!leftadj && width > length) { + while (--width >= length) { + if (add_char( &io, padchar) >= MAX_IO_SIZE) + print_string(&io); /* write it */ + } + } + + if (width>length) + width -= length; + else + width = 0; + + if (length <= 1) { + if (length == 1) { + if (add_char( &io, *ostr) >= MAX_IO_SIZE) + print_string(&io); /* write it */ + } + } + else { + while ((temp = *ostr++) != 0) { + if (add_char( &io, (uchar) temp) >= MAX_IO_SIZE) + print_string(&io); /* write it */ + } + } + + while (--width >= 0) { + if (add_char( &io, padchar) >= MAX_IO_SIZE) + print_string(&io); /* write it */ + } + + } /* while more in control string */ + + if (altctl != NULL) { + control = altctl; + arg.ip = altarg.ip; + goto mainloop; + } + + if (io.index) /* anything left? */ + print_string(&io); /* write it */ + + return(io.count); +} /* fmtout */ +/*FIXARGS*/ +_local_ int +fc_sprintf_fargs( +uchar *string, /* output buffer */ +void *control, /* format string */ +char *fixArgs) /* control arguments */ +{ + return( fmtout((uchar *)string, (uchar *)control, fixArgs)); +} /* fc_sprintf_fargs */ +/*VARARGS*/ +int fc_sprintf_vargs( + void *string, /* output buffer */ + void *control, /* format string */ + ...) /* control arguments */ +{ + int iocnt; + va_list args; + va_start(args, control); + + iocnt = fmtout((uchar *)string, (uchar *)control, args); + va_end( args); + return( iocnt); +} /* fc_sprintf_vargs */ +/****************************************/ +/** fc_log_printf_msg_vargs **/ +/****************************************/ +/* +All log messages come through this routine. +All log messages are unique. +All log messages are define by a msgLogDef messages structure. +*/ +/*VARARGS*/ +_static_ int +fc_log_printf_msg_vargs( + int brdno, + msgLogDef * msg, /* Pionter to LOG msg structure */ + void * control, + ...) +{ + uchar str2[MAX_IO_SIZE + MAX_TBUFF]; /* extra room to convert numbers */ + int iocnt; + int log_only; + va_list args; + va_start(args, control); + + log_only = 0; + if( fc_check_this_log_msg_disabled( brdno, msg, &log_only)) + return(0); /* This LOG message disabled */ + + /* + If LOG message is disabled via any SW method, we SHOULD NOT get this far! + We should have taken the above return. + */ + + str2[0] = '\0'; + iocnt = fc_sprintf_fargs(str2, control, args); + va_end( args); + + return( log_printf_msgblk( brdno, msg, (char *)str2, log_only)); +} /* fc_log_printf_msg_vargs */ + +/*****************************************************/ +/** Function name : fc_check_this_log_msg_disabled **/ +/** **/ +/** Description : **/ +/** **/ +/** Return : 0 LOG message enabled **/ +/** : 1 LOG message disabled **/ +/*****************************************************/ +int fc_check_this_log_msg_disabled( int brdno, + msgLogDef *msg, + int *log_only) +{ + fc_dev_ctl_t * p_dev_ctl; + iCfgParam * clp; + int verbose; + + verbose = 0; + if( msg->msgOutput == FC_MSG_OPUT_DISA) + return(1); /* This LOG message disabled */ + + if ((p_dev_ctl = DD_CTL.p_dev[brdno])) { + clp = DD_CTL.p_config[brdno]; + if((*log_only = clp[CFG_LOG_ONLY].a_current) > 1) + return(1); /* This LOG message disabled */ + verbose = clp[CFG_LOG_VERBOSE].a_current; + } + + if( msg->msgOutput == FC_MSG_OPUT_FORCE) + return(0); /* This LOG message enabled */ + /* + * If this is a verbose message (INFO or WARN) and we are not in + * verbose mode, return 1. If it is a verbose message and the verbose + * error doesn't match our verbose mask, return 1. + */ + if( (msg->msgType == FC_LOG_MSG_TYPE_INFO) || + (msg->msgType == FC_LOG_MSG_TYPE_WARN)) { + /* LOG msg is INFO or WARN */ + if ((msg->msgMask & verbose) == 0) + return(1); /* This LOG mesaage disabled */ + } + return(0); /* This LOG message enabled */ +} /* fc_check_this_log_msg_disabled */ + +/*************************************************/ +/** fc_asc_to_hex **/ +/** Convert an ASCII hex character to hex. **/ +/** Return Hex value if success **/ +/** -1 if character not ASCII hex **/ +/*************************************************/ + +_forward_ int +fc_asc_to_hex( + uchar c) /* Character to convert */ +{ +if (c >= '0' && c <= '9') + return(c - '0'); +else if (c >= 'A' && c <= 'F') + return(c - 'A'+ 10); +else if (c >= 'a' && c <= 'f') + return(c - 'a'+ 10); +else + return(-1); +} /* fc_asc_to_hex */ + +/***************************************************/ +/** fc_asc_seq_to_hex **/ +/** **/ +/** Convert an ASCII character sequence to a **/ +/** hex number sequence **/ +/** **/ +/** return >0 Success. Return number of ASCII **/ +/** hex characters converted. **/ +/** -1 Input byte count < 1 **/ +/** -2 Input byte count > max **/ +/** -3 Output buffer to small **/ +/** -4 Input character sequence not **/ +/** ASCII hex. **/ +/***************************************************/ + +/* +This routine converts an ASCII char stream of byte into +a stream of hex bytes. The byte order of the input and +output stream are identical. The caller must deal with +SWAPPING bytes if required. + +The maximum number of ASCII hex characters that can be +convert to hex is hard coded by the LOCAL define +MAX_ASC_HEX_CHARS_INPUT. + +Two ASCII hex input characters require 1 byte of output +buffer. + +A NULL terminator at the end of an ASCII hex input string +is not required nor is it counted in the strings byte size. + +To determine the byte size of the output buffer: +(1) Add 1 to input buffer byte size if size is odd. +(2) Output buffer size = input buffer size / 2. + +Therefore an input buffer containing 10 ASC hex chars +requires an output buffer size of 5 bytes. + +An input buffer containing 11 ASC hex chars requires an +output buffer size of 6 bytes. +*/ + +_forward_ int +fc_asc_seq_to_hex( fc_dev_ctl_t *p_dev_ctl, + int input_bc, /* Number of bytes (ASC hex chars) to be converted */ + int output_bc, /* Number of bytes in hex output buffer (modulo INT) */ + char *inp, /* Pointer to ASC hex input character sequence */ + char *outp) /* Pointer to hex output buffer */ +{ +#define HEX_DIGITS_PER_BYTE 2 +#define MAX_ASC_HEX_CHARS_INPUT 32 /* Limit damage if over-write */ +#define MAX_BUF_SIZE_HEX_OUTPUT (MAX_ASC_HEX_CHARS_INPUT / HEX_DIGITS_PER_BYTE) + + FC_BRD_INFO *binfo; + int lowNib, hiNib; + int inputCharsConverted; + uchar twoHexDig; + + binfo = &BINFO; + inputCharsConverted = 0; + lowNib = -1; + hiNib = -1; + + if(input_bc < 1) { + /* Convert ASC to hex. Input byte cnt < 1. */ + fc_log_printf_msg_vargs( binfo->fc_brd_no, + &fc_msgBlk1210, /* ptr to msg structure */ + fc_mes1210, /* ptr to msg */ + fc_msgBlk1210.msgPreambleStr); /* begin & end varargs */ + return(-1); + } + if(input_bc > MAX_ASC_HEX_CHARS_INPUT) { + /* Convert ASC to hex. Input byte cnt > max */ + fc_log_printf_msg_vargs( binfo->fc_brd_no, + &fc_msgBlk1211, /* ptr to msg structure */ + fc_mes1211, /* ptr to msg */ + fc_msgBlk1211.msgPreambleStr, /* begin varargs */ + MAX_ASC_HEX_CHARS_INPUT); /* end varargs */ + return(-2); + } + if((output_bc * 2) < input_bc) { + /* Convert ASC to hex. Output buffer to small. */ + fc_log_printf_msg_vargs( binfo->fc_brd_no, + &fc_msgBlk1212, /* ptr to msg structure */ + fc_mes1212, /* ptr to msg */ + fc_msgBlk1212.msgPreambleStr); /* begin & end varargs */ + return(-4); + } + + while( input_bc) { + twoHexDig = 0; + lowNib = -1; + hiNib = fc_asc_to_hex( *inp++); + if( --input_bc > 0) { + lowNib = fc_asc_to_hex( *inp++); + input_bc--; + } + if ((lowNib < 0) || (hiNib < 0)) { + /* Convert ASC to hex. Input char seq not ASC hex. */ + fc_log_printf_msg_vargs( binfo->fc_brd_no, + &fc_msgBlk1213, /* ptr to msg structure */ + fc_mes1213, /* ptr to msg */ + fc_msgBlk1213.msgPreambleStr); /* begin & end varargs */ + return( -4); + } + if( lowNib >= 0) { + /* There were 2 digits */ + hiNib <<= 4; + twoHexDig = (hiNib | lowNib); + inputCharsConverted += 2; + } + else { + /* There was a single digit */ + twoHexDig = lowNib; + inputCharsConverted++; + } + *outp++ = twoHexDig; + } /* while */ + return(inputCharsConverted); /* ASC to hex conversion complete. Return # of chars converted */ +} /* fc_asc_seq_to_hex */ + +/********************************************/ +/** fc_is_digit **/ +/** **/ +/** Check if ASCII input value is numeric. **/ +/** **/ +/** Return 0 = input NOT numeric **/ +/** 1 = input IS numeric **/ +/********************************************/ +_forward_ int +fc_is_digit(int chr) +{ + if( (chr >= '0') && (chr <= '9')) + return(1); + return(0); +} /* fc_is_digit */ + diff -purN -X /home/mbligh/.diff.exclude 350-autoswap/drivers/scsi/lpfc/fcstratb.c 370-emulex/drivers/scsi/lpfc/fcstratb.c --- 350-autoswap/drivers/scsi/lpfc/fcstratb.c 1969-12-31 16:00:00.000000000 -0800 +++ 370-emulex/drivers/scsi/lpfc/fcstratb.c 2004-02-28 11:20:05.000000000 -0800 @@ -0,0 +1,2080 @@ +/******************************************************************* + * This file is part of the Emulex Linux Device Driver for * + * Enterprise Fibre Channel Host Bus Adapters. * + * Refer to the README file included with this package for * + * driver version and adapter support. * + * Copyright (C) 2003 Emulex Corporation. * + * www.emulex.com * + * * + * This program is free software; you can redistribute it and/or * + * modify it under the terms of the GNU General Public License * + * as published by the Free Software Foundation; either version 2 * + * of the License, or (at your option) any later version. * + * * + * This program is distributed in the hope that it will be useful, * + * but WITHOUT ANY WARRANTY; without even the implied warranty of * + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * + * GNU General Public License for more details, a copy of which * + * can be found in the file COPYING included with this package. * + *******************************************************************/ + +#include "fc_os.h" + +#include "fc_hw.h" +#include "fc.h" + +#include "fcdiag.h" +#include "fcfgparm.h" +#include "fcmsg.h" +#include "fc_crtn.h" +#include "fc_ertn.h" + +extern fc_dd_ctl_t DD_CTL; +extern iCfgParam icfgparam[]; + + + + +/* Some timers in data structures are stored in seconds, some environments + * timeout functions work in ticks, thus some conversion is required. + * Other externs, as needed for environemt are defined here. + */ +extern uint32 fc_scsi_abort_timeout_ticks; +extern uint32 fc_ticks_per_second; + + + + +/* Routine Declaration - Local */ +_local_ void fc_deq_abort_bdr(dvi_t *dev_ptr); +_local_ void fc_deq_wait(dvi_t *dev_ptr); +/* End Routine Declaration - Local */ + +/* AlpaArray for assignment of scsid for scan-down == 2 */ +_static_ uchar AlpaArray[] = + { + 0xEF, 0xE8, 0xE4, 0xE2, 0xE1, 0xE0, 0xDC, 0xDA, 0xD9, 0xD6, + 0xD5, 0xD4, 0xD3, 0xD2, 0xD1, 0xCE, 0xCD, 0xCC, 0xCB, 0xCA, + 0xC9, 0xC7, 0xC6, 0xC5, 0xC3, 0xBC, 0xBA, 0xB9, 0xB6, 0xB5, + 0xB4, 0xB3, 0xB2, 0xB1, 0xAE, 0xAD, 0xAC, 0xAB, 0xAA, 0xA9, + 0xA7, 0xA6, 0xA5, 0xA3, 0x9F, 0x9E, 0x9D, 0x9B, 0x98, 0x97, + 0x90, 0x8F, 0x88, 0x84, 0x82, 0x81, 0x80, 0x7C, 0x7A, 0x79, + 0x76, 0x75, 0x74, 0x73, 0x72, 0x71, 0x6E, 0x6D, 0x6C, 0x6B, + 0x6A, 0x69, 0x67, 0x66, 0x65, 0x63, 0x5C, 0x5A, 0x59, 0x56, + 0x55, 0x54, 0x53, 0x52, 0x51, 0x4E, 0x4D, 0x4C, 0x4B, 0x4A, + 0x49, 0x47, 0x46, 0x45, 0x43, 0x3C, 0x3A, 0x39, 0x36, 0x35, + 0x34, 0x33, 0x32, 0x31, 0x2E, 0x2D, 0x2C, 0x2B, 0x2A, 0x29, + 0x27, 0x26, 0x25, 0x23, 0x1F, 0x1E, 0x1D, 0x1B, 0x18, 0x17, + 0x10, 0x0F, 0x08, 0x04, 0x02, 0x01 + }; + + +_static_ dvi_t * +fc_fcp_abort( + fc_dev_ctl_t * p_dev_ctl, + int flag, + int target, + int lun) +{ + FC_BRD_INFO * binfo; + node_t * node_ptr; + dvi_t * dev_ptr; + dvi_t * xmt_devp, * devp; + RING * rp; + int i; + + binfo = &BINFO; + if(binfo->fc_flag & FC_ESTABLISH_LINK) + return(0); + + rp = &binfo->fc_ring[FC_FCP_RING]; + xmt_devp = 0; + /* Clear the queues for one or more SCSI devices + * flag will indicate perform a Target Reset, Lun Reset, or Abort Task Set + * if target = -1, all targets (bus reset). + * if lun = -1 all luns on the target. + */ + for (i = 0; i < MAX_FC_TARGETS; i++) { + if ((node_ptr = binfo->device_queue_hash[i].node_ptr) != NULL) { + if ((target != -1) && (node_ptr->scsi_id != target)) + continue; + dev_ptr = node_ptr->lunlist; + if((flag == TARGET_RESET) && + (dev_ptr != NULL)) { + if((node_ptr->rpi != 0xFFFE) && (binfo->fc_ffstate == FC_READY)) { + if(dev_ptr->flags & (SCSI_LUN_RESET | SCSI_ABORT_TSET)) { + /* check if we sent abort task set or reset lun */ + for (devp = p_dev_ctl->ABORT_BDR_head; (devp != NULL); + devp = devp->ABORT_BDR_fwd) { + if(devp == dev_ptr) + break; + } + if(devp) { + /* we found devp, its not sent yet, + * so change it to target reset. + */ + dev_ptr->flags &= ~CHK_SCSI_ABDR; + dev_ptr->flags |= SCSI_TARGET_RESET; + } + else { + /* just Q another task mgmt cmd, target reset */ + dev_ptr->flags |= SCSI_TARGET_RESET; + fc_enq_abort_bdr(dev_ptr); + } + xmt_devp = dev_ptr; + } + else if(!(dev_ptr->flags & SCSI_TARGET_RESET)) { + dev_ptr->flags |= SCSI_TARGET_RESET; + fc_enq_abort_bdr(dev_ptr); + fc_issue_cmd(p_dev_ctl); + xmt_devp = dev_ptr; + } + } + } + for (dev_ptr = node_ptr->lunlist; dev_ptr != NULL; + dev_ptr = dev_ptr->next) { + if ((lun != -1) && (dev_ptr->lun_id != lun)) + continue; + + if(flag == TARGET_RESET) { + if((node_ptr->rpi != 0xFFFE) && (binfo->fc_ffstate == FC_READY)) { + dev_ptr->flags |= SCSI_TARGET_RESET; + dev_ptr->queue_state = HALTED; + fc_fail_pendq(dev_ptr, (char) EIO, 0); + } + else { + /* First send ABTS on outstanding I/Os in txp queue */ + fc_abort_fcp_txpq(binfo, dev_ptr); + + fc_fail_pendq(dev_ptr, (char) EIO, 0); + fc_fail_cmd(dev_ptr, (char) EIO, 0); + } + } + + if((flag == LUN_RESET) && + !(dev_ptr->flags & CHK_SCSI_ABDR)) { + + if((node_ptr->rpi != 0xFFFE) && (binfo->fc_ffstate == FC_READY)) { + dev_ptr->flags |= SCSI_LUN_RESET; + fc_enq_abort_bdr(dev_ptr); + fc_issue_cmd(p_dev_ctl); + xmt_devp = dev_ptr; + dev_ptr->queue_state = HALTED; + fc_fail_pendq(dev_ptr, (char) EIO, 0); + } + else { + /* First send ABTS on outstanding I/Os in txp queue */ + fc_abort_fcp_txpq(binfo, dev_ptr); + + fc_fail_pendq(dev_ptr, (char) EIO, 0); + fc_fail_cmd(dev_ptr, (char) EIO, 0); + } + } + + if((flag == ABORT_TASK_SET) && + !(dev_ptr->flags & CHK_SCSI_ABDR)) { + + if((node_ptr->rpi != 0xFFFE) && (binfo->fc_ffstate == FC_READY)) { + dev_ptr->flags |= SCSI_ABORT_TSET; + fc_enq_abort_bdr(dev_ptr); + fc_issue_cmd(p_dev_ctl); + xmt_devp = dev_ptr; + dev_ptr->queue_state = HALTED; + fc_fail_pendq(dev_ptr, (char) EIO, 0); + } + else { + /* First send ABTS on outstanding I/Os in txp queue */ + fc_abort_fcp_txpq(binfo, dev_ptr); + + fc_fail_pendq(dev_ptr, (char) EIO, 0); + fc_fail_cmd(dev_ptr, (char) EIO, 0); + } + } + } + } + } + return(xmt_devp); +} + +_static_ int +issue_abdr( + fc_dev_ctl_t * ap, + dvi_t * dev_ptr, + RING * rp, + fc_lun_t lun) +{ + FC_BRD_INFO * binfo; + iCfgParam * clp; + fc_buf_t * fcptr; + T_SCSIBUF * sbp; + IOCB * cmd; + IOCBQ * temp; + uint32 * lp; + MATCHMAP * bmp; + ULP_BDE64 * bpl; + int i; + + binfo = &ap->info; + if ((fcptr = fc_deq_fcbuf(dev_ptr)) == NULL) { + return(EIO); + } + + if ((temp = (IOCBQ * )fc_mem_get(binfo, MEM_IOCB)) == NULL) { + fc_enq_fcbuf(fcptr); + return(EIO); + } + + { + uint32 did; + uint32 pan; + uint32 sid; + + if ((dev_ptr->nodep) && (dev_ptr->nodep->nlp)) { + did = dev_ptr->nodep->nlp->nlp_DID; + pan = dev_ptr->nodep->nlp->id.nlp_pan; + sid = dev_ptr->nodep->nlp->id.nlp_sid; + } else { + did = 0; + pan = 0; + sid = 0; + } + + if (dev_ptr->flags & SCSI_ABORT_TSET) { + /* Issue Abort Task Set I/O for LUN */ + fc_log_printf_msg_vargs( binfo->fc_brd_no, + &fc_msgBlk0701, /* ptr to msg structure */ + fc_mes0701, /* ptr to msg */ + fc_msgBlk0701.msgPreambleStr, /* begin varargs */ + (uint32)lun, + did, + FC_SCSID(pan, sid), + dev_ptr->flags); /* end varargs */ + } else if (dev_ptr->flags & SCSI_TARGET_RESET) { + /* Issue Target Reset I/O */ + fc_log_printf_msg_vargs( binfo->fc_brd_no, + &fc_msgBlk0702, /* ptr to msg structure */ + fc_mes0702, /* ptr to msg */ + fc_msgBlk0702.msgPreambleStr, /* begin varargs */ + (uint32)lun, + did, + FC_SCSID(pan, sid), + dev_ptr->flags); /* end varargs */ + } else if (dev_ptr->flags & SCSI_LUN_RESET) { + /* Issue LUN Reset I/O for LUN */ + fc_log_printf_msg_vargs( binfo->fc_brd_no, + &fc_msgBlk0703, /* ptr to msg structure */ + fc_mes0703, /* ptr to msg */ + fc_msgBlk0703.msgPreambleStr, /* begin varargs */ + (uint32)lun, + did, + FC_SCSID(pan, sid), + dev_ptr->flags); /* end varargs */ + } + } + + sbp = &dev_ptr->scbuf; + clp = DD_CTL.p_config[binfo->fc_brd_no]; + + fc_bzero((void *)fcptr, sizeof(FCP_CMND) + sizeof(FCP_RSP)); + + /* shift lun id into the right payload byte */ + fcptr->fcp_cmd.fcpLunMsl = lun << FC_LUN_SHIFT; + fcptr->fcp_cmd.fcpLunLsl = 0; + if (dev_ptr->nodep->addr_mode == VOLUME_SET_ADDRESSING) { + fcptr->fcp_cmd.fcpLunMsl |= SWAP_DATA(0x40000000); + } + + fcptr->sc_bufp = sbp; + fcptr->flags = 0; + sbp->bufstruct.b_flags = 0; + sbp->bufstruct.b_error = 0; + + if (dev_ptr->flags & SCSI_ABORT_TSET) { + /* Issue an Abort Task Set task management command */ + fcptr->fcp_cmd.fcpCntl2 = ABORT_TASK_SET; + } else if (dev_ptr->flags & SCSI_TARGET_RESET) { + /* Issue a Target Reset task management command */ + fcptr->fcp_cmd.fcpCntl2 = TARGET_RESET; + } else if (dev_ptr->flags & SCSI_LUN_RESET) { + /* Issue a Lun Reset task management command */ + fcptr->fcp_cmd.fcpCntl2 = LUN_RESET; + } + + /* set up an iotag so we can match the completion iocb */ + for (i = 0; i < MAX_FCP_CMDS; i++) { + fcptr->iotag = rp->fc_iotag++; + if (rp->fc_iotag >= MAX_FCP_CMDS) + rp->fc_iotag = 1; + if (binfo->fc_table->fcp_array[fcptr->iotag] == 0) + break; + } + + if (i >= MAX_FCP_CMDS) { + /* No more command slots available, retry later */ + fc_mem_put(binfo, MEM_IOCB, (uchar * )temp); + fc_enq_fcbuf(fcptr); + return(EIO); + } + + fc_bzero((void *)temp, sizeof(IOCBQ)); /* zero the iocb entry */ + cmd = &temp->iocb; + + if (binfo->fc_flag & FC_SLI2) { + /* Allocate buffer for Buffer ptr list */ + if ((bmp = (MATCHMAP * )fc_mem_get(binfo, MEM_BPL)) == 0) { + fc_mem_put(binfo, MEM_IOCB, (uchar * )temp); + fc_enq_fcbuf(fcptr); + return(EIO); + } + bpl = (ULP_BDE64 * )bmp->virt; + bpl->addrHigh = PCIMEM_LONG((uint32)putPaddrHigh(GET_PAYLOAD_PHYS_ADDR(fcptr))); + bpl->addrLow = PCIMEM_LONG((uint32)putPaddrLow(GET_PAYLOAD_PHYS_ADDR(fcptr))); + bpl->tus.f.bdeSize = sizeof(FCP_CMND); + bpl->tus.f.bdeFlags = BUFF_USE_CMND; + bpl->tus.w = PCIMEM_LONG(bpl->tus.w); + + bpl++; + bpl->addrHigh = PCIMEM_LONG((uint32)putPaddrHigh(GET_PAYLOAD_PHYS_ADDR(fcptr)+sizeof(FCP_CMND))); + bpl->addrLow = PCIMEM_LONG((uint32)putPaddrLow(GET_PAYLOAD_PHYS_ADDR(fcptr)+sizeof(FCP_CMND))); + bpl->tus.f.bdeSize = sizeof(FCP_RSP); + bpl->tus.f.bdeFlags = (BUFF_USE_CMND | BUFF_USE_RCV); + bpl->tus.w = PCIMEM_LONG(bpl->tus.w); + + bpl++; + cmd->un.fcpi64.bdl.ulpIoTag32 = (uint32)0; + cmd->un.fcpi64.bdl.addrHigh = (uint32)putPaddrHigh(bmp->phys); + cmd->un.fcpi64.bdl.addrLow = (uint32)putPaddrLow(bmp->phys); + cmd->un.fcpi64.bdl.bdeSize = (2 * sizeof(ULP_BDE64)); + cmd->un.fcpi64.bdl.bdeFlags = BUFF_TYPE_BDL; + + cmd->ulpCommand = CMD_FCP_ICMND64_CR; + cmd->ulpBdeCount = 1; + fcptr->bmp = bmp; + temp->bpl = (uchar *)0; + } else { + cmd->un.fcpi.fcpi_cmnd.bdeAddress = (uint32)putPaddrLow(GET_PAYLOAD_PHYS_ADDR(fcptr)); + cmd->un.fcpi.fcpi_cmnd.bdeSize = sizeof(FCP_CMND); + cmd->un.fcpi.fcpi_rsp.bdeAddress = (uint32)(putPaddrLow((GET_PAYLOAD_PHYS_ADDR(fcptr) + sizeof(FCP_CMND)))); + cmd->un.fcpi.fcpi_rsp.bdeSize = sizeof(FCP_RSP); + cmd->ulpCommand = CMD_FCP_ICMND_CR; + cmd->ulpBdeCount = 2; + temp->bpl = (uchar *)0; + } + cmd->ulpContext = dev_ptr->nodep->rpi; + cmd->ulpIoTag = fcptr->iotag; + cmd->ulpClass = (dev_ptr->nodep->nlp->id.nlp_fcp_info & 0x0f); + cmd->ulpOwner = OWN_CHIP; + cmd->ulpLe = 1; + + /* Timeout for this command is 30 seconds */ + curtime(&fcptr->timeout); + + + /* Need to set the FCP timeout in the fcptr structure and the IOCB + * for this I/O to get the adapter to run a timer. + */ + { + uint32 time_out; + + time_out = fc_scsi_abort_timeout_ticks; + if (binfo->fc_flag & FC_FABRIC) { + time_out += (fc_ticks_per_second * + (clp[CFG_FCPFABRIC_TMO].a_current + (2 * binfo->fc_ratov))); + } + + fcptr->timeout = ((ulong)fcptr->timeout + time_out + fc_scsi_abort_timeout_ticks); + + /* Set the FCP timeout in the IOCB to get the adapter to run a timer */ + if ((time_out / fc_ticks_per_second) < 256) + cmd->ulpTimeout = time_out / fc_ticks_per_second; + + } + + lp = (uint32 * ) & fcptr->fcp_cmd; + dev_ptr->active_io_count++; + dev_ptr->nodep->num_active_io++; + + /* Queue command to last iocb entry in xmit queue */ + if (rp->fc_tx.q_first == NULL) { + rp->fc_tx.q_first = (uchar * )temp; + } else { + ((IOCBQ * )(rp->fc_tx.q_last))->q = (uchar * )temp; + } + rp->fc_tx.q_last = (uchar * )temp; + rp->fc_tx.q_cnt++; + + fc_enq_fcbuf_active(rp, fcptr); + return (0); +} + + +/************************************************************************/ +/* */ +/* NAME: fc_issue_cmd */ +/* */ +/* FUNCTION: issues a waiting FCP command, or ABORT/BDR command */ +/* */ +/* EXECUTION ENVIRONMENT: */ +/* Called by a process or the interrupt handler */ +/* */ +/* INPUTS: */ +/* ap pointer to the adapter structure */ +/* */ +/* RETURN VALUE DESCRIPTION: none */ +/* */ +/* ERROR DESCRIPTION: none */ +/* */ +/* EXTERNAL PROCEDURES CALLED: */ +/* iodone */ +/************************************************************************/ +_static_ void +fc_issue_cmd( + fc_dev_ctl_t * ap) +{ + dvi_t * dev_ptr, * requeue_ptr; + T_SCSIBUF * sbp; + int rc, requeue, exit; + FC_BRD_INFO * binfo; + RING * rp; + node_t * nodep; + + binfo = &ap->info; + if(binfo->fc_flag & FC_ESTABLISH_LINK) + return; + + rp = &binfo->fc_ring[FC_FCP_RING]; + + /* ALUN */ + /* If the abort/bdr queue is not empty we deal with it first */ + for (dev_ptr = ap->ABORT_BDR_head; (dev_ptr != NULL); + dev_ptr = ap->ABORT_BDR_head) { + + if(dev_ptr->flags & CHK_SCSI_ABDR) { + rc = issue_abdr(ap, dev_ptr, rp, dev_ptr->lun_id); + if (rc != 0) { + break; + } + } + + fc_deq_abort_bdr(dev_ptr); + } + + requeue_ptr = NULL; + exit = 0; + + /* See if there is something on the waiting queue */ + while (((dev_ptr = ap->DEVICE_WAITING_head) != NULL) + && (binfo->fc_ffstate == FC_READY) + && (dev_ptr != requeue_ptr)) { + + nodep = dev_ptr->nodep; + /* Check if a target queue depth is set */ + if (nodep->rptlunstate == REPORT_LUN_ONGOING) { + requeue = 1; + } else if (nodep->tgt_queue_depth && + (nodep->tgt_queue_depth == nodep->num_active_io)) { + if (dev_ptr->nodep->last_dev == NULL) + dev_ptr->nodep->last_dev = dev_ptr; + requeue = 1; + } else if (dev_ptr->flags & (CHK_SCSI_ABDR | SCSI_TQ_HALTED)) { + requeue = 1; + } else { + requeue = 0; + + while ((sbp = dev_ptr->pend_head) != NULL) + { + if ((dev_ptr->active_io_count >= dev_ptr->fcp_cur_queue_depth) || + (dev_ptr->stop_send_io)) { + requeue = 1; + break; + } + if ((rc = issue_fcp_cmd(ap, dev_ptr, sbp, 1))) { + if (rc & FCP_REQUEUE) { + requeue = 1; + break; + } else if (rc & FCP_EXIT) { + exit = 1; + break; + } + continue; + } + dev_ptr->pend_count--; + dev_ptr->pend_head = (T_SCSIBUF *) sbp->bufstruct.av_forw; + if (dev_ptr->pend_head == NULL) + dev_ptr->pend_tail = NULL; + else + dev_ptr->pend_head->bufstruct.av_back = NULL; + + /* Check if a target queue depth is set */ + if (nodep->tgt_queue_depth && + (nodep->tgt_queue_depth == nodep->num_active_io)) { + /* requeue I/O if max cmds to tgt are outstanding */ + if (dev_ptr->nodep->last_dev == NULL) + dev_ptr->nodep->last_dev = dev_ptr; + requeue = 1; + break; + } + } /* while pend_head */ + } + if (exit) + break; + + fc_deq_wait(dev_ptr); + + if (requeue) { + if (requeue_ptr == NULL) + requeue_ptr = dev_ptr; + fc_enq_wait(dev_ptr); + } + + } /* while wait queue */ + + if (rp->fc_tx.q_cnt) { + issue_iocb_cmd(binfo, rp, 0); + /* [SYNC] */ + if (binfo->fc_flag & FC_POLL_MODE) { + fc_polling(binfo, HA_R2ATT); + } + } + + return; + +} /* End fc_issue_cmd */ + + +/**************************************************************************/ +/* */ +/* NAME: fc_enq_fcbuf_active, fc_enq_wait, fc_enq_fcbuf, fc_enq_abort_bdr */ +/* */ +/* FUNCTION: */ +/* Utility routines to handle queuing of device structures to each */ +/* of the queues in use. */ +/* */ +/* EXECUTION ENVIRONMENT: */ +/* */ +/* RETURN VALUE DESCRIPTION: none */ +/* */ +/* ERROR DESCRIPTION: The following errno values may be returned: */ +/* none */ +/* */ +/**************************************************************************/ +_static_ void +fc_enq_fcbuf_active( +RING *rp, /* Pointer to ring for fcbufs */ +fc_buf_t *fcptr) /* Pointer to fcbuf to enqueue */ +{ + FC_BRD_INFO * binfo; + fc_dev_ctl_t *p_dev_ctl; + + binfo = (FC_BRD_INFO * )(rp->fc_binfo); + p_dev_ctl = (fc_dev_ctl_t *)(binfo->fc_p_dev_ctl); + /* Sync the FCP_CMND payload data */ + /* Use correct offset and size for syncing */ + fc_mpdata_sync(fcptr->fc_cmd_dma_handle, (off_t)fcptr->offset, + sizeof(FCP_CMND), DDI_DMA_SYNC_FORDEV); + + /* Enqueue the fcbuf on the FCP ring active queue */ + if (rp->fc_txp.q_first) { + fcptr->fc_bkwd = (fc_buf_t * )rp->fc_txp.q_last; + ((fc_buf_t * )rp->fc_txp.q_last)->fc_fwd = fcptr; + rp->fc_txp.q_last = (uchar * )fcptr; + } else { + rp->fc_txp.q_first = (uchar * )fcptr; + rp->fc_txp.q_last = (uchar * )fcptr; + fcptr->fc_bkwd = NULL; + } + + fcptr->fc_fwd = NULL; + rp->fc_txp.q_cnt++; + if(rp->fc_txp.q_cnt > rp->fc_txp.q_max) { + rp->fc_txp.q_max = rp->fc_txp.q_cnt; + } + binfo->fc_table->fcp_array[fcptr->iotag] = fcptr; +} /* End fc_enq_fcbuf_active */ + + +/* + * Name: fc_enq_wait + * Function: Place dev_ptr on the adapter's wait queue. + * Input: dvi_t *dev_ptr dev_ptr to enqueue. + * Returns: nothing. + */ +_static_ void +fc_enq_wait( +dvi_t *dev_ptr) +{ + fc_dev_ctl_t * ap; + + ap = dev_ptr->nodep->ap; + + /* Queue the dev_ptr if it is not already on the queue */ + if ((dev_ptr->DEVICE_WAITING_fwd == NULL) + && (ap->DEVICE_WAITING_tail != dev_ptr)) { + + if (ap->DEVICE_WAITING_head == NULL) { + ap->DEVICE_WAITING_head = dev_ptr; + } else { + ap->DEVICE_WAITING_tail->DEVICE_WAITING_fwd = dev_ptr; + } + ap->DEVICE_WAITING_tail = dev_ptr; + } +} /* End fc_enq_wait */ + +/* ALUN */ +/* + * Name: fc_enq_fcbuf + * Function: Place fc_buf on the device's free queue. + * Input: fc_buf_t *fcptr fc_buf to enqueue + * Returns: nothing. + */ +_static_ void +fc_enq_fcbuf( +fc_buf_t *fcptr) +{ + dvi_t * dev_ptr; + + dev_ptr = fcptr->dev_ptr; + + if (dev_ptr->fcbuf_head == NULL) { + dev_ptr->fcbuf_head = fcptr; + } else { + dev_ptr->fcbuf_tail->fc_fwd = fcptr; + } + fcptr->fc_fwd = NULL; + dev_ptr->fcbuf_tail = fcptr; + dev_ptr->numfcbufs++; + + if (dev_ptr->numfcbufs == dev_ptr->fcp_lun_queue_depth) { + if (dev_ptr->flags & SCSI_TQ_CLEARING) { + /* Call iodone for all the CLEARQ error bufs */ + fc_free_clearq(dev_ptr); + } + if (dev_ptr->queue_state == STOPPING) { + /* If we are trying to close, check to see if all done */ + } + } + + return; +} /* End fc_enq_fcbuf */ + + +/* + * Name: fc_enq_abort_bdr + * Function: Place dev_ptr on the adapter's Bus Device Reset queue. + * Input: dvi_t *dev_ptr dev_ptr to enqueue. + * Returns: nothing. + */ +_static_ void +fc_enq_abort_bdr( + dvi_t * dev_ptr) +{ + fc_dev_ctl_t * ap; + + ap = dev_ptr->nodep->ap; + + if (ap->ABORT_BDR_head == NULL) { + dev_ptr->ABORT_BDR_fwd = NULL; + dev_ptr->ABORT_BDR_bkwd = NULL; + ap->ABORT_BDR_head = dev_ptr; + ap->ABORT_BDR_tail = dev_ptr; + } else { + dev_ptr->ABORT_BDR_bkwd = ap->ABORT_BDR_tail; + dev_ptr->ABORT_BDR_fwd = NULL; + ap->ABORT_BDR_tail->ABORT_BDR_fwd = dev_ptr; + ap->ABORT_BDR_tail = dev_ptr; + } +} /* End fc_enq_abort_bdr */ + + +/**************************************************************************/ +/* */ +/* NAME: fc_deq_fcbuf_active, fc_deq_wait, fc_deq_fcbuf, fc_deq_abort_bdr */ +/* */ +/* FUNCTION: */ +/* Utility routines to handle dequeueing device structures from */ +/* each of the queues in use. */ +/* */ +/* EXECUTION ENVIRONMENT: */ +/* */ +/* ERROR DESCRIPTION: The following errno values may be returned: */ +/* none */ +/* */ +/**************************************************************************/ +_static_ fc_buf_t * +fc_deq_fcbuf_active( + RING * rp, + ushort iotag) /* tag to match I/O */ +{ + FC_BRD_INFO * binfo; + fc_dev_ctl_t * p_dev_ctl; + fc_buf_t * fcptr = NULL; + + binfo = (FC_BRD_INFO * )(rp->fc_binfo); + p_dev_ctl = (fc_dev_ctl_t *)(binfo->fc_p_dev_ctl); + /* Remove an fcbuf from the FCP ring active queue based on iotag */ + + if ((iotag < MAX_FCP_CMDS) && + (fcptr = binfo->fc_table->fcp_array[iotag])) { + + /* Remove fcbuf from list, adjust first, last and cnt */ + if (fcptr->fc_bkwd) { + fcptr->fc_bkwd->fc_fwd = fcptr->fc_fwd; + } else { + rp->fc_txp.q_first = (uchar * )fcptr->fc_fwd; + } + + if (fcptr->fc_fwd) { + fcptr->fc_fwd->fc_bkwd = fcptr->fc_bkwd; + } else { + rp->fc_txp.q_last = (uchar * )fcptr->fc_bkwd; + } + + rp->fc_txp.q_cnt--; + binfo->fc_table->fcp_array[iotag] = NULL; + } + + if (fcptr) { + if (binfo->fc_flag & FC_SLI2) { + MATCHMAP * next_bmp; + + while(fcptr->bmp) { + next_bmp = (MATCHMAP *)fcptr->bmp->fc_mptr; + fc_mem_put(binfo, MEM_BPL, (uchar *)fcptr->bmp); + fcptr->bmp = next_bmp; + } + } + fcptr->bmp = 0; + + /* Use correct offset and size for syncing */ + fc_mpdata_sync(fcptr->fc_cmd_dma_handle, + (off_t)(fcptr->offset + sizeof(FCP_CMND)), + (u_int) sizeof(FCP_RSP), DDI_DMA_SYNC_FORCPU); + + } + return(fcptr); +} /* End fc_deq_fcbuf_active */ + + +/* + * Name: fc_deq_wait + * Function: Remove a dev_ptr from the adapter's wait queue. + * Input: dvi_t *dev_ptr dev_ptr to be dequeued. + * Returns: nothing. + */ +_local_ void +fc_deq_wait( + dvi_t * dev_ptr) +{ + fc_dev_ctl_t * ap; + dvi_t *prev_ptr; + + if(dev_ptr == NULL) { + return; + } + ap = dev_ptr->nodep->ap; + if(ap->DEVICE_WAITING_head == NULL) { + return; + } + + if(dev_ptr != ap->DEVICE_WAITING_head) { + prev_ptr = ap->DEVICE_WAITING_head; + while(prev_ptr->DEVICE_WAITING_fwd != dev_ptr && + prev_ptr != ap->DEVICE_WAITING_tail) + { + prev_ptr=prev_ptr->DEVICE_WAITING_fwd; + } + if(prev_ptr->DEVICE_WAITING_fwd == dev_ptr) { + prev_ptr->DEVICE_WAITING_fwd = dev_ptr->DEVICE_WAITING_fwd; + if(ap->DEVICE_WAITING_tail == dev_ptr) { + ap->DEVICE_WAITING_tail = prev_ptr; + } + dev_ptr->DEVICE_WAITING_fwd = NULL; + } + return; + } + if (ap->DEVICE_WAITING_head == ap->DEVICE_WAITING_tail) { + ap->DEVICE_WAITING_head = NULL; + ap->DEVICE_WAITING_tail = NULL; + } else { + ap->DEVICE_WAITING_head = dev_ptr->DEVICE_WAITING_fwd; + } + dev_ptr->DEVICE_WAITING_fwd = NULL; + +} /* End fc_deq_wait */ + + +/* + * Name: fc_deq_fcbuf + * Function: Remove an fc_buf from the device's free queue. + * Input: dvi_t *dev_ptr dev_ptr with the free list. + * Returns: pointer to the fc_buf, or NULL if none exist. + */ +_static_ fc_buf_t * +fc_deq_fcbuf( + dvi_t * dev_ptr) +{ + fc_buf_t * fcptr; + + if (dev_ptr->fcbuf_head == NULL) + return(NULL); + + fcptr = dev_ptr->fcbuf_head; + if (dev_ptr->fcbuf_head == dev_ptr->fcbuf_tail) { + dev_ptr->fcbuf_head = NULL; + dev_ptr->fcbuf_tail = NULL; + } else { + dev_ptr->fcbuf_head = fcptr->fc_fwd; + } + dev_ptr->numfcbufs--; + + return(fcptr); + +} /* End fc_deq_fcbuf */ + + +/* + * Name: fc_deq_abort_bdr + * Function: Removes a dev_ptr from the adapter's abort Bus Device Reset + * queue. + * Input: dvi_t *dev_ptr dev_ptr to be removed. + * Returns: nothing. + */ +_local_ void +fc_deq_abort_bdr( +dvi_t *dev_ptr) +{ + fc_dev_ctl_t * ap; + + ap = dev_ptr->nodep->ap; + + if (ap->ABORT_BDR_head == ap->ABORT_BDR_tail) { + ap->ABORT_BDR_head = NULL; + ap->ABORT_BDR_tail = NULL; + } else if (ap->ABORT_BDR_head == dev_ptr) { + /* first one */ + ap->ABORT_BDR_head = dev_ptr->ABORT_BDR_fwd; + dev_ptr->ABORT_BDR_fwd->ABORT_BDR_bkwd = dev_ptr->ABORT_BDR_bkwd; + } else if (ap->ABORT_BDR_tail == dev_ptr) { + /* last one */ + ap->ABORT_BDR_tail = dev_ptr->ABORT_BDR_bkwd; + dev_ptr->ABORT_BDR_bkwd->ABORT_BDR_fwd = dev_ptr->ABORT_BDR_fwd; + } else { + /* in the middle */ + dev_ptr->ABORT_BDR_bkwd->ABORT_BDR_fwd = dev_ptr->ABORT_BDR_fwd; + dev_ptr->ABORT_BDR_fwd->ABORT_BDR_bkwd = dev_ptr->ABORT_BDR_bkwd; + } + dev_ptr->ABORT_BDR_fwd = NULL; + dev_ptr->ABORT_BDR_bkwd = NULL; + +} /* End fc_deq_abort_bdr */ + + +/* Assign a SCSI ID to a nodelist table entry */ +_static_ int +fc_assign_scsid( +fc_dev_ctl_t *p_dev_ctl, +NODELIST *ndlp) +{ + FC_BRD_INFO * binfo; + iCfgParam * clp; + node_t * node_ptr; + nodeh_t * hp; + NODELIST * seedndlp; + NODELIST * new_ndlp; + int dev_index, i; + + binfo = &BINFO; + clp = DD_CTL.p_config[binfo->fc_brd_no]; + /* Next check to see if our binding already has a SCSI ID */ + for (dev_index = 0; dev_index < MAX_FC_TARGETS; dev_index++) { + hp = &binfo->device_queue_hash[dev_index]; + i = (hp->node_flag & FCP_SEED_MASK); + if ((i & FCP_SEED_DID) && (ndlp->nlp_DID == hp->un.dev_did)) + break; /* a match */ + else if ((i & FCP_SEED_WWPN) && + (fc_geportname(&ndlp->nlp_portname, &hp->un.dev_portname) == 2)) + break; /* a match */ + else if ((i & FCP_SEED_WWNN) && + (fc_geportname(&ndlp->nlp_nodename, &hp->un.dev_nodename) == 2)) + break; /* a match */ + } + + /* If not, assign a new SCSI ID / pan number */ + if (dev_index == MAX_FC_TARGETS) { + seedndlp = binfo->fc_nlpbind_start; + if(seedndlp == (NODELIST *)&binfo->fc_nlpbind_start) + seedndlp = binfo->fc_nlpunmap_start; + if(seedndlp == (NODELIST *)&binfo->fc_nlpunmap_start) + seedndlp = binfo->fc_nlpmap_start; + while(seedndlp != (NODELIST *)&binfo->fc_nlpmap_start) { + new_ndlp = (NODELIST *)seedndlp->nlp_listp_next; + + if (seedndlp->nlp_type & NLP_SEED_MASK) { + if (seedndlp->nlp_type & NLP_SEED_WWNN) { + if (fc_geportname(&ndlp->nlp_nodename, + &seedndlp->nlp_nodename) == 2) { + ndlp->id.nlp_pan = seedndlp->id.nlp_pan; + ndlp->id.nlp_sid = seedndlp->id.nlp_sid; + ndlp->nlp_type |= NLP_SEED_WWNN; + if(seedndlp != ndlp) { + seedndlp->nlp_type &= ~NLP_FCP_TARGET; + fc_freenode(binfo, seedndlp, 0); + seedndlp->nlp_state = NLP_LIMBO; + fc_nlp_bind(binfo, seedndlp); + } + dev_index = INDEX(ndlp->id.nlp_pan, ndlp->id.nlp_sid); + hp = &binfo->device_queue_hash[dev_index]; + + /* Claim SCSI ID by copying bind parameter to + * proper index in device_queue_hash. + */ + if(hp->node_ptr) + ndlp->nlp_targetp = (uchar *)hp->node_ptr; + fc_bcopy(&ndlp->nlp_nodename, &hp->un.dev_nodename, + sizeof(NAME_TYPE)); + hp->node_flag &= ~FCP_SEED_MASK; + hp->node_flag |= FCP_SEED_WWNN; + goto out1; + } + } + if (seedndlp->nlp_type & NLP_SEED_WWPN) { + if (fc_geportname(&ndlp->nlp_portname, + &seedndlp->nlp_portname) == 2) { + ndlp->id.nlp_pan = seedndlp->id.nlp_pan; + ndlp->id.nlp_sid = seedndlp->id.nlp_sid; + ndlp->nlp_type |= NLP_SEED_WWPN; + if(seedndlp != ndlp) { + seedndlp->nlp_type &= ~NLP_FCP_TARGET; + fc_freenode(binfo, seedndlp, 0); + seedndlp->nlp_state = NLP_LIMBO; + fc_nlp_bind(binfo, seedndlp); + } + dev_index = INDEX(ndlp->id.nlp_pan, ndlp->id.nlp_sid); + hp = &binfo->device_queue_hash[dev_index]; + + /* Claim SCSI ID by copying bind parameter to + * proper index in device_queue_hash. + */ + if(hp->node_ptr) + ndlp->nlp_targetp = (uchar *)hp->node_ptr; + fc_bcopy(&ndlp->nlp_portname, &hp->un.dev_portname, + sizeof(NAME_TYPE)); + hp->node_flag &= ~FCP_SEED_MASK; + hp->node_flag |= FCP_SEED_WWPN; + goto out1; + } + } + if (seedndlp->nlp_type & NLP_SEED_DID) { + if (ndlp->nlp_DID == seedndlp->nlp_DID) { + ndlp->id.nlp_pan = seedndlp->id.nlp_pan; + ndlp->id.nlp_sid = seedndlp->id.nlp_sid; + ndlp->nlp_type |= NLP_SEED_DID; + if(seedndlp != ndlp) { + seedndlp->nlp_type &= ~NLP_FCP_TARGET; + fc_freenode(binfo, seedndlp, 0); + seedndlp->nlp_state = NLP_LIMBO; + fc_nlp_bind(binfo, seedndlp); + } + dev_index = INDEX(ndlp->id.nlp_pan, ndlp->id.nlp_sid); + hp = &binfo->device_queue_hash[dev_index]; + + /* Claim SCSI ID by copying bind parameter to + * proper index in device_queue_hash. + */ + if(hp->node_ptr) + ndlp->nlp_targetp = (uchar *)hp->node_ptr; + hp->un.dev_did = ndlp->nlp_DID; + hp->node_flag &= ~FCP_SEED_MASK; + hp->node_flag |= FCP_SEED_DID; + goto out1; + } + } + } + seedndlp = new_ndlp; + if(seedndlp == (NODELIST *)&binfo->fc_nlpbind_start) + seedndlp = binfo->fc_nlpunmap_start; + if(seedndlp == (NODELIST *)&binfo->fc_nlpunmap_start) + seedndlp = binfo->fc_nlpmap_start; + } + + if(clp[CFG_AUTOMAP].a_current) { + /* Fill in nodelist entry */ + if (DEV_PAN(p_dev_ctl->sid_cnt) == NLP_MAXPAN) { + return(0); /* No more available SCSI IDs */ + } + + /* If scan-down == 2 and we are private loop, automap + * method is based on ALPA. + */ + if((clp[CFG_SCAN_DOWN].a_current == 2) && + !(binfo->fc_flag & (FC_PUBLIC_LOOP | FC_FABRIC)) && + (binfo->fc_topology == TOPOLOGY_LOOP)) { + for (i = 0; i < FC_MAXLOOP; i++) { + if(ndlp->nlp_DID == (uint32)AlpaArray[i]) + break; + } + if(i == FC_MAXLOOP) { + goto jmp_auto; + } + ndlp->id.nlp_pan = DEV_PAN(i); + ndlp->id.nlp_sid = DEV_SID(i); + } + else { + /* Check to make sure assigned scsi id does not overlap + * with a seeded value. + */ +jmp_auto: + seedndlp = binfo->fc_nlpbind_start; + if(seedndlp == (NODELIST *)&binfo->fc_nlpbind_start) + seedndlp = binfo->fc_nlpunmap_start; + if(seedndlp == (NODELIST *)&binfo->fc_nlpunmap_start) + seedndlp = binfo->fc_nlpmap_start; + while(seedndlp != (NODELIST *)&binfo->fc_nlpmap_start) { + if ((seedndlp->nlp_state == NLP_SEED) || + (seedndlp->nlp_type & NLP_SEED_MASK)) { + if ((seedndlp->id.nlp_pan == DEV_PAN(p_dev_ctl->sid_cnt)) && + (seedndlp->id.nlp_sid == DEV_SID(p_dev_ctl->sid_cnt))) { + /* We overlap, so pick a new id and start again */ + p_dev_ctl->sid_cnt++; + goto jmp_auto; + } + } + seedndlp = (NODELIST *)seedndlp->nlp_listp_next; + if(seedndlp == (NODELIST *)&binfo->fc_nlpbind_start) + seedndlp = binfo->fc_nlpunmap_start; + if(seedndlp == (NODELIST *)&binfo->fc_nlpunmap_start) + seedndlp = binfo->fc_nlpmap_start; + } + + ndlp->id.nlp_pan = DEV_PAN(p_dev_ctl->sid_cnt); + ndlp->id.nlp_sid = DEV_SID(p_dev_ctl->sid_cnt); + p_dev_ctl->sid_cnt++; + } + ndlp->nlp_type |= NLP_AUTOMAP; + + dev_index = INDEX(ndlp->id.nlp_pan, ndlp->id.nlp_sid); + hp = &binfo->device_queue_hash[dev_index]; + + /* Claim SCSI ID by copying bind parameter to + * proper index in device_queue_hash. + */ + if(hp->node_ptr) + ndlp->nlp_targetp = (uchar *)hp->node_ptr; + switch(p_dev_ctl->fcp_mapping) { + case FCP_SEED_DID: + hp->un.dev_did = ndlp->nlp_DID; + ndlp->nlp_type |= NLP_SEED_DID; + break; + case FCP_SEED_WWPN: + fc_bcopy(&ndlp->nlp_portname, &hp->un.dev_portname, sizeof(NAME_TYPE)); + ndlp->nlp_type |= NLP_SEED_WWPN; + break; + case FCP_SEED_WWNN: + default: + fc_bcopy(&ndlp->nlp_nodename, &hp->un.dev_nodename, sizeof(NAME_TYPE)); + ndlp->nlp_type |= NLP_SEED_WWNN; + break; + } + hp->node_flag &= ~FCP_SEED_MASK; + hp->node_flag |= p_dev_ctl->fcp_mapping; + goto out1; + } + return(0); /* Cannot assign a scsi id */ + } + + /* If scan-down == 2 and we are private loop, automap + * method is based on ALPA. + */ + if((clp[CFG_SCAN_DOWN].a_current == 2) && + !(binfo->fc_flag & (FC_PUBLIC_LOOP | FC_FABRIC)) && + (binfo->fc_topology == TOPOLOGY_LOOP)) { + for (i = 0; i < FC_MAXLOOP; i++) { + if(ndlp->nlp_DID == (uint32)AlpaArray[i]) + break; + } + if(i == FC_MAXLOOP) { + goto jmp_auto; + } + ndlp->id.nlp_pan = DEV_PAN(i); + ndlp->id.nlp_sid = DEV_SID(i); + goto out1; + } + /* Copy SCSI ID for the WWN into nodelist */ + ndlp->id.nlp_pan = DEV_PAN(dev_index); + ndlp->id.nlp_sid = DEV_SID(dev_index); + + /* Update rpi for that SCSI ID's device node info */ + if ((node_ptr = (node_t * )ndlp->nlp_targetp) != NULL) { + node_ptr->rpi = ndlp->nlp_Rpi; + node_ptr->last_good_rpi = ndlp->nlp_Rpi; + node_ptr->nlp = ndlp; + node_ptr->flags &= ~FC_NODEV_TMO; + ndlp->nlp_flag &= ~NLP_NODEV_TMO; + if(node_ptr->nodev_tmr) { + /* STOP nodev timer */ + fc_log_printf_msg_vargs( binfo->fc_brd_no, + &fc_msgBlk0704, /* ptr to msg structure */ + fc_mes0704, /* ptr to msg */ + fc_msgBlk0704.msgPreambleStr, /* begin varargs */ + (ulong)ndlp, + ndlp->nlp_flag, + ndlp->nlp_state, + ndlp->nlp_DID); /* end varargs */ + fc_clk_can(p_dev_ctl, node_ptr->nodev_tmr); + node_ptr->nodev_tmr = 0; + } + } + else { + int dev_index; +out1: + dev_index = INDEX(ndlp->id.nlp_pan, ndlp->id.nlp_sid); + node_ptr = binfo->device_queue_hash[dev_index].node_ptr; + if(node_ptr) { + /* This is a new device that entered the loop */ + node_ptr->nlp = ndlp; + node_ptr->rpi = ndlp->nlp_Rpi; + node_ptr->last_good_rpi = ndlp->nlp_Rpi; + node_ptr->scsi_id = dev_index; + ndlp->nlp_targetp = (uchar *)node_ptr; + node_ptr->flags &= ~FC_NODEV_TMO; + ndlp->nlp_flag &= ~NLP_NODEV_TMO; + if(node_ptr->nodev_tmr) { + /* STOP nodev timer */ + fc_log_printf_msg_vargs( binfo->fc_brd_no, + &fc_msgBlk0705, /* ptr to msg structure */ + fc_mes0705, /* ptr to msg */ + fc_msgBlk0705.msgPreambleStr, /* begin varargs */ + (ulong)ndlp, + ndlp->nlp_flag, + ndlp->nlp_state, + ndlp->nlp_DID); /* end varargs */ + fc_clk_can(p_dev_ctl, node_ptr->nodev_tmr); + node_ptr->nodev_tmr = 0; + } + } + } + return(1); +} /* End fc_assign_scsid */ + + +/************************************************************************/ +/* */ +/* NAME: fc_fail_cmd */ +/* */ +/* FUNCTION: Fail All Pending Commands Routine */ +/* */ +/* This routine is called to clear out all pending commands */ +/* for a SCSI FCP device. */ +/* */ +/* EXECUTION ENVIRONMENT: */ +/* This routine can only be called on priority levels */ +/* equal to that of the interrupt handler. */ +/* */ +/* DATA STRUCTURES: */ +/* sc_buf - input/output request struct used between the adapter */ +/* driver and the calling SCSI device driver */ +/* */ +/* INPUTS: */ +/* dev_info structure - pointer to device information structure */ +/* */ +/* RETURN VALUE DESCRIPTION: The following are the return values: */ +/* none */ +/* */ +/************************************************************************/ +_static_ void +fc_fail_cmd( + dvi_t * dev_ptr, + char error, + uint32 statistic) +{ + T_SCSIBUF * sbp; + RING * rp; + IOCBQ * iocb_cmd, *next; + IOCB * icmd; + Q tmpq; + fc_buf_t * fcptr; + struct buf * bp; + dvi_t * next_dev_ptr; + fc_dev_ctl_t * p_dev_ctl; + FC_BRD_INFO * binfo; + iCfgParam * clp; + + p_dev_ctl = dev_ptr->nodep->ap; + binfo = &BINFO; + rp = &binfo->fc_ring[FC_FCP_RING]; + clp = DD_CTL.p_config[binfo->fc_brd_no]; + /* First clear out all sc_buf structures in the pending queue */ + if(! clp[CFG_HOLDIO].a_current) { + if((dev_ptr->nodep) && + (dev_ptr->nodep->rptlunstate == REPORT_LUN_ONGOING)) + goto out; + sbp = dev_ptr->pend_head; + dev_ptr->pend_head = NULL; /* reset tail pointer */ + dev_ptr->pend_tail = NULL; /* reset tail pointer */ + dev_ptr->pend_count = 0; + + while (sbp != NULL) { + T_SCSIBUF *nextsbp; + + sbp->bufstruct.b_flags |= B_ERROR; /* set b_flags B_ERROR flag */ + sbp->bufstruct.b_error = error; + sbp->bufstruct.b_resid = sbp->bufstruct.b_bcount; + if (error) { + sbp->status_validity = SC_ADAPTER_ERROR; + SET_ADAPTER_STATUS(sbp,SC_NO_DEVICE_RESPONSE) + } else { + sbp->status_validity = 0; + } + + /* Point to next sc_buf in pending chain, if any */ + nextsbp = (T_SCSIBUF *) sbp->bufstruct.av_forw; + sbp->bufstruct.av_forw = 0; + fc_do_iodone((struct buf *) sbp); /* This could reque to pend_head */ + sbp = nextsbp; + } + } + +out: + /* Next clear out all fc_buf structures in the iocb queue for this device */ + tmpq.q_first = NULL; + + /* Get next command from ring xmit queue */ + iocb_cmd = fc_ringtx_get(rp); + + while (iocb_cmd) { + icmd = &iocb_cmd->iocb; + if ((icmd->ulpCommand != CMD_IOCB_CONTINUE_CN) && + (icmd->ulpContext == dev_ptr->nodep->last_good_rpi) && + (icmd->ulpIoTag < MAX_FCP_CMDS) && + (fcptr = binfo->fc_table->fcp_array[icmd->ulpIoTag]) && + (fcptr->dev_ptr == dev_ptr)) { + + if ((fcptr = fc_deq_fcbuf_active(rp, icmd->ulpIoTag)) != NULL) { + bp = (struct buf *)fcptr->sc_bufp; + + /* Reject this command with error */ + if (fcptr->fcp_cmd.fcpCntl2) { + + /* This is a task management command */ + dev_ptr->ioctl_errno = error; + if (fcptr->fcp_cmd.fcpCntl2 == ABORT_TASK_SET) + dev_ptr->flags &= ~SCSI_ABORT_TSET; + + if (fcptr->fcp_cmd.fcpCntl2 & TARGET_RESET) { + dev_ptr->flags &= ~SCSI_TARGET_RESET; + for (next_dev_ptr = dev_ptr->nodep->lunlist; + next_dev_ptr != NULL; next_dev_ptr = next_dev_ptr->next) { + next_dev_ptr->flags &= ~SCSI_TARGET_RESET; + } + } + + if (fcptr->fcp_cmd.fcpCntl2 & LUN_RESET) + dev_ptr->flags &= ~SCSI_LUN_RESET; + + if (dev_ptr->ioctl_wakeup == 1) { + dev_ptr->ioctl_wakeup = 0; + + fc_admin_wakeup(p_dev_ctl, dev_ptr, fcptr->sc_bufp); + } + else { + fc_do_iodone(bp); + } + + dev_ptr->active_io_count--; + dev_ptr->nodep->num_active_io--; + + } else { + /* This is a regular FCP command */ + bp->b_error = error; + bp->b_resid = bp->b_bcount; + bp->b_flags |= B_ERROR; + if (error) { + sbp = fcptr->sc_bufp; + sbp->status_validity = SC_ADAPTER_ERROR; + SET_ADAPTER_STATUS(sbp,SC_NO_DEVICE_RESPONSE) + } + + sbp = fcptr->sc_bufp; + + dev_ptr->active_io_count--; + dev_ptr->nodep->num_active_io--; + fc_do_iodone(bp); + } + fc_enq_fcbuf(fcptr); + } + + fc_mem_put(binfo, MEM_IOCB, (uchar * )iocb_cmd); + + while ((iocb_cmd = fc_ringtx_get(rp)) != NULL) { + icmd = &iocb_cmd->iocb; + if (icmd->ulpCommand != CMD_IOCB_CONTINUE_CN) + break; + fc_mem_put(binfo, MEM_IOCB, (uchar * )iocb_cmd); + } + } else { + /* Queue this iocb to the temporary queue */ + if (tmpq.q_first) { + ((IOCBQ * )tmpq.q_last)->q = (uchar * )iocb_cmd; + tmpq.q_last = (uchar * )iocb_cmd; + } else { + tmpq.q_first = (uchar * )iocb_cmd; + tmpq.q_last = (uchar * )iocb_cmd; + } + iocb_cmd->q = NULL; + + iocb_cmd = fc_ringtx_get(rp); + } + } + + /* Put the temporary queue back in the FCP iocb queue */ + iocb_cmd = (IOCBQ * )tmpq.q_first; + while (iocb_cmd) { + next = (IOCBQ * )iocb_cmd->q; + fc_ringtx_put(rp, iocb_cmd); + iocb_cmd = next; + } + + return; +} /* End fc_fail_cmd */ + +/* Fix up any changed RPIs in FCP IOCBs queued up a txq + * Called from CLEAR_LA after a link up. + */ +_static_ void +fc_fcp_fix_txq( + fc_dev_ctl_t * p_dev_ctl) +{ + RING * rp; + FC_BRD_INFO * binfo; + fc_buf_t * fcptr; + IOCBQ * temp; + IOCB * cmd; + dvi_t * dev_ptr; + unsigned long iflag; + + iflag = lpfc_q_disable_lock(p_dev_ctl); + binfo = &BINFO; + rp = &binfo->fc_ring[FC_FCP_RING]; + + /* Make sure all RPIs on txq are still ok */ + temp = (IOCBQ *)rp->fc_tx.q_first; + while (temp != NULL) { + cmd = &temp->iocb; + if ((fcptr = binfo->fc_table->fcp_array[cmd->ulpIoTag]) != NULL) { + dev_ptr = fcptr->dev_ptr; + if((dev_ptr) && (dev_ptr->nodep) && + (cmd->ulpContext != dev_ptr->nodep->rpi)) { + cmd->ulpContext = dev_ptr->nodep->rpi; + } + } + if(rp->fc_tx.q_last == (uchar * )temp) + break; + temp = (IOCBQ *)temp->q; + } + lpfc_q_unlock_enable(p_dev_ctl, iflag); + return; +} /* End fc_fcp_fix_txq */ + +_static_ void +fc_fail_pendq( + dvi_t * dev_ptr, + char error, + uint32 statistic) +{ + T_SCSIBUF * sbp; + RING * rp; + fc_dev_ctl_t * p_dev_ctl; + FC_BRD_INFO * binfo; + iCfgParam * clp; + + p_dev_ctl = dev_ptr->nodep->ap; + binfo = &BINFO; + clp = DD_CTL.p_config[binfo->fc_brd_no]; + rp = &binfo->fc_ring[FC_FCP_RING]; + + if((dev_ptr->nodep) && + (dev_ptr->nodep->rptlunstate == REPORT_LUN_ONGOING)) + goto out; + + if(clp[CFG_HOLDIO].a_current) + goto out; + + sbp = dev_ptr->pend_head; + dev_ptr->pend_head = NULL; /* reset tail pointer */ + dev_ptr->pend_tail = NULL; /* reset tail pointer */ + dev_ptr->pend_count = 0; + + while (sbp != NULL) { + T_SCSIBUF *nextsbp; + + sbp->bufstruct.b_flags |= B_ERROR; /* set b_flags B_ERROR flag */ + sbp->bufstruct.b_error = error; + sbp->bufstruct.b_resid = sbp->bufstruct.b_bcount; + if (error) { + sbp->status_validity = SC_ADAPTER_ERROR; + SET_ADAPTER_STATUS(sbp,SC_NO_DEVICE_RESPONSE) + } else { + sbp->status_validity = 0; + } + + /* Point to next sc_buf in pending chain, if any */ + nextsbp = (T_SCSIBUF *) sbp->bufstruct.av_forw; + sbp->bufstruct.av_forw = 0; + fc_do_iodone((struct buf *) sbp); /* This could reque to pend_head */ + sbp = nextsbp; + } + +out: + return; +} /* End fc_fail_pendq */ + +/************************************************************************/ +/* */ +/* NAME:issue_fcp_cmd */ +/* */ +/* FUNCTION:Issue an FCP command to the adapter iocb queue */ +/* */ +/* EXECUTION ENVIRONMENT: */ +/* This routine always runs at interrupt level */ +/* */ +/* DATA STRUCTURES: */ +/* sc_buf- input/output request struct used between the adapter */ +/* driver and the calling SCSI device driver */ +/* */ +/* RETURN VALUE DESCRIPTION: 0 = success */ +/* 1 = continue */ +/* 2 = requeue */ +/* 4 = exit */ +/* */ +/************************************************************************/ +_static_ int +issue_fcp_cmd( + fc_dev_ctl_t * p_dev_ctl, + dvi_t * dev_ptr, + T_SCSIBUF * sbp, + int pend) +{ + FC_BRD_INFO * binfo = &BINFO; + iCfgParam * clp; + struct buf * bp; + fc_buf_t * fcptr; + int i, rc; + RING * rp; + IOCBQ * temp; + IOCB * cmd; + uint32 count, * lp; + fc_lun_t lun; + ULP_BDE64 * bpl; + MATCHMAP * bmp; + NODELIST * ndlp; + + rp = &binfo->fc_ring[FC_FCP_RING]; + bp = (struct buf *) sbp; + clp = DD_CTL.p_config[binfo->fc_brd_no]; + + if((dev_ptr->nodep == 0) || + ((ndlp = dev_ptr->nodep->nlp) == 0)) + return(FCP_REQUEUE); + + if ( !(ndlp->capabilities & FC_CAP_AUTOSENSE) ) { + if (dev_ptr->sense_valid && + (sbp->scsi_command.scsi_cmd.scsi_op_code == SCSI_REQUEST_SENSE)) { + + /* Request sense command - use saved sense data */ + if (bp->b_bcount > (int)dev_ptr->sense_length) { + bp->b_resid = bp->b_bcount - (int)dev_ptr->sense_length; + count = dev_ptr->sense_length; + } else { + count = bp->b_bcount; + } + lp = (uint32 * )dev_ptr->sense; + lpfc_copy_sense(dev_ptr, bp); + bp->b_error = 0; + bp->b_flags &= ~B_ERROR; + + if (pend) { + dev_ptr->pend_head = (T_SCSIBUF *) bp->av_forw; + if (dev_ptr->pend_head == NULL) + dev_ptr->pend_tail = NULL; + else + dev_ptr->pend_head->bufstruct.av_back = NULL; + dev_ptr->pend_count--; + } + dev_ptr->sense_valid = 0; + + FCSTATCTR.fcpSense++; + fc_do_iodone(bp); + return(FCP_CONTINUE); + } + } + + + if(dev_ptr->queue_state != ACTIVE) { + return(FCP_REQUEUE); + } + + if(binfo->fc_process_LA == 0) { + return(FCP_REQUEUE); + } + + /* Check if device is in process of resetting */ + if (dev_ptr->flags & SCSI_DEV_RESET) { + return(FCP_REQUEUE); + } + + if (dev_ptr->nodep->rpi == 0xFFFE) { + + if(clp[CFG_HOLDIO].a_current) { + return(FCP_REQUEUE); + } + + if((clp[CFG_NODEV_TMO].a_current) && + ((dev_ptr->nodep->flags & FC_NODEV_TMO) == 0)) { + + /* Kick off first PLOGI to device */ + if (!(ndlp->nlp_flag & NLP_REQ_SND)) { + uint32 did; + + did = ndlp->nlp_DID; + if(did == (uint32)0) { + if((ndlp->nlp_type & (NLP_AUTOMAP | NLP_SEED_MASK)) && + (ndlp->nlp_state == NLP_LIMBO) && ndlp->nlp_oldDID) + did = ndlp->nlp_oldDID; + } + ndlp->nlp_flag &= ~NLP_RM_ENTRY; + if ((!(ndlp->nlp_flag & NLP_NODEV_TMO)) && + (did != (uint32)0)) { + if(!(ndlp->nlp_flag & NLP_NS_REMOVED)) { + ndlp->nlp_flag |= NLP_NODEV_TMO; + fc_els_cmd(binfo, ELS_CMD_PLOGI, (void *)((ulong)did), + (uint32)0, (ushort)0, ndlp); + } + } + } + else { + ndlp->nlp_flag |= NLP_NODEV_TMO; + } + return(FCP_REQUEUE); + } + + /* The device is not active at this time */ + bp->b_error = EIO; + bp->b_resid = bp->b_bcount; + bp->b_flags |= B_ERROR; + sbp->status_validity = SC_ADAPTER_ERROR; + SET_ADAPTER_STATUS(sbp,SC_NO_DEVICE_RESPONSE) + if (pend) { + dev_ptr->pend_head = (T_SCSIBUF *) bp->av_forw; + if (dev_ptr->pend_head == NULL) + dev_ptr->pend_tail = NULL; + else + dev_ptr->pend_head->bufstruct.av_back = NULL; + dev_ptr->pend_count--; + } + + FCSTATCTR.fcpNoDevice++; + fc_delay_iodone(p_dev_ctl, sbp); + + { + uint32 did; + uint32 pan; + uint32 sid; + + did = ndlp->nlp_DID; + pan = ndlp->id.nlp_pan; + sid = ndlp->id.nlp_sid; + + if (!(dev_ptr->flags & DONT_LOG_INVALID_RPI)) { + /* Cannot issue FCP command */ + fc_log_printf_msg_vargs( binfo->fc_brd_no, + &fc_msgBlk0706, /* ptr to msg structure */ + fc_mes0706, /* ptr to msg */ + fc_msgBlk0706.msgPreambleStr, /* begin varargs */ + did, + FC_SCSID(pan, sid)); /* end varargs */ + dev_ptr->flags |= DONT_LOG_INVALID_RPI; + } + } + return(FCP_CONTINUE); + } + + if (ndlp->nlp_action & NLP_DO_RSCN) { + return(FCP_REQUEUE); + } + + if ((fcptr = fc_deq_fcbuf(dev_ptr)) == NULL) { + return(FCP_REQUEUE); + } + + if ((temp = (IOCBQ * )fc_mem_get(binfo, MEM_IOCB)) == NULL) { + fc_enq_fcbuf(fcptr); + return(FCP_EXIT); + } + + fc_bzero((void *)fcptr, sizeof(FCP_CMND) + sizeof(FCP_RSP)); + + /* Copy SCSI cmd into FCP payload for xmit.*/ + lun = (uint32) sbp->scsi_command.scsi_lun; + { + int i; + fcptr->fcp_cmd.fcpCdb[0]= sbp->scsi_command.scsi_cmd.scsi_op_code; + fcptr->fcp_cmd.fcpCdb[1]= sbp->scsi_command.scsi_cmd.lun; + for(i=0; i< (sizeof(struct sc_cmd)-2); i++) + fcptr->fcp_cmd.fcpCdb[i+2]= sbp->scsi_command.scsi_cmd.scsi_bytes[i]; + fcptr->fcp_cmd.fcpCntl1 = sbp->scsi_command.flags; + } + + /* Put LUN in the FCP command using the Peripheral Addressing Method */ + fcptr->fcp_cmd.fcpLunMsl = lun << FC_LUN_SHIFT; + fcptr->fcp_cmd.fcpLunLsl = 0; + + /* + * The Logical Unit Addressing method is not supported at + * this current release. + */ + if (dev_ptr->nodep->addr_mode == VOLUME_SET_ADDRESSING) { + fcptr->fcp_cmd.fcpLunMsl |= SWAP_DATA(0x40000000); + } + + fcptr->fcp_cmd.fcpDl = SWAP_DATA(bp->b_bcount); + + fcptr->sc_bufp = sbp; + fcptr->flags = 0; + + /* set up an iotag so we can match the completion iocb */ + for (i = 0; i < MAX_FCP_CMDS; i++) { + fcptr->iotag = rp->fc_iotag++; + if (rp->fc_iotag >= MAX_FCP_CMDS) + rp->fc_iotag = 1; + if (binfo->fc_table->fcp_array[fcptr->iotag] == 0) + break; + } + if (i >= MAX_FCP_CMDS) { + /* No more command slots available, retry later */ + fc_mem_put(binfo, MEM_IOCB, (uchar * )temp); + fc_enq_fcbuf(fcptr); + return(FCP_EXIT); + } + + fc_bzero((void *)temp, sizeof(IOCBQ)); /* zero the iocb entry */ + cmd = &temp->iocb; + + if (binfo->fc_flag & FC_SLI2) { + /* Allocate buffer for Buffer ptr list */ + if ((bmp = (MATCHMAP * )fc_mem_get(binfo, MEM_BPL)) == 0) { + fc_mem_put(binfo, MEM_IOCB, (uchar * )temp); + fc_enq_fcbuf(fcptr); + return(FCP_EXIT); + } + bpl = (ULP_BDE64 * )bmp->virt; + bpl->addrHigh = PCIMEM_LONG((uint32)putPaddrHigh(GET_PAYLOAD_PHYS_ADDR(fcptr))); + bpl->addrLow = PCIMEM_LONG((uint32)putPaddrLow(GET_PAYLOAD_PHYS_ADDR(fcptr))); + bpl->tus.f.bdeSize = sizeof(FCP_CMND); + bpl->tus.f.bdeFlags = BUFF_USE_CMND; + bpl->tus.w = PCIMEM_LONG(bpl->tus.w); + bpl++; + bpl->addrHigh = PCIMEM_LONG((uint32)putPaddrHigh(GET_PAYLOAD_PHYS_ADDR(fcptr)+sizeof(FCP_CMND))); + bpl->addrLow = PCIMEM_LONG((uint32)putPaddrLow(GET_PAYLOAD_PHYS_ADDR(fcptr)+sizeof(FCP_CMND))); + bpl->tus.f.bdeSize = sizeof(FCP_RSP); + bpl->tus.f.bdeFlags = (BUFF_USE_CMND | BUFF_USE_RCV); + bpl->tus.w = PCIMEM_LONG(bpl->tus.w); + bpl++; + + cmd->un.fcpi64.bdl.ulpIoTag32 = (uint32)0; + cmd->un.fcpi64.bdl.addrHigh = (uint32)putPaddrHigh(bmp->phys); + cmd->un.fcpi64.bdl.addrLow = (uint32)putPaddrLow(bmp->phys); + cmd->un.fcpi64.bdl.bdeSize = (2 * sizeof(ULP_BDE64)); + cmd->un.fcpi64.bdl.bdeFlags = BUFF_TYPE_BDL; + cmd->ulpBdeCount = 1; + fcptr->bmp = bmp; + temp->bpl = (uchar *)0; + } else { + bpl = 0; + cmd->un.fcpi.fcpi_cmnd.bdeAddress = (uint32)putPaddrLow(GET_PAYLOAD_PHYS_ADDR(fcptr)); + cmd->un.fcpi.fcpi_cmnd.bdeSize = sizeof(FCP_CMND); + cmd->un.fcpi.fcpi_rsp.bdeAddress = (uint32)(putPaddrLow((GET_PAYLOAD_PHYS_ADDR(fcptr) + sizeof(FCP_CMND)))); + cmd->un.fcpi.fcpi_rsp.bdeSize = sizeof(FCP_RSP); + cmd->ulpBdeCount = 2; + fcptr->bmp = 0; + temp->bpl = (uchar *)0; + } + + cmd->ulpContext = dev_ptr->nodep->rpi; + cmd->ulpIoTag = fcptr->iotag; + /* + * if device is FCP-2 device, set the following bit that says + * to run the FC-TAPE protocol. + */ + if (ndlp->id.nlp_fcp_info & NLP_FCP_2_DEVICE) { + cmd->ulpFCP2Rcvy = 1; + } + cmd->ulpClass = (ndlp->id.nlp_fcp_info & 0x0f); + cmd->ulpOwner = OWN_CHIP; + + if (sbp->timeout_value == 0) + sbp->timeout_value = 3600; /* One hour in seconds */ + + curtime(&fcptr->timeout); + + /* Need to set the FCP timeout in the fcptr structure and the IOCB + * for this I/O to get the adapter to run a timer. + */ + { + uint32 time_out; + + if(sbp->timeout_value) + time_out = sbp->timeout_value * fc_ticks_per_second; + else + time_out = 30 * fc_ticks_per_second; + + if (binfo->fc_flag & FC_FABRIC) { + time_out += (fc_ticks_per_second * + (clp[CFG_FCPFABRIC_TMO].a_current + (2 * binfo->fc_ratov))); + } + + fcptr->timeout = ((ulong)fcptr->timeout + time_out + (300 * fc_ticks_per_second)); + + /* Set the FCP timeout in the IOCB to get the adapter to run a timer */ + if ((time_out / fc_ticks_per_second) < 256) + cmd->ulpTimeout = time_out / fc_ticks_per_second; + } + + if (bp->b_bcount == 0) { + /* Set up for SCSI command */ + if (binfo->fc_flag & FC_SLI2) + cmd->ulpCommand = CMD_FCP_ICMND64_CR; + else + cmd->ulpCommand = CMD_FCP_ICMND_CR; + + if (((fcptr->fcp_cmd.fcpCdb[0] & 0xBF) == SCSI_RESERVE_UNIT) || + ((fcptr->fcp_cmd.fcpCdb[0] & 0xBF) == SCSI_RELEASE_UNIT)) { + /* Mask off the lun field for reserve/release commands */ + fcptr->fcp_cmd.fcpCdb[1] &= 0x1f; + } + if(bpl) { + bpl->addrHigh = 0; + bpl->addrLow = 0; + bpl->tus.w = 0; + } + cmd->un.fcpi.fcpi_parm = 0; + fcptr->fcp_cmd.fcpCntl3 = 0; + + cmd->ulpLe = 1; + /* Queue cmd chain to last iocb entry in xmit queue */ + if (rp->fc_tx.q_first == NULL) { + rp->fc_tx.q_first = (uchar * )temp; + } else { + ((IOCBQ * )(rp->fc_tx.q_last))->q = (uchar * )temp; + } + rp->fc_tx.q_last = (uchar * )temp; + rp->fc_tx.q_cnt++; + + } else if (bp->b_flags & B_READ) { + /* Set up for SCSI read */ + if (binfo->fc_flag & FC_SLI2) + cmd->ulpCommand = CMD_FCP_IREAD64_CR; + else + cmd->ulpCommand = CMD_FCP_IREAD_CR; + cmd->ulpPU = PARM_READ_CHECK; + cmd->un.fcpi.fcpi_parm = bp->b_bcount; + fcptr->fcp_cmd.fcpCntl3 = READ_DATA; + if((rc = fc_fcp_bufmap(p_dev_ctl, sbp, fcptr, temp, bpl, dev_ptr, pend)) != 0) + return(rc); + } else { + /* Set up for SCSI write */ + if (binfo->fc_flag & FC_SLI2) + cmd->ulpCommand = CMD_FCP_IWRITE64_CR; + else + cmd->ulpCommand = CMD_FCP_IWRITE_CR; + fcptr->fcp_cmd.fcpCntl3 = WRITE_DATA; + if((rc = fc_fcp_bufmap(p_dev_ctl, sbp, fcptr, temp, bpl, dev_ptr, pend)) != 0) + return(rc); + } + + if(dev_ptr->nodep->flags & FC_FCP2_RECOVERY) + cmd->ulpFCP2Rcvy = 1; + + lp = (uint32 * ) & fcptr->fcp_cmd; + fc_enq_fcbuf_active(rp, fcptr); + + dev_ptr->active_io_count++; + dev_ptr->nodep->num_active_io++; + FCSTATCTR.fcpCmd++; + + return(0); +} /* End issue_fcp_cmd */ + + +_static_ int +fc_failio( + fc_dev_ctl_t * p_dev_ctl) +{ + FC_BRD_INFO * binfo; + node_t * node_ptr; + dvi_t * dev_ptr; + struct buf *bp, *nextbp; + int i; + + binfo = &BINFO; + + /* Clear the queues for one or more SCSI devices */ + for (i = 0; i < MAX_FC_TARGETS; i++) { + if ((node_ptr = binfo->device_queue_hash[i].node_ptr) != NULL) { + for (dev_ptr = node_ptr->lunlist; dev_ptr != NULL; + dev_ptr = dev_ptr->next) { + + dev_ptr->queue_state = HALTED; + fc_return_standby_queue(dev_ptr, + (uchar)((binfo->fc_flag & FC_BUS_RESET) ? EIO : EFAULT), 0); + + /* First send ABTS on outstanding I/Os in txp queue */ + fc_abort_fcp_txpq(binfo, dev_ptr); + + fc_fail_pendq(dev_ptr, (char)((binfo->fc_flag & FC_BUS_RESET) ? + EIO : EFAULT), 0); + + fc_fail_cmd(dev_ptr, (char)((binfo->fc_flag & FC_BUS_RESET) ? + EIO : EFAULT), 0); + + /* Call iodone for all the CLEARQ error bufs */ + fc_free_clearq(dev_ptr); + } + } + } + /* Call iodone for any commands that timed out previously */ + for (bp = p_dev_ctl->timeout_head; bp != NULL; ) { + nextbp = bp->av_forw; + bp->b_error = ETIMEDOUT; + bp->b_flags |= B_ERROR; + fc_do_iodone(bp); + bp = nextbp; + } + p_dev_ctl->timeout_head = NULL; + p_dev_ctl->timeout_count = 0; + return(0); +} + + +_static_ void +fc_return_standby_queue( + dvi_t * dev_ptr, + uchar status, + uint32 statistic) +{ + T_SCSIBUF * sp; + + /* It is possible to have IOs on the pending queue because + of the way the scheduler works. */ + + while ((sp = dev_ptr->standby_queue_head) != NULL) { + dev_ptr->standby_count--; + dev_ptr->standby_queue_head = (T_SCSIBUF *)sp->bufstruct.av_forw; + fc_do_iodone((struct buf *) sp); + } + dev_ptr->standby_queue_head = NULL; + dev_ptr->standby_queue_tail = NULL; +} + +/* + * Restart all devices for a given adapter. Should only be + * invoked at the conclusion of loop {re}discovery. + */ +_static_ int +fc_restart_all_devices( + fc_dev_ctl_t * p_dev_ctl) +{ + dvi_t * dev_ptr; + FC_BRD_INFO * binfo; + int i; + node_t * node_ptr; + + binfo = &BINFO; + + for (i = 0; i < MAX_FC_TARGETS; ++i) { + if ((node_ptr = binfo->device_queue_hash[i].node_ptr) != NULL) { + dev_ptr = node_ptr->lunlist; + while (dev_ptr) { + if ((dev_ptr->queue_state == RESTART_WHEN_READY) || + (dev_ptr->queue_state == HALTED)) { + fc_restart_device(dev_ptr); + } + + if (dev_ptr->nodep->rpi != 0xfffe) + dev_ptr->flags &= ~(NORPI_RESET_DONE | DONT_LOG_INVALID_RPI); + else + dev_ptr->flags &= ~DONT_LOG_INVALID_RPI; + fc_enq_wait(dev_ptr); + dev_ptr = dev_ptr->next; + } + } + } + return(0); +} /* End fc_restart_all_devices */ + +/* + * Restart a device by draining its standby queue. + */ +_static_ int +fc_restart_device( + dvi_t * dev_ptr) +{ + FC_BRD_INFO * binfo; + + binfo = &dev_ptr->nodep->ap->info; + if (binfo->fc_ffstate != FC_READY || + (dev_ptr->flags & (SCSI_TQ_CLEARING | CHK_SCSI_ABDR))) { + + dev_ptr->queue_state = RESTART_WHEN_READY; + return(0); + } + + dev_ptr->queue_state = ACTIVE; + dev_ptr->flags &= ~(SCSI_TQ_HALTED | CHK_SCSI_ABDR); + fc_return_standby_queue(dev_ptr, + (uchar)((binfo->fc_flag & FC_BUS_RESET) ? EIO : EFAULT), 0); + + return(1); +} /* End fc_restart_device */ + +/* Called to reissue fcp command if tgt throttle was reached */ +_static_ void +re_issue_fcp_cmd( + dvi_t * dev_ptr) +{ + fc_dev_ctl_t * ap; + dvi_t * next_ptr; + dvi_t * start_ptr; + T_SCSIBUF * sbp = NULL; + int rc; + FC_BRD_INFO * binfo; + RING * rp; + + if (dev_ptr == NULL) + return; + + ap = dev_ptr->nodep->ap; + binfo = &ap->info; + + rp = &binfo->fc_ring[FC_FCP_RING]; + + next_ptr = dev_ptr; + start_ptr = next_ptr->nodep->lunlist; + + if (start_ptr == NULL) + return; + + do { + + if ((sbp = next_ptr->pend_head) != NULL) + break; + + next_ptr = next_ptr->next; + if (!next_ptr) + next_ptr = start_ptr; + } while ( next_ptr != dev_ptr ); + + if (! sbp) { + next_ptr->nodep->last_dev = NULL; + return; + } + + if ((rc = issue_fcp_cmd(ap, next_ptr, sbp, 1))) { + if ((rc & FCP_REQUEUE) || (rc & FCP_EXIT)) + return; + } + next_ptr->pend_count--; + next_ptr->pend_head = (T_SCSIBUF *) sbp->bufstruct.av_forw; + if (next_ptr->pend_head == NULL) + next_ptr->pend_tail = NULL; + else + next_ptr->pend_head->bufstruct.av_back = NULL; + + if (next_ptr->pend_count == 0) + fc_deq_wait(next_ptr); + + next_ptr->nodep->last_dev = next_ptr->next; + if (next_ptr->nodep->last_dev == NULL) + next_ptr->nodep->last_dev = next_ptr->nodep->lunlist; + + if (rp->fc_tx.q_cnt) + issue_iocb_cmd(binfo, rp, 0); + + return; +} /* End re_issue_fcp_cmd */ + +/* Find a SCSI device structure for a given LUN */ +_static_ dvi_t * +fc_find_lun( +FC_BRD_INFO *binfo, +int hash_index, +fc_lun_t lun) +{ + node_t * node_ptr; + dvi_t * dev_ptr; + + if ((hash_index < 0) || (hash_index > MAX_FC_TARGETS)) + return(NULL); + + node_ptr = binfo->device_queue_hash[hash_index].node_ptr; + + if (node_ptr == NULL) { + dev_ptr = NULL; + } else { + for (dev_ptr = node_ptr->lunlist; dev_ptr != NULL; + dev_ptr = dev_ptr->next) { + + if (dev_ptr->lun_id == lun) { + /* We found the correct entry */ + break; + } + } + } + return(dev_ptr); +} /* End fc_find_lun */ + +_static_ int +fc_reset_dev_q_depth( + fc_dev_ctl_t * p_dev_ctl) +{ + dvi_t * dev_ptr; + FC_BRD_INFO * binfo; + int i; + iCfgParam * clp; + node_t * node_ptr; + + binfo = &BINFO; + clp = DD_CTL.p_config[binfo->fc_brd_no]; + + for (i = 0; i < MAX_FC_TARGETS; ++i) { + if ((node_ptr = binfo->device_queue_hash[i].node_ptr) != NULL) { + dev_ptr = node_ptr->lunlist; + while (dev_ptr) { + dev_ptr->fcp_cur_queue_depth = (ushort)clp[CFG_DFT_LUN_Q_DEPTH].a_current; + dev_ptr = dev_ptr->next; + } + } + } + return(0); +} /* End fc_reset_dev_q_depth */ + + +/* [SYNC] */ +_static_ void +fc_polling( + FC_BRD_INFO *binfo, + uint32 att_bit) +{ + volatile uint32 ha_copy; + void *ioa; + fc_dev_ctl_t * p_dev_ctl; + + p_dev_ctl = (fc_dev_ctl_t *)binfo->fc_p_dev_ctl; + do { + ioa = (void *)FC_MAP_IO(&binfo->fc_iomap_io); /* map in io registers */ + ha_copy = READ_CSR_REG(binfo, FC_HA_REG(binfo, ioa)); + FC_UNMAP_MEMIO(ioa); + if (ha_copy & att_bit) + break; + } while (1); + fc_intr((struct intr *)p_dev_ctl); +} diff -purN -X /home/mbligh/.diff.exclude 350-autoswap/drivers/scsi/lpfc/fcxmitb.c 370-emulex/drivers/scsi/lpfc/fcxmitb.c --- 350-autoswap/drivers/scsi/lpfc/fcxmitb.c 1969-12-31 16:00:00.000000000 -0800 +++ 370-emulex/drivers/scsi/lpfc/fcxmitb.c 2004-02-28 11:20:05.000000000 -0800 @@ -0,0 +1,1442 @@ +/******************************************************************* + * This file is part of the Emulex Linux Device Driver for * + * Enterprise Fibre Channel Host Bus Adapters. * + * Refer to the README file included with this package for * + * driver version and adapter support. * + * Copyright (C) 2003 Emulex Corporation. * + * www.emulex.com * + * * + * This program is free software; you can redistribute it and/or * + * modify it under the terms of the GNU General Public License * + * as published by the Free Software Foundation; either version 2 * + * of the License, or (at your option) any later version. * + * * + * This program is distributed in the hope that it will be useful, * + * but WITHOUT ANY WARRANTY; without even the implied warranty of * + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * + * GNU General Public License for more details, a copy of which * + * can be found in the file COPYING included with this package. * + *******************************************************************/ + +#include "fc_os.h" + +#include "fc_hw.h" +#include "fc.h" + +#include "fcdiag.h" +#include "fcfgparm.h" +#include "fcmsg.h" +#include "fc_crtn.h" /* Core - external routine definitions */ +#include "fc_ertn.h" /* Environment - external routine definitions */ + +extern fc_dd_ctl_t DD_CTL; +extern iCfgParam icfgparam[]; +extern int lpfc_nethdr; + +/* Routine Declaration - Local */ +_local_ int fc_mbuf_to_iocb(fc_dev_ctl_t *p_dev_ctl, fcipbuf_t *p_mbuf); +_local_ fcipbuf_t *fc_txq_put(fc_dev_ctl_t *p_dev_ctl, RING *rp, + fcipbuf_t *p_mbuf); +/* End Routine Declaration - Local */ + +/*****************************************************************************/ +/* + * NAME: fc_ringtx_put + * + * FUNCTION: put xmit iocb onto the ring transmit queue. + * + * EXECUTION ENVIRONMENT: process and interrupt level. + * + * CALLED FROM: + * fc_els_cmd + * + * INPUT: + * binfo - pointer to the device info area + * iocbq - pointer to iocbq entry of xmit iocb + * + * RETURNS: + * none + */ +/*****************************************************************************/ +_static_ void +fc_ringtx_put( +RING *rp, +IOCBQ *iocbq) /* pointer to iocbq entry */ +{ + FC_BRD_INFO * binfo; + + binfo = (FC_BRD_INFO * )rp->fc_binfo; + if (rp->fc_tx.q_first) { + ((IOCBQ * )rp->fc_tx.q_last)->q = (uchar * )iocbq; + rp->fc_tx.q_last = (uchar * )iocbq; + } else { + rp->fc_tx.q_first = (uchar * )iocbq; + rp->fc_tx.q_last = (uchar * )iocbq; + } + + iocbq->q = NULL; + rp->fc_tx.q_cnt++; + + return; + +} /* End fc_ringtx_put */ + + +/*****************************************************************************/ +/* + * NAME: fc_ringtx_get + * + * FUNCTION: get a packet off the ring transmit queue. + * + * EXECUTION ENVIRONMENT: interrupt level. + * + * CALLED FROM: + * fc_els_cmd + * + * INPUT: + * rp - pointer to the ring to get an iocb from + * + * RETURNS: + * NULL - no iocbs found + * iocb pointer - pointer to an iocb to transmit + */ +/*****************************************************************************/ +_static_ IOCBQ * +fc_ringtx_get( +RING *rp) +{ + FC_BRD_INFO * binfo; + NODELIST * nlp; + IOCBQ * p_first = NULL; + IOCBQ * prev = NULL; + uchar * daddr; + ushort xri; + + binfo = (FC_BRD_INFO * )rp->fc_binfo; + if (rp->fc_tx.q_first) { + p_first = (IOCBQ * )rp->fc_tx.q_first; + + /* Make sure we already have a login and exchange to the remote node */ + while (p_first->iocb.ulpCommand == 0) { + if (rp->fc_ringno == FC_IP_RING) { + NETHDR * np; + + /* check to see if nlplist entry exists yet */ + np = (NETHDR * )(fcdata(((fcipbuf_t * )(p_first->bp)))); + daddr = np->fc_destname.IEEE; + if ((xri = fc_emac_lookup(binfo, daddr, &nlp))) { + /* exchange to destination already exists */ + if (binfo->fc_flag & FC_SLI2) + p_first->iocb.ulpCommand = CMD_XMIT_SEQUENCE64_CX; + else + p_first->iocb.ulpCommand = CMD_XMIT_SEQUENCE_CX; + p_first->iocb.ulpContext = xri; + p_first->info = (uchar * )nlp; + break; + } + } + + /* loop past continuation iocbs */ + while (p_first->iocb.ulpLe == 0) { + prev = p_first; + if ((p_first = (IOCBQ * )p_first->q) == 0) { + return(0); + } + } + prev = p_first; + if ((p_first = (IOCBQ * )p_first->q) == 0) { + return(0); + } + } + + /* adjust last if necessary */ + if (p_first->q == 0) { + rp->fc_tx.q_last = (uchar * )prev; + } + + /* remove iocb chain to process */ + if (prev == 0) { + rp->fc_tx.q_first = p_first->q; + } else { + prev->q = (uchar * )p_first->q; + } + + p_first->q = NULL; + rp->fc_tx.q_cnt--; + } + return(p_first); + +} /* End fc_ringtx_get */ + + +/*****************************************************************************/ +/* + * NAME: fc_ringtx_drain + * + * FUNCTION: get all packets off the ring transmit queue. + * + * EXECUTION ENVIRONMENT: interrupt level. + * + * NOTES: + * + * CALLED FROM: + * fc_els_cmd + * + * INPUT: + * binfo - pointer to the device info area + * + * RETURNS: + * NULL - no match found + * mbuf pointer - pointer to a mbuf chain which contains a packet. + */ +/*****************************************************************************/ +_static_ IOCBQ * +fc_ringtx_drain( +RING *rp) +{ + FC_BRD_INFO * binfo; + IOCBQ * p_first; + IOCBQ * prev; + + binfo = (FC_BRD_INFO * )rp->fc_binfo; + p_first = (IOCBQ * )rp->fc_tx.q_first; + if (p_first) { + prev = (IOCBQ * )p_first->q; + + /* remove iocb chain to process */ + if (prev == 0) { + rp->fc_tx.q_first = 0; + rp->fc_tx.q_last = 0; + } else { + rp->fc_tx.q_first = (uchar * )prev; + } + + p_first->q = NULL; + rp->fc_tx.q_cnt--; + } + + return(p_first); + +} /* End fc_ringtx_drain */ + + + + +/*****************************************************************************/ +/* + * NAME: fc_ringtxp_put + * + * FUNCTION: put xmit iocb onto the ring pending queue. + * + * EXECUTION ENVIRONMENT: process and interrupt level. + * + * CALLED FROM: + * fc_elsp_cmd + * + * INPUT: + * rp - pointer to the ring + * iocbq - pointer to iocbq entry of xmit iocb + * + * RETURNS: + * none + */ +/*****************************************************************************/ +_static_ void +fc_ringtxp_put( +RING *rp, +IOCBQ *iocbq) /* pointer to iocbq entry */ +{ + fc_dev_ctl_t * p_dev_ctl; + FC_BRD_INFO * binfo; + unsigned long iflag; + + binfo = (FC_BRD_INFO * )rp->fc_binfo; + p_dev_ctl = (fc_dev_ctl_t *)binfo->fc_p_dev_ctl; + + iflag = lpfc_q_disable_lock(p_dev_ctl); + if (rp->fc_txp.q_first) { + ((IOCBQ * )rp->fc_txp.q_last)->q = (uchar * )iocbq; + rp->fc_txp.q_last = (uchar * )iocbq; + } else { + rp->fc_txp.q_first = (uchar * )iocbq; + rp->fc_txp.q_last = (uchar * )iocbq; + + /* start watchdog timer on first xmit only */ + if (rp->fc_ringno != FC_FCP_RING) { + lpfc_q_unlock_enable(p_dev_ctl, iflag); + RINGTMO = fc_clk_set((fc_dev_ctl_t *)(binfo->fc_p_dev_ctl), + rp->fc_ringtmo, fc_cmdring_timeout, (void *)rp, 0); + iflag = lpfc_q_disable_lock(p_dev_ctl); + } + } + + iocbq->q = NULL; + rp->fc_txp.q_cnt++; + + lpfc_q_unlock_enable(p_dev_ctl, iflag); + return; + +} /* End fc_ringtxp_put */ + + +/*****************************************************************************/ +/* + * NAME: fc_ringtxp_get + * + * FUNCTION: get a packet off the ring pending queue. + * + * EXECUTION ENVIRONMENT: interrupt level. + * + * CALLED FROM: + * fc_els_cmd + * + * INPUT: + * rp - pointer to the ring + * + * RETURNS: + * NULL - no match found + * iocbq pointer - pointer to iocbq which matches the iotag + */ +/*****************************************************************************/ +_static_ IOCBQ * +fc_ringtxp_get( +RING *rp, +ushort iotag) /* tag to match i/o */ +{ + fc_dev_ctl_t * p_dev_ctl; + FC_BRD_INFO * binfo; + IOCBQ * iocbq; /* pointer to iocbq entry */ + IOCBQ * pq; /* pointer to previous iocbq entry */ + IOCBQ * save; /* pointer to iocb entry of chain */ + unsigned long iflag; + + binfo = (FC_BRD_INFO * )rp->fc_binfo; + p_dev_ctl = (fc_dev_ctl_t *)binfo->fc_p_dev_ctl; + pq = 0; + save = 0; + + /* Right now this just loops through the linked list looking + * for a match on iotag. This can get optimized in the future + * to have iotag just index into an array. + */ + iflag = lpfc_q_disable_lock(p_dev_ctl); + iocbq = (IOCBQ * )(rp->fc_txp.q_first); + while (iocbq) { + /* do we match on iotag */ + if ((iocbq->iocb.ulpIoTag == iotag) || (iotag == 0)) { + /* loop past continuation iocbs */ + while (iocbq->iocb.ulpLe == 0) { + rp->fc_txp.q_cnt--; + save = iocbq; + if ((iocbq = (IOCBQ * )iocbq->q) == 0) { + iocbq = save; + break; + } + } + save = iocbq; + iocbq = (IOCBQ * )iocbq->q; + + save->q = 0; /* NULL terminate iocb chain */ + + /* Remove iocbq chain from list, adjust first, last and cnt */ + if (iocbq == 0) + rp->fc_txp.q_last = (uchar * )pq; + + if (pq) { + save = (IOCBQ * )pq->q; + pq->q = (uchar * )iocbq; + } else { + save = (IOCBQ * )rp->fc_txp.q_first; + rp->fc_txp.q_first = (uchar * )iocbq; + } + rp->fc_txp.q_cnt--; + + /* stop watchdog timer */ + if(RINGTMO) { + lpfc_q_unlock_enable(p_dev_ctl, iflag); + fc_clk_can((fc_dev_ctl_t *)(binfo->fc_p_dev_ctl), RINGTMO); + iflag = lpfc_q_disable_lock(p_dev_ctl); + RINGTMO = 0; + } + + /* if xmits are still pending, restart the watchdog timer */ + if (rp->fc_txp.q_cnt > 0) { + /* start watchdog timer */ + if (rp->fc_ringno != FC_FCP_RING) { + lpfc_q_unlock_enable(p_dev_ctl, iflag); + RINGTMO = fc_clk_set((fc_dev_ctl_t *)(binfo->fc_p_dev_ctl), + rp->fc_ringtmo, fc_cmdring_timeout, (void *)rp, 0); + iflag = lpfc_q_disable_lock(p_dev_ctl); + } + } + break; + } + + pq = iocbq; + iocbq = (IOCBQ * )iocbq->q; + } + + lpfc_q_unlock_enable(p_dev_ctl, iflag); + return(save); +} /* End fc_ringtxp_get */ + + +/*****************************************************************************/ +/* + * NAME: fc_xmit + * + * FUNCTION: Fibre Channel driver output routine. + * + * EXECUTION ENVIRONMENT: process only + * + * NOTES: + * + * CALLED FROM: + * fc_output fc_intr + * + * INPUT: + * p_dev_ctl - pointer to device information. + * p_mbuf - pointer to a mbuf (chain) for outgoing packets + * + * RETURNS: + * 0 - successful + * EAGAIN - transmit queue is full + */ +/*****************************************************************************/ +int +fc_xmit( +fc_dev_ctl_t *p_dev_ctl, +fcipbuf_t *p_mbuf) +{ + fcipbuf_t * p_cur_mbuf; + fcipbuf_t * buf_tofree; + RING * rp; + FC_BRD_INFO * binfo; + iCfgParam * clp; + + binfo = &BINFO; + clp = DD_CTL.p_config[binfo->fc_brd_no]; + if(clp[CFG_NETWORK_ON].a_current == 0) + return(EIO); + + rp = &binfo->fc_ring[FC_IP_RING]; + buf_tofree = fc_txq_put(p_dev_ctl, rp, p_mbuf); + if (NDDSTAT.ndd_xmitque_max < rp->fc_tx.q_cnt) { + NDDSTAT.ndd_xmitque_max = rp->fc_tx.q_cnt; + } + + /* xmit queue was totally full */ + if (buf_tofree == p_mbuf) { + while (p_mbuf) { + NDDSTAT.ndd_xmitque_ovf++; + NDDSTAT.ndd_opackets_drop++; + p_mbuf = fcnextpkt(p_mbuf); + } + + /* send the packet(s) on the xmit queue */ + issue_iocb_cmd(binfo, rp, 0); + + return(EAGAIN); + } + + /* xmit queue could not fit entire chain */ + while ((p_cur_mbuf = buf_tofree) != NULL) { + NDDSTAT.ndd_xmitque_ovf++; + NDDSTAT.ndd_opackets_drop++; + buf_tofree = fcnextpkt(buf_tofree); + fcnextpkt(p_cur_mbuf) = NULL; + m_freem(p_cur_mbuf); + } + + /* send the packet(s) on the xmit queue */ + issue_iocb_cmd(binfo, rp, 0); + + return(0); +} /* End fc_xmit */ + + +/*****************************************************************************/ +/* + * NAME: fc_txq_put + * + * FUNCTION: put packets onto the transmit queue. + * + * EXECUTION ENVIRONMENT: process and interrupt level. + * + * NOTES: + * + * CALLED FROM: + * fc_xmit + * + * INPUT: + * p_dev_ctl - pointer to the device information area + * rp - pointer to the device information area + * p_mbuf - pointer to a mbuf chain + * + * RETURNS: + * NULL - all mbufs are queued. + * mbuf pointer - point to a mbuf chain which contains packets + * that overflows the transmit queue. + */ +/*****************************************************************************/ +_local_ fcipbuf_t * +fc_txq_put( +fc_dev_ctl_t *p_dev_ctl, +RING *rp, +fcipbuf_t *p_mbuf) /* pointer to a mbuf chain */ +{ + FC_BRD_INFO * binfo; + fcipbuf_t * p_last, *p_over, *p_next; + int room; + + room = rp->fc_tx.q_max - NDDSTAT.ndd_xmitque_cur; + binfo = &BINFO; + if (room > 0) { + p_over = 0; + p_next = p_mbuf; + while (p_next) { + p_last = fcnextpkt(p_next); + fcnextpkt(p_next) = NULL; + if (fc_mbuf_to_iocb(p_dev_ctl, p_next)) { + fcnextpkt(p_next) = p_last; + p_over = p_next; + break; + } + p_next = p_last; + if ( --room <= 0) { + p_over = p_next; + break; + } + } + binfo->fc_flag &= ~FC_NO_ROOM_IP; + } else { + FCSTATCTR.xmitnoroom++; + p_over = p_mbuf; + + if(!(binfo->fc_flag & FC_NO_ROOM_IP)) { + /* No room on IP xmit queue */ + fc_log_printf_msg_vargs( binfo->fc_brd_no, + &fc_msgBlk0605, /* ptr to msg structure */ + fc_mes0605, /* ptr to msg */ + fc_msgBlk0605.msgPreambleStr, /* begin varargs */ + FCSTATCTR.xmitnoroom); /* end varargs */ + } + binfo->fc_flag |= FC_NO_ROOM_IP; + } + + return(p_over); + +} /* End fc_txq_put */ + + + +/*****************************************************************************/ +/* + * NAME: fc_mbuf_to_iocb + * + * FUNCTION: converts and mbuf into an iocb cmd chain and put on transmit q + * + * EXECUTION ENVIRONMENT: process and interrupt + * + * NOTES: + * + * CALLED FROM: + * + * INPUT: + * p_dev_ctl - pointer to the device information area + * p_mbuf - pointer to a packet in mbuf + * + * RETURNS: + * 0 - OK + * -1 - error occurred during transmit + */ +/*****************************************************************************/ +_local_ int +fc_mbuf_to_iocb( +fc_dev_ctl_t *p_dev_ctl, +fcipbuf_t *p_mbuf) /* pointer to the packet in mbuf */ +{ + FC_BRD_INFO * binfo; + iCfgParam * clp; + uchar * daddr; + RING * rp; + IOCBQ * temp; + IOCBQ * qhead, * qtail; + IOCB * cmd; + NODELIST * nlp; + fcipbuf_t * p_cur_mbuf; /* pointer to current packet in mbuf */ + fcipbuf_t * m_net; + ushort * sp1, * sp2; + ULP_BDE64 * bpl, * topbpl; + MATCHMAP * bmp; + MATCHMAP * bmphead, *bmptail; + MATCHMAP * savebmp; + void * handle; + emac_t * ep; + NETHDR * np; + int i, j, mapcnt; + int count, firstbuflen; + int num_iocbs, num_bdes, numble; + ushort leftover, xri; + uchar isbcast, ismcast; + + binfo = &BINFO; + rp = &binfo->fc_ring[FC_IP_RING]; + clp = DD_CTL.p_config[binfo->fc_brd_no]; + + /* First get a temporary iocb buffers. temp will be + * used for the first iocb entry XMIT_SEQUENCE, and will + * be used for each successive IOCB_CONTINUE entry. + * qhead will be saved for the return + */ + if ((temp = (IOCBQ * )fc_mem_get(binfo, MEM_IOCB)) == 0) { + m_freem(p_mbuf); + return(0); + } + + fc_bzero((void *)temp, sizeof(IOCBQ)); /* initially zero the iocb entry */ + cmd = &temp->iocb; + mapcnt = 0; + numble = 0; + qhead = 0; + qtail = 0; + leftover = 0; + bmp = 0; + topbpl = 0; + if (binfo->fc_flag & FC_SLI2) { + bmphead = 0; + bmptail = 0; + /* Allocate buffer for Buffer ptr list */ + if ((bmp = (MATCHMAP * )fc_mem_get(binfo, MEM_BPL)) == 0) { + fc_mem_put(binfo, MEM_IOCB, (uchar * )temp); + m_freem(p_mbuf); + return(0); + } + bpl = (ULP_BDE64 * )bmp->virt; + cmd->un.xseq64.bdl.ulpIoTag32 = (uint32)0; + cmd->un.xseq64.bdl.addrHigh = (uint32)putPaddrHigh(bmp->phys); + cmd->un.xseq64.bdl.addrLow = (uint32)putPaddrLow(bmp->phys); + cmd->un.xseq64.bdl.bdeFlags = BUFF_TYPE_BDL; + temp->bpl = (uchar *)bmp; + } + else { + bpl = 0; + bmphead = 0; + bmptail = 0; + } + + if(lpfc_nethdr == 0) { + ep = (emac_t * )(fcdata(p_mbuf)); + daddr = ep->dest_addr; + + /* We need to convert 802.3 header (14 bytes) into + * fc network header (16 bytes). Since the header is at + * the begining of the buffer, we need to allocate extra space. + */ + + count = fcpktlen(p_mbuf) + 2; /* total data in mbuf after copy */ + firstbuflen = fcdatalen(p_mbuf); + /* Assume first data buffer holds emac and LLC/SNAP at a minimun */ + if (firstbuflen < sizeof(struct fc_hdr )) { + FCSTATCTR.mbufcopy++; + fc_mem_put(binfo, MEM_IOCB, (uchar * )temp); + if (bmp) { + fc_mem_put(binfo, MEM_BPL, (uchar * ) bmp); + } + m_freem(p_mbuf); + return(0); + } + + + /* Allocate a buffer big enough to hold the Fibre Channel header + * and the LLC/SNAP header. + */ + if ((m_net = (fcipbuf_t * )m_getclustm(M_DONTWAIT, MT_DATA, + (sizeof(NETHDR) + sizeof(snaphdr_t)))) == 0) { + fc_mem_put(binfo, MEM_IOCB, (uchar * )temp); + if (bmp) { + fc_mem_put(binfo, MEM_BPL, (uchar * ) bmp); + } + return(EIO); + } + fcsethandle(m_net, 0); + + np = (NETHDR * )fcdata(m_net); + + /* Copy data from emac_t header to network header */ + sp1 = (ushort * ) & np->fc_destname; + *sp1++ = 0; + np->fc_destname.nameType = NAME_IEEE; /* IEEE name */ + sp2 = (ushort * )ep->dest_addr; + + if (*sp2 & SWAP_DATA16(0x8000)) /* Check for multicast */ { + ismcast = 1; + if (*sp2 != 0xffff) /* Check for broadcast */ + isbcast = 0; + else + isbcast = 1; + } else { + ismcast = 0; + isbcast = 0; + } + + /* First copy over the dest IEEE address */ + *sp1++ = *sp2++; + if (isbcast && (*sp2 != 0xffff)) + isbcast = 0; + *sp1++ = *sp2++; + if (isbcast && (*sp2 != 0xffff)) + isbcast = 0; + *sp1++ = *sp2++; + + /* Next copy over the src IEEE address */ + sp1 = (ushort * ) & np->fc_srcname; + *sp1++ = 0; + np->fc_srcname.nameType = NAME_IEEE; /* IEEE name */ + sp2 = (ushort * )binfo->fc_portname.IEEE; + *sp1++ = *sp2++; + *sp1++ = *sp2++; + *sp1++ = *sp2++; + + sp2 = (ushort * )((uchar *)ep + sizeof(emac_t)); + + /* Now Copy LLC/SNAP */ + *sp1++ = *sp2++; + *sp1++ = *sp2++; + *sp1++ = *sp2++; + *sp1++ = *sp2++; + + p_cur_mbuf = m_net; + fcsetdatalen(m_net, (sizeof(NETHDR) + sizeof(snaphdr_t))); + + fcincdatalen(p_mbuf, (-(sizeof(struct fc_hdr )))); + + fcdata(p_mbuf) += sizeof(struct fc_hdr ); + + /* Fixup mbuf chain so data is in line */ + fcnextdata(m_net) = p_mbuf; + } + else { + np = (NETHDR * )(fcdata(((fcipbuf_t * )(p_mbuf)))); + daddr = np->fc_destname.IEEE; + count = fcpktlen(p_mbuf); + p_cur_mbuf = p_mbuf; + m_net = p_mbuf; + + sp2 = (ushort * )daddr; + if (*sp2 & SWAP_DATA16(0x8000)) /* Check for multicast */ { + ismcast = 1; + if (*sp2 != 0xffff) /* Check for broadcast */ + isbcast = 0; + else + isbcast = 1; + } else { + ismcast = 0; + isbcast = 0; + } + } + + num_iocbs = 0; /* count number of iocbs needed to xmit p_mbuf */ + num_bdes = 2; /* Will change to 3 for IOCB_CONTINUE */ + nlp = 0; + + /* + * While there's data left to send and we are not at the end of + * the mbuf chain, put the data from each mbuf in the chain into + * a seperate iocb entry. + */ + while (count && p_cur_mbuf) { + if (binfo->fc_flag & FC_SLI2) { + qhead = temp; + qtail = temp; + /* Set to max number of ULP_BDE64's that fit into a bpl */ + /* Save the last BDE for a continuation ptr, if needed */ + num_bdes = ((FCELSSIZE / sizeof(ULP_BDE64)) - 1); + numble = 0; + if (bmphead == 0) { + bmphead = bmp; + bmptail = bmp; + } else { + bmptail->fc_mptr = (uchar * )bmp; + bmptail = bmp; + } + bmp->fc_mptr = 0; + } else { + if (qhead == 0) { + qhead = temp; + qtail = temp; + } else { + qtail->q = (uchar * )temp; + qtail = temp; + } + } + temp->q = 0; + /* + * copy data pointers into iocb entry + */ + for (i = 0; i < num_bdes; i++) { + /* Skip mblk's with 0 data length */ + while (p_cur_mbuf && (fcdatalen(p_cur_mbuf) == 0)) + p_cur_mbuf = fcnextdata(p_cur_mbuf); /* goto next mbuf in chain */ + + if ((count <= 0) || (p_cur_mbuf == 0)) + break; + + if (leftover == 0) { + mapcnt = fc_bufmap(p_dev_ctl, (uchar * )(fcdata(p_cur_mbuf)), + (uint32)fcdatalen(p_cur_mbuf), binfo->physaddr, binfo->cntaddr, &handle); + + /* fill in BDEs for command */ + if (mapcnt <= 0) { + cmd->ulpBdeCount = i; + goto out; + } + + /* Save dmahandle if one was returned */ + fcsethandle(p_cur_mbuf, handle); + } + + for (j = leftover; j < mapcnt; j++) { + if ((i + j - leftover) >= num_bdes) { + i = num_bdes; + leftover = j; + goto lim; + } + if (binfo->fc_flag & FC_SLI2) { + bpl->addrHigh = (uint32)putPaddrHigh(binfo->physaddr[j]); + bpl->addrHigh = PCIMEM_LONG(bpl->addrHigh); + bpl->addrLow = (uint32)putPaddrLow(binfo->physaddr[j]); + bpl->addrLow = PCIMEM_LONG(bpl->addrLow); + bpl->tus.f.bdeSize = binfo->cntaddr[j]; + bpl->tus.f.bdeFlags = BDE64_SIZE_WORD; + bpl->tus.w = PCIMEM_LONG(bpl->tus.w); + bpl++; + numble++; + } else { + cmd->un.cont[i+j-leftover].bdeAddress = (uint32)putPaddrLow(binfo->physaddr[j]); + cmd->un.cont[i+j-leftover].bdeSize = binfo->cntaddr[j]; + cmd->un.cont[i+j-leftover].bdeAddrHigh = 0; + cmd->un.cont[i+j-leftover].bdeReserved = 0; + } + } + + i = i + j - leftover - 1; + count -= fcdatalen(p_cur_mbuf); /* adjust count of data left */ + leftover = 0; + p_cur_mbuf = fcnextdata(p_cur_mbuf); /* goto next mbuf in chain */ + } + +lim: + /* Fill in rest of iocb entry, all non-zero fields */ + + cmd->ulpBdeCount = i; + + /* Setup command to use accordingly */ + if (++num_iocbs > 1) { + if (!(binfo->fc_flag & FC_SLI2)) { + cmd->ulpCommand = CMD_IOCB_CONTINUE_CN; + temp->bp = 0; + temp->info = 0; + } + } else { + /* set up an iotag so we can match the completion to an iocb/mbuf */ + cmd->ulpIoTag = rp->fc_iotag++; + if (rp->fc_iotag == 0) { + rp->fc_iotag = 1; + } + + /* Setup fibre channel header information */ + cmd->un.xrseq.w5.hcsw.Fctl = 0; + cmd->un.xrseq.w5.hcsw.Dfctl = FC_NET_HDR; /* network headers */ + cmd->un.xrseq.w5.hcsw.Rctl = FC_UNSOL_DATA; + cmd->un.xrseq.w5.hcsw.Type = FC_LLC_SNAP; + + if (isbcast) { + if (++NDDSTAT.ndd_ifOutBcastPkts_lsw == 0) + NDDSTAT.ndd_ifOutBcastPkts_msw++; + if (binfo->fc_flag & FC_SLI2) + cmd->ulpCommand = CMD_XMIT_BCAST64_CN; + else + cmd->ulpCommand = CMD_XMIT_BCAST_CN; + cmd->ulpContext = 0; + nlp = 0; + } else if (ismcast) { + if (++NDDSTAT.ndd_ifOutMcastPkts_lsw == 0) + NDDSTAT.ndd_ifOutMcastPkts_msw++; + if (binfo->fc_flag & FC_SLI2) + cmd->ulpCommand = CMD_XMIT_BCAST64_CN; + else + cmd->ulpCommand = CMD_XMIT_BCAST_CN; + cmd->ulpContext = 0; + nlp = 0; + } else { + if (++NDDSTAT.ndd_ifOutUcastPkts_lsw == 0) + NDDSTAT.ndd_ifOutUcastPkts_msw++; + + /* data from upper layer has a full MAC header on it. We + * need to match the destination address with the portname + * field in our nlp table to determine if we already have an + * exchange opened to this destination. + */ + if (((xri = fc_emac_lookup(binfo, daddr, &nlp)) != 0) && + !(nlp->nlp_action & NLP_DO_RSCN) && + (nlp->nlp_bp == 0)) { + /* exchange to destination already exists */ + if (binfo->fc_flag & FC_SLI2) + cmd->ulpCommand = CMD_XMIT_SEQUENCE64_CX; + else + cmd->ulpCommand = CMD_XMIT_SEQUENCE_CX; + cmd->ulpContext = xri; + nlp->nlp_type |= NLP_IP_NODE; + } else { /* need to wait for exchange to destination */ + FCSTATCTR.frameXmitDelay++; + cmd->ulpCommand = 0; + cmd->ulpContext = 0; + + if ((binfo->fc_flag & FC_LNK_DOWN) || + (binfo->fc_ffstate < rp->fc_xmitstate)) + goto out; + + if (nlp == 0) { + /* A partial entry doesn't even exist, so initiate + * ELS login by sending a FARP + */ + /* Add FARP code here */ + fc_els_cmd(binfo, ELS_CMD_FARP, (void *)daddr, + (uint32)0, (ushort)0, (NODELIST *)0); + } else { + if ((nlp->nlp_DID != Bcast_DID) && + !(nlp->nlp_action & NLP_DO_ADDR_AUTH) && + !(nlp->nlp_action & NLP_DO_RSCN) && + !(nlp->nlp_flag & (NLP_FARP_SND | NLP_REQ_SND | NLP_RPI_XRI))) { + /* If a cached entry exists, PLOGI first */ + if ((nlp->nlp_state == NLP_LIMBO) || + (nlp->nlp_state == NLP_LOGOUT)) { + fc_els_cmd(binfo, ELS_CMD_PLOGI, + (void *)((ulong)nlp->nlp_DID), (uint32)0, (ushort)0, nlp); + } + /* establish a new exchange */ + if ((nlp->nlp_Rpi) && (nlp->nlp_Xri == 0)) { + nlp->nlp_flag |= NLP_RPI_XRI; + fc_create_xri(binfo, &binfo->fc_ring[FC_ELS_RING], nlp); + } + } + } + + cmd = &temp->iocb; + if (binfo->fc_flag & FC_SLI2) { + while (bpl && (bpl != (ULP_BDE64 * )bmp->virt)) { + bpl--; + fc_bufunmap(p_dev_ctl, + (uchar *)getPaddr(bpl->addrHigh, bpl->addrLow), 0, bpl->tus.f.bdeSize); + } + if (bmp) { + fc_mem_put(binfo, MEM_BPL, (uchar * ) bmp); + } + } else { + for (i = 0; i < (int)cmd->ulpBdeCount; i++) { + fc_bufunmap(p_dev_ctl, (uchar *)((ulong)cmd->un.cont[i].bdeAddress), 0, (uint32)cmd->un.cont[i].bdeSize); + } + } + if(lpfc_nethdr == 0) { + /* Free Resources */ + fcnextdata(m_net) = 0; + fcfreehandle(p_dev_ctl, m_net); + m_freem(m_net); + + /* Put p_mbuf back the way it was, without NETHDR */ + fcincdatalen(p_mbuf, sizeof(struct fc_hdr )); + fcdata(p_mbuf) -= sizeof(struct fc_hdr ); + } + + fcfreehandle(p_dev_ctl, p_mbuf); + + fc_mem_put(binfo, MEM_IOCB, (uchar * )temp); + + /* save buffer till ELS login completes */ + + if (nlp == 0) { + m_freem(p_mbuf); + return(0); + } + + if (nlp->nlp_bp == 0) { + nlp->nlp_bp = (uchar * )p_mbuf; + } else { + /* Only keep one mbuf chain per node "on deck" */ + p_cur_mbuf = (fcipbuf_t * )nlp->nlp_bp; + nlp->nlp_bp = (uchar * )p_mbuf; + m_freem(p_cur_mbuf); + } + return(0); + } + cmd->ulpClass = nlp->id.nlp_ip_info; + } + + num_bdes = 3; /* in case IOCB_CONTINUEs are needed */ + temp->bp = (uchar * )m_net; + temp->info = (uchar * )nlp; + } + + cmd->ulpOwner = OWN_CHIP; + + /* is this the last iocb entry we will need */ + if ((count == 0) || (p_cur_mbuf == 0)) { + temp = 0; + cmd->ulpLe = 1; + /* if so queue cmd chain to last iocb entry in xmit queue */ + if (rp->fc_tx.q_first == 0) { + rp->fc_tx.q_first = (uchar * )qhead; + rp->fc_tx.q_last = (uchar * )qtail; + } else { + ((IOCBQ * )(rp->fc_tx.q_last))->q = (uchar * )qhead; + rp->fc_tx.q_last = (uchar * )qtail; + } + rp->fc_tx.q_cnt += num_iocbs; + NDDSTAT.ndd_xmitque_cur++; + break; + } else { + cmd->ulpLe = 0; + } + + /* get another iocb entry buffer */ + if (binfo->fc_flag & FC_SLI2) { + /* Allocate buffer for Buffer ptr list */ + if ((bmp = (MATCHMAP * )fc_mem_get(binfo, MEM_BPL)) == 0) { + goto out; + } + /* Fill in continuation entry to next bpl */ + bpl->addrHigh = (uint32)putPaddrHigh(bmp->phys); + bpl->addrHigh = PCIMEM_LONG(bpl->addrHigh); + bpl->addrLow = (uint32)putPaddrLow(bmp->phys); + bpl->addrLow = PCIMEM_LONG(bpl->addrLow); + bpl->tus.f.bdeFlags = BPL64_SIZE_WORD; + numble++; + if (num_iocbs == 1) { + cmd->un.xseq64.bdl.bdeSize = (numble * sizeof(ULP_BDE64)); + } else { + topbpl->tus.f.bdeSize = (numble * sizeof(ULP_BDE64)); + topbpl->tus.w = PCIMEM_LONG(topbpl->tus.w); + } + topbpl = bpl; + bpl = (ULP_BDE64 * )bmp->virt; + leftover = 0; + } else { + if ((temp = (IOCBQ * )fc_mem_get(binfo, MEM_IOCB)) == 0) { +out: + /* no more available, so toss mbuf by freeing + * resources associated with qhead + */ + if (binfo->fc_flag & FC_SLI2) { + num_bdes = ((FCELSSIZE / sizeof(ULP_BDE64)) - 1); + bmp = bmphead; + while (bmp) { + i = 0; + bpl = (ULP_BDE64 * )bmp->virt; + while (bpl && (i < num_bdes)) { + bpl++; + i++; + fc_bufunmap(p_dev_ctl, + (uchar *)getPaddr(bpl->addrHigh, bpl->addrLow), 0, bpl->tus.f.bdeSize); + } + savebmp = (MATCHMAP * )bmp->fc_mptr; + if (bmp) { + fc_mem_put(binfo, MEM_BPL, (uchar * )bmp); + } + bmp = savebmp; + } + + fc_mem_put(binfo, MEM_IOCB, (uchar * )temp); + } else { + while (qhead) { + temp = qhead; + cmd = &temp->iocb; + for (i = 0; i < (int)cmd->ulpBdeCount; i++) { + fc_bufunmap(p_dev_ctl, (uchar *)((ulong)cmd->un.cont[i].bdeAddress), 0, (uint32)cmd->un.cont[i].bdeSize); + } + qhead = (IOCBQ * )temp->q; + fc_mem_put(binfo, MEM_IOCB, (uchar * )temp); + } + } + + if(lpfc_nethdr == 0) { + fcnextdata(m_net) = 0; + fcfreehandle(p_dev_ctl, m_net); + m_freem(m_net); + + /* Put p_mbuf back the way it was, without NETHDR */ + fcincdatalen(p_mbuf, sizeof(struct fc_hdr )); + fcdata(p_mbuf) -= sizeof(struct fc_hdr ); + } + + fcfreehandle(p_dev_ctl, p_mbuf); + + if (binfo->fc_flag & FC_SLI2) { + m_freem(p_mbuf); + return(0); + } + return(EIO); + } + fc_bzero((void *)temp, sizeof(IOCBQ)); + cmd = &temp->iocb; + } + } + + if (binfo->fc_flag & FC_SLI2) { + bpl->addrHigh = 0; + bpl->addrLow = 0; + bpl->tus.w = 0; + cmd->ulpBdeCount = 1; + if (num_iocbs == 1) { + cmd->un.xseq64.bdl.bdeSize = (numble * sizeof(ULP_BDE64)); + } else { + topbpl->tus.f.bdeSize = (numble * sizeof(ULP_BDE64)); + topbpl->tus.w = PCIMEM_LONG(topbpl->tus.w); + } + } + + if (temp) + fc_mem_put(binfo, MEM_IOCB, (uchar * )temp); + + return(0); +} /* End fc_mbuf_to_iocb */ + + + +/**********************************************/ +/** handle_xmit_cmpl **/ +/** **/ +/** Process all transmit completions **/ +/** **/ +/**********************************************/ +_static_ int +handle_xmit_cmpl( +fc_dev_ctl_t *p_dev_ctl, +RING *rp, +IOCBQ *temp) +{ + FC_BRD_INFO * binfo; + IOCB * cmd; + IOCBQ * xmitiq; + IOCBQ * save; + NODELIST * nlp; + fcipbuf_t * p_mbuf; + fcipbuf_t * m_net; + int i, cnt; + ULP_BDE64 * bpl; + MATCHMAP * bmp; + DMATCHMAP * indmp; + + cmd = &temp->iocb; + binfo = &BINFO; + if (++NDDSTAT.ndd_xmitintr_lsw == 0) { + NDDSTAT.ndd_xmitintr_msw++; + } + + /* look up xmit compl by IoTag */ + if ((xmitiq = fc_ringtxp_get(rp, cmd->ulpIoTag)) == 0) { + FCSTATCTR.strayXmitCmpl++; + /* Stray XmitSequence completion */ + fc_log_printf_msg_vargs( binfo->fc_brd_no, + &fc_msgBlk0606, /* ptr to msg structure */ + fc_mes0606, /* ptr to msg */ + fc_msgBlk0606.msgPreambleStr, /* begin varargs */ + cmd->ulpCommand, + cmd->ulpIoTag); /* end varargs */ + /* completion with missing xmit command */ + return(EIO); + } + + if (rp->fc_ringno == FC_ELS_RING) { + indmp = (DMATCHMAP * )xmitiq->bp; + if (cmd->ulpStatus) { + indmp->dfc_flag = -1; + } + else { + indmp->dfc_flag = xmitiq->iocb.un.xseq64.bdl.bdeSize; + } + fc_mem_put(binfo, MEM_IOCB, (uchar * )xmitiq); + return(0); + } + + + NDDSTAT.ndd_xmitque_cur--; + + /* get mbuf ptr for completed xmit */ + m_net = (fcipbuf_t * )xmitiq->bp; + + /* check for first xmit completion in sequence */ + nlp = (NODELIST * ) xmitiq->info; + + if (cmd->ulpStatus) { + uint32 did = 0; + + NDDSTAT.ndd_oerrors++; + + if (nlp) + did = nlp->nlp_DID; + /* Xmit Sequence completion error */ + fc_log_printf_msg_vargs( binfo->fc_brd_no, + &fc_msgBlk0607, /* ptr to msg structure */ + fc_mes0607, /* ptr to msg */ + fc_msgBlk0607.msgPreambleStr, /* begin varargs */ + cmd->ulpStatus, + cmd->ulpIoTag, + cmd->un.ulpWord[4], + did); /* end varargs */ + if (nlp && (nlp->nlp_state >= NLP_LOGIN)) { + /* If XRI in xmit sequence with status error matches XRI + * in nlplist entry, we need to create a new one. + */ + if ((nlp->nlp_Xri == cmd->ulpContext) && + !(nlp->nlp_flag & NLP_RPI_XRI)) { + /* on xmit error, exchange is aborted */ + nlp->nlp_Xri = 0; /* xri */ + /* establish a new exchange */ + if ((nlp->nlp_Rpi) && + (binfo->fc_ffstate == FC_READY)) { + nlp->nlp_flag |= NLP_RPI_XRI; + fc_create_xri(binfo, &binfo->fc_ring[FC_ELS_RING], nlp); + } + } + } + } else { + if (++NDDSTAT.ndd_opackets_lsw == 0) + NDDSTAT.ndd_opackets_msw++; + + if (m_net && + ((nlp && ((nlp->nlp_DID & CT_DID_MASK) != CT_DID_MASK)) || + (xmitiq->iocb.ulpCommand == CMD_XMIT_BCAST_CX))) { + + if(lpfc_nethdr == 0) { + p_mbuf = fcnextdata(m_net); + cnt = fcpktlen(p_mbuf); + } + else { + p_mbuf = m_net; + cnt = fcpktlen(p_mbuf) - sizeof(NETHDR); /* total data in mbuf */ + } + + NDDSTAT.ndd_obytes_lsw += cnt; + if ((int)NDDSTAT.ndd_obytes_lsw < cnt) + NDDSTAT.ndd_obytes_msw++; + } + } + + if (nlp && (nlp->nlp_DID == NameServer_DID)) { + MATCHMAP * mp; + + mp = (MATCHMAP * )m_net; + if (binfo->fc_flag & FC_SLI2) { + fc_mem_put(binfo, MEM_BPL, (uchar * )xmitiq->bpl); + } + fc_mem_put(binfo, MEM_IOCB, (uchar * )xmitiq); + fc_mem_put(binfo, MEM_BUF, (uchar * )mp); + return(0); + } + + /* Loop through iocb chain and unmap memory pages associated with mbuf */ + if (binfo->fc_flag & FC_SLI2) { + MATCHMAP * savebmp; + int cnt; + + bmp = (MATCHMAP * )xmitiq->bpl; + cnt = xmitiq->iocb.un.xseq64.bdl.bdeSize; + while (bmp) { + bpl = (ULP_BDE64 * )bmp->virt; + while (bpl && cnt) { + bpl->addrHigh = PCIMEM_LONG(bpl->addrHigh); + bpl->addrLow = PCIMEM_LONG(bpl->addrLow); + bpl->tus.w = PCIMEM_LONG(bpl->tus.w); + switch (bpl->tus.f.bdeFlags) { + case BPL64_SIZE_WORD: + cnt = bpl->tus.f.bdeSize; + bpl = 0; + break; + case BDE64_SIZE_WORD: + fc_bufunmap(p_dev_ctl, (uchar *)getPaddr(bpl->addrHigh, bpl->addrLow), 0, bpl->tus.f.bdeSize); + bpl++; + cnt -= sizeof(ULP_BDE64); + break; + default: + bpl = 0; + cnt = 0; + break; + } + } + savebmp = (MATCHMAP * )bmp->fc_mptr; + fc_mem_put(binfo, MEM_BPL, (uchar * )bmp); + bmp = savebmp; + } + fc_mem_put(binfo, MEM_IOCB, (uchar * )xmitiq); + } else { + while (xmitiq) { + for (i = 0; i < (int)xmitiq->iocb.ulpBdeCount; i++) { + fc_bufunmap(p_dev_ctl, (uchar *)((ulong)xmitiq->iocb.un.cont[i].bdeAddress), 0, (uint32)xmitiq->iocb.un.cont[i].bdeSize); + } + save = (IOCBQ * )xmitiq->q; + fc_mem_put(binfo, MEM_IOCB, (uchar * )xmitiq); + xmitiq = save; + } + } + + /* free mbuf */ + if (m_net) { + if(lpfc_nethdr == 0) { + p_mbuf = fcnextdata(m_net); + fcnextdata(m_net) = 0; + fcfreehandle(p_dev_ctl, m_net); + m_freem(m_net); + + /* Put p_mbuf back the way it was, without NETHDR */ + fcincdatalen(p_mbuf, sizeof(struct fc_hdr )); + + fcdata(p_mbuf) -= sizeof(struct fc_hdr ); + } + else { + p_mbuf = m_net; + } + + fcfreehandle(p_dev_ctl, p_mbuf); + m_freem(p_mbuf); + } + + fc_restartio(p_dev_ctl, nlp); + + return(0); +} /* End handle_xmit_cmpl */ + + +/* + * Issue an iocb command to create an exchange with the remote + * specified by the NODELIST entry. + */ +_static_ int +fc_create_xri( +FC_BRD_INFO *binfo, +RING *rp, +NODELIST *nlp) +{ + IOCB * icmd; + IOCBQ * temp; + + /* While there are buffers to post */ + if ((temp = (IOCBQ * )fc_mem_get(binfo, MEM_IOCB)) == 0) { + return(1); + } + fc_bzero((void *)temp, sizeof(IOCBQ)); + icmd = &temp->iocb; + + /* set up an iotag so we can match the completion to an iocb/mbuf */ + icmd->ulpIoTag = rp->fc_iotag++; + if (rp->fc_iotag == 0) { + rp->fc_iotag = 1; + } + icmd->ulpContext = nlp->nlp_Rpi; + icmd->ulpLe = 1; + + icmd->ulpCommand = CMD_CREATE_XRI_CR; + icmd->ulpOwner = OWN_CHIP; + + temp->bp = (uchar * )nlp; /* used for delimiter between commands */ + + FCSTATCTR.cmdCreateXri++; + + issue_iocb_cmd(binfo, rp, temp); + return(0); +} /* End fc_create_xri */ + + +/* + * Process a create_xri command completion. + */ +_static_ int +handle_create_xri( +fc_dev_ctl_t *p_dev_ctl, +RING *rp, +IOCBQ *temp) +{ + FC_BRD_INFO * binfo; + IOCB * cmd; + NODELIST * nlp; + IOCBQ * xmitiq; + + cmd = &temp->iocb; + binfo = &BINFO; + /* look up xmit compl by IoTag */ + if ((xmitiq = fc_ringtxp_get(rp, cmd->ulpIoTag)) == 0) { + FCSTATCTR.strayXmitCmpl++; + /* Stray CreateXRI completion */ + fc_log_printf_msg_vargs( binfo->fc_brd_no, + &fc_msgBlk0608, /* ptr to msg structure */ + fc_mes0608, /* ptr to msg */ + fc_msgBlk0608.msgPreambleStr, /* begin varargs */ + cmd->ulpCommand, + cmd->ulpIoTag); /* end varargs */ + /* completion with missing xmit command */ + return(EIO); + } + + /* check for first xmit completion in sequence */ + nlp = (NODELIST * ) xmitiq->bp; + + if (cmd->ulpStatus) { + fc_mem_put(binfo, MEM_IOCB, (uchar * )xmitiq); + + nlp->nlp_flag &= ~NLP_RPI_XRI; + + fc_freenode_did(binfo, nlp->nlp_DID, 0); + + FCSTATCTR.xriStatErr++; + return(EIO); + } + + FCSTATCTR.xriCmdCmpl++; + + nlp->nlp_Xri = cmd->ulpContext; + nlp->nlp_flag &= ~NLP_RPI_XRI; + + fc_mem_put(binfo, MEM_IOCB, (uchar * )xmitiq); + + fc_restartio(p_dev_ctl, nlp); + return(0); +} /* End handle_create_xri */ + + +_static_ void +fc_restartio( +fc_dev_ctl_t *p_dev_ctl, +NODELIST *nlp) +{ + FC_BRD_INFO * binfo; + RING * rp; + fcipbuf_t * p_cur_mbuf; + fcipbuf_t * buf_tofree; + + binfo = &BINFO; + rp = &binfo->fc_ring[FC_IP_RING]; + + if (nlp) { + if ((nlp->nlp_bp) && (nlp->nlp_Xri)) { + p_cur_mbuf = (fcipbuf_t * )nlp->nlp_bp; + nlp->nlp_bp = 0; + buf_tofree = fc_txq_put(p_dev_ctl, rp, p_cur_mbuf); + while ((p_cur_mbuf = buf_tofree) != 0) { + NDDSTAT.ndd_opackets_drop++; + buf_tofree = fcnextpkt(buf_tofree); + fcnextpkt(p_cur_mbuf) = NULL; + m_freem(p_cur_mbuf); + } + } + } + + /* Is there a xmit waiting to be started */ + if (rp->fc_tx.q_first) { + /* If so, start it */ + issue_iocb_cmd(binfo, rp, 0); + } + + /* If needed */ +} /* End fc_restartio */ + + diff -purN -X /home/mbligh/.diff.exclude 350-autoswap/drivers/scsi/lpfc/hbaapi.h 370-emulex/drivers/scsi/lpfc/hbaapi.h --- 350-autoswap/drivers/scsi/lpfc/hbaapi.h 1969-12-31 16:00:00.000000000 -0800 +++ 370-emulex/drivers/scsi/lpfc/hbaapi.h 2004-02-28 11:20:05.000000000 -0800 @@ -0,0 +1,311 @@ +/******************************************************************* + * This file is part of the Emulex Linux Device Driver for * + * Enterprise Fibre Channel Host Bus Adapters. * + * Refer to the README file included with this package for * + * driver version and adapter support. * + * Copyright (C) 2003 Emulex Corporation. * + * www.emulex.com * + * * + * This program is free software; you can redistribute it and/or * + * modify it under the terms of the GNU General Public License * + * as published by the Free Software Foundation; either version 2 * + * of the License, or (at your option) any later version. * + * * + * This program is distributed in the hope that it will be useful, * + * but WITHOUT ANY WARRANTY; without even the implied warranty of * + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * + * GNU General Public License for more details, a copy of which * + * can be found in the file COPYING included with this package. * + *******************************************************************/ + +#ifndef HBA_API_H +#define HBA_API_H + +/* Library version string */ +#define HBA_LIBVERSION 1 + +/* DLL imports for WIN32 operation */ +#define HBA_API + +/* OS specific definitions */ + + +typedef unsigned char HBA_UINT8; /* Unsigned 8 bits */ +typedef char HBA_INT8; /* Signed 8 bits */ +typedef unsigned short HBA_UINT16; /* Unsigned 16 bits */ +typedef short HBA_INT16; /* Signed 16 bits */ +typedef unsigned int HBA_UINT32; /* Unsigned 32 bits */ +typedef int HBA_INT32; /* Signed 32 bits */ +typedef void* HBA_PVOID; /* Pointer to void */ +typedef HBA_UINT32 HBA_VOID32; /* Opaque 32 bits */ +typedef long long HBA_INT64; +typedef long long HBA_UINT64; + + + +/* 4.2.1 Handle to Device */ +typedef HBA_UINT32 HBA_HANDLE; + +/* 4.2.2 Status Return Values */ +typedef HBA_UINT32 HBA_STATUS; + +#define HBA_STATUS_OK 0 +#define HBA_STATUS_ERROR 1 /* Error */ +#define HBA_STATUS_ERROR_NOT_SUPPORTED 2 /* Function not supported.*/ +#define HBA_STATUS_ERROR_INVALID_HANDLE 3 /* invalid handle */ +#define HBA_STATUS_ERROR_ARG 4 /* Bad argument */ +#define HBA_STATUS_ERROR_ILLEGAL_WWN 5 /* WWN not recognized */ +#define HBA_STATUS_ERROR_ILLEGAL_INDEX 6 /* Index not recognized */ +#define HBA_STATUS_ERROR_MORE_DATA 7 /* Larger buffer required */ +#define HBA_STATUS_ERROR_STALE_DATA 8 /* need a refresh */ + + + +/* 4.2.3 Port Operational Modes Values */ + +typedef HBA_UINT32 HBA_PORTTYPE; + +#define HBA_PORTTYPE_UNKNOWN 1 /* Unknown */ +#define HBA_PORTTYPE_OTHER 2 /* Other */ +#define HBA_PORTTYPE_NOTPRESENT 3 /* Not present */ +#define HBA_PORTTYPE_NPORT 5 /* Fabric */ +#define HBA_PORTTYPE_NLPORT 6 /* Public Loop */ +#define HBA_PORTTYPE_FLPORT 7 /* Fabric Loop Port */ +#define HBA_PORTTYPE_FPORT 8 /* Fabric Port */ +#define HBA_PORTTYPE_EPORT 9 /* Fabric expansion port */ +#define HBA_PORTTYPE_GPORT 10 /* Generic Fabric Port */ +#define HBA_PORTTYPE_LPORT 20 /* Private Loop */ +#define HBA_PORTTYPE_PTP 21 /* Point to Point */ + + +typedef HBA_UINT32 HBA_PORTSTATE; +#define HBA_PORTSTATE_UNKNOWN 1 /* Unknown */ +#define HBA_PORTSTATE_ONLINE 2 /* Operational */ +#define HBA_PORTSTATE_OFFLINE 3 /* User Offline */ +#define HBA_PORTSTATE_BYPASSED 4 /* Bypassed */ +#define HBA_PORTSTATE_DIAGNOSTICS 5 /* In diagnostics mode */ +#define HBA_PORTSTATE_LINKDOWN 6 /* Link Down */ +#define HBA_PORTSTATE_ERROR 7 /* Port Error */ +#define HBA_PORTSTATE_LOOPBACK 8 /* Loopback */ + + +typedef HBA_UINT32 HBA_PORTSPEED; +#define HBA_PORTSPEED_1GBIT 1 /* 1 GBit/sec */ +#define HBA_PORTSPEED_2GBIT 2 /* 2 GBit/sec */ +#define HBA_PORTSPEED_10GBIT 4 /* 10 GBit/sec */ + + + +/* 4.2.4 Class of Service Values - See GS-2 Spec.*/ + +typedef HBA_UINT32 HBA_COS; + + +/* 4.2.5 Fc4Types Values */ + +typedef struct HBA_fc4types { + HBA_UINT8 bits[32]; /* 32 bytes of FC-4 per GS-2 */ +} HBA_FC4TYPES, *PHBA_FC4TYPES; + +/* 4.2.6 Basic Types */ + +typedef struct HBA_wwn { + HBA_UINT8 wwn[8]; +} HBA_WWN, *PHBA_WWN; + +typedef struct HBA_ipaddress { + int ipversion; /* see enumerations in RNID */ + union + { + unsigned char ipv4address[4]; + unsigned char ipv6address[16]; + } ipaddress; +} HBA_IPADDRESS, *PHBA_IPADDRESS; + +/* 4.2.7 Adapter Attributes */ +typedef struct hba_AdapterAttributes { + char Manufacturer[64]; /*Emulex */ + char SerialNumber[64]; /* A12345 */ + char Model[256]; /* QLA2200 */ + char ModelDescription[256]; /* Agilent TachLite */ + HBA_WWN NodeWWN; + char NodeSymbolicName[256]; /* From GS-3 */ + char HardwareVersion[256]; /* Vendor use */ + char DriverVersion[256]; /* Vendor use */ + char OptionROMVersion[256]; /* Vendor use - i.e. hardware boot ROM*/ + char FirmwareVersion[256]; /* Vendor use */ + HBA_UINT32 VendorSpecificID; /* Vendor specific */ + HBA_UINT32 NumberOfPorts; + char DriverName[256]; /* Binary path and/or name of driver file. */ +} HBA_ADAPTERATTRIBUTES, *PHBA_ADAPTERATTRIBUTES; + +/* 4.2.8 Port Attributes */ +typedef struct HBA_PortAttributes { + HBA_WWN NodeWWN; + HBA_WWN PortWWN; + HBA_UINT32 PortFcId; + HBA_PORTTYPE PortType; /*PTP, Fabric, etc. */ + HBA_PORTSTATE PortState; + HBA_COS PortSupportedClassofService; + HBA_FC4TYPES PortSupportedFc4Types; + HBA_FC4TYPES PortActiveFc4Types; + char PortSymbolicName[256]; + char OSDeviceName[256]; /* \device\ScsiPort3 */ + HBA_PORTSPEED PortSupportedSpeed; + HBA_PORTSPEED PortSpeed; + HBA_UINT32 PortMaxFrameSize; + HBA_WWN FabricName; + HBA_UINT32 NumberofDiscoveredPorts; +} HBA_PORTATTRIBUTES, *PHBA_PORTATTRIBUTES; + + + +/* 4.2.9 Port Statistics */ + +typedef struct HBA_PortStatistics { + HBA_INT64 SecondsSinceLastReset; + HBA_INT64 TxFrames; + HBA_INT64 TxWords; + HBA_INT64 RxFrames; + HBA_INT64 RxWords; + HBA_INT64 LIPCount; + HBA_INT64 NOSCount; + HBA_INT64 ErrorFrames; + HBA_INT64 DumpedFrames; + HBA_INT64 LinkFailureCount; + HBA_INT64 LossOfSyncCount; + HBA_INT64 LossOfSignalCount; + HBA_INT64 PrimitiveSeqProtocolErrCount; + HBA_INT64 InvalidTxWordCount; + HBA_INT64 InvalidCRCCount; +} HBA_PORTSTATISTICS, *PHBA_PORTSTATISTICS; + + + +/* 4.2.10 FCP Attributes */ + +typedef enum HBA_fcpbindingtype { TO_D_ID, TO_WWN } HBA_FCPBINDINGTYPE; + +typedef struct HBA_ScsiId { + char OSDeviceName[256]; /* \device\ScsiPort3 */ + HBA_UINT32 ScsiBusNumber; /* Bus on the HBA */ + HBA_UINT32 ScsiTargetNumber; /* SCSI Target ID to OS */ + HBA_UINT32 ScsiOSLun; +} HBA_SCSIID, *PHBA_SCSIID; + +typedef struct HBA_FcpId { + HBA_UINT32 FcId; + HBA_WWN NodeWWN; + HBA_WWN PortWWN; + HBA_UINT64 FcpLun; +} HBA_FCPID, *PHBA_FCPID; + +typedef struct HBA_FcpScsiEntry { + HBA_SCSIID ScsiId; + HBA_FCPID FcpId; +} HBA_FCPSCSIENTRY, *PHBA_FCPSCSIENTRY; + +typedef struct HBA_FCPTargetMapping { + HBA_UINT32 NumberOfEntries; + HBA_FCPSCSIENTRY entry[1]; /* Variable length array containing mappings*/ +} HBA_FCPTARGETMAPPING, *PHBA_FCPTARGETMAPPING; + +typedef struct HBA_FCPBindingEntry { + HBA_FCPBINDINGTYPE type; + HBA_SCSIID ScsiId; + HBA_FCPID FcpId; /* WWN valid only if type is to WWN, FcpLun always valid */ + HBA_UINT32 FcId; /* valid only if type is to DID */ +} HBA_FCPBINDINGENTRY, *PHBA_FCPBINDINGENTRY; + +typedef struct HBA_FCPBinding { + HBA_UINT32 NumberOfEntries; + HBA_FCPBINDINGENTRY entry[1]; /* Variable length array */ +} HBA_FCPBINDING, *PHBA_FCPBINDING; + +/* 4.2.11 FC-3 Management Atrributes */ + +typedef enum HBA_wwntype { NODE_WWN, PORT_WWN } HBA_WWNTYPE; + +typedef struct HBA_MgmtInfo { + HBA_WWN wwn; + HBA_UINT32 unittype; + HBA_UINT32 PortId; + HBA_UINT32 NumberOfAttachedNodes; + HBA_UINT16 IPVersion; + HBA_UINT16 UDPPort; + HBA_UINT8 IPAddress[16]; + HBA_UINT16 reserved; + HBA_UINT16 TopologyDiscoveryFlags; +} HBA_MGMTINFO, *PHBA_MGMTINFO; + +#define HBA_EVENT_LIP_OCCURRED 1 +#define HBA_EVENT_LINK_UP 2 +#define HBA_EVENT_LINK_DOWN 3 +#define HBA_EVENT_LIP_RESET_OCCURRED 4 +#define HBA_EVENT_RSCN 5 +#define HBA_EVENT_PROPRIETARY 0xFFFF + +typedef struct HBA_Link_EventInfo { + HBA_UINT32 PortFcId; /* Port which this event occurred */ + HBA_UINT32 Reserved[3]; +} HBA_LINK_EVENTINFO, *PHBA_LINK_EVENTINFO; + +typedef struct HBA_RSCN_EventInfo { + HBA_UINT32 PortFcId; /* Port which this event occurred */ + HBA_UINT32 NPortPage; /* Reference FC-FS for RSCN ELS "Affected N-Port Pages"*/ + HBA_UINT32 Reserved[2]; +} HBA_RSCN_EVENTINFO, *PHBA_RSCN_EVENTINFO; + +typedef struct HBA_Pty_EventInfo { + HBA_UINT32 PtyData[4]; /* Proprietary data */ +} HBA_PTY_EVENTINFO, *PHBA_PTY_EVENTINFO; + +typedef struct HBA_EventInfo { + HBA_UINT32 EventCode; + union { + HBA_LINK_EVENTINFO Link_EventInfo; + HBA_RSCN_EVENTINFO RSCN_EventInfo; + HBA_PTY_EVENTINFO Pty_EventInfo; + } Event; +} HBA_EVENTINFO, *PHBA_EVENTINFO; + +/* Used for OSDeviceName */ +typedef struct HBA_osdn { + char drvname[32]; + HBA_UINT32 instance; + HBA_UINT32 target; + HBA_UINT32 lun; + HBA_UINT32 bus; + char flags; + char sizeSN; + char InquirySN[32]; +} HBA_OSDN; + +/* Function Prototypes */ +#if (!defined(_KERNEL) && !defined(__KERNEL__)) +uint32 GetAdapterAttributes(uint32, HBA_ADAPTERATTRIBUTES *); +uint32 GetAdapterPortAttributes(uint32, HBA_UINT32, HBA_PORTATTRIBUTES *); +uint32 GetPortStatistics(uint32, HBA_UINT32, HBA_PORTSTATISTICS *); +uint32 GetDiscoveredPortAttributes(uint32, HBA_UINT32, HBA_UINT32, HBA_PORTATTRIBUTES *); +uint32 GetPortAttributesByWWN(uint32, HBA_WWN *, HBA_PORTATTRIBUTES *); +uint32 GetPortAttributesByIndex(uint32, HBA_UINT32, HBA_UINT32, HBA_PORTATTRIBUTES *); +uint32 GetEventBuffer(uint32, PHBA_EVENTINFO, HBA_UINT32 *); +uint32 SetRNIDMgmtInfo(uint32, HBA_MGMTINFO *); +uint32 GetRNIDMgmtInfo(uint32, HBA_MGMTINFO *); +uint32 SendRNID(uint32, HBA_WWN *, HBA_WWNTYPE, void *, HBA_UINT32 *); +void ResetStatistics(uint32, HBA_UINT32); +uint32 RefreshInformation(uint32); +uint32 GetFcpTargetMapping(uint32, PHBA_FCPTARGETMAPPING); +uint32 GetFcpPersistentBinding(uint32, PHBA_FCPBINDING); +uint32 SendCTPassThru(uint32, void *, HBA_UINT32, void *, HBA_UINT32 *); +uint32 SendReportLUNs(uint32, HBA_WWN *, void *, HBA_UINT32 *, void *, + HBA_UINT32 *); +uint32 SendReadCapacity(uint32, HBA_WWN *, HBA_UINT64, void *, HBA_UINT32 *, + void *, HBA_UINT32 *); +uint32 SendScsiInquiry(uint32, HBA_WWN *, HBA_UINT64, HBA_UINT8, HBA_UINT32, + void *, HBA_UINT32 *, void *, HBA_UINT32 *); +#endif + + +#endif + diff -purN -X /home/mbligh/.diff.exclude 350-autoswap/drivers/scsi/lpfc/lp6000.c 370-emulex/drivers/scsi/lpfc/lp6000.c --- 350-autoswap/drivers/scsi/lpfc/lp6000.c 1969-12-31 16:00:00.000000000 -0800 +++ 370-emulex/drivers/scsi/lpfc/lp6000.c 2004-02-28 11:20:05.000000000 -0800 @@ -0,0 +1,2696 @@ +/******************************************************************* + * This file is part of the Emulex Linux Device Driver for * + * Enterprise Fibre Channel Host Bus Adapters. * + * Refer to the README file included with this package for * + * driver version and adapter support. * + * Copyright (C) 2003 Emulex Corporation. * + * www.emulex.com * + * * + * This program is free software; you can redistribute it and/or * + * modify it under the terms of the GNU General Public License * + * as published by the Free Software Foundation; either version 2 * + * of the License, or (at your option) any later version. * + * * + * This program is distributed in the hope that it will be useful, * + * but WITHOUT ANY WARRANTY; without even the implied warranty of * + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * + * GNU General Public License for more details, a copy of which * + * can be found in the file COPYING included with this package. * + *******************************************************************/ + +/* Routine Declaration - Local */ +_local_ int fc_binfo_init(fc_dev_ctl_t *p_dev_ctl); +_local_ int fc_parse_vpd(fc_dev_ctl_t *p_dev_ctl, uchar *vpd); +_local_ int fc_proc_ring_event( fc_dev_ctl_t *p_dev_ctl, RING *rp, + IOCBQ *saveq); +/* End Routine Declaration - Local */ +extern uint32 fcPAGESIZE; +extern uint32 fc_diag_state; +extern int fcinstance[]; + +int fc_check_for_vpd = 1; +int fc_reset_on_attach = 0; + +extern int fc_max_els_sent; + +#define FC_MAX_VPD_SIZE 0x100 +static uint32 fc_vpd_data[FC_MAX_VPD_SIZE]; + +static uint32 fc_run_biu_test[256] = { + /* Walking ones */ + 0x80000000, 0x40000000, 0x20000000, 0x10000000, + 0x08000000, 0x04000000, 0x02000000, 0x01000000, + 0x00800000, 0x00400000, 0x00200000, 0x00100000, + 0x00080000, 0x00040000, 0x00020000, 0x00010000, + 0x00008000, 0x00004000, 0x00002000, 0x00001000, + 0x00000800, 0x00000400, 0x00000200, 0x00000100, + 0x00000080, 0x00000040, 0x00000020, 0x00000010, + 0x00000008, 0x00000004, 0x00000002, 0x00000001, + + /* Walking zeros */ + 0x7fffffff, 0xbfffffff, 0xdfffffff, 0xefffffff, + 0xf7ffffff, 0xfbffffff, 0xfdffffff, 0xfeffffff, + 0xff7fffff, 0xffbfffff, 0xffdfffff, 0xffefffff, + 0xfff7ffff, 0xfffbffff, 0xfffdffff, 0xfffeffff, + 0xffff7fff, 0xffffbfff, 0xffffdfff, 0xffffefff, + 0xfffff7ff, 0xfffffbff, 0xfffffdff, 0xfffffeff, + 0xffffff7f, 0xffffffbf, 0xffffffdf, 0xffffffef, + 0xfffffff7, 0xfffffffb, 0xfffffffd, 0xfffffffe, + + /* all zeros */ + 0x00000000, 0x00000000, 0x00000000, 0x00000000, + 0x00000000, 0x00000000, 0x00000000, 0x00000000, + 0x00000000, 0x00000000, 0x00000000, 0x00000000, + 0x00000000, 0x00000000, 0x00000000, 0x00000000, + 0x00000000, 0x00000000, 0x00000000, 0x00000000, + 0x00000000, 0x00000000, 0x00000000, 0x00000000, + 0x00000000, 0x00000000, 0x00000000, 0x00000000, + 0x00000000, 0x00000000, 0x00000000, 0x00000000, + + /* all ones */ + 0xffffffff, 0xffffffff, 0xffffffff, 0xffffffff, + 0xffffffff, 0xffffffff, 0xffffffff, 0xffffffff, + 0xffffffff, 0xffffffff, 0xffffffff, 0xffffffff, + 0xffffffff, 0xffffffff, 0xffffffff, 0xffffffff, + 0xffffffff, 0xffffffff, 0xffffffff, 0xffffffff, + 0xffffffff, 0xffffffff, 0xffffffff, 0xffffffff, + 0xffffffff, 0xffffffff, 0xffffffff, 0xffffffff, + 0xffffffff, 0xffffffff, 0xffffffff, 0xffffffff, + + /* all 5's */ + 0x55555555, 0x55555555, 0x55555555, 0x55555555, + 0x55555555, 0x55555555, 0x55555555, 0x55555555, + 0x55555555, 0x55555555, 0x55555555, 0x55555555, + 0x55555555, 0x55555555, 0x55555555, 0x55555555, + 0x55555555, 0x55555555, 0x55555555, 0x55555555, + 0x55555555, 0x55555555, 0x55555555, 0x55555555, + 0x55555555, 0x55555555, 0x55555555, 0x55555555, + 0x55555555, 0x55555555, 0x55555555, 0x55555555, + + /* all a's */ + 0xaaaaaaaa, 0xaaaaaaaa, 0xaaaaaaaa, 0xaaaaaaaa, + 0xaaaaaaaa, 0xaaaaaaaa, 0xaaaaaaaa, 0xaaaaaaaa, + 0xaaaaaaaa, 0xaaaaaaaa, 0xaaaaaaaa, 0xaaaaaaaa, + 0xaaaaaaaa, 0xaaaaaaaa, 0xaaaaaaaa, 0xaaaaaaaa, + 0xaaaaaaaa, 0xaaaaaaaa, 0xaaaaaaaa, 0xaaaaaaaa, + 0xaaaaaaaa, 0xaaaaaaaa, 0xaaaaaaaa, 0xaaaaaaaa, + 0xaaaaaaaa, 0xaaaaaaaa, 0xaaaaaaaa, 0xaaaaaaaa, + 0xaaaaaaaa, 0xaaaaaaaa, 0xaaaaaaaa, 0xaaaaaaaa, + + /* all 5a's */ + 0x5a5a5a5a, 0x5a5a5a5a, 0x5a5a5a5a, 0x5a5a5a5a, + 0x5a5a5a5a, 0x5a5a5a5a, 0x5a5a5a5a, 0x5a5a5a5a, + 0x5a5a5a5a, 0x5a5a5a5a, 0x5a5a5a5a, 0x5a5a5a5a, + 0x5a5a5a5a, 0x5a5a5a5a, 0x5a5a5a5a, 0x5a5a5a5a, + 0x5a5a5a5a, 0x5a5a5a5a, 0x5a5a5a5a, 0x5a5a5a5a, + 0x5a5a5a5a, 0x5a5a5a5a, 0x5a5a5a5a, 0x5a5a5a5a, + 0x5a5a5a5a, 0x5a5a5a5a, 0x5a5a5a5a, 0x5a5a5a5a, + 0x5a5a5a5a, 0x5a5a5a5a, 0x5a5a5a5a, 0x5a5a5a5a, + + /* all a5's */ + 0xa5a5a5a5, 0xa5a5a5a5, 0xa5a5a5a5, 0xa5a5a5a5, + 0xa5a5a5a5, 0xa5a5a5a5, 0xa5a5a5a5, 0xa5a5a5a5, + 0xa5a5a5a5, 0xa5a5a5a5, 0xa5a5a5a5, 0xa5a5a5a5, + 0xa5a5a5a5, 0xa5a5a5a5, 0xa5a5a5a5, 0xa5a5a5a5, + 0xa5a5a5a5, 0xa5a5a5a5, 0xa5a5a5a5, 0xa5a5a5a5, + 0xa5a5a5a5, 0xa5a5a5a5, 0xa5a5a5a5, 0xa5a5a5a5, + 0xa5a5a5a5, 0xa5a5a5a5, 0xa5a5a5a5, 0xa5a5a5a5, + 0xa5a5a5a5, 0xa5a5a5a5, 0xa5a5a5a5, 0xa5a5a5a5 +}; + +extern _static_ void fc_read_nv(FC_BRD_INFO *binfo, MAILBOX *mb); +#define S(N,V) (((V)<<(N))|((V)>>(32-(N)))) +#define BYTESWAP(x) ((x<<24) | (x >> 24) | (0xFF00 & (x >> 8)) | (0xFF0000 & (x << 8))); + +/************************************************************************/ +/* */ +/* fc_swap_bcopy */ +/* */ +/************************************************************************/ +_static_ void +fc_swap_bcopy( +uint32 *src, +uint32 *dest, +uint32 cnt) +{ + uint32 ldata; + int i; + + for (i = 0; i < (int)cnt; i += sizeof(uint32)) { + ldata = *src++; + ldata = cpu_to_be32(ldata); + *dest++ = ldata; + } +} /* End fc_swap_bcopy */ + +/************************************************************************/ +/* */ +/* fc_init_hba */ +/* */ +/************************************************************************/ +uint32 +fc_init_hba( +fc_dev_ctl_t * p_dev_ctl, +MAILBOX * mb, +uint32 * pwwnn) +{ + FC_BRD_INFO * binfo; + uint32 * pText; + char licensed[56] = "key unlock for use with gnu public licensed code only\0"; + pText = (uint32 *) licensed; + fc_swap_bcopy(pText, pText, 56); + binfo = &BINFO; + /* Setup and issue mailbox READ NVPARAMS command */ + binfo->fc_ffstate = FC_INIT_NVPARAMS; + fc_read_nv(binfo, mb); + memset((void*) mb->un.varRDnvp.rsvd3, 0, sizeof(mb->un.varRDnvp.rsvd3)); + memcpy((void*) mb->un.varRDnvp.rsvd3, licensed, sizeof(licensed)); + if (issue_mb_cmd(binfo, mb, MBX_POLL) != MBX_SUCCESS) { + /* Adapter initialization error, mbxCmd READ_NVPARM, mbxStatus */ + fc_log_printf_msg_vargs( binfo->fc_brd_no, + &fc_msgBlk0303, /* ptr to msg structure */ + fc_mes0303, /* ptr to msg */ + fc_msgBlk0303.msgPreambleStr, /* begin varargs */ + mb->mbxCommand, + mb->mbxStatus); /* end varargs */ + return(0); + } + fc_bcopy ((uchar*)mb->un.varRDnvp.nodename, (uchar*) pwwnn, sizeof(mb->un.varRDnvp.nodename)); + return(1); +} + +/************************************************************************/ +/* */ +/* sha_initialize */ +/* */ +/************************************************************************/ +void +sha_initialize( +uint32 *HashResultPointer) +{ + HashResultPointer[0] = 0x67452301; + HashResultPointer[1] = 0xEFCDAB89; + HashResultPointer[2] = 0x98BADCFE; + HashResultPointer[3] = 0x10325476; + HashResultPointer[4] = 0xC3D2E1F0; +} +/************************************************************************/ +/* */ +/* sha_iterate */ +/* */ +/************************************************************************/ +void +sha_iterate( +uint32 *HashResultPointer, +uint32 *HashWorkingPointer) +{ + int t; + uint32 TEMP; + uint32 A, B, C, D, E; + t = 16; + do + { + HashWorkingPointer[t] = S(1,HashWorkingPointer[t-3]^HashWorkingPointer[t-8]^HashWorkingPointer[t-14]^HashWorkingPointer[t-16]); + } while (++t <= 79); + t = 0; + A = HashResultPointer[0]; + B = HashResultPointer[1]; + C = HashResultPointer[2]; + D = HashResultPointer[3]; + E = HashResultPointer[4]; + + do + { + if (t < 20) + { + TEMP = ((B & C) | ((~B) & D)) + 0x5A827999; + } else if (t < 40) { + TEMP = (B ^ C ^ D) + 0x6ED9EBA1; + } else if (t < 60) { + TEMP = ((B & C) | (B & D) | (C & D)) + 0x8F1BBCDC; + } else { + TEMP = (B ^ C ^ D) + 0xCA62C1D6; + } + TEMP += S(5,A) + E + HashWorkingPointer[t]; + E = D; + D = C; + C = S(30,B); + B = A; + A = TEMP; + } while (++t <= 79); + + HashResultPointer[0] += A; + HashResultPointer[1] += B; + HashResultPointer[2] += C; + HashResultPointer[3] += D; + HashResultPointer[4] += E; + +} +/************************************************************************/ +/* */ +/* Challenge_XOR_KEY */ +/* */ +/************************************************************************/ +void +Challenge_XOR_KEY +(uint32 *RandomChallenge, + uint32 *HashWorking) +{ + *HashWorking = (*RandomChallenge ^ *HashWorking); +} + +/************************************************************************/ +/* */ +/* fc_SHA1 */ +/* */ +/************************************************************************/ +void +fc_SHA1( +uint32 * pwwnn, +uint32 * phbainitEx, +uint32 * RandomData) +{ + int t; + uint32 HashWorking[80]; + + fc_bzero(HashWorking, sizeof(HashWorking)); + HashWorking[0] = HashWorking[78] = *pwwnn++; + HashWorking[1] = HashWorking[79] = *pwwnn; + for (t = 0; t < 7 ; t++) { + Challenge_XOR_KEY(RandomData+t,HashWorking+t); + } + sha_initialize(phbainitEx); + sha_iterate(phbainitEx, HashWorking); +} + +/************************************************************************/ +/* */ +/* fc_ffinit */ +/* */ +/************************************************************************/ +_static_ int +fc_ffinit( +fc_dev_ctl_t *p_dev_ctl) +{ + FC_BRD_INFO * binfo; + iCfgParam * clp; + fc_vpd_t * vp; + uint32 status, i, j; + uint32 read_rev_reset, hbainit = 0; + uint32 RandomData[7]; + uint32 hbainitEx[5]; + uint32 wwnn[2]; + struct pci_dev *pdev; + int ipri, flogi_sent; + MBUF_INFO bufinfo; + MBUF_INFO * buf_info; + void * ioa; + RING * rp; + MAILBOX * mb; + MATCHMAP * mp, *mp1, *mp2; + uchar * inptr, *outptr; + + binfo = &BINFO; + clp = DD_CTL.p_config[binfo->fc_brd_no]; + vp = &VPD; + mb = 0; + + pdev = p_dev_ctl->pcidev ; + /* Set board state to initialization started */ + binfo->fc_ffstate = FC_INIT_START; + read_rev_reset = 0; + + if(fc_reset_on_attach) { + binfo->fc_ffstate = 0; + fc_brdreset(p_dev_ctl); + binfo->fc_ffstate = FC_INIT_START; + DELAYMS(2500); + } + +top: + ioa = (void *)FC_MAP_IO(&binfo->fc_iomap_io); /* map in io registers */ + +#if LITTLE_ENDIAN_HOST + /* For Little Endian, BIU_BSE is not supported */ +#else +#ifdef BIU_BSE + status = READ_CSR_REG(binfo, FC_BC_REG(binfo, ioa)); + WRITE_CSR_REG(binfo, FC_BC_REG(binfo, ioa), (BC_BSE_SWAP | status)); + i = READ_CSR_REG(binfo, FC_BC_REG(binfo, ioa)); +#endif +#endif + + status = READ_CSR_REG(binfo, FC_STAT_REG(binfo, ioa)); + FC_UNMAP_MEMIO(ioa); + + i = 0; + + /* Check status register to see what current state is */ + while ((status & (HS_FFRDY | HS_MBRDY)) != (HS_FFRDY | HS_MBRDY)) { + + /* Check every 100ms for 5 retries, then every 500ms for 5, then + * every 2.5 sec for 5, then reset board and every 2.5 sec for 4. + */ + if (i++ >= 20) { + /* Adapter failed to init, timeout, status reg */ + fc_log_printf_msg_vargs( binfo->fc_brd_no, + &fc_msgBlk0436, /* ptr to msg structure */ + fc_mes0436, /* ptr to msg */ + fc_msgBlk0436.msgPreambleStr, /* begin varargs */ + status); /* end varargs */ + binfo->fc_ffstate = FC_ERROR; + return(EIO); + } + + /* Check to see if any errors occurred during init */ + if (status & HS_FFERM) { + /* ERROR: During chipset initialization */ + /* Adapter failed to init, chipset, status reg */ + fc_log_printf_msg_vargs( binfo->fc_brd_no, + &fc_msgBlk0437, /* ptr to msg structure */ + fc_mes0437, /* ptr to msg */ + fc_msgBlk0437.msgPreambleStr, /* begin varargs */ + status); /* end varargs */ + binfo->fc_ffstate = FC_ERROR; + return(EIO); + } + + if (i <= 5) { + DELAYMS(100); + } + else if (i <= 10) { + DELAYMS(500); + } + else { + DELAYMS(2500); + } + + if (i == 15) { + /* Reset board and try one more time */ + binfo->fc_ffstate = 0; + fc_brdreset(p_dev_ctl); + binfo->fc_ffstate = FC_INIT_START; + } + + ioa = (void *)FC_MAP_IO(&binfo->fc_iomap_io); /* map in io registers */ + status = READ_CSR_REG(binfo, FC_STAT_REG(binfo, ioa)); + FC_UNMAP_MEMIO(ioa); + } + + /* Check to see if any errors occurred during init */ + if (status & HS_FFERM) { + /* ERROR: During chipset initialization */ + /* Adapter failed to init, chipset, status reg */ + fc_log_printf_msg_vargs( binfo->fc_brd_no, + &fc_msgBlk0438, /* ptr to msg structure */ + fc_mes0438, /* ptr to msg */ + fc_msgBlk0438.msgPreambleStr, /* begin varargs */ + status); /* end varargs */ + binfo->fc_ffstate = FC_ERROR; + return(EIO); + } + + ioa = (void *)FC_MAP_IO(&binfo->fc_iomap_io); /* map in io registers */ + + /* Clear all interrupt enable conditions */ + WRITE_CSR_REG(binfo, FC_HC_REG(binfo, ioa), 0); + + /* setup host attn register */ + WRITE_CSR_REG(binfo, FC_HA_REG(binfo, ioa), 0xffffffff); + + FC_UNMAP_MEMIO(ioa); + + if(read_rev_reset) + goto do_read_rev; + + fc_binfo_init(p_dev_ctl); + + /* Allocate some memory for buffers */ + if (fc_malloc_buffer(p_dev_ctl) == 0) { + binfo->fc_ffstate = FC_ERROR; + return(ENOMEM); + } + + fc_get_dds_bind(p_dev_ctl); + + /* Get a buffer which will be used repeatedly for mailbox commands */ + if ((mb = (MAILBOX * )fc_mem_get(binfo, MEM_MBOX | MEM_PRI)) == 0) { + binfo->fc_ffstate = FC_ERROR; + fc_free_buffer(p_dev_ctl); + return(ENOMEM); + } + +do_read_rev: + if((pdev->device == PCI_DEVICE_ID_TFLY)|| + (pdev->device == PCI_DEVICE_ID_PFLY)) + hbainit = fc_init_hba(p_dev_ctl, mb, wwnn); + /* Setup and issue mailbox READ REV command */ + binfo->fc_ffstate = FC_INIT_REV; + fc_read_rev(binfo, mb); + if (issue_mb_cmd(binfo, mb, MBX_POLL) != MBX_SUCCESS) { + /* Adapter failed to init, mbxCmd READ_REV, mbxStatus */ + fc_log_printf_msg_vargs( binfo->fc_brd_no, + &fc_msgBlk0439, /* ptr to msg structure */ + fc_mes0439, /* ptr to msg */ + fc_msgBlk0439.msgPreambleStr, /* begin varargs */ + mb->mbxCommand, + mb->mbxStatus); /* end varargs */ + + /* If read_rev fails, give it one more chance */ + if(read_rev_reset == 0) { + binfo->fc_ffstate = 0; + fc_brdreset(p_dev_ctl); + binfo->fc_ffstate = FC_INIT_START; + + DELAYMS(2500); + DELAYMS(2500); + + read_rev_reset = 1; + goto top; + } + binfo->fc_ffstate = FC_ERROR; + fc_mem_put(binfo, MEM_MBOX, (uchar * )mb); + fc_free_buffer(p_dev_ctl); + return(EIO); + } + + if(mb->un.varRdRev.rr == 0) { + + if(read_rev_reset == 0) { + binfo->fc_ffstate = 0; + fc_brdreset(p_dev_ctl); + binfo->fc_ffstate = FC_INIT_START; + + DELAYMS(2500); + DELAYMS(2500); + + read_rev_reset = 1; + goto top; + } + + vp->rev.rBit = 0; + fc_log_printf_msg_vargs( binfo->fc_brd_no, + &fc_msgBlk0440, /* ptr to msg structure */ + fc_mes0440, /* ptr to msg */ + fc_msgBlk0440.msgPreambleStr, /* begin varargs */ + mb->mbxCommand, + read_rev_reset); /* end varargs */ + } + else { + if(mb->un.varRdRev.un.b.ProgType != 2) { + if(read_rev_reset == 0) { + binfo->fc_ffstate = 0; + fc_brdreset(p_dev_ctl); + binfo->fc_ffstate = FC_INIT_START; + + DELAYMS(2500); + DELAYMS(2500); + + read_rev_reset = 1; + goto top; + } + } + vp->rev.rBit = 1; + vp->rev.sli1FwRev = mb->un.varRdRev.sli1FwRev; + fc_bcopy((uchar *)mb->un.varRdRev.sli1FwName, (uchar *)vp->rev.sli1FwName, 16); + vp->rev.sli2FwRev = mb->un.varRdRev.sli2FwRev; + fc_bcopy((uchar *)mb->un.varRdRev.sli2FwName, (uchar *)vp->rev.sli2FwName, 16); + } + + /* Save information as VPD data */ + vp->rev.biuRev = mb->un.varRdRev.biuRev; + vp->rev.smRev = mb->un.varRdRev.smRev; + vp->rev.smFwRev = mb->un.varRdRev.un.smFwRev; + vp->rev.endecRev = mb->un.varRdRev.endecRev; + vp->rev.fcphHigh = mb->un.varRdRev.fcphHigh; + vp->rev.fcphLow = mb->un.varRdRev.fcphLow; + vp->rev.feaLevelHigh = mb->un.varRdRev.feaLevelHigh; + vp->rev.feaLevelLow = mb->un.varRdRev.feaLevelLow; + vp->rev.postKernRev = mb->un.varRdRev.postKernRev; + vp->rev.opFwRev = mb->un.varRdRev.opFwRev; + if((pdev->device == PCI_DEVICE_ID_TFLY)|| + (pdev->device == PCI_DEVICE_ID_PFLY)) + fc_bcopy((uchar *)&mb->un.varWords[24], (uchar *)RandomData, sizeof(RandomData)); + + dfc_fmw_rev(p_dev_ctl); /* Save firmware rev for HBAAPI */ + + if(fc_check_for_vpd) { + /* Get adapter VPD information */ + fc_dump_mem(binfo, mb); + if (issue_mb_cmd(binfo, mb, MBX_POLL) != MBX_SUCCESS) { + /* + * Let it go through even if failed. + */ + /* Adapter failed to init, mbxCmd DUMP VPD, mbxStatus */ + fc_log_printf_msg_vargs( binfo->fc_brd_no, + &fc_msgBlk0441, /* ptr to msg structure */ + fc_mes0441, /* ptr to msg */ + fc_msgBlk0441.msgPreambleStr, /* begin varargs */ + mb->mbxCommand, + mb->mbxStatus); /* end varargs */ + + /* If dump_mem times out, give it one more chance */ + if((read_rev_reset == 0) && (mb->mbxStatus == 0)) { + binfo->fc_ffstate = 0; + fc_brdreset(p_dev_ctl); + binfo->fc_ffstate = FC_INIT_START; + + DELAYMS(2500); + DELAYMS(2500); + + read_rev_reset = 1; + goto top; + } + } + else { + if((mb->un.varDmp.ra == 1) && + (mb->un.varDmp.word_cnt <= FC_MAX_VPD_SIZE)) { + uint32 *lp1, *lp2; + + lp1 = (uint32 * )&mb->un.varDmp.resp_offset; + lp2 = (uint32 * )&fc_vpd_data[0]; + for(i=0;iun.varDmp.word_cnt;i++) { + status = *lp1++; + *lp2++ = SWAP_LONG(status); + } + fc_parse_vpd(p_dev_ctl, (uchar *)&fc_vpd_data[0]); + } + } + } + + /* Setup and issue mailbox CONFIG_PORT or PARTITION_SLIM command */ + binfo->fc_ffstate = FC_INIT_PARTSLIM; + if (binfo->fc_sli == 2) { + if((pdev->device == PCI_DEVICE_ID_TFLY)|| + (pdev->device == PCI_DEVICE_ID_PFLY)){ + fc_SHA1(wwnn, hbainitEx, RandomData); + fc_config_port(binfo, mb, (uint32 *) hbainitEx); + } + else + fc_config_port(binfo, mb, &hbainit); + if (issue_mb_cmd(binfo, mb, MBX_POLL) != MBX_SUCCESS) { + /* Adapter failed to init, mbxCmd CONFIG_PORT, mbxStatus */ + fc_log_printf_msg_vargs( binfo->fc_brd_no, + &fc_msgBlk0442, /* ptr to msg structure */ + fc_mes0442, /* ptr to msg */ + fc_msgBlk0442.msgPreambleStr, /* begin varargs */ + mb->mbxCommand, + mb->mbxStatus, + 0); /* end varargs */ + + /* If config_port fails, give it one more chance */ + if(read_rev_reset == 0) { + binfo->fc_ffstate = 0; + fc_brdreset(p_dev_ctl); + binfo->fc_ffstate = FC_INIT_START; + + DELAYMS(2500); + DELAYMS(2500); + + read_rev_reset = 1; + goto top; + } + + binfo->fc_flag &= ~FC_SLI2; + binfo->fc_mboxaddr = 0; + if (binfo->fc_slim2.virt) { + buf_info = &bufinfo; + if (binfo->fc_slim2.phys) { + buf_info->phys = (void * )binfo->fc_slim2.phys; + buf_info->data_handle = binfo->fc_slim2.data_handle; + buf_info->dma_handle = binfo->fc_slim2.dma_handle; + buf_info->flags = FC_MBUF_DMA; + } else { + buf_info->phys = 0; + buf_info->data_handle = 0; + buf_info->dma_handle = 0; + buf_info->flags = 0; + } + buf_info->size = fcPAGESIZE; + buf_info->virt = (void * )binfo->fc_slim2.virt; + fc_free(p_dev_ctl, buf_info); + binfo->fc_slim2.virt = 0; + binfo->fc_slim2.phys = 0; + binfo->fc_slim2.dma_handle = 0; + binfo->fc_slim2.data_handle = 0; + } + binfo->fc_ffstate = FC_ERROR; + fc_mem_put(binfo, MEM_MBOX, (uchar * )mb); + fc_free_buffer(p_dev_ctl); + return(EIO); + } + } else { + /* SLI1 not supported, mbxCmd , mbxStatus */ + fc_log_printf_msg_vargs( binfo->fc_brd_no, + &fc_msgBlk0443, /* ptr to msg structure */ + fc_mes0443, /* ptr to msg */ + fc_msgBlk0443.msgPreambleStr, /* begin varargs */ + mb->mbxCommand, + mb->mbxStatus, + 0); /* end varargs */ + binfo->fc_ffstate = FC_ERROR; + fc_mem_put(binfo, MEM_MBOX, (uchar * )mb); + fc_free_buffer(p_dev_ctl); + return(EIO); + } + + /* Initialize cmd/rsp ring pointers */ + for (i = 0; i < (uint32)binfo->fc_ffnumrings; i++) { + rp = &binfo->fc_ring[i]; + + rp->fc_ringno = (uchar)i; + rp->fc_xmitstate = FC_LINK_UP; + if ((i == FC_IP_RING) || (i == FC_FCP_RING)) + rp->fc_xmitstate = FC_READY; + rp->fc_binfo = (uchar * )binfo; + rp->fc_iocbhd = 0; + rp->fc_iocbtl = 0; + rp->fc_cmdidx = 0; + rp->fc_rspidx = 0; + rp->fc_iotag = 1; /* used to identify each I/O */ + if (i == FC_FCP_RING) + rp->fc_bufcnt = MAX_FCP_CMDS; /* Used for ABTS iotag */ + + /* offsets are from the beginning of SLIM */ + if (!(binfo->fc_flag & FC_SLI2)) { + /* offsets are from the beginning of SLIM */ + rp->fc_cmdringaddr = (void *)((ulong)(mb->un.varSlim.ringdef[i].offCiocb)); + rp->fc_rspringaddr = (void *)((ulong)(mb->un.varSlim.ringdef[i].offRiocb)); + + } + } + + mp1 = 0; + mp2 = 0; + /* Setup and issue mailbox RUN BIU DIAG command */ + /* setup test buffers */ + if (((mp = (MATCHMAP * )fc_mem_get(binfo, MEM_BUF | MEM_PRI)) == 0) || + ((mp1 = (MATCHMAP * )fc_mem_get(binfo, MEM_BUF | MEM_PRI)) == 0) || + ((mp2 = (MATCHMAP * )fc_mem_get(binfo, MEM_BUF | MEM_PRI)) == 0)) { + /* Adapter failed to init, no buffers for RUN_BIU_DIAG */ + fc_log_printf_msg_vargs( binfo->fc_brd_no, + &fc_msgBlk0444, /* ptr to msg structure */ + fc_mes0444, /* ptr to msg */ + fc_msgBlk0444.msgPreambleStr); /* begin & end varargs */ + if (mp) + fc_mem_put(binfo, MEM_BUF, (uchar * )mp); + if (mp1) + fc_mem_put(binfo, MEM_BUF, (uchar * )mp1); + binfo->fc_ffstate = FC_ERROR; + fc_mem_put(binfo, MEM_MBOX, (uchar * )mb); + fc_free_buffer(p_dev_ctl); + return(ENOMEM); + } + + fc_mpdata_incopy(p_dev_ctl, mp, (uchar * ) & fc_run_biu_test[0], FCELSSIZE); + fc_mpdata_sync(mp->dma_handle, 0, 0, DDI_DMA_SYNC_FORDEV); + inptr = mp->virt; + /* Issue mailbox command */ + fc_runBIUdiag(binfo, mb, mp->phys, mp1->phys); + if (issue_mb_cmd(binfo, mb, MBX_POLL) != MBX_SUCCESS) { + ioa = (void *)FC_MAP_IO(&binfo->fc_iomap_io); /* map in io registers */ + FC_UNMAP_MEMIO(ioa); + /* Adapter failed init, mailbox cmd runBIUdiag mbxStatus */ + fc_log_printf_msg_vargs( binfo->fc_brd_no, + &fc_msgBlk0447, /* ptr to msg structure */ + fc_mes0447, /* ptr to msg */ + fc_msgBlk0447.msgPreambleStr, /* begin varargs */ + mb->mbxCommand, + mb->mbxStatus); /* end varargs */ + fc_mem_put(binfo, MEM_BUF, (uchar * )mp); + fc_mem_put(binfo, MEM_BUF, (uchar * )mp1); + fc_mem_put(binfo, MEM_BUF, (uchar * )mp2); + binfo->fc_ffstate = FC_ERROR; + fc_mem_put(binfo, MEM_MBOX, (uchar * )mb); + fc_free_buffer(p_dev_ctl); + return(EIO); + } + + fc_mpdata_sync(mp1->dma_handle, 0, 0, DDI_DMA_SYNC_FORKERNEL); + fc_mpdata_outcopy(p_dev_ctl, mp1, (uchar * )mp2->virt, FCELSSIZE); + outptr = (uchar * )mp2->virt; + + for (i = 0; i < FCELSSIZE; i++) { + if (*outptr++ != *inptr++) { + outptr--; + inptr--; + /* RUN_BIU_DIAG failed */ + fc_log_printf_msg_vargs( binfo->fc_brd_no, + &fc_msgBlk0445, /* ptr to msg structure */ + fc_mes0445, /* ptr to msg */ + fc_msgBlk0445.msgPreambleStr); /* begin & end varargs */ + fc_mem_put(binfo, MEM_BUF, (uchar * )mp); + fc_mem_put(binfo, MEM_BUF, (uchar * )mp1); + fc_mem_put(binfo, MEM_BUF, (uchar * )mp2); + binfo->fc_ffstate = FC_ERROR; + fc_mem_put(binfo, MEM_MBOX, (uchar * )mb); + fc_free_buffer(p_dev_ctl); + return(EIO); + } + } + fc_mem_put(binfo, MEM_BUF, (uchar * )mp); + fc_mem_put(binfo, MEM_BUF, (uchar * )mp1); + fc_mem_put(binfo, MEM_BUF, (uchar * )mp2); + + /* Setup and issue mailbox CONFIGURE RING command */ + for (i = 0; i < (uint32)binfo->fc_ffnumrings; i++) { + binfo->fc_ffstate = FC_INIT_CFGRING; + fc_config_ring(binfo, i, 0, mb); + if (issue_mb_cmd(binfo, mb, MBX_POLL) != MBX_SUCCESS) { + /* Adapter failed to init, mbxCmd CFG_RING, mbxStatus , ring */ + fc_log_printf_msg_vargs( binfo->fc_brd_no, + &fc_msgBlk0446, /* ptr to msg structure */ + fc_mes0446, /* ptr to msg */ + fc_msgBlk0446.msgPreambleStr, /* begin varargs */ + mb->mbxCommand, + mb->mbxStatus, + i); /* ring num - end varargs */ + binfo->fc_ffstate = FC_ERROR; + fc_mem_put(binfo, MEM_MBOX, (uchar * )mb); + fc_free_buffer(p_dev_ctl); + return(EIO); + } + } + + /* Setup link timers */ + fc_config_link(p_dev_ctl, mb); + if (issue_mb_cmd(binfo, mb, MBX_POLL) != MBX_SUCCESS) { + /* Adapter failed to init, mbxCmd CONFIG_LINK mbxStatus */ + fc_log_printf_msg_vargs( binfo->fc_brd_no, + &fc_msgBlk0447, /* ptr to msg structure */ + fc_mes0447, /* ptr to msg */ + fc_msgBlk0447.msgPreambleStr, /* begin varargs */ + mb->mbxCommand, + mb->mbxStatus); /* end varargs */ + binfo->fc_ffstate = FC_ERROR; + fc_ffcleanup(p_dev_ctl); + i_clear(&IHS); + fc_mem_put(binfo, MEM_MBOX, (uchar * )mb); + fc_free_buffer(p_dev_ctl); + return(EIO); + } + + /* We need to get login parameters for NID */ + fc_read_sparam(p_dev_ctl, mb); + if (issue_mb_cmd(binfo, mb, MBX_POLL) != MBX_SUCCESS) { + /* Adapter failed to init, mbxCmd READ_SPARM mbxStatus */ + fc_log_printf_msg_vargs( binfo->fc_brd_no, + &fc_msgBlk0448, /* ptr to msg structure */ + fc_mes0448, /* ptr to msg */ + fc_msgBlk0448.msgPreambleStr, /* begin varargs */ + mb->mbxCommand, + mb->mbxStatus); /* end varargs */ + binfo->fc_ffstate = FC_ERROR; + fc_mem_put(binfo, MEM_MBOX, (uchar * )mb); + fc_free_buffer(p_dev_ctl); + return(EIO); + } + + mp = (MATCHMAP * )binfo->fc_mbbp; + fc_mpdata_sync(mp->dma_handle, 0, sizeof(SERV_PARM), + DDI_DMA_SYNC_FORKERNEL); + fc_mpdata_outcopy(p_dev_ctl, mp, (uchar * ) & binfo->fc_sparam, + sizeof(SERV_PARM)); + + fc_mem_put(binfo, MEM_BUF, (uchar * )mp); + binfo->fc_mbbp = 0; + + fc_bcopy((uchar * )&binfo->fc_sparam.nodeName, (uchar * )&binfo->fc_nodename, + sizeof(NAME_TYPE)); + fc_bcopy((uchar * )&binfo->fc_sparam.portName, (uchar * )&binfo->fc_portname, + sizeof(NAME_TYPE)); + fc_bcopy(binfo->fc_portname.IEEE, p_dev_ctl->phys_addr, 6); + + /* If no serial number in VPD data, use low 6 bytes of WWNN */ + if(binfo->fc_SerialNumber[0] == 0) { + outptr = (uchar *) &binfo->fc_nodename.IEEE[0]; + for(i=0;i<12;i++) { + status = *outptr++; + j = ((status & 0xf0) >> 4); + if(j <= 9) + binfo->fc_SerialNumber[i] = (char)((uchar)0x30 + (uchar)j); + else + binfo->fc_SerialNumber[i] = (char)((uchar)0x61 + (uchar)(j-10)); + i++; + j = (status & 0xf); + if(j <= 9) + binfo->fc_SerialNumber[i] = (char)((uchar)0x30 + (uchar)j); + else + binfo->fc_SerialNumber[i] = (char)((uchar)0x61 + (uchar)(j-10)); + } + } + + if(clp[CFG_NETWORK_ON].a_current) { + if ((binfo->fc_sparam.portName.nameType != NAME_IEEE) || + (binfo->fc_sparam.portName.IEEEextMsn != 0) || + (binfo->fc_sparam.portName.IEEEextLsb != 0)) { + clp[CFG_NETWORK_ON].a_current = 0; + /* WorldWide PortName Type doesn't conform to IP Profile */ + fc_log_printf_msg_vargs( binfo->fc_brd_no, + &fc_msgBlk0449, /* ptr to msg structure */ + fc_mes0449, /* ptr to msg */ + fc_msgBlk0449.msgPreambleStr, /* begin varargs */ + binfo->fc_sparam.portName.nameType); /* end varargs */ + } + + fc_config_farp(binfo, mb); + if (issue_mb_cmd(binfo, mb, MBX_POLL) != MBX_SUCCESS) { + /* + * Let it go through even if failed. + */ + /* Adapter failed to init, mbxCmd FARP, mbxStatus */ + fc_log_printf_msg_vargs( binfo->fc_brd_no, + &fc_msgBlk0450, /* ptr to msg structure */ + fc_mes0450, /* ptr to msg */ + fc_msgBlk0450.msgPreambleStr, /* begin varargs */ + mb->mbxCommand, + mb->mbxStatus); /* end varargs */ + } + } + + if (p_dev_ctl->intr_inited != 1) { + /* Add our interrupt routine to kernel's interrupt chain & enable it */ + + + IHS.handler = fc_intr; + + if ((i_init((struct intr *) & IHS)) == INTR_FAIL) { + /* Enable interrupt handler failed */ + fc_log_printf_msg_vargs( binfo->fc_brd_no, + &fc_msgBlk0451, /* ptr to msg structure */ + fc_mes0451, /* ptr to msg */ + fc_msgBlk0451.msgPreambleStr); /* begin & end varargs */ + binfo->fc_ffstate = FC_ERROR; + fc_mem_put(binfo, MEM_MBOX, (uchar * )mb); + fc_free_buffer(p_dev_ctl); + return(EIO); + } + p_dev_ctl->intr_inited = 1; + } + + fc_disable_tc(binfo, (MAILBOX * )mb); + if (issue_mb_cmd(binfo, mb, MBX_POLL) != MBX_SUCCESS) { + binfo->fc_ffstate = FC_ERROR; + fc_ffcleanup(p_dev_ctl); + i_clear(&IHS); + fc_mem_put(binfo, MEM_MBOX, (uchar * )mb); + fc_free_buffer(p_dev_ctl); + return(EIO); + } + + fc_read_config(binfo, (MAILBOX * )mb); + if (issue_mb_cmd(binfo, mb, MBX_POLL) != MBX_SUCCESS) { + /* Adapter failed to init, mbxCmd READ_CONFIG, mbxStatus */ + fc_log_printf_msg_vargs( binfo->fc_brd_no, + &fc_msgBlk0453, /* ptr to msg structure */ + fc_mes0453, /* ptr to msg */ + fc_msgBlk0453.msgPreambleStr, /* begin varargs */ + mb->mbxCommand, + mb->mbxStatus); /* end varargs */ + binfo->fc_ffstate = FC_ERROR; + fc_ffcleanup(p_dev_ctl); + i_clear(&IHS); + fc_mem_put(binfo, MEM_MBOX, (uchar * )mb); + fc_free_buffer(p_dev_ctl); + return(EIO); + } + + if (mb->un.varRdConfig.lmt & LMT_2125_10bit) + /* HBA is 2G capable */ + binfo->fc_flag |= FC_2G_CAPABLE; + + binfo->fc_ffstate = FC_LINK_DOWN; + binfo->fc_flag |= FC_LNK_DOWN; + + /* Activate the adapter and allocate all the resources needed for ELS */ + fc_start(p_dev_ctl); + + /* Setup and issue mailbox INITIALIZE LINK command */ + fc_init_link(binfo, mb, clp[CFG_TOPOLOGY].a_current, + clp[CFG_LINK_SPEED].a_current); + if (issue_mb_cmd(binfo, mb, MBX_NOWAIT) != MBX_SUCCESS) { + /* Adapter failed to init, mbxCmd INIT_LINK, mbxStatus */ + fc_log_printf_msg_vargs( binfo->fc_brd_no, + &fc_msgBlk0454, /* ptr to msg structure */ + fc_mes0454, /* ptr to msg */ + fc_msgBlk0454.msgPreambleStr, /* begin varargs */ + mb->mbxCommand, + mb->mbxStatus); /* end varargs */ + binfo->fc_ffstate = FC_ERROR; + fc_ffcleanup(p_dev_ctl); + i_clear(&IHS); + fc_mem_put(binfo, MEM_MBOX, (uchar * )mb); + fc_free_buffer(p_dev_ctl); + return(EIO); + } + + + /* Enable link attention interrupt */ + ipri = disable_lock(FC_LVL, &CMD_LOCK); + ioa = (void *)FC_MAP_IO(&binfo->fc_iomap_io); /* map in io registers */ + status = READ_CSR_REG(binfo, FC_HC_REG(binfo, ioa)); + status = status | HC_LAINT_ENA; + WRITE_CSR_REG(binfo, FC_HC_REG(binfo, ioa), status); + FC_UNMAP_MEMIO(ioa); + binfo->fc_process_LA = 1; + p_dev_ctl->fc_waitflogi = (FCCLOCK *)1; + unlock_enable(ipri, &CMD_LOCK); + + fc_mem_put(binfo, MEM_MBOX, (uchar * )mb); + + binfo->fc_prevDID = Mask_DID; + /* If we are point to point, don't wait for link up */ + if ((clp[CFG_TOPOLOGY].a_current == FLAGS_TOPOLOGY_MODE_PT_PT) && + (clp[CFG_FCP_ON].a_current == 0)) { + goto out; + } + + flogi_sent = 0; + i = 0; + while (binfo->fc_ffstate != FC_READY) { + /* Check every second for 20 retries. */ + if ((i++ > 20) || + ((i >= 10) && (binfo->fc_ffstate <= FC_LINK_DOWN))) { + /* The link is down, so set linkdown timeout */ + rp = &binfo->fc_ring[FC_FCP_RING]; + RINGTMO = fc_clk_set(p_dev_ctl, rp->fc_ringtmo, fc_linkdown_timeout, 0, 0); + break; + } + ipri = disable_lock(FC_LVL, &CMD_LOCK); + if((i > 1) && (binfo->fc_ffstate == FC_FLOGI) && + (flogi_sent == 0) && (p_dev_ctl->power_up == 0)) { + if(p_dev_ctl->fc_waitflogi) { + if (p_dev_ctl->fc_waitflogi != (FCCLOCK *)1) + fc_clk_can(p_dev_ctl, p_dev_ctl->fc_waitflogi); + p_dev_ctl->fc_waitflogi = 0; + } + fc_snd_flogi(p_dev_ctl, 0, 0); + flogi_sent = 1; + rp = &binfo->fc_ring[FC_ELS_RING]; + if(RINGTMO) + fc_clk_res(p_dev_ctl, 20, RINGTMO); + } + unlock_enable(ipri, &CMD_LOCK); + + DELAYMS(1000); + } + +out: + ipri = disable_lock(FC_LVL, &CMD_LOCK); + if((binfo->fc_ffstate == FC_FLOGI) && (p_dev_ctl->power_up == 0)) { + fc_snd_flogi(p_dev_ctl, 0, 0); + } + p_dev_ctl->power_up = 1; + unlock_enable(ipri, &CMD_LOCK); + + return(0); +} /* End fc_ffinit */ + +/************************************************************************/ +/* */ +/* fc_binfo_init */ +/* This routine will initialize the binfo structure */ +/* */ +/************************************************************************/ +_local_ int +fc_binfo_init( +fc_dev_ctl_t *p_dev_ctl) +{ + FC_BRD_INFO * binfo; + iCfgParam * clp; + int idx; + + binfo = &BINFO; + clp = DD_CTL.p_config[binfo->fc_brd_no]; + + /* Initialize configuration parameters */ + if(binfo->fc_flag & FC_ESTABLISH_LINK) + binfo->fc_flag = FC_ESTABLISH_LINK; + else + binfo->fc_flag = 0; /* don't change nvram or tov */ + + binfo->fc_ffnumrings = MAX_CONFIGURED_RINGS - 1; /* number of rings */ + + /* Ring 0 - ELS */ + binfo->fc_nummask[0] = 4; + + binfo->fc_rval[0] = FC_ELS_REQ; /* ELS request */ + binfo->fc_tval[0] = FC_ELS_DATA; /* ELS */ + binfo->fc_rval[1] = FC_ELS_RSP; /* ELS response */ + binfo->fc_tval[1] = FC_ELS_DATA; /* ELS */ + binfo->fc_rval[2] = FC_UNSOL_CTL; /* NameServer Inquiries */ + binfo->fc_tval[2] = FC_COMMON_TRANSPORT_ULP; /* NameServer */ + binfo->fc_rval[3] = FC_SOL_CTL; /* NameServer response */ + binfo->fc_tval[3] = FC_COMMON_TRANSPORT_ULP; /* NameServer */ + if (binfo->fc_sli == 2) { + binfo->fc_ring[0].fc_numCiocb = SLI2_IOCB_CMD_R0_ENTRIES; + binfo->fc_ring[0].fc_numRiocb = SLI2_IOCB_RSP_R0_ENTRIES; + } else { + binfo->fc_ring[0].fc_numCiocb = IOCB_CMD_R0_ENTRIES; + binfo->fc_ring[0].fc_numRiocb = IOCB_RSP_R0_ENTRIES; + } + + /* Ring 1 - IP */ + if(clp[CFG_NETWORK_ON].a_current) { + binfo->fc_nummask[1] = 1; + idx = 5; + } else { + binfo->fc_nummask[1] = 0; + idx = 4; + } + binfo->fc_rval[4] = FC_UNSOL_DATA; /* Unsolicited Data */ + binfo->fc_tval[4] = FC_LLC_SNAP; /* LLC/SNAP */ + if (binfo->fc_sli == 2) { + binfo->fc_ring[1].fc_numCiocb = SLI2_IOCB_CMD_R1_ENTRIES; + binfo->fc_ring[1].fc_numRiocb = SLI2_IOCB_RSP_R1_ENTRIES; + if(clp[CFG_NETWORK_ON].a_current == 0) { + binfo->fc_ring[1].fc_numCiocb -= SLI2_IOCB_CMD_R1XTRA_ENTRIES; + binfo->fc_ring[1].fc_numRiocb -= SLI2_IOCB_RSP_R1XTRA_ENTRIES; + } + } else { + binfo->fc_ring[1].fc_numCiocb = IOCB_CMD_R1_ENTRIES; + binfo->fc_ring[1].fc_numRiocb = IOCB_RSP_R1_ENTRIES; + } + + /* Ring 2 - FCP */ + binfo->fc_nummask[2] = 0; + if (binfo->fc_sli == 2) { + binfo->fc_ring[2].fc_numCiocb = SLI2_IOCB_CMD_R2_ENTRIES; + binfo->fc_ring[2].fc_numRiocb = SLI2_IOCB_RSP_R2_ENTRIES; + if(clp[CFG_NETWORK_ON].a_current == 0) { + binfo->fc_ring[2].fc_numCiocb += SLI2_IOCB_CMD_R2XTRA_ENTRIES; + binfo->fc_ring[2].fc_numRiocb += SLI2_IOCB_RSP_R2XTRA_ENTRIES; + } + } else { + binfo->fc_ring[2].fc_numCiocb = IOCB_CMD_R2_ENTRIES; + binfo->fc_ring[2].fc_numRiocb = IOCB_RSP_R2_ENTRIES; + } + + + binfo->ipVersion = RNID_IPV4; + return(0); +} /* End fc_binfo_init */ + +/************************************************************************/ +/* */ +/* fc_parse_vpd */ +/* This routine will parse the VPD data */ +/* */ +/************************************************************************/ +_local_ int +fc_parse_vpd( +fc_dev_ctl_t *p_dev_ctl, +uchar *vpd) +{ + FC_BRD_INFO * binfo; + int finished = 0; + int index = 0; + uchar lenlo, lenhi; + unsigned char *Length; + int i, j; + + binfo = &BINFO; + /* Vital Product */ + fc_log_printf_msg_vargs( binfo->fc_brd_no, + &fc_msgBlk0455, /* ptr to msg structure */ + fc_mes0455, /* ptr to msg */ + fc_msgBlk0455.msgPreambleStr, /* begin varargs */ + (uint32)vpd[0], + (uint32)vpd[1], + (uint32)vpd[2], + (uint32)vpd[3]); /* end varargs */ + do { + switch (vpd[index]) { + case 0x82: + index += 1; + lenlo = vpd[index]; + index += 1; + lenhi = vpd[index]; + index += 1; + i = ((((unsigned short)lenhi) << 8) + lenlo); + index += i; + break; + case 0x90: + index += 1; + lenlo = vpd[index]; + index += 1; + lenhi = vpd[index]; + index += 1; + i = ((((unsigned short)lenhi) << 8) + lenlo); + do { + /* Look for Serial Number */ + if ((vpd[index] == 'S') && (vpd[index+1] == 'N')) { + index += 2; + Length = &vpd[index]; + index += 1; + i = *Length; + j = 0; + while(i--) { + binfo->fc_SerialNumber[j++] = vpd[index++]; + if(j == 31) + break; + } + binfo->fc_SerialNumber[j] = 0; + return(1); + } + else { + index += 2; + Length = &vpd[index]; + index += 1; + j = (int)(*Length); + index += j; + i -= (3 + j); + } + } while (i > 0); + finished = 0; + break; + case 0x78: + finished = 1; + break; + default: + return(0); + } + } while (!finished); + return(1); +} + +_static_ char fwrevision[32]; + +/* TAPE */ +_static_ char * +decode_firmware_rev( +FC_BRD_INFO *binfo, +fc_vpd_t *vp) +{ + uint32 b1, b2, b3, b4, ldata; + char c; + uint32 i, rev; + uint32 *ptr, str[4]; + + if ( vp->rev.rBit ) { + if (binfo->fc_sli == 2) + rev = vp->rev.sli2FwRev; + else + rev = vp->rev.sli1FwRev; + + b1 = (rev & 0x0000f000) >> 12; + b2 = (rev & 0x00000f00) >> 8; + b3 = (rev & 0x000000c0) >> 6; + b4 = (rev & 0x00000030) >> 4; + + switch (b4) { + case 0: + c = 'N'; + break; + case 1: + c = 'A'; + break; + case 2: + c = 'B'; + break; + case 3: + default: + c = 0; + break; + } + b4 = (rev & 0x0000000f); + + if (binfo->fc_sli == 2) { + for (i=0; i<16; i++) { + if (vp->rev.sli2FwName[i] == 0x20) { + vp->rev.sli2FwName[i] = 0; + } + } + ptr = (uint32 *)vp->rev.sli2FwName; + } else { + for (i=0; i<16; i++) { + if (vp->rev.sli1FwName[i] == 0x20) { + vp->rev.sli1FwName[i] = 0; + } + } + ptr = (uint32 *)vp->rev.sli1FwName; + } + for (i=0; i<3; i++) { + ldata = *ptr++; + ldata = SWAP_DATA(ldata); + str[i] = ldata; + } + + fwrevision[0] = (char)((int)'0' + b1); + fwrevision[1] = '.'; + fwrevision[2] = (char)((int)'0' + b2); + fwrevision[3] = (char)((int)'0' + b3); + if(c) { + fwrevision[4] = c; + fwrevision[5] = (char)((int)'0' + b4); + fwrevision[6] = 0; + } + else { + fwrevision[4] = 0; + } + } else { + rev = vp->rev.smFwRev; + + b1 = (rev & 0xff000000) >> 24; + b2 = (rev & 0x00f00000) >> 20; + b3 = (rev & 0x000f0000) >> 16; + c = (char)((rev & 0x0000ff00) >> 8); + b4 = (rev & 0x000000ff); + + fwrevision[0] = (char)((int)'0' + b1); + fwrevision[1] = '.'; + fwrevision[2] = (char)((int)'0' + b2); + fwrevision[3] = (char)((int)'0' + b3); + fwrevision[4] = c; + fwrevision[5] = (char)((int)'0' + b4); + fwrevision[6] = 0; + } + return(fwrevision); +} /* End decode_firmware_rev */ + + +/*****************************************************************************/ +/* + * NAME: fc_intr + * + * FUNCTION: Fibre Channel driver interrupt routine. + * + * EXECUTION ENVIRONMENT: interrupt only + * + * CALLED FROM: + * The FLIH + * + * INPUT: + * p_ihs - point to the interrupt structure. + * + * RETURNS: + * INTR_SUCC - our interrupt + * INTR_FAIL - not our interrupt + */ +/*****************************************************************************/ +_static_ int +fc_intr( +struct intr *p_ihs) /* This also points to device control area */ +{ + fc_dev_ctl_t * p_dev_ctl = (fc_dev_ctl_t * )p_ihs; + volatile uint32 ha_copy; + FC_BRD_INFO * binfo; + iCfgParam * clp; + fcipbuf_t * mbp; + MAILBOXQ * mb; + IOCBQ * delayiocb; + IOCBQ * temp; + IOCBQ * processiocb; + IOCBQ * endiocb; + void * ioa; + int ipri, rc; + + binfo = &BINFO; + + ipri = disable_lock(FC_LVL, &CMD_LOCK); + binfo->fc_flag |= FC_INTR_THREAD; + + ioa = (void *)FC_MAP_IO(&binfo->fc_iomap_io); /* map in io registers */ + + /* Read host attention register to determine interrupt source */ + ha_copy = READ_CSR_REG(binfo, FC_HA_REG(binfo, ioa)); + + /* Clear Attention Sources, except ERROR (to preserve status) & LATT */ + WRITE_CSR_REG(binfo, FC_HA_REG(binfo, ioa), + (ha_copy & ~HA_ERATT & ~HA_LATT)); + + FC_UNMAP_MEMIO(ioa); + + + if (ha_copy) { + rc = INTR_SUCC; + binfo->fc_flag |= FC_INTR_WORK; + } else { + clp = DD_CTL.p_config[binfo->fc_brd_no]; + if (clp[CFG_INTR_ACK].a_current && (binfo->fc_flag&FC_INTR_WORK)) { + rc = INTR_SUCC; /* Just claim the first non-working interrupt */ + binfo->fc_flag &= ~FC_INTR_WORK; + } else { + if (clp[CFG_INTR_ACK].a_current == 2) + rc = INTR_SUCC; /* Always claim the interrupt */ + else + rc = INTR_FAIL; + } + } + + if (binfo->fc_flag & FC_OFFLINE_MODE) { + binfo->fc_flag &= ~FC_INTR_THREAD; + unlock_enable(ipri, &CMD_LOCK); + return(INTR_FAIL); + } + + processiocb = 0; + if(binfo->fc_delayxmit) { + delayiocb = binfo->fc_delayxmit; + binfo->fc_delayxmit = 0; + endiocb = 0; + while(delayiocb) { + temp = delayiocb; + delayiocb = (IOCBQ *)temp->q; + temp->rsvd2--; + /* If retry == 0, process IOCB */ + if(temp->rsvd2 == 0) { + if(processiocb == 0) { + processiocb = temp; + } + else { + endiocb->q = (uchar *)temp; + } + endiocb = temp; + temp->q = 0; + } + else { + /* Make delayxmit point to first non-zero retry */ + if(binfo->fc_delayxmit == 0) + binfo->fc_delayxmit = temp; + } + } + if(processiocb) { + /* Handle any delayed IOCBs */ + endiocb = processiocb; + while(endiocb) { + temp = endiocb; + endiocb = (IOCBQ *)temp->q; + temp->q = 0; + issue_iocb_cmd(binfo, &binfo->fc_ring[FC_ELS_RING], temp); + } + } + } + + + if (ha_copy & HA_ERATT) { /* Link / board error */ + unlock_enable(ipri, &CMD_LOCK); + handle_ff_error(p_dev_ctl); + return (rc); + } else { + if (ha_copy & HA_MBATT) { /* Mailbox interrupt */ + handle_mb_event(p_dev_ctl); + if(binfo->fc_flag & FC_PENDING_RING0) { + binfo->fc_flag &= ~FC_PENDING_RING0; + ha_copy |= HA_R0ATT; /* event on ring 0 */ + } + } + + if (ha_copy & HA_LATT) { /* Link Attention interrupt */ + if (binfo->fc_process_LA) { + handle_link_event(p_dev_ctl); + } + } + + if (ha_copy & HA_R0ATT) { /* event on ring 0 */ + if(binfo->fc_mbox_active == 0) + handle_ring_event(p_dev_ctl, 0, (ha_copy & 0x0000000F)); + else + binfo->fc_flag |= FC_PENDING_RING0; + } + + if (ha_copy & HA_R1ATT) { /* event on ring 1 */ + /* This ring handles IP. Defer processing anything on this ring + * till all FCP ELS traffic settles down. + */ + if (binfo->fc_ffstate <= FC_NODE_DISC) + binfo->fc_deferip |= (uchar)((ha_copy >> 4) & 0x0000000F); + else + handle_ring_event(p_dev_ctl, 1, ((ha_copy >> 4) & 0x0000000F)); + } + + if (ha_copy & HA_R2ATT) { /* event on ring 2 */ + handle_ring_event(p_dev_ctl, 2, ((ha_copy >> 8) & 0x0000000F)); + } + + if (ha_copy & HA_R3ATT) { /* event on ring 3 */ + handle_ring_event(p_dev_ctl, 3, ((ha_copy >> 12) & 0x0000000F)); + } + } + + if((processiocb == 0) && (binfo->fc_delayxmit) && + (binfo->fc_mbox_active == 0)) { + if ((mb = (MAILBOXQ * )fc_mem_get(binfo, MEM_MBOX))) { + fc_read_rpi(binfo, (uint32)1, (MAILBOX * )mb, (uint32)0); + if (issue_mb_cmd(binfo, (MAILBOX * )mb, MBX_NOWAIT) != MBX_BUSY) { + fc_mem_put(binfo, MEM_MBOX, (uchar * )mb); + } + } + } + + binfo->fc_flag &= ~FC_INTR_THREAD; + + while (p_dev_ctl->mbufl_head != 0) { + binfo->fc_flag |= FC_INTR_WORK; + mbp = (fcipbuf_t * )p_dev_ctl->mbufl_head; + p_dev_ctl->mbufl_head = (uchar * )fcnextpkt(mbp); + fcnextpkt(mbp) = 0; + fc_xmit(p_dev_ctl, mbp); + } + p_dev_ctl->mbufl_tail = 0; + + + unlock_enable(ipri, &CMD_LOCK); + return(rc); +} /* End fc_intr */ + + + +/**************************************************/ +/** handle_ff_error **/ +/** **/ +/** Runs at Interrupt level **/ +/** **/ +/**************************************************/ +_static_ void +handle_ff_error( +fc_dev_ctl_t *p_dev_ctl) +{ + volatile uint32 status, status1, status2; + void *ioa; + FC_BRD_INFO * binfo; + iCfgParam * clp; + int ipri; + + ipri = disable_lock(FC_LVL, &CMD_LOCK); + + binfo = &BINFO; + clp = DD_CTL.p_config[binfo->fc_brd_no]; + + status = p_dev_ctl->dpc_hstatus; + p_dev_ctl->dpc_hstatus = 0; + + ioa = (void *)FC_MAP_MEM(&binfo->fc_iomap_mem); /* map in SLIM */ + status1 = READ_SLIM_ADDR(binfo, ((volatile uchar * )ioa + 0xa8)); + status2 = READ_SLIM_ADDR(binfo, ((volatile uchar * )ioa + 0xac)); + FC_UNMAP_MEMIO(ioa); + + + if (status & HS_FFER6) { + + + /* Re-establishing Link */ + fc_log_printf_msg_vargs( binfo->fc_brd_no, + &fc_msgBlk1301, /* ptr to msg structure */ + fc_mes1301, /* ptr to msg */ + fc_msgBlk1301.msgPreambleStr, /* begin varargs */ + status, + status1, + status2); /* end varargs */ + binfo->fc_flag |= FC_ESTABLISH_LINK; + fc_cfg_remove(p_dev_ctl); + + binfo->fc_flag |= FC_OFFLINE_MODE; + + lpfc_cfg_init(p_dev_ctl); + + unlock_enable(ipri, &CMD_LOCK); + } else { + /* Adapter Hardware Error */ + fc_log_printf_msg_vargs( binfo->fc_brd_no, + &fc_msgBlk0457, /* ptr to msg structure */ + fc_mes0457, /* ptr to msg */ + fc_msgBlk0457.msgPreambleStr, /* begin varargs */ + status, + status1, + status2); /* end varargs */ + if (status & HS_FFER8) { /* Chipset error 8 */ + } else if (status & HS_FFER7) { /* Chipset error 7 */ + } else if (status & HS_FFER5) { /* Chipset error 5 */ + } else if (status & HS_FFER4) { /* Chipset error 4 */ + } else if (status & HS_FFER3) { /* Chipset error 3 */ + } else if (status & HS_FFER2) { /* Chipset error 2 */ + } else if (status & HS_FFER1) { /* Chipset error 1 */ + } + + fc_free_rpilist(p_dev_ctl, 0); + + p_dev_ctl->device_state = DEAD; + binfo->fc_ffstate = FC_ERROR; + unlock_enable(ipri, &CMD_LOCK); + } + +} /* End handle_ff_error */ + + +/**************************************************/ +/** handle_link_event **/ +/** **/ +/** Description: Process a Link Attention. **/ +/** **/ +/**************************************************/ +_static_ void +handle_link_event( +fc_dev_ctl_t *p_dev_ctl) +{ + /* called from host_interrupt, to process LATT */ + MAILBOX * mb; + FC_BRD_INFO * binfo; + void *ioa; + volatile uint32 control; + + binfo = &BINFO; + FCSTATCTR.linkEvent++; + + /* Get a buffer which will be used for mailbox commands */ + if ((mb = (MAILBOX * )fc_mem_get(binfo, MEM_MBOX | MEM_PRI))) { + if (fc_read_la(p_dev_ctl, mb) == 0) { + if (issue_mb_cmd(binfo, mb, MBX_NOWAIT) != MBX_BUSY) { + fc_mem_put(binfo, MEM_MBOX, (uchar * )mb); + } + /* Turn off Link Attention interrupts until CLEAR_LA done */ + binfo->fc_process_LA = 0; + ioa = (void *)FC_MAP_IO(&binfo->fc_iomap_io); /* map in io registers */ + control = READ_CSR_REG(binfo, FC_HC_REG(binfo, ioa)); + control &= ~HC_LAINT_ENA; + WRITE_CSR_REG(binfo, FC_HC_REG(binfo, ioa), control); + /* Clear Link Attention in HA REG */ + WRITE_CSR_REG(binfo, FC_HA_REG(binfo, ioa), + (volatile uint32)(HA_LATT)); + FC_UNMAP_MEMIO(ioa); + } + else { + fc_mem_put(binfo, MEM_MBOX, (uchar * )mb); + } + } +} /* End handle_link_event */ + + +/**************************************************/ +/** handle_ring_event **/ +/** **/ +/** Description: Process a Ring Attention. **/ +/** **/ +/**************************************************/ +_static_ void +handle_ring_event( +fc_dev_ctl_t *p_dev_ctl, +int ring_no, +uint32 reg_mask) +{ + FC_BRD_INFO * binfo; + RING * rp; + IOCB * entry; + IOCBQ * saveq; + IOCBQ * temp; + void * ioa; + int fcpfound = 0; + uint32 * xx; + uint32 portGet; + volatile uint32 chipatt; + uint32 portRspPut; + + binfo = &BINFO; + /* called from host_interrupt() to process RxATT */ + + rp = &binfo->fc_ring[ring_no]; + temp = NULL; + fc_mpdata_sync(binfo->fc_slim2.dma_handle, 0, 0, DDI_DMA_SYNC_FORKERNEL); + + /* Gather iocb entries off response ring. + * Ensure entry is owned by the host. + */ + entry = (IOCB * )IOCB_ENTRY(rp->fc_rspringaddr, rp->fc_rspidx); + portRspPut = PCIMEM_LONG(((SLI2_SLIM * )binfo->fc_slim2.virt)->mbx.us.s2.port[ring_no].rspPutInx); + if (portRspPut >= rp->fc_numRiocb) { + return; + } + + while (rp->fc_rspidx != portRspPut) { + if((ring_no == 0) && (binfo->fc_mbox_active)) { + binfo->fc_flag |= FC_PENDING_RING0; + break; + } + /* get an iocb buffer to copy entry into */ + if ((temp = (IOCBQ * )fc_mem_get(binfo, MEM_IOCB | MEM_PRI)) == NULL) { + break; + } + + + fc_pcimem_bcopy((uint32 * )entry, (uint32 * ) & temp->iocb, sizeof(IOCB)); + temp->q = NULL; + + /* bump iocb available response index */ + if (++rp->fc_rspidx >= rp->fc_numRiocb) { + rp->fc_rspidx = 0; + } + + /* SLIM POINTER */ + if (binfo->fc_busflag & FC_HOSTPTR) { + ((SLI2_SLIM * )binfo->fc_slim2.virt)->mbx.us.s2.host[ring_no].rspGetInx = + PCIMEM_LONG(rp->fc_rspidx); + } else { + void * ioa2; + + ioa = (void *)FC_MAP_MEM(&binfo->fc_iomap_mem); /* map in SLIM */ + ioa2 = (void *)((char *)ioa + ((SLIMOFF+(ring_no*2)+1)*4)); + WRITE_SLIM_ADDR(binfo, (volatile uint32 *)ioa2, rp->fc_rspidx); + FC_UNMAP_MEMIO(ioa); + } + + /* chain all iocb entries until LE is set */ + if (rp->fc_iocbhd == NULL) { + rp->fc_iocbhd = temp; + rp->fc_iocbtl = temp; + } else { + rp->fc_iocbtl->q = (uchar * )temp; + rp->fc_iocbtl = temp; + } + + /* when LE is set, entire Command has been received */ + if (temp->iocb.ulpLe) { + saveq = rp->fc_iocbhd; + + rp->fc_iocbhd = NULL; + rp->fc_iocbtl = NULL; + + /* get a ptr to first iocb entry in chain and process it */ + xx = (uint32 * ) & saveq->iocb; + fcpfound = fc_proc_ring_event(p_dev_ctl, rp, saveq); + + /* Free up iocb buffer chain for command just processed */ + while (saveq) { + temp = saveq; + saveq = (IOCBQ * )temp->q; + fc_mem_put(binfo, MEM_IOCB, (uchar * )temp); + } + + } /* Entire Command has been received */ + + entry = (IOCB * )IOCB_ENTRY(rp->fc_rspringaddr, rp->fc_rspidx); + + } /* While(entry->ulpOwner == 0) */ + + if ((temp != NULL) && (reg_mask & HA_R0RE_REQ)) { + /* At least one response entry has been freed */ + FCSTATCTR.chipRingFree++; + ioa = (void *)FC_MAP_IO(&binfo->fc_iomap_io); /* map in io registers */ + /* SET R0RE_RSP in Chip Att register */ + chipatt = ((CA_R0ATT | CA_R0RE_RSP) << (ring_no * 4)); + WRITE_CSR_REG(binfo, FC_FF_REG(binfo, ioa), chipatt); + FC_UNMAP_MEMIO(ioa); + } + + if (reg_mask != 0xffffffff) { + if (fcpfound) { + fc_issue_cmd(p_dev_ctl); + } else if (reg_mask & HA_R0CE_RSP) { + FCSTATCTR.hostRingFree++; + /* Cmd ring is available, queue any available cmds */ + portGet = issue_iocb_cmd(binfo, rp, 0); + if(portGet != PCIMEM_LONG(((SLI2_SLIM * )binfo->fc_slim2.virt)->mbx.us.s2.port[rp->fc_ringno].cmdGetInx)) { + issue_iocb_cmd(binfo, rp, 0); + } + } + FCSTATCTR.ringEvent++; + } + + return; +} /* End handle_ring_event */ + +_static_ int +fc_proc_ring_event( +fc_dev_ctl_t *p_dev_ctl, +RING *rp, +IOCBQ *saveq) +{ + FC_BRD_INFO * binfo; + NODELIST * ndlp; + IOCB * cmd; + int rc; + + binfo = &BINFO; + cmd = &saveq->iocb; + rc = 0; + FCSTATCTR.iocbRsp++; + + switch (cmd->ulpCommand) { + case CMD_FCP_ICMND_CR: + case CMD_FCP_ICMND_CX: + case CMD_FCP_IREAD_CR: + case CMD_FCP_IREAD_CX: + case CMD_FCP_IWRITE_CR: + case CMD_FCP_IWRITE_CX: + case CMD_FCP_ICMND64_CR: + case CMD_FCP_ICMND64_CX: + case CMD_FCP_IREAD64_CR: + case CMD_FCP_IREAD64_CX: + case CMD_FCP_IWRITE64_CR: + case CMD_FCP_IWRITE64_CX: + handle_fcp_event(p_dev_ctl, rp, saveq); + rc = 1; + break; + + case CMD_RCV_SEQUENCE_CX: /* received incoming frame */ + case CMD_RCV_SEQUENCE64_CX: /* received incoming frame */ + switch(rp->fc_ringno) { + case FC_ELS_RING: + handle_elsrcv_seq(p_dev_ctl, rp, saveq); + break; + case FC_IP_RING: + handle_iprcv_seq(p_dev_ctl, rp, saveq); + break; + } + break; + + case CMD_XMIT_BCAST_CN: /* process xmit completion */ + case CMD_XMIT_BCAST_CX: + case CMD_XMIT_SEQUENCE_CX: + case CMD_XMIT_SEQUENCE_CR: + case CMD_XMIT_BCAST64_CN: /* process xmit completion */ + case CMD_XMIT_BCAST64_CX: + case CMD_XMIT_SEQUENCE64_CX: + case CMD_XMIT_SEQUENCE64_CR: + handle_xmit_cmpl(p_dev_ctl, rp, saveq); + break; + + case CMD_RCV_ELS_REQ_CX: /* received an els frame */ + case CMD_RCV_ELS_REQ64_CX: /* received an els frame */ + handle_rcv_els_req(p_dev_ctl, rp, saveq); + break; + + case CMD_CREATE_XRI_CR: + case CMD_CREATE_XRI_CX: + handle_create_xri(p_dev_ctl, rp, saveq); + break; + + case CMD_ELS_REQUEST_CR: /* xmit els frame completion */ + case CMD_ELS_REQUEST_CX: + case CMD_XMIT_ELS_RSP_CX: + case CMD_ELS_REQUEST64_CR: + case CMD_ELS_REQUEST64_CX: + case CMD_XMIT_ELS_RSP64_CX: + case CMD_GEN_REQUEST64_CR: + case CMD_GEN_REQUEST64_CX: + handle_els_event(p_dev_ctl, rp, saveq); + break; + + case CMD_ABORT_XRI_CN: /* Abort fcp command */ + break; + + case CMD_ABORT_XRI_CX: /* Abort command */ + break; + + case CMD_XRI_ABORTED_CX: /* Handle ABORT condition */ + /* + * If we find an NODELIST entry that matches the aborted + * XRI, clear out the Xri field. + */ + if (((ndlp = fc_findnode_oxri(binfo, NLP_SEARCH_UNMAPPED | NLP_SEARCH_MAPPED, + cmd->ulpContext)) != NULL) && !(ndlp->nlp_flag & NLP_RPI_XRI)) { + ndlp->nlp_Xri = 0; /* xri */ + /* establish a new exchange */ + if ((ndlp->nlp_Rpi) && + ((ndlp->nlp_DID & CT_DID_MASK) != CT_DID_MASK) && + (binfo->fc_ffstate == FC_READY)) { + ndlp->nlp_flag |= NLP_RPI_XRI; + fc_create_xri(binfo, &binfo->fc_ring[FC_ELS_RING], ndlp); + } + } + break; + + case CMD_ADAPTER_MSG: + if ((binfo->fc_msgidx + MAX_MSG_DATA) <= FC_MAX_ADPTMSG) { + fc_bcopy((uchar * )cmd, &binfo->fc_adaptermsg[binfo->fc_msgidx], + MAX_MSG_DATA); + binfo->fc_msgidx += MAX_MSG_DATA; + con_print("lpfc%d: %s", binfo->fc_brd_no, binfo->fc_adaptermsg); + fc_bzero((void *)binfo->fc_adaptermsg, FC_MAX_ADPTMSG); + binfo->fc_msgidx = 0; + } else { + con_print("lpfc%d: %s\n", binfo->fc_brd_no, binfo->fc_adaptermsg); + fc_bzero(binfo->fc_adaptermsg, FC_MAX_ADPTMSG); + binfo->fc_msgidx = 0; + } + break; + + + default: + /* Unknown IOCB command */ + fc_log_printf_msg_vargs( binfo->fc_brd_no, + &fc_msgBlk1400, /* ptr to msg structure */ + fc_mes1400, /* ptr to msg */ + fc_msgBlk1400.msgPreambleStr, /* begin varargs */ + cmd->ulpCommand, + cmd->ulpStatus, + cmd->ulpIoTag, + cmd->ulpContext); /* end varargs */ + break; + } /* switch(cmd->ulpCommand) */ + + return(rc); +} /* End fc_proc_ring_event */ + + +/**************************************************/ +/** handle_mb_event **/ +/** **/ +/** Description: Process a Mailbox Attention. **/ +/** Called from host_interrupt to process MBATT **/ +/** **/ +/** Returns: **/ +/** **/ +/**************************************************/ +_static_ int +handle_mb_event( +fc_dev_ctl_t *p_dev_ctl) +{ + FC_BRD_INFO * binfo; + MAILBOX * mb; + MAILBOX * swpmb; + MAILBOXQ * mbox; + IOCBQ * iocbq; + NODELIST * ndlp; + void *ioa; + uint32 control; + volatile uint32 word0; + volatile uint32 ldata; + volatile uint32 ldid; + volatile uint32 lrpi; + iCfgParam * clp; + + binfo = &BINFO; + clp = DD_CTL.p_config[binfo->fc_brd_no]; + + if (binfo->fc_flag & FC_SLI2) { + fc_mpdata_sync(binfo->fc_slim2.dma_handle, 0, 0, DDI_DMA_SYNC_FORKERNEL); + /* First copy command data */ + mb = FC_SLI2_MAILBOX(binfo); + word0 = *((volatile uint32 * )mb); + word0 = PCIMEM_LONG(word0); + } else { + /* First copy command data */ + ioa = (void *)FC_MAP_MEM(&binfo->fc_iomap_mem); /* map in SLIM */ + mb = FC_MAILBOX(binfo, ioa); + word0 = READ_SLIM_ADDR(binfo, ((volatile uint32 * )mb)); + FC_UNMAP_MEMIO(ioa); + } + + swpmb = (MAILBOX * ) & word0; + + FCSTATCTR.mboxEvent++; + + /* Sanity check to ensure the host owns the mailbox */ + if (swpmb->mbxOwner != OWN_HOST) { + int i; + + for(i=0; i<10240;i++) { + if (binfo->fc_flag & FC_SLI2) { + fc_mpdata_sync(binfo->fc_slim2.dma_handle, 0, 0, DDI_DMA_SYNC_FORKERNEL); + /* First copy command data */ + mb = FC_SLI2_MAILBOX(binfo); + word0 = *((volatile uint32 * )mb); + word0 = PCIMEM_LONG(word0); + } else { + /* First copy command data */ + ioa = (void *)FC_MAP_MEM(&binfo->fc_iomap_mem); /* map in SLIM */ + mb = FC_MAILBOX(binfo, ioa); + word0 = READ_SLIM_ADDR(binfo, ((volatile uint32 * )mb)); + FC_UNMAP_MEMIO(ioa); + } + + swpmb = (MAILBOX * ) & word0; + if (swpmb->mbxOwner == OWN_HOST) + goto out; + } + /* Stray Mailbox Interrupt, mbxCommand mbxStatus */ + fc_log_printf_msg_vargs( binfo->fc_brd_no, + &fc_msgBlk0304, /* ptr to msg structure */ + fc_mes0304, /* ptr to msg */ + fc_msgBlk0304.msgPreambleStr, /* begin varargs */ + swpmb->mbxCommand, + swpmb->mbxStatus); /* end varargs */ + return(1); + } + +out: + + /* stop watchdog timer */ + if(MBOXTMO) { + fc_clk_can(p_dev_ctl, MBOXTMO); + MBOXTMO = 0; + } + + if (swpmb->mbxStatus) { + if (swpmb->mbxStatus == MBXERR_NO_RESOURCES) { + FCSTATCTR.mboxStatErr++; + /* Mbox cmd cmpl error - RETRYing */ + fc_log_printf_msg_vargs( binfo->fc_brd_no, + &fc_msgBlk0305, /* ptr to msg structure */ + fc_mes0305, /* ptr to msg */ + fc_msgBlk0305.msgPreambleStr, /* begin varargs */ + swpmb->mbxCommand, + word0, + binfo->fc_ffstate, + binfo->fc_flag); /* end varargs */ + if ((mbox = (MAILBOXQ * )fc_mem_get(binfo, MEM_MBOX))) { + if (binfo->fc_flag & FC_SLI2) { + /* First copy mbox command data */ + mb = FC_SLI2_MAILBOX(binfo); + fc_pcimem_bcopy((uint32 * )mb, (uint32 * )mbox, + (sizeof(uint32) * (MAILBOX_CMD_WSIZE))); + } else { + /* First copy mbox command data */ + ioa = (void *)FC_MAP_MEM(&binfo->fc_iomap_mem); /* map in SLIM */ + mb = FC_MAILBOX(binfo, ioa); + READ_SLIM_COPY(binfo, (uint32 *)mbox, (uint32 *)mb, + MAILBOX_CMD_WSIZE); + FC_UNMAP_MEMIO(ioa); + } + switch(((MAILBOX *)mbox)->mbxCommand) { + case MBX_READ_SPARM: + control = ((MAILBOX *)mbox)->un.varRdSparm.un.sp.bdeSize; + if(control == 0) { + fc_read_sparam(p_dev_ctl, (MAILBOX *)mbox); + } + case MBX_READ_SPARM64: + control = ((MAILBOX *)mbox)->un.varRdSparm.un.sp64.tus.f.bdeSize; + if(control == 0) { + fc_read_sparam(p_dev_ctl, (MAILBOX *)mbox); + } + case MBX_REG_LOGIN: + control = ((MAILBOX *)mbox)->un.varRegLogin.un.sp.bdeSize; + if(control == 0) { + goto mbout; + } + case MBX_REG_LOGIN64: + control = ((MAILBOX *)mbox)->un.varRegLogin.un.sp64.tus.f.bdeSize; + if(control == 0) { + goto mbout; + } + case MBX_READ_LA: + control = ((MAILBOX *)mbox)->un.varReadLA.un.lilpBde.bdeSize; + if(control == 0) { + fc_read_la(p_dev_ctl, (MAILBOX *)mbox); + } + case MBX_READ_LA64: + control = ((MAILBOX *)mbox)->un.varReadLA.un.lilpBde64.tus.f.bdeSize; + if(control == 0) { + fc_read_la(p_dev_ctl, (MAILBOX *)mbox); + } + } + ((MAILBOX *)mbox)->mbxOwner = OWN_HOST; + ((MAILBOX *)mbox)->mbxStatus = 0; + mbox->bp = (uchar * )binfo->fc_mbbp; + binfo->fc_mbox_active = 0; + if (issue_mb_cmd(binfo, (MAILBOX * )mbox, MBX_NOWAIT) != MBX_BUSY) { + fc_mem_put(binfo, MEM_MBOX, (uchar * )mbox); + } + return(0); + } + } + if (!((swpmb->mbxCommand == MBX_CLEAR_LA) && + (swpmb->mbxStatus == 0x1601))) { + /* Mbox cmd cmpl error */ + fc_log_printf_msg_vargs( binfo->fc_brd_no, + &fc_msgBlk0306, /* ptr to msg structure */ + fc_mes0306, /* ptr to msg */ + fc_msgBlk0306.msgPreambleStr, /* begin varargs */ + swpmb->mbxCommand, + word0, + binfo->fc_ffstate, + binfo->fc_flag); /* end varargs */ + FCSTATCTR.mboxStatErr++; + switch (swpmb->mbxCommand) { + case MBX_REG_LOGIN: + case MBX_REG_LOGIN64: + if (binfo->fc_flag & FC_SLI2) { + /* First copy command data */ + mb = FC_SLI2_MAILBOX(binfo); + ldata = mb->un.varWords[1]; /* get did */ + ldata = PCIMEM_LONG(ldata); + } else { + /* First copy command data */ + ioa = (void *)FC_MAP_MEM(&binfo->fc_iomap_mem); /* map in SLIM */ + mb = FC_MAILBOX(binfo, ioa); + ldata = READ_SLIM_ADDR(binfo, &mb->un.varWords[1]); + FC_UNMAP_MEMIO(ioa); + } + + ldid = ldata & Mask_DID; + if ((ndlp=fc_findnode_odid(binfo,(NLP_SEARCH_MAPPED | NLP_SEARCH_UNMAPPED), ldid))) { + if (ndlp->nlp_action & NLP_DO_DISC_START) { + /* Goto next entry */ + fc_nextnode(p_dev_ctl, ndlp); + } + fc_freenode(binfo, ndlp, 0); + ndlp->nlp_state = NLP_LIMBO; + fc_nlp_bind(binfo, ndlp); + } + break; + + case MBX_UNREG_LOGIN: + if (binfo->fc_flag & FC_SLI2) { + /* First copy command data */ + mb = FC_SLI2_MAILBOX(binfo); + ldata = mb->un.varWords[0]; /* get rpi */ + ldata = PCIMEM_LONG(ldata); + } else { + /* First copy command data */ + ioa = (void *)FC_MAP_MEM(&binfo->fc_iomap_mem); /* map in SLIM */ + mb = FC_MAILBOX(binfo, ioa); + ldata = READ_SLIM_ADDR(binfo, &mb->un.varWords[0]); + FC_UNMAP_MEMIO(ioa); + } + + lrpi = ldata & 0xffff; + + if ((ndlp = fc_findnode_rpi(binfo, lrpi)) == 0) + break; + binfo->fc_nlplookup[ndlp->nlp_Rpi] = 0; + ndlp->nlp_Rpi = 0; + fc_freenode(binfo, ndlp, 0); + ndlp->nlp_state = NLP_LIMBO; + fc_nlp_bind(binfo, ndlp); + break; + + case MBX_READ_LA: + case MBX_READ_LA64: + case MBX_CLEAR_LA: + /* Turn on Link Attention interrupts */ + binfo->fc_process_LA = 1; + + ioa = (void *)FC_MAP_IO(&binfo->fc_iomap_io); /* map in io registers */ + control = READ_CSR_REG(binfo, FC_HC_REG(binfo, ioa)); + control |= HC_LAINT_ENA; + WRITE_CSR_REG(binfo, FC_HC_REG(binfo, ioa), control); + FC_UNMAP_MEMIO(ioa); + break; + + case MBX_INIT_LINK: + if (binfo->fc_flag & FC_SLI2) { + if ((clp[CFG_LINK_SPEED].a_current > 0) && + ((swpmb->mbxStatus == 0x0011) || (swpmb->mbxStatus == 0x0500))) { + /* Reset link speed to auto. 1G node detected in loop. */ + fc_log_printf_msg_vargs( binfo->fc_brd_no, + &fc_msgBlk1302, /* ptr to msg structure */ + fc_mes1302, /* ptr to msg */ + fc_msgBlk1302.msgPreambleStr); /* begin & end varargs */ + clp[CFG_LINK_SPEED].a_current = LINK_SPEED_AUTO; + if ((mbox = (MAILBOXQ * )fc_mem_get(binfo, MEM_MBOX))) { + /* First copy mbox command data */ + mb = FC_SLI2_MAILBOX(binfo); + fc_pcimem_bcopy((uint32 * )mb, (uint32 * )mbox, + (sizeof(uint32) * (MAILBOX_CMD_WSIZE))); + ((MAILBOX *)mbox)->un.varInitLnk.link_flags &= ~FLAGS_LINK_SPEED; + ((MAILBOX *)mbox)->un.varInitLnk.link_speed = 0; /* LINK_SPEED_AUTO */ + ((MAILBOX *)mbox)->mbxOwner = OWN_HOST; + ((MAILBOX *)mbox)->mbxStatus = 0; + mbox->bp = (uchar * )binfo->fc_mbbp; + binfo->fc_mbox_active = 0; + if (issue_mb_cmd(binfo, (MAILBOX * )mbox, MBX_NOWAIT) != MBX_BUSY) { + fc_mem_put(binfo, MEM_MBOX, (uchar * )mbox); + } + return(0); + } + } + } + break; + } + if (binfo->fc_mbbp) { + fc_mem_put(binfo, MEM_BUF, (uchar * )binfo->fc_mbbp); + binfo->fc_mbbp = 0; + } + goto mbout; + } + } + + /* Mbox cmd cmpl */ + fc_log_printf_msg_vargs( binfo->fc_brd_no, + &fc_msgBlk0307, /* ptr to msg structure */ + fc_mes0307, /* ptr to msg */ + fc_msgBlk0307.msgPreambleStr, /* begin varargs */ + swpmb->mbxCommand, + word0, + binfo->fc_ffstate, + binfo->fc_flag); /* end varargs */ + + if(binfo->fc_mbox_active == 2) { + MAILBOX *mbslim; + + /* command was issued by dfc layer, so save mbox cmpl */ + if ((binfo->fc_flag & FC_SLI2) && (!(binfo->fc_flag & FC_OFFLINE_MODE))) { + /* First copy command data */ + mbslim = FC_SLI2_MAILBOX(binfo); + /* copy results back to user */ + fc_pcimem_bcopy((uint32 * )mbslim, (uint32 * )&p_dev_ctl->dfcmb, + (sizeof(uint32) * MAILBOX_CMD_WSIZE)); + } else { + /* First copy command data */ + ioa = (void *)FC_MAP_MEM(&binfo->fc_iomap_mem); /* map in SLIM */ + mbslim = FC_MAILBOX(binfo, ioa); + /* copy results back to user */ + READ_SLIM_COPY(binfo, (uint32 * )&p_dev_ctl->dfcmb, (uint32 * )mbslim, + MAILBOX_CMD_WSIZE); + FC_UNMAP_MEMIO(ioa); + } + } + else { + handle_mb_cmd(p_dev_ctl, swpmb, (uint32)swpmb->mbxCommand); + } + + +mbout: + /* Process next mailbox command if there is one */ + binfo->fc_mbox_active = 0; + if ((mbox = fc_mbox_get(binfo))) { + if (issue_mb_cmd(binfo, (MAILBOX * )mbox, MBX_NOWAIT) != MBX_BUSY) { + fc_mem_put(binfo, MEM_MBOX, (uchar * )mbox); + } + } else { + if (binfo->fc_flag & FC_DELAY_PLOGI) { + binfo->fc_flag &= ~FC_DELAY_PLOGI; + if((binfo->fc_flag & FC_RSCN_MODE) && (binfo->fc_ffstate == FC_READY)) + fc_nextrscn(p_dev_ctl, fc_max_els_sent); + else + fc_nextdisc(p_dev_ctl, fc_max_els_sent); + } + if (binfo->fc_flag & FC_DELAY_NSLOGI) { + if ((iocbq = fc_plogi_get(binfo))) { + fc_els_cmd(binfo, ELS_CMD_PLOGI, + (void *)((ulong)iocbq->iocb.un.elsreq.remoteID), + (uint32)0, (ushort)0, (NODELIST *)0); + fc_mem_put(binfo, MEM_IOCB, (uchar * )iocbq); + } + else { + binfo->fc_flag &= ~FC_DELAY_NSLOGI; + } + } + if (binfo->fc_flag & FC_DELAY_RSCN) { + IOCBQ *temp; + IOCB *iocb; + MATCHMAP *mp; + RING *rp; + int i; + + rp = &binfo->fc_ring[FC_ELS_RING]; + binfo->fc_flag &= ~FC_DELAY_RSCN; + while (binfo->fc_rscn.q_first) { + temp = (IOCBQ * )binfo->fc_rscn.q_first; + if ((binfo->fc_rscn.q_first = temp->q) == 0) { + binfo->fc_rscn.q_last = 0; + } + binfo->fc_rscn.q_cnt--; + iocb = &temp->iocb; + mp = *((MATCHMAP **)iocb); + *((MATCHMAP **)iocb) = 0; + temp->q = NULL; + fc_process_rscn(p_dev_ctl, temp, mp); + + fc_mem_put(binfo, MEM_BUF, (uchar * )mp); + + i = 1; + /* free resources associated with this iocb and repost the ring buffers */ + if (!(binfo->fc_flag & FC_SLI2)) { + for (i = 1; i < (int)iocb->ulpBdeCount; i++) { + mp = fc_getvaddr(p_dev_ctl, rp, (uchar * )((ulong)iocb->un.cont[i].bdeAddress)); + if (mp) { + fc_mem_put(binfo, MEM_BUF, (uchar * )mp); + } + } + } + fc_mem_put(binfo, MEM_IOCB, (uchar * )temp); + } + } + } + return(0); +} /* End handle_mb_event */ + + +/**********************************************************/ +/** issue_mb_cmd Issue a mailbox command. **/ +/** If the mailbox is currently busy, **/ +/** queue command to mbox queue. **/ +/**********************************************************/ +_static_ int +issue_mb_cmd( +FC_BRD_INFO *binfo, +MAILBOX *mb, +int flag) +{ + MAILBOX * mbox; + MAILBOXQ * mbq; + int i; + void *ioa; + uint32 status, evtctr; + uint32 ha_copy; + fc_dev_ctl_t *p_dev_ctl; + volatile uint32 word0, ldata; + + mbq = (MAILBOXQ * )mb; + status = MBX_SUCCESS; + + if (binfo->fc_mbox_active) { + /* Another mailbox command is still being processed, queue this + * command to be processed later. + */ + fc_mbox_put(binfo, mbq); + + /* Mbox cmd issue - BUSY */ + fc_log_printf_msg_vargs( binfo->fc_brd_no, + &fc_msgBlk0308, /* ptr to msg structure */ + fc_mes0308, /* ptr to msg */ + fc_msgBlk0308.msgPreambleStr, /* begin varargs */ + mb->mbxCommand, + binfo->fc_ffstate, + binfo->fc_flag, + flag); /* end varargs */ + FCSTATCTR.mboxCmdBusy++; + + return(MBX_BUSY); + } + + binfo->fc_mbox_active = 1; + p_dev_ctl = (fc_dev_ctl_t *)(binfo->fc_p_dev_ctl); + + /* Mailbox cmd issue */ + fc_log_printf_msg_vargs( binfo->fc_brd_no, + &fc_msgBlk0309, /* ptr to msg structure */ + fc_mes0309, /* ptr to msg */ + fc_msgBlk0309.msgPreambleStr, /* begin varargs */ + mb->mbxCommand, + binfo->fc_ffstate, + binfo->fc_flag, + flag); /* end varargs */ + /* If we are not polling, turn on watchdog timer */ + if (flag != MBX_POLL) { + MBOXTMO = fc_clk_set(p_dev_ctl, MBOX_TMO_DFT, fc_mbox_timeout, 0, 0); + } + + FCSTATCTR.issueMboxCmd++; + evtctr = FCSTATCTR.mboxEvent; + + /* if there is one, save buffer to release in completion */ + if (mbq->bp) { + binfo->fc_mbbp = mbq->bp; + mbq->bp = 0; + } + + /* next set own bit for the adapter and copy over command word */ + mb->mbxOwner = OWN_CHIP; + + if (binfo->fc_flag & FC_SLI2) { + /* First copy command data */ + mbox = FC_SLI2_MAILBOX(binfo); + fc_pcimem_bcopy((uint32 * )mb, (uint32 * )mbox, + (sizeof(uint32) * (MAILBOX_CMD_WSIZE))); + fc_mpdata_sync(binfo->fc_slim2.dma_handle, 0, 0, DDI_DMA_SYNC_FORDEV); + } else { + if (mb->mbxCommand == MBX_CONFIG_PORT) { + /* copy command data into host mbox for cmpl */ + fc_pcimem_bcopy((uint32 * )mb, + (uint32 * ) & ((SLI2_SLIM * )binfo->fc_slim2.virt)->mbx, + (sizeof(uint32) * (MAILBOX_CMD_WSIZE))); + } + + /* First copy command data */ + ioa = (void *)FC_MAP_MEM(&binfo->fc_iomap_mem); /* map in SLIM */ + + mbox = FC_MAILBOX(binfo, ioa); + WRITE_SLIM_COPY(binfo, &mb->un.varWords, &mbox->un.varWords, + (MAILBOX_CMD_WSIZE - 1)); + + + /* copy over last word, with mbxOwner set */ + ldata = *((volatile uint32 * )mb); + + WRITE_SLIM_ADDR(binfo, ((volatile uint32 * )mbox), ldata); + FC_UNMAP_MEMIO(ioa); + + if (mb->mbxCommand == MBX_CONFIG_PORT) { + /* switch over to host mailbox */ + binfo->fc_mboxaddr = (uint32 *)&((SLI2_SLIM * )binfo->fc_slim2.virt)->mbx; + binfo->fc_flag |= FC_SLI2; + } + } + + + /* interrupt board to doit right away */ + ioa = (void *)FC_MAP_IO(&binfo->fc_iomap_io); /* map in io registers */ + WRITE_CSR_REG(binfo, FC_FF_REG(binfo, ioa), CA_MBATT); + FC_UNMAP_MEMIO(ioa); + + switch (flag) { + case MBX_SLEEP: + case MBX_NOWAIT: + break; + + case MBX_POLL: + i = 0; + if (binfo->fc_flag & FC_SLI2) { + fc_mpdata_sync(binfo->fc_slim2.dma_handle, 0, 0, + DDI_DMA_SYNC_FORKERNEL); + + /* First copy command data */ + mbox = FC_SLI2_MAILBOX(binfo); + word0 = *((volatile uint32 * )mbox); + word0 = PCIMEM_LONG(word0); + } else { + /* First copy command data */ + ioa = (void *)FC_MAP_MEM(&binfo->fc_iomap_mem); /* map in SLIM */ + mbox = FC_MAILBOX(binfo, ioa); + word0 = READ_SLIM_ADDR(binfo, ((volatile uint32 * )mbox)); + FC_UNMAP_MEMIO(ioa); + } + + ioa = (void *)FC_MAP_IO(&binfo->fc_iomap_io); /* map in io registers */ + ha_copy = READ_CSR_REG(binfo, FC_HA_REG(binfo, ioa)); + FC_UNMAP_MEMIO(ioa); + + /* Wait for command to complete */ + while (((word0 & OWN_CHIP) == OWN_CHIP) || !(ha_copy & HA_MBATT)) { + if (i++ >= 100) { + binfo->fc_mbox_active = 0; + return(MBX_NOT_FINISHED); + } + + /* Check if we took a mbox interrupt while we were polling */ + if(((word0 & OWN_CHIP) != OWN_CHIP) && (evtctr != FCSTATCTR.mboxEvent)) + break; + + DELAYMS(i); + + if (binfo->fc_flag & FC_SLI2) { + fc_mpdata_sync(binfo->fc_slim2.dma_handle, 0, 0, + DDI_DMA_SYNC_FORKERNEL); + + /* First copy command data */ + mbox = FC_SLI2_MAILBOX(binfo); + word0 = *((volatile uint32 * )mbox); + word0 = PCIMEM_LONG(word0); + } else { + /* First copy command data */ + ioa = (void *)FC_MAP_MEM(&binfo->fc_iomap_mem); /* map in SLIM */ + mbox = FC_MAILBOX(binfo, ioa); + word0 = READ_SLIM_ADDR(binfo, ((volatile uint32 * )mbox)); + FC_UNMAP_MEMIO(ioa); + } + ioa = (void *)FC_MAP_IO(&binfo->fc_iomap_io); /* map in io registers */ + ha_copy = READ_CSR_REG(binfo, FC_HA_REG(binfo, ioa)); + FC_UNMAP_MEMIO(ioa); + } + + if (binfo->fc_flag & FC_SLI2) { + fc_mpdata_sync(binfo->fc_slim2.dma_handle, 0, 0, + DDI_DMA_SYNC_FORKERNEL); + + /* First copy command data */ + mbox = FC_SLI2_MAILBOX(binfo); + /* copy results back to user */ + fc_pcimem_bcopy((uint32 * )mbox, (uint32 * )mb, + (sizeof(uint32) * MAILBOX_CMD_WSIZE)); + } else { + /* First copy command data */ + ioa = (void *)FC_MAP_MEM(&binfo->fc_iomap_mem); /* map in SLIM */ + mbox = FC_MAILBOX(binfo, ioa); + /* copy results back to user */ + READ_SLIM_COPY(binfo, (uint32 * )mb, (uint32 * )mbox, MAILBOX_CMD_WSIZE); + FC_UNMAP_MEMIO(ioa); + } + + ioa = (void *)FC_MAP_IO(&binfo->fc_iomap_io); /* map in io registers */ + WRITE_CSR_REG(binfo, FC_HA_REG(binfo, ioa), HA_MBATT); + FC_UNMAP_MEMIO(ioa); + + binfo->fc_mbox_active = 0; + status = mb->mbxStatus; + break; + } + return(status); +} /* End issue_mb_cmd */ + + +/* + * This routine will issue as many iocb commands from the + * ring's xmit queue to the adapter as it can. + * If iocb_cmd is specified it will be queued to the xmit queue. + */ +_static_ uint32 +issue_iocb_cmd( +FC_BRD_INFO *binfo, +RING *rp, +IOCBQ *iocb_cmd) +{ + IOCB * iocb; + IOCB * icmd; + void * ioa; + uint32 status; + uint32 * xx; + int onetime; + uint32 portCmdGet, rc; + fc_dev_ctl_t *p_dev_ctl; + + rc = PCIMEM_LONG(((SLI2_SLIM * )binfo->fc_slim2.virt)->mbx.us.s2.port[rp->fc_ringno].cmdGetInx); + onetime = 0; + if ((binfo->fc_flag & FC_LNK_DOWN) || + (binfo->fc_ffstate < rp->fc_xmitstate)) { + if (iocb_cmd) { + icmd = &iocb_cmd->iocb; + if ((icmd->ulpCommand != CMD_QUE_RING_BUF_CN) && + (icmd->ulpCommand != CMD_QUE_RING_BUF64_CN) && + (icmd->ulpCommand != CMD_CREATE_XRI_CR)) { + fc_ringtx_put(rp, iocb_cmd); + + FCSTATCTR.NoIssueIocb++; + /* If link is down, just return */ + return(rc); + } + onetime = 1; + } else { + /* If link is down, just return */ + return(rc); + } + } else { + if (iocb_cmd) { + /* Queue command to ring xmit queue */ + fc_ringtx_put(rp, iocb_cmd); + } + if((binfo->fc_process_LA == 0) && + (rp->fc_ringno == FC_FCP_RING)) { + return(rc); + } + } + + p_dev_ctl = (fc_dev_ctl_t *)(binfo->fc_p_dev_ctl); + fc_mpdata_sync(binfo->fc_slim2.dma_handle, 0, 0, DDI_DMA_SYNC_FORKERNEL); + + /* onetime should only be set for QUE_RING_BUF or CREATE_XRI + * iocbs sent with link down. + */ + + /* get the next available command iocb */ + iocb = (IOCB * )IOCB_ENTRY(rp->fc_cmdringaddr, rp->fc_cmdidx); + + portCmdGet = rc; + + if (portCmdGet >= rp->fc_numCiocb) { + if (iocb_cmd) { + /* Queue command to ring xmit queue */ + fc_ringtx_put(rp, iocb_cmd); + } + return(rc); + } + + /* bump iocb available command index */ + if (++rp->fc_cmdidx >= rp->fc_numCiocb) { + rp->fc_cmdidx = 0; + } + + /* While IOCB entries are available */ + while (rp->fc_cmdidx != portCmdGet) { + /* get next command from ring xmit queue */ + if ((onetime == 0) && ((iocb_cmd = fc_ringtx_get(rp)) == NULL)) { +out: + fc_mpdata_sync(binfo->fc_slim2.dma_handle, 0, 0, + DDI_DMA_SYNC_FORKERNEL); + fc_mpdata_sync(binfo->fc_slim2.dma_handle, 0, 0, + DDI_DMA_SYNC_FORDEV); + + /* SLIM POINTER */ + if (binfo->fc_busflag & FC_HOSTPTR) { + rp->fc_cmdidx = + (uchar)PCIMEM_LONG(((SLI2_SLIM * )binfo->fc_slim2.virt)->mbx.us.s2.host[rp->fc_ringno].cmdPutInx); + } else { + void *ioa2; + + ioa = (void *)FC_MAP_MEM(&binfo->fc_iomap_mem); /* map in SLIM */ + ioa2 = (void *)((char *)ioa +((SLIMOFF+(rp->fc_ringno*2))*4)); + rp->fc_cmdidx = (uchar)READ_SLIM_ADDR(binfo, (volatile uint32 *)ioa2); + FC_UNMAP_MEMIO(ioa); + } + + ioa = (void *)FC_MAP_IO(&binfo->fc_iomap_io); /* map in io registers */ + status = ((CA_R0ATT) << (rp->fc_ringno * 4)); + WRITE_CSR_REG(binfo, FC_FF_REG(binfo, ioa), (volatile uint32)status); + FC_UNMAP_MEMIO(ioa); + return(rc); + } + icmd = &iocb_cmd->iocb; + + xx = (uint32 * ) icmd; + /* issue iocb command to adapter */ + fc_pcimem_bcopy((uint32 * )icmd, (uint32 * )iocb, sizeof(IOCB)); + FCSTATCTR.IssueIocb++; + + if ((icmd->ulpCommand == CMD_QUE_RING_BUF_CN) || + (icmd->ulpCommand == CMD_QUE_RING_BUF64_CN) || + (rp->fc_ringno == FC_FCP_RING) || + (icmd->ulpCommand == CMD_ABORT_XRI_CX) || + (icmd->ulpCommand == CMD_ABORT_XRI_CN)) { + fc_mem_put(binfo, MEM_IOCB, (uchar * )iocb_cmd); + } else { + fc_ringtxp_put(rp, iocb_cmd); + } + + /* SLIM POINTER */ + if (binfo->fc_busflag & FC_HOSTPTR) { + ((SLI2_SLIM * )binfo->fc_slim2.virt)->mbx.us.s2.host[rp->fc_ringno].cmdPutInx = PCIMEM_LONG(rp->fc_cmdidx); + } else { + void *ioa2; + + ioa = (void *)FC_MAP_MEM(&binfo->fc_iomap_mem); /* map in SLIM */ + ioa2 = (void *)((char *)ioa +((SLIMOFF+(rp->fc_ringno*2))*4)); + WRITE_SLIM_ADDR(binfo, (volatile uint32 *)ioa2, rp->fc_cmdidx); + FC_UNMAP_MEMIO(ioa); + } + + if (onetime) { + goto out; + } + + /* get the next available command iocb */ + iocb = (IOCB * )IOCB_ENTRY(rp->fc_cmdringaddr, rp->fc_cmdidx); + + /* bump iocb available command index */ + if (++rp->fc_cmdidx >= rp->fc_numCiocb) { + rp->fc_cmdidx = 0; + } + } + + fc_mpdata_sync(binfo->fc_slim2.dma_handle, 0, 0, + DDI_DMA_SYNC_FORKERNEL); + fc_mpdata_sync(binfo->fc_slim2.dma_handle, 0, 0, + DDI_DMA_SYNC_FORDEV); + + /* SLIM POINTER */ + if (binfo->fc_busflag & FC_HOSTPTR) { + rp->fc_cmdidx = + (uchar)PCIMEM_LONG(((SLI2_SLIM * )binfo->fc_slim2.virt)->mbx.us.s2.host[rp->fc_ringno].cmdPutInx); + } else { + void *ioa2; + + ioa = (void *)FC_MAP_MEM(&binfo->fc_iomap_mem); /* map in SLIM */ + ioa2 = (void *)((char *)ioa +((SLIMOFF+(rp->fc_ringno*2))*4)); + rp->fc_cmdidx = (uchar)READ_SLIM_ADDR(binfo, (volatile uint32 *)ioa2); + FC_UNMAP_MEMIO(ioa); + } + + + /* If we get here, iocb list is full */ + /* + * Set ring 'x' to SET R0CE_REQ in Chip Att register. + * Chip will tell us when an entry is freed. + */ + ioa = (void *)FC_MAP_IO(&binfo->fc_iomap_io); /* map in io registers */ + status = ((CA_R0ATT | CA_R0CE_REQ) << (rp->fc_ringno * 4)); + WRITE_CSR_REG(binfo, FC_FF_REG(binfo, ioa), (volatile uint32)status); + FC_UNMAP_MEMIO(ioa); + + FCSTATCTR.iocbRingBusy++; + + if (onetime) { + /* Queue command to ring xmit queue */ + fc_ringtx_put(rp, iocb_cmd); + } + return(rc); +} /* End issue_iocb_cmd */ + + + + +/*****************************************************************************/ +/* + * NAME: fc_brdreset + * + * FUNCTION: hardware reset of adapter is performed + * + * EXECUTION ENVIRONMENT: process only + * + * NOTES: + * + * CALLED FROM: + * fc_cfg_init + * + * INPUT: + * p_dev_ctl - point to the dev_ctl area + * + */ +/*****************************************************************************/ +_static_ void +fc_brdreset ( +fc_dev_ctl_t *p_dev_ctl) /* point to the dev_ctl area */ +{ + uint32 word0; + ushort cfg_value, skip_post; + void *ioa; + FC_BRD_INFO * binfo; + MAILBOX * swpmb; + MAILBOX * mb; + + binfo = &BINFO; + ioa = (void *)FC_MAP_MEM(&binfo->fc_iomap_mem); /* map in SLIM */ + + + /* use REAL SLIM !!! */ + binfo->fc_mboxaddr = 0; + binfo->fc_flag &= ~FC_SLI2; + + /* Reset the board - First put restart command in mailbox */ + mb = FC_MAILBOX(binfo, ioa); + word0 = 0; + swpmb = (MAILBOX * ) & word0; + swpmb->mbxCommand = MBX_RESTART; + swpmb->mbxHc = 1; + WRITE_SLIM_ADDR(binfo, ((volatile uint32 * )mb), word0); + /* Only skip post after fc_ffinit is completed */ + if (binfo->fc_ffstate) { + skip_post = 1; + WRITE_SLIM_ADDR(binfo, (((volatile uint32 * )mb) + 1), 1); /* Skip post */ + } + else { + skip_post = 0; + } + FC_UNMAP_MEMIO(ioa); + + /* Turn off SERR, PERR in PCI cmd register */ + binfo->fc_ffstate = FC_INIT_START; + + cfg_value = fc_rdpci_cmd(p_dev_ctl); + fc_wrpci_cmd(p_dev_ctl, (ushort)(cfg_value & ~(CMD_PARITY_CHK | CMD_SERR_ENBL))); + + ioa = (void *)FC_MAP_IO(&binfo->fc_iomap_io); /* map in io registers */ + + WRITE_CSR_REG(binfo, FC_HC_REG(binfo, ioa), (volatile uint32)HC_INITFF); + DELAYMS(1); + + WRITE_CSR_REG(binfo, FC_HC_REG(binfo, ioa), (volatile uint32)0); + + FC_UNMAP_MEMIO(ioa); + + /* Restore PCI cmd register */ + fc_wrpci_cmd(p_dev_ctl, cfg_value); + + if(skip_post) { + DELAYMS(100); + } + else { + DELAYMS(2000); + } + + binfo->fc_ffstate = FC_INIT_START; + binfo->fc_eventTag = 0; + binfo->fc_myDID = 0; + binfo->fc_prevDID = 0; + p_dev_ctl->power_up = 0; + return; +} diff -purN -X /home/mbligh/.diff.exclude 350-autoswap/drivers/scsi/lpfc/lpfc.conf.c 370-emulex/drivers/scsi/lpfc/lpfc.conf.c --- 350-autoswap/drivers/scsi/lpfc/lpfc.conf.c 1969-12-31 16:00:00.000000000 -0800 +++ 370-emulex/drivers/scsi/lpfc/lpfc.conf.c 2004-02-28 11:20:05.000000000 -0800 @@ -0,0 +1,336 @@ +/******************************************************************* + * This file is part of the Emulex Linux Device Driver for * + * Enterprise Fibre Channel Host Bus Adapters. * + * Refer to the README file included with this package for * + * driver version and adapter support. * + * Copyright (C) 2003 Emulex Corporation. * + * www.emulex.com * + * * + * This program is free software; you can redistribute it and/or * + * modify it under the terms of the GNU General Public License * + * as published by the Free Software Foundation; either version 2 * + * of the License, or (at your option) any later version. * + * * + * This program is distributed in the hope that it will be useful, * + * but WITHOUT ANY WARRANTY; without even the implied warranty of * + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * + * GNU General Public License for more details, a copy of which * + * can be found in the file COPYING included with this package. * + *******************************************************************/ + +#include +#include "fc_os.h" +#include "fc_hw.h" +#include "fc.h" +#include "fcmsg.h" + +/* +# Verbosity: only turn this flag on if you are willing to risk being +# deluged with LOTS of information. +# You can set a bit mask to record specific types of verbose messages: +# +# LOG_ELS 0x1 ELS events +# LOG_DISCOVERY 0x2 Link discovery events +# LOG_MBOX 0x4 Mailbox events +# LOG_INIT 0x8 Initialization events +# LOG_LINK_EVENT 0x10 Link events +# LOG_IP 0x20 IP traffic history +# LOG_FCP 0x40 FCP traffic history +# LOG_NODE 0x80 Node table events +# LOG_MISC 0x400 Miscellaneous events +# LOG_SLI 0x800 SLI events +# LOG_CHK_COND 0x1000 FCP Check condition flag +# LOG_ALL_MSG 0x1fff LOG all messages +*/ +int lpfc_log_verbose =0; + +/* +# Setting log-only to 0 causes log messages to be printed on the +# console and to be logged to syslog (which may send them to the +# console again if it's configured to do so). +# Setting log-only to 1 causes log messages to go to syslog only. +*/ +int lpfc_log_only =0; + +/* +# lun-queue-depth: the default value lpfc will use to limit +# the number of outstanding commands per FCP LUN. This value is +# global, affecting each LUN recognized by the driver. +*/ +int lpfc_lun_queue_depth =30; + +/* +# lpfc_lun_skip : Is a LINUX OS parameter to support LUN skipping / no LUN +# If this is set to 1, lpfc will fake out the LINUX scsi layer to allow +# it to detect all LUNs if there are LUN holes on a device. +*/ +int lpfc_lun_skip=0; + +/* +# tgt-queue-depth: the default value lpfc will use to limit +# the number of outstanding commands per FCP target. This value is +# global, affecting each target recognized by the driver. +*/ +int lpfc_tgt_queue_depth =0; + +/* +# no-device-delay [0 or 1 to 30] - determines the length of +# the interval between deciding to fail back an I/O because there is no way +# to communicate with its particular device (e.g., due to device failure) and +# the actual fail back. A value of zero implies no delay whatsoever. +# Cautions: (1) This value is in seconds. +# (2) Setting a long delay value may permit I/O to build up, +# each with a pending timeout, which could result in the exhaustion of +# critical LINUX kernel resources. +# +# Note that this value can have an impact on the speed with which a +# system can shut down with I/Os pending and with the HBA not able to +# communicate with the loop or fabric, e.g., with a cable pulled. +*/ +int lpfc_no_device_delay =1; + +/* +# +++ Variables relating to IP networking support. +++ +*/ + +/* +# network-on: true (1) if networking is enabled, false (0) if not +*/ +int lpfc_network_on = 0; + +/* +# xmt-que-size: size of the transmit queue for mbufs (128 - 10240) +*/ +int lpfc_xmt_que_size = 256; + +/* +# +++ Variables common to both SCSI (FCP) and IP networking support. +++ +*/ + +/* +# Some disk devices have a "select ID" or "select Target" capability. +# From a protocol standpoint "select ID" usually means select the +# Fibre channel "ALPA". In the FC-AL Profile there is an "informative +# annex" which contains a table that maps a "select ID" (a number +# between 0 and 7F) to an ALPA. By default, for compatibility with +# older drivers, the lpfc driver scans its ALPA map from low ALPA +# to high ALPA. +# +# Turning on the scan-down variable (on = 1, off = 0) will +# cause the lpfc driver to use an inverted ALPA map, effectively +# scanning ALPAs from high to low as specified in the FC-AL annex. +# A value of 2, will also cause target assignment in a private loop +# environment to be based on the ALPA. Persistent bindings should NOT be +# used if scan-down is 2. +# +# (Note: This "select ID" functionality is a LOOP ONLY characteristic +# and will not work across a fabric.) +*/ +int lpfc_scandown =2; + +/* +# Determine how long the driver will wait to begin linkdown processing +# when a cable has been pulled or the link has otherwise become +# inaccessible, 1 - 255 secs. Linkdown processing includes failing back +# cmds to the target driver that have been waiting around for the link +# to come back up. There's a tradeoff here: small values of the timer +# cause the link to appear to "bounce", while large values of the +# timer can delay failover in a fault tolerant environment. Units are in +# seconds. A value of 0 means never failback cmds until the link comes up. +*/ +int lpfc_linkdown_tmo =30; + +/* +# If set, nodev-holdio will hold all I/O errors on devices that disappear +# until they come back. Default is 0, return errors with no-device-delay +*/ +int lpfc_nodev_holdio =0; + +/* +# If set, nodev-tmo will hold all I/O errors on devices that disappear +# until the timer expires. Default is 0, return errors with no-device-delay. +*/ +int lpfc_nodev_tmo =30; + +/* +# Use no-device-delay to delay FCP RSP errors and certain check conditions +*/ +int lpfc_delay_rsp_err =1; + +/* +# Treat certain check conditions as a FCP error +*/ +int lpfc_check_cond_err =1; + +/* +# num-iocbs: number of iocb buffers to allocate (128 to 10240) +*/ +int lpfc_num_iocbs = 2048; + +/* +# num-bufs: number of ELS buffers to allocate (64 to 4096) +# ELS buffers are needed to support Fibre channel Extended Link Services. +# Also used for SLI-2 FCP buffers, one per FCP command, and Mailbox commands. +*/ +int lpfc_num_bufs = 4096; + +/* +# topology: link topology for init link +# 0x0 = attempt loop mode then point-to-point +# 0x02 = attempt point-to-point mode only +# 0x04 = attempt loop mode only +# 0x06 = attempt point-to-point mode then loop +# Set point-to-point mode if you want to run as an N_Port. +# Set loop mode if you want to run as an NL_Port. +*/ +int lpfc_topology = 0; + +/* +# link-speed:link speed selection for initializing the Fibre Channel connection. +# 0 = auto select (default) +# 1 = 1 Gigabaud +# 2 = 2 Gigabaud +*/ +int lpfc_link_speed = 0; + +/* +# ip-class: FC class (2 or 3) to use for the IP protocol. +*/ +int lpfc_ip_class = 3; + +/* +# fcp-class: FC class (2 or 3) to use for the FCP protocol. +*/ +int lpfc_fcp_class = 3; + +/* +# Use ADISC for FCP rediscovery instead of PLOGI +*/ +int lpfc_use_adisc =0; + +/* +# Extra FCP timeout for fabrics +*/ +int lpfc_fcpfabric_tmo =0; + +/* +# Number of 4k STREAMS buffers to post to IP ring +*/ +int lpfc_post_ip_buf =128; + +/* +#Use dqfull-throttle-up-time to specify when to increment the current Q depth. +# This variable is in seconds. +*/ +int lpfc_dqfull_throttle_up_time =1; + +/* +# Increment the current Q depth by dqfull-throttle-up-inc +*/ +int lpfc_dqfull_throttle_up_inc =1; + +/* +# Use ACK0, instead of ACK1 for class 2 acknowledgement +*/ +int lpfc_ack0support =0; + +/* +# Vendor specific flag for vendor specifc actions. +*/ +int lpfc_vendor =0x1; + +/* +# Linux does not scan past lun 0 is it's missing. Emulex driver can +# work around this limitation if this feature is on (1). +*/ +int lpfc_lun0_missing =0; + +/* +# When a disk disapears, fiber cable being disconnected for example, +# this option will report it missing BUT removable. This allows +# Linux to re-discover the disk later on without scan, when the cable +# is re-connected in our example. +# Warning: when this option is set, statuses and timeout values on +# disk missing reported to the kernel may have an effect +# on other software packages like failover, multipath, etc... +*/ +int lpfc_use_removable =1; + +/* +# specified the maximum number of luns per target. A value of 20 means +# luns from 0 to 19 are valid. +# Default of 0 means to use driver's maximum of 256. + */ +int lpfc_max_lun =0; + +/* +# When the scsi layer passes the driver a command, the SCSI command structure +# has a field in it, sc_data_direction, to indicate if the SCSI command is a +# read or a write SCSI operation. Under some instances, this field is invalid +# and the SCSI opcode can be used to determine the type of SCSI operation. If +# wish to use the SCSI opcode, set this to 0. +# Note: For LINUX kernel revisions <= 2.4.4, this is ignored and the SCSI +# opcode is always used. +*/ +int lpfc_use_data_direction =1; + +/* +# Setup FCP persistent bindings, +# fcp-bind-WWPN binds a specific WorldWide PortName to a target id, +# fcp-bind-WWNN binds a specific WorldWide NodeName to a target id, +# fcp-bind-DID binds a specific DID to a target id. +# Only one binding method can be used. "lpfc_automap" needs to +# be changed to 0 and scan-down should NOT be set to 2 +# when one of these binding methods is used. +# WWNN, WWPN and DID are hexadecimal values. +# WWNN must be 16 digit BCD with leading 0s. +# WWPN must be 16 digit BCD with leading 0s. +# DID must be 6 digit BCD with leading 0s. +# The SCSI ID to bind to consists of two parts, the lpfc interface +# to bind to, and the target number for that interface. +# Thus lpfc0t2 specifies target 2 on interface lpfc0. +# +# Here are some examples: +# WWNN SCSI ID +# char *lpfc_fcp_bind_WWNN[]={"22000020370b8275:lpfc0t1", +# "22000020370b8998:lpfc0t2"}; +# +# WWPN SCSI ID +# char *lpfc_fcp_bind_WWPN[]={"22000020370b8275:lpfc0t1", +# "22000020370b8998:lpfc0t2"}; +# +# DID SCSI ID +# char *lpfc_fcp_bind_DID[]={"0000dc:lpfc0t1", +# "0000e0:lpfc0t2"}; +# +*/ +int lpfc_bind_entries =0; +char *lpfc_fcp_bind_WWNN[MAX_FC_BINDINGS]; +char *lpfc_fcp_bind_WWPN[MAX_FC_BINDINGS]; +char *lpfc_fcp_bind_DID[MAX_FC_BINDINGS]; + +/* +# If automap is set, SCSI IDs for all FCP nodes without +# persistent bindings will be automatically generated. +# If new FCP devices are added to the network when the system is down, +# there is no guarantee that these SCSI IDs will remain the same +# when the system is booted again. +# If one of the above fcp binding methods is specified, then automap +# devices will use the same mapping method to preserve +# SCSI IDs between link down and link up. +# If no bindings are specified above, a value of 1 will force WWNN +# binding, 2 for WWPN binding, and 3 for DID binding. +# If automap is 0, only devices with persistent bindings will be +# recognized by the system. +*/ +int lpfc_automap =2; + +/* +# Default values for I/O colaesing +# cr_delay ms or cr_count outstanding commands +*/ +int lpfc_cr_delay =0; +int lpfc_cr_count =0; + + + diff -purN -X /home/mbligh/.diff.exclude 350-autoswap/drivers/scsi/lpfc/lpfc.conf.defs 370-emulex/drivers/scsi/lpfc/lpfc.conf.defs --- 350-autoswap/drivers/scsi/lpfc/lpfc.conf.defs 1969-12-31 16:00:00.000000000 -0800 +++ 370-emulex/drivers/scsi/lpfc/lpfc.conf.defs 2004-02-28 11:20:05.000000000 -0800 @@ -0,0 +1,3380 @@ +/******************************************************************* + * This file is part of the Emulex Linux Device Driver for * + * Enterprise Fibre Channel Host Bus Adapters. * + * Refer to the README file included with this package for * + * driver version and adapter support. * + * Copyright (C) 2003 Emulex Corporation. * + * www.emulex.com * + * * + * This program is free software; you can redistribute it and/or * + * modify it under the terms of the GNU General Public License * + * as published by the Free Software Foundation; either version 2 * + * of the License, or (at your option) any later version. * + * * + * This program is distributed in the hope that it will be useful, * + * but WITHOUT ANY WARRANTY; without even the implied warranty of * + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * + * GNU General Public License for more details, a copy of which * + * can be found in the file COPYING included with this package. * + *******************************************************************/ + +/* This file is to support different configurations for each HBA */ +/* HBA 0 */ +#ifdef MODULE_PARM +MODULE_PARM(lpfc0_log_verbose, "i"); +MODULE_PARM(lpfc0_log_only, "i"); +MODULE_PARM(lpfc0_lun_queue_depth, "i"); +MODULE_PARM(lpfc0_tgt_queue_depth, "i"); +MODULE_PARM(lpfc0_no_device_delay, "i"); +MODULE_PARM(lpfc0_network_on, "i"); +MODULE_PARM(lpfc0_xmt_que_size, "i"); +MODULE_PARM(lpfc0_scandown, "i"); +MODULE_PARM(lpfc0_linkdown_tmo, "i"); +MODULE_PARM(lpfc0_nodev_tmo, "i"); +MODULE_PARM(lpfc0_delay_rsp_err, "i"); +MODULE_PARM(lpfc0_nodev_holdio, "i"); +MODULE_PARM(lpfc0_check_cond_err, "i"); +MODULE_PARM(lpfc0_num_iocbs, "i"); +MODULE_PARM(lpfc0_num_bufs, "i"); +MODULE_PARM(lpfc0_topology, "i"); +MODULE_PARM(lpfc0_link_speed, "i"); +MODULE_PARM(lpfc0_ip_class, "i"); +MODULE_PARM(lpfc0_fcp_class, "i"); +MODULE_PARM(lpfc0_use_adisc, "i"); +MODULE_PARM(lpfc0_fcpfabric_tmo, "i"); +MODULE_PARM(lpfc0_post_ip_buf, "i"); +MODULE_PARM(lpfc0_dqfull_throttle_up_time, "i"); +MODULE_PARM(lpfc0_dqfull_throttle_up_inc, "i"); +MODULE_PARM(lpfc0_ack0support, "i"); +MODULE_PARM(lpfc0_automap, "i"); +MODULE_PARM(lpfc0_cr_delay, "i"); +MODULE_PARM(lpfc0_cr_count, "i"); +#endif + +static int lpfc0_log_verbose = -1; +static int lpfc0_log_only = -1; +static int lpfc0_lun_queue_depth = -1; +static int lpfc0_tgt_queue_depth = -1; +static int lpfc0_no_device_delay = -1; +static int lpfc0_network_on = -1; +static int lpfc0_xmt_que_size = -1; +static int lpfc0_scandown = -1; +static int lpfc0_linkdown_tmo = -1; +static int lpfc0_nodev_tmo = -1; +static int lpfc0_delay_rsp_err = -1; +static int lpfc0_nodev_holdio = -1; +static int lpfc0_check_cond_err = -1; +static int lpfc0_num_iocbs = -1; +static int lpfc0_num_bufs = -1; +static int lpfc0_topology = -1; +static int lpfc0_link_speed = -1; +static int lpfc0_ip_class = -1; +static int lpfc0_fcp_class = -1; +static int lpfc0_use_adisc = -1; +static int lpfc0_fcpfabric_tmo = -1; +static int lpfc0_post_ip_buf = -1; +static int lpfc0_dqfull_throttle_up_time = -1; +static int lpfc0_dqfull_throttle_up_inc = -1; +static int lpfc0_ack0support = -1; +static int lpfc0_automap = -1; +static int lpfc0_cr_delay = -1; +static int lpfc0_cr_count = -1; + +/* HBA 1 */ +#ifdef MODULE_PARM +MODULE_PARM(lpfc1_log_verbose, "i"); +MODULE_PARM(lpfc1_log_only, "i"); +MODULE_PARM(lpfc1_lun_queue_depth, "i"); +MODULE_PARM(lpfc1_tgt_queue_depth, "i"); +MODULE_PARM(lpfc1_no_device_delay, "i"); +MODULE_PARM(lpfc1_network_on, "i"); +MODULE_PARM(lpfc1_xmt_que_size, "i"); +MODULE_PARM(lpfc1_scandown, "i"); +MODULE_PARM(lpfc1_linkdown_tmo, "i"); +MODULE_PARM(lpfc1_nodev_tmo, "i"); +MODULE_PARM(lpfc1_delay_rsp_err, "i"); +MODULE_PARM(lpfc1_nodev_holdio, "i"); +MODULE_PARM(lpfc1_check_cond_err, "i"); +MODULE_PARM(lpfc1_num_iocbs, "i"); +MODULE_PARM(lpfc1_num_bufs, "i"); +MODULE_PARM(lpfc1_topology, "i"); +MODULE_PARM(lpfc1_link_speed, "i"); +MODULE_PARM(lpfc1_ip_class, "i"); +MODULE_PARM(lpfc1_fcp_class, "i"); +MODULE_PARM(lpfc1_use_adisc, "i"); +MODULE_PARM(lpfc1_fcpfabric_tmo, "i"); +MODULE_PARM(lpfc1_post_ip_buf, "i"); +MODULE_PARM(lpfc1_dqfull_throttle_up_time, "i"); +MODULE_PARM(lpfc1_dqfull_throttle_up_inc, "i"); +MODULE_PARM(lpfc1_ack0support, "i"); +MODULE_PARM(lpfc1_automap, "i"); +MODULE_PARM(lpfc1_cr_delay, "i"); +MODULE_PARM(lpfc1_cr_count, "i"); +#endif + +static int lpfc1_log_verbose = -1; +static int lpfc1_log_only = -1; +static int lpfc1_lun_queue_depth = -1; +static int lpfc1_tgt_queue_depth = -1; +static int lpfc1_no_device_delay = -1; +static int lpfc1_network_on = -1; +static int lpfc1_xmt_que_size = -1; +static int lpfc1_scandown = -1; +static int lpfc1_linkdown_tmo = -1; +static int lpfc1_nodev_tmo = -1; +static int lpfc1_delay_rsp_err = -1; +static int lpfc1_nodev_holdio = -1; +static int lpfc1_check_cond_err = -1; +static int lpfc1_num_iocbs = -1; +static int lpfc1_num_bufs = -1; +static int lpfc1_topology = -1; +static int lpfc1_link_speed = -1; +static int lpfc1_ip_class = -1; +static int lpfc1_fcp_class = -1; +static int lpfc1_use_adisc = -1; +static int lpfc1_fcpfabric_tmo = -1; +static int lpfc1_post_ip_buf = -1; +static int lpfc1_dqfull_throttle_up_time = -1; +static int lpfc1_dqfull_throttle_up_inc = -1; +static int lpfc1_ack0support = -1; +static int lpfc1_automap = -1; +static int lpfc1_cr_delay = -1; +static int lpfc1_cr_count = -1; + +/* HBA 2 */ +#ifdef MODULE_PARM +MODULE_PARM(lpfc2_log_verbose, "i"); +MODULE_PARM(lpfc2_log_only, "i"); +MODULE_PARM(lpfc2_lun_queue_depth, "i"); +MODULE_PARM(lpfc2_tgt_queue_depth, "i"); +MODULE_PARM(lpfc2_no_device_delay, "i"); +MODULE_PARM(lpfc2_network_on, "i"); +MODULE_PARM(lpfc2_xmt_que_size, "i"); +MODULE_PARM(lpfc2_scandown, "i"); +MODULE_PARM(lpfc2_linkdown_tmo, "i"); +MODULE_PARM(lpfc2_nodev_tmo, "i"); +MODULE_PARM(lpfc2_delay_rsp_err, "i"); +MODULE_PARM(lpfc2_nodev_holdio, "i"); +MODULE_PARM(lpfc2_check_cond_err, "i"); +MODULE_PARM(lpfc2_num_iocbs, "i"); +MODULE_PARM(lpfc2_num_bufs, "i"); +MODULE_PARM(lpfc2_topology, "i"); +MODULE_PARM(lpfc2_link_speed, "i"); +MODULE_PARM(lpfc2_ip_class, "i"); +MODULE_PARM(lpfc2_fcp_class, "i"); +MODULE_PARM(lpfc2_use_adisc, "i"); +MODULE_PARM(lpfc2_fcpfabric_tmo, "i"); +MODULE_PARM(lpfc2_post_ip_buf, "i"); +MODULE_PARM(lpfc2_dqfull_throttle_up_time, "i"); +MODULE_PARM(lpfc2_dqfull_throttle_up_inc, "i"); +MODULE_PARM(lpfc2_ack0support, "i"); +MODULE_PARM(lpfc2_automap, "i"); +MODULE_PARM(lpfc2_cr_delay, "i"); +MODULE_PARM(lpfc2_cr_count, "i"); +#endif + +static int lpfc2_log_verbose = -1; +static int lpfc2_log_only = -1; +static int lpfc2_lun_queue_depth = -1; +static int lpfc2_tgt_queue_depth = -1; +static int lpfc2_no_device_delay = -1; +static int lpfc2_network_on = -1; +static int lpfc2_xmt_que_size = -1; +static int lpfc2_scandown = -1; +static int lpfc2_linkdown_tmo = -1; +static int lpfc2_nodev_tmo = -1; +static int lpfc2_delay_rsp_err = -1; +static int lpfc2_nodev_holdio = -1; +static int lpfc2_check_cond_err = -1; +static int lpfc2_num_iocbs = -1; +static int lpfc2_num_bufs = -1; +static int lpfc2_topology = -1; +static int lpfc2_link_speed = -1; +static int lpfc2_ip_class = -1; +static int lpfc2_fcp_class = -1; +static int lpfc2_use_adisc = -1; +static int lpfc2_fcpfabric_tmo = -1; +static int lpfc2_post_ip_buf = -1; +static int lpfc2_dqfull_throttle_up_time = -1; +static int lpfc2_dqfull_throttle_up_inc = -1; +static int lpfc2_ack0support = -1; +static int lpfc2_automap = -1; +static int lpfc2_cr_delay = -1; +static int lpfc2_cr_count = -1; + +/* HBA 3 */ +#ifdef MODULE_PARM +MODULE_PARM(lpfc3_log_verbose, "i"); +MODULE_PARM(lpfc3_log_only, "i"); +MODULE_PARM(lpfc3_lun_queue_depth, "i"); +MODULE_PARM(lpfc3_tgt_queue_depth, "i"); +MODULE_PARM(lpfc3_no_device_delay, "i"); +MODULE_PARM(lpfc3_network_on, "i"); +MODULE_PARM(lpfc3_xmt_que_size, "i"); +MODULE_PARM(lpfc3_scandown, "i"); +MODULE_PARM(lpfc3_linkdown_tmo, "i"); +MODULE_PARM(lpfc3_nodev_tmo, "i"); +MODULE_PARM(lpfc3_delay_rsp_err, "i"); +MODULE_PARM(lpfc3_nodev_holdio, "i"); +MODULE_PARM(lpfc3_check_cond_err, "i"); +MODULE_PARM(lpfc3_num_iocbs, "i"); +MODULE_PARM(lpfc3_num_bufs, "i"); +MODULE_PARM(lpfc3_topology, "i"); +MODULE_PARM(lpfc3_link_speed, "i"); +MODULE_PARM(lpfc3_ip_class, "i"); +MODULE_PARM(lpfc3_fcp_class, "i"); +MODULE_PARM(lpfc3_use_adisc, "i"); +MODULE_PARM(lpfc3_fcpfabric_tmo, "i"); +MODULE_PARM(lpfc3_post_ip_buf, "i"); +MODULE_PARM(lpfc3_dqfull_throttle_up_time, "i"); +MODULE_PARM(lpfc3_dqfull_throttle_up_inc, "i"); +MODULE_PARM(lpfc3_ack0support, "i"); +MODULE_PARM(lpfc3_automap, "i"); +MODULE_PARM(lpfc3_cr_delay, "i"); +MODULE_PARM(lpfc3_cr_count, "i"); +#endif + +static int lpfc3_log_verbose = -1; +static int lpfc3_log_only = -1; +static int lpfc3_lun_queue_depth = -1; +static int lpfc3_tgt_queue_depth = -1; +static int lpfc3_no_device_delay = -1; +static int lpfc3_network_on = -1; +static int lpfc3_xmt_que_size = -1; +static int lpfc3_scandown = -1; +static int lpfc3_linkdown_tmo = -1; +static int lpfc3_nodev_tmo = -1; +static int lpfc3_delay_rsp_err = -1; +static int lpfc3_nodev_holdio = -1; +static int lpfc3_check_cond_err = -1; +static int lpfc3_num_iocbs = -1; +static int lpfc3_num_bufs = -1; +static int lpfc3_topology = -1; +static int lpfc3_link_speed = -1; +static int lpfc3_ip_class = -1; +static int lpfc3_fcp_class = -1; +static int lpfc3_use_adisc = -1; +static int lpfc3_fcpfabric_tmo = -1; +static int lpfc3_post_ip_buf = -1; +static int lpfc3_dqfull_throttle_up_time = -1; +static int lpfc3_dqfull_throttle_up_inc = -1; +static int lpfc3_ack0support = -1; +static int lpfc3_automap = -1; +static int lpfc3_cr_delay = -1; +static int lpfc3_cr_count = -1; + +/* HBA 4 */ +#ifdef MODULE_PARM +MODULE_PARM(lpfc4_log_verbose, "i"); +MODULE_PARM(lpfc4_log_only, "i"); +MODULE_PARM(lpfc4_lun_queue_depth, "i"); +MODULE_PARM(lpfc4_tgt_queue_depth, "i"); +MODULE_PARM(lpfc4_no_device_delay, "i"); +MODULE_PARM(lpfc4_network_on, "i"); +MODULE_PARM(lpfc4_xmt_que_size, "i"); +MODULE_PARM(lpfc4_scandown, "i"); +MODULE_PARM(lpfc4_linkdown_tmo, "i"); +MODULE_PARM(lpfc4_nodev_tmo, "i"); +MODULE_PARM(lpfc4_delay_rsp_err, "i"); +MODULE_PARM(lpfc4_nodev_holdio, "i"); +MODULE_PARM(lpfc4_check_cond_err, "i"); +MODULE_PARM(lpfc4_num_iocbs, "i"); +MODULE_PARM(lpfc4_num_bufs, "i"); +MODULE_PARM(lpfc4_topology, "i"); +MODULE_PARM(lpfc4_link_speed, "i"); +MODULE_PARM(lpfc4_ip_class, "i"); +MODULE_PARM(lpfc4_fcp_class, "i"); +MODULE_PARM(lpfc4_use_adisc, "i"); +MODULE_PARM(lpfc4_fcpfabric_tmo, "i"); +MODULE_PARM(lpfc4_post_ip_buf, "i"); +MODULE_PARM(lpfc4_dqfull_throttle_up_time, "i"); +MODULE_PARM(lpfc4_dqfull_throttle_up_inc, "i"); +MODULE_PARM(lpfc4_ack0support, "i"); +MODULE_PARM(lpfc4_automap, "i"); +MODULE_PARM(lpfc4_cr_delay, "i"); +MODULE_PARM(lpfc4_cr_count, "i"); +#endif + +static int lpfc4_log_verbose = -1; +static int lpfc4_log_only = -1; +static int lpfc4_lun_queue_depth = -1; +static int lpfc4_tgt_queue_depth = -1; +static int lpfc4_no_device_delay = -1; +static int lpfc4_network_on = -1; +static int lpfc4_xmt_que_size = -1; +static int lpfc4_scandown = -1; +static int lpfc4_linkdown_tmo = -1; +static int lpfc4_nodev_tmo = -1; +static int lpfc4_delay_rsp_err = -1; +static int lpfc4_nodev_holdio = -1; +static int lpfc4_check_cond_err = -1; +static int lpfc4_num_iocbs = -1; +static int lpfc4_num_bufs = -1; +static int lpfc4_topology = -1; +static int lpfc4_link_speed = -1; +static int lpfc4_ip_class = -1; +static int lpfc4_fcp_class = -1; +static int lpfc4_use_adisc = -1; +static int lpfc4_fcpfabric_tmo = -1; +static int lpfc4_post_ip_buf = -1; +static int lpfc4_dqfull_throttle_up_time = -1; +static int lpfc4_dqfull_throttle_up_inc = -1; +static int lpfc4_ack0support = -1; +static int lpfc4_automap = -1; +static int lpfc4_cr_delay = -1; +static int lpfc4_cr_count = -1; + +/* HBA 5 */ +#ifdef MODULE_PARM +MODULE_PARM(lpfc5_log_verbose, "i"); +MODULE_PARM(lpfc5_log_only, "i"); +MODULE_PARM(lpfc5_lun_queue_depth, "i"); +MODULE_PARM(lpfc5_tgt_queue_depth, "i"); +MODULE_PARM(lpfc5_no_device_delay, "i"); +MODULE_PARM(lpfc5_network_on, "i"); +MODULE_PARM(lpfc5_xmt_que_size, "i"); +MODULE_PARM(lpfc5_scandown, "i"); +MODULE_PARM(lpfc5_linkdown_tmo, "i"); +MODULE_PARM(lpfc5_nodev_tmo, "i"); +MODULE_PARM(lpfc5_delay_rsp_err, "i"); +MODULE_PARM(lpfc5_nodev_holdio, "i"); +MODULE_PARM(lpfc5_check_cond_err, "i"); +MODULE_PARM(lpfc5_num_iocbs, "i"); +MODULE_PARM(lpfc5_num_bufs, "i"); +MODULE_PARM(lpfc5_topology, "i"); +MODULE_PARM(lpfc5_link_speed, "i"); +MODULE_PARM(lpfc5_ip_class, "i"); +MODULE_PARM(lpfc5_fcp_class, "i"); +MODULE_PARM(lpfc5_use_adisc, "i"); +MODULE_PARM(lpfc5_fcpfabric_tmo, "i"); +MODULE_PARM(lpfc5_post_ip_buf, "i"); +MODULE_PARM(lpfc5_dqfull_throttle_up_time, "i"); +MODULE_PARM(lpfc5_dqfull_throttle_up_inc, "i"); +MODULE_PARM(lpfc5_ack0support, "i"); +MODULE_PARM(lpfc5_automap, "i"); +MODULE_PARM(lpfc5_cr_delay, "i"); +MODULE_PARM(lpfc5_cr_count, "i"); +#endif + +static int lpfc5_log_verbose = -1; +static int lpfc5_log_only = -1; +static int lpfc5_lun_queue_depth = -1; +static int lpfc5_tgt_queue_depth = -1; +static int lpfc5_no_device_delay = -1; +static int lpfc5_network_on = -1; +static int lpfc5_xmt_que_size = -1; +static int lpfc5_scandown = -1; +static int lpfc5_linkdown_tmo = -1; +static int lpfc5_nodev_tmo = -1; +static int lpfc5_delay_rsp_err = -1; +static int lpfc5_nodev_holdio = -1; +static int lpfc5_check_cond_err = -1; +static int lpfc5_num_iocbs = -1; +static int lpfc5_num_bufs = -1; +static int lpfc5_topology = -1; +static int lpfc5_link_speed = -1; +static int lpfc5_ip_class = -1; +static int lpfc5_fcp_class = -1; +static int lpfc5_use_adisc = -1; +static int lpfc5_fcpfabric_tmo = -1; +static int lpfc5_post_ip_buf = -1; +static int lpfc5_dqfull_throttle_up_time = -1; +static int lpfc5_dqfull_throttle_up_inc = -1; +static int lpfc5_ack0support = -1; +static int lpfc5_automap = -1; +static int lpfc5_cr_delay = -1; +static int lpfc5_cr_count = -1; + +/* HBA 6 */ +#ifdef MODULE_PARM +MODULE_PARM(lpfc6_log_verbose, "i"); +MODULE_PARM(lpfc6_log_only, "i"); +MODULE_PARM(lpfc6_lun_queue_depth, "i"); +MODULE_PARM(lpfc6_tgt_queue_depth, "i"); +MODULE_PARM(lpfc6_no_device_delay, "i"); +MODULE_PARM(lpfc6_network_on, "i"); +MODULE_PARM(lpfc6_xmt_que_size, "i"); +MODULE_PARM(lpfc6_scandown, "i"); +MODULE_PARM(lpfc6_linkdown_tmo, "i"); +MODULE_PARM(lpfc6_nodev_tmo, "i"); +MODULE_PARM(lpfc6_delay_rsp_err, "i"); +MODULE_PARM(lpfc6_nodev_holdio, "i"); +MODULE_PARM(lpfc6_check_cond_err, "i"); +MODULE_PARM(lpfc6_num_iocbs, "i"); +MODULE_PARM(lpfc6_num_bufs, "i"); +MODULE_PARM(lpfc6_topology, "i"); +MODULE_PARM(lpfc6_link_speed, "i"); +MODULE_PARM(lpfc6_ip_class, "i"); +MODULE_PARM(lpfc6_fcp_class, "i"); +MODULE_PARM(lpfc6_use_adisc, "i"); +MODULE_PARM(lpfc6_fcpfabric_tmo, "i"); +MODULE_PARM(lpfc6_post_ip_buf, "i"); +MODULE_PARM(lpfc6_dqfull_throttle_up_time, "i"); +MODULE_PARM(lpfc6_dqfull_throttle_up_inc, "i"); +MODULE_PARM(lpfc6_ack0support, "i"); +MODULE_PARM(lpfc6_automap, "i"); +MODULE_PARM(lpfc6_cr_delay, "i"); +MODULE_PARM(lpfc6_cr_count, "i"); +#endif + +static int lpfc6_log_verbose = -1; +static int lpfc6_log_only = -1; +static int lpfc6_lun_queue_depth = -1; +static int lpfc6_tgt_queue_depth = -1; +static int lpfc6_no_device_delay = -1; +static int lpfc6_network_on = -1; +static int lpfc6_xmt_que_size = -1; +static int lpfc6_scandown = -1; +static int lpfc6_linkdown_tmo = -1; +static int lpfc6_nodev_tmo = -1; +static int lpfc6_delay_rsp_err = -1; +static int lpfc6_nodev_holdio = -1; +static int lpfc6_check_cond_err = -1; +static int lpfc6_num_iocbs = -1; +static int lpfc6_num_bufs = -1; +static int lpfc6_topology = -1; +static int lpfc6_link_speed = -1; +static int lpfc6_ip_class = -1; +static int lpfc6_fcp_class = -1; +static int lpfc6_use_adisc = -1; +static int lpfc6_fcpfabric_tmo = -1; +static int lpfc6_post_ip_buf = -1; +static int lpfc6_dqfull_throttle_up_time = -1; +static int lpfc6_dqfull_throttle_up_inc = -1; +static int lpfc6_ack0support = -1; +static int lpfc6_automap = -1; +static int lpfc6_cr_delay = -1; +static int lpfc6_cr_count = -1; + +/* HBA 7 */ +#ifdef MODULE_PARM +MODULE_PARM(lpfc7_log_verbose, "i"); +MODULE_PARM(lpfc7_log_only, "i"); +MODULE_PARM(lpfc7_lun_queue_depth, "i"); +MODULE_PARM(lpfc7_tgt_queue_depth, "i"); +MODULE_PARM(lpfc7_no_device_delay, "i"); +MODULE_PARM(lpfc7_network_on, "i"); +MODULE_PARM(lpfc7_xmt_que_size, "i"); +MODULE_PARM(lpfc7_scandown, "i"); +MODULE_PARM(lpfc7_linkdown_tmo, "i"); +MODULE_PARM(lpfc7_nodev_tmo, "i"); +MODULE_PARM(lpfc7_delay_rsp_err, "i"); +MODULE_PARM(lpfc7_nodev_holdio, "i"); +MODULE_PARM(lpfc7_check_cond_err, "i"); +MODULE_PARM(lpfc7_num_iocbs, "i"); +MODULE_PARM(lpfc7_num_bufs, "i"); +MODULE_PARM(lpfc7_topology, "i"); +MODULE_PARM(lpfc7_link_speed, "i"); +MODULE_PARM(lpfc7_ip_class, "i"); +MODULE_PARM(lpfc7_fcp_class, "i"); +MODULE_PARM(lpfc7_use_adisc, "i"); +MODULE_PARM(lpfc7_fcpfabric_tmo, "i"); +MODULE_PARM(lpfc7_post_ip_buf, "i"); +MODULE_PARM(lpfc7_dqfull_throttle_up_time, "i"); +MODULE_PARM(lpfc7_dqfull_throttle_up_inc, "i"); +MODULE_PARM(lpfc7_ack0support, "i"); +MODULE_PARM(lpfc7_automap, "i"); +MODULE_PARM(lpfc7_cr_delay, "i"); +MODULE_PARM(lpfc7_cr_count, "i"); +#endif + +static int lpfc7_log_verbose = -1; +static int lpfc7_log_only = -1; +static int lpfc7_lun_queue_depth = -1; +static int lpfc7_tgt_queue_depth = -1; +static int lpfc7_no_device_delay = -1; +static int lpfc7_network_on = -1; +static int lpfc7_xmt_que_size = -1; +static int lpfc7_scandown = -1; +static int lpfc7_linkdown_tmo = -1; +static int lpfc7_nodev_tmo = -1; +static int lpfc7_delay_rsp_err = -1; +static int lpfc7_nodev_holdio = -1; +static int lpfc7_check_cond_err = -1; +static int lpfc7_num_iocbs = -1; +static int lpfc7_num_bufs = -1; +static int lpfc7_topology = -1; +static int lpfc7_link_speed = -1; +static int lpfc7_ip_class = -1; +static int lpfc7_fcp_class = -1; +static int lpfc7_use_adisc = -1; +static int lpfc7_fcpfabric_tmo = -1; +static int lpfc7_post_ip_buf = -1; +static int lpfc7_dqfull_throttle_up_time = -1; +static int lpfc7_dqfull_throttle_up_inc = -1; +static int lpfc7_ack0support = -1; +static int lpfc7_automap = -1; +static int lpfc7_cr_delay = -1; +static int lpfc7_cr_count = -1; + +/* HBA 8 */ +#ifdef MODULE_PARM +MODULE_PARM(lpfc8_log_verbose, "i"); +MODULE_PARM(lpfc8_log_only, "i"); +MODULE_PARM(lpfc8_lun_queue_depth, "i"); +MODULE_PARM(lpfc8_tgt_queue_depth, "i"); +MODULE_PARM(lpfc8_no_device_delay, "i"); +MODULE_PARM(lpfc8_network_on, "i"); +MODULE_PARM(lpfc8_xmt_que_size, "i"); +MODULE_PARM(lpfc8_scandown, "i"); +MODULE_PARM(lpfc8_linkdown_tmo, "i"); +MODULE_PARM(lpfc8_nodev_tmo, "i"); +MODULE_PARM(lpfc8_delay_rsp_err, "i"); +MODULE_PARM(lpfc8_nodev_holdio, "i"); +MODULE_PARM(lpfc8_check_cond_err, "i"); +MODULE_PARM(lpfc8_num_iocbs, "i"); +MODULE_PARM(lpfc8_num_bufs, "i"); +MODULE_PARM(lpfc8_topology, "i"); +MODULE_PARM(lpfc8_link_speed, "i"); +MODULE_PARM(lpfc8_ip_class, "i"); +MODULE_PARM(lpfc8_fcp_class, "i"); +MODULE_PARM(lpfc8_use_adisc, "i"); +MODULE_PARM(lpfc8_fcpfabric_tmo, "i"); +MODULE_PARM(lpfc8_post_ip_buf, "i"); +MODULE_PARM(lpfc8_dqfull_throttle_up_time, "i"); +MODULE_PARM(lpfc8_dqfull_throttle_up_inc, "i"); +MODULE_PARM(lpfc8_ack0support, "i"); +MODULE_PARM(lpfc8_automap, "i"); +MODULE_PARM(lpfc8_cr_delay, "i"); +MODULE_PARM(lpfc8_cr_count, "i"); +#endif + +static int lpfc8_log_verbose = -1; +static int lpfc8_log_only = -1; +static int lpfc8_lun_queue_depth = -1; +static int lpfc8_tgt_queue_depth = -1; +static int lpfc8_no_device_delay = -1; +static int lpfc8_network_on = -1; +static int lpfc8_xmt_que_size = -1; +static int lpfc8_scandown = -1; +static int lpfc8_linkdown_tmo = -1; +static int lpfc8_nodev_tmo = -1; +static int lpfc8_delay_rsp_err = -1; +static int lpfc8_nodev_holdio = -1; +static int lpfc8_check_cond_err = -1; +static int lpfc8_num_iocbs = -1; +static int lpfc8_num_bufs = -1; +static int lpfc8_topology = -1; +static int lpfc8_link_speed = -1; +static int lpfc8_ip_class = -1; +static int lpfc8_fcp_class = -1; +static int lpfc8_use_adisc = -1; +static int lpfc8_fcpfabric_tmo = -1; +static int lpfc8_post_ip_buf = -1; +static int lpfc8_dqfull_throttle_up_time = -1; +static int lpfc8_dqfull_throttle_up_inc = -1; +static int lpfc8_ack0support = -1; +static int lpfc8_automap = -1; +static int lpfc8_cr_delay = -1; +static int lpfc8_cr_count = -1; + +/* HBA 9 */ +#ifdef MODULE_PARM +MODULE_PARM(lpfc9_log_verbose, "i"); +MODULE_PARM(lpfc9_log_only, "i"); +MODULE_PARM(lpfc9_lun_queue_depth, "i"); +MODULE_PARM(lpfc9_tgt_queue_depth, "i"); +MODULE_PARM(lpfc9_no_device_delay, "i"); +MODULE_PARM(lpfc9_network_on, "i"); +MODULE_PARM(lpfc9_xmt_que_size, "i"); +MODULE_PARM(lpfc9_scandown, "i"); +MODULE_PARM(lpfc9_linkdown_tmo, "i"); +MODULE_PARM(lpfc9_nodev_tmo, "i"); +MODULE_PARM(lpfc9_delay_rsp_err, "i"); +MODULE_PARM(lpfc9_nodev_holdio, "i"); +MODULE_PARM(lpfc9_check_cond_err, "i"); +MODULE_PARM(lpfc9_num_iocbs, "i"); +MODULE_PARM(lpfc9_num_bufs, "i"); +MODULE_PARM(lpfc9_topology, "i"); +MODULE_PARM(lpfc9_link_speed, "i"); +MODULE_PARM(lpfc9_ip_class, "i"); +MODULE_PARM(lpfc9_fcp_class, "i"); +MODULE_PARM(lpfc9_use_adisc, "i"); +MODULE_PARM(lpfc9_fcpfabric_tmo, "i"); +MODULE_PARM(lpfc9_post_ip_buf, "i"); +MODULE_PARM(lpfc9_dqfull_throttle_up_time, "i"); +MODULE_PARM(lpfc9_dqfull_throttle_up_inc, "i"); +MODULE_PARM(lpfc9_ack0support, "i"); +MODULE_PARM(lpfc9_automap, "i"); +MODULE_PARM(lpfc9_cr_delay, "i"); +MODULE_PARM(lpfc9_cr_count, "i"); +#endif + +static int lpfc9_log_verbose = -1; +static int lpfc9_log_only = -1; +static int lpfc9_lun_queue_depth = -1; +static int lpfc9_tgt_queue_depth = -1; +static int lpfc9_no_device_delay = -1; +static int lpfc9_network_on = -1; +static int lpfc9_xmt_que_size = -1; +static int lpfc9_scandown = -1; +static int lpfc9_linkdown_tmo = -1; +static int lpfc9_nodev_tmo = -1; +static int lpfc9_delay_rsp_err = -1; +static int lpfc9_nodev_holdio = -1; +static int lpfc9_check_cond_err = -1; +static int lpfc9_num_iocbs = -1; +static int lpfc9_num_bufs = -1; +static int lpfc9_topology = -1; +static int lpfc9_link_speed = -1; +static int lpfc9_ip_class = -1; +static int lpfc9_fcp_class = -1; +static int lpfc9_use_adisc = -1; +static int lpfc9_fcpfabric_tmo = -1; +static int lpfc9_post_ip_buf = -1; +static int lpfc9_dqfull_throttle_up_time = -1; +static int lpfc9_dqfull_throttle_up_inc = -1; +static int lpfc9_ack0support = -1; +static int lpfc9_automap = -1; +static int lpfc9_cr_delay = -1; +static int lpfc9_cr_count = -1; + +/* HBA 10 */ +#ifdef MODULE_PARM +MODULE_PARM(lpfc10_log_verbose, "i"); +MODULE_PARM(lpfc10_log_only, "i"); +MODULE_PARM(lpfc10_lun_queue_depth, "i"); +MODULE_PARM(lpfc10_tgt_queue_depth, "i"); +MODULE_PARM(lpfc10_no_device_delay, "i"); +MODULE_PARM(lpfc10_network_on, "i"); +MODULE_PARM(lpfc10_xmt_que_size, "i"); +MODULE_PARM(lpfc10_scandown, "i"); +MODULE_PARM(lpfc10_linkdown_tmo, "i"); +MODULE_PARM(lpfc10_nodev_tmo, "i"); +MODULE_PARM(lpfc10_delay_rsp_err, "i"); +MODULE_PARM(lpfc10_nodev_holdio, "i"); +MODULE_PARM(lpfc10_check_cond_err, "i"); +MODULE_PARM(lpfc10_num_iocbs, "i"); +MODULE_PARM(lpfc10_num_bufs, "i"); +MODULE_PARM(lpfc10_topology, "i"); +MODULE_PARM(lpfc10_link_speed, "i"); +MODULE_PARM(lpfc10_ip_class, "i"); +MODULE_PARM(lpfc10_fcp_class, "i"); +MODULE_PARM(lpfc10_use_adisc, "i"); +MODULE_PARM(lpfc10_fcpfabric_tmo, "i"); +MODULE_PARM(lpfc10_post_ip_buf, "i"); +MODULE_PARM(lpfc10_dqfull_throttle_up_time, "i"); +MODULE_PARM(lpfc10_dqfull_throttle_up_inc, "i"); +MODULE_PARM(lpfc10_ack0support, "i"); +MODULE_PARM(lpfc10_automap, "i"); +MODULE_PARM(lpfc10_cr_delay, "i"); +MODULE_PARM(lpfc10_cr_count, "i"); +#endif + +static int lpfc10_log_verbose = -1; +static int lpfc10_log_only = -1; +static int lpfc10_lun_queue_depth = -1; +static int lpfc10_tgt_queue_depth = -1; +static int lpfc10_no_device_delay = -1; +static int lpfc10_network_on = -1; +static int lpfc10_xmt_que_size = -1; +static int lpfc10_scandown = -1; +static int lpfc10_linkdown_tmo = -1; +static int lpfc10_nodev_tmo = -1; +static int lpfc10_delay_rsp_err = -1; +static int lpfc10_nodev_holdio = -1; +static int lpfc10_check_cond_err = -1; +static int lpfc10_num_iocbs = -1; +static int lpfc10_num_bufs = -1; +static int lpfc10_topology = -1; +static int lpfc10_link_speed = -1; +static int lpfc10_ip_class = -1; +static int lpfc10_fcp_class = -1; +static int lpfc10_use_adisc = -1; +static int lpfc10_fcpfabric_tmo = -1; +static int lpfc10_post_ip_buf = -1; +static int lpfc10_dqfull_throttle_up_time = -1; +static int lpfc10_dqfull_throttle_up_inc = -1; +static int lpfc10_ack0support = -1; +static int lpfc10_automap = -1; +static int lpfc10_cr_delay = -1; +static int lpfc10_cr_count = -1; + +/* HBA 11 */ +#ifdef MODULE_PARM +MODULE_PARM(lpfc11_log_verbose, "i"); +MODULE_PARM(lpfc11_log_only, "i"); +MODULE_PARM(lpfc11_lun_queue_depth, "i"); +MODULE_PARM(lpfc11_tgt_queue_depth, "i"); +MODULE_PARM(lpfc11_no_device_delay, "i"); +MODULE_PARM(lpfc11_network_on, "i"); +MODULE_PARM(lpfc11_xmt_que_size, "i"); +MODULE_PARM(lpfc11_scandown, "i"); +MODULE_PARM(lpfc11_linkdown_tmo, "i"); +MODULE_PARM(lpfc11_nodev_tmo, "i"); +MODULE_PARM(lpfc11_delay_rsp_err, "i"); +MODULE_PARM(lpfc11_nodev_holdio, "i"); +MODULE_PARM(lpfc11_check_cond_err, "i"); +MODULE_PARM(lpfc11_num_iocbs, "i"); +MODULE_PARM(lpfc11_num_bufs, "i"); +MODULE_PARM(lpfc11_topology, "i"); +MODULE_PARM(lpfc11_link_speed, "i"); +MODULE_PARM(lpfc11_ip_class, "i"); +MODULE_PARM(lpfc11_fcp_class, "i"); +MODULE_PARM(lpfc11_use_adisc, "i"); +MODULE_PARM(lpfc11_fcpfabric_tmo, "i"); +MODULE_PARM(lpfc11_post_ip_buf, "i"); +MODULE_PARM(lpfc11_dqfull_throttle_up_time, "i"); +MODULE_PARM(lpfc11_dqfull_throttle_up_inc, "i"); +MODULE_PARM(lpfc11_ack0support, "i"); +MODULE_PARM(lpfc11_automap, "i"); +MODULE_PARM(lpfc11_cr_delay, "i"); +MODULE_PARM(lpfc11_cr_count, "i"); +#endif + +static int lpfc11_log_verbose = -1; +static int lpfc11_log_only = -1; +static int lpfc11_lun_queue_depth = -1; +static int lpfc11_tgt_queue_depth = -1; +static int lpfc11_no_device_delay = -1; +static int lpfc11_network_on = -1; +static int lpfc11_xmt_que_size = -1; +static int lpfc11_scandown = -1; +static int lpfc11_linkdown_tmo = -1; +static int lpfc11_nodev_tmo = -1; +static int lpfc11_delay_rsp_err = -1; +static int lpfc11_nodev_holdio = -1; +static int lpfc11_check_cond_err = -1; +static int lpfc11_num_iocbs = -1; +static int lpfc11_num_bufs = -1; +static int lpfc11_topology = -1; +static int lpfc11_link_speed = -1; +static int lpfc11_ip_class = -1; +static int lpfc11_fcp_class = -1; +static int lpfc11_use_adisc = -1; +static int lpfc11_fcpfabric_tmo = -1; +static int lpfc11_post_ip_buf = -1; +static int lpfc11_dqfull_throttle_up_time = -1; +static int lpfc11_dqfull_throttle_up_inc = -1; +static int lpfc11_ack0support = -1; +static int lpfc11_automap = -1; +static int lpfc11_cr_delay = -1; +static int lpfc11_cr_count = -1; + +/* HBA 12 */ +#ifdef MODULE_PARM +MODULE_PARM(lpfc12_log_verbose, "i"); +MODULE_PARM(lpfc12_log_only, "i"); +MODULE_PARM(lpfc12_lun_queue_depth, "i"); +MODULE_PARM(lpfc12_tgt_queue_depth, "i"); +MODULE_PARM(lpfc12_no_device_delay, "i"); +MODULE_PARM(lpfc12_network_on, "i"); +MODULE_PARM(lpfc12_xmt_que_size, "i"); +MODULE_PARM(lpfc12_scandown, "i"); +MODULE_PARM(lpfc12_linkdown_tmo, "i"); +MODULE_PARM(lpfc12_nodev_tmo, "i"); +MODULE_PARM(lpfc12_delay_rsp_err, "i"); +MODULE_PARM(lpfc12_nodev_holdio, "i"); +MODULE_PARM(lpfc12_check_cond_err, "i"); +MODULE_PARM(lpfc12_num_iocbs, "i"); +MODULE_PARM(lpfc12_num_bufs, "i"); +MODULE_PARM(lpfc12_topology, "i"); +MODULE_PARM(lpfc12_link_speed, "i"); +MODULE_PARM(lpfc12_ip_class, "i"); +MODULE_PARM(lpfc12_fcp_class, "i"); +MODULE_PARM(lpfc12_use_adisc, "i"); +MODULE_PARM(lpfc12_fcpfabric_tmo, "i"); +MODULE_PARM(lpfc12_post_ip_buf, "i"); +MODULE_PARM(lpfc12_dqfull_throttle_up_time, "i"); +MODULE_PARM(lpfc12_dqfull_throttle_up_inc, "i"); +MODULE_PARM(lpfc12_ack0support, "i"); +MODULE_PARM(lpfc12_automap, "i"); +MODULE_PARM(lpfc12_cr_delay, "i"); +MODULE_PARM(lpfc12_cr_count, "i"); +#endif + +static int lpfc12_log_verbose = -1; +static int lpfc12_log_only = -1; +static int lpfc12_lun_queue_depth = -1; +static int lpfc12_tgt_queue_depth = -1; +static int lpfc12_no_device_delay = -1; +static int lpfc12_network_on = -1; +static int lpfc12_xmt_que_size = -1; +static int lpfc12_scandown = -1; +static int lpfc12_linkdown_tmo = -1; +static int lpfc12_nodev_tmo = -1; +static int lpfc12_delay_rsp_err = -1; +static int lpfc12_nodev_holdio = -1; +static int lpfc12_check_cond_err = -1; +static int lpfc12_num_iocbs = -1; +static int lpfc12_num_bufs = -1; +static int lpfc12_topology = -1; +static int lpfc12_link_speed = -1; +static int lpfc12_ip_class = -1; +static int lpfc12_fcp_class = -1; +static int lpfc12_use_adisc = -1; +static int lpfc12_fcpfabric_tmo = -1; +static int lpfc12_post_ip_buf = -1; +static int lpfc12_dqfull_throttle_up_time = -1; +static int lpfc12_dqfull_throttle_up_inc = -1; +static int lpfc12_ack0support = -1; +static int lpfc12_automap = -1; +static int lpfc12_cr_delay = -1; +static int lpfc12_cr_count = -1; + +/* HBA 13 */ +#ifdef MODULE_PARM +MODULE_PARM(lpfc13_log_verbose, "i"); +MODULE_PARM(lpfc13_log_only, "i"); +MODULE_PARM(lpfc13_lun_queue_depth, "i"); +MODULE_PARM(lpfc13_tgt_queue_depth, "i"); +MODULE_PARM(lpfc13_no_device_delay, "i"); +MODULE_PARM(lpfc13_network_on, "i"); +MODULE_PARM(lpfc13_xmt_que_size, "i"); +MODULE_PARM(lpfc13_scandown, "i"); +MODULE_PARM(lpfc13_linkdown_tmo, "i"); +MODULE_PARM(lpfc13_nodev_tmo, "i"); +MODULE_PARM(lpfc13_delay_rsp_err, "i"); +MODULE_PARM(lpfc13_nodev_holdio, "i"); +MODULE_PARM(lpfc13_check_cond_err, "i"); +MODULE_PARM(lpfc13_num_iocbs, "i"); +MODULE_PARM(lpfc13_num_bufs, "i"); +MODULE_PARM(lpfc13_topology, "i"); +MODULE_PARM(lpfc13_link_speed, "i"); +MODULE_PARM(lpfc13_ip_class, "i"); +MODULE_PARM(lpfc13_fcp_class, "i"); +MODULE_PARM(lpfc13_use_adisc, "i"); +MODULE_PARM(lpfc13_fcpfabric_tmo, "i"); +MODULE_PARM(lpfc13_post_ip_buf, "i"); +MODULE_PARM(lpfc13_dqfull_throttle_up_time, "i"); +MODULE_PARM(lpfc13_dqfull_throttle_up_inc, "i"); +MODULE_PARM(lpfc13_ack0support, "i"); +MODULE_PARM(lpfc13_automap, "i"); +MODULE_PARM(lpfc13_cr_delay, "i"); +MODULE_PARM(lpfc13_cr_count, "i"); +#endif + +static int lpfc13_log_verbose = -1; +static int lpfc13_log_only = -1; +static int lpfc13_lun_queue_depth = -1; +static int lpfc13_tgt_queue_depth = -1; +static int lpfc13_no_device_delay = -1; +static int lpfc13_network_on = -1; +static int lpfc13_xmt_que_size = -1; +static int lpfc13_scandown = -1; +static int lpfc13_linkdown_tmo = -1; +static int lpfc13_nodev_tmo = -1; +static int lpfc13_delay_rsp_err = -1; +static int lpfc13_nodev_holdio = -1; +static int lpfc13_check_cond_err = -1; +static int lpfc13_num_iocbs = -1; +static int lpfc13_num_bufs = -1; +static int lpfc13_topology = -1; +static int lpfc13_link_speed = -1; +static int lpfc13_ip_class = -1; +static int lpfc13_fcp_class = -1; +static int lpfc13_use_adisc = -1; +static int lpfc13_fcpfabric_tmo = -1; +static int lpfc13_post_ip_buf = -1; +static int lpfc13_dqfull_throttle_up_time = -1; +static int lpfc13_dqfull_throttle_up_inc = -1; +static int lpfc13_ack0support = -1; +static int lpfc13_automap = -1; +static int lpfc13_cr_delay = -1; +static int lpfc13_cr_count = -1; + +/* HBA 14 */ +#ifdef MODULE_PARM +MODULE_PARM(lpfc14_log_verbose, "i"); +MODULE_PARM(lpfc14_log_only, "i"); +MODULE_PARM(lpfc14_lun_queue_depth, "i"); +MODULE_PARM(lpfc14_tgt_queue_depth, "i"); +MODULE_PARM(lpfc14_no_device_delay, "i"); +MODULE_PARM(lpfc14_network_on, "i"); +MODULE_PARM(lpfc14_xmt_que_size, "i"); +MODULE_PARM(lpfc14_scandown, "i"); +MODULE_PARM(lpfc14_linkdown_tmo, "i"); +MODULE_PARM(lpfc14_nodev_tmo, "i"); +MODULE_PARM(lpfc14_delay_rsp_err, "i"); +MODULE_PARM(lpfc14_nodev_holdio, "i"); +MODULE_PARM(lpfc14_check_cond_err, "i"); +MODULE_PARM(lpfc14_num_iocbs, "i"); +MODULE_PARM(lpfc14_num_bufs, "i"); +MODULE_PARM(lpfc14_topology, "i"); +MODULE_PARM(lpfc14_link_speed, "i"); +MODULE_PARM(lpfc14_ip_class, "i"); +MODULE_PARM(lpfc14_fcp_class, "i"); +MODULE_PARM(lpfc14_use_adisc, "i"); +MODULE_PARM(lpfc14_fcpfabric_tmo, "i"); +MODULE_PARM(lpfc14_post_ip_buf, "i"); +MODULE_PARM(lpfc14_dqfull_throttle_up_time, "i"); +MODULE_PARM(lpfc14_dqfull_throttle_up_inc, "i"); +MODULE_PARM(lpfc14_ack0support, "i"); +MODULE_PARM(lpfc14_automap, "i"); +MODULE_PARM(lpfc14_cr_delay, "i"); +MODULE_PARM(lpfc14_cr_count, "i"); +#endif + +static int lpfc14_log_verbose = -1; +static int lpfc14_log_only = -1; +static int lpfc14_lun_queue_depth = -1; +static int lpfc14_tgt_queue_depth = -1; +static int lpfc14_no_device_delay = -1; +static int lpfc14_network_on = -1; +static int lpfc14_xmt_que_size = -1; +static int lpfc14_scandown = -1; +static int lpfc14_linkdown_tmo = -1; +static int lpfc14_nodev_tmo = -1; +static int lpfc14_delay_rsp_err = -1; +static int lpfc14_nodev_holdio = -1; +static int lpfc14_check_cond_err = -1; +static int lpfc14_num_iocbs = -1; +static int lpfc14_num_bufs = -1; +static int lpfc14_topology = -1; +static int lpfc14_link_speed = -1; +static int lpfc14_ip_class = -1; +static int lpfc14_fcp_class = -1; +static int lpfc14_use_adisc = -1; +static int lpfc14_fcpfabric_tmo = -1; +static int lpfc14_post_ip_buf = -1; +static int lpfc14_dqfull_throttle_up_time = -1; +static int lpfc14_dqfull_throttle_up_inc = -1; +static int lpfc14_ack0support = -1; +static int lpfc14_automap = -1; +static int lpfc14_cr_delay = -1; +static int lpfc14_cr_count = -1; + +/* HBA 15 */ +#ifdef MODULE_PARM +MODULE_PARM(lpfc15_log_verbose, "i"); +MODULE_PARM(lpfc15_log_only, "i"); +MODULE_PARM(lpfc15_lun_queue_depth, "i"); +MODULE_PARM(lpfc15_tgt_queue_depth, "i"); +MODULE_PARM(lpfc15_no_device_delay, "i"); +MODULE_PARM(lpfc15_network_on, "i"); +MODULE_PARM(lpfc15_xmt_que_size, "i"); +MODULE_PARM(lpfc15_scandown, "i"); +MODULE_PARM(lpfc15_linkdown_tmo, "i"); +MODULE_PARM(lpfc15_nodev_tmo, "i"); +MODULE_PARM(lpfc15_delay_rsp_err, "i"); +MODULE_PARM(lpfc15_nodev_holdio, "i"); +MODULE_PARM(lpfc15_check_cond_err, "i"); +MODULE_PARM(lpfc15_num_iocbs, "i"); +MODULE_PARM(lpfc15_num_bufs, "i"); +MODULE_PARM(lpfc15_topology, "i"); +MODULE_PARM(lpfc15_link_speed, "i"); +MODULE_PARM(lpfc15_ip_class, "i"); +MODULE_PARM(lpfc15_fcp_class, "i"); +MODULE_PARM(lpfc15_use_adisc, "i"); +MODULE_PARM(lpfc15_fcpfabric_tmo, "i"); +MODULE_PARM(lpfc15_post_ip_buf, "i"); +MODULE_PARM(lpfc15_dqfull_throttle_up_time, "i"); +MODULE_PARM(lpfc15_dqfull_throttle_up_inc, "i"); +MODULE_PARM(lpfc15_ack0support, "i"); +MODULE_PARM(lpfc15_automap, "i"); +MODULE_PARM(lpfc15_cr_delay, "i"); +MODULE_PARM(lpfc15_cr_count, "i"); +#endif + +static int lpfc15_log_verbose = -1; +static int lpfc15_log_only = -1; +static int lpfc15_lun_queue_depth = -1; +static int lpfc15_tgt_queue_depth = -1; +static int lpfc15_no_device_delay = -1; +static int lpfc15_network_on = -1; +static int lpfc15_xmt_que_size = -1; +static int lpfc15_scandown = -1; +static int lpfc15_linkdown_tmo = -1; +static int lpfc15_nodev_tmo = -1; +static int lpfc15_delay_rsp_err = -1; +static int lpfc15_nodev_holdio = -1; +static int lpfc15_check_cond_err = -1; +static int lpfc15_num_iocbs = -1; +static int lpfc15_num_bufs = -1; +static int lpfc15_topology = -1; +static int lpfc15_link_speed = -1; +static int lpfc15_ip_class = -1; +static int lpfc15_fcp_class = -1; +static int lpfc15_use_adisc = -1; +static int lpfc15_fcpfabric_tmo = -1; +static int lpfc15_post_ip_buf = -1; +static int lpfc15_dqfull_throttle_up_time = -1; +static int lpfc15_dqfull_throttle_up_inc = -1; +static int lpfc15_ack0support = -1; +static int lpfc15_automap = -1; +static int lpfc15_cr_delay = -1; +static int lpfc15_cr_count = -1; + +#ifdef MODULE_PARM +MODULE_PARM(lpfc_log_verbose, "i"); +MODULE_PARM(lpfc_log_only, "i"); +MODULE_PARM(lpfc_lun_queue_depth, "i"); +MODULE_PARM(lpfc_tgt_queue_depth, "i"); +MODULE_PARM(lpfc_no_device_delay, "i"); +MODULE_PARM(lpfc_network_on, "i"); +MODULE_PARM(lpfc_xmt_que_size, "i"); +MODULE_PARM(lpfc_scandown, "i"); +MODULE_PARM(lpfc_linkdown_tmo, "i"); +MODULE_PARM(lpfc_nodev_tmo, "i"); +MODULE_PARM(lpfc_delay_rsp_err, "i"); +MODULE_PARM(lpfc_nodev_holdio, "i"); +MODULE_PARM(lpfc_check_cond_err, "i"); +MODULE_PARM(lpfc_num_iocbs, "i"); +MODULE_PARM(lpfc_num_bufs, "i"); +MODULE_PARM(lpfc_topology, "i"); +MODULE_PARM(lpfc_link_speed, "i"); +MODULE_PARM(lpfc_ip_class, "i"); +MODULE_PARM(lpfc_fcp_class, "i"); +MODULE_PARM(lpfc_use_adisc, "i"); +MODULE_PARM(lpfc_fcpfabric_tmo, "i"); +MODULE_PARM(lpfc_post_ip_buf, "i"); +MODULE_PARM(lpfc_dqfull_throttle_up_time, "i"); +MODULE_PARM(lpfc_dqfull_throttle_up_inc, "i"); +MODULE_PARM(lpfc_ack0support, "i"); +MODULE_PARM(lpfc_automap, "i"); +MODULE_PARM(lpfc_cr_delay, "i"); +MODULE_PARM(lpfc_cr_count, "i"); +#endif + +extern int lpfc_log_verbose; +extern int lpfc_log_only; +extern int lpfc_lun_queue_depth; +extern int lpfc_tgt_queue_depth; +extern int lpfc_no_device_delay; +extern int lpfc_network_on; +extern int lpfc_xmt_que_size; +extern int lpfc_scandown; +extern int lpfc_linkdown_tmo; +extern int lpfc_nodev_tmo; +extern int lpfc_delay_rsp_err; +extern int lpfc_nodev_holdio; +extern int lpfc_check_cond_err; +extern int lpfc_num_iocbs; +extern int lpfc_num_bufs; +extern int lpfc_topology; +extern int lpfc_link_speed; +extern int lpfc_ip_class; +extern int lpfc_fcp_class; +extern int lpfc_use_adisc; +extern int lpfc_fcpfabric_tmo; +extern int lpfc_post_ip_buf; +extern int lpfc_dqfull_throttle_up_time; +extern int lpfc_dqfull_throttle_up_inc; +extern int lpfc_ack0support; +extern int lpfc_automap; +extern int lpfc_cr_delay; +extern int lpfc_cr_count; + + +void * +fc_get_cfg_param( +int brd, +int param) +{ + void *value; + + value = (void *)((ulong)(-1)); + switch(brd) { + case 0: /* HBA 0 */ + switch(param) { + case CFG_LOG_VERBOSE: /* log-verbose */ + value = (void *)((ulong)lpfc_log_verbose); + if(lpfc0_log_verbose != -1) + value = (void *)((ulong)lpfc0_log_verbose); + break; + case CFG_LOG_ONLY: /* log-only */ + value = (void *)((ulong)lpfc_log_only); + if(lpfc0_log_only != -1) + value = (void *)((ulong)lpfc0_log_only); + break; + case CFG_NUM_IOCBS: /* num-iocbs */ + value = (void *)((ulong)lpfc_num_iocbs); + if(lpfc0_num_iocbs != -1) + value = (void *)((ulong)lpfc0_num_iocbs); + break; + case CFG_NUM_BUFS: /* num-bufs */ + value = (void *)((ulong)lpfc_num_bufs); + if(lpfc0_num_bufs != -1) + value = (void *)((ulong)lpfc0_num_bufs); + break; + case CFG_AUTOMAP: /* automap */ + value = (void *)((ulong)lpfc_automap); + if(lpfc0_automap != -1) + value = (void *)((ulong)lpfc0_automap); + break; + case CFG_CR_DELAY: /* cr_delay */ + value = (void *)((ulong)lpfc_cr_delay); + if(lpfc0_cr_delay != -1) + value = (void *)((ulong)lpfc0_cr_delay); + break; + case CFG_CR_COUNT: /* cr_count */ + value = (void *)((ulong)lpfc_cr_count); + if(lpfc0_cr_count != -1) + value = (void *)((ulong)lpfc0_cr_count); + break; + case CFG_DFT_TGT_Q_DEPTH: /* tgt_queue_depth */ + value = (void *)((ulong)lpfc_tgt_queue_depth); + if(lpfc0_tgt_queue_depth != -1) + value = (void *)((ulong)lpfc0_tgt_queue_depth); + break; + case CFG_DFT_LUN_Q_DEPTH: /* lun_queue_depth */ + value = (void *)((ulong)lpfc_lun_queue_depth); + if(lpfc0_lun_queue_depth != -1) + value = (void *)((ulong)lpfc0_lun_queue_depth); + break; + case CFG_FCPFABRIC_TMO: /* fcpfabric-tmo */ + value = (void *)((ulong)lpfc_fcpfabric_tmo); + if(lpfc0_fcpfabric_tmo != -1) + value = (void *)((ulong)lpfc0_fcpfabric_tmo); + break; + case CFG_FCP_CLASS: /* fcp-class */ + value = (void *)((ulong)lpfc_fcp_class); + if(lpfc0_fcp_class != -1) + value = (void *)((ulong)lpfc0_fcp_class); + break; + case CFG_USE_ADISC: /* use-adisc */ + value = (void *)((ulong)lpfc_use_adisc); + if(lpfc0_use_adisc != -1) + value = (void *)((ulong)lpfc0_use_adisc); + break; + case CFG_NO_DEVICE_DELAY: /* no-device-delay */ + value = (void *)((ulong)lpfc_no_device_delay); + if(lpfc0_no_device_delay != -1) + value = (void *)((ulong)lpfc0_no_device_delay); + break; + case CFG_NETWORK_ON: /* network-on */ + value = (void *)((ulong)lpfc_network_on); + if(lpfc0_network_on != -1) + value = (void *)((ulong)lpfc0_network_on); + break; + case CFG_POST_IP_BUF: /* post-ip-buf */ + value = (void *)((ulong)lpfc_post_ip_buf); + if(lpfc0_post_ip_buf != -1) + value = (void *)((ulong)lpfc0_post_ip_buf); + break; + case CFG_XMT_Q_SIZE: /* xmt-que-size */ + value = (void *)((ulong)lpfc_xmt_que_size); + if(lpfc0_xmt_que_size != -1) + value = (void *)((ulong)lpfc0_xmt_que_size); + break; + case CFG_IP_CLASS: /* ip-class */ + value = (void *)((ulong)lpfc_ip_class); + if(lpfc0_ip_class != -1) + value = (void *)((ulong)lpfc0_ip_class); + break; + case CFG_ACK0: /* ack0 */ + value = (void *)((ulong)lpfc_ack0support); + if(lpfc0_ack0support != -1) + value = (void *)((ulong)lpfc0_ack0support); + break; + case CFG_TOPOLOGY: /* topology */ + value = (void *)((ulong)lpfc_topology); + if(lpfc0_topology != -1) + value = (void *)((ulong)lpfc0_topology); + break; + case CFG_SCAN_DOWN: /* scan-down */ + value = (void *)((ulong)lpfc_scandown); + if(lpfc0_scandown != -1) + value = (void *)((ulong)lpfc0_scandown); + break; + case CFG_LINKDOWN_TMO: /* linkdown-tmo */ + value = (void *)((ulong)lpfc_linkdown_tmo); + if(lpfc0_linkdown_tmo != -1) + value = (void *)((ulong)lpfc0_linkdown_tmo); + break; + case CFG_HOLDIO: /* nodev-holdio */ + value = (void *)((ulong)lpfc_nodev_holdio); + if(lpfc0_nodev_holdio != -1) + value = (void *)((ulong)lpfc0_nodev_holdio); + break; + case CFG_DELAY_RSP_ERR: /* delay-rsp-err */ + value = (void *)((ulong)lpfc_delay_rsp_err); + if(lpfc0_delay_rsp_err != -1) + value = (void *)((ulong)lpfc0_delay_rsp_err); + break; + case CFG_CHK_COND_ERR: /* check-cond-err */ + value = (void *)((ulong)lpfc_check_cond_err); + if(lpfc0_check_cond_err != -1) + value = (void *)((ulong)lpfc0_check_cond_err); + break; + case CFG_NODEV_TMO: /* nodev-tmo */ + value = (void *)((ulong)lpfc_nodev_tmo); + if(lpfc0_nodev_tmo != -1) + value = (void *)((ulong)lpfc0_nodev_tmo); + break; + case CFG_LINK_SPEED: /* link-speed */ + value = (void *)((ulong)lpfc_link_speed); + if(lpfc0_link_speed != -1) + value = (void *)((ulong)lpfc0_link_speed); + break; + case CFG_DQFULL_THROTTLE_UP_TIME: /* dqfull-throttle-up-time */ + value = (void *)((ulong)lpfc_dqfull_throttle_up_time); + if(lpfc0_dqfull_throttle_up_time != -1) + value = (void *)((ulong)lpfc0_dqfull_throttle_up_time); + break; + case CFG_DQFULL_THROTTLE_UP_INC: /* dqfull-throttle-up-inc */ + value = (void *)((ulong)lpfc_dqfull_throttle_up_inc); + if(lpfc0_dqfull_throttle_up_inc != -1) + value = (void *)((ulong)lpfc0_dqfull_throttle_up_inc); + break; + default: + break; + } + break; + case 1: /* HBA 1 */ + switch(param) { + case CFG_LOG_VERBOSE: /* log-verbose */ + value = (void *)((ulong)lpfc_log_verbose); + if(lpfc1_log_verbose != -1) + value = (void *)((ulong)lpfc1_log_verbose); + break; + case CFG_LOG_ONLY: /* log-only */ + value = (void *)((ulong)lpfc_log_only); + if(lpfc1_log_only != -1) + value = (void *)((ulong)lpfc1_log_only); + break; + case CFG_NUM_IOCBS: /* num-iocbs */ + value = (void *)((ulong)lpfc_num_iocbs); + if(lpfc1_num_iocbs != -1) + value = (void *)((ulong)lpfc1_num_iocbs); + break; + case CFG_NUM_BUFS: /* num-bufs */ + value = (void *)((ulong)lpfc_num_bufs); + if(lpfc1_num_bufs != -1) + value = (void *)((ulong)lpfc1_num_bufs); + break; + case CFG_AUTOMAP: /* automap */ + value = (void *)((ulong)lpfc_automap); + if(lpfc1_automap != -1) + value = (void *)((ulong)lpfc1_automap); + break; + case CFG_CR_DELAY: /* cr_delay */ + value = (void *)((ulong)lpfc_cr_delay); + if(lpfc1_cr_delay != -1) + value = (void *)((ulong)lpfc1_cr_delay); + break; + case CFG_CR_COUNT: /* cr_count */ + value = (void *)((ulong)lpfc_cr_count); + if(lpfc1_cr_count != -1) + value = (void *)((ulong)lpfc1_cr_count); + break; + case CFG_DFT_TGT_Q_DEPTH: /* tgt_queue_depth */ + value = (void *)((ulong)lpfc_tgt_queue_depth); + if(lpfc1_tgt_queue_depth != -1) + value = (void *)((ulong)lpfc1_tgt_queue_depth); + break; + case CFG_DFT_LUN_Q_DEPTH: /* lun_queue_depth */ + value = (void *)((ulong)lpfc_lun_queue_depth); + if(lpfc1_lun_queue_depth != -1) + value = (void *)((ulong)lpfc1_lun_queue_depth); + break; + case CFG_FCPFABRIC_TMO: /* fcpfabric-tmo */ + value = (void *)((ulong)lpfc_fcpfabric_tmo); + if(lpfc1_fcpfabric_tmo != -1) + value = (void *)((ulong)lpfc1_fcpfabric_tmo); + break; + case CFG_FCP_CLASS: /* fcp-class */ + value = (void *)((ulong)lpfc_fcp_class); + if(lpfc1_fcp_class != -1) + value = (void *)((ulong)lpfc1_fcp_class); + break; + case CFG_USE_ADISC: /* use-adisc */ + value = (void *)((ulong)lpfc_use_adisc); + if(lpfc1_use_adisc != -1) + value = (void *)((ulong)lpfc1_use_adisc); + break; + case CFG_NO_DEVICE_DELAY: /* no-device-delay */ + value = (void *)((ulong)lpfc_no_device_delay); + if(lpfc1_no_device_delay != -1) + value = (void *)((ulong)lpfc1_no_device_delay); + break; + case CFG_NETWORK_ON: /* network-on */ + value = (void *)((ulong)lpfc_network_on); + if(lpfc1_network_on != -1) + value = (void *)((ulong)lpfc1_network_on); + break; + case CFG_POST_IP_BUF: /* post-ip-buf */ + value = (void *)((ulong)lpfc_post_ip_buf); + if(lpfc1_post_ip_buf != -1) + value = (void *)((ulong)lpfc1_post_ip_buf); + break; + case CFG_XMT_Q_SIZE: /* xmt-que-size */ + value = (void *)((ulong)lpfc_xmt_que_size); + if(lpfc1_xmt_que_size != -1) + value = (void *)((ulong)lpfc1_xmt_que_size); + break; + case CFG_IP_CLASS: /* ip-class */ + value = (void *)((ulong)lpfc_ip_class); + if(lpfc1_ip_class != -1) + value = (void *)((ulong)lpfc1_ip_class); + break; + case CFG_ACK0: /* ack0 */ + value = (void *)((ulong)lpfc_ack0support); + if(lpfc1_ack0support != -1) + value = (void *)((ulong)lpfc1_ack0support); + break; + case CFG_TOPOLOGY: /* topology */ + value = (void *)((ulong)lpfc_topology); + if(lpfc1_topology != -1) + value = (void *)((ulong)lpfc1_topology); + break; + case CFG_SCAN_DOWN: /* scan-down */ + value = (void *)((ulong)lpfc_scandown); + if(lpfc1_scandown != -1) + value = (void *)((ulong)lpfc1_scandown); + break; + case CFG_LINKDOWN_TMO: /* linkdown-tmo */ + value = (void *)((ulong)lpfc_linkdown_tmo); + if(lpfc1_linkdown_tmo != -1) + value = (void *)((ulong)lpfc1_linkdown_tmo); + break; + case CFG_HOLDIO: /* nodev-holdio */ + value = (void *)((ulong)lpfc_nodev_holdio); + if(lpfc1_nodev_holdio != -1) + value = (void *)((ulong)lpfc1_nodev_holdio); + break; + case CFG_DELAY_RSP_ERR: /* delay-rsp-err */ + value = (void *)((ulong)lpfc_delay_rsp_err); + if(lpfc1_delay_rsp_err != -1) + value = (void *)((ulong)lpfc1_delay_rsp_err); + break; + case CFG_CHK_COND_ERR: /* check-cond-err */ + value = (void *)((ulong)lpfc_check_cond_err); + if(lpfc1_check_cond_err != -1) + value = (void *)((ulong)lpfc1_check_cond_err); + break; + case CFG_NODEV_TMO: /* nodev-tmo */ + value = (void *)((ulong)lpfc_nodev_tmo); + if(lpfc1_nodev_tmo != -1) + value = (void *)((ulong)lpfc1_nodev_tmo); + break; + case CFG_LINK_SPEED: /* link-speed */ + value = (void *)((ulong)lpfc_link_speed); + if(lpfc1_link_speed != -1) + value = (void *)((ulong)lpfc1_link_speed); + break; + case CFG_DQFULL_THROTTLE_UP_TIME: /* dqfull-throttle-up-time */ + value = (void *)((ulong)lpfc_dqfull_throttle_up_time); + if(lpfc1_dqfull_throttle_up_time != -1) + value = (void *)((ulong)lpfc1_dqfull_throttle_up_time); + break; + case CFG_DQFULL_THROTTLE_UP_INC: /* dqfull-throttle-up-inc */ + value = (void *)((ulong)lpfc_dqfull_throttle_up_inc); + if(lpfc1_dqfull_throttle_up_inc != -1) + value = (void *)((ulong)lpfc1_dqfull_throttle_up_inc); + break; + } + break; + case 2: /* HBA 2 */ + switch(param) { + case CFG_LOG_VERBOSE: /* log-verbose */ + value = (void *)((ulong)lpfc_log_verbose); + if(lpfc2_log_verbose != -1) + value = (void *)((ulong)lpfc2_log_verbose); + break; + case CFG_LOG_ONLY: /* log-only */ + value = (void *)((ulong)lpfc_log_only); + if(lpfc2_log_only != -1) + value = (void *)((ulong)lpfc2_log_only); + break; + case CFG_NUM_IOCBS: /* num-iocbs */ + value = (void *)((ulong)lpfc_num_iocbs); + if(lpfc2_num_iocbs != -1) + value = (void *)((ulong)lpfc2_num_iocbs); + break; + case CFG_NUM_BUFS: /* num-bufs */ + value = (void *)((ulong)lpfc_num_bufs); + if(lpfc2_num_bufs != -1) + value = (void *)((ulong)lpfc2_num_bufs); + break; + case CFG_AUTOMAP: /* automap */ + value = (void *)((ulong)lpfc_automap); + if(lpfc2_automap != -1) + value = (void *)((ulong)lpfc2_automap); + break; + case CFG_CR_DELAY: /* cr_delay */ + value = (void *)((ulong)lpfc_cr_delay); + if(lpfc2_cr_delay != -1) + value = (void *)((ulong)lpfc2_cr_delay); + break; + case CFG_CR_COUNT: /* cr_count */ + value = (void *)((ulong)lpfc_cr_count); + if(lpfc2_cr_count != -1) + value = (void *)((ulong)lpfc2_cr_count); + break; + case CFG_DFT_TGT_Q_DEPTH: /* tgt_queue_depth */ + value = (void *)((ulong)lpfc_tgt_queue_depth); + if(lpfc2_tgt_queue_depth != -1) + value = (void *)((ulong)lpfc2_tgt_queue_depth); + break; + case CFG_DFT_LUN_Q_DEPTH: /* lun_queue_depth */ + value = (void *)((ulong)lpfc_lun_queue_depth); + if(lpfc2_lun_queue_depth != -1) + value = (void *)((ulong)lpfc2_lun_queue_depth); + break; + case CFG_FCPFABRIC_TMO: /* fcpfabric-tmo */ + value = (void *)((ulong)lpfc_fcpfabric_tmo); + if(lpfc2_fcpfabric_tmo != -1) + value = (void *)((ulong)lpfc2_fcpfabric_tmo); + break; + case CFG_FCP_CLASS: /* fcp-class */ + value = (void *)((ulong)lpfc_fcp_class); + if(lpfc2_fcp_class != -1) + value = (void *)((ulong)lpfc2_fcp_class); + break; + case CFG_USE_ADISC: /* use-adisc */ + value = (void *)((ulong)lpfc_use_adisc); + if(lpfc2_use_adisc != -1) + value = (void *)((ulong)lpfc2_use_adisc); + break; + case CFG_NO_DEVICE_DELAY: /* no-device-delay */ + value = (void *)((ulong)lpfc_no_device_delay); + if(lpfc2_no_device_delay != -1) + value = (void *)((ulong)lpfc2_no_device_delay); + break; + case CFG_NETWORK_ON: /* network-on */ + value = (void *)((ulong)lpfc_network_on); + if(lpfc2_network_on != -1) + value = (void *)((ulong)lpfc2_network_on); + break; + case CFG_POST_IP_BUF: /* post-ip-buf */ + value = (void *)((ulong)lpfc_post_ip_buf); + if(lpfc2_post_ip_buf != -1) + value = (void *)((ulong)lpfc2_post_ip_buf); + break; + case CFG_XMT_Q_SIZE: /* xmt-que-size */ + value = (void *)((ulong)lpfc_xmt_que_size); + if(lpfc2_xmt_que_size != -1) + value = (void *)((ulong)lpfc2_xmt_que_size); + break; + case CFG_IP_CLASS: /* ip-class */ + value = (void *)((ulong)lpfc_ip_class); + if(lpfc2_ip_class != -1) + value = (void *)((ulong)lpfc2_ip_class); + break; + case CFG_ACK0: /* ack0 */ + value = (void *)((ulong)lpfc_ack0support); + if(lpfc2_ack0support != -1) + value = (void *)((ulong)lpfc2_ack0support); + break; + case CFG_TOPOLOGY: /* topology */ + value = (void *)((ulong)lpfc_topology); + if(lpfc2_topology != -1) + value = (void *)((ulong)lpfc2_topology); + break; + case CFG_SCAN_DOWN: /* scan-down */ + value = (void *)((ulong)lpfc_scandown); + if(lpfc2_scandown != -1) + value = (void *)((ulong)lpfc2_scandown); + break; + case CFG_LINKDOWN_TMO: /* linkdown-tmo */ + value = (void *)((ulong)lpfc_linkdown_tmo); + if(lpfc2_linkdown_tmo != -1) + value = (void *)((ulong)lpfc2_linkdown_tmo); + break; + case CFG_HOLDIO: /* nodev-holdio */ + value = (void *)((ulong)lpfc_nodev_holdio); + if(lpfc2_nodev_holdio != -1) + value = (void *)((ulong)lpfc2_nodev_holdio); + break; + case CFG_DELAY_RSP_ERR: /* delay-rsp-err */ + value = (void *)((ulong)lpfc_delay_rsp_err); + if(lpfc2_delay_rsp_err != -1) + value = (void *)((ulong)lpfc2_delay_rsp_err); + break; + case CFG_CHK_COND_ERR: /* check-cond-err */ + value = (void *)((ulong)lpfc_check_cond_err); + if(lpfc2_check_cond_err != -1) + value = (void *)((ulong)lpfc2_check_cond_err); + break; + case CFG_NODEV_TMO: /* nodev-tmo */ + value = (void *)((ulong)lpfc_nodev_tmo); + if(lpfc2_nodev_tmo != -1) + value = (void *)((ulong)lpfc2_nodev_tmo); + break; + case CFG_LINK_SPEED: /* link-speed */ + value = (void *)((ulong)lpfc_link_speed); + if(lpfc2_link_speed != -1) + value = (void *)((ulong)lpfc2_link_speed); + break; + case CFG_DQFULL_THROTTLE_UP_TIME: /* dqfull-throttle-up-time */ + value = (void *)((ulong)lpfc_dqfull_throttle_up_time); + if(lpfc2_dqfull_throttle_up_time != -1) + value = (void *)((ulong)lpfc2_dqfull_throttle_up_time); + break; + case CFG_DQFULL_THROTTLE_UP_INC: /* dqfull-throttle-up-inc */ + value = (void *)((ulong)lpfc_dqfull_throttle_up_inc); + if(lpfc2_dqfull_throttle_up_inc != -1) + value = (void *)((ulong)lpfc2_dqfull_throttle_up_inc); + break; + } + break; + case 3: /* HBA 3 */ + switch(param) { + case CFG_LOG_VERBOSE: /* log-verbose */ + value = (void *)((ulong)lpfc_log_verbose); + if(lpfc3_log_verbose != -1) + value = (void *)((ulong)lpfc3_log_verbose); + break; + case CFG_LOG_ONLY: /* log-only */ + value = (void *)((ulong)lpfc_log_only); + if(lpfc3_log_only != -1) + value = (void *)((ulong)lpfc3_log_only); + break; + case CFG_NUM_IOCBS: /* num-iocbs */ + value = (void *)((ulong)lpfc_num_iocbs); + if(lpfc3_num_iocbs != -1) + value = (void *)((ulong)lpfc3_num_iocbs); + break; + case CFG_NUM_BUFS: /* num-bufs */ + value = (void *)((ulong)lpfc_num_bufs); + if(lpfc3_num_bufs != -1) + value = (void *)((ulong)lpfc3_num_bufs); + break; + case CFG_AUTOMAP: /* automap */ + value = (void *)((ulong)lpfc_automap); + if(lpfc3_automap != -1) + value = (void *)((ulong)lpfc3_automap); + break; + case CFG_CR_DELAY: /* cr_delay */ + value = (void *)((ulong)lpfc_cr_delay); + if(lpfc3_cr_delay != -1) + value = (void *)((ulong)lpfc3_cr_delay); + break; + case CFG_CR_COUNT: /* cr_count */ + value = (void *)((ulong)lpfc_cr_count); + if(lpfc3_cr_count != -1) + value = (void *)((ulong)lpfc3_cr_count); + break; + case CFG_DFT_TGT_Q_DEPTH: /* tgt_queue_depth */ + value = (void *)((ulong)lpfc_tgt_queue_depth); + if(lpfc3_tgt_queue_depth != -1) + value = (void *)((ulong)lpfc3_tgt_queue_depth); + break; + case CFG_DFT_LUN_Q_DEPTH: /* lun_queue_depth */ + value = (void *)((ulong)lpfc_lun_queue_depth); + if(lpfc3_lun_queue_depth != -1) + value = (void *)((ulong)lpfc3_lun_queue_depth); + break; + case CFG_FCPFABRIC_TMO: /* fcpfabric-tmo */ + value = (void *)((ulong)lpfc_fcpfabric_tmo); + if(lpfc3_fcpfabric_tmo != -1) + value = (void *)((ulong)lpfc3_fcpfabric_tmo); + break; + case CFG_FCP_CLASS: /* fcp-class */ + value = (void *)((ulong)lpfc_fcp_class); + if(lpfc3_fcp_class != -1) + value = (void *)((ulong)lpfc3_fcp_class); + break; + case CFG_USE_ADISC: /* use-adisc */ + value = (void *)((ulong)lpfc_use_adisc); + if(lpfc3_use_adisc != -1) + value = (void *)((ulong)lpfc3_use_adisc); + break; + case CFG_NO_DEVICE_DELAY: /* no-device-delay */ + value = (void *)((ulong)lpfc_no_device_delay); + if(lpfc3_no_device_delay != -1) + value = (void *)((ulong)lpfc3_no_device_delay); + break; + case CFG_NETWORK_ON: /* network-on */ + value = (void *)((ulong)lpfc_network_on); + if(lpfc3_network_on != -1) + value = (void *)((ulong)lpfc3_network_on); + break; + case CFG_POST_IP_BUF: /* post-ip-buf */ + value = (void *)((ulong)lpfc_post_ip_buf); + if(lpfc3_post_ip_buf != -1) + value = (void *)((ulong)lpfc3_post_ip_buf); + break; + case CFG_XMT_Q_SIZE: /* xmt-que-size */ + value = (void *)((ulong)lpfc_xmt_que_size); + if(lpfc3_xmt_que_size != -1) + value = (void *)((ulong)lpfc3_xmt_que_size); + break; + case CFG_IP_CLASS: /* ip-class */ + value = (void *)((ulong)lpfc_ip_class); + if(lpfc3_ip_class != -1) + value = (void *)((ulong)lpfc3_ip_class); + break; + case CFG_ACK0: /* ack0 */ + value = (void *)((ulong)lpfc_ack0support); + if(lpfc3_ack0support != -1) + value = (void *)((ulong)lpfc3_ack0support); + break; + case CFG_TOPOLOGY: /* topology */ + value = (void *)((ulong)lpfc_topology); + if(lpfc3_topology != -1) + value = (void *)((ulong)lpfc3_topology); + break; + case CFG_SCAN_DOWN: /* scan-down */ + value = (void *)((ulong)lpfc_scandown); + if(lpfc3_scandown != -1) + value = (void *)((ulong)lpfc3_scandown); + break; + case CFG_LINKDOWN_TMO: /* linkdown-tmo */ + value = (void *)((ulong)lpfc_linkdown_tmo); + if(lpfc3_linkdown_tmo != -1) + value = (void *)((ulong)lpfc3_linkdown_tmo); + break; + case CFG_HOLDIO: /* nodev-holdio */ + value = (void *)((ulong)lpfc_nodev_holdio); + if(lpfc3_nodev_holdio != -1) + value = (void *)((ulong)lpfc3_nodev_holdio); + break; + case CFG_DELAY_RSP_ERR: /* delay-rsp-err */ + value = (void *)((ulong)lpfc_delay_rsp_err); + if(lpfc3_delay_rsp_err != -1) + value = (void *)((ulong)lpfc3_delay_rsp_err); + break; + case CFG_CHK_COND_ERR: /* check-cond-err */ + value = (void *)((ulong)lpfc_check_cond_err); + if(lpfc3_check_cond_err != -1) + value = (void *)((ulong)lpfc3_check_cond_err); + break; + case CFG_NODEV_TMO: /* nodev-tmo */ + value = (void *)((ulong)lpfc_nodev_tmo); + if(lpfc3_nodev_tmo != -1) + value = (void *)((ulong)lpfc3_nodev_tmo); + break; + case CFG_LINK_SPEED: /* link-speed */ + value = (void *)((ulong)lpfc_link_speed); + if(lpfc3_link_speed != -1) + value = (void *)((ulong)lpfc3_link_speed); + break; + case CFG_DQFULL_THROTTLE_UP_TIME: /* dqfull-throttle-up-time */ + value = (void *)((ulong)lpfc_dqfull_throttle_up_time); + if(lpfc3_dqfull_throttle_up_time != -1) + value = (void *)((ulong)lpfc3_dqfull_throttle_up_time); + break; + case CFG_DQFULL_THROTTLE_UP_INC: /* dqfull-throttle-up-inc */ + value = (void *)((ulong)lpfc_dqfull_throttle_up_inc); + if(lpfc3_dqfull_throttle_up_inc != -1) + value = (void *)((ulong)lpfc3_dqfull_throttle_up_inc); + break; + } + break; + case 4: /* HBA 4 */ + switch(param) { + case CFG_LOG_VERBOSE: /* log-verbose */ + value = (void *)((ulong)lpfc_log_verbose); + if(lpfc4_log_verbose != -1) + value = (void *)((ulong)lpfc4_log_verbose); + break; + case CFG_LOG_ONLY: /* log-only */ + value = (void *)((ulong)lpfc_log_only); + if(lpfc4_log_only != -1) + value = (void *)((ulong)lpfc4_log_only); + break; + case CFG_NUM_IOCBS: /* num-iocbs */ + value = (void *)((ulong)lpfc_num_iocbs); + if(lpfc4_num_iocbs != -1) + value = (void *)((ulong)lpfc4_num_iocbs); + break; + case CFG_NUM_BUFS: /* num-bufs */ + value = (void *)((ulong)lpfc_num_bufs); + if(lpfc4_num_bufs != -1) + value = (void *)((ulong)lpfc4_num_bufs); + break; + case CFG_AUTOMAP: /* automap */ + value = (void *)((ulong)lpfc_automap); + if(lpfc4_automap != -1) + value = (void *)((ulong)lpfc4_automap); + break; + case CFG_CR_DELAY: /* cr_delay */ + value = (void *)((ulong)lpfc_cr_delay); + if(lpfc4_cr_delay != -1) + value = (void *)((ulong)lpfc4_cr_delay); + break; + case CFG_CR_COUNT: /* cr_count */ + value = (void *)((ulong)lpfc_cr_count); + if(lpfc4_cr_count != -1) + value = (void *)((ulong)lpfc4_cr_count); + break; + case CFG_DFT_TGT_Q_DEPTH: /* tgt_queue_depth */ + value = (void *)((ulong)lpfc_tgt_queue_depth); + if(lpfc4_tgt_queue_depth != -1) + value = (void *)((ulong)lpfc4_tgt_queue_depth); + break; + case CFG_DFT_LUN_Q_DEPTH: /* lun_queue_depth */ + value = (void *)((ulong)lpfc_lun_queue_depth); + if(lpfc4_lun_queue_depth != -1) + value = (void *)((ulong)lpfc4_lun_queue_depth); + break; + case CFG_FCPFABRIC_TMO: /* fcpfabric-tmo */ + value = (void *)((ulong)lpfc_fcpfabric_tmo); + if(lpfc4_fcpfabric_tmo != -1) + value = (void *)((ulong)lpfc4_fcpfabric_tmo); + break; + case CFG_FCP_CLASS: /* fcp-class */ + value = (void *)((ulong)lpfc_fcp_class); + if(lpfc4_fcp_class != -1) + value = (void *)((ulong)lpfc4_fcp_class); + break; + case CFG_USE_ADISC: /* use-adisc */ + value = (void *)((ulong)lpfc_use_adisc); + if(lpfc4_use_adisc != -1) + value = (void *)((ulong)lpfc4_use_adisc); + break; + case CFG_NO_DEVICE_DELAY: /* no-device-delay */ + value = (void *)((ulong)lpfc_no_device_delay); + if(lpfc4_no_device_delay != -1) + value = (void *)((ulong)lpfc4_no_device_delay); + break; + case CFG_NETWORK_ON: /* network-on */ + value = (void *)((ulong)lpfc_network_on); + if(lpfc4_network_on != -1) + value = (void *)((ulong)lpfc4_network_on); + break; + case CFG_POST_IP_BUF: /* post-ip-buf */ + value = (void *)((ulong)lpfc_post_ip_buf); + if(lpfc4_post_ip_buf != -1) + value = (void *)((ulong)lpfc4_post_ip_buf); + break; + case CFG_XMT_Q_SIZE: /* xmt-que-size */ + value = (void *)((ulong)lpfc_xmt_que_size); + if(lpfc4_xmt_que_size != -1) + value = (void *)((ulong)lpfc4_xmt_que_size); + break; + case CFG_IP_CLASS: /* ip-class */ + value = (void *)((ulong)lpfc_ip_class); + if(lpfc4_ip_class != -1) + value = (void *)((ulong)lpfc4_ip_class); + break; + case CFG_ACK0: /* ack0 */ + value = (void *)((ulong)lpfc_ack0support); + if(lpfc4_ack0support != -1) + value = (void *)((ulong)lpfc4_ack0support); + break; + case CFG_TOPOLOGY: /* topology */ + value = (void *)((ulong)lpfc_topology); + if(lpfc4_topology != -1) + value = (void *)((ulong)lpfc4_topology); + break; + case CFG_SCAN_DOWN: /* scan-down */ + value = (void *)((ulong)lpfc_scandown); + if(lpfc4_scandown != -1) + value = (void *)((ulong)lpfc4_scandown); + break; + case CFG_LINKDOWN_TMO: /* linkdown-tmo */ + value = (void *)((ulong)lpfc_linkdown_tmo); + if(lpfc4_linkdown_tmo != -1) + value = (void *)((ulong)lpfc4_linkdown_tmo); + break; + case CFG_HOLDIO: /* nodev-holdio */ + value = (void *)((ulong)lpfc_nodev_holdio); + if(lpfc4_nodev_holdio != -1) + value = (void *)((ulong)lpfc4_nodev_holdio); + break; + case CFG_DELAY_RSP_ERR: /* delay-rsp-err */ + value = (void *)((ulong)lpfc_delay_rsp_err); + if(lpfc4_delay_rsp_err != -1) + value = (void *)((ulong)lpfc4_delay_rsp_err); + break; + case CFG_CHK_COND_ERR: /* check-cond-err */ + value = (void *)((ulong)lpfc_check_cond_err); + if(lpfc4_check_cond_err != -1) + value = (void *)((ulong)lpfc4_check_cond_err); + break; + case CFG_NODEV_TMO: /* nodev-tmo */ + value = (void *)((ulong)lpfc_nodev_tmo); + if(lpfc4_nodev_tmo != -1) + value = (void *)((ulong)lpfc4_nodev_tmo); + break; + case CFG_LINK_SPEED: /* link-speed */ + value = (void *)((ulong)lpfc_link_speed); + if(lpfc4_link_speed != -1) + value = (void *)((ulong)lpfc4_link_speed); + break; + case CFG_DQFULL_THROTTLE_UP_TIME: /* dqfull-throttle-up-time */ + value = (void *)((ulong)lpfc_dqfull_throttle_up_time); + if(lpfc4_dqfull_throttle_up_time != -1) + value = (void *)((ulong)lpfc4_dqfull_throttle_up_time); + break; + case CFG_DQFULL_THROTTLE_UP_INC: /* dqfull-throttle-up-inc */ + value = (void *)((ulong)lpfc_dqfull_throttle_up_inc); + if(lpfc4_dqfull_throttle_up_inc != -1) + value = (void *)((ulong)lpfc4_dqfull_throttle_up_inc); + break; + } + break; + case 5: /* HBA 5 */ + switch(param) { + case CFG_LOG_VERBOSE: /* log-verbose */ + value = (void *)((ulong)lpfc_log_verbose); + if(lpfc5_log_verbose != -1) + value = (void *)((ulong)lpfc5_log_verbose); + break; + case CFG_LOG_ONLY: /* log-only */ + value = (void *)((ulong)lpfc_log_only); + if(lpfc5_log_only != -1) + value = (void *)((ulong)lpfc5_log_only); + break; + case CFG_NUM_IOCBS: /* num-iocbs */ + value = (void *)((ulong)lpfc_num_iocbs); + if(lpfc5_num_iocbs != -1) + value = (void *)((ulong)lpfc5_num_iocbs); + break; + case CFG_NUM_BUFS: /* num-bufs */ + value = (void *)((ulong)lpfc_num_bufs); + if(lpfc5_num_bufs != -1) + value = (void *)((ulong)lpfc5_num_bufs); + break; + case CFG_AUTOMAP: /* automap */ + value = (void *)((ulong)lpfc_automap); + if(lpfc5_automap != -1) + value = (void *)((ulong)lpfc5_automap); + break; + case CFG_CR_DELAY: /* cr_delay */ + value = (void *)((ulong)lpfc_cr_delay); + if(lpfc5_cr_delay != -1) + value = (void *)((ulong)lpfc5_cr_delay); + break; + case CFG_CR_COUNT: /* cr_count */ + value = (void *)((ulong)lpfc_cr_count); + if(lpfc5_cr_count != -1) + value = (void *)((ulong)lpfc5_cr_count); + break; + case CFG_DFT_TGT_Q_DEPTH: /* tgt_queue_depth */ + value = (void *)((ulong)lpfc_tgt_queue_depth); + if(lpfc5_tgt_queue_depth != -1) + value = (void *)((ulong)lpfc5_tgt_queue_depth); + break; + case CFG_DFT_LUN_Q_DEPTH: /* lun_queue_depth */ + value = (void *)((ulong)lpfc_lun_queue_depth); + if(lpfc5_lun_queue_depth != -1) + value = (void *)((ulong)lpfc5_lun_queue_depth); + break; + case CFG_FCPFABRIC_TMO: /* fcpfabric-tmo */ + value = (void *)((ulong)lpfc_fcpfabric_tmo); + if(lpfc5_fcpfabric_tmo != -1) + value = (void *)((ulong)lpfc5_fcpfabric_tmo); + break; + case CFG_FCP_CLASS: /* fcp-class */ + value = (void *)((ulong)lpfc_fcp_class); + if(lpfc5_fcp_class != -1) + value = (void *)((ulong)lpfc5_fcp_class); + break; + case CFG_USE_ADISC: /* use-adisc */ + value = (void *)((ulong)lpfc_use_adisc); + if(lpfc5_use_adisc != -1) + value = (void *)((ulong)lpfc5_use_adisc); + break; + case CFG_NO_DEVICE_DELAY: /* no-device-delay */ + value = (void *)((ulong)lpfc_no_device_delay); + if(lpfc5_no_device_delay != -1) + value = (void *)((ulong)lpfc5_no_device_delay); + break; + case CFG_NETWORK_ON: /* network-on */ + value = (void *)((ulong)lpfc_network_on); + if(lpfc5_network_on != -1) + value = (void *)((ulong)lpfc5_network_on); + break; + case CFG_POST_IP_BUF: /* post-ip-buf */ + value = (void *)((ulong)lpfc_post_ip_buf); + if(lpfc5_post_ip_buf != -1) + value = (void *)((ulong)lpfc5_post_ip_buf); + break; + case CFG_XMT_Q_SIZE: /* xmt-que-size */ + value = (void *)((ulong)lpfc_xmt_que_size); + if(lpfc5_xmt_que_size != -1) + value = (void *)((ulong)lpfc5_xmt_que_size); + break; + case CFG_IP_CLASS: /* ip-class */ + value = (void *)((ulong)lpfc_ip_class); + if(lpfc5_ip_class != -1) + value = (void *)((ulong)lpfc5_ip_class); + break; + case CFG_ACK0: /* ack0 */ + value = (void *)((ulong)lpfc_ack0support); + if(lpfc5_ack0support != -1) + value = (void *)((ulong)lpfc5_ack0support); + break; + case CFG_TOPOLOGY: /* topology */ + value = (void *)((ulong)lpfc_topology); + if(lpfc5_topology != -1) + value = (void *)((ulong)lpfc5_topology); + break; + case CFG_SCAN_DOWN: /* scan-down */ + value = (void *)((ulong)lpfc_scandown); + if(lpfc5_scandown != -1) + value = (void *)((ulong)lpfc5_scandown); + break; + case CFG_LINKDOWN_TMO: /* linkdown-tmo */ + value = (void *)((ulong)lpfc_linkdown_tmo); + if(lpfc5_linkdown_tmo != -1) + value = (void *)((ulong)lpfc5_linkdown_tmo); + break; + case CFG_HOLDIO: /* nodev-holdio */ + value = (void *)((ulong)lpfc_nodev_holdio); + if(lpfc5_nodev_holdio != -1) + value = (void *)((ulong)lpfc5_nodev_holdio); + break; + case CFG_DELAY_RSP_ERR: /* delay-rsp-err */ + value = (void *)((ulong)lpfc_delay_rsp_err); + if(lpfc5_delay_rsp_err != -1) + value = (void *)((ulong)lpfc5_delay_rsp_err); + break; + case CFG_CHK_COND_ERR: /* check-cond-err */ + value = (void *)((ulong)lpfc_check_cond_err); + if(lpfc5_check_cond_err != -1) + value = (void *)((ulong)lpfc5_check_cond_err); + break; + case CFG_NODEV_TMO: /* nodev-tmo */ + value = (void *)((ulong)lpfc_nodev_tmo); + if(lpfc5_nodev_tmo != -1) + value = (void *)((ulong)lpfc5_nodev_tmo); + break; + case CFG_LINK_SPEED: /* link-speed */ + value = (void *)((ulong)lpfc_link_speed); + if(lpfc5_link_speed != -1) + value = (void *)((ulong)lpfc5_link_speed); + break; + case CFG_DQFULL_THROTTLE_UP_TIME: /* dqfull-throttle-up-time */ + value = (void *)((ulong)lpfc_dqfull_throttle_up_time); + if(lpfc5_dqfull_throttle_up_time != -1) + value = (void *)((ulong)lpfc5_dqfull_throttle_up_time); + break; + case CFG_DQFULL_THROTTLE_UP_INC: /* dqfull-throttle-up-inc */ + value = (void *)((ulong)lpfc_dqfull_throttle_up_inc); + if(lpfc5_dqfull_throttle_up_inc != -1) + value = (void *)((ulong)lpfc5_dqfull_throttle_up_inc); + break; + } + break; + case 6: /* HBA 6 */ + switch(param) { + case CFG_LOG_VERBOSE: /* log-verbose */ + value = (void *)((ulong)lpfc_log_verbose); + if(lpfc6_log_verbose != -1) + value = (void *)((ulong)lpfc6_log_verbose); + break; + case CFG_LOG_ONLY: /* log-only */ + value = (void *)((ulong)lpfc_log_only); + if(lpfc6_log_only != -1) + value = (void *)((ulong)lpfc6_log_only); + break; + case CFG_NUM_IOCBS: /* num-iocbs */ + value = (void *)((ulong)lpfc_num_iocbs); + if(lpfc6_num_iocbs != -1) + value = (void *)((ulong)lpfc6_num_iocbs); + break; + case CFG_NUM_BUFS: /* num-bufs */ + value = (void *)((ulong)lpfc_num_bufs); + if(lpfc6_num_bufs != -1) + value = (void *)((ulong)lpfc6_num_bufs); + break; + case CFG_AUTOMAP: /* automap */ + value = (void *)((ulong)lpfc_automap); + if(lpfc6_automap != -1) + value = (void *)((ulong)lpfc6_automap); + break; + case CFG_CR_DELAY: /* cr_delay */ + value = (void *)((ulong)lpfc_cr_delay); + if(lpfc6_cr_delay != -1) + value = (void *)((ulong)lpfc6_cr_delay); + break; + case CFG_CR_COUNT: /* cr_count */ + value = (void *)((ulong)lpfc_cr_count); + if(lpfc6_cr_count != -1) + value = (void *)((ulong)lpfc6_cr_count); + break; + case CFG_DFT_TGT_Q_DEPTH: /* tgt_queue_depth */ + value = (void *)((ulong)lpfc_tgt_queue_depth); + if(lpfc6_tgt_queue_depth != -1) + value = (void *)((ulong)lpfc6_tgt_queue_depth); + break; + case CFG_DFT_LUN_Q_DEPTH: /* lun_queue_depth */ + value = (void *)((ulong)lpfc_lun_queue_depth); + if(lpfc6_lun_queue_depth != -1) + value = (void *)((ulong)lpfc6_lun_queue_depth); + break; + case CFG_FCPFABRIC_TMO: /* fcpfabric-tmo */ + value = (void *)((ulong)lpfc_fcpfabric_tmo); + if(lpfc6_fcpfabric_tmo != -1) + value = (void *)((ulong)lpfc6_fcpfabric_tmo); + break; + case CFG_FCP_CLASS: /* fcp-class */ + value = (void *)((ulong)lpfc_fcp_class); + if(lpfc6_fcp_class != -1) + value = (void *)((ulong)lpfc6_fcp_class); + break; + case CFG_USE_ADISC: /* use-adisc */ + value = (void *)((ulong)lpfc_use_adisc); + if(lpfc6_use_adisc != -1) + value = (void *)((ulong)lpfc6_use_adisc); + break; + case CFG_NO_DEVICE_DELAY: /* no-device-delay */ + value = (void *)((ulong)lpfc_no_device_delay); + if(lpfc6_no_device_delay != -1) + value = (void *)((ulong)lpfc6_no_device_delay); + break; + case CFG_NETWORK_ON: /* network-on */ + value = (void *)((ulong)lpfc_network_on); + if(lpfc6_network_on != -1) + value = (void *)((ulong)lpfc6_network_on); + break; + case CFG_POST_IP_BUF: /* post-ip-buf */ + value = (void *)((ulong)lpfc_post_ip_buf); + if(lpfc6_post_ip_buf != -1) + value = (void *)((ulong)lpfc6_post_ip_buf); + break; + case CFG_XMT_Q_SIZE: /* xmt-que-size */ + value = (void *)((ulong)lpfc_xmt_que_size); + if(lpfc6_xmt_que_size != -1) + value = (void *)((ulong)lpfc6_xmt_que_size); + break; + case CFG_IP_CLASS: /* ip-class */ + value = (void *)((ulong)lpfc_ip_class); + if(lpfc6_ip_class != -1) + value = (void *)((ulong)lpfc6_ip_class); + break; + case CFG_ACK0: /* ack0 */ + value = (void *)((ulong)lpfc_ack0support); + if(lpfc6_ack0support != -1) + value = (void *)((ulong)lpfc6_ack0support); + break; + case CFG_TOPOLOGY: /* topology */ + value = (void *)((ulong)lpfc_topology); + if(lpfc6_topology != -1) + value = (void *)((ulong)lpfc6_topology); + break; + case CFG_SCAN_DOWN: /* scan-down */ + value = (void *)((ulong)lpfc_scandown); + if(lpfc6_scandown != -1) + value = (void *)((ulong)lpfc6_scandown); + break; + case CFG_LINKDOWN_TMO: /* linkdown-tmo */ + value = (void *)((ulong)lpfc_linkdown_tmo); + if(lpfc6_linkdown_tmo != -1) + value = (void *)((ulong)lpfc6_linkdown_tmo); + break; + case CFG_HOLDIO: /* nodev-holdio */ + value = (void *)((ulong)lpfc_nodev_holdio); + if(lpfc6_nodev_holdio != -1) + value = (void *)((ulong)lpfc6_nodev_holdio); + break; + case CFG_DELAY_RSP_ERR: /* delay-rsp-err */ + value = (void *)((ulong)lpfc_delay_rsp_err); + if(lpfc6_delay_rsp_err != -1) + value = (void *)((ulong)lpfc6_delay_rsp_err); + break; + case CFG_CHK_COND_ERR: /* check-cond-err */ + value = (void *)((ulong)lpfc_check_cond_err); + if(lpfc6_check_cond_err != -1) + value = (void *)((ulong)lpfc6_check_cond_err); + break; + case CFG_NODEV_TMO: /* nodev-tmo */ + value = (void *)((ulong)lpfc_nodev_tmo); + if(lpfc6_nodev_tmo != -1) + value = (void *)((ulong)lpfc6_nodev_tmo); + break; + case CFG_LINK_SPEED: /* link-speed */ + value = (void *)((ulong)lpfc_link_speed); + if(lpfc6_link_speed != -1) + value = (void *)((ulong)lpfc6_link_speed); + break; + case CFG_DQFULL_THROTTLE_UP_TIME: /* dqfull-throttle-up-time */ + value = (void *)((ulong)lpfc_dqfull_throttle_up_time); + if(lpfc6_dqfull_throttle_up_time != -1) + value = (void *)((ulong)lpfc6_dqfull_throttle_up_time); + break; + case CFG_DQFULL_THROTTLE_UP_INC: /* dqfull-throttle-up-inc */ + value = (void *)((ulong)lpfc_dqfull_throttle_up_inc); + if(lpfc6_dqfull_throttle_up_inc != -1) + value = (void *)((ulong)lpfc6_dqfull_throttle_up_inc); + break; + } + break; + case 7: /* HBA 7 */ + switch(param) { + case CFG_LOG_VERBOSE: /* log-verbose */ + value = (void *)((ulong)lpfc_log_verbose); + if(lpfc7_log_verbose != -1) + value = (void *)((ulong)lpfc7_log_verbose); + break; + case CFG_LOG_ONLY: /* log-only */ + value = (void *)((ulong)lpfc_log_only); + if(lpfc7_log_only != -1) + value = (void *)((ulong)lpfc7_log_only); + break; + case CFG_NUM_IOCBS: /* num-iocbs */ + value = (void *)((ulong)lpfc_num_iocbs); + if(lpfc7_num_iocbs != -1) + value = (void *)((ulong)lpfc7_num_iocbs); + break; + case CFG_NUM_BUFS: /* num-bufs */ + value = (void *)((ulong)lpfc_num_bufs); + if(lpfc7_num_bufs != -1) + value = (void *)((ulong)lpfc7_num_bufs); + break; + case CFG_AUTOMAP: /* automap */ + value = (void *)((ulong)lpfc_automap); + if(lpfc7_automap != -1) + value = (void *)((ulong)lpfc7_automap); + break; + case CFG_CR_DELAY: /* cr_delay */ + value = (void *)((ulong)lpfc_cr_delay); + if(lpfc7_cr_delay != -1) + value = (void *)((ulong)lpfc7_cr_delay); + break; + case CFG_CR_COUNT: /* cr_count */ + value = (void *)((ulong)lpfc_cr_count); + if(lpfc7_cr_count != -1) + value = (void *)((ulong)lpfc7_cr_count); + break; + case CFG_DFT_TGT_Q_DEPTH: /* tgt_queue_depth */ + value = (void *)((ulong)lpfc_tgt_queue_depth); + if(lpfc7_tgt_queue_depth != -1) + value = (void *)((ulong)lpfc7_tgt_queue_depth); + break; + case CFG_DFT_LUN_Q_DEPTH: /* lun_queue_depth */ + value = (void *)((ulong)lpfc_lun_queue_depth); + if(lpfc7_lun_queue_depth != -1) + value = (void *)((ulong)lpfc7_lun_queue_depth); + break; + case CFG_FCPFABRIC_TMO: /* fcpfabric-tmo */ + value = (void *)((ulong)lpfc_fcpfabric_tmo); + if(lpfc7_fcpfabric_tmo != -1) + value = (void *)((ulong)lpfc7_fcpfabric_tmo); + break; + case CFG_FCP_CLASS: /* fcp-class */ + value = (void *)((ulong)lpfc_fcp_class); + if(lpfc7_fcp_class != -1) + value = (void *)((ulong)lpfc7_fcp_class); + break; + case CFG_USE_ADISC: /* use-adisc */ + value = (void *)((ulong)lpfc_use_adisc); + if(lpfc7_use_adisc != -1) + value = (void *)((ulong)lpfc7_use_adisc); + break; + case CFG_NO_DEVICE_DELAY: /* no-device-delay */ + value = (void *)((ulong)lpfc_no_device_delay); + if(lpfc7_no_device_delay != -1) + value = (void *)((ulong)lpfc7_no_device_delay); + break; + case CFG_NETWORK_ON: /* network-on */ + value = (void *)((ulong)lpfc_network_on); + if(lpfc7_network_on != -1) + value = (void *)((ulong)lpfc7_network_on); + break; + case CFG_POST_IP_BUF: /* post-ip-buf */ + value = (void *)((ulong)lpfc_post_ip_buf); + if(lpfc7_post_ip_buf != -1) + value = (void *)((ulong)lpfc7_post_ip_buf); + break; + case CFG_XMT_Q_SIZE: /* xmt-que-size */ + value = (void *)((ulong)lpfc_xmt_que_size); + if(lpfc7_xmt_que_size != -1) + value = (void *)((ulong)lpfc7_xmt_que_size); + break; + case CFG_IP_CLASS: /* ip-class */ + value = (void *)((ulong)lpfc_ip_class); + if(lpfc7_ip_class != -1) + value = (void *)((ulong)lpfc7_ip_class); + break; + case CFG_ACK0: /* ack0 */ + value = (void *)((ulong)lpfc_ack0support); + if(lpfc7_ack0support != -1) + value = (void *)((ulong)lpfc7_ack0support); + break; + case CFG_TOPOLOGY: /* topology */ + value = (void *)((ulong)lpfc_topology); + if(lpfc7_topology != -1) + value = (void *)((ulong)lpfc7_topology); + break; + case CFG_SCAN_DOWN: /* scan-down */ + value = (void *)((ulong)lpfc_scandown); + if(lpfc7_scandown != -1) + value = (void *)((ulong)lpfc7_scandown); + break; + case CFG_LINKDOWN_TMO: /* linkdown-tmo */ + value = (void *)((ulong)lpfc_linkdown_tmo); + if(lpfc7_linkdown_tmo != -1) + value = (void *)((ulong)lpfc7_linkdown_tmo); + break; + case CFG_HOLDIO: /* nodev-holdio */ + value = (void *)((ulong)lpfc_nodev_holdio); + if(lpfc7_nodev_holdio != -1) + value = (void *)((ulong)lpfc7_nodev_holdio); + break; + case CFG_DELAY_RSP_ERR: /* delay-rsp-err */ + value = (void *)((ulong)lpfc_delay_rsp_err); + if(lpfc7_delay_rsp_err != -1) + value = (void *)((ulong)lpfc7_delay_rsp_err); + break; + case CFG_CHK_COND_ERR: /* check-cond-err */ + value = (void *)((ulong)lpfc_check_cond_err); + if(lpfc7_check_cond_err != -1) + value = (void *)((ulong)lpfc7_check_cond_err); + break; + case CFG_NODEV_TMO: /* nodev-tmo */ + value = (void *)((ulong)lpfc_nodev_tmo); + if(lpfc7_nodev_tmo != -1) + value = (void *)((ulong)lpfc7_nodev_tmo); + break; + case CFG_LINK_SPEED: /* link-speed */ + value = (void *)((ulong)lpfc_link_speed); + if(lpfc7_link_speed != -1) + value = (void *)((ulong)lpfc7_link_speed); + break; + case CFG_DQFULL_THROTTLE_UP_TIME: /* dqfull-throttle-up-time */ + value = (void *)((ulong)lpfc_dqfull_throttle_up_time); + if(lpfc7_dqfull_throttle_up_time != -1) + value = (void *)((ulong)lpfc7_dqfull_throttle_up_time); + break; + case CFG_DQFULL_THROTTLE_UP_INC: /* dqfull-throttle-up-inc */ + value = (void *)((ulong)lpfc_dqfull_throttle_up_inc); + if(lpfc7_dqfull_throttle_up_inc != -1) + value = (void *)((ulong)lpfc7_dqfull_throttle_up_inc); + break; + } + break; + case 8: /* HBA 8 */ + switch(param) { + case CFG_LOG_VERBOSE: /* log-verbose */ + value = (void *)((ulong)lpfc_log_verbose); + if(lpfc8_log_verbose != -1) + value = (void *)((ulong)lpfc8_log_verbose); + break; + case CFG_LOG_ONLY: /* log-only */ + value = (void *)((ulong)lpfc_log_only); + if(lpfc8_log_only != -1) + value = (void *)((ulong)lpfc8_log_only); + break; + case CFG_NUM_IOCBS: /* num-iocbs */ + value = (void *)((ulong)lpfc_num_iocbs); + if(lpfc8_num_iocbs != -1) + value = (void *)((ulong)lpfc8_num_iocbs); + break; + case CFG_NUM_BUFS: /* num-bufs */ + value = (void *)((ulong)lpfc_num_bufs); + if(lpfc8_num_bufs != -1) + value = (void *)((ulong)lpfc8_num_bufs); + break; + case CFG_AUTOMAP: /* automap */ + value = (void *)((ulong)lpfc_automap); + if(lpfc8_automap != -1) + value = (void *)((ulong)lpfc8_automap); + break; + case CFG_CR_DELAY: /* cr_delay */ + value = (void *)((ulong)lpfc_cr_delay); + if(lpfc8_cr_delay != -1) + value = (void *)((ulong)lpfc8_cr_delay); + break; + case CFG_CR_COUNT: /* cr_count */ + value = (void *)((ulong)lpfc_cr_count); + if(lpfc8_cr_count != -1) + value = (void *)((ulong)lpfc8_cr_count); + break; + case CFG_DFT_TGT_Q_DEPTH: /* tgt_queue_depth */ + value = (void *)((ulong)lpfc_tgt_queue_depth); + if(lpfc8_tgt_queue_depth != -1) + value = (void *)((ulong)lpfc8_tgt_queue_depth); + break; + case CFG_DFT_LUN_Q_DEPTH: /* lun_queue_depth */ + value = (void *)((ulong)lpfc_lun_queue_depth); + if(lpfc8_lun_queue_depth != -1) + value = (void *)((ulong)lpfc8_lun_queue_depth); + break; + case CFG_FCPFABRIC_TMO: /* fcpfabric-tmo */ + value = (void *)((ulong)lpfc_fcpfabric_tmo); + if(lpfc8_fcpfabric_tmo != -1) + value = (void *)((ulong)lpfc8_fcpfabric_tmo); + break; + case CFG_FCP_CLASS: /* fcp-class */ + value = (void *)((ulong)lpfc_fcp_class); + if(lpfc8_fcp_class != -1) + value = (void *)((ulong)lpfc8_fcp_class); + break; + case CFG_USE_ADISC: /* use-adisc */ + value = (void *)((ulong)lpfc_use_adisc); + if(lpfc8_use_adisc != -1) + value = (void *)((ulong)lpfc8_use_adisc); + break; + case CFG_NO_DEVICE_DELAY: /* no-device-delay */ + value = (void *)((ulong)lpfc_no_device_delay); + if(lpfc8_no_device_delay != -1) + value = (void *)((ulong)lpfc8_no_device_delay); + break; + case CFG_NETWORK_ON: /* network-on */ + value = (void *)((ulong)lpfc_network_on); + if(lpfc8_network_on != -1) + value = (void *)((ulong)lpfc8_network_on); + break; + case CFG_POST_IP_BUF: /* post-ip-buf */ + value = (void *)((ulong)lpfc_post_ip_buf); + if(lpfc8_post_ip_buf != -1) + value = (void *)((ulong)lpfc8_post_ip_buf); + break; + case CFG_XMT_Q_SIZE: /* xmt-que-size */ + value = (void *)((ulong)lpfc_xmt_que_size); + if(lpfc8_xmt_que_size != -1) + value = (void *)((ulong)lpfc8_xmt_que_size); + break; + case CFG_IP_CLASS: /* ip-class */ + value = (void *)((ulong)lpfc_ip_class); + if(lpfc8_ip_class != -1) + value = (void *)((ulong)lpfc8_ip_class); + break; + case CFG_ACK0: /* ack0 */ + value = (void *)((ulong)lpfc_ack0support); + if(lpfc8_ack0support != -1) + value = (void *)((ulong)lpfc8_ack0support); + break; + case CFG_TOPOLOGY: /* topology */ + value = (void *)((ulong)lpfc_topology); + if(lpfc8_topology != -1) + value = (void *)((ulong)lpfc8_topology); + break; + case CFG_SCAN_DOWN: /* scan-down */ + value = (void *)((ulong)lpfc_scandown); + if(lpfc8_scandown != -1) + value = (void *)((ulong)lpfc8_scandown); + break; + case CFG_LINKDOWN_TMO: /* linkdown-tmo */ + value = (void *)((ulong)lpfc_linkdown_tmo); + if(lpfc8_linkdown_tmo != -1) + value = (void *)((ulong)lpfc8_linkdown_tmo); + break; + case CFG_HOLDIO: /* nodev-holdio */ + value = (void *)((ulong)lpfc_nodev_holdio); + if(lpfc8_nodev_holdio != -1) + value = (void *)((ulong)lpfc8_nodev_holdio); + break; + case CFG_DELAY_RSP_ERR: /* delay-rsp-err */ + value = (void *)((ulong)lpfc_delay_rsp_err); + if(lpfc8_delay_rsp_err != -1) + value = (void *)((ulong)lpfc8_delay_rsp_err); + break; + case CFG_CHK_COND_ERR: /* check-cond-err */ + value = (void *)((ulong)lpfc_check_cond_err); + if(lpfc8_check_cond_err != -1) + value = (void *)((ulong)lpfc8_check_cond_err); + break; + case CFG_NODEV_TMO: /* nodev-tmo */ + value = (void *)((ulong)lpfc_nodev_tmo); + if(lpfc8_nodev_tmo != -1) + value = (void *)((ulong)lpfc8_nodev_tmo); + break; + case CFG_LINK_SPEED: /* link-speed */ + value = (void *)((ulong)lpfc_link_speed); + if(lpfc8_link_speed != -1) + value = (void *)((ulong)lpfc8_link_speed); + break; + case CFG_DQFULL_THROTTLE_UP_TIME: /* dqfull-throttle-up-time */ + value = (void *)((ulong)lpfc_dqfull_throttle_up_time); + if(lpfc8_dqfull_throttle_up_time != -1) + value = (void *)((ulong)lpfc8_dqfull_throttle_up_time); + break; + case CFG_DQFULL_THROTTLE_UP_INC: /* dqfull-throttle-up-inc */ + value = (void *)((ulong)lpfc_dqfull_throttle_up_inc); + if(lpfc8_dqfull_throttle_up_inc != -1) + value = (void *)((ulong)lpfc8_dqfull_throttle_up_inc); + break; + } + break; + case 9: /* HBA 9 */ + switch(param) { + case CFG_LOG_VERBOSE: /* log-verbose */ + value = (void *)((ulong)lpfc_log_verbose); + if(lpfc9_log_verbose != -1) + value = (void *)((ulong)lpfc9_log_verbose); + break; + case CFG_LOG_ONLY: /* log-only */ + value = (void *)((ulong)lpfc_log_only); + if(lpfc9_log_only != -1) + value = (void *)((ulong)lpfc9_log_only); + break; + case CFG_NUM_IOCBS: /* num-iocbs */ + value = (void *)((ulong)lpfc_num_iocbs); + if(lpfc9_num_iocbs != -1) + value = (void *)((ulong)lpfc9_num_iocbs); + break; + case CFG_NUM_BUFS: /* num-bufs */ + value = (void *)((ulong)lpfc_num_bufs); + if(lpfc9_num_bufs != -1) + value = (void *)((ulong)lpfc9_num_bufs); + break; + case CFG_AUTOMAP: /* automap */ + value = (void *)((ulong)lpfc_automap); + if(lpfc9_automap != -1) + value = (void *)((ulong)lpfc9_automap); + break; + case CFG_CR_DELAY: /* cr_delay */ + value = (void *)((ulong)lpfc_cr_delay); + if(lpfc9_cr_delay != -1) + value = (void *)((ulong)lpfc9_cr_delay); + break; + case CFG_CR_COUNT: /* cr_count */ + value = (void *)((ulong)lpfc_cr_count); + if(lpfc9_cr_count != -1) + value = (void *)((ulong)lpfc9_cr_count); + break; + case CFG_DFT_TGT_Q_DEPTH: /* tgt_queue_depth */ + value = (void *)((ulong)lpfc_tgt_queue_depth); + if(lpfc9_tgt_queue_depth != -1) + value = (void *)((ulong)lpfc9_tgt_queue_depth); + break; + case CFG_DFT_LUN_Q_DEPTH: /* lun_queue_depth */ + value = (void *)((ulong)lpfc_lun_queue_depth); + if(lpfc9_lun_queue_depth != -1) + value = (void *)((ulong)lpfc9_lun_queue_depth); + break; + case CFG_FCPFABRIC_TMO: /* fcpfabric-tmo */ + value = (void *)((ulong)lpfc_fcpfabric_tmo); + if(lpfc9_fcpfabric_tmo != -1) + value = (void *)((ulong)lpfc9_fcpfabric_tmo); + break; + case CFG_FCP_CLASS: /* fcp-class */ + value = (void *)((ulong)lpfc_fcp_class); + if(lpfc9_fcp_class != -1) + value = (void *)((ulong)lpfc9_fcp_class); + break; + case CFG_USE_ADISC: /* use-adisc */ + value = (void *)((ulong)lpfc_use_adisc); + if(lpfc9_use_adisc != -1) + value = (void *)((ulong)lpfc9_use_adisc); + break; + case CFG_NO_DEVICE_DELAY: /* no-device-delay */ + value = (void *)((ulong)lpfc_no_device_delay); + if(lpfc9_no_device_delay != -1) + value = (void *)((ulong)lpfc9_no_device_delay); + break; + case CFG_NETWORK_ON: /* network-on */ + value = (void *)((ulong)lpfc_network_on); + if(lpfc9_network_on != -1) + value = (void *)((ulong)lpfc9_network_on); + break; + case CFG_POST_IP_BUF: /* post-ip-buf */ + value = (void *)((ulong)lpfc_post_ip_buf); + if(lpfc9_post_ip_buf != -1) + value = (void *)((ulong)lpfc9_post_ip_buf); + break; + case CFG_XMT_Q_SIZE: /* xmt-que-size */ + value = (void *)((ulong)lpfc_xmt_que_size); + if(lpfc9_xmt_que_size != -1) + value = (void *)((ulong)lpfc9_xmt_que_size); + break; + case CFG_IP_CLASS: /* ip-class */ + value = (void *)((ulong)lpfc_ip_class); + if(lpfc9_ip_class != -1) + value = (void *)((ulong)lpfc9_ip_class); + break; + case CFG_ACK0: /* ack0 */ + value = (void *)((ulong)lpfc_ack0support); + if(lpfc9_ack0support != -1) + value = (void *)((ulong)lpfc9_ack0support); + break; + case CFG_TOPOLOGY: /* topology */ + value = (void *)((ulong)lpfc_topology); + if(lpfc9_topology != -1) + value = (void *)((ulong)lpfc9_topology); + break; + case CFG_SCAN_DOWN: /* scan-down */ + value = (void *)((ulong)lpfc_scandown); + if(lpfc9_scandown != -1) + value = (void *)((ulong)lpfc9_scandown); + break; + case CFG_LINKDOWN_TMO: /* linkdown-tmo */ + value = (void *)((ulong)lpfc_linkdown_tmo); + if(lpfc9_linkdown_tmo != -1) + value = (void *)((ulong)lpfc9_linkdown_tmo); + break; + case CFG_HOLDIO: /* nodev-holdio */ + value = (void *)((ulong)lpfc_nodev_holdio); + if(lpfc9_nodev_holdio != -1) + value = (void *)((ulong)lpfc9_nodev_holdio); + break; + case CFG_DELAY_RSP_ERR: /* delay-rsp-err */ + value = (void *)((ulong)lpfc_delay_rsp_err); + if(lpfc9_delay_rsp_err != -1) + value = (void *)((ulong)lpfc9_delay_rsp_err); + break; + case CFG_CHK_COND_ERR: /* check-cond-err */ + value = (void *)((ulong)lpfc_check_cond_err); + if(lpfc9_check_cond_err != -1) + value = (void *)((ulong)lpfc9_check_cond_err); + break; + case CFG_NODEV_TMO: /* nodev-tmo */ + value = (void *)((ulong)lpfc_nodev_tmo); + if(lpfc9_nodev_tmo != -1) + value = (void *)((ulong)lpfc9_nodev_tmo); + break; + case CFG_LINK_SPEED: /* link-speed */ + value = (void *)((ulong)lpfc_link_speed); + if(lpfc9_link_speed != -1) + value = (void *)((ulong)lpfc9_link_speed); + break; + case CFG_DQFULL_THROTTLE_UP_TIME: /* dqfull-throttle-up-time */ + value = (void *)((ulong)lpfc_dqfull_throttle_up_time); + if(lpfc9_dqfull_throttle_up_time != -1) + value = (void *)((ulong)lpfc9_dqfull_throttle_up_time); + break; + case CFG_DQFULL_THROTTLE_UP_INC: /* dqfull-throttle-up-inc */ + value = (void *)((ulong)lpfc_dqfull_throttle_up_inc); + if(lpfc9_dqfull_throttle_up_inc != -1) + value = (void *)((ulong)lpfc9_dqfull_throttle_up_inc); + break; + } + break; + case 10: /* HBA 10 */ + switch(param) { + case CFG_LOG_VERBOSE: /* log-verbose */ + value = (void *)((ulong)lpfc_log_verbose); + if(lpfc10_log_verbose != -1) + value = (void *)((ulong)lpfc10_log_verbose); + break; + case CFG_LOG_ONLY: /* log-only */ + value = (void *)((ulong)lpfc_log_only); + if(lpfc10_log_only != -1) + value = (void *)((ulong)lpfc10_log_only); + break; + case CFG_NUM_IOCBS: /* num-iocbs */ + value = (void *)((ulong)lpfc_num_iocbs); + if(lpfc10_num_iocbs != -1) + value = (void *)((ulong)lpfc10_num_iocbs); + break; + case CFG_NUM_BUFS: /* num-bufs */ + value = (void *)((ulong)lpfc_num_bufs); + if(lpfc10_num_bufs != -1) + value = (void *)((ulong)lpfc10_num_bufs); + break; + case CFG_AUTOMAP: /* automap */ + value = (void *)((ulong)lpfc_automap); + if(lpfc10_automap != -1) + value = (void *)((ulong)lpfc10_automap); + break; + case CFG_CR_DELAY: /* cr_delay */ + value = (void *)((ulong)lpfc_cr_delay); + if(lpfc10_cr_delay != -1) + value = (void *)((ulong)lpfc10_cr_delay); + break; + case CFG_CR_COUNT: /* cr_count */ + value = (void *)((ulong)lpfc_cr_count); + if(lpfc10_cr_count != -1) + value = (void *)((ulong)lpfc10_cr_count); + break; + case CFG_DFT_TGT_Q_DEPTH: /* tgt_queue_depth */ + value = (void *)((ulong)lpfc_tgt_queue_depth); + if(lpfc10_tgt_queue_depth != -1) + value = (void *)((ulong)lpfc10_tgt_queue_depth); + break; + case CFG_DFT_LUN_Q_DEPTH: /* lun_queue_depth */ + value = (void *)((ulong)lpfc_lun_queue_depth); + if(lpfc10_lun_queue_depth != -1) + value = (void *)((ulong)lpfc10_lun_queue_depth); + break; + case CFG_FCPFABRIC_TMO: /* fcpfabric-tmo */ + value = (void *)((ulong)lpfc_fcpfabric_tmo); + if(lpfc10_fcpfabric_tmo != -1) + value = (void *)((ulong)lpfc10_fcpfabric_tmo); + break; + case CFG_FCP_CLASS: /* fcp-class */ + value = (void *)((ulong)lpfc_fcp_class); + if(lpfc10_fcp_class != -1) + value = (void *)((ulong)lpfc10_fcp_class); + break; + case CFG_USE_ADISC: /* use-adisc */ + value = (void *)((ulong)lpfc_use_adisc); + if(lpfc10_use_adisc != -1) + value = (void *)((ulong)lpfc10_use_adisc); + break; + case CFG_NO_DEVICE_DELAY: /* no-device-delay */ + value = (void *)((ulong)lpfc_no_device_delay); + if(lpfc10_no_device_delay != -1) + value = (void *)((ulong)lpfc10_no_device_delay); + break; + case CFG_NETWORK_ON: /* network-on */ + value = (void *)((ulong)lpfc_network_on); + if(lpfc10_network_on != -1) + value = (void *)((ulong)lpfc10_network_on); + break; + case CFG_POST_IP_BUF: /* post-ip-buf */ + value = (void *)((ulong)lpfc_post_ip_buf); + if(lpfc10_post_ip_buf != -1) + value = (void *)((ulong)lpfc10_post_ip_buf); + break; + case CFG_XMT_Q_SIZE: /* xmt-que-size */ + value = (void *)((ulong)lpfc_xmt_que_size); + if(lpfc10_xmt_que_size != -1) + value = (void *)((ulong)lpfc10_xmt_que_size); + break; + case CFG_IP_CLASS: /* ip-class */ + value = (void *)((ulong)lpfc_ip_class); + if(lpfc10_ip_class != -1) + value = (void *)((ulong)lpfc10_ip_class); + break; + case CFG_ACK0: /* ack0 */ + value = (void *)((ulong)lpfc_ack0support); + if(lpfc10_ack0support != -1) + value = (void *)((ulong)lpfc10_ack0support); + break; + case CFG_TOPOLOGY: /* topology */ + value = (void *)((ulong)lpfc_topology); + if(lpfc10_topology != -1) + value = (void *)((ulong)lpfc10_topology); + break; + case CFG_SCAN_DOWN: /* scan-down */ + value = (void *)((ulong)lpfc_scandown); + if(lpfc10_scandown != -1) + value = (void *)((ulong)lpfc10_scandown); + break; + case CFG_LINKDOWN_TMO: /* linkdown-tmo */ + value = (void *)((ulong)lpfc_linkdown_tmo); + if(lpfc10_linkdown_tmo != -1) + value = (void *)((ulong)lpfc10_linkdown_tmo); + break; + case CFG_HOLDIO: /* nodev-holdio */ + value = (void *)((ulong)lpfc_nodev_holdio); + if(lpfc10_nodev_holdio != -1) + value = (void *)((ulong)lpfc10_nodev_holdio); + break; + case CFG_DELAY_RSP_ERR: /* delay-rsp-err */ + value = (void *)((ulong)lpfc_delay_rsp_err); + if(lpfc10_delay_rsp_err != -1) + value = (void *)((ulong)lpfc10_delay_rsp_err); + break; + case CFG_CHK_COND_ERR: /* check-cond-err */ + value = (void *)((ulong)lpfc_check_cond_err); + if(lpfc10_check_cond_err != -1) + value = (void *)((ulong)lpfc10_check_cond_err); + break; + case CFG_NODEV_TMO: /* nodev-tmo */ + value = (void *)((ulong)lpfc_nodev_tmo); + if(lpfc10_nodev_tmo != -1) + value = (void *)((ulong)lpfc10_nodev_tmo); + break; + case CFG_LINK_SPEED: /* link-speed */ + value = (void *)((ulong)lpfc_link_speed); + if(lpfc10_link_speed != -1) + value = (void *)((ulong)lpfc10_link_speed); + break; + case CFG_DQFULL_THROTTLE_UP_TIME: /* dqfull-throttle-up-time */ + value = (void *)((ulong)lpfc_dqfull_throttle_up_time); + if(lpfc10_dqfull_throttle_up_time != -1) + value = (void *)((ulong)lpfc10_dqfull_throttle_up_time); + break; + case CFG_DQFULL_THROTTLE_UP_INC: /* dqfull-throttle-up-inc */ + value = (void *)((ulong)lpfc_dqfull_throttle_up_inc); + if(lpfc10_dqfull_throttle_up_inc != -1) + value = (void *)((ulong)lpfc10_dqfull_throttle_up_inc); + break; + } + break; + case 11: /* HBA 11 */ + switch(param) { + case CFG_LOG_VERBOSE: /* log-verbose */ + value = (void *)((ulong)lpfc_log_verbose); + if(lpfc11_log_verbose != -1) + value = (void *)((ulong)lpfc11_log_verbose); + break; + case CFG_LOG_ONLY: /* log-only */ + value = (void *)((ulong)lpfc_log_only); + if(lpfc11_log_only != -1) + value = (void *)((ulong)lpfc11_log_only); + break; + case CFG_NUM_IOCBS: /* num-iocbs */ + value = (void *)((ulong)lpfc_num_iocbs); + if(lpfc11_num_iocbs != -1) + value = (void *)((ulong)lpfc11_num_iocbs); + break; + case CFG_NUM_BUFS: /* num-bufs */ + value = (void *)((ulong)lpfc_num_bufs); + if(lpfc11_num_bufs != -1) + value = (void *)((ulong)lpfc11_num_bufs); + break; + case CFG_AUTOMAP: /* automap */ + value = (void *)((ulong)lpfc_automap); + if(lpfc11_automap != -1) + value = (void *)((ulong)lpfc11_automap); + break; + case CFG_CR_DELAY: /* cr_delay */ + value = (void *)((ulong)lpfc_cr_delay); + if(lpfc11_cr_delay != -1) + value = (void *)((ulong)lpfc11_cr_delay); + break; + case CFG_CR_COUNT: /* cr_count */ + value = (void *)((ulong)lpfc_cr_count); + if(lpfc11_cr_count != -1) + value = (void *)((ulong)lpfc11_cr_count); + break; + case CFG_DFT_TGT_Q_DEPTH: /* tgt_queue_depth */ + value = (void *)((ulong)lpfc_tgt_queue_depth); + if(lpfc11_tgt_queue_depth != -1) + value = (void *)((ulong)lpfc11_tgt_queue_depth); + break; + case CFG_DFT_LUN_Q_DEPTH: /* lun_queue_depth */ + value = (void *)((ulong)lpfc_lun_queue_depth); + if(lpfc11_lun_queue_depth != -1) + value = (void *)((ulong)lpfc11_lun_queue_depth); + break; + case CFG_FCPFABRIC_TMO: /* fcpfabric-tmo */ + value = (void *)((ulong)lpfc_fcpfabric_tmo); + if(lpfc11_fcpfabric_tmo != -1) + value = (void *)((ulong)lpfc11_fcpfabric_tmo); + break; + case CFG_FCP_CLASS: /* fcp-class */ + value = (void *)((ulong)lpfc_fcp_class); + if(lpfc11_fcp_class != -1) + value = (void *)((ulong)lpfc11_fcp_class); + break; + case CFG_USE_ADISC: /* use-adisc */ + value = (void *)((ulong)lpfc_use_adisc); + if(lpfc11_use_adisc != -1) + value = (void *)((ulong)lpfc11_use_adisc); + break; + case CFG_NO_DEVICE_DELAY: /* no-device-delay */ + value = (void *)((ulong)lpfc_no_device_delay); + if(lpfc11_no_device_delay != -1) + value = (void *)((ulong)lpfc11_no_device_delay); + break; + case CFG_NETWORK_ON: /* network-on */ + value = (void *)((ulong)lpfc_network_on); + if(lpfc11_network_on != -1) + value = (void *)((ulong)lpfc11_network_on); + break; + case CFG_POST_IP_BUF: /* post-ip-buf */ + value = (void *)((ulong)lpfc_post_ip_buf); + if(lpfc11_post_ip_buf != -1) + value = (void *)((ulong)lpfc11_post_ip_buf); + break; + case CFG_XMT_Q_SIZE: /* xmt-que-size */ + value = (void *)((ulong)lpfc_xmt_que_size); + if(lpfc11_xmt_que_size != -1) + value = (void *)((ulong)lpfc11_xmt_que_size); + break; + case CFG_IP_CLASS: /* ip-class */ + value = (void *)((ulong)lpfc_ip_class); + if(lpfc11_ip_class != -1) + value = (void *)((ulong)lpfc11_ip_class); + break; + case CFG_ACK0: /* ack0 */ + value = (void *)((ulong)lpfc_ack0support); + if(lpfc11_ack0support != -1) + value = (void *)((ulong)lpfc11_ack0support); + break; + case CFG_TOPOLOGY: /* topology */ + value = (void *)((ulong)lpfc_topology); + if(lpfc11_topology != -1) + value = (void *)((ulong)lpfc11_topology); + break; + case CFG_SCAN_DOWN: /* scan-down */ + value = (void *)((ulong)lpfc_scandown); + if(lpfc11_scandown != -1) + value = (void *)((ulong)lpfc11_scandown); + break; + case CFG_LINKDOWN_TMO: /* linkdown-tmo */ + value = (void *)((ulong)lpfc_linkdown_tmo); + if(lpfc11_linkdown_tmo != -1) + value = (void *)((ulong)lpfc11_linkdown_tmo); + break; + case CFG_HOLDIO: /* nodev-holdio */ + value = (void *)((ulong)lpfc_nodev_holdio); + if(lpfc11_nodev_holdio != -1) + value = (void *)((ulong)lpfc11_nodev_holdio); + break; + case CFG_DELAY_RSP_ERR: /* delay-rsp-err */ + value = (void *)((ulong)lpfc_delay_rsp_err); + if(lpfc11_delay_rsp_err != -1) + value = (void *)((ulong)lpfc11_delay_rsp_err); + break; + case CFG_CHK_COND_ERR: /* check-cond-err */ + value = (void *)((ulong)lpfc_check_cond_err); + if(lpfc11_check_cond_err != -1) + value = (void *)((ulong)lpfc11_check_cond_err); + break; + case CFG_NODEV_TMO: /* nodev-tmo */ + value = (void *)((ulong)lpfc_nodev_tmo); + if(lpfc11_nodev_tmo != -1) + value = (void *)((ulong)lpfc11_nodev_tmo); + break; + case CFG_LINK_SPEED: /* link-speed */ + value = (void *)((ulong)lpfc_link_speed); + if(lpfc11_link_speed != -1) + value = (void *)((ulong)lpfc11_link_speed); + break; + case CFG_DQFULL_THROTTLE_UP_TIME: /* dqfull-throttle-up-time */ + value = (void *)((ulong)lpfc_dqfull_throttle_up_time); + if(lpfc11_dqfull_throttle_up_time != -1) + value = (void *)((ulong)lpfc11_dqfull_throttle_up_time); + break; + case CFG_DQFULL_THROTTLE_UP_INC: /* dqfull-throttle-up-inc */ + value = (void *)((ulong)lpfc_dqfull_throttle_up_inc); + if(lpfc11_dqfull_throttle_up_inc != -1) + value = (void *)((ulong)lpfc11_dqfull_throttle_up_inc); + break; + } + break; + case 12: /* HBA 12 */ + switch(param) { + case CFG_LOG_VERBOSE: /* log-verbose */ + value = (void *)((ulong)lpfc_log_verbose); + if(lpfc12_log_verbose != -1) + value = (void *)((ulong)lpfc12_log_verbose); + break; + case CFG_LOG_ONLY: /* log-only */ + value = (void *)((ulong)lpfc_log_only); + if(lpfc12_log_only != -1) + value = (void *)((ulong)lpfc12_log_only); + break; + case CFG_NUM_IOCBS: /* num-iocbs */ + value = (void *)((ulong)lpfc_num_iocbs); + if(lpfc12_num_iocbs != -1) + value = (void *)((ulong)lpfc12_num_iocbs); + break; + case CFG_NUM_BUFS: /* num-bufs */ + value = (void *)((ulong)lpfc_num_bufs); + if(lpfc12_num_bufs != -1) + value = (void *)((ulong)lpfc12_num_bufs); + break; + case CFG_AUTOMAP: /* automap */ + value = (void *)((ulong)lpfc_automap); + if(lpfc12_automap != -1) + value = (void *)((ulong)lpfc12_automap); + break; + case CFG_CR_DELAY: /* cr_delay */ + value = (void *)((ulong)lpfc_cr_delay); + if(lpfc12_cr_delay != -1) + value = (void *)((ulong)lpfc12_cr_delay); + break; + case CFG_CR_COUNT: /* cr_count */ + value = (void *)((ulong)lpfc_cr_count); + if(lpfc12_cr_count != -1) + value = (void *)((ulong)lpfc12_cr_count); + break; + case CFG_DFT_TGT_Q_DEPTH: /* tgt_queue_depth */ + value = (void *)((ulong)lpfc_tgt_queue_depth); + if(lpfc12_tgt_queue_depth != -1) + value = (void *)((ulong)lpfc12_tgt_queue_depth); + break; + case CFG_DFT_LUN_Q_DEPTH: /* lun_queue_depth */ + value = (void *)((ulong)lpfc_lun_queue_depth); + if(lpfc12_lun_queue_depth != -1) + value = (void *)((ulong)lpfc12_lun_queue_depth); + break; + case CFG_FCPFABRIC_TMO: /* fcpfabric-tmo */ + value = (void *)((ulong)lpfc_fcpfabric_tmo); + if(lpfc12_fcpfabric_tmo != -1) + value = (void *)((ulong)lpfc12_fcpfabric_tmo); + break; + case CFG_FCP_CLASS: /* fcp-class */ + value = (void *)((ulong)lpfc_fcp_class); + if(lpfc12_fcp_class != -1) + value = (void *)((ulong)lpfc12_fcp_class); + break; + case CFG_USE_ADISC: /* use-adisc */ + value = (void *)((ulong)lpfc_use_adisc); + if(lpfc12_use_adisc != -1) + value = (void *)((ulong)lpfc12_use_adisc); + break; + case CFG_NO_DEVICE_DELAY: /* no-device-delay */ + value = (void *)((ulong)lpfc_no_device_delay); + if(lpfc12_no_device_delay != -1) + value = (void *)((ulong)lpfc12_no_device_delay); + break; + case CFG_NETWORK_ON: /* network-on */ + value = (void *)((ulong)lpfc_network_on); + if(lpfc12_network_on != -1) + value = (void *)((ulong)lpfc12_network_on); + break; + case CFG_POST_IP_BUF: /* post-ip-buf */ + value = (void *)((ulong)lpfc_post_ip_buf); + if(lpfc12_post_ip_buf != -1) + value = (void *)((ulong)lpfc12_post_ip_buf); + break; + case CFG_XMT_Q_SIZE: /* xmt-que-size */ + value = (void *)((ulong)lpfc_xmt_que_size); + if(lpfc12_xmt_que_size != -1) + value = (void *)((ulong)lpfc12_xmt_que_size); + break; + case CFG_IP_CLASS: /* ip-class */ + value = (void *)((ulong)lpfc_ip_class); + if(lpfc12_ip_class != -1) + value = (void *)((ulong)lpfc12_ip_class); + break; + case CFG_ACK0: /* ack0 */ + value = (void *)((ulong)lpfc_ack0support); + if(lpfc12_ack0support != -1) + value = (void *)((ulong)lpfc12_ack0support); + break; + case CFG_TOPOLOGY: /* topology */ + value = (void *)((ulong)lpfc_topology); + if(lpfc12_topology != -1) + value = (void *)((ulong)lpfc12_topology); + break; + case CFG_SCAN_DOWN: /* scan-down */ + value = (void *)((ulong)lpfc_scandown); + if(lpfc12_scandown != -1) + value = (void *)((ulong)lpfc12_scandown); + break; + case CFG_LINKDOWN_TMO: /* linkdown-tmo */ + value = (void *)((ulong)lpfc_linkdown_tmo); + if(lpfc12_linkdown_tmo != -1) + value = (void *)((ulong)lpfc12_linkdown_tmo); + break; + case CFG_HOLDIO: /* nodev-holdio */ + value = (void *)((ulong)lpfc_nodev_holdio); + if(lpfc12_nodev_holdio != -1) + value = (void *)((ulong)lpfc12_nodev_holdio); + break; + case CFG_DELAY_RSP_ERR: /* delay-rsp-err */ + value = (void *)((ulong)lpfc_delay_rsp_err); + if(lpfc12_delay_rsp_err != -1) + value = (void *)((ulong)lpfc12_delay_rsp_err); + break; + case CFG_CHK_COND_ERR: /* check-cond-err */ + value = (void *)((ulong)lpfc_check_cond_err); + if(lpfc12_check_cond_err != -1) + value = (void *)((ulong)lpfc12_check_cond_err); + break; + case CFG_NODEV_TMO: /* nodev-tmo */ + value = (void *)((ulong)lpfc_nodev_tmo); + if(lpfc12_nodev_tmo != -1) + value = (void *)((ulong)lpfc12_nodev_tmo); + break; + case CFG_LINK_SPEED: /* link-speed */ + value = (void *)((ulong)lpfc_link_speed); + if(lpfc12_link_speed != -1) + value = (void *)((ulong)lpfc12_link_speed); + break; + case CFG_DQFULL_THROTTLE_UP_TIME: /* dqfull-throttle-up-time */ + value = (void *)((ulong)lpfc_dqfull_throttle_up_time); + if(lpfc12_dqfull_throttle_up_time != -1) + value = (void *)((ulong)lpfc12_dqfull_throttle_up_time); + break; + case CFG_DQFULL_THROTTLE_UP_INC: /* dqfull-throttle-up-inc */ + value = (void *)((ulong)lpfc_dqfull_throttle_up_inc); + if(lpfc12_dqfull_throttle_up_inc != -1) + value = (void *)((ulong)lpfc12_dqfull_throttle_up_inc); + break; + } + break; + case 13: /* HBA 13 */ + switch(param) { + case CFG_LOG_VERBOSE: /* log-verbose */ + value = (void *)((ulong)lpfc_log_verbose); + if(lpfc13_log_verbose != -1) + value = (void *)((ulong)lpfc13_log_verbose); + break; + case CFG_LOG_ONLY: /* log-only */ + value = (void *)((ulong)lpfc_log_only); + if(lpfc13_log_only != -1) + value = (void *)((ulong)lpfc13_log_only); + break; + case CFG_NUM_IOCBS: /* num-iocbs */ + value = (void *)((ulong)lpfc_num_iocbs); + if(lpfc13_num_iocbs != -1) + value = (void *)((ulong)lpfc13_num_iocbs); + break; + case CFG_NUM_BUFS: /* num-bufs */ + value = (void *)((ulong)lpfc_num_bufs); + if(lpfc13_num_bufs != -1) + value = (void *)((ulong)lpfc13_num_bufs); + break; + case CFG_AUTOMAP: /* automap */ + value = (void *)((ulong)lpfc_automap); + if(lpfc13_automap != -1) + value = (void *)((ulong)lpfc13_automap); + break; + case CFG_CR_DELAY: /* cr_delay */ + value = (void *)((ulong)lpfc_cr_delay); + if(lpfc13_cr_delay != -1) + value = (void *)((ulong)lpfc13_cr_delay); + break; + case CFG_CR_COUNT: /* cr_count */ + value = (void *)((ulong)lpfc_cr_count); + if(lpfc13_cr_count != -1) + value = (void *)((ulong)lpfc13_cr_count); + break; + case CFG_DFT_TGT_Q_DEPTH: /* tgt_queue_depth */ + value = (void *)((ulong)lpfc_tgt_queue_depth); + if(lpfc13_tgt_queue_depth != -1) + value = (void *)((ulong)lpfc13_tgt_queue_depth); + break; + case CFG_DFT_LUN_Q_DEPTH: /* lun_queue_depth */ + value = (void *)((ulong)lpfc_lun_queue_depth); + if(lpfc13_lun_queue_depth != -1) + value = (void *)((ulong)lpfc13_lun_queue_depth); + break; + case CFG_FCPFABRIC_TMO: /* fcpfabric-tmo */ + value = (void *)((ulong)lpfc_fcpfabric_tmo); + if(lpfc13_fcpfabric_tmo != -1) + value = (void *)((ulong)lpfc13_fcpfabric_tmo); + break; + case CFG_FCP_CLASS: /* fcp-class */ + value = (void *)((ulong)lpfc_fcp_class); + if(lpfc13_fcp_class != -1) + value = (void *)((ulong)lpfc13_fcp_class); + break; + case CFG_USE_ADISC: /* use-adisc */ + value = (void *)((ulong)lpfc_use_adisc); + if(lpfc13_use_adisc != -1) + value = (void *)((ulong)lpfc13_use_adisc); + break; + case CFG_NO_DEVICE_DELAY: /* no-device-delay */ + value = (void *)((ulong)lpfc_no_device_delay); + if(lpfc13_no_device_delay != -1) + value = (void *)((ulong)lpfc13_no_device_delay); + break; + case CFG_NETWORK_ON: /* network-on */ + value = (void *)((ulong)lpfc_network_on); + if(lpfc13_network_on != -1) + value = (void *)((ulong)lpfc13_network_on); + break; + case CFG_POST_IP_BUF: /* post-ip-buf */ + value = (void *)((ulong)lpfc_post_ip_buf); + if(lpfc13_post_ip_buf != -1) + value = (void *)((ulong)lpfc13_post_ip_buf); + break; + case CFG_XMT_Q_SIZE: /* xmt-que-size */ + value = (void *)((ulong)lpfc_xmt_que_size); + if(lpfc13_xmt_que_size != -1) + value = (void *)((ulong)lpfc13_xmt_que_size); + break; + case CFG_IP_CLASS: /* ip-class */ + value = (void *)((ulong)lpfc_ip_class); + if(lpfc13_ip_class != -1) + value = (void *)((ulong)lpfc13_ip_class); + break; + case CFG_ACK0: /* ack0 */ + value = (void *)((ulong)lpfc_ack0support); + if(lpfc13_ack0support != -1) + value = (void *)((ulong)lpfc13_ack0support); + break; + case CFG_TOPOLOGY: /* topology */ + value = (void *)((ulong)lpfc_topology); + if(lpfc13_topology != -1) + value = (void *)((ulong)lpfc13_topology); + break; + case CFG_SCAN_DOWN: /* scan-down */ + value = (void *)((ulong)lpfc_scandown); + if(lpfc13_scandown != -1) + value = (void *)((ulong)lpfc13_scandown); + break; + case CFG_LINKDOWN_TMO: /* linkdown-tmo */ + value = (void *)((ulong)lpfc_linkdown_tmo); + if(lpfc13_linkdown_tmo != -1) + value = (void *)((ulong)lpfc13_linkdown_tmo); + break; + case CFG_HOLDIO: /* nodev-holdio */ + value = (void *)((ulong)lpfc_nodev_holdio); + if(lpfc13_nodev_holdio != -1) + value = (void *)((ulong)lpfc13_nodev_holdio); + break; + case CFG_DELAY_RSP_ERR: /* delay-rsp-err */ + value = (void *)((ulong)lpfc_delay_rsp_err); + if(lpfc13_delay_rsp_err != -1) + value = (void *)((ulong)lpfc13_delay_rsp_err); + break; + case CFG_CHK_COND_ERR: /* check-cond-err */ + value = (void *)((ulong)lpfc_check_cond_err); + if(lpfc13_check_cond_err != -1) + value = (void *)((ulong)lpfc13_check_cond_err); + break; + case CFG_NODEV_TMO: /* nodev-tmo */ + value = (void *)((ulong)lpfc_nodev_tmo); + if(lpfc13_nodev_tmo != -1) + value = (void *)((ulong)lpfc13_nodev_tmo); + break; + case CFG_LINK_SPEED: /* link-speed */ + value = (void *)((ulong)lpfc_link_speed); + if(lpfc13_link_speed != -1) + value = (void *)((ulong)lpfc13_link_speed); + break; + case CFG_DQFULL_THROTTLE_UP_TIME: /* dqfull-throttle-up-time */ + value = (void *)((ulong)lpfc_dqfull_throttle_up_time); + if(lpfc13_dqfull_throttle_up_time != -1) + value = (void *)((ulong)lpfc13_dqfull_throttle_up_time); + break; + case CFG_DQFULL_THROTTLE_UP_INC: /* dqfull-throttle-up-inc */ + value = (void *)((ulong)lpfc_dqfull_throttle_up_inc); + if(lpfc13_dqfull_throttle_up_inc != -1) + value = (void *)((ulong)lpfc13_dqfull_throttle_up_inc); + break; + } + break; + case 14: /* HBA 14 */ + switch(param) { + case CFG_LOG_VERBOSE: /* log-verbose */ + value = (void *)((ulong)lpfc_log_verbose); + if(lpfc14_log_verbose != -1) + value = (void *)((ulong)lpfc14_log_verbose); + break; + case CFG_LOG_ONLY: /* log-only */ + value = (void *)((ulong)lpfc_log_only); + if(lpfc14_log_only != -1) + value = (void *)((ulong)lpfc14_log_only); + break; + case CFG_NUM_IOCBS: /* num-iocbs */ + value = (void *)((ulong)lpfc_num_iocbs); + if(lpfc14_num_iocbs != -1) + value = (void *)((ulong)lpfc14_num_iocbs); + break; + case CFG_NUM_BUFS: /* num-bufs */ + value = (void *)((ulong)lpfc_num_bufs); + if(lpfc14_num_bufs != -1) + value = (void *)((ulong)lpfc14_num_bufs); + break; + case CFG_AUTOMAP: /* automap */ + value = (void *)((ulong)lpfc_automap); + if(lpfc14_automap != -1) + value = (void *)((ulong)lpfc14_automap); + break; + case CFG_CR_DELAY: /* cr_delay */ + value = (void *)((ulong)lpfc_cr_delay); + if(lpfc14_cr_delay != -1) + value = (void *)((ulong)lpfc14_cr_delay); + break; + case CFG_CR_COUNT: /* cr_count */ + value = (void *)((ulong)lpfc_cr_count); + if(lpfc14_cr_count != -1) + value = (void *)((ulong)lpfc14_cr_count); + break; + case CFG_DFT_TGT_Q_DEPTH: /* tgt_queue_depth */ + value = (void *)((ulong)lpfc_tgt_queue_depth); + if(lpfc14_tgt_queue_depth != -1) + value = (void *)((ulong)lpfc14_tgt_queue_depth); + break; + case CFG_DFT_LUN_Q_DEPTH: /* lun_queue_depth */ + value = (void *)((ulong)lpfc_lun_queue_depth); + if(lpfc14_lun_queue_depth != -1) + value = (void *)((ulong)lpfc14_lun_queue_depth); + break; + case CFG_FCPFABRIC_TMO: /* fcpfabric-tmo */ + value = (void *)((ulong)lpfc_fcpfabric_tmo); + if(lpfc14_fcpfabric_tmo != -1) + value = (void *)((ulong)lpfc14_fcpfabric_tmo); + break; + case CFG_FCP_CLASS: /* fcp-class */ + value = (void *)((ulong)lpfc_fcp_class); + if(lpfc14_fcp_class != -1) + value = (void *)((ulong)lpfc14_fcp_class); + break; + case CFG_USE_ADISC: /* use-adisc */ + value = (void *)((ulong)lpfc_use_adisc); + if(lpfc14_use_adisc != -1) + value = (void *)((ulong)lpfc14_use_adisc); + break; + case CFG_NO_DEVICE_DELAY: /* no-device-delay */ + value = (void *)((ulong)lpfc_no_device_delay); + if(lpfc14_no_device_delay != -1) + value = (void *)((ulong)lpfc14_no_device_delay); + break; + case CFG_NETWORK_ON: /* network-on */ + value = (void *)((ulong)lpfc_network_on); + if(lpfc14_network_on != -1) + value = (void *)((ulong)lpfc14_network_on); + break; + case CFG_POST_IP_BUF: /* post-ip-buf */ + value = (void *)((ulong)lpfc_post_ip_buf); + if(lpfc14_post_ip_buf != -1) + value = (void *)((ulong)lpfc14_post_ip_buf); + break; + case CFG_XMT_Q_SIZE: /* xmt-que-size */ + value = (void *)((ulong)lpfc_xmt_que_size); + if(lpfc14_xmt_que_size != -1) + value = (void *)((ulong)lpfc14_xmt_que_size); + break; + case CFG_IP_CLASS: /* ip-class */ + value = (void *)((ulong)lpfc_ip_class); + if(lpfc14_ip_class != -1) + value = (void *)((ulong)lpfc14_ip_class); + break; + case CFG_ACK0: /* ack0 */ + value = (void *)((ulong)lpfc_ack0support); + if(lpfc14_ack0support != -1) + value = (void *)((ulong)lpfc14_ack0support); + break; + case CFG_TOPOLOGY: /* topology */ + value = (void *)((ulong)lpfc_topology); + if(lpfc14_topology != -1) + value = (void *)((ulong)lpfc14_topology); + break; + case CFG_SCAN_DOWN: /* scan-down */ + value = (void *)((ulong)lpfc_scandown); + if(lpfc14_scandown != -1) + value = (void *)((ulong)lpfc14_scandown); + break; + case CFG_LINKDOWN_TMO: /* linkdown-tmo */ + value = (void *)((ulong)lpfc_linkdown_tmo); + if(lpfc14_linkdown_tmo != -1) + value = (void *)((ulong)lpfc14_linkdown_tmo); + break; + case CFG_HOLDIO: /* nodev-holdio */ + value = (void *)((ulong)lpfc_nodev_holdio); + if(lpfc14_nodev_holdio != -1) + value = (void *)((ulong)lpfc14_nodev_holdio); + break; + case CFG_DELAY_RSP_ERR: /* delay-rsp-err */ + value = (void *)((ulong)lpfc_delay_rsp_err); + if(lpfc14_delay_rsp_err != -1) + value = (void *)((ulong)lpfc14_delay_rsp_err); + break; + case CFG_CHK_COND_ERR: /* check-cond-err */ + value = (void *)((ulong)lpfc_check_cond_err); + if(lpfc14_check_cond_err != -1) + value = (void *)((ulong)lpfc14_check_cond_err); + break; + case CFG_NODEV_TMO: /* nodev-tmo */ + value = (void *)((ulong)lpfc_nodev_tmo); + if(lpfc14_nodev_tmo != -1) + value = (void *)((ulong)lpfc14_nodev_tmo); + break; + case CFG_LINK_SPEED: /* link-speed */ + value = (void *)((ulong)lpfc_link_speed); + if(lpfc14_link_speed != -1) + value = (void *)((ulong)lpfc14_link_speed); + break; + case CFG_DQFULL_THROTTLE_UP_TIME: /* dqfull-throttle-up-time */ + value = (void *)((ulong)lpfc_dqfull_throttle_up_time); + if(lpfc14_dqfull_throttle_up_time != -1) + value = (void *)((ulong)lpfc14_dqfull_throttle_up_time); + break; + case CFG_DQFULL_THROTTLE_UP_INC: /* dqfull-throttle-up-inc */ + value = (void *)((ulong)lpfc_dqfull_throttle_up_inc); + if(lpfc14_dqfull_throttle_up_inc != -1) + value = (void *)((ulong)lpfc14_dqfull_throttle_up_inc); + break; + } + break; + case 15: /* HBA 15 */ + switch(param) { + case CFG_LOG_VERBOSE: /* log-verbose */ + value = (void *)((ulong)lpfc_log_verbose); + if(lpfc15_log_verbose != -1) + value = (void *)((ulong)lpfc15_log_verbose); + break; + case CFG_LOG_ONLY: /* log-only */ + value = (void *)((ulong)lpfc_log_only); + if(lpfc15_log_only != -1) + value = (void *)((ulong)lpfc15_log_only); + break; + case CFG_NUM_IOCBS: /* num-iocbs */ + value = (void *)((ulong)lpfc_num_iocbs); + if(lpfc15_num_iocbs != -1) + value = (void *)((ulong)lpfc15_num_iocbs); + break; + case CFG_NUM_BUFS: /* num-bufs */ + value = (void *)((ulong)lpfc_num_bufs); + if(lpfc15_num_bufs != -1) + value = (void *)((ulong)lpfc15_num_bufs); + break; + case CFG_AUTOMAP: /* automap */ + value = (void *)((ulong)lpfc_automap); + if(lpfc15_automap != -1) + value = (void *)((ulong)lpfc15_automap); + break; + case CFG_CR_DELAY: /* cr_delay */ + value = (void *)((ulong)lpfc_cr_delay); + if(lpfc15_cr_delay != -1) + value = (void *)((ulong)lpfc15_cr_delay); + break; + case CFG_CR_COUNT: /* cr_count */ + value = (void *)((ulong)lpfc_cr_count); + if(lpfc15_cr_count != -1) + value = (void *)((ulong)lpfc15_cr_count); + break; + case CFG_DFT_TGT_Q_DEPTH: /* tgt_queue_depth */ + value = (void *)((ulong)lpfc_tgt_queue_depth); + if(lpfc15_tgt_queue_depth != -1) + value = (void *)((ulong)lpfc15_tgt_queue_depth); + break; + case CFG_DFT_LUN_Q_DEPTH: /* lun_queue_depth */ + value = (void *)((ulong)lpfc_lun_queue_depth); + if(lpfc15_lun_queue_depth != -1) + value = (void *)((ulong)lpfc15_lun_queue_depth); + break; + case CFG_FCPFABRIC_TMO: /* fcpfabric-tmo */ + value = (void *)((ulong)lpfc_fcpfabric_tmo); + if(lpfc15_fcpfabric_tmo != -1) + value = (void *)((ulong)lpfc15_fcpfabric_tmo); + break; + case CFG_FCP_CLASS: /* fcp-class */ + value = (void *)((ulong)lpfc_fcp_class); + if(lpfc15_fcp_class != -1) + value = (void *)((ulong)lpfc15_fcp_class); + break; + case CFG_USE_ADISC: /* use-adisc */ + value = (void *)((ulong)lpfc_use_adisc); + if(lpfc15_use_adisc != -1) + value = (void *)((ulong)lpfc15_use_adisc); + break; + case CFG_NO_DEVICE_DELAY: /* no-device-delay */ + value = (void *)((ulong)lpfc_no_device_delay); + if(lpfc15_no_device_delay != -1) + value = (void *)((ulong)lpfc15_no_device_delay); + break; + case CFG_NETWORK_ON: /* network-on */ + value = (void *)((ulong)lpfc_network_on); + if(lpfc15_network_on != -1) + value = (void *)((ulong)lpfc15_network_on); + break; + case CFG_POST_IP_BUF: /* post-ip-buf */ + value = (void *)((ulong)lpfc_post_ip_buf); + if(lpfc15_post_ip_buf != -1) + value = (void *)((ulong)lpfc15_post_ip_buf); + break; + case CFG_XMT_Q_SIZE: /* xmt-que-size */ + value = (void *)((ulong)lpfc_xmt_que_size); + if(lpfc15_xmt_que_size != -1) + value = (void *)((ulong)lpfc15_xmt_que_size); + break; + case CFG_IP_CLASS: /* ip-class */ + value = (void *)((ulong)lpfc_ip_class); + if(lpfc15_ip_class != -1) + value = (void *)((ulong)lpfc15_ip_class); + break; + case CFG_ACK0: /* ack0 */ + value = (void *)((ulong)lpfc_ack0support); + if(lpfc15_ack0support != -1) + value = (void *)((ulong)lpfc15_ack0support); + break; + case CFG_TOPOLOGY: /* topology */ + value = (void *)((ulong)lpfc_topology); + if(lpfc15_topology != -1) + value = (void *)((ulong)lpfc15_topology); + break; + case CFG_SCAN_DOWN: /* scan-down */ + value = (void *)((ulong)lpfc_scandown); + if(lpfc15_scandown != -1) + value = (void *)((ulong)lpfc15_scandown); + break; + case CFG_LINKDOWN_TMO: /* linkdown-tmo */ + value = (void *)((ulong)lpfc_linkdown_tmo); + if(lpfc15_linkdown_tmo != -1) + value = (void *)((ulong)lpfc15_linkdown_tmo); + break; + case CFG_HOLDIO: /* nodev-holdio */ + value = (void *)((ulong)lpfc_nodev_holdio); + if(lpfc15_nodev_holdio != -1) + value = (void *)((ulong)lpfc15_nodev_holdio); + break; + case CFG_DELAY_RSP_ERR: /* delay-rsp-err */ + value = (void *)((ulong)lpfc_delay_rsp_err); + if(lpfc15_delay_rsp_err != -1) + value = (void *)((ulong)lpfc15_delay_rsp_err); + break; + case CFG_CHK_COND_ERR: /* check-cond-err */ + value = (void *)((ulong)lpfc_check_cond_err); + if(lpfc15_check_cond_err != -1) + value = (void *)((ulong)lpfc15_check_cond_err); + break; + case CFG_NODEV_TMO: /* nodev-tmo */ + value = (void *)((ulong)lpfc_nodev_tmo); + if(lpfc15_nodev_tmo != -1) + value = (void *)((ulong)lpfc15_nodev_tmo); + break; + case CFG_LINK_SPEED: /* link-speed */ + value = (void *)((ulong)lpfc_link_speed); + if(lpfc15_link_speed != -1) + value = (void *)((ulong)lpfc15_link_speed); + break; + case CFG_DQFULL_THROTTLE_UP_TIME: /* dqfull-throttle-up-time */ + value = (void *)((ulong)lpfc_dqfull_throttle_up_time); + if(lpfc15_dqfull_throttle_up_time != -1) + value = (void *)((ulong)lpfc15_dqfull_throttle_up_time); + break; + case CFG_DQFULL_THROTTLE_UP_INC: /* dqfull-throttle-up-inc */ + value = (void *)((ulong)lpfc_dqfull_throttle_up_inc); + if(lpfc15_dqfull_throttle_up_inc != -1) + value = (void *)((ulong)lpfc15_dqfull_throttle_up_inc); + break; + } + break; + default: + break; + } + return(value); +} + + diff -purN -X /home/mbligh/.diff.exclude 350-autoswap/drivers/scsi/lpfc/lpfc.spec 370-emulex/drivers/scsi/lpfc/lpfc.spec --- 350-autoswap/drivers/scsi/lpfc/lpfc.spec 1969-12-31 16:00:00.000000000 -0800 +++ 370-emulex/drivers/scsi/lpfc/lpfc.spec 2004-02-28 11:20:05.000000000 -0800 @@ -0,0 +1,127 @@ +#******************************************************************* +# * This file is part of the Emulex Linux Device Driver for * +# * Enterprise Fibre Channel Host Bus Adapters. * +# * Refer to the README file included with this package for * +# * driver version and adapter support. * +# * Copyright (C) 2003 Emulex Corporation. * +# * www.emulex.com * +# * * +# * This program is free software; you can redistribute it and/or * +# * modify it under the terms of the GNU General Public License * +# * as published by the Free Software Foundation; either version 2 * +# * of the License, or (at your option) any later version. * +# * * +# * This program is distributed in the hope that it will be useful, * +# * but WITHOUT ANY WARRANTY; without even the implied warranty of * +# * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * +# * GNU General Public License for more details, a copy of which * +# * can be found in the file COPYING included with this package. * +# ******************************************************************* +%define rel 1 +%define ver LPFC_DRIVER_VERSION +%define tarName lpfcdriver.tar + +Summary: Emulex Driver Kit for Linux +Name: lpfcdriver +Version: %ver +Release: %rel +Copyright: Emulex Corp. +Group: System Environment/Kernel +Source: %tarName +URL: http://www.emulex.com +Vendor: Emulex Corp. +Packager: Regis.Goupil +BuildRoot: /tmp/lpfc-%{ver} +Requires: kernel >= 2.2.0 +Requires: rpm >= 3.0.4 + +%description +Emulex Open Source Fibre Channel driver for Linux version %ver + +%prep + +%build +rm -rf %{buildroot} +mkdir -p %{buildroot}/lpfc-%{ver} +cd lpfc-%{ver} +find . -print | cpio -pdumv %{buildroot}/ + +%install +cd %{buildroot}/lpfc-%{ver} +tar -xf /usr/src/redhat/SOURCES/lpfc-%{ver}/lpfcdriver.tar +if [ -e /usr/src/linux-2.4/drivers/scsi ]; then dirval="linux-2.4"; \ +else if [ -e /usr/src/linux/drivers/scsi ]; then dirval="linux"; \ +else echo "Cannot find the kernel sources directory"; exit 1; fi fi +if [ -e /usr/src/$dirval/drivers/scsi/lpfc/ ]; then \ +rm -fr /usr/src/$dirval/drivers/scsi/lpfc; +fi +mkdir -p /usr/src/$dirval/drivers/scsi/lpfc; +cp * /usr/src/$dirval/drivers/scsi/lpfc; + +# post install (on client machine) section +%post +if [ -e /usr/src/linux-2.4/drivers/scsi ]; then dirval="linux-2.4"; \ +else if [ -e /usr/src/linux/drivers/scsi ]; then dirval="linux"; \ +else echo "Cannot find the kernel sources directory"; exit 1; fi fi +rm -fr lpfc-%{ver}/lpfc; +rm -fr /usr/src/$dirval/drivers/scsi/lpfc; +mkdir /usr/src/$dirval/drivers/scsi/lpfc; +cp lpfc-%{ver}/* /usr/src/$dirval/drivers/scsi/lpfc; + +echo " " +echo "The Emulex Open Source Driver has been installed on your system." +echo "Source files have been installed under a temporary directory /lpfc-%{ver}" +echo "and under /usr/src/$dirval/drivers/scsi/lpfc." +echo "Please refer to the Emulex documentation for the next step." +echo " " + +%preun +if [ -e /usr/src/linux-2.4/drivers/scsi/lpfc ]; then dirval="linux-2.4"; \ +else if [ -e /usr/src/linux/drivers/scsi/lpfc ]; then dirval="linux"; fi fi +echo " " +echo "The lpfcdriver rpm is about to be removed from your system." +echo "All the source files under /usr/src/$dirval/drivers/scsi/lpfc" +echo "and /lpfc-%{ver} will be removed." +echo " " + +%postun +if [ -e /usr/src/linux-2.4/drivers/scsi/lpfc ]; then dirval="linux-2.4"; \ +else if [ -e /usr/src/linux/drivers/scsi/lpfc ]; then dirval="linux"; fi fi +rm -fr /usr/src/$dirval/drivers/scsi/lpfc; +echo " " +echo "The Emulex Open Source Driver has been removed from your system." +echo "Remove the appropriate entry in modules.conf if this file was modified." +echo " " +rm -fr lpfc-%{ver}; + +%files +/lpfc-%{ver}/COPYING +/lpfc-%{ver}/dfcdd.c +/lpfc-%{ver}/dfc.h +/lpfc-%{ver}/fcclockb.c +/lpfc-%{ver}/fc_crtn.h +/lpfc-%{ver}/fcdds.h +/lpfc-%{ver}/fcdiag.h +/lpfc-%{ver}/fcelsb.c +/lpfc-%{ver}/fc_ertn.h +/lpfc-%{ver}/fcfgparm.h +/lpfc-%{ver}/fc.h +/lpfc-%{ver}/fc_hw.h +/lpfc-%{ver}/fcLINUXfcp.c +/lpfc-%{ver}/fcLINUXlan.c +/lpfc-%{ver}/fcmboxb.c +/lpfc-%{ver}/fcmemb.c +/lpfc-%{ver}/fcmsgcom.c +/lpfc-%{ver}/fcmsg.h +/lpfc-%{ver}/fc_os.h +/lpfc-%{ver}/fcrpib.c +/lpfc-%{ver}/fcscsib.c +/lpfc-%{ver}/fcstratb.c +/lpfc-%{ver}/fcxmitb.c +/lpfc-%{ver}/hbaapi.h +/lpfc-%{ver}/lp6000.c +/lpfc-%{ver}/lpfc.conf.c +/lpfc-%{ver}/lpfc.conf.defs +/lpfc-%{ver}/Makefile +/lpfc-%{ver}/README +/lpfc-%{ver}/lpfc.spec