1 /*
2   SCSI Tape Driver for Linux version 1.1 and newer. See the accompanying
3   file Documentation/scsi/st.txt for more information.
4 
5   History:
6 
7   OnStream SCSI Tape support (osst) cloned from st.c by
8   Willem Riede (osst@riede.org) Feb 2000
9   Fixes ... Kurt Garloff <garloff@suse.de> Mar 2000
10 
11   Rewritten from Dwayne Forsyth's SCSI tape driver by Kai Makisara.
12   Contribution and ideas from several people including (in alphabetical
13   order) Klaus Ehrenfried, Wolfgang Denk, Steve Hirsch, Andreas Koppenh"ofer,
14   Michael Leodolter, Eyal Lebedinsky, J"org Weule, and Eric Youngdale.
15 
16   Copyright 1992 - 2002 Kai Makisara / 2000 - 2006 Willem Riede
17 	 email osst@riede.org
18 
19   $Header: /cvsroot/osst/Driver/osst.c,v 1.73 2005/01/01 21:13:34 wriede Exp $
20 
21   Microscopic alterations - Rik Ling, 2000/12/21
22   Last st.c sync: Tue Oct 15 22:01:04 2002 by makisara
23   Some small formal changes - aeb, 950809
24 */
25 
26 static const char * cvsid = "$Id: osst.c,v 1.73 2005/01/01 21:13:34 wriede Exp $";
27 static const char * osst_version = "0.99.4";
28 
29 /* The "failure to reconnect" firmware bug */
30 #define OSST_FW_NEED_POLL_MIN 10601 /*(107A)*/
31 #define OSST_FW_NEED_POLL_MAX 10704 /*(108D)*/
32 #define OSST_FW_NEED_POLL(x,d) ((x) >= OSST_FW_NEED_POLL_MIN && (x) <= OSST_FW_NEED_POLL_MAX && d->host->this_id != 7)
33 
34 #include <linux/module.h>
35 
36 #include <linux/fs.h>
37 #include <linux/kernel.h>
38 #include <linux/sched/signal.h>
39 #include <linux/proc_fs.h>
40 #include <linux/mm.h>
41 #include <linux/slab.h>
42 #include <linux/init.h>
43 #include <linux/string.h>
44 #include <linux/errno.h>
45 #include <linux/mtio.h>
46 #include <linux/ioctl.h>
47 #include <linux/fcntl.h>
48 #include <linux/spinlock.h>
49 #include <linux/vmalloc.h>
50 #include <linux/blkdev.h>
51 #include <linux/moduleparam.h>
52 #include <linux/delay.h>
53 #include <linux/jiffies.h>
54 #include <linux/mutex.h>
55 #include <linux/uaccess.h>
56 #include <asm/dma.h>
57 
58 /* The driver prints some debugging information on the console if DEBUG
59    is defined and non-zero. */
60 #define DEBUG 0
61 
62 /* The message level for the debug messages is currently set to KERN_NOTICE
63    so that people can easily see the messages. Later when the debugging messages
64    in the drivers are more widely classified, this may be changed to KERN_DEBUG. */
65 #define OSST_DEB_MSG  KERN_NOTICE
66 
67 #include <scsi/scsi.h>
68 #include <scsi/scsi_dbg.h>
69 #include <scsi/scsi_device.h>
70 #include <scsi/scsi_driver.h>
71 #include <scsi/scsi_eh.h>
72 #include <scsi/scsi_host.h>
73 #include <scsi/scsi_ioctl.h>
74 
75 #define ST_KILOBYTE 1024
76 
77 #include "st.h"
78 #include "osst.h"
79 #include "osst_options.h"
80 #include "osst_detect.h"
81 
82 static DEFINE_MUTEX(osst_int_mutex);
83 static int max_dev = 0;
84 static int write_threshold_kbs = 0;
85 static int max_sg_segs = 0;
86 
87 #ifdef MODULE
88 MODULE_AUTHOR("Willem Riede");
89 MODULE_DESCRIPTION("OnStream {DI-|FW-|SC-|USB}{30|50} Tape Driver");
90 MODULE_LICENSE("GPL");
91 MODULE_ALIAS_CHARDEV_MAJOR(OSST_MAJOR);
92 MODULE_ALIAS_SCSI_DEVICE(TYPE_TAPE);
93 
94 module_param(max_dev, int, 0444);
95 MODULE_PARM_DESC(max_dev, "Maximum number of OnStream Tape Drives to attach (4)");
96 
97 module_param(write_threshold_kbs, int, 0644);
98 MODULE_PARM_DESC(write_threshold_kbs, "Asynchronous write threshold (KB; 32)");
99 
100 module_param(max_sg_segs, int, 0644);
101 MODULE_PARM_DESC(max_sg_segs, "Maximum number of scatter/gather segments to use (9)");
102 #else
103 static struct osst_dev_parm {
104        char   *name;
105        int    *val;
106 } parms[] __initdata = {
107        { "max_dev",             &max_dev             },
108        { "write_threshold_kbs", &write_threshold_kbs },
109        { "max_sg_segs",         &max_sg_segs         }
110 };
111 #endif
112 
113 /* Some default definitions have been moved to osst_options.h */
114 #define OSST_BUFFER_SIZE (OSST_BUFFER_BLOCKS * ST_KILOBYTE)
115 #define OSST_WRITE_THRESHOLD (OSST_WRITE_THRESHOLD_BLOCKS * ST_KILOBYTE)
116 
117 /* The buffer size should fit into the 24 bits for length in the
118    6-byte SCSI read and write commands. */
119 #if OSST_BUFFER_SIZE >= (2 << 24 - 1)
120 #error "Buffer size should not exceed (2 << 24 - 1) bytes!"
121 #endif
122 
123 #if DEBUG
124 static int debugging = 1;
125 /* uncomment define below to test error recovery */
126 // #define OSST_INJECT_ERRORS 1
127 #endif
128 
129 /* Do not retry! The drive firmware already retries when appropriate,
130    and when it tries to tell us something, we had better listen... */
131 #define MAX_RETRIES 0
132 
133 #define NO_TAPE  NOT_READY
134 
135 #define OSST_WAIT_POSITION_COMPLETE   (HZ > 200 ? HZ / 200 : 1)
136 #define OSST_WAIT_WRITE_COMPLETE      (HZ / 12)
137 #define OSST_WAIT_LONG_WRITE_COMPLETE (HZ / 2)
138 
139 #define OSST_TIMEOUT (200 * HZ)
140 #define OSST_LONG_TIMEOUT (1800 * HZ)
141 
142 #define TAPE_NR(x) (iminor(x) & ~(-1 << ST_MODE_SHIFT))
143 #define TAPE_MODE(x) ((iminor(x) & ST_MODE_MASK) >> ST_MODE_SHIFT)
144 #define TAPE_REWIND(x) ((iminor(x) & 0x80) == 0)
145 #define TAPE_IS_RAW(x) (TAPE_MODE(x) & (ST_NBR_MODES >> 1))
146 
147 /* Internal ioctl to set both density (uppermost 8 bits) and blocksize (lower
148    24 bits) */
149 #define SET_DENS_AND_BLK 0x10001
150 
151 static int osst_buffer_size       = OSST_BUFFER_SIZE;
152 static int osst_write_threshold   = OSST_WRITE_THRESHOLD;
153 static int osst_max_sg_segs       = OSST_MAX_SG;
154 static int osst_max_dev           = OSST_MAX_TAPES;
155 static int osst_nr_dev;
156 
157 static struct osst_tape **os_scsi_tapes = NULL;
158 static DEFINE_RWLOCK(os_scsi_tapes_lock);
159 
160 static int modes_defined = 0;
161 
162 static struct osst_buffer *new_tape_buffer(int, int, int);
163 static int enlarge_buffer(struct osst_buffer *, int);
164 static void normalize_buffer(struct osst_buffer *);
165 static int append_to_buffer(const char __user *, struct osst_buffer *, int);
166 static int from_buffer(struct osst_buffer *, char __user *, int);
167 static int osst_zero_buffer_tail(struct osst_buffer *);
168 static int osst_copy_to_buffer(struct osst_buffer *, unsigned char *);
169 static int osst_copy_from_buffer(struct osst_buffer *, unsigned char *);
170 
171 static int osst_probe(struct device *);
172 static int osst_remove(struct device *);
173 
174 static struct scsi_driver osst_template = {
175 	.gendrv = {
176 		.name		=  "osst",
177 		.owner		= THIS_MODULE,
178 		.probe		= osst_probe,
179 		.remove		= osst_remove,
180 	}
181 };
182 
183 static int osst_int_ioctl(struct osst_tape *STp, struct osst_request ** aSRpnt,
184 			    unsigned int cmd_in, unsigned long arg);
185 
186 static int osst_set_frame_position(struct osst_tape *STp, struct osst_request ** aSRpnt, int frame, int skip);
187 
188 static int osst_get_frame_position(struct osst_tape *STp, struct osst_request ** aSRpnt);
189 
190 static int osst_flush_write_buffer(struct osst_tape *STp, struct osst_request ** aSRpnt);
191 
192 static int osst_write_error_recovery(struct osst_tape * STp, struct osst_request ** aSRpnt, int pending);
193 
tape_name(struct osst_tape * tape)194 static inline char *tape_name(struct osst_tape *tape)
195 {
196 	return tape->drive->disk_name;
197 }
198 
199 /* Routines that handle the interaction with mid-layer SCSI routines */
200 
201 
202 /* Normalize Sense */
osst_analyze_sense(struct osst_request * SRpnt,struct st_cmdstatus * s)203 static void osst_analyze_sense(struct osst_request *SRpnt, struct st_cmdstatus *s)
204 {
205 	const u8 *ucp;
206 	const u8 *sense = SRpnt->sense;
207 
208 	s->have_sense = scsi_normalize_sense(SRpnt->sense,
209 				SCSI_SENSE_BUFFERSIZE, &s->sense_hdr);
210 	s->flags = 0;
211 
212 	if (s->have_sense) {
213 		s->deferred = 0;
214 		s->remainder_valid =
215 			scsi_get_sense_info_fld(sense, SCSI_SENSE_BUFFERSIZE, &s->uremainder64);
216 		switch (sense[0] & 0x7f) {
217 		case 0x71:
218 			s->deferred = 1;
219 		case 0x70:
220 			s->fixed_format = 1;
221 			s->flags = sense[2] & 0xe0;
222 			break;
223 		case 0x73:
224 			s->deferred = 1;
225 		case 0x72:
226 			s->fixed_format = 0;
227 			ucp = scsi_sense_desc_find(sense, SCSI_SENSE_BUFFERSIZE, 4);
228 			s->flags = ucp ? (ucp[3] & 0xe0) : 0;
229 			break;
230 		}
231 	}
232 }
233 
234 /* Convert the result to success code */
osst_chk_result(struct osst_tape * STp,struct osst_request * SRpnt)235 static int osst_chk_result(struct osst_tape * STp, struct osst_request * SRpnt)
236 {
237 	char *name = tape_name(STp);
238 	int result = SRpnt->result;
239 	u8 * sense = SRpnt->sense, scode;
240 #if DEBUG
241 	const char *stp;
242 #endif
243 	struct st_cmdstatus *cmdstatp;
244 
245 	if (!result)
246 		return 0;
247 
248 	cmdstatp = &STp->buffer->cmdstat;
249 	osst_analyze_sense(SRpnt, cmdstatp);
250 
251 	if (cmdstatp->have_sense)
252 		scode = STp->buffer->cmdstat.sense_hdr.sense_key;
253 	else
254 		scode = 0;
255 #if DEBUG
256 	if (debugging) {
257 		printk(OSST_DEB_MSG "%s:D: Error: %x, cmd: %x %x %x %x %x %x\n",
258 		   name, result,
259 		   SRpnt->cmd[0], SRpnt->cmd[1], SRpnt->cmd[2],
260 		   SRpnt->cmd[3], SRpnt->cmd[4], SRpnt->cmd[5]);
261 		if (scode) printk(OSST_DEB_MSG "%s:D: Sense: %02x, ASC: %02x, ASCQ: %02x\n",
262 				  name, scode, sense[12], sense[13]);
263 		if (cmdstatp->have_sense)
264 			__scsi_print_sense(STp->device, name,
265 					   SRpnt->sense, SCSI_SENSE_BUFFERSIZE);
266 	}
267 	else
268 #endif
269 	if (cmdstatp->have_sense && (
270 		 scode != NO_SENSE &&
271 		 scode != RECOVERED_ERROR &&
272 /*      	 scode != UNIT_ATTENTION && */
273 		 scode != BLANK_CHECK &&
274 		 scode != VOLUME_OVERFLOW &&
275 		 SRpnt->cmd[0] != MODE_SENSE &&
276 		 SRpnt->cmd[0] != TEST_UNIT_READY)) { /* Abnormal conditions for tape */
277 		if (cmdstatp->have_sense) {
278 			printk(KERN_WARNING "%s:W: Command with sense data:\n", name);
279 			__scsi_print_sense(STp->device, name,
280 					   SRpnt->sense, SCSI_SENSE_BUFFERSIZE);
281 		}
282 		else {
283 			static	int	notyetprinted = 1;
284 
285 			printk(KERN_WARNING
286 			     "%s:W: Warning %x (driver bt 0x%x, host bt 0x%x).\n",
287 			     name, result, driver_byte(result),
288 			     host_byte(result));
289 			if (notyetprinted) {
290 				notyetprinted = 0;
291 				printk(KERN_INFO
292 					"%s:I: This warning may be caused by your scsi controller,\n", name);
293 				printk(KERN_INFO
294 					"%s:I: it has been reported with some Buslogic cards.\n", name);
295 			}
296 		}
297 	}
298 	STp->pos_unknown |= STp->device->was_reset;
299 
300 	if (cmdstatp->have_sense && scode == RECOVERED_ERROR) {
301 		STp->recover_count++;
302 		STp->recover_erreg++;
303 #if DEBUG
304 		if (debugging) {
305 			if (SRpnt->cmd[0] == READ_6)
306 				stp = "read";
307 			else if (SRpnt->cmd[0] == WRITE_6)
308 				stp = "write";
309 			else
310 				stp = "ioctl";
311 			printk(OSST_DEB_MSG "%s:D: Recovered %s error (%d).\n", name, stp,
312 					     STp->recover_count);
313 		}
314 #endif
315 		if ((sense[2] & 0xe0) == 0)
316 			return 0;
317 	}
318 	return (-EIO);
319 }
320 
321 
322 /* Wakeup from interrupt */
osst_end_async(struct request * req,blk_status_t status)323 static void osst_end_async(struct request *req, blk_status_t status)
324 {
325 	struct scsi_request *rq = scsi_req(req);
326 	struct osst_request *SRpnt = req->end_io_data;
327 	struct osst_tape *STp = SRpnt->stp;
328 	struct rq_map_data *mdata = &SRpnt->stp->buffer->map_data;
329 
330 	STp->buffer->cmdstat.midlevel_result = SRpnt->result = rq->result;
331 #if DEBUG
332 	STp->write_pending = 0;
333 #endif
334 	if (rq->sense_len)
335 		memcpy(SRpnt->sense, rq->sense, SCSI_SENSE_BUFFERSIZE);
336 	if (SRpnt->waiting)
337 		complete(SRpnt->waiting);
338 
339 	if (SRpnt->bio) {
340 		kfree(mdata->pages);
341 		blk_rq_unmap_user(SRpnt->bio);
342 	}
343 
344 	__blk_put_request(req->q, req);
345 }
346 
347 /* osst_request memory management */
osst_allocate_request(void)348 static struct osst_request *osst_allocate_request(void)
349 {
350 	return kzalloc(sizeof(struct osst_request), GFP_KERNEL);
351 }
352 
osst_release_request(struct osst_request * streq)353 static void osst_release_request(struct osst_request *streq)
354 {
355 	kfree(streq);
356 }
357 
osst_execute(struct osst_request * SRpnt,const unsigned char * cmd,int cmd_len,int data_direction,void * buffer,unsigned bufflen,int use_sg,int timeout,int retries)358 static int osst_execute(struct osst_request *SRpnt, const unsigned char *cmd,
359 			int cmd_len, int data_direction, void *buffer, unsigned bufflen,
360 			int use_sg, int timeout, int retries)
361 {
362 	struct request *req;
363 	struct scsi_request *rq;
364 	struct page **pages = NULL;
365 	struct rq_map_data *mdata = &SRpnt->stp->buffer->map_data;
366 
367 	int err = 0;
368 	int write = (data_direction == DMA_TO_DEVICE);
369 
370 	req = blk_get_request(SRpnt->stp->device->request_queue,
371 			write ? REQ_OP_SCSI_OUT : REQ_OP_SCSI_IN, 0);
372 	if (IS_ERR(req))
373 		return DRIVER_ERROR << 24;
374 
375 	rq = scsi_req(req);
376 	req->rq_flags |= RQF_QUIET;
377 
378 	SRpnt->bio = NULL;
379 
380 	if (use_sg) {
381 		struct scatterlist *sg, *sgl = (struct scatterlist *)buffer;
382 		int i;
383 
384 		pages = kcalloc(use_sg, sizeof(struct page *), GFP_KERNEL);
385 		if (!pages)
386 			goto free_req;
387 
388 		for_each_sg(sgl, sg, use_sg, i)
389 			pages[i] = sg_page(sg);
390 
391 		mdata->null_mapped = 1;
392 
393 		mdata->page_order = get_order(sgl[0].length);
394 		mdata->nr_entries =
395 			DIV_ROUND_UP(bufflen, PAGE_SIZE << mdata->page_order);
396 		mdata->offset = 0;
397 
398 		err = blk_rq_map_user(req->q, req, mdata, NULL, bufflen, GFP_KERNEL);
399 		if (err) {
400 			kfree(pages);
401 			goto free_req;
402 		}
403 		SRpnt->bio = req->bio;
404 		mdata->pages = pages;
405 
406 	} else if (bufflen) {
407 		err = blk_rq_map_kern(req->q, req, buffer, bufflen, GFP_KERNEL);
408 		if (err)
409 			goto free_req;
410 	}
411 
412 	rq->cmd_len = cmd_len;
413 	memset(rq->cmd, 0, BLK_MAX_CDB); /* ATAPI hates garbage after CDB */
414 	memcpy(rq->cmd, cmd, rq->cmd_len);
415 	req->timeout = timeout;
416 	rq->retries = retries;
417 	req->end_io_data = SRpnt;
418 
419 	blk_execute_rq_nowait(req->q, NULL, req, 1, osst_end_async);
420 	return 0;
421 free_req:
422 	blk_put_request(req);
423 	return DRIVER_ERROR << 24;
424 }
425 
426 /* Do the scsi command. Waits until command performed if do_wait is true.
427    Otherwise osst_write_behind_check() is used to check that the command
428    has finished. */
osst_do_scsi(struct osst_request * SRpnt,struct osst_tape * STp,unsigned char * cmd,int bytes,int direction,int timeout,int retries,int do_wait)429 static	struct osst_request * osst_do_scsi(struct osst_request *SRpnt, struct osst_tape *STp,
430 	unsigned char *cmd, int bytes, int direction, int timeout, int retries, int do_wait)
431 {
432 	unsigned char *bp;
433 	unsigned short use_sg;
434 #ifdef OSST_INJECT_ERRORS
435 	static   int   inject = 0;
436 	static   int   repeat = 0;
437 #endif
438 	struct completion *waiting;
439 
440 	/* if async, make sure there's no command outstanding */
441 	if (!do_wait && ((STp->buffer)->last_SRpnt)) {
442 		printk(KERN_ERR "%s: Async command already active.\n",
443 		       tape_name(STp));
444 		if (signal_pending(current))
445 			(STp->buffer)->syscall_result = (-EINTR);
446 		else
447 			(STp->buffer)->syscall_result = (-EBUSY);
448 		return NULL;
449 	}
450 
451 	if (SRpnt == NULL) {
452 		SRpnt = osst_allocate_request();
453 		if (SRpnt == NULL) {
454 			printk(KERN_ERR "%s: Can't allocate SCSI request.\n",
455 				     tape_name(STp));
456 			if (signal_pending(current))
457 				(STp->buffer)->syscall_result = (-EINTR);
458 			else
459 				(STp->buffer)->syscall_result = (-EBUSY);
460 			return NULL;
461 		}
462 		SRpnt->stp = STp;
463 	}
464 
465 	/* If async IO, set last_SRpnt. This ptr tells write_behind_check
466 	   which IO is outstanding. It's nulled out when the IO completes. */
467 	if (!do_wait)
468 		(STp->buffer)->last_SRpnt = SRpnt;
469 
470 	waiting = &STp->wait;
471 	init_completion(waiting);
472 	SRpnt->waiting = waiting;
473 
474 	use_sg = (bytes > STp->buffer->sg[0].length) ? STp->buffer->use_sg : 0;
475 	if (use_sg) {
476 		bp = (char *)&(STp->buffer->sg[0]);
477 		if (STp->buffer->sg_segs < use_sg)
478 			use_sg = STp->buffer->sg_segs;
479 	}
480 	else
481 		bp = (STp->buffer)->b_data;
482 
483 	memcpy(SRpnt->cmd, cmd, sizeof(SRpnt->cmd));
484 	STp->buffer->cmdstat.have_sense = 0;
485 	STp->buffer->syscall_result = 0;
486 
487 	if (osst_execute(SRpnt, cmd, COMMAND_SIZE(cmd[0]), direction, bp, bytes,
488 			 use_sg, timeout, retries))
489 		/* could not allocate the buffer or request was too large */
490 		(STp->buffer)->syscall_result = (-EBUSY);
491 	else if (do_wait) {
492 		wait_for_completion(waiting);
493 		SRpnt->waiting = NULL;
494 		STp->buffer->syscall_result = osst_chk_result(STp, SRpnt);
495 #ifdef OSST_INJECT_ERRORS
496 		if (STp->buffer->syscall_result == 0 &&
497 		    cmd[0] == READ_6 &&
498 		    cmd[4] &&
499 		    ( (++ inject % 83) == 29  ||
500 		      (STp->first_frame_position == 240
501 			         /* or STp->read_error_frame to fail again on the block calculated above */ &&
502 				 ++repeat < 3))) {
503 			printk(OSST_DEB_MSG "%s:D: Injecting read error\n", tape_name(STp));
504 			STp->buffer->last_result_fatal = 1;
505 		}
506 #endif
507 	}
508 	return SRpnt;
509 }
510 
511 
512 /* Handle the write-behind checking (downs the semaphore) */
osst_write_behind_check(struct osst_tape * STp)513 static void osst_write_behind_check(struct osst_tape *STp)
514 {
515 	struct osst_buffer * STbuffer;
516 
517 	STbuffer = STp->buffer;
518 
519 #if DEBUG
520 	if (STp->write_pending)
521 		STp->nbr_waits++;
522 	else
523 		STp->nbr_finished++;
524 #endif
525 	wait_for_completion(&(STp->wait));
526 	STp->buffer->last_SRpnt->waiting = NULL;
527 
528 	STp->buffer->syscall_result = osst_chk_result(STp, STp->buffer->last_SRpnt);
529 
530 	if (STp->buffer->syscall_result)
531 		STp->buffer->syscall_result =
532 			osst_write_error_recovery(STp, &(STp->buffer->last_SRpnt), 1);
533 	else
534 		STp->first_frame_position++;
535 
536 	osst_release_request(STp->buffer->last_SRpnt);
537 
538 	if (STbuffer->writing < STbuffer->buffer_bytes)
539 		printk(KERN_WARNING "osst :A: write_behind_check: something left in buffer!\n");
540 
541 	STbuffer->last_SRpnt = NULL;
542 	STbuffer->buffer_bytes -= STbuffer->writing;
543 	STbuffer->writing = 0;
544 
545 	return;
546 }
547 
548 
549 
550 /* Onstream specific Routines */
551 /*
552  * Initialize the OnStream AUX
553  */
osst_init_aux(struct osst_tape * STp,int frame_type,int frame_seq_number,int logical_blk_num,int blk_sz,int blk_cnt)554 static void osst_init_aux(struct osst_tape * STp, int frame_type, int frame_seq_number,
555 					 int logical_blk_num, int blk_sz, int blk_cnt)
556 {
557 	os_aux_t       *aux = STp->buffer->aux;
558 	os_partition_t *par = &aux->partition;
559 	os_dat_t       *dat = &aux->dat;
560 
561 	if (STp->raw) return;
562 
563 	memset(aux, 0, sizeof(*aux));
564 	aux->format_id = htonl(0);
565 	memcpy(aux->application_sig, "LIN4", 4);
566 	aux->hdwr = htonl(0);
567 	aux->frame_type = frame_type;
568 
569 	switch (frame_type) {
570 	  case	OS_FRAME_TYPE_HEADER:
571 		aux->update_frame_cntr    = htonl(STp->update_frame_cntr);
572 		par->partition_num        = OS_CONFIG_PARTITION;
573 		par->par_desc_ver         = OS_PARTITION_VERSION;
574 		par->wrt_pass_cntr        = htons(0xffff);
575 		/* 0-4 = reserved, 5-9 = header, 2990-2994 = header, 2995-2999 = reserved */
576 		par->first_frame_ppos     = htonl(0);
577 		par->last_frame_ppos      = htonl(0xbb7);
578 		aux->frame_seq_num        = htonl(0);
579 		aux->logical_blk_num_high = htonl(0);
580 		aux->logical_blk_num      = htonl(0);
581 		aux->next_mark_ppos       = htonl(STp->first_mark_ppos);
582 		break;
583 	  case	OS_FRAME_TYPE_DATA:
584 	  case	OS_FRAME_TYPE_MARKER:
585 		dat->dat_sz = 8;
586 		dat->reserved1 = 0;
587 		dat->entry_cnt = 1;
588 		dat->reserved3 = 0;
589 		dat->dat_list[0].blk_sz   = htonl(blk_sz);
590 		dat->dat_list[0].blk_cnt  = htons(blk_cnt);
591 		dat->dat_list[0].flags    = frame_type==OS_FRAME_TYPE_MARKER?
592 							OS_DAT_FLAGS_MARK:OS_DAT_FLAGS_DATA;
593 		dat->dat_list[0].reserved = 0;
594 	  case	OS_FRAME_TYPE_EOD:
595 		aux->update_frame_cntr    = htonl(0);
596 		par->partition_num        = OS_DATA_PARTITION;
597 		par->par_desc_ver         = OS_PARTITION_VERSION;
598 		par->wrt_pass_cntr        = htons(STp->wrt_pass_cntr);
599 		par->first_frame_ppos     = htonl(STp->first_data_ppos);
600 		par->last_frame_ppos      = htonl(STp->capacity);
601 		aux->frame_seq_num        = htonl(frame_seq_number);
602 		aux->logical_blk_num_high = htonl(0);
603 		aux->logical_blk_num      = htonl(logical_blk_num);
604 		break;
605 	  default: ; /* probably FILL */
606 	}
607 	aux->filemark_cnt = htonl(STp->filemark_cnt);
608 	aux->phys_fm = htonl(0xffffffff);
609 	aux->last_mark_ppos = htonl(STp->last_mark_ppos);
610 	aux->last_mark_lbn  = htonl(STp->last_mark_lbn);
611 }
612 
613 /*
614  * Verify that we have the correct tape frame
615  */
osst_verify_frame(struct osst_tape * STp,int frame_seq_number,int quiet)616 static int osst_verify_frame(struct osst_tape * STp, int frame_seq_number, int quiet)
617 {
618 	char               * name = tape_name(STp);
619 	os_aux_t           * aux  = STp->buffer->aux;
620 	os_partition_t     * par  = &(aux->partition);
621 	struct st_partstat * STps = &(STp->ps[STp->partition]);
622 	unsigned int	     blk_cnt, blk_sz, i;
623 
624 	if (STp->raw) {
625 		if (STp->buffer->syscall_result) {
626 			for (i=0; i < STp->buffer->sg_segs; i++)
627 				memset(page_address(sg_page(&STp->buffer->sg[i])),
628 				       0, STp->buffer->sg[i].length);
629 			strcpy(STp->buffer->b_data, "READ ERROR ON FRAME");
630                 } else
631 			STp->buffer->buffer_bytes = OS_FRAME_SIZE;
632 		return 1;
633 	}
634 	if (STp->buffer->syscall_result) {
635 #if DEBUG
636 		printk(OSST_DEB_MSG "%s:D: Skipping frame, read error\n", name);
637 #endif
638 		return 0;
639 	}
640 	if (ntohl(aux->format_id) != 0) {
641 #if DEBUG
642 		printk(OSST_DEB_MSG "%s:D: Skipping frame, format_id %u\n", name, ntohl(aux->format_id));
643 #endif
644 		goto err_out;
645 	}
646 	if (memcmp(aux->application_sig, STp->application_sig, 4) != 0 &&
647 	    (memcmp(aux->application_sig, "LIN3", 4) != 0 || STp->linux_media_version != 4)) {
648 #if DEBUG
649 		printk(OSST_DEB_MSG "%s:D: Skipping frame, incorrect application signature\n", name);
650 #endif
651 		goto err_out;
652 	}
653 	if (par->partition_num != OS_DATA_PARTITION) {
654 		if (!STp->linux_media || STp->linux_media_version != 2) {
655 #if DEBUG
656 			printk(OSST_DEB_MSG "%s:D: Skipping frame, partition num %d\n",
657 					    name, par->partition_num);
658 #endif
659 			goto err_out;
660 		}
661 	}
662 	if (par->par_desc_ver != OS_PARTITION_VERSION) {
663 #if DEBUG
664 		printk(OSST_DEB_MSG "%s:D: Skipping frame, partition version %d\n", name, par->par_desc_ver);
665 #endif
666 		goto err_out;
667 	}
668 	if (ntohs(par->wrt_pass_cntr) != STp->wrt_pass_cntr) {
669 #if DEBUG
670 		printk(OSST_DEB_MSG "%s:D: Skipping frame, wrt_pass_cntr %d (expected %d)\n",
671 				    name, ntohs(par->wrt_pass_cntr), STp->wrt_pass_cntr);
672 #endif
673 		goto err_out;
674 	}
675 	if (aux->frame_type != OS_FRAME_TYPE_DATA &&
676 	    aux->frame_type != OS_FRAME_TYPE_EOD &&
677 	    aux->frame_type != OS_FRAME_TYPE_MARKER) {
678 		if (!quiet) {
679 #if DEBUG
680 			printk(OSST_DEB_MSG "%s:D: Skipping frame, frame type %x\n", name, aux->frame_type);
681 #endif
682 		}
683 		goto err_out;
684 	}
685 	if (aux->frame_type == OS_FRAME_TYPE_EOD &&
686 	    STp->first_frame_position < STp->eod_frame_ppos) {
687 		printk(KERN_INFO "%s:I: Skipping premature EOD frame %d\n", name,
688 				 STp->first_frame_position);
689 		goto err_out;
690 	}
691         if (frame_seq_number != -1 && ntohl(aux->frame_seq_num) != frame_seq_number) {
692 		if (!quiet) {
693 #if DEBUG
694 			printk(OSST_DEB_MSG "%s:D: Skipping frame, sequence number %u (expected %d)\n",
695 					    name, ntohl(aux->frame_seq_num), frame_seq_number);
696 #endif
697 		}
698 		goto err_out;
699 	}
700 	if (aux->frame_type == OS_FRAME_TYPE_MARKER) {
701 		STps->eof = ST_FM_HIT;
702 
703 		i = ntohl(aux->filemark_cnt);
704 		if (STp->header_cache != NULL && i < OS_FM_TAB_MAX && (i > STp->filemark_cnt ||
705 		    STp->first_frame_position - 1 != ntohl(STp->header_cache->dat_fm_tab.fm_tab_ent[i]))) {
706 #if DEBUG
707 			printk(OSST_DEB_MSG "%s:D: %s filemark %d at frame pos %d\n", name,
708 				  STp->header_cache->dat_fm_tab.fm_tab_ent[i] == 0?"Learned":"Corrected",
709 				  i, STp->first_frame_position - 1);
710 #endif
711 			STp->header_cache->dat_fm_tab.fm_tab_ent[i] = htonl(STp->first_frame_position - 1);
712 			if (i >= STp->filemark_cnt)
713 				 STp->filemark_cnt = i+1;
714 		}
715 	}
716 	if (aux->frame_type == OS_FRAME_TYPE_EOD) {
717 		STps->eof = ST_EOD_1;
718 		STp->frame_in_buffer = 1;
719 	}
720 	if (aux->frame_type == OS_FRAME_TYPE_DATA) {
721                 blk_cnt = ntohs(aux->dat.dat_list[0].blk_cnt);
722 		blk_sz  = ntohl(aux->dat.dat_list[0].blk_sz);
723 		STp->buffer->buffer_bytes = blk_cnt * blk_sz;
724 		STp->buffer->read_pointer = 0;
725 		STp->frame_in_buffer = 1;
726 
727 		/* See what block size was used to write file */
728 		if (STp->block_size != blk_sz && blk_sz > 0) {
729 			printk(KERN_INFO
730 	    	"%s:I: File was written with block size %d%c, currently %d%c, adjusted to match.\n",
731        				name, blk_sz<1024?blk_sz:blk_sz/1024,blk_sz<1024?'b':'k',
732 				STp->block_size<1024?STp->block_size:STp->block_size/1024,
733 				STp->block_size<1024?'b':'k');
734 			STp->block_size            = blk_sz;
735 			STp->buffer->buffer_blocks = OS_DATA_SIZE / blk_sz;
736 		}
737 		STps->eof = ST_NOEOF;
738 	}
739         STp->frame_seq_number = ntohl(aux->frame_seq_num);
740 	STp->logical_blk_num  = ntohl(aux->logical_blk_num);
741 	return 1;
742 
743 err_out:
744 	if (STp->read_error_frame == 0)
745 		STp->read_error_frame = STp->first_frame_position - 1;
746 	return 0;
747 }
748 
749 /*
750  * Wait for the unit to become Ready
751  */
osst_wait_ready(struct osst_tape * STp,struct osst_request ** aSRpnt,unsigned timeout,int initial_delay)752 static int osst_wait_ready(struct osst_tape * STp, struct osst_request ** aSRpnt,
753 				 unsigned timeout, int initial_delay)
754 {
755 	unsigned char		cmd[MAX_COMMAND_SIZE];
756 	struct osst_request   * SRpnt;
757 	unsigned long		startwait = jiffies;
758 #if DEBUG
759 	int			dbg  = debugging;
760 	char    	      * name = tape_name(STp);
761 
762 	printk(OSST_DEB_MSG "%s:D: Reached onstream wait ready\n", name);
763 #endif
764 
765 	if (initial_delay > 0)
766 		msleep(jiffies_to_msecs(initial_delay));
767 
768 	memset(cmd, 0, MAX_COMMAND_SIZE);
769 	cmd[0] = TEST_UNIT_READY;
770 
771 	SRpnt = osst_do_scsi(*aSRpnt, STp, cmd, 0, DMA_NONE, STp->timeout, MAX_RETRIES, 1);
772 	*aSRpnt = SRpnt;
773 	if (!SRpnt) return (-EBUSY);
774 
775 	while ( STp->buffer->syscall_result && time_before(jiffies, startwait + timeout*HZ) &&
776 	       (( SRpnt->sense[2]  == 2 && SRpnt->sense[12] == 4    &&
777 		 (SRpnt->sense[13] == 1 || SRpnt->sense[13] == 8)    ) ||
778 		( SRpnt->sense[2]  == 6 && SRpnt->sense[12] == 0x28 &&
779 		  SRpnt->sense[13] == 0                                        )  )) {
780 #if DEBUG
781 	    if (debugging) {
782 		printk(OSST_DEB_MSG "%s:D: Sleeping in onstream wait ready\n", name);
783 		printk(OSST_DEB_MSG "%s:D: Turning off debugging for a while\n", name);
784 		debugging = 0;
785 	    }
786 #endif
787 	    msleep(100);
788 
789 	    memset(cmd, 0, MAX_COMMAND_SIZE);
790 	    cmd[0] = TEST_UNIT_READY;
791 
792 	    SRpnt = osst_do_scsi(SRpnt, STp, cmd, 0, DMA_NONE, STp->timeout, MAX_RETRIES, 1);
793 	}
794 	*aSRpnt = SRpnt;
795 #if DEBUG
796 	debugging = dbg;
797 #endif
798 	if ( STp->buffer->syscall_result &&
799 	     osst_write_error_recovery(STp, aSRpnt, 0) ) {
800 #if DEBUG
801 	    printk(OSST_DEB_MSG "%s:D: Abnormal exit from onstream wait ready\n", name);
802 	    printk(OSST_DEB_MSG "%s:D: Result = %d, Sense: 0=%02x, 2=%02x, 12=%02x, 13=%02x\n", name,
803 			STp->buffer->syscall_result, SRpnt->sense[0], SRpnt->sense[2],
804 			SRpnt->sense[12], SRpnt->sense[13]);
805 #endif
806 	    return (-EIO);
807 	}
808 #if DEBUG
809 	printk(OSST_DEB_MSG "%s:D: Normal exit from onstream wait ready\n", name);
810 #endif
811 	return 0;
812 }
813 
814 /*
815  * Wait for a tape to be inserted in the unit
816  */
osst_wait_for_medium(struct osst_tape * STp,struct osst_request ** aSRpnt,unsigned timeout)817 static int osst_wait_for_medium(struct osst_tape * STp, struct osst_request ** aSRpnt, unsigned timeout)
818 {
819 	unsigned char		cmd[MAX_COMMAND_SIZE];
820 	struct osst_request   * SRpnt;
821 	unsigned long		startwait = jiffies;
822 #if DEBUG
823 	int			dbg = debugging;
824 	char    	      * name = tape_name(STp);
825 
826 	printk(OSST_DEB_MSG "%s:D: Reached onstream wait for medium\n", name);
827 #endif
828 
829 	memset(cmd, 0, MAX_COMMAND_SIZE);
830 	cmd[0] = TEST_UNIT_READY;
831 
832 	SRpnt = osst_do_scsi(*aSRpnt, STp, cmd, 0, DMA_NONE, STp->timeout, MAX_RETRIES, 1);
833 	*aSRpnt = SRpnt;
834 	if (!SRpnt) return (-EBUSY);
835 
836 	while ( STp->buffer->syscall_result && time_before(jiffies, startwait + timeout*HZ) &&
837 		SRpnt->sense[2] == 2 && SRpnt->sense[12] == 0x3a && SRpnt->sense[13] == 0  ) {
838 #if DEBUG
839 	    if (debugging) {
840 		printk(OSST_DEB_MSG "%s:D: Sleeping in onstream wait medium\n", name);
841 		printk(OSST_DEB_MSG "%s:D: Turning off debugging for a while\n", name);
842 		debugging = 0;
843 	    }
844 #endif
845 	    msleep(100);
846 
847 	    memset(cmd, 0, MAX_COMMAND_SIZE);
848 	    cmd[0] = TEST_UNIT_READY;
849 
850 	    SRpnt = osst_do_scsi(SRpnt, STp, cmd, 0, DMA_NONE, STp->timeout, MAX_RETRIES, 1);
851 	}
852 	*aSRpnt = SRpnt;
853 #if DEBUG
854 	debugging = dbg;
855 #endif
856 	if ( STp->buffer->syscall_result     && SRpnt->sense[2]  != 2 &&
857 	     SRpnt->sense[12] != 4 && SRpnt->sense[13] == 1) {
858 #if DEBUG
859 	    printk(OSST_DEB_MSG "%s:D: Abnormal exit from onstream wait medium\n", name);
860 	    printk(OSST_DEB_MSG "%s:D: Result = %d, Sense: 0=%02x, 2=%02x, 12=%02x, 13=%02x\n", name,
861 			STp->buffer->syscall_result, SRpnt->sense[0], SRpnt->sense[2],
862 			SRpnt->sense[12], SRpnt->sense[13]);
863 #endif
864 	    return 0;
865 	}
866 #if DEBUG
867 	printk(OSST_DEB_MSG "%s:D: Normal exit from onstream wait medium\n", name);
868 #endif
869 	return 1;
870 }
871 
osst_position_tape_and_confirm(struct osst_tape * STp,struct osst_request ** aSRpnt,int frame)872 static int osst_position_tape_and_confirm(struct osst_tape * STp, struct osst_request ** aSRpnt, int frame)
873 {
874 	int	retval;
875 
876 	osst_wait_ready(STp, aSRpnt, 15 * 60, 0);			/* TODO - can this catch a write error? */
877 	retval = osst_set_frame_position(STp, aSRpnt, frame, 0);
878 	if (retval) return (retval);
879 	osst_wait_ready(STp, aSRpnt, 15 * 60, OSST_WAIT_POSITION_COMPLETE);
880 	return (osst_get_frame_position(STp, aSRpnt));
881 }
882 
883 /*
884  * Wait for write(s) to complete
885  */
osst_flush_drive_buffer(struct osst_tape * STp,struct osst_request ** aSRpnt)886 static int osst_flush_drive_buffer(struct osst_tape * STp, struct osst_request ** aSRpnt)
887 {
888 	unsigned char		cmd[MAX_COMMAND_SIZE];
889 	struct osst_request   * SRpnt;
890 	int			result = 0;
891 	int			delay  = OSST_WAIT_WRITE_COMPLETE;
892 #if DEBUG
893 	char		      * name = tape_name(STp);
894 
895 	printk(OSST_DEB_MSG "%s:D: Reached onstream flush drive buffer (write filemark)\n", name);
896 #endif
897 
898 	memset(cmd, 0, MAX_COMMAND_SIZE);
899 	cmd[0] = WRITE_FILEMARKS;
900 	cmd[1] = 1;
901 
902 	SRpnt = osst_do_scsi(*aSRpnt, STp, cmd, 0, DMA_NONE, STp->timeout, MAX_RETRIES, 1);
903 	*aSRpnt = SRpnt;
904 	if (!SRpnt) return (-EBUSY);
905 	if (STp->buffer->syscall_result) {
906 		if ((SRpnt->sense[2] & 0x0f) == 2 && SRpnt->sense[12] == 4) {
907 			if (SRpnt->sense[13] == 8) {
908 				delay = OSST_WAIT_LONG_WRITE_COMPLETE;
909 			}
910 		} else
911 			result = osst_write_error_recovery(STp, aSRpnt, 0);
912 	}
913 	result |= osst_wait_ready(STp, aSRpnt, 5 * 60, delay);
914 	STp->ps[STp->partition].rw = OS_WRITING_COMPLETE;
915 
916 	return (result);
917 }
918 
919 #define OSST_POLL_PER_SEC 10
osst_wait_frame(struct osst_tape * STp,struct osst_request ** aSRpnt,int curr,int minlast,int to)920 static int osst_wait_frame(struct osst_tape * STp, struct osst_request ** aSRpnt, int curr, int minlast, int to)
921 {
922 	unsigned long	startwait = jiffies;
923 	char	      * name      = tape_name(STp);
924 #if DEBUG
925 	char	   notyetprinted  = 1;
926 #endif
927 	if (minlast >= 0 && STp->ps[STp->partition].rw != ST_READING)
928 		printk(KERN_ERR "%s:A: Waiting for frame without having initialized read!\n", name);
929 
930 	while (time_before (jiffies, startwait + to*HZ))
931 	{
932 		int result;
933 		result = osst_get_frame_position(STp, aSRpnt);
934 		if (result == -EIO)
935 			if ((result = osst_write_error_recovery(STp, aSRpnt, 0)) == 0)
936 				return 0;	/* successful recovery leaves drive ready for frame */
937 		if (result < 0) break;
938 		if (STp->first_frame_position == curr &&
939 		    ((minlast < 0 &&
940 		      (signed)STp->last_frame_position > (signed)curr + minlast) ||
941 		     (minlast >= 0 && STp->cur_frames > minlast)
942 		    ) && result >= 0)
943 		{
944 #if DEBUG
945 			if (debugging || time_after_eq(jiffies, startwait + 2*HZ/OSST_POLL_PER_SEC))
946 				printk (OSST_DEB_MSG
947 					"%s:D: Succ wait f fr %i (>%i): %i-%i %i (%i): %3li.%li s\n",
948 					name, curr, curr+minlast, STp->first_frame_position,
949 					STp->last_frame_position, STp->cur_frames,
950 					result, (jiffies-startwait)/HZ,
951 					(((jiffies-startwait)%HZ)*10)/HZ);
952 #endif
953 			return 0;
954 		}
955 #if DEBUG
956 		if (time_after_eq(jiffies, startwait + 2*HZ/OSST_POLL_PER_SEC) && notyetprinted)
957 		{
958 			printk (OSST_DEB_MSG "%s:D: Wait for frame %i (>%i): %i-%i %i (%i)\n",
959 				name, curr, curr+minlast, STp->first_frame_position,
960 				STp->last_frame_position, STp->cur_frames, result);
961 			notyetprinted--;
962 		}
963 #endif
964 		msleep(1000 / OSST_POLL_PER_SEC);
965 	}
966 #if DEBUG
967 	printk (OSST_DEB_MSG "%s:D: Fail wait f fr %i (>%i): %i-%i %i: %3li.%li s\n",
968 		name, curr, curr+minlast, STp->first_frame_position,
969 		STp->last_frame_position, STp->cur_frames,
970 		(jiffies-startwait)/HZ, (((jiffies-startwait)%HZ)*10)/HZ);
971 #endif
972 	return -EBUSY;
973 }
974 
osst_recover_wait_frame(struct osst_tape * STp,struct osst_request ** aSRpnt,int writing)975 static int osst_recover_wait_frame(struct osst_tape * STp, struct osst_request ** aSRpnt, int writing)
976 {
977 	struct osst_request   * SRpnt;
978 	unsigned char		cmd[MAX_COMMAND_SIZE];
979 	unsigned long   	startwait = jiffies;
980 	int			retval    = 1;
981         char		      * name      = tape_name(STp);
982 
983 	if (writing) {
984 		char	mybuf[24];
985 		char  * olddata = STp->buffer->b_data;
986 		int	oldsize = STp->buffer->buffer_size;
987 
988 		/* write zero fm then read pos - if shows write error, try to recover - if no progress, wait */
989 
990 		memset(cmd, 0, MAX_COMMAND_SIZE);
991 		cmd[0] = WRITE_FILEMARKS;
992 		cmd[1] = 1;
993 		SRpnt = osst_do_scsi(*aSRpnt, STp, cmd, 0, DMA_NONE, STp->timeout,
994 								MAX_RETRIES, 1);
995 
996 		while (retval && time_before (jiffies, startwait + 5*60*HZ)) {
997 
998 			if (STp->buffer->syscall_result && (SRpnt->sense[2] & 0x0f) != 2) {
999 
1000 				/* some failure - not just not-ready */
1001 				retval = osst_write_error_recovery(STp, aSRpnt, 0);
1002 				break;
1003 			}
1004 			schedule_timeout_interruptible(HZ / OSST_POLL_PER_SEC);
1005 
1006 			STp->buffer->b_data = mybuf; STp->buffer->buffer_size = 24;
1007 			memset(cmd, 0, MAX_COMMAND_SIZE);
1008 			cmd[0] = READ_POSITION;
1009 
1010 			SRpnt = osst_do_scsi(SRpnt, STp, cmd, 20, DMA_FROM_DEVICE, STp->timeout,
1011 										MAX_RETRIES, 1);
1012 
1013 			retval = ( STp->buffer->syscall_result || (STp->buffer)->b_data[15] > 25 );
1014 			STp->buffer->b_data = olddata; STp->buffer->buffer_size = oldsize;
1015 		}
1016 		if (retval)
1017 			printk(KERN_ERR "%s:E: Device did not succeed to write buffered data\n", name);
1018 	} else
1019 		/* TODO - figure out which error conditions can be handled */
1020 		if (STp->buffer->syscall_result)
1021 			printk(KERN_WARNING
1022 				"%s:W: Recover_wait_frame(read) cannot handle %02x:%02x:%02x\n", name,
1023 					(*aSRpnt)->sense[ 2] & 0x0f,
1024 					(*aSRpnt)->sense[12],
1025 					(*aSRpnt)->sense[13]);
1026 
1027 	return retval;
1028 }
1029 
1030 /*
1031  * Read the next OnStream tape frame at the current location
1032  */
osst_read_frame(struct osst_tape * STp,struct osst_request ** aSRpnt,int timeout)1033 static int osst_read_frame(struct osst_tape * STp, struct osst_request ** aSRpnt, int timeout)
1034 {
1035 	unsigned char		cmd[MAX_COMMAND_SIZE];
1036 	struct osst_request   * SRpnt;
1037 	int			retval = 0;
1038 #if DEBUG
1039 	os_aux_t	      * aux    = STp->buffer->aux;
1040 	char		      * name   = tape_name(STp);
1041 #endif
1042 
1043 	if (STp->poll)
1044 		if (osst_wait_frame (STp, aSRpnt, STp->first_frame_position, 0, timeout))
1045 			retval = osst_recover_wait_frame(STp, aSRpnt, 0);
1046 
1047 	memset(cmd, 0, MAX_COMMAND_SIZE);
1048 	cmd[0] = READ_6;
1049 	cmd[1] = 1;
1050 	cmd[4] = 1;
1051 
1052 #if DEBUG
1053 	if (debugging)
1054 		printk(OSST_DEB_MSG "%s:D: Reading frame from OnStream tape\n", name);
1055 #endif
1056 	SRpnt = osst_do_scsi(*aSRpnt, STp, cmd, OS_FRAME_SIZE, DMA_FROM_DEVICE,
1057 				      STp->timeout, MAX_RETRIES, 1);
1058 	*aSRpnt = SRpnt;
1059 	if (!SRpnt)
1060 		return (-EBUSY);
1061 
1062 	if ((STp->buffer)->syscall_result) {
1063 	    retval = 1;
1064 	    if (STp->read_error_frame == 0) {
1065 		STp->read_error_frame = STp->first_frame_position;
1066 #if DEBUG
1067 		printk(OSST_DEB_MSG "%s:D: Recording read error at %d\n", name, STp->read_error_frame);
1068 #endif
1069 	    }
1070 #if DEBUG
1071 	    if (debugging)
1072 		printk(OSST_DEB_MSG "%s:D: Sense: %2x %2x %2x %2x %2x %2x %2x %2x\n",
1073 		   name,
1074 		   SRpnt->sense[0], SRpnt->sense[1],
1075 		   SRpnt->sense[2], SRpnt->sense[3],
1076 		   SRpnt->sense[4], SRpnt->sense[5],
1077 		   SRpnt->sense[6], SRpnt->sense[7]);
1078 #endif
1079 	}
1080 	else
1081 	    STp->first_frame_position++;
1082 #if DEBUG
1083 	if (debugging) {
1084 	   char sig[8]; int i;
1085 	   for (i=0;i<4;i++)
1086 		   sig[i] = aux->application_sig[i]<32?'^':aux->application_sig[i];
1087 	   sig[4] = '\0';
1088 	   printk(OSST_DEB_MSG
1089 		"%s:D: AUX: %s UpdFrCt#%d Wpass#%d %s FrSeq#%d LogBlk#%d Qty=%d Sz=%d\n", name, sig,
1090 			ntohl(aux->update_frame_cntr), ntohs(aux->partition.wrt_pass_cntr),
1091 			aux->frame_type==1?"EOD":aux->frame_type==2?"MARK":
1092 			aux->frame_type==8?"HEADR":aux->frame_type==0x80?"DATA":"FILL",
1093 			ntohl(aux->frame_seq_num), ntohl(aux->logical_blk_num),
1094 			ntohs(aux->dat.dat_list[0].blk_cnt), ntohl(aux->dat.dat_list[0].blk_sz) );
1095 	   if (aux->frame_type==2)
1096 		printk(OSST_DEB_MSG "%s:D: mark_cnt=%d, last_mark_ppos=%d, last_mark_lbn=%d\n", name,
1097 			ntohl(aux->filemark_cnt), ntohl(aux->last_mark_ppos), ntohl(aux->last_mark_lbn));
1098 	   printk(OSST_DEB_MSG "%s:D: Exit read frame from OnStream tape with code %d\n", name, retval);
1099 	}
1100 #endif
1101 	return (retval);
1102 }
1103 
osst_initiate_read(struct osst_tape * STp,struct osst_request ** aSRpnt)1104 static int osst_initiate_read(struct osst_tape * STp, struct osst_request ** aSRpnt)
1105 {
1106 	struct st_partstat    * STps   = &(STp->ps[STp->partition]);
1107 	struct osst_request   * SRpnt  ;
1108 	unsigned char		cmd[MAX_COMMAND_SIZE];
1109 	int			retval = 0;
1110 	char		      * name   = tape_name(STp);
1111 
1112 	if (STps->rw != ST_READING) {         /* Initialize read operation */
1113 		if (STps->rw == ST_WRITING || STp->dirty) {
1114 			STp->write_type = OS_WRITE_DATA;
1115                         osst_flush_write_buffer(STp, aSRpnt);
1116 			osst_flush_drive_buffer(STp, aSRpnt);
1117 		}
1118 		STps->rw = ST_READING;
1119 		STp->frame_in_buffer = 0;
1120 
1121 		/*
1122 		 *      Issue a read 0 command to get the OnStream drive
1123                  *      read frames into its buffer.
1124 		 */
1125 		memset(cmd, 0, MAX_COMMAND_SIZE);
1126 		cmd[0] = READ_6;
1127 		cmd[1] = 1;
1128 
1129 #if DEBUG
1130 		printk(OSST_DEB_MSG "%s:D: Start Read Ahead on OnStream tape\n", name);
1131 #endif
1132 		SRpnt   = osst_do_scsi(*aSRpnt, STp, cmd, 0, DMA_NONE, STp->timeout, MAX_RETRIES, 1);
1133 		*aSRpnt = SRpnt;
1134 		if ((retval = STp->buffer->syscall_result))
1135 			printk(KERN_WARNING "%s:W: Error starting read ahead\n", name);
1136 	}
1137 
1138 	return retval;
1139 }
1140 
osst_get_logical_frame(struct osst_tape * STp,struct osst_request ** aSRpnt,int frame_seq_number,int quiet)1141 static int osst_get_logical_frame(struct osst_tape * STp, struct osst_request ** aSRpnt,
1142 						int frame_seq_number, int quiet)
1143 {
1144 	struct st_partstat * STps  = &(STp->ps[STp->partition]);
1145 	char		   * name  = tape_name(STp);
1146 	int		     cnt   = 0,
1147 			     bad   = 0,
1148 			     past  = 0,
1149 			     x,
1150 			     position;
1151 
1152 	/*
1153 	 * If we want just any frame (-1) and there is a frame in the buffer, return it
1154 	 */
1155 	if (frame_seq_number == -1 && STp->frame_in_buffer) {
1156 #if DEBUG
1157 		printk(OSST_DEB_MSG "%s:D: Frame %d still in buffer\n", name, STp->frame_seq_number);
1158 #endif
1159 		return (STps->eof);
1160 	}
1161 	/*
1162          * Search and wait for the next logical tape frame
1163 	 */
1164 	while (1) {
1165 		if (cnt++ > 400) {
1166                         printk(KERN_ERR "%s:E: Couldn't find logical frame %d, aborting\n",
1167 					    name, frame_seq_number);
1168 			if (STp->read_error_frame) {
1169 				osst_set_frame_position(STp, aSRpnt, STp->read_error_frame, 0);
1170 #if DEBUG
1171                         	printk(OSST_DEB_MSG "%s:D: Repositioning tape to bad frame %d\n",
1172 						    name, STp->read_error_frame);
1173 #endif
1174 				STp->read_error_frame = 0;
1175 				STp->abort_count++;
1176 			}
1177 			return (-EIO);
1178 		}
1179 #if DEBUG
1180 		if (debugging)
1181 			printk(OSST_DEB_MSG "%s:D: Looking for frame %d, attempt %d\n",
1182 					  name, frame_seq_number, cnt);
1183 #endif
1184 		if ( osst_initiate_read(STp, aSRpnt)
1185                 || ( (!STp->frame_in_buffer) && osst_read_frame(STp, aSRpnt, 30) ) ) {
1186 			if (STp->raw)
1187 				return (-EIO);
1188 			position = osst_get_frame_position(STp, aSRpnt);
1189 			if (position >= 0xbae && position < 0xbb8)
1190 				position = 0xbb8;
1191 			else if (position > STp->eod_frame_ppos || ++bad == 10) {
1192 				position = STp->read_error_frame - 1;
1193 				bad = 0;
1194 			}
1195 			else {
1196 				position += 29;
1197 				cnt      += 19;
1198 			}
1199 #if DEBUG
1200 			printk(OSST_DEB_MSG "%s:D: Bad frame detected, positioning tape to block %d\n",
1201 					 name, position);
1202 #endif
1203 			osst_set_frame_position(STp, aSRpnt, position, 0);
1204 			continue;
1205 		}
1206 		if (osst_verify_frame(STp, frame_seq_number, quiet))
1207 			break;
1208 		if (osst_verify_frame(STp, -1, quiet)) {
1209 			x = ntohl(STp->buffer->aux->frame_seq_num);
1210 			if (STp->fast_open) {
1211 				printk(KERN_WARNING
1212 				       "%s:W: Found logical frame %d instead of %d after fast open\n",
1213 				       name, x, frame_seq_number);
1214 				STp->header_ok = 0;
1215 				STp->read_error_frame = 0;
1216 				return (-EIO);
1217 			}
1218 			if (x > frame_seq_number) {
1219 				if (++past > 3) {
1220 					/* positioning backwards did not bring us to the desired frame */
1221 					position = STp->read_error_frame - 1;
1222 				}
1223 				else {
1224 			        	position = osst_get_frame_position(STp, aSRpnt)
1225 					         + frame_seq_number - x - 1;
1226 
1227 					if (STp->first_frame_position >= 3000 && position < 3000)
1228 						position -= 10;
1229 				}
1230 #if DEBUG
1231                                 printk(OSST_DEB_MSG
1232 				       "%s:D: Found logical frame %d while looking for %d: back up %d\n",
1233 						name, x, frame_seq_number,
1234 					       	STp->first_frame_position - position);
1235 #endif
1236                         	osst_set_frame_position(STp, aSRpnt, position, 0);
1237 				cnt += 10;
1238 			}
1239 			else
1240 				past = 0;
1241 		}
1242 		if (osst_get_frame_position(STp, aSRpnt) == 0xbaf) {
1243 #if DEBUG
1244 			printk(OSST_DEB_MSG "%s:D: Skipping config partition\n", name);
1245 #endif
1246 			osst_set_frame_position(STp, aSRpnt, 0xbb8, 0);
1247 			cnt--;
1248 		}
1249 		STp->frame_in_buffer = 0;
1250 	}
1251 	if (cnt > 1) {
1252 		STp->recover_count++;
1253 		STp->recover_erreg++;
1254 		printk(KERN_WARNING "%s:I: Don't worry, Read error at position %d recovered\n",
1255 					name, STp->read_error_frame);
1256  	}
1257 	STp->read_count++;
1258 
1259 #if DEBUG
1260 	if (debugging || STps->eof)
1261 		printk(OSST_DEB_MSG
1262 			"%s:D: Exit get logical frame (%d=>%d) from OnStream tape with code %d\n",
1263 			name, frame_seq_number, STp->frame_seq_number, STps->eof);
1264 #endif
1265 	STp->fast_open = 0;
1266 	STp->read_error_frame = 0;
1267 	return (STps->eof);
1268 }
1269 
osst_seek_logical_blk(struct osst_tape * STp,struct osst_request ** aSRpnt,int logical_blk_num)1270 static int osst_seek_logical_blk(struct osst_tape * STp, struct osst_request ** aSRpnt, int logical_blk_num)
1271 {
1272         struct st_partstat * STps = &(STp->ps[STp->partition]);
1273 	char		   * name = tape_name(STp);
1274 	int	retries    = 0;
1275 	int	frame_seq_estimate, ppos_estimate, move;
1276 
1277 	if (logical_blk_num < 0) logical_blk_num = 0;
1278 #if DEBUG
1279 	printk(OSST_DEB_MSG "%s:D: Seeking logical block %d (now at %d, size %d%c)\n",
1280 				name, logical_blk_num, STp->logical_blk_num,
1281 				STp->block_size<1024?STp->block_size:STp->block_size/1024,
1282 				STp->block_size<1024?'b':'k');
1283 #endif
1284 	/* Do we know where we are? */
1285 	if (STps->drv_block >= 0) {
1286 		move                = logical_blk_num - STp->logical_blk_num;
1287 		if (move < 0) move -= (OS_DATA_SIZE / STp->block_size) - 1;
1288 		move               /= (OS_DATA_SIZE / STp->block_size);
1289 		frame_seq_estimate  = STp->frame_seq_number + move;
1290 	} else
1291 		frame_seq_estimate  = logical_blk_num * STp->block_size / OS_DATA_SIZE;
1292 
1293 	if (frame_seq_estimate < 2980) ppos_estimate = frame_seq_estimate + 10;
1294 	else			       ppos_estimate = frame_seq_estimate + 20;
1295 	while (++retries < 10) {
1296 	   if (ppos_estimate > STp->eod_frame_ppos-2) {
1297 	       frame_seq_estimate += STp->eod_frame_ppos - 2 - ppos_estimate;
1298 	       ppos_estimate       = STp->eod_frame_ppos - 2;
1299 	   }
1300 	   if (frame_seq_estimate < 0) {
1301 	       frame_seq_estimate = 0;
1302 	       ppos_estimate      = 10;
1303 	   }
1304 	   osst_set_frame_position(STp, aSRpnt, ppos_estimate, 0);
1305 	   if (osst_get_logical_frame(STp, aSRpnt, frame_seq_estimate, 1) >= 0) {
1306 	      /* we've located the estimated frame, now does it have our block? */
1307 	      if (logical_blk_num <  STp->logical_blk_num ||
1308 	          logical_blk_num >= STp->logical_blk_num + ntohs(STp->buffer->aux->dat.dat_list[0].blk_cnt)) {
1309 		 if (STps->eof == ST_FM_HIT)
1310 		    move = logical_blk_num < STp->logical_blk_num? -2 : 1;
1311 		 else {
1312 		    move                = logical_blk_num - STp->logical_blk_num;
1313 		    if (move < 0) move -= (OS_DATA_SIZE / STp->block_size) - 1;
1314 		    move               /= (OS_DATA_SIZE / STp->block_size);
1315 		 }
1316 		 if (!move) move = logical_blk_num > STp->logical_blk_num ? 1 : -1;
1317 #if DEBUG
1318 		 printk(OSST_DEB_MSG
1319 			"%s:D: Seek retry %d at ppos %d fsq %d (est %d) lbn %d (need %d) move %d\n",
1320 				name, retries, ppos_estimate, STp->frame_seq_number, frame_seq_estimate,
1321 				STp->logical_blk_num, logical_blk_num, move);
1322 #endif
1323 		 frame_seq_estimate += move;
1324 		 ppos_estimate      += move;
1325 		 continue;
1326 	      } else {
1327 		 STp->buffer->read_pointer  = (logical_blk_num - STp->logical_blk_num) * STp->block_size;
1328 		 STp->buffer->buffer_bytes -= STp->buffer->read_pointer;
1329 		 STp->logical_blk_num       =  logical_blk_num;
1330 #if DEBUG
1331 		 printk(OSST_DEB_MSG
1332 			"%s:D: Seek success at ppos %d fsq %d in_buf %d, bytes %d, ptr %d*%d\n",
1333 				name, ppos_estimate, STp->frame_seq_number, STp->frame_in_buffer,
1334 				STp->buffer->buffer_bytes, STp->buffer->read_pointer / STp->block_size,
1335 				STp->block_size);
1336 #endif
1337 		 STps->drv_file = ntohl(STp->buffer->aux->filemark_cnt);
1338 		 if (STps->eof == ST_FM_HIT) {
1339 		     STps->drv_file++;
1340 		     STps->drv_block = 0;
1341 		 } else {
1342 		     STps->drv_block = ntohl(STp->buffer->aux->last_mark_lbn)?
1343 					  STp->logical_blk_num -
1344 					     (STps->drv_file ? ntohl(STp->buffer->aux->last_mark_lbn) + 1 : 0):
1345 					-1;
1346 		 }
1347 		 STps->eof = (STp->first_frame_position >= STp->eod_frame_ppos)?ST_EOD:ST_NOEOF;
1348 		 return 0;
1349 	      }
1350 	   }
1351 	   if (osst_get_logical_frame(STp, aSRpnt, -1, 1) < 0)
1352 	      goto error;
1353 	   /* we are not yet at the estimated frame, adjust our estimate of its physical position */
1354 #if DEBUG
1355 	   printk(OSST_DEB_MSG "%s:D: Seek retry %d at ppos %d fsq %d (est %d) lbn %d (need %d)\n",
1356 			   name, retries, ppos_estimate, STp->frame_seq_number, frame_seq_estimate,
1357 			   STp->logical_blk_num, logical_blk_num);
1358 #endif
1359 	   if (frame_seq_estimate != STp->frame_seq_number)
1360 	      ppos_estimate += frame_seq_estimate - STp->frame_seq_number;
1361 	   else
1362 	      break;
1363 	}
1364 error:
1365 	printk(KERN_ERR "%s:E: Couldn't seek to logical block %d (at %d), %d retries\n",
1366 			    name, logical_blk_num, STp->logical_blk_num, retries);
1367 	return (-EIO);
1368 }
1369 
1370 /* The values below are based on the OnStream frame payload size of 32K == 2**15,
1371  * that is, OSST_FRAME_SHIFT + OSST_SECTOR_SHIFT must be 15. With a minimum block
1372  * size of 512 bytes, we need to be able to resolve 32K/512 == 64 == 2**6 positions
1373  * inside each frame. Finally, OSST_SECTOR_MASK == 2**OSST_FRAME_SHIFT - 1.
1374  */
1375 #define OSST_FRAME_SHIFT  6
1376 #define OSST_SECTOR_SHIFT 9
1377 #define OSST_SECTOR_MASK  0x03F
1378 
osst_get_sector(struct osst_tape * STp,struct osst_request ** aSRpnt)1379 static int osst_get_sector(struct osst_tape * STp, struct osst_request ** aSRpnt)
1380 {
1381 	int	sector;
1382 #if DEBUG
1383 	char  * name = tape_name(STp);
1384 
1385 	printk(OSST_DEB_MSG
1386 		"%s:D: Positioned at ppos %d, frame %d, lbn %d, file %d, blk %d, %cptr %d, eof %d\n",
1387 		name, STp->first_frame_position, STp->frame_seq_number, STp->logical_blk_num,
1388 		STp->ps[STp->partition].drv_file, STp->ps[STp->partition].drv_block,
1389 		STp->ps[STp->partition].rw == ST_WRITING?'w':'r',
1390 		STp->ps[STp->partition].rw == ST_WRITING?STp->buffer->buffer_bytes:
1391 		STp->buffer->read_pointer, STp->ps[STp->partition].eof);
1392 #endif
1393 	/* do we know where we are inside a file? */
1394 	if (STp->ps[STp->partition].drv_block >= 0) {
1395 		sector = (STp->frame_in_buffer ? STp->first_frame_position-1 :
1396 				STp->first_frame_position) << OSST_FRAME_SHIFT;
1397 		if (STp->ps[STp->partition].rw == ST_WRITING)
1398 		       	sector |= (STp->buffer->buffer_bytes >> OSST_SECTOR_SHIFT) & OSST_SECTOR_MASK;
1399 		else
1400 	       		sector |= (STp->buffer->read_pointer >> OSST_SECTOR_SHIFT) & OSST_SECTOR_MASK;
1401 	} else {
1402 		sector = osst_get_frame_position(STp, aSRpnt);
1403 		if (sector > 0)
1404 			sector <<= OSST_FRAME_SHIFT;
1405 	}
1406 	return sector;
1407 }
1408 
osst_seek_sector(struct osst_tape * STp,struct osst_request ** aSRpnt,int sector)1409 static int osst_seek_sector(struct osst_tape * STp, struct osst_request ** aSRpnt, int sector)
1410 {
1411         struct st_partstat * STps   = &(STp->ps[STp->partition]);
1412 	int		     frame  = sector >> OSST_FRAME_SHIFT,
1413 			     offset = (sector & OSST_SECTOR_MASK) << OSST_SECTOR_SHIFT,
1414 			     r;
1415 #if DEBUG
1416 	char          * name = tape_name(STp);
1417 
1418 	printk(OSST_DEB_MSG "%s:D: Seeking sector %d in frame %d at offset %d\n",
1419 				name, sector, frame, offset);
1420 #endif
1421 	if (frame < 0 || frame >= STp->capacity) return (-ENXIO);
1422 
1423 	if (frame <= STp->first_data_ppos) {
1424 		STp->frame_seq_number = STp->logical_blk_num = STps->drv_file = STps->drv_block = 0;
1425 		return (osst_set_frame_position(STp, aSRpnt, frame, 0));
1426 	}
1427 	r = osst_set_frame_position(STp, aSRpnt, offset?frame:frame-1, 0);
1428 	if (r < 0) return r;
1429 
1430 	r = osst_get_logical_frame(STp, aSRpnt, -1, 1);
1431 	if (r < 0) return r;
1432 
1433 	if (osst_get_frame_position(STp, aSRpnt) != (offset?frame+1:frame)) return (-EIO);
1434 
1435 	if (offset) {
1436 		STp->logical_blk_num      += offset / STp->block_size;
1437 		STp->buffer->read_pointer  = offset;
1438 		STp->buffer->buffer_bytes -= offset;
1439 	} else {
1440 		STp->frame_seq_number++;
1441 		STp->frame_in_buffer       = 0;
1442 		STp->logical_blk_num      += ntohs(STp->buffer->aux->dat.dat_list[0].blk_cnt);
1443 		STp->buffer->buffer_bytes  = STp->buffer->read_pointer = 0;
1444 	}
1445 	STps->drv_file = ntohl(STp->buffer->aux->filemark_cnt);
1446 	if (STps->eof == ST_FM_HIT) {
1447 		STps->drv_file++;
1448 		STps->drv_block = 0;
1449 	} else {
1450 		STps->drv_block = ntohl(STp->buffer->aux->last_mark_lbn)?
1451 				    STp->logical_blk_num -
1452 					(STps->drv_file ? ntohl(STp->buffer->aux->last_mark_lbn) + 1 : 0):
1453 				  -1;
1454 	}
1455 	STps->eof       = (STp->first_frame_position >= STp->eod_frame_ppos)?ST_EOD:ST_NOEOF;
1456 #if DEBUG
1457 	printk(OSST_DEB_MSG
1458 		"%s:D: Now positioned at ppos %d, frame %d, lbn %d, file %d, blk %d, rptr %d, eof %d\n",
1459 		name, STp->first_frame_position, STp->frame_seq_number, STp->logical_blk_num,
1460 		STps->drv_file, STps->drv_block, STp->buffer->read_pointer, STps->eof);
1461 #endif
1462 	return 0;
1463 }
1464 
1465 /*
1466  * Read back the drive's internal buffer contents, as a part
1467  * of the write error recovery mechanism for old OnStream
1468  * firmware revisions.
1469  * Precondition for this function to work: all frames in the
1470  * drive's buffer must be of one type (DATA, MARK or EOD)!
1471  */
osst_read_back_buffer_and_rewrite(struct osst_tape * STp,struct osst_request ** aSRpnt,unsigned int frame,unsigned int skip,int pending)1472 static int osst_read_back_buffer_and_rewrite(struct osst_tape * STp, struct osst_request ** aSRpnt,
1473 						unsigned int frame, unsigned int skip, int pending)
1474 {
1475 	struct osst_request   * SRpnt = * aSRpnt;
1476 	unsigned char	      * buffer, * p;
1477 	unsigned char		cmd[MAX_COMMAND_SIZE];
1478 	int			flag, new_frame, i;
1479 	int			nframes          = STp->cur_frames;
1480 	int			blks_per_frame   = ntohs(STp->buffer->aux->dat.dat_list[0].blk_cnt);
1481 	int			frame_seq_number = ntohl(STp->buffer->aux->frame_seq_num)
1482 						- (nframes + pending - 1);
1483 	int			logical_blk_num  = ntohl(STp->buffer->aux->logical_blk_num)
1484 						- (nframes + pending - 1) * blks_per_frame;
1485 	char		      * name             = tape_name(STp);
1486 	unsigned long		startwait        = jiffies;
1487 #if DEBUG
1488 	int			dbg              = debugging;
1489 #endif
1490 
1491 	if ((buffer = vmalloc(array_size((nframes + 1), OS_DATA_SIZE))) == NULL)
1492 		return (-EIO);
1493 
1494 	printk(KERN_INFO "%s:I: Reading back %d frames from drive buffer%s\n",
1495 			 name, nframes, pending?" and one that was pending":"");
1496 
1497 	osst_copy_from_buffer(STp->buffer, (p = &buffer[nframes * OS_DATA_SIZE]));
1498 #if DEBUG
1499 	if (pending && debugging)
1500 		printk(OSST_DEB_MSG "%s:D: Pending frame %d (lblk %d), data %02x %02x %02x %02x\n",
1501 				name, frame_seq_number + nframes,
1502 			       	logical_blk_num + nframes * blks_per_frame,
1503 			       	p[0], p[1], p[2], p[3]);
1504 #endif
1505 	for (i = 0, p = buffer; i < nframes; i++, p += OS_DATA_SIZE) {
1506 
1507 		memset(cmd, 0, MAX_COMMAND_SIZE);
1508 		cmd[0] = 0x3C;		/* Buffer Read           */
1509 		cmd[1] = 6;		/* Retrieve Faulty Block */
1510 		cmd[7] = 32768 >> 8;
1511 		cmd[8] = 32768 & 0xff;
1512 
1513 		SRpnt = osst_do_scsi(SRpnt, STp, cmd, OS_FRAME_SIZE, DMA_FROM_DEVICE,
1514 					    STp->timeout, MAX_RETRIES, 1);
1515 
1516 		if ((STp->buffer)->syscall_result || !SRpnt) {
1517 			printk(KERN_ERR "%s:E: Failed to read frame back from OnStream buffer\n", name);
1518 			vfree(buffer);
1519 			*aSRpnt = SRpnt;
1520 			return (-EIO);
1521 		}
1522 		osst_copy_from_buffer(STp->buffer, p);
1523 #if DEBUG
1524 		if (debugging)
1525 			printk(OSST_DEB_MSG "%s:D: Read back logical frame %d, data %02x %02x %02x %02x\n",
1526 					  name, frame_seq_number + i, p[0], p[1], p[2], p[3]);
1527 #endif
1528 	}
1529 	*aSRpnt = SRpnt;
1530 	osst_get_frame_position(STp, aSRpnt);
1531 
1532 #if DEBUG
1533 	printk(OSST_DEB_MSG "%s:D: Frames left in buffer: %d\n", name, STp->cur_frames);
1534 #endif
1535 	/* Write synchronously so we can be sure we're OK again and don't have to recover recursively */
1536 	/* In the header we don't actually re-write the frames that fail, just the ones after them */
1537 
1538 	for (flag=1, new_frame=frame, p=buffer, i=0; i < nframes + pending; ) {
1539 
1540 		if (flag) {
1541 			if (STp->write_type == OS_WRITE_HEADER) {
1542 				i += skip;
1543 				p += skip * OS_DATA_SIZE;
1544 			}
1545 			else if (new_frame < 2990 && new_frame+skip+nframes+pending >= 2990)
1546 				new_frame = 3000-i;
1547 			else
1548 				new_frame += skip;
1549 #if DEBUG
1550 			printk(OSST_DEB_MSG "%s:D: Position to frame %d, write fseq %d\n",
1551 						name, new_frame+i, frame_seq_number+i);
1552 #endif
1553 			osst_set_frame_position(STp, aSRpnt, new_frame + i, 0);
1554 			osst_wait_ready(STp, aSRpnt, 60, OSST_WAIT_POSITION_COMPLETE);
1555 			osst_get_frame_position(STp, aSRpnt);
1556 			SRpnt = * aSRpnt;
1557 
1558 			if (new_frame > frame + 1000) {
1559 				printk(KERN_ERR "%s:E: Failed to find writable tape media\n", name);
1560 				vfree(buffer);
1561 				return (-EIO);
1562 			}
1563 			if ( i >= nframes + pending ) break;
1564 			flag = 0;
1565 		}
1566 		osst_copy_to_buffer(STp->buffer, p);
1567 		/*
1568 		 * IMPORTANT: for error recovery to work, _never_ queue frames with mixed frame type!
1569 		 */
1570 		osst_init_aux(STp, STp->buffer->aux->frame_type, frame_seq_number+i,
1571 			       	logical_blk_num + i*blks_per_frame,
1572 			       	ntohl(STp->buffer->aux->dat.dat_list[0].blk_sz), blks_per_frame);
1573 		memset(cmd, 0, MAX_COMMAND_SIZE);
1574 		cmd[0] = WRITE_6;
1575 		cmd[1] = 1;
1576 		cmd[4] = 1;
1577 
1578 #if DEBUG
1579 		if (debugging)
1580 			printk(OSST_DEB_MSG
1581 				"%s:D: About to write frame %d, seq %d, lbn %d, data %02x %02x %02x %02x\n",
1582 				name, new_frame+i, frame_seq_number+i, logical_blk_num + i*blks_per_frame,
1583 				p[0], p[1], p[2], p[3]);
1584 #endif
1585 		SRpnt = osst_do_scsi(SRpnt, STp, cmd, OS_FRAME_SIZE, DMA_TO_DEVICE,
1586 					    STp->timeout, MAX_RETRIES, 1);
1587 
1588 		if (STp->buffer->syscall_result)
1589 			flag = 1;
1590 		else {
1591 			p += OS_DATA_SIZE; i++;
1592 
1593 			/* if we just sent the last frame, wait till all successfully written */
1594 			if ( i == nframes + pending ) {
1595 #if DEBUG
1596 				printk(OSST_DEB_MSG "%s:D: Check re-write successful\n", name);
1597 #endif
1598 				memset(cmd, 0, MAX_COMMAND_SIZE);
1599 				cmd[0] = WRITE_FILEMARKS;
1600 				cmd[1] = 1;
1601 				SRpnt = osst_do_scsi(SRpnt, STp, cmd, 0, DMA_NONE,
1602 							    STp->timeout, MAX_RETRIES, 1);
1603 #if DEBUG
1604 				if (debugging) {
1605 					printk(OSST_DEB_MSG "%s:D: Sleeping in re-write wait ready\n", name);
1606 					printk(OSST_DEB_MSG "%s:D: Turning off debugging for a while\n", name);
1607 					debugging = 0;
1608 				}
1609 #endif
1610 				flag = STp->buffer->syscall_result;
1611 				while ( !flag && time_before(jiffies, startwait + 60*HZ) ) {
1612 
1613 					memset(cmd, 0, MAX_COMMAND_SIZE);
1614 					cmd[0] = TEST_UNIT_READY;
1615 
1616 					SRpnt = osst_do_scsi(SRpnt, STp, cmd, 0, DMA_NONE, STp->timeout,
1617 												MAX_RETRIES, 1);
1618 
1619 					if (SRpnt->sense[2] == 2 && SRpnt->sense[12] == 4 &&
1620 					    (SRpnt->sense[13] == 1 || SRpnt->sense[13] == 8)) {
1621 						/* in the process of becoming ready */
1622 						msleep(100);
1623 						continue;
1624 					}
1625 					if (STp->buffer->syscall_result)
1626 						flag = 1;
1627 					break;
1628 				}
1629 #if DEBUG
1630 				debugging = dbg;
1631 				printk(OSST_DEB_MSG "%s:D: Wait re-write finished\n", name);
1632 #endif
1633 			}
1634 		}
1635 		*aSRpnt = SRpnt;
1636 		if (flag) {
1637 			if ((SRpnt->sense[ 2] & 0x0f) == 13 &&
1638 			     SRpnt->sense[12]         ==  0 &&
1639 			     SRpnt->sense[13]         ==  2) {
1640 				printk(KERN_ERR "%s:E: Volume overflow in write error recovery\n", name);
1641 				vfree(buffer);
1642 				return (-EIO);			/* hit end of tape = fail */
1643 			}
1644 			i = ((SRpnt->sense[3] << 24) |
1645 			     (SRpnt->sense[4] << 16) |
1646 			     (SRpnt->sense[5] <<  8) |
1647 			      SRpnt->sense[6]        ) - new_frame;
1648 			p = &buffer[i * OS_DATA_SIZE];
1649 #if DEBUG
1650 			printk(OSST_DEB_MSG "%s:D: Additional write error at %d\n", name, new_frame+i);
1651 #endif
1652 			osst_get_frame_position(STp, aSRpnt);
1653 #if DEBUG
1654 			printk(OSST_DEB_MSG "%s:D: reported frame positions: host = %d, tape = %d, buffer = %d\n",
1655 					  name, STp->first_frame_position, STp->last_frame_position, STp->cur_frames);
1656 #endif
1657 		}
1658 	}
1659 	if (flag) {
1660 		/* error recovery did not successfully complete */
1661 		printk(KERN_ERR "%s:D: Write error recovery failed in %s\n", name,
1662 				STp->write_type == OS_WRITE_HEADER?"header":"body");
1663 	}
1664 	if (!pending)
1665 		osst_copy_to_buffer(STp->buffer, p);	/* so buffer content == at entry in all cases */
1666 	vfree(buffer);
1667 	return 0;
1668 }
1669 
osst_reposition_and_retry(struct osst_tape * STp,struct osst_request ** aSRpnt,unsigned int frame,unsigned int skip,int pending)1670 static int osst_reposition_and_retry(struct osst_tape * STp, struct osst_request ** aSRpnt,
1671 					unsigned int frame, unsigned int skip, int pending)
1672 {
1673 	unsigned char		cmd[MAX_COMMAND_SIZE];
1674 	struct osst_request   * SRpnt;
1675 	char		      * name      = tape_name(STp);
1676 	int			expected  = 0;
1677 	int			attempts  = 1000 / skip;
1678 	int			flag      = 1;
1679 	unsigned long		startwait = jiffies;
1680 #if DEBUG
1681 	int			dbg       = debugging;
1682 #endif
1683 
1684 	while (attempts && time_before(jiffies, startwait + 60*HZ)) {
1685 		if (flag) {
1686 #if DEBUG
1687 			debugging = dbg;
1688 #endif
1689 			if (frame < 2990 && frame+skip+STp->cur_frames+pending >= 2990)
1690 				frame = 3000-skip;
1691 			expected = frame+skip+STp->cur_frames+pending;
1692 #if DEBUG
1693 			printk(OSST_DEB_MSG "%s:D: Position to fppos %d, re-write from fseq %d\n",
1694 					  name, frame+skip, STp->frame_seq_number-STp->cur_frames-pending);
1695 #endif
1696 			osst_set_frame_position(STp, aSRpnt, frame + skip, 1);
1697 			flag = 0;
1698 			attempts--;
1699 			schedule_timeout_interruptible(msecs_to_jiffies(100));
1700 		}
1701 		if (osst_get_frame_position(STp, aSRpnt) < 0) {		/* additional write error */
1702 #if DEBUG
1703 			printk(OSST_DEB_MSG "%s:D: Addl error, host %d, tape %d, buffer %d\n",
1704 					  name, STp->first_frame_position,
1705 					  STp->last_frame_position, STp->cur_frames);
1706 #endif
1707 			frame = STp->last_frame_position;
1708 			flag = 1;
1709 			continue;
1710 		}
1711 		if (pending && STp->cur_frames < 50) {
1712 
1713 			memset(cmd, 0, MAX_COMMAND_SIZE);
1714 			cmd[0] = WRITE_6;
1715 			cmd[1] = 1;
1716 			cmd[4] = 1;
1717 #if DEBUG
1718 			printk(OSST_DEB_MSG "%s:D: About to write pending fseq %d at fppos %d\n",
1719 					  name, STp->frame_seq_number-1, STp->first_frame_position);
1720 #endif
1721 			SRpnt = osst_do_scsi(*aSRpnt, STp, cmd, OS_FRAME_SIZE, DMA_TO_DEVICE,
1722 						      STp->timeout, MAX_RETRIES, 1);
1723 			*aSRpnt = SRpnt;
1724 
1725 			if (STp->buffer->syscall_result) {		/* additional write error */
1726 				if ((SRpnt->sense[ 2] & 0x0f) == 13 &&
1727 				     SRpnt->sense[12]         ==  0 &&
1728 				     SRpnt->sense[13]         ==  2) {
1729 					printk(KERN_ERR
1730 					       "%s:E: Volume overflow in write error recovery\n",
1731 					       name);
1732 					break;				/* hit end of tape = fail */
1733 				}
1734 				flag = 1;
1735 			}
1736 			else
1737 				pending = 0;
1738 
1739 			continue;
1740 		}
1741 		if (STp->cur_frames == 0) {
1742 #if DEBUG
1743 			debugging = dbg;
1744 			printk(OSST_DEB_MSG "%s:D: Wait re-write finished\n", name);
1745 #endif
1746 			if (STp->first_frame_position != expected) {
1747 				printk(KERN_ERR "%s:A: Actual position %d - expected %d\n",
1748 						name, STp->first_frame_position, expected);
1749 				return (-EIO);
1750 			}
1751 			return 0;
1752 		}
1753 #if DEBUG
1754 		if (debugging) {
1755 			printk(OSST_DEB_MSG "%s:D: Sleeping in re-write wait ready\n", name);
1756 			printk(OSST_DEB_MSG "%s:D: Turning off debugging for a while\n", name);
1757 			debugging = 0;
1758 		}
1759 #endif
1760 		schedule_timeout_interruptible(msecs_to_jiffies(100));
1761 	}
1762 	printk(KERN_ERR "%s:E: Failed to find valid tape media\n", name);
1763 #if DEBUG
1764 	debugging = dbg;
1765 #endif
1766 	return (-EIO);
1767 }
1768 
1769 /*
1770  * Error recovery algorithm for the OnStream tape.
1771  */
1772 
osst_write_error_recovery(struct osst_tape * STp,struct osst_request ** aSRpnt,int pending)1773 static int osst_write_error_recovery(struct osst_tape * STp, struct osst_request ** aSRpnt, int pending)
1774 {
1775 	struct osst_request * SRpnt  = * aSRpnt;
1776 	struct st_partstat  * STps   = & STp->ps[STp->partition];
1777 	char		    * name   = tape_name(STp);
1778 	int		      retval = 0;
1779 	int		      rw_state;
1780 	unsigned int	      frame, skip;
1781 
1782 	rw_state = STps->rw;
1783 
1784 	if ((SRpnt->sense[ 2] & 0x0f) != 3
1785 	  || SRpnt->sense[12]         != 12
1786 	  || SRpnt->sense[13]         != 0) {
1787 #if DEBUG
1788 		printk(OSST_DEB_MSG "%s:D: Write error recovery cannot handle %02x:%02x:%02x\n", name,
1789 			SRpnt->sense[2], SRpnt->sense[12], SRpnt->sense[13]);
1790 #endif
1791 		return (-EIO);
1792 	}
1793 	frame =	(SRpnt->sense[3] << 24) |
1794 		(SRpnt->sense[4] << 16) |
1795 		(SRpnt->sense[5] <<  8) |
1796 		 SRpnt->sense[6];
1797 	skip  =  SRpnt->sense[9];
1798 
1799 #if DEBUG
1800 	printk(OSST_DEB_MSG "%s:D: Detected physical bad frame at %u, advised to skip %d\n", name, frame, skip);
1801 #endif
1802 	osst_get_frame_position(STp, aSRpnt);
1803 #if DEBUG
1804 	printk(OSST_DEB_MSG "%s:D: reported frame positions: host = %d, tape = %d\n",
1805 			name, STp->first_frame_position, STp->last_frame_position);
1806 #endif
1807 	switch (STp->write_type) {
1808 	   case OS_WRITE_DATA:
1809 	   case OS_WRITE_EOD:
1810 	   case OS_WRITE_NEW_MARK:
1811 		printk(KERN_WARNING
1812 			"%s:I: Relocating %d buffered logical frames from position %u to %u\n",
1813 			name, STp->cur_frames, frame, (frame + skip > 3000 && frame < 3000)?3000:frame + skip);
1814 		if (STp->os_fw_rev >= 10600)
1815 			retval = osst_reposition_and_retry(STp, aSRpnt, frame, skip, pending);
1816 		else
1817 			retval = osst_read_back_buffer_and_rewrite(STp, aSRpnt, frame, skip, pending);
1818 		printk(KERN_WARNING "%s:%s: %sWrite error%srecovered\n", name,
1819 			       	retval?"E"    :"I",
1820 			       	retval?""     :"Don't worry, ",
1821 			       	retval?" not ":" ");
1822 		break;
1823 	   case OS_WRITE_LAST_MARK:
1824 		printk(KERN_ERR "%s:E: Bad frame in update last marker, fatal\n", name);
1825 		osst_set_frame_position(STp, aSRpnt, frame + STp->cur_frames + pending, 0);
1826 		retval = -EIO;
1827 		break;
1828 	   case OS_WRITE_HEADER:
1829 		printk(KERN_WARNING "%s:I: Bad frame in header partition, skipped\n", name);
1830 		retval = osst_read_back_buffer_and_rewrite(STp, aSRpnt, frame, 1, pending);
1831 		break;
1832 	   default:
1833 		printk(KERN_INFO "%s:I: Bad frame in filler, ignored\n", name);
1834 		osst_set_frame_position(STp, aSRpnt, frame + STp->cur_frames + pending, 0);
1835 	}
1836 	osst_get_frame_position(STp, aSRpnt);
1837 #if DEBUG
1838 	printk(OSST_DEB_MSG "%s:D: Positioning complete, cur_frames %d, pos %d, tape pos %d\n",
1839 			name, STp->cur_frames, STp->first_frame_position, STp->last_frame_position);
1840 	printk(OSST_DEB_MSG "%s:D: next logical frame to write: %d\n", name, STp->logical_blk_num);
1841 #endif
1842 	if (retval == 0) {
1843 		STp->recover_count++;
1844 		STp->recover_erreg++;
1845 	} else
1846 		STp->abort_count++;
1847 
1848 	STps->rw = rw_state;
1849 	return retval;
1850 }
1851 
osst_space_over_filemarks_backward(struct osst_tape * STp,struct osst_request ** aSRpnt,int mt_op,int mt_count)1852 static int osst_space_over_filemarks_backward(struct osst_tape * STp, struct osst_request ** aSRpnt,
1853 								 int mt_op, int mt_count)
1854 {
1855 	char  * name = tape_name(STp);
1856 	int     cnt;
1857 	int     last_mark_ppos = -1;
1858 
1859 #if DEBUG
1860 	printk(OSST_DEB_MSG "%s:D: Reached space_over_filemarks_backwards %d %d\n", name, mt_op, mt_count);
1861 #endif
1862 	if (osst_get_logical_frame(STp, aSRpnt, -1, 0) < 0) {
1863 #if DEBUG
1864 		printk(OSST_DEB_MSG "%s:D: Couldn't get logical blk num in space_filemarks_bwd\n", name);
1865 #endif
1866 		return -EIO;
1867 	}
1868 	if (STp->linux_media_version >= 4) {
1869 		/*
1870 		 * direct lookup in header filemark list
1871 		 */
1872 		cnt = ntohl(STp->buffer->aux->filemark_cnt);
1873 		if (STp->header_ok                         &&
1874 		    STp->header_cache != NULL              &&
1875 		    (cnt - mt_count)  >= 0                 &&
1876 		    (cnt - mt_count)   < OS_FM_TAB_MAX     &&
1877 		    (cnt - mt_count)   < STp->filemark_cnt &&
1878 		    STp->header_cache->dat_fm_tab.fm_tab_ent[cnt-1] == STp->buffer->aux->last_mark_ppos)
1879 
1880 			last_mark_ppos = ntohl(STp->header_cache->dat_fm_tab.fm_tab_ent[cnt - mt_count]);
1881 #if DEBUG
1882 		if (STp->header_cache == NULL || (cnt - mt_count) < 0 || (cnt - mt_count) >= OS_FM_TAB_MAX)
1883 			printk(OSST_DEB_MSG "%s:D: Filemark lookup fail due to %s\n", name,
1884 			       STp->header_cache == NULL?"lack of header cache":"count out of range");
1885 		else
1886 			printk(OSST_DEB_MSG "%s:D: Filemark lookup: prev mark %d (%s), skip %d to %d\n",
1887 				name, cnt,
1888 				((cnt == -1 && ntohl(STp->buffer->aux->last_mark_ppos) == -1) ||
1889 				 (STp->header_cache->dat_fm_tab.fm_tab_ent[cnt-1] ==
1890 					 STp->buffer->aux->last_mark_ppos))?"match":"error",
1891 			       mt_count, last_mark_ppos);
1892 #endif
1893 		if (last_mark_ppos > 10 && last_mark_ppos < STp->eod_frame_ppos) {
1894 			osst_position_tape_and_confirm(STp, aSRpnt, last_mark_ppos);
1895 			if (osst_get_logical_frame(STp, aSRpnt, -1, 0) < 0) {
1896 #if DEBUG
1897 				printk(OSST_DEB_MSG
1898 					"%s:D: Couldn't get logical blk num in space_filemarks\n", name);
1899 #endif
1900 				return (-EIO);
1901 			}
1902 			if (STp->buffer->aux->frame_type != OS_FRAME_TYPE_MARKER) {
1903 				printk(KERN_WARNING "%s:W: Expected to find marker at ppos %d, not found\n",
1904 						 name, last_mark_ppos);
1905 				return (-EIO);
1906 			}
1907 			goto found;
1908 		}
1909 #if DEBUG
1910 		printk(OSST_DEB_MSG "%s:D: Reverting to scan filemark backwards\n", name);
1911 #endif
1912 	}
1913 	cnt = 0;
1914 	while (cnt != mt_count) {
1915 		last_mark_ppos = ntohl(STp->buffer->aux->last_mark_ppos);
1916 		if (last_mark_ppos == -1)
1917 			return (-EIO);
1918 #if DEBUG
1919 		printk(OSST_DEB_MSG "%s:D: Positioning to last mark at %d\n", name, last_mark_ppos);
1920 #endif
1921 		osst_position_tape_and_confirm(STp, aSRpnt, last_mark_ppos);
1922 		cnt++;
1923 		if (osst_get_logical_frame(STp, aSRpnt, -1, 0) < 0) {
1924 #if DEBUG
1925 			printk(OSST_DEB_MSG "%s:D: Couldn't get logical blk num in space_filemarks\n", name);
1926 #endif
1927 			return (-EIO);
1928 		}
1929 		if (STp->buffer->aux->frame_type != OS_FRAME_TYPE_MARKER) {
1930 			printk(KERN_WARNING "%s:W: Expected to find marker at ppos %d, not found\n",
1931 					 name, last_mark_ppos);
1932 			return (-EIO);
1933 		}
1934 	}
1935 found:
1936 	if (mt_op == MTBSFM) {
1937 		STp->frame_seq_number++;
1938 		STp->frame_in_buffer      = 0;
1939 		STp->buffer->buffer_bytes = 0;
1940 		STp->buffer->read_pointer = 0;
1941 		STp->logical_blk_num     += ntohs(STp->buffer->aux->dat.dat_list[0].blk_cnt);
1942 	}
1943 	return 0;
1944 }
1945 
1946 /*
1947  * ADRL 1.1 compatible "slow" space filemarks fwd version
1948  *
1949  * Just scans for the filemark sequentially.
1950  */
osst_space_over_filemarks_forward_slow(struct osst_tape * STp,struct osst_request ** aSRpnt,int mt_op,int mt_count)1951 static int osst_space_over_filemarks_forward_slow(struct osst_tape * STp, struct osst_request ** aSRpnt,
1952 								     int mt_op, int mt_count)
1953 {
1954 	int	cnt = 0;
1955 #if DEBUG
1956 	char  * name = tape_name(STp);
1957 
1958 	printk(OSST_DEB_MSG "%s:D: Reached space_over_filemarks_forward_slow %d %d\n", name, mt_op, mt_count);
1959 #endif
1960 	if (osst_get_logical_frame(STp, aSRpnt, -1, 0) < 0) {
1961 #if DEBUG
1962 		printk(OSST_DEB_MSG "%s:D: Couldn't get logical blk num in space_filemarks_fwd\n", name);
1963 #endif
1964 		return (-EIO);
1965 	}
1966 	while (1) {
1967 		if (osst_get_logical_frame(STp, aSRpnt, -1, 0) < 0) {
1968 #if DEBUG
1969 			printk(OSST_DEB_MSG "%s:D: Couldn't get logical blk num in space_filemarks\n", name);
1970 #endif
1971 			return (-EIO);
1972 		}
1973 		if (STp->buffer->aux->frame_type == OS_FRAME_TYPE_MARKER)
1974 			cnt++;
1975 		if (STp->buffer->aux->frame_type == OS_FRAME_TYPE_EOD) {
1976 #if DEBUG
1977 			printk(OSST_DEB_MSG "%s:D: space_fwd: EOD reached\n", name);
1978 #endif
1979 			if (STp->first_frame_position > STp->eod_frame_ppos+1) {
1980 #if DEBUG
1981 				printk(OSST_DEB_MSG "%s:D: EOD position corrected (%d=>%d)\n",
1982 					       	name, STp->eod_frame_ppos, STp->first_frame_position-1);
1983 #endif
1984 				STp->eod_frame_ppos = STp->first_frame_position-1;
1985 			}
1986 			return (-EIO);
1987 		}
1988 		if (cnt == mt_count)
1989 			break;
1990 		STp->frame_in_buffer = 0;
1991 	}
1992 	if (mt_op == MTFSF) {
1993 		STp->frame_seq_number++;
1994 		STp->frame_in_buffer      = 0;
1995 		STp->buffer->buffer_bytes = 0;
1996 		STp->buffer->read_pointer = 0;
1997 		STp->logical_blk_num     += ntohs(STp->buffer->aux->dat.dat_list[0].blk_cnt);
1998 	}
1999 	return 0;
2000 }
2001 
2002 /*
2003  * Fast linux specific version of OnStream FSF
2004  */
osst_space_over_filemarks_forward_fast(struct osst_tape * STp,struct osst_request ** aSRpnt,int mt_op,int mt_count)2005 static int osst_space_over_filemarks_forward_fast(struct osst_tape * STp, struct osst_request ** aSRpnt,
2006 								     int mt_op, int mt_count)
2007 {
2008 	char  * name = tape_name(STp);
2009 	int	cnt  = 0,
2010 		next_mark_ppos = -1;
2011 
2012 #if DEBUG
2013 	printk(OSST_DEB_MSG "%s:D: Reached space_over_filemarks_forward_fast %d %d\n", name, mt_op, mt_count);
2014 #endif
2015 	if (osst_get_logical_frame(STp, aSRpnt, -1, 0) < 0) {
2016 #if DEBUG
2017 		printk(OSST_DEB_MSG "%s:D: Couldn't get logical blk num in space_filemarks_fwd\n", name);
2018 #endif
2019 		return (-EIO);
2020 	}
2021 
2022 	if (STp->linux_media_version >= 4) {
2023 		/*
2024 		 * direct lookup in header filemark list
2025 		 */
2026 		cnt = ntohl(STp->buffer->aux->filemark_cnt) - 1;
2027 		if (STp->header_ok                         &&
2028 		    STp->header_cache != NULL              &&
2029 		    (cnt + mt_count)   < OS_FM_TAB_MAX     &&
2030 		    (cnt + mt_count)   < STp->filemark_cnt &&
2031 		    ((cnt == -1 && ntohl(STp->buffer->aux->last_mark_ppos) == -1) ||
2032 		     (STp->header_cache->dat_fm_tab.fm_tab_ent[cnt] == STp->buffer->aux->last_mark_ppos)))
2033 
2034 			next_mark_ppos = ntohl(STp->header_cache->dat_fm_tab.fm_tab_ent[cnt + mt_count]);
2035 #if DEBUG
2036 		if (STp->header_cache == NULL || (cnt + mt_count) >= OS_FM_TAB_MAX)
2037 			printk(OSST_DEB_MSG "%s:D: Filemark lookup fail due to %s\n", name,
2038 			       STp->header_cache == NULL?"lack of header cache":"count out of range");
2039 		else
2040 			printk(OSST_DEB_MSG "%s:D: Filemark lookup: prev mark %d (%s), skip %d to %d\n",
2041 			       name, cnt,
2042 			       ((cnt == -1 && ntohl(STp->buffer->aux->last_mark_ppos) == -1) ||
2043 				(STp->header_cache->dat_fm_tab.fm_tab_ent[cnt] ==
2044 					 STp->buffer->aux->last_mark_ppos))?"match":"error",
2045 			       mt_count, next_mark_ppos);
2046 #endif
2047 		if (next_mark_ppos <= 10 || next_mark_ppos > STp->eod_frame_ppos) {
2048 #if DEBUG
2049 			printk(OSST_DEB_MSG "%s:D: Reverting to slow filemark space\n", name);
2050 #endif
2051 			return osst_space_over_filemarks_forward_slow(STp, aSRpnt, mt_op, mt_count);
2052 		} else {
2053 			osst_position_tape_and_confirm(STp, aSRpnt, next_mark_ppos);
2054 			if (osst_get_logical_frame(STp, aSRpnt, -1, 0) < 0) {
2055 #if DEBUG
2056 				printk(OSST_DEB_MSG "%s:D: Couldn't get logical blk num in space_filemarks\n",
2057 						 name);
2058 #endif
2059 				return (-EIO);
2060 			}
2061 			if (STp->buffer->aux->frame_type != OS_FRAME_TYPE_MARKER) {
2062 				printk(KERN_WARNING "%s:W: Expected to find marker at ppos %d, not found\n",
2063 						 name, next_mark_ppos);
2064 				return (-EIO);
2065 			}
2066 			if (ntohl(STp->buffer->aux->filemark_cnt) != cnt + mt_count) {
2067 				printk(KERN_WARNING "%s:W: Expected to find marker %d at ppos %d, not %d\n",
2068 						 name, cnt+mt_count, next_mark_ppos,
2069 						 ntohl(STp->buffer->aux->filemark_cnt));
2070        				return (-EIO);
2071 			}
2072 		}
2073 	} else {
2074 		/*
2075 		 * Find nearest (usually previous) marker, then jump from marker to marker
2076 		 */
2077 		while (1) {
2078 			if (STp->buffer->aux->frame_type == OS_FRAME_TYPE_MARKER)
2079 				break;
2080 			if (STp->buffer->aux->frame_type == OS_FRAME_TYPE_EOD) {
2081 #if DEBUG
2082 				printk(OSST_DEB_MSG "%s:D: space_fwd: EOD reached\n", name);
2083 #endif
2084 				return (-EIO);
2085 			}
2086 			if (ntohl(STp->buffer->aux->filemark_cnt) == 0) {
2087 				if (STp->first_mark_ppos == -1) {
2088 #if DEBUG
2089 					printk(OSST_DEB_MSG "%s:D: Reverting to slow filemark space\n", name);
2090 #endif
2091 					return osst_space_over_filemarks_forward_slow(STp, aSRpnt, mt_op, mt_count);
2092 				}
2093 				osst_position_tape_and_confirm(STp, aSRpnt, STp->first_mark_ppos);
2094 				if (osst_get_logical_frame(STp, aSRpnt, -1, 0) < 0) {
2095 #if DEBUG
2096 					printk(OSST_DEB_MSG
2097 					       "%s:D: Couldn't get logical blk num in space_filemarks_fwd_fast\n",
2098 					       name);
2099 #endif
2100 					return (-EIO);
2101 				}
2102 				if (STp->buffer->aux->frame_type != OS_FRAME_TYPE_MARKER) {
2103 					printk(KERN_WARNING "%s:W: Expected to find filemark at %d\n",
2104 							 name, STp->first_mark_ppos);
2105 					return (-EIO);
2106 				}
2107 			} else {
2108 				if (osst_space_over_filemarks_backward(STp, aSRpnt, MTBSF, 1) < 0)
2109 					return (-EIO);
2110 				mt_count++;
2111 			}
2112 		}
2113 		cnt++;
2114 		while (cnt != mt_count) {
2115 			next_mark_ppos = ntohl(STp->buffer->aux->next_mark_ppos);
2116 			if (!next_mark_ppos || next_mark_ppos > STp->eod_frame_ppos) {
2117 #if DEBUG
2118 				printk(OSST_DEB_MSG "%s:D: Reverting to slow filemark space\n", name);
2119 #endif
2120 				return osst_space_over_filemarks_forward_slow(STp, aSRpnt, mt_op, mt_count - cnt);
2121 			}
2122 #if DEBUG
2123 			else printk(OSST_DEB_MSG "%s:D: Positioning to next mark at %d\n", name, next_mark_ppos);
2124 #endif
2125 			osst_position_tape_and_confirm(STp, aSRpnt, next_mark_ppos);
2126 			cnt++;
2127 			if (osst_get_logical_frame(STp, aSRpnt, -1, 0) < 0) {
2128 #if DEBUG
2129 				printk(OSST_DEB_MSG "%s:D: Couldn't get logical blk num in space_filemarks\n",
2130 						 name);
2131 #endif
2132 				return (-EIO);
2133 			}
2134 			if (STp->buffer->aux->frame_type != OS_FRAME_TYPE_MARKER) {
2135 				printk(KERN_WARNING "%s:W: Expected to find marker at ppos %d, not found\n",
2136 						 name, next_mark_ppos);
2137 				return (-EIO);
2138 			}
2139 		}
2140 	}
2141 	if (mt_op == MTFSF) {
2142 		STp->frame_seq_number++;
2143 		STp->frame_in_buffer      = 0;
2144 		STp->buffer->buffer_bytes = 0;
2145 		STp->buffer->read_pointer = 0;
2146 		STp->logical_blk_num     += ntohs(STp->buffer->aux->dat.dat_list[0].blk_cnt);
2147 	}
2148 	return 0;
2149 }
2150 
2151 /*
2152  * In debug mode, we want to see as many errors as possible
2153  * to test the error recovery mechanism.
2154  */
2155 #if DEBUG
osst_set_retries(struct osst_tape * STp,struct osst_request ** aSRpnt,int retries)2156 static void osst_set_retries(struct osst_tape * STp, struct osst_request ** aSRpnt, int retries)
2157 {
2158 	unsigned char		cmd[MAX_COMMAND_SIZE];
2159 	struct osst_request   * SRpnt  = * aSRpnt;
2160 	char		      * name   = tape_name(STp);
2161 
2162 	memset(cmd, 0, MAX_COMMAND_SIZE);
2163 	cmd[0] = MODE_SELECT;
2164 	cmd[1] = 0x10;
2165 	cmd[4] = NUMBER_RETRIES_PAGE_LENGTH + MODE_HEADER_LENGTH;
2166 
2167 	(STp->buffer)->b_data[0] = cmd[4] - 1;
2168 	(STp->buffer)->b_data[1] = 0;			/* Medium Type - ignoring */
2169 	(STp->buffer)->b_data[2] = 0;			/* Reserved */
2170 	(STp->buffer)->b_data[3] = 0;			/* Block Descriptor Length */
2171 	(STp->buffer)->b_data[MODE_HEADER_LENGTH + 0] = NUMBER_RETRIES_PAGE | (1 << 7);
2172 	(STp->buffer)->b_data[MODE_HEADER_LENGTH + 1] = 2;
2173 	(STp->buffer)->b_data[MODE_HEADER_LENGTH + 2] = 4;
2174 	(STp->buffer)->b_data[MODE_HEADER_LENGTH + 3] = retries;
2175 
2176 	if (debugging)
2177 	    printk(OSST_DEB_MSG "%s:D: Setting number of retries on OnStream tape to %d\n", name, retries);
2178 
2179 	SRpnt = osst_do_scsi(SRpnt, STp, cmd, cmd[4], DMA_TO_DEVICE, STp->timeout, 0, 1);
2180 	*aSRpnt = SRpnt;
2181 
2182 	if ((STp->buffer)->syscall_result)
2183 	    printk (KERN_ERR "%s:D: Couldn't set retries to %d\n", name, retries);
2184 }
2185 #endif
2186 
2187 
osst_write_filemark(struct osst_tape * STp,struct osst_request ** aSRpnt)2188 static int osst_write_filemark(struct osst_tape * STp, struct osst_request ** aSRpnt)
2189 {
2190 	int	result;
2191 	int	this_mark_ppos = STp->first_frame_position;
2192 	int	this_mark_lbn  = STp->logical_blk_num;
2193 #if DEBUG
2194 	char  * name = tape_name(STp);
2195 #endif
2196 
2197 	if (STp->raw) return 0;
2198 
2199 	STp->write_type = OS_WRITE_NEW_MARK;
2200 #if DEBUG
2201 	printk(OSST_DEB_MSG "%s:D: Writing Filemark %i at fppos %d (fseq %d, lblk %d)\n",
2202 	       name, STp->filemark_cnt, this_mark_ppos, STp->frame_seq_number, this_mark_lbn);
2203 #endif
2204 	STp->dirty = 1;
2205 	result  = osst_flush_write_buffer(STp, aSRpnt);
2206 	result |= osst_flush_drive_buffer(STp, aSRpnt);
2207 	STp->last_mark_ppos = this_mark_ppos;
2208 	STp->last_mark_lbn  = this_mark_lbn;
2209 	if (STp->header_cache != NULL && STp->filemark_cnt < OS_FM_TAB_MAX)
2210 		STp->header_cache->dat_fm_tab.fm_tab_ent[STp->filemark_cnt] = htonl(this_mark_ppos);
2211 	if (STp->filemark_cnt++ == 0)
2212 		STp->first_mark_ppos = this_mark_ppos;
2213 	return result;
2214 }
2215 
osst_write_eod(struct osst_tape * STp,struct osst_request ** aSRpnt)2216 static int osst_write_eod(struct osst_tape * STp, struct osst_request ** aSRpnt)
2217 {
2218 	int	result;
2219 #if DEBUG
2220 	char  * name = tape_name(STp);
2221 #endif
2222 
2223 	if (STp->raw) return 0;
2224 
2225 	STp->write_type = OS_WRITE_EOD;
2226 	STp->eod_frame_ppos = STp->first_frame_position;
2227 #if DEBUG
2228 	printk(OSST_DEB_MSG "%s:D: Writing EOD at fppos %d (fseq %d, lblk %d)\n", name,
2229 			STp->eod_frame_ppos, STp->frame_seq_number, STp->logical_blk_num);
2230 #endif
2231 	STp->dirty = 1;
2232 
2233 	result  = osst_flush_write_buffer(STp, aSRpnt);
2234 	result |= osst_flush_drive_buffer(STp, aSRpnt);
2235 	STp->eod_frame_lfa = --(STp->frame_seq_number);
2236 	return result;
2237 }
2238 
osst_write_filler(struct osst_tape * STp,struct osst_request ** aSRpnt,int where,int count)2239 static int osst_write_filler(struct osst_tape * STp, struct osst_request ** aSRpnt, int where, int count)
2240 {
2241 	char * name = tape_name(STp);
2242 
2243 #if DEBUG
2244 	printk(OSST_DEB_MSG "%s:D: Reached onstream write filler group %d\n", name, where);
2245 #endif
2246 	osst_wait_ready(STp, aSRpnt, 60 * 5, 0);
2247 	osst_set_frame_position(STp, aSRpnt, where, 0);
2248 	STp->write_type = OS_WRITE_FILLER;
2249 	while (count--) {
2250 		memcpy(STp->buffer->b_data, "Filler", 6);
2251 		STp->buffer->buffer_bytes = 6;
2252 		STp->dirty = 1;
2253 		if (osst_flush_write_buffer(STp, aSRpnt)) {
2254 			printk(KERN_INFO "%s:I: Couldn't write filler frame\n", name);
2255 			return (-EIO);
2256 		}
2257 	}
2258 #if DEBUG
2259 	printk(OSST_DEB_MSG "%s:D: Exiting onstream write filler group\n", name);
2260 #endif
2261 	return osst_flush_drive_buffer(STp, aSRpnt);
2262 }
2263 
__osst_write_header(struct osst_tape * STp,struct osst_request ** aSRpnt,int where,int count)2264 static int __osst_write_header(struct osst_tape * STp, struct osst_request ** aSRpnt, int where, int count)
2265 {
2266 	char * name = tape_name(STp);
2267 	int     result;
2268 
2269 #if DEBUG
2270 	printk(OSST_DEB_MSG "%s:D: Reached onstream write header group %d\n", name, where);
2271 #endif
2272 	osst_wait_ready(STp, aSRpnt, 60 * 5, 0);
2273 	osst_set_frame_position(STp, aSRpnt, where, 0);
2274 	STp->write_type = OS_WRITE_HEADER;
2275 	while (count--) {
2276 		osst_copy_to_buffer(STp->buffer, (unsigned char *)STp->header_cache);
2277 		STp->buffer->buffer_bytes = sizeof(os_header_t);
2278 		STp->dirty = 1;
2279 		if (osst_flush_write_buffer(STp, aSRpnt)) {
2280 			printk(KERN_INFO "%s:I: Couldn't write header frame\n", name);
2281 			return (-EIO);
2282 		}
2283 	}
2284 	result = osst_flush_drive_buffer(STp, aSRpnt);
2285 #if DEBUG
2286 	printk(OSST_DEB_MSG "%s:D: Write onstream header group %s\n", name, result?"failed":"done");
2287 #endif
2288 	return result;
2289 }
2290 
osst_write_header(struct osst_tape * STp,struct osst_request ** aSRpnt,int locate_eod)2291 static int osst_write_header(struct osst_tape * STp, struct osst_request ** aSRpnt, int locate_eod)
2292 {
2293 	os_header_t * header;
2294 	int	      result;
2295 	char        * name = tape_name(STp);
2296 
2297 #if DEBUG
2298 	printk(OSST_DEB_MSG "%s:D: Writing tape header\n", name);
2299 #endif
2300 	if (STp->raw) return 0;
2301 
2302 	if (STp->header_cache == NULL) {
2303 		if ((STp->header_cache = vmalloc(sizeof(os_header_t))) == NULL) {
2304 			printk(KERN_ERR "%s:E: Failed to allocate header cache\n", name);
2305 			return (-ENOMEM);
2306 		}
2307 		memset(STp->header_cache, 0, sizeof(os_header_t));
2308 #if DEBUG
2309 		printk(OSST_DEB_MSG "%s:D: Allocated and cleared memory for header cache\n", name);
2310 #endif
2311 	}
2312 	if (STp->header_ok) STp->update_frame_cntr++;
2313 	else                STp->update_frame_cntr = 0;
2314 
2315 	header = STp->header_cache;
2316 	strcpy(header->ident_str, "ADR_SEQ");
2317 	header->major_rev      = 1;
2318 	header->minor_rev      = 4;
2319 	header->ext_trk_tb_off = htons(17192);
2320 	header->pt_par_num     = 1;
2321 	header->partition[0].partition_num              = OS_DATA_PARTITION;
2322 	header->partition[0].par_desc_ver               = OS_PARTITION_VERSION;
2323 	header->partition[0].wrt_pass_cntr              = htons(STp->wrt_pass_cntr);
2324 	header->partition[0].first_frame_ppos           = htonl(STp->first_data_ppos);
2325 	header->partition[0].last_frame_ppos            = htonl(STp->capacity);
2326 	header->partition[0].eod_frame_ppos             = htonl(STp->eod_frame_ppos);
2327 	header->cfg_col_width                           = htonl(20);
2328 	header->dat_col_width                           = htonl(1500);
2329 	header->qfa_col_width                           = htonl(0);
2330 	header->ext_track_tb.nr_stream_part             = 1;
2331 	header->ext_track_tb.et_ent_sz                  = 32;
2332 	header->ext_track_tb.dat_ext_trk_ey.et_part_num = 0;
2333 	header->ext_track_tb.dat_ext_trk_ey.fmt         = 1;
2334 	header->ext_track_tb.dat_ext_trk_ey.fm_tab_off  = htons(17736);
2335 	header->ext_track_tb.dat_ext_trk_ey.last_hlb_hi = 0;
2336 	header->ext_track_tb.dat_ext_trk_ey.last_hlb    = htonl(STp->eod_frame_lfa);
2337 	header->ext_track_tb.dat_ext_trk_ey.last_pp	= htonl(STp->eod_frame_ppos);
2338 	header->dat_fm_tab.fm_part_num                  = 0;
2339 	header->dat_fm_tab.fm_tab_ent_sz                = 4;
2340 	header->dat_fm_tab.fm_tab_ent_cnt               = htons(STp->filemark_cnt<OS_FM_TAB_MAX?
2341 								STp->filemark_cnt:OS_FM_TAB_MAX);
2342 
2343 	result  = __osst_write_header(STp, aSRpnt, 0xbae, 5);
2344 	if (STp->update_frame_cntr == 0)
2345 		    osst_write_filler(STp, aSRpnt, 0xbb3, 5);
2346 	result &= __osst_write_header(STp, aSRpnt,     5, 5);
2347 
2348 	if (locate_eod) {
2349 #if DEBUG
2350 		printk(OSST_DEB_MSG "%s:D: Locating back to eod frame addr %d\n", name, STp->eod_frame_ppos);
2351 #endif
2352 		osst_set_frame_position(STp, aSRpnt, STp->eod_frame_ppos, 0);
2353 	}
2354 	if (result)
2355 		printk(KERN_ERR "%s:E: Write header failed\n", name);
2356 	else {
2357 		memcpy(STp->application_sig, "LIN4", 4);
2358 		STp->linux_media         = 1;
2359 		STp->linux_media_version = 4;
2360 		STp->header_ok           = 1;
2361 	}
2362 	return result;
2363 }
2364 
osst_reset_header(struct osst_tape * STp,struct osst_request ** aSRpnt)2365 static int osst_reset_header(struct osst_tape * STp, struct osst_request ** aSRpnt)
2366 {
2367 	if (STp->header_cache != NULL)
2368 		memset(STp->header_cache, 0, sizeof(os_header_t));
2369 
2370 	STp->logical_blk_num = STp->frame_seq_number = 0;
2371 	STp->frame_in_buffer = 0;
2372 	STp->eod_frame_ppos = STp->first_data_ppos = 0x0000000A;
2373 	STp->filemark_cnt = 0;
2374 	STp->first_mark_ppos = STp->last_mark_ppos = STp->last_mark_lbn = -1;
2375 	return osst_write_header(STp, aSRpnt, 1);
2376 }
2377 
__osst_analyze_headers(struct osst_tape * STp,struct osst_request ** aSRpnt,int ppos)2378 static int __osst_analyze_headers(struct osst_tape * STp, struct osst_request ** aSRpnt, int ppos)
2379 {
2380 	char        * name = tape_name(STp);
2381 	os_header_t * header;
2382 	os_aux_t    * aux;
2383 	char          id_string[8];
2384 	int	      linux_media_version,
2385 		      update_frame_cntr;
2386 
2387 	if (STp->raw)
2388 		return 1;
2389 
2390 	if (ppos == 5 || ppos == 0xbae || STp->buffer->syscall_result) {
2391 		if (osst_set_frame_position(STp, aSRpnt, ppos, 0))
2392 			printk(KERN_WARNING "%s:W: Couldn't position tape\n", name);
2393 		osst_wait_ready(STp, aSRpnt, 60 * 15, 0);
2394 		if (osst_initiate_read (STp, aSRpnt)) {
2395 			printk(KERN_WARNING "%s:W: Couldn't initiate read\n", name);
2396 			return 0;
2397 		}
2398 	}
2399 	if (osst_read_frame(STp, aSRpnt, 180)) {
2400 #if DEBUG
2401 		printk(OSST_DEB_MSG "%s:D: Couldn't read header frame\n", name);
2402 #endif
2403 		return 0;
2404 	}
2405 	header = (os_header_t *) STp->buffer->b_data;	/* warning: only first segment addressable */
2406 	aux = STp->buffer->aux;
2407 	if (aux->frame_type != OS_FRAME_TYPE_HEADER) {
2408 #if DEBUG
2409 		printk(OSST_DEB_MSG "%s:D: Skipping non-header frame (%d)\n", name, ppos);
2410 #endif
2411 		return 0;
2412 	}
2413 	if (ntohl(aux->frame_seq_num)              != 0                   ||
2414 	    ntohl(aux->logical_blk_num)            != 0                   ||
2415 	          aux->partition.partition_num     != OS_CONFIG_PARTITION ||
2416 	    ntohl(aux->partition.first_frame_ppos) != 0                   ||
2417 	    ntohl(aux->partition.last_frame_ppos)  != 0xbb7               ) {
2418 #if DEBUG
2419 		printk(OSST_DEB_MSG "%s:D: Invalid header frame (%d,%d,%d,%d,%d)\n", name,
2420 				ntohl(aux->frame_seq_num), ntohl(aux->logical_blk_num),
2421 			       	aux->partition.partition_num, ntohl(aux->partition.first_frame_ppos),
2422 			       	ntohl(aux->partition.last_frame_ppos));
2423 #endif
2424 		return 0;
2425 	}
2426 	if (strncmp(header->ident_str, "ADR_SEQ", 7) != 0 &&
2427 	    strncmp(header->ident_str, "ADR-SEQ", 7) != 0) {
2428 		strlcpy(id_string, header->ident_str, 8);
2429 #if DEBUG
2430 		printk(OSST_DEB_MSG "%s:D: Invalid header identification string %s\n", name, id_string);
2431 #endif
2432 		return 0;
2433 	}
2434 	update_frame_cntr = ntohl(aux->update_frame_cntr);
2435 	if (update_frame_cntr < STp->update_frame_cntr) {
2436 #if DEBUG
2437 		printk(OSST_DEB_MSG "%s:D: Skipping frame %d with update_frame_counter %d<%d\n",
2438 				   name, ppos, update_frame_cntr, STp->update_frame_cntr);
2439 #endif
2440 		return 0;
2441 	}
2442 	if (header->major_rev != 1 || header->minor_rev != 4 ) {
2443 #if DEBUG
2444 		printk(OSST_DEB_MSG "%s:D: %s revision %d.%d detected (1.4 supported)\n",
2445 				 name, (header->major_rev != 1 || header->minor_rev < 2 ||
2446 				       header->minor_rev  > 4 )? "Invalid" : "Warning:",
2447 				 header->major_rev, header->minor_rev);
2448 #endif
2449 		if (header->major_rev != 1 || header->minor_rev < 2 || header->minor_rev > 4)
2450 			return 0;
2451 	}
2452 #if DEBUG
2453 	if (header->pt_par_num != 1)
2454 		printk(KERN_INFO "%s:W: %d partitions defined, only one supported\n",
2455 				 name, header->pt_par_num);
2456 #endif
2457 	memcpy(id_string, aux->application_sig, 4);
2458 	id_string[4] = 0;
2459 	if (memcmp(id_string, "LIN", 3) == 0) {
2460 		STp->linux_media = 1;
2461 		linux_media_version = id_string[3] - '0';
2462 		if (linux_media_version != 4)
2463 			printk(KERN_INFO "%s:I: Linux media version %d detected (current 4)\n",
2464 					 name, linux_media_version);
2465 	} else {
2466 		printk(KERN_WARNING "%s:W: Non Linux media detected (%s)\n", name, id_string);
2467 		return 0;
2468 	}
2469 	if (linux_media_version < STp->linux_media_version) {
2470 #if DEBUG
2471 		printk(OSST_DEB_MSG "%s:D: Skipping frame %d with linux_media_version %d\n",
2472 				  name, ppos, linux_media_version);
2473 #endif
2474 		return 0;
2475 	}
2476 	if (linux_media_version > STp->linux_media_version) {
2477 #if DEBUG
2478 		printk(OSST_DEB_MSG "%s:D: Frame %d sets linux_media_version to %d\n",
2479 				   name, ppos, linux_media_version);
2480 #endif
2481 		memcpy(STp->application_sig, id_string, 5);
2482 		STp->linux_media_version = linux_media_version;
2483 		STp->update_frame_cntr = -1;
2484 	}
2485 	if (update_frame_cntr > STp->update_frame_cntr) {
2486 #if DEBUG
2487 		printk(OSST_DEB_MSG "%s:D: Frame %d sets update_frame_counter to %d\n",
2488 				   name, ppos, update_frame_cntr);
2489 #endif
2490 		if (STp->header_cache == NULL) {
2491 			if ((STp->header_cache = vmalloc(sizeof(os_header_t))) == NULL) {
2492 				printk(KERN_ERR "%s:E: Failed to allocate header cache\n", name);
2493 				return 0;
2494 			}
2495 #if DEBUG
2496 			printk(OSST_DEB_MSG "%s:D: Allocated memory for header cache\n", name);
2497 #endif
2498 		}
2499 		osst_copy_from_buffer(STp->buffer, (unsigned char *)STp->header_cache);
2500 		header = STp->header_cache;	/* further accesses from cached (full) copy */
2501 
2502 		STp->wrt_pass_cntr     = ntohs(header->partition[0].wrt_pass_cntr);
2503 		STp->first_data_ppos   = ntohl(header->partition[0].first_frame_ppos);
2504 		STp->eod_frame_ppos    = ntohl(header->partition[0].eod_frame_ppos);
2505 		STp->eod_frame_lfa     = ntohl(header->ext_track_tb.dat_ext_trk_ey.last_hlb);
2506 		STp->filemark_cnt      = ntohl(aux->filemark_cnt);
2507 		STp->first_mark_ppos   = ntohl(aux->next_mark_ppos);
2508 		STp->last_mark_ppos    = ntohl(aux->last_mark_ppos);
2509 		STp->last_mark_lbn     = ntohl(aux->last_mark_lbn);
2510 		STp->update_frame_cntr = update_frame_cntr;
2511 #if DEBUG
2512 	printk(OSST_DEB_MSG "%s:D: Detected write pass %d, update frame counter %d, filemark counter %d\n",
2513 			  name, STp->wrt_pass_cntr, STp->update_frame_cntr, STp->filemark_cnt);
2514 	printk(OSST_DEB_MSG "%s:D: first data frame on tape = %d, last = %d, eod frame = %d\n", name,
2515 			  STp->first_data_ppos,
2516 			  ntohl(header->partition[0].last_frame_ppos),
2517 			  ntohl(header->partition[0].eod_frame_ppos));
2518 	printk(OSST_DEB_MSG "%s:D: first mark on tape = %d, last = %d, eod frame = %d\n",
2519 			  name, STp->first_mark_ppos, STp->last_mark_ppos, STp->eod_frame_ppos);
2520 #endif
2521 		if (header->minor_rev < 4 && STp->linux_media_version == 4) {
2522 #if DEBUG
2523 			printk(OSST_DEB_MSG "%s:D: Moving filemark list to ADR 1.4 location\n", name);
2524 #endif
2525 			memcpy((void *)header->dat_fm_tab.fm_tab_ent,
2526 			       (void *)header->old_filemark_list, sizeof(header->dat_fm_tab.fm_tab_ent));
2527 			memset((void *)header->old_filemark_list, 0, sizeof(header->old_filemark_list));
2528 		}
2529 		if (header->minor_rev == 4   &&
2530 		    (header->ext_trk_tb_off                          != htons(17192)               ||
2531 		     header->partition[0].partition_num              != OS_DATA_PARTITION          ||
2532 		     header->partition[0].par_desc_ver               != OS_PARTITION_VERSION       ||
2533 		     header->partition[0].last_frame_ppos            != htonl(STp->capacity)       ||
2534 		     header->cfg_col_width                           != htonl(20)                  ||
2535 		     header->dat_col_width                           != htonl(1500)                ||
2536 		     header->qfa_col_width                           != htonl(0)                   ||
2537 		     header->ext_track_tb.nr_stream_part             != 1                          ||
2538 		     header->ext_track_tb.et_ent_sz                  != 32                         ||
2539 		     header->ext_track_tb.dat_ext_trk_ey.et_part_num != OS_DATA_PARTITION          ||
2540 		     header->ext_track_tb.dat_ext_trk_ey.fmt         != 1                          ||
2541 		     header->ext_track_tb.dat_ext_trk_ey.fm_tab_off  != htons(17736)               ||
2542 		     header->ext_track_tb.dat_ext_trk_ey.last_hlb_hi != 0                          ||
2543 		     header->ext_track_tb.dat_ext_trk_ey.last_pp     != htonl(STp->eod_frame_ppos) ||
2544 		     header->dat_fm_tab.fm_part_num                  != OS_DATA_PARTITION          ||
2545 		     header->dat_fm_tab.fm_tab_ent_sz                != 4                          ||
2546 		     header->dat_fm_tab.fm_tab_ent_cnt               !=
2547 			     htons(STp->filemark_cnt<OS_FM_TAB_MAX?STp->filemark_cnt:OS_FM_TAB_MAX)))
2548 			printk(KERN_WARNING "%s:W: Failed consistency check ADR 1.4 format\n", name);
2549 
2550 	}
2551 
2552 	return 1;
2553 }
2554 
osst_analyze_headers(struct osst_tape * STp,struct osst_request ** aSRpnt)2555 static int osst_analyze_headers(struct osst_tape * STp, struct osst_request ** aSRpnt)
2556 {
2557 	int	position, ppos;
2558 	int	first, last;
2559 	int	valid = 0;
2560 	char  * name  = tape_name(STp);
2561 
2562 	position = osst_get_frame_position(STp, aSRpnt);
2563 
2564 	if (STp->raw) {
2565 		STp->header_ok = STp->linux_media = 1;
2566 		STp->linux_media_version = 0;
2567 		return 1;
2568 	}
2569 	STp->header_ok = STp->linux_media = STp->linux_media_version = 0;
2570 	STp->wrt_pass_cntr = STp->update_frame_cntr = -1;
2571 	STp->eod_frame_ppos = STp->first_data_ppos = -1;
2572 	STp->first_mark_ppos = STp->last_mark_ppos = STp->last_mark_lbn = -1;
2573 #if DEBUG
2574 	printk(OSST_DEB_MSG "%s:D: Reading header\n", name);
2575 #endif
2576 
2577 	/* optimization for speed - if we are positioned at ppos 10, read second group first  */
2578 	/* TODO try the ADR 1.1 locations for the second group if we have no valid one yet... */
2579 
2580 	first = position==10?0xbae: 5;
2581 	last  = position==10?0xbb3:10;
2582 
2583 	for (ppos = first; ppos < last; ppos++)
2584 		if (__osst_analyze_headers(STp, aSRpnt, ppos))
2585 			valid = 1;
2586 
2587 	first = position==10? 5:0xbae;
2588 	last  = position==10?10:0xbb3;
2589 
2590 	for (ppos = first; ppos < last; ppos++)
2591 		if (__osst_analyze_headers(STp, aSRpnt, ppos))
2592 			valid = 1;
2593 
2594 	if (!valid) {
2595 		printk(KERN_ERR "%s:E: Failed to find valid ADRL header, new media?\n", name);
2596 		STp->eod_frame_ppos = STp->first_data_ppos = 0;
2597 		osst_set_frame_position(STp, aSRpnt, 10, 0);
2598 		return 0;
2599 	}
2600 	if (position <= STp->first_data_ppos) {
2601 		position = STp->first_data_ppos;
2602 		STp->ps[0].drv_file = STp->ps[0].drv_block = STp->frame_seq_number = STp->logical_blk_num = 0;
2603 	}
2604 	osst_set_frame_position(STp, aSRpnt, position, 0);
2605 	STp->header_ok = 1;
2606 
2607 	return 1;
2608 }
2609 
osst_verify_position(struct osst_tape * STp,struct osst_request ** aSRpnt)2610 static int osst_verify_position(struct osst_tape * STp, struct osst_request ** aSRpnt)
2611 {
2612 	int	frame_position  = STp->first_frame_position;
2613 	int	frame_seq_numbr = STp->frame_seq_number;
2614 	int	logical_blk_num = STp->logical_blk_num;
2615        	int	halfway_frame   = STp->frame_in_buffer;
2616 	int	read_pointer    = STp->buffer->read_pointer;
2617 	int	prev_mark_ppos  = -1;
2618 	int	actual_mark_ppos, i, n;
2619 #if DEBUG
2620 	char  * name = tape_name(STp);
2621 
2622 	printk(OSST_DEB_MSG "%s:D: Verify that the tape is really the one we think before writing\n", name);
2623 #endif
2624 	osst_set_frame_position(STp, aSRpnt, frame_position - 1, 0);
2625 	if (osst_get_logical_frame(STp, aSRpnt, -1, 0) < 0) {
2626 #if DEBUG
2627 		printk(OSST_DEB_MSG "%s:D: Couldn't get logical blk num in verify_position\n", name);
2628 #endif
2629 		return (-EIO);
2630 	}
2631 	if (STp->linux_media_version >= 4) {
2632 		for (i=0; i<STp->filemark_cnt; i++)
2633 			if ((n=ntohl(STp->header_cache->dat_fm_tab.fm_tab_ent[i])) < frame_position)
2634 				prev_mark_ppos = n;
2635 	} else
2636 		prev_mark_ppos = frame_position - 1;  /* usually - we don't really know */
2637 	actual_mark_ppos = STp->buffer->aux->frame_type == OS_FRAME_TYPE_MARKER ?
2638 				frame_position - 1 : ntohl(STp->buffer->aux->last_mark_ppos);
2639 	if (frame_position  != STp->first_frame_position                   ||
2640 	    frame_seq_numbr != STp->frame_seq_number + (halfway_frame?0:1) ||
2641 	    prev_mark_ppos  != actual_mark_ppos                            ) {
2642 #if DEBUG
2643 		printk(OSST_DEB_MSG "%s:D: Block mismatch: fppos %d-%d, fseq %d-%d, mark %d-%d\n", name,
2644 				  STp->first_frame_position, frame_position,
2645 				  STp->frame_seq_number + (halfway_frame?0:1),
2646 				  frame_seq_numbr, actual_mark_ppos, prev_mark_ppos);
2647 #endif
2648 		return (-EIO);
2649 	}
2650 	if (halfway_frame) {
2651 		/* prepare buffer for append and rewrite on top of original */
2652 		osst_set_frame_position(STp, aSRpnt, frame_position - 1, 0);
2653 		STp->buffer->buffer_bytes  = read_pointer;
2654 		STp->ps[STp->partition].rw = ST_WRITING;
2655 		STp->dirty                 = 1;
2656 	}
2657 	STp->frame_in_buffer  = halfway_frame;
2658 	STp->frame_seq_number = frame_seq_numbr;
2659 	STp->logical_blk_num  = logical_blk_num;
2660 	return 0;
2661 }
2662 
2663 /* Acc. to OnStream, the vers. numbering is the following:
2664  * X.XX for released versions (X=digit),
2665  * XXXY for unreleased versions (Y=letter)
2666  * Ordering 1.05 < 106A < 106B < ...  < 106a < ... < 1.06
2667  * This fn makes monoton numbers out of this scheme ...
2668  */
osst_parse_firmware_rev(const char * str)2669 static unsigned int osst_parse_firmware_rev (const char * str)
2670 {
2671 	if (str[1] == '.') {
2672 		return (str[0]-'0')*10000
2673 			+(str[2]-'0')*1000
2674 			+(str[3]-'0')*100;
2675 	} else {
2676 		return (str[0]-'0')*10000
2677 			+(str[1]-'0')*1000
2678 			+(str[2]-'0')*100 - 100
2679 			+(str[3]-'@');
2680 	}
2681 }
2682 
2683 /*
2684  * Configure the OnStream SCII tape drive for default operation
2685  */
osst_configure_onstream(struct osst_tape * STp,struct osst_request ** aSRpnt)2686 static int osst_configure_onstream(struct osst_tape *STp, struct osst_request ** aSRpnt)
2687 {
2688 	unsigned char                  cmd[MAX_COMMAND_SIZE];
2689 	char                         * name = tape_name(STp);
2690 	struct osst_request          * SRpnt = * aSRpnt;
2691 	osst_mode_parameter_header_t * header;
2692 	osst_block_size_page_t       * bs;
2693 	osst_capabilities_page_t     * cp;
2694 	osst_tape_paramtr_page_t     * prm;
2695 	int                            drive_buffer_size;
2696 
2697 	if (STp->ready != ST_READY) {
2698 #if DEBUG
2699 	    printk(OSST_DEB_MSG "%s:D: Not Ready\n", name);
2700 #endif
2701 	    return (-EIO);
2702 	}
2703 
2704 	if (STp->os_fw_rev < 10600) {
2705 	    printk(KERN_INFO "%s:I: Old OnStream firmware revision detected (%s),\n", name, STp->device->rev);
2706 	    printk(KERN_INFO "%s:I: an upgrade to version 1.06 or above is recommended\n", name);
2707 	}
2708 
2709 	/*
2710 	 * Configure 32.5KB (data+aux) frame size.
2711          * Get the current frame size from the block size mode page
2712 	 */
2713 	memset(cmd, 0, MAX_COMMAND_SIZE);
2714 	cmd[0] = MODE_SENSE;
2715 	cmd[1] = 8;
2716 	cmd[2] = BLOCK_SIZE_PAGE;
2717 	cmd[4] = BLOCK_SIZE_PAGE_LENGTH + MODE_HEADER_LENGTH;
2718 
2719 	SRpnt = osst_do_scsi(SRpnt, STp, cmd, cmd[4], DMA_FROM_DEVICE, STp->timeout, 0, 1);
2720 	if (SRpnt == NULL) {
2721 #if DEBUG
2722  	    printk(OSST_DEB_MSG "osst :D: Busy\n");
2723 #endif
2724 	    return (-EBUSY);
2725 	}
2726 	*aSRpnt = SRpnt;
2727 	if ((STp->buffer)->syscall_result != 0) {
2728 	    printk (KERN_ERR "%s:E: Can't get tape block size mode page\n", name);
2729 	    return (-EIO);
2730 	}
2731 
2732 	header = (osst_mode_parameter_header_t *) (STp->buffer)->b_data;
2733 	bs = (osst_block_size_page_t *) ((STp->buffer)->b_data + sizeof(osst_mode_parameter_header_t) + header->bdl);
2734 
2735 #if DEBUG
2736 	printk(OSST_DEB_MSG "%s:D: 32KB play back: %s\n",   name, bs->play32     ? "Yes" : "No");
2737 	printk(OSST_DEB_MSG "%s:D: 32.5KB play back: %s\n", name, bs->play32_5   ? "Yes" : "No");
2738 	printk(OSST_DEB_MSG "%s:D: 32KB record: %s\n",      name, bs->record32   ? "Yes" : "No");
2739 	printk(OSST_DEB_MSG "%s:D: 32.5KB record: %s\n",    name, bs->record32_5 ? "Yes" : "No");
2740 #endif
2741 
2742 	/*
2743 	 * Configure default auto columns mode, 32.5KB transfer mode
2744 	 */
2745 	bs->one = 1;
2746 	bs->play32 = 0;
2747 	bs->play32_5 = 1;
2748 	bs->record32 = 0;
2749 	bs->record32_5 = 1;
2750 
2751 	memset(cmd, 0, MAX_COMMAND_SIZE);
2752 	cmd[0] = MODE_SELECT;
2753 	cmd[1] = 0x10;
2754 	cmd[4] = BLOCK_SIZE_PAGE_LENGTH + MODE_HEADER_LENGTH;
2755 
2756 	SRpnt = osst_do_scsi(SRpnt, STp, cmd, cmd[4], DMA_TO_DEVICE, STp->timeout, 0, 1);
2757 	*aSRpnt = SRpnt;
2758 	if ((STp->buffer)->syscall_result != 0) {
2759 	    printk (KERN_ERR "%s:E: Couldn't set tape block size mode page\n", name);
2760 	    return (-EIO);
2761 	}
2762 
2763 #if DEBUG
2764 	printk(KERN_INFO "%s:D: Drive Block Size changed to 32.5K\n", name);
2765 	 /*
2766 	 * In debug mode, we want to see as many errors as possible
2767 	 * to test the error recovery mechanism.
2768 	 */
2769 	osst_set_retries(STp, aSRpnt, 0);
2770 	SRpnt = * aSRpnt;
2771 #endif
2772 
2773 	/*
2774 	 * Set vendor name to 'LIN4' for "Linux support version 4".
2775 	 */
2776 
2777 	memset(cmd, 0, MAX_COMMAND_SIZE);
2778 	cmd[0] = MODE_SELECT;
2779 	cmd[1] = 0x10;
2780 	cmd[4] = VENDOR_IDENT_PAGE_LENGTH + MODE_HEADER_LENGTH;
2781 
2782 	header->mode_data_length = VENDOR_IDENT_PAGE_LENGTH + MODE_HEADER_LENGTH - 1;
2783 	header->medium_type      = 0;	/* Medium Type - ignoring */
2784 	header->dsp              = 0;	/* Reserved */
2785 	header->bdl              = 0;	/* Block Descriptor Length */
2786 
2787 	(STp->buffer)->b_data[MODE_HEADER_LENGTH + 0] = VENDOR_IDENT_PAGE | (1 << 7);
2788 	(STp->buffer)->b_data[MODE_HEADER_LENGTH + 1] = 6;
2789 	(STp->buffer)->b_data[MODE_HEADER_LENGTH + 2] = 'L';
2790 	(STp->buffer)->b_data[MODE_HEADER_LENGTH + 3] = 'I';
2791 	(STp->buffer)->b_data[MODE_HEADER_LENGTH + 4] = 'N';
2792 	(STp->buffer)->b_data[MODE_HEADER_LENGTH + 5] = '4';
2793 	(STp->buffer)->b_data[MODE_HEADER_LENGTH + 6] = 0;
2794 	(STp->buffer)->b_data[MODE_HEADER_LENGTH + 7] = 0;
2795 
2796 	SRpnt = osst_do_scsi(SRpnt, STp, cmd, cmd[4], DMA_TO_DEVICE, STp->timeout, 0, 1);
2797 	*aSRpnt = SRpnt;
2798 
2799 	if ((STp->buffer)->syscall_result != 0) {
2800 	    printk (KERN_ERR "%s:E: Couldn't set vendor name to %s\n", name,
2801 			(char *) ((STp->buffer)->b_data + MODE_HEADER_LENGTH + 2));
2802 	    return (-EIO);
2803 	}
2804 
2805 	memset(cmd, 0, MAX_COMMAND_SIZE);
2806 	cmd[0] = MODE_SENSE;
2807 	cmd[1] = 8;
2808 	cmd[2] = CAPABILITIES_PAGE;
2809 	cmd[4] = CAPABILITIES_PAGE_LENGTH + MODE_HEADER_LENGTH;
2810 
2811 	SRpnt = osst_do_scsi(SRpnt, STp, cmd, cmd[4], DMA_FROM_DEVICE, STp->timeout, 0, 1);
2812 	*aSRpnt = SRpnt;
2813 
2814 	if ((STp->buffer)->syscall_result != 0) {
2815 	    printk (KERN_ERR "%s:E: Can't get capabilities page\n", name);
2816 	    return (-EIO);
2817 	}
2818 
2819 	header = (osst_mode_parameter_header_t *) (STp->buffer)->b_data;
2820 	cp     = (osst_capabilities_page_t    *) ((STp->buffer)->b_data +
2821 		 sizeof(osst_mode_parameter_header_t) + header->bdl);
2822 
2823 	drive_buffer_size = ntohs(cp->buffer_size) / 2;
2824 
2825 	memset(cmd, 0, MAX_COMMAND_SIZE);
2826 	cmd[0] = MODE_SENSE;
2827 	cmd[1] = 8;
2828 	cmd[2] = TAPE_PARAMTR_PAGE;
2829 	cmd[4] = TAPE_PARAMTR_PAGE_LENGTH + MODE_HEADER_LENGTH;
2830 
2831 	SRpnt = osst_do_scsi(SRpnt, STp, cmd, cmd[4], DMA_FROM_DEVICE, STp->timeout, 0, 1);
2832 	*aSRpnt = SRpnt;
2833 
2834 	if ((STp->buffer)->syscall_result != 0) {
2835 	    printk (KERN_ERR "%s:E: Can't get tape parameter page\n", name);
2836 	    return (-EIO);
2837 	}
2838 
2839 	header = (osst_mode_parameter_header_t *) (STp->buffer)->b_data;
2840 	prm    = (osst_tape_paramtr_page_t    *) ((STp->buffer)->b_data +
2841 		 sizeof(osst_mode_parameter_header_t) + header->bdl);
2842 
2843 	STp->density  = prm->density;
2844 	STp->capacity = ntohs(prm->segtrk) * ntohs(prm->trks);
2845 #if DEBUG
2846 	printk(OSST_DEB_MSG "%s:D: Density %d, tape length: %dMB, drive buffer size: %dKB\n",
2847 			  name, STp->density, STp->capacity / 32, drive_buffer_size);
2848 #endif
2849 
2850 	return 0;
2851 
2852 }
2853 
2854 
2855 /* Step over EOF if it has been inadvertently crossed (ioctl not used because
2856    it messes up the block number). */
cross_eof(struct osst_tape * STp,struct osst_request ** aSRpnt,int forward)2857 static int cross_eof(struct osst_tape *STp, struct osst_request ** aSRpnt, int forward)
2858 {
2859 	int	result;
2860 	char  * name = tape_name(STp);
2861 
2862 #if DEBUG
2863 	if (debugging)
2864 		printk(OSST_DEB_MSG "%s:D: Stepping over filemark %s.\n",
2865 	   			  name, forward ? "forward" : "backward");
2866 #endif
2867 
2868 	if (forward) {
2869 	   /* assumes that the filemark is already read by the drive, so this is low cost */
2870 	   result = osst_space_over_filemarks_forward_slow(STp, aSRpnt, MTFSF, 1);
2871 	}
2872 	else
2873 	   /* assumes this is only called if we just read the filemark! */
2874 	   result = osst_seek_logical_blk(STp, aSRpnt, STp->logical_blk_num - 1);
2875 
2876 	if (result < 0)
2877 	   printk(KERN_WARNING "%s:W: Stepping over filemark %s failed.\n",
2878 				name, forward ? "forward" : "backward");
2879 
2880 	return result;
2881 }
2882 
2883 
2884 /* Get the tape position. */
2885 
osst_get_frame_position(struct osst_tape * STp,struct osst_request ** aSRpnt)2886 static int osst_get_frame_position(struct osst_tape *STp, struct osst_request ** aSRpnt)
2887 {
2888 	unsigned char		scmd[MAX_COMMAND_SIZE];
2889 	struct osst_request   * SRpnt;
2890 	int			result = 0;
2891 	char    	      * name   = tape_name(STp);
2892 
2893 	/* KG: We want to be able to use it for checking Write Buffer availability
2894 	 *  and thus don't want to risk to overwrite anything. Exchange buffers ... */
2895 	char		mybuf[24];
2896 	char	      * olddata = STp->buffer->b_data;
2897 	int		oldsize = STp->buffer->buffer_size;
2898 
2899 	if (STp->ready != ST_READY) return (-EIO);
2900 
2901 	memset (scmd, 0, MAX_COMMAND_SIZE);
2902 	scmd[0] = READ_POSITION;
2903 
2904 	STp->buffer->b_data = mybuf; STp->buffer->buffer_size = 24;
2905 	SRpnt = osst_do_scsi(*aSRpnt, STp, scmd, 20, DMA_FROM_DEVICE,
2906 				      STp->timeout, MAX_RETRIES, 1);
2907 	if (!SRpnt) {
2908 		STp->buffer->b_data = olddata; STp->buffer->buffer_size = oldsize;
2909 		return (-EBUSY);
2910 	}
2911 	*aSRpnt = SRpnt;
2912 
2913 	if (STp->buffer->syscall_result)
2914 		result = ((SRpnt->sense[2] & 0x0f) == 3) ? -EIO : -EINVAL;	/* 3: Write Error */
2915 
2916 	if (result == -EINVAL)
2917 		printk(KERN_ERR "%s:E: Can't read tape position.\n", name);
2918 	else {
2919 		if (result == -EIO) {	/* re-read position - this needs to preserve media errors */
2920 			unsigned char mysense[16];
2921 			memcpy (mysense, SRpnt->sense, 16);
2922 			memset (scmd, 0, MAX_COMMAND_SIZE);
2923 			scmd[0] = READ_POSITION;
2924 			STp->buffer->b_data = mybuf; STp->buffer->buffer_size = 24;
2925 			SRpnt = osst_do_scsi(SRpnt, STp, scmd, 20, DMA_FROM_DEVICE,
2926 						    STp->timeout, MAX_RETRIES, 1);
2927 #if DEBUG
2928 			printk(OSST_DEB_MSG "%s:D: Reread position, reason=[%02x:%02x:%02x], result=[%s%02x:%02x:%02x]\n",
2929 					name, mysense[2], mysense[12], mysense[13], STp->buffer->syscall_result?"":"ok:",
2930 					SRpnt->sense[2],SRpnt->sense[12],SRpnt->sense[13]);
2931 #endif
2932 			if (!STp->buffer->syscall_result)
2933 				memcpy (SRpnt->sense, mysense, 16);
2934 			else
2935 				printk(KERN_WARNING "%s:W: Double error in get position\n", name);
2936 		}
2937 		STp->first_frame_position = ((STp->buffer)->b_data[4] << 24)
2938 					  + ((STp->buffer)->b_data[5] << 16)
2939 					  + ((STp->buffer)->b_data[6] << 8)
2940 					  +  (STp->buffer)->b_data[7];
2941 		STp->last_frame_position  = ((STp->buffer)->b_data[ 8] << 24)
2942 					  + ((STp->buffer)->b_data[ 9] << 16)
2943 					  + ((STp->buffer)->b_data[10] <<  8)
2944 					  +  (STp->buffer)->b_data[11];
2945 		STp->cur_frames           =  (STp->buffer)->b_data[15];
2946 #if DEBUG
2947 		if (debugging) {
2948 			printk(OSST_DEB_MSG "%s:D: Drive Positions: host %d, tape %d%s, buffer %d\n", name,
2949 					    STp->first_frame_position, STp->last_frame_position,
2950 					    ((STp->buffer)->b_data[0]&0x80)?" (BOP)":
2951 					    ((STp->buffer)->b_data[0]&0x40)?" (EOP)":"",
2952 					    STp->cur_frames);
2953 		}
2954 #endif
2955 		if (STp->cur_frames == 0 && STp->first_frame_position != STp->last_frame_position) {
2956 #if DEBUG
2957 			printk(OSST_DEB_MSG "%s:D: Correcting read position %d, %d, %d\n", name,
2958 					STp->first_frame_position, STp->last_frame_position, STp->cur_frames);
2959 #endif
2960 			STp->first_frame_position = STp->last_frame_position;
2961 		}
2962 	}
2963 	STp->buffer->b_data = olddata; STp->buffer->buffer_size = oldsize;
2964 
2965 	return (result == 0 ? STp->first_frame_position : result);
2966 }
2967 
2968 
2969 /* Set the tape block */
osst_set_frame_position(struct osst_tape * STp,struct osst_request ** aSRpnt,int ppos,int skip)2970 static int osst_set_frame_position(struct osst_tape *STp, struct osst_request ** aSRpnt, int ppos, int skip)
2971 {
2972 	unsigned char		scmd[MAX_COMMAND_SIZE];
2973 	struct osst_request   * SRpnt;
2974 	struct st_partstat    * STps;
2975 	int			result = 0;
2976 	int			pp     = (ppos == 3000 && !skip)? 0 : ppos;
2977 	char		      * name   = tape_name(STp);
2978 
2979 	if (STp->ready != ST_READY) return (-EIO);
2980 
2981 	STps = &(STp->ps[STp->partition]);
2982 
2983 	if (ppos < 0 || ppos > STp->capacity) {
2984 		printk(KERN_WARNING "%s:W: Reposition request %d out of range\n", name, ppos);
2985 		pp = ppos = ppos < 0 ? 0 : (STp->capacity - 1);
2986 		result = (-EINVAL);
2987 	}
2988 
2989 	do {
2990 #if DEBUG
2991 		if (debugging)
2992 			printk(OSST_DEB_MSG "%s:D: Setting ppos to %d.\n", name, pp);
2993 #endif
2994 		memset (scmd, 0, MAX_COMMAND_SIZE);
2995 		scmd[0] = SEEK_10;
2996 		scmd[1] = 1;
2997 		scmd[3] = (pp >> 24);
2998 		scmd[4] = (pp >> 16);
2999 		scmd[5] = (pp >> 8);
3000 		scmd[6] =  pp;
3001 		if (skip)
3002 			scmd[9] = 0x80;
3003 
3004 		SRpnt = osst_do_scsi(*aSRpnt, STp, scmd, 0, DMA_NONE, STp->long_timeout,
3005 								MAX_RETRIES, 1);
3006 		if (!SRpnt)
3007 			return (-EBUSY);
3008 		*aSRpnt  = SRpnt;
3009 
3010 		if ((STp->buffer)->syscall_result != 0) {
3011 #if DEBUG
3012 			printk(OSST_DEB_MSG "%s:D: SEEK command from %d to %d failed.\n",
3013 					name, STp->first_frame_position, pp);
3014 #endif
3015 			result = (-EIO);
3016 		}
3017 		if (pp != ppos)
3018 			osst_wait_ready(STp, aSRpnt, 5 * 60, OSST_WAIT_POSITION_COMPLETE);
3019 	} while ((pp != ppos) && (pp = ppos));
3020 	STp->first_frame_position = STp->last_frame_position = ppos;
3021 	STps->eof = ST_NOEOF;
3022 	STps->at_sm = 0;
3023 	STps->rw = ST_IDLE;
3024 	STp->frame_in_buffer = 0;
3025 	return result;
3026 }
3027 
osst_write_trailer(struct osst_tape * STp,struct osst_request ** aSRpnt,int leave_at_EOT)3028 static int osst_write_trailer(struct osst_tape *STp, struct osst_request ** aSRpnt, int leave_at_EOT)
3029 {
3030 	struct st_partstat * STps = &(STp->ps[STp->partition]);
3031 	int result = 0;
3032 
3033 	if (STp->write_type != OS_WRITE_NEW_MARK) {
3034 		/* true unless the user wrote the filemark for us */
3035 		result = osst_flush_drive_buffer(STp, aSRpnt);
3036 		if (result < 0) goto out;
3037 		result = osst_write_filemark(STp, aSRpnt);
3038 		if (result < 0) goto out;
3039 
3040 		if (STps->drv_file >= 0)
3041 			STps->drv_file++ ;
3042 		STps->drv_block = 0;
3043 	}
3044 	result = osst_write_eod(STp, aSRpnt);
3045 	osst_write_header(STp, aSRpnt, leave_at_EOT);
3046 
3047 	STps->eof = ST_FM;
3048 out:
3049 	return result;
3050 }
3051 
3052 /* osst versions of st functions - augmented and stripped to suit OnStream only */
3053 
3054 /* Flush the write buffer (never need to write if variable blocksize). */
osst_flush_write_buffer(struct osst_tape * STp,struct osst_request ** aSRpnt)3055 static int osst_flush_write_buffer(struct osst_tape *STp, struct osst_request ** aSRpnt)
3056 {
3057 	int			offset, transfer, blks = 0;
3058 	int			result = 0;
3059 	unsigned char		cmd[MAX_COMMAND_SIZE];
3060 	struct osst_request   * SRpnt = *aSRpnt;
3061 	struct st_partstat    * STps;
3062 	char		      * name = tape_name(STp);
3063 
3064 	if ((STp->buffer)->writing) {
3065 		if (SRpnt == (STp->buffer)->last_SRpnt)
3066 #if DEBUG
3067 			{ printk(OSST_DEB_MSG
3068 	 "%s:D: aSRpnt points to osst_request that write_behind_check will release -- cleared\n", name);
3069 #endif
3070 			*aSRpnt = SRpnt = NULL;
3071 #if DEBUG
3072 			} else if (SRpnt)
3073 				printk(OSST_DEB_MSG
3074 	 "%s:D: aSRpnt does not point to osst_request that write_behind_check will release -- strange\n", name);
3075 #endif
3076 		osst_write_behind_check(STp);
3077 		if ((STp->buffer)->syscall_result) {
3078 #if DEBUG
3079 			if (debugging)
3080 				printk(OSST_DEB_MSG "%s:D: Async write error (flush) %x.\n",
3081 				       name, (STp->buffer)->midlevel_result);
3082 #endif
3083 			if ((STp->buffer)->midlevel_result == INT_MAX)
3084 				return (-ENOSPC);
3085 			return (-EIO);
3086 		}
3087 	}
3088 
3089 	result = 0;
3090 	if (STp->dirty == 1) {
3091 
3092 		STp->write_count++;
3093 		STps     = &(STp->ps[STp->partition]);
3094 		STps->rw = ST_WRITING;
3095 		offset   = STp->buffer->buffer_bytes;
3096 		blks     = (offset + STp->block_size - 1) / STp->block_size;
3097 		transfer = OS_FRAME_SIZE;
3098 
3099 		if (offset < OS_DATA_SIZE)
3100 			osst_zero_buffer_tail(STp->buffer);
3101 
3102 		if (STp->poll)
3103 			if (osst_wait_frame (STp, aSRpnt, STp->first_frame_position, -50, 120))
3104 				result = osst_recover_wait_frame(STp, aSRpnt, 1);
3105 
3106 		memset(cmd, 0, MAX_COMMAND_SIZE);
3107 		cmd[0] = WRITE_6;
3108 		cmd[1] = 1;
3109 		cmd[4] = 1;
3110 
3111 		switch	(STp->write_type) {
3112 		   case OS_WRITE_DATA:
3113 #if DEBUG
3114    			if (debugging)
3115 				printk(OSST_DEB_MSG "%s:D: Writing %d blocks to frame %d, lblks %d-%d\n",
3116 					name, blks, STp->frame_seq_number,
3117 					STp->logical_blk_num - blks, STp->logical_blk_num - 1);
3118 #endif
3119 			osst_init_aux(STp, OS_FRAME_TYPE_DATA, STp->frame_seq_number++,
3120 				      STp->logical_blk_num - blks, STp->block_size, blks);
3121 			break;
3122 		   case OS_WRITE_EOD:
3123 			osst_init_aux(STp, OS_FRAME_TYPE_EOD, STp->frame_seq_number++,
3124 				      STp->logical_blk_num, 0, 0);
3125 			break;
3126 		   case OS_WRITE_NEW_MARK:
3127 			osst_init_aux(STp, OS_FRAME_TYPE_MARKER, STp->frame_seq_number++,
3128 				      STp->logical_blk_num++, 0, blks=1);
3129 			break;
3130 		   case OS_WRITE_HEADER:
3131 			osst_init_aux(STp, OS_FRAME_TYPE_HEADER, 0, 0, 0, blks=0);
3132 			break;
3133 		default: /* probably FILLER */
3134 			osst_init_aux(STp, OS_FRAME_TYPE_FILL, 0, 0, 0, 0);
3135 		}
3136 #if DEBUG
3137 		if (debugging)
3138 			printk(OSST_DEB_MSG "%s:D: Flushing %d bytes, Transferring %d bytes in %d lblocks.\n",
3139 			  			 name, offset, transfer, blks);
3140 #endif
3141 
3142 		SRpnt = osst_do_scsi(*aSRpnt, STp, cmd, transfer, DMA_TO_DEVICE,
3143 					      STp->timeout, MAX_RETRIES, 1);
3144 		*aSRpnt = SRpnt;
3145 		if (!SRpnt)
3146 			return (-EBUSY);
3147 
3148 		if ((STp->buffer)->syscall_result != 0) {
3149 #if DEBUG
3150 			printk(OSST_DEB_MSG
3151 				"%s:D: write sense [0]=0x%02x [2]=%02x [12]=%02x [13]=%02x\n",
3152 				name, SRpnt->sense[0], SRpnt->sense[2],
3153 				SRpnt->sense[12], SRpnt->sense[13]);
3154 #endif
3155 			if ((SRpnt->sense[0] & 0x70) == 0x70 &&
3156 			    (SRpnt->sense[2] & 0x40) && /* FIXME - SC-30 drive doesn't assert EOM bit */
3157 			    (SRpnt->sense[2] & 0x0f) == NO_SENSE) {
3158 				STp->dirty = 0;
3159 				(STp->buffer)->buffer_bytes = 0;
3160 				result = (-ENOSPC);
3161 			}
3162 			else {
3163 				if (osst_write_error_recovery(STp, aSRpnt, 1)) {
3164 					printk(KERN_ERR "%s:E: Error on flush write.\n", name);
3165 					result = (-EIO);
3166 				}
3167 			}
3168 			STps->drv_block = (-1);		/* FIXME - even if write recovery succeeds? */
3169 		}
3170 		else {
3171 			STp->first_frame_position++;
3172 			STp->dirty = 0;
3173 			(STp->buffer)->buffer_bytes = 0;
3174 		}
3175 	}
3176 #if DEBUG
3177 	printk(OSST_DEB_MSG "%s:D: Exit flush write buffer with code %d\n", name, result);
3178 #endif
3179 	return result;
3180 }
3181 
3182 
3183 /* Flush the tape buffer. The tape will be positioned correctly unless
3184    seek_next is true. */
osst_flush_buffer(struct osst_tape * STp,struct osst_request ** aSRpnt,int seek_next)3185 static int osst_flush_buffer(struct osst_tape * STp, struct osst_request ** aSRpnt, int seek_next)
3186 {
3187 	struct st_partstat * STps;
3188 	int    backspace = 0, result = 0;
3189 #if DEBUG
3190 	char * name = tape_name(STp);
3191 #endif
3192 
3193 	/*
3194 	 * If there was a bus reset, block further access
3195 	 * to this device.
3196 	 */
3197 	if( STp->pos_unknown)
3198 		return (-EIO);
3199 
3200 	if (STp->ready != ST_READY)
3201 		return 0;
3202 
3203 	STps = &(STp->ps[STp->partition]);
3204 	if (STps->rw == ST_WRITING || STp->dirty) {	/* Writing */
3205 		STp->write_type = OS_WRITE_DATA;
3206 		return osst_flush_write_buffer(STp, aSRpnt);
3207 	}
3208 	if (STp->block_size == 0)
3209 		return 0;
3210 
3211 #if DEBUG
3212 	printk(OSST_DEB_MSG "%s:D: Reached flush (read) buffer\n", name);
3213 #endif
3214 
3215 	if (!STp->can_bsr) {
3216 		backspace = ((STp->buffer)->buffer_bytes + (STp->buffer)->read_pointer) / STp->block_size -
3217 			    ((STp->buffer)->read_pointer + STp->block_size - 1        ) / STp->block_size ;
3218 		(STp->buffer)->buffer_bytes = 0;
3219 		(STp->buffer)->read_pointer = 0;
3220 		STp->frame_in_buffer = 0;		/* FIXME is this relevant w. OSST? */
3221 	}
3222 
3223 	if (!seek_next) {
3224 		if (STps->eof == ST_FM_HIT) {
3225 			result = cross_eof(STp, aSRpnt, 0); /* Back over the EOF hit */
3226 			if (!result)
3227 				STps->eof = ST_NOEOF;
3228 			else {
3229 				if (STps->drv_file >= 0)
3230 					STps->drv_file++;
3231 				STps->drv_block = 0;
3232 			}
3233 		}
3234 		if (!result && backspace > 0)	/* TODO -- design and run a test case for this */
3235 			result = osst_seek_logical_blk(STp, aSRpnt, STp->logical_blk_num - backspace);
3236 	}
3237 	else if (STps->eof == ST_FM_HIT) {
3238 		if (STps->drv_file >= 0)
3239 			STps->drv_file++;
3240 		STps->drv_block = 0;
3241 		STps->eof = ST_NOEOF;
3242 	}
3243 
3244 	return result;
3245 }
3246 
osst_write_frame(struct osst_tape * STp,struct osst_request ** aSRpnt,int synchronous)3247 static int osst_write_frame(struct osst_tape * STp, struct osst_request ** aSRpnt, int synchronous)
3248 {
3249 	unsigned char		cmd[MAX_COMMAND_SIZE];
3250 	struct osst_request   * SRpnt;
3251 	int			blks;
3252 #if DEBUG
3253 	char		      * name = tape_name(STp);
3254 #endif
3255 
3256 	if ((!STp-> raw) && (STp->first_frame_position == 0xbae)) { /* _must_ preserve buffer! */
3257 #if DEBUG
3258 		printk(OSST_DEB_MSG "%s:D: Reaching config partition.\n", name);
3259 #endif
3260 		if (osst_flush_drive_buffer(STp, aSRpnt) < 0) {
3261 			return (-EIO);
3262 		}
3263 		/* error recovery may have bumped us past the header partition */
3264 		if (osst_get_frame_position(STp, aSRpnt) < 0xbb8) {
3265 #if DEBUG
3266 			printk(OSST_DEB_MSG "%s:D: Skipping over config partition.\n", name);
3267 #endif
3268 		osst_position_tape_and_confirm(STp, aSRpnt, 0xbb8);
3269 		}
3270 	}
3271 
3272 	if (STp->poll)
3273 		if (osst_wait_frame (STp, aSRpnt, STp->first_frame_position, -48, 120))
3274 			if (osst_recover_wait_frame(STp, aSRpnt, 1))
3275 				return (-EIO);
3276 
3277 //	osst_build_stats(STp, &SRpnt);
3278 
3279 	STp->ps[STp->partition].rw = ST_WRITING;
3280 	STp->write_type            = OS_WRITE_DATA;
3281 
3282 	memset(cmd, 0, MAX_COMMAND_SIZE);
3283 	cmd[0]   = WRITE_6;
3284 	cmd[1]   = 1;
3285 	cmd[4]   = 1;						/* one frame at a time... */
3286 	blks     = STp->buffer->buffer_bytes / STp->block_size;
3287 #if DEBUG
3288 	if (debugging)
3289 		printk(OSST_DEB_MSG "%s:D: Writing %d blocks to frame %d, lblks %d-%d\n", name, blks,
3290 			STp->frame_seq_number, STp->logical_blk_num - blks, STp->logical_blk_num - 1);
3291 #endif
3292 	osst_init_aux(STp, OS_FRAME_TYPE_DATA, STp->frame_seq_number++,
3293 		      STp->logical_blk_num - blks, STp->block_size, blks);
3294 
3295 #if DEBUG
3296 	if (!synchronous)
3297 		STp->write_pending = 1;
3298 #endif
3299 	SRpnt = osst_do_scsi(*aSRpnt, STp, cmd, OS_FRAME_SIZE, DMA_TO_DEVICE, STp->timeout,
3300 									MAX_RETRIES, synchronous);
3301 	if (!SRpnt)
3302 		return (-EBUSY);
3303 	*aSRpnt = SRpnt;
3304 
3305 	if (synchronous) {
3306 		if (STp->buffer->syscall_result != 0) {
3307 #if DEBUG
3308 			if (debugging)
3309 				printk(OSST_DEB_MSG "%s:D: Error on write:\n", name);
3310 #endif
3311 			if ((SRpnt->sense[0] & 0x70) == 0x70 &&
3312 			    (SRpnt->sense[2] & 0x40)) {
3313 				if ((SRpnt->sense[2] & 0x0f) == VOLUME_OVERFLOW)
3314 					return (-ENOSPC);
3315 			}
3316 			else {
3317 				if (osst_write_error_recovery(STp, aSRpnt, 1))
3318 					return (-EIO);
3319 			}
3320 		}
3321 		else
3322 			STp->first_frame_position++;
3323 	}
3324 
3325 	STp->write_count++;
3326 
3327 	return 0;
3328 }
3329 
3330 /* Lock or unlock the drive door. Don't use when struct osst_request allocated. */
do_door_lock(struct osst_tape * STp,int do_lock)3331 static int do_door_lock(struct osst_tape * STp, int do_lock)
3332 {
3333 	int retval;
3334 
3335 #if DEBUG
3336 	printk(OSST_DEB_MSG "%s:D: %socking drive door.\n", tape_name(STp), do_lock ? "L" : "Unl");
3337 #endif
3338 
3339 	retval = scsi_set_medium_removal(STp->device,
3340 			do_lock ? SCSI_REMOVAL_PREVENT : SCSI_REMOVAL_ALLOW);
3341 	if (!retval)
3342 		STp->door_locked = do_lock ? ST_LOCKED_EXPLICIT : ST_UNLOCKED;
3343 	else
3344 		STp->door_locked = ST_LOCK_FAILS;
3345 	return retval;
3346 }
3347 
3348 /* Set the internal state after reset */
reset_state(struct osst_tape * STp)3349 static void reset_state(struct osst_tape *STp)
3350 {
3351 	int i;
3352 	struct st_partstat *STps;
3353 
3354 	STp->pos_unknown = 0;
3355 	for (i = 0; i < ST_NBR_PARTITIONS; i++) {
3356 		STps = &(STp->ps[i]);
3357 		STps->rw = ST_IDLE;
3358 		STps->eof = ST_NOEOF;
3359 		STps->at_sm = 0;
3360 		STps->last_block_valid = 0;
3361 		STps->drv_block = -1;
3362 		STps->drv_file = -1;
3363 	}
3364 }
3365 
3366 
3367 /* Entry points to osst */
3368 
3369 /* Write command */
osst_write(struct file * filp,const char __user * buf,size_t count,loff_t * ppos)3370 static ssize_t osst_write(struct file * filp, const char __user * buf, size_t count, loff_t *ppos)
3371 {
3372 	ssize_t		      total, retval = 0;
3373 	ssize_t		      i, do_count, blks, transfer;
3374 	int		      write_threshold;
3375 	int		      doing_write = 0;
3376 	const char   __user * b_point;
3377 	struct osst_request * SRpnt = NULL;
3378 	struct st_modedef   * STm;
3379 	struct st_partstat  * STps;
3380 	struct osst_tape    * STp  = filp->private_data;
3381 	char		    * name = tape_name(STp);
3382 
3383 
3384 	if (mutex_lock_interruptible(&STp->lock))
3385 		return (-ERESTARTSYS);
3386 
3387 	/*
3388 	 * If we are in the middle of error recovery, don't let anyone
3389 	 * else try and use this device.  Also, if error recovery fails, it
3390 	 * may try and take the device offline, in which case all further
3391 	 * access to the device is prohibited.
3392 	 */
3393 	if( !scsi_block_when_processing_errors(STp->device) ) {
3394 		retval = (-ENXIO);
3395 		goto out;
3396 	}
3397 
3398 	if (STp->ready != ST_READY) {
3399 		if (STp->ready == ST_NO_TAPE)
3400 			retval = (-ENOMEDIUM);
3401 		else
3402 			retval = (-EIO);
3403 		goto out;
3404 	}
3405 	STm = &(STp->modes[STp->current_mode]);
3406 	if (!STm->defined) {
3407 		retval = (-ENXIO);
3408 		goto out;
3409 	}
3410 	if (count == 0)
3411 		goto out;
3412 
3413 	/*
3414 	 * If there was a bus reset, block further access
3415 	 * to this device.
3416 	 */
3417 	if (STp->pos_unknown) {
3418 		retval = (-EIO);
3419 		goto out;
3420 	}
3421 
3422 #if DEBUG
3423 	if (!STp->in_use) {
3424 		printk(OSST_DEB_MSG "%s:D: Incorrect device.\n", name);
3425 		retval = (-EIO);
3426 		goto out;
3427 	}
3428 #endif
3429 
3430 	if (STp->write_prot) {
3431 		retval = (-EACCES);
3432 		goto out;
3433 	}
3434 
3435 	/* Write must be integral number of blocks */
3436 	if (STp->block_size != 0 && (count % STp->block_size) != 0) {
3437 		printk(KERN_ERR "%s:E: Write (%zd bytes) not multiple of tape block size (%d%c).\n",
3438 				       name, count, STp->block_size<1024?
3439 				       STp->block_size:STp->block_size/1024, STp->block_size<1024?'b':'k');
3440 		retval = (-EINVAL);
3441 		goto out;
3442 	}
3443 
3444 	if (STp->first_frame_position >= STp->capacity - OSST_EOM_RESERVE) {
3445 		printk(KERN_ERR "%s:E: Write truncated at EOM early warning (frame %d).\n",
3446 				       name, STp->first_frame_position);
3447 		retval = (-ENOSPC);
3448 		goto out;
3449 	}
3450 
3451 	if (STp->do_auto_lock && STp->door_locked == ST_UNLOCKED && !do_door_lock(STp, 1))
3452 		STp->door_locked = ST_LOCKED_AUTO;
3453 
3454 	STps = &(STp->ps[STp->partition]);
3455 
3456 	if (STps->rw == ST_READING) {
3457 #if DEBUG
3458 		printk(OSST_DEB_MSG "%s:D: Switching from read to write at file %d, block %d\n", name,
3459 					STps->drv_file, STps->drv_block);
3460 #endif
3461 		retval = osst_flush_buffer(STp, &SRpnt, 0);
3462 		if (retval)
3463 			goto out;
3464 		STps->rw = ST_IDLE;
3465 	}
3466 	if (STps->rw != ST_WRITING) {
3467 		/* Are we totally rewriting this tape? */
3468 		if (!STp->header_ok ||
3469 		    (STp->first_frame_position == STp->first_data_ppos && STps->drv_block < 0) ||
3470 		    (STps->drv_file == 0 && STps->drv_block == 0)) {
3471 			STp->wrt_pass_cntr++;
3472 #if DEBUG
3473 			printk(OSST_DEB_MSG "%s:D: Allocating next write pass counter: %d\n",
3474 						  name, STp->wrt_pass_cntr);
3475 #endif
3476 			osst_reset_header(STp, &SRpnt);
3477 			STps->drv_file = STps->drv_block = 0;
3478 		}
3479 		/* Do we know where we'll be writing on the tape? */
3480 		else {
3481 			if ((STp->fast_open && osst_verify_position(STp, &SRpnt)) ||
3482 			  		STps->drv_file < 0 || STps->drv_block < 0) {
3483 				if (STp->first_frame_position == STp->eod_frame_ppos) {	/* at EOD */
3484 			  		STps->drv_file = STp->filemark_cnt;
3485 			  		STps->drv_block = 0;
3486 				}
3487 				else {
3488 					/* We have no idea where the tape is positioned - give up */
3489 #if DEBUG
3490 					printk(OSST_DEB_MSG
3491 						"%s:D: Cannot write at indeterminate position.\n", name);
3492 #endif
3493 					retval = (-EIO);
3494 					goto out;
3495 				}
3496       			}
3497 			if ((STps->drv_file + STps->drv_block) > 0 && STps->drv_file < STp->filemark_cnt) {
3498 				STp->filemark_cnt = STps->drv_file;
3499 				STp->last_mark_ppos =
3500 				       	ntohl(STp->header_cache->dat_fm_tab.fm_tab_ent[STp->filemark_cnt-1]);
3501 				printk(KERN_WARNING
3502 					"%s:W: Overwriting file %d with old write pass counter %d\n",
3503 						name, STps->drv_file, STp->wrt_pass_cntr);
3504 				printk(KERN_WARNING
3505 					"%s:W: may lead to stale data being accepted on reading back!\n",
3506 						name);
3507 #if DEBUG
3508 				printk(OSST_DEB_MSG
3509 				  "%s:D: resetting filemark count to %d and last mark ppos,lbn to %d,%d\n",
3510 					name, STp->filemark_cnt, STp->last_mark_ppos, STp->last_mark_lbn);
3511 #endif
3512 			}
3513 		}
3514 		STp->fast_open = 0;
3515 	}
3516 	if (!STp->header_ok) {
3517 #if DEBUG
3518 		printk(OSST_DEB_MSG "%s:D: Write cannot proceed without valid headers\n", name);
3519 #endif
3520 		retval = (-EIO);
3521 		goto out;
3522 	}
3523 
3524 	if ((STp->buffer)->writing) {
3525 if (SRpnt) printk(KERN_ERR "%s:A: Not supposed to have SRpnt at line %d\n", name, __LINE__);
3526 		osst_write_behind_check(STp);
3527 		if ((STp->buffer)->syscall_result) {
3528 #if DEBUG
3529 		if (debugging)
3530 			printk(OSST_DEB_MSG "%s:D: Async write error (write) %x.\n", name,
3531 						 (STp->buffer)->midlevel_result);
3532 #endif
3533 		if ((STp->buffer)->midlevel_result == INT_MAX)
3534 			STps->eof = ST_EOM_OK;
3535 		else
3536 			STps->eof = ST_EOM_ERROR;
3537 		}
3538 	}
3539 	if (STps->eof == ST_EOM_OK) {
3540 		retval = (-ENOSPC);
3541 		goto out;
3542 	}
3543 	else if (STps->eof == ST_EOM_ERROR) {
3544 		retval = (-EIO);
3545 		goto out;
3546 	}
3547 
3548 	/* Check the buffer readability in cases where copy_user might catch
3549 		 the problems after some tape movement. */
3550 	if ((copy_from_user(&i, buf, 1) != 0 ||
3551 	     copy_from_user(&i, buf + count - 1, 1) != 0)) {
3552 		retval = (-EFAULT);
3553 		goto out;
3554 	}
3555 
3556 	if (!STm->do_buffer_writes) {
3557 		write_threshold = 1;
3558 	}
3559 	else
3560 		write_threshold = (STp->buffer)->buffer_blocks * STp->block_size;
3561 	if (!STm->do_async_writes)
3562 		write_threshold--;
3563 
3564 	total = count;
3565 #if DEBUG
3566 	if (debugging)
3567 		printk(OSST_DEB_MSG "%s:D: Writing %d bytes to file %d block %d lblk %d fseq %d fppos %d\n",
3568 				name, (int) count, STps->drv_file, STps->drv_block,
3569 				STp->logical_blk_num, STp->frame_seq_number, STp->first_frame_position);
3570 #endif
3571 	b_point = buf;
3572 	while ((STp->buffer)->buffer_bytes + count > write_threshold)
3573 	{
3574 		doing_write = 1;
3575 		do_count = (STp->buffer)->buffer_blocks * STp->block_size -
3576 			   (STp->buffer)->buffer_bytes;
3577 		if (do_count > count)
3578 			do_count = count;
3579 
3580 		i = append_to_buffer(b_point, STp->buffer, do_count);
3581 		if (i) {
3582 			retval = i;
3583 			goto out;
3584 		}
3585 
3586 		blks = do_count / STp->block_size;
3587 		STp->logical_blk_num += blks;  /* logical_blk_num is incremented as data is moved from user */
3588 
3589 		i = osst_write_frame(STp, &SRpnt, 1);
3590 
3591 		if (i == (-ENOSPC)) {
3592 			transfer = STp->buffer->writing;	/* FIXME -- check this logic */
3593 			if (transfer <= do_count) {
3594 				*ppos += do_count - transfer;
3595 				count -= do_count - transfer;
3596 				if (STps->drv_block >= 0) {
3597 					STps->drv_block += (do_count - transfer) / STp->block_size;
3598 				}
3599 				STps->eof = ST_EOM_OK;
3600 				retval = (-ENOSPC);		/* EOM within current request */
3601 #if DEBUG
3602 				if (debugging)
3603 				      printk(OSST_DEB_MSG "%s:D: EOM with %d bytes unwritten.\n",
3604 							     name, (int) transfer);
3605 #endif
3606 			}
3607 			else {
3608 				STps->eof = ST_EOM_ERROR;
3609 				STps->drv_block = (-1);		/* Too cautious? */
3610 				retval = (-EIO);		/* EOM for old data */
3611 #if DEBUG
3612 				if (debugging)
3613 				      printk(OSST_DEB_MSG "%s:D: EOM with lost data.\n", name);
3614 #endif
3615 			}
3616 		}
3617 		else
3618 			retval = i;
3619 
3620 		if (retval < 0) {
3621 			if (SRpnt != NULL) {
3622 				osst_release_request(SRpnt);
3623 				SRpnt = NULL;
3624 			}
3625 			STp->buffer->buffer_bytes = 0;
3626 			STp->dirty = 0;
3627 			if (count < total)
3628 				retval = total - count;
3629 			goto out;
3630 		}
3631 
3632 		*ppos += do_count;
3633 		b_point += do_count;
3634 		count -= do_count;
3635 		if (STps->drv_block >= 0) {
3636 			STps->drv_block += blks;
3637 		}
3638 		STp->buffer->buffer_bytes = 0;
3639 		STp->dirty = 0;
3640 	}  /* end while write threshold exceeded */
3641 
3642 	if (count != 0) {
3643 		STp->dirty = 1;
3644 		i = append_to_buffer(b_point, STp->buffer, count);
3645 		if (i) {
3646 			retval = i;
3647 			goto out;
3648 		}
3649 		blks = count / STp->block_size;
3650 		STp->logical_blk_num += blks;
3651 		if (STps->drv_block >= 0) {
3652 			STps->drv_block += blks;
3653 		}
3654 		*ppos += count;
3655 		count = 0;
3656 	}
3657 
3658 	if (doing_write && (STp->buffer)->syscall_result != 0) {
3659 		retval = (STp->buffer)->syscall_result;
3660 		goto out;
3661 	}
3662 
3663 	if (STm->do_async_writes && ((STp->buffer)->buffer_bytes >= STp->write_threshold)) {
3664 		/* Schedule an asynchronous write */
3665 		(STp->buffer)->writing = ((STp->buffer)->buffer_bytes /
3666 					   STp->block_size) * STp->block_size;
3667 		STp->dirty = !((STp->buffer)->writing ==
3668 				          (STp->buffer)->buffer_bytes);
3669 
3670 		i = osst_write_frame(STp, &SRpnt, 0);
3671 		if (i < 0) {
3672 			retval = (-EIO);
3673 			goto out;
3674 		}
3675 		SRpnt = NULL;			/* Prevent releasing this request! */
3676 	}
3677 	STps->at_sm &= (total == 0);
3678 	if (total > 0)
3679 		STps->eof = ST_NOEOF;
3680 
3681 	retval = total;
3682 
3683 out:
3684 	if (SRpnt != NULL) osst_release_request(SRpnt);
3685 
3686 	mutex_unlock(&STp->lock);
3687 
3688 	return retval;
3689 }
3690 
3691 
3692 /* Read command */
osst_read(struct file * filp,char __user * buf,size_t count,loff_t * ppos)3693 static ssize_t osst_read(struct file * filp, char __user * buf, size_t count, loff_t *ppos)
3694 {
3695 	ssize_t		      total, retval = 0;
3696 	ssize_t		      i, transfer;
3697 	int		      special;
3698 	struct st_modedef   * STm;
3699 	struct st_partstat  * STps;
3700 	struct osst_request * SRpnt = NULL;
3701 	struct osst_tape    * STp   = filp->private_data;
3702 	char		    * name  = tape_name(STp);
3703 
3704 
3705 	if (mutex_lock_interruptible(&STp->lock))
3706 		return (-ERESTARTSYS);
3707 
3708 	/*
3709 	 * If we are in the middle of error recovery, don't let anyone
3710 	 * else try and use this device.  Also, if error recovery fails, it
3711 	 * may try and take the device offline, in which case all further
3712 	 * access to the device is prohibited.
3713 	 */
3714 	if( !scsi_block_when_processing_errors(STp->device) ) {
3715 		retval = (-ENXIO);
3716 		goto out;
3717 	}
3718 
3719 	if (STp->ready != ST_READY) {
3720 		if (STp->ready == ST_NO_TAPE)
3721 			retval = (-ENOMEDIUM);
3722 		else
3723 			retval = (-EIO);
3724 		goto out;
3725 	}
3726 	STm = &(STp->modes[STp->current_mode]);
3727 	if (!STm->defined) {
3728 		retval = (-ENXIO);
3729 		goto out;
3730 	}
3731 #if DEBUG
3732 	if (!STp->in_use) {
3733 		printk(OSST_DEB_MSG "%s:D: Incorrect device.\n", name);
3734 		retval = (-EIO);
3735 		goto out;
3736 	}
3737 #endif
3738 	/* Must have initialized medium */
3739 	if (!STp->header_ok) {
3740 		retval = (-EIO);
3741 		goto out;
3742 	}
3743 
3744 	if (STp->do_auto_lock && STp->door_locked == ST_UNLOCKED && !do_door_lock(STp, 1))
3745 		STp->door_locked = ST_LOCKED_AUTO;
3746 
3747 	STps = &(STp->ps[STp->partition]);
3748 	if (STps->rw == ST_WRITING) {
3749 		retval = osst_flush_buffer(STp, &SRpnt, 0);
3750 		if (retval)
3751 			goto out;
3752 		STps->rw = ST_IDLE;
3753 		/* FIXME -- this may leave the tape without EOD and up2date headers */
3754 	}
3755 
3756 	if ((count % STp->block_size) != 0) {
3757 		printk(KERN_WARNING
3758 		    "%s:W: Read (%zd bytes) not multiple of tape block size (%d%c).\n", name, count,
3759 		    STp->block_size<1024?STp->block_size:STp->block_size/1024, STp->block_size<1024?'b':'k');
3760 	}
3761 
3762 #if DEBUG
3763 	if (debugging && STps->eof != ST_NOEOF)
3764 		printk(OSST_DEB_MSG "%s:D: EOF/EOM flag up (%d). Bytes %d\n", name,
3765 				     STps->eof, (STp->buffer)->buffer_bytes);
3766 #endif
3767 	if ((STp->buffer)->buffer_bytes == 0 &&
3768 	     STps->eof >= ST_EOD_1) {
3769 		if (STps->eof < ST_EOD) {
3770 			STps->eof += 1;
3771 			retval = 0;
3772 			goto out;
3773 		}
3774 		retval = (-EIO);  /* EOM or Blank Check */
3775 		goto out;
3776 	}
3777 
3778 	/* Check the buffer writability before any tape movement. Don't alter
3779 		 buffer data. */
3780 	if (copy_from_user(&i, buf, 1)             != 0 ||
3781 	    copy_to_user  (buf, &i, 1)             != 0 ||
3782 	    copy_from_user(&i, buf + count - 1, 1) != 0 ||
3783 	    copy_to_user  (buf + count - 1, &i, 1) != 0) {
3784 		retval = (-EFAULT);
3785 		goto out;
3786 	}
3787 
3788 	/* Loop until enough data in buffer or a special condition found */
3789 	for (total = 0, special = 0; total < count - STp->block_size + 1 && !special; ) {
3790 
3791 		/* Get new data if the buffer is empty */
3792 		if ((STp->buffer)->buffer_bytes == 0) {
3793 			if (STps->eof == ST_FM_HIT)
3794 				break;
3795 			special = osst_get_logical_frame(STp, &SRpnt, STp->frame_seq_number, 0);
3796 			if (special < 0) { 			/* No need to continue read */
3797 				STp->frame_in_buffer = 0;
3798 				retval = special;
3799 				goto out;
3800 			}
3801 		}
3802 
3803 		/* Move the data from driver buffer to user buffer */
3804 		if ((STp->buffer)->buffer_bytes > 0) {
3805 #if DEBUG
3806 			if (debugging && STps->eof != ST_NOEOF)
3807 			    printk(OSST_DEB_MSG "%s:D: EOF up (%d). Left %d, needed %d.\n", name,
3808 						 STps->eof, (STp->buffer)->buffer_bytes, (int) (count - total));
3809 #endif
3810 		       	/* force multiple of block size, note block_size may have been adjusted */
3811 			transfer = (((STp->buffer)->buffer_bytes < count - total ?
3812 				     (STp->buffer)->buffer_bytes : count - total)/
3813 					STp->block_size) * STp->block_size;
3814 
3815 			if (transfer == 0) {
3816 				printk(KERN_WARNING
3817 				  "%s:W: Nothing can be transferred, requested %zd, tape block size (%d%c).\n",
3818 			   		name, count, STp->block_size < 1024?
3819 					STp->block_size:STp->block_size/1024,
3820 				       	STp->block_size<1024?'b':'k');
3821 				break;
3822 			}
3823 			i = from_buffer(STp->buffer, buf, transfer);
3824 			if (i)  {
3825 				retval = i;
3826 				goto out;
3827 			}
3828 			STp->logical_blk_num += transfer / STp->block_size;
3829 			STps->drv_block      += transfer / STp->block_size;
3830 			*ppos          += transfer;
3831 			buf                  += transfer;
3832 			total                += transfer;
3833 		}
3834 
3835 		if ((STp->buffer)->buffer_bytes == 0) {
3836 #if DEBUG
3837 			if (debugging)
3838 				printk(OSST_DEB_MSG "%s:D: Finished with frame %d\n",
3839 					       	name, STp->frame_seq_number);
3840 #endif
3841 			STp->frame_in_buffer = 0;
3842 			STp->frame_seq_number++;              /* frame to look for next time */
3843 		}
3844 	} /* for (total = 0, special = 0; total < count && !special; ) */
3845 
3846 	/* Change the eof state if no data from tape or buffer */
3847 	if (total == 0) {
3848 		if (STps->eof == ST_FM_HIT) {
3849 			STps->eof = (STp->first_frame_position >= STp->eod_frame_ppos)?ST_EOD_2:ST_FM;
3850 			STps->drv_block = 0;
3851 			if (STps->drv_file >= 0)
3852 				STps->drv_file++;
3853 		}
3854 		else if (STps->eof == ST_EOD_1) {
3855 			STps->eof = ST_EOD_2;
3856 			if (STps->drv_block > 0 && STps->drv_file >= 0)
3857 				STps->drv_file++;
3858 			STps->drv_block = 0;
3859 		}
3860 		else if (STps->eof == ST_EOD_2)
3861 			STps->eof = ST_EOD;
3862 	}
3863 	else if (STps->eof == ST_FM)
3864 		STps->eof = ST_NOEOF;
3865 
3866 	retval = total;
3867 
3868 out:
3869 	if (SRpnt != NULL) osst_release_request(SRpnt);
3870 
3871 	mutex_unlock(&STp->lock);
3872 
3873 	return retval;
3874 }
3875 
3876 
3877 /* Set the driver options */
osst_log_options(struct osst_tape * STp,struct st_modedef * STm,char * name)3878 static void osst_log_options(struct osst_tape *STp, struct st_modedef *STm, char *name)
3879 {
3880   printk(KERN_INFO
3881 "%s:I: Mode %d options: buffer writes: %d, async writes: %d, read ahead: %d\n",
3882 	 name, STp->current_mode, STm->do_buffer_writes, STm->do_async_writes,
3883 	 STm->do_read_ahead);
3884   printk(KERN_INFO
3885 "%s:I:    can bsr: %d, two FMs: %d, fast mteom: %d, auto lock: %d,\n",
3886 	 name, STp->can_bsr, STp->two_fm, STp->fast_mteom, STp->do_auto_lock);
3887   printk(KERN_INFO
3888 "%s:I:    defs for wr: %d, no block limits: %d, partitions: %d, s2 log: %d\n",
3889 	 name, STm->defaults_for_writes, STp->omit_blklims, STp->can_partitions,
3890 	 STp->scsi2_logical);
3891   printk(KERN_INFO
3892 "%s:I:    sysv: %d\n", name, STm->sysv);
3893 #if DEBUG
3894   printk(KERN_INFO
3895 	 "%s:D:    debugging: %d\n",
3896 	 name, debugging);
3897 #endif
3898 }
3899 
3900 
osst_set_options(struct osst_tape * STp,long options)3901 static int osst_set_options(struct osst_tape *STp, long options)
3902 {
3903 	int		    value;
3904 	long		    code;
3905 	struct st_modedef * STm;
3906 	char		  * name = tape_name(STp);
3907 
3908 	STm = &(STp->modes[STp->current_mode]);
3909 	if (!STm->defined) {
3910 		memcpy(STm, &(STp->modes[0]), sizeof(*STm));
3911 		modes_defined = 1;
3912 #if DEBUG
3913 		if (debugging)
3914 			printk(OSST_DEB_MSG "%s:D: Initialized mode %d definition from mode 0\n",
3915 					     name, STp->current_mode);
3916 #endif
3917 	}
3918 
3919 	code = options & MT_ST_OPTIONS;
3920 	if (code == MT_ST_BOOLEANS) {
3921 		STm->do_buffer_writes = (options & MT_ST_BUFFER_WRITES) != 0;
3922 		STm->do_async_writes  = (options & MT_ST_ASYNC_WRITES) != 0;
3923 		STm->defaults_for_writes = (options & MT_ST_DEF_WRITES) != 0;
3924 		STm->do_read_ahead    = (options & MT_ST_READ_AHEAD) != 0;
3925 		STp->two_fm	      = (options & MT_ST_TWO_FM) != 0;
3926 		STp->fast_mteom	      = (options & MT_ST_FAST_MTEOM) != 0;
3927 		STp->do_auto_lock     = (options & MT_ST_AUTO_LOCK) != 0;
3928 		STp->can_bsr          = (options & MT_ST_CAN_BSR) != 0;
3929 		STp->omit_blklims     = (options & MT_ST_NO_BLKLIMS) != 0;
3930 		if ((STp->device)->scsi_level >= SCSI_2)
3931 			STp->can_partitions = (options & MT_ST_CAN_PARTITIONS) != 0;
3932 		STp->scsi2_logical    = (options & MT_ST_SCSI2LOGICAL) != 0;
3933 		STm->sysv	      = (options & MT_ST_SYSV) != 0;
3934 #if DEBUG
3935 		debugging = (options & MT_ST_DEBUGGING) != 0;
3936 #endif
3937 		osst_log_options(STp, STm, name);
3938 	}
3939 	else if (code == MT_ST_SETBOOLEANS || code == MT_ST_CLEARBOOLEANS) {
3940 		value = (code == MT_ST_SETBOOLEANS);
3941 		if ((options & MT_ST_BUFFER_WRITES) != 0)
3942 			STm->do_buffer_writes = value;
3943 		if ((options & MT_ST_ASYNC_WRITES) != 0)
3944 			STm->do_async_writes = value;
3945 		if ((options & MT_ST_DEF_WRITES) != 0)
3946 			STm->defaults_for_writes = value;
3947 		if ((options & MT_ST_READ_AHEAD) != 0)
3948 			STm->do_read_ahead = value;
3949 		if ((options & MT_ST_TWO_FM) != 0)
3950 			STp->two_fm = value;
3951 		if ((options & MT_ST_FAST_MTEOM) != 0)
3952 			STp->fast_mteom = value;
3953 		if ((options & MT_ST_AUTO_LOCK) != 0)
3954 			STp->do_auto_lock = value;
3955 		if ((options & MT_ST_CAN_BSR) != 0)
3956 			STp->can_bsr = value;
3957 		if ((options & MT_ST_NO_BLKLIMS) != 0)
3958 			STp->omit_blklims = value;
3959 		if ((STp->device)->scsi_level >= SCSI_2 &&
3960 		    (options & MT_ST_CAN_PARTITIONS) != 0)
3961 			STp->can_partitions = value;
3962 		if ((options & MT_ST_SCSI2LOGICAL) != 0)
3963 			STp->scsi2_logical = value;
3964 		if ((options & MT_ST_SYSV) != 0)
3965 			STm->sysv = value;
3966 #if DEBUG
3967 		if ((options & MT_ST_DEBUGGING) != 0)
3968 			debugging = value;
3969 #endif
3970 		osst_log_options(STp, STm, name);
3971 	}
3972 	else if (code == MT_ST_WRITE_THRESHOLD) {
3973 		value = (options & ~MT_ST_OPTIONS) * ST_KILOBYTE;
3974 		if (value < 1 || value > osst_buffer_size) {
3975 			printk(KERN_WARNING "%s:W: Write threshold %d too small or too large.\n",
3976 					     name, value);
3977 			return (-EIO);
3978 		}
3979 		STp->write_threshold = value;
3980 		printk(KERN_INFO "%s:I: Write threshold set to %d bytes.\n",
3981 				  name, value);
3982 	}
3983 	else if (code == MT_ST_DEF_BLKSIZE) {
3984 		value = (options & ~MT_ST_OPTIONS);
3985 		if (value == ~MT_ST_OPTIONS) {
3986 			STm->default_blksize = (-1);
3987 			printk(KERN_INFO "%s:I: Default block size disabled.\n", name);
3988 		}
3989 		else {
3990 			if (value < 512 || value > OS_DATA_SIZE || OS_DATA_SIZE % value) {
3991 				printk(KERN_WARNING "%s:W: Default block size cannot be set to %d.\n",
3992 							 name, value);
3993 				return (-EINVAL);
3994 			}
3995 			STm->default_blksize = value;
3996 			printk(KERN_INFO "%s:I: Default block size set to %d bytes.\n",
3997 					  name, STm->default_blksize);
3998 		}
3999 	}
4000 	else if (code == MT_ST_TIMEOUTS) {
4001 		value = (options & ~MT_ST_OPTIONS);
4002 		if ((value & MT_ST_SET_LONG_TIMEOUT) != 0) {
4003 			STp->long_timeout = (value & ~MT_ST_SET_LONG_TIMEOUT) * HZ;
4004 			printk(KERN_INFO "%s:I: Long timeout set to %d seconds.\n", name,
4005 					     (value & ~MT_ST_SET_LONG_TIMEOUT));
4006 		}
4007 		else {
4008 			STp->timeout = value * HZ;
4009 			printk(KERN_INFO "%s:I: Normal timeout set to %d seconds.\n", name, value);
4010 		}
4011 	}
4012 	else if (code == MT_ST_DEF_OPTIONS) {
4013 		code = (options & ~MT_ST_CLEAR_DEFAULT);
4014 		value = (options & MT_ST_CLEAR_DEFAULT);
4015 		if (code == MT_ST_DEF_DENSITY) {
4016 			if (value == MT_ST_CLEAR_DEFAULT) {
4017 				STm->default_density = (-1);
4018 				printk(KERN_INFO "%s:I: Density default disabled.\n", name);
4019 			}
4020 			else {
4021 				STm->default_density = value & 0xff;
4022 				printk(KERN_INFO "%s:I: Density default set to %x\n",
4023 						  name, STm->default_density);
4024 			}
4025 		}
4026 		else if (code == MT_ST_DEF_DRVBUFFER) {
4027 			if (value == MT_ST_CLEAR_DEFAULT) {
4028 				STp->default_drvbuffer = 0xff;
4029 				printk(KERN_INFO "%s:I: Drive buffer default disabled.\n", name);
4030 			}
4031 			else {
4032 				STp->default_drvbuffer = value & 7;
4033 				printk(KERN_INFO "%s:I: Drive buffer default set to %x\n",
4034 						  name, STp->default_drvbuffer);
4035 			}
4036 		}
4037 		else if (code == MT_ST_DEF_COMPRESSION) {
4038 			if (value == MT_ST_CLEAR_DEFAULT) {
4039 				STm->default_compression = ST_DONT_TOUCH;
4040 				printk(KERN_INFO "%s:I: Compression default disabled.\n", name);
4041 			}
4042 			else {
4043 				STm->default_compression = (value & 1 ? ST_YES : ST_NO);
4044 				printk(KERN_INFO "%s:I: Compression default set to %x\n",
4045 						  name, (value & 1));
4046 			}
4047 		}
4048 	}
4049 	else
4050 		return (-EIO);
4051 
4052 	return 0;
4053 }
4054 
4055 
4056 /* Internal ioctl function */
osst_int_ioctl(struct osst_tape * STp,struct osst_request ** aSRpnt,unsigned int cmd_in,unsigned long arg)4057 static int osst_int_ioctl(struct osst_tape * STp, struct osst_request ** aSRpnt,
4058 			     unsigned int cmd_in, unsigned long arg)
4059 {
4060 	int			timeout;
4061 	long			ltmp;
4062 	int			i, ioctl_result;
4063 	int			chg_eof = 1;
4064 	unsigned char		cmd[MAX_COMMAND_SIZE];
4065 	struct osst_request   * SRpnt = * aSRpnt;
4066 	struct st_partstat    * STps;
4067 	int			fileno, blkno, at_sm, frame_seq_numbr, logical_blk_num;
4068 	int			datalen = 0, direction = DMA_NONE;
4069 	char		      * name = tape_name(STp);
4070 
4071 	if (STp->ready != ST_READY && cmd_in != MTLOAD) {
4072 		if (STp->ready == ST_NO_TAPE)
4073 			return (-ENOMEDIUM);
4074 		else
4075 			return (-EIO);
4076 	}
4077 	timeout = STp->long_timeout;
4078 	STps = &(STp->ps[STp->partition]);
4079 	fileno = STps->drv_file;
4080 	blkno = STps->drv_block;
4081 	at_sm = STps->at_sm;
4082 	frame_seq_numbr = STp->frame_seq_number;
4083 	logical_blk_num = STp->logical_blk_num;
4084 
4085 	memset(cmd, 0, MAX_COMMAND_SIZE);
4086 	switch (cmd_in) {
4087 	 case MTFSFM:
4088 		chg_eof = 0; /* Changed from the FSF after this */
4089 	 case MTFSF:
4090 		if (STp->raw)
4091 		   return (-EIO);
4092 		if (STp->linux_media)
4093 		   ioctl_result = osst_space_over_filemarks_forward_fast(STp, &SRpnt, cmd_in, arg);
4094 		else
4095 		   ioctl_result = osst_space_over_filemarks_forward_slow(STp, &SRpnt, cmd_in, arg);
4096 		if (fileno >= 0)
4097 		   fileno += arg;
4098 		blkno = 0;
4099 		at_sm &= (arg == 0);
4100 		goto os_bypass;
4101 
4102 	 case MTBSF:
4103 		chg_eof = 0; /* Changed from the FSF after this */
4104 	 case MTBSFM:
4105 		if (STp->raw)
4106 		   return (-EIO);
4107 		ioctl_result = osst_space_over_filemarks_backward(STp, &SRpnt, cmd_in, arg);
4108 		if (fileno >= 0)
4109 		   fileno -= arg;
4110 		blkno = (-1);  /* We can't know the block number */
4111 		at_sm &= (arg == 0);
4112 		goto os_bypass;
4113 
4114 	 case MTFSR:
4115 	 case MTBSR:
4116 #if DEBUG
4117 		if (debugging)
4118 		   printk(OSST_DEB_MSG "%s:D: Skipping %lu blocks %s from logical block %d\n",
4119 				name, arg, cmd_in==MTFSR?"forward":"backward", logical_blk_num);
4120 #endif
4121 		if (cmd_in == MTFSR) {
4122 		   logical_blk_num += arg;
4123 		   if (blkno >= 0) blkno += arg;
4124 		}
4125 		else {
4126 		   logical_blk_num -= arg;
4127 		   if (blkno >= 0) blkno -= arg;
4128 		}
4129 		ioctl_result = osst_seek_logical_blk(STp, &SRpnt, logical_blk_num);
4130 		fileno = STps->drv_file;
4131 		blkno  = STps->drv_block;
4132 		at_sm &= (arg == 0);
4133 		goto os_bypass;
4134 
4135 	 case MTFSS:
4136 		cmd[0] = SPACE;
4137 		cmd[1] = 0x04; /* Space Setmarks */   /* FIXME -- OS can't do this? */
4138 		cmd[2] = (arg >> 16);
4139 		cmd[3] = (arg >> 8);
4140 		cmd[4] = arg;
4141 #if DEBUG
4142 		if (debugging)
4143 			printk(OSST_DEB_MSG "%s:D: Spacing tape forward %d setmarks.\n", name,
4144 		cmd[2] * 65536 + cmd[3] * 256 + cmd[4]);
4145 #endif
4146 		if (arg != 0) {
4147 			blkno = fileno = (-1);
4148 			at_sm = 1;
4149 		}
4150 		break;
4151 	 case MTBSS:
4152 		cmd[0] = SPACE;
4153 		cmd[1] = 0x04; /* Space Setmarks */   /* FIXME -- OS can't do this? */
4154 		ltmp = (-arg);
4155 		cmd[2] = (ltmp >> 16);
4156 		cmd[3] = (ltmp >> 8);
4157 		cmd[4] = ltmp;
4158 #if DEBUG
4159 		if (debugging) {
4160 			if (cmd[2] & 0x80)
4161 			   ltmp = 0xff000000;
4162 			ltmp = ltmp | (cmd[2] << 16) | (cmd[3] << 8) | cmd[4];
4163 			printk(OSST_DEB_MSG "%s:D: Spacing tape backward %ld setmarks.\n",
4164 						name, (-ltmp));
4165 		 }
4166 #endif
4167 		 if (arg != 0) {
4168 			blkno = fileno = (-1);
4169 			at_sm = 1;
4170 		 }
4171 		 break;
4172 	 case MTWEOF:
4173 		 if ((STps->rw == ST_WRITING || STp->dirty) && !STp->pos_unknown) {
4174 			STp->write_type = OS_WRITE_DATA;
4175 			ioctl_result = osst_flush_write_buffer(STp, &SRpnt);
4176 		 } else
4177 			ioctl_result = 0;
4178 #if DEBUG
4179 		 if (debugging)
4180 			   printk(OSST_DEB_MSG "%s:D: Writing %ld filemark(s).\n", name, arg);
4181 #endif
4182 		 for (i=0; i<arg; i++)
4183 			ioctl_result |= osst_write_filemark(STp, &SRpnt);
4184 		 if (fileno >= 0) fileno += arg;
4185 		 if (blkno  >= 0) blkno   = 0;
4186 		 goto os_bypass;
4187 
4188 	 case MTWSM:
4189 		 if (STp->write_prot)
4190 			return (-EACCES);
4191 		 if (!STp->raw)
4192 			return 0;
4193 		 cmd[0] = WRITE_FILEMARKS;   /* FIXME -- need OS version */
4194 		 if (cmd_in == MTWSM)
4195 			 cmd[1] = 2;
4196 		 cmd[2] = (arg >> 16);
4197 		 cmd[3] = (arg >> 8);
4198 		 cmd[4] = arg;
4199 		 timeout = STp->timeout;
4200 #if DEBUG
4201 		 if (debugging)
4202 			   printk(OSST_DEB_MSG "%s:D: Writing %d setmark(s).\n", name,
4203 				  cmd[2] * 65536 + cmd[3] * 256 + cmd[4]);
4204 #endif
4205 		 if (fileno >= 0)
4206 			fileno += arg;
4207 		 blkno = 0;
4208 		 at_sm = (cmd_in == MTWSM);
4209 		 break;
4210 	 case MTOFFL:
4211 	 case MTLOAD:
4212 	 case MTUNLOAD:
4213 	 case MTRETEN:
4214 		 cmd[0] = START_STOP;
4215 		 cmd[1] = 1;			/* Don't wait for completion */
4216 		 if (cmd_in == MTLOAD) {
4217 		     if (STp->ready == ST_NO_TAPE)
4218 			 cmd[4] = 4;		/* open tray */
4219 		      else
4220 			 cmd[4] = 1;		/* load */
4221 		 }
4222 		 if (cmd_in == MTRETEN)
4223 			 cmd[4] = 3;		/* retension then mount */
4224 		 if (cmd_in == MTOFFL)
4225 			 cmd[4] = 4;		/* rewind then eject */
4226 		 timeout = STp->timeout;
4227 #if DEBUG
4228 		 if (debugging) {
4229 			 switch (cmd_in) {
4230 				 case MTUNLOAD:
4231 					 printk(OSST_DEB_MSG "%s:D: Unloading tape.\n", name);
4232 					 break;
4233 				 case MTLOAD:
4234 					 printk(OSST_DEB_MSG "%s:D: Loading tape.\n", name);
4235 					 break;
4236 				 case MTRETEN:
4237 					 printk(OSST_DEB_MSG "%s:D: Retensioning tape.\n", name);
4238 					 break;
4239 				 case MTOFFL:
4240 					 printk(OSST_DEB_MSG "%s:D: Ejecting tape.\n", name);
4241 					 break;
4242 			 }
4243 		 }
4244 #endif
4245        fileno = blkno = at_sm = frame_seq_numbr = logical_blk_num = 0 ;
4246 		 break;
4247 	 case MTNOP:
4248 #if DEBUG
4249 		 if (debugging)
4250 			 printk(OSST_DEB_MSG "%s:D: No-op on tape.\n", name);
4251 #endif
4252 		 return 0;  /* Should do something ? */
4253 		 break;
4254 	 case MTEOM:
4255 #if DEBUG
4256 		if (debugging)
4257 		   printk(OSST_DEB_MSG "%s:D: Spacing to end of recorded medium.\n", name);
4258 #endif
4259 		if ((osst_position_tape_and_confirm(STp, &SRpnt, STp->eod_frame_ppos) < 0) ||
4260 			    (osst_get_logical_frame(STp, &SRpnt, -1, 0)               < 0)) {
4261 		   ioctl_result = -EIO;
4262 		   goto os_bypass;
4263 		}
4264 		if (STp->buffer->aux->frame_type != OS_FRAME_TYPE_EOD) {
4265 #if DEBUG
4266 		   printk(OSST_DEB_MSG "%s:D: No EOD frame found where expected.\n", name);
4267 #endif
4268 		   ioctl_result = -EIO;
4269 		   goto os_bypass;
4270 		}
4271 		ioctl_result = osst_set_frame_position(STp, &SRpnt, STp->eod_frame_ppos, 0);
4272 		fileno = STp->filemark_cnt;
4273 		blkno  = at_sm = 0;
4274 		goto os_bypass;
4275 
4276 	 case MTERASE:
4277 		if (STp->write_prot)
4278 		   return (-EACCES);
4279 		ioctl_result = osst_reset_header(STp, &SRpnt);
4280 		i = osst_write_eod(STp, &SRpnt);
4281 		if (i < ioctl_result) ioctl_result = i;
4282 		i = osst_position_tape_and_confirm(STp, &SRpnt, STp->eod_frame_ppos);
4283 		if (i < ioctl_result) ioctl_result = i;
4284 		fileno = blkno = at_sm = 0 ;
4285 		goto os_bypass;
4286 
4287 	 case MTREW:
4288 		cmd[0] = REZERO_UNIT; /* rewind */
4289 		cmd[1] = 1;
4290 #if DEBUG
4291 		if (debugging)
4292 		   printk(OSST_DEB_MSG "%s:D: Rewinding tape, Immed=%d.\n", name, cmd[1]);
4293 #endif
4294 		fileno = blkno = at_sm = frame_seq_numbr = logical_blk_num = 0 ;
4295 		break;
4296 
4297 	 case MTSETBLK:           /* Set block length */
4298 		 if ((STps->drv_block == 0 )			  &&
4299 		     !STp->dirty				  &&
4300 		     ((STp->buffer)->buffer_bytes == 0)		  &&
4301 		     ((arg & MT_ST_BLKSIZE_MASK) >= 512 )	  &&
4302 		     ((arg & MT_ST_BLKSIZE_MASK) <= OS_DATA_SIZE) &&
4303 		     !(OS_DATA_SIZE % (arg & MT_ST_BLKSIZE_MASK))  ) {
4304 			 /*
4305 			  * Only allowed to change the block size if you opened the
4306 			  * device at the beginning of a file before writing anything.
4307 			  * Note, that when reading, changing block_size is futile,
4308 			  * as the size used when writing overrides it.
4309 			  */
4310 			 STp->block_size = (arg & MT_ST_BLKSIZE_MASK);
4311 			 printk(KERN_INFO "%s:I: Block size set to %d bytes.\n",
4312 					   name, STp->block_size);
4313 			 return 0;
4314 		 }
4315 	 case MTSETDENSITY:       /* Set tape density */
4316 	 case MTSETDRVBUFFER:     /* Set drive buffering */
4317 	 case SET_DENS_AND_BLK:   /* Set density and block size */
4318 		 chg_eof = 0;
4319 		 if (STp->dirty || (STp->buffer)->buffer_bytes != 0)
4320 			 return (-EIO);       /* Not allowed if data in buffer */
4321 		 if ((cmd_in == MTSETBLK || cmd_in == SET_DENS_AND_BLK) &&
4322 		     (arg & MT_ST_BLKSIZE_MASK) != 0                    &&
4323 		     (arg & MT_ST_BLKSIZE_MASK) != STp->block_size       ) {
4324 			 printk(KERN_WARNING "%s:W: Illegal to set block size to %d%s.\n",
4325 						name, (int)(arg & MT_ST_BLKSIZE_MASK),
4326 						(OS_DATA_SIZE % (arg & MT_ST_BLKSIZE_MASK))?"":" now");
4327 			 return (-EINVAL);
4328 		 }
4329 		 return 0;  /* FIXME silently ignore if block size didn't change */
4330 
4331 	 default:
4332 		return (-ENOSYS);
4333 	}
4334 
4335 	SRpnt = osst_do_scsi(SRpnt, STp, cmd, datalen, direction, timeout, MAX_RETRIES, 1);
4336 
4337 	ioctl_result = (STp->buffer)->syscall_result;
4338 
4339 	if (!SRpnt) {
4340 #if DEBUG
4341 		printk(OSST_DEB_MSG "%s:D: Couldn't exec scsi cmd for IOCTL\n", name);
4342 #endif
4343 		return ioctl_result;
4344 	}
4345 
4346 	if (!ioctl_result) {  /* SCSI command successful */
4347 		STp->frame_seq_number = frame_seq_numbr;
4348 		STp->logical_blk_num  = logical_blk_num;
4349 	}
4350 
4351 os_bypass:
4352 #if DEBUG
4353 	if (debugging)
4354 		printk(OSST_DEB_MSG "%s:D: IOCTL (%d) Result=%d\n", name, cmd_in, ioctl_result);
4355 #endif
4356 
4357 	if (!ioctl_result) {				/* success */
4358 
4359 		if (cmd_in == MTFSFM) {
4360 			 fileno--;
4361 			 blkno--;
4362 		}
4363 		if (cmd_in == MTBSFM) {
4364 			 fileno++;
4365 			 blkno++;
4366 		}
4367 		STps->drv_block = blkno;
4368 		STps->drv_file = fileno;
4369 		STps->at_sm = at_sm;
4370 
4371 		if (cmd_in == MTEOM)
4372 			STps->eof = ST_EOD;
4373 		else if ((cmd_in == MTFSFM || cmd_in == MTBSF) && STps->eof == ST_FM_HIT) {
4374 			ioctl_result = osst_seek_logical_blk(STp, &SRpnt, STp->logical_blk_num-1);
4375 			STps->drv_block++;
4376 			STp->logical_blk_num++;
4377 			STp->frame_seq_number++;
4378 			STp->frame_in_buffer = 0;
4379 			STp->buffer->read_pointer = 0;
4380 		}
4381 		else if (cmd_in == MTFSF)
4382 			STps->eof = (STp->first_frame_position >= STp->eod_frame_ppos)?ST_EOD:ST_FM;
4383 		else if (chg_eof)
4384 			STps->eof = ST_NOEOF;
4385 
4386 		if (cmd_in == MTOFFL || cmd_in == MTUNLOAD)
4387 			STp->rew_at_close = 0;
4388 		else if (cmd_in == MTLOAD) {
4389 			for (i=0; i < ST_NBR_PARTITIONS; i++) {
4390 			    STp->ps[i].rw = ST_IDLE;
4391 			    STp->ps[i].last_block_valid = 0;/* FIXME - where else is this field maintained? */
4392 			}
4393 			STp->partition = 0;
4394 		}
4395 
4396 		if (cmd_in == MTREW) {
4397 			ioctl_result = osst_position_tape_and_confirm(STp, &SRpnt, STp->first_data_ppos);
4398 			if (ioctl_result > 0)
4399 				ioctl_result = 0;
4400 		}
4401 
4402 	} else if (cmd_in == MTBSF || cmd_in == MTBSFM ) {
4403 		if (osst_position_tape_and_confirm(STp, &SRpnt, STp->first_data_ppos) < 0)
4404 			STps->drv_file = STps->drv_block = -1;
4405 		else
4406 			STps->drv_file = STps->drv_block = 0;
4407 		STps->eof = ST_NOEOF;
4408 	} else if (cmd_in == MTFSF || cmd_in == MTFSFM) {
4409 		if (osst_position_tape_and_confirm(STp, &SRpnt, STp->eod_frame_ppos) < 0)
4410 			STps->drv_file = STps->drv_block = -1;
4411 		else {
4412 			STps->drv_file  = STp->filemark_cnt;
4413 			STps->drv_block = 0;
4414 		}
4415 		STps->eof = ST_EOD;
4416 	} else if (cmd_in == MTBSR || cmd_in == MTFSR || cmd_in == MTWEOF || cmd_in == MTEOM) {
4417 		STps->drv_file = STps->drv_block = (-1);
4418 		STps->eof = ST_NOEOF;
4419 		STp->header_ok = 0;
4420 	} else if (cmd_in == MTERASE) {
4421 		STp->header_ok = 0;
4422 	} else if (SRpnt) {  /* SCSI command was not completely successful. */
4423 		if (SRpnt->sense[2] & 0x40) {
4424 			STps->eof = ST_EOM_OK;
4425 			STps->drv_block = 0;
4426 		}
4427 		if (chg_eof)
4428 			STps->eof = ST_NOEOF;
4429 
4430 		if ((SRpnt->sense[2] & 0x0f) == BLANK_CHECK)
4431 			STps->eof = ST_EOD;
4432 
4433 		if (cmd_in == MTLOAD && osst_wait_for_medium(STp, &SRpnt, 60))
4434 			ioctl_result = osst_wait_ready(STp, &SRpnt, 5 * 60, OSST_WAIT_POSITION_COMPLETE);
4435 	}
4436 	*aSRpnt = SRpnt;
4437 
4438 	return ioctl_result;
4439 }
4440 
4441 
4442 /* Open the device */
__os_scsi_tape_open(struct inode * inode,struct file * filp)4443 static int __os_scsi_tape_open(struct inode * inode, struct file * filp)
4444 {
4445 	unsigned short	      flags;
4446 	int		      i, b_size, new_session = 0, retval = 0;
4447 	unsigned char	      cmd[MAX_COMMAND_SIZE];
4448 	struct osst_request * SRpnt = NULL;
4449 	struct osst_tape    * STp;
4450 	struct st_modedef   * STm;
4451 	struct st_partstat  * STps;
4452 	char		    * name;
4453 	int		      dev  = TAPE_NR(inode);
4454 	int		      mode = TAPE_MODE(inode);
4455 
4456 	/*
4457 	 * We really want to do nonseekable_open(inode, filp); here, but some
4458 	 * versions of tar incorrectly call lseek on tapes and bail out if that
4459 	 * fails.  So we disallow pread() and pwrite(), but permit lseeks.
4460 	 */
4461 	filp->f_mode &= ~(FMODE_PREAD | FMODE_PWRITE);
4462 
4463 	write_lock(&os_scsi_tapes_lock);
4464 	if (dev >= osst_max_dev || os_scsi_tapes == NULL ||
4465 	    (STp = os_scsi_tapes[dev]) == NULL || !STp->device) {
4466 		write_unlock(&os_scsi_tapes_lock);
4467 		return (-ENXIO);
4468 	}
4469 
4470 	name = tape_name(STp);
4471 
4472 	if (STp->in_use) {
4473 		write_unlock(&os_scsi_tapes_lock);
4474 #if DEBUG
4475 		printk(OSST_DEB_MSG "%s:D: Device already in use.\n", name);
4476 #endif
4477 		return (-EBUSY);
4478 	}
4479 	if (scsi_device_get(STp->device)) {
4480 		write_unlock(&os_scsi_tapes_lock);
4481 #if DEBUG
4482                 printk(OSST_DEB_MSG "%s:D: Failed scsi_device_get.\n", name);
4483 #endif
4484 		return (-ENXIO);
4485 	}
4486 	filp->private_data = STp;
4487 	STp->in_use = 1;
4488 	write_unlock(&os_scsi_tapes_lock);
4489 	STp->rew_at_close = TAPE_REWIND(inode);
4490 
4491 	if( !scsi_block_when_processing_errors(STp->device) ) {
4492 		return -ENXIO;
4493 	}
4494 
4495 	if (mode != STp->current_mode) {
4496 #if DEBUG
4497 		if (debugging)
4498 			printk(OSST_DEB_MSG "%s:D: Mode change from %d to %d.\n",
4499 					       name, STp->current_mode, mode);
4500 #endif
4501 		new_session = 1;
4502 		STp->current_mode = mode;
4503 	}
4504 	STm = &(STp->modes[STp->current_mode]);
4505 
4506 	flags = filp->f_flags;
4507 	STp->write_prot = ((flags & O_ACCMODE) == O_RDONLY);
4508 
4509 	STp->raw = TAPE_IS_RAW(inode);
4510 	if (STp->raw)
4511 		STp->header_ok = 0;
4512 
4513 	/* Allocate data segments for this device's tape buffer */
4514 	if (!enlarge_buffer(STp->buffer, STp->restr_dma)) {
4515 		printk(KERN_ERR "%s:E: Unable to allocate memory segments for tape buffer.\n", name);
4516 		retval = (-EOVERFLOW);
4517 		goto err_out;
4518 	}
4519 	if (STp->buffer->buffer_size >= OS_FRAME_SIZE) {
4520 		for (i = 0, b_size = 0;
4521 		     (i < STp->buffer->sg_segs) && ((b_size + STp->buffer->sg[i].length) <= OS_DATA_SIZE);
4522 		     b_size += STp->buffer->sg[i++].length);
4523 		STp->buffer->aux = (os_aux_t *) (page_address(sg_page(&STp->buffer->sg[i])) + OS_DATA_SIZE - b_size);
4524 #if DEBUG
4525 		printk(OSST_DEB_MSG "%s:D: b_data points to %p in segment 0 at %p\n", name,
4526 			STp->buffer->b_data, page_address(STp->buffer->sg[0].page));
4527 		printk(OSST_DEB_MSG "%s:D: AUX points to %p in segment %d at %p\n", name,
4528 			 STp->buffer->aux, i, page_address(STp->buffer->sg[i].page));
4529 #endif
4530 	} else {
4531 		STp->buffer->aux = NULL; /* this had better never happen! */
4532 		printk(KERN_NOTICE "%s:A: Framesize %d too large for buffer.\n", name, OS_FRAME_SIZE);
4533 		retval = (-EIO);
4534 		goto err_out;
4535 	}
4536 	STp->buffer->writing = 0;
4537 	STp->buffer->syscall_result = 0;
4538 	STp->dirty = 0;
4539 	for (i=0; i < ST_NBR_PARTITIONS; i++) {
4540 		STps = &(STp->ps[i]);
4541 		STps->rw = ST_IDLE;
4542 	}
4543 	STp->ready = ST_READY;
4544 #if DEBUG
4545 	STp->nbr_waits = STp->nbr_finished = 0;
4546 #endif
4547 
4548 	memset (cmd, 0, MAX_COMMAND_SIZE);
4549 	cmd[0] = TEST_UNIT_READY;
4550 
4551 	SRpnt = osst_do_scsi(NULL, STp, cmd, 0, DMA_NONE, STp->timeout, MAX_RETRIES, 1);
4552 	if (!SRpnt) {
4553 		retval = (STp->buffer)->syscall_result;		/* FIXME - valid? */
4554 		goto err_out;
4555 	}
4556 	if ((SRpnt->sense[0] & 0x70) == 0x70      &&
4557 	    (SRpnt->sense[2] & 0x0f) == NOT_READY &&
4558 	     SRpnt->sense[12]        == 4         ) {
4559 #if DEBUG
4560 		printk(OSST_DEB_MSG "%s:D: Unit not ready, cause %x\n", name, SRpnt->sense[13]);
4561 #endif
4562 		if (filp->f_flags & O_NONBLOCK) {
4563 			retval = -EAGAIN;
4564 			goto err_out;
4565 		}
4566 		if (SRpnt->sense[13] == 2) {	/* initialize command required (LOAD) */
4567 			memset (cmd, 0, MAX_COMMAND_SIZE);
4568         		cmd[0] = START_STOP;
4569 			cmd[1] = 1;
4570 			cmd[4] = 1;
4571 			SRpnt = osst_do_scsi(SRpnt, STp, cmd, 0, DMA_NONE,
4572 					     STp->timeout, MAX_RETRIES, 1);
4573 		}
4574 		osst_wait_ready(STp, &SRpnt, (SRpnt->sense[13]==1?15:3) * 60, 0);
4575 	}
4576 	if ((SRpnt->sense[0] & 0x70) == 0x70 &&
4577 	    (SRpnt->sense[2] & 0x0f) == UNIT_ATTENTION) { /* New media? */
4578 #if DEBUG
4579 		printk(OSST_DEB_MSG "%s:D: Unit wants attention\n", name);
4580 #endif
4581 		STp->header_ok = 0;
4582 
4583 		for (i=0; i < 10; i++) {
4584 
4585 			memset (cmd, 0, MAX_COMMAND_SIZE);
4586 			cmd[0] = TEST_UNIT_READY;
4587 
4588 			SRpnt = osst_do_scsi(SRpnt, STp, cmd, 0, DMA_NONE,
4589 					     STp->timeout, MAX_RETRIES, 1);
4590 			if ((SRpnt->sense[0] & 0x70) != 0x70 ||
4591 			    (SRpnt->sense[2] & 0x0f) != UNIT_ATTENTION)
4592 				break;
4593 		}
4594 
4595 		STp->pos_unknown = 0;
4596 		STp->partition = STp->new_partition = 0;
4597 		if (STp->can_partitions)
4598 			STp->nbr_partitions = 1;  /* This guess will be updated later if necessary */
4599 		for (i=0; i < ST_NBR_PARTITIONS; i++) {
4600 			STps = &(STp->ps[i]);
4601 			STps->rw = ST_IDLE;		/* FIXME - seems to be redundant... */
4602 			STps->eof = ST_NOEOF;
4603 			STps->at_sm = 0;
4604 			STps->last_block_valid = 0;
4605 			STps->drv_block = 0;
4606 			STps->drv_file = 0 ;
4607 		}
4608 		new_session = 1;
4609 		STp->recover_count = 0;
4610 		STp->abort_count = 0;
4611 	}
4612 	/*
4613 	 * if we have valid headers from before, and the drive/tape seem untouched,
4614 	 * open without reconfiguring and re-reading the headers
4615 	 */
4616 	if (!STp->buffer->syscall_result && STp->header_ok &&
4617 	    !SRpnt->result && SRpnt->sense[0] == 0) {
4618 
4619 		memset(cmd, 0, MAX_COMMAND_SIZE);
4620 		cmd[0] = MODE_SENSE;
4621 		cmd[1] = 8;
4622 		cmd[2] = VENDOR_IDENT_PAGE;
4623 		cmd[4] = VENDOR_IDENT_PAGE_LENGTH + MODE_HEADER_LENGTH;
4624 
4625 		SRpnt = osst_do_scsi(SRpnt, STp, cmd, cmd[4], DMA_FROM_DEVICE, STp->timeout, 0, 1);
4626 
4627 		if (STp->buffer->syscall_result                     ||
4628 		    STp->buffer->b_data[MODE_HEADER_LENGTH + 2] != 'L' ||
4629 		    STp->buffer->b_data[MODE_HEADER_LENGTH + 3] != 'I' ||
4630 		    STp->buffer->b_data[MODE_HEADER_LENGTH + 4] != 'N' ||
4631 		    STp->buffer->b_data[MODE_HEADER_LENGTH + 5] != '4'  ) {
4632 #if DEBUG
4633 			printk(OSST_DEB_MSG "%s:D: Signature was changed to %c%c%c%c\n", name,
4634 			  STp->buffer->b_data[MODE_HEADER_LENGTH + 2],
4635 			  STp->buffer->b_data[MODE_HEADER_LENGTH + 3],
4636 			  STp->buffer->b_data[MODE_HEADER_LENGTH + 4],
4637 			  STp->buffer->b_data[MODE_HEADER_LENGTH + 5]);
4638 #endif
4639 			STp->header_ok = 0;
4640 		}
4641 		i = STp->first_frame_position;
4642 		if (STp->header_ok && i == osst_get_frame_position(STp, &SRpnt)) {
4643 			if (STp->door_locked == ST_UNLOCKED) {
4644 				if (do_door_lock(STp, 1))
4645 					printk(KERN_INFO "%s:I: Can't lock drive door\n", name);
4646 				else
4647 					STp->door_locked = ST_LOCKED_AUTO;
4648 			}
4649 			if (!STp->frame_in_buffer) {
4650 				STp->block_size = (STm->default_blksize > 0) ?
4651 							STm->default_blksize : OS_DATA_SIZE;
4652 				STp->buffer->buffer_bytes = STp->buffer->read_pointer = 0;
4653 			}
4654 			STp->buffer->buffer_blocks = OS_DATA_SIZE / STp->block_size;
4655 			STp->fast_open = 1;
4656 			osst_release_request(SRpnt);
4657 			return 0;
4658 		}
4659 #if DEBUG
4660 		if (i != STp->first_frame_position)
4661 			printk(OSST_DEB_MSG "%s:D: Tape position changed from %d to %d\n",
4662 						name, i, STp->first_frame_position);
4663 #endif
4664 		STp->header_ok = 0;
4665 	}
4666 	STp->fast_open = 0;
4667 
4668 	if ((STp->buffer)->syscall_result != 0 &&   /* in all error conditions except no medium */
4669 	    (SRpnt->sense[2] != 2 || SRpnt->sense[12] != 0x3A) ) {
4670 
4671 		memset(cmd, 0, MAX_COMMAND_SIZE);
4672 		cmd[0] = MODE_SELECT;
4673 		cmd[1] = 0x10;
4674 		cmd[4] = 4 + MODE_HEADER_LENGTH;
4675 
4676 		(STp->buffer)->b_data[0] = cmd[4] - 1;
4677 		(STp->buffer)->b_data[1] = 0;			/* Medium Type - ignoring */
4678 		(STp->buffer)->b_data[2] = 0;			/* Reserved */
4679 		(STp->buffer)->b_data[3] = 0;			/* Block Descriptor Length */
4680 		(STp->buffer)->b_data[MODE_HEADER_LENGTH + 0] = 0x3f;
4681 		(STp->buffer)->b_data[MODE_HEADER_LENGTH + 1] = 1;
4682 		(STp->buffer)->b_data[MODE_HEADER_LENGTH + 2] = 2;
4683 		(STp->buffer)->b_data[MODE_HEADER_LENGTH + 3] = 3;
4684 
4685 #if DEBUG
4686 		printk(OSST_DEB_MSG "%s:D: Applying soft reset\n", name);
4687 #endif
4688 		SRpnt = osst_do_scsi(SRpnt, STp, cmd, cmd[4], DMA_TO_DEVICE, STp->timeout, 0, 1);
4689 
4690 		STp->header_ok = 0;
4691 
4692 		for (i=0; i < 10; i++) {
4693 
4694 			memset (cmd, 0, MAX_COMMAND_SIZE);
4695 			cmd[0] = TEST_UNIT_READY;
4696 
4697 			SRpnt = osst_do_scsi(SRpnt, STp, cmd, 0, DMA_NONE,
4698 						    STp->timeout, MAX_RETRIES, 1);
4699 			if ((SRpnt->sense[0] & 0x70) != 0x70 ||
4700 			    (SRpnt->sense[2] & 0x0f) == NOT_READY)
4701 			break;
4702 
4703 			if ((SRpnt->sense[2] & 0x0f) == UNIT_ATTENTION) {
4704 				int j;
4705 
4706 				STp->pos_unknown = 0;
4707 				STp->partition = STp->new_partition = 0;
4708 				if (STp->can_partitions)
4709 					STp->nbr_partitions = 1;  /* This guess will be updated later if necessary */
4710 				for (j = 0; j < ST_NBR_PARTITIONS; j++) {
4711 					STps = &(STp->ps[j]);
4712 					STps->rw = ST_IDLE;
4713 					STps->eof = ST_NOEOF;
4714 					STps->at_sm = 0;
4715 					STps->last_block_valid = 0;
4716 					STps->drv_block = 0;
4717 					STps->drv_file = 0 ;
4718 				}
4719 				new_session = 1;
4720 			}
4721 		}
4722 	}
4723 
4724 	if (osst_wait_ready(STp, &SRpnt, 15 * 60, 0))		/* FIXME - not allowed with NOBLOCK */
4725 		 printk(KERN_INFO "%s:I: Device did not become Ready in open\n", name);
4726 
4727 	if ((STp->buffer)->syscall_result != 0) {
4728 		if ((STp->device)->scsi_level >= SCSI_2 &&
4729 		    (SRpnt->sense[0] & 0x70) == 0x70 &&
4730 		    (SRpnt->sense[2] & 0x0f) == NOT_READY &&
4731 		     SRpnt->sense[12] == 0x3a) { /* Check ASC */
4732 			STp->ready = ST_NO_TAPE;
4733 		} else
4734 			STp->ready = ST_NOT_READY;
4735 		osst_release_request(SRpnt);
4736 		SRpnt = NULL;
4737 		STp->density = 0;   	/* Clear the erroneous "residue" */
4738 		STp->write_prot = 0;
4739 		STp->block_size = 0;
4740 		STp->ps[0].drv_file = STp->ps[0].drv_block = (-1);
4741 		STp->partition = STp->new_partition = 0;
4742 		STp->door_locked = ST_UNLOCKED;
4743 		return 0;
4744 	}
4745 
4746 	osst_configure_onstream(STp, &SRpnt);
4747 
4748 	STp->block_size = STp->raw ? OS_FRAME_SIZE : (
4749 			     (STm->default_blksize > 0) ? STm->default_blksize : OS_DATA_SIZE);
4750 	STp->buffer->buffer_blocks = STp->raw ? 1 : OS_DATA_SIZE / STp->block_size;
4751 	STp->buffer->buffer_bytes  =
4752 	STp->buffer->read_pointer  =
4753 	STp->frame_in_buffer       = 0;
4754 
4755 #if DEBUG
4756 	if (debugging)
4757 		printk(OSST_DEB_MSG "%s:D: Block size: %d, frame size: %d, buffer size: %d (%d blocks).\n",
4758 		     name, STp->block_size, OS_FRAME_SIZE, (STp->buffer)->buffer_size,
4759 		     (STp->buffer)->buffer_blocks);
4760 #endif
4761 
4762 	if (STp->drv_write_prot) {
4763 		STp->write_prot = 1;
4764 #if DEBUG
4765 		if (debugging)
4766 			printk(OSST_DEB_MSG "%s:D: Write protected\n", name);
4767 #endif
4768 		if ((flags & O_ACCMODE) == O_WRONLY || (flags & O_ACCMODE) == O_RDWR) {
4769 			retval = (-EROFS);
4770 			goto err_out;
4771 		}
4772 	}
4773 
4774 	if (new_session) {  /* Change the drive parameters for the new mode */
4775 #if DEBUG
4776 		if (debugging)
4777 	printk(OSST_DEB_MSG "%s:D: New Session\n", name);
4778 #endif
4779 		STp->density_changed = STp->blksize_changed = 0;
4780 		STp->compression_changed = 0;
4781 	}
4782 
4783 	/*
4784 	 * properly position the tape and check the ADR headers
4785 	 */
4786 	if (STp->door_locked == ST_UNLOCKED) {
4787 		 if (do_door_lock(STp, 1))
4788 			printk(KERN_INFO "%s:I: Can't lock drive door\n", name);
4789 		 else
4790 			STp->door_locked = ST_LOCKED_AUTO;
4791 	}
4792 
4793 	osst_analyze_headers(STp, &SRpnt);
4794 
4795 	osst_release_request(SRpnt);
4796 	SRpnt = NULL;
4797 
4798 	return 0;
4799 
4800 err_out:
4801 	if (SRpnt != NULL)
4802 		osst_release_request(SRpnt);
4803 	normalize_buffer(STp->buffer);
4804 	STp->header_ok = 0;
4805 	STp->in_use = 0;
4806 	scsi_device_put(STp->device);
4807 
4808 	return retval;
4809 }
4810 
4811 /* BKL pushdown: spaghetti avoidance wrapper */
os_scsi_tape_open(struct inode * inode,struct file * filp)4812 static int os_scsi_tape_open(struct inode * inode, struct file * filp)
4813 {
4814 	int ret;
4815 
4816 	mutex_lock(&osst_int_mutex);
4817 	ret = __os_scsi_tape_open(inode, filp);
4818 	mutex_unlock(&osst_int_mutex);
4819 	return ret;
4820 }
4821 
4822 
4823 
4824 /* Flush the tape buffer before close */
os_scsi_tape_flush(struct file * filp,fl_owner_t id)4825 static int os_scsi_tape_flush(struct file * filp, fl_owner_t id)
4826 {
4827 	int		      result = 0, result2;
4828 	struct osst_tape    * STp    = filp->private_data;
4829 	struct st_modedef   * STm    = &(STp->modes[STp->current_mode]);
4830 	struct st_partstat  * STps   = &(STp->ps[STp->partition]);
4831 	struct osst_request * SRpnt  = NULL;
4832 	char		    * name   = tape_name(STp);
4833 
4834 	if (file_count(filp) > 1)
4835 		return 0;
4836 
4837 	if ((STps->rw == ST_WRITING || STp->dirty) && !STp->pos_unknown) {
4838 		STp->write_type = OS_WRITE_DATA;
4839 		result = osst_flush_write_buffer(STp, &SRpnt);
4840 		if (result != 0 && result != (-ENOSPC))
4841 			goto out;
4842 	}
4843 	if ( STps->rw >= ST_WRITING && !STp->pos_unknown) {
4844 
4845 #if DEBUG
4846 		if (debugging) {
4847 			printk(OSST_DEB_MSG "%s:D: File length %ld bytes.\n",
4848 					       name, (long)(filp->f_pos));
4849 			printk(OSST_DEB_MSG "%s:D: Async write waits %d, finished %d.\n",
4850 					       name, STp->nbr_waits, STp->nbr_finished);
4851 		}
4852 #endif
4853 		result = osst_write_trailer(STp, &SRpnt, !(STp->rew_at_close));
4854 #if DEBUG
4855 		if (debugging)
4856 			printk(OSST_DEB_MSG "%s:D: Buffer flushed, %d EOF(s) written\n",
4857 					       name, 1+STp->two_fm);
4858 #endif
4859 	}
4860 	else if (!STp->rew_at_close) {
4861 		STps = &(STp->ps[STp->partition]);
4862 		if (!STm->sysv || STps->rw != ST_READING) {
4863 			if (STp->can_bsr)
4864 				result = osst_flush_buffer(STp, &SRpnt, 0); /* this is the default path */
4865 			else if (STps->eof == ST_FM_HIT) {
4866 				result = cross_eof(STp, &SRpnt, 0);
4867 					if (result) {
4868 						if (STps->drv_file >= 0)
4869 							STps->drv_file++;
4870 						STps->drv_block = 0;
4871 						STps->eof = ST_FM;
4872 					}
4873 					else
4874 						STps->eof = ST_NOEOF;
4875 			}
4876 		}
4877 		else if ((STps->eof == ST_NOEOF &&
4878 			  !(result = cross_eof(STp, &SRpnt, 1))) ||
4879 			 STps->eof == ST_FM_HIT) {
4880 			if (STps->drv_file >= 0)
4881 				STps->drv_file++;
4882 			STps->drv_block = 0;
4883 			STps->eof = ST_FM;
4884 		}
4885 	}
4886 
4887 out:
4888 	if (STp->rew_at_close) {
4889 		result2 = osst_position_tape_and_confirm(STp, &SRpnt, STp->first_data_ppos);
4890 		STps->drv_file = STps->drv_block = STp->frame_seq_number = STp->logical_blk_num = 0;
4891 		if (result == 0 && result2 < 0)
4892 			result = result2;
4893 	}
4894 	if (SRpnt) osst_release_request(SRpnt);
4895 
4896 	if (STp->abort_count || STp->recover_count) {
4897 		printk(KERN_INFO "%s:I:", name);
4898 		if (STp->abort_count)
4899 			printk(" %d unrecovered errors", STp->abort_count);
4900 		if (STp->recover_count)
4901 			printk(" %d recovered errors", STp->recover_count);
4902 		if (STp->write_count)
4903 			printk(" in %d frames written", STp->write_count);
4904 		if (STp->read_count)
4905 			printk(" in %d frames read", STp->read_count);
4906 		printk("\n");
4907 		STp->recover_count = 0;
4908 		STp->abort_count   = 0;
4909 	}
4910 	STp->write_count = 0;
4911 	STp->read_count  = 0;
4912 
4913 	return result;
4914 }
4915 
4916 
4917 /* Close the device and release it */
os_scsi_tape_close(struct inode * inode,struct file * filp)4918 static int os_scsi_tape_close(struct inode * inode, struct file * filp)
4919 {
4920 	int		      result = 0;
4921 	struct osst_tape    * STp    = filp->private_data;
4922 
4923 	if (STp->door_locked == ST_LOCKED_AUTO)
4924 		do_door_lock(STp, 0);
4925 
4926 	if (STp->raw)
4927 		STp->header_ok = 0;
4928 
4929 	normalize_buffer(STp->buffer);
4930 	write_lock(&os_scsi_tapes_lock);
4931 	STp->in_use = 0;
4932 	write_unlock(&os_scsi_tapes_lock);
4933 
4934 	scsi_device_put(STp->device);
4935 
4936 	return result;
4937 }
4938 
4939 
4940 /* The ioctl command */
osst_ioctl(struct file * file,unsigned int cmd_in,unsigned long arg)4941 static long osst_ioctl(struct file * file,
4942 	 unsigned int cmd_in, unsigned long arg)
4943 {
4944 	int		      i, cmd_nr, cmd_type, blk, retval = 0;
4945 	struct st_modedef   * STm;
4946 	struct st_partstat  * STps;
4947 	struct osst_request * SRpnt = NULL;
4948 	struct osst_tape    * STp   = file->private_data;
4949 	char		    * name  = tape_name(STp);
4950 	void	    __user  * p     = (void __user *)arg;
4951 
4952 	mutex_lock(&osst_int_mutex);
4953 	if (mutex_lock_interruptible(&STp->lock)) {
4954 		mutex_unlock(&osst_int_mutex);
4955 		return -ERESTARTSYS;
4956 	}
4957 
4958 #if DEBUG
4959 	if (debugging && !STp->in_use) {
4960 		printk(OSST_DEB_MSG "%s:D: Incorrect device.\n", name);
4961 		retval = (-EIO);
4962 		goto out;
4963 	}
4964 #endif
4965 	STm = &(STp->modes[STp->current_mode]);
4966 	STps = &(STp->ps[STp->partition]);
4967 
4968 	/*
4969 	 * If we are in the middle of error recovery, don't let anyone
4970 	 * else try and use this device.  Also, if error recovery fails, it
4971 	 * may try and take the device offline, in which case all further
4972 	 * access to the device is prohibited.
4973 	 */
4974 	retval = scsi_ioctl_block_when_processing_errors(STp->device, cmd_in,
4975 			file->f_flags & O_NDELAY);
4976 	if (retval)
4977 		goto out;
4978 
4979 	cmd_type = _IOC_TYPE(cmd_in);
4980 	cmd_nr   = _IOC_NR(cmd_in);
4981 #if DEBUG
4982 	printk(OSST_DEB_MSG "%s:D: Ioctl %d,%d in %s mode\n", name,
4983 			    cmd_type, cmd_nr, STp->raw?"raw":"normal");
4984 #endif
4985 	if (cmd_type == _IOC_TYPE(MTIOCTOP) && cmd_nr == _IOC_NR(MTIOCTOP)) {
4986 		struct mtop mtc;
4987 		int    auto_weof = 0;
4988 
4989 		if (_IOC_SIZE(cmd_in) != sizeof(mtc)) {
4990 			retval = (-EINVAL);
4991 			goto out;
4992 		}
4993 
4994 		i = copy_from_user((char *) &mtc, p, sizeof(struct mtop));
4995 		if (i) {
4996 			retval = (-EFAULT);
4997 			goto out;
4998 		}
4999 
5000 		if (mtc.mt_op == MTSETDRVBUFFER && !capable(CAP_SYS_ADMIN)) {
5001 			printk(KERN_WARNING "%s:W: MTSETDRVBUFFER only allowed for root.\n", name);
5002 			retval = (-EPERM);
5003 			goto out;
5004 		}
5005 
5006 		if (!STm->defined && (mtc.mt_op != MTSETDRVBUFFER && (mtc.mt_count & MT_ST_OPTIONS) == 0)) {
5007 			retval = (-ENXIO);
5008 			goto out;
5009 		}
5010 
5011 		if (!STp->pos_unknown) {
5012 
5013 			if (STps->eof == ST_FM_HIT) {
5014 				if (mtc.mt_op == MTFSF || mtc.mt_op == MTFSFM|| mtc.mt_op == MTEOM) {
5015 					mtc.mt_count -= 1;
5016 					if (STps->drv_file >= 0)
5017 						STps->drv_file += 1;
5018 				}
5019 				else if (mtc.mt_op == MTBSF || mtc.mt_op == MTBSFM) {
5020 					mtc.mt_count += 1;
5021 					if (STps->drv_file >= 0)
5022 						STps->drv_file += 1;
5023 				}
5024 			}
5025 
5026 			if (mtc.mt_op == MTSEEK) {
5027 				/* Old position must be restored if partition will be changed */
5028 				i = !STp->can_partitions || (STp->new_partition != STp->partition);
5029 			}
5030 			else {
5031 				i = mtc.mt_op == MTREW   || mtc.mt_op == MTOFFL ||
5032 				    mtc.mt_op == MTRETEN || mtc.mt_op == MTEOM  ||
5033 				    mtc.mt_op == MTLOCK  || mtc.mt_op == MTLOAD ||
5034 				    mtc.mt_op == MTFSF   || mtc.mt_op == MTFSFM ||
5035 				    mtc.mt_op == MTBSF   || mtc.mt_op == MTBSFM ||
5036 				    mtc.mt_op == MTCOMPRESSION;
5037 			}
5038 			i = osst_flush_buffer(STp, &SRpnt, i);
5039 			if (i < 0) {
5040 				retval = i;
5041 				goto out;
5042 			}
5043 		}
5044 		else {
5045 			/*
5046 			 * If there was a bus reset, block further access
5047 			 * to this device.  If the user wants to rewind the tape,
5048 			 * then reset the flag and allow access again.
5049 			 */
5050 			if(mtc.mt_op != MTREW   &&
5051 			   mtc.mt_op != MTOFFL  &&
5052 			   mtc.mt_op != MTRETEN &&
5053 			   mtc.mt_op != MTERASE &&
5054 			   mtc.mt_op != MTSEEK  &&
5055 			   mtc.mt_op != MTEOM)   {
5056 				retval = (-EIO);
5057 				goto out;
5058 			}
5059 			reset_state(STp);
5060 			/* remove this when the midlevel properly clears was_reset */
5061 			STp->device->was_reset = 0;
5062 		}
5063 
5064 		if (mtc.mt_op != MTCOMPRESSION  && mtc.mt_op != MTLOCK         &&
5065 		    mtc.mt_op != MTNOP          && mtc.mt_op != MTSETBLK       &&
5066 		    mtc.mt_op != MTSETDENSITY   && mtc.mt_op != MTSETDRVBUFFER &&
5067 		    mtc.mt_op != MTMKPART       && mtc.mt_op != MTSETPART      &&
5068 		    mtc.mt_op != MTWEOF         && mtc.mt_op != MTWSM           ) {
5069 
5070 			/*
5071 			 * The user tells us to move to another position on the tape.
5072 			 * If we were appending to the tape content, that would leave
5073 			 * the tape without proper end, in that case write EOD and
5074 			 * update the header to reflect its position.
5075 			 */
5076 #if DEBUG
5077 			printk(KERN_WARNING "%s:D: auto_weod %s at ffp=%d,efp=%d,fsn=%d,lbn=%d,fn=%d,bn=%d\n", name,
5078 					STps->rw >= ST_WRITING ? "write" : STps->rw == ST_READING ? "read" : "idle",
5079 					STp->first_frame_position, STp->eod_frame_ppos, STp->frame_seq_number,
5080 					STp->logical_blk_num, STps->drv_file, STps->drv_block );
5081 #endif
5082 			if (STps->rw >= ST_WRITING && STp->first_frame_position >= STp->eod_frame_ppos) {
5083 				auto_weof = ((STp->write_type != OS_WRITE_NEW_MARK) &&
5084 							!(mtc.mt_op == MTREW || mtc.mt_op == MTOFFL));
5085 				i = osst_write_trailer(STp, &SRpnt,
5086 							!(mtc.mt_op == MTREW || mtc.mt_op == MTOFFL));
5087 #if DEBUG
5088 				printk(KERN_WARNING "%s:D: post trailer xeof=%d,ffp=%d,efp=%d,fsn=%d,lbn=%d,fn=%d,bn=%d\n",
5089 						name, auto_weof, STp->first_frame_position, STp->eod_frame_ppos,
5090 						STp->frame_seq_number, STp->logical_blk_num, STps->drv_file, STps->drv_block );
5091 #endif
5092 				if (i < 0) {
5093 					retval = i;
5094 					goto out;
5095 				}
5096 			}
5097 			STps->rw = ST_IDLE;
5098 		}
5099 
5100 		if (mtc.mt_op == MTOFFL && STp->door_locked != ST_UNLOCKED)
5101 			do_door_lock(STp, 0);  /* Ignore result! */
5102 
5103 		if (mtc.mt_op == MTSETDRVBUFFER &&
5104 		   (mtc.mt_count & MT_ST_OPTIONS) != 0) {
5105 			retval = osst_set_options(STp, mtc.mt_count);
5106 			goto out;
5107 		}
5108 
5109 		if (mtc.mt_op == MTSETPART) {
5110 			if (mtc.mt_count >= STp->nbr_partitions)
5111 				retval = -EINVAL;
5112 			else {
5113 				STp->new_partition = mtc.mt_count;
5114 				retval = 0;
5115 			}
5116 			goto out;
5117 		}
5118 
5119 		if (mtc.mt_op == MTMKPART) {
5120 			if (!STp->can_partitions) {
5121 				retval = (-EINVAL);
5122 				goto out;
5123 			}
5124 			if ((i = osst_int_ioctl(STp, &SRpnt, MTREW, 0)) < 0 /*||
5125 			    (i = partition_tape(inode, mtc.mt_count)) < 0*/) {
5126 				retval = i;
5127 				goto out;
5128 			}
5129 			for (i=0; i < ST_NBR_PARTITIONS; i++) {
5130 				STp->ps[i].rw = ST_IDLE;
5131 				STp->ps[i].at_sm = 0;
5132 				STp->ps[i].last_block_valid = 0;
5133 			}
5134 			STp->partition = STp->new_partition = 0;
5135 			STp->nbr_partitions = 1;  /* Bad guess ?-) */
5136 			STps->drv_block = STps->drv_file = 0;
5137 			retval = 0;
5138 			goto out;
5139 	 	}
5140 
5141 		if (mtc.mt_op == MTSEEK) {
5142 			if (STp->raw)
5143 				i = osst_set_frame_position(STp, &SRpnt, mtc.mt_count, 0);
5144 			else
5145 				i = osst_seek_sector(STp, &SRpnt, mtc.mt_count);
5146 			if (!STp->can_partitions)
5147 				STp->ps[0].rw = ST_IDLE;
5148 			retval = i;
5149 			goto out;
5150 		}
5151 
5152 		if (mtc.mt_op == MTLOCK || mtc.mt_op == MTUNLOCK) {
5153 			retval = do_door_lock(STp, (mtc.mt_op == MTLOCK));
5154 			goto out;
5155 		}
5156 
5157 		if (auto_weof)
5158 			cross_eof(STp, &SRpnt, 0);
5159 
5160 		if (mtc.mt_op == MTCOMPRESSION)
5161 			retval = -EINVAL;       /* OnStream drives don't have compression hardware */
5162 		else
5163 			/* MTBSF MTBSFM MTBSR MTBSS MTEOM MTERASE MTFSF MTFSFB MTFSR MTFSS
5164 			 * MTLOAD MTOFFL MTRESET MTRETEN MTREW MTUNLOAD MTWEOF MTWSM */
5165 			retval = osst_int_ioctl(STp, &SRpnt, mtc.mt_op, mtc.mt_count);
5166 		goto out;
5167 	}
5168 
5169 	if (!STm->defined) {
5170 		retval = (-ENXIO);
5171 		goto out;
5172 	}
5173 
5174 	if ((i = osst_flush_buffer(STp, &SRpnt, 0)) < 0) {
5175 		retval = i;
5176 		goto out;
5177 	}
5178 
5179 	if (cmd_type == _IOC_TYPE(MTIOCGET) && cmd_nr == _IOC_NR(MTIOCGET)) {
5180 		struct mtget mt_status;
5181 
5182 		if (_IOC_SIZE(cmd_in) != sizeof(struct mtget)) {
5183 			 retval = (-EINVAL);
5184 			 goto out;
5185 		}
5186 
5187 		mt_status.mt_type = MT_ISONSTREAM_SC;
5188 		mt_status.mt_erreg = STp->recover_erreg << MT_ST_SOFTERR_SHIFT;
5189 		mt_status.mt_dsreg =
5190 			((STp->block_size << MT_ST_BLKSIZE_SHIFT) & MT_ST_BLKSIZE_MASK) |
5191 			((STp->density    << MT_ST_DENSITY_SHIFT) & MT_ST_DENSITY_MASK);
5192 		mt_status.mt_blkno = STps->drv_block;
5193 		mt_status.mt_fileno = STps->drv_file;
5194 		if (STp->block_size != 0) {
5195 			if (STps->rw == ST_WRITING)
5196 				mt_status.mt_blkno += (STp->buffer)->buffer_bytes / STp->block_size;
5197 			else if (STps->rw == ST_READING)
5198 				mt_status.mt_blkno -= ((STp->buffer)->buffer_bytes +
5199 							STp->block_size - 1) / STp->block_size;
5200 		}
5201 
5202 		mt_status.mt_gstat = 0;
5203 		if (STp->drv_write_prot)
5204 			mt_status.mt_gstat |= GMT_WR_PROT(0xffffffff);
5205 		if (mt_status.mt_blkno == 0) {
5206 			if (mt_status.mt_fileno == 0)
5207 				mt_status.mt_gstat |= GMT_BOT(0xffffffff);
5208 			else
5209 				mt_status.mt_gstat |= GMT_EOF(0xffffffff);
5210 		}
5211 		mt_status.mt_resid = STp->partition;
5212 		if (STps->eof == ST_EOM_OK || STps->eof == ST_EOM_ERROR)
5213 			mt_status.mt_gstat |= GMT_EOT(0xffffffff);
5214 		else if (STps->eof >= ST_EOM_OK)
5215 			mt_status.mt_gstat |= GMT_EOD(0xffffffff);
5216 		if (STp->density == 1)
5217 			mt_status.mt_gstat |= GMT_D_800(0xffffffff);
5218 		else if (STp->density == 2)
5219 			mt_status.mt_gstat |= GMT_D_1600(0xffffffff);
5220 		else if (STp->density == 3)
5221 			mt_status.mt_gstat |= GMT_D_6250(0xffffffff);
5222 		if (STp->ready == ST_READY)
5223 			mt_status.mt_gstat |= GMT_ONLINE(0xffffffff);
5224 		if (STp->ready == ST_NO_TAPE)
5225 			mt_status.mt_gstat |= GMT_DR_OPEN(0xffffffff);
5226 		if (STps->at_sm)
5227 			mt_status.mt_gstat |= GMT_SM(0xffffffff);
5228 		if (STm->do_async_writes || (STm->do_buffer_writes && STp->block_size != 0) ||
5229 		    STp->drv_buffer != 0)
5230 			mt_status.mt_gstat |= GMT_IM_REP_EN(0xffffffff);
5231 
5232 		i = copy_to_user(p, &mt_status, sizeof(struct mtget));
5233 		if (i) {
5234 			retval = (-EFAULT);
5235 			goto out;
5236 		}
5237 
5238 		STp->recover_erreg = 0;  /* Clear after read */
5239 		retval = 0;
5240 		goto out;
5241 	} /* End of MTIOCGET */
5242 
5243 	if (cmd_type == _IOC_TYPE(MTIOCPOS) && cmd_nr == _IOC_NR(MTIOCPOS)) {
5244 		struct mtpos mt_pos;
5245 
5246 		if (_IOC_SIZE(cmd_in) != sizeof(struct mtpos)) {
5247 			retval = (-EINVAL);
5248 			goto out;
5249 		}
5250 		if (STp->raw)
5251 			blk = osst_get_frame_position(STp, &SRpnt);
5252 		else
5253 			blk = osst_get_sector(STp, &SRpnt);
5254 		if (blk < 0) {
5255 			retval = blk;
5256 			goto out;
5257 		}
5258 		mt_pos.mt_blkno = blk;
5259 		i = copy_to_user(p, &mt_pos, sizeof(struct mtpos));
5260 		if (i)
5261 			retval = -EFAULT;
5262 		goto out;
5263 	}
5264 	if (SRpnt) osst_release_request(SRpnt);
5265 
5266 	mutex_unlock(&STp->lock);
5267 
5268 	retval = scsi_ioctl(STp->device, cmd_in, p);
5269 	mutex_unlock(&osst_int_mutex);
5270 	return retval;
5271 
5272 out:
5273 	if (SRpnt) osst_release_request(SRpnt);
5274 
5275 	mutex_unlock(&STp->lock);
5276 	mutex_unlock(&osst_int_mutex);
5277 
5278 	return retval;
5279 }
5280 
5281 #ifdef CONFIG_COMPAT
osst_compat_ioctl(struct file * file,unsigned int cmd_in,unsigned long arg)5282 static long osst_compat_ioctl(struct file * file, unsigned int cmd_in, unsigned long arg)
5283 {
5284 	struct osst_tape *STp = file->private_data;
5285 	struct scsi_device *sdev = STp->device;
5286 	int ret = -ENOIOCTLCMD;
5287 	if (sdev->host->hostt->compat_ioctl) {
5288 
5289 		ret = sdev->host->hostt->compat_ioctl(sdev, cmd_in, (void __user *)arg);
5290 
5291 	}
5292 	return ret;
5293 }
5294 #endif
5295 
5296 
5297 
5298 /* Memory handling routines */
5299 
5300 /* Try to allocate a new tape buffer skeleton. Caller must not hold os_scsi_tapes_lock */
new_tape_buffer(int from_initialization,int need_dma,int max_sg)5301 static struct osst_buffer * new_tape_buffer( int from_initialization, int need_dma, int max_sg )
5302 {
5303 	int i;
5304 	gfp_t priority;
5305 	struct osst_buffer *tb;
5306 
5307 	if (from_initialization)
5308 		priority = GFP_ATOMIC;
5309 	else
5310 		priority = GFP_KERNEL;
5311 
5312 	i = sizeof(struct osst_buffer) + (osst_max_sg_segs - 1) * sizeof(struct scatterlist);
5313 	tb = kzalloc(i, priority);
5314 	if (!tb) {
5315 		printk(KERN_NOTICE "osst :I: Can't allocate new tape buffer.\n");
5316 		return NULL;
5317 	}
5318 
5319 	tb->sg_segs = tb->orig_sg_segs = 0;
5320 	tb->use_sg = max_sg;
5321 	tb->in_use = 1;
5322 	tb->dma = need_dma;
5323 	tb->buffer_size = 0;
5324 #if DEBUG
5325 	if (debugging)
5326 		printk(OSST_DEB_MSG
5327 			"osst :D: Allocated tape buffer skeleton (%d bytes, %d segments, dma: %d).\n",
5328 			   i, max_sg, need_dma);
5329 #endif
5330 	return tb;
5331 }
5332 
5333 /* Try to allocate a temporary (while a user has the device open) enlarged tape buffer */
enlarge_buffer(struct osst_buffer * STbuffer,int need_dma)5334 static int enlarge_buffer(struct osst_buffer *STbuffer, int need_dma)
5335 {
5336 	int segs, nbr, max_segs, b_size, order, got;
5337 	gfp_t priority;
5338 
5339 	if (STbuffer->buffer_size >= OS_FRAME_SIZE)
5340 		return 1;
5341 
5342 	if (STbuffer->sg_segs) {
5343 		printk(KERN_WARNING "osst :A: Buffer not previously normalized.\n");
5344 		normalize_buffer(STbuffer);
5345 	}
5346 	/* See how many segments we can use -- need at least two */
5347 	nbr = max_segs = STbuffer->use_sg;
5348 	if (nbr <= 2)
5349 		return 0;
5350 
5351 	priority = GFP_KERNEL /* | __GFP_NOWARN */;
5352 	if (need_dma)
5353 		priority |= GFP_DMA;
5354 
5355 	/* Try to allocate the first segment up to OS_DATA_SIZE and the others
5356 	   big enough to reach the goal (code assumes no segments in place) */
5357 	for (b_size = OS_DATA_SIZE, order = OSST_FIRST_ORDER; b_size >= PAGE_SIZE; order--, b_size /= 2) {
5358 		struct page *page = alloc_pages(priority, order);
5359 
5360 		STbuffer->sg[0].offset = 0;
5361 		if (page != NULL) {
5362 		    sg_set_page(&STbuffer->sg[0], page, b_size, 0);
5363 		    STbuffer->b_data = page_address(page);
5364 		    break;
5365 		}
5366 	}
5367 	if (sg_page(&STbuffer->sg[0]) == NULL) {
5368 		printk(KERN_NOTICE "osst :I: Can't allocate tape buffer main segment.\n");
5369 		return 0;
5370 	}
5371 	/* Got initial segment of 'bsize,order', continue with same size if possible, except for AUX */
5372 	for (segs=STbuffer->sg_segs=1, got=b_size;
5373 	     segs < max_segs && got < OS_FRAME_SIZE; ) {
5374 		struct page *page = alloc_pages(priority, (OS_FRAME_SIZE - got <= PAGE_SIZE) ? 0 : order);
5375 		STbuffer->sg[segs].offset = 0;
5376 		if (page == NULL) {
5377 			printk(KERN_WARNING "osst :W: Failed to enlarge buffer to %d bytes.\n",
5378 						OS_FRAME_SIZE);
5379 #if DEBUG
5380 			STbuffer->buffer_size = got;
5381 #endif
5382 			normalize_buffer(STbuffer);
5383 			return 0;
5384 		}
5385 		sg_set_page(&STbuffer->sg[segs], page, (OS_FRAME_SIZE - got <= PAGE_SIZE / 2) ? (OS_FRAME_SIZE - got) : b_size, 0);
5386 		got += STbuffer->sg[segs].length;
5387 		STbuffer->buffer_size = got;
5388 		STbuffer->sg_segs = ++segs;
5389 	}
5390 #if DEBUG
5391 	if (debugging) {
5392 		printk(OSST_DEB_MSG
5393 			   "osst :D: Expanded tape buffer (%d bytes, %d->%d segments, dma: %d, at: %p).\n",
5394 			   got, STbuffer->orig_sg_segs, STbuffer->sg_segs, need_dma, STbuffer->b_data);
5395 		printk(OSST_DEB_MSG
5396 			   "osst :D: segment sizes: first %d at %p, last %d bytes at %p.\n",
5397 			   STbuffer->sg[0].length, page_address(STbuffer->sg[0].page),
5398 			   STbuffer->sg[segs-1].length, page_address(STbuffer->sg[segs-1].page));
5399 	}
5400 #endif
5401 
5402 	return 1;
5403 }
5404 
5405 
5406 /* Release the segments */
normalize_buffer(struct osst_buffer * STbuffer)5407 static void normalize_buffer(struct osst_buffer *STbuffer)
5408 {
5409   int i, order, b_size;
5410 
5411 	for (i=0; i < STbuffer->sg_segs; i++) {
5412 
5413 		for (b_size = PAGE_SIZE, order = 0;
5414 		     b_size < STbuffer->sg[i].length;
5415 		     b_size *= 2, order++);
5416 
5417 		__free_pages(sg_page(&STbuffer->sg[i]), order);
5418 		STbuffer->buffer_size -= STbuffer->sg[i].length;
5419 	}
5420 #if DEBUG
5421 	if (debugging && STbuffer->orig_sg_segs < STbuffer->sg_segs)
5422 		printk(OSST_DEB_MSG "osst :D: Buffer at %p normalized to %d bytes (segs %d).\n",
5423 			     STbuffer->b_data, STbuffer->buffer_size, STbuffer->sg_segs);
5424 #endif
5425 	STbuffer->sg_segs = STbuffer->orig_sg_segs = 0;
5426 }
5427 
5428 
5429 /* Move data from the user buffer to the tape buffer. Returns zero (success) or
5430    negative error code. */
append_to_buffer(const char __user * ubp,struct osst_buffer * st_bp,int do_count)5431 static int append_to_buffer(const char __user *ubp, struct osst_buffer *st_bp, int do_count)
5432 {
5433 	int i, cnt, res, offset;
5434 
5435 	for (i=0, offset=st_bp->buffer_bytes;
5436 	     i < st_bp->sg_segs && offset >= st_bp->sg[i].length; i++)
5437 		offset -= st_bp->sg[i].length;
5438 	if (i == st_bp->sg_segs) {  /* Should never happen */
5439 		printk(KERN_WARNING "osst :A: Append_to_buffer offset overflow.\n");
5440 		return (-EIO);
5441 	}
5442 	for ( ; i < st_bp->sg_segs && do_count > 0; i++) {
5443 		cnt = st_bp->sg[i].length - offset < do_count ?
5444 		      st_bp->sg[i].length - offset : do_count;
5445 		res = copy_from_user(page_address(sg_page(&st_bp->sg[i])) + offset, ubp, cnt);
5446 		if (res)
5447 			return (-EFAULT);
5448 		do_count -= cnt;
5449 		st_bp->buffer_bytes += cnt;
5450 		ubp += cnt;
5451 		offset = 0;
5452 	}
5453 	if (do_count) {  /* Should never happen */
5454 		printk(KERN_WARNING "osst :A: Append_to_buffer overflow (left %d).\n",
5455 		       do_count);
5456 		return (-EIO);
5457 	}
5458 	return 0;
5459 }
5460 
5461 
5462 /* Move data from the tape buffer to the user buffer. Returns zero (success) or
5463    negative error code. */
from_buffer(struct osst_buffer * st_bp,char __user * ubp,int do_count)5464 static int from_buffer(struct osst_buffer *st_bp, char __user *ubp, int do_count)
5465 {
5466 	int i, cnt, res, offset;
5467 
5468 	for (i=0, offset=st_bp->read_pointer;
5469 	     i < st_bp->sg_segs && offset >= st_bp->sg[i].length; i++)
5470 		offset -= st_bp->sg[i].length;
5471 	if (i == st_bp->sg_segs) {  /* Should never happen */
5472 		printk(KERN_WARNING "osst :A: From_buffer offset overflow.\n");
5473 		return (-EIO);
5474 	}
5475 	for ( ; i < st_bp->sg_segs && do_count > 0; i++) {
5476 		cnt = st_bp->sg[i].length - offset < do_count ?
5477 		      st_bp->sg[i].length - offset : do_count;
5478 		res = copy_to_user(ubp, page_address(sg_page(&st_bp->sg[i])) + offset, cnt);
5479 		if (res)
5480 			return (-EFAULT);
5481 		do_count -= cnt;
5482 		st_bp->buffer_bytes -= cnt;
5483 		st_bp->read_pointer += cnt;
5484 		ubp += cnt;
5485 		offset = 0;
5486 	}
5487 	if (do_count) {  /* Should never happen */
5488 		printk(KERN_WARNING "osst :A: From_buffer overflow (left %d).\n", do_count);
5489 		return (-EIO);
5490 	}
5491 	return 0;
5492 }
5493 
5494 /* Sets the tail of the buffer after fill point to zero.
5495    Returns zero (success) or negative error code.        */
osst_zero_buffer_tail(struct osst_buffer * st_bp)5496 static int osst_zero_buffer_tail(struct osst_buffer *st_bp)
5497 {
5498 	int	i, offset, do_count, cnt;
5499 
5500 	for (i = 0, offset = st_bp->buffer_bytes;
5501 	     i < st_bp->sg_segs && offset >= st_bp->sg[i].length; i++)
5502 		offset -= st_bp->sg[i].length;
5503 	if (i == st_bp->sg_segs) {  /* Should never happen */
5504 		printk(KERN_WARNING "osst :A: Zero_buffer offset overflow.\n");
5505 		return (-EIO);
5506 	}
5507 	for (do_count = OS_DATA_SIZE - st_bp->buffer_bytes;
5508 	     i < st_bp->sg_segs && do_count > 0; i++) {
5509 		cnt = st_bp->sg[i].length - offset < do_count ?
5510 		      st_bp->sg[i].length - offset : do_count ;
5511 		memset(page_address(sg_page(&st_bp->sg[i])) + offset, 0, cnt);
5512 		do_count -= cnt;
5513 		offset = 0;
5514 	}
5515 	if (do_count) {  /* Should never happen */
5516 		printk(KERN_WARNING "osst :A: Zero_buffer overflow (left %d).\n", do_count);
5517 		return (-EIO);
5518 	}
5519 	return 0;
5520 }
5521 
5522 /* Copy a osst 32K chunk of memory into the buffer.
5523    Returns zero (success) or negative error code.  */
osst_copy_to_buffer(struct osst_buffer * st_bp,unsigned char * ptr)5524 static int osst_copy_to_buffer(struct osst_buffer *st_bp, unsigned char *ptr)
5525 {
5526 	int	i, cnt, do_count = OS_DATA_SIZE;
5527 
5528 	for (i = 0; i < st_bp->sg_segs && do_count > 0; i++) {
5529 		cnt = st_bp->sg[i].length < do_count ?
5530 		      st_bp->sg[i].length : do_count ;
5531 		memcpy(page_address(sg_page(&st_bp->sg[i])), ptr, cnt);
5532 		do_count -= cnt;
5533 		ptr      += cnt;
5534 	}
5535 	if (do_count || i != st_bp->sg_segs-1) {  /* Should never happen */
5536 		printk(KERN_WARNING "osst :A: Copy_to_buffer overflow (left %d at sg %d).\n",
5537 					 do_count, i);
5538 		return (-EIO);
5539 	}
5540 	return 0;
5541 }
5542 
5543 /* Copy a osst 32K chunk of memory from the buffer.
5544    Returns zero (success) or negative error code.  */
osst_copy_from_buffer(struct osst_buffer * st_bp,unsigned char * ptr)5545 static int osst_copy_from_buffer(struct osst_buffer *st_bp, unsigned char *ptr)
5546 {
5547 	int	i, cnt, do_count = OS_DATA_SIZE;
5548 
5549 	for (i = 0; i < st_bp->sg_segs && do_count > 0; i++) {
5550 		cnt = st_bp->sg[i].length < do_count ?
5551 		      st_bp->sg[i].length : do_count ;
5552 		memcpy(ptr, page_address(sg_page(&st_bp->sg[i])), cnt);
5553 		do_count -= cnt;
5554 		ptr      += cnt;
5555 	}
5556 	if (do_count || i != st_bp->sg_segs-1) {  /* Should never happen */
5557 		printk(KERN_WARNING "osst :A: Copy_from_buffer overflow (left %d at sg %d).\n",
5558 					 do_count, i);
5559 		return (-EIO);
5560 	}
5561 	return 0;
5562 }
5563 
5564 
5565 /* Module housekeeping */
5566 
validate_options(void)5567 static void validate_options (void)
5568 {
5569   if (max_dev > 0)
5570 		osst_max_dev = max_dev;
5571   if (write_threshold_kbs > 0)
5572 		osst_write_threshold = write_threshold_kbs * ST_KILOBYTE;
5573   if (osst_write_threshold > osst_buffer_size)
5574 		osst_write_threshold = osst_buffer_size;
5575   if (max_sg_segs >= OSST_FIRST_SG)
5576 		osst_max_sg_segs = max_sg_segs;
5577 #if DEBUG
5578   printk(OSST_DEB_MSG "osst :D: max tapes %d, write threshold %d, max s/g segs %d.\n",
5579 			   osst_max_dev, osst_write_threshold, osst_max_sg_segs);
5580 #endif
5581 }
5582 
5583 #ifndef MODULE
5584 /* Set the boot options. Syntax: osst=xxx,yyy,...
5585    where xxx is write threshold in 1024 byte blocks,
5586    and   yyy is number of s/g segments to use. */
osst_setup(char * str)5587 static int __init osst_setup (char *str)
5588 {
5589   int i, ints[5];
5590   char *stp;
5591 
5592   stp = get_options(str, ARRAY_SIZE(ints), ints);
5593 
5594   if (ints[0] > 0) {
5595 	for (i = 0; i < ints[0] && i < ARRAY_SIZE(parms); i++)
5596 		  *parms[i].val = ints[i + 1];
5597   } else {
5598 	while (stp != NULL) {
5599 		for (i = 0; i < ARRAY_SIZE(parms); i++) {
5600 			int len = strlen(parms[i].name);
5601 			if (!strncmp(stp, parms[i].name, len) &&
5602 			    (*(stp + len) == ':' || *(stp + len) == '=')) {
5603 				*parms[i].val =
5604 					simple_strtoul(stp + len + 1, NULL, 0);
5605 				break;
5606 			}
5607 		}
5608 		if (i >= ARRAY_SIZE(parms))
5609 			printk(KERN_INFO "osst :I: Illegal parameter in '%s'\n",
5610 			       stp);
5611 		stp = strchr(stp, ',');
5612 		if (stp)
5613 			stp++;
5614 	}
5615   }
5616 
5617   return 1;
5618 }
5619 
5620 __setup("osst=", osst_setup);
5621 
5622 #endif
5623 
5624 static const struct file_operations osst_fops = {
5625 	.owner =        THIS_MODULE,
5626 	.read =         osst_read,
5627 	.write =        osst_write,
5628 	.unlocked_ioctl = osst_ioctl,
5629 #ifdef CONFIG_COMPAT
5630 	.compat_ioctl = osst_compat_ioctl,
5631 #endif
5632 	.open =         os_scsi_tape_open,
5633 	.flush =        os_scsi_tape_flush,
5634 	.release =      os_scsi_tape_close,
5635 	.llseek =	noop_llseek,
5636 };
5637 
osst_supports(struct scsi_device * SDp)5638 static int osst_supports(struct scsi_device * SDp)
5639 {
5640 	struct	osst_support_data {
5641 		char *vendor;
5642 		char *model;
5643 		char *rev;
5644 		char *driver_hint; /* Name of the correct driver, NULL if unknown */
5645 	};
5646 
5647 static	struct	osst_support_data support_list[] = {
5648 		/* {"XXX", "Yy-", "", NULL},  example */
5649 		SIGS_FROM_OSST,
5650 		{NULL, }};
5651 
5652 	struct	osst_support_data *rp;
5653 
5654 	/* We are willing to drive OnStream SC-x0 as well as the
5655 	 * 	 * IDE, ParPort, FireWire, USB variants, if accessible by
5656 	 * 	 	 * emulation layer (ide-scsi, usb-storage, ...) */
5657 
5658 	for (rp=&(support_list[0]); rp->vendor != NULL; rp++)
5659 		if (!strncmp(rp->vendor, SDp->vendor, strlen(rp->vendor)) &&
5660 		    !strncmp(rp->model, SDp->model, strlen(rp->model)) &&
5661 		    !strncmp(rp->rev, SDp->rev, strlen(rp->rev)))
5662 			return 1;
5663 	return 0;
5664 }
5665 
5666 /*
5667  * sysfs support for osst driver parameter information
5668  */
5669 
version_show(struct device_driver * ddd,char * buf)5670 static ssize_t version_show(struct device_driver *ddd, char *buf)
5671 {
5672 	return snprintf(buf, PAGE_SIZE, "%s\n", osst_version);
5673 }
5674 
5675 static DRIVER_ATTR_RO(version);
5676 
osst_create_sysfs_files(struct device_driver * sysfs)5677 static int osst_create_sysfs_files(struct device_driver *sysfs)
5678 {
5679 	return driver_create_file(sysfs, &driver_attr_version);
5680 }
5681 
osst_remove_sysfs_files(struct device_driver * sysfs)5682 static void osst_remove_sysfs_files(struct device_driver *sysfs)
5683 {
5684 	driver_remove_file(sysfs, &driver_attr_version);
5685 }
5686 
5687 /*
5688  * sysfs support for accessing ADR header information
5689  */
5690 
osst_adr_rev_show(struct device * dev,struct device_attribute * attr,char * buf)5691 static ssize_t osst_adr_rev_show(struct device *dev,
5692 				 struct device_attribute *attr, char *buf)
5693 {
5694 	struct osst_tape * STp = (struct osst_tape *) dev_get_drvdata (dev);
5695 	ssize_t l = 0;
5696 
5697 	if (STp && STp->header_ok && STp->linux_media)
5698 		l = snprintf(buf, PAGE_SIZE, "%d.%d\n", STp->header_cache->major_rev, STp->header_cache->minor_rev);
5699 	return l;
5700 }
5701 
5702 DEVICE_ATTR(ADR_rev, S_IRUGO, osst_adr_rev_show, NULL);
5703 
osst_linux_media_version_show(struct device * dev,struct device_attribute * attr,char * buf)5704 static ssize_t osst_linux_media_version_show(struct device *dev,
5705 					     struct device_attribute *attr,
5706 					     char *buf)
5707 {
5708 	struct osst_tape * STp = (struct osst_tape *) dev_get_drvdata (dev);
5709 	ssize_t l = 0;
5710 
5711 	if (STp && STp->header_ok && STp->linux_media)
5712 		l = snprintf(buf, PAGE_SIZE, "LIN%d\n", STp->linux_media_version);
5713 	return l;
5714 }
5715 
5716 DEVICE_ATTR(media_version, S_IRUGO, osst_linux_media_version_show, NULL);
5717 
osst_capacity_show(struct device * dev,struct device_attribute * attr,char * buf)5718 static ssize_t osst_capacity_show(struct device *dev,
5719 				  struct device_attribute *attr, char *buf)
5720 {
5721 	struct osst_tape * STp = (struct osst_tape *) dev_get_drvdata (dev);
5722 	ssize_t l = 0;
5723 
5724 	if (STp && STp->header_ok && STp->linux_media)
5725 		l = snprintf(buf, PAGE_SIZE, "%d\n", STp->capacity);
5726 	return l;
5727 }
5728 
5729 DEVICE_ATTR(capacity, S_IRUGO, osst_capacity_show, NULL);
5730 
osst_first_data_ppos_show(struct device * dev,struct device_attribute * attr,char * buf)5731 static ssize_t osst_first_data_ppos_show(struct device *dev,
5732 					 struct device_attribute *attr,
5733 					 char *buf)
5734 {
5735 	struct osst_tape * STp = (struct osst_tape *) dev_get_drvdata (dev);
5736 	ssize_t l = 0;
5737 
5738 	if (STp && STp->header_ok && STp->linux_media)
5739 		l = snprintf(buf, PAGE_SIZE, "%d\n", STp->first_data_ppos);
5740 	return l;
5741 }
5742 
5743 DEVICE_ATTR(BOT_frame, S_IRUGO, osst_first_data_ppos_show, NULL);
5744 
osst_eod_frame_ppos_show(struct device * dev,struct device_attribute * attr,char * buf)5745 static ssize_t osst_eod_frame_ppos_show(struct device *dev,
5746 					struct device_attribute *attr,
5747 					char *buf)
5748 {
5749 	struct osst_tape * STp = (struct osst_tape *) dev_get_drvdata (dev);
5750 	ssize_t l = 0;
5751 
5752 	if (STp && STp->header_ok && STp->linux_media)
5753 		l = snprintf(buf, PAGE_SIZE, "%d\n", STp->eod_frame_ppos);
5754 	return l;
5755 }
5756 
5757 DEVICE_ATTR(EOD_frame, S_IRUGO, osst_eod_frame_ppos_show, NULL);
5758 
osst_filemark_cnt_show(struct device * dev,struct device_attribute * attr,char * buf)5759 static ssize_t osst_filemark_cnt_show(struct device *dev,
5760 				      struct device_attribute *attr, char *buf)
5761 {
5762 	struct osst_tape * STp = (struct osst_tape *) dev_get_drvdata (dev);
5763 	ssize_t l = 0;
5764 
5765 	if (STp && STp->header_ok && STp->linux_media)
5766 		l = snprintf(buf, PAGE_SIZE, "%d\n", STp->filemark_cnt);
5767 	return l;
5768 }
5769 
5770 DEVICE_ATTR(file_count, S_IRUGO, osst_filemark_cnt_show, NULL);
5771 
5772 static struct class *osst_sysfs_class;
5773 
osst_sysfs_init(void)5774 static int osst_sysfs_init(void)
5775 {
5776 	osst_sysfs_class = class_create(THIS_MODULE, "onstream_tape");
5777 	if (IS_ERR(osst_sysfs_class)) {
5778 		printk(KERN_ERR "osst :W: Unable to register sysfs class\n");
5779 		return PTR_ERR(osst_sysfs_class);
5780 	}
5781 
5782 	return 0;
5783 }
5784 
osst_sysfs_destroy(dev_t dev)5785 static void osst_sysfs_destroy(dev_t dev)
5786 {
5787 	device_destroy(osst_sysfs_class, dev);
5788 }
5789 
osst_sysfs_add(dev_t dev,struct device * device,struct osst_tape * STp,char * name)5790 static int osst_sysfs_add(dev_t dev, struct device *device, struct osst_tape * STp, char * name)
5791 {
5792 	struct device *osst_member;
5793 	int err;
5794 
5795 	osst_member = device_create(osst_sysfs_class, device, dev, STp,
5796 				    "%s", name);
5797 	if (IS_ERR(osst_member)) {
5798 		printk(KERN_WARNING "osst :W: Unable to add sysfs class member %s\n", name);
5799 		return PTR_ERR(osst_member);
5800 	}
5801 
5802 	err = device_create_file(osst_member, &dev_attr_ADR_rev);
5803 	if (err)
5804 		goto err_out;
5805 	err = device_create_file(osst_member, &dev_attr_media_version);
5806 	if (err)
5807 		goto err_out;
5808 	err = device_create_file(osst_member, &dev_attr_capacity);
5809 	if (err)
5810 		goto err_out;
5811 	err = device_create_file(osst_member, &dev_attr_BOT_frame);
5812 	if (err)
5813 		goto err_out;
5814 	err = device_create_file(osst_member, &dev_attr_EOD_frame);
5815 	if (err)
5816 		goto err_out;
5817 	err = device_create_file(osst_member, &dev_attr_file_count);
5818 	if (err)
5819 		goto err_out;
5820 
5821 	return 0;
5822 
5823 err_out:
5824 	osst_sysfs_destroy(dev);
5825 	return err;
5826 }
5827 
osst_sysfs_cleanup(void)5828 static void osst_sysfs_cleanup(void)
5829 {
5830 	class_destroy(osst_sysfs_class);
5831 }
5832 
5833 /*
5834  * osst startup / cleanup code
5835  */
5836 
osst_probe(struct device * dev)5837 static int osst_probe(struct device *dev)
5838 {
5839 	struct scsi_device * SDp = to_scsi_device(dev);
5840 	struct osst_tape   * tpnt;
5841 	struct st_modedef  * STm;
5842 	struct st_partstat * STps;
5843 	struct osst_buffer * buffer;
5844 	struct gendisk	   * drive;
5845 	int		     i, dev_num, err = -ENODEV;
5846 
5847 	if (SDp->type != TYPE_TAPE || !osst_supports(SDp))
5848 		return -ENODEV;
5849 
5850 	drive = alloc_disk(1);
5851 	if (!drive) {
5852 		printk(KERN_ERR "osst :E: Out of memory. Device not attached.\n");
5853 		return -ENODEV;
5854 	}
5855 
5856 	/* if this is the first attach, build the infrastructure */
5857 	write_lock(&os_scsi_tapes_lock);
5858 	if (os_scsi_tapes == NULL) {
5859 		os_scsi_tapes = kmalloc_array(osst_max_dev,
5860                                               sizeof(struct osst_tape *),
5861                                               GFP_ATOMIC);
5862 		if (os_scsi_tapes == NULL) {
5863 			write_unlock(&os_scsi_tapes_lock);
5864 			printk(KERN_ERR "osst :E: Unable to allocate array for OnStream SCSI tapes.\n");
5865 			goto out_put_disk;
5866 		}
5867 		for (i=0; i < osst_max_dev; ++i) os_scsi_tapes[i] = NULL;
5868 	}
5869 
5870 	if (osst_nr_dev >= osst_max_dev) {
5871 		write_unlock(&os_scsi_tapes_lock);
5872 		printk(KERN_ERR "osst :E: Too many tape devices (max. %d).\n", osst_max_dev);
5873 		goto out_put_disk;
5874 	}
5875 
5876 	/* find a free minor number */
5877 	for (i = 0; i < osst_max_dev && os_scsi_tapes[i]; i++)
5878 		;
5879 	if(i >= osst_max_dev) panic ("Scsi_devices corrupt (osst)");
5880 	dev_num = i;
5881 
5882 	/* allocate a struct osst_tape for this device */
5883 	tpnt = kzalloc(sizeof(struct osst_tape), GFP_ATOMIC);
5884 	if (!tpnt) {
5885 		write_unlock(&os_scsi_tapes_lock);
5886 		printk(KERN_ERR "osst :E: Can't allocate device descriptor, device not attached.\n");
5887 		goto out_put_disk;
5888 	}
5889 
5890 	/* allocate a buffer for this device */
5891 	i = SDp->host->sg_tablesize;
5892 	if (osst_max_sg_segs < i)
5893 		i = osst_max_sg_segs;
5894 	buffer = new_tape_buffer(1, SDp->host->unchecked_isa_dma, i);
5895 	if (buffer == NULL) {
5896 		write_unlock(&os_scsi_tapes_lock);
5897 		printk(KERN_ERR "osst :E: Unable to allocate a tape buffer, device not attached.\n");
5898 		kfree(tpnt);
5899 		goto out_put_disk;
5900 	}
5901 	os_scsi_tapes[dev_num] = tpnt;
5902 	tpnt->buffer = buffer;
5903 	tpnt->device = SDp;
5904 	drive->private_data = &tpnt->driver;
5905 	sprintf(drive->disk_name, "osst%d", dev_num);
5906 	tpnt->driver = &osst_template;
5907 	tpnt->drive = drive;
5908 	tpnt->in_use = 0;
5909 	tpnt->capacity = 0xfffff;
5910 	tpnt->dirty = 0;
5911 	tpnt->drv_buffer = 1;  /* Try buffering if no mode sense */
5912 	tpnt->restr_dma = (SDp->host)->unchecked_isa_dma;
5913 	tpnt->density = 0;
5914 	tpnt->do_auto_lock = OSST_AUTO_LOCK;
5915 	tpnt->can_bsr = OSST_IN_FILE_POS;
5916 	tpnt->can_partitions = 0;
5917 	tpnt->two_fm = OSST_TWO_FM;
5918 	tpnt->fast_mteom = OSST_FAST_MTEOM;
5919 	tpnt->scsi2_logical = OSST_SCSI2LOGICAL; /* FIXME */
5920 	tpnt->write_threshold = osst_write_threshold;
5921 	tpnt->default_drvbuffer = 0xff; /* No forced buffering */
5922 	tpnt->partition = 0;
5923 	tpnt->new_partition = 0;
5924 	tpnt->nbr_partitions = 0;
5925 	tpnt->min_block = 512;
5926 	tpnt->max_block = OS_DATA_SIZE;
5927 	tpnt->timeout = OSST_TIMEOUT;
5928 	tpnt->long_timeout = OSST_LONG_TIMEOUT;
5929 
5930 	/* Recognize OnStream tapes */
5931 	/* We don't need to test for OnStream, as this has been done in detect () */
5932 	tpnt->os_fw_rev = osst_parse_firmware_rev (SDp->rev);
5933 	tpnt->omit_blklims = 1;
5934 
5935 	tpnt->poll = (strncmp(SDp->model, "DI-", 3) == 0) ||
5936 		     (strncmp(SDp->model, "FW-", 3) == 0) || OSST_FW_NEED_POLL(tpnt->os_fw_rev,SDp);
5937 	tpnt->frame_in_buffer = 0;
5938 	tpnt->header_ok = 0;
5939 	tpnt->linux_media = 0;
5940 	tpnt->header_cache = NULL;
5941 
5942 	for (i=0; i < ST_NBR_MODES; i++) {
5943 		STm = &(tpnt->modes[i]);
5944 		STm->defined = 0;
5945 		STm->sysv = OSST_SYSV;
5946 		STm->defaults_for_writes = 0;
5947 		STm->do_async_writes = OSST_ASYNC_WRITES;
5948 		STm->do_buffer_writes = OSST_BUFFER_WRITES;
5949 		STm->do_read_ahead = OSST_READ_AHEAD;
5950 		STm->default_compression = ST_DONT_TOUCH;
5951 		STm->default_blksize = 512;
5952 		STm->default_density = (-1);  /* No forced density */
5953 	}
5954 
5955 	for (i=0; i < ST_NBR_PARTITIONS; i++) {
5956 		STps = &(tpnt->ps[i]);
5957 		STps->rw = ST_IDLE;
5958 		STps->eof = ST_NOEOF;
5959 		STps->at_sm = 0;
5960 		STps->last_block_valid = 0;
5961 		STps->drv_block = (-1);
5962 		STps->drv_file = (-1);
5963 	}
5964 
5965 	tpnt->current_mode = 0;
5966 	tpnt->modes[0].defined = 1;
5967 	tpnt->modes[2].defined = 1;
5968 	tpnt->density_changed = tpnt->compression_changed = tpnt->blksize_changed = 0;
5969 
5970 	mutex_init(&tpnt->lock);
5971 	osst_nr_dev++;
5972 	write_unlock(&os_scsi_tapes_lock);
5973 
5974 	{
5975 		char name[8];
5976 
5977 		/*  Rewind entry  */
5978 		err = osst_sysfs_add(MKDEV(OSST_MAJOR, dev_num), dev, tpnt, tape_name(tpnt));
5979 		if (err)
5980 			goto out_free_buffer;
5981 
5982 		/*  No-rewind entry  */
5983 		snprintf(name, 8, "%s%s", "n", tape_name(tpnt));
5984 		err = osst_sysfs_add(MKDEV(OSST_MAJOR, dev_num + 128), dev, tpnt, name);
5985 		if (err)
5986 			goto out_free_sysfs1;
5987 	}
5988 
5989 	sdev_printk(KERN_INFO, SDp,
5990 		"osst :I: Attached OnStream %.5s tape as %s\n",
5991 		SDp->model, tape_name(tpnt));
5992 
5993 	return 0;
5994 
5995 out_free_sysfs1:
5996 	osst_sysfs_destroy(MKDEV(OSST_MAJOR, dev_num));
5997 out_free_buffer:
5998 	kfree(buffer);
5999 out_put_disk:
6000         put_disk(drive);
6001         return err;
6002 };
6003 
osst_remove(struct device * dev)6004 static int osst_remove(struct device *dev)
6005 {
6006 	struct scsi_device * SDp = to_scsi_device(dev);
6007 	struct osst_tape * tpnt;
6008 	int i;
6009 
6010 	if ((SDp->type != TYPE_TAPE) || (osst_nr_dev <= 0))
6011 		return 0;
6012 
6013 	write_lock(&os_scsi_tapes_lock);
6014 	for(i=0; i < osst_max_dev; i++) {
6015 		if((tpnt = os_scsi_tapes[i]) && (tpnt->device == SDp)) {
6016 			osst_sysfs_destroy(MKDEV(OSST_MAJOR, i));
6017 			osst_sysfs_destroy(MKDEV(OSST_MAJOR, i+128));
6018 			tpnt->device = NULL;
6019 			put_disk(tpnt->drive);
6020 			os_scsi_tapes[i] = NULL;
6021 			osst_nr_dev--;
6022 			write_unlock(&os_scsi_tapes_lock);
6023 			vfree(tpnt->header_cache);
6024 			if (tpnt->buffer) {
6025 				normalize_buffer(tpnt->buffer);
6026 				kfree(tpnt->buffer);
6027 			}
6028 			kfree(tpnt);
6029 			return 0;
6030 		}
6031 	}
6032 	write_unlock(&os_scsi_tapes_lock);
6033 	return 0;
6034 }
6035 
init_osst(void)6036 static int __init init_osst(void)
6037 {
6038 	int err;
6039 
6040 	printk(KERN_INFO "osst :I: Tape driver with OnStream support version %s\nosst :I: %s\n", osst_version, cvsid);
6041 
6042 	validate_options();
6043 
6044 	err = osst_sysfs_init();
6045 	if (err)
6046 		return err;
6047 
6048 	err = register_chrdev(OSST_MAJOR, "osst", &osst_fops);
6049 	if (err < 0) {
6050 		printk(KERN_ERR "osst :E: Unable to register major %d for OnStream tapes\n", OSST_MAJOR);
6051 		goto err_out;
6052 	}
6053 
6054 	err = scsi_register_driver(&osst_template.gendrv);
6055 	if (err)
6056 		goto err_out_chrdev;
6057 
6058 	err = osst_create_sysfs_files(&osst_template.gendrv);
6059 	if (err)
6060 		goto err_out_scsidrv;
6061 
6062 	return 0;
6063 
6064 err_out_scsidrv:
6065 	scsi_unregister_driver(&osst_template.gendrv);
6066 err_out_chrdev:
6067 	unregister_chrdev(OSST_MAJOR, "osst");
6068 err_out:
6069 	osst_sysfs_cleanup();
6070 	return err;
6071 }
6072 
exit_osst(void)6073 static void __exit exit_osst (void)
6074 {
6075 	int i;
6076 	struct osst_tape * STp;
6077 
6078 	osst_remove_sysfs_files(&osst_template.gendrv);
6079 	scsi_unregister_driver(&osst_template.gendrv);
6080 	unregister_chrdev(OSST_MAJOR, "osst");
6081 	osst_sysfs_cleanup();
6082 
6083 	if (os_scsi_tapes) {
6084 		for (i=0; i < osst_max_dev; ++i) {
6085 			if (!(STp = os_scsi_tapes[i])) continue;
6086 			/* This is defensive, supposed to happen during detach */
6087 			vfree(STp->header_cache);
6088 			if (STp->buffer) {
6089 				normalize_buffer(STp->buffer);
6090 				kfree(STp->buffer);
6091 			}
6092 			put_disk(STp->drive);
6093 			kfree(STp);
6094 		}
6095 		kfree(os_scsi_tapes);
6096 	}
6097 	printk(KERN_INFO "osst :I: Unloaded.\n");
6098 }
6099 
6100 module_init(init_osst);
6101 module_exit(exit_osst);
6102