pax_global_header00006660000000000000000000000064146572242520014523gustar00rootroot0000000000000052 comment=8f86e0be53b273188bf2779d974fcf3f9c68b8f0 megactl-0.4.5/000077500000000000000000000000001465722425200131455ustar00rootroot00000000000000megactl-0.4.5/.github/000077500000000000000000000000001465722425200145055ustar00rootroot00000000000000megactl-0.4.5/.github/FUNDING.yml000066400000000000000000000000571465722425200163240ustar00rootroot00000000000000custom: [https://www.buymeacoffee.com/namiltd] megactl-0.4.5/.github/workflows/000077500000000000000000000000001465722425200165425ustar00rootroot00000000000000megactl-0.4.5/.github/workflows/codeql-analysis.yml000066400000000000000000000037171465722425200223650ustar00rootroot00000000000000name: "CodeQL" on: push: branches: [master] pull_request: # The branches below must be a subset of the branches above branches: [master] schedule: - cron: '0 20 * * 6' jobs: analyze: name: Analyze runs-on: ubuntu-latest strategy: fail-fast: false matrix: # Override automatic language detection by changing the below list # Supported options are ['csharp', 'cpp', 'go', 'java', 'javascript', 'python'] language: ['cpp'] # Learn more... # https://docs.github.com/en/github/finding-security-vulnerabilities-and-errors-in-your-code/configuring-code-scanning#overriding-automatic-language-detection steps: - name: Checkout repository uses: actions/checkout@v2 with: # We must fetch at least the immediate parents so that if this is # a pull request then we can checkout the head. fetch-depth: 2 # If this run was triggered by a pull request event, then checkout # the head of the pull request instead of the merge commit. - run: git checkout HEAD^2 if: ${{ github.event_name == 'pull_request' }} # Initializes the CodeQL tools for scanning. - name: Initialize CodeQL uses: github/codeql-action/init@v1 with: languages: ${{ matrix.language }} # Autobuild attempts to build any compiled languages (C/C++, C#, or Java). # If this step fails, then you should remove it and run the build manually (see below) - name: Autobuild uses: github/codeql-action/autobuild@v1 # â„šī¸ Command-line programs to run using the OS shell. # 📚 https://git.io/JvXDl # âœī¸ If the Autobuild fails above, remove it and uncomment the following three lines # and modify them (or add more) to build your code if your project # uses a compiled language #- run: | # make bootstrap # make release - name: Perform CodeQL Analysis uses: github/codeql-action/analyze@v1 megactl-0.4.5/.gitignore000066400000000000000000000000441465722425200151330ustar00rootroot00000000000000*.o /megatrace /megactl /megasasctl megactl-0.4.5/AUTHOR000066400000000000000000000003061465722425200140710ustar00rootroot00000000000000 Other than the included megaraid2 driver code from LSI (GPLv2), and the SCSI header files from Joerg Schilling (GPLv2), this software was written entirely by Jefferson Ogata . megactl-0.4.5/COPYING000066400000000000000000000435431465722425200142110ustar00rootroot00000000000000 Note: This program includes megaraid2 driver source code, which was copied from the kernel source of a Red Hat system, and header files from Joerg Schilling's cdrecord, also as distributed on Red Hat, and also under GPL. ---------------------------------------- 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. megactl-0.4.5/Makefile000066400000000000000000000032421465722425200146060ustar00rootroot00000000000000DESTDIR:= PREFIX:= /usr BINDIR:= $(PREFIX)/bin METAINFODIR:= $(PREFIX)/share/metainfo/ INSTALL= install SRCS= megactl.c adapter.c megaioctl.c megatrace.c callinfo.c dumpbytes.c logpage.c ntrim.c INC= -I./schily -Iincludes-hack HDRS= mega.h adapter.h megaioctl.h callinfo.h logpage.h dumpbytes.h CPPFLAGS+= CFLAGS+= -g -Wall $(INC) $(ARCH) $(CPPFLAGS) LDFLAGS+= -g $(ARCH) PROGRAMS= megactl megasasctl all: $(PROGRAMS) megatrace: megatrace.o callinfo.o dumpbytes.o $(CC) $(LDFLAGS) -o $@ megatrace.o callinfo.o dumpbytes.o megactl: megactl.o adapter.o dumpbytes.o megaioctl.o logpage.o ntrim.o $(CC) $(LDFLAGS) -o $@ megactl.o adapter.o dumpbytes.o megaioctl.o logpage.o ntrim.o megasasctl: megasasctl.o adapter.o dumpbytes.o megaioctl.o logpage.o ntrim.o $(CC) $(LDFLAGS) -o $@ megasasctl.o adapter.o dumpbytes.o megaioctl.o logpage.o ntrim.o megasasctl.o: megactl.c $(CC) $(CFLAGS) -c -o $@ -DMEGA_SAS_CTL megactl.c %.o: Makefile.bak %.c $(CC) $(CFLAGS) -c -o $@ $*.c install: $(PROGRAMS) $(INSTALL) -d $(DESTDIR)$(BINDIR)/ $(INSTALL) $(PROGRAMS) $(DESTDIR)$(BINDIR) $(INSTALL) -d $(DESTDIR)$(METAINFODIR)/ $(INSTALL) -m644 megactl.metainfo.xml $(DESTDIR)$(METAINFODIR)/ clean: $(RM) $(PROGRAMS) *.o depend: makedepend -- $(CFLAGS) -- $(SRCS) megactl.o: mega.h adapter.h megaioctl.h logpage.h dumpbytes.h megasasctl.o: mega.h adapter.h megaioctl.h logpage.h dumpbytes.h adapter.o: mega.h megaioctl.h logpage.h ntrim.h megaioctl.o: mega.h megaioctl.h logpage.h megatrace.o: mega.h megaioctl.h logpage.h callinfo.h dumpbytes.h callinfo.o: callinfo.h logpage.o: mega.h megaioctl.h logpage.h ntrim.h dumpbytes.h ntrim.o: ntrim.h # DO NOT DELETE megactl-0.4.5/README000066400000000000000000000227651465722425200140410ustar00rootroot00000000000000LSI Megaraid Control and Monitoring Tools by Jefferson Ogata ------------------------------------------------------------ Disclaimer ---------- WARNING: Use this software at your own risk. The author accepts no responsibility for the consequences of your use of this software. WARNING: Use this software at your own risk. The author accepts no responsibility for the consequences of your use of this software. WARNING: Use this software at your own risk. The author accepts no responsibility for the consequences of your use of this software. These programs directly query megaraid adapters via the ioctl(2) driver interface and do a number of undocumented things. I and my colleagues use this software regularly and have had no problems, but your mileage may vary. If something goes terribly wrong and your RAID configs all get blown away, the author accepts no responsibility for the consequences. Please read this document carefully as it contains a warning or two. If you have built the programs but are having any issues running them, please see the Building, Device Nodes, and Limitations notes further down in this document. Introduction ------------ I've spent a fair amount of time working out the low-level interface to megaraid adapters. This stems from the fact that I use a lot of these beasts and have had failures at one time or another. The adapters are fast and extremely useful, but they aren't bulletproof. For example, disks showing a certain number of media errors are not failed immediately by the adapters; the adapters seem to want to pass some threshold of failure before they decide that a disk really needs to be dropped from a RAID, and by that time it's possible there could be consistency problems. I wrote these tools so I could more effectively monitor media errors (dellmgr makes this very tedious) and also take advantage of the device self-test functions provided with drives. Self-tests are in my opinion a suitable way to detect imminent drive failures without tying up the adapter and SCSI bandwidth doing patrol reads. It is also very useful to be able to conduct a self-test on a spare disk before using it for a rebuild. Another issue I've had with megaraids is keeping current documentation on RAID configuration. You may choose a completely logical RAID layout when first configuration a system, but that doesn't mean you'll remember it if you have to reconstruct it in an emergency--did I leave out a disk for a hot spare? Which one? Furthermore, as disks fail and hot spares are rotated in place, the configuration changes over time. If you don't update your documentation every time a disk fails, you lose track of it. While LSI's MegaCli program provides methods for dumping the configuration (although verbosely) and saving and restoring it from files, Dell's dellmgr doesn't give you any sensible way to track down what spans comprise a logical disk. I wrote these programs in part to solve this problem. Programs -------- This distribution contains three programs and a script: *megactl* megactl queries PERC2, PERC3, and PERC4 adapters and reports adapter configuration, physical and logical drive condition, drive log sense pages, and various other useful information. This allows you to document the actual configuration of the adapter, since, for one thing, Dell's dellmgr does not tell you which specific logical drive a given disk belongs to. megactl has several features to query SCSI drive log pages, where each drive controller saves accumulated error counts, drive temperature, self-test results, et al. To get a list of supported log pages for a given drive, use "megactl -vv -l 0 " where target is the name of the drive, e.g. a0c1t2 for SCSI target 2 on channel 1 of adapter 0. In addition "-s" is shorthand for "-l 0x10", "-t" is shorthand for "-l 0x0d", and "-e" is shorthand for "-l 0x02 -l 0x03 -l 0x05". megactl knows how to parse several useful log pages, but there are others where you'll have to interpret the results yourself. Feel free to write more parsing code. megactl output is governed by a verbosity flag. At lower verbosity levels, the program tends to minimize log page output unless it represents an actual problem. So to see the full self-test log, you need to add "-vv". I usually run the program with a single "-v". Self-test and most status operations allow you to designate either an entire adapter (a0), a specific channel (a0c1), or a specific drive (a0c1t2). When performing drive self-test operations (q.v.), be sure to specify the actual drive you wish to test, or you will end up starting a test on every drive on the system. You may designate as many objects as you please, e.g. "a0c0t{1,2,3,4,5,8} a0c1 a1". megactl provides a health-check function, which inspects health check operation allows only entire adapters to be designated. If no target is designated, the program operates on all possible objects. megactl with the -H option performs a health check of all (or specified) adapters. By default, the health check checks the state of the adapter battery, the state of all logical drives, and for each physical drive, the media error count logged by the adapter, the read, write,and verify error log pages, and the temperature log page. You can tune the log pages the health check will inspect by specifying them with "-e", "-s", "-t", or "-l"; note that if you do this, there is no default and you must specify every log page you wish to inspect ("-et" for the default behaviour). If a problem is found, the program prints the adapter and relevant drive info. If everything is okay, the program is completely silent. So "megactl -vH" can be a useful cron job. When using the health check you may specify which adapters you want to check, but you may not designate specific channels or drives. megactl also allows you to instruct the drive to perform a long ("-T long") or short ("-T short") background self-test procedure, which does not take the drive offline. I have performed self-tests on drives that are part of an operational RAID many times with no problems. I recommend that you self-test only one drive in a given span at a time; if the self-test causes the drive to log errors, the adapter may fail the drive, and you don't want that to happen to two drives in a span simultaneously or you may lose data. You can get full usage info for megactl by executing it with the -? flag. I use megactl on a number of PERC models, especially PERC3/QCs and PERC4/DCs. In the past, megactl was known to work well with PERC2/DC adapters but I no longer operate any systems with these adapters, so this may have broken. Please let me know if you have success or problems. megactl generally tries not to do anything harmful, so it's pretty safe. Primarily it queries disks; the only instructions it issues in its current form are to execute self-test operations. *megasasctl* The second program, megasasctl, is just like megactl, but intended for PERC5 adapters. The only syntactic difference is that instead of naming targets with channels and ids, they are named with enclosures and slots, e.g. a0, a1e0, a2e1s9. The SAS support is brand new, and I'm sure I've got some things wrong. I haven't been able to fully test SAS support yet because I don't have any bad SAS disks. *megatrace* megatrace is a debugging program which can be used to trace PERC-related ioctl() system calls that another program makes. You won't need that unless you're trying to add features to megactl, or are exceptionally curious. This program uses ptrace(2) and can inspect and modify data structures to help you suss out what's going on in dellmgr and MegaCli. *megarpt* megarpt is a script I run in a cron job each night. It performs a health check on all adapters, and emails any problems, along with the adapter configuration, to root. It is handy to have the adapter configuration logged in case you need to reconstruct adapter state in a catastrophic failure. There are various scenarios involving hot spares and multiple drive failures where the adapter configuration may not be quite what you thought it was. To use megarpt, copy megarpt and megactl into /root/ and add a cron entry for /root/megarpt. Or tweak as you see fit; there isn't much to it. megarpt needs to be tweaked for megasasctl applications; it currently works only with pre-SAS models. *megasasrpt* megasasrpt is just like megarpt, but for PERC5 adapters. Building -------- This software has been built successfully on RHEL 3, 4, and 5, and Debian Etch, using the default gcc compiler, and Red Hat Linux 7.3 or RHEL 2.1 should work as well. Simply run make in the src directory. Device Nodes ------------ megactl and megasasctl require the existence of an appropriate device node in order to communicate with adapters. For megactl, this device node should be /dev/megadev0, and is created automatically by Dell's dellmgr program. You may create it yourself by finding the major device number for megadev in /proc/devices and creating a character device with that major number and minor number 0. See the megarpt shell script if this is not clear. For megasasctl, the device node is /dev/megaraid_sas_ioctl_node, and is created automatically by LSI's MegaCli program. It should have the major number of megaraid_sas_ioctl from /proc/devices and minor number 0. See the megasasrpt shell script for an example of how to create this. Limitations ----------- Currently these programs only operate if built as 32-bit targets. On 64-bit architectures, you therefore will need 32-bit compatibility libraries. This should not require any special action on Red Hat, but on Debian you may need to install a few things. megactl-0.4.5/adapter.c000066400000000000000000000713561465722425200147450ustar00rootroot00000000000000/* * High-level interface to adapter information. * * Copyright (c) 2007 by Jefferson Ogata */ /* * 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, 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; see the file COPYING. If not, write to the Free Software * Foundation, 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. */ #include "megaioctl.h" #include "logpage.h" #include "ntrim.h" #include #include #include #include #include static void batteryStatus (struct adapter_config *a, uint8_t status) { a->battery.module_missing = (status & BATTERY_MODULE_MISSING) != 0; a->battery.pack_missing = (status & BATTERY_PACK_MISSING) != 0; a->battery.low_voltage = (status & BATTERY_LOW_VOLTAGE) != 0; a->battery.high_temperature = (status & BATTERY_TEMP_HIGH) != 0; a->battery.cycles_exceeded = (status & BATTERY_CYCLES_EXCEEDED) != 0; switch (status & BATTERY_CHARGE_MASK) { case BATTERY_CHARGE_FAIL: a->battery.charger_state = ChargerStateFailed; break; case BATTERY_CHARGE_DONE: a->battery.charger_state = ChargerStateComplete; break; case BATTERY_CHARGE_INPROG: a->battery.charger_state = ChargerStateInProgress; break; default: a->battery.charger_state = ChargerStateUnknown; break; } a->battery.voltage = -1; a->battery.temperature = -1; a->battery.healthy = !(a->battery.module_missing || a->battery.pack_missing || a->battery.low_voltage || a->battery.high_temperature || a->battery.cycles_exceeded || (a->battery.charger_state != ChargerStateComplete)); } static void batteryStatus5 (struct adapter_config *a) { struct mega_battery_state_sas *b = &a->q.v5.battery.state; a->battery.module_missing = !(a->q.v5.adapinfo.hw_present.bbu); a->battery.pack_missing = b->type == MEGA_BATTERY_TYPE_NONE; /*a->battery.low_voltage = b->remaining_capacity_alarm || b->remaining_time_alarm || b->fully_discharged;*/ a->battery.low_voltage = !b->fully_charged && (b->remaining_time_alarm || b->remaining_capacity_alarm || b->fully_discharged) ; a->battery.high_temperature = b->over_temperature != 0; a->battery.over_charged = b->over_charged != 0; switch (b->charger_status) { case 0: a->battery.charger_state = ChargerStateFailed; break; case 1: a->battery.charger_state = ChargerStateComplete; break; case 2: a->battery.charger_state = ChargerStateInProgress; break; default: a->battery.charger_state = ChargerStateUnknown; break; } a->battery.voltage = b->voltage; a->battery.temperature = b->temperature; a->battery.healthy = !(a->battery.module_missing || a->battery.pack_missing || a->battery.low_voltage || a->battery.high_temperature /*|| a->battery.cycles_exceeded */|| (a->battery.charger_state != ChargerStateComplete) || (!b->health)); } static struct log_page_list *getPage (struct physical_drive_info *d, uint8_t page) { struct log_page_list *p; if ((p = (struct log_page_list *) malloc (sizeof (*p))) == NULL) return NULL; memset (p, 0, sizeof (*p)); if (megaScsiLogSense (&d->adapter->target, d->target, &p->buf, sizeof (p->buf), 1, page, 0) < 0) { free (p); return NULL; } if (parseLogPage (&p->buf, sizeof (p->buf), &p->log) < 0) { free (p); return NULL; } return p; } struct log_page_list *getDriveLogPage (struct physical_drive_info *d, uint8_t page) { struct supportedLogsPage *supported = NULL; struct log_page_list *p; for (p = d->log; p; p = p->next) { if (p->log.h.page_code == page) return p; if (p->log.h.page_code == 0) supported = &p->log.u.supported; } if (supported == NULL) { if ((p = getPage (d, 0)) == NULL) return NULL; p->next = d->log; d->log = p; if (page == 0) return p; supported = &p->log.u.supported; } /* Is the requested page supported? */ if (supported->page[page] == 0) return NULL; if ((p = getPage (d, page)) == NULL) return NULL; p->next = d->log; d->log = p; return p; } static int cmpPhysical (const void *a, const void *b) { struct physical_drive_info *x = *((struct physical_drive_info **) a); struct physical_drive_info *y = *((struct physical_drive_info **) b); if (x->adapter->target.adapno != y->adapter->target.adapno) return (int) (x->adapter->target.adapno) - (int) (y->adapter->target.adapno); if (x->channel != y->channel) return (int) (x->channel) - (int) (y->channel); if (x->id != y->id) return (int) (x->id) - (int) (y->id); return 0; } struct physical_drive_info *getPhysicalDriveInfo (struct adapter_config *a, uint16_t target, int fetch) { int k; struct physical_drive_info *d; /* Look for it. */ for (k = 0, d = a->physical; k < a->num_physicals; ++k, ++d) { if (d->adapter == NULL) break; if (d->target == target) return d->present ? d : NULL; } /* Not there and no place for it. That's just wrong. */ if (k >= a->num_physicals) { fprintf (stderr, "me so crazy, me think adapter crazy too. sorry, mister.\n"); return NULL; } /* If we don't want to query it, we're done. */ if (!fetch) return NULL; d->adapter = a; d->target = target; if (a->is_sas) { struct mega_physical_disk_info_sas *info = &d->q.v5.info; if (megaSasGetDiskInfo (&a->target, target, info) < 0) { d->error_string = megaErrorString (); d->present = 0; return NULL; } d->channel = info->enclosure; d->id = info->slot; if (d->channel == DISK_NOENC) snprintf (d->name, sizeof (d->name), "%se*s%u", a->name, d->id); else snprintf (d->name, sizeof (d->name), "%se%us%u", a->name, d->channel, d->id); d->inquiry = info->inquiry.inq; strncpy (d->vendor, d->inquiry.vendor_info, sizeof (d->vendor) - 1); d->vendor[sizeof (d->vendor) - 1] = '\0'; ntrim (d->vendor); strncpy (d->model, d->inquiry.prod_ident, sizeof (d->model) - 1); d->model[sizeof (d->model) - 1] = '\0'; ntrim (d->model); strncpy (d->revision, d->inquiry.prod_revision, sizeof (d->revision) - 1); d->revision[sizeof (d->revision) - 1] = '\0'; ntrim (d->revision); if ((d->inquiry.qualifier == INQ_DEV_PRESENT) && (d->inquiry.type == INQ_DASD)) { d->present = 1; } else { d->present = 0; return NULL; } strncpy (d->serial, (char *) info->inquiry.buf + sizeof (info->inquiry.inq), sizeof (d->serial)); d->serial[sizeof (d->serial) - 1] = '\0'; ntrim (d->serial); if (info->configured) { if (info->online) d->state = PdStateOnline; else if (info->rebuild) d->state = PdStateRebuild; else if (info->failure) d->state = PdStateFailed; else d->state = PdStateUnknown; } else { if (info->hotspare) d->state = PdStateHotspare; else if (info->failure) d->state = PdStateUnconfiguredBad; else d->state = PdStateUnconfiguredGood; } d->blocks = info->raw_size; d->media_errors = info->media_errors; d->other_errors = info->other_errors; d->predictive_failures = info->predictive_failures; } else { int status; struct scsi_inquiry inq; uint8_t evpd[128]; struct mega_physical_drive_error_info errors; d->channel = (target >> 4) & 0xf; d->id = target & 0xf; snprintf (d->name, sizeof (d->name), "%sc%ut%u", a->name, d->channel, d->id); if (megaScsiDriveInquiry (&a->target, target, &inq, sizeof (inq), 0, 0) == 0) { d->inquiry = inq; strncpy (d->vendor, d->inquiry.vendor_info, sizeof (d->vendor) - 1); d->vendor[sizeof (d->vendor) - 1] = '\0'; ntrim (d->vendor); strncpy (d->model, d->inquiry.prod_ident, sizeof (d->model) - 1); d->model[sizeof (d->model) - 1] = '\0'; ntrim (d->model); strncpy (d->revision, d->inquiry.prod_revision, sizeof (d->revision) - 1); d->revision[sizeof (d->revision) - 1] = '\0'; ntrim (d->revision); if ((d->inquiry.qualifier == INQ_DEV_PRESENT) && (d->inquiry.type == INQ_DASD)) { d->present = 1; } else { d->present = 0; return NULL; } } else { d->error_string = megaErrorString (); d->present = 0; return NULL; } if (megaScsiDriveInquiry (&a->target, target, evpd, sizeof evpd, 0x80, 1) == 0) { uint8_t len = evpd[3]; if ((evpd[1] == 0x80) && (len + 4 <= sizeof evpd)) { if (len > sizeof (d->serial) - 1) len = sizeof (d->serial) - 1; strncpy (d->serial, (char *) evpd + 4, len); d->serial[len] = '\0'; ntrim (d->serial); } } if ((status = megaGetDriveErrorCount (&a->target, target, &errors)) == 0) { d->media_errors = errors.media; d->other_errors = errors.other; } else d->error_string = megaErrorString (); } /* Add it to the device list and sort it. */ for (k = 0; k < a->num_physicals; ++k) if (a->physical_list[k] == NULL) break; if (k >= a->num_physicals) { fprintf (stderr, "not ok at the ok corral. freak out, mama!\n"); return NULL; } a->physical_list[k++] = d; qsort (a->physical_list, k, sizeof (*a->physical_list), cmpPhysical); return d; } /* Adapter handling for PERC2. */ static char *getAdapterConfig2 (struct adapter_config *a) { int k; logdrv_8ld_span8_t *ml; int spanIndex; mraid_adapinfo1_t *pinfo = &a->q.v2.inquiry.adapter_info; mraid_inquiry1_t *inquiry = &a->q.v2.inquiry; disk_array_8ld_span8_t *config = &a->q.v2.config; a->target.type = MEGA_ADAPTER_V2; if (megaGetAdapterInquiry (&a->target, inquiry) < 0) return "cannot query adapter"; if (megaGetAdapterConfig8 (&a->target, config) < 0) return "cannot read adapter config"; if (megaGetPredictiveMap (&a->target, &a->q.v2.map) < 0) return "cannot read adapter predictive map"; a->rebuild_rate = pinfo->rebuild_rate; a->dram_size = pinfo->dram_size; snprintf (a->name, sizeof (a->name), "a%u", a->target.adapno); strcpy (a->product, "PERC2/"); switch (pinfo->nchannels) { case 1: strcat (a->product, "SC"); break; case 2: strcat (a->product, "DC"); break; case 4: strcat (a->product, "QC"); break; default: return "invalid number of channels"; } strncpy (a->bios, (char *) pinfo->bios_version, sizeof (a->bios)); a->bios[sizeof (a->bios) - 1] = '\0'; ntrim (a->bios); strncpy (a->firmware, (char *) pinfo->fw_version, sizeof (a->firmware)); a->firmware[sizeof (a->firmware) - 1] = '\0'; ntrim (a->firmware); batteryStatus (a, pinfo->battery_status); if (config->numldrv > sizeof (config->ldrv) / sizeof (config->ldrv[0])) return "invalid number of logical drives"; a->num_channels = pinfo->nchannels; if ((a->channel = (uint16_t *) malloc (a->num_channels * sizeof (*a->channel))) == NULL) return "out of memory (channels)"; for (k = 0; k < a->num_channels; ++k) a->channel[k] = k; a->num_physicals = FC_MAX_PHYSICAL_DEVICES; if ((a->physical = (struct physical_drive_info *) malloc (a->num_physicals * sizeof (*a->physical))) == NULL) return "out of memory (physical drives)"; memset (a->physical, 0, a->num_physicals * sizeof (*a->physical)); if ((a->physical_list = (struct physical_drive_info **) malloc (a->num_physicals * sizeof (*a->physical_list))) == NULL) return "out of memory (physical drives)"; memset (a->physical_list, 0, a->num_physicals * sizeof (*a->physical_list)); a->num_logicals = config->numldrv; if ((a->logical = (struct logical_drive_info *) malloc (a->num_logicals * sizeof (*a->logical))) == NULL) return "out of memory (logical drives)"; memset (a->logical, 0, a->num_logicals * sizeof (*a->logical)); /* Count how many spans there are. */ for (k = 0, ml = config->ldrv, a->num_spans = 0; k < config->numldrv; ++k, ++ml) a->num_spans += ml->lparam.span_depth; if ((a->span = (struct span_info *) malloc (a->num_spans * sizeof (*a->span))) == NULL) return "out of memory (spans)"; memset (a->span, 0, a->num_spans * sizeof (*a->span)); /* Copy drive states. */ for (k = 0; k < sizeof (inquiry->pdrv_info.pdrv_state) / sizeof (inquiry->pdrv_info.pdrv_state[0]); ++k) switch (inquiry->pdrv_info.pdrv_state[k] & 0xf) { case PDRV_UNCNF: a->physical[k].state = PdStateUnconfiguredGood; continue; case PDRV_ONLINE: a->physical[k].state = PdStateOnline; continue; case PDRV_FAILED: a->physical[k].state = PdStateFailed; continue; case PDRV_RBLD: a->physical[k].state = PdStateRebuild; continue; case PDRV_HOTSPARE: a->physical[k].state = PdStateHotspare; continue; default: a->physical[k].state = PdStateUnknown; continue; } /* Copy drive sizes. */ for (k = 0; k < sizeof (config->pdrv) / sizeof (config->pdrv[0]); ++k) a->physical[k].blocks = config->pdrv[k].size; /* Copy drive predictive failures flag */ for (k = 0; k < 8 * sizeof (a->q.v2.map.map) / sizeof (a->q.v2.map.map[0]); ++k) a->physical[k].predictive_failures = ((a->q.v2.map.map[k >> 3] & (1 << (k & 0x7))) != 0); /* Examine all the logical drives. */ for (k = 0, ml = config->ldrv, spanIndex = 0; k < config->numldrv; ++k, ++ml) { struct span_info *span; adap_span_8ld_t *mr; int j; struct logical_drive_info *l = &a->logical[k]; l->adapter = a; snprintf (l->name, sizeof (l->name), "a%ud%u", a->target.adapno, k); l->target = k; switch (ml->lparam.status) { case RDRV_OFFLINE: l->state = LdStateOffline; break; case RDRV_DEGRADED: l->state = LdStateDegraded; break; case RDRV_OPTIMAL: l->state = LdStateOptimal; break; case RDRV_DELETED: l->state = LdStateDeleted; break; default: l->state = LdStateUnknown; break; } l->raid_level = ml->lparam.level; l->span_size = ml->lparam.row_size; l->num_spans = ml->lparam.span_depth; if ((l->span = (struct span_reference *) malloc (l->num_spans * sizeof (*l->span))) == NULL) return "out of memory (span references)"; for (j = 0, mr = ml->span; j < ml->lparam.span_depth; ++j, ++mr) { int i; span = &a->span[spanIndex++]; span->adapter = a; span->num_logical_drives = 1; if ((span->logical_drive = (struct logical_drive_info **) malloc (span->num_logical_drives * sizeof (*span->logical_drive))) == NULL) return "out of memory (span -> ldrv pointers)"; span->logical_drive[0] = l; span->blocks_per_disk = mr->num_blks; span->num_disks = ml->lparam.row_size; if ((span->disk = (struct physical_drive_info **) malloc (span->num_disks * sizeof (*span->disk))) == NULL) return "out of memory (span -> disk pointers)"; /* Logical drives use the whole span. */ l->span[j].offset = 0; l->span[j].blocks_per_disk = span->blocks_per_disk; l->span[j].span = span; for (i = 0; i < span->num_disks; ++i) { span->disk[i] = &a->physical[mr->device[i].target]; span->disk[i]->span = span; } } } return NULL; } /* Adapter handling for PERC3 and PERC4 adapters. */ static char *getAdapterConfig3 (struct adapter_config *a) { int k; logdrv_40ld_t *ml; int spanIndex; mraid_pinfo_t *pinfo = &a->q.v3.adapinfo; mraid_inquiry3_t *enquiry3 = &a->q.v3.enquiry3; disk_array_40ld_t *config = &a->q.v3.config; a->target.type = MEGA_ADAPTER_V34; if (megaGetAdapterEnquiry3 (&a->target, &a->q.v3.enquiry3) < 0) return "cannot query adapter"; if (megaGetAdapterConfig40 (&a->target, config) < 0) return "cannot read adapter config"; if (megaGetPredictiveMap (&a->target, &a->q.v3.map) < 0) return "cannot read adapter predictive map"; a->rebuild_rate = enquiry3->rebuild_rate; a->dram_size = pinfo->dram_size; snprintf (a->name, sizeof (a->name), "a%u", a->target.adapno); switch (pinfo->nchannels) { case 1: break; case 2: break; case 4: break; default: return "invalid number of channels"; } strncpy (a->product, (char *) pinfo->product_name, sizeof (a->product)); a->product[sizeof (a->product) - 1] = '\0'; ntrim (a->product); strncpy (a->bios, (char *) pinfo->bios_version, sizeof (a->bios)); a->bios[sizeof (a->bios) - 1] = '\0'; ntrim (a->bios); strncpy (a->firmware, (char *) pinfo->fw_version, sizeof (a->firmware)); a->firmware[sizeof (a->firmware) - 1] = '\0'; ntrim (a->firmware); batteryStatus (a, enquiry3->battery_status); if (config->numldrv > sizeof (config->ldrv) / sizeof (config->ldrv[0])) return "invalid number of logical drives"; a->num_channels = pinfo->nchannels; if ((a->channel = (uint16_t *) malloc (a->num_channels * sizeof (*a->channel))) == NULL) return "out of memory (channels)"; for (k = 0; k < a->num_channels; ++k) a->channel[k] = k; a->num_physicals = FC_MAX_PHYSICAL_DEVICES; if ((a->physical = (struct physical_drive_info *) malloc (a->num_physicals * sizeof (*a->physical))) == NULL) return "out of memory (physical drives)"; memset (a->physical, 0, a->num_physicals * sizeof (*a->physical)); if ((a->physical_list = (struct physical_drive_info **) malloc (a->num_physicals * sizeof (*a->physical_list))) == NULL) return "out of memory (physical drives)"; memset (a->physical_list, 0, a->num_physicals * sizeof (*a->physical_list)); a->num_logicals = config->numldrv; if ((a->logical = (struct logical_drive_info *) malloc (a->num_logicals * sizeof (*a->logical))) == NULL) return "out of memory (logical drives)"; memset (a->logical, 0, a->num_logicals * sizeof (*a->logical)); /* Count how many spans there are. */ for (k = 0, ml = config->ldrv, a->num_spans = 0; k < config->numldrv; ++k, ++ml) a->num_spans += ml->lparam.span_depth; if ((a->span = (struct span_info *) malloc (a->num_spans * sizeof (*a->span))) == NULL) return "out of memory (spans)"; memset (a->span, 0, a->num_spans * sizeof (*a->span)); /* Copy drive states. */ for (k = 0; k < sizeof (enquiry3->pdrv_state) / sizeof (enquiry3->pdrv_state[0]); ++k) switch (enquiry3->pdrv_state[k] & 0xf) { case PDRV_UNCNF: a->physical[k].state = PdStateUnconfiguredGood; continue; case PDRV_ONLINE: a->physical[k].state = PdStateOnline; continue; case PDRV_FAILED: a->physical[k].state = PdStateFailed; continue; case PDRV_RBLD: a->physical[k].state = PdStateRebuild; continue; case PDRV_HOTSPARE: a->physical[k].state = PdStateHotspare; continue; default: a->physical[k].state = PdStateUnknown; continue; } /* Copy drive sizes. */ for (k = 0; k < sizeof (config->pdrv) / sizeof (config->pdrv[0]); ++k) a->physical[k].blocks = config->pdrv[k].size; /* Copy drive predictive failures flag */ for (k = 0; k < 8 * sizeof (a->q.v3.map.map) / sizeof (a->q.v3.map.map[0]); ++k) a->physical[k].predictive_failures = ((a->q.v3.map.map[k >> 3] & (1 << (k & 0x7))) != 0); /* Examine all the logical drives. */ for (k = 0, ml = config->ldrv, spanIndex = 0; k < config->numldrv; ++k, ++ml) { struct span_info *span; adap_span_40ld_t *mr; int j; struct logical_drive_info *l = &a->logical[k]; l->adapter = a; snprintf (l->name, sizeof (l->name), "a%ud%u", a->target.adapno, k); l->target = k; switch (ml->lparam.status) { case RDRV_OFFLINE: l->state = LdStateOffline; break; case RDRV_DEGRADED: l->state = LdStateDegraded; break; case RDRV_OPTIMAL: l->state = LdStateOptimal; break; case RDRV_DELETED: l->state = LdStateDeleted; break; default: l->state = LdStateUnknown; break; } l->raid_level = ml->lparam.level; l->span_size = ml->lparam.row_size; l->num_spans = ml->lparam.span_depth; if ((l->span = (struct span_reference *) malloc (l->num_spans * sizeof (*l->span))) == NULL) return "out of memory (span references)"; for (j = 0, mr = ml->span; j < ml->lparam.span_depth; ++j, ++mr) { int i; span = &a->span[spanIndex++]; span->adapter = a; span->num_logical_drives = 1; if ((span->logical_drive = (struct logical_drive_info **) malloc (span->num_logical_drives * sizeof (*span->logical_drive))) == NULL) return "out of memory (span -> ldrv pointers)"; span->logical_drive[0] = l; span->blocks_per_disk = mr->num_blks; span->num_disks = ml->lparam.row_size; if ((span->disk = (struct physical_drive_info **) malloc (span->num_disks * sizeof (*span->disk))) == NULL) return "out of memory (span -> disk pointers)"; /* Logical drives use the whole span. */ l->span[j].offset = 0; l->span[j].blocks_per_disk = span->blocks_per_disk; l->span[j].span = span; for (i = 0; i < span->num_disks; ++i) { span->disk[i] = &a->physical[mr->device[i].target]; span->disk[i]->span = span; } } } #if 0 /* Go ahead and hit all the other devices that have a non-zero scsi transfer rate. */ for (k = 0; k < sizeof (a->q.v3.enquiry3.targ_xfer) / sizeof (a->q.v3.enquiry3.targ_xfer[0]); ++k) if (a->q.v3.enquiry3.targ_xfer[k]) (void) getPhysicalDriveInfo (a, (uint8_t) k, 1); #endif return NULL; } static int cmpChannel (const void *a, const void *b) { int x = (int) *((uint8_t *) a); int y = (int) *((uint8_t *) b); return x - y; } /* Adapter handling for PERC5 adapters. */ static char *getAdapterConfig5 (struct adapter_config *a) { int k; struct mega_array_span_def_sas *ms; struct mega_array_disk_def_sas *ml; struct megasas_ctrl_info *pinfo = &a->q.v5.adapinfo; struct mega_device_list_sas *device; struct mega_array_config_sas *config = &a->q.v5.config; a->target.type = MEGA_ADAPTER_V5; if (megaSasGetDeviceList (&a->target, &(a->q.v5.device)) < 0) return "cannot retrieve device list"; device = a->q.v5.device; if (megaSasGetArrayConfig (&a->target, &(a->q.v5.config)) < 0) return "cannot retrieve array configuration"; if (megaSasGetBatteryInfo (&a->target, &(a->q.v5.battery)) < 0) return "cannot retrieve battery info"; a->rebuild_rate = pinfo->properties.rebuild_rate; a->dram_size = pinfo->memory_size; snprintf (a->name, sizeof (a->name), "a%u", a->target.adapno); strncpy (a->product, (char *) pinfo->product_name, sizeof (a->product)); a->product[sizeof (a->product) - 1] = '\0'; ntrim (a->product); for (k = 0; k < pinfo->image_component_count; ++k) { if (!strcmp (pinfo->image_component[k].name, "BIOS")) { strncpy (a->bios, pinfo->image_component[k].version, sizeof (a->bios)); a->bios[sizeof (a->bios) - 1] = '\0'; ntrim (a->bios); } else if (!strcmp (pinfo->image_component[k].name, "APP ")) { strncpy (a->firmware, pinfo->image_component[k].version, sizeof (a->firmware)); a->firmware[sizeof (a->firmware) - 1] = '\0'; ntrim (a->firmware); } } batteryStatus5 (a); /* Build enclosure map. */ for (k = 0, a->num_channels = 0, a->channel = NULL; k < device->num_devices; ++k) { int j; for (j = 0; j < a->num_channels; ++j) if (device->device[k].enclosure == a->channel[j]) break; if (j < a->num_channels) continue; /* Didn't find this enclosure; extend the map */ ++a->num_channels; if ((a->channel = (uint16_t *) realloc (a->channel, a->num_channels * sizeof (*a->channel))) == NULL) return "out of memory (channels)"; a->channel[a->num_channels - 1] = device->device[k].enclosure; } qsort (a->channel, a->num_channels, sizeof (*a->channel), cmpChannel); /* Some notes: Different meanings on different models. - FC_MAX_PHYSICAL_DEVICES used on older controllers, which is 256 disks (overallocation) - pd_disk_present_count is number of working drives, not counting missing drives - pd_present_count is unclear. It is pd_disk_present_count + 1 on some controllers - device_interface.port_count contains number of physical ports on the controller pd_present_count was used here, but in some controllers causes segfaults when there is a failed drive, and not enough space is allocated. Since there cannot be more devices than there are ports, that is a safe number to set without going overboard. */ a->num_physicals = pinfo->device_interface.port_count; /* On some controllers, namely the PERC6e, the controller does not know how many ports there are in the enclosure. Fall back to the worst case scenario. */ if (a->num_physicals < pinfo->pd_disk_present_count) a->num_physicals = FC_MAX_PHYSICAL_DEVICES; if ((a->physical = (struct physical_drive_info *) malloc (a->num_physicals * sizeof (*a->physical))) == NULL) return "out of memory (physical drives)"; memset (a->physical, 0, a->num_physicals * sizeof (*a->physical)); if ((a->physical_list = (struct physical_drive_info **) malloc (a->num_physicals * sizeof (*a->physical_list))) == NULL) return "out of memory (physical drives)"; memset (a->physical_list, 0, a->num_physicals * sizeof (*a->physical_list)); a->num_logicals = config->header->num_disk_defs; if ((a->logical = (struct logical_drive_info *) malloc (a->num_logicals * sizeof (*a->logical))) == NULL) return "out of memory (logical drives)"; memset (a->logical, 0, a->num_logicals * sizeof (*a->logical)); a->num_spans = config->header->num_span_defs; if ((a->span = (struct span_info *) malloc (a->num_spans * sizeof (*a->span))) == NULL) return "out of memory (spans)"; memset (a->span, 0, a->num_spans * sizeof (*a->span)); /* Get drive info. (This is fast on a PERC5.) */ for (k = 0; k < device->num_devices; ++k) if ((device->device[k].type == INQ_DASD) && (getPhysicalDriveInfo (a, device->device[k].device_id, 1) == NULL)) return "cannot get physical device info"; /* Examine all the spans. */ for (k = 0, ms = config->span; k < config->header->num_span_defs; ++k, ++ms) { struct span_info *span = &a->span[k]; int i; span->adapter = a; span->num_logical_drives = 0; span->logical_drive = NULL; span->blocks_per_disk = ms->sectors_per_disk; span->num_disks = ms->span_size; if ((span->disk = (struct physical_drive_info **) malloc (span->num_disks * sizeof (*span->disk))) == NULL) return "out of memory (span -> disk pointers)"; for (i = 0; i < span->num_disks; ++i) { span->disk[i] = getPhysicalDriveInfo (a, ms->disk[i].device_id, 1); span->disk[i]->span = span; } } /* Examine all the logical drives. */ for (k = 0, ml = config->disk; k < config->header->num_disk_defs; ++k, ++ml) { struct span_info *span; struct mega_array_disk_entry_sas *mr; int j; struct logical_drive_info *l = &a->logical[k]; l->adapter = a; snprintf (l->name, sizeof (l->name), "a%ud%u", a->target.adapno, k); l->target = k; switch (ml->state) { case MEGA_SAS_LD_OFFLINE: l->state = LdStateOffline; break; case MEGA_SAS_LD_PARTIALLY_DEGRADED: l->state = LdStatePartiallyDegraded; break; case MEGA_SAS_LD_DEGRADED: l->state = LdStateDegraded; break; case MEGA_SAS_LD_OPTIMAL: l->state = LdStateOptimal; break; default: l->state = LdStateUnknown; break; } l->raid_level = ml->raid_level; l->span_size = ml->disks_per_span; l->num_spans = ml->num_spans; if ((l->span = (struct span_reference *) malloc (l->num_spans * sizeof (*l->span))) == NULL) return "out of memory (span references)"; for (j = 0, mr = ml->span; j < ml->num_spans; ++j, ++mr) { span = &a->span[mr->span_index]; ++(span->num_logical_drives); if ((span->logical_drive = (struct logical_drive_info **) realloc (span->logical_drive, span->num_logical_drives * sizeof (*span->logical_drive))) == NULL) return "out of memory (span -> ldrv pointers)"; span->logical_drive[span->num_logical_drives - 1] = l; l->span[j].offset = mr->offset; l->span[j].blocks_per_disk = mr->sectors_per_disk; l->span[j].span = span; } } return NULL; } struct adapter_config *getAdapterConfig (int fd, uint8_t adapno, int sas) { static struct adapter_config *cf = NULL; struct adapter_config *a; char *status; for (a = cf; a; a = a->next) if ((a->target.adapno == adapno) && (a->is_sas == sas)) return a; if ((a = (struct adapter_config *) malloc (sizeof (*a))) == NULL) return NULL; memset (a, 0, sizeof (*a)); a->target.fd = fd; a->target.adapno = adapno; a->is_sas = sas; if (sas) { if (megaSasGetAdapterProductInfo (fd, adapno, &a->q.v5.adapinfo) < 0) return NULL; status = getAdapterConfig5 (a); } else { mraid_pinfo_t pinfo; if (megaGetAdapterProductInfo (fd, adapno, &pinfo) < 0) return NULL; if (pinfo.data_size == 0) status = getAdapterConfig2 (a); else { a->q.v3.adapinfo = pinfo; status = getAdapterConfig3 (a); } } if (status) { free (a); fprintf (stderr, "adapter %d: %s\n", adapno, status); return NULL; } a->next = cf; cf = a; return a; } megactl-0.4.5/adapter.h000066400000000000000000000022311465722425200147340ustar00rootroot00000000000000#ifndef _ADAPTER_H #define _ADAPTER_H /* * Definitions for high-level adapter interface. * * Copyright (c) 2007 by Jefferson Ogata */ /* * 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, 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; see the file COPYING. If not, write to the Free Software * Foundation, 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. */ #include "mega.h" #include struct log_page_list *getDriveLogPage (struct physical_drive_info *d, uint8_t page); struct physical_drive_info *getPhysicalDriveInfo (struct adapter_config *cf, uint16_t target, int fetch); struct adapter_config *getAdapterConfig (int fd, uint8_t adapno, int sas); #endif megactl-0.4.5/callinfo.c000066400000000000000000000313011465722425200150760ustar00rootroot00000000000000/* * Sysctl call data for ptrace(2). * * Copyright (c) 2007 by Jefferson Ogata */ /* * 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, 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; see the file COPYING. If not, write to the Free Software * Foundation, 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. */ #include #include #include #include "callinfo.h" #ifndef SYS_pread #define SYS_pread SYS_pread64 #endif #ifndef SYS_pwrite #define SYS_pwrite SYS_pwrite64 #endif struct callinfo callinfo[] = { { 0, 0, NULL }, { SYS_exit, 0, "exit" }, { SYS_fork, 0, "fork" }, { SYS_read, 0, "read" }, { SYS_write, 0, "write" }, { SYS_open, 0, "open" }, { SYS_close, 0, "close" }, { SYS_waitpid, 0, "waitpid" }, { SYS_creat, 0, "creat" }, { SYS_link, 0, "link" }, { SYS_unlink, 0, "unlink" }, { SYS_execve, 0, "execve" }, { SYS_chdir, 0, "chdir" }, { SYS_time, 0, "time" }, { SYS_mknod, 0, "mknod" }, { SYS_chmod, 0, "chmod" }, { SYS_lchown, 0, "lchown" }, { SYS_break, 0, "break" }, { SYS_oldstat, 0, "oldstat" }, { SYS_lseek, 0, "lseek" }, { SYS_getpid, 0, "getpid" }, { SYS_mount, 0, "mount" }, { SYS_umount, 0, "umount" }, { SYS_setuid, 0, "setuid" }, { SYS_getuid, 0, "getuid" }, { SYS_stime, 0, "stime" }, { SYS_ptrace, 1, "ptrace" }, { SYS_alarm, 0, "alarm" }, { SYS_oldfstat, 0, "oldfstat" }, { SYS_pause, 0, "pause" }, { SYS_utime, 0, "utime" }, { SYS_stty, 0, "stty" }, { SYS_gtty, 0, "gtty" }, { SYS_access, 0, "access" }, { SYS_nice, 0, "nice" }, { SYS_ftime, 0, "ftime" }, { SYS_sync, 0, "sync" }, { SYS_kill, 0, "kill" }, { SYS_rename, 0, "rename" }, { SYS_mkdir, 0, "mkdir" }, { SYS_rmdir, 0, "rmdir" }, { SYS_dup, 0, "dup" }, { SYS_pipe, 0, "pipe" }, { SYS_times, 0, "times" }, { SYS_prof, 0, "prof" }, { SYS_brk, 1, "brk" }, { SYS_setgid, 0, "setgid" }, { SYS_getgid, 0, "getgid" }, { SYS_signal, 0, "signal" }, { SYS_geteuid, 0, "geteuid" }, { SYS_getegid, 0, "getegid" }, { SYS_acct, 0, "acct" }, { SYS_umount2, 0, "umount2" }, { SYS_lock, 0, "lock" }, { SYS_ioctl, 0, "ioctl" }, { SYS_fcntl, 0, "fcntl" }, { SYS_mpx, 0, "mpx" }, { SYS_setpgid, 0, "setpgid" }, { SYS_ulimit, 0, "ulimit" }, { SYS_oldolduname, 0, "oldolduname" }, { SYS_umask, 0, "umask" }, { SYS_chroot, 0, "chroot" }, { SYS_ustat, 0, "ustat" }, { SYS_dup2, 0, "dup2" }, { SYS_getppid, 0, "getppid" }, { SYS_getpgrp, 0, "getpgrp" }, { SYS_setsid, 0, "setsid" }, { SYS_sigaction, 0, "sigaction" }, { SYS_sgetmask, 0, "sgetmask" }, { SYS_ssetmask, 0, "ssetmask" }, { SYS_setreuid, 0, "setreuid" }, { SYS_setregid, 0, "setregid" }, { SYS_sigsuspend, 0, "sigsuspend" }, { SYS_sigpending, 0, "sigpending" }, { SYS_sethostname, 0, "sethostname" }, { SYS_setrlimit, 0, "setrlimit" }, { SYS_getrlimit, 0, "getrlimit" }, { SYS_getrusage, 0, "getrusage" }, { SYS_gettimeofday, 0, "gettimeofday" }, { SYS_settimeofday, 0, "settimeofday" }, { SYS_getgroups, 0, "getgroups" }, { SYS_setgroups, 0, "setgroups" }, { SYS_select, 0, "select" }, { SYS_symlink, 0, "symlink" }, { SYS_oldlstat, 0, "oldlstat" }, { SYS_readlink, 0, "readlink" }, { SYS_uselib, 0, "uselib" }, { SYS_swapon, 0, "swapon" }, { SYS_reboot, 0, "reboot" }, { SYS_readdir, 0, "readdir" }, { SYS_mmap2, 1, "mmap2" }, { SYS_munmap, 0, "munmap" }, { SYS_truncate, 0, "truncate" }, { SYS_ftruncate, 0, "ftruncate" }, { SYS_fchmod, 0, "fchmod" }, { SYS_fchown, 0, "fchown" }, { SYS_getpriority, 0, "getpriority" }, { SYS_setpriority, 0, "setpriority" }, { SYS_profil, 0, "profil" }, { SYS_statfs, 0, "statfs" }, { SYS_fstatfs, 0, "fstatfs" }, { SYS_ioperm, 0, "ioperm" }, { SYS_socketcall, 0, "socketcall" }, { SYS_syslog, 0, "syslog" }, { SYS_setitimer, 0, "setitimer" }, { SYS_getitimer, 0, "getitimer" }, { SYS_stat, 0, "stat" }, { SYS_lstat, 0, "lstat" }, { SYS_fstat, 0, "fstat" }, { SYS_olduname, 0, "olduname" }, { SYS_iopl, 0, "iopl" }, { SYS_vhangup, 0, "vhangup" }, { SYS_idle, 0, "idle" }, { SYS_vm86old, 0, "vm86old" }, { SYS_wait4, 0, "wait4" }, { SYS_swapoff, 0, "swapoff" }, { SYS_sysinfo, 0, "sysinfo" }, { SYS_ipc, 0, "ipc" }, { SYS_fsync, 0, "fsync" }, { SYS_sigreturn, 0, "sigreturn" }, { SYS_clone, 0, "clone" }, { SYS_setdomainname, 0, "setdomainname" }, { SYS_uname, 0, "uname" }, { SYS_modify_ldt, 0, "modify_ldt" }, { SYS_adjtimex, 0, "adjtimex" }, { SYS_mprotect, 0, "mprotect" }, { SYS_sigprocmask, 0, "sigprocmask" }, { SYS_create_module, 0, "create_module" }, { SYS_init_module, 0, "init_module" }, { SYS_delete_module, 0, "delete_module" }, { SYS_get_kernel_syms, 0, "get_kernel_syms" }, { SYS_quotactl, 0, "quotactl" }, { SYS_getpgid, 0, "getpgid" }, { SYS_fchdir, 0, "fchdir" }, { SYS_bdflush, 0, "bdflush" }, { SYS_sysfs, 0, "sysfs" }, { SYS_personality, 0, "personality" }, { SYS_afs_syscall, 0, "afs_syscall" }, { SYS_setfsuid, 0, "setfsuid" }, { SYS_setfsgid, 0, "setfsgid" }, { SYS__llseek, 0, "_llseek" }, { SYS_getdents, 0, "getdents" }, { SYS__newselect, 0, "_newselect" }, { SYS_flock, 0, "flock" }, { SYS_msync, 0, "msync" }, { SYS_readv, 0, "readv" }, { SYS_writev, 0, "writev" }, { SYS_getsid, 0, "getsid" }, { SYS_fdatasync, 0, "fdatasync" }, { SYS__sysctl, 0, "_sysctl" }, { SYS_mlock, 0, "mlock" }, { SYS_munlock, 0, "munlock" }, { SYS_mlockall, 0, "mlockall" }, { SYS_munlockall, 0, "munlockall" }, { SYS_sched_setparam, 0, "sched_setparam" }, { SYS_sched_getparam, 0, "sched_getparam" }, { SYS_sched_setscheduler, 0, "sched_setscheduler" }, { SYS_sched_getscheduler, 0, "sched_getscheduler" }, { SYS_sched_yield, 0, "sched_yield" }, { SYS_sched_get_priority_max, 0, "sched_get_priority_max" }, { SYS_sched_get_priority_min, 0, "sched_get_priority_min" }, { SYS_sched_rr_get_interval, 0, "sched_rr_get_interval" }, { SYS_nanosleep, 0, "nanosleep" }, { SYS_mremap, 0, "mremap" }, { SYS_setresuid, 0, "setresuid" }, { SYS_getresuid, 0, "getresuid" }, { SYS_vm86, 0, "vm86" }, { SYS_query_module, 0, "query_module" }, { SYS_poll, 0, "poll" }, { SYS_nfsservctl, 0, "nfsservctl" }, { SYS_setresgid, 0, "setresgid" }, { SYS_getresgid, 0, "getresgid" }, { SYS_prctl, 0, "prctl" }, { SYS_rt_sigreturn, 0, "rt_sigreturn" }, { SYS_rt_sigaction, 0, "rt_sigaction" }, { SYS_rt_sigprocmask, 0, "rt_sigprocmask" }, { SYS_rt_sigpending, 0, "rt_sigpending" }, { SYS_rt_sigtimedwait, 0, "rt_sigtimedwait" }, { SYS_rt_sigqueueinfo, 0, "rt_sigqueueinfo" }, { SYS_rt_sigsuspend, 0, "rt_sigsuspend" }, { SYS_pread, 0, "pread" }, { SYS_pwrite, 0, "pwrite" }, { SYS_chown, 0, "chown" }, { SYS_getcwd, 0, "getcwd" }, { SYS_capget, 0, "capget" }, { SYS_capset, 0, "capset" }, { SYS_sigaltstack, 0, "sigaltstack" }, { SYS_sendfile, 0, "sendfile" }, { SYS_getpmsg, 0, "getpmsg" }, { SYS_putpmsg, 0, "putpmsg" }, { SYS_vfork, 0, "vfork" }, { SYS_ugetrlimit, 0, "ugetrlimit" }, { SYS_mmap2, 1, "mmap2" }, { SYS_truncate64, 0, "truncate64" }, { SYS_ftruncate64, 0, "ftruncate64" }, { SYS_stat64, 0, "stat64" }, { SYS_lstat64, 0, "lstat64" }, { SYS_fstat64, 0, "fstat64" }, { SYS_lchown32, 0, "lchown32" }, { SYS_getuid32, 0, "getuid32" }, { SYS_getgid32, 0, "getgid32" }, { SYS_geteuid32, 0, "geteuid32" }, { SYS_getegid32, 0, "getegid32" }, { SYS_setreuid32, 0, "setreuid32" }, { SYS_setregid32, 0, "setregid32" }, { SYS_getgroups32, 0, "getgroups32" }, { SYS_setgroups32, 0, "setgroups32" }, { SYS_fchown32, 0, "fchown32" }, { SYS_setresuid32, 0, "setresuid32" }, { SYS_getresuid32, 0, "getresuid32" }, { SYS_setresgid32, 0, "setresgid32" }, { SYS_getresgid32, 0, "getresgid32" }, { SYS_chown32, 0, "chown32" }, { SYS_setuid32, 0, "setuid32" }, { SYS_setgid32, 0, "setgid32" }, { SYS_setfsuid32, 0, "setfsuid32" }, { SYS_setfsgid32, 0, "setfsgid32" }, { SYS_pivot_root, 0, "pivot_root" }, { SYS_mincore, 0, "mincore" }, { SYS_madvise1, 0, "madvise1" }, { SYS_getdents64, 0, "getdents64" }, { SYS_fcntl64, 0, "fcntl64" }, { 222, 0, NULL }, { 223 /* SYS_security */, 0, NULL /* "security" */ }, { SYS_gettid, 0, "gettid" }, { SYS_readahead, 0, "readahead" }, { SYS_setxattr, 0, "setxattr" }, { SYS_lsetxattr, 0, "lsetxattr" }, { SYS_fsetxattr, 0, "fsetxattr" }, { SYS_getxattr, 0, "getxattr" }, { SYS_lgetxattr, 0, "lgetxattr" }, { SYS_fgetxattr, 0, "fgetxattr" }, { SYS_listxattr, 0, "listxattr" }, { SYS_llistxattr, 0, "llistxattr" }, { SYS_flistxattr, 0, "flistxattr" }, { SYS_removexattr, 0, "removexattr" }, { SYS_lremovexattr, 0, "lremovexattr" }, { SYS_fremovexattr, 0, "fremovexattr" }, { SYS_tkill, 0, "tkill" }, { SYS_sendfile64, 0, "sendfile64" }, { SYS_futex, 0, "futex" }, { SYS_sched_setaffinity, 0, "sched_setaffinity" }, { SYS_sched_getaffinity, 0, "sched_getaffinity" }, #ifdef SYS_set_thread_area { SYS_set_thread_area, 0, "set_thread_area " }, #else { 243, 0, NULL }, #endif #ifdef SYS_get_thread_area { SYS_get_thread_area, 0, "get_thread_area" }, #else { 244, 0, NULL }, #endif #ifdef SYS_io_setup { SYS_io_setup, 0, "io_setup" }, #else { 245, 0, NULL }, #endif #ifdef SYS_io_destroy { SYS_io_destroy, 0, "io_destroy" }, #else { 246, 0, NULL }, #endif #ifdef SYS_io_getevents { SYS_io_getevents, 0, "io_getevents" }, #else { 247, 0, NULL }, #endif #ifdef SYS_io_submit { SYS_io_submit, 0, "io_submit" }, #else { 248, 0, NULL }, #endif #ifdef SYS_io_cancel { SYS_io_cancel, 0, "io_cancel" }, #else { 249, 0, NULL }, #endif #ifdef SYS_fadvise64 { SYS_fadvise64, 0, "fadvise64" }, #else { 250, 0, NULL }, #endif { 251, 0, NULL }, #ifdef SYS_exit_group { SYS_exit_group, 0, "exit_group" }, #else { 252, 0, NULL }, #endif #ifdef SYS_lookup_dcookie { SYS_lookup_dcookie, 0, "lookup_dcookie" }, #else { 253, 0, NULL }, #endif #ifdef SYS_epoll_create { SYS_epoll_create, 0, "epoll_create" }, #else { 254, 0, NULL }, #endif #ifdef SYS_epoll_ctl { SYS_epoll_ctl, 0, "epoll_ctl" }, #else { 255, 0, NULL }, #endif #ifdef SYS_epoll_wait { SYS_epoll_wait, 0, "epoll_wait" }, #else { 256, 0, NULL }, #endif #ifdef SYS_remap_file_pages { SYS_remap_file_pages, 0, "remap_file_pages" }, #else { 257, 0, NULL }, #endif #ifdef SYS_set_tid_address { SYS_set_tid_address, 0, "set_tid_address" }, #else { 258, 0, NULL }, #endif #ifdef SYS_timer_create { SYS_timer_create, 0, "timer_create" }, #else { 259, 0, NULL }, #endif #ifdef SYS_timer_settime { SYS_timer_settime, 0, "timer_settime" }, #else { 260, 0, NULL }, #endif #ifdef SYS_timer_gettime { SYS_timer_gettime, 0, "timer_gettime" }, #else { 261, 0, NULL }, #endif #ifdef SYS_timer_getoverrun { SYS_timer_getoverrun, 0, "timer_getoverrun" }, #else { 262, 0, NULL }, #endif #ifdef SYS_timer_delete { SYS_timer_delete, 0, "timer_delete" }, #else { 263, 0, NULL }, #endif #ifdef SYS_clock_settime { SYS_clock_settime, 0, "clock_settime" }, #else { 264, 0, NULL }, #endif #ifdef SYS_clock_gettime { SYS_clock_gettime, 0, "clock_gettime" }, #else { 265, 0, NULL }, #endif #ifdef SYS_clock_getres { SYS_clock_getres, 0, "clock_getres" }, #else { 266, 0, NULL }, #endif #ifdef SYS_clock_nansleep { SYS_clock_nanosleep, 0, "clock_nanosleep" }, #else { 267, 0, NULL }, #endif { 268, 0, NULL }, { 269, 0, NULL }, #ifdef SYS_tgkill { SYS_tgkill, 0, "tgkill" }, #else { 270, 0, NULL }, #endif }; int callmax = sizeof (callinfo) / sizeof (callinfo[0]); megactl-0.4.5/callinfo.h000066400000000000000000000017321465722425200151100ustar00rootroot00000000000000#ifndef _CALLINFO_H #define _CALLINFO_H /* * Definitions for syscall constants. * * Copyright (c) 2007 by Jefferson Ogata */ /* * 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, 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; see the file COPYING. If not, write to the Free Software * Foundation, 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. */ struct callinfo { int id; int ptrval; char *name; }; extern struct callinfo callinfo[]; extern int callmax; #endif megactl-0.4.5/dumpbytes.c000066400000000000000000000034131465722425200153260ustar00rootroot00000000000000/* * Hexadecimal dump for displaying ioctl data structures. * * Copyright (c) 2007 by Jefferson Ogata */ /* * 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, 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; see the file COPYING. If not, write to the Free Software * Foundation, 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. */ #include #include #include #include void dumpbytes (FILE *f, void *z, size_t len, void *addr, char *prefix) { off_t k; int j = 15; char abuf[20]; unsigned char *buf = z; for (k = 0; k < len; ++k) { unsigned char c = buf[k]; j = k % 16; if (j == 0) { if (prefix) fprintf (f, " %s+%04lx:\t", prefix, k); else fprintf (f, " %08lx:\t", ((unsigned long) addr) + k); memset (abuf, ' ', sizeof abuf - 1); abuf[sizeof abuf - 1] = '\0'; } else { if (j % 4 == 0) putc (' ', f); if (j % 8 == 0) putc (' ', f); } fprintf (f, "%02x", c); abuf[j + j / 4] = isprint (c) ? c : '.'; if (j == 15) { fprintf (f, " %s\n", abuf); } } if (j != 15) { for ( ; j < 15; ++j) { if (j % 4 == 0) putc (' ', f); if (j % 8 == 0) putc (' ', f); putc (' ', f); putc (' ', f); } fprintf (f, " %s\n", abuf); } } megactl-0.4.5/dumpbytes.h000066400000000000000000000017031465722425200153330ustar00rootroot00000000000000#ifndef _DUMPBYTES_H #define _DUMPBYTES_H /* * Definitions for hex dump routine. * * Copyright (c) 2007 by Jefferson Ogata */ /* * 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, 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; see the file COPYING. If not, write to the Free Software * Foundation, 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. */ #include extern void dumpbytes (FILE *f, void *z, size_t len, void *addr, char *prefix); #endif megactl-0.4.5/includes-hack/000077500000000000000000000000001465722425200156575ustar00rootroot00000000000000megactl-0.4.5/includes-hack/asm/000077500000000000000000000000001465722425200164375ustar00rootroot00000000000000megactl-0.4.5/includes-hack/asm/semaphore.h000066400000000000000000000000001465722425200205610ustar00rootroot00000000000000megactl-0.4.5/kernel-2.6.9-55.0.2.EL/000077500000000000000000000000001465722425200161235ustar00rootroot00000000000000megactl-0.4.5/kernel-2.6.9-55.0.2.EL/megaraid000077700000000000000000000000001465722425200226642megaraid-2.20.4.6-rh2ustar00rootroot00000000000000megactl-0.4.5/kernel-2.6.9-55.0.2.EL/megaraid-2.20.4.6-rh2/000077500000000000000000000000001465722425200212525ustar00rootroot00000000000000megactl-0.4.5/kernel-2.6.9-55.0.2.EL/megaraid-2.20.4.6-rh2/mbox_defs.h000066400000000000000000000530161465722425200233760ustar00rootroot00000000000000/* * * Linux MegaRAID Unified device driver * * Copyright (c) 2003-2004 LSI Logic Corporation. * * 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. * * FILE : mbox_defs.h * */ #ifndef _MRAID_MBOX_DEFS_H_ #define _MRAID_MBOX_DEFS_H_ #include /* * Commands and states for mailbox based controllers */ #define MBOXCMD_LREAD 0x01 #define MBOXCMD_LWRITE 0x02 #define MBOXCMD_PASSTHRU 0x03 #define MBOXCMD_ADPEXTINQ 0x04 #define MBOXCMD_ADAPTERINQ 0x05 #define MBOXCMD_LREAD64 0xA7 #define MBOXCMD_LWRITE64 0xA8 #define MBOXCMD_PASSTHRU64 0xC3 #define MBOXCMD_EXTPTHRU 0xE3 #define MAIN_MISC_OPCODE 0xA4 #define GET_MAX_SG_SUPPORT 0x01 #define SUPPORT_EXT_CDB 0x16 #define FC_NEW_CONFIG 0xA1 #define NC_SUBOP_PRODUCT_INFO 0x0E #define NC_SUBOP_ENQUIRY3 0x0F #define ENQ3_GET_SOLICITED_FULL 0x02 #define OP_DCMD_READ_CONFIG 0x04 #define NEW_READ_CONFIG_8LD 0x67 #define READ_CONFIG_8LD 0x07 #define FLUSH_ADAPTER 0x0A #define FLUSH_SYSTEM 0xFE /* * Command for random deletion of logical drives */ #define FC_DEL_LOGDRV 0xA4 #define OP_SUP_DEL_LOGDRV 0x2A #define OP_GET_LDID_MAP 0x18 #define OP_DEL_LOGDRV 0x1C /* * BIOS commands */ #define IS_BIOS_ENABLED 0x62 #define GET_BIOS 0x01 #define CHNL_CLASS 0xA9 #define GET_CHNL_CLASS 0x00 #define SET_CHNL_CLASS 0x01 #define CH_RAID 0x01 #define CH_SCSI 0x00 #define BIOS_PVT_DATA 0x40 #define GET_BIOS_PVT_DATA 0x00 /* * Commands to support clustering */ #define GET_TARGET_ID 0x7D #define CLUSTER_OP 0x70 #define GET_CLUSTER_MODE 0x02 #define CLUSTER_CMD 0x6E #define RESERVE_LD 0x01 #define RELEASE_LD 0x02 #define RESET_RESERVATIONS 0x03 #define RESERVATION_STATUS 0x04 #define RESERVE_PD 0x05 #define RELEASE_PD 0x06 /* * Module battery status */ #define BATTERY_MODULE_MISSING 0x01 #define BATTERY_LOW_VOLTAGE 0x02 #define BATTERY_TEMP_HIGH 0x04 #define BATTERY_PACK_MISSING 0x08 #define BATTERY_CHARGE_MASK 0x30 #define BATTERY_CHARGE_DONE 0x00 #define BATTERY_CHARGE_INPROG 0x10 #define BATTERY_CHARGE_FAIL 0x20 #define BATTERY_CYCLES_EXCEEDED 0x40 /* * Physical drive states. */ #define PDRV_UNCNF 0 #define PDRV_ONLINE 3 #define PDRV_FAILED 4 #define PDRV_RBLD 5 #define PDRV_HOTSPARE 6 /* * Raid logical drive states. */ #define RDRV_OFFLINE 0 #define RDRV_DEGRADED 1 #define RDRV_OPTIMAL 2 #define RDRV_DELETED 3 /* * Read, write and cache policies */ #define NO_READ_AHEAD 0 #define READ_AHEAD 1 #define ADAP_READ_AHEAD 2 #define WRMODE_WRITE_THRU 0 #define WRMODE_WRITE_BACK 1 #define CACHED_IO 0 #define DIRECT_IO 1 #define MAX_LOGICAL_DRIVES_8LD 8 #define MAX_LOGICAL_DRIVES_40LD 40 #define FC_MAX_PHYSICAL_DEVICES 256 #define MAX_MBOX_CHANNELS 5 #define MAX_MBOX_TARGET 15 #define MBOX_MAX_PHYSICAL_DRIVES MAX_MBOX_CHANNELS*MAX_MBOX_TARGET #define MAX_ROW_SIZE_40LD 32 #define MAX_ROW_SIZE_8LD 8 #define SPAN_DEPTH_8_SPANS 8 #define SPAN_DEPTH_4_SPANS 4 #define MAX_REQ_SENSE_LEN 0x20 /** * struct mbox_t - Driver and f/w handshake structure. * @cmd : firmware command * @cmdid : command id * @numsectors : number of sectors to be transferred * @lba : Logical Block Address on LD * @xferaddr : DMA address for data transfer * @logdrv : logical drive number * @numsge : number of scatter gather elements in sg list * @resvd : reserved * @busy : f/w busy, must wait to issue more commands. * @numstatus : number of commands completed. * @status : status of the commands completed * @completed : array of completed command ids. * @poll : poll and ack sequence * @ack : poll and ack sequence * * The central handshake structure between the driver and the firmware. This * structure must be allocated by the driver and aligned at 8-byte boundary. */ #define MBOX_MAX_FIRMWARE_STATUS 46 typedef struct { uint8_t cmd; uint8_t cmdid; uint16_t numsectors; uint32_t lba; uint32_t xferaddr; uint8_t logdrv; uint8_t numsge; uint8_t resvd; uint8_t busy; uint8_t numstatus; uint8_t status; uint8_t completed[MBOX_MAX_FIRMWARE_STATUS]; uint8_t poll; uint8_t ack; } __attribute__ ((packed)) mbox_t; /** * mbox64_t - 64-bit extension for the mailbox * @segment_lo : the low 32-bits of the address of the scatter-gather list * @segment_hi : the upper 32-bits of the address of the scatter-gather list * @mbox : 32-bit mailbox, whose xferadder field must be set to * 0xFFFFFFFF * * This is the extension of the 32-bit mailbox to be able to perform DMA * beyond 4GB address range. */ typedef struct { uint32_t xferaddr_lo; uint32_t xferaddr_hi; mbox_t mbox32; } __attribute__ ((packed)) mbox64_t; /* * mailbox structure used for internal commands */ typedef struct { u8 cmd; u8 cmdid; u8 opcode; u8 subopcode; u32 lba; u32 xferaddr; u8 logdrv; u8 rsvd[3]; u8 numstatus; u8 status; } __attribute__ ((packed)) int_mbox_t; /** * mraid_passthru_t - passthru structure to issue commands to physical devices * @timeout : command timeout, 0=6sec, 1=60sec, 2=10min, 3=3hr * @ars : set if ARS required after check condition * @islogical : set if command meant for logical devices * @logdrv : logical drive number if command for LD * @channel : Channel on which physical device is located * @target : SCSI target of the device * @queuetag : unused * @queueaction : unused * @cdb : SCSI CDB * @cdblen : length of the CDB * @reqsenselen : amount of request sense data to be returned * @reqsensearea : Sense information buffer * @numsge : number of scatter-gather elements in the sg list * @scsistatus : SCSI status of the command completed. * @dataxferaddr : DMA data transfer address * @dataxferlen : amount of the data to be transferred. */ typedef struct { uint8_t timeout :3; uint8_t ars :1; uint8_t reserved :3; uint8_t islogical :1; uint8_t logdrv; uint8_t channel; uint8_t target; uint8_t queuetag; uint8_t queueaction; uint8_t cdb[10]; uint8_t cdblen; uint8_t reqsenselen; uint8_t reqsensearea[MAX_REQ_SENSE_LEN]; uint8_t numsge; uint8_t scsistatus; uint32_t dataxferaddr; uint32_t dataxferlen; } __attribute__ ((packed)) mraid_passthru_t; typedef struct { uint32_t dataxferaddr_lo; uint32_t dataxferaddr_hi; mraid_passthru_t pthru32; } __attribute__ ((packed)) mega_passthru64_t; /** * mraid_epassthru_t - passthru structure to issue commands to physical devices * @timeout : command timeout, 0=6sec, 1=60sec, 2=10min, 3=3hr * @ars : set if ARS required after check condition * @rsvd1 : reserved field * @cd_rom : (?) * @rsvd2 : reserved field * @islogical : set if command meant for logical devices * @logdrv : logical drive number if command for LD * @channel : Channel on which physical device is located * @target : SCSI target of the device * @queuetag : unused * @queueaction : unused * @cdblen : length of the CDB * @rsvd3 : reserved field * @cdb : SCSI CDB * @numsge : number of scatter-gather elements in the sg list * @status : SCSI status of the command completed. * @reqsenselen : amount of request sense data to be returned * @reqsensearea : Sense information buffer * @rsvd4 : reserved field * @dataxferaddr : DMA data transfer address * @dataxferlen : amount of the data to be transferred. */ typedef struct { uint8_t timeout :3; uint8_t ars :1; uint8_t rsvd1 :1; uint8_t cd_rom :1; uint8_t rsvd2 :1; uint8_t islogical :1; uint8_t logdrv; uint8_t channel; uint8_t target; uint8_t queuetag; uint8_t queueaction; uint8_t cdblen; uint8_t rsvd3; uint8_t cdb[16]; uint8_t numsge; uint8_t status; uint8_t reqsenselen; uint8_t reqsensearea[MAX_REQ_SENSE_LEN]; uint8_t rsvd4; uint32_t dataxferaddr; uint32_t dataxferlen; } __attribute__ ((packed)) mraid_epassthru_t; /** * mraid_pinfo_t - product info, static information about the controller * @data_size : current size in bytes (not including resvd) * @config_signature : Current value is 0x00282008 * @fw_version : Firmware version * @bios_version : version of the BIOS * @product_name : Name given to the controller * @max_commands : Maximum concurrent commands supported * @nchannels : Number of SCSI Channels detected * @fc_loop_present : Number of Fibre Loops detected * @mem_type : EDO, FPM, SDRAM etc * @signature : * @dram_size : In terms of MB * @subsysid : device PCI subsystem ID * @subsysvid : device PCI subsystem vendor ID * @notify_counters : * @pad1k : 135 + 889 resvd = 1024 total size * * This structures holds the information about the controller which is not * expected to change dynamically. * * The current value of config signature is 0x00282008: * 0x28 = MAX_LOGICAL_DRIVES, * 0x20 = Number of stripes and * 0x08 = Number of spans */ typedef struct { uint32_t data_size; uint32_t config_signature; uint8_t fw_version[16]; uint8_t bios_version[16]; uint8_t product_name[80]; uint8_t max_commands; uint8_t nchannels; uint8_t fc_loop_present; uint8_t mem_type; uint32_t signature; uint16_t dram_size; uint16_t subsysid; uint16_t subsysvid; uint8_t notify_counters; uint8_t pad1k[889]; } __attribute__ ((packed)) mraid_pinfo_t; /** * mraid_notify_t - the notification structure * @global_counter : Any change increments this counter * @param_counter : Indicates any params changed * @param_id : Param modified - defined below * @param_val : New val of last param modified * @write_config_counter : write config occurred * @write_config_rsvd : * @ldrv_op_counter : Indicates ldrv op started/completed * @ldrv_opid : ldrv num * @ldrv_opcmd : ldrv operation - defined below * @ldrv_opstatus : status of the operation * @ldrv_state_counter : Indicates change of ldrv state * @ldrv_state_id : ldrv num * @ldrv_state_new : New state * @ldrv_state_old : old state * @pdrv_state_counter : Indicates change of ldrv state * @pdrv_state_id : pdrv id * @pdrv_state_new : New state * @pdrv_state_old : old state * @pdrv_fmt_counter : Indicates pdrv format started/over * @pdrv_fmt_id : pdrv id * @pdrv_fmt_val : format started/over * @pdrv_fmt_rsvd : * @targ_xfer_counter : Indicates SCSI-2 Xfer rate change * @targ_xfer_id : pdrv Id * @targ_xfer_val : new Xfer params of last pdrv * @targ_xfer_rsvd : * @fcloop_id_chg_counter : Indicates loopid changed * @fcloopid_pdrvid : pdrv id * @fcloop_id0 : loopid on fc loop 0 * @fcloop_id1 : loopid on fc loop 1 * @fcloop_state_counter : Indicates loop state changed * @fcloop_state0 : state of fc loop 0 * @fcloop_state1 : state of fc loop 1 * @fcloop_state_rsvd : */ typedef struct { uint32_t global_counter; uint8_t param_counter; uint8_t param_id; uint16_t param_val; uint8_t write_config_counter; uint8_t write_config_rsvd[3]; uint8_t ldrv_op_counter; uint8_t ldrv_opid; uint8_t ldrv_opcmd; uint8_t ldrv_opstatus; uint8_t ldrv_state_counter; uint8_t ldrv_state_id; uint8_t ldrv_state_new; uint8_t ldrv_state_old; uint8_t pdrv_state_counter; uint8_t pdrv_state_id; uint8_t pdrv_state_new; uint8_t pdrv_state_old; uint8_t pdrv_fmt_counter; uint8_t pdrv_fmt_id; uint8_t pdrv_fmt_val; uint8_t pdrv_fmt_rsvd; uint8_t targ_xfer_counter; uint8_t targ_xfer_id; uint8_t targ_xfer_val; uint8_t targ_xfer_rsvd; uint8_t fcloop_id_chg_counter; uint8_t fcloopid_pdrvid; uint8_t fcloop_id0; uint8_t fcloop_id1; uint8_t fcloop_state_counter; uint8_t fcloop_state0; uint8_t fcloop_state1; uint8_t fcloop_state_rsvd; } __attribute__ ((packed)) mraid_notify_t; /** * mraid_inquiry3_t - enquiry for device information * * @data_size : current size in bytes (not including resvd) * @notify : * @notify_rsvd : * @rebuild_rate : rebuild rate (0% - 100%) * @cache_flush_int : cache flush interval in seconds * @sense_alert : * @drive_insert_count : drive insertion count * @battery_status : * @num_ldrv : no. of Log Drives configured * @recon_state : state of reconstruct * @ldrv_op_status : logdrv Status * @ldrv_size : size of each log drv * @ldrv_prop : * @ldrv_state : state of log drives * @pdrv_state : state of phys drvs. * @pdrv_format : * @targ_xfer : phys device transfer rate * @pad1k : 761 + 263reserved = 1024 bytes total size */ #define MAX_NOTIFY_SIZE 0x80 #define CUR_NOTIFY_SIZE sizeof(mraid_notify_t) typedef struct { uint32_t data_size; mraid_notify_t notify; uint8_t notify_rsvd[MAX_NOTIFY_SIZE - CUR_NOTIFY_SIZE]; uint8_t rebuild_rate; uint8_t cache_flush_int; uint8_t sense_alert; uint8_t drive_insert_count; uint8_t battery_status; uint8_t num_ldrv; uint8_t recon_state[MAX_LOGICAL_DRIVES_40LD / 8]; uint16_t ldrv_op_status[MAX_LOGICAL_DRIVES_40LD / 8]; uint32_t ldrv_size[MAX_LOGICAL_DRIVES_40LD]; uint8_t ldrv_prop[MAX_LOGICAL_DRIVES_40LD]; uint8_t ldrv_state[MAX_LOGICAL_DRIVES_40LD]; uint8_t pdrv_state[FC_MAX_PHYSICAL_DEVICES]; uint16_t pdrv_format[FC_MAX_PHYSICAL_DEVICES / 16]; uint8_t targ_xfer[80]; uint8_t pad1k[263]; } __attribute__ ((packed)) mraid_inquiry3_t; /** * mraid_adapinfo_t - information about the adapter * @max_commands : max concurrent commands supported * @rebuild_rate : rebuild rate - 0% thru 100% * @max_targ_per_chan : max targ per channel * @nchannels : number of channels on HBA * @fw_version : firmware version * @age_of_flash : number of times FW has been flashed * @chip_set_value : contents of 0xC0000832 * @dram_size : in MB * @cache_flush_interval : in seconds * @bios_version : * @board_type : * @sense_alert : * @write_config_count : increase with every configuration change * @drive_inserted_count : increase with every drive inserted * @inserted_drive : channel:Id of inserted drive * @battery_status : bit 0: battery module missing * bit 1: VBAD * bit 2: temprature high * bit 3: battery pack missing * bit 4,5: * 00 - charge complete * 01 - fast charge in progress * 10 - fast charge fail * 11 - undefined * bit 6: counter > 1000 * bit 7: Undefined * @dec_fault_bus_info : */ typedef struct { uint8_t max_commands; uint8_t rebuild_rate; uint8_t max_targ_per_chan; uint8_t nchannels; uint8_t fw_version[4]; uint16_t age_of_flash; uint8_t chip_set_value; uint8_t dram_size; uint8_t cache_flush_interval; uint8_t bios_version[4]; uint8_t board_type; uint8_t sense_alert; uint8_t write_config_count; uint8_t battery_status; uint8_t dec_fault_bus_info; } __attribute__ ((packed)) mraid_adapinfo_t; /** * mraid_ldrv_info_t - information about the logical drives * @nldrv : Number of logical drives configured * @rsvd : * @size : size of each logical drive * @prop : * @state : state of each logical drive */ typedef struct { uint8_t nldrv; uint8_t rsvd[3]; uint32_t size[MAX_LOGICAL_DRIVES_8LD]; uint8_t prop[MAX_LOGICAL_DRIVES_8LD]; uint8_t state[MAX_LOGICAL_DRIVES_8LD]; } __attribute__ ((packed)) mraid_ldrv_info_t; /** * mraid_pdrv_info_t - information about the physical drives * @pdrv_state : state of each physical drive */ typedef struct { uint8_t pdrv_state[MBOX_MAX_PHYSICAL_DRIVES]; uint8_t rsvd; } __attribute__ ((packed)) mraid_pdrv_info_t; /** * mraid_inquiry_t - RAID inquiry, mailbox command 0x05 * @mraid_adapinfo_t : adapter information * @mraid_ldrv_info_t : logical drives information * @mraid_pdrv_info_t : physical drives information */ typedef struct { mraid_adapinfo_t adapter_info; mraid_ldrv_info_t logdrv_info; mraid_pdrv_info_t pdrv_info; } __attribute__ ((packed)) mraid_inquiry_t; /** * mraid_extinq_t - RAID extended inquiry, mailbox command 0x04 * * @raid_inq : raid inquiry * @phys_drv_format : * @stack_attn : * @modem_status : * @rsvd : */ typedef struct { mraid_inquiry_t raid_inq; uint16_t phys_drv_format[MAX_MBOX_CHANNELS]; uint8_t stack_attn; uint8_t modem_status; uint8_t rsvd[2]; } __attribute__ ((packed)) mraid_extinq_t; /** * adap_device_t - device information * @channel : channel fpor the device * @target : target ID of the device */ typedef struct { uint8_t channel; uint8_t target; }__attribute__ ((packed)) adap_device_t; /** * adap_span_40ld_t - 40LD span * @start_blk : starting block * @num_blks : number of blocks */ typedef struct { uint32_t start_blk; uint32_t num_blks; adap_device_t device[MAX_ROW_SIZE_40LD]; }__attribute__ ((packed)) adap_span_40ld_t; /** * adap_span_8ld_t - 8LD span * @start_blk : starting block * @num_blks : number of blocks */ typedef struct { uint32_t start_blk; uint32_t num_blks; adap_device_t device[MAX_ROW_SIZE_8LD]; }__attribute__ ((packed)) adap_span_8ld_t; /** * logdrv_param_t - logical drives parameters * * @span_depth : total number of spans * @level : RAID level * @read_ahead : read ahead, no read ahead, adaptive read ahead * @stripe_sz : encoded stripe size * @status : status of the logical drive * @write_mode : write mode, write_through/write_back * @direct_io : direct io or through cache * @row_size : number of stripes in a row */ typedef struct { uint8_t span_depth; uint8_t level; uint8_t read_ahead; uint8_t stripe_sz; uint8_t status; uint8_t write_mode; uint8_t direct_io; uint8_t row_size; } __attribute__ ((packed)) logdrv_param_t; /** * logdrv_40ld_t - logical drive definition for 40LD controllers * @lparam : logical drives parameters * @span : span */ typedef struct { logdrv_param_t lparam; adap_span_40ld_t span[SPAN_DEPTH_8_SPANS]; }__attribute__ ((packed)) logdrv_40ld_t; /** * logdrv_8ld_span8_t - logical drive definition for 8LD controllers * @lparam : logical drives parameters * @span : span * * 8-LD logical drive with upto 8 spans */ typedef struct { logdrv_param_t lparam; adap_span_8ld_t span[SPAN_DEPTH_8_SPANS]; }__attribute__ ((packed)) logdrv_8ld_span8_t; /** * logdrv_8ld_span4_t - logical drive definition for 8LD controllers * @lparam : logical drives parameters * @span : span * * 8-LD logical drive with upto 4 spans */ typedef struct { logdrv_param_t lparam; adap_span_8ld_t span[SPAN_DEPTH_4_SPANS]; }__attribute__ ((packed)) logdrv_8ld_span4_t; /** * phys_drive_t - physical device information * @type : Type of the device * @cur_status : current status of the device * @tag_depth : Level of tagging * @sync_neg : sync negotiation - ENABLE or DISBALE * @size : configurable size in terms of 512 byte */ typedef struct { uint8_t type; uint8_t cur_status; uint8_t tag_depth; uint8_t sync_neg; uint32_t size; }__attribute__ ((packed)) phys_drive_t; /** * disk_array_40ld_t - disk array for 40LD controllers * @numldrv : number of logical drives * @resvd : * @ldrv : logical drives information * @pdrv : physical drives information */ typedef struct { uint8_t numldrv; uint8_t resvd[3]; logdrv_40ld_t ldrv[MAX_LOGICAL_DRIVES_40LD]; phys_drive_t pdrv[MBOX_MAX_PHYSICAL_DRIVES]; }__attribute__ ((packed)) disk_array_40ld_t; /** * disk_array_8ld_span8_t - disk array for 8LD controllers * @numldrv : number of logical drives * @resvd : * @ldrv : logical drives information * @pdrv : physical drives information * * Disk array for 8LD logical drives with upto 8 spans */ typedef struct { uint8_t numldrv; uint8_t resvd[3]; logdrv_8ld_span8_t ldrv[MAX_LOGICAL_DRIVES_8LD]; phys_drive_t pdrv[MBOX_MAX_PHYSICAL_DRIVES]; }__attribute__ ((packed)) disk_array_8ld_span8_t; /** * disk_array_8ld_span4_t - disk array for 8LD controllers * @numldrv : number of logical drives * @resvd : * @ldrv : logical drives information * @pdrv : physical drives information * * Disk array for 8LD logical drives with upto 4 spans */ typedef struct { uint8_t numldrv; uint8_t resvd[3]; logdrv_8ld_span4_t ldrv[MAX_LOGICAL_DRIVES_8LD]; phys_drive_t pdrv[MBOX_MAX_PHYSICAL_DRIVES]; }__attribute__ ((packed)) disk_array_8ld_span4_t; /** * private_bios_data - bios private data for boot devices * @geometry : bits 0-3 - BIOS geometry, 0x0001 - 1GB, 0x0010 - 2GB, * 0x1000 - 8GB, Others values are invalid * @unused : bits 4-7 are unused * @boot_drv : logical drive set as boot drive, 0..7 - for 8LD cards, * 0..39 - for 40LD cards * @cksum : 0-(sum of first 13 bytes of this structure) */ struct private_bios_data { uint8_t geometry :4; uint8_t unused :4; uint8_t boot_drv; uint8_t rsvd[12]; uint16_t cksum; } __attribute__ ((packed)); /** * mbox_sgl64 - 64-bit scatter list for mailbox based controllers * @address : address of the buffer * @length : data transfer length */ typedef struct { uint64_t address; uint32_t length; } __attribute__ ((packed)) mbox_sgl64; /** * mbox_sgl32 - 32-bit scatter list for mailbox based controllers * @address : address of the buffer * @length : data transfer length */ typedef struct { uint32_t address; uint32_t length; } __attribute__ ((packed)) mbox_sgl32; #undef wait_event #define wait_event mraid_mm_diskdump_wait_event #undef wake_up #define wake_up mraid_mm_diskdump_wake_up extern void mraid_mm_diskdump_schedule(void); extern void mraid_mm_diskdump_wake_up(wait_queue_head_t *q); #define __mraid_mm_diskdump_wait_event(wq, condition) \ do { \ wait_queue_t __wait; \ init_waitqueue_entry(&__wait, current); \ \ add_wait_queue(&wq, &__wait); \ for (;;) { \ set_current_state(TASK_UNINTERRUPTIBLE); \ if (condition) \ break; \ mraid_mm_diskdump_schedule(); \ } \ current->state = TASK_RUNNING; \ remove_wait_queue(&wq, &__wait); \ } while (0) #define mraid_mm_diskdump_wait_event(wq, condition) \ do { \ if (condition) \ break; \ __mraid_mm_diskdump_wait_event(wq, condition); \ } while (0) #endif // _MRAID_MBOX_DEFS_H_ /* vim: set ts=8 sw=8 tw=78: */ megactl-0.4.5/kernel-2.6.9-55.0.2.EL/megaraid-2.20.4.6-rh2/mega_common.h000066400000000000000000000227101465722425200237060ustar00rootroot00000000000000/* * * Linux MegaRAID device driver * * Copyright (c) 2003-2004 LSI Logic Corporation. * * 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. * * FILE : mega_common.h * * Libaray of common routine used by all low-level megaraid drivers */ #ifndef _MEGA_COMMON_H_ #define _MEGA_COMMON_H_ #include #include #include #include #include #include #include #include #include #include #include #include #include #include #include #include #include #define LSI_MAX_CHANNELS 16 #define LSI_MAX_LOGICAL_DRIVES_64LD (64+1) #define HBA_SIGNATURE_64BIT 0x0299 #define PCI_CONF_AMISIG64 0xa4 /** * scb_t - scsi command control block * @param ccb : command control block for individual driver * @param list : list of control blocks * @param gp : general purpose field for LLDs * @param sno : all SCBs have a serial number * @param scp : associated scsi command * @param state : current state of scb * @param dma_dir : direction of data transfer * @param dma_type : transfer with sg list, buffer, or no data transfer * @param dev_channel : actual channel on the device * @param dev_target : actual target on the device * @param status : completion status * * This is our central data structure to issue commands the each driver. * Driver specific data structures are maintained in the ccb field. * scb provides a field 'gp', which can be used by LLD for its own purposes * * dev_channel and dev_target must be initialized with the actual channel and * target on the controller. */ typedef struct { caddr_t ccb; struct list_head list; unsigned long gp; unsigned int sno; struct scsi_cmnd *scp; uint32_t state; uint32_t dma_direction; uint32_t dma_type; uint16_t dev_channel; uint16_t dev_target; uint32_t status; } scb_t; /* * SCB states as it transitions from one state to another */ #define SCB_FREE 0x0000 /* on the free list */ #define SCB_ACTIVE 0x0001 /* off the free list */ #define SCB_PENDQ 0x0002 /* on the pending queue */ #define SCB_ISSUED 0x0004 /* issued - owner f/w */ #define SCB_ABORT 0x0008 /* Got an abort for this one */ #define SCB_RESET 0x0010 /* Got a reset for this one */ /* * DMA types for scb */ #define MRAID_DMA_NONE 0x0000 /* no data transfer for this command */ #define MRAID_DMA_WSG 0x0001 /* data transfer using a sg list */ #define MRAID_DMA_WBUF 0x0002 /* data transfer using a contiguous buffer */ /** * struct adapter_t - driver's initialization structure * @param dpc_h : tasklet handle * @param pdev : pci configuration pointer for kernel * @param host : pointer to host structure of mid-layer * @param host_lock : pointer to appropriate lock * @param lock : synchronization lock for mid-layer and driver * @param quiescent : driver is quiescent for now. * @param outstanding_cmds : number of commands pending in the driver * @param kscb_list : pointer to the bulk of SCBs pointers for IO * @param kscb_pool : pool of free scbs for IO * @param kscb_pool_lock : lock for pool of free scbs * @param pend_list : pending commands list * @param pend_list_lock : exlusion lock for pending commands list * @param completed_list : list of completed commands * @param completed_list_lock : exclusion lock for list of completed commands * @param sglen : max sg elements supported * @param device_ids : to convert kernel device addr to our devices. * @param raid_device : raid adapter specific pointer * @param max_channel : maximum channel number supported - inclusive * @param max_target : max target supported - inclusive * @param max_lun : max lun supported - inclusive * @param unique_id : unique identifier for each adapter * @param irq : IRQ for this adapter * @param ito : internal timeout value, (-1) means no timeout * @param ibuf : buffer to issue internal commands * @param ibuf_dma_h : dma handle for the above buffer * @param uscb_list : SCB pointers for user cmds, common mgmt module * @param uscb_pool : pool of SCBs for user commands * @param uscb_pool_lock : exclusion lock for these SCBs * @param max_cmds : max outstanding commands * @param fw_version : firmware version * @param bios_version : bios version * @param max_cdb_sz : biggest CDB size supported. * @param ha : is high availability present - clustering * @param init_id : initiator ID, the default value should be 7 * @param max_sectors : max sectors per request * @param cmd_per_lun : max outstanding commands per LUN * @param being_detached : set when unloading, no more mgmt calls * * * mraid_setup_device_map() can be called anytime after the device map is * available and MRAID_GET_DEVICE_MAP() can be called whenever the mapping is * required, usually from LLD's queue entry point. The formar API sets up the * MRAID_IS_LOGICAL(adapter_t *, struct scsi_cmnd *) to find out if the * device in question is a logical drive. * * quiescent flag should be set by the driver if it is not accepting more * commands * * NOTE: The fields of this structures are placed to minimize cache misses */ // amount of space required to store the bios and firmware version strings #define VERSION_SIZE 16 typedef struct { struct tasklet_struct dpc_h; struct pci_dev *pdev; struct Scsi_Host *host; spinlock_t *host_lock; spinlock_t lock; uint8_t quiescent; int outstanding_cmds; scb_t *kscb_list; struct list_head kscb_pool; spinlock_t kscb_pool_lock; struct list_head pend_list; spinlock_t pend_list_lock; struct list_head completed_list; spinlock_t completed_list_lock; uint16_t sglen; int device_ids[LSI_MAX_CHANNELS] [LSI_MAX_LOGICAL_DRIVES_64LD]; caddr_t raid_device; uint8_t max_channel; uint16_t max_target; uint8_t max_lun; uint32_t unique_id; uint8_t irq; uint8_t ito; caddr_t ibuf; dma_addr_t ibuf_dma_h; scb_t *uscb_list; struct list_head uscb_pool; spinlock_t uscb_pool_lock; int max_cmds; uint8_t fw_version[VERSION_SIZE]; uint8_t bios_version[VERSION_SIZE]; uint8_t max_cdb_sz; uint8_t ha; uint16_t init_id; uint16_t max_sectors; uint16_t cmd_per_lun; atomic_t being_detached; } adapter_t; #define SCSI_FREE_LIST_LOCK(adapter) (&adapter->kscb_pool_lock) #define USER_FREE_LIST_LOCK(adapter) (&adapter->uscb_pool_lock) #define PENDING_LIST_LOCK(adapter) (&adapter->pend_list_lock) #define COMPLETED_LIST_LOCK(adapter) (&adapter->completed_list_lock) // conversion from scsi command #define SCP2HOST(scp) (scp)->device->host // to host #define SCP2HOSTDATA(scp) SCP2HOST(scp)->hostdata // to soft state #define SCP2CHANNEL(scp) (scp)->device->channel // to channel #define SCP2TARGET(scp) (scp)->device->id // to target #define SCP2LUN(scp) (scp)->device->lun // to LUN // generic macro to convert scsi command and host to controller's soft state #define SCSIHOST2ADAP(host) (((caddr_t *)(host->hostdata))[0]) #define SCP2ADAPTER(scp) (adapter_t *)SCSIHOST2ADAP(SCP2HOST(scp)) /** * MRAID_GET_DEVICE_MAP - device ids * @param adp - Adapter's soft state * @param scp - mid-layer scsi command pointer * @param p_chan - physical channel on the controller * @param target - target id of the device or logical drive number * @param islogical - set if the command is for the logical drive * * Macro to retrieve information about device class, logical or physical and * the corresponding physical channel and target or logical drive number **/ #define MRAID_IS_LOGICAL(adp, scp) \ (SCP2CHANNEL(scp) == (adp)->max_channel) ? 1 : 0 #define MRAID_IS_LOGICAL_SDEV(adp, sdev) \ (sdev->channel == (adp)->max_channel) ? 1 : 0 #define MRAID_GET_DEVICE_MAP(adp, scp, p_chan, target, islogical) \ /* \ * Is the request coming for the virtual channel \ */ \ islogical = MRAID_IS_LOGICAL(adp, scp); \ \ /* \ * Get an index into our table of drive ids mapping \ */ \ if (islogical) { \ p_chan = 0xFF; \ target = \ (adp)->device_ids[(adp)->max_channel][SCP2TARGET(scp)]; \ } \ else { \ p_chan = ((adp)->device_ids[SCP2CHANNEL(scp)] \ [SCP2TARGET(scp)] >> 8) & 0xFF; \ target = ((adp)->device_ids[SCP2CHANNEL(scp)] \ [SCP2TARGET(scp)] & 0xFF); \ } /* * ### Helper routines ### */ #define LSI_DBGLVL mraid_debug_level // each LLD must define a global // mraid_debug_level #ifdef DEBUG #if defined (_ASSERT_PANIC) #define ASSERT_ACTION panic #else #define ASSERT_ACTION printk #endif #define ASSERT(expression) \ if (!(expression)) { \ ASSERT_ACTION("assertion failed:(%s), file: %s, line: %d:%s\n", \ #expression, __FILE__, __LINE__, __FUNCTION__); \ } #else #define ASSERT(expression) #endif /* * struct mraid_pci_blk - structure holds DMA memory block info * @param vaddr : virtual address to a memory block * @param dma_addr : DMA handle to a memory block * * This structure is filled up for the caller. It is the responsibilty of the * caller to allocate this array big enough to store addresses for all * requested elements */ struct mraid_pci_blk { caddr_t vaddr; dma_addr_t dma_addr; }; #endif // _MEGA_COMMON_H_ // vim: set ts=8 sw=8 tw=78: megactl-0.4.5/kernel-2.6.9-55.0.2.EL/megaraid-2.20.4.6-rh2/megaraid_ioctl.h000066400000000000000000000205371465722425200243750ustar00rootroot00000000000000/* * * Linux MegaRAID device driver * * Copyright (c) 2003-2004 LSI Logic Corporation. * * 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. * * FILE : megaraid_ioctl.h * * Definitions to interface with user level applications */ #ifndef _MEGARAID_IOCTL_H_ #define _MEGARAID_IOCTL_H_ #include #include #include "mbox_defs.h" /** * con_log() - console log routine * @param level : indicates the severity of the message. * @fparam mt : format string * * con_log displays the error messages on the console based on the current * debug level. Also it attaches the appropriate kernel severity level with * the message. * * * consolge messages debug levels */ #define CL_ANN 0 /* print unconditionally, announcements */ #define CL_DLEVEL1 1 /* debug level 1, informative */ #define CL_DLEVEL2 2 /* debug level 2, verbose */ #define CL_DLEVEL3 3 /* debug level 3, very verbose */ #define con_log(level, fmt) if (LSI_DBGLVL >= level) printk fmt; /* * Definitions & Declarations needed to use common management module */ #define MEGAIOC_MAGIC 'm' #define MEGAIOCCMD _IOWR(MEGAIOC_MAGIC, 0, mimd_t) #define MEGAIOC_QNADAP 'm' /* Query # of adapters */ #define MEGAIOC_QDRVRVER 'e' /* Query driver version */ #define MEGAIOC_QADAPINFO 'g' /* Query adapter information */ #define USCSICMD 0x80 #define UIOC_RD 0x00001 #define UIOC_WR 0x00002 #define MBOX_CMD 0x00000 #define GET_DRIVER_VER 0x10000 #define GET_N_ADAP 0x20000 #define GET_ADAP_INFO 0x30000 #define GET_CAP 0x40000 #define GET_STATS 0x50000 #define GET_IOCTL_VERSION 0x01 #define EXT_IOCTL_SIGN_SZ 16 #define EXT_IOCTL_SIGN "$$_EXTD_IOCTL_$$" #define MBOX_LEGACY 0x00 /* ioctl has legacy mbox*/ #define MBOX_HPE 0x01 /* ioctl has hpe mbox */ #define APPTYPE_MIMD 0x00 /* old existing apps */ #define APPTYPE_UIOC 0x01 /* new apps using uioc */ #define IOCTL_ISSUE 0x00000001 /* Issue ioctl */ #define IOCTL_ABORT 0x00000002 /* Abort previous ioctl */ #define DRVRTYPE_MBOX 0x00000001 /* regular mbox driver */ #define DRVRTYPE_HPE 0x00000002 /* new hpe driver */ #define MKADAP(adapno) (MEGAIOC_MAGIC << 8 | (adapno) ) #define GETADAP(mkadap) ((mkadap) ^ MEGAIOC_MAGIC << 8) #define MAX_DMA_POOLS 5 /* 4k, 8k, 16k, 32k, 64k*/ /** * struct uioc_t - the common ioctl packet structure * * @signature : Must be "$$_EXTD_IOCTL_$$" * @mb_type : Type of the mail box (MB_LEGACY or MB_HPE) * @app_type : Type of the issuing application (existing or new) * @opcode : Opcode of the command * @adapno : Adapter number * @cmdbuf : Pointer to buffer - can point to mbox or plain data buffer * @xferlen : xferlen for DCMD and non mailbox commands * @data_dir : Direction of the data transfer * @status : Status from the driver * @reserved : reserved bytes for future expansion * * @user_data : user data transfer address is saved in this * @user_data_len: length of the data buffer sent by user app * @user_pthru : user passthru address is saves in this (null if DCMD) * @pthru32 : kernel address passthru (allocated per kioc) * @pthru32_h : physicall address of @pthru32 * @list : for kioc free pool list maintenance * @done : call back routine for llds to call when kioc is completed * @buf_vaddr : dma pool buffer attached to kioc for data transfer * @buf_paddr : physical address of the dma pool buffer * @pool_index : index of the dma pool that @buf_vaddr is taken from * @free_buf : indicates if buffer needs to be freed after kioc completes * * Note : All LSI drivers understand only this packet. Any other * : format sent by applications would be converted to this. */ typedef struct uioc { /* User Apps: */ uint8_t signature[EXT_IOCTL_SIGN_SZ]; uint16_t mb_type; uint16_t app_type; uint32_t opcode; uint32_t adapno; uint64_t cmdbuf; uint32_t xferlen; uint32_t data_dir; int32_t status; uint8_t reserved[128]; /* Driver Data: */ void __user * user_data; uint32_t user_data_len; /* 64bit alignment */ uint32_t pad_for_64bit_align; mraid_passthru_t __user *user_pthru; mraid_passthru_t *pthru32; dma_addr_t pthru32_h; struct list_head list; void (*done)(struct uioc*); caddr_t buf_vaddr; dma_addr_t buf_paddr; int8_t pool_index; uint8_t free_buf; uint8_t timedout; } __attribute__ ((aligned(1024),packed)) uioc_t; /** * struct mraid_hba_info - information about the controller * * @param pci_vendor_id : PCI vendor id * @param pci_device_id : PCI device id * @param subsystem_vendor_id : PCI subsystem vendor id * @param subsystem_device_id : PCI subsystem device id * @param baseport : base port of hba memory * @param pci_bus : PCI bus * @param pci_dev_fn : PCI device/function values * @param irq : interrupt vector for the device * * Extended information of 256 bytes about the controller. Align on the single * byte boundary so that 32-bit applications can be run on 64-bit platform * drivers withoug re-compilation. * NOTE: reduce the number of reserved bytes whenever new field are added, so * that total size of the structure remains 256 bytes. */ typedef struct mraid_hba_info { uint16_t pci_vendor_id; uint16_t pci_device_id; uint16_t subsys_vendor_id; uint16_t subsys_device_id; uint64_t baseport; uint8_t pci_bus; uint8_t pci_dev_fn; uint8_t pci_slot; uint8_t irq; uint32_t unique_id; uint32_t host_no; uint8_t num_ldrv; } __attribute__ ((aligned(256), packed)) mraid_hba_info_t; /** * mcontroller : adapter info structure for old mimd_t apps * * @base : base address * @irq : irq number * @numldrv : number of logical drives * @pcibus : pci bus * @pcidev : pci device * @pcifun : pci function * @pciid : pci id * @pcivendor : vendor id * @pcislot : slot number * @uid : unique id */ typedef struct mcontroller { uint64_t base; uint8_t irq; uint8_t numldrv; uint8_t pcibus; uint16_t pcidev; uint8_t pcifun; uint16_t pciid; uint16_t pcivendor; uint8_t pcislot; uint32_t uid; } __attribute__ ((packed)) mcontroller_t; /** * mm_dmapool_t : Represents one dma pool with just one buffer * * @vaddr : Virtual address * @paddr : DMA physicall address * @bufsize : In KB - 4 = 4k, 8 = 8k etc. * @handle : Handle to the dma pool * @lock : lock to synchronize access to the pool * @in_use : If pool already in use, attach new block */ typedef struct mm_dmapool { caddr_t vaddr; dma_addr_t paddr; uint32_t buf_size; struct dma_pool *handle; spinlock_t lock; uint8_t in_use; } mm_dmapool_t; /** * mraid_mmadp_t: Structure that drivers pass during (un)registration * * @unique_id : Any unique id (usually PCI bus+dev+fn) * @drvr_type : megaraid or hpe (DRVRTYPE_MBOX or DRVRTYPE_HPE) * @drv_data : Driver specific; not touched by the common module * @timeout : timeout for issued kiocs * @max_kioc : Maximum ioctl packets acceptable by the lld * @pdev : pci dev; used for allocating dma'ble memory * @issue_uioc : Driver supplied routine to issue uioc_t commands * : issue_uioc(drvr_data, kioc, ISSUE/ABORT, uioc_done) * @quiescent : flag to indicate if ioctl can be issued to this adp * @list : attach with the global list of adapters * @kioc_list : block of mem for @max_kioc number of kiocs * @kioc_pool : pool of free kiocs * @kioc_pool_lock : protection for free pool * @kioc_semaphore : so as not to exceed @max_kioc parallel ioctls * @mbox_list : block of mem for @max_kioc number of mboxes * @pthru_dma_pool : DMA pool to allocate passthru packets * @dma_pool_list : array of dma pools */ typedef struct mraid_mmadp { /* Filled by driver */ uint32_t unique_id; uint32_t drvr_type; unsigned long drvr_data; uint16_t timeout; uint8_t max_kioc; struct pci_dev *pdev; int(*issue_uioc)(unsigned long, uioc_t *, uint32_t); /* Maintained by common module */ uint32_t quiescent; struct list_head list; uioc_t *kioc_list; struct list_head kioc_pool; spinlock_t kioc_pool_lock; struct semaphore kioc_semaphore; mbox64_t *mbox_list; struct dma_pool *pthru_dma_pool; mm_dmapool_t dma_pool_list[MAX_DMA_POOLS]; } mraid_mmadp_t; int mraid_mm_register_adp(mraid_mmadp_t *); int mraid_mm_unregister_adp(uint32_t); uint32_t mraid_mm_adapter_app_handle(uint32_t); #endif /* _MEGARAID_IOCTL_H_ */ megactl-0.4.5/kernel-2.6.9-55.0.2.EL/megaraid-2.20.4.6-rh2/megaraid_mbox.c000066400000000000000000003166331465722425200242300ustar00rootroot00000000000000/* * * Linux MegaRAID device driver * * Copyright (c) 2003-2004 LSI Logic Corporation. * * 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. * * FILE : megaraid_mbox.c * Version : v2.20.4.6-rh2 (Jun 28 2006) * * Authors: * Atul Mukker * Sreenivas Bagalkote * Manoj Jose * * List of supported controllers * * OEM Product Name VID DID SSVID SSID * --- ------------ --- --- ---- ---- * Dell PERC3/QC 101E 1960 1028 0471 * Dell PERC3/DC 101E 1960 1028 0493 * Dell PERC3/SC 101E 1960 1028 0475 * Dell PERC3/Di 1028 1960 1028 0123 * Dell PERC4/SC 1000 1960 1028 0520 * Dell PERC4/DC 1000 1960 1028 0518 * Dell PERC4/QC 1000 0407 1028 0531 * Dell PERC4/Di 1028 000F 1028 014A * Dell PERC 4e/Si 1028 0013 1028 016c * Dell PERC 4e/Di 1028 0013 1028 016d * Dell PERC 4e/Di 1028 0013 1028 016e * Dell PERC 4e/Di 1028 0013 1028 016f * Dell PERC 4e/Di 1028 0013 1028 0170 * Dell PERC 4e/DC 1000 0408 1028 0002 * Dell PERC 4e/SC 1000 0408 1028 0001 * * * LSI MegaRAID SCSI 320-0 1000 1960 1000 A520 * LSI MegaRAID SCSI 320-1 1000 1960 1000 0520 * LSI MegaRAID SCSI 320-2 1000 1960 1000 0518 * LSI MegaRAID SCSI 320-0X 1000 0407 1000 0530 * LSI MegaRAID SCSI 320-2X 1000 0407 1000 0532 * LSI MegaRAID SCSI 320-4X 1000 0407 1000 0531 * LSI MegaRAID SCSI 320-1E 1000 0408 1000 0001 * LSI MegaRAID SCSI 320-2E 1000 0408 1000 0002 * LSI MegaRAID SATA 150-4 1000 1960 1000 4523 * LSI MegaRAID SATA 150-6 1000 1960 1000 0523 * LSI MegaRAID SATA 300-4X 1000 0409 1000 3004 * LSI MegaRAID SATA 300-8X 1000 0409 1000 3008 * * INTEL RAID Controller SRCU42X 1000 0407 8086 0532 * INTEL RAID Controller SRCS16 1000 1960 8086 0523 * INTEL RAID Controller SRCU42E 1000 0408 8086 0002 * INTEL RAID Controller SRCZCRX 1000 0407 8086 0530 * INTEL RAID Controller SRCS28X 1000 0409 8086 3008 * INTEL RAID Controller SROMBU42E 1000 0408 8086 3431 * INTEL RAID Controller SROMBU42E 1000 0408 8086 3499 * INTEL RAID Controller SRCU51L 1000 1960 8086 0520 * * FSC MegaRAID PCI Express ROMB 1000 0408 1734 1065 * * ACER MegaRAID ROMB-2E 1000 0408 1025 004D * * NEC MegaRAID PCI Express ROMB 1000 0408 1033 8287 * * For history of changes, see Documentation/ChangeLog.megaraid */ #include "megaraid_mbox.h" #undef msleep #define msleep(X) \ if (crashdump_mode()) { \ megaraid_diskdump_sleep(X); \ } else { \ msleep(X); \ } static int megaraid_init(void); static void megaraid_exit(void); static int megaraid_probe_one(struct pci_dev*, const struct pci_device_id *); static void megaraid_detach_one(struct pci_dev *); static void megaraid_mbox_shutdown(struct device *); static int megaraid_io_attach(adapter_t *); static void megaraid_io_detach(adapter_t *); static int megaraid_init_mbox(adapter_t *); static void megaraid_fini_mbox(adapter_t *); static int megaraid_alloc_cmd_packets(adapter_t *); static void megaraid_free_cmd_packets(adapter_t *); static int megaraid_mbox_setup_dma_pools(adapter_t *); static void megaraid_mbox_teardown_dma_pools(adapter_t *); static int megaraid_sysfs_alloc_resources(adapter_t *); static void megaraid_sysfs_free_resources(adapter_t *); static int megaraid_abort_handler(struct scsi_cmnd *); static int megaraid_reset_handler(struct scsi_cmnd *); static int mbox_post_sync_cmd(adapter_t *, uint8_t []); static int mbox_post_sync_cmd_fast(adapter_t *, uint8_t []); static int megaraid_busywait_mbox(mraid_device_t *); static int megaraid_mbox_product_info(adapter_t *); static int megaraid_mbox_extended_cdb(adapter_t *); static int megaraid_mbox_support_ha(adapter_t *, uint16_t *); static int megaraid_mbox_support_random_del(adapter_t *); static int megaraid_mbox_get_max_sg(adapter_t *); static void megaraid_mbox_enum_raid_scsi(adapter_t *); static void megaraid_mbox_flush_cache(adapter_t *); static void megaraid_mbox_display_scb(adapter_t *, scb_t *); static void megaraid_mbox_setup_device_map(adapter_t *); static int megaraid_queue_command(struct scsi_cmnd *, void (*)(struct scsi_cmnd *)); static scb_t *megaraid_mbox_build_cmd(adapter_t *, struct scsi_cmnd *, int *); static void megaraid_mbox_runpendq(adapter_t *, scb_t *); static void megaraid_mbox_prepare_pthru(adapter_t *, scb_t *, struct scsi_cmnd *); static void megaraid_mbox_prepare_epthru(adapter_t *, scb_t *, struct scsi_cmnd *); static irqreturn_t megaraid_isr(int, void *, struct pt_regs *); static void megaraid_mbox_dpc(unsigned long); static ssize_t megaraid_sysfs_show_app_hndl(struct class_device *, char *); static ssize_t megaraid_sysfs_show_ldnum(struct device *, char *); static int megaraid_cmm_register(adapter_t *); static int megaraid_cmm_unregister(adapter_t *); static int megaraid_mbox_mm_handler(unsigned long, uioc_t *, uint32_t); static int megaraid_mbox_mm_command(adapter_t *, uioc_t *); static void megaraid_mbox_mm_done(adapter_t *, scb_t *); static int gather_hbainfo(adapter_t *, mraid_hba_info_t *); static int wait_till_fw_empty(adapter_t *); static int megaraid_sanity_check(struct scsi_device *device); static int megaraid_quiesce(struct scsi_device *device); static void megaraid_poll(struct scsi_device *device); static void megaraid_diskdump_sleep(unsigned int timeout); extern int mraid_mm_woken; MODULE_AUTHOR("LSI Logic Corporation"); MODULE_DESCRIPTION("LSI Logic MegaRAID Mailbox Driver"); MODULE_LICENSE("GPL"); MODULE_VERSION(MEGARAID_VERSION); /* * ### modules parameters for driver ### */ /** * Set to enable driver to expose unconfigured disk to kernel */ static int megaraid_expose_unconf_disks = 0; module_param_named(unconf_disks, megaraid_expose_unconf_disks, int, 0); MODULE_PARM_DESC(unconf_disks, "Set to expose unconfigured disks to kernel (default=0)"); /** * driver wait time if the adapter's mailbox is busy */ static unsigned int max_mbox_busy_wait = MBOX_BUSY_WAIT; module_param_named(busy_wait, max_mbox_busy_wait, int, 0); MODULE_PARM_DESC(busy_wait, "Max wait for mailbox in microseconds if busy (default=10)"); /** * number of sectors per IO command */ static unsigned int megaraid_max_sectors = MBOX_MAX_SECTORS; module_param_named(max_sectors, megaraid_max_sectors, int, 0); MODULE_PARM_DESC(max_sectors, "Maximum number of sectors per IO command (default=128)"); /** * number of commands per logical unit */ static unsigned int megaraid_cmd_per_lun = MBOX_DEF_CMD_PER_LUN; module_param_named(cmd_per_lun, megaraid_cmd_per_lun, int, 0); MODULE_PARM_DESC(cmd_per_lun, "Maximum number of commands per logical unit (default=64)"); /** * Fast driver load option, skip scanning for physical devices during load. * This would result in non-disk devices being skipped during driver load * time. These can be later added though, using /proc/scsi/scsi */ static unsigned int megaraid_fast_load = 0; module_param_named(fast_load, megaraid_fast_load, int, 0); MODULE_PARM_DESC(fast_load, "Faster loading of the driver, skips physical devices! (default=0)"); /** * mraid_debug level - threshold for amount of information to be displayed by * the driver. This level can be changed through modules parameters, ioctl or * sysfs/proc interface. By default, print the announcement messages only. */ int mraid_debug_level = CL_ANN; module_param_named(debug_level, mraid_debug_level, int, 0); MODULE_PARM_DESC(debug_level, "Debug level for driver (default=0)"); /* * ### global data ### */ static uint8_t megaraid_mbox_version[8] = { 0x02, 0x20, 0x04, 0x06, 3, 7, 20, 5 }; /* * PCI table for all supported controllers. */ static struct pci_device_id pci_id_table_g[] = { { PCI_VENDOR_ID_DELL, PCI_DEVICE_ID_PERC4_DI_DISCOVERY, PCI_VENDOR_ID_DELL, PCI_SUBSYS_ID_PERC4_DI_DISCOVERY, }, { PCI_VENDOR_ID_LSI_LOGIC, PCI_DEVICE_ID_PERC4_SC, PCI_VENDOR_ID_DELL, PCI_SUBSYS_ID_PERC4_SC, }, { PCI_VENDOR_ID_LSI_LOGIC, PCI_DEVICE_ID_PERC4_DC, PCI_VENDOR_ID_DELL, PCI_SUBSYS_ID_PERC4_DC, }, { PCI_VENDOR_ID_LSI_LOGIC, PCI_DEVICE_ID_VERDE, PCI_ANY_ID, PCI_ANY_ID, }, { PCI_VENDOR_ID_DELL, PCI_DEVICE_ID_PERC4_DI_EVERGLADES, PCI_VENDOR_ID_DELL, PCI_SUBSYS_ID_PERC4_DI_EVERGLADES, }, { PCI_VENDOR_ID_DELL, PCI_DEVICE_ID_PERC4E_SI_BIGBEND, PCI_VENDOR_ID_DELL, PCI_SUBSYS_ID_PERC4E_SI_BIGBEND, }, { PCI_VENDOR_ID_DELL, PCI_DEVICE_ID_PERC4E_DI_KOBUK, PCI_VENDOR_ID_DELL, PCI_SUBSYS_ID_PERC4E_DI_KOBUK, }, { PCI_VENDOR_ID_DELL, PCI_DEVICE_ID_PERC4E_DI_CORVETTE, PCI_VENDOR_ID_DELL, PCI_SUBSYS_ID_PERC4E_DI_CORVETTE, }, { PCI_VENDOR_ID_DELL, PCI_DEVICE_ID_PERC4E_DI_EXPEDITION, PCI_VENDOR_ID_DELL, PCI_SUBSYS_ID_PERC4E_DI_EXPEDITION, }, { PCI_VENDOR_ID_DELL, PCI_DEVICE_ID_PERC4E_DI_GUADALUPE, PCI_VENDOR_ID_DELL, PCI_SUBSYS_ID_PERC4E_DI_GUADALUPE, }, { PCI_VENDOR_ID_LSI_LOGIC, PCI_DEVICE_ID_DOBSON, PCI_ANY_ID, PCI_ANY_ID, }, { PCI_VENDOR_ID_AMI, PCI_DEVICE_ID_AMI_MEGARAID3, PCI_VENDOR_ID_DELL, PCI_SUBSYS_ID_PERC3_QC, }, { PCI_VENDOR_ID_AMI, PCI_DEVICE_ID_AMI_MEGARAID3, PCI_VENDOR_ID_DELL, PCI_SUBSYS_ID_PERC3_DC, }, { PCI_VENDOR_ID_AMI, PCI_DEVICE_ID_AMI_MEGARAID3, PCI_VENDOR_ID_DELL, PCI_SUBSYS_ID_PERC3_SC, }, { PCI_VENDOR_ID_AMI, PCI_DEVICE_ID_AMI_MEGARAID3, PCI_VENDOR_ID_AMI, PCI_SUBSYS_ID_PERC3_SC, }, { PCI_VENDOR_ID_AMI, PCI_DEVICE_ID_AMI_MEGARAID3, PCI_VENDOR_ID_AMI, PCI_SUBSYS_ID_PERC3_DC, }, { PCI_VENDOR_ID_LSI_LOGIC, PCI_DEVICE_ID_MEGARAID_SCSI_320_0, PCI_VENDOR_ID_LSI_LOGIC, PCI_SUBSYS_ID_MEGARAID_SCSI_320_0, }, { PCI_VENDOR_ID_LSI_LOGIC, PCI_DEVICE_ID_MEGARAID_SCSI_320_1, PCI_VENDOR_ID_LSI_LOGIC, PCI_SUBSYS_ID_MEGARAID_SCSI_320_1, }, { PCI_VENDOR_ID_LSI_LOGIC, PCI_DEVICE_ID_MEGARAID_SCSI_320_2, PCI_VENDOR_ID_LSI_LOGIC, PCI_SUBSYS_ID_MEGARAID_SCSI_320_2, }, { PCI_VENDOR_ID_LSI_LOGIC, PCI_DEVICE_ID_MEGARAID_I4_133_RAID, PCI_VENDOR_ID_LSI_LOGIC, PCI_SUBSYS_ID_MEGARAID_I4_133_RAID, }, { PCI_VENDOR_ID_LSI_LOGIC, PCI_DEVICE_ID_MEGARAID_SATA_150_4, PCI_VENDOR_ID_LSI_LOGIC, PCI_SUBSYS_ID_MEGARAID_SATA_150_4, }, { PCI_VENDOR_ID_LSI_LOGIC, PCI_DEVICE_ID_MEGARAID_SATA_150_6, PCI_VENDOR_ID_LSI_LOGIC, PCI_SUBSYS_ID_MEGARAID_SATA_150_6, }, { PCI_VENDOR_ID_LSI_LOGIC, PCI_DEVICE_ID_LINDSAY, PCI_ANY_ID, PCI_ANY_ID, }, { PCI_VENDOR_ID_LSI_LOGIC, PCI_DEVICE_ID_INTEL_RAID_SRCS16, PCI_VENDOR_ID_INTEL, PCI_SUBSYS_ID_INTEL_RAID_SRCS16, }, { PCI_VENDOR_ID_LSI_LOGIC, PCI_DEVICE_ID_INTEL_RAID_SRCU41L_LAKE_SHETEK, PCI_VENDOR_ID_INTEL, PCI_SUBSYS_ID_INTEL_RAID_SRCU41L_LAKE_SHETEK, }, {0} /* Terminating entry */ }; MODULE_DEVICE_TABLE(pci, pci_id_table_g); static struct pci_driver megaraid_pci_driver_g = { .name = "megaraid", .id_table = pci_id_table_g, .probe = megaraid_probe_one, .remove = __devexit_p(megaraid_detach_one), .driver = { .shutdown = megaraid_mbox_shutdown, } }; // definitions for the device attributes for exporting logical drive number // for a scsi address (Host, Channel, Id, Lun) CLASS_DEVICE_ATTR(megaraid_mbox_app_hndl, S_IRUSR, megaraid_sysfs_show_app_hndl, NULL); // Host template initializer for megaraid mbox sysfs device attributes static struct class_device_attribute *megaraid_shost_attrs[] = { &class_device_attr_megaraid_mbox_app_hndl, NULL, }; DEVICE_ATTR(megaraid_mbox_ld, S_IRUSR, megaraid_sysfs_show_ldnum, NULL); // Host template initializer for megaraid mbox sysfs device attributes static struct device_attribute *megaraid_sdev_attrs[] = { &dev_attr_megaraid_mbox_ld, NULL, }; /* * Scsi host template for megaraid unified driver */ static struct scsi_host_template megaraid_template_g = { .module = THIS_MODULE, .name = "LSI Logic MegaRAID driver", .proc_name = "megaraid", .queuecommand = megaraid_queue_command, .eh_abort_handler = megaraid_abort_handler, .eh_device_reset_handler = megaraid_reset_handler, .eh_bus_reset_handler = megaraid_reset_handler, .eh_host_reset_handler = megaraid_reset_handler, .use_clustering = ENABLE_CLUSTERING, .sdev_attrs = megaraid_sdev_attrs, .shost_attrs = megaraid_shost_attrs, .dump_sanity_check = megaraid_sanity_check, .dump_quiesce = megaraid_quiesce, .dump_poll = megaraid_poll, }; /** * megaraid_init - module load hook * * We register ourselves as hotplug enabled module and let PCI subsystem * discover our adaters **/ static int __init megaraid_init(void) { int rval; // Announce the driver version con_log(CL_ANN, (KERN_INFO "megaraid: %s %s\n", MEGARAID_VERSION, MEGARAID_EXT_VERSION)); // check validity of module parameters if (megaraid_cmd_per_lun > MBOX_MAX_SCSI_CMDS) { con_log(CL_ANN, (KERN_WARNING "megaraid mailbox: max commands per lun reset to %d\n", MBOX_MAX_SCSI_CMDS)); megaraid_cmd_per_lun = MBOX_MAX_SCSI_CMDS; } // register as a PCI hot-plug driver module rval = pci_register_driver(&megaraid_pci_driver_g); if (rval < 0) { con_log(CL_ANN, (KERN_WARNING "megaraid: could not register hotplug support.\n")); } return rval; } /** * megaraid_exit - driver unload entry point * * We simply unwrap the megaraid_init routine here */ static void __exit megaraid_exit(void) { con_log(CL_DLEVEL1, (KERN_NOTICE "megaraid: unloading framework\n")); // unregister as PCI hotplug driver pci_unregister_driver(&megaraid_pci_driver_g); return; } /** * megaraid_probe_one - PCI hotplug entry point * @param pdev : handle to this controller's PCI configuration space * @param id : pci device id of the class of controllers * * This routine should be called whenever a new adapter is detected by the * PCI hotplug susbsytem. **/ static int __devinit megaraid_probe_one(struct pci_dev *pdev, const struct pci_device_id *id) { adapter_t *adapter; // detected a new controller con_log(CL_ANN, (KERN_INFO "megaraid: probe new device %#4.04x:%#4.04x:%#4.04x:%#4.04x: ", pdev->vendor, pdev->device, pdev->subsystem_vendor, pdev->subsystem_device)); con_log(CL_ANN, ("bus %d:slot %d:func %d\n", pdev->bus->number, PCI_SLOT(pdev->devfn), PCI_FUNC(pdev->devfn))); if (pci_enable_device(pdev)) { con_log(CL_ANN, (KERN_WARNING "megaraid: pci_enable_device failed\n")); return -ENODEV; } // Enable bus-mastering on this controller pci_set_master(pdev); // Allocate the per driver initialization structure adapter = kmalloc(sizeof(adapter_t), GFP_KERNEL); if (adapter == NULL) { con_log(CL_ANN, (KERN_WARNING "megaraid: out of memory, %s %d.\n", __FUNCTION__, __LINE__)); goto out_probe_one; } memset(adapter, 0, sizeof(adapter_t)); // set up PCI related soft state and other pre-known parameters adapter->unique_id = pdev->bus->number << 8 | pdev->devfn; adapter->irq = pdev->irq; adapter->pdev = pdev; atomic_set(&adapter->being_detached, 0); // Setup the default DMA mask. This would be changed later on // depending on hardware capabilities if (pci_set_dma_mask(adapter->pdev, DMA_32BIT_MASK) != 0) { con_log(CL_ANN, (KERN_WARNING "megaraid: pci_set_dma_mask failed:%d\n", __LINE__)); goto out_free_adapter; } // Initialize the synchronization lock for kernel and LLD spin_lock_init(&adapter->lock); adapter->host_lock = &adapter->lock; // Initialize the command queues: the list of free SCBs and the list // of pending SCBs. INIT_LIST_HEAD(&adapter->kscb_pool); spin_lock_init(SCSI_FREE_LIST_LOCK(adapter)); INIT_LIST_HEAD(&adapter->pend_list); spin_lock_init(PENDING_LIST_LOCK(adapter)); INIT_LIST_HEAD(&adapter->completed_list); spin_lock_init(COMPLETED_LIST_LOCK(adapter)); // Start the mailbox based controller if (megaraid_init_mbox(adapter) != 0) { con_log(CL_ANN, (KERN_WARNING "megaraid: maibox adapter did not initialize\n")); goto out_free_adapter; } // Register with LSI Common Management Module if (megaraid_cmm_register(adapter) != 0) { con_log(CL_ANN, (KERN_WARNING "megaraid: could not register with management module\n")); goto out_fini_mbox; } // setup adapter handle in PCI soft state pci_set_drvdata(pdev, adapter); // attach with scsi mid-layer if (megaraid_io_attach(adapter) != 0) { con_log(CL_ANN, (KERN_WARNING "megaraid: io attach failed\n")); goto out_cmm_unreg; } return 0; out_cmm_unreg: pci_set_drvdata(pdev, NULL); megaraid_cmm_unregister(adapter); out_fini_mbox: megaraid_fini_mbox(adapter); out_free_adapter: kfree(adapter); out_probe_one: pci_disable_device(pdev); return -ENODEV; } /** * megaraid_detach_one - release the framework resources and call LLD release * routine * @param pdev : handle for our PCI cofiguration space * * This routine is called during driver unload. We free all the allocated * resources and call the corresponding LLD so that it can also release all * its resources. * * This routine is also called from the PCI hotplug system **/ static void megaraid_detach_one(struct pci_dev *pdev) { adapter_t *adapter; struct Scsi_Host *host; // Start a rollback on this adapter adapter = pci_get_drvdata(pdev); if (!adapter) { con_log(CL_ANN, (KERN_CRIT "megaraid: Invalid detach on %#4.04x:%#4.04x:%#4.04x:%#4.04x\n", pdev->vendor, pdev->device, pdev->subsystem_vendor, pdev->subsystem_device)); return; } else { con_log(CL_ANN, (KERN_NOTICE "megaraid: detaching device %#4.04x:%#4.04x:%#4.04x:%#4.04x\n", pdev->vendor, pdev->device, pdev->subsystem_vendor, pdev->subsystem_device)); } host = adapter->host; // do not allow any more requests from the management module for this // adapter. // FIXME: How do we account for the request which might still be // pending with us? atomic_set(&adapter->being_detached, 1); // detach from the IO sub-system megaraid_io_detach(adapter); // reset the device state in the PCI structure. We check this // condition when we enter here. If the device state is NULL, // that would mean the device has already been removed pci_set_drvdata(pdev, NULL); // Unregister from common management module // // FIXME: this must return success or failure for conditions if there // is a command pending with LLD or not. megaraid_cmm_unregister(adapter); // finalize the mailbox based controller and release all resources megaraid_fini_mbox(adapter); kfree(adapter); scsi_host_put(host); pci_disable_device(pdev); return; } /** * megaraid_mbox_shutdown - PCI shutdown for megaraid HBA * @param device : generice driver model device * * Shutdown notification, perform flush cache */ static void megaraid_mbox_shutdown(struct device *device) { adapter_t *adapter = pci_get_drvdata(to_pci_dev(device)); static int counter; if (!adapter) { con_log(CL_ANN, (KERN_WARNING "megaraid: null device in shutdown\n")); return; } // flush caches now con_log(CL_ANN, (KERN_INFO "megaraid: flushing adapter %d...", counter++)); megaraid_mbox_flush_cache(adapter); con_log(CL_ANN, ("done\n")); } /** * megaraid_io_attach - attach a device with the IO subsystem * @param adapter : controller's soft state * * Attach this device with the IO subsystem **/ static int megaraid_io_attach(adapter_t *adapter) { struct Scsi_Host *host; // Initialize SCSI Host structure host = scsi_host_alloc(&megaraid_template_g, 8); if (!host) { con_log(CL_ANN, (KERN_WARNING "megaraid mbox: scsi_register failed\n")); return -1; } SCSIHOST2ADAP(host) = (caddr_t)adapter; adapter->host = host; // export the parameters required by the mid-layer scsi_assign_lock(host, adapter->host_lock); scsi_set_device(host, &adapter->pdev->dev); host->irq = adapter->irq; host->unique_id = adapter->unique_id; host->can_queue = adapter->max_cmds; host->this_id = adapter->init_id; host->sg_tablesize = adapter->sglen; host->max_sectors = adapter->max_sectors; host->cmd_per_lun = adapter->cmd_per_lun; host->max_channel = adapter->max_channel; host->max_id = adapter->max_target; host->max_lun = adapter->max_lun; // notify mid-layer about the new controller if (scsi_add_host(host, &adapter->pdev->dev)) { con_log(CL_ANN, (KERN_WARNING "megaraid mbox: scsi_add_host failed\n")); scsi_host_put(host); return -1; } scsi_scan_host(host); return 0; } /** * megaraid_io_detach - detach a device from the IO subsystem * @param adapter : controller's soft state * * Detach this device from the IO subsystem **/ static void megaraid_io_detach(adapter_t *adapter) { struct Scsi_Host *host; con_log(CL_DLEVEL1, (KERN_INFO "megaraid: io detach\n")); host = adapter->host; scsi_remove_host(host); return; } /* * START: Mailbox Low Level Driver * * This is section specific to the single mailbox based controllers */ /** * megaraid_init_mbox - initialize controller * @param adapter - our soft state * * . Allocate 16-byte aligned mailbox memory for firmware handshake * . Allocate controller's memory resources * . Find out all initialization data * . Allocate memory required for all the commands * . Use internal library of FW routines, build up complete soft state */ static int __init megaraid_init_mbox(adapter_t *adapter) { struct pci_dev *pdev; mraid_device_t *raid_dev; int i; unsigned int magic64; adapter->ito = MBOX_TIMEOUT; pdev = adapter->pdev; /* * Allocate and initialize the init data structure for mailbox * controllers */ raid_dev = kmalloc(sizeof(mraid_device_t), GFP_KERNEL); if (raid_dev == NULL) return -1; memset(raid_dev, 0, sizeof(mraid_device_t)); /* * Attach the adapter soft state to raid device soft state */ adapter->raid_device = (caddr_t)raid_dev; raid_dev->fast_load = megaraid_fast_load; // our baseport raid_dev->baseport = pci_resource_start(pdev, 0); if (pci_request_regions(pdev, "MegaRAID: LSI Logic Corporation") != 0) { con_log(CL_ANN, (KERN_WARNING "megaraid: mem region busy\n")); goto out_free_raid_dev; } raid_dev->baseaddr = ioremap_nocache(raid_dev->baseport, 128); if (!raid_dev->baseaddr) { con_log(CL_ANN, (KERN_WARNING "megaraid: could not map hba memory\n") ); goto out_release_regions; } // // Setup the rest of the soft state using the library of FW routines // // request IRQ and register the interrupt service routine if (request_irq(adapter->irq, megaraid_isr, SA_SHIRQ, "megaraid", adapter)) { con_log(CL_ANN, (KERN_WARNING "megaraid: Couldn't register IRQ %d!\n", adapter->irq)); goto out_iounmap; } // initialize the mutual exclusion lock for the mailbox spin_lock_init(&raid_dev->mailbox_lock); // allocate memory required for commands if (megaraid_alloc_cmd_packets(adapter) != 0) { goto out_free_irq; } // Product info if (megaraid_mbox_product_info(adapter) != 0) { goto out_alloc_cmds; } // Do we support extended CDBs adapter->max_cdb_sz = 10; if (megaraid_mbox_extended_cdb(adapter) == 0) { adapter->max_cdb_sz = 16; } /* * Do we support cluster environment, if we do, what is the initiator * id. * NOTE: In a non-cluster aware firmware environment, the LLD should * return 7 as initiator id. */ adapter->ha = 0; adapter->init_id = -1; if (megaraid_mbox_support_ha(adapter, &adapter->init_id) == 0) { adapter->ha = 1; } /* * Prepare the device ids array to have the mapping between the kernel * device address and megaraid device address. * We export the physical devices on their actual addresses. The * logical drives are exported on a virtual SCSI channel */ megaraid_mbox_setup_device_map(adapter); // If the firmware supports random deletion, update the device id map if (megaraid_mbox_support_random_del(adapter)) { // Change the logical drives numbers in device_ids array one // slot in device_ids is reserved for target id, that's why // "<=" below for (i = 0; i <= MAX_LOGICAL_DRIVES_40LD; i++) { adapter->device_ids[adapter->max_channel][i] += 0x80; } adapter->device_ids[adapter->max_channel][adapter->init_id] = 0xFF; raid_dev->random_del_supported = 1; } /* * find out the maximum number of scatter-gather elements supported by * this firmware */ adapter->sglen = megaraid_mbox_get_max_sg(adapter); // enumerate RAID and SCSI channels so that all devices on SCSI // channels can later be exported, including disk devices megaraid_mbox_enum_raid_scsi(adapter); /* * Other parameters required by upper layer * * maximum number of sectors per IO command */ adapter->max_sectors = megaraid_max_sectors; /* * number of queued commands per LUN. */ adapter->cmd_per_lun = megaraid_cmd_per_lun; /* * Allocate resources required to issue FW calls, when sysfs is * accessed */ if (megaraid_sysfs_alloc_resources(adapter) != 0) { goto out_alloc_cmds; } // Set the DMA mask to 64-bit. All supported controllers as capable of // DMA in this range pci_read_config_dword(adapter->pdev, PCI_CONF_AMISIG64, &magic64); if (((magic64 == HBA_SIGNATURE_64BIT) && ((adapter->pdev->subsystem_device != PCI_SUBSYS_ID_MEGARAID_SATA_150_6) && (adapter->pdev->subsystem_device != PCI_SUBSYS_ID_MEGARAID_SATA_150_4))) || (adapter->pdev->vendor == PCI_VENDOR_ID_DELL && adapter->pdev->device == PCI_DEVICE_ID_PERC4_DI_EVERGLADES) || (adapter->pdev->vendor == PCI_VENDOR_ID_LSI_LOGIC && adapter->pdev->device == PCI_DEVICE_ID_VERDE) || (adapter->pdev->vendor == PCI_VENDOR_ID_LSI_LOGIC && adapter->pdev->device == PCI_DEVICE_ID_DOBSON) || (adapter->pdev->vendor == PCI_VENDOR_ID_DELL && adapter->pdev->device == PCI_DEVICE_ID_PERC4E_DI_KOBUK) || (adapter->pdev->vendor == PCI_VENDOR_ID_LSI_LOGIC && adapter->pdev->device == PCI_DEVICE_ID_LINDSAY)) { if (pci_set_dma_mask(adapter->pdev, DMA_64BIT_MASK) != 0) { con_log(CL_ANN, (KERN_WARNING "megaraid: could not set DMA mask for 64-bit.\n")); goto out_free_sysfs_res; } } // setup tasklet for DPC tasklet_init(&adapter->dpc_h, megaraid_mbox_dpc, (unsigned long)adapter); con_log(CL_DLEVEL1, (KERN_INFO "megaraid mbox hba successfully initialized\n")); return 0; out_free_sysfs_res: megaraid_sysfs_free_resources(adapter); out_alloc_cmds: megaraid_free_cmd_packets(adapter); out_free_irq: free_irq(adapter->irq, adapter); out_iounmap: iounmap(raid_dev->baseaddr); out_release_regions: pci_release_regions(pdev); out_free_raid_dev: kfree(raid_dev); return -1; } /** * megaraid_fini_mbox - undo controller initialization * @param adapter : our soft state */ static void megaraid_fini_mbox(adapter_t *adapter) { mraid_device_t *raid_dev = ADAP2RAIDDEV(adapter); // flush all caches megaraid_mbox_flush_cache(adapter); tasklet_kill(&adapter->dpc_h); megaraid_sysfs_free_resources(adapter); megaraid_free_cmd_packets(adapter); free_irq(adapter->irq, adapter); iounmap(raid_dev->baseaddr); pci_release_regions(adapter->pdev); kfree(raid_dev); return; } /** * megaraid_alloc_cmd_packets - allocate shared mailbox * @param adapter : soft state of the raid controller * * Allocate and align the shared mailbox. This maibox is used to issue * all the commands. For IO based controllers, the mailbox is also regsitered * with the FW. Allocate memory for all commands as well. * This is our big allocator */ static int megaraid_alloc_cmd_packets(adapter_t *adapter) { mraid_device_t *raid_dev = ADAP2RAIDDEV(adapter); struct pci_dev *pdev; unsigned long align; scb_t *scb; mbox_ccb_t *ccb; struct mraid_pci_blk *epthru_pci_blk; struct mraid_pci_blk *sg_pci_blk; struct mraid_pci_blk *mbox_pci_blk; int i; pdev = adapter->pdev; /* * Setup the mailbox * Allocate the common 16-byte aligned memory for the handshake * mailbox. */ raid_dev->una_mbox64 = pci_alloc_consistent(adapter->pdev, sizeof(mbox64_t), &raid_dev->una_mbox64_dma); if (!raid_dev->una_mbox64) { con_log(CL_ANN, (KERN_WARNING "megaraid: out of memory, %s %d\n", __FUNCTION__, __LINE__)); return -1; } memset(raid_dev->una_mbox64, 0, sizeof(mbox64_t)); /* * Align the mailbox at 16-byte boundary */ raid_dev->mbox = &raid_dev->una_mbox64->mbox32; raid_dev->mbox = (mbox_t *)((((unsigned long)raid_dev->mbox) + 15) & (~0UL ^ 0xFUL)); raid_dev->mbox64 = (mbox64_t *)(((unsigned long)raid_dev->mbox) - 8); align = ((void *)raid_dev->mbox - ((void *)&raid_dev->una_mbox64->mbox32)); raid_dev->mbox_dma = (unsigned long)raid_dev->una_mbox64_dma + 8 + align; // Allocate memory for commands issued internally adapter->ibuf = pci_alloc_consistent(pdev, MBOX_IBUF_SIZE, &adapter->ibuf_dma_h); if (!adapter->ibuf) { con_log(CL_ANN, (KERN_WARNING "megaraid: out of memory, %s %d\n", __FUNCTION__, __LINE__)); goto out_free_common_mbox; } memset(adapter->ibuf, 0, MBOX_IBUF_SIZE); // Allocate memory for our SCSI Command Blocks and their associated // memory /* * Allocate memory for the base list of scb. Later allocate memory for * CCBs and embedded components of each CCB and point the pointers in * scb to the allocated components * NOTE: The code to allocate SCB will be duplicated in all the LLD * since the calling routine does not yet know the number of available * commands. */ adapter->kscb_list = kmalloc(sizeof(scb_t) * MBOX_MAX_SCSI_CMDS, GFP_KERNEL); if (adapter->kscb_list == NULL) { con_log(CL_ANN, (KERN_WARNING "megaraid: out of memory, %s %d\n", __FUNCTION__, __LINE__)); goto out_free_ibuf; } memset(adapter->kscb_list, 0, sizeof(scb_t) * MBOX_MAX_SCSI_CMDS); // memory allocation for our command packets if (megaraid_mbox_setup_dma_pools(adapter) != 0) { con_log(CL_ANN, (KERN_WARNING "megaraid: out of memory, %s %d\n", __FUNCTION__, __LINE__)); goto out_free_scb_list; } // Adjust the scb pointers and link in the free pool epthru_pci_blk = raid_dev->epthru_pool; sg_pci_blk = raid_dev->sg_pool; mbox_pci_blk = raid_dev->mbox_pool; for (i = 0; i < MBOX_MAX_SCSI_CMDS; i++) { scb = adapter->kscb_list + i; ccb = raid_dev->ccb_list + i; ccb->mbox = (mbox_t *)(mbox_pci_blk[i].vaddr + 16); ccb->raw_mbox = (uint8_t *)ccb->mbox; ccb->mbox64 = (mbox64_t *)(mbox_pci_blk[i].vaddr + 8); ccb->mbox_dma_h = (unsigned long)mbox_pci_blk[i].dma_addr + 16; // make sure the mailbox is aligned properly if (ccb->mbox_dma_h & 0x0F) { con_log(CL_ANN, (KERN_CRIT "megaraid mbox: not aligned on 16-bytes\n")); goto out_teardown_dma_pools; } ccb->epthru = (mraid_epassthru_t *) epthru_pci_blk[i].vaddr; ccb->epthru_dma_h = epthru_pci_blk[i].dma_addr; ccb->pthru = (mraid_passthru_t *)ccb->epthru; ccb->pthru_dma_h = ccb->epthru_dma_h; ccb->sgl64 = (mbox_sgl64 *)sg_pci_blk[i].vaddr; ccb->sgl_dma_h = sg_pci_blk[i].dma_addr; ccb->sgl32 = (mbox_sgl32 *)ccb->sgl64; scb->ccb = (caddr_t)ccb; scb->gp = 0; scb->sno = i; // command index scb->scp = NULL; scb->state = SCB_FREE; scb->dma_direction = PCI_DMA_NONE; scb->dma_type = MRAID_DMA_NONE; scb->dev_channel = -1; scb->dev_target = -1; // put scb in the free pool list_add_tail(&scb->list, &adapter->kscb_pool); } return 0; out_teardown_dma_pools: megaraid_mbox_teardown_dma_pools(adapter); out_free_scb_list: kfree(adapter->kscb_list); out_free_ibuf: pci_free_consistent(pdev, MBOX_IBUF_SIZE, (void *)adapter->ibuf, adapter->ibuf_dma_h); out_free_common_mbox: pci_free_consistent(adapter->pdev, sizeof(mbox64_t), (caddr_t)raid_dev->una_mbox64, raid_dev->una_mbox64_dma); return -1; } /** * megaraid_free_cmd_packets - free memory * @param adapter : soft state of the raid controller * * Release memory resources allocated for commands */ static void megaraid_free_cmd_packets(adapter_t *adapter) { mraid_device_t *raid_dev = ADAP2RAIDDEV(adapter); megaraid_mbox_teardown_dma_pools(adapter); kfree(adapter->kscb_list); pci_free_consistent(adapter->pdev, MBOX_IBUF_SIZE, (void *)adapter->ibuf, adapter->ibuf_dma_h); pci_free_consistent(adapter->pdev, sizeof(mbox64_t), (caddr_t)raid_dev->una_mbox64, raid_dev->una_mbox64_dma); return; } /** * megaraid_mbox_setup_dma_pools - setup dma pool for command packets * @param adapter : HBA soft state * * setup the dma pools for mailbox, passthru and extended passthru structures, * and scatter-gather lists */ static int megaraid_mbox_setup_dma_pools(adapter_t *adapter) { mraid_device_t *raid_dev = ADAP2RAIDDEV(adapter); struct mraid_pci_blk *epthru_pci_blk; struct mraid_pci_blk *sg_pci_blk; struct mraid_pci_blk *mbox_pci_blk; int i; // Allocate memory for 16-bytes aligned mailboxes raid_dev->mbox_pool_handle = pci_pool_create("megaraid mbox pool", adapter->pdev, sizeof(mbox64_t) + 16, 16, 0); if (raid_dev->mbox_pool_handle == NULL) { goto fail_setup_dma_pool; } mbox_pci_blk = raid_dev->mbox_pool; for (i = 0; i < MBOX_MAX_SCSI_CMDS; i++) { mbox_pci_blk[i].vaddr = pci_pool_alloc( raid_dev->mbox_pool_handle, GFP_KERNEL, &mbox_pci_blk[i].dma_addr); if (!mbox_pci_blk[i].vaddr) { goto fail_setup_dma_pool; } } /* * Allocate memory for each embedded passthru strucuture pointer * Request for a 128 bytes aligned structure for each passthru command * structure * Since passthru and extended passthru commands are exclusive, they * share common memory pool. Passthru structures piggyback on memory * allocted to extended passthru since passthru is smaller of the two */ raid_dev->epthru_pool_handle = pci_pool_create("megaraid mbox pthru", adapter->pdev, sizeof(mraid_epassthru_t), 128, 0); if (raid_dev->epthru_pool_handle == NULL) { goto fail_setup_dma_pool; } epthru_pci_blk = raid_dev->epthru_pool; for (i = 0; i < MBOX_MAX_SCSI_CMDS; i++) { epthru_pci_blk[i].vaddr = pci_pool_alloc( raid_dev->epthru_pool_handle, GFP_KERNEL, &epthru_pci_blk[i].dma_addr); if (!epthru_pci_blk[i].vaddr) { goto fail_setup_dma_pool; } } // Allocate memory for each scatter-gather list. Request for 512 bytes // alignment for each sg list raid_dev->sg_pool_handle = pci_pool_create("megaraid mbox sg", adapter->pdev, sizeof(mbox_sgl64) * MBOX_MAX_SG_SIZE, 512, 0); if (raid_dev->sg_pool_handle == NULL) { goto fail_setup_dma_pool; } sg_pci_blk = raid_dev->sg_pool; for (i = 0; i < MBOX_MAX_SCSI_CMDS; i++) { sg_pci_blk[i].vaddr = pci_pool_alloc( raid_dev->sg_pool_handle, GFP_KERNEL, &sg_pci_blk[i].dma_addr); if (!sg_pci_blk[i].vaddr) { goto fail_setup_dma_pool; } } return 0; fail_setup_dma_pool: megaraid_mbox_teardown_dma_pools(adapter); return -1; } /** * megaraid_mbox_teardown_dma_pools - teardown dma pools for command packets * @param adapter : HBA soft state * * teardown the dma pool for mailbox, passthru and extended passthru * structures, and scatter-gather lists */ static void megaraid_mbox_teardown_dma_pools(adapter_t *adapter) { mraid_device_t *raid_dev = ADAP2RAIDDEV(adapter); struct mraid_pci_blk *epthru_pci_blk; struct mraid_pci_blk *sg_pci_blk; struct mraid_pci_blk *mbox_pci_blk; int i; sg_pci_blk = raid_dev->sg_pool; for (i = 0; i < MBOX_MAX_SCSI_CMDS && sg_pci_blk[i].vaddr; i++) { pci_pool_free(raid_dev->sg_pool_handle, sg_pci_blk[i].vaddr, sg_pci_blk[i].dma_addr); } if (raid_dev->sg_pool_handle) pci_pool_destroy(raid_dev->sg_pool_handle); epthru_pci_blk = raid_dev->epthru_pool; for (i = 0; i < MBOX_MAX_SCSI_CMDS && epthru_pci_blk[i].vaddr; i++) { pci_pool_free(raid_dev->epthru_pool_handle, epthru_pci_blk[i].vaddr, epthru_pci_blk[i].dma_addr); } if (raid_dev->epthru_pool_handle) pci_pool_destroy(raid_dev->epthru_pool_handle); mbox_pci_blk = raid_dev->mbox_pool; for (i = 0; i < MBOX_MAX_SCSI_CMDS && mbox_pci_blk[i].vaddr; i++) { pci_pool_free(raid_dev->mbox_pool_handle, mbox_pci_blk[i].vaddr, mbox_pci_blk[i].dma_addr); } if (raid_dev->mbox_pool_handle) pci_pool_destroy(raid_dev->mbox_pool_handle); return; } /** * megaraid_alloc_scb - detach and return a scb from the free list * @adapter : controller's soft state * * return the scb from the head of the free list. NULL if there are none * available **/ static inline scb_t * megaraid_alloc_scb(adapter_t *adapter, struct scsi_cmnd *scp) { struct list_head *head = &adapter->kscb_pool; scb_t *scb = NULL; unsigned long flags; // detach scb from free pool spin_lock_irqsave(SCSI_FREE_LIST_LOCK(adapter), flags); if (list_empty(head)) { spin_unlock_irqrestore(SCSI_FREE_LIST_LOCK(adapter), flags); return NULL; } scb = list_entry(head->next, scb_t, list); list_del_init(&scb->list); spin_unlock_irqrestore(SCSI_FREE_LIST_LOCK(adapter), flags); scb->state = SCB_ACTIVE; scb->scp = scp; scb->dma_type = MRAID_DMA_NONE; return scb; } /** * megaraid_dealloc_scb - return the scb to the free pool * @adapter : controller's soft state * @scb : scb to be freed * * return the scb back to the free list of scbs. The caller must 'flush' the * SCB before calling us. E.g., performing pci_unamp and/or pci_sync etc. * NOTE NOTE: Make sure the scb is not on any list before calling this * routine. **/ static inline void megaraid_dealloc_scb(adapter_t *adapter, scb_t *scb) { unsigned long flags; // put scb in the free pool scb->state = SCB_FREE; scb->scp = NULL; spin_lock_irqsave(SCSI_FREE_LIST_LOCK(adapter), flags); list_add(&scb->list, &adapter->kscb_pool); spin_unlock_irqrestore(SCSI_FREE_LIST_LOCK(adapter), flags); return; } /** * megaraid_mbox_mksgl - make the scatter-gather list * @adapter - controller's soft state * @scb - scsi control block * * prepare the scatter-gather list */ static inline int megaraid_mbox_mksgl(adapter_t *adapter, scb_t *scb) { struct scatterlist *sgl; mbox_ccb_t *ccb; struct page *page; unsigned long offset; struct scsi_cmnd *scp; int sgcnt; int i; scp = scb->scp; ccb = (mbox_ccb_t *)scb->ccb; // no mapping required if no data to be transferred if (!scp->request_buffer || !scp->request_bufflen) return 0; if (!scp->use_sg) { /* scatter-gather list not used */ page = virt_to_page(scp->request_buffer); offset = ((unsigned long)scp->request_buffer & ~PAGE_MASK); ccb->buf_dma_h = pci_map_page(adapter->pdev, page, offset, scp->request_bufflen, scb->dma_direction); scb->dma_type = MRAID_DMA_WBUF; /* * We need to handle special 64-bit commands that need a * minimum of 1 SG */ sgcnt = 1; ccb->sgl64[0].address = ccb->buf_dma_h; ccb->sgl64[0].length = scp->request_bufflen; return sgcnt; } sgl = (struct scatterlist *)scp->request_buffer; // The number of sg elements returned must not exceed our limit sgcnt = pci_map_sg(adapter->pdev, sgl, scp->use_sg, scb->dma_direction); if (sgcnt > adapter->sglen) { con_log(CL_ANN, (KERN_CRIT "megaraid critical: too many sg elements:%d\n", sgcnt)); BUG(); } scb->dma_type = MRAID_DMA_WSG; for (i = 0; i < sgcnt; i++, sgl++) { ccb->sgl64[i].address = sg_dma_address(sgl); ccb->sgl64[i].length = sg_dma_len(sgl); } // Return count of SG nodes return sgcnt; } /** * mbox_post_cmd - issue a mailbox command * @adapter - controller's soft state * @scb - command to be issued * * post the command to the controller if mailbox is availble. */ static inline int mbox_post_cmd(adapter_t *adapter, scb_t *scb) { mraid_device_t *raid_dev = ADAP2RAIDDEV(adapter); mbox64_t *mbox64; mbox_t *mbox; mbox_ccb_t *ccb; unsigned long flags; unsigned int i = 0; ccb = (mbox_ccb_t *)scb->ccb; mbox = raid_dev->mbox; mbox64 = raid_dev->mbox64; /* * Check for busy mailbox. If it is, return failure - the caller * should retry later. */ spin_lock_irqsave(MAILBOX_LOCK(raid_dev), flags); if (unlikely(mbox->busy)) { do { udelay(1); i++; rmb(); } while(mbox->busy && (i < max_mbox_busy_wait)); if (mbox->busy) { spin_unlock_irqrestore(MAILBOX_LOCK(raid_dev), flags); return -1; } } // Copy this command's mailbox data into "adapter's" mailbox memcpy((caddr_t)mbox64, (caddr_t)ccb->mbox64, 22); mbox->cmdid = scb->sno; adapter->outstanding_cmds++; if (scb->dma_direction == PCI_DMA_TODEVICE) { if (!scb->scp->use_sg) { // sg list not used pci_dma_sync_single_for_device(adapter->pdev, ccb->buf_dma_h, scb->scp->request_bufflen, PCI_DMA_TODEVICE); } else { pci_dma_sync_sg_for_device(adapter->pdev, scb->scp->request_buffer, scb->scp->use_sg, PCI_DMA_TODEVICE); } } mbox->busy = 1; // Set busy mbox->poll = 0; mbox->ack = 0; wmb(); WRINDOOR(raid_dev, raid_dev->mbox_dma | 0x1); spin_unlock_irqrestore(MAILBOX_LOCK(raid_dev), flags); return 0; } /** * megaraid_queue_command - generic queue entry point for all LLDs * @scp : pointer to the scsi command to be executed * @done : callback routine to be called after the cmd has be completed * * Queue entry point for mailbox based controllers. */ static int megaraid_queue_command(struct scsi_cmnd *scp, void (* done)(struct scsi_cmnd *)) { adapter_t *adapter; scb_t *scb; int if_busy; adapter = SCP2ADAPTER(scp); scp->scsi_done = done; scp->result = 0; ASSERT(spin_is_locked(adapter->host_lock)); spin_unlock(adapter->host_lock); /* * Allocate and build a SCB request * if_busy flag will be set if megaraid_mbox_build_cmd() command could * not allocate scb. We will return non-zero status in that case. * NOTE: scb can be null even though certain commands completed * successfully, e.g., MODE_SENSE and TEST_UNIT_READY, it would * return 0 in that case, and we would do the callback right away. */ if_busy = 0; scb = megaraid_mbox_build_cmd(adapter, scp, &if_busy); if (scb) { megaraid_mbox_runpendq(adapter, scb); } spin_lock(adapter->host_lock); if (!scb) { // command already completed done(scp); return 0; } return if_busy; } /** * megaraid_mbox_build_cmd - transform the mid-layer scsi command to megaraid * firmware lingua * @adapter - controller's soft state * @scp - mid-layer scsi command pointer * @busy - set if request could not be completed because of lack of * resources * * convert the command issued by mid-layer to format understood by megaraid * firmware. We also complete certain command without sending them to firmware */ static scb_t * megaraid_mbox_build_cmd(adapter_t *adapter, struct scsi_cmnd *scp, int *busy) { mraid_device_t *rdev = ADAP2RAIDDEV(adapter); int channel; int target; int islogical; mbox_ccb_t *ccb; mraid_passthru_t *pthru; mbox64_t *mbox64; mbox_t *mbox; scb_t *scb; char skip[] = "skipping"; char scan[] = "scanning"; char *ss; /* * Get the appropriate device map for the device this command is * intended for */ MRAID_GET_DEVICE_MAP(adapter, scp, channel, target, islogical); /* * Logical drive commands */ if (islogical) { switch (scp->cmnd[0]) { case TEST_UNIT_READY: /* * Do we support clustering and is the support enabled * If no, return success always */ if (!adapter->ha) { scp->result = (DID_OK << 16); return NULL; } if (!(scb = megaraid_alloc_scb(adapter, scp))) { scp->result = (DID_ERROR << 16); *busy = 1; return NULL; } scb->dma_direction = scp->sc_data_direction; scb->dev_channel = 0xFF; scb->dev_target = target; ccb = (mbox_ccb_t *)scb->ccb; /* * The command id will be provided by the command * issuance routine */ ccb->raw_mbox[0] = CLUSTER_CMD; ccb->raw_mbox[2] = RESERVATION_STATUS; ccb->raw_mbox[3] = target; return scb; case MODE_SENSE: if (scp->use_sg) { struct scatterlist *sgl; caddr_t vaddr; sgl = (struct scatterlist *)scp->request_buffer; if (sgl->page) { vaddr = (caddr_t) (page_address((&sgl[0])->page) + (&sgl[0])->offset); memset(vaddr, 0, scp->cmnd[4]); } else { con_log(CL_ANN, (KERN_WARNING "megaraid mailbox: invalid sg:%d\n", __LINE__)); } } else { memset(scp->request_buffer, 0, scp->cmnd[4]); } scp->result = (DID_OK << 16); return NULL; case INQUIRY: /* * Display the channel scan for logical drives * Do not display scan for a channel if already done. */ if (!(rdev->last_disp & (1L << SCP2CHANNEL(scp)))) { con_log(CL_ANN, (KERN_INFO "scsi[%d]: scanning scsi channel %d", adapter->host->host_no, SCP2CHANNEL(scp))); con_log(CL_ANN, ( " [virtual] for logical drives\n")); rdev->last_disp |= (1L << SCP2CHANNEL(scp)); } /* * The firmware ignores the EVPD bit, and the command * allocation length. As a result, it may over-write * the request buffer and corrupt memory. Don't let * EVPD Inquirys through. */ if (scp->cmnd[1] & 0x01) { scp->sense_buffer[0] = 0x70; scp->sense_buffer[2] = ILLEGAL_REQUEST; scp->sense_buffer[12] = 0x24; /* INVALID_IN_CDB */ scp->result = CHECK_CONDITION << 1; return NULL; } /* Fall through */ case READ_CAPACITY: /* * Do not allow LUN > 0 for logical drives and * requests for more than 40 logical drives */ if (SCP2LUN(scp)) { scp->result = (DID_BAD_TARGET << 16); return NULL; } if ((target % 0x80) >= MAX_LOGICAL_DRIVES_40LD) { scp->result = (DID_BAD_TARGET << 16); return NULL; } /* Allocate a SCB and initialize passthru */ if (!(scb = megaraid_alloc_scb(adapter, scp))) { scp->result = (DID_ERROR << 16); *busy = 1; return NULL; } ccb = (mbox_ccb_t *)scb->ccb; scb->dev_channel = 0xFF; scb->dev_target = target; pthru = ccb->pthru; mbox = ccb->mbox; mbox64 = ccb->mbox64; pthru->timeout = 0; pthru->ars = 1; pthru->reqsenselen = 14; pthru->islogical = 1; pthru->logdrv = target; pthru->cdblen = scp->cmd_len; memcpy(pthru->cdb, scp->cmnd, scp->cmd_len); mbox->cmd = MBOXCMD_PASSTHRU64; scb->dma_direction = scp->sc_data_direction; pthru->dataxferlen = scp->request_bufflen; pthru->dataxferaddr = ccb->sgl_dma_h; pthru->numsge = megaraid_mbox_mksgl(adapter, scb); mbox->xferaddr = 0xFFFFFFFF; mbox64->xferaddr_lo = (uint32_t )ccb->pthru_dma_h; mbox64->xferaddr_hi = 0; return scb; case READ_6: case WRITE_6: case READ_10: case WRITE_10: case READ_12: case WRITE_12: /* * Allocate a SCB and initialize mailbox */ if (!(scb = megaraid_alloc_scb(adapter, scp))) { scp->result = (DID_ERROR << 16); *busy = 1; return NULL; } ccb = (mbox_ccb_t *)scb->ccb; scb->dev_channel = 0xFF; scb->dev_target = target; mbox = ccb->mbox; mbox64 = ccb->mbox64; mbox->logdrv = target; /* * A little HACK: 2nd bit is zero for all scsi read * commands and is set for all scsi write commands */ mbox->cmd = (scp->cmnd[0] & 0x02) ? MBOXCMD_LWRITE64: MBOXCMD_LREAD64 ; /* * 6-byte READ(0x08) or WRITE(0x0A) cdb */ if (scp->cmd_len == 6) { mbox->numsectors = (uint32_t)scp->cmnd[4]; mbox->lba = ((uint32_t)scp->cmnd[1] << 16) | ((uint32_t)scp->cmnd[2] << 8) | (uint32_t)scp->cmnd[3]; mbox->lba &= 0x1FFFFF; } /* * 10-byte READ(0x28) or WRITE(0x2A) cdb */ else if (scp->cmd_len == 10) { mbox->numsectors = (uint32_t)scp->cmnd[8] | ((uint32_t)scp->cmnd[7] << 8); mbox->lba = ((uint32_t)scp->cmnd[2] << 24) | ((uint32_t)scp->cmnd[3] << 16) | ((uint32_t)scp->cmnd[4] << 8) | (uint32_t)scp->cmnd[5]; } /* * 12-byte READ(0xA8) or WRITE(0xAA) cdb */ else if (scp->cmd_len == 12) { mbox->lba = ((uint32_t)scp->cmnd[2] << 24) | ((uint32_t)scp->cmnd[3] << 16) | ((uint32_t)scp->cmnd[4] << 8) | (uint32_t)scp->cmnd[5]; mbox->numsectors = ((uint32_t)scp->cmnd[6] << 24) | ((uint32_t)scp->cmnd[7] << 16) | ((uint32_t)scp->cmnd[8] << 8) | (uint32_t)scp->cmnd[9]; } else { con_log(CL_ANN, (KERN_WARNING "megaraid: unsupported CDB length\n")); megaraid_dealloc_scb(adapter, scb); scp->result = (DID_ERROR << 16); return NULL; } scb->dma_direction = scp->sc_data_direction; // Calculate Scatter-Gather info mbox64->xferaddr_lo = (uint32_t )ccb->sgl_dma_h; mbox->numsge = megaraid_mbox_mksgl(adapter, scb); mbox->xferaddr = 0xFFFFFFFF; mbox64->xferaddr_hi = 0; return scb; case RESERVE: case RELEASE: /* * Do we support clustering and is the support enabled */ if (!adapter->ha) { scp->result = (DID_BAD_TARGET << 16); return NULL; } /* * Allocate a SCB and initialize mailbox */ if (!(scb = megaraid_alloc_scb(adapter, scp))) { scp->result = (DID_ERROR << 16); *busy = 1; return NULL; } ccb = (mbox_ccb_t *)scb->ccb; scb->dev_channel = 0xFF; scb->dev_target = target; ccb->raw_mbox[0] = CLUSTER_CMD; ccb->raw_mbox[2] = (scp->cmnd[0] == RESERVE) ? RESERVE_LD : RELEASE_LD; ccb->raw_mbox[3] = target; scb->dma_direction = scp->sc_data_direction; return scb; case REQUEST_SENSE: case MODE_SELECT: case SYNCHRONIZE_CACHE: if ( crashdump_mode() ) { scp->result = (DID_OK << 16); scp->scsi_done(scp); return NULL; } default: scp->result = (DID_BAD_TARGET << 16); return NULL; } } else { // Passthru device commands // Do not allow access to target id > 15 or LUN > 7 if (target > 15 || SCP2LUN(scp) > 7) { scp->result = (DID_BAD_TARGET << 16); return NULL; } // if fast load option was set and scan for last device is // over, reset the fast_load flag so that during a possible // next scan, devices can be made available if (rdev->fast_load && (target == 15) && (SCP2CHANNEL(scp) == adapter->max_channel -1)) { con_log(CL_ANN, (KERN_INFO "megaraid[%d]: physical device scan re-enabled\n", adapter->host->host_no)); rdev->fast_load = 0; } /* * Display the channel scan for physical devices */ if (!(rdev->last_disp & (1L << SCP2CHANNEL(scp)))) { ss = rdev->fast_load ? skip : scan; con_log(CL_ANN, (KERN_INFO "scsi[%d]: %s scsi channel %d [Phy %d]", adapter->host->host_no, ss, SCP2CHANNEL(scp), channel)); con_log(CL_ANN, ( " for non-raid devices\n")); rdev->last_disp |= (1L << SCP2CHANNEL(scp)); } // disable channel sweep if fast load option given if (rdev->fast_load) { scp->result = (DID_BAD_TARGET << 16); return NULL; } // Allocate a SCB and initialize passthru if (!(scb = megaraid_alloc_scb(adapter, scp))) { scp->result = (DID_ERROR << 16); *busy = 1; return NULL; } ccb = (mbox_ccb_t *)scb->ccb; scb->dev_channel = channel; scb->dev_target = target; scb->dma_direction = scp->sc_data_direction; mbox = ccb->mbox; mbox64 = ccb->mbox64; // Does this firmware support extended CDBs if (adapter->max_cdb_sz == 16) { mbox->cmd = MBOXCMD_EXTPTHRU; megaraid_mbox_prepare_epthru(adapter, scb, scp); mbox64->xferaddr_lo = (uint32_t)ccb->epthru_dma_h; mbox64->xferaddr_hi = 0; mbox->xferaddr = 0xFFFFFFFF; } else { mbox->cmd = MBOXCMD_PASSTHRU64; megaraid_mbox_prepare_pthru(adapter, scb, scp); mbox64->xferaddr_lo = (uint32_t)ccb->pthru_dma_h; mbox64->xferaddr_hi = 0; mbox->xferaddr = 0xFFFFFFFF; } return scb; } // NOT REACHED } /** * megaraid_mbox_runpendq - execute commands queued in the pending queue * @adapter : controller's soft state * @scb : SCB to be queued in the pending list * * scan the pending list for commands which are not yet issued and try to * post to the controller. The SCB can be a null pointer, which would indicate * no SCB to be queue, just try to execute the ones in the pending list. * * NOTE: We do not actually traverse the pending list. The SCBs are plucked * out from the head of the pending list. If it is successfully issued, the * next SCB is at the head now. */ static void megaraid_mbox_runpendq(adapter_t *adapter, scb_t *scb_q) { scb_t *scb; unsigned long flags; spin_lock_irqsave(PENDING_LIST_LOCK(adapter), flags); if (scb_q) { scb_q->state = SCB_PENDQ; list_add_tail(&scb_q->list, &adapter->pend_list); } // if the adapter in not in quiescent mode, post the commands to FW if (adapter->quiescent) { spin_unlock_irqrestore(PENDING_LIST_LOCK(adapter), flags); return; } while (!list_empty(&adapter->pend_list)) { ASSERT(spin_is_locked(PENDING_LIST_LOCK(adapter))); scb = list_entry(adapter->pend_list.next, scb_t, list); // remove the scb from the pending list and try to // issue. If we are unable to issue it, put back in // the pending list and return list_del_init(&scb->list); spin_unlock_irqrestore(PENDING_LIST_LOCK(adapter), flags); // if mailbox was busy, return SCB back to pending // list. Make sure to add at the head, since that's // where it would have been removed from scb->state = SCB_ISSUED; if (mbox_post_cmd(adapter, scb) != 0) { spin_lock_irqsave(PENDING_LIST_LOCK(adapter), flags); scb->state = SCB_PENDQ; list_add(&scb->list, &adapter->pend_list); spin_unlock_irqrestore(PENDING_LIST_LOCK(adapter), flags); return; } spin_lock_irqsave(PENDING_LIST_LOCK(adapter), flags); } spin_unlock_irqrestore(PENDING_LIST_LOCK(adapter), flags); return; } /** * megaraid_mbox_prepare_pthru - prepare a command for physical devices * @adapter - pointer to controller's soft state * @scb - scsi control block * @scp - scsi command from the mid-layer * * prepare a command for the scsi physical devices */ static void megaraid_mbox_prepare_pthru(adapter_t *adapter, scb_t *scb, struct scsi_cmnd *scp) { mbox_ccb_t *ccb; mraid_passthru_t *pthru; uint8_t channel; uint8_t target; ccb = (mbox_ccb_t *)scb->ccb; pthru = ccb->pthru; channel = scb->dev_channel; target = scb->dev_target; // 0=6sec, 1=60sec, 2=10min, 3=3hrs, 4=NO timeout pthru->timeout = 4; pthru->ars = 1; pthru->islogical = 0; pthru->channel = 0; pthru->target = (channel << 4) | target; pthru->logdrv = SCP2LUN(scp); pthru->reqsenselen = 14; pthru->cdblen = scp->cmd_len; memcpy(pthru->cdb, scp->cmnd, scp->cmd_len); if (scp->request_bufflen) { pthru->dataxferlen = scp->request_bufflen; pthru->dataxferaddr = ccb->sgl_dma_h; pthru->numsge = megaraid_mbox_mksgl(adapter, scb); } else { pthru->dataxferaddr = 0; pthru->dataxferlen = 0; pthru->numsge = 0; } return; } /** * megaraid_mbox_prepare_epthru - prepare a command for physical devices * @adapter - pointer to controller's soft state * @scb - scsi control block * @scp - scsi command from the mid-layer * * prepare a command for the scsi physical devices. This rountine prepares * commands for devices which can take extended CDBs (>10 bytes) */ static void megaraid_mbox_prepare_epthru(adapter_t *adapter, scb_t *scb, struct scsi_cmnd *scp) { mbox_ccb_t *ccb; mraid_epassthru_t *epthru; uint8_t channel; uint8_t target; ccb = (mbox_ccb_t *)scb->ccb; epthru = ccb->epthru; channel = scb->dev_channel; target = scb->dev_target; // 0=6sec, 1=60sec, 2=10min, 3=3hrs, 4=NO timeout epthru->timeout = 4; epthru->ars = 1; epthru->islogical = 0; epthru->channel = 0; epthru->target = (channel << 4) | target; epthru->logdrv = SCP2LUN(scp); epthru->reqsenselen = 14; epthru->cdblen = scp->cmd_len; memcpy(epthru->cdb, scp->cmnd, scp->cmd_len); if (scp->request_bufflen) { epthru->dataxferlen = scp->request_bufflen; epthru->dataxferaddr = ccb->sgl_dma_h; epthru->numsge = megaraid_mbox_mksgl(adapter, scb); } else { epthru->dataxferaddr = 0; epthru->dataxferlen = 0; epthru->numsge = 0; } return; } /** * megaraid_ack_sequence - interrupt ack sequence for memory mapped HBAs * @adapter - controller's soft state * * Interrupt ackrowledgement sequence for memory mapped HBAs. Find out the * completed command and put them on the completed list for later processing. * * Returns: 1 if the interrupt is valid, 0 otherwise */ static inline int megaraid_ack_sequence(adapter_t *adapter) { mraid_device_t *raid_dev = ADAP2RAIDDEV(adapter); mbox_t *mbox; scb_t *scb; uint8_t nstatus; uint8_t completed[MBOX_MAX_FIRMWARE_STATUS]; struct list_head clist; int handled; uint32_t dword; unsigned long flags; int i, j; mbox = raid_dev->mbox; // move the SCBs from the firmware completed array to our local list INIT_LIST_HEAD(&clist); // loop till F/W has more commands for us to complete handled = 0; spin_lock_irqsave(MAILBOX_LOCK(raid_dev), flags); do { /* * Check if a valid interrupt is pending. If found, force the * interrupt line low. */ dword = RDOUTDOOR(raid_dev); if (dword != 0x10001234) break; handled = 1; WROUTDOOR(raid_dev, 0x10001234); nstatus = 0; // wait for valid numstatus to post for (i = 0; i < 0xFFFFF; i++) { if (mbox->numstatus != 0xFF) { nstatus = mbox->numstatus; break; } rmb(); } mbox->numstatus = 0xFF; adapter->outstanding_cmds -= nstatus; for (i = 0; i < nstatus; i++) { // wait for valid command index to post for (j = 0; j < 0xFFFFF; j++) { if (mbox->completed[i] != 0xFF) break; rmb(); } completed[i] = mbox->completed[i]; mbox->completed[i] = 0xFF; if (completed[i] == 0xFF) { con_log(CL_ANN, (KERN_CRIT "megaraid: command posting timed out\n")); BUG(); continue; } // Get SCB associated with this command id if (completed[i] >= MBOX_MAX_SCSI_CMDS) { // a cmm command scb = adapter->uscb_list + (completed[i] - MBOX_MAX_SCSI_CMDS); } else { // an os command scb = adapter->kscb_list + completed[i]; } scb->status = mbox->status; list_add_tail(&scb->list, &clist); } // Acknowledge interrupt WRINDOOR(raid_dev, 0x02); } while(1); spin_unlock_irqrestore(MAILBOX_LOCK(raid_dev), flags); // put the completed commands in the completed list. DPC would // complete these commands later spin_lock_irqsave(COMPLETED_LIST_LOCK(adapter), flags); list_splice(&clist, &adapter->completed_list); spin_unlock_irqrestore(COMPLETED_LIST_LOCK(adapter), flags); // schedule the DPC if there is some work for it if (handled) tasklet_schedule(&adapter->dpc_h); return handled; } /** * megaraid_isr - isr for memory based mailbox based controllers * @irq - irq * @devp - pointer to our soft state * @regs - unused * * Interrupt service routine for memory-mapped mailbox controllers. */ static irqreturn_t megaraid_isr(int irq, void *devp, struct pt_regs *regs) { adapter_t *adapter = devp; int handled; handled = megaraid_ack_sequence(adapter); /* Loop through any pending requests */ if (!adapter->quiescent) { megaraid_mbox_runpendq(adapter, NULL); } return IRQ_RETVAL(handled); } /** * megaraid_mbox_sync_scb - sync kernel buffers * @adapter : controller's soft state * @scb : pointer to the resource packet * * DMA sync if required. */ static inline void megaraid_mbox_sync_scb(adapter_t *adapter, scb_t *scb) { mbox_ccb_t *ccb; ccb = (mbox_ccb_t *)scb->ccb; switch (scb->dma_type) { case MRAID_DMA_WBUF: if (scb->dma_direction == PCI_DMA_FROMDEVICE) { pci_dma_sync_single_for_cpu(adapter->pdev, ccb->buf_dma_h, scb->scp->request_bufflen, PCI_DMA_FROMDEVICE); } pci_unmap_page(adapter->pdev, ccb->buf_dma_h, scb->scp->request_bufflen, scb->dma_direction); break; case MRAID_DMA_WSG: if (scb->dma_direction == PCI_DMA_FROMDEVICE) { pci_dma_sync_sg_for_cpu(adapter->pdev, scb->scp->request_buffer, scb->scp->use_sg, PCI_DMA_FROMDEVICE); } pci_unmap_sg(adapter->pdev, scb->scp->request_buffer, scb->scp->use_sg, scb->dma_direction); break; default: break; } return; } /** * megaraid_mbox_dpc - the tasklet to complete the commands from completed list * @devp : pointer to HBA soft state * * Pick up the commands from the completed list and send back to the owners. * This is a reentrant function and does not assume any locks are held while * it is being called. */ static void megaraid_mbox_dpc(unsigned long devp) { adapter_t *adapter = (adapter_t *)devp; mraid_device_t *raid_dev; struct list_head clist; struct scatterlist *sgl; scb_t *scb; scb_t *tmp; struct scsi_cmnd *scp; mraid_passthru_t *pthru; mraid_epassthru_t *epthru; mbox_ccb_t *ccb; int islogical; int pdev_index; int pdev_state; mbox_t *mbox; unsigned long flags; uint8_t c; int status; if (!adapter) return; raid_dev = ADAP2RAIDDEV(adapter); // move the SCBs from the completed list to our local list INIT_LIST_HEAD(&clist); spin_lock_irqsave(COMPLETED_LIST_LOCK(adapter), flags); list_splice_init(&adapter->completed_list, &clist); spin_unlock_irqrestore(COMPLETED_LIST_LOCK(adapter), flags); list_for_each_entry_safe(scb, tmp, &clist, list) { status = scb->status; scp = scb->scp; ccb = (mbox_ccb_t *)scb->ccb; pthru = ccb->pthru; epthru = ccb->epthru; mbox = ccb->mbox; // Make sure f/w has completed a valid command if (scb->state != SCB_ISSUED) { con_log(CL_ANN, (KERN_CRIT "megaraid critical err: invalid command %d:%d:%p\n", scb->sno, scb->state, scp)); BUG(); continue; // Must never happen! } // check for the management command and complete it right away if (scb->sno >= MBOX_MAX_SCSI_CMDS) { scb->state = SCB_FREE; scb->status = status; // remove from local clist list_del_init(&scb->list); megaraid_mbox_mm_done(adapter, scb); continue; } // Was an abort issued for this command earlier if (scb->state & SCB_ABORT) { con_log(CL_ANN, (KERN_NOTICE "megaraid: aborted cmd %lx[%x] completed\n", scp->serial_number, scb->sno)); } /* * If the inquiry came of a disk drive which is not part of * any RAID array, expose it to the kernel. For this to be * enabled, user must set the "megaraid_expose_unconf_disks" * flag to 1 by specifying it on module parameter list. * This would enable data migration off drives from other * configurations. */ islogical = MRAID_IS_LOGICAL(adapter, scp); if (scp->cmnd[0] == INQUIRY && status == 0 && islogical == 0 && IS_RAID_CH(raid_dev, scb->dev_channel)) { if (scp->use_sg) { sgl = (struct scatterlist *) scp->request_buffer; if (sgl->page) { c = *(unsigned char *) (page_address((&sgl[0])->page) + (&sgl[0])->offset); } else { con_log(CL_ANN, (KERN_WARNING "megaraid mailbox: invalid sg:%d\n", __LINE__)); c = 0; } } else { c = *(uint8_t *)scp->request_buffer; } if ((c & 0x1F ) == TYPE_DISK) { pdev_index = (scb->dev_channel * 16) + scb->dev_target; pdev_state = raid_dev->pdrv_state[pdev_index] & 0x0F; if (pdev_state == PDRV_ONLINE || pdev_state == PDRV_FAILED || pdev_state == PDRV_RBLD || pdev_state == PDRV_HOTSPARE || megaraid_expose_unconf_disks == 0) { status = 0xF0; } } } // Convert MegaRAID status to Linux error code switch (status) { case 0x00: scp->result = (DID_OK << 16); break; case 0x02: /* set sense_buffer and result fields */ if (mbox->cmd == MBOXCMD_PASSTHRU || mbox->cmd == MBOXCMD_PASSTHRU64) { memcpy(scp->sense_buffer, pthru->reqsensearea, 14); scp->result = DRIVER_SENSE << 24 | DID_OK << 16 | CHECK_CONDITION << 1; } else { if (mbox->cmd == MBOXCMD_EXTPTHRU) { memcpy(scp->sense_buffer, epthru->reqsensearea, 14); scp->result = DRIVER_SENSE << 24 | DID_OK << 16 | CHECK_CONDITION << 1; } else { scp->sense_buffer[0] = 0x70; scp->sense_buffer[2] = ABORTED_COMMAND; scp->result = CHECK_CONDITION << 1; } } break; case 0x08: scp->result = DID_BUS_BUSY << 16 | status; break; default: /* * If TEST_UNIT_READY fails, we know RESERVATION_STATUS * failed */ if (scp->cmnd[0] == TEST_UNIT_READY) { scp->result = DID_ERROR << 16 | RESERVATION_CONFLICT << 1; } else /* * Error code returned is 1 if Reserve or Release * failed or the input parameter is invalid */ if (status == 1 && (scp->cmnd[0] == RESERVE || scp->cmnd[0] == RELEASE)) { scp->result = DID_ERROR << 16 | RESERVATION_CONFLICT << 1; } else { scp->result = DID_BAD_TARGET << 16 | status; } } // print a debug message for all failed commands if (status) { megaraid_mbox_display_scb(adapter, scb); } // Free our internal resources and call the mid-layer callback // routine megaraid_mbox_sync_scb(adapter, scb); // remove from local clist list_del_init(&scb->list); // put back in free list megaraid_dealloc_scb(adapter, scb); // send the scsi packet back to kernel spin_lock(adapter->host_lock); scp->scsi_done(scp); spin_unlock(adapter->host_lock); } if (crashdump_mode()) mraid_mm_woken = 1; return; } /** * megaraid_abort_handler - abort the scsi command * @scp : command to be aborted * * Abort a previous SCSI request. Only commands on the pending list can be * aborted. All the commands issued to the F/W must complete. **/ static int megaraid_abort_handler(struct scsi_cmnd *scp) { adapter_t *adapter; mraid_device_t *raid_dev; scb_t *scb; scb_t *tmp; int found; unsigned long flags; int i; adapter = SCP2ADAPTER(scp); raid_dev = ADAP2RAIDDEV(adapter); ASSERT(spin_is_locked(adapter->host_lock)); con_log(CL_ANN, (KERN_WARNING "megaraid: aborting-%ld cmd=%x \n", scp->serial_number, scp->cmnd[0], SCP2CHANNEL(scp), SCP2TARGET(scp), SCP2LUN(scp))); // If FW has stopped responding, simply return failure if (raid_dev->hw_error) { con_log(CL_ANN, (KERN_NOTICE "megaraid: hw error, not aborting\n")); return FAILED; } // There might a race here, where the command was completed by the // firmware and now it is on the completed list. Before we could // complete the command to the kernel in dpc, the abort came. // Find out if this is the case to avoid the race. scb = NULL; spin_lock_irqsave(COMPLETED_LIST_LOCK(adapter), flags); list_for_each_entry_safe(scb, tmp, &adapter->completed_list, list) { if (scb->scp == scp) { // Found command list_del_init(&scb->list); // from completed list con_log(CL_ANN, (KERN_WARNING "megaraid: %ld:%d[%d:%d], abort from completed list\n", scp->serial_number, scb->sno, scb->dev_channel, scb->dev_target)); scp->result = (DID_ABORT << 16); scp->scsi_done(scp); megaraid_dealloc_scb(adapter, scb); spin_unlock_irqrestore(COMPLETED_LIST_LOCK(adapter), flags); return SUCCESS; } } spin_unlock_irqrestore(COMPLETED_LIST_LOCK(adapter), flags); // Find out if this command is still on the pending list. If it is and // was never issued, abort and return success. If the command is owned // by the firmware, we must wait for it to complete by the FW. spin_lock_irqsave(PENDING_LIST_LOCK(adapter), flags); list_for_each_entry_safe(scb, tmp, &adapter->pend_list, list) { if (scb->scp == scp) { // Found command list_del_init(&scb->list); // from pending list ASSERT(!(scb->state & SCB_ISSUED)); con_log(CL_ANN, (KERN_WARNING "megaraid abort: %ld[%d:%d], driver owner\n", scp->serial_number, scb->dev_channel, scb->dev_target)); scp->result = (DID_ABORT << 16); scp->scsi_done(scp); megaraid_dealloc_scb(adapter, scb); spin_unlock_irqrestore(PENDING_LIST_LOCK(adapter), flags); return SUCCESS; } } spin_unlock_irqrestore(PENDING_LIST_LOCK(adapter), flags); // Check do we even own this command, in which case this would be // owned by the firmware. The only way to locate the FW scb is to // traverse through the list of all SCB, since driver does not // maintain these SCBs on any list found = 0; for (i = 0; i < MBOX_MAX_SCSI_CMDS; i++) { scb = adapter->kscb_list + i; if (scb->scp == scp) { found = 1; if (!(scb->state & SCB_ISSUED)) { con_log(CL_ANN, (KERN_WARNING "megaraid abort: %ld%d[%d:%d], invalid state\n", scp->serial_number, scb->sno, scb->dev_channel, scb->dev_target)); BUG(); } else { con_log(CL_ANN, (KERN_WARNING "megaraid abort: %ld:%d[%d:%d], fw owner\n", scp->serial_number, scb->sno, scb->dev_channel, scb->dev_target)); } } } if (!found) { con_log(CL_ANN, (KERN_WARNING "megaraid abort: scsi cmd:%ld, do now own\n", scp->serial_number)); // FIXME: Should there be a callback for this command? return SUCCESS; } // We cannot actually abort a command owned by firmware, return // failure and wait for reset. In host reset handler, we will find out // if the HBA is still live return FAILED; } /** * megaraid_reset_handler - device reset hadler for mailbox based driver * @scp : reference command * * Reset handler for the mailbox based controller. First try to find out if * the FW is still live, in which case the outstanding commands counter mut go * down to 0. If that happens, also issue the reservation reset command to * relinquish (possible) reservations on the logical drives connected to this * host **/ static int megaraid_reset_handler(struct scsi_cmnd *scp) { adapter_t *adapter; scb_t *scb; scb_t *tmp; mraid_device_t *raid_dev; unsigned long flags; uint8_t raw_mbox[sizeof(mbox_t)]; int rval; int recovery_window; int recovering; int i; adapter = SCP2ADAPTER(scp); raid_dev = ADAP2RAIDDEV(adapter); ASSERT(spin_is_locked(adapter->host_lock)); con_log(CL_ANN, (KERN_WARNING "megaraid: resetting the host...\n")); // return failure if adapter is not responding if (raid_dev->hw_error) { con_log(CL_ANN, (KERN_NOTICE "megaraid: hw error, cannot reset\n")); return FAILED; } // Under exceptional conditions, FW can take up to 3 minutes to // complete command processing. Wait for additional 2 minutes for the // pending commands counter to go down to 0. If it doesn't, let the // controller be marked offline // Also, reset all the commands currently owned by the driver spin_lock_irqsave(PENDING_LIST_LOCK(adapter), flags); list_for_each_entry_safe(scb, tmp, &adapter->pend_list, list) { list_del_init(&scb->list); // from pending list con_log(CL_ANN, (KERN_WARNING "megaraid: %ld:%d[%d:%d], reset from pending list\n", scp->serial_number, scb->sno, scb->dev_channel, scb->dev_target)); scp->result = (DID_RESET << 16); if (scp->scsi_done) { scp->scsi_done(scp); } megaraid_dealloc_scb(adapter, scb); } spin_unlock_irqrestore(PENDING_LIST_LOCK(adapter), flags); if (adapter->outstanding_cmds) { con_log(CL_ANN, (KERN_NOTICE "megaraid: %d outstanding commands. Max wait %d sec\n", adapter->outstanding_cmds, MBOX_RESET_WAIT)); } spin_unlock(adapter->host_lock); recovery_window = MBOX_RESET_WAIT + MBOX_RESET_EXT_WAIT; recovering = adapter->outstanding_cmds; for (i = 0; i < recovery_window && adapter->outstanding_cmds; i++) { megaraid_ack_sequence(adapter); // print a message once every 5 seconds only if (!(i % 5)) { con_log(CL_ANN, ( "megaraid mbox: Wait for %d commands to complete:%d\n", adapter->outstanding_cmds, MBOX_RESET_WAIT - i)); } // bailout if no recovery happended in reset time if ((i == MBOX_RESET_WAIT) && (recovering == adapter->outstanding_cmds)) { break; } msleep(1000); } spin_lock(adapter->host_lock); // If still outstanding commands, bail out if (adapter->outstanding_cmds) { con_log(CL_ANN, (KERN_WARNING "megaraid mbox: critical hardware error!\n")); raid_dev->hw_error = 1; return FAILED; } else { con_log(CL_ANN, (KERN_NOTICE "megaraid mbox: reset sequence completed successfully\n")); } // If the controller supports clustering, reset reservations if (!adapter->ha) return SUCCESS; // clear reservations if any raw_mbox[0] = CLUSTER_CMD; raw_mbox[2] = RESET_RESERVATIONS; rval = SUCCESS; if (mbox_post_sync_cmd_fast(adapter, raw_mbox) == 0) { con_log(CL_ANN, (KERN_INFO "megaraid: reservation reset\n")); } else { rval = FAILED; con_log(CL_ANN, (KERN_WARNING "megaraid: reservation reset failed\n")); } return rval; } /* * START: internal commands library * * This section of the driver has the common routine used by the driver and * also has all the FW routines */ /** * mbox_post_sync_cmd() - blocking command to the mailbox based controllers * @adapter - controller's soft state * @raw_mbox - the mailbox * * Issue a scb in synchronous and non-interrupt mode for mailbox based * controllers */ static int mbox_post_sync_cmd(adapter_t *adapter, uint8_t raw_mbox[]) { mraid_device_t *raid_dev = ADAP2RAIDDEV(adapter); mbox64_t *mbox64; mbox_t *mbox; uint8_t status; int i; mbox64 = raid_dev->mbox64; mbox = raid_dev->mbox; /* * Wait until mailbox is free */ if (megaraid_busywait_mbox(raid_dev) != 0) goto blocked_mailbox; /* * Copy mailbox data into host structure */ memcpy((caddr_t)mbox, (caddr_t)raw_mbox, 16); mbox->cmdid = 0xFE; mbox->busy = 1; mbox->poll = 0; mbox->ack = 0; mbox->numstatus = 0xFF; mbox->status = 0xFF; wmb(); WRINDOOR(raid_dev, raid_dev->mbox_dma | 0x1); // wait for maximum 1 second for status to post. If the status is not // available within 1 second, assume FW is initializing and wait // for an extended amount of time if (mbox->numstatus == 0xFF) { // status not yet available udelay(25);; for (i = 0; mbox->numstatus == 0xFF && i < 1000; i++) { rmb(); msleep(1); } if (i == 1000) { con_log(CL_ANN, (KERN_NOTICE "megaraid mailbox: wait for FW to boot ")); for (i = 0; (mbox->numstatus == 0xFF) && (i < MBOX_RESET_WAIT); i++) { rmb(); con_log(CL_ANN, ("\b\b\b\b\b[%03d]", MBOX_RESET_WAIT - i)); msleep(1000); } if (i == MBOX_RESET_WAIT) { con_log(CL_ANN, ( "\nmegaraid mailbox: status not available\n")); return -1; } con_log(CL_ANN, ("\b\b\b\b\b[ok] \n")); } } // wait for maximum 1 second for poll semaphore if (mbox->poll != 0x77) { udelay(25); for (i = 0; (mbox->poll != 0x77) && (i < 1000); i++) { rmb(); msleep(1); } if (i == 1000) { con_log(CL_ANN, (KERN_WARNING "megaraid mailbox: could not get poll semaphore\n")); return -1; } } WRINDOOR(raid_dev, raid_dev->mbox_dma | 0x2); wmb(); // wait for maximum 1 second for acknowledgement if (RDINDOOR(raid_dev) & 0x2) { udelay(25); for (i = 0; (RDINDOOR(raid_dev) & 0x2) && (i < 1000); i++) { rmb(); msleep(1); } if (i == 1000) { con_log(CL_ANN, (KERN_WARNING "megaraid mailbox: could not acknowledge\n")); return -1; } } mbox->poll = 0; mbox->ack = 0x77; status = mbox->status; // invalidate the completed command id array. After command // completion, firmware would write the valid id. mbox->numstatus = 0xFF; mbox->status = 0xFF; for (i = 0; i < MBOX_MAX_FIRMWARE_STATUS; i++) { mbox->completed[i] = 0xFF; } return status; blocked_mailbox: con_log(CL_ANN, (KERN_WARNING "megaraid: blocked mailbox\n") ); return -1; } /** * mbox_post_sync_cmd_fast - blocking command to the mailbox based controllers * @adapter - controller's soft state * @raw_mbox - the mailbox * * Issue a scb in synchronous and non-interrupt mode for mailbox based * controllers. This is a faster version of the synchronous command and * therefore can be called in interrupt-context as well */ static int mbox_post_sync_cmd_fast(adapter_t *adapter, uint8_t raw_mbox[]) { mraid_device_t *raid_dev = ADAP2RAIDDEV(adapter); mbox_t *mbox; long i; mbox = raid_dev->mbox; // return immediately if the mailbox is busy if (mbox->busy) return -1; // Copy mailbox data into host structure memcpy((caddr_t)mbox, (caddr_t)raw_mbox, 14); mbox->cmdid = 0xFE; mbox->busy = 1; mbox->poll = 0; mbox->ack = 0; mbox->numstatus = 0xFF; mbox->status = 0xFF; wmb(); WRINDOOR(raid_dev, raid_dev->mbox_dma | 0x1); for (i = 0; i < MBOX_SYNC_WAIT_CNT; i++) { if (mbox->numstatus != 0xFF) break; rmb(); udelay(MBOX_SYNC_DELAY_200); } if (i == MBOX_SYNC_WAIT_CNT) { // We may need to re-calibrate the counter con_log(CL_ANN, (KERN_CRIT "megaraid: fast sync command timed out\n")); } WRINDOOR(raid_dev, raid_dev->mbox_dma | 0x2); wmb(); return mbox->status; } /** * megaraid_busywait_mbox() - Wait until the controller's mailbox is available * @raid_dev - RAID device (HBA) soft state * * wait until the controller's mailbox is available to accept more commands. * wait for at most 1 second */ static int megaraid_busywait_mbox(mraid_device_t *raid_dev) { mbox_t *mbox = raid_dev->mbox; int i = 0; if (mbox->busy) { udelay(25); for (i = 0; mbox->busy && i < 1000; i++) msleep(1); } if (i < 1000) return 0; else return -1; } /** * megaraid_mbox_product_info - some static information about the controller * @adapter - our soft state * * issue commands to the controller to grab some parameters required by our * caller. */ static int megaraid_mbox_product_info(adapter_t *adapter) { mraid_device_t *raid_dev = ADAP2RAIDDEV(adapter); mbox_t *mbox; uint8_t raw_mbox[sizeof(mbox_t)]; mraid_pinfo_t *pinfo; dma_addr_t pinfo_dma_h; mraid_inquiry3_t *mraid_inq3; int i; memset((caddr_t)raw_mbox, 0, sizeof(raw_mbox)); mbox = (mbox_t *)raw_mbox; /* * Issue an ENQUIRY3 command to find out certain adapter parameters, * e.g., max channels, max commands etc. */ pinfo = pci_alloc_consistent(adapter->pdev, sizeof(mraid_pinfo_t), &pinfo_dma_h); if (pinfo == NULL) { con_log(CL_ANN, (KERN_WARNING "megaraid: out of memory, %s %d\n", __FUNCTION__, __LINE__)); return -1; } memset(pinfo, 0, sizeof(mraid_pinfo_t)); mbox->xferaddr = (uint32_t)adapter->ibuf_dma_h; memset((void *)adapter->ibuf, 0, MBOX_IBUF_SIZE); raw_mbox[0] = FC_NEW_CONFIG; raw_mbox[2] = NC_SUBOP_ENQUIRY3; raw_mbox[3] = ENQ3_GET_SOLICITED_FULL; // Issue the command if (mbox_post_sync_cmd(adapter, raw_mbox) != 0) { con_log(CL_ANN, (KERN_WARNING "megaraid: Inquiry3 failed\n")); pci_free_consistent(adapter->pdev, sizeof(mraid_pinfo_t), pinfo, pinfo_dma_h); return -1; } /* * Collect information about state of each physical drive * attached to the controller. We will expose all the disks * which are not part of RAID */ mraid_inq3 = (mraid_inquiry3_t *)adapter->ibuf; for (i = 0; i < MBOX_MAX_PHYSICAL_DRIVES; i++) { raid_dev->pdrv_state[i] = mraid_inq3->pdrv_state[i]; } /* * Get product info for information like number of channels, * maximum commands supported. */ memset((caddr_t)raw_mbox, 0, sizeof(raw_mbox)); mbox->xferaddr = (uint32_t)pinfo_dma_h; raw_mbox[0] = FC_NEW_CONFIG; raw_mbox[2] = NC_SUBOP_PRODUCT_INFO; if (mbox_post_sync_cmd(adapter, raw_mbox) != 0) { con_log(CL_ANN, (KERN_WARNING "megaraid: product info failed\n")); pci_free_consistent(adapter->pdev, sizeof(mraid_pinfo_t), pinfo, pinfo_dma_h); return -1; } /* * Setup some parameters for host, as required by our caller */ adapter->max_channel = pinfo->nchannels; /* * we will export all the logical drives on a single channel. * Add 1 since inquires do not come for inititor ID */ adapter->max_target = MAX_LOGICAL_DRIVES_40LD + 1; adapter->max_lun = 8; // up to 8 LUNs for non-disk devices /* * These are the maximum outstanding commands for the scsi-layer */ adapter->max_cmds = MBOX_MAX_SCSI_CMDS; memset(adapter->fw_version, 0, VERSION_SIZE); memset(adapter->bios_version, 0, VERSION_SIZE); memcpy(adapter->fw_version, pinfo->fw_version, 4); adapter->fw_version[4] = 0; memcpy(adapter->bios_version, pinfo->bios_version, 4); adapter->bios_version[4] = 0; con_log(CL_ANN, (KERN_NOTICE "megaraid: fw version:[%s] bios version:[%s]\n", adapter->fw_version, adapter->bios_version)); pci_free_consistent(adapter->pdev, sizeof(mraid_pinfo_t), pinfo, pinfo_dma_h); return 0; } /** * megaraid_mbox_extended_cdb - check for support for extended CDBs * @adapter - soft state for the controller * * this routine check whether the controller in question supports extended * ( > 10 bytes ) CDBs */ static int megaraid_mbox_extended_cdb(adapter_t *adapter) { mbox_t *mbox; uint8_t raw_mbox[sizeof(mbox_t)]; int rval; mbox = (mbox_t *)raw_mbox; memset((caddr_t)raw_mbox, 0, sizeof(raw_mbox)); mbox->xferaddr = (uint32_t)adapter->ibuf_dma_h; memset((void *)adapter->ibuf, 0, MBOX_IBUF_SIZE); raw_mbox[0] = MAIN_MISC_OPCODE; raw_mbox[2] = SUPPORT_EXT_CDB; /* * Issue the command */ rval = 0; if (mbox_post_sync_cmd(adapter, raw_mbox) != 0) { rval = -1; } return rval; } /** * megaraid_mbox_support_ha - Do we support clustering * @adapter - soft state for the controller * @init_id - ID of the initiator * * Determine if the firmware supports clustering and the ID of the initiator. */ static int megaraid_mbox_support_ha(adapter_t *adapter, uint16_t *init_id) { mbox_t *mbox; uint8_t raw_mbox[sizeof(mbox_t)]; int rval; mbox = (mbox_t *)raw_mbox; memset((caddr_t)raw_mbox, 0, sizeof(raw_mbox)); mbox->xferaddr = (uint32_t)adapter->ibuf_dma_h; memset((void *)adapter->ibuf, 0, MBOX_IBUF_SIZE); raw_mbox[0] = GET_TARGET_ID; // Issue the command *init_id = 7; rval = -1; if (mbox_post_sync_cmd(adapter, raw_mbox) == 0) { *init_id = *(uint8_t *)adapter->ibuf; con_log(CL_ANN, (KERN_INFO "megaraid: cluster firmware, initiator ID: %d\n", *init_id)); rval = 0; } return rval; } /** * megaraid_mbox_support_random_del - Do we support random deletion * @adapter - soft state for the controller * * Determine if the firmware supports random deletion * Return: 1 is operation supported, 0 otherwise */ static int megaraid_mbox_support_random_del(adapter_t *adapter) { mbox_t *mbox; uint8_t raw_mbox[sizeof(mbox_t)]; int rval; mbox = (mbox_t *)raw_mbox; memset((caddr_t)raw_mbox, 0, sizeof(mbox_t)); raw_mbox[0] = FC_DEL_LOGDRV; raw_mbox[2] = OP_SUP_DEL_LOGDRV; // Issue the command rval = 0; if (mbox_post_sync_cmd(adapter, raw_mbox) == 0) { con_log(CL_DLEVEL1, ("megaraid: supports random deletion\n")); rval = 1; } return rval; } /** * megaraid_mbox_get_max_sg - maximum sg elements supported by the firmware * @adapter - soft state for the controller * * Find out the maximum number of scatter-gather elements supported by the * firmware */ static int megaraid_mbox_get_max_sg(adapter_t *adapter) { mbox_t *mbox; uint8_t raw_mbox[sizeof(mbox_t)]; int nsg; mbox = (mbox_t *)raw_mbox; memset((caddr_t)raw_mbox, 0, sizeof(mbox_t)); mbox->xferaddr = (uint32_t)adapter->ibuf_dma_h; memset((void *)adapter->ibuf, 0, MBOX_IBUF_SIZE); raw_mbox[0] = MAIN_MISC_OPCODE; raw_mbox[2] = GET_MAX_SG_SUPPORT; // Issue the command if (mbox_post_sync_cmd(adapter, raw_mbox) == 0) { nsg = *(uint8_t *)adapter->ibuf; } else { nsg = MBOX_DEFAULT_SG_SIZE; } if (nsg > MBOX_MAX_SG_SIZE) nsg = MBOX_MAX_SG_SIZE; return nsg; } /** * megaraid_mbox_enum_raid_scsi - enumerate the RAID and SCSI channels * @adapter - soft state for the controller * * Enumerate the RAID and SCSI channels for ROMB platoforms so that channels * can be exported as regular SCSI channels */ static void megaraid_mbox_enum_raid_scsi(adapter_t *adapter) { mraid_device_t *raid_dev = ADAP2RAIDDEV(adapter); mbox_t *mbox; uint8_t raw_mbox[sizeof(mbox_t)]; mbox = (mbox_t *)raw_mbox; memset((caddr_t)raw_mbox, 0, sizeof(mbox_t)); mbox->xferaddr = (uint32_t)adapter->ibuf_dma_h; memset((void *)adapter->ibuf, 0, MBOX_IBUF_SIZE); raw_mbox[0] = CHNL_CLASS; raw_mbox[2] = GET_CHNL_CLASS; // Issue the command. If the command fails, all channels are RAID // channels raid_dev->channel_class = 0xFF; if (mbox_post_sync_cmd(adapter, raw_mbox) == 0) { raid_dev->channel_class = *(uint8_t *)adapter->ibuf; } return; } /** * megaraid_mbox_flush_cache - flush adapter and disks cache * @param adapter : soft state for the controller * * Flush adapter cache followed by disks cache */ static void megaraid_mbox_flush_cache(adapter_t *adapter) { mbox_t *mbox; uint8_t raw_mbox[sizeof(mbox_t)]; mbox = (mbox_t *)raw_mbox; memset((caddr_t)raw_mbox, 0, sizeof(mbox_t)); raw_mbox[0] = FLUSH_ADAPTER; if (mbox_post_sync_cmd(adapter, raw_mbox) != 0) { con_log(CL_ANN, ("megaraid: flush adapter failed\n")); } raw_mbox[0] = FLUSH_SYSTEM; if (mbox_post_sync_cmd(adapter, raw_mbox) != 0) { con_log(CL_ANN, ("megaraid: flush disks cache failed\n")); } return; } /** * megaraid_mbox_display_scb - display SCB information, mostly debug purposes * @param adapter : controllers' soft state * @param scb : SCB to be displayed * @param level : debug level for console print * * Diplay information about the given SCB iff the current debug level is * verbose */ static void megaraid_mbox_display_scb(adapter_t *adapter, scb_t *scb) { mbox_ccb_t *ccb; struct scsi_cmnd *scp; mbox_t *mbox; int level; int i; ccb = (mbox_ccb_t *)scb->ccb; scp = scb->scp; mbox = ccb->mbox; level = CL_DLEVEL3; con_log(level, (KERN_NOTICE "megaraid mailbox: status:%#x cmd:%#x id:%#x ", scb->status, mbox->cmd, scb->sno)); con_log(level, ("sec:%#x lba:%#x addr:%#x ld:%d sg:%d\n", mbox->numsectors, mbox->lba, mbox->xferaddr, mbox->logdrv, mbox->numsge)); if (!scp) return; con_log(level, (KERN_NOTICE "scsi cmnd: ")); for (i = 0; i < scp->cmd_len; i++) { con_log(level, ("%#2.02x ", scp->cmnd[i])); } con_log(level, ("\n")); return; } /** * megaraid_mbox_setup_device_map - manage device ids * @adapter : Driver's soft state * * Manange the device ids to have an appropraite mapping between the kernel * scsi addresses and megaraid scsi and logical drive addresses. We export * scsi devices on their actual addresses, whereas the logical drives are * exported on a virtual scsi channel. **/ static void megaraid_mbox_setup_device_map(adapter_t *adapter) { uint8_t c; uint8_t t; /* * First fill the values on the logical drive channel */ for (t = 0; t < LSI_MAX_LOGICAL_DRIVES_64LD; t++) adapter->device_ids[adapter->max_channel][t] = (t < adapter->init_id) ? t : t - 1; adapter->device_ids[adapter->max_channel][adapter->init_id] = 0xFF; /* * Fill the values on the physical devices channels */ for (c = 0; c < adapter->max_channel; c++) for (t = 0; t < LSI_MAX_LOGICAL_DRIVES_64LD; t++) adapter->device_ids[c][t] = (c << 8) | t; } /* * END: internal commands library */ /* * START: Interface for the common management module * * This is the module, which interfaces with the common mangement module to * provide support for ioctl and sysfs */ /** * megaraid_cmm_register - register with the mangement module * @param adapter : HBA soft state * * Register with the management module, which allows applications to issue * ioctl calls to the drivers. This interface is used by the management module * to setup sysfs support as well. */ static int megaraid_cmm_register(adapter_t *adapter) { mraid_device_t *raid_dev = ADAP2RAIDDEV(adapter); mraid_mmadp_t adp; scb_t *scb; mbox_ccb_t *ccb; int rval; int i; // Allocate memory for the base list of scb for management module. adapter->uscb_list = kmalloc(sizeof(scb_t) * MBOX_MAX_USER_CMDS, GFP_KERNEL); if (adapter->uscb_list == NULL) { con_log(CL_ANN, (KERN_WARNING "megaraid: out of memory, %s %d\n", __FUNCTION__, __LINE__)); return -1; } memset(adapter->uscb_list, 0, sizeof(scb_t) * MBOX_MAX_USER_CMDS); // Initialize the synchronization parameters for resources for // commands for management module INIT_LIST_HEAD(&adapter->uscb_pool); spin_lock_init(USER_FREE_LIST_LOCK(adapter)); // link all the packets. Note, CCB for commands, coming from the // commom management module, mailbox physical address are already // setup by it. We just need placeholder for that in our local command // control blocks for (i = 0; i < MBOX_MAX_USER_CMDS; i++) { scb = adapter->uscb_list + i; ccb = raid_dev->uccb_list + i; scb->ccb = (caddr_t)ccb; ccb->mbox64 = raid_dev->umbox64 + i; ccb->mbox = &ccb->mbox64->mbox32; ccb->raw_mbox = (uint8_t *)ccb->mbox; scb->gp = 0; // COMMAND ID 0 - (MBOX_MAX_SCSI_CMDS-1) ARE RESERVED FOR // COMMANDS COMING FROM IO SUBSYSTEM (MID-LAYER) scb->sno = i + MBOX_MAX_SCSI_CMDS; scb->scp = NULL; scb->state = SCB_FREE; scb->dma_direction = PCI_DMA_NONE; scb->dma_type = MRAID_DMA_NONE; scb->dev_channel = -1; scb->dev_target = -1; // put scb in the free pool list_add_tail(&scb->list, &adapter->uscb_pool); } adp.unique_id = adapter->unique_id; adp.drvr_type = DRVRTYPE_MBOX; adp.drvr_data = (unsigned long)adapter; adp.pdev = adapter->pdev; adp.issue_uioc = megaraid_mbox_mm_handler; adp.timeout = 300; adp.max_kioc = MBOX_MAX_USER_CMDS; if ((rval = mraid_mm_register_adp(&adp)) != 0) { con_log(CL_ANN, (KERN_WARNING "megaraid mbox: did not register with CMM\n")); kfree(adapter->uscb_list); } return rval; } /** * megaraid_cmm_unregister - un-register with the mangement module * @param adapter : HBA soft state * * Un-register with the management module. * FIXME: mgmt module must return failure for unregister if it has pending * commands in LLD */ static int megaraid_cmm_unregister(adapter_t *adapter) { kfree(adapter->uscb_list); mraid_mm_unregister_adp(adapter->unique_id); return 0; } /** * megaraid_mbox_mm_handler - interface for CMM to issue commands to LLD * @param drvr_data : LLD specific data * @param kioc : CMM interface packet * @param action : command action * * This routine is invoked whenever the Common Mangement Module (CMM) has a * command for us. The 'action' parameter specifies if this is a new command * or otherwise. */ static int megaraid_mbox_mm_handler(unsigned long drvr_data, uioc_t *kioc, uint32_t action) { adapter_t *adapter; if (action != IOCTL_ISSUE) { con_log(CL_ANN, (KERN_WARNING "megaraid: unsupported management action:%#2x\n", action)); return (-ENOTSUPP); } adapter = (adapter_t *)drvr_data; // make sure this adapter is not being detached right now. if (atomic_read(&adapter->being_detached)) { con_log(CL_ANN, (KERN_WARNING "megaraid: reject management request, detaching\n")); return (-ENODEV); } switch (kioc->opcode) { case GET_ADAP_INFO: kioc->status = gather_hbainfo(adapter, (mraid_hba_info_t *) (unsigned long)kioc->buf_vaddr); kioc->done(kioc); return kioc->status; case MBOX_CMD: return megaraid_mbox_mm_command(adapter, kioc); default: kioc->status = (-EINVAL); kioc->done(kioc); return (-EINVAL); } return 0; // not reached } /** * megaraid_mbox_mm_command - issues commands routed through CMM * @param adapter : HBA soft state * @param kioc : management command packet * * Issues commands, which are routed through the management module. */ static int megaraid_mbox_mm_command(adapter_t *adapter, uioc_t *kioc) { struct list_head *head = &adapter->uscb_pool; mbox64_t *mbox64; uint8_t *raw_mbox; scb_t *scb; mbox_ccb_t *ccb; unsigned long flags; // detach one scb from free pool spin_lock_irqsave(USER_FREE_LIST_LOCK(adapter), flags); if (list_empty(head)) { // should never happen because of CMM con_log(CL_ANN, (KERN_WARNING "megaraid mbox: bug in cmm handler, lost resources\n")); spin_unlock_irqrestore(USER_FREE_LIST_LOCK(adapter), flags); return (-EINVAL); } scb = list_entry(head->next, scb_t, list); list_del_init(&scb->list); spin_unlock_irqrestore(USER_FREE_LIST_LOCK(adapter), flags); scb->state = SCB_ACTIVE; scb->dma_type = MRAID_DMA_NONE; scb->dma_direction = PCI_DMA_NONE; ccb = (mbox_ccb_t *)scb->ccb; mbox64 = (mbox64_t *)(unsigned long)kioc->cmdbuf; raw_mbox = (uint8_t *)&mbox64->mbox32; memcpy(ccb->mbox64, mbox64, sizeof(mbox64_t)); scb->gp = (unsigned long)kioc; /* * If it is a logdrv random delete operation, we have to wait till * there are no outstanding cmds at the fw and then issue it directly */ if (raw_mbox[0] == FC_DEL_LOGDRV && raw_mbox[2] == OP_DEL_LOGDRV) { if (wait_till_fw_empty(adapter)) { con_log(CL_ANN, (KERN_NOTICE "megaraid mbox: LD delete, timed out\n")); kioc->status = -ETIME; scb->status = -1; megaraid_mbox_mm_done(adapter, scb); return (-ETIME); } INIT_LIST_HEAD(&scb->list); scb->state = SCB_ISSUED; if (mbox_post_cmd(adapter, scb) != 0) { con_log(CL_ANN, (KERN_NOTICE "megaraid mbox: LD delete, mailbox busy\n")); kioc->status = -EBUSY; scb->status = -1; megaraid_mbox_mm_done(adapter, scb); return (-EBUSY); } return 0; } // put the command on the pending list and execute megaraid_mbox_runpendq(adapter, scb); return 0; } static int wait_till_fw_empty(adapter_t *adapter) { unsigned long flags = 0; int i; /* * Set the quiescent flag to stop issuing cmds to FW. */ spin_lock_irqsave(adapter->host_lock, flags); adapter->quiescent++; spin_unlock_irqrestore(adapter->host_lock, flags); /* * Wait till there are no more cmds outstanding at FW. Try for at most * 60 seconds */ for (i = 0; i < 60 && adapter->outstanding_cmds; i++) { con_log(CL_DLEVEL1, (KERN_INFO "megaraid: FW has %d pending commands\n", adapter->outstanding_cmds)); msleep(1000); } return adapter->outstanding_cmds; } /** * megaraid_mbox_mm_done - callback for CMM commands * @adapter : HBA soft state * @scb : completed command * * Callback routine for internal commands originated from the management * module. */ static void megaraid_mbox_mm_done(adapter_t *adapter, scb_t *scb) { uioc_t *kioc; mbox64_t *mbox64; uint8_t *raw_mbox; unsigned long flags; kioc = (uioc_t *)scb->gp; kioc->status = 0; mbox64 = (mbox64_t *)(unsigned long)kioc->cmdbuf; mbox64->mbox32.status = scb->status; raw_mbox = (uint8_t *)&mbox64->mbox32; // put scb in the free pool scb->state = SCB_FREE; scb->scp = NULL; spin_lock_irqsave(USER_FREE_LIST_LOCK(adapter), flags); list_add(&scb->list, &adapter->uscb_pool); spin_unlock_irqrestore(USER_FREE_LIST_LOCK(adapter), flags); // if a delete logical drive operation succeeded, restart the // controller if (raw_mbox[0] == FC_DEL_LOGDRV && raw_mbox[2] == OP_DEL_LOGDRV) { adapter->quiescent--; megaraid_mbox_runpendq(adapter, NULL); } kioc->done(kioc); return; } /** * gather_hbainfo - HBA characteristics for the applications * @param adapter : HBA soft state * @param hinfo : pointer to the caller's host info strucuture */ static int gather_hbainfo(adapter_t *adapter, mraid_hba_info_t *hinfo) { uint8_t dmajor; dmajor = megaraid_mbox_version[0]; hinfo->pci_vendor_id = adapter->pdev->vendor; hinfo->pci_device_id = adapter->pdev->device; hinfo->subsys_vendor_id = adapter->pdev->subsystem_vendor; hinfo->subsys_device_id = adapter->pdev->subsystem_device; hinfo->pci_bus = adapter->pdev->bus->number; hinfo->pci_dev_fn = adapter->pdev->devfn; hinfo->pci_slot = PCI_SLOT(adapter->pdev->devfn); hinfo->irq = adapter->host->irq; hinfo->baseport = ADAP2RAIDDEV(adapter)->baseport; hinfo->unique_id = (hinfo->pci_bus << 8) | adapter->pdev->devfn; hinfo->host_no = adapter->host->host_no; return 0; } /* * END: Interface for the common management module */ extern struct scsi_device *mraid_mm_diskdump_poll_device; extern void (*mraid_mm_poll_func)(struct scsi_device *device); static int megaraid_sanity_check(struct scsi_device *device) { adapter_t *adapter; adapter = (adapter_t *)SCSIHOST2ADAP(device->host); if ( adapter == NULL ) { return -ENXIO; } #ifdef SCSI_HAS_HOST_LOCK if (spin_is_locked(adapter->host_lock)) { return -EBUSY; } #endif mraid_mm_poll_func = megaraid_poll; mraid_mm_diskdump_poll_device = device; return 0; } static int megaraid_quiesce(struct scsi_device *device) { adapter_t *adapter; adapter = (adapter_t *)SCSIHOST2ADAP(device->host); /* * In case of crash dump, the tasklet list has been already abandoned * so the tasklet_struct must be reinitialized. * If it is not done, the tasklet is not scheduled because of garbage. */ tasklet_init(&adapter->dpc_h, megaraid_mbox_dpc, (unsigned long)adapter); return 0; } static void megaraid_poll(struct scsi_device *device) { adapter_t *adapter; u32 dword = 0; mraid_device_t *raid_dev; adapter = (adapter_t *)SCSIHOST2ADAP(device->host); /* Check if a valid interrupt is pending */ raid_dev = ADAP2RAIDDEV(adapter); dword = RDOUTDOOR(raid_dev); if ( dword != 0x10001234 ) { /* * No more pending commands */ return; } megaraid_isr(0, adapter, NULL); } static void megaraid_diskdump_sleep(unsigned int timeout) { unsigned long expire; if (!mraid_mm_diskdump_poll_device) { return; } expire = (unsigned long)timeout + jiffies; mraid_mm_woken = 0; while (time_before(jiffies, expire)) { megaraid_poll(mraid_mm_diskdump_poll_device); udelay(100); diskdump_update(); if (mraid_mm_woken) return; } return; } /** * megaraid_sysfs_alloc_resources - allocate sysfs related resources * * Allocate packets required to issue FW calls whenever the sysfs attributes * are read. These attributes would require up-to-date information from the * FW. Also set up resources for mutual exclusion to share these resources and * the wait queue. * * @param adapter : controller's soft state * * @return 0 on success * @return -ERROR_CODE on failure */ static int megaraid_sysfs_alloc_resources(adapter_t *adapter) { mraid_device_t *raid_dev = ADAP2RAIDDEV(adapter); int rval = 0; raid_dev->sysfs_uioc = kmalloc(sizeof(uioc_t), GFP_KERNEL); raid_dev->sysfs_mbox64 = kmalloc(sizeof(mbox64_t), GFP_KERNEL); raid_dev->sysfs_buffer = pci_alloc_consistent(adapter->pdev, PAGE_SIZE, &raid_dev->sysfs_buffer_dma); if (!raid_dev->sysfs_uioc || !raid_dev->sysfs_mbox64 || !raid_dev->sysfs_buffer) { con_log(CL_ANN, (KERN_WARNING "megaraid: out of memory, %s %d\n", __FUNCTION__, __LINE__)); rval = -ENOMEM; megaraid_sysfs_free_resources(adapter); } sema_init(&raid_dev->sysfs_sem, 1); init_waitqueue_head(&raid_dev->sysfs_wait_q); return rval; } /** * megaraid_sysfs_free_resources - free sysfs related resources * * Free packets allocated for sysfs FW commands * * @param adapter : controller's soft state */ static void megaraid_sysfs_free_resources(adapter_t *adapter) { mraid_device_t *raid_dev = ADAP2RAIDDEV(adapter); if (raid_dev->sysfs_uioc) kfree(raid_dev->sysfs_uioc); if (raid_dev->sysfs_mbox64) kfree(raid_dev->sysfs_mbox64); if (raid_dev->sysfs_buffer) { pci_free_consistent(adapter->pdev, PAGE_SIZE, raid_dev->sysfs_buffer, raid_dev->sysfs_buffer_dma); } } /** * megaraid_sysfs_get_ldmap_done - callback for get ldmap * * Callback routine called in the ISR/tasklet context for get ldmap call * * @param uioc : completed packet */ static void megaraid_sysfs_get_ldmap_done(uioc_t *uioc) { adapter_t *adapter = (adapter_t *)uioc->buf_vaddr; mraid_device_t *raid_dev = ADAP2RAIDDEV(adapter); uioc->status = 0; wake_up(&raid_dev->sysfs_wait_q); } /** * megaraid_sysfs_get_ldmap_timeout - timeout handling for get ldmap * * Timeout routine to recover and return to application, in case the adapter * has stopped responding. A timeout of 60 seconds for this command seem like * a good value * * @param uioc : timed out packet */ static void megaraid_sysfs_get_ldmap_timeout(unsigned long data) { uioc_t *uioc = (uioc_t *)data; adapter_t *adapter = (adapter_t *)uioc->buf_vaddr; mraid_device_t *raid_dev = ADAP2RAIDDEV(adapter); uioc->status = -ETIME; wake_up(&raid_dev->sysfs_wait_q); } /** * megaraid_sysfs_get_ldmap - get update logical drive map * * This routine will be called whenever user reads the logical drive * attributes, go get the current logical drive mapping table from the * firmware. We use the managment API's to issue commands to the controller. * * NOTE: The commands issuance functionality is not generalized and * implemented in context of "get ld map" command only. If required, the * command issuance logical can be trivially pulled out and implemented as a * standalone libary. For now, this should suffice since there is no other * user of this interface. * * @param adapter : controller's soft state * * @return 0 on success * @return -1 on failure */ static int megaraid_sysfs_get_ldmap(adapter_t *adapter) { mraid_device_t *raid_dev = ADAP2RAIDDEV(adapter); uioc_t *uioc; mbox64_t *mbox64; mbox_t *mbox; char *raw_mbox; struct timer_list sysfs_timer; struct timer_list *timerp; caddr_t ldmap; int rval = 0; /* * Allow only one read at a time to go through the sysfs attributes */ down(&raid_dev->sysfs_sem); uioc = raid_dev->sysfs_uioc; mbox64 = raid_dev->sysfs_mbox64; ldmap = raid_dev->sysfs_buffer; memset(uioc, 0, sizeof(uioc_t)); memset(mbox64, 0, sizeof(mbox64_t)); memset(ldmap, 0, sizeof(raid_dev->curr_ldmap)); mbox = &mbox64->mbox32; raw_mbox = (char *)mbox; uioc->cmdbuf = (uint64_t)(unsigned long)mbox64; uioc->buf_vaddr = (caddr_t)adapter; uioc->status = -ENODATA; uioc->done = megaraid_sysfs_get_ldmap_done; /* * Prepare the mailbox packet to get the current logical drive mapping * table */ mbox->xferaddr = (uint32_t)raid_dev->sysfs_buffer_dma; raw_mbox[0] = FC_DEL_LOGDRV; raw_mbox[2] = OP_GET_LDID_MAP; /* * Setup a timer to recover from a non-responding controller */ timerp = &sysfs_timer; init_timer(timerp); timerp->function = megaraid_sysfs_get_ldmap_timeout; timerp->data = (unsigned long)uioc; timerp->expires = jiffies + 60 * HZ; add_timer(timerp); /* * Send the command to the firmware */ rval = megaraid_mbox_mm_command(adapter, uioc); if (rval == 0) { // command successfully issued wait_event(raid_dev->sysfs_wait_q, (uioc->status != -ENODATA)); /* * Check if the command timed out */ if (uioc->status == -ETIME) { con_log(CL_ANN, (KERN_NOTICE "megaraid: sysfs get ld map timed out\n")); rval = -ETIME; } else { rval = mbox->status; } if (rval == 0) { memcpy(raid_dev->curr_ldmap, ldmap, sizeof(raid_dev->curr_ldmap)); } else { con_log(CL_ANN, (KERN_NOTICE "megaraid: get ld map failed with %x\n", rval)); } } else { con_log(CL_ANN, (KERN_NOTICE "megaraid: could not issue ldmap command:%x\n", rval)); } del_timer_sync(timerp); up(&raid_dev->sysfs_sem); return rval; } /** * megaraid_sysfs_show_app_hndl - display application handle for this adapter * * Display the handle used by the applications while executing management * tasks on the adapter. We invoke a management module API to get the adapter * handle, since we do not interface with applications directly. * * @param cdev : class device object representation for the host * @param buf : buffer to send data to */ static ssize_t megaraid_sysfs_show_app_hndl(struct class_device *cdev, char *buf) { struct Scsi_Host *shost = class_to_shost(cdev); adapter_t *adapter = (adapter_t *)SCSIHOST2ADAP(shost); uint32_t app_hndl; app_hndl = mraid_mm_adapter_app_handle(adapter->unique_id); return snprintf(buf, 8, "%u\n", app_hndl); } /** * megaraid_sysfs_show_ldnum - display the logical drive number for this device * * Display the logical drive number for the device in question, if it a valid * logical drive. For physical devices, "-1" is returned * The logical drive number is displayed in following format * * * * * @param dev : device object representation for the scsi device * @param buf : buffer to send data to */ static ssize_t megaraid_sysfs_show_ldnum(struct device *dev, char *buf) { struct scsi_device *sdev = to_scsi_device(dev); adapter_t *adapter = (adapter_t *)SCSIHOST2ADAP(sdev->host); mraid_device_t *raid_dev = ADAP2RAIDDEV(adapter); int scsi_id = -1; int logical_drv = -1; int ldid_map = -1; uint32_t app_hndl = 0; int mapped_sdev_id; int rval; int i; if (raid_dev->random_del_supported && MRAID_IS_LOGICAL_SDEV(adapter, sdev)) { rval = megaraid_sysfs_get_ldmap(adapter); if (rval == 0) { for (i = 0; i < MAX_LOGICAL_DRIVES_40LD; i++) { mapped_sdev_id = sdev->id; if (sdev->id > adapter->init_id) { mapped_sdev_id -= 1; } if (raid_dev->curr_ldmap[i] == mapped_sdev_id) { scsi_id = sdev->id; logical_drv = i; ldid_map = raid_dev->curr_ldmap[i]; app_hndl = mraid_mm_adapter_app_handle( adapter->unique_id); break; } } } else { con_log(CL_ANN, (KERN_NOTICE "megaraid: sysfs get ld map failed: %x\n", rval)); } } return snprintf(buf, 36, "%d %d %d %d\n", scsi_id, logical_drv, ldid_map, app_hndl); } /* * END: Mailbox Low Level Driver */ module_init(megaraid_init); module_exit(megaraid_exit); /* vim: set ts=8 sw=8 tw=78 ai si: */ megactl-0.4.5/kernel-2.6.9-55.0.2.EL/megaraid-2.20.4.6-rh2/megaraid_mbox.h000066400000000000000000000177631465722425200242370ustar00rootroot00000000000000/* * * Linux MegaRAID device driver * * Copyright (c) 2003-2004 LSI Logic Corporation. * * 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. * * FILE : megaraid_mbox.h */ #ifndef _MEGARAID_H_ #define _MEGARAID_H_ #include "mega_common.h" #include "mbox_defs.h" #include "megaraid_ioctl.h" #define MEGARAID_VERSION "2.20.4.6-rh2" #define MEGARAID_EXT_VERSION "(Release Date: Wed Jun 28 12:27:22 EST 2006)" /* * Define some PCI values here until they are put in the kernel */ #define PCI_DEVICE_ID_PERC4_DI_DISCOVERY 0x000E #define PCI_SUBSYS_ID_PERC4_DI_DISCOVERY 0x0123 #define PCI_DEVICE_ID_PERC4_SC 0x1960 #define PCI_SUBSYS_ID_PERC4_SC 0x0520 #define PCI_DEVICE_ID_PERC4_DC 0x1960 #define PCI_SUBSYS_ID_PERC4_DC 0x0518 #define PCI_DEVICE_ID_VERDE 0x0407 #define PCI_DEVICE_ID_PERC4_DI_EVERGLADES 0x000F #define PCI_SUBSYS_ID_PERC4_DI_EVERGLADES 0x014A #define PCI_DEVICE_ID_PERC4E_SI_BIGBEND 0x0013 #define PCI_SUBSYS_ID_PERC4E_SI_BIGBEND 0x016c #define PCI_DEVICE_ID_PERC4E_DI_KOBUK 0x0013 #define PCI_SUBSYS_ID_PERC4E_DI_KOBUK 0x016d #define PCI_DEVICE_ID_PERC4E_DI_CORVETTE 0x0013 #define PCI_SUBSYS_ID_PERC4E_DI_CORVETTE 0x016e #define PCI_DEVICE_ID_PERC4E_DI_EXPEDITION 0x0013 #define PCI_SUBSYS_ID_PERC4E_DI_EXPEDITION 0x016f #define PCI_DEVICE_ID_PERC4E_DI_GUADALUPE 0x0013 #define PCI_SUBSYS_ID_PERC4E_DI_GUADALUPE 0x0170 #define PCI_DEVICE_ID_DOBSON 0x0408 #define PCI_DEVICE_ID_MEGARAID_SCSI_320_0 0x1960 #define PCI_SUBSYS_ID_MEGARAID_SCSI_320_0 0xA520 #define PCI_DEVICE_ID_MEGARAID_SCSI_320_1 0x1960 #define PCI_SUBSYS_ID_MEGARAID_SCSI_320_1 0x0520 #define PCI_DEVICE_ID_MEGARAID_SCSI_320_2 0x1960 #define PCI_SUBSYS_ID_MEGARAID_SCSI_320_2 0x0518 #define PCI_DEVICE_ID_MEGARAID_I4_133_RAID 0x1960 #define PCI_SUBSYS_ID_MEGARAID_I4_133_RAID 0x0522 #define PCI_DEVICE_ID_MEGARAID_SATA_150_4 0x1960 #define PCI_SUBSYS_ID_MEGARAID_SATA_150_4 0x4523 #define PCI_DEVICE_ID_MEGARAID_SATA_150_6 0x1960 #define PCI_SUBSYS_ID_MEGARAID_SATA_150_6 0x0523 #define PCI_DEVICE_ID_LINDSAY 0x0409 #define PCI_DEVICE_ID_INTEL_RAID_SRCS16 0x1960 #define PCI_SUBSYS_ID_INTEL_RAID_SRCS16 0x0523 #define PCI_DEVICE_ID_INTEL_RAID_SRCU41L_LAKE_SHETEK 0x1960 #define PCI_SUBSYS_ID_INTEL_RAID_SRCU41L_LAKE_SHETEK 0x0520 #define PCI_SUBSYS_ID_PERC3_QC 0x0471 #define PCI_SUBSYS_ID_PERC3_DC 0x0493 #define PCI_SUBSYS_ID_PERC3_SC 0x0475 #define MBOX_MAX_SCSI_CMDS 128 // number of cmds reserved for kernel #define MBOX_MAX_USER_CMDS 32 // number of cmds for applications #define MBOX_DEF_CMD_PER_LUN 64 // default commands per lun #define MBOX_DEFAULT_SG_SIZE 26 // default sg size supported by all fw #define MBOX_MAX_SG_SIZE 32 // maximum scatter-gather list size #define MBOX_MAX_SECTORS 128 // maximum sectors per IO #define MBOX_TIMEOUT 30 // timeout value for internal cmds #define MBOX_BUSY_WAIT 10 // max usec to wait for busy mailbox #define MBOX_RESET_WAIT 180 // wait these many seconds in reset #define MBOX_RESET_EXT_WAIT 120 // extended wait reset #define MBOX_SYNC_WAIT_CNT 0xFFFF // wait loop index for synchronous mode #define MBOX_SYNC_DELAY_200 200 // 200 micro-secondes /* * maximum transfer that can happen through the firmware commands issued * internnaly from the driver. */ #define MBOX_IBUF_SIZE 4096 /** * mbox_ccb_t - command control block specific to mailbox based controllers * @raw_mbox : raw mailbox pointer * @mbox : mailbox * @mbox64 : extended mailbox * @mbox_dma_h : maibox dma address * @sgl64 : 64-bit scatter-gather list * @sgl32 : 32-bit scatter-gather list * @sgl_dma_h : dma handle for the scatter-gather list * @pthru : passthru structure * @pthru_dma_h : dma handle for the passthru structure * @epthru : extended passthru structure * @epthru_dma_h : dma handle for extended passthru structure * @buf_dma_h : dma handle for buffers w/o sg list * * command control block specific to the mailbox based controllers */ typedef struct { uint8_t *raw_mbox; mbox_t *mbox; mbox64_t *mbox64; dma_addr_t mbox_dma_h; mbox_sgl64 *sgl64; mbox_sgl32 *sgl32; dma_addr_t sgl_dma_h; mraid_passthru_t *pthru; dma_addr_t pthru_dma_h; mraid_epassthru_t *epthru; dma_addr_t epthru_dma_h; dma_addr_t buf_dma_h; } mbox_ccb_t; /** * mraid_device_t - adapter soft state structure for mailbox controllers * @param una_mbox64 : 64-bit mbox - unaligned * @param una_mbox64_dma : mbox dma addr - unaligned * @param mbox : 32-bit mbox - aligned * @param mbox64 : 64-bit mbox - aligned * @param mbox_dma : mbox dma addr - aligned * @param mailbox_lock : exclusion lock for the mailbox * @param baseport : base port of hba memory * @param baseaddr : mapped addr of hba memory * @param mbox_pool : pool of mailboxes * @param mbox_pool_handle : handle for the mailbox pool memory * @param epthru_pool : a pool for extended passthru commands * @param epthru_pool_handle : handle to the pool above * @param sg_pool : pool of scatter-gather lists for this driver * @param sg_pool_handle : handle to the pool above * @param ccb_list : list of our command control blocks * @param uccb_list : list of cmd control blocks for mgmt module * @param umbox64 : array of mailbox for user commands (cmm) * @param pdrv_state : array for state of each physical drive. * @param last_disp : flag used to show device scanning * @param hw_error : set if FW not responding * @param fast_load : If set, skip physical device scanning * @channel_class : channel class, RAID or SCSI * @sysfs_sem : semaphore to serialize access to sysfs res. * @sysfs_uioc : management packet to issue FW calls from sysfs * @sysfs_mbox64 : mailbox packet to issue FW calls from sysfs * @sysfs_buffer : data buffer for FW commands issued from sysfs * @sysfs_buffer_dma : DMA buffer for FW commands issued from sysfs * @sysfs_wait_q : wait queue for sysfs operations * @random_del_supported : set if the random deletion is supported * @curr_ldmap : current LDID map * * Initialization structure for mailbox controllers: memory based and IO based * All the fields in this structure are LLD specific and may be discovered at * init() or start() time. * * NOTE: The fields of this structures are placed to minimize cache misses */ #define MAX_LD_EXTENDED64 64 typedef struct { mbox64_t *una_mbox64; dma_addr_t una_mbox64_dma; mbox_t *mbox; mbox64_t *mbox64; dma_addr_t mbox_dma; spinlock_t mailbox_lock; unsigned long baseport; void __iomem * baseaddr; struct mraid_pci_blk mbox_pool[MBOX_MAX_SCSI_CMDS]; struct dma_pool *mbox_pool_handle; struct mraid_pci_blk epthru_pool[MBOX_MAX_SCSI_CMDS]; struct dma_pool *epthru_pool_handle; struct mraid_pci_blk sg_pool[MBOX_MAX_SCSI_CMDS]; struct dma_pool *sg_pool_handle; mbox_ccb_t ccb_list[MBOX_MAX_SCSI_CMDS]; mbox_ccb_t uccb_list[MBOX_MAX_USER_CMDS]; mbox64_t umbox64[MBOX_MAX_USER_CMDS]; uint8_t pdrv_state[MBOX_MAX_PHYSICAL_DRIVES]; uint32_t last_disp; int hw_error; int fast_load; uint8_t channel_class; struct semaphore sysfs_sem; uioc_t *sysfs_uioc; mbox64_t *sysfs_mbox64; caddr_t sysfs_buffer; dma_addr_t sysfs_buffer_dma; wait_queue_head_t sysfs_wait_q; int random_del_supported; uint16_t curr_ldmap[MAX_LD_EXTENDED64]; } mraid_device_t; // route to raid device from adapter #define ADAP2RAIDDEV(adp) ((mraid_device_t *)((adp)->raid_device)) #define MAILBOX_LOCK(rdev) (&(rdev)->mailbox_lock) // Find out if this channel is a RAID or SCSI #define IS_RAID_CH(rdev, ch) (((rdev)->channel_class >> (ch)) & 0x01) #define RDINDOOR(rdev) readl((rdev)->baseaddr + 0x20) #define RDOUTDOOR(rdev) readl((rdev)->baseaddr + 0x2C) #define WRINDOOR(rdev, value) writel(value, (rdev)->baseaddr + 0x20) #define WROUTDOOR(rdev, value) writel(value, (rdev)->baseaddr + 0x2C) #endif // _MEGARAID_H_ // vim: set ts=8 sw=8 tw=78: megactl-0.4.5/kernel-2.6.9-55.0.2.EL/megaraid-2.20.4.6-rh2/megaraid_mm.c000066400000000000000000000674021465722425200236710ustar00rootroot00000000000000/* * * Linux MegaRAID device driver * * Copyright (c) 2003-2004 LSI Logic Corporation. * * 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. * * FILE : megaraid_mm.c * Version : v2.20.2.6 (Mar 7 2005) * * Common management module */ #include "megaraid_mm.h" // Entry points for char node driver static int mraid_mm_open(struct inode *, struct file *); static int mraid_mm_ioctl(struct inode *, struct file *, uint, unsigned long); // routines to convert to and from the old the format static int mimd_to_kioc(mimd_t __user *, mraid_mmadp_t *, uioc_t *); static int kioc_to_mimd(uioc_t *, mimd_t __user *); // Helper functions static int handle_drvrcmd(void __user *, uint8_t, int *); static int lld_ioctl(mraid_mmadp_t *, uioc_t *); static void ioctl_done(uioc_t *); static void lld_timedout(unsigned long); static void hinfo_to_cinfo(mraid_hba_info_t *, mcontroller_t *); static mraid_mmadp_t *mraid_mm_get_adapter(mimd_t __user *, int *); static uioc_t *mraid_mm_alloc_kioc(mraid_mmadp_t *); static void mraid_mm_dealloc_kioc(mraid_mmadp_t *, uioc_t *); static int mraid_mm_attach_buf(mraid_mmadp_t *, uioc_t *, int); static int mraid_mm_setup_dma_pools(mraid_mmadp_t *); static void mraid_mm_free_adp_resources(mraid_mmadp_t *); static void mraid_mm_teardown_dma_pools(mraid_mmadp_t *); #ifdef CONFIG_COMPAT static int mraid_mm_compat_ioctl(unsigned int, unsigned int, unsigned long, struct file *); #endif MODULE_AUTHOR("LSI Logic Corporation"); MODULE_DESCRIPTION("LSI Logic Management Module"); MODULE_LICENSE("GPL"); MODULE_VERSION(LSI_COMMON_MOD_VERSION); static int dbglevel = CL_ANN; module_param_named(dlevel, dbglevel, int, 0); MODULE_PARM_DESC(dlevel, "Debug level (default=0)"); EXPORT_SYMBOL(mraid_mm_register_adp); EXPORT_SYMBOL(mraid_mm_unregister_adp); EXPORT_SYMBOL(mraid_mm_adapter_app_handle); void (*mraid_mm_poll_func)(struct scsi_device *device) = NULL; EXPORT_SYMBOL(mraid_mm_poll_func); struct scsi_device *mraid_mm_diskdump_poll_device = NULL; EXPORT_SYMBOL(mraid_mm_diskdump_poll_device); static int majorno; static uint32_t drvr_ver = 0x02200206; static int adapters_count_g; static struct list_head adapters_list_g; static wait_queue_head_t wait_q; static struct file_operations lsi_fops = { .open = mraid_mm_open, .ioctl = mraid_mm_ioctl, .owner = THIS_MODULE, }; int mraid_mm_woken; EXPORT_SYMBOL(mraid_mm_woken); static void _mraid_mm_diskdump_schedule(void); static void _mraid_mm_diskdump_wake_up(wait_queue_head_t *q, unsigned int mode, int nr_exclusive); void mraid_mm_diskdump_schedule(void); void mraid_mm_diskdump_wake_up(wait_queue_head_t *q); /** * mraid_mm_open - open routine for char node interface * @inod : unused * @filep : unused * * allow ioctl operations by apps only if they superuser privilege */ static int mraid_mm_open(struct inode *inode, struct file *filep) { /* * Only allow superuser to access private ioctl interface */ if (!capable(CAP_SYS_ADMIN)) return (-EACCES); return 0; } /** * mraid_mm_ioctl - module entry-point for ioctls * @inode : inode (ignored) * @filep : file operations pointer (ignored) * @cmd : ioctl command * @arg : user ioctl packet */ static int mraid_mm_ioctl(struct inode *inode, struct file *filep, unsigned int cmd, unsigned long arg) { uioc_t *kioc; char signature[EXT_IOCTL_SIGN_SZ] = {0}; int rval; mraid_mmadp_t *adp; uint8_t old_ioctl; int drvrcmd_rval; void __user *argp = (void __user *)arg; /* * Make sure only USCSICMD are issued through this interface. * MIMD application would still fire different command. */ if ((_IOC_TYPE(cmd) != MEGAIOC_MAGIC) && (cmd != USCSICMD)) { return (-EINVAL); } /* * Look for signature to see if this is the new or old ioctl format. */ if (copy_from_user(signature, argp, EXT_IOCTL_SIGN_SZ)) { con_log(CL_ANN, (KERN_WARNING "megaraid cmm: copy from usr addr failed\n")); return (-EFAULT); } if (memcmp(signature, EXT_IOCTL_SIGN, EXT_IOCTL_SIGN_SZ) == 0) old_ioctl = 0; else old_ioctl = 1; /* * At present, we don't support the new ioctl packet */ if (!old_ioctl ) return (-EINVAL); /* * If it is a driver ioctl (as opposed to fw ioctls), then we can * handle the command locally. rval > 0 means it is not a drvr cmd */ rval = handle_drvrcmd(argp, old_ioctl, &drvrcmd_rval); if (rval < 0) return rval; else if (rval == 0) return drvrcmd_rval; rval = 0; if ((adp = mraid_mm_get_adapter(argp, &rval)) == NULL) { return rval; } /* * Check if adapter can accept ioctl. We may have marked it offline * if any previous kioc had timedout on this controller. */ if (!adp->quiescent) { con_log(CL_ANN, (KERN_WARNING "megaraid cmm: controller cannot accept cmds due to " "earlier errors\n" )); return -EFAULT; } /* * The following call will block till a kioc is available */ kioc = mraid_mm_alloc_kioc(adp); /* * User sent the old mimd_t ioctl packet. Convert it to uioc_t. */ if ((rval = mimd_to_kioc(argp, adp, kioc))) { mraid_mm_dealloc_kioc(adp, kioc); return rval; } kioc->done = ioctl_done; /* * Issue the IOCTL to the low level driver. After the IOCTL completes * release the kioc if and only if it was _not_ timedout. If it was * timedout, that means that resources are still with low level driver. */ if ((rval = lld_ioctl(adp, kioc))) { if (!kioc->timedout) mraid_mm_dealloc_kioc(adp, kioc); return rval; } /* * Convert the kioc back to user space */ rval = kioc_to_mimd(kioc, argp); /* * Return the kioc to free pool */ mraid_mm_dealloc_kioc(adp, kioc); return rval; } /** * mraid_mm_get_adapter - Returns corresponding adapters for the mimd packet * @umimd : User space mimd_t ioctl packet * @adapter : pointer to the adapter (OUT) */ static mraid_mmadp_t * mraid_mm_get_adapter(mimd_t __user *umimd, int *rval) { mraid_mmadp_t *adapter; mimd_t mimd; uint32_t adapno; int iterator; if (copy_from_user(&mimd, umimd, sizeof(mimd_t))) { *rval = -EFAULT; return NULL; } adapno = GETADAP(mimd.ui.fcs.adapno); if (adapno >= adapters_count_g) { *rval = -ENODEV; return NULL; } adapter = NULL; iterator = 0; list_for_each_entry(adapter, &adapters_list_g, list) { if (iterator++ == adapno) break; } if (!adapter) { *rval = -ENODEV; return NULL; } return adapter; } /* * handle_drvrcmd - This routine checks if the opcode is a driver * cmd and if it is, handles it. * @arg : packet sent by the user app * @old_ioctl : mimd if 1; uioc otherwise */ static int handle_drvrcmd(void __user *arg, uint8_t old_ioctl, int *rval) { mimd_t __user *umimd; mimd_t kmimd; uint8_t opcode; uint8_t subopcode; if (old_ioctl) goto old_packet; else goto new_packet; new_packet: return (-ENOTSUPP); old_packet: *rval = 0; umimd = arg; if (copy_from_user(&kmimd, umimd, sizeof(mimd_t))) return (-EFAULT); opcode = kmimd.ui.fcs.opcode; subopcode = kmimd.ui.fcs.subopcode; /* * If the opcode is 0x82 and the subopcode is either GET_DRVRVER or * GET_NUMADP, then we can handle. Otherwise we should return 1 to * indicate that we cannot handle this. */ if (opcode != 0x82) return 1; switch (subopcode) { case MEGAIOC_QDRVRVER: if (copy_to_user(kmimd.data, &drvr_ver, sizeof(uint32_t))) return (-EFAULT); return 0; case MEGAIOC_QNADAP: *rval = adapters_count_g; if (copy_to_user(kmimd.data, &adapters_count_g, sizeof(uint32_t))) return (-EFAULT); return 0; default: /* cannot handle */ return 1; } return 0; } /** * mimd_to_kioc - Converter from old to new ioctl format * * @umimd : user space old MIMD IOCTL * @kioc : kernel space new format IOCTL * * Routine to convert MIMD interface IOCTL to new interface IOCTL packet. The * new packet is in kernel space so that driver can perform operations on it * freely. */ static int mimd_to_kioc(mimd_t __user *umimd, mraid_mmadp_t *adp, uioc_t *kioc) { mbox64_t *mbox64; mbox_t *mbox; mraid_passthru_t *pthru32; uint32_t adapno; uint8_t opcode; uint8_t subopcode; mimd_t mimd; if (copy_from_user(&mimd, umimd, sizeof(mimd_t))) return (-EFAULT); /* * Applications are not allowed to send extd pthru */ if ((mimd.mbox[0] == MBOXCMD_PASSTHRU64) || (mimd.mbox[0] == MBOXCMD_EXTPTHRU)) return (-EINVAL); opcode = mimd.ui.fcs.opcode; subopcode = mimd.ui.fcs.subopcode; adapno = GETADAP(mimd.ui.fcs.adapno); if (adapno >= adapters_count_g) return (-ENODEV); kioc->adapno = adapno; kioc->mb_type = MBOX_LEGACY; kioc->app_type = APPTYPE_MIMD; switch (opcode) { case 0x82: if (subopcode == MEGAIOC_QADAPINFO) { kioc->opcode = GET_ADAP_INFO; kioc->data_dir = UIOC_RD; kioc->xferlen = sizeof(mraid_hba_info_t); if (mraid_mm_attach_buf(adp, kioc, kioc->xferlen)) return (-ENOMEM); } else { con_log(CL_ANN, (KERN_WARNING "megaraid cmm: Invalid subop\n")); return (-EINVAL); } break; case 0x81: kioc->opcode = MBOX_CMD; kioc->xferlen = mimd.ui.fcs.length; kioc->user_data_len = kioc->xferlen; kioc->user_data = mimd.ui.fcs.buffer; if (mraid_mm_attach_buf(adp, kioc, kioc->xferlen)) return (-ENOMEM); if (mimd.outlen) kioc->data_dir = UIOC_RD; if (mimd.inlen) kioc->data_dir |= UIOC_WR; break; case 0x80: kioc->opcode = MBOX_CMD; kioc->xferlen = (mimd.outlen > mimd.inlen) ? mimd.outlen : mimd.inlen; kioc->user_data_len = kioc->xferlen; kioc->user_data = mimd.data; if (mraid_mm_attach_buf(adp, kioc, kioc->xferlen)) return (-ENOMEM); if (mimd.outlen) kioc->data_dir = UIOC_RD; if (mimd.inlen) kioc->data_dir |= UIOC_WR; break; default: return (-EINVAL); } /* * If driver command, nothing else to do */ if (opcode == 0x82) return 0; /* * This is a mailbox cmd; copy the mailbox from mimd */ mbox64 = (mbox64_t *)((unsigned long)kioc->cmdbuf); mbox = &mbox64->mbox32; memcpy(mbox, mimd.mbox, 14); if (mbox->cmd != MBOXCMD_PASSTHRU) { // regular DCMD mbox->xferaddr = (uint32_t)kioc->buf_paddr; if (kioc->data_dir & UIOC_WR) { if (copy_from_user(kioc->buf_vaddr, kioc->user_data, kioc->xferlen)) { return (-EFAULT); } } return 0; } /* * This is a regular 32-bit pthru cmd; mbox points to pthru struct. * Just like in above case, the beginning for memblk is treated as * a mailbox. The passthru will begin at next 1K boundary. And the * data will start 1K after that. */ pthru32 = kioc->pthru32; kioc->user_pthru = &umimd->pthru; mbox->xferaddr = (uint32_t)kioc->pthru32_h; if (copy_from_user(pthru32, kioc->user_pthru, sizeof(mraid_passthru_t))) { return (-EFAULT); } pthru32->dataxferaddr = kioc->buf_paddr; if (kioc->data_dir & UIOC_WR) { if (copy_from_user(kioc->buf_vaddr, kioc->user_data, pthru32->dataxferlen)) { return (-EFAULT); } } return 0; } /** * mraid_mm_attch_buf - Attach a free dma buffer for required size * * @adp : Adapter softstate * @kioc : kioc that the buffer needs to be attached to * @xferlen : required length for buffer * * First we search for a pool with smallest buffer that is >= @xferlen. If * that pool has no free buffer, we will try for the next bigger size. If none * is available, we will try to allocate the smallest buffer that is >= * @xferlen and attach it the pool. */ static int mraid_mm_attach_buf(mraid_mmadp_t *adp, uioc_t *kioc, int xferlen) { mm_dmapool_t *pool; int right_pool = -1; unsigned long flags; int i; kioc->pool_index = -1; kioc->buf_vaddr = NULL; kioc->buf_paddr = 0; kioc->free_buf = 0; /* * We need xferlen amount of memory. See if we can get it from our * dma pools. If we don't get exact size, we will try bigger buffer */ for (i = 0; i < MAX_DMA_POOLS; i++) { pool = &adp->dma_pool_list[i]; if (xferlen > pool->buf_size) continue; if (right_pool == -1) right_pool = i; spin_lock_irqsave(&pool->lock, flags); if (!pool->in_use) { pool->in_use = 1; kioc->pool_index = i; kioc->buf_vaddr = pool->vaddr; kioc->buf_paddr = pool->paddr; spin_unlock_irqrestore(&pool->lock, flags); return 0; } else { spin_unlock_irqrestore(&pool->lock, flags); continue; } } /* * If xferlen doesn't match any of our pools, return error */ if (right_pool == -1) return -EINVAL; /* * We did not get any buffer from the preallocated pool. Let us try * to allocate one new buffer. NOTE: This is a blocking call. */ pool = &adp->dma_pool_list[right_pool]; spin_lock_irqsave(&pool->lock, flags); kioc->pool_index = right_pool; kioc->free_buf = 1; kioc->buf_vaddr = pci_pool_alloc(pool->handle, GFP_KERNEL, &kioc->buf_paddr); spin_unlock_irqrestore(&pool->lock, flags); if (!kioc->buf_vaddr) return -ENOMEM; return 0; } /** * mraid_mm_alloc_kioc - Returns a uioc_t from free list * @adp : Adapter softstate for this module * * The kioc_semaphore is initialized with number of kioc nodes in the * free kioc pool. If the kioc pool is empty, this function blocks till * a kioc becomes free. */ static uioc_t * mraid_mm_alloc_kioc(mraid_mmadp_t *adp) { uioc_t *kioc; struct list_head* head; unsigned long flags; down(&adp->kioc_semaphore); spin_lock_irqsave(&adp->kioc_pool_lock, flags); head = &adp->kioc_pool; if (list_empty(head)) { up(&adp->kioc_semaphore); spin_unlock_irqrestore(&adp->kioc_pool_lock, flags); con_log(CL_ANN, ("megaraid cmm: kioc list empty!\n")); return NULL; } kioc = list_entry(head->next, uioc_t, list); list_del_init(&kioc->list); spin_unlock_irqrestore(&adp->kioc_pool_lock, flags); memset((caddr_t)(unsigned long)kioc->cmdbuf, 0, sizeof(mbox64_t)); memset((caddr_t) kioc->pthru32, 0, sizeof(mraid_passthru_t)); kioc->buf_vaddr = NULL; kioc->buf_paddr = 0; kioc->pool_index =-1; kioc->free_buf = 0; kioc->user_data = NULL; kioc->user_data_len = 0; kioc->user_pthru = NULL; kioc->timedout = 0; return kioc; } /** * mraid_mm_dealloc_kioc - Return kioc to free pool * * @adp : Adapter softstate * @kioc : uioc_t node to be returned to free pool */ static void mraid_mm_dealloc_kioc(mraid_mmadp_t *adp, uioc_t *kioc) { mm_dmapool_t *pool; unsigned long flags; if (kioc->pool_index != -1) { pool = &adp->dma_pool_list[kioc->pool_index]; /* This routine may be called in non-isr context also */ spin_lock_irqsave(&pool->lock, flags); /* * While attaching the dma buffer, if we didn't get the * required buffer from the pool, we would have allocated * it at the run time and set the free_buf flag. We must * free that buffer. Otherwise, just mark that the buffer is * not in use */ if (kioc->free_buf == 1) pci_pool_free(pool->handle, kioc->buf_vaddr, kioc->buf_paddr); else pool->in_use = 0; spin_unlock_irqrestore(&pool->lock, flags); } /* Return the kioc to the free pool */ spin_lock_irqsave(&adp->kioc_pool_lock, flags); list_add(&kioc->list, &adp->kioc_pool); spin_unlock_irqrestore(&adp->kioc_pool_lock, flags); /* increment the free kioc count */ up(&adp->kioc_semaphore); return; } /** * lld_ioctl - Routine to issue ioctl to low level drvr * * @adp : The adapter handle * @kioc : The ioctl packet with kernel addresses */ static int lld_ioctl(mraid_mmadp_t *adp, uioc_t *kioc) { int rval; struct timer_list timer; struct timer_list *tp = NULL; kioc->status = -ENODATA; rval = adp->issue_uioc(adp->drvr_data, kioc, IOCTL_ISSUE); if (rval) return rval; /* * Start the timer */ if (adp->timeout > 0) { tp = &timer; init_timer(tp); tp->function = lld_timedout; tp->data = (unsigned long)kioc; tp->expires = jiffies + adp->timeout * HZ; add_timer(tp); } /* * Wait till the low level driver completes the ioctl. After this * call, the ioctl either completed successfully or timedout. */ wait_event(wait_q, (kioc->status != -ENODATA)); if (tp) { del_timer_sync(tp); } /* * If the command had timedout, we mark the controller offline * before returning */ if (kioc->timedout) { adp->quiescent = 0; } return kioc->status; } /** * ioctl_done - callback from the low level driver * * @kioc : completed ioctl packet */ static void ioctl_done(uioc_t *kioc) { uint32_t adapno; int iterator; mraid_mmadp_t* adapter; /* * When the kioc returns from driver, make sure it still doesn't * have ENODATA in status. Otherwise, driver will hang on wait_event * forever */ if (kioc->status == -ENODATA) { con_log(CL_ANN, (KERN_WARNING "megaraid cmm: lld didn't change status!\n")); kioc->status = -EINVAL; } /* * Check if this kioc was timedout before. If so, nobody is waiting * on this kioc. We don't have to wake up anybody. Instead, we just * have to free the kioc */ if (kioc->timedout) { iterator = 0; adapter = NULL; adapno = kioc->adapno; con_log(CL_ANN, ( KERN_WARNING "megaraid cmm: completed " "ioctl that was timedout before\n")); list_for_each_entry(adapter, &adapters_list_g, list) { if (iterator++ == adapno) break; } kioc->timedout = 0; if (adapter) { mraid_mm_dealloc_kioc( adapter, kioc ); } } else { wake_up(&wait_q); } } /* * lld_timedout : callback from the expired timer * * @ptr : ioctl packet that timed out */ static void lld_timedout(unsigned long ptr) { uioc_t *kioc = (uioc_t *)ptr; kioc->status = -ETIME; kioc->timedout = 1; con_log(CL_ANN, (KERN_WARNING "megaraid cmm: ioctl timed out\n")); wake_up(&wait_q); } /** * kioc_to_mimd : Converter from new back to old format * * @kioc : Kernel space IOCTL packet (successfully issued) * @mimd : User space MIMD packet */ static int kioc_to_mimd(uioc_t *kioc, mimd_t __user *mimd) { mimd_t kmimd; uint8_t opcode; uint8_t subopcode; mbox64_t *mbox64; mraid_passthru_t __user *upthru32; mraid_passthru_t *kpthru32; mcontroller_t cinfo; mraid_hba_info_t *hinfo; if (copy_from_user(&kmimd, mimd, sizeof(mimd_t))) return (-EFAULT); opcode = kmimd.ui.fcs.opcode; subopcode = kmimd.ui.fcs.subopcode; if (opcode == 0x82) { switch (subopcode) { case MEGAIOC_QADAPINFO: hinfo = (mraid_hba_info_t *)(unsigned long) kioc->buf_vaddr; hinfo_to_cinfo(hinfo, &cinfo); if (copy_to_user(kmimd.data, &cinfo, sizeof(cinfo))) return (-EFAULT); return 0; default: return (-EINVAL); } return 0; } mbox64 = (mbox64_t *)(unsigned long)kioc->cmdbuf; if (kioc->user_pthru) { upthru32 = kioc->user_pthru; kpthru32 = kioc->pthru32; if (copy_to_user(&upthru32->scsistatus, &kpthru32->scsistatus, sizeof(uint8_t))) { return (-EFAULT); } } if (kioc->user_data) { if (copy_to_user(kioc->user_data, kioc->buf_vaddr, kioc->user_data_len)) { return (-EFAULT); } } if (copy_to_user(&mimd->mbox[17], &mbox64->mbox32.status, sizeof(uint8_t))) { return (-EFAULT); } return 0; } /** * hinfo_to_cinfo - Convert new format hba info into old format * * @hinfo : New format, more comprehensive adapter info * @cinfo : Old format adapter info to support mimd_t apps */ static void hinfo_to_cinfo(mraid_hba_info_t *hinfo, mcontroller_t *cinfo) { if (!hinfo || !cinfo) return; cinfo->base = hinfo->baseport; cinfo->irq = hinfo->irq; cinfo->numldrv = hinfo->num_ldrv; cinfo->pcibus = hinfo->pci_bus; cinfo->pcidev = hinfo->pci_slot; cinfo->pcifun = PCI_FUNC(hinfo->pci_dev_fn); cinfo->pciid = hinfo->pci_device_id; cinfo->pcivendor = hinfo->pci_vendor_id; cinfo->pcislot = hinfo->pci_slot; cinfo->uid = hinfo->unique_id; } /* * mraid_mm_register_adp - Registration routine for low level drvrs * * @adp : Adapter objejct */ int mraid_mm_register_adp(mraid_mmadp_t *lld_adp) { mraid_mmadp_t *adapter; mbox64_t *mbox_list; uioc_t *kioc; uint32_t rval; int i; if (lld_adp->drvr_type != DRVRTYPE_MBOX) return (-EINVAL); adapter = kmalloc(sizeof(mraid_mmadp_t), GFP_KERNEL); if (!adapter) { rval = -ENOMEM; goto memalloc_error; } memset(adapter, 0, sizeof(mraid_mmadp_t)); adapter->unique_id = lld_adp->unique_id; adapter->drvr_type = lld_adp->drvr_type; adapter->drvr_data = lld_adp->drvr_data; adapter->pdev = lld_adp->pdev; adapter->issue_uioc = lld_adp->issue_uioc; adapter->timeout = lld_adp->timeout; adapter->max_kioc = lld_adp->max_kioc; adapter->quiescent = 1; /* * Allocate single blocks of memory for all required kiocs, * mailboxes and passthru structures. */ adapter->kioc_list = kmalloc(sizeof(uioc_t) * lld_adp->max_kioc, GFP_KERNEL); adapter->mbox_list = kmalloc(sizeof(mbox64_t) * lld_adp->max_kioc, GFP_KERNEL); adapter->pthru_dma_pool = pci_pool_create("megaraid mm pthru pool", adapter->pdev, sizeof(mraid_passthru_t), 16, 0); if (!adapter->kioc_list || !adapter->mbox_list || !adapter->pthru_dma_pool) { con_log(CL_ANN, (KERN_WARNING "megaraid cmm: out of memory, %s %d\n", __FUNCTION__, __LINE__)); rval = (-ENOMEM); goto memalloc_error; } /* * Slice kioc_list and make a kioc_pool with the individiual kiocs */ INIT_LIST_HEAD(&adapter->kioc_pool); spin_lock_init(&adapter->kioc_pool_lock); sema_init(&adapter->kioc_semaphore, lld_adp->max_kioc); mbox_list = (mbox64_t *)adapter->mbox_list; for (i = 0; i < lld_adp->max_kioc; i++) { kioc = adapter->kioc_list + i; kioc->cmdbuf = (uint64_t)(unsigned long)(mbox_list + i); kioc->pthru32 = pci_pool_alloc(adapter->pthru_dma_pool, GFP_KERNEL, &kioc->pthru32_h); if (!kioc->pthru32) { con_log(CL_ANN, (KERN_WARNING "megaraid cmm: out of memory, %s %d\n", __FUNCTION__, __LINE__)); rval = (-ENOMEM); goto pthru_dma_pool_error; } list_add_tail(&kioc->list, &adapter->kioc_pool); } // Setup the dma pools for data buffers if ((rval = mraid_mm_setup_dma_pools(adapter)) != 0) { goto dma_pool_error; } list_add_tail(&adapter->list, &adapters_list_g); adapters_count_g++; return 0; dma_pool_error: /* Do nothing */ pthru_dma_pool_error: for (i = 0; i < lld_adp->max_kioc; i++) { kioc = adapter->kioc_list + i; if (kioc->pthru32) { pci_pool_free(adapter->pthru_dma_pool, kioc->pthru32, kioc->pthru32_h); } } memalloc_error: if (adapter->kioc_list) kfree(adapter->kioc_list); if (adapter->mbox_list) kfree(adapter->mbox_list); if (adapter->pthru_dma_pool) pci_pool_destroy(adapter->pthru_dma_pool); if (adapter) kfree(adapter); return rval; } /** * mraid_mm_adapter_app_handle - return the application handle for this adapter * * For the given driver data, locate the adadpter in our global list and * return the corresponding handle, which is also used by applications to * uniquely identify an adapter. * * @param unique_id : adapter unique identifier * * @return adapter handle if found in the list * @return 0 if adapter could not be located, should never happen though */ uint32_t mraid_mm_adapter_app_handle(uint32_t unique_id) { mraid_mmadp_t *adapter; mraid_mmadp_t *tmp; int index = 0; list_for_each_entry_safe(adapter, tmp, &adapters_list_g, list) { if (adapter->unique_id == unique_id) { return MKADAP(index); } index++; } return 0; } /** * mraid_mm_setup_dma_pools - Set up dma buffer pools per adapter * * @adp : Adapter softstate * * We maintain a pool of dma buffers per each adapter. Each pool has one * buffer. E.g, we may have 5 dma pools - one each for 4k, 8k ... 64k buffers. * We have just one 4k buffer in 4k pool, one 8k buffer in 8k pool etc. We * dont' want to waste too much memory by allocating more buffers per each * pool. */ static int mraid_mm_setup_dma_pools(mraid_mmadp_t *adp) { mm_dmapool_t *pool; int bufsize; int i; /* * Create MAX_DMA_POOLS number of pools */ bufsize = MRAID_MM_INIT_BUFF_SIZE; for (i = 0; i < MAX_DMA_POOLS; i++){ pool = &adp->dma_pool_list[i]; pool->buf_size = bufsize; spin_lock_init(&pool->lock); pool->handle = pci_pool_create("megaraid mm data buffer", adp->pdev, bufsize, 16, 0); if (!pool->handle) { goto dma_pool_setup_error; } pool->vaddr = pci_pool_alloc(pool->handle, GFP_KERNEL, &pool->paddr); if (!pool->vaddr) goto dma_pool_setup_error; bufsize = bufsize * 2; } return 0; dma_pool_setup_error: mraid_mm_teardown_dma_pools(adp); return (-ENOMEM); } /* * mraid_mm_unregister_adp - Unregister routine for low level drivers * Assume no outstanding ioctls to llds. * * @unique_id : UID of the adpater */ int mraid_mm_unregister_adp(uint32_t unique_id) { mraid_mmadp_t *adapter; mraid_mmadp_t *tmp; list_for_each_entry_safe(adapter, tmp, &adapters_list_g, list) { if (adapter->unique_id == unique_id) { adapters_count_g--; list_del_init(&adapter->list); mraid_mm_free_adp_resources(adapter); kfree(adapter); con_log(CL_ANN, ( "megaraid cmm: Unregistered one adapter:%#x\n", unique_id)); return 0; } } return (-ENODEV); } /** * mraid_mm_free_adp_resources - Free adapter softstate * * @adp : Adapter softstate */ static void mraid_mm_free_adp_resources(mraid_mmadp_t *adp) { uioc_t *kioc; int i; mraid_mm_teardown_dma_pools(adp); for (i = 0; i < adp->max_kioc; i++) { kioc = adp->kioc_list + i; pci_pool_free(adp->pthru_dma_pool, kioc->pthru32, kioc->pthru32_h); } kfree(adp->kioc_list); kfree(adp->mbox_list); pci_pool_destroy(adp->pthru_dma_pool); return; } /** * mraid_mm_teardown_dma_pools - Free all per adapter dma buffers * * @adp : Adapter softstate */ static void mraid_mm_teardown_dma_pools(mraid_mmadp_t *adp) { int i; mm_dmapool_t *pool; for (i = 0; i < MAX_DMA_POOLS; i++) { pool = &adp->dma_pool_list[i]; if (pool->handle) { if (pool->vaddr) pci_pool_free(pool->handle, pool->vaddr, pool->paddr); pci_pool_destroy(pool->handle); pool->handle = NULL; } } return; } /** * mraid_mm_init : Module entry point */ static int __init mraid_mm_init(void) { // Announce the driver version con_log(CL_ANN, (KERN_INFO "megaraid cmm: %s %s\n", LSI_COMMON_MOD_VERSION, LSI_COMMON_MOD_EXT_VERSION)); majorno = register_chrdev(0, "megadev", &lsi_fops); if (majorno < 0) { con_log(CL_ANN, ("megaraid cmm: cannot get major\n")); return majorno; } init_waitqueue_head(&wait_q); INIT_LIST_HEAD(&adapters_list_g); register_ioctl32_conversion(MEGAIOCCMD, mraid_mm_compat_ioctl); return 0; } /** * mraid_mm_compat_ioctl : 32bit to 64bit ioctl conversion routine */ #ifdef CONFIG_COMPAT static int mraid_mm_compat_ioctl(unsigned int fd, unsigned int cmd, unsigned long arg, struct file *filep) { int err; struct inode *inode = filep->f_dentry->d_inode; err = mraid_mm_ioctl(inode, filep, cmd, arg); return err; } #endif /** * mraid_mm_exit : Module exit point */ static void __exit mraid_mm_exit(void) { con_log(CL_DLEVEL1 , ("exiting common mod\n")); unregister_chrdev(majorno, "megadev"); unregister_ioctl32_conversion(MEGAIOCCMD); } void mraid_mm_diskdump_schedule(void) { if (crashdump_mode()) _mraid_mm_diskdump_schedule(); else schedule(); return; } EXPORT_SYMBOL(mraid_mm_diskdump_schedule); void mraid_mm_diskdump_wake_up(wait_queue_head_t *q) { if (crashdump_mode()) _mraid_mm_diskdump_wake_up((q), TASK_UNINTERRUPTIBLE | TASK_INTERRUPTIBLE, 1); else __wake_up((q), TASK_UNINTERRUPTIBLE | TASK_INTERRUPTIBLE, 1, NULL); return; } EXPORT_SYMBOL(mraid_mm_diskdump_wake_up); static void _mraid_mm_diskdump_schedule(void) { mraid_mm_woken = 0; if (!mraid_mm_poll_func || !mraid_mm_diskdump_poll_device) { return; } while (!mraid_mm_woken) { mraid_mm_poll_func(mraid_mm_diskdump_poll_device); udelay(100); diskdump_update(); } } static void _mraid_mm_diskdump_wake_up(wait_queue_head_t *q, unsigned int mode, int nr_exclusive) { struct list_head *tmp; wait_queue_t *curr; task_t *p; list_for_each(tmp, &q->task_list) { curr = list_entry(tmp, wait_queue_t, task_list); p = curr->task; if (p == current) { if (p->state & mode) mraid_mm_woken = 1; } } } module_init(mraid_mm_init); module_exit(mraid_mm_exit); /* vi: set ts=8 sw=8 tw=78: */ megactl-0.4.5/kernel-2.6.9-55.0.2.EL/megaraid-2.20.4.6-rh2/megaraid_mm.h000066400000000000000000000042621465722425200236710ustar00rootroot00000000000000/* * * Linux MegaRAID device driver * * Copyright (c) 2003-2004 LSI Logic Corporation. * * 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. * * FILE : megaraid_mm.h */ #ifndef MEGARAID_MM_H #define MEGARAID_MM_H #include #include #include #include #include #include #include #include #include #include #include #include #include "mbox_defs.h" #include "megaraid_ioctl.h" #define LSI_COMMON_MOD_VERSION "2.20.2.6rh" #define LSI_COMMON_MOD_EXT_VERSION \ "(Release Date: Tue Jan 16 12:35:06 PST 2007)" #define LSI_DBGLVL dbglevel // The smallest dma pool #define MRAID_MM_INIT_BUFF_SIZE 4096 /** * mimd_t : Old style ioctl packet structure (deprecated) * * @inlen : * @outlen : * @fca : * @opcode : * @subopcode : * @adapno : * @buffer : * @pad : * @length : * @mbox : * @pthru : * @data : * @pad : * * Note : This structure is DEPRECATED. New applications must use * : uioc_t structure instead. All new hba drivers use the new * : format. If we get this mimd packet, we will convert it into * : new uioc_t format and send it to the hba drivers. */ typedef struct mimd { uint32_t inlen; uint32_t outlen; union { uint8_t fca[16]; struct { uint8_t opcode; uint8_t subopcode; uint16_t adapno; #if BITS_PER_LONG == 32 uint8_t __user *buffer; uint8_t pad[4]; #endif #if BITS_PER_LONG == 64 uint8_t __user *buffer; #endif uint32_t length; } __attribute__ ((packed)) fcs; } __attribute__ ((packed)) ui; uint8_t mbox[18]; /* 16 bytes + 2 status bytes */ mraid_passthru_t pthru; #if BITS_PER_LONG == 32 char __user *data; /* buffer <= 4096 for 0x80 commands */ char pad[4]; #endif #if BITS_PER_LONG == 64 char __user *data; #endif } __attribute__ ((packed))mimd_t; #endif // MEGARAID_MM_H // vi: set ts=8 sw=8 tw=78: megactl-0.4.5/kernel-2.6.9-55.0.2.EL/megaraid-2.20.4.6-rh2/megaraid_sas.c000066400000000000000000002345571465722425200240550ustar00rootroot00000000000000/* * * Linux MegaRAID driver for SAS based RAID controllers * * Copyright (c) 2003-2005 LSI Logic Corporation. * * 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. * * FILE : megaraid_sas.c * Version : v00.00.03.05 * * Authors: * Sreenivas Bagalkote * Sumant Patro * * List of supported controllers * * OEM Product Name VID DID SSVID SSID * --- ------------ --- --- ---- ---- */ #include #include #include #include #include #include #include #include #include #include #include #include #include #include #include #include #include #include #include #include #include "megaraid_sas.h" MODULE_LICENSE("GPL"); MODULE_VERSION(MEGASAS_VERSION); MODULE_AUTHOR("sreenivas.bagalkote@lsil.com"); MODULE_DESCRIPTION("LSI Logic MegaRAID SAS Driver"); /* * diskdump helper function. We can't call msleep() or mdelay() while dumping. */ static void megasas_msleep(unsigned long ms) { if(unlikely(crashdump_mode())) { diskdump_mdelay(ms); } else msleep(ms); } /* * PCI ID table for all supported controllers */ static struct pci_device_id megasas_pci_table[] = { {PCI_DEVICE(PCI_VENDOR_ID_LSI_LOGIC, PCI_DEVICE_ID_LSI_SAS1064R)}, /* xscale IOP */ {PCI_DEVICE(PCI_VENDOR_ID_LSI_LOGIC, PCI_DEVICE_ID_LSI_SAS1078R)}, /* ppc IOP */ {PCI_DEVICE(PCI_VENDOR_ID_LSI_LOGIC, PCI_DEVICE_ID_LSI_VERDE_ZCR)}, /* xscale IOP, vega */ {PCI_DEVICE(PCI_VENDOR_ID_DELL, PCI_DEVICE_ID_DELL_PERC5)}, /* xscale IOP */ {} }; MODULE_DEVICE_TABLE(pci, megasas_pci_table); static int megasas_mgmt_majorno; static struct megasas_mgmt_info megasas_mgmt_info; static struct fasync_struct *megasas_async_queue; static DECLARE_MUTEX(megasas_async_queue_mutex); static u32 megasas_dbg_lvl; static int megasas_deplete_reply_queue(struct megasas_instance *instance, u8 alt_status); static void megasas_flush_cache(struct megasas_instance *instance); static irqreturn_t megasas_isr(int irq, void *devp, struct pt_regs *regs); /** * megasas_get_cmd - Get a command from the free pool * @instance: Adapter soft state * * Returns a free command from the pool */ static inline struct megasas_cmd *megasas_get_cmd(struct megasas_instance *instance) { unsigned long flags; struct megasas_cmd *cmd = NULL; spin_lock_irqsave(&instance->cmd_pool_lock, flags); if (!list_empty(&instance->cmd_pool)) { cmd = list_entry((&instance->cmd_pool)->next, struct megasas_cmd, list); list_del_init(&cmd->list); } else { printk(KERN_ERR "megasas: Command pool empty!\n"); } spin_unlock_irqrestore(&instance->cmd_pool_lock, flags); return cmd; } /** * megasas_return_cmd - Return a cmd to free command pool * @instance: Adapter soft state * @cmd: Command packet to be returned to free command pool */ static inline void megasas_return_cmd(struct megasas_instance *instance, struct megasas_cmd *cmd) { unsigned long flags; spin_lock_irqsave(&instance->cmd_pool_lock, flags); cmd->scmd = NULL; list_add_tail(&cmd->list, &instance->cmd_pool); spin_unlock_irqrestore(&instance->cmd_pool_lock, flags); } /** * The following functions are defined for xscale * (deviceid : 1064R, PERC5) controllers */ /** * megasas_enable_intr_xscale - Enables interrupts * @regs: MFI register set */ static inline void megasas_enable_intr_xscale(struct megasas_register_set __iomem * regs) { writel(1, &(regs)->outbound_intr_mask); /* Dummy readl to force pci flush */ readl(®s->outbound_intr_mask); } /** * megasas_disable_intr_xscale -Disable interrupt * @regs: MFI register set */ static inline void megasas_disable_intr_xscale(struct megasas_register_set __iomem * regs) { u32 mask = 0x1f; writel(mask, ®s->outbound_intr_mask); /* Dummy readl to force pci flush */ readl(®s->outbound_intr_mask); } /** * megasas_read_fw_status_reg_xscale - returns the current FW status value * @regs: MFI register set */ static u32 megasas_read_fw_status_reg_xscale(struct megasas_register_set __iomem * regs) { return readl(&(regs)->outbound_msg_0); } /** * megasas_clear_interrupt_xscale - Check & clear interrupt * @regs: MFI register set */ static int megasas_clear_intr_xscale(struct megasas_register_set __iomem * regs) { u32 status; /* * Check if it is our interrupt */ status = readl(®s->outbound_intr_status); if (!(status & MFI_OB_INTR_STATUS_MASK)) { return 1; } /* * Clear the interrupt by writing back the same value */ writel(status, ®s->outbound_intr_status); return 0; } /** * megasas_fire_cmd_xscale - Sends command to the FW * @frame_phys_addr : Physical address of cmd * @frame_count : Number of frames for the command * @regs : MFI register set */ static inline void megasas_fire_cmd_xscale(dma_addr_t frame_phys_addr,u32 frame_count, struct megasas_register_set __iomem *regs) { writel((frame_phys_addr >> 3)|(frame_count), &(regs)->inbound_queue_port); } static struct megasas_instance_template megasas_instance_template_xscale = { .fire_cmd = megasas_fire_cmd_xscale, .enable_intr = megasas_enable_intr_xscale, .disable_intr = megasas_disable_intr_xscale, .clear_intr = megasas_clear_intr_xscale, .read_fw_status_reg = megasas_read_fw_status_reg_xscale, }; /** * This is the end of set of functions & definitions specific * to xscale (deviceid : 1064R, PERC5) controllers */ /** * The following functions are defined for ppc (deviceid : 0x60) * controllers */ /** * megasas_enable_intr_ppc - Enables interrupts * @regs: MFI register set */ static inline void megasas_enable_intr_ppc(struct megasas_register_set __iomem * regs) { writel(0xFFFFFFFF, &(regs)->outbound_doorbell_clear); writel(~0x80000004, &(regs)->outbound_intr_mask); /* Dummy readl to force pci flush */ readl(®s->outbound_intr_mask); } /** * megasas_disable_intr_ppc - Disable interrupt * @regs: MFI register set */ static inline void megasas_disable_intr_ppc(struct megasas_register_set __iomem * regs) { u32 mask = 0xFFFFFFFF; writel(mask, ®s->outbound_intr_mask); /* Dummy readl to force pci flush */ readl(®s->outbound_intr_mask); } /** * megasas_read_fw_status_reg_ppc - returns the current FW status value * @regs: MFI register set */ static u32 megasas_read_fw_status_reg_ppc(struct megasas_register_set __iomem * regs) { return readl(&(regs)->outbound_scratch_pad); } /** * megasas_clear_interrupt_ppc - Check & clear interrupt * @regs: MFI register set */ static int megasas_clear_intr_ppc(struct megasas_register_set __iomem * regs) { u32 status; /* * Check if it is our interrupt */ status = readl(®s->outbound_intr_status); if (!(status & MFI_REPLY_1078_MESSAGE_INTERRUPT)) { return 1; } /* * Clear the interrupt by writing back the same value */ writel(status, ®s->outbound_doorbell_clear); return 0; } /** * megasas_fire_cmd_ppc - Sends command to the FW * @frame_phys_addr : Physical address of cmd * @frame_count : Number of frames for the command * @regs : MFI register set */ static inline void megasas_fire_cmd_ppc(dma_addr_t frame_phys_addr, u32 frame_count, struct megasas_register_set __iomem *regs) { writel((frame_phys_addr | (frame_count<<1))|1, &(regs)->inbound_queue_port); } static struct megasas_instance_template megasas_instance_template_ppc = { .fire_cmd = megasas_fire_cmd_ppc, .enable_intr = megasas_enable_intr_ppc, .disable_intr = megasas_disable_intr_ppc, .clear_intr = megasas_clear_intr_ppc, .read_fw_status_reg = megasas_read_fw_status_reg_ppc, }; /** * This is the end of set of functions & definitions * specific to ppc (deviceid : 0x60) controllers */ /** * megasas_issue_polled - Issues a polling command * @instance: Adapter soft state * @cmd: Command packet to be issued * * For polling, MFI requires the cmd_status to be set to 0xFF before posting. */ static int megasas_issue_polled(struct megasas_instance *instance, struct megasas_cmd *cmd) { int i; u32 msecs = MFI_POLL_TIMEOUT_SECS * 1000; struct megasas_header *frame_hdr = &cmd->frame->hdr; frame_hdr->cmd_status = 0xFF; frame_hdr->flags |= MFI_FRAME_DONT_POST_IN_REPLY_QUEUE; /* * Issue the frame using inbound queue port */ instance->instancet->fire_cmd(cmd->frame_phys_addr ,0,instance->reg_set); /* * Wait for cmd_status to change */ for (i = 0; (i < msecs) && (frame_hdr->cmd_status == 0xff); i++) { rmb(); megasas_msleep(1); } if (frame_hdr->cmd_status == 0xff) return -ETIME; return 0; } /** * megasas_issue_blocked_cmd - Synchronous wrapper around regular FW cmds * @instance: Adapter soft state * @cmd: Command to be issued * * This function waits on an event for the command to be returned from ISR. * Max wait time is MEGASAS_INTERNAL_CMD_WAIT_TIME secs * Used to issue ioctl commands. */ static int megasas_issue_blocked_cmd(struct megasas_instance *instance, struct megasas_cmd *cmd) { cmd->cmd_status = ENODATA; instance->instancet->fire_cmd(cmd->frame_phys_addr ,0,instance->reg_set); wait_event_timeout(instance->int_cmd_wait_q, (cmd->cmd_status != ENODATA), MEGASAS_INTERNAL_CMD_WAIT_TIME*HZ); return 0; } /** * megasas_issue_blocked_abort_cmd - Aborts previously issued cmd * @instance: Adapter soft state * @cmd_to_abort: Previously issued cmd to be aborted * * MFI firmware can abort previously issued AEN comamnd (automatic event * notification). The megasas_issue_blocked_abort_cmd() issues such abort * cmd and waits for return status. * Max wait time is MEGASAS_INTERNAL_CMD_WAIT_TIME secs */ static int megasas_issue_blocked_abort_cmd(struct megasas_instance *instance, struct megasas_cmd *cmd_to_abort) { struct megasas_cmd *cmd; struct megasas_abort_frame *abort_fr; cmd = megasas_get_cmd(instance); if (!cmd) return -1; abort_fr = &cmd->frame->abort; /* * Prepare and issue the abort frame */ abort_fr->cmd = MFI_CMD_ABORT; abort_fr->cmd_status = 0xFF; abort_fr->flags = 0; abort_fr->abort_context = cmd_to_abort->index; abort_fr->abort_mfi_phys_addr_lo = cmd_to_abort->frame_phys_addr; abort_fr->abort_mfi_phys_addr_hi = 0; cmd->sync_cmd = 1; cmd->cmd_status = 0xFF; instance->instancet->fire_cmd(cmd->frame_phys_addr ,0,instance->reg_set); /* * Wait for this cmd to complete */ wait_event_timeout(instance->abort_cmd_wait_q, (cmd->cmd_status != 0xFF), MEGASAS_INTERNAL_CMD_WAIT_TIME*HZ); megasas_return_cmd(instance, cmd); return 0; } /** * megasas_make_sgl32 - Prepares 32-bit SGL * @instance: Adapter soft state * @scp: SCSI command from the mid-layer * @mfi_sgl: SGL to be filled in * * If successful, this function returns the number of SG elements. Otherwise, * it returnes -1. */ static inline int megasas_make_sgl32(struct megasas_instance *instance, struct scsi_cmnd *scp, union megasas_sgl *mfi_sgl) { int i; int sge_count; struct scatterlist *os_sgl; /* * Return 0 if there is no data transfer */ if (!scp->request_buffer || !scp->request_bufflen) return 0; if (!scp->use_sg) { mfi_sgl->sge32[0].phys_addr = pci_map_single(instance->pdev, scp-> request_buffer, scp-> request_bufflen, scp-> sc_data_direction); mfi_sgl->sge32[0].length = scp->request_bufflen; return 1; } os_sgl = (struct scatterlist *)scp->request_buffer; sge_count = pci_map_sg(instance->pdev, os_sgl, scp->use_sg, scp->sc_data_direction); for (i = 0; i < sge_count; i++, os_sgl++) { mfi_sgl->sge32[i].length = sg_dma_len(os_sgl); mfi_sgl->sge32[i].phys_addr = sg_dma_address(os_sgl); } return sge_count; } /** * megasas_make_sgl64 - Prepares 64-bit SGL * @instance: Adapter soft state * @scp: SCSI command from the mid-layer * @mfi_sgl: SGL to be filled in * * If successful, this function returns the number of SG elements. Otherwise, * it returnes -1. */ static inline int megasas_make_sgl64(struct megasas_instance *instance, struct scsi_cmnd *scp, union megasas_sgl *mfi_sgl) { int i; int sge_count; struct scatterlist *os_sgl; /* * Return 0 if there is no data transfer */ if (!scp->request_buffer || !scp->request_bufflen) return 0; if (!scp->use_sg) { mfi_sgl->sge64[0].phys_addr = pci_map_single(instance->pdev, scp-> request_buffer, scp-> request_bufflen, scp-> sc_data_direction); mfi_sgl->sge64[0].length = scp->request_bufflen; return 1; } os_sgl = (struct scatterlist *)scp->request_buffer; sge_count = pci_map_sg(instance->pdev, os_sgl, scp->use_sg, scp->sc_data_direction); for (i = 0; i < sge_count; i++, os_sgl++) { mfi_sgl->sge64[i].length = sg_dma_len(os_sgl); mfi_sgl->sge64[i].phys_addr = sg_dma_address(os_sgl); } return sge_count; } /** * megasas_get_frame_count - Computes the number of frames * @sge_count : number of sg elements * * Returns the number of frames required for numnber of sge's (sge_count) */ u32 megasas_get_frame_count(u8 sge_count) { int num_cnt; int sge_bytes; u32 sge_sz; u32 frame_count=0; sge_sz = (IS_DMA64) ? sizeof(struct megasas_sge64) : sizeof(struct megasas_sge32); /* * Main frame can contain 2 SGEs for 64-bit SGLs and * 3 SGEs for 32-bit SGLs */ if (IS_DMA64) num_cnt = sge_count - 2; else num_cnt = sge_count - 3; if(num_cnt>0){ sge_bytes = sge_sz * num_cnt; frame_count = (sge_bytes / MEGAMFI_FRAME_SIZE) + ((sge_bytes % MEGAMFI_FRAME_SIZE) ? 1 : 0) ; } /* Main frame */ frame_count +=1; if (frame_count > 7) frame_count = 8; return frame_count; } /** * megasas_build_dcdb - Prepares a direct cdb (DCDB) command * @instance: Adapter soft state * @scp: SCSI command * @cmd: Command to be prepared in * * This function prepares CDB commands. These are typcially pass-through * commands to the devices. */ static inline int megasas_build_dcdb(struct megasas_instance *instance, struct scsi_cmnd *scp, struct megasas_cmd *cmd) { u32 is_logical; u32 device_id; u16 flags = 0; struct megasas_pthru_frame *pthru; is_logical = MEGASAS_IS_LOGICAL(scp); device_id = MEGASAS_DEV_INDEX(instance, scp); pthru = (struct megasas_pthru_frame *)cmd->frame; if (scp->sc_data_direction == PCI_DMA_TODEVICE) flags = MFI_FRAME_DIR_WRITE; else if (scp->sc_data_direction == PCI_DMA_FROMDEVICE) flags = MFI_FRAME_DIR_READ; else if (scp->sc_data_direction == PCI_DMA_NONE) flags = MFI_FRAME_DIR_NONE; /* * Prepare the DCDB frame */ pthru->cmd = (is_logical) ? MFI_CMD_LD_SCSI_IO : MFI_CMD_PD_SCSI_IO; pthru->cmd_status = 0x0; pthru->scsi_status = 0x0; pthru->target_id = device_id; pthru->lun = scp->device->lun; pthru->cdb_len = scp->cmd_len; pthru->timeout = 0; pthru->flags = flags; pthru->data_xfer_len = scp->request_bufflen; memcpy(pthru->cdb, scp->cmnd, scp->cmd_len); /* * Construct SGL */ if (IS_DMA64) { pthru->flags |= MFI_FRAME_SGL64; pthru->sge_count = megasas_make_sgl64(instance, scp, &pthru->sgl); } else pthru->sge_count = megasas_make_sgl32(instance, scp, &pthru->sgl); /* * Sense info specific */ pthru->sense_len = SCSI_SENSE_BUFFERSIZE; pthru->sense_buf_phys_addr_hi = 0; pthru->sense_buf_phys_addr_lo = cmd->sense_phys_addr; /* * Compute the total number of frames this command consumes. FW uses * this number to pull sufficient number of frames from host memory. */ cmd->frame_count = megasas_get_frame_count(pthru->sge_count); return cmd->frame_count; } /** * megasas_build_ldio - Prepares IOs to logical devices * @instance: Adapter soft state * @scp: SCSI command * @cmd: Command to to be prepared * * Frames (and accompanying SGLs) for regular SCSI IOs use this function. */ static int megasas_build_ldio(struct megasas_instance *instance, struct scsi_cmnd *scp, struct megasas_cmd *cmd) { u32 device_id; u8 sc = scp->cmnd[0]; u16 flags = 0; struct megasas_io_frame *ldio; device_id = MEGASAS_DEV_INDEX(instance, scp); ldio = (struct megasas_io_frame *)cmd->frame; if (scp->sc_data_direction == PCI_DMA_TODEVICE) flags = MFI_FRAME_DIR_WRITE; else if (scp->sc_data_direction == PCI_DMA_FROMDEVICE) flags = MFI_FRAME_DIR_READ; /* * Prepare the Logical IO frame: 2nd bit is zero for all read cmds */ ldio->cmd = (sc & 0x02) ? MFI_CMD_LD_WRITE : MFI_CMD_LD_READ; ldio->cmd_status = 0x0; ldio->scsi_status = 0x0; ldio->target_id = device_id; ldio->timeout = 0; ldio->reserved_0 = 0; ldio->pad_0 = 0; ldio->flags = flags; ldio->start_lba_hi = 0; ldio->access_byte = (scp->cmd_len != 6) ? scp->cmnd[1] : 0; /* * 6-byte READ(0x08) or WRITE(0x0A) cdb */ if (scp->cmd_len == 6) { ldio->lba_count = (u32) scp->cmnd[4]; ldio->start_lba_lo = ((u32) scp->cmnd[1] << 16) | ((u32) scp->cmnd[2] << 8) | (u32) scp->cmnd[3]; ldio->start_lba_lo &= 0x1FFFFF; } /* * 10-byte READ(0x28) or WRITE(0x2A) cdb */ else if (scp->cmd_len == 10) { ldio->lba_count = (u32) scp->cmnd[8] | ((u32) scp->cmnd[7] << 8); ldio->start_lba_lo = ((u32) scp->cmnd[2] << 24) | ((u32) scp->cmnd[3] << 16) | ((u32) scp->cmnd[4] << 8) | (u32) scp->cmnd[5]; } /* * 12-byte READ(0xA8) or WRITE(0xAA) cdb */ else if (scp->cmd_len == 12) { ldio->lba_count = ((u32) scp->cmnd[6] << 24) | ((u32) scp->cmnd[7] << 16) | ((u32) scp->cmnd[8] << 8) | (u32) scp->cmnd[9]; ldio->start_lba_lo = ((u32) scp->cmnd[2] << 24) | ((u32) scp->cmnd[3] << 16) | ((u32) scp->cmnd[4] << 8) | (u32) scp->cmnd[5]; } /* * 16-byte READ(0x88) or WRITE(0x8A) cdb */ else if (scp->cmd_len == 16) { ldio->lba_count = ((u32) scp->cmnd[10] << 24) | ((u32) scp->cmnd[11] << 16) | ((u32) scp->cmnd[12] << 8) | (u32) scp->cmnd[13]; ldio->start_lba_lo = ((u32) scp->cmnd[6] << 24) | ((u32) scp->cmnd[7] << 16) | ((u32) scp->cmnd[8] << 8) | (u32) scp->cmnd[9]; ldio->start_lba_hi = ((u32) scp->cmnd[2] << 24) | ((u32) scp->cmnd[3] << 16) | ((u32) scp->cmnd[4] << 8) | (u32) scp->cmnd[5]; } /* * Construct SGL */ if (IS_DMA64) { ldio->flags |= MFI_FRAME_SGL64; ldio->sge_count = megasas_make_sgl64(instance, scp, &ldio->sgl); } else ldio->sge_count = megasas_make_sgl32(instance, scp, &ldio->sgl); /* * Sense info specific */ ldio->sense_len = SCSI_SENSE_BUFFERSIZE; ldio->sense_buf_phys_addr_hi = 0; ldio->sense_buf_phys_addr_lo = cmd->sense_phys_addr; /* * Compute the total number of frames this command consumes. FW uses * this number to pull sufficient number of frames from host memory. */ cmd->frame_count = megasas_get_frame_count(ldio->sge_count); return cmd->frame_count; } /** * megasas_is_ldio - Checks if the cmd is for logical drive * @scmd: SCSI command * * Called by megasas_queue_command to find out if the command to be queued * is a logical drive command */ static inline int megasas_is_ldio(struct scsi_cmnd *cmd) { if (!MEGASAS_IS_LOGICAL(cmd)) return 0; switch (cmd->cmnd[0]) { case READ_10: case WRITE_10: case READ_12: case WRITE_12: case READ_6: case WRITE_6: case READ_16: case WRITE_16: return 1; default: return 0; } } /** * megasas_dump_pending_frames - Dumps the frame address of all pending cmds * in FW * @instance: Adapter soft state */ static inline void megasas_dump_pending_frames(struct megasas_instance *instance) { struct megasas_cmd *cmd; int i,n; union megasas_sgl *mfi_sgl; struct megasas_io_frame *ldio; struct megasas_pthru_frame *pthru; u32 sgcount; u32 max_cmd = instance->max_fw_cmds; printk(KERN_ERR "\nmegasas[%d]: Dumping Frame Phys Address of all pending cmds in FW\n",instance->host->host_no); printk(KERN_ERR "megasas[%d]: Total OS Pending cmds : %d\n",instance->host->host_no,atomic_read(&instance->fw_outstanding)); if (IS_DMA64) printk(KERN_ERR "\nmegasas[%d]: 64 bit SGLs were sent to FW\n",instance->host->host_no); else printk(KERN_ERR "\nmegasas[%d]: 32 bit SGLs were sent to FW\n",instance->host->host_no); printk(KERN_ERR "megasas[%d]: Pending OS cmds in FW : \n",instance->host->host_no); for (i = 0; i < max_cmd; i++) { cmd = instance->cmd_list[i]; if(!cmd->scmd) continue; printk(KERN_ERR "megasas[%d]: Frame addr :0x%08lx : ",instance->host->host_no,(unsigned long)cmd->frame_phys_addr); if (megasas_is_ldio(cmd->scmd)){ ldio = (struct megasas_io_frame *)cmd->frame; mfi_sgl = &ldio->sgl; sgcount = ldio->sge_count; printk(KERN_ERR "megasas[%d]: frame count : 0x%x, Cmd : 0x%x, Tgt id : 0x%x, lba lo : 0x%x, lba_hi : 0x%x, sense_buf addr : 0x%x,sge count : 0x%x\n",instance->host->host_no, cmd->frame_count,ldio->cmd,ldio->target_id, ldio->start_lba_lo,ldio->start_lba_hi,ldio->sense_buf_phys_addr_lo,sgcount); } else { pthru = (struct megasas_pthru_frame *) cmd->frame; mfi_sgl = &pthru->sgl; sgcount = pthru->sge_count; printk(KERN_ERR "megasas[%d]: frame count : 0x%x, Cmd : 0x%x, Tgt id : 0x%x, lun : 0x%x, cdb_len : 0x%x, data xfer len : 0x%x, sense_buf addr : 0x%x,sge count : 0x%x\n",instance->host->host_no,cmd->frame_count,pthru->cmd,pthru->target_id,pthru->lun,pthru->cdb_len , pthru->data_xfer_len,pthru->sense_buf_phys_addr_lo,sgcount); } if(megasas_dbg_lvl & MEGASAS_DBG_LVL){ for (n = 0; n < sgcount; n++){ if (IS_DMA64) printk(KERN_ERR "megasas: sgl len : 0x%x, sgl addr : 0x%08lx ",mfi_sgl->sge64[n].length , (unsigned long)mfi_sgl->sge64[n].phys_addr) ; else printk(KERN_ERR "megasas: sgl len : 0x%x, sgl addr : 0x%x ",mfi_sgl->sge32[n].length , mfi_sgl->sge32[n].phys_addr) ; } } printk(KERN_ERR "\n"); } /*for max_cmd*/ printk(KERN_ERR "\nmegasas[%d]: Pending Internal cmds in FW : \n",instance->host->host_no); for (i = 0; i < max_cmd; i++) { cmd = instance->cmd_list[i]; if(cmd->sync_cmd == 1){ printk(KERN_ERR "0x%08lx : ", (unsigned long)cmd->frame_phys_addr); } } printk(KERN_ERR "megasas[%d]: Dumping Done.\n\n",instance->host->host_no); } /** * megasas_queue_command - Queue entry point * @scmd: SCSI command to be queued * @done: Callback entry point */ static int megasas_queue_command(struct scsi_cmnd *scmd, void (*done) (struct scsi_cmnd *)) { u32 frame_count; struct megasas_cmd *cmd; struct megasas_instance *instance; instance = (struct megasas_instance *) scmd->device->host->hostdata; scmd->scsi_done = done; scmd->result = 0; if (MEGASAS_IS_LOGICAL(scmd) && (scmd->device->id >= MEGASAS_MAX_LD || scmd->device->lun)) { scmd->result = DID_BAD_TARGET << 16; goto out_done; } if (MEGASAS_IS_LOGICAL(scmd)) { switch (scmd->cmnd[0]) { case SYNCHRONIZE_CACHE: if (crashdump_mode()) megasas_flush_cache(instance); case REQUEST_SENSE: case MODE_SELECT: case MODE_SENSE: if (crashdump_mode()) { scmd->result = (DID_OK << 16); goto out_done; } } } cmd = megasas_get_cmd(instance); if (!cmd) return SCSI_MLQUEUE_HOST_BUSY; /* * Logical drive command */ if (megasas_is_ldio(scmd)) frame_count = megasas_build_ldio(instance, scmd, cmd); else frame_count = megasas_build_dcdb(instance, scmd, cmd); if (!frame_count) goto out_return_cmd; cmd->scmd = scmd; /* * Issue the command to the FW */ atomic_inc(&instance->fw_outstanding); instance->instancet->fire_cmd(cmd->frame_phys_addr , cmd->frame_count-1,instance->reg_set); return 0; out_return_cmd: megasas_return_cmd(instance, cmd); out_done: done(scmd); return 0; } /** * megasas_wait_for_outstanding - Wait for all outstanding cmds * @instance: Adapter soft state * * This function waits for upto MEGASAS_RESET_WAIT_TIME seconds for FW to * complete all its outstanding commands. Returns error if one or more IOs * are pending after this time period. It also marks the controller dead. */ static int megasas_wait_for_outstanding(struct megasas_instance *instance) { int i; u32 wait_time = MEGASAS_RESET_WAIT_TIME; for (i = 0; i < wait_time; i++) { int outstanding = atomic_read(&instance->fw_outstanding); if (!outstanding) break; if (!(i % MEGASAS_RESET_NOTICE_INTERVAL)) { printk(KERN_NOTICE "megasas: [%2d]waiting for %d " "commands to complete\n",i,outstanding); } /* * In crash dump mode cannot complete cmds in interrupt context * Complete cmds from here */ if (crashdump_mode()) { megasas_deplete_reply_queue(instance, DID_OK); diskdump_update(); } megasas_msleep(1000); } if (atomic_read(&instance->fw_outstanding)) { /* * Send signal to FW to stop processing any pending cmds. * The controller will be taken offline by the OS now. */ writel(MFI_STOP_ADP, &instance->reg_set->inbound_doorbell); megasas_dump_pending_frames(instance); instance->hw_crit_error = 1; return FAILED; } return SUCCESS; } /** * megasas_generic_reset - Generic reset routine * @scmd: Mid-layer SCSI command * * This routine implements a generic reset handler for device, bus and host * reset requests. Device, bus and host specific reset handlers can use this * function after they do their specific tasks. */ static int megasas_generic_reset(struct scsi_cmnd *scmd) { int ret_val; struct megasas_instance *instance; instance = (struct megasas_instance *)scmd->device->host->hostdata; printk(KERN_NOTICE "megasas: RESET -%ld cmd=%x \n", scmd->serial_number, scmd->cmnd[0], scmd->device->channel, scmd->device->id, scmd->device->lun); if (instance->hw_crit_error) { printk(KERN_ERR "megasas: cannot recover from previous reset " "failures\n"); return FAILED; } spin_unlock(scmd->device->host->host_lock); ret_val = megasas_wait_for_outstanding(instance); if (ret_val == SUCCESS) printk(KERN_NOTICE "megasas: reset successful \n"); else printk(KERN_ERR "megasas: failed to do reset\n"); spin_lock(scmd->device->host->host_lock); return ret_val; } /** * megasas_reset_device - Device reset handler entry point */ static int megasas_reset_device(struct scsi_cmnd *scmd) { int ret; /* * First wait for all commands to complete */ ret = megasas_generic_reset(scmd); return ret; } /** * megasas_reset_bus_host - Bus & host reset handler entry point */ static int megasas_reset_bus_host(struct scsi_cmnd *scmd) { int ret; /* * Frist wait for all commands to complete */ ret = megasas_generic_reset(scmd); return ret; } /** * megasas_service_aen - Processes an event notification * @instance: Adapter soft state * @cmd: AEN command completed by the ISR * * For AEN, driver sends a command down to FW that is held by the FW till an * event occurs. When an event of interest occurs, FW completes the command * that it was previously holding. * * This routines sends SIGIO signal to processes that have registered with the * driver for AEN. */ static void megasas_service_aen(struct megasas_instance *instance, struct megasas_cmd *cmd) { /* * Don't signal app if it is just an aborted previously registered aen */ if (!cmd->abort_aen) kill_fasync(&megasas_async_queue, SIGIO, POLL_IN); else cmd->abort_aen = 0; instance->aen_cmd = NULL; megasas_return_cmd(instance, cmd); } static int megasas_slave_configure(struct scsi_device *sdev) { /* * The RAID firmware may require extended timeouts */ if(sdev->channel >= MEGASAS_MAX_PD_CHANNELS) sdev->timeout = 90 * HZ ; return 0; } /** * megasas_diskdump_sanity_check - Entry point for diskdump */ static int megasas_diskdump_sanity_check(struct scsi_device *device) { struct megasas_instance *instance; instance = (struct megasas_instance *)device->host->hostdata; if (!instance) return -ENXIO; if (spin_is_locked(&instance->cmd_pool_lock)) return -EBUSY; return 0; } /** * megasas_diskdump_poll - Interrupts are disabled during diskdump * so this fn is called by diskdump driver to * complete IO */ static void megasas_diskdump_poll(struct scsi_device *device) { struct megasas_instance *instance; instance = (struct megasas_instance *)device->host->hostdata; if (!instance) return; megasas_isr(0, instance, NULL); } /* * Scsi host template for megaraid_sas driver */ static struct scsi_host_template megasas_template = { .module = THIS_MODULE, .name = "LSI Logic SAS based MegaRAID driver", .proc_name = "megaraid_sas", .slave_configure = megasas_slave_configure, .queuecommand = megasas_queue_command, .eh_device_reset_handler = megasas_reset_device, .eh_bus_reset_handler = megasas_reset_bus_host, .eh_host_reset_handler = megasas_reset_bus_host, .use_clustering = ENABLE_CLUSTERING, .dump_sanity_check = megasas_diskdump_sanity_check, .dump_poll = megasas_diskdump_poll, }; /** * megasas_complete_int_cmd - Completes an internal command * @instance: Adapter soft state * @cmd: Command to be completed * * The megasas_issue_blocked_cmd() function waits for a command to complete * after it issues a command. This function wakes up that waiting routine by * calling wake_up() on the wait queue. */ static void megasas_complete_int_cmd(struct megasas_instance *instance, struct megasas_cmd *cmd) { cmd->cmd_status = cmd->frame->io.cmd_status; if (cmd->cmd_status == ENODATA) { cmd->cmd_status = 0; } wake_up(&instance->int_cmd_wait_q); } /** * megasas_complete_abort - Completes aborting a command * @instance: Adapter soft state * @cmd: Cmd that was issued to abort another cmd * * The megasas_issue_blocked_abort_cmd() function waits on abort_cmd_wait_q * after it issues an abort on a previously issued command. This function * wakes up all functions waiting on the same wait queue. */ static void megasas_complete_abort(struct megasas_instance *instance, struct megasas_cmd *cmd) { if (cmd->sync_cmd) { cmd->sync_cmd = 0; cmd->cmd_status = 0; wake_up(&instance->abort_cmd_wait_q); } return; } /** * megasas_unmap_sgbuf - Unmap SG buffers * @instance: Adapter soft state * @cmd: Completed command */ static inline void megasas_unmap_sgbuf(struct megasas_instance *instance, struct megasas_cmd *cmd) { dma_addr_t buf_h; u8 opcode; if (cmd->scmd->use_sg) { pci_unmap_sg(instance->pdev, cmd->scmd->request_buffer, cmd->scmd->use_sg, cmd->scmd->sc_data_direction); return; } if (!cmd->scmd->request_bufflen) return; opcode = cmd->frame->hdr.cmd; if ((opcode == MFI_CMD_LD_READ) || (opcode == MFI_CMD_LD_WRITE)) { if (IS_DMA64) buf_h = cmd->frame->io.sgl.sge64[0].phys_addr; else buf_h = cmd->frame->io.sgl.sge32[0].phys_addr; } else { if (IS_DMA64) buf_h = cmd->frame->pthru.sgl.sge64[0].phys_addr; else buf_h = cmd->frame->pthru.sgl.sge32[0].phys_addr; } pci_unmap_single(instance->pdev, buf_h, cmd->scmd->request_bufflen, cmd->scmd->sc_data_direction); return; } /** * megasas_complete_cmd - Completes a command * @instance: Adapter soft state * @cmd: Command to be completed * @alt_status: If non-zero, use this value as status to * SCSI mid-layer instead of the value returned * by the FW. This should be used if caller wants * an alternate status (as in the case of aborted * commands) */ static inline void megasas_complete_cmd(struct megasas_instance *instance, struct megasas_cmd *cmd, u8 alt_status) { int exception = 0; struct megasas_header *hdr = &cmd->frame->hdr; switch (hdr->cmd) { case MFI_CMD_PD_SCSI_IO: case MFI_CMD_LD_SCSI_IO: /* * MFI_CMD_PD_SCSI_IO and MFI_CMD_LD_SCSI_IO could have been * issued either through an IO path or an IOCTL path. If it * was via IOCTL, we will send it to internal completion. */ if (cmd->sync_cmd) { cmd->sync_cmd = 0; megasas_complete_int_cmd(instance, cmd); break; } /* * Don't export physical disk devices to mid-layer. */ if (!MEGASAS_IS_LOGICAL(cmd->scmd) && (hdr->cmd_status == MFI_STAT_OK) && (cmd->scmd->cmnd[0] == INQUIRY)) { if (((*(u8 *) cmd->scmd->request_buffer) & 0x1F) == TYPE_DISK) { cmd->scmd->result = DID_BAD_TARGET << 16; exception = 1; } } case MFI_CMD_LD_READ: case MFI_CMD_LD_WRITE: if (alt_status) { cmd->scmd->result = alt_status << 16; exception = 1; } if (exception) { atomic_dec(&instance->fw_outstanding); megasas_unmap_sgbuf(instance, cmd); cmd->scmd->scsi_done(cmd->scmd); megasas_return_cmd(instance, cmd); break; } switch (hdr->cmd_status) { case MFI_STAT_OK: cmd->scmd->result = DID_OK << 16; break; case MFI_STAT_SCSI_IO_FAILED: case MFI_STAT_LD_INIT_IN_PROGRESS: cmd->scmd->result = (DID_ERROR << 16) | hdr->scsi_status; break; case MFI_STAT_SCSI_DONE_WITH_ERROR: cmd->scmd->result = (DID_OK << 16) | hdr->scsi_status; if (hdr->scsi_status == SAM_STAT_CHECK_CONDITION) { memset(cmd->scmd->sense_buffer, 0, SCSI_SENSE_BUFFERSIZE); memcpy(cmd->scmd->sense_buffer, cmd->sense, hdr->sense_len); cmd->scmd->result |= DRIVER_SENSE << 24; } break; case MFI_STAT_LD_OFFLINE: case MFI_STAT_DEVICE_NOT_FOUND: cmd->scmd->result = DID_BAD_TARGET << 16; break; default: printk(KERN_DEBUG "megasas: MFI FW status %#x\n", hdr->cmd_status); cmd->scmd->result = DID_ERROR << 16; break; } atomic_dec(&instance->fw_outstanding); megasas_unmap_sgbuf(instance, cmd); cmd->scmd->scsi_done(cmd->scmd); megasas_return_cmd(instance, cmd); break; case MFI_CMD_SMP: case MFI_CMD_STP: case MFI_CMD_DCMD: /* * See if got an event notification */ if (cmd->frame->dcmd.opcode == MR_DCMD_CTRL_EVENT_WAIT) megasas_service_aen(instance, cmd); else megasas_complete_int_cmd(instance, cmd); break; case MFI_CMD_ABORT: /* * Cmd issued to abort another cmd returned */ megasas_complete_abort(instance, cmd); break; default: printk("megasas: Unknown command completed! [0x%X]\n", hdr->cmd); break; } } /** * megasas_deplete_reply_queue - Processes all completed commands * @instance: Adapter soft state * @alt_status: Alternate status to be returned to * SCSI mid-layer instead of the status * returned by the FW */ static int megasas_deplete_reply_queue(struct megasas_instance *instance, u8 alt_status) { /* * Check if it is our interrupt * Clear the interrupt */ if(instance->instancet->clear_intr(instance->reg_set)) return IRQ_NONE; /* * Schedule the tasklet for cmd completion */ tasklet_schedule(&instance->isr_tasklet); return IRQ_HANDLED; } /** * megasas_isr - isr entry point */ static irqreturn_t megasas_isr(int irq, void *devp, struct pt_regs *regs) { return megasas_deplete_reply_queue((struct megasas_instance *)devp, DID_OK); } /** * megasas_transition_to_ready - Move the FW to READY state * @instance: Adapter soft state * * During the initialization, FW passes can potentially be in any one of * several possible states. If the FW in operational, waiting-for-handshake * states, driver must take steps to bring it to ready state. Otherwise, it * has to wait for the ready state. */ static int megasas_transition_to_ready(struct megasas_instance* instance) { int i; u8 max_wait; u32 fw_state; u32 cur_state; fw_state = instance->instancet->read_fw_status_reg(instance->reg_set) & MFI_STATE_MASK; if (fw_state != MFI_STATE_READY) printk(KERN_INFO "megasas: Waiting for FW to come to ready" " state\n"); while (fw_state != MFI_STATE_READY) { switch (fw_state) { case MFI_STATE_FAULT: printk(KERN_DEBUG "megasas: FW in FAULT state!!\n"); return -ENODEV; case MFI_STATE_WAIT_HANDSHAKE: /* * Set the CLR bit in inbound doorbell */ writel(MFI_INIT_CLEAR_HANDSHAKE|MFI_INIT_HOTPLUG, &instance->reg_set->inbound_doorbell); max_wait = 2; cur_state = MFI_STATE_WAIT_HANDSHAKE; break; case MFI_STATE_BOOT_MESSAGE_PENDING: writel(MFI_INIT_HOTPLUG, &instance->reg_set->inbound_doorbell); max_wait = 10; cur_state = MFI_STATE_BOOT_MESSAGE_PENDING; break; case MFI_STATE_OPERATIONAL: /* * Bring it to READY state; assuming max wait 10 secs */ instance->instancet->disable_intr(instance->reg_set); writel(MFI_RESET_FLAGS, &instance->reg_set->inbound_doorbell); max_wait = 10; cur_state = MFI_STATE_OPERATIONAL; break; case MFI_STATE_UNDEFINED: /* * This state should not last for more than 2 seconds */ max_wait = 2; cur_state = MFI_STATE_UNDEFINED; break; case MFI_STATE_BB_INIT: max_wait = 2; cur_state = MFI_STATE_BB_INIT; break; case MFI_STATE_FW_INIT: max_wait = 20; cur_state = MFI_STATE_FW_INIT; break; case MFI_STATE_FW_INIT_2: max_wait = 20; cur_state = MFI_STATE_FW_INIT_2; break; case MFI_STATE_DEVICE_SCAN: max_wait = 20; cur_state = MFI_STATE_DEVICE_SCAN; break; case MFI_STATE_FLUSH_CACHE: max_wait = 20; cur_state = MFI_STATE_FLUSH_CACHE; break; default: printk(KERN_DEBUG "megasas: Unknown state 0x%x\n", fw_state); return -ENODEV; } /* * The cur_state should not last for more than max_wait secs */ for (i = 0; i < (max_wait * 1000); i++) { fw_state = instance->instancet->read_fw_status_reg(instance->reg_set) & MFI_STATE_MASK ; if (fw_state == cur_state) { megasas_msleep(1); } else break; } /* * Return error if fw_state hasn't changed after max_wait */ if (fw_state == cur_state) { printk(KERN_DEBUG "FW state [%d] hasn't changed " "in %d secs\n", fw_state, max_wait); return -ENODEV; } }; printk(KERN_INFO "megasas: FW now in Ready state\n"); return 0; } /** * megasas_teardown_frame_pool - Destroy the cmd frame DMA pool * @instance: Adapter soft state */ static void megasas_teardown_frame_pool(struct megasas_instance *instance) { int i; u32 max_cmd = instance->max_fw_cmds; struct megasas_cmd *cmd; if (!instance->frame_dma_pool) return; /* * Return all frames to pool */ for (i = 0; i < max_cmd; i++) { cmd = instance->cmd_list[i]; if (cmd->frame) pci_pool_free(instance->frame_dma_pool, cmd->frame, cmd->frame_phys_addr); if (cmd->sense) pci_pool_free(instance->sense_dma_pool, cmd->frame, cmd->sense_phys_addr); } /* * Now destroy the pool itself */ pci_pool_destroy(instance->frame_dma_pool); pci_pool_destroy(instance->sense_dma_pool); instance->frame_dma_pool = NULL; instance->sense_dma_pool = NULL; } /** * megasas_create_frame_pool - Creates DMA pool for cmd frames * @instance: Adapter soft state * * Each command packet has an embedded DMA memory buffer that is used for * filling MFI frame and the SG list that immediately follows the frame. This * function creates those DMA memory buffers for each command packet by using * PCI pool facility. */ static int megasas_create_frame_pool(struct megasas_instance *instance) { int i; u32 max_cmd; u32 sge_sz; u32 sgl_sz; u32 total_sz; u32 frame_count; struct megasas_cmd *cmd; max_cmd = instance->max_fw_cmds; /* * Size of our frame is 64 bytes for MFI frame, followed by max SG * elements and finally SCSI_SENSE_BUFFERSIZE bytes for sense buffer */ sge_sz = (IS_DMA64) ? sizeof(struct megasas_sge64) : sizeof(struct megasas_sge32); /* * Calculated the number of 64byte frames required for SGL */ sgl_sz = sge_sz * instance->max_num_sge; frame_count = (sgl_sz + MEGAMFI_FRAME_SIZE - 1) / MEGAMFI_FRAME_SIZE; /* * We need one extra frame for the MFI command */ frame_count++; total_sz = MEGAMFI_FRAME_SIZE * frame_count; /* * Use DMA pool facility provided by PCI layer */ instance->frame_dma_pool = pci_pool_create("megasas frame pool", instance->pdev, total_sz, 64, 0); if (!instance->frame_dma_pool) { printk(KERN_DEBUG "megasas: failed to setup frame pool\n"); return -ENOMEM; } instance->sense_dma_pool = pci_pool_create("megasas sense pool", instance->pdev, 128, 4, 0); if (!instance->sense_dma_pool) { printk(KERN_DEBUG "megasas: failed to setup sense pool\n"); pci_pool_destroy(instance->frame_dma_pool); instance->frame_dma_pool = NULL; return -ENOMEM; } /* * Allocate and attach a frame to each of the commands in cmd_list. * By making cmd->index as the context instead of the &cmd, we can * always use 32bit context regardless of the architecture */ for (i = 0; i < max_cmd; i++) { cmd = instance->cmd_list[i]; cmd->frame = pci_pool_alloc(instance->frame_dma_pool, GFP_KERNEL, &cmd->frame_phys_addr); cmd->sense = pci_pool_alloc(instance->sense_dma_pool, GFP_KERNEL, &cmd->sense_phys_addr); /* * megasas_teardown_frame_pool() takes care of freeing * whatever has been allocated */ if (!cmd->frame || !cmd->sense) { printk(KERN_DEBUG "megasas: pci_pool_alloc failed \n"); megasas_teardown_frame_pool(instance); return -ENOMEM; } cmd->frame->io.context = cmd->index; } return 0; } /** * megasas_free_cmds - Free all the cmds in the free cmd pool * @instance: Adapter soft state */ static void megasas_free_cmds(struct megasas_instance *instance) { int i; /* First free the MFI frame pool */ megasas_teardown_frame_pool(instance); /* Free all the commands in the cmd_list */ for (i = 0; i < instance->max_fw_cmds; i++) kfree(instance->cmd_list[i]); /* Free the cmd_list buffer itself */ kfree(instance->cmd_list); instance->cmd_list = NULL; INIT_LIST_HEAD(&instance->cmd_pool); } /** * megasas_alloc_cmds - Allocates the command packets * @instance: Adapter soft state * * Each command that is issued to the FW, whether IO commands from the OS or * internal commands like IOCTLs, are wrapped in local data structure called * megasas_cmd. The frame embedded in this megasas_cmd is actually issued to * the FW. * * Each frame has a 32-bit field called context (tag). This context is used * to get back the megasas_cmd from the frame when a frame gets completed in * the ISR. Typically the address of the megasas_cmd itself would be used as * the context. But we wanted to keep the differences between 32 and 64 bit * systems to the mininum. We always use 32 bit integers for the context. In * this driver, the 32 bit values are the indices into an array cmd_list. * This array is used only to look up the megasas_cmd given the context. The * free commands themselves are maintained in a linked list called cmd_pool. */ static int megasas_alloc_cmds(struct megasas_instance *instance) { int i; int j; u32 max_cmd; struct megasas_cmd *cmd; max_cmd = instance->max_fw_cmds; /* * instance->cmd_list is an array of struct megasas_cmd pointers. * Allocate the dynamic array first and then allocate individual * commands. */ instance->cmd_list = kmalloc(sizeof(struct megasas_cmd *) * max_cmd, GFP_KERNEL); if (!instance->cmd_list) { printk(KERN_DEBUG "megasas: out of memory\n"); return -ENOMEM; } memset(instance->cmd_list, 0, sizeof(struct megasas_cmd *) * max_cmd); for (i = 0; i < max_cmd; i++) { instance->cmd_list[i] = kmalloc(sizeof(struct megasas_cmd), GFP_KERNEL); if (!instance->cmd_list[i]) { for (j = 0; j < i; j++) kfree(instance->cmd_list[j]); kfree(instance->cmd_list); instance->cmd_list = NULL; return -ENOMEM; } } /* * Add all the commands to command pool (instance->cmd_pool) */ for (i = 0; i < max_cmd; i++) { cmd = instance->cmd_list[i]; memset(cmd, 0, sizeof(struct megasas_cmd)); cmd->index = i; cmd->instance = instance; list_add_tail(&cmd->list, &instance->cmd_pool); } /* * Create a frame pool and assign one frame to each cmd */ if (megasas_create_frame_pool(instance)) { printk(KERN_DEBUG "megasas: Error creating frame DMA pool\n"); megasas_free_cmds(instance); } return 0; } /** * megasas_get_controller_info - Returns FW's controller structure * @instance: Adapter soft state * @ctrl_info: Controller information structure * * Issues an internal command (DCMD) to get the FW's controller structure. * This information is mainly used to find out the maximum IO transfer per * command supported by the FW. */ static int megasas_get_ctrl_info(struct megasas_instance *instance, struct megasas_ctrl_info *ctrl_info) { int ret = 0; struct megasas_cmd *cmd; struct megasas_dcmd_frame *dcmd; struct megasas_ctrl_info *ci; dma_addr_t ci_h = 0; cmd = megasas_get_cmd(instance); if (!cmd) { printk(KERN_DEBUG "megasas: Failed to get a free cmd\n"); return -ENOMEM; } dcmd = &cmd->frame->dcmd; ci = pci_alloc_consistent(instance->pdev, sizeof(struct megasas_ctrl_info), &ci_h); if (!ci) { printk(KERN_DEBUG "Failed to alloc mem for ctrl info\n"); megasas_return_cmd(instance, cmd); return -ENOMEM; } memset(ci, 0, sizeof(*ci)); memset(dcmd->mbox.b, 0, MFI_MBOX_SIZE); dcmd->cmd = MFI_CMD_DCMD; dcmd->cmd_status = 0xFF; dcmd->sge_count = 1; dcmd->flags = MFI_FRAME_DIR_READ; dcmd->timeout = 0; dcmd->data_xfer_len = sizeof(struct megasas_ctrl_info); dcmd->opcode = MR_DCMD_CTRL_GET_INFO; dcmd->sgl.sge32[0].phys_addr = ci_h; dcmd->sgl.sge32[0].length = sizeof(struct megasas_ctrl_info); if (!megasas_issue_polled(instance, cmd)) { ret = 0; memcpy(ctrl_info, ci, sizeof(struct megasas_ctrl_info)); } else { ret = -1; } pci_free_consistent(instance->pdev, sizeof(struct megasas_ctrl_info), ci, ci_h); megasas_return_cmd(instance, cmd); return ret; } /** * megasas_complete_cmd_dpc - Returns FW's controller structure * @instance_addr: Address of adapter soft state * * Tasklet to complete cmds */ void megasas_complete_cmd_dpc(unsigned long instance_addr) { u32 producer; u32 consumer; u32 context; struct megasas_cmd *cmd; struct megasas_instance *instance = (struct megasas_instance *)instance_addr; producer = *instance->producer; consumer = *instance->consumer; while (consumer != producer) { context = instance->reply_queue[consumer]; cmd = instance->cmd_list[context]; megasas_complete_cmd(instance, cmd, DID_OK); consumer++; if (consumer == (instance->max_fw_cmds + 1)) { consumer = 0; } } *instance->consumer = producer; } /** * megasas_init_mfi - Initializes the FW * @instance: Adapter soft state * * This is the main function for initializing MFI firmware. */ static int megasas_init_mfi(struct megasas_instance *instance) { u32 context_sz; u32 reply_q_sz; u32 max_sectors_1; u32 max_sectors_2; struct megasas_register_set __iomem *reg_set; struct megasas_cmd *cmd; struct megasas_ctrl_info *ctrl_info; struct megasas_init_frame *init_frame; struct megasas_init_queue_info *initq_info; dma_addr_t init_frame_h; dma_addr_t initq_info_h; /* * Map the message registers */ instance->base_addr = pci_resource_start(instance->pdev, 0); if (pci_request_regions(instance->pdev, "megasas: LSI Logic")) { printk(KERN_DEBUG "megasas: IO memory region busy!\n"); return -EBUSY; } instance->reg_set = ioremap_nocache(instance->base_addr, 8192); if (!instance->reg_set) { printk(KERN_DEBUG "megasas: Failed to map IO mem\n"); goto fail_ioremap; } reg_set = instance->reg_set; switch(instance->pdev->device) { case PCI_DEVICE_ID_LSI_SAS1078R: instance->instancet = &megasas_instance_template_ppc; break; case PCI_DEVICE_ID_LSI_SAS1064R: case PCI_DEVICE_ID_DELL_PERC5: default: instance->instancet = &megasas_instance_template_xscale; break; } /* * We expect the FW state to be READY */ if (megasas_transition_to_ready(instance)) goto fail_ready_state; /* * Get various operational parameters from status register */ instance->max_fw_cmds = instance->instancet->read_fw_status_reg(reg_set) & 0x00FFFF; /* * Reduce the max supported FW cmds by 1. This is to ensure that the * reply_q_sz (1 more than the max cmd that driver may send) * does not exceed max_fw_cmds */ instance->max_fw_cmds = instance->max_fw_cmds-1; instance->max_num_sge = (instance->instancet->read_fw_status_reg(reg_set) & 0xFF0000) >> 0x10; /* * Create a pool of commands */ if (megasas_alloc_cmds(instance)) goto fail_alloc_cmds; /* * Allocate memory for reply queue. Length of reply queue should * be _one_ more than the maximum commands handled by the firmware. * * Note: When FW completes commands, it places corresponding contex * values in this circular reply queue. This circular queue is a fairly * typical producer-consumer queue. FW is the producer (of completed * commands) and the driver is the consumer. */ context_sz = sizeof(u32); reply_q_sz = context_sz * (instance->max_fw_cmds + 1); instance->reply_queue = pci_alloc_consistent(instance->pdev, reply_q_sz, &instance->reply_queue_h); if (!instance->reply_queue) { printk(KERN_DEBUG "megasas: Out of DMA mem for reply queue\n"); goto fail_reply_queue; } /* * Prepare a init frame. Note the init frame points to queue info * structure. Each frame has SGL allocated after first 64 bytes. For * this frame - since we don't need any SGL - we use SGL's space as * queue info structure * * We will not get a NULL command below. We just created the pool. */ cmd = megasas_get_cmd(instance); init_frame = (struct megasas_init_frame *)cmd->frame; initq_info = (struct megasas_init_queue_info *) ((unsigned long)init_frame + 64); init_frame_h = cmd->frame_phys_addr; initq_info_h = init_frame_h + 64; memset(init_frame, 0, MEGAMFI_FRAME_SIZE); memset(initq_info, 0, sizeof(struct megasas_init_queue_info)); initq_info->reply_queue_entries = instance->max_fw_cmds + 1; initq_info->reply_queue_start_phys_addr_lo = instance->reply_queue_h; initq_info->producer_index_phys_addr_lo = instance->producer_h; initq_info->consumer_index_phys_addr_lo = instance->consumer_h; init_frame->cmd = MFI_CMD_INIT; init_frame->cmd_status = 0xFF; init_frame->queue_info_new_phys_addr_lo = initq_info_h; init_frame->data_xfer_len = sizeof(struct megasas_init_queue_info); /* * disable the intr before fire the init frame to FW */ instance->instancet->disable_intr(instance->reg_set); /* * Issue the init frame in polled mode */ if (megasas_issue_polled(instance, cmd)) { printk(KERN_DEBUG "megasas: Failed to init firmware\n"); goto fail_fw_init; } megasas_return_cmd(instance, cmd); ctrl_info = kmalloc(sizeof(struct megasas_ctrl_info), GFP_KERNEL); /* * Compute the max allowed sectors per IO: The controller info has two * limits on max sectors. Driver should use the minimum of these two. * * 1 << stripe_sz_ops.min = max sectors per strip * * Note that older firmwares ( < FW ver 30) didn't report information * to calculate max_sectors_1. So the number ended up as zero always. */ if (ctrl_info && !megasas_get_ctrl_info(instance, ctrl_info)) { max_sectors_1 = (1 << ctrl_info->stripe_sz_ops.min) * ctrl_info->max_strips_per_io; max_sectors_2 = ctrl_info->max_request_size; instance->max_sectors_per_req = (max_sectors_1 < max_sectors_2) ? max_sectors_1 : max_sectors_2; } else instance->max_sectors_per_req = instance->max_num_sge * PAGE_SIZE / 512; kfree(ctrl_info); /* * Setup tasklet for cmd completion */ tasklet_init(&instance->isr_tasklet, megasas_complete_cmd_dpc, (unsigned long)instance); return 0; fail_fw_init: megasas_return_cmd(instance, cmd); pci_free_consistent(instance->pdev, reply_q_sz, instance->reply_queue, instance->reply_queue_h); fail_reply_queue: megasas_free_cmds(instance); fail_alloc_cmds: fail_ready_state: iounmap(instance->reg_set); fail_ioremap: pci_release_regions(instance->pdev); return -EINVAL; } /** * megasas_release_mfi - Reverses the FW initialization * @intance: Adapter soft state */ static void megasas_release_mfi(struct megasas_instance *instance) { u32 reply_q_sz = sizeof(u32) * (instance->max_fw_cmds + 1); pci_free_consistent(instance->pdev, reply_q_sz, instance->reply_queue, instance->reply_queue_h); megasas_free_cmds(instance); iounmap(instance->reg_set); pci_release_regions(instance->pdev); } /** * megasas_get_seq_num - Gets latest event sequence numbers * @instance: Adapter soft state * @eli: FW event log sequence numbers information * * FW maintains a log of all events in a non-volatile area. Upper layers would * usually find out the latest sequence number of the events, the seq number at * the boot etc. They would "read" all the events below the latest seq number * by issuing a direct fw cmd (DCMD). For the future events (beyond latest seq * number), they would subsribe to AEN (asynchronous event notification) and * wait for the events to happen. */ static int megasas_get_seq_num(struct megasas_instance *instance, struct megasas_evt_log_info *eli) { struct megasas_cmd *cmd; struct megasas_dcmd_frame *dcmd; struct megasas_evt_log_info *el_info; dma_addr_t el_info_h = 0; cmd = megasas_get_cmd(instance); if (!cmd) { return -ENOMEM; } dcmd = &cmd->frame->dcmd; el_info = pci_alloc_consistent(instance->pdev, sizeof(struct megasas_evt_log_info), &el_info_h); if (!el_info) { megasas_return_cmd(instance, cmd); return -ENOMEM; } memset(el_info, 0, sizeof(*el_info)); memset(dcmd->mbox.b, 0, MFI_MBOX_SIZE); dcmd->cmd = MFI_CMD_DCMD; dcmd->cmd_status = 0x0; dcmd->sge_count = 1; dcmd->flags = MFI_FRAME_DIR_READ; dcmd->timeout = 0; dcmd->data_xfer_len = sizeof(struct megasas_evt_log_info); dcmd->opcode = MR_DCMD_CTRL_EVENT_GET_INFO; dcmd->sgl.sge32[0].phys_addr = el_info_h; dcmd->sgl.sge32[0].length = sizeof(struct megasas_evt_log_info); megasas_issue_blocked_cmd(instance, cmd); /* * Copy the data back into callers buffer */ memcpy(eli, el_info, sizeof(struct megasas_evt_log_info)); pci_free_consistent(instance->pdev, sizeof(struct megasas_evt_log_info), el_info, el_info_h); megasas_return_cmd(instance, cmd); return 0; } /** * megasas_register_aen - Registers for asynchronous event notification * @instance: Adapter soft state * @seq_num: The starting sequence number * @class_locale: Class of the event * * This function subscribes for AEN for events beyond the @seq_num. It requests * to be notified if and only if the event is of type @class_locale */ static int megasas_register_aen(struct megasas_instance *instance, u32 seq_num, u32 class_locale_word) { int ret_val; struct megasas_cmd *cmd; struct megasas_dcmd_frame *dcmd; union megasas_evt_class_locale curr_aen; union megasas_evt_class_locale prev_aen; /* * If there an AEN pending already (aen_cmd), check if the * class_locale of that pending AEN is inclusive of the new * AEN request we currently have. If it is, then we don't have * to do anything. In other words, whichever events the current * AEN request is subscribing to, have already been subscribed * to. * * If the old_cmd is _not_ inclusive, then we have to abort * that command, form a class_locale that is superset of both * old and current and re-issue to the FW */ curr_aen.word = class_locale_word; if (instance->aen_cmd) { prev_aen.word = instance->aen_cmd->frame->dcmd.mbox.w[1]; /* * A class whose enum value is smaller is inclusive of all * higher values. If a PROGRESS (= -1) was previously * registered, then a new registration requests for higher * classes need not be sent to FW. They are automatically * included. * * Locale numbers don't have such hierarchy. They are bitmap * values */ if ((prev_aen.members.class <= curr_aen.members.class) && !((prev_aen.members.locale & curr_aen.members.locale) ^ curr_aen.members.locale)) { /* * Previously issued event registration includes * current request. Nothing to do. */ return 0; } else { curr_aen.members.locale |= prev_aen.members.locale; if (prev_aen.members.class < curr_aen.members.class) curr_aen.members.class = prev_aen.members.class; instance->aen_cmd->abort_aen = 1; ret_val = megasas_issue_blocked_abort_cmd(instance, instance-> aen_cmd); if (ret_val) { printk(KERN_DEBUG "megasas: Failed to abort " "previous AEN command\n"); return ret_val; } } } cmd = megasas_get_cmd(instance); if (!cmd) return -ENOMEM; dcmd = &cmd->frame->dcmd; memset(instance->evt_detail, 0, sizeof(struct megasas_evt_detail)); /* * Prepare DCMD for aen registration */ memset(dcmd->mbox.b, 0, MFI_MBOX_SIZE); dcmd->cmd = MFI_CMD_DCMD; dcmd->cmd_status = 0x0; dcmd->sge_count = 1; dcmd->flags = MFI_FRAME_DIR_READ; dcmd->timeout = 0; dcmd->data_xfer_len = sizeof(struct megasas_evt_detail); dcmd->opcode = MR_DCMD_CTRL_EVENT_WAIT; dcmd->mbox.w[0] = seq_num; dcmd->mbox.w[1] = curr_aen.word; dcmd->sgl.sge32[0].phys_addr = (u32) instance->evt_detail_h; dcmd->sgl.sge32[0].length = sizeof(struct megasas_evt_detail); /* * Store reference to the cmd used to register for AEN. When an * application wants us to register for AEN, we have to abort this * cmd and re-register with a new EVENT LOCALE supplied by that app */ instance->aen_cmd = cmd; /* * Issue the aen registration frame */ instance->instancet->fire_cmd(cmd->frame_phys_addr ,0,instance->reg_set); return 0; } /** * megasas_start_aen - Subscribes to AEN during driver load time * @instance: Adapter soft state */ static int megasas_start_aen(struct megasas_instance *instance) { struct megasas_evt_log_info eli; union megasas_evt_class_locale class_locale; /* * Get the latest sequence number from FW */ memset(&eli, 0, sizeof(eli)); if (megasas_get_seq_num(instance, &eli)) return -1; /* * Register AEN with FW for latest sequence number plus 1 */ class_locale.members.reserved = 0; class_locale.members.locale = MR_EVT_LOCALE_ALL; class_locale.members.class = MR_EVT_CLASS_DEBUG; return megasas_register_aen(instance, eli.newest_seq_num + 1, class_locale.word); } /** * megasas_io_attach - Attaches this driver to SCSI mid-layer * @instance: Adapter soft state */ static int megasas_io_attach(struct megasas_instance *instance) { struct Scsi_Host *host = instance->host; /* * Export parameters required by SCSI mid-layer */ host->irq = instance->pdev->irq; host->unique_id = instance->unique_id; host->can_queue = instance->max_fw_cmds - MEGASAS_INT_CMDS; host->this_id = instance->init_id; host->sg_tablesize = instance->max_num_sge; host->max_sectors = instance->max_sectors_per_req; host->cmd_per_lun = 128; host->max_channel = MEGASAS_MAX_CHANNELS - 1; host->max_id = MEGASAS_MAX_DEV_PER_CHANNEL; host->max_lun = MEGASAS_MAX_LUN; host->max_cmd_len = 16; /* * Notify the mid-layer about the new controller */ if (scsi_add_host(host, &instance->pdev->dev)) { printk(KERN_DEBUG "megasas: scsi_add_host failed\n"); return -ENODEV; } /* * Trigger SCSI to scan our drives */ scsi_scan_host(host); return 0; } /** * megasas_probe_one - PCI hotplug entry point * @pdev: PCI device structure * @id: PCI ids of supported hotplugged adapter */ static int __devinit megasas_probe_one(struct pci_dev *pdev, const struct pci_device_id *id) { int rval; struct Scsi_Host *host; struct megasas_instance *instance; /* * Announce PCI information */ printk(KERN_INFO "megasas: %#4.04x:%#4.04x:%#4.04x:%#4.04x: ", pdev->vendor, pdev->device, pdev->subsystem_vendor, pdev->subsystem_device); printk("bus %d:slot %d:func %d\n", pdev->bus->number, PCI_SLOT(pdev->devfn), PCI_FUNC(pdev->devfn)); /* * PCI prepping: enable device set bus mastering and dma mask */ rval = pci_enable_device(pdev); if (rval) { return rval; } pci_set_master(pdev); /* * All our contollers are capable of performing 64-bit DMA */ if (IS_DMA64) { if (pci_set_dma_mask(pdev, DMA_64BIT_MASK) != 0) { if (pci_set_dma_mask(pdev, DMA_32BIT_MASK) != 0) goto fail_set_dma_mask; } } else { if (pci_set_dma_mask(pdev, DMA_32BIT_MASK) != 0) goto fail_set_dma_mask; } host = scsi_host_alloc(&megasas_template, sizeof(struct megasas_instance)); if (!host) { printk(KERN_DEBUG "megasas: scsi_host_alloc failed\n"); goto fail_alloc_instance; } instance = (struct megasas_instance *)host->hostdata; memset(instance, 0, sizeof(*instance)); instance->producer = pci_alloc_consistent(pdev, sizeof(u32), &instance->producer_h); instance->consumer = pci_alloc_consistent(pdev, sizeof(u32), &instance->consumer_h); if (!instance->producer || !instance->consumer) { printk(KERN_DEBUG "megasas: Failed to allocate memory for " "producer, consumer\n"); goto fail_alloc_dma_buf; } *instance->producer = 0; *instance->consumer = 0; instance->evt_detail = pci_alloc_consistent(pdev, sizeof(struct megasas_evt_detail), &instance->evt_detail_h); if (!instance->evt_detail) { printk(KERN_DEBUG "megasas: Failed to allocate memory for " "event detail structure\n"); goto fail_alloc_dma_buf; } /* * Initialize locks and queues */ INIT_LIST_HEAD(&instance->cmd_pool); atomic_set(&instance->fw_outstanding,0); init_waitqueue_head(&instance->int_cmd_wait_q); init_waitqueue_head(&instance->abort_cmd_wait_q); spin_lock_init(&instance->cmd_pool_lock); sema_init(&instance->aen_mutex, 1); sema_init(&instance->ioctl_sem, MEGASAS_INT_CMDS); /* * Initialize PCI related and misc parameters */ instance->pdev = pdev; instance->host = host; instance->unique_id = pdev->bus->number << 8 | pdev->devfn; instance->init_id = MEGASAS_DEFAULT_INIT_ID; megasas_dbg_lvl = 0; /* * Initialize MFI Firmware */ if (megasas_init_mfi(instance)) goto fail_init_mfi; /* * Register IRQ */ if (request_irq(pdev->irq, megasas_isr, SA_SHIRQ, "megasas", instance)) { printk(KERN_DEBUG "megasas: Failed to register IRQ\n"); goto fail_irq; } instance->instancet->enable_intr(instance->reg_set); /* * Store instance in PCI softstate */ pci_set_drvdata(pdev, instance); /* * Add this controller to megasas_mgmt_info structure so that it * can be exported to management applications */ megasas_mgmt_info.count++; megasas_mgmt_info.instance[megasas_mgmt_info.max_index] = instance; megasas_mgmt_info.max_index++; /* * Initiate AEN (Asynchronous Event Notification) */ if (megasas_start_aen(instance)) { printk(KERN_DEBUG "megasas: start aen failed\n"); goto fail_start_aen; } /* * Register with SCSI mid-layer */ if (megasas_io_attach(instance)) goto fail_io_attach; return 0; fail_start_aen: fail_io_attach: megasas_mgmt_info.count--; megasas_mgmt_info.instance[megasas_mgmt_info.max_index] = NULL; megasas_mgmt_info.max_index--; pci_set_drvdata(pdev, NULL); instance->instancet->disable_intr(instance->reg_set); free_irq(instance->pdev->irq, instance); megasas_release_mfi(instance); fail_irq: fail_init_mfi: fail_alloc_dma_buf: if (instance->evt_detail) pci_free_consistent(pdev, sizeof(struct megasas_evt_detail), instance->evt_detail, instance->evt_detail_h); if (instance->producer) pci_free_consistent(pdev, sizeof(u32), instance->producer, instance->producer_h); if (instance->consumer) pci_free_consistent(pdev, sizeof(u32), instance->consumer, instance->consumer_h); scsi_host_put(host); fail_alloc_instance: fail_set_dma_mask: pci_disable_device(pdev); return -ENODEV; } /** * megasas_flush_cache - Requests FW to flush all its caches * @instance: Adapter soft state */ static void megasas_flush_cache(struct megasas_instance *instance) { struct megasas_cmd *cmd; struct megasas_dcmd_frame *dcmd; cmd = megasas_get_cmd(instance); if (!cmd) return; dcmd = &cmd->frame->dcmd; memset(dcmd->mbox.b, 0, MFI_MBOX_SIZE); dcmd->cmd = MFI_CMD_DCMD; dcmd->cmd_status = 0x0; dcmd->sge_count = 0; dcmd->flags = MFI_FRAME_DIR_NONE; dcmd->timeout = 0; dcmd->data_xfer_len = 0; dcmd->opcode = MR_DCMD_CTRL_CACHE_FLUSH; dcmd->mbox.b[0] = MR_FLUSH_CTRL_CACHE | MR_FLUSH_DISK_CACHE; if (crashdump_mode()) megasas_issue_polled(instance, cmd); else megasas_issue_blocked_cmd(instance, cmd); megasas_return_cmd(instance, cmd); return; } /** * megasas_shutdown_controller - Instructs FW to shutdown the controller * @instance: Adapter soft state */ static void megasas_shutdown_controller(struct megasas_instance *instance) { struct megasas_cmd *cmd; struct megasas_dcmd_frame *dcmd; cmd = megasas_get_cmd(instance); if (!cmd) return; if (instance->aen_cmd) megasas_issue_blocked_abort_cmd(instance, instance->aen_cmd); dcmd = &cmd->frame->dcmd; memset(dcmd->mbox.b, 0, MFI_MBOX_SIZE); dcmd->cmd = MFI_CMD_DCMD; dcmd->cmd_status = 0x0; dcmd->sge_count = 0; dcmd->flags = MFI_FRAME_DIR_NONE; dcmd->timeout = 0; dcmd->data_xfer_len = 0; dcmd->opcode = MR_DCMD_CTRL_SHUTDOWN; megasas_issue_blocked_cmd(instance, cmd); megasas_return_cmd(instance, cmd); return; } /** * megasas_detach_one - PCI hot"un"plug entry point * @pdev: PCI device structure */ static void megasas_detach_one(struct pci_dev *pdev) { int i; struct Scsi_Host *host; struct megasas_instance *instance; instance = pci_get_drvdata(pdev); host = instance->host; scsi_remove_host(instance->host); megasas_flush_cache(instance); megasas_shutdown_controller(instance); tasklet_kill(&instance->isr_tasklet); /* * Take the instance off the instance array. Note that we will not * decrement the max_index. We let this array be sparse array */ for (i = 0; i < megasas_mgmt_info.max_index; i++) { if (megasas_mgmt_info.instance[i] == instance) { megasas_mgmt_info.count--; megasas_mgmt_info.instance[i] = NULL; break; } } pci_set_drvdata(instance->pdev, NULL); instance->instancet->disable_intr(instance->reg_set); free_irq(instance->pdev->irq, instance); megasas_release_mfi(instance); pci_free_consistent(pdev, sizeof(struct megasas_evt_detail), instance->evt_detail, instance->evt_detail_h); pci_free_consistent(pdev, sizeof(u32), instance->producer, instance->producer_h); pci_free_consistent(pdev, sizeof(u32), instance->consumer, instance->consumer_h); scsi_host_put(host); pci_set_drvdata(pdev, NULL); pci_disable_device(pdev); return; } /** * megasas_shutdown - Shutdown entry point * @device: Generic device structure */ static void megasas_shutdown(struct device *device) { struct megasas_instance *instance = (struct megasas_instance *) dev_get_drvdata(device); megasas_flush_cache(instance); } /** * megasas_mgmt_open - char node "open" entry point */ static int megasas_mgmt_open(struct inode *inode, struct file *filep) { /* * Allow only those users with admin rights */ if (!capable(CAP_SYS_ADMIN)) return -EACCES; return 0; } /** * megasas_mgmt_release - char node "release" entry point */ static int megasas_mgmt_release(struct inode *inode, struct file *filep) { filep->private_data = NULL; fasync_helper(-1, filep, 0, &megasas_async_queue); return 0; } /** * megasas_mgmt_fasync - Async notifier registration from applications * * This function adds the calling process to a driver global queue. When an * event occurs, SIGIO will be sent to all processes in this queue. */ static int megasas_mgmt_fasync(int fd, struct file *filep, int mode) { int rc; down(&megasas_async_queue_mutex); rc = fasync_helper(fd, filep, mode, &megasas_async_queue); up(&megasas_async_queue_mutex); if (rc >= 0) { /* For sanity check when we get ioctl */ filep->private_data = filep; return 0; } printk(KERN_DEBUG "megasas: fasync_helper failed [%d]\n", rc); return rc; } /** * megasas_mgmt_fw_ioctl - Issues management ioctls to FW * @instance: Adapter soft state * @argp: User's ioctl packet */ static int megasas_mgmt_fw_ioctl(struct megasas_instance *instance, struct megasas_iocpacket __user * user_ioc, struct megasas_iocpacket *ioc) { struct megasas_sge32 *kern_sge32; struct megasas_cmd *cmd; void *kbuff_arr[MAX_IOCTL_SGE]; dma_addr_t buf_handle = 0; int error = 0, i; void *sense = NULL; dma_addr_t sense_handle; u32 *sense_ptr; memset(kbuff_arr, 0, sizeof(kbuff_arr)); if (ioc->sge_count > MAX_IOCTL_SGE) { printk(KERN_DEBUG "megasas: SGE count [%d] > max limit [%d]\n", ioc->sge_count, MAX_IOCTL_SGE); return -EINVAL; } cmd = megasas_get_cmd(instance); if (!cmd) { printk(KERN_DEBUG "megasas: Failed to get a cmd packet\n"); return -ENOMEM; } /* * User's IOCTL packet has 2 frames (maximum). Copy those two * frames into our cmd's frames. cmd->frame's context will get * overwritten when we copy from user's frames. So set that value * alone separately */ memcpy(cmd->frame, ioc->frame.raw, 2 * MEGAMFI_FRAME_SIZE); cmd->frame->hdr.context = cmd->index; /* * The management interface between applications and the fw uses * MFI frames. E.g, RAID configuration changes, LD property changes * etc are accomplishes through different kinds of MFI frames. The * driver needs to care only about substituting user buffers with * kernel buffers in SGLs. The location of SGL is embedded in the * struct iocpacket itself. */ kern_sge32 = (struct megasas_sge32 *) ((unsigned long)cmd->frame + ioc->sgl_off); /* * For each user buffer, create a mirror buffer and copy in */ for (i = 0; i < ioc->sge_count; i++) { kbuff_arr[i] = pci_alloc_consistent(instance->pdev, ioc->sgl[i].iov_len, &buf_handle); if (!kbuff_arr[i]) { printk(KERN_DEBUG "megasas: Failed to alloc " "kernel SGL buffer for IOCTL \n"); error = -ENOMEM; goto out; } /* * We don't change the dma_coherent_mask, so * pci_alloc_consistent only returns 32bit addresses */ kern_sge32[i].phys_addr = (u32) buf_handle; kern_sge32[i].length = ioc->sgl[i].iov_len; /* * We created a kernel buffer corresponding to the * user buffer. Now copy in from the user buffer */ if (copy_from_user(kbuff_arr[i], ioc->sgl[i].iov_base, (u32) (ioc->sgl[i].iov_len))) { error = -EFAULT; goto out; } } if (ioc->sense_len) { sense = pci_alloc_consistent(instance->pdev, ioc->sense_len, &sense_handle); if (!sense) { error = -ENOMEM; goto out; } sense_ptr = (u32 *) ((unsigned long)cmd->frame + ioc->sense_off); *sense_ptr = sense_handle; } /* * Set the sync_cmd flag so that the ISR knows not to complete this * cmd to the SCSI mid-layer */ cmd->sync_cmd = 1; megasas_issue_blocked_cmd(instance, cmd); cmd->sync_cmd = 0; /* * copy out the kernel buffers to user buffers */ for (i = 0; i < ioc->sge_count; i++) { if (copy_to_user(ioc->sgl[i].iov_base, kbuff_arr[i], ioc->sgl[i].iov_len)) { error = -EFAULT; goto out; } } /* * copy out the sense */ if (ioc->sense_len) { /* * sense_ptr points to the location that has the user * sense buffer address */ sense_ptr = (u32 *) ((unsigned long)ioc->frame.raw + ioc->sense_off); if (copy_to_user((void __user *)((unsigned long)(*sense_ptr)), sense, ioc->sense_len)) { error = -EFAULT; goto out; } } /* * copy the status codes returned by the fw */ if (copy_to_user(&user_ioc->frame.hdr.cmd_status, &cmd->frame->hdr.cmd_status, sizeof(u8))) { printk(KERN_DEBUG "megasas: Error copying out cmd_status\n"); error = -EFAULT; } out: if (sense) { pci_free_consistent(instance->pdev, ioc->sense_len, sense, sense_handle); } for (i = 0; i < ioc->sge_count && kbuff_arr[i]; i++) { pci_free_consistent(instance->pdev, kern_sge32[i].length, kbuff_arr[i], kern_sge32[i].phys_addr); } megasas_return_cmd(instance, cmd); return error; } static struct megasas_instance *megasas_lookup_instance(u16 host_no) { int i; for (i = 0; i < megasas_mgmt_info.max_index; i++) { if ((megasas_mgmt_info.instance[i]) && (megasas_mgmt_info.instance[i]->host->host_no == host_no)) return megasas_mgmt_info.instance[i]; } return NULL; } static int megasas_mgmt_ioctl_fw(struct file *file, unsigned long arg) { struct megasas_iocpacket __user *user_ioc = (struct megasas_iocpacket __user *)arg; struct megasas_iocpacket *ioc; struct megasas_instance *instance; int error; ioc = kmalloc(sizeof(*ioc), GFP_KERNEL); if (!ioc) return -ENOMEM; if (copy_from_user(ioc, user_ioc, sizeof(*ioc))) { error = -EFAULT; goto out_kfree_ioc; } instance = megasas_lookup_instance(ioc->host_no); if (!instance) { error = -ENODEV; goto out_kfree_ioc; } /* * We will allow only MEGASAS_INT_CMDS number of parallel ioctl cmds */ if (down_interruptible(&instance->ioctl_sem)) { error = -ERESTARTSYS; goto out_kfree_ioc; } error = megasas_mgmt_fw_ioctl(instance, user_ioc, ioc); up(&instance->ioctl_sem); out_kfree_ioc: kfree(ioc); return error; } static int megasas_mgmt_ioctl_aen(struct file *file, unsigned long arg) { struct megasas_instance *instance; struct megasas_aen aen; int error; if (file->private_data != file) { printk(KERN_DEBUG "megasas: fasync_helper was not " "called first\n"); return -EINVAL; } if (copy_from_user(&aen, (void __user *)arg, sizeof(aen))) return -EFAULT; instance = megasas_lookup_instance(aen.host_no); if (!instance) return -ENODEV; down(&instance->aen_mutex); error = megasas_register_aen(instance, aen.seq_num, aen.class_locale_word); up(&instance->aen_mutex); return error; } /** * megasas_mgmt_ioctl - char node ioctl entry point */ static int megasas_mgmt_ioctl(struct inode *inode, struct file *file, unsigned int cmd, unsigned long arg) { switch (cmd) { case MEGASAS_IOC_FIRMWARE: return megasas_mgmt_ioctl_fw(file, arg); case MEGASAS_IOC_GET_AEN: return megasas_mgmt_ioctl_aen(file, arg); } return -ENOTTY; } #ifdef CONFIG_COMPAT static int megasas_mgmt_compat_ioctl_fw(struct file *file, unsigned long arg) { struct compat_megasas_iocpacket __user *cioc = (struct compat_megasas_iocpacket __user *)arg; struct megasas_iocpacket __user *ioc = compat_alloc_user_space(sizeof(struct megasas_iocpacket)); int i; int error = 0; if (clear_user(ioc, sizeof(*ioc))) return -EFAULT; if (copy_in_user(&ioc->host_no, &cioc->host_no, sizeof(u16)) || copy_in_user(&ioc->sgl_off, &cioc->sgl_off, sizeof(u32)) || copy_in_user(&ioc->sense_off, &cioc->sense_off, sizeof(u32)) || copy_in_user(&ioc->sense_len, &cioc->sense_len, sizeof(u32)) || copy_in_user(ioc->frame.raw, cioc->frame.raw, 128) || copy_in_user(&ioc->sge_count, &cioc->sge_count, sizeof(u32))) return -EFAULT; for (i = 0; i < MAX_IOCTL_SGE; i++) { compat_uptr_t ptr; if (get_user(ptr, &cioc->sgl[i].iov_base) || put_user(compat_ptr(ptr), &ioc->sgl[i].iov_base) || copy_in_user(&ioc->sgl[i].iov_len, &cioc->sgl[i].iov_len, sizeof(compat_size_t))) return -EFAULT; } error = megasas_mgmt_ioctl_fw(file, (unsigned long)ioc); if (copy_in_user(&cioc->frame.hdr.cmd_status, &ioc->frame.hdr.cmd_status, sizeof(u8))) { printk(KERN_DEBUG "megasas: error copy_in_user cmd_status\n"); return -EFAULT; } return error; } static long megasas_mgmt_compat_ioctl(unsigned int fd, unsigned int cmd, unsigned long arg, struct file *file) { switch (cmd) { case MEGASAS_IOC_FIRMWARE32: return megasas_mgmt_compat_ioctl_fw(file, arg); case MEGASAS_IOC_GET_AEN: return megasas_mgmt_ioctl_aen(file, arg); } return -ENOTTY; } #endif /* * File operations structure for management interface */ static struct file_operations megasas_mgmt_fops = { .owner = THIS_MODULE, .open = megasas_mgmt_open, .release = megasas_mgmt_release, .fasync = megasas_mgmt_fasync, .ioctl = megasas_mgmt_ioctl, }; /* * PCI hotplug support registration structure */ static struct pci_driver megasas_pci_driver = { .name = "megaraid_sas", .id_table = megasas_pci_table, .probe = megasas_probe_one, .remove = __devexit_p(megasas_detach_one), .driver = { .shutdown = megasas_shutdown, } }; /* * Sysfs driver attributes */ static ssize_t megasas_sysfs_show_version(struct device_driver *dd, char *buf) { return snprintf(buf, strlen(MEGASAS_VERSION) + 2, "%s\n", MEGASAS_VERSION); } static DRIVER_ATTR(version, S_IRUGO, megasas_sysfs_show_version, NULL); static ssize_t megasas_sysfs_show_release_date(struct device_driver *dd, char *buf) { return snprintf(buf, strlen(MEGASAS_RELDATE) + 2, "%s\n", MEGASAS_RELDATE); } static DRIVER_ATTR(release_date, S_IRUGO, megasas_sysfs_show_release_date, NULL); static ssize_t megasas_sysfs_show_dbg_lvl(struct device_driver *dd, char *buf) { return sprintf(buf,"%u",megasas_dbg_lvl); } static ssize_t megasas_sysfs_set_dbg_lvl(struct device_driver *dd, const char *buf, size_t count) { int retval = count; if(sscanf(buf,"%u",&megasas_dbg_lvl)<1){ printk(KERN_ERR "megasas: could not set dbg_lvl\n"); retval = -EINVAL; } return retval; } static DRIVER_ATTR(dbg_lvl, S_IRUGO|S_IWUGO, megasas_sysfs_show_dbg_lvl, megasas_sysfs_set_dbg_lvl); /** * megasas_init - Driver load entry point */ static int __init megasas_init(void) { int rval; /* * Announce driver version and other information */ printk(KERN_INFO "megasas: %s %s\n", MEGASAS_VERSION, MEGASAS_EXT_VERSION); memset(&megasas_mgmt_info, 0, sizeof(megasas_mgmt_info)); /* * Register character device node */ rval = register_chrdev(0, "megaraid_sas_ioctl", &megasas_mgmt_fops); if (rval < 0) { printk(KERN_DEBUG "megasas: failed to open device node\n"); return rval; } megasas_mgmt_majorno = rval; /* * Register ourselves as PCI hotplug module */ rval = pci_module_init(&megasas_pci_driver); if (rval) { printk(KERN_DEBUG "megasas: PCI hotplug regisration failed \n"); goto err_pcidrv; } rval = driver_create_file(&megasas_pci_driver.driver, &driver_attr_version); if (rval) goto err_dcf_attr_ver; rval = driver_create_file(&megasas_pci_driver.driver, &driver_attr_release_date); if (rval) goto err_dcf_rel_date; rval = driver_create_file(&megasas_pci_driver.driver, &driver_attr_dbg_lvl); if (rval) goto err_dcf_dbg_lvl; #ifdef CONFIG_COMPAT register_ioctl32_conversion(MEGASAS_IOC_FIRMWARE32, megasas_mgmt_compat_ioctl); register_ioctl32_conversion(MEGASAS_IOC_GET_AEN, megasas_mgmt_compat_ioctl); #endif return rval; err_dcf_dbg_lvl: driver_remove_file(&megasas_pci_driver.driver, &driver_attr_release_date); err_dcf_rel_date: driver_remove_file(&megasas_pci_driver.driver, &driver_attr_version); err_dcf_attr_ver: pci_unregister_driver(&megasas_pci_driver); err_pcidrv: unregister_chrdev(megasas_mgmt_majorno, "megaraid_sas_ioctl"); return rval; } /** * megasas_exit - Driver unload entry point */ static void __exit megasas_exit(void) { #ifdef CONFIG_COMPAT unregister_ioctl32_conversion(MEGASAS_IOC_FIRMWARE32); unregister_ioctl32_conversion(MEGASAS_IOC_GET_AEN); #endif driver_remove_file(&megasas_pci_driver.driver, &driver_attr_version); driver_remove_file(&megasas_pci_driver.driver, &driver_attr_release_date); pci_unregister_driver(&megasas_pci_driver); unregister_chrdev(megasas_mgmt_majorno, "megaraid_sas_ioctl"); } module_init(megasas_init); module_exit(megasas_exit); megactl-0.4.5/kernel-2.6.9-55.0.2.EL/megaraid-2.20.4.6-rh2/megaraid_sas.h000066400000000000000000000605671465722425200240600ustar00rootroot00000000000000/* * * Linux MegaRAID driver for SAS based RAID controllers * * Copyright (c) 2003-2005 LSI Logic Corporation. * * 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. * * FILE : megaraid_sas.h */ #ifndef LSI_MEGARAID_SAS_H #define LSI_MEGARAID_SAS_H /** * MegaRAID SAS Driver meta data */ #define MEGASAS_VERSION "00.00.03.05" #define MEGASAS_RELDATE "Oct 02, 2006" #define MEGASAS_EXT_VERSION "Mon Oct 02 11:21:32 PDT 2006" /* * Device IDs */ #define PCI_DEVICE_ID_LSI_SAS1078R 0x0060 #define PCI_DEVICE_ID_LSI_VERDE_ZCR 0x0413 /* * Device IDs */ #define PCI_DEVICE_ID_LSI_VERDE_ZCR 0x0413 /* * ===================================== * MegaRAID SAS MFI firmware definitions * ===================================== */ /* * MFI stands for MegaRAID SAS FW Interface. This is just a moniker for * protocol between the software and firmware. Commands are issued using * "message frames" */ /** * FW posts its state in upper 4 bits of outbound_msg_0 register */ #define MFI_STATE_MASK 0xF0000000 #define MFI_STATE_UNDEFINED 0x00000000 #define MFI_STATE_BB_INIT 0x10000000 #define MFI_STATE_FW_INIT 0x40000000 #define MFI_STATE_WAIT_HANDSHAKE 0x60000000 #define MFI_STATE_FW_INIT_2 0x70000000 #define MFI_STATE_DEVICE_SCAN 0x80000000 #define MFI_STATE_BOOT_MESSAGE_PENDING 0x90000000 #define MFI_STATE_FLUSH_CACHE 0xA0000000 #define MFI_STATE_READY 0xB0000000 #define MFI_STATE_OPERATIONAL 0xC0000000 #define MFI_STATE_FAULT 0xF0000000 #define MEGAMFI_FRAME_SIZE 64 /** * During FW init, clear pending cmds & reset state using inbound_msg_0 * * ABORT : Abort all pending cmds * READY : Move from OPERATIONAL to READY state; discard queue info * MFIMODE : Discard (possible) low MFA posted in 64-bit mode (??) * CLR_HANDSHAKE: FW is waiting for HANDSHAKE from BIOS or Driver * HOTPLUG : Resume from Hotplug * MFI_STOP_ADP : Send signal to FW to stop processing */ #define MFI_INIT_ABORT 0x00000001 #define MFI_INIT_READY 0x00000002 #define MFI_INIT_MFIMODE 0x00000004 #define MFI_INIT_CLEAR_HANDSHAKE 0x00000008 #define MFI_INIT_HOTPLUG 0x00000010 #define MFI_STOP_ADP 0x00000020 #define MFI_RESET_FLAGS MFI_INIT_READY| \ MFI_INIT_MFIMODE| \ MFI_INIT_ABORT /** * MFI frame flags */ #define MFI_FRAME_POST_IN_REPLY_QUEUE 0x0000 #define MFI_FRAME_DONT_POST_IN_REPLY_QUEUE 0x0001 #define MFI_FRAME_SGL32 0x0000 #define MFI_FRAME_SGL64 0x0002 #define MFI_FRAME_SENSE32 0x0000 #define MFI_FRAME_SENSE64 0x0004 #define MFI_FRAME_DIR_NONE 0x0000 #define MFI_FRAME_DIR_WRITE 0x0008 #define MFI_FRAME_DIR_READ 0x0010 #define MFI_FRAME_DIR_BOTH 0x0018 /** * Definition for cmd_status */ #define MFI_CMD_STATUS_POLL_MODE 0xFF /** * MFI command opcodes */ #define MFI_CMD_INIT 0x00 #define MFI_CMD_LD_READ 0x01 #define MFI_CMD_LD_WRITE 0x02 #define MFI_CMD_LD_SCSI_IO 0x03 #define MFI_CMD_PD_SCSI_IO 0x04 #define MFI_CMD_DCMD 0x05 #define MFI_CMD_ABORT 0x06 #define MFI_CMD_SMP 0x07 #define MFI_CMD_STP 0x08 #define MR_DCMD_CTRL_GET_INFO 0x01010000 #define MR_DCMD_CTRL_CACHE_FLUSH 0x01101000 #define MR_FLUSH_CTRL_CACHE 0x01 #define MR_FLUSH_DISK_CACHE 0x02 #define MR_DCMD_CTRL_SHUTDOWN 0x01050000 #define MR_ENABLE_DRIVE_SPINDOWN 0x01 #define MR_DCMD_CTRL_EVENT_GET_INFO 0x01040100 #define MR_DCMD_CTRL_EVENT_GET 0x01040300 #define MR_DCMD_CTRL_EVENT_WAIT 0x01040500 #define MR_DCMD_LD_GET_PROPERTIES 0x03030000 #define MR_DCMD_CLUSTER 0x08000000 #define MR_DCMD_CLUSTER_RESET_ALL 0x08010100 #define MR_DCMD_CLUSTER_RESET_LD 0x08010200 /** * MFI command completion codes */ enum MFI_STAT { MFI_STAT_OK = 0x00, MFI_STAT_INVALID_CMD = 0x01, MFI_STAT_INVALID_DCMD = 0x02, MFI_STAT_INVALID_PARAMETER = 0x03, MFI_STAT_INVALID_SEQUENCE_NUMBER = 0x04, MFI_STAT_ABORT_NOT_POSSIBLE = 0x05, MFI_STAT_APP_HOST_CODE_NOT_FOUND = 0x06, MFI_STAT_APP_IN_USE = 0x07, MFI_STAT_APP_NOT_INITIALIZED = 0x08, MFI_STAT_ARRAY_INDEX_INVALID = 0x09, MFI_STAT_ARRAY_ROW_NOT_EMPTY = 0x0a, MFI_STAT_CONFIG_RESOURCE_CONFLICT = 0x0b, MFI_STAT_DEVICE_NOT_FOUND = 0x0c, MFI_STAT_DRIVE_TOO_SMALL = 0x0d, MFI_STAT_FLASH_ALLOC_FAIL = 0x0e, MFI_STAT_FLASH_BUSY = 0x0f, MFI_STAT_FLASH_ERROR = 0x10, MFI_STAT_FLASH_IMAGE_BAD = 0x11, MFI_STAT_FLASH_IMAGE_INCOMPLETE = 0x12, MFI_STAT_FLASH_NOT_OPEN = 0x13, MFI_STAT_FLASH_NOT_STARTED = 0x14, MFI_STAT_FLUSH_FAILED = 0x15, MFI_STAT_HOST_CODE_NOT_FOUNT = 0x16, MFI_STAT_LD_CC_IN_PROGRESS = 0x17, MFI_STAT_LD_INIT_IN_PROGRESS = 0x18, MFI_STAT_LD_LBA_OUT_OF_RANGE = 0x19, MFI_STAT_LD_MAX_CONFIGURED = 0x1a, MFI_STAT_LD_NOT_OPTIMAL = 0x1b, MFI_STAT_LD_RBLD_IN_PROGRESS = 0x1c, MFI_STAT_LD_RECON_IN_PROGRESS = 0x1d, MFI_STAT_LD_WRONG_RAID_LEVEL = 0x1e, MFI_STAT_MAX_SPARES_EXCEEDED = 0x1f, MFI_STAT_MEMORY_NOT_AVAILABLE = 0x20, MFI_STAT_MFC_HW_ERROR = 0x21, MFI_STAT_NO_HW_PRESENT = 0x22, MFI_STAT_NOT_FOUND = 0x23, MFI_STAT_NOT_IN_ENCL = 0x24, MFI_STAT_PD_CLEAR_IN_PROGRESS = 0x25, MFI_STAT_PD_TYPE_WRONG = 0x26, MFI_STAT_PR_DISABLED = 0x27, MFI_STAT_ROW_INDEX_INVALID = 0x28, MFI_STAT_SAS_CONFIG_INVALID_ACTION = 0x29, MFI_STAT_SAS_CONFIG_INVALID_DATA = 0x2a, MFI_STAT_SAS_CONFIG_INVALID_PAGE = 0x2b, MFI_STAT_SAS_CONFIG_INVALID_TYPE = 0x2c, MFI_STAT_SCSI_DONE_WITH_ERROR = 0x2d, MFI_STAT_SCSI_IO_FAILED = 0x2e, MFI_STAT_SCSI_RESERVATION_CONFLICT = 0x2f, MFI_STAT_SHUTDOWN_FAILED = 0x30, MFI_STAT_TIME_NOT_SET = 0x31, MFI_STAT_WRONG_STATE = 0x32, MFI_STAT_LD_OFFLINE = 0x33, MFI_STAT_PEER_NOTIFICATION_REJECTED = 0x34, MFI_STAT_PEER_NOTIFICATION_FAILED = 0x35, MFI_STAT_RESERVATION_IN_PROGRESS = 0x36, MFI_STAT_I2C_ERRORS_DETECTED = 0x37, MFI_STAT_PCI_ERRORS_DETECTED = 0x38, MFI_STAT_INVALID_STATUS = 0xFF }; /* * Number of mailbox bytes in DCMD message frame */ #define MFI_MBOX_SIZE 12 enum MR_EVT_CLASS { MR_EVT_CLASS_DEBUG = -2, MR_EVT_CLASS_PROGRESS = -1, MR_EVT_CLASS_INFO = 0, MR_EVT_CLASS_WARNING = 1, MR_EVT_CLASS_CRITICAL = 2, MR_EVT_CLASS_FATAL = 3, MR_EVT_CLASS_DEAD = 4, }; enum MR_EVT_LOCALE { MR_EVT_LOCALE_LD = 0x0001, MR_EVT_LOCALE_PD = 0x0002, MR_EVT_LOCALE_ENCL = 0x0004, MR_EVT_LOCALE_BBU = 0x0008, MR_EVT_LOCALE_SAS = 0x0010, MR_EVT_LOCALE_CTRL = 0x0020, MR_EVT_LOCALE_CONFIG = 0x0040, MR_EVT_LOCALE_CLUSTER = 0x0080, MR_EVT_LOCALE_ALL = 0xffff, }; enum MR_EVT_ARGS { MR_EVT_ARGS_NONE, MR_EVT_ARGS_CDB_SENSE, MR_EVT_ARGS_LD, MR_EVT_ARGS_LD_COUNT, MR_EVT_ARGS_LD_LBA, MR_EVT_ARGS_LD_OWNER, MR_EVT_ARGS_LD_LBA_PD_LBA, MR_EVT_ARGS_LD_PROG, MR_EVT_ARGS_LD_STATE, MR_EVT_ARGS_LD_STRIP, MR_EVT_ARGS_PD, MR_EVT_ARGS_PD_ERR, MR_EVT_ARGS_PD_LBA, MR_EVT_ARGS_PD_LBA_LD, MR_EVT_ARGS_PD_PROG, MR_EVT_ARGS_PD_STATE, MR_EVT_ARGS_PCI, MR_EVT_ARGS_RATE, MR_EVT_ARGS_STR, MR_EVT_ARGS_TIME, MR_EVT_ARGS_ECC, }; /* * SAS controller properties */ struct megasas_ctrl_prop { u16 seq_num; u16 pred_fail_poll_interval; u16 intr_throttle_count; u16 intr_throttle_timeouts; u8 rebuild_rate; u8 patrol_read_rate; u8 bgi_rate; u8 cc_rate; u8 recon_rate; u8 cache_flush_interval; u8 spinup_drv_count; u8 spinup_delay; u8 cluster_enable; u8 coercion_mode; u8 alarm_enable; u8 disable_auto_rebuild; u8 disable_battery_warn; u8 ecc_bucket_size; u16 ecc_bucket_leak_rate; u8 restore_hotspare_on_insertion; u8 expose_encl_devices; u8 reserved[38]; } __attribute__ ((packed)); /* * SAS controller information */ struct megasas_ctrl_info { /* * PCI device information */ struct { u16 vendor_id; u16 device_id; u16 sub_vendor_id; u16 sub_device_id; u8 reserved[24]; } __attribute__ ((packed)) pci; /* * Host interface information */ struct { u8 PCIX:1; u8 PCIE:1; u8 iSCSI:1; u8 SAS_3G:1; u8 reserved_0:4; u8 reserved_1[6]; u8 port_count; u64 port_addr[8]; } __attribute__ ((packed)) host_interface; /* * Device (backend) interface information */ struct { u8 SPI:1; u8 SAS_3G:1; u8 SATA_1_5G:1; u8 SATA_3G:1; u8 reserved_0:4; u8 reserved_1[6]; u8 port_count; u64 port_addr[8]; } __attribute__ ((packed)) device_interface; /* * List of components residing in flash. All str are null terminated */ u32 image_check_word; u32 image_component_count; struct { char name[8]; char version[32]; char build_date[16]; char built_time[16]; } __attribute__ ((packed)) image_component[8]; /* * List of flash components that have been flashed on the card, but * are not in use, pending reset of the adapter. This list will be * empty if a flash operation has not occurred. All stings are null * terminated */ u32 pending_image_component_count; struct { char name[8]; char version[32]; char build_date[16]; char build_time[16]; } __attribute__ ((packed)) pending_image_component[8]; u8 max_arms; u8 max_spans; u8 max_arrays; u8 max_lds; char product_name[80]; char serial_no[32]; /* * Other physical/controller/operation information. Indicates the * presence of the hardware */ struct { u32 bbu:1; u32 alarm:1; u32 nvram:1; u32 uart:1; u32 reserved:28; } __attribute__ ((packed)) hw_present; u32 current_fw_time; /* * Maximum data transfer sizes */ u16 max_concurrent_cmds; u16 max_sge_count; u32 max_request_size; /* * Logical and physical device counts */ u16 ld_present_count; u16 ld_degraded_count; u16 ld_offline_count; u16 pd_present_count; u16 pd_disk_present_count; u16 pd_disk_pred_failure_count; u16 pd_disk_failed_count; /* * Memory size information */ u16 nvram_size; u16 memory_size; u16 flash_size; /* * Error counters */ u16 mem_correctable_error_count; u16 mem_uncorrectable_error_count; /* * Cluster information */ u8 cluster_permitted; u8 cluster_active; /* * Additional max data transfer sizes */ u16 max_strips_per_io; /* * Controller capabilities structures */ struct { u32 raid_level_0:1; u32 raid_level_1:1; u32 raid_level_5:1; u32 raid_level_1E:1; u32 raid_level_6:1; u32 reserved:27; } __attribute__ ((packed)) raid_levels; struct { u32 rbld_rate:1; u32 cc_rate:1; u32 bgi_rate:1; u32 recon_rate:1; u32 patrol_rate:1; u32 alarm_control:1; u32 cluster_supported:1; u32 bbu:1; u32 spanning_allowed:1; u32 dedicated_hotspares:1; u32 revertible_hotspares:1; u32 foreign_config_import:1; u32 self_diagnostic:1; u32 mixed_redundancy_arr:1; u32 global_hot_spares:1; u32 reserved:17; } __attribute__ ((packed)) adapter_operations; struct { u32 read_policy:1; u32 write_policy:1; u32 io_policy:1; u32 access_policy:1; u32 disk_cache_policy:1; u32 reserved:27; } __attribute__ ((packed)) ld_operations; struct { u8 min; u8 max; u8 reserved[2]; } __attribute__ ((packed)) stripe_sz_ops; struct { u32 force_online:1; u32 force_offline:1; u32 force_rebuild:1; u32 reserved:29; } __attribute__ ((packed)) pd_operations; struct { u32 ctrl_supports_sas:1; u32 ctrl_supports_sata:1; u32 allow_mix_in_encl:1; u32 allow_mix_in_ld:1; u32 allow_sata_in_cluster:1; u32 reserved:27; } __attribute__ ((packed)) pd_mix_support; /* * Define ECC single-bit-error bucket information */ u8 ecc_bucket_count; u8 reserved_2[11]; /* * Include the controller properties (changeable items) */ struct megasas_ctrl_prop properties; /* * Define FW pkg version (set in envt v'bles on OEM basis) */ char package_version[0x60]; u8 pad[0x800 - 0x6a0]; } __attribute__ ((packed)); /* * =============================== * MegaRAID SAS driver definitions * =============================== */ #define MEGASAS_MAX_PD_CHANNELS 2 #define MEGASAS_MAX_LD_CHANNELS 2 #define MEGASAS_MAX_CHANNELS (MEGASAS_MAX_PD_CHANNELS + \ MEGASAS_MAX_LD_CHANNELS) #define MEGASAS_MAX_DEV_PER_CHANNEL 128 #define MEGASAS_DEFAULT_INIT_ID -1 #define MEGASAS_MAX_LUN 8 #define MEGASAS_MAX_LD 64 #define MEGASAS_DBG_LVL 1 /* * When SCSI mid-layer calls driver's reset routine, driver waits for * MEGASAS_RESET_WAIT_TIME seconds for all outstanding IO to complete. Note * that the driver cannot _actually_ abort or reset pending commands. While * it is waiting for the commands to complete, it prints a diagnostic message * every MEGASAS_RESET_NOTICE_INTERVAL seconds */ #define MEGASAS_RESET_WAIT_TIME 180 #define MEGASAS_INTERNAL_CMD_WAIT_TIME 180 #define MEGASAS_RESET_NOTICE_INTERVAL 5 #define MEGASAS_IOCTL_CMD 0 /* * FW reports the maximum of number of commands that it can accept (maximum * commands that can be outstanding) at any time. The driver must report a * lower number to the mid layer because it can issue a few internal commands * itself (E.g, AEN, abort cmd, IOCTLs etc). The number of commands it needs * is shown below */ #define MEGASAS_INT_CMDS 32 /* * FW can accept both 32 and 64 bit SGLs. We want to allocate 32/64 bit * SGLs based on the size of dma_addr_t */ #define IS_DMA64 (sizeof(dma_addr_t) == 8) #define MFI_OB_INTR_STATUS_MASK 0x00000002 #define MFI_POLL_TIMEOUT_SECS 10 #define MFI_REPLY_1078_MESSAGE_INTERRUPT 0x80000000 /* * register set for both 1068 and 1078 controllers * structure extended for 1078 registers */ struct megasas_register_set { u32 reserved_0[4]; /*0000h*/ u32 inbound_msg_0; /*0010h*/ u32 inbound_msg_1; /*0014h*/ u32 outbound_msg_0; /*0018h*/ u32 outbound_msg_1; /*001Ch*/ u32 inbound_doorbell; /*0020h*/ u32 inbound_intr_status; /*0024h*/ u32 inbound_intr_mask; /*0028h*/ u32 outbound_doorbell; /*002Ch*/ u32 outbound_intr_status; /*0030h*/ u32 outbound_intr_mask; /*0034h*/ u32 reserved_1[2]; /*0038h*/ u32 inbound_queue_port; /*0040h*/ u32 outbound_queue_port; /*0044h*/ u32 reserved_2[22]; /*0048h*/ u32 outbound_doorbell_clear; /*00A0h*/ u32 reserved_3[3]; /*00A4h*/ u32 outbound_scratch_pad ; /*00B0h*/ u32 reserved_4[3]; /*00B4h*/ u32 inbound_low_queue_port ; /*00C0h*/ u32 inbound_high_queue_port ; /*00C4h*/ u32 reserved_5; /*00C8h*/ u32 index_registers[820]; /*00CCh*/ } __attribute__ ((packed)); struct megasas_sge32 { u32 phys_addr; u32 length; } __attribute__ ((packed)); struct megasas_sge64 { u64 phys_addr; u32 length; } __attribute__ ((packed)); union megasas_sgl { struct megasas_sge32 sge32[1]; struct megasas_sge64 sge64[1]; } __attribute__ ((packed)); struct megasas_header { u8 cmd; /*00h */ u8 sense_len; /*01h */ u8 cmd_status; /*02h */ u8 scsi_status; /*03h */ u8 target_id; /*04h */ u8 lun; /*05h */ u8 cdb_len; /*06h */ u8 sge_count; /*07h */ u32 context; /*08h */ u32 pad_0; /*0Ch */ u16 flags; /*10h */ u16 timeout; /*12h */ u32 data_xferlen; /*14h */ } __attribute__ ((packed)); union megasas_sgl_frame { struct megasas_sge32 sge32[8]; struct megasas_sge64 sge64[5]; } __attribute__ ((packed)); struct megasas_init_frame { u8 cmd; /*00h */ u8 reserved_0; /*01h */ u8 cmd_status; /*02h */ u8 reserved_1; /*03h */ u32 reserved_2; /*04h */ u32 context; /*08h */ u32 pad_0; /*0Ch */ u16 flags; /*10h */ u16 reserved_3; /*12h */ u32 data_xfer_len; /*14h */ u32 queue_info_new_phys_addr_lo; /*18h */ u32 queue_info_new_phys_addr_hi; /*1Ch */ u32 queue_info_old_phys_addr_lo; /*20h */ u32 queue_info_old_phys_addr_hi; /*24h */ u32 reserved_4[6]; /*28h */ } __attribute__ ((packed)); struct megasas_init_queue_info { u32 init_flags; /*00h */ u32 reply_queue_entries; /*04h */ u32 reply_queue_start_phys_addr_lo; /*08h */ u32 reply_queue_start_phys_addr_hi; /*0Ch */ u32 producer_index_phys_addr_lo; /*10h */ u32 producer_index_phys_addr_hi; /*14h */ u32 consumer_index_phys_addr_lo; /*18h */ u32 consumer_index_phys_addr_hi; /*1Ch */ } __attribute__ ((packed)); struct megasas_io_frame { u8 cmd; /*00h */ u8 sense_len; /*01h */ u8 cmd_status; /*02h */ u8 scsi_status; /*03h */ u8 target_id; /*04h */ u8 access_byte; /*05h */ u8 reserved_0; /*06h */ u8 sge_count; /*07h */ u32 context; /*08h */ u32 pad_0; /*0Ch */ u16 flags; /*10h */ u16 timeout; /*12h */ u32 lba_count; /*14h */ u32 sense_buf_phys_addr_lo; /*18h */ u32 sense_buf_phys_addr_hi; /*1Ch */ u32 start_lba_lo; /*20h */ u32 start_lba_hi; /*24h */ union megasas_sgl sgl; /*28h */ } __attribute__ ((packed)); struct megasas_pthru_frame { u8 cmd; /*00h */ u8 sense_len; /*01h */ u8 cmd_status; /*02h */ u8 scsi_status; /*03h */ u8 target_id; /*04h */ u8 lun; /*05h */ u8 cdb_len; /*06h */ u8 sge_count; /*07h */ u32 context; /*08h */ u32 pad_0; /*0Ch */ u16 flags; /*10h */ u16 timeout; /*12h */ u32 data_xfer_len; /*14h */ u32 sense_buf_phys_addr_lo; /*18h */ u32 sense_buf_phys_addr_hi; /*1Ch */ u8 cdb[16]; /*20h */ union megasas_sgl sgl; /*30h */ } __attribute__ ((packed)); struct megasas_dcmd_frame { u8 cmd; /*00h */ u8 reserved_0; /*01h */ u8 cmd_status; /*02h */ u8 reserved_1[4]; /*03h */ u8 sge_count; /*07h */ u32 context; /*08h */ u32 pad_0; /*0Ch */ u16 flags; /*10h */ u16 timeout; /*12h */ u32 data_xfer_len; /*14h */ u32 opcode; /*18h */ union { /*1Ch */ u8 b[12]; u16 s[6]; u32 w[3]; } mbox; union megasas_sgl sgl; /*28h */ } __attribute__ ((packed)); struct megasas_abort_frame { u8 cmd; /*00h */ u8 reserved_0; /*01h */ u8 cmd_status; /*02h */ u8 reserved_1; /*03h */ u32 reserved_2; /*04h */ u32 context; /*08h */ u32 pad_0; /*0Ch */ u16 flags; /*10h */ u16 reserved_3; /*12h */ u32 reserved_4; /*14h */ u32 abort_context; /*18h */ u32 pad_1; /*1Ch */ u32 abort_mfi_phys_addr_lo; /*20h */ u32 abort_mfi_phys_addr_hi; /*24h */ u32 reserved_5[6]; /*28h */ } __attribute__ ((packed)); struct megasas_smp_frame { u8 cmd; /*00h */ u8 reserved_1; /*01h */ u8 cmd_status; /*02h */ u8 connection_status; /*03h */ u8 reserved_2[3]; /*04h */ u8 sge_count; /*07h */ u32 context; /*08h */ u32 pad_0; /*0Ch */ u16 flags; /*10h */ u16 timeout; /*12h */ u32 data_xfer_len; /*14h */ u64 sas_addr; /*18h */ union { struct megasas_sge32 sge32[2]; /* [0]: resp [1]: req */ struct megasas_sge64 sge64[2]; /* [0]: resp [1]: req */ } sgl; } __attribute__ ((packed)); struct megasas_stp_frame { u8 cmd; /*00h */ u8 reserved_1; /*01h */ u8 cmd_status; /*02h */ u8 reserved_2; /*03h */ u8 target_id; /*04h */ u8 reserved_3[2]; /*05h */ u8 sge_count; /*07h */ u32 context; /*08h */ u32 pad_0; /*0Ch */ u16 flags; /*10h */ u16 timeout; /*12h */ u32 data_xfer_len; /*14h */ u16 fis[10]; /*18h */ u32 stp_flags; union { struct megasas_sge32 sge32[2]; /* [0]: resp [1]: data */ struct megasas_sge64 sge64[2]; /* [0]: resp [1]: data */ } sgl; } __attribute__ ((packed)); union megasas_frame { struct megasas_header hdr; struct megasas_init_frame init; struct megasas_io_frame io; struct megasas_pthru_frame pthru; struct megasas_dcmd_frame dcmd; struct megasas_abort_frame abort; struct megasas_smp_frame smp; struct megasas_stp_frame stp; u8 raw_bytes[64]; }; struct megasas_cmd; union megasas_evt_class_locale { struct { u16 locale; u8 reserved; s8 class; } __attribute__ ((packed)) members; u32 word; } __attribute__ ((packed)); struct megasas_evt_log_info { u32 newest_seq_num; u32 oldest_seq_num; u32 clear_seq_num; u32 shutdown_seq_num; u32 boot_seq_num; } __attribute__ ((packed)); struct megasas_progress { u16 progress; u16 elapsed_seconds; } __attribute__ ((packed)); struct megasas_evtarg_ld { u16 target_id; u8 ld_index; u8 reserved; } __attribute__ ((packed)); struct megasas_evtarg_pd { u16 device_id; u8 encl_index; u8 slot_number; } __attribute__ ((packed)); struct megasas_evt_detail { u32 seq_num; u32 time_stamp; u32 code; union megasas_evt_class_locale cl; u8 arg_type; u8 reserved1[15]; union { struct { struct megasas_evtarg_pd pd; u8 cdb_length; u8 sense_length; u8 reserved[2]; u8 cdb[16]; u8 sense[64]; } __attribute__ ((packed)) cdbSense; struct megasas_evtarg_ld ld; struct { struct megasas_evtarg_ld ld; u64 count; } __attribute__ ((packed)) ld_count; struct { u64 lba; struct megasas_evtarg_ld ld; } __attribute__ ((packed)) ld_lba; struct { struct megasas_evtarg_ld ld; u32 prevOwner; u32 newOwner; } __attribute__ ((packed)) ld_owner; struct { u64 ld_lba; u64 pd_lba; struct megasas_evtarg_ld ld; struct megasas_evtarg_pd pd; } __attribute__ ((packed)) ld_lba_pd_lba; struct { struct megasas_evtarg_ld ld; struct megasas_progress prog; } __attribute__ ((packed)) ld_prog; struct { struct megasas_evtarg_ld ld; u32 prev_state; u32 new_state; } __attribute__ ((packed)) ld_state; struct { u64 strip; struct megasas_evtarg_ld ld; } __attribute__ ((packed)) ld_strip; struct megasas_evtarg_pd pd; struct { struct megasas_evtarg_pd pd; u32 err; } __attribute__ ((packed)) pd_err; struct { u64 lba; struct megasas_evtarg_pd pd; } __attribute__ ((packed)) pd_lba; struct { u64 lba; struct megasas_evtarg_pd pd; struct megasas_evtarg_ld ld; } __attribute__ ((packed)) pd_lba_ld; struct { struct megasas_evtarg_pd pd; struct megasas_progress prog; } __attribute__ ((packed)) pd_prog; struct { struct megasas_evtarg_pd pd; u32 prevState; u32 newState; } __attribute__ ((packed)) pd_state; struct { u16 vendorId; u16 deviceId; u16 subVendorId; u16 subDeviceId; } __attribute__ ((packed)) pci; u32 rate; char str[96]; struct { u32 rtc; u32 elapsedSeconds; } __attribute__ ((packed)) time; struct { u32 ecar; u32 elog; char str[64]; } __attribute__ ((packed)) ecc; u8 b[96]; u16 s[48]; u32 w[24]; u64 d[12]; } args; char description[128]; } __attribute__ ((packed)); struct megasas_instance_template { void (*fire_cmd)(dma_addr_t ,u32 ,struct megasas_register_set __iomem *); void (*enable_intr)(struct megasas_register_set __iomem *) ; void (*disable_intr)(struct megasas_register_set __iomem *); int (*clear_intr)(struct megasas_register_set __iomem *); u32 (*read_fw_status_reg)(struct megasas_register_set __iomem *); }; struct megasas_instance { u32 *producer; dma_addr_t producer_h; u32 *consumer; dma_addr_t consumer_h; u32 *reply_queue; dma_addr_t reply_queue_h; unsigned long base_addr; struct megasas_register_set __iomem *reg_set; s8 init_id; u8 reserved[3]; u16 max_num_sge; u16 max_fw_cmds; u32 max_sectors_per_req; struct megasas_cmd **cmd_list; struct list_head cmd_pool; spinlock_t cmd_pool_lock; struct dma_pool *frame_dma_pool; struct dma_pool *sense_dma_pool; struct megasas_evt_detail *evt_detail; dma_addr_t evt_detail_h; struct megasas_cmd *aen_cmd; struct semaphore aen_mutex; struct semaphore ioctl_sem; struct Scsi_Host *host; wait_queue_head_t int_cmd_wait_q; wait_queue_head_t abort_cmd_wait_q; struct pci_dev *pdev; u32 unique_id; atomic_t fw_outstanding; u32 hw_crit_error; struct megasas_instance_template *instancet; struct tasklet_struct isr_tasklet; }; #define MEGASAS_IS_LOGICAL(scp) \ (scp->device->channel < MEGASAS_MAX_PD_CHANNELS) ? 0 : 1 #define MEGASAS_DEV_INDEX(inst, scp) \ ((scp->device->channel % 2) * MEGASAS_MAX_DEV_PER_CHANNEL) + \ scp->device->id struct megasas_cmd { union megasas_frame *frame; dma_addr_t frame_phys_addr; u8 *sense; dma_addr_t sense_phys_addr; u32 index; u8 sync_cmd; u8 cmd_status; u16 abort_aen; struct list_head list; struct scsi_cmnd *scmd; struct megasas_instance *instance; u32 frame_count; }; #define MAX_MGMT_ADAPTERS 1024 #define MAX_IOCTL_SGE 16 struct megasas_iocpacket { u16 host_no; u16 __pad1; u32 sgl_off; u32 sge_count; u32 sense_off; u32 sense_len; union { u8 raw[128]; struct megasas_header hdr; } frame; struct iovec sgl[MAX_IOCTL_SGE]; } __attribute__ ((packed)); struct megasas_aen { u16 host_no; u16 __pad1; u32 seq_num; u32 class_locale_word; } __attribute__ ((packed)); #ifdef CONFIG_COMPAT struct compat_megasas_iocpacket { u16 host_no; u16 __pad1; u32 sgl_off; u32 sge_count; u32 sense_off; u32 sense_len; union { u8 raw[128]; struct megasas_header hdr; } frame; struct compat_iovec sgl[MAX_IOCTL_SGE]; } __attribute__ ((packed)); #define MEGASAS_IOC_FIRMWARE32 _IOWR('M', 1, struct compat_megasas_iocpacket) #endif #define MEGASAS_IOC_FIRMWARE _IOWR('M', 1, struct megasas_iocpacket) #define MEGASAS_IOC_GET_AEN _IOW('M', 3, struct megasas_aen) struct megasas_mgmt_info { u16 count; struct megasas_instance *instance[MAX_MGMT_ADAPTERS]; int max_index; }; #endif /*LSI_MEGARAID_SAS_H */ megactl-0.4.5/logpage.c000066400000000000000000000306161465722425200147350ustar00rootroot00000000000000/* * Parse and print SCSI log sense pages. * * Copyright (c) 2007 by Jefferson Ogata */ /* * 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, 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; see the file COPYING. If not, write to the Free Software * Foundation, 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. */ #include "megaioctl.h" #include "logpage.h" #include "ntrim.h" #include "dumpbytes.h" #include #include #include static char *logPageType[] = { /* 0 */ "supported log pages", /* 1 */ "buffer over-run/under-run", /* 2 */ "write error counter", /* 3 */ "read error counter", /* 4 */ "read reverse error counter", /* 5 */ "verify error counter", /* 6 */ "non-medium error", /* 7 */ "last n error events", /* 8 */ "format status", /* 9 */ NULL, /* a */ NULL, /* b */ "last n deferred errors os asynchronous events", /* c */ "sequential-access device", /* d */ "temperature", /* e */ "start-stop cycle counter", /* f */ "application client", /* 10 */ "self-test results", /* 11 */ "DTD status", /* 12 */ "TapeAlert response", /* 13 */ "requested recover", /* 14 */ "device statistics", /* 15 */ NULL, /* 16 */ NULL, /* 17 */ "non-volatile cache", /* 18 */ "protocol specific port", /* 19 */ NULL, /* 1a */ NULL, /* 1b */ NULL, /* 1c */ NULL, /* 1d */ NULL, /* 1e */ NULL, /* 1f */ NULL, /* 20 */ NULL, /* 21 */ NULL, /* 22 */ NULL, /* 23 */ NULL, /* 24 */ NULL, /* 25 */ NULL, /* 26 */ NULL, /* 27 */ NULL, /* 28 */ NULL, /* 29 */ NULL, /* 2a */ NULL, /* 2b */ NULL, /* 2c */ NULL, /* 2d */ NULL, /* 2e */ "TapeAlert", /* 2f */ "informational exceptions", /* 30 */ "vendor specific", /* 31 */ "vendor specific", /* 32 */ "vendor specific", /* 33 */ "vendor specific", /* 34 */ "vendor specific", /* 35 */ "vendor specific", /* 36 */ "vendor specific", /* 37 */ "vendor specific", /* 38 */ "vendor specific", /* 39 */ "vendor specific", /* 3a */ "vendor specific", /* 3b */ "vendor specific", /* 3c */ "vendor specific", /* 3d */ "vendor specific", /* 3e */ "vendor specific", /* 3f */ NULL, }; static char *friendlySize (uint64_t b, char *unit) { static char *suffix[] = { "", "Ki", "Mi", "Gi", "Ti", "Pi", "Ei", "Zi", "Yi", }; int k; static char bytes[128]; for (k = 0; (b >= 1024) && (k < sizeof (suffix) / sizeof (suffix[0]) - 1); ++k, b /= 1024) ; snprintf (bytes, sizeof bytes, "%3llu%s%s", (long long unsigned int)b, suffix[k], unit); return bytes; } static uint64_t extractInt64 (void *u, size_t len) { uint64_t x; uint8_t *v; for (x = 0, v = u; len > 0; --len, ++v) x = (x << 8) + *v; return x; } int parseLogPage (void *log, size_t len, struct logData *x) { struct logPageHeader *h = log; void *u = log + sizeof (*h); struct logParameterHeader *p; size_t pageLen; memset (x, 0, sizeof (*x)); if (len < sizeof (*h)) return -1; pageLen = ntohs (h->length) + sizeof (*h); if (len > pageLen) len = pageLen; len -= sizeof (*h); x->h = *h; x->h.length = pageLen; if (h->page_code == 0) { for ( ; len > 0; --len, ++u) { uint8_t code = *((unsigned char *) u); if (code < sizeof (x->u.supported.page) / sizeof (x->u.supported.page[0])) x->u.supported.page[code] = 1; } return 0; } while (len >= sizeof (*p)) { uint16_t code; uint64_t e; struct selfTestLogParameter *t; p = u; if (p->length + sizeof (*p) > len) break; len -= sizeof (*p); u += sizeof (*p); code = ntohs (p->parameter_code); switch (h->page_code) { case 0x02: case 0x03: case 0x04: case 0x05: e = extractInt64 (u, p->length); switch (code) { case 0x0000: x->u.error.corrected = e; break; case 0x0001: x->u.error.delayed = e; break; case 0x0002: x->u.error.reread = e; break; case 0x0003: x->u.error.total_corrected = e; break; case 0x0004: x->u.error.total_algorithm = e; break; case 0x0005: x->u.error.total_bytes = e; break; case 0x0006: x->u.error.total_uncorrected = e; if (e) x->problem = 1; break; default: break; } break; case 0x0d: switch (code) { case 0x0000: x->u.temperature.current = ((uint8_t *) u)[1]; break; case 0x0001: x->u.temperature.reference = ((uint8_t *) u)[1]; break; default: break; } break; case 0x0e: switch (code) { case 0x0001: strncpy (x->u.startstop.manufacture_year, u, sizeof (x->u.startstop.manufacture_year) - 1); x->u.startstop.manufacture_year[sizeof (x->u.startstop.manufacture_year) - 1] = '\0'; ntrim (x->u.startstop.manufacture_year); strncpy (x->u.startstop.manufacture_week, u + 4, sizeof (x->u.startstop.manufacture_week) - 1); x->u.startstop.manufacture_week[sizeof (x->u.startstop.manufacture_week) - 1] = '\0'; ntrim (x->u.startstop.manufacture_week); break; case 0x0002: strncpy (x->u.startstop.accounting_year, u, sizeof (x->u.startstop.accounting_year) - 1); x->u.startstop.accounting_year[sizeof (x->u.startstop.accounting_year) - 1] = '\0'; ntrim (x->u.startstop.accounting_year); strncpy (x->u.startstop.accounting_week, u + 4, sizeof (x->u.startstop.accounting_week) - 1); x->u.startstop.accounting_week[sizeof (x->u.startstop.accounting_week) - 1] = '\0'; ntrim (x->u.startstop.accounting_week); break; case 0x0003: x->u.startstop.recommended_starts = ntohl (*((uint32_t *) u)); break; case 0x0004: x->u.startstop.accumulated_starts = ntohl (*((uint32_t *) u)); break; default: break; } break; case 0x10: if ((code < 1) || (code > sizeof (x->u.selftest.entry) / sizeof (x->u.selftest.entry[0]))) break; if (p->length != sizeof (x->u.selftest.entry[0]) - sizeof (*p)) break; --code; t = &x->u.selftest.entry[code]; *t = *((struct selfTestLogParameter *) p); t->h.parameter_code = code; t->timestamp = ntohs (t->timestamp); t->lba = extractInt64 (&t->lba, sizeof (t->lba)); if (t->self_test_code || t->self_test_results || t->timestamp || t->number || t->lba) if ((t->self_test_results >= 4) && (t->self_test_results <= 7)) x->problem = 1; break; } len -= p->length; u += p->length; } /* flag any other problems */ switch (h->page_code) { case 0x0d: if (x->u.temperature.reference && (x->u.temperature.reference != 0xff) && (x->u.temperature.current >= x->u.temperature.reference)) x->problem = 1; break; } return 0; } void dumpLogPage (FILE *f, struct logData *x, void *log, size_t len, int verbosity) { struct logPageHeader *h = log; void *u = log + sizeof (*h); struct logParameterHeader *p; size_t pageLen; int k; switch (x->h.page_code) { case 0x00: fprintf (f, " %s:", logPageType[h->page_code]); if (verbosity > 1) fprintf (f, "\n"); for (k = 0; k < sizeof (x->u.supported.page) / sizeof (x->u.supported.page[0]); ++k) { if (!(x->u.supported.page[k])) continue; if (verbosity > 1) { char *name; if (logPageType[k]) name = logPageType[k]; else name = "unknown log page"; fprintf (f, " %02x %s\n", k, name); } else fprintf (f, " %02x", k); } if (!(verbosity > 1)) fprintf (f, "\n"); break; case 0x02: case 0x03: case 0x04: case 0x05: switch (x->h.page_code) { case 0x02: fprintf (f, " write errors:"); break; case 0x03: fprintf (f, " read errors:"); break; case 0x04: fprintf (f, " read/rev errors:"); break; case 0x05: fprintf (f, " verify errors:"); break; } fprintf (f, " corr:%-6s", friendlySize (x->u.error.corrected, "")); fprintf (f, " delay:%-6s", friendlySize (x->u.error.delayed, "")); switch (x->h.page_code) { case 0x02: fprintf (f, " rewrit:%-6s", friendlySize (x->u.error.reread, "")); break; case 0x03: fprintf (f, " reread:%-6s", friendlySize (x->u.error.reread, "")); break; case 0x04: fprintf (f, " reread:%-6s", friendlySize (x->u.error.reread, "")); break; case 0x05: fprintf (f, " revrfy:%-6s", friendlySize (x->u.error.reread, "")); break; } fprintf (f, " tot/corr:%-6s", friendlySize (x->u.error.total_corrected, "")); if (verbosity > 1) fprintf (f, " tot/alg:%-6s", friendlySize (x->u.error.total_algorithm, "")); if (verbosity > 1) fprintf (f, " tot/bytes:%-6s", friendlySize (x->u.error.total_bytes, "B")); fprintf (f, " tot/uncorr:%-6s", friendlySize (x->u.error.total_uncorrected, "")); fprintf (f, "\n"); break; case 0x0d: fprintf (f, " temperature: current:%uC threshold:%uC%s\n", x->u.temperature.current, x->u.temperature.reference, x->problem ? " warning:temperature threshold exceeded" : ""); break; case 0x0e: fprintf (f, " "); if (strlen (x->u.startstop.manufacture_year) && strlen (x->u.startstop.manufacture_week)) fprintf (f, " manufactured:%s/%s", x->u.startstop.manufacture_year, x->u.startstop.manufacture_week); if (strlen (x->u.startstop.accounting_year) && strlen (x->u.startstop.accounting_week)) fprintf (f, " accounting:%s/%s", x->u.startstop.accounting_year, x->u.startstop.accounting_week); fprintf (f, " starts:%d/%d", x->u.startstop.accumulated_starts, x->u.startstop.recommended_starts); fprintf (f, "\n"); break; case 0x10: for (k = 0; k < sizeof (x->u.selftest.entry) / sizeof (x->u.selftest.entry[0]); ++k) { struct selfTestLogParameter *t = &x->u.selftest.entry[k]; if (t->self_test_code || t->self_test_results || t->timestamp || t->number || t->lba) { char *test; char *result; int notice = 0; switch (t->self_test_code) { case SCSI_SELFTEST_DEFAULT: test = "default"; break; case SCSI_SELFTEST_BACKGROUND_SHORT: test = "bg short"; break; case SCSI_SELFTEST_BACKGROUND_LONG: test = "bg long"; break; case SCSI_SELFTEST_BACKGROUND_ABORT: test = "bg aborted"; break; case SCSI_SELFTEST_FOREGROUND_SHORT: test = "fg short"; break; case SCSI_SELFTEST_FOREGROUND_LONG: test = "fg long"; break; default: test = "unknown"; break; } switch (t->self_test_results) { case 0x0: result = "completed without error"; notice = 1; break; case 0x1: result = "aborted via send diagnostic"; notice = 1; break; case 0x2: result = "aborted via other method"; notice = 1; break; case 0x3: result = "unable to complete"; notice = 1; break; case 0x4: result = "failed in unknown segment"; notice = 0; break; case 0x5: result = "failed in segment 1"; notice = 0; break; case 0x6: result = "failed in segment 2"; notice = 0; break; case 0x7: result = "failed in other segment"; notice = 0; break; case 0xf: result = "in progress"; notice = 0; break; default: result = "unknown result"; notice = 0; break; } if (verbosity > notice) fprintf (f, " %2d: timestamp %4ud%02uh: %10s %-30s seg:%u lba:%-8lld sk:%u asc:%u ascq:%u vs:%u\n", k, t->timestamp / 24, t->timestamp % 24, test, result, t->number, (long long int)t->lba, t->sense_key, t->additional_sense_code, t->additional_sense_code_qualifier, t->vendor_specific); } } break; default: break; } if (!(verbosity > 2)) return; if (len < sizeof (*h)) return; pageLen = ntohs (h->length) + sizeof (*h); if (len > pageLen) len = pageLen; len -= sizeof (*h); fprintf (f, " log page %02x, length %u%s\n", h->page_code, ntohs (h->length), len < pageLen - sizeof (*h) ? " warning: truncated" : ""); while (len >= sizeof (*p)) { uint16_t code; p = u; if (p->length + sizeof (*p) > len) break; len -= sizeof (*p); u += sizeof (*p); code = ntohs (p->parameter_code); fprintf (f, " param %04x, du %u, ds %u, tsd %u, etc %u, tmc %u, lbin %u, lp %u, length %u\n", code, p->du, p->ds, p->tsd, p->etc, p->tmc, p->lbin, p->lp, p->length); dumpbytes (f, u, p->length, u, "param"); len -= p->length; u += p->length; } } megactl-0.4.5/logpage.h000066400000000000000000000066711465722425200147460ustar00rootroot00000000000000#ifndef _LOGPAGE_H #define _LOGPAGE_H /* * Definitions for SCSI log sense page parsing and printing. * * Copyright (c) 2007 by Jefferson Ogata */ /* * 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, 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; see the file COPYING. If not, write to the Free Software * Foundation, 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. */ #include #include #include struct logPageHeader { uint8_t page_code; uint8_t rsvd0; uint16_t length; } __attribute__ ((packed)); struct logParameterHeader { uint16_t parameter_code; #if defined(_BIT_FIELDS_LTOH) /* Intel byteorder (thanks, Schily) */ uint8_t lp:1; uint8_t lbin:1; uint8_t tmc:2; uint8_t etc:1; uint8_t tsd:1; uint8_t ds:1; uint8_t du:1; #else /* Motorola byteorder */ uint8_t du:1; uint8_t ds:1; uint8_t tsd:1; uint8_t etc:1; uint8_t tmc:2; uint8_t lbin:1; uint8_t lp:1; #endif uint8_t length; }; #define LOG_PAGE_MAX 0x40 struct supportedLogsPage { uint8_t page[LOG_PAGE_MAX]; }; struct errorLogPage { uint64_t corrected; uint64_t delayed; uint64_t reread; uint64_t total_corrected; uint64_t total_algorithm; uint64_t total_bytes; uint64_t total_uncorrected; }; struct selfTestLogParameter { struct logParameterHeader h; #if defined(_BIT_FIELDS_LTOH) /* Intel byteorder (thanks, Schily) */ uint8_t self_test_results:4; uint8_t rsvd0:1; uint8_t self_test_code:3; #else /* Motorola byteorder */ uint8_t self_test_code:3; uint8_t rsvd0:1; uint8_t self_test_results:4; #endif uint8_t number; uint16_t timestamp; uint64_t lba; #if defined(_BIT_FIELDS_LTOH) /* Intel byteorder (thanks, Schily) */ uint8_t sense_key:4; uint8_t rsvd1:4; #else /* Motorola byteorder */ uint8_t rsvd1:4; uint8_t sense_key:4; #endif uint8_t additional_sense_code; uint8_t additional_sense_code_qualifier; uint8_t vendor_specific; }; struct selfTestLogPage { struct selfTestLogParameter entry[20]; }; struct startStopCycleCounterLogPage { char manufacture_year[5]; char manufacture_week[3]; char accounting_year[5]; char accounting_week[3]; uint32_t recommended_starts; uint32_t accumulated_starts; }; struct temperatureLogPage { uint8_t current; uint8_t reference; }; struct logData { struct logPageHeader h; uint8_t problem; uint8_t pad[3]; union { struct supportedLogsPage supported; struct errorLogPage error; struct selfTestLogPage selftest; struct startStopCycleCounterLogPage startstop; struct temperatureLogPage temperature; } u; } __attribute__ ((packed)); extern int parseLogPage (void *log, size_t len, struct logData *x); extern void dumpLogPage (FILE *f, struct logData *x, void *log, size_t len, int verbosity); #endif megactl-0.4.5/mega.h000066400000000000000000000422721465722425200142360ustar00rootroot00000000000000#ifndef _MEGA_H #define _MEGA_H /* * Definitions of data structures used by the adapter and by our * high-level interface. * * Copyright (c) 2007 by Jefferson Ogata */ /* * 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, 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; see the file COPYING. If not, write to the Free Software * Foundation, 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. */ #include "logpage.h" #include #include #include typedef signed char s8; typedef unsigned char u8; typedef signed short s16; typedef unsigned short u16; typedef signed int s32; typedef unsigned int u32; typedef signed long long s64; typedef unsigned long long u64; #define BITS_PER_LONG 32 #include #ifdef NEED_UINT8_T typedef __u8 uint8_t; typedef __u16 uint16_t; typedef __u32 uint32_t; typedef __u64 uint64_t; #endif /* DMA addresses come in generic and 64-bit flavours. */ #ifdef CONFIG_HIGHMEM typedef u64 dma_addr_t; #else typedef u32 dma_addr_t; #endif typedef u64 dma64_addr_t; /* Hacks to get kernel module headers to compile. We're not using any data structures where these matter. */ typedef struct { volatile unsigned int lock; } spinlock_t; struct semaphore { int foo; }; typedef struct { volatile int counter; } atomic_t; struct tasklet_struct { struct tasklet_struct *next; unsigned long state; atomic_t count; void (*func)(unsigned long); unsigned long data; }; #define __iomem #define __user #define wait_queue_head_t void * /* typedef void wait_queue_head_t; */ struct list_head { struct list_head *next, *prev; }; /* Okay, should be able to include module headers now, hopefully. */ #include "megaraid/mbox_defs.h" #include "megaraid/megaraid_ioctl.h" #include "megaraid/megaraid_sas.h" #define MAX_CONTROLLERS 32 #define M_RD_IOCTL_CMD 0x80 #define M_RD_IOCTL_CMD_NEW 0x81 #define M_RD_DRIVER_IOCTL_INTERFACE 0x82 #define SCSI_SELFTEST_DEFAULT 0x00 #define SCSI_SELFTEST_BACKGROUND_SHORT 0x01 #define SCSI_SELFTEST_BACKGROUND_LONG 0x02 #define SCSI_SELFTEST_BACKGROUND_ABORT 0x04 #define SCSI_SELFTEST_FOREGROUND_SHORT 0x05 #define SCSI_SELFTEST_FOREGROUND_LONG 0x06 /* Drives without enclosure report this as the enclosure ID */ #define DISK_NOENC 0xffff /* megaraid2 header file gets this wrong. */ typedef struct { uint8_t max_commands; uint8_t rebuild_rate; uint8_t max_targ_per_chan; uint8_t nchannels; uint8_t fw_version[4]; uint16_t age_of_flash; uint8_t chip_set_value; uint8_t dram_size; uint8_t cache_flush_interval; uint8_t bios_version[4]; uint8_t board_type; uint8_t sense_alert; uint8_t write_config_count; uint8_t drive_inserted_count; uint8_t inserted_drive; uint8_t battery_status; uint8_t dec_fault_bus_info; } __attribute__ ((packed)) mraid_adapinfo1_t; typedef struct { mraid_adapinfo1_t adapter_info; mraid_ldrv_info_t logdrv_info; mraid_pdrv_info_t pdrv_info; } __attribute__ ((packed)) mraid_inquiry1_t; typedef struct { mraid_inquiry1_t raid_inq; uint16_t phys_drv_format[MAX_MBOX_CHANNELS]; uint8_t stack_attn; uint8_t modem_status; uint8_t rsvd[2]; } __attribute__ ((packed)) mraid_extinq1_t; /* Structures we've figured out over many hours of staring at hex data. */ struct mega_physical_drive_error_info { uint8_t media; uint8_t other; } __attribute__ ((packed)); struct mega_predictive_map { uint8_t map[FC_MAX_PHYSICAL_DEVICES / 8]; } __attribute__ ((packed)); struct mega_device_entry_sas { uint16_t device_id; uint16_t enclosure; uint8_t value_1; /* ? 1, 2 enclosure number + 1? backend port number? */ uint8_t slot; uint8_t type; /* INQ_DASD, INQ_ENCL */ uint8_t port; /* 1 << connected port number */ uint64_t sas_address[2]; } __attribute__ ((packed)); /* opcode 0x02010000 */ struct mega_device_list_sas { uint32_t length; uint16_t num_devices; uint16_t rsvd0; struct mega_device_entry_sas device[32]; /* actually any number */ } __attribute__ ((packed)); struct mega_array_header_sas { uint32_t length; uint16_t num_span_defs; uint16_t span_def_size; /* 0x0120 */ uint16_t num_disk_defs; uint16_t disk_def_size; /* 0x0100 */ uint16_t num_hot_spares; uint16_t value_0028; /* ? 0x0028 */ uint32_t pad0[4]; } __attribute__ ((packed)); struct mega_array_span_disk_sas { uint16_t device_id; /* 0xffff if device missing */ uint16_t sequence; /* ? 0x0002, 0x0004, 0x0006... as disks are created */ uint8_t flag_0:1; uint8_t hotspare:1; uint8_t rebuild:1; uint8_t online:1; uint8_t present:1; uint8_t flag_1; uint8_t enclosure; uint8_t slot; } __attribute__ ((packed)); struct mega_array_span_def_sas { uint64_t sectors_per_disk; uint16_t span_size; /* number of disks in span */ uint16_t span_index; /* 0, 1, 2... */ uint32_t value_1; /* ? 0 */ uint32_t pad0[4]; struct mega_array_span_disk_sas disk[32]; /* real number is (config.span_def_size - offset .disks) / sizeof span_entry */ } __attribute__ ((packed)); struct mega_array_disk_entry_sas { uint64_t offset; /* offset in sectors of this vd */ uint64_t sectors_per_disk; /* sectors used for this vd on each disk */ uint16_t span_index; /* number of this span */ uint16_t pad2; /* ? 0 */ uint32_t pad3; /* ? 0 */ } __attribute__ ((packed)); #define MEGA_SAS_LD_OFFLINE 0 #define MEGA_SAS_LD_PARTIALLY_DEGRADED 1 #define MEGA_SAS_LD_DEGRADED 2 #define MEGA_SAS_LD_OPTIMAL 3 struct mega_array_disk_def_sas { uint16_t disk_index; /* 0, 1, 2... */ uint16_t sequence; /* ? 0x0004, 0x0003 */ char name[16]; /* null-terminated, max 15 chars */ uint32_t flags; /* ? 0x01000001, 0x00000000 */ uint32_t pad0[2]; /* ? 0 */ uint8_t raid_level; /* 0, 1, 5 */ uint8_t raid_level_secondary; /* ? 3 for raid 5 with 4 spans, 0 for raid1 with 1 span */ uint8_t raid_level_qualifier; /* ? 3 for raid 5 with 4 spans, 0 for raid1 with 1 span */ uint8_t stripe_size; /* (2 << this) sectors per stripe; 4 == 8K, 5 == 16K, etc. */ uint8_t disks_per_span; uint8_t num_spans; uint16_t state; /* ? 0 == offline, 1 == partially degraded, 2 == degraded, 3 == optimal */ uint32_t value_4; /* ? 0x00000001, 0x00000000 */ uint32_t pad1[5]; /* ? 0 */ struct mega_array_disk_entry_sas span[8]; /* real number is (config.disk_def_size - offset .spans) / sizeof disk_entry */ } __attribute__ ((packed)); struct mega_array_hotspare_def_sas { uint16_t device_id; uint16_t sequence; /* ? 0x001c, 0x001e, 0x0020 */ uint32_t flags; /* ? 0x00000000 for global, 0x01000001 for dedicated */ uint32_t array; /* dedicated array index */ uint32_t pad0[7]; /* ? 0 */ } __attribute__ ((packed)); /* opcode 0x04010000: array config is { header span_def* disk_def* hotspare_def* } */ struct mega_array_config_sas { struct mega_array_header_sas *header; struct mega_array_span_def_sas *span; struct mega_array_disk_def_sas *disk; struct mega_array_hotspare_def_sas *hotspare; }; /* opcode 0x05010000 */ #define MEGA_BATTERY_TYPE_NONE 0 #define MEGA_BATTERY_TYPE_ITBBU 1 #define MEGA_BATTERY_TYPE_TBBU 2 struct mega_battery_state_sas { uint8_t type; /* see above */ uint8_t foo; /* ? */ uint16_t voltage; /* millivolts */ uint16_t current; /* milliamps */ uint16_t temperature; /* celsius */ uint32_t firmware_status; uint32_t pad0[5]; /* ? 0 */ uint8_t pad1:4; uint8_t fully_discharged:1; uint8_t fully_charged:1; uint8_t discharging:1; uint8_t initialized:1; uint8_t remaining_time_alarm:1; uint8_t remaining_capacity_alarm:1; uint8_t pad2:1; uint8_t discharge_terminated:1; uint8_t over_temperature:1; uint8_t pad3:1; uint8_t charging_terminated:1; uint8_t over_charged:1; uint16_t charge; /* percentage */ uint16_t charger_status; /* charger status 0 == off, 1 == complete, 2 == in progress */ uint16_t capacity_remaining; /* milliamp-hours */ uint16_t capacity_full; /* milliamp-hours */ uint16_t health; /* state of health 0 == no, * == good */ uint32_t pad9[5]; /* ? 0 */ } __attribute__ ((packed)); /* opcode 0x05020000 */ struct mega_battery_capacity_sas { uint16_t charge_relative; /* percentage */ uint16_t charge_absolute; /* percentage */ uint16_t capacity_remaining; /* milliamp-hours */ uint16_t capacity_full; /* milliamp-hours */ uint16_t time_empty_run; /* minutes */ uint16_t time_empty_average; /* minutes */ uint16_t time_full_average; /* minutes */ uint16_t cycles; uint16_t error_max; /* percentage */ uint16_t alarm_capacity; /* milliamp-hours */ uint16_t alarm_time; /* minutes */ uint16_t pad0; /* ? 0 */ uint32_t pad1[6]; /* ? 0 */ } __attribute__ ((packed)); /* opcode 0x05030000 */ struct mega_battery_design_sas { uint32_t manufacture_date; /* weird encoding: 0xfae87 == 2007/04/07, 0xfaebf == 2007/05/31 */ uint16_t design_capacity; /* milliamp-hours */ uint16_t design_voltage; /* millivolts */ uint16_t specification_info; uint16_t serial_number; uint16_t pack_stat_configuration; char manufacturer[12]; char device_name[8]; char device_chemistry[5]; char device_vendor[5]; uint32_t pad0[5]; /* ? 0 */ } __attribute__ ((packed)); /* opcode 0x05050100 */ struct mega_battery_properties_sas { uint32_t device_learn_period; /* seconds */ uint32_t next_learn_time; /* seconds */ uint32_t learn_delay_interval; /* ? hours */ uint32_t auto_learn_mode; /* ? */ uint32_t pad0[4]; /* ? 0 */ } __attribute__ ((packed)); struct mega_battery_info_sas { struct mega_battery_state_sas state; struct mega_battery_capacity_sas capacity; struct mega_battery_design_sas design; struct mega_battery_properties_sas properties; }; /* opcode 0x02020000 */ struct mega_physical_disk_info_sas { uint16_t device_id; uint16_t sequence; union { struct scsi_inquiry inq; uint8_t buf[96]; } inquiry; uint16_t value_x; /* ? 0x8300 */ /* 0x064 */ uint16_t value_y; /* ? 0x4800, 0x2000 */ struct { uint8_t value[60]; } mystery_struct; /* 0x0a4 */ uint16_t value_0; /* ? 0x0000 */ uint8_t port; /* 1 << connected port number */ uint8_t value_1; /* ? 0 */ uint32_t media_errors; uint32_t other_errors; uint32_t predictive_failures; uint32_t predictive_failure_event_sequence; uint8_t failure:1; uint8_t hotspare:1; uint8_t rebuild:1; uint8_t online:1; uint8_t configured:1; uint8_t flags_0:3; uint8_t flags_1; uint16_t value_4; /* ? 0x0000 */ uint32_t value_5; /* ? 0x00002002, 0x00003003, 0x00003009 */ uint32_t sas_address_count; /* number of sas addresses */ uint32_t pad_sas_addr; /* ? 0x00000000 */ uint64_t sas_address[4]; uint64_t raw_size; /* sectors; MegaCli only sees 32 bits */ /* 0x0e8 */ uint64_t noncoerced_size; /* sectors; MegaCli only sees 32 bits */ /* 0x0f0 */ uint64_t coerced_size; /* sectors; MegaCli only sees 32 bits */ /* 0x0f8 */ uint16_t enclosure; /* 0x100 */ uint8_t value_9; /* 1 or 2, not sure what it means, goes with enclosure */ uint8_t slot; uint8_t value_10[0xfc]; } __attribute__ ((packed)); /* Unified config structures for generic high-level interface. */ enum mega_adapter_enum { MEGA_ADAPTER_V2, /* PERC2 */ MEGA_ADAPTER_V34, /* PERC3 or PERC4 */ MEGA_ADAPTER_V5, /* PERC5 (SAS) */ }; /* Structure for io to adapters. */ struct mega_adapter_path { int fd; /* block device descriptor for adapter access */ uint8_t adapno; /* adapter number */ enum mega_adapter_enum type; /* adapter variant */ }; struct log_page_list { struct logData log; uint8_t buf[4095]; /* rhl 7.3 croaks on >= 4096 */ struct log_page_list *next; }; enum physical_drive_state { PdStateUnknown, PdStateUnconfiguredGood, PdStateUnconfiguredBad, PdStateHotspare, PdStateFailed, PdStateRebuild, PdStateOnline, }; struct physical_drive_info { uint8_t present; /* whether drive responds to inquiry */ struct adapter_config *adapter; /* adapter this drive belongs to */ struct span_info *span; /* span this disk is a member of */ char name[16]; /* drive name (AxCyTz) */ uint16_t target; /* scsi channel+id or device_id */ uint16_t channel; /* channel or enclosure */ uint8_t id; /* scsi id or enclosure slot */ enum physical_drive_state state; /* drive state */ char *error_string; /* status error string (NULL if okay) */ uint64_t blocks; /* number of blocks */ char vendor[9]; /* vendor name */ char model[17]; /* vendor model */ char revision[5]; /* firmware version */ char serial[32]; /* serial number */ uint32_t predictive_failures; /* predictive failure count */ uint32_t media_errors; uint32_t other_errors; struct scsi_inquiry inquiry; /* scsi inquiry result */ struct log_page_list *log; union { struct { struct mega_physical_disk_info_sas info; } v5; } q; }; struct span_info { struct adapter_config *adapter; /* adapter this span belongs to */ uint32_t blocks_per_disk; /* blocks used per disk for this span */ uint32_t num_disks; /* number of disks in this span */ struct physical_drive_info **disk; /* pointers to component disks */ uint32_t num_logical_drives; /* how many logical drives this span belongs to */ struct logical_drive_info **logical_drive; /* pointers to logical drives */ }; struct span_reference { uint64_t offset; /* offset into each disk */ uint64_t blocks_per_disk; /* number of blocks used per disk */ struct span_info *span; /* the span */ }; enum logical_drive_state { LdStateUnknown, LdStateOffline, LdStatePartiallyDegraded, LdStateDegraded, LdStateOptimal, LdStateDeleted, }; struct logical_drive_info { struct adapter_config *adapter; /* adapter this drive belongs to */ char name[16]; /* logical drive name (AxLDy) */ uint16_t target; /* logical drive number */ enum logical_drive_state state; /* logical drive state */ uint8_t raid_level; /* raid level */ uint8_t num_spans; /* how many spans in this logical drive */ struct span_reference *span; /* pointers to component spans */ uint8_t span_size; /* number of disks per span */ }; enum battery_charger_state { ChargerStateUnknown, ChargerStateFailed, ChargerStateInProgress, ChargerStateComplete, }; struct adapter_config { struct mega_adapter_path target; /* adapter access path */ uint8_t is_sas; /* adapter is a sas adapter */ char name[16]; /* adapter name (Ax) */ char product[81]; /* adapter product name */ char bios[17]; /* adapter bios version */ char firmware[17]; /* adapter firmware version */ struct { uint8_t healthy:1; uint8_t module_missing:1; uint8_t pack_missing:1; uint8_t low_voltage:1; uint8_t high_temperature:1; uint8_t cycles_exceeded:1; uint8_t over_charged:1; enum battery_charger_state charger_state; int16_t voltage; int16_t temperature; } battery; uint16_t dram_size; /* size of DRAM in MB */ uint16_t rebuild_rate; /* rebuild rate as percentage */ uint16_t num_channels; /* number of channels or enclosures */ uint16_t *channel; /* channel/enclosure map */ uint16_t num_physicals; struct physical_drive_info *physical; struct physical_drive_info **physical_list; /* ordered list of physical devices */ uint16_t num_spans; /* number of spans */ struct span_info *span; uint16_t num_logicals; /* number of logical drives */ struct logical_drive_info *logical; /* logical drives */ struct adapter_config *next; /* adapter-specific data structures */ union { struct { mraid_inquiry1_t inquiry; struct mega_predictive_map map; disk_array_8ld_span8_t config; } v2; struct { mraid_pinfo_t adapinfo; mraid_inquiry3_t enquiry3; struct mega_predictive_map map; disk_array_40ld_t config; } v3; struct { struct megasas_ctrl_info adapinfo; struct mega_device_list_sas *device; struct mega_array_config_sas config; struct mega_battery_info_sas battery; } v5; } q; }; #endif megactl-0.4.5/megactl.1000066400000000000000000000053611465722425200146500ustar00rootroot00000000000000.\" Text automatically generated by txt2man .TH megactl 1 "03 March 2024" "" .SH NAME megactl \- diagnostics on megaraid adapters and attached disks. .SH SYNOPSIS megactl [\fB-vest\fP] [\fB-H\fP] [\fB-l\fP log-page-nr] [\fB-T\fP long|short] [target \.\.\.] .PP Reports diagnostics on megaraid adapters and attached disks. Permits dumping of controller log pages for inspection of error, temperature, and self-test conditions, initiates self-test diagnostics, and documents adapter and logical drive configuration. Target devices may be adapters, (e.g. a0), channels (e.g. a0c0), or individual disks (e.g. a0c0t0). If no target is specified, reports configuration and drive state on all adapters. If a target matches a collection of disks, operations are applied to all matching devices. Options are: .TP .B \fB-v\fP Increase program verbosity. .TP .B \fB-e\fP Dump read (0x03), write (0x02), and verify (0x05) error log pages. .TP .B \fB-s\fP Dump self-test (0x10) log page. .TP .B \fB-t\fP Dump temperature (0x0d) log page. .TP .B \fB-l\fP page Dump the specified log page. Log page 0 documents the log pages the device supports. .TP .B \fB-p\fP Do not report physical disks. Reports only adapters and logical drives. Useful for concisely documenting adapter configuration. .TP .B \fB-T\fP test Initiate the background short or long self-test procedure. The test may take up to an hour to complete, but does not inhibit access to the device. The test may be monitored using the \fB-s\fP option. .TP .B \fB-H\fP Perform an adapter health check. Inspects state of all logical and physical drives and battery backup unit and reports problem conditions. If all is well, generates no output. Useful in a cron job. .TP .B \fB-B\fP When performing health check, do not treat battery problems as failures. .TP .B \fB-V\fP Show version. .PP N.B. The background long self test is a useful tool for diagnosing problems with individual disks. But be cautious with program usage. "megactl \fB-T\fP long" with no targets will initiate a background long self test on every drive on every adapter. This may not be what you want. .PP By default, the health check option inspects log pages 0x02, 0x03, and 0x05 for uncorrected read, write, and verify errors, 0x0d for excess temperature conditions, and 0x10 for failed self tests. If, however, any of the log page options is specified, only the designated log pages are inspected. .PP This program requires the device file /dev/megadev0 to be present on the system. If your system does not have this device file, you may create it either by executing Dell's "dellmgr" program once, or by locating the megadev entry in /proc/devices and creating /dev/megadev0 as a character device with suitable permissions with a matching major device number and a minor number of 0. megactl-0.4.5/megactl.c000066400000000000000000000573611465722425200147410ustar00rootroot00000000000000/* * Main program. * * Copyright (c) 2007 by Jefferson Ogata */ /* * 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, 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; see the file COPYING. If not, write to the Free Software * Foundation, 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. */ /******************************************************************** megactl/megasasctl Program to do the things you wish dellmgr or MegaCli could do, e.g. report device log pages, run device self tests, report disk error counts without having to pop in and out of countless dellmgr menus, and actually document the adapter configuration concisely (dellmgr gives you no way to do this). Author: Jefferson Ogata (JO317) Date: 2006/01/23 Version 0.4.0 major changes, including SAS support: 2007/08/20 TODO: Other log page parsers. Cleaner log page output. Fixes for 64-bit systems. Currently builds only with -m32. Fetch TTY logs. ********************************************************************/ #include "mega.h" #include "megaioctl.h" #include "adapter.h" #include #include #include #include #include #include #include #include #include #include #include #include #include #include #include #include "dumpbytes.h" #include "logpage.h" #ifdef MEGA_SAS_CTL #define MEGA_DEVICE "/dev/megaraid_sas_ioctl_node" #define MEGA_NAME "megaraid_sas_ioctl" #else #define MEGA_DEVICE "/dev/megadev0" #define MEGA_NAME "megadev" #define MEGA_MIN_VERSION 0x118c #endif /* defined(MEGA_SAS_CTL) */ static char *version = "0.4.3-hmage"; static int verbosity = 0; static char *me; static char *usages[] = { "usage: %p [-vest] [-H] [-l log-page-nr] [-T long|short] [target ...]", "", "Reports diagnostics on megaraid adapters and attached disks. Permits", "dumping of controller log pages for inspection of error, temperature,", "and self-test conditions, initiates self-test diagnostics, and documents", "adapter and logical drive configuration. Target devices may be adapters,", #ifdef MEGA_SAS_CTL "(e.g. a0), enclosures (e.g. a0e0), or individual disks (e.g. a0e0s0). If", #else "(e.g. a0), channels (e.g. a0c0), or individual disks (e.g. a0c0t0). If", #endif "no target is specified, reports configuration and drive state on all", "adapters. If a target matches a collection of disks, operations are", "applied to all matching devices. Options are:", "-v Increase program verbosity.", "-e Dump read (0x03), write (0x02), and verify (0x05) error log", " pages.", "-s Dump self-test (0x10) log page.", "-t Dump temperature (0x0d) log page.", "-l page Dump the specified log page. Log page 0 documents the log pages", " the device supports.", "-p Do not report physical disks. Reports only adapters and logical", " drives. Useful for concisely documenting adapter configuration.", "-T test Initiate the background short or long self-test procedure. The", " test may take up to an hour to complete, but does not inhibit", " access to the device. The test may be monitored using the -s", " option.", "-H Perform an adapter health check. Inspects state of all logical", " and physical drives and battery backup unit and reports problem", " conditions. If all is well, generates no output. Useful in a", " cron job.", "-B When performing health check, do not treat battery problems as", " failures.", "-V Show version.", "", "N.B. The background long self test is a useful tool for diagnosing", "problems with individual disks. But be cautious with program usage.", "\"%p -T long\" with no targets will initiate a background long self", "test on every drive on every adapter. This may not be what you want.", "", "By default, the health check option inspects log pages 0x02, 0x03, and", "0x05 for uncorrected read, write, and verify errors, 0x0d for excess", "temperature conditions, and 0x10 for failed self tests. If, however, any", "of the log page options is specified, only the designated log pages are", "inspected.", "", #ifdef MEGA_SAS_CTL "This program requires the device file " MEGA_DEVICE " to be", "present on the system. If your system does not have this device file,", "you may create it either by executing LSI\'s \"MegaCli\" program once,", "or by locating the megadev_sas_ioctl entry in /proc/devices and creating", MEGA_DEVICE " as a character device with suitable", "permissions with a matching major device number and a minor number of 0.", #else "This program requires the device file " MEGA_DEVICE " to be present on", "the system. If your system does not have this device file, you may", "create it either by executing Dell\'s \"dellmgr\" program once, or by", "locating the megadev entry in /proc/devices and creating " MEGA_DEVICE, "as a character device with suitable permissions with a matching major", "device number and a minor number of 0.", #endif 0, }; static void usage (const int ec, const char *format, ...) { char **u; va_list ap; va_start (ap, format); if (format) { fprintf (stderr, "%s: ", me); vfprintf (stderr, format, ap); fprintf (stderr, "\n\n"); } for (u = usages; *u; ++u) { char *s; int esc; for (s = *u, esc = 0; *s; ++s) { if (esc) { switch (*s) { case 'p': fputs (me, stderr); break; case '%': fputc ('%', stderr); break; default: fputc ('%', stderr); fputc (*s, stderr); break; } esc = 0; } else { switch (*s) { case '%': esc = 1; break; default: fputc (*s, stderr); break; } } } fputc ('\n', stderr); } exit (ec); } static char *friendlySize (uint64_t b, char *unit) { static char *suffix[] = { "", "Ki", "Mi", "Gi", "Ti", "Pi", "Ei", "Zi", "Yi", }; int k; static char bytes[128]; for (k = 0; (b >= 10000) && (k < sizeof (suffix) / sizeof (suffix[0]) - 1); ++k, b /= 1024) ; snprintf (bytes, sizeof bytes, "%4"PRIu64"%s%s", b, suffix[k], unit); return bytes; } static void describePhysicalDrive (FILE *f, struct physical_drive_info *d, int verbosity) { char *state; if (d->present) switch (d->state) { case PdStateUnconfiguredGood: state = "ready"; break; case PdStateUnconfiguredBad: state = "BAD"; break; case PdStateOnline: state = "online"; break; case PdStateFailed: state = d->span ? "FAILED" : "rdy/fail"; break; case PdStateRebuild: state = "rebuild"; break; case PdStateHotspare: state = "hotspare"; break; default: state = "???"; break; } else state = "absent"; fprintf (f, "%-8s", d->name); if (verbosity > 0) fprintf (f, " %8s %-16s", d->vendor, d->model); if (verbosity > 1) fprintf (f, " rev:%-4s s/n:%-20s", d->revision, d->serial); fprintf (f, " %8s", friendlySize (d->blocks << 9, "B")); fprintf (f, " %5s%c", d->span && d->span->num_logical_drives ? d->span->logical_drive[0]->name : "", d->span && (d->span->num_logical_drives > 1) ? '+' : ' '); fprintf (f, " %-8s", state); if (d->media_errors || d->other_errors) fprintf (f, " errs: media:%-2u other:%u", d->media_errors, d->other_errors); if (d->predictive_failures) fprintf (f, " predictive-failure"); fprintf (f, "\n"); if (d->present && d->error_string) fprintf (f, "\t%s\n", d->error_string); } static void describeLogicalDrive (FILE *f, struct logical_drive_info *l, int verbosity) { char *state; uint64_t blocks; int k; struct span_reference *r; switch (l->state) { case LdStateOffline: state = "OFFLINE"; break; case LdStatePartiallyDegraded: case LdStateDegraded: state = "DEGRADED"; break; case LdStateOptimal: state = "optimal"; break; case LdStateDeleted: state = "deleted"; break; default: state = "???"; break; } for (k = 0, blocks = 0; k < l->num_spans; ++k) { r = &l->span[k]; switch (l->raid_level) { case 0: blocks += r->blocks_per_disk * r->span->num_disks; break; case 1: blocks += r->blocks_per_disk * r->span->num_disks / 2; break; case 5: blocks += r->blocks_per_disk * (r->span->num_disks - 1); break; case 6: blocks += r->blocks_per_disk * (r->span->num_disks - 2); break; } } fprintf (f, "%-8s", l->name); fprintf (f, " %8s", friendlySize (blocks << 9, "B")); fprintf (f, " RAID %u%s", l->raid_level, l->num_spans > 1 ? "0" : " "); fprintf (f, " %2ux%-2u", l->num_spans, l->span_size); fprintf (f, " %s", state); fprintf (f, "\n"); if (verbosity > 0) { for (k = 0; k < l->num_spans; ++k) { struct physical_drive_info **p; int j; r = &l->span[k]; fprintf (f, " row %2d:", k); for (j = 0, p = r->span->disk; j < r->span->num_disks; ++j, ++p) { char *flag = (*p)->state != PdStateOnline ? "*" : " "; fprintf (f, " %s%-8s", flag, (*p)->name); } fprintf (f, "\n"); } } } static void describeBattery (FILE *f, struct adapter_config *a, int verbosity) { if (a->battery.healthy) fprintf (f, "good"); else { fprintf (f, "FAULT"); if (a->battery.module_missing) fprintf (f, ", module missing"); if (a->battery.pack_missing) fprintf (f, ", pack missing"); if (a->battery.low_voltage) fprintf (f, ", low voltage"); if (a->battery.high_temperature) fprintf (f, ", high temperature"); if (a->battery.cycles_exceeded) fprintf (f, ", cycles exceeded"); if (a->battery.over_charged) fprintf (f, ", over charged"); switch (a->battery.charger_state) { case ChargerStateComplete: break; case ChargerStateFailed: fprintf (f, ", charge failed"); break; case ChargerStateInProgress: fprintf (f, ", charging"); break; default: fprintf (f, ", unknown charge state"); break; } } if (verbosity) { if (a->battery.voltage >= 0) fprintf (f, "/%dmV", a->battery.voltage); if (a->battery.temperature >= 0) fprintf (f, "/%dC", a->battery.temperature); } } static void describeAdapter (FILE *f, struct adapter_config *a, int verbosity) { fprintf (f, "%-8s %-24s", a->name, a->product); if (verbosity > 0) fprintf (f, " bios:%s fw:%s", a->bios, a->firmware); fprintf (f, " %s:%u ldrv:%-2u", a->is_sas ? "encl" : "chan", a->num_channels, a->num_logicals); if (verbosity > 0) fprintf (f, " rbld:%u%%", a->rebuild_rate); if (verbosity > 1) fprintf (f, " mem:%uMiB", a->dram_size); fprintf (f, " batt:"); describeBattery (f, a, verbosity); fprintf (f, "\n"); } int main (int argc, char **argv) { int k; int fd; uint32_t driverVersion = 0; uint32_t numAdapters; int startSelfTest = -1; int healthCheck = 0; int checkBattery = 1; char *device = MEGA_DEVICE; struct query_object { int adapter; int channel; int id; } *object = NULL; int numObjects = 0; uint8_t readLog[LOG_PAGE_MAX] = { 0, }; int reportPhysical = 1; int showVersion = 0; FILE *fp; char *line = NULL; int major; size_t len = 0; char lf; #ifdef MEGA_SAS_CTL int sas = 1; #else int sas = 0; #endif if ((me = strrchr (argv[0], '/'))) ++me; else me = argv[0]; if (argc > 1) { if ((object = (struct query_object *) malloc ((argc - 1) * sizeof (*object))) == NULL) { perror ("malloc"); return 1; } } for (k = 1; k < argc; ++k) { if (argv[k][0] == '-') { char *s; for (s = argv[k] + 1; *s; ++s) { if (*s == 'v') { ++verbosity; continue; } if (*s == 'e') { /* read error log pages */ readLog[0x02] = 1; /* write errors */ readLog[0x03] = 1; /* read errors */ readLog[0x05] = 1; /* read errors */ continue; } if (*s == 's') { /* read self test log page */ readLog[0x10] = 1; continue; } if (*s == 't') { /* read temperature log page */ readLog[0x0d] = 1; continue; } if (*s == 'l') { /* read specific log page */ char *t; unsigned long u; if ((++k) >= argc) usage (2, "no log page specified"); u = strtoul (argv[k], &t, 0); if (*t) usage (2, "invalid log page \"%s\"", argv[k]); if (u >= sizeof (readLog) / sizeof (readLog[0])) usage (2, "log page out of range: \"%s\"", argv[k]); readLog[u] = 1; continue; } if (*s == 'D') { /* specify device file */ if ((++k) >= argc) usage (2, "no device specified"); device = argv[k]; continue; } if (*s == 'p') { reportPhysical = 0;; continue; } if (*s == 'B') { /* skip battery check */ checkBattery = 0; continue; } if (*s == 'H') { /* perform adapter health check */ ++healthCheck; continue; } if (*s == 'T') { /* start self test */ if ((++k) >= argc) usage (2, "must specify short or long self-test"); if (!strcmp (argv[k], "short")) startSelfTest = SCSI_SELFTEST_BACKGROUND_SHORT; else if (!strcmp (argv[k], "long")) startSelfTest = SCSI_SELFTEST_BACKGROUND_LONG; else usage (2, "invalid self test: \"%s\"; must specify short or long", argv[k]); continue; } else if ((*s == '?') || (*s == 'h')) usage (0, NULL); else if (*s == 'V') { ++showVersion; continue; } usage (2, "invalid flag \"%s\"", s); } } else { char *s; char *t; unsigned long l; s = argv[k]; object[numObjects].adapter = -1; object[numObjects].channel = -1; object[numObjects].id = -1; if (*s) { if (tolower (*s) != 'a') usage (2, "invalid specifier \"%s\"", argv[k]); ++s; l = strtoul (s, &t, 10); if (s == t) usage (2, "invalid specifier \"%s\"", argv[k]); #ifndef MEGA_SAS_CTL if (l >= MAX_CONTROLLERS) usage (2, "adapter out of range: \"%s\"", argv[k]); #endif object[numObjects].adapter = l; s = t; } if (*s) { if (tolower (*s) != (sas ? 'e' : 'c')) usage (2, "invalid specifier \"%s\"", argv[k]); ++s; l = strtoul (s, &t, 10); if (s == t) usage (2, "invalid specifier \"%s\"", argv[k]); #ifndef MEGA_SAS_CTL if (l >= MAX_MBOX_CHANNELS) usage (2, "channel out of range: \"%s\"", argv[k]); #endif object[numObjects].channel = l; s = t; } if (*s) { if (tolower (*s) != (sas ? 's' : 't')) usage (2, "invalid specifier \"%s\"", argv[k]); ++s; l = strtoul (s, &t, 10); if (s == t) usage (2, "invalid specifier \"%s\"", argv[k]); #ifndef MEGA_SAS_CTL if (l > MAX_MBOX_TARGET) usage (2, "target out of range: \"%s\"", argv[k]); #endif object[numObjects].id = l; s = t; } ++numObjects; } } if (showVersion) { if (verbosity) fprintf (stdout, "%s: version %s by Jefferson Ogata\n", me, version); else fprintf (stdout, "%s\n", version); return 0; } if (healthCheck) { int set = 0; for (k = 0; k < numObjects; ++k) if ((object[k].channel >= 0) || (object[k].id >= 0)) usage (2, "for health check, must specify adapter only"); for (k = 0; k < sizeof readLog / sizeof (readLog[0]); ++k) if (readLog[k]) { set = 1; break; } if (set == 0) { /* No specific log pages requested; check read/write/verify errors and temperature. */ readLog[0x02] = 1; readLog[0x03] = 1; readLog[0x05] = 1; readLog[0x0d] = 1; } } if ((fd = open (device, O_RDONLY)) < 0) { if ((fp = fopen ("/proc/devices", "r")) == NULL) { fprintf (stderr, "file /proc/devices access error\n"); return 1; } else { while (getline(&line, &len, fp) != -1) { if ((sscanf(line, "%d "MEGA_NAME"%c", &major, &lf) == 2) && (lf = 10)) { mknod(device, S_IFCHR /*| 0666*/, makedev(major, 0)); free(line); break; } if (line) { free(line); line = NULL; } } fclose(fp); } if ((fd = open (device, O_RDONLY)) < 0) { fprintf (stderr, "unable to open device %s: %s\n", device, strerror (errno)); return 1; } } #ifndef MEGA_SAS_CTL if (megaGetDriverVersion (fd, &driverVersion) < 0) { fprintf (stderr, "unable to determine megaraid driver version: %s\n", megaErrorString ()); return 1; } if (driverVersion < MEGA_MIN_VERSION) { fprintf (stderr, "megaraid driver version %x too old.\n", driverVersion); return 1; } #endif if (megaGetNumAdapters (fd, &numAdapters, sas) < 0) { fprintf (stderr, "unable to find any adapters: %s\n", megaErrorString ()); return 1; } if (verbosity > 2) fprintf (stderr, "%u adapters, driver version %08x\n\n", numAdapters, driverVersion); /* Default to enumerating all adapters. */ if (numObjects == 0) { if (object) free (object); if ((object = (struct query_object *) malloc (numAdapters * sizeof (*object))) == NULL) { perror ("malloc"); return 1; } for (k = 0; k < numAdapters; ++k) { object[k].adapter = k; object[k].channel = -1; object[k].id = -1; } numObjects = k; } for (k = 0; k < numObjects; ++k) { int adapter = object[k].adapter; int channel = object[k].channel; int id = object[k].id; char name[32]; struct adapter_config *a; uint32_t c; uint32_t i; int j; if (id >= 0) snprintf (name, sizeof name, "a%u%c%u%c%u", adapter, sas ? 'e' : 'c', channel, sas ? 's' : 't', id); else if (channel >= 0) snprintf (name, sizeof name, "a%u%c%u", adapter, sas ? 'e' : 'c', channel); else snprintf (name, sizeof name, "a%u", adapter); if (adapter >= numAdapters) { fprintf (stderr, "%s: no such adapter\n", name); continue; } if ((a = getAdapterConfig (fd, adapter, sas)) == NULL) { fprintf (stderr, "%s: cannot read adapter configuration: %s\n", name, megaErrorString ()); break; } if (healthCheck) { int adapterReported = 0; struct logical_drive_info *l; if (checkBattery && (!a->battery.healthy)) { if (!(adapterReported++)) describeAdapter (stdout, a, verbosity); } #ifndef MEGA_SAS_CTL /* Scan all physical devices. */ for (c = 0; c < a->num_channels; ++c) { for (i = 0; i <= MAX_MBOX_TARGET; ++i) { uint8_t target = (a->channel[c] << 4) | i; (void) getPhysicalDriveInfo (a, target, 1); } } #endif for (i = 0, l = a->logical; i < a->num_logicals; ++i, ++l) { int reportDrive = 0; if ((l->state != LdStateOptimal) && (l->state != LdStateDeleted)) ++reportDrive; if (reportDrive) { if (!(adapterReported++)) describeAdapter (stdout, a, verbosity); describeLogicalDrive (stdout, l, verbosity); } } for (i = 0; i < a->num_physicals; ++i) { struct physical_drive_info *d = a->physical_list[i]; int reportDrive = 0; struct log_page_list *log; if (d == NULL) break; if (!(d->present)) continue; //describePhysicalDrive (stdout, d, verbosity); /* check for drive problems */ if ((d->state == PdStateRebuild) || (d->span && (d->state == PdStateFailed))) ++reportDrive; if (d->media_errors) ++reportDrive; if (d->predictive_failures) ++reportDrive; /* check interesting log pages */ for (j = 0; j < sizeof (readLog) / sizeof (readLog[0]); ++j) { if (readLog[j] == 0) continue; if ((log = getDriveLogPage (d, j)) == NULL) continue; if (log->log.problem) ++reportDrive; } if (reportDrive) { if (!(adapterReported++)) describeAdapter (stdout, a, verbosity); describePhysicalDrive (stdout, d, verbosity); for (j = 0; j < sizeof (readLog) / sizeof (readLog[0]); ++j) { if (readLog[j] == 0) continue; if ((log = getDriveLogPage (d, j)) == NULL) continue; dumpLogPage (stdout, &log->log, NULL, 0, verbosity); } } } continue; } if (channel >= 0) { for (c = 0; c < a->num_channels; ++c) if (channel == a->channel[c]) break; if (c >= a->num_channels) { fprintf (stderr, "%s: no such channel\n", name); continue; } } if ((channel < 0) && (id < 0)) { struct logical_drive_info *l; int x; describeAdapter (stdout, a, verbosity); #ifndef MEGA_SAS_CTL /* Scan all physical devices. */ for (c = 0; c < a->num_channels; ++c) { for (i = 0; i <= MAX_MBOX_TARGET; ++i) { uint8_t target = (a->channel[c] << 4) | i; (void) getPhysicalDriveInfo (a, target, 1); } } #endif for (i = 0, l = a->logical; i < a->num_logicals; ++i, ++l) describeLogicalDrive (stdout, l, verbosity); x = 0; for (i = 0; i < a->num_physicals; ++i) { struct physical_drive_info *d = a->physical_list[i]; if (d == NULL) break; if (!(d->present)) continue; if (d->state == PdStateHotspare) { if (x == 0) fprintf (stdout, "hot spares :"); else if ((x % 8) == 0) fprintf (stdout, " :"); fprintf (stdout, " %-8s", d->name); if (((++x) % 8) == 0) fprintf (stdout, "\n"); } } if (x % 8) fprintf (stdout, "\n"); x = 0; for (i = 0; i < a->num_physicals; ++i) { struct physical_drive_info *d = a->physical_list[i]; if (d == NULL) break; if (!(d->present)) continue; if ((!(d->span)) && (d->state != PdStateHotspare)) { if (x == 0) fprintf (stdout, "unconfigured:"); else if ((x % 8) == 0) fprintf (stdout, " :"); fprintf (stdout, " %-8s", d->name); if (((++x) % 8) == 0) fprintf (stdout, "\n"); } } if (x % 8) fprintf (stdout, "\n"); } for (c = 0; c < a->num_channels; ++c) { if ((channel >= 0) && (channel != a->channel[c])) continue; #ifndef MEGA_SAS_CTL if (id >= 0) { uint8_t target = (a->channel[c] << 4) | id; (void) getPhysicalDriveInfo (a, target, 1); } else { /* Scan all devices on this channel. */ for (i = 0; i <= MAX_MBOX_TARGET; ++i) { uint8_t target = (a->channel[c] << 4) | i; (void) getPhysicalDriveInfo (a, target, 1); } } #endif for (i = 0; i < a->num_physicals; ++i) { struct physical_drive_info *d = a->physical_list[i]; if (d == NULL) break; if (d->channel != a->channel[c]) continue; if ((id >= 0) && (id != d->id)) continue; if (startSelfTest >= 0) { uint8_t diag[256]; memset (diag, 0, sizeof diag); if (megaScsiSendDiagnostic (&a->target, d->target, diag, sizeof diag, startSelfTest, 0, 0) < 0) fprintf (stderr, "self test: %s\n", megaErrorString ()); } if (reportPhysical) { describePhysicalDrive (stdout, d, verbosity); for (j = 0; j < sizeof (readLog) / sizeof (readLog[0]); ++j) { struct log_page_list *log; if (readLog[j] == 0) continue; if ((log = getDriveLogPage (d, j)) == NULL) continue; dumpLogPage (stdout, &log->log, &log->buf, sizeof (log->buf), verbosity); } } } } fprintf (stdout, "\n"); } return 0; } #if 0 if (0) { uint8_t modes[1024]; memset (modes, 0, sizeof modes); megaScsiModeSense (fd, adapter, target, modes, sizeof modes, 0, 0x3f, 0xff); } #endif megactl-0.4.5/megactl.metainfo.xml000066400000000000000000000045011465722425200171040ustar00rootroot00000000000000 com.github.namiltd.megactl CC0-1.0 megactl LSI Megaraid Control and Monitoring Tools

Provide tools to query hard drive and RAID volume status from PERC2, PERC3, PERC4 and PERC5 adapters.

https://github.com/namiltd/megactl/ Mieczyslaw Nalewaj lkmodule:megaraid lkmodule:megaraid_sas pci:v00001000d000010E7sv* pci:v00001000d000010E4sv* pci:v00001000d000010E3sv* pci:v00001000d000010E0sv* pci:v00001000d000010E6sv* pci:v00001000d000010E5sv* pci:v00001000d000010E2sv* pci:v00001000d000010E1sv* pci:v00001000d0000001Csv* pci:v00001000d0000001Bsv* pci:v00001000d00000017sv* pci:v00001000d00000016sv* pci:v00001000d00000015sv* pci:v00001000d00000014sv* pci:v00001000d00000053sv* pci:v00001000d00000052sv* pci:v00001000d000000CFsv* pci:v00001000d000000CEsv* pci:v00001000d0000005Fsv* pci:v00001000d0000005Dsv* pci:v00001000d0000002Fsv* pci:v00001000d0000005Bsv* pci:v00001028d00000015sv* pci:v00001000d00000413sv* pci:v00001000d00000071sv* pci:v00001000d00000073sv* pci:v00001000d00000079sv* pci:v00001000d00000078sv* pci:v00001000d0000007Csv* pci:v00001000d00000060sv* pci:v00001000d00000411sv* pci:v00008086d00001960sv* pci:v0000101Ed00009060sv* pci:v0000101Ed00009010sv*
megactl-0.4.5/megaioctl.c000066400000000000000000000362721465722425200152670ustar00rootroot00000000000000/* * Low-level interface to adapter information. * * Copyright (c) 2007 by Jefferson Ogata */ /* * 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, 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; see the file COPYING. If not, write to the Free Software * Foundation, 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. */ #include "megaioctl.h" /* Don't include */ #include #include #include #include #include #include /* This is arbitrary. */ #define MEGA_MAX_ADAPTERS 16 struct mega_adapter_map { uint8_t count; /* number of adapters found */ uint8_t host[MEGA_MAX_ADAPTERS]; /* map of adapter index to host number */ }; static struct mega_adapter_map *adapterMap = NULL; int megaErrno = 0; static u16 hostMap (u16 adapno) { if ((adapterMap == NULL) || (adapno >= adapterMap->count)) return 0; return adapterMap->host[adapno]; } static int doIoctl (struct mega_adapter_path *adapter, void *u) { switch (adapter->type) { case MEGA_ADAPTER_V2: case MEGA_ADAPTER_V34: return ioctl (adapter->fd, _IOWR(MEGAIOC_MAGIC, 0, struct uioctl_t), u); case MEGA_ADAPTER_V5: return ioctl (adapter->fd, MEGASAS_IOC_FIRMWARE, u); } return -1; } static int driverQuery (int fd, void *data, uint32_t len, uint8_t subop) { struct uioctl_t u; struct mega_adapter_path adapter; memset (&u, 0, sizeof u); u.outlen = len; u.ui.fcs.opcode = M_RD_DRIVER_IOCTL_INTERFACE; u.ui.fcs.subopcode = subop; u.ui.fcs.length = len; u.data = data; if (data) memset (data, 0, len); adapter.fd = fd; adapter.adapno = 0; adapter.type = MEGA_ADAPTER_V34; if (doIoctl (&adapter, &u) < 0) { megaErrno = errno; return -1; } return 0; } static int oldCommand (struct mega_adapter_path *adapter, void *data, uint32_t len, uint8_t cmd, uint8_t opcode, uint8_t subopcode) { struct uioctl_t u; int_mbox_t *m = (int_mbox_t *) &u.mbox; memset (&u, 0, sizeof u); u.outlen = len; u.ui.fcs.opcode = M_RD_IOCTL_CMD; u.ui.fcs.adapno = MKADAP(hostMap (adapter->adapno)); u.data = data; m->cmd = cmd; m->opcode = opcode; m->subopcode = subopcode; assert(UINT32_MAX > (uint32_t) data); m->xferaddr = (uint32_t) data; if (data) memset (data, 0, len); if (doIoctl (adapter, &u) < 0) { megaErrno = errno; return -1; } return 0; } static int newCommand (struct mega_adapter_path *adapter, void *data, uint32_t len, uint8_t cmd, uint8_t opcode, uint8_t subopcode) { struct uioctl_t u; int_mbox_t *m = (int_mbox_t *) &u.mbox; memset (&u, 0, sizeof u); u.outlen = len; u.ui.fcs.opcode = M_RD_IOCTL_CMD_NEW; u.ui.fcs.adapno = MKADAP(hostMap (adapter->adapno)); u.ui.fcs.buffer = data; u.ui.fcs.length = len; u.data = data; m->cmd = cmd; m->opcode = opcode; m->subopcode = subopcode; assert(UINT32_MAX > (uint32_t) data); m->xferaddr = (uint32_t) data; if (data) memset (data, 0, len); if (doIoctl (adapter, &u) < 0) { megaErrno = errno; return -1; } return 0; } static int sasCommand (struct mega_adapter_path *adapter, void *data, uint32_t len, uint32_t opcode, uint16_t flags, void *mbox, uint32_t mboxlen) { struct megasas_iocpacket u; struct megasas_dcmd_frame *f = (struct megasas_dcmd_frame *) &u.frame; memset (&u, 0, sizeof u); u.host_no = hostMap (adapter->adapno); f->cmd = MFI_CMD_DCMD; f->flags = (u16) flags; f->opcode = (u32) opcode; if ((data != NULL) && (len > 0)) { u.sgl_off = ((void *) &f->sgl) - ((void *) f); u.sge_count = 1; u.sgl[0].iov_base = data; u.sgl[0].iov_len = len; f->sge_count = 1; assert(UINT32_MAX > (uint32_t) data); f->data_xfer_len = (u32) len; f->sgl.sge32[0].phys_addr = (u32) data; f->sgl.sge32[0].length = (u32) len; } if (mbox != NULL) memcpy (&f->mbox, mbox, mboxlen); if (doIoctl (adapter, &u) < 0) { megaErrno = errno; return -1; } return f->cmd_status; } static int passthruCommand (struct mega_adapter_path *adapter, void *data, uint32_t len, uint8_t target, uint8_t *cdb, uint8_t cdblen) { if ((adapter->type == MEGA_ADAPTER_V2) || (adapter->type == MEGA_ADAPTER_V34)) { struct uioctl_t u; int_mbox_t *m = (int_mbox_t *) &u.mbox; mraid_passthru_t *p = &u.pthru; memset (&u, 0, sizeof u); u.outlen = len; u.ui.fcs.opcode = M_RD_IOCTL_CMD; u.ui.fcs.adapno = MKADAP(hostMap (adapter->adapno)); u.data = data; m->cmd = MBOXCMD_PASSTHRU; assert(UINT32_MAX > (uint32_t) p); m->xferaddr = (uint32_t) p; p->timeout = 3; p->ars = 1; p->target = target; assert(UINT32_MAX > (uint32_t) data); p->dataxferaddr = (uint32_t) data; p->dataxferlen = len; p->scsistatus = 239; /* HMMM */ memcpy (p->cdb, cdb, cdblen); p->cdblen = cdblen; if (data) memset (data, 0, len); if (doIoctl (adapter, &u) < 0) { megaErrno = errno; return -1; } if (m->status) { megaErrno = - (m->status); return -1; } if (p->scsistatus & CHECK_CONDITION) { megaErrno = - CHECK_CONDITION; return -1; } if ((p->scsistatus & STATUS_MASK) != GOOD) { megaErrno = - (p->scsistatus & STATUS_MASK); return -1; } } else { struct megasas_iocpacket u; struct megasas_pthru_frame *f = (struct megasas_pthru_frame *) &u.frame; memset (&u, 0, sizeof u); u.host_no = hostMap (adapter->adapno); f->cmd = MFI_CMD_PD_SCSI_IO; f->target_id = target; f->cdb_len = cdblen; f->flags = MFI_FRAME_DIR_READ; memcpy (f->cdb, cdb, cdblen); if ((data != NULL) && (len > 0)) { u.sgl_off = ((void *) &f->sgl) - ((void *) f); u.sge_count = 1; u.sgl[0].iov_base = data; u.sgl[0].iov_len = len; f->sge_count = 1; assert(UINT32_MAX > (uint32_t) len); f->data_xfer_len = (u32) len; f->sgl.sge32[0].phys_addr = (u32) data; f->sgl.sge32[0].length = (u32) len; } if (doIoctl (adapter, &u) < 0) { megaErrno = errno; return -1; } if (f->cmd_status) { megaErrno = - (f->cmd_status); return -1; } if ((f->scsi_status & STATUS_MASK) != GOOD) { megaErrno = - (f->scsi_status & STATUS_MASK); return -1; } } return 0; } int megaScsiDriveInquiry (struct mega_adapter_path *adapter, uint8_t target, void *data, uint32_t len, uint8_t pageCode, uint8_t evpd) { uint8_t cdb[6]; cdb[0] = INQUIRY; cdb[1] = (evpd != 0); cdb[2] = pageCode; cdb[3] = (len >> 8) & 0xff; cdb[4] = len & 0xff; cdb[5] = 0; return passthruCommand (adapter, data, len, target, cdb, sizeof cdb); } int megaScsiModeSense (struct mega_adapter_path *adapter, uint8_t target, void *data, uint32_t len, uint8_t pageControl, uint8_t page, uint8_t subpage) { #ifdef USE_MODE_SENSE_6 uint8_t cdb[6]; cdb[0] = MODE_SENSE; cdb[1] = 0; /* dbd in bit 3 */ cdb[2] = ((pageControl & 0x3) << 6) | (page & 0x3f); cdb[3] = subpage; cdb[4] = len & 0xff; cdb[5] = 0; #else uint8_t cdb[10]; cdb[0] = MODE_SENSE_10; cdb[1] = 0; /* llbaa in bit 4, dbd in bit 3 */ cdb[2] = ((pageControl & 0x3) << 6) | (page & 0x3f); cdb[3] = subpage; cdb[4] = 0; cdb[5] = 0; cdb[6] = 0; cdb[7] = (len >> 8) & 0xff; cdb[8] = len & 0xff; cdb[9] = 0; #endif return passthruCommand (adapter, data, len, target, cdb, sizeof cdb); } int megaScsiLogSense (struct mega_adapter_path *adapter, uint8_t target, void *data, uint32_t len, uint8_t pageControl, uint8_t page, uint16_t parameterPointer) { uint8_t cdb[10]; cdb[0] = LOG_SENSE; cdb[1] = 0; /* ppc in bit 1, sp in bit 1 */ cdb[2] = ((pageControl & 0x3) << 6) | (page & 0x3f); cdb[3] = 0; cdb[4] = 0; cdb[5] = (parameterPointer >> 8) & 0xff; cdb[6] = parameterPointer & 0xff; cdb[7] = (len >> 8) & 0xff; cdb[8] = len & 0xff; cdb[9] = 0; return passthruCommand (adapter, data, len, target, cdb, sizeof cdb); } int megaScsiSendDiagnostic (struct mega_adapter_path *adapter, uint8_t target, void *data, uint32_t len, uint8_t testCode, uint8_t unitOffline, uint8_t deviceOffline) { uint8_t cdb[6]; cdb[0] = SEND_DIAGNOSTIC; cdb[1] = ((testCode & 0x7) << 5) | ((deviceOffline != 0) << 1) | (unitOffline != 0); cdb[2] = 0; cdb[3] = 0; cdb[4] = 0; cdb[5] = 0; return passthruCommand (adapter, data, len, target, cdb, sizeof cdb); } int megaGetAdapterConfig8 (struct mega_adapter_path *adapter, disk_array_8ld_span8_t *config) { return oldCommand (adapter, config, sizeof (*config), NEW_READ_CONFIG_8LD, 0, 0); } int megaGetAdapterConfig40 (struct mega_adapter_path *adapter, disk_array_40ld_t *config) { return newCommand (adapter, config, sizeof (*config), FC_NEW_CONFIG, OP_DCMD_READ_CONFIG, 0); } int megaGetAdapterInquiry (struct mega_adapter_path *adapter, mraid_inquiry1_t *data) { return oldCommand (adapter, data, sizeof (*data), MBOXCMD_ADAPTERINQ, 0, 0); } int megaGetAdapterExtendedInquiry (struct mega_adapter_path *adapter, mraid_extinq1_t *data) { return oldCommand (adapter, data, sizeof (*data), MBOXCMD_ADPEXTINQ, 0, 0); } int megaGetAdapterEnquiry3 (struct mega_adapter_path *adapter, mraid_inquiry3_t *data) { return newCommand (adapter, data, sizeof (*data), FC_NEW_CONFIG, NC_SUBOP_ENQUIRY3, 0); } int megaGetPredictiveMap (struct mega_adapter_path *adapter, struct mega_predictive_map *data) { return oldCommand (adapter, data, sizeof (*data), MAIN_MISC_OPCODE, 0x0f, 0); } int megaGetDriveErrorCount (struct mega_adapter_path *adapter, uint8_t target, struct mega_physical_drive_error_info *data) { return oldCommand (adapter, data, sizeof (*data), 0x77, 0, target); } int megaSasGetDeviceList (struct mega_adapter_path *adapter, struct mega_device_list_sas **data) { unsigned char buf[sizeof(struct mega_device_list_sas)]; uint32_t len; if (sasCommand (adapter, buf, sizeof buf, 0x02010000, MFI_FRAME_DIR_READ, NULL, 0) < 0) return -1; len = ((struct mega_device_list_sas *) buf)->length; if ((*data = (struct mega_device_list_sas *) malloc (len)) == NULL) { megaErrno = errno; return -1; } return sasCommand (adapter, *data, len, 0x02010000, MFI_FRAME_DIR_READ, NULL, 0); } int megaSasGetDiskInfo (struct mega_adapter_path *adapter, uint8_t target, struct mega_physical_disk_info_sas *data) { uint8_t mbox[0xc]; memset (&mbox, 0, sizeof mbox); mbox[0] = target; return sasCommand (adapter, data, sizeof (*data), 0x02020000, MFI_FRAME_DIR_READ, mbox, sizeof mbox); } int megaSasGetArrayConfig (struct mega_adapter_path *adapter, struct mega_array_config_sas *data) { unsigned char buf[0x20]; uint32_t len; if (sasCommand (adapter, buf, sizeof buf, 0x04010000, MFI_FRAME_DIR_READ, NULL, 0) < 0) return -1; len = ((struct mega_array_header_sas *) buf)->length; if ((data->header = (struct mega_array_header_sas *) malloc (len)) == NULL) { megaErrno = errno; return -1; } if (sasCommand (adapter, data->header, len, 0x04010000, MFI_FRAME_DIR_READ, NULL, 0) < 0) { megaErrno = errno; return -1; } data->span = (struct mega_array_span_def_sas *) (data->header + 1); data->disk = (struct mega_array_disk_def_sas *) (data->span + data->header->num_span_defs); data->hotspare = (struct mega_array_hotspare_def_sas *) (data->disk + data->header->num_disk_defs); return 0; } int megaSasGetBatteryInfo (struct mega_adapter_path *adapter, struct mega_battery_info_sas *data) { if (sasCommand (adapter, &(data->state), sizeof (data->state), 0x05010000, MFI_FRAME_DIR_READ, NULL, 0) < 0) return -1; if (sasCommand (adapter, &(data->capacity), sizeof (data->capacity), 0x05020000, MFI_FRAME_DIR_READ, NULL, 0) < 0) return -1; if (sasCommand (adapter, &(data->design), sizeof (data->design), 0x05030000, MFI_FRAME_DIR_READ, NULL, 0) < 0) return -1; return sasCommand (adapter, &(data->properties), sizeof (data->properties), 0x05050100, MFI_FRAME_DIR_READ, NULL, 0); } int megaGetDriverVersion (int fd, uint32_t *version) { return driverQuery (fd, version, sizeof (*version), 'e'); } int megaGetNumAdapters (int fd, uint32_t *numAdapters, int sas) { static struct mega_adapter_map realMap; uint8_t k; uint8_t count; if (sas) { if (adapterMap == NULL) { struct mega_adapter_map fakeMap; /* initialize fake map to 1-to-1 map */ for (k = 0; k < MEGA_MAX_ADAPTERS; ++k) fakeMap.host[k] = k; fakeMap.count = k; adapterMap = &fakeMap; /* ping all possible adapters to build real map */ count = 0; for (k = 0; k < MEGA_MAX_ADAPTERS; ++k) if (megaSasAdapterPing (fd, k) >= 0) realMap.host[count++] = k; realMap.count = count; adapterMap = &realMap; } } else { if (adapterMap == NULL) { if (driverQuery (fd, &count, sizeof (count), 'm') < 0) return -1; if (count > MEGA_MAX_ADAPTERS) count = MEGA_MAX_ADAPTERS; for (k = 0; k < count; ++k) realMap.host[k] = k; realMap.count = count; adapterMap = &realMap; } } *numAdapters = adapterMap->count; return 0; } int megaGetAdapterProductInfo (int fd, uint8_t adapno, mraid_pinfo_t *data) { struct mega_adapter_path adapter; adapter.fd = fd; adapter.adapno = adapno; adapter.type = MEGA_ADAPTER_V34; return newCommand (&adapter, data, sizeof (*data), FC_NEW_CONFIG, NC_SUBOP_PRODUCT_INFO, 0); } int megaSasGetAdapterProductInfo (int fd, uint8_t adapno, struct megasas_ctrl_info *data) { struct mega_adapter_path adapter; adapter.fd = fd; adapter.adapno = adapno; adapter.type = MEGA_ADAPTER_V5; return sasCommand (&adapter, data, sizeof (*data), MR_DCMD_CTRL_GET_INFO, MFI_FRAME_DIR_READ, NULL, 0); } int megaSasAdapterPing (int fd, uint8_t adapno) { struct mega_adapter_path adapter; unsigned char data[0xc4]; adapter.fd = fd; adapter.adapno = adapno; adapter.type = MEGA_ADAPTER_V5; return sasCommand (&adapter, data, sizeof data, 0x04060100, MFI_FRAME_DIR_READ, NULL, 0); } char *megaErrorString (void) { if (megaErrno >= 0) return strerror (megaErrno); switch (-megaErrno) { case CHECK_CONDITION: return "scsi command status CHECK_CONDITION"; break; case CONDITION_GOOD: return "scsi command status CONDITION_GOOD"; break; case BUSY: return "scsi command status BUSY"; break; case INTERMEDIATE_GOOD: return "scsi command status INTERMEDIATE_GOOD"; break; case INTERMEDIATE_C_GOOD: return "scsi command status INTERMEDIATE_C_GOOD"; break; case RESERVATION_CONFLICT: return "scsi command status RESERVATION_CONFLICT"; break; case COMMAND_TERMINATED: return "scsi command status COMMAND_TERMINATED"; break; case QUEUE_FULL: return "scsi command status QUEUE_FULL"; break; default: return "scsi command status unknown"; break; } } megactl-0.4.5/megaioctl.h000066400000000000000000000077671465722425200153030ustar00rootroot00000000000000#ifndef _MEGAIOCTL_H #define _MEGAIOCTL_H /* * Definitions for low-level adapter interface. * * Copyright (c) 2007 by Jefferson Ogata */ /* * 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, 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; see the file COPYING. If not, write to the Free Software * Foundation, 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. */ #include "mega.h" /* Old-style ioctl structure for megaraid 1 & 2 drivers. Cribbed from version 1 megaraid.h. */ #pragma pack(1) struct uioctl_t { uint32_t inlen; uint32_t outlen; union { uint8_t fca[16]; struct { uint8_t opcode; uint8_t subopcode; uint16_t adapno; #if BITS_PER_LONG == 32 uint8_t *buffer; uint8_t pad[4]; #endif #if BITS_PER_LONG == 64 uint8_t *buffer; #endif uint32_t length; } fcs; } ui; uint8_t mbox[18]; /* 16 bytes + 2 status bytes */ mraid_passthru_t pthru; #if BITS_PER_LONG == 32 char *data; /* buffer <= 4096 for 0x80 commands */ char pad[4]; #endif #if BITS_PER_LONG == 64 char *data; #endif }; #pragma pack() /* Timestamps in the megaraid_sas event log are offset by this quantity. This is the epoch time of 2000-01-01T00:00:00 +0000. */ #define MEGA_SAS_TIME_OFFSET 0x386d4380 extern int megaErrno; extern int megaScsiDriveInquiry (struct mega_adapter_path *adapter, uint8_t target, void *data, uint32_t len, uint8_t pageCode, uint8_t evpd); extern int megaScsiModeSense (struct mega_adapter_path *adapter, uint8_t target, void *data, uint32_t len, uint8_t pageControl, uint8_t page, uint8_t subpage); extern int megaScsiLogSense (struct mega_adapter_path *adapter, uint8_t target, void *data, uint32_t len, uint8_t pageControl, uint8_t page, uint16_t parameterPointer); extern int megaScsiSendDiagnostic (struct mega_adapter_path *adapter, uint8_t target, void *data, uint32_t len, uint8_t testCode, uint8_t unitOffline, uint8_t deviceOffline); extern int megaGetAdapterConfig8 (struct mega_adapter_path *adapter, disk_array_8ld_span8_t *data); extern int megaGetAdapterConfig40 (struct mega_adapter_path *adapter, disk_array_40ld_t *data); extern int megaGetAdapterInquiry (struct mega_adapter_path *adapter, mraid_inquiry1_t *data); extern int megaGetAdapterExtendedInquiry (struct mega_adapter_path *adapter, mraid_extinq1_t *data); extern int megaGetAdapterEnquiry3 (struct mega_adapter_path *adapter, mraid_inquiry3_t *data); extern int megaGetPredictiveMap (struct mega_adapter_path *adapter, struct mega_predictive_map *data); extern int megaGetDriveErrorCount (struct mega_adapter_path *adapter, uint8_t target, struct mega_physical_drive_error_info *data); extern int megaSasGetDeviceList (struct mega_adapter_path *adapter, struct mega_device_list_sas **data); extern int megaSasGetDiskInfo (struct mega_adapter_path *adapter, uint8_t target, struct mega_physical_disk_info_sas *data); extern int megaSasGetArrayConfig (struct mega_adapter_path *adapter, struct mega_array_config_sas *data); extern int megaSasGetBatteryInfo (struct mega_adapter_path *adapter, struct mega_battery_info_sas *data); extern int megaGetDriverVersion (int fd, uint32_t *version); /* You must call megaGetNumAdapters() before you issue any other inquiries, other than megaGetDriverVersion(). */ extern int megaGetNumAdapters (int fd, uint32_t *numAdapters, int sas); extern int megaGetAdapterProductInfo (int fd, uint8_t adapno, mraid_pinfo_t *info); extern int megaSasGetAdapterProductInfo (int fd, uint8_t adapno, struct megasas_ctrl_info *info); extern int megaSasAdapterPing (int fd, uint8_t adapno); extern char *megaErrorString (void); #endif megactl-0.4.5/megaraid000077700000000000000000000000001465722425200226642kernel-2.6.9-55.0.2.EL/megaraid-2.20.4.6-rh2ustar00rootroot00000000000000megactl-0.4.5/megarpt000077500000000000000000000023431465722425200145340ustar00rootroot00000000000000#!/bin/sh # # megarpt # # Emails a message to root with megaraid configuration and any # output from a health check. Useful as a nightly cron job. # # Author: Jefferson Ogata (JO317) # Date: 2007/08/20 VERSION='0.3' MEGACTL=/root/megactl DEVICE=/dev/megadev0 DEVICENAME=megadev DEVICEPERM=644 ME=`basename $0` if [ -x $MEGACTL ]; then MEGACTLVERSION=`$MEGACTL -V` else echo "No megactl program in $MEGACTL" >&2 exit 1 fi MAJOR=`grep "$DEVICENAME" /proc/devices | awk '{print $1}'` if [ -n "$MAJOR" -a ! -e "$DEVICE" ]; then mknod "$DEVICE" c "$MAJOR" 0 chmod "$DEVICEPERM" "$DEVICE" fi if [ -e "$DEVICE" ]; then WARN= HOST=`/bin/uname -n` DATE=`/bin/date '+%Y/%m/%d %H:%M:%S %Z'` HC=/tmp/megactl.$$ $MEGACTL -vH > $HC 2>/dev/null if [ -s $HC ]; then WARN=' **WARNING**' fi ( if [ -s $HC ]; then echo "megaraid health check" echo "---------------------" cat $HC echo echo fi echo "megaraid configuration" echo "----------------------" $MEGACTL -vp echo echo "--------------" echo "$ME version: $VERSION" echo "megactl version: $MEGACTLVERSION" ) 2>/dev/null | /bin/mail -s "RAID report:$WARN $HOST $DATE" root rm -f $HC fi megactl-0.4.5/megasasctl.1000066400000000000000000000054461465722425200153630ustar00rootroot00000000000000.\" Text automatically generated by txt2man .TH megasasctl 1 "03 March 2024" "" .SH NAME megasasctl \- diagnostics on megaraid adapters and attached disks. .SH SYNOPSIS megasasctl [\fB-vest\fP] [\fB-H\fP] [\fB-l\fP log-page-nr] [\fB-T\fP long|short] [target \.\.\.] .PP Reports diagnostics on megaraid adapters and attached disks. Permits dumping of controller log pages for inspection of error, temperature, and self-test conditions, initiates self-test diagnostics, and documents adapter and logical drive configuration. Target devices may be adapters, (e.g. a0), enclosures (e.g. a0e0), or individual disks (e.g. a0e0s0). If no target is specified, reports configuration and drive state on all adapters. If a target matches a collection of disks, operations are applied to all matching devices. Options are: .TP .B \fB-v\fP Increase program verbosity. .TP .B \fB-e\fP Dump read (0x03), write (0x02), and verify (0x05) error log pages. .TP .B \fB-s\fP Dump self-test (0x10) log page. .TP .B \fB-t\fP Dump temperature (0x0d) log page. .TP .B \fB-l\fP page Dump the specified log page. Log page 0 documents the log pages the device supports. .TP .B \fB-p\fP Do not report physical disks. Reports only adapters and logical drives. Useful for concisely documenting adapter configuration. .TP .B \fB-T\fP test Initiate the background short or long self-test procedure. The test may take up to an hour to complete, but does not inhibit access to the device. The test may be monitored using the \fB-s\fP option. .TP .B \fB-H\fP Perform an adapter health check. Inspects state of all logical and physical drives and battery backup unit and reports problem conditions. If all is well, generates no output. Useful in a cron job. .TP .B \fB-B\fP When performing health check, do not treat battery problems as failures. .TP .B \fB-V\fP Show version. .PP N.B. The background long self test is a useful tool for diagnosing problems with individual disks. But be cautious with program usage. "megasasctl \fB-T\fP long" with no targets will initiate a background long self test on every drive on every adapter. This may not be what you want. .PP By default, the health check option inspects log pages 0x02, 0x03, and 0x05 for uncorrected read, write, and verify errors, 0x0d for excess temperature conditions, and 0x10 for failed self tests. If, however, any of the log page options is specified, only the designated log pages are inspected. .PP This program requires the device file /dev/megaraid_sas_ioctl_node to be present on the system. If your system does not have this device file, you may create it either by executing LSI's "MegaCli" program once, or by locating the megadev_sas_ioctl entry in /proc/devices and creating /dev/megaraid_sas_ioctl_node as a character device with suitable permissions with a matching major device number and a minor number of 0. megactl-0.4.5/megasasrpt000077500000000000000000000024001465722425200152350ustar00rootroot00000000000000#!/bin/sh # # megarpt # # Emails a message to root with megaraid configuration and any # output from a health check. Useful as a nightly cron job. # # Author: Jefferson Ogata (JO317) # Date: 2007/08/20 VERSION='0.3' MEGACTL=/root/megasasctl DEVICE=/dev/megaraid_sas_ioctl_node DEVICENAME=megaraid_sas_ioctl DEVICEPERM=400 ME=`basename $0` if [ -x $MEGACTL ]; then MEGACTLVERSION=`$MEGACTL -V` else echo "No megactl program in $MEGACTL" >&2 exit 1 fi MAJOR=`grep "$DEVICENAME" /proc/devices | awk '{print $1}'` if [ -n "$MAJOR" -a ! -e "$DEVICE" ]; then mknod "$DEVICE" c "$MAJOR" 0 chmod "$DEVICEPERM" "$DEVICE" fi if [ -e "$DEVICE" ]; then WARN= HOST=`/bin/uname -n` DATE=`/bin/date '+%Y/%m/%d %H:%M:%S %Z'` HC=/tmp/megactl.$$ $MEGACTL -vH > $HC 2>/dev/null if [ -s $HC ]; then WARN=' **WARNING**' fi ( if [ -s $HC ]; then echo "megaraid health check" echo "---------------------" cat $HC echo echo fi echo "megaraid configuration" echo "----------------------" $MEGACTL -vp echo echo "--------------" echo "$ME version: $VERSION" echo "megactl version: $MEGACTLVERSION" ) 2>/dev/null | /bin/mail -s "RAID report:$WARN $HOST $DATE" root rm -f $HC fi megactl-0.4.5/megatrace.c000066400000000000000000000331201465722425200152400ustar00rootroot00000000000000/* * Main program for ioctl tracer. * * Copyright (c) 2007 by Jefferson Ogata */ /* * 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, 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; see the file COPYING. If not, write to the Free Software * Foundation, 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. */ /******************************************************************** megatrace Program to ptrace another program and inspect megaraid-related ioctl syscalls it makes. Author: Jefferson Ogata (JO317) Date: 2006/01/23 TODO: Fixes for 64-bit systems. ********************************************************************/ #include "mega.h" #include "megaioctl.h" #include #include #include #include #include #include #include #include #include #include #include #include #include #include #include #include "callinfo.h" #include "dumpbytes.h" enum state { UNTRACED, INBOUND, OUTBOUND }; static inline void copyout (void *buf, size_t len, pid_t pid, uint32_t addr) { off_t k; uint32_t *z = (uint32_t *) buf; uint32_t sd; for (k = 0; k < (len + 3) / 4; ++k) { sd = ptrace (PTRACE_PEEKDATA, pid, (void *) (addr + 4 * k), 0); z[k] = sd; } } static inline void copyin (void *buf, size_t len, pid_t pid, uint32_t addr) { off_t k; uint32_t *z = (uint32_t *) buf; for (k = 0; k < (len + 3) / 4; ++k) ptrace (PTRACE_POKEDATA, pid, (void *) (addr + 4 * k), z[k]); } int main (int argc, char **argv, char **environ) { pid_t pid; int state = UNTRACED; struct timeval starttv; int printproc = 0; if ((pid = fork ()) == 0) { ptrace (PTRACE_TRACEME); ++argv; execvp (argv[0], argv); fprintf (stderr, "execve: %s: %s\n", argv[0], strerror (errno)); _exit (1); } if (pid < 0) { fprintf (stderr, "fork: %s\n", strerror (errno)); exit (1); } gettimeofday (&starttv, NULL); /*fprintf (stderr, "%d\n", sizeof (mega_host_config));*/ while (1) { pid_t w; int st; w = waitpid (pid, &st, /*WNOHANG*/ 0); if (w == 0) { fprintf (stderr, "wait: no child\n"); usleep (10); continue; } if (w < 0) { fprintf (stderr, "wait: %s\n", strerror (errno)); exit (1); } if (WIFEXITED (st)) { if (printproc) fprintf (stderr, "child exited with status %d\n", WEXITSTATUS (st)); break; } if (WIFSTOPPED (st)) { if (WSTOPSIG (st) == SIGTRAP) { struct timeval tv; long secs; long usecs; char tbuf[1024]; int printcalls = (getenv ("LOG_CALLS") != NULL); int printthis = 0; int printregs = (getenv ("LOG_REGS") != NULL); struct user_regs_struct r; u32 call; gettimeofday (&tv, NULL); secs = tv.tv_sec - starttv.tv_sec; usecs = tv.tv_usec - starttv.tv_usec; if (usecs < 0) { usecs += 1000000; secs -= 1; } snprintf (tbuf, sizeof tbuf, "%ld.%06ld", secs, usecs); if (ptrace (PTRACE_GETREGS, pid, 0, &r) < 0) { fprintf (stderr, "ptrace:getregs: %s\n", strerror (errno)); exit (1); } call = r.orig_eax; /*printthis = call == SYS_ioctl;*/ if (state == INBOUND) { if (printcalls || printthis) { if ((call >= 0) && (call < callmax) && (callinfo[call].name != NULL)) fprintf (stderr, "%s()", callinfo[call].name); else fprintf (stderr, "syscall(%u)", call); } } if (state == OUTBOUND) { if ((call < 0) || (call > callmax) || (callinfo[call].name == NULL)) { fprintf (stderr, "= 0x%08lx\n", (unsigned long) r.eax); } else { if (callinfo[call].ptrval) { if (printcalls || printthis) fprintf (stderr, " = 0x%08lx\n", r.eax); } else { long rv = r.eax; if (rv < 0) { if (printcalls || printthis) fprintf (stderr, " = -1 (%s)\n", strerror (-rv)); } else { if (printcalls || printthis) fprintf (stderr, " = %lu\n", rv); } } } } if ((call == SYS_ioctl) && ((state == OUTBOUND) || getenv ("LOG_INBOUND"))) { unsigned int len = 16; unsigned char buf[65536]; unsigned long fd = r.ebx; unsigned long ioc = r.ecx; unsigned int iocdir = _IOC_DIR(ioc); unsigned char ioctype = _IOC_TYPE(ioc); unsigned int iocnr = _IOC_NR(ioc); unsigned int iocsize = _IOC_SIZE(ioc); char *iocdirname; unsigned long arg = r.edx; switch (iocdir) { case _IOC_READ: iocdirname = "r"; break; case _IOC_WRITE: iocdirname = "w"; break; case _IOC_READ|_IOC_WRITE: iocdirname = "rw"; break; default: iocdirname = "none"; break; } fprintf (stderr, "%s: ioctl(%ld, _IOC(\"%s\",'%c',0x%02x,0x%02x), 0x%08lx)", tbuf, fd, iocdirname, ioctype, iocnr, iocsize, arg); if (state == OUTBOUND) fprintf (stderr, " = %ld\n", r.eax); if (getenv ("LOG_INBOUND")) fprintf (stderr, "\n"); if (_IOC_SIZE(ioc) > len) len = _IOC_SIZE(ioc); if (len > sizeof buf) len = sizeof buf; if (printregs) fprintf (stderr, " ebx=%08lx ecx=%08lx edx=%08lx esi=%08lx edi=%08lx ebp=%08lx eax=%08lx ds=%04x __ds=%04x es=%04x __es=%04x fs=%04x __fs=%04x gs=%04x __gs=%04x orig_eax=%08lx eip=%08lx cs=%04x __cs=%04x eflags=%08lx esp=%08lx ss=%04x __ss=%04x\n", r.ebx, r.ecx, r.edx, r.esi, r.edi, r.ebp, r.eax, r.ds, r.__ds, r.es, r.__es, r.fs, r.__fs, r.gs, r.__gs, r.orig_eax, r.eip, r.cs, r.__cs, r.eflags, r.esp, r.ss, r.__ss); copyout (buf, len, pid, r.edx); if ((ioctype == 'm') && (iocnr == 0) && (iocsize == sizeof (struct uioctl_t))) { /* megaraid_mbox-style ioctl */ struct uioctl_t *uio = (struct uioctl_t *) buf; mraid_passthru_t p = uio->pthru; unsigned long datalen; int_mbox_t *m = (int_mbox_t *) uio->mbox; fprintf (stderr, " uio:\tinlen %u, outlen %u, { op %02x, subop %02x, adap %04x, buf %08lx, len %u }, data %08lx\n", uio->inlen, uio->outlen, uio->ui.fcs.opcode, uio->ui.fcs.subopcode, uio->ui.fcs.adapno, (unsigned long) uio->ui.fcs.buffer, uio->ui.fcs.length, (unsigned long) uio->data); dumpbytes (stderr, uio, sizeof (*uio), uio, "uioc"); fprintf (stderr, " mbox:\tcmd %02x, cmdid %02x, op %02x, subop %02x, lba %08x, xfer %08x, ldrv %02x, numsge %u, busy %u, nstatus %u, status %u\n", m->cmd, m->cmdid, m->opcode, m->subopcode, m->lba, m->xferaddr, m->logdrv, m->rsvd[0], m->rsvd[2], m->numstatus, m->status); dumpbytes (stderr, uio->mbox, sizeof (uio->mbox), uio->mbox, "mbox"); fprintf (stderr, " pass:\ttimeout %u, ars %u, isldrv %u, ldrv %u, chan %u, targ %02x, qtag %u, qact %u, numsge %u, scsistat %u\n", p.timeout, p.ars, p.islogical, p.logdrv, p.channel, p.target, p.queuetag, p.queueaction, p.numsge, p.scsistatus); dumpbytes (stderr, &p.cdb, p.cdblen, &p.cdb, "cdb"); dumpbytes (stderr, &p.reqsensearea, p.reqsenselen, &p.reqsensearea, "rqsense"); dumpbytes (stderr, &uio->pthru, sizeof (uio->pthru), &uio->pthru, "pass"); if (p.dataxferaddr && p.dataxferlen) { unsigned char data[4096]; unsigned long len = p.dataxferlen; if (len > sizeof data) len = sizeof data; copyout (data, len, pid, p.dataxferaddr); dumpbytes (stderr, data, len, (void *) p.dataxferaddr, "parm"); } datalen = uio->ui.fcs.length; if (datalen < uio->outlen) datalen = uio->outlen; if (datalen > sizeof buf) datalen = sizeof buf; if (datalen < 16) datalen = 16; if (datalen && uio->data) { // if ((state == INBOUND) && (datalen > uio->inlen)) // datalen = uio->inlen; // else if ((state == OUTBOUND) && (datalen > uio->outlen)) // datalen = uio->outlen; // if (datalen) // { copyout (buf, datalen, pid, (unsigned long) uio->data); dumpbytes (stderr, buf, datalen, uio->data, "data"); // } } } else if ((ioctype == 'M') && (iocnr == 1) && (iocsize == sizeof (struct megasas_iocpacket))) { /* megaraid_sas-style ioctl */ struct megasas_iocpacket *iocp = (struct megasas_iocpacket *) buf; struct megasas_header *mh = &(iocp->frame.hdr); int k; u8 cmd; struct megasas_sge32 *sge = (struct megasas_sge32 *) ((u32) (&iocp->frame) + iocp->sgl_off); int log = 1; cmd = mh->cmd; if (cmd == MFI_CMD_DCMD) { struct megasas_dcmd_frame *f = (struct megasas_dcmd_frame *) mh; if ((getenv ("LOG_OPCODE") != 0) && (strtoul (getenv ("LOG_OPCODE"), NULL, 0) != f->opcode)) { log = 0; } /* Lie like a rug. */ if ((f->opcode == 0x02020000) && (state == OUTBOUND)) { u32 sgbase = sge[0].phys_addr; size_t sglen = sge[0].length; struct mega_physical_disk_info_sas disk; if (sglen > sizeof disk) sglen = sizeof disk; copyout (&disk, sglen, pid, sgbase); //if (!((disk.device_id == 16) || (disk.device_id == 15))) // log = 0; copyin (&disk, sglen, pid, sgbase); } if ((f->opcode == 0x04010000) && (state == OUTBOUND)) { u32 sgbase = sge[0].phys_addr; size_t sglen = sge[0].length; u8 config[4096]; if (sglen > sizeof config) sglen = sizeof config; copyout (&config, sglen, pid, sgbase); { struct mega_array_header_sas *header = (struct mega_array_header_sas *) config; struct mega_array_span_def_sas *span = (struct mega_array_span_def_sas *) (header + 1); struct mega_array_disk_def_sas *disk = (struct mega_array_disk_def_sas *) (span + header->num_span_defs); struct mega_array_hotspare_def_sas *hotspare = (struct mega_array_hotspare_def_sas *) (disk + header->num_disk_defs); int k; for (k = 0; k < header->num_disk_defs; ++k) { // disk[k].state = 0xffff; } } copyin (&config, sglen, pid, sgbase); } if ((f->opcode == 0x05010000) && (state == OUTBOUND)) { u32 sgbase = sge[0].phys_addr; size_t sglen = sge[0].length; struct mega_battery_state_sas bs; if (sglen > sizeof bs) sglen = sizeof bs; copyout (&bs, sglen, pid, sgbase); if (getenv ("BATTERY_X")) bs.type = strtoul (getenv ("BATTERY_X"), NULL, 0); if (getenv ("BATTERY_Y")) bs.foo = strtoul (getenv ("BATTERY_Y"), NULL, 0); bs.over_charged = 1; copyin (&bs, sglen, pid, sgbase); } if (log) { fprintf (stderr, " host %d, off 0x%04x, count %d, sense_off 0x%08x, sense_len 0x%08x\n", iocp->host_no, iocp->sgl_off, iocp->sge_count, iocp->sense_off, iocp->sense_len); fprintf (stderr, " DCMD: cmd_status %d, sge_count %d, context 0x%08x, flags 0x%04x, timeout %d, data_xfer_len 0x%x, opcode 0x%08x\n", f->cmd_status, f->sge_count, f->context, f->flags, f->timeout, f->data_xfer_len, f->opcode); dumpbytes (stderr, &f->mbox, sizeof (f->mbox), &f->mbox, "mbox"); } } else if (cmd == MFI_CMD_PD_SCSI_IO) { struct megasas_pthru_frame *f = (struct megasas_pthru_frame *) mh; fprintf (stderr, " host %d, off 0x%04x, count %d, sense_off 0x%08x, sense_len 0x%08x\n", iocp->host_no, iocp->sgl_off, iocp->sge_count, iocp->sense_off, iocp->sense_len); fprintf (stderr, " SCSI: cmd_status %d, sge_count %d, context 0x%08x, flags 0x%04x, timeout %d, data_xfer_len 0x%x\n", f->cmd_status, f->sge_count, f->context, f->flags, f->timeout, f->data_xfer_len); fprintf (stderr, " : scsi_status %d, target_id 0x%02x, lun %d, sense_len %d, sense_lo 0x%08x, sense_hi 0x%08x\n", f->scsi_status, f->target_id, f->lun, f->sense_len, f->sense_buf_phys_addr_lo, f->sense_buf_phys_addr_hi); dumpbytes (stderr, &f->cdb, f->cdb_len, &f->cdb, "cdb"); } else { fprintf (stderr, " host %d, off 0x%04x, count %d, sense_off 0x%08x, sense_len 0x%08x\n", iocp->host_no, iocp->sgl_off, iocp->sge_count, iocp->sense_off, iocp->sense_len); dumpbytes (stderr, buf, len, (void *) r.edx, NULL); } if (log) { for (k = 0; k < iocp->sge_count; ++k) { u32 sgbase = sge[k].phys_addr; size_t sglen = sge[k].length; char sgname[16]; char sgdata[4096]; snprintf (sgname, sizeof sgname, "sg%d", k); fprintf (stderr, " %s at 0x%08x [0x%x]:\n", sgname, sgbase, sglen); if (sglen > sizeof sgdata) sglen = sizeof sgdata; copyout (sgdata, sglen, pid, sgbase); dumpbytes (stderr, sgdata, sglen, (void *) sgbase, sgname); } } } else { dumpbytes (stderr, buf, len, (void *) r.edx, NULL); } fprintf (stderr, "\n"); } switch (state) { static u32 lasteip = 0; case UNTRACED: /* We don't know whether we were inbound or outbound on the first signal; this appears to differ between kernels. So we defer until we see the same eip in two successive traps, at which point we know we were outbound, so the next trap is inbound. */ if (lasteip == r.eip) state = INBOUND; lasteip = r.eip; break; case INBOUND: state = OUTBOUND; break; case OUTBOUND: state = INBOUND; break; } if (ptrace (PTRACE_SYSCALL, pid, 0, 0) < 0) { fprintf (stderr, "ptrace:syscall: %s\n", strerror (errno)); exit (1); } } } else { fprintf (stderr, "running\n"); } } exit (0); } megactl-0.4.5/modepage.c000066400000000000000000000303311465722425200150720ustar00rootroot00000000000000/* * Incomplete code for handling mode sense data. Not used. * * Copyright (c) 2007 by Jefferson Ogata */ /* * 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, 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; see the file COPYING. If not, write to the Free Software * Foundation, 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. */ #include "megactl.h" #include "megaioctl.h" #include "modepage.h" #include "dumpbytes.h" #include #include #include #if 0 static char *logPageType[] = { /* 0 */ "supported log pages", /* 1 */ "buffer over-run/under-run", /* 2 */ "write error counter", /* 3 */ "read error counter", /* 4 */ "read reverse error counter", /* 5 */ "verify error counter", /* 6 */ "non-medium error", /* 7 */ "last n error events", /* 8 */ "format status", /* 9 */ NULL, /* a */ NULL, /* b */ "last n deferred errors os asynchronous events", /* c */ "sequential-access device", /* d */ "temperature", /* e */ "start-stop cycle counter", /* f */ "application client", /* 10 */ "self-test results", /* 11 */ "DTD status", /* 12 */ "TapeAlert response", /* 13 */ "requested recover", /* 14 */ "device statistics", /* 15 */ NULL, /* 16 */ NULL, /* 17 */ "non-volatile cache", /* 18 */ "protocol specific port", /* 19 */ NULL, /* 1a */ NULL, /* 1b */ NULL, /* 1c */ NULL, /* 1d */ NULL, /* 1e */ NULL, /* 1f */ NULL, /* 20 */ NULL, /* 21 */ NULL, /* 22 */ NULL, /* 23 */ NULL, /* 24 */ NULL, /* 25 */ NULL, /* 26 */ NULL, /* 27 */ NULL, /* 28 */ NULL, /* 29 */ NULL, /* 2a */ NULL, /* 2b */ NULL, /* 2c */ NULL, /* 2d */ NULL, /* 2e */ "TapeAlert", /* 2f */ "informational exceptions", /* 30 */ "vendor specific", /* 31 */ "vendor specific", /* 32 */ "vendor specific", /* 33 */ "vendor specific", /* 34 */ "vendor specific", /* 35 */ "vendor specific", /* 36 */ "vendor specific", /* 37 */ "vendor specific", /* 38 */ "vendor specific", /* 39 */ "vendor specific", /* 3a */ "vendor specific", /* 3b */ "vendor specific", /* 3c */ "vendor specific", /* 3d */ "vendor specific", /* 3e */ "vendor specific", /* 3f */ NULL, }; char *friendlySize (uint64_t b, char *unit) { static char *suffix[] = { "", "Ki", "Mi", "Gi", "Ti", "Pi", "Ei", "Zi", "Yi", }; int k; static char bytes[128]; for (k = 0; (b >= 1024) && (k < sizeof (suffix) / sizeof (suffix[0]) - 1); ++k, b /= 1024) ; snprintf (bytes, sizeof bytes, "%3llu%s%s", b, suffix[k], unit); return bytes; } uint32_t blocksToGB (uint32_t blocks) { return (long) (((uint64_t) blocks) * 512 / 1000000000); } uint32_t blocksToGiB (uint32_t blocks) { return blocks / 2 / 1024 / 1024; } static uint64_t extractInt64 (void *u, size_t len) { uint64_t x; uint8_t *v; for (x = 0, v = u; len > 0; --len, ++v) x = (x << 8) + *v; return x; } int parseLogPage (void *log, size_t len, struct logData *x) { struct logPageHeader *h = log; void *u = log + sizeof (*h); struct logParameterHeader *p; size_t pageLen; memset (x, 0, sizeof (*x)); if (len < sizeof (*h)) return -1; pageLen = ntohs (h->length) + sizeof (*h); if (len > pageLen) len = pageLen; len -= sizeof (*h); x->h = *h; x->h.length = pageLen; while (len >= sizeof (*p)) { uint16_t code; uint64_t e; p = u; if (p->length + sizeof (*p) > len) break; len -= sizeof (*p); u += sizeof (*p); code = ntohs (p->parameter_code); switch (h->page_code) { case 0x02: case 0x03: case 0x04: case 0x05: e = extractInt64 (u, p->length); switch (code) { case 0x0000: x->u.error.corrected = e; break; case 0x0001: x->u.error.delayed = e; break; case 0x0002: x->u.error.reread = e; break; case 0x0003: x->u.error.total_corrected = e; break; case 0x0004: x->u.error.total_algorithm = e; break; case 0x0005: x->u.error.total_bytes = e; break; case 0x0006: x->u.error.total_uncorrected = e; break; default: break; } break; case 0x0d: switch (code) { case 0x0000: x->u.temperature.current = ((uint8_t *) u)[1]; break; case 0x0001: x->u.temperature.reference = ((uint8_t *) u)[1]; break; default: break; } break; case 0x0e: switch (code) { case 0x0001: strncpy (x->u.startstop.manufacture_year, u, sizeof (x->u.startstop.manufacture_year) - 1); x->u.startstop.manufacture_year[sizeof (x->u.startstop.manufacture_year) - 1] = '\0'; ntrim (x->u.startstop.manufacture_year); strncpy (x->u.startstop.manufacture_week, u + 4, sizeof (x->u.startstop.manufacture_week) - 1); x->u.startstop.manufacture_week[sizeof (x->u.startstop.manufacture_week) - 1] = '\0'; ntrim (x->u.startstop.manufacture_week); break; case 0x0002: strncpy (x->u.startstop.accounting_year, u, sizeof (x->u.startstop.accounting_year) - 1); x->u.startstop.accounting_year[sizeof (x->u.startstop.accounting_year) - 1] = '\0'; ntrim (x->u.startstop.accounting_year); strncpy (x->u.startstop.accounting_week, u + 4, sizeof (x->u.startstop.accounting_week) - 1); x->u.startstop.accounting_week[sizeof (x->u.startstop.accounting_week) - 1] = '\0'; ntrim (x->u.startstop.accounting_week); break; case 0x0003: x->u.startstop.recommended_starts = ntohl (*((uint32_t *) u)); break; case 0x0004: x->u.startstop.accumulated_starts = ntohl (*((uint32_t *) u)); break; default: break; } break; case 0x10: if ((code < 1) || (code > sizeof (x->u.selftest.entry) / sizeof (x->u.selftest.entry[0]))) break; if (p->length != sizeof (x->u.selftest.entry[0]) - sizeof (*p)) break; --code; x->u.selftest.entry[code] = *((struct selfTestLogParameter *) p); x->u.selftest.entry[code].h.parameter_code = code; x->u.selftest.entry[code].timestamp = ntohs (x->u.selftest.entry[code].timestamp); x->u.selftest.entry[code].lba = extractInt64 (&x->u.selftest.entry[code].lba, sizeof (x->u.selftest.entry[code].lba)); break; } len -= p->length; u += p->length; } /* flag any problems */ switch (h->page_code) { case 0x02: case 0x03: case 0x04: case 0x05: if (x->u.error.total_uncorrected) x->problem = 1; break; case 0x0d: if (x->u.temperature.reference && (x->u.temperature.reference != 0xff) && (x->u.temperature.current >= x->u.temperature.reference)) x->problem = 1; break; } return 0; } #endif void dumpModePage (FILE *f, struct modeData *x, void *mode, size_t len, int verbosity) { struct logPageHeader *h = log; void *u = log + sizeof (*h); struct logParameterHeader *p; size_t pageLen; int k; switch (x->h.page_code) { case 0x02: case 0x03: case 0x04: case 0x05: switch (x->h.page_code) { case 0x02: fprintf (f, " write errors:"); break; case 0x03: fprintf (f, " read errors:"); break; case 0x04: fprintf (f, " read/rev errors:"); break; case 0x05: fprintf (f, " verify errors:"); break; } fprintf (f, " corr:%-6s", friendlySize (x->u.error.corrected, "")); fprintf (f, " delay:%-6s", friendlySize (x->u.error.delayed, "")); switch (x->h.page_code) { case 0x02: fprintf (f, " rewrit:%-6s", friendlySize (x->u.error.reread, "")); break; case 0x03: fprintf (f, " reread:%-6s", friendlySize (x->u.error.reread, "")); break; case 0x04: fprintf (f, " reread:%-6s", friendlySize (x->u.error.reread, "")); break; case 0x05: fprintf (f, " revrfy:%-6s", friendlySize (x->u.error.reread, "")); break; } fprintf (f, " tot/corr:%-6s", friendlySize (x->u.error.total_corrected, "")); if (verbosity > 1) fprintf (f, " tot/alg:%-6s", friendlySize (x->u.error.total_algorithm, "")); if (verbosity > 1) fprintf (f, " tot/bytes:%-6s", friendlySize (x->u.error.total_bytes, "B")); fprintf (f, " tot/uncorr:%-6s", friendlySize (x->u.error.total_uncorrected, "")); fprintf (f, "\n"); break; case 0x0d: fprintf (f, " temperature: current:%uC threshold:%uC%s\n", x->u.temperature.current, x->u.temperature.reference, x->problem ? " warning:temperature threshold exceeded" : ""); break; case 0x0e: fprintf (f, " "); if (strlen (x->u.startstop.manufacture_year) && strlen (x->u.startstop.manufacture_week)) fprintf (f, " manufactured:%s/%s", x->u.startstop.manufacture_year, x->u.startstop.manufacture_week); if (strlen (x->u.startstop.accounting_year) && strlen (x->u.startstop.accounting_week)) fprintf (f, " accounting:%s/%s", x->u.startstop.accounting_year, x->u.startstop.accounting_week); fprintf (f, " starts:%d/%d", x->u.startstop.accumulated_starts, x->u.startstop.recommended_starts); fprintf (f, "\n"); break; case 0x10: for (k = 0; k < sizeof (x->u.selftest.entry) / sizeof (x->u.selftest.entry[0]); ++k) { struct selfTestLogParameter *t = &x->u.selftest.entry[k]; if (t->self_test_code || t->self_test_results || t->timestamp || t->number || t->lba) { char *test; char *result; switch (t->self_test_code) { case SCSI_SELFTEST_DEFAULT: test = "default"; break; case SCSI_SELFTEST_BACKGROUND_SHORT: test = "bg short"; break; case SCSI_SELFTEST_BACKGROUND_LONG: test = "bg long"; break; case SCSI_SELFTEST_BACKGROUND_ABORT: test = "bg aborted"; break; case SCSI_SELFTEST_FOREGROUND_SHORT: test = "fg short"; break; case SCSI_SELFTEST_FOREGROUND_LONG: test = "fg long"; break; default: test = "unknown"; break; } switch (t->self_test_results) { case 0x0: result = "completed without error"; break; case 0x1: result = "aborted via send diagnostic"; break; case 0x2: result = "aborted via other method"; break; case 0x3: result = "unable to complete"; break; case 0x4: result = "failed in unknown segment"; break; case 0x5: result = "failed in segment 1"; break; case 0x6: result = "failed in segment 2"; break; case 0x7: result = "failed in other segment"; break; case 0xf: result = "in progress"; break; default: result = "unknown result"; break; } fprintf (f, " %2d: timestamp %4ud%02uh: %10s %-30s seg:%u lba:%-8lld sk:%u asc:%u ascq:%u vs:%u\n", k, t->timestamp / 24, t->timestamp % 24, test, result, t->number, t->lba, t->sense_key, t->additional_sense_code, t->additional_sense_code_qualifier, t->vendor_specific); } } break; default: break; } if (!(verbosity > 2)) return; if (len < sizeof (*h)) return; pageLen = ntohs (h->length) + sizeof (*h); if (len > pageLen) len = pageLen; len -= sizeof (*h); switch (h->page_code) { case 0x00: fprintf (f, " %s:", logPageType[h->page_code]); if (verbosity > 1) fprintf (f, "\n"); for (k = len; k > 0; --k, ++u) { uint8_t code = *((unsigned char *) u); if (verbosity > 1) { char *name; if ((code < sizeof logPageType / sizeof (logPageType[0])) && logPageType[code]) name = logPageType[code]; else name = "unknown log page"; fprintf (f, " %02x %s\n", code, name); } else fprintf (f, " %02x", code); } if (verbosity <= 1) fprintf (f, "\n"); return; default: fprintf (f, " log page %02x, length %u%s\n", h->page_code, ntohs (h->length), len < pageLen - sizeof (*h) ? " warning: truncated" : ""); break; } while (len >= sizeof (*p)) { uint16_t code; p = u; if (p->length + sizeof (*p) > len) break; len -= sizeof (*p); u += sizeof (*p); code = ntohs (p->parameter_code); fprintf (f, " param %04x, du %u, ds %u, tsd %u, etc %u, tmc %u, lbin %u, lp %u, length %u\n", code, p->du, p->ds, p->tsd, p->etc, p->tmc, p->lbin, p->lp, p->length); dumpbytes (f, u, p->length, u, "param"); len -= p->length; u += p->length; } } megactl-0.4.5/modepage.h000066400000000000000000000036071465722425200151050ustar00rootroot00000000000000#ifndef _MODEPAGE_H #define _MODEPAGE_H /* * Definitions for unused mode page code. * * Copyright (c) 2007 by Jefferson Ogata */ /* * 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, 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; see the file COPYING. If not, write to the Free Software * Foundation, 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. */ #include #include #include struct modePage0Header { #if defined(_BIT_FIELDS_LTOH) /* Intel byteorder (thanks, Schily) */ uint8_t page_code:6; uint8_t spf:1; uint8_t ps:1; #else /* Motorola byteorder */ uint8_t ps:1; uint8_t spf:1; uint8_t page_code:6; #endif uint8_t length; } __attribute__ ((packed)); struct modeSubPageHeader { #if defined(_BIT_FIELDS_LTOH) /* Intel byteorder (thanks, Schily) */ uint8_t page_code:6; uint8_t spf:1; uint8_t ps:1; #else /* Motorola byteorder */ uint8_t ps:1; uint8_t spf:1; uint8_t page_code:6; #endif uint8_t subpage_code; uint16_t length; } __attribute__ ((packed)); struct modeData { union { struct modePage0Header error; struct modeSubPageHeader selftest; } u; } __attribute__ ((packed)); #if 0 extern int parseLogPage (void *log, size_t len, struct logData *x); #endif extern void dumpModePage (FILE *f, struct modeData *x, void *mode, size_t len, int verbosity); #endif megactl-0.4.5/ntrim.c000066400000000000000000000021731465722425200144450ustar00rootroot00000000000000/* * Little string-trimming function. * * Copyright (c) 2007 by Jefferson Ogata */ /* * 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, 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; see the file COPYING. If not, write to the Free Software * Foundation, 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. */ #include #include #include #include "ntrim.h" void ntrim (char *s) { char *t; size_t len = strlen (s); for (t = s + len - 1; (t >= s) && isspace (*t); --t) *t = '\0'; for (t = s; isspace (*t); ++t) ; if (t > s) { for ( ; *t; ++t, ++s) *s = *t; *s = *t; } } megactl-0.4.5/ntrim.h000066400000000000000000000016021465722425200144460ustar00rootroot00000000000000#ifndef _NTRIM_H #define _NTRIM_H /* * Definitions for little string trimmer function. * * Copyright (c) 2007 by Jefferson Ogata */ /* * 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, 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; see the file COPYING. If not, write to the Free Software * Foundation, 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. */ extern void ntrim (char *s); #endif megactl-0.4.5/schily/000077500000000000000000000000001465722425200144405ustar00rootroot00000000000000megactl-0.4.5/schily/allocax.h000066400000000000000000000033321465722425200162350ustar00rootroot00000000000000/* @(#)allocax.h 1.3 03/07/15 Copyright 2002 J. Schilling */ /* * Definitions for users of alloca() * * Important: #include this directly after * and before any other include file. * See comment in _AIX part below. * * Copyright (c) 2002 J. Schilling */ /* * 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, 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; see the file COPYING. If not, write to the Free Software * Foundation, 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. */ #ifndef _ALLOCAX_H #define _ALLOCAX_H #ifdef __GNUC__ # ifndef alloca # define alloca(s) __builtin_alloca(s) # endif #else # ifdef _MSC_VER # include # define alloca _alloca # else # if HAVE_ALLOCA_H # include # else # ifdef _AIX /* * Indent so pre-ANSI compilers will ignore it * * Some versions of AIX may require this to be * first in the file and only preceded by * comments and preprocessor directives/ */ #pragma alloca # else # ifndef alloca /* * predefined by HP cc +Olibcalls */ # ifdef PROTOTYPES extern void *alloca(); # else extern char *alloca(); # endif # endif # endif # endif # endif #endif #endif /* _ALLOCAX_H */ megactl-0.4.5/schily/btorder.h000066400000000000000000000063411465722425200162560ustar00rootroot00000000000000/* @(#)btorder.h 1.16 03/06/15 Copyright 1996 J. Schilling */ /* * Definitions for Bit and Byte ordering * * Copyright (c) 1996 J. Schilling */ /* * 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, 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; see the file COPYING. If not, write to the Free Software * Foundation, 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. */ #ifndef _BTORDER_H #define _BTORDER_H #ifndef _INCL_SYS_TYPES_H #include /* try to load isa_defs.h on Solaris */ #define _INCL_SYS_TYPES_H #endif #ifndef _MCONFIG_H #include /* load bit/byte-oder from xmconfig.h*/ #endif /* * Convert bit-order definitions from xconfig.h into our values * and verify them. */ #if defined(HAVE_C_BITFIELDS) && \ defined(BITFIELDS_LTOH) #define _BIT_FIELDS_LTOH #endif #if defined(HAVE_C_BITFIELDS) && \ defined(BITFIELDS_HTOL) #define _BIT_FIELDS_HTOL #endif #if defined(HAVE_C_BITFIELDS) && \ !defined(BITFIELDS_HTOL) #define BITFIELDS_LTOH #define _BIT_FIELDS_LTOH #endif #if defined(_BIT_FIELDS_LTOH) && defined(_BIT_FIELDS_HTOL) /* * #error will not work for all compilers (e.g. sunos4) * The following line will abort compilation on all compilers * if none of the above is defines. And that's what we want. */ error Only one of _BIT_FIELDS_LTOH or _BIT_FIELDS_HTOL may be defined #endif /* * Convert byte-order definitions from xconfig.h into our values * and verify them. * Note that we cannot use the definitions _LITTLE_ENDIAN and _BIG_ENDIAN * because they are used on IRIX-6.5 with different meaning. */ #if defined(HAVE_C_BIGENDIAN) && \ !defined(WORDS_BIGENDIAN) #define WORDS_LITTLEENDIAN /*#define _LITTLE_ENDIAN*/ #endif #if defined(HAVE_C_BIGENDIAN) && \ defined(WORDS_BIGENDIAN) #undef WORDS_LITTLEENDIAN /*#define _BIG_ENDIAN*/ #endif #if defined(_BIT_FIELDS_LTOH) || defined(_BIT_FIELDS_HTOL) /* * Bitorder is already known. */ #else /* * Bitorder not yet known. */ # if defined(sun3) || defined(mc68000) || \ defined(sun4) || defined(__sparc) || defined(sparc) || \ defined(__hppa) || defined(_ARCH_PPC) || defined(_IBMR2) # define _BIT_FIELDS_HTOL # endif # if defined(__sgi) && defined(__mips) # define _BIT_FIELDS_HTOL # endif # if defined(__i386__) || defined(__i386) || defined(i386) || \ defined(__ia64__) || defined(__ia64) || defined(ia64) || \ defined(__alpha__) || defined(__alpha) || defined(alpha) || \ defined(__arm__) || defined(__arm) || defined(arm) # define _BIT_FIELDS_LTOH # endif # if defined(__ppc__) || defined(ppc) || defined(__ppc) || \ defined(__PPC) || defined(powerpc) || defined(__powerpc__) # if defined(__BIG_ENDIAN__) # define _BIT_FIELDS_HTOL # else # define _BIT_FIELDS_LTOH # endif # endif #endif #endif /* _BTORDER_H */ megactl-0.4.5/schily/btorder.h.endian000066400000000000000000000062411465722425200175120ustar00rootroot00000000000000/* @(#)btorder.h 1.16 03/06/15 Copyright 1996 J. Schilling */ /* * Definitions for Bit and Byte ordering * * Copyright (c) 1996 J. Schilling */ /* * 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, 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; see the file COPYING. If not, write to the Free Software * Foundation, 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. */ #ifndef _BTORDER_H #define _BTORDER_H #ifndef _INCL_SYS_TYPES_H #include /* try to load isa_defs.h on Solaris */ #define _INCL_SYS_TYPES_H #endif #ifndef _MCONFIG_H #include /* load bit/byte-oder from xmconfig.h*/ #endif /* * Convert bit-order definitions from xconfig.h into our values * and verify them. */ #if defined(HAVE_C_BITFIELDS) && \ defined(BITFIELDS_LTOH) #define _BIT_FIELDS_LTOH #endif #if defined(HAVE_C_BITFIELDS) && \ defined(BITFIELDS_HTOL) #define _BIT_FIELDS_HTOL #endif #if defined(HAVE_C_BITFIELDS) && \ !defined(BITFIELDS_HTOL) #define BITFIELDS_LTOH #define _BIT_FIELDS_LTOH #endif #if defined(_BIT_FIELDS_LTOH) && defined(_BIT_FIELDS_HTOL) /* * #error will not work for all compilers (e.g. sunos4) * The following line will abort compilation on all compilers * if none of the above is defines. And that's what we want. */ error Only one of _BIT_FIELDS_LTOH or _BIT_FIELDS_HTOL may be defined #endif /* * Convert byte-order definitions from xconfig.h into our values * and verify them. * Note that we cannot use the definitions _LITTLE_ENDIAN and _BIG_ENDIAN * because they are used on IRIX-6.5 with different meaning. */ #if defined(HAVE_C_BIGENDIAN) && \ !defined(WORDS_BIGENDIAN) #define WORDS_LITTLEENDIAN /*#define _LITTLE_ENDIAN*/ #endif #if defined(HAVE_C_BIGENDIAN) && \ defined(WORDS_BIGENDIAN) #undef WORDS_LITTLEENDIAN /*#define _BIG_ENDIAN*/ #endif #if defined(_BIT_FIELDS_LTOH) || defined(_BIT_FIELDS_HTOL) /* * Bitorder is already known. */ #else /* * Bitorder not yet known. */ # if defined(sun3) || defined(mc68000) || \ defined(sun4) || defined(__sparc) || defined(sparc) || \ defined(__hppa) || defined(_ARCH_PPC) || defined(_IBMR2) # define _BIT_FIELDS_HTOL # endif # if defined(__sgi) && defined(__mips) # define _BIT_FIELDS_HTOL # endif # if defined(__i386__) || defined(__i386) || defined(i386) || \ defined(__alpha__) || defined(__alpha) || defined(alpha) || \ defined(__arm__) || defined(__arm) || defined(arm) # define _BIT_FIELDS_LTOH # endif # if defined(__ppc__) || defined(ppc) || defined(__ppc) || \ defined(__PPC) || defined(powerpc) || defined(__powerpc__) # if defined(__BIG_ENDIAN__) # define _BIT_FIELDS_HTOL # else # define _BIT_FIELDS_LTOH # endif # endif #endif #endif /* _BTORDER_H */ megactl-0.4.5/schily/ccomdefs.h000066400000000000000000000040661465722425200164020ustar00rootroot00000000000000/* @(#)ccomdefs.h 1.3 03/06/15 Copyright 2000 J. Schilling */ /* * Various compiler dependant macros. * * Copyright (c) 2000 J. Schilling */ /* * 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, 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; see the file COPYING. If not, write to the Free Software * Foundation, 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. */ #ifndef _CCOMDEFS_H #define _CCOMDEFS_H #ifdef __cplusplus extern "C" { #endif /* * Compiler-dependent macros to declare that functions take printf-like * or scanf-like arguments. They are defined to nothing for versions of gcc * that are not known to support the features properly (old versions of gcc-2 * didn't permit keeping the keywords out of the application namespace). */ #if __GNUC__ < 2 || __GNUC__ == 2 && __GNUC_MINOR__ < 7 #define __printflike__(fmtarg, firstvararg) #define __printf0like__(fmtarg, firstvararg) #define __scanflike__(fmtarg, firstvararg) #else /* We found GCC that supports __attribute__ */ #define __printflike__(fmtarg, firstvararg) \ __attribute__((__format__(__printf__, fmtarg, firstvararg))) #define __printf0like__(fmtarg, firstvararg) \ __attribute__((__format__(__printf0__, fmtarg, firstvararg))) /* * FreeBSD GCC implements printf0 that allows the format string to * be a NULL pointer. */ #if __FreeBSD_cc_version < 300001 #undef __printf0like__ #define __printf0like__ __printflike__ #endif #define __scanflike__(fmtarg, firstvararg) \ __attribute__((__format__(__scanf__, fmtarg, firstvararg))) #endif /* GNUC */ #ifdef __cplusplus } #endif #endif /* _CCOMDEFS_H */ megactl-0.4.5/schily/deflts.h000066400000000000000000000036761465722425200161060ustar00rootroot00000000000000/* @(#)deflts.h 1.6 02/08/26 Copyright 1997 J. Schilling */ /* * Definitions for reading program defaults. * * Copyright (c) 1997 J. Schilling */ /* * 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, 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; see the file COPYING. If not, write to * the Free Software Foundation, 675 Mass Ave, Cambridge, MA 02139, USA. */ #ifndef _DEFLTS_H #define _DEFLTS_H #ifndef _MCONFIG_H #include #endif #ifndef _PROTOTYP_H #include #endif #ifdef __cplusplus extern "C" { #endif #define DEFLT "/etc/default" /* * cmd's to defltcntl() */ #define DC_GETFLAGS 0 /* Get actual flags */ #define DC_SETFLAGS 1 /* Set new flags */ /* * flags to defltcntl() * * Make sure that when adding features, the default behaviour * is the same as old behaviour. */ #define DC_CASE 0x0001 /* Don't ignore case */ #define DC_STD DC_CASE /* Default flags */ /* * Macros to handle flags */ #ifndef TURNON #define TURNON(flags, mask) flags |= mask #define TURNOFF(flags, mask) flags &= ~(mask) #define ISON(flags, mask) (((flags) & (mask)) == (mask)) #define ISOFF(flags, mask) (((flags) & (mask)) != (mask)) #endif extern int defltopen __PR((const char *name)); extern int defltclose __PR((void)); extern void defltfirst __PR((void)); extern char *defltread __PR((const char *name)); extern char *defltnext __PR((const char *name)); extern int defltcntl __PR((int cmd, int flags)); #ifdef __cplusplus } #endif #endif /* _DEFLTS_H */ megactl-0.4.5/schily/device.h000066400000000000000000000072631465722425200160600ustar00rootroot00000000000000/* @(#)device.h 1.12 03/06/15 Copyright 1995 J. Schilling */ /* * Generic header for users of major(), minor() and makedev() * * Copyright (c) 1995 J. Schilling */ /* * 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, 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; see the file COPYING. If not, write to the Free Software * Foundation, 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. */ #ifndef _DEVICE_H #define _DEVICE_H #ifndef _MCONFIG_H #include #endif #ifndef _PROTOTYP_H #include #endif /* * On generic SVR4, major is a function (defined in sys/mkdev.h). * On Solaris it is defined ... * As we cannot just test if major is #define'd, we have to * define _FOUND_MAJOR_ instead. * * WARNING: Do never include in SVR4, it contains * an old definition for major()/minor() defining 8 minorbits. * Use instead. */ #ifndef _INCL_SYS_TYPES_H #include #define _INCL_SYS_TYPES_H #endif /* * Some systems define major in . * We are ready... */ #ifdef major # define _FOUND_MAJOR_ #endif #ifdef MAJOR_IN_MKDEV # ifndef _INCL_SYS_MKDEV_H # include # define _INCL_SYS_MKDEV_H # endif # define _FOUND_MAJOR_ #endif #ifndef _FOUND_MAJOR_ # ifdef MAJOR_IN_SYSMACROS # ifndef _INCL_SYS_SYSMACROS_H # include # define _INCL_SYS_SYSMACROS_H # endif # define _FOUND_MAJOR_ # endif #endif /* * If we are on HP/UX before HP/UX 8, * major/minor are not in . */ #ifndef _FOUND_MAJOR_ # if defined(hpux) || defined(__hpux__) || defined(__hpux) # ifndef _INCL_SYS_MKOD_H # include # define _INCL_SYS_MKOD_H # endif # define _FOUND_MAJOR_ # endif #endif #ifdef __cplusplus extern "C" { #endif /* * For all other systems define major()/minor() here. * XXX Check if this definition will be usefull for ms dos too. */ #ifndef _FOUND_MAJOR_ # define major(dev) (((dev) >> 8) & 0xFF) # define minor(dev) ((dev) & 0xFF) # define makedev(majo, mino) (((majo) << 8) | (mino)) #endif /* * Don't pollute namespace... */ #undef _FOUND_MAJOR_ #ifdef __XDEV__ /* * The following defines are currently only needed for 'star'. * We make it conditional code to avoid to pollute the namespace. */ #define XDEV_T unsigned long extern int minorbits; extern XDEV_T minormask; extern XDEV_T _dev_mask[]; #define dev_major(dev) (((XDEV_T)(dev)) >> minorbits) #define _dev_major(mbits, dev) (((XDEV_T)(dev)) >> (mbits)) #define dev_minor(dev) (((XDEV_T)(dev)) & minormask) #define _dev_minor(mbits, dev) (((XDEV_T)(dev)) & _dev_mask[(mbits)]) #define dev_make(majo, mino) ((((XDEV_T)(majo)) << minorbits) | \ ((XDEV_T)(mino))) #define _dev_make(mbits, majo, mino) ((((XDEV_T)(majo)) << (mbits) | \ ((XDEV_T)(mino))) extern void dev_init __PR((BOOL debug)); #ifndef dev_major extern XDEV_T dev_major __PR((XDEV_T dev)); extern XDEV_T _dev_major __PR((int mbits, XDEV_T dev)); extern XDEV_T dev_minor __PR((XDEV_T dev)); extern XDEV_T _dev_minor __PR((int mbits, XDEV_T dev)); extern XDEV_T dev_make __PR((XDEV_T majo, XDEV_T mino)); extern XDEV_T _dev_make __PR((int mbits, XDEV_T majo, XDEV_T mino)); #endif #endif /* __XDEV__ */ #ifdef __cplusplus } #endif #endif /* _DEVICE_H */ megactl-0.4.5/schily/dirdefs.h000066400000000000000000000073721465722425200162420ustar00rootroot00000000000000/* @(#)dirdefs.h 1.15 04/06/16 Copyright 1987, 1998 J. Schilling */ /* * Copyright (c) 1987, 1998 J. Schilling */ /* * 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, 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; see the file COPYING. If not, write to the Free Software * Foundation, 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. */ #ifndef _DIRDEFS_H #define _DIRDEFS_H #ifndef _MCONFIG_H #include #endif #ifdef __cplusplus extern "C" { #endif #ifdef JOS # ifndef _INCL_SYS_STYPES_H # include # define _INCL_SYS_STYPES_H # endif # ifndef _INCL_SYS_FILEDESC_H # include # define _INCL_SYS_FILEDESC_H # endif # define NEED_READDIR # define dirent _direct # define DIR_NAMELEN(dirent) strlen((dirent)->d_name) # define DIRSIZE 30 # define FOUND_DIRSIZE typedef struct _dirent { char name[DIRSIZE]; short ino; } dirent; #else /* !JOS */ # ifndef _INCL_SYS_TYPES_H # include # define _INCL_SYS_TYPES_H # endif # ifndef _INCL_SYS_STAT_H # include # define _INCL_SYS_STAT_H # endif # ifdef HAVE_LIMITS_H # ifndef _INCL_LIMITS_H # include # define _INCL_LIMITS_H # endif # endif # ifdef HAVE_SYS_PARAM_H # ifndef _INCL_SYS_PARAM_H # include # define _INCL_SYS_PARAM_H # endif # endif # ifdef HAVE_DIRENT_H /* This a POSIX compliant system */ # ifndef _INCL_DIRENT_H # include # define _INCL_DIRENT_H # endif # define DIR_NAMELEN(dirent) strlen((dirent)->d_name) # define _FOUND_DIR_ # else /* This is a Pre POSIX system */ # define dirent direct # define DIR_NAMELEN(dirent) (dirent)->d_namlen # if defined(HAVE_SYS_DIR_H) # ifndef _INCL_SYS_DIR_H # include # define _INCL_SYS_DIR_H # endif # define _FOUND_DIR_ # endif # if defined(HAVE_NDIR_H) && !defined(_FOUND_DIR_) # ifndef _INCL_NDIR_H # include # define _INCL_NDIR_H # endif # define _FOUND_DIR_ # endif # if defined(HAVE_SYS_NDIR_H) && !defined(_FOUND_DIR_) # ifndef _INCL_SYS_NDIR_H # include # define _INCL_SYS_NDIR_H # endif # define _FOUND_DIR_ # endif # endif /* HAVE_DIRENT_H */ # if defined(_FOUND_DIR_) /* * Don't use defaults here to allow recognition of problems. */ # ifdef MAXNAMELEN # define DIRSIZE MAXNAMELEN /* From sys/param.h */ # define FOUND_DIRSIZE # else # ifdef MAXNAMLEN # define DIRSIZE MAXNAMLEN /* From dirent.h */ # define FOUND_DIRSIZE # else # ifdef DIRSIZ # define DIRSIZE DIRSIZ /* From sys/dir.h */ # define FOUND_DIRSIZE # endif # endif # endif # else /* !_FOUND_DIR_ */ # define NEED_DIRENT # define NEED_READDIR # define dirent _direct # define DIR_NAMELEN(dirent) strlen((dirent)->d_name) # endif /* _FOUND_DIR_ */ #ifdef NEED_DIRENT #ifndef FOUND_DIRSIZE #define DIRSIZE 14 /* The old UNIX standard value */ #define FOUND_DIRSIZE #endif typedef struct _dirent { short ino; char name[DIRSIZE]; } dirent; #endif /* NEED_DIRENT */ #endif /* !JOS */ #ifdef NEED_READDIR typedef struct __dirdesc { FILE *dd_fd; } DIR; struct _direct { unsigned long d_ino; unsigned short d_reclen; unsigned short d_namlen; char d_name[DIRSIZE +1]; }; extern DIR *opendir(); extern closedir(); extern struct dirent *readdir(); #endif /* NEED_READDIR */ #ifdef __cplusplus } #endif #endif /* _DIRDEFS_H */ megactl-0.4.5/schily/fctldefs.h000066400000000000000000000040421465722425200164030ustar00rootroot00000000000000/* @(#)fctldefs.h 1.13 03/02/23 Copyright 1996 J. Schilling */ /* * Generic header for users of open(), creat() and chmod() * * Copyright (c) 1996 J. Schilling */ /* * 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, 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; see the file COPYING. If not, write to the Free Software * Foundation, 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. */ #ifndef _FCTLDEFS_H #define _FCTLDEFS_H #ifndef _MCONFIG_H #include #endif #ifndef _STATDEFS_H #include /* For 3rd arg of open() and chmod() */ #endif #ifndef _INCL_SYS_TYPES_H #include /* Needed for fcntl.h */ #define _INCL_SYS_TYPES_H #endif #ifdef HAVE_SYS_FILE_H /* * Historical systems with flock() only need sys/file.h */ # ifndef _INCL_SYS_FILE_H # include # define _INCL_SYS_FILE_H # endif #endif #ifdef HAVE_FCNTL_H # ifndef _INCL_FCNTL_H # include # define _INCL_FCNTL_H #endif #endif /* * Do not define more than O_RDONLY / O_WRONLY / O_RDWR / O_BINARY * The values may differ. * * O_BINARY is defined here to allow all applications to compile on a non DOS * environment without repeating this definition. */ #ifndef O_RDONLY # define O_RDONLY 0 #endif #ifndef O_WRONLY # define O_WRONLY 1 #endif #ifndef O_RDWR # define O_RDWR 2 #endif #ifndef O_BINARY /* Only present on DOS or similar */ # define O_BINARY 0 #endif #ifndef O_NDELAY /* This is undefined on BeOS :-( */ # define O_NDELAY 0 #endif #ifndef O_ACCMODE #define O_ACCMODE (O_RDONLY|O_WRONLY|O_RDWR) #endif #endif /* _FCTLDEFS_H */ megactl-0.4.5/schily/getargs.h000066400000000000000000000026121465722425200162460ustar00rootroot00000000000000/* @(#)getargs.h 1.9 03/06/15 Copyright 1985 J. Schilling */ /* * Definitions for getargs()/getallargs()/getfiles() * * Copyright (c) 1985 J. Schilling */ /* * 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, 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; see the file COPYING. If not, write to the Free Software * Foundation, 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. */ #ifndef _GETARGS_H #define _GETARGS_H #ifndef _MCONFIG_H #include #endif #ifndef _PROTOTYP_H #include #endif #ifdef __cplusplus extern "C" { #endif #define NOARGS 0 /* No more args */ #define NOTAFLAG 1 /* Not a flag type argument */ #define BADFLAG (-1) /* Not a valid flag argument */ #define BADFMT (-2) /* Error in format string */ #define NOTAFILE (-3) /* Seems to be a flag type */ typedef int (*getargfun) __PR((const void *, void *)); #ifdef __cplusplus } #endif #endif /* _GETARGS_H */ megactl-0.4.5/schily/getcwd.h000066400000000000000000000022321465722425200160650ustar00rootroot00000000000000/* @(#)getcwd.h 1.3 01/07/15 Copyright 1998 J. Schilling */ /* * Definitions for getcwd() * * Copyright (c) 1998 J. Schilling */ /* * 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, 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; see the file COPYING. If not, write to * the Free Software Foundation, 675 Mass Ave, Cambridge, MA 02139, USA. */ #ifndef _GETCWD_H #define _GETCWD_H #ifndef _MCONFIG_H #include #endif #ifdef JOS # ifndef _INCL_SYS_STYPES_H # include # define _INCL_SYS_STYPES_H # endif extern char *gwd(); # define getcwd(b, len) gwd(b) #else # ifndef HAVE_GETCWD # define getcwd(b, len) getwd(b) # endif #endif #endif /* _GETCWD_H */ megactl-0.4.5/schily/intcvt.h000066400000000000000000000070171465722425200161250ustar00rootroot00000000000000/* @(#)intcvt.h 1.4 03/12/29 Copyright 1986-2003 J. Schilling */ /* * Definitions for conversion to/from integer data types of various size. * * Copyright (c) 1986-2003 J. Schilling */ /* * 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, 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; see the file COPYING. If not, write to the Free Software * Foundation, 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. */ #ifndef _INTCVT_H #define _INTCVT_H #ifndef _MCONFIG_H #include #endif #define i_to_2_byte(a, i) (((Uchar *)(a))[0] = ((i) >> 8) & 0xFF,\ ((Uchar *)(a))[1] = (i) & 0xFF) #define i_to_3_byte(a, i) (((Uchar *)(a))[0] = ((i) >> 16)& 0xFF,\ ((Uchar *)(a))[1] = ((i) >> 8) & 0xFF,\ ((Uchar *)(a))[2] = (i) & 0xFF) #define i_to_4_byte(a, i) (((Uchar *)(a))[0] = ((i) >> 24)& 0xFF,\ ((Uchar *)(a))[1] = ((i) >> 16)& 0xFF,\ ((Uchar *)(a))[2] = ((i) >> 8) & 0xFF,\ ((Uchar *)(a))[3] = (i) & 0xFF) #define a_to_byte(a) (((Int8_t *) a)[0]) #define a_to_u_byte(a) ((UInt8_t) \ (((Uchar *) a)[0] & 0xFF)) #define a_to_u_2_byte(a) ((UInt16_t) \ ((((Uchar *) a)[1] & 0xFF) | \ (((Uchar *) a)[0] << 8 & 0xFF00))) #define a_to_2_byte(a) (int)(Int16_t)a_to_u_2_byte(a) #define a_to_u_3_byte(a) ((Ulong) \ ((((Uchar *) a)[2] & 0xFF) | \ (((Uchar *) a)[1] << 8 & 0xFF00) | \ (((Uchar *) a)[0] << 16 & 0xFF0000))) #define a_to_3_byte(a) a_to_u_3_byte(a) /* XXX Is there a signed version ? */ #ifdef __STDC__ # define __TOP_4BYTE 0xFF000000UL #else # define __TOP_4BYTE 0xFF000000 #endif #define a_to_u_4_byte(a) ((Ulong) \ ((((Uchar*) a)[3] & 0xFF) | \ (((Uchar*) a)[2] << 8 & 0xFF00) | \ (((Uchar*) a)[1] << 16 & 0xFF0000) | \ (((Uchar*) a)[0] << 24 & __TOP_4BYTE))) #define a_to_4_byte(a) (long)(Int32_t)a_to_u_4_byte(a) /* * Little Endian versions of above macros */ #define li_to_2_byte(a, i) (((Uchar *)(a))[1] = ((i) >> 8) & 0xFF,\ ((Uchar *)(a))[0] = (i) & 0xFF) #define li_to_3_byte(a, i) (((Uchar *)(a))[2] = ((i) >> 16)& 0xFF,\ ((Uchar *)(a))[1] = ((i) >> 8) & 0xFF,\ ((Uchar *)(a))[0] = (i) & 0xFF) #define li_to_4_byte(a, i) (((Uchar *)(a))[3] = ((i) >> 24)& 0xFF,\ ((Uchar *)(a))[2] = ((i) >> 16)& 0xFF,\ ((Uchar *)(a))[1] = ((i) >> 8) & 0xFF,\ ((Uchar *)(a))[0] = (i) & 0xFF) #define la_to_u_2_byte(a) ((UInt16_t) \ ((((Uchar*) a)[0] & 0xFF) | \ (((Uchar*) a)[1] << 8 & 0xFF00))) #define la_to_2_byte(a) (int)(Int16_t)la_to_u_2_byte(a) #define la_to_u_3_byte(a) ((Ulong) \ ((((Uchar*) a)[0] & 0xFF) | \ (((Uchar*) a)[1] << 8 & 0xFF00) | \ (((Uchar*) a)[2] << 16 & 0xFF0000))) #define la_to_3_byte(a) la_to_u_3_byte(a) /* XXX Is there a signed version ? */ #define la_to_u_4_byte(a) ((Ulong) \ ((((Uchar*) a)[0] & 0xFF) | \ (((Uchar*) a)[1] << 8 & 0xFF00) | \ (((Uchar*) a)[2] << 16 & 0xFF0000) | \ (((Uchar*) a)[3] << 24 & __TOP_4BYTE))) #define la_to_4_byte(a) (long)(Int32_t)la_to_u_4_byte(a) #endif /* _INTCVT_H */ megactl-0.4.5/schily/jmpdefs.h000066400000000000000000000020071465722425200162400ustar00rootroot00000000000000/* @(#)jmpdefs.h 1.2 00/11/08 Copyright 1999 J. Schilling */ /* * Definitions that help to handle a jmp_buf * * Copyright (c) 1998 J. Schilling */ /* * 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, 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; see the file COPYING. If not, write to * the Free Software Foundation, 675 Mass Ave, Cambridge, MA 02139, USA. */ #ifndef _JMPDEFS_H #define _JMPDEFS_H #ifdef __cplusplus extern "C" { #endif typedef struct { jmp_buf jb; } jmps_t; #ifdef __cplusplus } #endif #endif /* _JMPDEFS_H */ megactl-0.4.5/schily/libport.h000066400000000000000000000047601465722425200162730ustar00rootroot00000000000000/* @(#)libport.h 1.9 03/06/15 Copyright 1995 J. Schilling */ /* * Copyright (c) 1995 J. Schilling */ /* * 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, 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; see the file COPYING. If not, write to the Free Software * Foundation, 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. */ #ifndef _LIBPORT_H #define _LIBPORT_H #ifndef _MCONFIG_H #include #endif #ifndef _PROTOTYP_H #include #endif #ifndef _STANDARD_H #include #endif /* * Try to get HOST_NAME_MAX for gethostname() */ #ifndef _UNIXSTD_H #include #endif #ifndef HOST_NAME_MAX #if defined(HAVE_NETDB_H) && !defined(HOST_NOT_FOUND) && \ !defined(_INCL_NETDB_H) #include #define _INCL_NETDB_H #endif #ifdef MAXHOSTNAMELEN #define HOST_NAME_MAX MAXHOSTNAMELEN #endif #endif #ifndef HOST_NAME_MAX #ifdef HAVE_SYS_PARAM_H #include /* Include various defs needed with some OS */ /* Linux MAXHOSTNAMELEN */ #endif #ifdef MAXHOSTNAMELEN #define HOST_NAME_MAX MAXHOSTNAMELEN #endif #endif #ifndef HOST_NAME_MAX #define HOST_NAME_MAX 255 #endif #ifdef __cplusplus extern "C" { #endif #ifdef OPENSERVER /* * Don't use the usleep() from libc on SCO's OPENSERVER. * It will kill our processes with SIGALRM. */ /* * Don't #undef HAVE_USLEEP in this file, SCO has a * usleep() prototype in unistd.h */ /*#undef HAVE_USLEEP*/ #endif #ifndef HAVE_GETHOSTID extern long gethostid __PR((void)); #endif #ifndef HAVE_GETHOSTNAME extern int gethostname __PR((char *name, int namelen)); #endif #ifndef HAVE_GETDOMAINNAME extern int getdomainname __PR((char *name, int namelen)); #endif #ifndef HAVE_GETPAGESIZE EXPORT int getpagesize __PR((void)); #endif #ifndef HAVE_USLEEP extern int usleep __PR((int usec)); #endif #if !defined(HAVE_STRDUP) || defined(__SVR4) extern char *strdup __PR((const char *s)); #endif #ifndef HAVE_RENAME extern int rename __PR((const char *old, const char *new)); #endif #ifdef __cplusplus } #endif #endif /* _LIBPORT_H */ megactl-0.4.5/schily/librmt.h000066400000000000000000000041221465722425200161010ustar00rootroot00000000000000/* @(#)librmt.h 1.16 03/06/15 Copyright 1996 J. Schilling */ /* * Prototypes for rmt client subroutines * * Copyright (c) 1995,1996,2000-2002 J. Schilling */ /* * 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, 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; see the file COPYING. If not, write to the Free Software * Foundation, 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. */ #ifndef _LIBRMT_H #define _LIBRMT_H #ifndef _MCONFIG_H #include #endif #ifndef _PROTOTYP_H #include #endif #ifndef _INCL_SYS_TYPES_H #include #define _INCL_SYS_TYPES_H #endif #include /* * remote.c */ extern void rmtinit __PR((int (*errmsgn)(int, const char *, ...), void (*eexit)(int))); extern int rmtdebug __PR((int dlevel)); extern char *rmtfilename __PR((char *name)); extern char *rmthostname __PR((char *hostname, int hnsize, char *rmtspec)); extern int rmtgetconn __PR((char *host, int trsize, int excode)); extern int rmtopen __PR((int fd, char *fname, int fmode)); extern int rmtclose __PR((int fd)); extern int rmtread __PR((int fd, char *buf, int count)); extern int rmtwrite __PR((int fd, char *buf, int count)); extern off_t rmtseek __PR((int fd, off_t offset, int whence)); extern int rmtioctl __PR((int fd, int cmd, int count)); #ifdef MTWEOF extern int rmtstatus __PR((int fd, struct mtget *mtp)); #endif extern int rmtxstatus __PR((int fd, struct rmtget *mtp)); #ifdef MTWEOF extern void _rmtg2mtg __PR((struct mtget *mtp, struct rmtget *rmtp)); extern int _mtg2rmtg __PR((struct rmtget *rmtp, struct mtget *mtp)); #endif #endif /* _LIBRMT_H */ megactl-0.4.5/schily/maxpath.h000066400000000000000000000040051465722425200162520ustar00rootroot00000000000000/* @(#)maxpath.h 1.6 03/08/23 Copyright 1985, 1995, 1998 J. Schilling */ /* * Definitions for dealing with statically limitations on pathnames * * Copyright (c) 1985, 1995, 1998 J. Schilling */ /* * 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, 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; see the file COPYING. If not, write to the Free Software * Foundation, 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. */ #ifndef _MAXPATH_H #define _MAXPATH_H #ifndef _DIRDEFS_H #include /* Includes mconfig.h if needed */ #endif #ifdef JOS #ifndef _JOS_MAXP_H # include #endif # define FOUND_MAXPATHNAME # define FOUND_MAXFILENAME #else # ifdef MAXPATHLEN # define MAXPATHNAME MAXPATHLEN /* From sys/param.h */ # define FOUND_MAXPATHNAME # else # ifdef PATH_MAX # define MAXPATHNAME PATH_MAX /* From limits.h */ # define FOUND_MAXPATHNAME # else # define MAXPATHNAME 256 /* Is there a limit? */ # endif # endif /* * Don't use defaults here to allow recognition of problems. */ # ifdef MAXNAMELEN # define MAXFILENAME MAXNAMELEN /* From sys/param.h */ # define FOUND_MAXFILENAME # else # ifdef MAXNAMLEN # define MAXFILENAME MAXNAMLEN /* From dirent.h */ # define FOUND_MAXFILENAME # else # ifdef DIRSIZ # define MAXFILENAME DIRSIZ /* From sys/dir.h */ # define FOUND_MAXFILENAME # endif # endif # endif #if !defined(FOUND_MAXFILENAME) && defined(FOUND_DIRSIZE) # define MAXFILENAME DIRSIZE /* From dirdefs.h */ # define FOUND_MAXFILENAME #endif #endif /* JOS */ #endif /* _MAXPATH_H */ megactl-0.4.5/schily/mconfig.h000066400000000000000000000222201465722425200162310ustar00rootroot00000000000000/* @(#)mconfig.h 1.50 04/07/11 Copyright 1995 J. Schilling */ /* * definitions for machine configuration * * Copyright (c) 1995 J. Schilling * * This file must be included before any other file. * If this file is not included before stdio.h you will not be * able to get LARGEFILE support * * Use only cpp instructions. * * NOTE: SING: (Schily Is Not Gnu) */ /* * 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, 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; see the file COPYING. If not, write to the Free Software * Foundation, 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. */ #ifndef _MCONFIG_H #define _MCONFIG_H /* * Tell our users that this is a Schily SING compile environment. */ #define IS_SCHILY /* * This hack that is needed as long as VMS has no POSIX shell. */ #ifdef VMS # define USE_STATIC_CONF #endif #ifdef USE_STATIC_CONF #include /* This is the current static autoconf stuff */ #else #include /* This is the current dynamic autoconf stuff */ #endif #ifdef __cplusplus extern "C" { #endif /* * The NetBSD people want to bother us. * They removed the definition for 'unix' and are bleating for every test * for #if defined(unix). So we need to check for NetBSD early. */ #ifndef IS_UNIX # if defined(__NetBSD__) # define IS_UNIX # endif #endif #ifndef IS_UNIX # if (defined(unix) || defined(__unix) || defined(__unix__)) && !defined(__DJGPP__) # define IS_UNIX # endif #endif #ifdef __MSDOS__ # define IS_MSDOS #endif #if defined(tos) || defined(__tos) # define IS_TOS #endif #ifdef THINK_C # define IS_MAC #endif #if defined(sun) || defined(__sun) || defined(__sun__) # define IS_SUN #endif #if defined(__CYGWIN32__) || defined(__CYGWIN__) # define IS_GCC_WIN32 # define IS_CYGWIN #if defined(unix) || defined(_X86) # define IS_CYGWIN_1 #endif #endif /*--------------------------------------------------------------------------*/ /* * Some magic that cannot (yet) be figured out with autoconf. */ #if defined(sun3) || defined(mc68000) || defined(mc68020) # ifndef HAVE_SCANSTACK # define HAVE_SCANSTACK # endif #endif #ifdef sparc # ifndef HAVE_LDSTUB # define HAVE_LDSTUB # endif # ifndef HAVE_SCANSTACK # define HAVE_SCANSTACK # endif #endif #if defined(__i386_) || defined(i386) # ifndef HAVE_XCHG # define HAVE_XCHG # endif # ifndef HAVE_SCANSTACK # define HAVE_SCANSTACK # endif #endif /* * Use of SCANSTACK is disabled by default */ #ifndef USE_SCANSTACK # undef HAVE_SCANSTACK #else /* * But .... * The tests are much better now, so always give it a chance. */ #ifndef HAVE_SCANSTACK # define HAVE_SCANSTACK #endif #endif /* * Allow to overwrite the defines in the makefiles by calling * * make COPTX=-DFORCE_SCANSTACK */ #ifdef FORCE_SCANSTACK # undef NO_SCANSTACK #ifndef HAVE_SCANSTACK # define HAVE_SCANSTACK #endif #ifndef USE_SCANSTACK # define USE_SCANSTACK #endif #endif /* * This is the global switch to deactivate stack scanning */ #ifdef NO_SCANSTACK # ifdef HAVE_SCANSTACK # undef HAVE_SCANSTACK # endif #endif #ifdef NO_FORK # ifdef HAVE_FORK # undef HAVE_FORK # endif # ifdef HAVE_VFORK # undef HAVE_VFORK # endif #endif #ifdef NO_VFORK # ifdef HAVE_VFORK # undef HAVE_VFORK # endif #endif #if defined(SOL2) || defined(SOL2) || \ defined(S5R4) || defined(__S5R4) || defined(SVR4) # ifndef __SVR4 # define __SVR4 # endif #endif #ifdef __SVR4 # ifndef SVR4 # define SVR4 # endif #endif /* * SunOS 4.x / SunOS 5.x */ #if defined(IS_SUN) # define HAVE_GETAV0 #endif /* * AIX */ #if defined(_IBMR2) || defined(_AIX) # ifndef IS_UNIX # define IS_UNIX /* ??? really ??? */ # endif #endif /* * QNX */ #if defined(__QNX__) # ifndef IS_UNIX # define IS_UNIX # endif #endif /* * Silicon Graphics (must be before SVR4) */ #if defined(sgi) || defined(__sgi) # define __NOT_SVR4__ /* Not a real SVR4 implementation */ #endif /* * Data General */ #if defined(__DGUX__) #ifdef XXXXXXX # undef HAVE_MTGET_DSREG # undef HAVE_MTGET_RESID # undef HAVE_MTGET_FILENO # undef HAVE_MTGET_BLKNO #endif # define mt_type mt_model # define mt_dsreg mt_status1 # define mt_erreg mt_status2 /* * DGUX hides its flock as dg_flock. */ # define HAVE_FLOCK # define flock dg_flock /* * Use the BSD style wait on DGUX to get the resource usages of child * processes. */ # define _BSD_WAIT_FLAVOR #endif /* * Apple Rhapsody (This is the name for Mac OS X beta) */ #if defined(__NeXT__) && defined(__TARGET_OSNAME) && __TARGET_OSNAME == rhapsody # define HAVE_OSDEF /* prevent later definitions to overwrite current */ # ifndef IS_UNIX # define IS_UNIX # endif #endif /* * NextStep */ #if defined(__NeXT__) && !defined(HAVE_OSDEF) #define NO_PRINT_OVR #undef HAVE_USG_STDIO /* * NeXT Step 3.x uses __flsbuf(unsigned char, FILE *) * instead of __flsbuf(int, FILE *) */ # ifndef IS_UNIX # define IS_UNIX # endif #endif /* * Mac OS X */ #if defined(__APPLE__) && defined(__MACH__) # ifndef IS_UNIX # define IS_UNIX # endif # define IS_MACOS_X #endif /* * NextStep 3.x has a broken linker that does not allow us to override * these functions. */ #ifndef __OPRINTF__ #ifdef NO_PRINT_OVR # define printf Xprintf # define fprintf Xfprintf # define sprintf Xsprintf #endif #endif /* __OPRINTF__ */ /*--------------------------------------------------------------------------*/ /* * If there is no flock defined by the system, use emulation * through fcntl record locking. */ #ifndef HAVE_FLOCK #define LOCK_SH 1 /* shared lock */ #define LOCK_EX 2 /* exclusive lock */ #define LOCK_NB 4 /* don't block when locking */ #define LOCK_UN 8 /* unlock */ #endif #ifndef _PROTOTYP_H #include #endif /* * gcc 2.x generally implements the long long type. */ #ifdef __GNUC__ # if __GNUC__ > 1 # ifndef HAVE_LONGLONG # define HAVE_LONGLONG # endif # endif #endif #ifdef __CHAR_UNSIGNED__ /* GNU GCC define (dynamic) */ #ifndef CHAR_IS_UNSIGNED #define CHAR_IS_UNSIGNED /* Sing Schily define (static) */ #endif #endif /* * Convert to GNU name */ #ifdef HAVE_STDC_HEADERS # ifndef STDC_HEADERS # define STDC_HEADERS # endif #endif /* * Convert to SCHILY name */ #ifdef STDC_HEADERS # ifndef HAVE_STDC_HEADERS # define HAVE_STDC_HEADERS # endif #endif #ifdef IS_UNIX # define HAVE_PATH_DELIM # define PATH_DELIM '/' # define PATH_DELIM_STR "/" # define PATH_ENV_DELIM ':' # define PATH_ENV_DELIM_STR ":" # define far # define near #endif /* * Win32 with Gygwin */ #ifdef IS_GCC_WIN32 # define HAVE_PATH_DELIM # define PATH_DELIM '/' # define PATH_DELIM_STR "/" # define PATH_ENV_DELIM ':' # define PATH_ENV_DELIM_STR ":" # define HAVE_DOS_DRIVELETTER # define far # define near # define NEED_O_BINARY #endif /* * Win32 with Mingw32 */ #ifdef __MINGW32__ # define HAVE_PATH_DELIM # define PATH_DELIM '/' # define PATH_DELIM_STR "/" # define PATH_ENV_DELIM ';' # define PATH_ENV_DELIM_STR ";" # define HAVE_DOS_DRIVELETTER # define far # define near # define NEED_O_BINARY #endif /* * OS/2 EMX */ #ifdef __EMX__ /* We don't want to call it UNIX */ # define HAVE_PATH_DELIM # define PATH_DELIM '/' # define PATH_DELIM_STR "/" # define PATH_ENV_DELIM ';' # define PATH_ENV_DELIM_STR ";" # define HAVE_DOS_DRIVELETTER # define far # define near # define NEED_O_BINARY #endif #ifdef __BEOS__ /* We don't want to call it UNIX */ # define HAVE_PATH_DELIM # define PATH_DELIM '/' # define PATH_DELIM_STR "/" # define PATH_ENV_DELIM ':' # define PATH_ENV_DELIM_STR ":" # define far # define near #endif /* * DOS with DJGPP */ #ifdef __DJGPP__ /* We don't want to call it UNIX */ # define HAVE_PATH_DELIM # define PATH_DELIM '/' # define PATH_DELIM_STR "/" # define PATH_ENV_DELIM ';' # define PATH_ENV_DELIM_STR ";" # define HAVE_DOS_DRIVELETTER # define NEED_O_BINARY #endif /* * Vanilla DOS */ #if defined(IS_MSDOS) && !defined(__DJGPP__) # define HAVE_PATH_DELIM # define PATH_DELIM '\\' # define PATH_DELIM_STR "\\" # define PATH_ENV_DELIM ';' # define PATH_ENV_DELIM_STR ";" # define HAVE_DOS_DRIVELETTER # define NEED_O_BINARY #endif /* * ATARI TOS */ #ifdef IS_TOS # define HAVE_PATH_DELIM # define PATH_DELIM '\\' # define PATH_DELIM_STR "\\" # define PATH_ENV_DELIM ',' # define PATH_ENV_DELIM_STR "," # define HAVE_DOS_DRIVELETTER # define far # define near #endif /* * Mac OS 9 */ #ifdef IS_MAC # define HAVE_PATH_DELIM # define PATH_DELIM ':' # define PATH_DELIM_STR ":" # define PATH_ENV_DELIM ';' /* ??? */ # define PATH_ENV_DELIM_STR ";" /* ??? */ # define far # define near #endif /* * I hope this will make compilation on unknown OS easier. */ #ifndef HAVE_PATH_DELIM /* Default to POSIX rules */ # define HAVE_PATH_DELIM # define PATH_DELIM '/' # define PATH_DELIM_STR "/" # define PATH_ENV_DELIM ':' # define PATH_ENV_DELIM_STR ":" # define far # define near #endif #ifdef __cplusplus } #endif #endif /* _MCONFIG_H */ megactl-0.4.5/schily/mmapdefs.h000066400000000000000000000027531465722425200164140ustar00rootroot00000000000000/* @(#)mmapdefs.h 1.1 01/02/25 Copyright 2001 J. Schilling */ /* * Definitions to be used for mmap() * * Copyright (c) 2001 J. Schilling */ /* * 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, 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; see the file COPYING. If not, write to * the Free Software Foundation, 675 Mass Ave, Cambridge, MA 02139, USA. */ #ifndef _MMAPDEFS_H #define _MMAPDEFS_H #ifndef _MCONFIG_H #include #endif #ifndef _INCL_SYS_TYPES_H #include #define _INCL_SYS_TYPES_H #endif #if defined(HAVE_SMMAP) #ifndef _INCL_SYS_MMAN_H #include #define _INCL_SYS_MMAN_H #endif #ifndef MAP_ANONYMOUS # ifdef MAP_ANON # define MAP_ANONYMOUS MAP_ANON # endif #endif #ifndef MAP_FILE # define MAP_FILE 0 /* Needed on Apollo Domain/OS */ #endif /* * Needed for Apollo Domain/OS and may be for others? */ #ifdef _MMAP_WITH_SIZEP # define mmap_sizeparm(s) (&(s)) #else # define mmap_sizeparm(s) (s) #endif #endif /* defined(HAVE_SMMAP) */ #endif /* _MMAPDEFS_H */ megactl-0.4.5/schily/mtiodefs.h000066400000000000000000000054211465722425200164250ustar00rootroot00000000000000/* @(#)mtiodefs.h 1.4 02/08/26 Copyright 1995,2000-2002 J. Schilling */ /* * Generic header for users of magnetic tape ioctl interface. * * If there is no local mtio.h or equivalent, define * simplified mtio definitions here in order * to be able to do at least remote mtio on systems * that have no local mtio * * Copyright (c) 1995,2000-2002 J. Schilling */ /* * 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, 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; see the file COPYING. If not, write to * the Free Software Foundation, 675 Mass Ave, Cambridge, MA 02139, USA. */ #ifndef _MTIODEFS_H #define _MTIODEFS_H #ifndef _MCONFIG_H #include #endif #ifdef HAVE_SYS_MTIO_H #include #else /* ! HAVE_SYS_MTIO_H */ #ifdef __cplusplus extern "C" { #endif /* * Definitions for magnetic tape io control commands */ /* * structure for MTIOCTOP - magnetic tape operation command */ struct mtop { short mt_op; /* op code (see below) */ daddr_t mt_count; /* repeat count or param */ }; /* * op code values for mt_op */ #define MTWEOF 0 /* write EOF record(s) */ #define MTFSF 1 /* fwd space over file mark(s) */ #define MTBSF 2 /* back space over file mark(s) (1/2" only ) */ #define MTFSR 3 /* fwd space record(s) (to inter-record gap) */ #define MTBSR 4 /* back space record(s) (to inter-record gap)*/ #define MTREW 5 /* rewind tape */ #define MTOFFL 6 /* rewind and put the drive offline */ #define MTNOP 7 /* no operation (sets status ?) */ /* * structure for MTIOCGET - magnetic tape get status command */ struct mtget { short mt_type; /* type of magnetic tape device */ /* the next two regs are device dependent */ short mt_dsreg; /* drive status 'register' */ short mt_erreg; /* error 'register' */ daddr_t mt_resid; /* transfer residual count */ daddr_t mt_fileno; /* file # for current position */ daddr_t mt_blkno; /* block # for current position */ }; #define HAVE_MTGET_TYPE #define HAVE_MTGET_DSREG #define HAVE_MTGET_ERREG #define HAVE_MTGET_RESID #define HAVE_MTGET_FILENO #define HAVE_MTGET_BLKNO /* * Define some junk here as software may assume that these two definitions * are always present. */ #define MTIOCGET 0x12340001 #define MTIOCTOP 0x12340002 #ifdef __cplusplus } #endif #endif /* HAVE_SYS_MTIO_H */ #endif /* _MTIODEFS_H */ megactl-0.4.5/schily/patmatch.h000066400000000000000000000073611465722425200164210ustar00rootroot00000000000000/* @(#)patmatch.h 1.10 03/08/24 Copyright 1985 J. Schilling */ #ifndef _PATMATCH_H #define _PATMATCH_H /* * Definitions for the pattern matching functions. * * Copyright (c) 1985,1995 J. Schilling */ /* * 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, 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; see the file COPYING. If not, write to the Free Software * Foundation, 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. */ /* * The pattern matching functions are based on the algorithm * presented by Martin Richards in: * * "A Compact Function for Regular Expression Pattern Matching", * Software-Practice and Experience, Vol. 9, 527-534 (1979) * * Several changes have been made to the original source which has been * written in BCPL: * * '/' is replaced by '!' (to allow UNIX filenames) * '(',')' are replaced by '{', '}' * '\'' is replaced by '\\' (UNIX compatible quote) * * Character classes have been added to allow "[]" * to be used. * Start of line '^' and end of line '$' have been added. * * Any number in the following comment is zero or more occurrencies */ #ifndef _MCONFIG_H #include #endif #ifndef _PROTOTYP_H #include #endif #ifdef __cplusplus extern "C" { #endif #define ALT '!' /* Alternation in match i.e. this!that!the_other */ #define REP '#' /* Any number of occurrences of the following expr */ #define NIL '%' /* Empty string (exactly nothing) */ #define STAR '*' /* Any number of any character (equivalent of #?) */ #define ANY '?' /* Any one character */ #define QUOTE '\\' /* Quotes the next character */ #define LBRACK '{' /* Begin of precedence grouping */ #define RBRACK '}' /* End of precedence grouping */ #define LCLASS '[' /* Begin of character set */ #define RCLASS ']' /* End of character set */ #define NOT '^' /* If first in set: invert set content */ #define RANGE '-' /* Range notation in sets */ #define START '^' /* Begin of a line */ #define END '$' /* End of a line */ /* * A list of case statements that may be used for a issimple() or ispattern() * funtion that checks whether a string conrtains characters that need the * pattern matcher. * * Note that this list does not contain NOT or RANGE because you need * LCLASS and RCLASS in addition. */ #define casePAT case ALT: case REP: case NIL: case STAR: case ANY: \ case QUOTE: case LBRACK: case RBRACK: \ case LCLASS: case RCLASS: case START: case END: #define MAXPAT 128 /* Maximum length of pattern */ extern int patcompile __PR((const unsigned char * __pat, int __patlen, int * __aux)); extern unsigned char *opatmatch __PR((const unsigned char * __pat, const int * __aux, const unsigned char * __str, int __soff, int __slen, int __alt)); extern unsigned char *opatlmatch __PR((const unsigned char * __pat, const int * __aux, const unsigned char * __str, int __soff, int __slen, int __alt)); extern unsigned char *patmatch __PR((const unsigned char * __pat, const int * __aux, const unsigned char * __str, int __soff, int __slen, int __alt, int __state[])); extern unsigned char *patlmatch __PR((const unsigned char * __pat, const int * __aux, const unsigned char * __str, int __soff, int __slen, int __alt, int __state[])); #ifdef __cplusplus } #endif #endif /* _PATMATCH_H */ megactl-0.4.5/schily/prototyp.h000066400000000000000000000044141465722425200165140ustar00rootroot00000000000000/* @(#)prototyp.h 1.11 03/08/23 Copyright 1995 J. Schilling */ /* * Definitions for dealing with ANSI / KR C-Compilers * * Copyright (c) 1995 J. Schilling */ /* * 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, 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; see the file COPYING. If not, write to the Free Software * Foundation, 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. */ /* * mconfig.h includes prototype.h so we must do this include before we test * for _PROTOTYP_H */ #ifndef _MCONFIG_H #include #endif #ifndef _PROTOTYP_H #define _PROTOTYP_H #ifndef PROTOTYPES /* * If this has already been defined, * someone else knows better than us... */ # ifdef __STDC__ # if __STDC__ /* ANSI C */ # define PROTOTYPES # endif # if defined(sun) && __STDC__ - 0 == 0 /* Sun C */ # define PROTOTYPES # endif # endif #endif /* PROTOTYPES */ #if !defined(PROTOTYPES) && (defined(__cplusplus) || defined(_MSC_VER)) /* * C++ always supports prototypes. * Define PROTOTYPES so we are not forced to make * a separtate autoconf run for C++ * * Microsoft C has prototypes but does not define __STDC__ */ # define PROTOTYPES #endif /* * If we have prototypes, we should have stdlib.h string.h stdarg.h */ #ifdef PROTOTYPES #if !(defined(SABER) && defined(sun)) # ifndef HAVE_STDARG_H # define HAVE_STDARG_H # endif #endif #ifndef JOS # ifndef HAVE_STDLIB_H # define HAVE_STDLIB_H # endif # ifndef HAVE_STRING_H # define HAVE_STRING_H # endif # ifndef HAVE_STDC_HEADERS # define HAVE_STDC_HEADERS # endif # ifndef STDC_HEADERS # define STDC_HEADERS /* GNU name */ # endif #endif #endif #ifdef NO_PROTOTYPES /* Force not to use prototypes */ # undef PROTOTYPES #endif #ifdef PROTOTYPES # define __PR(a) a #else # define __PR(a) () #endif #endif /* _PROTOTYP_H */ megactl-0.4.5/schily/rmtio.h000066400000000000000000000125251465722425200157500ustar00rootroot00000000000000/* @(#)rmtio.h 1.5 03/06/15 Copyright 1995,2000 J. Schilling */ /* * Definition for enhanced remote tape IO * * Copyright (c) 1995,2000-2002 J. Schilling */ /* * 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, 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; see the file COPYING. If not, write to the Free Software * Foundation, 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. */ #ifndef _RMTIO_H #define _RMTIO_H #ifndef _MCONFIG_H #include #endif #ifndef _UTYPES_H #include #endif /* * values for mt_op */ #define RMTWEOF 0 /* write an end-of-file record */ #define RMTFSF 1 /* forward space over file mark */ #define RMTBSF 2 /* backward space over file mark (1/2" only ) */ #define RMTFSR 3 /* forward space to inter-record gap */ #define RMTBSR 4 /* backward space to inter-record gap */ #define RMTREW 5 /* rewind */ #define RMTOFFL 6 /* rewind and put the drive offline */ #define RMTNOP 7 /* no operation, sets status only */ #ifdef __needed__ #define MTRETEN 8 /* retension the tape (cartridge tape only) */ #define MTERASE 9 /* erase the entire tape */ #define MTEOM 10 /* position to end of media */ #define MTNBSF 11 /* backward space file to BOF */ #define MTSRSZ 12 /* set record size */ #define MTGRSZ 13 /* get record size */ #define MTLOAD 14 /* for loading a tape (use o_delay to open */ /* the tape device) */ #endif /* * Definitions for the new RMT Protocol version 1 * * The new Protocol version tries to make the use * of rmtioctl() more portable between different platforms. */ #define RMTIVERSION -1 /* Opcode to request version */ #define RMT_NOVERSION -1 /* Old version code */ #define RMT_VERSION 1 /* New (current) version code */ /* * Support for commands bejond MTWEOF..MTNOP (0..7) */ #define RMTICACHE 0 /* enable controller cache */ #define RMTINOCACHE 1 /* disable controller cache */ #define RMTIRETEN 2 /* retension the tape (cartridge tape only) */ #define RMTIERASE 3 /* erase the entire tape */ #define RMTIEOM 4 /* position to end of media */ #define RMTINBSF 5 /* backward space file to BOF */ /* * Old MTIOCGET copies a binary version of struct mtget back * over the wire. This is highly non portable. * MTS_* retrieves ascii versions (%d format) of a single * field in the struct mtget. * NOTE: MTS_ERREG may only be valid on the first call and * must be retrived first. */ #define MTS_TYPE 'T' /* mtget.mt_type */ #define MTS_DSREG 'D' /* mtget.mt_dsreg */ #define MTS_ERREG 'E' /* mtget.mt_erreg */ #define MTS_RESID 'R' /* mtget.mt_resid */ #define MTS_FILENO 'F' /* mtget.mt_fileno */ #define MTS_BLKNO 'B' /* mtget.mt_blkno */ #define MTS_FLAGS 'f' /* mtget.mt_flags */ #define MTS_BF 'b' /* mtget.mt_bf */ /* * structure for remote MTIOCGET - mag tape get status command */ struct rmtget { Llong mt_type; /* type of magtape device */ /* the following two registers are grossly device dependent */ Llong mt_dsreg; /* ``drive status'' register */ Int32_t mt_dsreg1; /* ``drive status'' register */ Int32_t mt_dsreg2; /* ``drive status'' register */ Llong mt_gstat; /* ``generic status'' register */ Llong mt_erreg; /* ``error'' register */ /* optional error info. */ Llong mt_resid; /* residual count */ Llong mt_fileno; /* file number of current position */ Llong mt_blkno; /* block number of current position */ Llong mt_flags; Llong mt_gflags; /* generic flags */ long mt_bf; /* optimum blocking factor */ int mt_xflags; /* eXistence flags for struct members */ }; /* * Values for mt_xflags */ #define RMT_TYPE 0x0001 /* mt_type/mt_model present */ #define RMT_DSREG 0x0002 /* mt_dsreg present */ #define RMT_DSREG1 0x0004 /* mt_dsreg1 present */ #define RMT_DSREG2 0x0008 /* mt_dsreg2 present */ #define RMT_GSTAT 0x0010 /* mt_gstat present */ #define RMT_ERREG 0x0020 /* mt_erreg present */ #define RMT_RESID 0x0040 /* mt_resid present */ #define RMT_FILENO 0x0080 /* mt_fileno present */ #define RMT_BLKNO 0x0100 /* mt_blkno present */ #define RMT_FLAGS 0x0200 /* mt_flags present */ #define RMT_BF 0x0400 /* mt_bf present */ #define RMT_COMPAT 0x0800 /* Created from old compat data */ /* * values for mt_flags */ #define RMTF_SCSI 0x01 #define RMTF_REEL 0x02 #define RMTF_ASF 0x04 #define RMTF_TAPE_HEAD_DIRTY 0x08 #define RMTF_TAPE_CLN_SUPPORTED 0x10 /* * these are recommended */ #ifdef __needed__ #define MT_ISQIC 0x32 /* generic QIC tape drive */ #define MT_ISREEL 0x33 /* generic reel tape drive */ #define MT_ISDAT 0x34 /* generic DAT tape drive */ #define MT_IS8MM 0x35 /* generic 8mm tape drive */ #define MT_ISOTHER 0x36 /* generic other type of tape drive */ /* more Sun devices */ #define MT_ISTAND25G 0x37 /* sun: SCSI Tandberg 2.5 Gig QIC */ #define MT_ISDLT 0x38 /* sun: SCSI DLT tape drive */ #define MT_ISSTK9840 0x39 /* sun: STK 9840 (Ironsides) */ #endif #endif /* _RMTIO_H */ megactl-0.4.5/schily/scg/000077500000000000000000000000001465722425200152145ustar00rootroot00000000000000megactl-0.4.5/schily/scg/aspi-dos.h000066400000000000000000000166001465722425200171070ustar00rootroot00000000000000#ifndef __ASPI16_H_ #define __ASPI16_H_ #define PACKED __attribute__((packed)) #define FAR typedef unsigned char BYTE; typedef unsigned short WORD; typedef unsigned long DWORD; //***************************************************************************** // %%% SCSI MISCELLANEOUS EQUATES %%% //***************************************************************************** #define SENSE_LEN 14 // Default sense buffer length #define SRB_DIR_SCSI 0x00 // Direction determined by SCSI #define SRB_POSTING 0x01 // Enable ASPI posting #define SRB_ENABLE_RESIDUAL_COUNT 0x04 // Enable residual byte count reporting #define SRB_DIR_IN 0x08 // Transfer from SCSI target to host #define SRB_DIR_OUT 0x10 // Transfer from host to SCSI target //***************************************************************************** // %%% ASPI Command Definitions %%% //***************************************************************************** #define SC_HA_INQUIRY 0x00 // Host adapter inquiry #define SC_GET_DEV_TYPE 0x01 // Get device type #define SC_EXEC_SCSI_CMD 0x02 // Execute SCSI command #define SC_ABORT_SRB 0x03 // Abort an SRB #define SC_RESET_DEV 0x04 // SCSI bus device reset #define SC_SET_HA_PARMS 0x05 // Set HA parameters #define SC_GET_DISK_INFO 0x06 // Get Disk information //***************************************************************************** // %%% SRB Status %%% //***************************************************************************** #define SS_PENDING 0x00 // SRB being processed #define SS_COMP 0x01 // SRB completed without error #define SS_ABORTED 0x02 // SRB aborted #define SS_ABORT_FAIL 0x03 // Unable to abort SRB #define SS_ERR 0x04 // SRB completed with error #define SS_INVALID_CMD 0x80 // Invalid ASPI command #define SS_INVALID_HA 0x81 // Invalid host adapter number #define SS_NO_DEVICE 0x82 // SCSI device not installed //***************************************************************************** // %%% Host Adapter Status %%% //***************************************************************************** #define HASTAT_OK 0x00 // Host adapter did not detect an // error #define HASTAT_SEL_TO 0x11 // Selection Timeout #define HASTAT_DO_DU 0x12 // Data overrun data underrun #define HASTAT_BUS_FREE 0x13 // Unexpected bus free #define HASTAT_PHASE_ERR 0x14 // Target bus phase sequence // failure #define HASTAT_TIMEOUT 0x09 // Timed out while SRB was waiting to beprocessed. #define HASTAT_COMMAND_TIMEOUT 0x0B // Adapter timed out processing SRB. #define HASTAT_MESSAGE_REJECT 0x0D // While processing SRB, the // adapter received a MESSAGE #define HASTAT_BUS_RESET 0x0E // A bus reset was detected. #define HASTAT_PARITY_ERROR 0x0F // A parity error was detected. #define HASTAT_REQUEST_SENSE_FAILED 0x10 // The adapter failed in issuing typedef struct { BYTE Cmd; // 00/000 ASPI command code = SC_EXEC_SCSI_CMD BYTE Status; // 01/001 ASPI command status byte BYTE HaId; // 02/002 ASPI host adapter number BYTE Flags; // 03/003 ASPI request flags DWORD Hdr_Rsvd; // 04/004 Reserved, MUST = 0 union { struct { BYTE Count; // 08/008 Number of host adapters present BYTE SCSI_ID; // 09/009 SCSI ID of host adapter BYTE ManagerId[16]; // 0A/010 String describing the manager BYTE Identifier[16]; // 1A/026 String describing the host adapter BYTE Unique[16]; // 2A/042 Host Adapter Unique parameters BYTE ExtBuffer[8]; // 3A/058 Extended inquiry data } PACKED HAInquiry; struct { BYTE Target; // 08/008 Target's SCSI ID BYTE Lun; // 09/009 Target's LUN number BYTE DeviceType; // 0A/010 Target's peripheral device type } PACKED GetDeviceType; struct { BYTE Target; // 08/008 Target's SCSI ID BYTE Lun; // 09/009 Target's LUN number DWORD BufLen; // 0A/010 Data Allocation Length BYTE SenseLen; // 0E/014 Sense Allocation Length BYTE FAR *BufPointer; // 0F/015 Data Buffer Pointer DWORD Rsvd1; // 13/019 Reserved, MUST = 0 BYTE CDBLen; // 17/023 CDB Length = 6/10/12 BYTE HaStat; // 18/024 Host Adapter Status BYTE TargStat; // 19/025 Target Status VOID FAR *PostProc; // 1A/026 Post routine BYTE Rsvd2[34]; // 1E/030 Reserved, MUST = 0 union { struct { BYTE CDBByte[6]; // 40/064 SCSI CDB BYTE SenseArea[SENSE_LEN+2]; // 46/070 Request Sense buffer } PACKED _6; struct { BYTE CDBByte[10]; // 40/064 SCSI CDB BYTE SenseArea[SENSE_LEN+2]; // 4A/074 Request Sense buffer } PACKED _10; struct { BYTE CDBByte[12]; // 40/064 SCSI CDB BYTE SenseArea[SENSE_LEN+2]; // 4C/076 Request Sense buffer } PACKED _12; } PACKED CmdLen; } PACKED ExecSCSICmd; struct { VOID FAR *SRBToAbort; // 08/008 Pointer to SRB to abort } PACKED Abort; struct { BYTE Target; // 08/008 Target's SCSI ID BYTE Lun; // 09/009 Target's LUN number BYTE ResetRsvd1[14]; // 0A/010 Reserved, MUST = 0 BYTE HaStat; // 18/024 Host Adapter Status BYTE TargStat; // 19/025 Target Status VOID FAR *PostProc; // 1A/026 Post routine BYTE ResetRsvd2[34]; // 1E/030 Reserved, MUST = 0 } Reset; } PACKED Type; } PACKED SRB; #endif //__ASPI16_H_ megactl-0.4.5/schily/scg/aspi-win32.h000066400000000000000000000267341465722425200172750ustar00rootroot00000000000000#ifndef __ASPI_WIN32_H_ #define __ASPI_WIN32_H_ #include /*************************************************************************** ** SCSI MISCELLANEOUS EQUATES ***************************************************************************/ #define SENSE_LEN 14 /* Default sense buffer length */ #define SRB_DIR_SCSI 0x00 /* Direction determined by SCSI */ #define SRB_POSTING 0x01 /* Enable ASPI posting */ #define SRB_ENABLE_RESIDUAL_COUNT 0x04 /* Enable residual byte count */ /* reporting */ #define SRB_DIR_IN 0x08 /* Transfer from SCSI target to */ /* host */ #define SRB_DIR_OUT 0x10 /* Transfer from host to SCSI */ /* target */ #define SRB_EVENT_NOTIFY 0x40 /* Enable ASPI event notification */ #define RESIDUAL_COUNT_SUPPORTED 0x02 /* Extended buffer flag */ #define MAX_SRB_TIMEOUT 1080001u /* 30 hour maximum timeout in sec */ #define DEFAULT_SRB_TIMEOUT 1080001u /* use max.timeout by default */ /*************************************************************************** ** ASPI command definitions ***************************************************************************/ #define SC_HA_INQUIRY 0x00 /* Host adapter inquiry */ #define SC_GET_DEV_TYPE 0x01 /* Get device type */ #define SC_EXEC_SCSI_CMD 0x02 /* Execute SCSI command */ #define SC_ABORT_SRB 0x03 /* Abort an SRB */ #define SC_RESET_DEV 0x04 /* SCSI bus device reset */ #define SC_SET_HA_PARMS 0x05 /* Set HA parameters */ #define SC_GET_DISK_INFO 0x06 /* Get Disk */ #define SC_RESCAN_SCSI_BUS 0x07 /* Rebuild SCSI device map */ #define SC_GETSET_TIMEOUTS 0x08 /* Get/Set target timeouts */ /*************************************************************************** ** SRB Status ***************************************************************************/ #define SS_PENDING 0x00 /* SRB being processed */ #define SS_COMP 0x01 /* SRB completed without error */ #define SS_ABORTED 0x02 /* SRB aborted */ #define SS_ABORT_FAIL 0x03 /* Unable to abort SRB */ #define SS_ERR 0x04 /* SRB completed with error */ #define SS_INVALID_CMD 0x80 /* Invalid ASPI command */ #define SS_INVALID_HA 0x81 /* Invalid host adapter number */ #define SS_NO_DEVICE 0x82 /* SCSI device not installed */ #define SS_INVALID_SRB 0xE0 /* Invalid parameter set in SRB */ #define SS_OLD_MANAGER 0xE1 /* ASPI manager doesn't support */ /* windows */ #define SS_BUFFER_ALIGN 0xE1 /* Buffer not aligned (replaces */ /* SS_OLD_MANAGER in Win32) */ #define SS_ILLEGAL_MODE 0xE2 /* Unsupported Windows mode */ #define SS_NO_ASPI 0xE3 /* No ASPI managers */ #define SS_FAILED_INIT 0xE4 /* ASPI for windows failed init */ #define SS_ASPI_IS_BUSY 0xE5 /* No resources available to */ /* execute command */ #define SS_BUFFER_TO_BIG 0xE6 /* Buffer size too big to handle */ #define SS_BUFFER_TOO_BIG 0xE6 /* Correct spelling of 'too' */ #define SS_MISMATCHED_COMPONENTS 0xE7 /* The DLLs/EXEs of ASPI don't */ /* version check */ #define SS_NO_ADAPTERS 0xE8 /* No host adapters to manager */ #define SS_INSUFFICIENT_RESOURCES 0xE9 /* Couldn't allocate resources */ /* needed to init */ #define SS_ASPI_IS_SHUTDOWN 0xEA /* Call came to ASPI after */ /* PROCESS_DETACH */ #define SS_BAD_INSTALL 0xEB /* The DLL or other components */ /* are installed wrong */ /*************************************************************************** ** Host Adapter Status ***************************************************************************/ #define HASTAT_OK 0x00 /* No error detected by HA */ #define HASTAT_SEL_TO 0x11 /* Selection Timeout */ #define HASTAT_DO_DU 0x12 /* Data overrun/data underrun */ #define HASTAT_BUS_FREE 0x13 /* Unexpected bus free */ #define HASTAT_PHASE_ERR 0x14 /* Target bus phase sequence */ #define HASTAT_TIMEOUT 0x09 /* Timed out while SRB was */ /* waiting to be processed */ #define HASTAT_COMMAND_TIMEOUT 0x0B /* Adapter timed out while */ /* processing SRB */ #define HASTAT_MESSAGE_REJECT 0x0D /* While processing the SRB, the */ /* adapter received a MESSAGE */ #define HASTAT_BUS_RESET 0x0E /* A bus reset was detected */ #define HASTAT_PARITY_ERROR 0x0F /* A parity error was detected */ #define HASTAT_REQUEST_SENSE_FAILED 0x10 /* The adapter failed in issuing */ /*************************************************************************** ** SRB - HOST ADAPTER INQUIRIY - SC_HA_INQUIRY (0) ***************************************************************************/ typedef struct { BYTE SRB_Cmd; /* 00/000 ASPI command code == SC_HA_INQUIRY */ BYTE SRB_Status; /* 01/001 ASPI command status byte */ BYTE SRB_HaId; /* 02/002 ASPI host adapter number */ BYTE SRB_Flags; /* 03/003 ASPI request flags */ DWORD SRB_Hdr_Rsvd; /* 04/004 Reserved, must = 0 */ BYTE HA_Count; /* 08/008 Number of host adapters present */ BYTE HA_SCSI_ID; /* 09/009 SCSI ID of host adapter */ BYTE HA_ManagerId[16]; /* 0a/010 String describing the manager */ BYTE HA_Identifier[16]; /* 1a/026 String describing the host adapter */ BYTE HA_Unique[16]; /* 2a/042 Host Adapter Unique parameters */ WORD HA_Rsvd1; /* 3a/058 Reserved, must = 0 */ } PACKED SRB_HAInquiry, *PSRB_HAInquiry, FAR *LPSRB_HAInquiry; /*************************************************************************** ** SRB - GET DEVICE TYPE - SC_GET_DEV_TYPE (1) ***************************************************************************/ typedef struct { BYTE SRB_Cmd; /* 00/000 ASPI cmd code == SC_GET_DEV_TYPE */ BYTE SRB_Status; /* 01/001 ASPI command status byte */ BYTE SRB_HaId; /* 02/002 ASPI host adapter number */ BYTE SRB_Flags; /* 03/003 Reserved, must = 0 */ DWORD SRB_Hdr_Rsvd; /* 04/004 Reserved, must = 0 */ BYTE SRB_Target; /* 08/008 Target's SCSI ID */ BYTE SRB_Lun; /* 09/009 Target's LUN number */ BYTE SRB_DeviceType; /* 0a/010 Target's peripheral device type */ BYTE SRB_Rsvd1; /* 0b/011 Reserved, must = 0 */ } PACKED SRB_GDEVBlock, *PSRB_GDEVBlock, FAR *LPSRB_GDEVBlock; /*************************************************************************** ** SRB - EXECUTE SCSI COMMAND - SC_EXEC_SCSI_CMD (2) ***************************************************************************/ typedef struct { BYTE SRB_Cmd; /* 00/000 ASPI cmd code == SC_EXEC_SCSI_CMD */ BYTE SRB_Status; /* 01/001 ASPI command status byte */ BYTE SRB_HaId; /* 02/002 ASPI host adapter number */ BYTE SRB_Flags; /* 03/003 Reserved, must = 0 */ DWORD SRB_Hdr_Rsvd; /* 04/004 Reserved, must = 0 */ BYTE SRB_Target; /* 08/008 Target's SCSI ID */ BYTE SRB_Lun; /* 09/009 Target's LUN */ WORD SRB_Rsvd1; /* 0a/010 Reserved for alignment */ DWORD SRB_BufLen; /* 0c/012 Data Allocation Length */ BYTE FAR *SRB_BufPointer; /* 10/016 Data Buffer Pointer */ BYTE SRB_SenseLen; /* 14/020 Sense Allocation Length */ BYTE SRB_CDBLen; /* 15/021 CDB Length */ BYTE SRB_HaStat; /* 16/022 Host Adapter Status */ BYTE SRB_TargStat; /* 17/023 Target Status */ VOID FAR *SRB_PostProc; /* 18/024 Post routine */ BYTE SRB_Rsvd2[20]; /* 1c/028 Reserved, must = 0 */ BYTE CDBByte[16]; /* 30/048 SCSI CDB */ BYTE SenseArea[SENSE_LEN+2]; /* 40/064 Request Sense buffer */ } PACKED SRB_ExecSCSICmd, *PSRB_ExecSCSICmd, FAR *LPSRB_ExecSCSICmd; typedef struct { BYTE SRB_Cmd; /* 00/000 ASPI cmd code == SC_ABORT_SRB */ BYTE SRB_Status; /* 01/001 ASPI command status byte */ BYTE SRB_HaId; /* 02/002 ASPI host adapter number */ BYTE SRB_Flags; /* 03/003 Reserved, must = 0 */ DWORD SRB_Hdr_Rsvd; /* 04/004 Reserved, must = 0 */ void *SRB_ToAbort; /* 08/008 Pointer to SRB to abort */ } PACKED SRB_Abort, *PSRB_Abort, FAR *LPSRB_Abort; /*************************************************************************** ** SRB - BUS DEVICE RESET - SC_RESET_DEV (4) ***************************************************************************/ typedef struct { BYTE SRB_Cmd; /* 00/000 ASPI cmd code == SC_RESET_DEV */ BYTE SRB_Status; /* 01/001 ASPI command status byte */ BYTE SRB_HaId; /* 02/002 ASPI host adapter number */ DWORD SRB_Flags; /* 04/004 Reserved */ BYTE SRB_Target; /* 08/008 Target's SCSI ID */ BYTE SRB_Lun; /* 09/009 Target's LUN number */ BYTE SRB_Rsvd1[12]; /* 0A/010 Reserved for alignment */ BYTE SRB_HaStat; /* 16/022 Host Adapter Status */ BYTE SRB_TargStat; /* 17/023 Target Status */ VOID FAR *SRB_PostProc; /* 18/024 Post routine */ BYTE SRB_Rsvd2[36]; /* 1C/028 Reserved, must = 0 */ } SRB_BusDeviceReset, *PSRB_BusDeviceReset, FAR *LPSRB_BusDeviceReset; typedef struct tag_ASPI32BUFF { PBYTE AB_BufPointer; DWORD AB_BufLen; DWORD AB_ZeroFill; DWORD AB_Reserved; } PACKED ASPI32BUFF, *PASPI32BUFF, FAR *LPASPI32BUFF; typedef struct { BYTE SRB_Cmd; BYTE SRB_Status; BYTE SRB_HaId; BYTE SRB_Flags; DWORD SRB_Hdr_Rsvd; } SRB, *PSRB, FAR *LPSRB; #endif megactl-0.4.5/schily/scg/scgcmd.h000066400000000000000000000144151465722425200166320ustar00rootroot00000000000000/* @(#)scgcmd.h 2.22 04/09/04 Copyright 1986 J. Schilling */ /* * Definitions for the SCSI 'scg_cmd' structure that has been created * for the SCSI general driver 'scg' for SunOS and Solaris but * now is used for wrapping general libscg SCSI transport requests. * * Copyright (c) 1986 J. Schilling */ /* * 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, 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; see the file COPYING. If not, write to the Free Software * Foundation, 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. */ #ifndef _SCG_SCGCMD_H #define _SCG_SCGCMD_H #include #include #if defined(_BIT_FIELDS_LTOH) /* Intel byteorder */ #else # if defined(_BIT_FIELDS_HTOL) /* Motorola byteorder */ # else /* * #error will not work for all compilers (e.g. sunos4) * The following line will abort compilation on all compilers * if none of the above is defines. And that's what we want. */ error One of _BIT_FIELDS_LTOH or _BIT_FIELDS_HTOL must be defined # endif #endif #include #include #include #ifdef __cplusplus extern "C" { #endif /* * Leave these definitions here if possible to avoid the need to * include scsireg.h which makes problems on some OS because these * OS define the same types as in scsireg.h */ /* * SCSI status bits. */ #define ST_VU_00 0x01 /* Vendor unique */ #define ST_CHK_COND 0x02 /* Check condition */ #define ST_COND_MET 0x04 /* Condition met */ #define ST_BUSY 0x08 /* Busy */ #define ST_IS_SEND 0x10 /* Intermediate status send */ #define ST_VU_05 0x20 /* Vendor unique */ #define ST_VU_06 0x40 /* Vendor unique */ #define ST_RSVD_07 0x80 /* Reserved */ /* * Sense key values for extended sense. */ #define SC_NO_SENSE 0x00 #define SC_RECOVERABLE_ERROR 0x01 #define SC_NOT_READY 0x02 #define SC_MEDIUM_ERROR 0x03 #define SC_HARDWARE_ERROR 0x04 #define SC_ILLEGAL_REQUEST 0x05 #define SC_UNIT_ATTENTION 0x06 #define SC_WRITE_PROTECT 0x07 #define SC_BLANK_CHECK 0x08 #define SC_VENDOR_UNIQUE 0x09 #define SC_COPY_ABORTED 0x0A #define SC_ABORTED_COMMAND 0x0B #define SC_EQUAL 0x0C #define SC_VOLUME_OVERFLOW 0x0D #define SC_MISCOMPARE 0x0E #define SC_RESERVED 0x0F /* * Messages that SCSI can send. */ #define SC_COMMAND_COMPLETE 0x00 #define SC_SYNCHRONOUS 0x01 #define SC_SAVE_DATA_PTR 0x02 #define SC_RESTORE_PTRS 0x03 #define SC_DISCONNECT 0x04 #define SC_ABORT 0x06 #define SC_MSG_REJECT 0x07 #define SC_NO_OP 0x08 #define SC_PARITY 0x09 #define SC_IDENTIFY 0x80 #define SC_DR_IDENTIFY 0xc0 #define SC_DEVICE_RESET 0x0c #define SC_G0_CDBLEN 6 /* Len of Group 0 commands */ #define SC_G1_CDBLEN 10 /* Len of Group 1 commands */ #define SC_G5_CDBLEN 12 /* Len of Group 5 commands */ #define SCG_MAX_CMD 24 /* 24 bytes max. size is supported */ #define SCG_MAX_STATUS 3 /* XXX (sollte 4 allign.) Mamimum Status Len */ #define SCG_MAX_SENSE 32 /* Mamimum Sense Len for auto Req. Sense */ #define DEF_SENSE_LEN 16 /* Default Sense Len */ #define CCS_SENSE_LEN 18 /* Sense Len for CCS compatible devices */ struct scg_cmd { caddr_t addr; /* Address of data in user space */ int size; /* DMA count for data transfer */ int flags; /* see below for definition */ int cdb_len; /* Size of SCSI command in bytes */ /* NOTE: rel 4 uses this field only */ /* with commands not in group 1 or 2*/ int sense_len; /* for intr() if -1 don't get sense */ int timeout; /* timeout in seconds */ /* NOTE: actual resolution depends */ /* on driver implementation */ int kdebug; /* driver kernel debug level */ int resid; /* Bytes not transfered */ int error; /* Error code from scgintr() */ int ux_errno; /* UNIX error code */ #ifdef comment XXX struct scsi_status scb; ??? /* Status returnd by command */ #endif union { struct scsi_status Scb; /* Status returnd by command */ Uchar cmd_scb[SCG_MAX_STATUS]; } u_scb; #define scb u_scb.Scb #ifdef comment XXX struct scsi_sense sense; ??? /* Sense bytes from command */ #endif union { struct scsi_sense Sense; /* Sense bytes from command */ Uchar cmd_sense[SCG_MAX_SENSE]; } u_sense; #define sense u_sense.Sense int sense_count; /* Number of bytes valid in sense */ int target; /* SCSI target id */ /* NOTE: The SCSI target id field */ /* does not need to be filled unless */ /* the low level transport is a real */ /* scg driver. In this case the low */ /* level transport routine of libscg */ /* will fill in the needed value */ union { /* SCSI command descriptor block */ struct scsi_g0cdb g0_cdb; struct scsi_g1cdb g1_cdb; struct scsi_g5cdb g5_cdb; Uchar cmd_cdb[SCG_MAX_CMD]; } cdb; /* 24 bytes max. size is supported */ }; #define dma_read flags /* 1 if DMA to Sun, 0 otherwise */ /* * definition for flags field in scg_cmd struct */ #define SCG_RECV_DATA 0x0001 /* DMA direction to Sun */ #define SCG_DISRE_ENA 0x0002 /* enable disconnect/reconnect */ #define SCG_SILENT 0x0004 /* be silent on errors */ #define SCG_CMD_RETRY 0x0008 /* enable retries */ #define SCG_NOPARITY 0x0010 /* disable parity for this command */ /* * definition for error field in scg_cmd struct * * The codes refer to SCSI general errors, not to device * specific errors. Device specific errors are discovered * by checking the sense data. * The distinction between retryable and fatal is somewhat ad hoc. */ #define SCG_NO_ERROR 0 /* cdb transported without error */ /* SCG_NO_ERROR incudes all commands */ /* where the SCSI status is valid */ #define SCG_RETRYABLE 1 /* any other case e.g. SCSI bus busy */ /* SCSI cdb could not be send, */ /* includes DMA errors other than */ /* DMA underrun */ #define SCG_FATAL 2 /* could not select target */ #define SCG_TIMEOUT 3 /* driver timed out */ #ifdef __cplusplus } #endif #endif /* _SCG_SCGCMD_H */ megactl-0.4.5/schily/scg/scgio.h000066400000000000000000000045341465722425200164770ustar00rootroot00000000000000/* @(#)scgio.h 2.16 00/11/07 Copyright 1986 J. Schilling */ /* * Definitions for the SCSI general driver 'scg' * * Copyright (c) 1986 J. Schilling */ /* * 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, 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; see the file COPYING. If not, write to * the Free Software Foundation, 675 Mass Ave, Cambridge, MA 02139, USA. */ #ifndef _SCG_SCGIO_H #define _SCG_SCGIO_H #ifndef _SCG_SCGCMD_H #include #endif #if defined(SVR4) #include #endif #ifdef __cplusplus extern "C" { #endif #if defined(__STDC__) || defined(SVR4) #define SCGIOCMD _IOWR('G', 1, struct scg_cmd) /* do a SCSI cmd */ #define SCGIORESET _IO('G', 2) /* reset SCSI bus */ #define SCGIOGDISRE _IOR('G', 4, int) /* get sc disre Val*/ #define SCGIOSDISRE _IOW('G', 5, int) /* set sc disre Val*/ #define SCGIOIDBG _IO('G', 100) /* Inc Debug Val */ #define SCGIODDBG _IO('G', 101) /* Dec Debug Val */ #define SCGIOGDBG _IOR('G', 102, int) /* get Debug Val */ #define SCGIOSDBG _IOW('G', 103, int) /* set Debug Val */ #define SCIOGDBG _IOR('G', 104, int) /* get sc Debug Val*/ #define SCIOSDBG _IOW('G', 105, int) /* set sc Debug Val*/ #else #define SCGIOCMD _IOWR(G, 1, struct scg_cmd) /* do a SCSI cmd */ #define SCGIORESET _IO(G, 2) /* reset SCSI bus */ #define SCGIOGDISRE _IOR(G, 4, int) /* get sc disre Val*/ #define SCGIOSDISRE _IOW(G, 5, int) /* set sc disre Val*/ #define SCGIOIDBG _IO(G, 100) /* Inc Debug Val */ #define SCGIODDBG _IO(G, 101) /* Dec Debug Val */ #define SCGIOGDBG _IOR(G, 102, int) /* get Debug Val */ #define SCGIOSDBG _IOW(G, 103, int) /* set Debug Val */ #define SCIOGDBG _IOR(G, 104, int) /* get sc Debug Val*/ #define SCIOSDBG _IOW(G, 105, int) /* set sc Debug Val*/ #endif #define SCGIO_CMD SCGIOCMD /* backward ccompatibility */ #ifdef __cplusplus } #endif #endif /* _SCG_SCGIO_H */ megactl-0.4.5/schily/scg/scgops.h000066400000000000000000000051531465722425200166670ustar00rootroot00000000000000/* @(#)scgops.h 1.5 02/10/19 Copyright 2000 J. Schilling */ /* * Copyright (c) 2000 J. Schilling */ /* * 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, 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; see the file COPYING. If not, write to * the Free Software Foundation, 675 Mass Ave, Cambridge, MA 02139, USA. */ #ifndef _SCG_SCGOPS_H #define _SCG_SCGOPS_H #ifdef __cplusplus extern "C" { #endif typedef struct scg_ops { int (*scgo_send) __PR((SCSI *scgp)); char * (*scgo_version) __PR((SCSI *scgp, int what)); #ifdef EOF /* stdio.h has been included */ int (*scgo_help) __PR((SCSI *scgp, FILE *f)); #else int (*scgo_help) __PR((SCSI *scgp, void *f)); #endif int (*scgo_open) __PR((SCSI *scgp, char *device)); int (*scgo_close) __PR((SCSI *scgp)); long (*scgo_maxdma) __PR((SCSI *scgp, long amt)); void * (*scgo_getbuf) __PR((SCSI *scgp, long amt)); void (*scgo_freebuf) __PR((SCSI *scgp)); BOOL (*scgo_havebus) __PR((SCSI *scgp, int busno)); int (*scgo_fileno) __PR((SCSI *scgp, int busno, int tgt, int tlun)); int (*scgo_initiator_id) __PR((SCSI *scgp)); int (*scgo_isatapi) __PR((SCSI *scgp)); int (*scgo_reset) __PR((SCSI *scgp, int what)); } scg_ops_t; #define SCGO_SEND(scgp) (*(scgp)->ops->scgo_send)(scgp) #define SCGO_VERSION(scgp, what) (*(scgp)->ops->scgo_version)(scgp, what) #define SCGO_HELP(scgp, f) (*(scgp)->ops->scgo_help)(scgp, f) #define SCGO_OPEN(scgp, device) (*(scgp)->ops->scgo_open)(scgp, device) #define SCGO_CLOSE(scgp) (*(scgp)->ops->scgo_close)(scgp) #define SCGO_MAXDMA(scgp, amt) (*(scgp)->ops->scgo_maxdma)(scgp, amt) #define SCGO_GETBUF(scgp, amt) (*(scgp)->ops->scgo_getbuf)(scgp, amt) #define SCGO_FREEBUF(scgp) (*(scgp)->ops->scgo_freebuf)(scgp) #define SCGO_HAVEBUS(scgp, busno) (*(scgp)->ops->scgo_havebus)(scgp, busno) #define SCGO_FILENO(scgp, busno, tgt, tlun) (*(scgp)->ops->scgo_fileno)(scgp, busno, tgt, tlun) #define SCGO_INITIATOR_ID(scgp) (*(scgp)->ops->scgo_initiator_id)(scgp) #define SCGO_ISATAPI(scgp) (*(scgp)->ops->scgo_isatapi)(scgp) #define SCGO_RESET(scgp, what) (*(scgp)->ops->scgo_reset)(scgp, what) #ifdef __cplusplus } #endif #endif /* _SCG_SCGOPS_H */ megactl-0.4.5/schily/scg/scsicdb.h000066400000000000000000000210601465722425200167760ustar00rootroot00000000000000/* @(#)scsicdb.h 2.19 04/09/04 Copyright 1986 J. Schilling */ /* * Definitions for the SCSI Command Descriptor Block * * Copyright (c) 1986 J. Schilling */ /* * 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, 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; see the file COPYING. If not, write to the Free Software * Foundation, 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. */ #ifndef _SCG_SCSICDB_H #define _SCG_SCSICDB_H #ifndef _UTYPES_H #include #endif #ifdef __cplusplus extern "C" { #endif /* * SCSI Operation codes. */ #define SC_TEST_UNIT_READY 0x00 #define SC_REZERO_UNIT 0x01 #define SC_REQUEST_SENSE 0x03 #define SC_FORMAT 0x04 #define SC_FORMAT_TRACK 0x06 #define SC_REASSIGN_BLOCK 0x07 /* CCS only */ #define SC_SEEK 0x0b #define SC_TRANSLATE 0x0f /* ACB4000 only */ #define SC_INQUIRY 0x12 /* CCS only */ #define SC_MODE_SELECT 0x15 #define SC_RESERVE 0x16 #define SC_RELEASE 0x17 #define SC_MODE_SENSE 0x1a #define SC_START 0x1b #define SC_READ_DEFECT_LIST 0x37 /* CCS only, group 1 */ #define SC_READ_BUFFER 0x3c /* CCS only, group 1 */ /* * Note, these two commands use identical command blocks for all * controllers except the Adaptec ACB 4000 which sets bit 1 of byte 1. */ #define SC_READ 0x08 #define SC_WRITE 0x0a #define SC_EREAD 0x28 /* 10 byte read */ #define SC_EWRITE 0x2a /* 10 byte write */ #define SC_WRITE_VERIFY 0x2e /* 10 byte write+verify */ #define SC_WRITE_FILE_MARK 0x10 #define SC_UNKNOWN 0xff /* cmd list terminator */ /* * Standard SCSI control blocks. * These go in or out over the SCSI bus. */ #if defined(_BIT_FIELDS_LTOH) /* Intel byteorder */ struct scsi_g0cdb { /* scsi group 0 command description block */ Uchar cmd; /* command code */ Ucbit high_addr : 5; /* high part of block address */ Ucbit lun : 3; /* logical unit number */ Uchar mid_addr; /* middle part of block address */ Uchar low_addr; /* low part of block address */ Uchar count; /* transfer length */ Ucbit link : 1; /* link (another command follows) */ Ucbit fr : 1; /* flag request (interrupt at completion) */ Ucbit naca : 1; /* Normal ACA (Auto Contingent Allegiance) */ Ucbit rsvd : 3; /* reserved */ Ucbit vu_56 : 1; /* vendor unique (byte 5 bit 6) */ Ucbit vu_57 : 1; /* vendor unique (byte 5 bit 7) */ }; #else /* Motorola byteorder */ struct scsi_g0cdb { /* scsi group 0 command description block */ Uchar cmd; /* command code */ Ucbit lun : 3; /* logical unit number */ Ucbit high_addr : 5; /* high part of block address */ Uchar mid_addr; /* middle part of block address */ Uchar low_addr; /* low part of block address */ Uchar count; /* transfer length */ Ucbit vu_57 : 1; /* vendor unique (byte 5 bit 7) */ Ucbit vu_56 : 1; /* vendor unique (byte 5 bit 6) */ Ucbit rsvd : 3; /* reserved */ Ucbit naca : 1; /* Normal ACA (Auto Contingent Allegiance) */ Ucbit fr : 1; /* flag request (interrupt at completion) */ Ucbit link : 1; /* link (another command follows) */ }; #endif #if defined(_BIT_FIELDS_LTOH) /* Intel byteorder */ struct scsi_g1cdb { /* scsi group 1 command description block */ Uchar cmd; /* command code */ Ucbit reladr : 1; /* address is relative */ Ucbit res : 4; /* reserved bits 1-4 of byte 1 */ Ucbit lun : 3; /* logical unit number */ Uchar addr[4]; /* logical block address */ Uchar res6; /* reserved byte 6 */ Uchar count[2]; /* transfer length */ Ucbit link : 1; /* link (another command follows) */ Ucbit fr : 1; /* flag request (interrupt at completion) */ Ucbit naca : 1; /* Normal ACA (Auto Contingent Allegiance) */ Ucbit rsvd : 3; /* reserved */ Ucbit vu_96 : 1; /* vendor unique (byte 5 bit 6) */ Ucbit vu_97 : 1; /* vendor unique (byte 5 bit 7) */ }; #else /* Motorola byteorder */ struct scsi_g1cdb { /* scsi group 1 command description block */ Uchar cmd; /* command code */ Ucbit lun : 3; /* logical unit number */ Ucbit res : 4; /* reserved bits 1-4 of byte 1 */ Ucbit reladr : 1; /* address is relative */ Uchar addr[4]; /* logical block address */ Uchar res6; /* reserved byte 6 */ Uchar count[2]; /* transfer length */ Ucbit vu_97 : 1; /* vendor unique (byte 5 bit 7) */ Ucbit vu_96 : 1; /* vendor unique (byte 5 bit 6) */ Ucbit rsvd : 3; /* reserved */ Ucbit naca : 1; /* Normal ACA (Auto Contingent Allegiance) */ Ucbit fr : 1; /* flag request (interrupt at completion) */ Ucbit link : 1; /* link (another command follows) */ }; #endif #if defined(_BIT_FIELDS_LTOH) /* Intel byteorder */ struct scsi_g5cdb { /* scsi group 5 command description block */ Uchar cmd; /* command code */ Ucbit reladr : 1; /* address is relative */ Ucbit res : 4; /* reserved bits 1-4 of byte 1 */ Ucbit lun : 3; /* logical unit number */ Uchar addr[4]; /* logical block address */ Uchar count[4]; /* transfer length */ Uchar res10; /* reserved byte 10 */ Ucbit link : 1; /* link (another command follows) */ Ucbit fr : 1; /* flag request (interrupt at completion) */ Ucbit naca : 1; /* Normal ACA (Auto Contingent Allegiance) */ Ucbit rsvd : 3; /* reserved */ Ucbit vu_B6 : 1; /* vendor unique (byte B bit 6) */ Ucbit vu_B7 : 1; /* vendor unique (byte B bit 7) */ }; #else /* Motorola byteorder */ struct scsi_g5cdb { /* scsi group 5 command description block */ Uchar cmd; /* command code */ Ucbit lun : 3; /* logical unit number */ Ucbit res : 4; /* reserved bits 1-4 of byte 1 */ Ucbit reladr : 1; /* address is relative */ Uchar addr[4]; /* logical block address */ Uchar count[4]; /* transfer length */ Uchar res10; /* reserved byte 10 */ Ucbit vu_B7 : 1; /* vendor unique (byte B bit 7) */ Ucbit vu_B6 : 1; /* vendor unique (byte B bit 6) */ Ucbit rsvd : 3; /* reserved */ Ucbit naca : 1; /* Normal ACA (Auto Contingent Allegiance) */ Ucbit fr : 1; /* flag request (interrupt at completion) */ Ucbit link : 1; /* link (another command follows) */ }; #endif #define g0_cdbaddr(cdb, a) ((cdb)->high_addr = (a) >> 16,\ (cdb)->mid_addr = ((a) >> 8) & 0xFF,\ (cdb)->low_addr = (a) & 0xFF) #define g1_cdbaddr(cdb, a) ((cdb)->addr[0] = (a) >> 24,\ (cdb)->addr[1] = ((a) >> 16)& 0xFF,\ (cdb)->addr[2] = ((a) >> 8) & 0xFF,\ (cdb)->addr[3] = (a) & 0xFF) #define g5_cdbaddr(cdb, a) g1_cdbaddr(cdb, a) #define g0_cdblen(cdb, len) ((cdb)->count = (len)) #define g1_cdblen(cdb, len) ((cdb)->count[0] = ((len) >> 8) & 0xFF,\ (cdb)->count[1] = (len) & 0xFF) #define g5_cdblen(cdb, len) ((cdb)->count[0] = (len) >> 24L,\ (cdb)->count[1] = ((len) >> 16L)& 0xFF,\ (cdb)->count[2] = ((len) >> 8L) & 0xFF,\ (cdb)->count[3] = (len) & 0xFF) /*#define XXXXX*/ #ifdef XXXXX #define i_to_long(a, i) (((Uchar *)(a))[0] = ((i) >> 24)& 0xFF,\ ((Uchar *)(a))[1] = ((i) >> 16)& 0xFF,\ ((Uchar *)(a))[2] = ((i) >> 8) & 0xFF,\ ((Uchar *)(a))[3] = (i) & 0xFF) #define i_to_3_byte(a, i) (((Uchar *)(a))[0] = ((i) >> 16)& 0xFF,\ ((Uchar *)(a))[1] = ((i) >> 8) & 0xFF,\ ((Uchar *)(a))[2] = (i) & 0xFF) #define i_to_4_byte(a, i) (((Uchar *)(a))[0] = ((i) >> 24)& 0xFF,\ ((Uchar *)(a))[1] = ((i) >> 16)& 0xFF,\ ((Uchar *)(a))[2] = ((i) >> 8) & 0xFF,\ ((Uchar *)(a))[3] = (i) & 0xFF) #define i_to_short(a, i) (((Uchar *)(a))[0] = ((i) >> 8) & 0xFF,\ ((Uchar *)(a))[1] = (i) & 0xFF) #define a_to_u_short(a) ((unsigned short) \ ((((Uchar*) a)[1] & 0xFF) | \ (((Uchar*) a)[0] << 8 & 0xFF00))) #define a_to_3_byte(a) ((Ulong) \ ((((Uchar*) a)[2] & 0xFF) | \ (((Uchar*) a)[1] << 8 & 0xFF00) | \ (((Uchar*) a)[0] << 16 & 0xFF0000))) #ifdef __STDC__ #define a_to_u_long(a) ((Ulong) \ ((((Uchar*) a)[3] & 0xFF) | \ (((Uchar*) a)[2] << 8 & 0xFF00) | \ (((Uchar*) a)[1] << 16 & 0xFF0000) | \ (((Uchar*) a)[0] << 24 & 0xFF000000UL))) #else #define a_to_u_long(a) ((Ulong) \ ((((Uchar*) a)[3] & 0xFF) | \ (((Uchar*) a)[2] << 8 & 0xFF00) | \ (((Uchar*) a)[1] << 16 & 0xFF0000) | \ (((Uchar*) a)[0] << 24 & 0xFF000000))) #endif #endif /* XXXX */ #ifdef __cplusplus } #endif #endif /* _SCG_SCSICDB_H */ megactl-0.4.5/schily/scg/scsidefs.h000066400000000000000000000036751465722425200172030ustar00rootroot00000000000000/* @(#)scsidefs.h 1.28 04/09/04 Copyright 1988 J. Schilling */ /* * Definitions for SCSI devices i.e. for error strings in scsierrs.c * * Copyright (c) 1988 J. Schilling */ /*@@C@@*/ #ifndef _SCG_SCSIDEFS_H #define _SCG_SCSIDEFS_H #ifdef __cplusplus extern "C" { #endif /* * Disks */ #ifdef DEV_UNKNOWN /* * True64 defines DEV_UNKNOWN in /usr/include/sys/devio.h as "UNKNOWN" */ #undef DEV_UNKNOWN #endif #define DEV_UNKNOWN 0 #define DEV_ACB40X0 1 #define DEV_ACB4000 2 #define DEV_ACB4010 3 #define DEV_ACB4070 4 #define DEV_ACB5500 5 #define DEV_ACB4520A 6 #define DEV_ACB4525 7 #define DEV_MD21 8 #define DEV_MD23 9 #define DEV_NON_CCS_DSK 10 #define DEV_CCS_GENDISK 11 /* * Tapes */ #define DEV_MT02 100 #define DEV_SC4000 101 /* * Printer */ #define DEV_PRT 200 /* * Processors */ #define DEV_PROC 300 /* * Worm */ #define DEV_WORM 400 #define DEV_RXT800S 401 /* * CD-ROM */ #define DEV_CDROM 500 #define DEV_MMC_CDROM 501 #define DEV_MMC_CDR 502 #define DEV_MMC_CDRW 503 #define DEV_MMC_DVD 504 #define DEV_MMC_DVD_WR 505 #define DEV_CDD_521_OLD 510 #define DEV_CDD_521 511 #define DEV_CDD_522 512 #define DEV_PCD_600 513 #define DEV_CDD_2000 514 #define DEV_CDD_2600 515 #define DEV_TYUDEN_EW50 516 #define DEV_YAMAHA_CDR_100 520 #define DEV_YAMAHA_CDR_400 521 #define DEV_PLASMON_RF_4100 530 #define DEV_SONY_CDU_924 540 #define DEV_RICOH_RO_1420C 550 #define DEV_RICOH_RO_1060C 551 #define DEV_TEAC_CD_R50S 560 #define DEV_MATSUSHITA_7501 570 #define DEV_MATSUSHITA_7502 571 #define DEV_PIONEER_DW_S114X 580 #define DEV_PIONEER_DVDR_S101 581 /* * Scanners */ #define DEV_HRSCAN 600 #define DEV_MS300A 601 /* * Optical memory */ #define DEV_SONY_SMO 700 #define old_acb(d) (((d) == DEV_ACB40X0) || \ ((d) == DEV_ACB4000) || ((d) == DEV_ACB4010) || \ ((d) == DEV_ACB4070) || ((d) == DEV_ACB5500)) #define is_ccs(d) (!old_acb(d)) #ifdef __cplusplus } #endif #endif /* _SCG_SCSIDEFS_H */ megactl-0.4.5/schily/scg/scsireg.h000066400000000000000000001077111465722425200170330ustar00rootroot00000000000000/* @(#)scsireg.h 1.31 04/09/04 Copyright 1987 J. Schilling */ /* * usefull definitions for dealing with CCS SCSI - devices * * Copyright (c) 1987 J. Schilling */ /* * 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, 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; see the file COPYING. If not, write to the Free Software * Foundation, 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. */ #ifndef _SCG_SCSIREG_H #define _SCG_SCSIREG_H #include #include #ifdef __cplusplus extern "C" { #endif #if defined(_BIT_FIELDS_LTOH) /* Intel byteorder */ struct scsi_inquiry { Ucbit type : 5; /* 0 */ Ucbit qualifier : 3; /* 0 */ Ucbit type_modifier : 7; /* 1 */ Ucbit removable : 1; /* 1 */ Ucbit ansi_version : 3; /* 2 */ Ucbit ecma_version : 3; /* 2 */ Ucbit iso_version : 2; /* 2 */ Ucbit data_format : 4; /* 3 */ Ucbit res3_54 : 2; /* 3 */ Ucbit termiop : 1; /* 3 */ Ucbit aenc : 1; /* 3 */ Ucbit add_len : 8; /* 4 */ Ucbit sense_len : 8; /* 5 */ /* only Emulex ??? */ Ucbit res2 : 8; /* 6 */ Ucbit softreset : 1; /* 7 */ Ucbit cmdque : 1; Ucbit res7_2 : 1; Ucbit linked : 1; Ucbit sync : 1; Ucbit wbus16 : 1; Ucbit wbus32 : 1; Ucbit reladr : 1; /* 7 */ char vendor_info[8]; /* 8 */ char prod_ident[16]; /* 16 */ char prod_revision[4]; /* 32 */ #ifdef comment char vendor_uniq[20]; /* 36 */ char reserved[40]; /* 56 */ #endif }; /* 96 */ #else /* Motorola byteorder */ struct scsi_inquiry { Ucbit qualifier : 3; /* 0 */ Ucbit type : 5; /* 0 */ Ucbit removable : 1; /* 1 */ Ucbit type_modifier : 7; /* 1 */ Ucbit iso_version : 2; /* 2 */ Ucbit ecma_version : 3; Ucbit ansi_version : 3; /* 2 */ Ucbit aenc : 1; /* 3 */ Ucbit termiop : 1; Ucbit res3_54 : 2; Ucbit data_format : 4; /* 3 */ Ucbit add_len : 8; /* 4 */ Ucbit sense_len : 8; /* 5 */ /* only Emulex ??? */ Ucbit res2 : 8; /* 6 */ Ucbit reladr : 1; /* 7 */ Ucbit wbus32 : 1; Ucbit wbus16 : 1; Ucbit sync : 1; Ucbit linked : 1; Ucbit res7_2 : 1; Ucbit cmdque : 1; Ucbit softreset : 1; char vendor_info[8]; /* 8 */ char prod_ident[16]; /* 16 */ char prod_revision[4]; /* 32 */ #ifdef comment char vendor_uniq[20]; /* 36 */ char reserved[40]; /* 56 */ #endif }; /* 96 */ #endif #ifdef __SCG_COMPAT__ #define info vendor_info #define ident prod_ident #define revision prod_revision #endif /* Peripheral Device Qualifier */ #define INQ_DEV_PRESENT 0x00 /* Physical device present */ #define INQ_DEV_NOTPR 0x01 /* Physical device not present */ #define INQ_DEV_RES 0x02 /* Reserved */ #define INQ_DEV_NOTSUP 0x03 /* Logical unit not supported */ /* Peripheral Device Type */ #define INQ_DASD 0x00 /* Direct-access device (disk) */ #define INQ_SEQD 0x01 /* Sequential-access device (tape) */ #define INQ_PRTD 0x02 /* Printer device */ #define INQ_PROCD 0x03 /* Processor device */ #define INQ_OPTD 0x04 /* Write once device (optical disk) */ #define INQ_WORM 0x04 /* Write once device (optical disk) */ #define INQ_ROMD 0x05 /* CD-ROM device */ #define INQ_SCAN 0x06 /* Scanner device */ #define INQ_OMEM 0x07 /* Optical Memory device */ #define INQ_JUKE 0x08 /* Medium Changer device (jukebox) */ #define INQ_COMM 0x09 /* Communications device */ #define INQ_IT8_1 0x0A /* IT8 */ #define INQ_IT8_2 0x0B /* IT8 */ #define INQ_STARR 0x0C /* Storage array device */ #define INQ_ENCL 0x0D /* Enclosure services device */ #define INQ_SDAD 0x0E /* Simplyfied direct-access device */ #define INQ_OCRW 0x0F /* Optical card reader/writer device */ #define INQ_BRIDGE 0x10 /* Bridging expander device */ #define INQ_OSD 0x11 /* Object based storage device */ #define INQ_ADC 0x12 /* Automation/Drive interface */ #define INQ_WELLKNOWN 0x1E /* Well known logical unit */ #define INQ_NODEV 0x1F /* Unknown or no device */ #define INQ_NOTPR 0x1F /* Logical unit not present (SCSI-1) */ #if defined(_BIT_FIELDS_LTOH) /* Intel byteorder */ struct scsi_mode_header { Ucbit sense_data_len : 8; Uchar medium_type; Ucbit res2 : 4; Ucbit cache : 1; Ucbit res : 2; Ucbit write_prot : 1; Uchar blockdesc_len; }; #else /* Motorola byteorder */ struct scsi_mode_header { Ucbit sense_data_len : 8; Uchar medium_type; Ucbit write_prot : 1; Ucbit res : 2; Ucbit cache : 1; Ucbit res2 : 4; Uchar blockdesc_len; }; #endif struct scsi_modesel_header { Ucbit sense_data_len : 8; Uchar medium_type; Ucbit res2 : 8; Uchar blockdesc_len; }; struct scsi_mode_blockdesc { Uchar density; Uchar nlblock[3]; Ucbit res : 8; Uchar lblen[3]; }; #if defined(_BIT_FIELDS_LTOH) /* Intel byteorder */ struct acb_mode_data { Uchar listformat; Uchar ncyl[2]; Uchar nhead; Uchar start_red_wcurrent[2]; Uchar start_precomp[2]; Uchar landing_zone; Uchar step_rate; Ucbit : 2; Ucbit hard_sec : 1; Ucbit fixed_media : 1; Ucbit : 4; Uchar sect_per_trk; }; #else /* Motorola byteorder */ struct acb_mode_data { Uchar listformat; Uchar ncyl[2]; Uchar nhead; Uchar start_red_wcurrent[2]; Uchar start_precomp[2]; Uchar landing_zone; Uchar step_rate; Ucbit : 4; Ucbit fixed_media : 1; Ucbit hard_sec : 1; Ucbit : 2; Uchar sect_per_trk; }; #endif #if defined(_BIT_FIELDS_LTOH) /* Intel byteorder */ struct scsi_mode_page_header { Ucbit p_code : 6; Ucbit res : 1; Ucbit parsave : 1; Uchar p_len; }; /* * This is a hack that allows mode pages without * any further bitfileds to be defined bitorder independent. */ #define MP_P_CODE \ Ucbit p_code : 6; \ Ucbit p_res : 1; \ Ucbit parsave : 1 #else /* Motorola byteorder */ struct scsi_mode_page_header { Ucbit parsave : 1; Ucbit res : 1; Ucbit p_code : 6; Uchar p_len; }; /* * This is a hack that allows mode pages without * any further bitfileds to be defined bitorder independent. */ #define MP_P_CODE \ Ucbit parsave : 1; \ Ucbit p_res : 1; \ Ucbit p_code : 6 #endif #if defined(_BIT_FIELDS_LTOH) /* Intel byteorder */ struct scsi_mode_page_01 { /* Error recovery Parameters */ MP_P_CODE; /* parsave & pagecode */ Uchar p_len; /* 0x0A = 12 Bytes */ Ucbit disa_correction : 1; /* Byte 2 */ Ucbit term_on_rec_err : 1; Ucbit report_rec_err : 1; Ucbit en_early_corr : 1; Ucbit read_continuous : 1; Ucbit tranfer_block : 1; Ucbit en_auto_reall_r : 1; Ucbit en_auto_reall_w : 1; /* Byte 2 */ Uchar rd_retry_count; /* Byte 3 */ Uchar correction_span; char head_offset_count; char data_strobe_offset; Uchar res; Uchar wr_retry_count; Uchar res_tape[2]; Uchar recov_timelim[2]; }; #else /* Motorola byteorder */ struct scsi_mode_page_01 { /* Error recovery Parameters */ MP_P_CODE; /* parsave & pagecode */ Uchar p_len; /* 0x0A = 12 Bytes */ Ucbit en_auto_reall_w : 1; /* Byte 2 */ Ucbit en_auto_reall_r : 1; Ucbit tranfer_block : 1; Ucbit read_continuous : 1; Ucbit en_early_corr : 1; Ucbit report_rec_err : 1; Ucbit term_on_rec_err : 1; Ucbit disa_correction : 1; /* Byte 2 */ Uchar rd_retry_count; /* Byte 3 */ Uchar correction_span; char head_offset_count; char data_strobe_offset; Uchar res; Uchar wr_retry_count; Uchar res_tape[2]; Uchar recov_timelim[2]; }; #endif #if defined(_BIT_FIELDS_LTOH) /* Intel byteorder */ struct scsi_mode_page_02 { /* Device dis/re connect Parameters */ MP_P_CODE; /* parsave & pagecode */ Uchar p_len; /* 0x0E = 16 Bytes */ Uchar buf_full_ratio; Uchar buf_empt_ratio; Uchar bus_inact_limit[2]; Uchar disc_time_limit[2]; Uchar conn_time_limit[2]; Uchar max_burst_size[2]; /* Start SCSI-2 */ Ucbit data_tr_dis_ctl : 2; Ucbit : 6; Uchar res[3]; }; #else /* Motorola byteorder */ struct scsi_mode_page_02 { /* Device dis/re connect Parameters */ MP_P_CODE; /* parsave & pagecode */ Uchar p_len; /* 0x0E = 16 Bytes */ Uchar buf_full_ratio; Uchar buf_empt_ratio; Uchar bus_inact_limit[2]; Uchar disc_time_limit[2]; Uchar conn_time_limit[2]; Uchar max_burst_size[2]; /* Start SCSI-2 */ Ucbit : 6; Ucbit data_tr_dis_ctl : 2; Uchar res[3]; }; #endif #define DTDC_DATADONE 0x01 /* * Target may not disconnect once * data transfer is started until * all data successfully transferred. */ #define DTDC_CMDDONE 0x03 /* * Target may not disconnect once * data transfer is started until * command completed. */ #if defined(_BIT_FIELDS_LTOH) /* Intel byteorder */ struct scsi_mode_page_03 { /* Direct access format Paramters */ MP_P_CODE; /* parsave & pagecode */ Uchar p_len; /* 0x16 = 24 Bytes */ Uchar trk_per_zone[2]; Uchar alt_sec_per_zone[2]; Uchar alt_trk_per_zone[2]; Uchar alt_trk_per_vol[2]; Uchar sect_per_trk[2]; Uchar bytes_per_phys_sect[2]; Uchar interleave[2]; Uchar trk_skew[2]; Uchar cyl_skew[2]; Ucbit : 3; Ucbit inhibit_save : 1; Ucbit fmt_by_surface : 1; Ucbit removable : 1; Ucbit hard_sec : 1; Ucbit soft_sec : 1; Uchar res[3]; }; #else /* Motorola byteorder */ struct scsi_mode_page_03 { /* Direct access format Paramters */ MP_P_CODE; /* parsave & pagecode */ Uchar p_len; /* 0x16 = 24 Bytes */ Uchar trk_per_zone[2]; Uchar alt_sec_per_zone[2]; Uchar alt_trk_per_zone[2]; Uchar alt_trk_per_vol[2]; Uchar sect_per_trk[2]; Uchar bytes_per_phys_sect[2]; Uchar interleave[2]; Uchar trk_skew[2]; Uchar cyl_skew[2]; Ucbit soft_sec : 1; Ucbit hard_sec : 1; Ucbit removable : 1; Ucbit fmt_by_surface : 1; Ucbit inhibit_save : 1; Ucbit : 3; Uchar res[3]; }; #endif #if defined(_BIT_FIELDS_LTOH) /* Intel byteorder */ struct scsi_mode_page_04 { /* Rigid disk Geometry Parameters */ MP_P_CODE; /* parsave & pagecode */ Uchar p_len; /* 0x16 = 24 Bytes */ Uchar ncyl[3]; Uchar nhead; Uchar start_precomp[3]; Uchar start_red_wcurrent[3]; Uchar step_rate[2]; Uchar landing_zone[3]; Ucbit rot_pos_locking : 2; /* Start SCSI-2 */ Ucbit : 6; /* Start SCSI-2 */ Uchar rotational_off; Uchar res1; Uchar rotation_rate[2]; Uchar res2[2]; }; #else /* Motorola byteorder */ struct scsi_mode_page_04 { /* Rigid disk Geometry Parameters */ MP_P_CODE; /* parsave & pagecode */ Uchar p_len; /* 0x16 = 24 Bytes */ Uchar ncyl[3]; Uchar nhead; Uchar start_precomp[3]; Uchar start_red_wcurrent[3]; Uchar step_rate[2]; Uchar landing_zone[3]; Ucbit : 6; /* Start SCSI-2 */ Ucbit rot_pos_locking : 2; /* Start SCSI-2 */ Uchar rotational_off; Uchar res1; Uchar rotation_rate[2]; Uchar res2[2]; }; #endif #if defined(_BIT_FIELDS_LTOH) /* Intel byteorder */ struct scsi_mode_page_05 { /* Flexible disk Parameters */ MP_P_CODE; /* parsave & pagecode */ Uchar p_len; /* 0x1E = 32 Bytes */ Uchar transfer_rate[2]; Uchar nhead; Uchar sect_per_trk; Uchar bytes_per_phys_sect[2]; Uchar ncyl[2]; Uchar start_precomp[2]; Uchar start_red_wcurrent[2]; Uchar step_rate[2]; Uchar step_pulse_width; Uchar head_settle_delay[2]; Uchar motor_on_delay; Uchar motor_off_delay; Ucbit spc : 4; Ucbit : 4; Ucbit : 5; Ucbit mo : 1; Ucbit ssn : 1; Ucbit trdy : 1; Uchar write_compensation; Uchar head_load_delay; Uchar head_unload_delay; Ucbit pin_2_use : 4; Ucbit pin_34_use : 4; Ucbit pin_1_use : 4; Ucbit pin_4_use : 4; Uchar rotation_rate[2]; Uchar res[2]; }; #else /* Motorola byteorder */ struct scsi_mode_page_05 { /* Flexible disk Parameters */ MP_P_CODE; /* parsave & pagecode */ Uchar p_len; /* 0x1E = 32 Bytes */ Uchar transfer_rate[2]; Uchar nhead; Uchar sect_per_trk; Uchar bytes_per_phys_sect[2]; Uchar ncyl[2]; Uchar start_precomp[2]; Uchar start_red_wcurrent[2]; Uchar step_rate[2]; Uchar step_pulse_width; Uchar head_settle_delay[2]; Uchar motor_on_delay; Uchar motor_off_delay; Ucbit trdy : 1; Ucbit ssn : 1; Ucbit mo : 1; Ucbit : 5; Ucbit : 4; Ucbit spc : 4; Uchar write_compensation; Uchar head_load_delay; Uchar head_unload_delay; Ucbit pin_34_use : 4; Ucbit pin_2_use : 4; Ucbit pin_4_use : 4; Ucbit pin_1_use : 4; Uchar rotation_rate[2]; Uchar res[2]; }; #endif #if defined(_BIT_FIELDS_LTOH) /* Intel byteorder */ struct scsi_mode_page_07 { /* Verify Error recovery */ MP_P_CODE; /* parsave & pagecode */ Uchar p_len; /* 0x0A = 12 Bytes */ Ucbit disa_correction : 1; /* Byte 2 */ Ucbit term_on_rec_err : 1; Ucbit report_rec_err : 1; Ucbit en_early_corr : 1; Ucbit res : 4; /* Byte 2 */ Uchar ve_retry_count; /* Byte 3 */ Uchar ve_correction_span; char res2[5]; /* Byte 5 */ Uchar ve_recov_timelim[2]; /* Byte 10 */ }; #else /* Motorola byteorder */ struct scsi_mode_page_07 { /* Verify Error recovery */ MP_P_CODE; /* parsave & pagecode */ Uchar p_len; /* 0x0A = 12 Bytes */ Ucbit res : 4; /* Byte 2 */ Ucbit en_early_corr : 1; Ucbit report_rec_err : 1; Ucbit term_on_rec_err : 1; Ucbit disa_correction : 1; /* Byte 2 */ Uchar ve_retry_count; /* Byte 3 */ Uchar ve_correction_span; char res2[5]; /* Byte 5 */ Uchar ve_recov_timelim[2]; /* Byte 10 */ }; #endif #if defined(_BIT_FIELDS_LTOH) /* Intel byteorder */ struct scsi_mode_page_08 { /* Caching Parameters */ MP_P_CODE; /* parsave & pagecode */ Uchar p_len; /* 0x0A = 12 Bytes */ Ucbit disa_rd_cache : 1; /* Byte 2 */ Ucbit muliple_fact : 1; Ucbit en_wt_cache : 1; Ucbit res : 5; /* Byte 2 */ Ucbit wt_ret_pri : 4; /* Byte 3 */ Ucbit demand_rd_ret_pri: 4; /* Byte 3 */ Uchar disa_pref_tr_len[2]; /* Byte 4 */ Uchar min_pref[2]; /* Byte 6 */ Uchar max_pref[2]; /* Byte 8 */ Uchar max_pref_ceiling[2]; /* Byte 10 */ }; #else /* Motorola byteorder */ struct scsi_mode_page_08 { /* Caching Parameters */ MP_P_CODE; /* parsave & pagecode */ Uchar p_len; /* 0x0A = 12 Bytes */ Ucbit res : 5; /* Byte 2 */ Ucbit en_wt_cache : 1; Ucbit muliple_fact : 1; Ucbit disa_rd_cache : 1; /* Byte 2 */ Ucbit demand_rd_ret_pri: 4; /* Byte 3 */ Ucbit wt_ret_pri : 4; Uchar disa_pref_tr_len[2]; /* Byte 4 */ Uchar min_pref[2]; /* Byte 6 */ Uchar max_pref[2]; /* Byte 8 */ Uchar max_pref_ceiling[2]; /* Byte 10 */ }; #endif struct scsi_mode_page_09 { /* Peripheral device Parameters */ MP_P_CODE; /* parsave & pagecode */ Uchar p_len; /* >= 0x06 = 8 Bytes */ Uchar interface_id[2]; /* Byte 2 */ Uchar res[4]; /* Byte 4 */ Uchar vendor_specific[1]; /* Byte 8 */ }; #define PDEV_SCSI 0x0000 /* scsi interface */ #define PDEV_SMD 0x0001 /* SMD interface */ #define PDEV_ESDI 0x0002 /* ESDI interface */ #define PDEV_IPI2 0x0003 /* IPI-2 interface */ #define PDEV_IPI3 0x0004 /* IPI-3 interface */ #if defined(_BIT_FIELDS_LTOH) /* Intel byteorder */ struct scsi_mode_page_0A { /* Common device Control Parameters */ MP_P_CODE; /* parsave & pagecode */ Uchar p_len; /* 0x06 = 8 Bytes */ Ucbit rep_log_exeption: 1; /* Byte 2 */ Ucbit res : 7; /* Byte 2 */ Ucbit dis_queuing : 1; /* Byte 3 */ Ucbit queuing_err_man : 1; Ucbit res2 : 2; Ucbit queue_alg_mod : 4; /* Byte 3 */ Ucbit EAENP : 1; /* Byte 4 */ Ucbit UAENP : 1; Ucbit RAENP : 1; Ucbit res3 : 4; Ucbit en_ext_cont_all : 1; /* Byte 4 */ Ucbit res4 : 8; Uchar ready_aen_hold_per[2]; /* Byte 6 */ }; #else /* Motorola byteorder */ struct scsi_mode_page_0A { /* Common device Control Parameters */ MP_P_CODE; /* parsave & pagecode */ Uchar p_len; /* 0x06 = 8 Bytes */ Ucbit res : 7; /* Byte 2 */ Ucbit rep_log_exeption: 1; /* Byte 2 */ Ucbit queue_alg_mod : 4; /* Byte 3 */ Ucbit res2 : 2; Ucbit queuing_err_man : 1; Ucbit dis_queuing : 1; /* Byte 3 */ Ucbit en_ext_cont_all : 1; /* Byte 4 */ Ucbit res3 : 4; Ucbit RAENP : 1; Ucbit UAENP : 1; Ucbit EAENP : 1; /* Byte 4 */ Ucbit res4 : 8; Uchar ready_aen_hold_per[2]; /* Byte 6 */ }; #endif #define CTRL_QMOD_RESTRICT 0x0 #define CTRL_QMOD_UNRESTRICT 0x1 struct scsi_mode_page_0B { /* Medium Types Supported Parameters */ MP_P_CODE; /* parsave & pagecode */ Uchar p_len; /* 0x06 = 8 Bytes */ Uchar res[2]; /* Byte 2 */ Uchar medium_one_supp; /* Byte 4 */ Uchar medium_two_supp; /* Byte 5 */ Uchar medium_three_supp; /* Byte 6 */ Uchar medium_four_supp; /* Byte 7 */ }; #if defined(_BIT_FIELDS_LTOH) /* Intel byteorder */ struct scsi_mode_page_0C { /* Notch & Partition Parameters */ MP_P_CODE; /* parsave & pagecode */ Uchar p_len; /* 0x16 = 24 Bytes */ Ucbit res : 6; /* Byte 2 */ Ucbit logical_notch : 1; Ucbit notched_drive : 1; /* Byte 2 */ Uchar res2; /* Byte 3 */ Uchar max_notches[2]; /* Byte 4 */ Uchar active_notch[2]; /* Byte 6 */ Uchar starting_boundary[4]; /* Byte 8 */ Uchar ending_boundary[4]; /* Byte 12 */ Uchar pages_notched[8]; /* Byte 16 */ }; #else /* Motorola byteorder */ struct scsi_mode_page_0C { /* Notch & Partition Parameters */ MP_P_CODE; /* parsave & pagecode */ Uchar p_len; /* 0x16 = 24 Bytes */ Ucbit notched_drive : 1; /* Byte 2 */ Ucbit logical_notch : 1; Ucbit res : 6; /* Byte 2 */ Uchar res2; /* Byte 3 */ Uchar max_notches[2]; /* Byte 4 */ Uchar active_notch[2]; /* Byte 6 */ Uchar starting_boundary[4]; /* Byte 8 */ Uchar ending_boundary[4]; /* Byte 12 */ Uchar pages_notched[8]; /* Byte 16 */ }; #endif #if defined(_BIT_FIELDS_LTOH) /* Intel byteorder */ struct scsi_mode_page_0D { /* CD-ROM Parameters */ MP_P_CODE; /* parsave & pagecode */ Uchar p_len; /* 0x06 = 8 Bytes */ Uchar res; /* Byte 2 */ Ucbit inact_timer_mult: 4; /* Byte 3 */ Ucbit res2 : 4; /* Byte 3 */ Uchar s_un_per_m_un[2]; /* Byte 4 */ Uchar f_un_per_s_un[2]; /* Byte 6 */ }; #else /* Motorola byteorder */ struct scsi_mode_page_0D { /* CD-ROM Parameters */ MP_P_CODE; /* parsave & pagecode */ Uchar p_len; /* 0x06 = 8 Bytes */ Uchar res; /* Byte 2 */ Ucbit res2 : 4; /* Byte 3 */ Ucbit inact_timer_mult: 4; /* Byte 3 */ Uchar s_un_per_m_un[2]; /* Byte 4 */ Uchar f_un_per_s_un[2]; /* Byte 6 */ }; #endif struct sony_mode_page_20 { /* Sony Format Mode Parameters */ MP_P_CODE; /* parsave & pagecode */ Uchar p_len; /* 0x0A = 12 Bytes */ Uchar format_mode; Uchar format_type; #define num_bands user_band_size /* Gilt bei Type 1 */ Uchar user_band_size[4]; /* Gilt bei Type 0 */ Uchar spare_band_size[2]; Uchar res[2]; }; #if defined(_BIT_FIELDS_LTOH) /* Intel byteorder */ struct toshiba_mode_page_20 { /* Toshiba Speed Control Parameters */ MP_P_CODE; /* parsave & pagecode */ Uchar p_len; /* 0x01 = 3 Bytes */ Ucbit speed : 1; Ucbit res : 7; }; #else /* Motorola byteorder */ struct toshiba_mode_page_20 { /* Toshiba Speed Control Parameters */ MP_P_CODE; /* parsave & pagecode */ Uchar p_len; /* 0x01 = 3 Bytes */ Ucbit res : 7; Ucbit speed : 1; }; #endif #if defined(_BIT_FIELDS_LTOH) /* Intel byteorder */ struct ccs_mode_page_38 { /* CCS Caching Parameters */ MP_P_CODE; /* parsave & pagecode */ Uchar p_len; /* 0x0E = 14 Bytes */ Ucbit cache_table_size: 4; /* Byte 3 */ Ucbit cache_en : 1; Ucbit res2 : 1; Ucbit wr_index_en : 1; Ucbit res : 1; /* Byte 3 */ Uchar threshold; /* Byte 4 Prefetch threshold */ Uchar max_prefetch; /* Byte 5 Max. prefetch */ Uchar max_multiplier; /* Byte 6 Max. prefetch multiplier */ Uchar min_prefetch; /* Byte 7 Min. prefetch */ Uchar min_multiplier; /* Byte 8 Min. prefetch multiplier */ Uchar res3[8]; /* Byte 9 */ }; #else /* Motorola byteorder */ struct ccs_mode_page_38 { /* CCS Caching Parameters */ MP_P_CODE; /* parsave & pagecode */ Uchar p_len; /* 0x0E = 14 Bytes */ Ucbit res : 1; /* Byte 3 */ Ucbit wr_index_en : 1; Ucbit res2 : 1; Ucbit cache_en : 1; Ucbit cache_table_size: 4; /* Byte 3 */ Uchar threshold; /* Byte 4 Prefetch threshold */ Uchar max_prefetch; /* Byte 5 Max. prefetch */ Uchar max_multiplier; /* Byte 6 Max. prefetch multiplier */ Uchar min_prefetch; /* Byte 7 Min. prefetch */ Uchar min_multiplier; /* Byte 8 Min. prefetch multiplier */ Uchar res3[8]; /* Byte 9 */ }; #endif #if defined(_BIT_FIELDS_LTOH) /* Intel byteorder */ struct cd_mode_page_05 { /* write parameters */ MP_P_CODE; /* parsave & pagecode */ Uchar p_len; /* 0x32 = 50 Bytes */ Ucbit write_type : 4; /* Session write type (PACKET/TAO...)*/ Ucbit test_write : 1; /* Do not actually write data */ Ucbit LS_V : 1; /* Link size valid */ Ucbit BUFE : 1; /* Enable Bufunderrun free rec. */ Ucbit res_2_7 : 1; Ucbit track_mode : 4; /* Track mode (Q-sub control nibble) */ Ucbit copy : 1; /* 1st higher gen of copy prot track ~*/ Ucbit fp : 1; /* Fixed packed (if in packet mode) */ Ucbit multi_session : 2; /* Multi session write type */ Ucbit dbtype : 4; /* Data block type */ Ucbit res_4 : 4; /* Reserved */ Uchar link_size; /* Link Size (default is 7) */ Uchar res_6; /* Reserved */ Ucbit host_appl_code : 6; /* Host application code of disk */ Ucbit res_7 : 2; /* Reserved */ Uchar session_format; /* Session format (DA/CDI/XA) */ Uchar res_9; /* Reserved */ Uchar packet_size[4]; /* # of user datablocks/fixed packet */ Uchar audio_pause_len[2]; /* # of blocks where index is zero */ Uchar media_cat_number[16]; /* Media catalog Number (MCN) */ Uchar ISRC[14]; /* ISRC for this track */ Uchar sub_header[4]; Uchar vendor_uniq[4]; }; #else /* Motorola byteorder */ struct cd_mode_page_05 { /* write parameters */ MP_P_CODE; /* parsave & pagecode */ Uchar p_len; /* 0x32 = 50 Bytes */ Ucbit res_2_7 : 1; Ucbit BUFE : 1; /* Enable Bufunderrun free rec. */ Ucbit LS_V : 1; /* Link size valid */ Ucbit test_write : 1; /* Do not actually write data */ Ucbit write_type : 4; /* Session write type (PACKET/TAO...)*/ Ucbit multi_session : 2; /* Multi session write type */ Ucbit fp : 1; /* Fixed packed (if in packet mode) */ Ucbit copy : 1; /* 1st higher gen of copy prot track */ Ucbit track_mode : 4; /* Track mode (Q-sub control nibble) */ Ucbit res_4 : 4; /* Reserved */ Ucbit dbtype : 4; /* Data block type */ Uchar link_size; /* Link Size (default is 7) */ Uchar res_6; /* Reserved */ Ucbit res_7 : 2; /* Reserved */ Ucbit host_appl_code : 6; /* Host application code of disk */ Uchar session_format; /* Session format (DA/CDI/XA) */ Uchar res_9; /* Reserved */ Uchar packet_size[4]; /* # of user datablocks/fixed packet */ Uchar audio_pause_len[2]; /* # of blocks where index is zero */ Uchar media_cat_number[16]; /* Media catalog Number (MCN) */ Uchar ISRC[14]; /* ISRC for this track */ Uchar sub_header[4]; Uchar vendor_uniq[4]; }; #endif #if defined(_BIT_FIELDS_LTOH) /* Intel byteorder */ struct cd_wr_speed_performance { Uchar res0; /* Reserved */ Ucbit rot_ctl_sel : 2; /* Rotational control selected */ Ucbit res_1_27 : 6; /* Reserved */ Uchar wr_speed_supp[2]; /* Supported write speed */ }; struct cd_mode_page_2A { /* CD Cap / mech status */ MP_P_CODE; /* parsave & pagecode */ Uchar p_len; /* 0x14 = 20 Bytes (MMC) */ /* 0x18 = 24 Bytes (MMC-2) */ /* 0x1C >= 28 Bytes (MMC-3) */ Ucbit cd_r_read : 1; /* Reads CD-R media */ Ucbit cd_rw_read : 1; /* Reads CD-RW media */ Ucbit method2 : 1; /* Reads fixed packet method2 media */ Ucbit dvd_rom_read : 1; /* Reads DVD ROM media */ Ucbit dvd_r_read : 1; /* Reads DVD-R media */ Ucbit dvd_ram_read : 1; /* Reads DVD-RAM media */ Ucbit res_2_67 : 2; /* Reserved */ Ucbit cd_r_write : 1; /* Supports writing CD-R media */ Ucbit cd_rw_write : 1; /* Supports writing CD-RW media */ Ucbit test_write : 1; /* Supports emulation write */ Ucbit res_3_3 : 1; /* Reserved */ Ucbit dvd_r_write : 1; /* Supports writing DVD-R media */ Ucbit dvd_ram_write : 1; /* Supports writing DVD-RAM media */ Ucbit res_3_67 : 2; /* Reserved */ Ucbit audio_play : 1; /* Supports Audio play operation */ Ucbit composite : 1; /* Deliveres composite A/V stream */ Ucbit digital_port_2 : 1; /* Supports digital output on port 2 */ Ucbit digital_port_1 : 1; /* Supports digital output on port 1 */ Ucbit mode_2_form_1 : 1; /* Reads Mode-2 form 1 media (XA) */ Ucbit mode_2_form_2 : 1; /* Reads Mode-2 form 2 media */ Ucbit multi_session : 1; /* Reads multi-session media */ Ucbit BUF : 1; /* Supports Buffer under. free rec. */ Ucbit cd_da_supported : 1; /* Reads audio data with READ CD cmd */ Ucbit cd_da_accurate : 1; /* READ CD data stream is accurate */ Ucbit rw_supported : 1; /* Reads R-W sub channel information */ Ucbit rw_deint_corr : 1; /* Reads de-interleved R-W sub chan */ Ucbit c2_pointers : 1; /* Supports C2 error pointers */ Ucbit ISRC : 1; /* Reads ISRC information */ Ucbit UPC : 1; /* Reads media catalog number (UPC) */ Ucbit read_bar_code : 1; /* Supports reading bar codes */ Ucbit lock : 1; /* PREVENT/ALLOW may lock media */ Ucbit lock_state : 1; /* Lock state 0=unlocked 1=locked */ Ucbit prevent_jumper : 1; /* State of prev/allow jumper 0=pres */ Ucbit eject : 1; /* Ejects disc/cartr with STOP LoEj */ Ucbit res_6_4 : 1; /* Reserved */ Ucbit loading_type : 3; /* Loading mechanism type */ Ucbit sep_chan_vol : 1; /* Vol controls each channel separat */ Ucbit sep_chan_mute : 1; /* Mute controls each channel separat*/ Ucbit disk_present_rep: 1; /* Changer supports disk present rep */ Ucbit sw_slot_sel : 1; /* Load empty slot in changer */ Ucbit side_change : 1; /* Side change capable */ Ucbit pw_in_lead_in : 1; /* Reads raw P-W sucode from lead in */ Ucbit res_7 : 2; /* Reserved */ Uchar max_read_speed[2]; /* Max. read speed in KB/s */ Uchar num_vol_levels[2]; /* # of supported volume levels */ Uchar buffer_size[2]; /* Buffer size for the data in KB */ Uchar cur_read_speed[2]; /* Current read speed in KB/s */ Uchar res_16; /* Reserved */ Ucbit res_17_0 : 1; /* Reserved */ Ucbit BCK : 1; /* Data valid on falling edge of BCK */ Ucbit RCK : 1; /* Set: HIGH high LRCK=left channel */ Ucbit LSBF : 1; /* Set: LSB first Clear: MSB first */ Ucbit length : 2; /* 0=32BCKs 1=16BCKs 2=24BCKs 3=24I2c*/ Ucbit res_17 : 2; /* Reserved */ Uchar max_write_speed[2]; /* Max. write speed supported in KB/s*/ Uchar cur_write_speed[2]; /* Current write speed in KB/s */ /* Byte 22 ... Only in MMC-2 */ Uchar copy_man_rev[2]; /* Copy management revision supported*/ Uchar res_24; /* Reserved */ Uchar res_25; /* Reserved */ /* Byte 26 ... Only in MMC-3 */ Uchar res_26; /* Reserved */ Ucbit res_27_27 : 6; /* Reserved */ Ucbit rot_ctl_sel : 2; /* Rotational control selected */ Uchar v3_cur_write_speed[2]; /* Current write speed in KB/s */ Uchar num_wr_speed_des[2]; /* # of wr speed perf descr. tables */ struct cd_wr_speed_performance wr_speed_des[1]; /* wr speed performance descriptor */ /* Actually more (num_wr_speed_des) */ }; #else /* Motorola byteorder */ struct cd_wr_speed_performance { Uchar res0; /* Reserved */ Ucbit res_1_27 : 6; /* Reserved */ Ucbit rot_ctl_sel : 2; /* Rotational control selected */ Uchar wr_speed_supp[2]; /* Supported write speed */ }; struct cd_mode_page_2A { /* CD Cap / mech status */ MP_P_CODE; /* parsave & pagecode */ Uchar p_len; /* 0x14 = 20 Bytes (MMC) */ /* 0x18 = 24 Bytes (MMC-2) */ /* 0x1C >= 28 Bytes (MMC-3) */ Ucbit res_2_67 : 2; /* Reserved */ Ucbit dvd_ram_read : 1; /* Reads DVD-RAM media */ Ucbit dvd_r_read : 1; /* Reads DVD-R media */ Ucbit dvd_rom_read : 1; /* Reads DVD ROM media */ Ucbit method2 : 1; /* Reads fixed packet method2 media */ Ucbit cd_rw_read : 1; /* Reads CD-RW media */ Ucbit cd_r_read : 1; /* Reads CD-R media */ Ucbit res_3_67 : 2; /* Reserved */ Ucbit dvd_ram_write : 1; /* Supports writing DVD-RAM media */ Ucbit dvd_r_write : 1; /* Supports writing DVD-R media */ Ucbit res_3_3 : 1; /* Reserved */ Ucbit test_write : 1; /* Supports emulation write */ Ucbit cd_rw_write : 1; /* Supports writing CD-RW media */ Ucbit cd_r_write : 1; /* Supports writing CD-R media */ Ucbit BUF : 1; /* Supports Buffer under. free rec. */ Ucbit multi_session : 1; /* Reads multi-session media */ Ucbit mode_2_form_2 : 1; /* Reads Mode-2 form 2 media */ Ucbit mode_2_form_1 : 1; /* Reads Mode-2 form 1 media (XA) */ Ucbit digital_port_1 : 1; /* Supports digital output on port 1 */ Ucbit digital_port_2 : 1; /* Supports digital output on port 2 */ Ucbit composite : 1; /* Deliveres composite A/V stream */ Ucbit audio_play : 1; /* Supports Audio play operation */ Ucbit read_bar_code : 1; /* Supports reading bar codes */ Ucbit UPC : 1; /* Reads media catalog number (UPC) */ Ucbit ISRC : 1; /* Reads ISRC information */ Ucbit c2_pointers : 1; /* Supports C2 error pointers */ Ucbit rw_deint_corr : 1; /* Reads de-interleved R-W sub chan */ Ucbit rw_supported : 1; /* Reads R-W sub channel information */ Ucbit cd_da_accurate : 1; /* READ CD data stream is accurate */ Ucbit cd_da_supported : 1; /* Reads audio data with READ CD cmd */ Ucbit loading_type : 3; /* Loading mechanism type */ Ucbit res_6_4 : 1; /* Reserved */ Ucbit eject : 1; /* Ejects disc/cartr with STOP LoEj */ Ucbit prevent_jumper : 1; /* State of prev/allow jumper 0=pres */ Ucbit lock_state : 1; /* Lock state 0=unlocked 1=locked */ Ucbit lock : 1; /* PREVENT/ALLOW may lock media */ Ucbit res_7 : 2; /* Reserved */ Ucbit pw_in_lead_in : 1; /* Reads raw P-W sucode from lead in */ Ucbit side_change : 1; /* Side change capable */ Ucbit sw_slot_sel : 1; /* Load empty slot in changer */ Ucbit disk_present_rep: 1; /* Changer supports disk present rep */ Ucbit sep_chan_mute : 1; /* Mute controls each channel separat*/ Ucbit sep_chan_vol : 1; /* Vol controls each channel separat */ Uchar max_read_speed[2]; /* Max. read speed in KB/s */ Uchar num_vol_levels[2]; /* # of supported volume levels */ Uchar buffer_size[2]; /* Buffer size for the data in KB */ Uchar cur_read_speed[2]; /* Current read speed in KB/s */ Uchar res_16; /* Reserved */ Ucbit res_17 : 2; /* Reserved */ Ucbit length : 2; /* 0=32BCKs 1=16BCKs 2=24BCKs 3=24I2c*/ Ucbit LSBF : 1; /* Set: LSB first Clear: MSB first */ Ucbit RCK : 1; /* Set: HIGH high LRCK=left channel */ Ucbit BCK : 1; /* Data valid on falling edge of BCK */ Ucbit res_17_0 : 1; /* Reserved */ Uchar max_write_speed[2]; /* Max. write speed supported in KB/s*/ Uchar cur_write_speed[2]; /* Current write speed in KB/s */ /* Byte 22 ... Only in MMC-2 */ Uchar copy_man_rev[2]; /* Copy management revision supported*/ Uchar res_24; /* Reserved */ Uchar res_25; /* Reserved */ /* Byte 26 ... Only in MMC-3 */ Uchar res_26; /* Reserved */ Ucbit res_27_27 : 6; /* Reserved */ Ucbit rot_ctl_sel : 2; /* Rotational control selected */ Uchar v3_cur_write_speed[2]; /* Current write speed in KB/s */ Uchar num_wr_speed_des[2]; /* # of wr speed perf descr. tables */ struct cd_wr_speed_performance wr_speed_des[1]; /* wr speed performance descriptor */ /* Actually more (num_wr_speed_des) */ }; #endif #define LT_CADDY 0 #define LT_TRAY 1 #define LT_POP_UP 2 #define LT_RES3 3 #define LT_CHANGER_IND 4 #define LT_CHANGER_CART 5 #define LT_RES6 6 #define LT_RES7 7 struct scsi_mode_data { struct scsi_mode_header header; struct scsi_mode_blockdesc blockdesc; union pagex { struct acb_mode_data acb; struct scsi_mode_page_01 page1; struct scsi_mode_page_02 page2; struct scsi_mode_page_03 page3; struct scsi_mode_page_04 page4; struct scsi_mode_page_05 page5; struct scsi_mode_page_07 page7; struct scsi_mode_page_08 page8; struct scsi_mode_page_09 page9; struct scsi_mode_page_0A pageA; struct scsi_mode_page_0B pageB; struct scsi_mode_page_0C pageC; struct scsi_mode_page_0D pageD; struct sony_mode_page_20 sony20; struct toshiba_mode_page_20 toshiba20; struct ccs_mode_page_38 ccs38; } pagex; }; struct scsi_capacity { Int32_t c_baddr; /* must convert byteorder!! */ Int32_t c_bsize; /* must convert byteorder!! */ }; #if defined(_BIT_FIELDS_LTOH) /* Intel byteorder */ struct scsi_def_header { Ucbit : 8; Ucbit format : 3; Ucbit gdl : 1; Ucbit mdl : 1; Ucbit : 3; Uchar length[2]; }; #else /* Motorola byteorder */ struct scsi_def_header { Ucbit : 8; Ucbit : 3; Ucbit mdl : 1; Ucbit gdl : 1; Ucbit format : 3; Uchar length[2]; }; #endif #if defined(_BIT_FIELDS_LTOH) /* Intel byteorder */ struct scsi_format_header { Ucbit res : 8; /* Adaptec 5500: 1 --> format track */ Ucbit vu : 1; /* Vendor Unique */ Ucbit immed : 1; /* Return Immediately from Format */ Ucbit tryout : 1; /* Check if format parameters OK */ Ucbit ipattern : 1; /* Init patter descriptor present */ Ucbit serr : 1; /* Stop on error */ Ucbit dcert : 1; /* Disable certification */ Ucbit dmdl : 1; /* Disable manufacturer defect list */ Ucbit enable : 1; /* Enable to use the next 3 bits */ Uchar length[2]; /* Length of following list in bytes*/ }; #else /* Motorola byteorder */ struct scsi_format_header { Ucbit res : 8; /* Adaptec 5500: 1 --> format track */ Ucbit enable : 1; /* Enable to use the next 3 bits */ Ucbit dmdl : 1; /* Disable manufacturer defect list */ Ucbit dcert : 1; /* Disable certification */ Ucbit serr : 1; /* Stop on error */ Ucbit ipattern : 1; /* Init patter descriptor present */ Ucbit tryout : 1; /* Check if format parameters OK */ Ucbit immed : 1; /* Return Immediately from Format */ Ucbit vu : 1; /* Vendor Unique */ Uchar length[2]; /* Length of following list in bytes*/ }; #endif struct scsi_def_bfi { Uchar cyl[3]; Uchar head; Uchar bfi[4]; }; struct scsi_def_phys { Uchar cyl[3]; Uchar head; Uchar sec[4]; }; struct scsi_def_list { struct scsi_def_header hd; union { Uchar list_block[1][4]; struct scsi_def_bfi list_bfi[1]; struct scsi_def_phys list_phys[1]; } def_list; }; struct scsi_format_data { struct scsi_format_header hd; union { Uchar list_block[1][4]; struct scsi_def_bfi list_bfi[1]; struct scsi_def_phys list_phys[1]; } def_list; }; #define def_block def_list.list_block #define def_bfi def_list.list_bfi #define def_phys def_list.list_phys #define SC_DEF_BLOCK 0 #define SC_DEF_BFI 4 #define SC_DEF_PHYS 5 #define SC_DEF_VU 6 #define SC_DEF_RES 7 struct scsi_format_cap_header { Uchar res[3]; /* Reserved */ Uchar len; /* Len (a multiple of 8) */ }; #if defined(_BIT_FIELDS_LTOH) /* Intel byteorder */ struct scsi_format_cap_desc { Uchar nblock[4]; /* Number of blocks */ Ucbit desc_type : 2; /* Descriptor type */ Ucbit fmt_type : 6; /* Format Taype */ Uchar blen[3]; /* Logical block length */ }; #else /* Motorola byteorder */ struct scsi_format_cap_desc { Uchar nblock[4]; /* Number of blocks */ Ucbit fmt_type : 6; /* Format Taype */ Ucbit desc_type : 2; /* Descriptor type */ Uchar blen[3]; /* Logical block length */ }; #endif /* * Defines for 'fmt_type'. */ #define FCAP_TYPE_DVDPLUS_FULL 0x26 /* DVD+RW Full Format */ /* * Defines for 'desc_type'. * In case of FCAP_DESC_RES, the descriptor is a formatted capacity descriptor * and the 'blen' field is type dependent. * For all other cases, this is the Current/Maximum Capacity descriptor and * the value of 'fmt_type' is reserved and must be zero. */ #define FCAP_DESC_RES 0 /* Reserved */ #define FCAP_DESC_UNFORM 1 /* Unformatted Media */ #define FCAP_DESC_FORM 2 /* Formatted Media */ #define FCAP_DESC_NOMEDIA 3 /* No Media */ struct scsi_cap_data { struct scsi_format_cap_header hd; struct scsi_format_cap_desc list[1]; }; struct scsi_send_diag_cmd { Uchar cmd; Uchar addr[4]; Ucbit : 8; }; #if defined(_BIT_FIELDS_LTOH) /* Intel byteorder */ struct scsi_sector_header { Uchar cyl[2]; Uchar head; Uchar sec; Ucbit : 5; Ucbit rp : 1; Ucbit sp : 1; Ucbit dt : 1; }; #else /* Motorola byteorder */ struct scsi_sector_header { Uchar cyl[2]; Uchar head; Uchar sec; Ucbit dt : 1; Ucbit sp : 1; Ucbit rp : 1; Ucbit : 5; }; #endif #ifdef __cplusplus } #endif #endif /* _SCG_SCSIREG_H */ megactl-0.4.5/schily/scg/scsisense.h000066400000000000000000000136141465722425200173710ustar00rootroot00000000000000/* @(#)scsisense.h 2.18 04/09/04 Copyright 1986 J. Schilling */ /* * Definitions for the SCSI status code and sense structure * * Copyright (c) 1986 J. Schilling */ /*@@C@@*/ #ifndef _SCG_SCSISENSE_H #define _SCG_SCSISENSE_H #ifdef __cplusplus extern "C" { #endif /* * SCSI status completion block. */ #define SCSI_EXTENDED_STATUS #if defined(_BIT_FIELDS_LTOH) /* Intel byteorder */ struct scsi_status { Ucbit vu_00 : 1; /* vendor unique */ Ucbit chk : 1; /* check condition: sense data available */ Ucbit cm : 1; /* condition met */ Ucbit busy : 1; /* device busy or reserved */ Ucbit is : 1; /* intermediate status sent */ Ucbit vu_05 : 1; /* vendor unique */ #define st_scsi2 vu_05 /* SCSI-2 modifier bit */ Ucbit vu_06 : 1; /* vendor unique */ Ucbit st_rsvd : 1; /* reserved */ #ifdef SCSI_EXTENDED_STATUS #define ext_st1 st_rsvd /* extended status (next byte valid) */ /* byte 1 */ Ucbit ha_er : 1; /* host adapter detected error */ Ucbit reserved: 6; /* reserved */ Ucbit ext_st2 : 1; /* extended status (next byte valid) */ /* byte 2 */ Uchar byte2; /* third byte */ #endif /* SCSI_EXTENDED_STATUS */ }; #else /* Motorola byteorder */ struct scsi_status { Ucbit st_rsvd : 1; /* reserved */ Ucbit vu_06 : 1; /* vendor unique */ Ucbit vu_05 : 1; /* vendor unique */ #define st_scsi2 vu_05 /* SCSI-2 modifier bit */ Ucbit is : 1; /* intermediate status sent */ Ucbit busy : 1; /* device busy or reserved */ Ucbit cm : 1; /* condition met */ Ucbit chk : 1; /* check condition: sense data available */ Ucbit vu_00 : 1; /* vendor unique */ #ifdef SCSI_EXTENDED_STATUS #define ext_st1 st_rsvd /* extended status (next byte valid) */ /* byte 1 */ Ucbit ext_st2 : 1; /* extended status (next byte valid) */ Ucbit reserved: 6; /* reserved */ Ucbit ha_er : 1; /* host adapter detected error */ /* byte 2 */ Uchar byte2; /* third byte */ #endif /* SCSI_EXTENDED_STATUS */ }; #endif /* * OLD Standard (Non Extended) SCSI Sense. Used mainly by the * Adaptec ACB 4000 which is the only controller that * does not support the Extended sense format. */ #if defined(_BIT_FIELDS_LTOH) /* Intel byteorder */ struct scsi_sense { /* scsi sense for error classes 0-6 */ Ucbit code : 7; /* error class/code */ Ucbit adr_val : 1; /* sense data is valid */ #ifdef comment Ucbit high_addr:5; /* high byte of block addr */ Ucbit rsvd : 3; #else Uchar high_addr; /* high byte of block addr */ #endif Uchar mid_addr; /* middle byte of block addr */ Uchar low_addr; /* low byte of block addr */ }; #else /* Motorola byteorder */ struct scsi_sense { /* scsi sense for error classes 0-6 */ Ucbit adr_val : 1; /* sense data is valid */ Ucbit code : 7; /* error class/code */ #ifdef comment Ucbit rsvd : 3; Ucbit high_addr:5; /* high byte of block addr */ #else Uchar high_addr; /* high byte of block addr */ #endif Uchar mid_addr; /* middle byte of block addr */ Uchar low_addr; /* low byte of block addr */ }; #endif /* * SCSI extended sense parameter block. */ #ifdef comment #define SC_CLASS_EXTENDED_SENSE 0x7 /* indicates extended sense */ #endif #if defined(_BIT_FIELDS_LTOH) /* Intel byteorder */ struct scsi_ext_sense { /* scsi extended sense for error class 7 */ /* byte 0 */ Ucbit type : 7; /* fixed at 0x70 */ Ucbit adr_val : 1; /* sense data is valid */ /* byte 1 */ Uchar seg_num; /* segment number, applies to copy cmd only */ /* byte 2 */ Ucbit key : 4; /* sense key, see below */ Ucbit : 1; /* reserved */ Ucbit ili : 1; /* incorrect length indicator */ Ucbit eom : 1; /* end of media */ Ucbit fil_mk : 1; /* file mark on device */ /* bytes 3 through 7 */ Uchar info_1; /* information byte 1 */ Uchar info_2; /* information byte 2 */ Uchar info_3; /* information byte 3 */ Uchar info_4; /* information byte 4 */ Uchar add_len; /* number of additional bytes */ /* bytes 8 through 13, CCS additions */ Uchar optional_8; /* CCS search and copy only */ Uchar optional_9; /* CCS search and copy only */ Uchar optional_10; /* CCS search and copy only */ Uchar optional_11; /* CCS search and copy only */ Uchar sense_code; /* sense code */ Uchar qual_code; /* sense code qualifier */ Uchar fru_code; /* Field replacable unit code */ Ucbit bptr : 3; /* bit pointer for failure (if bpv) */ Ucbit bpv : 1; /* bit pointer is valid */ Ucbit : 2; Ucbit cd : 1; /* pointers refer to command not data */ Ucbit sksv : 1; /* sense key specific valid */ Uchar field_ptr[2]; /* field pointer for failure */ Uchar add_info[2]; /* round up to 20 bytes */ }; #else /* Motorola byteorder */ struct scsi_ext_sense { /* scsi extended sense for error class 7 */ /* byte 0 */ Ucbit adr_val : 1; /* sense data is valid */ Ucbit type : 7; /* fixed at 0x70 */ /* byte 1 */ Uchar seg_num; /* segment number, applies to copy cmd only */ /* byte 2 */ Ucbit fil_mk : 1; /* file mark on device */ Ucbit eom : 1; /* end of media */ Ucbit ili : 1; /* incorrect length indicator */ Ucbit : 1; /* reserved */ Ucbit key : 4; /* sense key, see below */ /* bytes 3 through 7 */ Uchar info_1; /* information byte 1 */ Uchar info_2; /* information byte 2 */ Uchar info_3; /* information byte 3 */ Uchar info_4; /* information byte 4 */ Uchar add_len; /* number of additional bytes */ /* bytes 8 through 13, CCS additions */ Uchar optional_8; /* CCS search and copy only */ Uchar optional_9; /* CCS search and copy only */ Uchar optional_10; /* CCS search and copy only */ Uchar optional_11; /* CCS search and copy only */ Uchar sense_code; /* sense code */ Uchar qual_code; /* sense code qualifier */ Uchar fru_code; /* Field replacable unit code */ Ucbit sksv : 1; /* sense key specific valid */ Ucbit cd : 1; /* pointers refer to command not data */ Ucbit : 2; Ucbit bpv : 1; /* bit pointer is valid */ Ucbit bptr : 3; /* bit pointer for failure (if bpv) */ Uchar field_ptr[2]; /* field pointer for failure */ Uchar add_info[2]; /* round up to 20 bytes */ }; #endif #ifdef __cplusplus } #endif #endif /* _SCG_SCSISENSE_H */ megactl-0.4.5/schily/scg/scsitransp.h000066400000000000000000000207661465722425200175710ustar00rootroot00000000000000/* @(#)scsitransp.h 1.54 03/05/03 Copyright 1995 J. Schilling */ /* * Definitions for commands that use functions from scsitransp.c * * Copyright (c) 1995 J. Schilling */ /* * 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, 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; see the file COPYING. If not, write to the Free Software * Foundation, 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. */ #ifndef _SCG_SCSITRANSP_H #define _SCG_SCSITRANSP_H #ifdef __cplusplus extern "C" { #endif typedef struct scg_scsi SCSI; typedef struct { int scsibus; /* SCSI bus # for next I/O */ int target; /* SCSI target # for next I/O */ int lun; /* SCSI lun # for next I/O */ } scg_addr_t; #ifndef _SCG_SCGOPS_H #include #endif typedef int (*scg_cb_t) __PR((void *)); struct scg_scsi { scg_ops_t *ops; /* Ptr to low level SCSI transport ops */ int fd; /* File descriptor for next I/O */ scg_addr_t addr; /* SCSI address for next I/O */ int flags; /* Libscg flags (see below) */ int dflags; /* Drive specific flags (see below) */ int kdebug; /* Kernel debug value for next I/O */ int debug; /* Debug value for SCSI library */ int silent; /* Be silent if value > 0 */ int verbose; /* Be verbose if value > 0 */ int overbose; /* Be verbose in open() if value > 0 */ int disre_disable; int deftimeout; int noparity; /* Do not use SCSI parity fo next I/O */ int dev; /* from scsi_cdr.c */ struct scg_cmd *scmd; char *cmdname; char *curcmdname; BOOL running; int error; /* libscg error number */ long maxdma; /* Max DMA limit for this open instance */ long maxbuf; /* Cur DMA buffer limit for this inst. */ /* This is the size behind bufptr */ struct timeval *cmdstart; struct timeval *cmdstop; const char **nonstderrs; void *local; /* Local data from the low level code */ void *bufbase; /* needed for scsi_freebuf() */ void *bufptr; /* DMA buffer pointer for appl. use */ char *errstr; /* Error string for scsi_open/sendmcd */ char *errbeg; /* Pointer to begin of not flushed data */ char *errptr; /* Actual write pointer into errstr */ void *errfile; /* FILE to write errors to. NULL for not*/ /* writing and leaving errs in errstr */ scg_cb_t cb_fun; void *cb_arg; struct scsi_inquiry *inq; struct scsi_capacity *cap; }; /* * Macros for accessing members of the scg address structure. * scg_settarget() is the only function that is allowed to modify * the values of the SCSI address. */ #define scg_scsibus(scgp) (scgp)->addr.scsibus #define scg_target(scgp) (scgp)->addr.target #define scg_lun(scgp) (scgp)->addr.lun /* * Flags for struct SCSI: */ /* NONE yet */ /* * Drive specific flags for struct SCSI: */ #define DRF_MODE_DMA_OVR 0x0001 /* Drive gives DMA overrun */ /* on mode sense */ #define SCSI_ERRSTR_SIZE 4096 /* * Libscg error codes: */ #define SCG_ERRBASE 1000000 #define SCG_NOMEM 1000001 /* * Function codes for scg_version(): */ #define SCG_VERSION 0 /* libscg or transport version */ #define SCG_AUTHOR 1 /* Author of above */ #define SCG_SCCS_ID 2 /* SCCS id of above */ #define SCG_RVERSION 10 /* Remote transport version */ #define SCG_RAUTHOR 11 /* Remote transport author */ #define SCG_RSCCS_ID 12 /* Remote transport SCCS ID */ #define SCG_KVERSION 20 /* Kernel transport version */ /* * Function codes for scg_reset(): */ #define SCG_RESET_NOP 0 /* Test if reset is supported */ #define SCG_RESET_TGT 1 /* Reset Target only */ #define SCG_RESET_BUS 2 /* Reset complete SCSI Bus */ /* * Helpers for the error buffer in SCSI* */ #define scg_errsize(scgp) ((scgp)->errptr - (scgp)->errstr) #define scg_errrsize(scgp) (SCSI_ERRSTR_SIZE - scg_errsize(scgp)) /* * From scsitransp.c: */ extern char *scg_version __PR((SCSI *scgp, int what)); extern int scg__open __PR((SCSI *scgp, char *device)); extern int scg__close __PR((SCSI *scgp)); extern BOOL scg_havebus __PR((SCSI *scgp, int)); extern int scg_initiator_id __PR((SCSI *scgp)); extern int scg_isatapi __PR((SCSI *scgp)); extern int scg_reset __PR((SCSI *scgp, int what)); extern void *scg_getbuf __PR((SCSI *scgp, long)); extern void scg_freebuf __PR((SCSI *scgp)); extern long scg_bufsize __PR((SCSI *scgp, long)); extern void scg_setnonstderrs __PR((SCSI *scgp, const char **)); extern BOOL scg_yes __PR((char *)); extern int scg_cmd __PR((SCSI *scgp)); extern void scg_vhead __PR((SCSI *scgp)); extern int scg_svhead __PR((SCSI *scgp, char *buf, int maxcnt)); extern int scg_vtail __PR((SCSI *scgp)); extern int scg_svtail __PR((SCSI *scgp, int *retp, char *buf, int maxcnt)); extern void scg_vsetup __PR((SCSI *scgp)); extern int scg_getresid __PR((SCSI *scgp)); extern int scg_getdmacnt __PR((SCSI *scgp)); extern BOOL scg_cmd_err __PR((SCSI *scgp)); extern void scg_printerr __PR((SCSI *scgp)); #ifdef EOF /* stdio.h has been included */ extern void scg_fprinterr __PR((SCSI *scgp, FILE *f)); #endif extern int scg_sprinterr __PR((SCSI *scgp, char *buf, int maxcnt)); extern int scg__sprinterr __PR((SCSI *scgp, char *buf, int maxcnt)); extern void scg_printcdb __PR((SCSI *scgp)); extern int scg_sprintcdb __PR((SCSI *scgp, char *buf, int maxcnt)); extern void scg_printwdata __PR((SCSI *scgp)); extern int scg_sprintwdata __PR((SCSI *scgp, char *buf, int maxcnt)); extern void scg_printrdata __PR((SCSI *scgp)); extern int scg_sprintrdata __PR((SCSI *scgp, char *buf, int maxcnt)); extern void scg_printresult __PR((SCSI *scgp)); extern int scg_sprintresult __PR((SCSI *scgp, char *buf, int maxcnt)); extern void scg_printstatus __PR((SCSI *scgp)); extern int scg_sprintstatus __PR((SCSI *scgp, char *buf, int maxcnt)); #ifdef EOF /* stdio.h has been included */ extern void scg_fprbytes __PR((FILE *, char *, unsigned char *, int)); extern void scg_fprascii __PR((FILE *, char *, unsigned char *, int)); #endif extern void scg_prbytes __PR((char *, unsigned char *, int)); extern void scg_prascii __PR((char *, unsigned char *, int)); extern int scg_sprbytes __PR((char *buf, int maxcnt, char *, unsigned char *, int)); extern int scg_sprascii __PR((char *buf, int maxcnt, char *, unsigned char *, int)); #ifdef EOF /* stdio.h has been included */ extern void scg_fprsense __PR((FILE *f, unsigned char *, int)); #endif extern void scg_prsense __PR((unsigned char *, int)); extern int scg_sprsense __PR((char *buf, int maxcnt, unsigned char *, int)); extern int scg_cmd_status __PR((SCSI *scgp)); extern int scg_sense_key __PR((SCSI *scgp)); extern int scg_sense_code __PR((SCSI *scgp)); extern int scg_sense_qual __PR((SCSI *scgp)); #ifdef _SCG_SCSIREG_H #ifdef EOF /* stdio.h has been included */ extern void scg_fprintdev __PR((FILE *, struct scsi_inquiry *)); #endif extern void scg_printdev __PR((struct scsi_inquiry *)); #endif extern int scg_printf __PR((SCSI *scgp, const char *form, ...)); extern int scg_errflush __PR((SCSI *scgp)); #ifdef EOF /* stdio.h has been included */ extern int scg_errfflush __PR((SCSI *scgp, FILE *f)); #endif /* * From scsierrmsg.c: */ extern const char *scg_sensemsg __PR((int, int, int, const char **, char *, int maxcnt)); #ifdef _SCG_SCSISENSE_H extern int scg__errmsg __PR((SCSI *scgp, char *obuf, int maxcnt, struct scsi_sense *, struct scsi_status *, int)); #endif /* * From scsiopen.c: */ #ifdef EOF /* stdio.h has been included */ extern int scg_help __PR((FILE *f)); #endif extern SCSI *scg_open __PR((char *scsidev, char *errs, int slen, int odebug, int be_verbose)); extern int scg_close __PR((SCSI * scgp)); extern void scg_settimeout __PR((SCSI * scgp, int timeout)); extern SCSI *scg_smalloc __PR((void)); extern void scg_sfree __PR((SCSI *scgp)); /* * From scgsettarget.c: */ extern int scg_settarget __PR((SCSI *scgp, int scsibus, int target, int lun)); /* * From scsi-remote.c: */ extern scg_ops_t *scg_remote __PR((void)); /* * From scsihelp.c: */ #ifdef EOF /* stdio.h has been included */ extern void __scg_help __PR((FILE *f, char *name, char *tcomment, char *tind, char *tspec, char *texample, BOOL mayscan, BOOL bydev)); #endif #ifdef __cplusplus } #endif #endif /* _SCG_SCSITRANSP_H */ megactl-0.4.5/schily/scg/spti-wnt.h000066400000000000000000000060101465722425200171470ustar00rootroot00000000000000/* * distilled information from various header files from Microsoft's * DDK for Windows NT 4.0 */ #ifndef _SCSIPT_H_INC #define _SCSIPT_H_INC #include typedef struct { USHORT Length; UCHAR ScsiStatus; UCHAR PathId; UCHAR TargetId; UCHAR Lun; UCHAR CdbLength; UCHAR SenseInfoLength; UCHAR DataIn; ULONG DataTransferLength; ULONG TimeOutValue; ULONG DataBufferOffset; ULONG SenseInfoOffset; UCHAR Cdb[16]; } SCSI_PASS_THROUGH, *PSCSI_PASS_THROUGH; typedef struct { USHORT Length; UCHAR ScsiStatus; UCHAR PathId; UCHAR TargetId; UCHAR Lun; UCHAR CdbLength; UCHAR SenseInfoLength; UCHAR DataIn; ULONG DataTransferLength; ULONG TimeOutValue; PVOID DataBuffer; ULONG SenseInfoOffset; UCHAR Cdb[16]; } SCSI_PASS_THROUGH_DIRECT, *PSCSI_PASS_THROUGH_DIRECT; typedef struct { SCSI_PASS_THROUGH spt; ULONG Filler; UCHAR ucSenseBuf[32]; UCHAR ucDataBuf[512]; } SCSI_PASS_THROUGH_WITH_BUFFERS, *PSCSI_PASS_THROUGH_WITH_BUFFERS; typedef struct { SCSI_PASS_THROUGH_DIRECT spt; ULONG Filler; UCHAR ucSenseBuf[32]; } SCSI_PASS_THROUGH_DIRECT_WITH_BUFFER, *PSCSI_PASS_THROUGH_DIRECT_WITH_BUFFER; typedef struct { UCHAR NumberOfLogicalUnits; UCHAR InitiatorBusId; ULONG InquiryDataOffset; } SCSI_BUS_DATA, *PSCSI_BUS_DATA; typedef struct { UCHAR NumberOfBusses; SCSI_BUS_DATA BusData[1]; } SCSI_ADAPTER_BUS_INFO, *PSCSI_ADAPTER_BUS_INFO; typedef struct { UCHAR PathId; UCHAR TargetId; UCHAR Lun; BOOLEAN DeviceClaimed; ULONG InquiryDataLength; ULONG NextInquiryDataOffset; UCHAR InquiryData[1]; } SCSI_INQUIRY_DATA, *PSCSI_INQUIRY_DATA; typedef struct { ULONG Length; UCHAR PortNumber; UCHAR PathId; UCHAR TargetId; UCHAR Lun; } SCSI_ADDRESS, *PSCSI_ADDRESS; /* * method codes */ #define METHOD_BUFFERED 0 #define METHOD_IN_DIRECT 1 #define METHOD_OUT_DIRECT 2 #define METHOD_NEITHER 3 /* * file access values */ #define FILE_ANY_ACCESS 0 #define FILE_READ_ACCESS 0x0001 #define FILE_WRITE_ACCESS 0x0002 #define IOCTL_SCSI_BASE 0x00000004 /* * constants for DataIn member of SCSI_PASS_THROUGH* structures */ #define SCSI_IOCTL_DATA_OUT 0 #define SCSI_IOCTL_DATA_IN 1 #define SCSI_IOCTL_DATA_UNSPECIFIED 2 /* * Standard IOCTL define */ #define CTL_CODE(DevType, Function, Method, Access) \ (((DevType) << 16) | ((Access) << 14) | ((Function) << 2) | (Method)) #define IOCTL_SCSI_PASS_THROUGH CTL_CODE(IOCTL_SCSI_BASE, 0x0401, METHOD_BUFFERED, FILE_READ_ACCESS | FILE_WRITE_ACCESS) #define IOCTL_SCSI_MINIPORT CTL_CODE(IOCTL_SCSI_BASE, 0x0402, METHOD_BUFFERED, FILE_READ_ACCESS | FILE_WRITE_ACCESS) #define IOCTL_SCSI_GET_INQUIRY_DATA CTL_CODE(IOCTL_SCSI_BASE, 0x0403, METHOD_BUFFERED, FILE_ANY_ACCESS) #define IOCTL_SCSI_GET_CAPABILITIES CTL_CODE(IOCTL_SCSI_BASE, 0x0404, METHOD_BUFFERED, FILE_ANY_ACCESS) #define IOCTL_SCSI_PASS_THROUGH_DIRECT CTL_CODE(IOCTL_SCSI_BASE, 0x0405, METHOD_BUFFERED, FILE_READ_ACCESS | FILE_WRITE_ACCESS) #define IOCTL_SCSI_GET_ADDRESS CTL_CODE(IOCTL_SCSI_BASE, 0x0406, METHOD_BUFFERED, FILE_ANY_ACCESS) #endif megactl-0.4.5/schily/scg/srb_os2.h000066400000000000000000000161031465722425200167370ustar00rootroot00000000000000/* @(#)srb_os2.h 1.0 98/10/28 Copyright 1998 D. Dorau, C. Wohlgemuth */ /* * Definitions for ASPI-Router (ASPIROUT.SYS). * * Copyright (c) 1998 D. Dorau, C. Wohlgemuth */ /* * 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, 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; see the file COPYING. If not, write to * the Free Software Foundation, 675 Mass Ave, Cambridge, MA 02139, USA. */ #pragma pack(1) /* SRB command */ #define SRB_Inquiry 0x00 #define SRB_Device 0x01 #define SRB_Command 0x02 #define SRB_Abort 0x03 #define SRB_Reset 0x04 #define SRB_Param 0x05 /* SRB status */ #define SRB_Busy 0x00 /* SCSI request in progress */ #define SRB_Done 0x01 /* SCSI request completed without error */ #define SRB_Aborted 0x02 /* SCSI aborted by host */ #define SRB_BadAbort 0x03 /* Unable to abort SCSI request */ #define SRB_Error 0x04 /* SCSI request completed with error */ #define SRB_BusyPost 0x10 /* SCSI request in progress with POST - Nokia */ #define SRB_InvalidCmd 0x80 /* Invalid SCSI request */ #define SRB_InvalidHA 0x81 /* Invalid Hhost adapter number */ #define SRB_BadDevice 0x82 /* SCSI device not installed */ /* SRB flags */ #define SRB_Post 0x01 /* Post vector valid */ #define SRB_Link 0x02 /* Link vector valid */ #define SRB_SG 0x04 /* Nokia: scatter/gather */ /* S/G: n * (4 bytes length, 4 bytes addr) */ /* No of s/g items not limited by HA spec. */ #define SRB_NoCheck 0x00 /* determined by command, not checked */ #define SRB_Read 0x08 /* target to host, length checked */ #define SRB_Write 0x10 /* host to target, length checked */ #define SRB_NoTransfer 0x18 /* no data transfer */ #define SRB_DirMask 0x18 /* bit mask */ /* SRB host adapter status */ #define SRB_NoError 0x00 /* No host adapter detected error */ #define SRB_Timeout 0x11 /* Selection timeout */ #define SRB_DataLength 0x12 /* Data over/underrun */ #define SRB_BusFree 0x13 /* Unexpected bus free */ #define SRB_BusSequence 0x14 /* Target bus sequence failure */ /* SRB target status field */ #define SRB_NoStatus 0x00 /* No target status */ #define SRB_CheckStatus 0x02 /* Check status (sense data valid) */ #define SRB_LUN_Busy 0x08 /* Specified LUN is busy */ #define SRB_Reserved 0x18 /* Reservation conflict */ #define MaxCDBStatus 64 /* max size of CDB + status */ typedef struct SRb { unsigned char cmd, /* 00 */ status, /* 01 */ ha_num, /* 02 */ flags; /* 03 */ unsigned long res_04_07; /* 04..07 */ union { /* 08 */ /* SRB_Inquiry */ struct { unsigned char num_ha, /* 08 */ ha_target, /* 09 */ aspimgr_id[16], /* 0A..19 */ host_id[16], /* 1A..29 */ unique_id[16]; /* 2A..39 */ } inq; /* SRB_Device */ struct { unsigned char target, /* 08 */ lun, /* 09 */ devtype; /* 0A */ } dev; /* SRB_Command */ struct { unsigned char target, /* 08 */ lun; /* 09 */ unsigned long data_len; /* 0A..0D */ unsigned char sense_len; /* 0E */ unsigned long data_ptr; /* 0F..12 */ unsigned long link_ptr; /* 13..16 */ // void * _Seg16 data_ptr; /* 0F..12 */ // void * _Seg16 link_ptr; /* 13..16 */ unsigned char cdb_len, /* 17 */ ha_status, /* 18 */ target_status; /* 19 */ unsigned char _Seg16postSRB[4]; // void (* _Seg16 post) (SRB *); /* 1A..1D */ unsigned char res_1E_29[12]; /* 1E..29 */ unsigned char res_2A_3F[22]; /* 2A..3F */ unsigned char cdb_st[64]; /* 40..7F CDB+status */ unsigned char res_80_BF[64]; /* 80..BF */ } cmd; /* SRB_Abort */ struct { unsigned char _Seg16srb[4]; // void * _Seg16 srb; /* 08..0B */ } abt; /* SRB_Reset */ struct { unsigned char target, /* 08 */ lun, /* 09 */ res_0A_17[14], /* 0A..17 */ ha_status, /* 18 */ target_status; /* 19 */ } res; /* SRB_Param - unused by ASPI4OS2 */ struct { unsigned char unique[16]; /* 08..17 */ } par; } u; } SRB; // SCSI sense codes // Note! This list may not be complete. I did this compilation for use with tape drives. #define Sense_Current 0x70; // Current Error #define Sense_Deferred 0x71; // Deferred Error #define Sense_Filemark 0x80; // Filemark detected #define Sense_EOM 0x40; // End of medium detected #define Sense_ILI 0x20; // Incorrect length indicator // Sense Keys #define SK_NoSense 0x00; // No Sense #define SK_RcvrdErr 0x01; // Recovered Error #define SK_NotReady 0x02; // Not ready #define SK_MedErr 0x03; // Medium Error #define SK_HWErr 0x04; // Hardware Error #define SK_IllReq 0x05; // Illegal Request #define SK_UnitAtt 0x06; // Unit attention #define SK_DataProt 0x07: // Data Protect #define SK_BlankChk 0x08: // Blank Check #define SK_VndSpec 0x09; // Vendor Specific #define SK_CopyAbort 0x0A; // Copy Aborted #define SK_AbtdCmd 0x0B; // Aborted Command #define SK_Equal 0x0C; // Equal #define SK_VolOvfl 0x0D; // Volume Overflow #define SK_MisComp 0x0E; // Miscompare #define SK_Reserved 0x0F; // Reserved megactl-0.4.5/schily/schily.h000066400000000000000000000250521465722425200161100ustar00rootroot00000000000000/* @(#)schily.h 1.52 04/03/05 Copyright 1985-2002 J. Schilling */ /* * Definitions for libschily * * This file should be included past: * * mconfig.h / config.h * standard.h * stdio.h * stdlib.h (better use stdxlib.h) * unistd.h (better use unixstd.h) needed LARGEFILE support * string.h * sys/types.h * * If you need stdio.h, you must include it before schily.h * * NOTE: If you need ctype.h and did not include stdio.h you need to * include ctype.h past schily.h as OpenBSD does not follow POSIX and * defines EOF in ctype.h * * Copyright (c) 1985-2002 J. Schilling */ /* * 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, 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; see the file COPYING. If not, write to the Free Software * Foundation, 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. */ #ifndef _SCHILY_H #define _SCHILY_H #ifndef _STANDARD_H #include #endif #ifndef _CCOMDEFS_H #include #endif #ifdef __cplusplus extern "C" { #endif #if defined(_INCL_SYS_TYPES_H) || defined(off_t) # ifndef FOUND_OFF_T # define FOUND_OFF_T # endif #endif #if defined(_INCL_SYS_TYPES_H) || defined(size_t) # ifndef FOUND_SIZE_T # define FOUND_SIZE_T # endif #endif #ifdef __never_def__ /* * It turns out that we cannot use the folloginw definition because there are * some platforms that do not behave application friendly. These are mainly * BSD-4.4 based systems (which #undef a definition when size_t is available. * We actually removed this code because of a problem with QNX Neutrino. * For this reason, it is important not to include directly but * via the Schily SING include files so we know whether it has been included * before we come here. */ #if defined(_SIZE_T) || defined(_T_SIZE_) || defined(_T_SIZE) || \ defined(__SIZE_T) || defined(_SIZE_T_) || \ defined(_GCC_SIZE_T) || defined(_SIZET_) || \ defined(__sys_stdtypes_h) || defined(___int_size_t_h) || defined(size_t) #ifndef FOUND_SIZE_T # define FOUND_SIZE_T /* We already included a size_t definition */ #endif #endif #endif /* __never_def__ */ #if defined(HAVE_LARGEFILES) # define _fcons _fcons64 # define fdup fdup64 # define fileluopen fileluopen64 # define fileopen fileopen64 # define filemopen filemopen64 # define filepos filepos64 # define filereopen filereopen64 # define fileseek fileseek64 # define filesize filesize64 # define filestat filestat64 # define _openfd _openfd64 #endif #ifdef EOF /* stdio.h has been included */ extern int _cvmod __PR((const char *, int *, int *)); extern FILE *_fcons __PR((FILE *, int, int)); extern FILE *fdup __PR((FILE *)); extern int fdown __PR((FILE *)); extern int fexecl __PR((const char *, FILE *, FILE *, FILE *, const char *, ...)); extern int fexecle __PR((const char *, FILE *, FILE *, FILE *, const char *, ...)); /* 6th arg not const, fexecv forces av[ac] = NULL */ extern int fexecv __PR((const char *, FILE *, FILE *, FILE *, int, char **)); extern int fexecve __PR((const char *, FILE *, FILE *, FILE *, char * const *, char * const *)); extern int fspawnv __PR((FILE *, FILE *, FILE *, int, char * const *)); extern int fspawnl __PR((FILE *, FILE *, FILE *, const char *, const char *, ...)); extern int fspawnv_nowait __PR((FILE *, FILE *, FILE *, const char *, int, char *const*)); extern int fgetline __PR((FILE *, char *, int)); extern int fgetstr __PR((FILE *, char *, int)); extern void file_raise __PR((FILE *, int)); extern int fileclose __PR((FILE *)); extern FILE *fileluopen __PR((int, const char *)); extern FILE *fileopen __PR((const char *, const char *)); #ifdef _INCL_SYS_TYPES_H extern FILE *filemopen __PR((const char *, const char *, mode_t)); #endif #ifdef FOUND_OFF_T extern off_t filepos __PR((FILE *)); #endif extern int fileread __PR((FILE *, void *, int)); extern int ffileread __PR((FILE *, void *, int)); extern FILE *filereopen __PR((const char *, const char *, FILE *)); #ifdef FOUND_OFF_T extern int fileseek __PR((FILE *, off_t)); extern off_t filesize __PR((FILE *)); #endif #ifdef S_IFMT extern int filestat __PR((FILE *, struct stat *)); #endif extern int filewrite __PR((FILE *, void *, int)); extern int ffilewrite __PR((FILE *, void *, int)); extern int flush __PR((void)); extern int fpipe __PR((FILE **)); /*extern int fprintf __PR((FILE *, const char *, ...)) __printflike__(2, 3);*/ extern int getbroken __PR((FILE *, char *, char, char **, int)); extern int ofindline __PR((FILE *, char, const char *, int, char **, int)); extern int peekc __PR((FILE *)); #ifdef __never_def__ /* * We cannot define this or we may get into problems with DOS based systems. */ extern int spawnv __PR((FILE *, FILE *, FILE *, int, char * const *)); extern int spawnl __PR((FILE *, FILE *, FILE *, const char *, const char *, ...)); extern int spawnv_nowait __PR((FILE *, FILE *, FILE *, const char *, int, char *const*)); #endif /* __never_def__m */ #endif /* EOF */ extern int _niread __PR((int, void *, int)); extern int _niwrite __PR((int, void *, int)); extern int _nixread __PR((int, void *, int)); extern int _nixwrite __PR((int, void *, int)); extern int _openfd __PR((const char *, int)); extern int on_comerr __PR((void (*fun)(int, void *), void *arg)); /*PRINTFLIKE1*/ extern void comerr __PR((const char *, ...)) __printflike__(1, 2); /*PRINTFLIKE2*/ extern void comerrno __PR((int, const char *, ...)) __printflike__(2, 3); /*PRINTFLIKE1*/ extern int errmsg __PR((const char *, ...)) __printflike__(1, 2); /*PRINTFLIKE2*/ extern int errmsgno __PR((int, const char *, ...)) __printflike__(2, 3); #ifdef FOUND_SIZE_T /*PRINTFLIKE3*/ extern int serrmsg __PR((char *, size_t, const char *, ...)) __printflike__(3, 4); /*PRINTFLIKE4*/ extern int serrmsgno __PR((int, char *, size_t, const char *, ...)) __printflike__(4, 5); #endif extern void comexit __PR((int)); extern char *errmsgstr __PR((int)); /*PRINTFLIKE1*/ extern int error __PR((const char *, ...)) __printflike__(1, 2); extern char *fillbytes __PR((void *, int, char)); extern char *findbytes __PR((const void *, int, char)); extern int findline __PR((const char *, char, const char *, int, char **, int)); extern int getline __PR((char *, int)); extern int getstr __PR((char *, int)); extern int breakline __PR((char *, char, char **, int)); extern int getallargs __PR((int *, char * const**, const char *, ...)); extern int getargs __PR((int *, char * const**, const char *, ...)); extern int getfiles __PR((int *, char * const**, const char *)); extern char *astoi __PR((const char *, int *)); extern char *astol __PR((const char *, long *)); extern char *astolb __PR((const char *, long *, int base)); #ifdef _UTYPES_H extern char *astoll __PR((const char *, Llong *)); extern char *astollb __PR((const char *, Llong *, int base)); #endif /*extern void handlecond __PR((const char *, SIGBLK *, int(*)(const char *, long, long), long));*/ /*extern void unhandlecond __PR((SIGBLK *));*/ extern int patcompile __PR((const unsigned char *, int, int *)); extern unsigned char *patmatch __PR((const unsigned char *, const int *, const unsigned char *, int, int, int, int[])); extern unsigned char *patlmatch __PR((const unsigned char *, const int *, const unsigned char *, int, int, int, int[])); /*extern int printf __PR((const char *, ...)) __printflike__(1, 2);*/ extern char *movebytes __PR((const void *, void *, int)); extern void save_args __PR((int, char **)); extern int saved_ac __PR((void)); extern char **saved_av __PR((void)); extern char *saved_av0 __PR((void)); #ifndef seterrno extern int seterrno __PR((int)); #endif extern void set_progname __PR((const char *)); extern char *get_progname __PR((void)); extern void setfp __PR((void * const *)); extern int wait_chld __PR((int)); /* for fspawnv_nowait() */ extern int geterrno __PR((void)); extern void raisecond __PR((const char *, long)); #ifdef FOUND_SIZE_T /* * We currently cannot define this here because there IXIX has a definition * than violates the standard. */ #ifndef HAVE_SNPRINTF /*PRINTFLIKE3*/ extern int snprintf __PR((char *, size_t, const char *, ...)) __printflike__(3, 4); #endif #endif /*extern int sprintf __PR((char *, const char *, ...)); ist woanders falsch deklariert !!!*/ extern char *strcatl __PR((char *, ...)); extern int streql __PR((const char *, const char *)); #ifdef va_arg extern int format __PR((void (*)(char, long), long, const char *, va_list)); #else extern int format __PR((void (*)(char, long), long, const char *, void *)); #endif extern int ftoes __PR((char *, double, int, int)); extern int ftofs __PR((char *, double, int, int)); #ifdef EOF /* stdio.h has been included */ /*PRINTFLIKE2*/ extern int js_fprintf __PR((FILE *, const char *, ...)) __printflike__(2, 3); /*PRINTFLIKE1*/ extern int js_printf __PR((const char *, ...)) __printflike__(1, 2); #ifdef FOUND_SIZE_T /*PRINTFLIKE3*/ extern int js_snprintf __PR((char *, size_t, const char *, ...)) __printflike__(3, 4); #endif /*PRINTFLIKE2*/ extern int js_sprintf __PR((char *, const char *, ...)) __printflike__(2, 3); #endif /* EOF */ extern void swabbytes __PR((void *, int)); extern char **getmainfp __PR((void)); extern char **getavp __PR((void)); extern char *getav0 __PR((void)); extern void **getfp __PR((void)); extern int flush_reg_windows __PR((int)); extern int cmpbytes __PR((const void *, const void *, int)); extern int cmpnullbytes __PR((const void *, int)); #ifdef nonono #if defined(HAVE_LARGEFILES) /* * To allow this, we need to figure out how to do autoconfiguration for off64_t */ extern FILE *_fcons64 __PR((FILE *, int, int)); extern FILE *fdup64 __PR((FILE *)); extern FILE *fileluopen64 __PR((int, const char *)); extern FILE *fileopen64 __PR((const char *, const char *)); #ifdef FOUND_OFF_T extern off64_t filepos64 __PR((FILE *)); #endif extern FILE *filereopen64 __PR((const char *, const char *, FILE *)); #ifdef FOUND_OFF_T extern int fileseek64 __PR((FILE *, off64_t)); extern off64_t filesize64 __PR((FILE *)); #endif #ifdef S_IFMT extern int filestat64 __PR((FILE *, struct stat *)); #endif extern int _openfd64 __PR((const char *, int)); #endif #endif #ifdef __cplusplus } #endif #if defined(_JOS) || defined(JOS) # ifndef _JOS_IO_H # include # endif #endif #endif /* _SCHILY_H */ megactl-0.4.5/schily/sigblk.h000066400000000000000000000037521465722425200160730ustar00rootroot00000000000000/* @(#)sigblk.h 1.10 03/07/10 Copyright 1985, 1995-2003 J. Schilling */ /* * software signal block definition * * Copyright (c) 1985, 1995-2003 J. Schilling */ /* * 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, 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; see the file COPYING. If not, write to the Free Software * Foundation, 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. */ #ifndef _SIGBLK_H #define _SIGBLK_H #ifndef _MCONFIG_H #include #endif #ifndef _STANDARD_H #include #endif #ifdef __cplusplus extern "C" { #endif typedef struct sigblk { long **sb_savfp; /* Real saved framepointer */ struct sigblk *sb_signext; /* Next sw signal blk for this func */ short sb_siglen; /* Strlen for sb_signame */ const char *sb_signame; /* Name of software signal */ /* sb_sigfun: function to call */ int (*sb_sigfun) __PR((const char *, long, long)); long sb_sigarg; /* Second arg for sb_sigfun */ } SIGBLK; /* * The handler function is called with three arguments: * * 1) The name of the software signal * 2) The argument from the handlecond() call * 3) The argument from the raisecond() call */ typedef int (*handlefunc_t) __PR((const char *, long, long)); extern void handlecond __PR((const char *, SIGBLK *, int(*)(const char *, long, long), long)); extern void raisecond __PR((const char *, long)); extern void starthandlecond __PR((SIGBLK *)); extern void unhandlecond __PR((SIGBLK *)); #ifdef __cplusplus } #endif #endif /* _SIGBLK_H */ megactl-0.4.5/schily/sigdefs.h000066400000000000000000000035261465722425200162430ustar00rootroot00000000000000/* @(#)sigdefs.h 1.5 02/01/19 Copyright 1997 J. Schilling */ /* * Signal abstraction for BSD/SVR4 signals * * Copyright (c) 1997 J. Schilling */ /* * 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, 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; see the file COPYING. If not, write to * the Free Software Foundation, 675 Mass Ave, Cambridge, MA 02139, USA. */ #ifndef _SIGDEFS_H #define _SIGDEFS_H #ifndef _MCONFIG_H #include #endif #ifdef HAVE_SIGSET /* * Try to by default use the function that sets up signal handlers in a way * that does not reset the handler after it has been called. */ #define signal sigset #endif #ifdef HAVE_SIGPROCMASK #define block_sigs(a) { \ sigset_t __new; \ \ sigfillset(&__new); \ sigprocmask(SIG_BLOCK, &__new, &a);\ } #define unblock_sig(s) { \ sigset_t __new; \ \ sigemptyset(&__new); \ sigaddset(&__new, (s)); \ sigprocmask(SIG_UNBLOCK, &__new, NULL);\ } #define restore_sigs(a) sigprocmask(SIG_SETMASK, &a, 0); #else /* !HAVE_SIGPROCMASK */ #define sigset_t int #define block_sigs(a) a = sigblock(0xFFFFFFFF) #define restore_sigs(a) sigsetmask(a); #define unblock_sig(s) { \ int __old, __new; \ \ block_sigs(__old); \ __new = sigmask(s); \ __new = __old & ~__new; \ sigsetmask(__new); \ } #endif /* HAVE_SIGPROCMASK */ #endif /* _SIGDEFS_H */ megactl-0.4.5/schily/standard.h000066400000000000000000000066461465722425200164250ustar00rootroot00000000000000/* @(#)standard.h 1.31 03/08/23 Copyright 1985 J. Schilling */ /* * standard definitions * * This file should be included past: * * mconfig.h / config.h * stdio.h * stdlib.h (better use stdxlib.h) * unistd.h (better use unixstd.h) needed LARGEFILE support * * If you need stdio.h, you must include it before standard.h * * Copyright (c) 1985 J. Schilling */ /* * 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, 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; see the file COPYING. If not, write to the Free Software * Foundation, 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. */ #ifndef _STANDARD_H #define _STANDARD_H #ifndef _MCONFIG_H #include #endif #ifndef _PROTOTYP_H #include #endif #ifdef M68000 # ifndef tos # define JOS 1 # endif #endif /* * fundamental constants */ #ifndef NULL # define NULL 0 #endif #ifndef TRUE # define TRUE 1 # define FALSE 0 #endif /* * Program exit codes */ #define EX_BAD (-1) /* * standard storage class definitions */ #define GLOBAL extern #define IMPORT extern #define EXPORT #define INTERN static #define LOCAL static #define FAST register #ifndef PROTOTYPES # ifndef const # define const # endif # ifndef signed # define signed # endif # ifndef volatile # define volatile # endif #endif /* PROTOTYPES */ /* * standard type definitions * * The hidden Schily BOOL definition is used in case we need to deal * with other BOOL defines on systems we like to port to. */ typedef int __SBOOL; typedef int BOOL; #ifdef JOS # ifndef __GNUC__ # define NO_VOID # endif #endif #ifdef NO_VOID typedef int VOID; # ifndef lint typedef int void; # endif #else typedef void VOID; #endif #if defined(_INCL_SYS_TYPES_H) || defined(off_t) # ifndef FOUND_OFF_T # define FOUND_OFF_T # endif #endif #if defined(_INCL_SYS_TYPES_H) || defined(size_t) # ifndef FOUND_SIZE_T # define FOUND_SIZE_T # endif #endif #ifdef __never_def__ /* * It turns out that we cannot use the folloginw definition because there are * some platforms that do not behave application friendly. These are mainly * BSD-4.4 based systems (which #undef a definition when size_t is available. * We actually removed this code because of a problem with QNX Neutrino. * For this reason, it is important not to include directly but * via the Schily SING include files so we know whether it has been included * before we come here. */ #if defined(_SIZE_T) || defined(_T_SIZE_) || defined(_T_SIZE) || \ defined(__SIZE_T) || defined(_SIZE_T_) || \ defined(_GCC_SIZE_T) || defined(_SIZET_) || \ defined(__sys_stdtypes_h) || defined(___int_size_t_h) || defined(size_t) #ifndef FOUND_SIZE_T # define FOUND_SIZE_T /* We already included a size_t definition */ #endif #endif #endif /* __never_def__ */ #if defined(_JOS) || defined(JOS) # ifndef _SCHILY_H # include # endif # ifndef _JOS_DEFS_H # include # endif # ifndef _JOS_IO_H # include # endif #endif #endif /* _STANDARD_H */ megactl-0.4.5/schily/statdefs.h000066400000000000000000000212401465722425200164250ustar00rootroot00000000000000/* @(#)statdefs.h 1.9 03/06/15 Copyright 1998 J. Schilling */ /* * Definitions for stat() file mode * * Copyright (c) 1998 J. Schilling */ /* * 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, 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; see the file COPYING. If not, write to the Free Software * Foundation, 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. */ #ifndef _STATDEFS_H #define _STATDEFS_H #ifndef _MCONFIG_H #include #endif #ifndef _INCL_SYS_TYPES_H #include /* Needed for sys/stat.h */ #define _INCL_SYS_TYPES_H #endif #ifndef _INCL_SYS_STAT_H #include /* For S_IS* and S_IF* */ #define _INCL_SYS_STAT_H #endif /* * Apollo Domain/OS has a broken sys/stat.h that defines * S_IFIFO == S_IFSOCK and creates trouble if the constants * are used as case labels. */ #if S_IFIFO == S_IFSOCK # undef S_IFSOCK #endif #ifdef STAT_MACROS_BROKEN #undef S_ISFIFO /* Named pipe */ #undef S_ISCHR /* Character special */ #undef S_ISMPC /* UNUSED multiplexed c */ #undef S_ISDIR /* Directory */ #undef S_ISNAM /* Named file (XENIX) */ #undef S_ISBLK /* Block special */ #undef S_ISMPB /* UNUSED multiplexed b */ #undef S_ISREG /* Regular file */ #undef S_ISCNT /* Contiguous file */ #undef S_ISLNK /* Symbolic link */ #undef S_ISSHAD /* Solaris shadow inode */ #undef S_ISSOCK /* UNIX domain socket */ #undef S_ISDOOR /* Solaris DOOR */ #undef S_ISWHT /* BSD whiteout */ #undef S_ISEVC /* UNOS eventcount */ #endif #ifndef S_ISFIFO /* 1 Named pipe */ # ifdef S_IFIFO # define S_ISFIFO(m) (((m) & S_IFMT) == S_IFIFO) # else # define S_ISFIFO(m) (0) # endif #endif #ifndef S_ISCHR /* 2 Character special */ # ifdef S_IFCHR # define S_ISCHR(m) (((m) & S_IFMT) == S_IFCHR) # else # define S_ISCHR(m) (0) # endif #endif #ifndef S_ISMPC /* 3 UNUSED multiplexed char */ # ifdef S_IFMPC # define S_ISMPC(m) (((m) & S_IFMT) == S_IFMPC) # else # define S_ISMPC(m) (0) # endif #endif #ifndef S_ISDIR /* 4 Directory */ # ifdef S_IFDIR # define S_ISDIR(m) (((m) & S_IFMT) == S_IFDIR) # else # define S_ISDIR(m) (0) # endif #endif #ifndef S_ISNAM /* 5 Named file (XENIX) */ # ifdef S_IFNAM # define S_ISNAM(m) (((m) & S_IFMT) == S_IFNAM) # else # define S_ISNAM(m) (0) # endif #endif #ifndef S_ISBLK /* 6 Block special */ # ifdef S_IFBLK # define S_ISBLK(m) (((m) & S_IFMT) == S_IFBLK) # else # define S_ISBLK(m) (0) # endif #endif #ifndef S_ISMPB /* 7 UNUSED multiplexed block */ # ifdef S_IFMPB # define S_ISMPB(m) (((m) & S_IFMT) == S_IFMPB) # else # define S_ISMPB(m) (0) # endif #endif #ifndef S_ISREG /* 8 Regular file */ # ifdef S_IFREG # define S_ISREG(m) (((m) & S_IFMT) == S_IFREG) # else # define S_ISREG(m) (0) # endif #endif #ifndef S_ISCNT /* 9 Contiguous file */ # ifdef S_IFCNT # define S_ISCNT(m) (((m) & S_IFMT) == S_IFCNT) # else # define S_ISCNT(m) (0) # endif #endif #ifndef S_ISLNK /* 10 Symbolic link */ # ifdef S_IFLNK # define S_ISLNK(m) (((m) & S_IFMT) == S_IFLNK) # else # define S_ISLNK(m) (0) # endif #endif #ifndef S_ISSHAD /* 11 Solaris shadow inode */ # ifdef S_IFSHAD # define S_ISSHAD(m) (((m) & S_IFMT) == S_IFSHAD) # else # define S_ISSHAD(m) (0) # endif #endif #ifndef S_ISSOCK /* 12 UNIX domain socket */ # ifdef S_IFSOCK # define S_ISSOCK(m) (((m) & S_IFMT) == S_IFSOCK) # else # define S_ISSOCK(m) (0) # endif #endif #ifndef S_ISDOOR /* 13 Solaris DOOR */ # ifdef S_IFDOOR # define S_ISDOOR(m) (((m) & S_IFMT) == S_IFDOOR) # else # define S_ISDOOR(m) (0) # endif #endif #ifndef S_ISWHT /* 14 BSD whiteout */ # ifdef S_IFWHT # define S_ISWHT(m) (((m) & S_IFMT) == S_ISWHT) # else # define S_ISWHT(m) (0) # endif #endif #ifndef S_IFEVC /* 15 UNOS eventcount */ # ifdef S_IFEVC # define S_ISEVC(m) (((m) & S_IFMT) == S_IFEVC) # else # define S_ISEVC(m) (0) # endif #endif #ifndef S_TYPEISMQ /* * XXX ??? where is a definition of a message queue ??? */ # define S_TYPEISMQ(_stbuf) (0) #endif #ifndef S_TYPEISSEM # ifdef S_INSEM # define S_TYPEISSEM(_stbuf) (S_ISNAM((_stbuf)->st_mode) && (_stbuf)->st_rdev == S_INSEM) # else # define S_TYPEISSEM(_stbuf) (0) # endif #endif #ifndef S_TYPEISSHM # ifdef S_INSHD # define S_TYPEISSHM(_stbuf) (S_ISNAM((_stbuf)->st_mode) && (_stbuf)->st_rdev == S_INSHD) # else # define S_TYPEISSHM(_stbuf) (0) # endif #endif /* * Mode permission bits. * UNIX V.7 has only S_ISUID/S_ISGID/S_ISVTX and S_IREAD/S_IWRITE/S_IEXEC */ #ifndef S_ISUID /* Set-user-ID on execution */ #define S_ISUID 0 /* If it is not defined, it is not supported */ #endif #ifndef S_ISGID /* Set-group-ID on execution */ #define S_ISGID 0 /* If it is not defined, it is not supported */ #endif #ifndef S_ISVTX /* On directories, restricted deletion flag */ #define S_ISVTX 0 /* If it is not defined, it is not supported */ #endif #ifndef S_IRUSR /* Read permission, owner */ #ifdef S_IREAD #define S_IRUSR S_IREAD /* Needed on old UNIX systems */ #else #define S_IRUSR 0400 #endif #endif #ifndef S_IWUSR /* Write permission, owner */ #ifdef S_IWRITE #define S_IWUSR S_IWRITE /* Needed on old UNIX systems */ #else #define S_IWUSR 0200 #endif #endif #ifndef S_IXUSR /* Execute/search permission, owner */ #ifdef S_IEXEC #define S_IXUSR S_IEXEC /* Needed on old UNIX systems */ #else #define S_IXUSR 0100 #endif #endif #ifndef S_IRGRP /* Read permission, group */ #ifdef S_IREAD #define S_IRGRP (S_IREAD >> 3) /* Needed on old UNIX systems */ #else #define S_IRGRP 040 #endif #endif #ifndef S_IWGRP /* Write permission, group */ #ifdef S_IWRITE #define S_IWGRP (S_IWRITE >> 3) /* Needed on old UNIX systems */ #else #define S_IWGRP 020 #endif #endif #ifndef S_IXGRP /* Execute/search permission, group */ #ifdef S_IEXEC #define S_IXGRP (S_IEXEC >> 3) /* Needed on old UNIX systems */ #else #define S_IXGRP 010 #endif #endif #ifndef S_IROTH /* Read permission, others */ #ifdef S_IREAD #define S_IROTH (S_IREAD >> 6) /* Needed on old UNIX systems */ #else #define S_IROTH 004 #endif #endif #ifndef S_IWOTH /* Write permission, others */ #ifdef S_IWRITE #define S_IWOTH (S_IWRITE >> 6) /* Needed on old UNIX systems */ #else #define S_IWOTH 002 #endif #endif #ifndef S_IXOTH /* Execute/search permission, others */ #ifdef S_IEXEC #define S_IXOTH (S_IEXEC >> 6) /* Needed on old UNIX systems */ #else #define S_IXOTH 001 #endif #endif #ifndef S_IRWXU /* Read, write, execute/search by owner */ #define S_IRWXU (S_IRUSR|S_IWUSR|S_IXUSR) #endif #ifndef S_IRWXG /* Read, write, execute/search by group */ #define S_IRWXG (S_IRGRP|S_IWGRP|S_IXGRP) #endif #ifndef S_IRWXO /* Read, write, execute/search by others */ #define S_IRWXO (S_IROTH|S_IWOTH|S_IXOTH) #endif /* * SCO UnixWare has st_atim.st__tim.tv_nsec but the st_atim.tv_nsec tests also * succeeds. If we use st_atim.tv_nsec on UnixWare, we get a warning about * illegal structure usage. For this reason, our code needs to have * #ifdef HAVE_ST__TIM before #ifdef HAVE_ST_NSEC. */ #if defined(HAVE_ST_ATIMENSEC) #define stat_ansecs(s) ((s)->st_atimensec) #define stat_mnsecs(s) ((s)->st_mtimensec) #define stat_cnsecs(s) ((s)->st_ctimensec) #define _FOUND_STAT_NSECS_ #endif #if defined(HAVE_ST_SPARE1) && !defined(_FOUND_STAT_NSECS_) #define stat_ansecs(s) ((s)->st_spare1 * 1000) #define stat_mnsecs(s) ((s)->st_spare2 * 1000) #define stat_cnsecs(s) ((s)->st_spare3 * 1000) #define _FOUND_STAT_USECS_ #define _FOUND_STAT_NSECS_ #endif #if defined(HAVE_ST__TIM) && !defined(_FOUND_STAT_NSECS_) #define stat_ansecs(s) ((s)->st_atim.st__tim.tv_nsec) #define stat_mnsecs(s) ((s)->st_mtim.st__tim.tv_nsec) #define stat_cnsecs(s) ((s)->st_ctim.st__tim.tv_nsec) #define _FOUND_STAT_NSECS_ #endif #if defined(HAVE_ST_NSEC) && !defined(_FOUND_STAT_NSECS_) #define stat_ansecs(s) ((s)->st_atim.tv_nsec) #define stat_mnsecs(s) ((s)->st_mtim.tv_nsec) #define stat_cnsecs(s) ((s)->st_ctim.tv_nsec) #define _FOUND_STAT_NSECS_ #endif #if defined(HAVE_ST_ATIMESPEC) && !defined(_FOUND_STAT_NSECS_) #define stat_ansecs(s) ((s)->st_atimespec.tv_nsec) #define stat_mnsecs(s) ((s)->st_mtimespec.tv_nsec) #define stat_cnsecs(s) ((s)->st_ctimespec.tv_nsec) #define _FOUND_STAT_NSECS_ #endif #if !defined(_FOUND_STAT_NSECS_) #define stat_ansecs(s) (0) #define stat_mnsecs(s) (0) #define stat_cnsecs(s) (0) #endif #endif /* _STATDEFS_H */ megactl-0.4.5/schily/stdxlib.h000066400000000000000000000024241465722425200162640ustar00rootroot00000000000000/* @(#)stdxlib.h 1.6 01/07/15 Copyright 1996 J. Schilling */ /* * Definitions for stdlib * * Copyright (c) 1996 J. Schilling */ /* * 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, 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; see the file COPYING. If not, write to * the Free Software Foundation, 675 Mass Ave, Cambridge, MA 02139, USA. */ #ifndef _STDXLIB_H #define _STDXLIB_H #ifndef _MCONFIG_H #include #endif #ifdef HAVE_STDLIB_H #ifndef _INCL_STDLIB_H #include #define _INCL_STDLIB_H #endif #else extern char *malloc(); extern char *realloc(); extern double atof(); #endif /* HAVE_STDLIB_H */ #ifndef EXIT_FAILURE #define EXIT_FAILURE 1 #endif #ifndef EXIT_SUCCESS #define EXIT_SUCCESS 0 #endif #ifndef RAND_MAX #define RAND_MAX 32767 #endif #endif /* _STDXLIB_H */ megactl-0.4.5/schily/stkframe.h000066400000000000000000000046361465722425200164360ustar00rootroot00000000000000/* @(#)stkframe.h 1.10 03/06/15 Copyright 1995 J. Schilling */ /* * Common definitions for routines that parse the stack frame. * * This file has to be fixed if you want to port routines which use getfp(). * Have a look at struct frame below and use it as a sample, * the new struct frame must at least contain a member 'fr_savfp'. */ /* * 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, 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; see the file COPYING. If not, write to the Free Software * Foundation, 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. */ #ifndef _STKFRAME_H #define _STKFRAME_H #ifndef _MCONFIG_H #include #endif #if defined(sun) && (defined(SVR4) || defined(__SVR4) || defined(__SVR4__)) /* * Solaris 2.x aka SunOS 5.x */ # ifdef i386 /* * On Solaris 2.1 x86 sys/frame.h is not useful at all * On Solaris 2.4 x86 sys/frame.h is buggy (fr_savfp is int!!) */ # ifndef _INCL_SYS_REG_H # include # define _INCL_SYS_REG_H # endif # endif # ifndef _INCL_SYS_FRAME_H # include # define _INCL_SYS_FRAME_H # endif #else # if defined(sun) /* * SunOS 4.x */ # ifndef _INCL_MACHINE_FRAME_H # include # define _INCL_MACHINE_FRAME_H # endif # else /* * Anything that is not SunOS */ #ifdef __cplusplus extern "C" { #endif /* * XXX: I hope this will be useful on other machines (no guarantee) * XXX: It is taken from a sun Motorola system, but should also be useful * XXX: on a i386. * XXX: In general you have to write a sample program, set a breakpoint * XXX: on a small function and inspect the stackframe with adb. */ struct frame { struct frame *fr_savfp; /* saved frame pointer */ int fr_savpc; /* saved program counter */ int fr_arg[1]; /* array of arguments */ }; #ifdef __cplusplus } #endif # endif /* ! defined (sun) */ #endif /* ! defined (sun) && (defined(SVR4) || defined(__SVR4) || defined(__SVR4__)) */ #endif /* _STKFRAME_H */ megactl-0.4.5/schily/strdefs.h000066400000000000000000000062301465722425200162640ustar00rootroot00000000000000/* @(#)strdefs.h 1.8 03/03/09 Copyright 1996 J. Schilling */ /* * Definitions for strings * * Copyright (c) 1996 J. Schilling */ /* * 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, 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; see the file COPYING. If not, write to the Free Software * Foundation, 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. */ #ifndef _STRDEFS_H #define _STRDEFS_H #ifndef _MCONFIG_H #include #endif #ifndef _PROTOTYP_H #include #endif /* * It may be that IBM's AIX has problems when doing * #include * #include * So I moved the #include to the top. As the file strings.h * defines strcasecmp() we may need it... * * Note that the only real problem appears if we use rubbish FSF based code that * #defines _NO_PROTO */ #ifdef HAVE_STRINGS_H #ifndef _INCL_STRINGS_H #include #define _INCL_STRINGS_H #endif #endif /* HAVE_STRINGS_H */ #ifdef HAVE_STRING_H #ifndef _INCL_STRING_H #include #define _INCL_STRING_H #endif #else /* HAVE_STRING_H */ #ifdef __cplusplus extern "C" { #endif #ifndef NULL #define NULL 0 #endif extern void *memcpy __PR((void *, const void *, int)); extern void *memmove __PR((void *, const void *, int)); extern char *strcpy __PR((char *, const char *)); extern char *strncpy __PR((char *, const char *, int)); extern char *strcat __PR((char *, const char *)); extern char *strncat __PR((char *, const char *, int)); extern int memcmp __PR((const void *, const void *, int)); extern int strcmp __PR((const char *, const char *)); extern int strcoll __PR((const char *, const char *)); extern int strncmp __PR((const char *, const char *, int)); extern int strxfrm __PR((char *, const char *, int)); extern void *memchr __PR((const void *, int, int)); extern char *strchr __PR((const char *, int)); extern int strcspn __PR((const char *, const char *)); /*#pragma int_to_unsigned strcspn*/ extern char *strpbrk __PR((const char *, const char *)); extern char *strrchr __PR((const char *, int)); extern int strspn __PR((const char *, const char *)); /*#pragma int_to_unsigned strspn*/ extern char *strstr __PR((const char *, const char *)); extern char *strtok __PR((char *, const char *)); extern void *memset __PR((void *, int, int)); extern char *strerror __PR((int)); extern int strlen __PR((const char *)); /*#pragma int_to_unsigned strlen*/ extern void *memccpy __PR((void *, const void *, int, int)); extern int strcasecmp __PR((const char *, const char *)); extern int strncasecmp __PR((const char *, const char *, int)); /*#define index strchr*/ /*#define rindex strrchr*/ #ifdef __cplusplus } #endif #endif /* HAVE_STRING_H */ #endif /* _STRDEFS_H */ megactl-0.4.5/schily/termcap.h000066400000000000000000000036451465722425200162540ustar00rootroot00000000000000/* @(#)termcap.h 1.6 03/06/15 Copyright 1995 J. Schilling */ /* * Copyright (c) 1995 J. Schilling */ /* * 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, 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; see the file COPYING. If not, write to the Free Software * Foundation, 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. */ #ifndef _TERMCAP_H #define _TERMCAP_H #ifndef _MCONFIG_H #include #endif #ifndef _PROTOTYP_H #include #endif #ifdef __cplusplus extern "C" { #endif /* * Flags for tcsetflags() */ #define TCF_NO_TC 0x0001 /* Don't follow tc= entries */ #define TCF_NO_SIZE 0x0002 /* Don't get actual ttysize (li#/co#)*/ #define TCF_NO_STRIP 0x0004 /* Don't strip down termcap buffer */ extern char PC; /* Pad character */ extern char *BC; /* Backspace if not "\b" from "bc" capability*/ extern char *UP; /* Cursor up string from "up" capability */ extern short ospeed; /* output speed coded as in ioctl */ extern int tgetent __PR((char *bp, char *name)); extern int tcsetflags __PR((int flags)); extern char *tcgetbuf __PR((void)); extern int tgetnum __PR((char *ent)); extern BOOL tgetflag __PR((char *ent)); extern char *tgetstr __PR((char *ent, char **array)); extern char *tdecode __PR((char *ep, char **array)); extern int tputs __PR((char *cp, int affcnt, int (*outc)(int c))); extern char *tgoto __PR((char *cm, int destcol, int destline)); #ifdef __cplusplus } #endif #endif /* _TERMCAP_H */ megactl-0.4.5/schily/timedefs.h000066400000000000000000000044421465722425200164150ustar00rootroot00000000000000/* @(#)timedefs.h 1.11 03/11/24 Copyright 1996 J. Schilling */ /* * Generic header for users of time(), gettimeofday() ... * * It includes definitions for time_t, struct timeval, ... * * Copyright (c) 1996 J. Schilling */ /* * 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, 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; see the file COPYING. If not, write to the Free Software * Foundation, 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. */ #ifndef _TIMEDEFS_H #define _TIMEDEFS_H #ifndef _MCONFIG_H #include #endif #ifndef _INCL_SYS_TYPES_H #include /* Needed for time_t */ #define _INCL_SYS_TYPES_H #endif #ifdef TIME_WITH_SYS_TIME # ifndef _INCL_SYS_TIME_H # include # define _INCL_SYS_TIME_H # endif # ifndef _INCL_TIME_H # include # define _INCL_TIME_H # endif #else #ifdef HAVE_SYS_TIME_H # ifndef _INCL_SYS_TIME_H # include # define _INCL_SYS_TIME_H # endif #else # ifndef _INCL_TIME_H # include # define _INCL_TIME_H # endif #endif #endif #ifdef __cplusplus extern "C" { #endif #if defined(__CYGWIN32__) || defined(__EMX__) || defined(__linux__) || defined(__DJGPP__) /* * Cygnus defines struct timeval in sys/time.h but not timerclear * timerclear is defined in windows32/Sockets.h ??? * * EMX for OS/2 defines struct timeval in sys/time.h but not timerclear * * Linux defines struct timeval in sys/time.h but if __USE_BSD is not * defined, timerclear is missing. */ #ifndef timerclear #define timerclear(tvp) (tvp)->tv_sec = (tvp)->tv_usec = 0 #endif #endif #ifndef timerclear #ifndef VMS struct timeval { long tv_sec; long tv_usec; }; #endif struct timezone { int tz_minuteswest; int tz_dsttime; }; #define timerclear(tvp) (tvp)->tv_sec = (tvp)->tv_usec = 0 #endif #ifdef __cplusplus } #endif #endif /* _TIMEDEFS_H */ megactl-0.4.5/schily/ttydefs.h000066400000000000000000000050341465722425200162750ustar00rootroot00000000000000/* @(#)ttydefs.h 1.26 03/02/28 Copyright 1984-2003 J. Schilling */ /* * Terminal driver tty mode handling * * Copyright (c) 1984-2003 J. Schilling */ /* * 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, 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; see the file COPYING. If not, write to the Free Software * Foundation, 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. */ #ifndef _TTYDEFS_H #define _TTYDEFS_H #ifndef _MCONFIG_H #include #endif #ifndef _INCL_SYS_TYPES_H #include #define _INCL_SYS_TYPES_H #endif #ifdef JOS # include # include #else #ifdef HAVE_TERMIOS_H # include # define _INCL_TERMIOS_H # ifdef TIOCGETA /* FreeBSD */ # define TCGETS TIOCGETA # define TCSETSW TIOCSETAW # endif # ifdef TCGETATTR # define TCGETS TCGETATTR # define TCSETSW TCSETATTRD # endif #else # ifdef HAVE_TERMIO_H # include # define _INCL_TERMIO_H # ifndef TCGETS # define termios termio # define TCGETS TCGETA # define TCSETSW TCSETAW # endif # else # define USE_V7_TTY # endif #endif #endif #if !defined(HAVE_TCGETATTR) || !defined(HAVE_TCSETATTR) # undef TCSANOW #endif #ifndef TCSANOW # if !defined(TCGETS) || !defined(TCSETSW) # define USE_V7_TTY # endif #endif #if !defined(_INCL_TERMIOS_H) && !defined(_INCL_TERMIO_H) #ifdef HAVE_SYS_IOCTL_H # ifndef _INCL_SYS_IOCTl_H # include # define _INCL_SYS_IOCTL_H # endif #endif #endif #ifdef HAVE_SYS_BSDTTY_H #include #endif #if !defined(TIOCGWINSZ) && ! defined(TIOCGSIZE) # ifndef _INCL_SYS_IOCTl_H # include # define _INCL_SYS_IOCTL_H # endif #endif #ifndef OXTABS /* OS/2 EMX */ #define OXTABS 0 #endif #ifndef XTABS # ifndef TAB3 /* FreeBSD */ # define TABDLY OXTABS # define XTABS OXTABS # else # define XTABS TAB3 # endif #endif #ifndef ONLCR /* OS/2 EMX */ #define ONLCR 0 #endif #ifndef OCRNL /* FreeBSD */ # define OCRNL 0 #endif #ifndef ONLRET /* FreeBSD */ # define ONLRET 0 #endif #ifndef _POSIX_VDISABLE # define _POSIX_VDISABLE 0 #endif #endif /* _TTYDEFS_H */ megactl-0.4.5/schily/unixstd.h000066400000000000000000000060061465722425200163110ustar00rootroot00000000000000/* @(#)unixstd.h 1.12 04/06/17 Copyright 1996 J. Schilling */ /* * Definitions for unix system interface * * Copyright (c) 1996 J. Schilling */ /* * 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, 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; see the file COPYING. If not, write to the Free Software * Foundation, 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. */ #ifndef _UNIXSTD_H #define _UNIXSTD_H #ifndef _MCONFIG_H #include #endif #ifdef HAVE_UNISTD_H #ifndef _INCL_SYS_TYPES_H #include #define _INCL_SYS_TYPES_H #endif #ifndef _INCL_UNISTD_H #include #define _INCL_UNISTD_H #endif #ifndef _SC_PAGESIZE #ifdef _SC_PAGE_SIZE /* HP/UX & OSF */ #define _SC_PAGESIZE _SC_PAGE_SIZE #endif #endif #else /* HAVE_UNISTD_H */ /* * unistd.h grants things like off_t to be typedef'd. */ #ifndef _INCL_SYS_TYPES_H #include #define _INCL_SYS_TYPES_H #endif #endif /* HAVE_UNISTD_H */ #ifndef STDIN_FILENO # ifdef JOS # ifndef _JOS_IO_H # include # endif # else # define STDIN_FILENO 0 # define STDOUT_FILENO 1 # define STDERR_FILENO 2 # endif #endif #ifndef R_OK /* Symbolic constants for the "access" routine: */ #define R_OK 4 /* Test for Read permission */ #define W_OK 2 /* Test for Write permission */ #define X_OK 1 /* Test for eXecute permission */ #define F_OK 0 /* Test for existence of File */ #endif #ifndef E_OK #ifdef HAVE_ACCESS_E_OK #ifdef EFF_ONLY_OK #define E_OK EFF_ONLY_OK /* Irix */ #else #ifdef EUID_OK #define E_OK EUID_OK /* UNICOS (0400) */ #else #define E_OK 010 /* Test effective uids */ #endif /* EUID_OK */ #endif /* EFF_ONLY_OK */ #else #define E_OK 0 #endif /* HAVE_ACCESS_E_OK */ #endif /* !E_OK */ /* Symbolic constants for the "lseek" routine: */ #ifndef SEEK_SET #define SEEK_SET 0 /* Set file pointer to "offset" */ #endif #ifndef SEEK_CUR #define SEEK_CUR 1 /* Set file pointer to current plus "offset" */ #endif #ifndef SEEK_END #define SEEK_END 2 /* Set file pointer to EOF plus "offset" */ #endif #if !defined(HAVE_UNISTD_H) || !defined(_POSIX_VERSION) /* * Maybe we need a lot more definitions here... * It is not clear whether we should have prototyped definitions. */ extern int access __PR((const char *, int)); extern int close __PR((int)); extern int dup __PR((int)); extern int dup2 __PR((int, int)); extern void _exit __PR((int)); extern int link __PR((const char *, const char *)); extern int read __PR((int, void *, size_t)); extern int unlink __PR((const char *)); extern int write __PR((int, void *, size_t)); #endif #endif /* _UNIXSTD_H */ megactl-0.4.5/schily/unls.h000066400000000000000000000037121465722425200155750ustar00rootroot00000000000000/* @(#)unls.h 1.5 03/06/15 2000 J. Schilling */ /* * Modifications to make the code portable Copyright (c) 2000 J. Schilling * * Code taken from the Linux kernel. */ /* * 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, 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; see the file COPYING. If not, write to the Free Software * Foundation, 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. */ #ifndef _UNLS_H #define _UNLS_H #ifndef _MCONFIG_H #include #endif #ifndef _PROTOTYP_H #include #endif #ifdef USE_ICONV #include #endif #ifdef __cplusplus extern "C" { #endif struct nls_unicode { unsigned char uni1; unsigned char uni2; }; struct nls_table { char *charset; unsigned char **page_uni2charset; struct nls_unicode *charset2uni; #ifdef USE_ICONV iconv_t iconv_d; #endif void (*inc_use_count) __PR((void)); void (*dec_use_count) __PR((void)); struct nls_table *next; }; extern int init_nls __PR((void)); extern int register_nls __PR((struct nls_table *)); extern int unregister_nls __PR((struct nls_table *)); extern struct nls_table *find_nls __PR((char *)); extern void list_nls __PR((void)); extern struct nls_table *load_nls __PR((char *)); extern void unload_nls __PR((struct nls_table *)); extern struct nls_table *load_nls_default __PR((void)); extern int init_nls_file __PR((char * name)); #ifdef USE_ICONV extern int init_nls_iconv __PR((char * name)); #endif #ifdef __cplusplus } #endif #endif /* _UNLS_H */ megactl-0.4.5/schily/unls.h.utf8000066400000000000000000000034531465722425200164640ustar00rootroot00000000000000/* @(#)unls.h 1.5 03/06/15 2000 J. Schilling */ /* * Modifications to make the code portable Copyright (c) 2000 J. Schilling * * Code taken from the Linux kernel. */ /* * 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, 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; see the file COPYING. If not, write to the Free Software * Foundation, 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. */ #ifndef _UNLS_H #define _UNLS_H #ifndef _MCONFIG_H #include #endif #ifndef _PROTOTYP_H #include #endif #ifdef __cplusplus extern "C" { #endif struct nls_unicode { unsigned char uni1; unsigned char uni2; }; struct nls_table { char *charset; unsigned char **page_uni2charset; struct nls_unicode *charset2uni; void (*inc_use_count) __PR((void)); void (*dec_use_count) __PR((void)); struct nls_table *next; }; extern int init_nls __PR((void)); extern int register_nls __PR((struct nls_table *)); extern int unregister_nls __PR((struct nls_table *)); extern struct nls_table *find_nls __PR((char *)); extern void list_nls __PR((void)); extern struct nls_table *load_nls __PR((char *)); extern void unload_nls __PR((struct nls_table *)); extern struct nls_table *load_nls_default __PR((void)); extern int init_nls_file __PR((char * name)); #ifdef __cplusplus } #endif #endif /* _UNLS_H */ megactl-0.4.5/schily/utimdefs.h000066400000000000000000000032431465722425200164330ustar00rootroot00000000000000/* @(#)utimdefs.h 1.5 03/06/15 Copyright 2001 J. Schilling */ /* * Defines for utimes() / utime() * * Copyright (c) 2001 J. Schilling */ /* * 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, 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; see the file COPYING. If not, write to the Free Software * Foundation, 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. */ #ifndef _UTIMDEFS_H #define _UTIMDEFS_H #ifndef _MCONFIG_H #include #endif #ifndef _INCL_SYS_TYPES_H #include #define _INCL_SYS_TYPES_H #endif #ifdef HAVE_UTIMES #ifndef _TIMEDEFS_H #include #endif #endif #ifdef HAVE_UTIME_H #ifndef _INCL_UTIME_H #include #define _INCL_UTIME_H #endif #else #ifdef HAVE_SYS_UTIME_H #ifndef _INCL_SYS_UTIME_H #include #define _INCL_SYS_UTIME_H #endif #else struct utimbuf { time_t actime; time_t modtime; }; #endif #endif #ifdef __comment__ /* * file.c contains this * I am not sure if it is really needed. * It may be a good idea to add a test for HAVE_STRUCT_UTIMBUF * as in gnutar. */ #if (__COHERENT__ >= 0x420) # include #else # include #endif #endif /* __comment__ */ #endif /* _UTIMDEFS_H */ megactl-0.4.5/schily/utypes.h000066400000000000000000000161771465722425200161560ustar00rootroot00000000000000/* @(#)utypes.h 1.11 03/06/15 Copyright 1997 J. Schilling */ /* * Definitions for some user defined types * * Copyright (c) 1997 J. Schilling */ /* * 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, 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; see the file COPYING. If not, write to the Free Software * Foundation, 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. */ #ifndef _UTYPES_H #define _UTYPES_H #ifndef _MCONFIG_H #include #endif /* * Include limits.h for CHAR_BIT */ #ifdef HAVE_LIMITS_H #ifndef _INCL_LIMITS_H #include #define _INCL_LIMITS_H #endif #endif #ifndef CHAR_BIT #define CHAR_BIT 8 #endif /* * These macros may not work on all platforms but as we depend * on two's complement in many places, they do not reduce portability. */ #define TYPE_ISSIGNED(t) (((t)-1) < ((t)0)) #define TYPE_MSBVAL(t) ((t)(~((t)0) << (sizeof (t)*CHAR_BIT - 1))) #define TYPE_MINVAL(t) (TYPE_ISSIGNED(t) \ ? TYPE_MSBVAL(t) \ : ((t)0)) #define TYPE_MAXVAL(t) ((t)(~((t)0) - TYPE_MINVAL(t))) /* * Let us include system defined types too. */ #ifndef _INCL_SYS_TYPES_H #include #define _INCL_SYS_TYPES_H #endif #ifdef __CHAR_UNSIGNED__ /* GNU GCC define (dynamic) */ #ifndef CHAR_IS_UNSIGNED #define CHAR_IS_UNSIGNED /* Sing Schily define (static) */ #endif #endif /* * Several unsigned cardinal types */ typedef unsigned long Ulong; typedef unsigned int Uint; typedef unsigned short Ushort; typedef unsigned char Uchar; /* * This is a definition for a compiler dependant 64 bit type. * It currently is silently a long if the compiler does not * support it. Check if this is the right way. */ #ifndef NO_LONGLONG # if defined(HAVE_LONGLONG) # define USE_LONGLONG # endif #endif #ifdef USE_LONGLONG typedef long long Llong; typedef unsigned long long Ullong; #define SIZEOF_LLONG SIZEOF_LONG_LONG #define SIZEOF_ULLONG SIZEOF_UNSIGNED_LONG_LONG #else typedef long Llong; typedef unsigned long Ullong; #define SIZEOF_LLONG SIZEOF_LONG #define SIZEOF_ULLONG SIZEOF_UNSIGNED_LONG #endif /* * The IBM AIX C-compiler seems to be the only compiler on the world * which does not allow to use unsigned char bit fields as a hint * for packed bit fields. Define a pesical type to avoid warnings. * The packed attribute is honored wit unsigned int in this case too. */ #if defined(_AIX) && !defined(__GNUC__) typedef unsigned int Ucbit; #else typedef unsigned char Ucbit; #endif /* * Start inttypes.h emulation. * * Thanks to Solaris 2.4 and even recent 1999 Linux versions, we * cannot use the official UNIX-98 names here. Old Solaris versions * define parts of the types in some exotic include files. * Linux even defines incompatible types in . */ #ifdef HAVE_INTTYPES_H # ifndef _INCL_INTTYPES_H # include # define _INCL_INTTYPES_H # endif # define HAVE_INT64_T # define HAVE_UINT64_T #define Int8_t int8_t #define Int16_t int16_t #define Int32_t int32_t #define Int64_t int64_t #define Intmax_t intmax_t #define UInt8_t uint8_t #define UInt16_t uint16_t #define UInt32_t uint32_t #define UInt64_t uint64_t #define UIntmax_t uintmax_t #define Intptr_t intptr_t #define UIntptr_t uintptr_t #else /* !HAVE_INTTYPES_H */ #if SIZEOF_CHAR != 1 || SIZEOF_UNSIGNED_CHAR != 1 /* * #error will not work for all compilers (e.g. sunos4) * The following line will abort compilation on all compilers * if the above is true. And that's what we want. */ error Sizeof char is not equal 1 #endif #if defined(__STDC__) || defined(CHAR_IS_UNSIGNED) typedef signed char Int8_t; #else typedef char Int8_t; #endif #if SIZEOF_SHORT_INT == 2 typedef short Int16_t; #else error No int16_t found #endif #if SIZEOF_INT == 4 typedef int Int32_t; #else error No int32_t found #endif #if SIZEOF_LONG_INT == 8 typedef long Int64_t; # define HAVE_INT64_T #else #if SIZEOF_LONG_LONG == 8 typedef long long Int64_t; # define HAVE_INT64_T #else /* error No int64_t found*/ #endif #endif #if SIZEOF_CHAR_P == SIZEOF_INT typedef int Intptr_t; #else #if SIZEOF_CHAR_P == SIZEOF_LONG_INT typedef long Intptr_t; #else error No intptr_t found #endif #endif typedef unsigned char UInt8_t; #if SIZEOF_UNSIGNED_SHORT_INT == 2 typedef unsigned short UInt16_t; #else error No uint16_t found #endif #if SIZEOF_UNSIGNED_INT == 4 typedef unsigned int UInt32_t; #else error No int32_t found #endif #if SIZEOF_UNSIGNED_LONG_INT == 8 typedef unsigned long UInt64_t; # define HAVE_UINT64_T #else #if SIZEOF_UNSIGNED_LONG_LONG == 8 typedef unsigned long long UInt64_t; # define HAVE_UINT64_T #else /* error No uint64_t found*/ #endif #endif #define Intmax_t Llong #define UIntmax_t Ullong #if SIZEOF_CHAR_P == SIZEOF_UNSIGNED_INT typedef unsigned int UIntptr_t; #else #if SIZEOF_CHAR_P == SIZEOF_UNSIGNED_LONG_INT typedef unsigned long UIntptr_t; #else error No uintptr_t found #endif #endif #endif /* HAVE_INTTYPES_H */ #ifndef CHAR_MIN #define CHAR_MIN TYPE_MINVAL(char) #endif #ifndef CHAR_MAX #define CHAR_MAX TYPE_MAXVAL(char) #endif #ifndef UCHAR_MAX #define UCHAR_MAX TYPE_MAXVAL(unsigned char) #endif #ifndef SHRT_MIN #define SHRT_MIN TYPE_MINVAL(short) #endif #ifndef SHRT_MAX #define SHRT_MAX TYPE_MAXVAL(short) #endif #ifndef USHRT_MAX #define USHRT_MAX TYPE_MAXVAL(unsigned short) #endif #ifndef INT_MIN #define INT_MIN TYPE_MINVAL(int) #endif #ifndef INT_MAX #define INT_MAX TYPE_MAXVAL(int) #endif #ifndef UINT_MAX #define UINT_MAX TYPE_MAXVAL(unsigned int) #endif #ifndef LONG_MIN #define LONG_MIN TYPE_MINVAL(long) #endif #ifndef LONG_MAX #define LONG_MAX TYPE_MAXVAL(long) #endif #ifndef ULONG_MAX #define ULONG_MAX TYPE_MAXVAL(unsigned long) #endif #ifndef INT8_MIN #define INT8_MIN TYPE_MINVAL(Int8_t) #endif #ifndef INT8_MAX #define INT8_MAX TYPE_MAXVAL(Int8_t) #endif #ifndef UINT8_MAX #define UINT8_MAX TYPE_MAXVAL(UInt8_t) #endif #ifndef INT16_MIN #define INT16_MIN TYPE_MINVAL(Int16_t) #endif #ifndef INT16_MAX #define INT16_MAX TYPE_MAXVAL(Int16_t) #endif #ifndef UINT16_MAX #define UINT16_MAX TYPE_MAXVAL(UInt16_t) #endif #ifndef INT32_MIN #define INT32_MIN TYPE_MINVAL(Int32_t) #endif #ifndef INT32_MAX #define INT32_MAX TYPE_MAXVAL(Int32_t) #endif #ifndef UINT32_MAX #define UINT32_MAX TYPE_MAXVAL(UInt32_t) #endif #ifdef HAVE_INT64_T #ifndef INT64_MIN #define INT64_MIN TYPE_MINVAL(Int64_t) #endif #ifndef INT64_MAX #define INT64_MAX TYPE_MAXVAL(Int64_t) #endif #endif #ifdef HAVE_UINT64_T #ifndef UINT64_MAX #define UINT64_MAX TYPE_MAXVAL(UInt64_t) #endif #endif #ifndef INTMAX_MIN #define INTMAX_MIN TYPE_MINVAL(Intmax_t) #endif #ifndef INTMAX_MAX #define INTMAX_MAX TYPE_MAXVAL(Intmax_t) #endif #ifndef UINTMAX_MAX #define UINTMAX_MAX TYPE_MAXVAL(UIntmax_t) #endif #endif /* _UTYPES_H */ megactl-0.4.5/schily/vadefs.h000066400000000000000000000062361465722425200160700ustar00rootroot00000000000000/* @(#)vadefs.h 1.5 01/07/15 Copyright 1998 J. Schilling */ /* * Generic header for users of var args ... * * Includes a default definition for va_copy() * and some magic know how about the SVr4 Power PC var args ABI * to create a __va_arg_list() macro. * * Copyright (c) 1998 J. Schilling */ /* * 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, 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; see the file COPYING. If not, write to * the Free Software Foundation, 675 Mass Ave, Cambridge, MA 02139, USA. */ #ifndef _VADEFS_H #define _VADEFS_H #ifndef _MCONFIG_H #include #endif #ifdef PROTOTYPES /* * For ANSI C-compilers prefer stdarg.h */ # ifdef HAVE_STDARG_H # ifndef _INCL_STDARG_H # include # define _INCL_STDARG_H # endif # else # ifndef _INCL_VARARGS_H # include # define _INCL_VARARGS_H # endif # endif #else /* * For K&R C-compilers prefer varargs.h */ # ifdef HAVE_VARARGS_H # ifndef _INCL_VARARGS_H # include # define _INCL_VARARGS_H # endif # else # ifndef _INCL_STDARG_H # include # define _INCL_STDARG_H # endif # endif #endif #if (defined(__linux__) || defined(__linux) || defined(sun)) && \ (defined(__ppc) || defined(__PPC) || defined(powerpc) || defined(__powerpc__)) # ifndef VA_LIST_IS_ARRAY # define VA_LIST_IS_ARRAY # endif #endif /* * __va_copy() is used by GCC 2.8 or newer until va_copy() becomes * a final ISO standard. */ #if !defined(va_copy) && !defined(HAVE_VA_COPY) # if defined(__va_copy) # define va_copy(to, from) __va_copy(to, from) # endif #endif /* * va_copy() is a Solaris extension to provide a portable way to perform a * variable argument list "bookmarking" function. * If it is not available via stdarg.h, use a simple assignement for backward * compatibility. */ #if !defined(va_copy) && !defined(HAVE_VA_COPY) #ifdef VA_LIST_IS_ARRAY # define va_copy(to, from) ((to)[0] = (from)[0]) #else # define va_copy(to, from) ((to) = (from)) #endif #endif /* * I don't know any portable way to get an arbitrary * C object from a var arg list so I use a * system-specific routine __va_arg_list() that knows * if 'va_list' is an array. You will not be able to * assign the value of __va_arg_list() but it works * to be used as an argument of a function. * It is a requirement for recursive printf to be able * to use this function argument. If your system * defines va_list to be an array you need to know this * via autoconf or another mechanism. * It would be nice to have something like * __va_arg_list() in stdarg.h */ #ifdef VA_LIST_IS_ARRAY # define __va_arg_list(list) va_arg(list, void *) #else # define __va_arg_list(list) va_arg(list, va_list) #endif #endif /* _VADEFS_H */ megactl-0.4.5/schily/waitdefs.h000066400000000000000000000063061465722425200164240ustar00rootroot00000000000000/* @(#)waitdefs.h 1.10 03/02/25 Copyright 1995-2003 J. Schilling */ /* * Definitions to deal with various kinds of wait flavour * * Copyright (c) 1995-2003 J. Schilling */ /* * 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, 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; see the file COPYING. If not, write to the Free Software * Foundation, 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. */ #ifndef _WAITDEFS_H #define _WAITDEFS_H #ifndef _MCONFIG_H #include #endif /* * Needed for SysVr4 */ #ifndef _INCL_SYS_TYPES_H #include #define _INCL_SYS_TYPES_H #endif #if defined(HAVE_WAIT_H) # ifndef _INCL_WAIT_H # include # define _INCL_WAIT_H # endif #else /* * K&R Compiler doesn't like #elif */ # if defined(HAVE_SYS_WAIT_H) /* POSIX.1 compl. sys/wait.h */ # undef HAVE_UNION_WAIT /* POSIX.1 doesn't use U_W */ # ifndef _INCL_SYS_WAIT_H # include # define _INCL_SYS_WAIT_H # endif # else # if defined(HAVE_UNION_WAIT) /* Pure BSD U_W / sys/wait.h */ # ifndef _INCL_SYS_WAIT_H # include # define _INCL_SYS_WAIT_H # endif # endif # endif #endif #ifdef __cplusplus extern "C" { #endif #ifdef HAVE_UNION_WAIT # define WAIT_T union wait # ifndef WSTOPPED # define WSTOPPED 0x7F # endif # ifndef WTERMSIG # define WTERMSIG(status) ((status).w_termsig) # endif # ifndef WCOREDUMP # define WCOREDUMP(status) ((status).w_coredump) # endif # ifndef WEXITSTATUS # define WEXITSTATUS(status) ((status).w_retcode) # endif # ifndef WSTOPSIG # define WSTOPSIG(status) ((status).w_stopsig) # endif # ifndef WIFSTOPPED # define WIFSTOPPED(status) ((status).w_stopval == \ WSTOPPED) # endif # ifndef WIFSIGNALED # define WIFSIGNALED(status) ((status).w_stopval != \ WSTOPPED && \ (status).w_termsig != 0) # endif # ifndef WIFEXITED # define WIFEXITED(status) ((status).w_stopval != \ WSTOPPED && \ (status).w_termsig == 0) # endif #else # define WAIT_T int # ifndef WTERMSIG # define WTERMSIG(status) ((status) & 0x7F) # endif # ifndef WCOREDUMP # define WCOREDUMP(status) ((status) & 0x80) # endif # ifndef WEXITSTATUS # define WEXITSTATUS(status) (((status) >> 8) & 0xFF) # endif # ifndef WSTOPSIG # define WSTOPSIG(status) (((status) >> 8) & 0xFF) # endif # ifndef WIFSTOPPED # define WIFSTOPPED(status) (((status) & 0xFF) == 0x7F) # endif # ifndef WIFSIGNALED # define WIFSIGNALED(status) (((status) & 0xFF) != 0x7F && \ WTERMSIG(status) != 0) # endif # ifndef WIFEXITED # define WIFEXITED(status) (((status) & 0xFF) == 0) # endif #endif #ifndef WCOREFLG #define WCOREFLG 0x80 #endif #ifndef WSTOPFLG #define WSTOPFLG 0x7F #endif #ifndef WCONTFLG #define WCONTFLG 0xFFFF #endif #ifdef __cplusplus } #endif #endif /* _WAITDEFS_H */ megactl-0.4.5/schily/xconfig.h000066400000000000000000000662401465722425200162560ustar00rootroot00000000000000/* xconfig.h. Generated automatically by configure. */ /* @(#)xconfig.h.in 1.76 04/07/26 Copyright 1998-2003 J. Schilling */ /* * Dynamic autoconf C-include code. * * Copyright (c) 1998-2003 J. Schilling */ /* * Header Files */ #define PROTOTYPES 1 /* if Compiler supports ANSI C prototypes */ #define HAVE_STDARG_H 1 /* to use stdarg.h, else use varargs.h NOTE: SaberC on a Sun has prototypes but no stdarg.h */ /* #undef HAVE_VARARGS_H */ /* to use use varargs.h NOTE: The free HP-UX C-compiler has stdarg.h but no PROTOTYPES */ #define HAVE_STDLIB_H 1 /* to use general utility defines (malloc(), size_t ...) and general C library prototypes */ #define HAVE_STDDEF_H 1 /* to use offsetof(), ptrdiff_t, wchar>t, size_t */ #define HAVE_STRING_H 1 /* to get NULL and ANSI C string function prototypes */ #define HAVE_STRINGS_H 1 /* to get BSD string function prototypes */ #define STDC_HEADERS 1 /* if ANSI compliant stdlib.h, stdarg.h, string.h, float.h are present */ #define HAVE_UNISTD_H 1 /* to get POSIX syscall prototypes XXX sys/file.h fcntl.h (unixstd/fctl)XXX*/ #define HAVE_GETOPT_H 1 /* to get getopt() prototype from getopt.h instead of unistd.h */ #define HAVE_LIMITS_H 1 /* to get POSIX numeric limits constants */ #define HAVE_A_OUT_H 1 /* if a.out.h is present (may be a system using a.out format) */ /* #undef HAVE_AOUTHDR_H */ /* if aouthdr.h is present. This is a COFF system */ #define HAVE_ELF_H 1 /* if elf.h is present. This is an ELF system */ #define HAVE_FCNTL_H 1 /* to access, O_XXX constants for open(), otherwise use sys/file.h */ #define HAVE_SYS_FILE_H 1 /* to use O_XXX constants for open() and flock() defs */ #define HAVE_INTTYPES_H 1 /* to use UNIX-98 inttypes.h */ #define HAVE_DIRENT_H 1 /* to use POSIX dirent.h */ /* #undef HAVE_SYS_DIR_H */ /* to use BSD sys/dir.h */ /* #undef HAVE_NDIR_H */ /* to use ndir.h */ /* #undef HAVE_SYS_NDIR_H */ /* to use sys/ndir.h */ #define HAVE_ALLOCA_H 1 /* if alloca.h exists */ #define HAVE_MALLOC_H 1 /* if malloc.h exists */ #define HAVE_TERMIOS_H 1 /* to use POSIX termios.h */ #define HAVE_TERMIO_H 1 /* to use SVR4 termio.h */ #define HAVE_PWD_H 1 /* if pwd.h exists */ #define HAVE_GRP_H 1 /* if grp.h exists */ #define HAVE_SYS_ACL_H 1 /* to use for ACL definitions */ /* #undef HAVE_ACLLIB_H */ /* if HP-UX is present */ #define HAVE_SHADOW_H 1 /* if shadow.h exists */ #define HAVE_SYSLOG_H 1 /* if syslog.h exists */ #define HAVE_SYS_TIME_H 1 /* may include sys/time.h for struct timeval */ #define TIME_WITH_SYS_TIME 1 /* may include both time.h and sys/time.h */ #define HAVE_TIMES 1 /* to use times() and sys/times.h */ #define HAVE_SYS_TIMES_H 1 /* may include sys/times.h for struct tms */ #define HAVE_UTIME 1 /* to use AT&T utime() and utimbuf */ #define HAVE_UTIMES 1 /* to use BSD utimes() and sys/time.h */ #define HAVE_UTIME_H 1 /* to use utime.h for the utimbuf structure declaration, else declare struct utimbuf yourself */ /* #undef HAVE_SYS_UTIME_H */ /* to use sys/utime.h if utime.h does not exist */ #define HAVE_SYS_IOCTL_H 1 /* if sys/ioctl.h is present */ /* #undef HAVE_SYS_FILIO_H */ /* if sys/ioctl.h is present */ #define HAVE_SYS_PARAM_H 1 /* if sys/param.h is present */ #define HAVE_MNTENT_H 1 /* if mntent.h is present */ /* #undef HAVE_SYS_MNTENT_H */ /* if sys/mntent.h is present */ /* #undef HAVE_SYS_MNTTAB_H */ /* if sys/mnttab.h is present */ #define HAVE_SYS_MOUNT_H 1 /* if sys/mount.h is present */ #define HAVE_WAIT_H 1 /* to use wait.h for prototypes and union wait */ #define HAVE_SYS_WAIT_H 1 /* else use sys/wait.h */ #define HAVE_SYS_RESOURCE_H 1 /* to use sys/resource.h for rlimit() and wait3() */ #define HAVE_SYS_PROCFS_H 1 /* to use sys/procfs.h for wait3() emulation */ /* #undef HAVE_SYS_SYSTEMINFO_H */ /* to use SVr4 sysinfo() */ #define HAVE_SYS_UTSNAME_H 1 /* to use uname() */ /* #undef HAVE_SYS_PRIOCNTL_H */ /* to use SVr4 priocntl() instead of nice()/setpriority() */ /* #undef HAVE_SYS_RTPRIOCNTL_H */ /* if the system supports SVr4 real time classes */ #define HAVE_SYS_SYSCALL_H 1 /* to use syscall() */ #define HAVE_SYS_MTIO_H 1 /* to use mtio definitions from sys/mtio.h */ /* #undef HAVE_SYS_TAPE_H */ /* to use mtio definitions from AIX sys/tape.h */ #define HAVE_SYS_MMAN_H 1 /* to use definitions for mmap()/madvise()... from sys/mman.h */ #define HAVE_SYS_SHM_H 1 /* to use definitions for shmget() ... from sys/shm.h */ #define HAVE_SYS_IPC_H 1 /* to use definitions for shmget() ... from sys/ipc.h */ /* #undef MAJOR_IN_MKDEV */ /* if we should include sys/mkdev.h to get major()/minor()/makedev() */ #define MAJOR_IN_SYSMACROS 1 /* if we should include sys/sysmacros.h to get major()/minor()/makedev() */ /* #undef HAVE_SYS_DKIO_H */ /* if we may include sys/dkio.h for disk ioctls */ /* #undef HAVE_SYS_DKLABEL_H */ /* if we may include sys/dklabel.h for disk label */ /* #undef HAVE_SUN_DKIO_H */ /* if we may include sun/dkio.h for disk ioctls */ /* #undef HAVE_SUN_DKLABEL_H */ /* if we may include sun/dklabel.h for disk label */ #define HAVE_SYS_TYPES_H 1 /* if we may include sys/types.h (the standard) */ #define HAVE_SYS_STAT_H 1 /* if we may include sys/stat.h (the standard) */ /* #undef HAVE_TYPES_H */ /* if we may include types.h (rare cases e.g. ATARI TOS) */ /* #undef HAVE_STAT_H */ /* if we may include stat.h (rare cases e.g. ATARI TOS) */ #define HAVE_POLL_H 1 /* if we may include poll.h to use poll() */ #define HAVE_SYS_POLL_H 1 /* if we may include sys/poll.h to use poll() */ #define HAVE_SYS_SELECT_H 1 /* if we may have sys/select.h nonstandard use for select() on some systems*/ /* #undef NEED_SYS_SELECT_H */ /* if we need sys/select.h to use select() (this is nonstandard) */ #define HAVE_NETDB_H 1 /* if we have netdb.h for get*by*() and rcmd() */ #define HAVE_SYS_SOCKET_H 1 /* if we have sys/socket.h for socket() */ /* #undef NEED_SYS_SOCKET_H */ /* if we need sys/socket.h to use select() (this is nonstandard) */ #define HAVE_LINUX_PG_H 1 /* if we may include linux/pg.h for PP ATAPI sypport */ /* #undef HAVE_CAMLIB_H */ /* if we may include camlib.h for CAM SCSI transport definitions */ /* #undef HAVE_IEEEFP_H */ /* if we may include ieeefp.h for finite()/isnand() */ /* #undef HAVE_FP_H */ /* if we may include fp.h for FINITE()/IS_INF()/IS_NAN() */ #define HAVE_VALUES_H 1 /* if we may include values.h for MAXFLOAT */ #define HAVE_FLOAT_H 1 /* if we may include float.h for FLT_MAX */ /* #undef HAVE__FILBUF */ /* if we have _filbuf() for USG derived STDIO */ /* #undef HAVE___FILBUF */ /* if we have __filbuf() for USG derived STDIO */ /* #undef HAVE_USG_STDIO */ /* if we have USG derived STDIO */ #define HAVE_ERRNO_DEF 1 /* if we have errno definition in */ /* #undef HAVE_VFORK_H */ /* if we should include vfork.h for vfork() definitions */ #define HAVE_ARPA_INET_H 1 /* if we have arpa/inet.h (missing on BeOS) */ /* BeOS has inet_ntoa() in */ /* #undef HAVE_BSD_DEV_SCSIREG_H */ /* if we have a NeXT Step compatible sg driver */ /* #undef HAVE_SYS_BSDTTY_H */ /* if we have sys/bsdtty.h on HP-UX for TIOCGPGRP */ /* #undef HAVE_OS_H */ /* if we have the BeOS kernel definitions in OS.h */ #define HAVE_ATTR_XATTR_H 1 /* if we have the Linux Extended File Attr definitions in attr/xattr.h */ #define HAVE_FNMATCH_H 1 /* if we may include fnmatch.h */ /* * Convert to SCHILY name */ #ifdef STDC_HEADERS # ifndef HAVE_STDC_HEADERS # define HAVE_STDC_HEADERS # endif #endif #ifdef HAVE_ELF_H #define HAVE_ELF /* This system uses ELF */ #else # ifdef HAVE_AOUTHDR_H # define HAVE_COFF /* This system uses COFF */ # else # ifdef HAVE_A_OUT_H # define HAVE_AOUT /* This system uses AOUT */ # endif # endif #endif /* * Library Functions */ #define HAVE_ACCESS 1 /* access() is present in libc */ /* #undef HAVE_EACCESS */ /* eaccess() is present in libc */ #define HAVE_EUIDACCESS 1 /* euidaccess() is present in libc */ /* #undef HAVE_ACCESS_E_OK */ /* access() implements E_OK (010) for effective UIDs */ #define HAVE_CRYPT 1 /* crypt() is present in libc or libcrypt */ #define HAVE_STRERROR 1 /* strerror() is present in libc */ #define HAVE_MEMMOVE 1 /* memmove() is present in libc */ #define HAVE_MADVISE 1 /* madvise() is present in libc */ #define HAVE_MLOCK 1 /* mlock() is present in libc */ #define HAVE_MLOCKALL 1 /* working mlockall() is present in libc */ #define HAVE_MMAP 1 /* working mmap() is present in libc */ /* #undef _MMAP_WITH_SIZEP */ /* mmap() needs address of size parameter */ #define HAVE_FLOCK 1 /* *BSD flock() is present in libc */ #define HAVE_LOCKF 1 /* lockf() is present in libc (XOPEN) */ #define HAVE_FCNTL_LOCKF 1 /* file locking via fcntl() is present in libc */ #define HAVE_FCHDIR 1 /* fchdir() is present in libc */ #define HAVE_STATVFS 1 /* statvfs() is present in libc */ #define HAVE_QUOTACTL 1 /* quotactl() is present in libc */ /* #undef HAVE_QUOTAIOCTL */ /* use ioctl(f, Q_QUOTACTL, &q) instead of quotactl() */ #define HAVE_SETREUID 1 /* setreuid() is present in libc */ #define HAVE_SETRESUID 1 /* setresuid() is present in libc */ #define HAVE_SETEUID 1 /* seteuid() is present in libc */ #define HAVE_SETUID 1 /* setuid() is present in libc */ #define HAVE_SETREGID 1 /* setregid() is present in libc */ #define HAVE_SETRESGID 1 /* setresgid() is present in libc */ #define HAVE_SETEGID 1 /* setegid() is present in libc */ #define HAVE_SETGID 1 /* setgid() is present in libc */ #define HAVE_GETPGID 1 /* getpgid() is present in libc (POSIX) */ #define HAVE_SETPGID 1 /* setpgid() is present in libc (POSIX) */ #define HAVE_GETPGRP 1 /* getpgrp() is present in libc (ANY) */ #define HAVE_SETPGRP 1 /* setpgrp() is present in libc (ANY) */ /* #undef HAVE_BSD_GETPGRP */ /* getpgrp() in libc is BSD-4.2 compliant */ /* #undef HAVE_BSD_SETPGRP */ /* setpgrp() in libc is BSD-4.2 compliant */ #define HAVE_GETSPNAM 1 /* getspnam() in libc (SVR4 compliant) */ /* #undef HAVE_GETSPWNAM */ /* getspwnam() in libsec.a (HP-UX) */ #define HAVE_SYNC 1 /* sync() is present in libc */ #define HAVE_FSYNC 1 /* fsync() is present in libc */ #define HAVE_TCGETATTR 1 /* tcgetattr() is present in libc */ #define HAVE_TCSETATTR 1 /* tcsetattr() is present in libc */ #define HAVE_WAIT3 1 /* working wait3() is present in libc */ #define HAVE_WAIT4 1 /* wait4() is present in libc */ #define HAVE_WAITID 1 /* waitid() is present in libc */ #define HAVE_WAITPID 1 /* waitpid() is present in libc */ #define HAVE_GETHOSTID 1 /* gethostid() is present in libc */ #define HAVE_GETHOSTNAME 1 /* gethostname() is present in libc */ #define HAVE_GETDOMAINNAME 1 /* getdomainname() is present in libc */ #define HAVE_GETPAGESIZE 1 /* getpagesize() is present in libc */ #define HAVE_GETDTABLESIZE 1 /* getdtablesize() is present in libc */ #define HAVE_GETRUSAGE 1 /* getrusage() is present in libc */ #define HAVE_GETRLIMIT 1 /* getrlimit() is present in libc */ #define HAVE_SETRLIMIT 1 /* setrlimit() is present in libc */ #define HAVE_ULIMIT 1 /* ulimit() is present in libc */ #define HAVE_GETTIMEOFDAY 1 /* gettimeofday() is present in libc */ #define HAVE_SETTIMEOFDAY 1 /* settimeofday() is present in libc */ #define HAVE_TIME 1 /* time() is present in libc */ #define HAVE_STIME 1 /* stime() is present in libc */ #define HAVE_POLL 1 /* poll() is present in libc */ #define HAVE_SELECT 1 /* select() is present in libc */ #define HAVE_CHOWN 1 /* chown() is present in libc */ #define HAVE_LCHOWN 1 /* lchown() is present in libc */ #define HAVE_BRK 1 /* brk() is present in libc */ #define HAVE_SBRK 1 /* sbrk() is present in libc */ #define HAVE_VA_COPY 1 /* va_copy() is present in varargs.h/stdarg.h */ #define HAVE__VA_COPY 1 /* __va_copy() is present in varargs.h/stdarg.h */ /* #undef HAVE_DTOA */ /* BSD-4.4 __dtoa() is present in libc */ /* #undef HAVE_DTOA_R */ /* BSD-4.4 __dtoa() with result ptr (reentrant) */ #define HAVE_DUP2 1 /* dup2() is present in libc */ #define HAVE_GETCWD 1 /* POSIX getcwd() is present in libc */ #define HAVE_SMMAP 1 /* may map anonymous memory to get shared mem */ #define HAVE_SHMAT 1 /* shmat() is present in libc */ #define HAVE_SEMGET 1 /* semget() is present in libc */ #define HAVE_LSTAT 1 /* lstat() is present in libc */ #define HAVE_READLINK 1 /* readlink() is present in libc */ #define HAVE_SYMLINK 1 /* symlink() is present in libc */ #define HAVE_LINK 1 /* link() is present in libc */ #define HAVE_HARD_SYMLINKS 1 /* link() allows hard links on symlinks */ #define HAVE_LINK_NOFOLLOW 1 /* link() does not follow symlinks when hard linking symlinks */ #define HAVE_RENAME 1 /* rename() is present in libc */ #define HAVE_MKFIFO 1 /* mkfifo() is present in libc */ #define HAVE_MKNOD 1 /* mknod() is present in libc */ #define HAVE_ECVT 1 /* ecvt() is present in libc */ #define HAVE_FCVT 1 /* fcvt() is present in libc */ #define HAVE_GCVT 1 /* gcvt() is present in libc */ #define HAVE_ECVT_R 1 /* ecvt_r() is present in libc */ #define HAVE_FCVT_R 1 /* fcvt_r() is present in libc */ /* #undef HAVE_GCVT_R */ /* gcvt_r() is present in libc */ /* #undef HAVE_ECONVERT */ /* econvert() is present in libc */ /* #undef HAVE_FCONVERT */ /* fconvert() is present in libc */ /* #undef HAVE_GCONVERT */ /* gconvert() is present in libc */ #define HAVE_ISINF 1 /* isinf() is present in libc */ #define HAVE_ISNAN 1 /* isnan() is present in libc */ #define HAVE_RAND 1 /* rand() is present in libc */ #define HAVE_DRAND48 1 /* drand48() is present in libc */ #define HAVE_SETPRIORITY 1 /* setpriority() is present in libc */ #define HAVE_NICE 1 /* nice() is present in libc */ /* #undef HAVE_DOSSETPRIORITY */ /* DosSetPriority() is present in libc */ /* #undef HAVE_DOSALLOCSHAREDMEM */ /* DosAllocSharedMem() is present in libc */ #define HAVE_SEEKDIR 1 /* seekdir() is present in libc */ #define HAVE_PUTENV 1 /* putenv() is present in libc (preferred function) */ #define HAVE_SETENV 1 /* setenv() is present in libc (use instead of putenv()) */ #define HAVE_UNAME 1 /* uname() is present in libc */ #define HAVE_SNPRINTF 1 /* snprintf() is present in libc */ #define HAVE_STRCASECMP 1 /* strcasecmp() is present in libc */ #define HAVE_STRDUP 1 /* strdup() is present in libc */ #define HAVE_STRSIGNAL 1 /* strsignal() is present in libc */ /* #undef HAVE_STR2SIG */ /* str2sig() is present in libc */ /* #undef HAVE_SIG2STR */ /* sig2str() is present in libc */ #define HAVE_KILLPG 1 /* killpg() is present in libc */ #define HAVE_SIGRELSE 1 /* sigrelse() is present in libc */ #define HAVE_SIGPROCMASK 1 /* sigprocmask() is present in libc (POSIX) */ #define HAVE_SIGSETMASK 1 /* sigsetmask() is present in libc (BSD) */ #define HAVE_SIGSET 1 /* sigset() is present in libc (POSIX) */ #define HAVE_SYS_SIGLIST 1 /* char *sys_siglist[] is present in libc */ #define HAVE_NANOSLEEP 1 /* nanosleep() is present in libc */ #define HAVE_USLEEP 1 /* usleep() is present in libc */ #define HAVE_FORK 1 /* fork() is present in libc */ #define HAVE_EXECL 1 /* execl() is present in libc */ #define HAVE_EXECLE 1 /* execle() is present in libc */ #define HAVE_EXECLP 1 /* execlp() is present in libc */ #define HAVE_EXECV 1 /* execv() is present in libc */ #define HAVE_EXECVE 1 /* execve() is present in libc */ #define HAVE_EXECVP 1 /* execvp() is present in libc */ #define HAVE_ALLOCA 1 /* alloca() is present (else use malloc())*/ #define HAVE_VALLOC 1 /* valloc() is present in libc (else use malloc())*/ /* #undef vfork */ /* #undef HAVE_CHFLAGS */ /* chflags() is present in libc */ /* #undef HAVE_FCHFLAGS */ /* fchflags() is present in libc */ /* #undef HAVE_FFLAGSTOSTR */ /* fflagstostr() is present in libc */ /* #undef HAVE_STRTOFFLAGS */ /* strtofflags() is present in libc */ #define HAVE_FNMATCH 1 /* fnmatch() is present in libc */ /* * Linux Extended File Attributes */ #define HAVE_GETXATTR 1 /* getxattr() */ #define HAVE_SETXATTR 1 /* setxattr() */ #define HAVE_LISTXATTR 1 /* listxattr() */ /* * Important: This must be a result from a check _before_ the Large File test * has been run. It then tells us whether these functions are * available even when not in Large File mode. * * Do not run the AC_FUNC_FSEEKO test from the GNU tar Large File test * siute. It will use the same cache names and interfere with our test. * Instead use the tests AC_SMALL_FSEEKO/AC_SMALL/STELLO and make sure * they are placed before the large file tests. */ /* #undef HAVE_FSEEKO */ /* fseeko() is present in default compile mode */ /* #undef HAVE_FTELLO */ /* ftello() is present in default compile mode */ #define HAVE_RCMD 1 /* rcmd() is present in libc/libsocket */ #define HAVE_SOCKET 1 /* socket() is present in libc/libsocket */ #define HAVE_SOCKETPAIR 1 /* socketpair() is present in libc/libsocket */ #define HAVE_GETSERVBYNAME 1 /* getservbyname() is present in libc/libsocket */ #define HAVE_INET_NTOA 1 /* inet_ntoa() is present in libc/libsocket */ #define HAVE_GETADDRINFO 1 /* getaddrinfo() is present in libc/libsocket */ #define HAVE_GETNAMEINFO 1 /* getnameinfo() is present in libc/libsocket */ #if defined(HAVE_QUOTACTL) || defined(HAVE_QUOTAIOCTL) # define HAVE_QUOTA /* The system inludes quota */ #endif /* * We need to test for the include files too because Apollo Domain/OS has a * libc that includes the functions but the includes files are not visible * from the BSD compile environment. */ #if defined(HAVE_SHMAT) && defined(HAVE_SYS_SHM_H) && defined(HAVE_SYS_IPC_H) # define HAVE_USGSHM /* USG shared memory is present */ #endif #if defined(HAVE_SEMGET) && defined(HAVE_SYS_SHM_H) && defined(HAVE_SYS_IPC_H) # define HAVE_USGSEM /* USG semaphores are present */ #endif #if defined(HAVE_GETPGRP) && !defined(HAVE_BSD_GETPGRP) #define HAVE_POSIX_GETPGRP 1 /* getpgrp() in libc is POSIX compliant */ #endif #if defined(HAVE_SETPGRP) && !defined(HAVE_BSD_SETPGRP) #define HAVE_POSIX_SETPGRP 1 /* setpgrp() in libc is POSIX compliant */ #endif /* * Structures */ #define HAVE_MTGET_TYPE 1 /* if struct mtget contains mt_type (drive type) */ /* #undef HAVE_MTGET_MODEL */ /* if struct mtget contains mt_model (drive type) */ #define HAVE_MTGET_DSREG 1 /* if struct mtget contains mt_dsreg (drive status) */ /* #undef HAVE_MTGET_DSREG1 */ /* if struct mtget contains mt_dsreg1 (drive status msb) */ /* #undef HAVE_MTGET_DSREG2 */ /* if struct mtget contains mt_dsreg2 (drive status lsb) */ #define HAVE_MTGET_GSTAT 1 /* if struct mtget contains mt_gstat (generic status) */ #define HAVE_MTGET_ERREG 1 /* if struct mtget contains mt_erreg (error register) */ #define HAVE_MTGET_RESID 1 /* if struct mtget contains mt_resid (residual count) */ #define HAVE_MTGET_FILENO 1 /* if struct mtget contains mt_fileno (file #) */ #define HAVE_MTGET_BLKNO 1 /* if struct mtget contains mt_blkno (block #) */ /* #undef HAVE_MTGET_FLAGS */ /* if struct mtget contains mt_flags (flags) */ /* #undef HAVE_MTGET_BF */ /* if struct mtget contains mt_bf (optimum blocking factor) */ #define HAVE_STRUCT_RUSAGE 1 /* have struct rusage in sys/resource.h */ /* #undef HAVE_SI_UTIME */ /* if struct siginfo contains si_utime */ /* #undef HAVE_UNION_SEMUN */ /* have an illegal definition for union semun in sys/sem.h */ #define HAVE_UNION_WAIT 1 /* have union wait in wait.h */ /* * SCO UnixWare has st_atim.st__tim.tv_nsec but the st_atim.tv_nsec tests also * succeeds. If you use st_atim.tv_nsec on UnixWare, you get a warning about * illegal structure usage. For this reason, your code needs to have * #ifdef HAVE_ST__TIM before #ifdef HAVE_ST_NSEC. */ /* #undef HAVE_ST_SPARE1 */ /* if struct stat contains st_spare1 (usecs) */ /* #undef HAVE_ST_ATIMENSEC */ /* if struct stat contains st_atimensec (nanosecs) */ #define HAVE_ST_NSEC 1 /* if struct stat contains st_atim.tv_nsec (nanosecs) */ /* #undef HAVE_ST__TIM */ /* if struct stat contains st_atim.st__tim.tv_nsec (nanosecs) */ /* #undef HAVE_ST_ATIMESPEC */ /* if struct stat contains st_atimespec.tv_nsec (nanosecs) */ #define HAVE_ST_BLKSIZE 1 /* if struct stat contains st_blksize */ #define HAVE_ST_BLOCKS 1 /* if struct stat contains st_blocks */ /* #undef HAVE_ST_FSTYPE */ /* if struct stat contains st_fstype */ #define HAVE_ST_RDEV 1 /* if struct stat contains st_rdev */ /* #undef HAVE_ST_FLAGS */ /* if struct stat contains st_flags */ /* #undef STAT_MACROS_BROKEN */ /* if the macros S_ISDIR, S_ISREG .. don't work */ #define DEV_MINOR_BITS 32 /* # if bits needed to hold minor device number */ #define DEV_MINOR_NONCONTIG 1 /* if bits in minor device number are noncontiguous */ #define HAVE_SOCKADDR_STORAGE 1 /* if socket.h defines struct sockaddr_storage */ /* * Byteorder/Bitorder */ #define HAVE_C_BIGENDIAN /* Flag that WORDS_BIGENDIAN test was done */ /* #undef WORDS_BIGENDIAN */ /* If using network byte order */ #define HAVE_C_BITFIELDS /* Flag that BITFIELDS_HTOL test was done */ /* #undef BITFIELDS_HTOL */ /* If high bits come first in structures */ /* * Types/Keywords */ #define SIZEOF_CHAR 1 #define SIZEOF_SHORT_INT 2 #define SIZEOF_INT 4 #define SIZEOF_LONG_INT 4 #define SIZEOF_LONG_LONG 8 #define SIZEOF_CHAR_P 4 #define SIZEOF_UNSIGNED_CHAR 1 #define SIZEOF_UNSIGNED_SHORT_INT 2 #define SIZEOF_UNSIGNED_INT 4 #define SIZEOF_UNSIGNED_LONG_INT 4 #define SIZEOF_UNSIGNED_LONG_LONG 8 #define SIZEOF_UNSIGNED_CHAR_P 4 #define HAVE_LONGLONG 1 /* Compiler defines long long type */ /* #undef CHAR_IS_UNSIGNED */ /* Compiler defines char to be unsigned */ /* #undef const */ /* Define to empty if const doesn't work */ /* #undef uid_t */ /* To be used if uid_t is not present */ /* #undef gid_t */ /* To be used if gid_t is not present */ /* #undef size_t */ /* To be used if size_t is not present */ /* #undef ssize_t */ /* To be used if ssize_t is not present */ /* #undef pid_t */ /* To be used if pid_t is not present */ /* #undef off_t */ /* To be used if off_t is not present */ /* #undef mode_t */ /* To be used if mode_t is not present */ /* #undef time_t */ /* To be used if time_t is not present */ /* #undef caddr_t */ /* To be used if caddr_t is not present */ /* #undef daddr_t */ /* To be used if daddr_t is not present */ /* #undef dev_t */ /* To be used if dev_t is not present */ /* #undef ino_t */ /* To be used if ino_t is not present */ /* #undef nlink_t */ /* To be used if nlink_t is not present */ #define blksize_t long /* To be used if blksize_t is not present */ /* #undef blkcnt_t */ /* To be used if blkcnt_t is not present */ /* * Important: Next Step needs time.h for clock_t (because of a bug) */ /* #undef clock_t */ /* To be used if clock_t is not present */ /* #undef socklen_t */ /* To be used if socklen_t is not present */ /* * These types are present on all UNIX systems but should be avoided * for portability. * On Apollo/Domain OS we don't have them.... * * Better include and use Uchar, Uint & Ulong */ /* #undef u_char */ /* To be used if u_char is not present */ /* #undef u_short */ /* To be used if u_short is not present */ /* #undef u_int */ /* To be used if u_int is not present */ /* #undef u_long */ /* To be used if u_long is not present */ /*#undef HAVE_SIZE_T*/ /*#undef NO_SIZE_T*/ /* #undef VA_LIST_IS_ARRAY */ /* va_list is an array */ #define GETGROUPS_T gid_t #define GID_T GETGROUPS_T /* * Define as the return type of signal handlers (int or void). */ #define RETSIGTYPE void /* * Defines needed to get large file support. */ #ifdef USE_LARGEFILES #define HAVE_LARGEFILES 1 #ifdef HAVE_LARGEFILES /* If we have working largefiles at all */ /* This is not defined with glibc-2.1.3 */ #define _FILE_OFFSET_BITS 64 /* # of bits in off_t if settable */ #define _LARGEFILE_SOURCE 1 /* To make ftello() visible (HP-UX 10.20). */ /* #undef _LARGE_FILES */ /* Large file defined on AIX-style hosts. */ /* #undef _XOPEN_SOURCE */ /* To make ftello() visible (glibc 2.1.3). */ /* XXX We don't use this because glibc2.1.3*/ /* XXX is bad anyway. If we define */ /* XXX _XOPEN_SOURCE we will loose caddr_t */ /* #undef HAVE_FSEEKO */ /* Do we need this? If HAVE_LARGEFILES is */ /* defined, we have fseeko() */ #endif /* HAVE_LARGEFILES */ #endif /* USE_LARGEFILES */ #ifdef USE_ACL /* Enable/disable ACL support */ /* * POSIX ACL support */ #define HAVE_ACL_GET_FILE 1 /* acl_get_file() function */ #define HAVE_ACL_SET_FILE 1 /* acl_set_file() function */ #define HAVE_ACL_FROM_TEXT 1 /* acl_from_text() function */ #define HAVE_ACL_TO_TEXT 1 /* acl_to_text() function */ #define HAVE_ACL_FREE 1 /* acl_free() function */ #define HAVE_ACL_DELETE_DEF_FILE 1 /* acl_delete_def_file() function */ #if defined(HAVE_ACL_GET_FILE) && defined(HAVE_ACL_SET_FILE) && \ defined(HAVE_ACL_FROM_TEXT) && defined(HAVE_ACL_TO_TEXT) && \ defined(HAVE_ACL_FREE) # define HAVE_POSIX_ACL 1 /* POSIX ACL's present */ #endif /* * Sun ACL support. * Note: unfortunately, HP-UX has an (undocumented) acl() function in libc. */ /* #undef HAVE_ACL */ /* acl() function */ /* #undef HAVE_FACL */ /* facl() function */ /* #undef HAVE_ACLFROMTEXT */ /* aclfromtext() function */ /* #undef HAVE_ACLTOTEXT */ /* acltotext() function */ #if defined(HAVE_ACL) && defined(HAVE_FACL) && \ defined(HAVE_ACLFROMTEXT) && defined(HAVE_ACLTOTEXT) # define HAVE_SUN_ACL 1 /* Sun ACL's present */ #endif /* * HP-UX ACL support. * Note: unfortunately, HP-UX has an (undocumented) acl() function in libc. */ /* #undef HAVE_GETACL */ /* getacl() function */ /* #undef HAVE_FGETACL */ /* fgetacl() function */ /* #undef HAVE_SETACL */ /* setacl() function */ /* #undef HAVE_FSETACL */ /* fsetacl() function */ /* #undef HAVE_STRTOACL */ /* strtoacl() function */ /* #undef HAVE_ACLTOSTR */ /* acltostr() function */ /* #undef HAVE_CPACL */ /* cpacl() function */ /* #undef HAVE_FCPACL */ /* fcpacl() function */ /* #undef HAVE_CHOWNACL */ /* chownacl() function */ /* #undef HAVE_SETACLENTRY */ /* setaclentry() function */ /* #undef HAVE_FSETACLENTRY */ /* fsetaclentry() function */ #if defined(HAVE_GETACL) && defined(HAVE_FGETACL) && \ defined(HAVE_SETACL) && defined(HAVE_FSETACL) && \ defined(HAVE_STRTOACL) && defined(HAVE_ACLTOTEXT) # define HAVE_HP_ACL 1 /* HP-UX ACL's present */ #endif /* * Global definition whether ACL support is present. * As HP-UX differs too much from other implementations, HAVE_HP_ACL is not * included in HAVE_ANY_ACL. */ #if defined(HAVE_POSIX_ACL) || defined(HAVE_SUN_ACL) # define HAVE_ANY_ACL 1 /* Any ACL implementation present */ #endif #endif /* USE_ACL */ /* * Misc CC / LD related stuff */ /* #undef NO_USER_MALLOC */ /* If we cannot define our own malloc() */ #define HAVE_DYN_ARRAYS 1 /* If the compiler allows dynamic sized arrays */ /* * Strings that help to maintain OS/platform id's in C-programs */ #define HOST_ALIAS "i686-pc-linux-gnu" /* Output from config.guess (orig) */ #define HOST_SUB "i686-pc-linux-gnu" /* Output from config.sub (modified) */ #define HOST_CPU "i686" /* CPU part from HOST_SUB */ #define HOST_VENDOR "pc" /* VENDOR part from HOST_SUB */ #define HOST_OS "linux-gnu" /* CPU part from HOST_SUB */ /* * Begin restricted code for quality assurance. * * Warning: you are not allowed to include the #define below if you are not * using the Schily makefile system or if you modified the autoconfiguration * tests. * * If you only added other tests you are allowed to keep this #define. * * This restiction is introduced because this way, I hope that people * contribute to the project instead of creating branches. */ #define IS_SCHILY_XCONFIG /* * End restricted code for quality assurance. */ megactl-0.4.5/schily/xmconfig.h000066400000000000000000001035241465722425200164300ustar00rootroot00000000000000/* @(#)xmconfig.h 1.29 03/06/15 Copyright 1995 J. Schilling */ /* * Manual generated static definitions for machine configuration * * Copyright (c) 1995 J. Schilling * * This file is made to be included from and may be used * instead of configurations that are dynamically autogenerated. * Use only cpp instructions. * * NOTE: SING: (Schily Is Not Gnu) */ /* * 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, 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; see the file COPYING. If not, write to the Free Software * Foundation, 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. */ #ifndef _XMCONFIG_H #define _XMCONFIG_H #ifdef __cplusplus extern "C" { #endif /* * 1) Compiler and language related headers * * define PROTOTYPES to use ansi C prototypes * * define HAVE_ELF Object files are stored in System V.4 ELF format. * * define HAVE_COFF Object files are stored in System V.2 COFF format. * * define HAVE_AOUT Object files are stored in ATT/BSD a.out format. * * define HAVE_STDARG_H to use stdarg.h, else use varargs.h * NOTE: SaberC on a Sun has prototypes but no stdarg.h. * * define HAVE_VA_COPY have va_copy() to do assignements of va_list type objects. * define HAVE__VA_COPY have __va_copy() to do assignements of va_list type objects. * * define HAVE_STDLIB_H to use general utility defines (malloc(), size_t ...) * some C library prototypes my be found here * * define HAVE_STRING_H to get NULL and string function prototypes * * define HAVE_STRINGS_H to get BSD string function prototypes * * define HAVE_STDC_HEADERS to declare the presence of other ansi C headers * define STDC_HEADERS same as above (GNU name) * * define HAVE_LONGLONG to use long long for space/transfer calculations * * define HAVE_SIZE_T The type size_t is present * define NO_SIZE_T The type size_t is not present * * * 2) Operating system related headers * * define HAVE_OSDEF to prevent later definitions to overwrite current * * define __NOT_SVR4__ Not a real SVR4 implementation * * define HAVE_UNISTD_H to use access, lockf and lseek constants * syscall prototypes may be found here also * use sys/file.h otherwise for above constants * * define HAVE_FCNTL_H to use access, O_XXX constants for open() * and open(), creat(), fcntl() prototypes * use sys/file.h otherwise for above constants * * define HAVE_DIRENT_H to use dirent.h instead of the old BSD sys/dir.h * define HAVE_SYS_DIR_H to use the old BSD sys/dir.h, otherwise no readdir() * define HAVE_NDIR_H to use ndir.h * define HAVE_SYS_NDIR_H to use sys/ndir.h * * define HAVE_MALLOC_H if malloc.h exists * * define HAVE_TERMIOS_H to use posix terminal and session control (termios.h) * define HAVE_TERMIO_H to use SV terminal control (termio.h) *- no setpgrp -* * Else use BSD style sgttyb and setpgrp (ioctl.h) * XXX session control should be another define XXX * * define HAVE_SYS_TIME_H may include sys/time.h for struct timeval * used internally in timedefs.h * * define HAVE_UTIMES to use BSD utimes() and sys/time.h * define HAVE_UTIME_H to use utime.h for the utimbuf structure declaration * Else declare struct utimbuf yourself. * * define HAVE_WAIT_H to use wait.h for prototypes and union wait * define HAVE_SYS_WAIT_H else use sys/wait.h * Else declare it by yourself. * * define HAVE_SYS_PARAM_H if it is ok to include sys/param.h * * define HAVE_SYS_SYSTEMINFO_H to use sysinfo() * define HAVE_SYS_UTSNAME_H to use uname() * * define HAVE_SYS_PRIOCNTL_H to use priocntl() instead of nice()/setpriority() * define HAVE_SYS_RTPRIOCNTL_H if the system supports real time classes. * * define HAVE_SYS_MTIO_H to use mtio definitions from sys/mtio.h * define HAVE_MTGET_DSREG if struct mtget contains mt_dsreg (drive status) * define HAVE_MTGET_RESID if struct mtget contains mt_resid (residual count) * define HAVE_MTGET_FILENO if struct mtget contains mt_fileno (file #) * define HAVE_MTGET_BLKNO if struct mtget contains mt_blkno (block #0 * * define MAJOR_IN_MKDEV if we should include sys/mkdev.h to get * major(), minor() and makedev() * * define MAJOR_IN_SYSMACROS if we should include sys/sysmacros.h to get * major(), minor() and makedev() * * ... else look in sys/types.h for major() * * 3) Miscellaneous operating system/library/processor related things * * define HAVE_USG_STDIO to enable the use USG stdio.h internals * To to this we need: * f->_flag & _IONBF ... Unbuffered * f->_flag & _IOERR ... I/O error * f->_flag & _IOEOF ... End of File * f->_cnt ... r/w count in buf * f->_ptr ... pointer into buf * _filbuf(FILE * f) ... fill buffer, return 1st ch * _flsbuf(unsigned char *, FILE * f) ... flush buffer * * define HAVE_BRK may use brk() * * define HAVE_SBRK may use sbrk() * * * define HAVE_DTOA use the 4.4BSD function __dtoa() instead of * the AT&T standard functions ecvt()/fcvt()/gcvt() * * define HAVE_GETCWD use SysV getcwd() instead of BSD getwd() * * define HAVE_STRERROR may use strerror() instead of sys_errlist[] and sys_nerr * * define HAVE_MEMMOVE should use memmove() instead of bcopy() * * define HAVE_MLOCKALL may use mlockall() to lock the whole process into memory * * define HAVE_MMAP may map memory (sys/types.h + sys/mman.h) * define HAVE_SMMAP may map anonymous memory to get shared mem * * define HAVE_USGSHM may get shared memory SV style (sys/types.h + sys/ipc.h) * * define HAVE_USGSEM may use SysV style shared memory and semaphores. * May use shared memory and semaphores to manage a * sharing buffer and its synchronization. * If this is not defined, use mmap and flock. * * define HAVE_MSEM Has OSF/1 style memory semaphores. * Use instead of SysV semaphores or flock * for shared memory synchronisation. * * define HAVE_LDSTUB Has SPARC ldstub atomic instruction. * May be used instead of system V semaphores or flock * for shared memory synchronisation. * * define HAVE_XCHG Has i386 xchg atomic instruction. * May be used instead of system V semaphores or flock * for shared memory synchronisation. * * define HAVE_FLOCK Use flock for synchronization on logfiles. * If this is not defined use lockf. * * define HAVE_FCHDIR The fchdir system call may be used * to change the current directory and back. * Else remember the pathname and use chdir. * * define HAVE_STATVFS The statvfs and fstatvfs calls are available. * Else get filesystem statistics with * statfs or getmnt (on ultrix). * * define HAVE_QUOTA The quota or quotactl system calls are available. * * define HAVE_YP To use yellow pages. * * define HAVE_SHADOW To use shadow password file. * * define HAVE_SETREUID have BSD setreuid() * define HAVE_SETRESUID have HPUX only ??? setresuid() * define HAVE_SETEUID have SVr4 seteuid() * * define HAVE_LCHOWN Need to use lchown() instead of chown() on symlinks. * * define HAVE_PROCFS SVr4 style procfs is available. * * define HAVE_PROCFS2 SVr4.2 (SMP) style procfs is available. * * define HAVE_SIGINFO Use waitid and the siginfo_t structure for waiting * for child processes. * Else use wait3 and union wait. * * define HAVE_WAIT3 Have wait3. * * define HAVE_WAITPID Use waitpid and no resource usage instead of wait3. * * define HAVE_UNION_WAIT Have union wait in wait.h * * define HAVE_GETHOSTNAME to use gethostname() * * define HAVE_STREAMS Use streams networking calls. Else use sockets. * * define HAVE_STRPTYS Use SVr4 style streams pseudo ttys. * * define HAVE_POLL Use the poll system call to wait for I/O. * Else use select. * * define HAVE_SELECT Use the select system call to wait for I/O. * * define HAVE_TIRPC The remote procedure call library is of the * transport independent flavour. * * define GID_T The type to use for the getgroups() array. * This should be gid_t, but some BSD based systems * must have int there. * * * 4) Specials for libschily * * define HAVE_SCANSTACK Scanning of the stack is implemented for this * architecture: * getfp() * and the derived functions: * handlecond(), raisecond() * are working. * * XXX It is most likely that getfp() does not really work correctly * XXX if getav0() is not working. * XXX For this reason, HAVE_GETAV0 is not used anymore. * XXX Instead avoffset.h is included and the existence of * XXX AV_OFFSET and FP_INDIR is checked instead. * * define HAVE_GETAV0 Scanning of stack and locating the arg vector * is implemented for this architecture: * getav0() * is working. * get_progname() in saveargs.c will work in the main * thread without a prior call to save_args(). * */ #if defined(sun) || defined(__sun) || defined(__sun__) # ifndef IS_SUN # define IS_SUN # endif #endif #if defined(SOL2) || defined(SOL2) || \ defined(S5R4) || defined(__S5R4) || defined(SVR4) # ifndef __SVR4 # define __SVR4 # endif #endif #ifdef __SVR4 # ifndef SVR4 # define SVR4 # endif #endif /* * SunOS 4.x */ #if defined(IS_SUN) && !defined(__SVR4) /* * Sun C defines __STDC__ as zero. */ # ifdef __STDC__ # define PROTOTYPES # ifndef SABER # define HAVE_STDARG_H # define HAVE_LONGLONG # endif # endif # define HAVE_AOUT # define HAVE_STDLIB_H # define HAVE_STRING_H # define HAVE_UNISTD_H # define HAVE_FCNTL_H # define HAVE_DIRENT_H # define HAVE_SYS_DIR_H # define HAVE_TERMIOS_H # define HAVE_TERMIO_H # define HAVE_SYS_TIME_H # define HAVE_UTIMES # define HAVE_UTIME_H # define HAVE_SYS_WAIT_H # define HAVE_SYS_PARAM_H # define HAVE_SYS_UTSNAME_H # define HAVE_SYS_MTIO_H # define HAVE_MTGET_DSREG # define HAVE_MTGET_RESID # define HAVE_MTGET_FILENO # define HAVE_MTGET_BLKNO # define MAJOR_IN_SYSMACROS # define HAVE_UNION_WAIT # define HAVE_USG_STDIO # define HAVE_GETCWD # define HAVE_MLOCKALL # define HAVE_MMAP # define HAVE_SMMAP # define HAVE_USGSHM # define HAVE_USGSEM # ifdef sparc # define HAVE_LDSTUB # endif # define HAVE_FLOCK # define HAVE_FCHDIR # define HAVE_QUOTA # define HAVE_YP # define HAVE_SETREUID # define HAVE_WAIT3 # define HAVE_GETHOSTNAME # define HAVE_SELECT # define GID_T int # define USLEEPRETURN_T unsigned int # define HAVE_GETAV0 /* SunOS < 5 only runs on sparc/mc680xx */ # define HAVE_SCANSTACK /* SunOS < 5 only runs on sparc/mc680xx */ #endif /* * AIX */ #if defined(_IBMR2) || defined(_AIX) # define IS_UNIX /* ??? really ??? */ # define NO_FLOATINGPOINT /* XXX until isinf()/isnan() is solved */ # define USE_FLOATINGARGS /* Use up args from floatingpoint format */ #ifndef PROTOTYPES # define PROTOTYPES #endif # define HAVE_COFF # define HAVE_STDARG_H # define HAVE_STDLIB_H # define HAVE_STRING_H # define HAVE_LONGLONG # define HAVE_UNISTD_H # define HAVE_FCNTL_H # define HAVE_DIRENT_H # define HAVE_TERMIOS_H # define HAVE_TERMIO_H # define HAVE_SYS_TIME_H # define HAVE_UTIMES # define HAVE_UTIME_H # define HAVE_SYS_WAIT_H # define HAVE_SYS_PARAM_H # define HAVE_SYS_UTSNAME_H # define MAJOR_IN_SYSMACROS /*# define HAVE_USG_STDIO*/ # define HAVE_GETCWD # define HAVE_STRERROR # define HAVE_MEMMOVE # define HAVE_MMAP # define HAVE_SMMAP # define HAVE_USGSHM # define HAVE_USGSEM # define HAVE_MSEM # define HAVE_FLOCK # define HAVE_QUOTA # define HAVE_YP # define HAVE_WAIT3 # define HAVE_WAITPID # define HAVE_GETHOSTNAME # define HAVE_STREAMS # define HAVE_POLL # define HAVE_SELECT # define GID_T gid_t # define USLEEPRETURN_T int #endif /* * Silicon Graphics (must be before SVR4) */ #if defined(sgi) || defined(__sgi) # define __NOT_SVR4__ /* Not a real SVR4 implementation */ # define PROTOTYPES # define HAVE_ELF # define HAVE_COFF # define HAVE_STDARG_H # define HAVE_LONGLONG # define HAVE_UNISTD_H # define HAVE_FCNTL_H # define HAVE_DIRENT_H # define HAVE_TERMIOS_H # define HAVE_TERMIO_H # define HAVE_SYS_TIME_H # define HAVE_UTIMES # define HAVE_UTIME_H # define HAVE_WAIT_H # define HAVE_SYS_WAIT_H # define HAVE_SYS_PARAM_H # define HAVE_SYS_SYSTEMINFO_H # define HAVE_SYS_UTSNAME_H # define HAVE_SYS_MTIO_H # define HAVE_MTGET_DSREG # define HAVE_MTGET_RESID # define HAVE_MTGET_FILENO # define HAVE_MTGET_BLKNO # define MAJOR_IN_MKDEV # define HAVE_USG_STDIO # define HAVE_GETCWD # define HAVE_STRERROR # define HAVE_MEMMOVE # define HAVE_MMAP # define HAVE_SMMAP # define HAVE_USGSHM # define HAVE_USGSEM # define HAVE_FLOCK # define HAVE_FCHDIR # define HAVE_STATVFS # define HAVE_QUOTA # define HAVE_YP # define HAVE_SHADOW # define HAVE_PROCFS # define HAVE_SIGINFO # define HAVE_WAIT3 # define HAVE_WAITPID # define HAVE_GETHOSTNAME # define HAVE_STREAMS # define HAVE_STRPTYS # define HAVE_POLL # define HAVE_SELECT # define HAVE_STRPTYS # define GID_T gid_t /*# define USLEEPRETURN_T unsigned int*/ # define vfork fork #endif #if defined(mips) && !(defined(ultrix) || defined(sony) || defined(sgi)) # define HAVE_COFF # define HAVE_UNISTD_H # define HAVE_USGSHM # define HAVE_USGSEM # define HAVE_FLOCK # define HAVE_YP # define GID_T int # define USLEEPRETURN_T unsigned int #endif #if defined(sony) # ifdef mips # define HAVE_COFF # else # define HAVE_AOUT # endif # define HAVE_USGSHM # define HAVE_USGSEM # define HAVE_FLOCK # define HAVE_QUOTA # define HAVE_YP # define GID_T int # define USLEEPRETURN_T unsigned int # ifndef SEEK_SET # define SEEK_SET 0 /* Set file pointer to "offset" */ # define SEEK_CUR 1 /* Set file pointer to current plus "offset" */ # define SEEK_END 2 /* Set file pointer to EOF plus "offset" */ # endif #endif /* * Digital UNIX (OSF1) */ #if defined(__osf__) # define PROTOTYPES # define HAVE_OSDEF /* prevent later definitions to overwrite current */ /*# define __NOT_SVR4__*/ /* Not a real SVR4 implementation */ /*# define HAVE_ELF*/ # define HAVE_COFF /*# define HAVE_AOUT*/ # define HAVE_STDARG_H /*# define HAVE_VA_COPY*/ # define HAVE_STDLIB_H # define HAVE_STRING_H # define HAVE_STDC_HEADERS # define STDC_HEADERS /* GNU name */ # define HAVE_LONGLONG # define HAVE_UNISTD_H # define HAVE_FCNTL_H # define HAVE_DIRENT_H # define HAVE_SYS_DIR_H /*# define HAVE_NDIR_H*/ /*# define HAVE_SYS_NDIR_H*/ # define HAVE_TERMIOS_H # define HAVE_TERMIO_H # define HAVE_SYS_TIME_H # define HAVE_UTIMES # define HAVE_UTIME_H # define HAVE_WAIT_H # define HAVE_SYS_WAIT_H # define HAVE_SYS_PARAM_H # define HAVE_SYS_SYSTEMINFO_H # define HAVE_SYS_UTSNAME_H # define HAVE_SYS_PRIOCNTL_H # define HAVE_SYS_RTPRIOCNTL_H # define HAVE_SYS_MTIO_H # define HAVE_MTGET_DSREG # define HAVE_MTGET_RESID # define HAVE_MTGET_FILENO # define HAVE_MTGET_BLKNO /*# define MAJOR_IN_MKDEV*/ # define MAJOR_IN_SYSMACROS # define HAVE_USG_STDIO /*# define HAVE_DTOA*/ # define HAVE_GETCWD # define HAVE_STRERROR # define HAVE_MEMMOVE # define HAVE_MLOCKALL # define HAVE_MMAP # define HAVE_SMMAP # define HAVE_USGSHM # define HAVE_USGSEM # define HAVE_MSEM /*# define HAVE_LDSTUB*/ /*# define HAVE_XCHG*/ # define HAVE_FLOCK # define HAVE_FCHDIR # define HAVE_STATVFS # define HAVE_QUOTA # define HAVE_YP /*# define HAVE_SHADOW*/ /* No, but C2 */ # define HAVE_SETREUID /*# define HAVE_SETRESUID*/ # define HAVE_SETEUID # define HAVE_LCHOWN # define HAVE_PROCFS /*# define HAVE_PROCFS2*/ /* No */ # define HAVE_SIGINFO # define HAVE_WAIT3 # define HAVE_WAITPID # define HAVE_UNION_WAIT # define HAVE_GETHOSTNAME # define HAVE_STREAMS # define HAVE_STRPTYS # define HAVE_POLL # define HAVE_SELECT /* XXX needs sys/select.h */ /*# define HAVE_TIRPC*/ # define GID_T gid_t # define USLEEPRETURN_T int /*# define USLEEPRETURN_T void*/ /*# define USLEEPISVOID*/ /*# define HAVE_GETAV0*/ /*# define HAVE_SCANSTACK*/ #endif #if defined(ultrix) # ifdef mips # define HAVE_COFF # else # define HAVE_AOUT # endif # define HAVE_STDLIB_H # define HAVE_UNISTD_H # define HAVE_SYS_DIR_H # define HAVE_TERMIOS_H # define HAVE_UTIME_H # define HAVE_USGSHM # define HAVE_USGSEM # define HAVE_FLOCK # define HAVE_QUOTA # define HAVE_YP # define GID_T int # define USLEEPRETURN_T unsigned int #endif /* * HP/UX */ #if defined(__hpux) || defined(hpux) /*# define PROTOTYPES*/ # define HAVE_AOUT # define HAVE_STDARG_H # define HAVE_UNISTD_H # define HAVE_FCNTL_H # define HAVE_DIRENT_H # define HAVE_TERMIOS_H # define HAVE_TERMIO_H # define HAVE_SYS_TIME_H # define HAVE_UTIME_H # define HAVE_SYS_WAIT_H # define HAVE_SYS_PARAM_H # define HAVE_SYS_UTSNAME_H # define HAVE_SYS_MTIO_H # define MAJOR_IN_SYSMACROS # define HAVE_GETCWD # define HAVE_STRERROR # define HAVE_MEMMOVE # define HAVE_MMAP # define HAVE_SMMAP # define HAVE_USGSHM # define HAVE_USGSEM #if 0 # define HAVE_MSEM # endif # define HAVE_FCHDIR # define HAVE_QUOTA # define HAVE_YP # define HAVE_SETRESUID # define HAVE_WAIT3 # define HAVE_WAITPID # define HAVE_GETHOSTNAME # define HAVE_STREAMS # define HAVE_STRPTYS # define HAVE_POLL # define HAVE_SELECT # define GID_T gid_t /*# define USLEEPRETURN_T unsigned int*/ #endif /* * Data General */ #if defined(__DGUX__) # define PROTOTYPES # define HAVE_ELF # define HAVE_STDARG_H # define HAVE_UNISTD_H # define HAVE_DIRENT_H # define HAVE_TERMIOS_H # define HAVE_SYS_TIME_H # define HAVE_UTIMES # define HAVE_UTIME_H # define HAVE_SYS_PARAM_H # undef HAVE_MTGET_DSREG # undef HAVE_MTGET_RESID # undef HAVE_MTGET_FILENO # undef HAVE_MTGET_BLKNO # define mt_type mt_model # define mt_dsreg mt_status1 # define mt_erreg mt_status2 # define HAVE_GETCWD # define HAVE_STRERROR # define HAVE_MEMMOVE # define HAVE_USGSEM # if defined(__i386_) || defined(i386) # define HAVE_XCHG # endif /* * DGUX hides its flock as dg_flock. */ # define HAVE_FLOCK # define flock dg_flock # define HAVE_FCHDIR # define HAVE_STATVFS # undef HAVE_QUOTA # define HAVE_YP # define HAVE_SHADOW # undef HAVE_PROCFS # undef HAVE_PROCFS2 # define HAVE_WAIT3 # define HAVE_UNION_WAIT /*# define HAVE_GETHOSTNAME*/ # define HAVE_STREAMS # define HAVE_STRPTYS # define HAVE_POLL # define HAVE_SELECT # undef HAVE_TIRPC # define GID_T gid_t # define USLEEPRETURN_T unsigned int /* * Use the BSD style wait on DGUX to get the resource usages of child * processes. */ # define _BSD_WAIT_FLAVOR /*# define HAVE_GETAV0*/ # ifdef i386 # define HAVE_SCANSTACK # endif #endif /* * Linux */ #if defined(__linux__) || defined(__linux) # define PROTOTYPES # ifdef __ELF__ # define HAVE_ELF # else # define HAVE_AOUT # endif # define HAVE_STDARG_H # define HAVE_STDLIB_H # define HAVE_STRING_H # define HAVE_STDC_HEADERS # define STDC_HEADERS /* GNU name */ # define HAVE_LONGLONG # define HAVE_UNISTD_H # define HAVE_FCNTL_H # define HAVE_DIRENT_H # define HAVE_TERMIOS_H # define HAVE_TERMIO_H # define HAVE_SYS_TIME_H # define HAVE_UTIMES # define HAVE_UTIME_H /*# define HAVE_WAIT_H*/ # define HAVE_SYS_WAIT_H # define HAVE_SYS_PARAM_H # define HAVE_SYS_UTSNAME_H # define HAVE_SYS_MTIO_H # define HAVE_MTGET_DSREG # define HAVE_MTGET_RESID # define HAVE_MTGET_FILENO # define HAVE_MTGET_BLKNO # define MAJOR_IN_SYSMACROS # define HAVE_GETCWD # define HAVE_STRERROR # define HAVE_MEMMOVE # define HAVE_MLOCKALL # define HAVE_MMAP /*# define HAVE_SMMAP*/ # define HAVE_USGSHM # define HAVE_USGSEM # define HAVE_FLOCK # define HAVE_FCHDIR # define HAVE_STATVFS # define HAVE_QUOTA # define HAVE_YP # define HAVE_SETREUID /* >= Linux 1.1.37 */ # define HAVE_SETEUID /*# define HAVE_PROCFS*/ /* ??? */ /*# define HAVE_PROCFS2*/ # define HAVE_WAIT3 # define HAVE_WAITPID # define HAVE_GETHOSTNAME # define HAVE_SELECT # define GID_T gid_t # define USLEEPRETURN_T void # define USLEEPISVOID /*# define HAVE_GETAV0*/ # define HAVE_SCANSTACK #endif #if defined(OLD__bsdi__) # define HAVE_MSEM /* ??? */ # define F_ULOCK 0 /* Unlock a previously locked region */ # define F_LOCK 1 /* Lock a region for exclusive use */ # define F_TLOCK 2 /* Test and lock a region for exclusive use */ # define F_TEST 3 /* Test a region for other processes locks */ #endif /* * Prototype for FreeBSD / NetBSD / OpenBSD / BSD/OS */ #if defined(__FreeBSD__) || defined(__NetBSD__) || defined(__OpenBSD__) || defined(__bsdi__) # define PROTOTYPES # define HAVE_AOUT # define HAVE_STDARG_H # define HAVE_STDLIB_H # define HAVE_STRING_H # define HAVE_STDC_HEADERS # define STDC_HEADERS /* GNU name */ # define HAVE_LONGLONG # define HAVE_UNISTD_H # define HAVE_FCNTL_H # define HAVE_DIRENT_H # define HAVE_TERMIOS_H # define HAVE_SYS_TIME_H # define HAVE_UTIMES # define HAVE_UTIME_H # define HAVE_SYS_WAIT_H # define HAVE_SYS_PARAM_H # define HAVE_SYS_UTSNAME_H # define HAVE_SYS_MTIO_H # define HAVE_MTGET_DSREG # define HAVE_MTGET_RESID # define HAVE_MTGET_FILENO # define HAVE_MTGET_BLKNO /*# define HAVE_USG_STDIO*/ # define HAVE_DTOA # define HAVE_GETCWD # define HAVE_STRERROR # define HAVE_MEMMOVE # define HAVE_MMAP # define HAVE_SMMAP # define HAVE_USGSHM # define HAVE_USGSEM # ifdef sparc # define HAVE_LDSTUB # endif # ifdef i386 # define HAVE_XCHG # endif # define HAVE_FLOCK # define HAVE_FCHDIR # define HAVE_QUOTA # define HAVE_YP # define HAVE_SETREUID /*# define HAVE_SETRESUID*/ # define HAVE_SETEUID /*# define HAVE_LCHOWN*/ # define HAVE_WAIT3 # define HAVE_WAITPID # define HAVE_UNION_WAIT # define HAVE_GETHOSTNAME # define HAVE_SELECT # define GID_T gid_t /*# define USLEEPRETURN_T unsigned int*/ # define USLEEPRETURN_T void # define USLEEPISVOID /*# define HAVE_GETAV0*/ /*# define HAVE_SCANSTACK*/ #endif /* * SysVr4 */ #if defined(__SVR4) && !defined(__NOT_SVR4__) # define PROTOTYPES # define HAVE_ELF # define HAVE_STDARG_H # if defined(IS_SUN) # define HAVE_LONGLONG # define HAVE_UTIMES # define HAVE_QUOTA # define HAVE_GETAV0 /* XXX what about PPC ??? */ # define HAVE_SCANSTACK /* XXX what about PPC ??? */ # define HAVE_STRSIGNAL # define HAVE_STR2SIG # define HAVE_SIG2STR # endif # define HAVE_UNISTD_H # define HAVE_FCNTL_H # define HAVE_DIRENT_H # define HAVE_TERMIOS_H # define HAVE_TERMIO_H # define HAVE_SYS_TIME_H # define HAVE_UTIME_H # define HAVE_WAIT_H # define HAVE_SYS_WAIT_H # define HAVE_SYS_PARAM_H # define HAVE_SYS_SYSTEMINFO_H # define HAVE_SYS_UTSNAME_H # define HAVE_SYS_PRIOCNTL_H # define HAVE_SYS_RTPRIOCNTL_H # define HAVE_SYS_MTIO_H # define HAVE_MTGET_DSREG # define HAVE_MTGET_RESID # define HAVE_MTGET_FILENO # define HAVE_MTGET_BLKNO # define MAJOR_IN_MKDEV # define HAVE_USG_STDIO # define HAVE_GETCWD # define HAVE_STRERROR # define HAVE_MEMMOVE # define HAVE_MLOCKALL # define HAVE_MMAP # define HAVE_SMMAP # define HAVE_USGSHM # define HAVE_USGSEM # ifdef sparc # define HAVE_LDSTUB # endif # ifdef i386 # define HAVE_XCHG # endif # define HAVE_FCHDIR # define HAVE_STATVFS # define HAVE_YP # define HAVE_SHADOW # define HAVE_SETEUID # define HAVE_LCHOWN # define HAVE_PROCFS # if (defined(i386) && !defined(IS_SUN)) # define HAVE_PROCFS2 # define HAVE_QUOTA # endif # define HAVE_SIGINFO # define HAVE_WAITPID # define HAVE_STREAMS # define HAVE_STRPTYS # define HAVE_POLL # define HAVE_SELECT # define HAVE_TIRPC # define GID_T gid_t # define USLEEPRETURN_T unsigned int #endif /* * Apple Rhapsody */ #if defined(__NeXT__) && defined(__TARGET_OSNAME) && __TARGET_OSNAME == rhapsody # define HAVE_OSDEF /* prevent later definitions to overwrite current */ # define PROTOTYPES /*# define HAVE_ELF*/ /*# define HAVE_COFF*/ /*# define HAVE_AOUT*/ # define HAVE_STDARG_H # define HAVE_STDLIB_H # define HAVE_STRING_H # define HAVE_STDC_HEADERS # define STDC_HEADERS /* GNU name */ # define HAVE_LONGLONG # define HAVE_UNISTD_H # define HAVE_FCNTL_H # define HAVE_DIRENT_H # define HAVE_SYS_DIR_H /*# define HAVE_NDIR_H*/ /*# define HAVE_SYS_NDIR_H*/ # define HAVE_TERMIOS_H /*# define HAVE_TERMIO_H*/ # define HAVE_SYS_TIME_H # define HAVE_UTIMES # define HAVE_UTIME_H /*# define HAVE_WAIT_H*/ # define HAVE_SYS_WAIT_H # define HAVE_SYS_PARAM_H /*# define HAVE_SYS_SYSTEMINFO_H*/ # define HAVE_SYS_UTSNAME_H /*# define HAVE_SYS_PRIOCNTL_H*/ /*# define HAVE_SYS_RTPRIOCNTL_H*/ # define HAVE_SYS_MTIO_H # define HAVE_MTGET_DSREG # define HAVE_MTGET_RESID # define HAVE_MTGET_FILENO # define HAVE_MTGET_BLKNO /*# define MAJOR_IN_MKDEV*/ /*# define MAJOR_IN_SYSMACROS*/ /*# define HAVE_USG_STDIO*/ # define HAVE_DTOA # define HAVE_GETCWD # define HAVE_STRERROR # define HAVE_MEMMOVE # define HAVE_MMAP # define HAVE_SMMAP # define HAVE_USGSHM # define HAVE_USGSEM /*# define HAVE_MSEM*/ /*# define HAVE_LDSTUB*/ # if defined(__i386_) || defined(i386) # define HAVE_XCHG # endif # define HAVE_FLOCK /*# define HAVE_FCHDIR*/ /*# define HAVE_STATVFS*/ # define HAVE_QUOTA # define HAVE_YP /*# define HAVE_SHADOW*/ # define HAVE_SETREUID /*# define HAVE_SETRESUID*/ # define HAVE_SETEUID /*# define HAVE_LCHOWN*/ /*# define HAVE_PROCFS*/ /*# define HAVE_PROCFS2*/ /*# define HAVE_SIGINFO*/ # define HAVE_WAIT3 /*# define HAVE_WAITPID*/ # define HAVE_UNION_WAIT # define HAVE_GETHOSTNAME /*# define HAVE_STREAMS*/ /*# define HAVE_STRPTYS*/ # define HAVE_POLL # define HAVE_SELECT /*# define HAVE_TIRPC*/ /*# define GID_T gid_t*/ /*# define USLEEPRETURN_T unsigned int*/ /*# define USLEEPRETURN_T void*/ # define USLEEPISVOID /*# define HAVE_GETAV0*/ /*# define HAVE_SCANSTACK*/ #endif /* * NextStep */ #if defined(__NeXT__) && !defined(HAVE_OSDEF) #define printf Xprintf #define fprintf Xfprintf #define sprintf Xsprintf #ifdef XXX # define __NOT_SVR4__ /* Not a real SVR4 implementation */ #endif # define PROTOTYPES /*# define HAVE_ELF*/ /*# define HAVE_COFF*/ /*# define HAVE_AOUT*/ # define HAVE_STDARG_H # define HAVE_STDLIB_H # define HAVE_STRING_H # define HAVE_STDC_HEADERS # define STDC_HEADERS /* GNU name */ # define HAVE_LONGLONG # define HAVE_UNISTD_H # define HAVE_FCNTL_H /*# define HAVE_DIRENT_H XXX not posix compliant */ # define HAVE_SYS_DIR_H /*# define HAVE_NDIR_H*/ /*# define HAVE_SYS_NDIR_H*/ /*# define HAVE_TERMIOS_H XXX need buggy -lposix */ /*# define HAVE_TERMIO_H*/ # define HAVE_SYS_TIME_H # define HAVE_UTIMES # define HAVE_UTIME_H /*# define HAVE_WAIT_H*/ # define HAVE_SYS_WAIT_H # define HAVE_SYS_PARAM_H /*# define HAVE_SYS_SYSTEMINFO_H*/ /*# define HAVE_SYS_UTSNAME_H XXX needs buggy -lposix */ /*# define HAVE_SYS_PRIOCNTL_H*/ /*# define HAVE_SYS_RTPRIOCNTL_H*/ # define HAVE_SYS_MTIO_H # define HAVE_MTGET_DSREG # define HAVE_MTGET_RESID # define HAVE_MTGET_FILENO # define HAVE_MTGET_BLKNO /*# define MAJOR_IN_MKDEV*/ /*# define MAJOR_IN_SYSMACROS*/ /*# define HAVE_USG_STDIO XXX different _flsbuf() */ # define HAVE_STRERROR /*# define HAVE_MEMMOVE*/ /*# define HAVE_MMAP*/ /*# define HAVE_SMMAP*/ /*# define HAVE_USGSHM*/ /*# define HAVE_USGSEM*/ /*# define HAVE_MSEM*/ /*# define HAVE_LDSTUB*/ /*# define HAVE_XCHG*/ # define HAVE_FLOCK /*# define HAVE_FCHDIR*/ /*# define HAVE_STATVFS*/ /*# define HAVE_QUOTA*/ /*# define HAVE_YP*/ /*# define HAVE_SHADOW*/ # define HAVE_SETREUID /*# define HAVE_SETRESUID*/ # define HAVE_SETEUID /*# define HAVE_LCHOWN*/ /*# define HAVE_PROCFS*/ /*# define HAVE_PROCFS2*/ /*# define HAVE_SIGINFO*/ # define HAVE_WAIT3 /*# define HAVE_WAITPID*/ # define HAVE_UNION_WAIT # define HAVE_GETHOSTNAME /*# define HAVE_STREAMS*/ /*# define HAVE_STRPTYS*/ /*# define HAVE_POLL*/ # define HAVE_SELECT /*# define HAVE_TIRPC*/ # define GID_T gid_t # define USLEEPRETURN_T int /*# define USLEEPRETURN_T void*/ /*# define USLEEPISVOID*/ /*# define HAVE_GETAV0*/ /*# define HAVE_SCANSTACK*/ #endif /* * Cygwin 32 (NT) */ #if defined(__CYGWIN32__) # define PROTOTYPES # define HAVE_OSDEF /* prevent later definitions to overwrite current */ # define __NOT_SVR4__ /* Not a real SVR4 implementation */ /*# define HAVE_ELF*/ /*# define HAVE_COFF*/ # define HAVE_AOUT # define HAVE_STDARG_H /*# define HAVE_VA_COPY*/ # define HAVE_STDLIB_H # define HAVE_STRING_H # define HAVE_STDC_HEADERS # define STDC_HEADERS /* GNU name */ # define HAVE_LONGLONG # define HAVE_UNISTD_H # define HAVE_FCNTL_H # define HAVE_DIRENT_H /*# define HAVE_SYS_DIR_H*/ /*# define HAVE_NDIR_H*/ /*# define HAVE_SYS_NDIR_H*/ # define HAVE_TERMIOS_H # define HAVE_TERMIO_H # define HAVE_SYS_TIME_H /*# define HAVE_UTIMES*/ # define HAVE_UTIME_H /*# define HAVE_WAIT_H*/ # define HAVE_SYS_WAIT_H # define HAVE_SYS_PARAM_H /*# define HAVE_SYS_SYSTEMINFO_H*/ # define HAVE_SYS_UTSNAME_H /*# define HAVE_SYS_PRIOCNTL_H*/ /*# define HAVE_SYS_RTPRIOCNTL_H*/ /*# define HAVE_SYS_MTIO_H*/ /*# define HAVE_MTGET_DSREG*/ /*# define HAVE_MTGET_RESID*/ /*# define HAVE_MTGET_FILENO*/ /*# define HAVE_MTGET_BLKNO*/ /*# define MAJOR_IN_MKDEV*/ /*# define MAJOR_IN_SYSMACROS*/ /*# define HAVE_USG_STDIO*/ /*# define HAVE_DTOA*/ /* XXX eigentlich doch da */ # define HAVE_GETCWD # define HAVE_STRERROR # define HAVE_MEMMOVE # define HAVE_MMAP # define HAVE_SMMAP /*# define HAVE_USGSHM*/ /*# define HAVE_USGSEM*/ /*# define HAVE_MSEM*/ /*# define HAVE_LDSTUB*/ # if defined(__i386_) || defined(i386) # define HAVE_XCHG # endif /*# define HAVE_FLOCK*/ /*# define HAVE_FCHDIR*/ /*# define HAVE_STATVFS*/ /*# define HAVE_QUOTA*/ /*# define HAVE_YP*/ /*# define HAVE_SHADOW*/ /*# define HAVE_SETREUID*/ /*# define HAVE_SETRESUID*/ /*# define HAVE_SETEUID*/ /*# define HAVE_LCHOWN*/ /*# define HAVE_PROCFS*/ /*# define HAVE_PROCFS2*/ /*# define HAVE_SIGINFO*/ # define HAVE_WAIT3 # define HAVE_WAITPID # define HAVE_UNION_WAIT # define HAVE_GETHOSTNAME /*# define HAVE_STREAMS*/ /*# define HAVE_STRPTYS*/ /*# define HAVE_POLL*/ # define HAVE_SELECT /*# define HAVE_TIRPC*/ # define GID_T gid_t # define USLEEPRETURN_T unsigned int /*# define USLEEPRETURN_T void*/ /*# define USLEEPISVOID*/ /*# define HAVE_GETAV0*/ /*# define HAVE_SCANSTACK*/ #endif /* __CYGWIN32__ */ #if defined(VMS) # define PROTOTYPES # define HAVE_OSDEF /* prevent later definitions to overwrite current */ # define __NOT_SVR4__ /* Not a real SVR4 implementation */ # define HAVE_UNISTD_H /* # define HAVE_SYS_TIME_H */ # define HAVE_FCNTL_H # define HAVE_USLEEP # define HAVE_INTTYPES_H # include # define HOST_CPU "Alpha/VAX" # define HOST_VENDOR "CPQ" # define HOST_OS "VMS/OpenVMS" # define RETSIGTYPE void /*# define HAVE_ELF */ /*# define HAVE_COFF */ /*# define HAVE_AOUT */ /*# define HAVE_STDARG_H */ /*# define HAVE_VA_COPY */ /*# define HAVE_STDLIB_H */ /*# define HAVE_STRING_H */ /*# define HAVE_STDC_HEADERS */ /*# define STDC_HEADERS */ /*# define HAVE_LONGLONG */ /*# define HAVE_UNISTD_H */ /*# define HAVE_FCNTL_H */ /*# define HAVE_DIRENT_H */ /*# define HAVE_SYS_DIR_H */ /*# define HAVE_NDIR_H */ /*# define HAVE_SYS_NDIR_H */ /*# define HAVE_TERMIOS_H */ /*# define HAVE_TERMIO_H */ /*# define HAVE_SYS_TIME_H */ /*# define HAVE_UTIMES */ /*# define HAVE_UTIME_H */ /*# define HAVE_WAIT_H */ /*# define HAVE_SYS_WAIT_H */ /*# define HAVE_SYS_SYSTEMINFO_H */ /*# define HAVE_SYS_UTSNAME_H */ /*# define HAVE_SYS_PRIOCNTL_H */ /*# define HAVE_SYS_RTPRIOCNTL_H */ /*# define HAVE_SYS_MTIO_H */ /*# define HAVE_MTGET_DSREG */ /*# define HAVE_MTGET_RESID */ /*# define HAVE_MTGET_FILENO */ /*# define HAVE_MTGET_BLKNO */ /*# define MAJOR_IN_MKDEV */ /*# define MAJOR_IN_SYSMACROS */ /*# define HAVE_USG_STDIO */ /*# define HAVE_DTOA */ /*# define HAVE_STRERROR */ # define HAVE_MEMMOVE /*# define HAVE_MMAP */ /*# define HAVE_SMMAP */ /*# define HAVE_USGSHM */ /*# define HAVE_USGSEM */ /*# define HAVE_MSEM */ /*# define HAVE_LDSTUB */ /*# define HAVE_XCHG */ /*# define HAVE_FLOCK */ /*# define HAVE_FCHDIR */ /*# define HAVE_STATVFS */ /*# define HAVE_QUOTA */ /*# define HAVE_YP */ /*# define HAVE_SHADOW */ /*# define HAVE_SETREUID */ /*# define HAVE_SETRESUID */ /*# define HAVE_SETEUID */ /*# define HAVE_LCHOWN */ /*# define HAVE_PROCFS */ /*# define HAVE_PROCFS2 */ /*# define HAVE_SIGINFO */ /*# define HAVE_WAIT3 */ /*# define HAVE_WAITPID */ /*# define HAVE_UNION_WAIT */ # define HAVE_GETHOSTNAME /*# define HAVE_STREAMS */ /*# define HAVE_STRPTYS */ /*# define HAVE_POLL */ # define HAVE_SELECT /*# define HAVE_TIRPC */ /*# define GID_T gid_t */ # define USLEEPRETURN_T uint /*# define USLEEPRETURN_T void */ /*# define USLEEPISVOID */ /*# define HAVE_GETAV0 */ /*# define HAVE_SCANSTACK */ #endif /* * Prototype for new systems */ #if defined(__NEW_SYSTEM_TO_DEFINE__) # define PROTOTYPES # define HAVE_OSDEF /* prevent later definitions to overwrite current */ # define __NOT_SVR4__ /* Not a real SVR4 implementation */ # define HAVE_ELF # define HAVE_COFF # define HAVE_AOUT # define HAVE_STDARG_H # define HAVE_VA_COPY # define HAVE__VA_COPY # define HAVE_STDLIB_H # define HAVE_STRING_H # define HAVE_STRINGS_H # define HAVE_STDC_HEADERS # define STDC_HEADERS /* GNU name */ # define HAVE_LONGLONG # define HAVE_SIZE_T # define NO_SIZE_T # define HAVE_UNISTD_H # define HAVE_FCNTL_H # define HAVE_DIRENT_H # define HAVE_SYS_DIR_H # define HAVE_NDIR_H # define HAVE_MALLOC_H # define HAVE_SYS_NDIR_H # define HAVE_TERMIOS_H # define HAVE_TERMIO_H # define HAVE_SYS_TIME_H # define HAVE_UTIMES # define HAVE_UTIME_H # define HAVE_WAIT_H # define HAVE_SYS_WAIT_H # define HAVE_SYS_PARAM_H # define HAVE_SYS_SYSTEMINFO_H # define HAVE_SYS_UTSNAME_H # define HAVE_SYS_PRIOCNTL_H # define HAVE_SYS_RTPRIOCNTL_H # define HAVE_SYS_MTIO_H # define HAVE_MTGET_DSREG # define HAVE_MTGET_RESID # define HAVE_MTGET_FILENO # define HAVE_MTGET_BLKNO # define MAJOR_IN_MKDEV # define MAJOR_IN_SYSMACROS # define HAVE_USG_STDIO # define HAVE_BRK # define HAVE_SBRK # define HAVE_DTOA # define HAVE_GETCWD # define HAVE_STRERROR # define HAVE_MEMMOVE # define HAVE_MLOCKALL # define HAVE_MMAP # define HAVE_SMMAP # define HAVE_USGSHM # define HAVE_USGSEM # define HAVE_MSEM # define HAVE_LDSTUB # define HAVE_XCHG # define HAVE_FLOCK # define HAVE_FCHDIR # define HAVE_STATVFS # define HAVE_QUOTA # define HAVE_YP # define HAVE_SHADOW # define HAVE_SETREUID # define HAVE_SETRESUID # define HAVE_SETEUID # define HAVE_LCHOWN # define HAVE_PROCFS # define HAVE_PROCFS2 # define HAVE_SIGINFO # define HAVE_WAIT3 # define HAVE_WAITPID # define HAVE_UNION_WAIT # define HAVE_GETHOSTNAME # define HAVE_STREAMS # define HAVE_STRPTYS # define HAVE_POLL # define HAVE_SELECT # define HAVE_TIRPC # define GID_T gid_t # define USLEEPRETURN_T unsigned int # define USLEEPRETURN_T void # define USLEEPISVOID # define HAVE_GETAV0 # define HAVE_SCANSTACK #endif /* __NEW_SYSTEM_TO_DEFINE__ */ #ifdef __cplusplus } #endif #endif /* _XMCONFIG_H */