Print this page
4888 Undocument dma_req(9s)
4884 EOF scsi_hba_attach
4886 EOF ddi_dmae_getlim
4887 EOF ddi_iomin
4634 undocument scsi_hba_attach() and ddi_dma_lim(9s)
4630 clean stale references to ddi_iopb_alloc and ddi_iopb_free
Split |
Close |
Expand all |
Collapse all |
--- old/usr/src/uts/common/io/scsi/targets/st.c
+++ new/usr/src/uts/common/io/scsi/targets/st.c
1 1 /*
2 2 * CDDL HEADER START
3 3 *
4 4 * The contents of this file are subject to the terms of the
5 5 * Common Development and Distribution License (the "License").
6 6 * You may not use this file except in compliance with the License.
7 7 *
8 8 * You can obtain a copy of the license at usr/src/OPENSOLARIS.LICENSE
9 9 * or http://www.opensolaris.org/os/licensing.
10 10 * See the License for the specific language governing permissions
11 11 * and limitations under the License.
12 12 *
13 13 * When distributing Covered Code, include this CDDL HEADER in each
14 14 * file and include the License file at usr/src/OPENSOLARIS.LICENSE.
15 15 * If applicable, add the following below this CDDL HEADER, with the
16 16 * fields enclosed by brackets "[]" replaced with your own identifying
17 17 * information: Portions Copyright [yyyy] [name of copyright owner]
18 18 *
19 19 * CDDL HEADER END
20 20 */
21 21
22 22 /*
23 23 * Copyright (c) 1990, 2010, Oracle and/or its affiliates. All rights reserved.
24 24 * Copyright (c) 2011 Bayard G. Bell. All rights reserved.
25 25 */
26 26
27 27 /*
28 28 * SCSI SCSA-compliant and not-so-DDI-compliant Tape Driver
29 29 */
30 30
31 31 #if defined(lint) && !defined(DEBUG)
32 32 #define DEBUG 1
33 33 #endif
34 34
35 35 #include <sys/modctl.h>
36 36 #include <sys/scsi/scsi.h>
37 37 #include <sys/mtio.h>
38 38 #include <sys/scsi/targets/stdef.h>
39 39 #include <sys/file.h>
40 40 #include <sys/kstat.h>
41 41 #include <sys/ddidmareq.h>
42 42 #include <sys/ddi.h>
43 43 #include <sys/sunddi.h>
44 44 #include <sys/byteorder.h>
45 45
46 46 #define IOSP KSTAT_IO_PTR(un->un_stats)
47 47 /*
48 48 * stats maintained only for reads/writes as commands
49 49 * like rewind etc skew the wait/busy times
50 50 */
51 51 #define IS_RW(bp) ((bp)->b_bcount > 0)
52 52 #define ST_DO_KSTATS(bp, kstat_function) \
53 53 if ((bp != un->un_sbufp) && un->un_stats && IS_RW(bp)) { \
54 54 kstat_function(IOSP); \
55 55 }
56 56
57 57 #define ST_DO_ERRSTATS(un, x) \
58 58 if (un->un_errstats) { \
59 59 struct st_errstats *stp; \
60 60 stp = (struct st_errstats *)un->un_errstats->ks_data; \
61 61 stp->x.value.ul++; \
62 62 }
63 63
64 64 #define FILL_SCSI1_LUN(devp, pkt) \
65 65 if ((devp)->sd_inq->inq_ansi == 0x1) { \
66 66 int _lun; \
67 67 _lun = ddi_prop_get_int(DDI_DEV_T_ANY, (devp)->sd_dev, \
68 68 DDI_PROP_DONTPASS, SCSI_ADDR_PROP_LUN, 0); \
69 69 if (_lun > 0) { \
70 70 ((union scsi_cdb *)(pkt)->pkt_cdbp)->scc_lun = \
71 71 _lun; \
72 72 } \
73 73 }
74 74
75 75 /*
76 76 * get an available contig mem header, cp.
77 77 * when big_enough is true, we will return NULL, if no big enough
78 78 * contig mem is found.
79 79 * when big_enough is false, we will try to find cp containing big
80 80 * enough contig mem. if not found, we will ruturn the last cp available.
81 81 *
82 82 * used by st_get_contig_mem()
83 83 */
84 84 #define ST_GET_CONTIG_MEM_HEAD(un, cp, len, big_enough) { \
85 85 struct contig_mem *tmp_cp = NULL; \
86 86 for ((cp) = (un)->un_contig_mem; \
87 87 (cp) != NULL; \
88 88 tmp_cp = (cp), (cp) = (cp)->cm_next) { \
89 89 if (((cp)->cm_len >= (len)) || \
90 90 (!(big_enough) && ((cp)->cm_next == NULL))) { \
91 91 if (tmp_cp == NULL) { \
92 92 (un)->un_contig_mem = (cp)->cm_next; \
93 93 } else { \
94 94 tmp_cp->cm_next = (cp)->cm_next; \
95 95 } \
96 96 (cp)->cm_next = NULL; \
97 97 (un)->un_contig_mem_available_num--; \
98 98 break; \
99 99 } \
100 100 } \
101 101 }
102 102
103 103 #define ST_NUM_MEMBERS(array) (sizeof (array) / sizeof (array[0]))
104 104 #define COPY_POS(dest, source) bcopy(source, dest, sizeof (tapepos_t))
105 105 #define ISALNUM(byte) \
106 106 (((byte) >= 'a' && (byte) <= 'z') || \
107 107 ((byte) >= 'A' && (byte) <= 'Z') || \
108 108 ((byte) >= '0' && (byte) <= '9'))
109 109
110 110 #define ONE_K 1024
111 111
112 112 #define MAX_SPACE_CNT(cnt) if (cnt >= 0) { \
113 113 if (cnt > MIN(SP_CNT_MASK, INT32_MAX)) \
114 114 return (EINVAL); \
115 115 } else { \
116 116 if (-(cnt) > MIN(SP_CNT_MASK, INT32_MAX)) \
117 117 return (EINVAL); \
118 118 } \
119 119
120 120 /*
121 121 * Global External Data Definitions
122 122 */
123 123 extern struct scsi_key_strings scsi_cmds[];
124 124 extern uchar_t scsi_cdb_size[];
125 125
126 126 /*
127 127 * Local Static Data
128 128 */
129 129 static void *st_state;
130 130 static char *const st_label = "st";
131 131 static volatile int st_recov_sz = sizeof (recov_info);
132 132 static const char mp_misconf[] = {
133 133 "St Tape is misconfigured, MPxIO enabled and "
134 134 "tape-command-recovery-disable set in st.conf\n"
135 135 };
136 136
137 137 #ifdef __x86
138 138 /*
139 139 * We need to use below DMA attr to alloc physically contiguous
140 140 * memory to do I/O in big block size
141 141 */
142 142 static ddi_dma_attr_t st_contig_mem_dma_attr = {
143 143 DMA_ATTR_V0, /* version number */
144 144 0x0, /* lowest usable address */
145 145 0xFFFFFFFFull, /* high DMA address range */
146 146 0xFFFFFFFFull, /* DMA counter register */
147 147 1, /* DMA address alignment */
148 148 1, /* DMA burstsizes */
149 149 1, /* min effective DMA size */
150 150 0xFFFFFFFFull, /* max DMA xfer size */
151 151 0xFFFFFFFFull, /* segment boundary */
152 152 1, /* s/g list length */
153 153 1, /* granularity of device */
154 154 0 /* DMA transfer flags */
155 155 };
156 156
157 157 static ddi_device_acc_attr_t st_acc_attr = {
158 158 DDI_DEVICE_ATTR_V0,
159 159 DDI_NEVERSWAP_ACC,
160 160 DDI_STRICTORDER_ACC
161 161 };
162 162
163 163 /* set limitation for the number of contig_mem */
164 164 static int st_max_contig_mem_num = ST_MAX_CONTIG_MEM_NUM;
165 165 #endif
166 166
167 167 /*
168 168 * Tunable parameters
169 169 *
170 170 * DISCLAIMER
171 171 * ----------
172 172 * These parameters are intended for use only in system testing; if you use
173 173 * them in production systems, you do so at your own risk. Altering any
174 174 * variable not listed below may cause unpredictable system behavior.
175 175 *
176 176 * st_check_media_time
177 177 *
178 178 * Three second state check
179 179 *
180 180 * st_allow_large_xfer
181 181 *
182 182 * Gated with ST_NO_RECSIZE_LIMIT
183 183 *
184 184 * 0 - Transfers larger than 64KB will not be allowed
185 185 * regardless of the setting of ST_NO_RECSIZE_LIMIT
186 186 * 1 - Transfers larger than 64KB will be allowed
187 187 * if ST_NO_RECSIZE_LIMIT is TRUE for the drive
188 188 *
189 189 * st_report_soft_errors_on_close
190 190 *
191 191 * Gated with ST_SOFT_ERROR_REPORTING
192 192 *
193 193 * 0 - Errors will not be reported on close regardless
194 194 * of the setting of ST_SOFT_ERROR_REPORTING
195 195 *
196 196 * 1 - Errors will be reported on close if
197 197 * ST_SOFT_ERROR_REPORTING is TRUE for the drive
198 198 */
199 199 static int st_selection_retry_count = ST_SEL_RETRY_COUNT;
200 200 static int st_retry_count = ST_RETRY_COUNT;
201 201
202 202 static int st_io_time = ST_IO_TIME;
203 203 static int st_long_timeout_x = ST_LONG_TIMEOUT_X;
204 204
205 205 static int st_space_time = ST_SPACE_TIME;
206 206 static int st_long_space_time_x = ST_LONG_SPACE_TIME_X;
207 207
208 208 static int st_error_level = SCSI_ERR_RETRYABLE;
209 209 static int st_check_media_time = 3000000; /* 3 Second State Check */
210 210
211 211 static int st_max_throttle = ST_MAX_THROTTLE;
212 212
213 213 static clock_t st_wait_cmds_complete = ST_WAIT_CMDS_COMPLETE;
214 214
215 215 static int st_allow_large_xfer = 1;
216 216 static int st_report_soft_errors_on_close = 1;
217 217
218 218 /*
219 219 * End of tunable parameters list
220 220 */
221 221
222 222
223 223
224 224 /*
225 225 * Asynchronous I/O and persistent errors, refer to PSARC/1995/228
226 226 *
227 227 * Asynchronous I/O's main offering is that it is a non-blocking way to do
228 228 * reads and writes. The driver will queue up all the requests it gets and
229 229 * have them ready to transport to the HBA. Unfortunately, we cannot always
230 230 * just ship the I/O requests to the HBA, as there errors and exceptions
231 231 * that may happen when we don't want the HBA to continue. Therein comes
232 232 * the flush-on-errors capability. If the HBA supports it, then st will
233 233 * send in st_max_throttle I/O requests at the same time.
234 234 *
235 235 * Persistent errors : This was also reasonably simple. In the interrupt
236 236 * routines, if there was an error or exception (FM, LEOT, media error,
237 237 * transport error), the persistent error bits are set and shuts everything
238 238 * down, but setting the throttle to zero. If we hit and exception in the
239 239 * HBA, and flush-on-errors were set, we wait for all outstanding I/O's to
240 240 * come back (with CMD_ABORTED), then flush all bp's in the wait queue with
241 241 * the appropriate error, and this will preserve order. Of course, depending
242 242 * on the exception we have to show a zero read or write before we show
243 243 * errors back to the application.
244 244 */
245 245
246 246 extern const int st_ndrivetypes; /* defined in st_conf.c */
247 247 extern const struct st_drivetype st_drivetypes[];
248 248 extern const char st_conf_version[];
249 249
250 250 #ifdef STDEBUG
251 251 static int st_soft_error_report_debug = 0;
252 252 volatile int st_debug = 0;
253 253 static volatile dev_info_t *st_lastdev;
254 254 static kmutex_t st_debug_mutex;
255 255 #endif
256 256
257 257 #define ST_MT02_NAME "Emulex MT02 QIC-11/24 "
258 258
259 259 static const struct vid_drivetype {
260 260 char *vid;
261 261 char type;
262 262 } st_vid_dt[] = {
263 263 {"LTO-CVE ", MT_LTO},
264 264 {"QUANTUM ", MT_ISDLT},
265 265 {"SONY ", MT_ISAIT},
266 266 {"STK ", MT_ISSTK9840}
267 267 };
268 268
269 269 static const struct driver_minor_data {
270 270 char *name;
271 271 int minor;
272 272 } st_minor_data[] = {
273 273 /*
274 274 * The top 4 entries are for the default densities,
275 275 * don't alter their position.
276 276 */
277 277 {"", 0},
278 278 {"n", MT_NOREWIND},
279 279 {"b", MT_BSD},
280 280 {"bn", MT_NOREWIND | MT_BSD},
281 281 {"l", MT_DENSITY1},
282 282 {"m", MT_DENSITY2},
283 283 {"h", MT_DENSITY3},
284 284 {"c", MT_DENSITY4},
285 285 {"u", MT_DENSITY4},
286 286 {"ln", MT_DENSITY1 | MT_NOREWIND},
287 287 {"mn", MT_DENSITY2 | MT_NOREWIND},
288 288 {"hn", MT_DENSITY3 | MT_NOREWIND},
289 289 {"cn", MT_DENSITY4 | MT_NOREWIND},
290 290 {"un", MT_DENSITY4 | MT_NOREWIND},
291 291 {"lb", MT_DENSITY1 | MT_BSD},
292 292 {"mb", MT_DENSITY2 | MT_BSD},
293 293 {"hb", MT_DENSITY3 | MT_BSD},
294 294 {"cb", MT_DENSITY4 | MT_BSD},
295 295 {"ub", MT_DENSITY4 | MT_BSD},
296 296 {"lbn", MT_DENSITY1 | MT_NOREWIND | MT_BSD},
297 297 {"mbn", MT_DENSITY2 | MT_NOREWIND | MT_BSD},
298 298 {"hbn", MT_DENSITY3 | MT_NOREWIND | MT_BSD},
299 299 {"cbn", MT_DENSITY4 | MT_NOREWIND | MT_BSD},
300 300 {"ubn", MT_DENSITY4 | MT_NOREWIND | MT_BSD}
301 301 };
302 302
303 303 /* strings used in many debug and warning messages */
304 304 static const char wr_str[] = "write";
305 305 static const char rd_str[] = "read";
306 306 static const char wrg_str[] = "writing";
307 307 static const char rdg_str[] = "reading";
308 308 static const char *space_strs[] = {
309 309 "records",
310 310 "filemarks",
311 311 "sequential filemarks",
312 312 "eod",
313 313 "setmarks",
314 314 "sequential setmarks",
315 315 "Reserved",
316 316 "Reserved"
317 317 };
318 318 static const char *load_strs[] = {
319 319 "unload", /* LD_UNLOAD 0 */
320 320 "load", /* LD_LOAD 1 */
321 321 "retension", /* LD_RETEN 2 */
322 322 "load reten", /* LD_LOAD | LD_RETEN 3 */
323 323 "eod", /* LD_EOT 4 */
324 324 "load EOD", /* LD_LOAD | LD_EOT 5 */
325 325 "reten EOD", /* LD_RETEN | LD_EOT 6 */
326 326 "load reten EOD" /* LD_LOAD|LD_RETEN|LD_EOT 7 */
327 327 "hold", /* LD_HOLD 8 */
328 328 "load and hold" /* LD_LOAD | LD_HOLD 9 */
329 329 };
330 330
331 331 static const char *errstatenames[] = {
332 332 "COMMAND_DONE",
333 333 "COMMAND_DONE_ERROR",
334 334 "COMMAND_DONE_ERROR_RECOVERED",
335 335 "QUE_COMMAND",
336 336 "QUE_BUSY_COMMAND",
337 337 "QUE_SENSE",
338 338 "JUST_RETURN",
339 339 "COMMAND_DONE_EACCES",
340 340 "QUE_LAST_COMMAND",
341 341 "COMMAND_TIMEOUT",
342 342 "PATH_FAILED",
343 343 "DEVICE_RESET",
344 344 "DEVICE_TAMPER",
345 345 "ATTEMPT_RETRY"
346 346 };
347 347
348 348 const char *bogusID = "Unknown Media ID";
349 349
350 350 /* default density offsets in the table above */
351 351 #define DEF_BLANK 0
352 352 #define DEF_NOREWIND 1
353 353 #define DEF_BSD 2
354 354 #define DEF_BSD_NR 3
355 355
356 356 /* Sense Key, ASC/ASCQ for which tape ejection is needed */
357 357
358 358 static struct tape_failure_code {
359 359 uchar_t key;
360 360 uchar_t add_code;
361 361 uchar_t qual_code;
362 362 } st_tape_failure_code[] = {
363 363 { KEY_HARDWARE_ERROR, 0x15, 0x01},
364 364 { KEY_HARDWARE_ERROR, 0x44, 0x00},
365 365 { KEY_HARDWARE_ERROR, 0x53, 0x00},
366 366 { KEY_HARDWARE_ERROR, 0x53, 0x01},
367 367 { KEY_NOT_READY, 0x53, 0x00},
368 368 { 0xff}
369 369 };
370 370
371 371 /* clean bit position and mask */
372 372
373 373 static struct cln_bit_position {
374 374 ushort_t cln_bit_byte;
375 375 uchar_t cln_bit_mask;
376 376 } st_cln_bit_position[] = {
377 377 { 21, 0x08},
378 378 { 70, 0xc0},
379 379 { 18, 0x81} /* 80 bit indicates in bit mode, 1 bit clean light is on */
380 380 };
381 381
382 382 /*
383 383 * architecture dependent allocation restrictions. For x86, we'll set
384 384 * dma_attr_addr_hi to st_max_phys_addr and dma_attr_sgllen to
385 385 * st_sgl_size during _init().
386 386 */
387 387 #if defined(__sparc)
388 388 static ddi_dma_attr_t st_alloc_attr = {
389 389 DMA_ATTR_V0, /* version number */
390 390 0x0, /* lowest usable address */
391 391 0xFFFFFFFFull, /* high DMA address range */
392 392 0xFFFFFFFFull, /* DMA counter register */
393 393 1, /* DMA address alignment */
394 394 1, /* DMA burstsizes */
395 395 1, /* min effective DMA size */
396 396 0xFFFFFFFFull, /* max DMA xfer size */
397 397 0xFFFFFFFFull, /* segment boundary */
398 398 1, /* s/g list length */
399 399 512, /* granularity of device */
400 400 0 /* DMA transfer flags */
401 401 };
402 402 #elif defined(__x86)
403 403 static ddi_dma_attr_t st_alloc_attr = {
404 404 DMA_ATTR_V0, /* version number */
405 405 0x0, /* lowest usable address */
406 406 0x0, /* high DMA address range [set in _init()] */
407 407 0xFFFFull, /* DMA counter register */
408 408 512, /* DMA address alignment */
409 409 1, /* DMA burstsizes */
410 410 1, /* min effective DMA size */
411 411 0xFFFFFFFFull, /* max DMA xfer size */
412 412 0xFFFFFFFFull, /* segment boundary */
413 413 0, /* s/g list length */
414 414 512, /* granularity of device [set in _init()] */
415 415 0 /* DMA transfer flags */
416 416 };
417 417 uint64_t st_max_phys_addr = 0xFFFFFFFFull;
418 418 int st_sgl_size = 0xF;
419 419
420 420 #endif
421 421
422 422 /*
423 423 * Configuration Data:
424 424 *
425 425 * Device driver ops vector
426 426 */
427 427 static int st_aread(dev_t dev, struct aio_req *aio, cred_t *cred_p);
428 428 static int st_awrite(dev_t dev, struct aio_req *aio, cred_t *cred_p);
429 429 static int st_read(dev_t dev, struct uio *uio_p, cred_t *cred_p);
430 430 static int st_write(dev_t dev, struct uio *uio_p, cred_t *cred_p);
431 431 static int st_open(dev_t *devp, int flag, int otyp, cred_t *cred_p);
432 432 static int st_close(dev_t dev, int flag, int otyp, cred_t *cred_p);
433 433 static int st_strategy(struct buf *bp);
434 434 static int st_queued_strategy(buf_t *bp);
435 435 static int st_ioctl(dev_t dev, int cmd, intptr_t arg, int flag,
436 436 cred_t *cred_p, int *rval_p);
437 437 extern int nulldev(), nodev();
438 438
439 439 static struct cb_ops st_cb_ops = {
440 440 st_open, /* open */
441 441 st_close, /* close */
442 442 st_queued_strategy, /* strategy Not Block device but async checks */
443 443 nodev, /* print */
444 444 nodev, /* dump */
445 445 st_read, /* read */
446 446 st_write, /* write */
447 447 st_ioctl, /* ioctl */
448 448 nodev, /* devmap */
449 449 nodev, /* mmap */
450 450 nodev, /* segmap */
451 451 nochpoll, /* poll */
452 452 ddi_prop_op, /* cb_prop_op */
453 453 0, /* streamtab */
454 454 D_64BIT | D_MP | D_NEW | D_HOTPLUG |
455 455 D_OPEN_RETURNS_EINTR, /* cb_flag */
456 456 CB_REV, /* cb_rev */
457 457 st_aread, /* async I/O read entry point */
458 458 st_awrite /* async I/O write entry point */
459 459
460 460 };
461 461
462 462 static int st_info(dev_info_t *dip, ddi_info_cmd_t infocmd, void *arg,
463 463 void **result);
464 464 static int st_probe(dev_info_t *dev);
465 465 static int st_attach(dev_info_t *dev, ddi_attach_cmd_t cmd);
466 466 static int st_detach(dev_info_t *dev, ddi_detach_cmd_t cmd);
467 467
468 468 static struct dev_ops st_ops = {
469 469 DEVO_REV, /* devo_rev, */
470 470 0, /* refcnt */
471 471 st_info, /* info */
472 472 nulldev, /* identify */
473 473 st_probe, /* probe */
474 474 st_attach, /* attach */
475 475 st_detach, /* detach */
476 476 nodev, /* reset */
477 477 &st_cb_ops, /* driver operations */
478 478 (struct bus_ops *)0, /* bus operations */
479 479 nulldev, /* power */
480 480 ddi_quiesce_not_needed, /* devo_quiesce */
481 481 };
482 482
483 483 /*
484 484 * Local Function Declarations
485 485 */
486 486 static char *st_print_scsi_cmd(char cmd);
487 487 static void st_print_cdb(dev_info_t *dip, char *label, uint_t level,
488 488 char *title, char *cdb);
489 489 static void st_clean_print(dev_info_t *dev, char *label, uint_t level,
490 490 char *title, char *data, int len);
491 491 static int st_doattach(struct scsi_device *devp, int (*canwait)());
492 492 static void st_known_tape_type(struct scsi_tape *un);
493 493 static int st_get_conf_from_st_dot_conf(struct scsi_tape *, char *,
494 494 struct st_drivetype *);
495 495 static int st_get_conf_from_st_conf_dot_c(struct scsi_tape *, char *,
496 496 struct st_drivetype *);
497 497 static int st_get_conf_from_tape_drive(struct scsi_tape *, char *,
498 498 struct st_drivetype *);
499 499 static int st_get_densities_from_tape_drive(struct scsi_tape *,
500 500 struct st_drivetype *);
501 501 static int st_get_timeout_values_from_tape_drive(struct scsi_tape *,
502 502 struct st_drivetype *);
503 503 static int st_get_timeouts_value(struct scsi_tape *, uchar_t, ushort_t *,
504 504 ushort_t);
505 505 static int st_get_default_conf(struct scsi_tape *, char *,
506 506 struct st_drivetype *);
507 507 static int st_rw(dev_t dev, struct uio *uio, int flag);
508 508 static int st_arw(dev_t dev, struct aio_req *aio, int flag);
509 509 static int st_find_eod(struct scsi_tape *un);
510 510 static int st_check_density_or_wfm(dev_t dev, int wfm, int mode, int stepflag);
511 511 static int st_uscsi_cmd(struct scsi_tape *un, struct uscsi_cmd *, int flag);
512 512 static int st_mtioctop(struct scsi_tape *un, intptr_t arg, int flag);
513 513 static int st_mtiocltop(struct scsi_tape *un, intptr_t arg, int flag);
514 514 static int st_do_mtioctop(struct scsi_tape *un, struct mtlop *mtop);
515 515 static void st_start(struct scsi_tape *un);
516 516 static int st_handle_start_busy(struct scsi_tape *un, struct buf *bp,
517 517 clock_t timeout_interval, int queued);
518 518 static int st_handle_intr_busy(struct scsi_tape *un, struct buf *bp,
519 519 clock_t timeout_interval);
520 520 static int st_handle_intr_retry_lcmd(struct scsi_tape *un, struct buf *bp);
521 521 static void st_done_and_mutex_exit(struct scsi_tape *un, struct buf *bp);
522 522 static void st_init(struct scsi_tape *un);
523 523 static void st_make_cmd(struct scsi_tape *un, struct buf *bp,
524 524 int (*func)(caddr_t));
525 525 static void st_make_uscsi_cmd(struct scsi_tape *, struct uscsi_cmd *,
526 526 struct buf *bp, int (*func)(caddr_t));
527 527 static void st_intr(struct scsi_pkt *pkt);
528 528 static void st_set_state(struct scsi_tape *un, buf_t *bp);
529 529 static void st_test_append(struct buf *bp);
530 530 static int st_runout(caddr_t);
531 531 static int st_cmd(struct scsi_tape *un, int com, int64_t count, int wait);
532 532 static int st_setup_cmd(struct scsi_tape *un, buf_t *bp, int com,
533 533 int64_t count);
534 534 static int st_set_compression(struct scsi_tape *un);
535 535 static int st_write_fm(dev_t dev, int wfm);
536 536 static int st_determine_generic(struct scsi_tape *un);
537 537 static int st_determine_density(struct scsi_tape *un, int rw);
538 538 static int st_get_density(struct scsi_tape *un);
539 539 static int st_set_density(struct scsi_tape *un);
540 540 static int st_loadtape(struct scsi_tape *un);
541 541 static int st_modesense(struct scsi_tape *un);
542 542 static int st_modeselect(struct scsi_tape *un);
543 543 static errstate st_handle_incomplete(struct scsi_tape *un, struct buf *bp);
544 544 static int st_wrongtapetype(struct scsi_tape *un);
545 545 static errstate st_check_error(struct scsi_tape *un, struct scsi_pkt *pkt);
546 546 static errstate st_handle_sense(struct scsi_tape *un, struct buf *bp,
547 547 tapepos_t *);
548 548 static errstate st_handle_autosense(struct scsi_tape *un, struct buf *bp,
549 549 tapepos_t *);
550 550 static int st_get_error_entry(struct scsi_tape *un, intptr_t arg, int flag);
551 551 static void st_update_error_stack(struct scsi_tape *un, struct scsi_pkt *pkt,
552 552 struct scsi_arq_status *cmd);
553 553 static void st_empty_error_stack(struct scsi_tape *un);
554 554 static errstate st_decode_sense(struct scsi_tape *un, struct buf *bp, int amt,
555 555 struct scsi_arq_status *, tapepos_t *);
556 556 static int st_report_soft_errors(dev_t dev, int flag);
557 557 static void st_delayed_cv_broadcast(void *arg);
558 558 static int st_check_media(dev_t dev, enum mtio_state state);
559 559 static int st_media_watch_cb(caddr_t arg, struct scsi_watch_result *resultp);
560 560 static void st_intr_restart(void *arg);
561 561 static void st_start_restart(void *arg);
562 562 static int st_gen_mode_sense(struct scsi_tape *un, ubufunc_t ubf, int page,
563 563 struct seq_mode *page_data, int page_size);
564 564 static int st_change_block_size(struct scsi_tape *un, uint32_t nblksz);
565 565 static int st_gen_mode_select(struct scsi_tape *un, ubufunc_t ubf,
566 566 struct seq_mode *page_data, int page_size);
567 567 static int st_read_block_limits(struct scsi_tape *un,
568 568 struct read_blklim *read_blk);
569 569 static int st_report_density_support(struct scsi_tape *un,
570 570 uchar_t *density_data, size_t buflen);
571 571 static int st_report_supported_operation(struct scsi_tape *un,
572 572 uchar_t *oper_data, uchar_t option_code, ushort_t service_action);
573 573 static int st_tape_init(struct scsi_tape *un);
574 574 static void st_flush(struct scsi_tape *un);
575 575 static void st_set_pe_errno(struct scsi_tape *un);
576 576 static void st_hba_unflush(struct scsi_tape *un);
577 577 static void st_turn_pe_on(struct scsi_tape *un);
578 578 static void st_turn_pe_off(struct scsi_tape *un);
579 579 static void st_set_pe_flag(struct scsi_tape *un);
580 580 static void st_clear_pe(struct scsi_tape *un);
581 581 static void st_wait_for_io(struct scsi_tape *un);
582 582 static int st_set_devconfig_page(struct scsi_tape *un, int compression_on);
583 583 static int st_set_datacomp_page(struct scsi_tape *un, int compression_on);
584 584 static int st_reserve_release(struct scsi_tape *un, int command, ubufunc_t ubf);
585 585 static int st_check_cdb_for_need_to_reserve(struct scsi_tape *un, uchar_t *cdb);
586 586 static int st_check_cmd_for_need_to_reserve(struct scsi_tape *un, uchar_t cmd,
587 587 int count);
588 588 static int st_take_ownership(struct scsi_tape *un, ubufunc_t ubf);
589 589 static int st_check_asc_ascq(struct scsi_tape *un);
590 590 static int st_check_clean_bit(struct scsi_tape *un);
591 591 static int st_check_alert_flags(struct scsi_tape *un);
592 592 static int st_check_sequential_clean_bit(struct scsi_tape *un);
593 593 static int st_check_sense_clean_bit(struct scsi_tape *un);
594 594 static int st_clear_unit_attentions(dev_t dev_instance, int max_trys);
595 595 static void st_calculate_timeouts(struct scsi_tape *un);
596 596 static writablity st_is_drive_worm(struct scsi_tape *un);
597 597 static int st_read_attributes(struct scsi_tape *un, uint16_t attribute,
598 598 void *buf, size_t size, ubufunc_t bufunc);
599 599 static int st_get_special_inquiry(struct scsi_tape *un, uchar_t size,
600 600 caddr_t dest, uchar_t page);
601 601 static int st_update_block_pos(struct scsi_tape *un, bufunc_t bf,
602 602 int post_space);
603 603 static int st_interpret_read_pos(struct scsi_tape const *un, tapepos_t *dest,
604 604 read_p_types type, size_t data_sz, const caddr_t responce, int post_space);
605 605 static int st_get_read_pos(struct scsi_tape *un, buf_t *bp);
606 606 static int st_logical_block_locate(struct scsi_tape *un, ubufunc_t ubf,
607 607 tapepos_t *pos, uint64_t lblk, uchar_t partition);
608 608 static int st_mtfsf_ioctl(struct scsi_tape *un, int64_t files);
609 609 static int st_mtfsr_ioctl(struct scsi_tape *un, int64_t count);
610 610 static int st_mtbsf_ioctl(struct scsi_tape *un, int64_t files);
611 611 static int st_mtnbsf_ioctl(struct scsi_tape *un, int64_t count);
612 612 static int st_mtbsr_ioctl(struct scsi_tape *un, int64_t num);
613 613 static int st_mtfsfm_ioctl(struct scsi_tape *un, int64_t cnt);
614 614 static int st_mtbsfm_ioctl(struct scsi_tape *un, int64_t cnt);
615 615 static int st_backward_space_files(struct scsi_tape *un, int64_t count,
616 616 int infront);
617 617 static int st_forward_space_files(struct scsi_tape *un, int64_t files);
618 618 static int st_scenic_route_to_begining_of_file(struct scsi_tape *un,
619 619 int32_t fileno);
620 620 static int st_space_to_begining_of_file(struct scsi_tape *un);
621 621 static int st_space_records(struct scsi_tape *un, int64_t records);
622 622 static int st_get_media_identification(struct scsi_tape *un, ubufunc_t bufunc);
623 623 static errstate st_command_recovery(struct scsi_tape *un, struct scsi_pkt *pkt,
624 624 errstate onentry);
625 625 static void st_recover(void *arg);
626 626 static void st_recov_cb(struct scsi_pkt *pkt);
627 627 static int st_rcmd(struct scsi_tape *un, int com, int64_t count, int wait);
628 628 static int st_uscsi_rcmd(struct scsi_tape *un, struct uscsi_cmd *ucmd,
629 629 int flag);
630 630 static void st_add_recovery_info_to_pkt(struct scsi_tape *un, buf_t *bp,
631 631 struct scsi_pkt *cmd);
632 632 static int st_check_mode_for_change(struct scsi_tape *un, ubufunc_t ubf);
633 633 static int st_test_path_to_device(struct scsi_tape *un);
634 634 static int st_recovery_read_pos(struct scsi_tape *un, read_p_types type,
635 635 read_pos_data_t *raw);
636 636 static int st_recovery_get_position(struct scsi_tape *un, tapepos_t *read,
637 637 read_pos_data_t *raw);
638 638 static int st_compare_expected_position(struct scsi_tape *un, st_err_info *ei,
639 639 cmd_attribute const * cmd_att, tapepos_t *read);
640 640 static errstate st_recover_reissue_pkt(struct scsi_tape *us,
641 641 struct scsi_pkt *pkt);
642 642 static int st_transport(struct scsi_tape *un, struct scsi_pkt *pkt);
643 643 static buf_t *st_remove_from_queue(buf_t **head, buf_t **tail, buf_t *bp);
644 644 static void st_add_to_queue(buf_t **head, buf_t **tail, buf_t *end, buf_t *bp);
645 645 static int st_reset(struct scsi_tape *un, int reset_type);
646 646 static void st_reset_notification(caddr_t arg);
647 647 static const cmd_attribute *st_lookup_cmd_attribute(unsigned char cmd);
648 648
649 649 static int st_set_target_TLR_mode(struct scsi_tape *un, ubufunc_t ubf);
650 650 static int st_make_sure_mode_data_is_correct(struct scsi_tape *un,
651 651 ubufunc_t ubf);
652 652
653 653 #ifdef __x86
654 654 /*
655 655 * routines for I/O in big block size
656 656 */
657 657 static void st_release_contig_mem(struct scsi_tape *un, struct contig_mem *cp);
658 658 static struct contig_mem *st_get_contig_mem(struct scsi_tape *un, size_t len,
659 659 int alloc_flags);
660 660 static int st_bigblk_xfer_done(struct buf *bp);
661 661 static struct buf *st_get_bigblk_bp(struct buf *bp);
662 662 #endif
663 663 static void st_print_position(dev_info_t *dev, char *label, uint_t level,
664 664 const char *comment, tapepos_t *pos);
665 665
666 666 /*
667 667 * error statistics create/update functions
668 668 */
669 669 static int st_create_errstats(struct scsi_tape *, int);
670 670 static int st_validate_tapemarks(struct scsi_tape *un, ubufunc_t ubf,
671 671 tapepos_t *pos);
672 672
673 673 #ifdef STDEBUG
674 674 static void st_debug_cmds(struct scsi_tape *un, int com, int count, int wait);
675 675 #endif /* STDEBUG */
676 676 static char *st_dev_name(dev_t dev);
677 677
678 678 #if !defined(lint)
679 679 _NOTE(SCHEME_PROTECTS_DATA("unique per pkt",
680 680 scsi_pkt buf uio scsi_cdb uscsi_cmd))
681 681 _NOTE(SCHEME_PROTECTS_DATA("unique per pkt", scsi_extended_sense scsi_status))
682 682 _NOTE(SCHEME_PROTECTS_DATA("unique per pkt", recov_info))
683 683 _NOTE(SCHEME_PROTECTS_DATA("stable data", scsi_device))
684 684 _NOTE(DATA_READABLE_WITHOUT_LOCK(st_drivetype scsi_address))
685 685 #endif
686 686
687 687 /*
688 688 * autoconfiguration routines.
689 689 */
690 690
691 691 static struct modldrv modldrv = {
692 692 &mod_driverops, /* Type of module. This one is a driver */
693 693 "SCSI tape Driver", /* Name of the module. */
694 694 &st_ops /* driver ops */
695 695 };
696 696
697 697 static struct modlinkage modlinkage = {
698 698 MODREV_1, &modldrv, NULL
699 699 };
700 700
701 701 /*
702 702 * Notes on Post Reset Behavior in the tape driver:
703 703 *
704 704 * When the tape drive is opened, the driver attempts to make sure that
705 705 * the tape head is positioned exactly where it was left when it was last
706 706 * closed provided the medium is not changed. If the tape drive is
707 707 * opened in O_NDELAY mode, the repositioning (if necessary for any loss
708 708 * of position due to reset) will happen when the first tape operation or
709 709 * I/O occurs. The repositioning (if required) may not be possible under
710 710 * certain situations such as when the device firmware not able to report
711 711 * the medium change in the REQUEST SENSE data because of a reset or a
712 712 * misbehaving bus not allowing the reposition to happen. In such
713 713 * extraordinary situations, where the driver fails to position the head
714 714 * at its original position, it will fail the open the first time, to
715 715 * save the applications from overwriting the data. All further attempts
716 716 * to open the tape device will result in the driver attempting to load
717 717 * the tape at BOT (beginning of tape). Also a warning message to
718 718 * indicate that further attempts to open the tape device may result in
719 719 * the tape being loaded at BOT will be printed on the console. If the
720 720 * tape device is opened in O_NDELAY mode, failure to restore the
721 721 * original tape head position, will result in the failure of the first
722 722 * tape operation or I/O, Further, the driver will invalidate its
723 723 * internal tape position which will necessitate the applications to
724 724 * validate the position by using either a tape positioning ioctl (such
725 725 * as MTREW) or closing and reopening the tape device.
726 726 *
727 727 */
728 728
729 729 int
730 730 _init(void)
731 731 {
732 732 int e;
733 733
734 734 if (((e = ddi_soft_state_init(&st_state,
735 735 sizeof (struct scsi_tape), ST_MAXUNIT)) != 0)) {
736 736 return (e);
737 737 }
738 738
739 739 if ((e = mod_install(&modlinkage)) != 0) {
740 740 ddi_soft_state_fini(&st_state);
741 741 } else {
742 742 #ifdef STDEBUG
743 743 mutex_init(&st_debug_mutex, NULL, MUTEX_DRIVER, NULL);
744 744 #endif
745 745
746 746 #if defined(__x86)
747 747 /* set the max physical address for iob allocs on x86 */
748 748 st_alloc_attr.dma_attr_addr_hi = st_max_phys_addr;
749 749
750 750 /*
751 751 * set the sgllen for iob allocs on x86. If this is set less
752 752 * than the number of pages the buffer will take
753 753 * (taking into account alignment), it would force the
754 754 * allocator to try and allocate contiguous pages.
755 755 */
756 756 st_alloc_attr.dma_attr_sgllen = st_sgl_size;
757 757 #endif
758 758 }
759 759
760 760 return (e);
761 761 }
762 762
763 763 int
764 764 _fini(void)
765 765 {
766 766 int e;
767 767
768 768 if ((e = mod_remove(&modlinkage)) != 0) {
769 769 return (e);
770 770 }
771 771
772 772 #ifdef STDEBUG
773 773 mutex_destroy(&st_debug_mutex);
774 774 #endif
775 775
776 776 ddi_soft_state_fini(&st_state);
777 777
778 778 return (e);
779 779 }
780 780
781 781 int
782 782 _info(struct modinfo *modinfop)
783 783 {
784 784 return (mod_info(&modlinkage, modinfop));
785 785 }
786 786
787 787
788 788 static int
789 789 st_probe(dev_info_t *devi)
790 790 {
791 791 int instance;
792 792 struct scsi_device *devp;
793 793 int rval;
794 794
795 795 #if !defined(__sparc)
796 796 char *tape_prop;
797 797 int tape_prop_len;
798 798 #endif
799 799
800 800 ST_ENTR(devi, st_probe);
801 801
802 802 /* If self identifying device */
803 803 if (ddi_dev_is_sid(devi) == DDI_SUCCESS) {
804 804 return (DDI_PROBE_DONTCARE);
805 805 }
806 806
807 807 #if !defined(__sparc)
808 808 /*
809 809 * Since some x86 HBAs have devnodes that look like SCSI as
810 810 * far as we can tell but aren't really SCSI (DADK, like mlx)
811 811 * we check for the presence of the "tape" property.
812 812 */
813 813 if (ddi_prop_op(DDI_DEV_T_NONE, devi, PROP_LEN_AND_VAL_ALLOC,
814 814 DDI_PROP_CANSLEEP, "tape",
815 815 (caddr_t)&tape_prop, &tape_prop_len) != DDI_PROP_SUCCESS) {
816 816 return (DDI_PROBE_FAILURE);
817 817 }
818 818 if (strncmp(tape_prop, "sctp", tape_prop_len) != 0) {
819 819 kmem_free(tape_prop, tape_prop_len);
820 820 return (DDI_PROBE_FAILURE);
821 821 }
822 822 kmem_free(tape_prop, tape_prop_len);
823 823 #endif
824 824
825 825 devp = ddi_get_driver_private(devi);
826 826 instance = ddi_get_instance(devi);
827 827
828 828 if (ddi_get_soft_state(st_state, instance) != NULL) {
829 829 return (DDI_PROBE_PARTIAL);
830 830 }
831 831
832 832
833 833 /*
834 834 * Turn around and call probe routine to see whether
835 835 * we actually have a tape at this SCSI nexus.
836 836 */
837 837 if (scsi_probe(devp, NULL_FUNC) == SCSIPROBE_EXISTS) {
838 838
839 839 /*
840 840 * In checking the whole inq_dtype byte we are looking at both
841 841 * the Peripheral Qualifier and the Peripheral Device Type.
842 842 * For this driver we are only interested in sequential devices
843 843 * that are connected or capable if connecting to this logical
844 844 * unit.
845 845 */
846 846 if (devp->sd_inq->inq_dtype ==
847 847 (DTYPE_SEQUENTIAL | DPQ_POSSIBLE)) {
848 848 ST_DEBUG6(devi, st_label, SCSI_DEBUG,
849 849 "probe exists\n");
850 850 rval = DDI_PROBE_SUCCESS;
851 851 } else {
852 852 rval = DDI_PROBE_FAILURE;
853 853 }
854 854 } else {
855 855 ST_DEBUG6(devi, st_label, SCSI_DEBUG,
856 856 "probe failure: nothing there\n");
857 857 rval = DDI_PROBE_FAILURE;
858 858 }
859 859 scsi_unprobe(devp);
860 860 return (rval);
861 861 }
862 862
863 863 static int
864 864 st_attach(dev_info_t *devi, ddi_attach_cmd_t cmd)
865 865 {
866 866 int instance;
867 867 int wide;
868 868 int dev_instance;
869 869 int ret_status;
870 870 struct scsi_device *devp;
871 871 int node_ix;
872 872 struct scsi_tape *un;
873 873
874 874 ST_ENTR(devi, st_attach);
875 875
876 876 devp = ddi_get_driver_private(devi);
877 877 instance = ddi_get_instance(devi);
878 878
879 879 switch (cmd) {
880 880 case DDI_ATTACH:
881 881 if (ddi_getprop(DDI_DEV_T_ANY, devi, DDI_PROP_DONTPASS,
882 882 "tape-command-recovery-disable", 0) != 0) {
883 883 st_recov_sz = sizeof (pkt_info);
884 884 }
885 885 if (st_doattach(devp, SLEEP_FUNC) == DDI_FAILURE) {
886 886 return (DDI_FAILURE);
887 887 }
888 888 break;
889 889 case DDI_RESUME:
890 890 /*
891 891 * Suspend/Resume
892 892 *
893 893 * When the driver suspended, there might be
894 894 * outstanding cmds and therefore we need to
895 895 * reset the suspended flag and resume the scsi
896 896 * watch thread and restart commands and timeouts
897 897 */
898 898
899 899 if (!(un = ddi_get_soft_state(st_state, instance))) {
900 900 return (DDI_FAILURE);
901 901 }
902 902 dev_instance = ((un->un_dev == 0) ? MTMINOR(instance) :
903 903 un->un_dev);
904 904
905 905 mutex_enter(ST_MUTEX);
906 906
907 907 un->un_throttle = un->un_max_throttle;
908 908 un->un_tids_at_suspend = 0;
909 909 un->un_pwr_mgmt = ST_PWR_NORMAL;
910 910
911 911 if (un->un_swr_token) {
912 912 scsi_watch_resume(un->un_swr_token);
913 913 }
914 914
915 915 /*
916 916 * Restart timeouts
917 917 */
918 918 if ((un->un_tids_at_suspend & ST_DELAY_TID) != 0) {
919 919 mutex_exit(ST_MUTEX);
920 920 un->un_delay_tid = timeout(
921 921 st_delayed_cv_broadcast, un,
922 922 drv_usectohz((clock_t)
923 923 MEDIA_ACCESS_DELAY));
924 924 mutex_enter(ST_MUTEX);
925 925 }
926 926
927 927 if (un->un_tids_at_suspend & ST_HIB_TID) {
928 928 mutex_exit(ST_MUTEX);
929 929 un->un_hib_tid = timeout(st_intr_restart, un,
930 930 ST_STATUS_BUSY_TIMEOUT);
931 931 mutex_enter(ST_MUTEX);
932 932 }
933 933
934 934 ret_status = st_clear_unit_attentions(dev_instance, 5);
935 935
936 936 /*
937 937 * now check if we need to restore the tape position
938 938 */
939 939 if ((un->un_suspend_pos.pmode != invalid) &&
940 940 ((un->un_suspend_pos.fileno > 0) ||
941 941 (un->un_suspend_pos.blkno > 0)) ||
942 942 (un->un_suspend_pos.lgclblkno > 0)) {
943 943 if (ret_status != 0) {
944 944 /*
945 945 * tape didn't get good TUR
946 946 * just print out error messages
947 947 */
948 948 scsi_log(ST_DEVINFO, st_label, CE_WARN,
949 949 "st_attach-RESUME: tape failure "
950 950 " tape position will be lost");
951 951 } else {
952 952 /* this prints errors */
953 953 (void) st_validate_tapemarks(un,
954 954 st_uscsi_cmd, &un->un_suspend_pos);
955 955 }
956 956 /*
957 957 * there are no retries, if there is an error
958 958 * we don't know if the tape has changed
959 959 */
960 960 un->un_suspend_pos.pmode = invalid;
961 961 }
962 962
963 963 /* now we are ready to start up any queued I/Os */
964 964 if (un->un_ncmds || un->un_quef) {
965 965 st_start(un);
966 966 }
967 967
968 968 cv_broadcast(&un->un_suspend_cv);
969 969 mutex_exit(ST_MUTEX);
970 970 return (DDI_SUCCESS);
971 971
972 972 default:
973 973 return (DDI_FAILURE);
974 974 }
975 975
976 976 un = ddi_get_soft_state(st_state, instance);
977 977
978 978 ST_DEBUG(devi, st_label, SCSI_DEBUG,
979 979 "st_attach: instance=%x\n", instance);
980 980
981 981 /*
982 982 * Add a zero-length attribute to tell the world we support
983 983 * kernel ioctls (for layered drivers)
984 984 */
985 985 (void) ddi_prop_create(DDI_DEV_T_NONE, devi, DDI_PROP_CANSLEEP,
986 986 DDI_KERNEL_IOCTL, NULL, 0);
987 987
988 988 ddi_report_dev((dev_info_t *)devi);
989 989
990 990 /*
991 991 * If it's a SCSI-2 tape drive which supports wide,
992 992 * tell the host adapter to use wide.
993 993 */
994 994 wide = ((devp->sd_inq->inq_rdf == RDF_SCSI2) &&
995 995 (devp->sd_inq->inq_wbus16 || devp->sd_inq->inq_wbus32)) ? 1 : 0;
996 996
997 997 if (scsi_ifsetcap(ROUTE, "wide-xfer", wide, 1) == 1) {
998 998 ST_DEBUG(devi, st_label, SCSI_DEBUG,
999 999 "Wide Transfer %s\n", wide ? "enabled" : "disabled");
1000 1000 }
1001 1001
1002 1002 /*
1003 1003 * enable autorequest sense; keep the rq packet around in case
1004 1004 * the autorequest sense fails because of a busy condition
1005 1005 * do a getcap first in case the capability is not variable
1006 1006 */
1007 1007 if (scsi_ifgetcap(ROUTE, "auto-rqsense", 1) == 1) {
1008 1008 un->un_arq_enabled = 1;
1009 1009 } else {
1010 1010 un->un_arq_enabled =
1011 1011 ((scsi_ifsetcap(ROUTE, "auto-rqsense", 1, 1) == 1) ? 1 : 0);
1012 1012 }
1013 1013
1014 1014 ST_DEBUG(devi, st_label, SCSI_DEBUG, "auto request sense %s\n",
1015 1015 (un->un_arq_enabled ? "enabled" : "disabled"));
1016 1016
1017 1017 un->un_untagged_qing =
1018 1018 (scsi_ifgetcap(ROUTE, "untagged-qing", 0) == 1);
1019 1019
1020 1020 /*
1021 1021 * XXX - This is just for 2.6. to tell users that write buffering
1022 1022 * has gone away.
1023 1023 */
1024 1024 if (un->un_arq_enabled && un->un_untagged_qing) {
1025 1025 if (ddi_getprop(DDI_DEV_T_ANY, devi, DDI_PROP_DONTPASS,
1026 1026 "tape-driver-buffering", 0) != 0) {
1027 1027 scsi_log(ST_DEVINFO, st_label, CE_NOTE,
1028 1028 "Write Data Buffering has been depricated. Your "
1029 1029 "applications should continue to work normally.\n"
1030 1030 " But, they should ported to use Asynchronous "
1031 1031 " I/O\n"
1032 1032 " For more information, read about "
1033 1033 " tape-driver-buffering "
1034 1034 "property in the st(7d) man page\n");
1035 1035 }
1036 1036 }
1037 1037
1038 1038 un->un_max_throttle = un->un_throttle = un->un_last_throttle = 1;
1039 1039 un->un_flush_on_errors = 0;
1040 1040 un->un_mkr_pkt = (struct scsi_pkt *)NULL;
1041 1041
1042 1042 ST_DEBUG(devi, st_label, SCSI_DEBUG,
1043 1043 "throttle=%x, max_throttle = %x\n",
1044 1044 un->un_throttle, un->un_max_throttle);
1045 1045
1046 1046 /* initialize persistent errors to nil */
1047 1047 un->un_persistence = 0;
1048 1048 un->un_persist_errors = 0;
1049 1049
1050 1050 /*
1051 1051 * Get dma-max from HBA driver. If it is not defined, use 64k
1052 1052 */
1053 1053 un->un_maxdma = scsi_ifgetcap(&devp->sd_address, "dma-max", 1);
1054 1054 if (un->un_maxdma == -1) {
1055 1055 ST_DEBUG(devi, st_label, SCSI_DEBUG,
1056 1056 "Received a value that looked like -1. Using 64k maxdma");
1057 1057 un->un_maxdma = (64 * ONE_K);
1058 1058 }
1059 1059
1060 1060 #ifdef __x86
1061 1061 /*
1062 1062 * for x86, the device may be able to DMA more than the system will
1063 1063 * allow under some circumstances. We need account for both the HBA's
1064 1064 * and system's contraints.
1065 1065 *
1066 1066 * Get the maximum DMA under worse case conditions. e.g. looking at the
1067 1067 * device constraints, the max copy buffer size, and the worse case
1068 1068 * fragmentation. NOTE: this may differ from dma-max since dma-max
1069 1069 * doesn't take the worse case framentation into account.
1070 1070 *
1071 1071 * e.g. a device may be able to DMA 16MBytes, but can only DMA 1MByte
1072 1072 * if none of the pages are contiguous. Keeping track of both of these
1073 1073 * values allows us to support larger tape block sizes on some devices.
1074 1074 */
1075 1075 un->un_maxdma_arch = scsi_ifgetcap(&devp->sd_address, "dma-max-arch",
1076 1076 1);
1077 1077
1078 1078 /*
1079 1079 * If the dma-max-arch capability is not implemented, or the value
1080 1080 * comes back higher than what was reported in dma-max, use dma-max.
1081 1081 */
1082 1082 if ((un->un_maxdma_arch == -1) ||
1083 1083 ((uint_t)un->un_maxdma < (uint_t)un->un_maxdma_arch)) {
1084 1084 un->un_maxdma_arch = un->un_maxdma;
1085 1085 }
1086 1086 #endif
1087 1087
1088 1088 /*
1089 1089 * Get the max allowable cdb size
1090 1090 */
1091 1091 un->un_max_cdb_sz =
1092 1092 scsi_ifgetcap(&devp->sd_address, "max-cdb-length", 1);
1093 1093 if (un->un_max_cdb_sz < CDB_GROUP0) {
1094 1094 ST_DEBUG(devi, st_label, SCSI_DEBUG,
1095 1095 "HBA reported max-cdb-length as %d\n", un->un_max_cdb_sz);
1096 1096 un->un_max_cdb_sz = CDB_GROUP4; /* optimistic default */
1097 1097 }
1098 1098
1099 1099 if (strcmp(ddi_driver_name(ddi_get_parent(ST_DEVINFO)), "scsi_vhci")) {
1100 1100 un->un_multipath = 0;
1101 1101 } else {
1102 1102 un->un_multipath = 1;
1103 1103 }
1104 1104
1105 1105 un->un_maxbsize = MAXBSIZE_UNKNOWN;
1106 1106
1107 1107 un->un_mediastate = MTIO_NONE;
1108 1108 un->un_HeadClean = TAPE_ALERT_SUPPORT_UNKNOWN;
1109 1109
1110 1110 /*
1111 1111 * initialize kstats
1112 1112 */
1113 1113 un->un_stats = kstat_create("st", instance, NULL, "tape",
1114 1114 KSTAT_TYPE_IO, 1, KSTAT_FLAG_PERSISTENT);
1115 1115 if (un->un_stats) {
1116 1116 un->un_stats->ks_lock = ST_MUTEX;
1117 1117 kstat_install(un->un_stats);
1118 1118 }
1119 1119 (void) st_create_errstats(un, instance);
1120 1120
1121 1121 /*
1122 1122 * find the drive type for this target
1123 1123 */
1124 1124 mutex_enter(ST_MUTEX);
1125 1125 un->un_dev = MTMINOR(instance);
1126 1126 st_known_tape_type(un);
1127 1127 un->un_dev = 0;
1128 1128 mutex_exit(ST_MUTEX);
1129 1129
1130 1130 for (node_ix = 0; node_ix < ST_NUM_MEMBERS(st_minor_data); node_ix++) {
1131 1131 int minor;
1132 1132 char *name;
1133 1133
1134 1134 name = st_minor_data[node_ix].name;
1135 1135 minor = st_minor_data[node_ix].minor;
1136 1136
1137 1137 /*
1138 1138 * For default devices set the density to the
1139 1139 * preferred default density for this device.
1140 1140 */
1141 1141 if (node_ix <= DEF_BSD_NR) {
1142 1142 minor |= un->un_dp->default_density;
1143 1143 }
1144 1144 minor |= MTMINOR(instance);
1145 1145
1146 1146 if (ddi_create_minor_node(devi, name, S_IFCHR, minor,
1147 1147 DDI_NT_TAPE, NULL) == DDI_SUCCESS) {
1148 1148 continue;
1149 1149 }
1150 1150
1151 1151 ddi_remove_minor_node(devi, NULL);
1152 1152
1153 1153 (void) scsi_reset_notify(ROUTE, SCSI_RESET_CANCEL,
1154 1154 st_reset_notification, (caddr_t)un);
1155 1155 cv_destroy(&un->un_clscv);
1156 1156 cv_destroy(&un->un_sbuf_cv);
1157 1157 cv_destroy(&un->un_queue_cv);
1158 1158 cv_destroy(&un->un_state_cv);
1159 1159 #ifdef __x86
1160 1160 cv_destroy(&un->un_contig_mem_cv);
1161 1161 #endif
1162 1162 cv_destroy(&un->un_suspend_cv);
1163 1163 cv_destroy(&un->un_tape_busy_cv);
1164 1164 cv_destroy(&un->un_recov_buf_cv);
1165 1165 if (un->un_recov_taskq) {
1166 1166 ddi_taskq_destroy(un->un_recov_taskq);
1167 1167 }
1168 1168 if (un->un_sbufp) {
1169 1169 freerbuf(un->un_sbufp);
1170 1170 }
1171 1171 if (un->un_recov_buf) {
1172 1172 freerbuf(un->un_recov_buf);
1173 1173 }
1174 1174 if (un->un_uscsi_rqs_buf) {
1175 1175 kmem_free(un->un_uscsi_rqs_buf, SENSE_LENGTH);
1176 1176 }
1177 1177 if (un->un_mspl) {
1178 1178 i_ddi_mem_free((caddr_t)un->un_mspl, NULL);
1179 1179 }
1180 1180 if (un->un_dp_size) {
1181 1181 kmem_free(un->un_dp, un->un_dp_size);
1182 1182 }
1183 1183 if (un->un_state) {
1184 1184 kstat_delete(un->un_stats);
1185 1185 }
1186 1186 if (un->un_errstats) {
1187 1187 kstat_delete(un->un_errstats);
1188 1188 }
1189 1189
1190 1190 scsi_destroy_pkt(un->un_rqs);
1191 1191 scsi_free_consistent_buf(un->un_rqs_bp);
1192 1192 ddi_soft_state_free(st_state, instance);
1193 1193 devp->sd_private = NULL;
1194 1194 devp->sd_sense = NULL;
1195 1195
1196 1196 ddi_prop_remove_all(devi);
1197 1197 return (DDI_FAILURE);
1198 1198 }
1199 1199
1200 1200 return (DDI_SUCCESS);
1201 1201 }
1202 1202
1203 1203 /*
1204 1204 * st_detach:
1205 1205 *
1206 1206 * we allow a detach if and only if:
1207 1207 * - no tape is currently inserted
1208 1208 * - tape position is at BOT or unknown
1209 1209 * (if it is not at BOT then a no rewind
1210 1210 * device was opened and we have to preserve state)
1211 1211 * - it must be in a closed state : no timeouts or scsi_watch requests
1212 1212 * will exist if it is closed, so we don't need to check for
1213 1213 * them here.
1214 1214 */
1215 1215 /*ARGSUSED*/
1216 1216 static int
1217 1217 st_detach(dev_info_t *devi, ddi_detach_cmd_t cmd)
1218 1218 {
1219 1219 int instance;
1220 1220 int result;
1221 1221 struct scsi_device *devp;
1222 1222 struct scsi_tape *un;
1223 1223 clock_t wait_cmds_complete;
1224 1224
1225 1225 ST_ENTR(devi, st_detach);
1226 1226
1227 1227 instance = ddi_get_instance(devi);
1228 1228
1229 1229 if (!(un = ddi_get_soft_state(st_state, instance))) {
1230 1230 return (DDI_FAILURE);
1231 1231 }
1232 1232
1233 1233 mutex_enter(ST_MUTEX);
1234 1234
1235 1235 /*
1236 1236 * Clear error entry stack
1237 1237 */
1238 1238 st_empty_error_stack(un);
1239 1239
1240 1240 mutex_exit(ST_MUTEX);
1241 1241
1242 1242 switch (cmd) {
1243 1243
1244 1244 case DDI_DETACH:
1245 1245 /*
1246 1246 * Undo what we did in st_attach & st_doattach,
1247 1247 * freeing resources and removing things we installed.
1248 1248 * The system framework guarantees we are not active
1249 1249 * with this devinfo node in any other entry points at
1250 1250 * this time.
1251 1251 */
1252 1252
1253 1253 ST_DEBUG(ST_DEVINFO, st_label, SCSI_DEBUG,
1254 1254 "st_detach: instance=%x, un=%p\n", instance,
1255 1255 (void *)un);
1256 1256
1257 1257 if (((un->un_dp->options & ST_UNLOADABLE) == 0) ||
1258 1258 ((un->un_rsvd_status & ST_APPLICATION_RESERVATIONS) != 0) ||
1259 1259 (un->un_ncmds != 0) || (un->un_quef != NULL) ||
1260 1260 (un->un_state != ST_STATE_CLOSED)) {
1261 1261 /*
1262 1262 * we cannot unload some targets because the
1263 1263 * inquiry returns junk unless immediately
1264 1264 * after a reset
1265 1265 */
1266 1266 ST_DEBUG2(ST_DEVINFO, st_label, SCSI_DEBUG,
1267 1267 "cannot unload instance %x\n", instance);
1268 1268 un->un_unit_attention_flags |= 4;
1269 1269 return (DDI_FAILURE);
1270 1270 }
1271 1271
1272 1272 /*
1273 1273 * if the tape has been removed then we may unload;
1274 1274 * do a test unit ready and if it returns NOT READY
1275 1275 * then we assume that it is safe to unload.
1276 1276 * as a side effect, pmode may be set to invalid if the
1277 1277 * the test unit ready fails;
1278 1278 * also un_state may be set to non-closed, so reset it
1279 1279 */
1280 1280 if ((un->un_dev) && /* Been opened since attach */
1281 1281 ((un->un_pos.pmode == legacy) &&
1282 1282 (un->un_pos.fileno > 0) || /* Known position not rewound */
1283 1283 (un->un_pos.blkno != 0)) || /* Or within first file */
1284 1284 ((un->un_pos.pmode == logical) &&
1285 1285 (un->un_pos.lgclblkno > 0))) {
1286 1286 mutex_enter(ST_MUTEX);
1287 1287 /*
1288 1288 * Send Test Unit Ready in the hopes that if
1289 1289 * the drive is not in the state we think it is.
1290 1290 * And the state will be changed so it can be detached.
1291 1291 * If the command fails to reach the device and
1292 1292 * the drive was not rewound or unloaded we want
1293 1293 * to fail the detach till a user command fails
1294 1294 * where after the detach will succead.
1295 1295 */
1296 1296 result = st_cmd(un, SCMD_TEST_UNIT_READY, 0, SYNC_CMD);
1297 1297 /*
1298 1298 * After TUR un_state may be set to non-closed,
1299 1299 * so reset it back.
1300 1300 */
1301 1301 un->un_state = ST_STATE_CLOSED;
1302 1302 mutex_exit(ST_MUTEX);
1303 1303 }
1304 1304 ST_DEBUG(ST_DEVINFO, st_label, SCSI_DEBUG,
1305 1305 "un_status=%x, fileno=%x, blkno=%x\n",
1306 1306 un->un_status, un->un_pos.fileno, un->un_pos.blkno);
1307 1307
1308 1308 /*
1309 1309 * check again:
1310 1310 * if we are not at BOT then it is not safe to unload
1311 1311 */
1312 1312 if ((un->un_dev) && /* Been opened since attach */
1313 1313 (result != EACCES) && /* drive is use by somebody */
1314 1314 ((((un->un_pos.pmode == legacy) &&
1315 1315 (un->un_pos.fileno > 0) || /* Known position not rewound */
1316 1316 (un->un_pos.blkno != 0)) || /* Or within first file */
1317 1317 ((un->un_pos.pmode == logical) &&
1318 1318 (un->un_pos.lgclblkno > 0))) &&
1319 1319 ((un->un_state == ST_STATE_CLOSED) &&
1320 1320 (un->un_laststate == ST_STATE_CLOSING)))) {
1321 1321
1322 1322 ST_DEBUG(ST_DEVINFO, st_label, SCSI_DEBUG,
1323 1323 "cannot detach: pmode=%d fileno=0x%x, blkno=0x%x"
1324 1324 " lgclblkno=0x%"PRIx64"\n", un->un_pos.pmode,
1325 1325 un->un_pos.fileno, un->un_pos.blkno,
1326 1326 un->un_pos.lgclblkno);
1327 1327 un->un_unit_attention_flags |= 4;
1328 1328 return (DDI_FAILURE);
1329 1329 }
1330 1330
1331 1331 /*
1332 1332 * Just To make sure that we have released the
1333 1333 * tape unit .
1334 1334 */
1335 1335 if (un->un_dev && (un->un_rsvd_status & ST_RESERVE) &&
1336 1336 !DEVI_IS_DEVICE_REMOVED(devi)) {
1337 1337 mutex_enter(ST_MUTEX);
1338 1338 (void) st_reserve_release(un, ST_RELEASE, st_uscsi_cmd);
1339 1339 mutex_exit(ST_MUTEX);
1340 1340 }
1341 1341
1342 1342 /*
1343 1343 * now remove other data structures allocated in st_doattach()
1344 1344 */
1345 1345 ST_DEBUG(ST_DEVINFO, st_label, SCSI_DEBUG,
1346 1346 "destroying/freeing\n");
1347 1347
1348 1348 (void) scsi_reset_notify(ROUTE, SCSI_RESET_CANCEL,
1349 1349 st_reset_notification, (caddr_t)un);
1350 1350 cv_destroy(&un->un_clscv);
1351 1351 cv_destroy(&un->un_sbuf_cv);
1352 1352 cv_destroy(&un->un_queue_cv);
1353 1353 cv_destroy(&un->un_suspend_cv);
1354 1354 cv_destroy(&un->un_tape_busy_cv);
1355 1355 cv_destroy(&un->un_recov_buf_cv);
1356 1356
1357 1357 if (un->un_recov_taskq) {
1358 1358 ddi_taskq_destroy(un->un_recov_taskq);
1359 1359 }
1360 1360
1361 1361 if (un->un_hib_tid) {
1362 1362 (void) untimeout(un->un_hib_tid);
1363 1363 un->un_hib_tid = 0;
1364 1364 }
1365 1365
1366 1366 if (un->un_delay_tid) {
1367 1367 (void) untimeout(un->un_delay_tid);
1368 1368 un->un_delay_tid = 0;
1369 1369 }
1370 1370 cv_destroy(&un->un_state_cv);
1371 1371
1372 1372 #ifdef __x86
1373 1373 cv_destroy(&un->un_contig_mem_cv);
1374 1374
1375 1375 if (un->un_contig_mem_hdl != NULL) {
1376 1376 ddi_dma_free_handle(&un->un_contig_mem_hdl);
1377 1377 }
1378 1378 #endif
1379 1379 if (un->un_sbufp) {
1380 1380 freerbuf(un->un_sbufp);
1381 1381 }
1382 1382 if (un->un_recov_buf) {
1383 1383 freerbuf(un->un_recov_buf);
1384 1384 }
1385 1385 if (un->un_uscsi_rqs_buf) {
1386 1386 kmem_free(un->un_uscsi_rqs_buf, SENSE_LENGTH);
1387 1387 }
1388 1388 if (un->un_mspl) {
1389 1389 i_ddi_mem_free((caddr_t)un->un_mspl, NULL);
1390 1390 }
1391 1391 if (un->un_rqs) {
1392 1392 scsi_destroy_pkt(un->un_rqs);
1393 1393 scsi_free_consistent_buf(un->un_rqs_bp);
1394 1394 }
1395 1395 if (un->un_mkr_pkt) {
1396 1396 scsi_destroy_pkt(un->un_mkr_pkt);
1397 1397 }
1398 1398 if (un->un_arq_enabled) {
1399 1399 (void) scsi_ifsetcap(ROUTE, "auto-rqsense", 0, 1);
1400 1400 }
1401 1401 if (un->un_dp_size) {
1402 1402 kmem_free(un->un_dp, un->un_dp_size);
1403 1403 }
1404 1404 if (un->un_stats) {
1405 1405 kstat_delete(un->un_stats);
1406 1406 un->un_stats = (kstat_t *)0;
1407 1407 }
1408 1408 if (un->un_errstats) {
1409 1409 kstat_delete(un->un_errstats);
1410 1410 un->un_errstats = (kstat_t *)0;
1411 1411 }
1412 1412 if (un->un_media_id_len) {
1413 1413 kmem_free(un->un_media_id, un->un_media_id_len);
1414 1414 }
1415 1415 devp = ST_SCSI_DEVP;
1416 1416 ddi_soft_state_free(st_state, instance);
1417 1417 devp->sd_private = NULL;
1418 1418 devp->sd_sense = NULL;
1419 1419 scsi_unprobe(devp);
1420 1420 ddi_prop_remove_all(devi);
1421 1421 ddi_remove_minor_node(devi, NULL);
1422 1422 ST_DEBUG(0, st_label, SCSI_DEBUG, "st_detach done\n");
1423 1423 return (DDI_SUCCESS);
1424 1424
1425 1425 case DDI_SUSPEND:
1426 1426
1427 1427 /*
1428 1428 * Suspend/Resume
1429 1429 *
1430 1430 * To process DDI_SUSPEND, we must do the following:
1431 1431 *
1432 1432 * - check ddi_removing_power to see if power will be turned
1433 1433 * off. if so, return DDI_FAILURE
1434 1434 * - check if we are already suspended,
1435 1435 * if so, return DDI_FAILURE
1436 1436 * - check if device state is CLOSED,
1437 1437 * if not, return DDI_FAILURE.
1438 1438 * - wait until outstanding operations complete
1439 1439 * - save tape state
1440 1440 * - block new operations
1441 1441 * - cancel pending timeouts
1442 1442 *
1443 1443 */
1444 1444
1445 1445 if (ddi_removing_power(devi)) {
1446 1446 return (DDI_FAILURE);
1447 1447 }
1448 1448
1449 1449 if (un->un_dev == 0)
1450 1450 un->un_dev = MTMINOR(instance);
1451 1451
1452 1452 mutex_enter(ST_MUTEX);
1453 1453
1454 1454 /*
1455 1455 * Shouldn't already be suspended, if so return failure
1456 1456 */
1457 1457 if (un->un_pwr_mgmt == ST_PWR_SUSPENDED) {
1458 1458 mutex_exit(ST_MUTEX);
1459 1459 return (DDI_FAILURE);
1460 1460 }
1461 1461 if (un->un_state != ST_STATE_CLOSED) {
1462 1462 mutex_exit(ST_MUTEX);
1463 1463 return (DDI_FAILURE);
1464 1464 }
1465 1465
1466 1466 /*
1467 1467 * Wait for all outstanding I/O's to complete
1468 1468 *
1469 1469 * we wait on both ncmds and the wait queue for times
1470 1470 * when we are flushing after persistent errors are
1471 1471 * flagged, which is when ncmds can be 0, and the
1472 1472 * queue can still have I/O's. This way we preserve
1473 1473 * order of biodone's.
1474 1474 */
1475 1475 wait_cmds_complete = ddi_get_lbolt();
1476 1476 wait_cmds_complete +=
1477 1477 st_wait_cmds_complete * drv_usectohz(1000000);
1478 1478 while (un->un_ncmds || un->un_quef ||
1479 1479 (un->un_state == ST_STATE_RESOURCE_WAIT)) {
1480 1480
1481 1481 if (cv_timedwait(&un->un_tape_busy_cv, ST_MUTEX,
1482 1482 wait_cmds_complete) == -1) {
1483 1483 /*
1484 1484 * Time expired then cancel the command
1485 1485 */
1486 1486 if (st_reset(un, RESET_LUN) == 0) {
1487 1487 if (un->un_last_throttle) {
1488 1488 un->un_throttle =
1489 1489 un->un_last_throttle;
1490 1490 }
1491 1491 mutex_exit(ST_MUTEX);
1492 1492 return (DDI_FAILURE);
1493 1493 } else {
1494 1494 break;
1495 1495 }
1496 1496 }
1497 1497 }
1498 1498
1499 1499 /*
1500 1500 * DDI_SUSPEND says that the system "may" power down, we
1501 1501 * remember the file and block number before rewinding.
1502 1502 * we also need to save state before issuing
1503 1503 * any WRITE_FILE_MARK command.
1504 1504 */
1505 1505 (void) st_update_block_pos(un, st_cmd, 0);
1506 1506 COPY_POS(&un->un_suspend_pos, &un->un_pos);
1507 1507
1508 1508
1509 1509 /*
1510 1510 * Issue a zero write file fmk command to tell the drive to
1511 1511 * flush any buffered tape marks
1512 1512 */
1513 1513 (void) st_cmd(un, SCMD_WRITE_FILE_MARK, 0, SYNC_CMD);
1514 1514
1515 1515 /*
1516 1516 * Because not all tape drives correctly implement buffer
1517 1517 * flushing with the zero write file fmk command, issue a
1518 1518 * synchronous rewind command to force data flushing.
1519 1519 * st_validate_tapemarks() will do a rewind during DDI_RESUME
1520 1520 * anyway.
1521 1521 */
1522 1522 (void) st_cmd(un, SCMD_REWIND, 0, SYNC_CMD);
1523 1523
1524 1524 /* stop any new operations */
1525 1525 un->un_pwr_mgmt = ST_PWR_SUSPENDED;
1526 1526 un->un_throttle = 0;
1527 1527
1528 1528 /*
1529 1529 * cancel any outstanding timeouts
1530 1530 */
1531 1531 if (un->un_delay_tid) {
1532 1532 timeout_id_t temp_id = un->un_delay_tid;
1533 1533 un->un_delay_tid = 0;
1534 1534 un->un_tids_at_suspend |= ST_DELAY_TID;
1535 1535 mutex_exit(ST_MUTEX);
1536 1536 (void) untimeout(temp_id);
1537 1537 mutex_enter(ST_MUTEX);
1538 1538 }
1539 1539
1540 1540 if (un->un_hib_tid) {
1541 1541 timeout_id_t temp_id = un->un_hib_tid;
1542 1542 un->un_hib_tid = 0;
1543 1543 un->un_tids_at_suspend |= ST_HIB_TID;
1544 1544 mutex_exit(ST_MUTEX);
1545 1545 (void) untimeout(temp_id);
1546 1546 mutex_enter(ST_MUTEX);
1547 1547 }
1548 1548
1549 1549 /*
1550 1550 * Suspend the scsi_watch_thread
1551 1551 */
1552 1552 if (un->un_swr_token) {
1553 1553 opaque_t temp_token = un->un_swr_token;
1554 1554 mutex_exit(ST_MUTEX);
1555 1555 scsi_watch_suspend(temp_token);
1556 1556 } else {
1557 1557 mutex_exit(ST_MUTEX);
1558 1558 }
1559 1559
1560 1560 return (DDI_SUCCESS);
1561 1561
1562 1562 default:
1563 1563 ST_DEBUG(0, st_label, SCSI_DEBUG, "st_detach failed\n");
1564 1564 return (DDI_FAILURE);
1565 1565 }
1566 1566 }
1567 1567
1568 1568
1569 1569 /* ARGSUSED */
1570 1570 static int
1571 1571 st_info(dev_info_t *dip, ddi_info_cmd_t infocmd, void *arg, void **result)
1572 1572 {
1573 1573 dev_t dev;
1574 1574 struct scsi_tape *un;
1575 1575 int instance, error;
1576 1576
1577 1577 ST_ENTR(dip, st_info);
1578 1578
1579 1579 switch (infocmd) {
1580 1580 case DDI_INFO_DEVT2DEVINFO:
1581 1581 dev = (dev_t)arg;
1582 1582 instance = MTUNIT(dev);
1583 1583 if ((un = ddi_get_soft_state(st_state, instance)) == NULL)
1584 1584 return (DDI_FAILURE);
1585 1585 *result = (void *) ST_DEVINFO;
1586 1586 error = DDI_SUCCESS;
1587 1587 break;
1588 1588 case DDI_INFO_DEVT2INSTANCE:
1589 1589 dev = (dev_t)arg;
1590 1590 instance = MTUNIT(dev);
1591 1591 *result = (void *)(uintptr_t)instance;
1592 1592 error = DDI_SUCCESS;
1593 1593 break;
1594 1594 default:
1595 1595 error = DDI_FAILURE;
1596 1596 }
1597 1597 return (error);
1598 1598 }
1599 1599
1600 1600 static int
1601 1601 st_doattach(struct scsi_device *devp, int (*canwait)())
1602 1602 {
1603 1603 struct scsi_tape *un = NULL;
1604 1604 recov_info *ri;
1605 1605 int km_flags = (canwait != NULL_FUNC) ? KM_SLEEP : KM_NOSLEEP;
1606 1606 int instance;
1607 1607 size_t rlen;
1608 1608
1609 1609 ST_FUNC(devp->sd_dev, st_doattach);
1610 1610 /*
1611 1611 * Call the routine scsi_probe to do some of the dirty work.
1612 1612 * If the INQUIRY command succeeds, the field sd_inq in the
1613 1613 * device structure will be filled in.
1614 1614 */
1615 1615 ST_DEBUG(devp->sd_dev, st_label, SCSI_DEBUG,
1616 1616 "st_doattach(): probing\n");
1617 1617
1618 1618 if (scsi_probe(devp, canwait) == SCSIPROBE_EXISTS) {
1619 1619
1620 1620 /*
1621 1621 * In checking the whole inq_dtype byte we are looking at both
1622 1622 * the Peripheral Qualifier and the Peripheral Device Type.
1623 1623 * For this driver we are only interested in sequential devices
1624 1624 * that are connected or capable if connecting to this logical
1625 1625 * unit.
1626 1626 */
1627 1627 if (devp->sd_inq->inq_dtype ==
1628 1628 (DTYPE_SEQUENTIAL | DPQ_POSSIBLE)) {
1629 1629 ST_DEBUG(devp->sd_dev, st_label, SCSI_DEBUG,
1630 1630 "probe exists\n");
1631 1631 } else {
1632 1632 /* Something there but not a tape device */
1633 1633 scsi_unprobe(devp);
1634 1634 return (DDI_FAILURE);
1635 1635 }
1636 1636 } else {
1637 1637 /* Nothing there */
1638 1638 ST_DEBUG(devp->sd_dev, st_label, SCSI_DEBUG,
1639 1639 "probe failure: nothing there\n");
1640 1640 scsi_unprobe(devp);
1641 1641 return (DDI_FAILURE);
1642 1642 }
1643 1643
1644 1644
1645 1645 /*
1646 1646 * The actual unit is present.
1647 1647 * Now is the time to fill in the rest of our info..
1648 1648 */
1649 1649 instance = ddi_get_instance(devp->sd_dev);
1650 1650
1651 1651 if (ddi_soft_state_zalloc(st_state, instance) != DDI_SUCCESS) {
1652 1652 goto error;
1653 1653 }
1654 1654 un = ddi_get_soft_state(st_state, instance);
1655 1655
1656 1656 ASSERT(un != NULL);
1657 1657
1658 1658 un->un_rqs_bp = scsi_alloc_consistent_buf(&devp->sd_address, NULL,
1659 1659 MAX_SENSE_LENGTH, B_READ, canwait, NULL);
1660 1660 if (un->un_rqs_bp == NULL) {
1661 1661 goto error;
1662 1662 }
1663 1663 un->un_rqs = scsi_init_pkt(&devp->sd_address, NULL, un->un_rqs_bp,
1664 1664 CDB_GROUP0, 1, st_recov_sz, PKT_CONSISTENT, canwait, NULL);
1665 1665 if (!un->un_rqs) {
1666 1666 goto error;
1667 1667 }
1668 1668 ASSERT(un->un_rqs->pkt_resid == 0);
1669 1669 devp->sd_sense =
1670 1670 (struct scsi_extended_sense *)un->un_rqs_bp->b_un.b_addr;
1671 1671 ASSERT(geterror(un->un_rqs_bp) == NULL);
1672 1672
1673 1673 (void) scsi_setup_cdb((union scsi_cdb *)un->un_rqs->pkt_cdbp,
1674 1674 SCMD_REQUEST_SENSE, 0, MAX_SENSE_LENGTH, 0);
1675 1675 FILL_SCSI1_LUN(devp, un->un_rqs);
1676 1676 un->un_rqs->pkt_flags |= (FLAG_SENSING | FLAG_HEAD | FLAG_NODISCON);
1677 1677 un->un_rqs->pkt_time = st_io_time;
1678 1678 un->un_rqs->pkt_comp = st_intr;
1679 1679 ri = (recov_info *)un->un_rqs->pkt_private;
1680 1680 if (st_recov_sz == sizeof (recov_info)) {
1681 1681 ri->privatelen = sizeof (recov_info);
1682 1682 } else {
↓ open down ↓ |
1682 lines elided |
↑ open up ↑ |
1683 1683 ri->privatelen = sizeof (pkt_info);
1684 1684 }
1685 1685
1686 1686 un->un_sbufp = getrbuf(km_flags);
1687 1687 un->un_recov_buf = getrbuf(km_flags);
1688 1688
1689 1689 un->un_uscsi_rqs_buf = kmem_alloc(SENSE_LENGTH, KM_SLEEP);
1690 1690
1691 1691 /*
1692 1692 * use i_ddi_mem_alloc() for now until we have an interface to allocate
1693 - * memory for DMA which doesn't require a DMA handle. ddi_iopb_alloc()
1694 - * is obsolete and we want more flexibility in controlling the DMA
1695 - * address constraints.
1693 + * memory for DMA which doesn't require a DMA handle.
1696 1694 */
1697 1695 (void) i_ddi_mem_alloc(devp->sd_dev, &st_alloc_attr,
1698 1696 sizeof (struct seq_mode), ((km_flags == KM_SLEEP) ? 1 : 0), 0,
1699 1697 NULL, (caddr_t *)&un->un_mspl, &rlen, NULL);
1700 1698
1701 1699 (void) i_ddi_mem_alloc(devp->sd_dev, &st_alloc_attr,
1702 1700 sizeof (read_pos_data_t), ((km_flags == KM_SLEEP) ? 1 : 0), 0,
1703 1701 NULL, (caddr_t *)&un->un_read_pos_data, &rlen, NULL);
1704 1702
1705 1703 if (!un->un_sbufp || !un->un_mspl || !un->un_read_pos_data) {
1706 1704 ST_DEBUG6(devp->sd_dev, st_label, SCSI_DEBUG,
1707 1705 "probe partial failure: no space\n");
1708 1706 goto error;
1709 1707 }
1710 1708
1711 1709 bzero(un->un_mspl, sizeof (struct seq_mode));
1712 1710
1713 1711 cv_init(&un->un_sbuf_cv, NULL, CV_DRIVER, NULL);
1714 1712 cv_init(&un->un_queue_cv, NULL, CV_DRIVER, NULL);
1715 1713 cv_init(&un->un_clscv, NULL, CV_DRIVER, NULL);
1716 1714 cv_init(&un->un_state_cv, NULL, CV_DRIVER, NULL);
1717 1715 #ifdef __x86
1718 1716 cv_init(&un->un_contig_mem_cv, NULL, CV_DRIVER, NULL);
1719 1717 #endif
1720 1718
1721 1719 /* Initialize power managemnet condition variable */
1722 1720 cv_init(&un->un_suspend_cv, NULL, CV_DRIVER, NULL);
1723 1721 cv_init(&un->un_tape_busy_cv, NULL, CV_DRIVER, NULL);
1724 1722 cv_init(&un->un_recov_buf_cv, NULL, CV_DRIVER, NULL);
1725 1723
1726 1724 un->un_recov_taskq = ddi_taskq_create(devp->sd_dev,
1727 1725 "un_recov_taskq", 1, TASKQ_DEFAULTPRI, km_flags);
1728 1726
1729 1727 ASSERT(un->un_recov_taskq != NULL);
1730 1728
1731 1729 un->un_pos.pmode = invalid;
1732 1730 un->un_sd = devp;
1733 1731 un->un_swr_token = (opaque_t)NULL;
1734 1732 un->un_comp_page = ST_DEV_DATACOMP_PAGE | ST_DEV_CONFIG_PAGE;
1735 1733 un->un_wormable = st_is_drive_worm;
1736 1734 un->un_media_id_method = st_get_media_identification;
1737 1735 /*
1738 1736 * setting long a initial as it contains logical file info.
1739 1737 * support for long format is mandatory but many drive don't do it.
1740 1738 */
1741 1739 un->un_read_pos_type = LONG_POS;
1742 1740
1743 1741 un->un_suspend_pos.pmode = invalid;
1744 1742
1745 1743 st_add_recovery_info_to_pkt(un, un->un_rqs_bp, un->un_rqs);
1746 1744
1747 1745 #ifdef __x86
1748 1746 if (ddi_dma_alloc_handle(ST_DEVINFO, &st_contig_mem_dma_attr,
1749 1747 DDI_DMA_SLEEP, NULL, &un->un_contig_mem_hdl) != DDI_SUCCESS) {
1750 1748 ST_DEBUG6(devp->sd_dev, st_label, SCSI_DEBUG,
1751 1749 "allocation of contiguous memory dma handle failed!");
1752 1750 un->un_contig_mem_hdl = NULL;
1753 1751 goto error;
1754 1752 }
1755 1753 #endif
1756 1754
1757 1755 /*
1758 1756 * Since this driver manages devices with "remote" hardware,
1759 1757 * i.e. the devices themselves have no "reg" properties,
1760 1758 * the SUSPEND/RESUME commands in detach/attach will not be
1761 1759 * called by the power management framework unless we request
1762 1760 * it by creating a "pm-hardware-state" property and setting it
1763 1761 * to value "needs-suspend-resume".
1764 1762 */
1765 1763 if (ddi_prop_update_string(DDI_DEV_T_NONE, devp->sd_dev,
1766 1764 "pm-hardware-state", "needs-suspend-resume") !=
1767 1765 DDI_PROP_SUCCESS) {
1768 1766
1769 1767 ST_DEBUG(devp->sd_dev, st_label, SCSI_DEBUG,
1770 1768 "ddi_prop_update(\"pm-hardware-state\") failed\n");
1771 1769 goto error;
1772 1770 }
1773 1771
1774 1772 if (ddi_prop_create(DDI_DEV_T_NONE, devp->sd_dev, DDI_PROP_CANSLEEP,
1775 1773 "no-involuntary-power-cycles", NULL, 0) != DDI_PROP_SUCCESS) {
1776 1774
1777 1775 ST_DEBUG(devp->sd_dev, st_label, SCSI_DEBUG,
1778 1776 "ddi_prop_create(\"no-involuntary-power-cycles\") "
1779 1777 "failed\n");
1780 1778 goto error;
1781 1779 }
1782 1780
1783 1781 (void) scsi_reset_notify(ROUTE, SCSI_RESET_NOTIFY,
1784 1782 st_reset_notification, (caddr_t)un);
1785 1783
1786 1784 ST_DEBUG6(devp->sd_dev, st_label, SCSI_DEBUG, "attach success\n");
1787 1785 return (DDI_SUCCESS);
1788 1786
1789 1787 error:
1790 1788 devp->sd_sense = NULL;
1791 1789
1792 1790 ddi_remove_minor_node(devp->sd_dev, NULL);
1793 1791 if (un) {
1794 1792 if (un->un_mspl) {
1795 1793 i_ddi_mem_free((caddr_t)un->un_mspl, NULL);
1796 1794 }
1797 1795 if (un->un_read_pos_data) {
1798 1796 i_ddi_mem_free((caddr_t)un->un_read_pos_data, 0);
1799 1797 }
1800 1798 if (un->un_sbufp) {
1801 1799 freerbuf(un->un_sbufp);
1802 1800 }
1803 1801 if (un->un_recov_buf) {
1804 1802 freerbuf(un->un_recov_buf);
1805 1803 }
1806 1804 if (un->un_uscsi_rqs_buf) {
1807 1805 kmem_free(un->un_uscsi_rqs_buf, SENSE_LENGTH);
1808 1806 }
1809 1807 #ifdef __x86
1810 1808 if (un->un_contig_mem_hdl != NULL) {
1811 1809 ddi_dma_free_handle(&un->un_contig_mem_hdl);
1812 1810 }
1813 1811 #endif
1814 1812 if (un->un_rqs) {
1815 1813 scsi_destroy_pkt(un->un_rqs);
1816 1814 }
1817 1815
1818 1816 if (un->un_rqs_bp) {
1819 1817 scsi_free_consistent_buf(un->un_rqs_bp);
1820 1818 }
1821 1819
1822 1820 ddi_soft_state_free(st_state, instance);
1823 1821 devp->sd_private = NULL;
1824 1822 }
1825 1823
1826 1824 if (devp->sd_inq) {
1827 1825 scsi_unprobe(devp);
1828 1826 }
1829 1827 return (DDI_FAILURE);
1830 1828 }
1831 1829
1832 1830 typedef int
1833 1831 (*cfg_functp)(struct scsi_tape *, char *vidpid, struct st_drivetype *);
1834 1832
1835 1833 static cfg_functp config_functs[] = {
1836 1834 st_get_conf_from_st_dot_conf,
1837 1835 st_get_conf_from_st_conf_dot_c,
1838 1836 st_get_conf_from_tape_drive,
1839 1837 st_get_default_conf
1840 1838 };
1841 1839
1842 1840
1843 1841 /*
1844 1842 * determine tape type, using tape-config-list or built-in table or
1845 1843 * use a generic tape config entry
1846 1844 */
1847 1845 static void
1848 1846 st_known_tape_type(struct scsi_tape *un)
1849 1847 {
1850 1848 struct st_drivetype *dp;
1851 1849 cfg_functp *config_funct;
1852 1850 uchar_t reserved;
1853 1851
1854 1852 ST_FUNC(ST_DEVINFO, st_known_tape_type);
1855 1853
1856 1854 reserved = (un->un_rsvd_status & ST_RESERVE) ? ST_RESERVE
1857 1855 : ST_RELEASE;
1858 1856
1859 1857 /*
1860 1858 * XXX: Emulex MT-02 (and emulators) predates SCSI-1 and has
1861 1859 * no vid & pid inquiry data. So, we provide one.
1862 1860 */
1863 1861 if (ST_INQUIRY->inq_len == 0 ||
1864 1862 (bcmp("\0\0\0\0\0\0\0\0", ST_INQUIRY->inq_vid, 8) == 0)) {
1865 1863 (void) strcpy((char *)ST_INQUIRY->inq_vid, ST_MT02_NAME);
1866 1864 }
1867 1865
1868 1866 if (un->un_dp_size == 0) {
1869 1867 un->un_dp_size = sizeof (struct st_drivetype);
1870 1868 dp = kmem_zalloc((size_t)un->un_dp_size, KM_SLEEP);
1871 1869 un->un_dp = dp;
1872 1870 } else {
1873 1871 dp = un->un_dp;
1874 1872 }
1875 1873
1876 1874 un->un_dp->non_motion_timeout = st_io_time;
1877 1875 /*
1878 1876 * Loop through the configuration methods till one works.
1879 1877 */
1880 1878 for (config_funct = &config_functs[0]; ; config_funct++) {
1881 1879 if ((*config_funct)(un, ST_INQUIRY->inq_vid, dp)) {
1882 1880 break;
1883 1881 }
1884 1882 }
1885 1883
1886 1884 /*
1887 1885 * If we didn't just make up this configuration and
1888 1886 * all the density codes are the same..
1889 1887 * Set Auto Density over ride.
1890 1888 */
1891 1889 if (*config_funct != st_get_default_conf) {
1892 1890 /*
1893 1891 * If this device is one that is configured and all
1894 1892 * densities are the same, This saves doing gets and set
1895 1893 * that yield nothing.
1896 1894 */
1897 1895 if ((dp->densities[0]) == (dp->densities[1]) &&
1898 1896 (dp->densities[0]) == (dp->densities[2]) &&
1899 1897 (dp->densities[0]) == (dp->densities[3])) {
1900 1898
1901 1899 dp->options |= ST_AUTODEN_OVERRIDE;
1902 1900 }
1903 1901 }
1904 1902
1905 1903
1906 1904 /*
1907 1905 * Store tape drive characteristics.
1908 1906 */
1909 1907 un->un_status = 0;
1910 1908 un->un_attached = 1;
1911 1909 un->un_init_options = dp->options;
1912 1910
1913 1911 /* setup operation time-outs based on options */
1914 1912 st_calculate_timeouts(un);
1915 1913
1916 1914 /* TLR support */
1917 1915 if (un->un_dp->type != ST_TYPE_INVALID) {
1918 1916 int result;
1919 1917
1920 1918 /* try and enable TLR */
1921 1919 un->un_tlr_flag = TLR_SAS_ONE_DEVICE;
1922 1920 result = st_set_target_TLR_mode(un, st_uscsi_cmd);
1923 1921 if (result == EACCES) {
1924 1922 /*
1925 1923 * From attach command failed.
1926 1924 * Set dp type so is run again on open.
1927 1925 */
1928 1926 un->un_dp->type = ST_TYPE_INVALID;
1929 1927 un->un_tlr_flag = TLR_NOT_KNOWN;
1930 1928 } else if (result == 0) {
1931 1929 if (scsi_ifgetcap(&un->un_sd->sd_address,
1932 1930 "tran-layer-retries", 1) == -1) {
1933 1931 un->un_tlr_flag = TLR_NOT_SUPPORTED;
1934 1932 (void) st_set_target_TLR_mode(un, st_uscsi_cmd);
1935 1933 } else {
1936 1934 un->un_tlr_flag = TLR_SAS_ONE_DEVICE;
1937 1935 }
1938 1936 } else {
1939 1937 un->un_tlr_flag = TLR_NOT_SUPPORTED;
1940 1938 }
1941 1939 }
1942 1940
1943 1941 /* make sure if we are supposed to be variable, make it variable */
1944 1942 if (dp->options & ST_VARIABLE) {
1945 1943 dp->bsize = 0;
1946 1944 }
1947 1945
1948 1946 if (reserved != ((un->un_rsvd_status & ST_RESERVE) ? ST_RESERVE
1949 1947 : ST_RELEASE)) {
1950 1948 (void) st_reserve_release(un, reserved, st_uscsi_cmd);
1951 1949 }
1952 1950
1953 1951 un->un_unit_attention_flags |= 1;
1954 1952
1955 1953 scsi_log(ST_DEVINFO, st_label, CE_NOTE, "?<%s>\n", dp->name);
1956 1954
1957 1955 }
1958 1956
1959 1957
1960 1958 typedef struct {
1961 1959 int mask;
1962 1960 int bottom;
1963 1961 int top;
1964 1962 char *name;
1965 1963 } conf_limit;
1966 1964
1967 1965 static const conf_limit conf_limits[] = {
1968 1966
1969 1967 -1, 1, 2, "conf version",
1970 1968 -1, MT_ISTS, ST_LAST_TYPE, "drive type",
1971 1969 -1, 0, 0xffffff, "block size",
1972 1970 ST_VALID_OPTS, 0, ST_VALID_OPTS, "options",
1973 1971 -1, 0, 4, "number of densities",
1974 1972 -1, 0, UINT8_MAX, "density code",
1975 1973 -1, 0, 3, "default density",
1976 1974 -1, 0, UINT16_MAX, "non motion timeout",
1977 1975 -1, 0, UINT16_MAX, "I/O timeout",
1978 1976 -1, 0, UINT16_MAX, "space timeout",
1979 1977 -1, 0, UINT16_MAX, "load timeout",
1980 1978 -1, 0, UINT16_MAX, "unload timeout",
1981 1979 -1, 0, UINT16_MAX, "erase timeout",
1982 1980 0, 0, 0, NULL
1983 1981 };
1984 1982
1985 1983 static int
1986 1984 st_validate_conf_data(struct scsi_tape *un, int *list, int list_len,
1987 1985 const char *conf_name)
1988 1986 {
1989 1987 int dens;
1990 1988 int ndens;
1991 1989 int value;
1992 1990 int type;
1993 1991 int count;
1994 1992 const conf_limit *limit = &conf_limits[0];
1995 1993
1996 1994 ST_FUNC(ST_DEVINFO, st_validate_conf_data);
1997 1995
1998 1996 ST_DEBUG3(ST_DEVINFO, st_label, CE_NOTE,
1999 1997 "Checking %d entrys total with %d densities\n", list_len, list[4]);
2000 1998
2001 1999 count = list_len;
2002 2000 type = *list;
2003 2001 for (; count && limit->name; count--, list++, limit++) {
2004 2002
2005 2003 value = *list;
2006 2004 if (value & ~limit->mask) {
2007 2005 scsi_log(ST_DEVINFO, st_label, CE_NOTE,
2008 2006 "%s %s value invalid bits set: 0x%X\n",
2009 2007 conf_name, limit->name, value & ~limit->mask);
2010 2008 *list &= limit->mask;
2011 2009 } else if (value < limit->bottom) {
2012 2010 scsi_log(ST_DEVINFO, st_label, CE_NOTE,
2013 2011 "%s %s value too low: value = %d limit %d\n",
2014 2012 conf_name, limit->name, value, limit->bottom);
2015 2013 } else if (value > limit->top) {
2016 2014 scsi_log(ST_DEVINFO, st_label, CE_NOTE,
2017 2015 "%s %s value too high: value = %d limit %d\n",
2018 2016 conf_name, limit->name, value, limit->top);
2019 2017 } else {
2020 2018 ST_DEBUG3(ST_DEVINFO, st_label, CE_CONT,
2021 2019 "%s %s value = 0x%X\n",
2022 2020 conf_name, limit->name, value);
2023 2021 }
2024 2022
2025 2023 /* If not the number of densities continue */
2026 2024 if (limit != &conf_limits[4]) {
2027 2025 continue;
2028 2026 }
2029 2027
2030 2028 /* If number of densities is not in range can't use config */
2031 2029 if (value < limit->bottom || value > limit->top) {
2032 2030 return (-1);
2033 2031 }
2034 2032
2035 2033 ndens = min(value, NDENSITIES);
2036 2034 if ((type == 1) && (list_len - ndens) != 6) {
2037 2035 scsi_log(ST_DEVINFO, st_label, CE_NOTE,
2038 2036 "%s conf version 1 with %d densities has %d items"
2039 2037 " should have %d",
2040 2038 conf_name, ndens, list_len, 6 + ndens);
2041 2039 } else if ((type == 2) && (list_len - ndens) != 13) {
2042 2040 scsi_log(ST_DEVINFO, st_label, CE_NOTE,
2043 2041 "%s conf version 2 with %d densities has %d items"
2044 2042 " should have %d",
2045 2043 conf_name, ndens, list_len, 13 + ndens);
2046 2044 }
2047 2045
2048 2046 limit++;
2049 2047 for (dens = 0; dens < ndens && count; dens++) {
2050 2048 count--;
2051 2049 list++;
2052 2050 value = *list;
2053 2051 if (value < limit->bottom) {
2054 2052 scsi_log(ST_DEVINFO, st_label, CE_NOTE,
2055 2053 "%s density[%d] value too low: value ="
2056 2054 " 0x%X limit 0x%X\n",
2057 2055 conf_name, dens, value, limit->bottom);
2058 2056 } else if (value > limit->top) {
2059 2057 scsi_log(ST_DEVINFO, st_label, CE_NOTE,
2060 2058 "%s density[%d] value too high: value ="
2061 2059 " 0x%X limit 0x%X\n",
2062 2060 conf_name, dens, value, limit->top);
2063 2061 } else {
2064 2062 ST_DEBUG3(ST_DEVINFO, st_label, CE_CONT,
2065 2063 "%s density[%d] value = 0x%X\n",
2066 2064 conf_name, dens, value);
2067 2065 }
2068 2066 }
2069 2067 }
2070 2068
2071 2069 return (0);
2072 2070 }
2073 2071
2074 2072 static int
2075 2073 st_get_conf_from_st_dot_conf(struct scsi_tape *un, char *vidpid,
2076 2074 struct st_drivetype *dp)
2077 2075 {
2078 2076 caddr_t config_list = NULL;
2079 2077 caddr_t data_list = NULL;
2080 2078 int *data_ptr;
2081 2079 caddr_t vidptr, prettyptr, datanameptr;
2082 2080 size_t vidlen, prettylen, datanamelen, tripletlen = 0;
2083 2081 int config_list_len, data_list_len, len, i;
2084 2082 int version;
2085 2083 int found = 0;
2086 2084
2087 2085 ST_FUNC(ST_DEVINFO, st_get_conf_from_st_dot_conf);
2088 2086
2089 2087 /*
2090 2088 * Determine type of tape controller. Type is determined by
2091 2089 * checking the vendor ids of the earlier inquiry command and
2092 2090 * comparing those with vids in tape-config-list defined in st.conf
2093 2091 */
2094 2092 if (ddi_getlongprop(DDI_DEV_T_ANY, ST_DEVINFO, DDI_PROP_DONTPASS,
2095 2093 "tape-config-list", (caddr_t)&config_list, &config_list_len)
2096 2094 != DDI_PROP_SUCCESS) {
2097 2095 return (found);
2098 2096 }
2099 2097
2100 2098 ST_DEBUG6(ST_DEVINFO, st_label, SCSI_DEBUG,
2101 2099 "st_get_conf_from_st_dot_conf(): st.conf has tape-config-list\n");
2102 2100
2103 2101 /*
2104 2102 * Compare vids in each triplet - if it matches, get value for
2105 2103 * data_name and contruct a st_drivetype struct
2106 2104 * tripletlen is not set yet!
2107 2105 */
2108 2106 for (len = config_list_len, vidptr = config_list;
2109 2107 len > 0;
2110 2108 vidptr += tripletlen, len -= tripletlen) {
2111 2109
2112 2110 vidlen = strlen(vidptr);
2113 2111 prettyptr = vidptr + vidlen + 1;
2114 2112 prettylen = strlen(prettyptr);
2115 2113 datanameptr = prettyptr + prettylen + 1;
2116 2114 datanamelen = strlen(datanameptr);
2117 2115 tripletlen = vidlen + prettylen + datanamelen + 3;
2118 2116
2119 2117 if (vidlen == 0) {
2120 2118 continue;
2121 2119 }
2122 2120
2123 2121 /*
2124 2122 * If inquiry vid dosen't match this triplets vid,
2125 2123 * try the next.
2126 2124 */
2127 2125 if (strncasecmp(vidpid, vidptr, vidlen)) {
2128 2126 continue;
2129 2127 }
2130 2128
2131 2129 /*
2132 2130 * if prettylen is zero then use the vid string
2133 2131 */
2134 2132 if (prettylen == 0) {
2135 2133 prettyptr = vidptr;
2136 2134 prettylen = vidlen;
2137 2135 }
2138 2136
2139 2137 ST_DEBUG(ST_DEVINFO, st_label, SCSI_DEBUG,
2140 2138 "vid = %s, pretty=%s, dataname = %s\n",
2141 2139 vidptr, prettyptr, datanameptr);
2142 2140
2143 2141 /*
2144 2142 * get the data list
2145 2143 */
2146 2144 if (ddi_getlongprop(DDI_DEV_T_ANY, ST_DEVINFO, 0,
2147 2145 datanameptr, (caddr_t)&data_list,
2148 2146 &data_list_len) != DDI_PROP_SUCCESS) {
2149 2147 /*
2150 2148 * Error in getting property value
2151 2149 * print warning!
2152 2150 */
2153 2151 scsi_log(ST_DEVINFO, st_label, CE_WARN,
2154 2152 "data property (%s) has no value\n",
2155 2153 datanameptr);
2156 2154 continue;
2157 2155 }
2158 2156
2159 2157 /*
2160 2158 * now initialize the st_drivetype struct
2161 2159 */
2162 2160 (void) strncpy(dp->name, prettyptr, ST_NAMESIZE - 1);
2163 2161 dp->length = (int)min(vidlen, (VIDPIDLEN - 1));
2164 2162 (void) strncpy(dp->vid, vidptr, dp->length);
2165 2163 data_ptr = (int *)data_list;
2166 2164 /*
2167 2165 * check if data is enough for version, type,
2168 2166 * bsize, options, # of densities, density1,
2169 2167 * density2, ..., default_density
2170 2168 */
2171 2169 if ((data_list_len < 5 * sizeof (int)) ||
2172 2170 (data_list_len < 6 * sizeof (int) +
2173 2171 *(data_ptr + 4) * sizeof (int))) {
2174 2172 /*
2175 2173 * print warning and skip to next triplet.
2176 2174 */
2177 2175 scsi_log(ST_DEVINFO, st_label, CE_WARN,
2178 2176 "data property (%s) incomplete\n",
2179 2177 datanameptr);
2180 2178 kmem_free(data_list, data_list_len);
2181 2179 continue;
2182 2180 }
2183 2181
2184 2182 if (st_validate_conf_data(un, data_ptr,
2185 2183 data_list_len / sizeof (int), datanameptr)) {
2186 2184 kmem_free(data_list, data_list_len);
2187 2185 scsi_log(ST_DEVINFO, st_label, CE_WARN,
2188 2186 "data property (%s) rejected\n",
2189 2187 datanameptr);
2190 2188 continue;
2191 2189 }
2192 2190
2193 2191 /*
2194 2192 * check version
2195 2193 */
2196 2194 version = *data_ptr++;
2197 2195 if (version != 1 && version != 2) {
2198 2196 /* print warning but accept it */
2199 2197 scsi_log(ST_DEVINFO, st_label, CE_WARN,
2200 2198 "Version # for data property (%s) "
2201 2199 "not set to 1 or 2\n", datanameptr);
2202 2200 }
2203 2201
2204 2202 dp->type = *data_ptr++;
2205 2203 dp->bsize = *data_ptr++;
2206 2204 dp->options = *data_ptr++;
2207 2205 dp->options |= ST_DYNAMIC;
2208 2206 len = *data_ptr++;
2209 2207 for (i = 0; i < NDENSITIES; i++) {
2210 2208 if (i < len) {
2211 2209 dp->densities[i] = *data_ptr++;
2212 2210 }
2213 2211 }
2214 2212 dp->default_density = *data_ptr << 3;
2215 2213 if (version == 2 &&
2216 2214 data_list_len >= (13 + len) * sizeof (int)) {
2217 2215 data_ptr++;
2218 2216 dp->non_motion_timeout = *data_ptr++;
2219 2217 dp->io_timeout = *data_ptr++;
2220 2218 dp->rewind_timeout = *data_ptr++;
2221 2219 dp->space_timeout = *data_ptr++;
2222 2220 dp->load_timeout = *data_ptr++;
2223 2221 dp->unload_timeout = *data_ptr++;
2224 2222 dp->erase_timeout = *data_ptr++;
2225 2223 }
2226 2224 kmem_free(data_list, data_list_len);
2227 2225 found = 1;
2228 2226 ST_DEBUG(ST_DEVINFO, st_label, SCSI_DEBUG,
2229 2227 "found in st.conf: vid = %s, pretty=%s\n",
2230 2228 dp->vid, dp->name);
2231 2229 break;
2232 2230 }
2233 2231
2234 2232 /*
2235 2233 * free up the memory allocated by ddi_getlongprop
2236 2234 */
2237 2235 if (config_list) {
2238 2236 kmem_free(config_list, config_list_len);
2239 2237 }
2240 2238 return (found);
2241 2239 }
2242 2240
2243 2241 static int
2244 2242 st_get_conf_from_st_conf_dot_c(struct scsi_tape *un, char *vidpid,
2245 2243 struct st_drivetype *dp)
2246 2244 {
2247 2245 int i;
2248 2246
2249 2247 ST_FUNC(ST_DEVINFO, st_get_conf_from_st_conf_dot_c);
2250 2248 /*
2251 2249 * Determine type of tape controller. Type is determined by
2252 2250 * checking the result of the earlier inquiry command and
2253 2251 * comparing vendor ids with strings in a table declared in st_conf.c.
2254 2252 */
2255 2253 ST_DEBUG2(ST_DEVINFO, st_label, SCSI_DEBUG,
2256 2254 "st_get_conf_from_st_conf_dot_c(): looking at st_drivetypes\n");
2257 2255
2258 2256 for (i = 0; i < st_ndrivetypes; i++) {
2259 2257 if (st_drivetypes[i].length == 0) {
2260 2258 continue;
2261 2259 }
2262 2260 if (strncasecmp(vidpid, st_drivetypes[i].vid,
2263 2261 st_drivetypes[i].length)) {
2264 2262 continue;
2265 2263 }
2266 2264 bcopy(&st_drivetypes[i], dp, sizeof (st_drivetypes[i]));
2267 2265 return (1);
2268 2266 }
2269 2267 return (0);
2270 2268 }
2271 2269
2272 2270 static int
2273 2271 st_get_conf_from_tape_drive(struct scsi_tape *un, char *vidpid,
2274 2272 struct st_drivetype *dp)
2275 2273 {
2276 2274 int bsize;
2277 2275 ulong_t maxbsize;
2278 2276 caddr_t buf;
2279 2277 struct st_drivetype *tem_dp;
2280 2278 struct read_blklim *blklim;
2281 2279 int rval;
2282 2280 int i;
2283 2281
2284 2282 ST_FUNC(ST_DEVINFO, st_get_conf_from_tape_drive);
2285 2283
2286 2284 /*
2287 2285 * Determine the type of tape controller. Type is determined by
2288 2286 * sending SCSI commands to tape drive and deriving the type from
2289 2287 * the returned data.
2290 2288 */
2291 2289 ST_DEBUG2(ST_DEVINFO, st_label, SCSI_DEBUG,
2292 2290 "st_get_conf_from_tape_drive(): asking tape drive\n");
2293 2291
2294 2292 tem_dp = kmem_zalloc(sizeof (struct st_drivetype), KM_SLEEP);
2295 2293
2296 2294 /*
2297 2295 * Make up a name
2298 2296 */
2299 2297 bcopy(vidpid, tem_dp->name, VIDPIDLEN);
2300 2298 tem_dp->name[VIDPIDLEN] = '\0';
2301 2299 tem_dp->length = min(strlen(ST_INQUIRY->inq_vid), (VIDPIDLEN - 1));
2302 2300 (void) strncpy(tem_dp->vid, ST_INQUIRY->inq_vid, tem_dp->length);
2303 2301 /*
2304 2302 * 'clean' vendor and product strings of non-printing chars
2305 2303 */
2306 2304 for (i = 0; i < VIDPIDLEN - 1; i ++) {
2307 2305 if (tem_dp->name[i] < ' ' || tem_dp->name[i] > '~') {
2308 2306 tem_dp->name[i] = '.';
2309 2307 }
2310 2308 }
2311 2309
2312 2310 /*
2313 2311 * MODE SENSE to determine block size.
2314 2312 */
2315 2313 un->un_dp->options |= ST_MODE_SEL_COMP | ST_UNLOADABLE;
2316 2314 rval = st_modesense(un);
2317 2315 if (rval) {
2318 2316 if (rval == EACCES) {
2319 2317 un->un_dp->type = ST_TYPE_INVALID;
2320 2318 rval = 1;
2321 2319 } else {
2322 2320 un->un_dp->options &= ~ST_MODE_SEL_COMP;
2323 2321 rval = 0;
2324 2322 }
2325 2323 ST_DEBUG2(ST_DEVINFO, st_label, SCSI_DEBUG,
2326 2324 "st_get_conf_from_tape_drive(): fail to mode sense\n");
2327 2325 goto exit;
2328 2326 }
2329 2327
2330 2328 /* Can mode sense page 0x10 or 0xf */
2331 2329 tem_dp->options |= ST_MODE_SEL_COMP;
2332 2330 bsize = (un->un_mspl->high_bl << 16) |
2333 2331 (un->un_mspl->mid_bl << 8) |
2334 2332 (un->un_mspl->low_bl);
2335 2333
2336 2334 if (bsize == 0) {
2337 2335 tem_dp->options |= ST_VARIABLE;
2338 2336 tem_dp->bsize = 0;
2339 2337 } else if (bsize > ST_MAXRECSIZE_FIXED) {
2340 2338 rval = st_change_block_size(un, 0);
2341 2339 if (rval) {
2342 2340 if (rval == EACCES) {
2343 2341 un->un_dp->type = ST_TYPE_INVALID;
2344 2342 rval = 1;
2345 2343 } else {
2346 2344 rval = 0;
2347 2345 ST_DEBUG2(ST_DEVINFO, st_label, SCSI_DEBUG,
2348 2346 "st_get_conf_from_tape_drive(): "
2349 2347 "Fixed record size is too large and"
2350 2348 "cannot switch to variable record size");
2351 2349 }
2352 2350 goto exit;
2353 2351 }
2354 2352 tem_dp->options |= ST_VARIABLE;
2355 2353 } else {
2356 2354 rval = st_change_block_size(un, 0);
2357 2355 if (rval == 0) {
2358 2356 tem_dp->options |= ST_VARIABLE;
2359 2357 tem_dp->bsize = 0;
2360 2358 } else if (rval != EACCES) {
2361 2359 tem_dp->bsize = bsize;
2362 2360 } else {
2363 2361 un->un_dp->type = ST_TYPE_INVALID;
2364 2362 rval = 1;
2365 2363 goto exit;
2366 2364 }
2367 2365 }
2368 2366
2369 2367 /*
2370 2368 * If READ BLOCk LIMITS works and upper block size limit is
2371 2369 * more than 64K, ST_NO_RECSIZE_LIMIT is supported.
2372 2370 */
2373 2371 blklim = kmem_zalloc(sizeof (struct read_blklim), KM_SLEEP);
2374 2372 rval = st_read_block_limits(un, blklim);
2375 2373 if (rval) {
2376 2374 ST_DEBUG2(ST_DEVINFO, st_label, SCSI_DEBUG,
2377 2375 "st_get_conf_from_tape_drive(): "
2378 2376 "fail to read block limits.\n");
2379 2377 rval = 0;
2380 2378 kmem_free(blklim, sizeof (struct read_blklim));
2381 2379 goto exit;
2382 2380 }
2383 2381 maxbsize = (blklim->max_hi << 16) +
2384 2382 (blklim->max_mid << 8) + blklim->max_lo;
2385 2383 if (maxbsize > ST_MAXRECSIZE_VARIABLE) {
2386 2384 tem_dp->options |= ST_NO_RECSIZE_LIMIT;
2387 2385 }
2388 2386 kmem_free(blklim, sizeof (struct read_blklim));
2389 2387
2390 2388 /*
2391 2389 * Inquiry VPD page 0xb0 to see if the tape drive supports WORM
2392 2390 */
2393 2391 buf = kmem_zalloc(6, KM_SLEEP);
2394 2392 rval = st_get_special_inquiry(un, 6, buf, 0xb0);
2395 2393 if (rval) {
2396 2394 ST_DEBUG2(ST_DEVINFO, st_label, SCSI_DEBUG,
2397 2395 "st_get_conf_from_tape_drive(): "
2398 2396 "fail to read vitial inquiry.\n");
2399 2397 rval = 0;
2400 2398 kmem_free(buf, 6);
2401 2399 goto exit;
2402 2400 }
2403 2401 if (buf[4] & 1) {
2404 2402 tem_dp->options |= ST_WORMABLE;
2405 2403 }
2406 2404 kmem_free(buf, 6);
2407 2405
2408 2406 /* Assume BSD BSR KNOWS_EOD */
2409 2407 tem_dp->options |= ST_BSF | ST_BSR | ST_KNOWS_EOD | ST_UNLOADABLE;
2410 2408 tem_dp->max_rretries = -1;
2411 2409 tem_dp->max_wretries = -1;
2412 2410
2413 2411 /*
2414 2412 * Decide the densities supported by tape drive by sending
2415 2413 * REPORT DENSITY SUPPORT command.
2416 2414 */
2417 2415 if (st_get_densities_from_tape_drive(un, tem_dp) == 0) {
2418 2416 goto exit;
2419 2417 }
2420 2418
2421 2419 /*
2422 2420 * Decide the timeout values for several commands by sending
2423 2421 * REPORT SUPPORTED OPERATION CODES command.
2424 2422 */
2425 2423 rval = st_get_timeout_values_from_tape_drive(un, tem_dp);
2426 2424 if (rval == 0 || ((rval == 1) && (tem_dp->type == ST_TYPE_INVALID))) {
2427 2425 goto exit;
2428 2426 }
2429 2427
2430 2428 bcopy(tem_dp, dp, sizeof (struct st_drivetype));
2431 2429 rval = 1;
2432 2430
2433 2431 exit:
2434 2432 un->un_status = KEY_NO_SENSE;
2435 2433 kmem_free(tem_dp, sizeof (struct st_drivetype));
2436 2434 return (rval);
2437 2435 }
2438 2436
2439 2437 static int
2440 2438 st_get_densities_from_tape_drive(struct scsi_tape *un,
2441 2439 struct st_drivetype *dp)
2442 2440 {
2443 2441 int i, p;
2444 2442 size_t buflen;
2445 2443 ushort_t des_len;
2446 2444 uchar_t *den_header;
2447 2445 uchar_t num_den;
2448 2446 uchar_t den[NDENSITIES];
2449 2447 uchar_t deflt[NDENSITIES];
2450 2448 struct report_density_desc *den_desc;
2451 2449
2452 2450 ST_FUNC(ST_DEVINFO, st_get_densities_from_type_drive);
2453 2451
2454 2452 /*
2455 2453 * Since we have no idea how many densitiy support entries
2456 2454 * will be returned, we send the command firstly assuming
2457 2455 * there is only one. Then we can decide the number of
2458 2456 * entries by available density support length. If multiple
2459 2457 * entries exist, we will resend the command with enough
2460 2458 * buffer size.
2461 2459 */
2462 2460 buflen = sizeof (struct report_density_header) +
2463 2461 sizeof (struct report_density_desc);
2464 2462 den_header = kmem_zalloc(buflen, KM_SLEEP);
2465 2463 if (st_report_density_support(un, den_header, buflen) != 0) {
2466 2464 ST_DEBUG2(ST_DEVINFO, st_label, SCSI_DEBUG,
2467 2465 "st_get_conf_from_tape_drive(): fail to report density.\n");
2468 2466 kmem_free(den_header, buflen);
2469 2467 return (0);
2470 2468 }
2471 2469 des_len =
2472 2470 BE_16(((struct report_density_header *)den_header)->ava_dens_len);
2473 2471 num_den = (des_len - 2) / sizeof (struct report_density_desc);
2474 2472
2475 2473 if (num_den > 1) {
2476 2474 kmem_free(den_header, buflen);
2477 2475 buflen = sizeof (struct report_density_header) +
2478 2476 sizeof (struct report_density_desc) * num_den;
2479 2477 den_header = kmem_zalloc(buflen, KM_SLEEP);
2480 2478 if (st_report_density_support(un, den_header, buflen) != 0) {
2481 2479 ST_DEBUG2(ST_DEVINFO, st_label, SCSI_DEBUG,
2482 2480 "st_get_conf_from_tape_drive(): "
2483 2481 "fail to report density.\n");
2484 2482 kmem_free(den_header, buflen);
2485 2483 return (0);
2486 2484 }
2487 2485 }
2488 2486
2489 2487 den_desc = (struct report_density_desc *)(den_header
2490 2488 + sizeof (struct report_density_header));
2491 2489
2492 2490 /*
2493 2491 * Decide the drive type by assigning organization
2494 2492 */
2495 2493 for (i = 0; i < ST_NUM_MEMBERS(st_vid_dt); i ++) {
2496 2494 if (strncmp(st_vid_dt[i].vid, (char *)(den_desc->ass_org),
2497 2495 8) == 0) {
2498 2496 dp->type = st_vid_dt[i].type;
2499 2497 break;
2500 2498 }
2501 2499 }
2502 2500 if (i == ST_NUM_MEMBERS(st_vid_dt)) {
2503 2501 ST_DEBUG2(ST_DEVINFO, st_label, SCSI_DEBUG,
2504 2502 "st_get_conf_from_tape_drive(): "
2505 2503 "can't find match of assigned ort.\n");
2506 2504 kmem_free(den_header, buflen);
2507 2505 return (0);
2508 2506 }
2509 2507
2510 2508 /*
2511 2509 * The tape drive may support many tape formats, but the st driver
2512 2510 * supports only the four highest densities. Since density code
2513 2511 * values are returned by ascending sequence, we start from the
2514 2512 * last entry of density support data block descriptor.
2515 2513 */
2516 2514 p = 0;
2517 2515 den_desc += num_den - 1;
2518 2516 for (i = 0; i < num_den && p < NDENSITIES; i ++, den_desc --) {
2519 2517 if ((den_desc->pri_den != 0) && (den_desc->wrtok)) {
2520 2518 if (p != 0) {
2521 2519 if (den_desc->pri_den >= den[p - 1]) {
2522 2520 continue;
2523 2521 }
2524 2522 }
2525 2523 den[p] = den_desc->pri_den;
2526 2524 deflt[p] = den_desc->deflt;
2527 2525 p ++;
2528 2526 }
2529 2527 }
2530 2528
2531 2529 switch (p) {
2532 2530 case 0:
2533 2531 bzero(dp->densities, NDENSITIES);
2534 2532 dp->options |= ST_AUTODEN_OVERRIDE;
2535 2533 dp->default_density = MT_DENSITY4;
2536 2534 break;
2537 2535
2538 2536 case 1:
2539 2537 (void) memset(dp->densities, den[0], NDENSITIES);
2540 2538 dp->options |= ST_AUTODEN_OVERRIDE;
2541 2539 dp->default_density = MT_DENSITY4;
2542 2540 break;
2543 2541
2544 2542 case 2:
2545 2543 dp->densities[0] = den[1];
2546 2544 dp->densities[1] = den[1];
2547 2545 dp->densities[2] = den[0];
2548 2546 dp->densities[3] = den[0];
2549 2547 if (deflt[0]) {
2550 2548 dp->default_density = MT_DENSITY4;
2551 2549 } else {
2552 2550 dp->default_density = MT_DENSITY2;
2553 2551 }
2554 2552 break;
2555 2553
2556 2554 case 3:
2557 2555 dp->densities[0] = den[2];
2558 2556 dp->densities[1] = den[1];
2559 2557 dp->densities[2] = den[0];
2560 2558 dp->densities[3] = den[0];
2561 2559 if (deflt[0]) {
2562 2560 dp->default_density = MT_DENSITY4;
2563 2561 } else if (deflt[1]) {
2564 2562 dp->default_density = MT_DENSITY2;
2565 2563 } else {
2566 2564 dp->default_density = MT_DENSITY1;
2567 2565 }
2568 2566 break;
2569 2567
2570 2568 default:
2571 2569 for (i = p; i > p - NDENSITIES; i --) {
2572 2570 dp->densities[i - 1] = den[p - i];
2573 2571 }
2574 2572 if (deflt[0]) {
2575 2573 dp->default_density = MT_DENSITY4;
2576 2574 } else if (deflt[1]) {
2577 2575 dp->default_density = MT_DENSITY3;
2578 2576 } else if (deflt[2]) {
2579 2577 dp->default_density = MT_DENSITY2;
2580 2578 } else {
2581 2579 dp->default_density = MT_DENSITY1;
2582 2580 }
2583 2581 break;
2584 2582 }
2585 2583
2586 2584 bzero(dp->mediatype, NDENSITIES);
2587 2585
2588 2586 kmem_free(den_header, buflen);
2589 2587 return (1);
2590 2588 }
2591 2589
2592 2590 static int
2593 2591 st_get_timeout_values_from_tape_drive(struct scsi_tape *un,
2594 2592 struct st_drivetype *dp)
2595 2593 {
2596 2594 ushort_t timeout;
2597 2595 int rval;
2598 2596
2599 2597 ST_FUNC(ST_DEVINFO, st_get_timeout_values_from_type_drive);
2600 2598
2601 2599 rval = st_get_timeouts_value(un, SCMD_ERASE, &timeout, 0);
2602 2600 if (rval) {
2603 2601 if (rval == EACCES) {
2604 2602 un->un_dp->type = ST_TYPE_INVALID;
2605 2603 dp->type = ST_TYPE_INVALID;
2606 2604 return (1);
2607 2605 }
2608 2606 return (0);
2609 2607 }
2610 2608 dp->erase_timeout = timeout;
2611 2609
2612 2610 rval = st_get_timeouts_value(un, SCMD_READ, &timeout, 0);
2613 2611 if (rval) {
2614 2612 if (rval == EACCES) {
2615 2613 un->un_dp->type = ST_TYPE_INVALID;
2616 2614 dp->type = ST_TYPE_INVALID;
2617 2615 return (1);
2618 2616 }
2619 2617 return (0);
2620 2618 }
2621 2619 dp->io_timeout = timeout;
2622 2620
2623 2621 rval = st_get_timeouts_value(un, SCMD_WRITE, &timeout, 0);
2624 2622 if (rval) {
2625 2623 if (rval == EACCES) {
2626 2624 un->un_dp->type = ST_TYPE_INVALID;
2627 2625 dp->type = ST_TYPE_INVALID;
2628 2626 return (1);
2629 2627 }
2630 2628 return (0);
2631 2629 }
2632 2630 dp->io_timeout = max(dp->io_timeout, timeout);
2633 2631
2634 2632 rval = st_get_timeouts_value(un, SCMD_SPACE, &timeout, 0);
2635 2633 if (rval) {
2636 2634 if (rval == EACCES) {
2637 2635 un->un_dp->type = ST_TYPE_INVALID;
2638 2636 dp->type = ST_TYPE_INVALID;
2639 2637 return (1);
2640 2638 }
2641 2639 return (0);
2642 2640 }
2643 2641 dp->space_timeout = timeout;
2644 2642
2645 2643 rval = st_get_timeouts_value(un, SCMD_LOAD, &timeout, 0);
2646 2644 if (rval) {
2647 2645 if (rval == EACCES) {
2648 2646 un->un_dp->type = ST_TYPE_INVALID;
2649 2647 dp->type = ST_TYPE_INVALID;
2650 2648 return (1);
2651 2649 }
2652 2650 return (0);
2653 2651 }
2654 2652 dp->load_timeout = timeout;
2655 2653 dp->unload_timeout = timeout;
2656 2654
2657 2655 rval = st_get_timeouts_value(un, SCMD_REWIND, &timeout, 0);
2658 2656 if (rval) {
2659 2657 if (rval == EACCES) {
2660 2658 un->un_dp->type = ST_TYPE_INVALID;
2661 2659 dp->type = ST_TYPE_INVALID;
2662 2660 return (1);
2663 2661 }
2664 2662 return (0);
2665 2663 }
2666 2664 dp->rewind_timeout = timeout;
2667 2665
2668 2666 rval = st_get_timeouts_value(un, SCMD_INQUIRY, &timeout, 0);
2669 2667 if (rval) {
2670 2668 if (rval == EACCES) {
2671 2669 un->un_dp->type = ST_TYPE_INVALID;
2672 2670 dp->type = ST_TYPE_INVALID;
2673 2671 return (1);
2674 2672 }
2675 2673 return (0);
2676 2674 }
2677 2675 dp->non_motion_timeout = timeout;
2678 2676
2679 2677 return (1);
2680 2678 }
2681 2679
2682 2680 static int
2683 2681 st_get_timeouts_value(struct scsi_tape *un, uchar_t option_code,
2684 2682 ushort_t *timeout_value, ushort_t service_action)
2685 2683 {
2686 2684 uchar_t *timeouts;
2687 2685 uchar_t *oper;
2688 2686 uchar_t support;
2689 2687 uchar_t cdbsize;
2690 2688 uchar_t ctdp;
2691 2689 size_t buflen;
2692 2690 int rval;
2693 2691
2694 2692 ST_FUNC(ST_DEVINFO, st_get_timeouts_value);
2695 2693
2696 2694 buflen = sizeof (struct one_com_des) +
2697 2695 sizeof (struct com_timeout_des);
2698 2696 oper = kmem_zalloc(buflen, KM_SLEEP);
2699 2697 rval = st_report_supported_operation(un, oper, option_code,
2700 2698 service_action);
2701 2699
2702 2700 if (rval) {
2703 2701 ST_DEBUG2(ST_DEVINFO, st_label, SCSI_DEBUG,
2704 2702 "st_get_timeouts_value(): "
2705 2703 "fail to timeouts value for command %d.\n", option_code);
2706 2704 kmem_free(oper, buflen);
2707 2705 return (rval);
2708 2706 }
2709 2707
2710 2708 support = ((struct one_com_des *)oper)->support;
2711 2709 if ((support != SUPPORT_VALUES_SUPPORT_SCSI) &&
2712 2710 (support != SUPPORT_VALUES_SUPPORT_VENDOR)) {
2713 2711 ST_DEBUG2(ST_DEVINFO, st_label, SCSI_DEBUG,
2714 2712 "st_get_timeouts_value(): "
2715 2713 "command %d is not supported.\n", option_code);
2716 2714 kmem_free(oper, buflen);
2717 2715 return (ENOTSUP);
2718 2716 }
2719 2717
2720 2718 ctdp = ((struct one_com_des *)oper)->ctdp;
2721 2719 if (!ctdp) {
2722 2720 ST_DEBUG2(ST_DEVINFO, st_label, SCSI_DEBUG,
2723 2721 "st_get_timeouts_value(): "
2724 2722 "command timeout is not included.\n");
2725 2723 kmem_free(oper, buflen);
2726 2724 return (ENOTSUP);
2727 2725 }
2728 2726
2729 2727 cdbsize = BE_16(((struct one_com_des *)oper)->cdb_size);
2730 2728 timeouts = (uchar_t *)(oper + cdbsize + 4);
2731 2729
2732 2730 /*
2733 2731 * Timeout value in seconds is 4 bytes, but we only support the lower 2
2734 2732 * bytes. If the higher 2 bytes are not zero, the timeout value is set
2735 2733 * to 0xFFFF.
2736 2734 */
2737 2735 if (*(timeouts + 8) != 0 || *(timeouts + 9) != 0) {
2738 2736 *timeout_value = USHRT_MAX;
2739 2737 } else {
2740 2738 *timeout_value = ((*(timeouts + 10)) << 8) |
2741 2739 (*(timeouts + 11));
2742 2740 }
2743 2741
2744 2742 kmem_free(oper, buflen);
2745 2743 return (0);
2746 2744 }
2747 2745
2748 2746 static int
2749 2747 st_get_default_conf(struct scsi_tape *un, char *vidpid, struct st_drivetype *dp)
2750 2748 {
2751 2749 int i;
2752 2750
2753 2751 ST_FUNC(ST_DEVINFO, st_get_default_conf);
2754 2752
2755 2753 ST_DEBUG6(ST_DEVINFO, st_label, SCSI_DEBUG,
2756 2754 "st_get_default_conf(): making drivetype from INQ cmd\n");
2757 2755
2758 2756 /*
2759 2757 * Make up a name
2760 2758 */
2761 2759 bcopy("Vendor '", dp->name, 8);
2762 2760 bcopy(vidpid, &dp->name[8], VIDLEN);
2763 2761 bcopy("' Product '", &dp->name[16], 11);
2764 2762 bcopy(&vidpid[8], &dp->name[27], PIDLEN);
2765 2763 dp->name[ST_NAMESIZE - 2] = '\'';
2766 2764 dp->name[ST_NAMESIZE - 1] = '\0';
2767 2765 dp->length = min(strlen(ST_INQUIRY->inq_vid), (VIDPIDLEN - 1));
2768 2766 (void) strncpy(dp->vid, ST_INQUIRY->inq_vid, dp->length);
2769 2767 /*
2770 2768 * 'clean' vendor and product strings of non-printing chars
2771 2769 */
2772 2770 for (i = 0; i < ST_NAMESIZE - 2; i++) {
2773 2771 if (dp->name[i] < ' ' || dp->name[i] > '~') {
2774 2772 dp->name[i] = '.';
2775 2773 }
2776 2774 }
2777 2775 dp->type = ST_TYPE_INVALID;
2778 2776 dp->options |= (ST_DYNAMIC | ST_UNLOADABLE | ST_MODE_SEL_COMP);
2779 2777
2780 2778 return (1); /* Can Not Fail */
2781 2779 }
2782 2780
2783 2781 /*
2784 2782 * Regular Unix Entry points
2785 2783 */
2786 2784
2787 2785
2788 2786
2789 2787 /* ARGSUSED */
2790 2788 static int
2791 2789 st_open(dev_t *dev_p, int flag, int otyp, cred_t *cred_p)
2792 2790 {
2793 2791 dev_t dev = *dev_p;
2794 2792 int rval = 0;
2795 2793
2796 2794 GET_SOFT_STATE(dev);
2797 2795
2798 2796 ST_ENTR(ST_DEVINFO, st_open);
2799 2797
2800 2798 /*
2801 2799 * validate that we are addressing a sensible unit
2802 2800 */
2803 2801 mutex_enter(ST_MUTEX);
2804 2802
2805 2803 ST_DEBUG3(ST_DEVINFO, st_label, SCSI_DEBUG,
2806 2804 "st_open(node = %s dev = 0x%lx, flag = %d, otyp = %d)\n",
2807 2805 st_dev_name(dev), *dev_p, flag, otyp);
2808 2806
2809 2807 /*
2810 2808 * All device accesss go thru st_strategy() where we check
2811 2809 * suspend status
2812 2810 */
2813 2811
2814 2812 if (!un->un_attached) {
2815 2813 st_known_tape_type(un);
2816 2814 if (!un->un_attached) {
2817 2815 rval = ENXIO;
2818 2816 goto exit;
2819 2817 }
2820 2818
2821 2819 }
2822 2820
2823 2821 /*
2824 2822 * Check for the case of the tape in the middle of closing.
2825 2823 * This isn't simply a check of the current state, because
2826 2824 * we could be in state of sensing with the previous state
2827 2825 * that of closing.
2828 2826 *
2829 2827 * And don't allow multiple opens.
2830 2828 */
2831 2829 if (!(flag & (FNDELAY | FNONBLOCK)) && IS_CLOSING(un)) {
2832 2830 un->un_laststate = un->un_state;
2833 2831 un->un_state = ST_STATE_CLOSE_PENDING_OPEN;
2834 2832 while (IS_CLOSING(un) ||
2835 2833 un->un_state == ST_STATE_CLOSE_PENDING_OPEN) {
2836 2834 if (cv_wait_sig(&un->un_clscv, ST_MUTEX) == 0) {
2837 2835 rval = EINTR;
2838 2836 un->un_state = un->un_laststate;
2839 2837 goto exit;
2840 2838 }
2841 2839 }
2842 2840 } else if (un->un_state != ST_STATE_CLOSED) {
2843 2841 rval = EBUSY;
2844 2842 goto busy;
2845 2843 }
2846 2844
2847 2845 /*
2848 2846 * record current dev
2849 2847 */
2850 2848 un->un_dev = dev;
2851 2849 un->un_oflags = flag; /* save for use in st_tape_init() */
2852 2850 un->un_errno = 0; /* no errors yet */
2853 2851 un->un_restore_pos = 0;
2854 2852 un->un_rqs_state = 0;
2855 2853
2856 2854 /*
2857 2855 * If we are opening O_NDELAY, or O_NONBLOCK, we don't check for
2858 2856 * anything, leave internal states alone, if fileno >= 0
2859 2857 */
2860 2858 if (flag & (FNDELAY | FNONBLOCK)) {
2861 2859 switch (un->un_pos.pmode) {
2862 2860
2863 2861 case invalid:
2864 2862 un->un_state = ST_STATE_OFFLINE;
2865 2863 break;
2866 2864
2867 2865 case legacy:
2868 2866 /*
2869 2867 * If position is anything other than rewound.
2870 2868 */
2871 2869 if (un->un_pos.fileno != 0 || un->un_pos.blkno != 0) {
2872 2870 /*
2873 2871 * set un_read_only/write-protect status.
2874 2872 *
2875 2873 * If the tape is not bot we can assume
2876 2874 * that mspl->wp_status is set properly.
2877 2875 * else
2878 2876 * we need to do a mode sense/Tur once
2879 2877 * again to get the actual tape status.(since
2880 2878 * user might have replaced the tape)
2881 2879 * Hence make the st state OFFLINE so that
2882 2880 * we re-intialize the tape once again.
2883 2881 */
2884 2882 un->un_read_only =
2885 2883 (un->un_oflags & FWRITE) ? RDWR : RDONLY;
2886 2884 un->un_state = ST_STATE_OPEN_PENDING_IO;
2887 2885 } else {
2888 2886 un->un_state = ST_STATE_OFFLINE;
2889 2887 }
2890 2888 break;
2891 2889 case logical:
2892 2890 if (un->un_pos.lgclblkno == 0) {
2893 2891 un->un_state = ST_STATE_OFFLINE;
2894 2892 } else {
2895 2893 un->un_read_only =
2896 2894 (un->un_oflags & FWRITE) ? RDWR : RDONLY;
2897 2895 un->un_state = ST_STATE_OPEN_PENDING_IO;
2898 2896 }
2899 2897 break;
2900 2898 }
2901 2899 rval = 0;
2902 2900 } else {
2903 2901 /*
2904 2902 * Not opening O_NDELAY.
2905 2903 */
2906 2904 un->un_state = ST_STATE_OPENING;
2907 2905
2908 2906 /*
2909 2907 * Clear error entry stack
2910 2908 */
2911 2909 st_empty_error_stack(un);
2912 2910
2913 2911 rval = st_tape_init(un);
2914 2912 if ((rval == EACCES) && (un->un_read_only & WORM)) {
2915 2913 un->un_state = ST_STATE_OPEN_PENDING_IO;
2916 2914 rval = 0; /* so open doesn't fail */
2917 2915 } else if (rval) {
2918 2916 /*
2919 2917 * Release the tape unit, if reserved and not
2920 2918 * preserve reserve.
2921 2919 */
2922 2920 if ((un->un_rsvd_status &
2923 2921 (ST_RESERVE | ST_PRESERVE_RESERVE)) == ST_RESERVE) {
2924 2922 (void) st_reserve_release(un, ST_RELEASE,
2925 2923 st_uscsi_cmd);
2926 2924 }
2927 2925 } else {
2928 2926 un->un_state = ST_STATE_OPEN_PENDING_IO;
2929 2927 }
2930 2928 }
2931 2929
2932 2930 exit:
2933 2931 /*
2934 2932 * we don't want any uninvited guests scrogging our data when we're
2935 2933 * busy with something, so for successful opens or failed opens
2936 2934 * (except for EBUSY), reset these counters and state appropriately.
2937 2935 */
2938 2936 if (rval != EBUSY) {
2939 2937 if (rval) {
2940 2938 un->un_state = ST_STATE_CLOSED;
2941 2939 }
2942 2940 un->un_err_resid = 0;
2943 2941 un->un_retry_ct = 0;
2944 2942 }
2945 2943 busy:
2946 2944 ST_DEBUG3(ST_DEVINFO, st_label, SCSI_DEBUG,
2947 2945 "st_open: return val = %x, state = %d\n", rval, un->un_state);
2948 2946 mutex_exit(ST_MUTEX);
2949 2947 return (rval);
2950 2948
2951 2949 }
2952 2950
2953 2951 static int
2954 2952 st_tape_init(struct scsi_tape *un)
2955 2953 {
2956 2954 int err;
2957 2955 int rval = 0;
2958 2956
2959 2957 ST_FUNC(ST_DEVINFO, st_tape_init);
2960 2958
2961 2959 ASSERT(mutex_owned(ST_MUTEX));
2962 2960
2963 2961 ST_DEBUG3(ST_DEVINFO, st_label, SCSI_DEBUG,
2964 2962 "st_tape_init(un = 0x%p, oflags = %d)\n", (void*)un, un->un_oflags);
2965 2963
2966 2964 /*
2967 2965 * Clean up after any errors left by 'last' close.
2968 2966 * This also handles the case of the initial open.
2969 2967 */
2970 2968 if (un->un_state != ST_STATE_INITIALIZING) {
2971 2969 un->un_laststate = un->un_state;
2972 2970 un->un_state = ST_STATE_OPENING;
2973 2971 }
2974 2972
2975 2973 un->un_kbytes_xferred = 0;
2976 2974
2977 2975 /*
2978 2976 * do a throw away TUR to clear check condition
2979 2977 */
2980 2978 err = st_cmd(un, SCMD_TEST_UNIT_READY, 0, SYNC_CMD);
2981 2979
2982 2980 /*
2983 2981 * If test unit ready fails because the drive is reserved
2984 2982 * by another host fail the open for no access.
2985 2983 */
2986 2984 if (err) {
2987 2985 if (un->un_rsvd_status & ST_RESERVATION_CONFLICT) {
2988 2986 un->un_state = ST_STATE_CLOSED;
2989 2987 ST_DEBUG(ST_DEVINFO, st_label, SCSI_DEBUG,
2990 2988 "st_tape_init: RESERVATION CONFLICT\n");
2991 2989 rval = EACCES;
2992 2990 goto exit;
2993 2991 } else if ((un->un_rsvd_status &
2994 2992 ST_APPLICATION_RESERVATIONS) != 0) {
2995 2993 if ((ST_RQSENSE != NULL) &&
2996 2994 (ST_RQSENSE->es_add_code == 0x2a &&
2997 2995 ST_RQSENSE->es_qual_code == 0x03)) {
2998 2996 un->un_state = ST_STATE_CLOSED;
2999 2997 rval = EACCES;
3000 2998 goto exit;
3001 2999 }
3002 3000 }
3003 3001 }
3004 3002
3005 3003 /*
3006 3004 * Tape self identification could fail if the tape drive is used by
3007 3005 * another host during attach time. We try to get the tape type
3008 3006 * again. This is also applied to any posponed configuration methods.
3009 3007 */
3010 3008 if (un->un_dp->type == ST_TYPE_INVALID) {
3011 3009 un->un_comp_page = ST_DEV_DATACOMP_PAGE | ST_DEV_CONFIG_PAGE;
3012 3010 st_known_tape_type(un);
3013 3011 }
3014 3012
3015 3013 /*
3016 3014 * If the tape type is still invalid, try to determine the generic
3017 3015 * configuration.
3018 3016 */
3019 3017 if (un->un_dp->type == ST_TYPE_INVALID) {
3020 3018 rval = st_determine_generic(un);
3021 3019 if (rval) {
3022 3020 if (rval != EACCES) {
3023 3021 rval = EIO;
3024 3022 }
3025 3023 un->un_state = ST_STATE_CLOSED;
3026 3024 ST_DEBUG2(ST_DEVINFO, st_label, SCSI_DEBUG,
3027 3025 "st_tape_init: %s invalid type\n",
3028 3026 rval == EACCES ? "EACCES" : "EIO");
3029 3027 goto exit;
3030 3028 }
3031 3029 /*
3032 3030 * If this is a Unknown Type drive,
3033 3031 * Use the READ BLOCK LIMITS to determine if
3034 3032 * allow large xfer is approprate if not globally
3035 3033 * disabled with st_allow_large_xfer.
3036 3034 */
3037 3035 un->un_allow_large_xfer = (uchar_t)st_allow_large_xfer;
3038 3036 } else {
3039 3037
3040 3038 /*
3041 3039 * If we allow_large_xfer (ie >64k) and have not yet found out
3042 3040 * the max block size supported by the drive,
3043 3041 * find it by issueing a READ_BLKLIM command.
3044 3042 * if READ_BLKLIM cmd fails, assume drive doesn't
3045 3043 * allow_large_xfer and min/max block sizes as 1 byte and 63k.
3046 3044 */
3047 3045 un->un_allow_large_xfer = st_allow_large_xfer &&
3048 3046 (un->un_dp->options & ST_NO_RECSIZE_LIMIT);
3049 3047 }
3050 3048 /*
3051 3049 * if maxbsize is unknown, set the maximum block size.
3052 3050 */
3053 3051 if (un->un_maxbsize == MAXBSIZE_UNKNOWN) {
3054 3052
3055 3053 /*
3056 3054 * Get the Block limits of the tape drive.
3057 3055 * if un->un_allow_large_xfer = 0 , then make sure
3058 3056 * that maxbsize is <= ST_MAXRECSIZE_FIXED.
3059 3057 */
3060 3058 un->un_rbl = kmem_zalloc(RBLSIZE, KM_SLEEP);
3061 3059
3062 3060 err = st_cmd(un, SCMD_READ_BLKLIM, RBLSIZE, SYNC_CMD);
3063 3061 if (err) {
3064 3062 /* Retry */
3065 3063 err = st_cmd(un, SCMD_READ_BLKLIM, RBLSIZE, SYNC_CMD);
3066 3064 }
3067 3065 if (!err) {
3068 3066
3069 3067 /*
3070 3068 * if cmd successful, use limit returned
3071 3069 */
3072 3070 un->un_maxbsize = (un->un_rbl->max_hi << 16) +
3073 3071 (un->un_rbl->max_mid << 8) +
3074 3072 un->un_rbl->max_lo;
3075 3073 un->un_minbsize = (un->un_rbl->min_hi << 8) +
3076 3074 un->un_rbl->min_lo;
3077 3075 un->un_data_mod = 1 << un->un_rbl->granularity;
3078 3076 if ((un->un_maxbsize == 0) ||
3079 3077 (un->un_allow_large_xfer == 0 &&
3080 3078 un->un_maxbsize > ST_MAXRECSIZE_FIXED)) {
3081 3079 un->un_maxbsize = ST_MAXRECSIZE_FIXED;
3082 3080
3083 3081 } else if (un->un_dp->type == ST_TYPE_DEFAULT) {
3084 3082 /*
3085 3083 * Drive is not one that is configured, But the
3086 3084 * READ BLOCK LIMITS tells us it can do large
3087 3085 * xfers.
3088 3086 */
3089 3087 if (un->un_maxbsize > ST_MAXRECSIZE_FIXED) {
3090 3088 un->un_dp->options |=
3091 3089 ST_NO_RECSIZE_LIMIT;
3092 3090 }
3093 3091 /*
3094 3092 * If max and mimimum block limits are the
3095 3093 * same this is a fixed block size device.
3096 3094 */
3097 3095 if (un->un_maxbsize == un->un_minbsize) {
3098 3096 un->un_dp->options &= ~ST_VARIABLE;
3099 3097 }
3100 3098 }
3101 3099
3102 3100 if (un->un_minbsize == 0) {
3103 3101 un->un_minbsize = 1;
3104 3102 }
3105 3103
3106 3104 } else { /* error on read block limits */
3107 3105
3108 3106 scsi_log(ST_DEVINFO, st_label, CE_NOTE,
3109 3107 "!st_tape_init: Error on READ BLOCK LIMITS,"
3110 3108 " errno = %d un_rsvd_status = 0x%X\n",
3111 3109 err, un->un_rsvd_status);
3112 3110
3113 3111 /*
3114 3112 * since read block limits cmd failed,
3115 3113 * do not allow large xfers.
3116 3114 * use old values in st_minphys
3117 3115 */
3118 3116 if (un->un_rsvd_status & ST_RESERVATION_CONFLICT) {
3119 3117 rval = EACCES;
3120 3118 } else {
3121 3119 un->un_allow_large_xfer = 0;
3122 3120 scsi_log(ST_DEVINFO, st_label, CE_NOTE,
3123 3121 "!Disabling large transfers\n");
3124 3122
3125 3123 /*
3126 3124 * we guess maxbsize and minbsize
3127 3125 */
3128 3126 if (un->un_bsize) {
3129 3127 un->un_maxbsize = un->un_minbsize =
3130 3128 un->un_bsize;
3131 3129 } else {
3132 3130 un->un_maxbsize = ST_MAXRECSIZE_FIXED;
3133 3131 un->un_minbsize = 1;
3134 3132 }
3135 3133 /*
3136 3134 * Data Mod must be set,
3137 3135 * Even if read block limits fails.
3138 3136 * Prevents Divide By Zero in st_rw().
3139 3137 */
3140 3138 un->un_data_mod = 1;
3141 3139 }
3142 3140 }
3143 3141 if (un->un_rbl) {
3144 3142 kmem_free(un->un_rbl, RBLSIZE);
3145 3143 un->un_rbl = NULL;
3146 3144 }
3147 3145
3148 3146 if (rval) {
3149 3147 goto exit;
3150 3148 }
3151 3149 }
3152 3150
3153 3151 ST_DEBUG4(ST_DEVINFO, st_label, SCSI_DEBUG,
3154 3152 "maxdma = %d, maxbsize = %d, minbsize = %d, %s large xfer\n",
3155 3153 un->un_maxdma, un->un_maxbsize, un->un_minbsize,
3156 3154 (un->un_allow_large_xfer ? "ALLOW": "DON'T ALLOW"));
3157 3155
3158 3156 err = st_cmd(un, SCMD_TEST_UNIT_READY, 0, SYNC_CMD);
3159 3157
3160 3158 if (err != 0) {
3161 3159 if (err == EINTR) {
3162 3160 un->un_laststate = un->un_state;
3163 3161 un->un_state = ST_STATE_CLOSED;
3164 3162 rval = EINTR;
3165 3163 goto exit;
3166 3164 }
3167 3165 /*
3168 3166 * Make sure the tape is ready
3169 3167 */
3170 3168 un->un_pos.pmode = invalid;
3171 3169 if (un->un_status != KEY_UNIT_ATTENTION) {
3172 3170 /*
3173 3171 * allow open no media. Subsequent MTIOCSTATE
3174 3172 * with media present will complete the open
3175 3173 * logic.
3176 3174 */
3177 3175 un->un_laststate = un->un_state;
3178 3176 if (un->un_oflags & (FNONBLOCK|FNDELAY)) {
3179 3177 un->un_mediastate = MTIO_EJECTED;
3180 3178 un->un_state = ST_STATE_OFFLINE;
3181 3179 rval = 0;
3182 3180 goto exit;
3183 3181 } else {
3184 3182 un->un_state = ST_STATE_CLOSED;
3185 3183 ST_DEBUG2(ST_DEVINFO, st_label, SCSI_DEBUG,
3186 3184 "st_tape_init EIO no media, not opened "
3187 3185 "O_NONBLOCK|O_EXCL\n");
3188 3186 rval = EIO;
3189 3187 goto exit;
3190 3188 }
3191 3189 }
3192 3190 }
3193 3191
3194 3192 /*
3195 3193 * On each open, initialize block size from drivetype struct,
3196 3194 * as it could have been changed by MTSRSZ ioctl.
3197 3195 * Now, ST_VARIABLE simply means drive is capable of variable
3198 3196 * mode. All drives are assumed to support fixed records.
3199 3197 * Hence, un_bsize tells what mode the drive is in.
3200 3198 * un_bsize = 0 - variable record length
3201 3199 * = x - fixed record length is x
3202 3200 */
3203 3201 un->un_bsize = un->un_dp->bsize;
3204 3202
3205 3203 /*
3206 3204 * If saved position is valid go there
3207 3205 */
3208 3206 if (un->un_restore_pos) {
3209 3207 un->un_restore_pos = 0;
3210 3208 un->un_pos.fileno = un->un_save_fileno;
3211 3209 un->un_pos.blkno = un->un_save_blkno;
3212 3210 rval = st_validate_tapemarks(un, st_uscsi_cmd, &un->un_pos);
3213 3211 if (rval != 0) {
3214 3212 if (rval != EACCES) {
3215 3213 rval = EIO;
3216 3214 }
3217 3215 un->un_laststate = un->un_state;
3218 3216 un->un_state = ST_STATE_CLOSED;
3219 3217 goto exit;
3220 3218 }
3221 3219 }
3222 3220
3223 3221 if (un->un_pos.pmode == invalid) {
3224 3222 rval = st_loadtape(un);
3225 3223 if (rval) {
3226 3224 if (rval != EACCES) {
3227 3225 rval = EIO;
3228 3226 }
3229 3227 un->un_laststate = un->un_state;
3230 3228 un->un_state = ST_STATE_CLOSED;
3231 3229 ST_DEBUG2(ST_DEVINFO, st_label, SCSI_DEBUG,
3232 3230 "st_tape_init: %s can't open tape\n",
3233 3231 rval == EACCES ? "EACCES" : "EIO");
3234 3232 goto exit;
3235 3233 }
3236 3234 }
3237 3235
3238 3236 /*
3239 3237 * do a mode sense to pick up state of current write-protect,
3240 3238 * Could cause reserve and fail due to conflict.
3241 3239 */
3242 3240 if (un->un_unit_attention_flags) {
3243 3241 rval = st_modesense(un);
3244 3242 if (rval == EACCES) {
3245 3243 goto exit;
3246 3244 }
3247 3245 }
3248 3246
3249 3247 /*
3250 3248 * If we are opening the tape for writing, check
3251 3249 * to make sure that the tape can be written.
3252 3250 */
3253 3251 if (un->un_oflags & FWRITE) {
3254 3252 err = 0;
3255 3253 if (un->un_mspl->wp) {
3256 3254 un->un_status = KEY_WRITE_PROTECT;
3257 3255 un->un_laststate = un->un_state;
3258 3256 un->un_state = ST_STATE_CLOSED;
3259 3257 rval = EACCES;
3260 3258 /*
3261 3259 * STK sets the wp bit if volsafe tape is loaded.
3262 3260 */
3263 3261 if ((un->un_dp->type == MT_ISSTK9840) &&
3264 3262 (un->un_dp->options & ST_WORMABLE)) {
3265 3263 un->un_read_only = RDONLY;
3266 3264 } else {
3267 3265 goto exit;
3268 3266 }
3269 3267 } else {
3270 3268 un->un_read_only = RDWR;
3271 3269 }
3272 3270 } else {
3273 3271 un->un_read_only = RDONLY;
3274 3272 }
3275 3273
3276 3274 if (un->un_dp->options & ST_WORMABLE &&
3277 3275 un->un_unit_attention_flags) {
3278 3276 un->un_read_only |= un->un_wormable(un);
3279 3277
3280 3278 if (((un->un_read_only == WORM) ||
3281 3279 (un->un_read_only == RDWORM)) &&
3282 3280 ((un->un_oflags & FWRITE) == FWRITE)) {
3283 3281 un->un_status = KEY_DATA_PROTECT;
3284 3282 rval = EACCES;
3285 3283 ST_DEBUG4(ST_DEVINFO, st_label, CE_NOTE,
3286 3284 "read_only = %d eof = %d oflag = %d\n",
3287 3285 un->un_read_only, un->un_pos.eof, un->un_oflags);
3288 3286 }
3289 3287 }
3290 3288
3291 3289 /*
3292 3290 * If we're opening the tape write-only, we need to
3293 3291 * write 2 filemarks on the HP 1/2 inch drive, to
3294 3292 * create a null file.
3295 3293 */
3296 3294 if ((un->un_read_only == RDWR) ||
3297 3295 (un->un_read_only == WORM) && (un->un_oflags & FWRITE)) {
3298 3296 if (un->un_dp->options & ST_REEL) {
3299 3297 un->un_fmneeded = 2;
3300 3298 } else {
3301 3299 un->un_fmneeded = 1;
3302 3300 }
3303 3301 } else {
3304 3302 un->un_fmneeded = 0;
3305 3303 }
3306 3304
3307 3305 ST_DEBUG4(ST_DEVINFO, st_label, SCSI_DEBUG,
3308 3306 "fmneeded = %x\n", un->un_fmneeded);
3309 3307
3310 3308 /*
3311 3309 * Make sure the density can be selected correctly.
3312 3310 * If WORM can only write at the append point which in most cases
3313 3311 * isn't BOP. st_determine_density() with a B_WRITE only attempts
3314 3312 * to set and try densities if a BOP.
3315 3313 */
3316 3314 if (st_determine_density(un,
3317 3315 un->un_read_only == RDWR ? B_WRITE : B_READ)) {
3318 3316 un->un_status = KEY_ILLEGAL_REQUEST;
3319 3317 un->un_laststate = un->un_state;
3320 3318 un->un_state = ST_STATE_CLOSED;
3321 3319 ST_DEBUG(ST_DEVINFO, st_label, SCSI_DEBUG,
3322 3320 "st_tape_init: EIO can't determine density\n");
3323 3321 rval = EIO;
3324 3322 goto exit;
3325 3323 }
3326 3324
3327 3325 /*
3328 3326 * Destroy the knowledge that we have 'determined'
3329 3327 * density so that a later read at BOT comes along
3330 3328 * does the right density determination.
3331 3329 */
3332 3330
3333 3331 un->un_density_known = 0;
3334 3332
3335 3333
3336 3334 /*
3337 3335 * Okay, the tape is loaded and either at BOT or somewhere past.
3338 3336 * Mark the state such that any I/O or tape space operations
3339 3337 * will get/set the right density, etc..
3340 3338 */
3341 3339 un->un_laststate = un->un_state;
3342 3340 un->un_lastop = ST_OP_NIL;
3343 3341 un->un_mediastate = MTIO_INSERTED;
3344 3342 cv_broadcast(&un->un_state_cv);
3345 3343
3346 3344 /*
3347 3345 * Set test append flag if writing.
3348 3346 * First write must check that tape is positioned correctly.
3349 3347 */
3350 3348 un->un_test_append = (un->un_oflags & FWRITE);
3351 3349
3352 3350 /*
3353 3351 * if there are pending unit attention flags.
3354 3352 * Check that the media has not changed.
3355 3353 */
3356 3354 if (un->un_unit_attention_flags) {
3357 3355 rval = st_get_media_identification(un, st_uscsi_cmd);
3358 3356 if (rval != 0 && rval != EACCES) {
3359 3357 rval = EIO;
3360 3358 }
3361 3359 un->un_unit_attention_flags = 0;
3362 3360 }
3363 3361
3364 3362 exit:
3365 3363 un->un_err_resid = 0;
3366 3364 un->un_last_resid = 0;
3367 3365 un->un_last_count = 0;
3368 3366
3369 3367 ST_DEBUG6(ST_DEVINFO, st_label, SCSI_DEBUG,
3370 3368 "st_tape_init: return val = %x\n", rval);
3371 3369 return (rval);
3372 3370
3373 3371 }
3374 3372
3375 3373
3376 3374
3377 3375 /* ARGSUSED */
3378 3376 static int
3379 3377 st_close(dev_t dev, int flag, int otyp, cred_t *cred_p)
3380 3378 {
3381 3379 int err = 0;
3382 3380 int count, last_state;
3383 3381 minor_t minor = getminor(dev);
3384 3382 #ifdef __x86
3385 3383 struct contig_mem *cp, *cp_temp;
3386 3384 #endif
3387 3385
3388 3386 GET_SOFT_STATE(dev);
3389 3387
3390 3388 ST_ENTR(ST_DEVINFO, st_close);
3391 3389
3392 3390 /*
3393 3391 * wait till all cmds in the pipeline have been completed
3394 3392 */
3395 3393 mutex_enter(ST_MUTEX);
3396 3394
3397 3395 ST_DEBUG3(ST_DEVINFO, st_label, SCSI_DEBUG,
3398 3396 "st_close(dev = 0x%lx, flag = %d, otyp = %d)\n", dev, flag, otyp);
3399 3397
3400 3398 st_wait_for_io(un);
3401 3399
3402 3400 /* turn off persistent errors on close, as we want close to succeed */
3403 3401 st_turn_pe_off(un);
3404 3402
3405 3403 /*
3406 3404 * set state to indicate that we are in process of closing
3407 3405 */
3408 3406 last_state = un->un_laststate = un->un_state;
3409 3407 un->un_state = ST_STATE_CLOSING;
3410 3408
3411 3409 ST_POS(ST_DEVINFO, "st_close1:", &un->un_pos);
3412 3410
3413 3411 /*
3414 3412 * BSD behavior:
3415 3413 * a close always causes a silent span to the next file if we've hit
3416 3414 * an EOF (but not yet read across it).
3417 3415 */
3418 3416 if ((minor & MT_BSD) && (un->un_pos.eof == ST_EOF)) {
3419 3417 if (un->un_pos.pmode != invalid) {
3420 3418 un->un_pos.fileno++;
3421 3419 un->un_pos.blkno = 0;
3422 3420 }
3423 3421 un->un_pos.eof = ST_NO_EOF;
3424 3422 }
3425 3423
3426 3424 /*
3427 3425 * SVR4 behavior for skipping to next file:
3428 3426 *
3429 3427 * If we have not seen a filemark, space to the next file
3430 3428 *
3431 3429 * If we have already seen the filemark we are physically in the next
3432 3430 * file and we only increment the filenumber
3433 3431 */
3434 3432 if (((minor & (MT_BSD | MT_NOREWIND)) == MT_NOREWIND) &&
3435 3433 (flag & FREAD) && /* reading or at least asked to */
3436 3434 (un->un_mediastate == MTIO_INSERTED) && /* tape loaded */
3437 3435 (un->un_pos.pmode != invalid) && /* XXX position known */
3438 3436 ((un->un_pos.blkno != 0) && /* inside a file */
3439 3437 (un->un_lastop != ST_OP_WRITE) && /* Didn't just write */
3440 3438 (un->un_lastop != ST_OP_WEOF))) { /* or write filemarks */
3441 3439 switch (un->un_pos.eof) {
3442 3440 case ST_NO_EOF:
3443 3441 /*
3444 3442 * if we were reading and did not read the complete file
3445 3443 * skip to the next file, leaving the tape correctly
3446 3444 * positioned to read the first record of the next file
3447 3445 * Check first for REEL if we are at EOT by trying to
3448 3446 * read a block
3449 3447 */
3450 3448 if ((un->un_dp->options & ST_REEL) &&
3451 3449 (!(un->un_dp->options & ST_READ_IGNORE_EOFS)) &&
3452 3450 (un->un_pos.blkno == 0)) {
3453 3451 if (st_cmd(un, SCMD_SPACE, Blk(1), SYNC_CMD)) {
3454 3452 ST_DEBUG2(ST_DEVINFO, st_label,
3455 3453 SCSI_DEBUG,
3456 3454 "st_close : EIO can't space\n");
3457 3455 err = EIO;
3458 3456 goto error_out;
3459 3457 }
3460 3458 if (un->un_pos.eof >= ST_EOF_PENDING) {
3461 3459 un->un_pos.eof = ST_EOT_PENDING;
3462 3460 un->un_pos.fileno += 1;
3463 3461 un->un_pos.blkno = 0;
3464 3462 break;
3465 3463 }
3466 3464 }
3467 3465 if (st_cmd(un, SCMD_SPACE, Fmk(1), SYNC_CMD)) {
3468 3466 ST_DEBUG2(ST_DEVINFO, st_label, SCSI_DEBUG,
3469 3467 "st_close: EIO can't space #2\n");
3470 3468 err = EIO;
3471 3469 goto error_out;
3472 3470 } else {
3473 3471 ST_DEBUG6(ST_DEVINFO, st_label, SCSI_DEBUG,
3474 3472 "st_close2: fileno=%x,blkno=%x,eof=%x\n",
3475 3473 un->un_pos.fileno, un->un_pos.blkno,
3476 3474 un->un_pos.eof);
3477 3475 un->un_pos.eof = ST_NO_EOF;
3478 3476 }
3479 3477 break;
3480 3478
3481 3479 case ST_EOF_PENDING:
3482 3480 case ST_EOF:
3483 3481 un->un_pos.fileno += 1;
3484 3482 un->un_pos.lgclblkno += 1;
3485 3483 un->un_pos.blkno = 0;
3486 3484 un->un_pos.eof = ST_NO_EOF;
3487 3485 break;
3488 3486
3489 3487 case ST_EOT:
3490 3488 case ST_EOT_PENDING:
3491 3489 case ST_EOM:
3492 3490 /* nothing to do */
3493 3491 break;
3494 3492 default:
3495 3493 ST_DEBUG(ST_DEVINFO, st_label, CE_PANIC,
3496 3494 "Undefined state 0x%x", un->un_pos.eof);
3497 3495
3498 3496 }
3499 3497 }
3500 3498
3501 3499
3502 3500 /*
3503 3501 * For performance reasons (HP 88780), the driver should
3504 3502 * postpone writing the second tape mark until just before a file
3505 3503 * positioning ioctl is issued (e.g., rewind). This means that
3506 3504 * the user must not manually rewind the tape because the tape will
3507 3505 * be missing the second tape mark which marks EOM.
3508 3506 * However, this small performance improvement is not worth the risk.
3509 3507 */
3510 3508
3511 3509 /*
3512 3510 * We need to back up over the filemark we inadvertently popped
3513 3511 * over doing a read in between the two filemarks that constitute
3514 3512 * logical eot for 1/2" tapes. Note that ST_EOT_PENDING is only
3515 3513 * set while reading.
3516 3514 *
3517 3515 * If we happen to be at physical eot (ST_EOM) (writing case),
3518 3516 * the writing of filemark(s) will clear the ST_EOM state, which
3519 3517 * we don't want, so we save this state and restore it later.
3520 3518 */
3521 3519
3522 3520 ST_DEBUG6(ST_DEVINFO, st_label, SCSI_DEBUG,
3523 3521 "flag=%x, fmneeded=%x, lastop=%x, eof=%x\n",
3524 3522 flag, un->un_fmneeded, un->un_lastop, un->un_pos.eof);
3525 3523
3526 3524 if (un->un_pos.eof == ST_EOT_PENDING) {
3527 3525 if (minor & MT_NOREWIND) {
3528 3526 if (st_cmd(un, SCMD_SPACE, Fmk(-1), SYNC_CMD)) {
3529 3527 ST_DEBUG2(ST_DEVINFO, st_label, SCSI_DEBUG,
3530 3528 "st_close: EIO can't space #3\n");
3531 3529 err = EIO;
3532 3530 goto error_out;
3533 3531 } else {
3534 3532 un->un_pos.blkno = 0;
3535 3533 un->un_pos.eof = ST_EOT;
3536 3534 }
3537 3535 } else {
3538 3536 un->un_pos.eof = ST_NO_EOF;
3539 3537 }
3540 3538
3541 3539 /*
3542 3540 * Do we need to write a file mark?
3543 3541 *
3544 3542 * only write filemarks if there are fmks to be written and
3545 3543 * - open for write (possibly read/write)
3546 3544 * - the last operation was a write
3547 3545 * or:
3548 3546 * - opened for wronly
3549 3547 * - no data was written
3550 3548 */
3551 3549 } else if ((un->un_pos.pmode != invalid) &&
3552 3550 (un->un_fmneeded > 0) &&
3553 3551 (((flag & FWRITE) &&
3554 3552 ((un->un_lastop == ST_OP_WRITE)||(un->un_lastop == ST_OP_WEOF))) ||
3555 3553 ((flag == FWRITE) && (un->un_lastop == ST_OP_NIL)))) {
3556 3554
3557 3555 /* save ST_EOM state */
3558 3556 int was_at_eom = (un->un_pos.eof == ST_EOM) ? 1 : 0;
3559 3557
3560 3558 /*
3561 3559 * Note that we will write a filemark if we had opened
3562 3560 * the tape write only and no data was written, thus
3563 3561 * creating a null file.
3564 3562 *
3565 3563 * If the user already wrote one, we only have to write 1 more.
3566 3564 * If they wrote two, we don't have to write any.
3567 3565 */
3568 3566
3569 3567 count = un->un_fmneeded;
3570 3568 if (count > 0) {
3571 3569 if (st_cmd(un, SCMD_WRITE_FILE_MARK, count, SYNC_CMD)) {
3572 3570 ST_DEBUG2(ST_DEVINFO, st_label, SCSI_DEBUG,
3573 3571 "st_close : EIO can't wfm\n");
3574 3572 err = EIO;
3575 3573 goto error_out;
3576 3574 }
3577 3575 if ((un->un_dp->options & ST_REEL) &&
3578 3576 (minor & MT_NOREWIND)) {
3579 3577 if (st_cmd(un, SCMD_SPACE, Fmk(-1), SYNC_CMD)) {
3580 3578 ST_DEBUG2(ST_DEVINFO, st_label,
3581 3579 SCSI_DEBUG,
3582 3580 "st_close : EIO space fmk(-1)\n");
3583 3581 err = EIO;
3584 3582 goto error_out;
3585 3583 }
3586 3584 un->un_pos.eof = ST_NO_EOF;
3587 3585 /* fix up block number */
3588 3586 un->un_pos.blkno = 0;
3589 3587 }
3590 3588 }
3591 3589
3592 3590 /*
3593 3591 * If we aren't going to be rewinding, and we were at
3594 3592 * physical eot, restore the state that indicates we
3595 3593 * are at physical eot. Once you have reached physical
3596 3594 * eot, and you close the tape, the only thing you can
3597 3595 * do on the next open is to rewind. Access to trailer
3598 3596 * records is only allowed without closing the device.
3599 3597 */
3600 3598 if ((minor & MT_NOREWIND) == 0 && was_at_eom) {
3601 3599 un->un_pos.eof = ST_EOM;
3602 3600 }
3603 3601 }
3604 3602
3605 3603 /*
3606 3604 * report soft errors if enabled and available, if we never accessed
3607 3605 * the drive, don't get errors. This will prevent some DAT error
3608 3606 * messages upon LOG SENSE.
3609 3607 */
3610 3608 if (st_report_soft_errors_on_close &&
3611 3609 (un->un_dp->options & ST_SOFT_ERROR_REPORTING) &&
3612 3610 (last_state != ST_STATE_OFFLINE)) {
3613 3611 if (st_report_soft_errors(dev, flag)) {
3614 3612 err = EIO;
3615 3613 goto error_out;
3616 3614 }
3617 3615 }
3618 3616
3619 3617
3620 3618 /*
3621 3619 * Do we need to rewind? Can we rewind?
3622 3620 */
3623 3621 if ((minor & MT_NOREWIND) == 0 &&
3624 3622 un->un_pos.pmode != invalid && err == 0) {
3625 3623 /*
3626 3624 * We'd like to rewind with the
3627 3625 * 'immediate' bit set, but this
3628 3626 * causes problems on some drives
3629 3627 * where subsequent opens get a
3630 3628 * 'NOT READY' error condition
3631 3629 * back while the tape is rewinding,
3632 3630 * which is impossible to distinguish
3633 3631 * from the condition of 'no tape loaded'.
3634 3632 *
3635 3633 * Also, for some targets, if you disconnect
3636 3634 * with the 'immediate' bit set, you don't
3637 3635 * actually return right away, i.e., the
3638 3636 * target ignores your request for immediate
3639 3637 * return.
3640 3638 *
3641 3639 * Instead, we'll fire off an async rewind
3642 3640 * command. We'll mark the device as closed,
3643 3641 * and any subsequent open will stall on
3644 3642 * the first TEST_UNIT_READY until the rewind
3645 3643 * completes.
3646 3644 */
3647 3645
3648 3646 /*
3649 3647 * Used to be if reserve was not supported we'd send an
3650 3648 * asynchronious rewind. Comments above may be slightly invalid
3651 3649 * as the immediate bit was never set. Doing an immedate rewind
3652 3650 * makes sense, I think fixes to not ready status might handle
3653 3651 * the problems described above.
3654 3652 */
3655 3653 if (un->un_sd->sd_inq->inq_ansi < 2) {
3656 3654 if (st_cmd(un, SCMD_REWIND, 0, SYNC_CMD)) {
3657 3655 err = EIO;
3658 3656 }
3659 3657 } else {
3660 3658 /* flush data for older drives per scsi spec. */
3661 3659 if (st_cmd(un, SCMD_WRITE_FILE_MARK, 0, SYNC_CMD)) {
3662 3660 err = EIO;
3663 3661 } else {
3664 3662 /* release the drive before rewind immediate */
3665 3663 if ((un->un_rsvd_status &
3666 3664 (ST_RESERVE | ST_PRESERVE_RESERVE)) ==
3667 3665 ST_RESERVE) {
3668 3666 if (st_reserve_release(un, ST_RELEASE,
3669 3667 st_uscsi_cmd)) {
3670 3668 err = EIO;
3671 3669 }
3672 3670 }
3673 3671
3674 3672 /* send rewind with immediate bit set */
3675 3673 if (st_cmd(un, SCMD_REWIND, 1, ASYNC_CMD)) {
3676 3674 err = EIO;
3677 3675 }
3678 3676 }
3679 3677 }
3680 3678 /*
3681 3679 * Setting positions invalid in case the rewind doesn't
3682 3680 * happen. Drives don't like to rewind if resets happen
3683 3681 * they will tend to move back to where the rewind was
3684 3682 * issued if a reset or something happens so that if a
3685 3683 * write happens the data doesn't get clobbered.
3686 3684 *
3687 3685 * Not a big deal if the position is invalid when the
3688 3686 * open occures it will do a read position.
3689 3687 */
3690 3688 un->un_pos.pmode = invalid;
3691 3689 un->un_running.pmode = invalid;
3692 3690
3693 3691 if (err == EIO) {
3694 3692 goto error_out;
3695 3693 }
3696 3694 }
3697 3695
3698 3696 /*
3699 3697 * eject tape if necessary
3700 3698 */
3701 3699 if (un->un_eject_tape_on_failure) {
3702 3700 un->un_eject_tape_on_failure = 0;
3703 3701 if (st_cmd(un, SCMD_LOAD, LD_UNLOAD, SYNC_CMD)) {
3704 3702 ST_DEBUG2(ST_DEVINFO, st_label, SCSI_DEBUG,
3705 3703 "st_close : can't unload tape\n");
3706 3704 err = EIO;
3707 3705 goto error_out;
3708 3706 } else {
3709 3707 ST_DEBUG2(ST_DEVINFO, st_label, SCSI_DEBUG,
3710 3708 "st_close : tape unloaded \n");
3711 3709 un->un_pos.eof = ST_NO_EOF;
3712 3710 un->un_mediastate = MTIO_EJECTED;
3713 3711 }
3714 3712 }
3715 3713 /*
3716 3714 * Release the tape unit, if default reserve/release
3717 3715 * behaviour.
3718 3716 */
3719 3717 if ((un->un_rsvd_status &
3720 3718 (ST_RESERVE | ST_PRESERVE_RESERVE |
3721 3719 ST_APPLICATION_RESERVATIONS)) == ST_RESERVE) {
3722 3720 (void) st_reserve_release(un, ST_RELEASE, st_uscsi_cmd);
3723 3721 }
3724 3722 error_out:
3725 3723 /*
3726 3724 * clear up state
3727 3725 */
3728 3726 un->un_laststate = un->un_state;
3729 3727 un->un_state = ST_STATE_CLOSED;
3730 3728 un->un_lastop = ST_OP_NIL;
3731 3729 un->un_throttle = 1; /* assume one request at time, for now */
3732 3730 un->un_retry_ct = 0;
3733 3731 un->un_errno = 0;
3734 3732 un->un_swr_token = (opaque_t)NULL;
3735 3733 un->un_rsvd_status &= ~(ST_INIT_RESERVE);
3736 3734
3737 3735 /* Restore the options to the init time settings */
3738 3736 if (un->un_init_options & ST_READ_IGNORE_ILI) {
3739 3737 un->un_dp->options |= ST_READ_IGNORE_ILI;
3740 3738 } else {
3741 3739 un->un_dp->options &= ~ST_READ_IGNORE_ILI;
3742 3740 }
3743 3741
3744 3742 if (un->un_init_options & ST_READ_IGNORE_EOFS) {
3745 3743 un->un_dp->options |= ST_READ_IGNORE_EOFS;
3746 3744 } else {
3747 3745 un->un_dp->options &= ~ST_READ_IGNORE_EOFS;
3748 3746 }
3749 3747
3750 3748 if (un->un_init_options & ST_SHORT_FILEMARKS) {
3751 3749 un->un_dp->options |= ST_SHORT_FILEMARKS;
3752 3750 } else {
3753 3751 un->un_dp->options &= ~ST_SHORT_FILEMARKS;
3754 3752 }
3755 3753
3756 3754 ASSERT(mutex_owned(ST_MUTEX));
3757 3755
3758 3756 /*
3759 3757 * Signal anyone awaiting a close operation to complete.
3760 3758 */
3761 3759 cv_signal(&un->un_clscv);
3762 3760
3763 3761 /*
3764 3762 * any kind of error on closing causes all state to be tossed
3765 3763 */
3766 3764 if (err && un->un_status != KEY_ILLEGAL_REQUEST) {
3767 3765 /*
3768 3766 * note that st_intr has already set
3769 3767 * un_pos.pmode to invalid.
3770 3768 */
3771 3769 un->un_density_known = 0;
3772 3770 }
3773 3771
3774 3772 #ifdef __x86
3775 3773 /*
3776 3774 * free any contiguous mem alloc'ed for big block I/O
3777 3775 */
3778 3776 cp = un->un_contig_mem;
3779 3777 while (cp) {
3780 3778 if (cp->cm_addr) {
3781 3779 ddi_dma_mem_free(&cp->cm_acc_hdl);
3782 3780 }
3783 3781 cp_temp = cp;
3784 3782 cp = cp->cm_next;
3785 3783 kmem_free(cp_temp,
3786 3784 sizeof (struct contig_mem) + biosize());
3787 3785 }
3788 3786 un->un_contig_mem_total_num = 0;
3789 3787 un->un_contig_mem_available_num = 0;
3790 3788 un->un_contig_mem = NULL;
3791 3789 un->un_max_contig_mem_len = 0;
3792 3790 #endif
3793 3791
3794 3792 ST_DEBUG(ST_DEVINFO, st_label, SCSI_DEBUG,
3795 3793 "st_close3: return val = %x, fileno=%x, blkno=%x, eof=%x\n",
3796 3794 err, un->un_pos.fileno, un->un_pos.blkno, un->un_pos.eof);
3797 3795
3798 3796 mutex_exit(ST_MUTEX);
3799 3797 return (err);
3800 3798 }
3801 3799
3802 3800 /*
3803 3801 * These routines perform raw i/o operations.
3804 3802 */
3805 3803
3806 3804 /* ARGSUSED2 */
3807 3805 static int
3808 3806 st_aread(dev_t dev, struct aio_req *aio, cred_t *cred_p)
3809 3807 {
3810 3808 #ifdef STDEBUG
3811 3809 GET_SOFT_STATE(dev);
3812 3810 ST_ENTR(ST_DEVINFO, st_aread);
3813 3811 #endif
3814 3812 return (st_arw(dev, aio, B_READ));
3815 3813 }
3816 3814
3817 3815
3818 3816 /* ARGSUSED2 */
3819 3817 static int
3820 3818 st_awrite(dev_t dev, struct aio_req *aio, cred_t *cred_p)
3821 3819 {
3822 3820 #ifdef STDEBUG
3823 3821 GET_SOFT_STATE(dev);
3824 3822 ST_ENTR(ST_DEVINFO, st_awrite);
3825 3823 #endif
3826 3824 return (st_arw(dev, aio, B_WRITE));
3827 3825 }
3828 3826
3829 3827
3830 3828
3831 3829 /* ARGSUSED */
3832 3830 static int
3833 3831 st_read(dev_t dev, struct uio *uiop, cred_t *cred_p)
3834 3832 {
3835 3833 #ifdef STDEBUG
3836 3834 GET_SOFT_STATE(dev);
3837 3835 ST_ENTR(ST_DEVINFO, st_read);
3838 3836 #endif
3839 3837 return (st_rw(dev, uiop, B_READ));
3840 3838 }
3841 3839
3842 3840 /* ARGSUSED */
3843 3841 static int
3844 3842 st_write(dev_t dev, struct uio *uiop, cred_t *cred_p)
3845 3843 {
3846 3844 #ifdef STDEBUG
3847 3845 GET_SOFT_STATE(dev);
3848 3846 ST_ENTR(ST_DEVINFO, st_write);
3849 3847 #endif
3850 3848 return (st_rw(dev, uiop, B_WRITE));
3851 3849 }
3852 3850
3853 3851 /*
3854 3852 * Due to historical reasons, old limits are: For variable-length devices:
3855 3853 * if greater than 64KB - 1 (ST_MAXRECSIZE_VARIABLE), block into 64 KB - 2
3856 3854 * ST_MAXRECSIZE_VARIABLE_LIMIT) requests; otherwise,
3857 3855 * (let it through unmodified. For fixed-length record devices:
3858 3856 * 63K (ST_MAXRECSIZE_FIXED) is max (default minphys).
3859 3857 *
3860 3858 * The new limits used are un_maxdma (retrieved using scsi_ifgetcap()
3861 3859 * from the HBA) and un_maxbsize (retrieved by sending SCMD_READ_BLKLIM
3862 3860 * command to the drive).
3863 3861 *
3864 3862 */
3865 3863 static void
3866 3864 st_minphys(struct buf *bp)
3867 3865 {
3868 3866 struct scsi_tape *un;
3869 3867
3870 3868 un = ddi_get_soft_state(st_state, MTUNIT(bp->b_edev));
3871 3869
3872 3870 ST_FUNC(ST_DEVINFO, st_minphys);
3873 3871
3874 3872 ST_DEBUG3(ST_DEVINFO, st_label, SCSI_DEBUG,
3875 3873 "st_minphys(bp = 0x%p): b_bcount = 0x%lx\n", (void *)bp,
3876 3874 bp->b_bcount);
3877 3875
3878 3876 if (un->un_allow_large_xfer) {
3879 3877
3880 3878 /*
3881 3879 * check un_maxbsize for variable length devices only
3882 3880 */
3883 3881 if (un->un_bsize == 0 && bp->b_bcount > un->un_maxbsize) {
3884 3882 bp->b_bcount = un->un_maxbsize;
3885 3883 }
3886 3884 /*
3887 3885 * can't go more that HBA maxdma limit in either fixed-length
3888 3886 * or variable-length tape drives.
3889 3887 */
3890 3888 if (bp->b_bcount > un->un_maxdma) {
3891 3889 bp->b_bcount = un->un_maxdma;
3892 3890 }
3893 3891 } else {
3894 3892
3895 3893 /*
3896 3894 * use old fixed limits
3897 3895 */
3898 3896 if (un->un_bsize == 0) {
3899 3897 if (bp->b_bcount > ST_MAXRECSIZE_VARIABLE) {
3900 3898 bp->b_bcount = ST_MAXRECSIZE_VARIABLE_LIMIT;
3901 3899 }
3902 3900 } else {
3903 3901 if (bp->b_bcount > ST_MAXRECSIZE_FIXED) {
3904 3902 bp->b_bcount = ST_MAXRECSIZE_FIXED;
3905 3903 }
3906 3904 }
3907 3905 }
3908 3906
3909 3907 /*
3910 3908 * For regular raw I/O and Fixed Block length devices, make sure
3911 3909 * the adjusted block count is a whole multiple of the device
3912 3910 * block size.
3913 3911 */
3914 3912 if (bp != un->un_sbufp && un->un_bsize) {
3915 3913 bp->b_bcount -= (bp->b_bcount % un->un_bsize);
3916 3914 }
3917 3915 }
3918 3916
3919 3917 static int
3920 3918 st_rw(dev_t dev, struct uio *uio, int flag)
3921 3919 {
3922 3920 int rval = 0;
3923 3921 long len;
3924 3922
3925 3923 GET_SOFT_STATE(dev);
3926 3924
3927 3925 ST_FUNC(ST_DEVINFO, st_rw);
3928 3926
3929 3927 ST_DEBUG3(ST_DEVINFO, st_label, SCSI_DEBUG,
3930 3928 "st_rw(dev = 0x%lx, flag = %s)\n", dev,
3931 3929 (flag == B_READ ? rd_str: wr_str));
3932 3930
3933 3931 /* get local copy of transfer length */
3934 3932 len = uio->uio_iov->iov_len;
3935 3933
3936 3934 mutex_enter(ST_MUTEX);
3937 3935
3938 3936 /*
3939 3937 * Clear error entry stack
3940 3938 */
3941 3939 st_empty_error_stack(un);
3942 3940
3943 3941 /*
3944 3942 * If in fixed block size mode and requested read or write
3945 3943 * is not an even multiple of that block size.
3946 3944 */
3947 3945 if ((un->un_bsize != 0) && (len % un->un_bsize != 0)) {
3948 3946 scsi_log(ST_DEVINFO, st_label, CE_WARN,
3949 3947 "%s: not modulo %d block size\n",
3950 3948 (flag == B_WRITE) ? wr_str : rd_str, un->un_bsize);
3951 3949 rval = EINVAL;
3952 3950 }
3953 3951
3954 3952 /* If device has set granularity in the READ_BLKLIM we honor it. */
3955 3953 if ((un->un_data_mod != 0) && (len % un->un_data_mod != 0)) {
3956 3954 scsi_log(ST_DEVINFO, st_label, CE_WARN,
3957 3955 "%s: not modulo %d device granularity\n",
3958 3956 (flag == B_WRITE) ? wr_str : rd_str, un->un_data_mod);
3959 3957 rval = EINVAL;
3960 3958 }
3961 3959
3962 3960 if (st_recov_sz != sizeof (recov_info) && un->un_multipath) {
3963 3961 scsi_log(ST_DEVINFO, st_label, CE_WARN, mp_misconf);
3964 3962 rval = EFAULT;
3965 3963 }
3966 3964
3967 3965 if (rval != 0) {
3968 3966 un->un_errno = rval;
3969 3967 mutex_exit(ST_MUTEX);
3970 3968 return (rval);
3971 3969 }
3972 3970
3973 3971 /*
3974 3972 * Reset this so it can be set if Berkeley and read over a filemark.
3975 3973 */
3976 3974 un->un_silent_skip = 0;
3977 3975 mutex_exit(ST_MUTEX);
3978 3976
3979 3977 len = uio->uio_resid;
3980 3978
3981 3979 rval = physio(st_queued_strategy, (struct buf *)NULL,
3982 3980 dev, flag, st_minphys, uio);
3983 3981 /*
3984 3982 * if we have hit logical EOT during this xfer and there is not a
3985 3983 * full residue, then set eof back to ST_EOM to make sure that
3986 3984 * the user will see at least one zero write
3987 3985 * after this short write
3988 3986 */
3989 3987 mutex_enter(ST_MUTEX);
3990 3988 if (un->un_pos.eof > ST_NO_EOF) {
3991 3989 ST_DEBUG6(ST_DEVINFO, st_label, SCSI_DEBUG,
3992 3990 "eof=%d resid=%lx\n", un->un_pos.eof, uio->uio_resid);
3993 3991 }
3994 3992 if (un->un_pos.eof >= ST_EOM && (flag == B_WRITE)) {
3995 3993 if ((uio->uio_resid != len) && (uio->uio_resid != 0)) {
3996 3994 un->un_pos.eof = ST_EOM;
3997 3995 } else if (uio->uio_resid == len) {
3998 3996 un->un_pos.eof = ST_NO_EOF;
3999 3997 }
4000 3998 }
4001 3999
4002 4000 if (un->un_silent_skip && uio->uio_resid != len) {
4003 4001 un->un_pos.eof = ST_EOF;
4004 4002 un->un_pos.blkno = un->un_save_blkno;
4005 4003 un->un_pos.fileno--;
4006 4004 }
4007 4005
4008 4006 un->un_errno = rval;
4009 4007
4010 4008 mutex_exit(ST_MUTEX);
4011 4009
4012 4010 return (rval);
4013 4011 }
4014 4012
4015 4013 static int
4016 4014 st_arw(dev_t dev, struct aio_req *aio, int flag)
4017 4015 {
4018 4016 struct uio *uio = aio->aio_uio;
4019 4017 int rval = 0;
4020 4018 long len;
4021 4019
4022 4020 GET_SOFT_STATE(dev);
4023 4021
4024 4022 ST_FUNC(ST_DEVINFO, st_arw);
4025 4023
4026 4024 ST_DEBUG3(ST_DEVINFO, st_label, SCSI_DEBUG,
4027 4025 "st_arw(dev = 0x%lx, flag = %s)\n", dev,
4028 4026 (flag == B_READ ? rd_str: wr_str));
4029 4027
4030 4028 /* get local copy of transfer length */
4031 4029 len = uio->uio_iov->iov_len;
4032 4030
4033 4031 mutex_enter(ST_MUTEX);
4034 4032
4035 4033 /*
4036 4034 * If in fixed block size mode and requested read or write
4037 4035 * is not an even multiple of that block size.
4038 4036 */
4039 4037 if ((un->un_bsize != 0) && (len % un->un_bsize != 0)) {
4040 4038 scsi_log(ST_DEVINFO, st_label, CE_WARN,
4041 4039 "%s: not modulo %d block size\n",
4042 4040 (flag == B_WRITE) ? wr_str : rd_str, un->un_bsize);
4043 4041 rval = EINVAL;
4044 4042 }
4045 4043
4046 4044 /* If device has set granularity in the READ_BLKLIM we honor it. */
4047 4045 if ((un->un_data_mod != 0) && (len % un->un_data_mod != 0)) {
4048 4046 scsi_log(ST_DEVINFO, st_label, CE_WARN,
4049 4047 "%s: not modulo %d device granularity\n",
4050 4048 (flag == B_WRITE) ? wr_str : rd_str, un->un_data_mod);
4051 4049 rval = EINVAL;
4052 4050 }
4053 4051
4054 4052 if (st_recov_sz != sizeof (recov_info) && un->un_multipath) {
4055 4053 scsi_log(ST_DEVINFO, st_label, CE_WARN, mp_misconf);
4056 4054 rval = EFAULT;
4057 4055 }
4058 4056
4059 4057 if (rval != 0) {
4060 4058 un->un_errno = rval;
4061 4059 mutex_exit(ST_MUTEX);
4062 4060 return (rval);
4063 4061 }
4064 4062
4065 4063 mutex_exit(ST_MUTEX);
4066 4064
4067 4065 len = uio->uio_resid;
4068 4066
4069 4067 rval =
4070 4068 aphysio(st_queued_strategy, anocancel, dev, flag, st_minphys, aio);
4071 4069
4072 4070 /*
4073 4071 * if we have hit logical EOT during this xfer and there is not a
4074 4072 * full residue, then set eof back to ST_EOM to make sure that
4075 4073 * the user will see at least one zero write
4076 4074 * after this short write
4077 4075 *
4078 4076 * we keep this here just in case the application is not using
4079 4077 * persistent errors
4080 4078 */
4081 4079 mutex_enter(ST_MUTEX);
4082 4080 if (un->un_pos.eof > ST_NO_EOF) {
4083 4081 ST_DEBUG6(ST_DEVINFO, st_label, SCSI_DEBUG,
4084 4082 "eof=%d resid=%lx\n", un->un_pos.eof, uio->uio_resid);
4085 4083 }
4086 4084 if (un->un_pos.eof >= ST_EOM && (flag == B_WRITE)) {
4087 4085 if ((uio->uio_resid != len) && (uio->uio_resid != 0)) {
4088 4086 un->un_pos.eof = ST_EOM;
4089 4087 } else if (uio->uio_resid == len &&
4090 4088 !(un->un_persistence && un->un_persist_errors)) {
4091 4089 un->un_pos.eof = ST_NO_EOF;
4092 4090 }
4093 4091 }
4094 4092 un->un_errno = rval;
4095 4093 mutex_exit(ST_MUTEX);
4096 4094
4097 4095 return (rval);
4098 4096 }
4099 4097
4100 4098
4101 4099
4102 4100 static int
4103 4101 st_queued_strategy(buf_t *bp)
4104 4102 {
4105 4103 struct scsi_tape *un;
4106 4104 char reading = bp->b_flags & B_READ;
4107 4105 int wasopening = 0;
4108 4106
4109 4107 /*
4110 4108 * validate arguments
4111 4109 */
4112 4110 un = ddi_get_soft_state(st_state, MTUNIT(bp->b_edev));
4113 4111 if (un == NULL) {
4114 4112 bp->b_resid = bp->b_bcount;
4115 4113 bioerror(bp, ENXIO);
4116 4114 ST_DEBUG6(NULL, st_label, SCSI_DEBUG,
4117 4115 "st_queued_strategy: ENXIO error exit\n");
4118 4116 biodone(bp);
4119 4117 return (0);
4120 4118 }
4121 4119
4122 4120 ST_ENTR(ST_DEVINFO, st_queued_strategy);
4123 4121
4124 4122 mutex_enter(ST_MUTEX);
4125 4123
4126 4124 while (un->un_pwr_mgmt == ST_PWR_SUSPENDED) {
4127 4125 cv_wait(&un->un_suspend_cv, ST_MUTEX);
4128 4126 }
4129 4127
4130 4128 ST_DEBUG3(ST_DEVINFO, st_label, SCSI_DEBUG,
4131 4129 "st_queued_strategy(): bcount=0x%lx, fileno=%d, blkno=%x, eof=%d\n",
4132 4130 bp->b_bcount, un->un_pos.fileno, un->un_pos.blkno, un->un_pos.eof);
4133 4131
4134 4132 /*
4135 4133 * If persistent errors have been flagged, just nix this one. We wait
4136 4134 * for any outstanding I/O's below, so we will be in order.
4137 4135 */
4138 4136 if (un->un_persistence && un->un_persist_errors) {
4139 4137 goto exit;
4140 4138 }
4141 4139
4142 4140 /*
4143 4141 * If last command was non queued, wait till it finishes.
4144 4142 */
4145 4143 while (un->un_sbuf_busy) {
4146 4144 cv_wait(&un->un_sbuf_cv, ST_MUTEX);
4147 4145 /* woke up because of an error */
4148 4146 if (un->un_persistence && un->un_persist_errors) {
4149 4147 goto exit;
4150 4148 }
4151 4149 }
4152 4150
4153 4151 /*
4154 4152 * s_buf and recovery commands shouldn't come here.
4155 4153 */
4156 4154 ASSERT(bp != un->un_recov_buf);
4157 4155 ASSERT(bp != un->un_sbufp);
4158 4156
4159 4157 /*
4160 4158 * If we haven't done/checked reservation on the tape unit
4161 4159 * do it now.
4162 4160 */
4163 4161 if ((un->un_rsvd_status &
4164 4162 (ST_RESERVE | ST_APPLICATION_RESERVATIONS)) == 0) {
4165 4163 if ((un->un_dp->options & ST_NO_RESERVE_RELEASE) == 0) {
4166 4164 if (st_reserve_release(un, ST_RESERVE, st_uscsi_cmd)) {
4167 4165 st_bioerror(bp, un->un_errno);
4168 4166 goto exit;
4169 4167 }
4170 4168 } else if (un->un_state == ST_STATE_OPEN_PENDING_IO) {
4171 4169 /*
4172 4170 * Enter here to restore position for possible
4173 4171 * resets when the device was closed and opened
4174 4172 * in O_NDELAY mode subsequently
4175 4173 */
4176 4174 un->un_state = ST_STATE_INITIALIZING;
4177 4175 (void) st_cmd(un, SCMD_TEST_UNIT_READY,
4178 4176 0, SYNC_CMD);
4179 4177 un->un_state = ST_STATE_OPEN_PENDING_IO;
4180 4178 }
4181 4179 un->un_rsvd_status |= ST_INIT_RESERVE;
4182 4180 }
4183 4181
4184 4182 /*
4185 4183 * If we are offline, we have to initialize everything first.
4186 4184 * This is to handle either when opened with O_NDELAY, or
4187 4185 * we just got a new tape in the drive, after an offline.
4188 4186 * We don't observe O_NDELAY past the open,
4189 4187 * as it will not make sense for tapes.
4190 4188 */
4191 4189 if (un->un_state == ST_STATE_OFFLINE || un->un_restore_pos) {
4192 4190 /*
4193 4191 * reset state to avoid recursion
4194 4192 */
4195 4193 un->un_laststate = un->un_state;
4196 4194 un->un_state = ST_STATE_INITIALIZING;
4197 4195 if (st_tape_init(un)) {
4198 4196 ST_DEBUG2(ST_DEVINFO, st_label, SCSI_DEBUG,
4199 4197 "stioctl : OFFLINE init failure ");
4200 4198 un->un_state = ST_STATE_OFFLINE;
4201 4199 un->un_pos.pmode = invalid;
4202 4200 goto b_done_err;
4203 4201 }
4204 4202 /* un_restore_pos make invalid */
4205 4203 un->un_state = ST_STATE_OPEN_PENDING_IO;
4206 4204 un->un_restore_pos = 0;
4207 4205 }
4208 4206 /*
4209 4207 * Check for legal operations
4210 4208 */
4211 4209 if (un->un_pos.pmode == invalid) {
4212 4210 ST_DEBUG6(ST_DEVINFO, st_label, SCSI_DEBUG,
4213 4211 "strategy with un->un_pos.pmode invalid\n");
4214 4212 goto b_done_err;
4215 4213 }
4216 4214
4217 4215 ST_DEBUG6(ST_DEVINFO, st_label, SCSI_DEBUG,
4218 4216 "st_queued_strategy(): regular io\n");
4219 4217
4220 4218 /*
4221 4219 * Process this first. If we were reading, and we're pending
4222 4220 * logical eot, that means we've bumped one file mark too far.
4223 4221 */
4224 4222
4225 4223 /*
4226 4224 * Recursion warning: st_cmd will route back through here.
4227 4225 * Not anymore st_cmd will go through st_strategy()!
4228 4226 */
4229 4227 if (un->un_pos.eof == ST_EOT_PENDING) {
4230 4228 if (st_cmd(un, SCMD_SPACE, Fmk(-1), SYNC_CMD)) {
4231 4229 un->un_pos.pmode = invalid;
4232 4230 un->un_density_known = 0;
4233 4231 goto b_done_err;
4234 4232 }
4235 4233 un->un_pos.blkno = 0; /* fix up block number.. */
4236 4234 un->un_pos.eof = ST_EOT;
4237 4235 }
4238 4236
4239 4237 /*
4240 4238 * If we are in the process of opening, we may have to
4241 4239 * determine/set the correct density. We also may have
4242 4240 * to do a test_append (if QIC) to see whether we are
4243 4241 * in a position to append to the end of the tape.
4244 4242 *
4245 4243 * If we're already at logical eot, we transition
4246 4244 * to ST_NO_EOF. If we're at physical eot, we punt
4247 4245 * to the switch statement below to handle.
4248 4246 */
4249 4247 if ((un->un_state == ST_STATE_OPEN_PENDING_IO) ||
4250 4248 (un->un_test_append && (un->un_dp->options & ST_QIC))) {
4251 4249
4252 4250 if (un->un_state == ST_STATE_OPEN_PENDING_IO) {
4253 4251 if (st_determine_density(un, (int)reading)) {
4254 4252 goto b_done_err;
4255 4253 }
4256 4254 }
4257 4255
4258 4256 ST_DEBUG6(ST_DEVINFO, st_label, SCSI_DEBUG,
4259 4257 "pending_io@fileno %d rw %d qic %d eof %d\n",
4260 4258 un->un_pos.fileno, (int)reading,
4261 4259 (un->un_dp->options & ST_QIC) ? 1 : 0,
4262 4260 un->un_pos.eof);
4263 4261
4264 4262 if (!reading && un->un_pos.eof != ST_EOM) {
4265 4263 if (un->un_pos.eof == ST_EOT) {
4266 4264 un->un_pos.eof = ST_NO_EOF;
4267 4265 } else if (un->un_pos.pmode != invalid &&
4268 4266 (un->un_dp->options & ST_QIC)) {
4269 4267 /*
4270 4268 * st_test_append() will do it all
4271 4269 */
4272 4270 st_test_append(bp);
4273 4271 mutex_exit(ST_MUTEX);
4274 4272 return (0);
4275 4273 }
4276 4274 }
4277 4275 if (un->un_state == ST_STATE_OPEN_PENDING_IO) {
4278 4276 wasopening = 1;
4279 4277 }
4280 4278 un->un_laststate = un->un_state;
4281 4279 un->un_state = ST_STATE_OPEN;
4282 4280 }
4283 4281
4284 4282
4285 4283 /*
4286 4284 * Process rest of END OF FILE and END OF TAPE conditions
4287 4285 */
4288 4286
4289 4287 ST_DEBUG6(ST_DEVINFO, st_label, SCSI_DEBUG,
4290 4288 "eof=%x, wasopening=%x\n",
4291 4289 un->un_pos.eof, wasopening);
4292 4290
4293 4291 switch (un->un_pos.eof) {
4294 4292 case ST_EOM:
4295 4293 /*
4296 4294 * This allows writes to proceed past physical
4297 4295 * eot. We'll *really* be in trouble if the
4298 4296 * user continues blindly writing data too
4299 4297 * much past this point (unwind the tape).
4300 4298 * Physical eot really means 'early warning
4301 4299 * eot' in this context.
4302 4300 *
4303 4301 * Every other write from now on will succeed
4304 4302 * (if sufficient tape left).
4305 4303 * This write will return with resid == count
4306 4304 * but the next one should be successful
4307 4305 *
4308 4306 * Note that we only transition to logical EOT
4309 4307 * if the last state wasn't the OPENING state.
4310 4308 * We explicitly prohibit running up to physical
4311 4309 * eot, closing the device, and then re-opening
4312 4310 * to proceed. Trailer records may only be gotten
4313 4311 * at by keeping the tape open after hitting eot.
4314 4312 *
4315 4313 * Also note that ST_EOM cannot be set by reading-
4316 4314 * this can only be set during writing. Reading
4317 4315 * up to the end of the tape gets a blank check
4318 4316 * or a double-filemark indication (ST_EOT_PENDING),
4319 4317 * and we prohibit reading after that point.
4320 4318 *
4321 4319 */
4322 4320 ST_DEBUG6(ST_DEVINFO, st_label, SCSI_DEBUG, "EOM\n");
4323 4321 if (wasopening == 0) {
4324 4322 /*
4325 4323 * this allows st_rw() to reset it back to
4326 4324 * will see a zero write
4327 4325 */
4328 4326 un->un_pos.eof = ST_WRITE_AFTER_EOM;
4329 4327 }
4330 4328 un->un_status = SUN_KEY_EOT;
4331 4329 goto b_done;
4332 4330
4333 4331 case ST_WRITE_AFTER_EOM:
4334 4332 case ST_EOT:
4335 4333 ST_DEBUG6(ST_DEVINFO, st_label, SCSI_DEBUG, "EOT\n");
4336 4334 un->un_status = SUN_KEY_EOT;
4337 4335 if (SVR4_BEHAVIOR && reading) {
4338 4336 goto b_done_err;
4339 4337 }
4340 4338
4341 4339 if (reading) {
4342 4340 goto b_done;
4343 4341 }
4344 4342 un->un_pos.eof = ST_NO_EOF;
4345 4343 break;
4346 4344
4347 4345 case ST_EOF_PENDING:
4348 4346 ST_DEBUG6(ST_DEVINFO, st_label, SCSI_DEBUG,
4349 4347 "EOF PENDING\n");
4350 4348 un->un_status = SUN_KEY_EOF;
4351 4349 if (SVR4_BEHAVIOR) {
4352 4350 un->un_pos.eof = ST_EOF;
4353 4351 goto b_done;
4354 4352 }
4355 4353 /* FALLTHROUGH */
4356 4354 case ST_EOF:
4357 4355 ST_DEBUG6(ST_DEVINFO, st_label, SCSI_DEBUG, "EOF\n");
4358 4356 un->un_status = SUN_KEY_EOF;
4359 4357 if (SVR4_BEHAVIOR) {
4360 4358 goto b_done_err;
4361 4359 }
4362 4360
4363 4361 if (BSD_BEHAVIOR) {
4364 4362 un->un_pos.eof = ST_NO_EOF;
4365 4363 un->un_pos.fileno += 1;
4366 4364 un->un_pos.blkno = 0;
4367 4365 }
4368 4366
4369 4367 if (reading) {
4370 4368 ST_DEBUG6(ST_DEVINFO, st_label, SCSI_DEBUG,
4371 4369 "now file %d (read)\n",
4372 4370 un->un_pos.fileno);
4373 4371 goto b_done;
4374 4372 }
4375 4373 ST_DEBUG6(ST_DEVINFO, st_label, SCSI_DEBUG,
4376 4374 "now file %d (write)\n", un->un_pos.fileno);
4377 4375 break;
4378 4376 default:
4379 4377 un->un_status = 0;
4380 4378 break;
4381 4379 }
4382 4380
4383 4381 bp->b_flags &= ~(B_DONE);
4384 4382 st_bioerror(bp, 0);
4385 4383 bp->av_forw = NULL;
4386 4384 bp->b_resid = 0;
4387 4385 SET_BP_PKT(bp, 0);
4388 4386
4389 4387
4390 4388 ST_DEBUG6(ST_DEVINFO, st_label, SCSI_DEBUG,
4391 4389 "st_queued_strategy: cmd=0x%p count=%ld resid=%ld flags=0x%x"
4392 4390 " pkt=0x%p\n",
4393 4391 (void *)bp->b_forw, bp->b_bcount,
4394 4392 bp->b_resid, bp->b_flags, (void *)BP_PKT(bp));
4395 4393
4396 4394 #ifdef __x86
4397 4395 /*
4398 4396 * We will replace bp with a new bp that can do big blk xfer
4399 4397 * if the requested xfer size is bigger than un->un_maxdma_arch
4400 4398 *
4401 4399 * Also, we need to make sure that we're handling real I/O
4402 4400 * by checking group 0/1 SCSI I/O commands, if needed
4403 4401 */
4404 4402 if (bp->b_bcount > un->un_maxdma_arch &&
4405 4403 ((uchar_t)(uintptr_t)bp->b_forw == SCMD_READ ||
4406 4404 (uchar_t)(uintptr_t)bp->b_forw == SCMD_READ_G4 ||
4407 4405 (uchar_t)(uintptr_t)bp->b_forw == SCMD_WRITE ||
4408 4406 (uchar_t)(uintptr_t)bp->b_forw == SCMD_WRITE_G4)) {
4409 4407 mutex_exit(ST_MUTEX);
4410 4408 bp = st_get_bigblk_bp(bp);
4411 4409 mutex_enter(ST_MUTEX);
4412 4410 }
4413 4411 #endif
4414 4412
4415 4413 /* put on wait queue */
4416 4414 ST_DEBUG6(ST_DEVINFO, st_label, SCSI_DEBUG,
4417 4415 "st_queued_strategy: un->un_quef = 0x%p, bp = 0x%p\n",
4418 4416 (void *)un->un_quef, (void *)bp);
4419 4417
4420 4418 st_add_to_queue(&un->un_quef, &un->un_quel, un->un_quel, bp);
4421 4419
4422 4420 ST_DO_KSTATS(bp, kstat_waitq_enter);
4423 4421
4424 4422 st_start(un);
4425 4423
4426 4424 mutex_exit(ST_MUTEX);
4427 4425 return (0);
4428 4426
4429 4427 b_done_err:
4430 4428 st_bioerror(bp, EIO);
4431 4429 ST_DEBUG6(ST_DEVINFO, st_label, SCSI_DEBUG,
4432 4430 "st_queued_strategy : EIO b_done_err\n");
4433 4431
4434 4432 b_done:
4435 4433 ST_DEBUG6(ST_DEVINFO, st_label, SCSI_DEBUG,
4436 4434 "st_queued_strategy: b_done\n");
4437 4435
4438 4436 exit:
4439 4437 /*
4440 4438 * make sure no commands are outstanding or waiting before closing,
4441 4439 * so we can guarantee order
4442 4440 */
4443 4441 st_wait_for_io(un);
4444 4442 un->un_err_resid = bp->b_resid = bp->b_bcount;
4445 4443
4446 4444 /* override errno here, if persistent errors were flagged */
4447 4445 if (un->un_persistence && un->un_persist_errors)
4448 4446 bioerror(bp, un->un_errno);
4449 4447
4450 4448 mutex_exit(ST_MUTEX);
4451 4449
4452 4450 biodone(bp);
4453 4451 ASSERT(mutex_owned(ST_MUTEX) == 0);
4454 4452 return (0);
4455 4453 }
4456 4454
4457 4455
4458 4456 static int
4459 4457 st_strategy(struct buf *bp)
4460 4458 {
4461 4459 struct scsi_tape *un;
4462 4460
4463 4461 /*
4464 4462 * validate arguments
4465 4463 */
4466 4464 un = ddi_get_soft_state(st_state, MTUNIT(bp->b_edev));
4467 4465 if (un == NULL) {
4468 4466 bp->b_resid = bp->b_bcount;
4469 4467 bioerror(bp, ENXIO);
4470 4468 ST_DEBUG6(NULL, st_label, SCSI_DEBUG,
4471 4469 "st_strategy: ENXIO error exit\n");
4472 4470
4473 4471 biodone(bp);
4474 4472 return (0);
4475 4473
4476 4474 }
4477 4475
4478 4476 ST_ENTR(ST_DEVINFO, st_strategy);
4479 4477
4480 4478 mutex_enter(ST_MUTEX);
4481 4479
4482 4480 while (un->un_pwr_mgmt == ST_PWR_SUSPENDED) {
4483 4481 cv_wait(&un->un_suspend_cv, ST_MUTEX);
4484 4482 }
4485 4483
4486 4484 ST_DEBUG3(ST_DEVINFO, st_label, SCSI_DEBUG,
4487 4485 "st_strategy(): bcount=0x%lx, fileno=%d, blkno=%x, eof=%d\n",
4488 4486 bp->b_bcount, un->un_pos.fileno, un->un_pos.blkno, un->un_pos.eof);
4489 4487
4490 4488 ASSERT((bp == un->un_recov_buf) || (bp == un->un_sbufp));
4491 4489
4492 4490 bp->b_flags &= ~(B_DONE);
4493 4491 st_bioerror(bp, 0);
4494 4492 bp->av_forw = NULL;
4495 4493 bp->b_resid = 0;
4496 4494 SET_BP_PKT(bp, 0);
4497 4495
4498 4496
4499 4497 ST_DEBUG6(ST_DEVINFO, st_label, SCSI_DEBUG,
4500 4498 "st_strategy: cmd=0x%x count=%ld resid=%ld flags=0x%x"
4501 4499 " pkt=0x%p\n",
4502 4500 (unsigned char)(uintptr_t)bp->b_forw, bp->b_bcount,
4503 4501 bp->b_resid, bp->b_flags, (void *)BP_PKT(bp));
4504 4502 ST_DO_KSTATS(bp, kstat_waitq_enter);
4505 4503
4506 4504 st_start(un);
4507 4505
4508 4506 mutex_exit(ST_MUTEX);
4509 4507 return (0);
4510 4508 }
4511 4509
4512 4510 /*
4513 4511 * this routine spaces forward over filemarks
4514 4512 */
4515 4513 static int
4516 4514 st_space_fmks(struct scsi_tape *un, int64_t count)
4517 4515 {
4518 4516 int rval = 0;
4519 4517
4520 4518 ST_FUNC(ST_DEVINFO, st_space_fmks);
4521 4519
4522 4520 ST_DEBUG3(ST_DEVINFO, st_label, SCSI_DEBUG,
4523 4521 "st_space_fmks(dev = 0x%lx, count = %"PRIx64")\n",
4524 4522 un->un_dev, count);
4525 4523
4526 4524 ASSERT(mutex_owned(ST_MUTEX));
4527 4525
4528 4526 /*
4529 4527 * the risk with doing only one space operation is that we
4530 4528 * may accidentily jump in old data
4531 4529 * the exabyte 8500 reading 8200 tapes cannot use KNOWS_EOD
4532 4530 * because the 8200 does not append a marker; in order not to
4533 4531 * sacrifice the fast file skip, we do a slow skip if the low
4534 4532 * density device has been opened
4535 4533 */
4536 4534
4537 4535 if ((un->un_dp->options & ST_KNOWS_EOD) &&
4538 4536 !((un->un_dp->type == ST_TYPE_EXB8500 &&
4539 4537 MT_DENSITY(un->un_dev) == 0))) {
4540 4538 if (st_cmd(un, SCMD_SPACE, Fmk(count), SYNC_CMD)) {
4541 4539 ST_DEBUG2(ST_DEVINFO, st_label, SCSI_DEBUG,
4542 4540 "space_fmks : EIO can't do space cmd #1\n");
4543 4541 rval = EIO;
4544 4542 }
4545 4543 } else {
4546 4544 while (count > 0) {
4547 4545 if (st_cmd(un, SCMD_SPACE, Fmk(1), SYNC_CMD)) {
4548 4546 ST_DEBUG2(ST_DEVINFO, st_label, SCSI_DEBUG,
4549 4547 "space_fmks : EIO can't do space cmd #2\n");
4550 4548 rval = EIO;
4551 4549 break;
4552 4550 }
4553 4551 count -= 1;
4554 4552 /*
4555 4553 * read a block to see if we have reached
4556 4554 * end of medium (double filemark for reel or
4557 4555 * medium error for others)
4558 4556 */
4559 4557 if (count > 0) {
4560 4558 if (st_cmd(un, SCMD_SPACE, Blk(1), SYNC_CMD)) {
4561 4559 ST_DEBUG2(ST_DEVINFO, st_label,
4562 4560 SCSI_DEBUG,
4563 4561 "space_fmks : EIO can't do "
4564 4562 "space cmd #3\n");
4565 4563 rval = EIO;
4566 4564 break;
4567 4565 }
4568 4566 if ((un->un_pos.eof >= ST_EOF_PENDING) &&
4569 4567 (un->un_dp->options & ST_REEL)) {
4570 4568 un->un_status = SUN_KEY_EOT;
4571 4569 ST_DEBUG2(ST_DEVINFO, st_label,
4572 4570 SCSI_DEBUG,
4573 4571 "space_fmks : EIO ST_REEL\n");
4574 4572 rval = EIO;
4575 4573 break;
4576 4574 } else if (IN_EOF(un->un_pos)) {
4577 4575 un->un_pos.eof = ST_NO_EOF;
4578 4576 un->un_pos.fileno++;
4579 4577 un->un_pos.blkno = 0;
4580 4578 count--;
4581 4579 } else if (un->un_pos.eof > ST_EOF) {
4582 4580 ST_DEBUG2(ST_DEVINFO, st_label,
4583 4581 SCSI_DEBUG,
4584 4582 "space_fmks, EIO > ST_EOF\n");
4585 4583 rval = EIO;
4586 4584 break;
4587 4585 }
4588 4586
4589 4587 }
4590 4588 }
4591 4589 un->un_err_resid = count;
4592 4590 COPY_POS(&un->un_pos, &un->un_err_pos);
4593 4591 }
4594 4592 ASSERT(mutex_owned(ST_MUTEX));
4595 4593 return (rval);
4596 4594 }
4597 4595
4598 4596 /*
4599 4597 * this routine spaces to EOD
4600 4598 *
4601 4599 * it keeps track of the current filenumber and returns the filenumber after
4602 4600 * the last successful space operation, we keep the number high because as
4603 4601 * tapes are getting larger, the possibility of more and more files exist,
4604 4602 * 0x100000 (1 Meg of files) probably will never have to be changed any time
4605 4603 * soon
4606 4604 */
4607 4605 #define MAX_SKIP 0x100000 /* somewhat arbitrary */
4608 4606
4609 4607 static int
4610 4608 st_find_eod(struct scsi_tape *un)
4611 4609 {
4612 4610 tapepos_t savepos;
4613 4611 int64_t sp_type;
4614 4612 int result;
4615 4613
4616 4614 if (un == NULL) {
4617 4615 return (-1);
4618 4616 }
4619 4617
4620 4618 ST_FUNC(ST_DEVINFO, st_find_eod);
4621 4619
4622 4620 ST_DEBUG3(ST_DEVINFO, st_label, SCSI_DEBUG,
4623 4621 "st_find_eod(dev = 0x%lx): fileno = %d\n", un->un_dev,
4624 4622 un->un_pos.fileno);
4625 4623
4626 4624 ASSERT(mutex_owned(ST_MUTEX));
4627 4625
4628 4626 COPY_POS(&savepos, &un->un_pos);
4629 4627
4630 4628 /*
4631 4629 * see if the drive is smart enough to do the skips in
4632 4630 * one operation; 1/2" use two filemarks
4633 4631 * the exabyte 8500 reading 8200 tapes cannot use KNOWS_EOD
4634 4632 * because the 8200 does not append a marker; in order not to
4635 4633 * sacrifice the fast file skip, we do a slow skip if the low
4636 4634 * density device has been opened
4637 4635 */
4638 4636 if ((un->un_dp->options & ST_KNOWS_EOD) != 0) {
4639 4637 if ((un->un_dp->type == ST_TYPE_EXB8500) &&
4640 4638 (MT_DENSITY(un->un_dev) == 0)) {
4641 4639 sp_type = Fmk(1);
4642 4640 } else if (un->un_pos.pmode == logical) {
4643 4641 sp_type = SPACE(SP_EOD, 0);
4644 4642 } else {
4645 4643 sp_type = Fmk(MAX_SKIP);
4646 4644 }
4647 4645 } else {
4648 4646 sp_type = Fmk(1);
4649 4647 }
4650 4648
4651 4649 for (;;) {
4652 4650 result = st_cmd(un, SCMD_SPACE, sp_type, SYNC_CMD);
4653 4651
4654 4652 if (result == 0) {
4655 4653 COPY_POS(&savepos, &un->un_pos);
4656 4654 }
4657 4655
4658 4656 if (sp_type == SPACE(SP_EOD, 0)) {
4659 4657 if (result != 0) {
4660 4658 sp_type = Fmk(MAX_SKIP);
4661 4659 continue;
4662 4660 }
4663 4661
4664 4662 ST_DEBUG6(ST_DEVINFO, st_label, SCSI_DEBUG,
4665 4663 "st_find_eod: 0x%"PRIx64"\n",
4666 4664 savepos.lgclblkno);
4667 4665 /*
4668 4666 * What we return will become the current file position.
4669 4667 * After completing the space command with the position
4670 4668 * mode that is not invalid a read position command will
4671 4669 * be automaticly issued. If the drive support the long
4672 4670 * read position format a valid file position can be
4673 4671 * returned.
4674 4672 */
4675 4673 return (un->un_pos.fileno);
4676 4674 }
4677 4675
4678 4676 if (result != 0) {
4679 4677 break;
4680 4678 }
4681 4679
4682 4680 ST_DEBUG6(ST_DEVINFO, st_label, SCSI_DEBUG,
4683 4681 "count=%"PRIx64", eof=%x, status=%x\n",
4684 4682 SPACE_CNT(sp_type), un->un_pos.eof, un->un_status);
4685 4683
4686 4684 /*
4687 4685 * If we're not EOM smart, space a record
4688 4686 * to see whether we're now in the slot between
4689 4687 * the two sequential filemarks that logical
4690 4688 * EOM consists of (REEL) or hit nowhere land
4691 4689 * (8mm).
4692 4690 */
4693 4691 if (sp_type == Fmk(1)) {
4694 4692 /*
4695 4693 * no fast skipping, check a record
4696 4694 */
4697 4695 if (st_cmd(un, SCMD_SPACE, Blk((1)), SYNC_CMD)) {
4698 4696 break;
4699 4697 }
4700 4698 if ((un->un_pos.eof >= ST_EOF_PENDING) &&
4701 4699 (un->un_dp->options & ST_REEL)) {
4702 4700 un->un_status = KEY_BLANK_CHECK;
4703 4701 un->un_pos.fileno++;
4704 4702 un->un_pos.blkno = 0;
4705 4703 break;
4706 4704 }
4707 4705 if (IN_EOF(un->un_pos)) {
4708 4706 un->un_pos.eof = ST_NO_EOF;
4709 4707 un->un_pos.fileno++;
4710 4708 un->un_pos.blkno = 0;
4711 4709 }
4712 4710 if (un->un_pos.eof > ST_EOF) {
4713 4711 break;
4714 4712 }
4715 4713 } else {
4716 4714 if (un->un_pos.eof > ST_EOF) {
4717 4715 break;
4718 4716 }
4719 4717 }
4720 4718 }
4721 4719
4722 4720 if (un->un_dp->options & ST_KNOWS_EOD) {
4723 4721 COPY_POS(&savepos, &un->un_pos);
4724 4722 }
4725 4723
4726 4724 ASSERT(mutex_owned(ST_MUTEX));
4727 4725
4728 4726 ST_DEBUG6(ST_DEVINFO, st_label, SCSI_DEBUG,
4729 4727 "st_find_eod: %x\n", savepos.fileno);
4730 4728 return (savepos.fileno);
4731 4729 }
4732 4730
4733 4731
4734 4732 /*
4735 4733 * this routine is frequently used in ioctls below;
4736 4734 * it determines whether we know the density and if not will
4737 4735 * determine it
4738 4736 * if we have written the tape before, one or more filemarks are written
4739 4737 *
4740 4738 * depending on the stepflag, the head is repositioned to where it was before
4741 4739 * the filemarks were written in order not to confuse step counts
4742 4740 */
4743 4741 #define STEPBACK 0
4744 4742 #define NO_STEPBACK 1
4745 4743
4746 4744 static int
4747 4745 st_check_density_or_wfm(dev_t dev, int wfm, int mode, int stepflag)
4748 4746 {
4749 4747
4750 4748 GET_SOFT_STATE(dev);
4751 4749
4752 4750 ST_FUNC(ST_DEVINFO, st_check_density_or_wfm);
4753 4751
4754 4752 ST_DEBUG3(ST_DEVINFO, st_label, SCSI_DEBUG,
4755 4753 "st_check_density_or_wfm(dev= 0x%lx, wfm= %d, mode= %d, stpflg= %d)"
4756 4754 "\n", dev, wfm, mode, stepflag);
4757 4755
4758 4756 ASSERT(mutex_owned(ST_MUTEX));
4759 4757
4760 4758 /*
4761 4759 * If we don't yet know the density of the tape we have inserted,
4762 4760 * we have to either unconditionally set it (if we're 'writing'),
4763 4761 * or we have to determine it. As side effects, check for any
4764 4762 * write-protect errors, and for the need to put out any file-marks
4765 4763 * before positioning a tape.
4766 4764 *
4767 4765 * If we are going to be spacing forward, and we haven't determined
4768 4766 * the tape density yet, we have to do so now...
4769 4767 */
4770 4768 if (un->un_state == ST_STATE_OPEN_PENDING_IO) {
4771 4769 if (st_determine_density(un, mode)) {
4772 4770 ST_DEBUG2(ST_DEVINFO, st_label, SCSI_DEBUG,
4773 4771 "check_density_or_wfm : EIO can't determine "
4774 4772 "density\n");
4775 4773 un->un_errno = EIO;
4776 4774 return (EIO);
4777 4775 }
4778 4776 /*
4779 4777 * Presumably we are at BOT. If we attempt to write, it will
4780 4778 * either work okay, or bomb. We don't do a st_test_append
4781 4779 * unless we're past BOT.
4782 4780 */
4783 4781 un->un_laststate = un->un_state;
4784 4782 un->un_state = ST_STATE_OPEN;
4785 4783
4786 4784 } else if (un->un_pos.pmode != invalid && un->un_fmneeded > 0 &&
4787 4785 ((un->un_lastop == ST_OP_WEOF && wfm) ||
4788 4786 (un->un_lastop == ST_OP_WRITE && wfm))) {
4789 4787
4790 4788 tapepos_t spos;
4791 4789
4792 4790 COPY_POS(&spos, &un->un_pos);
4793 4791
4794 4792 /*
4795 4793 * We need to write one or two filemarks.
4796 4794 * In the case of the HP, we need to
4797 4795 * position the head between the two
4798 4796 * marks.
4799 4797 */
4800 4798 if ((un->un_fmneeded > 0) || (un->un_lastop == ST_OP_WEOF)) {
4801 4799 wfm = un->un_fmneeded;
4802 4800 un->un_fmneeded = 0;
4803 4801 }
4804 4802
4805 4803 if (st_write_fm(dev, wfm)) {
4806 4804 un->un_pos.pmode = invalid;
4807 4805 un->un_density_known = 0;
4808 4806 ST_DEBUG2(ST_DEVINFO, st_label, SCSI_DEBUG,
4809 4807 "check_density_or_wfm : EIO can't write fm\n");
4810 4808 un->un_errno = EIO;
4811 4809 return (EIO);
4812 4810 }
4813 4811
4814 4812 if (stepflag == STEPBACK) {
4815 4813 if (st_cmd(un, SCMD_SPACE, Fmk(-wfm), SYNC_CMD)) {
4816 4814 ST_DEBUG2(ST_DEVINFO, st_label, SCSI_DEBUG,
4817 4815 "check_density_or_wfm : EIO can't space "
4818 4816 "(-wfm)\n");
4819 4817 un->un_errno = EIO;
4820 4818 return (EIO);
4821 4819 }
4822 4820 COPY_POS(&un->un_pos, &spos);
4823 4821 }
4824 4822 }
4825 4823
4826 4824 /*
4827 4825 * Whatever we do at this point clears the state of the eof flag.
4828 4826 */
4829 4827
4830 4828 un->un_pos.eof = ST_NO_EOF;
4831 4829
4832 4830 /*
4833 4831 * If writing, let's check that we're positioned correctly
4834 4832 * at the end of tape before issuing the next write.
4835 4833 */
4836 4834 if (un->un_read_only == RDWR) {
4837 4835 un->un_test_append = 1;
4838 4836 }
4839 4837
4840 4838 ASSERT(mutex_owned(ST_MUTEX));
4841 4839 return (0);
4842 4840 }
4843 4841
4844 4842
4845 4843 /*
4846 4844 * Wait for all outstaning I/O's to complete
4847 4845 *
4848 4846 * we wait on both ncmds and the wait queue for times when we are flushing
4849 4847 * after persistent errors are flagged, which is when ncmds can be 0, and the
4850 4848 * queue can still have I/O's. This way we preserve order of biodone's.
4851 4849 */
4852 4850 static void
4853 4851 st_wait_for_io(struct scsi_tape *un)
4854 4852 {
4855 4853 ST_FUNC(ST_DEVINFO, st_wait_for_io);
4856 4854 ASSERT(mutex_owned(ST_MUTEX));
4857 4855 while ((un->un_ncmds) || (un->un_quef) || (un->un_runqf)) {
4858 4856 cv_wait(&un->un_queue_cv, ST_MUTEX);
4859 4857 }
4860 4858 }
4861 4859
4862 4860 /*
4863 4861 * This routine implements the ioctl calls. It is called
4864 4862 * from the device switch at normal priority.
4865 4863 */
4866 4864 /*ARGSUSED*/
4867 4865 static int
4868 4866 st_ioctl(dev_t dev, int cmd, intptr_t arg, int flag, cred_t *cred_p,
4869 4867 int *rval_p)
4870 4868 {
4871 4869 int tmp, rval = 0;
4872 4870
4873 4871 GET_SOFT_STATE(dev);
4874 4872
4875 4873 ST_ENTR(ST_DEVINFO, st_ioctl);
4876 4874
4877 4875 mutex_enter(ST_MUTEX);
4878 4876
4879 4877 ASSERT(un->un_recov_buf_busy == 0);
4880 4878
4881 4879 ST_DEBUG3(ST_DEVINFO, st_label, SCSI_DEBUG,
4882 4880 "st_ioctl(): fileno=%x, blkno=%x, eof=%x, state = %d, "
4883 4881 "pe_flag = %d\n",
4884 4882 un->un_pos.fileno, un->un_pos.blkno, un->un_pos.eof, un->un_state,
4885 4883 un->un_persistence && un->un_persist_errors);
4886 4884
4887 4885 /*
4888 4886 * We don't want to block on these, so let them through
4889 4887 * and we don't care about setting driver states here.
4890 4888 */
4891 4889 if ((cmd == MTIOCGETDRIVETYPE) ||
4892 4890 (cmd == MTIOCGUARANTEEDORDER) ||
4893 4891 (cmd == MTIOCPERSISTENTSTATUS)) {
4894 4892 goto check_commands;
4895 4893 }
4896 4894
4897 4895 /*
4898 4896 * We clear error entry stack except command
4899 4897 * MTIOCGETERROR and MTIOCGET
4900 4898 */
4901 4899 if ((cmd != MTIOCGETERROR) &&
4902 4900 (cmd != MTIOCGET)) {
4903 4901 st_empty_error_stack(un);
4904 4902 }
4905 4903
4906 4904 /*
4907 4905 * wait for all outstanding commands to complete, or be dequeued.
4908 4906 * And because ioctl's are synchronous commands, any return value
4909 4907 * after this, will be in order
4910 4908 */
4911 4909 st_wait_for_io(un);
4912 4910
4913 4911 /*
4914 4912 * allow only a through clear errors and persistent status, and
4915 4913 * status
4916 4914 */
4917 4915 if (un->un_persistence && un->un_persist_errors) {
4918 4916 if ((cmd == MTIOCLRERR) ||
4919 4917 (cmd == MTIOCPERSISTENT) ||
4920 4918 (cmd == MTIOCGET)) {
4921 4919 goto check_commands;
4922 4920 } else {
4923 4921 rval = un->un_errno;
4924 4922 goto exit;
4925 4923 }
4926 4924 }
4927 4925
4928 4926 ASSERT(un->un_throttle != 0);
4929 4927 un->un_throttle = 1; /* > 1 will never happen here */
4930 4928 un->un_errno = 0; /* start clean from here */
4931 4929
4932 4930 /*
4933 4931 * first and foremost, handle any ST_EOT_PENDING cases.
4934 4932 * That is, if a logical eot is pending notice, notice it.
4935 4933 */
4936 4934 if (un->un_pos.eof == ST_EOT_PENDING) {
4937 4935 int resid = un->un_err_resid;
4938 4936 uchar_t status = un->un_status;
4939 4937 uchar_t lastop = un->un_lastop;
4940 4938
4941 4939 if (st_cmd(un, SCMD_SPACE, Fmk(-1), SYNC_CMD)) {
4942 4940 ST_DEBUG2(ST_DEVINFO, st_label, SCSI_DEBUG,
4943 4941 "stioctl : EIO can't space fmk(-1)\n");
4944 4942 rval = EIO;
4945 4943 goto exit;
4946 4944 }
4947 4945 un->un_lastop = lastop; /* restore last operation */
4948 4946 if (status == SUN_KEY_EOF) {
4949 4947 un->un_status = SUN_KEY_EOT;
4950 4948 } else {
4951 4949 un->un_status = status;
4952 4950 }
4953 4951 un->un_err_resid = resid;
4954 4952 /* fix up block number */
4955 4953 un->un_err_pos.blkno = un->un_pos.blkno = 0;
4956 4954 /* now we're at logical eot */
4957 4955 un->un_pos.eof = ST_EOT;
4958 4956 }
4959 4957
4960 4958 /*
4961 4959 * now, handle the rest of the situations
4962 4960 */
4963 4961 check_commands:
4964 4962 switch (cmd) {
4965 4963 case MTIOCGET:
4966 4964 {
4967 4965 #ifdef _MULTI_DATAMODEL
4968 4966 /*
4969 4967 * For use when a 32 bit app makes a call into a
4970 4968 * 64 bit ioctl
4971 4969 */
4972 4970 struct mtget32 mtg_local32;
4973 4971 struct mtget32 *mtget_32 = &mtg_local32;
4974 4972 #endif /* _MULTI_DATAMODEL */
4975 4973
4976 4974 /* Get tape status */
4977 4975 struct mtget mtg_local;
4978 4976 struct mtget *mtget = &mtg_local;
4979 4977 ST_DEBUG4(ST_DEVINFO, st_label, SCSI_DEBUG,
4980 4978 "st_ioctl: MTIOCGET\n");
4981 4979
4982 4980 bzero((caddr_t)mtget, sizeof (struct mtget));
4983 4981 mtget->mt_erreg = un->un_status;
4984 4982 mtget->mt_resid = un->un_err_resid;
4985 4983 mtget->mt_dsreg = un->un_retry_ct;
4986 4984 if (un->un_err_pos.pmode == legacy) {
4987 4985 mtget->mt_fileno = un->un_err_pos.fileno;
4988 4986 } else {
4989 4987 mtget->mt_fileno = -1;
4990 4988 }
4991 4989 /*
4992 4990 * If the value is positive fine.
4993 4991 * If its negative we need to return a value based on the
4994 4992 * old way if counting backwards from INF (1,000,000,000).
4995 4993 */
4996 4994 if (un->un_err_pos.blkno >= 0) {
4997 4995 mtget->mt_blkno = un->un_err_pos.blkno;
4998 4996 } else {
4999 4997 mtget->mt_blkno = INF + 1 - (-un->un_err_pos.blkno);
5000 4998 }
5001 4999 mtget->mt_type = un->un_dp->type;
5002 5000 mtget->mt_flags = MTF_SCSI | MTF_ASF;
5003 5001 if (un->un_read_pos_type != NO_POS) {
5004 5002 mtget->mt_flags |= MTF_LOGICAL_BLOCK;
5005 5003 }
5006 5004 if (un->un_dp->options & ST_REEL) {
5007 5005 mtget->mt_flags |= MTF_REEL;
5008 5006 mtget->mt_bf = 20;
5009 5007 } else { /* 1/4" cartridges */
5010 5008 switch (mtget->mt_type) {
5011 5009 /* Emulex cartridge tape */
5012 5010 case MT_ISMT02:
5013 5011 mtget->mt_bf = 40;
5014 5012 break;
5015 5013 default:
5016 5014 mtget->mt_bf = 126;
5017 5015 break;
5018 5016 }
5019 5017 }
5020 5018
5021 5019 /*
5022 5020 * If large transfers are allowed and drive options
5023 5021 * has no record size limit set. Calculate blocking
5024 5022 * factor from the lesser of maxbsize and maxdma.
5025 5023 */
5026 5024 if ((un->un_allow_large_xfer) &&
5027 5025 (un->un_dp->options & ST_NO_RECSIZE_LIMIT)) {
5028 5026 mtget->mt_bf = min(un->un_maxbsize,
5029 5027 un->un_maxdma) / SECSIZE;
5030 5028 }
5031 5029
5032 5030 if (un->un_read_only == WORM ||
5033 5031 un->un_read_only == RDWORM) {
5034 5032 mtget->mt_flags |= MTF_WORM_MEDIA;
5035 5033 }
5036 5034
5037 5035 /*
5038 5036 * In persistent error mode sending a non-queued can hang
5039 5037 * because this ioctl gets to be run without turning off
5040 5038 * persistense. Fake the answer based on previous info.
5041 5039 */
5042 5040 if (un->un_persistence) {
5043 5041 rval = 0;
5044 5042 } else {
5045 5043 rval = st_check_clean_bit(un);
5046 5044 }
5047 5045 if (rval == 0) {
5048 5046 /*
5049 5047 * If zero is returned or in persistent mode,
5050 5048 * use the old data.
5051 5049 */
5052 5050 if ((un->un_HeadClean & (TAPE_ALERT_SUPPORTED |
5053 5051 TAPE_SEQUENTIAL_SUPPORTED|TAPE_ALERT_NOT_SUPPORTED))
5054 5052 != TAPE_ALERT_NOT_SUPPORTED) {
5055 5053 mtget->mt_flags |= MTF_TAPE_CLN_SUPPORTED;
5056 5054 }
5057 5055 if (un->un_HeadClean & (TAPE_PREVIOUSLY_DIRTY |
5058 5056 TAPE_ALERT_STILL_DIRTY)) {
5059 5057 mtget->mt_flags |= MTF_TAPE_HEAD_DIRTY;
5060 5058 }
5061 5059 } else {
5062 5060 mtget->mt_flags |= (ushort_t)rval;
5063 5061 rval = 0;
5064 5062 }
5065 5063
5066 5064 un->un_status = 0; /* Reset status */
5067 5065 un->un_err_resid = 0;
5068 5066 tmp = sizeof (struct mtget);
5069 5067
5070 5068 #ifdef _MULTI_DATAMODEL
5071 5069
5072 5070 switch (ddi_model_convert_from(flag & FMODELS)) {
5073 5071 case DDI_MODEL_ILP32:
5074 5072 /*
5075 5073 * Convert 64 bit back to 32 bit before doing
5076 5074 * copyout. This is what the ILP32 app expects.
5077 5075 */
5078 5076 mtget_32->mt_erreg = mtget->mt_erreg;
5079 5077 mtget_32->mt_resid = mtget->mt_resid;
5080 5078 mtget_32->mt_dsreg = mtget->mt_dsreg;
5081 5079 mtget_32->mt_fileno = (daddr32_t)mtget->mt_fileno;
5082 5080 mtget_32->mt_blkno = (daddr32_t)mtget->mt_blkno;
5083 5081 mtget_32->mt_type = mtget->mt_type;
5084 5082 mtget_32->mt_flags = mtget->mt_flags;
5085 5083 mtget_32->mt_bf = mtget->mt_bf;
5086 5084
5087 5085 if (ddi_copyout(mtget_32, (void *)arg,
5088 5086 sizeof (struct mtget32), flag)) {
5089 5087 rval = EFAULT;
5090 5088 }
5091 5089 break;
5092 5090
5093 5091 case DDI_MODEL_NONE:
5094 5092 if (ddi_copyout(mtget, (void *)arg, tmp, flag)) {
5095 5093 rval = EFAULT;
5096 5094 }
5097 5095 break;
5098 5096 }
5099 5097 #else /* ! _MULTI_DATAMODE */
5100 5098 if (ddi_copyout(mtget, (void *)arg, tmp, flag)) {
5101 5099 rval = EFAULT;
5102 5100 }
5103 5101 #endif /* _MULTI_DATAMODE */
5104 5102
5105 5103 break;
5106 5104 }
5107 5105 case MTIOCGETERROR:
5108 5106 /*
5109 5107 * get error entry from error stack
5110 5108 */
5111 5109 ST_DEBUG4(ST_DEVINFO, st_label, SCSI_DEBUG,
5112 5110 "st_ioctl: MTIOCGETERROR\n");
5113 5111
5114 5112 rval = st_get_error_entry(un, arg, flag);
5115 5113
5116 5114 break;
5117 5115
5118 5116 case MTIOCSTATE:
5119 5117 {
5120 5118 /*
5121 5119 * return when media presence matches state
5122 5120 */
5123 5121 enum mtio_state state;
5124 5122
5125 5123 ST_DEBUG4(ST_DEVINFO, st_label, SCSI_DEBUG,
5126 5124 "st_ioctl: MTIOCSTATE\n");
5127 5125
5128 5126 if (ddi_copyin((void *)arg, &state, sizeof (int), flag))
5129 5127 rval = EFAULT;
5130 5128
5131 5129 mutex_exit(ST_MUTEX);
5132 5130
5133 5131 rval = st_check_media(dev, state);
5134 5132
5135 5133 mutex_enter(ST_MUTEX);
5136 5134
5137 5135 if (rval != 0) {
5138 5136 break;
5139 5137 }
5140 5138
5141 5139 if (ddi_copyout(&un->un_mediastate, (void *)arg,
5142 5140 sizeof (int), flag))
5143 5141 rval = EFAULT;
5144 5142 break;
5145 5143
5146 5144 }
5147 5145
5148 5146 case MTIOCGETDRIVETYPE:
5149 5147 {
5150 5148 #ifdef _MULTI_DATAMODEL
5151 5149 /*
5152 5150 * For use when a 32 bit app makes a call into a
5153 5151 * 64 bit ioctl
5154 5152 */
5155 5153 struct mtdrivetype_request32 mtdtrq32;
5156 5154 #endif /* _MULTI_DATAMODEL */
5157 5155
5158 5156 /*
5159 5157 * return mtdrivetype
5160 5158 */
5161 5159 struct mtdrivetype_request mtdtrq;
5162 5160 struct mtdrivetype mtdrtyp;
5163 5161 struct mtdrivetype *mtdt = &mtdrtyp;
5164 5162 struct st_drivetype *stdt = un->un_dp;
5165 5163
5166 5164 ST_DEBUG4(ST_DEVINFO, st_label, SCSI_DEBUG,
5167 5165 "st_ioctl: MTIOCGETDRIVETYPE\n");
5168 5166
5169 5167 #ifdef _MULTI_DATAMODEL
5170 5168 switch (ddi_model_convert_from(flag & FMODELS)) {
5171 5169 case DDI_MODEL_ILP32:
5172 5170 {
5173 5171 if (ddi_copyin((void *)arg, &mtdtrq32,
5174 5172 sizeof (struct mtdrivetype_request32), flag)) {
5175 5173 rval = EFAULT;
5176 5174 break;
5177 5175 }
5178 5176 mtdtrq.size = mtdtrq32.size;
5179 5177 mtdtrq.mtdtp =
5180 5178 (struct mtdrivetype *)(uintptr_t)mtdtrq32.mtdtp;
5181 5179 ST_DEBUG4(ST_DEVINFO, st_label, SCSI_DEBUG,
5182 5180 "st_ioctl: size 0x%x\n", mtdtrq.size);
5183 5181 break;
5184 5182 }
5185 5183 case DDI_MODEL_NONE:
5186 5184 if (ddi_copyin((void *)arg, &mtdtrq,
5187 5185 sizeof (struct mtdrivetype_request), flag)) {
5188 5186 rval = EFAULT;
5189 5187 break;
5190 5188 }
5191 5189 break;
5192 5190 }
5193 5191
5194 5192 #else /* ! _MULTI_DATAMODEL */
5195 5193 if (ddi_copyin((void *)arg, &mtdtrq,
5196 5194 sizeof (struct mtdrivetype_request), flag)) {
5197 5195 rval = EFAULT;
5198 5196 break;
5199 5197 }
5200 5198 #endif /* _MULTI_DATAMODEL */
5201 5199
5202 5200 /*
5203 5201 * if requested size is < 0 then return
5204 5202 * error.
5205 5203 */
5206 5204 if (mtdtrq.size < 0) {
5207 5205 rval = EINVAL;
5208 5206 break;
5209 5207 }
5210 5208 bzero(mtdt, sizeof (struct mtdrivetype));
5211 5209 (void) strncpy(mtdt->name, stdt->name, ST_NAMESIZE);
5212 5210 (void) strncpy(mtdt->vid, stdt->vid, VIDPIDLEN - 1);
5213 5211 mtdt->type = stdt->type;
5214 5212 mtdt->bsize = stdt->bsize;
5215 5213 mtdt->options = stdt->options;
5216 5214 mtdt->max_rretries = stdt->max_rretries;
5217 5215 mtdt->max_wretries = stdt->max_wretries;
5218 5216 for (tmp = 0; tmp < NDENSITIES; tmp++) {
5219 5217 mtdt->densities[tmp] = stdt->densities[tmp];
5220 5218 }
5221 5219 mtdt->default_density = stdt->default_density;
5222 5220 /*
5223 5221 * Speed hasn't been used since the hayday of reel tape.
5224 5222 * For all drives not setting the option ST_KNOWS_MEDIA
5225 5223 * the speed member renamed to mediatype are zeros.
5226 5224 * Those drives that have ST_KNOWS_MEDIA set use the
5227 5225 * new mediatype member which is used to figure the
5228 5226 * type of media loaded.
5229 5227 *
5230 5228 * So as to not break applications speed in the
5231 5229 * mtdrivetype structure is not renamed.
5232 5230 */
5233 5231 for (tmp = 0; tmp < NDENSITIES; tmp++) {
5234 5232 mtdt->speeds[tmp] = stdt->mediatype[tmp];
5235 5233 }
5236 5234 mtdt->non_motion_timeout = stdt->non_motion_timeout;
5237 5235 mtdt->io_timeout = stdt->io_timeout;
5238 5236 mtdt->rewind_timeout = stdt->rewind_timeout;
5239 5237 mtdt->space_timeout = stdt->space_timeout;
5240 5238 mtdt->load_timeout = stdt->load_timeout;
5241 5239 mtdt->unload_timeout = stdt->unload_timeout;
5242 5240 mtdt->erase_timeout = stdt->erase_timeout;
5243 5241
5244 5242 /*
5245 5243 * Limit the maximum length of the result to
5246 5244 * sizeof (struct mtdrivetype).
5247 5245 */
5248 5246 tmp = sizeof (struct mtdrivetype);
5249 5247 if (mtdtrq.size < tmp)
5250 5248 tmp = mtdtrq.size;
5251 5249 if (ddi_copyout(mtdt, mtdtrq.mtdtp, tmp, flag)) {
5252 5250 rval = EFAULT;
5253 5251 }
5254 5252 break;
5255 5253 }
5256 5254 case MTIOCPERSISTENT:
5257 5255
5258 5256 if (ddi_copyin((void *)arg, &tmp, sizeof (tmp), flag)) {
5259 5257 rval = EFAULT;
5260 5258 break;
5261 5259 }
5262 5260
5263 5261 if (tmp) {
5264 5262 st_turn_pe_on(un);
5265 5263 } else {
5266 5264 st_turn_pe_off(un);
5267 5265 }
5268 5266
5269 5267 ST_DEBUG4(ST_DEVINFO, st_label, SCSI_DEBUG,
5270 5268 "st_ioctl: MTIOCPERSISTENT : persistence = %d\n",
5271 5269 un->un_persistence);
5272 5270
5273 5271 break;
5274 5272
5275 5273 case MTIOCPERSISTENTSTATUS:
5276 5274 tmp = (int)un->un_persistence;
5277 5275
5278 5276 if (ddi_copyout(&tmp, (void *)arg, sizeof (tmp), flag)) {
5279 5277 rval = EFAULT;
5280 5278 }
5281 5279 ST_DEBUG4(ST_DEVINFO, st_label, SCSI_DEBUG,
5282 5280 "st_ioctl: MTIOCPERSISTENTSTATUS:persistence = %d\n",
5283 5281 un->un_persistence);
5284 5282
5285 5283 break;
5286 5284
5287 5285 case MTIOCLRERR:
5288 5286 {
5289 5287 /* clear persistent errors */
5290 5288
5291 5289 ST_DEBUG4(ST_DEVINFO, st_label, SCSI_DEBUG,
5292 5290 "st_ioctl: MTIOCLRERR\n");
5293 5291
5294 5292 st_clear_pe(un);
5295 5293
5296 5294 break;
5297 5295 }
5298 5296
5299 5297 case MTIOCGUARANTEEDORDER:
5300 5298 {
5301 5299 /*
5302 5300 * this is just a holder to make a valid ioctl and
5303 5301 * it won't be in any earlier release
5304 5302 */
5305 5303 ST_DEBUG4(ST_DEVINFO, st_label, SCSI_DEBUG,
5306 5304 "st_ioctl: MTIOCGUARANTEEDORDER\n");
5307 5305
5308 5306 break;
5309 5307 }
5310 5308
5311 5309 case MTIOCRESERVE:
5312 5310 {
5313 5311 ST_DEBUG3(ST_DEVINFO, st_label, SCSI_DEBUG,
5314 5312 "st_ioctl: MTIOCRESERVE\n");
5315 5313
5316 5314 /*
5317 5315 * Check if Reserve/Release is supported.
5318 5316 */
5319 5317 if (un->un_dp->options & ST_NO_RESERVE_RELEASE) {
5320 5318 rval = ENOTTY;
5321 5319 break;
5322 5320 }
5323 5321
5324 5322 rval = st_reserve_release(un, ST_RESERVE, st_uscsi_cmd);
5325 5323
5326 5324 if (rval == 0) {
5327 5325 un->un_rsvd_status |= ST_PRESERVE_RESERVE;
5328 5326 }
5329 5327 break;
5330 5328 }
5331 5329
5332 5330 case MTIOCRELEASE:
5333 5331 {
5334 5332 ST_DEBUG3(ST_DEVINFO, st_label, SCSI_DEBUG,
5335 5333 "st_ioctl: MTIOCRELEASE\n");
5336 5334
5337 5335 /*
5338 5336 * Check if Reserve/Release is supported.
5339 5337 */
5340 5338 if (un->un_dp->options & ST_NO_RESERVE_RELEASE) {
5341 5339 rval = ENOTTY;
5342 5340 break;
5343 5341 }
5344 5342
5345 5343 /*
5346 5344 * Used to just clear ST_PRESERVE_RESERVE which
5347 5345 * made the reservation release at next close.
5348 5346 * As the user may have opened and then done a
5349 5347 * persistant reservation we now need to drop
5350 5348 * the reservation without closing if the user
5351 5349 * attempts to do this.
5352 5350 */
5353 5351 rval = st_reserve_release(un, ST_RELEASE, st_uscsi_cmd);
5354 5352
5355 5353 un->un_rsvd_status &= ~ST_PRESERVE_RESERVE;
5356 5354
5357 5355 break;
5358 5356 }
5359 5357
5360 5358 case MTIOCFORCERESERVE:
5361 5359 {
5362 5360 ST_DEBUG3(ST_DEVINFO, st_label, SCSI_DEBUG,
5363 5361 "st_ioctl: MTIOCFORCERESERVE\n");
5364 5362
5365 5363 /*
5366 5364 * Check if Reserve/Release is supported.
5367 5365 */
5368 5366 if (un->un_dp->options & ST_NO_RESERVE_RELEASE) {
5369 5367 rval = ENOTTY;
5370 5368 break;
5371 5369 }
5372 5370 /*
5373 5371 * allow only super user to run this.
5374 5372 */
5375 5373 if (drv_priv(cred_p) != 0) {
5376 5374 rval = EPERM;
5377 5375 break;
5378 5376 }
5379 5377 /*
5380 5378 * Throw away reserve,
5381 5379 * not using test-unit-ready
5382 5380 * since reserve can succeed without tape being
5383 5381 * present in the drive.
5384 5382 */
5385 5383 (void) st_reserve_release(un, ST_RESERVE, st_uscsi_cmd);
5386 5384
5387 5385 rval = st_take_ownership(un, st_uscsi_cmd);
5388 5386
5389 5387 break;
5390 5388 }
5391 5389
5392 5390 case USCSICMD:
5393 5391 {
5394 5392 cred_t *cr;
5395 5393
5396 5394 ST_DEBUG4(ST_DEVINFO, st_label, SCSI_DEBUG,
5397 5395 "st_ioctl: USCSICMD\n");
5398 5396
5399 5397 cr = ddi_get_cred();
5400 5398 if ((drv_priv(cred_p) != 0) && (drv_priv(cr) != 0)) {
5401 5399 rval = EPERM;
5402 5400 } else {
5403 5401 rval = st_uscsi_cmd(un, (struct uscsi_cmd *)arg, flag);
5404 5402 }
5405 5403 break;
5406 5404 }
5407 5405 case MTIOCTOP:
5408 5406 ST_DEBUG4(ST_DEVINFO, st_label, SCSI_DEBUG,
5409 5407 "st_ioctl: MTIOCTOP\n");
5410 5408 rval = st_mtioctop(un, arg, flag);
5411 5409 break;
5412 5410
5413 5411 case MTIOCLTOP:
5414 5412 ST_DEBUG4(ST_DEVINFO, st_label, SCSI_DEBUG,
5415 5413 "st_ioctl: MTIOLCTOP\n");
5416 5414 rval = st_mtiocltop(un, arg, flag);
5417 5415 break;
5418 5416
5419 5417 case MTIOCREADIGNOREILI:
5420 5418 {
5421 5419 int set_ili;
5422 5420
5423 5421 if (ddi_copyin((void *)arg, &set_ili,
5424 5422 sizeof (set_ili), flag)) {
5425 5423 rval = EFAULT;
5426 5424 break;
5427 5425 }
5428 5426
5429 5427 if (un->un_bsize) {
5430 5428 rval = ENOTTY;
5431 5429 break;
5432 5430 }
5433 5431
5434 5432 switch (set_ili) {
5435 5433 case 0:
5436 5434 un->un_dp->options &= ~ST_READ_IGNORE_ILI;
5437 5435 break;
5438 5436
5439 5437 case 1:
5440 5438 un->un_dp->options |= ST_READ_IGNORE_ILI;
5441 5439 break;
5442 5440
5443 5441 default:
5444 5442 rval = EINVAL;
5445 5443 break;
5446 5444 }
5447 5445 break;
5448 5446 }
5449 5447
5450 5448 case MTIOCREADIGNOREEOFS:
5451 5449 {
5452 5450 int ignore_eof;
5453 5451
5454 5452 if (ddi_copyin((void *)arg, &ignore_eof,
5455 5453 sizeof (ignore_eof), flag)) {
5456 5454 rval = EFAULT;
5457 5455 break;
5458 5456 }
5459 5457
5460 5458 if (!(un->un_dp->options & ST_REEL)) {
5461 5459 rval = ENOTTY;
5462 5460 break;
5463 5461 }
5464 5462
5465 5463 switch (ignore_eof) {
5466 5464 case 0:
5467 5465 un->un_dp->options &= ~ST_READ_IGNORE_EOFS;
5468 5466 break;
5469 5467
5470 5468 case 1:
5471 5469 un->un_dp->options |= ST_READ_IGNORE_EOFS;
5472 5470 break;
5473 5471
5474 5472 default:
5475 5473 rval = EINVAL;
5476 5474 break;
5477 5475 }
5478 5476 break;
5479 5477 }
5480 5478
5481 5479 case MTIOCSHORTFMK:
5482 5480 {
5483 5481 int short_fmk;
5484 5482
5485 5483 if (ddi_copyin((void *)arg, &short_fmk,
5486 5484 sizeof (short_fmk), flag)) {
5487 5485 rval = EFAULT;
5488 5486 break;
5489 5487 }
5490 5488
5491 5489 switch (un->un_dp->type) {
5492 5490 case ST_TYPE_EXB8500:
5493 5491 case ST_TYPE_EXABYTE:
5494 5492 if (!short_fmk) {
5495 5493 un->un_dp->options &= ~ST_SHORT_FILEMARKS;
5496 5494 } else if (short_fmk == 1) {
5497 5495 un->un_dp->options |= ST_SHORT_FILEMARKS;
5498 5496 } else {
5499 5497 rval = EINVAL;
5500 5498 }
5501 5499 break;
5502 5500
5503 5501 default:
5504 5502 rval = ENOTTY;
5505 5503 break;
5506 5504 }
5507 5505 break;
5508 5506 }
5509 5507
5510 5508 case MTIOCGETPOS:
5511 5509 rval = st_update_block_pos(un, st_cmd, 0);
5512 5510 if (rval == 0) {
5513 5511 if (ddi_copyout((void *)&un->un_pos, (void *)arg,
5514 5512 sizeof (tapepos_t), flag)) {
5515 5513 scsi_log(ST_DEVINFO, st_label, SCSI_DEBUG,
5516 5514 "MTIOCGETPOS copy out failed\n");
5517 5515 rval = EFAULT;
5518 5516 }
5519 5517 }
5520 5518 break;
5521 5519
5522 5520 case MTIOCRESTPOS:
5523 5521 {
5524 5522 tapepos_t dest;
5525 5523
5526 5524 if (ddi_copyin((void *)arg, &dest, sizeof (tapepos_t),
5527 5525 flag) != 0) {
5528 5526 scsi_log(ST_DEVINFO, st_label, SCSI_DEBUG,
5529 5527 "MTIOCRESTPOS copy in failed\n");
5530 5528 rval = EFAULT;
5531 5529 break;
5532 5530 }
5533 5531 rval = st_validate_tapemarks(un, st_uscsi_cmd, &dest);
5534 5532 if (rval != 0) {
5535 5533 rval = EIO;
5536 5534 }
5537 5535 break;
5538 5536 }
5539 5537 default:
5540 5538 ST_DEBUG4(ST_DEVINFO, st_label, SCSI_DEBUG,
5541 5539 "st_ioctl: unknown ioctl\n");
5542 5540 rval = ENOTTY;
5543 5541 }
5544 5542
5545 5543 exit:
5546 5544 if (!(un->un_persistence && un->un_persist_errors)) {
5547 5545 un->un_errno = rval;
5548 5546 }
5549 5547
5550 5548 mutex_exit(ST_MUTEX);
5551 5549
5552 5550 return (rval);
5553 5551 }
5554 5552
5555 5553
5556 5554 /*
5557 5555 * do some MTIOCTOP tape operations
5558 5556 */
5559 5557 static int
5560 5558 st_mtioctop(struct scsi_tape *un, intptr_t arg, int flag)
5561 5559 {
5562 5560 #ifdef _MULTI_DATAMODEL
5563 5561 /*
5564 5562 * For use when a 32 bit app makes a call into a
5565 5563 * 64 bit ioctl
5566 5564 */
5567 5565 struct mtop32 mtop_32_for_64;
5568 5566 #endif /* _MULTI_DATAMODEL */
5569 5567 struct mtop passed;
5570 5568 struct mtlop local;
5571 5569 int rval = 0;
5572 5570
5573 5571 ST_FUNC(ST_DEVINFO, st_mtioctop);
5574 5572
5575 5573 ASSERT(mutex_owned(ST_MUTEX));
5576 5574
5577 5575 #ifdef _MULTI_DATAMODEL
5578 5576 switch (ddi_model_convert_from(flag & FMODELS)) {
5579 5577 case DDI_MODEL_ILP32:
5580 5578 if (ddi_copyin((void *)arg, &mtop_32_for_64,
5581 5579 sizeof (struct mtop32), flag)) {
5582 5580 return (EFAULT);
5583 5581 }
5584 5582 local.mt_op = mtop_32_for_64.mt_op;
5585 5583 local.mt_count = (int64_t)mtop_32_for_64.mt_count;
5586 5584 break;
5587 5585
5588 5586 case DDI_MODEL_NONE:
5589 5587 if (ddi_copyin((void *)arg, &passed, sizeof (passed), flag)) {
5590 5588 return (EFAULT);
5591 5589 }
5592 5590 local.mt_op = passed.mt_op;
5593 5591 /* prevent sign extention */
5594 5592 local.mt_count = (UINT32_MAX & passed.mt_count);
5595 5593 break;
5596 5594 }
5597 5595
5598 5596 #else /* ! _MULTI_DATAMODEL */
5599 5597 if (ddi_copyin((void *)arg, &passed, sizeof (passed), flag)) {
5600 5598 return (EFAULT);
5601 5599 }
5602 5600 local.mt_op = passed.mt_op;
5603 5601 /* prevent sign extention */
5604 5602 local.mt_count = (UINT32_MAX & passed.mt_count);
5605 5603 #endif /* _MULTI_DATAMODEL */
5606 5604
5607 5605 rval = st_do_mtioctop(un, &local);
5608 5606
5609 5607 #ifdef _MULTI_DATAMODEL
5610 5608 switch (ddi_model_convert_from(flag & FMODELS)) {
5611 5609 case DDI_MODEL_ILP32:
5612 5610 if (((uint64_t)local.mt_count) > UINT32_MAX) {
5613 5611 rval = ERANGE;
5614 5612 break;
5615 5613 }
5616 5614 /*
5617 5615 * Convert 64 bit back to 32 bit before doing
5618 5616 * copyout. This is what the ILP32 app expects.
5619 5617 */
5620 5618 mtop_32_for_64.mt_op = local.mt_op;
5621 5619 mtop_32_for_64.mt_count = local.mt_count;
5622 5620
5623 5621 if (ddi_copyout(&mtop_32_for_64, (void *)arg,
5624 5622 sizeof (struct mtop32), flag)) {
5625 5623 rval = EFAULT;
5626 5624 }
5627 5625 break;
5628 5626
5629 5627 case DDI_MODEL_NONE:
5630 5628 passed.mt_count = local.mt_count;
5631 5629 passed.mt_op = local.mt_op;
5632 5630 if (ddi_copyout(&passed, (void *)arg, sizeof (passed), flag)) {
5633 5631 rval = EFAULT;
5634 5632 }
5635 5633 break;
5636 5634 }
5637 5635 #else /* ! _MULTI_DATAMODE */
5638 5636 if (((uint64_t)local.mt_count) > UINT32_MAX) {
5639 5637 rval = ERANGE;
5640 5638 } else {
5641 5639 passed.mt_op = local.mt_op;
5642 5640 passed.mt_count = local.mt_count;
5643 5641 if (ddi_copyout(&passed, (void *)arg, sizeof (passed), flag)) {
5644 5642 rval = EFAULT;
5645 5643 }
5646 5644 }
5647 5645 #endif /* _MULTI_DATAMODE */
5648 5646
5649 5647
5650 5648 ST_DEBUG6(ST_DEVINFO, st_label, SCSI_DEBUG,
5651 5649 "st_ioctl: fileno=%x, blkno=%x, eof=%x\n", un->un_pos.fileno,
5652 5650 un->un_pos.blkno, un->un_pos.eof);
5653 5651
5654 5652 if (un->un_pos.pmode == invalid) {
5655 5653 un->un_density_known = 0;
5656 5654 }
5657 5655
5658 5656 ASSERT(mutex_owned(ST_MUTEX));
5659 5657 return (rval);
5660 5658 }
5661 5659
5662 5660 static int
5663 5661 st_mtiocltop(struct scsi_tape *un, intptr_t arg, int flag)
5664 5662 {
5665 5663 struct mtlop local;
5666 5664 int rval;
5667 5665
5668 5666 ST_FUNC(ST_DEVINFO, st_mtiocltop);
5669 5667 if (ddi_copyin((void *)arg, &local, sizeof (local), flag)) {
5670 5668 return (EFAULT);
5671 5669 }
5672 5670
5673 5671 rval = st_do_mtioctop(un, &local);
5674 5672
5675 5673 if (ddi_copyout(&local, (void *)arg, sizeof (local), flag)) {
5676 5674 rval = EFAULT;
5677 5675 }
5678 5676 return (rval);
5679 5677 }
5680 5678
5681 5679
5682 5680 static int
5683 5681 st_do_mtioctop(struct scsi_tape *un, struct mtlop *mtop)
5684 5682 {
5685 5683 dev_t dev = un->un_dev;
5686 5684 int savefile;
5687 5685 int rval = 0;
5688 5686
5689 5687 ST_FUNC(ST_DEVINFO, st_do_mtioctop);
5690 5688
5691 5689 ST_DEBUG3(ST_DEVINFO, st_label, SCSI_DEBUG,
5692 5690 "st_do_mtioctop(): mt_op=%x\n", mtop->mt_op);
5693 5691 ST_DEBUG3(ST_DEVINFO, st_label, SCSI_DEBUG,
5694 5692 "fileno=%x, blkno=%x, eof=%x\n",
5695 5693 un->un_pos.fileno, un->un_pos.blkno, un->un_pos.eof);
5696 5694
5697 5695 un->un_status = 0;
5698 5696
5699 5697 /*
5700 5698 * if we are going to mess with a tape, we have to make sure we have
5701 5699 * one and are not offline (i.e. no tape is initialized). We let
5702 5700 * commands pass here that don't actually touch the tape, except for
5703 5701 * loading and initialization (rewinding).
5704 5702 */
5705 5703 if (un->un_state == ST_STATE_OFFLINE) {
5706 5704 switch (mtop->mt_op) {
5707 5705 case MTLOAD:
5708 5706 case MTNOP:
5709 5707 /*
5710 5708 * We don't want strategy calling st_tape_init here,
5711 5709 * so, change state
5712 5710 */
5713 5711 un->un_state = ST_STATE_INITIALIZING;
5714 5712 ST_DEBUG2(ST_DEVINFO, st_label, SCSI_DEBUG,
5715 5713 "st_do_mtioctop : OFFLINE state = %d\n",
5716 5714 un->un_state);
5717 5715 break;
5718 5716 default:
5719 5717 /*
5720 5718 * reinitialize by normal means
5721 5719 */
5722 5720 rval = st_tape_init(un);
5723 5721 if (rval) {
5724 5722 un->un_state = ST_STATE_INITIALIZING;
5725 5723 ST_DEBUG2(ST_DEVINFO, st_label, SCSI_DEBUG,
5726 5724 "st_do_mtioctop : OFFLINE init failure ");
5727 5725 un->un_state = ST_STATE_OFFLINE;
5728 5726 un->un_pos.pmode = invalid;
5729 5727 if (rval != EACCES) {
5730 5728 rval = EIO;
5731 5729 }
5732 5730 return (rval);
5733 5731 }
5734 5732 un->un_state = ST_STATE_OPEN_PENDING_IO;
5735 5733 break;
5736 5734 }
5737 5735 }
5738 5736
5739 5737 /*
5740 5738 * If the file position is invalid, allow only those
5741 5739 * commands that properly position the tape and fail
5742 5740 * the rest with EIO
5743 5741 */
5744 5742 if (un->un_pos.pmode == invalid) {
5745 5743 switch (mtop->mt_op) {
5746 5744 case MTWEOF:
5747 5745 case MTRETEN:
5748 5746 case MTERASE:
5749 5747 case MTEOM:
5750 5748 case MTFSF:
5751 5749 case MTFSR:
5752 5750 case MTBSF:
5753 5751 case MTNBSF:
5754 5752 case MTBSR:
5755 5753 case MTSRSZ:
5756 5754 case MTGRSZ:
5757 5755 case MTSEEK:
5758 5756 case MTBSSF:
5759 5757 case MTFSSF:
5760 5758 return (EIO);
5761 5759 /* NOTREACHED */
5762 5760 case MTREW:
5763 5761 case MTLOAD:
5764 5762 case MTOFFL:
5765 5763 case MTNOP:
5766 5764 case MTTELL:
5767 5765 case MTLOCK:
5768 5766 case MTUNLOCK:
5769 5767 break;
5770 5768
5771 5769 default:
5772 5770 return (ENOTTY);
5773 5771 /* NOTREACHED */
5774 5772 }
5775 5773 }
5776 5774
5777 5775 switch (mtop->mt_op) {
5778 5776 case MTERASE:
5779 5777 /*
5780 5778 * MTERASE rewinds the tape, erase it completely, and returns
5781 5779 * to the beginning of the tape
5782 5780 */
5783 5781 if (un->un_mspl->wp || un->un_read_only & WORM) {
5784 5782 un->un_status = KEY_WRITE_PROTECT;
5785 5783 un->un_err_resid = mtop->mt_count;
5786 5784 COPY_POS(&un->un_err_pos, &un->un_pos);
5787 5785 return (EACCES);
5788 5786 }
5789 5787 if (un->un_dp->options & ST_REEL) {
5790 5788 un->un_fmneeded = 2;
5791 5789 } else {
5792 5790 un->un_fmneeded = 1;
5793 5791 }
5794 5792 mtop->mt_count = mtop->mt_count ? 1 : 0;
5795 5793 if (st_check_density_or_wfm(dev, 1, B_WRITE, NO_STEPBACK) ||
5796 5794 st_cmd(un, SCMD_REWIND, 0, SYNC_CMD) ||
5797 5795 st_cmd(un, SCMD_ERASE, mtop->mt_count, SYNC_CMD)) {
5798 5796 un->un_pos.pmode = invalid;
5799 5797 ST_DEBUG2(ST_DEVINFO, st_label, SCSI_DEBUG,
5800 5798 "st_do_mtioctop : EIO space or erase or "
5801 5799 "check den)\n");
5802 5800 rval = EIO;
5803 5801 } else {
5804 5802 /* QIC and helical scan rewind after erase */
5805 5803 if (un->un_dp->options & ST_REEL) {
5806 5804 (void) st_cmd(un, SCMD_REWIND, 0, ASYNC_CMD);
5807 5805 }
5808 5806 }
5809 5807 break;
5810 5808
5811 5809 case MTWEOF:
5812 5810 /*
5813 5811 * write an end-of-file record
5814 5812 */
5815 5813 if (un->un_mspl->wp || un->un_read_only & RDONLY) {
5816 5814 un->un_status = KEY_WRITE_PROTECT;
5817 5815 un->un_err_resid = mtop->mt_count;
5818 5816 COPY_POS(&un->un_err_pos, &un->un_pos);
5819 5817 return (EACCES);
5820 5818 }
5821 5819
5822 5820 /*
5823 5821 * zero count means just flush buffers
5824 5822 * negative count is not permitted
5825 5823 */
5826 5824 if (mtop->mt_count < 0) {
5827 5825 return (EINVAL);
5828 5826 }
5829 5827
5830 5828 /* Not on worm */
5831 5829 if (un->un_read_only == RDWR) {
5832 5830 un->un_test_append = 1;
5833 5831 }
5834 5832
5835 5833 if (un->un_state == ST_STATE_OPEN_PENDING_IO) {
5836 5834 if (st_determine_density(un, B_WRITE)) {
5837 5835 ST_DEBUG2(ST_DEVINFO, st_label, SCSI_DEBUG,
5838 5836 "st_do_mtioctop : EIO : MTWEOF can't "
5839 5837 "determine density");
5840 5838 return (EIO);
5841 5839 }
5842 5840 }
5843 5841
5844 5842 rval = st_write_fm(dev, (int)mtop->mt_count);
5845 5843 if ((rval != 0) && (rval != EACCES)) {
5846 5844 /*
5847 5845 * Failure due to something other than illegal
5848 5846 * request results in loss of state (st_intr).
5849 5847 */
5850 5848 ST_DEBUG2(ST_DEVINFO, st_label, SCSI_DEBUG,
5851 5849 "st_do_mtioctop : EIO : MTWEOF can't write "
5852 5850 "file mark");
5853 5851 rval = EIO;
5854 5852 }
5855 5853 break;
5856 5854
5857 5855 case MTRETEN:
5858 5856 /*
5859 5857 * retension the tape
5860 5858 */
5861 5859 if (st_check_density_or_wfm(dev, 1, 0, NO_STEPBACK) ||
5862 5860 st_cmd(un, SCMD_LOAD, LD_LOAD | LD_RETEN, SYNC_CMD)) {
5863 5861 un->un_pos.pmode = invalid;
5864 5862 ST_DEBUG2(ST_DEVINFO, st_label, SCSI_DEBUG,
5865 5863 "st_do_mtioctop : EIO : MTRETEN ");
5866 5864 rval = EIO;
5867 5865 }
5868 5866 break;
5869 5867
5870 5868 case MTREW:
5871 5869 /*
5872 5870 * rewind the tape
5873 5871 */
5874 5872 if (st_check_density_or_wfm(dev, 1, 0, NO_STEPBACK)) {
5875 5873 ST_DEBUG2(ST_DEVINFO, st_label, SCSI_DEBUG,
5876 5874 "st_do_mtioctop : EIO:MTREW check "
5877 5875 "density/wfm failed");
5878 5876 return (EIO);
5879 5877 }
5880 5878 if (st_cmd(un, SCMD_REWIND, 0, SYNC_CMD)) {
5881 5879 ST_DEBUG2(ST_DEVINFO, st_label, SCSI_DEBUG,
5882 5880 "st_do_mtioctop : EIO : MTREW ");
5883 5881 rval = EIO;
5884 5882 }
5885 5883 break;
5886 5884
5887 5885 case MTOFFL:
5888 5886 /*
5889 5887 * rewinds, and, if appropriate, takes the device offline by
5890 5888 * unloading the tape
5891 5889 */
5892 5890 if (st_check_density_or_wfm(dev, 1, 0, NO_STEPBACK)) {
5893 5891 ST_DEBUG2(ST_DEVINFO, st_label, SCSI_DEBUG,
5894 5892 "st_do_mtioctop :EIO:MTOFFL check "
5895 5893 "density/wfm failed");
5896 5894 return (EIO);
5897 5895 }
5898 5896 (void) st_cmd(un, SCMD_REWIND, 0, SYNC_CMD);
5899 5897 if (st_cmd(un, SCMD_LOAD, LD_UNLOAD, SYNC_CMD)) {
5900 5898 ST_DEBUG2(ST_DEVINFO, st_label, SCSI_DEBUG,
5901 5899 "st_do_mtioctop : EIO : MTOFFL");
5902 5900 return (EIO);
5903 5901 }
5904 5902 un->un_pos.eof = ST_NO_EOF;
5905 5903 un->un_laststate = un->un_state;
5906 5904 un->un_state = ST_STATE_OFFLINE;
5907 5905 un->un_mediastate = MTIO_EJECTED;
5908 5906 break;
5909 5907
5910 5908 case MTLOAD:
5911 5909 /*
5912 5910 * This is to load a tape into the drive
5913 5911 * Note that if the tape is not loaded, the device will have
5914 5912 * to be opened via O_NDELAY or O_NONBLOCK.
5915 5913 */
5916 5914 /*
5917 5915 * Let's try and clean things up, if we are not
5918 5916 * initializing, and then send in the load command, no
5919 5917 * matter what.
5920 5918 *
5921 5919 * load after a media change by the user.
5922 5920 */
5923 5921
5924 5922 if (un->un_state > ST_STATE_INITIALIZING) {
5925 5923 (void) st_check_density_or_wfm(dev, 1, 0, NO_STEPBACK);
5926 5924 }
5927 5925 rval = st_cmd(un, SCMD_LOAD, LD_LOAD, SYNC_CMD);
5928 5926 /* Load command to a drive that doesn't support load */
5929 5927 if ((rval == EIO) &&
5930 5928 ((un->un_status == KEY_NOT_READY) &&
5931 5929 /* Medium not present */
5932 5930 (un->un_uscsi_rqs_buf->es_add_code == 0x3a) ||
5933 5931 ((un->un_status == KEY_ILLEGAL_REQUEST) &&
5934 5932 (un->un_dp->type == MT_ISSTK9840) &&
5935 5933 /* CSL not present */
5936 5934 (un->un_uscsi_rqs_buf->es_add_code == 0x80)))) {
5937 5935 rval = ENOTTY;
5938 5936 break;
5939 5937 } else if (rval != EACCES && rval != 0) {
5940 5938 rval = EIO;
5941 5939 }
5942 5940 if (rval) {
5943 5941 ST_DEBUG2(ST_DEVINFO, st_label, SCSI_DEBUG,
5944 5942 "st_do_mtioctop : %s : MTLOAD\n",
5945 5943 rval == EACCES ? "EACCES" : "EIO");
5946 5944 /*
5947 5945 * If load tape fails, who knows what happened...
5948 5946 */
5949 5947 un->un_pos.pmode = invalid;
5950 5948 break;
5951 5949 }
5952 5950
5953 5951 /*
5954 5952 * reset all counters appropriately using rewind, as if LOAD
5955 5953 * succeeds, we are at BOT
5956 5954 */
5957 5955 un->un_state = ST_STATE_INITIALIZING;
5958 5956
5959 5957 rval = st_tape_init(un);
5960 5958 if ((rval == EACCES) && (un->un_read_only & WORM)) {
5961 5959 rval = 0;
5962 5960 break;
5963 5961 }
5964 5962
5965 5963 if (rval != 0) {
5966 5964 ST_DEBUG2(ST_DEVINFO, st_label, SCSI_DEBUG,
5967 5965 "st_do_mtioctop : EIO : MTLOAD calls "
5968 5966 "st_tape_init\n");
5969 5967 rval = EIO;
5970 5968 un->un_state = ST_STATE_OFFLINE;
5971 5969 }
5972 5970
5973 5971 break;
5974 5972
5975 5973 case MTNOP:
5976 5974 un->un_status = 0; /* Reset status */
5977 5975 un->un_err_resid = 0;
5978 5976 mtop->mt_count = MTUNIT(dev);
5979 5977 break;
5980 5978
5981 5979 case MTEOM:
5982 5980 /*
5983 5981 * positions the tape at a location just after the last file
5984 5982 * written on the tape. For cartridge and 8 mm, this after
5985 5983 * the last file mark; for reel, this is inbetween the two
5986 5984 * last 2 file marks
5987 5985 */
5988 5986 if ((un->un_pos.pmode == legacy && un->un_pos.eof >= ST_EOT) ||
5989 5987 (un->un_lastop == ST_OP_WRITE) ||
5990 5988 (un->un_lastop == ST_OP_WEOF)) {
5991 5989 /*
5992 5990 * If the command wants to move to logical end
5993 5991 * of media, and we're already there, we're done.
5994 5992 * If we were at logical eot, we reset the state
5995 5993 * to be *not* at logical eot.
5996 5994 *
5997 5995 * If we're at physical or logical eot, we prohibit
5998 5996 * forward space operations (unconditionally).
5999 5997 *
6000 5998 * Also if the last operation was a write of any
6001 5999 * kind the tape is at EOD.
6002 6000 */
6003 6001 return (0);
6004 6002 }
6005 6003 /*
6006 6004 * physical tape position may not be what we've been
6007 6005 * telling the user; adjust the request accordingly
6008 6006 */
6009 6007 if (IN_EOF(un->un_pos)) {
6010 6008 un->un_pos.fileno++;
6011 6009 un->un_pos.blkno = 0;
6012 6010 }
6013 6011
6014 6012 if (st_check_density_or_wfm(dev, 1, B_READ, NO_STEPBACK)) {
6015 6013 ST_DEBUG2(ST_DEVINFO, st_label, SCSI_DEBUG,
6016 6014 "st_do_mtioctop : EIO:MTEOM check density/wfm "
6017 6015 " failed");
6018 6016 return (EIO);
6019 6017 }
6020 6018
6021 6019 /*
6022 6020 * st_find_eod() returns the last fileno we knew about;
6023 6021 */
6024 6022 savefile = st_find_eod(un);
6025 6023
6026 6024 if ((un->un_status != KEY_BLANK_CHECK) &&
6027 6025 (un->un_status != SUN_KEY_EOT)) {
6028 6026 un->un_pos.pmode = invalid;
6029 6027 ST_DEBUG2(ST_DEVINFO, st_label, SCSI_DEBUG,
6030 6028 "st_do_mtioctop : EIO : MTEOM status check failed");
6031 6029 rval = EIO;
6032 6030 } else {
6033 6031 /*
6034 6032 * For 1/2" reel tapes assume logical EOT marked
6035 6033 * by two file marks or we don't care that we may
6036 6034 * be extending the last file on the tape.
6037 6035 */
6038 6036 if (un->un_dp->options & ST_REEL) {
6039 6037 if (st_cmd(un, SCMD_SPACE, Fmk(-1), SYNC_CMD)) {
6040 6038 un->un_pos.pmode = invalid;
6041 6039 ST_DEBUG2(ST_DEVINFO, st_label,
6042 6040 SCSI_DEBUG,
6043 6041 "st_do_mtioctop : EIO : MTEOM space"
6044 6042 " cmd failed");
6045 6043 rval = EIO;
6046 6044 break;
6047 6045 }
6048 6046 /*
6049 6047 * Fix up the block number.
6050 6048 */
6051 6049 un->un_pos.blkno = 0;
6052 6050 un->un_err_pos.blkno = 0;
6053 6051 }
6054 6052 un->un_err_resid = 0;
6055 6053 un->un_pos.fileno = savefile;
6056 6054 un->un_pos.eof = ST_EOT;
6057 6055 }
6058 6056 un->un_status = 0;
6059 6057 break;
6060 6058
6061 6059 case MTFSF:
6062 6060 MAX_SPACE_CNT(mtop->mt_count);
6063 6061 rval = st_mtfsf_ioctl(un, mtop->mt_count);
6064 6062 break;
6065 6063
6066 6064 case MTFSR:
6067 6065 MAX_SPACE_CNT(mtop->mt_count);
6068 6066 rval = st_mtfsr_ioctl(un, mtop->mt_count);
6069 6067 break;
6070 6068
6071 6069 case MTBSF:
6072 6070 MAX_SPACE_CNT(mtop->mt_count);
6073 6071 rval = st_mtbsf_ioctl(un, mtop->mt_count);
6074 6072 break;
6075 6073
6076 6074 case MTNBSF:
6077 6075 MAX_SPACE_CNT(mtop->mt_count);
6078 6076 rval = st_mtnbsf_ioctl(un, mtop->mt_count);
6079 6077 break;
6080 6078
6081 6079 case MTBSR:
6082 6080 MAX_SPACE_CNT(mtop->mt_count);
6083 6081 rval = st_mtbsr_ioctl(un, mtop->mt_count);
6084 6082 break;
6085 6083
6086 6084 case MTBSSF:
6087 6085 MAX_SPACE_CNT(mtop->mt_count);
6088 6086 rval = st_mtbsfm_ioctl(un, mtop->mt_count);
6089 6087 break;
6090 6088
6091 6089 case MTFSSF:
6092 6090 MAX_SPACE_CNT(mtop->mt_count);
6093 6091 rval = st_mtfsfm_ioctl(un, mtop->mt_count);
6094 6092 break;
6095 6093
6096 6094 case MTSRSZ:
6097 6095
6098 6096 /*
6099 6097 * Set record-size to that sent by user
6100 6098 * Check to see if there is reason that the requested
6101 6099 * block size should not be set.
6102 6100 */
6103 6101
6104 6102 /* If requesting variable block size is it ok? */
6105 6103 if ((mtop->mt_count == 0) &&
6106 6104 ((un->un_dp->options & ST_VARIABLE) == 0)) {
6107 6105 return (ENOTTY);
6108 6106 }
6109 6107
6110 6108 /*
6111 6109 * If requested block size is not variable "0",
6112 6110 * is it less then minimum.
6113 6111 */
6114 6112 if ((mtop->mt_count != 0) &&
6115 6113 (mtop->mt_count < un->un_minbsize)) {
6116 6114 return (EINVAL);
6117 6115 }
6118 6116
6119 6117 /* Is the requested block size more then maximum */
6120 6118 if ((mtop->mt_count > min(un->un_maxbsize, un->un_maxdma)) &&
6121 6119 (un->un_maxbsize != 0)) {
6122 6120 return (EINVAL);
6123 6121 }
6124 6122
6125 6123 /* Is requested block size a modulus the device likes */
6126 6124 if ((mtop->mt_count % un->un_data_mod) != 0) {
6127 6125 return (EINVAL);
6128 6126 }
6129 6127
6130 6128 if (st_change_block_size(un, (uint32_t)mtop->mt_count) != 0) {
6131 6129 ST_DEBUG2(ST_DEVINFO, st_label, SCSI_DEBUG,
6132 6130 "st_ioctl : MTSRSZ : EIO : cant set block size");
6133 6131 return (EIO);
6134 6132 }
6135 6133
6136 6134 return (0);
6137 6135
6138 6136 case MTGRSZ:
6139 6137 /*
6140 6138 * Get record-size to the user
6141 6139 */
6142 6140 mtop->mt_count = un->un_bsize;
6143 6141 rval = 0;
6144 6142 break;
6145 6143
6146 6144 case MTTELL:
6147 6145 rval = st_update_block_pos(un, st_cmd, 0);
6148 6146 mtop->mt_count = un->un_pos.lgclblkno;
6149 6147 break;
6150 6148
6151 6149 case MTSEEK:
6152 6150 rval = st_logical_block_locate(un, st_uscsi_cmd, &un->un_pos,
6153 6151 (uint64_t)mtop->mt_count, un->un_pos.partition);
6154 6152 /*
6155 6153 * This bit of magic make mt print the actual position if
6156 6154 * the resulting position was not what was asked for.
6157 6155 */
6158 6156 if (rval == ESPIPE) {
6159 6157 rval = EIO;
6160 6158 if ((uint64_t)mtop->mt_count != un->un_pos.lgclblkno) {
6161 6159 mtop->mt_op = MTTELL;
6162 6160 mtop->mt_count = un->un_pos.lgclblkno;
6163 6161 }
6164 6162 }
6165 6163 break;
6166 6164
6167 6165 case MTLOCK:
6168 6166 if (st_cmd(un, SCMD_DOORLOCK, MR_LOCK, SYNC_CMD)) {
6169 6167 ST_DEBUG2(ST_DEVINFO, st_label, SCSI_DEBUG,
6170 6168 "st_do_mtioctop : EIO : MTLOCK");
6171 6169 rval = EIO;
6172 6170 }
6173 6171 break;
6174 6172
6175 6173 case MTUNLOCK:
6176 6174 if (st_cmd(un, SCMD_DOORLOCK, MR_UNLOCK, SYNC_CMD)) {
6177 6175 ST_DEBUG2(ST_DEVINFO, st_label, SCSI_DEBUG,
6178 6176 "st_do_mtioctop : EIO : MTUNLOCK");
6179 6177 rval = EIO;
6180 6178 }
6181 6179 break;
6182 6180
6183 6181 default:
6184 6182 rval = ENOTTY;
6185 6183 }
6186 6184
6187 6185 return (rval);
6188 6186 }
6189 6187
6190 6188
6191 6189 /*
6192 6190 * Run a command for uscsi ioctl.
6193 6191 */
6194 6192 static int
6195 6193 st_uscsi_cmd(struct scsi_tape *un, struct uscsi_cmd *ucmd, int flag)
6196 6194 {
6197 6195 struct uscsi_cmd *uscmd;
6198 6196 struct buf *bp;
6199 6197 enum uio_seg uioseg;
6200 6198 int offline_state = 0;
6201 6199 int err = 0;
6202 6200 dev_t dev = un->un_dev;
6203 6201
6204 6202 ST_FUNC(ST_DEVINFO, st_uscsi_cmd);
6205 6203
6206 6204 ST_DEBUG3(ST_DEVINFO, st_label, SCSI_DEBUG,
6207 6205 "st_uscsi_cmd(dev = 0x%lx)\n", un->un_dev);
6208 6206
6209 6207 ASSERT(mutex_owned(ST_MUTEX));
6210 6208
6211 6209 /*
6212 6210 * We really don't know what commands are coming in here and
6213 6211 * we don't want to limit the commands coming in.
6214 6212 *
6215 6213 * If st_tape_init() gets called from st_strategy(), then we
6216 6214 * will hang the process waiting for un->un_sbuf_busy to be cleared,
6217 6215 * which it never will, as we set it below. To prevent
6218 6216 * st_tape_init() from getting called, we have to set state to other
6219 6217 * than ST_STATE_OFFLINE, so we choose ST_STATE_INITIALIZING, which
6220 6218 * achieves this purpose already.
6221 6219 *
6222 6220 * We use offline_state to preserve the OFFLINE state, if it exists,
6223 6221 * so other entry points to the driver might have the chance to call
6224 6222 * st_tape_init().
6225 6223 */
6226 6224 if (un->un_state == ST_STATE_OFFLINE) {
6227 6225 un->un_laststate = ST_STATE_OFFLINE;
6228 6226 un->un_state = ST_STATE_INITIALIZING;
6229 6227 offline_state = 1;
6230 6228 }
6231 6229
6232 6230 mutex_exit(ST_MUTEX);
6233 6231 err = scsi_uscsi_alloc_and_copyin((intptr_t)ucmd, flag, ROUTE, &uscmd);
6234 6232 mutex_enter(ST_MUTEX);
6235 6233 if (err != 0) {
6236 6234 ST_DEBUG2(ST_DEVINFO, st_label, SCSI_DEBUG,
6237 6235 "st_uscsi_cmd: scsi_uscsi_alloc_and_copyin failed\n");
6238 6236 goto exit;
6239 6237 }
6240 6238
6241 6239 uioseg = (flag & FKIOCTL) ? UIO_SYSSPACE : UIO_USERSPACE;
6242 6240
6243 6241 /* check to see if this command requires the drive to be reserved */
6244 6242 if (uscmd->uscsi_cdb != NULL) {
6245 6243 err = st_check_cdb_for_need_to_reserve(un,
6246 6244 (uchar_t *)uscmd->uscsi_cdb);
6247 6245 if (err) {
6248 6246 goto exit_free;
6249 6247 }
6250 6248 /*
6251 6249 * If this is a space command we need to save the starting
6252 6250 * point so we can retry from there if the command fails.
6253 6251 */
6254 6252 if ((uscmd->uscsi_cdb[0] == SCMD_SPACE) ||
6255 6253 (uscmd->uscsi_cdb[0] == (char)SCMD_SPACE_G4)) {
6256 6254 (void) st_update_block_pos(un, st_cmd, 0);
6257 6255 }
6258 6256 }
6259 6257
6260 6258 /*
6261 6259 * Forground should not be doing anything while recovery is active.
6262 6260 */
6263 6261 ASSERT(un->un_recov_buf_busy == 0);
6264 6262
6265 6263 /*
6266 6264 * Get buffer resources...
6267 6265 */
6268 6266 while (un->un_sbuf_busy)
6269 6267 cv_wait(&un->un_sbuf_cv, ST_MUTEX);
6270 6268 un->un_sbuf_busy = 1;
6271 6269
6272 6270 #ifdef STDEBUG
6273 6271 if ((uscmd->uscsi_cdb != NULL) && (st_debug & 0x7) > 6) {
6274 6272 int rw = (uscmd->uscsi_flags & USCSI_READ) ? B_READ : B_WRITE;
6275 6273 st_print_cdb(ST_DEVINFO, st_label, SCSI_DEBUG,
6276 6274 "uscsi cdb", uscmd->uscsi_cdb);
6277 6275 if (uscmd->uscsi_buflen) {
6278 6276 ST_DEBUG6(ST_DEVINFO, st_label, SCSI_DEBUG,
6279 6277 "uscsi %s of %ld bytes %s %s space\n",
6280 6278 (rw == B_READ) ? rd_str : wr_str,
6281 6279 uscmd->uscsi_buflen,
6282 6280 (rw == B_READ) ? "to" : "from",
6283 6281 (uioseg == UIO_SYSSPACE) ? "system" : "user");
6284 6282 }
6285 6283 }
6286 6284 #endif /* STDEBUG */
6287 6285
6288 6286 /*
6289 6287 * Although st_uscsi_cmd() never makes use of these
6290 6288 * now, we are just being safe and consistent.
6291 6289 */
6292 6290 uscmd->uscsi_flags &= ~(USCSI_NOINTR | USCSI_NOPARITY |
6293 6291 USCSI_OTAG | USCSI_HTAG | USCSI_HEAD);
6294 6292
6295 6293 un->un_srqbufp = uscmd->uscsi_rqbuf;
6296 6294 bp = un->un_sbufp;
6297 6295 bzero(bp, sizeof (buf_t));
6298 6296 if (uscmd->uscsi_cdb != NULL) {
6299 6297 bp->b_forw = (struct buf *)(uintptr_t)uscmd->uscsi_cdb[0];
6300 6298 }
6301 6299 bp->b_back = (struct buf *)uscmd;
6302 6300
6303 6301 mutex_exit(ST_MUTEX);
6304 6302 err = scsi_uscsi_handle_cmd(dev, uioseg, uscmd, st_strategy, bp, NULL);
6305 6303 mutex_enter(ST_MUTEX);
6306 6304
6307 6305 /*
6308 6306 * If scsi reset successful, don't write any filemarks.
6309 6307 */
6310 6308 if ((err == 0) && (uscmd->uscsi_flags &
6311 6309 (USCSI_RESET_LUN | USCSI_RESET_TARGET | USCSI_RESET_ALL))) {
6312 6310 un->un_fmneeded = 0;
6313 6311 }
6314 6312
6315 6313 exit_free:
6316 6314 /*
6317 6315 * Free resources
6318 6316 */
6319 6317 un->un_sbuf_busy = 0;
6320 6318 un->un_srqbufp = NULL;
6321 6319
6322 6320 /*
6323 6321 * If was a space command need to update logical block position.
6324 6322 * If the command failed such that positioning is invalid, Don't
6325 6323 * update the position as the user must do this to validate the
6326 6324 * position for data protection.
6327 6325 */
6328 6326 if ((uscmd->uscsi_cdb != NULL) &&
6329 6327 ((uscmd->uscsi_cdb[0] == SCMD_SPACE) ||
6330 6328 (uscmd->uscsi_cdb[0] == (char)SCMD_SPACE_G4)) &&
6331 6329 (un->un_pos.pmode != invalid)) {
6332 6330 un->un_running.pmode = invalid;
6333 6331 (void) st_update_block_pos(un, st_cmd, 1);
6334 6332 /*
6335 6333 * Set running position to invalid so it updates on the
6336 6334 * next command.
6337 6335 */
6338 6336 un->un_running.pmode = invalid;
6339 6337 }
6340 6338 cv_signal(&un->un_sbuf_cv);
6341 6339 mutex_exit(ST_MUTEX);
6342 6340 (void) scsi_uscsi_copyout_and_free((intptr_t)ucmd, uscmd);
6343 6341 mutex_enter(ST_MUTEX);
6344 6342 ST_DEBUG6(ST_DEVINFO, st_label, SCSI_DEBUG,
6345 6343 "st_uscsi_cmd returns 0x%x\n", err);
6346 6344
6347 6345 exit:
6348 6346 /* don't lose offline state */
6349 6347 if (offline_state) {
6350 6348 un->un_state = ST_STATE_OFFLINE;
6351 6349 }
6352 6350
6353 6351 ASSERT(mutex_owned(ST_MUTEX));
6354 6352 return (err);
6355 6353 }
6356 6354
6357 6355 static int
6358 6356 st_write_fm(dev_t dev, int wfm)
6359 6357 {
6360 6358 int i;
6361 6359 int rval;
6362 6360
6363 6361 GET_SOFT_STATE(dev);
6364 6362
6365 6363 ST_FUNC(ST_DEVINFO, st_write_fm);
6366 6364
6367 6365 ASSERT(mutex_owned(ST_MUTEX));
6368 6366
6369 6367 ST_DEBUG3(ST_DEVINFO, st_label, SCSI_DEBUG,
6370 6368 "st_write_fm(dev = 0x%lx, wfm = %d)\n", dev, wfm);
6371 6369
6372 6370 /*
6373 6371 * write one filemark at the time after EOT
6374 6372 */
6375 6373 if (un->un_pos.eof >= ST_EOT) {
6376 6374 for (i = 0; i < wfm; i++) {
6377 6375 rval = st_cmd(un, SCMD_WRITE_FILE_MARK, 1, SYNC_CMD);
6378 6376 if (rval == EACCES) {
6379 6377 return (rval);
6380 6378 }
6381 6379 if (rval != 0) {
6382 6380 ST_DEBUG2(ST_DEVINFO, st_label, SCSI_DEBUG,
6383 6381 "st_write_fm : EIO : write EOT file mark");
6384 6382 return (EIO);
6385 6383 }
6386 6384 }
6387 6385 } else {
6388 6386 rval = st_cmd(un, SCMD_WRITE_FILE_MARK, wfm, SYNC_CMD);
6389 6387 if (rval == EACCES) {
6390 6388 return (rval);
6391 6389 }
6392 6390 if (rval) {
6393 6391 ST_DEBUG2(ST_DEVINFO, st_label, SCSI_DEBUG,
6394 6392 "st_write_fm : EIO : write file mark");
6395 6393 return (EIO);
6396 6394 }
6397 6395 }
6398 6396
6399 6397 ASSERT(mutex_owned(ST_MUTEX));
6400 6398 return (0);
6401 6399 }
6402 6400
6403 6401 #ifdef STDEBUG
6404 6402 static void
6405 6403 st_start_dump(struct scsi_tape *un, struct buf *bp)
6406 6404 {
6407 6405 struct scsi_pkt *pkt = BP_PKT(bp);
6408 6406 uchar_t *cdbp = (uchar_t *)pkt->pkt_cdbp;
6409 6407
6410 6408 ST_FUNC(ST_DEVINFO, st_start_dump);
6411 6409
6412 6410 if ((st_debug & 0x7) < 6)
6413 6411 return;
6414 6412 scsi_log(ST_DEVINFO, st_label, SCSI_DEBUG,
6415 6413 "st_start: cmd=0x%p count=%ld resid=%ld flags=0x%x pkt=0x%p\n",
6416 6414 (void *)bp->b_forw, bp->b_bcount,
6417 6415 bp->b_resid, bp->b_flags, (void *)BP_PKT(bp));
6418 6416 st_print_cdb(ST_DEVINFO, st_label, SCSI_DEBUG,
6419 6417 "st_start: cdb", (caddr_t)cdbp);
6420 6418 scsi_log(ST_DEVINFO, st_label, SCSI_DEBUG,
6421 6419 "st_start: fileno=%d, blk=%d\n",
6422 6420 un->un_pos.fileno, un->un_pos.blkno);
6423 6421 }
6424 6422 #endif
6425 6423
6426 6424
6427 6425 /*
6428 6426 * Command start && done functions
6429 6427 */
6430 6428
6431 6429 /*
6432 6430 * st_start()
6433 6431 *
6434 6432 * Called from:
6435 6433 * st_strategy() to start a command.
6436 6434 * st_runout() to retry when scsi_pkt allocation fails on previous attempt(s).
6437 6435 * st_attach() when resuming from power down state.
6438 6436 * st_start_restart() to retry transport when device was previously busy.
6439 6437 * st_done_and_mutex_exit() to start the next command when previous is done.
6440 6438 *
6441 6439 * On entry:
6442 6440 * scsi_pkt may or may not be allocated.
6443 6441 *
6444 6442 */
6445 6443 static void
6446 6444 st_start(struct scsi_tape *un)
6447 6445 {
6448 6446 struct buf *bp;
6449 6447 int status;
6450 6448 int queued;
6451 6449
6452 6450 ST_FUNC(ST_DEVINFO, st_start);
6453 6451 ASSERT(mutex_owned(ST_MUTEX));
6454 6452
6455 6453 ST_DEBUG3(ST_DEVINFO, st_label, SCSI_DEBUG,
6456 6454 "st_start(): dev = 0x%lx\n", un->un_dev);
6457 6455
6458 6456 if (un->un_recov_buf_busy) {
6459 6457 /* recovery commands can happen anytime */
6460 6458 bp = un->un_recov_buf;
6461 6459 queued = 0;
6462 6460 } else if (un->un_sbuf_busy) {
6463 6461 /* sbuf commands should only happen with an empty queue. */
6464 6462 ASSERT(un->un_quef == NULL);
6465 6463 ASSERT(un->un_runqf == NULL);
6466 6464 bp = un->un_sbufp;
6467 6465 queued = 0;
6468 6466 } else if (un->un_quef != NULL) {
6469 6467 if (un->un_persistence && un->un_persist_errors) {
6470 6468 return;
6471 6469 }
6472 6470 bp = un->un_quef;
6473 6471 queued = 1;
6474 6472 } else {
6475 6473 scsi_log(ST_DEVINFO, st_label, SCSI_DEBUG,
6476 6474 "st_start() returning no buf found\n");
6477 6475 return;
6478 6476 }
6479 6477
6480 6478 ASSERT((bp->b_flags & B_DONE) == 0);
6481 6479
6482 6480 /*
6483 6481 * Don't send more than un_throttle commands to the HBA
6484 6482 */
6485 6483 if ((un->un_throttle <= 0) || (un->un_ncmds >= un->un_throttle)) {
6486 6484 /*
6487 6485 * if doing recovery we know there is outstanding commands.
6488 6486 */
6489 6487 if (bp != un->un_recov_buf) {
6490 6488 ST_DEBUG2(ST_DEVINFO, st_label, SCSI_DEBUG,
6491 6489 "st_start returning throttle = %d or ncmds = %d\n",
6492 6490 un->un_throttle, un->un_ncmds);
6493 6491 if (un->un_ncmds == 0) {
6494 6492 typedef void (*func)();
6495 6493 func fnc = (func)st_runout;
6496 6494
6497 6495 scsi_log(ST_DEVINFO, st_label, SCSI_DEBUG,
6498 6496 "Sending delayed start to st_runout()\n");
6499 6497 mutex_exit(ST_MUTEX);
6500 6498 (void) timeout(fnc, un, drv_usectohz(1000000));
6501 6499 mutex_enter(ST_MUTEX);
6502 6500 }
6503 6501 return;
6504 6502 }
6505 6503 }
6506 6504
6507 6505 /*
6508 6506 * If the buf has no scsi_pkt call st_make_cmd() to get one and
6509 6507 * build the command.
6510 6508 */
6511 6509 if (BP_PKT(bp) == NULL) {
6512 6510 ASSERT((bp->b_flags & B_DONE) == 0);
6513 6511 st_make_cmd(un, bp, st_runout);
6514 6512 ASSERT((bp->b_flags & B_DONE) == 0);
6515 6513 status = geterror(bp);
6516 6514
6517 6515 /*
6518 6516 * Some HBA's don't call bioerror() to set an error.
6519 6517 * And geterror() returns zero if B_ERROR is not set.
6520 6518 * So if we get zero we must check b_error.
6521 6519 */
6522 6520 if (status == 0 && bp->b_error != 0) {
6523 6521 status = bp->b_error;
6524 6522 bioerror(bp, status);
6525 6523 }
6526 6524
6527 6525 /*
6528 6526 * Some HBA's convert DDI_DMA_NORESOURCES into ENOMEM.
6529 6527 * In tape ENOMEM has special meaning so we'll change it.
6530 6528 */
6531 6529 if (status == ENOMEM) {
6532 6530 status = 0;
6533 6531 bioerror(bp, status);
6534 6532 }
6535 6533
6536 6534 /*
6537 6535 * Did it fail and is it retryable?
6538 6536 * If so return and wait for the callback through st_runout.
6539 6537 * Also looks like scsi_init_pkt() will setup a callback even
6540 6538 * if it isn't retryable.
6541 6539 */
6542 6540 if (BP_PKT(bp) == NULL) {
6543 6541 if (status == 0) {
6544 6542 /*
6545 6543 * If first attempt save state.
6546 6544 */
6547 6545 if (un->un_state != ST_STATE_RESOURCE_WAIT) {
6548 6546 un->un_laststate = un->un_state;
6549 6547 un->un_state = ST_STATE_RESOURCE_WAIT;
6550 6548 }
6551 6549 ST_DEBUG2(ST_DEVINFO, st_label, SCSI_DEBUG,
6552 6550 "temp no resources for pkt\n");
6553 6551 } else if (status == EINVAL) {
6554 6552 scsi_log(ST_DEVINFO, st_label, SCSI_DEBUG,
6555 6553 "scsi_init_pkt rejected pkt as too big\n");
6556 6554 if (un->un_persistence) {
6557 6555 st_set_pe_flag(un);
6558 6556 }
6559 6557 } else {
6560 6558 /*
6561 6559 * Unlikely that it would be retryable then not.
6562 6560 */
6563 6561 if (un->un_state == ST_STATE_RESOURCE_WAIT) {
6564 6562 un->un_state = un->un_laststate;
6565 6563 }
6566 6564 scsi_log(ST_DEVINFO, st_label, SCSI_DEBUG,
6567 6565 "perm no resources for pkt errno = 0x%x\n",
6568 6566 status);
6569 6567 }
6570 6568 return;
6571 6569 }
6572 6570 /*
6573 6571 * Worked this time set the state back.
6574 6572 */
6575 6573 if (un->un_state == ST_STATE_RESOURCE_WAIT) {
6576 6574 un->un_state = un->un_laststate;
6577 6575 }
6578 6576 }
6579 6577
6580 6578 if (queued) {
6581 6579 /*
6582 6580 * move from waitq to runq
6583 6581 */
6584 6582 (void) st_remove_from_queue(&un->un_quef, &un->un_quel, bp);
6585 6583 st_add_to_queue(&un->un_runqf, &un->un_runql, un->un_runql, bp);
6586 6584 }
6587 6585
6588 6586
6589 6587 #ifdef STDEBUG
6590 6588 st_start_dump(un, bp);
6591 6589 #endif
6592 6590
6593 6591 /* could not get here if throttle was zero */
6594 6592 un->un_last_throttle = un->un_throttle;
6595 6593 un->un_throttle = 0; /* so nothing else will come in here */
6596 6594 un->un_ncmds++;
6597 6595
6598 6596 ST_DO_KSTATS(bp, kstat_waitq_to_runq);
6599 6597
6600 6598 status = st_transport(un, BP_PKT(bp));
6601 6599
6602 6600 if (un->un_last_throttle) {
6603 6601 un->un_throttle = un->un_last_throttle;
6604 6602 }
6605 6603
6606 6604 if (status != TRAN_ACCEPT) {
6607 6605 ST_DO_KSTATS(bp, kstat_runq_back_to_waitq);
6608 6606 ST_DEBUG(ST_DEVINFO, st_label, CE_WARN,
6609 6607 "Unhappy transport packet status 0x%x\n", status);
6610 6608
6611 6609 if (status == TRAN_BUSY) {
6612 6610 pkt_info *pkti = BP_PKT(bp)->pkt_private;
6613 6611
6614 6612 /*
6615 6613 * If command recovery is enabled and this isn't
6616 6614 * a recovery command try command recovery.
6617 6615 */
6618 6616 if (pkti->privatelen == sizeof (recov_info) &&
6619 6617 bp != un->un_recov_buf) {
6620 6618 ST_RECOV(ST_DEVINFO, st_label, CE_WARN,
6621 6619 "Command Recovery called on busy send\n");
6622 6620 if (st_command_recovery(un, BP_PKT(bp),
6623 6621 ATTEMPT_RETRY) == JUST_RETURN) {
6624 6622 return;
6625 6623 }
6626 6624 } else {
6627 6625 mutex_exit(ST_MUTEX);
6628 6626 if (st_handle_start_busy(un, bp,
6629 6627 ST_TRAN_BUSY_TIMEOUT, queued) == 0) {
6630 6628 mutex_enter(ST_MUTEX);
6631 6629 return;
6632 6630 }
6633 6631 /*
6634 6632 * if too many retries, fail the transport
6635 6633 */
6636 6634 mutex_enter(ST_MUTEX);
6637 6635 }
6638 6636 }
6639 6637 scsi_log(ST_DEVINFO, st_label, CE_WARN,
6640 6638 "transport rejected %d\n", status);
6641 6639 bp->b_resid = bp->b_bcount;
6642 6640
6643 6641 ST_DO_KSTATS(bp, kstat_waitq_exit);
6644 6642 ST_DO_ERRSTATS(un, st_transerrs);
6645 6643 if ((bp == un->un_recov_buf) && (status == TRAN_BUSY)) {
6646 6644 st_bioerror(bp, EBUSY);
6647 6645 } else {
6648 6646 st_bioerror(bp, EIO);
6649 6647 st_set_pe_flag(un);
6650 6648 }
6651 6649 st_done_and_mutex_exit(un, bp);
6652 6650 mutex_enter(ST_MUTEX);
6653 6651 }
6654 6652
6655 6653 ASSERT(mutex_owned(ST_MUTEX));
6656 6654 }
6657 6655
6658 6656 /*
6659 6657 * if the transport is busy, then put this bp back on the waitq
6660 6658 */
6661 6659 static int
6662 6660 st_handle_start_busy(struct scsi_tape *un, struct buf *bp,
6663 6661 clock_t timeout_interval, int queued)
6664 6662 {
6665 6663
6666 6664 pkt_info *pktinfo = BP_PKT(bp)->pkt_private;
6667 6665
6668 6666 ST_FUNC(ST_DEVINFO, st_handle_start_busy);
6669 6667
6670 6668 mutex_enter(ST_MUTEX);
6671 6669
6672 6670 ST_DEBUG3(ST_DEVINFO, st_label, SCSI_DEBUG,
6673 6671 "st_handle_start_busy()\n");
6674 6672
6675 6673 /*
6676 6674 * Check to see if we hit the retry timeout and one last check for
6677 6675 * making sure this is the last on the runq, if it is not, we have
6678 6676 * to fail
6679 6677 */
6680 6678 if ((pktinfo->str_retry_cnt++ > st_retry_count) ||
6681 6679 ((queued) && (un->un_runql != bp))) {
6682 6680 mutex_exit(ST_MUTEX);
6683 6681 return (-1);
6684 6682 }
6685 6683
6686 6684 if (queued) {
6687 6685 /* put the bp back on the waitq */
6688 6686 st_add_to_queue(&un->un_quef, &un->un_quel, un->un_quef, bp);
6689 6687 }
6690 6688
6691 6689 /*
6692 6690 * Decrement un_ncmds so that this
6693 6691 * gets thru' st_start() again.
6694 6692 */
6695 6693 un->un_ncmds--;
6696 6694
6697 6695 if (queued) {
6698 6696 /*
6699 6697 * since this is an error case, we won't have to do this list
6700 6698 * walking much. We've already made sure this bp was the
6701 6699 * last on the runq
6702 6700 */
6703 6701 (void) st_remove_from_queue(&un->un_runqf, &un->un_runql, bp);
6704 6702
6705 6703 /*
6706 6704 * send a marker pkt, if appropriate
6707 6705 */
6708 6706 st_hba_unflush(un);
6709 6707
6710 6708 }
6711 6709 /*
6712 6710 * all queues are aligned, we are just waiting to
6713 6711 * transport, don't alloc any more buf p's, when
6714 6712 * st_start is reentered.
6715 6713 */
6716 6714 (void) timeout(st_start_restart, un, timeout_interval);
6717 6715
6718 6716 mutex_exit(ST_MUTEX);
6719 6717 return (0);
6720 6718 }
6721 6719
6722 6720
6723 6721 /*
6724 6722 * st_runout a callback that is called what a resource allocatation failed
6725 6723 */
6726 6724 static int
6727 6725 st_runout(caddr_t arg)
6728 6726 {
6729 6727 struct scsi_tape *un = (struct scsi_tape *)arg;
6730 6728 struct buf *bp;
6731 6729 int queued;
6732 6730
6733 6731 ASSERT(un != NULL);
6734 6732
6735 6733 ST_FUNC(ST_DEVINFO, st_runout);
6736 6734
6737 6735 mutex_enter(ST_MUTEX);
6738 6736
6739 6737 ST_DEBUG3(ST_DEVINFO, st_label, SCSI_DEBUG, "st_runout()\n");
6740 6738
6741 6739 if (un->un_recov_buf_busy != 0) {
6742 6740 bp = un->un_recov_buf;
6743 6741 queued = 0;
6744 6742 } else if (un->un_sbuf_busy != 0) {
6745 6743 /* sbuf commands should only happen with an empty queue. */
6746 6744 ASSERT(un->un_quef == NULL);
6747 6745 ASSERT(un->un_runqf == NULL);
6748 6746 bp = un->un_sbufp;
6749 6747 queued = 0;
6750 6748 } else if (un->un_quef != NULL) {
6751 6749 bp = un->un_quef;
6752 6750 if (un->un_persistence && un->un_persist_errors) {
6753 6751 mutex_exit(ST_MUTEX);
6754 6752 bp->b_resid = bp->b_bcount;
6755 6753 biodone(bp);
6756 6754 return (1);
6757 6755 }
6758 6756 queued = 1;
6759 6757 } else {
6760 6758 ASSERT(1 == 0);
6761 6759 mutex_exit(ST_MUTEX);
6762 6760 return (1);
6763 6761 }
6764 6762
6765 6763 /*
6766 6764 * failed scsi_init_pkt(). If errno is zero its retryable.
6767 6765 */
6768 6766 if ((bp != NULL) && (geterror(bp) != 0)) {
6769 6767
6770 6768 scsi_log(ST_DEVINFO, st_label, CE_WARN,
6771 6769 "errors after pkt alloc (b_flags=0x%x, b_error=0x%x)\n",
6772 6770 bp->b_flags, geterror(bp));
6773 6771 ASSERT((bp->b_flags & B_DONE) == 0);
6774 6772
6775 6773 if (queued) {
6776 6774 (void) st_remove_from_queue(&un->un_quef, &un->un_quel,
6777 6775 bp);
6778 6776 }
6779 6777 mutex_exit(ST_MUTEX);
6780 6778
6781 6779 ASSERT((bp->b_flags & B_DONE) == 0);
6782 6780
6783 6781 /*
6784 6782 * Set resid, Error already set, then unblock calling thread.
6785 6783 */
6786 6784 bp->b_resid = bp->b_bcount;
6787 6785 biodone(bp);
6788 6786 } else {
6789 6787 /*
6790 6788 * Try Again
6791 6789 */
6792 6790 st_start(un);
6793 6791 mutex_exit(ST_MUTEX);
6794 6792 }
6795 6793
6796 6794 /*
6797 6795 * Comments courtesy of sd.c
6798 6796 * The scsi_init_pkt routine allows for the callback function to
6799 6797 * return a 0 indicating the callback should be rescheduled or a 1
6800 6798 * indicating not to reschedule. This routine always returns 1
6801 6799 * because the driver always provides a callback function to
6802 6800 * scsi_init_pkt. This results in a callback always being scheduled
6803 6801 * (via the scsi_init_pkt callback implementation) if a resource
6804 6802 * failure occurs.
6805 6803 */
6806 6804
6807 6805 return (1);
6808 6806 }
6809 6807
6810 6808 /*
6811 6809 * st_done_and_mutex_exit()
6812 6810 * - remove bp from runq
6813 6811 * - start up the next request
6814 6812 * - if this was an asynch bp, clean up
6815 6813 * - exit with released mutex
6816 6814 */
6817 6815 static void
6818 6816 st_done_and_mutex_exit(struct scsi_tape *un, struct buf *bp)
6819 6817 {
6820 6818 int pe_flagged = 0;
6821 6819 struct scsi_pkt *pkt = BP_PKT(bp);
6822 6820 pkt_info *pktinfo = pkt->pkt_private;
6823 6821
6824 6822 ASSERT(MUTEX_HELD(&un->un_sd->sd_mutex));
6825 6823 #if !defined(lint)
6826 6824 _NOTE(LOCK_RELEASED_AS_SIDE_EFFECT(&un->un_sd->sd_mutex))
6827 6825 #endif
6828 6826
6829 6827 ST_FUNC(ST_DEVINFO, st_done_and_mutex_exit);
6830 6828
6831 6829 ASSERT(mutex_owned(ST_MUTEX));
6832 6830
6833 6831 (void) st_remove_from_queue(&un->un_runqf, &un->un_runql, bp);
6834 6832
6835 6833 un->un_ncmds--;
6836 6834 cv_signal(&un->un_queue_cv);
6837 6835
6838 6836 ST_DEBUG3(ST_DEVINFO, st_label, SCSI_DEBUG,
6839 6837 "st_done_and_mutex_exit(): cmd=0x%x count=%ld resid=%ld flags="
6840 6838 "0x%x\n", pkt->pkt_cdbp[0], bp->b_bcount,
6841 6839 bp->b_resid, bp->b_flags);
6842 6840
6843 6841
6844 6842 /*
6845 6843 * update kstats with transfer count info
6846 6844 */
6847 6845 if (un->un_stats && (bp != un->un_sbufp) && IS_RW(bp)) {
6848 6846 uint32_t n_done = bp->b_bcount - bp->b_resid;
6849 6847 if (bp->b_flags & B_READ) {
6850 6848 IOSP->reads++;
6851 6849 IOSP->nread += n_done;
6852 6850 } else {
6853 6851 IOSP->writes++;
6854 6852 IOSP->nwritten += n_done;
6855 6853 }
6856 6854 }
6857 6855
6858 6856 /*
6859 6857 * Start the next one before releasing resources on this one, if
6860 6858 * there is something on the queue and persistent errors has not been
6861 6859 * flagged
6862 6860 */
6863 6861
6864 6862 if ((pe_flagged = (un->un_persistence && un->un_persist_errors)) != 0) {
6865 6863 un->un_last_resid = bp->b_resid;
6866 6864 un->un_last_count = bp->b_bcount;
6867 6865 }
6868 6866
6869 6867 if (un->un_pwr_mgmt == ST_PWR_SUSPENDED) {
6870 6868 cv_broadcast(&un->un_tape_busy_cv);
6871 6869 } else if (un->un_quef && un->un_throttle && !pe_flagged &&
6872 6870 (bp != un->un_recov_buf)) {
6873 6871 st_start(un);
6874 6872 }
6875 6873
6876 6874 un->un_retry_ct = max(pktinfo->pkt_retry_cnt, pktinfo->str_retry_cnt);
6877 6875
6878 6876 if (bp == un->un_sbufp && (bp->b_flags & B_ASYNC)) {
6879 6877 /*
6880 6878 * Since we marked this ourselves as ASYNC,
6881 6879 * there isn't anybody around waiting for
6882 6880 * completion any more.
6883 6881 */
6884 6882 uchar_t *cmd = pkt->pkt_cdbp;
6885 6883 if (*cmd == SCMD_READ || *cmd == SCMD_WRITE) {
6886 6884 bp->b_un.b_addr = (caddr_t)0;
6887 6885 }
6888 6886 ST_DEBUG(ST_DEVINFO, st_label, CE_NOTE,
6889 6887 "st_done_and_mutex_exit(async): freeing pkt\n");
6890 6888 st_print_cdb(ST_DEVINFO, st_label, CE_NOTE,
6891 6889 "CDB sent with B_ASYNC", (caddr_t)cmd);
6892 6890 if (pkt) {
6893 6891 scsi_destroy_pkt(pkt);
6894 6892 }
6895 6893 un->un_sbuf_busy = 0;
6896 6894 cv_signal(&un->un_sbuf_cv);
6897 6895 mutex_exit(ST_MUTEX);
6898 6896 return;
6899 6897 }
6900 6898
6901 6899 if (bp == un->un_sbufp && BP_UCMD(bp)) {
6902 6900 /*
6903 6901 * Copy status from scsi_pkt to uscsi_cmd
6904 6902 * since st_uscsi_cmd needs it
6905 6903 */
6906 6904 BP_UCMD(bp)->uscsi_status = SCBP_C(BP_PKT(bp));
6907 6905 }
6908 6906
6909 6907
6910 6908 #ifdef STDEBUG
6911 6909 if (((st_debug & 0x7) >= 4) &&
6912 6910 (((un->un_pos.blkno % 100) == 0) ||
6913 6911 (un->un_persistence && un->un_persist_errors))) {
6914 6912
6915 6913 ST_DEBUG(ST_DEVINFO, st_label, SCSI_DEBUG,
6916 6914 "st_d_a_m_exit(): ncmds = %d, thr = %d, "
6917 6915 "un_errno = %d, un_pe = %d\n",
6918 6916 un->un_ncmds, un->un_throttle, un->un_errno,
6919 6917 un->un_persist_errors);
6920 6918 }
6921 6919
6922 6920 #endif
6923 6921
6924 6922 mutex_exit(ST_MUTEX);
6925 6923 ST_DEBUG6(ST_DEVINFO, st_label, SCSI_DEBUG,
6926 6924 "st_done_and_mutex_exit: freeing pkt\n");
6927 6925
6928 6926 if (pkt) {
6929 6927 scsi_destroy_pkt(pkt);
6930 6928 }
6931 6929
6932 6930 biodone(bp);
6933 6931
6934 6932 /*
6935 6933 * now that we biodoned that command, if persistent errors have been
6936 6934 * flagged, flush the waitq
6937 6935 */
6938 6936 if (pe_flagged)
6939 6937 st_flush(un);
6940 6938 }
6941 6939
6942 6940
6943 6941 /*
6944 6942 * Tape error, flush tape driver queue.
6945 6943 */
6946 6944 static void
6947 6945 st_flush(struct scsi_tape *un)
6948 6946 {
6949 6947 struct buf *bp;
6950 6948
6951 6949 ST_FUNC(ST_DEVINFO, st_flush);
6952 6950
6953 6951 mutex_enter(ST_MUTEX);
6954 6952
6955 6953 ST_DEBUG(ST_DEVINFO, st_label, SCSI_DEBUG,
6956 6954 "st_flush(), ncmds = %d, quef = 0x%p\n",
6957 6955 un->un_ncmds, (void *)un->un_quef);
6958 6956
6959 6957 /*
6960 6958 * if we still have commands outstanding, wait for them to come in
6961 6959 * before flushing the queue, and make sure there is a queue
6962 6960 */
6963 6961 if (un->un_ncmds || !un->un_quef)
6964 6962 goto exit;
6965 6963
6966 6964 /*
6967 6965 * we have no more commands outstanding, so let's deal with special
6968 6966 * cases in the queue for EOM and FM. If we are here, and un_errno
6969 6967 * is 0, then we know there was no error and we return a 0 read or
6970 6968 * write before showing errors
6971 6969 */
6972 6970
6973 6971 /* Flush the wait queue. */
6974 6972 while ((bp = un->un_quef) != NULL) {
6975 6973 un->un_quef = bp->b_actf;
6976 6974
6977 6975 bp->b_resid = bp->b_bcount;
6978 6976
6979 6977 ST_DEBUG(ST_DEVINFO, st_label, SCSI_DEBUG,
6980 6978 "st_flush() : blkno=%d, err=%d, b_bcount=%ld\n",
6981 6979 un->un_pos.blkno, un->un_errno, bp->b_bcount);
6982 6980
6983 6981 st_set_pe_errno(un);
6984 6982
6985 6983 bioerror(bp, un->un_errno);
6986 6984
6987 6985 mutex_exit(ST_MUTEX);
6988 6986 /* it should have one, but check anyway */
6989 6987 if (BP_PKT(bp)) {
6990 6988 scsi_destroy_pkt(BP_PKT(bp));
6991 6989 }
6992 6990 biodone(bp);
6993 6991 mutex_enter(ST_MUTEX);
6994 6992 }
6995 6993
6996 6994 /*
6997 6995 * It's not a bad practice to reset the
6998 6996 * waitq tail pointer to NULL.
6999 6997 */
7000 6998 un->un_quel = NULL;
7001 6999
7002 7000 exit:
7003 7001 /* we mucked with the queue, so let others know about it */
7004 7002 cv_signal(&un->un_queue_cv);
7005 7003 mutex_exit(ST_MUTEX);
7006 7004 }
7007 7005
7008 7006
7009 7007 /*
7010 7008 * Utility functions
7011 7009 */
7012 7010 static int
7013 7011 st_determine_generic(struct scsi_tape *un)
7014 7012 {
7015 7013 int bsize;
7016 7014 static char *cart = "0.25 inch cartridge";
7017 7015 char *sizestr;
7018 7016
7019 7017 ST_FUNC(ST_DEVINFO, st_determine_generic);
7020 7018
7021 7019 ST_DEBUG3(ST_DEVINFO, st_label, SCSI_DEBUG,
7022 7020 "st_determine_generic(un = 0x%p)\n", (void*)un);
7023 7021
7024 7022 ASSERT(mutex_owned(ST_MUTEX));
7025 7023
7026 7024 if (st_modesense(un)) {
7027 7025 return (-1);
7028 7026 }
7029 7027
7030 7028 bsize = (un->un_mspl->high_bl << 16) |
7031 7029 (un->un_mspl->mid_bl << 8) |
7032 7030 (un->un_mspl->low_bl);
7033 7031
7034 7032 if (bsize == 0) {
7035 7033 un->un_dp->options |= ST_VARIABLE;
7036 7034 un->un_dp->bsize = 0;
7037 7035 un->un_bsize = 0;
7038 7036 } else if (bsize > ST_MAXRECSIZE_FIXED) {
7039 7037 /*
7040 7038 * record size of this device too big.
7041 7039 * try and convert it to variable record length.
7042 7040 *
7043 7041 */
7044 7042 un->un_dp->options |= ST_VARIABLE;
7045 7043 if (st_change_block_size(un, 0) != 0) {
7046 7044 ST_DEBUG6(ST_DEVINFO, st_label, CE_WARN,
7047 7045 "Fixed Record Size %d is too large\n", bsize);
7048 7046 ST_DEBUG6(ST_DEVINFO, st_label, CE_WARN,
7049 7047 "Cannot switch to variable record size\n");
7050 7048 un->un_dp->options &= ~ST_VARIABLE;
7051 7049 return (-1);
7052 7050 }
7053 7051 } else if (st_change_block_size(un, 0) == 0) {
7054 7052 /*
7055 7053 * If the drive was set to a non zero block size,
7056 7054 * See if it can be set to a zero block size.
7057 7055 * If it works, ST_VARIABLE so user can set it as they want.
7058 7056 */
7059 7057 un->un_dp->options |= ST_VARIABLE;
7060 7058 un->un_dp->bsize = 0;
7061 7059 un->un_bsize = 0;
7062 7060 } else {
7063 7061 un->un_dp->bsize = bsize;
7064 7062 un->un_bsize = bsize;
7065 7063 }
7066 7064
7067 7065
7068 7066 switch (un->un_mspl->density) {
7069 7067 default:
7070 7068 case 0x0:
7071 7069 /*
7072 7070 * default density, cannot determine any other
7073 7071 * information.
7074 7072 */
7075 7073 sizestr = "Unknown type- assuming 0.25 inch cartridge";
7076 7074 un->un_dp->type = ST_TYPE_DEFAULT;
7077 7075 un->un_dp->options |= (ST_AUTODEN_OVERRIDE|ST_QIC);
7078 7076 break;
7079 7077 case 0x1:
7080 7078 case 0x2:
7081 7079 case 0x3:
7082 7080 case 0x6:
7083 7081 /*
7084 7082 * 1/2" reel
7085 7083 */
7086 7084 sizestr = "0.50 inch reel";
7087 7085 un->un_dp->type = ST_TYPE_REEL;
7088 7086 un->un_dp->options |= ST_REEL;
7089 7087 un->un_dp->densities[0] = 0x1;
7090 7088 un->un_dp->densities[1] = 0x2;
7091 7089 un->un_dp->densities[2] = 0x6;
7092 7090 un->un_dp->densities[3] = 0x3;
7093 7091 break;
7094 7092 case 0x4:
7095 7093 case 0x5:
7096 7094 case 0x7:
7097 7095 case 0x0b:
7098 7096
7099 7097 /*
7100 7098 * Quarter inch.
7101 7099 */
7102 7100 sizestr = cart;
7103 7101 un->un_dp->type = ST_TYPE_DEFAULT;
7104 7102 un->un_dp->options |= ST_QIC;
7105 7103
7106 7104 un->un_dp->densities[1] = 0x4;
7107 7105 un->un_dp->densities[2] = 0x5;
7108 7106 un->un_dp->densities[3] = 0x7;
7109 7107 un->un_dp->densities[0] = 0x0b;
7110 7108 break;
7111 7109
7112 7110 case 0x0f:
7113 7111 case 0x10:
7114 7112 case 0x11:
7115 7113 case 0x12:
7116 7114 /*
7117 7115 * QIC-120, QIC-150, QIC-320, QIC-600
7118 7116 */
7119 7117 sizestr = cart;
7120 7118 un->un_dp->type = ST_TYPE_DEFAULT;
7121 7119 un->un_dp->options |= ST_QIC;
7122 7120 un->un_dp->densities[0] = 0x0f;
7123 7121 un->un_dp->densities[1] = 0x10;
7124 7122 un->un_dp->densities[2] = 0x11;
7125 7123 un->un_dp->densities[3] = 0x12;
7126 7124 break;
7127 7125
7128 7126 case 0x09:
7129 7127 case 0x0a:
7130 7128 case 0x0c:
7131 7129 case 0x0d:
7132 7130 /*
7133 7131 * 1/2" cartridge tapes. Include HI-TC.
7134 7132 */
7135 7133 sizestr = cart;
7136 7134 sizestr[2] = '5';
7137 7135 sizestr[3] = '0';
7138 7136 un->un_dp->type = ST_TYPE_HIC;
7139 7137 un->un_dp->densities[0] = 0x09;
7140 7138 un->un_dp->densities[1] = 0x0a;
7141 7139 un->un_dp->densities[2] = 0x0c;
7142 7140 un->un_dp->densities[3] = 0x0d;
7143 7141 break;
7144 7142
7145 7143 case 0x13:
7146 7144 /* DDS-2/DDS-3 scsi spec densities */
7147 7145 case 0x24:
7148 7146 case 0x25:
7149 7147 case 0x26:
7150 7148 sizestr = "DAT Data Storage (DDS)";
7151 7149 un->un_dp->type = ST_TYPE_DAT;
7152 7150 un->un_dp->options |= ST_AUTODEN_OVERRIDE;
7153 7151 break;
7154 7152
7155 7153 case 0x14:
7156 7154 /*
7157 7155 * Helical Scan (Exabyte) devices
7158 7156 */
7159 7157 sizestr = "8mm helical scan cartridge";
7160 7158 un->un_dp->type = ST_TYPE_EXABYTE;
7161 7159 un->un_dp->options |= ST_AUTODEN_OVERRIDE;
7162 7160 break;
7163 7161 }
7164 7162
7165 7163 /*
7166 7164 * Assume LONG ERASE, BSF and BSR
7167 7165 */
7168 7166
7169 7167 un->un_dp->options |=
7170 7168 (ST_LONG_ERASE | ST_UNLOADABLE | ST_BSF | ST_BSR | ST_KNOWS_EOD);
7171 7169
7172 7170 /*
7173 7171 * Only if mode sense data says no buffered write, set NOBUF
7174 7172 */
7175 7173 if (un->un_mspl->bufm == 0)
7176 7174 un->un_dp->options |= ST_NOBUF;
7177 7175
7178 7176 /*
7179 7177 * set up large read and write retry counts
7180 7178 */
7181 7179
7182 7180 un->un_dp->max_rretries = un->un_dp->max_wretries = 1000;
7183 7181
7184 7182 /*
7185 7183 * If this is a 0.50 inch reel tape, and
7186 7184 * it is *not* variable mode, try and
7187 7185 * set it to variable record length
7188 7186 * mode.
7189 7187 */
7190 7188 if ((un->un_dp->options & ST_REEL) && un->un_bsize != 0 &&
7191 7189 (un->un_dp->options & ST_VARIABLE)) {
7192 7190 if (st_change_block_size(un, 0) == 0) {
7193 7191 un->un_dp->bsize = 0;
7194 7192 un->un_mspl->high_bl = un->un_mspl->mid_bl =
7195 7193 un->un_mspl->low_bl = 0;
7196 7194 }
7197 7195 }
7198 7196
7199 7197 /*
7200 7198 * Write to console about type of device found
7201 7199 */
7202 7200 ST_DEBUG6(ST_DEVINFO, st_label, CE_NOTE,
7203 7201 "Generic Drive, Vendor=%s\n\t%s", un->un_dp->name,
7204 7202 sizestr);
7205 7203 if (un->un_dp->options & ST_VARIABLE) {
7206 7204 scsi_log(ST_DEVINFO, st_label, CE_NOTE,
7207 7205 "!Variable record length I/O\n");
7208 7206 } else {
7209 7207 scsi_log(ST_DEVINFO, st_label, CE_NOTE,
7210 7208 "!Fixed record length (%d byte blocks) I/O\n",
7211 7209 un->un_dp->bsize);
7212 7210 }
7213 7211 ASSERT(mutex_owned(ST_MUTEX));
7214 7212 return (0);
7215 7213 }
7216 7214
7217 7215 static int
7218 7216 st_determine_density(struct scsi_tape *un, int rw)
7219 7217 {
7220 7218 int rval = 0;
7221 7219
7222 7220 ST_FUNC(ST_DEVINFO, st_determine_density);
7223 7221
7224 7222 ST_DEBUG3(ST_DEVINFO, st_label, SCSI_DEBUG,
7225 7223 "st_determine_density(un = 0x%p, rw = %s)\n",
7226 7224 (void*)un, (rw == B_WRITE ? wr_str: rd_str));
7227 7225
7228 7226 ASSERT(mutex_owned(ST_MUTEX));
7229 7227
7230 7228 /*
7231 7229 * If we're past BOT, density is determined already.
7232 7230 */
7233 7231 if (un->un_pos.pmode == logical) {
7234 7232 if (un->un_pos.lgclblkno != 0) {
7235 7233 goto exit;
7236 7234 }
7237 7235 } else if (un->un_pos.pmode == legacy) {
7238 7236 if ((un->un_pos.fileno != 0) || (un->un_pos.blkno != 0)) {
7239 7237 /*
7240 7238 * XXX: put in a bitch message about attempting to
7241 7239 * XXX: change density past BOT.
7242 7240 */
7243 7241 goto exit;
7244 7242 }
7245 7243 } else {
7246 7244 goto exit;
7247 7245 }
7248 7246 if ((un->un_pos.pmode == logical) &&
7249 7247 (un->un_pos.lgclblkno != 0)) {
7250 7248 goto exit;
7251 7249 }
7252 7250
7253 7251
7254 7252 /*
7255 7253 * If we're going to be writing, we set the density
7256 7254 */
7257 7255 if (rw == 0 || rw == B_WRITE) {
7258 7256 /* un_curdens is used as an index into densities table */
7259 7257 un->un_curdens = MT_DENSITY(un->un_dev);
7260 7258 if (st_set_density(un)) {
7261 7259 rval = -1;
7262 7260 }
7263 7261 goto exit;
7264 7262 }
7265 7263
7266 7264 /*
7267 7265 * If density is known already,
7268 7266 * we don't have to get it again.(?)
7269 7267 */
7270 7268 if (!un->un_density_known) {
7271 7269 if (st_get_density(un)) {
7272 7270 rval = -1;
7273 7271 }
7274 7272 }
7275 7273
7276 7274 exit:
7277 7275 ASSERT(mutex_owned(ST_MUTEX));
7278 7276 return (rval);
7279 7277 }
7280 7278
7281 7279
7282 7280 /*
7283 7281 * Try to determine density. We do this by attempting to read the
7284 7282 * first record off the tape, cycling through the available density
7285 7283 * codes as we go.
7286 7284 */
7287 7285
7288 7286 static int
7289 7287 st_get_density(struct scsi_tape *un)
7290 7288 {
7291 7289 int succes = 0, rval = -1, i;
7292 7290 uint_t size;
7293 7291 uchar_t dens, olddens;
7294 7292
7295 7293 ST_FUNC(ST_DEVINFO, st_get_density);
7296 7294
7297 7295 ST_DEBUG3(ST_DEVINFO, st_label, SCSI_DEBUG,
7298 7296 "st_get_density(un = 0x%p)\n", (void*)un);
7299 7297
7300 7298 ASSERT(mutex_owned(ST_MUTEX));
7301 7299
7302 7300 /*
7303 7301 * If Auto Density override is enabled The drive has
7304 7302 * only one density and there is no point in attempting
7305 7303 * find the correct one.
7306 7304 *
7307 7305 * Since most modern drives auto detect the density
7308 7306 * and format of the recorded media before they come
7309 7307 * ready. What this function does is a legacy behavior
7310 7308 * and modern drives not only don't need it, The backup
7311 7309 * utilities that do positioning via uscsi find the un-
7312 7310 * expected rewinds problematic.
7313 7311 *
7314 7312 * The drives that need this are old reel to reel devices.
7315 7313 * I took a swag and said they must be scsi-1 or older.
7316 7314 * I don't beleave there will any of the newer devices
7317 7315 * that need this. There will be some scsi-1 devices that
7318 7316 * don't need this but I don't think they will be using the
7319 7317 * BIG aftermarket backup and restore utilitys.
7320 7318 */
7321 7319 if ((un->un_dp->options & ST_AUTODEN_OVERRIDE) ||
7322 7320 (un->un_sd->sd_inq->inq_ansi > 1)) {
7323 7321 un->un_density_known = 1;
7324 7322 rval = 0;
7325 7323 goto exit;
7326 7324 }
7327 7325
7328 7326 /*
7329 7327 * This will only work on variable record length tapes
7330 7328 * if and only if all variable record length tapes autodensity
7331 7329 * select.
7332 7330 */
7333 7331 size = (unsigned)(un->un_dp->bsize ? un->un_dp->bsize : SECSIZE);
7334 7332 un->un_tmpbuf = kmem_alloc(size, KM_SLEEP);
7335 7333
7336 7334 /*
7337 7335 * Start at the specified density
7338 7336 */
7339 7337
7340 7338 dens = olddens = un->un_curdens = MT_DENSITY(un->un_dev);
7341 7339
7342 7340 for (i = 0; i < NDENSITIES; i++, ((un->un_curdens == NDENSITIES - 1) ?
7343 7341 (un->un_curdens = 0) : (un->un_curdens += 1))) {
7344 7342 /*
7345 7343 * If we've done this density before,
7346 7344 * don't bother to do it again.
7347 7345 */
7348 7346 dens = un->un_dp->densities[un->un_curdens];
7349 7347 if (i > 0 && dens == olddens)
7350 7348 continue;
7351 7349 olddens = dens;
7352 7350 ST_DEBUG6(ST_DEVINFO, st_label, SCSI_DEBUG,
7353 7351 "trying density 0x%x\n", dens);
7354 7352 if (st_set_density(un)) {
7355 7353 continue;
7356 7354 }
7357 7355
7358 7356 /*
7359 7357 * XXX - the creates lots of headaches and slowdowns - must
7360 7358 * fix.
7361 7359 */
7362 7360 succes = (st_cmd(un, SCMD_READ, (int)size, SYNC_CMD) == 0);
7363 7361 if (st_cmd(un, SCMD_REWIND, 0, SYNC_CMD)) {
7364 7362 break;
7365 7363 }
7366 7364 if (succes) {
7367 7365 st_init(un);
7368 7366 rval = 0;
7369 7367 un->un_density_known = 1;
7370 7368 break;
7371 7369 }
7372 7370 }
7373 7371 kmem_free(un->un_tmpbuf, size);
7374 7372 un->un_tmpbuf = 0;
7375 7373
7376 7374 exit:
7377 7375 ASSERT(mutex_owned(ST_MUTEX));
7378 7376 return (rval);
7379 7377 }
7380 7378
7381 7379 static int
7382 7380 st_set_density(struct scsi_tape *un)
7383 7381 {
7384 7382 int rval = 0;
7385 7383
7386 7384 ST_FUNC(ST_DEVINFO, st_set_density);
7387 7385
7388 7386 ST_DEBUG3(ST_DEVINFO, st_label, SCSI_DEBUG,
7389 7387 "st_set_density(un = 0x%p): density = 0x%x\n", (void*)un,
7390 7388 un->un_dp->densities[un->un_curdens]);
7391 7389
7392 7390 ASSERT(mutex_owned(ST_MUTEX));
7393 7391
7394 7392 un->un_mspl->density = un->un_dp->densities[un->un_curdens];
7395 7393
7396 7394 if ((un->un_dp->options & ST_AUTODEN_OVERRIDE) == 0) {
7397 7395 /*
7398 7396 * If auto density override is not set, Use mode select
7399 7397 * to set density and compression.
7400 7398 */
7401 7399 if (st_modeselect(un)) {
7402 7400 rval = -1;
7403 7401 }
7404 7402 } else if ((un->un_dp->options & ST_MODE_SEL_COMP) != 0) {
7405 7403 /*
7406 7404 * If auto density and mode select compression are set,
7407 7405 * This is a drive with one density code but compression
7408 7406 * can be enabled or disabled.
7409 7407 * Set compression but no need to set density.
7410 7408 */
7411 7409 rval = st_set_compression(un);
7412 7410 if ((rval != 0) && (rval != EALREADY)) {
7413 7411 rval = -1;
7414 7412 } else {
7415 7413 rval = 0;
7416 7414 }
7417 7415 }
7418 7416
7419 7417 /* If sucessful set density and/or compression, mark density known */
7420 7418 if (rval == 0) {
7421 7419 un->un_density_known = 1;
7422 7420 }
7423 7421
7424 7422 ASSERT(mutex_owned(ST_MUTEX));
7425 7423 return (rval);
7426 7424 }
7427 7425
7428 7426 static int
7429 7427 st_loadtape(struct scsi_tape *un)
7430 7428 {
7431 7429 int rval;
7432 7430
7433 7431 ST_FUNC(ST_DEVINFO, st_loadtape);
7434 7432
7435 7433 ST_DEBUG3(ST_DEVINFO, st_label, SCSI_DEBUG,
7436 7434 "st_loadtape(un = 0x%p)\n", (void*) un);
7437 7435
7438 7436 ASSERT(mutex_owned(ST_MUTEX));
7439 7437
7440 7438 rval = st_update_block_pos(un, st_cmd, 0);
7441 7439 if (rval == EACCES) {
7442 7440 return (rval);
7443 7441 }
7444 7442
7445 7443 /*
7446 7444 * 'LOAD' the tape to BOT by rewinding
7447 7445 */
7448 7446 rval = st_cmd(un, SCMD_REWIND, 1, SYNC_CMD);
7449 7447 if (rval == 0) {
7450 7448 st_init(un);
7451 7449 un->un_density_known = 0;
7452 7450 }
7453 7451
7454 7452 ASSERT(mutex_owned(ST_MUTEX));
7455 7453 return (rval);
7456 7454 }
7457 7455
7458 7456
7459 7457 /*
7460 7458 * Note: QIC devices aren't so smart. If you try to append
7461 7459 * after EOM, the write can fail because the device doesn't know
7462 7460 * it's at EOM. In that case, issue a read. The read should fail
7463 7461 * because there's no data, but the device knows it's at EOM,
7464 7462 * so a subsequent write should succeed. To further confuse matters,
7465 7463 * the target returns the same error if the tape is positioned
7466 7464 * such that a write would overwrite existing data. That's why
7467 7465 * we have to do the append test. A read in the middle of
7468 7466 * recorded data would succeed, thus indicating we're attempting
7469 7467 * something illegal.
7470 7468 */
7471 7469
7472 7470
7473 7471 static void
7474 7472 st_test_append(struct buf *bp)
7475 7473 {
7476 7474 dev_t dev = bp->b_edev;
7477 7475 struct scsi_tape *un;
7478 7476 uchar_t status;
7479 7477 unsigned bcount;
7480 7478
7481 7479 un = ddi_get_soft_state(st_state, MTUNIT(dev));
7482 7480
7483 7481 ST_FUNC(ST_DEVINFO, st_test_append);
7484 7482
7485 7483 ASSERT(mutex_owned(ST_MUTEX));
7486 7484
7487 7485 ST_DEBUG3(ST_DEVINFO, st_label, SCSI_DEBUG,
7488 7486 "st_test_append(): fileno %d\n", un->un_pos.fileno);
7489 7487
7490 7488 un->un_laststate = un->un_state;
7491 7489 un->un_state = ST_STATE_APPEND_TESTING;
7492 7490 un->un_test_append = 0;
7493 7491
7494 7492 /*
7495 7493 * first, map in the buffer, because we're doing a double write --
7496 7494 * first into the kernel, then onto the tape.
7497 7495 */
7498 7496 bp_mapin(bp);
7499 7497
7500 7498 /*
7501 7499 * get a copy of the data....
7502 7500 */
7503 7501 un->un_tmpbuf = kmem_alloc((unsigned)bp->b_bcount, KM_SLEEP);
7504 7502 bcopy(bp->b_un.b_addr, un->un_tmpbuf, (uint_t)bp->b_bcount);
7505 7503
7506 7504 /*
7507 7505 * attempt the write..
7508 7506 */
7509 7507
7510 7508 if (st_cmd(un, (int)SCMD_WRITE, (int)bp->b_bcount, SYNC_CMD) == 0) {
7511 7509 success:
7512 7510 ST_DEBUG6(ST_DEVINFO, st_label, SCSI_DEBUG,
7513 7511 "append write succeeded\n");
7514 7512 bp->b_resid = un->un_sbufp->b_resid;
7515 7513 mutex_exit(ST_MUTEX);
7516 7514 bcount = (unsigned)bp->b_bcount;
7517 7515 biodone(bp);
7518 7516 mutex_enter(ST_MUTEX);
7519 7517 un->un_laststate = un->un_state;
7520 7518 un->un_state = ST_STATE_OPEN;
7521 7519 kmem_free(un->un_tmpbuf, bcount);
7522 7520 un->un_tmpbuf = NULL;
7523 7521 return;
7524 7522 }
7525 7523
7526 7524 /*
7527 7525 * The append failed. Do a short read. If that fails, we are at EOM
7528 7526 * so we can retry the write command. If that succeeds, than we're
7529 7527 * all screwed up (the controller reported a real error).
7530 7528 *
7531 7529 * XXX: should the dummy read be > SECSIZE? should it be the device's
7532 7530 * XXX: block size?
7533 7531 *
7534 7532 */
7535 7533 status = un->un_status;
7536 7534 un->un_status = 0;
7537 7535 (void) st_cmd(un, SCMD_READ, SECSIZE, SYNC_CMD);
7538 7536 if (un->un_status == KEY_BLANK_CHECK) {
7539 7537 ST_DEBUG6(ST_DEVINFO, st_label, SCSI_DEBUG,
7540 7538 "append at EOM\n");
7541 7539 /*
7542 7540 * Okay- the read failed. We should actually have confused
7543 7541 * the controller enough to allow writing. In any case, the
7544 7542 * i/o is on its own from here on out.
7545 7543 */
7546 7544 un->un_laststate = un->un_state;
7547 7545 un->un_state = ST_STATE_OPEN;
7548 7546 bcopy(bp->b_un.b_addr, un->un_tmpbuf, (uint_t)bp->b_bcount);
7549 7547 if (st_cmd(un, (int)SCMD_WRITE, (int)bp->b_bcount,
7550 7548 SYNC_CMD) == 0) {
7551 7549 goto success;
7552 7550 }
7553 7551 }
7554 7552
7555 7553 ST_DEBUG6(ST_DEVINFO, st_label, SCSI_DEBUG,
7556 7554 "append write failed- not at EOM\n");
7557 7555 bp->b_resid = bp->b_bcount;
7558 7556 st_bioerror(bp, EIO);
7559 7557
7560 7558 ST_DEBUG2(ST_DEVINFO, st_label, SCSI_DEBUG,
7561 7559 "st_test_append : EIO : append write failed - not at EOM");
7562 7560
7563 7561 /*
7564 7562 * backspace one record to get back to where we were
7565 7563 */
7566 7564 if (st_cmd(un, SCMD_SPACE, Blk(-1), SYNC_CMD)) {
7567 7565 un->un_pos.pmode = invalid;
7568 7566 }
7569 7567
7570 7568 un->un_err_resid = bp->b_resid;
7571 7569 un->un_status = status;
7572 7570
7573 7571 /*
7574 7572 * Note: biodone will do a bp_mapout()
7575 7573 */
7576 7574 mutex_exit(ST_MUTEX);
7577 7575 bcount = (unsigned)bp->b_bcount;
7578 7576 biodone(bp);
7579 7577 mutex_enter(ST_MUTEX);
7580 7578 un->un_laststate = un->un_state;
7581 7579 un->un_state = ST_STATE_OPEN_PENDING_IO;
7582 7580 kmem_free(un->un_tmpbuf, bcount);
7583 7581 un->un_tmpbuf = NULL;
7584 7582 }
7585 7583
7586 7584 /*
7587 7585 * Special command handler
7588 7586 */
7589 7587
7590 7588 /*
7591 7589 * common st_cmd code. The fourth parameter states
7592 7590 * whether the caller wishes to await the results
7593 7591 * Note the release of the mutex during most of the function
7594 7592 */
7595 7593 static int
7596 7594 st_cmd(struct scsi_tape *un, int com, int64_t count, int wait)
7597 7595 {
7598 7596 struct buf *bp;
7599 7597 int err;
7600 7598 uint_t last_err_resid;
7601 7599
7602 7600 ST_FUNC(ST_DEVINFO, st_cmd);
7603 7601
7604 7602 ST_DEBUG3(ST_DEVINFO, st_label, SCSI_DEBUG,
7605 7603 "st_cmd(dev = 0x%lx, com = 0x%x, count = %"PRIx64", wait = %d)\n",
7606 7604 un->un_dev, com, count, wait);
7607 7605
7608 7606 ASSERT(MUTEX_HELD(&un->un_sd->sd_mutex));
7609 7607 ASSERT(mutex_owned(ST_MUTEX));
7610 7608
7611 7609 #ifdef STDEBUG
7612 7610 if ((st_debug & 0x7)) {
7613 7611 st_debug_cmds(un, com, count, wait);
7614 7612 }
7615 7613 #endif
7616 7614
7617 7615 st_wait_for_io(un);
7618 7616
7619 7617 /* check to see if this command requires the drive to be reserved */
7620 7618 err = st_check_cmd_for_need_to_reserve(un, com, count);
7621 7619
7622 7620 if (err) {
7623 7621 return (err);
7624 7622 }
7625 7623
7626 7624 /*
7627 7625 * A space command is not recoverable if we don't know were we
7628 7626 * were when it was issued.
7629 7627 */
7630 7628 if ((com == SCMD_SPACE) || (com == SCMD_SPACE_G4)) {
7631 7629 (void) st_update_block_pos(un, st_cmd, 0);
7632 7630 }
7633 7631
7634 7632 /*
7635 7633 * Forground should not be doing anything while recovery is active.
7636 7634 */
7637 7635 ASSERT(un->un_recov_buf_busy == 0);
7638 7636
7639 7637 while (un->un_sbuf_busy)
7640 7638 cv_wait(&un->un_sbuf_cv, ST_MUTEX);
7641 7639 un->un_sbuf_busy = 1;
7642 7640
7643 7641 bp = un->un_sbufp;
7644 7642 bzero(bp, sizeof (buf_t));
7645 7643
7646 7644 bp->b_flags = (wait) ? B_BUSY : B_BUSY|B_ASYNC;
7647 7645
7648 7646 err = st_setup_cmd(un, bp, com, count);
7649 7647
7650 7648 un->un_sbuf_busy = 0;
7651 7649
7652 7650 /*
7653 7651 * If was a space command need to update logical block position.
7654 7652 * Only do this if the command was sucessful or it will mask the fact
7655 7653 * that the space command failed by promoting the pmode to logical.
7656 7654 */
7657 7655 if (((com == SCMD_SPACE) || (com == SCMD_SPACE_G4)) &&
7658 7656 (un->un_pos.pmode != invalid)) {
7659 7657 un->un_running.pmode = invalid;
7660 7658 last_err_resid = un->un_err_resid;
7661 7659 (void) st_update_block_pos(un, st_cmd, 1);
7662 7660 /*
7663 7661 * Set running position to invalid so it updates on the
7664 7662 * next command.
7665 7663 */
7666 7664 un->un_running.pmode = invalid;
7667 7665 un->un_err_resid = last_err_resid;
7668 7666 }
7669 7667
7670 7668 cv_signal(&un->un_sbuf_cv);
7671 7669
7672 7670 return (err);
7673 7671 }
7674 7672
7675 7673 static int
7676 7674 st_setup_cmd(struct scsi_tape *un, buf_t *bp, int com, int64_t count)
7677 7675 {
7678 7676 int err;
7679 7677 dev_t dev = un->un_dev;
7680 7678
7681 7679 ST_FUNC(ST_DEVINFO, st_setup_cmd);
7682 7680 /*
7683 7681 * Set count to the actual size of the data tranfer.
7684 7682 * For commands with no data transfer, set bp->b_bcount
7685 7683 * to the value to be used when constructing the
7686 7684 * cdb in st_make_cmd().
7687 7685 */
7688 7686 switch (com) {
7689 7687 case SCMD_READ:
7690 7688 ST_DEBUG6(ST_DEVINFO, st_label, SCSI_DEBUG,
7691 7689 "special read %"PRId64"\n", count);
7692 7690 bp->b_flags |= B_READ;
7693 7691 bp->b_un.b_addr = un->un_tmpbuf;
7694 7692 break;
7695 7693
7696 7694 case SCMD_WRITE:
7697 7695 ST_DEBUG6(ST_DEVINFO, st_label, SCSI_DEBUG,
7698 7696 "special write %"PRId64"\n", count);
7699 7697 bp->b_un.b_addr = un->un_tmpbuf;
7700 7698 break;
7701 7699
7702 7700 case SCMD_WRITE_FILE_MARK:
7703 7701 ST_DEBUG6(ST_DEVINFO, st_label, SCSI_DEBUG,
7704 7702 "write %"PRId64" file marks\n", count);
7705 7703 bp->b_bcount = count;
7706 7704 count = 0;
7707 7705 break;
7708 7706
7709 7707 case SCMD_REWIND:
7710 7708 ST_DEBUG6(ST_DEVINFO, st_label, SCSI_DEBUG, "rewind\n");
7711 7709 bp->b_bcount = count;
7712 7710 count = 0;
7713 7711 break;
7714 7712
7715 7713 case SCMD_SPACE:
7716 7714 ST_DEBUG6(ST_DEVINFO, st_label, SCSI_DEBUG, "space\n");
7717 7715 /*
7718 7716 * If the user could have entered a number that will
7719 7717 * not fit in the 12 bit count field of space(8),
7720 7718 * use space(16).
7721 7719 */
7722 7720 if (((int64_t)SPACE_CNT(count) > 0x7fffff) ||
7723 7721 ((int64_t)SPACE_CNT(count) < -(0x7fffff))) {
7724 7722 com = SCMD_SPACE_G4;
7725 7723 }
7726 7724 bp->b_bcount = count;
7727 7725 count = 0;
7728 7726 break;
7729 7727
7730 7728 case SCMD_RESERVE:
7731 7729 ST_DEBUG6(ST_DEVINFO, st_label, SCSI_DEBUG, "reserve");
7732 7730 bp->b_bcount = 0;
7733 7731 count = 0;
7734 7732 break;
7735 7733
7736 7734 case SCMD_RELEASE:
7737 7735 ST_DEBUG6(ST_DEVINFO, st_label, SCSI_DEBUG, "release");
7738 7736 bp->b_bcount = 0;
7739 7737 count = 0;
7740 7738 break;
7741 7739
7742 7740 case SCMD_LOAD:
7743 7741 ST_DEBUG6(ST_DEVINFO, st_label, SCSI_DEBUG,
7744 7742 "%s tape\n", (count & LD_LOAD) ? "load" : "unload");
7745 7743 bp->b_bcount = count;
7746 7744 count = 0;
7747 7745 break;
7748 7746
7749 7747 case SCMD_ERASE:
7750 7748 ST_DEBUG6(ST_DEVINFO, st_label, SCSI_DEBUG,
7751 7749 "erase tape\n");
7752 7750 bp->b_bcount = count;
7753 7751 count = 0;
7754 7752 break;
7755 7753
7756 7754 case SCMD_MODE_SENSE:
7757 7755 ST_DEBUG6(ST_DEVINFO, st_label, SCSI_DEBUG,
7758 7756 "mode sense\n");
7759 7757 bp->b_flags |= B_READ;
7760 7758 bp->b_un.b_addr = (caddr_t)(un->un_mspl);
7761 7759 break;
7762 7760
7763 7761 case SCMD_MODE_SELECT:
7764 7762 ST_DEBUG6(ST_DEVINFO, st_label, SCSI_DEBUG,
7765 7763 "mode select\n");
7766 7764 bp->b_un.b_addr = (caddr_t)(un->un_mspl);
7767 7765 break;
7768 7766
7769 7767 case SCMD_READ_BLKLIM:
7770 7768 ST_DEBUG6(ST_DEVINFO, st_label, SCSI_DEBUG,
7771 7769 "read block limits\n");
7772 7770 bp->b_bcount = count;
7773 7771 bp->b_flags |= B_READ;
7774 7772 bp->b_un.b_addr = (caddr_t)(un->un_rbl);
7775 7773 break;
7776 7774
7777 7775 case SCMD_TEST_UNIT_READY:
7778 7776 ST_DEBUG6(ST_DEVINFO, st_label, SCSI_DEBUG,
7779 7777 "test unit ready\n");
7780 7778 bp->b_bcount = 0;
7781 7779 count = 0;
7782 7780 break;
7783 7781
7784 7782 case SCMD_DOORLOCK:
7785 7783 ST_DEBUG6(ST_DEVINFO, st_label, SCSI_DEBUG,
7786 7784 "%s tape\n", (count & MR_LOCK) ? "lock" : "unlock");
7787 7785 bp->b_bcount = count = 0;
7788 7786 break;
7789 7787
7790 7788 case SCMD_READ_POSITION:
7791 7789 ST_DEBUG6(ST_DEVINFO, st_label, SCSI_DEBUG,
7792 7790 "read position\n");
7793 7791 switch (un->un_read_pos_type) {
7794 7792 case LONG_POS:
7795 7793 count = sizeof (tape_position_long_t);
7796 7794 break;
7797 7795 case EXT_POS:
7798 7796 count = min(count, sizeof (tape_position_ext_t));
7799 7797 break;
7800 7798 case SHORT_POS:
7801 7799 count = sizeof (tape_position_t);
7802 7800 break;
7803 7801 default:
7804 7802 ST_DEBUG(ST_DEVINFO, st_label, CE_PANIC,
7805 7803 "Unknown read position type 0x%x in "
7806 7804 "st_make_cmd()\n", un->un_read_pos_type);
7807 7805 }
7808 7806 bp->b_bcount = count;
7809 7807 bp->b_flags |= B_READ;
7810 7808 bp->b_un.b_addr = (caddr_t)un->un_read_pos_data;
7811 7809 break;
7812 7810
7813 7811 default:
7814 7812 ST_DEBUG(ST_DEVINFO, st_label, CE_PANIC,
7815 7813 "Unhandled scsi command 0x%x in st_setup_cmd()\n", com);
7816 7814 }
7817 7815
7818 7816 mutex_exit(ST_MUTEX);
7819 7817
7820 7818 if (count > 0) {
7821 7819 int flg = (bp->b_flags & B_READ) ? B_READ : B_WRITE;
7822 7820 /*
7823 7821 * We're going to do actual I/O.
7824 7822 * Set things up for physio.
7825 7823 */
7826 7824 struct iovec aiov;
7827 7825 struct uio auio;
7828 7826 struct uio *uio = &auio;
7829 7827
7830 7828 bzero(&auio, sizeof (struct uio));
7831 7829 bzero(&aiov, sizeof (struct iovec));
7832 7830 aiov.iov_base = bp->b_un.b_addr;
7833 7831 aiov.iov_len = count;
7834 7832
7835 7833 uio->uio_iov = &aiov;
7836 7834 uio->uio_iovcnt = 1;
7837 7835 uio->uio_resid = aiov.iov_len;
7838 7836 uio->uio_segflg = UIO_SYSSPACE;
7839 7837
7840 7838 /*
7841 7839 * Let physio do the rest...
7842 7840 */
7843 7841 bp->b_forw = (struct buf *)(uintptr_t)com;
7844 7842 bp->b_back = NULL;
7845 7843 err = physio(st_strategy, bp, dev, flg, st_minphys, uio);
7846 7844 ST_DEBUG6(ST_DEVINFO, st_label, SCSI_DEBUG,
7847 7845 "st_setup_cmd: physio returns %d\n", err);
7848 7846 } else {
7849 7847 /*
7850 7848 * Mimic physio
7851 7849 */
7852 7850 bp->b_forw = (struct buf *)(uintptr_t)com;
7853 7851 bp->b_back = NULL;
7854 7852 bp->b_edev = dev;
7855 7853 bp->b_dev = cmpdev(dev);
7856 7854 bp->b_blkno = 0;
7857 7855 bp->b_resid = 0;
7858 7856 (void) st_strategy(bp);
7859 7857 if (bp->b_flags & B_ASYNC) {
7860 7858 /*
7861 7859 * This is an async command- the caller won't wait
7862 7860 * and doesn't care about errors.
7863 7861 */
7864 7862 mutex_enter(ST_MUTEX);
7865 7863 return (0);
7866 7864 }
7867 7865
7868 7866 /*
7869 7867 * BugTraq #4260046
7870 7868 * ----------------
7871 7869 * Restore Solaris 2.5.1 behavior, namely call biowait
7872 7870 * unconditionally. The old comment said...
7873 7871 *
7874 7872 * "if strategy was flagged with persistent errors, we would
7875 7873 * have an error here, and the bp would never be sent, so we
7876 7874 * don't want to wait on a bp that was never sent...or hang"
7877 7875 *
7878 7876 * The new rationale, courtesy of Chitrank...
7879 7877 *
7880 7878 * "we should unconditionally biowait() here because
7881 7879 * st_strategy() will do a biodone() in the persistent error
7882 7880 * case and the following biowait() will return immediately.
7883 7881 * If not, in the case of "errors after pkt alloc" in
7884 7882 * st_start(), we will not biowait here which will cause the
7885 7883 * next biowait() to return immediately which will cause
7886 7884 * us to send out the next command. In the case where both of
7887 7885 * these use the sbuf, when the first command completes we'll
7888 7886 * free the packet attached to sbuf and the same pkt will
7889 7887 * get freed again when we complete the second command.
7890 7888 * see esc 518987. BTW, it is necessary to do biodone() in
7891 7889 * st_start() for the pkt alloc failure case because physio()
7892 7890 * does biowait() and will hang if we don't do biodone()"
7893 7891 */
7894 7892
7895 7893 err = biowait(bp);
7896 7894 ST_DEBUG6(ST_DEVINFO, st_label, SCSI_DEBUG,
7897 7895 "st_setup_cmd: biowait returns %d\n", err);
7898 7896 }
7899 7897
7900 7898 mutex_enter(ST_MUTEX);
7901 7899
7902 7900 return (err);
7903 7901 }
7904 7902
7905 7903 static int
7906 7904 st_set_compression(struct scsi_tape *un)
7907 7905 {
7908 7906 int rval;
7909 7907 int turn_compression_on;
7910 7908 minor_t minor;
7911 7909
7912 7910 ST_FUNC(ST_DEVINFO, st_set_compression);
7913 7911
7914 7912 /*
7915 7913 * Drive either dosn't have compression or it is controlled with
7916 7914 * special density codes. Return ENOTTY so caller
7917 7915 * knows nothing was done.
7918 7916 */
7919 7917 if ((un->un_dp->options & ST_MODE_SEL_COMP) == 0) {
7920 7918 un->un_comp_page = 0;
7921 7919 return (ENOTTY);
7922 7920 }
7923 7921
7924 7922 /* set compression based on minor node opened */
7925 7923 minor = MT_DENSITY(un->un_dev);
7926 7924
7927 7925 /*
7928 7926 * If this the compression density or
7929 7927 * the drive has two densities and uses mode select for
7930 7928 * control of compression turn on compression for MT_DENSITY2
7931 7929 * as well.
7932 7930 */
7933 7931 if ((minor == ST_COMPRESSION_DENSITY) ||
7934 7932 (minor == MT_DENSITY(MT_DENSITY2)) &&
7935 7933 (un->un_dp->densities[0] == un->un_dp->densities[1]) &&
7936 7934 (un->un_dp->densities[2] == un->un_dp->densities[3]) &&
7937 7935 (un->un_dp->densities[0] != un->un_dp->densities[2])) {
7938 7936
7939 7937 turn_compression_on = 1;
7940 7938 } else {
7941 7939 turn_compression_on = 0;
7942 7940 }
7943 7941
7944 7942 un->un_mspl->high_bl = (uchar_t)(un->un_bsize >> 16);
7945 7943 un->un_mspl->mid_bl = (uchar_t)(un->un_bsize >> 8);
7946 7944 un->un_mspl->low_bl = (uchar_t)(un->un_bsize);
7947 7945
7948 7946 /*
7949 7947 * Need to determine which page does the device use for compression.
7950 7948 * First try the data compression page. If this fails try the device
7951 7949 * configuration page
7952 7950 */
7953 7951
7954 7952 if ((un->un_comp_page & ST_DEV_DATACOMP_PAGE) == ST_DEV_DATACOMP_PAGE) {
7955 7953 rval = st_set_datacomp_page(un, turn_compression_on);
7956 7954 if (rval == EALREADY) {
7957 7955 return (rval);
7958 7956 }
7959 7957 if (rval != 0) {
7960 7958 if (un->un_status == KEY_ILLEGAL_REQUEST) {
7961 7959 /*
7962 7960 * This device does not support data
7963 7961 * compression page
7964 7962 */
7965 7963 un->un_comp_page = ST_DEV_CONFIG_PAGE;
7966 7964 } else if (un->un_state >= ST_STATE_OPEN) {
7967 7965 un->un_pos.pmode = invalid;
7968 7966 rval = EIO;
7969 7967 } else {
7970 7968 rval = -1;
7971 7969 }
7972 7970 } else {
7973 7971 un->un_comp_page = ST_DEV_DATACOMP_PAGE;
7974 7972 }
7975 7973 }
7976 7974
7977 7975 if ((un->un_comp_page & ST_DEV_CONFIG_PAGE) == ST_DEV_CONFIG_PAGE) {
7978 7976 rval = st_set_devconfig_page(un, turn_compression_on);
7979 7977 if (rval == EALREADY) {
7980 7978 return (rval);
7981 7979 }
7982 7980 if (rval != 0) {
7983 7981 if (un->un_status == KEY_ILLEGAL_REQUEST) {
7984 7982 /*
7985 7983 * This device does not support
7986 7984 * compression at all advice the
7987 7985 * user and unset ST_MODE_SEL_COMP
7988 7986 */
7989 7987 un->un_dp->options &= ~ST_MODE_SEL_COMP;
7990 7988 un->un_comp_page = 0;
7991 7989 scsi_log(ST_DEVINFO, st_label, CE_NOTE,
7992 7990 "Device Does Not Support Compression\n");
7993 7991 } else if (un->un_state >= ST_STATE_OPEN) {
7994 7992 un->un_pos.pmode = invalid;
7995 7993 rval = EIO;
7996 7994 } else {
7997 7995 rval = -1;
7998 7996 }
7999 7997 }
8000 7998 }
8001 7999
8002 8000 return (rval);
8003 8001 }
8004 8002
8005 8003 /*
8006 8004 * set or unset compression thru device configuration page.
8007 8005 */
8008 8006 static int
8009 8007 st_set_devconfig_page(struct scsi_tape *un, int compression_on)
8010 8008 {
8011 8009 unsigned char cflag;
8012 8010 int rval = 0;
8013 8011
8014 8012
8015 8013 ST_FUNC(ST_DEVINFO, st_set_devconfig_page);
8016 8014
8017 8015 ASSERT(mutex_owned(ST_MUTEX));
8018 8016
8019 8017 /*
8020 8018 * if the mode sense page is not the correct one, load the correct one.
8021 8019 */
8022 8020 if (un->un_mspl->page_code != ST_DEV_CONFIG_PAGE) {
8023 8021 rval = st_gen_mode_sense(un, st_uscsi_cmd, ST_DEV_CONFIG_PAGE,
8024 8022 un->un_mspl, sizeof (struct seq_mode));
8025 8023 if (rval)
8026 8024 return (rval);
8027 8025 }
8028 8026
8029 8027 /*
8030 8028 * Figure what to set compression flag to.
8031 8029 */
8032 8030 if (compression_on) {
8033 8031 /* They have selected a compression node */
8034 8032 if (un->un_dp->type == ST_TYPE_FUJI) {
8035 8033 cflag = 0x84; /* use EDRC */
8036 8034 } else {
8037 8035 cflag = ST_DEV_CONFIG_DEF_COMP;
8038 8036 }
8039 8037 } else {
8040 8038 cflag = ST_DEV_CONFIG_NO_COMP;
8041 8039 }
8042 8040
8043 8041 /*
8044 8042 * If compression is already set the way it was requested.
8045 8043 * And if this not the first time we has tried.
8046 8044 */
8047 8045 if ((cflag == un->un_mspl->page.dev.comp_alg) &&
8048 8046 (un->un_comp_page == ST_DEV_CONFIG_PAGE)) {
8049 8047 return (EALREADY);
8050 8048 }
8051 8049
8052 8050 un->un_mspl->page.dev.comp_alg = cflag;
8053 8051 /*
8054 8052 * need to send mode select even if correct compression is
8055 8053 * already set since need to set density code
8056 8054 */
8057 8055
8058 8056 #ifdef STDEBUG
8059 8057 if ((st_debug & 0x7) >= 6) {
8060 8058 st_clean_print(ST_DEVINFO, st_label, SCSI_DEBUG,
8061 8059 "st_set_devconfig_page: sense data for mode select",
8062 8060 (char *)un->un_mspl, sizeof (struct seq_mode));
8063 8061 }
8064 8062 #endif
8065 8063 rval = st_gen_mode_select(un, st_uscsi_cmd, un->un_mspl,
8066 8064 sizeof (struct seq_mode));
8067 8065
8068 8066 return (rval);
8069 8067 }
8070 8068
8071 8069 /*
8072 8070 * set/reset compression bit thru data compression page
8073 8071 */
8074 8072 static int
8075 8073 st_set_datacomp_page(struct scsi_tape *un, int compression_on)
8076 8074 {
8077 8075 int compression_on_already;
8078 8076 int rval = 0;
8079 8077
8080 8078
8081 8079 ST_FUNC(ST_DEVINFO, st_set_datacomp_page);
8082 8080
8083 8081 ASSERT(mutex_owned(ST_MUTEX));
8084 8082
8085 8083 /*
8086 8084 * if the mode sense page is not the correct one, load the correct one.
8087 8085 */
8088 8086 if (un->un_mspl->page_code != ST_DEV_DATACOMP_PAGE) {
8089 8087 rval = st_gen_mode_sense(un, st_uscsi_cmd, ST_DEV_DATACOMP_PAGE,
8090 8088 un->un_mspl, sizeof (struct seq_mode));
8091 8089 if (rval)
8092 8090 return (rval);
8093 8091 }
8094 8092
8095 8093 /*
8096 8094 * If drive is not capable of compression (at this time)
8097 8095 * return EALREADY so caller doesn't think that this page
8098 8096 * is not supported. This check is for drives that can
8099 8097 * disable compression from the front panel or configuration.
8100 8098 * I doubt that a drive that supports this page is not really
8101 8099 * capable of compression.
8102 8100 */
8103 8101 if (un->un_mspl->page.comp.dcc == 0) {
8104 8102 return (EALREADY);
8105 8103 }
8106 8104
8107 8105 /* See if compression currently turned on */
8108 8106 if (un->un_mspl->page.comp.dce) {
8109 8107 compression_on_already = 1;
8110 8108 } else {
8111 8109 compression_on_already = 0;
8112 8110 }
8113 8111
8114 8112 /*
8115 8113 * If compression is already set the way it was requested.
8116 8114 * And if this not the first time we has tried.
8117 8115 */
8118 8116 if ((compression_on == compression_on_already) &&
8119 8117 (un->un_comp_page == ST_DEV_DATACOMP_PAGE)) {
8120 8118 return (EALREADY);
8121 8119 }
8122 8120
8123 8121 /*
8124 8122 * if we are already set to the appropriate compression
8125 8123 * mode, don't set it again
8126 8124 */
8127 8125 if (compression_on) {
8128 8126 /* compression selected */
8129 8127 un->un_mspl->page.comp.dce = 1;
8130 8128 } else {
8131 8129 un->un_mspl->page.comp.dce = 0;
8132 8130 }
8133 8131
8134 8132
8135 8133 #ifdef STDEBUG
8136 8134 if ((st_debug & 0x7) >= 6) {
8137 8135 st_clean_print(ST_DEVINFO, st_label, SCSI_DEBUG,
8138 8136 "st_set_datacomp_page: sense data for mode select",
8139 8137 (char *)un->un_mspl, sizeof (struct seq_mode));
8140 8138 }
8141 8139 #endif
8142 8140 rval = st_gen_mode_select(un, st_uscsi_cmd, un->un_mspl,
8143 8141 sizeof (struct seq_mode));
8144 8142
8145 8143 return (rval);
8146 8144 }
8147 8145
8148 8146 static int
8149 8147 st_modesense(struct scsi_tape *un)
8150 8148 {
8151 8149 int rval;
8152 8150 uchar_t page;
8153 8151
8154 8152 ST_FUNC(ST_DEVINFO, st_modesense);
8155 8153
8156 8154 page = un->un_comp_page;
8157 8155
8158 8156 switch (page) {
8159 8157 case ST_DEV_DATACOMP_PAGE:
8160 8158 case ST_DEV_CONFIG_PAGE: /* FALLTHROUGH */
8161 8159 rval = st_gen_mode_sense(un, st_uscsi_cmd, page, un->un_mspl,
8162 8160 sizeof (struct seq_mode));
8163 8161 break;
8164 8162
8165 8163 case ST_DEV_DATACOMP_PAGE | ST_DEV_CONFIG_PAGE:
8166 8164 if (un->un_dp->options & ST_MODE_SEL_COMP) {
8167 8165 page = ST_DEV_DATACOMP_PAGE;
8168 8166 rval = st_gen_mode_sense(un, st_uscsi_cmd, page,
8169 8167 un->un_mspl, sizeof (struct seq_mode));
8170 8168 if (rval == 0 && un->un_mspl->page_code == page) {
8171 8169 un->un_comp_page = page;
8172 8170 break;
8173 8171 }
8174 8172 page = ST_DEV_CONFIG_PAGE;
8175 8173 rval = st_gen_mode_sense(un, st_uscsi_cmd, page,
8176 8174 un->un_mspl, sizeof (struct seq_mode));
8177 8175 if (rval == 0 && un->un_mspl->page_code == page) {
8178 8176 un->un_comp_page = page;
8179 8177 break;
8180 8178 }
8181 8179 un->un_dp->options &= ~ST_MODE_SEL_COMP;
8182 8180 un->un_comp_page = 0;
8183 8181 } else {
8184 8182 un->un_comp_page = 0;
8185 8183 }
8186 8184
8187 8185 default: /* FALLTHROUGH */
8188 8186 rval = st_cmd(un, SCMD_MODE_SENSE, MSIZE, SYNC_CMD);
8189 8187 }
8190 8188 return (rval);
8191 8189 }
8192 8190
8193 8191 static int
8194 8192 st_modeselect(struct scsi_tape *un)
8195 8193 {
8196 8194 int rval = 0;
8197 8195 int ix;
8198 8196
8199 8197 ST_FUNC(ST_DEVINFO, st_modeselect);
8200 8198
8201 8199 ST_DEBUG3(ST_DEVINFO, st_label, SCSI_DEBUG,
8202 8200 "st_modeselect(dev = 0x%lx): density = 0x%x\n",
8203 8201 un->un_dev, un->un_mspl->density);
8204 8202
8205 8203 ASSERT(mutex_owned(ST_MUTEX));
8206 8204
8207 8205 /*
8208 8206 * The parameter list should be the same for all of the
8209 8207 * cases that follow so set them here
8210 8208 *
8211 8209 * Try mode select first if if fails set fields manually
8212 8210 */
8213 8211 rval = st_modesense(un);
8214 8212 if (rval != 0) {
8215 8213 ST_DEBUG3(ST_DEVINFO, st_label, CE_WARN,
8216 8214 "st_modeselect: First mode sense failed\n");
8217 8215 un->un_mspl->bd_len = 8;
8218 8216 un->un_mspl->high_nb = 0;
8219 8217 un->un_mspl->mid_nb = 0;
8220 8218 un->un_mspl->low_nb = 0;
8221 8219 }
8222 8220 un->un_mspl->high_bl = (uchar_t)(un->un_bsize >> 16);
8223 8221 un->un_mspl->mid_bl = (uchar_t)(un->un_bsize >> 8);
8224 8222 un->un_mspl->low_bl = (uchar_t)(un->un_bsize);
8225 8223
8226 8224
8227 8225 /*
8228 8226 * If configured to use a specific density code for a media type.
8229 8227 * curdens is previously set by the minor node opened.
8230 8228 * If the media type doesn't match the minor node we change it so it
8231 8229 * looks like the correct one was opened.
8232 8230 */
8233 8231 if (un->un_dp->options & ST_KNOWS_MEDIA) {
8234 8232 uchar_t best;
8235 8233
8236 8234 for (best = 0xff, ix = 0; ix < NDENSITIES; ix++) {
8237 8235 if (un->un_mspl->media_type ==
8238 8236 un->un_dp->mediatype[ix]) {
8239 8237 best = ix;
8240 8238 /*
8241 8239 * It matches but it might not be the only one.
8242 8240 * Use the highest matching media type but not
8243 8241 * to exceed the density selected by the open.
8244 8242 */
8245 8243 if (ix < un->un_curdens) {
8246 8244 continue;
8247 8245 }
8248 8246 un->un_curdens = ix;
8249 8247 break;
8250 8248 }
8251 8249 }
8252 8250 /* If a match was found best will not be 0xff any more */
8253 8251 if (best < NDENSITIES) {
8254 8252 ST_DEBUG3(ST_DEVINFO, st_label, CE_WARN,
8255 8253 "found media 0x%X using density 0x%X\n",
8256 8254 un->un_mspl->media_type,
8257 8255 un->un_dp->densities[best]);
8258 8256 un->un_mspl->density = un->un_dp->densities[best];
8259 8257 } else {
8260 8258 /* Otherwise set density based on minor node opened */
8261 8259 un->un_mspl->density =
8262 8260 un->un_dp->densities[un->un_curdens];
8263 8261 }
8264 8262 } else {
8265 8263 un->un_mspl->density = un->un_dp->densities[un->un_curdens];
8266 8264 }
8267 8265
8268 8266 if (un->un_dp->options & ST_NOBUF) {
8269 8267 un->un_mspl->bufm = 0;
8270 8268 } else {
8271 8269 un->un_mspl->bufm = 1;
8272 8270 }
8273 8271
8274 8272 rval = st_set_compression(un);
8275 8273
8276 8274 /*
8277 8275 * If st_set_compression returned invalid or already it
8278 8276 * found no need to do the mode select.
8279 8277 * So do it here.
8280 8278 */
8281 8279 if ((rval == ENOTTY) || (rval == EALREADY)) {
8282 8280
8283 8281 /* Zero non-writeable fields */
8284 8282 un->un_mspl->data_len = 0;
8285 8283 un->un_mspl->media_type = 0;
8286 8284 un->un_mspl->wp = 0;
8287 8285
8288 8286 /* need to set the density code */
8289 8287 rval = st_cmd(un, SCMD_MODE_SELECT, MSIZE, SYNC_CMD);
8290 8288 if (rval != 0) {
8291 8289 if (un->un_state >= ST_STATE_OPEN) {
8292 8290 ST_DEBUG6(ST_DEVINFO, st_label, CE_WARN,
8293 8291 "unable to set tape mode\n");
8294 8292 un->un_pos.pmode = invalid;
8295 8293 rval = EIO;
8296 8294 } else {
8297 8295 rval = -1;
8298 8296 }
8299 8297 }
8300 8298 }
8301 8299
8302 8300 /*
8303 8301 * The spec recommends to send a mode sense after a mode select
8304 8302 */
8305 8303 (void) st_modesense(un);
8306 8304
8307 8305 ASSERT(mutex_owned(ST_MUTEX));
8308 8306
8309 8307 return (rval);
8310 8308 }
8311 8309
8312 8310 /*
8313 8311 * st_gen_mode_sense
8314 8312 *
8315 8313 * generic mode sense.. it allows for any page
8316 8314 */
8317 8315 static int
8318 8316 st_gen_mode_sense(struct scsi_tape *un, ubufunc_t ubf, int page,
8319 8317 struct seq_mode *page_data, int page_size)
8320 8318 {
8321 8319
8322 8320 int r;
8323 8321 char cdb[CDB_GROUP0];
8324 8322 struct uscsi_cmd *com;
8325 8323 struct scsi_arq_status status;
8326 8324
8327 8325 ST_FUNC(ST_DEVINFO, st_gen_mode_sense);
8328 8326
8329 8327 com = kmem_zalloc(sizeof (*com), KM_SLEEP);
8330 8328
8331 8329 bzero(cdb, CDB_GROUP0);
8332 8330 cdb[0] = SCMD_MODE_SENSE;
8333 8331 cdb[2] = (char)page;
8334 8332 cdb[4] = (char)page_size;
8335 8333
8336 8334 com->uscsi_cdb = cdb;
8337 8335 com->uscsi_cdblen = CDB_GROUP0;
8338 8336 com->uscsi_bufaddr = (caddr_t)page_data;
8339 8337 com->uscsi_buflen = page_size;
8340 8338 com->uscsi_rqlen = sizeof (status);
8341 8339 com->uscsi_rqbuf = (caddr_t)&status;
8342 8340 com->uscsi_timeout = un->un_dp->non_motion_timeout;
8343 8341 com->uscsi_flags = USCSI_DIAGNOSE | USCSI_RQENABLE | USCSI_READ;
8344 8342
8345 8343 r = ubf(un, com, FKIOCTL);
8346 8344 kmem_free(com, sizeof (*com));
8347 8345 return (r);
8348 8346 }
8349 8347
8350 8348 /*
8351 8349 * st_gen_mode_select
8352 8350 *
8353 8351 * generic mode select.. it allows for any page
8354 8352 */
8355 8353 static int
8356 8354 st_gen_mode_select(struct scsi_tape *un, ubufunc_t ubf,
8357 8355 struct seq_mode *page_data, int page_size)
8358 8356 {
8359 8357
8360 8358 int r;
8361 8359 char cdb[CDB_GROUP0];
8362 8360 struct uscsi_cmd *com;
8363 8361 struct scsi_arq_status status;
8364 8362
8365 8363 ST_FUNC(ST_DEVINFO, st_gen_mode_select);
8366 8364
8367 8365 /* Zero non-writeable fields */
8368 8366 page_data->data_len = 0;
8369 8367 page_data->media_type = 0;
8370 8368 page_data->wp = 0;
8371 8369
8372 8370 /*
8373 8371 * If mode select has any page data, zero the ps (Page Savable) bit.
8374 8372 */
8375 8373 if (page_size > MSIZE) {
8376 8374 page_data->ps = 0;
8377 8375 }
8378 8376
8379 8377
8380 8378 com = kmem_zalloc(sizeof (*com), KM_SLEEP);
8381 8379
8382 8380 /*
8383 8381 * then, do a mode select to set what ever info
8384 8382 */
8385 8383 bzero(cdb, CDB_GROUP0);
8386 8384 cdb[0] = SCMD_MODE_SELECT;
8387 8385 cdb[1] = 0x10; /* set PF bit for many third party drives */
8388 8386 cdb[4] = (char)page_size;
8389 8387
8390 8388 com->uscsi_cdb = cdb;
8391 8389 com->uscsi_cdblen = CDB_GROUP0;
8392 8390 com->uscsi_bufaddr = (caddr_t)page_data;
8393 8391 com->uscsi_buflen = page_size;
8394 8392 com->uscsi_rqlen = sizeof (status);
8395 8393 com->uscsi_rqbuf = (caddr_t)&status;
8396 8394 com->uscsi_timeout = un->un_dp->non_motion_timeout;
8397 8395 com->uscsi_flags = USCSI_DIAGNOSE | USCSI_RQENABLE | USCSI_WRITE;
8398 8396
8399 8397 r = ubf(un, com, FKIOCTL);
8400 8398
8401 8399 kmem_free(com, sizeof (*com));
8402 8400 return (r);
8403 8401 }
8404 8402
8405 8403 static int
8406 8404 st_read_block_limits(struct scsi_tape *un, struct read_blklim *read_blk)
8407 8405 {
8408 8406 int rval;
8409 8407 char cdb[CDB_GROUP0];
8410 8408 struct uscsi_cmd *com;
8411 8409 struct scsi_arq_status status;
8412 8410
8413 8411 ST_FUNC(ST_DEVINFO, st_read_block_limits);
8414 8412
8415 8413 com = kmem_zalloc(sizeof (*com), KM_SLEEP);
8416 8414
8417 8415 bzero(cdb, CDB_GROUP0);
8418 8416 cdb[0] = SCMD_READ_BLKLIM;
8419 8417
8420 8418 com->uscsi_cdb = cdb;
8421 8419 com->uscsi_cdblen = CDB_GROUP0;
8422 8420 com->uscsi_bufaddr = (caddr_t)read_blk;
8423 8421 com->uscsi_buflen = sizeof (struct read_blklim);
8424 8422 com->uscsi_rqlen = sizeof (status);
8425 8423 com->uscsi_rqbuf = (caddr_t)&status;
8426 8424 com->uscsi_timeout = un->un_dp->non_motion_timeout;
8427 8425 com->uscsi_flags = USCSI_DIAGNOSE | USCSI_RQENABLE | USCSI_READ;
8428 8426
8429 8427 rval = st_uscsi_cmd(un, com, FKIOCTL);
8430 8428 if (com->uscsi_status || com->uscsi_resid) {
8431 8429 rval = -1;
8432 8430 }
8433 8431
8434 8432 kmem_free(com, sizeof (*com));
8435 8433 return (rval);
8436 8434 }
8437 8435
8438 8436 static int
8439 8437 st_report_density_support(struct scsi_tape *un, uchar_t *density_data,
8440 8438 size_t buflen)
8441 8439 {
8442 8440 int rval;
8443 8441 char cdb[CDB_GROUP1];
8444 8442 struct uscsi_cmd *com;
8445 8443 struct scsi_arq_status status;
8446 8444
8447 8445 ST_FUNC(ST_DEVINFO, st_report_density_support);
8448 8446
8449 8447 com = kmem_zalloc(sizeof (*com), KM_SLEEP);
8450 8448
8451 8449 bzero(cdb, CDB_GROUP1);
8452 8450 cdb[0] = SCMD_REPORT_DENSITIES;
8453 8451 cdb[7] = (buflen & 0xff00) >> 8;
8454 8452 cdb[8] = buflen & 0xff;
8455 8453
8456 8454 com->uscsi_cdb = cdb;
8457 8455 com->uscsi_cdblen = CDB_GROUP1;
8458 8456 com->uscsi_bufaddr = (caddr_t)density_data;
8459 8457 com->uscsi_buflen = buflen;
8460 8458 com->uscsi_rqlen = sizeof (status);
8461 8459 com->uscsi_rqbuf = (caddr_t)&status;
8462 8460 com->uscsi_timeout = un->un_dp->non_motion_timeout;
8463 8461 com->uscsi_flags = USCSI_DIAGNOSE | USCSI_RQENABLE | USCSI_READ;
8464 8462
8465 8463 rval = st_uscsi_cmd(un, com, FKIOCTL);
8466 8464 if (com->uscsi_status || com->uscsi_resid) {
8467 8465 rval = -1;
8468 8466 }
8469 8467
8470 8468 kmem_free(com, sizeof (*com));
8471 8469 return (rval);
8472 8470 }
8473 8471
8474 8472 static int
8475 8473 st_report_supported_operation(struct scsi_tape *un, uchar_t *oper_data,
8476 8474 uchar_t option_code, ushort_t service_action)
8477 8475 {
8478 8476 int rval;
8479 8477 char cdb[CDB_GROUP5];
8480 8478 struct uscsi_cmd *com;
8481 8479 struct scsi_arq_status status;
8482 8480 uint32_t allo_length;
8483 8481
8484 8482 ST_FUNC(ST_DEVINFO, st_report_supported_operation);
8485 8483
8486 8484 allo_length = sizeof (struct one_com_des) +
8487 8485 sizeof (struct com_timeout_des);
8488 8486 com = kmem_zalloc(sizeof (*com), KM_SLEEP);
8489 8487
8490 8488 bzero(cdb, CDB_GROUP5);
8491 8489 cdb[0] = (char)SCMD_MAINTENANCE_IN;
8492 8490 cdb[1] = SSVC_ACTION_GET_SUPPORTED_OPERATIONS;
8493 8491 if (service_action) {
8494 8492 cdb[2] = (char)(ONE_COMMAND_DATA_FORMAT | 0x80); /* RCTD */
8495 8493 cdb[4] = (service_action & 0xff00) >> 8;
8496 8494 cdb[5] = service_action & 0xff;
8497 8495 } else {
8498 8496 cdb[2] = (char)(ONE_COMMAND_NO_SERVICE_DATA_FORMAT |
8499 8497 0x80); /* RCTD */
8500 8498 }
8501 8499 cdb[3] = option_code;
8502 8500 cdb[6] = (allo_length & 0xff000000) >> 24;
8503 8501 cdb[7] = (allo_length & 0xff0000) >> 16;
8504 8502 cdb[8] = (allo_length & 0xff00) >> 8;
8505 8503 cdb[9] = allo_length & 0xff;
8506 8504
8507 8505 com->uscsi_cdb = cdb;
8508 8506 com->uscsi_cdblen = CDB_GROUP5;
8509 8507 com->uscsi_bufaddr = (caddr_t)oper_data;
8510 8508 com->uscsi_buflen = allo_length;
8511 8509 com->uscsi_rqlen = sizeof (status);
8512 8510 com->uscsi_rqbuf = (caddr_t)&status;
8513 8511 com->uscsi_timeout = un->un_dp->non_motion_timeout;
8514 8512 com->uscsi_flags = USCSI_DIAGNOSE | USCSI_RQENABLE | USCSI_READ;
8515 8513
8516 8514 rval = st_uscsi_cmd(un, com, FKIOCTL);
8517 8515 if (com->uscsi_status) {
8518 8516 rval = -1;
8519 8517 }
8520 8518
8521 8519 kmem_free(com, sizeof (*com));
8522 8520 return (rval);
8523 8521 }
8524 8522
8525 8523 /*
8526 8524 * Changes devices blocksize and bsize to requested blocksize nblksz.
8527 8525 * Returns returned value from first failed call or zero on success.
8528 8526 */
8529 8527 static int
8530 8528 st_change_block_size(struct scsi_tape *un, uint32_t nblksz)
8531 8529 {
8532 8530 struct seq_mode *current;
8533 8531 int rval;
8534 8532 uint32_t oldblksz;
8535 8533
8536 8534 ST_FUNC(ST_DEVINFO, st_change_block_size);
8537 8535
8538 8536 current = kmem_zalloc(MSIZE, KM_SLEEP);
8539 8537
8540 8538 /*
8541 8539 * If we haven't got the compression page yet, do that first.
8542 8540 */
8543 8541 if (un->un_comp_page == (ST_DEV_DATACOMP_PAGE | ST_DEV_CONFIG_PAGE)) {
8544 8542 (void) st_modesense(un);
8545 8543 }
8546 8544
8547 8545 /* Read current settings */
8548 8546 rval = st_gen_mode_sense(un, st_uscsi_cmd, 0, current, MSIZE);
8549 8547 if (rval != 0) {
8550 8548 scsi_log(ST_DEVINFO, st_label, SCSI_DEBUG,
8551 8549 "mode sense for change block size failed: rval = %d", rval);
8552 8550 goto finish;
8553 8551 }
8554 8552
8555 8553 /* Figure the current block size */
8556 8554 oldblksz =
8557 8555 (current->high_bl << 16) |
8558 8556 (current->mid_bl << 8) |
8559 8557 (current->low_bl);
8560 8558
8561 8559 /* If current block size is the same as requested were done */
8562 8560 if (oldblksz == nblksz) {
8563 8561 un->un_bsize = nblksz;
8564 8562 rval = 0;
8565 8563 goto finish;
8566 8564 }
8567 8565
8568 8566 /* Change to requested block size */
8569 8567 current->high_bl = (uchar_t)(nblksz >> 16);
8570 8568 current->mid_bl = (uchar_t)(nblksz >> 8);
8571 8569 current->low_bl = (uchar_t)(nblksz);
8572 8570
8573 8571 /* Attempt to change block size */
8574 8572 rval = st_gen_mode_select(un, st_uscsi_cmd, current, MSIZE);
8575 8573 if (rval != 0) {
8576 8574 scsi_log(ST_DEVINFO, st_label, SCSI_DEBUG,
8577 8575 "Set new block size failed: rval = %d", rval);
8578 8576 goto finish;
8579 8577 }
8580 8578
8581 8579 /* Read back and verify setting */
8582 8580 rval = st_modesense(un);
8583 8581 if (rval == 0) {
8584 8582 un->un_bsize =
8585 8583 (un->un_mspl->high_bl << 16) |
8586 8584 (un->un_mspl->mid_bl << 8) |
8587 8585 (un->un_mspl->low_bl);
8588 8586
8589 8587 if (un->un_bsize != nblksz) {
8590 8588 scsi_log(ST_DEVINFO, st_label, SCSI_DEBUG,
8591 8589 "Blocksize set does not equal requested blocksize"
8592 8590 "(read: %u requested: %u)\n", nblksz, un->un_bsize);
8593 8591 rval = EIO;
8594 8592 }
8595 8593 }
8596 8594 finish:
8597 8595 kmem_free(current, MSIZE);
8598 8596 return (rval);
8599 8597 }
8600 8598
8601 8599
8602 8600 static void
8603 8601 st_init(struct scsi_tape *un)
8604 8602 {
8605 8603 ST_FUNC(ST_DEVINFO, st_init);
8606 8604
8607 8605 ASSERT(mutex_owned(ST_MUTEX));
8608 8606
8609 8607 ST_DEBUG3(ST_DEVINFO, st_label, SCSI_DEBUG,
8610 8608 "st_init(): dev = 0x%lx, will reset fileno, blkno, eof\n",
8611 8609 un->un_dev);
8612 8610
8613 8611 un->un_pos.blkno = 0;
8614 8612 un->un_pos.fileno = 0;
8615 8613 un->un_lastop = ST_OP_NIL;
8616 8614 un->un_pos.eof = ST_NO_EOF;
8617 8615 un->un_pwr_mgmt = ST_PWR_NORMAL;
8618 8616 if (st_error_level != SCSI_ERR_ALL) {
8619 8617 if (DEBUGGING) {
8620 8618 st_error_level = SCSI_ERR_ALL;
8621 8619 } else {
8622 8620 st_error_level = SCSI_ERR_RETRYABLE;
8623 8621 }
8624 8622 }
8625 8623 }
8626 8624
8627 8625
8628 8626 static void
8629 8627 st_make_cmd(struct scsi_tape *un, struct buf *bp, int (*func)(caddr_t))
8630 8628 {
8631 8629 struct scsi_pkt *pkt;
8632 8630 struct uscsi_cmd *ucmd;
8633 8631 recov_info *ri;
8634 8632 int tval = 0;
8635 8633 int64_t count;
8636 8634 uint32_t additional = 0;
8637 8635 uint32_t address = 0;
8638 8636 union scsi_cdb *ucdb;
8639 8637 int flags = 0;
8640 8638 int cdb_len = CDB_GROUP0; /* default */
8641 8639 uchar_t com;
8642 8640 char fixbit;
8643 8641 char short_fm = 0;
8644 8642 optype prev_op = un->un_lastop;
8645 8643 int stat_size =
8646 8644 (un->un_arq_enabled ? sizeof (struct scsi_arq_status) : 1);
8647 8645
8648 8646 ST_FUNC(ST_DEVINFO, st_make_cmd);
8649 8647
8650 8648 ASSERT(mutex_owned(ST_MUTEX));
8651 8649
8652 8650 ST_DEBUG3(ST_DEVINFO, st_label, SCSI_DEBUG,
8653 8651 "st_make_cmd(): dev = 0x%lx\n", un->un_dev);
8654 8652
8655 8653
8656 8654 /*
8657 8655 * fixbit is for setting the Fixed Mode and Suppress Incorrect
8658 8656 * Length Indicator bits on read/write commands, for setting
8659 8657 * the Long bit on erase commands, and for setting the Code
8660 8658 * Field bits on space commands.
8661 8659 */
8662 8660
8663 8661 /* regular raw I/O */
8664 8662 if ((bp != un->un_sbufp) && (bp != un->un_recov_buf)) {
8665 8663 pkt = scsi_init_pkt(ROUTE, NULL, bp,
8666 8664 CDB_GROUP0, stat_size, st_recov_sz, 0, func,
8667 8665 (caddr_t)un);
8668 8666 if (pkt == NULL) {
8669 8667 scsi_log(ST_DEVINFO, st_label, CE_NOTE,
8670 8668 "Read Write scsi_init_pkt() failure\n");
8671 8669 goto exit;
8672 8670 }
8673 8671 ASSERT(pkt->pkt_resid == 0);
8674 8672 #ifdef STDEBUG
8675 8673 bzero(pkt->pkt_private, st_recov_sz);
8676 8674 bzero(pkt->pkt_scbp, stat_size);
8677 8675 #endif
8678 8676 ri = (recov_info *)pkt->pkt_private;
8679 8677 ri->privatelen = st_recov_sz;
8680 8678 if (un->un_bsize == 0) {
8681 8679 count = bp->b_bcount;
8682 8680 fixbit = 0;
8683 8681 } else {
8684 8682 count = bp->b_bcount / un->un_bsize;
8685 8683 fixbit = 1;
8686 8684 }
8687 8685 if (bp->b_flags & B_READ) {
8688 8686 com = SCMD_READ;
8689 8687 un->un_lastop = ST_OP_READ;
8690 8688 if ((un->un_bsize == 0) && /* Not Fixed Block */
8691 8689 (un->un_dp->options & ST_READ_IGNORE_ILI)) {
8692 8690 fixbit = 2;
8693 8691 }
8694 8692 } else {
8695 8693 com = SCMD_WRITE;
8696 8694 un->un_lastop = ST_OP_WRITE;
8697 8695 }
8698 8696 tval = un->un_dp->io_timeout;
8699 8697
8700 8698 /*
8701 8699 * For really large xfers, increase timeout
8702 8700 */
8703 8701 if (bp->b_bcount > (10 * ONE_MEG))
8704 8702 tval *= bp->b_bcount/(10 * ONE_MEG);
8705 8703
8706 8704 ST_DEBUG6(ST_DEVINFO, st_label, SCSI_DEBUG,
8707 8705 "%s %d amt 0x%lx\n", (com == SCMD_WRITE) ?
8708 8706 wr_str: rd_str, un->un_pos.blkno, bp->b_bcount);
8709 8707
8710 8708 } else if ((ucmd = BP_UCMD(bp)) != NULL) {
8711 8709 /*
8712 8710 * uscsi - build command, allocate scsi resources
8713 8711 */
8714 8712 st_make_uscsi_cmd(un, ucmd, bp, func);
8715 8713 goto exit;
8716 8714
8717 8715 } else { /* special I/O */
8718 8716 struct buf *allocbp = NULL;
8719 8717 com = (uchar_t)(uintptr_t)bp->b_forw;
8720 8718 count = bp->b_bcount;
8721 8719
8722 8720 switch (com) {
8723 8721 case SCMD_READ:
8724 8722 ST_DEBUG6(ST_DEVINFO, st_label, SCSI_DEBUG,
8725 8723 "special read %"PRId64"\n", count);
8726 8724 if (un->un_bsize == 0) {
8727 8725 fixbit = 2; /* suppress SILI */
8728 8726 } else {
8729 8727 fixbit = 1; /* Fixed Block Mode */
8730 8728 count /= un->un_bsize;
8731 8729 }
8732 8730 allocbp = bp;
8733 8731 un->un_lastop = ST_OP_READ;
8734 8732 tval = un->un_dp->io_timeout;
8735 8733 break;
8736 8734
8737 8735 case SCMD_WRITE:
8738 8736 ST_DEBUG6(ST_DEVINFO, st_label, SCSI_DEBUG,
8739 8737 "special write %"PRId64"\n", count);
8740 8738 if (un->un_bsize != 0) {
8741 8739 fixbit = 1; /* Fixed Block Mode */
8742 8740 count /= un->un_bsize;
8743 8741 } else {
8744 8742 fixbit = 0;
8745 8743 }
8746 8744 allocbp = bp;
8747 8745 un->un_lastop = ST_OP_WRITE;
8748 8746 tval = un->un_dp->io_timeout;
8749 8747 break;
8750 8748
8751 8749 case SCMD_WRITE_FILE_MARK:
8752 8750 ST_DEBUG6(ST_DEVINFO, st_label, SCSI_DEBUG,
8753 8751 "write %"PRId64" file marks\n", count);
8754 8752 un->un_lastop = ST_OP_WEOF;
8755 8753 fixbit = 0;
8756 8754 tval = un->un_dp->io_timeout;
8757 8755 /*
8758 8756 * If ST_SHORT_FILEMARKS bit is ON for EXABYTE
8759 8757 * device, set the Vendor Unique bit to
8760 8758 * write Short File Mark.
8761 8759 */
8762 8760 if ((un->un_dp->options & ST_SHORT_FILEMARKS) &&
8763 8761 ((un->un_dp->type == ST_TYPE_EXB8500) ||
8764 8762 (un->un_dp->type == ST_TYPE_EXABYTE))) {
8765 8763 /*
8766 8764 * Now the Vendor Unique bit 7 in Byte 5 of CDB
8767 8765 * is set to to write Short File Mark
8768 8766 */
8769 8767 short_fm = 1;
8770 8768 }
8771 8769 break;
8772 8770
8773 8771 case SCMD_REWIND:
8774 8772 /*
8775 8773 * In the case of rewind we're gona do the rewind with
8776 8774 * the immediate bit set so status will be retured when
8777 8775 * the command is accepted by the device. We clear the
8778 8776 * B_ASYNC flag so we wait for that acceptance.
8779 8777 */
8780 8778 fixbit = 0;
8781 8779 if (bp->b_flags & B_ASYNC) {
8782 8780 allocbp = bp;
8783 8781 if (count) {
8784 8782 fixbit = 1;
8785 8783 bp->b_flags &= ~B_ASYNC;
8786 8784 }
8787 8785 }
8788 8786 count = 0;
8789 8787 bp->b_bcount = 0;
8790 8788 un->un_lastop = ST_OP_CTL;
8791 8789 tval = un->un_dp->rewind_timeout;
8792 8790 ST_DEBUG6(ST_DEVINFO, st_label, SCSI_DEBUG,
8793 8791 "rewind\n");
8794 8792 break;
8795 8793
8796 8794 case SCMD_SPACE_G4:
8797 8795 cdb_len = CDB_GROUP4;
8798 8796 fixbit = SPACE_TYPE(bp->b_bcount);
8799 8797 count = SPACE_CNT(bp->b_bcount);
8800 8798 ST_DEBUG6(ST_DEVINFO, st_label, CE_WARN,
8801 8799 " %s space %s %"PRId64" from file %d blk %d\n",
8802 8800 bp->b_bcount & SP_BACKSP ? "backward" : "forward",
8803 8801 space_strs[fixbit & 7], count,
8804 8802 un->un_pos.fileno, un->un_pos.blkno);
8805 8803 address = (count >> 48) & 0x1fff;
8806 8804 additional = (count >> 16) & 0xffffffff;
8807 8805 count &= 0xffff;
8808 8806 count <<= 16;
8809 8807 un->un_lastop = ST_OP_CTL;
8810 8808 tval = un->un_dp->space_timeout;
8811 8809 break;
8812 8810
8813 8811 case SCMD_SPACE:
8814 8812 fixbit = SPACE_TYPE(bp->b_bcount);
8815 8813 count = SPACE_CNT(bp->b_bcount);
8816 8814 ST_DEBUG6(ST_DEVINFO, st_label, SCSI_DEBUG,
8817 8815 " %s space %s %"PRId64" from file %d blk %d\n",
8818 8816 bp->b_bcount & SP_BACKSP ? "backward" : "forward",
8819 8817 space_strs[fixbit & 7], count,
8820 8818 un->un_pos.fileno, un->un_pos.blkno);
8821 8819 count &= 0xffffffff;
8822 8820 un->un_lastop = ST_OP_CTL;
8823 8821 tval = un->un_dp->space_timeout;
8824 8822 break;
8825 8823
8826 8824 case SCMD_LOAD:
8827 8825 ASSERT(count < 10);
8828 8826 ST_DEBUG6(ST_DEVINFO, st_label, SCSI_DEBUG,
8829 8827 "%s tape\n", load_strs[count]);
8830 8828 fixbit = 0;
8831 8829
8832 8830 /* Loading or Unloading */
8833 8831 if (count & LD_LOAD) {
8834 8832 tval = un->un_dp->load_timeout;
8835 8833 } else {
8836 8834 tval = un->un_dp->unload_timeout;
8837 8835 }
8838 8836 /* Is Retension requested */
8839 8837 if (count & LD_RETEN) {
8840 8838 tval += un->un_dp->rewind_timeout;
8841 8839 }
8842 8840 un->un_lastop = ST_OP_CTL;
8843 8841 break;
8844 8842
8845 8843 case SCMD_ERASE:
8846 8844 ST_DEBUG6(ST_DEVINFO, st_label, SCSI_DEBUG,
8847 8845 "erase tape\n");
8848 8846 ASSERT(count == 1); /* mt sets this */
8849 8847 if (count == 1) {
8850 8848 /*
8851 8849 * do long erase
8852 8850 */
8853 8851 fixbit = 1; /* Long */
8854 8852
8855 8853 /* Drive might not honor immidiate bit */
8856 8854 tval = un->un_dp->erase_timeout;
8857 8855 } else {
8858 8856 /* Short Erase */
8859 8857 tval = un->un_dp->erase_timeout;
8860 8858 fixbit = 0;
8861 8859 }
8862 8860 un->un_lastop = ST_OP_CTL;
8863 8861 count = 0;
8864 8862 break;
8865 8863
8866 8864 case SCMD_MODE_SENSE:
8867 8865 ST_DEBUG6(ST_DEVINFO, st_label, SCSI_DEBUG,
8868 8866 "mode sense\n");
8869 8867 allocbp = bp;
8870 8868 fixbit = 0;
8871 8869 tval = un->un_dp->non_motion_timeout;
8872 8870 un->un_lastop = ST_OP_CTL;
8873 8871 break;
8874 8872
8875 8873 case SCMD_MODE_SELECT:
8876 8874 ST_DEBUG6(ST_DEVINFO, st_label, SCSI_DEBUG,
8877 8875 "mode select\n");
8878 8876 allocbp = bp;
8879 8877 fixbit = 0;
8880 8878 tval = un->un_dp->non_motion_timeout;
8881 8879 un->un_lastop = ST_OP_CTL;
8882 8880 break;
8883 8881
8884 8882 case SCMD_RESERVE:
8885 8883 ST_DEBUG6(ST_DEVINFO, st_label, SCSI_DEBUG,
8886 8884 "reserve\n");
8887 8885 fixbit = 0;
8888 8886 tval = un->un_dp->non_motion_timeout;
8889 8887 un->un_lastop = ST_OP_CTL;
8890 8888 break;
8891 8889
8892 8890 case SCMD_RELEASE:
8893 8891 ST_DEBUG6(ST_DEVINFO, st_label, SCSI_DEBUG,
8894 8892 "release\n");
8895 8893 fixbit = 0;
8896 8894 tval = un->un_dp->non_motion_timeout;
8897 8895 un->un_lastop = ST_OP_CTL;
8898 8896 break;
8899 8897
8900 8898 case SCMD_READ_BLKLIM:
8901 8899 ST_DEBUG6(ST_DEVINFO, st_label, SCSI_DEBUG,
8902 8900 "read block limits\n");
8903 8901 allocbp = bp;
8904 8902 fixbit = count = 0;
8905 8903 tval = un->un_dp->non_motion_timeout;
8906 8904 un->un_lastop = ST_OP_CTL;
8907 8905 break;
8908 8906
8909 8907 case SCMD_TEST_UNIT_READY:
8910 8908 ST_DEBUG6(ST_DEVINFO, st_label, SCSI_DEBUG,
8911 8909 "test unit ready\n");
8912 8910 fixbit = 0;
8913 8911 tval = un->un_dp->non_motion_timeout;
8914 8912 un->un_lastop = ST_OP_CTL;
8915 8913 break;
8916 8914
8917 8915 case SCMD_DOORLOCK:
8918 8916 ST_DEBUG6(ST_DEVINFO, st_label, SCSI_DEBUG,
8919 8917 "prevent/allow media removal\n");
8920 8918 fixbit = 0;
8921 8919 tval = un->un_dp->non_motion_timeout;
8922 8920 un->un_lastop = ST_OP_CTL;
8923 8921 break;
8924 8922
8925 8923 case SCMD_READ_POSITION:
8926 8924 ST_DEBUG6(ST_DEVINFO, st_label, SCSI_DEBUG,
8927 8925 "read position\n");
8928 8926 fixbit = un->un_read_pos_type;
8929 8927 cdb_len = CDB_GROUP1;
8930 8928 tval = un->un_dp->non_motion_timeout;
8931 8929 allocbp = bp;
8932 8930 un->un_lastop = ST_OP_CTL;
8933 8931 switch (un->un_read_pos_type) {
8934 8932 case LONG_POS:
8935 8933 count = 0;
8936 8934 break;
8937 8935 case EXT_POS:
8938 8936 count = sizeof (tape_position_ext_t);
8939 8937 break;
8940 8938 case SHORT_POS:
8941 8939 count = 0;
8942 8940 break;
8943 8941 default:
8944 8942 ST_DEBUG(ST_DEVINFO, st_label, CE_PANIC,
8945 8943 "Unknown read position type 0x%x in "
8946 8944 " st_make_cmd()\n", un->un_read_pos_type);
8947 8945 }
8948 8946 break;
8949 8947
8950 8948 default:
8951 8949 ST_DEBUG(ST_DEVINFO, st_label, CE_PANIC,
8952 8950 "Unhandled scsi command 0x%x in st_make_cmd()\n",
8953 8951 com);
8954 8952 }
8955 8953
8956 8954 pkt = scsi_init_pkt(ROUTE, NULL, allocbp, cdb_len, stat_size,
8957 8955 st_recov_sz, 0, func, (caddr_t)un);
8958 8956 if (pkt == NULL) {
8959 8957 scsi_log(ST_DEVINFO, st_label, CE_NOTE,
8960 8958 "generic command scsi_init_pkt() failure\n");
8961 8959 goto exit;
8962 8960 }
8963 8961
8964 8962 ASSERT(pkt->pkt_resid == 0);
8965 8963 #ifdef STDEBUG
8966 8964 bzero(pkt->pkt_private, st_recov_sz);
8967 8965 bzero(pkt->pkt_scbp, stat_size);
8968 8966 #endif
8969 8967 ri = (recov_info *)pkt->pkt_private;
8970 8968 ri->privatelen = st_recov_sz;
8971 8969 if (allocbp) {
8972 8970 ASSERT(geterror(allocbp) == 0);
8973 8971 }
8974 8972
8975 8973 }
8976 8974
8977 8975 ucdb = (union scsi_cdb *)pkt->pkt_cdbp;
8978 8976
8979 8977 (void) scsi_setup_cdb(ucdb, com, address, (uint_t)count, additional);
8980 8978 FILL_SCSI1_LUN(un->un_sd, pkt);
8981 8979 /*
8982 8980 * Initialize the SILI/Fixed bits of the byte 1 of cdb.
8983 8981 */
8984 8982 ucdb->t_code = fixbit;
8985 8983 ucdb->g0_vu_1 = short_fm;
8986 8984 pkt->pkt_flags = flags;
8987 8985
8988 8986 ASSERT(tval);
8989 8987 pkt->pkt_time = tval;
8990 8988 if (bp == un->un_recov_buf) {
8991 8989 pkt->pkt_comp = st_recov_cb;
8992 8990 } else {
8993 8991 pkt->pkt_comp = st_intr;
8994 8992 }
8995 8993
8996 8994 st_add_recovery_info_to_pkt(un, bp, pkt);
8997 8995
8998 8996 /*
8999 8997 * If we just write data to tape and did a command that doesn't
9000 8998 * change position, we still need to write a filemark.
9001 8999 */
9002 9000 if ((prev_op == ST_OP_WRITE) || (prev_op == ST_OP_WEOF)) {
9003 9001 recov_info *rcvi = pkt->pkt_private;
9004 9002 cmd_attribute const *atrib;
9005 9003
9006 9004 if (rcvi->privatelen == sizeof (recov_info)) {
9007 9005 atrib = rcvi->cmd_attrib;
9008 9006 } else {
9009 9007 atrib = st_lookup_cmd_attribute(com);
9010 9008 }
9011 9009 if (atrib->chg_tape_direction == DIR_NONE) {
9012 9010 un->un_lastop = prev_op;
9013 9011 }
9014 9012 }
9015 9013
9016 9014 exit:
9017 9015 ASSERT(mutex_owned(ST_MUTEX));
9018 9016 }
9019 9017
9020 9018
9021 9019 /*
9022 9020 * Build a command based on a uscsi command;
9023 9021 */
9024 9022 static void
9025 9023 st_make_uscsi_cmd(struct scsi_tape *un, struct uscsi_cmd *ucmd,
9026 9024 struct buf *bp, int (*func)(caddr_t))
9027 9025 {
9028 9026 struct scsi_pkt *pkt;
9029 9027 recov_info *ri;
9030 9028 caddr_t cdb;
9031 9029 int cdblen;
9032 9030 int stat_size = 1;
9033 9031 int flags = 0;
9034 9032
9035 9033 ST_FUNC(ST_DEVINFO, st_make_uscsi_cmd);
9036 9034
9037 9035 ST_DEBUG3(ST_DEVINFO, st_label, SCSI_DEBUG,
9038 9036 "st_make_uscsi_cmd(): dev = 0x%lx\n", un->un_dev);
9039 9037
9040 9038 if (ucmd->uscsi_flags & USCSI_RQENABLE) {
9041 9039 if (un->un_arq_enabled) {
9042 9040 if (ucmd->uscsi_rqlen > SENSE_LENGTH) {
9043 9041 stat_size = (int)(ucmd->uscsi_rqlen) +
9044 9042 sizeof (struct scsi_arq_status) -
9045 9043 sizeof (struct scsi_extended_sense);
9046 9044 flags = PKT_XARQ;
9047 9045 } else {
9048 9046 stat_size = sizeof (struct scsi_arq_status);
9049 9047 }
9050 9048 }
9051 9049 }
9052 9050
9053 9051 ASSERT(mutex_owned(ST_MUTEX));
9054 9052
9055 9053 cdb = ucmd->uscsi_cdb;
9056 9054 cdblen = ucmd->uscsi_cdblen;
9057 9055
9058 9056 ST_DEBUG6(ST_DEVINFO, st_label, SCSI_DEBUG,
9059 9057 "st_make_uscsi_cmd: buflen=%ld bcount=%ld\n",
9060 9058 ucmd->uscsi_buflen, bp->b_bcount);
9061 9059 pkt = scsi_init_pkt(ROUTE, NULL,
9062 9060 (bp->b_bcount > 0) ? bp : NULL,
9063 9061 cdblen, stat_size, st_recov_sz, flags, func, (caddr_t)un);
9064 9062 if (pkt == NULL) {
9065 9063 scsi_log(ST_DEVINFO, st_label, CE_NOTE,
9066 9064 "uscsi command scsi_init_pkt() failure\n");
9067 9065 goto exit;
9068 9066 }
9069 9067
9070 9068 ASSERT(pkt->pkt_resid == 0);
9071 9069 #ifdef STDEBUG
9072 9070 bzero(pkt->pkt_private, st_recov_sz);
9073 9071 bzero(pkt->pkt_scbp, stat_size);
9074 9072 #endif
9075 9073 ri = (recov_info *)pkt->pkt_private;
9076 9074 ri->privatelen = st_recov_sz;
9077 9075
9078 9076 bcopy(cdb, pkt->pkt_cdbp, (uint_t)cdblen);
9079 9077
9080 9078 #ifdef STDEBUG
9081 9079 if ((st_debug & 0x7) >= 6) {
9082 9080 st_clean_print(ST_DEVINFO, st_label, SCSI_DEBUG,
9083 9081 "pkt_cdbp", (char *)cdb, cdblen);
9084 9082 }
9085 9083 #endif
9086 9084
9087 9085 if (ucmd->uscsi_flags & USCSI_SILENT) {
9088 9086 pkt->pkt_flags |= FLAG_SILENT;
9089 9087 }
9090 9088
9091 9089 (void) scsi_uscsi_pktinit(ucmd, pkt);
9092 9090
9093 9091 pkt->pkt_time = ucmd->uscsi_timeout;
9094 9092 if (bp == un->un_recov_buf) {
9095 9093 pkt->pkt_comp = st_recov_cb;
9096 9094 } else {
9097 9095 pkt->pkt_comp = st_intr;
9098 9096 }
9099 9097
9100 9098 st_add_recovery_info_to_pkt(un, bp, pkt);
9101 9099 exit:
9102 9100 ASSERT(mutex_owned(ST_MUTEX));
9103 9101 }
9104 9102
9105 9103
9106 9104 /*
9107 9105 * restart cmd currently at the head of the runq
9108 9106 *
9109 9107 * If scsi_transport() succeeds or the retries
9110 9108 * count exhausted, restore the throttle that was
9111 9109 * zeroed out in st_handle_intr_busy().
9112 9110 *
9113 9111 */
9114 9112 static void
9115 9113 st_intr_restart(void *arg)
9116 9114 {
9117 9115 struct scsi_tape *un = arg;
9118 9116 struct buf *bp;
9119 9117 int queued;
9120 9118 int status = TRAN_ACCEPT;
9121 9119
9122 9120 mutex_enter(ST_MUTEX);
9123 9121
9124 9122 ST_FUNC(ST_DEVINFO, st_intr_restart);
9125 9123
9126 9124 ST_DEBUG3(ST_DEVINFO, st_label, SCSI_DEBUG,
9127 9125 "st_intr_restart(), un = 0x%p\n", (void *)un);
9128 9126
9129 9127 un->un_hib_tid = 0;
9130 9128
9131 9129 if (un->un_recov_buf_busy != 0) {
9132 9130 bp = un->un_recov_buf;
9133 9131 queued = 0;
9134 9132 } else if (un->un_sbuf_busy != 0) {
9135 9133 bp = un->un_sbufp;
9136 9134 queued = 0;
9137 9135 } else if (un->un_quef != NULL) {
9138 9136 bp = un->un_quef;
9139 9137 queued = 1;
9140 9138 } else {
9141 9139 mutex_exit(ST_MUTEX);
9142 9140 return;
9143 9141 }
9144 9142
9145 9143 /*
9146 9144 * Here we know :
9147 9145 * throttle = 0, via st_handle_intr_busy
9148 9146 */
9149 9147
9150 9148 if (queued) {
9151 9149 /*
9152 9150 * move from waitq to runq, if there is anything on the waitq
9153 9151 */
9154 9152 (void) st_remove_from_queue(&un->un_quef, &un->un_quef, bp);
9155 9153
9156 9154 if (un->un_runqf) {
9157 9155 /*
9158 9156 * not good, we don't want to requeue something after
9159 9157 * another.
9160 9158 */
9161 9159 goto done_error;
9162 9160 } else {
9163 9161 un->un_runqf = bp;
9164 9162 un->un_runql = bp;
9165 9163 }
9166 9164 }
9167 9165
9168 9166 ST_CDB(ST_DEVINFO, "Interrupt restart CDB",
9169 9167 (char *)BP_PKT(bp)->pkt_cdbp);
9170 9168
9171 9169 ST_DO_KSTATS(bp, kstat_waitq_to_runq);
9172 9170
9173 9171 status = st_transport(un, BP_PKT(bp));
9174 9172
9175 9173 if (status != TRAN_ACCEPT) {
9176 9174 ST_DO_KSTATS(bp, kstat_runq_back_to_waitq);
9177 9175
9178 9176 if (status == TRAN_BUSY) {
9179 9177 pkt_info *pkti = BP_PKT(bp)->pkt_private;
9180 9178
9181 9179 if (pkti->privatelen == sizeof (recov_info) &&
9182 9180 un->un_unit_attention_flags &&
9183 9181 bp != un->un_recov_buf) {
9184 9182 un->un_unit_attention_flags = 0;
9185 9183 ST_RECOV(ST_DEVINFO, st_label, CE_WARN,
9186 9184 "Command Recovery called on busy resend\n");
9187 9185 if (st_command_recovery(un, BP_PKT(bp),
9188 9186 ATTEMPT_RETRY) == JUST_RETURN) {
9189 9187 mutex_exit(ST_MUTEX);
9190 9188 return;
9191 9189 }
9192 9190 }
9193 9191 mutex_exit(ST_MUTEX);
9194 9192 if (st_handle_intr_busy(un, bp,
9195 9193 ST_TRAN_BUSY_TIMEOUT) == 0)
9196 9194 return; /* timeout is setup again */
9197 9195 mutex_enter(ST_MUTEX);
9198 9196 }
9199 9197
9200 9198 done_error:
9201 9199 ST_DEBUG6(ST_DEVINFO, st_label, CE_WARN,
9202 9200 "restart transport rejected\n");
9203 9201 bp->b_resid = bp->b_bcount;
9204 9202
9205 9203 if (un->un_last_throttle) {
9206 9204 un->un_throttle = un->un_last_throttle;
9207 9205 }
9208 9206 if (status != TRAN_ACCEPT) {
9209 9207 ST_DO_ERRSTATS(un, st_transerrs);
9210 9208 }
9211 9209 ST_DO_KSTATS(bp, kstat_waitq_exit);
9212 9210 ST_DEBUG6(ST_DEVINFO, st_label, CE_WARN,
9213 9211 "busy restart aborted\n");
9214 9212 st_set_pe_flag(un);
9215 9213 st_bioerror(bp, EIO);
9216 9214 st_done_and_mutex_exit(un, bp);
9217 9215 } else {
9218 9216 if (un->un_last_throttle) {
9219 9217 un->un_throttle = un->un_last_throttle;
9220 9218 }
9221 9219 mutex_exit(ST_MUTEX);
9222 9220 }
9223 9221 }
9224 9222
9225 9223 /*
9226 9224 * st_check_media():
9227 9225 * Periodically check the media state using scsi_watch service;
9228 9226 * this service calls back after TUR and possibly request sense
9229 9227 * the callback handler (st_media_watch_cb()) decodes the request sense
9230 9228 * data (if any)
9231 9229 */
9232 9230
9233 9231 static int
9234 9232 st_check_media(dev_t dev, enum mtio_state state)
9235 9233 {
9236 9234 int rval = 0;
9237 9235 enum mtio_state prev_state;
9238 9236 opaque_t token = NULL;
9239 9237
9240 9238 GET_SOFT_STATE(dev);
9241 9239
9242 9240 ST_FUNC(ST_DEVINFO, st_check_media);
9243 9241
9244 9242 mutex_enter(ST_MUTEX);
9245 9243
9246 9244 ST_DEBUG(ST_DEVINFO, st_label, SCSI_DEBUG,
9247 9245 "st_check_media:state=%x, mediastate=%x\n",
9248 9246 state, un->un_mediastate);
9249 9247
9250 9248 prev_state = un->un_mediastate;
9251 9249
9252 9250 /*
9253 9251 * is there anything to do?
9254 9252 */
9255 9253 retry:
9256 9254 if (state == un->un_mediastate || un->un_mediastate == MTIO_NONE) {
9257 9255 /*
9258 9256 * submit the request to the scsi_watch service;
9259 9257 * scsi_media_watch_cb() does the real work
9260 9258 */
9261 9259 mutex_exit(ST_MUTEX);
9262 9260 token = scsi_watch_request_submit(ST_SCSI_DEVP,
9263 9261 st_check_media_time, SENSE_LENGTH,
9264 9262 st_media_watch_cb, (caddr_t)dev);
9265 9263 if (token == NULL) {
9266 9264 rval = EAGAIN;
9267 9265 goto done;
9268 9266 }
9269 9267 mutex_enter(ST_MUTEX);
9270 9268
9271 9269 un->un_swr_token = token;
9272 9270 un->un_specified_mediastate = state;
9273 9271
9274 9272 /*
9275 9273 * now wait for media change
9276 9274 * we will not be signalled unless mediastate == state but it
9277 9275 * still better to test for this condition, since there
9278 9276 * is a 5 sec cv_broadcast delay when
9279 9277 * mediastate == MTIO_INSERTED
9280 9278 */
9281 9279 ST_DEBUG(ST_DEVINFO, st_label, SCSI_DEBUG,
9282 9280 "st_check_media:waiting for media state change\n");
9283 9281 while (un->un_mediastate == state) {
9284 9282 if (cv_wait_sig(&un->un_state_cv, ST_MUTEX) == 0) {
9285 9283 mutex_exit(ST_MUTEX);
9286 9284 ST_DEBUG(ST_DEVINFO, st_label, SCSI_DEBUG,
9287 9285 "st_check_media:waiting for media state "
9288 9286 "was interrupted\n");
9289 9287 rval = EINTR;
9290 9288 goto done;
9291 9289 }
9292 9290 ST_DEBUG(ST_DEVINFO, st_label, SCSI_DEBUG,
9293 9291 "st_check_media:received signal, state=%x\n",
9294 9292 un->un_mediastate);
9295 9293 }
9296 9294 }
9297 9295
9298 9296 /*
9299 9297 * if we transitioned to MTIO_INSERTED, media has really been
9300 9298 * inserted. If TUR fails, it is probably a exabyte slow spin up.
9301 9299 * Reset and retry the state change. If everything is ok, replay
9302 9300 * the open() logic.
9303 9301 */
9304 9302 if ((un->un_mediastate == MTIO_INSERTED) &&
9305 9303 (un->un_state == ST_STATE_OFFLINE)) {
9306 9304 ST_DEBUG(ST_DEVINFO, st_label, SCSI_DEBUG,
9307 9305 "st_check_media: calling st_cmd to confirm inserted\n");
9308 9306
9309 9307 /*
9310 9308 * set this early so that TUR will make it through strategy
9311 9309 * without triggering a st_tape_init(). We needed it set
9312 9310 * before calling st_tape_init() ourselves anyway. If TUR
9313 9311 * fails, set it back
9314 9312 */
9315 9313 un->un_state = ST_STATE_INITIALIZING;
9316 9314
9317 9315 /*
9318 9316 * If not reserved fail as getting reservation conflict
9319 9317 * will make this hang forever.
9320 9318 */
9321 9319 if ((un->un_rsvd_status &
9322 9320 (ST_RESERVE | ST_APPLICATION_RESERVATIONS)) == 0) {
9323 9321 mutex_exit(ST_MUTEX);
9324 9322 rval = EACCES;
9325 9323 goto done;
9326 9324 }
9327 9325 rval = st_cmd(un, SCMD_TEST_UNIT_READY, 0, SYNC_CMD);
9328 9326 if (rval == EACCES) {
9329 9327 ST_DEBUG(ST_DEVINFO, st_label, SCSI_DEBUG,
9330 9328 "st_check_media: TUR got Reservation Conflict\n");
9331 9329 mutex_exit(ST_MUTEX);
9332 9330 goto done;
9333 9331 }
9334 9332 if (rval) {
9335 9333 ST_DEBUG(ST_DEVINFO, st_label, SCSI_DEBUG,
9336 9334 "st_check_media: TUR failed, going to retry\n");
9337 9335 un->un_mediastate = prev_state;
9338 9336 un->un_state = ST_STATE_OFFLINE;
9339 9337 goto retry;
9340 9338 }
9341 9339 ST_DEBUG(ST_DEVINFO, st_label, SCSI_DEBUG,
9342 9340 "st_check_media: media inserted\n");
9343 9341
9344 9342 /* this also rewinds the tape */
9345 9343 rval = st_tape_init(un);
9346 9344 if (rval != 0) {
9347 9345 ST_DEBUG(ST_DEVINFO, st_label, SCSI_DEBUG,
9348 9346 "st_check_media : OFFLINE init failure ");
9349 9347 un->un_state = ST_STATE_OFFLINE;
9350 9348 un->un_pos.pmode = invalid;
9351 9349 } else {
9352 9350 un->un_state = ST_STATE_OPEN_PENDING_IO;
9353 9351 }
9354 9352 } else if ((un->un_mediastate == MTIO_EJECTED) &&
9355 9353 (un->un_state != ST_STATE_OFFLINE)) {
9356 9354 /*
9357 9355 * supported devices must be rewound before ejection
9358 9356 * rewind resets fileno & blkno
9359 9357 */
9360 9358 un->un_laststate = un->un_state;
9361 9359 un->un_state = ST_STATE_OFFLINE;
9362 9360 }
9363 9361 mutex_exit(ST_MUTEX);
9364 9362 done:
9365 9363 if (token) {
9366 9364 (void) scsi_watch_request_terminate(token,
9367 9365 SCSI_WATCH_TERMINATE_WAIT);
9368 9366 mutex_enter(ST_MUTEX);
9369 9367 un->un_swr_token = (opaque_t)NULL;
9370 9368 mutex_exit(ST_MUTEX);
9371 9369 }
9372 9370
9373 9371 ST_DEBUG(ST_DEVINFO, st_label, SCSI_DEBUG, "st_check_media: done\n");
9374 9372
9375 9373 return (rval);
9376 9374 }
9377 9375
9378 9376 /*
9379 9377 * st_media_watch_cb() is called by scsi_watch_thread for
9380 9378 * verifying the request sense data (if any)
9381 9379 */
9382 9380 static int
9383 9381 st_media_watch_cb(caddr_t arg, struct scsi_watch_result *resultp)
9384 9382 {
9385 9383 struct scsi_status *statusp = resultp->statusp;
9386 9384 struct scsi_extended_sense *sensep = resultp->sensep;
9387 9385 uchar_t actual_sense_length = resultp->actual_sense_length;
9388 9386 struct scsi_tape *un;
9389 9387 enum mtio_state state = MTIO_NONE;
9390 9388 int instance;
9391 9389 dev_t dev = (dev_t)arg;
9392 9390
9393 9391 instance = MTUNIT(dev);
9394 9392 if ((un = ddi_get_soft_state(st_state, instance)) == NULL) {
9395 9393 return (-1);
9396 9394 }
9397 9395
9398 9396 mutex_enter(ST_MUTEX);
9399 9397 ST_FUNC(ST_DEVINFO, st_media_watch_cb);
9400 9398 ST_DEBUG3(ST_DEVINFO, st_label, SCSI_DEBUG,
9401 9399 "st_media_watch_cb: status=%x, sensep=%p, len=%x\n",
9402 9400 *((char *)statusp), (void *)sensep,
9403 9401 actual_sense_length);
9404 9402
9405 9403
9406 9404 /*
9407 9405 * if there was a check condition then sensep points to valid
9408 9406 * sense data
9409 9407 * if status was not a check condition but a reservation or busy
9410 9408 * status then the new state is MTIO_NONE
9411 9409 */
9412 9410 if (sensep) {
9413 9411 ST_DEBUG(ST_DEVINFO, st_label, SCSI_DEBUG,
9414 9412 "st_media_watch_cb: KEY=%x, ASC=%x, ASCQ=%x\n",
9415 9413 sensep->es_key, sensep->es_add_code, sensep->es_qual_code);
9416 9414
9417 9415 switch (un->un_dp->type) {
9418 9416 default:
9419 9417 ST_DEBUG(ST_DEVINFO, st_label, SCSI_DEBUG,
9420 9418 "st_media_watch_cb: unknown drive type %d, "
9421 9419 "default to ST_TYPE_HP\n", un->un_dp->type);
9422 9420 /* FALLTHROUGH */
9423 9421
9424 9422 case ST_TYPE_STC3490: /* STK 4220 1/2" cartridge */
9425 9423 case ST_TYPE_FUJI: /* 1/2" cartridge */
9426 9424 case ST_TYPE_HP: /* HP 88780 1/2" reel */
9427 9425 if (un->un_dp->type == ST_TYPE_FUJI) {
9428 9426 ST_DEBUG4(ST_DEVINFO, st_label, SCSI_DEBUG,
9429 9427 "st_media_watch_cb: ST_TYPE_FUJI\n");
9430 9428 } else {
9431 9429 ST_DEBUG4(ST_DEVINFO, st_label, SCSI_DEBUG,
9432 9430 "st_media_watch_cb: ST_TYPE_HP\n");
9433 9431 }
9434 9432 switch (sensep->es_key) {
9435 9433 case KEY_UNIT_ATTENTION:
9436 9434 /* not ready to ready transition */
9437 9435 /* hp/es_qual_code == 80 on>off>on */
9438 9436 /* hp/es_qual_code == 0 on>off>unld>ld>on */
9439 9437 if (sensep->es_add_code == 0x28) {
9440 9438 state = MTIO_INSERTED;
9441 9439 }
9442 9440 break;
9443 9441 case KEY_NOT_READY:
9444 9442 /* in process, rewinding or loading */
9445 9443 if ((sensep->es_add_code == 0x04) &&
9446 9444 (sensep->es_qual_code == 0x00)) {
9447 9445 state = MTIO_EJECTED;
9448 9446 }
9449 9447 break;
9450 9448 }
9451 9449 break;
9452 9450
9453 9451 case ST_TYPE_EXB8500: /* Exabyte 8500 */
9454 9452 ST_DEBUG4(ST_DEVINFO, st_label, SCSI_DEBUG,
9455 9453 "st_media_watch_cb: ST_TYPE_EXB8500\n");
9456 9454 switch (sensep->es_key) {
9457 9455 case KEY_UNIT_ATTENTION:
9458 9456 /* operator medium removal request */
9459 9457 if ((sensep->es_add_code == 0x5a) &&
9460 9458 (sensep->es_qual_code == 0x01)) {
9461 9459 state = MTIO_EJECTED;
9462 9460 /* not ready to ready transition */
9463 9461 } else if ((sensep->es_add_code == 0x28) &&
9464 9462 (sensep->es_qual_code == 0x00)) {
9465 9463 state = MTIO_INSERTED;
9466 9464 }
9467 9465 break;
9468 9466 case KEY_NOT_READY:
9469 9467 /* medium not present */
9470 9468 if (sensep->es_add_code == 0x3a) {
9471 9469 state = MTIO_EJECTED;
9472 9470 }
9473 9471 break;
9474 9472 }
9475 9473 break;
9476 9474 case ST_TYPE_EXABYTE: /* Exabyte 8200 */
9477 9475 ST_DEBUG4(ST_DEVINFO, st_label, SCSI_DEBUG,
9478 9476 "st_media_watch_cb: ST_TYPE_EXABYTE\n");
9479 9477 switch (sensep->es_key) {
9480 9478 case KEY_NOT_READY:
9481 9479 if ((sensep->es_add_code == 0x04) &&
9482 9480 (sensep->es_qual_code == 0x00)) {
9483 9481 /* volume not mounted? */
9484 9482 state = MTIO_EJECTED;
9485 9483 } else if (sensep->es_add_code == 0x3a) {
9486 9484 state = MTIO_EJECTED;
9487 9485 }
9488 9486 break;
9489 9487 case KEY_UNIT_ATTENTION:
9490 9488 state = MTIO_EJECTED;
9491 9489 break;
9492 9490 }
9493 9491 break;
9494 9492
9495 9493 case ST_TYPE_DLT: /* quantum DLT4xxx */
9496 9494 switch (sensep->es_key) {
9497 9495 case KEY_UNIT_ATTENTION:
9498 9496 if (sensep->es_add_code == 0x28) {
9499 9497 state = MTIO_INSERTED;
9500 9498 }
9501 9499 break;
9502 9500 case KEY_NOT_READY:
9503 9501 if (sensep->es_add_code == 0x04) {
9504 9502 /* in transition but could be either */
9505 9503 state = un->un_specified_mediastate;
9506 9504 } else if ((sensep->es_add_code == 0x3a) &&
9507 9505 (sensep->es_qual_code == 0x00)) {
9508 9506 state = MTIO_EJECTED;
9509 9507 }
9510 9508 break;
9511 9509 }
9512 9510 break;
9513 9511 }
9514 9512 } else if (*((char *)statusp) == STATUS_GOOD) {
9515 9513 state = MTIO_INSERTED;
9516 9514 }
9517 9515
9518 9516 ST_DEBUG4(ST_DEVINFO, st_label, SCSI_DEBUG,
9519 9517 "st_media_watch_cb:state=%x, specified=%x\n",
9520 9518 state, un->un_specified_mediastate);
9521 9519
9522 9520 /*
9523 9521 * now signal the waiting thread if this is *not* the specified state;
9524 9522 * delay the signal if the state is MTIO_INSERTED
9525 9523 * to allow the target to recover
9526 9524 */
9527 9525 if (state != un->un_specified_mediastate) {
9528 9526 un->un_mediastate = state;
9529 9527 if (state == MTIO_INSERTED) {
9530 9528 /*
9531 9529 * delay the signal to give the drive a chance
9532 9530 * to do what it apparently needs to do
9533 9531 */
9534 9532 ST_DEBUG4(ST_DEVINFO, st_label, SCSI_DEBUG,
9535 9533 "st_media_watch_cb:delayed cv_broadcast\n");
9536 9534 un->un_delay_tid = timeout(st_delayed_cv_broadcast,
9537 9535 un, drv_usectohz((clock_t)MEDIA_ACCESS_DELAY));
9538 9536 } else {
9539 9537 ST_DEBUG4(ST_DEVINFO, st_label, SCSI_DEBUG,
9540 9538 "st_media_watch_cb:immediate cv_broadcast\n");
9541 9539 cv_broadcast(&un->un_state_cv);
9542 9540 }
9543 9541 }
9544 9542 mutex_exit(ST_MUTEX);
9545 9543 return (0);
9546 9544 }
9547 9545
9548 9546 /*
9549 9547 * delayed cv_broadcast to allow for target to recover
9550 9548 * from media insertion
9551 9549 */
9552 9550 static void
9553 9551 st_delayed_cv_broadcast(void *arg)
9554 9552 {
9555 9553 struct scsi_tape *un = arg;
9556 9554
9557 9555 ST_FUNC(ST_DEVINFO, st_delayed_cv_broadcast);
9558 9556
9559 9557 ST_DEBUG3(ST_DEVINFO, st_label, SCSI_DEBUG,
9560 9558 "st_delayed_cv_broadcast:delayed cv_broadcast\n");
9561 9559
9562 9560 mutex_enter(ST_MUTEX);
9563 9561 cv_broadcast(&un->un_state_cv);
9564 9562 mutex_exit(ST_MUTEX);
9565 9563 }
9566 9564
9567 9565 /*
9568 9566 * restart cmd currently at the start of the waitq
9569 9567 */
9570 9568 static void
9571 9569 st_start_restart(void *arg)
9572 9570 {
9573 9571 struct scsi_tape *un = arg;
9574 9572
9575 9573 ST_FUNC(ST_DEVINFO, st_start_restart);
9576 9574
9577 9575 ASSERT(un != NULL);
9578 9576
9579 9577 mutex_enter(ST_MUTEX);
9580 9578
9581 9579 ST_DEBUG3(ST_DEVINFO, st_label, SCSI_DEBUG, "st_tran_restart()\n");
9582 9580
9583 9581 st_start(un);
9584 9582
9585 9583 mutex_exit(ST_MUTEX);
9586 9584 }
9587 9585
9588 9586
9589 9587 /*
9590 9588 * Command completion processing
9591 9589 *
9592 9590 */
9593 9591 static void
9594 9592 st_intr(struct scsi_pkt *pkt)
9595 9593 {
9596 9594 recov_info *rcv = pkt->pkt_private;
9597 9595 struct buf *bp = rcv->cmd_bp;
9598 9596 struct scsi_tape *un;
9599 9597 errstate action = COMMAND_DONE;
9600 9598 clock_t timout;
9601 9599 int status;
9602 9600
9603 9601 un = ddi_get_soft_state(st_state, MTUNIT(bp->b_edev));
9604 9602
9605 9603 ST_FUNC(ST_DEVINFO, st_intr);
9606 9604
9607 9605 ASSERT(un != NULL);
9608 9606
9609 9607 mutex_enter(ST_MUTEX);
9610 9608
9611 9609 ASSERT(bp != un->un_recov_buf);
9612 9610
9613 9611 un->un_rqs_state &= ~(ST_RQS_ERROR);
9614 9612
9615 9613 ST_DEBUG3(ST_DEVINFO, st_label, SCSI_DEBUG, "st_intr()\n");
9616 9614
9617 9615 if (pkt->pkt_reason != CMD_CMPLT) {
9618 9616 ST_DEBUG(ST_DEVINFO, st_label, CE_WARN,
9619 9617 "Unhappy packet status reason = %s statistics = 0x%x\n",
9620 9618 scsi_rname(pkt->pkt_reason), pkt->pkt_statistics);
9621 9619
9622 9620 /* If device has gone away not much else to do */
9623 9621 if (pkt->pkt_reason == CMD_DEV_GONE) {
9624 9622 action = COMMAND_DONE_ERROR;
9625 9623 } else if ((pkt == un->un_rqs) ||
9626 9624 (un->un_state == ST_STATE_SENSING)) {
9627 9625 ASSERT(pkt == un->un_rqs);
9628 9626 ASSERT(un->un_state == ST_STATE_SENSING);
9629 9627 un->un_state = un->un_laststate;
9630 9628 rcv->cmd_bp = un->un_rqs_bp;
9631 9629 ST_DO_ERRSTATS(un, st_transerrs);
9632 9630 action = COMMAND_DONE_ERROR;
9633 9631 } else {
9634 9632 action = st_handle_incomplete(un, bp);
9635 9633 }
9636 9634 /*
9637 9635 * At this point we know that the command was successfully
9638 9636 * completed. Now what?
9639 9637 */
9640 9638 } else if ((pkt == un->un_rqs) || (un->un_state == ST_STATE_SENSING)) {
9641 9639 /*
9642 9640 * okay. We were running a REQUEST SENSE. Find
9643 9641 * out what to do next.
9644 9642 */
9645 9643 ASSERT(pkt == un->un_rqs);
9646 9644 ASSERT(un->un_state == ST_STATE_SENSING);
9647 9645 scsi_sync_pkt(pkt);
9648 9646 action = st_handle_sense(un, bp, &un->un_pos);
9649 9647 /*
9650 9648 * Make rqs isn't going to be retied.
9651 9649 */
9652 9650 if (action != QUE_BUSY_COMMAND && action != QUE_COMMAND) {
9653 9651 /*
9654 9652 * set pkt back to original packet in case we will have
9655 9653 * to requeue it
9656 9654 */
9657 9655 pkt = BP_PKT(bp);
9658 9656 rcv->cmd_bp = un->un_rqs_bp;
9659 9657 /*
9660 9658 * some actions are based on un_state, hence
9661 9659 * restore the state st was in before ST_STATE_SENSING.
9662 9660 */
9663 9661 un->un_state = un->un_laststate;
9664 9662 }
9665 9663
9666 9664 } else if (un->un_arq_enabled && (pkt->pkt_state & STATE_ARQ_DONE)) {
9667 9665 /*
9668 9666 * the transport layer successfully completed an autorqsense
9669 9667 */
9670 9668 action = st_handle_autosense(un, bp, &un->un_pos);
9671 9669
9672 9670 } else if ((SCBP(pkt)->sts_busy) ||
9673 9671 (SCBP(pkt)->sts_chk) ||
9674 9672 (SCBP(pkt)->sts_vu7)) {
9675 9673 /*
9676 9674 * Okay, we weren't running a REQUEST SENSE. Call a routine
9677 9675 * to see if the status bits we're okay. If a request sense
9678 9676 * is to be run, that will happen.
9679 9677 */
9680 9678 action = st_check_error(un, pkt);
9681 9679 }
9682 9680
9683 9681 if (un->un_pwr_mgmt == ST_PWR_SUSPENDED) {
9684 9682 switch (action) {
9685 9683 case QUE_COMMAND:
9686 9684 /*
9687 9685 * return cmd to head to the queue
9688 9686 * since we are suspending so that
9689 9687 * it gets restarted during resume
9690 9688 */
9691 9689 st_add_to_queue(&un->un_runqf, &un->un_runql,
9692 9690 un->un_runqf, bp);
9693 9691
9694 9692 action = JUST_RETURN;
9695 9693 break;
9696 9694
9697 9695 case QUE_SENSE:
9698 9696 action = COMMAND_DONE_ERROR;
9699 9697 break;
9700 9698
9701 9699 default:
9702 9700 break;
9703 9701 }
9704 9702 }
9705 9703
9706 9704 /*
9707 9705 * check for undetected path failover.
9708 9706 */
9709 9707 if (un->un_multipath) {
9710 9708
9711 9709 struct uscsi_cmd *ucmd = BP_UCMD(bp);
9712 9710 int pkt_valid = 0;
9713 9711
9714 9712 if (ucmd) {
9715 9713 /*
9716 9714 * Also copies path instance to the uscsi structure.
9717 9715 */
9718 9716 pkt_valid = scsi_uscsi_pktfini(pkt, ucmd);
9719 9717
9720 9718 /*
9721 9719 * scsi_uscsi_pktfini() zeros pkt_path_instance.
9722 9720 */
9723 9721 pkt->pkt_path_instance = ucmd->uscsi_path_instance;
9724 9722 } else {
9725 9723 pkt_valid = scsi_pkt_allocated_correctly(pkt);
9726 9724 }
9727 9725
9728 9726 /*
9729 9727 * If the scsi_pkt was not allocated correctly the
9730 9728 * pkt_path_instance is not even there.
9731 9729 */
9732 9730 if ((pkt_valid != 0) &&
9733 9731 (un->un_last_path_instance != pkt->pkt_path_instance)) {
9734 9732 /*
9735 9733 * Don't recover the path change if it was done
9736 9734 * intentionally or if the device has not completely
9737 9735 * opened yet.
9738 9736 */
9739 9737 if (((pkt->pkt_flags & FLAG_PKT_PATH_INSTANCE) == 0) &&
9740 9738 (un->un_state > ST_STATE_OPENING)) {
9741 9739 ST_RECOV(ST_DEVINFO, st_label, CE_NOTE,
9742 9740 "Failover detected, action is %s\n",
9743 9741 errstatenames[action]);
9744 9742 if (action == COMMAND_DONE) {
9745 9743 action = PATH_FAILED;
9746 9744 }
9747 9745 }
9748 9746 un->un_last_path_instance = pkt->pkt_path_instance;
9749 9747 }
9750 9748 }
9751 9749
9752 9750 /*
9753 9751 * Restore old state if we were sensing.
9754 9752 */
9755 9753 if (un->un_state == ST_STATE_SENSING && action != QUE_SENSE) {
9756 9754 un->un_state = un->un_laststate;
9757 9755 }
9758 9756
9759 9757 ST_DEBUG6(ST_DEVINFO, st_label, SCSI_DEBUG,
9760 9758 "st_intr: pkt=%p, bp=%p, action=%s, status=%x\n",
9761 9759 (void *)pkt, (void *)bp, errstatenames[action], SCBP_C(pkt));
9762 9760
9763 9761 again:
9764 9762 switch (action) {
9765 9763 case COMMAND_DONE_EACCES:
9766 9764 /* this is to report a reservation conflict */
9767 9765 st_bioerror(bp, EACCES);
9768 9766 ST_DEBUG(ST_DEVINFO, st_label, SCSI_DEBUG,
9769 9767 "Reservation Conflict \n");
9770 9768 un->un_pos.pmode = invalid;
9771 9769
9772 9770 /*FALLTHROUGH*/
9773 9771 case COMMAND_DONE_ERROR:
9774 9772 if (un->un_pos.eof < ST_EOT_PENDING &&
9775 9773 un->un_state >= ST_STATE_OPEN) {
9776 9774 /*
9777 9775 * all errors set state of the tape to 'unknown'
9778 9776 * unless we're at EOT or are doing append testing.
9779 9777 * If sense key was illegal request, preserve state.
9780 9778 */
9781 9779 if (un->un_status != KEY_ILLEGAL_REQUEST) {
9782 9780 un->un_pos.pmode = invalid;
9783 9781 }
9784 9782 }
9785 9783
9786 9784 un->un_err_resid = bp->b_resid = bp->b_bcount;
9787 9785 /*
9788 9786 * since we have an error (COMMAND_DONE_ERROR), we want to
9789 9787 * make sure an error ocurrs, so make sure at least EIO is
9790 9788 * returned
9791 9789 */
9792 9790 if (geterror(bp) == 0)
9793 9791 st_bioerror(bp, EIO);
9794 9792
9795 9793 st_set_pe_flag(un);
9796 9794 if (!(un->un_rqs_state & ST_RQS_ERROR) &&
9797 9795 (un->un_errno == EIO)) {
9798 9796 un->un_rqs_state &= ~(ST_RQS_VALID);
9799 9797 }
9800 9798 break;
9801 9799
9802 9800 case COMMAND_DONE_ERROR_RECOVERED:
9803 9801 un->un_err_resid = bp->b_resid = bp->b_bcount;
9804 9802 ST_DEBUG2(ST_DEVINFO, st_label, SCSI_DEBUG,
9805 9803 "st_intr(): COMMAND_DONE_ERROR_RECOVERED");
9806 9804 if (geterror(bp) == 0) {
9807 9805 st_bioerror(bp, EIO);
9808 9806 }
9809 9807 st_set_pe_flag(un);
9810 9808 if (!(un->un_rqs_state & ST_RQS_ERROR) &&
9811 9809 (un->un_errno == EIO)) {
9812 9810 un->un_rqs_state &= ~(ST_RQS_VALID);
9813 9811 }
9814 9812 /*FALLTHROUGH*/
9815 9813 case COMMAND_DONE:
9816 9814 st_set_state(un, bp);
9817 9815 break;
9818 9816
9819 9817 case QUE_SENSE:
9820 9818 if ((un->un_ncmds > 1) && !un->un_flush_on_errors)
9821 9819 goto sense_error;
9822 9820
9823 9821 if (un->un_state != ST_STATE_SENSING) {
9824 9822 un->un_laststate = un->un_state;
9825 9823 un->un_state = ST_STATE_SENSING;
9826 9824 }
9827 9825
9828 9826 /*
9829 9827 * zero the sense data.
9830 9828 */
9831 9829 bzero(un->un_rqs->pkt_scbp, SENSE_LENGTH);
9832 9830
9833 9831 /*
9834 9832 * If this is not a retry on QUE_SENSE point to the original
9835 9833 * bp of the command that got us here.
9836 9834 */
9837 9835 if (pkt != un->un_rqs) {
9838 9836 ((recov_info *)un->un_rqs->pkt_private)->cmd_bp = bp;
9839 9837 }
9840 9838
9841 9839 if (un->un_throttle) {
9842 9840 un->un_last_throttle = un->un_throttle;
9843 9841 un->un_throttle = 0;
9844 9842 }
9845 9843
9846 9844 ST_CDB(ST_DEVINFO, "Queue sense CDB",
9847 9845 (char *)BP_PKT(bp)->pkt_cdbp);
9848 9846
9849 9847 /*
9850 9848 * never retry this, some other command will have nuked the
9851 9849 * sense, anyway
9852 9850 */
9853 9851 status = st_transport(un, un->un_rqs);
9854 9852
9855 9853 if (un->un_last_throttle) {
9856 9854 un->un_throttle = un->un_last_throttle;
9857 9855 }
9858 9856
9859 9857 if (status == TRAN_ACCEPT) {
9860 9858 mutex_exit(ST_MUTEX);
9861 9859 return;
9862 9860 }
9863 9861 if (status != TRAN_BUSY)
9864 9862 ST_DO_ERRSTATS(un, st_transerrs);
9865 9863 sense_error:
9866 9864 un->un_pos.pmode = invalid;
9867 9865 st_bioerror(bp, EIO);
9868 9866 st_set_pe_flag(un);
9869 9867 break;
9870 9868
9871 9869 case QUE_BUSY_COMMAND:
9872 9870 /* longish timeout */
9873 9871 timout = ST_STATUS_BUSY_TIMEOUT;
9874 9872 goto que_it_up;
9875 9873
9876 9874 case QUE_COMMAND:
9877 9875 /* short timeout */
9878 9876 timout = ST_TRAN_BUSY_TIMEOUT;
9879 9877 que_it_up:
9880 9878 /*
9881 9879 * let st_handle_intr_busy put this bp back on waitq and make
9882 9880 * checks to see if it is ok to requeue the command.
9883 9881 */
9884 9882 ST_DO_KSTATS(bp, kstat_runq_back_to_waitq);
9885 9883
9886 9884 /*
9887 9885 * Save the throttle before setting up the timeout
9888 9886 */
9889 9887 if (un->un_throttle) {
9890 9888 un->un_last_throttle = un->un_throttle;
9891 9889 }
9892 9890 mutex_exit(ST_MUTEX);
9893 9891 if (st_handle_intr_busy(un, bp, timout) == 0)
9894 9892 return; /* timeout is setup again */
9895 9893
9896 9894 mutex_enter(ST_MUTEX);
9897 9895 un->un_pos.pmode = invalid;
9898 9896 un->un_err_resid = bp->b_resid = bp->b_bcount;
9899 9897 st_bioerror(bp, EIO);
9900 9898 st_set_pe_flag(un);
9901 9899 break;
9902 9900
9903 9901 case QUE_LAST_COMMAND:
9904 9902
9905 9903 if ((un->un_ncmds > 1) && !un->un_flush_on_errors) {
9906 9904 scsi_log(ST_DEVINFO, st_label, CE_CONT,
9907 9905 "un_ncmds: %d can't retry cmd \n", un->un_ncmds);
9908 9906 goto last_command_error;
9909 9907 }
9910 9908 mutex_exit(ST_MUTEX);
9911 9909 if (st_handle_intr_retry_lcmd(un, bp) == 0)
9912 9910 return;
9913 9911 mutex_enter(ST_MUTEX);
9914 9912 last_command_error:
9915 9913 un->un_err_resid = bp->b_resid = bp->b_bcount;
9916 9914 un->un_pos.pmode = invalid;
9917 9915 st_bioerror(bp, EIO);
9918 9916 st_set_pe_flag(un);
9919 9917 break;
9920 9918
9921 9919 case COMMAND_TIMEOUT:
9922 9920 case DEVICE_RESET:
9923 9921 case DEVICE_TAMPER:
9924 9922 case ATTEMPT_RETRY:
9925 9923 case PATH_FAILED:
9926 9924 ST_RECOV(ST_DEVINFO, st_label, CE_WARN,
9927 9925 "Command Recovery called on %s status\n",
9928 9926 errstatenames[action]);
9929 9927 action = st_command_recovery(un, pkt, action);
9930 9928 goto again;
9931 9929
9932 9930 default:
9933 9931 ASSERT(0);
9934 9932 /* FALLTHRU */
9935 9933 case JUST_RETURN:
9936 9934 ST_DO_KSTATS(bp, kstat_runq_back_to_waitq);
9937 9935 mutex_exit(ST_MUTEX);
9938 9936 return;
9939 9937 }
9940 9938
9941 9939 ST_DO_KSTATS(bp, kstat_runq_exit);
9942 9940 st_done_and_mutex_exit(un, bp);
9943 9941 }
9944 9942
9945 9943 static errstate
9946 9944 st_handle_incomplete(struct scsi_tape *un, struct buf *bp)
9947 9945 {
9948 9946 static char *fail = "SCSI transport failed: reason '%s': %s\n";
9949 9947 recov_info *rinfo;
9950 9948 errstate rval = COMMAND_DONE_ERROR;
9951 9949 struct scsi_pkt *pkt = (un->un_state == ST_STATE_SENSING) ?
9952 9950 un->un_rqs : BP_PKT(bp);
9953 9951 int result;
9954 9952
9955 9953 ST_FUNC(ST_DEVINFO, st_handle_incomplete);
9956 9954
9957 9955 rinfo = (recov_info *)pkt->pkt_private;
9958 9956
9959 9957 ST_DEBUG3(ST_DEVINFO, st_label, SCSI_DEBUG,
9960 9958 "st_handle_incomplete(): dev = 0x%lx\n", un->un_dev);
9961 9959
9962 9960 ASSERT(mutex_owned(ST_MUTEX));
9963 9961
9964 9962 /* prevent infinite number of retries */
9965 9963 if (rinfo->pkt_retry_cnt++ > st_retry_count) {
9966 9964 ST_RECOV(ST_DEVINFO, st_label, CE_NOTE,
9967 9965 "Recovery stopped for incomplete %s command, "
9968 9966 "retries exhausted",
9969 9967 st_print_scsi_cmd(pkt->pkt_cdbp[0]));
9970 9968 return (COMMAND_DONE_ERROR);
9971 9969 }
9972 9970
9973 9971 switch (pkt->pkt_reason) {
9974 9972 case CMD_INCOMPLETE: /* tran stopped with not normal state */
9975 9973 /*
9976 9974 * this occurs when accessing a powered down drive, no
9977 9975 * need to complain; just fail the open
9978 9976 */
9979 9977 ST_CDB(ST_DEVINFO, "Incomplete CDB", (char *)pkt->pkt_cdbp);
9980 9978
9981 9979 /*
9982 9980 * if we have commands outstanding in HBA, and a command
9983 9981 * comes back incomplete, we're hosed, so reset target
9984 9982 * If we have the bus, but cmd_incomplete, we probably just
9985 9983 * have a failed selection, so don't reset the target, just
9986 9984 * requeue the command and try again
9987 9985 */
9988 9986 if ((un->un_ncmds > 1) || (pkt->pkt_state != STATE_GOT_BUS)) {
9989 9987 goto reset_target;
9990 9988 }
9991 9989
9992 9990 /*
9993 9991 * Retry selection a couple more times if we're
9994 9992 * open. If opening, we only try just once to
9995 9993 * reduce probe time for nonexistant devices.
9996 9994 */
9997 9995 if ((un->un_laststate > ST_STATE_OPENING) &&
9998 9996 (rinfo->pkt_retry_cnt < st_selection_retry_count)) {
9999 9997 /* XXX check retriable? */
10000 9998 rval = QUE_COMMAND;
10001 9999 }
10002 10000 ST_DO_ERRSTATS(un, st_transerrs);
10003 10001 break;
10004 10002
10005 10003 case CMD_ABORTED:
10006 10004 /*
10007 10005 * most likely this is caused by flush-on-error support. If
10008 10006 * it was not there, the we're in trouble.
10009 10007 */
10010 10008 if (!un->un_flush_on_errors) {
10011 10009 un->un_status = SUN_KEY_FATAL;
10012 10010 goto reset_target;
10013 10011 }
10014 10012
10015 10013 st_set_pe_errno(un);
10016 10014 bioerror(bp, un->un_errno);
10017 10015 if (un->un_errno)
10018 10016 return (COMMAND_DONE_ERROR);
10019 10017 else
10020 10018 return (COMMAND_DONE);
10021 10019
10022 10020 case CMD_TIMEOUT: /* Command timed out */
10023 10021 un->un_status = SUN_KEY_TIMEOUT;
10024 10022 return (COMMAND_TIMEOUT);
10025 10023
10026 10024 case CMD_TRAN_ERR:
10027 10025 case CMD_RESET:
10028 10026 if (pkt->pkt_statistics & (STAT_BUS_RESET | STAT_DEV_RESET)) {
10029 10027 if ((un->un_rsvd_status &
10030 10028 (ST_RESERVE | ST_APPLICATION_RESERVATIONS)) ==
10031 10029 ST_RESERVE) {
10032 10030 un->un_rsvd_status |= ST_LOST_RESERVE;
10033 10031 ST_DEBUG3(ST_DEVINFO, st_label, CE_WARN,
10034 10032 "Lost Reservation\n");
10035 10033 }
10036 10034 rval = DEVICE_RESET;
10037 10035 return (rval);
10038 10036 }
10039 10037 if (pkt->pkt_statistics & (STAT_ABORTED | STAT_TERMINATED)) {
10040 10038 rval = DEVICE_RESET;
10041 10039 return (rval);
10042 10040 }
10043 10041 /*FALLTHROUGH*/
10044 10042 default:
10045 10043 scsi_log(ST_DEVINFO, st_label, CE_WARN,
10046 10044 "Unhandled packet status reason = %s statistics = 0x%x\n",
10047 10045 scsi_rname(pkt->pkt_reason), pkt->pkt_statistics);
10048 10046 reset_target:
10049 10047
10050 10048 ST_DEBUG6(ST_DEVINFO, st_label, CE_WARN,
10051 10049 "transport completed with %s\n",
10052 10050 scsi_rname(pkt->pkt_reason));
10053 10051 ST_DO_ERRSTATS(un, st_transerrs);
10054 10052 if ((pkt->pkt_state & STATE_GOT_TARGET) &&
10055 10053 ((pkt->pkt_statistics & (STAT_BUS_RESET | STAT_DEV_RESET |
10056 10054 STAT_ABORTED)) == 0)) {
10057 10055
10058 10056 /*
10059 10057 * If we haven't reserved the drive don't reset it.
10060 10058 */
10061 10059 if ((un->un_rsvd_status &
10062 10060 (ST_RESERVE | ST_APPLICATION_RESERVATIONS)) == 0) {
10063 10061 return (rval);
10064 10062 }
10065 10063
10066 10064 /*
10067 10065 * if we aren't lost yet we will be soon.
10068 10066 */
10069 10067 un->un_pos.pmode = invalid;
10070 10068
10071 10069 result = st_reset(un, RESET_LUN);
10072 10070
10073 10071 if ((result == 0) && (un->un_state >= ST_STATE_OPEN)) {
10074 10072 /* no hope left to recover */
10075 10073 scsi_log(ST_DEVINFO, st_label, CE_WARN,
10076 10074 "recovery by resets failed\n");
10077 10075 return (rval);
10078 10076 }
10079 10077 }
10080 10078 }
10081 10079
10082 10080
10083 10081 if (un->un_pwr_mgmt == ST_PWR_SUSPENDED) {
10084 10082 rval = QUE_COMMAND;
10085 10083 } else if (bp == un->un_sbufp) {
10086 10084 if (rinfo->privatelen == sizeof (recov_info)) {
10087 10085 if (rinfo->cmd_attrib->retriable) {
10088 10086 /*
10089 10087 * These commands can be rerun
10090 10088 * with impunity
10091 10089 */
10092 10090 rval = QUE_COMMAND;
10093 10091 }
10094 10092 } else {
10095 10093 cmd_attribute const *attrib;
10096 10094 attrib = st_lookup_cmd_attribute(pkt->pkt_cdbp[0]);
10097 10095 if (attrib->retriable) {
10098 10096 rval = QUE_COMMAND;
10099 10097 }
10100 10098 }
10101 10099 }
10102 10100
10103 10101 if (un->un_state >= ST_STATE_OPEN) {
10104 10102 scsi_log(ST_DEVINFO, st_label, CE_WARN,
10105 10103 fail, scsi_rname(pkt->pkt_reason),
10106 10104 (rval == COMMAND_DONE_ERROR)?
10107 10105 "giving up" : "retrying command");
10108 10106 }
10109 10107 return (rval);
10110 10108 }
10111 10109
10112 10110 /*
10113 10111 * if the device is busy, then put this bp back on the waitq, on the
10114 10112 * interrupt thread, where we want the head of the queue and not the
10115 10113 * end
10116 10114 *
10117 10115 * The callers of this routine should take measures to save the
10118 10116 * un_throttle in un_last_throttle which will be restored in
10119 10117 * st_intr_restart(). The only exception should be st_intr_restart()
10120 10118 * calling this routine for which the saving is already done.
10121 10119 */
10122 10120 static int
10123 10121 st_handle_intr_busy(struct scsi_tape *un, struct buf *bp,
10124 10122 clock_t timeout_interval)
10125 10123 {
10126 10124
10127 10125 int queued;
10128 10126 int rval = 0;
10129 10127 pkt_info *pktinfo = BP_PKT(bp)->pkt_private;
10130 10128
10131 10129 mutex_enter(ST_MUTEX);
10132 10130
10133 10131 ST_FUNC(ST_DEVINFO, st_handle_intr_busy);
10134 10132
10135 10133 ST_DEBUG3(ST_DEVINFO, st_label, SCSI_DEBUG,
10136 10134 "st_handle_intr_busy(), un = 0x%p\n", (void *)un);
10137 10135
10138 10136 if ((bp != un->un_sbufp) && (bp != un->un_recov_buf)) {
10139 10137 queued = 1;
10140 10138 } else {
10141 10139 queued = 0;
10142 10140 }
10143 10141
10144 10142 /*
10145 10143 * Check to see if we hit the retry timeout. We check to make sure
10146 10144 * this is the first one on the runq and make sure we have not
10147 10145 * queued up any more, so this one has to be the last on the list
10148 10146 * also. If it is not, we have to fail. If it is not the first, but
10149 10147 * is the last we are in trouble anyway, as we are in the interrupt
10150 10148 * context here.
10151 10149 */
10152 10150 if ((pktinfo->str_retry_cnt++ > st_retry_count) ||
10153 10151 ((un->un_runqf != bp) && (un->un_runql != bp) && (queued))) {
10154 10152 rval = -1;
10155 10153 goto exit;
10156 10154 }
10157 10155
10158 10156 /* put the bp back on the waitq */
10159 10157 if (queued) {
10160 10158 (void) st_remove_from_queue(&un->un_runqf, &un->un_runql, bp);
10161 10159 st_add_to_queue(&un->un_quef, &un->un_quel, un->un_quef, bp);
10162 10160 }
10163 10161
10164 10162 /*
10165 10163 * We don't want any other commands being started in the mean time.
10166 10164 * If start had just released mutex after putting something on the
10167 10165 * runq, we won't even get here.
10168 10166 */
10169 10167 un->un_throttle = 0;
10170 10168
10171 10169 /*
10172 10170 * send a marker pkt, if appropriate
10173 10171 */
10174 10172 st_hba_unflush(un);
10175 10173
10176 10174 /*
10177 10175 * all queues are aligned, we are just waiting to
10178 10176 * transport
10179 10177 */
10180 10178 un->un_hib_tid = timeout(st_intr_restart, un, timeout_interval);
10181 10179
10182 10180 exit:
10183 10181 mutex_exit(ST_MUTEX);
10184 10182 return (rval);
10185 10183 }
10186 10184
10187 10185 /*
10188 10186 * To get one error entry from error stack
10189 10187 */
10190 10188 static int
10191 10189 st_get_error_entry(struct scsi_tape *un, intptr_t arg, int flag)
10192 10190 {
10193 10191 #ifdef _MULTI_DATAMODEL
10194 10192 /*
10195 10193 * For use when a 32 bit app makes a call into a
10196 10194 * 64 bit ioctl
10197 10195 */
10198 10196 struct mterror_entry32 err_entry32;
10199 10197 #endif /* _MULTI_DATAMODEL */
10200 10198
10201 10199 int rval = 0;
10202 10200 struct mterror_entry err_entry;
10203 10201 struct mterror_entry_stack *err_link_entry_p;
10204 10202 size_t arq_status_len_in, arq_status_len_kr;
10205 10203
10206 10204 ST_FUNC(ST_DEVINFO, st_get_error_entry);
10207 10205
10208 10206 ASSERT(mutex_owned(ST_MUTEX));
10209 10207
10210 10208 ST_DEBUG3(ST_DEVINFO, st_label, SCSI_DEBUG,
10211 10209 "st_get_error_entry()\n");
10212 10210
10213 10211 /*
10214 10212 * if error record stack empty, return ENXIO
10215 10213 */
10216 10214 if (un->un_error_entry_stk == NULL) {
10217 10215 ST_DEBUG4(ST_DEVINFO, st_label, SCSI_DEBUG,
10218 10216 "st_get_error_entry: Error Entry Stack Empty!\n");
10219 10217 rval = ENXIO;
10220 10218 goto ret;
10221 10219 }
10222 10220
10223 10221 /*
10224 10222 * get the top entry from stack
10225 10223 */
10226 10224 err_link_entry_p = un->un_error_entry_stk;
10227 10225 arq_status_len_kr =
10228 10226 err_link_entry_p->mtees_entry.mtee_arq_status_len;
10229 10227
10230 10228 #ifdef _MULTI_DATAMODEL
10231 10229 switch (ddi_model_convert_from(flag & FMODELS)) {
10232 10230 case DDI_MODEL_ILP32:
10233 10231 if (ddi_copyin((void *)arg, &err_entry32,
10234 10232 MTERROR_ENTRY_SIZE_32, flag)) {
10235 10233 rval = EFAULT;
10236 10234 goto ret;
10237 10235 }
10238 10236
10239 10237 arq_status_len_in =
10240 10238 (size_t)err_entry32.mtee_arq_status_len;
10241 10239
10242 10240 err_entry32.mtee_cdb_len =
10243 10241 (size32_t)err_link_entry_p->mtees_entry.mtee_cdb_len;
10244 10242
10245 10243 if (arq_status_len_in > arq_status_len_kr)
10246 10244 err_entry32.mtee_arq_status_len =
10247 10245 (size32_t)arq_status_len_kr;
10248 10246
10249 10247 if (ddi_copyout(
10250 10248 err_link_entry_p->mtees_entry.mtee_cdb_buf,
10251 10249 (void *)(uintptr_t)err_entry32.mtee_cdb_buf,
10252 10250 err_entry32.mtee_cdb_len, flag)) {
10253 10251 ST_DEBUG4(ST_DEVINFO, st_label, SCSI_DEBUG,
10254 10252 "st_get_error_entry: Copy cdb buffer error!");
10255 10253 rval = EFAULT;
10256 10254 }
10257 10255
10258 10256 if (ddi_copyout(
10259 10257 err_link_entry_p->mtees_entry.mtee_arq_status,
10260 10258 (void *)(uintptr_t)err_entry32.mtee_arq_status,
10261 10259 err_entry32.mtee_arq_status_len, flag)) {
10262 10260 ST_DEBUG4(ST_DEVINFO, st_label, SCSI_DEBUG,
10263 10261 "st_get_error_entry: copy arq status error!");
10264 10262 rval = EFAULT;
10265 10263 }
10266 10264
10267 10265 if (ddi_copyout(&err_entry32, (void *)arg,
10268 10266 MTERROR_ENTRY_SIZE_32, flag)) {
10269 10267 ST_DEBUG4(ST_DEVINFO, st_label, SCSI_DEBUG,
10270 10268 "st_get_error_entry: copy arq status out error!");
10271 10269 rval = EFAULT;
10272 10270 }
10273 10271 break;
10274 10272
10275 10273 case DDI_MODEL_NONE:
10276 10274 if (ddi_copyin((void *)arg, &err_entry,
10277 10275 MTERROR_ENTRY_SIZE_64, flag)) {
10278 10276 rval = EFAULT;
10279 10277 goto ret;
10280 10278 }
10281 10279 arq_status_len_in = err_entry.mtee_arq_status_len;
10282 10280
10283 10281 err_entry.mtee_cdb_len =
10284 10282 err_link_entry_p->mtees_entry.mtee_cdb_len;
10285 10283
10286 10284 if (arq_status_len_in > arq_status_len_kr)
10287 10285 err_entry.mtee_arq_status_len =
10288 10286 arq_status_len_kr;
10289 10287
10290 10288 if (ddi_copyout(
10291 10289 err_link_entry_p->mtees_entry.mtee_cdb_buf,
10292 10290 err_entry.mtee_cdb_buf,
10293 10291 err_entry.mtee_cdb_len, flag)) {
10294 10292 ST_DEBUG4(ST_DEVINFO, st_label, SCSI_DEBUG,
10295 10293 "st_get_error_entry: Copy cdb buffer error!");
10296 10294 rval = EFAULT;
10297 10295 }
10298 10296
10299 10297 if (ddi_copyout(
10300 10298 err_link_entry_p->mtees_entry.mtee_arq_status,
10301 10299 err_entry.mtee_arq_status,
10302 10300 err_entry.mtee_arq_status_len, flag)) {
10303 10301 ST_DEBUG4(ST_DEVINFO, st_label, SCSI_DEBUG,
10304 10302 "st_get_error_entry: copy arq status error!");
10305 10303 rval = EFAULT;
10306 10304 }
10307 10305
10308 10306 if (ddi_copyout(&err_entry, (void *)arg,
10309 10307 MTERROR_ENTRY_SIZE_64, flag)) {
10310 10308 ST_DEBUG4(ST_DEVINFO, st_label, SCSI_DEBUG,
10311 10309 "st_get_error_entry: copy arq status out error!");
10312 10310 rval = EFAULT;
10313 10311 }
10314 10312 break;
10315 10313 }
10316 10314 #else /* _MULTI_DATAMODEL */
10317 10315 if (ddi_copyin((void *)arg, &err_entry,
10318 10316 MTERROR_ENTRY_SIZE_64, flag)) {
10319 10317 rval = EFAULT;
10320 10318 goto ret;
10321 10319 }
10322 10320 arq_status_len_in = err_entry.mtee_arq_status_len;
10323 10321
10324 10322 err_entry.mtee_cdb_len =
10325 10323 err_link_entry_p->mtees_entry.mtee_cdb_len;
10326 10324
10327 10325 if (arq_status_len_in > arq_status_len_kr)
10328 10326 err_entry.mtee_arq_status_len =
10329 10327 arq_status_len_kr;
10330 10328
10331 10329 if (ddi_copyout(
10332 10330 err_link_entry_p->mtees_entry.mtee_cdb_buf,
10333 10331 err_entry.mtee_cdb_buf,
10334 10332 err_entry.mtee_cdb_len, flag)) {
10335 10333 ST_DEBUG4(ST_DEVINFO, st_label, SCSI_DEBUG,
10336 10334 "st_get_error_entry: Copy cdb buffer error!");
10337 10335 rval = EFAULT;
10338 10336 }
10339 10337
10340 10338 if (ddi_copyout(
10341 10339 err_link_entry_p->mtees_entry.mtee_arq_status,
10342 10340 err_entry.mtee_arq_status,
10343 10341 err_entry.mtee_arq_status_len, flag)) {
10344 10342 ST_DEBUG4(ST_DEVINFO, st_label, SCSI_DEBUG,
10345 10343 "st_get_error_entry: copy arq status buffer error!");
10346 10344 rval = EFAULT;
10347 10345 }
10348 10346
10349 10347 if (ddi_copyout(&err_entry, (void *)arg,
10350 10348 MTERROR_ENTRY_SIZE_64, flag)) {
10351 10349 ST_DEBUG4(ST_DEVINFO, st_label, SCSI_DEBUG,
10352 10350 "st_get_error_entry: copy arq status out error!");
10353 10351 rval = EFAULT;
10354 10352 }
10355 10353 #endif /* _MULTI_DATAMODEL */
10356 10354
10357 10355 /*
10358 10356 * update stack
10359 10357 */
10360 10358 un->un_error_entry_stk = err_link_entry_p->mtees_nextp;
10361 10359
10362 10360 kmem_free(err_link_entry_p->mtees_entry.mtee_cdb_buf,
10363 10361 err_link_entry_p->mtees_entry.mtee_cdb_len);
10364 10362 err_link_entry_p->mtees_entry.mtee_cdb_buf = NULL;
10365 10363
10366 10364 kmem_free(err_link_entry_p->mtees_entry.mtee_arq_status,
10367 10365 SECMDS_STATUS_SIZE);
10368 10366 err_link_entry_p->mtees_entry.mtee_arq_status = NULL;
10369 10367
10370 10368 kmem_free(err_link_entry_p, MTERROR_LINK_ENTRY_SIZE);
10371 10369 err_link_entry_p = NULL;
10372 10370 ret:
10373 10371 return (rval);
10374 10372 }
10375 10373
10376 10374 /*
10377 10375 * MTIOCGETERROR ioctl needs to retrieve the current sense data along with
10378 10376 * the scsi CDB command which causes the error and generates sense data and
10379 10377 * the scsi status.
10380 10378 *
10381 10379 * error-record stack
10382 10380 *
10383 10381 *
10384 10382 * TOP BOTTOM
10385 10383 * ------------------------------------------
10386 10384 * | 0 | 1 | 2 | ... | n |
10387 10385 * ------------------------------------------
10388 10386 * ^
10389 10387 * |
10390 10388 * pointer to error entry
10391 10389 *
10392 10390 * when st driver generates one sense data record, it creates a error-entry
10393 10391 * and pushes it onto the stack.
10394 10392 *
10395 10393 */
10396 10394
10397 10395 static void
10398 10396 st_update_error_stack(struct scsi_tape *un,
10399 10397 struct scsi_pkt *pkt,
10400 10398 struct scsi_arq_status *cmd)
10401 10399 {
10402 10400 struct mterror_entry_stack *err_entry_tmp;
10403 10401 uchar_t *cdbp = (uchar_t *)pkt->pkt_cdbp;
10404 10402 size_t cdblen = scsi_cdb_size[CDB_GROUPID(cdbp[0])];
10405 10403
10406 10404 ST_FUNC(ST_DEVINFO, st_update_error_stack);
10407 10405
10408 10406 ASSERT(mutex_owned(ST_MUTEX));
10409 10407
10410 10408 ST_DEBUG3(ST_DEVINFO, st_label, SCSI_DEBUG,
10411 10409 "st_update_error_stack()\n");
10412 10410
10413 10411 ASSERT(cmd);
10414 10412 ASSERT(cdbp);
10415 10413 if (cdblen == 0) {
10416 10414 ST_DEBUG3(ST_DEVINFO, st_label, SCSI_DEBUG,
10417 10415 "st_update_error_stack: CDB length error!\n");
10418 10416 return;
10419 10417 }
10420 10418
10421 10419 err_entry_tmp = kmem_alloc(MTERROR_LINK_ENTRY_SIZE, KM_SLEEP);
10422 10420 ASSERT(err_entry_tmp != NULL);
10423 10421
10424 10422 err_entry_tmp->mtees_entry.mtee_cdb_buf =
10425 10423 kmem_alloc(cdblen, KM_SLEEP);
10426 10424 ASSERT(err_entry_tmp->mtees_entry.mtee_cdb_buf != NULL);
10427 10425
10428 10426 err_entry_tmp->mtees_entry.mtee_arq_status =
10429 10427 kmem_alloc(SECMDS_STATUS_SIZE, KM_SLEEP);
10430 10428 ASSERT(err_entry_tmp->mtees_entry.mtee_arq_status != NULL);
10431 10429
10432 10430 /*
10433 10431 * copy cdb command & length to current error entry
10434 10432 */
10435 10433 err_entry_tmp->mtees_entry.mtee_cdb_len = cdblen;
10436 10434 bcopy(cdbp, err_entry_tmp->mtees_entry.mtee_cdb_buf, cdblen);
10437 10435
10438 10436 /*
10439 10437 * copy scsi status length to current error entry
10440 10438 */
10441 10439 err_entry_tmp->mtees_entry.mtee_arq_status_len =
10442 10440 SECMDS_STATUS_SIZE;
10443 10441
10444 10442 /*
10445 10443 * copy sense data and scsi status to current error entry
10446 10444 */
10447 10445 bcopy(cmd, err_entry_tmp->mtees_entry.mtee_arq_status,
10448 10446 SECMDS_STATUS_SIZE);
10449 10447
10450 10448 err_entry_tmp->mtees_nextp = un->un_error_entry_stk;
10451 10449 un->un_error_entry_stk = err_entry_tmp;
10452 10450
10453 10451 }
10454 10452
10455 10453 /*
10456 10454 * Empty all the error entry in stack
10457 10455 */
10458 10456 static void
10459 10457 st_empty_error_stack(struct scsi_tape *un)
10460 10458 {
10461 10459 struct mterror_entry_stack *linkp;
10462 10460
10463 10461 ST_FUNC(ST_DEVINFO, st_empty_error_stack);
10464 10462
10465 10463 ASSERT(mutex_owned(ST_MUTEX));
10466 10464
10467 10465 ST_DEBUG3(ST_DEVINFO, st_label, SCSI_DEBUG,
10468 10466 "st_empty_entry_stack()\n");
10469 10467
10470 10468 while (un->un_error_entry_stk != NULL) {
10471 10469 linkp = un->un_error_entry_stk;
10472 10470 un->un_error_entry_stk =
10473 10471 un->un_error_entry_stk->mtees_nextp;
10474 10472
10475 10473 if (linkp->mtees_entry.mtee_cdb_buf != NULL)
10476 10474 kmem_free(linkp->mtees_entry.mtee_cdb_buf,
10477 10475 linkp->mtees_entry.mtee_cdb_len);
10478 10476
10479 10477 if (linkp->mtees_entry.mtee_arq_status != NULL)
10480 10478 kmem_free(linkp->mtees_entry.mtee_arq_status,
10481 10479 linkp->mtees_entry.mtee_arq_status_len);
10482 10480
10483 10481 kmem_free(linkp, MTERROR_LINK_ENTRY_SIZE);
10484 10482 linkp = NULL;
10485 10483 }
10486 10484 }
10487 10485
10488 10486 static errstate
10489 10487 st_handle_sense(struct scsi_tape *un, struct buf *bp, tapepos_t *pos)
10490 10488 {
10491 10489 struct scsi_pkt *pkt = BP_PKT(bp);
10492 10490 struct scsi_pkt *rqpkt = un->un_rqs;
10493 10491 struct scsi_arq_status arqstat;
10494 10492 recov_info *rcif = pkt->pkt_private;
10495 10493
10496 10494 errstate rval = COMMAND_DONE_ERROR;
10497 10495 int amt;
10498 10496
10499 10497 ST_FUNC(ST_DEVINFO, st_handle_sense);
10500 10498
10501 10499 ASSERT(mutex_owned(ST_MUTEX));
10502 10500
10503 10501 ST_DEBUG3(ST_DEVINFO, st_label, SCSI_DEBUG,
10504 10502 "st_handle_sense()\n");
10505 10503
10506 10504 if (SCBP(rqpkt)->sts_busy) {
10507 10505 if (rcif->privatelen == sizeof (recov_info)) {
10508 10506 ST_RECOV(ST_DEVINFO, st_label, CE_WARN,
10509 10507 "Attempt recovery of busy unit on request sense\n");
10510 10508 rval = ATTEMPT_RETRY;
10511 10509 } else if (rcif->pkt_retry_cnt++ < st_retry_count) {
10512 10510 ST_DEBUG4(ST_DEVINFO, st_label, CE_WARN,
10513 10511 "Retry busy unit on request sense\n");
10514 10512 rval = QUE_BUSY_COMMAND;
10515 10513 }
10516 10514 return (rval);
10517 10515 } else if (SCBP(rqpkt)->sts_chk) {
10518 10516 ST_DEBUG6(ST_DEVINFO, st_label, CE_WARN,
10519 10517 "Check Condition on REQUEST SENSE\n");
10520 10518 return (rval);
10521 10519 }
10522 10520
10523 10521 /*
10524 10522 * Make sure there is sense data to look at.
10525 10523 */
10526 10524 if ((rqpkt->pkt_state & (STATE_GOT_BUS | STATE_GOT_TARGET |
10527 10525 STATE_SENT_CMD | STATE_GOT_STATUS)) != (STATE_GOT_BUS |
10528 10526 STATE_GOT_TARGET | STATE_SENT_CMD | STATE_GOT_STATUS)) {
10529 10527 return (rval);
10530 10528 }
10531 10529
10532 10530 /* was there enough data? */
10533 10531 amt = (int)MAX_SENSE_LENGTH - rqpkt->pkt_resid;
10534 10532 if ((rqpkt->pkt_state & STATE_XFERRED_DATA) == 0 ||
10535 10533 (amt < SUN_MIN_SENSE_LENGTH)) {
10536 10534 ST_DEBUG6(ST_DEVINFO, st_label, CE_WARN,
10537 10535 "REQUEST SENSE couldn't get sense data\n");
10538 10536 return (rval);
10539 10537 }
10540 10538
10541 10539 bcopy(SCBP(pkt), &arqstat.sts_status,
10542 10540 sizeof (struct scsi_status));
10543 10541 bcopy(SCBP(rqpkt), &arqstat.sts_rqpkt_status,
10544 10542 sizeof (struct scsi_status));
10545 10543 arqstat.sts_rqpkt_reason = rqpkt->pkt_reason;
10546 10544 arqstat.sts_rqpkt_resid = rqpkt->pkt_resid;
10547 10545 arqstat.sts_rqpkt_state = rqpkt->pkt_state;
10548 10546 arqstat.sts_rqpkt_statistics = rqpkt->pkt_statistics;
10549 10547 bcopy(ST_RQSENSE, &arqstat.sts_sensedata, SENSE_LENGTH);
10550 10548
10551 10549 /*
10552 10550 * copy one arqstat entry in the sense data buffer
10553 10551 */
10554 10552 st_update_error_stack(un, pkt, &arqstat);
10555 10553 return (st_decode_sense(un, bp, amt, &arqstat, pos));
10556 10554 }
10557 10555
10558 10556 static errstate
10559 10557 st_handle_autosense(struct scsi_tape *un, struct buf *bp, tapepos_t *pos)
10560 10558 {
10561 10559 struct scsi_pkt *pkt = BP_PKT(bp);
10562 10560 struct scsi_arq_status *arqstat =
10563 10561 (struct scsi_arq_status *)pkt->pkt_scbp;
10564 10562 errstate rval = COMMAND_DONE_ERROR;
10565 10563 int amt;
10566 10564
10567 10565 ST_FUNC(ST_DEVINFO, st_handle_autosense);
10568 10566
10569 10567 ASSERT(mutex_owned(ST_MUTEX));
10570 10568
10571 10569 ST_DEBUG3(ST_DEVINFO, st_label, SCSI_DEBUG,
10572 10570 "st_handle_autosense()\n");
10573 10571
10574 10572 if (arqstat->sts_rqpkt_status.sts_busy) {
10575 10573 ST_DEBUG4(ST_DEVINFO, st_label, CE_WARN,
10576 10574 "busy unit on request sense\n");
10577 10575 /*
10578 10576 * we return QUE_SENSE so st_intr will setup the SENSE cmd.
10579 10577 * the disadvantage is that we do not have any delay for the
10580 10578 * second retry of rqsense and we have to keep a packet around
10581 10579 */
10582 10580 return (QUE_SENSE);
10583 10581
10584 10582 } else if (arqstat->sts_rqpkt_reason != CMD_CMPLT) {
10585 10583 ST_DEBUG6(ST_DEVINFO, st_label, CE_WARN,
10586 10584 "transport error on REQUEST SENSE\n");
10587 10585 if ((arqstat->sts_rqpkt_state & STATE_GOT_TARGET) &&
10588 10586 ((arqstat->sts_rqpkt_statistics &
10589 10587 (STAT_BUS_RESET | STAT_DEV_RESET | STAT_ABORTED)) == 0)) {
10590 10588 if (st_reset(un, RESET_LUN) == 0) {
10591 10589 ST_DEBUG6(ST_DEVINFO, st_label, CE_WARN,
10592 10590 "recovery by resets failed\n");
10593 10591 }
10594 10592 }
10595 10593 return (rval);
10596 10594
10597 10595 } else if (arqstat->sts_rqpkt_status.sts_chk) {
10598 10596 ST_DEBUG6(ST_DEVINFO, st_label, CE_WARN,
10599 10597 "Check Condition on REQUEST SENSE\n");
10600 10598 return (rval);
10601 10599 }
10602 10600
10603 10601
10604 10602 /* was there enough data? */
10605 10603 if (pkt->pkt_state & STATE_XARQ_DONE) {
10606 10604 amt = (int)MAX_SENSE_LENGTH - arqstat->sts_rqpkt_resid;
10607 10605 } else {
10608 10606 if (arqstat->sts_rqpkt_resid > SENSE_LENGTH) {
10609 10607 amt = (int)MAX_SENSE_LENGTH - arqstat->sts_rqpkt_resid;
10610 10608 } else {
10611 10609 amt = (int)SENSE_LENGTH - arqstat->sts_rqpkt_resid;
10612 10610 }
10613 10611 }
10614 10612 if ((arqstat->sts_rqpkt_state & STATE_XFERRED_DATA) == 0 ||
10615 10613 (amt < SUN_MIN_SENSE_LENGTH)) {
10616 10614 ST_DEBUG6(ST_DEVINFO, st_label, CE_WARN,
10617 10615 "REQUEST SENSE couldn't get sense data\n");
10618 10616 return (rval);
10619 10617 }
10620 10618
10621 10619 if (pkt->pkt_state & STATE_XARQ_DONE) {
10622 10620 bcopy(&arqstat->sts_sensedata, ST_RQSENSE, MAX_SENSE_LENGTH);
10623 10621 } else {
10624 10622 bcopy(&arqstat->sts_sensedata, ST_RQSENSE, SENSE_LENGTH);
10625 10623 }
10626 10624
10627 10625 /*
10628 10626 * copy one arqstat entry in the sense data buffer
10629 10627 */
10630 10628 st_update_error_stack(un, pkt, arqstat);
10631 10629
10632 10630 return (st_decode_sense(un, bp, amt, arqstat, pos));
10633 10631 }
10634 10632
10635 10633 static errstate
10636 10634 st_decode_sense(struct scsi_tape *un, struct buf *bp, int amt,
10637 10635 struct scsi_arq_status *statusp, tapepos_t *pos)
10638 10636 {
10639 10637 struct scsi_pkt *pkt = BP_PKT(bp);
10640 10638 recov_info *ri = pkt->pkt_private;
10641 10639 errstate rval = COMMAND_DONE_ERROR;
10642 10640 cmd_attribute const *attrib;
10643 10641 long resid;
10644 10642 struct scsi_extended_sense *sensep = ST_RQSENSE;
10645 10643 int severity;
10646 10644 int get_error;
10647 10645
10648 10646 ST_FUNC(ST_DEVINFO, st_decode_sense);
10649 10647
10650 10648 ASSERT(mutex_owned(ST_MUTEX));
10651 10649 ST_DEBUG3(ST_DEVINFO, st_label, SCSI_DEBUG,
10652 10650 "st_decode_sense()\n");
10653 10651
10654 10652 /*
10655 10653 * For uscsi commands, squirrel away a copy of the
10656 10654 * results of the Request Sense.
10657 10655 */
10658 10656 if (USCSI_CMD(bp)) {
10659 10657 struct uscsi_cmd *ucmd = BP_UCMD(bp);
10660 10658 ucmd->uscsi_rqstatus = *(uchar_t *)statusp;
10661 10659 if (ucmd->uscsi_rqlen && un->un_srqbufp) {
10662 10660 uchar_t rqlen = min((uchar_t)amt, ucmd->uscsi_rqlen);
10663 10661 ucmd->uscsi_rqresid = ucmd->uscsi_rqlen - rqlen;
10664 10662 bcopy(ST_RQSENSE, un->un_srqbufp, rqlen);
10665 10663 ST_DEBUG4(ST_DEVINFO, st_label, SCSI_DEBUG,
10666 10664 "st_decode_sense: stat=0x%x resid=0x%x\n",
10667 10665 ucmd->uscsi_rqstatus, ucmd->uscsi_rqresid);
10668 10666 }
10669 10667 }
10670 10668
10671 10669 if (ri->privatelen == sizeof (recov_info)) {
10672 10670 attrib = ri->cmd_attrib;
10673 10671 } else {
10674 10672 attrib = st_lookup_cmd_attribute(pkt->pkt_cdbp[0]);
10675 10673 }
10676 10674
10677 10675 /*
10678 10676 * If the drive is an MT-02, reposition the
10679 10677 * secondary error code into the proper place.
10680 10678 *
10681 10679 * XXX MT-02 is non-CCS tape, so secondary error code
10682 10680 * is in byte 8. However, in SCSI-2, tape has CCS definition
10683 10681 * so it's in byte 12.
10684 10682 */
10685 10683 if (un->un_dp->type == ST_TYPE_EMULEX) {
10686 10684 sensep->es_code = sensep->es_add_info[0];
10687 10685 }
10688 10686
10689 10687 ST_CDB(ST_DEVINFO, "st_decode_sense failed CDB",
10690 10688 (caddr_t)&CDBP(pkt)->scc_cmd);
10691 10689
10692 10690 ST_SENSE(ST_DEVINFO, "st_decode_sense sense data", (caddr_t)statusp,
10693 10691 sizeof (*statusp));
10694 10692
10695 10693 /* for normal I/O check extract the resid values. */
10696 10694 if (bp != un->un_sbufp && bp != un->un_recov_buf) {
10697 10695 if (sensep->es_valid) {
10698 10696 resid =
10699 10697 (sensep->es_info_1 << 24) |
10700 10698 (sensep->es_info_2 << 16) |
10701 10699 (sensep->es_info_3 << 8) |
10702 10700 (sensep->es_info_4);
10703 10701 /* If fixed block */
10704 10702 if (un->un_bsize) {
10705 10703 resid *= un->un_bsize;
10706 10704 }
10707 10705 } else if (pkt->pkt_state & STATE_XFERRED_DATA) {
10708 10706 resid = pkt->pkt_resid;
10709 10707 } else {
10710 10708 resid = bp->b_bcount;
10711 10709 }
10712 10710 ST_DEBUG6(ST_DEVINFO, st_label, SCSI_DEBUG,
10713 10711 "st_decode_sense (rw): xferred bit = %d, resid=%ld (%d), "
10714 10712 "pkt_resid=%ld\n", pkt->pkt_state & STATE_XFERRED_DATA,
10715 10713 resid,
10716 10714 (sensep->es_info_1 << 24) |
10717 10715 (sensep->es_info_2 << 16) |
10718 10716 (sensep->es_info_3 << 8) |
10719 10717 (sensep->es_info_4),
10720 10718 pkt->pkt_resid);
10721 10719 /*
10722 10720 * The problem is, what should we believe?
10723 10721 */
10724 10722 if (resid && (pkt->pkt_resid == 0)) {
10725 10723 pkt->pkt_resid = resid;
10726 10724 }
10727 10725 } else {
10728 10726 /*
10729 10727 * If the command is SCMD_SPACE, we need to get the
10730 10728 * residual as returned in the sense data, to adjust
10731 10729 * our idea of current tape position correctly
10732 10730 */
10733 10731 if ((sensep->es_valid) &&
10734 10732 (CDBP(pkt)->scc_cmd == SCMD_LOCATE) ||
10735 10733 (CDBP(pkt)->scc_cmd == SCMD_LOCATE_G4) ||
10736 10734 (CDBP(pkt)->scc_cmd == SCMD_SPACE) ||
10737 10735 (CDBP(pkt)->scc_cmd == SCMD_SPACE_G4) ||
10738 10736 (CDBP(pkt)->scc_cmd == SCMD_WRITE_FILE_MARK)) {
10739 10737 resid =
10740 10738 (sensep->es_info_1 << 24) |
10741 10739 (sensep->es_info_2 << 16) |
10742 10740 (sensep->es_info_3 << 8) |
10743 10741 (sensep->es_info_4);
10744 10742 bp->b_resid = resid;
10745 10743 ST_DEBUG6(ST_DEVINFO, st_label, SCSI_DEBUG,
10746 10744 "st_decode_sense(other): resid=%ld\n", resid);
10747 10745 } else {
10748 10746 /*
10749 10747 * If the special command is SCMD_READ,
10750 10748 * the correct resid will be set later.
10751 10749 */
10752 10750 if (attrib->get_cnt != NULL) {
10753 10751 resid = attrib->get_cnt(pkt->pkt_cdbp);
10754 10752 } else {
10755 10753 resid = bp->b_bcount;
10756 10754 }
10757 10755 ST_DEBUG6(ST_DEVINFO, st_label, SCSI_DEBUG,
10758 10756 "st_decode_sense(special read): resid=%ld\n",
10759 10757 resid);
10760 10758 }
10761 10759 }
10762 10760
10763 10761 if ((un->un_state >= ST_STATE_OPEN) &&
10764 10762 (DEBUGGING || st_error_level == SCSI_ERR_ALL)) {
10765 10763 st_print_cdb(ST_DEVINFO, st_label, CE_NOTE,
10766 10764 "Failed CDB", (char *)pkt->pkt_cdbp);
10767 10765 st_clean_print(ST_DEVINFO, st_label, CE_CONT,
10768 10766 "sense data", (char *)sensep, amt);
10769 10767 scsi_log(ST_DEVINFO, st_label, CE_CONT,
10770 10768 "count 0x%lx resid 0x%lx pktresid 0x%lx\n",
10771 10769 bp->b_bcount, resid, pkt->pkt_resid);
10772 10770 }
10773 10771
10774 10772 switch (un->un_status = sensep->es_key) {
10775 10773 case KEY_NO_SENSE:
10776 10774 severity = SCSI_ERR_INFO;
10777 10775
10778 10776 /*
10779 10777 * Erase, locate or rewind operation in progress, retry
10780 10778 * ASC ASCQ
10781 10779 * 00 18 Erase operation in progress
10782 10780 * 00 19 Locate operation in progress
10783 10781 * 00 1A Rewind operation in progress
10784 10782 */
10785 10783 if (sensep->es_add_code == 0 &&
10786 10784 ((sensep->es_qual_code == 0x18) ||
10787 10785 (sensep->es_qual_code == 0x19) ||
10788 10786 (sensep->es_qual_code == 0x1a))) {
10789 10787 rval = QUE_BUSY_COMMAND;
10790 10788 break;
10791 10789 }
10792 10790
10793 10791 goto common;
10794 10792
10795 10793 case KEY_RECOVERABLE_ERROR:
10796 10794 severity = SCSI_ERR_RECOVERED;
10797 10795 if ((sensep->es_class == CLASS_EXTENDED_SENSE) &&
10798 10796 (sensep->es_code == ST_DEFERRED_ERROR)) {
10799 10797 if (un->un_dp->options &
10800 10798 ST_RETRY_ON_RECOVERED_DEFERRED_ERROR) {
10801 10799 rval = QUE_LAST_COMMAND;
10802 10800 scsi_errmsg(ST_SCSI_DEVP, pkt, st_label,
10803 10801 severity, pos->lgclblkno,
10804 10802 un->un_err_pos.lgclblkno, scsi_cmds,
10805 10803 sensep);
10806 10804 scsi_log(ST_DEVINFO, st_label, CE_CONT,
10807 10805 "Command will be retried\n");
10808 10806 } else {
10809 10807 severity = SCSI_ERR_FATAL;
10810 10808 rval = COMMAND_DONE_ERROR_RECOVERED;
10811 10809 ST_DO_ERRSTATS(un, st_softerrs);
10812 10810 scsi_errmsg(ST_SCSI_DEVP, pkt, st_label,
10813 10811 severity, pos->lgclblkno,
10814 10812 un->un_err_pos.lgclblkno, scsi_cmds,
10815 10813 sensep);
10816 10814 }
10817 10815 break;
10818 10816 }
10819 10817 common:
10820 10818 /*
10821 10819 * XXX only want reads to be stopped by filemarks.
10822 10820 * Don't want them to be stopped by EOT. EOT matters
10823 10821 * only on write.
10824 10822 */
10825 10823 if (sensep->es_filmk && !sensep->es_eom) {
10826 10824 rval = COMMAND_DONE;
10827 10825 } else if (sensep->es_eom) {
10828 10826 rval = COMMAND_DONE;
10829 10827 } else if (sensep->es_ili) {
10830 10828 /*
10831 10829 * Fun with variable length record devices:
10832 10830 * for specifying larger blocks sizes than the
10833 10831 * actual physical record size.
10834 10832 */
10835 10833 if (un->un_bsize == 0 && resid > 0) {
10836 10834 /*
10837 10835 * XXX! Ugly.
10838 10836 * The requested blocksize is > tape blocksize,
10839 10837 * so this is ok, so we just return the
10840 10838 * actual size xferred.
10841 10839 */
10842 10840 pkt->pkt_resid = resid;
10843 10841 rval = COMMAND_DONE;
10844 10842 } else if (un->un_bsize == 0 && resid < 0) {
10845 10843 /*
10846 10844 * The requested blocksize is < tape blocksize,
10847 10845 * so this is not ok, so we err with ENOMEM
10848 10846 */
10849 10847 rval = COMMAND_DONE_ERROR_RECOVERED;
10850 10848 st_bioerror(bp, ENOMEM);
10851 10849 } else {
10852 10850 ST_DO_ERRSTATS(un, st_softerrs);
10853 10851 severity = SCSI_ERR_FATAL;
10854 10852 rval = COMMAND_DONE_ERROR;
10855 10853 st_bioerror(bp, EINVAL);
10856 10854 un->un_running.pmode = invalid;
10857 10855 }
10858 10856 } else {
10859 10857 /*
10860 10858 * we hope and pray for this just being
10861 10859 * something we can ignore (ie. a
10862 10860 * truly recoverable soft error)
10863 10861 */
10864 10862 rval = COMMAND_DONE;
10865 10863 }
10866 10864 if (sensep->es_filmk) {
10867 10865 ST_DEBUG6(ST_DEVINFO, st_label, SCSI_DEBUG,
10868 10866 "filemark\n");
10869 10867 un->un_status = SUN_KEY_EOF;
10870 10868 pos->eof = ST_EOF_PENDING;
10871 10869 st_set_pe_flag(un);
10872 10870 }
10873 10871
10874 10872 /*
10875 10873 * ignore eom when reading, a fmk should terminate reading
10876 10874 */
10877 10875 if ((sensep->es_eom) &&
10878 10876 (CDBP(pkt)->scc_cmd != SCMD_READ)) {
10879 10877 if ((sensep->es_add_code == 0) &&
10880 10878 (sensep->es_qual_code == 4)) {
10881 10879 ST_DEBUG6(ST_DEVINFO, st_label, SCSI_DEBUG,
10882 10880 "bot\n");
10883 10881 un->un_status = SUN_KEY_BOT;
10884 10882 pos->eof = ST_NO_EOF;
10885 10883 pos->lgclblkno = 0;
10886 10884 pos->fileno = 0;
10887 10885 pos->blkno = 0;
10888 10886 if (pos->pmode != legacy)
10889 10887 pos->pmode = legacy;
10890 10888 } else {
10891 10889 ST_DEBUG6(ST_DEVINFO, st_label, SCSI_DEBUG,
10892 10890 "eom\n");
10893 10891 un->un_status = SUN_KEY_EOT;
10894 10892 pos->eof = ST_EOM;
10895 10893 }
10896 10894 st_set_pe_flag(un);
10897 10895 }
10898 10896
10899 10897 break;
10900 10898
10901 10899 case KEY_ILLEGAL_REQUEST:
10902 10900
10903 10901 if (un->un_laststate >= ST_STATE_OPEN) {
10904 10902 ST_DO_ERRSTATS(un, st_softerrs);
10905 10903 severity = SCSI_ERR_FATAL;
10906 10904 } else {
10907 10905 severity = SCSI_ERR_INFO;
10908 10906 }
10909 10907 break;
10910 10908
10911 10909 case KEY_MEDIUM_ERROR:
10912 10910 ST_DO_ERRSTATS(un, st_harderrs);
10913 10911 severity = SCSI_ERR_FATAL;
10914 10912 un->un_pos.pmode = invalid;
10915 10913 un->un_running.pmode = invalid;
10916 10914 check_keys:
10917 10915 /*
10918 10916 * attempt to process the keys in the presence of
10919 10917 * other errors
10920 10918 */
10921 10919 if (sensep->es_ili && rval != COMMAND_DONE_ERROR) {
10922 10920 /*
10923 10921 * Fun with variable length record devices:
10924 10922 * for specifying larger blocks sizes than the
10925 10923 * actual physical record size.
10926 10924 */
10927 10925 if (un->un_bsize == 0 && resid > 0) {
10928 10926 /*
10929 10927 * XXX! Ugly
10930 10928 */
10931 10929 pkt->pkt_resid = resid;
10932 10930 } else if (un->un_bsize == 0 && resid < 0) {
10933 10931 st_bioerror(bp, EINVAL);
10934 10932 } else {
10935 10933 severity = SCSI_ERR_FATAL;
10936 10934 rval = COMMAND_DONE_ERROR;
10937 10935 st_bioerror(bp, EINVAL);
10938 10936 }
10939 10937 }
10940 10938 if (sensep->es_filmk) {
10941 10939 ST_DEBUG6(ST_DEVINFO, st_label, SCSI_DEBUG,
10942 10940 "filemark\n");
10943 10941 un->un_status = SUN_KEY_EOF;
10944 10942 pos->eof = ST_EOF_PENDING;
10945 10943 st_set_pe_flag(un);
10946 10944 }
10947 10945
10948 10946 /*
10949 10947 * ignore eom when reading, a fmk should terminate reading
10950 10948 */
10951 10949 if ((sensep->es_eom) &&
10952 10950 (CDBP(pkt)->scc_cmd != SCMD_READ)) {
10953 10951 ST_DEBUG6(ST_DEVINFO, st_label, SCSI_DEBUG, "eom\n");
10954 10952 un->un_status = SUN_KEY_EOT;
10955 10953 pos->eof = ST_EOM;
10956 10954 st_set_pe_flag(un);
10957 10955 }
10958 10956
10959 10957 break;
10960 10958
10961 10959 case KEY_VOLUME_OVERFLOW:
10962 10960 ST_DO_ERRSTATS(un, st_softerrs);
10963 10961 pos->eof = ST_EOM;
10964 10962 severity = SCSI_ERR_FATAL;
10965 10963 rval = COMMAND_DONE_ERROR;
10966 10964 goto check_keys;
10967 10965
10968 10966 case KEY_HARDWARE_ERROR:
10969 10967 ST_DO_ERRSTATS(un, st_harderrs);
10970 10968 severity = SCSI_ERR_FATAL;
10971 10969 rval = COMMAND_DONE_ERROR;
10972 10970 if (un->un_dp->options & ST_EJECT_ON_CHANGER_FAILURE)
10973 10971 un->un_eject_tape_on_failure = st_check_asc_ascq(un);
10974 10972 break;
10975 10973
10976 10974 case KEY_BLANK_CHECK:
10977 10975 ST_DO_ERRSTATS(un, st_softerrs);
10978 10976 severity = SCSI_ERR_INFO;
10979 10977
10980 10978 /*
10981 10979 * if not a special request and some data was xferred then it
10982 10980 * it is not an error yet
10983 10981 */
10984 10982 if (bp != un->un_sbufp && (bp->b_flags & B_READ)) {
10985 10983 /*
10986 10984 * no error for read with or without data xferred
10987 10985 */
10988 10986 un->un_status = SUN_KEY_EOT;
10989 10987 pos->eof = ST_EOT;
10990 10988 rval = COMMAND_DONE_ERROR;
10991 10989 un->un_running.pmode = invalid;
10992 10990 st_set_pe_flag(un);
10993 10991 goto check_keys;
10994 10992 } else if (bp != un->un_sbufp &&
10995 10993 (pkt->pkt_state & STATE_XFERRED_DATA)) {
10996 10994 rval = COMMAND_DONE;
10997 10995 } else {
10998 10996 rval = COMMAND_DONE_ERROR_RECOVERED;
10999 10997 }
11000 10998
11001 10999 if (un->un_laststate >= ST_STATE_OPEN) {
11002 11000 ST_DEBUG6(ST_DEVINFO, st_label, SCSI_DEBUG,
11003 11001 "blank check\n");
11004 11002 pos->eof = ST_EOM;
11005 11003 }
11006 11004 if ((CDBP(pkt)->scc_cmd == SCMD_LOCATE) ||
11007 11005 (CDBP(pkt)->scc_cmd == SCMD_LOCATE_G4) ||
11008 11006 (CDBP(pkt)->scc_cmd == SCMD_SPACE) &&
11009 11007 (un->un_dp->options & ST_KNOWS_EOD)) {
11010 11008 /*
11011 11009 * we were doing a fast forward by skipping
11012 11010 * multiple fmk at the time
11013 11011 */
11014 11012 st_bioerror(bp, EIO);
11015 11013 severity = SCSI_ERR_RECOVERED;
11016 11014 rval = COMMAND_DONE;
11017 11015 }
11018 11016 st_set_pe_flag(un);
11019 11017 goto check_keys;
11020 11018
11021 11019 case KEY_WRITE_PROTECT:
11022 11020 if (st_wrongtapetype(un)) {
11023 11021 un->un_status = SUN_KEY_WRONGMEDIA;
11024 11022 ST_DEBUG6(ST_DEVINFO, st_label, CE_WARN,
11025 11023 "wrong tape for writing- use DC6150 tape "
11026 11024 "(or equivalent)\n");
11027 11025 severity = SCSI_ERR_UNKNOWN;
11028 11026 } else {
11029 11027 severity = SCSI_ERR_FATAL;
11030 11028 }
11031 11029 ST_DO_ERRSTATS(un, st_harderrs);
11032 11030 rval = COMMAND_DONE_ERROR;
11033 11031 st_bioerror(bp, EACCES);
11034 11032 break;
11035 11033
11036 11034 case KEY_UNIT_ATTENTION:
11037 11035 ST_DEBUG6(ST_DEVINFO, st_label, CE_WARN,
11038 11036 "KEY_UNIT_ATTENTION : un_state = %d\n", un->un_state);
11039 11037
11040 11038 un->un_unit_attention_flags |= 1;
11041 11039 /*
11042 11040 * If we have detected a Bus Reset and the tape
11043 11041 * drive has been reserved.
11044 11042 */
11045 11043 if (ST_RQSENSE->es_add_code == 0x29) {
11046 11044 rval = DEVICE_RESET;
11047 11045 if ((un->un_rsvd_status &
11048 11046 (ST_RESERVE | ST_APPLICATION_RESERVATIONS)) ==
11049 11047 ST_RESERVE) {
11050 11048 un->un_rsvd_status |= ST_LOST_RESERVE;
11051 11049 ST_DEBUG(ST_DEVINFO, st_label, CE_WARN,
11052 11050 "st_decode_sense: Lost Reservation\n");
11053 11051 }
11054 11052 }
11055 11053
11056 11054 /*
11057 11055 * If this is a recovery command and retrable, retry.
11058 11056 */
11059 11057 if (bp == un->un_recov_buf) {
11060 11058 severity = SCSI_ERR_INFO;
11061 11059 if (attrib->retriable &&
11062 11060 ri->pkt_retry_cnt++ < st_retry_count) {
11063 11061 rval = QUE_COMMAND;
11064 11062 } else {
11065 11063 rval = COMMAND_DONE_ERROR;
11066 11064 }
11067 11065 break; /* Don't set position invalid */
11068 11066 }
11069 11067
11070 11068 /*
11071 11069 * If ST_APPLICATION_RESERVATIONS is set,
11072 11070 * If the asc/ascq indicates that the reservation
11073 11071 * has been cleared just allow the write to continue
11074 11072 * which would force a scsi 2 reserve.
11075 11073 * If preempted that persistent reservation
11076 11074 * the scsi 2 reserve would get a reservation conflict.
11077 11075 */
11078 11076 if ((un->un_rsvd_status &
11079 11077 ST_APPLICATION_RESERVATIONS) != 0) {
11080 11078 /*
11081 11079 * RESERVATIONS PREEMPTED
11082 11080 * With MPxIO this could be a fail over? XXX
11083 11081 */
11084 11082 if (ST_RQSENSE->es_add_code == 0x2a &&
11085 11083 ST_RQSENSE->es_qual_code == 0x03) {
11086 11084 severity = SCSI_ERR_INFO;
11087 11085 rval = COMMAND_DONE_ERROR;
11088 11086 pos->pmode = invalid;
11089 11087 break;
11090 11088 /*
11091 11089 * RESERVATIONS RELEASED
11092 11090 */
11093 11091 } else if (ST_RQSENSE->es_add_code == 0x2a &&
11094 11092 ST_RQSENSE->es_qual_code == 0x04) {
11095 11093 severity = SCSI_ERR_INFO;
11096 11094 rval = COMMAND_DONE;
11097 11095 break;
11098 11096 }
11099 11097 }
11100 11098
11101 11099 if (un->un_state <= ST_STATE_OPENING) {
11102 11100 /*
11103 11101 * Look, the tape isn't open yet, now determine
11104 11102 * if the cause is a BUS RESET, Save the file
11105 11103 * and Block positions for the callers to
11106 11104 * recover from the loss of position.
11107 11105 */
11108 11106 severity = SCSI_ERR_INFO;
11109 11107 if ((pos->pmode != invalid) &&
11110 11108 (rval == DEVICE_RESET) &&
11111 11109 (un->un_restore_pos != 1)) {
11112 11110 un->un_save_fileno = pos->fileno;
11113 11111 un->un_save_blkno = pos->blkno;
11114 11112 un->un_restore_pos = 1;
11115 11113 }
11116 11114
11117 11115 if (attrib->retriable &&
11118 11116 ri->pkt_retry_cnt++ < st_retry_count) {
11119 11117 rval = QUE_COMMAND;
11120 11118 } else if (rval == DEVICE_RESET) {
11121 11119 break;
11122 11120 } else {
11123 11121 rval = COMMAND_DONE_ERROR;
11124 11122 }
11125 11123 /*
11126 11124 * Means it thinks the mode parameters have changed.
11127 11125 * This is the result of a reset clearing settings or
11128 11126 * another initiator changing what we set.
11129 11127 */
11130 11128 }
11131 11129 if (ST_RQSENSE->es_add_code == 0x2a) {
11132 11130 if (ST_RQSENSE->es_qual_code == 0x1) {
11133 11131 /* Error recovery will modeselect and retry. */
11134 11132 rval = DEVICE_TAMPER;
11135 11133 severity = SCSI_ERR_INFO;
11136 11134 break; /* don't set position invalid */
11137 11135 }
11138 11136 if (ST_RQSENSE->es_qual_code == 0x0 ||
11139 11137 ST_RQSENSE->es_qual_code == 0x2 ||
11140 11138 ST_RQSENSE->es_qual_code == 0x3 ||
11141 11139 ST_RQSENSE->es_qual_code == 0x4 ||
11142 11140 ST_RQSENSE->es_qual_code == 0x5 ||
11143 11141 ST_RQSENSE->es_qual_code == 0x6 ||
11144 11142 ST_RQSENSE->es_qual_code == 0x7) {
11145 11143 rval = DEVICE_TAMPER;
11146 11144 severity = SCSI_ERR_INFO;
11147 11145 }
11148 11146 } else if (ST_RQSENSE->es_add_code == 0x28 &&
11149 11147 ((ST_RQSENSE->es_qual_code == 0x0) ||
11150 11148 ST_RQSENSE->es_qual_code == 0x5)) {
11151 11149 /*
11152 11150 * Not Ready to Ready change, Media may have changed.
11153 11151 */
11154 11152 rval = DEVICE_TAMPER;
11155 11153 severity = SCSI_ERR_RETRYABLE;
11156 11154 } else {
11157 11155 if (rval != DEVICE_RESET) {
11158 11156 rval = COMMAND_DONE_ERROR;
11159 11157 } else {
11160 11158 /*
11161 11159 * Returning DEVICE_RESET will call
11162 11160 * error recovery.
11163 11161 */
11164 11162 severity = SCSI_ERR_INFO;
11165 11163 break; /* don't set position invalid */
11166 11164 }
11167 11165 /*
11168 11166 * Check if it is an Unexpected Unit Attention.
11169 11167 * If state is >= ST_STATE_OPEN, we have
11170 11168 * already done the initialization .
11171 11169 * In this case it is Fatal Error
11172 11170 * since no further reading/writing
11173 11171 * can be done with fileno set to < 0.
11174 11172 */
11175 11173 if (un->un_state >= ST_STATE_OPEN) {
11176 11174 ST_DO_ERRSTATS(un, st_harderrs);
11177 11175 severity = SCSI_ERR_FATAL;
11178 11176 } else {
11179 11177 severity = SCSI_ERR_INFO;
11180 11178 }
11181 11179 }
11182 11180
11183 11181 pos->pmode = invalid;
11184 11182
11185 11183 break;
11186 11184
11187 11185 case KEY_NOT_READY:
11188 11186 /*
11189 11187 * If in process of getting ready retry.
11190 11188 */
11191 11189 if (sensep->es_add_code == 0x04) {
11192 11190 switch (sensep->es_qual_code) {
11193 11191 case 0x07:
11194 11192 /*
11195 11193 * We get here when the tape is rewinding.
11196 11194 * QUE_BUSY_COMMAND retries every 10 seconds.
11197 11195 */
11198 11196 if (ri->pkt_retry_cnt++ <
11199 11197 (un->un_dp->rewind_timeout / 10)) {
11200 11198 rval = QUE_BUSY_COMMAND;
11201 11199 severity = SCSI_ERR_INFO;
11202 11200 } else {
11203 11201 /* give up */
11204 11202 rval = COMMAND_DONE_ERROR;
11205 11203 severity = SCSI_ERR_FATAL;
11206 11204 }
11207 11205 break;
11208 11206 case 0x01:
11209 11207 if (ri->pkt_retry_cnt++ < st_retry_count) {
11210 11208 rval = QUE_COMMAND;
11211 11209 severity = SCSI_ERR_INFO;
11212 11210 break;
11213 11211 }
11214 11212 default: /* FALLTHRU */
11215 11213 /* give up */
11216 11214 rval = COMMAND_DONE_ERROR;
11217 11215 severity = SCSI_ERR_FATAL;
11218 11216 }
11219 11217 } else {
11220 11218 /* give up */
11221 11219 rval = COMMAND_DONE_ERROR;
11222 11220 severity = SCSI_ERR_FATAL;
11223 11221 }
11224 11222
11225 11223 /*
11226 11224 * If this was an error and after device opened
11227 11225 * do error stats.
11228 11226 */
11229 11227 if (rval == COMMAND_DONE_ERROR &&
11230 11228 un->un_state > ST_STATE_OPENING) {
11231 11229 ST_DO_ERRSTATS(un, st_harderrs);
11232 11230 }
11233 11231
11234 11232 if (ST_RQSENSE->es_add_code == 0x3a) {
11235 11233 if (st_error_level >= SCSI_ERR_FATAL)
11236 11234 scsi_log(ST_DEVINFO, st_label, CE_NOTE,
11237 11235 "Tape not inserted in drive\n");
11238 11236 un->un_mediastate = MTIO_EJECTED;
11239 11237 cv_broadcast(&un->un_state_cv);
11240 11238 }
11241 11239 if ((un->un_dp->options & ST_EJECT_ON_CHANGER_FAILURE) &&
11242 11240 (rval != QUE_COMMAND))
11243 11241 un->un_eject_tape_on_failure = st_check_asc_ascq(un);
11244 11242 break;
11245 11243
11246 11244 case KEY_ABORTED_COMMAND:
11247 11245 /* XXX Do drives return this when they see a lost light? */
11248 11246 /* Testing would say yes */
11249 11247
11250 11248 if (ri->pkt_retry_cnt++ < st_retry_count) {
11251 11249 rval = ATTEMPT_RETRY;
11252 11250 severity = SCSI_ERR_RETRYABLE;
11253 11251 goto check_keys;
11254 11252 }
11255 11253 /*
11256 11254 * Probably a parity error...
11257 11255 * if we retry here then this may cause data to be
11258 11256 * written twice or data skipped during reading
11259 11257 */
11260 11258 ST_DO_ERRSTATS(un, st_harderrs);
11261 11259 severity = SCSI_ERR_FATAL;
11262 11260 rval = COMMAND_DONE_ERROR;
11263 11261 goto check_keys;
11264 11262
11265 11263 default:
11266 11264 /*
11267 11265 * Undecoded sense key. Try retries and hope
11268 11266 * that will fix the problem. Otherwise, we're
11269 11267 * dead.
11270 11268 */
11271 11269 ST_DEBUG6(ST_DEVINFO, st_label, CE_WARN,
11272 11270 "Unhandled Sense Key '%s'\n",
11273 11271 sense_keys[un->un_status]);
11274 11272 ST_DO_ERRSTATS(un, st_harderrs);
11275 11273 severity = SCSI_ERR_FATAL;
11276 11274 rval = COMMAND_DONE_ERROR;
11277 11275 goto check_keys;
11278 11276 }
11279 11277
11280 11278 if ((!(pkt->pkt_flags & FLAG_SILENT) &&
11281 11279 un->un_state >= ST_STATE_OPEN) && (DEBUGGING ||
11282 11280 (un->un_laststate > ST_STATE_OPENING) &&
11283 11281 (severity >= st_error_level))) {
11284 11282
11285 11283 scsi_errmsg(ST_SCSI_DEVP, pkt, st_label, severity,
11286 11284 pos->lgclblkno, un->un_err_pos.lgclblkno,
11287 11285 scsi_cmds, sensep);
11288 11286 if (sensep->es_filmk) {
11289 11287 scsi_log(ST_DEVINFO, st_label, CE_CONT,
11290 11288 "File Mark Detected\n");
11291 11289 }
11292 11290 if (sensep->es_eom) {
11293 11291 scsi_log(ST_DEVINFO, st_label, CE_CONT,
11294 11292 "End-of-Media Detected\n");
11295 11293 }
11296 11294 if (sensep->es_ili) {
11297 11295 scsi_log(ST_DEVINFO, st_label, CE_CONT,
11298 11296 "Incorrect Length Indicator Set\n");
11299 11297 }
11300 11298 }
11301 11299 get_error = geterror(bp);
11302 11300 if (((rval == COMMAND_DONE_ERROR) ||
11303 11301 (rval == COMMAND_DONE_ERROR_RECOVERED)) &&
11304 11302 ((get_error == EIO) || (get_error == 0))) {
11305 11303 un->un_rqs_state |= (ST_RQS_ERROR | ST_RQS_VALID);
11306 11304 bcopy(ST_RQSENSE, un->un_uscsi_rqs_buf, SENSE_LENGTH);
11307 11305 if (un->un_rqs_state & ST_RQS_READ) {
11308 11306 un->un_rqs_state &= ~(ST_RQS_READ);
11309 11307 } else {
11310 11308 un->un_rqs_state |= ST_RQS_OVR;
11311 11309 }
11312 11310 }
11313 11311
11314 11312 return (rval);
11315 11313 }
11316 11314
11317 11315
11318 11316 static int
11319 11317 st_handle_intr_retry_lcmd(struct scsi_tape *un, struct buf *bp)
11320 11318 {
11321 11319 int status = TRAN_ACCEPT;
11322 11320 pkt_info *pktinfo = BP_PKT(bp)->pkt_private;
11323 11321
11324 11322 mutex_enter(ST_MUTEX);
11325 11323
11326 11324 ST_FUNC(ST_DEVINFO, st_handle_intr_retry_lcmd);
11327 11325
11328 11326 ST_DEBUG3(ST_DEVINFO, st_label, SCSI_DEBUG,
11329 11327 "st_handle_intr_rtr_lcmd(), un = 0x%p\n", (void *)un);
11330 11328
11331 11329 /*
11332 11330 * Check to see if we hit the retry timeout. We check to make sure
11333 11331 * this is the first one on the runq and make sure we have not
11334 11332 * queued up any more, so this one has to be the last on the list
11335 11333 * also. If it is not, we have to fail. If it is not the first, but
11336 11334 * is the last we are in trouble anyway, as we are in the interrupt
11337 11335 * context here.
11338 11336 */
11339 11337 if ((pktinfo->pkt_retry_cnt > st_retry_count) ||
11340 11338 ((un->un_runqf != bp) && (un->un_runql != bp))) {
11341 11339 goto exit;
11342 11340 }
11343 11341
11344 11342 if (un->un_throttle) {
11345 11343 un->un_last_throttle = un->un_throttle;
11346 11344 un->un_throttle = 0;
11347 11345 }
11348 11346
11349 11347 /*
11350 11348 * Here we know : bp is the first and last one on the runq
11351 11349 * it is not necessary to put it back on the head of the
11352 11350 * waitq and then move from waitq to runq. Save this queuing
11353 11351 * and call scsi_transport.
11354 11352 */
11355 11353 ST_CDB(ST_DEVINFO, "Retry lcmd CDB", (char *)BP_PKT(bp)->pkt_cdbp);
11356 11354
11357 11355 status = st_transport(un, BP_PKT(bp));
11358 11356
11359 11357 if (status == TRAN_ACCEPT) {
11360 11358 if (un->un_last_throttle) {
11361 11359 un->un_throttle = un->un_last_throttle;
11362 11360 }
11363 11361 mutex_exit(ST_MUTEX);
11364 11362
11365 11363 ST_DEBUG6(ST_DEVINFO, st_label, CE_WARN,
11366 11364 "restart transport \n");
11367 11365 return (0);
11368 11366 }
11369 11367
11370 11368 ST_DO_KSTATS(bp, kstat_runq_back_to_waitq);
11371 11369 mutex_exit(ST_MUTEX);
11372 11370
11373 11371 if (status == TRAN_BUSY) {
11374 11372 if (st_handle_intr_busy(un, bp, ST_TRAN_BUSY_TIMEOUT) == 0) {
11375 11373 return (0);
11376 11374 }
11377 11375 }
11378 11376 ST_DEBUG6(ST_DEVINFO, st_label, CE_WARN,
11379 11377 "restart transport rejected\n");
11380 11378 mutex_enter(ST_MUTEX);
11381 11379 ST_DO_ERRSTATS(un, st_transerrs);
11382 11380 if (un->un_last_throttle) {
11383 11381 un->un_throttle = un->un_last_throttle;
11384 11382 }
11385 11383 exit:
11386 11384 mutex_exit(ST_MUTEX);
11387 11385 return (-1);
11388 11386 }
11389 11387
11390 11388 static int
11391 11389 st_wrongtapetype(struct scsi_tape *un)
11392 11390 {
11393 11391
11394 11392 ST_FUNC(ST_DEVINFO, st_wrongtapetype);
11395 11393
11396 11394 ASSERT(mutex_owned(ST_MUTEX));
11397 11395
11398 11396 ST_DEBUG3(ST_DEVINFO, st_label, SCSI_DEBUG, "st_wrongtapetype()\n");
11399 11397
11400 11398 /*
11401 11399 * Hack to handle 600A, 600XTD, 6150 && 660 vs. 300XL tapes...
11402 11400 */
11403 11401 if (un->un_dp && (un->un_dp->options & ST_QIC) && un->un_mspl) {
11404 11402 switch (un->un_dp->type) {
11405 11403 case ST_TYPE_WANGTEK:
11406 11404 case ST_TYPE_ARCHIVE:
11407 11405 /*
11408 11406 * If this really worked, we could go off of
11409 11407 * the density codes set in the modesense
11410 11408 * page. For this drive, 0x10 == QIC-120,
11411 11409 * 0xf == QIC-150, and 0x5 should be for
11412 11410 * both QIC-24 and, maybe, QIC-11. However,
11413 11411 * the h/w doesn't do what the manual says
11414 11412 * that it should, so we'll key off of
11415 11413 * getting a WRITE PROTECT error AND wp *not*
11416 11414 * set in the mode sense information.
11417 11415 */
11418 11416 /*
11419 11417 * XXX but we already know that status is
11420 11418 * write protect, so don't check it again.
11421 11419 */
11422 11420
11423 11421 if (un->un_status == KEY_WRITE_PROTECT &&
11424 11422 un->un_mspl->wp == 0) {
11425 11423 return (1);
11426 11424 }
11427 11425 break;
11428 11426 default:
11429 11427 break;
11430 11428 }
11431 11429 }
11432 11430 return (0);
11433 11431 }
11434 11432
11435 11433 static errstate
11436 11434 st_check_error(struct scsi_tape *un, struct scsi_pkt *pkt)
11437 11435 {
11438 11436 errstate action;
11439 11437 recov_info *rcvi = pkt->pkt_private;
11440 11438 buf_t *bp = rcvi->cmd_bp;
11441 11439 struct scsi_arq_status *stat = (struct scsi_arq_status *)pkt->pkt_scbp;
11442 11440
11443 11441 ST_FUNC(ST_DEVINFO, st_check_error);
11444 11442
11445 11443 ASSERT(mutex_owned(ST_MUTEX));
11446 11444
11447 11445 ST_DEBUG3(ST_DEVINFO, st_label, SCSI_DEBUG, "st_check_error()\n");
11448 11446
11449 11447 switch (SCBP_C(pkt)) {
11450 11448 case STATUS_RESERVATION_CONFLICT:
11451 11449 /*
11452 11450 * Command recovery is enabled, not just opening,
11453 11451 * we had the drive reserved and we thing its ours.
11454 11452 * Call recovery to attempt to take it back.
11455 11453 */
11456 11454 if ((rcvi->privatelen == sizeof (recov_info)) &&
11457 11455 (bp != un->un_recov_buf) &&
11458 11456 (un->un_state > ST_STATE_OPEN_PENDING_IO) &&
11459 11457 ((un->un_rsvd_status & (ST_RESERVE |
11460 11458 ST_APPLICATION_RESERVATIONS)) != 0)) {
11461 11459 action = ATTEMPT_RETRY;
11462 11460 un->un_rsvd_status |= ST_LOST_RESERVE;
11463 11461 } else {
11464 11462 action = COMMAND_DONE_EACCES;
11465 11463 un->un_rsvd_status |= ST_RESERVATION_CONFLICT;
11466 11464 }
11467 11465 break;
11468 11466
11469 11467 case STATUS_BUSY:
11470 11468 ST_DEBUG4(ST_DEVINFO, st_label, SCSI_DEBUG, "unit busy\n");
11471 11469 if (rcvi->privatelen == sizeof (recov_info) &&
11472 11470 un->un_multipath && (pkt->pkt_state == (STATE_GOT_BUS |
11473 11471 STATE_GOT_TARGET | STATE_SENT_CMD | STATE_GOT_STATUS))) {
11474 11472 /*
11475 11473 * Status returned by scsi_vhci indicating path
11476 11474 * has failed over.
11477 11475 */
11478 11476 action = PATH_FAILED;
11479 11477 break;
11480 11478 }
11481 11479 /* FALLTHRU */
11482 11480 case STATUS_QFULL:
11483 11481 if (rcvi->privatelen == sizeof (recov_info)) {
11484 11482 /*
11485 11483 * If recovery is inabled use it instead of
11486 11484 * blind reties.
11487 11485 */
11488 11486 action = ATTEMPT_RETRY;
11489 11487 } else if (rcvi->pkt_retry_cnt++ < st_retry_count) {
11490 11488 action = QUE_BUSY_COMMAND;
11491 11489 } else if ((un->un_rsvd_status &
11492 11490 (ST_RESERVE | ST_APPLICATION_RESERVATIONS)) == 0) {
11493 11491 /*
11494 11492 * If this is a command done before reserve is done
11495 11493 * don't reset.
11496 11494 */
11497 11495 action = COMMAND_DONE_ERROR;
11498 11496 } else {
11499 11497 ST_DEBUG2(ST_DEVINFO, st_label, CE_WARN,
11500 11498 "unit busy too long\n");
11501 11499 (void) st_reset(un, RESET_ALL);
11502 11500 action = COMMAND_DONE_ERROR;
11503 11501 }
11504 11502 break;
11505 11503
11506 11504 case STATUS_CHECK:
11507 11505 case STATUS_TERMINATED:
11508 11506 /*
11509 11507 * we should only get here if the auto rqsense failed
11510 11508 * thru a uscsi cmd without autorequest sense
11511 11509 * so we just try again
11512 11510 */
11513 11511 if (un->un_arq_enabled &&
11514 11512 stat->sts_rqpkt_reason == CMD_CMPLT &&
11515 11513 (stat->sts_rqpkt_state & (STATE_GOT_BUS |
11516 11514 STATE_GOT_TARGET | STATE_SENT_CMD | STATE_GOT_STATUS)) ==
11517 11515 (STATE_GOT_BUS | STATE_GOT_TARGET | STATE_SENT_CMD |
11518 11516 STATE_GOT_STATUS)) {
11519 11517
11520 11518 ST_DEBUG2(ST_DEVINFO, st_label, CE_WARN,
11521 11519 "Really got sense data\n");
11522 11520 action = st_decode_sense(un, bp, MAX_SENSE_LENGTH -
11523 11521 pkt->pkt_resid, stat, &un->un_pos);
11524 11522 } else {
11525 11523 ST_DEBUG2(ST_DEVINFO, st_label, CE_WARN,
11526 11524 "Trying to queue sense command\n");
11527 11525 action = QUE_SENSE;
11528 11526 }
11529 11527 break;
11530 11528
11531 11529 case STATUS_TASK_ABORT:
11532 11530 /*
11533 11531 * This is an aborted task. This can be a reset on the other
11534 11532 * port of a multiport drive. Lets try and recover it.
11535 11533 */
11536 11534 action = DEVICE_RESET;
11537 11535 break;
11538 11536
11539 11537 default:
11540 11538 action = COMMAND_DONE;
11541 11539 ST_DEBUG(ST_DEVINFO, st_label, CE_PANIC,
11542 11540 "Unexpected scsi status byte 0x%x\n", SCBP_C(pkt));
11543 11541 }
11544 11542 return (action);
11545 11543 }
11546 11544
11547 11545 static void
11548 11546 st_calc_bnum(struct scsi_tape *un, struct buf *bp, struct scsi_pkt *pkt)
11549 11547 {
11550 11548 int nblks;
11551 11549 int nfiles;
11552 11550 long count;
11553 11551 recov_info *ri = pkt->pkt_private;
11554 11552 cmd_attribute const *attrib;
11555 11553
11556 11554 ST_FUNC(ST_DEVINFO, st_calc_bnum);
11557 11555
11558 11556 ASSERT(mutex_owned(ST_MUTEX));
11559 11557
11560 11558 if (ri->privatelen == sizeof (recov_info)) {
11561 11559 attrib = ri->cmd_attrib;
11562 11560 ASSERT(attrib->recov_pos_type == POS_EXPECTED);
11563 11561 ASSERT(attrib->chg_tape_pos);
11564 11562 } else {
11565 11563 ri = NULL;
11566 11564 attrib = st_lookup_cmd_attribute(pkt->pkt_cdbp[0]);
11567 11565 }
11568 11566
11569 11567 count = bp->b_bcount - bp->b_resid;
11570 11568
11571 11569 /* Command reads or writes data */
11572 11570 if (attrib->transfers_data != TRAN_NONE) {
11573 11571 if (count == 0) {
11574 11572 if (attrib->transfers_data == TRAN_WRTE) {
11575 11573 ASSERT(un->un_pos.eof == ST_EOM);
11576 11574 nblks = 0;
11577 11575 nfiles = 0;
11578 11576 } else {
11579 11577 ASSERT(un->un_pos.eof == ST_EOF_PENDING);
11580 11578 nblks = 0;
11581 11579 nfiles = 1;
11582 11580 }
11583 11581 } else if (un->un_bsize == 0) {
11584 11582 /*
11585 11583 * If variable block mode.
11586 11584 * Fixed bit in CBD should be zero.
11587 11585 */
11588 11586 ASSERT((pkt->pkt_cdbp[1] & 1) == 0);
11589 11587 nblks = 1;
11590 11588 un->un_kbytes_xferred += (count / ONE_K);
11591 11589 nfiles = 0;
11592 11590 } else {
11593 11591 /*
11594 11592 * If fixed block mode.
11595 11593 * Fixed bit in CBD should be one.
11596 11594 */
11597 11595 ASSERT((pkt->pkt_cdbp[1] & 1) == 1);
11598 11596 nblks = (count / un->un_bsize);
11599 11597 un->un_kbytes_xferred += (nblks * un->un_bsize) / ONE_K;
11600 11598 nfiles = 0;
11601 11599 }
11602 11600 /*
11603 11601 * So its possable to read some blocks and hit a filemark.
11604 11602 * Example reading in fixed block mode where more then one
11605 11603 * block at a time is requested. In this case because the
11606 11604 * filemark is hit something less then the requesed number
11607 11605 * of blocks is read.
11608 11606 */
11609 11607 if (un->un_pos.eof == ST_EOF_PENDING && bp->b_resid) {
11610 11608 nfiles = 1;
11611 11609 }
11612 11610 } else {
11613 11611 nblks = 0;
11614 11612 nfiles = count;
11615 11613 }
11616 11614
11617 11615 /*
11618 11616 * If some command failed after this one started and it seems
11619 11617 * to have finshed without error count the position.
11620 11618 */
11621 11619 if (un->un_persistence && un->un_persist_errors) {
11622 11620 ASSERT(un->un_pos.pmode != invalid);
11623 11621 }
11624 11622
11625 11623 if (attrib->chg_tape_direction == DIR_FORW) {
11626 11624 un->un_pos.blkno += nblks;
11627 11625 un->un_pos.lgclblkno += nblks;
11628 11626 un->un_pos.lgclblkno += nfiles;
11629 11627 } else if (attrib->chg_tape_direction == DIR_REVC) {
11630 11628 un->un_pos.blkno -= nblks;
11631 11629 un->un_pos.lgclblkno -= nblks;
11632 11630 un->un_pos.lgclblkno -= nfiles;
11633 11631 } else {
11634 11632 ASSERT(0);
11635 11633 }
11636 11634
11637 11635 /* recovery disabled */
11638 11636 if (ri == NULL) {
11639 11637 un->un_running.pmode = invalid;
11640 11638 return;
11641 11639 }
11642 11640
11643 11641 /*
11644 11642 * If we didn't just read a filemark.
11645 11643 */
11646 11644 if (un->un_pos.eof != ST_EOF_PENDING) {
11647 11645 ASSERT(nblks != 0 && nfiles == 0);
11648 11646 /*
11649 11647 * If Previously calulated expected position does not match
11650 11648 * debug the expected position.
11651 11649 */
11652 11650 if ((ri->pos.pmode != invalid) && nblks &&
11653 11651 ((un->un_pos.blkno != ri->pos.blkno) ||
11654 11652 (un->un_pos.lgclblkno != ri->pos.lgclblkno))) {
11655 11653 #ifdef STDEBUG
11656 11654 st_print_position(ST_DEVINFO, st_label, CE_NOTE,
11657 11655 "Expected", &ri->pos);
11658 11656 st_print_position(ST_DEVINFO, st_label, CE_NOTE,
11659 11657 "But Got", &un->un_pos);
11660 11658 #endif
11661 11659 un->un_running.pmode = invalid;
11662 11660 }
11663 11661 } else {
11664 11662 ASSERT(nfiles != 0);
11665 11663 if (un->un_running.pmode != invalid) {
11666 11664 /*
11667 11665 * blkno and lgclblkno already counted in
11668 11666 * st_add_recovery_info_to_pkt(). Since a block was not
11669 11667 * read and a filemark was.
11670 11668 */
11671 11669 if (attrib->chg_tape_direction == DIR_FORW) {
11672 11670 un->un_running.fileno++;
11673 11671 un->un_running.blkno = 0;
11674 11672 } else if (attrib->chg_tape_direction == DIR_REVC) {
11675 11673 un->un_running.fileno--;
11676 11674 un->un_running.blkno = LASTBLK;
11677 11675 }
11678 11676 }
11679 11677 }
11680 11678 }
11681 11679
11682 11680 static void
11683 11681 st_set_state(struct scsi_tape *un, struct buf *bp)
11684 11682 {
11685 11683 struct scsi_pkt *sp = BP_PKT(bp);
11686 11684 struct uscsi_cmd *ucmd;
11687 11685
11688 11686 ST_FUNC(ST_DEVINFO, st_set_state);
11689 11687
11690 11688 ASSERT(mutex_owned(ST_MUTEX));
11691 11689 ASSERT(bp != un->un_recov_buf);
11692 11690
11693 11691 ST_DEBUG3(ST_DEVINFO, st_label, SCSI_DEBUG,
11694 11692 "st_set_state(): eof=%x fmneeded=%x pkt_resid=0x%lx (%ld)\n",
11695 11693 un->un_pos.eof, un->un_fmneeded, sp->pkt_resid, sp->pkt_resid);
11696 11694
11697 11695 if (bp != un->un_sbufp) {
11698 11696 #ifdef STDEBUG
11699 11697 if (DEBUGGING && sp->pkt_resid) {
11700 11698 ST_DEBUG6(ST_DEVINFO, st_label, SCSI_DEBUG,
11701 11699 "pkt_resid %ld bcount %ld\n",
11702 11700 sp->pkt_resid, bp->b_bcount);
11703 11701 }
11704 11702 #endif
11705 11703 bp->b_resid = sp->pkt_resid;
11706 11704 if (geterror(bp) != EIO) {
11707 11705 st_calc_bnum(un, bp, sp);
11708 11706 }
11709 11707 if (bp->b_flags & B_READ) {
11710 11708 un->un_lastop = ST_OP_READ;
11711 11709 un->un_fmneeded = 0;
11712 11710 } else {
11713 11711 un->un_lastop = ST_OP_WRITE;
11714 11712 if (un->un_dp->options & ST_REEL) {
11715 11713 un->un_fmneeded = 2;
11716 11714 } else {
11717 11715 un->un_fmneeded = 1;
11718 11716 }
11719 11717 }
11720 11718 /*
11721 11719 * all is honky dory at this point, so let's
11722 11720 * readjust the throttle, to increase speed, if we
11723 11721 * have not throttled down.
11724 11722 */
11725 11723 if (un->un_throttle) {
11726 11724 un->un_throttle = un->un_max_throttle;
11727 11725 }
11728 11726 } else {
11729 11727 optype new_lastop = ST_OP_NIL;
11730 11728 uchar_t cmd = (uchar_t)(intptr_t)bp->b_forw;
11731 11729
11732 11730 switch (cmd) {
11733 11731 case SCMD_WRITE:
11734 11732 case SCMD_WRITE_G4:
11735 11733 bp->b_resid = sp->pkt_resid;
11736 11734 new_lastop = ST_OP_WRITE;
11737 11735 if (geterror(bp) == EIO) {
11738 11736 break;
11739 11737 }
11740 11738 st_calc_bnum(un, bp, sp);
11741 11739 if (un->un_dp->options & ST_REEL) {
11742 11740 un->un_fmneeded = 2;
11743 11741 } else {
11744 11742 un->un_fmneeded = 1;
11745 11743 }
11746 11744 break;
11747 11745 case SCMD_READ:
11748 11746 case SCMD_READ_G4:
11749 11747 bp->b_resid = sp->pkt_resid;
11750 11748 new_lastop = ST_OP_READ;
11751 11749 un->un_lastop = ST_OP_READ;
11752 11750 if (geterror(bp) == EIO) {
11753 11751 break;
11754 11752 }
11755 11753 st_calc_bnum(un, bp, sp);
11756 11754 un->un_fmneeded = 0;
11757 11755 break;
11758 11756 case SCMD_WRITE_FILE_MARK_G4:
11759 11757 case SCMD_WRITE_FILE_MARK:
11760 11758 {
11761 11759 int fmdone;
11762 11760
11763 11761 if (un->un_pos.eof != ST_EOM) {
11764 11762 un->un_pos.eof = ST_NO_EOF;
11765 11763 }
11766 11764 fmdone = (bp->b_bcount - bp->b_resid);
11767 11765 if (fmdone > 0) {
11768 11766 un->un_lastop = new_lastop = ST_OP_WEOF;
11769 11767 un->un_pos.lgclblkno += fmdone;
11770 11768 un->un_pos.fileno += fmdone;
11771 11769 un->un_pos.blkno = 0;
11772 11770 } else {
11773 11771 new_lastop = ST_OP_CTL;
11774 11772 ST_DEBUG2(ST_DEVINFO, st_label, SCSI_DEBUG,
11775 11773 "Flushed buffer\n");
11776 11774 }
11777 11775 if (fmdone > un->un_fmneeded) {
11778 11776 un->un_fmneeded = 0;
11779 11777 } else {
11780 11778 un->un_fmneeded -= fmdone;
11781 11779 }
11782 11780 break;
11783 11781 }
11784 11782 case SCMD_REWIND:
11785 11783 un->un_pos.eof = ST_NO_EOF;
11786 11784 un->un_pos.fileno = 0;
11787 11785 un->un_pos.blkno = 0;
11788 11786 un->un_pos.lgclblkno = 0;
11789 11787 if (un->un_pos.pmode != legacy)
11790 11788 un->un_pos.pmode = legacy;
11791 11789 new_lastop = ST_OP_CTL;
11792 11790 un->un_restore_pos = 0;
11793 11791 break;
11794 11792
11795 11793 case SCMD_SPACE:
11796 11794 case SCMD_SPACE_G4:
11797 11795 {
11798 11796 int64_t count;
11799 11797 int64_t resid;
11800 11798 int64_t done;
11801 11799 cmd_attribute const *attrib;
11802 11800 recov_info *ri = sp->pkt_private;
11803 11801
11804 11802 if (ri->privatelen == sizeof (recov_info)) {
11805 11803 attrib = ri->cmd_attrib;
11806 11804 } else {
11807 11805 attrib =
11808 11806 st_lookup_cmd_attribute(sp->pkt_cdbp[0]);
11809 11807 }
11810 11808
11811 11809 resid = (int64_t)SPACE_CNT(bp->b_resid);
11812 11810 count = (int64_t)attrib->get_cnt(sp->pkt_cdbp);
11813 11811
11814 11812 if (count >= 0) {
11815 11813 done = (count - resid);
11816 11814 } else {
11817 11815 done = ((-count) - resid);
11818 11816 }
11819 11817 if (done > 0) {
11820 11818 un->un_lastop = new_lastop = ST_OP_CTL;
11821 11819 } else {
11822 11820 new_lastop = ST_OP_CTL;
11823 11821 }
11824 11822
11825 11823 ST_SPAC(ST_DEVINFO, st_label, CE_WARN,
11826 11824 "space cmd: cdb[1] = %s\n"
11827 11825 "space data: = 0x%lx\n"
11828 11826 "space count: = %"PRId64"\n"
11829 11827 "space resid: = %"PRId64"\n"
11830 11828 "spaces done: = %"PRId64"\n"
11831 11829 "fileno before = %d\n"
11832 11830 "blkno before = %d\n",
11833 11831 space_strs[sp->pkt_cdbp[1] & 7],
11834 11832 bp->b_bcount,
11835 11833 count, resid, done,
11836 11834 un->un_pos.fileno, un->un_pos.blkno);
11837 11835
11838 11836 switch (sp->pkt_cdbp[1]) {
11839 11837 case SPACE_TYPE(SP_FLM):
11840 11838 /* Space file forward */
11841 11839 if (count >= 0) {
11842 11840 if (un->un_pos.eof <= ST_EOF) {
11843 11841 un->un_pos.eof = ST_NO_EOF;
11844 11842 }
11845 11843 un->un_pos.fileno += done;
11846 11844 un->un_pos.blkno = 0;
11847 11845 break;
11848 11846 }
11849 11847 /* Space file backward */
11850 11848 if (done > un->un_pos.fileno) {
11851 11849 un->un_pos.fileno = 0;
11852 11850 un->un_pos.blkno = 0;
11853 11851 } else {
11854 11852 un->un_pos.fileno -= done;
11855 11853 un->un_pos.blkno = LASTBLK;
11856 11854 un->un_running.pmode = invalid;
11857 11855 }
11858 11856 break;
11859 11857 case SPACE_TYPE(SP_BLK):
11860 11858 /* Space block forward */
11861 11859 if (count >= 0) {
11862 11860 un->un_pos.blkno += done;
11863 11861 break;
11864 11862 }
11865 11863 /* Space block backward */
11866 11864 if (un->un_pos.eof >= ST_EOF_PENDING) {
11867 11865 /*
11868 11866 * we stepped back into
11869 11867 * a previous file; we are not
11870 11868 * making an effort to pretend that
11871 11869 * we are still in the current file
11872 11870 * ie. logical == physical position
11873 11871 * and leave it to st_ioctl to correct
11874 11872 */
11875 11873 if (done > un->un_pos.blkno) {
11876 11874 un->un_pos.blkno = 0;
11877 11875 } else {
11878 11876 un->un_pos.fileno--;
11879 11877 un->un_pos.blkno = LASTBLK;
11880 11878 un->un_running.pmode = invalid;
11881 11879 }
11882 11880 } else {
11883 11881 un->un_pos.blkno -= done;
11884 11882 }
11885 11883 break;
11886 11884 case SPACE_TYPE(SP_SQFLM):
11887 11885 un->un_pos.pmode = logical;
11888 11886 un->un_pos.blkno = 0;
11889 11887 un->un_lastop = new_lastop = ST_OP_CTL;
11890 11888 break;
11891 11889 case SPACE_TYPE(SP_EOD):
11892 11890 un->un_pos.pmode = logical;
11893 11891 un->un_pos.eof = ST_EOM;
11894 11892 un->un_status = KEY_BLANK_CHECK;
11895 11893 break;
11896 11894 default:
11897 11895 un->un_pos.pmode = invalid;
11898 11896 scsi_log(ST_DEVINFO, st_label, SCSI_DEBUG,
11899 11897 "Unsupported space cmd: %s\n",
11900 11898 space_strs[sp->pkt_cdbp[1] & 7]);
11901 11899
11902 11900 un->un_lastop = new_lastop = ST_OP_CTL;
11903 11901 }
11904 11902
11905 11903 ST_DEBUG6(ST_DEVINFO, st_label, SCSI_DEBUG,
11906 11904 "after_space rs %"PRId64" fil %d blk %d\n",
11907 11905 resid, un->un_pos.fileno, un->un_pos.blkno);
11908 11906
11909 11907 break;
11910 11908 }
11911 11909 case SCMD_LOAD:
11912 11910 if ((bp->b_bcount & (LD_LOAD | LD_EOT)) == LD_LOAD) {
11913 11911 un->un_pos.fileno = 0;
11914 11912 if (un->un_pos.pmode != legacy)
11915 11913 un->un_pos.pmode = legacy;
11916 11914 } else {
11917 11915 un->un_state = ST_STATE_OFFLINE;
11918 11916 un->un_pos.pmode = invalid;
11919 11917
11920 11918 }
11921 11919 /*
11922 11920 * If we are loading or unloading we expect the media id
11923 11921 * to change. Lets make it unknown.
11924 11922 */
11925 11923 if (un->un_media_id != bogusID && un->un_media_id_len) {
11926 11924 kmem_free(un->un_media_id, un->un_media_id_len);
11927 11925 un->un_media_id = NULL;
11928 11926 un->un_media_id_len = 0;
11929 11927 }
11930 11928 un->un_density_known = 0;
11931 11929 un->un_pos.eof = ST_NO_EOF;
11932 11930 un->un_pos.blkno = 0;
11933 11931 un->un_lastop = new_lastop = ST_OP_CTL;
11934 11932 break;
11935 11933 case SCMD_ERASE:
11936 11934 un->un_pos.eof = ST_NO_EOF;
11937 11935 un->un_pos.blkno = 0;
11938 11936 un->un_pos.fileno = 0;
11939 11937 un->un_pos.lgclblkno = 0;
11940 11938 if (un->un_pos.pmode != legacy)
11941 11939 un->un_pos.pmode = legacy;
11942 11940 new_lastop = ST_OP_CTL;
11943 11941 break;
11944 11942 case SCMD_RESERVE:
11945 11943 un->un_rsvd_status |= ST_RESERVE;
11946 11944 un->un_rsvd_status &=
11947 11945 ~(ST_RELEASE | ST_LOST_RESERVE |
11948 11946 ST_RESERVATION_CONFLICT | ST_INITIATED_RESET);
11949 11947 new_lastop = ST_OP_CTL;
11950 11948 break;
11951 11949 case SCMD_RELEASE:
11952 11950 un->un_rsvd_status |= ST_RELEASE;
11953 11951 un->un_rsvd_status &=
11954 11952 ~(ST_RESERVE | ST_LOST_RESERVE |
11955 11953 ST_RESERVATION_CONFLICT | ST_INITIATED_RESET);
11956 11954 new_lastop = ST_OP_CTL;
11957 11955 break;
11958 11956 case SCMD_PERSISTENT_RESERVE_IN:
11959 11957 ST_DEBUG6(ST_DEVINFO, st_label, CE_WARN,
11960 11958 "PGR_IN command\n");
11961 11959 new_lastop = ST_OP_CTL;
11962 11960 break;
11963 11961 case SCMD_PERSISTENT_RESERVE_OUT:
11964 11962 switch (sp->pkt_cdbp[1] & ST_SA_MASK) {
11965 11963 case ST_SA_SCSI3_RESERVE:
11966 11964 case ST_SA_SCSI3_PREEMPT:
11967 11965 case ST_SA_SCSI3_PREEMPTANDABORT:
11968 11966 un->un_rsvd_status |=
11969 11967 (ST_APPLICATION_RESERVATIONS | ST_RESERVE);
11970 11968 un->un_rsvd_status &= ~(ST_RELEASE |
11971 11969 ST_LOST_RESERVE | ST_RESERVATION_CONFLICT |
11972 11970 ST_INITIATED_RESET);
11973 11971 ST_DEBUG6(ST_DEVINFO, st_label, CE_WARN,
11974 11972 "PGR Reserve and set: entering"
11975 11973 " ST_APPLICATION_RESERVATIONS mode");
11976 11974 break;
11977 11975 case ST_SA_SCSI3_REGISTER:
11978 11976 ST_DEBUG6(ST_DEVINFO, st_label, CE_WARN,
11979 11977 "PGR Reserve register key");
11980 11978 un->un_rsvd_status |= ST_INIT_RESERVE;
11981 11979 break;
11982 11980 case ST_SA_SCSI3_CLEAR:
11983 11981 un->un_rsvd_status &= ~ST_INIT_RESERVE;
11984 11982 /* FALLTHROUGH */
11985 11983 case ST_SA_SCSI3_RELEASE:
11986 11984 un->un_rsvd_status &=
11987 11985 ~(ST_APPLICATION_RESERVATIONS | ST_RESERVE |
11988 11986 ST_LOST_RESERVE | ST_RESERVATION_CONFLICT |
11989 11987 ST_INITIATED_RESET);
11990 11988 un->un_rsvd_status |= ST_RELEASE;
11991 11989 ST_DEBUG6(ST_DEVINFO, st_label, CE_WARN,
11992 11990 "PGR Release and reset: exiting"
11993 11991 " ST_APPLICATION_RESERVATIONS mode");
11994 11992 break;
11995 11993 }
11996 11994 new_lastop = ST_OP_CTL;
11997 11995 break;
11998 11996 case SCMD_TEST_UNIT_READY:
11999 11997 case SCMD_READ_BLKLIM:
12000 11998 case SCMD_REQUEST_SENSE:
12001 11999 case SCMD_INQUIRY:
12002 12000 case SCMD_RECOVER_BUF:
12003 12001 case SCMD_MODE_SELECT:
12004 12002 case SCMD_MODE_SENSE:
12005 12003 case SCMD_DOORLOCK:
12006 12004 case SCMD_READ_BUFFER:
12007 12005 case SCMD_REPORT_DENSITIES:
12008 12006 case SCMD_LOG_SELECT_G1:
12009 12007 case SCMD_LOG_SENSE_G1:
12010 12008 case SCMD_REPORT_LUNS:
12011 12009 case SCMD_READ_ATTRIBUTE:
12012 12010 case SCMD_WRITE_ATTRIBUTE:
12013 12011 case SCMD_SVC_ACTION_IN_G5:
12014 12012 case SCMD_SECURITY_PROTO_IN:
12015 12013 case SCMD_SECURITY_PROTO_OUT:
12016 12014 new_lastop = ST_OP_CTL;
12017 12015 break;
12018 12016 case SCMD_READ_POSITION:
12019 12017 new_lastop = ST_OP_CTL;
12020 12018 /*
12021 12019 * Only if the buf used was un_sbufp.
12022 12020 * Among other things the prevents read positions used
12023 12021 * as part of error recovery from messing up our
12024 12022 * current position as they will use un_recov_buf.
12025 12023 */
12026 12024 if (USCSI_CMD(bp)) {
12027 12025 (void) st_get_read_pos(un, bp);
12028 12026 }
12029 12027 break;
12030 12028 case SCMD_LOCATE:
12031 12029 case SCMD_LOCATE_G4:
12032 12030 /* Locate makes position mode no longer legacy */
12033 12031 un->un_lastop = new_lastop = ST_OP_CTL;
12034 12032 break;
12035 12033 case SCMD_MAINTENANCE_IN:
12036 12034 switch (sp->pkt_cdbp[1]) {
12037 12035 case SSVC_ACTION_GET_SUPPORTED_OPERATIONS:
12038 12036 case SSVC_ACTION_SET_TARGET_PORT_GROUPS:
12039 12037 new_lastop = ST_OP_CTL;
12040 12038 break;
12041 12039 }
12042 12040 if (new_lastop != ST_OP_NIL) {
12043 12041 break;
12044 12042 }
12045 12043 default:
12046 12044 /*
12047 12045 * Unknown command, If was USCSI and USCSI_SILENT
12048 12046 * flag was not set, set position to unknown.
12049 12047 */
12050 12048 if ((((ucmd = BP_UCMD(bp)) != NULL) &&
12051 12049 (ucmd->uscsi_flags & USCSI_SILENT) == 0)) {
12052 12050 ST_DEBUG2(ST_DEVINFO, st_label, CE_WARN,
12053 12051 "unknown cmd 0x%X caused loss of state\n",
12054 12052 cmd);
12055 12053 } else {
12056 12054 /*
12057 12055 * keep the old agreement to allow unknown
12058 12056 * commands with the USCSI_SILENT set.
12059 12057 * This prevents ASSERT below.
12060 12058 */
12061 12059 new_lastop = ST_OP_CTL;
12062 12060 break;
12063 12061 }
12064 12062 /* FALLTHROUGH */
12065 12063 case SCMD_WRITE_BUFFER: /* Writes new firmware to device */
12066 12064 un->un_pos.pmode = invalid;
12067 12065 un->un_lastop = new_lastop = ST_OP_CTL;
12068 12066 break;
12069 12067 }
12070 12068
12071 12069 /* new_lastop should have been changed */
12072 12070 ASSERT(new_lastop != ST_OP_NIL);
12073 12071
12074 12072 /* If un_lastop should copy new_lastop */
12075 12073 if (((un->un_lastop == ST_OP_WRITE) ||
12076 12074 (un->un_lastop == ST_OP_WEOF)) &&
12077 12075 new_lastop != ST_OP_CTL) {
12078 12076 un->un_lastop = new_lastop;
12079 12077 }
12080 12078 }
12081 12079
12082 12080 /*
12083 12081 * In the st driver we have a logical and physical file position.
12084 12082 * Under BSD behavior, when you get a zero read, the logical position
12085 12083 * is before the filemark but after the last record of the file.
12086 12084 * The physical position is after the filemark. MTIOCGET should always
12087 12085 * return the logical file position.
12088 12086 *
12089 12087 * The next read gives a silent skip to the next file.
12090 12088 * Under SVR4, the logical file position remains before the filemark
12091 12089 * until the file is closed or a space operation is performed.
12092 12090 * Hence set err_resid and err_file before changing fileno if case
12093 12091 * BSD Behaviour.
12094 12092 */
12095 12093 un->un_err_resid = bp->b_resid;
12096 12094 COPY_POS(&un->un_err_pos, &un->un_pos);
12097 12095
12098 12096
12099 12097 /*
12100 12098 * If we've seen a filemark via the last read operation
12101 12099 * advance the file counter, but mark things such that
12102 12100 * the next read operation gets a zero count. We have
12103 12101 * to put this here to handle the case of sitting right
12104 12102 * at the end of a tape file having seen the file mark,
12105 12103 * but the tape is closed and then re-opened without
12106 12104 * any further i/o. That is, the position information
12107 12105 * must be updated before a close.
12108 12106 */
12109 12107
12110 12108 if (un->un_lastop == ST_OP_READ && un->un_pos.eof == ST_EOF_PENDING) {
12111 12109 /*
12112 12110 * If we're a 1/2" tape, and we get a filemark
12113 12111 * right on block 0, *AND* we were not in the
12114 12112 * first file on the tape, and we've hit logical EOM.
12115 12113 * We'll mark the state so that later we do the
12116 12114 * right thing (in st_close(), st_strategy() or
12117 12115 * st_ioctl()).
12118 12116 *
12119 12117 */
12120 12118 if ((un->un_dp->options & ST_REEL) &&
12121 12119 !(un->un_dp->options & ST_READ_IGNORE_EOFS) &&
12122 12120 un->un_pos.blkno == 0 && un->un_pos.fileno > 0) {
12123 12121 un->un_pos.eof = ST_EOT_PENDING;
12124 12122 ST_DEBUG6(ST_DEVINFO, st_label, SCSI_DEBUG,
12125 12123 "eot pending\n");
12126 12124 un->un_pos.fileno++;
12127 12125 un->un_pos.blkno = 0;
12128 12126 } else if (BP_UCMD(bp)) {
12129 12127 /*
12130 12128 * Uscsi reads have no concept of Berkley ver System IV.
12131 12129 * Counts here must match raw device.
12132 12130 * A non-full resid implies fix block mode where an
12133 12131 * attempt to read X blocks resulted in less then X.
12134 12132 */
12135 12133 if (bp->b_resid != bp->b_bcount) {
12136 12134 un->un_pos.eof = ST_EOF;
12137 12135 } else {
12138 12136 /* Read over a file mark */
12139 12137 un->un_pos.fileno++;
12140 12138 /* logical block is counted up elsewhere */
12141 12139 /* we're before the first block in next file */
12142 12140 un->un_pos.blkno = 0;
12143 12141 /* EOF is no longer pending */
12144 12142 un->un_pos.eof = ST_NO_EOF;
12145 12143 }
12146 12144 } else if (BSD_BEHAVIOR) {
12147 12145 /*
12148 12146 * If the read of the filemark was a side effect
12149 12147 * of reading some blocks (i.e., data was actually
12150 12148 * read), then the EOF mark is pending and the
12151 12149 * bump into the next file awaits the next read
12152 12150 * operation (which will return a zero count), or
12153 12151 * a close or a space operation, else the bump
12154 12152 * into the next file occurs now.
12155 12153 */
12156 12154 ST_DEBUG6(ST_DEVINFO, st_label, SCSI_DEBUG,
12157 12155 "resid=%lx, bcount=%lx\n",
12158 12156 bp->b_resid, bp->b_bcount);
12159 12157
12160 12158 if (bp->b_resid != bp->b_bcount) {
12161 12159 un->un_pos.eof = ST_EOF;
12162 12160 } else {
12163 12161 un->un_silent_skip = 1;
12164 12162 un->un_pos.eof = ST_NO_EOF;
12165 12163 un->un_pos.fileno++;
12166 12164 un->un_pos.lgclblkno++;
12167 12165 un->un_save_blkno = un->un_pos.blkno;
12168 12166 un->un_pos.blkno = 0;
12169 12167 }
12170 12168 ST_DEBUG6(ST_DEVINFO, st_label, SCSI_DEBUG,
12171 12169 "eof of file %d, eof=%d\n",
12172 12170 un->un_pos.fileno, un->un_pos.eof);
12173 12171 } else if (SVR4_BEHAVIOR) {
12174 12172 /*
12175 12173 * If the read of the filemark was a side effect
12176 12174 * of reading some blocks (i.e., data was actually
12177 12175 * read), then the next read should return 0
12178 12176 */
12179 12177 ST_DEBUG6(ST_DEVINFO, st_label, SCSI_DEBUG,
12180 12178 "resid=%lx, bcount=%lx\n",
12181 12179 bp->b_resid, bp->b_bcount);
12182 12180 if (bp->b_resid == bp->b_bcount) {
12183 12181 un->un_pos.eof = ST_EOF;
12184 12182 }
12185 12183 ST_DEBUG6(ST_DEVINFO, st_label, SCSI_DEBUG,
12186 12184 "eof of file=%d, eof=%d\n",
12187 12185 un->un_pos.fileno, un->un_pos.eof);
12188 12186 }
12189 12187 }
12190 12188 }
12191 12189
12192 12190 /*
12193 12191 * set the correct un_errno, to take corner cases into consideration
12194 12192 */
12195 12193 static void
12196 12194 st_set_pe_errno(struct scsi_tape *un)
12197 12195 {
12198 12196 ST_FUNC(ST_DEVINFO, st_set_pe_errno);
12199 12197
12200 12198 ASSERT(mutex_owned(ST_MUTEX));
12201 12199
12202 12200 /* if errno is already set, don't reset it */
12203 12201 if (un->un_errno)
12204 12202 return;
12205 12203
12206 12204 /* here un_errno == 0 */
12207 12205 /*
12208 12206 * if the last transfer before flushing all the
12209 12207 * waiting I/O's, was 0 (resid = count), then we
12210 12208 * want to give the user an error on all the rest,
12211 12209 * so here. If there was a transfer, we set the
12212 12210 * resid and counts to 0, and let it drop through,
12213 12211 * giving a zero return. the next I/O will then
12214 12212 * give an error.
12215 12213 */
12216 12214 if (un->un_last_resid == un->un_last_count) {
12217 12215 switch (un->un_pos.eof) {
12218 12216 case ST_EOM:
12219 12217 un->un_errno = ENOMEM;
12220 12218 break;
12221 12219 case ST_EOT:
12222 12220 case ST_EOF:
12223 12221 un->un_errno = EIO;
12224 12222 break;
12225 12223 }
12226 12224 } else {
12227 12225 /*
12228 12226 * we know they did not have a zero, so make
12229 12227 * sure they get one
12230 12228 */
12231 12229 un->un_last_resid = un->un_last_count = 0;
12232 12230 }
12233 12231 }
12234 12232
12235 12233
12236 12234 /*
12237 12235 * send in a marker pkt to terminate flushing of commands by BBA (via
12238 12236 * flush-on-errors) property. The HBA will always return TRAN_ACCEPT
12239 12237 */
12240 12238 static void
12241 12239 st_hba_unflush(struct scsi_tape *un)
12242 12240 {
12243 12241 ST_FUNC(ST_DEVINFO, st_hba_unflush);
12244 12242
12245 12243 ASSERT(mutex_owned(ST_MUTEX));
12246 12244
12247 12245 if (!un->un_flush_on_errors)
12248 12246 return;
12249 12247
12250 12248 #ifdef FLUSH_ON_ERRORS
12251 12249
12252 12250 if (!un->un_mkr_pkt) {
12253 12251 un->un_mkr_pkt = scsi_init_pkt(ROUTE, NULL, (struct buf *)NULL,
12254 12252 NULL, 0, 0, 0, SLEEP_FUNC, NULL);
12255 12253
12256 12254 /* we slept, so it must be there */
12257 12255 pkt->pkt_flags |= FLAG_FLUSH_MARKER;
12258 12256 }
12259 12257
12260 12258 st_transport(un, un->un_mkr_pkt);
12261 12259 #endif
12262 12260 }
12263 12261
12264 12262 static char *
12265 12263 st_print_scsi_cmd(char cmd)
12266 12264 {
12267 12265 char tmp[64];
12268 12266 char *cpnt;
12269 12267
12270 12268 cpnt = scsi_cmd_name(cmd, scsi_cmds, tmp);
12271 12269 /* tmp goes out of scope on return and caller sees garbage */
12272 12270 if (cpnt == tmp) {
12273 12271 cpnt = "Unknown Command";
12274 12272 }
12275 12273 return (cpnt);
12276 12274 }
12277 12275
12278 12276 static void
12279 12277 st_print_cdb(dev_info_t *dip, char *label, uint_t level,
12280 12278 char *title, char *cdb)
12281 12279 {
12282 12280 int len = scsi_cdb_size[CDB_GROUPID(cdb[0])];
12283 12281 char buf[256];
12284 12282 struct scsi_tape *un;
12285 12283 int instance = ddi_get_instance(dip);
12286 12284
12287 12285 un = ddi_get_soft_state(st_state, instance);
12288 12286
12289 12287 ST_FUNC(dip, st_print_cdb);
12290 12288
12291 12289 /* force one line output so repeated commands are printed once */
12292 12290 if ((st_debug & 0x180) == 0x100) {
12293 12291 scsi_log(dip, label, level, "node %s cmd %s\n",
12294 12292 st_dev_name(un->un_dev), st_print_scsi_cmd(*cdb));
12295 12293 return;
12296 12294 }
12297 12295
12298 12296 /* force one line output so repeated CDB's are printed once */
12299 12297 if ((st_debug & 0x180) == 0x80) {
12300 12298 st_clean_print(dip, label, level, NULL, cdb, len);
12301 12299 } else {
12302 12300 (void) sprintf(buf, "%s for cmd(%s)", title,
12303 12301 st_print_scsi_cmd(*cdb));
12304 12302 st_clean_print(dip, label, level, buf, cdb, len);
12305 12303 }
12306 12304 }
12307 12305
12308 12306 static void
12309 12307 st_clean_print(dev_info_t *dev, char *label, uint_t level,
12310 12308 char *title, char *data, int len)
12311 12309 {
12312 12310 int i;
12313 12311 int c;
12314 12312 char *format;
12315 12313 char buf[256];
12316 12314 uchar_t byte;
12317 12315
12318 12316 ST_FUNC(dev, st_clean_print);
12319 12317
12320 12318
12321 12319 if (title) {
12322 12320 (void) sprintf(buf, "%s:\n", title);
12323 12321 scsi_log(dev, label, level, "%s", buf);
12324 12322 level = CE_CONT;
12325 12323 }
12326 12324
12327 12325 for (i = 0; i < len; ) {
12328 12326 buf[0] = 0;
12329 12327 for (c = 0; c < 8 && i < len; c++, i++) {
12330 12328 byte = (uchar_t)data[i];
12331 12329 if (byte < 0x10)
12332 12330 format = "0x0%x ";
12333 12331 else
12334 12332 format = "0x%x ";
12335 12333 (void) sprintf(&buf[(int)strlen(buf)], format, byte);
12336 12334 }
12337 12335 (void) sprintf(&buf[(int)strlen(buf)], "\n");
12338 12336
12339 12337 scsi_log(dev, label, level, "%s\n", buf);
12340 12338 level = CE_CONT;
12341 12339 }
12342 12340 }
12343 12341
12344 12342 /*
12345 12343 * Conditionally enabled debugging
12346 12344 */
12347 12345 #ifdef STDEBUG
12348 12346 static void
12349 12347 st_debug_cmds(struct scsi_tape *un, int com, int count, int wait)
12350 12348 {
12351 12349 char tmpbuf[64];
12352 12350
12353 12351 ST_FUNC(ST_DEVINFO, st_debug_cmds);
12354 12352
12355 12353 ST_DEBUG3(ST_DEVINFO, st_label, SCSI_DEBUG,
12356 12354 "cmd=%s count=0x%x (%d) %ssync\n",
12357 12355 scsi_cmd_name(com, scsi_cmds, tmpbuf),
12358 12356 count, count,
12359 12357 wait == ASYNC_CMD ? "a" : "");
12360 12358 }
12361 12359 #endif /* STDEBUG */
12362 12360
12363 12361 /*
12364 12362 * Returns pointer to name of minor node name of device 'dev'.
12365 12363 */
12366 12364 static char *
12367 12365 st_dev_name(dev_t dev)
12368 12366 {
12369 12367 struct scsi_tape *un;
12370 12368 const char density[] = { 'l', 'm', 'h', 'c' };
12371 12369 static char name[32];
12372 12370 minor_t minor;
12373 12371 int instance;
12374 12372 int nprt = 0;
12375 12373
12376 12374 minor = getminor(dev);
12377 12375 instance = ((minor & 0xff80) >> 5) | (minor & 3);
12378 12376 un = ddi_get_soft_state(st_state, instance);
12379 12377 if (un) {
12380 12378 ST_FUNC(ST_DEVINFO, st_dev_name);
12381 12379 }
12382 12380
12383 12381 name[nprt] = density[(minor & MT_DENSITY_MASK) >> 3];
12384 12382
12385 12383 if (minor & MT_BSD) {
12386 12384 name[++nprt] = 'b';
12387 12385 }
12388 12386
12389 12387 if (minor & MT_NOREWIND) {
12390 12388 name[++nprt] = 'n';
12391 12389 }
12392 12390
12393 12391 /* NULL terminator */
12394 12392 name[++nprt] = 0;
12395 12393
12396 12394 return (name);
12397 12395 }
12398 12396
12399 12397 /*
12400 12398 * Soft error reporting, so far unique to each drive
12401 12399 *
12402 12400 * Currently supported: exabyte and DAT soft error reporting
12403 12401 */
12404 12402 static int
12405 12403 st_report_exabyte_soft_errors(dev_t dev, int flag)
12406 12404 {
12407 12405 uchar_t *sensep;
12408 12406 int amt;
12409 12407 int rval = 0;
12410 12408 char cdb[CDB_GROUP0], *c = cdb;
12411 12409 struct uscsi_cmd *com;
12412 12410
12413 12411 GET_SOFT_STATE(dev);
12414 12412
12415 12413 ST_FUNC(ST_DEVINFO, st_report_exabyte_soft_errors);
12416 12414
12417 12415 ST_DEBUG3(ST_DEVINFO, st_label, SCSI_DEBUG,
12418 12416 "st_report_exabyte_soft_errors(dev = 0x%lx, flag = %d)\n",
12419 12417 dev, flag);
12420 12418
12421 12419 ASSERT(mutex_owned(ST_MUTEX));
12422 12420
12423 12421 com = kmem_zalloc(sizeof (*com), KM_SLEEP);
12424 12422 sensep = kmem_zalloc(TAPE_SENSE_LENGTH, KM_SLEEP);
12425 12423
12426 12424 *c++ = SCMD_REQUEST_SENSE;
12427 12425 *c++ = 0;
12428 12426 *c++ = 0;
12429 12427 *c++ = 0;
12430 12428 *c++ = TAPE_SENSE_LENGTH;
12431 12429 /*
12432 12430 * set CLRCNT (byte 5, bit 7 which clears the error counts)
12433 12431 */
12434 12432 *c = (char)0x80;
12435 12433
12436 12434 com->uscsi_cdb = cdb;
12437 12435 com->uscsi_cdblen = CDB_GROUP0;
12438 12436 com->uscsi_bufaddr = (caddr_t)sensep;
12439 12437 com->uscsi_buflen = TAPE_SENSE_LENGTH;
12440 12438 com->uscsi_flags = USCSI_DIAGNOSE | USCSI_SILENT | USCSI_READ;
12441 12439 com->uscsi_timeout = un->un_dp->non_motion_timeout;
12442 12440
12443 12441 rval = st_uscsi_cmd(un, com, FKIOCTL);
12444 12442 if (rval || com->uscsi_status) {
12445 12443 goto done;
12446 12444 }
12447 12445
12448 12446 /*
12449 12447 * was there enough data?
12450 12448 */
12451 12449 amt = (int)TAPE_SENSE_LENGTH - com->uscsi_resid;
12452 12450
12453 12451 if ((amt >= 19) && un->un_kbytes_xferred) {
12454 12452 uint_t count, error_rate;
12455 12453 uint_t rate;
12456 12454
12457 12455 if (sensep[21] & CLN) {
12458 12456 scsi_log(ST_DEVINFO, st_label, CE_WARN,
12459 12457 "Periodic head cleaning required");
12460 12458 }
12461 12459 if (un->un_kbytes_xferred < (EXABYTE_MIN_TRANSFER/ONE_K)) {
12462 12460 goto done;
12463 12461 }
12464 12462 /*
12465 12463 * check if soft error reporting needs to be done.
12466 12464 */
12467 12465 count = sensep[16] << 16 | sensep[17] << 8 | sensep[18];
12468 12466 count &= 0xffffff;
12469 12467 error_rate = (count * 100)/un->un_kbytes_xferred;
12470 12468
12471 12469 #ifdef STDEBUG
12472 12470 if (st_soft_error_report_debug) {
12473 12471 scsi_log(ST_DEVINFO, st_label, CE_NOTE,
12474 12472 "Exabyte Soft Error Report:\n");
12475 12473 scsi_log(ST_DEVINFO, st_label, CE_CONT,
12476 12474 "read/write error counter: %d\n", count);
12477 12475 scsi_log(ST_DEVINFO, st_label, CE_CONT,
12478 12476 "number of bytes transferred: %dK\n",
12479 12477 un->un_kbytes_xferred);
12480 12478 scsi_log(ST_DEVINFO, st_label, CE_CONT,
12481 12479 "error_rate: %d%%\n", error_rate);
12482 12480
12483 12481 if (amt >= 22) {
12484 12482 scsi_log(ST_DEVINFO, st_label, CE_CONT,
12485 12483 "unit sense: 0x%b 0x%b 0x%b\n",
12486 12484 sensep[19], SENSE_19_BITS,
12487 12485 sensep[20], SENSE_20_BITS,
12488 12486 sensep[21], SENSE_21_BITS);
12489 12487 }
12490 12488 if (amt >= 27) {
12491 12489 scsi_log(ST_DEVINFO, st_label, CE_CONT,
12492 12490 "tracking retry counter: %d\n",
12493 12491 sensep[26]);
12494 12492 scsi_log(ST_DEVINFO, st_label, CE_CONT,
12495 12493 "read/write retry counter: %d\n",
12496 12494 sensep[27]);
12497 12495 }
12498 12496 }
12499 12497 #endif
12500 12498
12501 12499 if (flag & FWRITE) {
12502 12500 rate = EXABYTE_WRITE_ERROR_THRESHOLD;
12503 12501 } else {
12504 12502 rate = EXABYTE_READ_ERROR_THRESHOLD;
12505 12503 }
12506 12504 if (error_rate >= rate) {
12507 12505 scsi_log(ST_DEVINFO, st_label, CE_WARN,
12508 12506 "Soft error rate (%d%%) during %s was too high",
12509 12507 error_rate,
12510 12508 ((flag & FWRITE) ? wrg_str : rdg_str));
12511 12509 scsi_log(ST_DEVINFO, st_label, CE_CONT,
12512 12510 "Please, replace tape cartridge\n");
12513 12511 }
12514 12512 }
12515 12513
12516 12514 done:
12517 12515 kmem_free(com, sizeof (*com));
12518 12516 kmem_free(sensep, TAPE_SENSE_LENGTH);
12519 12517
12520 12518 if (rval != 0) {
12521 12519 scsi_log(ST_DEVINFO, st_label, CE_WARN,
12522 12520 "exabyte soft error reporting failed\n");
12523 12521 }
12524 12522 return (rval);
12525 12523 }
12526 12524
12527 12525 /*
12528 12526 * this is very specific to Archive 4mm dat
12529 12527 */
12530 12528 #define ONE_GIG (ONE_K * ONE_K * ONE_K)
12531 12529
12532 12530 static int
12533 12531 st_report_dat_soft_errors(dev_t dev, int flag)
12534 12532 {
12535 12533 uchar_t *sensep;
12536 12534 int amt, i;
12537 12535 int rval = 0;
12538 12536 char cdb[CDB_GROUP1], *c = cdb;
12539 12537 struct uscsi_cmd *com;
12540 12538 struct scsi_arq_status status;
12541 12539
12542 12540 GET_SOFT_STATE(dev);
12543 12541
12544 12542 ST_FUNC(ST_DEVINFO, st_report_dat_soft_errors);
12545 12543
12546 12544 ST_DEBUG3(ST_DEVINFO, st_label, SCSI_DEBUG,
12547 12545 "st_report_dat_soft_errors(dev = 0x%lx, flag = %d)\n", dev, flag);
12548 12546
12549 12547 ASSERT(mutex_owned(ST_MUTEX));
12550 12548
12551 12549 com = kmem_zalloc(sizeof (*com), KM_SLEEP);
12552 12550 sensep = kmem_zalloc(LOG_SENSE_LENGTH, KM_SLEEP);
12553 12551
12554 12552 *c++ = SCMD_LOG_SENSE_G1;
12555 12553 *c++ = 0;
12556 12554 *c++ = (flag & FWRITE) ? 0x42 : 0x43;
12557 12555 *c++ = 0;
12558 12556 *c++ = 0;
12559 12557 *c++ = 0;
12560 12558 *c++ = 2;
12561 12559 *c++ = 0;
12562 12560 *c++ = (char)LOG_SENSE_LENGTH;
12563 12561 *c = 0;
12564 12562 com->uscsi_cdb = cdb;
12565 12563 com->uscsi_cdblen = CDB_GROUP1;
12566 12564 com->uscsi_bufaddr = (caddr_t)sensep;
12567 12565 com->uscsi_buflen = LOG_SENSE_LENGTH;
12568 12566 com->uscsi_rqlen = sizeof (status);
12569 12567 com->uscsi_rqbuf = (caddr_t)&status;
12570 12568 com->uscsi_flags = USCSI_DIAGNOSE | USCSI_RQENABLE | USCSI_READ;
12571 12569 com->uscsi_timeout = un->un_dp->non_motion_timeout;
12572 12570 rval = st_uscsi_cmd(un, com, FKIOCTL);
12573 12571 if (rval) {
12574 12572 scsi_log(ST_DEVINFO, st_label, CE_WARN,
12575 12573 "DAT soft error reporting failed\n");
12576 12574 }
12577 12575 if (rval || com->uscsi_status) {
12578 12576 goto done;
12579 12577 }
12580 12578
12581 12579 /*
12582 12580 * was there enough data?
12583 12581 */
12584 12582 amt = (int)LOG_SENSE_LENGTH - com->uscsi_resid;
12585 12583
12586 12584 if ((amt >= MIN_LOG_SENSE_LENGTH) && un->un_kbytes_xferred) {
12587 12585 int total, retries, param_code;
12588 12586
12589 12587 total = -1;
12590 12588 retries = -1;
12591 12589 amt = sensep[3] + 4;
12592 12590
12593 12591
12594 12592 #ifdef STDEBUG
12595 12593 if (st_soft_error_report_debug) {
12596 12594 (void) printf("logsense:");
12597 12595 for (i = 0; i < MIN_LOG_SENSE_LENGTH; i++) {
12598 12596 if (i % 16 == 0) {
12599 12597 (void) printf("\t\n");
12600 12598 }
12601 12599 (void) printf(" %x", sensep[i]);
12602 12600 }
12603 12601 (void) printf("\n");
12604 12602 }
12605 12603 #endif
12606 12604
12607 12605 /*
12608 12606 * parse the param_codes
12609 12607 */
12610 12608 if (sensep[0] == 2 || sensep[0] == 3) {
12611 12609 for (i = 4; i < amt; i++) {
12612 12610 param_code = (sensep[i++] << 8);
12613 12611 param_code += sensep[i++];
12614 12612 i++; /* skip control byte */
12615 12613 if (param_code == 5) {
12616 12614 if (sensep[i++] == 4) {
12617 12615 total = (sensep[i++] << 24);
12618 12616 total += (sensep[i++] << 16);
12619 12617 total += (sensep[i++] << 8);
12620 12618 total += sensep[i];
12621 12619 }
12622 12620 } else if (param_code == 0x8007) {
12623 12621 if (sensep[i++] == 2) {
12624 12622 retries = sensep[i++] << 8;
12625 12623 retries += sensep[i];
12626 12624 }
12627 12625 } else {
12628 12626 i += sensep[i];
12629 12627 }
12630 12628 }
12631 12629 }
12632 12630
12633 12631 /*
12634 12632 * if the log sense returned valid numbers then determine
12635 12633 * the read and write error thresholds based on the amount of
12636 12634 * data transferred
12637 12635 */
12638 12636
12639 12637 if (total > 0 && retries > 0) {
12640 12638 short normal_retries = 0;
12641 12639 ST_DEBUG4(ST_DEVINFO, st_label, SCSI_DEBUG,
12642 12640 "total xferred (%s) =%x, retries=%x\n",
12643 12641 ((flag & FWRITE) ? wrg_str : rdg_str),
12644 12642 total, retries);
12645 12643
12646 12644 if (flag & FWRITE) {
12647 12645 if (total <=
12648 12646 WRITE_SOFT_ERROR_WARNING_THRESHOLD) {
12649 12647 normal_retries =
12650 12648 DAT_SMALL_WRITE_ERROR_THRESHOLD;
12651 12649 } else {
12652 12650 normal_retries =
12653 12651 DAT_LARGE_WRITE_ERROR_THRESHOLD;
12654 12652 }
12655 12653 } else {
12656 12654 if (total <=
12657 12655 READ_SOFT_ERROR_WARNING_THRESHOLD) {
12658 12656 normal_retries =
12659 12657 DAT_SMALL_READ_ERROR_THRESHOLD;
12660 12658 } else {
12661 12659 normal_retries =
12662 12660 DAT_LARGE_READ_ERROR_THRESHOLD;
12663 12661 }
12664 12662 }
12665 12663
12666 12664 ST_DEBUG4(ST_DEVINFO, st_label, SCSI_DEBUG,
12667 12665 "normal retries=%d\n", normal_retries);
12668 12666
12669 12667 if (retries >= normal_retries) {
12670 12668 scsi_log(ST_DEVINFO, st_label, CE_WARN,
12671 12669 "Soft error rate (retries = %d) during "
12672 12670 "%s was too high", retries,
12673 12671 ((flag & FWRITE) ? wrg_str : rdg_str));
12674 12672 scsi_log(ST_DEVINFO, st_label, CE_CONT,
12675 12673 "Periodic head cleaning required "
12676 12674 "and/or replace tape cartridge\n");
12677 12675 }
12678 12676
12679 12677 } else if (total == -1 || retries == -1) {
12680 12678 scsi_log(ST_DEVINFO, st_label, CE_WARN,
12681 12679 "log sense parameter code does not make sense\n");
12682 12680 }
12683 12681 }
12684 12682
12685 12683 /*
12686 12684 * reset all values
12687 12685 */
12688 12686 c = cdb;
12689 12687 *c++ = SCMD_LOG_SELECT_G1;
12690 12688 *c++ = 2; /* this resets all values */
12691 12689 *c++ = (char)0xc0;
12692 12690 *c++ = 0;
12693 12691 *c++ = 0;
12694 12692 *c++ = 0;
12695 12693 *c++ = 0;
12696 12694 *c++ = 0;
12697 12695 *c++ = 0;
12698 12696 *c = 0;
12699 12697 com->uscsi_bufaddr = NULL;
12700 12698 com->uscsi_buflen = 0;
12701 12699 com->uscsi_flags = USCSI_DIAGNOSE | USCSI_SILENT;
12702 12700 rval = st_uscsi_cmd(un, com, FKIOCTL);
12703 12701 if (rval) {
12704 12702 scsi_log(ST_DEVINFO, st_label, CE_WARN,
12705 12703 "DAT soft error reset failed\n");
12706 12704 }
12707 12705 done:
12708 12706 kmem_free(com, sizeof (*com));
12709 12707 kmem_free(sensep, LOG_SENSE_LENGTH);
12710 12708 return (rval);
12711 12709 }
12712 12710
12713 12711 static int
12714 12712 st_report_soft_errors(dev_t dev, int flag)
12715 12713 {
12716 12714 GET_SOFT_STATE(dev);
12717 12715
12718 12716 ST_FUNC(ST_DEVINFO, st_report_soft_errors);
12719 12717
12720 12718 ST_DEBUG3(ST_DEVINFO, st_label, SCSI_DEBUG,
12721 12719 "st_report_soft_errors(dev = 0x%lx, flag = %d)\n", dev, flag);
12722 12720
12723 12721 ASSERT(mutex_owned(ST_MUTEX));
12724 12722
12725 12723 switch (un->un_dp->type) {
12726 12724 case ST_TYPE_EXB8500:
12727 12725 case ST_TYPE_EXABYTE:
12728 12726 return (st_report_exabyte_soft_errors(dev, flag));
12729 12727 /*NOTREACHED*/
12730 12728 case ST_TYPE_PYTHON:
12731 12729 return (st_report_dat_soft_errors(dev, flag));
12732 12730 /*NOTREACHED*/
12733 12731 default:
12734 12732 un->un_dp->options &= ~ST_SOFT_ERROR_REPORTING;
12735 12733 return (-1);
12736 12734 }
12737 12735 }
12738 12736
12739 12737 /*
12740 12738 * persistent error routines
12741 12739 */
12742 12740
12743 12741 /*
12744 12742 * enable persistent errors, and set the throttle appropriately, checking
12745 12743 * for flush-on-errors capability
12746 12744 */
12747 12745 static void
12748 12746 st_turn_pe_on(struct scsi_tape *un)
12749 12747 {
12750 12748 ST_FUNC(ST_DEVINFO, st_turn_pe_on);
12751 12749
12752 12750 ST_DEBUG3(ST_DEVINFO, st_label, SCSI_DEBUG, "st_pe_on\n");
12753 12751 ASSERT(mutex_owned(ST_MUTEX));
12754 12752
12755 12753 un->un_persistence = 1;
12756 12754
12757 12755 /*
12758 12756 * only use flush-on-errors if auto-request-sense and untagged-qing are
12759 12757 * enabled. This will simplify the error handling for request senses
12760 12758 */
12761 12759
12762 12760 if (un->un_arq_enabled && un->un_untagged_qing) {
12763 12761 uchar_t f_o_e;
12764 12762
12765 12763 mutex_exit(ST_MUTEX);
12766 12764 f_o_e = (scsi_ifsetcap(ROUTE, "flush-on-errors", 1, 1) == 1) ?
12767 12765 1 : 0;
12768 12766 mutex_enter(ST_MUTEX);
12769 12767
12770 12768 un->un_flush_on_errors = f_o_e;
12771 12769 } else {
12772 12770 un->un_flush_on_errors = 0;
12773 12771 }
12774 12772
12775 12773 if (un->un_flush_on_errors)
12776 12774 un->un_max_throttle = (uchar_t)st_max_throttle;
12777 12775 else
12778 12776 un->un_max_throttle = 1;
12779 12777
12780 12778 if (un->un_dp->options & ST_RETRY_ON_RECOVERED_DEFERRED_ERROR)
12781 12779 un->un_max_throttle = 1;
12782 12780
12783 12781 /* this will send a marker pkt */
12784 12782 st_clear_pe(un);
12785 12783 }
12786 12784
12787 12785 /*
12788 12786 * This turns persistent errors permanently off
12789 12787 */
12790 12788 static void
12791 12789 st_turn_pe_off(struct scsi_tape *un)
12792 12790 {
12793 12791 ST_FUNC(ST_DEVINFO, st_turn_pe_off);
12794 12792 ST_DEBUG3(ST_DEVINFO, st_label, SCSI_DEBUG, "st_pe_off\n");
12795 12793 ASSERT(mutex_owned(ST_MUTEX));
12796 12794
12797 12795 /* turn it off for good */
12798 12796 un->un_persistence = 0;
12799 12797
12800 12798 /* this will send a marker pkt */
12801 12799 st_clear_pe(un);
12802 12800
12803 12801 /* turn off flush on error capability, if enabled */
12804 12802 if (un->un_flush_on_errors) {
12805 12803 mutex_exit(ST_MUTEX);
12806 12804 (void) scsi_ifsetcap(ROUTE, "flush-on-errors", 0, 1);
12807 12805 mutex_enter(ST_MUTEX);
12808 12806 }
12809 12807
12810 12808
12811 12809 un->un_flush_on_errors = 0;
12812 12810 }
12813 12811
12814 12812 /*
12815 12813 * This clear persistent errors, allowing more commands through, and also
12816 12814 * sending a marker packet.
12817 12815 */
12818 12816 static void
12819 12817 st_clear_pe(struct scsi_tape *un)
12820 12818 {
12821 12819 ST_FUNC(ST_DEVINFO, st_clear_pe);
12822 12820 ST_DEBUG3(ST_DEVINFO, st_label, SCSI_DEBUG, "st_pe_clear\n");
12823 12821 ASSERT(mutex_owned(ST_MUTEX));
12824 12822
12825 12823 un->un_persist_errors = 0;
12826 12824 un->un_throttle = un->un_last_throttle = 1;
12827 12825 un->un_errno = 0;
12828 12826 st_hba_unflush(un);
12829 12827 }
12830 12828
12831 12829 /*
12832 12830 * This will flag persistent errors, shutting everything down, if the
12833 12831 * application had enabled persistent errors via MTIOCPERSISTENT
12834 12832 */
12835 12833 static void
12836 12834 st_set_pe_flag(struct scsi_tape *un)
12837 12835 {
12838 12836 ST_FUNC(ST_DEVINFO, st_set_pe_flag);
12839 12837 ASSERT(mutex_owned(ST_MUTEX));
12840 12838
12841 12839 if (un->un_persistence) {
12842 12840 ST_DEBUG3(ST_DEVINFO, st_label, SCSI_DEBUG, "st_pe_flag\n");
12843 12841 un->un_persist_errors = 1;
12844 12842 un->un_throttle = un->un_last_throttle = 0;
12845 12843 cv_broadcast(&un->un_sbuf_cv);
12846 12844 }
12847 12845 }
12848 12846
12849 12847 static int
12850 12848 st_do_reserve(struct scsi_tape *un)
12851 12849 {
12852 12850 int rval;
12853 12851 int was_lost = un->un_rsvd_status & ST_LOST_RESERVE;
12854 12852
12855 12853 ST_FUNC(ST_DEVINFO, st_do_reserve);
12856 12854
12857 12855 /*
12858 12856 * Issue a Throw-Away reserve command to clear the
12859 12857 * check condition.
12860 12858 * If the current behaviour of reserve/release is to
12861 12859 * hold reservation across opens , and if a Bus reset
12862 12860 * has been issued between opens then this command
12863 12861 * would set the ST_LOST_RESERVE flags in rsvd_status.
12864 12862 * In this case return an EACCES so that user knows that
12865 12863 * reservation has been lost in between opens.
12866 12864 * If this error is not returned and we continue with
12867 12865 * successful open , then user may think position of the
12868 12866 * tape is still the same but inreality we would rewind the
12869 12867 * tape and continue from BOT.
12870 12868 */
12871 12869 rval = st_reserve_release(un, ST_RESERVE, st_uscsi_cmd);
12872 12870 if (rval) {
12873 12871 if ((un->un_rsvd_status & ST_LOST_RESERVE_BETWEEN_OPENS) ==
12874 12872 ST_LOST_RESERVE_BETWEEN_OPENS) {
12875 12873 un->un_rsvd_status &= ~(ST_LOST_RESERVE | ST_RESERVE);
12876 12874 un->un_errno = EACCES;
12877 12875 return (EACCES);
12878 12876 }
12879 12877 rval = st_reserve_release(un, ST_RESERVE, st_uscsi_cmd);
12880 12878 }
12881 12879 if (rval == 0) {
12882 12880 un->un_rsvd_status |= ST_INIT_RESERVE;
12883 12881 }
12884 12882 if (was_lost) {
12885 12883 un->un_running.pmode = invalid;
12886 12884 }
12887 12885
12888 12886 return (rval);
12889 12887 }
12890 12888
12891 12889 static int
12892 12890 st_check_cdb_for_need_to_reserve(struct scsi_tape *un, uchar_t *cdb)
12893 12891 {
12894 12892 int rval;
12895 12893 cmd_attribute const *attrib;
12896 12894
12897 12895 ST_FUNC(ST_DEVINFO, st_check_cdb_for_need_to_reserve);
12898 12896
12899 12897 /*
12900 12898 * If already reserved no need to do it again.
12901 12899 * Also if Reserve and Release are disabled Just return.
12902 12900 */
12903 12901 if ((un->un_rsvd_status & (ST_APPLICATION_RESERVATIONS)) ||
12904 12902 ((un->un_rsvd_status & (ST_RESERVE | ST_LOST_RESERVE)) ==
12905 12903 ST_RESERVE) || (un->un_dp->options & ST_NO_RESERVE_RELEASE)) {
12906 12904 ST_DEBUG6(ST_DEVINFO, st_label, CE_NOTE,
12907 12905 "st_check_cdb_for_need_to_reserve() reserve unneeded %s",
12908 12906 st_print_scsi_cmd((uchar_t)cdb[0]));
12909 12907 return (0);
12910 12908 }
12911 12909
12912 12910 /* See if command is on the list */
12913 12911 attrib = st_lookup_cmd_attribute(cdb[0]);
12914 12912
12915 12913 if (attrib == NULL) {
12916 12914 rval = 1; /* Not found, when in doubt reserve */
12917 12915 } else if ((attrib->requires_reserve) != 0) {
12918 12916 rval = 1;
12919 12917 } else if ((attrib->reserve_byte) != 0) {
12920 12918 /*
12921 12919 * cmd is on list.
12922 12920 * if byte is zero always allowed.
12923 12921 */
12924 12922 rval = 1;
12925 12923 } else if (((cdb[attrib->reserve_byte]) &
12926 12924 (attrib->reserve_mask)) != 0) {
12927 12925 rval = 1;
12928 12926 } else {
12929 12927 rval = 0;
12930 12928 }
12931 12929
12932 12930 if (rval) {
12933 12931 ST_DEBUG6(ST_DEVINFO, st_label, CE_NOTE,
12934 12932 "Command %s requires reservation",
12935 12933 st_print_scsi_cmd(cdb[0]));
12936 12934
12937 12935 rval = st_do_reserve(un);
12938 12936 }
12939 12937
12940 12938 return (rval);
12941 12939 }
12942 12940
12943 12941 static int
12944 12942 st_check_cmd_for_need_to_reserve(struct scsi_tape *un, uchar_t cmd, int cnt)
12945 12943 {
12946 12944 int rval;
12947 12945 cmd_attribute const *attrib;
12948 12946
12949 12947 ST_FUNC(ST_DEVINFO, st_check_cmd_for_need_to_reserve);
12950 12948
12951 12949 /*
12952 12950 * Do not reserve when already reserved, when not supported or when
12953 12951 * auto-rewinding on device closure.
12954 12952 */
12955 12953 if ((un->un_rsvd_status & (ST_APPLICATION_RESERVATIONS)) ||
12956 12954 ((un->un_rsvd_status & (ST_RESERVE | ST_LOST_RESERVE)) ==
12957 12955 ST_RESERVE) || (un->un_dp->options & ST_NO_RESERVE_RELEASE) ||
12958 12956 ((un->un_state == ST_STATE_CLOSING) && (cmd == SCMD_REWIND))) {
12959 12957 ST_DEBUG6(ST_DEVINFO, st_label, CE_NOTE,
12960 12958 "st_check_cmd_for_need_to_reserve() reserve unneeded %s",
12961 12959 st_print_scsi_cmd(cmd));
12962 12960 return (0);
12963 12961 }
12964 12962
12965 12963 /* search for this command on the list */
12966 12964 attrib = st_lookup_cmd_attribute(cmd);
12967 12965
12968 12966 if (attrib == NULL) {
12969 12967 rval = 1; /* Not found, when in doubt reserve */
12970 12968 } else if ((attrib->requires_reserve) != 0) {
12971 12969 rval = 1;
12972 12970 } else if ((attrib->reserve_byte) != 0) {
12973 12971 /*
12974 12972 * cmd is on list.
12975 12973 * if byte is zero always allowed.
12976 12974 */
12977 12975 rval = 1;
12978 12976 } else if (((attrib->reserve_mask) & cnt) != 0) {
12979 12977 rval = 1;
12980 12978 } else {
12981 12979 rval = 0;
12982 12980 }
12983 12981
12984 12982 if (rval) {
12985 12983 ST_DEBUG6(ST_DEVINFO, st_label, CE_NOTE,
12986 12984 "Cmd %s requires reservation", st_print_scsi_cmd(cmd));
12987 12985
12988 12986 rval = st_do_reserve(un);
12989 12987 }
12990 12988
12991 12989 return (rval);
12992 12990 }
12993 12991
12994 12992 static int
12995 12993 st_reserve_release(struct scsi_tape *un, int cmd, ubufunc_t ubf)
12996 12994 {
12997 12995 struct uscsi_cmd uscsi_cmd;
12998 12996 int rval;
12999 12997 char cdb[CDB_GROUP0];
13000 12998 struct scsi_arq_status stat;
13001 12999
13002 13000
13003 13001
13004 13002 ST_FUNC(ST_DEVINFO, st_reserve_release);
13005 13003
13006 13004 ASSERT(mutex_owned(ST_MUTEX));
13007 13005
13008 13006 ST_DEBUG3(ST_DEVINFO, st_label, SCSI_DEBUG,
13009 13007 "st_reserve_release: %s \n",
13010 13008 (cmd == ST_RELEASE)? "Releasing":"Reserving");
13011 13009
13012 13010 bzero(&cdb, CDB_GROUP0);
13013 13011 if (cmd == ST_RELEASE) {
13014 13012 cdb[0] = SCMD_RELEASE;
13015 13013 } else {
13016 13014 cdb[0] = SCMD_RESERVE;
13017 13015 }
13018 13016 bzero(&uscsi_cmd, sizeof (struct uscsi_cmd));
13019 13017 uscsi_cmd.uscsi_flags = USCSI_WRITE | USCSI_RQENABLE;
13020 13018 uscsi_cmd.uscsi_cdb = cdb;
13021 13019 uscsi_cmd.uscsi_cdblen = CDB_GROUP0;
13022 13020 uscsi_cmd.uscsi_timeout = un->un_dp->non_motion_timeout;
13023 13021 uscsi_cmd.uscsi_rqbuf = (caddr_t)&stat;
13024 13022 uscsi_cmd.uscsi_rqlen = sizeof (stat);
13025 13023
13026 13024 rval = ubf(un, &uscsi_cmd, FKIOCTL);
13027 13025
13028 13026 ST_DEBUG3(ST_DEVINFO, st_label, SCSI_DEBUG,
13029 13027 "st_reserve_release: rval(1)=%d\n", rval);
13030 13028
13031 13029 if (rval) {
13032 13030 if (uscsi_cmd.uscsi_status == STATUS_RESERVATION_CONFLICT) {
13033 13031 rval = EACCES;
13034 13032 }
13035 13033 /*
13036 13034 * dynamically turn off reserve/release support
13037 13035 * in case of drives which do not support
13038 13036 * reserve/release command(ATAPI drives).
13039 13037 */
13040 13038 if (un->un_status == KEY_ILLEGAL_REQUEST) {
13041 13039 if ((un->un_dp->options & ST_NO_RESERVE_RELEASE) == 0) {
13042 13040 un->un_dp->options |= ST_NO_RESERVE_RELEASE;
13043 13041 ST_DEBUG3(ST_DEVINFO, st_label, SCSI_DEBUG,
13044 13042 "Tape unit does not support "
13045 13043 "reserve/release \n");
13046 13044 }
13047 13045 rval = 0;
13048 13046 }
13049 13047 }
13050 13048 return (rval);
13051 13049 }
13052 13050
13053 13051 static int
13054 13052 st_take_ownership(struct scsi_tape *un, ubufunc_t ubf)
13055 13053 {
13056 13054 int rval;
13057 13055
13058 13056 ST_FUNC(ST_DEVINFO, st_take_ownership);
13059 13057
13060 13058 ASSERT(mutex_owned(ST_MUTEX));
13061 13059
13062 13060 ST_DEBUG3(ST_DEVINFO, st_label, SCSI_DEBUG,
13063 13061 "st_take_ownership: Entering ...\n");
13064 13062
13065 13063
13066 13064 rval = st_reserve_release(un, ST_RESERVE, ubf);
13067 13065 /*
13068 13066 * XXX -> Should reset be done only if we get EACCES.
13069 13067 * .
13070 13068 */
13071 13069 if (rval) {
13072 13070 if (st_reset(un, RESET_LUN) == 0) {
13073 13071 return (EIO);
13074 13072 }
13075 13073 un->un_rsvd_status &=
13076 13074 ~(ST_LOST_RESERVE | ST_RESERVATION_CONFLICT);
13077 13075
13078 13076 mutex_exit(ST_MUTEX);
13079 13077 delay(drv_usectohz(ST_RESERVATION_DELAY));
13080 13078 mutex_enter(ST_MUTEX);
13081 13079 /*
13082 13080 * remove the check condition.
13083 13081 */
13084 13082 (void) st_reserve_release(un, ST_RESERVE, ubf);
13085 13083 rval = st_reserve_release(un, ST_RESERVE, ubf);
13086 13084 if (rval != 0) {
13087 13085 if ((st_reserve_release(un, ST_RESERVE, ubf))
13088 13086 != 0) {
13089 13087 rval = (un->un_rsvd_status &
13090 13088 ST_RESERVATION_CONFLICT) ? EACCES : EIO;
13091 13089 return (rval);
13092 13090 }
13093 13091 }
13094 13092 /*
13095 13093 * Set tape state to ST_STATE_OFFLINE , in case if
13096 13094 * the user wants to continue and start using
13097 13095 * the tape.
13098 13096 */
13099 13097 un->un_state = ST_STATE_OFFLINE;
13100 13098 un->un_rsvd_status |= ST_INIT_RESERVE;
13101 13099 }
13102 13100 return (rval);
13103 13101 }
13104 13102
13105 13103 static int
13106 13104 st_create_errstats(struct scsi_tape *un, int instance)
13107 13105 {
13108 13106 char kstatname[KSTAT_STRLEN];
13109 13107
13110 13108 ST_FUNC(ST_DEVINFO, st_create_errstats);
13111 13109
13112 13110 /*
13113 13111 * Create device error kstats
13114 13112 */
13115 13113
13116 13114 if (un->un_errstats == (kstat_t *)0) {
13117 13115 (void) sprintf(kstatname, "st%d,err", instance);
13118 13116 un->un_errstats = kstat_create("sterr", instance, kstatname,
13119 13117 "device_error", KSTAT_TYPE_NAMED,
13120 13118 sizeof (struct st_errstats) / sizeof (kstat_named_t),
13121 13119 KSTAT_FLAG_PERSISTENT);
13122 13120
13123 13121 if (un->un_errstats) {
13124 13122 struct st_errstats *stp;
13125 13123
13126 13124 stp = (struct st_errstats *)un->un_errstats->ks_data;
13127 13125 kstat_named_init(&stp->st_softerrs, "Soft Errors",
13128 13126 KSTAT_DATA_ULONG);
13129 13127 kstat_named_init(&stp->st_harderrs, "Hard Errors",
13130 13128 KSTAT_DATA_ULONG);
13131 13129 kstat_named_init(&stp->st_transerrs, "Transport Errors",
13132 13130 KSTAT_DATA_ULONG);
13133 13131 kstat_named_init(&stp->st_vid, "Vendor",
13134 13132 KSTAT_DATA_CHAR);
13135 13133 kstat_named_init(&stp->st_pid, "Product",
13136 13134 KSTAT_DATA_CHAR);
13137 13135 kstat_named_init(&stp->st_revision, "Revision",
13138 13136 KSTAT_DATA_CHAR);
13139 13137 kstat_named_init(&stp->st_serial, "Serial No",
13140 13138 KSTAT_DATA_CHAR);
13141 13139 un->un_errstats->ks_private = un;
13142 13140 un->un_errstats->ks_update = nulldev;
13143 13141 kstat_install(un->un_errstats);
13144 13142 /*
13145 13143 * Fill in the static data
13146 13144 */
13147 13145 (void) strncpy(&stp->st_vid.value.c[0],
13148 13146 ST_INQUIRY->inq_vid, 8);
13149 13147 /*
13150 13148 * XXX: Emulex MT-02 (and emulators) predates
13151 13149 * SCSI-1 and has no vid & pid inquiry data.
13152 13150 */
13153 13151 if (ST_INQUIRY->inq_len != 0) {
13154 13152 (void) strncpy(&stp->st_pid.value.c[0],
13155 13153 ST_INQUIRY->inq_pid, 16);
13156 13154 (void) strncpy(&stp->st_revision.value.c[0],
13157 13155 ST_INQUIRY->inq_revision, 4);
13158 13156 }
13159 13157 }
13160 13158 }
13161 13159 return (0);
13162 13160 }
13163 13161
13164 13162 static int
13165 13163 st_validate_tapemarks(struct scsi_tape *un, ubufunc_t ubf, tapepos_t *pos)
13166 13164 {
13167 13165 int rval;
13168 13166 bufunc_t bf = (ubf == st_uscsi_rcmd) ? st_rcmd : st_cmd;
13169 13167
13170 13168 ST_FUNC(ST_DEVINFO, st_validate_tapemarks);
13171 13169
13172 13170 ASSERT(MUTEX_HELD(&un->un_sd->sd_mutex));
13173 13171 ASSERT(mutex_owned(ST_MUTEX));
13174 13172
13175 13173 /* Can't restore an invalid position */
13176 13174 if (pos->pmode == invalid) {
13177 13175 return (4);
13178 13176 }
13179 13177
13180 13178 /*
13181 13179 * Assumtions:
13182 13180 * If a position was read and is in logical position mode.
13183 13181 * If a drive supports read position it supports locate.
13184 13182 * If the read position type is not NO_POS. even though
13185 13183 * a read position make not have been attemped yet.
13186 13184 *
13187 13185 * The drive can locate to the position.
13188 13186 */
13189 13187 if (pos->pmode == logical || un->un_read_pos_type != NO_POS) {
13190 13188 /*
13191 13189 * If position mode is logical or legacy mode try
13192 13190 * to locate there as it is faster.
13193 13191 * If it fails try the old way.
13194 13192 */
13195 13193 scsi_log(ST_DEVINFO, st_label, CE_NOTE,
13196 13194 "Restoring tape position to lgclblkbo=0x%"PRIx64"....",
13197 13195 pos->lgclblkno);
13198 13196
13199 13197 if (st_logical_block_locate(un, st_uscsi_cmd, &un->un_pos,
13200 13198 pos->lgclblkno, pos->partition) == 0) {
13201 13199 /* Assume we are there copy rest of position back */
13202 13200 if (un->un_pos.lgclblkno == pos->lgclblkno) {
13203 13201 COPY_POS(&un->un_pos, pos);
13204 13202 }
13205 13203 return (0);
13206 13204 }
13207 13205
13208 13206 /*
13209 13207 * If logical block locate failed to restore a logical
13210 13208 * position, can't recover.
13211 13209 */
13212 13210 if (pos->pmode == logical) {
13213 13211 return (-1);
13214 13212 }
13215 13213 }
13216 13214
13217 13215
13218 13216 scsi_log(ST_DEVINFO, st_label, CE_NOTE,
13219 13217 "Restoring tape position at fileno=%x, blkno=%x....",
13220 13218 pos->fileno, pos->blkno);
13221 13219
13222 13220 /*
13223 13221 * Rewind ? Oh yeah, Fidelity has got the STK F/W changed
13224 13222 * so as not to rewind tape on RESETS: Gee, Has life ever
13225 13223 * been simple in tape land ?
13226 13224 */
13227 13225 rval = bf(un, SCMD_REWIND, 0, SYNC_CMD);
13228 13226 if (rval) {
13229 13227 scsi_log(ST_DEVINFO, st_label, CE_WARN,
13230 13228 "Failed to restore the last file and block position: In"
13231 13229 " this state, Tape will be loaded at BOT during next open");
13232 13230 un->un_pos.pmode = invalid;
13233 13231 return (rval);
13234 13232 }
13235 13233
13236 13234 /* If the position was as the result of back space file */
13237 13235 if (pos->blkno > (INF / 2)) {
13238 13236 /* Go one extra file forward */
13239 13237 pos->fileno++;
13240 13238 /* Figure how many blocks to back into the previous file */
13241 13239 pos->blkno = -(INF - pos->blkno);
13242 13240 }
13243 13241
13244 13242 /* Go to requested fileno */
13245 13243 if (pos->fileno) {
13246 13244 rval = st_cmd(un, SCMD_SPACE, Fmk(pos->fileno), SYNC_CMD);
13247 13245 if (rval) {
13248 13246 scsi_log(ST_DEVINFO, st_label, CE_WARN,
13249 13247 "Failed to restore the last file position: In this "
13250 13248 " state, Tape will be loaded at BOT during next"
13251 13249 " open %d", __LINE__);
13252 13250 un->un_pos.pmode = invalid;
13253 13251 pos->pmode = invalid;
13254 13252 return (rval);
13255 13253 }
13256 13254 }
13257 13255
13258 13256 /*
13259 13257 * If backing into a file we already did an extra file forward.
13260 13258 * Now we have to back over the filemark to get to the end of
13261 13259 * the previous file. The blkno has been ajusted to a negative
13262 13260 * value so we will get to the expected location.
13263 13261 */
13264 13262 if (pos->blkno) {
13265 13263 rval = bf(un, SCMD_SPACE, Fmk(-1), SYNC_CMD);
13266 13264 if (rval) {
13267 13265 scsi_log(ST_DEVINFO, st_label, CE_WARN,
13268 13266 "Failed to restore the last file position: In this "
13269 13267 " state, Tape will be loaded at BOT during next"
13270 13268 " open %d", __LINE__);
13271 13269 un->un_pos.pmode = invalid;
13272 13270 pos->pmode = invalid;
13273 13271 return (rval);
13274 13272 }
13275 13273 }
13276 13274
13277 13275 /*
13278 13276 * The position mode, block and fileno should be correct,
13279 13277 * This updates eof and logical position information.
13280 13278 */
13281 13279 un->un_pos.eof = pos->eof;
13282 13280 un->un_pos.lgclblkno = pos->lgclblkno;
13283 13281
13284 13282 return (0);
13285 13283 }
13286 13284
13287 13285 /*
13288 13286 * check sense key, ASC, ASCQ in order to determine if the tape needs
13289 13287 * to be ejected
13290 13288 */
13291 13289
13292 13290 static int
13293 13291 st_check_asc_ascq(struct scsi_tape *un)
13294 13292 {
13295 13293 struct scsi_extended_sense *sensep = ST_RQSENSE;
13296 13294 struct tape_failure_code *code;
13297 13295
13298 13296 ST_FUNC(ST_DEVINFO, st_check_asc_ascq);
13299 13297
13300 13298 for (code = st_tape_failure_code; code->key != 0xff; code++) {
13301 13299 if ((code->key == sensep->es_key) &&
13302 13300 (code->add_code == sensep->es_add_code) &&
13303 13301 (code->qual_code == sensep->es_qual_code))
13304 13302 return (1);
13305 13303 }
13306 13304 return (0);
13307 13305 }
13308 13306
13309 13307 /*
13310 13308 * st_logpage_supported() sends a Log Sense command with
13311 13309 * page code = 0 = Supported Log Pages Page to the device,
13312 13310 * to see whether the page 'page' is supported.
13313 13311 * Return values are:
13314 13312 * -1 if the Log Sense command fails
13315 13313 * 0 if page is not supported
13316 13314 * 1 if page is supported
13317 13315 */
13318 13316
13319 13317 static int
13320 13318 st_logpage_supported(struct scsi_tape *un, uchar_t page)
13321 13319 {
13322 13320 uchar_t *sp, *sensep;
13323 13321 unsigned length;
13324 13322 struct uscsi_cmd *com;
13325 13323 struct scsi_arq_status status;
13326 13324 int rval;
13327 13325 char cdb[CDB_GROUP1] = {
13328 13326 SCMD_LOG_SENSE_G1,
13329 13327 0,
13330 13328 SUPPORTED_LOG_PAGES_PAGE,
13331 13329 0,
13332 13330 0,
13333 13331 0,
13334 13332 0,
13335 13333 0,
13336 13334 (char)LOG_SENSE_LENGTH,
13337 13335 0
13338 13336 };
13339 13337
13340 13338 ST_FUNC(ST_DEVINFO, st_logpage_supported);
13341 13339
13342 13340 ASSERT(mutex_owned(ST_MUTEX));
13343 13341
13344 13342 com = kmem_zalloc(sizeof (struct uscsi_cmd), KM_SLEEP);
13345 13343 sensep = kmem_zalloc(LOG_SENSE_LENGTH, KM_SLEEP);
13346 13344
13347 13345 com->uscsi_cdb = cdb;
13348 13346 com->uscsi_cdblen = CDB_GROUP1;
13349 13347 com->uscsi_bufaddr = (caddr_t)sensep;
13350 13348 com->uscsi_buflen = LOG_SENSE_LENGTH;
13351 13349 com->uscsi_rqlen = sizeof (status);
13352 13350 com->uscsi_rqbuf = (caddr_t)&status;
13353 13351 com->uscsi_flags =
13354 13352 USCSI_DIAGNOSE | USCSI_RQENABLE | USCSI_READ;
13355 13353 com->uscsi_timeout = un->un_dp->non_motion_timeout;
13356 13354 rval = st_uscsi_cmd(un, com, FKIOCTL);
13357 13355 if (rval || com->uscsi_status) {
13358 13356 /* uscsi-command failed */
13359 13357 rval = -1;
13360 13358 } else {
13361 13359
13362 13360 sp = sensep + 3;
13363 13361
13364 13362 for (length = *sp++; length > 0; length--, sp++) {
13365 13363
13366 13364 if (*sp == page) {
13367 13365 rval = 1;
13368 13366 break;
13369 13367 }
13370 13368 }
13371 13369 }
13372 13370 kmem_free(com, sizeof (struct uscsi_cmd));
13373 13371 kmem_free(sensep, LOG_SENSE_LENGTH);
13374 13372 return (rval);
13375 13373 }
13376 13374
13377 13375
13378 13376 /*
13379 13377 * st_check_clean_bit() gets the status of the tape's cleaning bit.
13380 13378 *
13381 13379 * If the device does support the TapeAlert log page, then the cleaning bit
13382 13380 * information will be read from this page. Otherwise we will see if one of
13383 13381 * ST_CLN_TYPE_1, ST_CLN_TYPE_2 or ST_CLN_TYPE_3 is set in the properties of
13384 13382 * the device, which means, that we can get the cleaning bit information via
13385 13383 * a RequestSense command.
13386 13384 * If both methods of getting cleaning bit information are not supported
13387 13385 * st_check_clean_bit() will return with 0. Otherwise st_check_clean_bit()
13388 13386 * returns with
13389 13387 * - MTF_TAPE_CLN_SUPPORTED if cleaning bit is not set or
13390 13388 * - MTF_TAPE_CLN_SUPPORTED | MTF_TAPE_HEAD_DIRTY if cleaning bit is set.
13391 13389 * If the call to st_uscsi_cmd() to do the Log Sense or the Request Sense
13392 13390 * command fails, or if the amount of Request Sense data is not enough, then
13393 13391 * st_check_clean_bit() returns with -1.
13394 13392 */
13395 13393
13396 13394 static int
13397 13395 st_check_clean_bit(struct scsi_tape *un)
13398 13396 {
13399 13397 int rval = 0;
13400 13398
13401 13399 ST_FUNC(ST_DEVINFO, st_check_clean_bit);
13402 13400
13403 13401 ASSERT(mutex_owned(ST_MUTEX));
13404 13402
13405 13403 if (un->un_HeadClean & TAPE_ALERT_NOT_SUPPORTED) {
13406 13404 return (rval);
13407 13405 }
13408 13406
13409 13407 if (un->un_HeadClean == TAPE_ALERT_SUPPORT_UNKNOWN) {
13410 13408
13411 13409 rval = st_logpage_supported(un, TAPE_SEQUENTIAL_PAGE);
13412 13410 if (rval == -1) {
13413 13411 return (0);
13414 13412 }
13415 13413 if (rval == 1) {
13416 13414
13417 13415 un->un_HeadClean |= TAPE_SEQUENTIAL_SUPPORTED;
13418 13416 }
13419 13417
13420 13418 rval = st_logpage_supported(un, TAPE_ALERT_PAGE);
13421 13419 if (rval == -1) {
13422 13420 return (0);
13423 13421 }
13424 13422 if (rval == 1) {
13425 13423
13426 13424 un->un_HeadClean |= TAPE_ALERT_SUPPORTED;
13427 13425 }
13428 13426
13429 13427 if (un->un_HeadClean == TAPE_ALERT_SUPPORT_UNKNOWN) {
13430 13428
13431 13429 un->un_HeadClean = TAPE_ALERT_NOT_SUPPORTED;
13432 13430 }
13433 13431 }
13434 13432
13435 13433 rval = 0;
13436 13434
13437 13435 if (un->un_HeadClean & TAPE_SEQUENTIAL_SUPPORTED) {
13438 13436
13439 13437 rval = st_check_sequential_clean_bit(un);
13440 13438 if (rval == -1) {
13441 13439 return (0);
13442 13440 }
13443 13441 }
13444 13442
13445 13443 if ((rval == 0) && (un->un_HeadClean & TAPE_ALERT_SUPPORTED)) {
13446 13444
13447 13445 rval = st_check_alert_flags(un);
13448 13446 if (rval == -1) {
13449 13447 return (0);
13450 13448 }
13451 13449 }
13452 13450
13453 13451 if ((rval == 0) && (un->un_dp->options & ST_CLN_MASK)) {
13454 13452
13455 13453 rval = st_check_sense_clean_bit(un);
13456 13454 if (rval == -1) {
13457 13455 return (0);
13458 13456 }
13459 13457 }
13460 13458
13461 13459 /*
13462 13460 * If found a supported means to check need to clean.
13463 13461 */
13464 13462 if (rval & MTF_TAPE_CLN_SUPPORTED) {
13465 13463
13466 13464 /*
13467 13465 * head needs to be cleaned.
13468 13466 */
13469 13467 if (rval & MTF_TAPE_HEAD_DIRTY) {
13470 13468
13471 13469 /*
13472 13470 * Print log message only first time
13473 13471 * found needing cleaned.
13474 13472 */
13475 13473 if ((un->un_HeadClean & TAPE_PREVIOUSLY_DIRTY) == 0) {
13476 13474
13477 13475 scsi_log(ST_DEVINFO, st_label, CE_WARN,
13478 13476 "Periodic head cleaning required");
13479 13477
13480 13478 un->un_HeadClean |= TAPE_PREVIOUSLY_DIRTY;
13481 13479 }
13482 13480
13483 13481 } else {
13484 13482
13485 13483 un->un_HeadClean &= ~TAPE_PREVIOUSLY_DIRTY;
13486 13484 }
13487 13485 }
13488 13486
13489 13487 return (rval);
13490 13488 }
13491 13489
13492 13490
13493 13491 static int
13494 13492 st_check_sequential_clean_bit(struct scsi_tape *un)
13495 13493 {
13496 13494 int rval;
13497 13495 int ix;
13498 13496 ushort_t parameter;
13499 13497 struct uscsi_cmd *cmd;
13500 13498 struct log_sequential_page *sp;
13501 13499 struct log_sequential_page_parameter *prm;
13502 13500 struct scsi_arq_status status;
13503 13501 char cdb[CDB_GROUP1] = {
13504 13502 SCMD_LOG_SENSE_G1,
13505 13503 0,
13506 13504 TAPE_SEQUENTIAL_PAGE | CURRENT_CUMULATIVE_VALUES,
13507 13505 0,
13508 13506 0,
13509 13507 0,
13510 13508 0,
13511 13509 (char)(sizeof (struct log_sequential_page) >> 8),
13512 13510 (char)(sizeof (struct log_sequential_page)),
13513 13511 0
13514 13512 };
13515 13513
13516 13514 ST_FUNC(ST_DEVINFO, st_check_sequential_clean_bit);
13517 13515
13518 13516 cmd = kmem_zalloc(sizeof (struct uscsi_cmd), KM_SLEEP);
13519 13517 sp = kmem_zalloc(sizeof (struct log_sequential_page), KM_SLEEP);
13520 13518
13521 13519 cmd->uscsi_flags =
13522 13520 USCSI_DIAGNOSE | USCSI_RQENABLE | USCSI_READ;
13523 13521 cmd->uscsi_timeout = un->un_dp->non_motion_timeout;
13524 13522 cmd->uscsi_cdb = cdb;
13525 13523 cmd->uscsi_cdblen = CDB_GROUP1;
13526 13524 cmd->uscsi_bufaddr = (caddr_t)sp;
13527 13525 cmd->uscsi_buflen = sizeof (struct log_sequential_page);
13528 13526 cmd->uscsi_rqlen = sizeof (status);
13529 13527 cmd->uscsi_rqbuf = (caddr_t)&status;
13530 13528
13531 13529 rval = st_uscsi_cmd(un, cmd, FKIOCTL);
13532 13530
13533 13531 if (rval || cmd->uscsi_status || cmd->uscsi_resid) {
13534 13532
13535 13533 rval = -1;
13536 13534
13537 13535 } else if (sp->log_page.code != TAPE_SEQUENTIAL_PAGE) {
13538 13536
13539 13537 rval = -1;
13540 13538 }
13541 13539
13542 13540 prm = &sp->param[0];
13543 13541
13544 13542 for (ix = 0; rval == 0 && ix < TAPE_SEQUENTIAL_PAGE_PARA; ix++) {
13545 13543
13546 13544 if (prm->log_param.length == 0) {
13547 13545 break;
13548 13546 }
13549 13547
13550 13548 parameter = (((prm->log_param.pc_hi << 8) & 0xff00) +
13551 13549 (prm->log_param.pc_lo & 0xff));
13552 13550
13553 13551 if (parameter == SEQUENTIAL_NEED_CLN) {
13554 13552
13555 13553 rval = MTF_TAPE_CLN_SUPPORTED;
13556 13554 if (prm->param_value[prm->log_param.length - 1]) {
13557 13555
13558 13556 ST_DEBUG2(ST_DEVINFO, st_label, SCSI_DEBUG,
13559 13557 "sequential log says head dirty\n");
13560 13558 rval |= MTF_TAPE_HEAD_DIRTY;
13561 13559 }
13562 13560 }
13563 13561 prm = (struct log_sequential_page_parameter *)
13564 13562 &prm->param_value[prm->log_param.length];
13565 13563 }
13566 13564
13567 13565 kmem_free(cmd, sizeof (struct uscsi_cmd));
13568 13566 kmem_free(sp, sizeof (struct log_sequential_page));
13569 13567
13570 13568 return (rval);
13571 13569 }
13572 13570
13573 13571
13574 13572 static int
13575 13573 st_check_alert_flags(struct scsi_tape *un)
13576 13574 {
13577 13575 struct st_tape_alert *ta;
13578 13576 struct uscsi_cmd *com;
13579 13577 struct scsi_arq_status status;
13580 13578 unsigned ix, length;
13581 13579 int rval;
13582 13580 tape_alert_flags flag;
13583 13581 char cdb[CDB_GROUP1] = {
13584 13582 SCMD_LOG_SENSE_G1,
13585 13583 0,
13586 13584 TAPE_ALERT_PAGE | CURRENT_THRESHOLD_VALUES,
13587 13585 0,
13588 13586 0,
13589 13587 0,
13590 13588 0,
13591 13589 (char)(sizeof (struct st_tape_alert) >> 8),
13592 13590 (char)(sizeof (struct st_tape_alert)),
13593 13591 0
13594 13592 };
13595 13593
13596 13594 ST_FUNC(ST_DEVINFO, st_check_alert_clean_bit);
13597 13595
13598 13596 com = kmem_zalloc(sizeof (struct uscsi_cmd), KM_SLEEP);
13599 13597 ta = kmem_zalloc(sizeof (struct st_tape_alert), KM_SLEEP);
13600 13598
13601 13599 com->uscsi_cdb = cdb;
13602 13600 com->uscsi_cdblen = CDB_GROUP1;
13603 13601 com->uscsi_bufaddr = (caddr_t)ta;
13604 13602 com->uscsi_buflen = sizeof (struct st_tape_alert);
13605 13603 com->uscsi_rqlen = sizeof (status);
13606 13604 com->uscsi_rqbuf = (caddr_t)&status;
13607 13605 com->uscsi_flags =
13608 13606 USCSI_DIAGNOSE | USCSI_RQENABLE | USCSI_READ;
13609 13607 com->uscsi_timeout = un->un_dp->non_motion_timeout;
13610 13608
13611 13609 rval = st_uscsi_cmd(un, com, FKIOCTL);
13612 13610
13613 13611 if (rval || com->uscsi_status || com->uscsi_resid) {
13614 13612
13615 13613 rval = -1; /* uscsi-command failed */
13616 13614
13617 13615 } else if (ta->log_page.code != TAPE_ALERT_PAGE) {
13618 13616
13619 13617 ST_DEBUG2(ST_DEVINFO, st_label, SCSI_DEBUG,
13620 13618 "Not Alert Log Page returned 0x%X\n", ta->log_page.code);
13621 13619 rval = -1;
13622 13620 }
13623 13621
13624 13622 length = (ta->log_page.length_hi << 8) + ta->log_page.length_lo;
13625 13623
13626 13624
13627 13625 if (length != TAPE_ALERT_PARAMETER_LENGTH) {
13628 13626
13629 13627 ST_DEBUG2(ST_DEVINFO, st_label, SCSI_DEBUG,
13630 13628 "TapeAlert length %d\n", length);
13631 13629 }
13632 13630
13633 13631
13634 13632 for (ix = 0; ix < TAPE_ALERT_MAX_PARA; ix++) {
13635 13633
13636 13634 /*
13637 13635 * if rval is bad before the first pass don't bother
13638 13636 */
13639 13637 if (ix == 0 && rval != 0) {
13640 13638
13641 13639 break;
13642 13640 }
13643 13641
13644 13642 flag = ((ta->param[ix].log_param.pc_hi << 8) +
13645 13643 ta->param[ix].log_param.pc_lo);
13646 13644
13647 13645 if ((ta->param[ix].param_value & 1) == 0) {
13648 13646 continue;
13649 13647 }
13650 13648 /*
13651 13649 * check to see if current parameter is of interest.
13652 13650 * CLEAN_FOR_ERRORS is vendor specific to 9840 9940 stk's.
13653 13651 */
13654 13652 if ((flag == TAF_CLEAN_NOW) ||
13655 13653 (flag == TAF_CLEAN_PERIODIC) ||
13656 13654 ((flag == CLEAN_FOR_ERRORS) &&
13657 13655 (un->un_dp->type == ST_TYPE_STK9840))) {
13658 13656
13659 13657 rval = MTF_TAPE_CLN_SUPPORTED;
13660 13658
13661 13659
13662 13660 ST_DEBUG2(ST_DEVINFO, st_label, SCSI_DEBUG,
13663 13661 "alert_page drive needs clean %d\n", flag);
13664 13662 un->un_HeadClean |= TAPE_ALERT_STILL_DIRTY;
13665 13663 rval |= MTF_TAPE_HEAD_DIRTY;
13666 13664
13667 13665 } else if (flag == TAF_CLEANING_MEDIA) {
13668 13666
13669 13667 ST_DEBUG2(ST_DEVINFO, st_label, SCSI_DEBUG,
13670 13668 "alert_page drive was cleaned\n");
13671 13669 un->un_HeadClean &= ~TAPE_ALERT_STILL_DIRTY;
13672 13670 }
13673 13671
13674 13672 }
13675 13673
13676 13674 /*
13677 13675 * Report it as dirty till we see it cleaned
13678 13676 */
13679 13677 if (un->un_HeadClean & TAPE_ALERT_STILL_DIRTY) {
13680 13678
13681 13679 ST_DEBUG2(ST_DEVINFO, st_label, SCSI_DEBUG,
13682 13680 "alert_page still dirty\n");
13683 13681 rval |= MTF_TAPE_HEAD_DIRTY;
13684 13682 }
13685 13683
13686 13684 kmem_free(com, sizeof (struct uscsi_cmd));
13687 13685 kmem_free(ta, sizeof (struct st_tape_alert));
13688 13686
13689 13687 return (rval);
13690 13688 }
13691 13689
13692 13690
13693 13691 static int
13694 13692 st_check_sense_clean_bit(struct scsi_tape *un)
13695 13693 {
13696 13694 uchar_t *sensep;
13697 13695 char cdb[CDB_GROUP0];
13698 13696 struct uscsi_cmd *com;
13699 13697 ushort_t byte_pos;
13700 13698 uchar_t bit_mask;
13701 13699 unsigned length;
13702 13700 int index;
13703 13701 int rval;
13704 13702
13705 13703 ST_FUNC(ST_DEVINFO, st_check_sense_clean_bit);
13706 13704
13707 13705 /*
13708 13706 * Since this tape does not support Tape Alert,
13709 13707 * we now try to get the cleanbit status via
13710 13708 * Request Sense.
13711 13709 */
13712 13710
13713 13711 if ((un->un_dp->options & ST_CLN_MASK) == ST_CLN_TYPE_1) {
13714 13712
13715 13713 index = 0;
13716 13714
13717 13715 } else if ((un->un_dp->options & ST_CLN_MASK) == ST_CLN_TYPE_2) {
13718 13716
13719 13717 index = 1;
13720 13718
13721 13719 } else if ((un->un_dp->options & ST_CLN_MASK) == ST_CLN_TYPE_3) {
13722 13720
13723 13721 index = 2;
13724 13722
13725 13723 } else {
13726 13724
13727 13725 return (-1);
13728 13726 }
13729 13727
13730 13728 byte_pos = st_cln_bit_position[index].cln_bit_byte;
13731 13729 bit_mask = st_cln_bit_position[index].cln_bit_mask;
13732 13730 length = byte_pos + 1;
13733 13731
13734 13732 com = kmem_zalloc(sizeof (struct uscsi_cmd), KM_SLEEP);
13735 13733 sensep = kmem_zalloc(length, KM_SLEEP);
13736 13734
13737 13735 cdb[0] = SCMD_REQUEST_SENSE;
13738 13736 cdb[1] = 0;
13739 13737 cdb[2] = 0;
13740 13738 cdb[3] = 0;
13741 13739 cdb[4] = (char)length;
13742 13740 cdb[5] = 0;
13743 13741
13744 13742 com->uscsi_cdb = cdb;
13745 13743 com->uscsi_cdblen = CDB_GROUP0;
13746 13744 com->uscsi_bufaddr = (caddr_t)sensep;
13747 13745 com->uscsi_buflen = length;
13748 13746 com->uscsi_flags =
13749 13747 USCSI_DIAGNOSE | USCSI_SILENT | USCSI_READ;
13750 13748 com->uscsi_timeout = un->un_dp->non_motion_timeout;
13751 13749
13752 13750 rval = st_uscsi_cmd(un, com, FKIOCTL);
13753 13751
13754 13752 if (rval || com->uscsi_status || com->uscsi_resid) {
13755 13753
13756 13754 rval = -1;
13757 13755
13758 13756 } else {
13759 13757
13760 13758 rval = MTF_TAPE_CLN_SUPPORTED;
13761 13759 if ((sensep[byte_pos] & bit_mask) == bit_mask) {
13762 13760
13763 13761 ST_DEBUG2(ST_DEVINFO, st_label, SCSI_DEBUG,
13764 13762 "sense data says head dirty\n");
13765 13763 rval |= MTF_TAPE_HEAD_DIRTY;
13766 13764 }
13767 13765 }
13768 13766
13769 13767 kmem_free(com, sizeof (struct uscsi_cmd));
13770 13768 kmem_free(sensep, length);
13771 13769 return (rval);
13772 13770 }
13773 13771
13774 13772 /*
13775 13773 * st_clear_unit_attention
13776 13774 *
13777 13775 * run test unit ready's to clear out outstanding
13778 13776 * unit attentions.
13779 13777 * returns zero for SUCCESS or the errno from st_cmd call
13780 13778 */
13781 13779 static int
13782 13780 st_clear_unit_attentions(dev_t dev_instance, int max_trys)
13783 13781 {
13784 13782 int i = 0;
13785 13783 int rval;
13786 13784
13787 13785 GET_SOFT_STATE(dev_instance);
13788 13786 ST_FUNC(ST_DEVINFO, st_clear_unit_attentions);
13789 13787
13790 13788 do {
13791 13789 rval = st_cmd(un, SCMD_TEST_UNIT_READY, 0, SYNC_CMD);
13792 13790 } while ((rval != 0) && (rval != ENXIO) && (++i < max_trys));
13793 13791 return (rval);
13794 13792 }
13795 13793
13796 13794 static void
13797 13795 st_calculate_timeouts(struct scsi_tape *un)
13798 13796 {
13799 13797 ST_FUNC(ST_DEVINFO, st_calculate_timeouts);
13800 13798
13801 13799 if (un->un_dp->non_motion_timeout == 0) {
13802 13800 if (un->un_dp->options & ST_LONG_TIMEOUTS) {
13803 13801 un->un_dp->non_motion_timeout =
13804 13802 st_io_time * st_long_timeout_x;
13805 13803 } else {
13806 13804 un->un_dp->non_motion_timeout = (ushort_t)st_io_time;
13807 13805 }
13808 13806 }
13809 13807
13810 13808 if (un->un_dp->io_timeout == 0) {
13811 13809 if (un->un_dp->options & ST_LONG_TIMEOUTS) {
13812 13810 un->un_dp->io_timeout = st_io_time * st_long_timeout_x;
13813 13811 } else {
13814 13812 un->un_dp->io_timeout = (ushort_t)st_io_time;
13815 13813 }
13816 13814 }
13817 13815
13818 13816 if (un->un_dp->rewind_timeout == 0) {
13819 13817 if (un->un_dp->options & ST_LONG_TIMEOUTS) {
13820 13818 un->un_dp->rewind_timeout =
13821 13819 st_space_time * st_long_timeout_x;
13822 13820 } else {
13823 13821 un->un_dp->rewind_timeout = (ushort_t)st_space_time;
13824 13822 }
13825 13823 }
13826 13824
13827 13825 if (un->un_dp->space_timeout == 0) {
13828 13826 if (un->un_dp->options & ST_LONG_TIMEOUTS) {
13829 13827 un->un_dp->space_timeout =
13830 13828 st_space_time * st_long_timeout_x;
13831 13829 } else {
13832 13830 un->un_dp->space_timeout = (ushort_t)st_space_time;
13833 13831 }
13834 13832 }
13835 13833
13836 13834 if (un->un_dp->load_timeout == 0) {
13837 13835 if (un->un_dp->options & ST_LONG_TIMEOUTS) {
13838 13836 un->un_dp->load_timeout =
13839 13837 st_space_time * st_long_timeout_x;
13840 13838 } else {
13841 13839 un->un_dp->load_timeout = (ushort_t)st_space_time;
13842 13840 }
13843 13841 }
13844 13842
13845 13843 if (un->un_dp->unload_timeout == 0) {
13846 13844 if (un->un_dp->options & ST_LONG_TIMEOUTS) {
13847 13845 un->un_dp->unload_timeout =
13848 13846 st_space_time * st_long_timeout_x;
13849 13847 } else {
13850 13848 un->un_dp->unload_timeout = (ushort_t)st_space_time;
13851 13849 }
13852 13850 }
13853 13851
13854 13852 if (un->un_dp->erase_timeout == 0) {
13855 13853 if (un->un_dp->options & ST_LONG_ERASE) {
13856 13854 un->un_dp->erase_timeout =
13857 13855 st_space_time * st_long_space_time_x;
13858 13856 } else {
13859 13857 un->un_dp->erase_timeout = (ushort_t)st_space_time;
13860 13858 }
13861 13859 }
13862 13860 }
13863 13861
13864 13862
13865 13863 static writablity
13866 13864 st_is_not_wormable(struct scsi_tape *un)
13867 13865 {
13868 13866 ST_FUNC(ST_DEVINFO, st_is_not_wormable);
13869 13867 return (RDWR);
13870 13868 }
13871 13869
13872 13870 static writablity
13873 13871 st_is_hp_dat_tape_worm(struct scsi_tape *un)
13874 13872 {
13875 13873 writablity wrt;
13876 13874
13877 13875 ST_FUNC(ST_DEVINFO, st_is_hp_dat_tape_worm);
13878 13876
13879 13877 /* Mode sense should be current */
13880 13878 if (un->un_mspl->media_type == 1) {
13881 13879 ST_DEBUG2(ST_DEVINFO, st_label, SCSI_DEBUG,
13882 13880 "Drive has WORM media loaded\n");
13883 13881 wrt = WORM;
13884 13882 } else {
13885 13883 ST_DEBUG2(ST_DEVINFO, st_label, SCSI_DEBUG,
13886 13884 "Drive has non WORM media loaded\n");
13887 13885 wrt = RDWR;
13888 13886 }
13889 13887 return (wrt);
13890 13888 }
13891 13889
13892 13890 #define HP_DAT_INQUIRY 0x4A
13893 13891 static writablity
13894 13892 st_is_hp_dat_worm(struct scsi_tape *un)
13895 13893 {
13896 13894 char *buf;
13897 13895 int result;
13898 13896 writablity wrt;
13899 13897
13900 13898 ST_FUNC(ST_DEVINFO, st_is_hp_dat_worm);
13901 13899
13902 13900 buf = kmem_zalloc(HP_DAT_INQUIRY, KM_SLEEP);
13903 13901
13904 13902 result = st_get_special_inquiry(un, HP_DAT_INQUIRY, buf, 0);
13905 13903
13906 13904 if (result != 0) {
13907 13905 ST_DEBUG2(ST_DEVINFO, st_label, SCSI_DEBUG,
13908 13906 "Read Standard Inquiry for WORM support failed");
13909 13907 wrt = FAILED;
13910 13908 } else if ((buf[40] & 1) == 0) {
13911 13909 ST_DEBUG2(ST_DEVINFO, st_label, SCSI_DEBUG,
13912 13910 "Drive is NOT WORMable\n");
13913 13911 /* This drive doesn't support it so don't check again */
13914 13912 un->un_dp->options &= ~ST_WORMABLE;
13915 13913 wrt = RDWR;
13916 13914 un->un_wormable = st_is_not_wormable;
13917 13915 } else {
13918 13916 ST_DEBUG2(ST_DEVINFO, st_label, SCSI_DEBUG,
13919 13917 "Drive supports WORM version %d\n", buf[40] >> 1);
13920 13918 un->un_wormable = st_is_hp_dat_tape_worm;
13921 13919 wrt = un->un_wormable(un);
13922 13920 }
13923 13921
13924 13922 kmem_free(buf, HP_DAT_INQUIRY);
13925 13923
13926 13924 /*
13927 13925 * If drive doesn't support it no point in checking further.
13928 13926 */
13929 13927 return (wrt);
13930 13928 }
13931 13929
13932 13930 static writablity
13933 13931 st_is_hp_lto_tape_worm(struct scsi_tape *un)
13934 13932 {
13935 13933 writablity wrt;
13936 13934
13937 13935 ST_FUNC(ST_DEVINFO, st_is_hp_lto_tape_worm);
13938 13936
13939 13937 /* Mode sense should be current */
13940 13938 switch (un->un_mspl->media_type) {
13941 13939 case 0x00:
13942 13940 switch (un->un_mspl->density) {
13943 13941 case 0x40:
13944 13942 ST_DEBUG2(ST_DEVINFO, st_label, SCSI_DEBUG,
13945 13943 "Drive has standard Gen I media loaded\n");
13946 13944 break;
13947 13945 case 0x42:
13948 13946 ST_DEBUG2(ST_DEVINFO, st_label, SCSI_DEBUG,
13949 13947 "Drive has standard Gen II media loaded\n");
13950 13948 break;
13951 13949 case 0x44:
13952 13950 ST_DEBUG2(ST_DEVINFO, st_label, SCSI_DEBUG,
13953 13951 "Drive has standard Gen III media loaded\n");
13954 13952 break;
13955 13953 case 0x46:
13956 13954 ST_DEBUG2(ST_DEVINFO, st_label, SCSI_DEBUG,
13957 13955 "Drive has standard Gen IV media loaded\n");
13958 13956 break;
13959 13957 default:
13960 13958 ST_DEBUG2(ST_DEVINFO, st_label, SCSI_DEBUG,
13961 13959 "Drive has standard unknown 0x%X media loaded\n",
13962 13960 un->un_mspl->density);
13963 13961 }
13964 13962 wrt = RDWR;
13965 13963 break;
13966 13964 case 0x01:
13967 13965 ST_DEBUG2(ST_DEVINFO, st_label, SCSI_DEBUG,
13968 13966 "Drive has WORM medium loaded\n");
13969 13967 wrt = WORM;
13970 13968 break;
13971 13969 case 0x80:
13972 13970 ST_DEBUG2(ST_DEVINFO, st_label, SCSI_DEBUG,
13973 13971 "Drive has CD-ROM emulation medium loaded\n");
13974 13972 wrt = WORM;
13975 13973 break;
13976 13974 default:
13977 13975 ST_DEBUG2(ST_DEVINFO, st_label, SCSI_DEBUG,
13978 13976 "Drive has an unexpected medium type 0x%X loaded\n",
13979 13977 un->un_mspl->media_type);
13980 13978 wrt = RDWR;
13981 13979 }
13982 13980
13983 13981 return (wrt);
13984 13982 }
13985 13983
13986 13984 #define LTO_REQ_INQUIRY 44
13987 13985 static writablity
13988 13986 st_is_hp_lto_worm(struct scsi_tape *un)
13989 13987 {
13990 13988 char *buf;
13991 13989 int result;
13992 13990 writablity wrt;
13993 13991
13994 13992 ST_FUNC(ST_DEVINFO, st_is_hp_lto_worm);
13995 13993
13996 13994 buf = kmem_zalloc(LTO_REQ_INQUIRY, KM_SLEEP);
13997 13995
13998 13996 result = st_get_special_inquiry(un, LTO_REQ_INQUIRY, buf, 0);
13999 13997
14000 13998 if (result != 0) {
14001 13999 ST_DEBUG2(ST_DEVINFO, st_label, SCSI_DEBUG,
14002 14000 "Read Standard Inquiry for WORM support failed");
14003 14001 wrt = FAILED;
14004 14002 } else if ((buf[40] & 1) == 0) {
14005 14003 ST_DEBUG2(ST_DEVINFO, st_label, SCSI_DEBUG,
14006 14004 "Drive is NOT WORMable\n");
14007 14005 /* This drive doesn't support it so don't check again */
14008 14006 un->un_dp->options &= ~ST_WORMABLE;
14009 14007 wrt = RDWR;
14010 14008 un->un_wormable = st_is_not_wormable;
14011 14009 } else {
14012 14010 ST_DEBUG2(ST_DEVINFO, st_label, SCSI_DEBUG,
14013 14011 "Drive supports WORM version %d\n", buf[40] >> 1);
14014 14012 un->un_wormable = st_is_hp_lto_tape_worm;
14015 14013 wrt = un->un_wormable(un);
14016 14014 }
14017 14015
14018 14016 kmem_free(buf, LTO_REQ_INQUIRY);
14019 14017
14020 14018 /*
14021 14019 * If drive doesn't support it no point in checking further.
14022 14020 */
14023 14021 return (wrt);
14024 14022 }
14025 14023
14026 14024 static writablity
14027 14025 st_is_t10_worm_device(struct scsi_tape *un)
14028 14026 {
14029 14027 writablity wrt;
14030 14028
14031 14029 ST_FUNC(ST_DEVINFO, st_is_t10_worm_device);
14032 14030
14033 14031 if (un->un_mspl->media_type == 0x3c) {
14034 14032 ST_DEBUG2(ST_DEVINFO, st_label, SCSI_DEBUG,
14035 14033 "Drive has WORM media loaded\n");
14036 14034 wrt = WORM;
14037 14035 } else {
14038 14036 ST_DEBUG2(ST_DEVINFO, st_label, SCSI_DEBUG,
14039 14037 "Drive has non WORM media loaded\n");
14040 14038 wrt = RDWR;
14041 14039 }
14042 14040 return (wrt);
14043 14041 }
14044 14042
14045 14043 #define SEQ_CAP_PAGE (char)0xb0
14046 14044 static writablity
14047 14045 st_is_t10_worm(struct scsi_tape *un)
14048 14046 {
14049 14047 char *buf;
14050 14048 int result;
14051 14049 writablity wrt;
14052 14050
14053 14051 ST_FUNC(ST_DEVINFO, st_is_t10_worm);
14054 14052
14055 14053 buf = kmem_zalloc(6, KM_SLEEP);
14056 14054
14057 14055 result = st_get_special_inquiry(un, 6, buf, SEQ_CAP_PAGE);
14058 14056
14059 14057 if (result != 0) {
14060 14058 ST_DEBUG2(ST_DEVINFO, st_label, SCSI_DEBUG,
14061 14059 "Read Vitial Inquiry for Sequental Capability"
14062 14060 " WORM support failed %x", result);
14063 14061 wrt = FAILED;
14064 14062 } else if ((buf[4] & 1) == 0) {
14065 14063 ASSERT(buf[1] == SEQ_CAP_PAGE);
14066 14064 ST_DEBUG2(ST_DEVINFO, st_label, SCSI_DEBUG,
14067 14065 "Drive is NOT WORMable\n");
14068 14066 /* This drive doesn't support it so don't check again */
14069 14067 un->un_dp->options &= ~ST_WORMABLE;
14070 14068 wrt = RDWR;
14071 14069 un->un_wormable = st_is_not_wormable;
14072 14070 } else {
14073 14071 ST_DEBUG2(ST_DEVINFO, st_label, SCSI_DEBUG,
14074 14072 "Drive supports WORM\n");
14075 14073 un->un_wormable = st_is_t10_worm_device;
14076 14074 wrt = un->un_wormable(un);
14077 14075 }
14078 14076
14079 14077 kmem_free(buf, 6);
14080 14078
14081 14079 return (wrt);
14082 14080 }
14083 14081
14084 14082
14085 14083 #define STK_REQ_SENSE 26
14086 14084
14087 14085 static writablity
14088 14086 st_is_stk_worm(struct scsi_tape *un)
14089 14087 {
14090 14088 char cdb[CDB_GROUP0] = {SCMD_REQUEST_SENSE, 0, 0, 0, STK_REQ_SENSE, 0};
14091 14089 struct scsi_extended_sense *sense;
14092 14090 struct uscsi_cmd *cmd;
14093 14091 char *buf;
14094 14092 int result;
14095 14093 writablity wrt;
14096 14094
14097 14095 ST_FUNC(ST_DEVINFO, st_is_stk_worm);
14098 14096
14099 14097 cmd = kmem_zalloc(sizeof (struct uscsi_cmd), KM_SLEEP);
14100 14098 buf = kmem_alloc(STK_REQ_SENSE, KM_SLEEP);
14101 14099 sense = (struct scsi_extended_sense *)buf;
14102 14100
14103 14101 cmd->uscsi_flags = USCSI_READ;
14104 14102 cmd->uscsi_timeout = un->un_dp->non_motion_timeout;
14105 14103 cmd->uscsi_cdb = &cdb[0];
14106 14104 cmd->uscsi_bufaddr = buf;
14107 14105 cmd->uscsi_buflen = STK_REQ_SENSE;
14108 14106 cmd->uscsi_cdblen = CDB_GROUP0;
14109 14107 cmd->uscsi_rqlen = 0;
14110 14108 cmd->uscsi_rqbuf = NULL;
14111 14109
14112 14110 result = st_uscsi_cmd(un, cmd, FKIOCTL);
14113 14111
14114 14112 if (result != 0 || cmd->uscsi_status != 0) {
14115 14113 ST_DEBUG2(ST_DEVINFO, st_label, SCSI_DEBUG,
14116 14114 "Request Sense for WORM failed");
14117 14115 wrt = RDWR;
14118 14116 } else if (sense->es_add_len + 8 < 24) {
14119 14117 ST_DEBUG2(ST_DEVINFO, st_label, SCSI_DEBUG,
14120 14118 "Drive didn't send enough sense data for WORM byte %d\n",
14121 14119 sense->es_add_len + 8);
14122 14120 wrt = RDWR;
14123 14121 un->un_wormable = st_is_not_wormable;
14124 14122 } else if ((buf[24]) & 0x02) {
14125 14123 ST_DEBUG2(ST_DEVINFO, st_label, SCSI_DEBUG,
14126 14124 "Drive has WORM tape loaded\n");
14127 14125 wrt = WORM;
14128 14126 un->un_wormable = st_is_stk_worm;
14129 14127 } else {
14130 14128 ST_DEBUG2(ST_DEVINFO, st_label, SCSI_DEBUG,
14131 14129 "Drive has normal tape loaded\n");
14132 14130 wrt = RDWR;
14133 14131 un->un_wormable = st_is_stk_worm;
14134 14132 }
14135 14133
14136 14134 kmem_free(buf, STK_REQ_SENSE);
14137 14135 kmem_free(cmd, sizeof (struct uscsi_cmd));
14138 14136 return (wrt);
14139 14137 }
14140 14138
14141 14139 #define DLT_INQ_SZ 44
14142 14140
14143 14141 static writablity
14144 14142 st_is_dlt_tape_worm(struct scsi_tape *un)
14145 14143 {
14146 14144 caddr_t buf;
14147 14145 int result;
14148 14146 writablity wrt;
14149 14147
14150 14148 ST_FUNC(ST_DEVINFO, st_is_dlt_tape_worm);
14151 14149
14152 14150 buf = kmem_alloc(DLT_INQ_SZ, KM_SLEEP);
14153 14151
14154 14152 /* Read Attribute Media Type */
14155 14153
14156 14154 result = st_read_attributes(un, 0x0408, buf, 10, st_uscsi_cmd);
14157 14155
14158 14156 /*
14159 14157 * If this quantum drive is attached via an HBA that cannot
14160 14158 * support thr read attributes command return error in the
14161 14159 * hope that someday they will support the t10 method.
14162 14160 */
14163 14161 if (result == EINVAL && un->un_max_cdb_sz < CDB_GROUP4) {
14164 14162 scsi_log(ST_DEVINFO, st_label, SCSI_DEBUG,
14165 14163 "Read Attribute Command for WORM Media detection is not "
14166 14164 "supported on the HBA that this drive is attached to.");
14167 14165 wrt = RDWR;
14168 14166 un->un_wormable = st_is_not_wormable;
14169 14167 goto out;
14170 14168 }
14171 14169
14172 14170 if (result != 0) {
14173 14171 ST_DEBUG2(ST_DEVINFO, st_label, SCSI_DEBUG,
14174 14172 "Read Attribute Command for WORM Media returned 0x%x",
14175 14173 result);
14176 14174 wrt = RDWR;
14177 14175 un->un_dp->options &= ~ST_WORMABLE;
14178 14176 goto out;
14179 14177 }
14180 14178
14181 14179 if ((uchar_t)buf[9] == 0x80) {
14182 14180 ST_DEBUG2(ST_DEVINFO, st_label, SCSI_DEBUG,
14183 14181 "Drive media is WORM\n");
14184 14182 wrt = WORM;
14185 14183 } else {
14186 14184 ST_DEBUG2(ST_DEVINFO, st_label, SCSI_DEBUG,
14187 14185 "Drive media is not WORM Media 0x%x\n", (uchar_t)buf[9]);
14188 14186 wrt = RDWR;
14189 14187 }
14190 14188
14191 14189 out:
14192 14190 kmem_free(buf, DLT_INQ_SZ);
14193 14191 return (wrt);
14194 14192 }
14195 14193
14196 14194 static writablity
14197 14195 st_is_dlt_worm(struct scsi_tape *un)
14198 14196 {
14199 14197 caddr_t buf;
14200 14198 int result;
14201 14199 writablity wrt;
14202 14200
14203 14201 ST_FUNC(ST_DEVINFO, st_is_dlt_worm);
14204 14202
14205 14203 buf = kmem_alloc(DLT_INQ_SZ, KM_SLEEP);
14206 14204
14207 14205 result = st_get_special_inquiry(un, DLT_INQ_SZ, buf, 0xC0);
14208 14206
14209 14207 if (result != 0) {
14210 14208 ST_DEBUG2(ST_DEVINFO, st_label, SCSI_DEBUG,
14211 14209 "Read Vendor Specific Inquiry for WORM support failed");
14212 14210 wrt = RDWR;
14213 14211 goto out;
14214 14212 }
14215 14213
14216 14214 if ((buf[2] & 1) == 0) {
14217 14215 ST_DEBUG2(ST_DEVINFO, st_label, SCSI_DEBUG,
14218 14216 "Drive is not WORMable\n");
14219 14217 wrt = RDWR;
14220 14218 un->un_dp->options &= ~ST_WORMABLE;
14221 14219 un->un_wormable = st_is_not_wormable;
14222 14220 goto out;
14223 14221 } else {
14224 14222 ST_DEBUG2(ST_DEVINFO, st_label, SCSI_DEBUG,
14225 14223 "Drive is WORMable\n");
14226 14224 un->un_wormable = st_is_dlt_tape_worm;
14227 14225 wrt = un->un_wormable(un);
14228 14226 }
14229 14227 out:
14230 14228 kmem_free(buf, DLT_INQ_SZ);
14231 14229
14232 14230 return (wrt);
14233 14231 }
14234 14232
14235 14233 typedef struct {
14236 14234 struct modeheader_seq header;
14237 14235 #if defined(_BIT_FIELDS_LTOH) /* X86 */
14238 14236 uchar_t pagecode :6,
14239 14237 :2;
14240 14238 uchar_t page_len;
14241 14239 uchar_t syslogalive :2,
14242 14240 device :1,
14243 14241 abs :1,
14244 14242 ulpbot :1,
14245 14243 prth :1,
14246 14244 ponej :1,
14247 14245 ait :1;
14248 14246 uchar_t span;
14249 14247
14250 14248 uchar_t :6,
14251 14249 worm :1,
14252 14250 mic :1;
14253 14251 uchar_t worm_cap :1,
14254 14252 :7;
14255 14253 uint32_t :32;
14256 14254 #else /* SPARC */
14257 14255 uchar_t :2,
14258 14256 pagecode :6;
14259 14257 uchar_t page_len;
14260 14258 uchar_t ait :1,
14261 14259 device :1,
14262 14260 abs :1,
14263 14261 ulpbot :1,
14264 14262 prth :1,
14265 14263 ponej :1,
14266 14264 syslogalive :2;
14267 14265 uchar_t span;
14268 14266 uchar_t mic :1,
14269 14267 worm :1,
14270 14268 :6;
14271 14269 uchar_t :7,
14272 14270 worm_cap :1;
14273 14271 uint32_t :32;
14274 14272 #endif
14275 14273 }ait_dev_con;
14276 14274
14277 14275 #define AIT_DEV_PAGE 0x31
14278 14276 static writablity
14279 14277 st_is_sony_worm(struct scsi_tape *un)
14280 14278 {
14281 14279 int result;
14282 14280 writablity wrt;
14283 14281 ait_dev_con *ait_conf;
14284 14282
14285 14283 ST_FUNC(ST_DEVINFO, st_is_sony_worm);
14286 14284
14287 14285 ait_conf = kmem_zalloc(sizeof (ait_dev_con), KM_SLEEP);
14288 14286
14289 14287 result = st_gen_mode_sense(un, st_uscsi_cmd, AIT_DEV_PAGE,
14290 14288 (struct seq_mode *)ait_conf, sizeof (ait_dev_con));
14291 14289
14292 14290 if (result == 0) {
14293 14291
14294 14292 if (ait_conf->pagecode != AIT_DEV_PAGE) {
14295 14293 ST_DEBUG2(ST_DEVINFO, st_label, SCSI_DEBUG,
14296 14294 "returned page 0x%x not 0x%x AIT_DEV_PAGE\n",
14297 14295 ait_conf->pagecode, AIT_DEV_PAGE);
14298 14296 wrt = RDWR;
14299 14297 un->un_wormable = st_is_not_wormable;
14300 14298
14301 14299 } else if (ait_conf->worm_cap) {
14302 14300
14303 14301 un->un_wormable = st_is_sony_worm;
14304 14302
14305 14303 ST_DEBUG2(ST_DEVINFO, st_label, SCSI_DEBUG,
14306 14304 "Drives is WORMable\n");
14307 14305 if (ait_conf->worm) {
14308 14306 ST_DEBUG2(ST_DEVINFO, st_label, SCSI_DEBUG,
14309 14307 "Media is WORM\n");
14310 14308 wrt = WORM;
14311 14309 } else {
14312 14310 ST_DEBUG2(ST_DEVINFO, st_label, SCSI_DEBUG,
14313 14311 "Media is not WORM\n");
14314 14312 wrt = RDWR;
14315 14313 }
14316 14314
14317 14315 } else {
14318 14316 ST_DEBUG2(ST_DEVINFO, st_label, SCSI_DEBUG,
14319 14317 "Drives not is WORMable\n");
14320 14318 wrt = RDWR;
14321 14319 /* No further checking required */
14322 14320 un->un_dp->options &= ~ST_WORMABLE;
14323 14321 }
14324 14322
14325 14323 } else {
14326 14324
14327 14325 ST_DEBUG2(ST_DEVINFO, st_label, SCSI_DEBUG,
14328 14326 "AIT device config mode sense page read command failed"
14329 14327 " result = %d ", result);
14330 14328 wrt = FAILED;
14331 14329 un->un_wormable = st_is_not_wormable;
14332 14330 }
14333 14331
14334 14332 kmem_free(ait_conf, sizeof (ait_dev_con));
14335 14333 return (wrt);
14336 14334 }
14337 14335
14338 14336 static writablity
14339 14337 st_is_drive_worm(struct scsi_tape *un)
14340 14338 {
14341 14339 writablity wrt;
14342 14340
14343 14341 ST_FUNC(ST_DEVINFO, st_is_sony_worm);
14344 14342
14345 14343 switch (un->un_dp->type) {
14346 14344 case MT_ISDLT:
14347 14345 wrt = st_is_dlt_worm(un);
14348 14346 break;
14349 14347
14350 14348 case MT_ISSTK9840:
14351 14349 wrt = st_is_stk_worm(un);
14352 14350 break;
14353 14351
14354 14352 case MT_IS8MM:
14355 14353 case MT_ISAIT:
14356 14354 wrt = st_is_sony_worm(un);
14357 14355 break;
14358 14356
14359 14357 case MT_LTO:
14360 14358 if (strncmp("HP ", un->un_dp->vid, 3) == 0) {
14361 14359 wrt = st_is_hp_lto_worm(un);
14362 14360 } else {
14363 14361 wrt = st_is_t10_worm(un);
14364 14362 }
14365 14363 break;
14366 14364
14367 14365 case MT_ISDAT:
14368 14366 if (strncmp("HP ", un->un_dp->vid, 3) == 0) {
14369 14367 wrt = st_is_hp_dat_worm(un);
14370 14368 } else {
14371 14369 wrt = st_is_t10_worm(un);
14372 14370 }
14373 14371 break;
14374 14372
14375 14373 default:
14376 14374 wrt = FAILED;
14377 14375 break;
14378 14376 }
14379 14377
14380 14378 /*
14381 14379 * If any of the above failed try the t10 standard method.
14382 14380 */
14383 14381 if (wrt == FAILED) {
14384 14382 wrt = st_is_t10_worm(un);
14385 14383 }
14386 14384
14387 14385 /*
14388 14386 * Unknown method for detecting WORM media.
14389 14387 */
14390 14388 if (wrt == FAILED) {
14391 14389 ST_DEBUG2(ST_DEVINFO, st_label, SCSI_DEBUG,
14392 14390 "Unknown method for WORM media detection\n");
14393 14391 wrt = RDWR;
14394 14392 un->un_dp->options &= ~ST_WORMABLE;
14395 14393 }
14396 14394
14397 14395 return (wrt);
14398 14396 }
14399 14397
14400 14398 static int
14401 14399 st_read_attributes(struct scsi_tape *un, uint16_t attribute, void *pnt,
14402 14400 size_t size, ubufunc_t bufunc)
14403 14401 {
14404 14402 char cdb[CDB_GROUP4];
14405 14403 int result;
14406 14404 struct uscsi_cmd *cmd;
14407 14405 struct scsi_arq_status status;
14408 14406
14409 14407 caddr_t buf = (caddr_t)pnt;
14410 14408
14411 14409 ST_FUNC(ST_DEVINFO, st_read_attributes);
14412 14410
14413 14411 if (un->un_sd->sd_inq->inq_ansi < 3) {
14414 14412 return (ENOTTY);
14415 14413 }
14416 14414
14417 14415 cmd = kmem_zalloc(sizeof (struct uscsi_cmd), KM_SLEEP);
14418 14416
14419 14417 cdb[0] = (char)SCMD_READ_ATTRIBUTE;
14420 14418 cdb[1] = 0;
14421 14419 cdb[2] = 0;
14422 14420 cdb[3] = 0;
14423 14421 cdb[4] = 0;
14424 14422 cdb[5] = 0;
14425 14423 cdb[6] = 0;
14426 14424 cdb[7] = 0;
14427 14425 cdb[8] = (char)(attribute >> 8);
14428 14426 cdb[9] = (char)(attribute);
14429 14427 cdb[10] = (char)(size >> 24);
14430 14428 cdb[11] = (char)(size >> 16);
14431 14429 cdb[12] = (char)(size >> 8);
14432 14430 cdb[13] = (char)(size);
14433 14431 cdb[14] = 0;
14434 14432 cdb[15] = 0;
14435 14433
14436 14434
14437 14435 cmd->uscsi_flags = USCSI_READ | USCSI_RQENABLE | USCSI_DIAGNOSE;
14438 14436 cmd->uscsi_timeout = un->un_dp->non_motion_timeout;
14439 14437 cmd->uscsi_cdb = &cdb[0];
14440 14438 cmd->uscsi_bufaddr = (caddr_t)buf;
14441 14439 cmd->uscsi_buflen = size;
14442 14440 cmd->uscsi_cdblen = sizeof (cdb);
14443 14441 cmd->uscsi_rqlen = sizeof (status);
14444 14442 cmd->uscsi_rqbuf = (caddr_t)&status;
14445 14443
14446 14444 result = bufunc(un, cmd, FKIOCTL);
14447 14445
14448 14446 if (result != 0 || cmd->uscsi_status != 0) {
14449 14447 ST_DEBUG3(ST_DEVINFO, st_label, SCSI_DEBUG,
14450 14448 "st_read_attribute failed: result %d status %d\n",
14451 14449 result, cmd->uscsi_status);
14452 14450 /*
14453 14451 * If this returns invalid operation code don't try again.
14454 14452 */
14455 14453 if (un->un_sd->sd_sense->es_key == KEY_ILLEGAL_REQUEST &&
14456 14454 un->un_sd->sd_sense->es_add_code == 0x20) {
14457 14455 result = ENOTTY;
14458 14456 } else if (result == 0) {
14459 14457 result = EIO;
14460 14458 }
14461 14459
14462 14460 } else {
14463 14461
14464 14462 /*
14465 14463 * The attribute retured should match the attribute requested.
14466 14464 */
14467 14465 if (buf[4] != cdb[8] || buf[5] != cdb[9]) {
14468 14466 scsi_log(ST_DEVINFO, st_label, SCSI_DEBUG,
14469 14467 "st_read_attribute got wrong data back expected "
14470 14468 "0x%x got 0x%x\n", attribute, buf[6] << 8 | buf[7]);
14471 14469 st_clean_print(ST_DEVINFO, st_label, SCSI_DEBUG,
14472 14470 "bad? data", buf, size);
14473 14471 result = EIO;
14474 14472 }
14475 14473 }
14476 14474
14477 14475 kmem_free(cmd, sizeof (struct uscsi_cmd));
14478 14476
14479 14477 return (result);
14480 14478 }
14481 14479
14482 14480 static int
14483 14481 st_get_special_inquiry(struct scsi_tape *un, uchar_t size, caddr_t dest,
14484 14482 uchar_t page)
14485 14483 {
14486 14484 char cdb[CDB_GROUP0];
14487 14485 struct scsi_extended_sense *sense;
14488 14486 struct uscsi_cmd *cmd;
14489 14487 int result;
14490 14488
14491 14489 ST_FUNC(ST_DEVINFO, st_get_special_inquiry);
14492 14490
14493 14491 cdb[0] = SCMD_INQUIRY;
14494 14492 cdb[1] = page ? 1 : 0;
14495 14493 cdb[2] = page;
14496 14494 cdb[3] = 0;
14497 14495 cdb[4] = size;
14498 14496 cdb[5] = 0;
14499 14497
14500 14498 cmd = kmem_zalloc(sizeof (struct uscsi_cmd), KM_SLEEP);
14501 14499 sense = kmem_alloc(sizeof (struct scsi_extended_sense), KM_SLEEP);
14502 14500
14503 14501 cmd->uscsi_flags = USCSI_READ | USCSI_RQENABLE;
14504 14502 cmd->uscsi_timeout = un->un_dp->non_motion_timeout;
14505 14503 cmd->uscsi_cdb = &cdb[0];
14506 14504 cmd->uscsi_bufaddr = dest;
14507 14505 cmd->uscsi_buflen = size;
14508 14506 cmd->uscsi_cdblen = CDB_GROUP0;
14509 14507 cmd->uscsi_rqlen = sizeof (struct scsi_extended_sense);
14510 14508 cmd->uscsi_rqbuf = (caddr_t)sense;
14511 14509
14512 14510 result = st_uscsi_cmd(un, cmd, FKIOCTL);
14513 14511
14514 14512 if (result != 0 || cmd->uscsi_status != 0) {
14515 14513 ST_DEBUG2(ST_DEVINFO, st_label, SCSI_DEBUG,
14516 14514 "st_get_special_inquiry() failed for page %x", page);
14517 14515 if (result == 0) {
14518 14516 result = EIO;
14519 14517 }
14520 14518 }
14521 14519
14522 14520 kmem_free(sense, sizeof (struct scsi_extended_sense));
14523 14521 kmem_free(cmd, sizeof (struct uscsi_cmd));
14524 14522
14525 14523 return (result);
14526 14524 }
14527 14525
14528 14526
14529 14527 static int
14530 14528 st_update_block_pos(struct scsi_tape *un, bufunc_t bf, int post_space)
14531 14529 {
14532 14530 int rval = ENOTTY;
14533 14531 uchar_t status = un->un_status;
14534 14532 posmode previous_pmode = un->un_running.pmode;
14535 14533
14536 14534 ST_FUNC(ST_DEVINFO, st_update_block_pos);
14537 14535
14538 14536 while (un->un_read_pos_type != NO_POS) {
14539 14537 rval = bf(un, SCMD_READ_POSITION, 32, SYNC_CMD);
14540 14538
14541 14539 /*
14542 14540 * If read position command returned good status
14543 14541 * Parse the data to see if the position can be interpreted.
14544 14542 */
14545 14543 if ((rval == 0) &&
14546 14544 ((rval = st_interpret_read_pos(un, &un->un_pos,
14547 14545 un->un_read_pos_type, 32, (caddr_t)un->un_read_pos_data,
14548 14546 post_space)) == 0)) {
14549 14547 /*
14550 14548 * Update the running position as well if un_pos was
14551 14549 * ok. But only if recovery is enabled.
14552 14550 */
14553 14551 if (st_recov_sz != sizeof (recov_info)) {
14554 14552 break;
14555 14553 }
14556 14554 rval = st_interpret_read_pos(un, &un->un_running,
14557 14555 un->un_read_pos_type, 32,
14558 14556 (caddr_t)un->un_read_pos_data, post_space);
14559 14557 un->un_status = status;
14560 14558 break;
14561 14559 } else if (un->un_status == KEY_UNIT_ATTENTION) {
14562 14560 un->un_running.pmode = previous_pmode;
14563 14561 continue;
14564 14562 } else if (un->un_status != KEY_ILLEGAL_REQUEST) {
14565 14563 scsi_log(ST_DEVINFO, st_label, CE_NOTE,
14566 14564 "st_update_block_pos() read position cmd 0x%x"
14567 14565 " returned 0x%x un_status = %d",
14568 14566 un->un_read_pos_type, rval, un->un_status);
14569 14567 /* ENOTTY means it read garbage. try something else. */
14570 14568 if (rval == ENOTTY) {
14571 14569 rval = EIO; /* so ENOTTY is not final rval */
14572 14570 } else {
14573 14571 break;
14574 14572 }
14575 14573 } else {
14576 14574 ST_DEBUG4(ST_DEVINFO, st_label, CE_NOTE,
14577 14575 "st_update_block_pos() read position cmd %x"
14578 14576 " returned %x", un->un_read_pos_type, rval);
14579 14577 un->un_running.pmode = previous_pmode;
14580 14578 }
14581 14579
14582 14580 switch (un->un_read_pos_type) {
14583 14581 case SHORT_POS:
14584 14582 un->un_read_pos_type = NO_POS;
14585 14583 break;
14586 14584
14587 14585 case LONG_POS:
14588 14586 un->un_read_pos_type = EXT_POS;
14589 14587 break;
14590 14588
14591 14589 case EXT_POS:
14592 14590 un->un_read_pos_type = SHORT_POS;
14593 14591 break;
14594 14592
14595 14593 default:
14596 14594 ST_DEBUG(ST_DEVINFO, st_label, CE_PANIC,
14597 14595 "Unexpected read position type 0x%x",
14598 14596 un->un_read_pos_type);
14599 14597 }
14600 14598 un->un_status = KEY_NO_SENSE;
14601 14599 }
14602 14600
14603 14601 return (rval);
14604 14602 }
14605 14603
14606 14604 static int
14607 14605 st_get_read_pos(struct scsi_tape *un, buf_t *bp)
14608 14606 {
14609 14607 int result;
14610 14608 size_t d_sz;
14611 14609 caddr_t pos_info;
14612 14610 struct uscsi_cmd *cmd = (struct uscsi_cmd *)bp->b_back;
14613 14611
14614 14612 ST_FUNC(ST_DEVINFO, st_get_read_pos);
14615 14613
14616 14614 if (cmd->uscsi_bufaddr == NULL || cmd->uscsi_buflen <= 0) {
14617 14615 return (0);
14618 14616 }
14619 14617
14620 14618 if (bp_mapin_common(bp, VM_NOSLEEP) == NULL) {
14621 14619
14622 14620 scsi_log(ST_DEVINFO, st_label, SCSI_DEBUG,
14623 14621 "bp_mapin_common() failed");
14624 14622
14625 14623 return (EIO);
14626 14624 }
14627 14625
14628 14626 d_sz = bp->b_bcount - bp->b_resid;
14629 14627 if (d_sz == 0) {
14630 14628 bp_mapout(bp);
14631 14629 return (EIO);
14632 14630 }
14633 14631
14634 14632 /*
14635 14633 * Copy the buf to a double-word aligned memory that can hold the
14636 14634 * tape_position_t data structure.
14637 14635 */
14638 14636 if ((pos_info = kmem_alloc(d_sz, KM_NOSLEEP)) == NULL) {
14639 14637 scsi_log(ST_DEVINFO, st_label, SCSI_DEBUG,
14640 14638 "kmem_alloc() failed");
14641 14639 bp_mapout(bp);
14642 14640 return (EIO);
14643 14641 }
14644 14642 bcopy(bp->b_un.b_addr, pos_info, d_sz);
14645 14643
14646 14644 #ifdef STDEBUG
14647 14645 if ((st_debug & 0x7) > 2) {
14648 14646 st_clean_print(ST_DEVINFO, st_label, SCSI_DEBUG,
14649 14647 "st_get_read_pos() position info",
14650 14648 pos_info, bp->b_bcount);
14651 14649 }
14652 14650 #endif
14653 14651
14654 14652 result = st_interpret_read_pos(un, &un->un_pos, cmd->uscsi_cdb[1],
14655 14653 d_sz, pos_info, 0);
14656 14654
14657 14655 COPY_POS(&un->un_running, &un->un_pos);
14658 14656
14659 14657 kmem_free(pos_info, d_sz);
14660 14658 bp_mapout(bp);
14661 14659
14662 14660 return (result);
14663 14661 }
14664 14662
14665 14663 #if defined(_BIG_ENDIAN)
14666 14664
14667 14665 #define FIX_ENDIAN16(x)
14668 14666 #define FIX_ENDIAN32(x)
14669 14667 #define FIX_ENDIAN64(x)
14670 14668
14671 14669 #elif defined(_LITTLE_ENDIAN)
14672 14670
14673 14671 static void
14674 14672 st_swap16(uint16_t *val)
14675 14673 {
14676 14674 uint16_t tmp;
14677 14675
14678 14676 tmp = (*val >> 8) & 0xff;
14679 14677 tmp |= (*val << 8) & 0xff00;
14680 14678
14681 14679 *val = tmp;
14682 14680 }
14683 14681
14684 14682 static void
14685 14683 st_swap32(uint32_t *val)
14686 14684 {
14687 14685 uint32_t tmp;
14688 14686
14689 14687 tmp = (*val >> 24) & 0xff;
14690 14688 tmp |= (*val >> 8) & 0xff00;
14691 14689 tmp |= (*val << 8) & 0xff0000;
14692 14690 tmp |= (*val << 24) & 0xff000000;
14693 14691
14694 14692 *val = tmp;
14695 14693 }
14696 14694
14697 14695 static void
14698 14696 st_swap64(uint64_t *val)
14699 14697 {
14700 14698 uint32_t low;
14701 14699 uint32_t high;
14702 14700
14703 14701 low = (uint32_t)(*val);
14704 14702 high = (uint32_t)(*val >> 32);
14705 14703
14706 14704 st_swap32(&low);
14707 14705 st_swap32(&high);
14708 14706
14709 14707 *val = high;
14710 14708 *val |= ((uint64_t)low << 32);
14711 14709 }
14712 14710
14713 14711 #define FIX_ENDIAN16(x) st_swap16(x)
14714 14712 #define FIX_ENDIAN32(x) st_swap32(x)
14715 14713 #define FIX_ENDIAN64(x) st_swap64(x)
14716 14714 #endif
14717 14715
14718 14716 /*
14719 14717 * st_interpret_read_pos()
14720 14718 *
14721 14719 * Returns:
14722 14720 * 0 If secsessful.
14723 14721 * EIO If read postion responce data was unuseable or invalid.
14724 14722 * ERANGE If the position of the drive is too large for the read_p_type.
14725 14723 * ENOTTY If the responce data looks invalid for the read position type.
14726 14724 */
14727 14725
14728 14726 static int
14729 14727 st_interpret_read_pos(struct scsi_tape const *un, tapepos_t *dest,
14730 14728 read_p_types type, size_t data_sz, const caddr_t responce, int post_space)
14731 14729 {
14732 14730 int rval = 0;
14733 14731 int flag = 0;
14734 14732 tapepos_t org;
14735 14733
14736 14734 ST_FUNC(ST_DEVINFO, st_interpret_read_pos);
14737 14735
14738 14736 /*
14739 14737 * We expect the position value to change after a space command.
14740 14738 * So if post_space is set we don't print out what has changed.
14741 14739 */
14742 14740 if ((dest != &un->un_pos) && (post_space == 0) &&
14743 14741 (st_recov_sz == sizeof (recov_info))) {
14744 14742 COPY_POS(&org, dest);
14745 14743 flag = 1;
14746 14744 }
14747 14745
14748 14746 /*
14749 14747 * See what kind of read position was requested.
14750 14748 */
14751 14749 switch (type) {
14752 14750
14753 14751 case SHORT_POS: /* Short data format */
14754 14752 {
14755 14753 tape_position_t *pos_info = (tape_position_t *)responce;
14756 14754 uint32_t value;
14757 14755
14758 14756 /* If reserved fields are non zero don't use the data */
14759 14757 if (pos_info->reserved0 || pos_info->reserved1 ||
14760 14758 pos_info->reserved2[0] || pos_info->reserved2[1] ||
14761 14759 pos_info->reserved3) {
14762 14760 ST_DEBUG(ST_DEVINFO, st_label, SCSI_DEBUG,
14763 14761 "Invalid Read Short Position Data returned\n");
14764 14762 rval = EIO;
14765 14763 break;
14766 14764 }
14767 14765 /*
14768 14766 * Position is to large to use this type of read position.
14769 14767 */
14770 14768 if (pos_info->posi_err == 1) {
14771 14769 ST_DEBUG(ST_DEVINFO, st_label, SCSI_DEBUG,
14772 14770 "Drive reported position error\n");
14773 14771 rval = ERANGE;
14774 14772 break;
14775 14773 }
14776 14774 /*
14777 14775 * If your at the begining of partition and end at the same
14778 14776 * time it's very small partition or bad data.
14779 14777 */
14780 14778 if (pos_info->begin_of_part && pos_info->end_of_part) {
14781 14779 ST_DEBUG(ST_DEVINFO, st_label, SCSI_DEBUG,
14782 14780 "SHORT_POS returned begin and end of"
14783 14781 " partition\n");
14784 14782 rval = EIO;
14785 14783 break;
14786 14784 }
14787 14785
14788 14786 if (pos_info->blk_posi_unkwn == 0) {
14789 14787
14790 14788 value = pos_info->host_block;
14791 14789 FIX_ENDIAN32(&value);
14792 14790
14793 14791 /*
14794 14792 * If the tape is rewound the host blcok should be 0.
14795 14793 */
14796 14794 if ((pos_info->begin_of_part == 1) &&
14797 14795 (value != 0)) {
14798 14796 ST_DEBUG(ST_DEVINFO, st_label, SCSI_DEBUG,
14799 14797 "SHORT_POS returned begin of partition"
14800 14798 " but host block was 0x%x\n", value);
14801 14799 rval = EIO;
14802 14800 break;
14803 14801 }
14804 14802
14805 14803 if (dest->lgclblkno != value) {
14806 14804 if (flag)
14807 14805 flag++;
14808 14806 ST_DEBUG(ST_DEVINFO, st_label, SCSI_DEBUG,
14809 14807 "SHORT_POS current logical 0x%"PRIx64" read"
14810 14808 " 0x%x\n", dest->lgclblkno, value);
14811 14809 }
14812 14810
14813 14811 dest->lgclblkno = (uint64_t)value;
14814 14812
14815 14813 /*
14816 14814 * If the begining of partition is true and the
14817 14815 * block number is zero we will beleive that it is
14818 14816 * rewound. Promote the pmode to legacy.
14819 14817 */
14820 14818 if ((pos_info->begin_of_part == 1) &&
14821 14819 (value == 0)) {
14822 14820 dest->blkno = 0;
14823 14821 dest->fileno = 0;
14824 14822 if (dest->pmode != legacy)
14825 14823 dest->pmode = legacy;
14826 14824 /*
14827 14825 * otherwise if the pmode was invalid,
14828 14826 * promote it to logical.
14829 14827 */
14830 14828 } else if (dest->pmode == invalid) {
14831 14829 dest->pmode = logical;
14832 14830 }
14833 14831
14834 14832 if (dest->partition != pos_info->partition_number) {
14835 14833 if (flag)
14836 14834 flag++;
14837 14835 ST_DEBUG(ST_DEVINFO, st_label, SCSI_DEBUG,
14838 14836 "SHORT_POS current partition %d read %d\n",
14839 14837 dest->partition,
14840 14838 pos_info->partition_number);
14841 14839 }
14842 14840
14843 14841 dest->partition = pos_info->partition_number;
14844 14842
14845 14843 } else {
14846 14844 dest->pmode = invalid;
14847 14845 ST_DEBUG(ST_DEVINFO, st_label, SCSI_DEBUG,
14848 14846 "Tape drive reported block position as unknown\n");
14849 14847 }
14850 14848 break;
14851 14849 }
14852 14850
14853 14851 case LONG_POS: /* Long data format */
14854 14852 {
14855 14853 uint64_t value;
14856 14854 tape_position_long_t *long_pos_info =
14857 14855 (tape_position_long_t *)responce;
14858 14856
14859 14857 /* If reserved fields are non zero don't use the data */
14860 14858 if ((long_pos_info->reserved0) ||
14861 14859 (long_pos_info->reserved1) ||
14862 14860 (long_pos_info->reserved2)) {
14863 14861 ST_DEBUG(ST_DEVINFO, st_label, SCSI_DEBUG,
14864 14862 "Invalid Read Long Position Data returned\n");
14865 14863 rval = ENOTTY;
14866 14864 break;
14867 14865 }
14868 14866
14869 14867 /* Is position Valid */
14870 14868 if (long_pos_info->blk_posi_unkwn == 0) {
14871 14869 uint32_t part;
14872 14870
14873 14871 value = long_pos_info->block_number;
14874 14872 FIX_ENDIAN64(&value);
14875 14873
14876 14874 /*
14877 14875 * If it says we are at the begining of partition
14878 14876 * the block value better be 0.
14879 14877 */
14880 14878 if ((long_pos_info->begin_of_part == 1) &&
14881 14879 (value != 0)) {
14882 14880 ST_DEBUG(ST_DEVINFO, st_label, SCSI_DEBUG,
14883 14881 "LONG_POS returned begin of partition but"
14884 14882 " block number was 0x%"PRIx64"\n", value);
14885 14883 rval = ENOTTY;
14886 14884 break;
14887 14885 }
14888 14886 /*
14889 14887 * Can't be at the start and the end of the partition
14890 14888 * at the same time if the partition is larger the 0.
14891 14889 */
14892 14890 if (long_pos_info->begin_of_part &&
14893 14891 long_pos_info->end_of_part) {
14894 14892 ST_DEBUG(ST_DEVINFO, st_label, SCSI_DEBUG,
14895 14893 "LONG_POS returned begin and end of"
14896 14894 " partition\n");
14897 14895 rval = ENOTTY;
14898 14896 break;
14899 14897 }
14900 14898
14901 14899 /*
14902 14900 * If the logical block number is not what we expected.
14903 14901 */
14904 14902 if (dest->lgclblkno != value) {
14905 14903 if (flag)
14906 14904 flag++;
14907 14905 ST_DEBUG(ST_DEVINFO, st_label, SCSI_DEBUG,
14908 14906 "LONG_POS current logical 0x%"PRIx64
14909 14907 " read 0x%"PRIx64"\n",
14910 14908 dest->lgclblkno, value);
14911 14909 }
14912 14910 dest->lgclblkno = value;
14913 14911
14914 14912 /*
14915 14913 * If the begining of partition is true and the
14916 14914 * block number is zero we will beleive that it is
14917 14915 * rewound. Promote the pmode to legacy.
14918 14916 */
14919 14917 if ((long_pos_info->begin_of_part == 1) &&
14920 14918 (long_pos_info->block_number == 0)) {
14921 14919 dest->blkno = 0;
14922 14920 dest->fileno = 0;
14923 14921 if (dest->pmode != legacy)
14924 14922 dest->pmode = legacy;
14925 14923 /*
14926 14924 * otherwise if the pmode was invalid,
14927 14925 * promote it to logical.
14928 14926 */
14929 14927 } else if (dest->pmode == invalid) {
14930 14928 dest->pmode = logical;
14931 14929 }
14932 14930
14933 14931 part = long_pos_info->partition;
14934 14932 FIX_ENDIAN32(&part);
14935 14933 if (dest->partition != part) {
14936 14934 if (flag)
14937 14935 flag++;
14938 14936 ST_DEBUG(ST_DEVINFO, st_label, SCSI_DEBUG,
14939 14937 "LONG_POS current partition %d"
14940 14938 " read %d\n", dest->partition, part);
14941 14939 }
14942 14940 dest->partition = part;
14943 14941 } else {
14944 14942 /*
14945 14943 * If the drive doesn't know location,
14946 14944 * we don't either.
14947 14945 */
14948 14946 ST_DEBUG(ST_DEVINFO, st_label, SCSI_DEBUG,
14949 14947 "Tape drive reported block position as unknown\n");
14950 14948 dest->pmode = invalid;
14951 14949 }
14952 14950
14953 14951 /* Is file position valid */
14954 14952 if (long_pos_info->mrk_posi_unkwn == 0) {
14955 14953 value = long_pos_info->file_number;
14956 14954 FIX_ENDIAN64(&value);
14957 14955 /*
14958 14956 * If it says we are at the begining of partition
14959 14957 * the block value better be 0.
14960 14958 */
14961 14959 if ((long_pos_info->begin_of_part == 1) &&
14962 14960 (value != 0)) {
14963 14961 ST_DEBUG(ST_DEVINFO, st_label, SCSI_DEBUG,
14964 14962 "LONG_POS returned begin of partition but"
14965 14963 " block number was 0x%"PRIx64"\n", value);
14966 14964 rval = ENOTTY;
14967 14965 break;
14968 14966 }
14969 14967 if (((dest->pmode == legacy) ||
14970 14968 (dest->pmode == logical)) &&
14971 14969 (dest->fileno != value)) {
14972 14970 if (flag)
14973 14971 flag++;
14974 14972 ST_DEBUG(ST_DEVINFO, st_label, SCSI_DEBUG,
14975 14973 "LONG_POS fileno 0x%"PRIx64
14976 14974 " not un_pos %x\n", value,
14977 14975 dest->fileno);
14978 14976 } else if (dest->pmode == invalid) {
14979 14977 dest->pmode = logical;
14980 14978 }
14981 14979 dest->fileno = (int32_t)value;
14982 14980 }
14983 14981
14984 14982 if (dest->pmode != invalid && long_pos_info->end_of_part) {
14985 14983 dest->eof = ST_EOT;
14986 14984 }
14987 14985
14988 14986 break;
14989 14987 }
14990 14988
14991 14989 case EXT_POS: /* Extended data format */
14992 14990 {
14993 14991 uint64_t value;
14994 14992 uint16_t len;
14995 14993 tape_position_ext_t *ext_pos_info =
14996 14994 (tape_position_ext_t *)responce;
14997 14995
14998 14996 /* Make sure that there is enough data there */
14999 14997 if (data_sz < 16) {
15000 14998 break;
15001 14999 }
15002 15000
15003 15001 /* If reserved fields are non zero don't use the data */
15004 15002 if (ext_pos_info->reserved0 || ext_pos_info->reserved1) {
15005 15003 ST_DEBUG(ST_DEVINFO, st_label, SCSI_DEBUG,
15006 15004 "EXT_POS reserved fields not zero\n");
15007 15005 rval = ENOTTY;
15008 15006 break;
15009 15007 }
15010 15008
15011 15009 /*
15012 15010 * In the unlikely event of overflowing 64 bits of position.
15013 15011 */
15014 15012 if (ext_pos_info->posi_err != 0) {
15015 15013 rval = ERANGE;
15016 15014 break;
15017 15015 }
15018 15016
15019 15017 len = ext_pos_info->parameter_len;
15020 15018 FIX_ENDIAN16(&len);
15021 15019
15022 15020 if (len != 0x1c) {
15023 15021 ST_DEBUG(ST_DEVINFO, st_label, SCSI_DEBUG,
15024 15022 "EXT_POS parameter_len should be 0x1c was 0x%x\n",
15025 15023 len);
15026 15024 rval = ENOTTY;
15027 15025 break;
15028 15026 }
15029 15027
15030 15028 /* Is block position information valid */
15031 15029 if (ext_pos_info->blk_posi_unkwn == 0) {
15032 15030
15033 15031 value = ext_pos_info->host_block;
15034 15032 FIX_ENDIAN64(&value);
15035 15033 if ((ext_pos_info->begin_of_part == 1) &&
15036 15034 (value != 0)) {
15037 15035 ST_DEBUG(ST_DEVINFO, st_label, SCSI_DEBUG,
15038 15036 "EXT_POS returned begining of partition but"
15039 15037 " the host block was 0x%"PRIx64"\n", value);
15040 15038 rval = ENOTTY;
15041 15039 break;
15042 15040 }
15043 15041
15044 15042 if (dest->lgclblkno != value) {
15045 15043 if (flag)
15046 15044 flag++;
15047 15045 ST_DEBUG(ST_DEVINFO, st_label, SCSI_DEBUG,
15048 15046 "EXT_POS current logical 0x%"PRIx64
15049 15047 " read 0x%"PRIx64"\n",
15050 15048 dest->lgclblkno, value);
15051 15049 }
15052 15050 dest->lgclblkno = value;
15053 15051
15054 15052 /*
15055 15053 * If the begining of partition is true and the
15056 15054 * block number is zero we will beleive that it is
15057 15055 * rewound. Promote the pmode to legacy.
15058 15056 */
15059 15057 if ((ext_pos_info->begin_of_part == 1) &&
15060 15058 (ext_pos_info->host_block == 0)) {
15061 15059 dest->blkno = 0;
15062 15060 dest->fileno = 0;
15063 15061 if (dest->pmode != legacy) {
15064 15062 dest->pmode = legacy;
15065 15063 }
15066 15064 /*
15067 15065 * otherwise if the pmode was invalid,
15068 15066 * promote it to logical.
15069 15067 */
15070 15068 } else if (dest->pmode == invalid) {
15071 15069 dest->pmode = logical;
15072 15070 }
15073 15071
15074 15072 if (dest->partition != ext_pos_info->partition) {
15075 15073 if (flag)
15076 15074 flag++;
15077 15075 ST_DEBUG(ST_DEVINFO, st_label, SCSI_DEBUG,
15078 15076 "EXT_POS current partition %d read %d\n",
15079 15077 dest->partition,
15080 15078 ext_pos_info->partition);
15081 15079 }
15082 15080 dest->partition = ext_pos_info->partition;
15083 15081
15084 15082 } else {
15085 15083 dest->pmode = invalid;
15086 15084 }
15087 15085 break;
15088 15086 }
15089 15087
15090 15088 default:
15091 15089 ST_DEBUG(ST_DEVINFO, st_label, CE_PANIC,
15092 15090 "Got unexpected SCMD_READ_POSITION type %d\n", type);
15093 15091 rval = EIO;
15094 15092 }
15095 15093
15096 15094 if ((flag > 1) && (rval == 0) && (org.pmode != invalid)) {
15097 15095 st_print_position(ST_DEVINFO, st_label, CE_NOTE,
15098 15096 "position read in", &org);
15099 15097 st_print_position(ST_DEVINFO, st_label, CE_NOTE,
15100 15098 "position read out", dest);
15101 15099 }
15102 15100
15103 15101 return (rval);
15104 15102 }
15105 15103
15106 15104 static int
15107 15105 st_logical_block_locate(struct scsi_tape *un, ubufunc_t ubf, tapepos_t *pos,
15108 15106 uint64_t lblk, uchar_t partition)
15109 15107 {
15110 15108 int rval;
15111 15109 char cdb[CDB_GROUP4];
15112 15110 struct uscsi_cmd *cmd;
15113 15111 struct scsi_extended_sense sense;
15114 15112 bufunc_t bf = (ubf == st_uscsi_cmd) ? st_cmd : st_rcmd;
15115 15113
15116 15114 ST_FUNC(ST_DEVINFO, st_logical_block_locate);
15117 15115 /*
15118 15116 * Not sure what to do when doing recovery and not wanting
15119 15117 * to update un_pos
15120 15118 */
15121 15119
15122 15120 cmd = kmem_zalloc(sizeof (struct uscsi_cmd), KM_SLEEP);
15123 15121
15124 15122 if (lblk <= INT32_MAX) {
15125 15123 cmd->uscsi_cdblen = CDB_GROUP1;
15126 15124 cdb[0] = SCMD_LOCATE;
15127 15125 cdb[1] = pos->partition == partition ? 0 : 2;
15128 15126 cdb[2] = 0;
15129 15127 cdb[3] = (char)(lblk >> 24);
15130 15128 cdb[4] = (char)(lblk >> 16);
15131 15129 cdb[5] = (char)(lblk >> 8);
15132 15130 cdb[6] = (char)(lblk);
15133 15131 cdb[7] = 0;
15134 15132 cdb[8] = partition;
15135 15133 cdb[9] = 0;
15136 15134 } else {
15137 15135 /*
15138 15136 * If the drive doesn't give a 64 bit read position data
15139 15137 * it is unlikely it will accept 64 bit locates.
15140 15138 */
15141 15139 if (un->un_read_pos_type != LONG_POS) {
15142 15140 kmem_free(cmd, sizeof (struct uscsi_cmd));
15143 15141 return (ERANGE);
15144 15142 }
15145 15143 cmd->uscsi_cdblen = CDB_GROUP4;
15146 15144 cdb[0] = (char)SCMD_LOCATE_G4;
15147 15145 cdb[1] = pos->partition == partition ? 0 : 2;
15148 15146 cdb[2] = 0;
15149 15147 cdb[3] = partition;
15150 15148 cdb[4] = (char)(lblk >> 56);
15151 15149 cdb[5] = (char)(lblk >> 48);
15152 15150 cdb[6] = (char)(lblk >> 40);
15153 15151 cdb[7] = (char)(lblk >> 32);
15154 15152 cdb[8] = (char)(lblk >> 24);
15155 15153 cdb[9] = (char)(lblk >> 16);
15156 15154 cdb[10] = (char)(lblk >> 8);
15157 15155 cdb[11] = (char)(lblk);
15158 15156 cdb[12] = 0;
15159 15157 cdb[13] = 0;
15160 15158 cdb[14] = 0;
15161 15159 cdb[15] = 0;
15162 15160 }
15163 15161
15164 15162
15165 15163 cmd->uscsi_flags = USCSI_WRITE | USCSI_DIAGNOSE | USCSI_RQENABLE;
15166 15164 cmd->uscsi_rqbuf = (caddr_t)&sense;
15167 15165 cmd->uscsi_rqlen = sizeof (sense);
15168 15166 cmd->uscsi_timeout = un->un_dp->space_timeout;
15169 15167 cmd->uscsi_cdb = cdb;
15170 15168
15171 15169 rval = ubf(un, cmd, FKIOCTL);
15172 15170
15173 15171 pos->pmode = logical;
15174 15172 pos->eof = ST_NO_EOF;
15175 15173
15176 15174 if (lblk > INT32_MAX) {
15177 15175 /*
15178 15176 * XXX This is a work around till we handle Descriptor format
15179 15177 * sense data. Since we are sending a command where the standard
15180 15178 * sense data can not correctly represent a correct residual in
15181 15179 * 4 bytes.
15182 15180 */
15183 15181 if (un->un_status == KEY_ILLEGAL_REQUEST) {
15184 15182 scsi_log(ST_DEVINFO, st_label, SCSI_DEBUG,
15185 15183 "Big LOCATE ILLEGAL_REQUEST: rval = %d\n", rval);
15186 15184 /* Doesn't like big locate command */
15187 15185 un->un_status = 0;
15188 15186 rval = ERANGE;
15189 15187 } else if ((un->un_pos.pmode == invalid) || (rval != 0)) {
15190 15188 /* Aborted big locate command */
15191 15189 scsi_log(ST_DEVINFO, st_label, SCSI_DEBUG,
15192 15190 "Big LOCATE resulted in invalid pos: rval = %d\n",
15193 15191 rval);
15194 15192 un->un_status = 0;
15195 15193 rval = EIO;
15196 15194 } else if (st_update_block_pos(un, bf, 1)) {
15197 15195 /* read position failed */
15198 15196 scsi_log(ST_DEVINFO, st_label, SCSI_DEBUG,
15199 15197 "Big LOCATE and read pos: rval = %d\n", rval);
15200 15198 rval = EIO;
15201 15199 } else if (lblk > un->un_pos.lgclblkno) {
15202 15200 /* read position worked but position was not expected */
15203 15201 scsi_log(ST_DEVINFO, st_label, SCSI_DEBUG,
15204 15202 "Big LOCATE and recover read less then desired 0x%"
15205 15203 PRIx64"\n", un->un_pos.lgclblkno);
15206 15204 un->un_err_resid = lblk - un->un_pos.lgclblkno;
15207 15205 un->un_status = KEY_BLANK_CHECK;
15208 15206 rval = ESPIPE;
15209 15207 } else if (lblk == un->un_pos.lgclblkno) {
15210 15208 /* read position was what was expected */
15211 15209 scsi_log(ST_DEVINFO, st_label, SCSI_DEBUG,
15212 15210 "Big LOCATE and recover seems to have worked\n");
15213 15211 un->un_err_resid = 0;
15214 15212 rval = 0;
15215 15213 } else {
15216 15214 ST_DEBUG(ST_DEVINFO, st_label, CE_PANIC,
15217 15215 "BIGLOCATE end up going backwards");
15218 15216 un->un_err_resid = lblk;
15219 15217 rval = EIO;
15220 15218 }
15221 15219
15222 15220 } else if (rval == 0) {
15223 15221 /* Worked as requested */
15224 15222 pos->lgclblkno = lblk;
15225 15223
15226 15224 } else if (((cmd->uscsi_status & ST_STATUS_MASK) == STATUS_CHECK) &&
15227 15225 (cmd->uscsi_resid != 0)) {
15228 15226 /* Got part way there but wasn't enough blocks on tape */
15229 15227 pos->lgclblkno = lblk - cmd->uscsi_resid;
15230 15228 un->un_err_resid = cmd->uscsi_resid;
15231 15229 un->un_status = KEY_BLANK_CHECK;
15232 15230 rval = ESPIPE;
15233 15231
15234 15232 } else if (st_update_block_pos(un, bf, 1) == 0) {
15235 15233 /* Got part way there but drive didn't tell what we missed by */
15236 15234 un->un_err_resid = lblk - pos->lgclblkno;
15237 15235 un->un_status = KEY_BLANK_CHECK;
15238 15236 rval = ESPIPE;
15239 15237
15240 15238 } else {
15241 15239 scsi_log(ST_DEVINFO, st_label, SCSI_DEBUG,
15242 15240 "Failed LOCATE and recover pos: rval = %d status = %d\n",
15243 15241 rval, cmd->uscsi_status);
15244 15242 un->un_err_resid = lblk;
15245 15243 un->un_status = KEY_ILLEGAL_REQUEST;
15246 15244 pos->pmode = invalid;
15247 15245 rval = EIO;
15248 15246 }
15249 15247
15250 15248 kmem_free(cmd, sizeof (struct uscsi_cmd));
15251 15249
15252 15250 return (rval);
15253 15251 }
15254 15252
15255 15253 static int
15256 15254 st_mtfsf_ioctl(struct scsi_tape *un, int64_t files)
15257 15255 {
15258 15256 int rval;
15259 15257
15260 15258 ST_FUNC(ST_DEVINFO, st_mtfsf_ioctl);
15261 15259
15262 15260
15263 15261 ST_DEBUG4(ST_DEVINFO, st_label, SCSI_DEBUG,
15264 15262 "st_mtfsf_ioctl: count=%"PRIx64", eof=%x\n", files, un->un_pos.eof);
15265 15263 #if 0
15266 15264 if ((IN_EOF(un->un_pos)) && (files == 1)) {
15267 15265 un->un_pos.fileno++;
15268 15266 un->un_pos.blkno = 0;
15269 15267 return (0);
15270 15268 }
15271 15269 #endif
15272 15270 /* pmode == invalid already handled */
15273 15271 if (un->un_pos.pmode == legacy) {
15274 15272 /*
15275 15273 * forward space over filemark
15276 15274 *
15277 15275 * For ASF we allow a count of 0 on fsf which means
15278 15276 * we just want to go to beginning of current file.
15279 15277 * Equivalent to "nbsf(0)" or "bsf(1) + fsf".
15280 15278 * Allow stepping over double fmk with reel
15281 15279 */
15282 15280 if ((un->un_pos.eof >= ST_EOT) &&
15283 15281 (files > 0) &&
15284 15282 ((un->un_dp->options & ST_REEL) == 0)) {
15285 15283 /* we're at EOM */
15286 15284 un->un_err_resid = files;
15287 15285 un->un_status = KEY_BLANK_CHECK;
15288 15286 ST_DEBUG2(ST_DEVINFO, st_label, SCSI_DEBUG,
15289 15287 "st_mtfsf_ioctl: EIO : MTFSF at EOM");
15290 15288 return (EIO);
15291 15289 }
15292 15290
15293 15291 /*
15294 15292 * physical tape position may not be what we've been
15295 15293 * telling the user; adjust the request accordingly
15296 15294 */
15297 15295 if (IN_EOF(un->un_pos)) {
15298 15296 un->un_pos.fileno++;
15299 15297 un->un_pos.blkno = 0;
15300 15298 /*
15301 15299 * For positive direction case, we're now covered.
15302 15300 * For zero or negative direction, we're covered
15303 15301 * (almost)
15304 15302 */
15305 15303 files--;
15306 15304 }
15307 15305
15308 15306 }
15309 15307
15310 15308 if (st_check_density_or_wfm(un->un_dev, 1, B_READ, STEPBACK)) {
15311 15309 ST_DEBUG2(ST_DEVINFO, st_label, SCSI_DEBUG,
15312 15310 "st_mtfsf_ioctl: EIO : MTFSF density/wfm failed");
15313 15311 return (EIO);
15314 15312 }
15315 15313
15316 15314
15317 15315 /*
15318 15316 * Forward space file marks.
15319 15317 * We leave ourselves at block zero
15320 15318 * of the target file number.
15321 15319 */
15322 15320 if (files < 0) {
15323 15321 rval = st_backward_space_files(un, -files, 0);
15324 15322 } else {
15325 15323 rval = st_forward_space_files(un, files);
15326 15324 }
15327 15325
15328 15326 return (rval);
15329 15327 }
15330 15328
15331 15329 static int
15332 15330 st_forward_space_files(struct scsi_tape *un, int64_t count)
15333 15331 {
15334 15332 int rval;
15335 15333
15336 15334 ST_FUNC(ST_DEVINFO, st_forward_space_files);
15337 15335
15338 15336 ST_DEBUG4(ST_DEVINFO, st_label, SCSI_DEBUG,
15339 15337 "fspace: count=%"PRIx64", eof=%x\n", count, un->un_pos.eof);
15340 15338
15341 15339 ASSERT(count >= 0);
15342 15340 ASSERT(un->un_pos.pmode != invalid);
15343 15341
15344 15342 /*
15345 15343 * A space with a count of zero means take me to the start of file.
15346 15344 */
15347 15345 if (count == 0) {
15348 15346
15349 15347 /* Hay look were already there */
15350 15348 if (un->un_pos.pmode == legacy && un->un_pos.blkno == 0) {
15351 15349 un->un_err_resid = 0;
15352 15350 COPY_POS(&un->un_err_pos, &un->un_pos);
15353 15351 return (0);
15354 15352 }
15355 15353
15356 15354 /*
15357 15355 * Well we are in the first file.
15358 15356 * A rewind will get to the start.
15359 15357 */
15360 15358 if (un->un_pos.pmode == legacy && un->un_pos.fileno == 0) {
15361 15359 rval = st_cmd(un, SCMD_REWIND, 0, SYNC_CMD);
15362 15360
15363 15361 /*
15364 15362 * Can we backspace to get there?
15365 15363 * This should work in logical mode.
15366 15364 */
15367 15365 } else if (un->un_dp->options & ST_BSF) {
15368 15366 rval = st_space_to_begining_of_file(un);
15369 15367
15370 15368 /*
15371 15369 * Can't back space but current file number is known,
15372 15370 * So rewind and space from the begining of the partition.
15373 15371 */
15374 15372 } else if (un->un_pos.pmode == legacy) {
15375 15373 rval = st_scenic_route_to_begining_of_file(un,
15376 15374 un->un_pos.fileno);
15377 15375
15378 15376 /*
15379 15377 * pmode is logical and ST_BSF is not set.
15380 15378 * The LONG_POS read position contains the fileno.
15381 15379 * If the read position works, rewind and space.
15382 15380 */
15383 15381 } else if (un->un_read_pos_type == LONG_POS) {
15384 15382 rval = st_cmd(un, SCMD_READ_POSITION, 0, SYNC_CMD);
15385 15383 if (rval) {
15386 15384 /*
15387 15385 * We didn't get the file position from the
15388 15386 * read position command.
15389 15387 * We are going to trust the drive to backspace
15390 15388 * and then position after the filemark.
15391 15389 */
15392 15390 rval = st_space_to_begining_of_file(un);
15393 15391 }
15394 15392 rval = st_interpret_read_pos(un, &un->un_pos, LONG_POS,
15395 15393 32, (caddr_t)un->un_read_pos_data, 0);
15396 15394 if ((rval) && (un->un_pos.pmode == invalid)) {
15397 15395 rval = st_space_to_begining_of_file(un);
15398 15396 } else {
15399 15397 rval = st_scenic_route_to_begining_of_file(un,
15400 15398 un->un_pos.fileno);
15401 15399 }
15402 15400 } else {
15403 15401 rval = EIO;
15404 15402 }
15405 15403 /*
15406 15404 * If something didn't work we are lost
15407 15405 */
15408 15406 if (rval != 0) {
15409 15407 un->un_pos.pmode = invalid;
15410 15408 ST_DEBUG2(ST_DEVINFO, st_label, SCSI_DEBUG,
15411 15409 "st_mtioctop : EIO : fspace pmode invalid");
15412 15410
15413 15411 rval = EIO;
15414 15412 }
15415 15413
15416 15414 } else {
15417 15415 rval = st_space_fmks(un, count);
15418 15416 }
15419 15417
15420 15418 if (rval != EIO && count < 0) {
15421 15419 /*
15422 15420 * we came here with a count < 0; we now need
15423 15421 * to skip back to end up before the filemark
15424 15422 */
15425 15423 rval = st_backward_space_files(un, 1, 1);
15426 15424 }
15427 15425
15428 15426 return (rval);
15429 15427 }
15430 15428
15431 15429 static int
15432 15430 st_scenic_route_to_begining_of_file(struct scsi_tape *un, int32_t fileno)
15433 15431 {
15434 15432 int rval;
15435 15433
15436 15434 ST_FUNC(ST_DEVINFO, st_scenic_route_to_begining_of_file);
15437 15435
15438 15436 if (st_cmd(un, SCMD_REWIND, 0, SYNC_CMD)) {
15439 15437 rval = EIO;
15440 15438 } else if (st_cmd(un, SCMD_SPACE, Fmk(fileno), SYNC_CMD)) {
15441 15439 rval = EIO;
15442 15440 }
15443 15441
15444 15442 return (rval);
15445 15443 }
15446 15444
15447 15445 static int
15448 15446 st_space_to_begining_of_file(struct scsi_tape *un)
15449 15447 {
15450 15448 int rval;
15451 15449
15452 15450 ST_FUNC(ST_DEVINFO, st_space_to_begining_of_file);
15453 15451
15454 15452 /*
15455 15453 * Back space of the file at the begining of the file.
15456 15454 */
15457 15455 rval = st_cmd(un, SCMD_SPACE, Fmk(-1), SYNC_CMD);
15458 15456 if (rval) {
15459 15457 rval = EIO;
15460 15458 return (rval);
15461 15459 }
15462 15460
15463 15461 /*
15464 15462 * Other interesting answers might be crashed BOT which isn't bad.
15465 15463 */
15466 15464 if (un->un_status == SUN_KEY_BOT) {
15467 15465 return (rval);
15468 15466 }
15469 15467
15470 15468 un->un_running.pmode = invalid;
15471 15469
15472 15470 /*
15473 15471 * Now we are on the BOP side of the filemark. Forward space to
15474 15472 * the EOM side and we are at the begining of the file.
15475 15473 */
15476 15474 rval = st_cmd(un, SCMD_SPACE, Fmk(1), SYNC_CMD);
15477 15475 if (rval) {
15478 15476 rval = EIO;
15479 15477 }
15480 15478
15481 15479 return (rval);
15482 15480 }
15483 15481
15484 15482 static int
15485 15483 st_mtfsr_ioctl(struct scsi_tape *un, int64_t count)
15486 15484 {
15487 15485
15488 15486 ST_FUNC(ST_DEVINFO, st_mtfsr_ioctl);
15489 15487
15490 15488 /*
15491 15489 * forward space to inter-record gap
15492 15490 *
15493 15491 */
15494 15492
15495 15493 ST_DEBUG4(ST_DEVINFO, st_label, SCSI_DEBUG,
15496 15494 "st_ioctl_fsr: count=%"PRIx64", eof=%x\n", count, un->un_pos.eof);
15497 15495
15498 15496 if (un->un_pos.pmode == legacy) {
15499 15497 /*
15500 15498 * If were are at end of tape and count is forward.
15501 15499 * Return blank check.
15502 15500 */
15503 15501 if ((un->un_pos.eof >= ST_EOT) && (count > 0)) {
15504 15502 /* we're at EOM */
15505 15503 un->un_err_resid = count;
15506 15504 un->un_status = KEY_BLANK_CHECK;
15507 15505 ST_DEBUG2(ST_DEVINFO, st_label, SCSI_DEBUG,
15508 15506 "st_mtfsr_ioctl: EIO : MTFSR eof > ST_EOT");
15509 15507 return (EIO);
15510 15508 }
15511 15509
15512 15510 /*
15513 15511 * If count is zero there is nothing to do.
15514 15512 */
15515 15513 if (count == 0) {
15516 15514 un->un_err_pos.fileno = un->un_pos.fileno;
15517 15515 un->un_err_pos.blkno = un->un_pos.blkno;
15518 15516 un->un_err_resid = 0;
15519 15517 if (IN_EOF(un->un_pos) && SVR4_BEHAVIOR) {
15520 15518 un->un_status = SUN_KEY_EOF;
15521 15519 }
15522 15520 return (0);
15523 15521 }
15524 15522
15525 15523 /*
15526 15524 * physical tape position may not be what we've been
15527 15525 * telling the user; adjust the position accordingly
15528 15526 */
15529 15527 if (IN_EOF(un->un_pos)) {
15530 15528 daddr_t blkno = un->un_pos.blkno;
15531 15529 int fileno = un->un_pos.fileno;
15532 15530
15533 15531 optype lastop = un->un_lastop;
15534 15532 if (st_cmd(un, SCMD_SPACE, Fmk(-1), SYNC_CMD)
15535 15533 == -1) {
15536 15534 ST_DEBUG2(ST_DEVINFO, st_label, SCSI_DEBUG,
15537 15535 "st_mtfsr_ioctl:EIO:MTFSR count && IN_EOF");
15538 15536 return (EIO);
15539 15537 }
15540 15538
15541 15539 un->un_pos.blkno = blkno;
15542 15540 un->un_pos.fileno = fileno;
15543 15541 un->un_lastop = lastop;
15544 15542 }
15545 15543 }
15546 15544
15547 15545 if (st_check_density_or_wfm(un->un_dev, 1, B_READ, STEPBACK)) {
15548 15546 ST_DEBUG2(ST_DEVINFO, st_label, SCSI_DEBUG,
15549 15547 "st_mtfsr_ioctl: EIO : MTFSR st_check_den");
15550 15548 return (EIO);
15551 15549 }
15552 15550
15553 15551 return (st_space_records(un, count));
15554 15552 }
15555 15553
15556 15554 static int
15557 15555 st_space_records(struct scsi_tape *un, int64_t count)
15558 15556 {
15559 15557 int64_t dblk;
15560 15558 int rval = 0;
15561 15559
15562 15560 ST_FUNC(ST_DEVINFO, st_space_records);
15563 15561
15564 15562 ST_DEBUG4(ST_DEVINFO, st_label, SCSI_DEBUG,
15565 15563 "st_space_records: count=%"PRIx64", eof=%x\n",
15566 15564 count, un->un_pos.eof);
15567 15565
15568 15566 if (un->un_pos.pmode == logical) {
15569 15567 rval = st_cmd(un, SCMD_SPACE, Blk(count), SYNC_CMD);
15570 15568 if (rval != 0) {
15571 15569 rval = EIO;
15572 15570 }
15573 15571 return (rval);
15574 15572 }
15575 15573
15576 15574 dblk = count + un->un_pos.blkno;
15577 15575
15578 15576 /* Already there */
15579 15577 if (dblk == un->un_pos.blkno) {
15580 15578 un->un_err_resid = 0;
15581 15579 COPY_POS(&un->un_err_pos, &un->un_pos);
15582 15580 return (0);
15583 15581 }
15584 15582
15585 15583 /*
15586 15584 * If the destination block is forward
15587 15585 * or the drive will backspace records.
15588 15586 */
15589 15587 if (un->un_pos.blkno < dblk || (un->un_dp->options & ST_BSR)) {
15590 15588 /*
15591 15589 * If we're spacing forward, or the device can
15592 15590 * backspace records, we can just use the SPACE
15593 15591 * command.
15594 15592 */
15595 15593 dblk -= un->un_pos.blkno;
15596 15594 if (st_cmd(un, SCMD_SPACE, Blk(dblk), SYNC_CMD)) {
15597 15595 ST_DEBUG2(ST_DEVINFO, st_label, SCSI_DEBUG,
15598 15596 "st_space_records:EIO:space_records can't spc");
15599 15597 rval = EIO;
15600 15598 } else if (un->un_pos.eof >= ST_EOF_PENDING) {
15601 15599 /*
15602 15600 * check if we hit BOT/EOT
15603 15601 */
15604 15602 if (dblk < 0 && un->un_pos.eof == ST_EOM) {
15605 15603 un->un_status = SUN_KEY_BOT;
15606 15604 un->un_pos.eof = ST_NO_EOF;
15607 15605 } else if (dblk < 0 &&
15608 15606 un->un_pos.eof == ST_EOF_PENDING) {
15609 15607 int residue = un->un_err_resid;
15610 15608 /*
15611 15609 * we skipped over a filemark
15612 15610 * and need to go forward again
15613 15611 */
15614 15612 if (st_cmd(un, SCMD_SPACE, Fmk(1), SYNC_CMD)) {
15615 15613 ST_DEBUG2(ST_DEVINFO, st_label,
15616 15614 SCSI_DEBUG, "st_space_records: EIO"
15617 15615 " : can't space #2");
15618 15616 rval = EIO;
15619 15617 }
15620 15618 un->un_err_resid = residue;
15621 15619 }
15622 15620 if (rval == 0) {
15623 15621 ST_DEBUG2(ST_DEVINFO, st_label, SCSI_DEBUG,
15624 15622 "st_space_records: EIO : space_rec rval"
15625 15623 " == 0");
15626 15624 rval = EIO;
15627 15625 }
15628 15626 }
15629 15627 } else {
15630 15628 /*
15631 15629 * else we rewind, space forward across filemarks to
15632 15630 * the desired file, and then space records to the
15633 15631 * desired block.
15634 15632 */
15635 15633
15636 15634 int dfile = un->un_pos.fileno; /* save current file */
15637 15635
15638 15636 if (dblk < 0) {
15639 15637 /*
15640 15638 * Wups - we're backing up over a filemark
15641 15639 */
15642 15640 if (un->un_pos.blkno != 0 &&
15643 15641 (st_cmd(un, SCMD_REWIND, 0, SYNC_CMD) ||
15644 15642 st_cmd(un, SCMD_SPACE, Fmk(dfile), SYNC_CMD))) {
15645 15643 un->un_pos.pmode = invalid;
15646 15644 }
15647 15645 un->un_err_resid = -dblk;
15648 15646 if (un->un_pos.fileno == 0 && un->un_pos.blkno == 0) {
15649 15647 un->un_status = SUN_KEY_BOT;
15650 15648 un->un_pos.eof = ST_NO_EOF;
15651 15649 } else if (un->un_pos.fileno > 0) {
15652 15650 un->un_status = SUN_KEY_EOF;
15653 15651 un->un_pos.eof = ST_NO_EOF;
15654 15652 }
15655 15653 COPY_POS(&un->un_err_pos, &un->un_pos);
15656 15654 ST_DEBUG2(ST_DEVINFO, st_label, SCSI_DEBUG,
15657 15655 "st_space_records:EIO:space_records : dblk < 0");
15658 15656 rval = EIO;
15659 15657 } else if (st_cmd(un, SCMD_REWIND, 0, SYNC_CMD) ||
15660 15658 st_cmd(un, SCMD_SPACE, Fmk(dfile), SYNC_CMD) ||
15661 15659 st_cmd(un, SCMD_SPACE, Blk(dblk), SYNC_CMD)) {
15662 15660 ST_DEBUG2(ST_DEVINFO, st_label, SCSI_DEBUG,
15663 15661 "st_space_records: EIO :space_records : rewind "
15664 15662 "and space failed");
15665 15663 un->un_pos.pmode = invalid;
15666 15664 rval = EIO;
15667 15665 }
15668 15666 }
15669 15667
15670 15668 return (rval);
15671 15669 }
15672 15670
15673 15671 static int
15674 15672 st_mtbsf_ioctl(struct scsi_tape *un, int64_t files)
15675 15673 {
15676 15674 ST_FUNC(ST_DEVINFO, st_mtbsf_ioctl);
15677 15675
15678 15676 ST_DEBUG4(ST_DEVINFO, st_label, SCSI_DEBUG,
15679 15677 "st_mtbsf_ioctl: count=%"PRIx64", eof=%x\n", files, un->un_pos.eof);
15680 15678 /*
15681 15679 * backward space of file filemark (1/2" and 8mm)
15682 15680 * tape position will end on the beginning of tape side
15683 15681 * of the desired file mark
15684 15682 */
15685 15683 if ((un->un_dp->options & ST_BSF) == 0) {
15686 15684 return (ENOTTY);
15687 15685 }
15688 15686
15689 15687 if (un->un_pos.pmode == legacy) {
15690 15688
15691 15689 /*
15692 15690 * If a negative count (which implies a forward space op)
15693 15691 * is specified, and we're at logical or physical eot,
15694 15692 * bounce the request.
15695 15693 */
15696 15694
15697 15695 if (un->un_pos.eof >= ST_EOT && files < 0) {
15698 15696 un->un_err_resid = files;
15699 15697 un->un_status = SUN_KEY_EOT;
15700 15698 ST_DEBUG2(ST_DEVINFO, st_label, SCSI_DEBUG,
15701 15699 "st_ioctl_mt_bsf : EIO : MTBSF : eof > ST_EOF");
15702 15700 return (EIO);
15703 15701 }
15704 15702 /*
15705 15703 * physical tape position may not be what we've been
15706 15704 * telling the user; adjust the request accordingly
15707 15705 */
15708 15706 if (IN_EOF(un->un_pos)) {
15709 15707 un->un_pos.fileno++;
15710 15708 un->un_pos.blkno = 0;
15711 15709 files++;
15712 15710 ST_DEBUG4(ST_DEVINFO, st_label, SCSI_DEBUG,
15713 15711 "st_mtbsf_ioctl in eof: count=%"PRIx64", op=%x\n",
15714 15712 files, MTBSF);
15715 15713
15716 15714 }
15717 15715 }
15718 15716
15719 15717 if (st_check_density_or_wfm(un->un_dev, 1, 0, STEPBACK)) {
15720 15718 ST_DEBUG2(ST_DEVINFO, st_label, SCSI_DEBUG,
15721 15719 "st_ioctl : EIO : MTBSF : check den wfm");
15722 15720 return (EIO);
15723 15721 }
15724 15722
15725 15723 if (files <= 0) {
15726 15724 /*
15727 15725 * for a negative count, we need to step forward
15728 15726 * first and then step back again
15729 15727 */
15730 15728 files = -files + 1;
15731 15729 return (st_forward_space_files(un, files));
15732 15730 }
15733 15731 return (st_backward_space_files(un, files, 1));
15734 15732 }
15735 15733
15736 15734 static int
15737 15735 st_backward_space_files(struct scsi_tape *un, int64_t count, int infront)
15738 15736 {
15739 15737 int64_t end_fileno;
15740 15738 int64_t skip_cnt;
15741 15739 int rval = 0;
15742 15740
15743 15741 ST_FUNC(ST_DEVINFO, st_backward_space_files);
15744 15742
15745 15743 ST_DEBUG4(ST_DEVINFO, st_label, SCSI_DEBUG,
15746 15744 "st_backward_space_files: count=%"PRIx64" eof=%x\n",
15747 15745 count, un->un_pos.eof);
15748 15746 /*
15749 15747 * Backspace files (MTNBSF): infront == 0
15750 15748 *
15751 15749 * For tapes that can backspace, backspace
15752 15750 * count+1 filemarks and then run forward over
15753 15751 * a filemark
15754 15752 *
15755 15753 * For tapes that can't backspace,
15756 15754 * calculate desired filenumber
15757 15755 * (un->un_pos.fileno - count), rewind,
15758 15756 * and then space forward this amount
15759 15757 *
15760 15758 * Backspace filemarks (MTBSF) infront == 1
15761 15759 *
15762 15760 * For tapes that can backspace, backspace count
15763 15761 * filemarks
15764 15762 *
15765 15763 * For tapes that can't backspace, calculate
15766 15764 * desired filenumber (un->un_pos.fileno - count),
15767 15765 * add 1, rewind, space forward this amount,
15768 15766 * and mark state as ST_EOF_PENDING appropriately.
15769 15767 */
15770 15768
15771 15769 if (un->un_pos.pmode == logical) {
15772 15770
15773 15771 ST_DEBUG4(ST_DEVINFO, st_label, SCSI_DEBUG,
15774 15772 "st_backward_space_files: mt_op=%x count=%"PRIx64
15775 15773 "lgclblkno=%"PRIx64"\n", infront?MTBSF:MTNBSF, count,
15776 15774 un->un_pos.lgclblkno);
15777 15775
15778 15776
15779 15777 /* In case a drive that won't back space gets in logical mode */
15780 15778 if ((un->un_dp->options & ST_BSF) == 0) {
15781 15779 rval = EIO;
15782 15780 return (rval);
15783 15781 }
15784 15782 if ((infront == 1) &&
15785 15783 (st_cmd(un, SCMD_SPACE, Fmk(-count), SYNC_CMD))) {
15786 15784 rval = EIO;
15787 15785 return (rval);
15788 15786 } else if ((infront == 0) &&
15789 15787 (st_cmd(un, SCMD_SPACE, Fmk((-count)-1), SYNC_CMD)) &&
15790 15788 (st_cmd(un, SCMD_SPACE, Fmk(1), SYNC_CMD))) {
15791 15789 rval = EIO;
15792 15790 return (rval);
15793 15791 }
15794 15792 return (rval);
15795 15793 }
15796 15794
15797 15795 ST_DEBUG4(ST_DEVINFO, st_label, SCSI_DEBUG,
15798 15796 "st_backward_space_files: mt_op=%x count=%"PRIx64
15799 15797 "fileno=%x blkno=%x\n",
15800 15798 infront?MTBSF:MTNBSF, count, un->un_pos.fileno, un->un_pos.blkno);
15801 15799
15802 15800
15803 15801
15804 15802 /*
15805 15803 * Handle the simple case of BOT
15806 15804 * playing a role in these cmds.
15807 15805 * We do this by calculating the
15808 15806 * ending file number. If the ending
15809 15807 * file is < BOT, rewind and set an
15810 15808 * error and mark resid appropriately.
15811 15809 * If we're backspacing a file (not a
15812 15810 * filemark) and the target file is
15813 15811 * the first file on the tape, just
15814 15812 * rewind.
15815 15813 */
15816 15814
15817 15815 /* figure expected destination of this SPACE command */
15818 15816 end_fileno = un->un_pos.fileno - count;
15819 15817
15820 15818 /*
15821 15819 * Would the end effect of this SPACE be the same as rewinding?
15822 15820 * If so just rewind instead.
15823 15821 */
15824 15822 if ((infront != 0) && (end_fileno < 0) ||
15825 15823 (infront == 0) && (end_fileno <= 0)) {
15826 15824 if (st_cmd(un, SCMD_REWIND, 0, SYNC_CMD)) {
15827 15825 ST_DEBUG2(ST_DEVINFO, st_label, SCSI_DEBUG,
15828 15826 "st_backward_space_files: EIO : "
15829 15827 "rewind in lou of BSF failed\n");
15830 15828 rval = EIO;
15831 15829 }
15832 15830 if (end_fileno < 0) {
15833 15831 ST_DEBUG2(ST_DEVINFO, st_label, SCSI_DEBUG,
15834 15832 "st_backward_space_files: EIO : "
15835 15833 "back space file greater then fileno\n");
15836 15834 rval = EIO;
15837 15835 un->un_err_resid = -end_fileno;
15838 15836 un->un_status = SUN_KEY_BOT;
15839 15837 }
15840 15838 return (rval);
15841 15839 }
15842 15840
15843 15841 if (un->un_dp->options & ST_BSF) {
15844 15842 skip_cnt = 1 - infront;
15845 15843 /*
15846 15844 * If we are going to end up at the beginning
15847 15845 * of the file, we have to space one extra file
15848 15846 * first, and then space forward later.
15849 15847 */
15850 15848 end_fileno = -(count + skip_cnt);
15851 15849 ST_DEBUG6(ST_DEVINFO, st_label, SCSI_DEBUG,
15852 15850 "skip_cnt=%"PRIx64", tmp=%"PRIx64"\n",
15853 15851 skip_cnt, end_fileno);
15854 15852 if (st_cmd(un, SCMD_SPACE, Fmk(end_fileno), SYNC_CMD)) {
15855 15853 ST_DEBUG2(ST_DEVINFO, st_label, SCSI_DEBUG,
15856 15854 "st_backward_space_files:EIO:back space fm failed");
15857 15855 rval = EIO;
15858 15856 }
15859 15857 } else {
15860 15858 if (st_cmd(un, SCMD_REWIND, 0, SYNC_CMD)) {
15861 15859 rval = EIO;
15862 15860 } else {
15863 15861 skip_cnt = end_fileno + infront;
15864 15862 }
15865 15863 }
15866 15864
15867 15865 /*
15868 15866 * If we have to space forward, do so...
15869 15867 */
15870 15868 ST_DEBUG6(ST_DEVINFO, st_label, SCSI_DEBUG,
15871 15869 "space forward skip_cnt=%"PRIx64", rval=%x\n", skip_cnt, rval);
15872 15870
15873 15871 if (rval == 0 && skip_cnt) {
15874 15872 if (st_cmd(un, SCMD_SPACE, Fmk(skip_cnt), SYNC_CMD)) {
15875 15873 ST_DEBUG2(ST_DEVINFO, st_label, SCSI_DEBUG,
15876 15874 "st_backward_space_files:EIO:space fm skip count");
15877 15875 rval = EIO;
15878 15876 } else if (infront) {
15879 15877 /*
15880 15878 * If we had to space forward, and we're
15881 15879 * not a tape that can backspace, mark state
15882 15880 * as if we'd just seen a filemark during a
15883 15881 * a read.
15884 15882 */
15885 15883 if ((un->un_dp->options & ST_BSF) == 0) {
15886 15884 un->un_pos.eof = ST_EOF_PENDING;
15887 15885 un->un_pos.fileno -= 1;
15888 15886 un->un_pos.blkno = LASTBLK;
15889 15887 un->un_running.pmode = invalid;
15890 15888 }
15891 15889 }
15892 15890 }
15893 15891
15894 15892 if (rval != 0) {
15895 15893 un->un_pos.pmode = invalid;
15896 15894 }
15897 15895
15898 15896 return (rval);
15899 15897 }
15900 15898
15901 15899 static int
15902 15900 st_mtnbsf_ioctl(struct scsi_tape *un, int64_t count)
15903 15901 {
15904 15902 int rval;
15905 15903
15906 15904 ST_FUNC(ST_DEVINFO, st_mtnbsf_ioctl);
15907 15905
15908 15906 ST_DEBUG4(ST_DEVINFO, st_label, SCSI_DEBUG,
15909 15907 "nbsf: count=%"PRIx64", eof=%x\n", count, un->un_pos.eof);
15910 15908
15911 15909 if (un->un_pos.pmode == legacy) {
15912 15910 /*
15913 15911 * backward space file to beginning of file
15914 15912 *
15915 15913 * If a negative count (which implies a forward space op)
15916 15914 * is specified, and we're at logical or physical eot,
15917 15915 * bounce the request.
15918 15916 */
15919 15917
15920 15918 if (un->un_pos.eof >= ST_EOT && count < 0) {
15921 15919 un->un_err_resid = count;
15922 15920 un->un_status = SUN_KEY_EOT;
15923 15921 ST_DEBUG2(ST_DEVINFO, st_label, SCSI_DEBUG,
15924 15922 "st_ioctl : EIO : > EOT and count < 0");
15925 15923 return (EIO);
15926 15924 }
15927 15925 /*
15928 15926 * physical tape position may not be what we've been
15929 15927 * telling the user; adjust the request accordingly
15930 15928 */
15931 15929 if (IN_EOF(un->un_pos)) {
15932 15930 un->un_pos.fileno++;
15933 15931 un->un_pos.blkno = 0;
15934 15932 count++;
15935 15933 }
15936 15934 }
15937 15935
15938 15936 if (st_check_density_or_wfm(un->un_dev, 1, 0, STEPBACK)) {
15939 15937 ST_DEBUG2(ST_DEVINFO, st_label, SCSI_DEBUG,
15940 15938 "st_ioctl : EIO : MTNBSF check den and wfm");
15941 15939 return (EIO);
15942 15940 }
15943 15941
15944 15942 ST_DEBUG4(ST_DEVINFO, st_label, SCSI_DEBUG,
15945 15943 "mtnbsf: count=%"PRIx64", eof=%x\n", count, un->un_pos.eof);
15946 15944
15947 15945 if (count <= 0) {
15948 15946 rval = st_forward_space_files(un, -count);
15949 15947 } else {
15950 15948 rval = st_backward_space_files(un, count, 0);
15951 15949 }
15952 15950 return (rval);
15953 15951 }
15954 15952
15955 15953 static int
15956 15954 st_mtbsr_ioctl(struct scsi_tape *un, int64_t num)
15957 15955 {
15958 15956 ST_FUNC(ST_DEVINFO, st_mtbsr_ioctl);
15959 15957
15960 15958 ST_DEBUG4(ST_DEVINFO, st_label, SCSI_DEBUG,
15961 15959 "bsr: count=%"PRIx64", eof=%x\n", num, un->un_pos.eof);
15962 15960
15963 15961 if (un->un_pos.pmode == legacy) {
15964 15962 /*
15965 15963 * backward space into inter-record gap
15966 15964 *
15967 15965 * If a negative count (which implies a forward space op)
15968 15966 * is specified, and we're at logical or physical eot,
15969 15967 * bounce the request.
15970 15968 */
15971 15969 if (un->un_pos.eof >= ST_EOT && num < 0) {
15972 15970 un->un_err_resid = num;
15973 15971 un->un_status = SUN_KEY_EOT;
15974 15972 ST_DEBUG2(ST_DEVINFO, st_label, SCSI_DEBUG,
15975 15973 "st_ioctl : EIO : MTBSR > EOT");
15976 15974 return (EIO);
15977 15975 }
15978 15976
15979 15977 if (num == 0) {
15980 15978 COPY_POS(&un->un_err_pos, &un->un_pos);
15981 15979 un->un_err_resid = 0;
15982 15980 if (IN_EOF(un->un_pos) && SVR4_BEHAVIOR) {
15983 15981 un->un_status = SUN_KEY_EOF;
15984 15982 }
15985 15983 return (0);
15986 15984 }
15987 15985
15988 15986 /*
15989 15987 * physical tape position may not be what we've been
15990 15988 * telling the user; adjust the position accordingly.
15991 15989 * bsr can not skip filemarks and continue to skip records
15992 15990 * therefore if we are logically before the filemark but
15993 15991 * physically at the EOT side of the filemark, we need to step
15994 15992 * back; this allows fsr N where N > number of blocks in file
15995 15993 * followed by bsr 1 to position at the beginning of last block
15996 15994 */
15997 15995 if (IN_EOF(un->un_pos)) {
15998 15996 tapepos_t save;
15999 15997 optype lastop = un->un_lastop;
16000 15998
16001 15999 COPY_POS(&save, &un->un_pos);
16002 16000 if (st_cmd(un, SCMD_SPACE, Fmk(-1), SYNC_CMD) == -1) {
16003 16001 ST_DEBUG2(ST_DEVINFO, st_label, SCSI_DEBUG,
16004 16002 "st_mtbsr_ioctl: EIO : MTBSR can't space");
16005 16003 return (EIO);
16006 16004 }
16007 16005
16008 16006 COPY_POS(&un->un_pos, &save);
16009 16007 un->un_lastop = lastop;
16010 16008 }
16011 16009 }
16012 16010
16013 16011 un->un_pos.eof = ST_NO_EOF;
16014 16012
16015 16013 if (st_check_density_or_wfm(un->un_dev, 1, 0, STEPBACK)) {
16016 16014 ST_DEBUG2(ST_DEVINFO, st_label, SCSI_DEBUG,
16017 16015 "st_ioctl : EIO : MTBSR : can't set density or wfm");
16018 16016 return (EIO);
16019 16017 }
16020 16018
16021 16019 num = -num;
16022 16020 return (st_space_records(un, num));
16023 16021 }
16024 16022
16025 16023 static int
16026 16024 st_mtfsfm_ioctl(struct scsi_tape *un, int64_t cnt)
16027 16025 {
16028 16026 int rval;
16029 16027
16030 16028 ST_FUNC(ST_DEVINFO, st_mtfsfm_ioctl);
16031 16029
16032 16030 rval = st_cmd(un, SCMD_SPACE, SPACE(SP_SQFLM, cnt), SYNC_CMD);
16033 16031 if (rval == 0) {
16034 16032 un->un_pos.pmode = logical;
16035 16033 } else if ((un->un_status == KEY_ILLEGAL_REQUEST) &&
16036 16034 (un->un_sd->sd_sense->es_add_code == 0x24)) {
16037 16035 /*
16038 16036 * Drive says invalid field in cdb.
16039 16037 * Doesn't like space multiple. Position isn't lost.
16040 16038 */
16041 16039 un->un_err_resid = cnt;
16042 16040 un->un_status = 0;
16043 16041 rval = ENOTTY;
16044 16042 } else {
16045 16043 un->un_err_resid = cnt;
16046 16044 un->un_pos.pmode = invalid;
16047 16045 }
16048 16046 return (rval);
16049 16047 }
16050 16048
16051 16049 static int
16052 16050 st_mtbsfm_ioctl(struct scsi_tape *un, int64_t cnt)
16053 16051 {
16054 16052 int rval;
16055 16053
16056 16054 ST_FUNC(ST_DEVINFO, st_mtbsfm_ioctl);
16057 16055
16058 16056 rval = st_cmd(un, SCMD_SPACE, SPACE(SP_SQFLM, -cnt), SYNC_CMD);
16059 16057 if (rval == 0) {
16060 16058 un->un_pos.pmode = logical;
16061 16059 } else if ((un->un_status == KEY_ILLEGAL_REQUEST) &&
16062 16060 (un->un_sd->sd_sense->es_add_code == 0x24)) {
16063 16061 /*
16064 16062 * Drive says invalid field in cdb.
16065 16063 * Doesn't like space multiple. Position isn't lost.
16066 16064 */
16067 16065 un->un_err_resid = cnt;
16068 16066 un->un_status = 0;
16069 16067 rval = ENOTTY;
16070 16068 } else {
16071 16069 un->un_err_resid = cnt;
16072 16070 un->un_pos.pmode = invalid;
16073 16071 }
16074 16072 return (rval);
16075 16073 }
16076 16074
16077 16075 #ifdef __x86
16078 16076
16079 16077 /*
16080 16078 * release contig_mem and wake up waiting thread, if any
16081 16079 */
16082 16080 static void
16083 16081 st_release_contig_mem(struct scsi_tape *un, struct contig_mem *cp)
16084 16082 {
16085 16083 mutex_enter(ST_MUTEX);
16086 16084
16087 16085 ST_FUNC(ST_DEVINFO, st_release_contig_mem);
16088 16086
16089 16087 cp->cm_next = un->un_contig_mem;
16090 16088 un->un_contig_mem = cp;
16091 16089 un->un_contig_mem_available_num++;
16092 16090 cv_broadcast(&un->un_contig_mem_cv);
16093 16091
16094 16092 mutex_exit(ST_MUTEX);
16095 16093 }
16096 16094
16097 16095 /*
16098 16096 * St_get_contig_mem will return a contig_mem if there is one available
16099 16097 * in current system. Otherwise, it will try to alloc one, if the total
16100 16098 * number of contig_mem is within st_max_contig_mem_num.
16101 16099 * It will sleep, if allowed by caller or return NULL, if no contig_mem
16102 16100 * is available for now.
16103 16101 */
16104 16102 static struct contig_mem *
16105 16103 st_get_contig_mem(struct scsi_tape *un, size_t len, int alloc_flags)
16106 16104 {
16107 16105 size_t rlen;
16108 16106 struct contig_mem *cp = NULL;
16109 16107 ddi_acc_handle_t acc_hdl;
16110 16108 caddr_t addr;
16111 16109 int big_enough = 0;
16112 16110 int (*dma_alloc_cb)() = (alloc_flags == KM_SLEEP) ?
16113 16111 DDI_DMA_SLEEP : DDI_DMA_DONTWAIT;
16114 16112
16115 16113 /* Try to get one available contig_mem */
16116 16114 mutex_enter(ST_MUTEX);
16117 16115
16118 16116 ST_FUNC(ST_DEVINFO, st_get_contig_mem);
16119 16117
16120 16118 if (un->un_contig_mem_available_num > 0) {
16121 16119 ST_GET_CONTIG_MEM_HEAD(un, cp, len, big_enough);
16122 16120 } else if (un->un_contig_mem_total_num < st_max_contig_mem_num) {
16123 16121 /*
16124 16122 * we failed to get one. we're going to
16125 16123 * alloc one more contig_mem for this I/O
16126 16124 */
16127 16125 mutex_exit(ST_MUTEX);
16128 16126 cp = (struct contig_mem *)kmem_zalloc(
16129 16127 sizeof (struct contig_mem) + biosize(),
16130 16128 alloc_flags);
16131 16129 if (cp == NULL) {
16132 16130 ST_DEBUG2(ST_DEVINFO, st_label, SCSI_DEBUG,
16133 16131 "alloc contig_mem failure\n");
16134 16132 return (NULL); /* cannot get one */
16135 16133 }
16136 16134 cp->cm_bp = (struct buf *)
16137 16135 (((caddr_t)cp) + sizeof (struct contig_mem));
16138 16136 bioinit(cp->cm_bp);
16139 16137 mutex_enter(ST_MUTEX);
16140 16138 un->un_contig_mem_total_num++; /* one more available */
16141 16139 } else {
16142 16140 /*
16143 16141 * we failed to get one and we're NOT allowed to
16144 16142 * alloc more contig_mem
16145 16143 */
16146 16144 if (alloc_flags == KM_SLEEP) {
16147 16145 while (un->un_contig_mem_available_num <= 0) {
16148 16146 cv_wait(&un->un_contig_mem_cv, ST_MUTEX);
16149 16147 }
16150 16148 ST_GET_CONTIG_MEM_HEAD(un, cp, len, big_enough);
16151 16149 } else {
16152 16150 mutex_exit(ST_MUTEX);
16153 16151 ST_DEBUG2(ST_DEVINFO, st_label, SCSI_DEBUG,
16154 16152 "alloc contig_mem failure\n");
16155 16153 return (NULL); /* cannot get one */
16156 16154 }
16157 16155 }
16158 16156 mutex_exit(ST_MUTEX);
16159 16157
16160 16158 /* We need to check if this block of mem is big enough for this I/O */
16161 16159 if (cp->cm_len < len) {
16162 16160 /* not big enough, need to alloc a new one */
16163 16161 if (ddi_dma_mem_alloc(un->un_contig_mem_hdl, len, &st_acc_attr,
16164 16162 DDI_DMA_STREAMING, dma_alloc_cb, NULL,
16165 16163 &addr, &rlen, &acc_hdl) != DDI_SUCCESS) {
16166 16164 ST_DEBUG2(ST_DEVINFO, st_label, SCSI_DEBUG,
16167 16165 "alloc contig_mem failure: not enough mem\n");
16168 16166 st_release_contig_mem(un, cp);
16169 16167 cp = NULL;
16170 16168 } else {
16171 16169 if (cp->cm_addr) {
16172 16170 /* release previous one before attach new one */
16173 16171 ddi_dma_mem_free(&cp->cm_acc_hdl);
16174 16172 }
16175 16173 mutex_enter(ST_MUTEX);
16176 16174 un->un_max_contig_mem_len =
16177 16175 un->un_max_contig_mem_len >= len ?
16178 16176 un->un_max_contig_mem_len : len;
16179 16177 mutex_exit(ST_MUTEX);
16180 16178
16181 16179 /* attach new mem to this cp */
16182 16180 cp->cm_addr = addr;
16183 16181 cp->cm_acc_hdl = acc_hdl;
16184 16182 cp->cm_len = len;
16185 16183
16186 16184 goto alloc_ok; /* get one usable cp */
16187 16185 }
16188 16186 } else {
16189 16187 goto alloc_ok; /* get one usable cp */
16190 16188 }
16191 16189
16192 16190 /* cannot find/alloc a usable cp, when we get here */
16193 16191
16194 16192 mutex_enter(ST_MUTEX);
16195 16193 if ((un->un_max_contig_mem_len < len) ||
16196 16194 (alloc_flags != KM_SLEEP)) {
16197 16195 mutex_exit(ST_MUTEX);
16198 16196 return (NULL);
16199 16197 }
16200 16198
16201 16199 /*
16202 16200 * we're allowed to sleep, and there is one big enough
16203 16201 * contig mem in the system, which is currently in use,
16204 16202 * wait for it...
16205 16203 */
16206 16204 big_enough = 1;
16207 16205 do {
16208 16206 cv_wait(&un->un_contig_mem_cv, ST_MUTEX);
16209 16207 ST_GET_CONTIG_MEM_HEAD(un, cp, len, big_enough);
16210 16208 } while (cp == NULL);
16211 16209 mutex_exit(ST_MUTEX);
16212 16210
16213 16211 /* we get the big enough contig mem, finally */
16214 16212
16215 16213 alloc_ok:
16216 16214 /* init bp attached to this cp */
16217 16215 bioreset(cp->cm_bp);
16218 16216 cp->cm_bp->b_un.b_addr = cp->cm_addr;
16219 16217 cp->cm_bp->b_private = (void *)cp;
16220 16218
16221 16219 return (cp);
16222 16220 }
16223 16221
16224 16222 /*
16225 16223 * this is the biodone func for the bp used in big block I/O
16226 16224 */
16227 16225 static int
16228 16226 st_bigblk_xfer_done(struct buf *bp)
16229 16227 {
16230 16228 struct contig_mem *cp;
16231 16229 struct buf *orig_bp;
16232 16230 int ioerr;
16233 16231 struct scsi_tape *un;
16234 16232
16235 16233 /* sanity check */
16236 16234 if (bp == NULL) {
16237 16235 return (DDI_FAILURE);
16238 16236 }
16239 16237
16240 16238 un = ddi_get_soft_state(st_state, MTUNIT(bp->b_edev));
16241 16239 if (un == NULL) {
16242 16240 return (DDI_FAILURE);
16243 16241 }
16244 16242
16245 16243 ST_FUNC(ST_DEVINFO, st_bigblk_xfer_done);
16246 16244
16247 16245 cp = (struct contig_mem *)bp->b_private;
16248 16246 orig_bp = cp->cm_bp; /* get back the bp we have replaced */
16249 16247 cp->cm_bp = bp;
16250 16248
16251 16249 /* special handling for special I/O */
16252 16250 if (cp->cm_use_sbuf) {
16253 16251 #ifndef __lock_lint
16254 16252 ASSERT(un->un_sbuf_busy);
16255 16253 #endif
16256 16254 un->un_sbufp = orig_bp;
16257 16255 cp->cm_use_sbuf = 0;
16258 16256 }
16259 16257
16260 16258 orig_bp->b_resid = bp->b_resid;
16261 16259 ioerr = geterror(bp);
16262 16260 if (ioerr != 0) {
16263 16261 bioerror(orig_bp, ioerr);
16264 16262 } else if (orig_bp->b_flags & B_READ) {
16265 16263 /* copy data back to original bp */
16266 16264 (void) bp_copyout(bp->b_un.b_addr, orig_bp, 0,
16267 16265 bp->b_bcount - bp->b_resid);
16268 16266 }
16269 16267
16270 16268 st_release_contig_mem(un, cp);
16271 16269
16272 16270 biodone(orig_bp);
16273 16271
16274 16272 return (DDI_SUCCESS);
16275 16273 }
16276 16274
16277 16275 /*
16278 16276 * We use this func to replace original bp that may not be able to do I/O
16279 16277 * in big block size with one that can
16280 16278 */
16281 16279 static struct buf *
16282 16280 st_get_bigblk_bp(struct buf *bp)
16283 16281 {
16284 16282 struct contig_mem *cp;
16285 16283 struct scsi_tape *un;
16286 16284 struct buf *cont_bp;
16287 16285
16288 16286 un = ddi_get_soft_state(st_state, MTUNIT(bp->b_edev));
16289 16287 if (un == NULL) {
16290 16288 return (bp);
16291 16289 }
16292 16290
16293 16291 ST_FUNC(ST_DEVINFO, st_get_bigblk_bp);
16294 16292
16295 16293 /* try to get one contig_mem */
16296 16294 cp = st_get_contig_mem(un, bp->b_bcount, KM_SLEEP);
16297 16295 if (!cp) {
16298 16296 scsi_log(ST_DEVINFO, st_label, CE_WARN,
16299 16297 "Cannot alloc contig buf for I/O for %lu blk size",
16300 16298 bp->b_bcount);
16301 16299 return (bp);
16302 16300 }
16303 16301 cont_bp = cp->cm_bp;
16304 16302 cp->cm_bp = bp;
16305 16303
16306 16304 /* make sure that we "are" using un_sbufp for special I/O */
16307 16305 if (bp == un->un_sbufp) {
16308 16306 #ifndef __lock_lint
16309 16307 ASSERT(un->un_sbuf_busy);
16310 16308 #endif
16311 16309 un->un_sbufp = cont_bp;
16312 16310 cp->cm_use_sbuf = 1;
16313 16311 }
16314 16312
16315 16313 /* clone bp */
16316 16314 cont_bp->b_bcount = bp->b_bcount;
16317 16315 cont_bp->b_resid = bp->b_resid;
16318 16316 cont_bp->b_iodone = st_bigblk_xfer_done;
16319 16317 cont_bp->b_file = bp->b_file;
16320 16318 cont_bp->b_offset = bp->b_offset;
16321 16319 cont_bp->b_dip = bp->b_dip;
16322 16320 cont_bp->b_error = 0;
16323 16321 cont_bp->b_proc = NULL;
16324 16322 cont_bp->b_flags = bp->b_flags & ~(B_PAGEIO | B_PHYS | B_SHADOW);
16325 16323 cont_bp->b_shadow = NULL;
16326 16324 cont_bp->b_pages = NULL;
16327 16325 cont_bp->b_edev = bp->b_edev;
16328 16326 cont_bp->b_dev = bp->b_dev;
16329 16327 cont_bp->b_lblkno = bp->b_lblkno;
16330 16328 cont_bp->b_forw = bp->b_forw;
16331 16329 cont_bp->b_back = bp->b_back;
16332 16330 cont_bp->av_forw = bp->av_forw;
16333 16331 cont_bp->av_back = bp->av_back;
16334 16332 cont_bp->b_bufsize = bp->b_bufsize;
16335 16333
16336 16334 /* get data in original bp */
16337 16335 if (bp->b_flags & B_WRITE) {
16338 16336 (void) bp_copyin(bp, cont_bp->b_un.b_addr, 0, bp->b_bcount);
16339 16337 }
16340 16338
16341 16339 return (cont_bp);
16342 16340 }
16343 16341 #else
16344 16342 #ifdef __lock_lint
16345 16343 static int
16346 16344 st_bigblk_xfer_done(struct buf *bp)
16347 16345 {
16348 16346 return (0);
16349 16347 }
16350 16348 #endif
16351 16349 #endif
16352 16350
16353 16351 static const char *eof_status[] =
16354 16352 {
16355 16353 "NO_EOF",
16356 16354 "EOF_PENDING",
16357 16355 "EOF",
16358 16356 "EOT_PENDING",
16359 16357 "EOT",
16360 16358 "EOM",
16361 16359 "AFTER_EOM"
16362 16360 };
16363 16361 static const char *mode[] = {
16364 16362 "invalid",
16365 16363 "legacy",
16366 16364 "logical"
16367 16365 };
16368 16366
16369 16367 static void
16370 16368 st_print_position(dev_info_t *dev, char *label, uint_t level,
16371 16369 const char *comment, tapepos_t *pos)
16372 16370 {
16373 16371 ST_FUNC(dev, st_print_position);
16374 16372
16375 16373 scsi_log(dev, label, level,
16376 16374 "%s Position data:\n", comment);
16377 16375 scsi_log(dev, label, CE_CONT,
16378 16376 "Positioning mode = %s", mode[pos->pmode]);
16379 16377 scsi_log(dev, label, CE_CONT,
16380 16378 "End Of File/Tape = %s", eof_status[pos->eof]);
16381 16379 scsi_log(dev, label, CE_CONT,
16382 16380 "File Number = 0x%x", pos->fileno);
16383 16381 scsi_log(dev, label, CE_CONT,
16384 16382 "Block Number = 0x%x", pos->blkno);
16385 16383 scsi_log(dev, label, CE_CONT,
16386 16384 "Logical Block = 0x%"PRIx64, pos->lgclblkno);
16387 16385 scsi_log(dev, label, CE_CONT,
16388 16386 "Partition Number = 0x%x", pos->partition);
16389 16387 }
16390 16388 static int
16391 16389 st_check_if_media_changed(struct scsi_tape *un, caddr_t data, int size)
16392 16390 {
16393 16391
16394 16392 int result = 0;
16395 16393 int i;
16396 16394 ST_FUNC(ST_DEVINFO, st_check_if_media_changed);
16397 16395
16398 16396 /*
16399 16397 * find non alpha numeric working from the end.
16400 16398 */
16401 16399 for (i = size - 1; i >= 0; i--) {
16402 16400 if (ISALNUM(data[i]) == 0 || data[i] == ' ') {
16403 16401 data[i] = 0;
16404 16402 size = i;
16405 16403 }
16406 16404 }
16407 16405
16408 16406 if (size == 1) {
16409 16407 /*
16410 16408 * Drive seems to think its returning useful data
16411 16409 * but it looks like all junk
16412 16410 */
16413 16411 return (result);
16414 16412 }
16415 16413
16416 16414 size++;
16417 16415
16418 16416 /*
16419 16417 * Actually got a valid serial number.
16420 16418 * If never stored one before alloc space for it.
16421 16419 */
16422 16420 if (un->un_media_id_len == 0) {
16423 16421 un->un_media_id = kmem_zalloc(size, KM_SLEEP);
16424 16422 un->un_media_id_len = size;
16425 16423 (void) strncpy(un->un_media_id, data, min(size, strlen(data)));
16426 16424 un->un_media_id[min(size, strlen(data))] = 0;
16427 16425 ST_DEBUG1(ST_DEVINFO, st_label, SCSI_DEBUG,
16428 16426 "Found Media Id %s length = %d\n", un->un_media_id, size);
16429 16427 } else if (size > un->un_media_id_len) {
16430 16428 if (strncmp(un->un_media_id, data, size) != 0) {
16431 16429 result = ESPIPE;
16432 16430 }
16433 16431 ST_DEBUG1(ST_DEVINFO, st_label, SCSI_DEBUG,
16434 16432 "Longer Media Id old ID:%s new ID:%s\n",
16435 16433 un->un_media_id, data);
16436 16434 kmem_free(un->un_media_id, un->un_media_id_len);
16437 16435 un->un_media_id = kmem_zalloc(size, KM_SLEEP);
16438 16436 un->un_media_id_len = size;
16439 16437 (void) strncpy(un->un_media_id, data, size);
16440 16438 un->un_media_id[size] = 0;
16441 16439 } else if (strncmp(data, un->un_media_id,
16442 16440 min(size, un->un_media_id_len)) != 0) {
16443 16441 ST_DEBUG1(ST_DEVINFO, st_label, SCSI_DEBUG,
16444 16442 "Old Media Id %s length = %d New %s length = %d\n",
16445 16443 un->un_media_id, un->un_media_id_len, data, size);
16446 16444 bzero(un->un_media_id, un->un_media_id_len);
16447 16445 (void) strncpy(un->un_media_id, data, min(size, strlen(data)));
16448 16446 un->un_media_id[min(size, strlen(data))] = 0;
16449 16447 result = ESPIPE;
16450 16448 } else {
16451 16449 ST_DEBUG4(ST_DEVINFO, st_label, SCSI_DEBUG,
16452 16450 "Media Id still %s\n", un->un_media_id);
16453 16451 }
16454 16452
16455 16453 ASSERT(strlen(un->un_media_id) <= size);
16456 16454
16457 16455 return (result);
16458 16456 }
16459 16457 #define ID_SIZE 32
16460 16458 typedef struct
16461 16459 {
16462 16460 uchar_t avilable_data0;
16463 16461 uchar_t avilable_data1;
16464 16462 uchar_t avilable_data2;
16465 16463 uchar_t avilable_data3;
16466 16464 uchar_t attribute_msb;
16467 16465 uchar_t attribute_lsb;
16468 16466 #ifdef _BIT_FIELDS_LTOH
16469 16467 uchar_t format : 2,
16470 16468 : 5,
16471 16469 read_only : 1;
16472 16470 #else
16473 16471 uchar_t read_only : 1,
16474 16472 : 5,
16475 16473 format : 2;
16476 16474 #endif
16477 16475 uchar_t attribute_len_msb;
16478 16476 uchar_t attribute_len_lsb;
16479 16477 }attribute_header;
16480 16478
16481 16479 typedef struct {
16482 16480 attribute_header header;
16483 16481 char data[1];
16484 16482 }mam_attribute;
16485 16483
16486 16484 static int
16487 16485 st_handle_hex_media_id(struct scsi_tape *un, void *pnt, int size)
16488 16486 {
16489 16487 int result;
16490 16488 int newsize = (size << 1) + 3; /* extra for leading 0x and null term */
16491 16489 int i;
16492 16490 uchar_t byte;
16493 16491 char *format;
16494 16492 uchar_t *data = (uchar_t *)pnt;
16495 16493 char *buf = kmem_alloc(newsize, KM_SLEEP);
16496 16494
16497 16495 ST_FUNC(ST_DEVINFO, st_handle_hex_media_id);
16498 16496
16499 16497 (void) sprintf(buf, "0x");
16500 16498 for (i = 0; i < size; i++) {
16501 16499 byte = data[i];
16502 16500 if (byte < 0x10)
16503 16501 format = "0%x";
16504 16502 else
16505 16503 format = "%x";
16506 16504 (void) sprintf(&buf[(int)strlen(buf)], format, byte);
16507 16505 }
16508 16506 result = st_check_if_media_changed(un, buf, newsize);
16509 16507
16510 16508 kmem_free(buf, newsize);
16511 16509
16512 16510 return (result);
16513 16511 }
16514 16512
16515 16513
16516 16514 static int
16517 16515 st_get_media_id_via_read_attribute(struct scsi_tape *un, ubufunc_t bufunc)
16518 16516 {
16519 16517 int result;
16520 16518 mam_attribute *buffer;
16521 16519 int size;
16522 16520 int newsize;
16523 16521
16524 16522 ST_FUNC(ST_DEVINFO, st_get_media_id_via_read_attribute);
16525 16523 size = sizeof (attribute_header) + max(un->un_media_id_len, ID_SIZE);
16526 16524 again:
16527 16525 buffer = kmem_zalloc(size, KM_SLEEP);
16528 16526 result = st_read_attributes(un, 0x0401, buffer, size, bufunc);
16529 16527 if (result == 0) {
16530 16528
16531 16529 newsize = (buffer->header.attribute_len_msb << 8) |
16532 16530 buffer->header.attribute_len_lsb;
16533 16531
16534 16532 if (newsize + sizeof (attribute_header) > size) {
16535 16533 ST_DEBUG(ST_DEVINFO, st_label, SCSI_DEBUG,
16536 16534 "resizing read attribute data from %d to %d format"
16537 16535 " %d\n", size, (int)sizeof (attribute_header) +
16538 16536 newsize, buffer->header.format);
16539 16537 kmem_free(buffer, size);
16540 16538 size = newsize + sizeof (attribute_header);
16541 16539 goto again;
16542 16540 }
16543 16541
16544 16542 un->un_media_id_method = st_get_media_id_via_read_attribute;
16545 16543 if (buffer->header.format == 0) {
16546 16544 result =
16547 16545 st_handle_hex_media_id(un, buffer->data, newsize);
16548 16546 } else {
16549 16547 result = st_check_if_media_changed(un, buffer->data,
16550 16548 newsize);
16551 16549 }
16552 16550 } else if (result == EINVAL && un->un_max_cdb_sz < CDB_GROUP4) {
16553 16551 scsi_log(ST_DEVINFO, st_label, CE_NOTE,
16554 16552 "Read Attribute Command for Media Identification is not "
16555 16553 "supported on the HBA that this drive is attached to.");
16556 16554 result = ENOTTY;
16557 16555 }
16558 16556
16559 16557 kmem_free(buffer, size);
16560 16558 un->un_status = 0;
16561 16559
16562 16560 return (result);
16563 16561 }
16564 16562
16565 16563
16566 16564 static int
16567 16565 st_get_media_id_via_media_serial_cmd(struct scsi_tape *un, ubufunc_t bufunc)
16568 16566 {
16569 16567 char cdb[CDB_GROUP5];
16570 16568 struct uscsi_cmd *ucmd;
16571 16569 struct scsi_extended_sense sense;
16572 16570 int rval;
16573 16571 int size = max(un->un_media_id_len, ID_SIZE);
16574 16572 caddr_t buf;
16575 16573
16576 16574 ST_FUNC(ST_DEVINFO, st_get_media_id_via_media_serial_cmd);
16577 16575
16578 16576 if (un->un_sd->sd_inq->inq_ansi < 3) {
16579 16577 return (ENOTTY);
16580 16578 }
16581 16579
16582 16580 ucmd = kmem_zalloc(sizeof (struct uscsi_cmd), KM_SLEEP);
16583 16581 upsize:
16584 16582 buf = kmem_alloc(size, KM_SLEEP);
16585 16583
16586 16584 cdb[0] = (char)SCMD_SVC_ACTION_IN_G5;
16587 16585 cdb[1] = SSVC_ACTION_READ_MEDIA_SERIAL;
16588 16586 cdb[2] = 0;
16589 16587 cdb[3] = 0;
16590 16588 cdb[4] = 0;
16591 16589 cdb[5] = 0;
16592 16590 cdb[6] = (char)(size >> 24);
16593 16591 cdb[7] = (char)(size >> 16);
16594 16592 cdb[8] = (char)(size >> 8);
16595 16593 cdb[9] = (char)(size);
16596 16594 cdb[10] = 0;
16597 16595 cdb[11] = 0;
16598 16596
16599 16597 ucmd->uscsi_flags = USCSI_READ | USCSI_RQENABLE;
16600 16598 ucmd->uscsi_timeout = un->un_dp->non_motion_timeout;
16601 16599 ucmd->uscsi_cdb = &cdb[0];
16602 16600 ucmd->uscsi_cdblen = sizeof (cdb);
16603 16601 ucmd->uscsi_bufaddr = buf;
16604 16602 ucmd->uscsi_buflen = size;
16605 16603 ucmd->uscsi_rqbuf = (caddr_t)&sense;
16606 16604 ucmd->uscsi_rqlen = sizeof (sense);
16607 16605
16608 16606 rval = bufunc(un, ucmd, FKIOCTL);
16609 16607
16610 16608 if (rval || ucmd->uscsi_status != 0) {
16611 16609 ST_DEBUG3(ST_DEVINFO, st_label, SCSI_DEBUG,
16612 16610 "media serial command returned %d scsi_status %d"
16613 16611 " rqstatus %d", rval, ucmd->uscsi_status,
16614 16612 ucmd->uscsi_rqstatus);
16615 16613 /*
16616 16614 * If this returns invalid operation code don't try again.
16617 16615 */
16618 16616 if (sense.es_key == KEY_ILLEGAL_REQUEST &&
16619 16617 sense.es_add_code == 0x20) {
16620 16618 rval = ENOTTY;
16621 16619 } else if (rval == 0) {
16622 16620 rval = EIO;
16623 16621 }
16624 16622 un->un_status = 0;
16625 16623 } else {
16626 16624 int act_size;
16627 16625
16628 16626 /*
16629 16627 * get reported size.
16630 16628 */
16631 16629 act_size = (int)buf[3] | (int)(buf[2] << 8) |
16632 16630 (int)(buf[1] << 16) | (int)(buf[0] << 24);
16633 16631
16634 16632 /* documentation says mod 4. */
16635 16633 while (act_size & 3) {
16636 16634 act_size++;
16637 16635 }
16638 16636
16639 16637 /*
16640 16638 * If reported size is larger that we our buffer.
16641 16639 * Free the old one and allocate one that is larger
16642 16640 * enough and re-issuse the command.
16643 16641 */
16644 16642 if (act_size + 4 > size) {
16645 16643 kmem_free(buf, size);
16646 16644 size = act_size + 4;
16647 16645 goto upsize;
16648 16646 }
16649 16647
16650 16648 if (act_size == 0) {
16651 16649 ST_DEBUG3(ST_DEVINFO, st_label, SCSI_DEBUG,
16652 16650 "media serial number is not available");
16653 16651 un->un_status = 0;
16654 16652 rval = 0;
16655 16653 } else {
16656 16654 /*
16657 16655 * set data pointer to point to the start
16658 16656 * of that serial number.
16659 16657 */
16660 16658 un->un_media_id_method =
16661 16659 st_get_media_id_via_media_serial_cmd;
16662 16660 rval =
16663 16661 st_check_if_media_changed(un, &buf[4], act_size);
16664 16662 }
16665 16663 }
16666 16664
16667 16665 kmem_free(ucmd, sizeof (struct uscsi_cmd));
16668 16666 kmem_free(buf, size);
16669 16667
16670 16668 return (rval);
16671 16669 }
16672 16670
16673 16671
16674 16672 /* ARGSUSED */
16675 16673 static int
16676 16674 st_bogus_media_id(struct scsi_tape *un, ubufunc_t bufunc)
16677 16675 {
16678 16676 ST_FUNC(ST_DEVINFO, st_bogus_media_id);
16679 16677
16680 16678 ASSERT(un->un_media_id == NULL || un->un_media_id == bogusID);
16681 16679 ASSERT(un->un_media_id_len == 0);
16682 16680 un->un_media_id = (char *)bogusID;
16683 16681 un->un_media_id_len = 0;
16684 16682 return (0);
16685 16683 }
16686 16684
16687 16685 typedef int (*media_chk_function)(struct scsi_tape *, ubufunc_t bufunc);
16688 16686
16689 16687 media_chk_function media_chk_functions[] = {
16690 16688 st_get_media_id_via_media_serial_cmd,
16691 16689 st_get_media_id_via_read_attribute,
16692 16690 st_bogus_media_id
16693 16691 };
16694 16692
16695 16693 static int
16696 16694 st_get_media_identification(struct scsi_tape *un, ubufunc_t bufunc)
16697 16695 {
16698 16696 int result = 0;
16699 16697 int i;
16700 16698
16701 16699 ST_FUNC(ST_DEVINFO, st_get_media_identification);
16702 16700
16703 16701 for (i = 0; i < ST_NUM_MEMBERS(media_chk_functions); i++) {
16704 16702 if (result == ENOTTY) {
16705 16703 /*
16706 16704 * Last operation type not supported by this device.
16707 16705 * Make so next time it doesn`t do that again.
16708 16706 */
16709 16707 un->un_media_id_method = media_chk_functions[i];
16710 16708 } else if (un->un_media_id_method != media_chk_functions[i] &&
16711 16709 un->un_media_id_method != st_get_media_identification) {
16712 16710 continue;
16713 16711 }
16714 16712 result = media_chk_functions[i](un, bufunc);
16715 16713 /*
16716 16714 * If result indicates the function was successful or
16717 16715 * that the media is not the same as last known, break.
16718 16716 */
16719 16717 if (result == 0 || result == ESPIPE) {
16720 16718 break;
16721 16719 }
16722 16720 }
16723 16721
16724 16722 return (result);
16725 16723 }
16726 16724
16727 16725 static errstate
16728 16726 st_command_recovery(struct scsi_tape *un, struct scsi_pkt *pkt,
16729 16727 errstate onentry)
16730 16728 {
16731 16729
16732 16730 int ret;
16733 16731 st_err_info *errinfo;
16734 16732 recov_info *ri = (recov_info *)pkt->pkt_private;
16735 16733
16736 16734 ST_FUNC(ST_DEVINFO, st_command_recovery);
16737 16735
16738 16736 ASSERT(MUTEX_HELD(&un->un_sd->sd_mutex));
16739 16737
16740 16738 ASSERT(un->un_recov_buf_busy == 0);
16741 16739
16742 16740 /*
16743 16741 * Don't try and recover a reset that this device sent.
16744 16742 */
16745 16743 if (un->un_rsvd_status & ST_INITIATED_RESET &&
16746 16744 onentry == DEVICE_RESET) {
16747 16745 return (COMMAND_DONE_ERROR);
16748 16746 }
16749 16747
16750 16748 /*
16751 16749 * See if expected position was passed with scsi_pkt.
16752 16750 */
16753 16751 if (ri->privatelen == sizeof (recov_info)) {
16754 16752
16755 16753 /*
16756 16754 * Not for this command.
16757 16755 */
16758 16756 if (ri->cmd_attrib->do_not_recover) {
16759 16757 return (COMMAND_DONE_ERROR);
16760 16758 }
16761 16759
16762 16760 /*
16763 16761 * Create structure to hold all error state info.
16764 16762 */
16765 16763 errinfo = kmem_zalloc(ST_ERR_INFO_SIZE, KM_SLEEP);
16766 16764 errinfo->ei_error_type = onentry;
16767 16765 errinfo->ei_failing_bp = ri->cmd_bp;
16768 16766 COPY_POS(&errinfo->ei_expected_pos, &ri->pos);
16769 16767 } else {
16770 16768 /* disabled */
16771 16769 return (COMMAND_DONE_ERROR);
16772 16770 }
16773 16771
16774 16772 bcopy(pkt, &errinfo->ei_failed_pkt, scsi_pkt_size());
16775 16773 bcopy(pkt->pkt_scbp, &errinfo->ei_failing_status, SECMDS_STATUS_SIZE);
16776 16774 ret = ddi_taskq_dispatch(un->un_recov_taskq, st_recover, errinfo,
16777 16775 DDI_NOSLEEP);
16778 16776 ASSERT(ret == DDI_SUCCESS);
16779 16777 if (ret != DDI_SUCCESS) {
16780 16778 kmem_free(errinfo, ST_ERR_INFO_SIZE);
16781 16779 return (COMMAND_DONE_ERROR);
16782 16780 }
16783 16781 return (JUST_RETURN); /* release calling thread */
16784 16782 }
16785 16783
16786 16784
16787 16785 static void
16788 16786 st_recov_ret(struct scsi_tape *un, st_err_info *errinfo, errstate err)
16789 16787 {
16790 16788 int error_number;
16791 16789 buf_t *bp;
16792 16790
16793 16791
16794 16792 ST_FUNC(ST_DEVINFO, st_recov_ret);
16795 16793
16796 16794 ASSERT(MUTEX_HELD(&un->un_sd->sd_mutex));
16797 16795 #if !defined(lint)
16798 16796 _NOTE(LOCK_RELEASED_AS_SIDE_EFFECT(&un->un_sd->sd_mutex))
16799 16797 #endif
16800 16798
16801 16799 bp = errinfo->ei_failing_bp;
16802 16800 kmem_free(errinfo, ST_ERR_INFO_SIZE);
16803 16801
16804 16802 switch (err) {
16805 16803 case JUST_RETURN:
16806 16804 mutex_exit(&un->un_sd->sd_mutex);
16807 16805 return;
16808 16806
16809 16807 case COMMAND_DONE:
16810 16808 case COMMAND_DONE_ERROR_RECOVERED:
16811 16809 ST_DO_KSTATS(bp, kstat_runq_exit);
16812 16810 error_number = 0;
16813 16811 break;
16814 16812
16815 16813 default:
16816 16814 ST_DEBUG(ST_DEVINFO, st_label, CE_PANIC,
16817 16815 "st_recov_ret with unhandled errstat %d\n", err);
16818 16816 /* FALLTHROUGH */
16819 16817 case COMMAND_DONE_ERROR:
16820 16818 un->un_pos.pmode = invalid;
16821 16819 un->un_running.pmode = invalid;
16822 16820 /* FALLTHROUGH */
16823 16821 case COMMAND_DONE_EACCES:
16824 16822 ST_DO_KSTATS(bp, kstat_waitq_exit);
16825 16823 ST_DO_ERRSTATS(un, st_transerrs);
16826 16824 error_number = EIO;
16827 16825 st_set_pe_flag(un);
16828 16826 break;
16829 16827
16830 16828 }
16831 16829
16832 16830 st_bioerror(bp, error_number);
16833 16831 st_done_and_mutex_exit(un, bp);
16834 16832 }
16835 16833
16836 16834
16837 16835 static void
16838 16836 st_recover(void *arg)
16839 16837 {
16840 16838 st_err_info *const errinfo = (st_err_info *)arg;
16841 16839 uchar_t com = errinfo->ei_failed_pkt.pkt_cdbp[0];
16842 16840 struct scsi_tape *un;
16843 16841 tapepos_t cur_pos;
16844 16842 int rval;
16845 16843 errstate status = COMMAND_DONE_ERROR;
16846 16844 recov_info *rcv;
16847 16845 buf_t *bp;
16848 16846
16849 16847
16850 16848 rcv = errinfo->ei_failed_pkt.pkt_private;
16851 16849 ASSERT(rcv->privatelen == sizeof (recov_info));
16852 16850 bp = rcv->cmd_bp;
16853 16851
16854 16852 un = ddi_get_soft_state(st_state, MTUNIT(bp->b_edev));
16855 16853
16856 16854 ASSERT(un != NULL);
16857 16855
16858 16856 mutex_enter(ST_MUTEX);
16859 16857
16860 16858 ST_FUNC(ST_DEVINFO, st_recover);
16861 16859
16862 16860 ST_CDB(ST_DEVINFO, "Recovering command",
16863 16861 (caddr_t)errinfo->ei_failed_pkt.pkt_cdbp);
16864 16862 ST_SENSE(ST_DEVINFO, "sense status for failed command",
16865 16863 (caddr_t)&errinfo->ei_failing_status,
16866 16864 sizeof (struct scsi_arq_status));
16867 16865 ST_POS(ST_DEVINFO, rcv->cmd_attrib->recov_pos_type == POS_STARTING ?
16868 16866 "starting position for recovery command" :
16869 16867 "expected position for recovery command",
16870 16868 &errinfo->ei_expected_pos);
16871 16869
16872 16870 rval = st_test_path_to_device(un);
16873 16871
16874 16872 ST_RECOV(ST_DEVINFO, st_label, CE_NOTE,
16875 16873 "st_recover called with %s, TUR returned %d\n",
16876 16874 errstatenames[errinfo->ei_error_type], rval);
16877 16875 /*
16878 16876 * If the drive responed to the TUR lets try and get it to sync
16879 16877 * any data it might have in the buffer.
16880 16878 */
16881 16879 if (rval == 0 && rcv->cmd_attrib->chg_tape_data) {
16882 16880 rval = st_rcmd(un, SCMD_WRITE_FILE_MARK, 0, SYNC_CMD);
16883 16881 if (rval) {
16884 16882 ST_RECOV(ST_DEVINFO, st_label, CE_NOTE,
16885 16883 "st_recover failed to flush, returned %d\n", rval);
16886 16884 st_recov_ret(un, errinfo, COMMAND_DONE_ERROR);
16887 16885 return;
16888 16886 }
16889 16887 }
16890 16888 switch (errinfo->ei_error_type) {
16891 16889 case ATTEMPT_RETRY:
16892 16890 case COMMAND_TIMEOUT:
16893 16891 case DEVICE_RESET:
16894 16892 case PATH_FAILED:
16895 16893 /*
16896 16894 * For now if we can't talk to the device we are done.
16897 16895 * If the drive is reserved we can try to get it back.
16898 16896 */
16899 16897 if (rval != 0 && rval != EACCES) {
16900 16898 st_recov_ret(un, errinfo, COMMAND_DONE_ERROR);
16901 16899 return;
16902 16900 }
16903 16901
16904 16902 /*
16905 16903 * If reservation conflict and do a preempt, fail it.
16906 16904 */
16907 16905 if ((un->un_rsvd_status &
16908 16906 (ST_APPLICATION_RESERVATIONS | ST_RESERVE)) != 0) {
16909 16907 if ((errinfo->ei_failed_pkt.pkt_cdbp[0] ==
16910 16908 SCMD_PERSISTENT_RESERVE_OUT) &&
16911 16909 (errinfo->ei_failed_pkt.pkt_cdbp[1] ==
16912 16910 ST_SA_SCSI3_PREEMPT) &&
16913 16911 (SCBP_C(&errinfo->ei_failed_pkt) ==
16914 16912 STATUS_RESERVATION_CONFLICT)) {
16915 16913 st_recov_ret(un, errinfo, COMMAND_DONE_ERROR);
16916 16914 return;
16917 16915 }
16918 16916 }
16919 16917
16920 16918 /*
16921 16919 * If we have already set a scsi II reserve and get a
16922 16920 * conflict on a scsi III type reserve fail without
16923 16921 * any attempt to recover.
16924 16922 */
16925 16923 if ((un->un_rsvd_status & ST_RESERVE | ST_PRESERVE_RESERVE) &&
16926 16924 (errinfo->ei_failed_pkt.pkt_cdbp[0] ==
16927 16925 SCMD_PERSISTENT_RESERVE_OUT) ||
16928 16926 (errinfo->ei_failed_pkt.pkt_cdbp[0] ==
16929 16927 SCMD_PERSISTENT_RESERVE_IN)) {
16930 16928 st_recov_ret(un, errinfo, COMMAND_DONE_EACCES);
16931 16929 return;
16932 16930 }
16933 16931
16934 16932 /*
16935 16933 * If scsi II lost reserve try and get it back.
16936 16934 */
16937 16935 if ((((un->un_rsvd_status &
16938 16936 (ST_LOST_RESERVE | ST_APPLICATION_RESERVATIONS)) ==
16939 16937 ST_LOST_RESERVE)) &&
16940 16938 (errinfo->ei_failed_pkt.pkt_cdbp[0] != SCMD_RELEASE)) {
16941 16939 rval = st_reserve_release(un, ST_RESERVE,
16942 16940 st_uscsi_rcmd);
16943 16941 if (rval != 0) {
16944 16942 if (st_take_ownership(un, st_uscsi_rcmd) != 0) {
16945 16943 st_recov_ret(un, errinfo,
16946 16944 COMMAND_DONE_EACCES);
16947 16945 return;
16948 16946 }
16949 16947 }
16950 16948 un->un_rsvd_status |= ST_RESERVE;
16951 16949 un->un_rsvd_status &= ~(ST_RELEASE | ST_LOST_RESERVE |
16952 16950 ST_RESERVATION_CONFLICT | ST_INITIATED_RESET);
16953 16951 }
16954 16952 rval = st_make_sure_mode_data_is_correct(un, st_uscsi_rcmd);
16955 16953 if (rval) {
16956 16954 st_recov_ret(un, errinfo, COMMAND_DONE_ERROR);
16957 16955 return;
16958 16956 }
16959 16957 break;
16960 16958 case DEVICE_TAMPER:
16961 16959 /*
16962 16960 * Check if the ASC/ASCQ says mode data has changed.
16963 16961 */
16964 16962 if ((errinfo->ei_failing_status.sts_sensedata.es_add_code ==
16965 16963 0x2a) &&
16966 16964 (errinfo->ei_failing_status.sts_sensedata.es_qual_code ==
16967 16965 0x01)) {
16968 16966 /*
16969 16967 * See if mode sense changed.
16970 16968 */
16971 16969 rval = st_make_sure_mode_data_is_correct(un,
16972 16970 st_uscsi_rcmd);
16973 16971 if (rval) {
16974 16972 st_recov_ret(un, errinfo, COMMAND_DONE_ERROR);
16975 16973 return;
16976 16974 }
16977 16975 }
16978 16976 /*
16979 16977 * if we have a media id and its not bogus.
16980 16978 * Check to see if it the same.
16981 16979 */
16982 16980 if (un->un_media_id != NULL && un->un_media_id != bogusID) {
16983 16981 rval = st_get_media_identification(un, st_uscsi_rcmd);
16984 16982 if (rval == ESPIPE) {
16985 16983 st_recov_ret(un, errinfo, COMMAND_DONE_EACCES);
16986 16984 return;
16987 16985 }
16988 16986 }
16989 16987 break;
16990 16988 default:
16991 16989 ST_DEBUG(ST_DEVINFO, st_label, CE_PANIC,
16992 16990 "Unhandled error type %s in st_recover() 0x%x\n",
16993 16991 errstatenames[errinfo->ei_error_type], com);
16994 16992 }
16995 16993
16996 16994 /*
16997 16995 * if command is retriable retry it.
16998 16996 * Special case here. The command attribute for SCMD_REQUEST_SENSE
16999 16997 * does not say that it is retriable. That because if you reissue a
17000 16998 * request sense and the target responds the sense data will have
17001 16999 * been consumed and no long be valid. If we get a busy status on
17002 17000 * request sense while the state is ST_STATE_SENSING this will
17003 17001 * reissue that pkt.
17004 17002 *
17005 17003 * XXX If this request sense gets sent to a different port then
17006 17004 * the original command that failed was sent on it will not get
17007 17005 * valid sense data for that command.
17008 17006 */
17009 17007 if (rcv->cmd_attrib->retriable || un->un_rqs_bp == bp) {
17010 17008 status = st_recover_reissue_pkt(un, &errinfo->ei_failed_pkt);
17011 17009
17012 17010 /*
17013 17011 * if drive doesn't support read position we are done
17014 17012 */
17015 17013 } else if (un->un_read_pos_type == NO_POS) {
17016 17014 status = COMMAND_DONE_ERROR;
17017 17015 /*
17018 17016 * If this command results in a changed tape position,
17019 17017 * lets see where we are.
17020 17018 */
17021 17019 } else if (rcv->cmd_attrib->chg_tape_pos) {
17022 17020 /*
17023 17021 * XXX May be a reason to choose a different type here.
17024 17022 * Long format has file position information.
17025 17023 * Short and Extended have information about whats
17026 17024 * in the buffer. St's positioning assumes in the buffer
17027 17025 * to be the same as on tape.
17028 17026 */
17029 17027 rval = st_compare_expected_position(un, errinfo,
17030 17028 rcv->cmd_attrib, &cur_pos);
17031 17029 if (rval == 0) {
17032 17030 status = COMMAND_DONE;
17033 17031 } else if (rval == EAGAIN) {
17034 17032 status = st_recover_reissue_pkt(un,
17035 17033 &errinfo->ei_failed_pkt);
17036 17034 } else {
17037 17035 status = COMMAND_DONE_ERROR;
17038 17036 }
17039 17037 } else {
17040 17038 ASSERT(0);
17041 17039 }
17042 17040
17043 17041 st_recov_ret(un, errinfo, status);
17044 17042 }
17045 17043
17046 17044 static void
17047 17045 st_recov_cb(struct scsi_pkt *pkt)
17048 17046 {
17049 17047 struct scsi_tape *un;
17050 17048 struct buf *bp;
17051 17049 recov_info *rcv;
17052 17050 errstate action = COMMAND_DONE_ERROR;
17053 17051 int timout = ST_TRAN_BUSY_TIMEOUT; /* short (default) timeout */
17054 17052
17055 17053 /*
17056 17054 * Get the buf from the packet.
17057 17055 */
17058 17056 rcv = pkt->pkt_private;
17059 17057 ASSERT(rcv->privatelen == sizeof (recov_info));
17060 17058 bp = rcv->cmd_bp;
17061 17059
17062 17060 /*
17063 17061 * get the unit from the buf.
17064 17062 */
17065 17063 un = ddi_get_soft_state(st_state, MTUNIT(bp->b_edev));
17066 17064 ASSERT(un != NULL);
17067 17065
17068 17066 ST_FUNC(ST_DEVINFO, st_recov_cb);
17069 17067
17070 17068 mutex_enter(ST_MUTEX);
17071 17069
17072 17070 ASSERT(bp == un->un_recov_buf);
17073 17071
17074 17072
17075 17073 switch (pkt->pkt_reason) {
17076 17074 case CMD_CMPLT:
17077 17075 if (un->un_arq_enabled && pkt->pkt_state & STATE_ARQ_DONE) {
17078 17076 action = st_handle_autosense(un, bp, &rcv->pos);
17079 17077 } else if ((SCBP(pkt)->sts_busy) ||
17080 17078 (SCBP(pkt)->sts_chk) ||
17081 17079 (SCBP(pkt)->sts_vu7)) {
17082 17080 action = st_check_error(un, pkt);
17083 17081 } else {
17084 17082 action = COMMAND_DONE;
17085 17083 }
17086 17084 break;
17087 17085 case CMD_TIMEOUT:
17088 17086 action = COMMAND_TIMEOUT;
17089 17087 break;
17090 17088 case CMD_TRAN_ERR:
17091 17089 action = QUE_COMMAND;
17092 17090 break;
17093 17091 case CMD_DEV_GONE:
17094 17092 if (un->un_multipath)
17095 17093 action = PATH_FAILED;
17096 17094 else
17097 17095 action = COMMAND_DONE_ERROR;
17098 17096 break;
17099 17097 default:
17100 17098 ST_DEBUG(ST_DEVINFO, st_label, CE_PANIC,
17101 17099 "pkt_reason not handled yet %s",
17102 17100 scsi_rname(pkt->pkt_reason));
17103 17101 action = COMMAND_DONE_ERROR;
17104 17102 }
17105 17103
17106 17104 /*
17107 17105 * check for undetected path failover.
17108 17106 */
17109 17107 if (un->un_multipath) {
17110 17108 if (scsi_pkt_allocated_correctly(pkt) &&
17111 17109 (un->un_last_path_instance != pkt->pkt_path_instance)) {
17112 17110 if (un->un_state > ST_STATE_OPENING) {
17113 17111 ST_RECOV(ST_DEVINFO, st_label, CE_NOTE,
17114 17112 "Failover detected in recovery, action is "
17115 17113 "%s\n", errstatenames[action]);
17116 17114 }
17117 17115 un->un_last_path_instance = pkt->pkt_path_instance;
17118 17116 }
17119 17117 }
17120 17118
17121 17119 ST_RECOV(ST_DEVINFO, st_label, CE_WARN,
17122 17120 "Recovery call back got %s status on %s\n",
17123 17121 errstatenames[action], st_print_scsi_cmd(pkt->pkt_cdbp[0]));
17124 17122
17125 17123 switch (action) {
17126 17124 case COMMAND_DONE:
17127 17125 break;
17128 17126
17129 17127 case COMMAND_DONE_EACCES:
17130 17128 bioerror(bp, EACCES);
17131 17129 break;
17132 17130
17133 17131 case COMMAND_DONE_ERROR_RECOVERED: /* XXX maybe wrong */
17134 17132 ASSERT(0);
17135 17133 break;
17136 17134
17137 17135 case COMMAND_TIMEOUT:
17138 17136 case COMMAND_DONE_ERROR:
17139 17137 bioerror(bp, EIO);
17140 17138 break;
17141 17139
17142 17140 case DEVICE_RESET:
17143 17141 case QUE_BUSY_COMMAND:
17144 17142 case PATH_FAILED:
17145 17143 /* longish timeout */
17146 17144 timout = ST_STATUS_BUSY_TIMEOUT;
17147 17145 /* FALLTHRU */
17148 17146 case QUE_COMMAND:
17149 17147 case DEVICE_TAMPER:
17150 17148 case ATTEMPT_RETRY:
17151 17149 /*
17152 17150 * let st_handle_intr_busy put this bp back on waitq and make
17153 17151 * checks to see if it is ok to requeue the command.
17154 17152 */
17155 17153 ST_DO_KSTATS(bp, kstat_runq_back_to_waitq);
17156 17154
17157 17155 /*
17158 17156 * Save the throttle before setting up the timeout
17159 17157 */
17160 17158 if (un->un_throttle) {
17161 17159 un->un_last_throttle = un->un_throttle;
17162 17160 }
17163 17161 mutex_exit(ST_MUTEX);
17164 17162 if (st_handle_intr_busy(un, bp, timout) == 0) {
17165 17163 return; /* timeout is setup again */
17166 17164 }
17167 17165 mutex_enter(ST_MUTEX);
17168 17166 un->un_pos.pmode = invalid;
17169 17167 un->un_err_resid = bp->b_resid = bp->b_bcount;
17170 17168 st_bioerror(bp, EIO);
17171 17169 st_set_pe_flag(un);
17172 17170 break;
17173 17171
17174 17172 default:
17175 17173 ST_DEBUG(ST_DEVINFO, st_label, CE_PANIC,
17176 17174 "Unhandled recovery state 0x%x\n", action);
17177 17175 un->un_pos.pmode = invalid;
17178 17176 un->un_err_resid = bp->b_resid = bp->b_bcount;
17179 17177 st_bioerror(bp, EIO);
17180 17178 st_set_pe_flag(un);
17181 17179 break;
17182 17180 }
17183 17181
17184 17182 st_done_and_mutex_exit(un, bp);
17185 17183 }
17186 17184
17187 17185 static int
17188 17186 st_rcmd(struct scsi_tape *un, int com, int64_t count, int wait)
17189 17187 {
17190 17188 struct buf *bp;
17191 17189 int err;
17192 17190
17193 17191 ST_FUNC(ST_DEVINFO, st_rcmd);
17194 17192
17195 17193 ST_DEBUG3(ST_DEVINFO, st_label, SCSI_DEBUG,
17196 17194 "st_rcmd(un = 0x%p, com = 0x%x, count = %"PRIx64", wait = %d)\n",
17197 17195 (void *)un, com, count, wait);
17198 17196
17199 17197 ASSERT(MUTEX_HELD(&un->un_sd->sd_mutex));
17200 17198 ASSERT(mutex_owned(ST_MUTEX));
17201 17199
17202 17200 #ifdef STDEBUG
17203 17201 if ((st_debug & 0x7)) {
17204 17202 st_debug_cmds(un, com, count, wait);
17205 17203 }
17206 17204 #endif
17207 17205
17208 17206 while (un->un_recov_buf_busy)
17209 17207 cv_wait(&un->un_recov_buf_cv, ST_MUTEX);
17210 17208 un->un_recov_buf_busy = 1;
17211 17209
17212 17210 bp = un->un_recov_buf;
17213 17211 bzero(bp, sizeof (buf_t));
17214 17212
17215 17213 bp->b_flags = (wait) ? B_BUSY : B_BUSY|B_ASYNC;
17216 17214
17217 17215 err = st_setup_cmd(un, bp, com, count);
17218 17216
17219 17217 un->un_recov_buf_busy = 0;
17220 17218
17221 17219 cv_signal(&un->un_recov_buf_cv);
17222 17220
17223 17221 return (err);
17224 17222 }
17225 17223
17226 17224 /* args used */
17227 17225 static int
17228 17226 st_uscsi_rcmd(struct scsi_tape *un, struct uscsi_cmd *ucmd, int flag)
17229 17227 {
17230 17228 int rval;
17231 17229 buf_t *bp;
17232 17230
17233 17231 ST_FUNC(ST_DEVINFO, st_uscsi_rcmd);
17234 17232 ASSERT(flag == FKIOCTL);
17235 17233
17236 17234 /*
17237 17235 * Get buffer resources...
17238 17236 */
17239 17237 while (un->un_recov_buf_busy)
17240 17238 cv_wait(&un->un_recov_buf_cv, ST_MUTEX);
17241 17239 un->un_recov_buf_busy = 1;
17242 17240
17243 17241 bp = un->un_recov_buf;
17244 17242 bzero(bp, sizeof (buf_t));
17245 17243
17246 17244 bp->b_forw = (struct buf *)(uintptr_t)ucmd->uscsi_cdb[0];
17247 17245 bp->b_back = (struct buf *)ucmd;
17248 17246
17249 17247 mutex_exit(ST_MUTEX);
17250 17248 rval = scsi_uscsi_handle_cmd(un->un_dev, UIO_SYSSPACE, ucmd,
17251 17249 st_strategy, bp, NULL);
17252 17250 mutex_enter(ST_MUTEX);
17253 17251
17254 17252 ucmd->uscsi_resid = bp->b_resid;
17255 17253
17256 17254 /*
17257 17255 * Free resources
17258 17256 */
17259 17257 un->un_recov_buf_busy = 0;
17260 17258 cv_signal(&un->un_recov_buf_cv);
17261 17259
17262 17260 return (rval);
17263 17261 }
17264 17262
17265 17263 /*
17266 17264 * Add data to scsi_pkt to help know what to do if the command fails.
17267 17265 */
17268 17266 static void
17269 17267 st_add_recovery_info_to_pkt(struct scsi_tape *un, buf_t *bp,
17270 17268 struct scsi_pkt *pkt)
17271 17269 {
17272 17270 uint64_t count;
17273 17271 recov_info *rinfo = (recov_info *)pkt->pkt_private;
17274 17272
17275 17273 ST_FUNC(ST_DEVINFO, st_add_recovery_info_to_pkt);
17276 17274
17277 17275 ASSERT(rinfo->privatelen == sizeof (pkt_info) ||
17278 17276 rinfo->privatelen == sizeof (recov_info));
17279 17277
17280 17278 SET_BP_PKT(bp, pkt);
17281 17279 rinfo->cmd_bp = bp;
17282 17280
17283 17281 if (rinfo->privatelen != sizeof (recov_info)) {
17284 17282 return;
17285 17283 }
17286 17284
17287 17285 rinfo->cmd_bp = bp;
17288 17286
17289 17287 rinfo->cmd_attrib = NULL;
17290 17288
17291 17289 /*
17292 17290 * lookup the command attributes and add them to the recovery info.
17293 17291 */
17294 17292 rinfo->cmd_attrib = st_lookup_cmd_attribute(pkt->pkt_cdbp[0]);
17295 17293
17296 17294 ASSERT(rinfo->cmd_attrib);
17297 17295
17298 17296 /*
17299 17297 * For commands that there is no way to figure the expected position
17300 17298 * once completed, we save the position the command was started from
17301 17299 * so that if they fail we can position back and try again.
17302 17300 * This has already been done in st_cmd() or st_iscsi_cmd().
17303 17301 */
17304 17302 if (rinfo->cmd_attrib->recov_pos_type == POS_STARTING) {
17305 17303 /* save current position as the starting position. */
17306 17304 COPY_POS(&rinfo->pos, &un->un_pos);
17307 17305 un->un_running.pmode = invalid;
17308 17306 return;
17309 17307 }
17310 17308
17311 17309 /*
17312 17310 * Don't want to update the running position for recovery.
17313 17311 */
17314 17312 if (bp == un->un_recov_buf) {
17315 17313 rinfo->pos.pmode = un->un_running.pmode;
17316 17314 return;
17317 17315 }
17318 17316 /*
17319 17317 * If running position is invalid copy the current position.
17320 17318 * Running being set invalid means we are not in a read, write
17321 17319 * or write filemark sequence.
17322 17320 * We'll copy the current position and start from there.
17323 17321 */
17324 17322 if (un->un_running.pmode == invalid) {
17325 17323 COPY_POS(&un->un_running, &un->un_pos);
17326 17324 COPY_POS(&rinfo->pos, &un->un_running);
17327 17325 } else {
17328 17326 COPY_POS(&rinfo->pos, &un->un_running);
17329 17327 if (rinfo->pos.pmode == legacy) {
17330 17328 /*
17331 17329 * Always should be more logical blocks then
17332 17330 * data blocks and files marks.
17333 17331 */
17334 17332 ASSERT((rinfo->pos.blkno >= 0) ?
17335 17333 rinfo->pos.lgclblkno >=
17336 17334 (rinfo->pos.blkno + rinfo->pos.fileno) : 1);
17337 17335 }
17338 17336 }
17339 17337
17340 17338 /*
17341 17339 * If the command is not expected to change the drive position
17342 17340 * then the running position should be the expected position.
17343 17341 */
17344 17342 if (rinfo->cmd_attrib->chg_tape_pos == 0) {
17345 17343 ASSERT(rinfo->cmd_attrib->chg_tape_direction == DIR_NONE);
17346 17344 return;
17347 17345 }
17348 17346
17349 17347 if (rinfo->cmd_attrib->explicit_cmd_set) {
17350 17348 ASSERT(rinfo->pos.pmode != invalid);
17351 17349 ASSERT(rinfo->cmd_attrib->get_cnt);
17352 17350 count = rinfo->cmd_attrib->get_cnt(pkt->pkt_cdbp);
17353 17351 /*
17354 17352 * This is a user generated CDB.
17355 17353 */
17356 17354 if (bp == un->un_sbufp) {
17357 17355 uint64_t lbn;
17358 17356
17359 17357 lbn = rinfo->cmd_attrib->get_lba(pkt->pkt_cdbp);
17360 17358
17361 17359 /*
17362 17360 * See if this CDB will generate a locate or change
17363 17361 * partition.
17364 17362 */
17365 17363 if ((lbn != un->un_running.lgclblkno) ||
17366 17364 (pkt->pkt_cdbp[3] != un->un_running.partition)) {
17367 17365 rinfo->pos.partition = pkt->pkt_cdbp[3];
17368 17366 rinfo->pos.pmode = logical;
17369 17367 rinfo->pos.lgclblkno = lbn;
17370 17368 un->un_running.partition = pkt->pkt_cdbp[3];
17371 17369 un->un_running.pmode = logical;
17372 17370 un->un_running.lgclblkno = lbn;
17373 17371 }
17374 17372 } else {
17375 17373 uint64_t lbn = un->un_running.lgclblkno;
17376 17374
17377 17375 pkt->pkt_cdbp[3] = (uchar_t)un->un_running.partition;
17378 17376
17379 17377 pkt->pkt_cdbp[4] = (uchar_t)(lbn >> 56);
17380 17378 pkt->pkt_cdbp[5] = (uchar_t)(lbn >> 48);
17381 17379 pkt->pkt_cdbp[6] = (uchar_t)(lbn >> 40);
17382 17380 pkt->pkt_cdbp[7] = (uchar_t)(lbn >> 32);
17383 17381 pkt->pkt_cdbp[8] = (uchar_t)(lbn >> 24);
17384 17382 pkt->pkt_cdbp[9] = (uchar_t)(lbn >> 16);
17385 17383 pkt->pkt_cdbp[10] = (uchar_t)(lbn >> 8);
17386 17384 pkt->pkt_cdbp[11] = (uchar_t)(lbn);
17387 17385 }
17388 17386 rinfo->pos.lgclblkno += count;
17389 17387 rinfo->pos.blkno += count;
17390 17388 un->un_running.lgclblkno += count;
17391 17389 return;
17392 17390 }
17393 17391
17394 17392 if (rinfo->cmd_attrib->chg_tape_pos) {
17395 17393
17396 17394 /* should not have got an invalid position from running. */
17397 17395 if (un->un_mediastate == MTIO_INSERTED) {
17398 17396 ASSERT(rinfo->pos.pmode != invalid);
17399 17397 }
17400 17398
17401 17399 /* should have either a get count or or get lba function */
17402 17400 ASSERT(rinfo->cmd_attrib->get_cnt != NULL ||
17403 17401 rinfo->cmd_attrib->get_lba != NULL);
17404 17402
17405 17403 /* only explicit commands have both and they're handled above */
17406 17404 ASSERT(!(rinfo->cmd_attrib->get_cnt != NULL &&
17407 17405 rinfo->cmd_attrib->get_lba != NULL));
17408 17406
17409 17407 /* if it has a get count function */
17410 17408 if (rinfo->cmd_attrib->get_cnt != NULL) {
17411 17409 count = rinfo->cmd_attrib->get_cnt(pkt->pkt_cdbp);
17412 17410 if (count == 0) {
17413 17411 return;
17414 17412 }
17415 17413 /*
17416 17414 * Changes position but doesn't transfer data.
17417 17415 * i.e. rewind, write_file_mark and load.
17418 17416 */
17419 17417 if (rinfo->cmd_attrib->transfers_data == TRAN_NONE) {
17420 17418 switch (rinfo->cmd_attrib->chg_tape_direction) {
17421 17419 case DIR_NONE: /* Erase */
17422 17420 ASSERT(rinfo->cmd_attrib->cmd ==
17423 17421 SCMD_ERASE);
17424 17422 break;
17425 17423 case DIR_FORW: /* write_file_mark */
17426 17424 rinfo->pos.fileno += count;
17427 17425 rinfo->pos.lgclblkno += count;
17428 17426 rinfo->pos.blkno = 0;
17429 17427 un->un_running.fileno += count;
17430 17428 un->un_running.lgclblkno += count;
17431 17429 un->un_running.blkno = 0;
17432 17430 break;
17433 17431 case DIR_REVC: /* rewind */
17434 17432 rinfo->pos.fileno = 0;
17435 17433 rinfo->pos.lgclblkno = 0;
17436 17434 rinfo->pos.blkno = 0;
17437 17435 rinfo->pos.eof = ST_NO_EOF;
17438 17436 rinfo->pos.pmode = legacy;
17439 17437 un->un_running.fileno = 0;
17440 17438 un->un_running.lgclblkno = 0;
17441 17439 un->un_running.blkno = 0;
17442 17440 un->un_running.eof = ST_NO_EOF;
17443 17441 if (un->un_running.pmode != legacy)
17444 17442 un->un_running.pmode = legacy;
17445 17443 break;
17446 17444 case DIR_EITH: /* Load unload */
17447 17445 ASSERT(rinfo->cmd_attrib->cmd ==
17448 17446 SCMD_LOAD);
17449 17447 switch (count & (LD_LOAD | LD_RETEN |
17450 17448 LD_RETEN | LD_HOLD)) {
17451 17449 case LD_UNLOAD:
17452 17450 case LD_RETEN:
17453 17451 case LD_HOLD:
17454 17452 case LD_LOAD | LD_HOLD:
17455 17453 case LD_EOT | LD_HOLD:
17456 17454 case LD_RETEN | LD_HOLD:
17457 17455 rinfo->pos.pmode = invalid;
17458 17456 un->un_running.pmode = invalid;
17459 17457 break;
17460 17458 case LD_EOT:
17461 17459 case LD_LOAD | LD_EOT:
17462 17460 rinfo->pos.eof = ST_EOT;
17463 17461 rinfo->pos.pmode = invalid;
17464 17462 un->un_running.eof = ST_EOT;
17465 17463 un->un_running.pmode = invalid;
17466 17464 break;
17467 17465 case LD_LOAD:
17468 17466 case LD_RETEN | LD_LOAD:
17469 17467 rinfo->pos.fileno = 0;
17470 17468 rinfo->pos.lgclblkno = 0;
17471 17469 rinfo->pos.blkno = 0;
17472 17470 rinfo->pos.eof = ST_NO_EOF;
17473 17471 rinfo->pos.pmode = legacy;
17474 17472 un->un_running.fileno = 0;
17475 17473 un->un_running.lgclblkno = 0;
17476 17474 un->un_running.blkno = 0;
17477 17475 un->un_running.eof = ST_NO_EOF;
17478 17476 break;
17479 17477 default:
17480 17478 ASSERT(0);
17481 17479 }
17482 17480 break;
17483 17481 default:
17484 17482 ASSERT(0);
17485 17483 break;
17486 17484 }
17487 17485 } else {
17488 17486 /*
17489 17487 * Changes position and does transfer data.
17490 17488 * i.e. read or write.
17491 17489 */
17492 17490 switch (rinfo->cmd_attrib->chg_tape_direction) {
17493 17491 case DIR_FORW:
17494 17492 rinfo->pos.lgclblkno += count;
17495 17493 rinfo->pos.blkno += count;
17496 17494 un->un_running.lgclblkno += count;
17497 17495 un->un_running.blkno += count;
17498 17496 break;
17499 17497 case DIR_REVC:
17500 17498 rinfo->pos.lgclblkno -= count;
17501 17499 rinfo->pos.blkno -= count;
17502 17500 un->un_running.lgclblkno -= count;
17503 17501 un->un_running.blkno -= count;
17504 17502 break;
17505 17503 default:
17506 17504 ASSERT(0);
17507 17505 break;
17508 17506 }
17509 17507 }
17510 17508 } else if (rinfo->cmd_attrib->get_lba != NULL) {
17511 17509 /* Have a get LBA fuction. i.e. Locate */
17512 17510 ASSERT(rinfo->cmd_attrib->chg_tape_direction ==
17513 17511 DIR_EITH);
17514 17512 count = rinfo->cmd_attrib->get_lba(pkt->pkt_cdbp);
17515 17513 un->un_running.lgclblkno = count;
17516 17514 un->un_running.blkno = 0;
17517 17515 un->un_running.fileno = 0;
17518 17516 un->un_running.pmode = logical;
17519 17517 rinfo->pos.lgclblkno = count;
17520 17518 rinfo->pos.pmode = invalid;
17521 17519 } else {
17522 17520 ASSERT(0);
17523 17521 }
17524 17522 return;
17525 17523 }
17526 17524
17527 17525 ST_CDB(ST_DEVINFO, "Unhanded CDB for position prediction",
17528 17526 (char *)pkt->pkt_cdbp);
17529 17527
17530 17528 }
17531 17529
17532 17530 static int
17533 17531 st_make_sure_mode_data_is_correct(struct scsi_tape *un, ubufunc_t ubf)
17534 17532 {
17535 17533 int rval;
17536 17534
17537 17535 ST_FUNC(ST_DEVINFO, st_make_sure_mode_data_is_correct);
17538 17536
17539 17537 /*
17540 17538 * check to see if mode data has changed.
17541 17539 */
17542 17540 rval = st_check_mode_for_change(un, ubf);
17543 17541 if (rval) {
17544 17542 rval = st_gen_mode_select(un, ubf, un->un_mspl,
17545 17543 sizeof (struct seq_mode));
17546 17544 }
17547 17545 if (un->un_tlr_flag != TLR_NOT_SUPPORTED) {
17548 17546 rval |= st_set_target_TLR_mode(un, ubf);
17549 17547 }
17550 17548 return (rval);
17551 17549 }
17552 17550
17553 17551 static int
17554 17552 st_check_mode_for_change(struct scsi_tape *un, ubufunc_t ubf)
17555 17553 {
17556 17554 struct seq_mode *current;
17557 17555 int rval;
17558 17556 int i;
17559 17557 caddr_t this;
17560 17558 caddr_t that;
17561 17559
17562 17560 ST_FUNC(ST_DEVINFO, st_check_mode_for_change);
17563 17561
17564 17562 /* recovery called with mode tamper before mode selection */
17565 17563 if (un->un_comp_page == (ST_DEV_DATACOMP_PAGE | ST_DEV_CONFIG_PAGE)) {
17566 17564 ST_RECOV(ST_DEVINFO, st_label, CE_NOTE,
17567 17565 "Mode Select not done yet");
17568 17566 return (0);
17569 17567 }
17570 17568
17571 17569 current = kmem_zalloc(sizeof (struct seq_mode), KM_SLEEP);
17572 17570
17573 17571 rval = st_gen_mode_sense(un, ubf, un->un_comp_page, current,
17574 17572 sizeof (struct seq_mode));
17575 17573 if (rval != 0) {
17576 17574 ST_RECOV(ST_DEVINFO, st_label, CE_NOTE,
17577 17575 "Mode Sense for mode verification failed");
17578 17576 kmem_free(current, sizeof (struct seq_mode));
17579 17577 return (rval);
17580 17578 }
17581 17579
17582 17580 this = (caddr_t)current;
17583 17581 that = (caddr_t)un->un_mspl;
17584 17582
17585 17583 rval = bcmp(this, that, sizeof (struct seq_mode));
17586 17584 if (rval == 0) {
17587 17585 ST_RECOV(ST_DEVINFO, st_label, CE_NOTE,
17588 17586 "Found no changes in mode data");
17589 17587 }
17590 17588 #ifdef STDEBUG
17591 17589 else {
17592 17590 for (i = 1; i < sizeof (struct seq_mode); i++) {
17593 17591 if (this[i] != that[i]) {
17594 17592 ST_RECOV(ST_DEVINFO, st_label, CE_CONT,
17595 17593 "sense data changed at byte %d was "
17596 17594 "0x%x now 0x%x", i,
17597 17595 (uchar_t)that[i], (uchar_t)this[i]);
17598 17596 }
17599 17597 }
17600 17598 }
17601 17599 #endif
17602 17600 kmem_free(current, sizeof (struct seq_mode));
17603 17601
17604 17602 return (rval);
17605 17603 }
17606 17604
17607 17605 static int
17608 17606 st_test_path_to_device(struct scsi_tape *un)
17609 17607 {
17610 17608 int rval = 0;
17611 17609 int limit = st_retry_count;
17612 17610
17613 17611 ST_FUNC(ST_DEVINFO, st_test_path_to_device);
17614 17612
17615 17613 /*
17616 17614 * XXX Newer drives may not RESEVATION CONFLICT a TUR.
17617 17615 */
17618 17616 do {
17619 17617 if (rval != 0) {
17620 17618 mutex_exit(ST_MUTEX);
17621 17619 delay(drv_usectohz(1000000));
17622 17620 mutex_enter(ST_MUTEX);
17623 17621 }
17624 17622 rval = st_rcmd(un, SCMD_TEST_UNIT_READY, 0, SYNC_CMD);
17625 17623 ST_RECOV(ST_DEVINFO, st_label, CE_NOTE,
17626 17624 "ping TUR returned 0x%x", rval);
17627 17625 limit--;
17628 17626 } while (((rval == EACCES) || (rval == EBUSY)) && limit);
17629 17627
17630 17628 if (un->un_status == KEY_NOT_READY || un->un_mediastate == MTIO_EJECTED)
17631 17629 rval = 0;
17632 17630
17633 17631 return (rval);
17634 17632 }
17635 17633
17636 17634 /*
17637 17635 * Does read position using recov_buf and doesn't update un_pos.
17638 17636 * Does what ever kind of read position you want.
17639 17637 */
17640 17638 static int
17641 17639 st_recovery_read_pos(struct scsi_tape *un, read_p_types type,
17642 17640 read_pos_data_t *raw)
17643 17641 {
17644 17642 int rval;
17645 17643 struct uscsi_cmd cmd;
17646 17644 struct scsi_arq_status status;
17647 17645 char cdb[CDB_GROUP1];
17648 17646
17649 17647 ST_FUNC(ST_DEVINFO, st_recovery_read_pos);
17650 17648 bzero(&cmd, sizeof (cmd));
17651 17649
17652 17650 cdb[0] = SCMD_READ_POSITION;
17653 17651 cdb[1] = type;
17654 17652 cdb[2] = 0;
17655 17653 cdb[3] = 0;
17656 17654 cdb[4] = 0;
17657 17655 cdb[5] = 0;
17658 17656 cdb[6] = 0;
17659 17657 cdb[7] = 0;
17660 17658 cdb[8] = (type == EXT_POS) ? 28 : 0;
17661 17659 cdb[9] = 0;
17662 17660
17663 17661 cmd.uscsi_flags = USCSI_READ | USCSI_RQENABLE;
17664 17662 cmd.uscsi_timeout = un->un_dp->non_motion_timeout;
17665 17663 cmd.uscsi_cdb = cdb;
17666 17664 cmd.uscsi_cdblen = sizeof (cdb);
17667 17665 cmd.uscsi_rqlen = sizeof (status);
17668 17666 cmd.uscsi_rqbuf = (caddr_t)&status;
17669 17667 cmd.uscsi_bufaddr = (caddr_t)raw;
17670 17668 switch (type) {
17671 17669 case SHORT_POS:
17672 17670 cmd.uscsi_buflen = sizeof (tape_position_t);
17673 17671 break;
17674 17672 case LONG_POS:
17675 17673 cmd.uscsi_buflen = sizeof (tape_position_long_t);
17676 17674 break;
17677 17675 case EXT_POS:
17678 17676 cmd.uscsi_buflen = sizeof (tape_position_ext_t);
17679 17677 break;
17680 17678 default:
17681 17679 ASSERT(0);
17682 17680 }
17683 17681
17684 17682 rval = st_uscsi_rcmd(un, &cmd, FKIOCTL);
17685 17683 if (cmd.uscsi_status) {
17686 17684 rval = EIO;
17687 17685 }
17688 17686 return (rval);
17689 17687 }
17690 17688
17691 17689 static int
17692 17690 st_recovery_get_position(struct scsi_tape *un, tapepos_t *read,
17693 17691 read_pos_data_t *raw)
17694 17692 {
17695 17693 int rval;
17696 17694 read_p_types type = un->un_read_pos_type;
17697 17695
17698 17696 ST_FUNC(ST_DEVINFO, st_recovery_get_position);
17699 17697
17700 17698 do {
17701 17699 rval = st_recovery_read_pos(un, type, raw);
17702 17700 if (rval != 0) {
17703 17701 switch (type) {
17704 17702 case SHORT_POS:
17705 17703 type = NO_POS;
17706 17704 break;
17707 17705
17708 17706 case LONG_POS:
17709 17707 type = EXT_POS;
17710 17708 break;
17711 17709
17712 17710 case EXT_POS:
17713 17711 type = SHORT_POS;
17714 17712 break;
17715 17713
17716 17714 default:
17717 17715 type = LONG_POS;
17718 17716 break;
17719 17717
17720 17718 }
17721 17719 } else {
17722 17720 if (type != un->un_read_pos_type) {
17723 17721 un->un_read_pos_type = type;
17724 17722 }
17725 17723 break;
17726 17724 }
17727 17725 } while (type != NO_POS);
17728 17726
17729 17727 if (rval == 0) {
17730 17728 rval = st_interpret_read_pos(un, read, type,
17731 17729 sizeof (read_pos_data_t), (caddr_t)raw, 1);
17732 17730 }
17733 17731 return (rval);
17734 17732 }
17735 17733
17736 17734 /*
17737 17735 * based on the command do we retry, continue or give up?
17738 17736 * possable return values?
17739 17737 * zero do nothing looks fine.
17740 17738 * EAGAIN retry.
17741 17739 * EIO failed makes no sense.
17742 17740 */
17743 17741 static int
17744 17742 st_compare_expected_position(struct scsi_tape *un, st_err_info *ei,
17745 17743 cmd_attribute const * cmd_att, tapepos_t *read)
17746 17744 {
17747 17745 int rval;
17748 17746 read_pos_data_t *readp_datap;
17749 17747
17750 17748 ST_FUNC(ST_DEVINFO, st_compare_expected_position);
17751 17749
17752 17750 ASSERT(un != NULL);
17753 17751 ASSERT(ei != NULL);
17754 17752 ASSERT(read != NULL);
17755 17753 ASSERT(cmd_att->chg_tape_pos);
17756 17754
17757 17755 COPY_POS(read, &ei->ei_expected_pos);
17758 17756
17759 17757 readp_datap = kmem_zalloc(sizeof (read_pos_data_t), KM_SLEEP);
17760 17758
17761 17759 rval = st_recovery_get_position(un, read, readp_datap);
17762 17760
17763 17761 kmem_free(readp_datap, sizeof (read_pos_data_t));
17764 17762
17765 17763 if (rval != 0) {
17766 17764 return (EIO);
17767 17765 }
17768 17766
17769 17767 ST_POS(ST_DEVINFO, "st_compare_expected_position", read);
17770 17768
17771 17769 if ((read->pmode == invalid) ||
17772 17770 (ei->ei_expected_pos.pmode == invalid)) {
17773 17771 return (EIO);
17774 17772 }
17775 17773
17776 17774 /*
17777 17775 * Command that changes tape position and have an expected position
17778 17776 * if it were to chave completed sucessfully.
17779 17777 */
17780 17778 if (cmd_att->recov_pos_type == POS_EXPECTED) {
17781 17779 uint32_t count;
17782 17780 int64_t difference;
17783 17781 uchar_t reposition = 0;
17784 17782
17785 17783 ASSERT(cmd_att->get_cnt);
17786 17784 count = cmd_att->get_cnt(ei->ei_failed_pkt.pkt_cdbp);
17787 17785
17788 17786 ST_RECOV(ST_DEVINFO, st_label, CE_NOTE,
17789 17787 "Got count from CDB and it was %d\n", count);
17790 17788
17791 17789 /*
17792 17790 * At expected?
17793 17791 */
17794 17792 if (read->lgclblkno == ei->ei_expected_pos.lgclblkno) {
17795 17793 ST_RECOV(ST_DEVINFO, st_label, CE_NOTE,
17796 17794 "Found drive to be at expected position\n");
17797 17795
17798 17796 /*
17799 17797 * If the command should move tape and it got a busy
17800 17798 * it shouldn't be in the expected position.
17801 17799 */
17802 17800 if (ei->ei_failing_status.sts_status.sts_busy != 0) {
17803 17801 reposition = 1;
17804 17802
17805 17803 /*
17806 17804 * If the command doesn't transfer data should be good.
17807 17805 */
17808 17806 } else if (cmd_att->transfers_data == TRAN_NONE) {
17809 17807 return (0); /* Good */
17810 17808
17811 17809 /*
17812 17810 * Command transfers data, should have done so.
17813 17811 */
17814 17812 } else if (ei->ei_failed_pkt.pkt_state &
17815 17813 STATE_XFERRED_DATA) {
17816 17814 return (0); /* Good */
17817 17815 } else {
17818 17816 reposition = 1;
17819 17817 }
17820 17818 }
17821 17819
17822 17820 if (cmd_att->chg_tape_direction == DIR_FORW) {
17823 17821 difference =
17824 17822 ei->ei_expected_pos.lgclblkno - read->lgclblkno;
17825 17823
17826 17824 ST_RECOV(ST_DEVINFO, st_label, CE_NOTE,
17827 17825 "difference between expected and actual is %"
17828 17826 PRId64"\n", difference);
17829 17827 if (count == difference && reposition == 0) {
17830 17828 ST_RECOV(ST_DEVINFO, st_label, CE_NOTE,
17831 17829 "Found failed FORW command, retrying\n");
17832 17830 return (EAGAIN);
17833 17831 }
17834 17832
17835 17833 /*
17836 17834 * If rewound or somewhere between the starting position
17837 17835 * and the expected position (partial read or write).
17838 17836 * Locate to the starting position and try the whole
17839 17837 * thing over again.
17840 17838 */
17841 17839 if ((read->lgclblkno == 0) ||
17842 17840 ((difference > 0) && (difference < count))) {
17843 17841 rval = st_logical_block_locate(un,
17844 17842 st_uscsi_rcmd, read,
17845 17843 ei->ei_expected_pos.lgclblkno - count,
17846 17844 ei->ei_expected_pos.partition);
17847 17845 if (rval == 0) {
17848 17846 ST_RECOV(ST_DEVINFO, st_label,
17849 17847 CE_NOTE, "reestablished FORW"
17850 17848 " command retrying\n");
17851 17849 return (EAGAIN);
17852 17850 }
17853 17851 /*
17854 17852 * This handles flushed read ahead on the drive or
17855 17853 * an aborted read that presents as a busy and advanced
17856 17854 * the tape position.
17857 17855 */
17858 17856 } else if ((cmd_att->transfers_data == TRAN_READ) &&
17859 17857 ((difference < 0) || (reposition == 1))) {
17860 17858 rval = st_logical_block_locate(un,
17861 17859 st_uscsi_rcmd, read,
17862 17860 ei->ei_expected_pos.lgclblkno - count,
17863 17861 ei->ei_expected_pos.partition);
17864 17862 if (rval == 0) {
17865 17863 ST_RECOV(ST_DEVINFO, st_label,
17866 17864 CE_NOTE, "reestablished FORW"
17867 17865 " read command retrying\n");
17868 17866 return (EAGAIN);
17869 17867 }
17870 17868 /*
17871 17869 * XXX swag seeing difference of 2 on write filemark.
17872 17870 * If the space to the starting position works on a
17873 17871 * write that means the previous write made it to tape.
17874 17872 * If not we lost data and have to give up.
17875 17873 *
17876 17874 * The plot thickens. Now I am attempting to cover a
17877 17875 * count of 1 and a differance of 2 on a write.
17878 17876 */
17879 17877 } else if ((difference > count) || (reposition == 1)) {
17880 17878 rval = st_logical_block_locate(un,
17881 17879 st_uscsi_rcmd, read,
17882 17880 ei->ei_expected_pos.lgclblkno - count,
17883 17881 ei->ei_expected_pos.partition);
17884 17882 if (rval == 0) {
17885 17883 ST_RECOV(ST_DEVINFO, st_label,
17886 17884 CE_NOTE, "reestablished FORW"
17887 17885 " write command retrying\n");
17888 17886 return (EAGAIN);
17889 17887 }
17890 17888 ST_RECOV(ST_DEVINFO, st_label, CE_NOTE,
17891 17889 "Seek to block %"PRId64" returned %d\n",
17892 17890 ei->ei_expected_pos.lgclblkno - count,
17893 17891 rval);
17894 17892 } else {
17895 17893 ST_RECOV(ST_DEVINFO, st_label, CE_NOTE,
17896 17894 "Not expected transfers_data = %d "
17897 17895 "difference = %"PRId64,
17898 17896 cmd_att->transfers_data, difference);
17899 17897 }
17900 17898
17901 17899 return (EIO);
17902 17900
17903 17901 } else if (cmd_att->chg_tape_direction == DIR_REVC) {
17904 17902 /* Don't think we can write backwards */
17905 17903 ASSERT(cmd_att->transfers_data != TRAN_WRTE);
17906 17904 difference =
17907 17905 read->lgclblkno - ei->ei_expected_pos.lgclblkno;
17908 17906 ST_RECOV(ST_DEVINFO, st_label, CE_NOTE,
17909 17907 "difference between expected and actual is %"
17910 17908 PRId64"\n", difference);
17911 17909 if (count == difference && reposition == 0) {
17912 17910 ST_RECOV(ST_DEVINFO, st_label, CE_NOTE,
17913 17911 "Found failed REVC command, retrying\n");
17914 17912 return (EAGAIN);
17915 17913 }
17916 17914 if ((read->lgclblkno == 0) ||
17917 17915 ((difference > 0) && (difference < count))) {
17918 17916 rval = st_logical_block_locate(un,
17919 17917 st_uscsi_rcmd, read,
17920 17918 ei->ei_expected_pos.lgclblkno + count,
17921 17919 ei->ei_expected_pos.partition);
17922 17920 if (rval == 0) {
17923 17921 ST_RECOV(ST_DEVINFO, st_label,
17924 17922 CE_NOTE, "reestablished REVC"
17925 17923 " command retrying\n");
17926 17924 return (EAGAIN);
17927 17925 }
17928 17926 /* This handles read ahead in reverse direction */
17929 17927 } else if ((cmd_att->transfers_data == TRAN_READ) &&
17930 17928 (difference < 0) || (reposition == 1)) {
17931 17929 rval = st_logical_block_locate(un,
17932 17930 st_uscsi_rcmd, read,
17933 17931 ei->ei_expected_pos.lgclblkno - count,
17934 17932 ei->ei_expected_pos.partition);
17935 17933 if (rval == 0) {
17936 17934 ST_RECOV(ST_DEVINFO, st_label,
17937 17935 CE_NOTE, "reestablished REVC"
17938 17936 " read command retrying\n");
17939 17937 return (EAGAIN);
17940 17938 }
17941 17939 } else {
17942 17940 ST_RECOV(ST_DEVINFO, st_label, CE_NOTE,
17943 17941 "Not expected transfers_data = %d "
17944 17942 "difference = %"PRId64,
17945 17943 cmd_att->transfers_data, difference);
17946 17944 }
17947 17945 return (EIO);
17948 17946
17949 17947 } else {
17950 17948 /*
17951 17949 * Commands that change tape position either
17952 17950 * direction or don't change position should not
17953 17951 * get here.
17954 17952 */
17955 17953 ASSERT(0);
17956 17954 }
17957 17955 ST_RECOV(ST_DEVINFO, st_label, CE_NOTE,
17958 17956 "Didn't find a recoverable position, Failing\n");
17959 17957
17960 17958 /*
17961 17959 * Command that changes tape position and can only be recovered
17962 17960 * by going back to the point of origin and retrying.
17963 17961 *
17964 17962 * Example SCMD_SPACE.
17965 17963 */
17966 17964 } else if (cmd_att->recov_pos_type == POS_STARTING) {
17967 17965 /*
17968 17966 * This type of command stores the starting position.
17969 17967 * If the read position is the starting position,
17970 17968 * reissue the command.
17971 17969 */
17972 17970 if (ei->ei_expected_pos.lgclblkno == read->lgclblkno) {
17973 17971 ST_RECOV(ST_DEVINFO, st_label, CE_NOTE,
17974 17972 "Found Space command at starting position, "
17975 17973 "Reissuing\n");
17976 17974 return (EAGAIN);
17977 17975 }
17978 17976 /*
17979 17977 * Not in the position that the command was originally issued,
17980 17978 * Attempt to locate to that position.
17981 17979 */
17982 17980 rval = st_logical_block_locate(un, st_uscsi_rcmd, read,
17983 17981 ei->ei_expected_pos.lgclblkno,
17984 17982 ei->ei_expected_pos.partition);
17985 17983 if (rval) {
17986 17984 ST_RECOV(ST_DEVINFO, st_label, CE_NOTE,
17987 17985 "Found Space at an unexpected position and locate "
17988 17986 "back to starting position failed\n");
17989 17987 return (EIO);
17990 17988 }
17991 17989 ST_RECOV(ST_DEVINFO, st_label, CE_NOTE,
17992 17990 "Found Space at an unexpected position and locate "
17993 17991 "back to starting position worked, Reissuing\n");
17994 17992 return (EAGAIN);
17995 17993 }
17996 17994 st_print_position(ST_DEVINFO, st_label, CE_NOTE,
17997 17995 "Unhandled attribute/expected position", &ei->ei_expected_pos);
17998 17996 st_print_position(ST_DEVINFO, st_label, CE_NOTE,
17999 17997 "Read position above did not make sense", read);
18000 17998 ASSERT(0);
18001 17999 return (EIO);
18002 18000 }
18003 18001
18004 18002 static errstate
18005 18003 st_recover_reissue_pkt(struct scsi_tape *un, struct scsi_pkt *oldpkt)
18006 18004 {
18007 18005 buf_t *bp;
18008 18006 buf_t *pkt_bp;
18009 18007 struct scsi_pkt *newpkt;
18010 18008 cmd_attribute const *attrib;
18011 18009 recov_info *rcv = oldpkt->pkt_private;
18012 18010 uint_t cdblen;
18013 18011 int queued = 0;
18014 18012 int rval;
18015 18013 int flags = 0;
18016 18014 int stat_size =
18017 18015 (un->un_arq_enabled ? sizeof (struct scsi_arq_status) : 1);
18018 18016
18019 18017 ST_FUNC(ST_DEVINFO, st_recover_reissue_pkt);
18020 18018
18021 18019 bp = rcv->cmd_bp;
18022 18020
18023 18021 if (rcv->privatelen == sizeof (recov_info)) {
18024 18022 attrib = rcv->cmd_attrib;
18025 18023 } else {
18026 18024 attrib = st_lookup_cmd_attribute(oldpkt->pkt_cdbp[0]);
18027 18025 }
18028 18026
18029 18027 /*
18030 18028 * Some non-uscsi commands use the b_bcount for values that
18031 18029 * have nothing to do with how much data is transfered.
18032 18030 * In those cases we need to hide the buf_t from scsi_init_pkt().
18033 18031 */
18034 18032 if ((BP_UCMD(bp)) && (bp->b_bcount)) {
18035 18033 pkt_bp = bp;
18036 18034 } else if (attrib->transfers_data == TRAN_NONE) {
18037 18035 pkt_bp = NULL;
18038 18036 } else {
18039 18037 pkt_bp = bp;
18040 18038 }
18041 18039
18042 18040 /*
18043 18041 * if this is a queued command make sure it the only one in the
18044 18042 * run queue.
18045 18043 */
18046 18044 if (bp != un->un_sbufp && bp != un->un_recov_buf) {
18047 18045 ASSERT(un->un_runqf == un->un_runql);
18048 18046 ASSERT(un->un_runqf == bp);
18049 18047 queued = 1;
18050 18048 }
18051 18049
18052 18050 cdblen = scsi_cdb_size[CDB_GROUPID(oldpkt->pkt_cdbp[0])];
18053 18051
18054 18052 if (pkt_bp == un->un_rqs_bp) {
18055 18053 flags |= PKT_CONSISTENT;
18056 18054 stat_size = 1;
18057 18055 }
18058 18056
18059 18057 newpkt = scsi_init_pkt(ROUTE, NULL, pkt_bp, cdblen,
18060 18058 stat_size, rcv->privatelen, flags, NULL_FUNC, NULL);
18061 18059 if (newpkt == NULL) {
18062 18060 ST_RECOV(ST_DEVINFO, st_label, CE_NOTE,
18063 18061 "Reissue pkt scsi_init_pkt() failure\n");
18064 18062 return (COMMAND_DONE_ERROR);
18065 18063 }
18066 18064
18067 18065 ASSERT(newpkt->pkt_resid == 0);
18068 18066 bp->b_flags &= ~(B_DONE);
18069 18067 bp->b_resid = 0;
18070 18068 st_bioerror(bp, 0);
18071 18069
18072 18070 bcopy(oldpkt->pkt_private, newpkt->pkt_private, rcv->privatelen);
18073 18071
18074 18072 newpkt->pkt_comp = oldpkt->pkt_comp;
18075 18073 newpkt->pkt_time = oldpkt->pkt_time;
18076 18074
18077 18075 bzero(newpkt->pkt_scbp, stat_size);
18078 18076 bcopy(oldpkt->pkt_cdbp, newpkt->pkt_cdbp, cdblen);
18079 18077
18080 18078 newpkt->pkt_state = 0;
18081 18079 newpkt->pkt_statistics = 0;
18082 18080
18083 18081 /*
18084 18082 * oldpkt passed in was a copy of the original.
18085 18083 * to distroy we need the address of the original.
18086 18084 */
18087 18085 oldpkt = BP_PKT(bp);
18088 18086
18089 18087 if (oldpkt == un->un_rqs) {
18090 18088 ASSERT(bp == un->un_rqs_bp);
18091 18089 un->un_rqs = newpkt;
18092 18090 }
18093 18091
18094 18092 SET_BP_PKT(bp, newpkt);
18095 18093
18096 18094 scsi_destroy_pkt(oldpkt);
18097 18095
18098 18096 rval = st_transport(un, newpkt);
18099 18097 if (rval == TRAN_ACCEPT) {
18100 18098 return (JUST_RETURN);
18101 18099 }
18102 18100 ST_RECOV(ST_DEVINFO, st_label, CE_NOTE,
18103 18101 "Reissue pkt st_transport(0x%x) failure\n", rval);
18104 18102 if (rval != TRAN_BUSY) {
18105 18103 return (COMMAND_DONE_ERROR);
18106 18104 }
18107 18105 mutex_exit(ST_MUTEX);
18108 18106 rval = st_handle_start_busy(un, bp, ST_TRAN_BUSY_TIMEOUT, queued);
18109 18107 mutex_enter(ST_MUTEX);
18110 18108 if (rval) {
18111 18109 return (COMMAND_DONE_ERROR);
18112 18110 }
18113 18111
18114 18112 return (JUST_RETURN);
18115 18113 }
18116 18114
18117 18115 static int
18118 18116 st_transport(struct scsi_tape *un, struct scsi_pkt *pkt)
18119 18117 {
18120 18118 int status;
18121 18119
18122 18120 ST_FUNC(ST_DEVINFO, st_transport);
18123 18121
18124 18122 ST_CDB(ST_DEVINFO, "transport CDB", (caddr_t)pkt->pkt_cdbp);
18125 18123
18126 18124 mutex_exit(ST_MUTEX);
18127 18125
18128 18126 status = scsi_transport(pkt);
18129 18127
18130 18128 mutex_enter(ST_MUTEX);
18131 18129
18132 18130 return (status);
18133 18131 }
18134 18132
18135 18133 /*
18136 18134 * Removed the buf_t bp from the queue referenced to by head and tail.
18137 18135 * Returns the buf_t pointer if it is found in the queue.
18138 18136 * Returns NULL if it is not found.
18139 18137 */
18140 18138 static buf_t *
18141 18139 st_remove_from_queue(buf_t **head, buf_t **tail, buf_t *bp)
18142 18140 {
18143 18141 buf_t *runqbp;
18144 18142 buf_t *prevbp = NULL;
18145 18143
18146 18144 for (runqbp = *head; runqbp != 0; runqbp = runqbp->av_forw) {
18147 18145 if (runqbp == bp) {
18148 18146 /* found it, is it at the head? */
18149 18147 if (runqbp == *head) {
18150 18148 *head = bp->av_forw;
18151 18149 } else {
18152 18150 prevbp->av_forw = bp->av_forw;
18153 18151 }
18154 18152 if (*tail == bp) {
18155 18153 *tail = prevbp;
18156 18154 }
18157 18155 bp->av_forw = NULL;
18158 18156 return (bp); /* found and removed */
18159 18157 }
18160 18158 prevbp = runqbp;
18161 18159 }
18162 18160 return (NULL);
18163 18161 }
18164 18162
18165 18163 /*
18166 18164 * Adds a buf_t to the queue pointed to by head and tail.
18167 18165 * Adds it either to the head end or the tail end based on which
18168 18166 * the passed variable end (head or tail) points at.
18169 18167 */
18170 18168 static void
18171 18169 st_add_to_queue(buf_t **head, buf_t **tail, buf_t *end, buf_t *bp)
18172 18170 {
18173 18171
18174 18172 bp->av_forw = NULL;
18175 18173 if (*head) {
18176 18174 /* Queue is not empty */
18177 18175 if (end == *head) {
18178 18176 /* Add at front of queue */
18179 18177 bp->av_forw = *head;
18180 18178 *head = bp;
18181 18179 } else if (end == *tail) {
18182 18180 /* Add at end of queue */
18183 18181 (*tail)->av_forw = bp;
18184 18182 *tail = bp;
18185 18183 } else {
18186 18184 ASSERT(0);
18187 18185 }
18188 18186 } else {
18189 18187 /* Queue is empty */
18190 18188 *head = bp;
18191 18189 *tail = bp;
18192 18190 }
18193 18191 }
18194 18192
18195 18193
18196 18194 static uint64_t
18197 18195 st_get_cdb_g0_rw_count(uchar_t *cdb)
18198 18196 {
18199 18197 uint64_t count;
18200 18198
18201 18199 if ((cdb[1]) & 1) {
18202 18200 /* fixed block mode, the count is the number of blocks */
18203 18201 count =
18204 18202 cdb[2] << 16 |
18205 18203 cdb[3] << 8 |
18206 18204 cdb[4];
18207 18205 } else {
18208 18206 /* variable block mode, the count is the block size */
18209 18207 count = 1;
18210 18208 }
18211 18209 return (count);
18212 18210 }
18213 18211
18214 18212 static uint64_t
18215 18213 st_get_cdb_g0_sign_count(uchar_t *cdb)
18216 18214 {
18217 18215 uint64_t count;
18218 18216
18219 18217 count =
18220 18218 cdb[2] << 16 |
18221 18219 cdb[3] << 8 |
18222 18220 cdb[4];
18223 18221 /*
18224 18222 * If the sign bit of the 3 byte value is set, extended it.
18225 18223 */
18226 18224 if (count & 0x800000) {
18227 18225 count |= 0xffffffffff000000;
18228 18226 }
18229 18227 return (count);
18230 18228 }
18231 18229
18232 18230 static uint64_t
18233 18231 st_get_cdb_g0_count(uchar_t *cdb)
18234 18232 {
18235 18233 uint64_t count;
18236 18234
18237 18235 count =
18238 18236 cdb[2] << 16 |
18239 18237 cdb[3] << 8 |
18240 18238 cdb[4];
18241 18239 return (count);
18242 18240 }
18243 18241
18244 18242 static uint64_t
18245 18243 st_get_cdb_g5_rw_cnt(uchar_t *cdb)
18246 18244 {
18247 18245 uint64_t count;
18248 18246
18249 18247 if ((cdb[1]) & 1) {
18250 18248 /* fixed block mode */
18251 18249 count =
18252 18250 cdb[12] << 16 |
18253 18251 cdb[13] << 8 |
18254 18252 cdb[14];
18255 18253 } else {
18256 18254 /* variable block mode */
18257 18255 count = 1;
18258 18256 }
18259 18257 return (count);
18260 18258 }
18261 18259
18262 18260 static uint64_t
18263 18261 st_get_no_count(uchar_t *cdb)
18264 18262 {
18265 18263 ASSERT(cdb[0] == SCMD_REWIND);
18266 18264 return ((uint64_t)cdb[0]);
18267 18265 }
18268 18266
18269 18267 static uint64_t
18270 18268 st_get_load_options(uchar_t *cdb)
18271 18269 {
18272 18270 return ((uint64_t)(cdb[4] | (LD_HOLD << 1)));
18273 18271 }
18274 18272
18275 18273 static uint64_t
18276 18274 st_get_erase_options(uchar_t *cdb)
18277 18275 {
18278 18276 return (cdb[1] | (cdb[0] << 8));
18279 18277 }
18280 18278
18281 18279 static uint64_t
18282 18280 st_get_cdb_g1_lba(uchar_t *cdb)
18283 18281 {
18284 18282 uint64_t lba;
18285 18283
18286 18284 lba =
18287 18285 cdb[3] << 24 |
18288 18286 cdb[4] << 16 |
18289 18287 cdb[5] << 8 |
18290 18288 cdb[6];
18291 18289 return (lba);
18292 18290 }
18293 18291
18294 18292 static uint64_t
18295 18293 st_get_cdb_g5_count(uchar_t *cdb)
18296 18294 {
18297 18295 uint64_t count =
18298 18296 cdb[12] << 16 |
18299 18297 cdb[13] << 8 |
18300 18298 cdb[14];
18301 18299
18302 18300 return (count);
18303 18301 }
18304 18302
18305 18303 static uint64_t
18306 18304 st_get_cdb_g4g5_cnt(uchar_t *cdb)
18307 18305 {
18308 18306 uint64_t lba;
18309 18307
18310 18308 lba =
18311 18309 (uint64_t)cdb[4] << 56 |
18312 18310 (uint64_t)cdb[5] << 48 |
18313 18311 (uint64_t)cdb[6] << 40 |
18314 18312 (uint64_t)cdb[7] << 32 |
18315 18313 (uint64_t)cdb[8] << 24 |
18316 18314 (uint64_t)cdb[9] << 16 |
18317 18315 (uint64_t)cdb[10] << 8 |
18318 18316 (uint64_t)cdb[11];
18319 18317 return (lba);
18320 18318 }
18321 18319
18322 18320 static const cmd_attribute cmd_attributes[] = {
18323 18321 { SCMD_READ,
18324 18322 1, 0, 1, 0, 0, DIR_FORW, TRAN_READ, POS_EXPECTED,
18325 18323 0, 0, 0, st_get_cdb_g0_rw_count },
18326 18324 { SCMD_WRITE,
18327 18325 1, 0, 1, 1, 0, DIR_FORW, TRAN_WRTE, POS_EXPECTED,
18328 18326 0, 0, 0, st_get_cdb_g0_rw_count },
18329 18327 { SCMD_TEST_UNIT_READY,
18330 18328 0, 1, 0, 0, 0, DIR_NONE, TRAN_NONE, POS_EXPECTED,
18331 18329 0, 0, 0 },
18332 18330 { SCMD_REWIND,
18333 18331 1, 1, 1, 0, 0, DIR_REVC, TRAN_NONE, POS_EXPECTED,
18334 18332 0, 0, 0, st_get_no_count },
18335 18333 { SCMD_REQUEST_SENSE,
18336 18334 0, 0, 0, 0, 0, DIR_NONE, TRAN_READ, POS_EXPECTED,
18337 18335 0, 0, 0 },
18338 18336 { SCMD_READ_BLKLIM,
18339 18337 0, 1, 0, 0, 0, DIR_NONE, TRAN_READ, POS_EXPECTED,
18340 18338 0, 0, 0 },
18341 18339 { SCMD_READ_G4,
18342 18340 1, 0, 1, 0, 1, DIR_FORW, TRAN_READ, POS_EXPECTED,
18343 18341 0, 0, 0, st_get_cdb_g5_rw_cnt, st_get_cdb_g4g5_cnt },
18344 18342 { SCMD_WRITE_G4,
18345 18343 1, 0, 1, 1, 1, DIR_FORW, TRAN_WRTE, POS_EXPECTED,
18346 18344 0, 0, 0, st_get_cdb_g5_rw_cnt, st_get_cdb_g4g5_cnt },
18347 18345 { SCMD_READ_REVERSE,
18348 18346 1, 0, 1, 1, 0, DIR_REVC, TRAN_READ, POS_EXPECTED,
18349 18347 0, 0, 0, st_get_cdb_g0_rw_count },
18350 18348 { SCMD_READ_REVERSE_G4,
18351 18349 1, 0, 1, 1, 1, DIR_REVC, TRAN_READ, POS_EXPECTED,
18352 18350 0, 0, 0, st_get_cdb_g5_rw_cnt, st_get_cdb_g4g5_cnt },
18353 18351 { SCMD_WRITE_FILE_MARK,
18354 18352 1, 0, 1, 1, 0, DIR_FORW, TRAN_NONE, POS_EXPECTED,
18355 18353 0, 0, 0, st_get_cdb_g0_count },
18356 18354 { SCMD_WRITE_FILE_MARK_G4,
18357 18355 1, 0, 1, 1, 1, DIR_FORW, TRAN_NONE, POS_EXPECTED,
18358 18356 0, 0, 0, st_get_cdb_g5_count, st_get_cdb_g4g5_cnt },
18359 18357 { SCMD_SPACE,
18360 18358 1, 0, 1, 0, 0, DIR_EITH, TRAN_NONE, POS_STARTING,
18361 18359 0, 0, 0, st_get_cdb_g0_sign_count },
18362 18360 { SCMD_SPACE_G4,
18363 18361 1, 0, 1, 0, 0, DIR_EITH, TRAN_NONE, POS_STARTING,
18364 18362 0, 0, 0, st_get_cdb_g4g5_cnt },
18365 18363 { SCMD_INQUIRY,
18366 18364 0, 1, 0, 0, 0, DIR_NONE, TRAN_READ, POS_EXPECTED,
18367 18365 0, 0, 0 },
18368 18366 { SCMD_VERIFY_G0,
18369 18367 1, 0, 1, 0, 0, DIR_FORW, TRAN_NONE, POS_EXPECTED,
18370 18368 0, 0, 0, st_get_cdb_g0_rw_count },
18371 18369 { SCMD_VERIFY_G4,
18372 18370 1, 0, 1, 0, 1, DIR_FORW, TRAN_NONE, POS_EXPECTED,
18373 18371 0, 0, 0, st_get_cdb_g5_rw_cnt, st_get_cdb_g4g5_cnt },
18374 18372 { SCMD_RECOVER_BUF,
18375 18373 1, 0, 1, 1, 0, DIR_REVC, TRAN_READ, POS_EXPECTED,
18376 18374 0, 0, 0 },
18377 18375 { SCMD_MODE_SELECT,
18378 18376 1, 1, 0, 0, 0, DIR_NONE, TRAN_WRTE, POS_EXPECTED,
18379 18377 0, 0, 0 },
18380 18378 { SCMD_RESERVE,
18381 18379 0, 1, 0, 0, 0, DIR_NONE, TRAN_NONE, POS_EXPECTED,
18382 18380 0, 0, 0 },
18383 18381 { SCMD_RELEASE,
18384 18382 0, 1, 0, 0, 0, DIR_NONE, TRAN_NONE, POS_EXPECTED,
18385 18383 0, 0, 0 },
18386 18384 { SCMD_ERASE,
18387 18385 1, 0, 1, 1, 0, DIR_NONE, TRAN_NONE, POS_EXPECTED,
18388 18386 0, 0, 0, st_get_erase_options },
18389 18387 { SCMD_MODE_SENSE,
18390 18388 1, 1, 0, 0, 0, DIR_NONE, TRAN_READ, POS_EXPECTED,
18391 18389 0, 0, 0 },
18392 18390 { SCMD_LOAD,
18393 18391 1, 1, 1, 0, 0, DIR_EITH, TRAN_NONE, POS_EXPECTED,
18394 18392 0, 0, 0, st_get_load_options },
18395 18393 { SCMD_GDIAG,
18396 18394 1, 1, 0, 0, 0, DIR_NONE, TRAN_READ, POS_EXPECTED,
18397 18395 1, 0, 0 },
18398 18396 { SCMD_SDIAG,
18399 18397 1, 0, 1, 1, 0, DIR_EITH, TRAN_WRTE, POS_EXPECTED,
18400 18398 1, 0, 0 },
18401 18399 { SCMD_DOORLOCK,
18402 18400 0, 1, 0, 0, 0, DIR_NONE, TRAN_NONE, POS_EXPECTED,
18403 18401 0, 4, 3 },
18404 18402 { SCMD_LOCATE,
18405 18403 1, 1, 1, 0, 0, DIR_EITH, TRAN_NONE, POS_EXPECTED,
18406 18404 0, 0, 0, NULL, st_get_cdb_g1_lba },
18407 18405 { SCMD_READ_POSITION,
18408 18406 1, 1, 0, 0, 0, DIR_NONE, TRAN_READ, POS_EXPECTED,
18409 18407 0, 0, 0 },
18410 18408 { SCMD_WRITE_BUFFER,
18411 18409 1, 0, 0, 0, 0, DIR_NONE, TRAN_WRTE, POS_EXPECTED,
18412 18410 1, 0, 0 },
18413 18411 { SCMD_READ_BUFFER,
18414 18412 1, 0, 0, 0, 0, DIR_NONE, TRAN_READ, POS_EXPECTED,
18415 18413 1, 0, 0 },
18416 18414 { SCMD_REPORT_DENSITIES,
18417 18415 0, 1, 0, 0, 0, DIR_NONE, TRAN_READ, POS_EXPECTED,
18418 18416 0, 0, 0 },
18419 18417 { SCMD_LOG_SELECT_G1,
18420 18418 1, 1, 0, 0, 0, DIR_NONE, TRAN_WRTE, POS_EXPECTED,
18421 18419 0, 0, 0 },
18422 18420 { SCMD_LOG_SENSE_G1,
18423 18421 1, 1, 0, 0, 0, DIR_NONE, TRAN_READ, POS_EXPECTED,
18424 18422 0, 0, 0 },
18425 18423 { SCMD_PRIN,
18426 18424 0, 1, 0, 0, 0, DIR_NONE, TRAN_READ, POS_EXPECTED,
18427 18425 0, 0, 0 },
18428 18426 { SCMD_PROUT,
18429 18427 0, 1, 0, 0, 0, DIR_NONE, TRAN_WRTE, POS_EXPECTED,
18430 18428 0, 0, 0 },
18431 18429 { SCMD_READ_ATTRIBUTE,
18432 18430 1, 1, 0, 0, 0, DIR_NONE, TRAN_READ, POS_EXPECTED,
18433 18431 0, 0, 0 },
18434 18432 { SCMD_WRITE_ATTRIBUTE,
18435 18433 1, 1, 0, 0, 0, DIR_NONE, TRAN_WRTE, POS_EXPECTED,
18436 18434 0, 0, 0 },
18437 18435 { SCMD_LOCATE_G4,
18438 18436 1, 1, 1, 0, 0, DIR_EITH, TRAN_NONE, POS_EXPECTED,
18439 18437 0, 0, 0, NULL, st_get_cdb_g4g5_cnt },
18440 18438 { SCMD_REPORT_LUNS,
18441 18439 0, 1, 0, 0, 0, DIR_NONE, TRAN_READ, POS_EXPECTED,
18442 18440 0, 0, 0 },
18443 18441 { SCMD_SVC_ACTION_IN_G5,
18444 18442 1, 1, 0, 0, 0, DIR_NONE, TRAN_READ, POS_EXPECTED,
18445 18443 0, 0, 0 },
18446 18444 { SCMD_MAINTENANCE_IN,
18447 18445 1, 1, 0, 0, 0, DIR_NONE, TRAN_READ, POS_EXPECTED,
18448 18446 0, 0, 0 },
18449 18447 { SCMD_MAINTENANCE_OUT,
18450 18448 1, 1, 0, 0, 0, DIR_NONE, TRAN_WRTE, POS_EXPECTED,
18451 18449 0, 0, 0 },
18452 18450 { 0xff, /* Default attribute for unsupported commands */
18453 18451 1, 0, 0, 0, 0, DIR_NONE, TRAN_NONE, POS_STARTING,
18454 18452 1, 0, 0, NULL, NULL }
18455 18453 };
18456 18454
18457 18455 static const cmd_attribute *
18458 18456 st_lookup_cmd_attribute(unsigned char cmd)
18459 18457 {
18460 18458 int i;
18461 18459 cmd_attribute const *attribute;
18462 18460
18463 18461 for (i = 0; i < ST_NUM_MEMBERS(cmd_attributes); i++) {
18464 18462 attribute = &cmd_attributes[i];
18465 18463 if (attribute->cmd == cmd) {
18466 18464 return (attribute);
18467 18465 }
18468 18466 }
18469 18467 ASSERT(attribute);
18470 18468 return (attribute);
18471 18469 }
18472 18470
18473 18471 static int
18474 18472 st_reset(struct scsi_tape *un, int reset_type)
18475 18473 {
18476 18474 int rval;
18477 18475
18478 18476 ASSERT(MUTEX_HELD(&un->un_sd->sd_mutex));
18479 18477
18480 18478 ST_FUNC(ST_DEVINFO, st_reset);
18481 18479 un->un_rsvd_status |= ST_INITIATED_RESET;
18482 18480 mutex_exit(ST_MUTEX);
18483 18481 do {
18484 18482 rval = scsi_reset(&un->un_sd->sd_address, reset_type);
18485 18483 if (rval == 0) {
18486 18484 switch (reset_type) {
18487 18485 case RESET_LUN:
18488 18486 ST_DEBUG3(ST_DEVINFO, st_label, CE_WARN,
18489 18487 "LUN reset failed trying target reset");
18490 18488 reset_type = RESET_TARGET;
18491 18489 break;
18492 18490 case RESET_TARGET:
18493 18491 ST_DEBUG3(ST_DEVINFO, st_label, CE_WARN,
18494 18492 "target reset failed trying bus reset");
18495 18493 reset_type = RESET_BUS;
18496 18494 break;
18497 18495 case RESET_BUS:
18498 18496 ST_DEBUG3(ST_DEVINFO, st_label, CE_WARN,
18499 18497 "bus reset failed trying all reset");
18500 18498 reset_type = RESET_ALL;
18501 18499 default:
18502 18500 mutex_enter(ST_MUTEX);
18503 18501 return (rval);
18504 18502 }
18505 18503 }
18506 18504 } while (rval == 0);
18507 18505 mutex_enter(ST_MUTEX);
18508 18506 return (rval);
18509 18507 }
18510 18508
18511 18509 #define SAS_TLR_MOD_LEN sizeof (struct seq_mode)
18512 18510 static int
18513 18511 st_set_target_TLR_mode(struct scsi_tape *un, ubufunc_t ubf)
18514 18512 {
18515 18513 int ret;
18516 18514 int amount = SAS_TLR_MOD_LEN;
18517 18515 struct seq_mode *mode_data;
18518 18516
18519 18517 ST_FUNC(ST_DEVINFO, st_set_target_TLR_mode);
18520 18518
18521 18519 mode_data = kmem_zalloc(SAS_TLR_MOD_LEN, KM_SLEEP);
18522 18520 ret = st_gen_mode_sense(un, ubf, 0x18, mode_data, amount);
18523 18521 if (ret != DDI_SUCCESS) {
18524 18522 if (ret != EACCES)
18525 18523 un->un_tlr_flag = TLR_NOT_SUPPORTED;
18526 18524 goto out;
18527 18525 }
18528 18526 if (mode_data->data_len != amount + 1) {
18529 18527 amount = mode_data->data_len + 1;
18530 18528 }
18531 18529 /* Must be SAS protocol */
18532 18530 if (mode_data->page.saslun.protocol_id != 6) {
18533 18531 un->un_tlr_flag = TLR_NOT_SUPPORTED;
18534 18532 ret = ENOTSUP;
18535 18533 goto out;
18536 18534 }
18537 18535 if (un->un_tlr_flag == TLR_SAS_ONE_DEVICE) {
18538 18536 if (mode_data->page.saslun.tran_layer_ret == 1)
18539 18537 goto out;
18540 18538 mode_data->page.saslun.tran_layer_ret = 1;
18541 18539 } else {
18542 18540 if (mode_data->page.saslun.tran_layer_ret == 0)
18543 18541 goto out;
18544 18542 mode_data->page.saslun.tran_layer_ret = 0;
18545 18543 }
18546 18544 ret = st_gen_mode_select(un, ubf, mode_data, amount);
18547 18545 if (ret != DDI_SUCCESS) {
18548 18546 if (ret != EACCES)
18549 18547 un->un_tlr_flag = TLR_NOT_SUPPORTED;
18550 18548 } else {
18551 18549 if (mode_data->page.saslun.tran_layer_ret == 0)
18552 18550 un->un_tlr_flag = TLR_NOT_KNOWN;
18553 18551 else
18554 18552 un->un_tlr_flag = TLR_SAS_ONE_DEVICE;
18555 18553 }
18556 18554 #ifdef STDEBUG
18557 18555 st_clean_print(ST_DEVINFO, st_label, SCSI_DEBUG, "TLR data sent",
18558 18556 (char *)mode_data, amount);
18559 18557 #endif
18560 18558 out:
18561 18559 kmem_free(mode_data, SAS_TLR_MOD_LEN);
18562 18560 return (ret);
18563 18561 }
18564 18562
18565 18563
18566 18564 static void
18567 18565 st_reset_notification(caddr_t arg)
18568 18566 {
18569 18567 struct scsi_tape *un = (struct scsi_tape *)arg;
18570 18568
18571 18569 ST_FUNC(ST_DEVINFO, st_reset_notification);
18572 18570 mutex_enter(ST_MUTEX);
18573 18571
18574 18572 un->un_unit_attention_flags |= 2;
18575 18573 if ((un->un_rsvd_status & (ST_RESERVE | ST_APPLICATION_RESERVATIONS)) ==
18576 18574 ST_RESERVE) {
18577 18575 un->un_rsvd_status |= ST_LOST_RESERVE;
18578 18576 ST_DEBUG2(ST_DEVINFO, st_label, CE_WARN,
18579 18577 "Lost Reservation notification");
18580 18578 } else {
18581 18579 ST_DEBUG2(ST_DEVINFO, st_label, CE_WARN,
18582 18580 "reset notification");
18583 18581 }
18584 18582
18585 18583 if ((un->un_restore_pos == 0) &&
18586 18584 (un->un_state == ST_STATE_CLOSED) ||
18587 18585 (un->un_state == ST_STATE_OPEN_PENDING_IO) ||
18588 18586 (un->un_state == ST_STATE_CLOSING)) {
18589 18587 un->un_restore_pos = 1;
18590 18588 }
18591 18589 ST_DEBUG6(ST_DEVINFO, st_label, CE_WARN,
18592 18590 "reset and state was %d\n", un->un_state);
18593 18591 mutex_exit(ST_MUTEX);
18594 18592 }
↓ open down ↓ |
16889 lines elided |
↑ open up ↑ |
XXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXX