====================================================================== SCSIBios V1.0 (c) 1991 by Oliver Groeger Graf-Konrad-Str. 25 8000 Muenchen 40 ====================================================================== Contents: ========= 1. Intro 2. Disclaimer 3. Check the System for SCSIBios 4. Functions Provided By SCSIBios 4.1. Common Functions 4.1.1 SCSIVersion 4.1.2 SetTimeout 4.2. Common SCSI Functions 4.2.1 Inquiry 4.2.2 MSelect 4.2.3 MSense 4.2.4 ReqSense 4.2.5 TestUnit 4.3. Harddisk SCSI Commands 4.3.1 HDCapacity 4.3.2 HDCopy 4.3.3 HDDefect 4.3.4 HDFormat 4.3.5 HDRead 4.3.6 HDReleas 4.3.7 HDReserv 4.3.8 HDStart 4.3.9 HDStop 4.3.10 HDWrite 4.4. Streamer SCSI Commands 4.4.1 STAppend 4.4.2 STErase 4.4.3 STLock 4.4.4 STPrewind 4.4.5 STRead 4.4.6 STReqAux 4.4.7 STRewind 4.4.8 STSkip 4.4.9 STUnlock 4.4.10 STWFileM 4.4.11 STWrite 1. Intro: ========= SCSIBios is an extension to the operating system of the ATARI ST, STE and TT series. It installs a new XBios handler and than waits until it will be requested by special adaptec user application. SCSIBios provides a means to handle every I/O with the ACSI and SCSI interface of ATARI Computers. You may copy this extension freely, but the following files must be included in the copied material and no copyright notes may be changed: SCSIBIOS.PRG (The OS Extension for the AUTO-Folder) SCSIBIOS.TXT (The documentation you're just reading) SCSIBIOS.LIB (Binding-Library for Turbo-C V2.x) SCSIBIOS.H (Header to be included in your programs) MSCSI.C (Demonstration source for SCSIBios) MSCSI.PRG (Executable program of demo source) MSCSI.PRJ (Project file for demo program) If you use SCSIBios frequently in you programs and/or you want to distribute SCSIBios and/or programs using SCSIBios for commercial purposes I recommend you to send me a demonstrational copy of your program and DM50,-- for the use of SCSIBios. 2. Disclaimer: ============== SCSIBios V1.0 is tested in certain programs and a command line inter- preter. Until now there have been no errors found. I will not take any responsilities for SCSIBios damaging any soft- or hardware. It is in the responsibility of anyone using SCSIBios to take care of his equipment. 3. Check the System for SCSIBios: ================================= There are two ways to check if SCSIBios is installed in the system: a) SCSIBios installs a cookie in the cookie jar name 'SCSI'. The value of the cookie is the version of SCSIBios which is installed. The High-Word contains the major version number and the Low-Word contains the minor version number. b) If no cookie jar is present you may find SCSIBios by checking the exception vector #46 (XBios Trap handler) of your system. If SCSIBios is installed, you will find an 'XBRA' protocol right in front of the code pointed to by the exception vector. You can check for SCSIBios using the following code: CheckBios: move.l #-1, -(sp) ; Get exception vector #46 move.w #46, -(sp) move.w #5, -(sp) ; Setexc trap #$D addq.l #8, SP ; clear stack movea.l D0, A0 ; check if SCSIBios is cmpi.l #'SCSI', -8(A0) ; already resident beq.b ishere clr.l D0 ishere: rts This function returns in D0 a value not equal to zero if SCSIBios is installed. 4. Functions Provided By SCSIBios: ================================== In the descripton of the funtion below the parameter 'pdev' is used in two ways. On ATARI ST and STE computer it represents the physical unit number to be accessed. On the ATARI TT computers 'pdev' ranging from 0 to 7 represent the ACSI-devices and 'pdev' ranging from 8 to 15 re- present the SCSI-Devices. If you ty to access units in the TT-DMA range without running on a TT the function result will always be -1 (0xff) This function-description is not ment to replace a complete SCSI documentation you will always have to refer to your unit data guide to get the correct parameters and to knoe how those commands are used. 4.1. Common Functions --------------------- 4.1.1 SCSIVersion Name >Get SCSIBios Version< - Return version number of SCSIBios Definition #include long SCSIVersion(void); Description This function returns a long value containing the version number of the installed SCSIBios. It might be useful to check this version numbers if some later releases are containing more functions. Result The High-Word contains the major version number and the Low-Word contains the minor version number. 4.1.2 SetTimeout Name >Get/Set Timeouts< - Get/Set the Timeouts in SCSIBios Definition #include SCSI_TIMEOUT *SetTimeout(SCSI_TIMEOUT *scsi_timeout); Description This function sets the internal timeouts used in SCSIBios. As a function result you will receive a copy of the internal timeout-structure. Don't try to change the time- outs by changing the values pointed to by the structure. It is only a copy! The times specified in this struct are in 200Hz cycles according to the internal system counter. 'scsi_timeout' is a pointer to a struct looking as follows: typedef struct { ULONG BeforeCommand; ULONG AfterCommand; ULONG ShortTimeout; ULONG LongTimeout; ULONG Wait4IRQ; ULONG XtraShortTimeout; ULONG CommandDelay; } SCSI_TIMEOUT; 'BeforeCommand' is waited before sending the command. This time is additional to 'CommandDelay'. Preset is 20UL (25ms). 'AfterCommand' is waited after sending the command. This time is additional to 'CommandDelay'. Preset is 20UL (25ms). 'ShortTimeout' is used as the time to wait for response by the attached unit. It is used for commands like Inquiry. Preset is 60000UL (30s). 'LongTimeout' is used as the time to wait for response by the attached unit. It is used for commands like HDRead or HDWrite. Preset is 120000UL (60s). 'Wait4IRQ' is used as the time to wait for response by the attached unit. It is used for special long timing commands like HDFormat. Preset is 2400000UL (20min). 'XtraShortTimeout' is used as the time to wait for response by the attached unit. It is used for commands like TestUnit. Preset is 50UL (250ms). 'CommandDelay' is used as the time to pass by between sending two commands to the Unit. This timeout is necessary on TT and STE computers, because they are that fast that mose units are totaly confused. You can get the SCSIBios timeouts without setting any new ones by passing -1L as 'scsi_timeout'. Result This function returns a copy of the internal timeouts. 4.2. Common SCSI Functions -------------------------- 4.2.1 Inquiry Name >Inquiry< - Get vendor and unit information Definition #include int Inquiry(int pdev, int ldev, int bytes, char *buf); Description Inquiry is used to get information about the connected units. 'pdev' is the physical ID of the desired unit and 'ldev' the logical one. Usually ldev will be 0. 'bytes' indicates the number of bytes to be transferred and 'buf' is the location where the gained information will be stored. Result Inquiry will return 0 is no error occured and a value non zero if the command failed. 4.2.2 MSelect Name >Mode Select< - Set drive geometry and default values Definition #include int MSelect(int pdev, int ldev, int bytes, char *buf); Description The Mode Select command allows the you to specify device parameters to the drive. 'pdev' is the physical ID of the desired unit and 'ldev' is the logical one. Usually 'ldev' will be 0. 'bytes' indiactes the number of bytes to be transferred and 'buf' is a pointer to the data hloding buffer. Result MSelect will return 0 is no error occured and a value non zero if the command failed. 4.2.3 MSense Name >Mode Sense< - Get drive geometry and default values Definition #include int MSense(int pdev, int ldev, int page, int bytes, char *buf); Description The Mode Sense command allows the you to read device parameters from the drive. 'pdev' is the physical ID of the desired unit and 'ldev' is the logical one. Usually 'ldev' will be 0. 'bytes' indiactes the number of bytes to be transferred and 'buf' is a pointer to the buffer which will contain the data. 'page' defines which information should be transferred. Result MSense will return 0 is no error occured and a value non zero if the command failed. 4.2.4 ReqSense Name >Request Sense< - Get information about last ocurred error Definition #include int ReqSense(int pdev, int ldev, int bytes, char *buf); Description The ReqSense command reads information about the last occurred error on the sepcifier unit. If no error occurred, ReqSense will transferre an empty buffer. 'pdev' is the physical ID of the desired unit and 'ldev' is the logical one. Usually 'ldev' will be 0. 'bytes' indiactes the number of bytes to be transferred and 'buf' is a pointer to the buffer which will contain the data. Result ReqSense will return 0 is no error occured and a value non zero if the command failed. 4.2.5 TestUnit Name >Test Unit Ready< - See if a unit is ready for operation Definition #include int TestUnit(int pdev, int ldev); Description The TestUnit command test a unit to be ready for operation. 'pdev' is the physical ID of the desired unit and 'ldev' is the logical one. Usually 'ldev' will be 0. See your SCSI-Manual for detailed information about the return values. Result TestUnit will return 0 if the unit is ready to perform or any other value received by the unit. 4.3. Harddisk SCSI Commands --------------------------- 4.3.1 HDCapacity Name >Read Capacity< - Get capacity of harddisk drive Definition #include int HDCapacity(int pdev, int ldev, int iface, char *buf); Description The HDCapacity command gets the capacity in number of blocks which can be used for data storage. 'pdev' is the physical ID of the desired unit and 'ldev' is the logical one. Usually 'ldev' will be 0. 'bytes' indiactes the number of bytes to be transferred and 'buf' is a pointer to the buffer which will contain the data. 'iface' is the physical unit number of a connected 'STATUS'-SCSI-Interface. On TT-Computers 'iface' should be set to zero. Result HDCapacity will return 0 is no error occured and a value non zero if the command failed. Note Do not use this function if you have no 'STATUS'-Interface in use and you are working with an ST/STE Computer. Otherwise this function will not perform properly or may damage data. 4.3.2 HDCopy Name >Copy Data< - Get capacity of harddisk drive Definition #include int HDCopy(int pdev, int ldev, long length, char *buf, int erase); Description The HDCopy commands copies data from one unit to another. 'pdev' and 'ldev' specify the unit to perform the command. 'buf' contains infoermation data for the command. 'erase' is the corresponding bit in the command descriptor block. Result HDCOpy will return 0 if no error occured and a value non zero if the command failed. Note This function will only work on TT-Computers, because it is using a re-connection phase which recommends full SCSI-standards. 4.3.3 HDDefect Name >Read Defect Data< - Get unit defect sector information Definition #include int HDDefect(int pdev, int ldev, int iface, int fmt, int bytes, char *buf); Description The HDDefect command is used to read the defect information of a physical unit. 'pdev' is the physical ID of the desired unit and 'ldev' is the logical one. Usually 'ldev' will be 0. 'bytes' indiactes the number of bytes to be transferred and 'buf' is a pointer to the buffer which will contain the data. 'fmt' represents byte 3 of the command descriptor block. It is passed to the unit as you pass it to the function. 'iface' is the physical unit number of a connected 'STATUS'-SCSI-Interface. On TT-Computers 'iface' should be set to zero. Result HDDefect will return 0 is no error occured and a value non zero if the command failed. Note Do not use this function if you have no 'STATUS'-Interface in use and you are working with an ST/STE Computer. Otherwise this function will not perform properly or may damage data. 4.3.4 HDFormat Name >Format Unit< - Format the entire unit Definition #include int HDFormat(int pdev, int ldev, int interleave); Description The HDFormat command is used to format an entire unit to prepare it for operation. 'pdev' is the physical ID of the desired unit and 'ldev' is the logical one. Usually 'ldev' will be 0. 'bytes' indiactes the number of bytes to be transferred and 'buf' is a pointer to the buffer which will contain the data. 'interleeave' is the interleave factor for the hard disk drive. Result HDFormat will return 0 if no error occured and a value non zero if the command failed. 4.3.5 HDRead Name >Read< - Read sectors from a unit Definition #include int HDRead(int pdev, int ldev, long start, long count, char *buf); Description The HDRead command is used to read sectors from a unit. Usually you can't transfere more than 127 sectors via ST/STE DMA bus. We have solved this problem an are splitting the reading accesses to 127 boundaries. 'pdev' is the physical ID of the desired unit and 'ldev' is the logical one. Usually 'ldev' will be 0. 'start' describes the starting sector for reading. 'count' specifies the number of sectors(!!) to be read. 'buf' is a pointer to the buffer which will contain the data. Result HDRead will return 0 if no error occured and a value non zero if the command failed. 4.3.6 HDReleas Name >Release unit< - release a previously reserved unit Definition #include int HDReleas(int pdev, int ldev); Description The HDRelease command will release a unit from exclusive use by one initiator. This command will usually not be used on ATARI computer due to the non-interlaced bus system. 'pdev' is the physical ID of the desired unit and 'ldev' is the logical one. Usually 'ldev' will be 0. Result HDRelease will return 0 if no error occured and a value non zero if the command failed. 4.3.7 HDReserv Name >Reserve unit< - reserve a unit for exclusive use Definition #include int HDReserv(int pdev, int ldev); Description The HDReserv command will reserve a unit for exclusive use by one initiator. This command will usually not be used on ATARI computer due to the non-interlaced bus system. 'pdev' is the physical ID of the desired unit and 'ldev' is the logical one. Usually 'ldev' will be 0. Result HDReserve will return 0 if no error occured and a value non zero if the command failed. 4.3.8 HDStart Name >Start unit< - Enable a unit for operation Definition #include int HDStart(int pdev, int ldev); Description The HDStart command enables a unit for operation. On some units this might be neccessary, if the spin up phse is not initiated alone. 'pdev' is the physical ID of the desired unit and 'ldev' is the logical one. Usually 'ldev' will be 0. Result HDStart will return 0 if no error occured and a value non zero if the command failed. 4.3.9 HDStop Name >Stop unit< - Disable a unit Definition #include int HDStop(int pdev, int ldev, int eject); Description The HDStop command enables you to park a unit. If the unit has got a removeable medium, you may also eject it. 'pdev' is the physical ID of the desired unit and 'ldev' is the logical one. Usually 'ldev' will be 0. If 'eject' is 1 (TRUE) the inserted medium will be released and ejected. If the Hard Disk Drive has no removeable medium the parameter should be set zero. Result HDStop will return 0 if no error occured and a value non zero if the command failed. 4.3.10 HDWrite Name >Write< - Write sectors to a unit Definition #include int HDWrite(int pdev, int ldev, long start, long count, char *buf); Description The HDWrite command is used to write sectors to a unit. Usually you can't transfere more than 127 sectors via ST/STE DMA bus. We have solved this problem an are splitting the writing accesses to 127 boundaries. 'pdev' is the physical ID of the desired unit and 'ldev' is the logical one. Usually 'ldev' will be 0. 'start' describes the starting sector for writing. 'count' specifies the number of sectors(!!) to be written. 'buf' is a pointer to the buffer which will contain the data. Result HDWrite will return 0 if no error occured and a value non zero if the command failed. 4.4. Streamer SCSI Commands --------------------------- 4.4.1 STAppend Name >Append Data< - prewind to end of data Definition #include int STAppend(int pdev, int ldev); Description The STAppend command prewinds until the end of written information is reached. 'pdev' is the physical ID of the desired unit and 'ldev' is the logical one. Usually 'ldev' will be 0. Result STAppend will return 0 if no error occured and a value non zero if the command failed. 4.4.2 STErase Name >Erase Tape< - Erase information on a tape Definition #include int STErase(int pdev, int ldev, int async); Description The STErase command erases a whole tape by writing initial data to it. 'pdev' is the physical ID of the desired unit and 'ldev' is the logical one. Usually 'ldev' will be 0. An 'async' value of 1 indicates that the operation will be done in the background and the computer gains control again at once. In any other cases this value should be set to zero. Result STErase will return 0 if no error occured and a value non zero if the command failed. 4.4.3 STLock Name >Lock Tape< - Lock the tape inside the streamer Definition #include int STLock(int pdev, int ldev); Description The STLock command causes the tape inside the streamer to be locked. 'pdev' is the physical ID of the desired unit and 'ldev' is the logical one. Usually 'ldev' will be 0. Result STLock will return 0 if no error occured and a value non zero if the command failed. 4.4.4 STPrewind Name >Prewind Tape< - prewind the tape to its end Definition #include int STPrewind(int pdev, int ldev, int async); Description The STPrewind command causes streamer to prewind the tape. 'pdev' is the physical ID of the desired unit and 'ldev' is the logical one. Usually 'ldev' will be 0. An 'async' value of 1 indicates that the operation will be done in the background and the computer gains control again at once. In any other cases this value should be set to zero. Result STPrewind will return 0 if no error occured and a value non zero if the command failed. 4.4.5 STRead Name >Read< - Read sectors from the tape Definition #include int STRead(int pdev, int ldev, long count, char *buf); Description The STRead command is used to read sectors from a unit. Usually you can't transfere more than 127 sectors via ST/STE DMA bus. We have solved this problem an are splitting the reading accesses to 127 boundaries. 'pdev' is the physical ID of the desired unit and 'ldev' is the logical one. Usually 'ldev' will be 0. 'count' specifies the number of sectors(!!) to be read. 'buf' is a pointer to the buffer which will contain the data. Result STRead will return 0 if no error occured and a value non zero if the command failed. 4.4.6 STReqAux Name >Request Auxilliary Information< - Get detailed information on streamer and inserted tape. Definition #include int STReqAux(int pdev, int ldev, int bytes, char *buf); Description This command is used to get detailed information about the streamer and the inserted tape. This information contains error-codes, current tape-position and other. 'pdev' is the physical ID of the desired unit and 'ldev' is the logical one. Usually 'ldev' will be 0. 'bytes' indicates the number of bytes to be transferred and 'buf' is the location where the gained information will be stored. Result STReqAux will return 0 if no error occured and a value non zero if the command failed. 4.4.7 STRewind Name >Rewind Tape< - Rewind the inserted tape Definition #include int STRewind(int pdev, int ldev, int async); Description The STRewind command causes streamer to rewind the tape. 'pdev' is the physical ID of the desired unit and 'ldev' is the logical one. Usually 'ldev' will be 0. An 'async' value of 1 indicates that the operation will be done in the background and the computer gains control again at once. In any other cases this value should be set to zero. Result STRewind will return 0 if no error occured and a value non zero if the command failed. 4.4.8 STSkip Name >Skip Filemarks< - Skip a certain number of filemarks Definition #include int STSkip(int pdev, int ldev, int kind, int count); Description The STSkip command is used to skip 'count' number of filemarks with type 'kind'. 'pdev' is the physical ID of the desired unit and 'ldev' is the logical one. Usually 'ldev' will be 0. Result STSkip will return 0 if no error occured and a value non zero if the command failed. 4.4.9 STUnlock Name >Unlock Tape< - Unlock the tape inside the streamer Definition #include int STUnlock(int pdev, int ldev); Description The STUnlock command causes the tape inside the streamer to be unlocked. 'pdev' is the physical ID of the desired unit and 'ldev' is the logical one. Usually 'ldev' will be 0. Result STUnlock will return 0 if no error occured and a value non zero if the command failed. 4.4.10 STWFileM Name >Write Filemark< - Write Filemark of a given type Definition #include int STWFileM(int pdev, int ldev, int kind); Description The STWFileM command is used to write a file mark of tape 'kind'. 'pdev' is the physical ID of the desired unit and 'ldev' is the logical one. Usually 'ldev' will be 0. Result STWFileM will return 0 if no error occured and a value non zero if the command failed. 4.4.11 STWrite Name >Write< - Write sectors to the tape Definition #include int STWrite(int pdev, int ldev, long count, char *buf); Description The STWrite command is used to write sectors to a unit. Usually you can't transfere more than 127 sectors via ST/STE DMA bus. We have solved this problem an are splitting the reading accesses to 127 boundaries. 'pdev' is the physical ID of the desired unit and 'ldev' is the logical one. Usually 'ldev' will be 0. 'count' specifies the number of sectors(!!) to be written. 'buf' is a pointer to the buffer which will contain the data. Result STWrite will return 0 if no error occured and a value non zero if the command failed.