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