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-irix.c,v 1.23 2006/05/25 01:47:08 johnfranks Exp $
29 * Interface to execute SCSI commands on an SGI Workstation
31 * Copyright (c) Thomas Hepper th@ant.han.de
38 #include <sys/dsreq.h>
41 #include <scsi-defs.h>
43 void SCSI_OS_Version()
46 static char rcsid[] = "$Id: scsi-irix.c,v 1.23 2006/05/25 01:47:08 johnfranks Exp $";
47 DebugPrint(DEBUG_INFO, SECTION_INFO, "scsi-os-layer: %s\n",rcsid);
54 int SCSI_OpenDevice(int ip)
56 extern OpenFiles_T *pDev;
60 if (pDev[ip].inqdone == 0)
62 if ((DeviceFD = open(pDev[ip].dev, O_RDWR | O_EXCL)) >= 0)
64 pDev[ip].inqdone = 1; pDev[ip].SCSI = 0;
66 pDev[ip].fd = DeviceFD;
67 pDev[ip].inquiry = (SCSIInquiry_T *)malloc(INQUIRY_SIZE);
68 if (SCSI_Inquiry(ip, pDev[ip].inquiry, INQUIRY_SIZE) == 0)
70 if (pDev[ip].inquiry->type == TYPE_TAPE || pDev[ip].inquiry->type == TYPE_CHANGER)
73 pDev[ip].ident[i] = pDev[ip].inquiry->prod_ident[i];
74 for (i=15; i >= 0 && !isalnum((int)pDev[ip].ident[i]) ; i--)
76 pDev[ip].ident[i] = '\0';
81 if (pDev[ip].inquiry->type == TYPE_TAPE)
83 pDev[ip].type = stralloc("tape");
86 if (pDev[ip].inquiry->type == TYPE_CHANGER)
88 pDev[ip].type = stralloc("changer");
91 PrintInquiry(pDev[ip].inquiry);
93 } else { /* ! TYPE_TAPE ! TYPE_CHANGER */
95 free(pDev[ip].inquiry);
96 pDev[ip].inquiry = NULL;
101 /* inquiry failed or no SCSI communication available */
103 free(pDev[ip].inquiry);
104 pDev[ip].inquiry = NULL;
109 if ((DeviceFD = open(pDev[ip].dev, O_RDWR | O_EXCL)) >= 0)
111 pDev[ip].fd = DeviceFD;
112 pDev[ip].devopen = 1;
115 pDev[ip].devopen = 0;
122 int SCSI_CloseDevice(int DeviceFD)
124 extern OpenFiles_T *pDev;
127 if (pDev[DeviceFD].devopen == 1)
129 pDev[DeviceFD].devopen = 0;
130 ret = close(pDev[DeviceFD].fd);
136 int SCSI_ExecuteCommand(int DeviceFD,
137 Direction_T Direction,
141 size_t DataBufferLength,
142 RequestSense_T *pRequestSense,
143 size_t RequestSenseLength)
145 extern OpenFiles_T *pDev;
146 ExtendedRequestSense_T ExtendedRequestSense;
151 /* Basic sanity checks */
152 assert(CDB_Length <= UCHAR_MAX);
153 assert(RequestSenseLength <= UCHAR_MAX);
155 /* Clear buffer for cases where sense is not returned */
156 memset(pRequestSense, 0, RequestSenseLength);
158 if (pDev[DeviceFD].avail == 0)
163 memset(&ds, 0, SIZEOF(struct dsreq));
164 memset(pRequestSense, 0, RequestSenseLength);
165 memset(&ExtendedRequestSense, 0 , SIZEOF(ExtendedRequestSense_T));
167 ds.ds_flags = DSRQ_SENSE|DSRQ_TRACE|DSRQ_PRINT;
171 ds.ds_cmdbuf = (caddr_t)CDB;
172 ds.ds_cmdlen = CDB_Length;
173 /* Data buffer for results */
174 ds.ds_databuf = (caddr_t)DataBuffer;
175 ds.ds_datalen = DataBufferLength;
177 ds.ds_sensebuf = (caddr_t)pRequestSense;
178 ds.ds_senselen = RequestSenseLength;
183 ds.ds_flags = ds.ds_flags | DSRQ_READ;
186 ds.ds_flags = ds.ds_flags | DSRQ_WRITE;
190 while (--retries > 0) {
191 if (pDev[DeviceFD].devopen == 0)
193 if (SCSI_OpenDevice(DeviceFD) == 0)
195 dbprintf(_("SCSI_ExecuteCommand could not open %s: %s\n"),
198 sleep(1); /* Give device a little time befor retry */
202 Result = ioctl(pDev[DeviceFD].fd, DS_ENTER, &ds);
203 SCSI_CloseDevice(DeviceFD);
207 RET(&ds) = DSRT_DEVSCSI;
208 SCSI_CloseDevice(DeviceFD);
211 DecodeSCSI(CDB, "SCSI_ExecuteCommand : ");
212 dbprintf(_("\t\t\tSTATUS(%02X) RET(%02X)\n"), STATUS(&ds), RET(&ds));
215 case ST_BUSY: /* BUSY */
218 case STA_RESERV: /* RESERV CONFLICT */
223 case ST_GOOD: /* GOOD 0x00 */
231 case ST_CHECK: /* CHECK CONDITION 0x02 */
239 case ST_COND_MET: /* INTERM/GOOD 0x10 */
247 int Tape_Ioctl ( int DeviceFD, int command)
249 extern OpenFiles_T *pDev;
252 if (pDev[DeviceFD].devopen == 0)
254 if (SCSI_OpenDevice(DeviceFD) == 0)
261 mtop.mt_op = MTUNLOAD;
268 ioctl(pDev[DeviceFD].fd, MTIOCTOP, &mtop);
269 SCSI_CloseDevice(DeviceFD);
273 int Tape_Status( int DeviceFD)
275 extern OpenFiles_T *pDev;
279 if (pDev[DeviceFD].devopen == 0)
281 if (SCSI_OpenDevice(DeviceFD) == 0)
285 if (ioctl(pDev[DeviceFD].fd , MTIOCGET, &mtget) != 0)
287 dbprintf(_("Tape_Status error ioctl %s\n"),strerror(errno));
288 SCSI_CloseDevice(DeviceFD);
292 switch(mtget.mt_dposn)
295 ret = ret | TAPE_EOT;
298 ret = ret | TAPE_BOT;
301 ret = ret | TAPE_WR_PROT;
314 SCSI_CloseDevice(DeviceFD);
318 int ScanBus(int print)
321 struct dirent *dirent;
322 extern OpenFiles_T *pDev;
326 if ((dir = opendir("/dev/scsi")) == NULL)
328 dbprintf(_("Can not read /dev/scsi: %s"), strerror(errno));
332 while ((dirent = readdir(dir)) != NULL)
334 if (strstr(dirent->d_name, "sc") != NULL)
336 pDev[count].dev = malloc(10);
337 pDev[count].inqdone = 0;
338 g_sprintf(pDev[count].dev,"/dev/scsi/%s", dirent->d_name);
339 if (OpenDevice(count,pDev[count].dev, "Scan", NULL ))
341 SCSI_CloseDevice(count);
342 pDev[count].inqdone = 0;
346 g_printf(_("name /dev/scsi/%s "), dirent->d_name);
348 switch (pDev[count].inquiry->type)
357 g_printf(_("Printer"));
360 g_printf(_("Processor"));
366 g_printf(_("Cdrom"));
369 g_printf(_("Scanner"));
372 g_printf(_("Optical"));
375 g_printf(_("Changer"));
381 g_printf(_("unknown %d"),pDev[count].inquiry->type);
387 g_printf(_("Count %d\n"),count);
389 free(pDev[count].dev);
390 pDev[count].dev=NULL;
399 * indent-tabs-mode: nil