Imported Debian patch 1.3.11-1
[debian/mtx] / scsi_hpux.c
1 /* Copyright 1997, 1998 Leonard Zubkoff <lnz@dandelion.com>
2    Changes copyright 2000 Eric Green <eric@badtux.org>
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 {
15         unsigned flags;                 // IN: SCTL_READ
16         unsigned cdb_length;            // IN
17         unsigned char cdb[16];          // IN 
18         void *data;                     // IN 
19         unsigned data_length;           // IN 
20         unsigned max_msecs;             // IN: milli-seconds before abort 
21         unsigned data_xfer;             // OUT 
22         unsigned cdb_status;            // OUT: SCSI status 
23         unsigned char sense[256];       // OUT 
24         unsigned sense_status;          // OUT: SCSI status 
25         unsigned sense_xfer;            // OUT: bytes of sense data received 
26         unsigned reserved[16];          // IN: Must be zero; OUT: undefined 
27 };
28
29 */
30
31
32 /* Hockey Pux may define these. If so, *UN*define them. */
33 #ifdef ILI
34 #undef ILI
35 #endif
36
37 #ifdef EOM
38 #undef EOM
39 #endif
40
41 /* This is the SCSI commands for HPUX. */
42
43 #define LONG_PRINT_REQUEST_SENSE  /* Sigh! */
44
45 DEVICE_TYPE SCSI_OpenDevice(char *DeviceName)
46 {
47         int DeviceFD = open(DeviceName, O_RDWR | O_NDELAY);
48
49         if (DeviceFD < 0)
50                 FatalError("cannot open SCSI device '%s' - %m\n", DeviceName);
51
52         return (DEVICE_TYPE) DeviceFD;
53 }
54
55
56 void SCSI_CloseDevice(char *DeviceName, DEVICE_TYPE DeviceFD)
57 {
58         if (close(DeviceFD) < 0)
59                 FatalError("cannot close SCSI device '%s' - %m\n", DeviceName);
60 }
61
62 #define MTX_HZ 1000
63 #define DEFAULT_HZ (5*60*MTX_HZ)
64
65 static int sctl_io_timeout=DEFAULT_HZ;          /* default timeout is 5 minutes. */
66
67
68 void SCSI_Set_Timeout(int to)
69 {
70         sctl_io_timeout=to*60*MTX_HZ;
71 }
72
73 void SCSI_Default_Timeout(void)
74 {
75         sctl_io_timeout=DEFAULT_HZ;
76 }
77
78
79 int SCSI_ExecuteCommand(DEVICE_TYPE DeviceFD,
80                                                 Direction_T Direction,
81                                                 CDB_T *CDB,
82                                                 int CDB_Length,
83                                                 void *DataBuffer,
84                                                 int DataBufferLength,
85                                                 RequestSense_T *RequestSense)
86 {
87         int ioctl_result;
88         struct sctl_io Command;
89
90         int i;
91
92         memset(&Command, 0, sizeof(struct sctl_io));
93         memset(RequestSense, 0, sizeof(RequestSense_T));
94
95         switch (Direction)
96         {
97         case Input:
98                 if (DataBufferLength > 0)
99                         memset(DataBuffer, 0, DataBufferLength);
100                 Command.flags =  SCTL_READ | SCTL_INIT_SDTR;
101                 break;
102
103         case Output:
104                 Command.flags = SCTL_INIT_WDTR | SCTL_INIT_SDTR;
105                 break;
106         }
107
108         Command.max_msecs = sctl_io_timeout;    /* Set timeout to <n> minutes. */
109         memcpy(Command.cdb, CDB, CDB_Length);
110         Command.cdb_length = CDB_Length;
111         Command.data = DataBuffer;
112         Command.data_length = DataBufferLength;
113         ioctl_result=ioctl(DeviceFD, SIOC_IO, &Command);
114         SCSI_Default_Timeout();                 /* change the default back to 5 minutes */
115
116         if (ioctl_result < 0)
117         {
118                 perror("mtx");
119                 return ioctl_result;
120         }
121
122         if (Command.sense_xfer > sizeof(RequestSense_T))
123         {
124                 Command.sense_xfer=sizeof(RequestSense_T);
125         }
126
127         if (Command.sense_xfer)
128         {
129                 memcpy(RequestSense, Command.sense, Command.sense_xfer);
130         }
131
132         return Command.sense_status;
133 }