Imported Upstream version 1.3.11
[debian/mtx] / scsi_aix.c
index 1c65b6acb15553e5e2f2b81ff8f1c4b428664242..41ced9341d509d26906e0ba06de1c07823b34632 100644 (file)
@@ -1,8 +1,7 @@
-/* Copyright 2001 Enhanced Software Technologies Inc.
- *   Written by Eric Lee Green <eric@estinc.com>
- *
- *$Date: 2001/06/05 17:10:25 $
- *$Revision: 1.1.1.1 $
+/* Changes 2003 Steve Heck <steve.heck@am.sony.com>
+
+$Date: 2007-03-04 15:27:11 -0800 (Sun, 04 Mar 2007) $
+$Revision: 164 $
 
   This program is free software; you may redistribute and/or modify it under
   the terms of the GNU General Public License Version 2 as published by the
 
 */
 
-/* These are the SCSI commands for AIX. The syntax for AIX is:
- *
- *  /dev/scsi<n>/<id>.<lun>
- *
- * where <n> is the number of the scsi adapter (0..n) and
- * <id> and <lun> are the SCSI ID and LUN of the device you wish to
- * talk to. 
- *
- * AIX has a very flexible SCSI subsystem, but it is somewhat
- * clumsy to use. 
- */
-
-/* we do very nasty thing here -- we operate upon device name! */
-DEVICE_TYPE SCSI_OpenDevice(char *DeviceName) {
-  /* okay, we must first parse out the ID and LUN: */
-  char *rptr;
-  struct tm_device_type *retval = (struct tm_device_type *) malloc(sizeof(struct tm_device_type));
-  int id,lun,filenum,idlun;
-
-  if (retval==NULL) {
-    fprintf(stderr,"%s: Allocation error in SCSI_OpenDevice for %s. Exiting.\n",argv0,DeviceName);
-    fflush(stderr);
-    exit(1);
-  }
-
-  rptr=strrchr(DeviceName,'/');
-  
-  if (!rptr) {
-    fprintf(stderr,"%s: Illegal device name '%s'. Exiting.\n",argv0,DeviceName);
-    fflush(stderr);
-    exit(1);
-  }
-  
-  *rptr++=0;
-
-  if (sscanf(rptr,"%d.%d",&id,&lun) < 2) {
-    /* whoops, we did not get 2 items:  */ 
-    fprintf(stderr,"%s: Illegal device name '%s/%s'. Exiting.\n",argv0,DeviceName,rptr);
-    fflush(stderr);
-    exit(1);
-  }
-
-  /* Okay, now to try to open the DeviceName */
-  if ((filenum=open(DeviceName,0))<0) {
-    fprintf(stderr,"%s: Illegal device name '%s/%s'. Exiting.\n",argv0,DeviceName,rptr);
-    perror(argv0);
-    fflush(stderr);
-    exit(1);
-  }
-
-  retval->filenum=filenum;
-  retval->id=id;
-  retval->lun=lun;
-  retval->DeviceName=DeviceName;
-  return (DEVICE_TYPE) retval;
+
+/* This is the SCSI commands for AIX using GSC Generic SCSI Interface. */
+
+#define LONG_PRINT_REQUEST_SENSE  /* sigh! */
+
+DEVICE_TYPE SCSI_OpenDevice(char *DeviceName)
+{
+       int DeviceFD = open(DeviceName, 0); 
+
+       if (DeviceFD < 0)
+               FatalError("cannot open SCSI device '%s' - %m\n", DeviceName);
+       return (DEVICE_TYPE) DeviceFD;
+}
+
+
+void SCSI_CloseDevice(char *DeviceName, DEVICE_TYPE DeviceFD)
+{
+       if (close(DeviceFD) < 0)
+               FatalError("cannot close SCSI device '%s' - %m\n", DeviceName);
 }
 
-#define MTX_HZ 1000 
-#define MTX_DEFAULT_SCSI_TIMEOUT 60*5*MTX_HZ /* 5 minutes! */
-static int mtx_default_timeout = MTX_DEFAULT_SCSI_TIMEOUT ;
-void SCSI_Set_Timeout(int sec) {
-  mtx_default_timeout=sec*MTX_HZ;
+
+#define HAS_SCSI_TIMEOUT
+
+static int timeout = 9 * 60;
+
+void SCSI_Set_Timeout(int to)
+{
+       timeout = to;
+}
+
+void SCSI_Default_Timeout(void)
+{
+       timeout = 9 * 60; /* the default */
 }
 
-void SCSI_Default_Timeout() {
-  mtx_default_timeout=MTX_DEFAULT_SCSI_TIMEOUT;
+#ifdef DEBUG
+int SCSI_DumpBuffer(int DataBufferLength, unsigned char *DataBuffer)
+{
+       int i, j;
+       j = 0;
+
+       for (i = 0; i < DataBufferLength; i++)
+       {
+               if (j == 25)
+               {
+                       fprintf(stderr, "\n");
+                       j = 0;
+               }
+
+               if (j == 0)
+               {
+                       fprintf(stderr, "%04x:", i);
+               }
+
+               if (j > 0)
+               {
+                       fprintf(stderr, " ");
+               }
+
+               fprintf(stderr, "%02x", (int)DataBuffer[i]);
+               j++;
+       }
+       fprintf(stderr, "\n");
 }
+#endif
+
+
 
-/* Okay , now *DO IT!* */
 int SCSI_ExecuteCommand(DEVICE_TYPE DeviceFD,
-                       Direction_T Direction,
-                       CDB_T *CDB,
-                       int CDB_Length,
-                       void *DataBuffer,
-                       int DataBufferLength,
-                       RequestSense_T *RequestSense) {
-
-  int id,lun;
-  struct tm_device_type *fd=(struct tm_device_type *) DeviceFD;
-  struct devinfo info;
-  struct sc_buf sb; /* the sc_buf struct needed to commicate w/adapter. */
-
-
-  id=fd->id;
-  lun=fd->lun;
-
-  /* okay, first of all, make sure we're not asking for a bigger
-   * operation than we are allowed to ask for, by going to the driver
-   * with IOCINFO. 
-   */
-  if (ioctl(filenum,IOCINFO,&info)) {
-    fprintf(stderr,"%s: Could not get info for %s. Exiting.\n",argv0,fd->DeviceName);
-    exit(1);
-  }
-    
-  /* Now check the max_transfer: */
-  if ((int)info.scsi.max_transfer < DataBufferLength) {
-    fprintf(stderr,"%s: SCSI transfer too large. %d requested, %d allowed.\n",argv0,DataBufferLength,(int)info.scsi.max_transfer);
-    fflush(stderr);
-    exit(1);
-  }
-  
-  /* okay, we have our open file, we have the other stuff: Now initialize
-     a transaction with that ID/LUN:
-  */
-
-  if (ioctl(filenum, SCIOSTART,IDLUN(id,lun))) {
-    fprintf(stderr,"%s: Could not start SCSI transaction with %s/%d.%d. Exiting.\n",argv0,fd->DeviceName,id,lun);
-    fflush(stderr);
-    exit(1);
-  }
-  
-  /* okay, now to decide command: */
-  
-  
-
-
-  /*... have finished command...*/
-  
-  /* when done w/command, get rid of the connection: */  
-  if (ioctl(filenum,SCIOSTOP,IDLUN(id,lun))) {
-    fprintf(stderr,"%s: Could not stop SCSI transaction with %s/%d.%d. Exiting.\n",argv0,fd->DeviceName,id,lun);
-    fflush(stderr);
-    exit(1);
-  }
-     
-  
+                                               Direction_T Direction,
+                                               CDB_T *CDB,
+                                               int CDB_Length,
+                                               void *DataBuffer,
+                                               int DataBufferLength,
+                                               RequestSense_T *RequestSense)
+{
+       int ioctl_result;
+       char sbyte;
+       scmd_t scmd;
+
+#ifdef DEBUG_SCSI
+       fprintf(stderr,"------CDB--------\n");
+       SCSI_DumpBuffer(CDB_Length,(char *)CDB);
+#endif
+
+       /* memset(&scmd, 0, sizeof(struct scmd_t)); */
+       /* memset(RequestSense, 0, sizeof(RequestSense_T)); */
+       switch (Direction)
+       {
+       case Input:
+               scmd.rw = 1;
+               if (DataBufferLength > 0)
+               {
+                       memset(DataBuffer, 0, DataBufferLength);
+               }
+               break;
+
+       case Output:
+               scmd.rw = 2;
+               break;
+       }
+       /* Set timeout to 5 minutes. */
+#ifdef DEBUG_TIMEOUT
+       fprintf(stderr,"timeout=%d\n",timeout);
+       fflush(stderr);
+#endif
+
+       scmd.timeval = timeout;
+
+       scmd.cdb = (caddr_t) CDB;
+       scmd.cdblen = CDB_Length;
+       scmd.data_buf = DataBuffer;
+       scmd.datalen = DataBufferLength;
+       scmd.sense_buf = (caddr_t) RequestSense;
+       scmd.senselen = sizeof(RequestSense_T);
+       scmd.statusp = &sbyte;
+       ioctl_result = ioctl(DeviceFD, GSC_CMD, (caddr_t) &scmd);
+
+       SCSI_Default_Timeout(); /* set it back to default, sigh. */
+
+       if (ioctl_result < 0)
+       {
+#ifdef DEBUG
+               perror("mtx");
+#endif
+               return ioctl_result;
+       }
+
+       if (sbyte != 0)
+       {
+               return -1;
+       }
+#ifdef DEBUG_SCSI
+       if (Direction==Input)
+       {
+               fprintf(stderr,"--------input data-----------\n");
+               SCSI_DumpBuffer(DataBufferLength,DataBuffer);
+       }
+#endif
+       return 0;
+}