-/* 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;
+}