Imported Upstream version 3.1.0
[debian/amanda] / changer-src / scsi-hpux_new.c
1 /*
2  * Amanda, The Advanced Maryland Automatic Network Disk Archiver
3  * Copyright (c) 1991-2000 University of Maryland at College Park
4  * All Rights Reserved.
5  *
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.
15  *
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.
22  *
23  * Authors: the Amanda Development Team.  Its members are listed in a
24  * file named AUTHORS, in the root directory of this distribution.
25  */
26 /*
27  * $Id: scsi-hpux_new.c,v 1.19 2006/05/25 01:47:08 johnfranks Exp $
28  *
29  * Interface to execute SCSI commands on an HP-UX Workstation
30  *
31  * Copyright (c) Thomas Hepper th@ant.han.de
32  */
33
34
35 #include "amanda.h"
36
37 #include <sys/scsi.h>
38 #include <sys/mtio.h>
39
40 #include <scsi-defs.h>
41
42 void SCSI_OS_Version()
43 {
44 #ifndef lint
45     static char rcsid[] = "$Id: scsi-hpux_new.c,v 1.19 2006/05/25 01:47:08 johnfranks Exp $";
46    DebugPrint(DEBUG_INFO, SECTION_INFO, "scsi-os-layer: %s\n",rcsid);
47 #endif
48 }
49
50 int SCSI_OpenDevice(int ip)
51 {
52   extern OpenFiles_T *pDev;
53   int DeviceFD;
54   int i;
55
56   if (pDev[ip].inqdone == 0)
57     {
58       pDev[ip].inqdone = 1;
59       if ((DeviceFD = open(pDev[ip].dev, O_RDWR| O_NDELAY)) >= 0)
60         {
61           pDev[ip].avail = 1;
62           pDev[ip].fd = DeviceFD;
63           pDev[ip].devopen = 1;
64           pDev[ip].SCSI = 0;
65           pDev[ip].inquiry = (SCSIInquiry_T *)malloc(INQUIRY_SIZE);
66           
67           if (SCSI_Inquiry(ip, pDev[ip].inquiry, INQUIRY_SIZE) == 0)
68             {
69               if (pDev[ip].inquiry->type == TYPE_TAPE || pDev[ip].inquiry->type == TYPE_CHANGER)
70                 {
71                   for (i=0;i < 16;i++)
72                     pDev[ip].ident[i] = pDev[ip].inquiry->prod_ident[i];
73                   for (i=15; i >= 0 && !isalnum(pDev[ip].inquiry->prod_ident[i]) ; i--)
74                     {
75                       pDev[ip].inquiry->prod_ident[i] = '\0';
76                     }
77                   pDev[ip].SCSI = 1;
78
79                   if (pDev[ip].inquiry->type == TYPE_TAPE)
80                   {
81                           pDev[ip].type = stralloc("tape");
82                   }
83
84                   if (pDev[ip].inquiry->type == TYPE_CHANGER)
85                   {
86                           pDev[ip].type = stralloc("changer");
87                   }
88
89                   PrintInquiry(pDev[ip].inquiry);
90                   return(1);    
91                 } else {
92                   close(DeviceFD);
93                   free(pDev[ip].inquiry);
94                   return(0);
95               }
96             }
97             close(DeviceFD);
98             free(pDev[ip].inquiry);
99             pDev[ip].inquiry = NULL;
100             return(1);
101         }
102     } else {
103       if ((DeviceFD = open(pDev[ip].dev, O_RDWR| O_NDELAY)) >= 0)
104         {
105           pDev[ip].fd = DeviceFD;
106           pDev[ip].devopen = 1;
107           return(1);
108         }
109     }
110
111   return(0); 
112 }
113
114 int SCSI_CloseDevice(int DeviceFD)
115 {
116   extern OpenFiles_T *pDev;
117   int ret;
118
119   ret = close(pDev[DeviceFD].fd);
120   pDev[DeviceFD].devopen = 0;
121   return(ret);
122 }
123
124 int SCSI_ExecuteCommand(int DeviceFD,
125                         Direction_T Direction,
126                         CDB_T CDB,
127                         size_t CDB_Length,
128                         void *DataBuffer,
129                         size_t DataBufferLength,
130                         RequestSense_T *RequestSenseBuf,
131                         size_t RequestSenseLength)
132 {
133   extern OpenFiles_T *pDev;
134   struct sctl_io sctl_io;
135   int Retries = 3;
136   int Zero = 0, Result;
137   
138   /* Basic sanity checks */
139   assert(CDB_Length <= UCHAR_MAX);
140   assert(RequestSenseLength <= UCHAR_MAX);
141
142   /* Clear buffer for cases where sense is not returned */
143   memset(RequestSenseBuf, 0, RequestSenseLength);
144
145   if (pDev[DeviceFD].avail == 0)
146     {
147       return(SCSI_ERROR);
148     }
149
150
151   memset(&sctl_io, '\0', SIZEOF(struct sctl_io));
152
153   sctl_io.flags = 0;  
154   sctl_io.max_msecs = 240000;
155   /* Set the cmd */
156   memcpy(sctl_io.cdb, CDB, CDB_Length);
157   sctl_io.cdb_length = CDB_Length;
158   /* Data buffer for results */
159   sctl_io.data = DataBuffer;
160   sctl_io.data_length = (unsigned)DataBufferLength;
161
162   switch (Direction) 
163     {
164     case Input:
165       sctl_io.flags = sctl_io.flags | SCTL_READ;
166       break;
167     case Output:
168       break;
169     }
170
171   while (--Retries > 0) {
172
173     if (pDev[DeviceFD].devopen == 0)
174       {
175         if (SCSI_OpenDevice(DeviceFD) == 0)
176           {
177             dbprintf(_("SCSI_ExecuteCommand could not open %s: %s\n"),
178                       pDev[DeviceFD].dev,
179                       strerror(errno));
180             sleep(1); /* Give device a little time befor retry */
181             continue;
182           }
183       }
184
185     DecodeSCSI(CDB, "SCSI_ExecuteCommand : ");
186     Result = ioctl(pDev[DeviceFD].fd, SIOC_IO, &sctl_io);
187     SCSI_CloseDevice(DeviceFD);
188     if (Result < 0)
189       {
190         return(SCSI_ERROR);
191       }
192     
193     SCSI_CloseDevice(DeviceFD);
194
195     memcpy(RequestSenseBuf, sctl_io.sense, RequestSenseLength);
196     
197     switch(sctl_io.cdb_status)
198       {
199       case S_GOOD:
200         return(SCSI_OK);
201
202       case S_CHECK_CONDITION:
203         return(SCSI_CHECK);
204
205       default:
206         return(SCSI_ERROR);
207       }
208   }
209   return(SCSI_ERROR);
210 }
211 /*
212  * Send the command to the device with the
213  * ioctl interface
214  */
215 int Tape_Ioctl( int DeviceFD, int command)
216 {
217   extern OpenFiles_T *pDev;
218   struct mtop mtop;
219   int ret = 0;
220
221   if (pDev[DeviceFD].devopen == 0)
222       if (SCSI_OpenDevice(DeviceFD) == 0)
223           return(-1);
224
225   switch (command)
226     {
227     case IOCTL_EJECT:
228       mtop.mt_op = MTOFFL;
229       mtop.mt_count = 1;
230       break;
231
232     default:
233       break;
234     }
235
236   if (ioctl(pDev[DeviceFD].fd , MTIOCTOP, &mtop) != 0)
237     {
238       dbprintf(_("Tape_Ioctl error ioctl %s\n"), strerror(errno));
239       SCSI_CloseDevice(DeviceFD);
240       return(-1);
241     }
242
243   SCSI_CloseDevice(DeviceFD);
244   return(ret);  
245 }
246
247
248
249 int Tape_Status( int DeviceFD)
250 {
251   extern OpenFiles_T *pDev;
252   struct mtget mtget;
253   int ret = 0;
254
255   if (pDev[DeviceFD].devopen == 0)
256       if (SCSI_OpenDevice(DeviceFD) == 0)
257           return(-1);
258
259   if (ioctl(pDev[DeviceFD].fd, MTIOCGET, &mtget) != 0)
260   {
261      dbprintf(_("Tape_Status error ioctl %s\n"), strerror(errno));
262      SCSI_CloseDevice(DeviceFD);
263      return(-1);
264   }
265
266   dbprintf(_("ioctl -> mtget.mt_gstat %X\n"),mtget.mt_gstat);
267   if (GMT_ONLINE(mtget.mt_gstat))
268   {
269     ret = TAPE_ONLINE;
270   }
271
272   if (GMT_BOT(mtget.mt_gstat))
273   {
274     ret = ret | TAPE_BOT;
275   }
276
277   if (GMT_EOT(mtget.mt_gstat))
278   {
279     ret = ret | TAPE_EOT;
280   }
281
282   if (GMT_WR_PROT(mtget.mt_gstat))
283   {
284     ret = ret | TAPE_WR_PROT;
285   }
286
287   SCSI_CloseDevice(DeviceFD);
288   return(ret); 
289 }
290
291 int ScanBus(int print)
292 {
293 /*
294   Not yet
295 */
296   return(-1);
297 }
298 /*
299  * Local variables:
300  * indent-tabs-mode: nil
301  * c-file-style: gnu
302  * End:
303  */