source: trunk/minix/commands/i386/mtools-3.9.7/scsi.c@ 15

Last change on this file since 15 was 9, checked in by Mattia Monga, 14 years ago

Minix 3.1.2a

File size: 6.1 KB
Line 
1/*
2 * scsi.c
3 * Iomega Zip/Jaz drive tool
4 * change protection mode and eject disk
5 */
6
7/* scis.c by Markus Gyger <mgyger@itr.ch> */
8/* This code is based on ftp://gear.torque.net/pub/ziptool.c */
9/* by Grant R. Guenther with the following copyright notice: */
10
11/* (c) 1996 Grant R. Guenther, based on work of Itai Nahshon */
12/* http://www.torque.net/ziptool.html */
13
14
15/* A.K. Moved this from mzip.c to a separate file in order to share with
16 * plain_io.c */
17
18#include "sysincludes.h"
19#include "mtools.h"
20#include "scsi.h"
21
22#if defined OS_hpux
23#include <sys/scsi.h>
24#endif
25
26#ifdef OS_solaris
27#include <sys/scsi/scsi.h>
28#endif /* solaris */
29
30#ifdef OS_sunos
31#include <scsi/generic/commands.h>
32#include <scsi/impl/uscsi.h>
33#endif /* sunos */
34
35#ifdef sgi
36#include <sys/dsreq.h>
37#endif
38
39#ifdef OS_linux
40#define SCSI_IOCTL_SEND_COMMAND 1
41struct scsi_ioctl_command {
42 int inlen;
43 int outlen;
44 char cmd[5008];
45};
46#endif
47
48#ifdef _SCO_DS
49#include <sys/scsicmd.h>
50#endif
51
52#if (defined(OS_freebsd)) && (__FreeBSD__ >= 2)
53#include <camlib.h>
54#endif
55
56int scsi_max_length(void)
57{
58#ifdef OS_linux
59 return 8;
60#else
61 return 255;
62#endif
63}
64
65int scsi_open(const char *name, int flag, int mode, void **extra_data)
66{
67#if (defined(OS_freebsd)) && (__FreeBSD__ >= 2)
68 struct cam_device *cam_dev;
69 cam_dev = cam_open_device(name, O_RDWR);
70 *extra_data = (void *) cam_dev;
71 if (cam_dev)
72 return cam_dev->fd;
73 else
74 return -1;
75#else
76 return open(name, O_RDONLY
77#ifdef O_NDELAY
78 | O_NDELAY
79#endif
80 /* O_RDONLY | dev->mode*/);
81#endif
82}
83
84int scsi_cmd(int fd, unsigned char *cdb, int cmdlen, scsi_io_mode_t mode,
85 void *data, size_t len, void *extra_data)
86{
87#if defined OS_hpux
88 struct sctl_io sctl_io;
89
90 memset(&sctl_io, 0, sizeof sctl_io); /* clear reserved fields */
91 memcpy(sctl_io.cdb, cdb, cmdlen); /* copy command */
92 sctl_io.cdb_length = cmdlen; /* command length */
93 sctl_io.max_msecs = 2000; /* allow 2 seconds for cmd */
94
95 switch (mode) {
96 case SCSI_IO_READ:
97 sctl_io.flags = SCTL_READ;
98 sctl_io.data_length = len;
99 sctl_io.data = data;
100 break;
101 case SCSI_IO_WRITE:
102 sctl_io.flags = 0;
103 sctl_io.data_length = data ? len : 0;
104 sctl_io.data = len ? data : 0;
105 break;
106 }
107
108 if (ioctl(fd, SIOC_IO, &sctl_io) == -1) {
109 perror("scsi_io");
110 return -1;
111 }
112
113 return sctl_io.cdb_status;
114
115#elif defined OS_sunos || defined OS_solaris
116 struct uscsi_cmd uscsi_cmd;
117 memset(&uscsi_cmd, 0, sizeof uscsi_cmd);
118 uscsi_cmd.uscsi_cdb = (char *)cdb;
119 uscsi_cmd.uscsi_cdblen = cmdlen;
120#ifdef OS_solaris
121 uscsi_cmd.uscsi_timeout = 20; /* msec? */
122#endif /* solaris */
123
124 uscsi_cmd.uscsi_buflen = (u_int)len;
125 uscsi_cmd.uscsi_bufaddr = data;
126
127 switch (mode) {
128 case SCSI_IO_READ:
129 uscsi_cmd.uscsi_flags = USCSI_READ;
130 break;
131 case SCSI_IO_WRITE:
132 uscsi_cmd.uscsi_flags = USCSI_WRITE;
133 break;
134 }
135
136 if (ioctl(fd, USCSICMD, &uscsi_cmd) == -1) {
137 perror("scsi_io");
138 return -1;
139 }
140
141 if(uscsi_cmd.uscsi_status) {
142 errno = 0;
143 fprintf(stderr,"scsi status=%x\n",
144 (unsigned short)uscsi_cmd.uscsi_status);
145 return -1;
146 }
147
148 return 0;
149
150#elif defined OS_linux
151 struct scsi_ioctl_command scsi_cmd;
152
153
154 memcpy(scsi_cmd.cmd, cdb, cmdlen); /* copy command */
155
156 switch (mode) {
157 case SCSI_IO_READ:
158 scsi_cmd.inlen = 0;
159 scsi_cmd.outlen = len;
160 break;
161 case SCSI_IO_WRITE:
162 scsi_cmd.inlen = len;
163 scsi_cmd.outlen = 0;
164 memcpy(scsi_cmd.cmd + cmdlen,data,len);
165 break;
166 }
167
168 if (ioctl(fd, SCSI_IOCTL_SEND_COMMAND, &scsi_cmd) < 0) {
169 perror("scsi_io");
170 return -1;
171 }
172
173 switch (mode) {
174 case SCSI_IO_READ:
175 memcpy(data, &scsi_cmd.cmd[0], len);
176 break;
177 case SCSI_IO_WRITE:
178 break;
179 }
180
181 return 0; /* where to get scsi status? */
182
183#elif defined _SCO_DS
184 struct scsicmd scsi_cmd;
185
186 memset(scsi_cmd.cdb, 0, SCSICMDLEN); /* ensure zero pad */
187 memcpy(scsi_cmd.cdb, cdb, cmdlen);
188 scsi_cmd.cdb_len = cmdlen;
189 scsi_cmd.data_len = len;
190 scsi_cmd.data_ptr = data;
191 scsi_cmd.is_write = mode == SCSI_IO_WRITE;
192 if (ioctl(fd,SCSIUSERCMD,&scsi_cmd) == -1) {
193 perror("scsi_io");
194 printf("scsi status: host=%x; target=%x\n",
195 (unsigned)scsi_cmd.host_sts,(unsigned)scsi_cmd.target_sts);
196 return -1;
197 }
198 return 0;
199#elif defined sgi
200 struct dsreq scsi_cmd;
201
202 scsi_cmd.ds_cmdbuf = (char *)cdb;
203 scsi_cmd.ds_cmdlen = cmdlen;
204 scsi_cmd.ds_databuf = data;
205 scsi_cmd.ds_datalen = len;
206 switch (mode) {
207 case SCSI_IO_READ:
208 scsi_cmd.ds_flags = DSRQ_READ|DSRQ_SENSE;
209 break;
210 case SCSI_IO_WRITE:
211 scsi_cmd.ds_flags = DSRQ_WRITE|DSRQ_SENSE;
212 break;
213 }
214 scsi_cmd.ds_time = 10000;
215 scsi_cmd.ds_link = 0;
216 scsi_cmd.ds_synch =0;
217 scsi_cmd.ds_ret =0;
218 if (ioctl(fd, DS_ENTER, &scsi_cmd) == -1) {
219 perror("scsi_io");
220 return -1;
221 }
222
223 if(scsi_cmd.ds_status) {
224 errno = 0;
225 fprintf(stderr,"scsi status=%x\n",
226 (unsigned short)scsi_cmd.ds_status);
227 return -1;
228 }
229
230 return 0;
231#elif (defined OS_freebsd) && (__FreeBSD__ >= 2)
232#define MSG_SIMPLE_Q_TAG 0x20 /* O/O */
233 union ccb *ccb;
234 int flags;
235 int r;
236 struct cam_device *cam_dev = (struct cam_device *) extra_data;
237
238
239 if (cam_dev==NULL || cam_dev->fd!=fd)
240 {
241 fprintf(stderr,"invalid file descriptor\n");
242 return -1;
243 }
244 ccb = cam_getccb(cam_dev);
245
246 bcopy(cdb, ccb->csio.cdb_io.cdb_bytes, cmdlen);
247
248 if (mode == SCSI_IO_READ)
249 flags = CAM_DIR_IN;
250 else if (data && len)
251 flags = CAM_DIR_OUT;
252 else
253 flags = CAM_DIR_NONE;
254 cam_fill_csio(&ccb->csio,
255 /* retry */ 1,
256 /* cbfcnp */ NULL,
257 flags,
258 /* tag_action */ MSG_SIMPLE_Q_TAG,
259 /*data_ptr*/ len ? data : 0,
260 /*data_len */ data ? len : 0,
261 96,
262 cmdlen,
263 5000);
264
265 if (cam_send_ccb(cam_dev, ccb) < 0 ||
266 (ccb->ccb_h.status & CAM_STATUS_MASK) != CAM_REQ_CMP) {
267 return -1;
268 }
269 return 0;
270#else
271 fprintf(stderr, "scsi_io not implemented\n");
272 return -1;
273#endif
274}
Note: See TracBrowser for help on using the repository browser.