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-aix.c,v 1.22 2005/10/15 13:20:47 martinea Exp $
29 * Interface to execute SCSI commands on an AIX System
31 * Copyright (c) Thomas Hepper th@ant.han.de
37 #ifdef HAVE_AIX_LIKE_SCSI
39 #ifdef HAVE_SYS_TYPES_H
40 #include <sys/types.h>
58 #include <sys/scarray.h>
61 #include <scsi-defs.h>
64 void SCSI_OS_Version()
67 static char rcsid[] = "$Id: scsi-aix.c,v 1.22 2005/10/15 13:20:47 martinea Exp $";
68 DebugPrint(DEBUG_INFO, SECTION_INFO, "scsi-os-layer: %s\n",rcsid);
73 int SCSI_OpenDevice(int ip)
77 extern OpenFiles_T *pDev;
79 if (pDev[ip].inqdone == 0)
83 * Check if it is an gsc (generic SCSI device)
85 if (strncmp("/dev/gsc", pDev[ip].dev, 8) == 0)
87 pDev[ip].flags = AIX_USE_GSC;
88 DeviceFD = open(pDev[ip].dev, 0);
90 DeviceFD = openx(pDev[ip].dev, O_RDWR, 0, SC_DIAGNOSTIC);
95 pDev[ip].fd = DeviceFD;
98 pDev[ip].inquiry = (SCSIInquiry_T *)malloc(INQUIRY_SIZE);
100 if (SCSI_Inquiry(ip, pDev[ip].inquiry, INQUIRY_SIZE) == 0)
102 if (pDev[ip].inquiry->type == TYPE_TAPE || pDev[ip].inquiry->type == TYPE_CHANGER)
105 pDev[ip].ident[i] = pDev[ip].inquiry->prod_ident[i];
106 for (i=15; i >= 0 && !isalnum(pDev[ip].ident[i]) ; i--)
108 pDev[ip].ident[i] = '\0';
112 if (pDev[ip].inquiry->type == TYPE_TAPE)
114 pDev[ip].type = stralloc("tape");
117 if (pDev[ip].inquiry->type == TYPE_CHANGER)
119 pDev[ip].type = stralloc("changer");
122 PrintInquiry(pDev[ip].inquiry);
126 free(pDev[ip].inquiry);
130 free(pDev[ip].inquiry);
131 pDev[ip].inquiry = NULL;
136 dbprintf(("SCSI_OpenDevice %s failed\n", pDev[ip].dev));
140 if ((DeviceFD = openx(pDev[ip].dev, O_RDWR, 0, SC_DIAGNOSTIC)) >= 0)
142 pDev[ip].fd = DeviceFD;
143 pDev[ip].devopen = 1;
150 int SCSI_CloseDevice(int DeviceFD)
153 extern OpenFiles_T *pDev;
155 ret = close(pDev[DeviceFD].fd);
156 pDev[DeviceFD].devopen = 0;
161 int SCSI_ExecuteCommand(int DeviceFD,
162 Direction_T Direction,
166 int DataBufferLength,
167 char *RequestSenseBuf,
168 int RequestSenseLength)
170 extern OpenFiles_T *pDev;
171 extern FILE * debug_file;
174 ExtendedRequestSense_T ExtendedRequestSense;
183 if (pDev[DeviceFD].avail == 0)
189 if (pDev[DeviceFD].flags == AIX_USE_GSC)
192 scmd.cdblen = CDB_Length;
193 scmd.data_buf = DataBuffer;
194 scmd.datalen = DataBufferLength;
195 scmd.sense_buf = RequestSenseBuf;
196 scmd.senselen = RequestSenseLength;
197 scmd.statusp = &sbyte;
209 if (ioctl(pDev[DeviceFD].fd, GSC_CMD, (caddr_t) &scmd) < 0) {
215 bzero(&ds, sizeof(struct sc_iocmd));
216 bzero(RequestSenseBuf, RequestSenseLength);
217 bzero(&ExtendedRequestSense, sizeof(ExtendedRequestSense_T));
221 ds.timeout_value = 60;
222 bcopy(CDB, ds.scsi_cdb, CDB_Length);
223 ds.command_length = CDB_Length;
225 * Data buffer for results
226 * If the size of the buffer is 0
227 * then keep this fields untouched
229 if (DataBufferLength > 0)
231 ds.buffer = DataBuffer;
232 ds.data_length = DataBufferLength;
235 /* Sense Buffer is not available on AIX ?*/
237 ds.req_sense_length = 255;
238 ds.request_sense_ptr = (char *)RequestSense;
243 ds.flags = ds.flags | B_READ;
246 ds.flags = ds.flags | B_WRITE;
249 DecodeSCSI(CDB, "SCSI_ExecuteCommand : ");
251 if (pDev[DeviceFD].devopen == 0)
252 if (SCSI_OpenDevice(DeviceFD) == 0)
254 Result = ioctl(pDev[DeviceFD].fd, STIOCMD, &ds);
255 SCSI_CloseDevice(DeviceFD);
259 switch (ds.scsi_bus_status)
262 SINQ[0] = SC_COM_REQUEST_SENSE;
268 bcopy(SINQ, ds.scsi_cdb, 6);
269 ds.command_length = 6;
270 ds.buffer = RequestSenseBuf;
271 ds.data_length = RequestSenseLength;
273 if (pDev[DeviceFD].devopen == 0)
274 if (SCSI_OpenDevice(DeviceFD) == 0)
276 Result = ioctl(pDev[DeviceFD].fd, STIOCMD, &ds);
277 SCSI_CloseDevice(DeviceFD);
283 case SC_CHECK_CONDITION:
284 SINQ[0] = SC_COM_REQUEST_SENSE;
290 bcopy(SINQ, ds.scsi_cdb, 6);
291 ds.command_length = 6;
292 ds.buffer = RequestSenseBuf;
293 ds.data_length = RequestSenseLength;
295 if (pDev[DeviceFD].devopen == 0)
296 if (SCSI_OpenDevice(DeviceFD) == 0)
298 Result = ioctl(pDev[DeviceFD].fd, STIOCMD, &ds);
299 SCSI_CloseDevice(DeviceFD);
304 * Makes no sense yet, may result in an endless loop
306 RequestSense(DeviceFD, &ExtendedRequestSense, 0);
307 DecodeExtSense(&ExtendedRequestSense, "SCSI_ExecuteCommand:", debug_file);
308 bcopy(&ExtendedRequestSense, RequestSenseBuf, RequestSenseLength);
310 dbprintf(("ioctl on %d return %d\n", pDev[DeviceFD].fd, Result));
311 dbprintf(("ret: %d errno: %d (%s)\n", Result, errno, ""));
312 dbprintf(("data_length: %d\n", ds.data_length));
313 dbprintf(("buffer: 0x%X\n", ds.buffer));
314 dbprintf(("timeout_value: %d\n", ds.timeout_value));
315 dbprintf(("status_validity: %d\n", ds.status_validity));
316 dbprintf(("scsi_bus_status: 0x%X\n", ds.scsi_bus_status));
317 dbprintf(("adapter_status: 0x%X\n", ds.adapter_status));
318 dbprintf(("adap_q_status: 0x%X\n", ds.adap_q_status));
319 dbprintf(("q_tag_msg: 0x%X\n", ds.q_tag_msg));
320 dbprintf(("flags: 0X%X\n", ds.flags));
332 struct sc_inquiry si;
338 char bus[] = "/dev/scsi0";
340 if ((fd = open(bus, O_RDWR)) == -1)
343 for (target = 0; target < 7; target++)
345 for (lun = 0; lun < 7; lun++)
347 printf("Target:Lun %d:%d\n", target,lun);
348 if (ioctl(fd, SCIOSTART, IDLUN(target, lun)) == -1) {
349 if (errno == EINVAL) {
350 printf("is in use\n");
359 bzero(&si, sizeof(si));
362 si.inquiry_len = 255;
363 si.inquiry_ptr = (char *)&buf;
364 if (ioctl(fd, SCIOINQU, &si) == -1)
366 printf("SCIOINQU: %s\n", strerror(errno));
368 dump_hex(&buf, 255, DEBUG_INFO, SECTION_SCSI);
369 type = buf[0] & 0x1f;
371 printf(stdout,"%-28s|Device Type %d\n",buf[8], type);
373 if (!isbusy && ioctl(fd, SCIOSTOP, IDLUN(target, lun)) == -1)
379 int Tape_Ioctl(int DeviceFD, int command)
381 extern OpenFiles_T *pDev;
386 int Tape_Status( int DeviceFD)
394 int ScanBus(int print)
406 * indent-tabs-mode: nil