Imported Upstream version 1.2.16rel
[debian/mtx] / scsi_hpux.c
1 /* Copyright 1997, 1998 Leonard Zubkoff <lnz@dandelion.com>
2    Changes copyright 2000 Eric Green <eric@estinc.com>
3
4   This program is free software; you may redistribute and/or modify it under
5   the terms of the GNU General Public License Version 2 as published by the
6   Free Software Foundation.
7
8   This program is distributed in the hope that it will be useful, but
9   WITHOUT ANY WARRANTY, without even the implied warranty of MERCHANTABILITY
10   or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License
11   for complete details.
12
13 struct sctl_io {
14         unsigned flags;                 // IN: SCTL_READ
15         unsigned cdb_length;            // IN
16         unsigned char cdb[16];          // IN 
17         void *data;                     // IN 
18         unsigned data_length;           // IN 
19         unsigned max_msecs;             // IN: milli-seconds before abort 
20         unsigned data_xfer;             // OUT 
21         unsigned cdb_status;            // OUT: SCSI status 
22         unsigned char sense[256];       // OUT 
23         unsigned sense_status;          // OUT: SCSI status 
24         unsigned sense_xfer;            // OUT: bytes of sense data received 
25         unsigned reserved[16];          // IN: Must be zero; OUT: undefined 
26 };
27
28 */
29
30
31 /* Hockey Pux may define these. If so, *UN*define them. */
32 #ifdef ILI
33 #undef ILI
34 #endif
35
36 #ifdef EOM
37 #undef EOM
38 #endif
39
40 /* This is the SCSI commands for HPUX. */
41
42 #define LONG_PRINT_REQUEST_SENSE  /* Sigh! */
43
44 DEVICE_TYPE SCSI_OpenDevice(char *DeviceName)
45 {
46   int DeviceFD = open(DeviceName, O_RDWR | O_NDELAY);
47   if (DeviceFD < 0)
48     FatalError("cannot open SCSI device '%s' - %m\n", DeviceName);
49   return (DEVICE_TYPE) DeviceFD;
50 }
51
52
53 void SCSI_CloseDevice(char *DeviceName,
54                              DEVICE_TYPE DeviceFD)
55 {
56   if (close(DeviceFD) < 0)
57     FatalError("cannot close SCSI device '%s' - %m\n", DeviceName);
58 }
59
60 #define MTX_HZ 1000
61 #define DEFAULT_HZ (5*60*MTX_HZ)
62
63 static int sctl_io_timeout=DEFAULT_HZ;  /* default timeout is 5 minutes. */
64
65
66 void SCSI_Set_Timeout(int to) {
67   sctl_io_timeout=to*60*MTX_HZ;
68 }
69
70 void SCSI_Default_Timeout(void) {
71   sctl_io_timeout=DEFAULT_HZ;
72 }
73
74
75 int SCSI_ExecuteCommand(DEVICE_TYPE DeviceFD,
76                                Direction_T Direction,
77                                CDB_T *CDB,
78                                int CDB_Length,
79                                void *DataBuffer,
80                                int DataBufferLength,
81                                RequestSense_T *RequestSense)
82 {
83     int ioctl_result;
84     struct sctl_io Command;
85
86     int i;
87
88     memset(&Command, 0, sizeof(struct sctl_io));
89     memset(RequestSense, 0, sizeof(RequestSense_T));
90
91     switch (Direction) {
92          case Input:
93               if (DataBufferLength > 0)
94                    memset(DataBuffer, 0, DataBufferLength);
95               Command.flags =  SCTL_READ | SCTL_INIT_SDTR;
96               break;
97          case Output:
98               Command.flags = SCTL_INIT_WDTR | SCTL_INIT_SDTR;
99               break;
100          }
101
102     Command.max_msecs = sctl_io_timeout;    /* Set timeout to <n> minutes. */
103     memcpy(Command.cdb, CDB, CDB_Length);
104     Command.cdb_length = CDB_Length;
105     Command.data = DataBuffer;
106     Command.data_length = DataBufferLength;
107     ioctl_result=ioctl(DeviceFD, SIOC_IO, &Command);
108     SCSI_Default_Timeout();  /* change the default back to 5 minutes */
109     if (ioctl_result < 0) {
110          perror("mtx");
111          return ioctl_result;
112          }
113
114     if (Command.sense_xfer > sizeof(RequestSense_T)) {
115       Command.sense_xfer=sizeof(RequestSense_T);
116     }
117
118     if (Command.sense_xfer) {
119       memcpy(RequestSense, Command.sense, Command.sense_xfer);
120     }
121
122     return Command.sense_status;
123 }