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