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-hpux_new.c,v 1.19 2006/05/25 01:47:08 johnfranks Exp $
29 * Interface to execute SCSI commands on an HP-UX Workstation
31 * Copyright (c) Thomas Hepper th@ant.han.de
37 #ifdef HAVE_HPUX_LIKE_SCSI
49 #ifdef HAVE_SYS_IOCTL_H
50 #include <sys/ioctl.h>
56 #include <scsi-defs.h>
58 void SCSI_OS_Version()
61 static char rcsid[] = "$Id: scsi-hpux_new.c,v 1.19 2006/05/25 01:47:08 johnfranks Exp $";
62 DebugPrint(DEBUG_INFO, SECTION_INFO, "scsi-os-layer: %s\n",rcsid);
66 int SCSI_OpenDevice(int ip)
68 extern OpenFiles_T *pDev;
72 if (pDev[ip].inqdone == 0)
75 if ((DeviceFD = open(pDev[ip].dev, O_RDWR| O_NDELAY)) >= 0)
78 pDev[ip].fd = DeviceFD;
81 pDev[ip].inquiry = (SCSIInquiry_T *)malloc(INQUIRY_SIZE);
83 if (SCSI_Inquiry(ip, pDev[ip].inquiry, INQUIRY_SIZE) == 0)
85 if (pDev[ip].inquiry->type == TYPE_TAPE || pDev[ip].inquiry->type == TYPE_CHANGER)
88 pDev[ip].ident[i] = pDev[ip].inquiry->prod_ident[i];
89 for (i=15; i >= 0 && !isalnum(pDev[ip].inquiry->prod_ident[i]) ; i--)
91 pDev[ip].inquiry->prod_ident[i] = '\0';
95 if (pDev[ip].inquiry->type == TYPE_TAPE)
97 pDev[ip].type = stralloc("tape");
100 if (pDev[ip].inquiry->type == TYPE_CHANGER)
102 pDev[ip].type = stralloc("changer");
105 PrintInquiry(pDev[ip].inquiry);
109 free(pDev[ip].inquiry);
114 free(pDev[ip].inquiry);
115 pDev[ip].inquiry = NULL;
119 if ((DeviceFD = open(pDev[ip].dev, O_RDWR| O_NDELAY)) >= 0)
121 pDev[ip].fd = DeviceFD;
122 pDev[ip].devopen = 1;
130 int SCSI_CloseDevice(int DeviceFD)
132 extern OpenFiles_T *pDev;
135 ret = close(pDev[DeviceFD].fd);
136 pDev[DeviceFD].devopen = 0;
140 int SCSI_ExecuteCommand(int DeviceFD,
141 Direction_T Direction,
145 size_t DataBufferLength,
146 RequestSense_T *RequestSenseBuf,
147 size_t RequestSenseLength)
149 extern OpenFiles_T *pDev;
150 struct sctl_io sctl_io;
152 int Zero = 0, Result;
154 /* Basic sanity checks */
155 assert(CDB_Length <= UCHAR_MAX);
156 assert(RequestSenseLength <= UCHAR_MAX);
158 /* Clear buffer for cases where sense is not returned */
159 memset(RequestSenseBuf, 0, RequestSenseLength);
161 if (pDev[DeviceFD].avail == 0)
167 memset(&sctl_io, '\0', SIZEOF(struct sctl_io));
170 sctl_io.max_msecs = 240000;
172 memcpy(sctl_io.cdb, CDB, CDB_Length);
173 sctl_io.cdb_length = CDB_Length;
174 /* Data buffer for results */
175 sctl_io.data = DataBuffer;
176 sctl_io.data_length = (unsigned)DataBufferLength;
181 sctl_io.flags = sctl_io.flags | SCTL_READ;
187 while (--Retries > 0) {
189 if (pDev[DeviceFD].devopen == 0)
191 if (SCSI_OpenDevice(DeviceFD) == 0)
193 dbprintf(("SCSI_ExecuteCommand could not open %s: %s\n",
196 sleep(1); /* Give device a little time befor retry */
201 DecodeSCSI(CDB, "SCSI_ExecuteCommand : ");
202 Result = ioctl(pDev[DeviceFD].fd, SIOC_IO, &sctl_io);
203 SCSI_CloseDevice(DeviceFD);
209 SCSI_CloseDevice(DeviceFD);
211 memcpy(RequestSenseBuf, sctl_io.sense, RequestSenseLength);
213 switch(sctl_io.cdb_status)
218 case S_CHECK_CONDITION:
228 * Send the command to the device with the
231 int Tape_Ioctl( int DeviceFD, int command)
233 extern OpenFiles_T *pDev;
237 if (pDev[DeviceFD].devopen == 0)
238 if (SCSI_OpenDevice(DeviceFD) == 0)
252 if (ioctl(pDev[DeviceFD].fd , MTIOCTOP, &mtop) != 0)
254 dbprintf(("Tape_Ioctl error ioctl %s\n", strerror(errno)));
255 SCSI_CloseDevice(DeviceFD);
259 SCSI_CloseDevice(DeviceFD);
265 int Tape_Status( int DeviceFD)
267 extern OpenFiles_T *pDev;
271 if (pDev[DeviceFD].devopen == 0)
272 if (SCSI_OpenDevice(DeviceFD) == 0)
275 if (ioctl(pDev[DeviceFD].fd, MTIOCGET, &mtget) != 0)
277 dbprintf(("Tape_Status error ioctl %s\n", strerror(errno)));
278 SCSI_CloseDevice(DeviceFD);
282 dbprintf(("ioctl -> mtget.mt_gstat %X\n",mtget.mt_gstat));
283 if (GMT_ONLINE(mtget.mt_gstat))
288 if (GMT_BOT(mtget.mt_gstat))
290 ret = ret | TAPE_BOT;
293 if (GMT_EOT(mtget.mt_gstat))
295 ret = ret | TAPE_EOT;
298 if (GMT_WR_PROT(mtget.mt_gstat))
300 ret = ret | TAPE_WR_PROT;
303 SCSI_CloseDevice(DeviceFD);
307 int ScanBus(int print)
317 * indent-tabs-mode: nil