1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
|
.TH SCSI 3
.SH NAME
openscsi, scsiready, scsi, scsicmd, scsierror \- SCSI device operations
.SH SYNOPSIS
.nf
.ft L
#include <u.h>
#include <libc.h>
#include <disk.h>
.ft
.PP
.ft L
typedef struct Scsi {
char *inquire;
int rawfd;
int nchange;
ulong changetime;
};
.ft
.PP
.B
Scsi* openscsi(char *devdir)
.PP
.B
void closescsi(Scsi *s)
.PP
.B
int scsiready(Scsi *s)
.PP
.B
int scsi(Scsi *s, uchar *cmd, int ncmd,
.br
void *data, int ndata, int dir)
.PP
.B
int scsicmd(Scsi *s, uchar *cmd, int ncmd,
.br
void *data, int ndata, int dir)
.PP
.B
char* scsierror(int asc, int ascq)
.PP
.B
int scsiverbose;
.SH DESCRIPTION
These routines provide an interface
to a SCSI or ATAPI device via Plan 9's
\fIsd\fR(3).
.PP
.I Openscsi
attempts to open the file
.IB devdir /raw
and use it to send raw SCSI commands.
On success, it reads the device's inquiry
string and stores it in in returned
.B Scsi
structure.
.I Closescsi
closes the connection and frees the
.B Scsi
structure.
.PP
.I Scsiready
sends the ``unit ready'' command up to three times,
returning zero if the unit responds that it is ready,
or \-1 on error.
.PP
.I Scsierror
returns a textual description of the SCSI status
denoted by the ASC and ASCQ sense codes.
The description is found by consulting
.BR /sys/lib/scsicodes .
The returned string will be overwritten by
the next call to
.IR scsierror .
.PP
.I Scsi
and
.I scsicmd
execute a single SCSI command on the named device.
There should be
.I ncmd
bytes of
command data in
.IR cmd ;
if
.I dir
is
.BR Sread ,
a successful operation
will store up to
.I ndata
bytes into
.IR data ,
returning the number of bytes stored.
If
.I dir
is
.BR Swrite ,
the
.I ndata
bytes beginning at
.I data
are transmitted as the data argument to
the command, and the
number of bytes written is returned.
If
.I dir
is
.BR Snone ,
.I data
and
.I ndata
are ignored.
On error,
.I scsi
and
.I scsicmd
return \-1.
.I Scsicmd
simply issues the command and
returns the result;
.I scsi
works a bit harder and
is the more commonly used routine.
.I Scsi
attempts to send the command;
if it is successful,
.I scsi
returns what
.I scsicmd
returned.
Otherwise,
.I scsi
sends a request sense command to
obtain the reason for the failure,
sends a unit ready command in
an attempt to bring the unit out of any
inconsistent states, and tries again.
If the second try fails,
.I scsi
sends the request
sense and unit ready commands
again
and then uses
.I scsierror
to set
.I errstr
with a reason for failure.
.PP
The
.B nchange
and
.B changetime
fields
in the
.B Scsi
structure
record the number of times a media
change has been detected, and the
time when the current media was
inserted into the drive (really the
first time a SCSI command was issued
after it was inserted).
They are maintained by
.IR scsi .
.PP
If
.I scsiverbose
is set,
these commands will produce a fair
amount of debugging output on file descriptor 2
when SCSI commands fail.
.SH FILES
.TP
.B /sys/lib/scsicodes
List of textual messages corresponding to SCSI error codes;
consulted by
.BR scsierror .
.SH SOURCE
.B /usr/local/plan9/src/libdisk/scsi.c
.SH SEE ALSO
Plan 9's
\fIsd\fR(3) and
\fIscuzz\fR(8)
.SH BUGS
SCSI devices on Unix do not present the interface expected by
these routines.
|