ide-tape.c 67.9 KB
Newer Older
L
Linus Torvalds 已提交
1
/*
2 3
 * IDE ATAPI streaming tape driver.
 *
4 5
 * Copyright (C) 1995-1999  Gadi Oxman <gadio@netvision.net.il>
 * Copyright (C) 2003-2005  Bartlomiej Zolnierkiewicz
L
Linus Torvalds 已提交
6 7 8 9 10 11 12 13
 *
 * This driver was constructed as a student project in the software laboratory
 * of the faculty of electrical engineering in the Technion - Israel's
 * Institute Of Technology, with the guide of Avner Lottem and Dr. Ilana David.
 *
 * It is hereby placed under the terms of the GNU general public license.
 * (See linux/COPYING).
 *
14 15
 * For a historical changelog see
 * Documentation/ide/ChangeLog.ide-tape.1995-2002
L
Linus Torvalds 已提交
16 17
 */

18 19
#define DRV_NAME "ide-tape"

20
#define IDETAPE_VERSION "1.20"
L
Linus Torvalds 已提交
21 22 23 24 25 26 27 28 29

#include <linux/module.h>
#include <linux/types.h>
#include <linux/string.h>
#include <linux/kernel.h>
#include <linux/delay.h>
#include <linux/timer.h>
#include <linux/mm.h>
#include <linux/interrupt.h>
30
#include <linux/jiffies.h>
L
Linus Torvalds 已提交
31 32 33 34 35 36 37 38 39
#include <linux/major.h>
#include <linux/errno.h>
#include <linux/genhd.h>
#include <linux/slab.h>
#include <linux/pci.h>
#include <linux/ide.h>
#include <linux/smp_lock.h>
#include <linux/completion.h>
#include <linux/bitops.h>
40
#include <linux/mutex.h>
41
#include <scsi/scsi.h>
L
Linus Torvalds 已提交
42 43

#include <asm/byteorder.h>
44 45 46
#include <linux/irq.h>
#include <linux/uaccess.h>
#include <linux/io.h>
L
Linus Torvalds 已提交
47 48 49
#include <asm/unaligned.h>
#include <linux/mtio.h>

50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73
enum {
	/* output errors only */
	DBG_ERR =		(1 << 0),
	/* output all sense key/asc */
	DBG_SENSE =		(1 << 1),
	/* info regarding all chrdev-related procedures */
	DBG_CHRDEV =		(1 << 2),
	/* all remaining procedures */
	DBG_PROCS =		(1 << 3),
};

/* define to see debug info */
#define IDETAPE_DEBUG_LOG		0

