Bug Summary

File:scsi/st.c
Warning:line 751, column 2
Value stored to 'link' is never read

Annotated Source Code

Press '?' to see keyboard shortcuts

clang -cc1 -cc1 -triple amd64-unknown-openbsd7.4 -analyze -disable-free -clear-ast-before-backend -disable-llvm-verifier -discard-value-names -main-file-name st.c -analyzer-checker=core -analyzer-checker=apiModeling -analyzer-checker=unix -analyzer-checker=deadcode -analyzer-checker=security.insecureAPI.UncheckedReturn -analyzer-checker=security.insecureAPI.getpw -analyzer-checker=security.insecureAPI.gets -analyzer-checker=security.insecureAPI.mktemp -analyzer-checker=security.insecureAPI.mkstemp -analyzer-checker=security.insecureAPI.vfork -analyzer-checker=nullability.NullPassedToNonnull -analyzer-checker=nullability.NullReturnedFromNonnull -analyzer-output plist -w -setup-static-analyzer -mrelocation-model static -mframe-pointer=all -relaxed-aliasing -ffp-contract=on -fno-rounding-math -mconstructor-aliases -ffreestanding -mcmodel=kernel -target-cpu x86-64 -target-feature +retpoline-indirect-calls -target-feature +retpoline-indirect-branches -target-feature -sse2 -target-feature -sse -target-feature -3dnow -target-feature -mmx -target-feature +save-args -target-feature +retpoline-external-thunk -disable-red-zone -no-implicit-float -tune-cpu generic -debugger-tuning=gdb -fcoverage-compilation-dir=/usr/src/sys/arch/amd64/compile/GENERIC.MP/obj -nostdsysteminc -nobuiltininc -resource-dir /usr/local/llvm16/lib/clang/16 -I /usr/src/sys -I /usr/src/sys/arch/amd64/compile/GENERIC.MP/obj -I /usr/src/sys/arch -I /usr/src/sys/dev/pci/drm/include -I /usr/src/sys/dev/pci/drm/include/uapi -I /usr/src/sys/dev/pci/drm/amd/include/asic_reg -I /usr/src/sys/dev/pci/drm/amd/include -I /usr/src/sys/dev/pci/drm/amd/amdgpu -I /usr/src/sys/dev/pci/drm/amd/display -I /usr/src/sys/dev/pci/drm/amd/display/include -I /usr/src/sys/dev/pci/drm/amd/display/dc -I /usr/src/sys/dev/pci/drm/amd/display/amdgpu_dm -I /usr/src/sys/dev/pci/drm/amd/pm/inc -I /usr/src/sys/dev/pci/drm/amd/pm/legacy-dpm -I /usr/src/sys/dev/pci/drm/amd/pm/swsmu -I /usr/src/sys/dev/pci/drm/amd/pm/swsmu/inc -I /usr/src/sys/dev/pci/drm/amd/pm/swsmu/smu11 -I /usr/src/sys/dev/pci/drm/amd/pm/swsmu/smu12 -I /usr/src/sys/dev/pci/drm/amd/pm/swsmu/smu13 -I /usr/src/sys/dev/pci/drm/amd/pm/powerplay/inc -I /usr/src/sys/dev/pci/drm/amd/pm/powerplay/hwmgr -I /usr/src/sys/dev/pci/drm/amd/pm/powerplay/smumgr -I /usr/src/sys/dev/pci/drm/amd/pm/swsmu/inc -I /usr/src/sys/dev/pci/drm/amd/pm/swsmu/inc/pmfw_if -I /usr/src/sys/dev/pci/drm/amd/display/dc/inc -I /usr/src/sys/dev/pci/drm/amd/display/dc/inc/hw -I /usr/src/sys/dev/pci/drm/amd/display/dc/clk_mgr -I /usr/src/sys/dev/pci/drm/amd/display/modules/inc -I /usr/src/sys/dev/pci/drm/amd/display/modules/hdcp -I /usr/src/sys/dev/pci/drm/amd/display/dmub/inc -I /usr/src/sys/dev/pci/drm/i915 -D DDB -D DIAGNOSTIC -D KTRACE -D ACCOUNTING -D KMEMSTATS -D PTRACE -D POOL_DEBUG -D CRYPTO -D SYSVMSG -D SYSVSEM -D SYSVSHM -D UVM_SWAP_ENCRYPT -D FFS -D FFS2 -D FFS_SOFTUPDATES -D UFS_DIRHASH -D QUOTA -D EXT2FS -D MFS -D NFSCLIENT -D NFSSERVER -D CD9660 -D UDF -D MSDOSFS -D FIFO -D FUSE -D SOCKET_SPLICE -D TCP_ECN -D TCP_SIGNATURE -D INET6 -D IPSEC -D PPP_BSDCOMP -D PPP_DEFLATE -D PIPEX -D MROUTING -D MPLS -D BOOT_CONFIG -D USER_PCICONF -D APERTURE -D MTRR -D NTFS -D SUSPEND -D HIBERNATE -D PCIVERBOSE -D USBVERBOSE -D WSDISPLAY_COMPAT_USL -D WSDISPLAY_COMPAT_RAWKBD -D WSDISPLAY_DEFAULTSCREENS=6 -D X86EMU -D ONEWIREVERBOSE -D MULTIPROCESSOR -D MAXUSERS=80 -D _KERNEL -O2 -Wno-pointer-sign -Wno-address-of-packed-member -Wno-constant-conversion -Wno-unused-but-set-variable -Wno-gnu-folding-constant -fdebug-compilation-dir=/usr/src/sys/arch/amd64/compile/GENERIC.MP/obj -ferror-limit 19 -fwrapv -D_RET_PROTECTOR -ret-protector -fcf-protection=branch -fgnuc-version=4.2.1 -vectorize-loops -vectorize-slp -fno-builtin-malloc -fno-builtin-calloc -fno-builtin-realloc -fno-builtin-valloc -fno-builtin-free -fno-builtin-strdup -fno-builtin-strndup -analyzer-output=html -faddrsig -o /home/ben/Projects/scan/2024-01-11-110808-61670-1 -x c /usr/src/sys/scsi/st.c
1/* $OpenBSD: st.c,v 1.190 2023/04/27 18:21:44 robert Exp $ */
2/* $NetBSD: st.c,v 1.71 1997/02/21 23:03:49 thorpej Exp $ */
3
4/*
5 * Copyright (c) 1994 Charles Hannum. All rights reserved.
6 *
7 * Redistribution and use in source and binary forms, with or without
8 * modification, are permitted provided that the following conditions
9 * are met:
10 * 1. Redistributions of source code must retain the above copyright
11 * notice, this list of conditions and the following disclaimer.
12 * 2. Redistributions in binary form must reproduce the above copyright
13 * notice, this list of conditions and the following disclaimer in the
14 * documentation and/or other materials provided with the distribution.
15 * 3. All advertising materials mentioning features or use of this software
16 * must display the following acknowledgement:
17 * This product includes software developed by Charles Hannum.
18 * 4. The name of the author may not be used to endorse or promote products
19 * derived from this software without specific prior written permission.
20 *
21 * THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR
22 * IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES
23 * OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED.
24 * IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT,
25 * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT
26 * NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
27 * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
28 * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
29 * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF
30 * THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
31 */
32
33/*
34 * Originally written by Julian Elischer (julian@tfs.com)
35 * for TRW Financial Systems for use under the MACH(2.5) operating system.
36 *
37 * TRW Financial Systems, in accordance with their agreement with Carnegie
38 * Mellon University, makes this software available to CMU to distribute
39 * or use in any manner that they see fit as long as this message is kept with
40 * the software. For this reason TFS also grants any other persons or
41 * organisations permission to use or modify this software.
42 *
43 * TFS supplies this software to be publicly redistributed
44 * on the understanding that TFS is not responsible for the correct
45 * functioning of this software in any circumstances.
46 *
47 * Ported to run under 386BSD by Julian Elischer (julian@tfs.com) Sept 1992
48 * major changes by Julian Elischer (julian@jules.dialix.oz.au) May 1993
49 */
50
51/*
52 * To do:
53 * work out some better way of guessing what a good timeout is going
54 * to be depending on whether we expect to retension or not.
55 */
56
57#include <sys/param.h>
58#include <sys/systm.h>
59#include <sys/timeout.h>
60#include <sys/fcntl.h>
61#include <sys/errno.h>
62#include <sys/ioctl.h>
63#include <sys/stat.h>
64#include <sys/pool.h>
65#include <sys/buf.h>
66#include <sys/mtio.h>
67#include <sys/device.h>
68#include <sys/disk.h>
69#include <sys/conf.h>
70#include <sys/vnode.h>
71
72#include <scsi/scsi_all.h>
73#include <scsi/scsi_debug.h>
74#include <scsi/scsi_tape.h>
75#include <scsi/scsiconf.h>
76
77/* Defines for device specific stuff */
78#define DEF_FIXED_BSIZE512 512
79
80#define STMODE(z)( ((unsigned)((z) & 0xff) | (((z) & 0xffff0000) >>
8)) & 0x03)
( minor(z)((unsigned)((z) & 0xff) | (((z) & 0xffff0000) >>
8))
& 0x03)
81#define STUNIT(z)((((unsigned)((z) & 0xff) | (((z) & 0xffff0000) >>
8)) >> 4) )
((minor(z)((unsigned)((z) & 0xff) | (((z) & 0xffff0000) >>
8))
>> 4) )
82
83#define STMINOR(unit, mode)(((unit) << 4) + (mode)) (((unit) << 4) + (mode))
84#define MAXSTMODES16 16 /* Old max retained so minor's don't change. */
85
86#define ST_IO_TIME(3 * 60 * 1000) (3 * 60 * 1000) /* 3 minutes */
87#define ST_CTL_TIME(30 * 1000) (30 * 1000) /* 30 seconds */
88#define ST_SPC_TIME(4 * 60 * 60 * 1000) (4 * 60 * 60 * 1000) /* 4 hours */
89
90/*
91 * Maximum density code allowed in SCSI spec (SSC2R08f, Section 8.3).
92 */
93#define SCSI_MAX_DENSITY_CODE0xff 0xff
94
95/*
96 * Define various devices that we know mis-behave in some way,
97 * and note how they are bad, so we can correct for them
98 */
99struct mode {
100 int blksize;
101 u_int8_t density;
102};
103
104struct quirkdata {
105 u_int quirks;
106#define ST_Q_SENSE_HELP0x0001 0x0001 /* must do READ for good MODE SENSE */
107#define ST_Q_IGNORE_LOADS0x0002 0x0002
108#define ST_Q_UNIMODAL0x0004 0x0004 /* unimode drive rejects mode select */
109 struct mode mode;
110};
111
112struct st_quirk_inquiry_pattern {
113 struct scsi_inquiry_pattern pattern;
114 struct quirkdata quirkdata;
115};
116
117const struct st_quirk_inquiry_pattern st_quirk_patterns[] = {
118 {{T_SEQUENTIAL0x01, T_REMOV1,
119 " ", " ", " "}, {0,
120 {512, 0}}},
121 {{T_SEQUENTIAL0x01, T_REMOV1,
122 "TANDBERG", " TDC 3800 ", ""}, {0,
123 {512, 0}}},
124 {{T_SEQUENTIAL0x01, T_REMOV1,
125 "ARCHIVE ", "VIPER 2525 25462", ""}, {ST_Q_SENSE_HELP0x0001,
126 {0, 0}}},
127 {{T_SEQUENTIAL0x01, T_REMOV1,
128 "SANKYO ", "CP525 ", ""}, {0,
129 {512, 0}}},
130 {{T_SEQUENTIAL0x01, T_REMOV1,
131 "ANRITSU ", "DMT780 ", ""}, {0,
132 {512, 0}}},
133 {{T_SEQUENTIAL0x01, T_REMOV1,
134 "ARCHIVE ", "VIPER 150 21531", ""}, {ST_Q_SENSE_HELP0x0001,
135 {0, 0}}},
136 {{T_SEQUENTIAL0x01, T_REMOV1,
137 "WANGTEK ", "5099ES SCSI", ""}, {0,
138 {512, 0}}},
139 {{T_SEQUENTIAL0x01, T_REMOV1,
140 "WANGTEK ", "5150ES SCSI", ""}, {0,
141 {512, 0}}},
142 {{T_SEQUENTIAL0x01, T_REMOV1,
143 "HP ", "T4000s ", ""}, {ST_Q_UNIMODAL0x0004,
144 {0, QIC_30950x45}}},
145 {{T_SEQUENTIAL0x01, T_REMOV1,
146 "WANGTEK ", "5150ES SCSI FA15", "01 A"}, {ST_Q_IGNORE_LOADS0x0002,
147 {0, 0}}},
148 {{T_SEQUENTIAL0x01, T_REMOV1,
149 "TEAC ", "MT-2ST/N50 ", ""}, {ST_Q_IGNORE_LOADS0x0002,
150 {0, 0}}},
151};
152
153#define NOEJECT0 0
154#define EJECT1 1
155
156#define NOREWIND0 0
157#define DOREWIND1 1
158
159struct st_softc {
160 struct device sc_dev;
161 struct disk sc_dk;
162
163 int flags;
164#define ST_INFO_VALID0x00000001 0x00000001
165#define ST_WRITTEN0x00000004 0x00000004
166#define ST_FIXEDBLOCKS0x00000008 0x00000008
167#define ST_AT_FILEMARK0x00000010 0x00000010
168#define ST_EIO_PENDING0x00000020 0x00000020
169#define ST_EOM_PENDING0x00000040 0x00000040
170#define ST_EOD_DETECTED0x00000080 0x00000080
171#define ST_FM_WRITTEN0x00000100 0x00000100
172#define ST_BLANK_READ0x00000200 0x00000200
173#define ST_2FM_AT_EOD0x00000400 0x00000400
174#define ST_MOUNTED0x00000800 0x00000800
175#define ST_DONTBUFFER0x00001000 0x00001000
176#define ST_DYING0x00004000 0x00004000
177#define ST_BOD_DETECTED0x00008000 0x00008000
178#define ST_MODE_DENSITY0x00010000 0x00010000
179#define ST_MODE_BLKSIZE0x00040000 0x00040000
180
181 u_int quirks; /* quirks for the open mode */
182 int blksize; /* blksize we are using */
183 u_int8_t density; /* present density */
184 short mt_resid; /* last (short) resid */
185 short mt_erreg; /* last error (sense key) seen */
186
187 struct scsi_link *sc_link; /* our link to the adapter etc. */
188
189 int blkmin; /* min blk size */
190 int blkmax; /* max blk size */
191
192 u_int32_t media_blksize; /* 0 if not ST_FIXEDBLOCKS */
193 u_int32_t media_density; /* this is what it said when asked */
194 int media_fileno; /* relative to BOT. -1 means unknown. */
195 int media_blkno; /* relative to BOF. -1 means unknown. */
196 int media_eom; /* relative to BOT. -1 means unknown. */
197
198 struct mode mode;
199 struct bufq sc_bufq;
200 struct scsi_xshandler sc_xsh;
201};
202
203
204int stmatch(struct device *, void *, void *);
205void stattach(struct device *, struct device *, void *);
206int stactivate(struct device *, int);
207int stdetach(struct device *, int);
208void stminphys(struct buf *);
209void ststart(struct scsi_xfer *);
210
211int st_mount_tape(struct st_softc *, int);
212void st_unmount(struct st_softc *, int, int);
213int st_decide_mode(struct st_softc *, int);
214void st_buf_done(struct scsi_xfer *);
215int st_read(struct st_softc *, char *, int, int);
216int st_read_block_limits(struct st_softc *, int);
217int st_mode_sense(struct st_softc *, int);
218int st_mode_select(struct st_softc *, int);
219int st_space(struct st_softc *, int, u_int, int);
220int st_write_filemarks(struct st_softc *, int, int);
221int st_check_eod(struct st_softc *, int, int *, int);
222int st_load(struct st_softc *, u_int, int);
223int st_rewind(struct st_softc *, u_int, int);
224int st_interpret_sense(struct scsi_xfer *);
225int st_touch_tape(struct st_softc *);
226int st_erase(struct st_softc *, int, int);
227
228const struct cfattach st_ca = {
229 sizeof(struct st_softc), stmatch, stattach,
230 stdetach, stactivate
231};
232
233struct cfdriver st_cd = {
234 NULL((void *)0), "st", DV_TAPE
235};
236
237#define ST_PER_ACTION(0x00000010 | 0x00000020 | 0x00000040 | 0x00000200) (ST_AT_FILEMARK0x00000010 | ST_EIO_PENDING0x00000020 | ST_EOM_PENDING0x00000040 | \
238 ST_BLANK_READ0x00000200)
239
240#define stlookup(unit)(struct st_softc *)device_lookup(&st_cd, (unit)) (struct st_softc *)device_lookup(&st_cd, (unit))
241
242const struct scsi_inquiry_pattern st_patterns[] = {
243 {T_SEQUENTIAL0x01, T_REMOV1,
244 "", "", ""},
245};
246
247int
248stmatch(struct device *parent, void *match, void *aux)
249{
250 struct scsi_attach_args *sa = aux;
251 struct scsi_inquiry_data *inq = &sa->sa_sc_link->inqdata;
252 int priority;
253
254 (void)scsi_inqmatch(inq, st_patterns, nitems(st_patterns)(sizeof((st_patterns)) / sizeof((st_patterns)[0])),
255 sizeof(st_patterns[0]), &priority);
256 return priority;
257}
258
259/*
260 * The routine called by the low level scsi routine when it discovers
261 * a device suitable for this driver.
262 */
263void
264stattach(struct device *parent, struct device *self, void *aux)
265{
266 const struct st_quirk_inquiry_pattern *finger;
267 struct st_softc *st = (void *)self;
268 struct scsi_attach_args *sa = aux;
269 struct scsi_link *link = sa->sa_sc_link;
270 int priority;
271
272 SC_DEBUG(link, SDEV_DB2, ("stattach:\n"));
273
274 /*
275 * Store information needed to contact our base driver
276 */
277 st->sc_link = link;
278 link->interpret_sense = st_interpret_sense;
279 link->device_softc = st;
280
281 /* Get any quirks and mode information. */
282 finger = (const struct st_quirk_inquiry_pattern *)scsi_inqmatch(
283 &link->inqdata,
284 st_quirk_patterns,
285 nitems(st_quirk_patterns)(sizeof((st_quirk_patterns)) / sizeof((st_quirk_patterns)[0])
)
,
286 sizeof(st_quirk_patterns[0]), &priority);
287 if (finger != NULL((void *)0)) {
288 st->quirks = finger->quirkdata.quirks;
289 st->mode = finger->quirkdata.mode;
290 CLR(st->flags, ST_MODE_BLKSIZE | ST_MODE_DENSITY)((st->flags) &= ~(0x00040000 | 0x00010000));
291 if (st->mode.blksize != 0)
292 SET(st->flags, ST_MODE_BLKSIZE)((st->flags) |= (0x00040000));
293 if (st->mode.density != 0)
294 SET(st->flags, ST_MODE_DENSITY)((st->flags) |= (0x00010000));
295 }
296 printf("\n");
297
298 scsi_xsh_set(&st->sc_xsh, link, ststart);
299
300 st->sc_dk.dk_name = st->sc_dev.dv_xname;
301
302 /* Set up the buf queue for this device. */
303 bufq_init(&st->sc_bufq, BUFQ_FIFO0);
304
305 /* Start up with media position unknown. */
306 st->media_fileno = -1;
307 st->media_blkno = -1;
308 st->media_eom = -1;
309
310 /*
311 * Reset the media loaded flag, sometimes the data
312 * acquired at boot time is not quite accurate. This
313 * will be checked again at the first open.
314 */
315 CLR(link->flags, SDEV_MEDIA_LOADED)((link->flags) &= ~(0x0002));
316
317 st->sc_dk.dk_flags = DKF_NOLABELREAD0x0004;
318 disk_attach(&st->sc_dev, &st->sc_dk);
319}
320
321int
322stactivate(struct device *self, int act)
323{
324 struct st_softc *st = (struct st_softc *)self;
325
326 switch (act) {
327 case DVACT_DEACTIVATE1:
328 SET(st->flags, ST_DYING)((st->flags) |= (0x00004000));
329 scsi_xsh_del(&st->sc_xsh);
330 break;
331 }
332
333 return 0;
334}
335
336int
337stdetach(struct device *self, int flags)
338{
339 struct st_softc *st = (struct st_softc *)self;
340 int cmaj, mn;
341
342 bufq_drain(&st->sc_bufq);
343
344 /* Locate the lowest minor number to be detached. */
345 mn = STMINOR(self->dv_unit, 0)(((self->dv_unit) << 4) + (0));
346
347 for (cmaj = 0; cmaj < nchrdev; cmaj++)
348 if (cdevsw[cmaj].d_open == stopen)
349 vdevgone(cmaj, mn, mn + MAXSTMODES16 - 1, VCHR);
350
351 bufq_destroy(&st->sc_bufq);
352
353 disk_detach(&st->sc_dk);
354
355 return 0;
356}
357
358/*
359 * open the device.
360 */
361int
362stopen(dev_t dev, int flags, int fmt, struct proc *p)
363{
364 struct scsi_link *link;
365 struct st_softc *st;
366 int error = 0;
367
368 st = stlookup(STUNIT(dev))(struct st_softc *)device_lookup(&st_cd, (((((unsigned)((
dev) & 0xff) | (((dev) & 0xffff0000) >> 8)) >>
4) )))
;
369 if (st == NULL((void *)0))
370 return ENXIO6;
371 if (ISSET(st->flags, ST_DYING)((st->flags) & (0x00004000))) {
372 device_unref(&st->sc_dev);
373 return ENXIO6;
374 }
375 link = st->sc_link;
376
377 if ((error = disk_lock(&st->sc_dk)) != 0) {
378 device_unref(&st->sc_dev);
379 return error;
380 }
381
382 if (ISSET(flags, FWRITE)((flags) & (0x0002)) && ISSET(link->flags, SDEV_READONLY)((link->flags) & (0x0004))) {
383 error = EACCES13;
384 goto done;
385 }
386
387 SC_DEBUG(link, SDEV_DB1, ("open: dev=0x%x (unit %d (of %d))\n", dev,
388 STUNIT(dev), st_cd.cd_ndevs));
389
390 /*
391 * Tape is an exclusive media. Only one open at a time.
392 */
393 if (ISSET(link->flags, SDEV_OPEN)((link->flags) & (0x0008))) {
394 SC_DEBUG(link, SDEV_DB4, ("already open\n"));
395 error = EBUSY16;
396 goto done;
397 }
398
399 /* Use st_interpret_sense() now. */
400 SET(link->flags, SDEV_OPEN)((link->flags) |= (0x0008));
401
402 /*
403 * Check the unit status. This clears any outstanding errors and
404 * will ensure that media is present.
405 */
406 error = scsi_test_unit_ready(link, TEST_READY_RETRIES5,
407 SCSI_SILENT0x00020 | SCSI_IGNORE_MEDIA_CHANGE0x00080 |
408 SCSI_IGNORE_ILLEGAL_REQUEST0x00100);
409
410 /*
411 * Terminate any existing mount session if there is no media.
412 */
413 if (!ISSET(link->flags, SDEV_MEDIA_LOADED)((link->flags) & (0x0002)))
414 st_unmount(st, NOEJECT0, DOREWIND1);
415
416 if (error != 0) {
417 CLR(link->flags, SDEV_OPEN)((link->flags) &= ~(0x0008));
418 goto done;
419 }
420
421 error = st_mount_tape(st, flags);
422 if (error != 0) {
423 CLR(link->flags, SDEV_OPEN)((link->flags) &= ~(0x0008));
424 goto done;
425 }
426
427 /*
428 * Make sure that a tape opened in write-only mode will have
429 * file marks written on it when closed, even if not written to.
430 * This is for SUN compatibility
431 */
432 if ((flags & O_ACCMODE0x0003) == FWRITE0x0002)
433 SET(st->flags, ST_WRITTEN)((st->flags) |= (0x00000004));
434
435done:
436 SC_DEBUG(link, SDEV_DB2, ("open complete\n"));
437 disk_unlock(&st->sc_dk);
438 device_unref(&st->sc_dev);
439 return error;
440}
441
442/*
443 * close the device.. only called if we are the LAST
444 * occurrence of an open device
445 */
446int
447stclose(dev_t dev, int flags, int mode, struct proc *p)
448{
449 struct scsi_link *link;
450 struct st_softc *st;
451 int error = 0;
452
453 st = stlookup(STUNIT(dev))(struct st_softc *)device_lookup(&st_cd, (((((unsigned)((
dev) & 0xff) | (((dev) & 0xffff0000) >> 8)) >>
4) )))
;
454 if (st == NULL((void *)0))
455 return ENXIO6;
456 if (ISSET(st->flags, ST_DYING)((st->flags) & (0x00004000))) {
457 error = ENXIO6;
458 goto done;
459 }
460 link = st->sc_link;
461
462 disk_lock_nointr(&st->sc_dk);
463
464 SC_DEBUG(link, SDEV_DB1, ("closing\n"));
465
466 if (ISSET(st->flags, ST_WRITTEN)((st->flags) & (0x00000004)) && !ISSET(st->flags, ST_FM_WRITTEN)((st->flags) & (0x00000100)))
467 st_write_filemarks(st, 1, 0);
468
469 switch (STMODE(dev)( ((unsigned)((dev) & 0xff) | (((dev) & 0xffff0000) >>
8)) & 0x03)
) {
470 case 0: /* /dev/rstN */
471 st_unmount(st, NOEJECT0, DOREWIND1);
472 break;
473 case 1: /* /dev/nrstN */
474 st_unmount(st, NOEJECT0, NOREWIND0);
475 break;
476 case 2: /* /dev/erstN */
477 st_unmount(st, EJECT1, DOREWIND1);
478 break;
479 case 3: /* /dev/enrstN */
480 st_unmount(st, EJECT1, NOREWIND0);
481 break;
482 }
483 CLR(link->flags, SDEV_OPEN)((link->flags) &= ~(0x0008));
484 scsi_xsh_del(&st->sc_xsh);
485
486 disk_unlock(&st->sc_dk);
487
488done:
489 device_unref(&st->sc_dev);
490 return error;
491}
492
493/*
494 * Start a new mount session if needed.
495 */
496int
497st_mount_tape(struct st_softc *st, int flags)
498{
499 struct scsi_link *link = st->sc_link;
500 int error = 0;
501
502 if (ISSET(st->flags, ST_MOUNTED)((st->flags) & (0x00000800)))
503 return 0;
504
505 SC_DEBUG(link, SDEV_DB1, ("mounting\n"));
506
507 /*
508 * Assume the media is new and give it a chance to
509 * to do a 'load' instruction.
510 */
511 if ((error = st_load(st, LD_LOAD0x01, 0)) != 0)
512 goto done;
513
514 /*
515 * Throw another dummy instruction to catch
516 * 'Unit attention' errors. Some drives appear to give
517 * these after doing a Load instruction.
518 * (notably some DAT drives)
519 */
520 /* XXX */
521 scsi_test_unit_ready(link, TEST_READY_RETRIES5, SCSI_SILENT0x00020);
522
523 /*
524 * Some devices can't tell you much until they have been
525 * asked to look at the media. This quirk does this.
526 */
527 if (ISSET(st->quirks, ST_Q_SENSE_HELP)((st->quirks) & (0x0001)))
528 if ((error = st_touch_tape(st)) != 0)
529 return error;
530 /*
531 * Load the physical device parameters
532 * loads: blkmin, blkmax
533 */
534 if (!ISSET(link->flags, SDEV_ATAPI)((link->flags) & (0x0200)) &&
535 (error = st_read_block_limits(st, 0)) != 0)
536 goto done;
537
538 /*
539 * Load the media dependent parameters
540 * includes: media_blksize,media_density
541 * As we have a tape in, it should be reflected here.
542 * If not you may need the "quirk" above.
543 */
544 if ((error = st_mode_sense(st, 0)) != 0)
545 goto done;
546
547 /*
548 * If we have gained a permanent density from somewhere,
549 * then use it in preference to the one supplied by
550 * default by the driver.
551 */
552 if (ISSET(st->flags, ST_MODE_DENSITY)((st->flags) & (0x00010000)))
553 st->density = st->mode.density;
554 else
555 st->density = st->media_density;
556 /*
557 * If we have gained a permanent blocksize
558 * then use it in preference to the one supplied by
559 * default by the driver.
560 */
561 CLR(st->flags, ST_FIXEDBLOCKS)((st->flags) &= ~(0x00000008));
562 if (ISSET(st->flags, ST_MODE_BLKSIZE)((st->flags) & (0x00040000))) {
563 st->blksize = st->mode.blksize;
564 if (st->blksize)
565 SET(st->flags, ST_FIXEDBLOCKS)((st->flags) |= (0x00000008));
566 } else {
567 if ((error = st_decide_mode(st, 0)) != 0)
568 goto done;
569 }
570 if ((error = st_mode_select(st, 0)) != 0) {
571 printf("%s: cannot set selected mode\n", st->sc_dev.dv_xname);
572 goto done;
573 }
574 scsi_prevent(link, PR_PREVENT0x01,
575 SCSI_IGNORE_ILLEGAL_REQUEST0x00100 | SCSI_IGNORE_NOT_READY0x00040);
576 SET(st->flags, ST_MOUNTED)((st->flags) |= (0x00000800));
577 SET(link->flags, SDEV_MEDIA_LOADED)((link->flags) |= (0x0002)); /* move earlier? */
578 st->media_fileno = 0;
579 st->media_blkno = 0;
580 st->media_eom = -1;
581
582done:
583 return error;
584}
585
586/*
587 * End the present mount session.
588 * Rewind, and optionally eject the tape.
589 * Reset various flags to indicate that all new
590 * operations require another mount operation
591 */
592void
593st_unmount(struct st_softc *st, int eject, int rewind)
594{
595 struct scsi_link *link = st->sc_link;
596 int nmarks;
597
598 if (eject == NOEJECT0 && rewind == NOREWIND0) {
599 if (ISSET(link->flags, SDEV_MEDIA_LOADED)((link->flags) & (0x0002)))
600 return;
601 }
602
603 st->media_fileno = -1;
604 st->media_blkno = -1;
605
606 if (!ISSET(st->flags, ST_MOUNTED)((st->flags) & (0x00000800)))
607 return;
608 SC_DEBUG(link, SDEV_DB1, ("unmounting\n"));
609 st_check_eod(st, 0, &nmarks, SCSI_IGNORE_NOT_READY0x00040);
610 if (rewind == DOREWIND1)
611 st_rewind(st, 0, SCSI_IGNORE_NOT_READY0x00040);
612 scsi_prevent(link, PR_ALLOW0x00,
613 SCSI_IGNORE_ILLEGAL_REQUEST0x00100 | SCSI_IGNORE_NOT_READY0x00040);
614 if (eject == EJECT1)
615 st_load(st, LD_UNLOAD0x00, SCSI_IGNORE_NOT_READY0x00040);
616 CLR(st->flags, ST_MOUNTED)((st->flags) &= ~(0x00000800));
617 CLR(link->flags, SDEV_MEDIA_LOADED)((link->flags) &= ~(0x0002));
618}
619
620/*
621 * Given all we know about the device, media, mode, 'quirks' and
622 * initial operation, make a decision as to how we should be set
623 * to run (regarding blocking and EOD marks)
624 */
625int
626st_decide_mode(struct st_softc *st, int first_read)
627{
628 struct scsi_link *link = st->sc_link;
629
630 SC_DEBUG(link, SDEV_DB2, ("starting block mode decision\n"));
631
632 /* ATAPI tapes are always fixed blocksize. */
633 if (ISSET(link->flags, SDEV_ATAPI)((link->flags) & (0x0200))) {
634 SET(st->flags, ST_FIXEDBLOCKS)((st->flags) |= (0x00000008));
635 if (st->media_blksize > 0)
636 st->blksize = st->media_blksize;
637 else
638 st->blksize = DEF_FIXED_BSIZE512;
639 goto done;
640 }
641
642 /*
643 * If the drive can only handle fixed-length blocks and only at
644 * one size, perhaps we should just do that.
645 */
646 if (st->blkmin && (st->blkmin == st->blkmax)) {
647 SET(st->flags, ST_FIXEDBLOCKS)((st->flags) |= (0x00000008));
648 st->blksize = st->blkmin;
649 SC_DEBUG(link, SDEV_DB3,
650 ("blkmin == blkmax of %d\n", st->blkmin));
651 goto done;
652 }
653 /*
654 * If the tape density mandates (or even suggests) use of fixed
655 * or variable-length blocks, comply.
656 */
657 switch (st->density) {
658 case HALFINCH_8000x01:
659 case HALFINCH_16000x02:
660 case HALFINCH_62500x03:
661 case DDS0x13:
662 CLR(st->flags, ST_FIXEDBLOCKS)((st->flags) &= ~(0x00000008));
663 st->blksize = 0;
664 SC_DEBUG(link, SDEV_DB3, ("density specified variable\n"));
665 goto done;
666 case QIC_110x04:
667 case QIC_240x05:
668 case QIC_1200x0f:
669 case QIC_1500x10:
670 case QIC_5250x11:
671 case QIC_13200x12:
672 SET(st->flags, ST_FIXEDBLOCKS)((st->flags) |= (0x00000008));
673 if (st->media_blksize > 0)
674 st->blksize = st->media_blksize;
675 else
676 st->blksize = DEF_FIXED_BSIZE512;
677 SC_DEBUG(link, SDEV_DB3, ("density specified fixed\n"));
678 goto done;
679 }
680 /*
681 * If we're about to read the tape, perhaps we should choose
682 * fixed or variable-length blocks and block size according to
683 * what the drive found on the tape.
684 */
685 if (first_read) {
686 if (st->media_blksize > 0)
687 SET(st->flags, ST_FIXEDBLOCKS)((st->flags) |= (0x00000008));
688 else
689 CLR(st->flags, ST_FIXEDBLOCKS)((st->flags) &= ~(0x00000008));
690 st->blksize = st->media_blksize;
691 SC_DEBUG(link, SDEV_DB3,
692 ("Used media_blksize of %d\n", st->media_blksize));
693 goto done;
694 }
695 /*
696 * We're getting no hints from any direction. Choose variable-
697 * length blocks arbitrarily.
698 */
699 CLR(st->flags, ST_FIXEDBLOCKS)((st->flags) &= ~(0x00000008));
700 st->blksize = 0;
701 SC_DEBUG(link, SDEV_DB3,
702 ("Give up and default to variable mode\n"));
703
704done:
705 /*
706 * Decide whether or not to write two file marks to signify end-
707 * of-data. Make the decision as a function of density. If
708 * the decision is not to use a second file mark, the SCSI BLANK
709 * CHECK condition code will be recognized as end-of-data when
710 * first read.
711 * (I think this should be a by-product of fixed/variable..julian)
712 */
713 switch (st->density) {
714/* case 8 mm: What is the SCSI density code for 8 mm, anyway? */
715 case QIC_110x04:
716 case QIC_240x05:
717 case QIC_1200x0f:
718 case QIC_1500x10:
719 case QIC_5250x11:
720 case QIC_13200x12:
721 CLR(st->flags, ST_2FM_AT_EOD)((st->flags) &= ~(0x00000400));
722 break;
723 default:
724 SET(st->flags, ST_2FM_AT_EOD)((st->flags) |= (0x00000400));
725 }
726 return 0;
727}
728
729/*
730 * Actually translate the requested transfer into
731 * one the physical driver can understand
732 * The transfer is described by a buf and will include
733 * only one physical transfer.
734 */
735void
736ststrategy(struct buf *bp)
737{
738 struct scsi_link *link;
739 struct st_softc *st;
740 int s;
741
742 st = stlookup(STUNIT(bp->b_dev))(struct st_softc *)device_lookup(&st_cd, (((((unsigned)((
bp->b_dev) & 0xff) | (((bp->b_dev) & 0xffff0000
) >> 8)) >> 4) )))
;
743 if (st == NULL((void *)0)) {
744 bp->b_error = ENXIO6;
745 goto bad;
746 }
747 if (ISSET(st->flags, ST_DYING)((st->flags) & (0x00004000))) {
748 bp->b_error = ENXIO6;
749 goto bad;
750 }
751 link = st->sc_link;
Value stored to 'link' is never read
752
753 SC_DEBUG(link, SDEV_DB2, ("ststrategy: %ld bytes @ blk %lld\n",
754 bp->b_bcount, (long long)bp->b_blkno));
755
756 /*
757 * If it's a null transfer, return immediately.
758 */
759 if (bp->b_bcount == 0)
760 goto done;
761 /*
762 * Odd sized request on fixed drives are verboten
763 */
764 if (ISSET(st->flags, ST_FIXEDBLOCKS)((st->flags) & (0x00000008))) {
765 if (bp->b_bcount % st->blksize) {
766 printf("%s: bad request, must be multiple of %d\n",
767 st->sc_dev.dv_xname, st->blksize);
768 bp->b_error = EIO5;
769 goto bad;
770 }
771 }
772 /*
773 * as are out-of-range requests on variable drives.
774 */
775 else if (bp->b_bcount < st->blkmin ||
776 (st->blkmax && bp->b_bcount > st->blkmax)) {
777 printf("%s: bad request, must be between %d and %d\n",
778 st->sc_dev.dv_xname, st->blkmin, st->blkmax);
779 bp->b_error = EIO5;
780 goto bad;
781 }
782
783 /*
784 * Place it in the queue of activities for this tape
785 * at the end (a bit silly because we only have on user..
786 * (but it could fork()))
787 */
788 bufq_queue(&st->sc_bufq, bp);
789
790 /*
791 * Tell the device to get going on the transfer if it's
792 * not doing anything, otherwise just wait for completion
793 * (All a bit silly if we're only allowing 1 open but..)
794 */
795 scsi_xsh_add(&st->sc_xsh);
796
797 device_unref(&st->sc_dev);
798 return;
799bad:
800 SET(bp->b_flags, B_ERROR)((bp->b_flags) |= (0x00000400));
801done:
802 /* Set b_resid to indicate no xfer was done. */
803 bp->b_resid = bp->b_bcount;
804 s = splbio()splraise(0x3);
805 biodone(bp);
806 splx(s)spllower(s);
807 if (st)
808 device_unref(&st->sc_dev);
809}
810
811void
812ststart(struct scsi_xfer *xs)
813{
814 struct scsi_link *link = xs->sc_link;
815 struct st_softc *st = link->device_softc;
816 struct buf *bp;
817 struct scsi_rw_tape *cmd;
818 int s;
819
820 SC_DEBUG(link, SDEV_DB2, ("ststart\n"));
821
822 if (ISSET(st->flags, ST_DYING)((st->flags) & (0x00004000))) {
823 scsi_xs_put(xs);
824 return;
825 }
826
827 /*
828 * if the device has been unmounted by the user
829 * then throw away all requests until done
830 */
831 if (!ISSET(st->flags, ST_MOUNTED)((st->flags) & (0x00000800)) ||
832 !ISSET(link->flags, SDEV_MEDIA_LOADED)((link->flags) & (0x0002))) {
833 /* make sure that one implies the other.. */
834 CLR(link->flags, SDEV_MEDIA_LOADED)((link->flags) &= ~(0x0002));
835 bufq_drain(&st->sc_bufq);
836 scsi_xs_put(xs);
837 return;
838 }
839
840 for (;;) {
841 bp = bufq_dequeue(&st->sc_bufq);
842 if (bp == NULL((void *)0)) {
843 scsi_xs_put(xs);
844 return;
845 }
846
847 /*
848 * Only FIXEDBLOCK devices have pending I/O or space
849 * operations.
850 */
851 if (ISSET(st->flags, ST_FIXEDBLOCKS)((st->flags) & (0x00000008))) {
852 /*
853 * If we are at a filemark but have not reported it yet
854 * then we should report it now
855 */
856 if (ISSET(st->flags, ST_AT_FILEMARK)((st->flags) & (0x00000010))) {
857 if ((bp->b_flags & B_READ0x00008000) == B_WRITE0x00000000) {
858 /*
859 * Handling of ST_AT_FILEMARK in
860 * st_space will fill in the right file
861 * mark count.
862 * Back up over filemark
863 */
864 if (st_space(st, 0, SP_FILEMARKS0x01, 0)) {
865 SET(bp->b_flags, B_ERROR)((bp->b_flags) |= (0x00000400));
866 bp->b_resid = bp->b_bcount;
867 bp->b_error = EIO5;
868 s = splbio()splraise(0x3);
869 biodone(bp);
870 splx(s)spllower(s);
871 continue;
872 }
873 } else {
874 bp->b_resid = bp->b_bcount;
875 bp->b_error = 0;
876 CLR(bp->b_flags, B_ERROR)((bp->b_flags) &= ~(0x00000400));
877 CLR(st->flags, ST_AT_FILEMARK)((st->flags) &= ~(0x00000010));
878 s = splbio()splraise(0x3);
879 biodone(bp);
880 splx(s)spllower(s);
881 continue; /* seek more work */
882 }
883 }
884 }
885
886 /*
887 * If we are at EIO or EOM but have not reported it
888 * yet then we should report it now.
889 */
890 if (ISSET(st->flags, ST_EOM_PENDING | ST_EIO_PENDING)((st->flags) & (0x00000040 | 0x00000020))) {
891 bp->b_resid = bp->b_bcount;
892 if (ISSET(st->flags, ST_EIO_PENDING)((st->flags) & (0x00000020))) {
893 bp->b_error = EIO5;
894 SET(bp->b_flags, B_ERROR)((bp->b_flags) |= (0x00000400));
895 }
896 CLR(st->flags, ST_EOM_PENDING | ST_EIO_PENDING)((st->flags) &= ~(0x00000040 | 0x00000020));
897 s = splbio()splraise(0x3);
898 biodone(bp);
899 splx(s)spllower(s);
900 continue; /* seek more work */
901 }
902 break;
903 }
904
905 /*
906 * Fill out the scsi command
907 */
908 cmd = (struct scsi_rw_tape *)&xs->cmd;
909 bzero(cmd, sizeof(*cmd))__builtin_bzero((cmd), (sizeof(*cmd)));
910 if ((bp->b_flags & B_READ0x00008000) == B_WRITE0x00000000) {
911 cmd->opcode = WRITE0x0a;
912 CLR(st->flags, ST_FM_WRITTEN)((st->flags) &= ~(0x00000100));
913 SET(st->flags, ST_WRITTEN)((st->flags) |= (0x00000004));
914 SET(xs->flags, SCSI_DATA_OUT)((xs->flags) |= (0x01000));
915 } else {
916 cmd->opcode = READ0x08;
917 SET(xs->flags, SCSI_DATA_IN)((xs->flags) |= (0x00800));
918 }
919
920 /*
921 * Handle "fixed-block-mode" tape drives by using the
922 * block count instead of the length.
923 */
924 if (ISSET(st->flags, ST_FIXEDBLOCKS)((st->flags) & (0x00000008))) {
925 SET(cmd->byte2, SRW_FIXED)((cmd->byte2) |= (0x01));
926 _lto3b(bp->b_bcount / st->blksize, cmd->len);
927 } else
928 _lto3b(bp->b_bcount, cmd->len);
929
930 if (st->media_blkno != -1) {
931 /* Update block count now, errors will set it to -1. */
932 if (ISSET(st->flags, ST_FIXEDBLOCKS)((st->flags) & (0x00000008)))
933 st->media_blkno += _3btol(cmd->len);
934 else if (_3btol(cmd->len) != 0)
935 st->media_blkno++;
936 }
937
938 xs->cmdlen = sizeof(*cmd);
939 xs->timeout = ST_IO_TIME(3 * 60 * 1000);
940 xs->data = bp->b_data;
941 xs->datalen = bp->b_bcount;
942 xs->done = st_buf_done;
943 xs->cookie = bp;
944 xs->bp = bp;
945
946 /* Instrumentation. */
947 disk_busy(&st->sc_dk);
948
949 /*
950 * go ask the adapter to do all this for us
951 */
952 scsi_xs_exec(xs);
953
954 /*
955 * should we try do more work now?
956 */
957 if (bufq_peek(&st->sc_bufq))
958 scsi_xsh_add(&st->sc_xsh);
959}
960
961void
962st_buf_done(struct scsi_xfer *xs)
963{
964 struct st_softc *st = xs->sc_link->device_softc;
965 struct buf *bp = xs->cookie;
966 int error, s;
967
968 switch (xs->error) {
969 case XS_NOERROR0:
970 bp->b_error = 0;
971 CLR(bp->b_flags, B_ERROR)((bp->b_flags) &= ~(0x00000400));
972 bp->b_resid = xs->resid;
973 break;
974
975 case XS_SENSE1:
976 case XS_SHORTSENSE6:
977 SC_DEBUG_SENSE(xs);
978 error = st_interpret_sense(xs);
979 if (error == 0) {
980 bp->b_error = 0;
981 CLR(bp->b_flags, B_ERROR)((bp->b_flags) &= ~(0x00000400));
982 bp->b_resid = xs->resid;
983 break;
984 }
985 if (error != ERESTART-1)
986 xs->retries = 0;
987 goto retry;
988
989 case XS_BUSY5:
990 if (xs->retries) {
991 if (scsi_delay(xs, 1) != ERESTART-1)
992 xs->retries = 0;
993 }
994 goto retry;
995
996 case XS_TIMEOUT4:
997 retry:
998 if (xs->retries--) {
999 scsi_xs_exec(xs);
1000 return;
1001 }
1002 /* FALLTHROUGH */
1003
1004 default:
1005 bp->b_error = EIO5;
1006 SET(bp->b_flags, B_ERROR)((bp->b_flags) |= (0x00000400));
1007 bp->b_resid = bp->b_bcount;
1008 break;
1009 }
1010
1011 disk_unbusy(&st->sc_dk, bp->b_bcount - xs->resid, bp->b_blkno,
1012 bp->b_flags & B_READ0x00008000);
1013
1014 s = splbio()splraise(0x3);
1015 biodone(bp);
1016 splx(s)spllower(s);
1017 scsi_xs_put(xs);
1018}
1019
1020void
1021stminphys(struct buf *bp)
1022{
1023 struct scsi_link *link;
1024 struct st_softc *sc;
1025
1026 sc = stlookup(STUNIT(bp->b_dev))(struct st_softc *)device_lookup(&st_cd, (((((unsigned)((
bp->b_dev) & 0xff) | (((bp->b_dev) & 0xffff0000
) >> 8)) >> 4) )))
;
1027 if (sc == NULL((void *)0))
1028 return;
1029 link = sc->sc_link;
1030
1031 if (link->bus->sb_adapter->dev_minphys != NULL((void *)0))
1032 (*link->bus->sb_adapter->dev_minphys)(bp, link);
1033 else
1034 minphys(bp);
1035
1036 device_unref(&sc->sc_dev);
1037}
1038
1039int
1040stread(dev_t dev, struct uio *uio, int iomode)
1041{
1042 return physio(ststrategy, dev, B_READ0x00008000, stminphys, uio);
1043}
1044
1045int
1046stwrite(dev_t dev, struct uio *uio, int iomode)
1047{
1048 return physio(ststrategy, dev, B_WRITE0x00000000, stminphys, uio);
1049}
1050
1051/*
1052 * Perform special action on behalf of the user;
1053 * knows about the internals of this device
1054 */
1055int
1056stioctl(dev_t dev, u_long cmd, caddr_t arg, int flag, struct proc *p)
1057{
1058 int error = 0;
1059 int nmarks;
1060 int flags = 0;
1061 struct st_softc *st;
1062 int hold_blksize;
1063 u_int8_t hold_density;
1064 struct mtop *mt = (struct mtop *) arg;
1065 int number;
1066
1067 /*
1068 * Find the device that the user is talking about
1069 */
1070 st = stlookup(STUNIT(dev))(struct st_softc *)device_lookup(&st_cd, (((((unsigned)((
dev) & 0xff) | (((dev) & 0xffff0000) >> 8)) >>
4) )))
;
1071 if (st == NULL((void *)0))
1072 return ENXIO6;
1073
1074 if (ISSET(st->flags, ST_DYING)((st->flags) & (0x00004000))) {
1075 error = ENXIO6;
1076 goto done;
1077 }
1078
1079 hold_blksize = st->blksize;
1080 hold_density = st->density;
1081
1082 switch (cmd) {
1083
1084 case MTIOCGET((unsigned long)0x40000000 | ((sizeof(struct mtget) & 0x1fff
) << 16) | ((('m')) << 8) | ((2)))
: {
1085 struct mtget *g = (struct mtget *) arg;
1086
1087 /*
1088 * (to get the current state of READONLY)
1089 */
1090 error = st_mode_sense(st, SCSI_SILENT0x00020);
1091 if (error != 0)
1092 break;
1093
1094 SC_DEBUG(st->sc_link, SDEV_DB1, ("[ioctl: get status]\n"));
1095 bzero(g, sizeof(struct mtget))__builtin_bzero((g), (sizeof(struct mtget)));
1096 g->mt_type = 0x7; /* Ultrix compat *//*? */
1097 g->mt_blksiz = st->blksize;
1098 g->mt_density = st->density;
1099 g->mt_mblksiz = st->mode.blksize;
1100 g->mt_mdensity = st->mode.density;
1101 if (ISSET(st->sc_link->flags, SDEV_READONLY)((st->sc_link->flags) & (0x0004)))
1102 SET(g->mt_dsreg, MT_DS_RDONLY)((g->mt_dsreg) |= (0x10));
1103 if (ISSET(st->flags, ST_MOUNTED)((st->flags) & (0x00000800)))
1104 SET(g->mt_dsreg, MT_DS_MOUNTED)((g->mt_dsreg) |= (0x03));
1105 g->mt_resid = st->mt_resid;
1106 g->mt_erreg = st->mt_erreg;
1107 g->mt_fileno = st->media_fileno;
1108 g->mt_blkno = st->media_blkno;
1109 /*
1110 * clear latched errors.
1111 */
1112 st->mt_resid = 0;
1113 st->mt_erreg = 0;
1114 break;
1115 }
1116 case MTIOCTOP((unsigned long)0x80000000 | ((sizeof(struct mtop) & 0x1fff
) << 16) | ((('m')) << 8) | ((1)))
: {
1117
1118 SC_DEBUG(st->sc_link, SDEV_DB1,
1119 ("[ioctl: op=0x%x count=0x%x]\n", mt->mt_op, mt->mt_count));
1120
1121 number = mt->mt_count;
1122 switch (mt->mt_op) {
1123 case MTWEOF0: /* write an end-of-file record */
1124 error = st_write_filemarks(st, number, flags);
1125 break;
1126 case MTBSF2: /* backward space file */
1127 number = -number;
1128 case MTFSF1: /* forward space file */
1129 error = st_check_eod(st, 0, &nmarks, flags);
1130 if (error == 0)
1131 error = st_space(st, number - nmarks,
1132 SP_FILEMARKS0x01, flags);
1133 break;
1134 case MTBSR4: /* backward space record */
1135 number = -number;
1136 case MTFSR3: /* forward space record */
1137 error = st_check_eod(st, 1, &nmarks, flags);
1138 if (error == 0)
1139 error = st_space(st, number, SP_BLKS0x00, flags);
1140 break;
1141 case MTREW5: /* rewind */
1142 error = st_rewind(st, 0, flags);
1143 break;
1144 case MTOFFL6: /* rewind and put the drive offline */
1145 st_unmount(st, EJECT1, DOREWIND1);
1146 break;
1147 case MTNOP7: /* no operation, sets status only */
1148 break;
1149 case MTRETEN8: /* retension the tape */
1150 error = st_load(st, LD_RETENSION0x02, flags);
1151 if (error == 0)
1152 error = st_load(st, LD_LOAD0x01, flags);
1153 break;
1154 case MTEOM10: /* forward space to end of media */
1155 error = st_check_eod(st, 0, &nmarks, flags);
1156 if (error == 0)
1157 error = st_space(st, 1, SP_EOM0x03, flags);
1158 break;
1159 case MTCACHE12: /* enable controller cache */
1160 CLR(st->flags, ST_DONTBUFFER)((st->flags) &= ~(0x00001000));
1161 goto try_new_value;
1162 case MTNOCACHE13: /* disable controller cache */
1163 SET(st->flags, ST_DONTBUFFER)((st->flags) |= (0x00001000));
1164 goto try_new_value;
1165 case MTERASE9: /* erase volume */
1166 error = st_erase(st, number, flags);
1167 break;
1168 case MTSETBSIZ14: /* Set block size for device and mode. */
1169 if (number == 0) {
1170 CLR(st->flags, ST_FIXEDBLOCKS)((st->flags) &= ~(0x00000008));
1171 } else {
1172 if ((st->blkmin || st->blkmax) &&
1173 (number < st->blkmin ||
1174 number > st->blkmax)) {
1175 error = EINVAL22;
1176 break;
1177 }
1178 SET(st->flags, ST_FIXEDBLOCKS)((st->flags) |= (0x00000008));
1179 }
1180 st->blksize = number;
1181 goto try_new_value;
1182
1183 case MTSETDNSTY15: /* Set density for device and mode. */
1184 if (number < 0 || number > SCSI_MAX_DENSITY_CODE0xff) {
1185 error = EINVAL22;
1186 break;
1187 }
1188 st->density = number;
1189 goto try_new_value;
1190
1191 default:
1192 error = EINVAL22;
1193 }
1194 break;
1195 }
1196 case MTIOCIEOT((unsigned long)0x20000000 | ((0 & 0x1fff) << 16) |
((('m')) << 8) | ((3)))
:
1197 case MTIOCEEOT((unsigned long)0x20000000 | ((0 & 0x1fff) << 16) |
((('m')) << 8) | ((4)))
:
1198 break;
1199
1200#if 0
1201 case MTIOCRDSPOS((unsigned long)0x40000000 | ((sizeof(u_int32_t) & 0x1fff
) << 16) | ((('m')) << 8) | ((5)))
:
1202 error = st_rdpos(st, 0, (u_int32_t *) arg);
1203 break;
1204
1205 case MTIOCRDHPOS((unsigned long)0x40000000 | ((sizeof(u_int32_t) & 0x1fff
) << 16) | ((('m')) << 8) | ((6)))
:
1206 error = st_rdpos(st, 1, (u_int32_t *) arg);
1207 break;
1208
1209 case MTIOCSLOCATE((unsigned long)0x80000000 | ((sizeof(u_int32_t) & 0x1fff
) << 16) | ((('m')) << 8) | ((5)))
:
1210 error = st_setpos(st, 0, (u_int32_t *) arg);
1211 break;
1212
1213 case MTIOCHLOCATE((unsigned long)0x80000000 | ((sizeof(u_int32_t) & 0x1fff
) << 16) | ((('m')) << 8) | ((6)))
:
1214 error = st_setpos(st, 1, (u_int32_t *) arg);
1215 break;
1216#endif /* 0 */
1217
1218 default:
1219 error = scsi_do_ioctl(st->sc_link, cmd, arg, flag);
1220 break;
1221 }
1222 goto done;
1223
1224try_new_value:
1225 /*
1226 * Check that the mode being asked for is aggreeable to the
1227 * drive. If not, put it back the way it was.
1228 */
1229 if ((error = st_mode_select(st, 0)) != 0) {/* put it back as it was */
1230 printf("%s: cannot set selected mode\n", st->sc_dev.dv_xname);
1231 st->density = hold_density;
1232 st->blksize = hold_blksize;
1233 if (st->blksize)
1234 SET(st->flags, ST_FIXEDBLOCKS)((st->flags) |= (0x00000008));
1235 else
1236 CLR(st->flags, ST_FIXEDBLOCKS)((st->flags) &= ~(0x00000008));
1237 goto done;
1238 }
1239 /*
1240 * As the drive liked it, if we are setting a new default,
1241 * set it into the structures as such.
1242 */
1243 switch (mt->mt_op) {
1244 case MTSETBSIZ14:
1245 st->mode.blksize = st->blksize;
1246 SET(st->flags, ST_MODE_BLKSIZE)((st->flags) |= (0x00040000));
1247 break;
1248 case MTSETDNSTY15:
1249 st->mode.density = st->density;
1250 SET(st->flags, ST_MODE_DENSITY)((st->flags) |= (0x00010000));
1251 break;
1252 }
1253
1254done:
1255 device_unref(&st->sc_dev);
1256 return error;
1257}
1258
1259/*
1260 * Do a synchronous read.
1261 */
1262int
1263st_read(struct st_softc *st, char *buf, int size, int flags)
1264{
1265 struct scsi_rw_tape *cmd;
1266 struct scsi_xfer *xs;
1267 int error;
1268
1269 if (size == 0)
1270 return 0;
1271
1272 xs = scsi_xs_get(st->sc_link, flags | SCSI_DATA_IN0x00800);
1273 if (xs == NULL((void *)0))
1274 return ENOMEM12;
1275 xs->cmdlen = sizeof(*cmd);
1276 xs->data = buf;
1277 xs->datalen = size;
1278 xs->retries = 0;
1279 xs->timeout = ST_IO_TIME(3 * 60 * 1000);
1280
1281 cmd = (struct scsi_rw_tape *)&xs->cmd;
1282 cmd->opcode = READ0x08;
1283 if (ISSET(st->flags, ST_FIXEDBLOCKS)((st->flags) & (0x00000008))) {
1284 SET(cmd->byte2, SRW_FIXED)((cmd->byte2) |= (0x01));
1285 _lto3b(size / (st->blksize ? st->blksize : DEF_FIXED_BSIZE512),
1286 cmd->len);
1287 } else
1288 _lto3b(size, cmd->len);
1289
1290 error = scsi_xs_sync(xs);
1291 scsi_xs_put(xs);
1292
1293 return error;
1294}
1295
1296/*
1297 * Ask the drive what its min and max blk sizes are.
1298 */
1299int
1300st_read_block_limits(struct st_softc *st, int flags)
1301{
1302 struct scsi_block_limits_data *block_limits = NULL((void *)0);
1303 struct scsi_block_limits *cmd;
1304 struct scsi_link *link = st->sc_link;
1305 struct scsi_xfer *xs;
1306 int error = 0;
1307
1308 if (ISSET(link->flags, SDEV_MEDIA_LOADED)((link->flags) & (0x0002)))
1309 return 0;
1310
1311 block_limits = dma_alloc(sizeof(*block_limits), PR_NOWAIT0x0002);
1312 if (block_limits == NULL((void *)0))
1313 return ENOMEM12;
1314
1315 xs = scsi_xs_get(link, flags | SCSI_DATA_IN0x00800);
1316 if (xs == NULL((void *)0)) {
1317 error = ENOMEM12;
1318 goto done;
1319 }
1320
1321 xs->cmdlen = sizeof(*cmd);
1322 xs->data = (void *)block_limits;
1323 xs->datalen = sizeof(*block_limits);
1324 xs->timeout = ST_CTL_TIME(30 * 1000);
1325
1326 cmd = (struct scsi_block_limits *)&xs->cmd;
1327 cmd->opcode = READ_BLOCK_LIMITS0x05;
1328
1329 error = scsi_xs_sync(xs);
1330 scsi_xs_put(xs);
1331
1332 if (error == 0) {
1333 st->blkmin = _2btol(block_limits->min_length);
1334 st->blkmax = _3btol(block_limits->max_length);
1335 SC_DEBUG(link, SDEV_DB3,
1336 ("(%d <= blksize <= %d)\n", st->blkmin, st->blkmax));
1337 }
1338
1339done:
1340 if (block_limits)
1341 dma_free(block_limits, sizeof(*block_limits));
1342 return error;
1343}
1344
1345/*
1346 * Get the scsi driver to send a full inquiry to the
1347 * device and use the results to fill out the global
1348 * parameter structure.
1349 *
1350 * called from:
1351 * attach
1352 * open
1353 * ioctl (to reset original blksize)
1354 */
1355int
1356st_mode_sense(struct st_softc *st, int flags)
1357{
1358 union scsi_mode_sense_buf *data = NULL((void *)0);
1359 struct scsi_link *link = st->sc_link;
1360 u_int64_t block_count;
1361 u_int32_t density, block_size;
1362 u_char *page0 = NULL((void *)0);
1363 u_int8_t dev_spec;
1364 int error = 0, big;
1365
1366 data = dma_alloc(sizeof(*data), PR_NOWAIT0x0002);
1367 if (data == NULL((void *)0))
1368 return ENOMEM12;
1369
1370 /*
1371 * Ask for page 0 (vendor specific) mode sense data.
1372 */
1373 density = 0;
1374 block_count = 0;
1375 block_size = 0;
1376 error = scsi_do_mode_sense(link, 0, data, (void **)&page0, 1,
1377 flags | SCSI_SILENT0x00020, &big);
1378 if (error != 0)
1379 goto done;
1380 scsi_parse_blkdesc(link, data, big, &density, &block_count,
1381 &block_size);
1382
1383 /* It is valid for no page0 to be available. */
1384
1385 if (big)
1386 dev_spec = data->hdr_big.dev_spec;
1387 else
1388 dev_spec = data->hdr.dev_spec;
1389
1390 if (ISSET(dev_spec, SMH_DSP_WRITE_PROT)((dev_spec) & (0x80)))
1391 SET(link->flags, SDEV_READONLY)((link->flags) |= (0x0004));
1392 else
1393 CLR(link->flags, SDEV_READONLY)((link->flags) &= ~(0x0004));
1394
1395 st->media_blksize = block_size;
1396 st->media_density = density;
1397
1398 SC_DEBUG(link, SDEV_DB3,
1399 ("density code 0x%x, %d-byte blocks, write-%s, %sbuffered\n",
1400 st->media_density, st->media_blksize,
1401 ISSET(link->flags, SDEV_READONLY) ? "protected" : "enabled",
1402 ISSET(dev_spec, SMH_DSP_BUFF_MODE) ? "" : "un"));
1403
1404 SET(link->flags, SDEV_MEDIA_LOADED)((link->flags) |= (0x0002));
1405
1406 done:
1407 if (data)
1408 dma_free(data, sizeof(*data));
1409 return error;
1410}
1411
1412/*
1413 * Send a filled out parameter structure to the drive to
1414 * set it into the desire mode etc.
1415 */
1416int
1417st_mode_select(struct st_softc *st, int flags)
1418{
1419 union scsi_mode_sense_buf *inbuf = NULL((void *)0), *outbuf = NULL((void *)0);
1420 struct scsi_blk_desc general;
1421 struct scsi_link *link = st->sc_link;
1422 u_int8_t *page0 = NULL((void *)0);
1423 int error = 0, big, page0_size;
1424
1425 inbuf = dma_alloc(sizeof(*inbuf), PR_NOWAIT0x0002);
1426 if (inbuf == NULL((void *)0)) {
1427 error = ENOMEM12;
1428 goto done;
1429 }
1430 outbuf = dma_alloc(sizeof(*outbuf), PR_NOWAIT0x0002 | PR_ZERO0x0008);
1431 if (outbuf == NULL((void *)0)) {
1432 error = ENOMEM12;
1433 goto done;
1434 }
1435
1436 /*
1437 * This quirk deals with drives that have only one valid mode and think
1438 * this gives them license to reject all mode selects, even if the
1439 * selected mode is the one that is supported.
1440 */
1441 if (ISSET(st->quirks, ST_Q_UNIMODAL)((st->quirks) & (0x0004))) {
1442 SC_DEBUG(link, SDEV_DB3,
1443 ("not setting density 0x%x blksize 0x%x\n",
1444 st->density, st->blksize));
1445 error = 0;
1446 goto done;
1447 }
1448
1449 if (ISSET(link->flags, SDEV_ATAPI)((link->flags) & (0x0200))) {
1450 error = 0;
1451 goto done;
1452 }
1453
1454 bzero(&general, sizeof(general))__builtin_bzero((&general), (sizeof(general)));
1455
1456 general.density = st->density;
1457 if (ISSET(st->flags, ST_FIXEDBLOCKS)((st->flags) & (0x00000008)))
1458 _lto3b(st->blksize, general.blklen);
1459
1460 /*
1461 * Ask for page 0 (vendor specific) mode sense data.
1462 *
1463 * page0 == NULL is a valid situation.
1464 */
1465 error = scsi_do_mode_sense(link, 0, inbuf, (void **)&page0, 1,
1466 flags | SCSI_SILENT0x00020, &big);
1467 if (error != 0)
1468 goto done;
1469
1470 if (page0 == NULL((void *)0)) {
1471 page0_size = 0;
1472 } else if (big == 0) {
1473 page0_size = inbuf->hdr.data_length +
1474 sizeof(inbuf->hdr.data_length) - sizeof(inbuf->hdr) -
1475 inbuf->hdr.blk_desc_len;
1476 memcpy(&outbuf->buf[sizeof(outbuf->hdr)+ sizeof(general)],__builtin_memcpy((&outbuf->buf[sizeof(outbuf->hdr)+
sizeof(general)]), (page0), (page0_size))
1477 page0, page0_size)__builtin_memcpy((&outbuf->buf[sizeof(outbuf->hdr)+
sizeof(general)]), (page0), (page0_size))
;
1478 } else {
1479 page0_size = _2btol(inbuf->hdr_big.data_length) +
1480 sizeof(inbuf->hdr_big.data_length) -
1481 sizeof(inbuf->hdr_big) -
1482 _2btol(inbuf->hdr_big.blk_desc_len);
1483 memcpy(&outbuf->buf[sizeof(outbuf->hdr_big) + sizeof(general)],__builtin_memcpy((&outbuf->buf[sizeof(outbuf->hdr_big
) + sizeof(general)]), (page0), (page0_size))
1484 page0, page0_size)__builtin_memcpy((&outbuf->buf[sizeof(outbuf->hdr_big
) + sizeof(general)]), (page0), (page0_size))
;
1485 }
1486
1487 /*
1488 * Set up for a mode select.
1489 */
1490 if (big == 0) {
1491 outbuf->hdr.data_length = sizeof(outbuf->hdr) +
1492 sizeof(general) + page0_size -
1493 sizeof(outbuf->hdr.data_length);
1494 if (!ISSET(st->flags, ST_DONTBUFFER)((st->flags) & (0x00001000)))
1495 outbuf->hdr.dev_spec = SMH_DSP_BUFF_MODE_ON0x10;
1496 outbuf->hdr.blk_desc_len = sizeof(general);
1497 memcpy(&outbuf->buf[sizeof(outbuf->hdr)],__builtin_memcpy((&outbuf->buf[sizeof(outbuf->hdr)]
), (&general), (sizeof(general)))
1498 &general, sizeof(general))__builtin_memcpy((&outbuf->buf[sizeof(outbuf->hdr)]
), (&general), (sizeof(general)))
;
1499 error = scsi_mode_select(st->sc_link, 0, &outbuf->hdr,
1500 flags, ST_CTL_TIME(30 * 1000));
1501 goto done;
1502 }
1503
1504 /* MODE SENSE (10) header was returned, so use MODE SELECT (10). */
1505 _lto2b((sizeof(outbuf->hdr_big) + sizeof(general) + page0_size -
1506 sizeof(outbuf->hdr_big.data_length)), outbuf->hdr_big.data_length);
1507 if (!ISSET(st->flags, ST_DONTBUFFER)((st->flags) & (0x00001000)))
1508 outbuf->hdr_big.dev_spec = SMH_DSP_BUFF_MODE_ON0x10;
1509 _lto2b(sizeof(general), outbuf->hdr_big.blk_desc_len);
1510 memcpy(&outbuf->buf[sizeof(outbuf->hdr_big)], &general,__builtin_memcpy((&outbuf->buf[sizeof(outbuf->hdr_big
)]), (&general), (sizeof(general)))
1511 sizeof(general))__builtin_memcpy((&outbuf->buf[sizeof(outbuf->hdr_big
)]), (&general), (sizeof(general)))
;
1512
1513 error = scsi_mode_select_big(st->sc_link, 0, &outbuf->hdr_big,
1514 flags, ST_CTL_TIME(30 * 1000));
1515done:
1516 if (inbuf)
1517 dma_free(inbuf, sizeof(*inbuf));
1518 if (outbuf)
1519 dma_free(outbuf, sizeof(*outbuf));
1520 return error;
1521}
1522
1523/*
1524 * issue an erase command
1525 */
1526int
1527st_erase(struct st_softc *st, int full, int flags)
1528{
1529 struct scsi_erase *cmd;
1530 struct scsi_xfer *xs;
1531 int error;
1532
1533 xs = scsi_xs_get(st->sc_link, flags);
1534 if (xs == NULL((void *)0))
1535 return ENOMEM12;
1536 xs->cmdlen = sizeof(*cmd);
1537
1538 /*
1539 * Full erase means set LONG bit in erase command, which asks
1540 * the drive to erase the entire unit. Without this bit, we're
1541 * asking the drive to write an erase gap.
1542 */
1543 cmd = (struct scsi_erase *)&xs->cmd;
1544 cmd->opcode = ERASE0x19;
1545 if (full) {
1546 cmd->byte2 = SE_IMMED0x02|SE_LONG0x01;
1547 xs->timeout = ST_SPC_TIME(4 * 60 * 60 * 1000);
1548 } else {
1549 cmd->byte2 = SE_IMMED0x02;
1550 xs->timeout = ST_IO_TIME(3 * 60 * 1000);
1551 }
1552
1553 /*
1554 * XXX We always do this asynchronously, for now. How long should
1555 * we wait if we want to (eventually) to it synchronously?
1556 */
1557 error = scsi_xs_sync(xs);
1558 scsi_xs_put(xs);
1559
1560 return error;
1561}
1562
1563/*
1564 * skip N blocks/filemarks/seq filemarks/eom
1565 */
1566int
1567st_space(struct st_softc *st, int number, u_int what, int flags)
1568{
1569 struct scsi_space *cmd;
1570 struct scsi_xfer *xs;
1571 int error;
1572
1573 switch (what) {
1574 case SP_BLKS0x00:
1575 if (ISSET(st->flags, ST_PER_ACTION)((st->flags) & ((0x00000010 | 0x00000020 | 0x00000040 |
0x00000200)))
) {
1576 if (number > 0) {
1577 CLR(st->flags, ST_PER_ACTION)((st->flags) &= ~((0x00000010 | 0x00000020 | 0x00000040
| 0x00000200)))
;
1578 return EIO5;
1579 } else if (number < 0) {
1580 if (ISSET(st->flags, ST_AT_FILEMARK)((st->flags) & (0x00000010))) {
1581 /*
1582 * Handling of ST_AT_FILEMARK
1583 * in st_space will fill in the
1584 * right file mark count.
1585 */
1586 error = st_space(st, 0, SP_FILEMARKS0x01,
1587 flags);
1588 if (error != 0)
1589 return error;
1590 }
1591 if (ISSET(st->flags, ST_BLANK_READ)((st->flags) & (0x00000200))) {
1592 CLR(st->flags, ST_BLANK_READ)((st->flags) &= ~(0x00000200));
1593 return EIO5;
1594 }
1595 CLR(st->flags, ST_EIO_PENDING | ST_EOM_PENDING)((st->flags) &= ~(0x00000020 | 0x00000040));
1596 }
1597 }
1598 break;
1599 case SP_FILEMARKS0x01:
1600 if (ISSET(st->flags, ST_EIO_PENDING)((st->flags) & (0x00000020))) {
1601 if (number > 0) {
1602 /* pretend we just discovered the error */
1603 CLR(st->flags, ST_EIO_PENDING)((st->flags) &= ~(0x00000020));
1604 return EIO5;
1605 } else if (number < 0) {
1606 /* back away from the error */
1607 CLR(st->flags, ST_EIO_PENDING)((st->flags) &= ~(0x00000020));
1608 }
1609 }
1610 if (ISSET(st->flags, ST_AT_FILEMARK)((st->flags) & (0x00000010))) {
1611 CLR(st->flags, ST_AT_FILEMARK)((st->flags) &= ~(0x00000010));
1612 number--;
1613 }
1614 if (ISSET(st->flags, ST_BLANK_READ)((st->flags) & (0x00000200)) && (number < 0)) {
1615 /* back away from unwritten tape */
1616 CLR(st->flags, ST_BLANK_READ)((st->flags) &= ~(0x00000200));
1617 number++; /* XXX dubious */
1618 }
1619 break;
1620 case SP_EOM0x03:
1621 if (ISSET(st->flags, ST_EOM_PENDING)((st->flags) & (0x00000040))) {
1622 /* We are already there. */
1623 CLR(st->flags, ST_EOM_PENDING)((st->flags) &= ~(0x00000040));
1624 return 0;
1625 }
1626 if (ISSET(st->flags, ST_EIO_PENDING)((st->flags) & (0x00000020))) {
1627 /* pretend we just discovered the error */
1628 CLR(st->flags, ST_EIO_PENDING)((st->flags) &= ~(0x00000020));
1629 return EIO5;
1630 }
1631 if (ISSET(st->flags, ST_AT_FILEMARK)((st->flags) & (0x00000010)))
1632 CLR(st->flags, ST_AT_FILEMARK)((st->flags) &= ~(0x00000010));
1633 break;
1634 }
1635 if (number == 0)
1636 return 0;
1637
1638 xs = scsi_xs_get(st->sc_link, flags);
1639 if (xs == NULL((void *)0))
1640 return ENOMEM12;
1641
1642 cmd = (struct scsi_space *)&xs->cmd;
1643 cmd->opcode = SPACE0x11;
1644 cmd->byte2 = what;
1645 _lto3b(number, cmd->number);
1646 xs->cmdlen = sizeof(*cmd);
1647 xs->timeout = ST_SPC_TIME(4 * 60 * 60 * 1000);
1648
1649 CLR(st->flags, ST_EOD_DETECTED)((st->flags) &= ~(0x00000080));
1650
1651 error = scsi_xs_sync(xs);
1652 scsi_xs_put(xs);
1653
1654 if (error != 0) {
1655 st->media_fileno = -1;
1656 st->media_blkno = -1;
1657 } else {
1658 switch (what) {
1659 case SP_BLKS0x00:
1660 if (st->media_blkno != -1) {
1661 st->media_blkno += number;
1662 if (st->media_blkno < 0)
1663 st->media_blkno = -1;
1664 }
1665 break;
1666 case SP_FILEMARKS0x01:
1667 if (st->media_fileno != -1) {
1668 if (!ISSET(st->flags, ST_EOD_DETECTED)((st->flags) & (0x00000080)))
1669 st->media_fileno += number;
1670 if (st->media_fileno > st->media_eom)
1671 st->media_eom = st->media_fileno;
1672 st->media_blkno = 0;
1673 }
1674 break;
1675 case SP_EOM0x03:
1676 if (st->media_eom != -1) {
1677 st->media_fileno = st->media_eom;
1678 st->media_blkno = 0;
1679 } else {
1680 st->media_fileno = -1;
1681 st->media_blkno = -1;
1682 }
1683 break;
1684 default:
1685 st->media_fileno = -1;
1686 st->media_blkno = -1;
1687 break;
1688 }
1689 }
1690
1691 return error;
1692}
1693
1694/*
1695 * write N filemarks
1696 */
1697int
1698st_write_filemarks(struct st_softc *st, int number, int flags)
1699{
1700 struct scsi_write_filemarks *cmd;
1701 struct scsi_xfer *xs;
1702 int error;
1703
1704 if (number < 0)
1705 return EINVAL22;
1706
1707 xs = scsi_xs_get(st->sc_link, flags);
1708 if (xs == NULL((void *)0))
1709 return ENOMEM12;
1710
1711 xs->cmdlen = sizeof(*cmd);
1712 xs->timeout = ST_IO_TIME(3 * 60 * 1000) * 4;
1713
1714 switch (number) {
1715 case 0: /* really a command to sync the drive's buffers */
1716 break;
1717 case 1:
1718 if (ISSET(st->flags, ST_FM_WRITTEN)((st->flags) & (0x00000100))) /* already have one down */
1719 CLR(st->flags, ST_WRITTEN)((st->flags) &= ~(0x00000004));
1720 else
1721 SET(st->flags, ST_FM_WRITTEN)((st->flags) |= (0x00000100));
1722 CLR(st->flags, ST_PER_ACTION)((st->flags) &= ~((0x00000010 | 0x00000020 | 0x00000040
| 0x00000200)))
;
1723 break;
1724 default:
1725 CLR(st->flags, ST_PER_ACTION | ST_WRITTEN)((st->flags) &= ~((0x00000010 | 0x00000020 | 0x00000040
| 0x00000200) | 0x00000004))
;
1726 break;
1727 }
1728
1729 cmd = (struct scsi_write_filemarks *)&xs->cmd;
1730 cmd->opcode = WRITE_FILEMARKS0x10;
1731 _lto3b(number, cmd->number);
1732
1733 error = scsi_xs_sync(xs);
1734 scsi_xs_put(xs);
1735
1736 if (error != 0) {
1737 st->media_fileno = -1;
1738 st->media_blkno = -1;
1739 st->media_eom = -1;
1740 } else if (st->media_fileno != -1) {
1741 st->media_fileno += number;
1742 st->media_eom = st->media_fileno;
1743 st->media_blkno = 0;
1744 }
1745
1746 return error;
1747}
1748
1749/*
1750 * Make sure the right number of file marks is on tape if the
1751 * tape has been written. If the position argument is true,
1752 * leave the tape positioned where it was originally.
1753 *
1754 * nmarks returns the number of marks to skip (or, if position
1755 * true, which were skipped) to get back original position.
1756 */
1757int
1758st_check_eod(struct st_softc *st, int position, int *nmarks, int flags)
1759{
1760 int error;
1761
1762 switch (st->flags & (ST_WRITTEN0x00000004 | ST_FM_WRITTEN0x00000100 | ST_2FM_AT_EOD0x00000400)) {
1763 default:
1764 *nmarks = 0;
1765 return 0;
1766 case ST_WRITTEN0x00000004:
1767 case ST_WRITTEN0x00000004 | ST_FM_WRITTEN0x00000100 | ST_2FM_AT_EOD0x00000400:
1768 *nmarks = 1;
1769 break;
1770 case ST_WRITTEN0x00000004 | ST_2FM_AT_EOD0x00000400:
1771 *nmarks = 2;
1772 }
1773 error = st_write_filemarks(st, *nmarks, flags);
1774 if (error == 0 && position != 0)
1775 error = st_space(st, -*nmarks, SP_FILEMARKS0x01, flags);
1776 return error;
1777}
1778
1779/*
1780 * load/unload/retension
1781 */
1782int
1783st_load(struct st_softc *st, u_int type, int flags)
1784{
1785 struct scsi_load *cmd;
1786 struct scsi_xfer *xs;
1787 int error, nmarks;
1788
1789 st->media_fileno = -1;
1790 st->media_blkno = -1;
1791 st->media_eom = -1;
1792
1793 if (type != LD_LOAD0x01) {
1794 error = st_check_eod(st, 0, &nmarks, flags);
1795 if (error != 0)
1796 return error;
1797 }
1798
1799 if (ISSET(st->quirks, ST_Q_IGNORE_LOADS)((st->quirks) & (0x0002))) {
1800 if (type == LD_LOAD0x01) {
1801 /*
1802 * If we ignore loads, at least we should try a rewind.
1803 */
1804 return st_rewind(st, 0, flags);
1805 }
1806 return 0;
1807 }
1808
1809
1810 xs = scsi_xs_get(st->sc_link, flags);
1811 if (xs == NULL((void *)0))
1812 return ENOMEM12;
1813 xs->cmdlen = sizeof(*cmd);
1814 xs->timeout = ST_SPC_TIME(4 * 60 * 60 * 1000);
1815
1816 cmd = (struct scsi_load *)&xs->cmd;
1817 cmd->opcode = LOAD0x1b;
1818 cmd->how = type;
1819
1820 error = scsi_xs_sync(xs);
1821 scsi_xs_put(xs);
1822
1823 return error;
1824}
1825
1826/*
1827 * Rewind the device
1828 */
1829int
1830st_rewind(struct st_softc *st, u_int immediate, int flags)
1831{
1832 struct scsi_rewind *cmd;
1833 struct scsi_xfer *xs;
1834 int error, nmarks;
1835
1836 error = st_check_eod(st, 0, &nmarks, flags);
1837 if (error != 0)
1838 return error;
1839 CLR(st->flags, ST_PER_ACTION)((st->flags) &= ~((0x00000010 | 0x00000020 | 0x00000040
| 0x00000200)))
;
1840
1841 xs = scsi_xs_get(st->sc_link, flags);
1842 if (xs == NULL((void *)0))
1843 return ENOMEM12;
1844 xs->cmdlen = sizeof(*cmd);
1845 xs->timeout = immediate ? ST_CTL_TIME(30 * 1000) : ST_SPC_TIME(4 * 60 * 60 * 1000);
1846
1847 cmd = (struct scsi_rewind *)&xs->cmd;
1848 cmd->opcode = REWIND0x01;
1849 cmd->byte2 = immediate;
1850
1851 error = scsi_xs_sync(xs);
1852 scsi_xs_put(xs);
1853
1854 if (error == 0) {
1855 st->media_fileno = 0;
1856 st->media_blkno = 0;
1857 }
1858
1859 return error;
1860}
1861
1862/*
1863 * Look at the returned sense and act on the error to determine
1864 * the unix error number to pass back... (0 = report no error)
1865 * (-1 = continue processing)
1866 */
1867int
1868st_interpret_sense(struct scsi_xfer *xs)
1869{
1870 struct scsi_sense_data *sense = &xs->sense;
1871 struct scsi_link *link = xs->sc_link;
1872 struct scsi_space *space;
1873 struct st_softc *st = link->device_softc;
1874 u_int8_t serr = sense->error_code & SSD_ERRCODE0x7F;
1875 u_int8_t skey = sense->flags & SSD_KEY0x0F;
1876 int32_t resid, info, number;
1877 int datalen;
1878
1879 if (!ISSET(link->flags, SDEV_OPEN)((link->flags) & (0x0008)) ||
1880 (serr != SSD_ERRCODE_CURRENT0x70 && serr != SSD_ERRCODE_DEFERRED0x71))
1881 return scsi_interpret_sense(xs);
1882
1883 info = (int32_t)_4btol(sense->info);
1884
1885 switch (skey) {
1886
1887 /*
1888 * We do custom processing in st for the unit becoming ready case.
1889 * in this case we do not allow xs->retries to be decremented
1890 * only on the "Unit Becoming Ready" case. This is because tape
1891 * drives report "Unit Becoming Ready" when loading media, etc.
1892 * and can take a long time. Rather than having a massive timeout
1893 * for all operations (which would cause other problems) we allow
1894 * operations to wait (but be interruptible with Ctrl-C) forever
1895 * as long as the drive is reporting that it is becoming ready.
1896 * all other cases are handled as per the default.
1897 */
1898
1899 case SKEY_NOT_READY0x02:
1900 if (ISSET(xs->flags, SCSI_IGNORE_NOT_READY)((xs->flags) & (0x00040)))
1901 return 0;
1902 switch (ASC_ASCQ(sense)((sense->add_sense_code << 8) | sense->add_sense_code_qual
)
) {
1903 case SENSE_NOT_READY_BECOMING_READY0x0401:
1904 SC_DEBUG(link, SDEV_DB1, ("not ready: busy (%#x)\n",
1905 sense->add_sense_code_qual));
1906 /* don't count this as a retry */
1907 xs->retries++;
1908 return scsi_delay(xs, 1);
1909 default:
1910 return scsi_interpret_sense(xs);
1911 }
1912 break;
1913 case SKEY_BLANK_CHECK0x08:
1914 if (sense->error_code & SSD_ERRCODE_VALID0x80 &&
1915 xs->cmd.opcode == SPACE0x11) {
1916 switch (ASC_ASCQ(sense)((sense->add_sense_code << 8) | sense->add_sense_code_qual
)
) {
1917 case SENSE_END_OF_DATA_DETECTED0x0005:
1918 SET(st->flags, ST_EOD_DETECTED)((st->flags) |= (0x00000080));
1919 space = (struct scsi_space *)&xs->cmd;
1920 number = _3btol(space->number);
1921 st->media_fileno = number - info;
1922 st->media_eom = st->media_fileno;
1923 return 0;
1924 case SENSE_BEGINNING_OF_MEDIUM_DETECTED0x0004:
1925 /* Standard says: Position is undefined! */
1926 SET(st->flags, ST_BOD_DETECTED)((st->flags) |= (0x00008000));
1927 st->media_fileno = -1;
1928 st->media_blkno = -1;
1929 return 0;
1930 }
1931 }
1932 break;
1933 case SKEY_NO_SENSE0x00:
1934 case SKEY_RECOVERED_ERROR0x01:
1935 case SKEY_MEDIUM_ERROR0x03:
1936 case SKEY_VOLUME_OVERFLOW0x0D:
1937 break;
1938 default:
1939 return scsi_interpret_sense(xs);
1940 }
1941
1942 /*
1943 * 'resid' can be in units of st->blksize or bytes. xs->resid and
1944 * xs->datalen are always in units of bytes. So we need a variable
1945 * to store datalen in the same units as resid and to adjust
1946 * xs->resid to be in bytes.
1947 */
1948 if (ISSET(sense->error_code, SSD_ERRCODE_VALID)((sense->error_code) & (0x80))) {
1949 if (ISSET(st->flags, ST_FIXEDBLOCKS)((st->flags) & (0x00000008)))
1950 resid = info * st->blksize; /* XXXX overflow? */
1951 else
1952 resid = info;
1953 } else {
1954 resid = xs->datalen;
1955 }
1956
1957 if (resid < 0 || resid > xs->datalen)
1958 xs->resid = xs->datalen;
1959 else
1960 xs->resid = resid;
1961
1962 datalen = xs->datalen;
1963 if (ISSET(st->flags, ST_FIXEDBLOCKS)((st->flags) & (0x00000008))) {
1964 resid /= st->blksize;
1965 datalen /= st->blksize;
1966 }
1967
1968 if (ISSET(sense->flags, SSD_FILEMARK)((sense->flags) & (0x80))) {
1969 if (st->media_fileno != -1) {
1970 st->media_fileno++;
1971 if (st->media_fileno > st->media_eom)
1972 st->media_eom = st->media_fileno;
1973 st->media_blkno = 0;
1974 }
1975 if (!ISSET(st->flags, ST_FIXEDBLOCKS)((st->flags) & (0x00000008)))
1976 return 0;
1977 SET(st->flags, ST_AT_FILEMARK)((st->flags) |= (0x00000010));
1978 }
1979
1980 if (ISSET(sense->flags, SSD_EOM)((sense->flags) & (0x40))) {
1981 SET(st->flags, ST_EOM_PENDING)((st->flags) |= (0x00000040));
1982 xs->resid = 0;
1983 if (ISSET(st->flags, ST_FIXEDBLOCKS)((st->flags) & (0x00000008)))
1984 return 0;
1985 }
1986
1987 if (ISSET(sense->flags, SSD_ILI)((sense->flags) & (0x20))) {
1988 if (!ISSET(st->flags, ST_FIXEDBLOCKS)((st->flags) & (0x00000008))) {
1989 if (resid >= 0 && resid <= datalen)
1990 return 0;
1991 if (!ISSET(xs->flags, SCSI_SILENT)((xs->flags) & (0x00020)))
1992 printf( "%s: bad residual %d out of "
1993 "%d\n", st->sc_dev.dv_xname, resid,
1994 datalen);
1995 return EIO5;
1996 }
1997
1998 /* Fixed size blocks. */
1999 if (ISSET(sense->error_code, SSD_ERRCODE_VALID)((sense->error_code) & (0x80)))
2000 if (!ISSET(xs->flags, SCSI_SILENT)((xs->flags) & (0x00020)))
2001 printf("%s: block wrong size, %d blocks "
2002 "residual\n", st->sc_dev.dv_xname, resid);
2003 SET(st->flags, ST_EIO_PENDING)((st->flags) |= (0x00000020));
2004 /*
2005 * This quirk code helps the drive read the first tape block,
2006 * regardless of format. That is required for these drives to
2007 * return proper MODE SENSE information.
2008 */
2009 if (ISSET(st->quirks, ST_Q_SENSE_HELP)((st->quirks) & (0x0001)) &&
2010 !ISSET(link->flags, SDEV_MEDIA_LOADED)((link->flags) & (0x0002)))
2011 st->blksize -= 512;
2012 }
2013
2014 if (ISSET(st->flags, ST_FIXEDBLOCKS)((st->flags) & (0x00000008)) && xs->resid == xs->datalen) {
2015 if (ISSET(st->flags, ST_EIO_PENDING)((st->flags) & (0x00000020)))
2016 return EIO5;
2017 if (ISSET(st->flags, ST_AT_FILEMARK)((st->flags) & (0x00000010)))
2018 return 0;
2019 }
2020
2021 if (skey == SKEY_BLANK_CHECK0x08) {
2022 /*
2023 * This quirk code helps the drive read the first tape block,
2024 * regardless of format. That is required for these drives to
2025 * return proper MODE SENSE information.
2026 */
2027 if (ISSET(st->quirks, ST_Q_SENSE_HELP)((st->quirks) & (0x0001)) &&
2028 !ISSET(link->flags, SDEV_MEDIA_LOADED)((link->flags) & (0x0002))) {
2029 /* still starting */
2030 st->blksize -= 512;
2031 } else if (!ISSET(st->flags, ST_2FM_AT_EOD | ST_BLANK_READ)((st->flags) & (0x00000400 | 0x00000200))) {
2032 SET(st->flags, ST_BLANK_READ)((st->flags) |= (0x00000200));
2033 SET(st->flags, ST_EOM_PENDING)((st->flags) |= (0x00000040));
2034 xs->resid = xs->datalen;
2035 return 0;
2036 }
2037 }
2038
2039 return scsi_interpret_sense(xs);
2040}
2041
2042/*
2043 * The quirk here is that the drive returns some value to st_mode_sense
2044 * incorrectly until the tape has actually passed by the head.
2045 *
2046 * The method is to set the drive to large fixed-block state (user-specified
2047 * density and 1024-byte blocks), then read and rewind to get it to sense the
2048 * tape. If that doesn't work, try 512-byte fixed blocks. If that doesn't
2049 * work, as a last resort, try variable- length blocks. The result will be
2050 * the ability to do an accurate st_mode_sense.
2051 *
2052 * We know we can do a rewind because we just did a load, which implies rewind.
2053 * Rewind seems preferable to space backward if we have a virgin tape.
2054 *
2055 * The rest of the code for this quirk is in ILI processing and BLANK CHECK
2056 * error processing, both part of st_interpret_sense.
2057 */
2058int
2059st_touch_tape(struct st_softc *st)
2060{
2061 char *buf = NULL((void *)0);
2062 int readsize, maxblksize = 1024;
2063 int error = 0;
2064
2065 if ((error = st_mode_sense(st, 0)) != 0)
2066 goto done;
2067 buf = dma_alloc(maxblksize, PR_NOWAIT0x0002);
2068 if (buf == NULL((void *)0)) {
2069 error = ENOMEM12;
2070 goto done;
2071 }
2072
2073 st->blksize = 1024;
2074 do {
2075 switch (st->blksize) {
2076 case 512:
2077 case 1024:
2078 readsize = st->blksize;
2079 SET(st->flags, ST_FIXEDBLOCKS)((st->flags) |= (0x00000008));
2080 break;
2081 default:
2082 readsize = 1;
2083 CLR(st->flags, ST_FIXEDBLOCKS)((st->flags) &= ~(0x00000008));
2084 }
2085 if ((error = st_mode_select(st, 0)) != 0)
2086 goto done;
2087 st_read(st, buf, readsize, SCSI_SILENT0x00020); /* XXX */
2088 if ((error = st_rewind(st, 0, 0)) != 0)
2089 goto done;
2090 } while (readsize != 1 && readsize > st->blksize);
2091done:
2092 dma_free(buf, maxblksize);
2093 return error;
2094}