Book a Demo!
CoCalc Logo Icon
StoreFeaturesDocsShareSupportNewsAboutPoliciesSign UpSign In
freebsd
GitHub Repository: freebsd/freebsd-src
Path: blob/main/sys/cam/scsi/scsi_sa.c
39478 views
1
/*-
2
* Implementation of SCSI Sequential Access Peripheral driver for CAM.
3
*
4
* SPDX-License-Identifier: BSD-2-Clause
5
*
6
* Copyright (c) 1999, 2000 Matthew Jacob
7
* Copyright (c) 2013, 2014, 2015, 2021 Spectra Logic Corporation
8
* All rights reserved.
9
*
10
* Redistribution and use in source and binary forms, with or without
11
* modification, are permitted provided that the following conditions
12
* are met:
13
* 1. Redistributions of source code must retain the above copyright
14
* notice, this list of conditions, and the following disclaimer,
15
* without modification, immediately at the beginning of the file.
16
* 2. The name of the author may not be used to endorse or promote products
17
* derived from this software without specific prior written permission.
18
*
19
* THIS SOFTWARE IS PROVIDED BY THE AUTHOR AND CONTRIBUTORS ``AS IS'' AND
20
* ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
21
* IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
22
* ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE FOR
23
* ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
24
* DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
25
* OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
26
* HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
27
* LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
28
* OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
29
* SUCH DAMAGE.
30
*/
31
32
#include <sys/param.h>
33
#include <sys/queue.h>
34
#ifdef _KERNEL
35
#include <sys/systm.h>
36
#include <sys/kernel.h>
37
#endif
38
#include <sys/types.h>
39
#include <sys/time.h>
40
#include <sys/bio.h>
41
#include <sys/limits.h>
42
#include <sys/malloc.h>
43
#include <sys/mtio.h>
44
#ifdef _KERNEL
45
#include <sys/conf.h>
46
#include <sys/sbuf.h>
47
#include <sys/sysctl.h>
48
#include <sys/taskqueue.h>
49
#endif
50
#include <sys/fcntl.h>
51
#include <sys/devicestat.h>
52
53
#ifndef _KERNEL
54
#include <stdio.h>
55
#include <string.h>
56
#endif
57
58
#include <cam/cam.h>
59
#include <cam/cam_ccb.h>
60
#include <cam/cam_periph.h>
61
#include <cam/cam_xpt_periph.h>
62
#include <cam/cam_debug.h>
63
64
#include <cam/scsi/scsi_all.h>
65
#include <cam/scsi/scsi_message.h>
66
#include <cam/scsi/scsi_sa.h>
67
68
#ifdef _KERNEL
69
70
#include "opt_sa.h"
71
72
#ifndef SA_IO_TIMEOUT
73
#define SA_IO_TIMEOUT 32
74
#endif
75
#ifndef SA_SPACE_TIMEOUT
76
#define SA_SPACE_TIMEOUT 1 * 60
77
#endif
78
#ifndef SA_REWIND_TIMEOUT
79
#define SA_REWIND_TIMEOUT 2 * 60
80
#endif
81
#ifndef SA_ERASE_TIMEOUT
82
#define SA_ERASE_TIMEOUT 4 * 60
83
#endif
84
#ifndef SA_REP_DENSITY_TIMEOUT
85
#define SA_REP_DENSITY_TIMEOUT 1
86
#endif
87
88
#define SCSIOP_TIMEOUT (60 * 1000) /* not an option */
89
90
#define IO_TIMEOUT (SA_IO_TIMEOUT * 60 * 1000)
91
#define REWIND_TIMEOUT (SA_REWIND_TIMEOUT * 60 * 1000)
92
#define ERASE_TIMEOUT (SA_ERASE_TIMEOUT * 60 * 1000)
93
#define SPACE_TIMEOUT (SA_SPACE_TIMEOUT * 60 * 1000)
94
#define REP_DENSITY_TIMEOUT (SA_REP_DENSITY_TIMEOUT * 60 * 1000)
95
96
/*
97
* Additional options that can be set for config: SA_1FM_AT_EOT
98
*/
99
100
#ifndef UNUSED_PARAMETER
101
#define UNUSED_PARAMETER(x) x = x
102
#endif
103
104
#define QFRLS(ccb) \
105
if (((ccb)->ccb_h.status & CAM_DEV_QFRZN) != 0) \
106
cam_release_devq((ccb)->ccb_h.path, 0, 0, 0, FALSE)
107
108
/*
109
* Driver states
110
*/
111
112
static MALLOC_DEFINE(M_SCSISA, "SCSI sa", "SCSI sequential access buffers");
113
114
typedef enum {
115
SA_STATE_NORMAL, SA_STATE_PROBE, SA_STATE_ABNORMAL
116
} sa_state;
117
118
#define ccb_pflags ppriv_field0
119
#define ccb_bp ppriv_ptr1
120
121
/* bits in ccb_pflags */
122
#define SA_POSITION_UPDATED 0x1
123
124
typedef enum {
125
SA_FLAG_OPEN = 0x00001,
126
SA_FLAG_FIXED = 0x00002,
127
SA_FLAG_TAPE_LOCKED = 0x00004,
128
SA_FLAG_TAPE_MOUNTED = 0x00008,
129
SA_FLAG_TAPE_WP = 0x00010,
130
SA_FLAG_TAPE_WRITTEN = 0x00020,
131
SA_FLAG_EOM_PENDING = 0x00040,
132
SA_FLAG_EIO_PENDING = 0x00080,
133
SA_FLAG_EOF_PENDING = 0x00100,
134
SA_FLAG_ERR_PENDING = (SA_FLAG_EOM_PENDING|SA_FLAG_EIO_PENDING|
135
SA_FLAG_EOF_PENDING),
136
SA_FLAG_INVALID = 0x00200,
137
SA_FLAG_COMP_ENABLED = 0x00400,
138
SA_FLAG_COMP_SUPP = 0x00800,
139
SA_FLAG_COMP_UNSUPP = 0x01000,
140
SA_FLAG_TAPE_FROZEN = 0x02000,
141
SA_FLAG_PROTECT_SUPP = 0x04000,
142
143
SA_FLAG_COMPRESSION = (SA_FLAG_COMP_SUPP|SA_FLAG_COMP_ENABLED|
144
SA_FLAG_COMP_UNSUPP),
145
SA_FLAG_SCTX_INIT = 0x08000,
146
SA_FLAG_RSOC_TO_TRY = 0x10000,
147
} sa_flags;
148
149
typedef enum {
150
SA_MODE_REWIND = 0x00,
151
SA_MODE_NOREWIND = 0x01,
152
SA_MODE_OFFLINE = 0x02
153
} sa_mode;
154
155
typedef enum {
156
SA_TIMEOUT_ERASE,
157
SA_TIMEOUT_LOAD,
158
SA_TIMEOUT_LOCATE,
159
SA_TIMEOUT_MODE_SELECT,
160
SA_TIMEOUT_MODE_SENSE,
161
SA_TIMEOUT_PREVENT,
162
SA_TIMEOUT_READ,
163
SA_TIMEOUT_READ_BLOCK_LIMITS,
164
SA_TIMEOUT_READ_POSITION,
165
SA_TIMEOUT_REP_DENSITY,
166
SA_TIMEOUT_RESERVE,
167
SA_TIMEOUT_REWIND,
168
SA_TIMEOUT_SPACE,
169
SA_TIMEOUT_TUR,
170
SA_TIMEOUT_WRITE,
171
SA_TIMEOUT_WRITE_FILEMARKS,
172
SA_TIMEOUT_TYPE_MAX
173
} sa_timeout_types;
174
175
/*
176
* These are the default timeout values that apply to all tape drives.
177
*
178
* We get timeouts from the following places in order of increasing
179
* priority:
180
* 1. Driver default timeouts. (Set in the structure below.)
181
* 2. Timeouts loaded from the drive via REPORT SUPPORTED OPERATION
182
* CODES. (If the drive supports it, SPC-4/LTO-5 and newer should.)
183
* 3. Global loader tunables, used for all sa(4) driver instances on
184
* a machine.
185
* 4. Instance-specific loader tunables, used for say sa5.
186
* 5. On the fly user sysctl changes.
187
*
188
* Each step will overwrite the timeout value set from the one
189
* before, so you go from general to most specific.
190
*/
191
static struct sa_timeout_desc {
192
const char *desc;
193
int value;
194
} sa_default_timeouts[SA_TIMEOUT_TYPE_MAX] = {
195
{"erase", ERASE_TIMEOUT},
196
{"load", REWIND_TIMEOUT},
197
{"locate", SPACE_TIMEOUT},
198
{"mode_select", SCSIOP_TIMEOUT},
199
{"mode_sense", SCSIOP_TIMEOUT},
200
{"prevent", SCSIOP_TIMEOUT},
201
{"read", IO_TIMEOUT},
202
{"read_block_limits", SCSIOP_TIMEOUT},
203
{"read_position", SCSIOP_TIMEOUT},
204
{"report_density", REP_DENSITY_TIMEOUT},
205
{"reserve", SCSIOP_TIMEOUT},
206
{"rewind", REWIND_TIMEOUT},
207
{"space", SPACE_TIMEOUT},
208
{"tur", SCSIOP_TIMEOUT},
209
{"write", IO_TIMEOUT},
210
{"write_filemarks", IO_TIMEOUT},
211
};
212
213
typedef enum {
214
SA_PARAM_NONE = 0x000,
215
SA_PARAM_BLOCKSIZE = 0x001,
216
SA_PARAM_DENSITY = 0x002,
217
SA_PARAM_COMPRESSION = 0x004,
218
SA_PARAM_BUFF_MODE = 0x008,
219
SA_PARAM_NUMBLOCKS = 0x010,
220
SA_PARAM_WP = 0x020,
221
SA_PARAM_SPEED = 0x040,
222
SA_PARAM_DENSITY_EXT = 0x080,
223
SA_PARAM_LBP = 0x100,
224
SA_PARAM_ALL = 0x1ff
225
} sa_params;
226
227
typedef enum {
228
SA_QUIRK_NONE = 0x000,
229
SA_QUIRK_NOCOMP = 0x001, /* Can't deal with compression at all*/
230
SA_QUIRK_FIXED = 0x002, /* Force fixed mode */
231
SA_QUIRK_VARIABLE = 0x004, /* Force variable mode */
232
SA_QUIRK_2FM = 0x008, /* Needs Two File Marks at EOD */
233
SA_QUIRK_1FM = 0x010, /* No more than 1 File Mark at EOD */
234
SA_QUIRK_NODREAD = 0x020, /* Don't try and dummy read density */
235
SA_QUIRK_NO_MODESEL = 0x040, /* Don't do mode select at all */
236
SA_QUIRK_NO_CPAGE = 0x080, /* Don't use DEVICE COMPRESSION page */
237
SA_QUIRK_NO_LONG_POS = 0x100 /* No long position information */
238
} sa_quirks;
239
240
#define SA_QUIRK_BIT_STRING \
241
"\020" \
242
"\001NOCOMP" \
243
"\002FIXED" \
244
"\003VARIABLE" \
245
"\0042FM" \
246
"\0051FM" \
247
"\006NODREAD" \
248
"\007NO_MODESEL" \
249
"\010NO_CPAGE" \
250
"\011NO_LONG_POS"
251
252
#define SAMODE(z) (dev2unit(z) & 0x3)
253
#define SA_IS_CTRL(z) (dev2unit(z) & (1 << 4))
254
255
#define SA_NOT_CTLDEV 0
256
#define SA_CTLDEV 1
257
258
#define SA_ATYPE_R 0
259
#define SA_ATYPE_NR 1
260
#define SA_ATYPE_ER 2
261
#define SA_NUM_ATYPES 3
262
263
#define SAMINOR(ctl, access) \
264
((ctl << 4) | (access & 0x3))
265
266
struct sa_devs {
267
struct cdev *ctl_dev;
268
struct cdev *r_dev;
269
struct cdev *nr_dev;
270
struct cdev *er_dev;
271
};
272
273
#define SASBADDBASE(sb, indent, data, xfmt, name, type, xsize, desc) \
274
sbuf_printf(sb, "%*s<%s type=\"%s\" size=\"%zd\" " \
275
"fmt=\"%s\" desc=\"%s\">" #xfmt "</%s>\n", indent, "", \
276
#name, #type, xsize, #xfmt, desc ? desc : "", data, #name);
277
278
#define SASBADDINT(sb, indent, data, fmt, name) \
279
SASBADDBASE(sb, indent, data, fmt, name, int, sizeof(data), \
280
NULL)
281
282
#define SASBADDINTDESC(sb, indent, data, fmt, name, desc) \
283
SASBADDBASE(sb, indent, data, fmt, name, int, sizeof(data), \
284
desc)
285
286
#define SASBADDUINT(sb, indent, data, fmt, name) \
287
SASBADDBASE(sb, indent, data, fmt, name, uint, sizeof(data), \
288
NULL)
289
290
#define SASBADDUINTDESC(sb, indent, data, fmt, name, desc) \
291
SASBADDBASE(sb, indent, data, fmt, name, uint, sizeof(data), \
292
desc)
293
294
#define SASBADDFIXEDSTR(sb, indent, data, fmt, name) \
295
SASBADDBASE(sb, indent, data, fmt, name, str, sizeof(data), \
296
NULL)
297
298
#define SASBADDFIXEDSTRDESC(sb, indent, data, fmt, name, desc) \
299
SASBADDBASE(sb, indent, data, fmt, name, str, sizeof(data), \
300
desc)
301
302
#define SASBADDVARSTR(sb, indent, data, fmt, name, maxlen) \
303
SASBADDBASE(sb, indent, data, fmt, name, str, maxlen, NULL)
304
305
#define SASBADDVARSTRDESC(sb, indent, data, fmt, name, maxlen, desc) \
306
SASBADDBASE(sb, indent, data, fmt, name, str, maxlen, desc)
307
308
#define SASBADDNODE(sb, indent, name) { \
309
sbuf_printf(sb, "%*s<%s type=\"%s\">\n", indent, "", #name, \
310
"node"); \
311
indent += 2; \
312
}
313
314
#define SASBADDNODENUM(sb, indent, name, num) { \
315
sbuf_printf(sb, "%*s<%s type=\"%s\" num=\"%d\">\n", indent, "", \
316
#name, "node", num); \
317
indent += 2; \
318
}
319
320
#define SASBENDNODE(sb, indent, name) { \
321
indent -= 2; \
322
sbuf_printf(sb, "%*s</%s>\n", indent, "", #name); \
323
}
324
325
#define SA_DENSITY_TYPES 4
326
327
struct sa_prot_state {
328
int initialized;
329
uint32_t prot_method;
330
uint32_t pi_length;
331
uint32_t lbp_w;
332
uint32_t lbp_r;
333
uint32_t rbdp;
334
};
335
336
struct sa_prot_info {
337
struct sa_prot_state cur_prot_state;
338
struct sa_prot_state pending_prot_state;
339
};
340
341
/*
342
* A table mapping protection parameters to their types and values.
343
*/
344
struct sa_prot_map {
345
char *name;
346
mt_param_set_type param_type;
347
off_t offset;
348
uint32_t min_val;
349
uint32_t max_val;
350
uint32_t *value;
351
} sa_prot_table[] = {
352
{ "prot_method", MT_PARAM_SET_UNSIGNED,
353
__offsetof(struct sa_prot_state, prot_method),
354
/*min_val*/ 0, /*max_val*/ 255, NULL },
355
{ "pi_length", MT_PARAM_SET_UNSIGNED,
356
__offsetof(struct sa_prot_state, pi_length),
357
/*min_val*/ 0, /*max_val*/ SA_CTRL_DP_PI_LENGTH_MASK, NULL },
358
{ "lbp_w", MT_PARAM_SET_UNSIGNED,
359
__offsetof(struct sa_prot_state, lbp_w),
360
/*min_val*/ 0, /*max_val*/ 1, NULL },
361
{ "lbp_r", MT_PARAM_SET_UNSIGNED,
362
__offsetof(struct sa_prot_state, lbp_r),
363
/*min_val*/ 0, /*max_val*/ 1, NULL },
364
{ "rbdp", MT_PARAM_SET_UNSIGNED,
365
__offsetof(struct sa_prot_state, rbdp),
366
/*min_val*/ 0, /*max_val*/ 1, NULL }
367
};
368
369
#define SA_NUM_PROT_ENTS nitems(sa_prot_table)
370
371
#define SA_PROT_ENABLED(softc) ((softc->flags & SA_FLAG_PROTECT_SUPP) \
372
&& (softc->prot_info.cur_prot_state.initialized != 0) \
373
&& (softc->prot_info.cur_prot_state.prot_method != 0))
374
375
#define SA_PROT_LEN(softc) softc->prot_info.cur_prot_state.pi_length
376
377
struct sa_softc {
378
sa_state state;
379
sa_flags flags;
380
sa_quirks quirks;
381
u_int si_flags;
382
struct cam_periph *periph;
383
struct bio_queue_head bio_queue;
384
int queue_count;
385
struct devstat *device_stats;
386
struct sa_devs devs;
387
int open_count;
388
int num_devs_to_destroy;
389
int blk_gran;
390
int blk_mask;
391
int blk_shift;
392
uint32_t max_blk;
393
uint32_t min_blk;
394
uint32_t maxio;
395
uint32_t cpi_maxio;
396
int allow_io_split;
397
int inject_eom;
398
int set_pews_status;
399
uint32_t comp_algorithm;
400
uint32_t saved_comp_algorithm;
401
uint32_t media_blksize;
402
uint32_t last_media_blksize;
403
uint32_t media_numblks;
404
uint8_t media_density;
405
uint8_t speed;
406
uint8_t scsi_rev;
407
uint8_t dsreg; /* mtio mt_dsreg, redux */
408
int buffer_mode;
409
int filemarks;
410
int last_resid_was_io;
411
uint8_t density_type_bits[SA_DENSITY_TYPES];
412
int density_info_valid[SA_DENSITY_TYPES];
413
uint8_t density_info[SA_DENSITY_TYPES][SRDS_MAX_LENGTH];
414
int timeout_info[SA_TIMEOUT_TYPE_MAX];
415
416
struct sa_prot_info prot_info;
417
418
int sili;
419
int eot_warn;
420
421
/*
422
* Current position information. -1 means that the given value is
423
* unknown. fileno and blkno are always calculated. blkno is
424
* relative to the previous file mark. rep_fileno and rep_blkno
425
* are as reported by the drive, if it supports the long form
426
* report for the READ POSITION command. rep_blkno is relative to
427
* the beginning of the partition.
428
*
429
* bop means that the drive is at the beginning of the partition.
430
* eop means that the drive is between early warning and end of
431
* partition, inside the current partition.
432
* bpew means that the position is in a PEWZ (Programmable Early
433
* Warning Zone)
434
*/
435
daddr_t partition; /* Absolute from BOT */
436
daddr_t fileno; /* Relative to beginning of partition */
437
daddr_t blkno; /* Relative to last file mark */
438
daddr_t rep_blkno; /* Relative to beginning of partition */
439
daddr_t rep_fileno; /* Relative to beginning of partition */
440
int bop; /* Beginning of Partition */
441
int eop; /* End of Partition */
442
int bpew; /* Beyond Programmable Early Warning */
443
444
/*
445
* Latched Error Info
446
*/
447
struct {
448
struct scsi_sense_data _last_io_sense;
449
uint64_t _last_io_resid;
450
uint8_t _last_io_cdb[CAM_MAX_CDBLEN];
451
struct scsi_sense_data _last_ctl_sense;
452
uint64_t _last_ctl_resid;
453
uint8_t _last_ctl_cdb[CAM_MAX_CDBLEN];
454
#define last_io_sense errinfo._last_io_sense
455
#define last_io_resid errinfo._last_io_resid
456
#define last_io_cdb errinfo._last_io_cdb
457
#define last_ctl_sense errinfo._last_ctl_sense
458
#define last_ctl_resid errinfo._last_ctl_resid
459
#define last_ctl_cdb errinfo._last_ctl_cdb
460
} errinfo;
461
/*
462
* Misc other flags/state
463
*/
464
uint32_t
465
: 29,
466
open_rdonly : 1, /* open read-only */
467
open_pending_mount : 1, /* open pending mount */
468
ctrl_mode : 1; /* control device open */
469
470
struct task sysctl_task;
471
struct sysctl_ctx_list sysctl_ctx;
472
struct sysctl_oid *sysctl_tree;
473
struct sysctl_ctx_list sysctl_timeout_ctx;
474
struct sysctl_oid *sysctl_timeout_tree;
475
};
476
477
struct sa_quirk_entry {
478
struct scsi_inquiry_pattern inq_pat; /* matching pattern */
479
sa_quirks quirks; /* specific quirk type */
480
uint32_t prefblk; /* preferred blocksize when in fixed mode */
481
};
482
483
static struct sa_quirk_entry sa_quirk_table[] =
484
{
485
{
486
{ T_SEQUENTIAL, SIP_MEDIA_REMOVABLE, "OnStream",
487
"ADR*", "*"}, SA_QUIRK_FIXED|SA_QUIRK_NODREAD |
488
SA_QUIRK_1FM|SA_QUIRK_NO_MODESEL, 32768
489
},
490
{
491
{ T_SEQUENTIAL, SIP_MEDIA_REMOVABLE, "ARCHIVE",
492
"Python 06408*", "*"}, SA_QUIRK_NODREAD, 0
493
},
494
{
495
{ T_SEQUENTIAL, SIP_MEDIA_REMOVABLE, "ARCHIVE",
496
"Python 25601*", "*"}, SA_QUIRK_NOCOMP|SA_QUIRK_NODREAD, 0
497
},
498
{
499
{ T_SEQUENTIAL, SIP_MEDIA_REMOVABLE, "ARCHIVE",
500
"Python*", "*"}, SA_QUIRK_NODREAD, 0
501
},
502
{
503
{ T_SEQUENTIAL, SIP_MEDIA_REMOVABLE, "ARCHIVE",
504
"VIPER 150*", "*"}, SA_QUIRK_FIXED|SA_QUIRK_1FM, 512
505
},
506
{
507
{ T_SEQUENTIAL, SIP_MEDIA_REMOVABLE, "ARCHIVE",
508
"VIPER 2525 25462", "-011"},
509
SA_QUIRK_NOCOMP|SA_QUIRK_1FM|SA_QUIRK_NODREAD, 0
510
},
511
{
512
{ T_SEQUENTIAL, SIP_MEDIA_REMOVABLE, "ARCHIVE",
513
"VIPER 2525*", "*"}, SA_QUIRK_FIXED|SA_QUIRK_1FM, 1024
514
},
515
#if 0
516
{
517
{ T_SEQUENTIAL, SIP_MEDIA_REMOVABLE, "HP",
518
"C15*", "*"}, SA_QUIRK_VARIABLE|SA_QUIRK_NO_CPAGE, 0,
519
},
520
#endif
521
{
522
{ T_SEQUENTIAL, SIP_MEDIA_REMOVABLE, "HP",
523
"C56*", "*"}, SA_QUIRK_VARIABLE|SA_QUIRK_2FM, 0
524
},
525
{
526
{ T_SEQUENTIAL, SIP_MEDIA_REMOVABLE, "HP",
527
"T20*", "*"}, SA_QUIRK_FIXED|SA_QUIRK_1FM, 512
528
},
529
{
530
{ T_SEQUENTIAL, SIP_MEDIA_REMOVABLE, "HP",
531
"T4000*", "*"}, SA_QUIRK_FIXED|SA_QUIRK_1FM, 512
532
},
533
{
534
{ T_SEQUENTIAL, SIP_MEDIA_REMOVABLE, "HP",
535
"HP-88780*", "*"}, SA_QUIRK_VARIABLE|SA_QUIRK_2FM, 0
536
},
537
{
538
{ T_SEQUENTIAL, SIP_MEDIA_REMOVABLE, "KENNEDY",
539
"*", "*"}, SA_QUIRK_VARIABLE|SA_QUIRK_2FM, 0
540
},
541
{
542
{ T_SEQUENTIAL, SIP_MEDIA_REMOVABLE, "M4 DATA",
543
"123107 SCSI*", "*"}, SA_QUIRK_VARIABLE|SA_QUIRK_2FM, 0
544
},
545
{ /* [email protected] */
546
{ T_SEQUENTIAL, SIP_MEDIA_REMOVABLE, "Seagate",
547
"STT8000N*", "*"}, SA_QUIRK_1FM, 0
548
},
549
{ /* [email protected] */
550
{ T_SEQUENTIAL, SIP_MEDIA_REMOVABLE, "Seagate",
551
"STT20000*", "*"}, SA_QUIRK_1FM, 0
552
},
553
{
554
{ T_SEQUENTIAL, SIP_MEDIA_REMOVABLE, "SEAGATE",
555
"DAT 06241-XXX", "*"}, SA_QUIRK_VARIABLE|SA_QUIRK_2FM, 0
556
},
557
{
558
{ T_SEQUENTIAL, SIP_MEDIA_REMOVABLE, "TANDBERG",
559
" TDC 3600", "U07:"}, SA_QUIRK_NOCOMP|SA_QUIRK_1FM, 512
560
},
561
{
562
{ T_SEQUENTIAL, SIP_MEDIA_REMOVABLE, "TANDBERG",
563
" TDC 3800", "*"}, SA_QUIRK_NOCOMP|SA_QUIRK_1FM, 512
564
},
565
{
566
{ T_SEQUENTIAL, SIP_MEDIA_REMOVABLE, "TANDBERG",
567
" TDC 4100", "*"}, SA_QUIRK_NOCOMP|SA_QUIRK_1FM, 512
568
},
569
{
570
{ T_SEQUENTIAL, SIP_MEDIA_REMOVABLE, "TANDBERG",
571
" TDC 4200", "*"}, SA_QUIRK_NOCOMP|SA_QUIRK_1FM, 512
572
},
573
{
574
{ T_SEQUENTIAL, SIP_MEDIA_REMOVABLE, "TANDBERG",
575
" SLR*", "*"}, SA_QUIRK_1FM, 0
576
},
577
{
578
{ T_SEQUENTIAL, SIP_MEDIA_REMOVABLE, "WANGTEK",
579
"5525ES*", "*"}, SA_QUIRK_FIXED|SA_QUIRK_1FM, 512
580
},
581
{
582
{ T_SEQUENTIAL, SIP_MEDIA_REMOVABLE, "WANGTEK",
583
"51000*", "*"}, SA_QUIRK_FIXED|SA_QUIRK_1FM, 1024
584
}
585
};
586
587
static d_open_t saopen;
588
static d_close_t saclose;
589
static d_strategy_t sastrategy;
590
static d_ioctl_t saioctl;
591
static periph_init_t sainit;
592
static periph_ctor_t saregister;
593
static periph_oninv_t saoninvalidate;
594
static periph_dtor_t sacleanup;
595
static periph_start_t sastart;
596
static void saasync(void *callback_arg, uint32_t code,
597
struct cam_path *path, void *arg);
598
static void sadone(struct cam_periph *periph,
599
union ccb *start_ccb);
600
static int saerror(union ccb *ccb, uint32_t cam_flags,
601
uint32_t sense_flags);
602
static int samarkswanted(struct cam_periph *);
603
static int sacheckeod(struct cam_periph *periph);
604
static int sagetparams(struct cam_periph *periph,
605
sa_params params_to_get,
606
uint32_t *blocksize, uint8_t *density,
607
uint32_t *numblocks, int *buff_mode,
608
uint8_t *write_protect, uint8_t *speed,
609
int *comp_supported, int *comp_enabled,
610
uint32_t *comp_algorithm,
611
sa_comp_t *comp_page,
612
struct scsi_control_data_prot_subpage
613
*prot_page, int dp_size,
614
int prot_changeable);
615
static int sasetprot(struct cam_periph *periph,
616
struct sa_prot_state *new_prot);
617
static int sasetparams(struct cam_periph *periph,
618
sa_params params_to_set,
619
uint32_t blocksize, uint8_t density,
620
uint32_t comp_algorithm,
621
uint32_t sense_flags);
622
static int sasetsili(struct cam_periph *periph,
623
struct mtparamset *ps, int num_params);
624
static int saseteotwarn(struct cam_periph *periph,
625
struct mtparamset *ps, int num_params);
626
static void safillprot(struct sa_softc *softc, int *indent,
627
struct sbuf *sb);
628
static void sapopulateprots(struct sa_prot_state *cur_state,
629
struct sa_prot_map *new_table,
630
int table_ents);
631
static struct sa_prot_map *safindprotent(char *name, struct sa_prot_map *table,
632
int table_ents);
633
static int sasetprotents(struct cam_periph *periph,
634
struct mtparamset *ps, int num_params);
635
static const struct sa_param_ent *safindparament(struct mtparamset *ps);
636
static int saparamsetlist(struct cam_periph *periph,
637
struct mtsetlist *list, int need_copy);
638
static int saextget(struct cdev *dev, struct cam_periph *periph,
639
struct sbuf *sb, struct mtextget *g);
640
static int saparamget(struct sa_softc *softc, struct sbuf *sb);
641
static void saprevent(struct cam_periph *periph, int action);
642
static int sarewind(struct cam_periph *periph);
643
static int saspace(struct cam_periph *periph, int count,
644
scsi_space_code code);
645
static void sadevgonecb(void *arg);
646
static void sasetupdev(struct sa_softc *softc, struct cdev *dev);
647
static void saloadtotunables(struct sa_softc *softc);
648
static void sasysctlinit(void *context, int pending);
649
static int samount(struct cam_periph *, int, struct cdev *);
650
static int saretension(struct cam_periph *periph);
651
static int sareservereleaseunit(struct cam_periph *periph,
652
int reserve);
653
static int saloadunload(struct cam_periph *periph, int load);
654
static int saerase(struct cam_periph *periph, int longerase);
655
static int sawritefilemarks(struct cam_periph *periph,
656
int nmarks, int setmarks, int immed);
657
static int sagetpos(struct cam_periph *periph);
658
static int sardpos(struct cam_periph *periph, int, uint32_t *);
659
static int sasetpos(struct cam_periph *periph, int,
660
struct mtlocate *);
661
static void safilldenstypesb(struct sbuf *sb, int *indent,
662
uint8_t *buf, int buf_len,
663
int is_density);
664
static void safilldensitysb(struct sa_softc *softc, int *indent,
665
struct sbuf *sb);
666
static void saloadtimeouts(struct sa_softc *softc, union ccb *ccb);
667
668
#ifndef SA_DEFAULT_IO_SPLIT
669
#define SA_DEFAULT_IO_SPLIT 0
670
#endif
671
672
static int sa_allow_io_split = SA_DEFAULT_IO_SPLIT;
673
674
/*
675
* Tunable to allow the user to set a global allow_io_split value. Note
676
* that this WILL GO AWAY in FreeBSD 11.0. Silently splitting the I/O up
677
* is bad behavior, because it hides the true tape block size from the
678
* application.
679
*/
680
static SYSCTL_NODE(_kern_cam, OID_AUTO, sa, CTLFLAG_RD | CTLFLAG_MPSAFE, 0,
681
"CAM Sequential Access Tape Driver");
682
SYSCTL_INT(_kern_cam_sa, OID_AUTO, allow_io_split, CTLFLAG_RDTUN,
683
&sa_allow_io_split, 0, "Default I/O split value");
684
685
static struct periph_driver sadriver =
686
{
687
sainit, "sa",
688
TAILQ_HEAD_INITIALIZER(sadriver.units), /* generation */ 0
689
};
690
691
PERIPHDRIVER_DECLARE(sa, sadriver);
692
693
/* For 2.2-stable support */
694
#ifndef D_TAPE
695
#define D_TAPE 0
696
#endif
697
698
static struct cdevsw sa_cdevsw = {
699
.d_version = D_VERSION,
700
.d_open = saopen,
701
.d_close = saclose,
702
.d_read = physread,
703
.d_write = physwrite,
704
.d_ioctl = saioctl,
705
.d_strategy = sastrategy,
706
.d_name = "sa",
707
.d_flags = D_TAPE | D_TRACKCLOSE,
708
};
709
710
static int
711
saopen(struct cdev *dev, int flags, int fmt, struct thread *td)
712
{
713
struct cam_periph *periph;
714
struct sa_softc *softc;
715
int error;
716
717
periph = (struct cam_periph *)dev->si_drv1;
718
if (cam_periph_acquire(periph) != 0) {
719
return (ENXIO);
720
}
721
722
cam_periph_lock(periph);
723
724
softc = (struct sa_softc *)periph->softc;
725
726
CAM_DEBUG(periph->path, CAM_DEBUG_TRACE|CAM_DEBUG_INFO,
727
("saopen(%s): softc=0x%x\n", devtoname(dev), softc->flags));
728
729
if (SA_IS_CTRL(dev)) {
730
softc->ctrl_mode = 1;
731
softc->open_count++;
732
cam_periph_unlock(periph);
733
return (0);
734
}
735
736
if ((error = cam_periph_hold(periph, PRIBIO|PCATCH)) != 0) {
737
cam_periph_unlock(periph);
738
cam_periph_release(periph);
739
return (error);
740
}
741
742
if (softc->flags & SA_FLAG_OPEN) {
743
error = EBUSY;
744
} else if (softc->flags & SA_FLAG_INVALID) {
745
error = ENXIO;
746
} else {
747
/*
748
* Preserve whether this is a read_only open.
749
*/
750
softc->open_rdonly = (flags & O_RDWR) == O_RDONLY;
751
752
/*
753
* The function samount ensures media is loaded and ready.
754
* It also does a device RESERVE if the tape isn't yet mounted.
755
*
756
* If the mount fails and this was a non-blocking open,
757
* make this a 'open_pending_mount' action.
758
*/
759
error = samount(periph, flags, dev);
760
if (error && (flags & O_NONBLOCK)) {
761
softc->flags |= SA_FLAG_OPEN;
762
softc->open_pending_mount = 1;
763
softc->open_count++;
764
cam_periph_unhold(periph);
765
cam_periph_unlock(periph);
766
return (0);
767
}
768
}
769
770
if (error) {
771
cam_periph_unhold(periph);
772
cam_periph_unlock(periph);
773
cam_periph_release(periph);
774
return (error);
775
}
776
777
saprevent(periph, PR_PREVENT);
778
softc->flags |= SA_FLAG_OPEN;
779
softc->open_count++;
780
781
cam_periph_unhold(periph);
782
cam_periph_unlock(periph);
783
return (error);
784
}
785
786
static int
787
saclose(struct cdev *dev, int flag, int fmt, struct thread *td)
788
{
789
struct cam_periph *periph;
790
struct sa_softc *softc;
791
int mode, error, writing, tmp, i;
792
int closedbits = SA_FLAG_OPEN;
793
794
mode = SAMODE(dev);
795
periph = (struct cam_periph *)dev->si_drv1;
796
cam_periph_lock(periph);
797
798
softc = (struct sa_softc *)periph->softc;
799
800
CAM_DEBUG(periph->path, CAM_DEBUG_TRACE|CAM_DEBUG_INFO,
801
("saclose(%s): softc=0x%x\n", devtoname(dev), softc->flags));
802
803
softc->open_rdonly = 0;
804
if (SA_IS_CTRL(dev)) {
805
softc->ctrl_mode = 0;
806
softc->open_count--;
807
cam_periph_unlock(periph);
808
cam_periph_release(periph);
809
return (0);
810
}
811
812
if (softc->open_pending_mount) {
813
softc->flags &= ~SA_FLAG_OPEN;
814
softc->open_pending_mount = 0;
815
softc->open_count--;
816
cam_periph_unlock(periph);
817
cam_periph_release(periph);
818
return (0);
819
}
820
821
if ((error = cam_periph_hold(periph, PRIBIO)) != 0) {
822
cam_periph_unlock(periph);
823
return (error);
824
}
825
826
/*
827
* Were we writing the tape?
828
*/
829
writing = (softc->flags & SA_FLAG_TAPE_WRITTEN) != 0;
830
831
/*
832
* See whether or not we need to write filemarks. If this
833
* fails, we probably have to assume we've lost tape
834
* position.
835
*/
836
error = sacheckeod(periph);
837
if (error) {
838
xpt_print(periph->path,
839
"failed to write terminating filemark(s)\n");
840
softc->flags |= SA_FLAG_TAPE_FROZEN;
841
}
842
843
/*
844
* Whatever we end up doing, allow users to eject tapes from here on.
845
*/
846
saprevent(periph, PR_ALLOW);
847
848
/*
849
* Decide how to end...
850
*/
851
if ((softc->flags & SA_FLAG_TAPE_MOUNTED) == 0) {
852
closedbits |= SA_FLAG_TAPE_FROZEN;
853
} else switch (mode) {
854
case SA_MODE_OFFLINE:
855
/*
856
* An 'offline' close is an unconditional release of
857
* frozen && mount conditions, irrespective of whether
858
* these operations succeeded. The reason for this is
859
* to allow at least some kind of programmatic way
860
* around our state getting all fouled up. If somebody
861
* issues an 'offline' command, that will be allowed
862
* to clear state.
863
*/
864
(void) sarewind(periph);
865
(void) saloadunload(periph, FALSE);
866
closedbits |= SA_FLAG_TAPE_MOUNTED|SA_FLAG_TAPE_FROZEN;
867
break;
868
case SA_MODE_REWIND:
869
/*
870
* If the rewind fails, return an error- if anyone cares,
871
* but not overwriting any previous error.
872
*
873
* We don't clear the notion of mounted here, but we do
874
* clear the notion of frozen if we successfully rewound.
875
*/
876
tmp = sarewind(periph);
877
if (tmp) {
878
if (error != 0)
879
error = tmp;
880
} else {
881
closedbits |= SA_FLAG_TAPE_FROZEN;
882
}
883
break;
884
case SA_MODE_NOREWIND:
885
/*
886
* If we're not rewinding/unloading the tape, find out
887
* whether we need to back up over one of two filemarks
888
* we wrote (if we wrote two filemarks) so that appends
889
* from this point on will be sane.
890
*/
891
if (error == 0 && writing && (softc->quirks & SA_QUIRK_2FM)) {
892
tmp = saspace(periph, -1, SS_FILEMARKS);
893
if (tmp) {
894
xpt_print(periph->path, "unable to backspace "
895
"over one of double filemarks at end of "
896
"tape\n");
897
xpt_print(periph->path, "it is possible that "
898
"this device needs a SA_QUIRK_1FM quirk set"
899
"for it\n");
900
softc->flags |= SA_FLAG_TAPE_FROZEN;
901
}
902
}
903
break;
904
default:
905
xpt_print(periph->path, "unknown mode 0x%x in saclose\n", mode);
906
/* NOTREACHED */
907
break;
908
}
909
910
/*
911
* We wish to note here that there are no more filemarks to be written.
912
*/
913
softc->filemarks = 0;
914
softc->flags &= ~SA_FLAG_TAPE_WRITTEN;
915
916
/*
917
* And we are no longer open for business.
918
*/
919
softc->flags &= ~closedbits;
920
softc->open_count--;
921
922
/*
923
* Invalidate any density information that depends on having tape
924
* media in the drive.
925
*/
926
for (i = 0; i < SA_DENSITY_TYPES; i++) {
927
if (softc->density_type_bits[i] & SRDS_MEDIA)
928
softc->density_info_valid[i] = 0;
929
}
930
931
/*
932
* Inform users if tape state if frozen....
933
*/
934
if (softc->flags & SA_FLAG_TAPE_FROZEN) {
935
xpt_print(periph->path, "tape is now frozen- use an OFFLINE, "
936
"REWIND or MTEOM command to clear this state.\n");
937
}
938
939
/* release the device if it is no longer mounted */
940
if ((softc->flags & SA_FLAG_TAPE_MOUNTED) == 0)
941
sareservereleaseunit(periph, FALSE);
942
943
cam_periph_unhold(periph);
944
cam_periph_unlock(periph);
945
cam_periph_release(periph);
946
947
return (error);
948
}
949
950
/*
951
* Actually translate the requested transfer into one the physical driver
952
* can understand. The transfer is described by a buf and will include
953
* only one physical transfer.
954
*/
955
static void
956
sastrategy(struct bio *bp)
957
{
958
struct cam_periph *periph;
959
struct sa_softc *softc;
960
961
bp->bio_resid = bp->bio_bcount;
962
if (SA_IS_CTRL(bp->bio_dev)) {
963
biofinish(bp, NULL, EINVAL);
964
return;
965
}
966
periph = (struct cam_periph *)bp->bio_dev->si_drv1;
967
cam_periph_lock(periph);
968
969
softc = (struct sa_softc *)periph->softc;
970
971
if (softc->flags & SA_FLAG_INVALID) {
972
cam_periph_unlock(periph);
973
biofinish(bp, NULL, ENXIO);
974
return;
975
}
976
977
if (softc->flags & SA_FLAG_TAPE_FROZEN) {
978
cam_periph_unlock(periph);
979
biofinish(bp, NULL, EPERM);
980
return;
981
}
982
983
/*
984
* This should actually never occur as the write(2)
985
* system call traps attempts to write to a read-only
986
* file descriptor.
987
*/
988
if (bp->bio_cmd == BIO_WRITE && softc->open_rdonly) {
989
cam_periph_unlock(periph);
990
biofinish(bp, NULL, EBADF);
991
return;
992
}
993
994
if (softc->open_pending_mount) {
995
int error = samount(periph, 0, bp->bio_dev);
996
if (error) {
997
cam_periph_unlock(periph);
998
biofinish(bp, NULL, ENXIO);
999
return;
1000
}
1001
saprevent(periph, PR_PREVENT);
1002
softc->open_pending_mount = 0;
1003
}
1004
1005
/*
1006
* If it's a null transfer, return immediately
1007
*/
1008
if (bp->bio_bcount == 0) {
1009
cam_periph_unlock(periph);
1010
biodone(bp);
1011
return;
1012
}
1013
1014
/* valid request? */
1015
if (softc->flags & SA_FLAG_FIXED) {
1016
/*
1017
* Fixed block device. The byte count must
1018
* be a multiple of our block size.
1019
*/
1020
if (((softc->blk_mask != ~0) &&
1021
((bp->bio_bcount & softc->blk_mask) != 0)) ||
1022
((softc->blk_mask == ~0) &&
1023
((bp->bio_bcount % softc->min_blk) != 0))) {
1024
xpt_print(periph->path, "Invalid request. Fixed block "
1025
"device requests must be a multiple of %d bytes\n",
1026
softc->min_blk);
1027
cam_periph_unlock(periph);
1028
biofinish(bp, NULL, EINVAL);
1029
return;
1030
}
1031
} else if ((bp->bio_bcount > softc->max_blk) ||
1032
(bp->bio_bcount < softc->min_blk) ||
1033
(bp->bio_bcount & softc->blk_mask) != 0) {
1034
xpt_print_path(periph->path);
1035
printf("Invalid request. Variable block "
1036
"device requests must be ");
1037
if (softc->blk_mask != 0) {
1038
printf("a multiple of %d ", (0x1 << softc->blk_gran));
1039
}
1040
printf("between %d and %d bytes\n", softc->min_blk,
1041
softc->max_blk);
1042
cam_periph_unlock(periph);
1043
biofinish(bp, NULL, EINVAL);
1044
return;
1045
}
1046
1047
/*
1048
* Place it at the end of the queue.
1049
*/
1050
bioq_insert_tail(&softc->bio_queue, bp);
1051
softc->queue_count++;
1052
#if 0
1053
CAM_DEBUG(periph->path, CAM_DEBUG_INFO,
1054
("sastrategy: queuing a %ld %s byte %s\n", bp->bio_bcount,
1055
(softc->flags & SA_FLAG_FIXED)? "fixed" : "variable",
1056
(bp->bio_cmd == BIO_READ)? "read" : "write"));
1057
#endif
1058
if (softc->queue_count > 1) {
1059
CAM_DEBUG(periph->path, CAM_DEBUG_INFO,
1060
("sastrategy: queue count now %d\n", softc->queue_count));
1061
}
1062
1063
/*
1064
* Schedule ourselves for performing the work.
1065
*/
1066
xpt_schedule(periph, CAM_PRIORITY_NORMAL);
1067
cam_periph_unlock(periph);
1068
1069
return;
1070
}
1071
1072
static int
1073
sasetsili(struct cam_periph *periph, struct mtparamset *ps, int num_params)
1074
{
1075
uint32_t sili_blocksize;
1076
struct sa_softc *softc;
1077
int error;
1078
1079
error = 0;
1080
softc = (struct sa_softc *)periph->softc;
1081
1082
if (ps->value_type != MT_PARAM_SET_SIGNED) {
1083
snprintf(ps->error_str, sizeof(ps->error_str),
1084
"sili is a signed parameter");
1085
goto bailout;
1086
}
1087
if ((ps->value.value_signed < 0)
1088
|| (ps->value.value_signed > 1)) {
1089
snprintf(ps->error_str, sizeof(ps->error_str),
1090
"invalid sili value %jd", (intmax_t)ps->value.value_signed);
1091
goto bailout_error;
1092
}
1093
/*
1094
* We only set the SILI flag in variable block
1095
* mode. You'll get a check condition in fixed
1096
* block mode if things don't line up in any case.
1097
*/
1098
if (softc->flags & SA_FLAG_FIXED) {
1099
snprintf(ps->error_str, sizeof(ps->error_str),
1100
"can't set sili bit in fixed block mode");
1101
goto bailout_error;
1102
}
1103
if (softc->sili == ps->value.value_signed)
1104
goto bailout;
1105
1106
if (ps->value.value_signed == 1)
1107
sili_blocksize = 4;
1108
else
1109
sili_blocksize = 0;
1110
1111
error = sasetparams(periph, SA_PARAM_BLOCKSIZE,
1112
sili_blocksize, 0, 0, SF_QUIET_IR);
1113
if (error != 0) {
1114
snprintf(ps->error_str, sizeof(ps->error_str),
1115
"sasetparams() returned error %d", error);
1116
goto bailout_error;
1117
}
1118
1119
softc->sili = ps->value.value_signed;
1120
1121
bailout:
1122
ps->status = MT_PARAM_STATUS_OK;
1123
return (error);
1124
1125
bailout_error:
1126
ps->status = MT_PARAM_STATUS_ERROR;
1127
if (error == 0)
1128
error = EINVAL;
1129
1130
return (error);
1131
}
1132
1133
static int
1134
saseteotwarn(struct cam_periph *periph, struct mtparamset *ps, int num_params)
1135
{
1136
struct sa_softc *softc;
1137
int error;
1138
1139
error = 0;
1140
softc = (struct sa_softc *)periph->softc;
1141
1142
if (ps->value_type != MT_PARAM_SET_SIGNED) {
1143
snprintf(ps->error_str, sizeof(ps->error_str),
1144
"eot_warn is a signed parameter");
1145
ps->status = MT_PARAM_STATUS_ERROR;
1146
goto bailout;
1147
}
1148
if ((ps->value.value_signed < 0)
1149
|| (ps->value.value_signed > 1)) {
1150
snprintf(ps->error_str, sizeof(ps->error_str),
1151
"invalid eot_warn value %jd\n",
1152
(intmax_t)ps->value.value_signed);
1153
ps->status = MT_PARAM_STATUS_ERROR;
1154
goto bailout;
1155
}
1156
softc->eot_warn = ps->value.value_signed;
1157
ps->status = MT_PARAM_STATUS_OK;
1158
bailout:
1159
if (ps->status != MT_PARAM_STATUS_OK)
1160
error = EINVAL;
1161
1162
return (error);
1163
}
1164
1165
static void
1166
safillprot(struct sa_softc *softc, int *indent, struct sbuf *sb)
1167
{
1168
int tmpint;
1169
1170
SASBADDNODE(sb, *indent, protection);
1171
if (softc->flags & SA_FLAG_PROTECT_SUPP)
1172
tmpint = 1;
1173
else
1174
tmpint = 0;
1175
SASBADDINTDESC(sb, *indent, tmpint, %d, protection_supported,
1176
"Set to 1 if protection information is supported");
1177
1178
if ((tmpint != 0)
1179
&& (softc->prot_info.cur_prot_state.initialized != 0)) {
1180
struct sa_prot_state *prot;
1181
1182
prot = &softc->prot_info.cur_prot_state;
1183
1184
SASBADDUINTDESC(sb, *indent, prot->prot_method, %u,
1185
prot_method, "Current Protection Method");
1186
SASBADDUINTDESC(sb, *indent, prot->pi_length, %u,
1187
pi_length, "Length of Protection Information");
1188
SASBADDUINTDESC(sb, *indent, prot->lbp_w, %u,
1189
lbp_w, "Check Protection on Writes");
1190
SASBADDUINTDESC(sb, *indent, prot->lbp_r, %u,
1191
lbp_r, "Check and Include Protection on Reads");
1192
SASBADDUINTDESC(sb, *indent, prot->rbdp, %u,
1193
rbdp, "Transfer Protection Information for RECOVER "
1194
"BUFFERED DATA command");
1195
}
1196
SASBENDNODE(sb, *indent, protection);
1197
}
1198
1199
static void
1200
sapopulateprots(struct sa_prot_state *cur_state, struct sa_prot_map *new_table,
1201
int table_ents)
1202
{
1203
int i;
1204
1205
bcopy(sa_prot_table, new_table, min(table_ents * sizeof(*new_table),
1206
sizeof(sa_prot_table)));
1207
1208
table_ents = min(table_ents, SA_NUM_PROT_ENTS);
1209
1210
for (i = 0; i < table_ents; i++)
1211
new_table[i].value = (uint32_t *)((uint8_t *)cur_state +
1212
new_table[i].offset);
1213
1214
return;
1215
}
1216
1217
static struct sa_prot_map *
1218
safindprotent(char *name, struct sa_prot_map *table, int table_ents)
1219
{
1220
char *prot_name = "protection.";
1221
int i, prot_len;
1222
1223
prot_len = strlen(prot_name);
1224
1225
/*
1226
* This shouldn't happen, but we check just in case.
1227
*/
1228
if (strncmp(name, prot_name, prot_len) != 0)
1229
goto bailout;
1230
1231
for (i = 0; i < table_ents; i++) {
1232
if (strcmp(&name[prot_len], table[i].name) != 0)
1233
continue;
1234
return (&table[i]);
1235
}
1236
bailout:
1237
return (NULL);
1238
}
1239
1240
static int
1241
sasetprotents(struct cam_periph *periph, struct mtparamset *ps, int num_params)
1242
{
1243
struct sa_softc *softc;
1244
struct sa_prot_map prot_ents[SA_NUM_PROT_ENTS];
1245
struct sa_prot_state new_state;
1246
int error;
1247
int i;
1248
1249
softc = (struct sa_softc *)periph->softc;
1250
error = 0;
1251
1252
/*
1253
* Make sure that this tape drive supports protection information.
1254
* Otherwise we can't set anything.
1255
*/
1256
if ((softc->flags & SA_FLAG_PROTECT_SUPP) == 0) {
1257
snprintf(ps[0].error_str, sizeof(ps[0].error_str),
1258
"Protection information is not supported for this device");
1259
ps[0].status = MT_PARAM_STATUS_ERROR;
1260
goto bailout;
1261
}
1262
1263
/*
1264
* We can't operate with physio(9) splitting enabled, because there
1265
* is no way to insure (especially in variable block mode) that
1266
* what the user writes (with a checksum block at the end) will
1267
* make it into the sa(4) driver intact.
1268
*/
1269
if ((softc->si_flags & SI_NOSPLIT) == 0) {
1270
snprintf(ps[0].error_str, sizeof(ps[0].error_str),
1271
"Protection information cannot be enabled with I/O "
1272
"splitting");
1273
ps[0].status = MT_PARAM_STATUS_ERROR;
1274
goto bailout;
1275
}
1276
1277
/*
1278
* Take the current cached protection state and use that as the
1279
* basis for our new entries.
1280
*/
1281
bcopy(&softc->prot_info.cur_prot_state, &new_state, sizeof(new_state));
1282
1283
/*
1284
* Populate the table mapping property names to pointers into the
1285
* state structure.
1286
*/
1287
sapopulateprots(&new_state, prot_ents, SA_NUM_PROT_ENTS);
1288
1289
/*
1290
* For each parameter the user passed in, make sure the name, type
1291
* and value are valid.
1292
*/
1293
for (i = 0; i < num_params; i++) {
1294
struct sa_prot_map *ent;
1295
1296
ent = safindprotent(ps[i].value_name, prot_ents,
1297
SA_NUM_PROT_ENTS);
1298
if (ent == NULL) {
1299
ps[i].status = MT_PARAM_STATUS_ERROR;
1300
snprintf(ps[i].error_str, sizeof(ps[i].error_str),
1301
"Invalid protection entry name %s",
1302
ps[i].value_name);
1303
error = EINVAL;
1304
goto bailout;
1305
}
1306
if (ent->param_type != ps[i].value_type) {
1307
ps[i].status = MT_PARAM_STATUS_ERROR;
1308
snprintf(ps[i].error_str, sizeof(ps[i].error_str),
1309
"Supplied type %d does not match actual type %d",
1310
ps[i].value_type, ent->param_type);
1311
error = EINVAL;
1312
goto bailout;
1313
}
1314
if ((ps[i].value.value_unsigned < ent->min_val)
1315
|| (ps[i].value.value_unsigned > ent->max_val)) {
1316
ps[i].status = MT_PARAM_STATUS_ERROR;
1317
snprintf(ps[i].error_str, sizeof(ps[i].error_str),
1318
"Value %ju is outside valid range %u - %u",
1319
(uintmax_t)ps[i].value.value_unsigned, ent->min_val,
1320
ent->max_val);
1321
error = EINVAL;
1322
goto bailout;
1323
}
1324
*(ent->value) = ps[i].value.value_unsigned;
1325
}
1326
1327
/*
1328
* Actually send the protection settings to the drive.
1329
*/
1330
error = sasetprot(periph, &new_state);
1331
if (error != 0) {
1332
for (i = 0; i < num_params; i++) {
1333
ps[i].status = MT_PARAM_STATUS_ERROR;
1334
snprintf(ps[i].error_str, sizeof(ps[i].error_str),
1335
"Unable to set parameter, see dmesg(8)");
1336
}
1337
goto bailout;
1338
}
1339
1340
/*
1341
* Let the user know that his settings were stored successfully.
1342
*/
1343
for (i = 0; i < num_params; i++)
1344
ps[i].status = MT_PARAM_STATUS_OK;
1345
1346
bailout:
1347
return (error);
1348
}
1349
/*
1350
* Entry handlers generally only handle a single entry. Node handlers will
1351
* handle a contiguous range of parameters to set in a single call.
1352
*/
1353
typedef enum {
1354
SA_PARAM_TYPE_ENTRY,
1355
SA_PARAM_TYPE_NODE
1356
} sa_param_type;
1357
1358
static const struct sa_param_ent {
1359
char *name;
1360
sa_param_type param_type;
1361
int (*set_func)(struct cam_periph *periph, struct mtparamset *ps,
1362
int num_params);
1363
} sa_param_table[] = {
1364
{"sili", SA_PARAM_TYPE_ENTRY, sasetsili },
1365
{"eot_warn", SA_PARAM_TYPE_ENTRY, saseteotwarn },
1366
{"protection.", SA_PARAM_TYPE_NODE, sasetprotents }
1367
};
1368
1369
static const struct sa_param_ent *
1370
safindparament(struct mtparamset *ps)
1371
{
1372
unsigned int i;
1373
1374
for (i = 0; i < nitems(sa_param_table); i++){
1375
/*
1376
* For entries, we compare all of the characters. For
1377
* nodes, we only compare the first N characters. The node
1378
* handler will decode the rest.
1379
*/
1380
if (sa_param_table[i].param_type == SA_PARAM_TYPE_ENTRY) {
1381
if (strcmp(ps->value_name, sa_param_table[i].name) != 0)
1382
continue;
1383
} else {
1384
if (strncmp(ps->value_name, sa_param_table[i].name,
1385
strlen(sa_param_table[i].name)) != 0)
1386
continue;
1387
}
1388
return (&sa_param_table[i]);
1389
}
1390
1391
return (NULL);
1392
}
1393
1394
/*
1395
* Go through a list of parameters, coalescing contiguous parameters with
1396
* the same parent node into a single call to a set_func.
1397
*/
1398
static int
1399
saparamsetlist(struct cam_periph *periph, struct mtsetlist *list,
1400
int need_copy)
1401
{
1402
int i, contig_ents;
1403
int error;
1404
struct mtparamset *params, *first;
1405
const struct sa_param_ent *first_ent;
1406
1407
error = 0;
1408
params = NULL;
1409
1410
if (list->num_params == 0)
1411
/* Nothing to do */
1412
goto bailout;
1413
1414
/*
1415
* Verify that the user has the correct structure size.
1416
*/
1417
if ((list->num_params * sizeof(struct mtparamset)) !=
1418
list->param_len) {
1419
xpt_print(periph->path, "%s: length of params %d != "
1420
"sizeof(struct mtparamset) %zd * num_params %d\n",
1421
__func__, list->param_len, sizeof(struct mtparamset),
1422
list->num_params);
1423
error = EINVAL;
1424
goto bailout;
1425
}
1426
1427
if (need_copy != 0) {
1428
/*
1429
* XXX KDM will dropping the lock cause an issue here?
1430
*/
1431
cam_periph_unlock(periph);
1432
params = malloc(list->param_len, M_SCSISA, M_WAITOK | M_ZERO);
1433
error = copyin(list->params, params, list->param_len);
1434
cam_periph_lock(periph);
1435
1436
if (error != 0)
1437
goto bailout;
1438
} else {
1439
params = list->params;
1440
}
1441
1442
contig_ents = 0;
1443
first = NULL;
1444
first_ent = NULL;
1445
for (i = 0; i < list->num_params; i++) {
1446
const struct sa_param_ent *ent;
1447
1448
ent = safindparament(&params[i]);
1449
if (ent == NULL) {
1450
snprintf(params[i].error_str,
1451
sizeof(params[i].error_str),
1452
"%s: cannot find parameter %s", __func__,
1453
params[i].value_name);
1454
params[i].status = MT_PARAM_STATUS_ERROR;
1455
break;
1456
}
1457
1458
if (first != NULL) {
1459
if (first_ent == ent) {
1460
/*
1461
* We're still in a contiguous list of
1462
* parameters that can be handled by one
1463
* node handler.
1464
*/
1465
contig_ents++;
1466
continue;
1467
} else {
1468
error = first_ent->set_func(periph, first,
1469
contig_ents);
1470
first = NULL;
1471
first_ent = NULL;
1472
contig_ents = 0;
1473
if (error != 0) {
1474
error = 0;
1475
break;
1476
}
1477
}
1478
}
1479
if (ent->param_type == SA_PARAM_TYPE_NODE) {
1480
first = &params[i];
1481
first_ent = ent;
1482
contig_ents = 1;
1483
} else {
1484
error = ent->set_func(periph, &params[i], 1);
1485
if (error != 0) {
1486
error = 0;
1487
break;
1488
}
1489
}
1490
}
1491
if (first != NULL)
1492
first_ent->set_func(periph, first, contig_ents);
1493
1494
bailout:
1495
if (need_copy != 0) {
1496
if (error != EFAULT) {
1497
int error1;
1498
1499
cam_periph_unlock(periph);
1500
error1 = copyout(params, list->params, list->param_len);
1501
if (error == 0)
1502
error = error1;
1503
cam_periph_lock(periph);
1504
}
1505
free(params, M_SCSISA);
1506
}
1507
return (error);
1508
}
1509
1510
static int
1511
sagetparams_common(struct cdev *dev, struct cam_periph *periph)
1512
{
1513
struct sa_softc *softc;
1514
uint8_t write_protect;
1515
int comp_enabled, comp_supported, error;
1516
1517
softc = (struct sa_softc *)periph->softc;
1518
1519
if (softc->open_pending_mount)
1520
return (0);
1521
1522
/* The control device may issue getparams() if there are no opens. */
1523
if (SA_IS_CTRL(dev) && (softc->flags & SA_FLAG_OPEN) != 0)
1524
return (0);
1525
1526
error = sagetparams(periph, SA_PARAM_ALL, &softc->media_blksize,
1527
&softc->media_density, &softc->media_numblks, &softc->buffer_mode,
1528
&write_protect, &softc->speed, &comp_supported, &comp_enabled,
1529
&softc->comp_algorithm, NULL, NULL, 0, 0);
1530
if (error)
1531
return (error);
1532
if (write_protect)
1533
softc->flags |= SA_FLAG_TAPE_WP;
1534
else
1535
softc->flags &= ~SA_FLAG_TAPE_WP;
1536
softc->flags &= ~SA_FLAG_COMPRESSION;
1537
if (comp_supported) {
1538
if (softc->saved_comp_algorithm == 0)
1539
softc->saved_comp_algorithm =
1540
softc->comp_algorithm;
1541
softc->flags |= SA_FLAG_COMP_SUPP;
1542
if (comp_enabled)
1543
softc->flags |= SA_FLAG_COMP_ENABLED;
1544
} else
1545
softc->flags |= SA_FLAG_COMP_UNSUPP;
1546
1547
return (0);
1548
}
1549
1550
#define PENDING_MOUNT_CHECK(softc, periph, dev) \
1551
if (softc->open_pending_mount) { \
1552
error = samount(periph, 0, dev); \
1553
if (error) { \
1554
break; \
1555
} \
1556
saprevent(periph, PR_PREVENT); \
1557
softc->open_pending_mount = 0; \
1558
}
1559
1560
static int
1561
saioctl(struct cdev *dev, u_long cmd, caddr_t arg, int flag, struct thread *td)
1562
{
1563
struct cam_periph *periph;
1564
struct sa_softc *softc;
1565
scsi_space_code spaceop;
1566
int didlockperiph = 0;
1567
int mode;
1568
int error = 0;
1569
1570
mode = SAMODE(dev);
1571
error = 0; /* shut up gcc */
1572
spaceop = 0; /* shut up gcc */
1573
1574
periph = (struct cam_periph *)dev->si_drv1;
1575
cam_periph_lock(periph);
1576
softc = (struct sa_softc *)periph->softc;
1577
1578
/*
1579
* Check for control mode accesses. We allow MTIOCGET and
1580
* MTIOCERRSTAT (but need to be the only one open in order
1581
* to clear latched status), and MTSETBSIZE, MTSETDNSTY
1582
* and MTCOMP (but need to be the only one accessing this
1583
* device to run those).
1584
*/
1585
1586
if (SA_IS_CTRL(dev)) {
1587
switch (cmd) {
1588
case MTIOCGETEOTMODEL:
1589
case MTIOCGET:
1590
case MTIOCEXTGET:
1591
case MTIOCPARAMGET:
1592
case MTIOCRBLIM:
1593
break;
1594
case MTIOCERRSTAT:
1595
/*
1596
* If the periph isn't already locked, lock it
1597
* so our MTIOCERRSTAT can reset latched error stats.
1598
*
1599
* If the periph is already locked, skip it because
1600
* we're just getting status and it'll be up to the
1601
* other thread that has this device open to do
1602
* an MTIOCERRSTAT that would clear latched status.
1603
*/
1604
if ((periph->flags & CAM_PERIPH_LOCKED) == 0) {
1605
error = cam_periph_hold(periph, PRIBIO|PCATCH);
1606
if (error != 0) {
1607
cam_periph_unlock(periph);
1608
return (error);
1609
}
1610
didlockperiph = 1;
1611
}
1612
break;
1613
1614
case MTIOCTOP:
1615
{
1616
struct mtop *mt = (struct mtop *) arg;
1617
1618
/*
1619
* Check to make sure it's an OP we can perform
1620
* with no media inserted.
1621
*/
1622
switch (mt->mt_op) {
1623
case MTSETBSIZ:
1624
case MTSETDNSTY:
1625
case MTCOMP:
1626
mt = NULL;
1627
/* FALLTHROUGH */
1628
default:
1629
break;
1630
}
1631
if (mt != NULL) {
1632
break;
1633
}
1634
/* FALLTHROUGH */
1635
}
1636
case MTIOCSETEOTMODEL:
1637
/*
1638
* We need to acquire the peripheral here rather
1639
* than at open time because we are sharing writable
1640
* access to data structures.
1641
*/
1642
error = cam_periph_hold(periph, PRIBIO|PCATCH);
1643
if (error != 0) {
1644
cam_periph_unlock(periph);
1645
return (error);
1646
}
1647
didlockperiph = 1;
1648
break;
1649
1650
default:
1651
cam_periph_unlock(periph);
1652
return (EINVAL);
1653
}
1654
}
1655
1656
/*
1657
* Find the device that the user is talking about
1658
*/
1659
switch (cmd) {
1660
case MTIOCGET:
1661
{
1662
struct mtget *g = (struct mtget *)arg;
1663
1664
error = sagetparams_common(dev, periph);
1665
if (error)
1666
break;
1667
bzero(g, sizeof(struct mtget));
1668
g->mt_type = MT_ISAR;
1669
if (softc->flags & SA_FLAG_COMP_UNSUPP) {
1670
g->mt_comp = MT_COMP_UNSUPP;
1671
g->mt_comp0 = MT_COMP_UNSUPP;
1672
g->mt_comp1 = MT_COMP_UNSUPP;
1673
g->mt_comp2 = MT_COMP_UNSUPP;
1674
g->mt_comp3 = MT_COMP_UNSUPP;
1675
} else {
1676
if ((softc->flags & SA_FLAG_COMP_ENABLED) == 0) {
1677
g->mt_comp = MT_COMP_DISABLED;
1678
} else {
1679
g->mt_comp = softc->comp_algorithm;
1680
}
1681
g->mt_comp0 = softc->comp_algorithm;
1682
g->mt_comp1 = softc->comp_algorithm;
1683
g->mt_comp2 = softc->comp_algorithm;
1684
g->mt_comp3 = softc->comp_algorithm;
1685
}
1686
g->mt_density = softc->media_density;
1687
g->mt_density0 = softc->media_density;
1688
g->mt_density1 = softc->media_density;
1689
g->mt_density2 = softc->media_density;
1690
g->mt_density3 = softc->media_density;
1691
g->mt_blksiz = softc->media_blksize;
1692
g->mt_blksiz0 = softc->media_blksize;
1693
g->mt_blksiz1 = softc->media_blksize;
1694
g->mt_blksiz2 = softc->media_blksize;
1695
g->mt_blksiz3 = softc->media_blksize;
1696
g->mt_fileno = softc->fileno;
1697
g->mt_blkno = softc->blkno;
1698
g->mt_dsreg = (short) softc->dsreg;
1699
/*
1700
* Yes, we know that this is likely to overflow
1701
*/
1702
if (softc->last_resid_was_io) {
1703
if ((g->mt_resid = (short) softc->last_io_resid) != 0) {
1704
if (SA_IS_CTRL(dev) == 0 || didlockperiph) {
1705
softc->last_io_resid = 0;
1706
}
1707
}
1708
} else {
1709
if ((g->mt_resid = (short)softc->last_ctl_resid) != 0) {
1710
if (SA_IS_CTRL(dev) == 0 || didlockperiph) {
1711
softc->last_ctl_resid = 0;
1712
}
1713
}
1714
}
1715
error = 0;
1716
break;
1717
}
1718
case MTIOCEXTGET:
1719
case MTIOCPARAMGET:
1720
{
1721
struct mtextget *g = (struct mtextget *)arg;
1722
char *tmpstr2;
1723
struct sbuf *sb;
1724
1725
/*
1726
* Report drive status using an XML format.
1727
*/
1728
1729
/*
1730
* XXX KDM will dropping the lock cause any problems here?
1731
*/
1732
cam_periph_unlock(periph);
1733
sb = sbuf_new(NULL, NULL, g->alloc_len, SBUF_FIXEDLEN);
1734
if (sb == NULL) {
1735
g->status = MT_EXT_GET_ERROR;
1736
snprintf(g->error_str, sizeof(g->error_str),
1737
"Unable to allocate %d bytes for status info",
1738
g->alloc_len);
1739
cam_periph_lock(periph);
1740
goto extget_bailout;
1741
}
1742
cam_periph_lock(periph);
1743
1744
if (cmd == MTIOCEXTGET)
1745
error = saextget(dev, periph, sb, g);
1746
else
1747
error = saparamget(softc, sb);
1748
1749
if (error != 0)
1750
goto extget_bailout;
1751
1752
error = sbuf_finish(sb);
1753
if (error == ENOMEM) {
1754
g->status = MT_EXT_GET_NEED_MORE_SPACE;
1755
error = 0;
1756
} else if (error != 0) {
1757
g->status = MT_EXT_GET_ERROR;
1758
snprintf(g->error_str, sizeof(g->error_str),
1759
"Error %d returned from sbuf_finish()", error);
1760
} else
1761
g->status = MT_EXT_GET_OK;
1762
1763
error = 0;
1764
tmpstr2 = sbuf_data(sb);
1765
g->fill_len = strlen(tmpstr2) + 1;
1766
cam_periph_unlock(periph);
1767
1768
error = copyout(tmpstr2, g->status_xml, g->fill_len);
1769
1770
cam_periph_lock(periph);
1771
1772
extget_bailout:
1773
sbuf_delete(sb);
1774
break;
1775
}
1776
case MTIOCPARAMSET:
1777
{
1778
struct mtsetlist list;
1779
struct mtparamset *ps = (struct mtparamset *)arg;
1780
1781
bzero(&list, sizeof(list));
1782
list.num_params = 1;
1783
list.param_len = sizeof(*ps);
1784
list.params = ps;
1785
1786
error = saparamsetlist(periph, &list, /*need_copy*/ 0);
1787
break;
1788
}
1789
case MTIOCSETLIST:
1790
{
1791
struct mtsetlist *list = (struct mtsetlist *)arg;
1792
1793
error = saparamsetlist(periph, list, /*need_copy*/ 1);
1794
break;
1795
}
1796
case MTIOCERRSTAT:
1797
{
1798
struct scsi_tape_errors *sep =
1799
&((union mterrstat *)arg)->scsi_errstat;
1800
1801
CAM_DEBUG(periph->path, CAM_DEBUG_TRACE,
1802
("saioctl: MTIOCERRSTAT\n"));
1803
1804
bzero(sep, sizeof(*sep));
1805
sep->io_resid = softc->last_io_resid;
1806
bcopy((caddr_t) &softc->last_io_sense, sep->io_sense,
1807
sizeof (sep->io_sense));
1808
bcopy((caddr_t) &softc->last_io_cdb, sep->io_cdb,
1809
sizeof (sep->io_cdb));
1810
sep->ctl_resid = softc->last_ctl_resid;
1811
bcopy((caddr_t) &softc->last_ctl_sense, sep->ctl_sense,
1812
sizeof (sep->ctl_sense));
1813
bcopy((caddr_t) &softc->last_ctl_cdb, sep->ctl_cdb,
1814
sizeof (sep->ctl_cdb));
1815
1816
if ((SA_IS_CTRL(dev) == 0 && !softc->open_pending_mount) ||
1817
didlockperiph)
1818
bzero((caddr_t) &softc->errinfo,
1819
sizeof (softc->errinfo));
1820
error = 0;
1821
break;
1822
}
1823
case MTIOCTOP:
1824
{
1825
struct mtop *mt;
1826
int count;
1827
1828
PENDING_MOUNT_CHECK(softc, periph, dev);
1829
1830
mt = (struct mtop *)arg;
1831
1832
CAM_DEBUG(periph->path, CAM_DEBUG_TRACE,
1833
("saioctl: op=0x%x count=0x%x\n",
1834
mt->mt_op, mt->mt_count));
1835
1836
count = mt->mt_count;
1837
switch (mt->mt_op) {
1838
case MTWEOF: /* write an end-of-file marker */
1839
/*
1840
* We don't need to clear the SA_FLAG_TAPE_WRITTEN
1841
* flag because by keeping track of filemarks
1842
* we have last written we know whether or not
1843
* we need to write more when we close the device.
1844
*/
1845
error = sawritefilemarks(periph, count, FALSE, FALSE);
1846
break;
1847
case MTWEOFI:
1848
/* write an end-of-file marker without waiting */
1849
error = sawritefilemarks(periph, count, FALSE, TRUE);
1850
break;
1851
case MTWSS: /* write a setmark */
1852
error = sawritefilemarks(periph, count, TRUE, FALSE);
1853
break;
1854
case MTBSR: /* backward space record */
1855
case MTFSR: /* forward space record */
1856
case MTBSF: /* backward space file */
1857
case MTFSF: /* forward space file */
1858
case MTBSS: /* backward space setmark */
1859
case MTFSS: /* forward space setmark */
1860
case MTEOD: /* space to end of recorded medium */
1861
{
1862
int nmarks;
1863
1864
spaceop = SS_FILEMARKS;
1865
nmarks = softc->filemarks;
1866
error = sacheckeod(periph);
1867
if (error) {
1868
xpt_print(periph->path,
1869
"EOD check prior to spacing failed\n");
1870
softc->flags |= SA_FLAG_EIO_PENDING;
1871
break;
1872
}
1873
nmarks -= softc->filemarks;
1874
switch(mt->mt_op) {
1875
case MTBSR:
1876
count = -count;
1877
/* FALLTHROUGH */
1878
case MTFSR:
1879
spaceop = SS_BLOCKS;
1880
break;
1881
case MTBSF:
1882
count = -count;
1883
/* FALLTHROUGH */
1884
case MTFSF:
1885
break;
1886
case MTBSS:
1887
count = -count;
1888
/* FALLTHROUGH */
1889
case MTFSS:
1890
spaceop = SS_SETMARKS;
1891
break;
1892
case MTEOD:
1893
spaceop = SS_EOD;
1894
count = 0;
1895
nmarks = 0;
1896
break;
1897
default:
1898
error = EINVAL;
1899
break;
1900
}
1901
if (error)
1902
break;
1903
1904
nmarks = softc->filemarks;
1905
/*
1906
* XXX: Why are we checking again?
1907
*/
1908
error = sacheckeod(periph);
1909
if (error)
1910
break;
1911
nmarks -= softc->filemarks;
1912
error = saspace(periph, count - nmarks, spaceop);
1913
/*
1914
* At this point, clear that we've written the tape
1915
* and that we've written any filemarks. We really
1916
* don't know what the applications wishes to do next-
1917
* the sacheckeod's will make sure we terminated the
1918
* tape correctly if we'd been writing, but the next
1919
* action the user application takes will set again
1920
* whether we need to write filemarks.
1921
*/
1922
softc->flags &=
1923
~(SA_FLAG_TAPE_WRITTEN|SA_FLAG_TAPE_FROZEN);
1924
softc->filemarks = 0;
1925
break;
1926
}
1927
case MTREW: /* rewind */
1928
PENDING_MOUNT_CHECK(softc, periph, dev);
1929
(void) sacheckeod(periph);
1930
error = sarewind(periph);
1931
/* see above */
1932
softc->flags &=
1933
~(SA_FLAG_TAPE_WRITTEN|SA_FLAG_TAPE_FROZEN);
1934
softc->flags &= ~SA_FLAG_ERR_PENDING;
1935
softc->filemarks = 0;
1936
break;
1937
case MTERASE: /* erase */
1938
PENDING_MOUNT_CHECK(softc, periph, dev);
1939
error = saerase(periph, count);
1940
softc->flags &=
1941
~(SA_FLAG_TAPE_WRITTEN|SA_FLAG_TAPE_FROZEN);
1942
softc->flags &= ~SA_FLAG_ERR_PENDING;
1943
break;
1944
case MTRETENS: /* re-tension tape */
1945
PENDING_MOUNT_CHECK(softc, periph, dev);
1946
error = saretension(periph);
1947
softc->flags &=
1948
~(SA_FLAG_TAPE_WRITTEN|SA_FLAG_TAPE_FROZEN);
1949
softc->flags &= ~SA_FLAG_ERR_PENDING;
1950
break;
1951
case MTOFFL: /* rewind and put the drive offline */
1952
1953
PENDING_MOUNT_CHECK(softc, periph, dev);
1954
1955
(void) sacheckeod(periph);
1956
/* see above */
1957
softc->flags &= ~SA_FLAG_TAPE_WRITTEN;
1958
softc->filemarks = 0;
1959
1960
error = sarewind(periph);
1961
/* clear the frozen flag anyway */
1962
softc->flags &= ~SA_FLAG_TAPE_FROZEN;
1963
1964
/*
1965
* Be sure to allow media removal before ejecting.
1966
*/
1967
1968
saprevent(periph, PR_ALLOW);
1969
if (error == 0) {
1970
error = saloadunload(periph, FALSE);
1971
if (error == 0) {
1972
softc->flags &= ~SA_FLAG_TAPE_MOUNTED;
1973
}
1974
}
1975
break;
1976
1977
case MTLOAD:
1978
error = saloadunload(periph, TRUE);
1979
break;
1980
case MTNOP: /* no operation, sets status only */
1981
case MTCACHE: /* enable controller cache */
1982
case MTNOCACHE: /* disable controller cache */
1983
error = 0;
1984
break;
1985
1986
case MTSETBSIZ: /* Set block size for device */
1987
1988
PENDING_MOUNT_CHECK(softc, periph, dev);
1989
1990
if ((softc->sili != 0)
1991
&& (count != 0)) {
1992
xpt_print(periph->path, "Can't enter fixed "
1993
"block mode with SILI enabled\n");
1994
error = EINVAL;
1995
break;
1996
}
1997
error = sasetparams(periph, SA_PARAM_BLOCKSIZE, count,
1998
0, 0, 0);
1999
if (error == 0) {
2000
softc->last_media_blksize =
2001
softc->media_blksize;
2002
softc->media_blksize = count;
2003
if (count) {
2004
softc->flags |= SA_FLAG_FIXED;
2005
if (powerof2(count)) {
2006
softc->blk_shift =
2007
ffs(count) - 1;
2008
softc->blk_mask = count - 1;
2009
} else {
2010
softc->blk_mask = ~0;
2011
softc->blk_shift = 0;
2012
}
2013
/*
2014
* Make the user's desire 'persistent'.
2015
*/
2016
softc->quirks &= ~SA_QUIRK_VARIABLE;
2017
softc->quirks |= SA_QUIRK_FIXED;
2018
} else {
2019
softc->flags &= ~SA_FLAG_FIXED;
2020
if (softc->max_blk == 0) {
2021
softc->max_blk = ~0;
2022
}
2023
softc->blk_shift = 0;
2024
if (softc->blk_gran != 0) {
2025
softc->blk_mask =
2026
softc->blk_gran - 1;
2027
} else {
2028
softc->blk_mask = 0;
2029
}
2030
/*
2031
* Make the user's desire 'persistent'.
2032
*/
2033
softc->quirks |= SA_QUIRK_VARIABLE;
2034
softc->quirks &= ~SA_QUIRK_FIXED;
2035
}
2036
}
2037
break;
2038
case MTSETDNSTY: /* Set density for device and mode */
2039
PENDING_MOUNT_CHECK(softc, periph, dev);
2040
2041
if (count > UCHAR_MAX) {
2042
error = EINVAL;
2043
break;
2044
} else {
2045
error = sasetparams(periph, SA_PARAM_DENSITY,
2046
0, count, 0, 0);
2047
}
2048
break;
2049
case MTCOMP: /* enable compression */
2050
PENDING_MOUNT_CHECK(softc, periph, dev);
2051
/*
2052
* Some devices don't support compression, and
2053
* don't like it if you ask them for the
2054
* compression page.
2055
*/
2056
if ((softc->quirks & SA_QUIRK_NOCOMP) ||
2057
(softc->flags & SA_FLAG_COMP_UNSUPP)) {
2058
error = ENODEV;
2059
break;
2060
}
2061
error = sasetparams(periph, SA_PARAM_COMPRESSION,
2062
0, 0, count, SF_NO_PRINT);
2063
break;
2064
default:
2065
error = EINVAL;
2066
}
2067
break;
2068
}
2069
case MTIOCIEOT:
2070
case MTIOCEEOT:
2071
error = 0;
2072
break;
2073
case MTIOCRDSPOS:
2074
PENDING_MOUNT_CHECK(softc, periph, dev);
2075
error = sardpos(periph, 0, (uint32_t *) arg);
2076
break;
2077
case MTIOCRDHPOS:
2078
PENDING_MOUNT_CHECK(softc, periph, dev);
2079
error = sardpos(periph, 1, (uint32_t *) arg);
2080
break;
2081
case MTIOCSLOCATE:
2082
case MTIOCHLOCATE: {
2083
struct mtlocate locate_info;
2084
int hard;
2085
2086
bzero(&locate_info, sizeof(locate_info));
2087
locate_info.logical_id = *((uint32_t *)arg);
2088
if (cmd == MTIOCSLOCATE)
2089
hard = 0;
2090
else
2091
hard = 1;
2092
2093
PENDING_MOUNT_CHECK(softc, periph, dev);
2094
2095
error = sasetpos(periph, hard, &locate_info);
2096
break;
2097
}
2098
case MTIOCEXTLOCATE:
2099
PENDING_MOUNT_CHECK(softc, periph, dev);
2100
error = sasetpos(periph, /*hard*/ 0, (struct mtlocate *)arg);
2101
softc->flags &=
2102
~(SA_FLAG_TAPE_WRITTEN|SA_FLAG_TAPE_FROZEN);
2103
softc->flags &= ~SA_FLAG_ERR_PENDING;
2104
softc->filemarks = 0;
2105
break;
2106
case MTIOCGETEOTMODEL:
2107
error = 0;
2108
if (softc->quirks & SA_QUIRK_1FM)
2109
mode = 1;
2110
else
2111
mode = 2;
2112
*((uint32_t *) arg) = mode;
2113
break;
2114
case MTIOCSETEOTMODEL:
2115
error = 0;
2116
switch (*((uint32_t *) arg)) {
2117
case 1:
2118
softc->quirks &= ~SA_QUIRK_2FM;
2119
softc->quirks |= SA_QUIRK_1FM;
2120
break;
2121
case 2:
2122
softc->quirks &= ~SA_QUIRK_1FM;
2123
softc->quirks |= SA_QUIRK_2FM;
2124
break;
2125
default:
2126
error = EINVAL;
2127
break;
2128
}
2129
break;
2130
case MTIOCRBLIM: {
2131
struct mtrblim *rblim;
2132
2133
rblim = (struct mtrblim *)arg;
2134
2135
rblim->granularity = softc->blk_gran;
2136
rblim->min_block_length = softc->min_blk;
2137
rblim->max_block_length = softc->max_blk;
2138
break;
2139
}
2140
default:
2141
error = cam_periph_ioctl(periph, cmd, arg, saerror);
2142
break;
2143
}
2144
2145
/*
2146
* Check to see if we cleared a frozen state
2147
*/
2148
if (error == 0 && (softc->flags & SA_FLAG_TAPE_FROZEN)) {
2149
switch(cmd) {
2150
case MTIOCRDSPOS:
2151
case MTIOCRDHPOS:
2152
case MTIOCSLOCATE:
2153
case MTIOCHLOCATE:
2154
/*
2155
* XXX KDM look at this.
2156
*/
2157
softc->fileno = (daddr_t) -1;
2158
softc->blkno = (daddr_t) -1;
2159
softc->rep_blkno = (daddr_t) -1;
2160
softc->rep_fileno = (daddr_t) -1;
2161
softc->partition = (daddr_t) -1;
2162
softc->flags &= ~SA_FLAG_TAPE_FROZEN;
2163
xpt_print(periph->path,
2164
"tape state now unfrozen.\n");
2165
break;
2166
default:
2167
break;
2168
}
2169
}
2170
if (didlockperiph) {
2171
cam_periph_unhold(periph);
2172
}
2173
cam_periph_unlock(periph);
2174
return (error);
2175
}
2176
2177
static void
2178
sainit(void)
2179
{
2180
cam_status status;
2181
2182
/*
2183
* Install a global async callback.
2184
*/
2185
status = xpt_register_async(AC_FOUND_DEVICE, saasync, NULL, NULL);
2186
2187
if (status != CAM_REQ_CMP) {
2188
printf("sa: Failed to attach master async callback "
2189
"due to status 0x%x!\n", status);
2190
}
2191
}
2192
2193
static void
2194
sadevgonecb(void *arg)
2195
{
2196
struct cam_periph *periph;
2197
struct mtx *mtx;
2198
struct sa_softc *softc;
2199
2200
periph = (struct cam_periph *)arg;
2201
softc = (struct sa_softc *)periph->softc;
2202
2203
mtx = cam_periph_mtx(periph);
2204
mtx_lock(mtx);
2205
2206
softc->num_devs_to_destroy--;
2207
if (softc->num_devs_to_destroy == 0) {
2208
int i;
2209
2210
/*
2211
* When we have gotten all of our callbacks, we will get
2212
* no more close calls from devfs. So if we have any
2213
* dangling opens, we need to release the reference held
2214
* for that particular context.
2215
*/
2216
for (i = 0; i < softc->open_count; i++)
2217
cam_periph_release_locked(periph);
2218
2219
softc->open_count = 0;
2220
2221
/*
2222
* Release the reference held for devfs, all of our
2223
* instances are gone now.
2224
*/
2225
cam_periph_release_locked(periph);
2226
}
2227
2228
/*
2229
* We reference the lock directly here, instead of using
2230
* cam_periph_unlock(). The reason is that the final call to
2231
* cam_periph_release_locked() above could result in the periph
2232
* getting freed. If that is the case, dereferencing the periph
2233
* with a cam_periph_unlock() call would cause a page fault.
2234
*/
2235
mtx_unlock(mtx);
2236
}
2237
2238
static void
2239
saoninvalidate(struct cam_periph *periph)
2240
{
2241
struct sa_softc *softc;
2242
2243
softc = (struct sa_softc *)periph->softc;
2244
2245
/*
2246
* De-register any async callbacks.
2247
*/
2248
xpt_register_async(0, saasync, periph, periph->path);
2249
2250
softc->flags |= SA_FLAG_INVALID;
2251
2252
/*
2253
* Return all queued I/O with ENXIO.
2254
* XXX Handle any transactions queued to the card
2255
* with XPT_ABORT_CCB.
2256
*/
2257
bioq_flush(&softc->bio_queue, NULL, ENXIO);
2258
softc->queue_count = 0;
2259
2260
/*
2261
* Tell devfs that all of our devices have gone away, and ask for a
2262
* callback when it has cleaned up its state.
2263
*/
2264
destroy_dev_sched_cb(softc->devs.ctl_dev, sadevgonecb, periph);
2265
destroy_dev_sched_cb(softc->devs.r_dev, sadevgonecb, periph);
2266
destroy_dev_sched_cb(softc->devs.nr_dev, sadevgonecb, periph);
2267
destroy_dev_sched_cb(softc->devs.er_dev, sadevgonecb, periph);
2268
}
2269
2270
static void
2271
sacleanup(struct cam_periph *periph)
2272
{
2273
struct sa_softc *softc;
2274
2275
softc = (struct sa_softc *)periph->softc;
2276
2277
cam_periph_unlock(periph);
2278
2279
if ((softc->flags & SA_FLAG_SCTX_INIT) != 0
2280
&& (((softc->sysctl_timeout_tree != NULL)
2281
&& (sysctl_ctx_free(&softc->sysctl_timeout_ctx) != 0))
2282
|| sysctl_ctx_free(&softc->sysctl_ctx) != 0))
2283
xpt_print(periph->path, "can't remove sysctl context\n");
2284
2285
cam_periph_lock(periph);
2286
2287
devstat_remove_entry(softc->device_stats);
2288
2289
free(softc, M_SCSISA);
2290
}
2291
2292
static void
2293
saasync(void *callback_arg, uint32_t code,
2294
struct cam_path *path, void *arg)
2295
{
2296
struct cam_periph *periph;
2297
2298
periph = (struct cam_periph *)callback_arg;
2299
switch (code) {
2300
case AC_FOUND_DEVICE:
2301
{
2302
struct ccb_getdev *cgd;
2303
cam_status status;
2304
2305
cgd = (struct ccb_getdev *)arg;
2306
if (cgd == NULL)
2307
break;
2308
2309
if (cgd->protocol != PROTO_SCSI)
2310
break;
2311
if (SID_QUAL(&cgd->inq_data) != SID_QUAL_LU_CONNECTED)
2312
break;
2313
if (SID_TYPE(&cgd->inq_data) != T_SEQUENTIAL)
2314
break;
2315
2316
/*
2317
* Allocate a peripheral instance for
2318
* this device and start the probe
2319
* process.
2320
*/
2321
status = cam_periph_alloc(saregister, saoninvalidate,
2322
sacleanup, sastart,
2323
"sa", CAM_PERIPH_BIO, path,
2324
saasync, AC_FOUND_DEVICE, cgd);
2325
2326
if (status != CAM_REQ_CMP
2327
&& status != CAM_REQ_INPROG)
2328
printf("saasync: Unable to probe new device "
2329
"due to status 0x%x\n", status);
2330
break;
2331
}
2332
default:
2333
cam_periph_async(periph, code, path, arg);
2334
break;
2335
}
2336
}
2337
2338
static void
2339
sasetupdev(struct sa_softc *softc, struct cdev *dev)
2340
{
2341
2342
dev->si_iosize_max = softc->maxio;
2343
dev->si_flags |= softc->si_flags;
2344
/*
2345
* Keep a count of how many non-alias devices we have created,
2346
* so we can make sure we clean them all up on shutdown. Aliases
2347
* are cleaned up when we destroy the device they're an alias for.
2348
*/
2349
if ((dev->si_flags & SI_ALIAS) == 0)
2350
softc->num_devs_to_destroy++;
2351
}
2352
2353
/*
2354
* Load the global (for all sa(4) instances) and per-instance tunable
2355
* values for timeouts for various sa(4) commands. This should be run
2356
* after the default timeouts are fetched from the drive, so the user's
2357
* preference will override the drive's defaults.
2358
*/
2359
static void
2360
saloadtotunables(struct sa_softc *softc)
2361
{
2362
int i;
2363
char tmpstr[80];
2364
2365
for (i = 0; i < SA_TIMEOUT_TYPE_MAX; i++) {
2366
int tmpval, retval;
2367
2368
/* First grab any global timeout setting */
2369
snprintf(tmpstr, sizeof(tmpstr), "kern.cam.sa.timeout.%s",
2370
sa_default_timeouts[i].desc);
2371
retval = TUNABLE_INT_FETCH(tmpstr, &tmpval);
2372
if (retval != 0)
2373
softc->timeout_info[i] = tmpval;
2374
2375
/*
2376
* Then overwrite any global timeout settings with
2377
* per-instance timeout settings.
2378
*/
2379
snprintf(tmpstr, sizeof(tmpstr), "kern.cam.sa.%u.timeout.%s",
2380
softc->periph->unit_number, sa_default_timeouts[i].desc);
2381
retval = TUNABLE_INT_FETCH(tmpstr, &tmpval);
2382
if (retval != 0)
2383
softc->timeout_info[i] = tmpval;
2384
}
2385
}
2386
2387
static void
2388
sasysctlinit(void *context, int pending)
2389
{
2390
struct cam_periph *periph;
2391
struct sa_softc *softc;
2392
char tmpstr[64], tmpstr2[16];
2393
int i;
2394
2395
periph = (struct cam_periph *)context;
2396
/*
2397
* If the periph is invalid, no need to setup the sysctls.
2398
*/
2399
if (periph->flags & CAM_PERIPH_INVALID)
2400
goto bailout;
2401
2402
softc = (struct sa_softc *)periph->softc;
2403
2404
snprintf(tmpstr, sizeof(tmpstr), "CAM SA unit %d", periph->unit_number);
2405
snprintf(tmpstr2, sizeof(tmpstr2), "%u", periph->unit_number);
2406
2407
sysctl_ctx_init(&softc->sysctl_ctx);
2408
softc->flags |= SA_FLAG_SCTX_INIT;
2409
softc->sysctl_tree = SYSCTL_ADD_NODE_WITH_LABEL(&softc->sysctl_ctx,
2410
SYSCTL_STATIC_CHILDREN(_kern_cam_sa), OID_AUTO, tmpstr2,
2411
CTLFLAG_RD | CTLFLAG_MPSAFE, 0, tmpstr, "device_index");
2412
if (softc->sysctl_tree == NULL)
2413
goto bailout;
2414
2415
SYSCTL_ADD_INT(&softc->sysctl_ctx, SYSCTL_CHILDREN(softc->sysctl_tree),
2416
OID_AUTO, "allow_io_split", CTLFLAG_RDTUN | CTLFLAG_NOFETCH,
2417
&softc->allow_io_split, 0, "Allow Splitting I/O");
2418
SYSCTL_ADD_INT(&softc->sysctl_ctx, SYSCTL_CHILDREN(softc->sysctl_tree),
2419
OID_AUTO, "maxio", CTLFLAG_RD,
2420
&softc->maxio, 0, "Maximum I/O size");
2421
SYSCTL_ADD_INT(&softc->sysctl_ctx, SYSCTL_CHILDREN(softc->sysctl_tree),
2422
OID_AUTO, "cpi_maxio", CTLFLAG_RD,
2423
&softc->cpi_maxio, 0, "Maximum Controller I/O size");
2424
SYSCTL_ADD_INT(&softc->sysctl_ctx, SYSCTL_CHILDREN(softc->sysctl_tree),
2425
OID_AUTO, "inject_eom", CTLFLAG_RW,
2426
&softc->inject_eom, 0, "Queue EOM for the next write/read");
2427
2428
sysctl_ctx_init(&softc->sysctl_timeout_ctx);
2429
softc->sysctl_timeout_tree = SYSCTL_ADD_NODE(&softc->sysctl_timeout_ctx,
2430
SYSCTL_CHILDREN(softc->sysctl_tree), OID_AUTO, "timeout",
2431
CTLFLAG_RD | CTLFLAG_MPSAFE, 0, "Timeouts");
2432
if (softc->sysctl_timeout_tree == NULL)
2433
goto bailout;
2434
2435
for (i = 0; i < SA_TIMEOUT_TYPE_MAX; i++) {
2436
snprintf(tmpstr, sizeof(tmpstr), "%s timeout",
2437
sa_default_timeouts[i].desc);
2438
2439
/*
2440
* Do NOT change this sysctl declaration to also load any
2441
* tunable values for this sa(4) instance. In other words,
2442
* do not change this to CTLFLAG_RWTUN. This function is
2443
* run in parallel with the probe routine that fetches
2444
* recommended timeout values from the tape drive, and we
2445
* don't want the values from the drive to override the
2446
* user's preference.
2447
*/
2448
SYSCTL_ADD_INT(&softc->sysctl_timeout_ctx,
2449
SYSCTL_CHILDREN(softc->sysctl_timeout_tree),
2450
OID_AUTO, sa_default_timeouts[i].desc, CTLFLAG_RW,
2451
&softc->timeout_info[i], 0, tmpstr);
2452
}
2453
2454
bailout:
2455
/*
2456
* Release the reference that was held when this task was enqueued.
2457
*/
2458
cam_periph_release(periph);
2459
}
2460
2461
static cam_status
2462
saregister(struct cam_periph *periph, void *arg)
2463
{
2464
struct sa_softc *softc;
2465
struct ccb_getdev *cgd;
2466
struct ccb_pathinq cpi;
2467
struct make_dev_args args;
2468
caddr_t match;
2469
char tmpstr[80];
2470
int error;
2471
int i;
2472
2473
cgd = (struct ccb_getdev *)arg;
2474
if (cgd == NULL) {
2475
printf("saregister: no getdev CCB, can't register device\n");
2476
return (CAM_REQ_CMP_ERR);
2477
}
2478
2479
softc = (struct sa_softc *)
2480
malloc(sizeof (*softc), M_SCSISA, M_NOWAIT | M_ZERO);
2481
if (softc == NULL) {
2482
printf("saregister: Unable to probe new device. "
2483
"Unable to allocate softc\n");
2484
return (CAM_REQ_CMP_ERR);
2485
}
2486
softc->scsi_rev = SID_ANSI_REV(&cgd->inq_data);
2487
softc->state = SA_STATE_NORMAL;
2488
softc->fileno = (daddr_t) -1;
2489
softc->blkno = (daddr_t) -1;
2490
softc->rep_fileno = (daddr_t) -1;
2491
softc->rep_blkno = (daddr_t) -1;
2492
softc->partition = (daddr_t) -1;
2493
softc->bop = -1;
2494
softc->eop = -1;
2495
softc->bpew = -1;
2496
2497
bioq_init(&softc->bio_queue);
2498
softc->periph = periph;
2499
periph->softc = softc;
2500
2501
/*
2502
* See if this device has any quirks.
2503
*/
2504
match = cam_quirkmatch((caddr_t)&cgd->inq_data,
2505
(caddr_t)sa_quirk_table,
2506
nitems(sa_quirk_table),
2507
sizeof(*sa_quirk_table), scsi_inquiry_match);
2508
2509
if (match != NULL) {
2510
softc->quirks = ((struct sa_quirk_entry *)match)->quirks;
2511
softc->last_media_blksize =
2512
((struct sa_quirk_entry *)match)->prefblk;
2513
} else
2514
softc->quirks = SA_QUIRK_NONE;
2515
2516
2517
/*
2518
* Initialize the default timeouts. If this drive supports
2519
* timeout descriptors we'll overwrite these values with the
2520
* recommended timeouts from the drive.
2521
*/
2522
for (i = 0; i < SA_TIMEOUT_TYPE_MAX; i++)
2523
softc->timeout_info[i] = sa_default_timeouts[i].value;
2524
2525
/*
2526
* Long format data for READ POSITION was introduced in SSC, which
2527
* was after SCSI-2. (Roughly equivalent to SCSI-3.) If the drive
2528
* reports that it is SCSI-2 or older, it is unlikely to support
2529
* long position data, but it might. Some drives from that era
2530
* claim to be SCSI-2, but do support long position information.
2531
* So, instead of immediately disabling long position information
2532
* for SCSI-2 devices, we'll try one pass through sagetpos(), and
2533
* then disable long position information if we get an error.
2534
*/
2535
if (cgd->inq_data.version <= SCSI_REV_CCS)
2536
softc->quirks |= SA_QUIRK_NO_LONG_POS;
2537
2538
/*
2539
* The SCSI REPORT SUPPORTED OPERATION CODES command was added in
2540
* SPC-4. That command optionally includes timeout data for
2541
* different commands. Timeout values can vary wildly among
2542
* different drives, so if the drive itself has recommended values,
2543
* we will try to use them. Set this flag to indicate we're going
2544
* to ask the drive for timeout data. This flag also tells us to
2545
* wait on loading timeout tunables so we can properly override
2546
* timeouts with any user-specified values.
2547
*/
2548
if (SID_ANSI_REV(&cgd->inq_data) >= SCSI_REV_SPC4)
2549
softc->flags |= SA_FLAG_RSOC_TO_TRY;
2550
2551
if (cgd->inq_data.spc3_flags & SPC3_SID_PROTECT) {
2552
struct ccb_dev_advinfo cdai;
2553
struct scsi_vpd_extended_inquiry_data ext_inq;
2554
2555
bzero(&ext_inq, sizeof(ext_inq));
2556
2557
memset(&cdai, 0, sizeof(cdai));
2558
xpt_setup_ccb(&cdai.ccb_h, periph->path, CAM_PRIORITY_NORMAL);
2559
2560
cdai.ccb_h.func_code = XPT_DEV_ADVINFO;
2561
cdai.flags = CDAI_FLAG_NONE;
2562
cdai.buftype = CDAI_TYPE_EXT_INQ;
2563
cdai.bufsiz = sizeof(ext_inq);
2564
cdai.buf = (uint8_t *)&ext_inq;
2565
xpt_action((union ccb *)&cdai);
2566
2567
if ((cdai.ccb_h.status & CAM_DEV_QFRZN) != 0)
2568
cam_release_devq(cdai.ccb_h.path, 0, 0, 0, FALSE);
2569
if ((cdai.ccb_h.status == CAM_REQ_CMP)
2570
&& (ext_inq.flags1 & SVPD_EID_SA_SPT_LBP))
2571
softc->flags |= SA_FLAG_PROTECT_SUPP;
2572
}
2573
2574
xpt_path_inq(&cpi, periph->path);
2575
2576
/*
2577
* The SA driver supports a blocksize, but we don't know the
2578
* blocksize until we media is inserted. So, set a flag to
2579
* indicate that the blocksize is unavailable right now.
2580
*/
2581
cam_periph_unlock(periph);
2582
softc->device_stats = devstat_new_entry("sa", periph->unit_number, 0,
2583
DEVSTAT_BS_UNAVAILABLE, SID_TYPE(&cgd->inq_data) |
2584
XPORT_DEVSTAT_TYPE(cpi.transport), DEVSTAT_PRIORITY_TAPE);
2585
2586
/*
2587
* Load the default value that is either compiled in, or loaded
2588
* in the global kern.cam.sa.allow_io_split tunable.
2589
*/
2590
softc->allow_io_split = sa_allow_io_split;
2591
2592
/*
2593
* Load a per-instance tunable, if it exists. NOTE that this
2594
* tunable WILL GO AWAY in FreeBSD 11.0.
2595
*/
2596
snprintf(tmpstr, sizeof(tmpstr), "kern.cam.sa.%u.allow_io_split",
2597
periph->unit_number);
2598
TUNABLE_INT_FETCH(tmpstr, &softc->allow_io_split);
2599
2600
/*
2601
* If maxio isn't set, we fall back to DFLTPHYS. Otherwise we take
2602
* the smaller of cpi.maxio or maxphys.
2603
*/
2604
if (cpi.maxio == 0)
2605
softc->maxio = DFLTPHYS;
2606
else if (cpi.maxio > maxphys)
2607
softc->maxio = maxphys;
2608
else
2609
softc->maxio = cpi.maxio;
2610
2611
/*
2612
* Record the controller's maximum I/O size so we can report it to
2613
* the user later.
2614
*/
2615
softc->cpi_maxio = cpi.maxio;
2616
2617
/*
2618
* By default we tell physio that we do not want our I/O split.
2619
* The user needs to have a 1:1 mapping between the size of his
2620
* write to a tape character device and the size of the write
2621
* that actually goes down to the drive.
2622
*/
2623
if (softc->allow_io_split == 0)
2624
softc->si_flags = SI_NOSPLIT;
2625
else
2626
softc->si_flags = 0;
2627
2628
TASK_INIT(&softc->sysctl_task, 0, sasysctlinit, periph);
2629
2630
/*
2631
* If the SIM supports unmapped I/O, let physio know that we can
2632
* handle unmapped buffers.
2633
*/
2634
if (cpi.hba_misc & PIM_UNMAPPED)
2635
softc->si_flags |= SI_UNMAPPED;
2636
2637
/*
2638
* Acquire a reference to the periph before we create the devfs
2639
* instances for it. We'll release this reference once the devfs
2640
* instances have been freed.
2641
*/
2642
if (cam_periph_acquire(periph) != 0) {
2643
xpt_print(periph->path, "%s: lost periph during "
2644
"registration!\n", __func__);
2645
cam_periph_lock(periph);
2646
return (CAM_REQ_CMP_ERR);
2647
}
2648
2649
make_dev_args_init(&args);
2650
args.mda_devsw = &sa_cdevsw;
2651
args.mda_si_drv1 = softc->periph;
2652
args.mda_uid = UID_ROOT;
2653
args.mda_gid = GID_OPERATOR;
2654
args.mda_mode = 0660;
2655
2656
args.mda_unit = SAMINOR(SA_CTLDEV, SA_ATYPE_R);
2657
error = make_dev_s(&args, &softc->devs.ctl_dev, "%s%d.ctl",
2658
periph->periph_name, periph->unit_number);
2659
if (error != 0) {
2660
cam_periph_lock(periph);
2661
return (CAM_REQ_CMP_ERR);
2662
}
2663
sasetupdev(softc, softc->devs.ctl_dev);
2664
2665
args.mda_unit = SAMINOR(SA_NOT_CTLDEV, SA_ATYPE_R);
2666
error = make_dev_s(&args, &softc->devs.r_dev, "%s%d",
2667
periph->periph_name, periph->unit_number);
2668
if (error != 0) {
2669
cam_periph_lock(periph);
2670
return (CAM_REQ_CMP_ERR);
2671
}
2672
sasetupdev(softc, softc->devs.r_dev);
2673
2674
args.mda_unit = SAMINOR(SA_NOT_CTLDEV, SA_ATYPE_NR);
2675
error = make_dev_s(&args, &softc->devs.nr_dev, "n%s%d",
2676
periph->periph_name, periph->unit_number);
2677
if (error != 0) {
2678
cam_periph_lock(periph);
2679
return (CAM_REQ_CMP_ERR);
2680
}
2681
sasetupdev(softc, softc->devs.nr_dev);
2682
2683
args.mda_unit = SAMINOR(SA_NOT_CTLDEV, SA_ATYPE_ER);
2684
error = make_dev_s(&args, &softc->devs.er_dev, "e%s%d",
2685
periph->periph_name, periph->unit_number);
2686
if (error != 0) {
2687
cam_periph_lock(periph);
2688
return (CAM_REQ_CMP_ERR);
2689
}
2690
sasetupdev(softc, softc->devs.er_dev);
2691
2692
cam_periph_lock(periph);
2693
2694
softc->density_type_bits[0] = 0;
2695
softc->density_type_bits[1] = SRDS_MEDIA;
2696
softc->density_type_bits[2] = SRDS_MEDIUM_TYPE;
2697
softc->density_type_bits[3] = SRDS_MEDIUM_TYPE | SRDS_MEDIA;
2698
/*
2699
* Bump the peripheral refcount for the sysctl thread, in case we
2700
* get invalidated before the thread has a chance to run. Note
2701
* that this runs in parallel with the probe for the timeout
2702
* values.
2703
*/
2704
cam_periph_acquire(periph);
2705
taskqueue_enqueue(taskqueue_thread, &softc->sysctl_task);
2706
2707
/*
2708
* Add an async callback so that we get
2709
* notified if this device goes away.
2710
*/
2711
xpt_register_async(AC_LOST_DEVICE, saasync, periph, periph->path);
2712
2713
/*
2714
* See comment above, try fetching timeout values for drives that
2715
* might support it. Otherwise, use the defaults.
2716
*
2717
* We get timeouts from the following places in order of increasing
2718
* priority:
2719
* 1. Driver default timeouts.
2720
* 2. Timeouts loaded from the drive via REPORT SUPPORTED OPERATION
2721
* CODES. (We kick that off here if SA_FLAG_RSOC_TO_TRY is set.)
2722
* 3. Global loader tunables, used for all sa(4) driver instances on
2723
* a machine.
2724
* 4. Instance-specific loader tunables, used for say sa5.
2725
* 5. On the fly user sysctl changes.
2726
*
2727
* Each step will overwrite the timeout value set from the one
2728
* before, so you go from general to most specific.
2729
*/
2730
if (softc->flags & SA_FLAG_RSOC_TO_TRY) {
2731
/*
2732
* Bump the peripheral refcount while we are probing.
2733
*/
2734
cam_periph_acquire(periph);
2735
softc->state = SA_STATE_PROBE;
2736
xpt_schedule(periph, CAM_PRIORITY_DEV);
2737
} else {
2738
/*
2739
* This drive doesn't support Report Supported Operation
2740
* Codes, so we load the tunables at this point to bring
2741
* in any user preferences.
2742
*/
2743
saloadtotunables(softc);
2744
2745
xpt_announce_periph(periph, NULL);
2746
xpt_announce_quirks(periph, softc->quirks, SA_QUIRK_BIT_STRING);
2747
}
2748
2749
return (CAM_REQ_CMP);
2750
}
2751
2752
static void
2753
sastart(struct cam_periph *periph, union ccb *start_ccb)
2754
{
2755
struct sa_softc *softc;
2756
2757
softc = (struct sa_softc *)periph->softc;
2758
2759
CAM_DEBUG(periph->path, CAM_DEBUG_TRACE, ("sastart\n"));
2760
2761
switch (softc->state) {
2762
case SA_STATE_NORMAL:
2763
{
2764
/* Pull a buffer from the queue and get going on it */
2765
struct bio *bp;
2766
2767
/*
2768
* See if there is a buf with work for us to do..
2769
*/
2770
bp = bioq_first(&softc->bio_queue);
2771
if (bp == NULL) {
2772
xpt_release_ccb(start_ccb);
2773
} else if (((softc->flags & SA_FLAG_ERR_PENDING) != 0)
2774
|| (softc->inject_eom != 0)) {
2775
struct bio *done_bp;
2776
2777
if (softc->inject_eom != 0) {
2778
softc->flags |= SA_FLAG_EOM_PENDING;
2779
softc->inject_eom = 0;
2780
/*
2781
* If we're injecting EOM for writes, we
2782
* need to keep PEWS set for 3 queries
2783
* to cover 2 position requests from the
2784
* kernel via sagetpos(), and then allow
2785
* for one for the user to see the BPEW
2786
* flag (e.g. via mt status). After that,
2787
* it will be cleared.
2788
*/
2789
if (bp->bio_cmd == BIO_WRITE)
2790
softc->set_pews_status = 3;
2791
else
2792
softc->set_pews_status = 1;
2793
}
2794
again:
2795
softc->queue_count--;
2796
bioq_remove(&softc->bio_queue, bp);
2797
bp->bio_resid = bp->bio_bcount;
2798
done_bp = bp;
2799
if ((softc->flags & SA_FLAG_EOM_PENDING) != 0) {
2800
/*
2801
* We have two different behaviors for
2802
* writes when we hit either Early Warning
2803
* or the PEWZ (Programmable Early Warning
2804
* Zone). The default behavior is that
2805
* for all writes that are currently
2806
* queued after the write where we saw the
2807
* early warning, we will return the write
2808
* with the residual equal to the count.
2809
* i.e. tell the application that 0 bytes
2810
* were written.
2811
*
2812
* The alternate behavior, which is enabled
2813
* when eot_warn is set, is that in
2814
* addition to setting the residual equal
2815
* to the count, we will set the error
2816
* to ENOSPC.
2817
*
2818
* In either case, once queued writes are
2819
* cleared out, we clear the error flag
2820
* (see below) and the application is free to
2821
* attempt to write more.
2822
*/
2823
if (softc->eot_warn != 0) {
2824
bp->bio_flags |= BIO_ERROR;
2825
bp->bio_error = ENOSPC;
2826
} else
2827
bp->bio_error = 0;
2828
} else if ((softc->flags & SA_FLAG_EOF_PENDING) != 0) {
2829
/*
2830
* This can only happen if we're reading
2831
* in fixed length mode. In this case,
2832
* we dump the rest of the list the
2833
* same way.
2834
*/
2835
bp->bio_error = 0;
2836
if (bioq_first(&softc->bio_queue) != NULL) {
2837
biodone(done_bp);
2838
goto again;
2839
}
2840
} else if ((softc->flags & SA_FLAG_EIO_PENDING) != 0) {
2841
bp->bio_error = EIO;
2842
bp->bio_flags |= BIO_ERROR;
2843
}
2844
bp = bioq_first(&softc->bio_queue);
2845
/*
2846
* Only if we have no other buffers queued up
2847
* do we clear the pending error flag.
2848
*/
2849
if (bp == NULL)
2850
softc->flags &= ~SA_FLAG_ERR_PENDING;
2851
CAM_DEBUG(periph->path, CAM_DEBUG_INFO,
2852
("sastart- ERR_PENDING now 0x%x, bp is %sNULL, "
2853
"%d more buffers queued up\n",
2854
(softc->flags & SA_FLAG_ERR_PENDING),
2855
(bp != NULL)? "not " : " ", softc->queue_count));
2856
xpt_release_ccb(start_ccb);
2857
biodone(done_bp);
2858
} else {
2859
uint32_t length;
2860
2861
bioq_remove(&softc->bio_queue, bp);
2862
softc->queue_count--;
2863
2864
if ((bp->bio_cmd != BIO_READ) &&
2865
(bp->bio_cmd != BIO_WRITE)) {
2866
biofinish(bp, NULL, EOPNOTSUPP);
2867
xpt_release_ccb(start_ccb);
2868
return;
2869
}
2870
length = bp->bio_bcount;
2871
2872
if ((softc->flags & SA_FLAG_FIXED) != 0) {
2873
if (softc->blk_shift != 0) {
2874
length = length >> softc->blk_shift;
2875
} else if (softc->media_blksize != 0) {
2876
length = length / softc->media_blksize;
2877
} else {
2878
bp->bio_error = EIO;
2879
xpt_print(periph->path, "zero blocksize"
2880
" for FIXED length writes?\n");
2881
biodone(bp);
2882
break;
2883
}
2884
#if 0
2885
CAM_DEBUG(start_ccb->ccb_h.path, CAM_DEBUG_INFO,
2886
("issuing a %d fixed record %s\n",
2887
length, (bp->bio_cmd == BIO_READ)? "read" :
2888
"write"));
2889
#endif
2890
} else {
2891
#if 0
2892
CAM_DEBUG(start_ccb->ccb_h.path, CAM_DEBUG_INFO,
2893
("issuing a %d variable byte %s\n",
2894
length, (bp->bio_cmd == BIO_READ)? "read" :
2895
"write"));
2896
#endif
2897
}
2898
devstat_start_transaction_bio(softc->device_stats, bp);
2899
/*
2900
* Some people have theorized that we should
2901
* suppress illegal length indication if we are
2902
* running in variable block mode so that we don't
2903
* have to request sense every time our requested
2904
* block size is larger than the written block.
2905
* The residual information from the ccb allows
2906
* us to identify this situation anyway. The only
2907
* problem with this is that we will not get
2908
* information about blocks that are larger than
2909
* our read buffer unless we set the block size
2910
* in the mode page to something other than 0.
2911
*
2912
* I believe that this is a non-issue. If user apps
2913
* don't adjust their read size to match our record
2914
* size, that's just life. Anyway, the typical usage
2915
* would be to issue, e.g., 64KB reads and occasionally
2916
* have to do deal with 512 byte or 1KB intermediate
2917
* records.
2918
*
2919
* That said, though, we now support setting the
2920
* SILI bit on reads, and we set the blocksize to 4
2921
* bytes when we do that. This gives us
2922
* compatibility with software that wants this,
2923
* although the only real difference between that
2924
* and not setting the SILI bit on reads is that we
2925
* won't get a check condition on reads where our
2926
* request size is larger than the block on tape.
2927
* That probably only makes a real difference in
2928
* non-packetized SCSI, where you have to go back
2929
* to the drive to request sense and thus incur
2930
* more latency.
2931
*/
2932
softc->dsreg = (bp->bio_cmd == BIO_READ)?
2933
MTIO_DSREG_RD : MTIO_DSREG_WR;
2934
scsi_sa_read_write(&start_ccb->csio, 0, sadone,
2935
MSG_SIMPLE_Q_TAG, (bp->bio_cmd == BIO_READ ?
2936
SCSI_RW_READ : SCSI_RW_WRITE) |
2937
((bp->bio_flags & BIO_UNMAPPED) != 0 ?
2938
SCSI_RW_BIO : 0), softc->sili,
2939
(softc->flags & SA_FLAG_FIXED) != 0, length,
2940
(bp->bio_flags & BIO_UNMAPPED) != 0 ? (void *)bp :
2941
bp->bio_data, bp->bio_bcount, SSD_FULL_SIZE,
2942
(bp->bio_cmd == BIO_READ) ?
2943
softc->timeout_info[SA_TIMEOUT_READ] :
2944
softc->timeout_info[SA_TIMEOUT_WRITE]);
2945
start_ccb->ccb_h.ccb_pflags &= ~SA_POSITION_UPDATED;
2946
start_ccb->ccb_h.ccb_bp = bp;
2947
bp = bioq_first(&softc->bio_queue);
2948
xpt_action(start_ccb);
2949
}
2950
2951
if (bp != NULL) {
2952
/* Have more work to do, so ensure we stay scheduled */
2953
xpt_schedule(periph, CAM_PRIORITY_NORMAL);
2954
}
2955
break;
2956
}
2957
case SA_STATE_PROBE: {
2958
int num_opcodes;
2959
size_t alloc_len;
2960
uint8_t *params;
2961
2962
/*
2963
* This is an arbitrary number. An IBM LTO-6 drive reports
2964
* 67 entries, and an IBM LTO-9 drive reports 71 entries.
2965
* There can theoretically be more than 256 because
2966
* service actions of a particular opcode are reported
2967
* separately, but we're far enough ahead of the practical
2968
* number here that we don't need to implement logic to
2969
* retry if we don't get all the timeout descriptors.
2970
*/
2971
num_opcodes = 256;
2972
2973
alloc_len = num_opcodes *
2974
(sizeof(struct scsi_report_supported_opcodes_descr) +
2975
sizeof(struct scsi_report_supported_opcodes_timeout));
2976
2977
params = malloc(alloc_len, M_SCSISA, M_NOWAIT| M_ZERO);
2978
if (params == NULL) {
2979
/*
2980
* If this happens, go with default
2981
* timeouts and announce the drive.
2982
*/
2983
saloadtotunables(softc);
2984
2985
softc->state = SA_STATE_NORMAL;
2986
2987
xpt_announce_periph(periph, NULL);
2988
xpt_announce_quirks(periph, softc->quirks,
2989
SA_QUIRK_BIT_STRING);
2990
xpt_release_ccb(start_ccb);
2991
cam_periph_release_locked(periph);
2992
return;
2993
}
2994
2995
scsi_report_supported_opcodes(&start_ccb->csio,
2996
/*retries*/ 3,
2997
/*cbfcnp*/ sadone,
2998
/*tag_action*/ MSG_SIMPLE_Q_TAG,
2999
/*options*/ RSO_RCTD,
3000
/*req_opcode*/ 0,
3001
/*req_service_action*/ 0,
3002
/*data_ptr*/ params,
3003
/*dxfer_len*/ alloc_len,
3004
/*sense_len*/ SSD_FULL_SIZE,
3005
/*timeout*/ softc->timeout_info[SA_TIMEOUT_TUR]);
3006
3007
xpt_action(start_ccb);
3008
break;
3009
}
3010
case SA_STATE_ABNORMAL:
3011
default:
3012
panic("state 0x%x in sastart", softc->state);
3013
break;
3014
}
3015
}
3016
3017
static void
3018
sadone(struct cam_periph *periph, union ccb *done_ccb)
3019
{
3020
struct sa_softc *softc;
3021
struct ccb_scsiio *csio;
3022
struct bio *bp;
3023
int error;
3024
3025
softc = (struct sa_softc *)periph->softc;
3026
csio = &done_ccb->csio;
3027
error = 0;
3028
3029
if (softc->state == SA_STATE_NORMAL) {
3030
softc->dsreg = MTIO_DSREG_REST;
3031
bp = (struct bio *)done_ccb->ccb_h.ccb_bp;
3032
3033
if ((done_ccb->ccb_h.status & CAM_STATUS_MASK) != CAM_REQ_CMP) {
3034
if ((error = saerror(done_ccb, 0, 0)) == ERESTART) {
3035
/*
3036
* A retry was scheduled, so just return.
3037
*/
3038
return;
3039
}
3040
}
3041
} else if (softc->state == SA_STATE_PROBE) {
3042
bp = NULL;
3043
if ((done_ccb->ccb_h.status & CAM_STATUS_MASK) != CAM_REQ_CMP) {
3044
/*
3045
* Note that on probe, we just run through
3046
* cam_periph_error(), since saerror() has a lot of
3047
* special handling for I/O errors. We don't need
3048
* that to get the opcodes. We either succeed
3049
* after a retry or two, or give up. We don't
3050
* print sense, we don't need to worry the user if
3051
* this drive doesn't support timeout descriptors.
3052
*/
3053
if ((error = cam_periph_error(done_ccb, 0,
3054
SF_NO_PRINT)) == ERESTART) {
3055
/*
3056
* A retry was scheduled, so just return.
3057
*/
3058
return;
3059
} else if (error != 0) {
3060
/* We failed to get opcodes. Give up. */
3061
3062
saloadtotunables(softc);
3063
3064
softc->state = SA_STATE_NORMAL;
3065
3066
xpt_release_ccb(done_ccb);
3067
3068
xpt_announce_periph(periph, NULL);
3069
xpt_announce_quirks(periph, softc->quirks,
3070
SA_QUIRK_BIT_STRING);
3071
cam_periph_release_locked(periph);
3072
return;
3073
}
3074
}
3075
/*
3076
* At this point, we have succeeded, so load the timeouts
3077
* and go into the normal state.
3078
*/
3079
softc->state = SA_STATE_NORMAL;
3080
3081
/*
3082
* First, load the timeouts we got from the drive.
3083
*/
3084
saloadtimeouts(softc, done_ccb);
3085
3086
/*
3087
* Next, overwrite the timeouts from the drive with any
3088
* loader tunables that the user set.
3089
*/
3090
saloadtotunables(softc);
3091
3092
xpt_release_ccb(done_ccb);
3093
xpt_announce_periph(periph, NULL);
3094
xpt_announce_quirks(periph, softc->quirks,
3095
SA_QUIRK_BIT_STRING);
3096
cam_periph_release_locked(periph);
3097
return;
3098
} else {
3099
panic("state 0x%x in sadone", softc->state);
3100
}
3101
3102
if (error == EIO) {
3103
/*
3104
* Catastrophic error. Mark the tape as frozen
3105
* (we no longer know tape position).
3106
*
3107
* Return all queued I/O with EIO, and unfreeze
3108
* our queue so that future transactions that
3109
* attempt to fix this problem can get to the
3110
* device.
3111
*
3112
*/
3113
3114
softc->flags |= SA_FLAG_TAPE_FROZEN;
3115
bioq_flush(&softc->bio_queue, NULL, EIO);
3116
}
3117
if (error != 0) {
3118
bp->bio_resid = bp->bio_bcount;
3119
bp->bio_error = error;
3120
bp->bio_flags |= BIO_ERROR;
3121
/*
3122
* In the error case, position is updated in saerror.
3123
*/
3124
} else {
3125
bp->bio_resid = csio->resid;
3126
bp->bio_error = 0;
3127
if (csio->resid != 0) {
3128
bp->bio_flags |= BIO_ERROR;
3129
}
3130
if (bp->bio_cmd == BIO_WRITE) {
3131
softc->flags |= SA_FLAG_TAPE_WRITTEN;
3132
softc->filemarks = 0;
3133
}
3134
if (!(csio->ccb_h.ccb_pflags & SA_POSITION_UPDATED) &&
3135
(softc->blkno != (daddr_t) -1)) {
3136
if ((softc->flags & SA_FLAG_FIXED) != 0) {
3137
uint32_t l;
3138
if (softc->blk_shift != 0) {
3139
l = bp->bio_bcount >>
3140
softc->blk_shift;
3141
} else {
3142
l = bp->bio_bcount /
3143
softc->media_blksize;
3144
}
3145
softc->blkno += (daddr_t) l;
3146
} else {
3147
softc->blkno++;
3148
}
3149
}
3150
}
3151
/*
3152
* If we had an error (immediate or pending),
3153
* release the device queue now.
3154
*/
3155
if (error || (softc->flags & SA_FLAG_ERR_PENDING))
3156
cam_release_devq(done_ccb->ccb_h.path, 0, 0, 0, 0);
3157
if (error || bp->bio_resid) {
3158
CAM_DEBUG(periph->path, CAM_DEBUG_INFO,
3159
("error %d resid %ld count %ld\n", error,
3160
bp->bio_resid, bp->bio_bcount));
3161
}
3162
biofinish(bp, softc->device_stats, 0);
3163
xpt_release_ccb(done_ccb);
3164
}
3165
3166
/*
3167
* Mount the tape (make sure it's ready for I/O).
3168
*/
3169
static int
3170
samount(struct cam_periph *periph, int oflags, struct cdev *dev)
3171
{
3172
struct sa_softc *softc;
3173
union ccb *ccb;
3174
int error;
3175
3176
/*
3177
* oflags can be checked for 'kind' of open (read-only check) - later
3178
* dev can be checked for a control-mode or compression open - later
3179
*/
3180
UNUSED_PARAMETER(oflags);
3181
UNUSED_PARAMETER(dev);
3182
3183
softc = (struct sa_softc *)periph->softc;
3184
3185
/*
3186
* This should determine if something has happened since the last
3187
* open/mount that would invalidate the mount. We do *not* want
3188
* to retry this command- we just want the status. But we only
3189
* do this if we're mounted already- if we're not mounted,
3190
* we don't care about the unit read state and can instead use
3191
* this opportunity to attempt to reserve the tape unit.
3192
*/
3193
3194
if (softc->flags & SA_FLAG_TAPE_MOUNTED) {
3195
ccb = cam_periph_getccb(periph, 1);
3196
scsi_test_unit_ready(&ccb->csio, 0, NULL,
3197
MSG_SIMPLE_Q_TAG, SSD_FULL_SIZE,
3198
softc->timeout_info[SA_TIMEOUT_TUR]);
3199
error = cam_periph_runccb(ccb, saerror, 0, SF_NO_PRINT,
3200
softc->device_stats);
3201
if (error == ENXIO) {
3202
softc->flags &= ~SA_FLAG_TAPE_MOUNTED;
3203
scsi_test_unit_ready(&ccb->csio, 0, NULL,
3204
MSG_SIMPLE_Q_TAG, SSD_FULL_SIZE,
3205
softc->timeout_info[SA_TIMEOUT_TUR]);
3206
error = cam_periph_runccb(ccb, saerror, 0, SF_NO_PRINT,
3207
softc->device_stats);
3208
} else if (error) {
3209
/*
3210
* We don't need to freeze the tape because we
3211
* will now attempt to rewind/load it.
3212
*/
3213
softc->flags &= ~SA_FLAG_TAPE_MOUNTED;
3214
if (CAM_DEBUGGED(periph->path, CAM_DEBUG_INFO)) {
3215
xpt_print(periph->path,
3216
"error %d on TUR in samount\n", error);
3217
}
3218
}
3219
} else {
3220
error = sareservereleaseunit(periph, TRUE);
3221
if (error) {
3222
return (error);
3223
}
3224
ccb = cam_periph_getccb(periph, 1);
3225
scsi_test_unit_ready(&ccb->csio, 0, NULL,
3226
MSG_SIMPLE_Q_TAG, SSD_FULL_SIZE,
3227
softc->timeout_info[SA_TIMEOUT_TUR]);
3228
error = cam_periph_runccb(ccb, saerror, 0, SF_NO_PRINT,
3229
softc->device_stats);
3230
}
3231
3232
if ((softc->flags & SA_FLAG_TAPE_MOUNTED) == 0) {
3233
struct scsi_read_block_limits_data *rblim = NULL;
3234
int comp_enabled, comp_supported;
3235
uint8_t write_protect, guessing = 0;
3236
3237
/*
3238
* Clear out old state.
3239
*/
3240
softc->flags &= ~(SA_FLAG_TAPE_WP|SA_FLAG_TAPE_WRITTEN|
3241
SA_FLAG_ERR_PENDING|SA_FLAG_COMPRESSION);
3242
softc->filemarks = 0;
3243
3244
/*
3245
* *Very* first off, make sure we're loaded to BOT.
3246
*/
3247
scsi_load_unload(&ccb->csio, 2, NULL, MSG_SIMPLE_Q_TAG, FALSE,
3248
FALSE, FALSE, 1, SSD_FULL_SIZE,
3249
softc->timeout_info[SA_TIMEOUT_LOAD]);
3250
error = cam_periph_runccb(ccb, saerror, 0, SF_NO_PRINT,
3251
softc->device_stats);
3252
3253
/*
3254
* In case this doesn't work, do a REWIND instead
3255
*/
3256
if (error) {
3257
scsi_rewind(&ccb->csio, 2, NULL, MSG_SIMPLE_Q_TAG,
3258
FALSE, SSD_FULL_SIZE,
3259
softc->timeout_info[SA_TIMEOUT_REWIND]);
3260
error = cam_periph_runccb(ccb, saerror, 0, SF_NO_PRINT,
3261
softc->device_stats);
3262
}
3263
if (error) {
3264
xpt_release_ccb(ccb);
3265
goto exit;
3266
}
3267
3268
/*
3269
* Do a dummy test read to force access to the
3270
* media so that the drive will really know what's
3271
* there. We actually don't really care what the
3272
* blocksize on tape is and don't expect to really
3273
* read a full record.
3274
*/
3275
rblim = (struct scsi_read_block_limits_data *)
3276
malloc(8192, M_SCSISA, M_NOWAIT);
3277
if (rblim == NULL) {
3278
xpt_print(periph->path, "no memory for test read\n");
3279
xpt_release_ccb(ccb);
3280
error = ENOMEM;
3281
goto exit;
3282
}
3283
3284
if ((softc->quirks & SA_QUIRK_NODREAD) == 0) {
3285
scsi_sa_read_write(&ccb->csio, 0, NULL,
3286
MSG_SIMPLE_Q_TAG, 1, FALSE, 0, 8192,
3287
(void *) rblim, 8192, SSD_FULL_SIZE,
3288
softc->timeout_info[SA_TIMEOUT_READ]);
3289
(void) cam_periph_runccb(ccb, saerror, 0, SF_NO_PRINT,
3290
softc->device_stats);
3291
scsi_rewind(&ccb->csio, 1, NULL, MSG_SIMPLE_Q_TAG,
3292
FALSE, SSD_FULL_SIZE,
3293
softc->timeout_info[SA_TIMEOUT_REWIND]);
3294
error = cam_periph_runccb(ccb, saerror, CAM_RETRY_SELTO,
3295
SF_NO_PRINT | SF_RETRY_UA,
3296
softc->device_stats);
3297
if (error) {
3298
xpt_print(periph->path,
3299
"unable to rewind after test read\n");
3300
xpt_release_ccb(ccb);
3301
goto exit;
3302
}
3303
}
3304
3305
/*
3306
* Next off, determine block limits.
3307
*/
3308
scsi_read_block_limits(&ccb->csio, 5, NULL, MSG_SIMPLE_Q_TAG,
3309
rblim, SSD_FULL_SIZE,
3310
softc->timeout_info[SA_TIMEOUT_READ_BLOCK_LIMITS]);
3311
3312
error = cam_periph_runccb(ccb, saerror, CAM_RETRY_SELTO,
3313
SF_NO_PRINT | SF_RETRY_UA, softc->device_stats);
3314
3315
xpt_release_ccb(ccb);
3316
3317
if (error != 0) {
3318
/*
3319
* If it's less than SCSI-2, READ BLOCK LIMITS is not
3320
* a MANDATORY command. Anyway- it doesn't matter-
3321
* we can proceed anyway.
3322
*/
3323
softc->blk_gran = 0;
3324
softc->max_blk = ~0;
3325
softc->min_blk = 0;
3326
} else {
3327
if (softc->scsi_rev >= SCSI_REV_SPC) {
3328
softc->blk_gran = RBL_GRAN(rblim);
3329
} else {
3330
softc->blk_gran = 0;
3331
}
3332
/*
3333
* We take max_blk == min_blk to mean a default to
3334
* fixed mode- but note that whatever we get out of
3335
* sagetparams below will actually determine whether
3336
* we are actually *in* fixed mode.
3337
*/
3338
softc->max_blk = scsi_3btoul(rblim->maximum);
3339
softc->min_blk = scsi_2btoul(rblim->minimum);
3340
}
3341
/*
3342
* Next, perform a mode sense to determine
3343
* current density, blocksize, compression etc.
3344
*/
3345
error = sagetparams(periph, SA_PARAM_ALL,
3346
&softc->media_blksize,
3347
&softc->media_density,
3348
&softc->media_numblks,
3349
&softc->buffer_mode, &write_protect,
3350
&softc->speed, &comp_supported,
3351
&comp_enabled, &softc->comp_algorithm,
3352
NULL, NULL, 0, 0);
3353
3354
if (error != 0) {
3355
/*
3356
* We could work a little harder here. We could
3357
* adjust our attempts to get information. It
3358
* might be an ancient tape drive. If someone
3359
* nudges us, we'll do that.
3360
*/
3361
goto exit;
3362
}
3363
3364
/*
3365
* If no quirk has determined that this is a device that is
3366
* preferred to be in fixed or variable mode, now is the time
3367
* to find out.
3368
*/
3369
if ((softc->quirks & (SA_QUIRK_FIXED|SA_QUIRK_VARIABLE)) == 0) {
3370
guessing = 1;
3371
/*
3372
* This could be expensive to find out. Luckily we
3373
* only need to do this once. If we start out in
3374
* 'default' mode, try and set ourselves to one
3375
* of the densities that would determine a wad
3376
* of other stuff. Go from highest to lowest.
3377
*/
3378
if (softc->media_density == SCSI_DEFAULT_DENSITY) {
3379
int i;
3380
static uint8_t ctry[] = {
3381
SCSI_DENSITY_HALFINCH_PE,
3382
SCSI_DENSITY_HALFINCH_6250C,
3383
SCSI_DENSITY_HALFINCH_6250,
3384
SCSI_DENSITY_HALFINCH_1600,
3385
SCSI_DENSITY_HALFINCH_800,
3386
SCSI_DENSITY_QIC_4GB,
3387
SCSI_DENSITY_QIC_2GB,
3388
SCSI_DENSITY_QIC_525_320,
3389
SCSI_DENSITY_QIC_150,
3390
SCSI_DENSITY_QIC_120,
3391
SCSI_DENSITY_QIC_24,
3392
SCSI_DENSITY_QIC_11_9TRK,
3393
SCSI_DENSITY_QIC_11_4TRK,
3394
SCSI_DENSITY_QIC_1320,
3395
SCSI_DENSITY_QIC_3080,
3396
0
3397
};
3398
for (i = 0; ctry[i]; i++) {
3399
error = sasetparams(periph,
3400
SA_PARAM_DENSITY, 0, ctry[i],
3401
0, SF_NO_PRINT);
3402
if (error == 0) {
3403
softc->media_density = ctry[i];
3404
break;
3405
}
3406
}
3407
}
3408
switch (softc->media_density) {
3409
case SCSI_DENSITY_QIC_11_4TRK:
3410
case SCSI_DENSITY_QIC_11_9TRK:
3411
case SCSI_DENSITY_QIC_24:
3412
case SCSI_DENSITY_QIC_120:
3413
case SCSI_DENSITY_QIC_150:
3414
case SCSI_DENSITY_QIC_525_320:
3415
case SCSI_DENSITY_QIC_1320:
3416
case SCSI_DENSITY_QIC_3080:
3417
softc->quirks &= ~SA_QUIRK_2FM;
3418
softc->quirks |= SA_QUIRK_FIXED|SA_QUIRK_1FM;
3419
softc->last_media_blksize = 512;
3420
break;
3421
case SCSI_DENSITY_QIC_4GB:
3422
case SCSI_DENSITY_QIC_2GB:
3423
softc->quirks &= ~SA_QUIRK_2FM;
3424
softc->quirks |= SA_QUIRK_FIXED|SA_QUIRK_1FM;
3425
softc->last_media_blksize = 1024;
3426
break;
3427
default:
3428
softc->last_media_blksize =
3429
softc->media_blksize;
3430
softc->quirks |= SA_QUIRK_VARIABLE;
3431
break;
3432
}
3433
}
3434
3435
/*
3436
* If no quirk has determined that this is a device that needs
3437
* to have 2 Filemarks at EOD, now is the time to find out.
3438
*/
3439
3440
if ((softc->quirks & SA_QUIRK_2FM) == 0) {
3441
switch (softc->media_density) {
3442
case SCSI_DENSITY_HALFINCH_800:
3443
case SCSI_DENSITY_HALFINCH_1600:
3444
case SCSI_DENSITY_HALFINCH_6250:
3445
case SCSI_DENSITY_HALFINCH_6250C:
3446
case SCSI_DENSITY_HALFINCH_PE:
3447
softc->quirks &= ~SA_QUIRK_1FM;
3448
softc->quirks |= SA_QUIRK_2FM;
3449
break;
3450
default:
3451
break;
3452
}
3453
}
3454
3455
/*
3456
* Now validate that some info we got makes sense.
3457
*/
3458
if ((softc->max_blk < softc->media_blksize) ||
3459
(softc->min_blk > softc->media_blksize &&
3460
softc->media_blksize)) {
3461
xpt_print(periph->path,
3462
"BLOCK LIMITS (%d..%d) could not match current "
3463
"block settings (%d)- adjusting\n", softc->min_blk,
3464
softc->max_blk, softc->media_blksize);
3465
softc->max_blk = softc->min_blk =
3466
softc->media_blksize;
3467
}
3468
3469
/*
3470
* Now put ourselves into the right frame of mind based
3471
* upon quirks...
3472
*/
3473
tryagain:
3474
/*
3475
* If we want to be in FIXED mode and our current blocksize
3476
* is not equal to our last blocksize (if nonzero), try and
3477
* set ourselves to this last blocksize (as the 'preferred'
3478
* block size). The initial quirkmatch at registry sets the
3479
* initial 'last' blocksize. If, for whatever reason, this
3480
* 'last' blocksize is zero, set the blocksize to 512,
3481
* or min_blk if that's larger.
3482
*/
3483
if ((softc->quirks & SA_QUIRK_FIXED) &&
3484
(softc->quirks & SA_QUIRK_NO_MODESEL) == 0 &&
3485
(softc->media_blksize != softc->last_media_blksize)) {
3486
softc->media_blksize = softc->last_media_blksize;
3487
if (softc->media_blksize == 0) {
3488
softc->media_blksize = 512;
3489
if (softc->media_blksize < softc->min_blk) {
3490
softc->media_blksize = softc->min_blk;
3491
}
3492
}
3493
error = sasetparams(periph, SA_PARAM_BLOCKSIZE,
3494
softc->media_blksize, 0, 0, SF_NO_PRINT);
3495
if (error) {
3496
xpt_print(periph->path,
3497
"unable to set fixed blocksize to %d\n",
3498
softc->media_blksize);
3499
goto exit;
3500
}
3501
}
3502
3503
if ((softc->quirks & SA_QUIRK_VARIABLE) &&
3504
(softc->media_blksize != 0)) {
3505
softc->last_media_blksize = softc->media_blksize;
3506
softc->media_blksize = 0;
3507
error = sasetparams(periph, SA_PARAM_BLOCKSIZE,
3508
0, 0, 0, SF_NO_PRINT);
3509
if (error) {
3510
/*
3511
* If this fails and we were guessing, just
3512
* assume that we got it wrong and go try
3513
* fixed block mode. Don't even check against
3514
* density code at this point.
3515
*/
3516
if (guessing) {
3517
softc->quirks &= ~SA_QUIRK_VARIABLE;
3518
softc->quirks |= SA_QUIRK_FIXED;
3519
if (softc->last_media_blksize == 0)
3520
softc->last_media_blksize = 512;
3521
goto tryagain;
3522
}
3523
xpt_print(periph->path,
3524
"unable to set variable blocksize\n");
3525
goto exit;
3526
}
3527
}
3528
3529
/*
3530
* Now that we have the current block size,
3531
* set up some parameters for sastart's usage.
3532
*/
3533
if (softc->media_blksize) {
3534
softc->flags |= SA_FLAG_FIXED;
3535
if (powerof2(softc->media_blksize)) {
3536
softc->blk_shift =
3537
ffs(softc->media_blksize) - 1;
3538
softc->blk_mask = softc->media_blksize - 1;
3539
} else {
3540
softc->blk_mask = ~0;
3541
softc->blk_shift = 0;
3542
}
3543
} else {
3544
/*
3545
* The SCSI-3 spec allows 0 to mean "unspecified".
3546
* The SCSI-1 spec allows 0 to mean 'infinite'.
3547
*
3548
* Either works here.
3549
*/
3550
if (softc->max_blk == 0) {
3551
softc->max_blk = ~0;
3552
}
3553
softc->blk_shift = 0;
3554
if (softc->blk_gran != 0) {
3555
softc->blk_mask = softc->blk_gran - 1;
3556
} else {
3557
softc->blk_mask = 0;
3558
}
3559
}
3560
3561
if (write_protect)
3562
softc->flags |= SA_FLAG_TAPE_WP;
3563
3564
if (comp_supported) {
3565
if (softc->saved_comp_algorithm == 0)
3566
softc->saved_comp_algorithm =
3567
softc->comp_algorithm;
3568
softc->flags |= SA_FLAG_COMP_SUPP;
3569
if (comp_enabled)
3570
softc->flags |= SA_FLAG_COMP_ENABLED;
3571
} else
3572
softc->flags |= SA_FLAG_COMP_UNSUPP;
3573
3574
if ((softc->buffer_mode == SMH_SA_BUF_MODE_NOBUF) &&
3575
(softc->quirks & SA_QUIRK_NO_MODESEL) == 0) {
3576
error = sasetparams(periph, SA_PARAM_BUFF_MODE, 0,
3577
0, 0, SF_NO_PRINT);
3578
if (error == 0) {
3579
softc->buffer_mode = SMH_SA_BUF_MODE_SIBUF;
3580
} else {
3581
xpt_print(periph->path,
3582
"unable to set buffered mode\n");
3583
}
3584
error = 0; /* not an error */
3585
}
3586
3587
if (error == 0) {
3588
softc->flags |= SA_FLAG_TAPE_MOUNTED;
3589
}
3590
exit:
3591
if (rblim != NULL)
3592
free(rblim, M_SCSISA);
3593
3594
if (error != 0) {
3595
softc->dsreg = MTIO_DSREG_NIL;
3596
} else {
3597
softc->fileno = softc->blkno = 0;
3598
softc->rep_fileno = softc->rep_blkno = -1;
3599
softc->partition = 0;
3600
softc->dsreg = MTIO_DSREG_REST;
3601
}
3602
#ifdef SA_1FM_AT_EOD
3603
if ((softc->quirks & SA_QUIRK_2FM) == 0)
3604
softc->quirks |= SA_QUIRK_1FM;
3605
#else
3606
if ((softc->quirks & SA_QUIRK_1FM) == 0)
3607
softc->quirks |= SA_QUIRK_2FM;
3608
#endif
3609
} else
3610
xpt_release_ccb(ccb);
3611
3612
/*
3613
* If we return an error, we're not mounted any more,
3614
* so release any device reservation.
3615
*/
3616
if (error != 0) {
3617
(void) sareservereleaseunit(periph, FALSE);
3618
} else {
3619
/*
3620
* Clear I/O residual.
3621
*/
3622
softc->last_io_resid = 0;
3623
softc->last_ctl_resid = 0;
3624
}
3625
return (error);
3626
}
3627
3628
/*
3629
* How many filemarks do we need to write if we were to terminate the
3630
* tape session right now? Note that this can be a negative number
3631
*/
3632
3633
static int
3634
samarkswanted(struct cam_periph *periph)
3635
{
3636
int markswanted;
3637
struct sa_softc *softc;
3638
3639
softc = (struct sa_softc *)periph->softc;
3640
markswanted = 0;
3641
if ((softc->flags & SA_FLAG_TAPE_WRITTEN) != 0) {
3642
markswanted++;
3643
if (softc->quirks & SA_QUIRK_2FM)
3644
markswanted++;
3645
}
3646
markswanted -= softc->filemarks;
3647
return (markswanted);
3648
}
3649
3650
static int
3651
sacheckeod(struct cam_periph *periph)
3652
{
3653
int error;
3654
int markswanted;
3655
3656
markswanted = samarkswanted(periph);
3657
3658
if (markswanted > 0) {
3659
error = sawritefilemarks(periph, markswanted, FALSE, FALSE);
3660
} else {
3661
error = 0;
3662
}
3663
return (error);
3664
}
3665
3666
static int
3667
saerror(union ccb *ccb, uint32_t cflgs, uint32_t sflgs)
3668
{
3669
static const char *toobig =
3670
"%d-byte tape record bigger than supplied buffer\n";
3671
struct cam_periph *periph;
3672
struct sa_softc *softc;
3673
struct ccb_scsiio *csio;
3674
struct scsi_sense_data *sense;
3675
uint64_t resid = 0;
3676
int64_t info = 0;
3677
cam_status status;
3678
int error_code, sense_key, asc, ascq, error, aqvalid, stream_valid;
3679
int sense_len;
3680
uint8_t stream_bits;
3681
3682
periph = xpt_path_periph(ccb->ccb_h.path);
3683
softc = (struct sa_softc *)periph->softc;
3684
csio = &ccb->csio;
3685
sense = &csio->sense_data;
3686
sense_len = csio->sense_len - csio->sense_resid;
3687
scsi_extract_sense_len(sense, sense_len, &error_code, &sense_key,
3688
&asc, &ascq, /*show_errors*/ 1);
3689
if (asc != -1 && ascq != -1)
3690
aqvalid = 1;
3691
else
3692
aqvalid = 0;
3693
if (scsi_get_stream_info(sense, sense_len, NULL, &stream_bits) == 0)
3694
stream_valid = 1;
3695
else
3696
stream_valid = 0;
3697
error = 0;
3698
3699
status = csio->ccb_h.status & CAM_STATUS_MASK;
3700
3701
/*
3702
* Calculate/latch up, any residuals... We do this in a funny 2-step
3703
* so we can print stuff here if we have CAM_DEBUG enabled for this
3704
* unit.
3705
*/
3706
if (status == CAM_SCSI_STATUS_ERROR) {
3707
if (scsi_get_sense_info(sense, sense_len, SSD_DESC_INFO, &resid,
3708
&info) == 0) {
3709
if ((softc->flags & SA_FLAG_FIXED) != 0)
3710
resid *= softc->media_blksize;
3711
} else {
3712
resid = csio->dxfer_len;
3713
info = resid;
3714
if ((softc->flags & SA_FLAG_FIXED) != 0) {
3715
if (softc->media_blksize)
3716
info /= softc->media_blksize;
3717
}
3718
}
3719
if (csio->cdb_io.cdb_bytes[0] == SA_READ ||
3720
csio->cdb_io.cdb_bytes[0] == SA_WRITE) {
3721
bcopy((caddr_t) sense, (caddr_t) &softc->last_io_sense,
3722
sizeof (struct scsi_sense_data));
3723
bcopy(csio->cdb_io.cdb_bytes, softc->last_io_cdb,
3724
(int) csio->cdb_len);
3725
softc->last_io_resid = resid;
3726
softc->last_resid_was_io = 1;
3727
} else {
3728
bcopy((caddr_t) sense, (caddr_t) &softc->last_ctl_sense,
3729
sizeof (struct scsi_sense_data));
3730
bcopy(csio->cdb_io.cdb_bytes, softc->last_ctl_cdb,
3731
(int) csio->cdb_len);
3732
softc->last_ctl_resid = resid;
3733
softc->last_resid_was_io = 0;
3734
}
3735
CAM_DEBUG(periph->path, CAM_DEBUG_INFO, ("CDB[0]=0x%x Key 0x%x "
3736
"ASC/ASCQ 0x%x/0x%x CAM STATUS 0x%x flags 0x%x resid %jd "
3737
"dxfer_len %d\n", csio->cdb_io.cdb_bytes[0] & 0xff,
3738
sense_key, asc, ascq, status,
3739
(stream_valid) ? stream_bits : 0, (intmax_t)resid,
3740
csio->dxfer_len));
3741
} else {
3742
CAM_DEBUG(periph->path, CAM_DEBUG_INFO,
3743
("Cam Status 0x%x\n", status));
3744
}
3745
3746
switch (status) {
3747
case CAM_REQ_CMP:
3748
return (0);
3749
case CAM_SCSI_STATUS_ERROR:
3750
/*
3751
* If a read/write command, we handle it here.
3752
*/
3753
if (csio->cdb_io.cdb_bytes[0] == SA_READ ||
3754
csio->cdb_io.cdb_bytes[0] == SA_WRITE) {
3755
break;
3756
}
3757
/*
3758
* If this was just EOM/EOP, Filemark, Setmark, ILI or
3759
* PEW detected on a non read/write command, we assume
3760
* it's not an error and propagate the residual and return.
3761
*/
3762
if ((aqvalid && asc == 0 && ((ascq > 0 && ascq <= 5)
3763
|| (ascq == 0x07)))
3764
|| (aqvalid == 0 && sense_key == SSD_KEY_NO_SENSE)) {
3765
csio->resid = resid;
3766
QFRLS(ccb);
3767
return (0);
3768
}
3769
/*
3770
* Otherwise, we let the common code handle this.
3771
*/
3772
return (cam_periph_error(ccb, cflgs, sflgs));
3773
3774
/*
3775
* XXX: To Be Fixed
3776
* We cannot depend upon CAM honoring retry counts for these.
3777
*/
3778
case CAM_SCSI_BUS_RESET:
3779
case CAM_BDR_SENT:
3780
if (ccb->ccb_h.retry_count <= 0) {
3781
return (EIO);
3782
}
3783
/* FALLTHROUGH */
3784
default:
3785
return (cam_periph_error(ccb, cflgs, sflgs));
3786
}
3787
3788
/*
3789
* Handle filemark, end of tape, mismatched record sizes....
3790
* From this point out, we're only handling read/write cases.
3791
* Handle writes && reads differently.
3792
*/
3793
3794
if (csio->cdb_io.cdb_bytes[0] == SA_WRITE) {
3795
if (sense_key == SSD_KEY_VOLUME_OVERFLOW) {
3796
csio->resid = resid;
3797
error = ENOSPC;
3798
} else if ((stream_valid != 0) && (stream_bits & SSD_EOM)) {
3799
softc->flags |= SA_FLAG_EOM_PENDING;
3800
/*
3801
* Grotesque as it seems, the few times
3802
* I've actually seen a non-zero resid,
3803
* the tape drive actually lied and had
3804
* written all the data!.
3805
*/
3806
csio->resid = 0;
3807
}
3808
} else {
3809
csio->resid = resid;
3810
if (sense_key == SSD_KEY_BLANK_CHECK) {
3811
if (softc->quirks & SA_QUIRK_1FM) {
3812
error = 0;
3813
softc->flags |= SA_FLAG_EOM_PENDING;
3814
} else {
3815
error = EIO;
3816
}
3817
} else if ((stream_valid != 0) && (stream_bits & SSD_FILEMARK)){
3818
if (softc->flags & SA_FLAG_FIXED) {
3819
error = -1;
3820
softc->flags |= SA_FLAG_EOF_PENDING;
3821
}
3822
/*
3823
* Unconditionally, if we detected a filemark on a read,
3824
* mark that we've run moved a file ahead.
3825
*/
3826
if (softc->fileno != (daddr_t) -1) {
3827
softc->fileno++;
3828
softc->blkno = 0;
3829
csio->ccb_h.ccb_pflags |= SA_POSITION_UPDATED;
3830
}
3831
}
3832
}
3833
3834
/*
3835
* Incorrect Length usually applies to read, but can apply to writes.
3836
*/
3837
if (error == 0 && (stream_valid != 0) && (stream_bits & SSD_ILI)) {
3838
if (info < 0) {
3839
xpt_print(csio->ccb_h.path, toobig,
3840
csio->dxfer_len - info);
3841
csio->resid = csio->dxfer_len;
3842
error = EIO;
3843
} else {
3844
csio->resid = resid;
3845
if (softc->flags & SA_FLAG_FIXED) {
3846
softc->flags |= SA_FLAG_EIO_PENDING;
3847
}
3848
/*
3849
* Bump the block number if we hadn't seen a filemark.
3850
* Do this independent of errors (we've moved anyway).
3851
*/
3852
if ((stream_valid == 0) ||
3853
(stream_bits & SSD_FILEMARK) == 0) {
3854
if (softc->blkno != (daddr_t) -1) {
3855
softc->blkno++;
3856
csio->ccb_h.ccb_pflags |=
3857
SA_POSITION_UPDATED;
3858
}
3859
}
3860
}
3861
}
3862
3863
if (error <= 0) {
3864
/*
3865
* Unfreeze the queue if frozen as we're not returning anything
3866
* to our waiters that would indicate an I/O error has occurred
3867
* (yet).
3868
*/
3869
QFRLS(ccb);
3870
error = 0;
3871
}
3872
return (error);
3873
}
3874
3875
static int
3876
sagetparams(struct cam_periph *periph, sa_params params_to_get,
3877
uint32_t *blocksize, uint8_t *density, uint32_t *numblocks,
3878
int *buff_mode, uint8_t *write_protect, uint8_t *speed,
3879
int *comp_supported, int *comp_enabled, uint32_t *comp_algorithm,
3880
sa_comp_t *tcs, struct scsi_control_data_prot_subpage *prot_page,
3881
int dp_size, int prot_changeable)
3882
{
3883
union ccb *ccb;
3884
void *mode_buffer;
3885
struct scsi_mode_header_6 *mode_hdr;
3886
struct scsi_mode_blk_desc *mode_blk;
3887
int mode_buffer_len;
3888
struct sa_softc *softc;
3889
uint8_t cpage;
3890
int error;
3891
cam_status status;
3892
3893
softc = (struct sa_softc *)periph->softc;
3894
ccb = cam_periph_getccb(periph, 1);
3895
if (softc->quirks & SA_QUIRK_NO_CPAGE)
3896
cpage = SA_DEVICE_CONFIGURATION_PAGE;
3897
else
3898
cpage = SA_DATA_COMPRESSION_PAGE;
3899
3900
retry:
3901
mode_buffer_len = sizeof(*mode_hdr) + sizeof(*mode_blk);
3902
3903
if (params_to_get & SA_PARAM_COMPRESSION) {
3904
if (softc->quirks & SA_QUIRK_NOCOMP) {
3905
*comp_supported = FALSE;
3906
params_to_get &= ~SA_PARAM_COMPRESSION;
3907
} else
3908
mode_buffer_len += sizeof (sa_comp_t);
3909
}
3910
3911
/* XXX Fix M_NOWAIT */
3912
mode_buffer = malloc(mode_buffer_len, M_SCSISA, M_NOWAIT | M_ZERO);
3913
if (mode_buffer == NULL) {
3914
xpt_release_ccb(ccb);
3915
return (ENOMEM);
3916
}
3917
mode_hdr = (struct scsi_mode_header_6 *)mode_buffer;
3918
mode_blk = (struct scsi_mode_blk_desc *)&mode_hdr[1];
3919
3920
/* it is safe to retry this */
3921
scsi_mode_sense(&ccb->csio, 5, NULL, MSG_SIMPLE_Q_TAG, FALSE,
3922
SMS_PAGE_CTRL_CURRENT, (params_to_get & SA_PARAM_COMPRESSION) ?
3923
cpage : SMS_VENDOR_SPECIFIC_PAGE, mode_buffer, mode_buffer_len,
3924
SSD_FULL_SIZE, softc->timeout_info[SA_TIMEOUT_MODE_SENSE]);
3925
3926
error = cam_periph_runccb(ccb, saerror, 0, SF_NO_PRINT,
3927
softc->device_stats);
3928
3929
status = ccb->ccb_h.status & CAM_STATUS_MASK;
3930
3931
if (error == EINVAL && (params_to_get & SA_PARAM_COMPRESSION) != 0) {
3932
/*
3933
* Hmm. Let's see if we can try another page...
3934
* If we've already done that, give up on compression
3935
* for this device and remember this for the future
3936
* and attempt the request without asking for compression
3937
* info.
3938
*/
3939
if (cpage == SA_DATA_COMPRESSION_PAGE) {
3940
cpage = SA_DEVICE_CONFIGURATION_PAGE;
3941
goto retry;
3942
}
3943
softc->quirks |= SA_QUIRK_NOCOMP;
3944
free(mode_buffer, M_SCSISA);
3945
goto retry;
3946
} else if (status == CAM_SCSI_STATUS_ERROR) {
3947
/* Tell the user about the fatal error. */
3948
scsi_sense_print(&ccb->csio);
3949
goto sagetparamsexit;
3950
}
3951
3952
/*
3953
* If the user only wants the compression information, and
3954
* the device doesn't send back the block descriptor, it's
3955
* no big deal. If the user wants more than just
3956
* compression, though, and the device doesn't pass back the
3957
* block descriptor, we need to send another mode sense to
3958
* get the block descriptor.
3959
*/
3960
if ((mode_hdr->blk_desc_len == 0) &&
3961
(params_to_get & SA_PARAM_COMPRESSION) &&
3962
(params_to_get & ~(SA_PARAM_COMPRESSION))) {
3963
/*
3964
* Decrease the mode buffer length by the size of
3965
* the compression page, to make sure the data
3966
* there doesn't get overwritten.
3967
*/
3968
mode_buffer_len -= sizeof (sa_comp_t);
3969
3970
/*
3971
* Now move the compression page that we presumably
3972
* got back down the memory chunk a little bit so
3973
* it doesn't get spammed.
3974
*/
3975
bcopy(&mode_hdr[0], &mode_hdr[1], sizeof (sa_comp_t));
3976
bzero(&mode_hdr[0], sizeof (mode_hdr[0]));
3977
3978
/*
3979
* Now, we issue another mode sense and just ask
3980
* for the block descriptor, etc.
3981
*/
3982
3983
scsi_mode_sense(&ccb->csio, 2, NULL, MSG_SIMPLE_Q_TAG, FALSE,
3984
SMS_PAGE_CTRL_CURRENT, SMS_VENDOR_SPECIFIC_PAGE,
3985
mode_buffer, mode_buffer_len, SSD_FULL_SIZE,
3986
softc->timeout_info[SA_TIMEOUT_MODE_SENSE]);
3987
3988
error = cam_periph_runccb(ccb, saerror, 0, SF_NO_PRINT,
3989
softc->device_stats);
3990
3991
if (error != 0)
3992
goto sagetparamsexit;
3993
}
3994
3995
if (params_to_get & SA_PARAM_BLOCKSIZE)
3996
*blocksize = scsi_3btoul(mode_blk->blklen);
3997
3998
if (params_to_get & SA_PARAM_NUMBLOCKS)
3999
*numblocks = scsi_3btoul(mode_blk->nblocks);
4000
4001
if (params_to_get & SA_PARAM_BUFF_MODE)
4002
*buff_mode = mode_hdr->dev_spec & SMH_SA_BUF_MODE_MASK;
4003
4004
if (params_to_get & SA_PARAM_DENSITY)
4005
*density = mode_blk->density;
4006
4007
if (params_to_get & SA_PARAM_WP)
4008
*write_protect = (mode_hdr->dev_spec & SMH_SA_WP)? TRUE : FALSE;
4009
4010
if (params_to_get & SA_PARAM_SPEED)
4011
*speed = mode_hdr->dev_spec & SMH_SA_SPEED_MASK;
4012
4013
if (params_to_get & SA_PARAM_COMPRESSION) {
4014
sa_comp_t *ntcs = (sa_comp_t *) &mode_blk[1];
4015
if (cpage == SA_DATA_COMPRESSION_PAGE) {
4016
struct scsi_data_compression_page *cp = &ntcs->dcomp;
4017
*comp_supported =
4018
(cp->dce_and_dcc & SA_DCP_DCC)? TRUE : FALSE;
4019
*comp_enabled =
4020
(cp->dce_and_dcc & SA_DCP_DCE)? TRUE : FALSE;
4021
*comp_algorithm = scsi_4btoul(cp->comp_algorithm);
4022
} else {
4023
struct scsi_dev_conf_page *cp = &ntcs->dconf;
4024
/*
4025
* We don't really know whether this device supports
4026
* Data Compression if the algorithm field is
4027
* zero. Just say we do.
4028
*/
4029
*comp_supported = TRUE;
4030
*comp_enabled =
4031
(cp->sel_comp_alg != SA_COMP_NONE)? TRUE : FALSE;
4032
*comp_algorithm = cp->sel_comp_alg;
4033
}
4034
if (tcs != NULL)
4035
bcopy(ntcs, tcs, sizeof (sa_comp_t));
4036
}
4037
4038
if ((params_to_get & SA_PARAM_DENSITY_EXT)
4039
&& (softc->scsi_rev >= SCSI_REV_SPC)) {
4040
int i;
4041
4042
for (i = 0; i < SA_DENSITY_TYPES; i++) {
4043
scsi_report_density_support(&ccb->csio,
4044
/*retries*/ 1,
4045
/*cbfcnp*/ NULL,
4046
/*tag_action*/ MSG_SIMPLE_Q_TAG,
4047
/*media*/ softc->density_type_bits[i] & SRDS_MEDIA,
4048
/*medium_type*/ softc->density_type_bits[i] &
4049
SRDS_MEDIUM_TYPE,
4050
/*data_ptr*/ softc->density_info[i],
4051
/*length*/ sizeof(softc->density_info[i]),
4052
/*sense_len*/ SSD_FULL_SIZE,
4053
/*timeout*/
4054
softc->timeout_info[SA_TIMEOUT_REP_DENSITY]);
4055
error = cam_periph_runccb(ccb, saerror, 0, SF_NO_PRINT,
4056
softc->device_stats);
4057
status = ccb->ccb_h.status & CAM_STATUS_MASK;
4058
4059
/*
4060
* Some tape drives won't support this command at
4061
* all, but hopefully we'll minimize that with the
4062
* check for SPC or greater support above. If they
4063
* don't support the default report (neither the
4064
* MEDIA or MEDIUM_TYPE bits set), then there is
4065
* really no point in continuing on to look for
4066
* other reports.
4067
*/
4068
if ((error != 0)
4069
|| (status != CAM_REQ_CMP)) {
4070
error = 0;
4071
softc->density_info_valid[i] = 0;
4072
if (softc->density_type_bits[i] == 0)
4073
break;
4074
else
4075
continue;
4076
}
4077
softc->density_info_valid[i] = ccb->csio.dxfer_len -
4078
ccb->csio.resid;
4079
}
4080
}
4081
4082
/*
4083
* Get logical block protection parameters if the drive supports it.
4084
*/
4085
if ((params_to_get & SA_PARAM_LBP)
4086
&& (softc->flags & SA_FLAG_PROTECT_SUPP)) {
4087
struct scsi_mode_header_10 *mode10_hdr;
4088
struct scsi_control_data_prot_subpage *dp_page;
4089
struct scsi_mode_sense_10 *cdb;
4090
struct sa_prot_state *prot;
4091
int dp_len, returned_len;
4092
4093
if (dp_size == 0)
4094
dp_size = sizeof(*dp_page);
4095
4096
dp_len = sizeof(*mode10_hdr) + dp_size;
4097
mode10_hdr = malloc(dp_len, M_SCSISA, M_NOWAIT | M_ZERO);
4098
if (mode10_hdr == NULL) {
4099
error = ENOMEM;
4100
goto sagetparamsexit;
4101
}
4102
4103
scsi_mode_sense_len(&ccb->csio,
4104
/*retries*/ 5,
4105
/*cbfcnp*/ NULL,
4106
/*tag_action*/ MSG_SIMPLE_Q_TAG,
4107
/*dbd*/ TRUE,
4108
/*page_code*/ (prot_changeable == 0) ?
4109
SMS_PAGE_CTRL_CURRENT :
4110
SMS_PAGE_CTRL_CHANGEABLE,
4111
/*page*/ SMS_CONTROL_MODE_PAGE,
4112
/*param_buf*/ (uint8_t *)mode10_hdr,
4113
/*param_len*/ dp_len,
4114
/*minimum_cmd_size*/ 10,
4115
/*sense_len*/ SSD_FULL_SIZE,
4116
/*timeout*/
4117
softc->timeout_info[SA_TIMEOUT_MODE_SENSE]);
4118
/*
4119
* XXX KDM we need to be able to set the subpage in the
4120
* fill function.
4121
*/
4122
cdb = (struct scsi_mode_sense_10 *)ccb->csio.cdb_io.cdb_bytes;
4123
cdb->subpage = SA_CTRL_DP_SUBPAGE_CODE;
4124
4125
error = cam_periph_runccb(ccb, saerror, 0, SF_NO_PRINT,
4126
softc->device_stats);
4127
if (error != 0) {
4128
free(mode10_hdr, M_SCSISA);
4129
goto sagetparamsexit;
4130
}
4131
4132
status = ccb->ccb_h.status & CAM_STATUS_MASK;
4133
if (status != CAM_REQ_CMP) {
4134
error = EINVAL;
4135
free(mode10_hdr, M_SCSISA);
4136
goto sagetparamsexit;
4137
}
4138
4139
/*
4140
* The returned data length at least has to be long enough
4141
* for us to look at length in the mode page header.
4142
*/
4143
returned_len = ccb->csio.dxfer_len - ccb->csio.resid;
4144
if (returned_len < sizeof(mode10_hdr->data_length)) {
4145
error = EINVAL;
4146
free(mode10_hdr, M_SCSISA);
4147
goto sagetparamsexit;
4148
}
4149
4150
returned_len = min(returned_len,
4151
sizeof(mode10_hdr->data_length) +
4152
scsi_2btoul(mode10_hdr->data_length));
4153
4154
dp_page = (struct scsi_control_data_prot_subpage *)
4155
&mode10_hdr[1];
4156
4157
/*
4158
* We also have to have enough data to include the prot_bits
4159
* in the subpage.
4160
*/
4161
if (returned_len < (sizeof(*mode10_hdr) +
4162
__offsetof(struct scsi_control_data_prot_subpage, prot_bits)
4163
+ sizeof(dp_page->prot_bits))) {
4164
error = EINVAL;
4165
free(mode10_hdr, M_SCSISA);
4166
goto sagetparamsexit;
4167
}
4168
4169
prot = &softc->prot_info.cur_prot_state;
4170
prot->prot_method = dp_page->prot_method;
4171
prot->pi_length = dp_page->pi_length &
4172
SA_CTRL_DP_PI_LENGTH_MASK;
4173
prot->lbp_w = (dp_page->prot_bits & SA_CTRL_DP_LBP_W) ? 1 :0;
4174
prot->lbp_r = (dp_page->prot_bits & SA_CTRL_DP_LBP_R) ? 1 :0;
4175
prot->rbdp = (dp_page->prot_bits & SA_CTRL_DP_RBDP) ? 1 :0;
4176
prot->initialized = 1;
4177
4178
if (prot_page != NULL)
4179
bcopy(dp_page, prot_page, min(sizeof(*prot_page),
4180
sizeof(*dp_page)));
4181
4182
free(mode10_hdr, M_SCSISA);
4183
}
4184
4185
if (CAM_DEBUGGED(periph->path, CAM_DEBUG_INFO)) {
4186
int idx;
4187
char *xyz = mode_buffer;
4188
xpt_print_path(periph->path);
4189
printf("Mode Sense Data=");
4190
for (idx = 0; idx < mode_buffer_len; idx++)
4191
printf(" 0x%02x", xyz[idx] & 0xff);
4192
printf("\n");
4193
}
4194
4195
sagetparamsexit:
4196
4197
xpt_release_ccb(ccb);
4198
free(mode_buffer, M_SCSISA);
4199
return (error);
4200
}
4201
4202
/*
4203
* Set protection information to the pending protection information stored
4204
* in the softc.
4205
*/
4206
static int
4207
sasetprot(struct cam_periph *periph, struct sa_prot_state *new_prot)
4208
{
4209
struct sa_softc *softc;
4210
struct scsi_control_data_prot_subpage *dp_page, *dp_changeable;
4211
struct scsi_mode_header_10 *mode10_hdr, *mode10_changeable;
4212
union ccb *ccb;
4213
uint8_t current_speed;
4214
size_t dp_size, dp_page_length;
4215
int dp_len, buff_mode;
4216
int error;
4217
4218
softc = (struct sa_softc *)periph->softc;
4219
mode10_hdr = NULL;
4220
mode10_changeable = NULL;
4221
ccb = NULL;
4222
4223
/*
4224
* Start off with the size set to the actual length of the page
4225
* that we have defined.
4226
*/
4227
dp_size = sizeof(*dp_changeable);
4228
dp_page_length = dp_size -
4229
__offsetof(struct scsi_control_data_prot_subpage, prot_method);
4230
4231
retry_length:
4232
4233
dp_len = sizeof(*mode10_changeable) + dp_size;
4234
mode10_changeable = malloc(dp_len, M_SCSISA, M_NOWAIT | M_ZERO);
4235
if (mode10_changeable == NULL) {
4236
error = ENOMEM;
4237
goto bailout;
4238
}
4239
4240
dp_changeable =
4241
(struct scsi_control_data_prot_subpage *)&mode10_changeable[1];
4242
4243
/*
4244
* First get the data protection page changeable parameters mask.
4245
* We need to know which parameters the drive supports changing.
4246
* We also need to know what the drive claims that its page length
4247
* is. The reason is that IBM drives in particular are very picky
4248
* about the page length. They want it (the length set in the
4249
* page structure itself) to be 28 bytes, and they want the
4250
* parameter list length specified in the mode select header to be
4251
* 40 bytes. So, to work with IBM drives as well as any other tape
4252
* drive, find out what the drive claims the page length is, and
4253
* make sure that we match that.
4254
*/
4255
error = sagetparams(periph, SA_PARAM_SPEED | SA_PARAM_LBP,
4256
NULL, NULL, NULL, &buff_mode, NULL, &current_speed, NULL, NULL,
4257
NULL, NULL, dp_changeable, dp_size, /*prot_changeable*/ 1);
4258
if (error != 0)
4259
goto bailout;
4260
4261
if (scsi_2btoul(dp_changeable->length) > dp_page_length) {
4262
dp_page_length = scsi_2btoul(dp_changeable->length);
4263
dp_size = dp_page_length +
4264
__offsetof(struct scsi_control_data_prot_subpage,
4265
prot_method);
4266
free(mode10_changeable, M_SCSISA);
4267
mode10_changeable = NULL;
4268
goto retry_length;
4269
}
4270
4271
mode10_hdr = malloc(dp_len, M_SCSISA, M_NOWAIT | M_ZERO);
4272
if (mode10_hdr == NULL) {
4273
error = ENOMEM;
4274
goto bailout;
4275
}
4276
4277
dp_page = (struct scsi_control_data_prot_subpage *)&mode10_hdr[1];
4278
4279
/*
4280
* Now grab the actual current settings in the page.
4281
*/
4282
error = sagetparams(periph, SA_PARAM_SPEED | SA_PARAM_LBP,
4283
NULL, NULL, NULL, &buff_mode, NULL, &current_speed, NULL, NULL,
4284
NULL, NULL, dp_page, dp_size, /*prot_changeable*/ 0);
4285
if (error != 0)
4286
goto bailout;
4287
4288
/* These two fields need to be 0 for MODE SELECT */
4289
scsi_ulto2b(0, mode10_hdr->data_length);
4290
mode10_hdr->medium_type = 0;
4291
/* We are not including a block descriptor */
4292
scsi_ulto2b(0, mode10_hdr->blk_desc_len);
4293
4294
mode10_hdr->dev_spec = current_speed;
4295
/* if set, set single-initiator buffering mode */
4296
if (softc->buffer_mode == SMH_SA_BUF_MODE_SIBUF) {
4297
mode10_hdr->dev_spec |= SMH_SA_BUF_MODE_SIBUF;
4298
}
4299
4300
/*
4301
* For each field, make sure that the drive allows changing it
4302
* before bringing in the user's setting.
4303
*/
4304
if (dp_changeable->prot_method != 0)
4305
dp_page->prot_method = new_prot->prot_method;
4306
4307
if (dp_changeable->pi_length & SA_CTRL_DP_PI_LENGTH_MASK) {
4308
dp_page->pi_length &= ~SA_CTRL_DP_PI_LENGTH_MASK;
4309
dp_page->pi_length |= (new_prot->pi_length &
4310
SA_CTRL_DP_PI_LENGTH_MASK);
4311
}
4312
if (dp_changeable->prot_bits & SA_CTRL_DP_LBP_W) {
4313
if (new_prot->lbp_w)
4314
dp_page->prot_bits |= SA_CTRL_DP_LBP_W;
4315
else
4316
dp_page->prot_bits &= ~SA_CTRL_DP_LBP_W;
4317
}
4318
4319
if (dp_changeable->prot_bits & SA_CTRL_DP_LBP_R) {
4320
if (new_prot->lbp_r)
4321
dp_page->prot_bits |= SA_CTRL_DP_LBP_R;
4322
else
4323
dp_page->prot_bits &= ~SA_CTRL_DP_LBP_R;
4324
}
4325
4326
if (dp_changeable->prot_bits & SA_CTRL_DP_RBDP) {
4327
if (new_prot->rbdp)
4328
dp_page->prot_bits |= SA_CTRL_DP_RBDP;
4329
else
4330
dp_page->prot_bits &= ~SA_CTRL_DP_RBDP;
4331
}
4332
4333
ccb = cam_periph_getccb(periph, 1);
4334
4335
scsi_mode_select_len(&ccb->csio,
4336
/*retries*/ 5,
4337
/*cbfcnp*/ NULL,
4338
/*tag_action*/ MSG_SIMPLE_Q_TAG,
4339
/*scsi_page_fmt*/ TRUE,
4340
/*save_pages*/ FALSE,
4341
/*param_buf*/ (uint8_t *)mode10_hdr,
4342
/*param_len*/ dp_len,
4343
/*minimum_cmd_size*/ 10,
4344
/*sense_len*/ SSD_FULL_SIZE,
4345
/*timeout*/
4346
softc->timeout_info[SA_TIMEOUT_MODE_SELECT]);
4347
4348
error = cam_periph_runccb(ccb, saerror, 0, 0, softc->device_stats);
4349
if (error != 0)
4350
goto bailout;
4351
4352
if ((ccb->ccb_h.status & CAM_STATUS_MASK) != CAM_REQ_CMP) {
4353
error = EINVAL;
4354
goto bailout;
4355
}
4356
4357
/*
4358
* The operation was successful. We could just copy the settings
4359
* the user requested, but just in case the drive ignored some of
4360
* our settings, let's ask for status again.
4361
*/
4362
error = sagetparams(periph, SA_PARAM_SPEED | SA_PARAM_LBP,
4363
NULL, NULL, NULL, &buff_mode, NULL, &current_speed, NULL, NULL,
4364
NULL, NULL, dp_page, dp_size, 0);
4365
4366
bailout:
4367
if (ccb != NULL)
4368
xpt_release_ccb(ccb);
4369
free(mode10_hdr, M_SCSISA);
4370
free(mode10_changeable, M_SCSISA);
4371
return (error);
4372
}
4373
4374
/*
4375
* The purpose of this function is to set one of four different parameters
4376
* for a tape drive:
4377
* - blocksize
4378
* - density
4379
* - compression / compression algorithm
4380
* - buffering mode
4381
*
4382
* The assumption is that this will be called from saioctl(), and therefore
4383
* from a process context. Thus the waiting malloc calls below. If that
4384
* assumption ever changes, the malloc calls should be changed to be
4385
* NOWAIT mallocs.
4386
*
4387
* Any or all of the four parameters may be set when this function is
4388
* called. It should handle setting more than one parameter at once.
4389
*/
4390
static int
4391
sasetparams(struct cam_periph *periph, sa_params params_to_set,
4392
uint32_t blocksize, uint8_t density, uint32_t calg,
4393
uint32_t sense_flags)
4394
{
4395
struct sa_softc *softc;
4396
uint32_t current_blocksize;
4397
uint32_t current_calg;
4398
uint8_t current_density;
4399
uint8_t current_speed;
4400
int comp_enabled, comp_supported;
4401
void *mode_buffer;
4402
int mode_buffer_len;
4403
struct scsi_mode_header_6 *mode_hdr;
4404
struct scsi_mode_blk_desc *mode_blk;
4405
sa_comp_t *ccomp, *cpage;
4406
int buff_mode;
4407
union ccb *ccb = NULL;
4408
int error;
4409
4410
softc = (struct sa_softc *)periph->softc;
4411
4412
ccomp = malloc(sizeof (sa_comp_t), M_SCSISA, M_NOWAIT);
4413
if (ccomp == NULL)
4414
return (ENOMEM);
4415
4416
/*
4417
* Since it doesn't make sense to set the number of blocks, or
4418
* write protection, we won't try to get the current value. We
4419
* always want to get the blocksize, so we can set it back to the
4420
* proper value.
4421
*/
4422
error = sagetparams(periph,
4423
params_to_set | SA_PARAM_BLOCKSIZE | SA_PARAM_SPEED,
4424
&current_blocksize, &current_density, NULL, &buff_mode, NULL,
4425
&current_speed, &comp_supported, &comp_enabled,
4426
&current_calg, ccomp, NULL, 0, 0);
4427
4428
if (error != 0) {
4429
free(ccomp, M_SCSISA);
4430
return (error);
4431
}
4432
4433
mode_buffer_len = sizeof(*mode_hdr) + sizeof(*mode_blk);
4434
if (params_to_set & SA_PARAM_COMPRESSION)
4435
mode_buffer_len += sizeof (sa_comp_t);
4436
4437
mode_buffer = malloc(mode_buffer_len, M_SCSISA, M_NOWAIT | M_ZERO);
4438
if (mode_buffer == NULL) {
4439
free(ccomp, M_SCSISA);
4440
return (ENOMEM);
4441
}
4442
4443
mode_hdr = (struct scsi_mode_header_6 *)mode_buffer;
4444
mode_blk = (struct scsi_mode_blk_desc *)&mode_hdr[1];
4445
4446
ccb = cam_periph_getccb(periph, 1);
4447
4448
retry:
4449
4450
if (params_to_set & SA_PARAM_COMPRESSION) {
4451
if (mode_blk) {
4452
cpage = (sa_comp_t *)&mode_blk[1];
4453
} else {
4454
cpage = (sa_comp_t *)&mode_hdr[1];
4455
}
4456
bcopy(ccomp, cpage, sizeof (sa_comp_t));
4457
cpage->hdr.pagecode &= ~0x80;
4458
} else
4459
cpage = NULL;
4460
4461
/*
4462
* If the caller wants us to set the blocksize, use the one they
4463
* pass in. Otherwise, use the blocksize we got back from the
4464
* mode select above.
4465
*/
4466
if (mode_blk) {
4467
if (params_to_set & SA_PARAM_BLOCKSIZE)
4468
scsi_ulto3b(blocksize, mode_blk->blklen);
4469
else
4470
scsi_ulto3b(current_blocksize, mode_blk->blklen);
4471
4472
/*
4473
* Set density if requested, else preserve old density.
4474
* SCSI_SAME_DENSITY only applies to SCSI-2 or better
4475
* devices, else density we've latched up in our softc.
4476
*/
4477
if (params_to_set & SA_PARAM_DENSITY) {
4478
mode_blk->density = density;
4479
} else if (softc->scsi_rev > SCSI_REV_CCS) {
4480
mode_blk->density = SCSI_SAME_DENSITY;
4481
} else {
4482
mode_blk->density = softc->media_density;
4483
}
4484
}
4485
4486
/*
4487
* For mode selects, these two fields must be zero.
4488
*/
4489
mode_hdr->data_length = 0;
4490
mode_hdr->medium_type = 0;
4491
4492
/* set the speed to the current value */
4493
mode_hdr->dev_spec = current_speed;
4494
4495
/* if set, set single-initiator buffering mode */
4496
if (softc->buffer_mode == SMH_SA_BUF_MODE_SIBUF) {
4497
mode_hdr->dev_spec |= SMH_SA_BUF_MODE_SIBUF;
4498
}
4499
4500
if (mode_blk)
4501
mode_hdr->blk_desc_len = sizeof(struct scsi_mode_blk_desc);
4502
else
4503
mode_hdr->blk_desc_len = 0;
4504
4505
/*
4506
* First, if the user wants us to set the compression algorithm or
4507
* just turn compression on, check to make sure that this drive
4508
* supports compression.
4509
*/
4510
if (params_to_set & SA_PARAM_COMPRESSION) {
4511
/*
4512
* If the compression algorithm is 0, disable compression.
4513
* If the compression algorithm is non-zero, enable
4514
* compression and set the compression type to the
4515
* specified compression algorithm, unless the algorithm is
4516
* MT_COMP_ENABLE. In that case, we look at the
4517
* compression algorithm that is currently set and if it is
4518
* non-zero, we leave it as-is. If it is zero, and we have
4519
* saved a compression algorithm from a time when
4520
* compression was enabled before, set the compression to
4521
* the saved value.
4522
*/
4523
switch (ccomp->hdr.pagecode & ~0x80) {
4524
case SA_DEVICE_CONFIGURATION_PAGE:
4525
{
4526
struct scsi_dev_conf_page *dcp = &cpage->dconf;
4527
if (calg == 0) {
4528
dcp->sel_comp_alg = SA_COMP_NONE;
4529
break;
4530
}
4531
if (calg != MT_COMP_ENABLE) {
4532
dcp->sel_comp_alg = calg;
4533
} else if (dcp->sel_comp_alg == SA_COMP_NONE &&
4534
softc->saved_comp_algorithm != 0) {
4535
dcp->sel_comp_alg = softc->saved_comp_algorithm;
4536
}
4537
break;
4538
}
4539
case SA_DATA_COMPRESSION_PAGE:
4540
if (ccomp->dcomp.dce_and_dcc & SA_DCP_DCC) {
4541
struct scsi_data_compression_page *dcp = &cpage->dcomp;
4542
if (calg == 0) {
4543
/*
4544
* Disable compression, but leave the
4545
* decompression and the capability bit
4546
* alone.
4547
*/
4548
dcp->dce_and_dcc = SA_DCP_DCC;
4549
dcp->dde_and_red |= SA_DCP_DDE;
4550
break;
4551
}
4552
/* enable compression && decompression */
4553
dcp->dce_and_dcc = SA_DCP_DCE | SA_DCP_DCC;
4554
dcp->dde_and_red |= SA_DCP_DDE;
4555
/*
4556
* If there, use compression algorithm from caller.
4557
* Otherwise, if there's a saved compression algorithm
4558
* and there is no current algorithm, use the saved
4559
* algorithm. Else parrot back what we got and hope
4560
* for the best.
4561
*/
4562
if (calg != MT_COMP_ENABLE) {
4563
scsi_ulto4b(calg, dcp->comp_algorithm);
4564
scsi_ulto4b(calg, dcp->decomp_algorithm);
4565
} else if (scsi_4btoul(dcp->comp_algorithm) == 0 &&
4566
softc->saved_comp_algorithm != 0) {
4567
scsi_ulto4b(softc->saved_comp_algorithm,
4568
dcp->comp_algorithm);
4569
scsi_ulto4b(softc->saved_comp_algorithm,
4570
dcp->decomp_algorithm);
4571
}
4572
break;
4573
}
4574
/*
4575
* Compression does not appear to be supported-
4576
* at least via the DATA COMPRESSION page. It
4577
* would be too much to ask us to believe that
4578
* the page itself is supported, but incorrectly
4579
* reports an ability to manipulate data compression,
4580
* so we'll assume that this device doesn't support
4581
* compression. We can just fall through for that.
4582
*/
4583
/* FALLTHROUGH */
4584
default:
4585
/*
4586
* The drive doesn't seem to support compression,
4587
* so turn off the set compression bit.
4588
*/
4589
params_to_set &= ~SA_PARAM_COMPRESSION;
4590
xpt_print(periph->path,
4591
"device does not seem to support compression\n");
4592
4593
/*
4594
* If that was the only thing the user wanted us to set,
4595
* clean up allocated resources and return with
4596
* 'operation not supported'.
4597
*/
4598
if (params_to_set == SA_PARAM_NONE) {
4599
free(mode_buffer, M_SCSISA);
4600
xpt_release_ccb(ccb);
4601
return (ENODEV);
4602
}
4603
4604
/*
4605
* That wasn't the only thing the user wanted us to set.
4606
* So, decrease the stated mode buffer length by the
4607
* size of the compression mode page.
4608
*/
4609
mode_buffer_len -= sizeof(sa_comp_t);
4610
}
4611
}
4612
4613
/* It is safe to retry this operation */
4614
scsi_mode_select(&ccb->csio, 5, NULL, MSG_SIMPLE_Q_TAG,
4615
(params_to_set & SA_PARAM_COMPRESSION)? TRUE : FALSE,
4616
FALSE, mode_buffer, mode_buffer_len, SSD_FULL_SIZE,
4617
softc->timeout_info[SA_TIMEOUT_MODE_SELECT]);
4618
4619
error = cam_periph_runccb(ccb, saerror, 0,
4620
sense_flags, softc->device_stats);
4621
4622
if (CAM_DEBUGGED(periph->path, CAM_DEBUG_INFO)) {
4623
int idx;
4624
char *xyz = mode_buffer;
4625
xpt_print_path(periph->path);
4626
printf("Err%d, Mode Select Data=", error);
4627
for (idx = 0; idx < mode_buffer_len; idx++)
4628
printf(" 0x%02x", xyz[idx] & 0xff);
4629
printf("\n");
4630
}
4631
4632
if (error) {
4633
/*
4634
* If we can, try without setting density/blocksize.
4635
*/
4636
if (mode_blk) {
4637
if ((params_to_set &
4638
(SA_PARAM_DENSITY|SA_PARAM_BLOCKSIZE)) == 0) {
4639
mode_blk = NULL;
4640
goto retry;
4641
}
4642
} else {
4643
mode_blk = (struct scsi_mode_blk_desc *)&mode_hdr[1];
4644
cpage = (sa_comp_t *)&mode_blk[1];
4645
}
4646
4647
/*
4648
* If we were setting the blocksize, and that failed, we
4649
* want to set it to its original value. If we weren't
4650
* setting the blocksize, we don't want to change it.
4651
*/
4652
scsi_ulto3b(current_blocksize, mode_blk->blklen);
4653
4654
/*
4655
* Set density if requested, else preserve old density.
4656
* SCSI_SAME_DENSITY only applies to SCSI-2 or better
4657
* devices, else density we've latched up in our softc.
4658
*/
4659
if (params_to_set & SA_PARAM_DENSITY) {
4660
mode_blk->density = current_density;
4661
} else if (softc->scsi_rev > SCSI_REV_CCS) {
4662
mode_blk->density = SCSI_SAME_DENSITY;
4663
} else {
4664
mode_blk->density = softc->media_density;
4665
}
4666
4667
if (params_to_set & SA_PARAM_COMPRESSION)
4668
bcopy(ccomp, cpage, sizeof (sa_comp_t));
4669
4670
/*
4671
* The retry count is the only CCB field that might have been
4672
* changed that we care about, so reset it back to 1.
4673
*/
4674
ccb->ccb_h.retry_count = 1;
4675
cam_periph_runccb(ccb, saerror, 0, sense_flags,
4676
softc->device_stats);
4677
}
4678
4679
xpt_release_ccb(ccb);
4680
4681
if (ccomp != NULL)
4682
free(ccomp, M_SCSISA);
4683
4684
if (params_to_set & SA_PARAM_COMPRESSION) {
4685
if (error) {
4686
softc->flags &= ~SA_FLAG_COMP_ENABLED;
4687
/*
4688
* Even if we get an error setting compression,
4689
* do not say that we don't support it. We could
4690
* have been wrong, or it may be media specific.
4691
* softc->flags &= ~SA_FLAG_COMP_SUPP;
4692
*/
4693
softc->saved_comp_algorithm = softc->comp_algorithm;
4694
softc->comp_algorithm = 0;
4695
} else {
4696
softc->flags |= SA_FLAG_COMP_ENABLED;
4697
softc->comp_algorithm = calg;
4698
}
4699
}
4700
4701
free(mode_buffer, M_SCSISA);
4702
return (error);
4703
}
4704
4705
static int
4706
saextget(struct cdev *dev, struct cam_periph *periph, struct sbuf *sb,
4707
struct mtextget *g)
4708
{
4709
int indent, error;
4710
char tmpstr[80];
4711
struct sa_softc *softc;
4712
int tmpint;
4713
uint32_t maxio_tmp;
4714
struct ccb_getdev cgd;
4715
4716
softc = (struct sa_softc *)periph->softc;
4717
4718
error = 0;
4719
4720
error = sagetparams_common(dev, periph);
4721
if (error)
4722
goto extget_bailout;
4723
if (!SA_IS_CTRL(dev) && !softc->open_pending_mount)
4724
sagetpos(periph);
4725
4726
indent = 0;
4727
SASBADDNODE(sb, indent, mtextget);
4728
/*
4729
* Basic CAM peripheral information.
4730
*/
4731
SASBADDVARSTR(sb, indent, periph->periph_name, %s, periph_name,
4732
strlen(periph->periph_name) + 1);
4733
SASBADDUINT(sb, indent, periph->unit_number, %u, unit_number);
4734
xpt_gdev_type(&cgd, periph->path);
4735
if ((cgd.ccb_h.status & CAM_STATUS_MASK) != CAM_REQ_CMP) {
4736
g->status = MT_EXT_GET_ERROR;
4737
snprintf(g->error_str, sizeof(g->error_str),
4738
"Error %#x returned for XPT_GDEV_TYPE CCB",
4739
cgd.ccb_h.status);
4740
goto extget_bailout;
4741
}
4742
4743
cam_strvis(tmpstr, cgd.inq_data.vendor,
4744
sizeof(cgd.inq_data.vendor), sizeof(tmpstr));
4745
SASBADDVARSTRDESC(sb, indent, tmpstr, %s, vendor,
4746
sizeof(cgd.inq_data.vendor) + 1, "SCSI Vendor ID");
4747
4748
cam_strvis(tmpstr, cgd.inq_data.product,
4749
sizeof(cgd.inq_data.product), sizeof(tmpstr));
4750
SASBADDVARSTRDESC(sb, indent, tmpstr, %s, product,
4751
sizeof(cgd.inq_data.product) + 1, "SCSI Product ID");
4752
4753
cam_strvis(tmpstr, cgd.inq_data.revision,
4754
sizeof(cgd.inq_data.revision), sizeof(tmpstr));
4755
SASBADDVARSTRDESC(sb, indent, tmpstr, %s, revision,
4756
sizeof(cgd.inq_data.revision) + 1, "SCSI Revision");
4757
4758
if (cgd.serial_num_len > 0) {
4759
char *tmpstr2;
4760
size_t ts2_len;
4761
int ts2_malloc;
4762
4763
ts2_len = 0;
4764
4765
if (cgd.serial_num_len > sizeof(tmpstr)) {
4766
ts2_len = cgd.serial_num_len + 1;
4767
ts2_malloc = 1;
4768
tmpstr2 = malloc(ts2_len, M_SCSISA, M_NOWAIT | M_ZERO);
4769
/*
4770
* The 80 characters allocated on the stack above
4771
* will handle the vast majority of serial numbers.
4772
* If we run into one that is larger than that, and
4773
* we can't malloc the length without blocking,
4774
* bail out with an out of memory error.
4775
*/
4776
if (tmpstr2 == NULL) {
4777
error = ENOMEM;
4778
goto extget_bailout;
4779
}
4780
} else {
4781
ts2_len = sizeof(tmpstr);
4782
ts2_malloc = 0;
4783
tmpstr2 = tmpstr;
4784
}
4785
4786
cam_strvis(tmpstr2, cgd.serial_num, cgd.serial_num_len,
4787
ts2_len);
4788
4789
SASBADDVARSTRDESC(sb, indent, tmpstr2, %s, serial_num,
4790
(ssize_t)cgd.serial_num_len + 1, "Serial Number");
4791
if (ts2_malloc != 0)
4792
free(tmpstr2, M_SCSISA);
4793
} else {
4794
/*
4795
* We return a serial_num element in any case, but it will
4796
* be empty if the device has no serial number.
4797
*/
4798
tmpstr[0] = '\0';
4799
SASBADDVARSTRDESC(sb, indent, tmpstr, %s, serial_num,
4800
(ssize_t)0, "Serial Number");
4801
}
4802
4803
SASBADDUINTDESC(sb, indent, softc->maxio, %u, maxio,
4804
"Maximum I/O size allowed by driver and controller");
4805
4806
SASBADDUINTDESC(sb, indent, softc->cpi_maxio, %u, cpi_maxio,
4807
"Maximum I/O size reported by controller");
4808
4809
SASBADDUINTDESC(sb, indent, softc->max_blk, %u, max_blk,
4810
"Maximum block size supported by tape drive and media");
4811
4812
SASBADDUINTDESC(sb, indent, softc->min_blk, %u, min_blk,
4813
"Minimum block size supported by tape drive and media");
4814
4815
SASBADDUINTDESC(sb, indent, softc->blk_gran, %u, blk_gran,
4816
"Block granularity supported by tape drive and media");
4817
4818
maxio_tmp = min(softc->max_blk, softc->maxio);
4819
4820
SASBADDUINTDESC(sb, indent, maxio_tmp, %u, max_effective_iosize,
4821
"Maximum possible I/O size");
4822
4823
SASBADDINTDESC(sb, indent, softc->flags & SA_FLAG_FIXED ? 1 : 0, %d,
4824
fixed_mode, "Set to 1 for fixed block mode, 0 for variable block");
4825
4826
/*
4827
* XXX KDM include SIM, bus, target, LUN?
4828
*/
4829
if (softc->flags & SA_FLAG_COMP_UNSUPP)
4830
tmpint = 0;
4831
else
4832
tmpint = 1;
4833
SASBADDINTDESC(sb, indent, tmpint, %d, compression_supported,
4834
"Set to 1 if compression is supported, 0 if not");
4835
if (softc->flags & SA_FLAG_COMP_ENABLED)
4836
tmpint = 1;
4837
else
4838
tmpint = 0;
4839
SASBADDINTDESC(sb, indent, tmpint, %d, compression_enabled,
4840
"Set to 1 if compression is enabled, 0 if not");
4841
SASBADDUINTDESC(sb, indent, softc->comp_algorithm, %u,
4842
compression_algorithm, "Numeric compression algorithm");
4843
4844
safillprot(softc, &indent, sb);
4845
4846
SASBADDUINTDESC(sb, indent, softc->media_blksize, %u,
4847
media_blocksize, "Block size reported by drive or set by user");
4848
SASBADDINTDESC(sb, indent, (intmax_t)softc->fileno, %jd,
4849
calculated_fileno, "Calculated file number, -1 if unknown");
4850
SASBADDINTDESC(sb, indent, (intmax_t)softc->blkno, %jd,
4851
calculated_rel_blkno, "Calculated block number relative to file, "
4852
"set to -1 if unknown");
4853
SASBADDINTDESC(sb, indent, (intmax_t)softc->rep_fileno, %jd,
4854
reported_fileno, "File number reported by drive, -1 if unknown");
4855
SASBADDINTDESC(sb, indent, (intmax_t)softc->rep_blkno, %jd,
4856
reported_blkno, "Block number relative to BOP/BOT reported by "
4857
"drive, -1 if unknown");
4858
SASBADDINTDESC(sb, indent, (intmax_t)softc->partition, %jd,
4859
partition, "Current partition number, 0 is the default");
4860
SASBADDINTDESC(sb, indent, softc->bop, %d, bop,
4861
"Set to 1 if drive is at the beginning of partition/tape, 0 if "
4862
"not, -1 if unknown");
4863
SASBADDINTDESC(sb, indent, softc->eop, %d, eop,
4864
"Set to 1 if drive is past early warning, 0 if not, -1 if unknown");
4865
SASBADDINTDESC(sb, indent, softc->bpew, %d, bpew,
4866
"Set to 1 if drive is past programmable early warning, 0 if not, "
4867
"-1 if unknown");
4868
SASBADDINTDESC(sb, indent, (intmax_t)softc->last_io_resid, %jd,
4869
residual, "Residual for the last I/O");
4870
/*
4871
* XXX KDM should we send a string with the current driver
4872
* status already decoded instead of a numeric value?
4873
*/
4874
SASBADDINTDESC(sb, indent, softc->dsreg, %d, dsreg,
4875
"Current state of the driver");
4876
4877
safilldensitysb(softc, &indent, sb);
4878
4879
SASBENDNODE(sb, indent, mtextget);
4880
4881
extget_bailout:
4882
4883
return (error);
4884
}
4885
4886
static int
4887
saparamget(struct sa_softc *softc, struct sbuf *sb)
4888
{
4889
int indent;
4890
4891
indent = 0;
4892
SASBADDNODE(sb, indent, mtparamget);
4893
SASBADDINTDESC(sb, indent, softc->sili, %d, sili,
4894
"Suppress an error on underlength variable reads");
4895
SASBADDINTDESC(sb, indent, softc->eot_warn, %d, eot_warn,
4896
"Return an error to warn that end of tape is approaching");
4897
safillprot(softc, &indent, sb);
4898
SASBENDNODE(sb, indent, mtparamget);
4899
4900
return (0);
4901
}
4902
4903
static void
4904
saprevent(struct cam_periph *periph, int action)
4905
{
4906
struct sa_softc *softc;
4907
union ccb *ccb;
4908
int error, sf;
4909
4910
softc = (struct sa_softc *)periph->softc;
4911
4912
if ((action == PR_ALLOW) && (softc->flags & SA_FLAG_TAPE_LOCKED) == 0)
4913
return;
4914
if ((action == PR_PREVENT) && (softc->flags & SA_FLAG_TAPE_LOCKED) != 0)
4915
return;
4916
4917
/*
4918
* We can be quiet about illegal requests.
4919
*/
4920
if (CAM_DEBUGGED(periph->path, CAM_DEBUG_INFO)) {
4921
sf = 0;
4922
} else
4923
sf = SF_QUIET_IR;
4924
4925
ccb = cam_periph_getccb(periph, 1);
4926
4927
/* It is safe to retry this operation */
4928
scsi_prevent(&ccb->csio, 5, NULL, MSG_SIMPLE_Q_TAG, action,
4929
SSD_FULL_SIZE, softc->timeout_info[SA_TIMEOUT_PREVENT]);
4930
4931
error = cam_periph_runccb(ccb, saerror, 0, sf, softc->device_stats);
4932
if (error == 0) {
4933
if (action == PR_ALLOW)
4934
softc->flags &= ~SA_FLAG_TAPE_LOCKED;
4935
else
4936
softc->flags |= SA_FLAG_TAPE_LOCKED;
4937
}
4938
4939
xpt_release_ccb(ccb);
4940
}
4941
4942
static int
4943
sarewind(struct cam_periph *periph)
4944
{
4945
union ccb *ccb;
4946
struct sa_softc *softc;
4947
int error;
4948
4949
softc = (struct sa_softc *)periph->softc;
4950
4951
ccb = cam_periph_getccb(periph, 1);
4952
4953
/* It is safe to retry this operation */
4954
scsi_rewind(&ccb->csio, 2, NULL, MSG_SIMPLE_Q_TAG, FALSE,
4955
SSD_FULL_SIZE, softc->timeout_info[SA_TIMEOUT_REWIND]);
4956
4957
softc->dsreg = MTIO_DSREG_REW;
4958
error = cam_periph_runccb(ccb, saerror, 0, 0, softc->device_stats);
4959
softc->dsreg = MTIO_DSREG_REST;
4960
4961
xpt_release_ccb(ccb);
4962
if (error == 0) {
4963
softc->partition = softc->fileno = softc->blkno = (daddr_t) 0;
4964
softc->rep_fileno = softc->rep_blkno = (daddr_t) 0;
4965
} else {
4966
softc->fileno = softc->blkno = (daddr_t) -1;
4967
softc->partition = (daddr_t) -1;
4968
softc->rep_fileno = softc->rep_blkno = (daddr_t) -1;
4969
}
4970
return (error);
4971
}
4972
4973
static int
4974
saspace(struct cam_periph *periph, int count, scsi_space_code code)
4975
{
4976
union ccb *ccb;
4977
struct sa_softc *softc;
4978
int error;
4979
4980
softc = (struct sa_softc *)periph->softc;
4981
4982
ccb = cam_periph_getccb(periph, 1);
4983
4984
/* This cannot be retried */
4985
4986
scsi_space(&ccb->csio, 0, NULL, MSG_SIMPLE_Q_TAG, code, count,
4987
SSD_FULL_SIZE, softc->timeout_info[SA_TIMEOUT_SPACE]);
4988
4989
/*
4990
* Clear residual because we will be using it.
4991
*/
4992
softc->last_ctl_resid = 0;
4993
4994
softc->dsreg = (count < 0)? MTIO_DSREG_REV : MTIO_DSREG_FWD;
4995
error = cam_periph_runccb(ccb, saerror, 0, 0, softc->device_stats);
4996
softc->dsreg = MTIO_DSREG_REST;
4997
4998
xpt_release_ccb(ccb);
4999
5000
/*
5001
* If a spacing operation has failed, we need to invalidate
5002
* this mount.
5003
*
5004
* If the spacing operation was setmarks or to end of recorded data,
5005
* we no longer know our relative position.
5006
*
5007
* If the spacing operations was spacing files in reverse, we
5008
* take account of the residual, but still check against less
5009
* than zero- if we've gone negative, we must have hit BOT.
5010
*
5011
* If the spacing operations was spacing records in reverse and
5012
* we have a residual, we've either hit BOT or hit a filemark.
5013
* In the former case, we know our new record number (0). In
5014
* the latter case, we have absolutely no idea what the real
5015
* record number is- we've stopped between the end of the last
5016
* record in the previous file and the filemark that stopped
5017
* our spacing backwards.
5018
*/
5019
if (error) {
5020
softc->fileno = softc->blkno = (daddr_t) -1;
5021
softc->rep_blkno = softc->partition = (daddr_t) -1;
5022
softc->rep_fileno = (daddr_t) -1;
5023
} else if (code == SS_SETMARKS || code == SS_EOD) {
5024
softc->fileno = softc->blkno = (daddr_t) -1;
5025
} else if (code == SS_FILEMARKS && softc->fileno != (daddr_t) -1) {
5026
softc->fileno += (count - softc->last_ctl_resid);
5027
if (softc->fileno < 0) /* we must of hit BOT */
5028
softc->fileno = 0;
5029
softc->blkno = 0;
5030
} else if (code == SS_BLOCKS && softc->blkno != (daddr_t) -1) {
5031
softc->blkno += (count - softc->last_ctl_resid);
5032
if (count < 0) {
5033
if (softc->last_ctl_resid || softc->blkno < 0) {
5034
if (softc->fileno == 0) {
5035
softc->blkno = 0;
5036
} else {
5037
softc->blkno = (daddr_t) -1;
5038
}
5039
}
5040
}
5041
}
5042
if (error == 0)
5043
sagetpos(periph);
5044
5045
return (error);
5046
}
5047
5048
static int
5049
sawritefilemarks(struct cam_periph *periph, int nmarks, int setmarks, int immed)
5050
{
5051
union ccb *ccb;
5052
struct sa_softc *softc;
5053
int error, nwm = 0;
5054
5055
softc = (struct sa_softc *)periph->softc;
5056
if (softc->open_rdonly)
5057
return (EBADF);
5058
5059
ccb = cam_periph_getccb(periph, 1);
5060
/*
5061
* Clear residual because we will be using it.
5062
*/
5063
softc->last_ctl_resid = 0;
5064
5065
softc->dsreg = MTIO_DSREG_FMK;
5066
/* this *must* not be retried */
5067
scsi_write_filemarks(&ccb->csio, 0, NULL, MSG_SIMPLE_Q_TAG,
5068
immed, setmarks, nmarks, SSD_FULL_SIZE,
5069
softc->timeout_info[SA_TIMEOUT_WRITE_FILEMARKS]);
5070
softc->dsreg = MTIO_DSREG_REST;
5071
5072
error = cam_periph_runccb(ccb, saerror, 0, 0, softc->device_stats);
5073
5074
if (error == 0 && nmarks) {
5075
struct sa_softc *softc = (struct sa_softc *)periph->softc;
5076
nwm = nmarks - softc->last_ctl_resid;
5077
softc->filemarks += nwm;
5078
}
5079
5080
xpt_release_ccb(ccb);
5081
5082
/*
5083
* Update relative positions (if we're doing that).
5084
*/
5085
if (error) {
5086
softc->fileno = softc->blkno = softc->partition = (daddr_t) -1;
5087
} else if (softc->fileno != (daddr_t) -1) {
5088
softc->fileno += nwm;
5089
softc->blkno = 0;
5090
}
5091
5092
/*
5093
* Ask the tape drive for position information.
5094
*/
5095
sagetpos(periph);
5096
5097
/*
5098
* If we got valid position information, since we just wrote a file
5099
* mark, we know we're at the file mark and block 0 after that
5100
* filemark.
5101
*/
5102
if (softc->rep_fileno != (daddr_t) -1) {
5103
softc->fileno = softc->rep_fileno;
5104
softc->blkno = 0;
5105
}
5106
5107
return (error);
5108
}
5109
5110
static int
5111
sagetpos(struct cam_periph *periph)
5112
{
5113
union ccb *ccb;
5114
struct scsi_tape_position_long_data long_pos;
5115
struct sa_softc *softc = (struct sa_softc *)periph->softc;
5116
int error;
5117
5118
if (softc->quirks & SA_QUIRK_NO_LONG_POS) {
5119
softc->rep_fileno = (daddr_t) -1;
5120
softc->rep_blkno = (daddr_t) -1;
5121
softc->bop = softc->eop = softc->bpew = -1;
5122
return (EOPNOTSUPP);
5123
}
5124
5125
bzero(&long_pos, sizeof(long_pos));
5126
5127
ccb = cam_periph_getccb(periph, CAM_PRIORITY_NORMAL);
5128
scsi_read_position_10(&ccb->csio,
5129
/*retries*/ 1,
5130
/*cbfcnp*/ NULL,
5131
/*tag_action*/ MSG_SIMPLE_Q_TAG,
5132
/*service_action*/ SA_RPOS_LONG_FORM,
5133
/*data_ptr*/ (uint8_t *)&long_pos,
5134
/*length*/ sizeof(long_pos),
5135
/*sense_len*/ SSD_FULL_SIZE,
5136
/*timeout*/
5137
softc->timeout_info[SA_TIMEOUT_READ_POSITION]);
5138
5139
softc->dsreg = MTIO_DSREG_RBSY;
5140
error = cam_periph_runccb(ccb, saerror, 0, SF_QUIET_IR,
5141
softc->device_stats);
5142
softc->dsreg = MTIO_DSREG_REST;
5143
5144
if (error == 0) {
5145
if (long_pos.flags & SA_RPOS_LONG_MPU) {
5146
/*
5147
* If the drive doesn't know what file mark it is
5148
* on, our calculated filemark isn't going to be
5149
* accurate either.
5150
*/
5151
softc->fileno = (daddr_t) -1;
5152
softc->rep_fileno = (daddr_t) -1;
5153
} else {
5154
softc->fileno = softc->rep_fileno =
5155
scsi_8btou64(long_pos.logical_file_num);
5156
}
5157
5158
if (long_pos.flags & SA_RPOS_LONG_LONU) {
5159
softc->partition = (daddr_t) -1;
5160
softc->rep_blkno = (daddr_t) -1;
5161
/*
5162
* If the tape drive doesn't know its block
5163
* position, we can't claim to know it either.
5164
*/
5165
softc->blkno = (daddr_t) -1;
5166
} else {
5167
softc->partition = scsi_4btoul(long_pos.partition);
5168
softc->rep_blkno =
5169
scsi_8btou64(long_pos.logical_object_num);
5170
}
5171
if (long_pos.flags & SA_RPOS_LONG_BOP)
5172
softc->bop = 1;
5173
else
5174
softc->bop = 0;
5175
5176
if (long_pos.flags & SA_RPOS_LONG_EOP)
5177
softc->eop = 1;
5178
else
5179
softc->eop = 0;
5180
5181
if ((long_pos.flags & SA_RPOS_LONG_BPEW)
5182
|| (softc->set_pews_status != 0)) {
5183
softc->bpew = 1;
5184
if (softc->set_pews_status > 0)
5185
softc->set_pews_status--;
5186
} else
5187
softc->bpew = 0;
5188
} else if (error == EINVAL) {
5189
/*
5190
* If this drive returned an invalid-request type error,
5191
* then it likely doesn't support the long form report.
5192
*/
5193
softc->quirks |= SA_QUIRK_NO_LONG_POS;
5194
}
5195
5196
if (error != 0) {
5197
softc->rep_fileno = softc->rep_blkno = (daddr_t) -1;
5198
softc->partition = (daddr_t) -1;
5199
softc->bop = softc->eop = softc->bpew = -1;
5200
}
5201
5202
xpt_release_ccb(ccb);
5203
5204
return (error);
5205
}
5206
5207
static int
5208
sardpos(struct cam_periph *periph, int hard, uint32_t *blkptr)
5209
{
5210
struct scsi_tape_position_data loc;
5211
union ccb *ccb;
5212
struct sa_softc *softc = (struct sa_softc *)periph->softc;
5213
int error;
5214
5215
/*
5216
* We try and flush any buffered writes here if we were writing
5217
* and we're trying to get hardware block position. It eats
5218
* up performance substantially, but I'm wary of drive firmware.
5219
*
5220
* I think that *logical* block position is probably okay-
5221
* but hardware block position might have to wait for data
5222
* to hit media to be valid. Caveat Emptor.
5223
*/
5224
5225
if (hard && (softc->flags & SA_FLAG_TAPE_WRITTEN)) {
5226
error = sawritefilemarks(periph, 0, 0, 0);
5227
if (error && error != EACCES)
5228
return (error);
5229
}
5230
5231
ccb = cam_periph_getccb(periph, 1);
5232
scsi_read_position(&ccb->csio, 1, NULL, MSG_SIMPLE_Q_TAG,
5233
hard, &loc, SSD_FULL_SIZE,
5234
softc->timeout_info[SA_TIMEOUT_READ_POSITION]);
5235
softc->dsreg = MTIO_DSREG_RBSY;
5236
error = cam_periph_runccb(ccb, saerror, 0, 0, softc->device_stats);
5237
softc->dsreg = MTIO_DSREG_REST;
5238
5239
if (error == 0) {
5240
if (loc.flags & SA_RPOS_UNCERTAIN) {
5241
error = EINVAL; /* nothing is certain */
5242
} else {
5243
*blkptr = scsi_4btoul(loc.firstblk);
5244
}
5245
}
5246
5247
xpt_release_ccb(ccb);
5248
return (error);
5249
}
5250
5251
static int
5252
sasetpos(struct cam_periph *periph, int hard, struct mtlocate *locate_info)
5253
{
5254
union ccb *ccb;
5255
struct sa_softc *softc;
5256
int locate16;
5257
int immed, cp;
5258
int error;
5259
5260
/*
5261
* We used to try and flush any buffered writes here.
5262
* Now we push this onto user applications to either
5263
* flush the pending writes themselves (via a zero count
5264
* WRITE FILEMARKS command) or they can trust their tape
5265
* drive to do this correctly for them.
5266
*/
5267
5268
softc = (struct sa_softc *)periph->softc;
5269
ccb = cam_periph_getccb(periph, 1);
5270
5271
cp = locate_info->flags & MT_LOCATE_FLAG_CHANGE_PART ? 1 : 0;
5272
immed = locate_info->flags & MT_LOCATE_FLAG_IMMED ? 1 : 0;
5273
5274
/*
5275
* Determine whether we have to use LOCATE or LOCATE16. The hard
5276
* bit is only possible with LOCATE, but the new ioctls do not
5277
* allow setting that bit. So we can't get into the situation of
5278
* having the hard bit set with a block address that is larger than
5279
* 32-bits.
5280
*/
5281
if (hard != 0)
5282
locate16 = 0;
5283
else if ((locate_info->dest_type != MT_LOCATE_DEST_OBJECT)
5284
|| (locate_info->block_address_mode != MT_LOCATE_BAM_IMPLICIT)
5285
|| (locate_info->logical_id > SA_SPOS_MAX_BLK))
5286
locate16 = 1;
5287
else
5288
locate16 = 0;
5289
5290
if (locate16 != 0) {
5291
scsi_locate_16(&ccb->csio,
5292
/*retries*/ 1,
5293
/*cbfcnp*/ NULL,
5294
/*tag_action*/ MSG_SIMPLE_Q_TAG,
5295
/*immed*/ immed,
5296
/*cp*/ cp,
5297
/*dest_type*/ locate_info->dest_type,
5298
/*bam*/ locate_info->block_address_mode,
5299
/*partition*/ locate_info->partition,
5300
/*logical_id*/ locate_info->logical_id,
5301
/*sense_len*/ SSD_FULL_SIZE,
5302
/*timeout*/
5303
softc->timeout_info[SA_TIMEOUT_LOCATE]);
5304
} else {
5305
scsi_locate_10(&ccb->csio,
5306
/*retries*/ 1,
5307
/*cbfcnp*/ NULL,
5308
/*tag_action*/ MSG_SIMPLE_Q_TAG,
5309
/*immed*/ immed,
5310
/*cp*/ cp,
5311
/*hard*/ hard,
5312
/*partition*/ locate_info->partition,
5313
/*block_address*/ locate_info->logical_id,
5314
/*sense_len*/ SSD_FULL_SIZE,
5315
/*timeout*/
5316
softc->timeout_info[SA_TIMEOUT_LOCATE]);
5317
}
5318
5319
softc->dsreg = MTIO_DSREG_POS;
5320
error = cam_periph_runccb(ccb, saerror, 0, 0, softc->device_stats);
5321
softc->dsreg = MTIO_DSREG_REST;
5322
xpt_release_ccb(ccb);
5323
5324
/*
5325
* We assume the calculated file and block numbers are unknown
5326
* unless we have enough information to populate them.
5327
*/
5328
softc->fileno = softc->blkno = (daddr_t) -1;
5329
5330
/*
5331
* If the user requested changing the partition and the request
5332
* succeeded, note the partition.
5333
*/
5334
if ((error == 0)
5335
&& (cp != 0))
5336
softc->partition = locate_info->partition;
5337
else
5338
softc->partition = (daddr_t) -1;
5339
5340
if (error == 0) {
5341
switch (locate_info->dest_type) {
5342
case MT_LOCATE_DEST_FILE:
5343
/*
5344
* This is the only case where we can reliably
5345
* calculate the file and block numbers.
5346
*/
5347
softc->fileno = locate_info->logical_id;
5348
softc->blkno = 0;
5349
break;
5350
case MT_LOCATE_DEST_OBJECT:
5351
case MT_LOCATE_DEST_SET:
5352
case MT_LOCATE_DEST_EOD:
5353
default:
5354
break;
5355
}
5356
}
5357
5358
/*
5359
* Ask the drive for current position information.
5360
*/
5361
sagetpos(periph);
5362
5363
return (error);
5364
}
5365
5366
static int
5367
saretension(struct cam_periph *periph)
5368
{
5369
union ccb *ccb;
5370
struct sa_softc *softc;
5371
int error;
5372
5373
softc = (struct sa_softc *)periph->softc;
5374
5375
ccb = cam_periph_getccb(periph, 1);
5376
5377
/* It is safe to retry this operation */
5378
scsi_load_unload(&ccb->csio, 5, NULL, MSG_SIMPLE_Q_TAG, FALSE,
5379
FALSE, TRUE, TRUE, SSD_FULL_SIZE,
5380
softc->timeout_info[SA_TIMEOUT_LOAD]);
5381
5382
softc->dsreg = MTIO_DSREG_TEN;
5383
error = cam_periph_runccb(ccb, saerror, 0, 0, softc->device_stats);
5384
softc->dsreg = MTIO_DSREG_REST;
5385
5386
xpt_release_ccb(ccb);
5387
if (error == 0) {
5388
softc->partition = softc->fileno = softc->blkno = (daddr_t) 0;
5389
sagetpos(periph);
5390
} else
5391
softc->partition = softc->fileno = softc->blkno = (daddr_t) -1;
5392
return (error);
5393
}
5394
5395
static int
5396
sareservereleaseunit(struct cam_periph *periph, int reserve)
5397
{
5398
union ccb *ccb;
5399
struct sa_softc *softc;
5400
int error;
5401
5402
softc = (struct sa_softc *)periph->softc;
5403
ccb = cam_periph_getccb(periph, 1);
5404
5405
/* It is safe to retry this operation */
5406
scsi_reserve_release_unit(&ccb->csio, 2, NULL, MSG_SIMPLE_Q_TAG,
5407
FALSE, 0, SSD_FULL_SIZE, softc->timeout_info[SA_TIMEOUT_RESERVE],
5408
reserve);
5409
softc->dsreg = MTIO_DSREG_RBSY;
5410
error = cam_periph_runccb(ccb, saerror, 0,
5411
SF_RETRY_UA | SF_NO_PRINT, softc->device_stats);
5412
softc->dsreg = MTIO_DSREG_REST;
5413
xpt_release_ccb(ccb);
5414
5415
/*
5416
* If the error was Illegal Request, then the device doesn't support
5417
* RESERVE/RELEASE. This is not an error.
5418
*/
5419
if (error == EINVAL) {
5420
error = 0;
5421
}
5422
5423
return (error);
5424
}
5425
5426
static int
5427
saloadunload(struct cam_periph *periph, int load)
5428
{
5429
union ccb *ccb;
5430
struct sa_softc *softc;
5431
int error;
5432
5433
softc = (struct sa_softc *)periph->softc;
5434
5435
ccb = cam_periph_getccb(periph, 1);
5436
5437
/* It is safe to retry this operation */
5438
scsi_load_unload(&ccb->csio, 5, NULL, MSG_SIMPLE_Q_TAG, FALSE,
5439
FALSE, FALSE, load, SSD_FULL_SIZE,
5440
softc->timeout_info[SA_TIMEOUT_LOAD]);
5441
5442
softc->dsreg = (load)? MTIO_DSREG_LD : MTIO_DSREG_UNL;
5443
error = cam_periph_runccb(ccb, saerror, 0, 0, softc->device_stats);
5444
softc->dsreg = MTIO_DSREG_REST;
5445
xpt_release_ccb(ccb);
5446
5447
if (error || load == 0) {
5448
softc->partition = softc->fileno = softc->blkno = (daddr_t) -1;
5449
softc->rep_fileno = softc->rep_blkno = (daddr_t) -1;
5450
} else if (error == 0) {
5451
softc->partition = softc->fileno = softc->blkno = (daddr_t) 0;
5452
sagetpos(periph);
5453
}
5454
return (error);
5455
}
5456
5457
static int
5458
saerase(struct cam_periph *periph, int longerase)
5459
{
5460
5461
union ccb *ccb;
5462
struct sa_softc *softc;
5463
int error;
5464
5465
softc = (struct sa_softc *)periph->softc;
5466
if (softc->open_rdonly)
5467
return (EBADF);
5468
5469
ccb = cam_periph_getccb(periph, 1);
5470
5471
scsi_erase(&ccb->csio, 1, NULL, MSG_SIMPLE_Q_TAG, FALSE, longerase,
5472
SSD_FULL_SIZE, softc->timeout_info[SA_TIMEOUT_ERASE]);
5473
5474
softc->dsreg = MTIO_DSREG_ZER;
5475
error = cam_periph_runccb(ccb, saerror, 0, 0, softc->device_stats);
5476
softc->dsreg = MTIO_DSREG_REST;
5477
5478
xpt_release_ccb(ccb);
5479
return (error);
5480
}
5481
5482
/*
5483
* Fill an sbuf with density data in XML format. This particular macro
5484
* works for multi-byte integer fields.
5485
*
5486
* Note that 1 byte fields aren't supported here. The reason is that the
5487
* compiler does not evaluate the sizeof(), and assumes that any of the
5488
* sizes are possible for a given field. So passing in a multi-byte
5489
* field will result in a warning that the assignment makes an integer
5490
* from a pointer without a cast, if there is an assignment in the 1 byte
5491
* case.
5492
*/
5493
#define SAFILLDENSSB(dens_data, sb, indent, field, desc_remain, \
5494
len_to_go, cur_offset, desc){ \
5495
size_t cur_field_len; \
5496
\
5497
cur_field_len = sizeof(dens_data->field); \
5498
if (desc_remain < cur_field_len) { \
5499
len_to_go -= desc_remain; \
5500
cur_offset += desc_remain; \
5501
continue; \
5502
} \
5503
len_to_go -= cur_field_len; \
5504
cur_offset += cur_field_len; \
5505
desc_remain -= cur_field_len; \
5506
\
5507
switch (sizeof(dens_data->field)) { \
5508
case 1: \
5509
KASSERT(1 == 0, ("Programmer error, invalid 1 byte " \
5510
"field width for SAFILLDENSFIELD")); \
5511
break; \
5512
case 2: \
5513
SASBADDUINTDESC(sb, indent, \
5514
scsi_2btoul(dens_data->field), %u, field, desc); \
5515
break; \
5516
case 3: \
5517
SASBADDUINTDESC(sb, indent, \
5518
scsi_3btoul(dens_data->field), %u, field, desc); \
5519
break; \
5520
case 4: \
5521
SASBADDUINTDESC(sb, indent, \
5522
scsi_4btoul(dens_data->field), %u, field, desc); \
5523
break; \
5524
case 8: \
5525
SASBADDUINTDESC(sb, indent, \
5526
(uintmax_t)scsi_8btou64(dens_data->field), %ju, \
5527
field, desc); \
5528
break; \
5529
default: \
5530
break; \
5531
} \
5532
};
5533
/*
5534
* Fill an sbuf with density data in XML format. This particular macro
5535
* works for strings.
5536
*/
5537
#define SAFILLDENSSBSTR(dens_data, sb, indent, field, desc_remain, \
5538
len_to_go, cur_offset, desc){ \
5539
size_t cur_field_len; \
5540
char tmpstr[32]; \
5541
\
5542
cur_field_len = sizeof(dens_data->field); \
5543
if (desc_remain < cur_field_len) { \
5544
len_to_go -= desc_remain; \
5545
cur_offset += desc_remain; \
5546
continue; \
5547
} \
5548
len_to_go -= cur_field_len; \
5549
cur_offset += cur_field_len; \
5550
desc_remain -= cur_field_len; \
5551
\
5552
cam_strvis(tmpstr, dens_data->field, \
5553
sizeof(dens_data->field), sizeof(tmpstr)); \
5554
SASBADDVARSTRDESC(sb, indent, tmpstr, %s, field, \
5555
strlen(tmpstr) + 1, desc); \
5556
};
5557
5558
/*
5559
* Fill an sbuf with density data descriptors.
5560
*/
5561
static void
5562
safilldenstypesb(struct sbuf *sb, int *indent, uint8_t *buf, int buf_len,
5563
int is_density)
5564
{
5565
struct scsi_density_hdr *hdr;
5566
uint32_t hdr_len;
5567
int len_to_go, cur_offset;
5568
int length_offset;
5569
int num_reports, need_close;
5570
5571
/*
5572
* We need at least the header length. Note that this isn't an
5573
* error, not all tape drives will have every data type.
5574
*/
5575
if (buf_len < sizeof(*hdr))
5576
goto bailout;
5577
5578
hdr = (struct scsi_density_hdr *)buf;
5579
hdr_len = scsi_2btoul(hdr->length);
5580
len_to_go = min(buf_len - sizeof(*hdr), hdr_len);
5581
if (is_density) {
5582
length_offset = __offsetof(struct scsi_density_data,
5583
bits_per_mm);
5584
} else {
5585
length_offset = __offsetof(struct scsi_medium_type_data,
5586
num_density_codes);
5587
}
5588
cur_offset = sizeof(*hdr);
5589
5590
num_reports = 0;
5591
need_close = 0;
5592
5593
while (len_to_go > length_offset) {
5594
struct scsi_density_data *dens_data;
5595
struct scsi_medium_type_data *type_data;
5596
int desc_remain;
5597
size_t cur_field_len;
5598
5599
dens_data = NULL;
5600
type_data = NULL;
5601
5602
if (is_density) {
5603
dens_data =(struct scsi_density_data *)&buf[cur_offset];
5604
if (dens_data->byte2 & SDD_DLV)
5605
desc_remain = scsi_2btoul(dens_data->length);
5606
else
5607
desc_remain = SDD_DEFAULT_LENGTH -
5608
length_offset;
5609
} else {
5610
type_data = (struct scsi_medium_type_data *)
5611
&buf[cur_offset];
5612
desc_remain = scsi_2btoul(type_data->length);
5613
}
5614
5615
len_to_go -= length_offset;
5616
desc_remain = min(desc_remain, len_to_go);
5617
cur_offset += length_offset;
5618
5619
if (need_close != 0) {
5620
SASBENDNODE(sb, *indent, density_entry);
5621
}
5622
5623
SASBADDNODENUM(sb, *indent, density_entry, num_reports);
5624
num_reports++;
5625
need_close = 1;
5626
5627
if (is_density) {
5628
SASBADDUINTDESC(sb, *indent,
5629
dens_data->primary_density_code, %u,
5630
primary_density_code, "Primary Density Code");
5631
SASBADDUINTDESC(sb, *indent,
5632
dens_data->secondary_density_code, %u,
5633
secondary_density_code, "Secondary Density Code");
5634
SASBADDUINTDESC(sb, *indent,
5635
dens_data->byte2 & ~SDD_DLV, %#x, density_flags,
5636
"Density Flags");
5637
5638
SAFILLDENSSB(dens_data, sb, *indent, bits_per_mm,
5639
desc_remain, len_to_go, cur_offset, "Bits per mm");
5640
SAFILLDENSSB(dens_data, sb, *indent, media_width,
5641
desc_remain, len_to_go, cur_offset, "Media width");
5642
SAFILLDENSSB(dens_data, sb, *indent, tracks,
5643
desc_remain, len_to_go, cur_offset,
5644
"Number of Tracks");
5645
SAFILLDENSSB(dens_data, sb, *indent, capacity,
5646
desc_remain, len_to_go, cur_offset, "Capacity");
5647
5648
SAFILLDENSSBSTR(dens_data, sb, *indent, assigning_org,
5649
desc_remain, len_to_go, cur_offset,
5650
"Assigning Organization");
5651
5652
SAFILLDENSSBSTR(dens_data, sb, *indent, density_name,
5653
desc_remain, len_to_go, cur_offset, "Density Name");
5654
5655
SAFILLDENSSBSTR(dens_data, sb, *indent, description,
5656
desc_remain, len_to_go, cur_offset, "Description");
5657
} else {
5658
int i;
5659
5660
SASBADDUINTDESC(sb, *indent, type_data->medium_type,
5661
%u, medium_type, "Medium Type");
5662
5663
cur_field_len =
5664
__offsetof(struct scsi_medium_type_data,
5665
media_width) -
5666
__offsetof(struct scsi_medium_type_data,
5667
num_density_codes);
5668
5669
if (desc_remain < cur_field_len) {
5670
len_to_go -= desc_remain;
5671
cur_offset += desc_remain;
5672
continue;
5673
}
5674
len_to_go -= cur_field_len;
5675
cur_offset += cur_field_len;
5676
desc_remain -= cur_field_len;
5677
5678
SASBADDINTDESC(sb, *indent,
5679
type_data->num_density_codes, %d,
5680
num_density_codes, "Number of Density Codes");
5681
SASBADDNODE(sb, *indent, density_code_list);
5682
for (i = 0; i < type_data->num_density_codes;
5683
i++) {
5684
SASBADDUINTDESC(sb, *indent,
5685
type_data->primary_density_codes[i], %u,
5686
density_code, "Density Code");
5687
}
5688
SASBENDNODE(sb, *indent, density_code_list);
5689
5690
SAFILLDENSSB(type_data, sb, *indent, media_width,
5691
desc_remain, len_to_go, cur_offset,
5692
"Media width");
5693
SAFILLDENSSB(type_data, sb, *indent, medium_length,
5694
desc_remain, len_to_go, cur_offset,
5695
"Medium length");
5696
5697
/*
5698
* Account for the two reserved bytes.
5699
*/
5700
cur_field_len = sizeof(type_data->reserved2);
5701
if (desc_remain < cur_field_len) {
5702
len_to_go -= desc_remain;
5703
cur_offset += desc_remain;
5704
continue;
5705
}
5706
len_to_go -= cur_field_len;
5707
cur_offset += cur_field_len;
5708
desc_remain -= cur_field_len;
5709
5710
SAFILLDENSSBSTR(type_data, sb, *indent, assigning_org,
5711
desc_remain, len_to_go, cur_offset,
5712
"Assigning Organization");
5713
SAFILLDENSSBSTR(type_data, sb, *indent,
5714
medium_type_name, desc_remain, len_to_go,
5715
cur_offset, "Medium type name");
5716
SAFILLDENSSBSTR(type_data, sb, *indent, description,
5717
desc_remain, len_to_go, cur_offset, "Description");
5718
}
5719
}
5720
if (need_close != 0) {
5721
SASBENDNODE(sb, *indent, density_entry);
5722
}
5723
5724
bailout:
5725
return;
5726
}
5727
5728
/*
5729
* Fill an sbuf with density data information
5730
*/
5731
static void
5732
safilldensitysb(struct sa_softc *softc, int *indent, struct sbuf *sb)
5733
{
5734
int i, is_density;
5735
5736
SASBADDNODE(sb, *indent, mtdensity);
5737
SASBADDUINTDESC(sb, *indent, softc->media_density, %u, media_density,
5738
"Current Medium Density");
5739
is_density = 0;
5740
for (i = 0; i < SA_DENSITY_TYPES; i++) {
5741
int tmpint;
5742
5743
if (softc->density_info_valid[i] == 0)
5744
continue;
5745
5746
SASBADDNODE(sb, *indent, density_report);
5747
if (softc->density_type_bits[i] & SRDS_MEDIUM_TYPE) {
5748
tmpint = 1;
5749
is_density = 0;
5750
} else {
5751
tmpint = 0;
5752
is_density = 1;
5753
}
5754
SASBADDINTDESC(sb, *indent, tmpint, %d, medium_type_report,
5755
"Medium type report");
5756
5757
if (softc->density_type_bits[i] & SRDS_MEDIA)
5758
tmpint = 1;
5759
else
5760
tmpint = 0;
5761
SASBADDINTDESC(sb, *indent, tmpint, %d, media_report,
5762
"Media report");
5763
5764
safilldenstypesb(sb, indent, softc->density_info[i],
5765
softc->density_info_valid[i], is_density);
5766
SASBENDNODE(sb, *indent, density_report);
5767
}
5768
SASBENDNODE(sb, *indent, mtdensity);
5769
}
5770
5771
/*
5772
* Given a completed REPORT SUPPORTED OPERATION CODES command with timeout
5773
* descriptors, go through the descriptors and set the sa(4) driver
5774
* timeouts to the recommended values.
5775
*/
5776
static void
5777
saloadtimeouts(struct sa_softc *softc, union ccb *ccb)
5778
{
5779
uint32_t valid_len, avail_len = 0, used_len = 0;
5780
struct scsi_report_supported_opcodes_all *hdr;
5781
struct scsi_report_supported_opcodes_descr *desc;
5782
uint8_t *buf;
5783
5784
hdr = (struct scsi_report_supported_opcodes_all *)ccb->csio.data_ptr;
5785
valid_len = ccb->csio.dxfer_len - ccb->csio.resid;
5786
5787
if (valid_len < sizeof(*hdr))
5788
return;
5789
5790
avail_len = scsi_4btoul(hdr->length) + sizeof(hdr->length);
5791
if ((avail_len != 0)
5792
&& (avail_len > valid_len)) {
5793
xpt_print(softc->periph->path, "WARNING: available timeout "
5794
"descriptor len %zu > valid len %u\n", avail_len,valid_len);
5795
}
5796
5797
used_len = sizeof(hdr->length);
5798
avail_len = MIN(avail_len, valid_len - sizeof(*hdr));
5799
buf = ccb->csio.data_ptr;
5800
while ((avail_len - used_len) > sizeof(*desc)) {
5801
struct scsi_report_supported_opcodes_timeout *td;
5802
uint32_t td_len;
5803
uint32_t rec_time;
5804
uint8_t *cur_ptr;
5805
5806
cur_ptr = &buf[used_len];
5807
desc = (struct scsi_report_supported_opcodes_descr *)cur_ptr;
5808
5809
used_len += sizeof(*desc);
5810
/* If there's no timeout descriptor, keep going */
5811
if ((desc->flags & RSO_CTDP) == 0)
5812
continue;
5813
5814
/*
5815
* If we don't have enough space to fit a timeout
5816
* descriptor then we're done.
5817
*/
5818
if ((avail_len - used_len) < sizeof(*td)) {
5819
used_len = avail_len;
5820
continue;
5821
}
5822
5823
cur_ptr = &buf[used_len];
5824
td = (struct scsi_report_supported_opcodes_timeout *)cur_ptr;
5825
td_len = scsi_2btoul(td->length);
5826
td_len += sizeof(td->length);
5827
used_len += td_len;
5828
5829
if (td_len < sizeof(*td))
5830
continue;
5831
5832
/*
5833
* Use the recommended timeout. The nominal time is the
5834
* time to wait before querying for status.
5835
*/
5836
rec_time = scsi_4btoul(td->recommended_time);
5837
5838
/*
5839
* Our timeouts are set in thousandths of a seconds.
5840
*/
5841
rec_time *= 1000;
5842
5843
switch(desc->opcode) {
5844
case ERASE:
5845
softc->timeout_info[SA_TIMEOUT_ERASE] = rec_time;
5846
break;
5847
case LOAD_UNLOAD:
5848
softc->timeout_info[SA_TIMEOUT_LOAD] = rec_time;
5849
break;
5850
case LOCATE:
5851
case LOCATE_16:
5852
/*
5853
* We are assuming these are the same timeout.
5854
*/
5855
softc->timeout_info[SA_TIMEOUT_LOCATE] = rec_time;
5856
break;
5857
case MODE_SELECT_6:
5858
case MODE_SELECT_10:
5859
/*
5860
* We are assuming these are the same timeout.
5861
*/
5862
softc->timeout_info[SA_TIMEOUT_MODE_SELECT] = rec_time;
5863
break;
5864
case MODE_SENSE_6:
5865
case MODE_SENSE_10:
5866
/*
5867
* We are assuming these are the same timeout.
5868
*/
5869
softc->timeout_info[SA_TIMEOUT_MODE_SENSE] = rec_time;
5870
break;
5871
case PREVENT_ALLOW:
5872
softc->timeout_info[SA_TIMEOUT_PREVENT] = rec_time;
5873
break;
5874
case SA_READ:
5875
softc->timeout_info[SA_TIMEOUT_READ] = rec_time;
5876
break;
5877
case READ_BLOCK_LIMITS:
5878
softc->timeout_info[SA_TIMEOUT_READ_BLOCK_LIMITS] =
5879
rec_time;
5880
break;
5881
case READ_POSITION:
5882
/*
5883
* Note that this may show up multiple times for
5884
* the short form, long form and extended form
5885
* service actions. We're assuming they are all
5886
* the same.
5887
*/
5888
softc->timeout_info[SA_TIMEOUT_READ_POSITION] =rec_time;
5889
break;
5890
case REPORT_DENSITY_SUPPORT:
5891
softc->timeout_info[SA_TIMEOUT_REP_DENSITY] = rec_time;
5892
break;
5893
case RESERVE_UNIT:
5894
case RELEASE_UNIT:
5895
/* We are assuming these are the same timeout.*/
5896
softc->timeout_info[SA_TIMEOUT_RESERVE] = rec_time;
5897
break;
5898
case REWIND:
5899
softc->timeout_info[SA_TIMEOUT_REWIND] = rec_time;
5900
break;
5901
case SPACE:
5902
softc->timeout_info[SA_TIMEOUT_SPACE] = rec_time;
5903
break;
5904
case TEST_UNIT_READY:
5905
softc->timeout_info[SA_TIMEOUT_TUR] = rec_time;
5906
break;
5907
case SA_WRITE:
5908
softc->timeout_info[SA_TIMEOUT_WRITE] = rec_time;
5909
break;
5910
case WRITE_FILEMARKS:
5911
softc->timeout_info[SA_TIMEOUT_WRITE_FILEMARKS] =
5912
rec_time;
5913
break;
5914
default:
5915
/*
5916
* We have explicit cases for all of the timeouts
5917
* we use.
5918
*/
5919
break;
5920
}
5921
}
5922
}
5923
5924
#endif /* _KERNEL */
5925
5926
/*
5927
* Read tape block limits command.
5928
*/
5929
void
5930
scsi_read_block_limits(struct ccb_scsiio *csio, uint32_t retries,
5931
void (*cbfcnp)(struct cam_periph *, union ccb *),
5932
uint8_t tag_action,
5933
struct scsi_read_block_limits_data *rlimit_buf,
5934
uint8_t sense_len, uint32_t timeout)
5935
{
5936
struct scsi_read_block_limits *scsi_cmd;
5937
5938
cam_fill_csio(csio, retries, cbfcnp, CAM_DIR_IN, tag_action,
5939
(uint8_t *)rlimit_buf, sizeof(*rlimit_buf), sense_len,
5940
sizeof(*scsi_cmd), timeout);
5941
5942
scsi_cmd = (struct scsi_read_block_limits *)&csio->cdb_io.cdb_bytes;
5943
bzero(scsi_cmd, sizeof(*scsi_cmd));
5944
scsi_cmd->opcode = READ_BLOCK_LIMITS;
5945
}
5946
5947
void
5948
scsi_sa_read_write(struct ccb_scsiio *csio, uint32_t retries,
5949
void (*cbfcnp)(struct cam_periph *, union ccb *),
5950
uint8_t tag_action, int readop, int sli,
5951
int fixed, uint32_t length, uint8_t *data_ptr,
5952
uint32_t dxfer_len, uint8_t sense_len, uint32_t timeout)
5953
{
5954
struct scsi_sa_rw *scsi_cmd;
5955
int read;
5956
5957
read = (readop & SCSI_RW_DIRMASK) == SCSI_RW_READ;
5958
5959
scsi_cmd = (struct scsi_sa_rw *)&csio->cdb_io.cdb_bytes;
5960
scsi_cmd->opcode = read ? SA_READ : SA_WRITE;
5961
scsi_cmd->sli_fixed = 0;
5962
if (sli && read)
5963
scsi_cmd->sli_fixed |= SAR_SLI;
5964
if (fixed)
5965
scsi_cmd->sli_fixed |= SARW_FIXED;
5966
scsi_ulto3b(length, scsi_cmd->length);
5967
scsi_cmd->control = 0;
5968
5969
cam_fill_csio(csio, retries, cbfcnp, (read ? CAM_DIR_IN : CAM_DIR_OUT) |
5970
((readop & SCSI_RW_BIO) != 0 ? CAM_DATA_BIO : 0),
5971
tag_action, data_ptr, dxfer_len, sense_len,
5972
sizeof(*scsi_cmd), timeout);
5973
}
5974
5975
void
5976
scsi_load_unload(struct ccb_scsiio *csio, uint32_t retries,
5977
void (*cbfcnp)(struct cam_periph *, union ccb *),
5978
uint8_t tag_action, int immediate, int eot,
5979
int reten, int load, uint8_t sense_len,
5980
uint32_t timeout)
5981
{
5982
struct scsi_load_unload *scsi_cmd;
5983
5984
scsi_cmd = (struct scsi_load_unload *)&csio->cdb_io.cdb_bytes;
5985
bzero(scsi_cmd, sizeof(*scsi_cmd));
5986
scsi_cmd->opcode = LOAD_UNLOAD;
5987
if (immediate)
5988
scsi_cmd->immediate = SLU_IMMED;
5989
if (eot)
5990
scsi_cmd->eot_reten_load |= SLU_EOT;
5991
if (reten)
5992
scsi_cmd->eot_reten_load |= SLU_RETEN;
5993
if (load)
5994
scsi_cmd->eot_reten_load |= SLU_LOAD;
5995
5996
cam_fill_csio(csio, retries, cbfcnp, CAM_DIR_NONE, tag_action,
5997
NULL, 0, sense_len, sizeof(*scsi_cmd), timeout);
5998
}
5999
6000
void
6001
scsi_rewind(struct ccb_scsiio *csio, uint32_t retries,
6002
void (*cbfcnp)(struct cam_periph *, union ccb *),
6003
uint8_t tag_action, int immediate, uint8_t sense_len,
6004
uint32_t timeout)
6005
{
6006
struct scsi_rewind *scsi_cmd;
6007
6008
scsi_cmd = (struct scsi_rewind *)&csio->cdb_io.cdb_bytes;
6009
bzero(scsi_cmd, sizeof(*scsi_cmd));
6010
scsi_cmd->opcode = REWIND;
6011
if (immediate)
6012
scsi_cmd->immediate = SREW_IMMED;
6013
6014
cam_fill_csio(csio, retries, cbfcnp, CAM_DIR_NONE, tag_action, NULL,
6015
0, sense_len, sizeof(*scsi_cmd), timeout);
6016
}
6017
6018
void
6019
scsi_space(struct ccb_scsiio *csio, uint32_t retries,
6020
void (*cbfcnp)(struct cam_periph *, union ccb *),
6021
uint8_t tag_action, scsi_space_code code,
6022
uint32_t count, uint8_t sense_len, uint32_t timeout)
6023
{
6024
struct scsi_space *scsi_cmd;
6025
6026
scsi_cmd = (struct scsi_space *)&csio->cdb_io.cdb_bytes;
6027
scsi_cmd->opcode = SPACE;
6028
scsi_cmd->code = code;
6029
scsi_ulto3b(count, scsi_cmd->count);
6030
scsi_cmd->control = 0;
6031
6032
cam_fill_csio(csio, retries, cbfcnp, CAM_DIR_NONE, tag_action, NULL,
6033
0, sense_len, sizeof(*scsi_cmd), timeout);
6034
}
6035
6036
void
6037
scsi_write_filemarks(struct ccb_scsiio *csio, uint32_t retries,
6038
void (*cbfcnp)(struct cam_periph *, union ccb *),
6039
uint8_t tag_action, int immediate, int setmark,
6040
uint32_t num_marks, uint8_t sense_len,
6041
uint32_t timeout)
6042
{
6043
struct scsi_write_filemarks *scsi_cmd;
6044
6045
scsi_cmd = (struct scsi_write_filemarks *)&csio->cdb_io.cdb_bytes;
6046
bzero(scsi_cmd, sizeof(*scsi_cmd));
6047
scsi_cmd->opcode = WRITE_FILEMARKS;
6048
if (immediate)
6049
scsi_cmd->byte2 |= SWFMRK_IMMED;
6050
if (setmark)
6051
scsi_cmd->byte2 |= SWFMRK_WSMK;
6052
6053
scsi_ulto3b(num_marks, scsi_cmd->num_marks);
6054
6055
cam_fill_csio(csio, retries, cbfcnp, CAM_DIR_NONE, tag_action, NULL,
6056
0, sense_len, sizeof(*scsi_cmd), timeout);
6057
}
6058
6059
/*
6060
* The reserve and release unit commands differ only by their opcodes.
6061
*/
6062
void
6063
scsi_reserve_release_unit(struct ccb_scsiio *csio, uint32_t retries,
6064
void (*cbfcnp)(struct cam_periph *, union ccb *),
6065
uint8_t tag_action, int third_party,
6066
int third_party_id, uint8_t sense_len,
6067
uint32_t timeout, int reserve)
6068
{
6069
struct scsi_reserve_release_unit *scsi_cmd;
6070
6071
scsi_cmd = (struct scsi_reserve_release_unit *)&csio->cdb_io.cdb_bytes;
6072
bzero(scsi_cmd, sizeof(*scsi_cmd));
6073
6074
if (reserve)
6075
scsi_cmd->opcode = RESERVE_UNIT;
6076
else
6077
scsi_cmd->opcode = RELEASE_UNIT;
6078
6079
if (third_party) {
6080
scsi_cmd->lun_thirdparty |= SRRU_3RD_PARTY;
6081
scsi_cmd->lun_thirdparty |=
6082
((third_party_id << SRRU_3RD_SHAMT) & SRRU_3RD_MASK);
6083
}
6084
6085
cam_fill_csio(csio, retries, cbfcnp, CAM_DIR_NONE, tag_action, NULL,
6086
0, sense_len, sizeof(*scsi_cmd), timeout);
6087
}
6088
6089
void
6090
scsi_erase(struct ccb_scsiio *csio, uint32_t retries,
6091
void (*cbfcnp)(struct cam_periph *, union ccb *),
6092
uint8_t tag_action, int immediate, int long_erase,
6093
uint8_t sense_len, uint32_t timeout)
6094
{
6095
struct scsi_erase *scsi_cmd;
6096
6097
scsi_cmd = (struct scsi_erase *)&csio->cdb_io.cdb_bytes;
6098
bzero(scsi_cmd, sizeof(*scsi_cmd));
6099
6100
scsi_cmd->opcode = ERASE;
6101
6102
if (immediate)
6103
scsi_cmd->lun_imm_long |= SE_IMMED;
6104
6105
if (long_erase)
6106
scsi_cmd->lun_imm_long |= SE_LONG;
6107
6108
cam_fill_csio(csio, retries, cbfcnp, CAM_DIR_NONE, tag_action, NULL,
6109
0, sense_len, sizeof(*scsi_cmd), timeout);
6110
}
6111
6112
/*
6113
* Read Tape Position command.
6114
*/
6115
void
6116
scsi_read_position(struct ccb_scsiio *csio, uint32_t retries,
6117
void (*cbfcnp)(struct cam_periph *, union ccb *),
6118
uint8_t tag_action, int hardsoft,
6119
struct scsi_tape_position_data *sbp,
6120
uint8_t sense_len, uint32_t timeout)
6121
{
6122
struct scsi_tape_read_position *scmd;
6123
6124
cam_fill_csio(csio, retries, cbfcnp, CAM_DIR_IN, tag_action,
6125
(uint8_t *)sbp, sizeof (*sbp), sense_len, sizeof(*scmd), timeout);
6126
scmd = (struct scsi_tape_read_position *)&csio->cdb_io.cdb_bytes;
6127
bzero(scmd, sizeof(*scmd));
6128
scmd->opcode = READ_POSITION;
6129
scmd->byte1 = hardsoft;
6130
}
6131
6132
/*
6133
* Read Tape Position command.
6134
*/
6135
void
6136
scsi_read_position_10(struct ccb_scsiio *csio, uint32_t retries,
6137
void (*cbfcnp)(struct cam_periph *, union ccb *),
6138
uint8_t tag_action, int service_action,
6139
uint8_t *data_ptr, uint32_t length,
6140
uint32_t sense_len, uint32_t timeout)
6141
{
6142
struct scsi_tape_read_position *scmd;
6143
6144
cam_fill_csio(csio,
6145
retries,
6146
cbfcnp,
6147
/*flags*/CAM_DIR_IN,
6148
tag_action,
6149
/*data_ptr*/data_ptr,
6150
/*dxfer_len*/length,
6151
sense_len,
6152
sizeof(*scmd),
6153
timeout);
6154
6155
scmd = (struct scsi_tape_read_position *)&csio->cdb_io.cdb_bytes;
6156
bzero(scmd, sizeof(*scmd));
6157
scmd->opcode = READ_POSITION;
6158
scmd->byte1 = service_action;
6159
/*
6160
* The length is only currently set (as of SSC4r03) if the extended
6161
* form is specified. The other forms have fixed lengths.
6162
*/
6163
if (service_action == SA_RPOS_EXTENDED_FORM)
6164
scsi_ulto2b(length, scmd->length);
6165
}
6166
6167
/*
6168
* Set Tape Position command.
6169
*/
6170
void
6171
scsi_set_position(struct ccb_scsiio *csio, uint32_t retries,
6172
void (*cbfcnp)(struct cam_periph *, union ccb *),
6173
uint8_t tag_action, int hardsoft, uint32_t blkno,
6174
uint8_t sense_len, uint32_t timeout)
6175
{
6176
struct scsi_tape_locate *scmd;
6177
6178
cam_fill_csio(csio, retries, cbfcnp, CAM_DIR_NONE, tag_action,
6179
(uint8_t *)NULL, 0, sense_len, sizeof(*scmd), timeout);
6180
scmd = (struct scsi_tape_locate *)&csio->cdb_io.cdb_bytes;
6181
bzero(scmd, sizeof(*scmd));
6182
scmd->opcode = LOCATE;
6183
if (hardsoft)
6184
scmd->byte1 |= SA_SPOS_BT;
6185
scsi_ulto4b(blkno, scmd->blkaddr);
6186
}
6187
6188
/*
6189
* XXX KDM figure out how to make a compatibility function.
6190
*/
6191
void
6192
scsi_locate_10(struct ccb_scsiio *csio, uint32_t retries,
6193
void (*cbfcnp)(struct cam_periph *, union ccb *),
6194
uint8_t tag_action, int immed, int cp, int hard,
6195
int64_t partition, uint32_t block_address,
6196
int sense_len, uint32_t timeout)
6197
{
6198
struct scsi_tape_locate *scmd;
6199
6200
cam_fill_csio(csio,
6201
retries,
6202
cbfcnp,
6203
CAM_DIR_NONE,
6204
tag_action,
6205
/*data_ptr*/ NULL,
6206
/*dxfer_len*/ 0,
6207
sense_len,
6208
sizeof(*scmd),
6209
timeout);
6210
scmd = (struct scsi_tape_locate *)&csio->cdb_io.cdb_bytes;
6211
bzero(scmd, sizeof(*scmd));
6212
scmd->opcode = LOCATE;
6213
if (immed)
6214
scmd->byte1 |= SA_SPOS_IMMED;
6215
if (cp)
6216
scmd->byte1 |= SA_SPOS_CP;
6217
if (hard)
6218
scmd->byte1 |= SA_SPOS_BT;
6219
scsi_ulto4b(block_address, scmd->blkaddr);
6220
scmd->partition = partition;
6221
}
6222
6223
void
6224
scsi_locate_16(struct ccb_scsiio *csio, uint32_t retries,
6225
void (*cbfcnp)(struct cam_periph *, union ccb *),
6226
uint8_t tag_action, int immed, int cp, uint8_t dest_type,
6227
int bam, int64_t partition, uint64_t logical_id,
6228
int sense_len, uint32_t timeout)
6229
{
6230
6231
struct scsi_locate_16 *scsi_cmd;
6232
6233
cam_fill_csio(csio,
6234
retries,
6235
cbfcnp,
6236
/*flags*/CAM_DIR_NONE,
6237
tag_action,
6238
/*data_ptr*/NULL,
6239
/*dxfer_len*/0,
6240
sense_len,
6241
sizeof(*scsi_cmd),
6242
timeout);
6243
6244
scsi_cmd = (struct scsi_locate_16 *)&csio->cdb_io.cdb_bytes;
6245
bzero(scsi_cmd, sizeof(*scsi_cmd));
6246
scsi_cmd->opcode = LOCATE_16;
6247
if (immed)
6248
scsi_cmd->byte1 |= SA_LC_IMMEDIATE;
6249
if (cp)
6250
scsi_cmd->byte1 |= SA_LC_CP;
6251
scsi_cmd->byte1 |= (dest_type << SA_LC_DEST_TYPE_SHIFT);
6252
6253
scsi_cmd->byte2 |= bam;
6254
scsi_cmd->partition = partition;
6255
scsi_u64to8b(logical_id, scsi_cmd->logical_id);
6256
}
6257
6258
void
6259
scsi_report_density_support(struct ccb_scsiio *csio, uint32_t retries,
6260
void (*cbfcnp)(struct cam_periph *, union ccb *),
6261
uint8_t tag_action, int media, int medium_type,
6262
uint8_t *data_ptr, uint32_t length,
6263
uint32_t sense_len, uint32_t timeout)
6264
{
6265
struct scsi_report_density_support *scsi_cmd;
6266
6267
scsi_cmd =(struct scsi_report_density_support *)&csio->cdb_io.cdb_bytes;
6268
bzero(scsi_cmd, sizeof(*scsi_cmd));
6269
6270
scsi_cmd->opcode = REPORT_DENSITY_SUPPORT;
6271
if (media != 0)
6272
scsi_cmd->byte1 |= SRDS_MEDIA;
6273
if (medium_type != 0)
6274
scsi_cmd->byte1 |= SRDS_MEDIUM_TYPE;
6275
6276
scsi_ulto2b(length, scsi_cmd->length);
6277
6278
cam_fill_csio(csio,
6279
retries,
6280
cbfcnp,
6281
/*flags*/CAM_DIR_IN,
6282
tag_action,
6283
/*data_ptr*/data_ptr,
6284
/*dxfer_len*/length,
6285
sense_len,
6286
sizeof(*scsi_cmd),
6287
timeout);
6288
}
6289
6290
void
6291
scsi_set_capacity(struct ccb_scsiio *csio, uint32_t retries,
6292
void (*cbfcnp)(struct cam_periph *, union ccb *),
6293
uint8_t tag_action, int byte1, uint32_t proportion,
6294
uint32_t sense_len, uint32_t timeout)
6295
{
6296
struct scsi_set_capacity *scsi_cmd;
6297
6298
scsi_cmd = (struct scsi_set_capacity *)&csio->cdb_io.cdb_bytes;
6299
bzero(scsi_cmd, sizeof(*scsi_cmd));
6300
6301
scsi_cmd->opcode = SET_CAPACITY;
6302
6303
scsi_cmd->byte1 = byte1;
6304
scsi_ulto2b(proportion, scsi_cmd->cap_proportion);
6305
6306
cam_fill_csio(csio,
6307
retries,
6308
cbfcnp,
6309
/*flags*/CAM_DIR_NONE,
6310
tag_action,
6311
/*data_ptr*/NULL,
6312
/*dxfer_len*/0,
6313
sense_len,
6314
sizeof(*scsi_cmd),
6315
timeout);
6316
}
6317
6318
void
6319
scsi_format_medium(struct ccb_scsiio *csio, uint32_t retries,
6320
void (*cbfcnp)(struct cam_periph *, union ccb *),
6321
uint8_t tag_action, int byte1, int byte2,
6322
uint8_t *data_ptr, uint32_t dxfer_len,
6323
uint32_t sense_len, uint32_t timeout)
6324
{
6325
struct scsi_format_medium *scsi_cmd;
6326
6327
scsi_cmd = (struct scsi_format_medium*)&csio->cdb_io.cdb_bytes;
6328
bzero(scsi_cmd, sizeof(*scsi_cmd));
6329
6330
scsi_cmd->opcode = FORMAT_MEDIUM;
6331
6332
scsi_cmd->byte1 = byte1;
6333
scsi_cmd->byte2 = byte2;
6334
6335
scsi_ulto2b(dxfer_len, scsi_cmd->length);
6336
6337
cam_fill_csio(csio,
6338
retries,
6339
cbfcnp,
6340
/*flags*/(dxfer_len > 0) ? CAM_DIR_OUT : CAM_DIR_NONE,
6341
tag_action,
6342
/*data_ptr*/ data_ptr,
6343
/*dxfer_len*/ dxfer_len,
6344
sense_len,
6345
sizeof(*scsi_cmd),
6346
timeout);
6347
}
6348
6349
void
6350
scsi_allow_overwrite(struct ccb_scsiio *csio, uint32_t retries,
6351
void (*cbfcnp)(struct cam_periph *, union ccb *),
6352
uint8_t tag_action, int allow_overwrite, int partition,
6353
uint64_t logical_id, uint32_t sense_len, uint32_t timeout)
6354
{
6355
struct scsi_allow_overwrite *scsi_cmd;
6356
6357
scsi_cmd = (struct scsi_allow_overwrite *)&csio->cdb_io.cdb_bytes;
6358
bzero(scsi_cmd, sizeof(*scsi_cmd));
6359
6360
scsi_cmd->opcode = ALLOW_OVERWRITE;
6361
6362
scsi_cmd->allow_overwrite = allow_overwrite;
6363
scsi_cmd->partition = partition;
6364
scsi_u64to8b(logical_id, scsi_cmd->logical_id);
6365
6366
cam_fill_csio(csio,
6367
retries,
6368
cbfcnp,
6369
CAM_DIR_NONE,
6370
tag_action,
6371
/*data_ptr*/ NULL,
6372
/*dxfer_len*/ 0,
6373
sense_len,
6374
sizeof(*scsi_cmd),
6375
timeout);
6376
}
6377
6378