#if IDETAPE_DEBUG_LOG
#define debug_log(lvl, fmt, args...)			\
{							\
	if (tape->debug_mask & lvl)			\
	printk(KERN_INFO "ide-tape: " fmt, ## args);	\
}
#else
#define debug_log(lvl, fmt, args...) do {} while (0)
#endif

L
Linus Torvalds 已提交
74 75
/**************************** Tunable parameters *****************************/
/*
76 77
 * After each failed packet command we issue a request sense command and retry
 * the packet command IDETAPE_MAX_PC_RETRIES times.
L
Linus Torvalds 已提交
78
 *
79
 * Setting IDETAPE_MAX_PC_RETRIES to 0 will disable retries.
L
Linus Torvalds 已提交
80 81 82 83
 */
#define IDETAPE_MAX_PC_RETRIES		3

/*
84 85 86 87
 * The following parameter is used to select the point in the internal tape fifo
 * in which we will start to refill the buffer. Decreasing the following
 * parameter will improve the system's latency and interactive response, while
 * using a high value might improve system throughput.
L
Linus Torvalds 已提交
88
 */
89
#define IDETAPE_FIFO_THRESHOLD		2
L
Linus Torvalds 已提交
90 91

/*
92
 * DSC polling parameters.
L
Linus Torvalds 已提交
93
 *
94 95
 * Polling for DSC (a single bit in the status register) is a very important
 * function in ide-tape. There are two cases in which we poll for DSC:
L
Linus Torvalds 已提交
96
 *
97 98 99 100 101
 * 1. Before a read/write packet command, to ensure that we can transfer data
 * from/to the tape's data buffers, without causing an actual media access.
 * In case the tape is not ready yet, we take out our request from the device
 * request queue, so that ide.c could service requests from the other device
 * on the same interface in the meantime.
L
Linus Torvalds 已提交
102
 *
103 104 105 106 107 108 109 110
 * 2. After the successful initialization of a "media access packet command",
 * which is a command that can take a long time to complete (the interval can
 * range from several seconds to even an hour). Again, we postpone our request
 * in the middle to free the bus for the other device. The polling frequency
 * here should be lower than the read/write frequency since those media access
 * commands are slow. We start from a "fast" frequency - IDETAPE_DSC_MA_FAST
 * (1 second), and if we don't receive DSC after IDETAPE_DSC_MA_THRESHOLD
 * (5 min), we switch it to a lower frequency - IDETAPE_DSC_MA_SLOW (1 min).
L
Linus Torvalds 已提交
111
 *
112 113
 * We also set a timeout for the timer, in case something goes wrong. The
 * timeout should be longer then the maximum execution time of a tape operation.
L
Linus Torvalds 已提交
114
 */
115 116

/* DSC timings. */
L
Linus Torvalds 已提交
117 118 119 120 121 122 123 124 125 126
#define IDETAPE_DSC_RW_MIN		5*HZ/100	/* 50 msec */
#define IDETAPE_DSC_RW_MAX		40*HZ/100	/* 400 msec */
#define IDETAPE_DSC_RW_TIMEOUT		2*60*HZ		/* 2 minutes */
#define IDETAPE_DSC_MA_FAST		2*HZ		/* 2 seconds */
#define IDETAPE_DSC_MA_THRESHOLD	5*60*HZ		/* 5 minutes */
#define IDETAPE_DSC_MA_SLOW		30*HZ		/* 30 seconds */
#define IDETAPE_DSC_MA_TIMEOUT		2*60*60*HZ	/* 2 hours */

/*************************** End of tunable parameters ***********************/

127 128 129 130 131 132
/* tape directions */
enum {
	IDETAPE_DIR_NONE  = (1 << 0),
	IDETAPE_DIR_READ  = (1 << 1),
	IDETAPE_DIR_WRITE = (1 << 2),
};
L
Linus Torvalds 已提交
133 134

struct idetape_bh {
135
	u32 b_size;
L
Linus Torvalds 已提交
136 137 138 139 140
	atomic_t b_count;
	struct idetape_bh *b_reqnext;
	char *b_data;
};

141 142 143 144 145 146 147 148 149 150 151 152 153 154 155 156 157 158 159 160 161 162 163
/* Tape door status */
#define DOOR_UNLOCKED			0
#define DOOR_LOCKED			1
#define DOOR_EXPLICITLY_LOCKED		2

/* Some defines for the SPACE command */
#define IDETAPE_SPACE_OVER_FILEMARK	1
#define IDETAPE_SPACE_TO_EOD		3

/* Some defines for the LOAD UNLOAD command */
#define IDETAPE_LU_LOAD_MASK		1
#define IDETAPE_LU_RETENSION_MASK	2
#define IDETAPE_LU_EOT_MASK		4

/* Error codes returned in rq->errors to the higher part of the driver. */
#define IDETAPE_ERROR_GENERAL		101
#define IDETAPE_ERROR_FILEMARK		102
#define IDETAPE_ERROR_EOD		103

/* Structures related to the SELECT SENSE / MODE SENSE packet commands. */
#define IDETAPE_BLOCK_DESCRIPTOR	0
#define IDETAPE_CAPABILITIES_PAGE	0x2a

L
Linus Torvalds 已提交
164
/*
165 166
 * Most of our global data which we need to save even as we leave the driver due
 * to an interrupt or a timer event is stored in the struct defined below.
L
Linus Torvalds 已提交
167 168 169 170 171 172 173 174 175 176 177 178 179 180
 */
typedef struct ide_tape_obj {
	ide_drive_t	*drive;
	ide_driver_t	*driver;
	struct gendisk	*disk;
	struct kref	kref;

	/*
	 *	failed_pc points to the last failed packet command, or contains
	 *	NULL if we do not need to retry any packet command. This is
	 *	required since an additional packet command is needed before the
	 *	retry, to get detailed information on what went wrong.
	 */
	/* Last failed packet command */
181
	struct ide_atapi_pc *failed_pc;
182 183
	/* used by REQ_IDETAPE_{READ,WRITE} requests */
	struct ide_atapi_pc queued_pc;
184

L
Linus Torvalds 已提交
185
	/*
186
	 * DSC polling variables.
L
Linus Torvalds 已提交
187
	 *
188 189 190
	 * While polling for DSC we use postponed_rq to postpone the current
	 * request so that ide.c will be able to service pending requests on the
	 * other device. Note that at most we will have only one DSC (usually
191
	 * data transfer) request in the device request queue.
L
Linus Torvalds 已提交
192 193 194 195 196 197 198
	 */
	struct request *postponed_rq;
	/* The time in which we started polling for DSC */
	unsigned long dsc_polling_start;
	/* Timer used to poll for dsc */
	struct timer_list dsc_timer;
	/* Read/Write dsc polling frequency */
199 200
	unsigned long best_dsc_rw_freq;
	unsigned long dsc_poll_freq;
L
Linus Torvalds 已提交
201 202
	unsigned long dsc_timeout;

203
	/* Read position information */
L
Linus Torvalds 已提交
204 205
	u8 partition;
	/* Current block */
206
	unsigned int first_frame;
L
Linus Torvalds 已提交
207

208
	/* Last error information */
L
Linus Torvalds 已提交
209 210
	u8 sense_key, asc, ascq;

211
	/* Character device operation */
L
Linus Torvalds 已提交
212 213 214 215
	unsigned int minor;
	/* device name */
	char name[4];
	/* Current character device data transfer direction */
216
	u8 chrdev_dir;
L
Linus Torvalds 已提交
217

218 219
	/* tape block size, usually 512 or 1024 bytes */
	unsigned short blk_size;
L
Linus Torvalds 已提交
220
	int user_bs_factor;
221

L
Linus Torvalds 已提交
222
	/* Copy of the tape's Capabilities and Mechanical Page */
223
	u8 caps[20];
L
Linus Torvalds 已提交
224 225

	/*
226
	 * Active data transfer request parameters.
L
Linus Torvalds 已提交
227
	 *
228 229 230
	 * At most, there is only one ide-tape originated data transfer request
	 * in the device request queue. This allows ide.c to easily service
	 * requests from the other device when we postpone our active request.
L
Linus Torvalds 已提交
231
	 */
232

233
	/* Data buffer size chosen based on the tape's recommendation */
234
	int buffer_size;
235 236
	/* merge buffer */
	struct idetape_bh *merge_bh;
237 238
	/* size of the merge buffer */
	int merge_bh_size;
239
	/* pointer to current buffer head within the merge buffer */
L
Linus Torvalds 已提交
240 241 242
	struct idetape_bh *bh;
	char *b_data;
	int b_count;
243

244
	int pages_per_buffer;
L
Linus Torvalds 已提交
245 246 247 248
	/* Wasted space in each stage */
	int excess_bh_size;

	/* protects the ide-tape queue */
249
	spinlock_t lock;
L
Linus Torvalds 已提交
250

251
	/* Measures average tape speed */
L
Linus Torvalds 已提交
252 253 254 255 256 257 258 259 260 261 262
	unsigned long avg_time;
	int avg_size;
	int avg_speed;

	/* the door is currently locked */
	int door_locked;
	/* the tape hardware is write protected */
	char drv_write_prot;
	/* the tape is write protected (hardware or opened as read-only) */
	char write_prot;

263
	u32 debug_mask;
L
Linus Torvalds 已提交
264 265
} idetape_tape_t;

266
static DEFINE_MUTEX(idetape_ref_mutex);
L
Linus Torvalds 已提交
267

268 269
static struct class *idetape_sysfs_class;

L
Linus Torvalds 已提交
270 271 272 273 274
#define to_ide_tape(obj) container_of(obj, struct ide_tape_obj, kref)

#define ide_tape_g(disk) \
	container_of((disk)->private_data, struct ide_tape_obj, driver)

275 276
static void ide_tape_release(struct kref *);

L
Linus Torvalds 已提交
277 278 279 280
static struct ide_tape_obj *ide_tape_get(struct gendisk *disk)
{
	struct ide_tape_obj *tape = NULL;

281
	mutex_lock(&idetape_ref_mutex);
L
Linus Torvalds 已提交
282
	tape = ide_tape_g(disk);
283
	if (tape) {
284
		if (ide_device_get(tape->drive))
285
			tape = NULL;
286 287
		else
			kref_get(&tape->kref);
288
	}
289
	mutex_unlock(&idetape_ref_mutex);
L
Linus Torvalds 已提交
290 291 292 293 294
	return tape;
}

static void ide_tape_put(struct ide_tape_obj *tape)
{
295 296
	ide_drive_t *drive = tape->drive;

297
	mutex_lock(&idetape_ref_mutex);
L
Linus Torvalds 已提交
298
	kref_put(&tape->kref, ide_tape_release);
299
	ide_device_put(drive);
300
	mutex_unlock(&idetape_ref_mutex);
L
Linus Torvalds 已提交
301 302 303
}

/*
304 305
 * The variables below are used for the character device interface. Additional
 * state variables are defined in our ide_drive_t structure.
L
Linus Torvalds 已提交
306
 */
307
static struct ide_tape_obj *idetape_devs[MAX_HWIFS * MAX_DRIVES];
L
Linus Torvalds 已提交
308 309 310 311 312 313 314

#define ide_tape_f(file) ((file)->private_data)

static struct ide_tape_obj *ide_tape_chrdev_get(unsigned int i)
{
	struct ide_tape_obj *tape = NULL;

315
	mutex_lock(&idetape_ref_mutex);
L
Linus Torvalds 已提交
316 317 318
	tape = idetape_devs[i];
	if (tape)
		kref_get(&tape->kref);
319
	mutex_unlock(&idetape_ref_mutex);
L
Linus Torvalds 已提交
320 321 322
	return tape;
}

323
static void idetape_input_buffers(ide_drive_t *drive, struct ide_atapi_pc *pc,
324
				  unsigned int bcount)
L
Linus Torvalds 已提交
325 326 327 328 329 330 331 332
{
	struct idetape_bh *bh = pc->bh;
	int count;

	while (bcount) {
		if (bh == NULL) {
			printk(KERN_ERR "ide-tape: bh == NULL in "
				"idetape_input_buffers\n");
333
			ide_pad_transfer(drive, 0, bcount);
L
Linus Torvalds 已提交
334 335
			return;
		}
336 337 338
		count = min(
			(unsigned int)(bh->b_size - atomic_read(&bh->b_count)),
			bcount);
339
		drive->hwif->tp_ops->input_data(drive, NULL, bh->b_data +
340
					atomic_read(&bh->b_count), count);
L
Linus Torvalds 已提交
341 342 343 344 345 346 347 348 349 350 351
		bcount -= count;
		atomic_add(count, &bh->b_count);
		if (atomic_read(&bh->b_count) == bh->b_size) {
			bh = bh->b_reqnext;
			if (bh)
				atomic_set(&bh->b_count, 0);
		}
	}
	pc->bh = bh;
}

352
static void idetape_output_buffers(ide_drive_t *drive, struct ide_atapi_pc *pc,
353
				   unsigned int bcount)
L
Linus Torvalds 已提交
354 355 356 357 358 359
{
	struct idetape_bh *bh = pc->bh;
	int count;

	while (bcount) {
		if (bh == NULL) {
360 361
			printk(KERN_ERR "ide-tape: bh == NULL in %s\n",
					__func__);
L
Linus Torvalds 已提交
362 363 364
			return;
		}
		count = min((unsigned int)pc->b_count, (unsigned int)bcount);
365
		drive->hwif->tp_ops->output_data(drive, NULL, pc->b_data, count);
L
Linus Torvalds 已提交
366 367 368 369
		bcount -= count;
		pc->b_data += count;
		pc->b_count -= count;
		if (!pc->b_count) {
370 371
			bh = bh->b_reqnext;
			pc->bh = bh;
L
Linus Torvalds 已提交
372 373 374 375 376 377 378 379
			if (bh) {
				pc->b_data = bh->b_data;
				pc->b_count = atomic_read(&bh->b_count);
			}
		}
	}
}

380
static void idetape_update_buffers(ide_drive_t *drive, struct ide_atapi_pc *pc)
L
Linus Torvalds 已提交
381 382 383
{
	struct idetape_bh *bh = pc->bh;
	int count;
384
	unsigned int bcount = pc->xferred;
L
Linus Torvalds 已提交
385

386
	if (pc->flags & PC_FLAG_WRITING)
L
Linus Torvalds 已提交
387 388 389
		return;
	while (bcount) {
		if (bh == NULL) {
390 391
			printk(KERN_ERR "ide-tape: bh == NULL in %s\n",
					__func__);
L
Linus Torvalds 已提交
392 393 394 395 396 397 398 399 400 401 402 403
			return;
		}
		count = min((unsigned int)bh->b_size, (unsigned int)bcount);
		atomic_set(&bh->b_count, count);
		if (atomic_read(&bh->b_count) == bh->b_size)
			bh = bh->b_reqnext;
		bcount -= count;
	}
	pc->bh = bh;
}

/*
404 405
 * called on each failed packet command retry to analyze the request sense. We
 * currently do not utilize this information.
L
Linus Torvalds 已提交
406
 */
407
static void idetape_analyze_error(ide_drive_t *drive, u8 *sense)
L
Linus Torvalds 已提交
408 409
{
	idetape_tape_t *tape = drive->driver_data;
410
	struct ide_atapi_pc *pc = tape->failed_pc;
L
Linus Torvalds 已提交
411

412 413 414
	tape->sense_key = sense[2] & 0xF;
	tape->asc       = sense[12];
	tape->ascq      = sense[13];
415 416 417

	debug_log(DBG_ERR, "pc = %x, sense key = %x, asc = %x, ascq = %x\n",
		 pc->c[0], tape->sense_key, tape->asc, tape->ascq);
L
Linus Torvalds 已提交
418

419
	/* Correct pc->xferred by asking the tape.	 */
420
	if (pc->flags & PC_FLAG_DMA_ERROR) {
421
		pc->xferred = pc->req_xfer -
422
			tape->blk_size *
423
			get_unaligned_be32(&sense[3]);
424
		idetape_update_buffers(drive, pc);
L
Linus Torvalds 已提交
425 426 427 428 429 430 431
	}

	/*
	 * If error was the result of a zero-length read or write command,
	 * with sense key=5, asc=0x22, ascq=0, let it slide.  Some drives
	 * (i.e. Seagate STT3401A Travan) don't support 0-length read/writes.
	 */
432
	if ((pc->c[0] == READ_6 || pc->c[0] == WRITE_6)
433 434 435
	    /* length == 0 */
	    && pc->c[4] == 0 && pc->c[3] == 0 && pc->c[2] == 0) {
		if (tape->sense_key == 5) {
L
Linus Torvalds 已提交
436 437 438
			/* don't report an error, everything's ok */
			pc->error = 0;
			/* don't retry read/write */
439
			pc->flags |= PC_FLAG_ABORT;
L
Linus Torvalds 已提交
440 441
		}
	}
442
	if (pc->c[0] == READ_6 && (sense[2] & 0x80)) {
L
Linus Torvalds 已提交
443
		pc->error = IDETAPE_ERROR_FILEMARK;
444
		pc->flags |= PC_FLAG_ABORT;
L
Linus Torvalds 已提交
445
	}
446
	if (pc->c[0] == WRITE_6) {
447 448
		if ((sense[2] & 0x40) || (tape->sense_key == 0xd
		     && tape->asc == 0x0 && tape->ascq == 0x2)) {
L
Linus Torvalds 已提交
449
			pc->error = IDETAPE_ERROR_EOD;
450
			pc->flags |= PC_FLAG_ABORT;
L
Linus Torvalds 已提交
451 452
		}
	}
453
	if (pc->c[0] == READ_6 || pc->c[0] == WRITE_6) {
454
		if (tape->sense_key == 8) {
L
Linus Torvalds 已提交
455
			pc->error = IDETAPE_ERROR_EOD;
456
			pc->flags |= PC_FLAG_ABORT;
L
Linus Torvalds 已提交
457
		}
458
		if (!(pc->flags & PC_FLAG_ABORT) &&
459
		    pc->xferred)
L
Linus Torvalds 已提交
460 461 462 463
			pc->retries = IDETAPE_MAX_PC_RETRIES + 1;
	}
}

464
/* Free data buffers completely. */
465
static void ide_tape_kfree_buffer(idetape_tape_t *tape)
L
Linus Torvalds 已提交
466
{
467
	struct idetape_bh *prev_bh, *bh = tape->merge_bh;
468 469 470 471 472 473 474 475 476 477 478 479

	while (bh) {
		u32 size = bh->b_size;

		while (size) {
			unsigned int order = fls(size >> PAGE_SHIFT)-1;

			if (bh->b_data)
				free_pages((unsigned long)bh->b_data, order);

			size &= (order-1);
			bh->b_data += (1 << order) * PAGE_SIZE;
L
Linus Torvalds 已提交
480 481 482 483 484 485 486 487 488 489 490 491 492 493
		}
		prev_bh = bh;
		bh = bh->b_reqnext;
		kfree(prev_bh);
	}
}

static int idetape_end_request(ide_drive_t *drive, int uptodate, int nr_sects)
{
	struct request *rq = HWGROUP(drive)->rq;
	idetape_tape_t *tape = drive->driver_data;
	unsigned long flags;
	int error;

494
	debug_log(DBG_PROCS, "Enter %s\n", __func__);
L
Linus Torvalds 已提交
495 496

	switch (uptodate) {
497 498 499
	case 0:	error = IDETAPE_ERROR_GENERAL; break;
	case 1: error = 0; break;
	default: error = uptodate;
L
Linus Torvalds 已提交
500 501 502 503 504
	}
	rq->errors = error;
	if (error)
		tape->failed_pc = NULL;

505 506 507 508 509
	if (!blk_special_request(rq)) {
		ide_end_request(drive, uptodate, nr_sects);
		return 0;
	}

510
	spin_lock_irqsave(&tape->lock, flags);
L
Linus Torvalds 已提交
511 512 513

	ide_end_drive_cmd(drive, 0, 0);

514
	spin_unlock_irqrestore(&tape->lock, flags);
L
Linus Torvalds 已提交
515 516 517
	return 0;
}

518 519 520
static void ide_tape_handle_dsc(ide_drive_t *);

static void ide_tape_callback(ide_drive_t *drive, int dsc)
L
Linus Torvalds 已提交
521 522
{
	idetape_tape_t *tape = drive->driver_data;
523
	struct ide_atapi_pc *pc = drive->pc;
524
	int uptodate = pc->error ? 0 : 1;
L
Linus Torvalds 已提交
525

526 527
	debug_log(DBG_PROCS, "Enter %s\n", __func__);

528 529 530
	if (dsc)
		ide_tape_handle_dsc(drive);

531 532 533
	if (tape->failed_pc == pc)
		tape->failed_pc = NULL;

534 535 536 537 538 539 540 541 542 543 544 545 546 547 548 549 550 551 552 553 554 555 556 557 558
	if (pc->c[0] == REQUEST_SENSE) {
		if (uptodate)
			idetape_analyze_error(drive, pc->buf);
		else
			printk(KERN_ERR "ide-tape: Error in REQUEST SENSE "
					"itself - Aborting request!\n");
	} else if (pc->c[0] == READ_6 || pc->c[0] == WRITE_6) {
		struct request *rq = drive->hwif->hwgroup->rq;
		int blocks = pc->xferred / tape->blk_size;

		tape->avg_size += blocks * tape->blk_size;

		if (time_after_eq(jiffies, tape->avg_time + HZ)) {
			tape->avg_speed = tape->avg_size * HZ /
				(jiffies - tape->avg_time) / 1024;
			tape->avg_size = 0;
			tape->avg_time = jiffies;
		}

		tape->first_frame += blocks;
		rq->current_nr_sectors -= blocks;

		if (pc->error)
			uptodate = pc->error;
	} else if (pc->c[0] == READ_POSITION && uptodate) {
559
		u8 *readpos = pc->buf;
560 561 562 563 564 565 566 567 568

		debug_log(DBG_SENSE, "BOP - %s\n",
				(readpos[0] & 0x80) ? "Yes" : "No");
		debug_log(DBG_SENSE, "EOP - %s\n",
				(readpos[0] & 0x40) ? "Yes" : "No");

		if (readpos[0] & 0x4) {
			printk(KERN_INFO "ide-tape: Block location is unknown"
					 "to the tape\n");
569
			clear_bit(IDE_AFLAG_ADDRESS_VALID, &drive->atapi_flags);
570 571 572
			uptodate = 0;
		} else {
			debug_log(DBG_SENSE, "Block Location - %u\n",
573
					be32_to_cpup((__be32 *)&readpos[4]));
574 575

			tape->partition = readpos[1];
576
			tape->first_frame = be32_to_cpup((__be32 *)&readpos[4]);
577
			set_bit(IDE_AFLAG_ADDRESS_VALID, &drive->atapi_flags);
578
		}
L
Linus Torvalds 已提交
579
	}
580 581

	idetape_end_request(drive, uptodate, 0);
L
Linus Torvalds 已提交
582 583
}

584
static void idetape_create_request_sense_cmd(struct ide_atapi_pc *pc)
L
Linus Torvalds 已提交
585
{
586
	ide_init_pc(pc);
587
	pc->c[0] = REQUEST_SENSE;
L
Linus Torvalds 已提交
588
	pc->c[4] = 20;
589
	pc->req_xfer = 20;
L
Linus Torvalds 已提交
590 591 592 593 594 595 596
}

/*
 *	idetape_retry_pc is called when an error was detected during the
 *	last packet command. We queue a request sense packet command in
 *	the head of the request list.
 */
597
static void idetape_retry_pc(ide_drive_t *drive)
L
Linus Torvalds 已提交
598
{
599
	struct ide_tape_obj *tape = drive->driver_data;
600 601
	struct request *rq = &drive->request_sense_rq;
	struct ide_atapi_pc *pc = &drive->request_sense_pc;
L
Linus Torvalds 已提交
602

603
	(void)ide_read_error(drive);
L
Linus Torvalds 已提交
604
	idetape_create_request_sense_cmd(pc);
605
	set_bit(IDE_AFLAG_IGNORE_DSC, &drive->atapi_flags);
606
	ide_queue_pc_head(drive, tape->disk, pc, rq);
L
Linus Torvalds 已提交
607 608 609
}

/*
610 611
 * Postpone the current request so that ide.c will be able to service requests
 * from another device on the same hwgroup while we are polling for DSC.
L
Linus Torvalds 已提交
612
 */
613
static void idetape_postpone_request(ide_drive_t *drive)
L
Linus Torvalds 已提交
614 615 616
{
	idetape_tape_t *tape = drive->driver_data;

617 618
	debug_log(DBG_PROCS, "Enter %s\n", __func__);

L
Linus Torvalds 已提交
619
	tape->postponed_rq = HWGROUP(drive)->rq;
620
	ide_stall_queue(drive, tape->dsc_poll_freq);
L
Linus Torvalds 已提交
621 622
}

623 624 625 626 627 628 629 630 631 632 633 634
static void ide_tape_handle_dsc(ide_drive_t *drive)
{
	idetape_tape_t *tape = drive->driver_data;

	/* Media access command */
	tape->dsc_polling_start = jiffies;
	tape->dsc_poll_freq = IDETAPE_DSC_MA_FAST;
	tape->dsc_timeout = jiffies + IDETAPE_DSC_MA_TIMEOUT;
	/* Allow ide.c to handle other requests */
	idetape_postpone_request(drive);
}

635
static int ide_tape_io_buffers(ide_drive_t *drive, struct ide_atapi_pc *pc,
636 637 638 639 640 641
				unsigned int bcount, int write)
{
	if (write)
		idetape_output_buffers(drive, pc, bcount);
	else
		idetape_input_buffers(drive, pc, bcount);
642 643

	return bcount;
644
}
645

L
Linus Torvalds 已提交
646
/*
647 648 649 650
 * This is the usual interrupt handler which will be called during a packet
 * command. We will transfer some of the data (as requested by the drive) and
 * will re-point interrupt handler to us. When data transfer is finished, we
 * will act according to the algorithm described before
651
 * idetape_issue_pc.
L
Linus Torvalds 已提交
652
 */
653
static ide_startstop_t idetape_pc_intr(ide_drive_t *drive)
L
Linus Torvalds 已提交
654
{
655 656
	return ide_pc_intr(drive, idetape_pc_intr, idetape_update_buffers,
			   idetape_retry_pc, ide_tape_io_buffers);
L
Linus Torvalds 已提交
657 658 659
}

/*
660
 * Packet Command Interface
L
Linus Torvalds 已提交
661
 *
662
 * The current Packet Command is available in drive->pc, and will not change
663 664
 * until we finish handling it. Each packet command is associated with a
 * callback function that will be called when the command is finished.
L
Linus Torvalds 已提交
665
 *
666
 * The handling will be done in three stages:
L
Linus Torvalds 已提交
667
 *
668 669
 * 1. idetape_issue_pc will send the packet command to the drive, and will set
 * the interrupt handler to idetape_pc_intr.
L
Linus Torvalds 已提交
670
 *
671 672
 * 2. On each interrupt, idetape_pc_intr will be called. This step will be
 * repeated until the device signals us that no more interrupts will be issued.
L
Linus Torvalds 已提交
673
 *
674 675 676 677 678 679 680
 * 3. ATAPI Tape media access commands have immediate status with a delayed
 * process. In case of a successful initiation of a media access packet command,
 * the DSC bit will be set when the actual execution of the command is finished.
 * Since the tape drive will not issue an interrupt, we have to poll for this
 * event. In this case, we define the request as "low priority request" by
 * setting rq_status to IDETAPE_RQ_POSTPONED, set a timer to poll for DSC and
 * exit the driver.
L
Linus Torvalds 已提交
681
 *
682 683
 * ide.c will then give higher priority to requests which originate from the
 * other device, until will change rq_status to RQ_ACTIVE.
L
Linus Torvalds 已提交
684
 *
685
 * 4. When the packet command is finished, it will be checked for errors.
L
Linus Torvalds 已提交
686
 *
687 688 689
 * 5. In case an error was found, we queue a request sense packet command in
 * front of the request queue and retry the operation up to
 * IDETAPE_MAX_PC_RETRIES times.
L
Linus Torvalds 已提交
690
 *
691 692 693
 * 6. In case no error was found, or we decided to give up and not to retry
 * again, the callback function will be called and then we will handle the next
 * request.
L
Linus Torvalds 已提交
694 695 696
 */
static ide_startstop_t idetape_transfer_pc(ide_drive_t *drive)
{
697
	return ide_transfer_pc(drive, idetape_pc_intr, WAIT_TAPE_CMD, NULL);
L
Linus Torvalds 已提交
698 699
}

700 701
static ide_startstop_t idetape_issue_pc(ide_drive_t *drive,
		struct ide_atapi_pc *pc)
L
Linus Torvalds 已提交
702 703 704
{
	idetape_tape_t *tape = drive->driver_data;

705
	if (drive->pc->c[0] == REQUEST_SENSE &&
706
	    pc->c[0] == REQUEST_SENSE) {
L
Linus Torvalds 已提交
707 708 709 710
		printk(KERN_ERR "ide-tape: possible ide-tape.c bug - "
			"Two request sense in serial were issued\n");
	}

711
	if (tape->failed_pc == NULL && pc->c[0] != REQUEST_SENSE)
L
Linus Torvalds 已提交
712
		tape->failed_pc = pc;
713

L
Linus Torvalds 已提交
714
	/* Set the current packet command */
715
	drive->pc = pc;
L
Linus Torvalds 已提交
716 717

	if (pc->retries > IDETAPE_MAX_PC_RETRIES ||
718
		(pc->flags & PC_FLAG_ABORT)) {
L
Linus Torvalds 已提交
719
		/*
720 721 722
		 * We will "abort" retrying a packet command in case legitimate
		 * error code was received (crossing a filemark, or end of the
		 * media, for example).
L
Linus Torvalds 已提交
723
		 */
724
		if (!(pc->flags & PC_FLAG_ABORT)) {
725
			if (!(pc->c[0] == TEST_UNIT_READY &&
L
Linus Torvalds 已提交
726 727 728 729 730 731 732 733 734 735 736 737 738
			      tape->sense_key == 2 && tape->asc == 4 &&
			     (tape->ascq == 1 || tape->ascq == 8))) {
				printk(KERN_ERR "ide-tape: %s: I/O error, "
						"pc = %2x, key = %2x, "
						"asc = %2x, ascq = %2x\n",
						tape->name, pc->c[0],
						tape->sense_key, tape->asc,
						tape->ascq);
			}
			/* Giving up */
			pc->error = IDETAPE_ERROR_GENERAL;
		}
		tape->failed_pc = NULL;
739
		drive->pc_callback(drive, 0);
740
		return ide_stopped;
L
Linus Torvalds 已提交
741
	}
742
	debug_log(DBG_SENSE, "Retry #%d, cmd = %02X\n", pc->retries, pc->c[0]);
L
Linus Torvalds 已提交
743 744 745

	pc->retries++;

746
	return ide_issue_pc(drive, idetape_transfer_pc, WAIT_TAPE_CMD, NULL);
L
Linus Torvalds 已提交
747 748
}

749
/* A mode sense command is used to "sense" tape parameters. */
750
static void idetape_create_mode_sense_cmd(struct ide_atapi_pc *pc, u8 page_code)
L
Linus Torvalds 已提交
751
{
752
	ide_init_pc(pc);
753
	pc->c[0] = MODE_SENSE;
L
Linus Torvalds 已提交
754
	if (page_code != IDETAPE_BLOCK_DESCRIPTOR)
755 756
		/* DBD = 1 - Don't return block descriptors */
		pc->c[1] = 8;
L
Linus Torvalds 已提交
757 758 759 760 761 762 763 764 765
	pc->c[2] = page_code;
	/*
	 * Changed pc->c[3] to 0 (255 will at best return unused info).
	 *
	 * For SCSI this byte is defined as subpage instead of high byte
	 * of length and some IDE drives seem to interpret it this way
	 * and return an error when 255 is used.
	 */
	pc->c[3] = 0;
766 767
	/* We will just discard data in that case */
	pc->c[4] = 255;
L
Linus Torvalds 已提交
768
	if (page_code == IDETAPE_BLOCK_DESCRIPTOR)
769
		pc->req_xfer = 12;
L
Linus Torvalds 已提交
770
	else if (page_code == IDETAPE_CAPABILITIES_PAGE)
771
		pc->req_xfer = 24;
L
Linus Torvalds 已提交
772
	else
773
		pc->req_xfer = 50;
L
Linus Torvalds 已提交
774 775
}

776
static ide_startstop_t idetape_media_access_finished(ide_drive_t *drive)
L
Linus Torvalds 已提交
777
{
778
	ide_hwif_t *hwif = drive->hwif;
L
Linus Torvalds 已提交
779
	idetape_tape_t *tape = drive->driver_data;
780
	struct ide_atapi_pc *pc = drive->pc;
781
	u8 stat;
L
Linus Torvalds 已提交
782

783
	stat = hwif->tp_ops->read_status(hwif);
784

785 786
	if (stat & ATA_DSC) {
		if (stat & ATA_ERR) {
L
Linus Torvalds 已提交
787
			/* Error detected */
788
			if (pc->c[0] != TEST_UNIT_READY)
L
Linus Torvalds 已提交
789 790 791
				printk(KERN_ERR "ide-tape: %s: I/O error, ",
						tape->name);
			/* Retry operation */
792 793
			idetape_retry_pc(drive);
			return ide_stopped;
L
Linus Torvalds 已提交
794 795 796 797 798 799
		}
		pc->error = 0;
	} else {
		pc->error = IDETAPE_ERROR_GENERAL;
		tape->failed_pc = NULL;
	}
800
	drive->pc_callback(drive, 0);
L
Linus Torvalds 已提交
801 802 803
	return ide_stopped;
}

804
static void ide_tape_create_rw_cmd(idetape_tape_t *tape,
805 806
				   struct ide_atapi_pc *pc, struct request *rq,
				   u8 opcode)
L
Linus Torvalds 已提交
807
{
808 809 810
	struct idetape_bh *bh = (struct idetape_bh *)rq->special;
	unsigned int length = rq->current_nr_sectors;

811
	ide_init_pc(pc);
812
	put_unaligned(cpu_to_be32(length), (unsigned int *) &pc->c[1]);
L
Linus Torvalds 已提交
813 814
	pc->c[1] = 1;
	pc->bh = bh;
815 816 817
	pc->buf = NULL;
	pc->buf_size = length * tape->blk_size;
	pc->req_xfer = pc->buf_size;
818
	if (pc->req_xfer == tape->buffer_size)
819
		pc->flags |= PC_FLAG_DMA_OK;
L
Linus Torvalds 已提交
820

821 822 823 824 825 826 827 828 829
	if (opcode == READ_6) {
		pc->c[0] = READ_6;
		atomic_set(&bh->b_count, 0);
	} else if (opcode == WRITE_6) {
		pc->c[0] = WRITE_6;
		pc->flags |= PC_FLAG_WRITING;
		pc->b_data = bh->b_data;
		pc->b_count = atomic_read(&bh->b_count);
	}
830 831

	memcpy(rq->cmd, pc->c, 12);
L
Linus Torvalds 已提交
832 833 834 835 836
}

static ide_startstop_t idetape_do_request(ide_drive_t *drive,
					  struct request *rq, sector_t block)
{
837
	ide_hwif_t *hwif = drive->hwif;
L
Linus Torvalds 已提交
838
	idetape_tape_t *tape = drive->driver_data;
839
	struct ide_atapi_pc *pc = NULL;
L
Linus Torvalds 已提交
840
	struct request *postponed_rq = tape->postponed_rq;
841
	u8 stat;
L
Linus Torvalds 已提交
842

843 844 845 846
	debug_log(DBG_SENSE, "sector: %llu, nr_sectors: %lu,"
			" current_nr_sectors: %u\n",
			(unsigned long long)rq->sector, rq->nr_sectors,
			rq->current_nr_sectors);
L
Linus Torvalds 已提交
847

848
	if (!blk_special_request(rq)) {
849
		/* We do not support buffer cache originated requests. */
L
Linus Torvalds 已提交
850
		printk(KERN_NOTICE "ide-tape: %s: Unsupported request in "
851
			"request queue (%d)\n", drive->name, rq->cmd_type);
L
Linus Torvalds 已提交
852 853 854 855
		ide_end_request(drive, 0, 0);
		return ide_stopped;
	}

856
	/* Retry a failed packet command */
857
	if (tape->failed_pc && drive->pc->c[0] == REQUEST_SENSE) {
858 859 860
		pc = tape->failed_pc;
		goto out;
	}
861

L
Linus Torvalds 已提交
862 863 864 865 866 867 868 869 870 871 872 873 874 875
	if (postponed_rq != NULL)
		if (rq != postponed_rq) {
			printk(KERN_ERR "ide-tape: ide-tape.c bug - "
					"Two DSC requests were queued\n");
			idetape_end_request(drive, 0, 0);
			return ide_stopped;
		}

	tape->postponed_rq = NULL;

	/*
	 * If the tape is still busy, postpone our request and service
	 * the other device meanwhile.
	 */
876
	stat = hwif->tp_ops->read_status(hwif);
L
Linus Torvalds 已提交
877

878
	if (!drive->dsc_overlap && !(rq->cmd[13] & REQ_IDETAPE_PC2))
879
		set_bit(IDE_AFLAG_IGNORE_DSC, &drive->atapi_flags);
L
Linus Torvalds 已提交
880 881

	if (drive->post_reset == 1) {
882
		set_bit(IDE_AFLAG_IGNORE_DSC, &drive->atapi_flags);
L
Linus Torvalds 已提交
883 884 885
		drive->post_reset = 0;
	}

886
	if (!test_and_clear_bit(IDE_AFLAG_IGNORE_DSC, &drive->atapi_flags) &&
887
	    (stat & ATA_DSC) == 0) {
L
Linus Torvalds 已提交
888 889
		if (postponed_rq == NULL) {
			tape->dsc_polling_start = jiffies;
890
			tape->dsc_poll_freq = tape->best_dsc_rw_freq;
L
Linus Torvalds 已提交
891 892 893 894
			tape->dsc_timeout = jiffies + IDETAPE_DSC_RW_TIMEOUT;
		} else if (time_after(jiffies, tape->dsc_timeout)) {
			printk(KERN_ERR "ide-tape: %s: DSC timeout\n",
				tape->name);
895
			if (rq->cmd[13] & REQ_IDETAPE_PC2) {
L
Linus Torvalds 已提交
896 897 898 899 900
				idetape_media_access_finished(drive);
				return ide_stopped;
			} else {
				return ide_do_reset(drive);
			}
901 902 903
		} else if (time_after(jiffies,
					tape->dsc_polling_start +
					IDETAPE_DSC_MA_THRESHOLD))
904
			tape->dsc_poll_freq = IDETAPE_DSC_MA_SLOW;
L
Linus Torvalds 已提交
905 906 907
		idetape_postpone_request(drive);
		return ide_stopped;
	}
908
	if (rq->cmd[13] & REQ_IDETAPE_READ) {
909
		pc = &tape->queued_pc;
910
		ide_tape_create_rw_cmd(tape, pc, rq, READ_6);
L
Linus Torvalds 已提交
911 912
		goto out;
	}
913
	if (rq->cmd[13] & REQ_IDETAPE_WRITE) {
914
		pc = &tape->queued_pc;
915
		ide_tape_create_rw_cmd(tape, pc, rq, WRITE_6);
L
Linus Torvalds 已提交
916 917
		goto out;
	}
918
	if (rq->cmd[13] & REQ_IDETAPE_PC1) {
919
		pc = (struct ide_atapi_pc *) rq->buffer;
920 921
		rq->cmd[13] &= ~(REQ_IDETAPE_PC1);
		rq->cmd[13] |= REQ_IDETAPE_PC2;
L
Linus Torvalds 已提交
922 923
		goto out;
	}
924
	if (rq->cmd[13] & REQ_IDETAPE_PC2) {
L
Linus Torvalds 已提交
925 926 927 928
		idetape_media_access_finished(drive);
		return ide_stopped;
	}
	BUG();
929

930
out:
931
	return idetape_issue_pc(drive, pc);
L
Linus Torvalds 已提交
932 933 934
}

/*
935
 * The function below uses __get_free_pages to allocate a data buffer of size
936
 * tape->buffer_size (or a bit more). We attempt to combine sequential pages as
937
 * much as possible.
L
Linus Torvalds 已提交
938
 *
939 940
 * It returns a pointer to the newly allocated buffer, or NULL in case of
 * failure.
L
Linus Torvalds 已提交
941
 */
942 943
static struct idetape_bh *ide_tape_kmalloc_buffer(idetape_tape_t *tape,
						  int full, int clear)
L
Linus Torvalds 已提交
944
{
945
	struct idetape_bh *prev_bh, *bh, *merge_bh;
946
	int pages = tape->pages_per_buffer;
947
	unsigned int order, b_allocd;
L
Linus Torvalds 已提交
948 949
	char *b_data = NULL;

950 951
	merge_bh = kmalloc(sizeof(struct idetape_bh), GFP_KERNEL);
	bh = merge_bh;
L
Linus Torvalds 已提交
952 953
	if (bh == NULL)
		goto abort;
954 955 956

	order = fls(pages) - 1;
	bh->b_data = (char *) __get_free_pages(GFP_KERNEL, order);
957
	if (!bh->b_data)
L
Linus Torvalds 已提交
958
		goto abort;
959 960 961
	b_allocd = (1 << order) * PAGE_SIZE;
	pages &= (order-1);

L
Linus Torvalds 已提交
962
	if (clear)
963 964 965
		memset(bh->b_data, 0, b_allocd);
	bh->b_reqnext = NULL;
	bh->b_size = b_allocd;
L
Linus Torvalds 已提交
966 967
	atomic_set(&bh->b_count, full ? bh->b_size : 0);

968 969 970
	while (pages) {
		order = fls(pages) - 1;
		b_data = (char *) __get_free_pages(GFP_KERNEL, order);
971
		if (!b_data)
L
Linus Torvalds 已提交
972
			goto abort;
973 974
		b_allocd = (1 << order) * PAGE_SIZE;

L
Linus Torvalds 已提交
975
		if (clear)
976 977 978 979 980 981
			memset(b_data, 0, b_allocd);

		/* newly allocated page frames below buffer header or ...*/
		if (bh->b_data == b_data + b_allocd) {
			bh->b_size += b_allocd;
			bh->b_data -= b_allocd;
L
Linus Torvalds 已提交
982
			if (full)
983
				atomic_add(b_allocd, &bh->b_count);
L
Linus Torvalds 已提交
984 985
			continue;
		}
986
		/* they are above the header */
L
Linus Torvalds 已提交
987
		if (b_data == bh->b_data + bh->b_size) {
988
			bh->b_size += b_allocd;
L
Linus Torvalds 已提交
989
			if (full)
990
				atomic_add(b_allocd, &bh->b_count);
L
Linus Torvalds 已提交
991 992 993
			continue;
		}
		prev_bh = bh;
994 995
		bh = kmalloc(sizeof(struct idetape_bh), GFP_KERNEL);
		if (!bh) {
996
			free_pages((unsigned long) b_data, order);
L
Linus Torvalds 已提交
997 998 999 1000
			goto abort;
		}
		bh->b_reqnext = NULL;
		bh->b_data = b_data;
1001
		bh->b_size = b_allocd;
L
Linus Torvalds 已提交
1002 1003
		atomic_set(&bh->b_count, full ? bh->b_size : 0);
		prev_bh->b_reqnext = bh;
1004 1005

		pages &= (order-1);
L
Linus Torvalds 已提交
1006
	}
1007

L
Linus Torvalds 已提交
1008 1009 1010
	bh->b_size -= tape->excess_bh_size;
	if (full)
		atomic_sub(tape->excess_bh_size, &bh->b_count);
1011
	return merge_bh;
L
Linus Torvalds 已提交
1012
abort:
1013
	ide_tape_kfree_buffer(tape);
L
Linus Torvalds 已提交
1014 1015 1016
	return NULL;
}

1017
static int idetape_copy_stage_from_user(idetape_tape_t *tape,
1018
					const char __user *buf, int n)
L
Linus Torvalds 已提交
1019 1020 1021
{
	struct idetape_bh *bh = tape->bh;
	int count;
1022
	int ret = 0;
L
Linus Torvalds 已提交
1023 1024 1025

	while (n) {
		if (bh == NULL) {
1026 1027
			printk(KERN_ERR "ide-tape: bh == NULL in %s\n",
					__func__);
1028
			return 1;
L
Linus Torvalds 已提交
1029
		}
1030 1031 1032 1033 1034
		count = min((unsigned int)
				(bh->b_size - atomic_read(&bh->b_count)),
				(unsigned int)n);
		if (copy_from_user(bh->b_data + atomic_read(&bh->b_count), buf,
				count))
1035
			ret = 1;
L
Linus Torvalds 已提交
1036 1037 1038 1039 1040 1041 1042 1043 1044 1045
		n -= count;
		atomic_add(count, &bh->b_count);
		buf += count;
		if (atomic_read(&bh->b_count) == bh->b_size) {
			bh = bh->b_reqnext;
			if (bh)
				atomic_set(&bh->b_count, 0);
		}
	}
	tape->bh = bh;
1046
	return ret;
L
Linus Torvalds 已提交
1047 1048
}

1049
static int idetape_copy_stage_to_user(idetape_tape_t *tape, char __user *buf,
1050
				      int n)
L
Linus Torvalds 已提交
1051 1052 1053
{
	struct idetape_bh *bh = tape->bh;
	int count;
1054
	int ret = 0;
L
Linus Torvalds 已提交
1055 1056 1057

	while (n) {
		if (bh == NULL) {
1058 1059
			printk(KERN_ERR "ide-tape: bh == NULL in %s\n",
					__func__);
1060
			return 1;
L
Linus Torvalds 已提交
1061 1062
		}
		count = min(tape->b_count, n);
1063 1064
		if  (copy_to_user(buf, tape->b_data, count))
			ret = 1;
L
Linus Torvalds 已提交
1065 1066 1067 1068 1069
		n -= count;
		tape->b_data += count;
		tape->b_count -= count;
		buf += count;
		if (!tape->b_count) {
1070 1071
			bh = bh->b_reqnext;
			tape->bh = bh;
L
Linus Torvalds 已提交
1072 1073 1074 1075 1076 1077
			if (bh) {
				tape->b_data = bh->b_data;
				tape->b_count = atomic_read(&bh->b_count);
			}
		}
	}
1078
	return ret;
L
Linus Torvalds 已提交
1079 1080
}

1081
static void idetape_init_merge_buffer(idetape_tape_t *tape)
L
Linus Torvalds 已提交
1082
{
1083 1084
	struct idetape_bh *bh = tape->merge_bh;
	tape->bh = tape->merge_bh;
1085

1086
	if (tape->chrdev_dir == IDETAPE_DIR_WRITE)
L
Linus Torvalds 已提交
1087 1088 1089 1090 1091 1092 1093 1094
		atomic_set(&bh->b_count, 0);
	else {
		tape->b_data = bh->b_data;
		tape->b_count = atomic_read(&bh->b_count);
	}
}

/*
1095 1096
 * Write a filemark if write_filemark=1. Flush the device buffers without
 * writing a filemark otherwise.
L
Linus Torvalds 已提交
1097
 */
1098
static void idetape_create_write_filemark_cmd(ide_drive_t *drive,
1099
		struct ide_atapi_pc *pc, int write_filemark)
L
Linus Torvalds 已提交
1100
{
1101
	ide_init_pc(pc);
1102
	pc->c[0] = WRITE_FILEMARKS;
L
Linus Torvalds 已提交
1103
	pc->c[4] = write_filemark;
1104
	pc->flags |= PC_FLAG_WAIT_FOR_DSC;
L
Linus Torvalds 已提交
1105 1106 1107 1108 1109
}

static int idetape_wait_ready(ide_drive_t *drive, unsigned long timeout)
{
	idetape_tape_t *tape = drive->driver_data;
1110
	struct gendisk *disk = tape->disk;
L
Linus Torvalds 已提交
1111 1112
	int load_attempted = 0;

1113
	/* Wait for the tape to become ready */
1114
	set_bit(IDE_AFLAG_MEDIUM_PRESENT, &drive->atapi_flags);
L
Linus Torvalds 已提交
1115 1116
	timeout += jiffies;
	while (time_before(jiffies, timeout)) {
1117
		if (ide_do_test_unit_ready(drive, disk) == 0)
L
Linus Torvalds 已提交
1118 1119
			return 0;
		if ((tape->sense_key == 2 && tape->asc == 4 && tape->ascq == 2)
1120 1121
		    || (tape->asc == 0x3A)) {
			/* no media */
L
Linus Torvalds 已提交
1122 1123
			if (load_attempted)
				return -ENOMEDIUM;
1124
			ide_do_start_stop(drive, disk, IDETAPE_LU_LOAD_MASK);
L
Linus Torvalds 已提交
1125 1126 1127 1128 1129
			load_attempted = 1;
		/* not about to be ready */
		} else if (!(tape->sense_key == 2 && tape->asc == 4 &&
			     (tape->ascq == 1 || tape->ascq == 8)))
			return -EIO;
1130
		msleep(100);
L
Linus Torvalds 已提交
1131 1132 1133 1134
	}
	return -EIO;
}

1135
static int idetape_flush_tape_buffers(ide_drive_t *drive)
L
Linus Torvalds 已提交
1136
{
1137
	struct ide_tape_obj *tape = drive->driver_data;
1138
	struct ide_atapi_pc pc;
L
Linus Torvalds 已提交
1139 1140 1141
	int rc;

	idetape_create_write_filemark_cmd(drive, &pc, 0);
1142
	rc = ide_queue_pc_tail(drive, tape->disk, &pc);
1143
	if (rc)
L
Linus Torvalds 已提交
1144 1145 1146 1147 1148
		return rc;
	idetape_wait_ready(drive, 60 * 5 * HZ);
	return 0;
}

1149
static void idetape_create_read_position_cmd(struct ide_atapi_pc *pc)
L
Linus Torvalds 已提交
1150
{
1151
	ide_init_pc(pc);
1152
	pc->c[0] = READ_POSITION;
1153
	pc->req_xfer = 20;
L
Linus Torvalds 已提交
1154 1155
}

1156
static int idetape_read_position(ide_drive_t *drive)
L
Linus Torvalds 已提交
1157 1158
{
	idetape_tape_t *tape = drive->driver_data;
1159
	struct ide_atapi_pc pc;
L
Linus Torvalds 已提交
1160 1161
	int position;

1162
	debug_log(DBG_PROCS, "Enter %s\n", __func__);
L
Linus Torvalds 已提交
1163 1164

	idetape_create_read_position_cmd(&pc);
1165
	if (ide_queue_pc_tail(drive, tape->disk, &pc))
L
Linus Torvalds 已提交
1166
		return -1;
1167
	position = tape->first_frame;
L
Linus Torvalds 已提交
1168 1169 1170
	return position;
}

1171 1172
static void idetape_create_locate_cmd(ide_drive_t *drive,
		struct ide_atapi_pc *pc,
1173
		unsigned int block, u8 partition, int skip)
L
Linus Torvalds 已提交
1174
{
1175
	ide_init_pc(pc);
1176
	pc->c[0] = POSITION_TO_ELEMENT;
L
Linus Torvalds 已提交
1177
	pc->c[1] = 2;
1178
	put_unaligned(cpu_to_be32(block), (unsigned int *) &pc->c[3]);
L
Linus Torvalds 已提交
1179
	pc->c[8] = partition;
1180
	pc->flags |= PC_FLAG_WAIT_FOR_DSC;
L
Linus Torvalds 已提交
1181 1182
}

1183
static void __ide_tape_discard_merge_buffer(ide_drive_t *drive)
L
Linus Torvalds 已提交
1184 1185 1186
{
	idetape_tape_t *tape = drive->driver_data;

1187
	if (tape->chrdev_dir != IDETAPE_DIR_READ)
1188
		return;
L
Linus Torvalds 已提交
1189

1190
	clear_bit(IDE_AFLAG_FILEMARK, &drive->atapi_flags);
1191
	tape->merge_bh_size = 0;
1192 1193 1194
	if (tape->merge_bh != NULL) {
		ide_tape_kfree_buffer(tape);
		tape->merge_bh = NULL;
L
Linus Torvalds 已提交
1195 1196
	}

1197
	tape->chrdev_dir = IDETAPE_DIR_NONE;
L
Linus Torvalds 已提交
1198 1199 1200
}

/*
1201 1202 1203 1204
 * Position the tape to the requested block using the LOCATE packet command.
 * A READ POSITION command is then issued to check where we are positioned. Like
 * all higher level operations, we queue the commands at the tail of the request
 * queue and wait for their completion.
L
Linus Torvalds 已提交
1205
 */
1206 1207
static int idetape_position_tape(ide_drive_t *drive, unsigned int block,
		u8 partition, int skip)
L
Linus Torvalds 已提交
1208 1209
{
	idetape_tape_t *tape = drive->driver_data;
1210
	struct gendisk *disk = tape->disk;
L
Linus Torvalds 已提交
1211
	int retval;
1212
	struct ide_atapi_pc pc;
L
Linus Torvalds 已提交
1213

1214
	if (tape->chrdev_dir == IDETAPE_DIR_READ)
1215
		__ide_tape_discard_merge_buffer(drive);
L
Linus Torvalds 已提交
1216 1217
	idetape_wait_ready(drive, 60 * 5 * HZ);
	idetape_create_locate_cmd(drive, &pc, block, partition, skip);
1218
	retval = ide_queue_pc_tail(drive, disk, &pc);
L
Linus Torvalds 已提交
1219 1220 1221 1222
	if (retval)
		return (retval);

	idetape_create_read_position_cmd(&pc);
1223
	return ide_queue_pc_tail(drive, disk, &pc);
L
Linus Torvalds 已提交
1224 1225
}

1226
static void ide_tape_discard_merge_buffer(ide_drive_t *drive,
1227
					  int restore_position)
L
Linus Torvalds 已提交
1228 1229 1230 1231
{
	idetape_tape_t *tape = drive->driver_data;
	int seek, position;

1232
	__ide_tape_discard_merge_buffer(drive);
L
Linus Torvalds 已提交
1233 1234
	if (restore_position) {
		position = idetape_read_position(drive);
1235
		seek = position > 0 ? position : 0;
L
Linus Torvalds 已提交
1236
		if (idetape_position_tape(drive, seek, 0, 0)) {
1237
			printk(KERN_INFO "ide-tape: %s: position_tape failed in"
1238
					 " %s\n", tape->name, __func__);
L
Linus Torvalds 已提交
1239 1240 1241 1242 1243 1244
			return;
		}
	}
}

/*
1245 1246
 * Generate a read/write request for the block device interface and wait for it
 * to be serviced.
L
Linus Torvalds 已提交
1247
 */
1248 1249
static int idetape_queue_rw_tail(ide_drive_t *drive, int cmd, int blocks,
				 struct idetape_bh *bh)
L
Linus Torvalds 已提交
1250 1251
{
	idetape_tape_t *tape = drive->driver_data;
1252 1253
	struct request *rq;
	int ret, errors;
L
Linus Torvalds 已提交
1254

1255 1256
	debug_log(DBG_SENSE, "%s: cmd=%d\n", __func__, cmd);

1257 1258
	rq = blk_get_request(drive->queue, READ, __GFP_WAIT);
	rq->cmd_type = REQ_TYPE_SPECIAL;
1259
	rq->cmd[13] = cmd;
1260 1261 1262 1263 1264 1265 1266 1267 1268 1269
	rq->rq_disk = tape->disk;
	rq->special = (void *)bh;
	rq->sector = tape->first_frame;
	rq->nr_sectors = blocks;
	rq->current_nr_sectors = blocks;
	blk_execute_rq(drive->queue, tape->disk, rq, 0);

	errors = rq->errors;
	ret = tape->blk_size * (blocks - rq->current_nr_sectors);
	blk_put_request(rq);
L
Linus Torvalds 已提交
1270 1271 1272 1273

	if ((cmd & (REQ_IDETAPE_READ | REQ_IDETAPE_WRITE)) == 0)
		return 0;

1274 1275
	if (tape->merge_bh)
		idetape_init_merge_buffer(tape);
1276
	if (errors == IDETAPE_ERROR_GENERAL)
L
Linus Torvalds 已提交
1277
		return -EIO;
1278
	return ret;
L
Linus Torvalds 已提交
1279 1280
}

1281
static void idetape_create_inquiry_cmd(struct ide_atapi_pc *pc)
L
Linus Torvalds 已提交
1282
{
1283
	ide_init_pc(pc);
1284
	pc->c[0] = INQUIRY;
1285
	pc->c[4] = 254;
1286
	pc->req_xfer = 254;
L
Linus Torvalds 已提交
1287 1288
}

1289 1290
static void idetape_create_rewind_cmd(ide_drive_t *drive,
		struct ide_atapi_pc *pc)
L
Linus Torvalds 已提交
1291
{
1292
	ide_init_pc(pc);
1293
	pc->c[0] = REZERO_UNIT;
1294
	pc->flags |= PC_FLAG_WAIT_FOR_DSC;
L
Linus Torvalds 已提交
1295 1296
}

1297
static void idetape_create_erase_cmd(struct ide_atapi_pc *pc)
L
Linus Torvalds 已提交
1298
{
1299
	ide_init_pc(pc);
1300
	pc->c[0] = ERASE;
L
Linus Torvalds 已提交
1301
	pc->c[1] = 1;
1302
	pc->flags |= PC_FLAG_WAIT_FOR_DSC;
L
Linus Torvalds 已提交
1303 1304
}

1305
static void idetape_create_space_cmd(struct ide_atapi_pc *pc, int count, u8 cmd)
L
Linus Torvalds 已提交
1306
{
1307
	ide_init_pc(pc);
1308
	pc->c[0] = SPACE;
1309
	put_unaligned(cpu_to_be32(count), (unsigned int *) &pc->c[1]);
L
Linus Torvalds 已提交
1310
	pc->c[1] = cmd;
1311
	pc->flags |= PC_FLAG_WAIT_FOR_DSC;
L
Linus Torvalds 已提交
1312 1313
}

1314
/* Queue up a character device originated write request. */
1315
static int idetape_add_chrdev_write_request(ide_drive_t *drive, int blocks)
L
Linus Torvalds 已提交
1316 1317 1318
{
	idetape_tape_t *tape = drive->driver_data;

1319
	debug_log(DBG_CHRDEV, "Enter %s\n", __func__);
L
Linus Torvalds 已提交
1320

1321
	return idetape_queue_rw_tail(drive, REQ_IDETAPE_WRITE,
1322
				     blocks, tape->merge_bh);
L
Linus Torvalds 已提交
1323 1324
}

1325
static void ide_tape_flush_merge_buffer(ide_drive_t *drive)
L
Linus Torvalds 已提交
1326 1327 1328 1329
{
	idetape_tape_t *tape = drive->driver_data;
	int blocks, min;
	struct idetape_bh *bh;
1330

1331
	if (tape->chrdev_dir != IDETAPE_DIR_WRITE) {
1332
		printk(KERN_ERR "ide-tape: bug: Trying to empty merge buffer"
1333
				" but we are not writing.\n");
L
Linus Torvalds 已提交
1334 1335
		return;
	}
1336
	if (tape->merge_bh_size > tape->buffer_size) {
L
Linus Torvalds 已提交
1337
		printk(KERN_ERR "ide-tape: bug: merge_buffer too big\n");
1338
		tape->merge_bh_size = tape->buffer_size;
L
Linus Torvalds 已提交
1339
	}
1340 1341 1342
	if (tape->merge_bh_size) {
		blocks = tape->merge_bh_size / tape->blk_size;
		if (tape->merge_bh_size % tape->blk_size) {
L
Linus Torvalds 已提交
1343 1344 1345
			unsigned int i;

			blocks++;
1346
			i = tape->blk_size - tape->merge_bh_size %
1347
				tape->blk_size;
L
Linus Torvalds 已提交
1348 1349 1350 1351 1352 1353 1354 1355
			bh = tape->bh->b_reqnext;
			while (bh) {
				atomic_set(&bh->b_count, 0);
				bh = bh->b_reqnext;
			}
			bh = tape->bh;
			while (i) {
				if (bh == NULL) {
1356 1357
					printk(KERN_INFO "ide-tape: bug,"
							 " bh NULL\n");
L
Linus Torvalds 已提交
1358 1359
					break;
				}
1360 1361 1362 1363
				min = min(i, (unsigned int)(bh->b_size -
						atomic_read(&bh->b_count)));
				memset(bh->b_data + atomic_read(&bh->b_count),
						0, min);
L
Linus Torvalds 已提交
1364 1365 1366 1367 1368 1369
				atomic_add(min, &bh->b_count);
				i -= min;
				bh = bh->b_reqnext;
			}
		}
		(void) idetape_add_chrdev_write_request(drive, blocks);
1370
		tape->merge_bh_size = 0;
L
Linus Torvalds 已提交
1371
	}
1372 1373 1374
	if (tape->merge_bh != NULL) {
		ide_tape_kfree_buffer(tape);
		tape->merge_bh = NULL;
L
Linus Torvalds 已提交
1375
	}
1376
	tape->chrdev_dir = IDETAPE_DIR_NONE;
L
Linus Torvalds 已提交
1377 1378
}

1379
static int idetape_init_read(ide_drive_t *drive)
L
Linus Torvalds 已提交
1380 1381 1382 1383 1384
{
	idetape_tape_t *tape = drive->driver_data;
	int bytes_read;

	/* Initialize read operation */
1385 1386
	if (tape->chrdev_dir != IDETAPE_DIR_READ) {
		if (tape->chrdev_dir == IDETAPE_DIR_WRITE) {
1387
			ide_tape_flush_merge_buffer(drive);
L
Linus Torvalds 已提交
1388 1389
			idetape_flush_tape_buffers(drive);
		}
1390
		if (tape->merge_bh || tape->merge_bh_size) {
1391
			printk(KERN_ERR "ide-tape: merge_bh_size should be"
1392
					 " 0 now\n");
1393
			tape->merge_bh_size = 0;
L
Linus Torvalds 已提交
1394
		}
1395 1396
		tape->merge_bh = ide_tape_kmalloc_buffer(tape, 0, 0);
		if (!tape->merge_bh)
L
Linus Torvalds 已提交
1397
			return -ENOMEM;
1398
		tape->chrdev_dir = IDETAPE_DIR_READ;
L
Linus Torvalds 已提交
1399 1400

		/*
1401 1402 1403 1404
		 * Issue a read 0 command to ensure that DSC handshake is
		 * switched from completion mode to buffer available mode.
		 * No point in issuing this if DSC overlap isn't supported, some
		 * drives (Seagate STT3401A) will return an error.
L
Linus Torvalds 已提交
1405 1406
		 */
		if (drive->dsc_overlap) {
1407 1408
			bytes_read = idetape_queue_rw_tail(drive,
							REQ_IDETAPE_READ, 0,
1409
							tape->merge_bh);
L
Linus Torvalds 已提交
1410
			if (bytes_read < 0) {
1411 1412
				ide_tape_kfree_buffer(tape);
				tape->merge_bh = NULL;
1413
				tape->chrdev_dir = IDETAPE_DIR_NONE;
L
Linus Torvalds 已提交
1414 1415 1416 1417
				return bytes_read;
			}
		}
	}
1418

L
Linus Torvalds 已提交
1419 1420 1421
	return 0;
}

1422
/* called from idetape_chrdev_read() to service a chrdev read request. */
1423
static int idetape_add_chrdev_read_request(ide_drive_t *drive, int blocks)
L
Linus Torvalds 已提交
1424 1425 1426
{
	idetape_tape_t *tape = drive->driver_data;

1427
	debug_log(DBG_PROCS, "Enter %s, %d blocks\n", __func__, blocks);
L
Linus Torvalds 已提交
1428

1429
	/* If we are at a filemark, return a read length of 0 */
1430
	if (test_bit(IDE_AFLAG_FILEMARK, &drive->atapi_flags))
L
Linus Torvalds 已提交
1431 1432
		return 0;

1433
	idetape_init_read(drive);
1434 1435

	return idetape_queue_rw_tail(drive, REQ_IDETAPE_READ, blocks,
1436
				     tape->merge_bh);
L
Linus Torvalds 已提交
1437 1438
}

1439
static void idetape_pad_zeros(ide_drive_t *drive, int bcount)
L
Linus Torvalds 已提交
1440 1441 1442 1443
{
	idetape_tape_t *tape = drive->driver_data;
	struct idetape_bh *bh;
	int blocks;
1444

L
Linus Torvalds 已提交
1445 1446 1447
	while (bcount) {
		unsigned int count;

1448
		bh = tape->merge_bh;
1449
		count = min(tape->buffer_size, bcount);
L
Linus Torvalds 已提交
1450
		bcount -= count;
1451
		blocks = count / tape->blk_size;
L
Linus Torvalds 已提交
1452
		while (count) {
1453 1454
			atomic_set(&bh->b_count,
				   min(count, (unsigned int)bh->b_size));
L
Linus Torvalds 已提交
1455 1456 1457 1458
			memset(bh->b_data, 0, atomic_read(&bh->b_count));
			count -= atomic_read(&bh->b_count);
			bh = bh->b_reqnext;
		}
1459
		idetape_queue_rw_tail(drive, REQ_IDETAPE_WRITE, blocks,
1460
				      tape->merge_bh);
L
Linus Torvalds 已提交
1461 1462 1463 1464
	}
}

/*
1465 1466 1467
 * Rewinds the tape to the Beginning Of the current Partition (BOP). We
 * currently support only one partition.
 */
1468
static int idetape_rewind_tape(ide_drive_t *drive)
L
Linus Torvalds 已提交
1469
{
1470 1471
	struct ide_tape_obj *tape = drive->driver_data;
	struct gendisk *disk = tape->disk;
L
Linus Torvalds 已提交
1472
	int retval;
1473
	struct ide_atapi_pc pc;
1474 1475 1476

	debug_log(DBG_SENSE, "Enter %s\n", __func__);

L
Linus Torvalds 已提交
1477
	idetape_create_rewind_cmd(drive, &pc);
1478
	retval = ide_queue_pc_tail(drive, disk, &pc);
L
Linus Torvalds 已提交
1479 1480 1481 1482
	if (retval)
		return retval;

	idetape_create_read_position_cmd(&pc);
1483
	retval = ide_queue_pc_tail(drive, disk, &pc);
L
Linus Torvalds 已提交
1484 1485 1486 1487 1488
	if (retval)
		return retval;
	return 0;
}

1489
/* mtio.h compatible commands should be issued to the chrdev interface. */
1490 1491
static int idetape_blkdev_ioctl(ide_drive_t *drive, unsigned int cmd,
				unsigned long arg)
L
Linus Torvalds 已提交
1492 1493 1494 1495
{
	idetape_tape_t *tape = drive->driver_data;
	void __user *argp = (void __user *)arg;

1496 1497 1498 1499 1500 1501
	struct idetape_config {
		int dsc_rw_frequency;
		int dsc_media_access_frequency;
		int nr_stages;
	} config;

1502 1503
	debug_log(DBG_PROCS, "Enter %s\n", __func__);

L
Linus Torvalds 已提交
1504
	switch (cmd) {
1505 1506 1507 1508 1509 1510 1511
	case 0x0340:
		if (copy_from_user(&config, argp, sizeof(config)))
			return -EFAULT;
		tape->best_dsc_rw_freq = config.dsc_rw_frequency;
		break;
	case 0x0350:
		config.dsc_rw_frequency = (int) tape->best_dsc_rw_freq;
1512
		config.nr_stages = 1;
1513 1514 1515 1516 1517
		if (copy_to_user(argp, &config, sizeof(config)))
			return -EFAULT;
		break;
	default:
		return -EIO;
L
Linus Torvalds 已提交
1518 1519 1520 1521
	}
	return 0;
}

1522 1523
static int idetape_space_over_filemarks(ide_drive_t *drive, short mt_op,
					int mt_count)
L
Linus Torvalds 已提交
1524 1525
{
	idetape_tape_t *tape = drive->driver_data;
1526
	struct gendisk *disk = tape->disk;
1527
	struct ide_atapi_pc pc;
1528
	int retval, count = 0;
1529
	int sprev = !!(tape->caps[4] & 0x20);
L
Linus Torvalds 已提交
1530 1531 1532 1533

	if (mt_count == 0)
		return 0;
	if (MTBSF == mt_op || MTBSFM == mt_op) {
1534
		if (!sprev)
L
Linus Torvalds 已提交
1535
			return -EIO;
1536
		mt_count = -mt_count;
L
Linus Torvalds 已提交
1537 1538
	}

1539
	if (tape->chrdev_dir == IDETAPE_DIR_READ) {
1540
		tape->merge_bh_size = 0;
1541
		if (test_and_clear_bit(IDE_AFLAG_FILEMARK, &drive->atapi_flags))
L
Linus Torvalds 已提交
1542
			++count;
1543
		ide_tape_discard_merge_buffer(drive, 0);
L
Linus Torvalds 已提交
1544 1545 1546
	}

	switch (mt_op) {
1547 1548 1549 1550
	case MTFSF:
	case MTBSF:
		idetape_create_space_cmd(&pc, mt_count - count,
					 IDETAPE_SPACE_OVER_FILEMARK);
1551
		return ide_queue_pc_tail(drive, disk, &pc);
1552 1553 1554 1555 1556 1557 1558 1559 1560 1561 1562 1563 1564 1565
	case MTFSFM:
	case MTBSFM:
		if (!sprev)
			return -EIO;
		retval = idetape_space_over_filemarks(drive, MTFSF,
						      mt_count - count);
		if (retval)
			return retval;
		count = (MTBSFM == mt_op ? 1 : -1);
		return idetape_space_over_filemarks(drive, MTFSF, count);
	default:
		printk(KERN_ERR "ide-tape: MTIO operation %d not supported\n",
				mt_op);
		return -EIO;
L
Linus Torvalds 已提交
1566 1567 1568 1569
	}
}

/*
1570
 * Our character device read / write functions.
L
Linus Torvalds 已提交
1571
 *
1572 1573 1574
 * The tape is optimized to maximize throughput when it is transferring an
 * integral number of the "continuous transfer limit", which is a parameter of
 * the specific tape (26kB on my particular tape, 32kB for Onstream).
L
Linus Torvalds 已提交
1575
 *
1576 1577 1578 1579 1580 1581 1582
 * As of version 1.3 of the driver, the character device provides an abstract
 * continuous view of the media - any mix of block sizes (even 1 byte) on the
 * same backup/restore procedure is supported. The driver will internally
 * convert the requests to the recommended transfer unit, so that an unmatch
 * between the user's block size to the recommended size will only result in a
 * (slightly) increased driver overhead, but will no longer hit performance.
 * This is not applicable to Onstream.
L
Linus Torvalds 已提交
1583
 */
1584 1585
static ssize_t idetape_chrdev_read(struct file *file, char __user *buf,
				   size_t count, loff_t *ppos)
L
Linus Torvalds 已提交
1586 1587 1588
{
	struct ide_tape_obj *tape = ide_tape_f(file);
	ide_drive_t *drive = tape->drive;
1589
	ssize_t bytes_read, temp, actually_read = 0, rc;
1590
	ssize_t ret = 0;
1591
	u16 ctl = *(u16 *)&tape->caps[12];
L
Linus Torvalds 已提交
1592

1593
	debug_log(DBG_CHRDEV, "Enter %s, count %Zd\n", __func__, count);
L
Linus Torvalds 已提交
1594

1595
	if (tape->chrdev_dir != IDETAPE_DIR_READ) {
1596
		if (test_bit(IDE_AFLAG_DETECT_BS, &drive->atapi_flags))
1597 1598 1599
			if (count > tape->blk_size &&
			    (count % tape->blk_size) == 0)
				tape->user_bs_factor = count / tape->blk_size;
L
Linus Torvalds 已提交
1600
	}
1601
	rc = idetape_init_read(drive);
1602
	if (rc < 0)
L
Linus Torvalds 已提交
1603 1604 1605
		return rc;
	if (count == 0)
		return (0);
1606 1607
	if (tape->merge_bh_size) {
		actually_read = min((unsigned int)(tape->merge_bh_size),
1608
				    (unsigned int)count);
1609
		if (idetape_copy_stage_to_user(tape, buf, actually_read))
1610
			ret = -EFAULT;
L
Linus Torvalds 已提交
1611
		buf += actually_read;
1612
		tape->merge_bh_size -= actually_read;
L
Linus Torvalds 已提交
1613 1614
		count -= actually_read;
	}
1615
	while (count >= tape->buffer_size) {
1616
		bytes_read = idetape_add_chrdev_read_request(drive, ctl);
L
Linus Torvalds 已提交
1617 1618
		if (bytes_read <= 0)
			goto finish;
1619
		if (idetape_copy_stage_to_user(tape, buf, bytes_read))
1620
			ret = -EFAULT;
L
Linus Torvalds 已提交
1621 1622 1623 1624 1625
		buf += bytes_read;
		count -= bytes_read;
		actually_read += bytes_read;
	}
	if (count) {
1626
		bytes_read = idetape_add_chrdev_read_request(drive, ctl);
L
Linus Torvalds 已提交
1627 1628 1629
		if (bytes_read <= 0)
			goto finish;
		temp = min((unsigned long)count, (unsigned long)bytes_read);
1630
		if (idetape_copy_stage_to_user(tape, buf, temp))
1631
			ret = -EFAULT;
L
Linus Torvalds 已提交
1632
		actually_read += temp;
1633
		tape->merge_bh_size = bytes_read-temp;
L
Linus Torvalds 已提交
1634 1635
	}
finish:
1636
	if (!actually_read && test_bit(IDE_AFLAG_FILEMARK, &drive->atapi_flags)) {
1637 1638
		debug_log(DBG_SENSE, "%s: spacing over filemark\n", tape->name);

L
Linus Torvalds 已提交
1639 1640 1641
		idetape_space_over_filemarks(drive, MTFSF, 1);
		return 0;
	}
1642

1643
	return ret ? ret : actually_read;
L
Linus Torvalds 已提交
1644 1645
}

1646
static ssize_t idetape_chrdev_write(struct file *file, const char __user *buf,
L
Linus Torvalds 已提交
1647 1648 1649 1650
				     size_t count, loff_t *ppos)
{
	struct ide_tape_obj *tape = ide_tape_f(file);
	ide_drive_t *drive = tape->drive;
1651 1652
	ssize_t actually_written = 0;
	ssize_t ret = 0;
1653
	u16 ctl = *(u16 *)&tape->caps[12];
L
Linus Torvalds 已提交
1654 1655 1656 1657 1658

	/* The drive is write protected. */
	if (tape->write_prot)
		return -EACCES;

1659
	debug_log(DBG_CHRDEV, "Enter %s, count %Zd\n", __func__, count);
L
Linus Torvalds 已提交
1660 1661

	/* Initialize write operation */
1662 1663
	if (tape->chrdev_dir != IDETAPE_DIR_WRITE) {
		if (tape->chrdev_dir == IDETAPE_DIR_READ)
1664
			ide_tape_discard_merge_buffer(drive, 1);
1665
		if (tape->merge_bh || tape->merge_bh_size) {
1666
			printk(KERN_ERR "ide-tape: merge_bh_size "
L
Linus Torvalds 已提交
1667
				"should be 0 now\n");
1668
			tape->merge_bh_size = 0;
L
Linus Torvalds 已提交
1669
		}
1670 1671
		tape->merge_bh = ide_tape_kmalloc_buffer(tape, 0, 0);
		if (!tape->merge_bh)
L
Linus Torvalds 已提交
1672
			return -ENOMEM;
1673
		tape->chrdev_dir = IDETAPE_DIR_WRITE;
1674
		idetape_init_merge_buffer(tape);
L
Linus Torvalds 已提交
1675 1676

		/*
1677 1678 1679 1680
		 * Issue a write 0 command to ensure that DSC handshake is
		 * switched from completion mode to buffer available mode. No
		 * point in issuing this if DSC overlap isn't supported, some
		 * drives (Seagate STT3401A) will return an error.
L
Linus Torvalds 已提交
1681 1682
		 */
		if (drive->dsc_overlap) {
1683 1684
			ssize_t retval = idetape_queue_rw_tail(drive,
							REQ_IDETAPE_WRITE, 0,
1685
							tape->merge_bh);
L
Linus Torvalds 已提交
1686
			if (retval < 0) {
1687 1688
				ide_tape_kfree_buffer(tape);
				tape->merge_bh = NULL;
1689
				tape->chrdev_dir = IDETAPE_DIR_NONE;
L
Linus Torvalds 已提交
1690 1691 1692 1693 1694 1695
				return retval;
			}
		}
	}
	if (count == 0)
		return (0);
1696 1697
	if (tape->merge_bh_size) {
		if (tape->merge_bh_size >= tape->buffer_size) {
1698
			printk(KERN_ERR "ide-tape: bug: merge buf too big\n");
1699
			tape->merge_bh_size = 0;
L
Linus Torvalds 已提交
1700
		}
1701
		actually_written = min((unsigned int)
1702
				(tape->buffer_size - tape->merge_bh_size),
1703
				(unsigned int)count);
1704
		if (idetape_copy_stage_from_user(tape, buf, actually_written))
1705
				ret = -EFAULT;
L
Linus Torvalds 已提交
1706
		buf += actually_written;
1707
		tape->merge_bh_size += actually_written;
L
Linus Torvalds 已提交
1708 1709
		count -= actually_written;

1710
		if (tape->merge_bh_size == tape->buffer_size) {
1711
			ssize_t retval;
1712
			tape->merge_bh_size = 0;
1713
			retval = idetape_add_chrdev_write_request(drive, ctl);
L
Linus Torvalds 已提交
1714 1715 1716 1717
			if (retval <= 0)
				return (retval);
		}
	}
1718
	while (count >= tape->buffer_size) {
1719
		ssize_t retval;
1720
		if (idetape_copy_stage_from_user(tape, buf, tape->buffer_size))
1721
			ret = -EFAULT;
1722 1723
		buf += tape->buffer_size;
		count -= tape->buffer_size;
1724
		retval = idetape_add_chrdev_write_request(drive, ctl);
1725
		actually_written += tape->buffer_size;
L
Linus Torvalds 已提交
1726 1727 1728 1729 1730
		if (retval <= 0)
			return (retval);
	}
	if (count) {
		actually_written += count;
1731
		if (idetape_copy_stage_from_user(tape, buf, count))
1732
			ret = -EFAULT;
1733
		tape->merge_bh_size += count;
L
Linus Torvalds 已提交
1734
	}
1735
	return ret ? ret : actually_written;
L
Linus Torvalds 已提交
1736 1737
}

1738
static int idetape_write_filemark(ide_drive_t *drive)
L
Linus Torvalds 已提交
1739
{
1740
	struct ide_tape_obj *tape = drive->driver_data;
1741
	struct ide_atapi_pc pc;
L
Linus Torvalds 已提交
1742 1743 1744

	/* Write a filemark */
	idetape_create_write_filemark_cmd(drive, &pc, 1);
1745
	if (ide_queue_pc_tail(drive, tape->disk, &pc)) {
L
Linus Torvalds 已提交
1746 1747 1748 1749 1750 1751 1752
		printk(KERN_ERR "ide-tape: Couldn't write a filemark\n");
		return -EIO;
	}
	return 0;
}

/*
1753 1754
 * Called from idetape_chrdev_ioctl when the general mtio MTIOCTOP ioctl is
 * requested.
L
Linus Torvalds 已提交
1755
 *
1756 1757
 * Note: MTBSF and MTBSFM are not supported when the tape doesn't support
 * spacing over filemarks in the reverse direction. In this case, MTFSFM is also
1758
 * usually not supported.
L
Linus Torvalds 已提交
1759
 *
1760
 * The following commands are currently not supported:
L
Linus Torvalds 已提交
1761
 *
1762 1763
 * MTFSS, MTBSS, MTWSM, MTSETDENSITY, MTSETDRVBUFFER, MT_ST_BOOLEANS,
 * MT_ST_WRITE_THRESHOLD.
L
Linus Torvalds 已提交
1764
 */
1765
static int idetape_mtioctop(ide_drive_t *drive, short mt_op, int mt_count)
L
Linus Torvalds 已提交
1766 1767
{
	idetape_tape_t *tape = drive->driver_data;
1768
	struct gendisk *disk = tape->disk;
1769
	struct ide_atapi_pc pc;
1770
	int i, retval;
L
Linus Torvalds 已提交
1771

1772 1773
	debug_log(DBG_ERR, "Handling MTIOCTOP ioctl: mt_op=%d, mt_count=%d\n",
			mt_op, mt_count);
1774

L
Linus Torvalds 已提交
1775
	switch (mt_op) {
1776 1777 1778 1779 1780 1781 1782 1783 1784
	case MTFSF:
	case MTFSFM:
	case MTBSF:
	case MTBSFM:
		if (!mt_count)
			return 0;
		return idetape_space_over_filemarks(drive, mt_op, mt_count);
	default:
		break;
L
Linus Torvalds 已提交
1785
	}
1786

L
Linus Torvalds 已提交
1787
	switch (mt_op) {
1788 1789 1790
	case MTWEOF:
		if (tape->write_prot)
			return -EACCES;
1791
		ide_tape_discard_merge_buffer(drive, 1);
1792 1793 1794 1795 1796 1797 1798
		for (i = 0; i < mt_count; i++) {
			retval = idetape_write_filemark(drive);
			if (retval)
				return retval;
		}
		return 0;
	case MTREW:
1799
		ide_tape_discard_merge_buffer(drive, 0);
1800 1801 1802 1803
		if (idetape_rewind_tape(drive))
			return -EIO;
		return 0;
	case MTLOAD:
1804
		ide_tape_discard_merge_buffer(drive, 0);
1805
		return ide_do_start_stop(drive, disk, IDETAPE_LU_LOAD_MASK);
1806 1807 1808 1809 1810 1811 1812
	case MTUNLOAD:
	case MTOFFL:
		/*
		 * If door is locked, attempt to unlock before
		 * attempting to eject.
		 */
		if (tape->door_locked) {
1813
			if (!ide_set_media_lock(drive, disk, 0))
1814
				tape->door_locked = DOOR_UNLOCKED;
1815
		}
1816
		ide_tape_discard_merge_buffer(drive, 0);
1817
		retval = ide_do_start_stop(drive, disk, !IDETAPE_LU_LOAD_MASK);
1818
		if (!retval)
1819
			clear_bit(IDE_AFLAG_MEDIUM_PRESENT, &drive->atapi_flags);
1820 1821
		return retval;
	case MTNOP:
1822
		ide_tape_discard_merge_buffer(drive, 0);
1823 1824
		return idetape_flush_tape_buffers(drive);
	case MTRETEN:
1825
		ide_tape_discard_merge_buffer(drive, 0);
1826
		return ide_do_start_stop(drive, disk,
1827 1828 1829
			IDETAPE_LU_RETENSION_MASK | IDETAPE_LU_LOAD_MASK);
	case MTEOM:
		idetape_create_space_cmd(&pc, 0, IDETAPE_SPACE_TO_EOD);
1830
		return ide_queue_pc_tail(drive, disk, &pc);
1831 1832 1833
	case MTERASE:
		(void)idetape_rewind_tape(drive);
		idetape_create_erase_cmd(&pc);
1834
		return ide_queue_pc_tail(drive, disk, &pc);
1835 1836 1837 1838
	case MTSETBLK:
		if (mt_count) {
			if (mt_count < tape->blk_size ||
			    mt_count % tape->blk_size)
L
Linus Torvalds 已提交
1839
				return -EIO;
1840
			tape->user_bs_factor = mt_count / tape->blk_size;
1841
			clear_bit(IDE_AFLAG_DETECT_BS, &drive->atapi_flags);
1842
		} else
1843
			set_bit(IDE_AFLAG_DETECT_BS, &drive->atapi_flags);
1844 1845
		return 0;
	case MTSEEK:
1846
		ide_tape_discard_merge_buffer(drive, 0);
1847 1848 1849
		return idetape_position_tape(drive,
			mt_count * tape->user_bs_factor, tape->partition, 0);
	case MTSETPART:
1850
		ide_tape_discard_merge_buffer(drive, 0);
1851 1852 1853 1854
		return idetape_position_tape(drive, 0, mt_count, 0);
	case MTFSR:
	case MTBSR:
	case MTLOCK:
1855
		retval = ide_set_media_lock(drive, disk, 1);
1856
		if (retval)
L
Linus Torvalds 已提交
1857
			return retval;
1858 1859 1860
		tape->door_locked = DOOR_EXPLICITLY_LOCKED;
		return 0;
	case MTUNLOCK:
1861
		retval = ide_set_media_lock(drive, disk, 0);
1862 1863 1864 1865 1866 1867 1868 1869
		if (retval)
			return retval;
		tape->door_locked = DOOR_UNLOCKED;
		return 0;
	default:
		printk(KERN_ERR "ide-tape: MTIO operation %d not supported\n",
				mt_op);
		return -EIO;
L
Linus Torvalds 已提交
1870 1871 1872 1873
	}
}

/*
1874 1875 1876
 * Our character device ioctls. General mtio.h magnetic io commands are
 * supported here, and not in the corresponding block interface. Our own
 * ide-tape ioctls are supported on both interfaces.
L
Linus Torvalds 已提交
1877
 */
1878 1879
static int idetape_chrdev_ioctl(struct inode *inode, struct file *file,
				unsigned int cmd, unsigned long arg)
L
Linus Torvalds 已提交
1880 1881 1882 1883 1884 1885
{
	struct ide_tape_obj *tape = ide_tape_f(file);
	ide_drive_t *drive = tape->drive;
	struct mtop mtop;
	struct mtget mtget;
	struct mtpos mtpos;
1886
	int block_offset = 0, position = tape->first_frame;
L
Linus Torvalds 已提交
1887 1888
	void __user *argp = (void __user *)arg;

1889
	debug_log(DBG_CHRDEV, "Enter %s, cmd=%u\n", __func__, cmd);
L
Linus Torvalds 已提交
1890

1891
	if (tape->chrdev_dir == IDETAPE_DIR_WRITE) {
1892
		ide_tape_flush_merge_buffer(drive);
L
Linus Torvalds 已提交
1893 1894 1895
		idetape_flush_tape_buffers(drive);
	}
	if (cmd == MTIOCGET || cmd == MTIOCPOS) {
1896
		block_offset = tape->merge_bh_size /
1897
			(tape->blk_size * tape->user_bs_factor);
1898 1899
		position = idetape_read_position(drive);
		if (position < 0)
L
Linus Torvalds 已提交
1900 1901 1902
			return -EIO;
	}
	switch (cmd) {
1903 1904 1905 1906 1907 1908 1909 1910 1911 1912 1913 1914 1915 1916 1917 1918 1919 1920 1921 1922 1923 1924 1925 1926 1927
	case MTIOCTOP:
		if (copy_from_user(&mtop, argp, sizeof(struct mtop)))
			return -EFAULT;
		return idetape_mtioctop(drive, mtop.mt_op, mtop.mt_count);
	case MTIOCGET:
		memset(&mtget, 0, sizeof(struct mtget));
		mtget.mt_type = MT_ISSCSI2;
		mtget.mt_blkno = position / tape->user_bs_factor - block_offset;
		mtget.mt_dsreg =
			((tape->blk_size * tape->user_bs_factor)
			 << MT_ST_BLKSIZE_SHIFT) & MT_ST_BLKSIZE_MASK;

		if (tape->drv_write_prot)
			mtget.mt_gstat |= GMT_WR_PROT(0xffffffff);

		if (copy_to_user(argp, &mtget, sizeof(struct mtget)))
			return -EFAULT;
		return 0;
	case MTIOCPOS:
		mtpos.mt_blkno = position / tape->user_bs_factor - block_offset;
		if (copy_to_user(argp, &mtpos, sizeof(struct mtpos)))
			return -EFAULT;
		return 0;
	default:
		if (tape->chrdev_dir == IDETAPE_DIR_READ)
1928
			ide_tape_discard_merge_buffer(drive, 1);
1929
		return idetape_blkdev_ioctl(drive, cmd, arg);
L
Linus Torvalds 已提交
1930 1931 1932
	}
}

1933 1934 1935 1936 1937 1938 1939
/*
 * Do a mode sense page 0 with block descriptor and if it succeeds set the tape
 * block size with the reported value.
 */
static void ide_tape_get_bsize_from_bdesc(ide_drive_t *drive)
{
	idetape_tape_t *tape = drive->driver_data;
1940
	struct ide_atapi_pc pc;
1941 1942

	idetape_create_mode_sense_cmd(&pc, IDETAPE_BLOCK_DESCRIPTOR);
1943
	if (ide_queue_pc_tail(drive, tape->disk, &pc)) {
1944
		printk(KERN_ERR "ide-tape: Can't get block descriptor\n");
1945
		if (tape->blk_size == 0) {
1946 1947
			printk(KERN_WARNING "ide-tape: Cannot deal with zero "
					    "block size, assuming 32k\n");
1948
			tape->blk_size = 32768;
1949 1950 1951
		}
		return;
	}
1952 1953 1954 1955
	tape->blk_size = (pc.buf[4 + 5] << 16) +
				(pc.buf[4 + 6] << 8)  +
				 pc.buf[4 + 7];
	tape->drv_write_prot = (pc.buf[2] & 0x80) >> 7;
1956
}
L
Linus Torvalds 已提交
1957

1958
static int idetape_chrdev_open(struct inode *inode, struct file *filp)
L
Linus Torvalds 已提交
1959 1960 1961 1962 1963 1964
{
	unsigned int minor = iminor(inode), i = minor & ~0xc0;
	ide_drive_t *drive;
	idetape_tape_t *tape;
	int retval;

1965 1966 1967
	if (i >= MAX_HWIFS * MAX_DRIVES)
		return -ENXIO;

1968
	lock_kernel();
1969
	tape = ide_tape_chrdev_get(i);
1970 1971
	if (!tape) {
		unlock_kernel();
1972
		return -ENXIO;
1973
	}
1974 1975 1976

	debug_log(DBG_CHRDEV, "Enter %s\n", __func__);

L
Linus Torvalds 已提交
1977 1978 1979 1980 1981 1982 1983 1984 1985 1986 1987
	/*
	 * We really want to do nonseekable_open(inode, filp); here, but some
	 * versions of tar incorrectly call lseek on tapes and bail out if that
	 * fails.  So we disallow pread() and pwrite(), but permit lseeks.
	 */
	filp->f_mode &= ~(FMODE_PREAD | FMODE_PWRITE);

	drive = tape->drive;

	filp->private_data = tape;

1988
	if (test_and_set_bit(IDE_AFLAG_BUSY, &drive->atapi_flags)) {
L
Linus Torvalds 已提交
1989 1990 1991 1992 1993 1994
		retval = -EBUSY;
		goto out_put_tape;
	}

	retval = idetape_wait_ready(drive, 60 * HZ);
	if (retval) {
1995
		clear_bit(IDE_AFLAG_BUSY, &drive->atapi_flags);
L
Linus Torvalds 已提交
1996 1997 1998 1999 2000
		printk(KERN_ERR "ide-tape: %s: drive not ready\n", tape->name);
		goto out_put_tape;
	}

	idetape_read_position(drive);
2001
	if (!test_bit(IDE_AFLAG_ADDRESS_VALID, &drive->atapi_flags))
L
Linus Torvalds 已提交
2002 2003 2004
		(void)idetape_rewind_tape(drive);

	/* Read block size and write protect status from drive. */
2005
	ide_tape_get_bsize_from_bdesc(drive);
L
Linus Torvalds 已提交
2006 2007 2008 2009 2010 2011 2012 2013 2014 2015 2016

	/* Set write protect flag if device is opened as read-only. */
	if ((filp->f_flags & O_ACCMODE) == O_RDONLY)
		tape->write_prot = 1;
	else
		tape->write_prot = tape->drv_write_prot;

	/* Make sure drive isn't write protected if user wants to write. */
	if (tape->write_prot) {
		if ((filp->f_flags & O_ACCMODE) == O_WRONLY ||
		    (filp->f_flags & O_ACCMODE) == O_RDWR) {
2017
			clear_bit(IDE_AFLAG_BUSY, &drive->atapi_flags);
L
Linus Torvalds 已提交
2018 2019 2020 2021 2022
			retval = -EROFS;
			goto out_put_tape;
		}
	}

2023
	/* Lock the tape drive door so user can't eject. */
2024
	if (tape->chrdev_dir == IDETAPE_DIR_NONE) {
2025
		if (!ide_set_media_lock(drive, tape->disk, 1)) {
2026 2027
			if (tape->door_locked != DOOR_EXPLICITLY_LOCKED)
				tape->door_locked = DOOR_LOCKED;
L
Linus Torvalds 已提交
2028 2029
		}
	}
2030
	unlock_kernel();
L
Linus Torvalds 已提交
2031 2032 2033 2034
	return 0;

out_put_tape:
	ide_tape_put(tape);
2035
	unlock_kernel();
L
Linus Torvalds 已提交
2036 2037 2038
	return retval;
}

2039
static void idetape_write_release(ide_drive_t *drive, unsigned int minor)
L
Linus Torvalds 已提交
2040 2041 2042
{
	idetape_tape_t *tape = drive->driver_data;

2043
	ide_tape_flush_merge_buffer(drive);
2044 2045
	tape->merge_bh = ide_tape_kmalloc_buffer(tape, 1, 0);
	if (tape->merge_bh != NULL) {
2046 2047
		idetape_pad_zeros(drive, tape->blk_size *
				(tape->user_bs_factor - 1));
2048 2049
		ide_tape_kfree_buffer(tape);
		tape->merge_bh = NULL;
L
Linus Torvalds 已提交
2050 2051 2052 2053 2054 2055
	}
	idetape_write_filemark(drive);
	idetape_flush_tape_buffers(drive);
	idetape_flush_tape_buffers(drive);
}

2056
static int idetape_chrdev_release(struct inode *inode, struct file *filp)
L
Linus Torvalds 已提交
2057 2058 2059 2060 2061 2062 2063
{
	struct ide_tape_obj *tape = ide_tape_f(filp);
	ide_drive_t *drive = tape->drive;
	unsigned int minor = iminor(inode);

	lock_kernel();
	tape = drive->driver_data;
2064 2065

	debug_log(DBG_CHRDEV, "Enter %s\n", __func__);
L
Linus Torvalds 已提交
2066

2067
	if (tape->chrdev_dir == IDETAPE_DIR_WRITE)
L
Linus Torvalds 已提交
2068
		idetape_write_release(drive, minor);
2069
	if (tape->chrdev_dir == IDETAPE_DIR_READ) {
L
Linus Torvalds 已提交
2070
		if (minor < 128)
2071
			ide_tape_discard_merge_buffer(drive, 1);
L
Linus Torvalds 已提交
2072
	}
2073

2074
	if (minor < 128 && test_bit(IDE_AFLAG_MEDIUM_PRESENT, &drive->atapi_flags))
L
Linus Torvalds 已提交
2075
		(void) idetape_rewind_tape(drive);
2076
	if (tape->chrdev_dir == IDETAPE_DIR_NONE) {
L
Linus Torvalds 已提交
2077
		if (tape->door_locked == DOOR_LOCKED) {
2078
			if (!ide_set_media_lock(drive, tape->disk, 0))
2079
				tape->door_locked = DOOR_UNLOCKED;
L
Linus Torvalds 已提交
2080 2081
		}
	}
2082
	clear_bit(IDE_AFLAG_BUSY, &drive->atapi_flags);
L
Linus Torvalds 已提交
2083 2084 2085 2086 2087
	ide_tape_put(tape);
	unlock_kernel();
	return 0;
}

2088
static void idetape_get_inquiry_results(ide_drive_t *drive)
L
Linus Torvalds 已提交
2089 2090
{
	idetape_tape_t *tape = drive->driver_data;
2091
	struct ide_atapi_pc pc;
B
Borislav Petkov 已提交
2092
	char fw_rev[4], vendor_id[8], product_id[16];
2093

L
Linus Torvalds 已提交
2094
	idetape_create_inquiry_cmd(&pc);
2095
	if (ide_queue_pc_tail(drive, tape->disk, &pc)) {
2096 2097
		printk(KERN_ERR "ide-tape: %s: can't get INQUIRY results\n",
				tape->name);
L
Linus Torvalds 已提交
2098 2099
		return;
	}
2100 2101 2102
	memcpy(vendor_id, &pc.buf[8], 8);
	memcpy(product_id, &pc.buf[16], 16);
	memcpy(fw_rev, &pc.buf[32], 4);
2103

B
Borislav Petkov 已提交
2104 2105 2106
	ide_fixstring(vendor_id, 8, 0);
	ide_fixstring(product_id, 16, 0);
	ide_fixstring(fw_rev, 4, 0);
2107

B
Borislav Petkov 已提交
2108
	printk(KERN_INFO "ide-tape: %s <-> %s: %.8s %.16s rev %.4s\n",
2109
			drive->name, tape->name, vendor_id, product_id, fw_rev);
L
Linus Torvalds 已提交
2110 2111 2112
}

/*
2113 2114
 * Ask the tape about its various parameters. In particular, we will adjust our
 * data transfer buffer	size to the recommended value as returned by the tape.
L
Linus Torvalds 已提交
2115
 */
2116
static void idetape_get_mode_sense_results(ide_drive_t *drive)
L
Linus Torvalds 已提交
2117 2118
{
	idetape_tape_t *tape = drive->driver_data;
2119
	struct ide_atapi_pc pc;
2120 2121
	u8 *caps;
	u8 speed, max_speed;
2122

L
Linus Torvalds 已提交
2123
	idetape_create_mode_sense_cmd(&pc, IDETAPE_CAPABILITIES_PAGE);
2124
	if (ide_queue_pc_tail(drive, tape->disk, &pc)) {
2125 2126
		printk(KERN_ERR "ide-tape: Can't get tape parameters - assuming"
				" some default values\n");
2127
		tape->blk_size = 512;
2128 2129 2130
		put_unaligned(52,   (u16 *)&tape->caps[12]);
		put_unaligned(540,  (u16 *)&tape->caps[14]);
		put_unaligned(6*52, (u16 *)&tape->caps[16]);
L
Linus Torvalds 已提交
2131 2132
		return;
	}
2133
	caps = pc.buf + 4 + pc.buf[3];
2134 2135

	/* convert to host order and save for later use */
2136 2137
	speed = be16_to_cpup((__be16 *)&caps[14]);
	max_speed = be16_to_cpup((__be16 *)&caps[8]);
L
Linus Torvalds 已提交
2138

2139 2140 2141 2142
	*(u16 *)&caps[8] = max_speed;
	*(u16 *)&caps[12] = be16_to_cpup((__be16 *)&caps[12]);
	*(u16 *)&caps[14] = speed;
	*(u16 *)&caps[16] = be16_to_cpup((__be16 *)&caps[16]);
L
Linus Torvalds 已提交
2143

2144 2145 2146
	if (!speed) {
		printk(KERN_INFO "ide-tape: %s: invalid tape speed "
				"(assuming 650KB/sec)\n", drive->name);
2147
		*(u16 *)&caps[14] = 650;
L
Linus Torvalds 已提交
2148
	}
2149 2150 2151
	if (!max_speed) {
		printk(KERN_INFO "ide-tape: %s: invalid max_speed "
				"(assuming 650KB/sec)\n", drive->name);
2152
		*(u16 *)&caps[8] = 650;
L
Linus Torvalds 已提交
2153 2154
	}

2155
	memcpy(&tape->caps, caps, 20);
2156 2157 2158 2159 2160

	/* device lacks locking support according to capabilities page */
	if ((caps[6] & 1) == 0)
		drive->atapi_flags |= IDE_AFLAG_NO_DOORLOCK;

2161
	if (caps[7] & 0x02)
2162
		tape->blk_size = 512;
2163
	else if (caps[7] & 0x04)
2164
		tape->blk_size = 1024;
L
Linus Torvalds 已提交
2165 2166
}

2167
#ifdef CONFIG_IDE_PROC_FS
2168 2169 2170 2171 2172 2173 2174 2175 2176 2177 2178 2179 2180 2181 2182
#define ide_tape_devset_get(name, field) \
static int get_##name(ide_drive_t *drive) \
{ \
	idetape_tape_t *tape = drive->driver_data; \
	return tape->field; \
}

#define ide_tape_devset_set(name, field) \
static int set_##name(ide_drive_t *drive, int arg) \
{ \
	idetape_tape_t *tape = drive->driver_data; \
	tape->field = arg; \
	return 0; \
}

2183
#define ide_tape_devset_rw_field(_name, _field) \
2184 2185
ide_tape_devset_get(_name, _field) \
ide_tape_devset_set(_name, _field) \
2186
IDE_DEVSET(_name, DS_SYNC, get_##_name, set_##_name)
2187

2188
#define ide_tape_devset_r_field(_name, _field) \
2189
ide_tape_devset_get(_name, _field) \
2190
IDE_DEVSET(_name, 0, get_##_name, NULL)
2191 2192 2193 2194 2195 2196

static int mulf_tdsc(ide_drive_t *drive)	{ return 1000; }
static int divf_tdsc(ide_drive_t *drive)	{ return   HZ; }
static int divf_buffer(ide_drive_t *drive)	{ return    2; }
static int divf_buffer_size(ide_drive_t *drive)	{ return 1024; }

2197 2198 2199 2200 2201 2202 2203 2204 2205 2206 2207 2208 2209 2210 2211 2212 2213 2214 2215 2216
ide_devset_rw_field(dsc_overlap, dsc_overlap);

ide_tape_devset_rw_field(debug_mask, debug_mask);
ide_tape_devset_rw_field(tdsc, best_dsc_rw_freq);

ide_tape_devset_r_field(avg_speed, avg_speed);
ide_tape_devset_r_field(speed, caps[14]);
ide_tape_devset_r_field(buffer, caps[16]);
ide_tape_devset_r_field(buffer_size, buffer_size);

static const struct ide_proc_devset idetape_settings[] = {
	__IDE_PROC_DEVSET(avg_speed,	0, 0xffff, NULL, NULL),
	__IDE_PROC_DEVSET(buffer,	0, 0xffff, NULL, divf_buffer),
	__IDE_PROC_DEVSET(buffer_size,	0, 0xffff, NULL, divf_buffer_size),
	__IDE_PROC_DEVSET(debug_mask,	0, 0xffff, NULL, NULL),
	__IDE_PROC_DEVSET(dsc_overlap,	0,      1, NULL, NULL),
	__IDE_PROC_DEVSET(speed,	0, 0xffff, NULL, NULL),
	__IDE_PROC_DEVSET(tdsc,		IDETAPE_DSC_RW_MIN, IDETAPE_DSC_RW_MAX,
					mulf_tdsc, divf_tdsc),
	{ 0 },
2217
};
2218
#endif
L
Linus Torvalds 已提交
2219 2220

/*
2221
 * The function below is called to:
L
Linus Torvalds 已提交
2222
 *
2223 2224 2225 2226
 * 1. Initialize our various state variables.
 * 2. Ask the tape for its capabilities.
 * 3. Allocate a buffer which will be used for data transfer. The buffer size
 * is chosen based on the recommendation which we received in step 2.
L
Linus Torvalds 已提交
2227
 *
2228 2229
 * Note that at this point ide.c already assigned us an irq, so that we can
 * queue requests here and wait for their completion.
L
Linus Torvalds 已提交
2230
 */
2231
static void idetape_setup(ide_drive_t *drive, idetape_tape_t *tape, int minor)
L
Linus Torvalds 已提交
2232
{
2233
	unsigned long t;
L
Linus Torvalds 已提交
2234
	int speed;
2235
	int buffer_size;
2236
	u8 gcw[2];
2237
	u16 *ctl = (u16 *)&tape->caps[12];
L
Linus Torvalds 已提交
2238

2239 2240
	drive->pc_callback = ide_tape_callback;

2241
	spin_lock_init(&tape->lock);
L
Linus Torvalds 已提交
2242
	drive->dsc_overlap = 1;
2243 2244 2245 2246
	if (drive->hwif->host_flags & IDE_HFLAG_NO_DSC) {
		printk(KERN_INFO "ide-tape: %s: disabling DSC overlap\n",
				 tape->name);
		drive->dsc_overlap = 0;
L
Linus Torvalds 已提交
2247 2248
	}
	/* Seagate Travan drives do not support DSC overlap. */
2249
	if (strstr((char *)&drive->id[ATA_ID_PROD], "Seagate STT3401"))
L
Linus Torvalds 已提交
2250 2251 2252 2253 2254
		drive->dsc_overlap = 0;
	tape->minor = minor;
	tape->name[0] = 'h';
	tape->name[1] = 't';
	tape->name[2] = '0' + minor;
2255
	tape->chrdev_dir = IDETAPE_DIR_NONE;
2256 2257

	*((u16 *)&gcw) = drive->id[ATA_ID_CONFIG];
2258 2259 2260

	/* Command packet DRQ type */
	if (((gcw[0] & 0x60) >> 5) == 1)
2261
		set_bit(IDE_AFLAG_DRQ_INTERRUPT, &drive->atapi_flags);
L
Linus Torvalds 已提交
2262 2263 2264

	idetape_get_inquiry_results(drive);
	idetape_get_mode_sense_results(drive);
2265
	ide_tape_get_bsize_from_bdesc(drive);
L
Linus Torvalds 已提交
2266
	tape->user_bs_factor = 1;
2267 2268
	tape->buffer_size = *ctl * tape->blk_size;
	while (tape->buffer_size > 0xffff) {
L
Linus Torvalds 已提交
2269
		printk(KERN_NOTICE "ide-tape: decreasing stage size\n");
2270
		*ctl /= 2;
2271
		tape->buffer_size = *ctl * tape->blk_size;
L
Linus Torvalds 已提交
2272
	}
2273
	buffer_size = tape->buffer_size;
2274
	tape->pages_per_buffer = buffer_size / PAGE_SIZE;
2275
	if (buffer_size % PAGE_SIZE) {
2276
		tape->pages_per_buffer++;
2277
		tape->excess_bh_size = PAGE_SIZE - buffer_size % PAGE_SIZE;
L
Linus Torvalds 已提交
2278 2279
	}

2280
	/* select the "best" DSC read/write polling freq */
2281
	speed = max(*(u16 *)&tape->caps[14], *(u16 *)&tape->caps[8]);
L
Linus Torvalds 已提交
2282

2283
	t = (IDETAPE_FIFO_THRESHOLD * tape->buffer_size * HZ) / (speed * 1000);
L
Linus Torvalds 已提交
2284 2285

	/*
2286 2287
	 * Ensure that the number we got makes sense; limit it within
	 * IDETAPE_DSC_RW_MIN and IDETAPE_DSC_RW_MAX.
L
Linus Torvalds 已提交
2288
	 */
2289 2290
	tape->best_dsc_rw_freq = clamp_t(unsigned long, t, IDETAPE_DSC_RW_MIN,
					 IDETAPE_DSC_RW_MAX);
L
Linus Torvalds 已提交
2291
	printk(KERN_INFO "ide-tape: %s <-> %s: %dKBps, %d*%dkB buffer, "
2292
		"%lums tDSC%s\n",
2293
		drive->name, tape->name, *(u16 *)&tape->caps[14],
2294 2295
		(*(u16 *)&tape->caps[16] * 512) / tape->buffer_size,
		tape->buffer_size / 1024,
2296
		tape->best_dsc_rw_freq * 1000 / HZ,
L
Linus Torvalds 已提交
2297 2298
		drive->using_dma ? ", DMA":"");

2299
	ide_proc_register_driver(drive, tape->driver);
L
Linus Torvalds 已提交
2300 2301
}

2302
static void ide_tape_remove(ide_drive_t *drive)
L
Linus Torvalds 已提交
2303 2304 2305
{
	idetape_tape_t *tape = drive->driver_data;

2306
	ide_proc_unregister_driver(drive, tape->driver);
L
Linus Torvalds 已提交
2307 2308 2309 2310 2311 2312 2313 2314 2315 2316 2317 2318

	ide_unregister_region(tape->disk);

	ide_tape_put(tape);
}

static void ide_tape_release(struct kref *kref)
{
	struct ide_tape_obj *tape = to_ide_tape(kref);
	ide_drive_t *drive = tape->drive;
	struct gendisk *g = tape->disk;

2319
	BUG_ON(tape->merge_bh_size);
2320

L
Linus Torvalds 已提交
2321 2322
	drive->dsc_overlap = 0;
	drive->driver_data = NULL;
2323
	device_destroy(idetape_sysfs_class, MKDEV(IDETAPE_MAJOR, tape->minor));
2324 2325
	device_destroy(idetape_sysfs_class,
			MKDEV(IDETAPE_MAJOR, tape->minor + 128));
L
Linus Torvalds 已提交
2326 2327 2328 2329 2330 2331
	idetape_devs[tape->minor] = NULL;
	g->private_data = NULL;
	put_disk(g);
	kfree(tape);
}

2332
#ifdef CONFIG_IDE_PROC_FS
L
Linus Torvalds 已提交
2333 2334 2335 2336 2337 2338 2339 2340 2341 2342 2343 2344 2345 2346 2347 2348 2349 2350 2351
static int proc_idetape_read_name
	(char *page, char **start, off_t off, int count, int *eof, void *data)
{
	ide_drive_t	*drive = (ide_drive_t *) data;
	idetape_tape_t	*tape = drive->driver_data;
	char		*out = page;
	int		len;

	len = sprintf(out, "%s\n", tape->name);
	PROC_IDE_READ_RETURN(page, start, off, count, eof, len);
}

static ide_proc_entry_t idetape_proc[] = {
	{ "capacity",	S_IFREG|S_IRUGO,	proc_ide_read_capacity, NULL },
	{ "name",	S_IFREG|S_IRUGO,	proc_idetape_read_name,	NULL },
	{ NULL, 0, NULL, NULL }
};
#endif

2352
static int ide_tape_probe(ide_drive_t *);
L
Linus Torvalds 已提交
2353 2354

static ide_driver_t idetape_driver = {
2355
	.gen_driver = {
2356
		.owner		= THIS_MODULE,
2357 2358 2359
		.name		= "ide-tape",
		.bus		= &ide_bus_type,
	},
2360 2361
	.probe			= ide_tape_probe,
	.remove			= ide_tape_remove,
L
Linus Torvalds 已提交
2362 2363 2364 2365 2366
	.version		= IDETAPE_VERSION,
	.media			= ide_tape,
	.do_request		= idetape_do_request,
	.end_request		= idetape_end_request,
	.error			= __ide_error,
2367
#ifdef CONFIG_IDE_PROC_FS
L
Linus Torvalds 已提交
2368
	.proc			= idetape_proc,
2369
	.settings		= idetape_settings,
2370
#endif
L
Linus Torvalds 已提交
2371 2372
};

2373
/* Our character device supporting functions, passed to register_chrdev. */
2374
static const struct file_operations idetape_fops = {
L
Linus Torvalds 已提交
2375 2376 2377 2378 2379 2380 2381 2382 2383 2384 2385 2386 2387
	.owner		= THIS_MODULE,
	.read		= idetape_chrdev_read,
	.write		= idetape_chrdev_write,
	.ioctl		= idetape_chrdev_ioctl,
	.open		= idetape_chrdev_open,
	.release	= idetape_chrdev_release,
};

static int idetape_open(struct inode *inode, struct file *filp)
{
	struct gendisk *disk = inode->i_bdev->bd_disk;
	struct ide_tape_obj *tape;

2388 2389
	tape = ide_tape_get(disk);
	if (!tape)
L
Linus Torvalds 已提交
2390 2391 2392 2393 2394 2395 2396 2397 2398 2399 2400 2401 2402 2403 2404 2405 2406 2407 2408 2409 2410 2411 2412 2413 2414 2415 2416 2417 2418 2419 2420 2421 2422 2423
		return -ENXIO;

	return 0;
}

static int idetape_release(struct inode *inode, struct file *filp)
{
	struct gendisk *disk = inode->i_bdev->bd_disk;
	struct ide_tape_obj *tape = ide_tape_g(disk);

	ide_tape_put(tape);

	return 0;
}

static int idetape_ioctl(struct inode *inode, struct file *file,
			unsigned int cmd, unsigned long arg)
{
	struct block_device *bdev = inode->i_bdev;
	struct ide_tape_obj *tape = ide_tape_g(bdev->bd_disk);
	ide_drive_t *drive = tape->drive;
	int err = generic_ide_ioctl(drive, file, bdev, cmd, arg);
	if (err == -EINVAL)
		err = idetape_blkdev_ioctl(drive, cmd, arg);
	return err;
}

static struct block_device_operations idetape_block_ops = {
	.owner		= THIS_MODULE,
	.open		= idetape_open,
	.release	= idetape_release,
	.ioctl		= idetape_ioctl,
};

2424
static int ide_tape_probe(ide_drive_t *drive)
L
Linus Torvalds 已提交
2425 2426 2427 2428 2429 2430 2431
{
	idetape_tape_t *tape;
	struct gendisk *g;
	int minor;

	if (!strstr("ide-tape", drive->driver_req))
		goto failed;
2432

L
Linus Torvalds 已提交
2433 2434
	if (drive->media != ide_tape)
		goto failed;
2435

2436
	if (drive->id_read == 1 && !ide_check_atapi_device(drive, DRV_NAME)) {
2437 2438
		printk(KERN_ERR "ide-tape: %s: not supported by this version of"
				" the driver\n", drive->name);
L
Linus Torvalds 已提交
2439 2440
		goto failed;
	}
2441
	tape = kzalloc(sizeof(idetape_tape_t), GFP_KERNEL);
L
Linus Torvalds 已提交
2442
	if (tape == NULL) {
2443 2444
		printk(KERN_ERR "ide-tape: %s: Can't allocate a tape struct\n",
				drive->name);
L
Linus Torvalds 已提交
2445 2446 2447 2448 2449 2450 2451 2452 2453 2454 2455 2456 2457 2458 2459 2460 2461 2462 2463
		goto failed;
	}

	g = alloc_disk(1 << PARTN_BITS);
	if (!g)
		goto out_free_tape;

	ide_init_disk(g, drive);

	kref_init(&tape->kref);

	tape->drive = drive;
	tape->driver = &idetape_driver;
	tape->disk = g;

	g->private_data = &tape->driver;

	drive->driver_data = tape;

2464
	mutex_lock(&idetape_ref_mutex);
L
Linus Torvalds 已提交
2465 2466 2467
	for (minor = 0; idetape_devs[minor]; minor++)
		;
	idetape_devs[minor] = tape;
2468
	mutex_unlock(&idetape_ref_mutex);
L
Linus Torvalds 已提交
2469 2470 2471

	idetape_setup(drive, tape, minor);

2472 2473 2474 2475 2476 2477
	device_create_drvdata(idetape_sysfs_class, &drive->gendev,
			      MKDEV(IDETAPE_MAJOR, minor), NULL,
			      "%s", tape->name);
	device_create_drvdata(idetape_sysfs_class, &drive->gendev,
			      MKDEV(IDETAPE_MAJOR, minor + 128), NULL,
			      "n%s", tape->name);
2478

L
Linus Torvalds 已提交
2479 2480 2481 2482
	g->fops = &idetape_block_ops;
	ide_register_region(g);

	return 0;
2483

L
Linus Torvalds 已提交
2484 2485 2486
out_free_tape:
	kfree(tape);
failed:
2487
	return -ENODEV;
L
Linus Torvalds 已提交
2488 2489
}

2490
static void __exit idetape_exit(void)
L
Linus Torvalds 已提交
2491
{
2492
	driver_unregister(&idetape_driver.gen_driver);
2493
	class_destroy(idetape_sysfs_class);
L
Linus Torvalds 已提交
2494 2495 2496
	unregister_chrdev(IDETAPE_MAJOR, "ht");
}

2497
static int __init idetape_init(void)
L
Linus Torvalds 已提交
2498
{
2499 2500 2501 2502 2503 2504 2505 2506 2507
	int error = 1;
	idetape_sysfs_class = class_create(THIS_MODULE, "ide_tape");
	if (IS_ERR(idetape_sysfs_class)) {
		idetape_sysfs_class = NULL;
		printk(KERN_ERR "Unable to create sysfs class for ide tapes\n");
		error = -EBUSY;
		goto out;
	}

L
Linus Torvalds 已提交
2508
	if (register_chrdev(IDETAPE_MAJOR, "ht", &idetape_fops)) {
2509 2510
		printk(KERN_ERR "ide-tape: Failed to register chrdev"
				" interface\n");
2511 2512
		error = -EBUSY;
		goto out_free_class;
L
Linus Torvalds 已提交
2513
	}
2514 2515 2516 2517 2518 2519 2520 2521 2522 2523 2524 2525 2526

	error = driver_register(&idetape_driver.gen_driver);
	if (error)
		goto out_free_driver;

	return 0;

out_free_driver:
	driver_unregister(&idetape_driver.gen_driver);
out_free_class:
	class_destroy(idetape_sysfs_class);
out:
	return error;
L
Linus Torvalds 已提交
2527 2528
}

2529
MODULE_ALIAS("ide:*m-tape*");
L
Linus Torvalds 已提交
2530 2531 2532
module_init(idetape_init);
module_exit(idetape_exit);
MODULE_ALIAS_CHARDEV_MAJOR(IDETAPE_MAJOR);
2533 2534
MODULE_DESCRIPTION("ATAPI Streaming TAPE Driver");
MODULE_LICENSE("GPL");