├── LICENSE ├── Makefile ├── README ├── README.md ├── doc ├── Example.txt └── scsi-generic_long.txt ├── include └── sg_err.h ├── setblocksize.c └── sg_err.c /LICENSE: -------------------------------------------------------------------------------- 1 | GNU GENERAL PUBLIC LICENSE 2 | 3 | Version 2, June 1991 4 | 5 | Copyright (C) 1989, 1991 Free Software Foundation, Inc. 59 Temple 6 | Place - Suite 330, Boston, MA 02111-1307, USA 7 | 8 | Everyone is permitted to copy and distribute verbatim copies of this 9 | license document, but changing it is not allowed. 10 | 11 | Preamble 12 | 13 | The licenses for most software are designed to take away your freedom 14 | to share and change it. By contrast, the GNU General Public License is 15 | intended to guarantee your freedom to share and change free 16 | software--to make sure the software is free for all its users. This 17 | General Public License applies to most of the Free Software 18 | Foundation's software and to any other program whose authors commit to 19 | using it. (Some other Free Software Foundation software is covered by 20 | the GNU Library General Public License instead.) You can apply it to 21 | your programs, too. 22 | 23 | When we speak of free software, we are referring to freedom, not 24 | price. Our General Public Licenses are designed to make sure that you 25 | have the freedom to distribute copies of free software (and charge for 26 | this service if you wish), that you receive source code or can get it 27 | if you want it, that you can change the software or use pieces of it 28 | in new free programs; and that you know you can do these things. 29 | 30 | To protect your rights, we need to make restrictions that forbid 31 | anyone to deny you these rights or to ask you to surrender the 32 | rights. These restrictions translate to certain responsibilities for 33 | you if you distribute copies of the software, or if you modify it. 34 | 35 | For example, if you distribute copies of such a program, whether 36 | gratis or for a fee, you must give the recipients all the rights that 37 | you have. You must make sure that they, too, receive or can get the 38 | source code. And you must show them these terms so they know their 39 | rights. 40 | 41 | We protect your rights with two steps: (1) copyright the software, and 42 | (2) offer you this license which gives you legal permission to copy, 43 | distribute and/or modify the software. 44 | 45 | Also, for each author's protection and ours, we want to make certain 46 | that everyone understands that there is no warranty for this free 47 | software. If the software is modified by someone else and passed on, 48 | we want its recipients to know that what they have is not the 49 | original, so that any problems introduced by others will not reflect 50 | on the original authors' reputations. 51 | 52 | Finally, any free program is threatened constantly by software 53 | patents. We wish to avoid the danger that redistributors of a free 54 | program will individually obtain patent licenses, in effect making the 55 | program proprietary. To prevent this, we have made it clear that any 56 | patent must be licensed for everyone's free use or not licensed at 57 | all. 58 | 59 | The precise terms and conditions for copying, distribution and 60 | modification follow. 61 | 62 | TERMS AND CONDITIONS FOR COPYING, DISTRIBUTION AND MODIFICATION 63 | 64 | 0. This License applies to any program or other work which contains a 65 | notice placed by the copyright holder saying it may be distributed 66 | under the terms of this General Public License. The "Program", below, 67 | refers to any such program or work, and a "work based on the Program" 68 | means either the Program or any derivative work under copyright law: 69 | that is to say, a work containing the Program or a portion of it, 70 | either verbatim or with modifications and/or translated into another 71 | language. (Hereinafter, translation is included without limitation in 72 | the term "modification".) Each licensee is addressed as "you". 73 | 74 | Activities other than copying, distribution and modification are not 75 | covered by this License; they are outside its scope. The act of 76 | running the Program is not restricted, and the output from the Program 77 | is covered only if its contents constitute a work based on the Program 78 | (independent of having been made by running the Program). Whether 79 | that is true depends on what the Program does. 80 | 81 | 1. You may copy and distribute verbatim copies of the Program's source 82 | code as you receive it, in any medium, provided that you conspicuously 83 | and appropriately publish on each copy an appropriate copyright notice 84 | and disclaimer of warranty; keep intact all the notices that refer to 85 | this License and to the absence of any warranty; and give any other 86 | recipients of the Program a copy of this License along with the 87 | Program. 88 | 89 | You may charge a fee for the physical act of transferring a copy, and 90 | you may at your option offer warranty protection in exchange for a 91 | fee. 92 | 93 | 2. You may modify your copy or copies of the Program or any portion of 94 | it, thus forming a work based on the Program, and copy and distribute 95 | such modifications or work under the terms of Section 1 above, 96 | provided that you also meet all of these conditions: 97 | 98 | a) You must cause the modified files to carry prominent notices 99 | stating that you changed the files and the date of any change. 100 | 101 | b) You must cause any work that you distribute or publish, that 102 | in whole or in part contains or is derived from the Program or 103 | any part thereof, to be licensed as a whole at no charge to all 104 | third parties under the terms of this License. 105 | 106 | c) If the modified program normally reads commands 107 | interactively when run, you must cause it, when started running 108 | for such interactive use in the most ordinary way, to print or 109 | display an announcement including an appropriate copyright 110 | notice and a notice that there is no warranty (or else, saying 111 | that you provide a warranty) and that users may redistribute 112 | the program under these conditions, and telling the user how to 113 | view a copy of this License. (Exception: if the Program itself 114 | is interactive but does not normally print such an 115 | announcement, your work based on the Program is not required to 116 | print an announcement.) 117 | 118 | These requirements apply to the modified work as a whole. If 119 | identifiable sections of that work are not derived from the Program, 120 | and can be reasonably considered independent and separate works in 121 | themselves, then this License, and its terms, do not apply to those 122 | sections when you distribute them as separate works. But when you 123 | distribute the same sections as part of a whole which is a work based 124 | on the Program, the distribution of the whole must be on the terms of 125 | this License, whose permissions for other licensees extend to the 126 | entire whole, and thus to each and every part regardless of who wrote 127 | it. 128 | 129 | Thus, it is not the intent of this section to claim rights or contest 130 | your rights to work written entirely by you; rather, the intent is to 131 | exercise the right to control the distribution of derivative or 132 | collective works based on the Program. 133 | 134 | In addition, mere aggregation of another work not based on the Program 135 | with the Program (or with a work based on the Program) on a volume of 136 | a storage or distribution medium does not bring the other work under 137 | the scope of this License. 138 | 139 | 3. You may copy and distribute the Program (or a work based on it, 140 | under Section 2) in object code or executable form under the terms of 141 | Sections 1 and 2 above provided that you also do one of the following: 142 | 143 | a) Accompany it with the complete corresponding 144 | machine-readable source code, which must be distributed under 145 | the terms of Sections 1 and 2 above on a medium customarily 146 | used for software interchange; or, 147 | 148 | b) Accompany it with a written offer, valid for at least three 149 | years, to give any third party, for a charge no more than your 150 | cost of physically performing source distribution, a complete 151 | machine-readable copy of the corresponding source code, to be 152 | distributed under the terms of Sections 1 and 2 above on a 153 | medium customarily used for software interchange; or, 154 | 155 | c) Accompany it with the information you received as to the 156 | offer to distribute corresponding source code. (This 157 | alternative is allowed only for noncommercial distribution and 158 | only if you received the program in object code or executable 159 | form with such an offer, in accord with Subsection b above.) 160 | 161 | The source code for a work means the preferred form of the work for 162 | making modifications to it. For an executable work, complete source 163 | code means all the source code for all modules it contains, plus any 164 | associated interface definition files, plus the scripts used to 165 | control compilation and installation of the executable. However, as a 166 | special exception, the source code distributed need not include 167 | anything that is normally distributed (in either source or binary 168 | form) with the major components (compiler, kernel, and so on) of the 169 | operating system on which the executable runs, unless that component 170 | itself accompanies the executable. 171 | 172 | If distribution of executable or object code is made by offering 173 | access to copy from a designated place, then offering equivalent 174 | access to copy the source code from the same place counts as 175 | distribution of the source code, even though third parties are not 176 | compelled to copy the source along with the object code. 177 | 178 | 4. You may not copy, modify, sublicense, or distribute the Program 179 | except as expressly provided under this License. Any attempt otherwise 180 | to copy, modify, sublicense or distribute the Program is void, and 181 | will automatically terminate your rights under this License. However, 182 | parties who have received copies, or rights, from you under this 183 | License will not have their licenses terminated so long as such 184 | parties remain in full compliance. 185 | 186 | 5. You are not required to accept this License, since you have not 187 | signed it. However, nothing else grants you permission to modify or 188 | distribute the Program or its derivative works. These actions are 189 | prohibited by law if you do not accept this License. Therefore, by 190 | modifying or distributing the Program (or any work based on the 191 | Program), you indicate your acceptance of this License to do so, and 192 | all its terms and conditions for copying, distributing or modifying 193 | the Program or works based on it. 194 | 195 | 6. Each time you redistribute the Program (or any work based on the 196 | Program), the recipient automatically receives a license from the 197 | original licensor to copy, distribute or modify the Program subject to 198 | these terms and conditions. You may not impose any further 199 | restrictions on the recipients' exercise of the rights granted 200 | herein. You are not responsible for enforcing compliance by third 201 | parties to this License. 202 | 203 | 7. If, as a consequence of a court judgment or allegation of patent 204 | infringement or for any other reason (not limited to patent issues), 205 | conditions are imposed on you (whether by court order, agreement or 206 | otherwise) that contradict the conditions of this License, they do not 207 | excuse you from the conditions of this License. If you cannot 208 | distribute so as to satisfy simultaneously your obligations under this 209 | License and any other pertinent obligations, then as a consequence you 210 | may not distribute the Program at all. For example, if a patent 211 | license would not permit royalty-free redistribution of the Program by 212 | all those who receive copies directly or indirectly through you, then 213 | the only way you could satisfy both it and this License would be to 214 | refrain entirely from distribution of the Program. 215 | 216 | If any portion of this section is held invalid or unenforceable under 217 | any particular circumstance, the balance of the section is intended to 218 | apply and the section as a whole is intended to apply in other 219 | circumstances. 220 | 221 | It is not the purpose of this section to induce you to infringe any 222 | patents or other property right claims or to contest validity of any 223 | such claims; this section has the sole purpose of protecting the 224 | integrity of the free software distribution system, which is 225 | implemented by public license practices. Many people have made 226 | generous contributions to the wide range of software distributed 227 | through that system in reliance on consistent application of that 228 | system; it is up to the author/donor to decide if he or she is willing 229 | to distribute software through any other system and a licensee cannot 230 | impose that choice. 231 | 232 | This section is intended to make thoroughly clear what is believed to 233 | be a consequence of the rest of this License. 234 | 235 | 8. If the distribution and/or use of the Program is restricted in 236 | certain countries either by patents or by copyrighted interfaces, the 237 | original copyright holder who places the Program under this License 238 | may add an explicit geographical distribution limitation excluding 239 | those countries, so that distribution is permitted only in or among 240 | countries not thus excluded. In such case, this License incorporates 241 | the limitation as if written in the body of this License. 242 | 243 | 9. The Free Software Foundation may publish revised and/or new 244 | versions of the General Public License from time to time. Such new 245 | versions will be similar in spirit to the present version, but may 246 | differ in detail to address new problems or concerns. 247 | 248 | Each version is given a distinguishing version number. If the Program 249 | specifies a version number of this License which applies to it and 250 | "any later version", you have the option of following the terms and 251 | conditions either of that version or of any later version published by 252 | the Free Software Foundation. If the Program does not specify a 253 | version number of this License, you may choose any version ever 254 | published by the Free Software Foundation. 255 | 256 | 10. If you wish to incorporate parts of the Program into other free 257 | programs whose distribution conditions are different, write to the 258 | author to ask for permission. For software which is copyrighted by the 259 | Free Software Foundation, write to the Free Software Foundation; we 260 | sometimes make exceptions for this. Our decision will be guided by the 261 | two goals of preserving the free status of all derivatives of our free 262 | software and of promoting the sharing and reuse of software generally. 263 | 264 | NO WARRANTY 265 | 266 | 11. BECAUSE THE PROGRAM IS LICENSED FREE OF CHARGE, THERE IS NO 267 | WARRANTY FOR THE PROGRAM, TO THE EXTENT PERMITTED BY APPLICABLE 268 | LAW. EXCEPT WHEN OTHERWISE STATED IN WRITING THE COPYRIGHT HOLDERS 269 | AND/OR OTHER PARTIES PROVIDE THE PROGRAM "AS IS" WITHOUT WARRANTY OF 270 | ANY KIND, EITHER EXPRESSED OR IMPLIED, INCLUDING, BUT NOT LIMITED TO, 271 | THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR 272 | PURPOSE. THE ENTIRE RISK AS TO THE QUALITY AND PERFORMANCE OF THE 273 | PROGRAM IS WITH YOU. SHOULD THE PROGRAM PROVE DEFECTIVE, YOU ASSUME 274 | THE COST OF ALL NECESSARY SERVICING, REPAIR OR CORRECTION. 275 | 276 | 12. IN NO EVENT UNLESS REQUIRED BY APPLICABLE LAW OR AGREED TO IN 277 | WRITING WILL ANY COPYRIGHT HOLDER, OR ANY OTHER PARTY WHO MAY MODIFY 278 | AND/OR REDISTRIBUTE THE PROGRAM AS PERMITTED ABOVE, BE LIABLE TO YOU 279 | FOR DAMAGES, INCLUDING ANY GENERAL, SPECIAL, INCIDENTAL OR 280 | CONSEQUENTIAL DAMAGES ARISING OUT OF THE USE OR INABILITY TO USE THE 281 | PROGRAM (INCLUDING BUT NOT LIMITED TO LOSS OF DATA OR DATA BEING 282 | RENDERED INACCURATE OR LOSSES SUSTAINED BY YOU OR THIRD PARTIES OR A 283 | FAILURE OF THE PROGRAM TO OPERATE WITH ANY OTHER PROGRAMS), EVEN IF 284 | SUCH HOLDER OR OTHER PARTY HAS BEEN ADVISED OF THE POSSIBILITY OF SUCH 285 | DAMAGES. 286 | -------------------------------------------------------------------------------- /Makefile: -------------------------------------------------------------------------------- 1 | # ****************************************************************************** 2 | # Header 3 | # 4 | # Project: setblocksize 5 | # This file: Makefile 6 | # 7 | # Description: Makefile to build setblocksize 8 | # 9 | # Copyright: (C) 2002 by Michael Baeuerle 10 | # License: GPL V2 or any later version 11 | # 12 | # Language: GNU make 13 | # Style rules: - 14 | # 15 | # Written for: Platform: all 16 | # OS: UNIX 17 | # Tested with: Interpreter: GNU make (Version 3.77) 18 | # Platform: IA32 (Pentium) 19 | # OS: GNU/Linux (Kernel version: 2.2.10) 20 | # Tested with: Interpreter: GNU make (Version 3.77) 21 | # Platform: IA32-SMP (2x PentiumPro) 22 | # OS: GNU/Linux (Kernel version: 2.2.17) 23 | # Tested with: Compiler: gcc (Version: 3.3.6) 24 | # Platform: IA32 (PentiumPro) 25 | # OS: GNU/Linux (Kernel version: 2.6.16.20) 26 | # Do not work: Platform: non GNU/Linux 27 | # 28 | # Changelog: 29 | # 30 | # 2002-01-16 by Michael Baeuerle 31 | # Initial version 32 | # 33 | # 2003-03-22 by Michael Baeuerle 34 | # Minor changes 35 | # 36 | # 37 | # To do: - 38 | # ****************************************************************************** 39 | 40 | 41 | # ****************************************************************************** 42 | # Makro definitions 43 | # ****************************************************************************** 44 | 45 | # Version 46 | VER = V0.2 47 | 48 | # Target names 49 | TARGET = setblocksize 50 | 51 | # Compilers 52 | C1 = gcc 53 | 54 | # Flags 55 | C1FLAGS = -I $(INCLUDE) -D_REENTRANT -Wall -pipe 56 | A1FLAGS = 57 | A2FLAGS = 58 | 59 | # Include file and library directory 60 | INCLUDE = ./include 61 | LIBDIR = ./lib 62 | 63 | 64 | # ****************************************************************************** 65 | # Main rules 66 | # ****************************************************************************** 67 | 68 | # Create binary 69 | all: $(TARGET) 70 | @echo 71 | @echo "Finished." 72 | @echo 73 | 74 | # Delete all object and binary files 75 | # (this forces a complete re-build for "make all") 76 | clean: 77 | @echo 78 | @echo "Deleting all binary object and archive files ..." 79 | -rm -f ./*.o 80 | -rm -f ./$(TARGET) 81 | -rm -f ../$(TARGET)-$(VER).tar 82 | @echo 83 | 84 | # Create archive of the sources 85 | dist: clean 86 | @echo "Creating archive of sources ..." 87 | tar -C . -cvf ../$(TARGET)-$(VER).tar ./* 88 | @echo 89 | 90 | 91 | # ****************************************************************************** 92 | # Sub rules 93 | # ****************************************************************************** 94 | 95 | $(TARGET): $(TARGET).o sg_err.o 96 | @echo 97 | @echo "Creating binary ..." 98 | $(C1) -o $(TARGET) $(TARGET).o sg_err.o 99 | 100 | $(TARGET).o: $(TARGET).c 101 | @echo 102 | @echo "Creating main object file ..." 103 | $(C1) $(C1FLAGS) -c -o $(TARGET).o $(TARGET).c 104 | 105 | sg_err.o: sg_err.c 106 | @echo 107 | @echo "Creating error handling object file ..." 108 | $(C1) $(C1FLAGS) -c -o sg_err.o sg_err.c 109 | 110 | 111 | # EOF 112 | 113 | -------------------------------------------------------------------------------- /README: -------------------------------------------------------------------------------- 1 | 2 | README for 'setblocksize' tool 3 | ------------------------------ 4 | 5 | General 6 | ------- 7 | This is a tool for adjusting the blocksize of SCSI disks. 8 | It is available under GPL. See 'LICENSE' file. 9 | 10 | I have tested it with the following disks: 11 | - Seagate Barracuda 4 (ST15150DC) 12 | - Seagate Hawk 1LP (ST31200N) 13 | 14 | Seagate told me, that all of their disks use the same scheme for changing the 15 | blocksize (if they support it at all). It works like this: 16 | 1) Send a 'MODE SELECT' command with a block descriptor that contains the 17 | desired blocksize. The value on the Format page (03h) is not changeable! 18 | 2) Do *nothing* else or the buffered new blocksize is canceled. 19 | 3) Send a 'FORMAT UNIT' command. 20 | 4) Now the Format page (03h) reflect the new setting. 21 | 22 | I hope that this will work with disks from most other manufacturers too (Check 23 | the manual of your disk to verify whether the blocksize can be changed and/or 24 | which values are allowed). 25 | 26 | 27 | Requirements 28 | ------------ 29 | - SCSI disk ;-) 30 | - Linux with SCSI generic support (sg driver) 31 | The sg2 or sg3 drivers as in Linux 2.2.6 or newer works 32 | (Kernels 2.2.10, 2.4.21 and 2.6.16.20 are tested) 33 | - Kernel header files (in '/usr/src/linux/include') 34 | - GNU make 35 | - GCC 36 | 37 | 38 | How to configure 39 | ---------------- 40 | The desired blocksize must be specified in 'setblocksize.c' (default is a 41 | blocksize of 512 Bytes). 42 | Note: Since V0.2 the new blocksize can be specified on the command line. 43 | 44 | The SCSI command timeout is set to 2 hours. If your disk cannot complete a 45 | 'FORMAT UNIT' command within that time, you have to adjust the 'TIMEOUT' 46 | constant in 'setblocksize.c'. 47 | 48 | 49 | How to build 50 | ------------ 51 | Type 'make all' in this directory to build the binary. 52 | Type 'make clean' to get back to source only state. 53 | 54 | 55 | How to run 56 | ---------- 57 | The device file (normally '/dev/sg*') must be specified on the command line 58 | when running the binary. Use 'sg_map' and/or 'sg_scan' from the sg_utils 59 | package (http://www.torque.net/sg/index.html) to determine the correct device 60 | file if you don't know it. 61 | Check that you have adequate permission to nuke the data on the specified disk 62 | and execute like this: 63 | ------------------------------------------------------------------------------- 64 | ./setblocksize /dev/sg4 65 | ------------------------------------------------------------------------------- 66 | Note: Since V0.1 you get a last chance to abort before your data is lost. 67 | 68 | Note: Since V0.2 the blocksize can be specified on the command line like this: 69 | ------------------------------------------------------------------------------- 70 | ./setblocksize -b2048 /dev/sg4 71 | ------------------------------------------------------------------------------- 72 | 73 | Now the LED of the *disk* should be lit or flashing (My ST15150 flashes) ... 74 | Note that the disk is not formatted by the host, but formats itself - therefore 75 | the LED of the host adapter is off (there is no data transfer on the SCSI Bus). 76 | 77 | IMPORTANT: 78 | The LL-format can take some time ... be patient and do not manually interrupt. 79 | If you do so the disk can become unuseable! 80 | 81 | Use 'scsiinfo', 'scsi-config' or something like that to check the new blocksize 82 | after 'setblocksize' has finished. Search for the Format page (03h). 83 | 84 | 85 | 2007-09-04 Michael Baeuerle 86 | -------------------------------------------------------------------------------- /README.md: -------------------------------------------------------------------------------- 1 | README for 'setblocksize' tool 2 | ------------------------------ 3 | 4 | General 5 | ------- 6 | This is a tool for adjusting the blocksize of SCSI disks. 7 | It is available under GPL. See 'LICENSE' file. 8 | 9 | I have tested it with the following disks: 10 | - Seagate Barracuda 4 (ST15150DC) 11 | - Seagate Hawk 1LP (ST31200N) 12 | 13 | Seagate told me, that all of their disks use the same scheme for changing the 14 | blocksize (if they support it at all). It works like this: 15 | 1) Send a 'MODE SELECT' command with a block descriptor that contains the 16 | desired blocksize. The value on the Format page (03h) is not changeable! 17 | 2) Do *nothing* else or the buffered new blocksize is canceled. 18 | 3) Send a 'FORMAT UNIT' command. 19 | 4) Now the Format page (03h) reflect the new setting. 20 | 21 | I hope that this will work with disks from most other manufacturers too (Check 22 | the manual of your disk to verify whether the blocksize can be changed and/or 23 | which values are allowed). 24 | 25 | 26 | Requirements 27 | ------------ 28 | - SCSI disk ;-) 29 | - Linux with SCSI generic support (sg driver) 30 | The sg2 or sg3 drivers as in Linux 2.2.6 or newer works 31 | (Kernels 2.2.10, 2.4.21 and 2.6.16.20 are tested) 32 | - Kernel header files (in '/usr/src/linux/include') 33 | - GNU make 34 | - GCC 35 | 36 | 37 | How to configure 38 | ---------------- 39 | The desired blocksize must be specified in 'setblocksize.c' (default is a 40 | blocksize of 512 Bytes). 41 | Note: Since V0.2 the new blocksize can be specified on the command line. 42 | 43 | The SCSI command timeout is set to 2 hours. If your disk cannot complete a 44 | 'FORMAT UNIT' command within that time, you have to adjust the 'TIMEOUT' 45 | constant in 'setblocksize.c'. 46 | 47 | 48 | How to build 49 | ------------ 50 | Type 'make all' in this directory to build the binary. 51 | Type 'make clean' to get back to source only state. 52 | 53 | 54 | How to run 55 | ---------- 56 | The device file (normally '/dev/sg*') must be specified on the command line 57 | when running the binary. Use 'sg_map' and/or 'sg_scan' from the sg_utils 58 | package (http://www.torque.net/sg/index.html) to determine the correct device 59 | file if you don't know it. 60 | Check that you have adequate permission to nuke the data on the specified disk 61 | and execute like this: 62 | ------------------------------------------------------------------------------- 63 | ./setblocksize /dev/sg4 64 | ------------------------------------------------------------------------------- 65 | Note: Since V0.1 you get a last chance to abort before your data is lost. 66 | 67 | Note: Since V0.2 the blocksize can be specified on the command line like this: 68 | ------------------------------------------------------------------------------- 69 | ./setblocksize -b2048 /dev/sg4 70 | ------------------------------------------------------------------------------- 71 | 72 | Now the LED of the *disk* should be lit or flashing (My ST15150 flashes) ... 73 | Note that the disk is not formatted by the host, but formats itself - therefore 74 | the LED of the host adapter is off (there is no data transfer on the SCSI Bus). 75 | 76 | IMPORTANT: 77 | The LL-format can take some time ... be patient and do not manually interrupt. 78 | If you do so the disk can become unuseable! 79 | 80 | Use 'scsiinfo', 'scsi-config' or something like that to check the new blocksize 81 | after 'setblocksize' has finished. Search for the Format page (03h). 82 | 83 | 84 | 2007-09-04 Michael Baeuerle 85 | -------------------------------------------------------------------------------- /doc/Example.txt: -------------------------------------------------------------------------------- 1 | 2 | [root@WStation2:~/setblocksize/V0.2pre0]# ./setblocksize -b512 /dev/sg4 3 | 4 | setblocksize V0.2pre0 5 | 6 | Checking parameters ... 7 | Blocksize specified. 8 | Done. 9 | New blocksize: 512 Bytes 10 | Open device file ... 11 | Done. 12 | Prepare command ... 13 | Done. 14 | Send INQUIRY command ... 15 | Done. 16 | Check status ... 17 | Command successful. 18 | Check for LUN ... 19 | LUN present. 20 | 21 | =============================================================================== 22 | SCSI ID : 3 23 | LUN : 0 24 | Connected to: Host0 / Channel0 25 | Manufacturer: SEAGATE 26 | Model : ST15150W 27 | Device type : Disk 28 | =============================================================================== 29 | Do you really want to reformat this device [y/n]? y 30 | 31 | Prepare command ... 32 | Done. 33 | Send MODE SELECT command ... 34 | Done. 35 | Check status ... 36 | Command successful. 37 | Prepare command ... 38 | Done. 39 | Send FORMAT UNIT command ... 40 | *** Please wait - Do not manually interrupt or power down! *** 41 | Done. 42 | Check status ... 43 | Command successful. 44 | Close device file ... 45 | Done. 46 | 47 | Exiting ... 48 | 49 | -------------------------------------------------------------------------------- /doc/scsi-generic_long.txt: -------------------------------------------------------------------------------- 1 | Notes on Linux's SG driver version 2.1.39 2 | ----------------------------------------- 3 | 20010329 4 | 5 | Introduction 6 | ============ 7 | The SCSI Generic driver (sg) is one of the four "high level" SCSI device 8 | drivers along with sd, st and sr (disk, tape and CDROM respectively). Sg 9 | is more generalized (but lower level) than its siblings and tends to be 10 | used on SCSI devices that don't fit into the already serviced categories. 11 | Thus sg is used for scanners, cd writers and reading audio cds digitally 12 | amongst other things. 13 | 14 | These are notes on the Linux SCSI generic packet device driver (sg) 15 | describing version 2.1.39 . The original driver was written by Lawrence 16 | Foard and remained in place with minimal changes since circa 1992. 17 | Version 2 of this driver remains backward compatible (binary and 18 | source **) with the original. It adds scatter gather, command queuing, 19 | per file descriptor sequencing, asynchronous notification and better 20 | error reporting. 21 | 22 | A shorter (abridged) form of this document can be found at 23 | http://www.torque.net/sg/p/scsi-generic.txt . It can also be found in the 24 | kernel source: linux/Documentation/scsi-generic.txt . 25 | 26 | The Linux 2.4 series kernels have now been released. Lk 2.4 contains 27 | an upgraded "version 3" sg driver which is described in a supplementary 28 | document at http://www.torque.net/sg/p/scsi-generic_v3.txt . 29 | 30 | The interface and usage of the original sg driver have been documented 31 | by Heiko Eissfeldt in a HOWTO called SCSI-Programming-HOWTO. My copy 32 | of the document is version 1.5 dated 7th May 1996. It can found at 33 | ftp://sunsite.unc.edu/pub/Linux/docs/HOWTO-SCSI-Programming-HOWTO . 34 | A copy of this document can be found at: 35 | http://www.torque.net/sg/p/original/HOWTO-SCSI-Programming-HOWTO.txt . 36 | 37 | ** It is possible to write applications that perform differently 38 | depending on whether they are using the original or this version of 39 | the sg device driver. The author is not aware of any useful 40 | pre-existing applications that have problems with version 2. 41 | It may indeed be useful to distinguish between the original and the 42 | new driver and a following section discusses that subject. 43 | 44 | 45 | Architecture 46 | ============ 47 | The SCSI generic packet device driver (sg) is a character based device. 48 | It is one of the four high level device driver in the SCSI sub-system; 49 | the others are sd (for direct-access devices - disks), st (for tapes) 50 | and sr (for data cdroms). Sd and sr are block devices while st (like sg) 51 | is a character device. 52 | 53 | 54 | The unifying layer of the SCSI sub-system is the so-called mid-level. 55 | Below that are the "low level" drivers which are the drivers for the 56 | various adapters supported by Linux. Also at this level are pseudo 57 | adapter drivers such as ide-scsi which converts the SCSI protocol to 58 | ATAPI (which are similar to one another) for use by IDE devices. 59 | 60 | Since sg is a character device it supports the traditional Unix 61 | system calls of open(), close(), read(), write() and ioctl(). Two other 62 | related system calls: poll() and fcntl() are added to this list and 63 | how they interact with the sg device driver is documented later. 64 | 65 | An SG device is accessed by write()ing SCSI commands plus any associated 66 | outgoing data to it; the resulting status codes and any incoming data are 67 | then obtained by a read() call. The device can be opened O_NONBLOCK 68 | (non-blocking) and poll() used to monitor its progress. The device may be 69 | opened O_EXCL which excludes other "sg" users from this device (but not 70 | "sd", "st" or "sr" users). The buffer given to the write() call is made 71 | up as follows: 72 | - struct sg_header image (see below) 73 | - scsi command (6, 10 or 12 bytes long) 74 | - data to be written to the device (if any) 75 | 76 | The buffer received from the corresponding read() call contains: 77 | - struct sg_header image (check status/errors + sense_buffer) 78 | - data read back from device (if any) 79 | 80 | The given SCSI command has its LUN field overwritten by the LUN value of 81 | the associated sg device that has been open()ed. 82 | 83 | SCSI commands are only attempted once (i.e. there are no internal 84 | retries). If appropriate (e.g. a SCSI READ) the data buffer is copied back 85 | to user space irrespective of the values of the various SCSI related 86 | error/status codes. [Some adapters that use an old error interface in 87 | the SCSI mid level ignore the retry count and retry certain errors.] 88 | 89 | 90 | sg_header 91 | ========= 92 | This is the name of the control structure that conveys information 93 | about the length of data to be read/written by the associated SCSI 94 | command. It also conveys error and status information from the 95 | read() call. An instance of this structure is the first thing that 96 | is placed in the data buffers of both write() and read(). 97 | 98 | In its original form it looked like this: 99 | struct sg_header { 100 | int pack_len; 101 | int reply_len; 102 | int pack_id; 103 | int result; 104 | unsigned int twelve_byte:1; 105 | unsigned int other_flags:31; 106 | unsigned char sense_buffer[16]; 107 | }; /* this structure is 36 bytes long */ 108 | 109 | The 'pack_len' is bizarre and ends up having the 'reply_len' put in it 110 | (perhaps it had a use at some stage). Even though it looks like an 111 | input variable, it is not read by sg internally (only written). 112 | 113 | The 'reply_len' is the length of the data the corresponding read() 114 | will/should request (including the sg_header). 115 | 116 | The 'pack_id' is not acted upon by the sg device driver but is conveyed 117 | back to the corresponding read() so it can be used for sequencing by an 118 | application. 119 | 120 | The 'result' is also bizarre, turning certain types of host codes to 0 (no 121 | error), EBUSY or EIO. With better error reporting now available, the 122 | 'result' is best ignored. 123 | 124 | The 'twelve_byte' field overrides the internal SCSI command length detection 125 | algorithm for group 6 and 7 commands (ie when 1st byte >= 0xc0) and forces 126 | a command length of 12 bytes. 127 | The command length detection algorithm is as follows: 128 | Group: 0 1 2 3 4 5 6 7 129 | Length: 6 10 10 12 12 12 10 10 130 | 131 | 'other_flags' was originally documented as "not used" but some current 132 | applications assume it has 0 placed in it. 133 | 134 | The 'sense_buffer' is the first 16 bytes of SCSI sense buffer that is 135 | returned when the target returns a SCSI status code of CHECK_CONDITION 136 | or COMMAND_TERMINATED [or (driver_status & DRIVER_SENSE) is true]. This 137 | buffer should be at least 18 bytes long and arguably 32 bytes; unfortunately 138 | this is unlikely to happen in the 2.2.x series of kernels. 139 | 140 | The new sg_header offered in this driver is: 141 | #define SG_MAX_SENSE 16 142 | struct sg_header 143 | { 144 | int pack_len; /* [o] reply_len (ie useless) ignored as input */ 145 | int reply_len; /* [i] max length of expected reply (inc. sg_header) */ 146 | int pack_id; /* [io] id number of packet (use ints >= 0) */ 147 | int result; /* [o] 0==ok, else (+ve) Unix errno (best ignored) */ 148 | unsigned int twelve_byte:1; 149 | /* [i] Force 12 byte command length for group 6 & 7 commands */ 150 | unsigned int target_status:5; /* [o] scsi status from target */ 151 | unsigned int host_status:8; /* [o] host status (see "DID" codes) */ 152 | unsigned int driver_status:8; /* [o] driver status+suggestion */ 153 | unsigned int other_flags:10; /* unused */ 154 | unsigned char sense_buffer[SG_MAX_SENSE]; /* [o] Output in 3 cases: 155 | when target_status is CHECK_CONDITION or 156 | when target_status is COMMAND_TERMINATED or 157 | when (driver_status & DRIVER_SENSE) is true. */ 158 | }; /* This structure is 36 bytes long on i386 */ 159 | 160 | Firstly the new header is binary compatible with the original. This is 161 | important for keeping existing apps working without recompilation. 162 | 163 | Only those elements (or fields) that are new or in some way different 164 | from the original are documented below. 165 | 166 | 'pack_id' becomes input to a read() when ioctl(sg_fd, SG_SET_FORCE_PACK_ID, 167 | &one) is active. A 'pack_id' of -1 is interpreted as fetch the oldest 168 | waiting packet; any other value will cause the read() to wait (or yield 169 | EAGAIN) until a packet with that 'pack_id' becomes available. In all cases 170 | the value of 'pack_id' available after a read() is the value given to that 171 | variable in the prior, corresponding write(). 172 | 173 | The SCSI command length can now be given directly using the SG_NEXT_CMD_LEN 174 | ioctl(). 175 | 176 | The 'target_status' field is always output and is the (masked and shifted 177 | 1 bit right) SCSI status code from the target device. The allowable 178 | values are (found in ): 179 | /* N.B. 1 bit offset from usual SCSI status values */ 180 | #define GOOD 0x00 181 | #define CHECK_CONDITION 0x01 182 | #define CONDITION_GOOD 0x02 183 | #define BUSY 0x04 184 | #define INTERMEDIATE_GOOD 0x08 185 | #define INTERMEDIATE_C_GOOD 0x0a 186 | #define RESERVATION_CONFLICT 0x0c 187 | #define COMMAND_TERMINATED 0x11 188 | #define QUEUE_FULL 0x14 189 | When the 'target_status' is CHECK_CONDITION or COMMAND_TERMINATED the 190 | 'sense_buffer' is output. Note that when (driver_status & DRIVER_SENSE) 191 | is true then the 'sense_buffer' is also output (this seems to occur when 192 | the ide-scsi emulation is used). When the 'sense_buffer' is output the 193 | SCSI Sense Key can be found at (sense_buffer[2] & 0x0f) . 194 | 195 | The 'host_status' field is always output and has the following values 196 | whose "defines" are not visible outside the kernel. A copy of these 197 | defines can be found in sg_err.h (see the utilities section): 198 | #define DID_OK 0x00 /* NO error */ 199 | #define DID_NO_CONNECT 0x01 /* Couldn't connect before timeout period */ 200 | #define DID_BUS_BUSY 0x02 /* BUS stayed busy through time out period */ 201 | #define DID_TIME_OUT 0x03 /* TIMED OUT for other reason */ 202 | #define DID_BAD_TARGET 0x04 /* BAD target, device not responding */ 203 | #define DID_ABORT 0x05 /* Told to abort for some other reason */ 204 | #define DID_PARITY 0x06 /* Parity error */ 205 | #define DID_ERROR 0x07 /* Internal error [DMA underrun on aic7xxx]*/ 206 | #define DID_RESET 0x08 /* Reset by somebody. */ 207 | #define DID_BAD_INTR 0x09 /* Got an interrupt we weren't expecting. */ 208 | #define DID_PASSTHROUGH 0x0a /* Force command past mid-layer */ 209 | #define DID_SOFT_ERROR 0x0b /* The low level driver wants a retry */ 210 | 211 | The 'driver_status' field is always output. When ('driver_status' & 212 | DRIVER_SENSE) is true the 'sense_buffer' is also output. A copy of these 213 | defines can be found in sg_err.h (see the utilities section): 214 | #define DRIVER_OK 0x00 /* Typically no suggestion */ 215 | #define DRIVER_BUSY 0x01 216 | #define DRIVER_SOFT 0x02 217 | #define DRIVER_MEDIA 0x03 218 | #define DRIVER_ERROR 0x04 219 | #define DRIVER_INVALID 0x05 220 | #define DRIVER_TIMEOUT 0x06 221 | #define DRIVER_HARD 0x07 222 | #define DRIVER_SENSE 0x08 /* Implies sense_buffer output */ 223 | /* above status 'or'ed with one of the following suggestions */ 224 | #define SUGGEST_RETRY 0x10 225 | #define SUGGEST_ABORT 0x20 226 | #define SUGGEST_REMAP 0x30 227 | #define SUGGEST_DIE 0x40 228 | #define SUGGEST_SENSE 0x80 229 | 230 | 'other_flags' still remains as a 10 bit field (reduced from 31 bits), so 231 | code that places 0 in it will still be happy. It is not used. 232 | 233 | 234 | Memory issues 235 | ============= 236 | This driver uses a double-handling technique to move data from a SCSI 237 | device to the user's buffer. This technique will be termed as "indirect IO" 238 | here ("direct IO" is discussed in the Future Directions section). Indirect 239 | IO involves DMAing data from SCSI device to kernel buffers then using the 240 | CPU to move it from these kernel buffers to the user space (or vice versa 241 | in the case of writing data to a SCSI device). 242 | 243 | Obtaining memory for the kernel buffers for this indirect IO technique is 244 | the main theme of this section. These kernel buffers are needed during 245 | the write()-read() sequence associated with each SCSI command. The size 246 | of each buffer will be the maximum of the data written to the SCSI device 247 | (ie [write_count - sizeof(struct sg_header) - scsi_cmd_len]) or the data 248 | read from the SCSI device (ie [hdr.reply_len - sizeof(struct sg_header)]). 249 | Note that the 'read_count' does not affect the size of the kernel buffers 250 | but does affect the amount of data actually transferred back to the user 251 | space (if any). 252 | 253 | A "reserved" buffer is obtained when a file descriptor is opened. An attempt 254 | is made to find SG_DEF_RESERVED_SIZE bytes for the reserved buffer. The 255 | actual amount obtained (which may be as little as 0 bytes) can be found by 256 | calling the SG_GET_RESERVED_SIZE ioctl(). The size of the reserved buffer 257 | can subsequently be altered by calling the SG_SET_RESERVED_SIZE ioctl(). 258 | This reserved buffer becomes the kernel buffer for a given write()-read() 259 | sequence if 260 | 1) the reserved buffer is not already in use (eg during command queuing) 261 | 2) the reserved buffer is large enough. 262 | If either of these condition is not met then the write() will attempt to 263 | allocate a kernel buffer of the requested size and free it during the 264 | corresponding read(). The reserved buffer is freed when the file descriptor 265 | is close()d. Each buffer faces the following constraints: 266 | a) only "real" memory can be used (ie not swap) and must not be 267 | subsequently swapped out [this is what makes direct IO so interesting] 268 | b) in the case of ISA cards, only memory below the 16MB mark can be used 269 | (this is a good reason to buy a PCI adapter) 270 | c) if the adapter does not support scatter gather then the buffer must 271 | be one contiguous piece of memory, otherwise it can be made up of 272 | several contiguous pieces of memory 273 | d) The biggest contiguous piece of memory in Linux 2.2 is (32 * PAGE_SIZE) 274 | and there are not many of these (3 on my machine at the moment) 275 | PAGE_SIZE is 4096 bytes on i386 and 8192 on the alpha. Its value can be 276 | found by calling the getpagesize() function declared in . 277 | 278 | Linux 2.2 does not put aside any memory for drivers; they just compete for 279 | memory with user processes and other drivers. Given the above constraints 280 | there are no guarantees that suitable memory will be available when 281 | requested. [Even drivers that grab memory while the kernel is being loaded 282 | could be thwarted by another driver doing the same thing!] 283 | 284 | The original sg driver uses the following technique: grab a SG_BIG_BUFF 285 | sized (contiguous) buffer at driver initialization and use it for all 286 | requests greater than PAGE_SIZE. By default SG_BIG_BUFF is set to 32 KBytes 287 | in the original driver but many applications suggest that the user increases 288 | this number. Unfortunately if the sg driver is a module then there is a high 289 | chance that a contiguous block of memory will not be available at module 290 | initialization. This results in a kernel "OOPS" in the original driver. 291 | 292 | The author has found no "silver bullet" solution but uses multiple 293 | techniques hoping that at least one is able provide memory at the critical 294 | time. Listed below are some of these techniques: 295 | - obtain a reserved buffer at open() and use it if is available and 296 | of sufficient size 297 | - use scatter gather: then instead of one large buffer needing to 298 | be found, multiple smaller buffers can be used 299 | - use memory above the 16MByte level: the original driver limited 300 | itself to obtaining memory below the 16MByte level (on the i386) 301 | due to the shortcomings of DMA on ISA adapters. Yet more and more 302 | people use PCI adapters that don't have this problem. So make 303 | the decision based on the capabilities of the host adapter 304 | associated with the current SCSI device at runtime 305 | - if the kernel is short of memory then dip into the SCSI DMA 306 | pool (maintained by the mid-level driver) to a limited extent 307 | 308 | The safest strategy for limiting memory problems is: 309 | 1) after open() on the sg device, if the SG_DEF_RESERVED_SIZE is not large 310 | enough, then use the SG_SET_RESERVED_SIZE ioctl() and attempt to 311 | increase it 312 | 2) in all cases now call the SG_GET_RESERVED_SIZE ioctl() and see how much 313 | was actually reserved; if this is not enough exit 314 | 3) don't use command queuing 315 | 4) make sure no write()-read() sequence is requesting a buffer size larger 316 | than the actual reserved buffer size 317 | 318 | Alternatively, applications can be written in such a way to do something 319 | sensible (eg request a smaller buffer) when a write() returns an ENOMEM 320 | error. 321 | 322 | A discussion on tuning SG_BIG_BUFF, SG_DEF_RESERVED_SIZE and SG_SCATTER_SZ 323 | is in a later section. 324 | 325 | 326 | System Calls 327 | ============ 328 | What follows are descriptions of the characteristics of the standard 329 | Unix operating system calls when applied to a SCSI generic device 330 | using this version of the device driver. 331 | 332 | open(const char * filename, int flags) 333 | -------------------------------------- 334 | The filename should be an 'sg' device such as 335 | /dev/sg[0,1,2,...] 336 | /dev/sg[a-z] <<< now deprecated >>> 337 | or a symbolic link to one of these. [Devfs has its own sub-directory for 338 | sg devices with entries like: /dev/sg/c1b2t3u4 .] It seems as though SCSI 339 | devices are allocated to sg minor numbers in the same order as they appear 340 | in 'cat /proc/scsi/scsi'. Sg is a "character" based Linux device driver. 341 | This means it has an open/close/read/write/ioctl type interface. 342 | 343 | Flags can be either O_RDONLY or O_RDWR or-ed with either 344 | O_EXCL waits for other opens on sg device to be closed before 345 | proceeding. If O_NONBLOCK is set then yields EBUSY when 346 | someone else has the sg device open. The combination of 347 | O_RDONLY and O_EXCL is disallowed. 348 | O_NONBLOCK Sets non-blocking mode. Calls that would otherwise block 349 | yield EAGAIN (eg read() ) or EBUSY (eg open() ). 350 | 351 | The original version of sg did not allow the O_RDONLY (yielding a EACCES 352 | error). This version allows it for accessing ioctls (e.g. doing an sg 353 | device scan with the SG_GET_SCSI_ID ioctl) but write()s will not be 354 | allowed. These flags are found in . 355 | 356 | By default, sequencing is per file descriptor in this version of sg. This 357 | means, for example that 2 processes can independently manipulate the same 358 | sg device at the same time. This may or may not make sense depending on 359 | the application: 2 processes (logically) reading from the same direct access 360 | device (ie a disk) is ok while running 2 instances of cd writing software 361 | on the same device at the same time probably wouldn't be a good idea. The 362 | previous version of sg supported only per device sequencing and this can 363 | still be selected with the SG_SET_MERGE_FD,1 ioctl(). 364 | 365 | The driver will attempt to reserve SG_DEF_RESERVED_SIZE bytes (32KBytes in 366 | the current sg.h) on open(). The size of this reserved buffer can 367 | subsequently be modified with the SG_SET_RESERVED_SIZE ioctl(). In both 368 | cases these are requests subject to various dynamic constraints. The actual 369 | amount of memory obtained can be found by the SG_GET_RESERVED_SIZE ioctl(). 370 | The reserved buffer will be used if: 371 | - it is not already in use (eg when command queuing is in use) 372 | - a write() does not call for a buffer size larger than the 373 | reserved size. 374 | 375 | Returns a file descriptor if >= 0 , otherwise -1 implies an error. 376 | 377 | Error codes (value in 'errno' after -1 returned): 378 | EACCES Either the user doesn't have appropriate permissions on 379 | 'filename' or attempted to use both O_RDONLY and O_EXCL 380 | EBUSY O_NONBLOCK set and some user of this sg device has O_EXCL 381 | set while someone is already using this device 382 | EINTR while waiting for an "exclusive" lock to clear, a signal 383 | is received, just try again ... 384 | ENODEV sg not compiled into kernel or the kernel cannot find the 385 | sg module (or it can't initialize itself (low memory??)) 386 | ENOENT given filename not found 387 | ENOMEM An attempt to get memory to store this open's context 388 | failed (this was _not_ a request to reserve DMA memory) 389 | ENXIO either there is no attached device corresponding to given 390 | filename or scsi sub-system is currently processing some 391 | error (eg doing a device reset) or the sg driver/module 392 | removed or corrupted 393 | 394 | 395 | write(int sg_fd, const void * buffer, size_t count) 396 | --------------------------------------------------- 397 | Even though sg is a character-based device driver it sends and receives 398 | packets to/from the associated scsi device. Write() is used to send a 399 | packet containing 2 mandatory parts and 1 optional part. The mandatory 400 | parts are: 401 | - a control block (an instance of struct sg_header) 402 | - a SCSI command (6, 10 or 12 bytes long) 403 | The optional part is: 404 | - outgoing data (eg if a SCSI write command is being sent) 405 | These should appear as one contiguous string in the buffer given to 406 | write() in the above order with no pad characters. 407 | 408 | If a write() accepts this packet then at some later time the user should 409 | call a read() to get the result of the SCSI command. The previous sg 410 | driver enforced a strict write()/read()/write()/read() regime so that a 411 | second write() would block until first read() was finished. This sg 412 | driver relaxes that condition and thereby allows command queuing 413 | (limit is SG_MAX_QUEUE (16) outstanding packets per file descriptor). 414 | However, for backward compatibility, command queuing is turned off 415 | by default (#define SG_DEF_COMMAND_Q 0 in sg.h). This can be changed 416 | via the the SG_SET_COMMAND_Q ioctl() [or by recompiling after changing 417 | the above define to 1]. 418 | 419 | In this sg driver a write() should return more or less immediately. 420 | 421 | Returns number of bytes written if > 0 , otherwise -1 implies an error. 422 | 423 | Error codes (value in 'errno' after -1 returned): 424 | EACCES opened with RD_ONLY flag 425 | EAGAIN SCSI mid-level out of command blocks (rare), try again. 426 | This is more likely to happen when queuing commands, 427 | so wait a bit (eg usleep(10000) ) before trying again 428 | EDOM a) command queuing off: a packet is already queued 429 | b) command queuing on: too many packets queued 430 | (SG_MAX_QUEUE exceeded) 431 | EFAULT 'buffer' for 'count' bytes is an invalid memory range 432 | EIO a) incoming buffer too short. It should be at least 433 | (6 + sizeof(struct sg_header))==42 bytes long 434 | b) SCSI command length given in SG_NEXT_CMD_LEN too long 435 | c) reply_len negative 436 | ENOMEM can't get memory for DMA. Take evasive action ... 437 | (see section on memory) 438 | ENXIO either scsi sub-system is currently processing some error 439 | (eg doing a device reset) or the sg driver/module removed 440 | or corrupted 441 | 442 | 443 | read(int sg_fd, void * buffer, size_t count) 444 | -------------------------------------------- 445 | Read() is used to receive a packet containing 1 mandatory part and 1 446 | optional part. The mandatory part is: 447 | - a control block (an instance of struct sg_header) 448 | The optional part is: 449 | - incoming data (eg if a SCSI read command was sent by earlier write() ) 450 | The buffer given to a read() and its corresponding count should be 451 | sufficient to accommodate this packet to avoid truncation. Truncation occurs 452 | if count < sg_header::replylen . 453 | 454 | By default, read() will return the oldest packet queued up. If the 455 | SG_SET_FORCE_PACK_ID,1 ioctl() is active then read() will attempt to 456 | fetch the packet whose pack_id (given earlier to write()) matches the 457 | sg_header::pack_id given to this read(). If not available it will either 458 | wait or yield EAGAIN. As a special case, -1 in sg_header::pack_id given 459 | to read() will match the oldest packet. 460 | 461 | Returns number of bytes read if > 0 , otherwise -1 implies an error. 462 | Unfortunately the return value in the non-error case is simply the 463 | same as the count argument. It is not the actual number of bytes 464 | DMA-ed by the SCSI device. This driver is currently unable to provide 465 | such an underrun indication. 466 | 467 | If the SCSI device reports an error then a REQUEST SENSE is automatically 468 | done and the output is placed in the sense_buffer array which is in the 469 | control block. This action is sometimes called "auto-sense". 470 | 471 | Error codes (value in 'errno' after -1 returned): 472 | EAGAIN either no waiting packet or requested packet is not 473 | available while O_NONBLOCK flag was set 474 | EFAULT 'buffer' for 'count' bytes is an invalid memory range 475 | EINTR while waiting for a packet, a signal is received, just 476 | try again ... 477 | EIO if the 'count' given to read() is < sizeof(struct sg_header) 478 | and the 'result' element in sg_header is non-zero. Not a 479 | recommended error reporting technique 480 | ENXIO either scsi sub-system is currently processing some error 481 | (eg doing a device reset) or the sg driver/module removed 482 | or corrupted 483 | 484 | 485 | close(int sg_fd) 486 | ---------------- 487 | Preferably a close() should be done after all issued write()s have had 488 | their corresponding read() calls completed. Unfortunately this is not 489 | always possible. The semantics of close() in Unix are to return more 490 | or less immediately (ie not wait on any event) so the driver needs to 491 | arrange for an orderly cleanup of those packets that are still "in 492 | flight". 493 | 494 | A process that has an open file descriptor to an sg device may be aborted 495 | (eg by a kill signal). In this case, the kernel automatically calls close 496 | (which is called 'sg_release()' in the version 2 driver) to facilitate 497 | the cleanup mentioned above. 498 | 499 | A problem persists in version 2.1.39 if the sg driver is a module and is 500 | removed while packets are still "in flight". 501 | 502 | Returns 0 if successful, otherwise -1 implies an error. 503 | 504 | Error codes (value in 'errno' after -1 returned): 505 | ENXIO sg driver/module removed or corrupted 506 | 507 | ioctl(int sg_fd, int command, ...) [sg specific] 508 | ------------------------------------------------- 509 | Ken Thompson (or perhaps some other Unix luminary) described ioctl() as 510 | the "garbage bin of Unix". This driver compounds the situation by adding 511 | more ... 512 | If a ioctl command is not recognized by sg (and the various lower levels 513 | that it may pass the command on to) then the error EINVAL occurs. If an 514 | invalid address is given (in the 3rd argument) then the error EFAULT occurs. 515 | 516 | Those commands with an appended "+" are new in version 2. 517 | 518 | Those commands with an appended "W" are only accessible from file 519 | descriptors opened with O_RDWR. They will yield EACCES otherwise. 520 | 521 | SG_GET_TIMEOUT: 522 | Ignores its 3rd argument and _returns_ the timeout value (which will be 523 | >= 0 ). The unit of this timeout is "jiffies" which are currently 10 524 | millisecond intervals on i386 (less on an alpha). Linux supplies 525 | a manifest constant HZ which is the number of "jiffies" in 1 second. 526 | 527 | SG_SET_TIMEOUT: 528 | Assumes 3rd argument points to an int containing the new timeout value 529 | for this file descriptor. The unit is a "jiffy". Packets that are 530 | already "in flight" will not be affected. The default value is set 531 | on open() and is SG_DEFAULT_TIMEOUT (defined in sg.h). This default is 532 | currently 1 minute and may not be long enough for formats. Negative 533 | values will yield an EIO error. 534 | 535 | SG_EMULATED_HOST: 536 | Assumes 3rd argument points to an int and outputs a flag indicating 537 | whether the host (adapter) is connected to a real SCSI bus or is an 538 | emulated one (eg ide-scsi device driver). A value of 1 means emulated 539 | while 0 is not. 540 | 541 | SG_SET_TRANSFORM W: 542 | Only is meaningful when SG_EMULATED host has yielded 1 (i.e. the low-level 543 | is the ide-scsi device driver); otherwise an EINVAL error occurs. The 544 | default state is to _not_ transform SCSI commands to the corresponding 545 | ATAPI commands but pass them straight through as is. [Only certain classes 546 | of SCSI commands need to be transformed to their ATAPI equivalents.] 547 | The third argument is interpreted as an integer. When it is non-zero then 548 | a flag is set inside the ide-scsi driver that transforms subsequent 549 | commands sent to this driver. When zero is passed as the 3rd argument to 550 | this ioctl then the flag within the ide-scsi driver is cleared and 551 | subsequent commands are not transformed. Beware, this state will affect 552 | all devices (and hence all related sg file descriptors) associated with 553 | this ide-scsi "bus". 554 | 555 | SG_GET_TRANSFORM: 556 | Third argument is ignored. Only is meaningful when SG_EMULATED host has 557 | yielded 1 (ie the low-level is the ide-scsi device driver); otherwise 558 | an EINVAL error occurs. Returns 0 to indicate _not_ transforming SCSI 559 | to ATAPI commands (default). Returns 1 when it is transforming them. 560 | 561 | SG_SET_FORCE_LOW_DMA +: 562 | Assumes 3rd argument points to an int containing 0 or 1. 0 (default) 563 | means sg decides whether to use memory above 16 Mbyte level (on i386) 564 | based on the host adapter being used by this SCSI device. Typically 565 | PCI SCSI adapters will indicate they can DMA to the whole 32 bit address 566 | space. 567 | If 1 is given then the host adapter is overridden and only memory below 568 | the 16MB level is used for DMA. A requirement for this should be 569 | extremely rare. If the "reserved" buffer allocated on open() is not in 570 | use then it will be de-allocated and re-allocated under the 16MB level 571 | (and the latter operation could fail yielding ENOMEM). 572 | Only the current file descriptor is affected. 573 | 574 | SG_GET_LOW_DMA +: 575 | Assumes 3rd argument points to an int and places 0 or 1 in it. 0 576 | indicates the whole 32 bit address space is being used for DMA transfers 577 | on this file descriptor. 1 indicates the memory below the 16MB level 578 | (on i386) is being used (and this may be the case because the host 579 | adapters setting has been overridden by SG_SET_FORCE_LOW_DMA,1 . 580 | 581 | SG_GET_SCSI_ID +: 582 | Assumes 3rd argument is pointing to an object of type Sg_scsi_id (see 583 | sg.h) and populates it. That structure contains ints for host_no, 584 | channel, scsi_id, lun, scsi_type, allowable commands per lun and 585 | queue_depth. Most of this information is available from other sources 586 | (eg SCSI_IOCTL_GET_IDLUN and SCSI_IOCTL_GET_BUS_NUMBER) but tends to be 587 | awkward to collect. 588 | Allowable commands per lun and queue_depth give an insight to the 589 | command queuing capabilities of the adapters and the device. The latter 590 | overrides the former (logically) and the former is only of interest 591 | if it is equal to queue_depth which probably indicates the device 592 | does not support queueing commands (e.g. most scanners). 593 | 594 | SG_SET_FORCE_PACK_ID +: 595 | Assumes 3rd argument is pointing to an int. 0 (default) instructs read() 596 | to return the oldest (written) packet if multiple packets are 597 | waiting to be read (when command queuing is being used). 598 | 1 instructs read() to view the sg_header::pack_id as input and return the 599 | oldest packet matching that pack_id or wait until it arrives (or yield 600 | EAGAIN if O_NONBLOCK is in force). As a special case the pack_id of -1 601 | given to read() in the mode will match the oldest packet. 602 | Only the current file descriptor is affected by this command. 603 | 604 | SG_GET_PACK_ID +: 605 | Assumes 3rd argument points to an int and places the pack_id of the 606 | oldest (written) packet in it. If no packet is waiting to be read then 607 | yields -1. 608 | 609 | SG_GET_NUM_WAITING +: 610 | Assumes 3rd argument points to an int and places the number of packets 611 | waiting to be read in it. 612 | 613 | SG_GET_SG_TABLESIZE +: 614 | Assumes 3rd argument points to an int and places the maximum number of 615 | scatter gather elements supported by the host adapter. 0 indicates that 616 | the adapter does support scatter gather. 617 | 618 | SG_SET_RESERVED_SIZE +W: 619 | Assumes 3rd argument is pointing to an int. That value will be used to 620 | request a new reserved buffer of that size. The previous reserved buffer 621 | is freed (if it is not in use; if it was in use -EBUSY is returned). 622 | A new reserved buffer is then allocated and its actual size can be found by 623 | calling the SG_GET_RESERVED_SIZE ioctl(). The reserved buffer is then used 624 | for DMA purposes by subsequent write() commands if it is not already in 625 | use and if the write() is not calling for a buffer size larger than that 626 | reserved. The reserved buffer may well be a series of kernel buffers if the 627 | adapter supports scatter-gather. Large buffers can be requested (eg 1 MB). 628 | 629 | SG_GET_RESERVED_SIZE +: 630 | Assumes 3rd argument points to an int and places the size in bytes of 631 | the reserved buffer from open() or the most recent SG_SET_RESERVED_SIZE 632 | ioctl() call on this fd. The result can be 0 if memory is very tight. In 633 | this case it may not be wise to attempt something like burning a CD on 634 | this file descriptor. 635 | 636 | SG_SET_MERGE_FD +W: 637 | Assumes 3rd argument is pointing to an int. 0 (the default) causes all 638 | subsequent sequencing to be per file descriptor. 1 causes all subsequent 639 | sequencing to be per device. If this command tries to change the current 640 | state and there is one or more _other_ file descriptors using this sg 641 | device then an EBUSY error occurs. Per device sequencing was the original 642 | semantics and allowed, for example different processes to "share" the 643 | device, one perhaps write()ing with the other one read()ing. This command 644 | is supplied if anyone needs those semantics. Per file descriptor 645 | sequencing, perhaps with the use of the O_EXCL flag, seems more sensible. 646 | 647 | SG_GET_MERGE_FD +: 648 | Assumes 3rd argument points to an int and places 0 or 1 in it. 0 implies 649 | sequencing is per file descriptor. 1 implies sequencing is per device 650 | (original sg driver's semantics). 651 | 652 | SG_SET_COMMAND_Q +: 653 | Assumes 3rd argument is pointing to an int. 0 (current default, set by 654 | SG_DEF_COMMAND_Q in sg.h) disables command queuing. Attempts to write() 655 | a packet while one is already queued will result in a EDOM error. 656 | 1 turns command queuing on. 657 | Changing the queuing state only affects write()s done after the change. 658 | Only the current file descriptor is affected by this command. 659 | 660 | SG_GET_COMMAND_Q +: 661 | Assumes 3rd argument points to an int and places 0 or 1 in it. 0 implies 662 | that command queuing is off on this file descriptor. 1 implies command 663 | queuing is on. 664 | 665 | SG_SET_UNDERRUN_FLAG +: 666 | Assumes 3rd argument is pointing to an int. 0 (current default, set by 667 | SG_DEF_UNDERRUN_FLAG in sg.h) requests underruns be ignored. 1 requests 668 | that underruns be flagged. [The only low level driver that acts on this 669 | at the moment is the aic7xxx which yields a DID_ERROR error on underrun.] 670 | Only the current file descriptor is affected by this command (unless 671 | "per device" sequencing has been selected). 672 | 673 | SG_GET_UNDERRUN_FLAG +: 674 | Assumes 3rd argument points to an int and places 0 or 1 in it. 0 implies 675 | that underruns are not being reported. 1 implies that underruns are being 676 | reported (see SG_SET_UNDERRUN_FLAG for more details). 677 | 678 | SG_NEXT_CMD_LEN +: 679 | Assumes 3rd argument is pointing to an int. The value of the int (if > 0) 680 | will be used as the SCSI command length of the next SCSI command sent to 681 | a write() on this fd. After that write() the SCSI command length logic is 682 | reset to use automatic length detection (ie depending on SCSI command group 683 | and the 'twelve_byte' field). If the current SCSI command length maximum of 684 | 12 is exceeded then the affected write() will yield an EDOM error. 685 | Giving this ioctl() a value of 0 will set automatic length detection for 686 | the next write(). N.B. Only the following write() on this fd is affected by 687 | this ioctl(). 688 | 689 | SG_GET_VERSION_NUM +: 690 | Assumes 3rd argument points to an int. The version number is then placed 691 | in that int. A sg version such as 2.1.36 will yield "20136" from this ioctl. 692 | 693 | SG_SCSI_RESET +: 694 | Assumes 3rd argument points to an int. Unfortunately doesn't currently 695 | do much (may in the future after other issues are resolved). Yields an 696 | EBUSY error if the SCSI bus or the associated device is being reset 697 | when this ioctl() is called, otherwise returns 0. 698 | N.B. In some recent distributions there is a patch to the SCSI mid level 699 | code that activates this ioctl. Check your distribution. 700 | 701 | SG_SET_DEBUG +: 702 | Assumes 3rd argument is pointing to an int. 0 (default) turns debugging 703 | off. Values > 0 cause the SCSI sense buffer to be decoded and output 704 | to the console/log when a SCSI device error occurs. Values > 8 cause 705 | the current sg device driver's state to be output to the console/log 706 | (this is a "one off" effect). 707 | If you need a _lot_ of the SCSI sub-system debug information (mainly from 708 | the mid-level) then try 'echo "scsi dump 0" > /proc/scsi/scsi' and lots of 709 | debug will appear in your console/log. 710 | 711 | ioctl(int s_fd, int command, ...) [in common with sd, st + sr] 712 | --------------------------------------------------------------- 713 | The following ioctl()s can be called from any high-level scsi device 714 | driver (ie sd, st, sr + sg). Access permissions may differ a little from 715 | one device to another, the access information given below is specific to 716 | the sg device driver. 717 | 718 | SCSI_IOCTL_GET_IDLUN: 719 | This ioctl takes a pointer to a "struct scsi_idlun" object as its third 720 | argument. The "struct scsi_idlun" definition is found in . 721 | It gets populated with scsi channel, device id and lun data for the given 722 | device. Unfortunately that header file "hides" that structure behind a 723 | "#ifdef __KERNEL__" block. This probably indicates that this ioctl command 724 | is deprecated. To use this, that structure needs to be replicated in 725 | the user's program. Something like: 726 | typedef struct my_scsi_idlun { 727 | int four_in_one; /* 4 separate bytes of info compacted into 1 int */ 728 | int host_unique_id; /* distinguishes adapter cards from same supplier */ 729 | } My_scsi_idlun; 730 | "four_in_one" is made up as follows: 731 | (scsi_device_id | (lun << 8) | (channel << 16) | (low_inode << 24)) 732 | These 4 components are assumed (or masked) to be 1 byte each. The first 733 | 3 should be obvious while 'low_inode' is a /proc pseudo file system entry 734 | for the adapter. Best not to use 'low_inode', it seems that 735 | SCSI_IOCTL_GET_BUS_NUMBER offers a more reliable service. The 736 | 'host_unique_id' assigns a different number to each controller from the 737 | same manufacturer/low-level device driver. Most of the information 738 | provided by this command is more easily obtained from SG_GET_SCSI_ID. 739 | 740 | SCSI_IOCTL_GET_BUS_NUMBER: 741 | Takes an 'int *' as its third argument and places the bus number associated 742 | with a device in the associated "int". Bus numbers are allocated sequentially 743 | from 0 by the SCSI mid-level and are roughly one bus number per physical 744 | SCSI host adapter in the machine. Things like the ide-scsi emulation driver 745 | get their own bus number after "real" SCSI adapters. Loading a low-level 746 | SCSI device driver as a module will add a new bus number to the end of 747 | the existing sequence. 748 | 749 | SCSI_IOCTL_SEND_COMMAND W: 750 | This command is forwarded onto the SCSI mid-level driver for processing. 751 | Essentially it is an alternate way to send a SCSI command (optionally 752 | with associated data), wait till the command is executed then return 753 | the SCSI error/status information (optionally with associated data). 754 | Comments in the kernel code suggest that this ioctl is deprecated. 755 | 756 | Here is a summary. The 3rd argument points to a structure looking like: 757 | struct sdata { 758 | unsigned int inlen; [i] Length of data to be written to device 759 | unsigned int outlen; [i] Length of data to be read from device 760 | unsigned char cmd[x]; [i] SCSI command (6 <= x <= 12). 761 | [o] Data read from device starts here. 762 | [o] On error, sense buffer starts here. 763 | unsigned char wdata[y]; [i] Data written to device starts here. 764 | }; 765 | Notes: 766 | - The SCSI command length is determined by examining the 1st byte 767 | of the given command. There is no way to override this. 768 | - Data transfers are limited to PAGE_SIZE (4K on i386, 8K on alpha). 769 | - The length (x + y) must be at least OMAX_SB_LEN bytes long to 770 | accomodate the sense buffer when an error occurs. 771 | The sense buffer is truncated to OMAX_SB_LEN (16) bytes so that 772 | old code will not be surprised. 773 | - If a Unix error occurs (e.g. ENOMEM) then the user will receive 774 | a negative return and the Unix error code in 'errno'. 775 | If the SCSI command succeeds then 0 is returned. 776 | Positive numbers returned are the compacted SCSI error codes (4 777 | bytes in one int) where the lowest byte is the SCSI status. 778 | See the drivers/scsi/scsi.h file for more information on this. 779 | 780 | One difference between SCSI commands sent to a device by this ioctl 781 | compared to via sg is that SCSI_IOCTL_SEND_COMMAND will do internal 782 | retries. Failed retries can lead to SCSI bus resets. Also if any 783 | status/error is detected then the sense buffer is copied back to the 784 | user space rather than data. For example: on a SCSI READ with 785 | CHECK CONDITION set and a RECOVERED ERROR indicated, you receive a 786 | sense buffer with that information rather than the data. 787 | 788 | 789 | SCSI_IOCTL_TAGGED_ENABLE W: 790 | SCSI_IOCTL_TAGGED_DISABLE W: 791 | SCSI_IOCTL_DOORLOCK W: 792 | SCSI_IOCTL_DOORUNLOCK W: 793 | SCSI_IOCTL_TEST_UNIT_READY W: 794 | SCSI_IOCTL_START_UNIT W: 795 | SCSI_IOCTL_STOP_UNIT W: 796 | These commands ignore their third argument and do what their name suggests 797 | returning a compacted scsi error/status code as the result. A returned 798 | value of 0 means no error occurred. These commands are performed by the 799 | the SCSI mid-level driver. 800 | 801 | SCSI_IOCTL_PROBE_HOST: 802 | This command should be given a pointer to a 'char' array as its 3rd 803 | argument. That array should be at least sizeof(int) long and have the 804 | length of the array as an 'int' at the beginning of the array! An ASCII 805 | string of no greater than that length containing "information" (or the 806 | name) of SCSI host (ie adapter) associated with this file descriptor is 807 | then placed in the given byte array. N.B. A trailing '\0' may need to 808 | be put on the output string if it has been truncated by the input 809 | length. Returns 1 if host is present, 0 if it is not and a negative 810 | value if there is an error. 811 | 812 | W: 813 | Any command that "falls though" and doesn't compare to one of the above 814 | will be passed onto the mid level and if not resolved there will be 815 | passed on to the low level SCSI driver before being rejected. Some 816 | low level SCSI drivers support ioctls specific to their hardware. 817 | 818 | 819 | poll(struct pollfd * udfds, unsigned int nfds, int timeout_ms) 820 | -------------------------------------------------------------- 821 | This is a native call in Linux 2.2 but most of its capabilities are available 822 | through the older select() call. Given a choice poll() should probably be 823 | used. Typically poll() is used when a sg scsi device is open()ed O_NONBLOCK 824 | for polling; and optionally with asynchronous notification as well using 825 | the fcntl() system call (below) and the SIGPOLL (aka SIGIO) signal. 826 | Only if something drastically is wrong (eg file handle gone stale) will 827 | POLLERR ever be set. POLLPRI, POLLHUP and POLLNVAL are never set. 828 | POLLIN is set when there is one or more packets waiting to be read. 829 | When POLLIN is set it implies that a read() will not block (nor yield 830 | EAGAIN in non-blocking mode) but return a packet immediately. 831 | POLLOUT (aka POLLWRNORM) is set when write() is able to accept a packet 832 | (ie will _not_ yield an EDOM error). The setting of POLLOUT is affected 833 | by the SG_SET_COMMAND_Q state: if the state is on then POLLOUT will remain 834 | set until the number of queued packets reaches SG_MAX_QUEUE, if the 835 | state is off then POLLOUT is only set when no packets are queued. 836 | Note that a packet can be queued after write()ing but not available to be 837 | read(); this typically happens when a SCSI read command is issued while 838 | the data is being retrieved. 839 | Poll() is per file descriptor unless SG_SET_MERGE_FD is set in which case 840 | it is per device. 841 | 842 | 843 | fcntl(int sg_fd, int cmd) or fcntl(int sg_fd, int cmd, long arg) 844 | ---------------------------------------------------------------- 845 | There are several uses for this system call in association with a sg 846 | file descriptor. The following pseudo code shows code that is useful for 847 | scanning the sg devices, taking care not to be caught in a wait for 848 | an O_EXCL lock by another process, and when the appropriate device is 849 | found, switching to normal blocked io. A working example of this logic 850 | is in the sg_scan utility program. 851 | 852 | open("/dev/sg0", O_RDONLY | O_NONBLOCK) 853 | /* check device, EBUSY means some other process has O_EXCL lock on it */ 854 | /* when the device you want is found then ... */ 855 | flags = fcntl(sg_fd, F_GETFL) 856 | fcntl(sg_fd, F_SETFL, flags & (~ O_NONBLOCK)) 857 | /* ince, or simple apps, it is easier to use normal blocked io */ 858 | 859 | 860 | Some work has to be done in Linux to set up for asynchronous notification. 861 | This is a non-blocking mode of operation in which, when the driver receives 862 | data back from a device so that a read() can be done, it sends a SIGPOLL 863 | (aka SIGIO) signal to the owning process. A working example of this logic 864 | is in the sg_poll test program. 865 | 866 | sigemptyset(&sig_set) 867 | sigaddset(&sig_set, SIGPOLL) 868 | sigaction(SIGPOLL, &s_action, 0) 869 | fcntl(sg_fd, F_SETOWN, getpid()) 870 | flags = fcntl(sg_fd, F_GETFL); 871 | fcntl(sg_fd, F_SETFL, flags | O_ASYNC) 872 | 873 | 874 | Utility and Test Programs 875 | ========================= 876 | See the README file in the sg_utils.tgz tarball. Look on the 877 | http://www.torque.net/sg website for the latest version. 878 | 879 | Briefly, that tarball contains the following utilities: 880 | sg_dd512 'dd' like program that assumes 512 byte blocks size 881 | sg_dd2048 'dd' like program that assumes 2048 byte blocks size 882 | sg_dd2352 'dd' like program that assumes 2352 byte blocks size 883 | sgq_dd512 like 'sg_dd512' but does command queuing on "if" 884 | sgp_dd probably the most flexible 'dd' variant. It uses POSIX 885 | threads, block size set by "bs=..." plus other options. 886 | sg_scan outputs information (optionally Inquiry) on SCSI devices 887 | sg_rbuf tests SCSI bus transfer speed (without physical IO) 888 | sg_whoami outputs info (optionally capacity) of given SCSI device 889 | sginfo outputs "mode" information about SCSI devices (it is a 890 | re-port of the scsiinfo program onto the sg interface) 891 | 892 | It also contains the following test programs: 893 | sg_debug outputs sg driver state to console/log file 894 | sg_poll tests asynchronous notification 895 | sg_runt_ex example run time selection program for application authors 896 | sg_simple1 example program first time users 897 | sg_simple2 like sg_simple1 but with more primitive error processing 898 | sg_inquiry does a SCSI Inquiry command (from original HOWTO) 899 | sg_tst_med checks presence of media (from original HOWTO) 900 | 901 | There are also 2 source files (sg_err.[hc]) for outputting and categorizing 902 | SCSI 2 errors and warnings. This code is used by most of the above 903 | utility and test programs. 904 | 905 | The following programs: sg_dd512, sg_dd2048, sg_dd2352, sg_scan, sg_runt_ex, 906 | sg_rbuf, sg_tst_med, sg_inquiry and sginfo, can be compiled either for this 907 | new sg driver _or_ the original sg driver (in 2.0 or 2.2 series kernels). 908 | sg_runt_ex can be run on 2.0, 2.2 or 2.3 series kernels even if it is 909 | compiled on a different series (eg compiled on 2.0, run on 2.2). 910 | 911 | 912 | Header files 913 | ============ 914 | User applications need to find the correct "sg.h" header file matching 915 | their kernel in order to write code using the sg device driver. This is 916 | sometimes more difficult than it should be. The correct "sg.h" will usually 917 | be found at /usr/src/linux/include/scsi/sg.h . Another important header 918 | file is "scsi.h" which will be in the same directory. 919 | 920 | Several distributions have taken their own copies of these files and placed 921 | them in /usr/include/scsi which is where "#include " would go 922 | looking. The directory /usr/include/scsi _should_ be a symbolic link to 923 | /usr/src/linux/include/scsi/ . It was is Redhat 5.1 and 5.2 but it is 924 | not is Redhat 6.0 . Some other distributions have the same problem. To 925 | solve this (as root) do the following: 926 | 927 | # cd /usr/include 928 | # mv scsi scsi_orig 929 | # ln -s ../src/linux/include/scsi scsi 930 | 931 | This doesn't seem to be a problem with /usr/include/linux (at least in 932 | Redhat where it is a symbolic link) so it is hard to understand why 933 | /usr/include/scsi is defined the way it is. The fact the 934 | /usr/include/linux is a symbolic link opens up the following solution 935 | proposed by the author of cdparanoia (Monty): 936 | #include 937 | 938 | 939 | Distinguishing the original from the new driver 940 | =============================================== 941 | People writing applications have to cope with the existing Linux code 942 | base in the field. Hence there are literally millions of systems 943 | running Linux with the original sg driver. So the problem arises: 944 | how to write applications that can take advantage of the new 945 | features (or at least better error reporting) of this sg driver but 946 | still run with the original sg driver? 947 | 948 | This can be addressed at 2 levels: run time and compile time. Even 949 | though run time identification is a little more difficult it is more 950 | flexible and minimizes backward compatibility problems and thus is 951 | recommended. 952 | 953 | For compile time selection "#ifdef #else #endif" style conditional 954 | compilation can be used. The SG_GET_RESERVED_SIZE "#define" in sg.h 955 | is suitable for this purpose (ie its presence indicates the new sg driver 956 | while its absence indicates the original). 957 | 958 | Run time selection is more flexible and can be based on whether a 959 | simple ioctl() command works or not. This is best demonstrated by 960 | a code fragment: 961 | 962 | #ifndef SG_GET_RESERVED_SIZE 963 | #define SG_GET_RESERVED_SIZE 0x2272 964 | #endif 965 | 966 | /* Assume sg device open and fd is called 'sg_fd' */ 967 | 968 | int reserved_size = 0; 969 | if (ioctl(sg_fd, SG_GET_RESERVED_SIZE, &reserved_size) < 0) { 970 | reserved_size = SG_BIG_BUFF; 971 | /* So we have the original sg driver ... */ 972 | ......... 973 | } 974 | else { 975 | /* So we have the new enhanced sg driver */ 976 | if (reserved_size <= 4096) 977 | /* Probably should not be cutting CDs with this fd ... */ 978 | ......... 979 | } 980 | 981 | As of sg version 2.1.36 an ioctl() called SG_GET_VERSION_NUM has been 982 | added. It yields the version with 2 decimal digits per component. Hence 983 | 20136 is the value associated with version 2.1.36 . The ioctl SG_SET_DEBUG 984 | outputs a version string to the console/log file (amongst other information). 985 | 986 | Map of SG verions to the Linux kernels in which they appear: 987 | ---------- ---------------------------------- 988 | original all kernels < 2.2.6 989 | 2.1.31 2.2.6 and 2.2.7 990 | 2.1.32 2.2.8 and 2.2.9 991 | 2.1.34 2.2.10 to 2.2.13 992 | 2.1.36 2.2.14 and 2.2.15 993 | 2.1.38 2.2.16 994 | 3.0.15 optional version 3 sg driver for 2.2 series 995 | 3.1.15 late 2.3 series approaching 2.4 996 | 997 | 998 | SG_BIG_BUFF and friends 999 | ======================= 1000 | Open source seems to attract people who like to tweak the source code 1001 | to get (a little) extra performance. In the case of the original 1002 | sg driver this meant increasing the value of the #define SG_BIG_BUFF 1003 | to the maximum value of (32 * PAGE_SIZE). Even the writers of the major 1004 | applications based on sg could not resist suggesting such a modification 1005 | to the users. Worse still, their applications acted on that value. 1006 | 1007 | In the original sg driver the SG_BIG_BUFF value modified the behaviour of 1008 | the sg driver (see "memory issues" section) and many applications based on 1009 | sg used it as well. In this driver SG_BIG_BUFF is _not_ used internally by 1010 | the driver. In a sense it has been decoupled. 1011 | 1012 | There are 3 relevant "#define"s in this driver (found in ): 1013 | 1014 | #define SG_SCATTER_SZ (8 * 4096) 1015 | #define SG_DEF_RESERVED_SIZE SG_SCATTER_SZ 1016 | #define SG_BIG_BUFF SG_DEF_RESERVED_SIZE 1017 | 1018 | SG_SCATTER_SZ is the size of the largest contiguous piece of kernel memory 1019 | that the driver will attempt to obtain. It has that value for backward 1020 | compatibility. If a SCSI host adapter does not support scatter gather then 1021 | it represents the largest buffer than can be used. If anything its value 1022 | should be reduced! Best to leave it alone. 1023 | 1024 | SG_DEF_RESERVED_SIZE is the size of the reserved buffer that the driver 1025 | will attempt to obtain on open(). If you have plenty of memory on your 1026 | box, a PCI SCSI adapter that does scatter gather, then this is the one 1027 | to play with. Try it at 512KB (524288) and see what happens. If you 1028 | wish to find the scatter gather table size for your SCSI adapter then 1029 | you can use the sg utility 'sg_whoami ' and look at the value 1030 | of sg_tablesize. If it is 0 then your SCSI adapter does not support 1031 | scatter gather. If it is > 0 then the maximum (theoretical) sized buffer 1032 | that can be obtained is (sg_tablesize * SG_SCATTER_SZ). This could be 1033 | a large number (eg 8MB on this machine) and it probably makes no sense 1034 | to try and obtain such a large buffer. 1035 | 1036 | SG_BIG_BUFF is not used internally by the driver. As can be seen above 1037 | it is set to the same value as SG_DEF_RESERVED_SIZE. This can be changed 1038 | with no adverse effect on the driver. However changing its value may well 1039 | affect a sg-based application compiled using it. Changing its value to be 1040 | larger than SG_DEF_RESERVED_SIZE may not be a good idea for some classes 1041 | of applications (eg those that burn CDs). In this case the reserved 1042 | buffer will often not be large enough forcing each write() to attempt to 1043 | find memory; an attempt that may fail with ENOMEM in adverse situations. 1044 | 1045 | There is a variable in the "proc" pseudo file system related to the 1046 | sg device. It is only visible when sg is built into the kernel (ie 1047 | not when it is a module). It can be accessed with: 1048 | # cat /proc/sys/kernel/sg-big-buf 1049 | and if present yields the size of the reserved buffer of the most recently 1050 | opened sg device. It is deprecated as this information is available 1051 | from the SG_GET_RESERVED_SIZE ioctl(). It only remains for backward 1052 | compatibility. 1053 | 1054 | 1055 | Shortcomings 1056 | ============ 1057 | Most real world programs need to make compromises to be implementable 1058 | and usable. Very little software works in a vacuum especially device 1059 | drivers. Sg is constrained by its former interface, the capabilities 1060 | of Linux and the services offered by the Linux SCSI mid level layer. 1061 | 1062 | Taking the last point first, the mid level layer is the unifying layer. 1063 | It defines most of the interfaces for both the high level drivers 1064 | (ie sd, st, sr and sg) and the low level drivers (host adapters of which 1065 | there are 50 or more). Given that investment, especially in those low 1066 | level drivers, changing the mid level's interfaces is not something 1067 | that is done lightly. It is planned that the next major changes to 1068 | occur in that area will be in the Linux 2.3 development kernel project. 1069 | 1070 | The following shortcomings are listed in point form: 1071 | - the sense buffer array is only 16 bytes long which seems to have 1072 | come from SCSI 1 days. SCSI 2 requires a minimum of 18 bytes and 1073 | preferably 32 bytes. 1074 | - the actual number of bytes transferred to or from the device (eg 1075 | SCSI write or read respectively) is not reported. This transfer 1076 | is typically done by DMA independently of the main processor. 1077 | Underruns and overruns are potentially silently ignored. 1078 | - there is no (non-deprecated) way to send a device or a bus 1079 | reset (which may be a blessing in disguise). 1080 | - there is no (non-deprecated) way to abort an unfinished command 1081 | or shorten its timeout. A Unix close() can occur at any time 1082 | and coping with unfinished commands adds considerable complexity 1083 | to the device driver. 1084 | - the O_EXCL lock only prevents access by others via a sg device 1085 | handle. Users may still be able to access that device via sd, 1086 | st or sr (ie the other 3 high level SCSI device drivers). 1087 | 1088 | Some people would prefer a unified space for SCSI device handles in 1089 | which packet commands could be sent to a disk via /dev/sd? or a cdrom 1090 | via /dev/sr? , for example. It is interesting that this was previously 1091 | attempted in Linux and some remnants still remain (eg the ioctl 1092 | SCSI_IOCTL_SEND_COMMAND) but has comments indicating it is deprecated. 1093 | There are arguments both ways, but from a device driver writer's 1094 | point of view a separate character driver controlling its owns state 1095 | is probably easier, making command queuing, non-blocking operation and 1096 | asynchronous notification easier to implement. Remember also that Linux 1097 | does not have the block+raw device handle model of some other Unixes. 1098 | The downside of the separate space is that each SCSI device potentially 1099 | appears as 2 device handles (eg often /dev/sda and /dev/sg0 will be the 1100 | same device). Note that devices such as scanners will only be found in 1101 | the "sg space". The difficulty for those devices that appear in both is 1102 | what is the mapping. Various ioctls in this driver can be used to 1103 | determine what this mapping is. Ultimately the introduction of the 1104 | devfs pseudo file system will make this easier. 1105 | 1106 | 1107 | Future Directions 1108 | ================= 1109 | One area that may warrant investigation is "direct IO" which bypasses 1110 | the double handling of data between the kernel buffers and the user 1111 | space. This is not as simple as it seems and only one Linux driver 1112 | (bttv) is currently using this technique. Recent experiments indicate 1113 | that the maximum throughput of the sg driver run on typical hardware is 1114 | about 20MBytes per second. This is more than sufficient for most current 1115 | sg-based applications. Some people are interested in significantly 1116 | higher bandwidths (eg 100MB per second) and for this direct IO would 1117 | be required. If this sg driver was to be used for both existing 1118 | "indirect IO"-based applications and "direct IO" experimentation 1119 | then the latter would (most likely) be having a significantly different 1120 | "sg_header" structure. This could be distinguished by having a negative 1121 | number in its second integer position (ie 'reply_len's position). 1122 | 1123 | Investigate CAM (in FreeBSD 3.2). 1124 | 1125 | 1126 | References 1127 | ========== 1128 | http://www.t10.org Very important site for SCSI related information. 1129 | Contains SCSI 2 and 3 draft standards. 1130 | http://www.andante.org/scsi.html 1131 | This is Eric Youngdale's site. Eric is primarily 1132 | responsible for the Linux SCSI architecture and 1133 | its mid-level implementation. 1134 | http://www.kernel.dk Jens Axboe's site for Linux cdrom matters including 1135 | the SCSI "sr" driver. 1136 | http://www.torque.net/sg 1137 | My site with sg related information. 1138 | newsgroup:linux-scsi@vger.kernel.org 1139 | Newsgroup for Linux related SCSI matters 1140 | /usr/src/linux/MAINTAINERS 1141 | This is a file in the Linux kernel source that 1142 | contains up to date information about who maintains 1143 | what and where information can be found. Links to 1144 | SCSI adapter information are also here. 1145 | 1146 | 1147 | Conclusion 1148 | ========== 1149 | The SCSI generic packet device driver attempts to make as few assumptions 1150 | as possible about the device it is connected to while giving applications 1151 | using it as much flexibility as possible on the SCSI command level. Sg 1152 | needs to hide the "messy" kernel related details while protecting 1153 | the integrity of the kernel against sg "abuse". Some of these aims are 1154 | contradictory and some compromises need to be made. For example: should 1155 | a sg based application be able to reset a SCSI bus when that could cause 1156 | collateral damage to a disk holding the root file system? There is no 1157 | easy answer to this and many other related questions. 1158 | 1159 | If you have any suggestion about sg (or improving (the accuracy of) this 1160 | document) please contact me. 1161 | 1162 | 1163 | 1164 | 1165 | 1166 | 1167 | Appendix 1168 | ======== 1169 | The following ASCII art is obtained from draft copies (and copies of 1170 | copies) of the SCSI 2 standard. Hopefully they are accurate. 1171 | 1172 | Summary of SCSI commands 1173 | ------------------------ 1174 | Shown are group 0, 1, 2 and 5 commands. [The "group" is the top 3 bits 1175 | of the SCSI command byte.] The other groups (3, 4, 6 or 7) are reserved 1176 | or vendor specific. 1177 | 1178 | SCSI-2 Operation Codes 1179 | 1180 | +=========================================================================+ 1181 | | D - DIRECT ACCESS DEVICE Device Column Key | 1182 | | .T - SEQUENTIAL ACCESS DEVICE M = Mandatory | 1183 | | . L - PRINTER DEVICE O = Optional | 1184 | | . P - PROCESSOR DEVICE V = Vendor Specific| 1185 | | . .W - WRITE ONCE READ MULTIPLE DEVICE R = Reserved | 1186 | | . . R - READ ONLY (CD-ROM) DEVICE . = Place holder | 1187 | | . . S - SCANNER DEVICE | 1188 | | . . .O - OPTICAL MEMORY DEVICE | 1189 | | . . . M - MEDIA CHANGER DEVICE | 1190 | | . . . C - COMMUNICATION DEVICE | 1191 | | . . . . | 1192 | | OP DTLPWRSOMC Description | 1193 | |----------+----------+---------------------------------------------------| 1194 | | 00 MMMMMMMMMM TEST UNIT READY | 1195 | | 01 M REWIND | 1196 | | 01 O V OO OO REZERO UNIT | 1197 | | 02 VVVVVV V | 1198 | | 03 MMMMMMMMMM REQUEST SENSE | 1199 | | 04 O FORMAT | 1200 | | 04 M O FORMAT UNIT | 1201 | | 05 VMVVVV V READ BLOCK LIMITS | 1202 | | 06 VVVVVV V | 1203 | | 07 O INITIALIZE ELEMENT STATUS | 1204 | | 07 OVV O OV REASSIGN BLOCKS | 1205 | | 08 .........M GET MESSAGE(06) | 1206 | | 08 OMV OO OV READ(06) | 1207 | | 08 O RECEIVE | 1208 | | 09 VVVVVV V | 1209 | | 0A M PRINT | 1210 | | 0A M SEND MESSAGE(06) | 1211 | | 0A M SEND(06) | 1212 | | 0A OM O OV WRITE(06) | 1213 | | 0B O OO OV SEEK(06) | 1214 | | 0B O SLEW AND PRINT | 1215 | | 0C VVVVVV V | 1216 | | 0D VVVVVV V | 1217 | | 0E VVVVVV V | 1218 | | 0F VOVVVV V READ REVERSE | 1219 | | 10 ..O.O..... SYNCHRONIZE BUFFER | 1220 | | 10 VM VVV WRITE FILEMARKS | 1221 | | 11 VMVVVV SPACE | 1222 | | 12 MMMMMMMMMM INQUIRY | 1223 | | 13 VOVVVV VERIFY(06) | 1224 | | 14 VOOVVV RECOVER BUFFERED DATA | 1225 | | 15 OMO OOOOOO MODE SELECT(06) | 1226 | | 16 M MM MO RESERVE | 1227 | | 16 MM M RESERVE UNIT | 1228 | | 17 M MM MO RELEASE | 1229 | | 17 MM M RELEASE UNIT | 1230 | | 18 OOOOOOOO.. COPY | 1231 | | 19 VMVVVV ERASE | 1232 | | 1A OMO OOOOOO MODE SENSE(06) | 1233 | | 1B O LOAD UNLOAD | 1234 | | 1B O SCAN | 1235 | | 1B O STOP PRINT | 1236 | | 1B O OO O STOP START UNIT | 1237 | | 1C OOOOOOOOOO RECEIVE DIAGNOSTIC RESULTS | 1238 | | 1D MMMMMMMMMM SEND DIAGNOSTIC | 1239 | | 1E OO OO OO PREVENT ALLOW MEDIUM REMOVAL | 1240 | | 1F | 1241 | |----------+----------+---------------------------------------------------| 1242 | | OP DTLPWRSOMC Description | 1243 | |----------+----------+---------------------------------------------------| 1244 | | 20 V VV V | 1245 | | 21 V VV V | 1246 | | 22 V VV V | 1247 | | 23 V VV V | 1248 | | 24 V VVM SET WINDOW | 1249 | | 25 O GET WINDOW | 1250 | | 25 M M M READ CAPACITY | 1251 | | 25 M READ CD-ROM CAPACITY | 1252 | | 26 V VV | 1253 | | 27 V VV | 1254 | | 28 .........O GET MESSAGE(10) | 1255 | | 28 M MMMM READ(10) | 1256 | | 29 V VV O READ GENERATION | 1257 | | 2A O SEND MESSAGE(10) | 1258 | | 2A O SEND(10) | 1259 | | 2A M M M WRITE(10) | 1260 | | 2B O LOCATE | 1261 | | 2B O POSITION TO ELEMENT | 1262 | | 2B O OO O SEEK(10) | 1263 | | 2C V O ERASE(10) | 1264 | | 2D V O O READ UPDATED BLOCK | 1265 | | 2E O O O WRITE AND VERIFY(10) | 1266 | | 2F O OO O VERIFY(10) | 1267 | | 30 O...OO.O.. SEARCH DATA HIGH(10) | 1268 | | 31 O OBJECT POSITION | 1269 | | 31 O OO O SEARCH DATA EQUAL(10) | 1270 | | 32 O OO O SEARCH DATA LOW(10) | 1271 | | 33 O OO O SET LIMITS(10) | 1272 | | 34 O GET DATA BUFFER STATUS | 1273 | | 34 O OO O PRE-FETCH | 1274 | | 34 O READ POSITION | 1275 | | 35 O OO O SYNCHRONIZE CACHE | 1276 | | 36 O OO O LOCK UNLOCK CACHE | 1277 | | 37 O O READ DEFECT DATA(10) | 1278 | | 38 ....O..O.. MEDIUM SCAN | 1279 | | 39 OOOOOOOO COMPARE | 1280 | | 3A OOOOOOOO COPY AND VERIFY | 1281 | | 3B OOOOOOOOOO WRITE BUFFER | 1282 | | 3C OOOOOOOOOO READ BUFFER | 1283 | | 3D O O UPDATE BLOCK | 1284 | | 3E O OO O READ LONG | 1285 | | 3F O O O WRITE LONG | 1286 | |----------+----------+---------------------------------------------------| 1287 | | OP DTLPWRSOMC Description | 1288 | |----------+----------+---------------------------------------------------| 1289 | | 40 OOOOOOOOOO CHANGE DEFINITION | 1290 | | 41 O WRITE SAME | 1291 | | 42 O READ SUB-CHANNEL | 1292 | | 43 O READ TOC | 1293 | | 44 O READ HEADER | 1294 | | 45 O PLAY AUDIO(10) | 1295 | | 46 | 1296 | | 47 O PLAY AUDIO MSF | 1297 | | 48 .....O.... PLAY AUDIO TRACK INDEX | 1298 | | 49 O PLAY TRACK RELATIVE(10) | 1299 | | 4A | 1300 | | 4B O PAUSE RESUME | 1301 | | 4C OOOOOOOOOO LOG SELECT | 1302 | | 4D OOOOOOOOOO LOG SENSE | 1303 | | 4E | 1304 | | 4F | 1305 | | 50 .......... | 1306 | | 51 | 1307 | | 52 | 1308 | | 53 | 1309 | | 54 | 1310 | | 55 OOO OOOOOO MODE SELECT(10) | 1311 | | 56 | 1312 | | 57 | 1313 | | 58 .......... | 1314 | | 59 | 1315 | | 5A OOO OOOOOO MODE SENSE(10) | 1316 | | 5B | 1317 | | 5C | 1318 | | 5D | 1319 | | 5E | 1320 | | 5F | 1321 | |----------+----------+---------------------------------------------------| 1322 | | OP DTLPWRSOMC Description | 1323 | |----------+----------+---------------------------------------------------| 1324 | | A0 | 1325 | | A1 | 1326 | | A2 | 1327 | | A3 | 1328 | | A4 | 1329 | | A5 M MOVE MEDIUM | 1330 | | A5 O PLAY AUDIO(12) | 1331 | | A6 O EXCHANGE MEDIUM | 1332 | | A7 | 1333 | | A8 O GET MESSAGE(12) | 1334 | | A8 OO O READ(12) | 1335 | | A9 O PLAY TRACK RELATIVE(12) | 1336 | | AA O SEND MESSAGE(12) | 1337 | | AA O O WRITE(12) | 1338 | | AB | 1339 | | AC O ERASE(12) | 1340 | | AD | 1341 | | AE O O WRITE AND VERIFY(12) | 1342 | | AF OO O VERIFY(12) | 1343 | | B0 ....OO.O.. SEARCH DATA HIGH(12) | 1344 | | B1 OO O SEARCH DATA EQUAL(12) | 1345 | | B2 OO O SEARCH DATA LOW(12) | 1346 | | B3 OO O SET LIMITS(12) | 1347 | | B4 | 1348 | | B5 | 1349 | | B5 O REQUEST VOLUME ELEMENT ADDRESS | 1350 | | B6 | 1351 | | B6 O SEND VOLUME TAG | 1352 | | B7 O READ DEFECT DATA(12) | 1353 | | B8 | 1354 | | B8 O READ ELEMENT STATUS | 1355 | | B9 | 1356 | | BA | 1357 | | BB | 1358 | | BC | 1359 | | BD | 1360 | | BE | 1361 | | BF | 1362 | |----------+----------+---------------------------------------------------| 1363 | | OP DTLPWRSOMC Description | 1364 | +=========================================================================+ 1365 | 1366 | 1367 | 1368 | Example of a SCSI command: READ(10) [for a direct access device] 1369 | ---------------------------------------------------------------- 1370 | As an example, here is probably the most common SCSI command sent to 1371 | a direct access device. Given a 512 byte block size it can access 1372 | anywhere on a 2 TeraByte disk from 1 to 65535 contiguous blocks 1373 | (ie a maximum of 32 MBytes). That should satisfy most requirements. 1374 | 1375 | 1376 | ============================================================================== 1377 | Bit| 7 | 6 | 5 | 4 | 3 | 2 | 1 | 0 | 1378 | Byte | | | | | | | | | 1379 | ============================================================================== 1380 | 0 | READ(10) Operation Code (28h) | 1381 | -----|-----------------------------------------------------------------------| 1382 | 1 | Logical Unit Number | DPO | FUA | Reserved | RelAdr | 1383 | -----|-----------------------------------------------------------------------| 1384 | 2 | (MSB) | 1385 | - - -|- - Logical Block Address - -| 1386 | 5 | (LSB) | 1387 | -----|-----------------------------------------------------------------------| 1388 | 6 | Reserved | 1389 | -----|-----------------------------------------------------------------------| 1390 | 7 | (MSB) | 1391 | -----|--- Transfer Length | 1392 | 8 | (LSB) | 1393 | -----|-----------------------------------------------------------------------| 1394 | 9 | Control | 1395 | ============================================================================== 1396 | 1397 | "A disable page out (DPO) bit of one indicates that the target shall assign 1398 | the logical blocks accessed by this command the lowest priority for being 1399 | fetched into or retained by the cache." 1400 | 1401 | "A force unit access (FUA) bit of one indicates that the target shall access 1402 | the media in performing the command prior to returning GOOD status." 1403 | 1404 | The 'Control' byte and other 'Reserved' fields should be set to 0 in 1405 | commands passed to sg. The 'Logical Unit Number' is set internally by 1406 | the sg driver so any value given by the user is overwritten. 1407 | 1408 | 1409 | 1410 | Example of a SCSI command: INQUIRY 1411 | ---------------------------------- 1412 | It is mandatory that all SCSI targets (ie devices) support this command. 1413 | 1414 | ============================================================================== 1415 | Bit| 7 | 6 | 5 | 4 | 3 | 2 | 1 | 0 | 1416 | Byte | | | | | | | | | 1417 | ============================================================================== 1418 | 0 | INQUIRY Operation Code (12h) | 1419 | -----|-----------------------------------------------------------------------| 1420 | 1 | Logical Unit Number | Reserved | EVPD | 1421 | -----|-----------------------------------------------------------------------| 1422 | 2 | Page Code | 1423 | -----|-----------------------------------------------------------------------| 1424 | 3 | Reserved | 1425 | -----|-----------------------------------------------------------------------| 1426 | 4 | Allocation Length | 1427 | -----|-----------------------------------------------------------------------| 1428 | 5 | Control | 1429 | ============================================================================== 1430 | 1431 | 1432 | "An enable vital product data (EVPD) bit of one specifies that the target 1433 | shall return the optional vital product data specified by the page code field. 1434 | ... An EVPD bit of zero specifies that the target shall return the standard 1435 | INQUIRY data." 1436 | 1437 | Unless EVPD is set 'Page Code' should be 0. 1438 | 1439 | "The allocation length field specifies the maximum number of bytes that an 1440 | initiator has allocated for returned data." 36 bytes of returned data are 1441 | mandated by the standard as shown by the following table: 1442 | 1443 | ============================================================================== 1444 | Bit| 7 | 6 | 5 | 4 | 3 | 2 | 1 | 0 | 1445 | Byte | | | | | | | | | 1446 | ============================================================================== 1447 | 0 | Peripheral Qualifier | Peripheral Device Type | 1448 | -----|-----------------------------------------------------------------------| 1449 | 1 | RMB | Device-Type Modifier | 1450 | -----|-----------------------------------------------------------------------| 1451 | 2 | ISO Version | ECMA Version | ANSI-Approved Version | 1452 | -----|-----------------------------------------------------------------------| 1453 | 3 | AENC | TrmIOP | Reserved | Response Data Format | 1454 | -----|-----------------------------------------------------------------------| 1455 | 4 | Additional Length (n-4) | 1456 | -----|-----------------------------------------------------------------------| 1457 | 5 | Reserved | 1458 | -----|-----------------------------------------------------------------------| 1459 | 6 | Reserved | 1460 | -----|-----------------------------------------------------------------------| 1461 | 7 | RelAdr | WBus32 | WBus16 | Sync | Linked |Reserved| CmdQue | SftRe | 1462 | -----|-+---------------------------------------------------------------------| 1463 | 8 | (MSB) | 1464 | - - -|- - Vendor Identification - -| 1465 | 15 | (LSB) | 1466 | -----|-+---------------------------------------------------------------------| 1467 | 16 | (MSB) | 1468 | - - -|- - Product Identification - -| 1469 | 31 | (LSB) | 1470 | -----|-+---------------------------------------------------------------------| 1471 | 32 | (MSB) | 1472 | - - -|- - Product Revision Level - -| 1473 | 35 | (LSB) | 1474 | -----|-+---------------------------------------------------------------------| 1475 | 36 | | 1476 | - - -|- - Vendor Specific - -| 1477 | 55 | | 1478 | -----|-+---------------------------------------------------------------------| 1479 | 56 | | 1480 | - - -|- - Reserved - -| 1481 | 95 | | 1482 | ============================================================================== 1483 | | Vendor-Specific Parameters | 1484 | ============================================================================== 1485 | 96 to| Vendor-Specific | 1486 | n | Parameter Bytes | 1487 | ============================================================================== 1488 | 1489 | 1490 | SCSI Status Byte 1491 | ---------------- 1492 | SCSI commands return a status byte. It is related to but not exactly the 1493 | same as the 'target_status' placed in the sg_header structure passed to 1494 | the user when a sg device handle is read(). The difference is that the 1495 | SCSI status byte has its reserved bits masked off and it is shifted once 1496 | right to yield the 5 bit number (ie in the range 0 to 31) that is 1497 | 'target_status'. The use of such a masked and shifted 'target_status" seems 1498 | to be the intention of earlier Linux SCSI designers since the "Status codes" 1499 | defines in are then appropriate (eg "#define CHECK_CONDITION 1500 | 0x01"). The following table and explanation is from the SCSI 2 standard: 1501 | 1502 | +=================================-==============================+ 1503 | | Bits of Status Byte | Status | 1504 | | 7 6 5 4 3 2 1 0 | | 1505 | |---------------------------------+------------------------------| 1506 | | R R 0 0 0 0 0 R | GOOD | 1507 | | R R 0 0 0 0 1 R | CHECK CONDITION | 1508 | | R R 0 0 0 1 0 R | CONDITION MET | 1509 | | R R 0 0 1 0 0 R | BUSY | 1510 | | R R 0 1 0 0 0 R | INTERMEDIATE | 1511 | | R R 0 1 0 1 0 R | INTERMEDIATE-CONDITION MET | 1512 | | R R 0 1 1 0 0 R | RESERVATION CONFLICT | 1513 | | R R 1 0 0 0 1 R | COMMAND TERMINATED | 1514 | | R R 1 0 1 0 0 R | QUEUE FULL | 1515 | | | | 1516 | | All Other Codes | Reserved | 1517 | |----------------------------------------------------------------| 1518 | | Key: R = Reserved bit | 1519 | +================================================================+ 1520 | 1521 | GOOD. This status indicates that the target has successfully completed the 1522 | command. 1523 | 1524 | CHECK CONDITION. This status indicates that a contingent allegiance 1525 | condition has occurred. [This means the sense_buffer has been ouput.] 1526 | 1527 | CONDITION MET. This status or INTERMEDIATE-CONDITION MET is returned whenever 1528 | the requested operation is satisfied (see the SEARCH DATA and PRE-FETCH 1529 | commands). 1530 | 1531 | BUSY. This status indicates that the target is busy. This status shall be 1532 | returned whenever a target is unable to accept a command from an otherwise 1533 | acceptable initiator (i.e., no reservation conflicts). The recommended 1534 | initiator recovery action is to issue the command again at a later time. 1535 | 1536 | INTERMEDIATE. This status or INTERMEDIATE-CONDITION MET shall be returned for 1537 | every successfully completed command in a series of linked commands (except 1538 | the last command), unless the command is terminated with CHECK CONDITION, 1539 | RESERVATION CONFLICT, or COMMAND TERMINATED status. If INTERMEDIATE or 1540 | INTERMEDIATE-CONDITION MET status is not returned, the series of linked 1541 | commands is terminated and the I/O process is ended. 1542 | 1543 | INTERMEDIATE-CONDITION MET. This status is the combination of the CONDITION 1544 | MET and INTERMEDIATE statuses. 1545 | 1546 | RESERVATION CONFLICT. This status shall be returned whenever an initiator 1547 | attempts to access a logical unit or an extent within a logical unit that is 1548 | reserved with a conflicting reservation type for another SCSI device (see the 1549 | RESERVE and RESERVE UNIT commands). The recommended initiator recovery action 1550 | is to issue the command again at a later time. 1551 | 1552 | COMMAND TERMINATED. This status shall be returned whenever the target 1553 | terminates the current I/O process after receiving a TERMINATE I/O PROCESS 1554 | message (see 5.6.22). This status also indicates that a contingent allegiance 1555 | condition has occurred. [This means the sense_buffer has been output.] 1556 | 1557 | QUEUE FULL. This status shall be implemented if tagged queuing is 1558 | implemented. This status is returned when a SIMPLE QUEUE TAG, ORDERED QUEUE 1559 | TAG, or HEAD OF QUEUE TAG message is received and the command queue is full. 1560 | The I/O process is not placed in the command queue. 1561 | 1562 | 1563 | Note that there are 2 status codes indicating the 'sense_buffer' is output: 1564 | CHECK CONDITION and COMMAND TERMINATED. In addition, the 'sense_buffer' is 1565 | also written when the DRIVER_SENSE mask is set in the 'driver_status'. 1566 | The latter case occurs in Linux since low level drivers that emulate a 1567 | SCSI device (eg ide-scsi) have problems "faking" the status code. 1568 | 1569 | Also CHECK CONDITION does not necessarily imply an error. For example, 1570 | if the associated "sense key" (found in (sense_buffer[2] & 0xf)) is 1571 | RECOVERED_ERROR then the requested SCSI command was completed 1572 | successfully after the target (device) performed some remedial action. 1573 | 1574 | 1575 | SCSI Sense buffer 1576 | ----------------- 1577 | As noted above the 'sense_buffer' is output (and accessed via a read()) 1578 | when 'target_status' is CHECK_CONDITION or COMMAND_TERMINATED or when 1579 | ('driver_status' & DRIVER_SENSE) is true. Only 16 of the required 18 1580 | bytes of the sense buffer are output. 1581 | 1582 | What actually happens is that when a SCSI target (device) returns a SCSI 1583 | status code indicating the sense buffer needs to be checked, the Linux 1584 | SCSI mid level automatically issues a follow up SCSI REQUEST SENSE command 1585 | and conveys the ouput of this command (ie the truncated sense buffer) back 1586 | to the 'sense_buffer' in sg's sg_header structure and thus back to the user 1587 | via a read() call. [When a SCSI device is being emulated things are 1588 | obviously a bit different.] 1589 | 1590 | The sense buffer returned by the REQUEST SENSE command looks like this: 1591 | 1592 | ============================================================================== 1593 | Bit| 7 | 6 | 5 | 4 | 3 | 2 | 1 | 0 | 1594 | Byte | | | | | | | | | 1595 | ============================================================================== 1596 | 0 | Valid | Error Code (70h or 71h) | 1597 | -----|-----------------------------------------------------------------------| 1598 | 1 | Segment Number | 1599 | -----|-----------------------------------------------------------------------| 1600 | 2 |Filemark| EOM | ILI |Reserved| Sense Key | 1601 | -----|-----------------------------------------------------------------------| 1602 | 3 | (MSB) | 1603 | - - -|- - Information - -| 1604 | 6 | (LSB) | 1605 | -----|-----------------------------------------------------------------------| 1606 | 7 | Additional Sense Length (n-7) | 1607 | -----|-----------------------------------------------------------------------| 1608 | 8 | (MSB) | 1609 | - - -|- - Command-Specific Information - -| 1610 | 11 | (LSB) | 1611 | -----|-----------------------------------------------------------------------| 1612 | 12 | Additional Sense Code [ASC] | 1613 | -----|-----------------------------------------------------------------------| 1614 | 13 | Additional Sense Code Qualifier [ASCQ] | 1615 | -----|-----------------------------------------------------------------------| 1616 | 14 | Field Replaceable Unit Code | 1617 | -----|-----------------------------------------------------------------------| 1618 | 15 to| SKSV | | 1619 | - - -|---------- - Sense-Key Specific - -| 1620 | 17 | | 1621 | -----|-----------------------------------------------------------------------| 1622 | 18 to| | 1623 | - - -|- - Additional Sense Bytes - -| 1624 | n | | 1625 | ============================================================================== 1626 | 1627 | This is a complicated beast and the reader is referred to the SCSI 2 1628 | standard for the complete interpretation. A brief summary of the important 1629 | fields and some rather long tables follow. 1630 | 1631 | The 'Valid' but is rather deceptively named and just indicates whether 1632 | the Information field has anything in it and if so whether that value 1633 | conforms with the standard. The important fields are the Sense Key, the 1634 | Additional Sense Code (ASC) and the Additional Sense Code Qualifier (ASCQ) 1635 | in that order. The Sense Key values follow: 1636 | 1637 | ============================================================================== 1638 | Sense Key Description 1639 | --------- ------------------------------------------------------------------- 1640 | 0h NO SENSE. Indicates that there is no specific sense key 1641 | information to be reported for the designated logical unit. This 1642 | would be the case for a successful command or a command that 1643 | received CHECK CONDITION or COMMAND TERMINATED status because one 1644 | of the filemark, EOM, or ILI bits is set to one. 1645 | 1646 | 1h RECOVERED ERROR. Indicates that the last command completed 1647 | successfully with some recovery action performed by the target. 1648 | Details may be determinable by examining the additional sense bytes 1649 | and the information field. When multiple recovered errors occur 1650 | during one command, the choice of which error to report (first, 1651 | last, most severe, etc.) is device specific. 1652 | 1653 | 2h NOT READY. Indicates that the logical unit addressed cannot be 1654 | accessed. Operator intervention may be required to correct this 1655 | condition. 1656 | 1657 | 3h MEDIUM ERROR. Indicates that the command terminated with a non- 1658 | recovered error condition that was probably caused by a flaw in the 1659 | medium or an error in the recorded data. This sense key may also 1660 | be returned if the target is unable to distinguish between a flaw 1661 | in the medium and a specific hardware failure (sense key 4h). 1662 | 1663 | 4h HARDWARE ERROR. Indicates that the target detected a non- 1664 | recoverable hardware failure (for example, controller failure, 1665 | device failure, parity error, etc.) while performing the command or 1666 | during a self test. 1667 | 1668 | 5h ILLEGAL REQUEST. Indicates that there was an illegal parameter in 1669 | the command descriptor block or in the additional parameters 1670 | supplied as data for some commands (FORMAT UNIT, SEARCH DATA, 1671 | etc.). If the target detects an invalid parameter in the command 1672 | descriptor block, then it shall terminate the command without 1673 | altering the medium. If the target detects an invalid parameter in 1674 | the additional parameters supplied as data, then the target may 1675 | have already altered the medium. This sense key may also indicate 1676 | that an invalid IDENTIFY message was received (5.6.7). 1677 | 1678 | 6h UNIT ATTENTION. Indicates that the removable medium may have been 1679 | changed or the target has been reset. See 6.9 for more detailed 1680 | information about the unit attention condition. 1681 | 1682 | 7h DATA PROTECT. Indicates that a command that reads or writes the 1683 | medium was attempted on a block that is protected from this 1684 | operation. The read or write operation is not performed. 1685 | 1686 | 8h BLANK CHECK. Indicates that a write-once device or a sequential- 1687 | access device encountered blank medium or format-defined end-of- 1688 | data indication while reading or a write-once device encountered a 1689 | non-blank medium while writing. 1690 | 1691 | 9h Vendor Specific. This sense key is available for reporting vendor 1692 | specific conditions. 1693 | 1694 | Ah COPY ABORTED. Indicates a COPY, COMPARE, or COPY AND VERIFY 1695 | command was aborted due to an error condition on the source device, 1696 | the destination device, or both. (See 7.2.3.2 for additional 1697 | information about this sense key.) 1698 | 1699 | Bh ABORTED COMMAND. Indicates that the target aborted the command. 1700 | The initiator may be able to recover by trying the command again. 1701 | 1702 | Ch EQUAL. Indicates a SEARCH DATA command has satisfied an equal 1703 | comparison. 1704 | 1705 | Dh VOLUME OVERFLOW. Indicates that a buffered peripheral device has 1706 | reached the end-of-partition and data may remain in the buffer that 1707 | has not been written to the medium. A RECOVER BUFFERED DATA 1708 | command(s) may be issued to read the unwritten data from the 1709 | buffer. 1710 | 1711 | Eh MISCOMPARE. Indicates that the source data did not match the data 1712 | read from the medium. 1713 | 1714 | Fh RESERVED. 1715 | 1716 | ============================================================================== 1717 | 1718 | 1719 | 2 long tables of Additional Sense Codes (ASC) and their associated Additional 1720 | Sense Code Qualifiers (ASCQ) follow. The same information is presented in 2 1721 | forms: first in numerical order (by ASC then ASCQ) and then in alphabetical 1722 | order (by description). 1723 | 1724 | ASC and ASCQ in numerical order 1725 | +============================================================================+ 1726 | | D - DIRECT ACCESS DEVICE | 1727 | | .T - SEQUENTIAL ACCESS DEVICE | 1728 | | . L - PRINTER DEVICE | 1729 | | . P - PROCESSOR DEVICE | 1730 | | . .W - WRITE ONCE READ MULTIPLE DEVICE | 1731 | | . . R - READ ONLY (CD-ROM) DEVICE | 1732 | | . . S - SCANNER DEVICE | 1733 | | . . .O - OPTICAL MEMORY DEVICE | 1734 | | . . . M - MEDIA CHANGER DEVICE | 1735 | | . . . C - COMMUNICATION DEVICE | 1736 | | . . . . | 1737 | | ASC ASCQ DTLPWRSOMC DESCRIPTION | 1738 | | --- ---- -----------------------------------------------------| 1739 | | 00 00 DTLPWRSOMC NO ADDITIONAL SENSE INFORMATION | 1740 | | 00 01 T FILEMARK DETECTED | 1741 | | 00 02 T S END-OF-PARTITION/MEDIUM DETECTED | 1742 | | 00 03 T SETMARK DETECTED | 1743 | | 00 04 T S BEGINNING-OF-PARTITION/MEDIUM DETECTED | 1744 | | 00 05 T S END-OF-DATA DETECTED | 1745 | | 00 06 DTLPWRSOMC I/O PROCESS TERMINATED | 1746 | | 00 11 R AUDIO PLAY OPERATION IN PROGRESS | 1747 | | 00 12 R AUDIO PLAY OPERATION PAUSED | 1748 | | 00 13 R AUDIO PLAY OPERATION SUCCESSFULLY COMPLETED | 1749 | | 00 14 R AUDIO PLAY OPERATION STOPPED DUE TO ERROR | 1750 | | 00 15 R NO CURRENT AUDIO STATUS TO RETURN | 1751 | | 01 00 DW O NO INDEX/SECTOR SIGNAL | 1752 | | 02 00 DWR OM NO SEEK COMPLETE | 1753 | | 03 00 DTL W SO PERIPHERAL DEVICE WRITE FAULT | 1754 | | 03 01 T NO WRITE CURRENT | 1755 | | 03 02 T EXCESSIVE WRITE ERRORS | 1756 | | 04 00 DTLPWRSOMC LOGICAL UNIT NOT READY, CAUSE NOT REPORTABLE | 1757 | | 04 01 DTLPWRSOMC LOGICAL UNIT IS IN PROCESS OF BECOMING READY | 1758 | | 04 02 DTLPWRSOMC LOGICAL UNIT NOT READY, INITIALIZING COMMAND REQUIRED| 1759 | | 04 03 DTLPWRSOMC LOGICAL UNIT NOT READY, MANUAL INTERVENTION REQUIRED | 1760 | | 04 04 DTL O LOGICAL UNIT NOT READY, FORMAT IN PROGRESS | 1761 | | 05 00 DTL WRSOMC LOGICAL UNIT DOES NOT RESPOND TO SELECTION | 1762 | | 06 00 DWR OM NO REFERENCE POSITION FOUND | 1763 | | 07 00 DTL WRSOM MULTIPLE PERIPHERAL DEVICES SELECTED | 1764 | | 08 00 DTL WRSOMC LOGICAL UNIT COMMUNICATION FAILURE | 1765 | | 08 01 DTL WRSOMC LOGICAL UNIT COMMUNICATION TIME-OUT | 1766 | | 08 02 DTL WRSOMC LOGICAL UNIT COMMUNICATION PARITY ERROR | 1767 | | 09 00 DT WR O TRACK FOLLOWING ERROR | 1768 | | 09 01 WR O TRACKING SERVO FAILURE | 1769 | | 09 02 WR O FOCUS SERVO FAILURE | 1770 | | 09 03 WR O SPINDLE SERVO FAILURE | 1771 | | 0A 00 DTLPWRSOMC ERROR LOG OVERFLOW | 1772 | | 0C 00 T S WRITE ERROR | 1773 | | 0C 01 D W O WRITE ERROR RECOVERED WITH AUTO REALLOCATION | 1774 | | 0C 02 D W O WRITE ERROR - AUTO REALLOCATION FAILED | 1775 | | 10 00 D W O ID CRC OR ECC ERROR | 1776 | | 11 00 DT WRSO UNRECOVERED READ ERROR | 1777 | | 11 01 DT W SO READ RETRIES EXHAUSTED | 1778 | | 11 02 DT W SO ERROR TOO LONG TO CORRECT | 1779 | | 11 03 DT W SO MULTIPLE READ ERRORS | 1780 | | 11 04 D W O UNRECOVERED READ ERROR - AUTO REALLOCATE FAILED | 1781 | | 11 05 WR O L-EC UNCORRECTABLE ERROR | 1782 | | 11 06 WR O CIRC UNRECOVERED ERROR | 1783 | | 11 07 W O DATA RESYCHRONIZATION ERROR | 1784 | | 11 08 T INCOMPLETE BLOCK READ | 1785 | | 11 09 T NO GAP FOUND | 1786 | | 11 0A DT O MISCORRECTED ERROR | 1787 | | 11 0B D W O UNRECOVERED READ ERROR - RECOMMEND REASSIGNMENT | 1788 | | 11 0C D W O UNRECOVERED READ ERROR - RECOMMEND REWRITE THE DATA | 1789 | | 12 00 D W O ADDRESS MARK NOT FOUND FOR ID FIELD | 1790 | | 13 00 D W O ADDRESS MARK NOT FOUND FOR DATA FIELD | 1791 | | 14 00 DTL WRSO RECORDED ENTITY NOT FOUND | 1792 | | 14 01 DT WR O RECORD NOT FOUND | 1793 | | 14 02 T FILEMARK OR SETMARK NOT FOUND | 1794 | | 14 03 T END-OF-DATA NOT FOUND | 1795 | | 14 04 T BLOCK SEQUENCE ERROR | 1796 | | 15 00 DTL WRSOM RANDOM POSITIONING ERROR | 1797 | | 15 01 DTL WRSOM MECHANICAL POSITIONING ERROR | 1798 | | 15 02 DT WR O POSITIONING ERROR DETECTED BY READ OF MEDIUM | 1799 | | 16 00 DW O DATA SYNCHRONIZATION MARK ERROR | 1800 | | 17 00 DT WRSO RECOVERED DATA WITH NO ERROR CORRECTION APPLIED | 1801 | | 17 01 DT WRSO RECOVERED DATA WITH RETRIES | 1802 | | 17 02 DT WR O RECOVERED DATA WITH POSITIVE HEAD OFFSET | 1803 | | 17 03 DT WR O RECOVERED DATA WITH NEGATIVE HEAD OFFSET | 1804 | | 17 04 WR O RECOVERED DATA WITH RETRIES AND/OR CIRC APPLIED | 1805 | | 17 05 D WR O RECOVERED DATA USING PREVIOUS SECTOR ID | 1806 | | 17 06 D W O RECOVERED DATA WITHOUT ECC - DATA AUTO-REALLOCATED | 1807 | | 17 07 D W O RECOVERED DATA WITHOUT ECC - RECOMMEND REASSIGNMENT | 1808 | | 17 08 D W O RECOVERED DATA WITHOUT ECC - RECOMMEND REWRITE | 1809 | | 18 00 DT WR O RECOVERED DATA WITH ERROR CORRECTION APPLIED | 1810 | | 18 01 D WR O RECOVERED DATA WITH ERROR CORRECTION & RETRIES APPLIE| 1811 | | 18 02 D WR O RECOVERED DATA - DATA AUTO-REALLOCATED | 1812 | | 18 03 R RECOVERED DATA WITH CIRC | 1813 | | 18 04 R RECOVERED DATA WITH LEC | 1814 | | 18 05 D WR O RECOVERED DATA - RECOMMEND REASSIGNMENT | 1815 | | 18 06 D WR O RECOVERED DATA - RECOMMEND REWRITE | 1816 | | 19 00 D O DEFECT LIST ERROR | 1817 | | 19 01 D O DEFECT LIST NOT AVAILABLE | 1818 | | 19 02 D O DEFECT LIST ERROR IN PRIMARY LIST | 1819 | | 19 03 D O DEFECT LIST ERROR IN GROWN LIST | 1820 | | 1A 00 DTLPWRSOMC PARAMETER LIST LENGTH ERROR | 1821 | | 1B 00 DTLPWRSOMC SYNCHRONOUS DATA TRANSFER ERROR | 1822 | | 1C 00 D O DEFECT LIST NOT FOUND | 1823 | | 1C 01 D O PRIMARY DEFECT LIST NOT FOUND | 1824 | | 1C 02 D O GROWN DEFECT LIST NOT FOUND | 1825 | | 1D 00 D W O MISCOMPARE DURING VERIFY OPERATION | 1826 | | 1E 00 D W O RECOVERED ID WITH ECC | 1827 | | 20 00 DTLPWRSOMC INVALID COMMAND OPERATION CODE | 1828 | | 21 00 DT WR OM LOGICAL BLOCK ADDRESS OUT OF RANGE | 1829 | | 21 01 M INVALID ELEMENT ADDRESS | 1830 | | 22 00 D ILLEGAL FUNCTION (SHOULD USE 20 00, 24 00, OR 26 00) | 1831 | | 24 00 DTLPWRSOMC INVALID FIELD IN CDB | 1832 | | 25 00 DTLPWRSOMC LOGICAL UNIT NOT SUPPORTED | 1833 | | 26 00 DTLPWRSOMC INVALID FIELD IN PARAMETER LIST | 1834 | | 26 01 DTLPWRSOMC PARAMETER NOT SUPPORTED | 1835 | | 26 02 DTLPWRSOMC PARAMETER VALUE INVALID | 1836 | | 26 03 DTLPWRSOMC THRESHOLD PARAMETERS NOT SUPPORTED | 1837 | | 27 00 DT W O WRITE PROTECTED | 1838 | | 28 00 DTLPWRSOMC NOT READY TO READY TRANSITION(MEDIUM MAY HAVE CHANGED| 1839 | | 28 01 M IMPORT OR EXPORT ELEMENT ACCESSED | 1840 | | 29 00 DTLPWRSOMC POWER ON, RESET, OR BUS DEVICE RESET OCCURRED | 1841 | | 2A 00 DTL WRSOMC PARAMETERS CHANGED | 1842 | | 2A 01 DTL WRSOMC MODE PARAMETERS CHANGED | 1843 | | 2A 02 DTL WRSOMC LOG PARAMETERS CHANGED | 1844 | | 2B 00 DTLPWRSO C COPY CANNOT EXECUTE SINCE HOST CANNOT DISCONNECT | 1845 | | 2C 00 DTLPWRSOMC COMMAND SEQUENCE ERROR | 1846 | | 2C 01 S TOO MANY WINDOWS SPECIFIED | 1847 | | 2C 02 S INVALID COMBINATION OF WINDOWS SPECIFIED | 1848 | | 2D 00 T OVERWRITE ERROR ON UPDATE IN PLACE | 1849 | | 2F 00 DTLPWRSOMC COMMANDS CLEARED BY ANOTHER INITIATOR | 1850 | | 30 00 DT WR OM INCOMPATIBLE MEDIUM INSTALLED | 1851 | | 30 01 DT WR O CANNOT READ MEDIUM - UNKNOWN FORMAT | 1852 | | 30 02 DT WR O CANNOT READ MEDIUM - INCOMPATIBLE FORMAT | 1853 | | 30 03 DT CLEANING CARTRIDGE INSTALLED | 1854 | | 31 00 DT W O MEDIUM FORMAT CORRUPTED | 1855 | | 31 01 D L O FORMAT COMMAND FAILED | 1856 | | 32 00 D W O NO DEFECT SPARE LOCATION AVAILABLE | 1857 | | 32 01 D W O DEFECT LIST UPDATE FAILURE | 1858 | | 33 00 T TAPE LENGTH ERROR | 1859 | | 36 00 L RIBBON, INK, OR TONER FAILURE | 1860 | | 37 00 DTL WRSOMC ROUNDED PARAMETER | 1861 | | 39 00 DTL WRSOMC SAVING PARAMETERS NOT SUPPORTED | 1862 | | 3A 00 DTL WRSOM MEDIUM NOT PRESENT | 1863 | | 3B 00 TL SEQUENTIAL POSITIONING ERROR | 1864 | | 3B 01 T TAPE POSITION ERROR AT BEGINNING-OF-MEDIUM | 1865 | | 3B 02 T TAPE POSITION ERROR AT END-OF-MEDIUM | 1866 | | 3B 03 L TAPE OR ELECTRONIC VERTICAL FORMS UNIT NOT READY | 1867 | | 3B 04 L SLEW FAILURE | 1868 | | 3B 05 L PAPER JAM | 1869 | | 3B 06 L FAILED TO SENSE TOP-OF-FORM | 1870 | | 3B 07 L FAILED TO SENSE BOTTOM-OF-FORM | 1871 | | 3B 08 T REPOSITION ERROR | 1872 | | 3B 09 S READ PAST END OF MEDIUM | 1873 | | 3B 0A S READ PAST BEGINNING OF MEDIUM | 1874 | | 3B 0B S POSITION PAST END OF MEDIUM | 1875 | | 3B 0C S POSITION PAST BEGINNING OF MEDIUM | 1876 | | 3B 0D M MEDIUM DESTINATION ELEMENT FULL | 1877 | | 3B 0E M MEDIUM SOURCE ELEMENT EMPTY | 1878 | | 3D 00 DTLPWRSOMC INVALID BITS IN IDENTIFY MESSAGE | 1879 | | 3E 00 DTLPWRSOMC LOGICAL UNIT HAS NOT SELF-CONFIGURED YET | 1880 | | 3F 00 DTLPWRSOMC TARGET OPERATING CONDITIONS HAVE CHANGED | 1881 | | 3F 01 DTLPWRSOMC MICROCODE HAS BEEN CHANGED | 1882 | | 3F 02 DTLPWRSOMC CHANGED OPERATING DEFINITION | 1883 | | 3F 03 DTLPWRSOMC INQUIRY DATA HAS CHANGED | 1884 | | 40 00 D RAM FAILURE (SHOULD USE 40 NN) | 1885 | | 40 NN DTLPWRSOMC DIAGNOSTIC FAILURE ON COMPONENT NN (80H-FFH) | 1886 | | 41 00 D DATA PATH FAILURE (SHOULD USE 40 NN) | 1887 | | 42 00 D POWER-ON OR SELF-TEST FAILURE (SHOULD USE 40 NN) | 1888 | | 43 00 DTLPWRSOMC MESSAGE ERROR | 1889 | | 44 00 DTLPWRSOMC INTERNAL TARGET FAILURE | 1890 | | 45 00 DTLPWRSOMC SELECT OR RESELECT FAILURE | 1891 | | 46 00 DTLPWRSOMC UNSUCCESSFUL SOFT RESET | 1892 | | 47 00 DTLPWRSOMC SCSI PARITY ERROR | 1893 | | 48 00 DTLPWRSOMC INITIATOR DETECTED ERROR MESSAGE RECEIVED | 1894 | | 49 00 DTLPWRSOMC INVALID MESSAGE ERROR | 1895 | | 4A 00 DTLPWRSOMC COMMAND PHASE ERROR | 1896 | | 4B 00 DTLPWRSOMC DATA PHASE ERROR | 1897 | | 4C 00 DTLPWRSOMC LOGICAL UNIT FAILED SELF-CONFIGURATION | 1898 | | 4E 00 DTLPWRSOMC OVERLAPPED COMMANDS ATTEMPTED | 1899 | | 50 00 T WRITE APPEND ERROR | 1900 | | 50 01 T WRITE APPEND POSITION ERROR | 1901 | | 50 02 T POSITION ERROR RELATED TO TIMING | 1902 | | 51 00 T O ERASE FAILURE | 1903 | | 52 00 T CARTRIDGE FAULT | 1904 | | 53 00 DTL WRSOM MEDIA LOAD OR EJECT FAILED | 1905 | | 53 01 T UNLOAD TAPE FAILURE | 1906 | | 53 02 DT WR OM MEDIUM REMOVAL PREVENTED | 1907 | | 54 00 P SCSI TO HOST SYSTEM INTERFACE FAILURE | 1908 | | 55 00 P SYSTEM RESOURCE FAILURE | 1909 | | 57 00 R UNABLE TO RECOVER TABLE-OF-CONTENTS | 1910 | | 58 00 O GENERATION DOES NOT EXIST | 1911 | | 59 00 O UPDATED BLOCK READ | 1912 | | 5A 00 DTLPWRSOM OPERATOR REQUEST OR STATE CHANGE INPUT (UNSPECIFIED) | 1913 | | 5A 01 DT WR OM OPERATOR MEDIUM REMOVAL REQUEST | 1914 | | 5A 02 DT W O OPERATOR SELECTED WRITE PROTECT | 1915 | | 5A 03 DT W O OPERATOR SELECTED WRITE PERMIT | 1916 | | 5B 00 DTLPWRSOM LOG EXCEPTION | 1917 | | 5B 01 DTLPWRSOM THRESHOLD CONDITION MET | 1918 | | 5B 02 DTLPWRSOM LOG COUNTER AT MAXIMUM | 1919 | | 5B 03 DTLPWRSOM LOG LIST CODES EXHAUSTED | 1920 | | 5C 00 D O RPL STATUS CHANGE | 1921 | | 5C 01 D O SPINDLES SYNCHRONIZED | 1922 | | 5C 02 D O SPINDLES NOT SYNCHRONIZED | 1923 | | 60 00 S LAMP FAILURE | 1924 | | 61 00 S VIDEO ACQUISITION ERROR | 1925 | | 61 01 S UNABLE TO ACQUIRE VIDEO | 1926 | | 61 02 S OUT OF FOCUS | 1927 | | 62 00 S SCAN HEAD POSITIONING ERROR | 1928 | | 63 00 R END OF USER AREA ENCOUNTERED ON THIS TRACK | 1929 | | 64 00 R ILLEGAL MODE FOR THIS TRACK | 1930 | | | 1931 | | 80 xxh \ | 1932 | | THROUGH > VENDOR SPECIFIC. | 1933 | | FF xxh / | 1934 | | | 1935 | | xxh 80 \ | 1936 | | THROUGH > VENDOR SPECIFIC QUALIFICATION OF STANDARD ASC. | 1937 | | xxh FF / | 1938 | | ALL CODES NOT SHOWN OR BLANK ARE RESERVED. | 1939 | +============================================================================+ 1940 | 1941 | 1942 | 1943 | ASC and ASCQ in alphabetical order by description 1944 | +============================================================================+ 1945 | | D - DIRECT ACCESS DEVICE | 1946 | | .T - SEQUENTIAL ACCESS DEVICE | 1947 | | . L - PRINTER DEVICE | 1948 | | . P - PROCESSOR DEVICE | 1949 | | . .W - WRITE ONCE READ MULTIPLE DEVICE | 1950 | | . . R - READ ONLY (CD-ROM) DEVICE | 1951 | | . . S - SCANNER DEVICE | 1952 | | . . .O - OPTICAL MEMORY DEVICE | 1953 | | . . . M - MEDIA CHANGER DEVICE | 1954 | | . . . C - COMMUNICATION DEVICE | 1955 | | . . . . | 1956 | | ASC ASCQ DTLPWRSOMC DESCRIPTION | 1957 | | --- ---- -----------------------------------------------------| 1958 | | 13h 00h D W O ADDRESS MARK NOT FOUND FOR DATA FIELD | 1959 | | 12h 00h D W O ADDRESS MARK NOT FOUND FOR ID FIELD | 1960 | | 00h 11h R AUDIO PLAY OPERATION IN PROGRESS | 1961 | | 00h 12h R AUDIO PLAY OPERATION PAUSED | 1962 | | 00h 14h R AUDIO PLAY OPERATION STOPPED DUE TO ERROR | 1963 | | 00h 13h R AUDIO PLAY OPERATION SUCCESSFULLY COMPLETED | 1964 | | 00h 04h T S BEGINNING-OF-PARTITION/MEDIUM DETECTED | 1965 | | 14h 04h T BLOCK SEQUENCE ERROR | 1966 | | 30h 02h DT WR O CANNOT READ MEDIUM - INCOMPATIBLE FORMAT | 1967 | | 30h 01h DT WR O CANNOT READ MEDIUM - UNKNOWN FORMAT | 1968 | | 52h 00h T CARTRIDGE FAULT | 1969 | | 3Fh 02h DTLPWRSOMC CHANGED OPERATING DEFINITION | 1970 | | 11h 06h WR O CIRC UNRECOVERED ERROR | 1971 | | 30h 03h DT CLEANING CARTRIDGE INSTALLED | 1972 | | 4Ah 00h DTLPWRSOMC COMMAND PHASE ERROR | 1973 | | 2Ch 00h DTLPWRSOMC COMMAND SEQUENCE ERROR | 1974 | | 2Fh 00h DTLPWRSOMC COMMANDS CLEARED BY ANOTHER INITIATOR | 1975 | | 2Bh 00h DTLPWRSO C COPY CANNOT EXECUTE SINCE HOST CANNOT DISCONNECT | 1976 | | 41h 00h D DATA PATH FAILURE (SHOULD USE 40 NN) | 1977 | | 4Bh 00h DTLPWRSOMC DATA PHASE ERROR | 1978 | | 11h 07h W O DATA RESYCHRONIZATION ERROR | 1979 | | 16h 00h D W O DATA SYNCHRONIZATION MARK ERROR | 1980 | | 19h 00h D O DEFECT LIST ERROR | 1981 | | 19h 03h D O DEFECT LIST ERROR IN GROWN LIST | 1982 | | 19h 02h D O DEFECT LIST ERROR IN PRIMARY LIST | 1983 | | 19h 01h D O DEFECT LIST NOT AVAILABLE | 1984 | | 1Ch 00h D O DEFECT LIST NOT FOUND | 1985 | | 32h 01h D W O DEFECT LIST UPDATE FAILURE | 1986 | | 40h NNh DTLPWRSOMC DIAGNOSTIC FAILURE ON COMPONENT NN (80H-FFH) | 1987 | | 63h 00h R END OF USER AREA ENCOUNTERED ON THIS TRACK | 1988 | | 00h 05h T S END-OF-DATA DETECTED | 1989 | | 14h 03h T END-OF-DATA NOT FOUND | 1990 | | 00h 02h T S END-OF-PARTITION/MEDIUM DETECTED | 1991 | | 51h 00h T O ERASE FAILURE | 1992 | | 0Ah 00h DTLPWRSOMC ERROR LOG OVERFLOW | 1993 | | 11h 02h DT W SO ERROR TOO LONG TO CORRECT | 1994 | | 03h 02h T EXCESSIVE WRITE ERRORS | 1995 | | 3Bh 07h L FAILED TO SENSE BOTTOM-OF-FORM | 1996 | | 3Bh 06h L FAILED TO SENSE TOP-OF-FORM | 1997 | | 00h 01h T FILEMARK DETECTED | 1998 | | 14h 02h T FILEMARK OR SETMARK NOT FOUND | 1999 | | 09h 02h WR O FOCUS SERVO FAILURE | 2000 | | 31h 01h D L O FORMAT COMMAND FAILED | 2001 | | 58h 00h O GENERATION DOES NOT EXIST | 2002 | | 1Ch 02h D O GROWN DEFECT LIST NOT FOUND | 2003 | | 00h 06h DTLPWRSOMC I/O PROCESS TERMINATED | 2004 | | 10h 00h D W O ID CRC OR ECC ERROR | 2005 | | 22h 00h D ILLEGAL FUNCTION (SHOULD USE 20 00, 24 00, OR 26 00) | 2006 | | 64h 00h R ILLEGAL MODE FOR THIS TRACK | 2007 | | 28h 01h M IMPORT OR EXPORT ELEMENT ACCESSED | 2008 | | 30h 00h DT WR OM INCOMPATIBLE MEDIUM INSTALLED | 2009 | | 11h 08h T INCOMPLETE BLOCK READ | 2010 | | 48h 00h DTLPWRSOMC INITIATOR DETECTED ERROR MESSAGE RECEIVED | 2011 | | 3Fh 03h DTLPWRSOMC INQUIRY DATA HAS CHANGED | 2012 | | 44h 00h DTLPWRSOMC INTERNAL TARGET FAILURE | 2013 | | 3Dh 00h DTLPWRSOMC INVALID BITS IN IDENTIFY MESSAGE | 2014 | | 2Ch 02h S INVALID COMBINATION OF WINDOWS SPECIFIED | 2015 | | 20h 00h DTLPWRSOMC INVALID COMMAND OPERATION CODE | 2016 | | 21h 01h M INVALID ELEMENT ADDRESS | 2017 | | 24h 00h DTLPWRSOMC INVALID FIELD IN CDB | 2018 | | 26h 00h DTLPWRSOMC INVALID FIELD IN PARAMETER LIST | 2019 | | 49h 00h DTLPWRSOMC INVALID MESSAGE ERROR | 2020 | | 11h 05h WR O L-EC UNCORRECTABLE ERROR | 2021 | | 60h 00h S LAMP FAILURE | 2022 | | 5Bh 02h DTLPWRSOM LOG COUNTER AT MAXIMUM | 2023 | | 5Bh 00h DTLPWRSOM LOG EXCEPTION | 2024 | | 5Bh 03h DTLPWRSOM LOG LIST CODES EXHAUSTED | 2025 | | 2Ah 02h DTL WRSOMC LOG PARAMETERS CHANGED | 2026 | | 21h 00h DT WR OM LOGICAL BLOCK ADDRESS OUT OF RANGE | 2027 | | 08h 00h DTL WRSOMC LOGICAL UNIT COMMUNICATION FAILURE | 2028 | | 08h 02h DTL WRSOMC LOGICAL UNIT COMMUNICATION PARITY ERROR | 2029 | | 08h 01h DTL WRSOMC LOGICAL UNIT COMMUNICATION TIME-OUT | 2030 | | 4Ch 00h DTLPWRSOMC LOGICAL UNIT FAILED SELF-CONFIGURATION | 2031 | | 3Eh 00h DTLPWRSOMC LOGICAL UNIT HAS NOT SELF-CONFIGURED YET | 2032 | | 04h 01h DTLPWRSOMC LOGICAL UNIT IS IN PROCESS OF BECOMING READY | 2033 | | 04h 00h DTLPWRSOMC LOGICAL UNIT NOT READY, CAUSE NOT REPORTABLE | 2034 | | 04h 04h DTL O LOGICAL UNIT NOT READY, FORMAT IN PROGRESS | 2035 | | 04h 02h DTLPWRSOMC LOGICAL UNIT NOT READY, INITIALIZING COMMAND REQUIRED| 2036 | | 04h 03h DTLPWRSOMC LOGICAL UNIT NOT READY, MANUAL INTERVENTION REQUIRED | 2037 | | 25h 00h DTLPWRSOMC LOGICAL UNIT NOT SUPPORTED | 2038 | | 15h 01h DTL WRSOM MECHANICAL POSITIONING ERROR | 2039 | | 53h 00h DTL WRSOM MEDIA LOAD OR EJECT FAILED | 2040 | | 3Bh 0Dh M MEDIUM DESTINATION ELEMENT FULL | 2041 | | 31h 00h DT W O MEDIUM FORMAT CORRUPTED | 2042 | | 3Ah 00h DTL WRSOM MEDIUM NOT PRESENT | 2043 | | 53h 02h DT WR OM MEDIUM REMOVAL PREVENTED | 2044 | | 3Bh 0Eh M MEDIUM SOURCE ELEMENT EMPTY | 2045 | | 43h 00h DTLPWRSOMC MESSAGE ERROR | 2046 | | 3Fh 01h DTLPWRSOMC MICROCODE HAS BEEN CHANGED | 2047 | | 1Dh 00h D W O MISCOMPARE DURING VERIFY OPERATION | 2048 | | 11h 0Ah DT O MISCORRECTED ERROR | 2049 | | 2Ah 01h DTL WRSOMC MODE PARAMETERS CHANGED | 2050 | | 07h 00h DTL WRSOM MULTIPLE PERIPHERAL DEVICES SELECTED | 2051 | | 11h 03h DT W SO MULTIPLE READ ERRORS | 2052 | | 00h 00h DTLPWRSOMC NO ADDITIONAL SENSE INFORMATION | 2053 | | 00h 15h R NO CURRENT AUDIO STATUS TO RETURN | 2054 | | 32h 00h D W O NO DEFECT SPARE LOCATION AVAILABLE | 2055 | | 11h 09h T NO GAP FOUND | 2056 | | 01h 00h D W O NO INDEX/SECTOR SIGNAL | 2057 | | 06h 00h D WR OM NO REFERENCE POSITION FOUND | 2058 | | 02h 00h D WR OM NO SEEK COMPLETE | 2059 | | 03h 01h T NO WRITE CURRENT | 2060 | | 28h 00h DTLPWRSOMC NOT READY TO READY TRANSITION, MEDIUM MAY HAVE CHANGE| 2061 | | 5Ah 01h DT WR OM OPERATOR MEDIUM REMOVAL REQUEST | 2062 | | 5Ah 00h DTLPWRSOM OPERATOR REQUEST OR STATE CHANGE INPUT (UNSPECIFIED) | 2063 | | 5Ah 03h DT W O OPERATOR SELECTED WRITE PERMIT | 2064 | | 5Ah 02h DT W O OPERATOR SELECTED WRITE PROTECT | 2065 | | 61h 02h S OUT OF FOCUS | 2066 | | 4Eh 00h DTLPWRSOMC OVERLAPPED COMMANDS ATTEMPTED | 2067 | | 2Dh 00h T OVERWRITE ERROR ON UPDATE IN PLACE | 2068 | | 3Bh 05h L PAPER JAM | 2069 | | 1Ah 00h DTLPWRSOMC PARAMETER LIST LENGTH ERROR | 2070 | | 26h 01h DTLPWRSOMC PARAMETER NOT SUPPORTED | 2071 | | 26h 02h DTLPWRSOMC PARAMETER VALUE INVALID | 2072 | | 2Ah 00h DTL WRSOMC PARAMETERS CHANGED | 2073 | | 03h 00h DTL W SO PERIPHERAL DEVICE WRITE FAULT | 2074 | | 50h 02h T POSITION ERROR RELATED TO TIMING | 2075 | | 3Bh 0Ch S POSITION PAST BEGINNING OF MEDIUM | 2076 | | 3Bh 0Bh S POSITION PAST END OF MEDIUM | 2077 | | 15h 02h DT WR O POSITIONING ERROR DETECTED BY READ OF MEDIUM | 2078 | | 29h 00h DTLPWRSOMC POWER ON, RESET, OR BUS DEVICE RESET OCCURRED | 2079 | | 42h 00h D POWER-ON OR SELF-TEST FAILURE (SHOULD USE 40 NN) | 2080 | | 1Ch 01h D O PRIMARY DEFECT LIST NOT FOUND | 2081 | | 40h 00h D RAM FAILURE (SHOULD USE 40 NN) | 2082 | | 15h 00h DTL WRSOM RANDOM POSITIONING ERROR | 2083 | | 3Bh 0Ah S READ PAST BEGINNING OF MEDIUM | 2084 | | 3Bh 09h S READ PAST END OF MEDIUM | 2085 | | 11h 01h DT W SO READ RETRIES EXHAUSTED | 2086 | | 14h 01h DT WR O RECORD NOT FOUND | 2087 | | 14h 00h DTL WRSO RECORDED ENTITY NOT FOUND | 2088 | | 18h 02h D WR O RECOVERED DATA - DATA AUTO-REALLOCATED | 2089 | | 18h 05h D WR O RECOVERED DATA - RECOMMEND REASSIGNMENT | 2090 | | 18h 06h D WR O RECOVERED DATA - RECOMMEND REWRITE | 2091 | | 17h 05h D WR O RECOVERED DATA USING PREVIOUS SECTOR ID | 2092 | | 18h 03h R RECOVERED DATA WITH CIRC | 2093 | | 18h 01h D WR O RECOVERED DATA WITH ERROR CORRECTION & RETRIES APPLIE| 2094 | | 18h 00h DT WR O RECOVERED DATA WITH ERROR CORRECTION APPLIED | 2095 | | 18h 04h R RECOVERED DATA WITH L-EC | 2096 | | 17h 03h DT WR O RECOVERED DATA WITH NEGATIVE HEAD OFFSET | 2097 | | 17h 00h DT WRSO RECOVERED DATA WITH NO ERROR CORRECTION APPLIED | 2098 | | 17h 02h DT WR O RECOVERED DATA WITH POSITIVE HEAD OFFSET | 2099 | | 17h 01h DT WRSO RECOVERED DATA WITH RETRIES | 2100 | | 17h 04h WR O RECOVERED DATA WITH RETRIES AND/OR CIRC APPLIED | 2101 | | 17h 06h D W O RECOVERED DATA WITHOUT ECC - DATA AUTO-REALLOCATED | 2102 | | 17h 07h D W O RECOVERED DATA WITHOUT ECC - RECOMMEND REASSIGNMENT | 2103 | | 17h 08h D W O RECOVERED DATA WITHOUT ECC - RECOMMEND REWRITE | 2104 | | 1Eh 00h D W O RECOVERED ID WITH ECC CORRECTION | 2105 | | 3Bh 08h T REPOSITION ERROR | 2106 | | 36h 00h L RIBBON, INK, OR TONER FAILURE | 2107 | | 37h 00h DTL WRSOMC ROUNDED PARAMETER | 2108 | | 5Ch 00h D O RPL STATUS CHANGE | 2109 | | 39h 00h DTL WRSOMC SAVING PARAMETERS NOT SUPPORTED | 2110 | | 62h 00h S SCAN HEAD POSITIONING ERROR | 2111 | | 47h 00h DTLPWRSOMC SCSI PARITY ERROR | 2112 | | 54h 00h P SCSI TO HOST SYSTEM INTERFACE FAILURE | 2113 | | 45h 00h DTLPWRSOMC SELECT OR RESELECT FAILURE | 2114 | | 3Bh 00h TL SEQUENTIAL POSITIONING ERROR | 2115 | | 00h 03h T SETMARK DETECTED | 2116 | | 3Bh 04h L SLEW FAILURE | 2117 | | 09h 03h WR O SPINDLE SERVO FAILURE | 2118 | | 5Ch 02h D O SPINDLES NOT SYNCHRONIZED | 2119 | | 5Ch 01h D O SPINDLES SYNCHRONIZED | 2120 | | 1Bh 00h DTLPWRSOMC SYNCHRONOUS DATA TRANSFER ERROR | 2121 | | 55h 00h P SYSTEM RESOURCE FAILURE | 2122 | | 33h 00h T TAPE LENGTH ERROR | 2123 | | 3Bh 03h L TAPE OR ELECTRONIC VERTICAL FORMS UNIT NOT READY | 2124 | | 3Bh 01h T TAPE POSITION ERROR AT BEGINNING-OF-MEDIUM | 2125 | | 3Bh 02h T TAPE POSITION ERROR AT END-OF-MEDIUM | 2126 | | 3Fh 00h DTLPWRSOMC TARGET OPERATING CONDITIONS HAVE CHANGED | 2127 | | 5Bh 01h DTLPWRSOM THRESHOLD CONDITION MET | 2128 | | 26h 03h DTLPWRSOMC THRESHOLD PARAMETERS NOT SUPPORTED | 2129 | | 2Ch 01h S TOO MANY WINDOWS SPECIFIED | 2130 | | 09h 00h DT WR O TRACK FOLLOWING ERROR | 2131 | | 09h 01h WR O TRACKING SERVO FAILURE | 2132 | | 61h 01h S UNABLE TO ACQUIRE VIDEO | 2133 | | 57h 00h R UNABLE TO RECOVER TABLE-OF-CONTENTS | 2134 | | 53h 01h T UNLOAD TAPE FAILURE | 2135 | | 11h 00h DT WRSO UNRECOVERED READ ERROR | 2136 | | 11h 04h D W O UNRECOVERED READ ERROR - AUTO REALLOCATE FAILED | 2137 | | 11h 0Bh D W O UNRECOVERED READ ERROR - RECOMMEND REASSIGNMENT | 2138 | | 11h 0Ch D W O UNRECOVERED READ ERROR - RECOMMEND REWRITE THE DATA | 2139 | | 46h 00h DTLPWRSOMC UNSUCCESSFUL SOFT RESET | 2140 | | 59h 00h O UPDATED BLOCK READ | 2141 | | 61h 00h S VIDEO ACQUISITION ERROR | 2142 | | 50h 00h T WRITE APPEND ERROR | 2143 | | 50h 01h T WRITE APPEND POSITION ERROR | 2144 | | 0Ch 00h T S WRITE ERROR | 2145 | | 0Ch 02h D W O WRITE ERROR - AUTO REALLOCATION FAILED | 2146 | | 0Ch 01h D W O WRITE ERROR RECOVERED WITH AUTO REALLOCATION | 2147 | | 27h 00h DT W O WRITE PROTECTED | 2148 | |----------------------------------------------------------------------------| 2149 | 2150 | 2151 | 2152 | 2153 | 2154 | Douglas Gilbert 2155 | dgilbert@interlog.com or dougg@triode.net.au 2156 | -------------------------------------------------------------------------------- /include/sg_err.h: -------------------------------------------------------------------------------- 1 | #ifndef SG_ERR_H 2 | #define SG_ERR_H 3 | 4 | /* Feel free to copy and modify this GPL-ed code into your applications. */ 5 | 6 | /* Version 0.84 (20010115) 7 | - all output now sent to stderr rather thatn stdout 8 | - remove header files included in this file 9 | */ 10 | 11 | 12 | /* Some of the following error/status codes are exchanged between the 13 | various layers of the SCSI sub-system in Linux and should never 14 | reach the user. They are placed here for completeness. What appears 15 | here is copied from drivers/scsi/scsi.h which is not visible in 16 | the user space. */ 17 | 18 | /* The following are 'host_status' codes */ 19 | #ifndef DID_OK 20 | #define DID_OK 0x00 21 | #endif 22 | #ifndef DID_NO_CONNECT 23 | #define DID_NO_CONNECT 0x01 /* Unable to connect before timeout */ 24 | #define DID_BUS_BUSY 0x02 /* Bus remain busy until timeout */ 25 | #define DID_TIME_OUT 0x03 /* Timed out for some other reason */ 26 | #define DID_BAD_TARGET 0x04 /* Bad target (id?) */ 27 | #define DID_ABORT 0x05 /* Told to abort for some other reason */ 28 | #define DID_PARITY 0x06 /* Parity error (on SCSI bus) */ 29 | #define DID_ERROR 0x07 /* Internal error */ 30 | #define DID_RESET 0x08 /* Reset by somebody */ 31 | #define DID_BAD_INTR 0x09 /* Received an unexpected interrupt */ 32 | #define DID_PASSTHROUGH 0x0a /* Force command past mid-level */ 33 | #define DID_SOFT_ERROR 0x0b /* The low-level driver wants a retry */ 34 | #endif 35 | 36 | /* These defines are to isolate applictaions from kernel define changes */ 37 | #define SG_ERR_DID_OK DID_OK 38 | #define SG_ERR_DID_NO_CONNECT DID_NO_CONNECT 39 | #define SG_ERR_DID_BUS_BUSY DID_BUS_BUSY 40 | #define SG_ERR_DID_TIME_OUT DID_TIME_OUT 41 | #define SG_ERR_DID_BAD_TARGET DID_BAD_TARGET 42 | #define SG_ERR_DID_ABORT DID_ABORT 43 | #define SG_ERR_DID_PARITY DID_PARITY 44 | #define SG_ERR_DID_ERROR DID_ERROR 45 | #define SG_ERR_DID_RESET DID_RESET 46 | #define SG_ERR_DID_BAD_INTR DID_BAD_INTR 47 | #define SG_ERR_DID_PASSTHROUGH DID_PASSTHROUGH 48 | #define SG_ERR_DID_SOFT_ERROR DID_SOFT_ERROR 49 | 50 | /* The following are 'driver_status' codes */ 51 | #ifndef DRIVER_OK 52 | #define DRIVER_OK 0x00 53 | #endif 54 | #ifndef DRIVER_BUSY 55 | #define DRIVER_BUSY 0x01 56 | #define DRIVER_SOFT 0x02 57 | #define DRIVER_MEDIA 0x03 58 | #define DRIVER_ERROR 0x04 59 | #define DRIVER_INVALID 0x05 60 | #define DRIVER_TIMEOUT 0x06 61 | #define DRIVER_HARD 0x07 62 | #define DRIVER_SENSE 0x08 /* Sense_buffer has been set */ 63 | 64 | /* Following "suggests" are "or-ed" with one of previous 8 entries */ 65 | #define SUGGEST_RETRY 0x10 66 | #define SUGGEST_ABORT 0x20 67 | #define SUGGEST_REMAP 0x30 68 | #define SUGGEST_DIE 0x40 69 | #define SUGGEST_SENSE 0x80 70 | #define SUGGEST_IS_OK 0xff 71 | #endif 72 | #ifndef DRIVER_MASK 73 | #define DRIVER_MASK 0x0f 74 | #endif 75 | #ifndef SUGGEST_MASK 76 | #define SUGGEST_MASK 0xf0 77 | #endif 78 | 79 | /* These defines are to isolate applictaions from kernel define changes */ 80 | #define SG_ERR_DRIVER_OK DRIVER_OK 81 | #define SG_ERR_DRIVER_BUSY DRIVER_BUSY 82 | #define SG_ERR_DRIVER_SOFT DRIVER_SOFT 83 | #define SG_ERR_DRIVER_MEDIA DRIVER_MEDIA 84 | #define SG_ERR_DRIVER_ERROR DRIVER_ERROR 85 | #define SG_ERR_DRIVER_INVALID DRIVER_INVALID 86 | #define SG_ERR_DRIVER_TIMEOUT DRIVER_TIMEOUT 87 | #define SG_ERR_DRIVER_HARD DRIVER_HARD 88 | #define SG_ERR_DRIVER_SENSE DRIVER_SENSE 89 | #define SG_ERR_SUGGEST_RETRY SUGGEST_RETRY 90 | #define SG_ERR_SUGGEST_ABORT SUGGEST_ABORT 91 | #define SG_ERR_SUGGEST_REMAP SUGGEST_REMAP 92 | #define SG_ERR_SUGGEST_DIE SUGGEST_DIE 93 | #define SG_ERR_SUGGEST_SENSE SUGGEST_SENSE 94 | #define SG_ERR_SUGGEST_IS_OK SUGGEST_IS_OK 95 | #define SG_ERR_DRIVER_MASK DRIVER_MASK 96 | #define SG_ERR_SUGGEST_MASK SUGGEST_MASK 97 | 98 | 99 | 100 | /* The following "print" functions send ACSII to stdout */ 101 | extern void sg_print_command(const unsigned char * command); 102 | extern void sg_print_sense(const char * leadin, 103 | const unsigned char * sense_buffer, int sb_len); 104 | extern void sg_print_status(int masked_status); 105 | extern void sg_print_host_status(int host_status); 106 | extern void sg_print_driver_status(int driver_status); 107 | 108 | /* sg_chk_n_print() returns 1 quietly if there are no errors/warnings 109 | else it prints to standard output and returns 0. */ 110 | extern int sg_chk_n_print(const char * leadin, int masked_status, 111 | int host_status, int driver_status, 112 | const unsigned char * sense_buffer, int sb_len); 113 | 114 | /* The following function declaration is for the sg version 3 driver. 115 | Only version 3 sg_err.c defines it. */ 116 | struct sg_io_hdr; 117 | extern int sg_chk_n_print3(const char * leadin, struct sg_io_hdr * hp); 118 | 119 | 120 | /* The following "category" function returns one of the following */ 121 | #define SG_ERR_CAT_CLEAN 0 /* No errors or other information */ 122 | #define SG_ERR_CAT_MEDIA_CHANGED 1 /* interpreted from sense buffer */ 123 | #define SG_ERR_CAT_RESET 2 /* interpreted from sense buffer */ 124 | #define SG_ERR_CAT_TIMEOUT 3 125 | #define SG_ERR_CAT_RECOVERED 4 /* Successful command after recovered err */ 126 | #define SG_ERR_CAT_SENSE 98 /* Something else is in the sense buffer */ 127 | #define SG_ERR_CAT_OTHER 99 /* Some other error/warning has occurred */ 128 | 129 | extern int sg_err_category(int masked_status, int host_status, 130 | int driver_status, const unsigned char * sense_buffer, 131 | int sb_len); 132 | 133 | /* The following function declaration is for the sg version 3 driver. 134 | Only version 3 sg_err.c defines it. */ 135 | extern int sg_err_category3(struct sg_io_hdr * hp); 136 | 137 | /* Returns length of SCSI command given the opcode (first byte) */ 138 | int sg_get_command_size(unsigned char opcode); 139 | 140 | #endif 141 | -------------------------------------------------------------------------------- /setblocksize.c: -------------------------------------------------------------------------------- 1 | /* 2 | ******************************************************************************** 3 | Header 4 | 5 | Project: setblocksize 6 | 7 | This file: setblocksize.c 8 | Version: V0.2 9 | 10 | Description: Reformat SCSI disk with specified block size 11 | Thanks to Seagate for providing protocol information 12 | 13 | Return value: 0 on success, 1 on error 14 | 15 | Copyright: (C) 2003 by Michael Baeuerle 16 | License: GPL V2 or any later version 17 | 18 | Language: C 19 | Style rules: - 20 | 21 | Written for: Platform: all 22 | OS: GNU/Linux 23 | Tested with: Compiler: gcc (Version: 2.91.66) 24 | Platform: IA32 (Pentium) 25 | OS: GNU/Linux (Kernel version: 2.2.10) 26 | Tested with: Compiler: gcc (Version: 2.96.1) 27 | Platform: IA32 (Pentium2) 28 | OS: GNU/Linux (Kernel version: 2.4.21) 29 | Tested with: Compiler: gcc (Version: 3.3.6) 30 | Platform: IA32 (PentiumPro) 31 | OS: GNU/Linux (Kernel version: 2.6.16.20) 32 | Do not work: Platform: non GNU/Linux 33 | 34 | Created: 2003-03-22 by Michael Baeuerle 35 | Last mod.: 2007-09-04 by Michael Baeuerle 36 | 37 | Changelog: 38 | 39 | V0.0 Initial version (Inspired by sg-utils) 40 | LUN and blocksize must be specified at compile time 41 | 42 | V0.1 Print manufacturer and model name of selected device and 43 | ask if this is the desired device (using INQUIRY command) 44 | LUN selection removed: ID and LUN are implicit specified with 45 | the sg device (The LUN value of V0.0 was ignored) 46 | Also print ID, LUN, Host and channel numbers 47 | Check for device type supports the FORMAT UNIT command 48 | 49 | V0.2 The new blocksize can now be specified on command line 50 | The program now aborts if a SCSI command reports CHECK CONDITION 51 | The timeout can now be specified on the command line 52 | 53 | 54 | To do: - 55 | ******************************************************************************** 56 | */ 57 | 58 | 59 | /* 60 | ******************************************************************************** 61 | * Include files 62 | ******************************************************************************** 63 | */ 64 | 65 | #include 66 | #include 67 | #include 68 | #include 69 | #include 70 | #include 71 | #include 72 | #include 73 | #include 74 | #include 75 | #include 76 | #include 77 | #include "sg_err.h" 78 | 79 | 80 | /* 81 | ******************************************************************************** 82 | * Global constants 83 | ******************************************************************************** 84 | */ 85 | 86 | #define TIMEOUT (48000 * HZ) /* 800 minute FORMAT UNIT default timeout */ 87 | #define BS 512 /* Default blocksize */ 88 | const char NAME[] = "setblocksize"; 89 | const char VER[] = "V0.2"; 90 | 91 | 92 | /* 93 | ******************************************************************************** 94 | * Main function 95 | ******************************************************************************** 96 | */ 97 | 98 | int main(int argc, char** argv) 99 | { 100 | unsigned short int bs = BS; 101 | int timeout = TIMEOUT; 102 | int sg_fd; 103 | int i; 104 | int ok; 105 | int buf; 106 | char sbuf[256]; 107 | char* file_name = NULL; 108 | unsigned char scsi_buf[65536]; 109 | struct sg_header* sghp = (struct sg_header*) scsi_buf; 110 | Sg_scsi_id device; 111 | /* INQUIRY command */ 112 | unsigned char inquiry[6] = {0x12, 0x00, 0x00, 0x00, 0x20, 0x00}; 113 | /* MODE SELECT command */ 114 | unsigned char mode_select[6] = {0x15, 0x11, 0x00, 0x00, 0x0C, 0x00}; 115 | /* FORMAT UNIT command */ 116 | unsigned char format_unit[6] = {0x04, 0x00, 0x00, 0x00, 0x00, 0x00}; 117 | /* Parameter list with block descriptor */ 118 | unsigned char para_list[12] = {0x00, 0x00, 0x00, 0x08, 119 | 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00}; 120 | int inquiry_data_len = sizeof(struct sg_header) + 0x06; 121 | int mode_select_data_len = sizeof(struct sg_header) + 0x06 + 0x0C; 122 | int format_unit_data_len = sizeof(struct sg_header) + 0x06; 123 | 124 | /* Print info */ 125 | sprintf(sbuf, "\n"); 126 | strcat(sbuf, NAME); 127 | strcat(sbuf, " "); 128 | strcat(sbuf, VER); 129 | strcat(sbuf, "\n\n"); 130 | printf(sbuf); 131 | 132 | /* Check parameters */ 133 | printf("Checking parameters ...\n"); 134 | for (i = 1; i < argc; i++) 135 | { 136 | if (*argv[i] == '-') 137 | { 138 | if (!strncmp(argv[i], "-b", 2)) 139 | { 140 | /* Use specified blocksize */ 141 | printf(" Blocksize specified.\n"); 142 | ok = sscanf(argv[i], "-b%d", &buf); 143 | bs = (unsigned short int) buf; 144 | if (ok != 1) break; 145 | } 146 | else if (!strncmp(argv[i], "-t", 2)) 147 | { 148 | /* Use specified timeout */ 149 | printf(" Timeout specified.\n"); 150 | ok = sscanf(argv[i], "-t%d", &buf); 151 | if ((buf < 1) || (buf > 1800)) break; 152 | timeout = buf * 60 * HZ; 153 | if (ok != 1) break; 154 | } 155 | else 156 | { 157 | printf(" Unknown parameter: %s\n", argv[i]); 158 | file_name = 0; 159 | break; 160 | } 161 | } 162 | else 163 | { 164 | if (file_name == NULL) 165 | file_name = argv[i]; 166 | else 167 | { 168 | printf(" Parameter error\n"); 169 | file_name = 0; 170 | break; 171 | } 172 | } 173 | } 174 | if (file_name == NULL) 175 | { 176 | /* Parameter error, print help message */ 177 | fprintf(stderr, " Parameter error!\n"); 178 | sprintf(sbuf, " Usage: '"); 179 | strcat(sbuf, NAME); 180 | strcat(sbuf, 181 | " [-b] [-t] '\n\n"); 182 | fprintf(stderr, sbuf); 183 | exit(1); 184 | } 185 | printf(" Done.\n"); 186 | 187 | /* Set new block size */ 188 | printf("New blocksize: %u Bytes\n", (unsigned int) bs); 189 | para_list[10] = (unsigned char) ((bs & 0xFF00) >> 8); 190 | para_list[11] = (unsigned char) (bs & 0x00FF); 191 | 192 | /* Print timeout */ 193 | printf("Format timeout: %d minutes\n", (timeout / 60) / HZ); 194 | 195 | /* Open device file */ 196 | printf("Open device file ...\n"); 197 | fflush(stdout); 198 | if ((sg_fd = open(file_name, O_RDWR | O_EXCL)) < 0) 199 | { 200 | fprintf(stderr, " File open error! (root permissions?)\n\n"); 201 | exit(1); 202 | } 203 | /* Just to be safe, check we have a sg device by trying an ioctl */ 204 | if (ioctl(sg_fd, SG_GET_TIMEOUT, NULL) < 0) 205 | { 206 | fprintf(stderr, " File open error!\n"); 207 | fprintf(stderr, " '%s' doesn't seem to be a sg device\n\n", file_name); 208 | close(sg_fd); 209 | exit(1); 210 | } 211 | printf(" Done.\n"); 212 | 213 | /* Send INQUIRY command */ 214 | printf("Prepare command ...\n"); 215 | fflush(stdout); 216 | sghp->reply_len = sizeof(struct sg_header) + 0x20; 217 | sghp->pack_id = 0; 218 | sghp->twelve_byte = 0; 219 | memcpy(scsi_buf + sizeof(struct sg_header), inquiry, 0x06); 220 | printf(" Done.\n"); 221 | printf("Send INQUIRY command ...\n"); 222 | fflush(stdout); 223 | if (write(sg_fd, scsi_buf, inquiry_data_len) < 0) 224 | { 225 | fprintf(stderr, " Write error\n\n"); 226 | close(sg_fd); 227 | exit(1); 228 | } 229 | /* Read status (sense_buffer) */ 230 | if (read(sg_fd, scsi_buf, sizeof(struct sg_header) + 0x20) < 0) 231 | { 232 | fprintf(stderr, " Read error\n\n"); 233 | close(sg_fd); 234 | exit(1); 235 | } 236 | printf(" Done.\n"); 237 | /* Error processing */ 238 | printf("Check status ...\n"); 239 | fflush(stdout); 240 | if (sghp->pack_id != 0) /* This shouldn't happen */ 241 | printf(" Inquiry pack_id mismatch: Wanted=%d, Got=%d\n!", 242 | 0, sghp->pack_id); 243 | ok = 0; 244 | switch (sg_err_category(sghp->target_status, sghp->host_status, 245 | sghp->driver_status, sghp->sense_buffer, SG_MAX_SENSE)) 246 | { 247 | case SG_ERR_CAT_CLEAN: 248 | ok = 1; 249 | break; 250 | case SG_ERR_CAT_RECOVERED: 251 | printf(" Recovered error, continue\n"); 252 | ok = 1; 253 | break; 254 | default: 255 | sg_chk_n_print(" Error", sghp->target_status, 256 | sghp->host_status, sghp->driver_status, 257 | sghp->sense_buffer, SG_MAX_SENSE); 258 | break; 259 | } 260 | if (ok) 261 | printf(" Command successful.\n"); 262 | else 263 | { 264 | fprintf(stderr, " Command NOT succesful!\n\n"); 265 | close(sg_fd); 266 | exit(1); 267 | } 268 | 269 | /* Check for LUN to be valid */ 270 | printf("Check for LUN ...\n"); 271 | switch(scsi_buf[sizeof(struct sg_header)] >> 5) 272 | { 273 | case 0: 274 | printf(" LUN present.\n"); 275 | break; 276 | case 1: 277 | fprintf(stderr, " Error: LUN supported but not present!\n\n"); 278 | close(sg_fd); 279 | exit(1); 280 | case 3: 281 | fprintf(stderr, " Error: LUN not supported by this device!\n\n"); 282 | close(sg_fd); 283 | exit(1); 284 | default: 285 | fprintf(stderr, " Error: Cannot determine status of LUN!\n\n"); 286 | close(sg_fd); 287 | exit(1); 288 | } 289 | if (ioctl(sg_fd, SG_GET_SCSI_ID, &device) < 0) 290 | { 291 | fprintf(stderr, " Cannot determine ID & LUN numbers!\n"); 292 | close(sg_fd); 293 | exit(1); 294 | } 295 | 296 | /* Print device name and ask for OK */ 297 | printf("\n=================================================================\ 298 | ==============\n"); 299 | printf("SCSI ID : %d\n", device.scsi_id); 300 | printf("LUN : %d\n", device.lun); 301 | printf("Connected to: Host%d / Channel%d\n", device.host_no, device.channel); 302 | strncpy(sbuf, scsi_buf + sizeof(struct sg_header) + 0x08, 0x08); 303 | sbuf[0x08] = 0x00; 304 | printf("Manufacturer: %s\n", sbuf); 305 | strncpy(sbuf, scsi_buf + sizeof(struct sg_header) + 0x10, 0x10); 306 | sbuf[0x10] = 0x00; 307 | printf("Model : %s\n", sbuf); 308 | ok = 0; 309 | switch (scsi_buf[sizeof(struct sg_header)] & 0x1F) 310 | { 311 | case 0: 312 | sprintf(sbuf, "Disk"); 313 | ok = 1; 314 | break; 315 | case 1: 316 | sprintf(sbuf, "Tape"); 317 | break; 318 | case 2: 319 | sprintf(sbuf, "Printer"); 320 | break; 321 | case 3: 322 | sprintf(sbuf, "Processor"); 323 | break; 324 | case 4: 325 | sprintf(sbuf, "WORM"); 326 | break; 327 | case 5: 328 | sprintf(sbuf, "CDROM"); 329 | break; 330 | case 6: 331 | sprintf(sbuf, "Scanner"); 332 | break; 333 | case 7: 334 | sprintf(sbuf, "Optical disk"); 335 | ok = 1; 336 | break; 337 | case 8: 338 | sprintf(sbuf, "Media changer"); 339 | break; 340 | case 9: 341 | sprintf(sbuf, "Communication"); 342 | break; 343 | case 12: 344 | sprintf(sbuf, "Storage array controller"); 345 | break; 346 | default: 347 | sprintf(sbuf, "Unknown"); 348 | } 349 | printf("Device type : %s\n", sbuf); 350 | printf("=================================================================\ 351 | ==============\n"); 352 | if (!ok) 353 | { 354 | fprintf(stderr, "This type of device do not support the FORMAT UNIT \ 355 | command!\n"); 356 | printf("Exiting ...\n\n"); 357 | close(sg_fd); 358 | exit(1); 359 | } 360 | printf("Do you really want to reformat this device [y/n]? "); 361 | fflush(stdout); 362 | fscanf(stdin, "%c", &sbuf[0]); 363 | printf("\n"); 364 | if (sbuf[0] != 'y') 365 | { 366 | printf("Aborted.\n\nExiting ...\n\n"); 367 | close(sg_fd); 368 | exit(1); 369 | } 370 | 371 | /* Send MODE SELECT command */ 372 | printf("Prepare command ...\n"); 373 | fflush(stdout); 374 | sghp->reply_len = sizeof(struct sg_header); 375 | sghp->pack_id = 0; 376 | sghp->twelve_byte = 0; 377 | memcpy(scsi_buf + sizeof(struct sg_header), mode_select, 0x06); 378 | memcpy(scsi_buf + sizeof(struct sg_header) + 6, para_list, 0x0C); 379 | printf(" Done.\n"); 380 | printf("Send MODE SELECT command ...\n"); 381 | fflush(stdout); 382 | if (write(sg_fd, scsi_buf, mode_select_data_len) < 0) 383 | { 384 | fprintf(stderr, " Write error\n\n"); 385 | close(sg_fd); 386 | exit(1); 387 | } 388 | /* Read status (sense_buffer) */ 389 | if (read(sg_fd, scsi_buf, sizeof(struct sg_header)) < 0) 390 | { 391 | fprintf(stderr, " Read error\n\n"); 392 | close(sg_fd); 393 | exit(1); 394 | } 395 | printf(" Done.\n"); 396 | /* Error processing */ 397 | printf("Check status ...\n"); 398 | fflush(stdout); 399 | if (sghp->pack_id != 0) /* This shouldn't happen */ 400 | printf(" Inquiry pack_id mismatch: Wanted=%d, Got=%d\n!", 401 | 0, sghp->pack_id); 402 | ok = 0; 403 | switch (sg_err_category(sghp->target_status, sghp->host_status, 404 | sghp->driver_status, sghp->sense_buffer, SG_MAX_SENSE)) 405 | { 406 | case SG_ERR_CAT_CLEAN: 407 | ok = 1; 408 | break; 409 | case SG_ERR_CAT_RECOVERED: 410 | printf(" Recovered error, continue\n"); 411 | ok = 1; 412 | break; 413 | default: 414 | sg_chk_n_print(" Error", sghp->target_status, 415 | sghp->host_status, sghp->driver_status, 416 | sghp->sense_buffer, SG_MAX_SENSE); 417 | break; 418 | } 419 | if (ok) 420 | printf(" Command successful.\n"); 421 | else 422 | { 423 | fprintf(stderr, " Command NOT succesful!\n\n"); 424 | close(sg_fd); 425 | exit(1); 426 | } 427 | 428 | /* Send FORMAT UNIT command */ 429 | printf("Prepare command ...\n"); 430 | fflush(stdout); 431 | sghp->reply_len = sizeof(struct sg_header); 432 | sghp->pack_id = 0; 433 | sghp->twelve_byte = 0; 434 | memcpy(scsi_buf + sizeof(struct sg_header), format_unit, 0x06); 435 | buf = timeout; 436 | if (ioctl(sg_fd, SG_SET_TIMEOUT, &buf) < 0) 437 | { 438 | fprintf(stderr, " Error!\n"); 439 | fprintf(stderr, " Cannot set timeout\n\n"); 440 | close(sg_fd); 441 | exit(1); 442 | } 443 | printf(" Done.\n"); 444 | printf("Send FORMAT UNIT command ...\n"); 445 | fflush(stdout); 446 | if (write(sg_fd, scsi_buf, format_unit_data_len) < 0) 447 | { 448 | fprintf(stderr, " Write error\n\n"); 449 | close(sg_fd); 450 | exit(1); 451 | } 452 | /* Read status (sense_buffer) and data */ 453 | printf(" *** Please wait - Do not manually interrupt or power down! ***\n"); 454 | if (read(sg_fd, scsi_buf, sizeof(struct sg_header)) < 0) 455 | { 456 | fprintf(stderr, " Read error\n\n"); 457 | close(sg_fd); 458 | exit(1); 459 | } 460 | printf(" Done.\n"); 461 | /* Error processing */ 462 | printf("Check status ... \n"); 463 | if (sghp->pack_id != 0) /* This shouldn't happen */ 464 | printf(" Inquiry pack_id mismatch: Wanted=%d, Got=%d\n!", 465 | 0, sghp->pack_id); 466 | ok = 0; 467 | switch (sg_err_category(sghp->target_status, sghp->host_status, 468 | sghp->driver_status, sghp->sense_buffer, SG_MAX_SENSE)) 469 | { 470 | case SG_ERR_CAT_CLEAN: 471 | ok = 1; 472 | break; 473 | case SG_ERR_CAT_RECOVERED: 474 | printf(" Recovered error, continue\n"); 475 | ok = 1; 476 | break; 477 | default: 478 | sg_chk_n_print(" Error", sghp->target_status, 479 | sghp->host_status, sghp->driver_status, 480 | sghp->sense_buffer, SG_MAX_SENSE); 481 | break; 482 | } 483 | if (ok) 484 | printf(" Command successful.\n"); 485 | else 486 | { 487 | fprintf(stderr, " Command NOT succesful!\n\n"); 488 | close(sg_fd); 489 | exit(1); 490 | } 491 | 492 | /* Close device file */ 493 | printf("Close device file ...\n"); 494 | close(sg_fd); 495 | printf(" Done.\n"); 496 | 497 | /* Exit */ 498 | printf("\nExiting ...\n\n"); 499 | exit(0); 500 | } 501 | 502 | 503 | /* EOF */ 504 | -------------------------------------------------------------------------------- /sg_err.c: -------------------------------------------------------------------------------- 1 | /* 2 | ******************************************************************************** 3 | Header 4 | 5 | Project: setblocksize 6 | 7 | This file: sg_err.c 8 | 9 | Description: Routines for human readable SCSI error messages 10 | 11 | Copyright: (C) 1993, 1994, 1995 Eric Youngdale 12 | (C) 1999 - 2001 D. Gilbert 13 | (C) 2007 Michael Baeuerle 14 | License: GPL V2 or any later version 15 | 16 | Language: C 17 | Style rules: - 18 | 19 | Written for: Platform: all 20 | OS: GNU/Linux 21 | Tested with: Compiler: gcc (Version: 2.91.66) 22 | Platform: IA32 (Pentium) 23 | OS: GNU/Linux (Kernel version: 2.2.10) 24 | Tested with: Compiler: gcc (Version: 2.96.1) 25 | Platform: IA32 (Pentium2) 26 | OS: GNU/Linux (Kernel version: 2.4.21) 27 | Tested with: Compiler: gcc (Version: 3.3.6) 28 | Platform: IA32 (PentiumPro) 29 | OS: GNU/Linux (Kernel version: 2.6.16.20) 30 | Do not work: Platform: non GNU/Linux 31 | 32 | Created: 1993 by Eric Youngdale 33 | Last mod.: 2007-09-04 by Michael Baeuerle 34 | 35 | Changelog: 36 | 37 | ASCII values for a number of symbolic constants, printing functions, etc. 38 | Some of the tables have been updated for SCSI 2. 39 | 40 | V0.84 (2001-01-15) Change output from stdout to stderr 41 | 42 | 2003-03-22 Adapted for setblocksize 43 | 44 | 45 | To do: - 46 | ******************************************************************************** 47 | */ 48 | 49 | 50 | /* 51 | ******************************************************************************** 52 | * Include files 53 | ******************************************************************************** 54 | */ 55 | 56 | #include 57 | #include 58 | #include 59 | #include 60 | #include "sg_err.h" 61 | 62 | 63 | /* 64 | ******************************************************************************** 65 | * Code 66 | ******************************************************************************** 67 | */ 68 | 69 | #define OUTP stderr 70 | 71 | static const unsigned char scsi_command_size[8] = { 6, 10, 10, 12, 72 | 12, 12, 10, 10 }; 73 | 74 | #define COMMAND_SIZE(opcode) scsi_command_size[((opcode) >> 5) & 7] 75 | 76 | static const char unknown[] = "UNKNOWN"; 77 | 78 | 79 | static const char * group_0_commands[] = { 80 | /* 00-03 */ "Test Unit Ready", "Rezero Unit", unknown, "Request Sense", 81 | /* 04-07 */ "Format Unit", "Read Block Limits", unknown, "Reasssign Blocks", 82 | /* 08-0d */ "Read (6)", unknown, "Write (6)", "Seek (6)", unknown, unknown, 83 | /* 0e-12 */ unknown, "Read Reverse", "Write Filemarks", "Space", "Inquiry", 84 | /* 13-16 */ "Verify", "Recover Buffered Data", "Mode Select", "Reserve", 85 | /* 17-1b */ "Release", "Copy", "Erase", "Mode Sense", "Start/Stop Unit", 86 | /* 1c-1d */ "Receive Diagnostic", "Send Diagnostic", 87 | /* 1e-1f */ "Prevent/Allow Medium Removal", unknown, 88 | }; 89 | 90 | 91 | static const char *group_1_commands[] = { 92 | /* 20-22 */ unknown, unknown, unknown, 93 | /* 23-28 */ unknown, "Define window parameters", "Read Capacity", 94 | unknown, unknown, "Read (10)", 95 | /* 29-2d */ "Read Generation", "Write (10)", "Seek (10)", "Erase", 96 | "Read updated block", 97 | /* 2e-31 */ "Write Verify","Verify", "Search High", "Search Equal", 98 | /* 32-34 */ "Search Low", "Set Limits", "Prefetch or Read Position", 99 | /* 35-37 */ "Synchronize Cache","Lock/Unlock Cache", "Read Defect Data", 100 | /* 38-3c */ "Medium Scan", "Compare", "Copy Verify", "Write Buffer", 101 | "Read Buffer", 102 | /* 3d-3f */ "Update Block", "Read Long", "Write Long", 103 | }; 104 | 105 | 106 | static const char *group_2_commands[] = { 107 | /* 40-41 */ "Change Definition", "Write Same", 108 | /* 42-48 */ "Read sub-channel", "Read TOC", "Read header", 109 | "Play audio (10)", unknown, "Play audio msf", 110 | "Play audio track/index", 111 | /* 49-4f */ "Play track relative (10)", unknown, "Pause/resume", 112 | "Log Select", "Log Sense", unknown, unknown, 113 | /* 50-55 */ unknown, unknown, unknown, unknown, unknown, "Mode Select (10)", 114 | /* 56-5b */ unknown, unknown, unknown, unknown, "Mode Sense (10)", unknown, 115 | /* 5c-5f */ unknown, unknown, unknown, 116 | }; 117 | 118 | 119 | /* The following are 12 byte commands in group 5 */ 120 | static const char *group_5_commands[] = { 121 | /* a0-a5 */ unknown, unknown, unknown, unknown, unknown, 122 | "Move medium/play audio(12)", 123 | /* a6-a9 */ "Exchange medium", unknown, "Read(12)", "Play track relative(12)", 124 | /* aa-ae */ "Write(12)", unknown, "Erase(12)", unknown, 125 | "Write and verify(12)", 126 | /* af-b1 */ "Verify(12)", "Search data high(12)", "Search data equal(12)", 127 | /* b2-b4 */ "Search data low(12)", "Set limits(12)", unknown, 128 | /* b5-b6 */ "Request volume element address", "Send volume tag", 129 | /* b7-b9 */ "Read defect data(12)", "Read element status", unknown, 130 | /* ba-bf */ unknown, unknown, unknown, unknown, unknown, unknown, 131 | }; 132 | 133 | 134 | #define group(opcode) (((opcode) >> 5) & 7) 135 | 136 | #define RESERVED_GROUP 0 137 | #define VENDOR_GROUP 1 138 | 139 | 140 | static const char **commands[] = { 141 | group_0_commands, group_1_commands, group_2_commands, 142 | (const char **) RESERVED_GROUP, (const char **) RESERVED_GROUP, 143 | group_5_commands, (const char **) VENDOR_GROUP, 144 | (const char **) VENDOR_GROUP 145 | }; 146 | 147 | 148 | static const char reserved[] = "RESERVED"; 149 | static const char vendor[] = "VENDOR SPECIFIC"; 150 | 151 | 152 | static void print_opcode(int opcode) { 153 | const char **table = commands[ group(opcode) ]; 154 | switch ((unsigned long) table) { 155 | case RESERVED_GROUP: 156 | fprintf(OUTP, "%s(0x%02x) ", reserved, opcode); 157 | break; 158 | case VENDOR_GROUP: 159 | fprintf(OUTP, "%s(0x%02x) ", vendor, opcode); 160 | break; 161 | default: 162 | if (table[opcode & 0x1f] != unknown) 163 | fprintf(OUTP, "%s ",table[opcode & 0x1f]); 164 | else 165 | fprintf(OUTP, "%s(0x%02x) ", unknown, opcode); 166 | break; 167 | } 168 | } 169 | 170 | 171 | void sg_print_command (const unsigned char * command) { 172 | int i,s; 173 | print_opcode(command[0]); 174 | for ( i = 1, s = COMMAND_SIZE(command[0]); i < s; ++i) 175 | fprintf(OUTP, "%02x ", command[i]); 176 | fprintf(OUTP, "\n"); 177 | } 178 | 179 | 180 | static const char * statuses[] = { 181 | /* 0-4 */ "Good", "Check Condition", "Condition Met", unknown, "Busy", 182 | /* 5-9 */ unknown, unknown, unknown, "Intermediate", unknown, 183 | /* a-c */ "Intermediate-Condition Met", unknown, "Reservation Conflict", 184 | /* d-10 */ unknown, unknown, unknown, unknown, 185 | /* 11-14 */ "Command Terminated", unknown, unknown, "Queue Full", 186 | /* 15-1a */ unknown, unknown, unknown, unknown, unknown, unknown, 187 | /* 1b-1f */ unknown, unknown, unknown, unknown, unknown, 188 | }; 189 | 190 | 191 | void sg_print_status (int masked_status) { 192 | /* status = (status >> 1) & 0xf; */ /* already done */ 193 | fprintf(OUTP, "%s ",statuses[masked_status]); 194 | } 195 | 196 | 197 | #define D 0x001 /* DIRECT ACCESS DEVICE (disk) */ 198 | #define T 0x002 /* SEQUENTIAL ACCESS DEVICE (tape) */ 199 | #define L 0x004 /* PRINTER DEVICE */ 200 | #define P 0x008 /* PROCESSOR DEVICE */ 201 | #define W 0x010 /* WRITE ONCE READ MULTIPLE DEVICE */ 202 | #define R 0x020 /* READ ONLY (CD-ROM) DEVICE */ 203 | #define S 0x040 /* SCANNER DEVICE */ 204 | #define O 0x080 /* OPTICAL MEMORY DEVICE */ 205 | #define M 0x100 /* MEDIA CHANGER DEVICE */ 206 | #define C 0x200 /* COMMUNICATION DEVICE */ 207 | 208 | 209 | struct error_info{ 210 | unsigned char code1, code2; 211 | unsigned short int devices; 212 | const char * text; 213 | }; 214 | 215 | 216 | struct error_info2{ 217 | unsigned char code1, code2_min, code2_max; 218 | unsigned short int devices; 219 | const char * text; 220 | }; 221 | 222 | 223 | static struct error_info2 additional2[] = 224 | { 225 | {0x40,0x00,0x7f,D,"Ram failure (%x)"}, 226 | {0x40,0x80,0xff,D|T|L|P|W|R|S|O|M|C,"Diagnostic failure on component (%x)"}, 227 | {0x41,0x00,0xff,D,"Data path failure (%x)"}, 228 | {0x42,0x00,0xff,D,"Power-on or self-test failure (%x)"}, 229 | {0, 0, 0, 0, NULL} 230 | }; 231 | 232 | 233 | static struct error_info additional[] = 234 | { 235 | {0x00,0x01,T,"Filemark detected"}, 236 | {0x00,0x02,T|S,"End-of-partition/medium detected"}, 237 | {0x00,0x03,T,"Setmark detected"}, 238 | {0x00,0x04,T|S,"Beginning-of-partition/medium detected"}, 239 | {0x00,0x05,T|S,"End-of-data detected"}, 240 | {0x00,0x06,D|T|L|P|W|R|S|O|M|C,"I/O process terminated"}, 241 | {0x00,0x11,R,"Audio play operation in progress"}, 242 | {0x00,0x12,R,"Audio play operation paused"}, 243 | {0x00,0x13,R,"Audio play operation successfully completed"}, 244 | {0x00,0x14,R,"Audio play operation stopped due to error"}, 245 | {0x00,0x15,R,"No current audio status to return"}, 246 | {0x01,0x00,D|W|O,"No index/sector signal"}, 247 | {0x02,0x00,D|W|R|O|M,"No seek complete"}, 248 | {0x03,0x00,D|T|L|W|S|O,"Peripheral device write fault"}, 249 | {0x03,0x01,T,"No write current"}, 250 | {0x03,0x02,T,"Excessive write errors"}, 251 | {0x04,0x00,D|T|L|P|W|R|S|O|M|C, 252 | "Logical unit not ready, cause not reportable"}, 253 | {0x04,0x01,D|T|L|P|W|R|S|O|M|C, 254 | "Logical unit is in process of becoming ready"}, 255 | {0x04,0x02,D|T|L|P|W|R|S|O|M|C, 256 | "Logical unit not ready, initializing command required"}, 257 | {0x04,0x03,D|T|L|P|W|R|S|O|M|C, 258 | "Logical unit not ready, manual intervention required"}, 259 | {0x04,0x04,D|T|L|O,"Logical unit not ready, format in progress"}, 260 | {0x05,0x00,D|T|L|W|R|S|O|M|C,"Logical unit does not respond to selection"}, 261 | {0x06,0x00,D|W|R|O|M,"No reference position found"}, 262 | {0x07,0x00,D|T|L|W|R|S|O|M,"Multiple peripheral devices selected"}, 263 | {0x08,0x00,D|T|L|W|R|S|O|M|C,"Logical unit communication failure"}, 264 | {0x08,0x01,D|T|L|W|R|S|O|M|C,"Logical unit communication time-out"}, 265 | {0x08,0x02,D|T|L|W|R|S|O|M|C,"Logical unit communication parity error"}, 266 | {0x09,0x00,D|T|W|R|O,"Track following error"}, 267 | {0x09,0x01,W|R|O,"Tracking servo failure"}, 268 | {0x09,0x02,W|R|O,"Focus servo failure"}, 269 | {0x09,0x03,W|R|O,"Spindle servo failure"}, 270 | {0x0A,0x00,D|T|L|P|W|R|S|O|M|C,"Error log overflow"}, 271 | {0x0C,0x00,T|S,"Write error"}, 272 | {0x0C,0x01,D|W|O,"Write error recovered with auto reallocation"}, 273 | {0x0C,0x02,D|W|O,"Write error - auto reallocation failed"}, 274 | {0x10,0x00,D|W|O,"Id crc or ecc error"}, 275 | {0x11,0x00,D|T|W|R|S|O,"Unrecovered read error"}, 276 | {0x11,0x01,D|T|W|S|O,"Read retries exhausted"}, 277 | {0x11,0x02,D|T|W|S|O,"Error too long to correct"}, 278 | {0x11,0x03,D|T|W|S|O,"Multiple read errors"}, 279 | {0x11,0x04,D|W|O,"Unrecovered read error - auto reallocate failed"}, 280 | {0x11,0x05,W|R|O,"L-ec uncorrectable error"}, 281 | {0x11,0x06,W|R|O,"Circ unrecovered error"}, 282 | {0x11,0x07,W|O,"Data resynchronization error"}, 283 | {0x11,0x08,T,"Incomplete block read"}, 284 | {0x11,0x09,T,"No gap found"}, 285 | {0x11,0x0A,D|T|O,"Miscorrected error"}, 286 | {0x11,0x0B,D|W|O,"Unrecovered read error - recommend reassignment"}, 287 | {0x11,0x0C,D|W|O,"Unrecovered read error - recommend rewrite the data"}, 288 | {0x12,0x00,D|W|O,"Address mark not found for id field"}, 289 | {0x13,0x00,D|W|O,"Address mark not found for data field"}, 290 | {0x14,0x00,D|T|L|W|R|S|O,"Recorded entity not found"}, 291 | {0x14,0x01,D|T|W|R|O,"Record not found"}, 292 | {0x14,0x02,T,"Filemark or setmark not found"}, 293 | {0x14,0x03,T,"End-of-data not found"}, 294 | {0x14,0x04,T,"Block sequence error"}, 295 | {0x15,0x00,D|T|L|W|R|S|O|M,"Random positioning error"}, 296 | {0x15,0x01,D|T|L|W|R|S|O|M,"Mechanical positioning error"}, 297 | {0x15,0x02,D|T|W|R|O,"Positioning error detected by read of medium"}, 298 | {0x16,0x00,D|W|O,"Data synchronization mark error"}, 299 | {0x17,0x00,D|T|W|R|S|O,"Recovered data with no error correction applied"}, 300 | {0x17,0x01,D|T|W|R|S|O,"Recovered data with retries"}, 301 | {0x17,0x02,D|T|W|R|O,"Recovered data with positive head offset"}, 302 | {0x17,0x03,D|T|W|R|O,"Recovered data with negative head offset"}, 303 | {0x17,0x04,W|R|O,"Recovered data with retries and/or circ applied"}, 304 | {0x17,0x05,D|W|R|O,"Recovered data using previous sector id"}, 305 | {0x17,0x06,D|W|O,"Recovered data without ecc - data auto-reallocated"}, 306 | {0x17,0x07,D|W|O,"Recovered data without ecc - recommend reassignment"}, 307 | {0x18,0x00,D|T|W|R|O,"Recovered data with error correction applied"}, 308 | {0x18,0x01,D|W|R|O,"Recovered data with error correction and retries applied"}, 309 | {0x18,0x02,D|W|R|O,"Recovered data - data auto-reallocated"}, 310 | {0x18,0x03,R,"Recovered data with circ"}, 311 | {0x18,0x04,R,"Recovered data with lec"}, 312 | {0x18,0x05,D|W|R|O,"Recovered data - recommend reassignment"}, 313 | {0x19,0x00,D|O,"Defect list error"}, 314 | {0x19,0x01,D|O,"Defect list not available"}, 315 | {0x19,0x02,D|O,"Defect list error in primary list"}, 316 | {0x19,0x03,D|O,"Defect list error in grown list"}, 317 | {0x1A,0x00,D|T|L|P|W|R|S|O|M|C,"Parameter list length error"}, 318 | {0x1B,0x00,D|T|L|P|W|R|S|O|M|C,"Synchronous data transfer error"}, 319 | {0x1C,0x00,D|O,"Defect list not found"}, 320 | {0x1C,0x01,D|O,"Primary defect list not found"}, 321 | {0x1C,0x02,D|O,"Grown defect list not found"}, 322 | {0x1D,0x00,D|W|O,"Miscompare during verify operation"}, 323 | {0x1E,0x00,D|W|O,"Recovered id with ecc correction"}, 324 | {0x20,0x00,D|T|L|P|W|R|S|O|M|C,"Invalid command operation code"}, 325 | {0x21,0x00,D|T|W|R|O|M,"Logical block address out of range"}, 326 | {0x21,0x01,M,"Invalid element address"}, 327 | {0x22,0x00,D,"Illegal function (should use 20 00, 24 00, or 26 00)"}, 328 | {0x24,0x00,D|T|L|P|W|R|S|O|M|C,"Invalid field in cdb"}, 329 | {0x25,0x00,D|T|L|P|W|R|S|O|M|C,"Logical unit not supported"}, 330 | {0x26,0x00,D|T|L|P|W|R|S|O|M|C,"Invalid field in parameter list"}, 331 | {0x26,0x01,D|T|L|P|W|R|S|O|M|C,"Parameter not supported"}, 332 | {0x26,0x02,D|T|L|P|W|R|S|O|M|C,"Parameter value invalid"}, 333 | {0x26,0x03,D|T|L|P|W|R|S|O|M|C,"Threshold parameters not supported"}, 334 | {0x27,0x00,D|T|W|O,"Write protected"}, 335 | {0x28,0x00,D|T|L|P|W|R|S|O|M|C,"Not ready to ready transition (medium may have changed)"}, 336 | {0x28,0x01,M,"Import or export element accessed"}, 337 | {0x29,0x00,D|T|L|P|W|R|S|O|M|C,"Power on, reset, or bus device reset occurred"}, 338 | {0x2A,0x00,D|T|L|W|R|S|O|M|C,"Parameters changed"}, 339 | {0x2A,0x01,D|T|L|W|R|S|O|M|C,"Mode parameters changed"}, 340 | {0x2A,0x02,D|T|L|W|R|S|O|M|C,"Log parameters changed"}, 341 | {0x2B,0x00,D|T|L|P|W|R|S|O|C,"Copy cannot execute since host cannot disconnect"}, 342 | {0x2C,0x00,D|T|L|P|W|R|S|O|M|C,"Command sequence error"}, 343 | {0x2C,0x01,S,"Too many windows specified"}, 344 | {0x2C,0x02,S,"Invalid combination of windows specified"}, 345 | {0x2D,0x00,T,"Overwrite error on update in place"}, 346 | {0x2F,0x00,D|T|L|P|W|R|S|O|M|C,"Commands cleared by another initiator"}, 347 | {0x30,0x00,D|T|W|R|O|M,"Incompatible medium installed"}, 348 | {0x30,0x01,D|T|W|R|O,"Cannot read medium - unknown format"}, 349 | {0x30,0x02,D|T|W|R|O,"Cannot read medium - incompatible format"}, 350 | {0x30,0x03,D|T,"Cleaning cartridge installed"}, 351 | {0x31,0x00,D|T|W|O,"Medium format corrupted"}, 352 | {0x31,0x01,D|L|O,"Format command failed"}, 353 | {0x32,0x00,D|W|O,"No defect spare location available"}, 354 | {0x32,0x01,D|W|O,"Defect list update failure"}, 355 | {0x33,0x00,T,"Tape length error"}, 356 | {0x36,0x00,L,"Ribbon, ink, or toner failure"}, 357 | {0x37,0x00,D|T|L|W|R|S|O|M|C,"Rounded parameter"}, 358 | {0x39,0x00,D|T|L|W|R|S|O|M|C,"Saving parameters not supported"}, 359 | {0x3A,0x00,D|T|L|W|R|S|O|M,"Medium not present"}, 360 | {0x3B,0x00,T|L,"Sequential positioning error"}, 361 | {0x3B,0x01,T,"Tape position error at beginning-of-medium"}, 362 | {0x3B,0x02,T,"Tape position error at end-of-medium"}, 363 | {0x3B,0x03,L,"Tape or electronic vertical forms unit not ready"}, 364 | {0x3B,0x04,L,"Slew failure"}, 365 | {0x3B,0x05,L,"Paper jam"}, 366 | {0x3B,0x06,L,"Failed to sense top-of-form"}, 367 | {0x3B,0x07,L,"Failed to sense bottom-of-form"}, 368 | {0x3B,0x08,T,"Reposition error"}, 369 | {0x3B,0x09,S,"Read past end of medium"}, 370 | {0x3B,0x0A,S,"Read past beginning of medium"}, 371 | {0x3B,0x0B,S,"Position past end of medium"}, 372 | {0x3B,0x0C,S,"Position past beginning of medium"}, 373 | {0x3B,0x0D,M,"Medium destination element full"}, 374 | {0x3B,0x0E,M,"Medium source element empty"}, 375 | {0x3D,0x00,D|T|L|P|W|R|S|O|M|C,"Invalid bits in identify message"}, 376 | {0x3E,0x00,D|T|L|P|W|R|S|O|M|C,"Logical unit has not self-configured yet"}, 377 | {0x3F,0x00,D|T|L|P|W|R|S|O|M|C,"Target operating conditions have changed"}, 378 | {0x3F,0x01,D|T|L|P|W|R|S|O|M|C,"Microcode has been changed"}, 379 | {0x3F,0x02,D|T|L|P|W|R|S|O|M|C,"Changed operating definition"}, 380 | {0x3F,0x03,D|T|L|P|W|R|S|O|M|C,"Inquiry data has changed"}, 381 | {0x43,0x00,D|T|L|P|W|R|S|O|M|C,"Message error"}, 382 | {0x44,0x00,D|T|L|P|W|R|S|O|M|C,"Internal target failure"}, 383 | {0x45,0x00,D|T|L|P|W|R|S|O|M|C,"Select or reselect failure"}, 384 | {0x46,0x00,D|T|L|P|W|R|S|O|M|C,"Unsuccessful soft reset"}, 385 | {0x47,0x00,D|T|L|P|W|R|S|O|M|C,"Scsi parity error"}, 386 | {0x48,0x00,D|T|L|P|W|R|S|O|M|C,"Initiator detected error message received"}, 387 | {0x49,0x00,D|T|L|P|W|R|S|O|M|C,"Invalid message error"}, 388 | {0x4A,0x00,D|T|L|P|W|R|S|O|M|C,"Command phase error"}, 389 | {0x4B,0x00,D|T|L|P|W|R|S|O|M|C,"Data phase error"}, 390 | {0x4C,0x00,D|T|L|P|W|R|S|O|M|C,"Logical unit failed self-configuration"}, 391 | {0x4E,0x00,D|T|L|P|W|R|S|O|M|C,"Overlapped commands attempted"}, 392 | {0x50,0x00,T,"Write append error"}, 393 | {0x50,0x01,T,"Write append position error"}, 394 | {0x50,0x02,T,"Position error related to timing"}, 395 | {0x51,0x00,T|O,"Erase failure"}, 396 | {0x52,0x00,T,"Cartridge fault"}, 397 | {0x53,0x00,D|T|L|W|R|S|O|M,"Media load or eject failed"}, 398 | {0x53,0x01,T,"Unload tape failure"}, 399 | {0x53,0x02,D|T|W|R|O|M,"Medium removal prevented"}, 400 | {0x54,0x00,P,"Scsi to host system interface failure"}, 401 | {0x55,0x00,P,"System resource failure"}, 402 | {0x57,0x00,R,"Unable to recover table-of-contents"}, 403 | {0x58,0x00,O,"Generation does not exist"}, 404 | {0x59,0x00,O,"Updated block read"}, 405 | {0x5A,0x00,D|T|L|P|W|R|S|O|M,"Operator request or state change input (unspecified)"}, 406 | {0x5A,0x01,D|T|W|R|O|M,"Operator medium removal request"}, 407 | {0x5A,0x02,D|T|W|O,"Operator selected write protect"}, 408 | {0x5A,0x03,D|T|W|O,"Operator selected write permit"}, 409 | {0x5B,0x00,D|T|L|P|W|R|S|O|M,"Log exception"}, 410 | {0x5B,0x01,D|T|L|P|W|R|S|O|M,"Threshold condition met"}, 411 | {0x5B,0x02,D|T|L|P|W|R|S|O|M,"Log counter at maximum"}, 412 | {0x5B,0x03,D|T|L|P|W|R|S|O|M,"Log list codes exhausted"}, 413 | {0x5C,0x00,D|O,"Rpl status change"}, 414 | {0x5C,0x01,D|O,"Spindles synchronized"}, 415 | {0x5C,0x02,D|O,"Spindles not synchronized"}, 416 | {0x60,0x00,S,"Lamp failure"}, 417 | {0x61,0x00,S,"Video acquisition error"}, 418 | {0x61,0x01,S,"Unable to acquire video"}, 419 | {0x61,0x02,S,"Out of focus"}, 420 | {0x62,0x00,S,"Scan head positioning error"}, 421 | {0x63,0x00,R,"End of user area encountered on this track"}, 422 | {0x64,0x00,R,"Illegal mode for this track"}, 423 | {0, 0, 0, NULL} 424 | }; 425 | 426 | 427 | static const char *snstext[] = { 428 | "None", /* There is no sense information */ 429 | "Recovered Error", /* The last command completed successfully 430 | but used error correction */ 431 | "Not Ready", /* The addressed target is not ready */ 432 | "Medium Error", /* Data error detected on the medium */ 433 | "Hardware Error", /* Controller or device failure */ 434 | "Illegal Request", 435 | "Unit Attention", /* Removable medium was changed, or 436 | the target has been reset */ 437 | "Data Protect", /* Access to the data is blocked */ 438 | "Blank Check", /* Reached unexpected written or unwritten 439 | region of the medium */ 440 | "Key=9", /* Vendor specific */ 441 | "Copy Aborted", /* COPY or COMPARE was aborted */ 442 | "Aborted Command", /* The target aborted the command */ 443 | "Equal", /* A SEARCH DATA command found data equal */ 444 | "Volume Overflow", /* Medium full with still data to be written */ 445 | "Miscompare", /* Source data and data on the medium 446 | do not agree */ 447 | "Key=15" /* Reserved */ 448 | }; 449 | 450 | 451 | /* Print sense information */ 452 | void sg_print_sense(const char * leadin, const unsigned char * sense_buffer, 453 | int sb_len) 454 | { 455 | int i, s; 456 | int sense_class, valid, code; 457 | const char * error = NULL; 458 | 459 | sense_class = (sense_buffer[0] >> 4) & 0x07; 460 | code = sense_buffer[0] & 0xf; 461 | valid = sense_buffer[0] & 0x80; 462 | 463 | if (sense_class == 7) { /* extended sense data */ 464 | s = sense_buffer[7] + 8; 465 | if(s > sb_len) 466 | s = sb_len; 467 | 468 | if (!valid) 469 | fprintf(OUTP, "[valid=0] "); 470 | fprintf(OUTP, "Info fld=0x%x, ", (int)((sense_buffer[3] << 24) | 471 | (sense_buffer[4] << 16) | (sense_buffer[5] << 8) | 472 | sense_buffer[6])); 473 | 474 | if (sense_buffer[2] & 0x80) 475 | fprintf(OUTP, "FMK "); /* current command has read a filemark */ 476 | if (sense_buffer[2] & 0x40) 477 | fprintf(OUTP, "EOM "); /* end-of-medium condition exists */ 478 | if (sense_buffer[2] & 0x20) 479 | fprintf(OUTP, "ILI "); /* incorrect block length requested */ 480 | 481 | switch (code) { 482 | case 0x0: 483 | error = "Current"; /* error concerns current command */ 484 | break; 485 | case 0x1: 486 | error = "Deferred"; /* error concerns some earlier command */ 487 | /* e.g., an earlier write to disk cache succeeded, but 488 | now the disk discovers that it cannot write the data */ 489 | break; 490 | default: 491 | error = "Invalid"; 492 | } 493 | 494 | fprintf(OUTP, "%s ", error); 495 | 496 | if (leadin) 497 | fprintf(OUTP, "%s: ", leadin); 498 | fprintf(OUTP, "sense key: %s\n", snstext[sense_buffer[2] & 0x0f]); 499 | 500 | /* Check to see if additional sense information is available */ 501 | if(sense_buffer[7] + 7 < 13 || 502 | (sense_buffer[12] == 0 && sense_buffer[13] == 0)) goto done; 503 | 504 | for(i=0; additional[i].text; i++) 505 | if(additional[i].code1 == sense_buffer[12] && 506 | additional[i].code2 == sense_buffer[13]) 507 | fprintf(OUTP, "Additional sense indicates: %s\n", 508 | additional[i].text); 509 | 510 | for(i=0; additional2[i].text; i++) 511 | if(additional2[i].code1 == sense_buffer[12] && 512 | additional2[i].code2_min >= sense_buffer[13] && 513 | additional2[i].code2_max <= sense_buffer[13]) { 514 | fprintf(OUTP, "Additional sense indicates: "); 515 | fprintf(OUTP, additional2[i].text, sense_buffer[13]); 516 | fprintf(OUTP, "\n"); 517 | }; 518 | } else { /* non-extended sense data */ 519 | 520 | /* 521 | * Standard says: 522 | * sense_buffer[0] & 0200 : address valid 523 | * sense_buffer[0] & 0177 : vendor-specific error code 524 | * sense_buffer[1] & 0340 : vendor-specific 525 | * sense_buffer[1..3] : 21-bit logical block address 526 | */ 527 | 528 | if (leadin) 529 | fprintf(OUTP, "%s: ", leadin); 530 | if (sense_buffer[0] < 15) 531 | fprintf(OUTP, 532 | "old sense: key %s\n", snstext[sense_buffer[0] & 0x0f]); 533 | else 534 | fprintf(OUTP, "sns = %2x %2x\n", sense_buffer[0], sense_buffer[2]); 535 | 536 | fprintf(OUTP, "Non-extended sense class %d code 0x%0x ", 537 | sense_class, code); 538 | s = 4; 539 | } 540 | 541 | done: 542 | fprintf(OUTP, "Raw sense data (in hex):\n "); 543 | for (i = 0; i < s; ++i) { 544 | if ((i > 0) && (0 == (i % 24))) 545 | fprintf(OUTP, "\n "); 546 | fprintf(OUTP, "%02x ", sense_buffer[i]); 547 | } 548 | fprintf(OUTP, "\n"); 549 | return; 550 | } 551 | 552 | 553 | static const char * hostbyte_table[]={ 554 | "DID_OK", "DID_NO_CONNECT", "DID_BUS_BUSY", "DID_TIME_OUT", "DID_BAD_TARGET", 555 | "DID_ABORT", "DID_PARITY", "DID_ERROR", "DID_RESET", "DID_BAD_INTR", 556 | "DID_PASSTHROUGH", "DID_SOFT_ERROR", NULL}; 557 | 558 | 559 | void sg_print_host_status(int host_status) 560 | { static int maxcode=0; 561 | int i; 562 | 563 | if(! maxcode) { 564 | for(i = 0; hostbyte_table[i]; i++) ; 565 | maxcode = i-1; 566 | } 567 | fprintf(OUTP, "Host_status=0x%02x", host_status); 568 | if(host_status > maxcode) { 569 | fprintf(OUTP, "is invalid "); 570 | return; 571 | } 572 | fprintf(OUTP, "(%s) ",hostbyte_table[host_status]); 573 | } 574 | 575 | 576 | static const char * driverbyte_table[]={ 577 | "DRIVER_OK", "DRIVER_BUSY", "DRIVER_SOFT", "DRIVER_MEDIA", "DRIVER_ERROR", 578 | "DRIVER_INVALID", "DRIVER_TIMEOUT", "DRIVER_HARD", "DRIVER_SENSE", NULL}; 579 | 580 | 581 | static const char * driversuggest_table[]={"SUGGEST_OK", 582 | "SUGGEST_RETRY", "SUGGEST_ABORT", "SUGGEST_REMAP", "SUGGEST_DIE", 583 | unknown,unknown,unknown, "SUGGEST_SENSE",NULL}; 584 | 585 | 586 | void sg_print_driver_status(int driver_status) 587 | { 588 | static int driver_max =0 , suggest_max=0; 589 | int i; 590 | int dr = driver_status & SG_ERR_DRIVER_MASK; 591 | int su = (driver_status & SG_ERR_SUGGEST_MASK) >> 4; 592 | 593 | if(! driver_max) { 594 | for(i = 0; driverbyte_table[i]; i++) ; 595 | driver_max = i; 596 | for(i = 0; driversuggest_table[i]; i++) ; 597 | suggest_max = i; 598 | } 599 | fprintf(OUTP, "Driver_status=0x%02x",driver_status); 600 | fprintf(OUTP, " (%s,%s) ", 601 | dr < driver_max ? driverbyte_table[dr]:"invalid", 602 | su < suggest_max ? driversuggest_table[su]:"invalid"); 603 | } 604 | 605 | 606 | #ifdef SG_IO 607 | int sg_chk_n_print3(const char * leadin, struct sg_io_hdr * hp) 608 | { 609 | return sg_chk_n_print(leadin, hp->masked_status, hp->host_status, 610 | hp->driver_status, hp->sbp, hp->sb_len_wr); 611 | } 612 | #endif 613 | 614 | 615 | int sg_chk_n_print(const char * leadin, int masked_status, 616 | int host_status, int driver_status, 617 | const unsigned char * sense_buffer, int sb_len) 618 | { 619 | int done_leadin = 0; 620 | int done_sense = 0; 621 | 622 | if ((0 == masked_status) && (0 == host_status) && 623 | (0 == driver_status)) 624 | return 1; /* No problems */ 625 | if (0 != masked_status) { 626 | if (leadin) 627 | fprintf(OUTP, "%s: ", leadin); 628 | done_leadin = 1; 629 | sg_print_status(masked_status); 630 | fprintf(OUTP, "\n"); 631 | if (sense_buffer && ((masked_status == CHECK_CONDITION) || 632 | (masked_status == COMMAND_TERMINATED))) { 633 | sg_print_sense(0, sense_buffer, sb_len); 634 | done_sense = 1; 635 | } 636 | } 637 | if (0 != host_status) { 638 | if (leadin && (! done_leadin)) 639 | fprintf(OUTP, "%s: ", leadin); 640 | if (done_leadin) 641 | fprintf(OUTP, " plus...: "); 642 | else 643 | done_leadin = 1; 644 | sg_print_host_status(host_status); 645 | fprintf(OUTP, "\n"); 646 | } 647 | if (0 != driver_status) { 648 | if (leadin && (! done_leadin)) 649 | fprintf(OUTP, "%s: ", leadin); 650 | if (done_leadin) 651 | fprintf(OUTP, " plus...: "); 652 | else 653 | done_leadin = 1; 654 | sg_print_driver_status(driver_status); 655 | fprintf(OUTP, "\n"); 656 | if (sense_buffer && (! done_sense) && 657 | (SG_ERR_DRIVER_SENSE & driver_status)) 658 | sg_print_sense(0, sense_buffer, sb_len); 659 | } 660 | return 0; 661 | } 662 | 663 | 664 | #ifdef SG_IO 665 | int sg_err_category3(struct sg_io_hdr * hp) 666 | { 667 | return sg_err_category(hp->masked_status, hp->host_status, 668 | hp->driver_status, hp->sbp, hp->sb_len_wr); 669 | } 670 | #endif 671 | 672 | 673 | int sg_err_category(int masked_status, int host_status, 674 | int driver_status, const unsigned char * sense_buffer, 675 | int sb_len) 676 | { 677 | if ((0 == masked_status) && (0 == host_status) && 678 | (0 == driver_status)) 679 | return SG_ERR_CAT_CLEAN; 680 | if ((CHECK_CONDITION == masked_status) || 681 | (COMMAND_TERMINATED == masked_status) || 682 | (SG_ERR_DRIVER_SENSE & driver_status)) { 683 | if (sense_buffer && (sb_len > 2)) { 684 | if(RECOVERED_ERROR == sense_buffer[2]) 685 | return SG_ERR_CAT_RECOVERED; 686 | else if ((UNIT_ATTENTION == (0x0f & sense_buffer[2])) && 687 | (sb_len > 12)) { 688 | if (0x28 == sense_buffer[12]) 689 | return SG_ERR_CAT_MEDIA_CHANGED; 690 | if (0x29 == sense_buffer[12]) 691 | return SG_ERR_CAT_RESET; 692 | } 693 | } 694 | return SG_ERR_CAT_SENSE; 695 | } 696 | if (0 != host_status) { 697 | if ((SG_ERR_DID_NO_CONNECT == host_status) || 698 | (SG_ERR_DID_BUS_BUSY == host_status) || 699 | (SG_ERR_DID_TIME_OUT == host_status)) 700 | return SG_ERR_CAT_TIMEOUT; 701 | } 702 | if (0 != driver_status) { 703 | if (SG_ERR_DRIVER_TIMEOUT == driver_status) 704 | return SG_ERR_CAT_TIMEOUT; 705 | } 706 | return SG_ERR_CAT_OTHER; 707 | } 708 | 709 | 710 | int sg_get_command_size(unsigned char opcode) 711 | { 712 | return COMMAND_SIZE(opcode); 713 | } 714 | 715 | 716 | /* EOF */ 717 | --------------------------------------------------------------------------------