2 * Amanda, The Advanced Maryland Automatic Network Disk Archiver
3 * Copyright (c) 1991-2000 University of Maryland at College Park
6 * Permission to use, copy, modify, distribute, and sell this software and its
7 * documentation for any purpose is hereby granted without fee, provided that
8 * the above copyright notice appear in all copies and that both that
9 * copyright notice and this permission notice appear in supporting
10 * documentation, and that the name of U.M. not be used in advertising or
11 * publicity pertaining to distribution of the software without specific,
12 * written prior permission. U.M. makes no representations about the
13 * suitability of this software for any purpose. It is provided "as is"
14 * without express or implied warranty.
16 * U.M. DISCLAIMS ALL WARRANTIES WITH REGARD TO THIS SOFTWARE, INCLUDING ALL
17 * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS, IN NO EVENT SHALL U.M.
18 * BE LIABLE FOR ANY SPECIAL, INDIRECT OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES
19 * WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN ACTION
20 * OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF OR IN
21 * CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
23 * Authors: the Amanda Development Team. Its members are listed in a
24 * file named AUTHORS, in the root directory of this distribution.
27 * $Id: scsi-solaris.c,v 1.26 2006/05/25 01:47:10 johnfranks Exp $
29 * Interface to execute SCSI commands on an Sun Workstation
31 * Copyright (c) Thomas Hepper th@ant.han.de
37 #ifdef HAVE_SOLARIS_LIKE_SCSI
45 #ifdef HAVE_SYS_TYPES_H
46 #include <sys/types.h>
48 #ifdef HAVE_SYS_STAT_H
55 #include <sys/scsi/impl/uscsi.h>
57 #include <scsi-defs.h>
60 void SCSI_OS_Version(void)
63 static char rcsid[] = "$Id: scsi-solaris.c,v 1.26 2006/05/25 01:47:10 johnfranks Exp $";
64 DebugPrint(DEBUG_INFO, SECTION_INFO, "scsi-os-layer: %s\n",rcsid);
68 int SCSI_OpenDevice(int ip)
72 extern OpenFiles_T *pDev;
74 if (pDev[ip].inqdone == 0)
77 if ((DeviceFD = open(pDev[ip].dev, O_RDWR| O_NONBLOCK)) >= 0)
80 pDev[ip].fd = DeviceFD;
83 pDev[ip].inquiry = (SCSIInquiry_T *)malloc(INQUIRY_SIZE);
85 if (SCSI_Inquiry(ip, pDev[ip].inquiry, (unsigned char)INQUIRY_SIZE) == 0)
87 if (pDev[ip].inquiry->type == TYPE_TAPE || pDev[ip].inquiry->type == TYPE_CHANGER)
90 pDev[ip].ident[i] = pDev[ip].inquiry->prod_ident[i];
91 for (i=15; i >= 0 && !isalnum((int)pDev[ip].ident[i]) ; i--)
93 pDev[ip].ident[i] = '\0';
97 if (pDev[ip].inquiry->type == TYPE_TAPE)
99 pDev[ip].type = stralloc("tape");
102 if (pDev[ip].inquiry->type == TYPE_CHANGER)
104 pDev[ip].type = stralloc("changer");
107 PrintInquiry(pDev[ip].inquiry);
111 free(pDev[ip].inquiry);
115 free(pDev[ip].inquiry);
116 pDev[ip].inquiry = NULL;
119 dbprintf(("SCSI_OpenDevice %s failed\n", pDev[ip].dev));
123 if ((DeviceFD = open(pDev[ip].dev, O_RDWR| O_NDELAY)) >= 0)
125 pDev[ip].fd = DeviceFD;
126 pDev[ip].devopen = 1;
134 int SCSI_CloseDevice(int DeviceFD)
137 extern OpenFiles_T *pDev;
139 ret = close(pDev[DeviceFD].fd);
140 pDev[DeviceFD].devopen = 0;
145 int SCSI_ExecuteCommand(int DeviceFD,
146 Direction_T Direction,
150 size_t DataBufferLength,
151 RequestSense_T *RequestSense,
152 size_t RequestSenseLength)
154 extern OpenFiles_T *pDev;
155 extern FILE * debug_file;
159 struct uscsi_cmd Command;
160 static int depth = 0;
162 /* Basic sanity checks */
163 assert(CDB_Length <= UCHAR_MAX);
164 assert(RequestSenseLength <= UCHAR_MAX);
166 /* Clear buffer for cases where sense is not returned */
167 memset(RequestSense, 0, RequestSenseLength);
169 if (pDev[DeviceFD].avail == 0)
177 SCSI_CloseDevice(DeviceFD);
180 memset(&Command, 0, SIZEOF(struct uscsi_cmd));
181 memset(RequestSense, 0, RequestSenseLength);
185 if (DataBufferLength > 0)
186 memset(DataBuffer, 0, DataBufferLength);
188 /* Command.uscsi_flags = USCSI_READ | USCSI_RQENABLE; */
189 Command.uscsi_flags = USCSI_DIAGNOSE | USCSI_ISOLATE
190 | USCSI_READ | USCSI_RQENABLE;
193 /* Command.uscsi_flags = USCSI_WRITE | USCSI_RQENABLE; */
194 Command.uscsi_flags = USCSI_DIAGNOSE | USCSI_ISOLATE
195 | USCSI_WRITE | USCSI_RQENABLE;
198 /* Set timeout to 5 minutes. */
199 Command.uscsi_timeout = 300;
200 Command.uscsi_cdb = (caddr_t) CDB;
201 Command.uscsi_cdblen = (u_char)CDB_Length;
203 if (DataBufferLength > 0)
205 Command.uscsi_bufaddr = DataBuffer;
206 Command.uscsi_buflen = DataBufferLength;
209 * If there is no data buffer force the direction to write, read with
210 * a null buffer will fail (errno 22)
212 Command.uscsi_flags = USCSI_DIAGNOSE | USCSI_ISOLATE
213 | USCSI_WRITE | USCSI_RQENABLE;
216 Command.uscsi_rqbuf = (caddr_t)RequestSense;
217 Command.uscsi_rqlen = (u_char)RequestSenseLength;
218 DecodeSCSI(CDB, "SCSI_ExecuteCommand : ");
221 if (pDev[DeviceFD].devopen == 0)
222 if (SCSI_OpenDevice(DeviceFD) == 0)
228 if ((ret = ioctl(pDev[DeviceFD].fd, USCSICMD, &Command)) >= 0)
230 ret = Command.uscsi_status;
233 dbprintf(("ioctl on %d failed, errno %s, ret %d\n",
234 pDev[DeviceFD].fd, strerror(errno), ret));
236 RequestSense(DeviceFD, &pExtendedRequestSense, 0);
238 DecodeSense(RequestSense, "SCSI_ExecuteCommand:", debug_file);
242 SCSI_CloseDevice(DeviceFD);
244 DebugPrint(DEBUG_INFO, SECTION_SCSI,"ioctl ret (%d)\n",ret);
249 * Send the command to the device with the
252 int Tape_Ioctl( int DeviceFD, int command)
254 extern OpenFiles_T *pDev;
258 if (pDev[DeviceFD].devopen == 0)
259 if (SCSI_OpenDevice(DeviceFD) == 0)
272 if (ioctl(pDev[DeviceFD].fd , MTIOCTOP, &mtop) != 0)
274 dbprintf(("Tape_Ioctl error ioctl %s\n", strerror(errno)));
275 SCSI_CloseDevice(DeviceFD);
279 SCSI_CloseDevice(DeviceFD);
283 int Tape_Status( int DeviceFD)
285 extern OpenFiles_T *pDev;
289 memset(&mtget, 0, SIZEOF(mtget));
290 if (pDev[DeviceFD].devopen == 0)
291 if (SCSI_OpenDevice(DeviceFD) == 0)
294 if (ioctl(pDev[DeviceFD].fd , MTIOCGET, &mtget) != 0)
296 dbprintf(("Tape_Status error ioctl %s\n", strerror(errno)));
297 SCSI_CloseDevice(DeviceFD);
302 * I have no idea what is the meaning of the bits in mt_erreg
303 * I assume that nothing set is tape loaded
304 * 0x2 is no tape online
307 DebugPrint(DEBUG_INFO, SECTION_TAPE, "ioctl result for mt_dsreg (%d)\n", mtget.mt_dsreg);
308 DebugPrint(DEBUG_INFO, SECTION_TAPE, "ioctl result for mt_erreg (%d)\n", mtget.mt_erreg);
310 if (mtget.mt_erreg == 0)
312 ret = ret | TAPE_ONLINE;
315 if (mtget.mt_erreg & 0x2)
317 ret = ret | TAPE_NOT_LOADED;
320 SCSI_CloseDevice(DeviceFD);
325 int ScanBus(int print)
327 (void)print; /* Quiet unused parameter warning */
334 * indent-tabs-mode: nil