blob: 203f22e816c0ecb21fb32ddab31b490162e1b98d [file] [log] [blame]
Linus Torvalds1da177e2005-04-16 15:20:36 -07001/*
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 Rewritten from Dwayne Forsyth's SCSI tape driver by Kai Makisara.
7 Contribution and ideas from several people including (in alphabetical
8 order) Klaus Ehrenfried, Eugene Exarevsky, Eric Lee Green, Wolfgang Denk,
9 Steve Hirsch, Andreas Koppenh"ofer, Michael Leodolter, Eyal Lebedinsky,
10 Michael Schaefer, J"org Weule, and Eric Youngdale.
11
Kai Makisarafd66c1b2008-01-17 22:45:22 +020012 Copyright 1992 - 2008 Kai Makisara
Linus Torvalds1da177e2005-04-16 15:20:36 -070013 email Kai.Makisara@kolumbus.fi
14
15 Some small formal changes - aeb, 950809
16
17 Last modified: 18-JAN-1998 Richard Gooch <rgooch@atnf.csiro.au> Devfs support
18 */
19
Kai Makisara626dcb12008-07-11 15:05:25 +030020static const char *verstr = "20080504";
Linus Torvalds1da177e2005-04-16 15:20:36 -070021
22#include <linux/module.h>
23
24#include <linux/fs.h>
25#include <linux/kernel.h>
26#include <linux/sched.h>
27#include <linux/mm.h>
28#include <linux/init.h>
29#include <linux/string.h>
30#include <linux/errno.h>
31#include <linux/mtio.h>
Kai Makisara 16c4b3e2005-05-01 18:11:55 +030032#include <linux/cdrom.h>
Linus Torvalds1da177e2005-04-16 15:20:36 -070033#include <linux/ioctl.h>
34#include <linux/fcntl.h>
35#include <linux/spinlock.h>
36#include <linux/blkdev.h>
37#include <linux/moduleparam.h>
Linus Torvalds1da177e2005-04-16 15:20:36 -070038#include <linux/cdev.h>
39#include <linux/delay.h>
Arjan van de Ven0b950672006-01-11 13:16:10 +010040#include <linux/mutex.h>
Jonathan Corbetb3369c62008-05-15 16:08:15 -060041#include <linux/smp_lock.h>
Linus Torvalds1da177e2005-04-16 15:20:36 -070042
43#include <asm/uaccess.h>
44#include <asm/dma.h>
45#include <asm/system.h>
46
47#include <scsi/scsi.h>
48#include <scsi/scsi_dbg.h>
49#include <scsi/scsi_device.h>
50#include <scsi/scsi_driver.h>
51#include <scsi/scsi_eh.h>
52#include <scsi/scsi_host.h>
53#include <scsi/scsi_ioctl.h>
Kai Makisara 16c4b3e2005-05-01 18:11:55 +030054#include <scsi/sg.h>
Linus Torvalds1da177e2005-04-16 15:20:36 -070055
56
57/* The driver prints some debugging information on the console if DEBUG
58 is defined and non-zero. */
59#define DEBUG 0
60
61#if DEBUG
62/* The message level for the debug messages is currently set to KERN_NOTICE
63 so that people can easily see the messages. Later when the debugging messages
64 in the drivers are more widely classified, this may be changed to KERN_DEBUG. */
65#define ST_DEB_MSG KERN_NOTICE
66#define DEB(a) a
67#define DEBC(a) if (debugging) { a ; }
68#else
69#define DEB(a)
70#define DEBC(a)
71#endif
72
73#define ST_KILOBYTE 1024
74
75#include "st_options.h"
76#include "st.h"
77
78static int buffer_kbs;
79static int max_sg_segs;
80static int try_direct_io = TRY_DIRECT_IO;
81static int try_rdio = 1;
82static int try_wdio = 1;
83
84static int st_dev_max;
85static int st_nr_dev;
86
gregkh@suse.ded2538782005-03-23 09:55:22 -080087static struct class *st_sysfs_class;
Linus Torvalds1da177e2005-04-16 15:20:36 -070088
89MODULE_AUTHOR("Kai Makisara");
Rene Hermanf018fa52006-03-08 00:14:20 -080090MODULE_DESCRIPTION("SCSI tape (st) driver");
Linus Torvalds1da177e2005-04-16 15:20:36 -070091MODULE_LICENSE("GPL");
Rene Hermanf018fa52006-03-08 00:14:20 -080092MODULE_ALIAS_CHARDEV_MAJOR(SCSI_TAPE_MAJOR);
Michael Tokarevd7b8bcb2006-10-27 16:02:37 +040093MODULE_ALIAS_SCSI_DEVICE(TYPE_TAPE);
Linus Torvalds1da177e2005-04-16 15:20:36 -070094
95/* Set 'perm' (4th argument) to 0 to disable module_param's definition
96 * of sysfs parameters (which module_param doesn't yet support).
97 * Sysfs parameters defined explicitly later.
98 */
99module_param_named(buffer_kbs, buffer_kbs, int, 0);
100MODULE_PARM_DESC(buffer_kbs, "Default driver buffer size for fixed block mode (KB; 32)");
101module_param_named(max_sg_segs, max_sg_segs, int, 0);
102MODULE_PARM_DESC(max_sg_segs, "Maximum number of scatter/gather segments to use (256)");
103module_param_named(try_direct_io, try_direct_io, int, 0);
104MODULE_PARM_DESC(try_direct_io, "Try direct I/O between user buffer and tape drive (1)");
105
106/* Extra parameters for testing */
107module_param_named(try_rdio, try_rdio, int, 0);
108MODULE_PARM_DESC(try_rdio, "Try direct read i/o when possible");
109module_param_named(try_wdio, try_wdio, int, 0);
110MODULE_PARM_DESC(try_wdio, "Try direct write i/o when possible");
111
112#ifndef MODULE
113static int write_threshold_kbs; /* retained for compatibility */
114static struct st_dev_parm {
115 char *name;
116 int *val;
117} parms[] __initdata = {
118 {
119 "buffer_kbs", &buffer_kbs
120 },
121 { /* Retained for compatibility with 2.4 */
122 "write_threshold_kbs", &write_threshold_kbs
123 },
124 {
125 "max_sg_segs", NULL
126 },
127 {
128 "try_direct_io", &try_direct_io
129 }
130};
131#endif
132
133/* Restrict the number of modes so that names for all are assigned */
134#if ST_NBR_MODES > 16
135#error "Maximum number of modes is 16"
136#endif
137/* Bit reversed order to get same names for same minors with all
138 mode counts */
Arjan van de Ven0ad78202005-11-28 16:22:25 +0100139static const char *st_formats[] = {
Linus Torvalds1da177e2005-04-16 15:20:36 -0700140 "", "r", "k", "s", "l", "t", "o", "u",
141 "m", "v", "p", "x", "a", "y", "q", "z"};
142
143/* The default definitions have been moved to st_options.h */
144
145#define ST_FIXED_BUFFER_SIZE (ST_FIXED_BUFFER_BLOCKS * ST_KILOBYTE)
146
147/* The buffer size should fit into the 24 bits for length in the
148 6-byte SCSI read and write commands. */
149#if ST_FIXED_BUFFER_SIZE >= (2 << 24 - 1)
150#error "Buffer size should not exceed (2 << 24 - 1) bytes!"
151#endif
152
153static int debugging = DEBUG;
154
155#define MAX_RETRIES 0
156#define MAX_WRITE_RETRIES 0
157#define MAX_READY_RETRIES 0
158#define NO_TAPE NOT_READY
159
160#define ST_TIMEOUT (900 * HZ)
161#define ST_LONG_TIMEOUT (14000 * HZ)
162
163/* Remove mode bits and auto-rewind bit (7) */
164#define TAPE_NR(x) ( ((iminor(x) & ~255) >> (ST_NBR_MODE_BITS + 1)) | \
165 (iminor(x) & ~(-1 << ST_MODE_SHIFT)) )
166#define TAPE_MODE(x) ((iminor(x) & ST_MODE_MASK) >> ST_MODE_SHIFT)
167
168/* Construct the minor number from the device (d), mode (m), and non-rewind (n) data */
169#define TAPE_MINOR(d, m, n) (((d & ~(255 >> (ST_NBR_MODE_BITS + 1))) << (ST_NBR_MODE_BITS + 1)) | \
170 (d & (255 >> (ST_NBR_MODE_BITS + 1))) | (m << ST_MODE_SHIFT) | ((n != 0) << 7) )
171
172/* Internal ioctl to set both density (uppermost 8 bits) and blocksize (lower
173 24 bits) */
174#define SET_DENS_AND_BLK 0x10001
175
176static DEFINE_RWLOCK(st_dev_arr_lock);
177
178static int st_fixed_buffer_size = ST_FIXED_BUFFER_SIZE;
179static int st_max_sg_segs = ST_MAX_SG;
180
181static struct scsi_tape **scsi_tapes = NULL;
182
183static int modes_defined;
184
185static struct st_buffer *new_tape_buffer(int, int, int);
186static int enlarge_buffer(struct st_buffer *, int, int);
Kai Makisara40f6b362008-02-24 22:23:24 +0200187static void clear_buffer(struct st_buffer *);
Linus Torvalds1da177e2005-04-16 15:20:36 -0700188static void normalize_buffer(struct st_buffer *);
189static int append_to_buffer(const char __user *, struct st_buffer *, int);
190static int from_buffer(struct st_buffer *, char __user *, int);
191static void move_buffer_data(struct st_buffer *, int);
192static void buf_to_sg(struct st_buffer *, unsigned int);
193
Linus Torvalds1da177e2005-04-16 15:20:36 -0700194static int sgl_map_user_pages(struct scatterlist *, const unsigned int,
195 unsigned long, size_t, int);
196static int sgl_unmap_user_pages(struct scatterlist *, const unsigned int, int);
197
198static int st_probe(struct device *);
199static int st_remove(struct device *);
Linus Torvalds1da177e2005-04-16 15:20:36 -0700200
Robert P. J. Day405ae7d2007-02-17 19:13:42 +0100201static int do_create_sysfs_files(void);
202static void do_remove_sysfs_files(void);
Jeff Garzik13026a62006-10-04 06:00:38 -0400203static int do_create_class_files(struct scsi_tape *, int, int);
Linus Torvalds1da177e2005-04-16 15:20:36 -0700204
205static struct scsi_driver st_template = {
206 .owner = THIS_MODULE,
207 .gendrv = {
208 .name = "st",
209 .probe = st_probe,
210 .remove = st_remove,
211 },
Linus Torvalds1da177e2005-04-16 15:20:36 -0700212};
213
214static int st_compression(struct scsi_tape *, int);
215
216static int find_partition(struct scsi_tape *);
217static int switch_partition(struct scsi_tape *);
218
219static int st_int_ioctl(struct scsi_tape *, unsigned int, unsigned long);
220
Kai Makisaraf03a5672005-08-02 13:40:47 +0300221static void scsi_tape_release(struct kref *);
222
223#define to_scsi_tape(obj) container_of(obj, struct scsi_tape, kref)
224
Arjan van de Ven0b950672006-01-11 13:16:10 +0100225static DEFINE_MUTEX(st_ref_mutex);
Kai Makisaraf03a5672005-08-02 13:40:47 +0300226
Linus Torvalds1da177e2005-04-16 15:20:36 -0700227
228#include "osst_detect.h"
229#ifndef SIGS_FROM_OSST
230#define SIGS_FROM_OSST \
231 {"OnStream", "SC-", "", "osst"}, \
232 {"OnStream", "DI-", "", "osst"}, \
233 {"OnStream", "DP-", "", "osst"}, \
234 {"OnStream", "USB", "", "osst"}, \
235 {"OnStream", "FW-", "", "osst"}
236#endif
237
Kai Makisaraf03a5672005-08-02 13:40:47 +0300238static struct scsi_tape *scsi_tape_get(int dev)
239{
240 struct scsi_tape *STp = NULL;
241
Arjan van de Ven0b950672006-01-11 13:16:10 +0100242 mutex_lock(&st_ref_mutex);
Kai Makisaraf03a5672005-08-02 13:40:47 +0300243 write_lock(&st_dev_arr_lock);
244
245 if (dev < st_dev_max && scsi_tapes != NULL)
246 STp = scsi_tapes[dev];
247 if (!STp) goto out;
248
249 kref_get(&STp->kref);
250
251 if (!STp->device)
252 goto out_put;
253
254 if (scsi_device_get(STp->device))
255 goto out_put;
256
257 goto out;
258
259out_put:
260 kref_put(&STp->kref, scsi_tape_release);
261 STp = NULL;
262out:
263 write_unlock(&st_dev_arr_lock);
Arjan van de Ven0b950672006-01-11 13:16:10 +0100264 mutex_unlock(&st_ref_mutex);
Kai Makisaraf03a5672005-08-02 13:40:47 +0300265 return STp;
266}
267
268static void scsi_tape_put(struct scsi_tape *STp)
269{
270 struct scsi_device *sdev = STp->device;
271
Arjan van de Ven0b950672006-01-11 13:16:10 +0100272 mutex_lock(&st_ref_mutex);
Kai Makisaraf03a5672005-08-02 13:40:47 +0300273 kref_put(&STp->kref, scsi_tape_release);
274 scsi_device_put(sdev);
Arjan van de Ven0b950672006-01-11 13:16:10 +0100275 mutex_unlock(&st_ref_mutex);
Kai Makisaraf03a5672005-08-02 13:40:47 +0300276}
277
Linus Torvalds1da177e2005-04-16 15:20:36 -0700278struct st_reject_data {
279 char *vendor;
280 char *model;
281 char *rev;
282 char *driver_hint; /* Name of the correct driver, NULL if unknown */
283};
284
285static struct st_reject_data reject_list[] = {
286 /* {"XXX", "Yy-", "", NULL}, example */
287 SIGS_FROM_OSST,
288 {NULL, }};
289
290/* If the device signature is on the list of incompatible drives, the
291 function returns a pointer to the name of the correct driver (if known) */
292static char * st_incompatible(struct scsi_device* SDp)
293{
294 struct st_reject_data *rp;
295
296 for (rp=&(reject_list[0]); rp->vendor != NULL; rp++)
297 if (!strncmp(rp->vendor, SDp->vendor, strlen(rp->vendor)) &&
298 !strncmp(rp->model, SDp->model, strlen(rp->model)) &&
299 !strncmp(rp->rev, SDp->rev, strlen(rp->rev))) {
300 if (rp->driver_hint)
301 return rp->driver_hint;
302 else
303 return "unknown";
304 }
305 return NULL;
306}
307
308
309static inline char *tape_name(struct scsi_tape *tape)
310{
311 return tape->disk->disk_name;
312}
313
314
Mike Christie8b05b772005-11-08 04:06:44 -0600315static void st_analyze_sense(struct st_request *SRpnt, struct st_cmdstatus *s)
Linus Torvalds1da177e2005-04-16 15:20:36 -0700316{
317 const u8 *ucp;
Mike Christie8b05b772005-11-08 04:06:44 -0600318 const u8 *sense = SRpnt->sense;
Linus Torvalds1da177e2005-04-16 15:20:36 -0700319
Mike Christie8b05b772005-11-08 04:06:44 -0600320 s->have_sense = scsi_normalize_sense(SRpnt->sense,
321 SCSI_SENSE_BUFFERSIZE, &s->sense_hdr);
Linus Torvalds1da177e2005-04-16 15:20:36 -0700322 s->flags = 0;
323
324 if (s->have_sense) {
325 s->deferred = 0;
326 s->remainder_valid =
327 scsi_get_sense_info_fld(sense, SCSI_SENSE_BUFFERSIZE, &s->uremainder64);
328 switch (sense[0] & 0x7f) {
329 case 0x71:
330 s->deferred = 1;
331 case 0x70:
332 s->fixed_format = 1;
333 s->flags = sense[2] & 0xe0;
334 break;
335 case 0x73:
336 s->deferred = 1;
337 case 0x72:
338 s->fixed_format = 0;
339 ucp = scsi_sense_desc_find(sense, SCSI_SENSE_BUFFERSIZE, 4);
340 s->flags = ucp ? (ucp[3] & 0xe0) : 0;
341 break;
342 }
343 }
344}
345
346
347/* Convert the result to success code */
Mike Christie8b05b772005-11-08 04:06:44 -0600348static int st_chk_result(struct scsi_tape *STp, struct st_request * SRpnt)
Linus Torvalds1da177e2005-04-16 15:20:36 -0700349{
Mike Christie8b05b772005-11-08 04:06:44 -0600350 int result = SRpnt->result;
Linus Torvalds1da177e2005-04-16 15:20:36 -0700351 u8 scode;
352 DEB(const char *stp;)
353 char *name = tape_name(STp);
354 struct st_cmdstatus *cmdstatp;
355
356 if (!result)
357 return 0;
358
359 cmdstatp = &STp->buffer->cmdstat;
Kai Makisaraf03a5672005-08-02 13:40:47 +0300360 st_analyze_sense(SRpnt, cmdstatp);
Linus Torvalds1da177e2005-04-16 15:20:36 -0700361
362 if (cmdstatp->have_sense)
363 scode = STp->buffer->cmdstat.sense_hdr.sense_key;
364 else
365 scode = 0;
366
367 DEB(
368 if (debugging) {
Mike Christie8b05b772005-11-08 04:06:44 -0600369 printk(ST_DEB_MSG "%s: Error: %x, cmd: %x %x %x %x %x %x\n",
Linus Torvalds1da177e2005-04-16 15:20:36 -0700370 name, result,
Mike Christie8b05b772005-11-08 04:06:44 -0600371 SRpnt->cmd[0], SRpnt->cmd[1], SRpnt->cmd[2],
372 SRpnt->cmd[3], SRpnt->cmd[4], SRpnt->cmd[5]);
Linus Torvalds1da177e2005-04-16 15:20:36 -0700373 if (cmdstatp->have_sense)
Luben Tuikov4e73ea72006-07-07 00:02:18 -0700374 __scsi_print_sense(name, SRpnt->sense, SCSI_SENSE_BUFFERSIZE);
Linus Torvalds1da177e2005-04-16 15:20:36 -0700375 } ) /* end DEB */
376 if (!debugging) { /* Abnormal conditions for tape */
377 if (!cmdstatp->have_sense)
378 printk(KERN_WARNING
379 "%s: Error %x (sugg. bt 0x%x, driver bt 0x%x, host bt 0x%x).\n",
380 name, result, suggestion(result),
381 driver_byte(result) & DRIVER_MASK, host_byte(result));
382 else if (cmdstatp->have_sense &&
383 scode != NO_SENSE &&
384 scode != RECOVERED_ERROR &&
385 /* scode != UNIT_ATTENTION && */
386 scode != BLANK_CHECK &&
387 scode != VOLUME_OVERFLOW &&
Mike Christie8b05b772005-11-08 04:06:44 -0600388 SRpnt->cmd[0] != MODE_SENSE &&
389 SRpnt->cmd[0] != TEST_UNIT_READY) {
Luben Tuikov4e73ea72006-07-07 00:02:18 -0700390
391 __scsi_print_sense(name, SRpnt->sense, SCSI_SENSE_BUFFERSIZE);
Linus Torvalds1da177e2005-04-16 15:20:36 -0700392 }
393 }
394
395 if (cmdstatp->fixed_format &&
396 STp->cln_mode >= EXTENDED_SENSE_START) { /* Only fixed format sense */
397 if (STp->cln_sense_value)
Mike Christie8b05b772005-11-08 04:06:44 -0600398 STp->cleaning_req |= ((SRpnt->sense[STp->cln_mode] &
Linus Torvalds1da177e2005-04-16 15:20:36 -0700399 STp->cln_sense_mask) == STp->cln_sense_value);
400 else
Mike Christie8b05b772005-11-08 04:06:44 -0600401 STp->cleaning_req |= ((SRpnt->sense[STp->cln_mode] &
Linus Torvalds1da177e2005-04-16 15:20:36 -0700402 STp->cln_sense_mask) != 0);
403 }
404 if (cmdstatp->have_sense &&
405 cmdstatp->sense_hdr.asc == 0 && cmdstatp->sense_hdr.ascq == 0x17)
406 STp->cleaning_req = 1; /* ASC and ASCQ => cleaning requested */
407
408 STp->pos_unknown |= STp->device->was_reset;
409
410 if (cmdstatp->have_sense &&
411 scode == RECOVERED_ERROR
412#if ST_RECOVERED_WRITE_FATAL
Mike Christie8b05b772005-11-08 04:06:44 -0600413 && SRpnt->cmd[0] != WRITE_6
414 && SRpnt->cmd[0] != WRITE_FILEMARKS
Linus Torvalds1da177e2005-04-16 15:20:36 -0700415#endif
416 ) {
417 STp->recover_count++;
418 STp->recover_reg++;
419
420 DEB(
421 if (debugging) {
Mike Christie8b05b772005-11-08 04:06:44 -0600422 if (SRpnt->cmd[0] == READ_6)
Linus Torvalds1da177e2005-04-16 15:20:36 -0700423 stp = "read";
Mike Christie8b05b772005-11-08 04:06:44 -0600424 else if (SRpnt->cmd[0] == WRITE_6)
Linus Torvalds1da177e2005-04-16 15:20:36 -0700425 stp = "write";
426 else
427 stp = "ioctl";
428 printk(ST_DEB_MSG "%s: Recovered %s error (%d).\n", name, stp,
429 STp->recover_count);
430 } ) /* end DEB */
431
432 if (cmdstatp->flags == 0)
433 return 0;
434 }
435 return (-EIO);
436}
437
438
439/* Wakeup from interrupt */
Mike Christie8b05b772005-11-08 04:06:44 -0600440static void st_sleep_done(void *data, char *sense, int result, int resid)
Linus Torvalds1da177e2005-04-16 15:20:36 -0700441{
Mike Christie8b05b772005-11-08 04:06:44 -0600442 struct st_request *SRpnt = data;
443 struct scsi_tape *STp = SRpnt->stp;
Linus Torvalds1da177e2005-04-16 15:20:36 -0700444
Mike Christie8b05b772005-11-08 04:06:44 -0600445 memcpy(SRpnt->sense, sense, SCSI_SENSE_BUFFERSIZE);
446 (STp->buffer)->cmdstat.midlevel_result = SRpnt->result = result;
Kai Makisara40f6b362008-02-24 22:23:24 +0200447 (STp->buffer)->cmdstat.residual = resid;
Linus Torvalds1da177e2005-04-16 15:20:36 -0700448 DEB( STp->write_pending = 0; )
449
Mike Christie8b05b772005-11-08 04:06:44 -0600450 if (SRpnt->waiting)
451 complete(SRpnt->waiting);
452}
453
FUJITA Tomonori4deba242008-12-05 15:25:20 +0900454static struct st_request *st_allocate_request(struct scsi_tape *stp)
Mike Christie8b05b772005-11-08 04:06:44 -0600455{
FUJITA Tomonori4deba242008-12-05 15:25:20 +0900456 struct st_request *streq;
457
458 streq = kzalloc(sizeof(*streq), GFP_KERNEL);
459 if (streq)
460 streq->stp = stp;
461 else {
462 DEBC(printk(KERN_ERR "%s: Can't get SCSI request.\n",
463 tape_name(stp)););
464 if (signal_pending(current))
465 stp->buffer->syscall_result = -EINTR;
466 else
467 stp->buffer->syscall_result = -EBUSY;
468 }
469
470 return streq;
Mike Christie8b05b772005-11-08 04:06:44 -0600471}
472
473static void st_release_request(struct st_request *streq)
474{
475 kfree(streq);
Linus Torvalds1da177e2005-04-16 15:20:36 -0700476}
477
478/* Do the scsi command. Waits until command performed if do_wait is true.
479 Otherwise write_behind_check() is used to check that the command
480 has finished. */
Mike Christie8b05b772005-11-08 04:06:44 -0600481static struct st_request *
482st_do_scsi(struct st_request * SRpnt, struct scsi_tape * STp, unsigned char *cmd,
Linus Torvalds1da177e2005-04-16 15:20:36 -0700483 int bytes, int direction, int timeout, int retries, int do_wait)
484{
Kai Makisaraf03a5672005-08-02 13:40:47 +0300485 struct completion *waiting;
Linus Torvalds1da177e2005-04-16 15:20:36 -0700486
Kai Makisaraf03a5672005-08-02 13:40:47 +0300487 /* if async, make sure there's no command outstanding */
488 if (!do_wait && ((STp->buffer)->last_SRpnt)) {
489 printk(KERN_ERR "%s: Async command already active.\n",
490 tape_name(STp));
491 if (signal_pending(current))
492 (STp->buffer)->syscall_result = (-EINTR);
493 else
494 (STp->buffer)->syscall_result = (-EBUSY);
495 return NULL;
496 }
497
FUJITA Tomonori4deba242008-12-05 15:25:20 +0900498 if (!SRpnt) {
499 SRpnt = st_allocate_request(STp);
500 if (!SRpnt)
Linus Torvalds1da177e2005-04-16 15:20:36 -0700501 return NULL;
Linus Torvalds1da177e2005-04-16 15:20:36 -0700502 }
503
Kai Makisaraf03a5672005-08-02 13:40:47 +0300504 /* If async IO, set last_SRpnt. This ptr tells write_behind_check
505 which IO is outstanding. It's nulled out when the IO completes. */
506 if (!do_wait)
507 (STp->buffer)->last_SRpnt = SRpnt;
508
509 waiting = &STp->wait;
510 init_completion(waiting);
Mike Christie8b05b772005-11-08 04:06:44 -0600511 SRpnt->waiting = waiting;
512
513 if (!STp->buffer->do_dio)
514 buf_to_sg(STp->buffer, bytes);
515
516 memcpy(SRpnt->cmd, cmd, sizeof(SRpnt->cmd));
Linus Torvalds1da177e2005-04-16 15:20:36 -0700517 STp->buffer->cmdstat.have_sense = 0;
Mike Christie8b05b772005-11-08 04:06:44 -0600518 STp->buffer->syscall_result = 0;
Linus Torvalds1da177e2005-04-16 15:20:36 -0700519
brking@us.ibm.combb1d1072006-01-23 15:03:22 -0600520 if (scsi_execute_async(STp->device, cmd, COMMAND_SIZE(cmd[0]), direction,
Mike Christie8b05b772005-11-08 04:06:44 -0600521 &((STp->buffer)->sg[0]), bytes, (STp->buffer)->sg_segs,
Kai Makisara787926b2005-11-13 10:04:44 +0200522 timeout, retries, SRpnt, st_sleep_done, GFP_KERNEL)) {
Mike Christie8b05b772005-11-08 04:06:44 -0600523 /* could not allocate the buffer or request was too large */
524 (STp->buffer)->syscall_result = (-EBUSY);
Kai Makisara787926b2005-11-13 10:04:44 +0200525 (STp->buffer)->last_SRpnt = NULL;
526 }
Mike Christie8b05b772005-11-08 04:06:44 -0600527 else if (do_wait) {
Kai Makisaraf03a5672005-08-02 13:40:47 +0300528 wait_for_completion(waiting);
Mike Christie8b05b772005-11-08 04:06:44 -0600529 SRpnt->waiting = NULL;
Linus Torvalds1da177e2005-04-16 15:20:36 -0700530 (STp->buffer)->syscall_result = st_chk_result(STp, SRpnt);
531 }
Mike Christie8b05b772005-11-08 04:06:44 -0600532
Linus Torvalds1da177e2005-04-16 15:20:36 -0700533 return SRpnt;
534}
535
536
537/* Handle the write-behind checking (waits for completion). Returns -ENOSPC if
538 write has been correct but EOM early warning reached, -EIO if write ended in
539 error or zero if write successful. Asynchronous writes are used only in
540 variable block mode. */
541static int write_behind_check(struct scsi_tape * STp)
542{
543 int retval = 0;
544 struct st_buffer *STbuffer;
545 struct st_partstat *STps;
546 struct st_cmdstatus *cmdstatp;
Mike Christie8b05b772005-11-08 04:06:44 -0600547 struct st_request *SRpnt;
Linus Torvalds1da177e2005-04-16 15:20:36 -0700548
549 STbuffer = STp->buffer;
550 if (!STbuffer->writing)
551 return 0;
552
553 DEB(
554 if (STp->write_pending)
555 STp->nbr_waits++;
556 else
557 STp->nbr_finished++;
558 ) /* end DEB */
559
560 wait_for_completion(&(STp->wait));
Kai Makisaraf03a5672005-08-02 13:40:47 +0300561 SRpnt = STbuffer->last_SRpnt;
562 STbuffer->last_SRpnt = NULL;
Mike Christie8b05b772005-11-08 04:06:44 -0600563 SRpnt->waiting = NULL;
Linus Torvalds1da177e2005-04-16 15:20:36 -0700564
Kai Makisaraf03a5672005-08-02 13:40:47 +0300565 (STp->buffer)->syscall_result = st_chk_result(STp, SRpnt);
Mike Christie8b05b772005-11-08 04:06:44 -0600566 st_release_request(SRpnt);
Linus Torvalds1da177e2005-04-16 15:20:36 -0700567
568 STbuffer->buffer_bytes -= STbuffer->writing;
569 STps = &(STp->ps[STp->partition]);
570 if (STps->drv_block >= 0) {
571 if (STp->block_size == 0)
572 STps->drv_block++;
573 else
574 STps->drv_block += STbuffer->writing / STp->block_size;
575 }
576
577 cmdstatp = &STbuffer->cmdstat;
578 if (STbuffer->syscall_result) {
579 retval = -EIO;
580 if (cmdstatp->have_sense && !cmdstatp->deferred &&
581 (cmdstatp->flags & SENSE_EOM) &&
582 (cmdstatp->sense_hdr.sense_key == NO_SENSE ||
583 cmdstatp->sense_hdr.sense_key == RECOVERED_ERROR)) {
584 /* EOM at write-behind, has all data been written? */
585 if (!cmdstatp->remainder_valid ||
586 cmdstatp->uremainder64 == 0)
587 retval = -ENOSPC;
588 }
589 if (retval == -EIO)
590 STps->drv_block = -1;
591 }
592 STbuffer->writing = 0;
593
594 DEB(if (debugging && retval)
595 printk(ST_DEB_MSG "%s: Async write error %x, return value %d.\n",
596 tape_name(STp), STbuffer->cmdstat.midlevel_result, retval);) /* end DEB */
597
598 return retval;
599}
600
601
602/* Step over EOF if it has been inadvertently crossed (ioctl not used because
603 it messes up the block number). */
604static int cross_eof(struct scsi_tape * STp, int forward)
605{
Mike Christie8b05b772005-11-08 04:06:44 -0600606 struct st_request *SRpnt;
Linus Torvalds1da177e2005-04-16 15:20:36 -0700607 unsigned char cmd[MAX_COMMAND_SIZE];
608
609 cmd[0] = SPACE;
610 cmd[1] = 0x01; /* Space FileMarks */
611 if (forward) {
612 cmd[2] = cmd[3] = 0;
613 cmd[4] = 1;
614 } else
615 cmd[2] = cmd[3] = cmd[4] = 0xff; /* -1 filemarks */
616 cmd[5] = 0;
617
618 DEBC(printk(ST_DEB_MSG "%s: Stepping over filemark %s.\n",
619 tape_name(STp), forward ? "forward" : "backward"));
620
621 SRpnt = st_do_scsi(NULL, STp, cmd, 0, DMA_NONE,
James Bottomleya02488e2008-11-30 10:36:26 -0600622 STp->device->request_queue->rq_timeout,
623 MAX_RETRIES, 1);
Linus Torvalds1da177e2005-04-16 15:20:36 -0700624 if (!SRpnt)
625 return (STp->buffer)->syscall_result;
626
Mike Christie8b05b772005-11-08 04:06:44 -0600627 st_release_request(SRpnt);
Linus Torvalds1da177e2005-04-16 15:20:36 -0700628 SRpnt = NULL;
629
630 if ((STp->buffer)->cmdstat.midlevel_result != 0)
631 printk(KERN_ERR "%s: Stepping over filemark %s failed.\n",
632 tape_name(STp), forward ? "forward" : "backward");
633
634 return (STp->buffer)->syscall_result;
635}
636
637
638/* Flush the write buffer (never need to write if variable blocksize). */
Adrian Bunk8ef8d592008-04-14 17:17:16 +0300639static int st_flush_write_buffer(struct scsi_tape * STp)
Linus Torvalds1da177e2005-04-16 15:20:36 -0700640{
Kai Makisara786231a2008-07-11 15:06:40 +0300641 int transfer, blks;
Linus Torvalds1da177e2005-04-16 15:20:36 -0700642 int result;
643 unsigned char cmd[MAX_COMMAND_SIZE];
Mike Christie8b05b772005-11-08 04:06:44 -0600644 struct st_request *SRpnt;
Linus Torvalds1da177e2005-04-16 15:20:36 -0700645 struct st_partstat *STps;
646
647 result = write_behind_check(STp);
648 if (result)
649 return result;
650
651 result = 0;
652 if (STp->dirty == 1) {
653
Kai Makisara786231a2008-07-11 15:06:40 +0300654 transfer = STp->buffer->buffer_bytes;
Linus Torvalds1da177e2005-04-16 15:20:36 -0700655 DEBC(printk(ST_DEB_MSG "%s: Flushing %d bytes.\n",
656 tape_name(STp), transfer));
657
Linus Torvalds1da177e2005-04-16 15:20:36 -0700658 memset(cmd, 0, MAX_COMMAND_SIZE);
659 cmd[0] = WRITE_6;
660 cmd[1] = 1;
661 blks = transfer / STp->block_size;
662 cmd[2] = blks >> 16;
663 cmd[3] = blks >> 8;
664 cmd[4] = blks;
665
666 SRpnt = st_do_scsi(NULL, STp, cmd, transfer, DMA_TO_DEVICE,
James Bottomleya02488e2008-11-30 10:36:26 -0600667 STp->device->request_queue->rq_timeout,
668 MAX_WRITE_RETRIES, 1);
Linus Torvalds1da177e2005-04-16 15:20:36 -0700669 if (!SRpnt)
670 return (STp->buffer)->syscall_result;
671
672 STps = &(STp->ps[STp->partition]);
673 if ((STp->buffer)->syscall_result != 0) {
674 struct st_cmdstatus *cmdstatp = &STp->buffer->cmdstat;
675
676 if (cmdstatp->have_sense && !cmdstatp->deferred &&
677 (cmdstatp->flags & SENSE_EOM) &&
678 (cmdstatp->sense_hdr.sense_key == NO_SENSE ||
679 cmdstatp->sense_hdr.sense_key == RECOVERED_ERROR) &&
680 (!cmdstatp->remainder_valid ||
681 cmdstatp->uremainder64 == 0)) { /* All written at EOM early warning */
682 STp->dirty = 0;
683 (STp->buffer)->buffer_bytes = 0;
684 if (STps->drv_block >= 0)
685 STps->drv_block += blks;
686 result = (-ENOSPC);
687 } else {
688 printk(KERN_ERR "%s: Error on flush.\n",
689 tape_name(STp));
690 STps->drv_block = (-1);
691 result = (-EIO);
692 }
693 } else {
694 if (STps->drv_block >= 0)
695 STps->drv_block += blks;
696 STp->dirty = 0;
697 (STp->buffer)->buffer_bytes = 0;
698 }
Mike Christie8b05b772005-11-08 04:06:44 -0600699 st_release_request(SRpnt);
Linus Torvalds1da177e2005-04-16 15:20:36 -0700700 SRpnt = NULL;
701 }
702 return result;
703}
704
705
706/* Flush the tape buffer. The tape will be positioned correctly unless
707 seek_next is true. */
708static int flush_buffer(struct scsi_tape *STp, int seek_next)
709{
710 int backspace, result;
711 struct st_buffer *STbuffer;
712 struct st_partstat *STps;
713
714 STbuffer = STp->buffer;
715
716 /*
717 * If there was a bus reset, block further access
718 * to this device.
719 */
720 if (STp->pos_unknown)
721 return (-EIO);
722
723 if (STp->ready != ST_READY)
724 return 0;
725 STps = &(STp->ps[STp->partition]);
726 if (STps->rw == ST_WRITING) /* Writing */
Adrian Bunk8ef8d592008-04-14 17:17:16 +0300727 return st_flush_write_buffer(STp);
Linus Torvalds1da177e2005-04-16 15:20:36 -0700728
729 if (STp->block_size == 0)
730 return 0;
731
732 backspace = ((STp->buffer)->buffer_bytes +
733 (STp->buffer)->read_pointer) / STp->block_size -
734 ((STp->buffer)->read_pointer + STp->block_size - 1) /
735 STp->block_size;
736 (STp->buffer)->buffer_bytes = 0;
737 (STp->buffer)->read_pointer = 0;
738 result = 0;
739 if (!seek_next) {
740 if (STps->eof == ST_FM_HIT) {
741 result = cross_eof(STp, 0); /* Back over the EOF hit */
742 if (!result)
743 STps->eof = ST_NOEOF;
744 else {
745 if (STps->drv_file >= 0)
746 STps->drv_file++;
747 STps->drv_block = 0;
748 }
749 }
750 if (!result && backspace > 0)
751 result = st_int_ioctl(STp, MTBSR, backspace);
752 } else if (STps->eof == ST_FM_HIT) {
753 if (STps->drv_file >= 0)
754 STps->drv_file++;
755 STps->drv_block = 0;
756 STps->eof = ST_NOEOF;
757 }
758 return result;
759
760}
761
762/* Set the mode parameters */
763static int set_mode_densblk(struct scsi_tape * STp, struct st_modedef * STm)
764{
765 int set_it = 0;
766 unsigned long arg;
767 char *name = tape_name(STp);
768
769 if (!STp->density_changed &&
770 STm->default_density >= 0 &&
771 STm->default_density != STp->density) {
772 arg = STm->default_density;
773 set_it = 1;
774 } else
775 arg = STp->density;
776 arg <<= MT_ST_DENSITY_SHIFT;
777 if (!STp->blksize_changed &&
778 STm->default_blksize >= 0 &&
779 STm->default_blksize != STp->block_size) {
780 arg |= STm->default_blksize;
781 set_it = 1;
782 } else
783 arg |= STp->block_size;
784 if (set_it &&
785 st_int_ioctl(STp, SET_DENS_AND_BLK, arg)) {
786 printk(KERN_WARNING
787 "%s: Can't set default block size to %d bytes and density %x.\n",
788 name, STm->default_blksize, STm->default_density);
789 if (modes_defined)
790 return (-EINVAL);
791 }
792 return 0;
793}
794
795
Mike Christie8b05b772005-11-08 04:06:44 -0600796/* Lock or unlock the drive door. Don't use when st_request allocated. */
Linus Torvalds1da177e2005-04-16 15:20:36 -0700797static int do_door_lock(struct scsi_tape * STp, int do_lock)
798{
799 int retval, cmd;
800 DEB(char *name = tape_name(STp);)
801
802
803 cmd = do_lock ? SCSI_IOCTL_DOORLOCK : SCSI_IOCTL_DOORUNLOCK;
804 DEBC(printk(ST_DEB_MSG "%s: %socking drive door.\n", name,
805 do_lock ? "L" : "Unl"));
806 retval = scsi_ioctl(STp->device, cmd, NULL);
807 if (!retval) {
808 STp->door_locked = do_lock ? ST_LOCKED_EXPLICIT : ST_UNLOCKED;
809 }
810 else {
811 STp->door_locked = ST_LOCK_FAILS;
812 }
813 return retval;
814}
815
816
817/* Set the internal state after reset */
818static void reset_state(struct scsi_tape *STp)
819{
820 int i;
821 struct st_partstat *STps;
822
823 STp->pos_unknown = 0;
824 for (i = 0; i < ST_NBR_PARTITIONS; i++) {
825 STps = &(STp->ps[i]);
826 STps->rw = ST_IDLE;
827 STps->eof = ST_NOEOF;
828 STps->at_sm = 0;
829 STps->last_block_valid = 0;
830 STps->drv_block = -1;
831 STps->drv_file = -1;
832 }
833 if (STp->can_partitions) {
834 STp->partition = find_partition(STp);
835 if (STp->partition < 0)
836 STp->partition = 0;
837 STp->new_partition = STp->partition;
838 }
839}
840
841/* Test if the drive is ready. Returns either one of the codes below or a negative system
842 error code. */
843#define CHKRES_READY 0
844#define CHKRES_NEW_SESSION 1
845#define CHKRES_NOT_READY 2
846#define CHKRES_NO_TAPE 3
847
848#define MAX_ATTENTIONS 10
849
850static int test_ready(struct scsi_tape *STp, int do_wait)
851{
852 int attentions, waits, max_wait, scode;
853 int retval = CHKRES_READY, new_session = 0;
854 unsigned char cmd[MAX_COMMAND_SIZE];
Mike Christie8b05b772005-11-08 04:06:44 -0600855 struct st_request *SRpnt = NULL;
Linus Torvalds1da177e2005-04-16 15:20:36 -0700856 struct st_cmdstatus *cmdstatp = &STp->buffer->cmdstat;
857
858 max_wait = do_wait ? ST_BLOCK_SECONDS : 0;
859
860 for (attentions=waits=0; ; ) {
861 memset((void *) &cmd[0], 0, MAX_COMMAND_SIZE);
862 cmd[0] = TEST_UNIT_READY;
863 SRpnt = st_do_scsi(SRpnt, STp, cmd, 0, DMA_NONE,
864 STp->long_timeout, MAX_READY_RETRIES, 1);
865
866 if (!SRpnt) {
867 retval = (STp->buffer)->syscall_result;
868 break;
869 }
870
871 if (cmdstatp->have_sense) {
872
873 scode = cmdstatp->sense_hdr.sense_key;
874
875 if (scode == UNIT_ATTENTION) { /* New media? */
876 new_session = 1;
877 if (attentions < MAX_ATTENTIONS) {
878 attentions++;
879 continue;
880 }
881 else {
882 retval = (-EIO);
883 break;
884 }
885 }
886
887 if (scode == NOT_READY) {
888 if (waits < max_wait) {
889 if (msleep_interruptible(1000)) {
890 retval = (-EINTR);
891 break;
892 }
893 waits++;
894 continue;
895 }
896 else {
897 if ((STp->device)->scsi_level >= SCSI_2 &&
898 cmdstatp->sense_hdr.asc == 0x3a) /* Check ASC */
899 retval = CHKRES_NO_TAPE;
900 else
901 retval = CHKRES_NOT_READY;
902 break;
903 }
904 }
905 }
906
907 retval = (STp->buffer)->syscall_result;
908 if (!retval)
909 retval = new_session ? CHKRES_NEW_SESSION : CHKRES_READY;
910 break;
911 }
912
913 if (SRpnt != NULL)
Mike Christie8b05b772005-11-08 04:06:44 -0600914 st_release_request(SRpnt);
Linus Torvalds1da177e2005-04-16 15:20:36 -0700915 return retval;
916}
917
918
919/* See if the drive is ready and gather information about the tape. Return values:
920 < 0 negative error code from errno.h
921 0 drive ready
922 1 drive not ready (possibly no tape)
923*/
924static int check_tape(struct scsi_tape *STp, struct file *filp)
925{
926 int i, retval, new_session = 0, do_wait;
927 unsigned char cmd[MAX_COMMAND_SIZE], saved_cleaning;
928 unsigned short st_flags = filp->f_flags;
Mike Christie8b05b772005-11-08 04:06:44 -0600929 struct st_request *SRpnt = NULL;
Linus Torvalds1da177e2005-04-16 15:20:36 -0700930 struct st_modedef *STm;
931 struct st_partstat *STps;
932 char *name = tape_name(STp);
Josef Sipek7ac62072006-12-08 02:37:37 -0800933 struct inode *inode = filp->f_path.dentry->d_inode;
Linus Torvalds1da177e2005-04-16 15:20:36 -0700934 int mode = TAPE_MODE(inode);
935
936 STp->ready = ST_READY;
937
938 if (mode != STp->current_mode) {
939 DEBC(printk(ST_DEB_MSG "%s: Mode change from %d to %d.\n",
940 name, STp->current_mode, mode));
941 new_session = 1;
942 STp->current_mode = mode;
943 }
944 STm = &(STp->modes[STp->current_mode]);
945
946 saved_cleaning = STp->cleaning_req;
947 STp->cleaning_req = 0;
948
949 do_wait = ((filp->f_flags & O_NONBLOCK) == 0);
950 retval = test_ready(STp, do_wait);
951
952 if (retval < 0)
953 goto err_out;
954
955 if (retval == CHKRES_NEW_SESSION) {
956 STp->pos_unknown = 0;
957 STp->partition = STp->new_partition = 0;
958 if (STp->can_partitions)
959 STp->nbr_partitions = 1; /* This guess will be updated later
960 if necessary */
961 for (i = 0; i < ST_NBR_PARTITIONS; i++) {
962 STps = &(STp->ps[i]);
963 STps->rw = ST_IDLE;
964 STps->eof = ST_NOEOF;
965 STps->at_sm = 0;
966 STps->last_block_valid = 0;
967 STps->drv_block = 0;
968 STps->drv_file = 0;
969 }
970 new_session = 1;
971 }
972 else {
973 STp->cleaning_req |= saved_cleaning;
974
975 if (retval == CHKRES_NOT_READY || retval == CHKRES_NO_TAPE) {
976 if (retval == CHKRES_NO_TAPE)
977 STp->ready = ST_NO_TAPE;
978 else
979 STp->ready = ST_NOT_READY;
980
981 STp->density = 0; /* Clear the erroneous "residue" */
982 STp->write_prot = 0;
983 STp->block_size = 0;
984 STp->ps[0].drv_file = STp->ps[0].drv_block = (-1);
985 STp->partition = STp->new_partition = 0;
986 STp->door_locked = ST_UNLOCKED;
987 return CHKRES_NOT_READY;
988 }
989 }
990
991 if (STp->omit_blklims)
992 STp->min_block = STp->max_block = (-1);
993 else {
994 memset((void *) &cmd[0], 0, MAX_COMMAND_SIZE);
995 cmd[0] = READ_BLOCK_LIMITS;
996
997 SRpnt = st_do_scsi(SRpnt, STp, cmd, 6, DMA_FROM_DEVICE,
James Bottomleya02488e2008-11-30 10:36:26 -0600998 STp->device->request_queue->rq_timeout,
999 MAX_READY_RETRIES, 1);
Linus Torvalds1da177e2005-04-16 15:20:36 -07001000 if (!SRpnt) {
1001 retval = (STp->buffer)->syscall_result;
1002 goto err_out;
1003 }
1004
Mike Christie8b05b772005-11-08 04:06:44 -06001005 if (!SRpnt->result && !STp->buffer->cmdstat.have_sense) {
Linus Torvalds1da177e2005-04-16 15:20:36 -07001006 STp->max_block = ((STp->buffer)->b_data[1] << 16) |
1007 ((STp->buffer)->b_data[2] << 8) | (STp->buffer)->b_data[3];
1008 STp->min_block = ((STp->buffer)->b_data[4] << 8) |
1009 (STp->buffer)->b_data[5];
1010 if ( DEB( debugging || ) !STp->inited)
Kai Makisara42252852006-11-07 21:56:38 +02001011 printk(KERN_INFO
Linus Torvalds1da177e2005-04-16 15:20:36 -07001012 "%s: Block limits %d - %d bytes.\n", name,
1013 STp->min_block, STp->max_block);
1014 } else {
1015 STp->min_block = STp->max_block = (-1);
1016 DEBC(printk(ST_DEB_MSG "%s: Can't read block limits.\n",
1017 name));
1018 }
1019 }
1020
1021 memset((void *) &cmd[0], 0, MAX_COMMAND_SIZE);
1022 cmd[0] = MODE_SENSE;
1023 cmd[4] = 12;
1024
1025 SRpnt = st_do_scsi(SRpnt, STp, cmd, 12, DMA_FROM_DEVICE,
James Bottomleya02488e2008-11-30 10:36:26 -06001026 STp->device->request_queue->rq_timeout,
1027 MAX_READY_RETRIES, 1);
Linus Torvalds1da177e2005-04-16 15:20:36 -07001028 if (!SRpnt) {
1029 retval = (STp->buffer)->syscall_result;
1030 goto err_out;
1031 }
1032
1033 if ((STp->buffer)->syscall_result != 0) {
1034 DEBC(printk(ST_DEB_MSG "%s: No Mode Sense.\n", name));
1035 STp->block_size = ST_DEFAULT_BLOCK; /* Educated guess (?) */
1036 (STp->buffer)->syscall_result = 0; /* Prevent error propagation */
1037 STp->drv_write_prot = 0;
1038 } else {
1039 DEBC(printk(ST_DEB_MSG
1040 "%s: Mode sense. Length %d, medium %x, WBS %x, BLL %d\n",
1041 name,
1042 (STp->buffer)->b_data[0], (STp->buffer)->b_data[1],
1043 (STp->buffer)->b_data[2], (STp->buffer)->b_data[3]));
1044
1045 if ((STp->buffer)->b_data[3] >= 8) {
1046 STp->drv_buffer = ((STp->buffer)->b_data[2] >> 4) & 7;
1047 STp->density = (STp->buffer)->b_data[4];
1048 STp->block_size = (STp->buffer)->b_data[9] * 65536 +
1049 (STp->buffer)->b_data[10] * 256 + (STp->buffer)->b_data[11];
1050 DEBC(printk(ST_DEB_MSG
1051 "%s: Density %x, tape length: %x, drv buffer: %d\n",
1052 name, STp->density, (STp->buffer)->b_data[5] * 65536 +
1053 (STp->buffer)->b_data[6] * 256 + (STp->buffer)->b_data[7],
1054 STp->drv_buffer));
1055 }
1056 STp->drv_write_prot = ((STp->buffer)->b_data[2] & 0x80) != 0;
1057 }
Mike Christie8b05b772005-11-08 04:06:44 -06001058 st_release_request(SRpnt);
Linus Torvalds1da177e2005-04-16 15:20:36 -07001059 SRpnt = NULL;
1060 STp->inited = 1;
1061
1062 if (STp->block_size > 0)
1063 (STp->buffer)->buffer_blocks =
1064 (STp->buffer)->buffer_size / STp->block_size;
1065 else
1066 (STp->buffer)->buffer_blocks = 1;
1067 (STp->buffer)->buffer_bytes = (STp->buffer)->read_pointer = 0;
1068
1069 DEBC(printk(ST_DEB_MSG
1070 "%s: Block size: %d, buffer size: %d (%d blocks).\n", name,
1071 STp->block_size, (STp->buffer)->buffer_size,
1072 (STp->buffer)->buffer_blocks));
1073
1074 if (STp->drv_write_prot) {
1075 STp->write_prot = 1;
1076
1077 DEBC(printk(ST_DEB_MSG "%s: Write protected\n", name));
1078
1079 if (do_wait &&
1080 ((st_flags & O_ACCMODE) == O_WRONLY ||
1081 (st_flags & O_ACCMODE) == O_RDWR)) {
1082 retval = (-EROFS);
1083 goto err_out;
1084 }
1085 }
1086
1087 if (STp->can_partitions && STp->nbr_partitions < 1) {
1088 /* This code is reached when the device is opened for the first time
1089 after the driver has been initialized with tape in the drive and the
1090 partition support has been enabled. */
1091 DEBC(printk(ST_DEB_MSG
1092 "%s: Updating partition number in status.\n", name));
1093 if ((STp->partition = find_partition(STp)) < 0) {
1094 retval = STp->partition;
1095 goto err_out;
1096 }
1097 STp->new_partition = STp->partition;
1098 STp->nbr_partitions = 1; /* This guess will be updated when necessary */
1099 }
1100
1101 if (new_session) { /* Change the drive parameters for the new mode */
1102 STp->density_changed = STp->blksize_changed = 0;
1103 STp->compression_changed = 0;
1104 if (!(STm->defaults_for_writes) &&
1105 (retval = set_mode_densblk(STp, STm)) < 0)
1106 goto err_out;
1107
1108 if (STp->default_drvbuffer != 0xff) {
1109 if (st_int_ioctl(STp, MTSETDRVBUFFER, STp->default_drvbuffer))
1110 printk(KERN_WARNING
1111 "%s: Can't set default drive buffering to %d.\n",
1112 name, STp->default_drvbuffer);
1113 }
1114 }
1115
1116 return CHKRES_READY;
1117
1118 err_out:
1119 return retval;
1120}
1121
1122
Jonathan Corbetb3369c62008-05-15 16:08:15 -06001123 /* Open the device. Needs to take the BKL only because of incrementing the SCSI host
Linus Torvalds1da177e2005-04-16 15:20:36 -07001124 module count. */
1125static int st_open(struct inode *inode, struct file *filp)
1126{
1127 int i, retval = (-EIO);
1128 struct scsi_tape *STp;
1129 struct st_partstat *STps;
1130 int dev = TAPE_NR(inode);
1131 char *name;
1132
Jonathan Corbetb3369c62008-05-15 16:08:15 -06001133 lock_kernel();
Linus Torvalds1da177e2005-04-16 15:20:36 -07001134 /*
1135 * We really want to do nonseekable_open(inode, filp); here, but some
1136 * versions of tar incorrectly call lseek on tapes and bail out if that
1137 * fails. So we disallow pread() and pwrite(), but permit lseeks.
1138 */
1139 filp->f_mode &= ~(FMODE_PREAD | FMODE_PWRITE);
1140
Jonathan Corbetb3369c62008-05-15 16:08:15 -06001141 if (!(STp = scsi_tape_get(dev))) {
1142 unlock_kernel();
Kai Makisaraf03a5672005-08-02 13:40:47 +03001143 return -ENXIO;
Jonathan Corbetb3369c62008-05-15 16:08:15 -06001144 }
Kai Makisaraf03a5672005-08-02 13:40:47 +03001145
Linus Torvalds1da177e2005-04-16 15:20:36 -07001146 write_lock(&st_dev_arr_lock);
Linus Torvalds1da177e2005-04-16 15:20:36 -07001147 filp->private_data = STp;
1148 name = tape_name(STp);
1149
1150 if (STp->in_use) {
1151 write_unlock(&st_dev_arr_lock);
Kai Makisaraf03a5672005-08-02 13:40:47 +03001152 scsi_tape_put(STp);
Jonathan Corbetb3369c62008-05-15 16:08:15 -06001153 unlock_kernel();
Linus Torvalds1da177e2005-04-16 15:20:36 -07001154 DEB( printk(ST_DEB_MSG "%s: Device already in use.\n", name); )
1155 return (-EBUSY);
1156 }
1157
Linus Torvalds1da177e2005-04-16 15:20:36 -07001158 STp->in_use = 1;
1159 write_unlock(&st_dev_arr_lock);
1160 STp->rew_at_close = STp->autorew_dev = (iminor(inode) & 0x80) == 0;
1161
1162 if (!scsi_block_when_processing_errors(STp->device)) {
1163 retval = (-ENXIO);
1164 goto err_out;
1165 }
1166
1167 /* See that we have at least a one page buffer available */
1168 if (!enlarge_buffer(STp->buffer, PAGE_SIZE, STp->restr_dma)) {
1169 printk(KERN_WARNING "%s: Can't allocate one page tape buffer.\n",
1170 name);
1171 retval = (-EOVERFLOW);
1172 goto err_out;
1173 }
1174
Kai Makisara40f6b362008-02-24 22:23:24 +02001175 (STp->buffer)->cleared = 0;
Linus Torvalds1da177e2005-04-16 15:20:36 -07001176 (STp->buffer)->writing = 0;
1177 (STp->buffer)->syscall_result = 0;
1178
1179 STp->write_prot = ((filp->f_flags & O_ACCMODE) == O_RDONLY);
1180
1181 STp->dirty = 0;
1182 for (i = 0; i < ST_NBR_PARTITIONS; i++) {
1183 STps = &(STp->ps[i]);
1184 STps->rw = ST_IDLE;
1185 }
Kai Makisara9abe16c2007-02-03 13:21:29 +02001186 STp->try_dio_now = STp->try_dio;
Linus Torvalds1da177e2005-04-16 15:20:36 -07001187 STp->recover_count = 0;
1188 DEB( STp->nbr_waits = STp->nbr_finished = 0;
Kai Makisaradeee13d2008-02-22 20:11:21 +02001189 STp->nbr_requests = STp->nbr_dio = STp->nbr_pages = 0; )
Linus Torvalds1da177e2005-04-16 15:20:36 -07001190
1191 retval = check_tape(STp, filp);
1192 if (retval < 0)
1193 goto err_out;
1194 if ((filp->f_flags & O_NONBLOCK) == 0 &&
1195 retval != CHKRES_READY) {
Kai Makisara413f7322006-10-05 22:59:46 +03001196 if (STp->ready == NO_TAPE)
1197 retval = (-ENOMEDIUM);
1198 else
1199 retval = (-EIO);
Linus Torvalds1da177e2005-04-16 15:20:36 -07001200 goto err_out;
1201 }
Jonathan Corbetb3369c62008-05-15 16:08:15 -06001202 unlock_kernel();
Linus Torvalds1da177e2005-04-16 15:20:36 -07001203 return 0;
1204
1205 err_out:
1206 normalize_buffer(STp->buffer);
1207 STp->in_use = 0;
Kai Makisaraf03a5672005-08-02 13:40:47 +03001208 scsi_tape_put(STp);
Jonathan Corbetb3369c62008-05-15 16:08:15 -06001209 unlock_kernel();
Linus Torvalds1da177e2005-04-16 15:20:36 -07001210 return retval;
1211
1212}
1213
1214
1215/* Flush the tape buffer before close */
Miklos Szeredi75e1fcc2006-06-23 02:05:12 -07001216static int st_flush(struct file *filp, fl_owner_t id)
Linus Torvalds1da177e2005-04-16 15:20:36 -07001217{
1218 int result = 0, result2;
1219 unsigned char cmd[MAX_COMMAND_SIZE];
Mike Christie8b05b772005-11-08 04:06:44 -06001220 struct st_request *SRpnt;
Linus Torvalds1da177e2005-04-16 15:20:36 -07001221 struct scsi_tape *STp = filp->private_data;
1222 struct st_modedef *STm = &(STp->modes[STp->current_mode]);
1223 struct st_partstat *STps = &(STp->ps[STp->partition]);
1224 char *name = tape_name(STp);
1225
1226 if (file_count(filp) > 1)
1227 return 0;
1228
1229 if (STps->rw == ST_WRITING && !STp->pos_unknown) {
Adrian Bunk8ef8d592008-04-14 17:17:16 +03001230 result = st_flush_write_buffer(STp);
Linus Torvalds1da177e2005-04-16 15:20:36 -07001231 if (result != 0 && result != (-ENOSPC))
1232 goto out;
1233 }
1234
1235 if (STp->can_partitions &&
1236 (result2 = switch_partition(STp)) < 0) {
1237 DEBC(printk(ST_DEB_MSG
1238 "%s: switch_partition at close failed.\n", name));
1239 if (result == 0)
1240 result = result2;
1241 goto out;
1242 }
1243
1244 DEBC( if (STp->nbr_requests)
Kai Makisaradeee13d2008-02-22 20:11:21 +02001245 printk(KERN_DEBUG "%s: Number of r/w requests %d, dio used in %d, pages %d.\n",
1246 name, STp->nbr_requests, STp->nbr_dio, STp->nbr_pages));
Linus Torvalds1da177e2005-04-16 15:20:36 -07001247
1248 if (STps->rw == ST_WRITING && !STp->pos_unknown) {
1249 struct st_cmdstatus *cmdstatp = &STp->buffer->cmdstat;
1250
1251 DEBC(printk(ST_DEB_MSG "%s: Async write waits %d, finished %d.\n",
1252 name, STp->nbr_waits, STp->nbr_finished);
1253 )
1254
1255 memset(cmd, 0, MAX_COMMAND_SIZE);
1256 cmd[0] = WRITE_FILEMARKS;
1257 cmd[4] = 1 + STp->two_fm;
1258
1259 SRpnt = st_do_scsi(NULL, STp, cmd, 0, DMA_NONE,
James Bottomleya02488e2008-11-30 10:36:26 -06001260 STp->device->request_queue->rq_timeout,
1261 MAX_WRITE_RETRIES, 1);
Linus Torvalds1da177e2005-04-16 15:20:36 -07001262 if (!SRpnt) {
1263 result = (STp->buffer)->syscall_result;
1264 goto out;
1265 }
1266
1267 if (STp->buffer->syscall_result == 0 ||
1268 (cmdstatp->have_sense && !cmdstatp->deferred &&
1269 (cmdstatp->flags & SENSE_EOM) &&
1270 (cmdstatp->sense_hdr.sense_key == NO_SENSE ||
1271 cmdstatp->sense_hdr.sense_key == RECOVERED_ERROR) &&
1272 (!cmdstatp->remainder_valid || cmdstatp->uremainder64 == 0))) {
1273 /* Write successful at EOM */
Mike Christie8b05b772005-11-08 04:06:44 -06001274 st_release_request(SRpnt);
Linus Torvalds1da177e2005-04-16 15:20:36 -07001275 SRpnt = NULL;
1276 if (STps->drv_file >= 0)
1277 STps->drv_file++;
1278 STps->drv_block = 0;
1279 if (STp->two_fm)
1280 cross_eof(STp, 0);
1281 STps->eof = ST_FM;
1282 }
1283 else { /* Write error */
Mike Christie8b05b772005-11-08 04:06:44 -06001284 st_release_request(SRpnt);
Linus Torvalds1da177e2005-04-16 15:20:36 -07001285 SRpnt = NULL;
1286 printk(KERN_ERR "%s: Error on write filemark.\n", name);
1287 if (result == 0)
1288 result = (-EIO);
1289 }
1290
1291 DEBC(printk(ST_DEB_MSG "%s: Buffer flushed, %d EOF(s) written\n",
1292 name, cmd[4]));
1293 } else if (!STp->rew_at_close) {
1294 STps = &(STp->ps[STp->partition]);
1295 if (!STm->sysv || STps->rw != ST_READING) {
1296 if (STp->can_bsr)
1297 result = flush_buffer(STp, 0);
1298 else if (STps->eof == ST_FM_HIT) {
1299 result = cross_eof(STp, 0);
1300 if (result) {
1301 if (STps->drv_file >= 0)
1302 STps->drv_file++;
1303 STps->drv_block = 0;
1304 STps->eof = ST_FM;
1305 } else
1306 STps->eof = ST_NOEOF;
1307 }
1308 } else if ((STps->eof == ST_NOEOF &&
1309 !(result = cross_eof(STp, 1))) ||
1310 STps->eof == ST_FM_HIT) {
1311 if (STps->drv_file >= 0)
1312 STps->drv_file++;
1313 STps->drv_block = 0;
1314 STps->eof = ST_FM;
1315 }
1316 }
1317
1318 out:
1319 if (STp->rew_at_close) {
1320 result2 = st_int_ioctl(STp, MTREW, 1);
1321 if (result == 0)
1322 result = result2;
1323 }
1324 return result;
1325}
1326
1327
1328/* Close the device and release it. BKL is not needed: this is the only thread
1329 accessing this tape. */
1330static int st_release(struct inode *inode, struct file *filp)
1331{
1332 int result = 0;
1333 struct scsi_tape *STp = filp->private_data;
1334
1335 if (STp->door_locked == ST_LOCKED_AUTO)
1336 do_door_lock(STp, 0);
1337
1338 normalize_buffer(STp->buffer);
1339 write_lock(&st_dev_arr_lock);
1340 STp->in_use = 0;
1341 write_unlock(&st_dev_arr_lock);
Kai Makisaraf03a5672005-08-02 13:40:47 +03001342 scsi_tape_put(STp);
Linus Torvalds1da177e2005-04-16 15:20:36 -07001343
1344 return result;
1345}
1346
1347/* The checks common to both reading and writing */
1348static ssize_t rw_checks(struct scsi_tape *STp, struct file *filp, size_t count)
1349{
1350 ssize_t retval = 0;
1351
1352 /*
1353 * If we are in the middle of error recovery, don't let anyone
1354 * else try and use this device. Also, if error recovery fails, it
1355 * may try and take the device offline, in which case all further
1356 * access to the device is prohibited.
1357 */
1358 if (!scsi_block_when_processing_errors(STp->device)) {
1359 retval = (-ENXIO);
1360 goto out;
1361 }
1362
1363 if (STp->ready != ST_READY) {
1364 if (STp->ready == ST_NO_TAPE)
1365 retval = (-ENOMEDIUM);
1366 else
1367 retval = (-EIO);
1368 goto out;
1369 }
1370
1371 if (! STp->modes[STp->current_mode].defined) {
1372 retval = (-ENXIO);
1373 goto out;
1374 }
1375
1376
1377 /*
1378 * If there was a bus reset, block further access
1379 * to this device.
1380 */
1381 if (STp->pos_unknown) {
1382 retval = (-EIO);
1383 goto out;
1384 }
1385
1386 if (count == 0)
1387 goto out;
1388
1389 DEB(
1390 if (!STp->in_use) {
1391 printk(ST_DEB_MSG "%s: Incorrect device.\n", tape_name(STp));
1392 retval = (-EIO);
1393 goto out;
1394 } ) /* end DEB */
1395
1396 if (STp->can_partitions &&
1397 (retval = switch_partition(STp)) < 0)
1398 goto out;
1399
1400 if (STp->block_size == 0 && STp->max_block > 0 &&
1401 (count < STp->min_block || count > STp->max_block)) {
1402 retval = (-EINVAL);
1403 goto out;
1404 }
1405
1406 if (STp->do_auto_lock && STp->door_locked == ST_UNLOCKED &&
1407 !do_door_lock(STp, 1))
1408 STp->door_locked = ST_LOCKED_AUTO;
1409
1410 out:
1411 return retval;
1412}
1413
1414
1415static int setup_buffering(struct scsi_tape *STp, const char __user *buf,
1416 size_t count, int is_read)
1417{
1418 int i, bufsize, retval = 0;
1419 struct st_buffer *STbp = STp->buffer;
1420
1421 if (is_read)
Kai Makisara9abe16c2007-02-03 13:21:29 +02001422 i = STp->try_dio_now && try_rdio;
Linus Torvalds1da177e2005-04-16 15:20:36 -07001423 else
Kai Makisara9abe16c2007-02-03 13:21:29 +02001424 i = STp->try_dio_now && try_wdio;
Mike Christie8b05b772005-11-08 04:06:44 -06001425
Linus Torvalds1da177e2005-04-16 15:20:36 -07001426 if (i && ((unsigned long)buf & queue_dma_alignment(
1427 STp->device->request_queue)) == 0) {
Mike Christie8b05b772005-11-08 04:06:44 -06001428 i = sgl_map_user_pages(&(STbp->sg[0]), STbp->use_sg,
1429 (unsigned long)buf, count, (is_read ? READ : WRITE));
Linus Torvalds1da177e2005-04-16 15:20:36 -07001430 if (i > 0) {
1431 STbp->do_dio = i;
1432 STbp->buffer_bytes = 0; /* can be used as transfer counter */
1433 }
1434 else
1435 STbp->do_dio = 0; /* fall back to buffering with any error */
1436 STbp->sg_segs = STbp->do_dio;
1437 STbp->frp_sg_current = 0;
1438 DEB(
1439 if (STbp->do_dio) {
1440 STp->nbr_dio++;
1441 STp->nbr_pages += STbp->do_dio;
Linus Torvalds1da177e2005-04-16 15:20:36 -07001442 }
1443 )
1444 } else
1445 STbp->do_dio = 0;
1446 DEB( STp->nbr_requests++; )
1447
1448 if (!STbp->do_dio) {
1449 if (STp->block_size)
1450 bufsize = STp->block_size > st_fixed_buffer_size ?
1451 STp->block_size : st_fixed_buffer_size;
Kai Makisara40f6b362008-02-24 22:23:24 +02001452 else {
Linus Torvalds1da177e2005-04-16 15:20:36 -07001453 bufsize = count;
Kai Makisara40f6b362008-02-24 22:23:24 +02001454 /* Make sure that data from previous user is not leaked even if
1455 HBA does not return correct residual */
1456 if (is_read && STp->sili && !STbp->cleared)
1457 clear_buffer(STbp);
1458 }
1459
Linus Torvalds1da177e2005-04-16 15:20:36 -07001460 if (bufsize > STbp->buffer_size &&
1461 !enlarge_buffer(STbp, bufsize, STp->restr_dma)) {
1462 printk(KERN_WARNING "%s: Can't allocate %d byte tape buffer.\n",
1463 tape_name(STp), bufsize);
1464 retval = (-EOVERFLOW);
1465 goto out;
1466 }
1467 if (STp->block_size)
1468 STbp->buffer_blocks = bufsize / STp->block_size;
1469 }
1470
1471 out:
1472 return retval;
1473}
1474
1475
1476/* Can be called more than once after each setup_buffer() */
Kai Makisara787926b2005-11-13 10:04:44 +02001477static void release_buffering(struct scsi_tape *STp, int is_read)
Linus Torvalds1da177e2005-04-16 15:20:36 -07001478{
1479 struct st_buffer *STbp;
1480
1481 STbp = STp->buffer;
1482 if (STbp->do_dio) {
Kai Makisara787926b2005-11-13 10:04:44 +02001483 sgl_unmap_user_pages(&(STbp->sg[0]), STbp->do_dio, is_read);
Linus Torvalds1da177e2005-04-16 15:20:36 -07001484 STbp->do_dio = 0;
Kai Makisara787926b2005-11-13 10:04:44 +02001485 STbp->sg_segs = 0;
Linus Torvalds1da177e2005-04-16 15:20:36 -07001486 }
1487}
1488
1489
1490/* Write command */
1491static ssize_t
1492st_write(struct file *filp, const char __user *buf, size_t count, loff_t * ppos)
1493{
1494 ssize_t total;
1495 ssize_t i, do_count, blks, transfer;
1496 ssize_t retval;
1497 int undone, retry_eot = 0, scode;
1498 int async_write;
1499 unsigned char cmd[MAX_COMMAND_SIZE];
1500 const char __user *b_point;
Mike Christie8b05b772005-11-08 04:06:44 -06001501 struct st_request *SRpnt = NULL;
Linus Torvalds1da177e2005-04-16 15:20:36 -07001502 struct scsi_tape *STp = filp->private_data;
1503 struct st_modedef *STm;
1504 struct st_partstat *STps;
1505 struct st_buffer *STbp;
1506 char *name = tape_name(STp);
1507
Matthias Kaehlcke28f85002007-07-29 23:38:15 +02001508 if (mutex_lock_interruptible(&STp->lock))
Linus Torvalds1da177e2005-04-16 15:20:36 -07001509 return -ERESTARTSYS;
1510
1511 retval = rw_checks(STp, filp, count);
1512 if (retval || count == 0)
1513 goto out;
1514
1515 /* Write must be integral number of blocks */
1516 if (STp->block_size != 0 && (count % STp->block_size) != 0) {
1517 printk(KERN_WARNING "%s: Write not multiple of tape block size.\n",
1518 name);
1519 retval = (-EINVAL);
1520 goto out;
1521 }
1522
1523 STm = &(STp->modes[STp->current_mode]);
1524 STps = &(STp->ps[STp->partition]);
1525
1526 if (STp->write_prot) {
1527 retval = (-EACCES);
1528 goto out;
1529 }
1530
1531
1532 if (STps->rw == ST_READING) {
1533 retval = flush_buffer(STp, 0);
1534 if (retval)
1535 goto out;
1536 STps->rw = ST_WRITING;
1537 } else if (STps->rw != ST_WRITING &&
1538 STps->drv_file == 0 && STps->drv_block == 0) {
1539 if ((retval = set_mode_densblk(STp, STm)) < 0)
1540 goto out;
1541 if (STm->default_compression != ST_DONT_TOUCH &&
1542 !(STp->compression_changed)) {
1543 if (st_compression(STp, (STm->default_compression == ST_YES))) {
1544 printk(KERN_WARNING "%s: Can't set default compression.\n",
1545 name);
1546 if (modes_defined) {
1547 retval = (-EINVAL);
1548 goto out;
1549 }
1550 }
1551 }
1552 }
1553
1554 STbp = STp->buffer;
1555 i = write_behind_check(STp);
1556 if (i) {
1557 if (i == -ENOSPC)
1558 STps->eof = ST_EOM_OK;
1559 else
1560 STps->eof = ST_EOM_ERROR;
1561 }
1562
1563 if (STps->eof == ST_EOM_OK) {
1564 STps->eof = ST_EOD_1; /* allow next write */
1565 retval = (-ENOSPC);
1566 goto out;
1567 }
1568 else if (STps->eof == ST_EOM_ERROR) {
1569 retval = (-EIO);
1570 goto out;
1571 }
1572
1573 /* Check the buffer readability in cases where copy_user might catch
1574 the problems after some tape movement. */
1575 if (STp->block_size != 0 &&
1576 !STbp->do_dio &&
1577 (copy_from_user(&i, buf, 1) != 0 ||
1578 copy_from_user(&i, buf + count - 1, 1) != 0)) {
1579 retval = (-EFAULT);
1580 goto out;
1581 }
1582
1583 retval = setup_buffering(STp, buf, count, 0);
1584 if (retval)
1585 goto out;
1586
1587 total = count;
1588
1589 memset(cmd, 0, MAX_COMMAND_SIZE);
1590 cmd[0] = WRITE_6;
1591 cmd[1] = (STp->block_size != 0);
1592
1593 STps->rw = ST_WRITING;
1594
1595 b_point = buf;
1596 while (count > 0 && !retry_eot) {
1597
1598 if (STbp->do_dio) {
1599 do_count = count;
1600 }
1601 else {
1602 if (STp->block_size == 0)
1603 do_count = count;
1604 else {
1605 do_count = STbp->buffer_blocks * STp->block_size -
1606 STbp->buffer_bytes;
1607 if (do_count > count)
1608 do_count = count;
1609 }
1610
1611 i = append_to_buffer(b_point, STbp, do_count);
1612 if (i) {
1613 retval = i;
1614 goto out;
1615 }
1616 }
1617 count -= do_count;
1618 b_point += do_count;
1619
1620 async_write = STp->block_size == 0 && !STbp->do_dio &&
1621 STm->do_async_writes && STps->eof < ST_EOM_OK;
1622
1623 if (STp->block_size != 0 && STm->do_buffer_writes &&
Kai Makisara9abe16c2007-02-03 13:21:29 +02001624 !(STp->try_dio_now && try_wdio) && STps->eof < ST_EOM_OK &&
Linus Torvalds1da177e2005-04-16 15:20:36 -07001625 STbp->buffer_bytes < STbp->buffer_size) {
1626 STp->dirty = 1;
1627 /* Don't write a buffer that is not full enough. */
1628 if (!async_write && count == 0)
1629 break;
1630 }
1631
1632 retry_write:
1633 if (STp->block_size == 0)
1634 blks = transfer = do_count;
1635 else {
1636 if (!STbp->do_dio)
1637 blks = STbp->buffer_bytes;
1638 else
1639 blks = do_count;
1640 blks /= STp->block_size;
1641 transfer = blks * STp->block_size;
1642 }
1643 cmd[2] = blks >> 16;
1644 cmd[3] = blks >> 8;
1645 cmd[4] = blks;
1646
1647 SRpnt = st_do_scsi(SRpnt, STp, cmd, transfer, DMA_TO_DEVICE,
James Bottomleya02488e2008-11-30 10:36:26 -06001648 STp->device->request_queue->rq_timeout,
1649 MAX_WRITE_RETRIES, !async_write);
Linus Torvalds1da177e2005-04-16 15:20:36 -07001650 if (!SRpnt) {
1651 retval = STbp->syscall_result;
1652 goto out;
1653 }
Mike Christie8b05b772005-11-08 04:06:44 -06001654 if (async_write && !STbp->syscall_result) {
Linus Torvalds1da177e2005-04-16 15:20:36 -07001655 STbp->writing = transfer;
1656 STp->dirty = !(STbp->writing ==
1657 STbp->buffer_bytes);
1658 SRpnt = NULL; /* Prevent releasing this request! */
1659 DEB( STp->write_pending = 1; )
1660 break;
1661 }
1662
1663 if (STbp->syscall_result != 0) {
1664 struct st_cmdstatus *cmdstatp = &STp->buffer->cmdstat;
1665
1666 DEBC(printk(ST_DEB_MSG "%s: Error on write:\n", name));
1667 if (cmdstatp->have_sense && (cmdstatp->flags & SENSE_EOM)) {
1668 scode = cmdstatp->sense_hdr.sense_key;
1669 if (cmdstatp->remainder_valid)
1670 undone = (int)cmdstatp->uremainder64;
1671 else if (STp->block_size == 0 &&
1672 scode == VOLUME_OVERFLOW)
1673 undone = transfer;
1674 else
1675 undone = 0;
1676 if (STp->block_size != 0)
1677 undone *= STp->block_size;
1678 if (undone <= do_count) {
1679 /* Only data from this write is not written */
1680 count += undone;
Kai Makisara626dcb12008-07-11 15:05:25 +03001681 b_point -= undone;
Linus Torvalds1da177e2005-04-16 15:20:36 -07001682 do_count -= undone;
1683 if (STp->block_size)
1684 blks = (transfer - undone) / STp->block_size;
1685 STps->eof = ST_EOM_OK;
1686 /* Continue in fixed block mode if all written
1687 in this request but still something left to write
1688 (retval left to zero)
1689 */
1690 if (STp->block_size == 0 ||
1691 undone > 0 || count == 0)
1692 retval = (-ENOSPC); /* EOM within current request */
1693 DEBC(printk(ST_DEB_MSG
1694 "%s: EOM with %d bytes unwritten.\n",
1695 name, (int)count));
1696 } else {
1697 /* EOT within data buffered earlier (possible only
1698 in fixed block mode without direct i/o) */
1699 if (!retry_eot && !cmdstatp->deferred &&
1700 (scode == NO_SENSE || scode == RECOVERED_ERROR)) {
1701 move_buffer_data(STp->buffer, transfer - undone);
1702 retry_eot = 1;
1703 if (STps->drv_block >= 0) {
1704 STps->drv_block += (transfer - undone) /
1705 STp->block_size;
1706 }
1707 STps->eof = ST_EOM_OK;
1708 DEBC(printk(ST_DEB_MSG
1709 "%s: Retry write of %d bytes at EOM.\n",
1710 name, STp->buffer->buffer_bytes));
1711 goto retry_write;
1712 }
1713 else {
1714 /* Either error within data buffered by driver or
1715 failed retry */
1716 count -= do_count;
1717 blks = do_count = 0;
1718 STps->eof = ST_EOM_ERROR;
1719 STps->drv_block = (-1); /* Too cautious? */
1720 retval = (-EIO); /* EOM for old data */
1721 DEBC(printk(ST_DEB_MSG
1722 "%s: EOM with lost data.\n",
1723 name));
1724 }
1725 }
1726 } else {
1727 count += do_count;
1728 STps->drv_block = (-1); /* Too cautious? */
Mike Christie8b05b772005-11-08 04:06:44 -06001729 retval = STbp->syscall_result;
Linus Torvalds1da177e2005-04-16 15:20:36 -07001730 }
1731
1732 }
1733
1734 if (STps->drv_block >= 0) {
1735 if (STp->block_size == 0)
1736 STps->drv_block += (do_count > 0);
1737 else
1738 STps->drv_block += blks;
1739 }
1740
1741 STbp->buffer_bytes = 0;
1742 STp->dirty = 0;
1743
1744 if (retval || retry_eot) {
1745 if (count < total)
1746 retval = total - count;
1747 goto out;
1748 }
1749 }
1750
1751 if (STps->eof == ST_EOD_1)
1752 STps->eof = ST_EOM_OK;
1753 else if (STps->eof != ST_EOM_OK)
1754 STps->eof = ST_NOEOF;
1755 retval = total - count;
1756
1757 out:
1758 if (SRpnt != NULL)
Mike Christie8b05b772005-11-08 04:06:44 -06001759 st_release_request(SRpnt);
Kai Makisara787926b2005-11-13 10:04:44 +02001760 release_buffering(STp, 0);
Matthias Kaehlcke28f85002007-07-29 23:38:15 +02001761 mutex_unlock(&STp->lock);
Linus Torvalds1da177e2005-04-16 15:20:36 -07001762
1763 return retval;
1764}
1765
1766/* Read data from the tape. Returns zero in the normal case, one if the
1767 eof status has changed, and the negative error code in case of a
1768 fatal error. Otherwise updates the buffer and the eof state.
1769
1770 Does release user buffer mapping if it is set.
1771*/
1772static long read_tape(struct scsi_tape *STp, long count,
Mike Christie8b05b772005-11-08 04:06:44 -06001773 struct st_request ** aSRpnt)
Linus Torvalds1da177e2005-04-16 15:20:36 -07001774{
1775 int transfer, blks, bytes;
1776 unsigned char cmd[MAX_COMMAND_SIZE];
Mike Christie8b05b772005-11-08 04:06:44 -06001777 struct st_request *SRpnt;
Linus Torvalds1da177e2005-04-16 15:20:36 -07001778 struct st_modedef *STm;
1779 struct st_partstat *STps;
1780 struct st_buffer *STbp;
1781 int retval = 0;
1782 char *name = tape_name(STp);
1783
1784 if (count == 0)
1785 return 0;
1786
1787 STm = &(STp->modes[STp->current_mode]);
1788 STps = &(STp->ps[STp->partition]);
1789 if (STps->eof == ST_FM_HIT)
1790 return 1;
1791 STbp = STp->buffer;
1792
1793 if (STp->block_size == 0)
1794 blks = bytes = count;
1795 else {
Kai Makisara9abe16c2007-02-03 13:21:29 +02001796 if (!(STp->try_dio_now && try_rdio) && STm->do_read_ahead) {
Linus Torvalds1da177e2005-04-16 15:20:36 -07001797 blks = (STp->buffer)->buffer_blocks;
1798 bytes = blks * STp->block_size;
1799 } else {
1800 bytes = count;
1801 if (!STbp->do_dio && bytes > (STp->buffer)->buffer_size)
1802 bytes = (STp->buffer)->buffer_size;
1803 blks = bytes / STp->block_size;
1804 bytes = blks * STp->block_size;
1805 }
1806 }
1807
1808 memset(cmd, 0, MAX_COMMAND_SIZE);
1809 cmd[0] = READ_6;
1810 cmd[1] = (STp->block_size != 0);
Kai Makisara40f6b362008-02-24 22:23:24 +02001811 if (!cmd[1] && STp->sili)
1812 cmd[1] |= 2;
Linus Torvalds1da177e2005-04-16 15:20:36 -07001813 cmd[2] = blks >> 16;
1814 cmd[3] = blks >> 8;
1815 cmd[4] = blks;
1816
1817 SRpnt = *aSRpnt;
1818 SRpnt = st_do_scsi(SRpnt, STp, cmd, bytes, DMA_FROM_DEVICE,
James Bottomleya02488e2008-11-30 10:36:26 -06001819 STp->device->request_queue->rq_timeout,
1820 MAX_RETRIES, 1);
Kai Makisara787926b2005-11-13 10:04:44 +02001821 release_buffering(STp, 1);
Linus Torvalds1da177e2005-04-16 15:20:36 -07001822 *aSRpnt = SRpnt;
1823 if (!SRpnt)
1824 return STbp->syscall_result;
1825
1826 STbp->read_pointer = 0;
1827 STps->at_sm = 0;
1828
1829 /* Something to check */
1830 if (STbp->syscall_result) {
1831 struct st_cmdstatus *cmdstatp = &STp->buffer->cmdstat;
1832
1833 retval = 1;
1834 DEBC(printk(ST_DEB_MSG "%s: Sense: %2x %2x %2x %2x %2x %2x %2x %2x\n",
1835 name,
Mike Christie8b05b772005-11-08 04:06:44 -06001836 SRpnt->sense[0], SRpnt->sense[1],
1837 SRpnt->sense[2], SRpnt->sense[3],
1838 SRpnt->sense[4], SRpnt->sense[5],
1839 SRpnt->sense[6], SRpnt->sense[7]));
Linus Torvalds1da177e2005-04-16 15:20:36 -07001840 if (cmdstatp->have_sense) {
1841
1842 if (cmdstatp->sense_hdr.sense_key == BLANK_CHECK)
1843 cmdstatp->flags &= 0xcf; /* No need for EOM in this case */
1844
1845 if (cmdstatp->flags != 0) { /* EOF, EOM, or ILI */
1846 /* Compute the residual count */
1847 if (cmdstatp->remainder_valid)
1848 transfer = (int)cmdstatp->uremainder64;
1849 else
1850 transfer = 0;
1851 if (STp->block_size == 0 &&
1852 cmdstatp->sense_hdr.sense_key == MEDIUM_ERROR)
1853 transfer = bytes;
1854
1855 if (cmdstatp->flags & SENSE_ILI) { /* ILI */
1856 if (STp->block_size == 0) {
1857 if (transfer <= 0) {
1858 if (transfer < 0)
1859 printk(KERN_NOTICE
1860 "%s: Failed to read %d byte block with %d byte transfer.\n",
1861 name, bytes - transfer, bytes);
1862 if (STps->drv_block >= 0)
1863 STps->drv_block += 1;
1864 STbp->buffer_bytes = 0;
1865 return (-ENOMEM);
1866 }
1867 STbp->buffer_bytes = bytes - transfer;
1868 } else {
Mike Christie8b05b772005-11-08 04:06:44 -06001869 st_release_request(SRpnt);
Linus Torvalds1da177e2005-04-16 15:20:36 -07001870 SRpnt = *aSRpnt = NULL;
1871 if (transfer == blks) { /* We did not get anything, error */
1872 printk(KERN_NOTICE "%s: Incorrect block size.\n", name);
1873 if (STps->drv_block >= 0)
1874 STps->drv_block += blks - transfer + 1;
1875 st_int_ioctl(STp, MTBSR, 1);
1876 return (-EIO);
1877 }
1878 /* We have some data, deliver it */
1879 STbp->buffer_bytes = (blks - transfer) *
1880 STp->block_size;
1881 DEBC(printk(ST_DEB_MSG
1882 "%s: ILI but enough data received %ld %d.\n",
1883 name, count, STbp->buffer_bytes));
1884 if (STps->drv_block >= 0)
1885 STps->drv_block += 1;
1886 if (st_int_ioctl(STp, MTBSR, 1))
1887 return (-EIO);
1888 }
1889 } else if (cmdstatp->flags & SENSE_FMK) { /* FM overrides EOM */
1890 if (STps->eof != ST_FM_HIT)
1891 STps->eof = ST_FM_HIT;
1892 else
1893 STps->eof = ST_EOD_2;
1894 if (STp->block_size == 0)
1895 STbp->buffer_bytes = 0;
1896 else
1897 STbp->buffer_bytes =
1898 bytes - transfer * STp->block_size;
1899 DEBC(printk(ST_DEB_MSG
1900 "%s: EOF detected (%d bytes read).\n",
1901 name, STbp->buffer_bytes));
1902 } else if (cmdstatp->flags & SENSE_EOM) {
1903 if (STps->eof == ST_FM)
1904 STps->eof = ST_EOD_1;
1905 else
1906 STps->eof = ST_EOM_OK;
1907 if (STp->block_size == 0)
1908 STbp->buffer_bytes = bytes - transfer;
1909 else
1910 STbp->buffer_bytes =
1911 bytes - transfer * STp->block_size;
1912
1913 DEBC(printk(ST_DEB_MSG "%s: EOM detected (%d bytes read).\n",
1914 name, STbp->buffer_bytes));
1915 }
1916 }
1917 /* end of EOF, EOM, ILI test */
1918 else { /* nonzero sense key */
1919 DEBC(printk(ST_DEB_MSG
1920 "%s: Tape error while reading.\n", name));
1921 STps->drv_block = (-1);
1922 if (STps->eof == ST_FM &&
1923 cmdstatp->sense_hdr.sense_key == BLANK_CHECK) {
1924 DEBC(printk(ST_DEB_MSG
1925 "%s: Zero returned for first BLANK CHECK after EOF.\n",
1926 name));
1927 STps->eof = ST_EOD_2; /* First BLANK_CHECK after FM */
1928 } else /* Some other extended sense code */
1929 retval = (-EIO);
1930 }
1931
1932 if (STbp->buffer_bytes < 0) /* Caused by bogus sense data */
1933 STbp->buffer_bytes = 0;
1934 }
1935 /* End of extended sense test */
1936 else { /* Non-extended sense */
1937 retval = STbp->syscall_result;
1938 }
1939
1940 }
1941 /* End of error handling */
Kai Makisara40f6b362008-02-24 22:23:24 +02001942 else { /* Read successful */
Linus Torvalds1da177e2005-04-16 15:20:36 -07001943 STbp->buffer_bytes = bytes;
Kai Makisara40f6b362008-02-24 22:23:24 +02001944 if (STp->sili) /* In fixed block mode residual is always zero here */
1945 STbp->buffer_bytes -= STp->buffer->cmdstat.residual;
1946 }
Linus Torvalds1da177e2005-04-16 15:20:36 -07001947
1948 if (STps->drv_block >= 0) {
1949 if (STp->block_size == 0)
1950 STps->drv_block++;
1951 else
1952 STps->drv_block += STbp->buffer_bytes / STp->block_size;
1953 }
1954 return retval;
1955}
1956
1957
1958/* Read command */
1959static ssize_t
1960st_read(struct file *filp, char __user *buf, size_t count, loff_t * ppos)
1961{
1962 ssize_t total;
1963 ssize_t retval = 0;
1964 ssize_t i, transfer;
1965 int special, do_dio = 0;
Mike Christie8b05b772005-11-08 04:06:44 -06001966 struct st_request *SRpnt = NULL;
Linus Torvalds1da177e2005-04-16 15:20:36 -07001967 struct scsi_tape *STp = filp->private_data;
1968 struct st_modedef *STm;
1969 struct st_partstat *STps;
1970 struct st_buffer *STbp = STp->buffer;
1971 DEB( char *name = tape_name(STp); )
1972
Matthias Kaehlcke28f85002007-07-29 23:38:15 +02001973 if (mutex_lock_interruptible(&STp->lock))
Linus Torvalds1da177e2005-04-16 15:20:36 -07001974 return -ERESTARTSYS;
1975
1976 retval = rw_checks(STp, filp, count);
1977 if (retval || count == 0)
1978 goto out;
1979
1980 STm = &(STp->modes[STp->current_mode]);
Kai Makisara9abe16c2007-02-03 13:21:29 +02001981 if (STp->block_size != 0 && (count % STp->block_size) != 0) {
1982 if (!STm->do_read_ahead) {
1983 retval = (-EINVAL); /* Read must be integral number of blocks */
1984 goto out;
1985 }
1986 STp->try_dio_now = 0; /* Direct i/o can't handle split blocks */
Linus Torvalds1da177e2005-04-16 15:20:36 -07001987 }
1988
1989 STps = &(STp->ps[STp->partition]);
1990 if (STps->rw == ST_WRITING) {
1991 retval = flush_buffer(STp, 0);
1992 if (retval)
1993 goto out;
1994 STps->rw = ST_READING;
1995 }
1996 DEB(
1997 if (debugging && STps->eof != ST_NOEOF)
1998 printk(ST_DEB_MSG "%s: EOF/EOM flag up (%d). Bytes %d\n", name,
1999 STps->eof, STbp->buffer_bytes);
2000 ) /* end DEB */
2001
2002 retval = setup_buffering(STp, buf, count, 1);
2003 if (retval)
2004 goto out;
2005 do_dio = STbp->do_dio;
2006
2007 if (STbp->buffer_bytes == 0 &&
2008 STps->eof >= ST_EOD_1) {
2009 if (STps->eof < ST_EOD) {
2010 STps->eof += 1;
2011 retval = 0;
2012 goto out;
2013 }
2014 retval = (-EIO); /* EOM or Blank Check */
2015 goto out;
2016 }
2017
2018 if (do_dio) {
2019 /* Check the buffer writability before any tape movement. Don't alter
2020 buffer data. */
2021 if (copy_from_user(&i, buf, 1) != 0 ||
2022 copy_to_user(buf, &i, 1) != 0 ||
2023 copy_from_user(&i, buf + count - 1, 1) != 0 ||
2024 copy_to_user(buf + count - 1, &i, 1) != 0) {
2025 retval = (-EFAULT);
2026 goto out;
2027 }
2028 }
2029
2030 STps->rw = ST_READING;
2031
2032
2033 /* Loop until enough data in buffer or a special condition found */
2034 for (total = 0, special = 0; total < count && !special;) {
2035
2036 /* Get new data if the buffer is empty */
2037 if (STbp->buffer_bytes == 0) {
2038 special = read_tape(STp, count - total, &SRpnt);
2039 if (special < 0) { /* No need to continue read */
2040 retval = special;
2041 goto out;
2042 }
2043 }
2044
2045 /* Move the data from driver buffer to user buffer */
2046 if (STbp->buffer_bytes > 0) {
2047 DEB(
2048 if (debugging && STps->eof != ST_NOEOF)
2049 printk(ST_DEB_MSG
2050 "%s: EOF up (%d). Left %d, needed %d.\n", name,
2051 STps->eof, STbp->buffer_bytes,
2052 (int)(count - total));
2053 ) /* end DEB */
2054 transfer = STbp->buffer_bytes < count - total ?
2055 STbp->buffer_bytes : count - total;
2056 if (!do_dio) {
2057 i = from_buffer(STbp, buf, transfer);
2058 if (i) {
2059 retval = i;
2060 goto out;
2061 }
2062 }
2063 buf += transfer;
2064 total += transfer;
2065 }
2066
2067 if (STp->block_size == 0)
2068 break; /* Read only one variable length block */
2069
2070 } /* for (total = 0, special = 0;
2071 total < count && !special; ) */
2072
2073 /* Change the eof state if no data from tape or buffer */
2074 if (total == 0) {
2075 if (STps->eof == ST_FM_HIT) {
2076 STps->eof = ST_FM;
2077 STps->drv_block = 0;
2078 if (STps->drv_file >= 0)
2079 STps->drv_file++;
2080 } else if (STps->eof == ST_EOD_1) {
2081 STps->eof = ST_EOD_2;
2082 STps->drv_block = 0;
2083 if (STps->drv_file >= 0)
2084 STps->drv_file++;
2085 } else if (STps->eof == ST_EOD_2)
2086 STps->eof = ST_EOD;
2087 } else if (STps->eof == ST_FM)
2088 STps->eof = ST_NOEOF;
2089 retval = total;
2090
2091 out:
2092 if (SRpnt != NULL) {
Mike Christie8b05b772005-11-08 04:06:44 -06002093 st_release_request(SRpnt);
Linus Torvalds1da177e2005-04-16 15:20:36 -07002094 SRpnt = NULL;
2095 }
2096 if (do_dio) {
Kai Makisara787926b2005-11-13 10:04:44 +02002097 release_buffering(STp, 1);
Linus Torvalds1da177e2005-04-16 15:20:36 -07002098 STbp->buffer_bytes = 0;
2099 }
Matthias Kaehlcke28f85002007-07-29 23:38:15 +02002100 mutex_unlock(&STp->lock);
Linus Torvalds1da177e2005-04-16 15:20:36 -07002101
2102 return retval;
2103}
2104
2105
2106
2107DEB(
2108/* Set the driver options */
2109static void st_log_options(struct scsi_tape * STp, struct st_modedef * STm, char *name)
2110{
2111 if (debugging) {
2112 printk(KERN_INFO
2113 "%s: Mode %d options: buffer writes: %d, async writes: %d, read ahead: %d\n",
2114 name, STp->current_mode, STm->do_buffer_writes, STm->do_async_writes,
2115 STm->do_read_ahead);
2116 printk(KERN_INFO
2117 "%s: can bsr: %d, two FMs: %d, fast mteom: %d, auto lock: %d,\n",
2118 name, STp->can_bsr, STp->two_fm, STp->fast_mteom, STp->do_auto_lock);
2119 printk(KERN_INFO
2120 "%s: defs for wr: %d, no block limits: %d, partitions: %d, s2 log: %d\n",
2121 name, STm->defaults_for_writes, STp->omit_blklims, STp->can_partitions,
2122 STp->scsi2_logical);
2123 printk(KERN_INFO
Kai Makisara40f6b362008-02-24 22:23:24 +02002124 "%s: sysv: %d nowait: %d sili: %d\n", name, STm->sysv, STp->immediate,
2125 STp->sili);
Linus Torvalds1da177e2005-04-16 15:20:36 -07002126 printk(KERN_INFO "%s: debugging: %d\n",
2127 name, debugging);
2128 }
2129}
2130 )
2131
2132
2133static int st_set_options(struct scsi_tape *STp, long options)
2134{
2135 int value;
2136 long code;
2137 struct st_modedef *STm;
2138 char *name = tape_name(STp);
2139 struct cdev *cd0, *cd1;
2140
2141 STm = &(STp->modes[STp->current_mode]);
2142 if (!STm->defined) {
2143 cd0 = STm->cdevs[0]; cd1 = STm->cdevs[1];
2144 memcpy(STm, &(STp->modes[0]), sizeof(struct st_modedef));
2145 STm->cdevs[0] = cd0; STm->cdevs[1] = cd1;
2146 modes_defined = 1;
2147 DEBC(printk(ST_DEB_MSG
2148 "%s: Initialized mode %d definition from mode 0\n",
2149 name, STp->current_mode));
2150 }
2151
2152 code = options & MT_ST_OPTIONS;
2153 if (code == MT_ST_BOOLEANS) {
2154 STm->do_buffer_writes = (options & MT_ST_BUFFER_WRITES) != 0;
2155 STm->do_async_writes = (options & MT_ST_ASYNC_WRITES) != 0;
2156 STm->defaults_for_writes = (options & MT_ST_DEF_WRITES) != 0;
2157 STm->do_read_ahead = (options & MT_ST_READ_AHEAD) != 0;
2158 STp->two_fm = (options & MT_ST_TWO_FM) != 0;
2159 STp->fast_mteom = (options & MT_ST_FAST_MTEOM) != 0;
2160 STp->do_auto_lock = (options & MT_ST_AUTO_LOCK) != 0;
2161 STp->can_bsr = (options & MT_ST_CAN_BSR) != 0;
2162 STp->omit_blklims = (options & MT_ST_NO_BLKLIMS) != 0;
2163 if ((STp->device)->scsi_level >= SCSI_2)
2164 STp->can_partitions = (options & MT_ST_CAN_PARTITIONS) != 0;
2165 STp->scsi2_logical = (options & MT_ST_SCSI2LOGICAL) != 0;
2166 STp->immediate = (options & MT_ST_NOWAIT) != 0;
2167 STm->sysv = (options & MT_ST_SYSV) != 0;
Kai Makisara40f6b362008-02-24 22:23:24 +02002168 STp->sili = (options & MT_ST_SILI) != 0;
Linus Torvalds1da177e2005-04-16 15:20:36 -07002169 DEB( debugging = (options & MT_ST_DEBUGGING) != 0;
2170 st_log_options(STp, STm, name); )
2171 } else if (code == MT_ST_SETBOOLEANS || code == MT_ST_CLEARBOOLEANS) {
2172 value = (code == MT_ST_SETBOOLEANS);
2173 if ((options & MT_ST_BUFFER_WRITES) != 0)
2174 STm->do_buffer_writes = value;
2175 if ((options & MT_ST_ASYNC_WRITES) != 0)
2176 STm->do_async_writes = value;
2177 if ((options & MT_ST_DEF_WRITES) != 0)
2178 STm->defaults_for_writes = value;
2179 if ((options & MT_ST_READ_AHEAD) != 0)
2180 STm->do_read_ahead = value;
2181 if ((options & MT_ST_TWO_FM) != 0)
2182 STp->two_fm = value;
2183 if ((options & MT_ST_FAST_MTEOM) != 0)
2184 STp->fast_mteom = value;
2185 if ((options & MT_ST_AUTO_LOCK) != 0)
2186 STp->do_auto_lock = value;
2187 if ((options & MT_ST_CAN_BSR) != 0)
2188 STp->can_bsr = value;
2189 if ((options & MT_ST_NO_BLKLIMS) != 0)
2190 STp->omit_blklims = value;
2191 if ((STp->device)->scsi_level >= SCSI_2 &&
2192 (options & MT_ST_CAN_PARTITIONS) != 0)
2193 STp->can_partitions = value;
2194 if ((options & MT_ST_SCSI2LOGICAL) != 0)
2195 STp->scsi2_logical = value;
2196 if ((options & MT_ST_NOWAIT) != 0)
2197 STp->immediate = value;
2198 if ((options & MT_ST_SYSV) != 0)
2199 STm->sysv = value;
Kai Makisara40f6b362008-02-24 22:23:24 +02002200 if ((options & MT_ST_SILI) != 0)
2201 STp->sili = value;
Linus Torvalds1da177e2005-04-16 15:20:36 -07002202 DEB(
2203 if ((options & MT_ST_DEBUGGING) != 0)
2204 debugging = value;
2205 st_log_options(STp, STm, name); )
2206 } else if (code == MT_ST_WRITE_THRESHOLD) {
2207 /* Retained for compatibility */
2208 } else if (code == MT_ST_DEF_BLKSIZE) {
2209 value = (options & ~MT_ST_OPTIONS);
2210 if (value == ~MT_ST_OPTIONS) {
2211 STm->default_blksize = (-1);
2212 DEBC( printk(KERN_INFO "%s: Default block size disabled.\n", name));
2213 } else {
2214 STm->default_blksize = value;
2215 DEBC( printk(KERN_INFO "%s: Default block size set to %d bytes.\n",
2216 name, STm->default_blksize));
2217 if (STp->ready == ST_READY) {
2218 STp->blksize_changed = 0;
2219 set_mode_densblk(STp, STm);
2220 }
2221 }
2222 } else if (code == MT_ST_TIMEOUTS) {
2223 value = (options & ~MT_ST_OPTIONS);
2224 if ((value & MT_ST_SET_LONG_TIMEOUT) != 0) {
2225 STp->long_timeout = (value & ~MT_ST_SET_LONG_TIMEOUT) * HZ;
2226 DEBC( printk(KERN_INFO "%s: Long timeout set to %d seconds.\n", name,
2227 (value & ~MT_ST_SET_LONG_TIMEOUT)));
2228 } else {
James Bottomleya02488e2008-11-30 10:36:26 -06002229 blk_queue_rq_timeout(STp->device->request_queue,
2230 value * HZ);
Linus Torvalds1da177e2005-04-16 15:20:36 -07002231 DEBC( printk(KERN_INFO "%s: Normal timeout set to %d seconds.\n",
2232 name, value) );
2233 }
2234 } else if (code == MT_ST_SET_CLN) {
2235 value = (options & ~MT_ST_OPTIONS) & 0xff;
2236 if (value != 0 &&
2237 value < EXTENDED_SENSE_START && value >= SCSI_SENSE_BUFFERSIZE)
2238 return (-EINVAL);
2239 STp->cln_mode = value;
2240 STp->cln_sense_mask = (options >> 8) & 0xff;
2241 STp->cln_sense_value = (options >> 16) & 0xff;
2242 printk(KERN_INFO
2243 "%s: Cleaning request mode %d, mask %02x, value %02x\n",
2244 name, value, STp->cln_sense_mask, STp->cln_sense_value);
2245 } else if (code == MT_ST_DEF_OPTIONS) {
2246 code = (options & ~MT_ST_CLEAR_DEFAULT);
2247 value = (options & MT_ST_CLEAR_DEFAULT);
2248 if (code == MT_ST_DEF_DENSITY) {
2249 if (value == MT_ST_CLEAR_DEFAULT) {
2250 STm->default_density = (-1);
2251 DEBC( printk(KERN_INFO "%s: Density default disabled.\n",
2252 name));
2253 } else {
2254 STm->default_density = value & 0xff;
2255 DEBC( printk(KERN_INFO "%s: Density default set to %x\n",
2256 name, STm->default_density));
2257 if (STp->ready == ST_READY) {
2258 STp->density_changed = 0;
2259 set_mode_densblk(STp, STm);
2260 }
2261 }
2262 } else if (code == MT_ST_DEF_DRVBUFFER) {
2263 if (value == MT_ST_CLEAR_DEFAULT) {
2264 STp->default_drvbuffer = 0xff;
2265 DEBC( printk(KERN_INFO
2266 "%s: Drive buffer default disabled.\n", name));
2267 } else {
2268 STp->default_drvbuffer = value & 7;
2269 DEBC( printk(KERN_INFO
2270 "%s: Drive buffer default set to %x\n",
2271 name, STp->default_drvbuffer));
2272 if (STp->ready == ST_READY)
2273 st_int_ioctl(STp, MTSETDRVBUFFER, STp->default_drvbuffer);
2274 }
2275 } else if (code == MT_ST_DEF_COMPRESSION) {
2276 if (value == MT_ST_CLEAR_DEFAULT) {
2277 STm->default_compression = ST_DONT_TOUCH;
2278 DEBC( printk(KERN_INFO
2279 "%s: Compression default disabled.\n", name));
2280 } else {
2281 if ((value & 0xff00) != 0) {
2282 STp->c_algo = (value & 0xff00) >> 8;
2283 DEBC( printk(KERN_INFO "%s: Compression algorithm set to 0x%x.\n",
2284 name, STp->c_algo));
2285 }
2286 if ((value & 0xff) != 0xff) {
2287 STm->default_compression = (value & 1 ? ST_YES : ST_NO);
2288 DEBC( printk(KERN_INFO "%s: Compression default set to %x\n",
2289 name, (value & 1)));
2290 if (STp->ready == ST_READY) {
2291 STp->compression_changed = 0;
2292 st_compression(STp, (STm->default_compression == ST_YES));
2293 }
2294 }
2295 }
2296 }
2297 } else
2298 return (-EIO);
2299
2300 return 0;
2301}
2302
2303#define MODE_HEADER_LENGTH 4
2304
2305/* Mode header and page byte offsets */
2306#define MH_OFF_DATA_LENGTH 0
2307#define MH_OFF_MEDIUM_TYPE 1
2308#define MH_OFF_DEV_SPECIFIC 2
2309#define MH_OFF_BDESCS_LENGTH 3
2310#define MP_OFF_PAGE_NBR 0
2311#define MP_OFF_PAGE_LENGTH 1
2312
2313/* Mode header and page bit masks */
2314#define MH_BIT_WP 0x80
2315#define MP_MSK_PAGE_NBR 0x3f
2316
2317/* Don't return block descriptors */
2318#define MODE_SENSE_OMIT_BDESCS 0x08
2319
2320#define MODE_SELECT_PAGE_FORMAT 0x10
2321
2322/* Read a mode page into the tape buffer. The block descriptors are included
2323 if incl_block_descs is true. The page control is ored to the page number
2324 parameter, if necessary. */
2325static int read_mode_page(struct scsi_tape *STp, int page, int omit_block_descs)
2326{
2327 unsigned char cmd[MAX_COMMAND_SIZE];
Mike Christie8b05b772005-11-08 04:06:44 -06002328 struct st_request *SRpnt = NULL;
Linus Torvalds1da177e2005-04-16 15:20:36 -07002329
2330 memset(cmd, 0, MAX_COMMAND_SIZE);
2331 cmd[0] = MODE_SENSE;
2332 if (omit_block_descs)
2333 cmd[1] = MODE_SENSE_OMIT_BDESCS;
2334 cmd[2] = page;
2335 cmd[4] = 255;
2336
2337 SRpnt = st_do_scsi(SRpnt, STp, cmd, cmd[4], DMA_FROM_DEVICE,
James Bottomleya02488e2008-11-30 10:36:26 -06002338 STp->device->request_queue->rq_timeout, 0, 1);
Linus Torvalds1da177e2005-04-16 15:20:36 -07002339 if (SRpnt == NULL)
2340 return (STp->buffer)->syscall_result;
2341
Mike Christie8b05b772005-11-08 04:06:44 -06002342 st_release_request(SRpnt);
Linus Torvalds1da177e2005-04-16 15:20:36 -07002343
2344 return (STp->buffer)->syscall_result;
2345}
2346
2347
2348/* Send the mode page in the tape buffer to the drive. Assumes that the mode data
2349 in the buffer is correctly formatted. The long timeout is used if slow is non-zero. */
2350static int write_mode_page(struct scsi_tape *STp, int page, int slow)
2351{
2352 int pgo;
2353 unsigned char cmd[MAX_COMMAND_SIZE];
Mike Christie8b05b772005-11-08 04:06:44 -06002354 struct st_request *SRpnt = NULL;
Linus Torvalds1da177e2005-04-16 15:20:36 -07002355
2356 memset(cmd, 0, MAX_COMMAND_SIZE);
2357 cmd[0] = MODE_SELECT;
2358 cmd[1] = MODE_SELECT_PAGE_FORMAT;
2359 pgo = MODE_HEADER_LENGTH + (STp->buffer)->b_data[MH_OFF_BDESCS_LENGTH];
2360 cmd[4] = pgo + (STp->buffer)->b_data[pgo + MP_OFF_PAGE_LENGTH] + 2;
2361
2362 /* Clear reserved fields */
2363 (STp->buffer)->b_data[MH_OFF_DATA_LENGTH] = 0;
2364 (STp->buffer)->b_data[MH_OFF_MEDIUM_TYPE] = 0;
2365 (STp->buffer)->b_data[MH_OFF_DEV_SPECIFIC] &= ~MH_BIT_WP;
2366 (STp->buffer)->b_data[pgo + MP_OFF_PAGE_NBR] &= MP_MSK_PAGE_NBR;
2367
2368 SRpnt = st_do_scsi(SRpnt, STp, cmd, cmd[4], DMA_TO_DEVICE,
James Bottomleya02488e2008-11-30 10:36:26 -06002369 (slow ? STp->long_timeout : STp->device->request_queue->rq_timeout), 0, 1);
Linus Torvalds1da177e2005-04-16 15:20:36 -07002370 if (SRpnt == NULL)
2371 return (STp->buffer)->syscall_result;
2372
Mike Christie8b05b772005-11-08 04:06:44 -06002373 st_release_request(SRpnt);
Linus Torvalds1da177e2005-04-16 15:20:36 -07002374
2375 return (STp->buffer)->syscall_result;
2376}
2377
2378
2379#define COMPRESSION_PAGE 0x0f
2380#define COMPRESSION_PAGE_LENGTH 16
2381
2382#define CP_OFF_DCE_DCC 2
2383#define CP_OFF_C_ALGO 7
2384
2385#define DCE_MASK 0x80
2386#define DCC_MASK 0x40
2387#define RED_MASK 0x60
2388
2389
2390/* Control the compression with mode page 15. Algorithm not changed if zero.
2391
2392 The block descriptors are read and written because Sony SDT-7000 does not
2393 work without this (suggestion from Michael Schaefer <Michael.Schaefer@dlr.de>).
2394 Including block descriptors should not cause any harm to other drives. */
2395
2396static int st_compression(struct scsi_tape * STp, int state)
2397{
2398 int retval;
2399 int mpoffs; /* Offset to mode page start */
2400 unsigned char *b_data = (STp->buffer)->b_data;
2401 DEB( char *name = tape_name(STp); )
2402
2403 if (STp->ready != ST_READY)
2404 return (-EIO);
2405
2406 /* Read the current page contents */
2407 retval = read_mode_page(STp, COMPRESSION_PAGE, 0);
2408 if (retval) {
2409 DEBC(printk(ST_DEB_MSG "%s: Compression mode page not supported.\n",
2410 name));
2411 return (-EIO);
2412 }
2413
2414 mpoffs = MODE_HEADER_LENGTH + b_data[MH_OFF_BDESCS_LENGTH];
2415 DEBC(printk(ST_DEB_MSG "%s: Compression state is %d.\n", name,
2416 (b_data[mpoffs + CP_OFF_DCE_DCC] & DCE_MASK ? 1 : 0)));
2417
2418 /* Check if compression can be changed */
2419 if ((b_data[mpoffs + CP_OFF_DCE_DCC] & DCC_MASK) == 0) {
2420 DEBC(printk(ST_DEB_MSG "%s: Compression not supported.\n", name));
2421 return (-EIO);
2422 }
2423
2424 /* Do the change */
2425 if (state) {
2426 b_data[mpoffs + CP_OFF_DCE_DCC] |= DCE_MASK;
2427 if (STp->c_algo != 0)
2428 b_data[mpoffs + CP_OFF_C_ALGO] = STp->c_algo;
2429 }
2430 else {
2431 b_data[mpoffs + CP_OFF_DCE_DCC] &= ~DCE_MASK;
2432 if (STp->c_algo != 0)
2433 b_data[mpoffs + CP_OFF_C_ALGO] = 0; /* no compression */
2434 }
2435
2436 retval = write_mode_page(STp, COMPRESSION_PAGE, 0);
2437 if (retval) {
2438 DEBC(printk(ST_DEB_MSG "%s: Compression change failed.\n", name));
2439 return (-EIO);
2440 }
2441 DEBC(printk(ST_DEB_MSG "%s: Compression state changed to %d.\n",
2442 name, state));
2443
2444 STp->compression_changed = 1;
2445 return 0;
2446}
2447
2448
2449/* Process the load and unload commands (does unload if the load code is zero) */
2450static int do_load_unload(struct scsi_tape *STp, struct file *filp, int load_code)
2451{
2452 int retval = (-EIO), timeout;
2453 DEB( char *name = tape_name(STp); )
2454 unsigned char cmd[MAX_COMMAND_SIZE];
2455 struct st_partstat *STps;
Mike Christie8b05b772005-11-08 04:06:44 -06002456 struct st_request *SRpnt;
Linus Torvalds1da177e2005-04-16 15:20:36 -07002457
2458 if (STp->ready != ST_READY && !load_code) {
2459 if (STp->ready == ST_NO_TAPE)
2460 return (-ENOMEDIUM);
2461 else
2462 return (-EIO);
2463 }
2464
2465 memset(cmd, 0, MAX_COMMAND_SIZE);
2466 cmd[0] = START_STOP;
2467 if (load_code)
2468 cmd[4] |= 1;
2469 /*
2470 * If arg >= 1 && arg <= 6 Enhanced load/unload in HP C1553A
2471 */
2472 if (load_code >= 1 + MT_ST_HPLOADER_OFFSET
2473 && load_code <= 6 + MT_ST_HPLOADER_OFFSET) {
2474 DEBC(printk(ST_DEB_MSG "%s: Enhanced %sload slot %2d.\n",
2475 name, (cmd[4]) ? "" : "un",
2476 load_code - MT_ST_HPLOADER_OFFSET));
2477 cmd[3] = load_code - MT_ST_HPLOADER_OFFSET; /* MediaID field of C1553A */
2478 }
2479 if (STp->immediate) {
2480 cmd[1] = 1; /* Don't wait for completion */
James Bottomleya02488e2008-11-30 10:36:26 -06002481 timeout = STp->device->request_queue->rq_timeout;
Linus Torvalds1da177e2005-04-16 15:20:36 -07002482 }
2483 else
2484 timeout = STp->long_timeout;
2485
2486 DEBC(
2487 if (!load_code)
2488 printk(ST_DEB_MSG "%s: Unloading tape.\n", name);
2489 else
2490 printk(ST_DEB_MSG "%s: Loading tape.\n", name);
2491 );
2492
2493 SRpnt = st_do_scsi(NULL, STp, cmd, 0, DMA_NONE,
2494 timeout, MAX_RETRIES, 1);
2495 if (!SRpnt)
2496 return (STp->buffer)->syscall_result;
2497
2498 retval = (STp->buffer)->syscall_result;
Mike Christie8b05b772005-11-08 04:06:44 -06002499 st_release_request(SRpnt);
Linus Torvalds1da177e2005-04-16 15:20:36 -07002500
2501 if (!retval) { /* SCSI command successful */
2502
2503 if (!load_code) {
2504 STp->rew_at_close = 0;
2505 STp->ready = ST_NO_TAPE;
2506 }
2507 else {
2508 STp->rew_at_close = STp->autorew_dev;
2509 retval = check_tape(STp, filp);
2510 if (retval > 0)
2511 retval = 0;
2512 }
2513 }
2514 else {
2515 STps = &(STp->ps[STp->partition]);
2516 STps->drv_file = STps->drv_block = (-1);
2517 }
2518
2519 return retval;
2520}
2521
2522#if DEBUG
2523#define ST_DEB_FORWARD 0
2524#define ST_DEB_BACKWARD 1
2525static void deb_space_print(char *name, int direction, char *units, unsigned char *cmd)
2526{
2527 s32 sc;
2528
2529 sc = cmd[2] & 0x80 ? 0xff000000 : 0;
2530 sc |= (cmd[2] << 16) | (cmd[3] << 8) | cmd[4];
2531 if (direction)
2532 sc = -sc;
2533 printk(ST_DEB_MSG "%s: Spacing tape %s over %d %s.\n", name,
2534 direction ? "backward" : "forward", sc, units);
2535}
2536#endif
2537
2538
2539/* Internal ioctl function */
2540static int st_int_ioctl(struct scsi_tape *STp, unsigned int cmd_in, unsigned long arg)
2541{
2542 int timeout;
2543 long ltmp;
2544 int ioctl_result;
2545 int chg_eof = 1;
2546 unsigned char cmd[MAX_COMMAND_SIZE];
Mike Christie8b05b772005-11-08 04:06:44 -06002547 struct st_request *SRpnt;
Linus Torvalds1da177e2005-04-16 15:20:36 -07002548 struct st_partstat *STps;
2549 int fileno, blkno, at_sm, undone;
2550 int datalen = 0, direction = DMA_NONE;
2551 char *name = tape_name(STp);
2552
2553 WARN_ON(STp->buffer->do_dio != 0);
2554 if (STp->ready != ST_READY) {
2555 if (STp->ready == ST_NO_TAPE)
2556 return (-ENOMEDIUM);
2557 else
2558 return (-EIO);
2559 }
2560 timeout = STp->long_timeout;
2561 STps = &(STp->ps[STp->partition]);
2562 fileno = STps->drv_file;
2563 blkno = STps->drv_block;
2564 at_sm = STps->at_sm;
2565
2566 memset(cmd, 0, MAX_COMMAND_SIZE);
2567 switch (cmd_in) {
2568 case MTFSFM:
2569 chg_eof = 0; /* Changed from the FSF after this */
2570 case MTFSF:
2571 cmd[0] = SPACE;
2572 cmd[1] = 0x01; /* Space FileMarks */
2573 cmd[2] = (arg >> 16);
2574 cmd[3] = (arg >> 8);
2575 cmd[4] = arg;
2576 DEBC(deb_space_print(name, ST_DEB_FORWARD, "filemarks", cmd);)
2577 if (fileno >= 0)
2578 fileno += arg;
2579 blkno = 0;
2580 at_sm &= (arg == 0);
2581 break;
2582 case MTBSFM:
2583 chg_eof = 0; /* Changed from the FSF after this */
2584 case MTBSF:
2585 cmd[0] = SPACE;
2586 cmd[1] = 0x01; /* Space FileMarks */
2587 ltmp = (-arg);
2588 cmd[2] = (ltmp >> 16);
2589 cmd[3] = (ltmp >> 8);
2590 cmd[4] = ltmp;
2591 DEBC(deb_space_print(name, ST_DEB_BACKWARD, "filemarks", cmd);)
2592 if (fileno >= 0)
2593 fileno -= arg;
2594 blkno = (-1); /* We can't know the block number */
2595 at_sm &= (arg == 0);
2596 break;
2597 case MTFSR:
2598 cmd[0] = SPACE;
2599 cmd[1] = 0x00; /* Space Blocks */
2600 cmd[2] = (arg >> 16);
2601 cmd[3] = (arg >> 8);
2602 cmd[4] = arg;
2603 DEBC(deb_space_print(name, ST_DEB_FORWARD, "blocks", cmd);)
2604 if (blkno >= 0)
2605 blkno += arg;
2606 at_sm &= (arg == 0);
2607 break;
2608 case MTBSR:
2609 cmd[0] = SPACE;
2610 cmd[1] = 0x00; /* Space Blocks */
2611 ltmp = (-arg);
2612 cmd[2] = (ltmp >> 16);
2613 cmd[3] = (ltmp >> 8);
2614 cmd[4] = ltmp;
2615 DEBC(deb_space_print(name, ST_DEB_BACKWARD, "blocks", cmd);)
2616 if (blkno >= 0)
2617 blkno -= arg;
2618 at_sm &= (arg == 0);
2619 break;
2620 case MTFSS:
2621 cmd[0] = SPACE;
2622 cmd[1] = 0x04; /* Space Setmarks */
2623 cmd[2] = (arg >> 16);
2624 cmd[3] = (arg >> 8);
2625 cmd[4] = arg;
2626 DEBC(deb_space_print(name, ST_DEB_FORWARD, "setmarks", cmd);)
2627 if (arg != 0) {
2628 blkno = fileno = (-1);
2629 at_sm = 1;
2630 }
2631 break;
2632 case MTBSS:
2633 cmd[0] = SPACE;
2634 cmd[1] = 0x04; /* Space Setmarks */
2635 ltmp = (-arg);
2636 cmd[2] = (ltmp >> 16);
2637 cmd[3] = (ltmp >> 8);
2638 cmd[4] = ltmp;
2639 DEBC(deb_space_print(name, ST_DEB_BACKWARD, "setmarks", cmd);)
2640 if (arg != 0) {
2641 blkno = fileno = (-1);
2642 at_sm = 1;
2643 }
2644 break;
2645 case MTWEOF:
2646 case MTWSM:
2647 if (STp->write_prot)
2648 return (-EACCES);
2649 cmd[0] = WRITE_FILEMARKS;
2650 if (cmd_in == MTWSM)
2651 cmd[1] = 2;
2652 cmd[2] = (arg >> 16);
2653 cmd[3] = (arg >> 8);
2654 cmd[4] = arg;
James Bottomleya02488e2008-11-30 10:36:26 -06002655 timeout = STp->device->request_queue->rq_timeout;
Linus Torvalds1da177e2005-04-16 15:20:36 -07002656 DEBC(
2657 if (cmd_in == MTWEOF)
2658 printk(ST_DEB_MSG "%s: Writing %d filemarks.\n", name,
2659 cmd[2] * 65536 + cmd[3] * 256 + cmd[4]);
2660 else
2661 printk(ST_DEB_MSG "%s: Writing %d setmarks.\n", name,
2662 cmd[2] * 65536 + cmd[3] * 256 + cmd[4]);
2663 )
2664 if (fileno >= 0)
2665 fileno += arg;
2666 blkno = 0;
2667 at_sm = (cmd_in == MTWSM);
2668 break;
2669 case MTREW:
2670 cmd[0] = REZERO_UNIT;
2671 if (STp->immediate) {
2672 cmd[1] = 1; /* Don't wait for completion */
James Bottomleya02488e2008-11-30 10:36:26 -06002673 timeout = STp->device->request_queue->rq_timeout;
Linus Torvalds1da177e2005-04-16 15:20:36 -07002674 }
2675 DEBC(printk(ST_DEB_MSG "%s: Rewinding tape.\n", name));
2676 fileno = blkno = at_sm = 0;
2677 break;
2678 case MTNOP:
2679 DEBC(printk(ST_DEB_MSG "%s: No op on tape.\n", name));
2680 return 0; /* Should do something ? */
2681 break;
2682 case MTRETEN:
2683 cmd[0] = START_STOP;
2684 if (STp->immediate) {
2685 cmd[1] = 1; /* Don't wait for completion */
James Bottomleya02488e2008-11-30 10:36:26 -06002686 timeout = STp->device->request_queue->rq_timeout;
Linus Torvalds1da177e2005-04-16 15:20:36 -07002687 }
2688 cmd[4] = 3;
2689 DEBC(printk(ST_DEB_MSG "%s: Retensioning tape.\n", name));
2690 fileno = blkno = at_sm = 0;
2691 break;
2692 case MTEOM:
2693 if (!STp->fast_mteom) {
2694 /* space to the end of tape */
2695 ioctl_result = st_int_ioctl(STp, MTFSF, 0x7fffff);
2696 fileno = STps->drv_file;
2697 if (STps->eof >= ST_EOD_1)
2698 return 0;
2699 /* The next lines would hide the number of spaced FileMarks
2700 That's why I inserted the previous lines. I had no luck
2701 with detecting EOM with FSF, so we go now to EOM.
2702 Joerg Weule */
2703 } else
2704 fileno = (-1);
2705 cmd[0] = SPACE;
2706 cmd[1] = 3;
2707 DEBC(printk(ST_DEB_MSG "%s: Spacing to end of recorded medium.\n",
2708 name));
2709 blkno = -1;
2710 at_sm = 0;
2711 break;
2712 case MTERASE:
2713 if (STp->write_prot)
2714 return (-EACCES);
2715 cmd[0] = ERASE;
2716 cmd[1] = (arg ? 1 : 0); /* Long erase with non-zero argument */
2717 if (STp->immediate) {
2718 cmd[1] |= 2; /* Don't wait for completion */
James Bottomleya02488e2008-11-30 10:36:26 -06002719 timeout = STp->device->request_queue->rq_timeout;
Linus Torvalds1da177e2005-04-16 15:20:36 -07002720 }
2721 else
2722 timeout = STp->long_timeout * 8;
2723
2724 DEBC(printk(ST_DEB_MSG "%s: Erasing tape.\n", name));
2725 fileno = blkno = at_sm = 0;
2726 break;
2727 case MTSETBLK: /* Set block length */
2728 case MTSETDENSITY: /* Set tape density */
2729 case MTSETDRVBUFFER: /* Set drive buffering */
2730 case SET_DENS_AND_BLK: /* Set density and block size */
2731 chg_eof = 0;
2732 if (STp->dirty || (STp->buffer)->buffer_bytes != 0)
2733 return (-EIO); /* Not allowed if data in buffer */
2734 if ((cmd_in == MTSETBLK || cmd_in == SET_DENS_AND_BLK) &&
2735 (arg & MT_ST_BLKSIZE_MASK) != 0 &&
2736 STp->max_block > 0 &&
2737 ((arg & MT_ST_BLKSIZE_MASK) < STp->min_block ||
2738 (arg & MT_ST_BLKSIZE_MASK) > STp->max_block)) {
2739 printk(KERN_WARNING "%s: Illegal block size.\n", name);
2740 return (-EINVAL);
2741 }
2742 cmd[0] = MODE_SELECT;
2743 if ((STp->use_pf & USE_PF))
2744 cmd[1] = MODE_SELECT_PAGE_FORMAT;
2745 cmd[4] = datalen = 12;
2746 direction = DMA_TO_DEVICE;
2747
2748 memset((STp->buffer)->b_data, 0, 12);
2749 if (cmd_in == MTSETDRVBUFFER)
2750 (STp->buffer)->b_data[2] = (arg & 7) << 4;
2751 else
2752 (STp->buffer)->b_data[2] =
2753 STp->drv_buffer << 4;
2754 (STp->buffer)->b_data[3] = 8; /* block descriptor length */
2755 if (cmd_in == MTSETDENSITY) {
2756 (STp->buffer)->b_data[4] = arg;
2757 STp->density_changed = 1; /* At least we tried ;-) */
2758 } else if (cmd_in == SET_DENS_AND_BLK)
2759 (STp->buffer)->b_data[4] = arg >> 24;
2760 else
2761 (STp->buffer)->b_data[4] = STp->density;
2762 if (cmd_in == MTSETBLK || cmd_in == SET_DENS_AND_BLK) {
2763 ltmp = arg & MT_ST_BLKSIZE_MASK;
2764 if (cmd_in == MTSETBLK)
2765 STp->blksize_changed = 1; /* At least we tried ;-) */
2766 } else
2767 ltmp = STp->block_size;
2768 (STp->buffer)->b_data[9] = (ltmp >> 16);
2769 (STp->buffer)->b_data[10] = (ltmp >> 8);
2770 (STp->buffer)->b_data[11] = ltmp;
James Bottomleya02488e2008-11-30 10:36:26 -06002771 timeout = STp->device->request_queue->rq_timeout;
Linus Torvalds1da177e2005-04-16 15:20:36 -07002772 DEBC(
2773 if (cmd_in == MTSETBLK || cmd_in == SET_DENS_AND_BLK)
2774 printk(ST_DEB_MSG
2775 "%s: Setting block size to %d bytes.\n", name,
2776 (STp->buffer)->b_data[9] * 65536 +
2777 (STp->buffer)->b_data[10] * 256 +
2778 (STp->buffer)->b_data[11]);
2779 if (cmd_in == MTSETDENSITY || cmd_in == SET_DENS_AND_BLK)
2780 printk(ST_DEB_MSG
2781 "%s: Setting density code to %x.\n", name,
2782 (STp->buffer)->b_data[4]);
2783 if (cmd_in == MTSETDRVBUFFER)
2784 printk(ST_DEB_MSG
2785 "%s: Setting drive buffer code to %d.\n", name,
2786 ((STp->buffer)->b_data[2] >> 4) & 7);
2787 )
2788 break;
2789 default:
2790 return (-ENOSYS);
2791 }
2792
2793 SRpnt = st_do_scsi(NULL, STp, cmd, datalen, direction,
2794 timeout, MAX_RETRIES, 1);
2795 if (!SRpnt)
2796 return (STp->buffer)->syscall_result;
2797
2798 ioctl_result = (STp->buffer)->syscall_result;
2799
2800 if (!ioctl_result) { /* SCSI command successful */
Mike Christie8b05b772005-11-08 04:06:44 -06002801 st_release_request(SRpnt);
Linus Torvalds1da177e2005-04-16 15:20:36 -07002802 SRpnt = NULL;
2803 STps->drv_block = blkno;
2804 STps->drv_file = fileno;
2805 STps->at_sm = at_sm;
2806
2807 if (cmd_in == MTBSFM)
2808 ioctl_result = st_int_ioctl(STp, MTFSF, 1);
2809 else if (cmd_in == MTFSFM)
2810 ioctl_result = st_int_ioctl(STp, MTBSF, 1);
2811
2812 if (cmd_in == MTSETBLK || cmd_in == SET_DENS_AND_BLK) {
2813 int old_block_size = STp->block_size;
2814 STp->block_size = arg & MT_ST_BLKSIZE_MASK;
2815 if (STp->block_size != 0) {
2816 if (old_block_size == 0)
2817 normalize_buffer(STp->buffer);
2818 (STp->buffer)->buffer_blocks =
2819 (STp->buffer)->buffer_size / STp->block_size;
2820 }
2821 (STp->buffer)->buffer_bytes = (STp->buffer)->read_pointer = 0;
2822 if (cmd_in == SET_DENS_AND_BLK)
2823 STp->density = arg >> MT_ST_DENSITY_SHIFT;
2824 } else if (cmd_in == MTSETDRVBUFFER)
2825 STp->drv_buffer = (arg & 7);
2826 else if (cmd_in == MTSETDENSITY)
2827 STp->density = arg;
2828
2829 if (cmd_in == MTEOM)
2830 STps->eof = ST_EOD;
2831 else if (cmd_in == MTFSF)
2832 STps->eof = ST_FM;
2833 else if (chg_eof)
2834 STps->eof = ST_NOEOF;
2835
2836 if (cmd_in == MTWEOF)
2837 STps->rw = ST_IDLE;
2838 } else { /* SCSI command was not completely successful. Don't return
2839 from this block without releasing the SCSI command block! */
2840 struct st_cmdstatus *cmdstatp = &STp->buffer->cmdstat;
2841
2842 if (cmdstatp->flags & SENSE_EOM) {
2843 if (cmd_in != MTBSF && cmd_in != MTBSFM &&
2844 cmd_in != MTBSR && cmd_in != MTBSS)
2845 STps->eof = ST_EOM_OK;
2846 STps->drv_block = 0;
2847 }
2848
2849 if (cmdstatp->remainder_valid)
2850 undone = (int)cmdstatp->uremainder64;
2851 else
2852 undone = 0;
2853
2854 if (cmd_in == MTWEOF &&
2855 cmdstatp->have_sense &&
Kai Makisara91614c02007-01-26 00:38:39 +02002856 (cmdstatp->flags & SENSE_EOM)) {
2857 if (cmdstatp->sense_hdr.sense_key == NO_SENSE ||
2858 cmdstatp->sense_hdr.sense_key == RECOVERED_ERROR) {
2859 ioctl_result = 0; /* EOF(s) written successfully at EOM */
2860 STps->eof = ST_NOEOF;
2861 } else { /* Writing EOF(s) failed */
2862 if (fileno >= 0)
2863 fileno -= undone;
2864 if (undone < arg)
2865 STps->eof = ST_NOEOF;
2866 }
Linus Torvalds1da177e2005-04-16 15:20:36 -07002867 STps->drv_file = fileno;
Linus Torvalds1da177e2005-04-16 15:20:36 -07002868 } else if ((cmd_in == MTFSF) || (cmd_in == MTFSFM)) {
2869 if (fileno >= 0)
2870 STps->drv_file = fileno - undone;
2871 else
2872 STps->drv_file = fileno;
2873 STps->drv_block = -1;
2874 STps->eof = ST_NOEOF;
2875 } else if ((cmd_in == MTBSF) || (cmd_in == MTBSFM)) {
2876 if (arg > 0 && undone < 0) /* Some drives get this wrong */
2877 undone = (-undone);
2878 if (STps->drv_file >= 0)
2879 STps->drv_file = fileno + undone;
2880 STps->drv_block = 0;
2881 STps->eof = ST_NOEOF;
2882 } else if (cmd_in == MTFSR) {
2883 if (cmdstatp->flags & SENSE_FMK) { /* Hit filemark */
2884 if (STps->drv_file >= 0)
2885 STps->drv_file++;
2886 STps->drv_block = 0;
2887 STps->eof = ST_FM;
2888 } else {
2889 if (blkno >= undone)
2890 STps->drv_block = blkno - undone;
2891 else
2892 STps->drv_block = (-1);
2893 STps->eof = ST_NOEOF;
2894 }
2895 } else if (cmd_in == MTBSR) {
2896 if (cmdstatp->flags & SENSE_FMK) { /* Hit filemark */
2897 STps->drv_file--;
2898 STps->drv_block = (-1);
2899 } else {
2900 if (arg > 0 && undone < 0) /* Some drives get this wrong */
2901 undone = (-undone);
2902 if (STps->drv_block >= 0)
2903 STps->drv_block = blkno + undone;
2904 }
2905 STps->eof = ST_NOEOF;
2906 } else if (cmd_in == MTEOM) {
2907 STps->drv_file = (-1);
2908 STps->drv_block = (-1);
2909 STps->eof = ST_EOD;
2910 } else if (cmd_in == MTSETBLK ||
2911 cmd_in == MTSETDENSITY ||
2912 cmd_in == MTSETDRVBUFFER ||
2913 cmd_in == SET_DENS_AND_BLK) {
2914 if (cmdstatp->sense_hdr.sense_key == ILLEGAL_REQUEST &&
2915 !(STp->use_pf & PF_TESTED)) {
2916 /* Try the other possible state of Page Format if not
2917 already tried */
2918 STp->use_pf = !STp->use_pf | PF_TESTED;
Mike Christie8b05b772005-11-08 04:06:44 -06002919 st_release_request(SRpnt);
Linus Torvalds1da177e2005-04-16 15:20:36 -07002920 SRpnt = NULL;
2921 return st_int_ioctl(STp, cmd_in, arg);
2922 }
2923 } else if (chg_eof)
2924 STps->eof = ST_NOEOF;
2925
2926 if (cmdstatp->sense_hdr.sense_key == BLANK_CHECK)
2927 STps->eof = ST_EOD;
2928
Mike Christie8b05b772005-11-08 04:06:44 -06002929 st_release_request(SRpnt);
Linus Torvalds1da177e2005-04-16 15:20:36 -07002930 SRpnt = NULL;
2931 }
2932
2933 return ioctl_result;
2934}
2935
2936
2937/* Get the tape position. If bt == 2, arg points into a kernel space mt_loc
2938 structure. */
2939
2940static int get_location(struct scsi_tape *STp, unsigned int *block, int *partition,
2941 int logical)
2942{
2943 int result;
2944 unsigned char scmd[MAX_COMMAND_SIZE];
Mike Christie8b05b772005-11-08 04:06:44 -06002945 struct st_request *SRpnt;
Linus Torvalds1da177e2005-04-16 15:20:36 -07002946 DEB( char *name = tape_name(STp); )
2947
2948 if (STp->ready != ST_READY)
2949 return (-EIO);
2950
2951 memset(scmd, 0, MAX_COMMAND_SIZE);
2952 if ((STp->device)->scsi_level < SCSI_2) {
2953 scmd[0] = QFA_REQUEST_BLOCK;
2954 scmd[4] = 3;
2955 } else {
2956 scmd[0] = READ_POSITION;
2957 if (!logical && !STp->scsi2_logical)
2958 scmd[1] = 1;
2959 }
2960 SRpnt = st_do_scsi(NULL, STp, scmd, 20, DMA_FROM_DEVICE,
James Bottomleya02488e2008-11-30 10:36:26 -06002961 STp->device->request_queue->rq_timeout,
2962 MAX_READY_RETRIES, 1);
Linus Torvalds1da177e2005-04-16 15:20:36 -07002963 if (!SRpnt)
2964 return (STp->buffer)->syscall_result;
2965
2966 if ((STp->buffer)->syscall_result != 0 ||
2967 (STp->device->scsi_level >= SCSI_2 &&
2968 ((STp->buffer)->b_data[0] & 4) != 0)) {
2969 *block = *partition = 0;
2970 DEBC(printk(ST_DEB_MSG "%s: Can't read tape position.\n", name));
2971 result = (-EIO);
2972 } else {
2973 result = 0;
2974 if ((STp->device)->scsi_level < SCSI_2) {
2975 *block = ((STp->buffer)->b_data[0] << 16)
2976 + ((STp->buffer)->b_data[1] << 8)
2977 + (STp->buffer)->b_data[2];
2978 *partition = 0;
2979 } else {
2980 *block = ((STp->buffer)->b_data[4] << 24)
2981 + ((STp->buffer)->b_data[5] << 16)
2982 + ((STp->buffer)->b_data[6] << 8)
2983 + (STp->buffer)->b_data[7];
2984 *partition = (STp->buffer)->b_data[1];
2985 if (((STp->buffer)->b_data[0] & 0x80) &&
2986 (STp->buffer)->b_data[1] == 0) /* BOP of partition 0 */
2987 STp->ps[0].drv_block = STp->ps[0].drv_file = 0;
2988 }
2989 DEBC(printk(ST_DEB_MSG "%s: Got tape pos. blk %d part %d.\n", name,
2990 *block, *partition));
2991 }
Mike Christie8b05b772005-11-08 04:06:44 -06002992 st_release_request(SRpnt);
Linus Torvalds1da177e2005-04-16 15:20:36 -07002993 SRpnt = NULL;
2994
2995 return result;
2996}
2997
2998
2999/* Set the tape block and partition. Negative partition means that only the
3000 block should be set in vendor specific way. */
3001static int set_location(struct scsi_tape *STp, unsigned int block, int partition,
3002 int logical)
3003{
3004 struct st_partstat *STps;
3005 int result, p;
3006 unsigned int blk;
3007 int timeout;
3008 unsigned char scmd[MAX_COMMAND_SIZE];
Mike Christie8b05b772005-11-08 04:06:44 -06003009 struct st_request *SRpnt;
Linus Torvalds1da177e2005-04-16 15:20:36 -07003010 DEB( char *name = tape_name(STp); )
3011
3012 if (STp->ready != ST_READY)
3013 return (-EIO);
3014 timeout = STp->long_timeout;
3015 STps = &(STp->ps[STp->partition]);
3016
3017 DEBC(printk(ST_DEB_MSG "%s: Setting block to %d and partition to %d.\n",
3018 name, block, partition));
3019 DEB(if (partition < 0)
3020 return (-EIO); )
3021
3022 /* Update the location at the partition we are leaving */
3023 if ((!STp->can_partitions && partition != 0) ||
3024 partition >= ST_NBR_PARTITIONS)
3025 return (-EINVAL);
3026 if (partition != STp->partition) {
3027 if (get_location(STp, &blk, &p, 1))
3028 STps->last_block_valid = 0;
3029 else {
3030 STps->last_block_valid = 1;
3031 STps->last_block_visited = blk;
3032 DEBC(printk(ST_DEB_MSG
3033 "%s: Visited block %d for partition %d saved.\n",
3034 name, blk, STp->partition));
3035 }
3036 }
3037
3038 memset(scmd, 0, MAX_COMMAND_SIZE);
3039 if ((STp->device)->scsi_level < SCSI_2) {
3040 scmd[0] = QFA_SEEK_BLOCK;
3041 scmd[2] = (block >> 16);
3042 scmd[3] = (block >> 8);
3043 scmd[4] = block;
3044 scmd[5] = 0;
3045 } else {
3046 scmd[0] = SEEK_10;
3047 scmd[3] = (block >> 24);
3048 scmd[4] = (block >> 16);
3049 scmd[5] = (block >> 8);
3050 scmd[6] = block;
3051 if (!logical && !STp->scsi2_logical)
3052 scmd[1] = 4;
3053 if (STp->partition != partition) {
3054 scmd[1] |= 2;
3055 scmd[8] = partition;
3056 DEBC(printk(ST_DEB_MSG
3057 "%s: Trying to change partition from %d to %d\n",
3058 name, STp->partition, partition));
3059 }
3060 }
3061 if (STp->immediate) {
3062 scmd[1] |= 1; /* Don't wait for completion */
James Bottomleya02488e2008-11-30 10:36:26 -06003063 timeout = STp->device->request_queue->rq_timeout;
Linus Torvalds1da177e2005-04-16 15:20:36 -07003064 }
3065
3066 SRpnt = st_do_scsi(NULL, STp, scmd, 0, DMA_NONE,
3067 timeout, MAX_READY_RETRIES, 1);
3068 if (!SRpnt)
3069 return (STp->buffer)->syscall_result;
3070
3071 STps->drv_block = STps->drv_file = (-1);
3072 STps->eof = ST_NOEOF;
3073 if ((STp->buffer)->syscall_result != 0) {
3074 result = (-EIO);
3075 if (STp->can_partitions &&
3076 (STp->device)->scsi_level >= SCSI_2 &&
3077 (p = find_partition(STp)) >= 0)
3078 STp->partition = p;
3079 } else {
3080 if (STp->can_partitions) {
3081 STp->partition = partition;
3082 STps = &(STp->ps[partition]);
3083 if (!STps->last_block_valid ||
3084 STps->last_block_visited != block) {
3085 STps->at_sm = 0;
3086 STps->rw = ST_IDLE;
3087 }
3088 } else
3089 STps->at_sm = 0;
3090 if (block == 0)
3091 STps->drv_block = STps->drv_file = 0;
3092 result = 0;
3093 }
3094
Mike Christie8b05b772005-11-08 04:06:44 -06003095 st_release_request(SRpnt);
Linus Torvalds1da177e2005-04-16 15:20:36 -07003096 SRpnt = NULL;
3097
3098 return result;
3099}
3100
3101
3102/* Find the current partition number for the drive status. Called from open and
3103 returns either partition number of negative error code. */
3104static int find_partition(struct scsi_tape *STp)
3105{
3106 int i, partition;
3107 unsigned int block;
3108
3109 if ((i = get_location(STp, &block, &partition, 1)) < 0)
3110 return i;
3111 if (partition >= ST_NBR_PARTITIONS)
3112 return (-EIO);
3113 return partition;
3114}
3115
3116
3117/* Change the partition if necessary */
3118static int switch_partition(struct scsi_tape *STp)
3119{
3120 struct st_partstat *STps;
3121
3122 if (STp->partition == STp->new_partition)
3123 return 0;
3124 STps = &(STp->ps[STp->new_partition]);
3125 if (!STps->last_block_valid)
3126 STps->last_block_visited = 0;
3127 return set_location(STp, STps->last_block_visited, STp->new_partition, 1);
3128}
3129
3130/* Functions for reading and writing the medium partition mode page. */
3131
3132#define PART_PAGE 0x11
3133#define PART_PAGE_FIXED_LENGTH 8
3134
3135#define PP_OFF_MAX_ADD_PARTS 2
3136#define PP_OFF_NBR_ADD_PARTS 3
3137#define PP_OFF_FLAGS 4
3138#define PP_OFF_PART_UNITS 6
3139#define PP_OFF_RESERVED 7
3140
3141#define PP_BIT_IDP 0x20
3142#define PP_MSK_PSUM_MB 0x10
3143
3144/* Get the number of partitions on the tape. As a side effect reads the
3145 mode page into the tape buffer. */
3146static int nbr_partitions(struct scsi_tape *STp)
3147{
3148 int result;
3149 DEB( char *name = tape_name(STp); )
3150
3151 if (STp->ready != ST_READY)
3152 return (-EIO);
3153
3154 result = read_mode_page(STp, PART_PAGE, 1);
3155
3156 if (result) {
3157 DEBC(printk(ST_DEB_MSG "%s: Can't read medium partition page.\n",
3158 name));
3159 result = (-EIO);
3160 } else {
3161 result = (STp->buffer)->b_data[MODE_HEADER_LENGTH +
3162 PP_OFF_NBR_ADD_PARTS] + 1;
3163 DEBC(printk(ST_DEB_MSG "%s: Number of partitions %d.\n", name, result));
3164 }
3165
3166 return result;
3167}
3168
3169
3170/* Partition the tape into two partitions if size > 0 or one partition if
3171 size == 0.
3172
3173 The block descriptors are read and written because Sony SDT-7000 does not
3174 work without this (suggestion from Michael Schaefer <Michael.Schaefer@dlr.de>).
3175
3176 My HP C1533A drive returns only one partition size field. This is used to
3177 set the size of partition 1. There is no size field for the default partition.
3178 Michael Schaefer's Sony SDT-7000 returns two descriptors and the second is
3179 used to set the size of partition 1 (this is what the SCSI-3 standard specifies).
3180 The following algorithm is used to accommodate both drives: if the number of
3181 partition size fields is greater than the maximum number of additional partitions
3182 in the mode page, the second field is used. Otherwise the first field is used.
3183
3184 For Seagate DDS drives the page length must be 8 when no partitions is defined
3185 and 10 when 1 partition is defined (information from Eric Lee Green). This is
3186 is acceptable also to some other old drives and enforced if the first partition
3187 size field is used for the first additional partition size.
3188 */
3189static int partition_tape(struct scsi_tape *STp, int size)
3190{
3191 char *name = tape_name(STp);
3192 int result;
3193 int pgo, psd_cnt, psdo;
3194 unsigned char *bp;
3195
3196 result = read_mode_page(STp, PART_PAGE, 0);
3197 if (result) {
3198 DEBC(printk(ST_DEB_MSG "%s: Can't read partition mode page.\n", name));
3199 return result;
3200 }
3201 /* The mode page is in the buffer. Let's modify it and write it. */
3202 bp = (STp->buffer)->b_data;
3203 pgo = MODE_HEADER_LENGTH + bp[MH_OFF_BDESCS_LENGTH];
3204 DEBC(printk(ST_DEB_MSG "%s: Partition page length is %d bytes.\n",
3205 name, bp[pgo + MP_OFF_PAGE_LENGTH] + 2));
3206
3207 psd_cnt = (bp[pgo + MP_OFF_PAGE_LENGTH] + 2 - PART_PAGE_FIXED_LENGTH) / 2;
3208 psdo = pgo + PART_PAGE_FIXED_LENGTH;
3209 if (psd_cnt > bp[pgo + PP_OFF_MAX_ADD_PARTS]) {
3210 bp[psdo] = bp[psdo + 1] = 0xff; /* Rest of the tape */
3211 psdo += 2;
3212 }
3213 memset(bp + psdo, 0, bp[pgo + PP_OFF_NBR_ADD_PARTS] * 2);
3214
3215 DEBC(printk("%s: psd_cnt %d, max.parts %d, nbr_parts %d\n", name,
3216 psd_cnt, bp[pgo + PP_OFF_MAX_ADD_PARTS],
3217 bp[pgo + PP_OFF_NBR_ADD_PARTS]));
3218
3219 if (size <= 0) {
3220 bp[pgo + PP_OFF_NBR_ADD_PARTS] = 0;
3221 if (psd_cnt <= bp[pgo + PP_OFF_MAX_ADD_PARTS])
3222 bp[pgo + MP_OFF_PAGE_LENGTH] = 6;
3223 DEBC(printk(ST_DEB_MSG "%s: Formatting tape with one partition.\n",
3224 name));
3225 } else {
3226 bp[psdo] = (size >> 8) & 0xff;
3227 bp[psdo + 1] = size & 0xff;
3228 bp[pgo + 3] = 1;
3229 if (bp[pgo + MP_OFF_PAGE_LENGTH] < 8)
3230 bp[pgo + MP_OFF_PAGE_LENGTH] = 8;
3231 DEBC(printk(ST_DEB_MSG
3232 "%s: Formatting tape with two partitions (1 = %d MB).\n",
3233 name, size));
3234 }
3235 bp[pgo + PP_OFF_PART_UNITS] = 0;
3236 bp[pgo + PP_OFF_RESERVED] = 0;
3237 bp[pgo + PP_OFF_FLAGS] = PP_BIT_IDP | PP_MSK_PSUM_MB;
3238
3239 result = write_mode_page(STp, PART_PAGE, 1);
3240 if (result) {
3241 printk(KERN_INFO "%s: Partitioning of tape failed.\n", name);
3242 result = (-EIO);
3243 }
3244
3245 return result;
3246}
3247
3248
3249
3250/* The ioctl command */
Kai Makisarafd66c1b2008-01-17 22:45:22 +02003251static long st_ioctl(struct file *file, unsigned int cmd_in, unsigned long arg)
Linus Torvalds1da177e2005-04-16 15:20:36 -07003252{
3253 int i, cmd_nr, cmd_type, bt;
3254 int retval = 0;
3255 unsigned int blk;
3256 struct scsi_tape *STp = file->private_data;
3257 struct st_modedef *STm;
3258 struct st_partstat *STps;
3259 char *name = tape_name(STp);
3260 void __user *p = (void __user *)arg;
3261
Matthias Kaehlcke28f85002007-07-29 23:38:15 +02003262 if (mutex_lock_interruptible(&STp->lock))
Linus Torvalds1da177e2005-04-16 15:20:36 -07003263 return -ERESTARTSYS;
3264
3265 DEB(
3266 if (debugging && !STp->in_use) {
3267 printk(ST_DEB_MSG "%s: Incorrect device.\n", name);
3268 retval = (-EIO);
3269 goto out;
3270 } ) /* end DEB */
3271
3272 STm = &(STp->modes[STp->current_mode]);
3273 STps = &(STp->ps[STp->partition]);
3274
3275 /*
3276 * If we are in the middle of error recovery, don't let anyone
3277 * else try and use this device. Also, if error recovery fails, it
3278 * may try and take the device offline, in which case all further
3279 * access to the device is prohibited.
3280 */
Al Viro83ff6fe2008-03-02 08:15:49 -05003281 retval = scsi_nonblockable_ioctl(STp->device, cmd_in, p,
3282 file->f_flags & O_NDELAY);
Linus Torvalds1da177e2005-04-16 15:20:36 -07003283 if (!scsi_block_when_processing_errors(STp->device) || retval != -ENODEV)
3284 goto out;
3285 retval = 0;
3286
3287 cmd_type = _IOC_TYPE(cmd_in);
3288 cmd_nr = _IOC_NR(cmd_in);
3289
3290 if (cmd_type == _IOC_TYPE(MTIOCTOP) && cmd_nr == _IOC_NR(MTIOCTOP)) {
3291 struct mtop mtc;
3292
3293 if (_IOC_SIZE(cmd_in) != sizeof(mtc)) {
3294 retval = (-EINVAL);
3295 goto out;
3296 }
3297
3298 i = copy_from_user(&mtc, p, sizeof(struct mtop));
3299 if (i) {
3300 retval = (-EFAULT);
3301 goto out;
3302 }
3303
3304 if (mtc.mt_op == MTSETDRVBUFFER && !capable(CAP_SYS_ADMIN)) {
3305 printk(KERN_WARNING
3306 "%s: MTSETDRVBUFFER only allowed for root.\n", name);
3307 retval = (-EPERM);
3308 goto out;
3309 }
3310 if (!STm->defined &&
3311 (mtc.mt_op != MTSETDRVBUFFER &&
3312 (mtc.mt_count & MT_ST_OPTIONS) == 0)) {
3313 retval = (-ENXIO);
3314 goto out;
3315 }
3316
3317 if (!STp->pos_unknown) {
3318
3319 if (STps->eof == ST_FM_HIT) {
3320 if (mtc.mt_op == MTFSF || mtc.mt_op == MTFSFM ||
3321 mtc.mt_op == MTEOM) {
3322 mtc.mt_count -= 1;
3323 if (STps->drv_file >= 0)
3324 STps->drv_file += 1;
3325 } else if (mtc.mt_op == MTBSF || mtc.mt_op == MTBSFM) {
3326 mtc.mt_count += 1;
3327 if (STps->drv_file >= 0)
3328 STps->drv_file += 1;
3329 }
3330 }
3331
3332 if (mtc.mt_op == MTSEEK) {
3333 /* Old position must be restored if partition will be
3334 changed */
3335 i = !STp->can_partitions ||
3336 (STp->new_partition != STp->partition);
3337 } else {
3338 i = mtc.mt_op == MTREW || mtc.mt_op == MTOFFL ||
3339 mtc.mt_op == MTRETEN || mtc.mt_op == MTEOM ||
3340 mtc.mt_op == MTLOCK || mtc.mt_op == MTLOAD ||
3341 mtc.mt_op == MTFSF || mtc.mt_op == MTFSFM ||
3342 mtc.mt_op == MTBSF || mtc.mt_op == MTBSFM ||
3343 mtc.mt_op == MTCOMPRESSION;
3344 }
3345 i = flush_buffer(STp, i);
3346 if (i < 0) {
3347 retval = i;
3348 goto out;
3349 }
3350 if (STps->rw == ST_WRITING &&
3351 (mtc.mt_op == MTREW || mtc.mt_op == MTOFFL ||
3352 mtc.mt_op == MTSEEK ||
3353 mtc.mt_op == MTBSF || mtc.mt_op == MTBSFM)) {
3354 i = st_int_ioctl(STp, MTWEOF, 1);
3355 if (i < 0) {
3356 retval = i;
3357 goto out;
3358 }
3359 if (mtc.mt_op == MTBSF || mtc.mt_op == MTBSFM)
3360 mtc.mt_count++;
3361 STps->rw = ST_IDLE;
3362 }
3363
3364 } else {
3365 /*
3366 * If there was a bus reset, block further access
3367 * to this device. If the user wants to rewind the tape,
3368 * then reset the flag and allow access again.
3369 */
3370 if (mtc.mt_op != MTREW &&
3371 mtc.mt_op != MTOFFL &&
3372 mtc.mt_op != MTRETEN &&
3373 mtc.mt_op != MTERASE &&
3374 mtc.mt_op != MTSEEK &&
3375 mtc.mt_op != MTEOM) {
3376 retval = (-EIO);
3377 goto out;
3378 }
3379 reset_state(STp);
3380 /* remove this when the midlevel properly clears was_reset */
3381 STp->device->was_reset = 0;
3382 }
3383
3384 if (mtc.mt_op != MTNOP && mtc.mt_op != MTSETBLK &&
3385 mtc.mt_op != MTSETDENSITY && mtc.mt_op != MTWSM &&
3386 mtc.mt_op != MTSETDRVBUFFER && mtc.mt_op != MTSETPART)
3387 STps->rw = ST_IDLE; /* Prevent automatic WEOF and fsf */
3388
3389 if (mtc.mt_op == MTOFFL && STp->door_locked != ST_UNLOCKED)
3390 do_door_lock(STp, 0); /* Ignore result! */
3391
3392 if (mtc.mt_op == MTSETDRVBUFFER &&
3393 (mtc.mt_count & MT_ST_OPTIONS) != 0) {
3394 retval = st_set_options(STp, mtc.mt_count);
3395 goto out;
3396 }
3397
3398 if (mtc.mt_op == MTSETPART) {
3399 if (!STp->can_partitions ||
3400 mtc.mt_count < 0 || mtc.mt_count >= ST_NBR_PARTITIONS) {
3401 retval = (-EINVAL);
3402 goto out;
3403 }
3404 if (mtc.mt_count >= STp->nbr_partitions &&
3405 (STp->nbr_partitions = nbr_partitions(STp)) < 0) {
3406 retval = (-EIO);
3407 goto out;
3408 }
3409 if (mtc.mt_count >= STp->nbr_partitions) {
3410 retval = (-EINVAL);
3411 goto out;
3412 }
3413 STp->new_partition = mtc.mt_count;
3414 retval = 0;
3415 goto out;
3416 }
3417
3418 if (mtc.mt_op == MTMKPART) {
3419 if (!STp->can_partitions) {
3420 retval = (-EINVAL);
3421 goto out;
3422 }
3423 if ((i = st_int_ioctl(STp, MTREW, 0)) < 0 ||
3424 (i = partition_tape(STp, mtc.mt_count)) < 0) {
3425 retval = i;
3426 goto out;
3427 }
3428 for (i = 0; i < ST_NBR_PARTITIONS; i++) {
3429 STp->ps[i].rw = ST_IDLE;
3430 STp->ps[i].at_sm = 0;
3431 STp->ps[i].last_block_valid = 0;
3432 }
3433 STp->partition = STp->new_partition = 0;
3434 STp->nbr_partitions = 1; /* Bad guess ?-) */
3435 STps->drv_block = STps->drv_file = 0;
3436 retval = 0;
3437 goto out;
3438 }
3439
3440 if (mtc.mt_op == MTSEEK) {
3441 i = set_location(STp, mtc.mt_count, STp->new_partition, 0);
3442 if (!STp->can_partitions)
3443 STp->ps[0].rw = ST_IDLE;
3444 retval = i;
3445 goto out;
3446 }
3447
3448 if (mtc.mt_op == MTUNLOAD || mtc.mt_op == MTOFFL) {
3449 retval = do_load_unload(STp, file, 0);
3450 goto out;
3451 }
3452
3453 if (mtc.mt_op == MTLOAD) {
3454 retval = do_load_unload(STp, file, max(1, mtc.mt_count));
3455 goto out;
3456 }
3457
3458 if (mtc.mt_op == MTLOCK || mtc.mt_op == MTUNLOCK) {
3459 retval = do_door_lock(STp, (mtc.mt_op == MTLOCK));
3460 goto out;
3461 }
3462
3463 if (STp->can_partitions && STp->ready == ST_READY &&
3464 (i = switch_partition(STp)) < 0) {
3465 retval = i;
3466 goto out;
3467 }
3468
3469 if (mtc.mt_op == MTCOMPRESSION)
3470 retval = st_compression(STp, (mtc.mt_count & 1));
3471 else
3472 retval = st_int_ioctl(STp, mtc.mt_op, mtc.mt_count);
3473 goto out;
3474 }
3475 if (!STm->defined) {
3476 retval = (-ENXIO);
3477 goto out;
3478 }
3479
3480 if ((i = flush_buffer(STp, 0)) < 0) {
3481 retval = i;
3482 goto out;
3483 }
3484 if (STp->can_partitions &&
3485 (i = switch_partition(STp)) < 0) {
3486 retval = i;
3487 goto out;
3488 }
3489
3490 if (cmd_type == _IOC_TYPE(MTIOCGET) && cmd_nr == _IOC_NR(MTIOCGET)) {
3491 struct mtget mt_status;
3492
3493 if (_IOC_SIZE(cmd_in) != sizeof(struct mtget)) {
3494 retval = (-EINVAL);
3495 goto out;
3496 }
3497
3498 mt_status.mt_type = STp->tape_type;
3499 mt_status.mt_dsreg =
3500 ((STp->block_size << MT_ST_BLKSIZE_SHIFT) & MT_ST_BLKSIZE_MASK) |
3501 ((STp->density << MT_ST_DENSITY_SHIFT) & MT_ST_DENSITY_MASK);
3502 mt_status.mt_blkno = STps->drv_block;
3503 mt_status.mt_fileno = STps->drv_file;
3504 if (STp->block_size != 0) {
3505 if (STps->rw == ST_WRITING)
3506 mt_status.mt_blkno +=
3507 (STp->buffer)->buffer_bytes / STp->block_size;
3508 else if (STps->rw == ST_READING)
3509 mt_status.mt_blkno -=
3510 ((STp->buffer)->buffer_bytes +
3511 STp->block_size - 1) / STp->block_size;
3512 }
3513
3514 mt_status.mt_gstat = 0;
3515 if (STp->drv_write_prot)
3516 mt_status.mt_gstat |= GMT_WR_PROT(0xffffffff);
3517 if (mt_status.mt_blkno == 0) {
3518 if (mt_status.mt_fileno == 0)
3519 mt_status.mt_gstat |= GMT_BOT(0xffffffff);
3520 else
3521 mt_status.mt_gstat |= GMT_EOF(0xffffffff);
3522 }
3523 mt_status.mt_erreg = (STp->recover_reg << MT_ST_SOFTERR_SHIFT);
3524 mt_status.mt_resid = STp->partition;
3525 if (STps->eof == ST_EOM_OK || STps->eof == ST_EOM_ERROR)
3526 mt_status.mt_gstat |= GMT_EOT(0xffffffff);
3527 else if (STps->eof >= ST_EOM_OK)
3528 mt_status.mt_gstat |= GMT_EOD(0xffffffff);
3529 if (STp->density == 1)
3530 mt_status.mt_gstat |= GMT_D_800(0xffffffff);
3531 else if (STp->density == 2)
3532 mt_status.mt_gstat |= GMT_D_1600(0xffffffff);
3533 else if (STp->density == 3)
3534 mt_status.mt_gstat |= GMT_D_6250(0xffffffff);
3535 if (STp->ready == ST_READY)
3536 mt_status.mt_gstat |= GMT_ONLINE(0xffffffff);
3537 if (STp->ready == ST_NO_TAPE)
3538 mt_status.mt_gstat |= GMT_DR_OPEN(0xffffffff);
3539 if (STps->at_sm)
3540 mt_status.mt_gstat |= GMT_SM(0xffffffff);
3541 if (STm->do_async_writes ||
3542 (STm->do_buffer_writes && STp->block_size != 0) ||
3543 STp->drv_buffer != 0)
3544 mt_status.mt_gstat |= GMT_IM_REP_EN(0xffffffff);
3545 if (STp->cleaning_req)
3546 mt_status.mt_gstat |= GMT_CLN(0xffffffff);
3547
3548 i = copy_to_user(p, &mt_status, sizeof(struct mtget));
3549 if (i) {
3550 retval = (-EFAULT);
3551 goto out;
3552 }
3553
3554 STp->recover_reg = 0; /* Clear after read */
3555 retval = 0;
3556 goto out;
3557 } /* End of MTIOCGET */
3558 if (cmd_type == _IOC_TYPE(MTIOCPOS) && cmd_nr == _IOC_NR(MTIOCPOS)) {
3559 struct mtpos mt_pos;
3560 if (_IOC_SIZE(cmd_in) != sizeof(struct mtpos)) {
3561 retval = (-EINVAL);
3562 goto out;
3563 }
3564 if ((i = get_location(STp, &blk, &bt, 0)) < 0) {
3565 retval = i;
3566 goto out;
3567 }
3568 mt_pos.mt_blkno = blk;
3569 i = copy_to_user(p, &mt_pos, sizeof(struct mtpos));
3570 if (i)
3571 retval = (-EFAULT);
3572 goto out;
3573 }
Matthias Kaehlcke28f85002007-07-29 23:38:15 +02003574 mutex_unlock(&STp->lock);
Linus Torvalds1da177e2005-04-16 15:20:36 -07003575 switch (cmd_in) {
3576 case SCSI_IOCTL_GET_IDLUN:
3577 case SCSI_IOCTL_GET_BUS_NUMBER:
3578 break;
3579 default:
Kai Makisara 16c4b3e2005-05-01 18:11:55 +03003580 if ((cmd_in == SG_IO ||
3581 cmd_in == SCSI_IOCTL_SEND_COMMAND ||
3582 cmd_in == CDROM_SEND_PACKET) &&
3583 !capable(CAP_SYS_RAWIO))
Linus Torvalds1da177e2005-04-16 15:20:36 -07003584 i = -EPERM;
3585 else
Al Viro74f3c8a2007-08-27 15:38:10 -04003586 i = scsi_cmd_ioctl(STp->disk->queue, STp->disk,
3587 file->f_mode, cmd_in, p);
Linus Torvalds1da177e2005-04-16 15:20:36 -07003588 if (i != -ENOTTY)
3589 return i;
3590 break;
3591 }
Kai Makisara 16c4b3e2005-05-01 18:11:55 +03003592 retval = scsi_ioctl(STp->device, cmd_in, p);
3593 if (!retval && cmd_in == SCSI_IOCTL_STOP_UNIT) { /* unload */
3594 STp->rew_at_close = 0;
3595 STp->ready = ST_NO_TAPE;
3596 }
3597 return retval;
Linus Torvalds1da177e2005-04-16 15:20:36 -07003598
3599 out:
Matthias Kaehlcke28f85002007-07-29 23:38:15 +02003600 mutex_unlock(&STp->lock);
Linus Torvalds1da177e2005-04-16 15:20:36 -07003601 return retval;
3602}
3603
3604#ifdef CONFIG_COMPAT
3605static long st_compat_ioctl(struct file *file, unsigned int cmd, unsigned long arg)
3606{
3607 struct scsi_tape *STp = file->private_data;
3608 struct scsi_device *sdev = STp->device;
3609 int ret = -ENOIOCTLCMD;
3610 if (sdev->host->hostt->compat_ioctl) {
3611
3612 ret = sdev->host->hostt->compat_ioctl(sdev, cmd, (void __user *)arg);
3613
3614 }
3615 return ret;
3616}
3617#endif
3618
3619
3620
3621/* Try to allocate a new tape buffer. Calling function must not hold
3622 dev_arr_lock. */
3623static struct st_buffer *
3624 new_tape_buffer(int from_initialization, int need_dma, int max_sg)
3625{
Mike Christie8b05b772005-11-08 04:06:44 -06003626 int i, got = 0;
Al Viroc53033f2005-10-21 03:22:08 -04003627 gfp_t priority;
Linus Torvalds1da177e2005-04-16 15:20:36 -07003628 struct st_buffer *tb;
3629
3630 if (from_initialization)
3631 priority = GFP_ATOMIC;
3632 else
3633 priority = GFP_KERNEL;
3634
3635 i = sizeof(struct st_buffer) + (max_sg - 1) * sizeof(struct scatterlist) +
3636 max_sg * sizeof(struct st_buf_fragment);
Jes Sorensen24669f752006-01-16 10:31:18 -05003637 tb = kzalloc(i, priority);
Linus Torvalds1da177e2005-04-16 15:20:36 -07003638 if (!tb) {
3639 printk(KERN_NOTICE "st: Can't allocate new tape buffer.\n");
3640 return NULL;
3641 }
Mike Christie8b05b772005-11-08 04:06:44 -06003642 tb->frp_segs = tb->orig_frp_segs = 0;
Linus Torvalds1da177e2005-04-16 15:20:36 -07003643 tb->use_sg = max_sg;
Linus Torvalds1da177e2005-04-16 15:20:36 -07003644 tb->frp = (struct st_buf_fragment *)(&(tb->sg[0]) + max_sg);
3645
Linus Torvalds1da177e2005-04-16 15:20:36 -07003646 tb->dma = need_dma;
3647 tb->buffer_size = got;
FUJITA Tomonoricd816212007-12-15 15:51:55 +09003648 sg_init_table(tb->sg, max_sg);
Linus Torvalds1da177e2005-04-16 15:20:36 -07003649
3650 return tb;
3651}
3652
3653
3654/* Try to allocate enough space in the tape buffer */
3655static int enlarge_buffer(struct st_buffer * STbuffer, int new_size, int need_dma)
3656{
Al Viroc53033f2005-10-21 03:22:08 -04003657 int segs, nbr, max_segs, b_size, order, got;
3658 gfp_t priority;
Linus Torvalds1da177e2005-04-16 15:20:36 -07003659
3660 if (new_size <= STbuffer->buffer_size)
3661 return 1;
3662
3663 if (STbuffer->buffer_size <= PAGE_SIZE)
3664 normalize_buffer(STbuffer); /* Avoid extra segment */
3665
3666 max_segs = STbuffer->use_sg;
3667 nbr = max_segs - STbuffer->frp_segs;
3668 if (nbr <= 0)
3669 return 0;
3670
3671 priority = GFP_KERNEL | __GFP_NOWARN;
3672 if (need_dma)
3673 priority |= GFP_DMA;
Mike Christie8b05b772005-11-08 04:06:44 -06003674 for (b_size = PAGE_SIZE, order=0; order <= 6 &&
Linus Torvalds1da177e2005-04-16 15:20:36 -07003675 b_size < new_size - STbuffer->buffer_size;
3676 order++, b_size *= 2)
3677 ; /* empty */
3678
3679 for (segs = STbuffer->frp_segs, got = STbuffer->buffer_size;
3680 segs < max_segs && got < new_size;) {
3681 STbuffer->frp[segs].page = alloc_pages(priority, order);
3682 if (STbuffer->frp[segs].page == NULL) {
3683 if (new_size - got <= (max_segs - segs) * b_size / 2) {
3684 b_size /= 2; /* Large enough for the rest of the buffers */
3685 order--;
3686 continue;
3687 }
3688 DEB(STbuffer->buffer_size = got);
3689 normalize_buffer(STbuffer);
3690 return 0;
3691 }
3692 STbuffer->frp[segs].length = b_size;
3693 STbuffer->frp_segs += 1;
3694 got += b_size;
3695 STbuffer->buffer_size = got;
Kai Makisara40f6b362008-02-24 22:23:24 +02003696 if (STbuffer->cleared)
3697 memset(page_address(STbuffer->frp[segs].page), 0, b_size);
Linus Torvalds1da177e2005-04-16 15:20:36 -07003698 segs++;
3699 }
3700 STbuffer->b_data = page_address(STbuffer->frp[0].page);
3701
3702 return 1;
3703}
3704
3705
Kai Makisara40f6b362008-02-24 22:23:24 +02003706/* Make sure that no data from previous user is in the internal buffer */
3707static void clear_buffer(struct st_buffer * st_bp)
3708{
3709 int i;
3710
3711 for (i=0; i < st_bp->frp_segs; i++)
3712 memset(page_address(st_bp->frp[i].page), 0, st_bp->frp[i].length);
3713 st_bp->cleared = 1;
3714}
3715
3716
Linus Torvalds1da177e2005-04-16 15:20:36 -07003717/* Release the extra buffer */
3718static void normalize_buffer(struct st_buffer * STbuffer)
3719{
3720 int i, order;
3721
3722 for (i = STbuffer->orig_frp_segs; i < STbuffer->frp_segs; i++) {
3723 order = get_order(STbuffer->frp[i].length);
3724 __free_pages(STbuffer->frp[i].page, order);
3725 STbuffer->buffer_size -= STbuffer->frp[i].length;
3726 }
3727 STbuffer->frp_segs = STbuffer->orig_frp_segs;
3728 STbuffer->frp_sg_current = 0;
Mike Christie8b05b772005-11-08 04:06:44 -06003729 STbuffer->sg_segs = 0;
Linus Torvalds1da177e2005-04-16 15:20:36 -07003730}
3731
3732
3733/* Move data from the user buffer to the tape buffer. Returns zero (success) or
3734 negative error code. */
3735static int append_to_buffer(const char __user *ubp, struct st_buffer * st_bp, int do_count)
3736{
3737 int i, cnt, res, offset;
3738
3739 for (i = 0, offset = st_bp->buffer_bytes;
3740 i < st_bp->frp_segs && offset >= st_bp->frp[i].length; i++)
3741 offset -= st_bp->frp[i].length;
3742 if (i == st_bp->frp_segs) { /* Should never happen */
3743 printk(KERN_WARNING "st: append_to_buffer offset overflow.\n");
3744 return (-EIO);
3745 }
3746 for (; i < st_bp->frp_segs && do_count > 0; i++) {
3747 cnt = st_bp->frp[i].length - offset < do_count ?
3748 st_bp->frp[i].length - offset : do_count;
3749 res = copy_from_user(page_address(st_bp->frp[i].page) + offset, ubp, cnt);
3750 if (res)
3751 return (-EFAULT);
3752 do_count -= cnt;
3753 st_bp->buffer_bytes += cnt;
3754 ubp += cnt;
3755 offset = 0;
3756 }
3757 if (do_count) /* Should never happen */
3758 return (-EIO);
3759
3760 return 0;
3761}
3762
3763
3764/* Move data from the tape buffer to the user buffer. Returns zero (success) or
3765 negative error code. */
3766static int from_buffer(struct st_buffer * st_bp, char __user *ubp, int do_count)
3767{
3768 int i, cnt, res, offset;
3769
3770 for (i = 0, offset = st_bp->read_pointer;
3771 i < st_bp->frp_segs && offset >= st_bp->frp[i].length; i++)
3772 offset -= st_bp->frp[i].length;
3773 if (i == st_bp->frp_segs) { /* Should never happen */
3774 printk(KERN_WARNING "st: from_buffer offset overflow.\n");
3775 return (-EIO);
3776 }
3777 for (; i < st_bp->frp_segs && do_count > 0; i++) {
3778 cnt = st_bp->frp[i].length - offset < do_count ?
3779 st_bp->frp[i].length - offset : do_count;
3780 res = copy_to_user(ubp, page_address(st_bp->frp[i].page) + offset, cnt);
3781 if (res)
3782 return (-EFAULT);
3783 do_count -= cnt;
3784 st_bp->buffer_bytes -= cnt;
3785 st_bp->read_pointer += cnt;
3786 ubp += cnt;
3787 offset = 0;
3788 }
3789 if (do_count) /* Should never happen */
3790 return (-EIO);
3791
3792 return 0;
3793}
3794
3795
3796/* Move data towards start of buffer */
3797static void move_buffer_data(struct st_buffer * st_bp, int offset)
3798{
3799 int src_seg, dst_seg, src_offset = 0, dst_offset;
3800 int count, total;
3801
3802 if (offset == 0)
3803 return;
3804
3805 total=st_bp->buffer_bytes - offset;
3806 for (src_seg=0; src_seg < st_bp->frp_segs; src_seg++) {
3807 src_offset = offset;
3808 if (src_offset < st_bp->frp[src_seg].length)
3809 break;
3810 offset -= st_bp->frp[src_seg].length;
3811 }
3812
3813 st_bp->buffer_bytes = st_bp->read_pointer = total;
3814 for (dst_seg=dst_offset=0; total > 0; ) {
3815 count = min(st_bp->frp[dst_seg].length - dst_offset,
3816 st_bp->frp[src_seg].length - src_offset);
3817 memmove(page_address(st_bp->frp[dst_seg].page) + dst_offset,
3818 page_address(st_bp->frp[src_seg].page) + src_offset, count);
3819 src_offset += count;
3820 if (src_offset >= st_bp->frp[src_seg].length) {
3821 src_seg++;
3822 src_offset = 0;
3823 }
3824 dst_offset += count;
3825 if (dst_offset >= st_bp->frp[dst_seg].length) {
3826 dst_seg++;
3827 dst_offset = 0;
3828 }
3829 total -= count;
3830 }
3831}
3832
3833
3834/* Fill the s/g list up to the length required for this transfer */
3835static void buf_to_sg(struct st_buffer *STbp, unsigned int length)
3836{
3837 int i;
3838 unsigned int count;
3839 struct scatterlist *sg;
3840 struct st_buf_fragment *frp;
3841
3842 if (length == STbp->frp_sg_current)
3843 return; /* work already done */
3844
3845 sg = &(STbp->sg[0]);
3846 frp = STbp->frp;
3847 for (i=count=0; count < length; i++) {
Linus Torvalds1da177e2005-04-16 15:20:36 -07003848 if (length - count > frp[i].length)
Jens Axboe642f1492007-10-24 11:20:47 +02003849 sg_set_page(&sg[i], frp[i].page, frp[i].length, 0);
Linus Torvalds1da177e2005-04-16 15:20:36 -07003850 else
Jens Axboe642f1492007-10-24 11:20:47 +02003851 sg_set_page(&sg[i], frp[i].page, length - count, 0);
Linus Torvalds1da177e2005-04-16 15:20:36 -07003852 count += sg[i].length;
Linus Torvalds1da177e2005-04-16 15:20:36 -07003853 }
3854 STbp->sg_segs = i;
3855 STbp->frp_sg_current = length;
3856}
3857
3858
3859/* Validate the options from command line or module parameters */
3860static void validate_options(void)
3861{
3862 if (buffer_kbs > 0)
3863 st_fixed_buffer_size = buffer_kbs * ST_KILOBYTE;
3864 if (max_sg_segs >= ST_FIRST_SG)
3865 st_max_sg_segs = max_sg_segs;
3866}
3867
3868#ifndef MODULE
3869/* Set the boot options. Syntax is defined in Documenation/scsi/st.txt.
3870 */
3871static int __init st_setup(char *str)
3872{
3873 int i, len, ints[5];
3874 char *stp;
3875
3876 stp = get_options(str, ARRAY_SIZE(ints), ints);
3877
3878 if (ints[0] > 0) {
3879 for (i = 0; i < ints[0] && i < ARRAY_SIZE(parms); i++)
3880 if (parms[i].val)
3881 *parms[i].val = ints[i + 1];
3882 } else {
3883 while (stp != NULL) {
3884 for (i = 0; i < ARRAY_SIZE(parms); i++) {
3885 len = strlen(parms[i].name);
3886 if (!strncmp(stp, parms[i].name, len) &&
3887 (*(stp + len) == ':' || *(stp + len) == '=')) {
3888 if (parms[i].val)
3889 *parms[i].val =
3890 simple_strtoul(stp + len + 1, NULL, 0);
3891 else
3892 printk(KERN_WARNING "st: Obsolete parameter %s\n",
3893 parms[i].name);
3894 break;
3895 }
3896 }
Tobias Klauser6391a112006-06-08 22:23:48 -07003897 if (i >= ARRAY_SIZE(parms))
Linus Torvalds1da177e2005-04-16 15:20:36 -07003898 printk(KERN_WARNING "st: invalid parameter in '%s'\n",
3899 stp);
3900 stp = strchr(stp, ',');
3901 if (stp)
3902 stp++;
3903 }
3904 }
3905
3906 validate_options();
3907
3908 return 1;
3909}
3910
3911__setup("st=", st_setup);
3912
3913#endif
3914
Arjan van de Ven00977a52007-02-12 00:55:34 -08003915static const struct file_operations st_fops =
Linus Torvalds1da177e2005-04-16 15:20:36 -07003916{
3917 .owner = THIS_MODULE,
3918 .read = st_read,
3919 .write = st_write,
Kai Makisarafd66c1b2008-01-17 22:45:22 +02003920 .unlocked_ioctl = st_ioctl,
Linus Torvalds1da177e2005-04-16 15:20:36 -07003921#ifdef CONFIG_COMPAT
3922 .compat_ioctl = st_compat_ioctl,
3923#endif
3924 .open = st_open,
3925 .flush = st_flush,
3926 .release = st_release,
3927};
3928
3929static int st_probe(struct device *dev)
3930{
3931 struct scsi_device *SDp = to_scsi_device(dev);
3932 struct gendisk *disk = NULL;
3933 struct cdev *cdev = NULL;
3934 struct scsi_tape *tpnt = NULL;
3935 struct st_modedef *STm;
3936 struct st_partstat *STps;
3937 struct st_buffer *buffer;
3938 int i, j, mode, dev_num, error;
3939 char *stp;
Linus Torvalds1da177e2005-04-16 15:20:36 -07003940
3941 if (SDp->type != TYPE_TAPE)
3942 return -ENODEV;
3943 if ((stp = st_incompatible(SDp))) {
Jeff Garzik3bf743e2005-10-24 18:04:06 -04003944 sdev_printk(KERN_INFO, SDp, "Found incompatible tape\n");
Linus Torvalds1da177e2005-04-16 15:20:36 -07003945 printk(KERN_INFO "st: The suggested driver is %s.\n", stp);
3946 return -ENODEV;
3947 }
3948
Mike Christie8b05b772005-11-08 04:06:44 -06003949 i = min(SDp->request_queue->max_hw_segments,
3950 SDp->request_queue->max_phys_segments);
Linus Torvalds1da177e2005-04-16 15:20:36 -07003951 if (st_max_sg_segs < i)
3952 i = st_max_sg_segs;
3953 buffer = new_tape_buffer(1, (SDp->host)->unchecked_isa_dma, i);
3954 if (buffer == NULL) {
3955 printk(KERN_ERR
3956 "st: Can't allocate new tape buffer. Device not attached.\n");
3957 goto out;
3958 }
3959
3960 disk = alloc_disk(1);
3961 if (!disk) {
3962 printk(KERN_ERR "st: out of memory. Device not attached.\n");
3963 goto out_buffer_free;
3964 }
3965
3966 write_lock(&st_dev_arr_lock);
3967 if (st_nr_dev >= st_dev_max) {
3968 struct scsi_tape **tmp_da;
3969 int tmp_dev_max;
3970
3971 tmp_dev_max = max(st_nr_dev * 2, 8);
3972 if (tmp_dev_max > ST_MAX_TAPES)
3973 tmp_dev_max = ST_MAX_TAPES;
3974 if (tmp_dev_max <= st_nr_dev) {
3975 write_unlock(&st_dev_arr_lock);
3976 printk(KERN_ERR "st: Too many tape devices (max. %d).\n",
3977 ST_MAX_TAPES);
3978 goto out_put_disk;
3979 }
3980
Jes Sorensen24669f752006-01-16 10:31:18 -05003981 tmp_da = kzalloc(tmp_dev_max * sizeof(struct scsi_tape *), GFP_ATOMIC);
Linus Torvalds1da177e2005-04-16 15:20:36 -07003982 if (tmp_da == NULL) {
3983 write_unlock(&st_dev_arr_lock);
3984 printk(KERN_ERR "st: Can't extend device array.\n");
3985 goto out_put_disk;
3986 }
3987
Linus Torvalds1da177e2005-04-16 15:20:36 -07003988 if (scsi_tapes != NULL) {
3989 memcpy(tmp_da, scsi_tapes,
3990 st_dev_max * sizeof(struct scsi_tape *));
3991 kfree(scsi_tapes);
3992 }
3993 scsi_tapes = tmp_da;
3994
3995 st_dev_max = tmp_dev_max;
3996 }
3997
3998 for (i = 0; i < st_dev_max; i++)
3999 if (scsi_tapes[i] == NULL)
4000 break;
4001 if (i >= st_dev_max)
4002 panic("scsi_devices corrupt (st)");
4003
Jes Sorensen24669f752006-01-16 10:31:18 -05004004 tpnt = kzalloc(sizeof(struct scsi_tape), GFP_ATOMIC);
Linus Torvalds1da177e2005-04-16 15:20:36 -07004005 if (tpnt == NULL) {
4006 write_unlock(&st_dev_arr_lock);
4007 printk(KERN_ERR "st: Can't allocate device descriptor.\n");
4008 goto out_put_disk;
4009 }
Kai Makisaraf03a5672005-08-02 13:40:47 +03004010 kref_init(&tpnt->kref);
Linus Torvalds1da177e2005-04-16 15:20:36 -07004011 tpnt->disk = disk;
4012 sprintf(disk->disk_name, "st%d", i);
4013 disk->private_data = &tpnt->driver;
4014 disk->queue = SDp->request_queue;
4015 tpnt->driver = &st_template;
4016 scsi_tapes[i] = tpnt;
4017 dev_num = i;
4018
4019 tpnt->device = SDp;
4020 if (SDp->scsi_level <= 2)
4021 tpnt->tape_type = MT_ISSCSI1;
4022 else
4023 tpnt->tape_type = MT_ISSCSI2;
4024
4025 tpnt->buffer = buffer;
Kai Makisaraf03a5672005-08-02 13:40:47 +03004026 tpnt->buffer->last_SRpnt = NULL;
Linus Torvalds1da177e2005-04-16 15:20:36 -07004027
4028 tpnt->inited = 0;
4029 tpnt->dirty = 0;
4030 tpnt->in_use = 0;
4031 tpnt->drv_buffer = 1; /* Try buffering if no mode sense */
4032 tpnt->restr_dma = (SDp->host)->unchecked_isa_dma;
4033 tpnt->use_pf = (SDp->scsi_level >= SCSI_2);
4034 tpnt->density = 0;
4035 tpnt->do_auto_lock = ST_AUTO_LOCK;
4036 tpnt->can_bsr = (SDp->scsi_level > 2 ? 1 : ST_IN_FILE_POS); /* BSR mandatory in SCSI3 */
4037 tpnt->can_partitions = 0;
4038 tpnt->two_fm = ST_TWO_FM;
4039 tpnt->fast_mteom = ST_FAST_MTEOM;
4040 tpnt->scsi2_logical = ST_SCSI2LOGICAL;
Kai Makisara40f6b362008-02-24 22:23:24 +02004041 tpnt->sili = ST_SILI;
Linus Torvalds1da177e2005-04-16 15:20:36 -07004042 tpnt->immediate = ST_NOWAIT;
4043 tpnt->default_drvbuffer = 0xff; /* No forced buffering */
4044 tpnt->partition = 0;
4045 tpnt->new_partition = 0;
4046 tpnt->nbr_partitions = 0;
James Bottomleya02488e2008-11-30 10:36:26 -06004047 blk_queue_rq_timeout(tpnt->device->request_queue, ST_TIMEOUT);
Linus Torvalds1da177e2005-04-16 15:20:36 -07004048 tpnt->long_timeout = ST_LONG_TIMEOUT;
4049 tpnt->try_dio = try_direct_io && !SDp->host->unchecked_isa_dma;
4050
Linus Torvalds1da177e2005-04-16 15:20:36 -07004051 for (i = 0; i < ST_NBR_MODES; i++) {
4052 STm = &(tpnt->modes[i]);
4053 STm->defined = 0;
4054 STm->sysv = ST_SYSV;
4055 STm->defaults_for_writes = 0;
4056 STm->do_async_writes = ST_ASYNC_WRITES;
4057 STm->do_buffer_writes = ST_BUFFER_WRITES;
4058 STm->do_read_ahead = ST_READ_AHEAD;
4059 STm->default_compression = ST_DONT_TOUCH;
4060 STm->default_blksize = (-1); /* No forced size */
4061 STm->default_density = (-1); /* No forced density */
4062 }
4063
4064 for (i = 0; i < ST_NBR_PARTITIONS; i++) {
4065 STps = &(tpnt->ps[i]);
4066 STps->rw = ST_IDLE;
4067 STps->eof = ST_NOEOF;
4068 STps->at_sm = 0;
4069 STps->last_block_valid = 0;
4070 STps->drv_block = (-1);
4071 STps->drv_file = (-1);
4072 }
4073
4074 tpnt->current_mode = 0;
4075 tpnt->modes[0].defined = 1;
4076
4077 tpnt->density_changed = tpnt->compression_changed =
4078 tpnt->blksize_changed = 0;
Matthias Kaehlcke28f85002007-07-29 23:38:15 +02004079 mutex_init(&tpnt->lock);
Linus Torvalds1da177e2005-04-16 15:20:36 -07004080
4081 st_nr_dev++;
4082 write_unlock(&st_dev_arr_lock);
4083
4084 for (mode = 0; mode < ST_NBR_MODES; ++mode) {
4085 STm = &(tpnt->modes[mode]);
4086 for (j=0; j < 2; j++) {
4087 cdev = cdev_alloc();
4088 if (!cdev) {
4089 printk(KERN_ERR
4090 "st%d: out of memory. Device not attached.\n",
4091 dev_num);
4092 goto out_free_tape;
4093 }
4094 cdev->owner = THIS_MODULE;
4095 cdev->ops = &st_fops;
4096
4097 error = cdev_add(cdev,
4098 MKDEV(SCSI_TAPE_MAJOR, TAPE_MINOR(dev_num, mode, j)),
4099 1);
4100 if (error) {
4101 printk(KERN_ERR "st%d: Can't add %s-rewind mode %d\n",
4102 dev_num, j ? "non" : "auto", mode);
4103 printk(KERN_ERR "st%d: Device not attached.\n", dev_num);
4104 goto out_free_tape;
4105 }
4106 STm->cdevs[j] = cdev;
4107
4108 }
Jeff Garzik13026a62006-10-04 06:00:38 -04004109 error = do_create_class_files(tpnt, dev_num, mode);
4110 if (error)
4111 goto out_free_tape;
Linus Torvalds1da177e2005-04-16 15:20:36 -07004112 }
4113
Kai Makisara42252852006-11-07 21:56:38 +02004114 sdev_printk(KERN_NOTICE, SDp,
Rene Herman8b1ea242006-05-20 15:00:22 -07004115 "Attached scsi tape %s\n", tape_name(tpnt));
Kai Makisara42252852006-11-07 21:56:38 +02004116 sdev_printk(KERN_INFO, SDp, "%s: try direct i/o: %s (alignment %d B)\n",
4117 tape_name(tpnt), tpnt->try_dio ? "yes" : "no",
4118 queue_dma_alignment(SDp->request_queue) + 1);
Linus Torvalds1da177e2005-04-16 15:20:36 -07004119
4120 return 0;
4121
4122out_free_tape:
4123 for (mode=0; mode < ST_NBR_MODES; mode++) {
4124 STm = &(tpnt->modes[mode]);
4125 sysfs_remove_link(&tpnt->device->sdev_gendev.kobj,
4126 "tape");
4127 for (j=0; j < 2; j++) {
4128 if (STm->cdevs[j]) {
4129 if (cdev == STm->cdevs[j])
4130 cdev = NULL;
Tony Jonesee959b02008-02-22 00:13:36 +01004131 device_destroy(st_sysfs_class,
4132 MKDEV(SCSI_TAPE_MAJOR,
4133 TAPE_MINOR(i, mode, j)));
Linus Torvalds1da177e2005-04-16 15:20:36 -07004134 cdev_del(STm->cdevs[j]);
4135 }
4136 }
4137 }
4138 if (cdev)
4139 cdev_del(cdev);
4140 write_lock(&st_dev_arr_lock);
4141 scsi_tapes[dev_num] = NULL;
4142 st_nr_dev--;
4143 write_unlock(&st_dev_arr_lock);
4144out_put_disk:
4145 put_disk(disk);
Jesper Juhlc9475cb2005-11-07 01:01:26 -08004146 kfree(tpnt);
Linus Torvalds1da177e2005-04-16 15:20:36 -07004147out_buffer_free:
4148 kfree(buffer);
4149out:
4150 return -ENODEV;
4151};
4152
4153
4154static int st_remove(struct device *dev)
4155{
4156 struct scsi_device *SDp = to_scsi_device(dev);
4157 struct scsi_tape *tpnt;
4158 int i, j, mode;
4159
4160 write_lock(&st_dev_arr_lock);
4161 for (i = 0; i < st_dev_max; i++) {
4162 tpnt = scsi_tapes[i];
4163 if (tpnt != NULL && tpnt->device == SDp) {
4164 scsi_tapes[i] = NULL;
4165 st_nr_dev--;
4166 write_unlock(&st_dev_arr_lock);
Linus Torvalds1da177e2005-04-16 15:20:36 -07004167 sysfs_remove_link(&tpnt->device->sdev_gendev.kobj,
4168 "tape");
4169 for (mode = 0; mode < ST_NBR_MODES; ++mode) {
Linus Torvalds1da177e2005-04-16 15:20:36 -07004170 for (j=0; j < 2; j++) {
Tony Jonesee959b02008-02-22 00:13:36 +01004171 device_destroy(st_sysfs_class,
4172 MKDEV(SCSI_TAPE_MAJOR,
4173 TAPE_MINOR(i, mode, j)));
Linus Torvalds1da177e2005-04-16 15:20:36 -07004174 cdev_del(tpnt->modes[mode].cdevs[j]);
4175 tpnt->modes[mode].cdevs[j] = NULL;
4176 }
4177 }
Linus Torvalds1da177e2005-04-16 15:20:36 -07004178
Arjan van de Ven0b950672006-01-11 13:16:10 +01004179 mutex_lock(&st_ref_mutex);
Kai Makisaraf03a5672005-08-02 13:40:47 +03004180 kref_put(&tpnt->kref, scsi_tape_release);
Arjan van de Ven0b950672006-01-11 13:16:10 +01004181 mutex_unlock(&st_ref_mutex);
Linus Torvalds1da177e2005-04-16 15:20:36 -07004182 return 0;
4183 }
4184 }
4185
4186 write_unlock(&st_dev_arr_lock);
4187 return 0;
4188}
4189
Kai Makisaraf03a5672005-08-02 13:40:47 +03004190/**
4191 * scsi_tape_release - Called to free the Scsi_Tape structure
4192 * @kref: pointer to embedded kref
4193 *
Arjan van de Ven0b950672006-01-11 13:16:10 +01004194 * st_ref_mutex must be held entering this routine. Because it is
Kai Makisaraf03a5672005-08-02 13:40:47 +03004195 * called on last put, you should always use the scsi_tape_get()
4196 * scsi_tape_put() helpers which manipulate the semaphore directly
4197 * and never do a direct kref_put().
4198 **/
4199static void scsi_tape_release(struct kref *kref)
4200{
4201 struct scsi_tape *tpnt = to_scsi_tape(kref);
4202 struct gendisk *disk = tpnt->disk;
4203
4204 tpnt->device = NULL;
4205
4206 if (tpnt->buffer) {
4207 tpnt->buffer->orig_frp_segs = 0;
4208 normalize_buffer(tpnt->buffer);
4209 kfree(tpnt->buffer);
4210 }
4211
4212 disk->private_data = NULL;
4213 put_disk(disk);
4214 kfree(tpnt);
4215 return;
4216}
4217
Linus Torvalds1da177e2005-04-16 15:20:36 -07004218static int __init init_st(void)
4219{
Jeff Garzik13026a62006-10-04 06:00:38 -04004220 int err;
4221
Linus Torvalds1da177e2005-04-16 15:20:36 -07004222 validate_options();
4223
Jeff Garzik13026a62006-10-04 06:00:38 -04004224 printk(KERN_INFO "st: Version %s, fixed bufsize %d, s/g segs %d\n",
Linus Torvalds1da177e2005-04-16 15:20:36 -07004225 verstr, st_fixed_buffer_size, st_max_sg_segs);
4226
gregkh@suse.ded2538782005-03-23 09:55:22 -08004227 st_sysfs_class = class_create(THIS_MODULE, "scsi_tape");
Linus Torvalds1da177e2005-04-16 15:20:36 -07004228 if (IS_ERR(st_sysfs_class)) {
Linus Torvalds1da177e2005-04-16 15:20:36 -07004229 printk(KERN_ERR "Unable create sysfs class for SCSI tapes\n");
Jeff Garzik13026a62006-10-04 06:00:38 -04004230 return PTR_ERR(st_sysfs_class);
Linus Torvalds1da177e2005-04-16 15:20:36 -07004231 }
4232
Jeff Garzik13026a62006-10-04 06:00:38 -04004233 err = register_chrdev_region(MKDEV(SCSI_TAPE_MAJOR, 0),
4234 ST_MAX_TAPE_ENTRIES, "st");
4235 if (err) {
4236 printk(KERN_ERR "Unable to get major %d for SCSI tapes\n",
4237 SCSI_TAPE_MAJOR);
4238 goto err_class;
Linus Torvalds1da177e2005-04-16 15:20:36 -07004239 }
Jeff Garzik13026a62006-10-04 06:00:38 -04004240
4241 err = scsi_register_driver(&st_template.gendrv);
4242 if (err)
4243 goto err_chrdev;
4244
Robert P. J. Day405ae7d2007-02-17 19:13:42 +01004245 err = do_create_sysfs_files();
Jeff Garzik13026a62006-10-04 06:00:38 -04004246 if (err)
4247 goto err_scsidrv;
4248
4249 return 0;
4250
4251err_scsidrv:
4252 scsi_unregister_driver(&st_template.gendrv);
4253err_chrdev:
4254 unregister_chrdev_region(MKDEV(SCSI_TAPE_MAJOR, 0),
4255 ST_MAX_TAPE_ENTRIES);
4256err_class:
Kai Makisarac2c96f42005-08-02 12:21:51 +03004257 class_destroy(st_sysfs_class);
Jeff Garzik13026a62006-10-04 06:00:38 -04004258 return err;
Linus Torvalds1da177e2005-04-16 15:20:36 -07004259}
4260
4261static void __exit exit_st(void)
4262{
Robert P. J. Day405ae7d2007-02-17 19:13:42 +01004263 do_remove_sysfs_files();
Linus Torvalds1da177e2005-04-16 15:20:36 -07004264 scsi_unregister_driver(&st_template.gendrv);
4265 unregister_chrdev_region(MKDEV(SCSI_TAPE_MAJOR, 0),
4266 ST_MAX_TAPE_ENTRIES);
Kai Makisarac2c96f42005-08-02 12:21:51 +03004267 class_destroy(st_sysfs_class);
Linus Torvalds1da177e2005-04-16 15:20:36 -07004268 kfree(scsi_tapes);
4269 printk(KERN_INFO "st: Unloaded.\n");
4270}
4271
4272module_init(init_st);
4273module_exit(exit_st);
4274
4275
4276/* The sysfs driver interface. Read-only at the moment */
4277static ssize_t st_try_direct_io_show(struct device_driver *ddp, char *buf)
4278{
4279 return snprintf(buf, PAGE_SIZE, "%d\n", try_direct_io);
4280}
4281static DRIVER_ATTR(try_direct_io, S_IRUGO, st_try_direct_io_show, NULL);
4282
4283static ssize_t st_fixed_buffer_size_show(struct device_driver *ddp, char *buf)
4284{
4285 return snprintf(buf, PAGE_SIZE, "%d\n", st_fixed_buffer_size);
4286}
4287static DRIVER_ATTR(fixed_buffer_size, S_IRUGO, st_fixed_buffer_size_show, NULL);
4288
4289static ssize_t st_max_sg_segs_show(struct device_driver *ddp, char *buf)
4290{
4291 return snprintf(buf, PAGE_SIZE, "%d\n", st_max_sg_segs);
4292}
4293static DRIVER_ATTR(max_sg_segs, S_IRUGO, st_max_sg_segs_show, NULL);
4294
4295static ssize_t st_version_show(struct device_driver *ddd, char *buf)
4296{
4297 return snprintf(buf, PAGE_SIZE, "[%s]\n", verstr);
4298}
4299static DRIVER_ATTR(version, S_IRUGO, st_version_show, NULL);
4300
Robert P. J. Day405ae7d2007-02-17 19:13:42 +01004301static int do_create_sysfs_files(void)
Linus Torvalds1da177e2005-04-16 15:20:36 -07004302{
Robert P. J. Day405ae7d2007-02-17 19:13:42 +01004303 struct device_driver *sysfs = &st_template.gendrv;
Jeff Garzik13026a62006-10-04 06:00:38 -04004304 int err;
Linus Torvalds1da177e2005-04-16 15:20:36 -07004305
Robert P. J. Day405ae7d2007-02-17 19:13:42 +01004306 err = driver_create_file(sysfs, &driver_attr_try_direct_io);
Jeff Garzik13026a62006-10-04 06:00:38 -04004307 if (err)
4308 return err;
Robert P. J. Day405ae7d2007-02-17 19:13:42 +01004309 err = driver_create_file(sysfs, &driver_attr_fixed_buffer_size);
Jeff Garzik13026a62006-10-04 06:00:38 -04004310 if (err)
4311 goto err_try_direct_io;
Robert P. J. Day405ae7d2007-02-17 19:13:42 +01004312 err = driver_create_file(sysfs, &driver_attr_max_sg_segs);
Jeff Garzik13026a62006-10-04 06:00:38 -04004313 if (err)
4314 goto err_attr_fixed_buf;
Robert P. J. Day405ae7d2007-02-17 19:13:42 +01004315 err = driver_create_file(sysfs, &driver_attr_version);
Jeff Garzik13026a62006-10-04 06:00:38 -04004316 if (err)
4317 goto err_attr_max_sg;
4318
4319 return 0;
4320
4321err_attr_max_sg:
Robert P. J. Day405ae7d2007-02-17 19:13:42 +01004322 driver_remove_file(sysfs, &driver_attr_max_sg_segs);
Jeff Garzik13026a62006-10-04 06:00:38 -04004323err_attr_fixed_buf:
Robert P. J. Day405ae7d2007-02-17 19:13:42 +01004324 driver_remove_file(sysfs, &driver_attr_fixed_buffer_size);
Jeff Garzik13026a62006-10-04 06:00:38 -04004325err_try_direct_io:
Robert P. J. Day405ae7d2007-02-17 19:13:42 +01004326 driver_remove_file(sysfs, &driver_attr_try_direct_io);
Jeff Garzik13026a62006-10-04 06:00:38 -04004327 return err;
Linus Torvalds1da177e2005-04-16 15:20:36 -07004328}
4329
Robert P. J. Day405ae7d2007-02-17 19:13:42 +01004330static void do_remove_sysfs_files(void)
Linus Torvalds1da177e2005-04-16 15:20:36 -07004331{
Robert P. J. Day405ae7d2007-02-17 19:13:42 +01004332 struct device_driver *sysfs = &st_template.gendrv;
Linus Torvalds1da177e2005-04-16 15:20:36 -07004333
Robert P. J. Day405ae7d2007-02-17 19:13:42 +01004334 driver_remove_file(sysfs, &driver_attr_version);
4335 driver_remove_file(sysfs, &driver_attr_max_sg_segs);
4336 driver_remove_file(sysfs, &driver_attr_fixed_buffer_size);
4337 driver_remove_file(sysfs, &driver_attr_try_direct_io);
Linus Torvalds1da177e2005-04-16 15:20:36 -07004338}
4339
4340
4341/* The sysfs simple class interface */
Tony Jonesee959b02008-02-22 00:13:36 +01004342static ssize_t
4343st_defined_show(struct device *dev, struct device_attribute *attr, char *buf)
Linus Torvalds1da177e2005-04-16 15:20:36 -07004344{
James Bottomley7d15d6a2008-03-14 14:12:43 -07004345 struct st_modedef *STm = dev_get_drvdata(dev);
Linus Torvalds1da177e2005-04-16 15:20:36 -07004346 ssize_t l = 0;
4347
4348 l = snprintf(buf, PAGE_SIZE, "%d\n", STm->defined);
4349 return l;
4350}
4351
Tony Jonesee959b02008-02-22 00:13:36 +01004352DEVICE_ATTR(defined, S_IRUGO, st_defined_show, NULL);
Linus Torvalds1da177e2005-04-16 15:20:36 -07004353
Tony Jonesee959b02008-02-22 00:13:36 +01004354static ssize_t
4355st_defblk_show(struct device *dev, struct device_attribute *attr, char *buf)
Linus Torvalds1da177e2005-04-16 15:20:36 -07004356{
James Bottomley7d15d6a2008-03-14 14:12:43 -07004357 struct st_modedef *STm = dev_get_drvdata(dev);
Linus Torvalds1da177e2005-04-16 15:20:36 -07004358 ssize_t l = 0;
4359
4360 l = snprintf(buf, PAGE_SIZE, "%d\n", STm->default_blksize);
4361 return l;
4362}
4363
Tony Jonesee959b02008-02-22 00:13:36 +01004364DEVICE_ATTR(default_blksize, S_IRUGO, st_defblk_show, NULL);
Linus Torvalds1da177e2005-04-16 15:20:36 -07004365
Tony Jonesee959b02008-02-22 00:13:36 +01004366static ssize_t
4367st_defdensity_show(struct device *dev, struct device_attribute *attr, char *buf)
Linus Torvalds1da177e2005-04-16 15:20:36 -07004368{
James Bottomley7d15d6a2008-03-14 14:12:43 -07004369 struct st_modedef *STm = dev_get_drvdata(dev);
Linus Torvalds1da177e2005-04-16 15:20:36 -07004370 ssize_t l = 0;
4371 char *fmt;
4372
4373 fmt = STm->default_density >= 0 ? "0x%02x\n" : "%d\n";
4374 l = snprintf(buf, PAGE_SIZE, fmt, STm->default_density);
4375 return l;
4376}
4377
Tony Jonesee959b02008-02-22 00:13:36 +01004378DEVICE_ATTR(default_density, S_IRUGO, st_defdensity_show, NULL);
Linus Torvalds1da177e2005-04-16 15:20:36 -07004379
Tony Jonesee959b02008-02-22 00:13:36 +01004380static ssize_t
4381st_defcompression_show(struct device *dev, struct device_attribute *attr,
4382 char *buf)
Linus Torvalds1da177e2005-04-16 15:20:36 -07004383{
James Bottomley7d15d6a2008-03-14 14:12:43 -07004384 struct st_modedef *STm = dev_get_drvdata(dev);
Linus Torvalds1da177e2005-04-16 15:20:36 -07004385 ssize_t l = 0;
4386
4387 l = snprintf(buf, PAGE_SIZE, "%d\n", STm->default_compression - 1);
4388 return l;
4389}
4390
Tony Jonesee959b02008-02-22 00:13:36 +01004391DEVICE_ATTR(default_compression, S_IRUGO, st_defcompression_show, NULL);
Linus Torvalds1da177e2005-04-16 15:20:36 -07004392
Tony Jonesee959b02008-02-22 00:13:36 +01004393static ssize_t
4394st_options_show(struct device *dev, struct device_attribute *attr, char *buf)
Kai Makisarab174be02008-02-24 22:29:12 +02004395{
James Bottomley7d15d6a2008-03-14 14:12:43 -07004396 struct st_modedef *STm = dev_get_drvdata(dev);
Kai Makisarab174be02008-02-24 22:29:12 +02004397 struct scsi_tape *STp;
4398 int i, j, options;
4399 ssize_t l = 0;
4400
4401 for (i=0; i < st_dev_max; i++) {
4402 for (j=0; j < ST_NBR_MODES; j++)
4403 if (&scsi_tapes[i]->modes[j] == STm)
4404 break;
4405 if (j < ST_NBR_MODES)
4406 break;
4407 }
4408 if (i == st_dev_max)
4409 return 0; /* should never happen */
4410
4411 STp = scsi_tapes[i];
4412
4413 options = STm->do_buffer_writes ? MT_ST_BUFFER_WRITES : 0;
4414 options |= STm->do_async_writes ? MT_ST_ASYNC_WRITES : 0;
4415 options |= STm->do_read_ahead ? MT_ST_READ_AHEAD : 0;
4416 DEB( options |= debugging ? MT_ST_DEBUGGING : 0 );
4417 options |= STp->two_fm ? MT_ST_TWO_FM : 0;
4418 options |= STp->fast_mteom ? MT_ST_FAST_MTEOM : 0;
4419 options |= STm->defaults_for_writes ? MT_ST_DEF_WRITES : 0;
4420 options |= STp->can_bsr ? MT_ST_CAN_BSR : 0;
4421 options |= STp->omit_blklims ? MT_ST_NO_BLKLIMS : 0;
4422 options |= STp->can_partitions ? MT_ST_CAN_PARTITIONS : 0;
4423 options |= STp->scsi2_logical ? MT_ST_SCSI2LOGICAL : 0;
4424 options |= STm->sysv ? MT_ST_SYSV : 0;
4425 options |= STp->immediate ? MT_ST_NOWAIT : 0;
4426 options |= STp->sili ? MT_ST_SILI : 0;
4427
4428 l = snprintf(buf, PAGE_SIZE, "0x%08x\n", options);
4429 return l;
4430}
4431
Tony Jonesee959b02008-02-22 00:13:36 +01004432DEVICE_ATTR(options, S_IRUGO, st_options_show, NULL);
Kai Makisarab174be02008-02-24 22:29:12 +02004433
Jeff Garzik13026a62006-10-04 06:00:38 -04004434static int do_create_class_files(struct scsi_tape *STp, int dev_num, int mode)
Linus Torvalds1da177e2005-04-16 15:20:36 -07004435{
4436 int i, rew, error;
4437 char name[10];
Tony Jonesee959b02008-02-22 00:13:36 +01004438 struct device *st_class_member;
Linus Torvalds1da177e2005-04-16 15:20:36 -07004439
Linus Torvalds1da177e2005-04-16 15:20:36 -07004440 for (rew=0; rew < 2; rew++) {
4441 /* Make sure that the minor numbers corresponding to the four
4442 first modes always get the same names */
4443 i = mode << (4 - ST_NBR_MODE_BITS);
4444 snprintf(name, 10, "%s%s%s", rew ? "n" : "",
4445 STp->disk->disk_name, st_formats[i]);
4446 st_class_member =
Greg Kroah-Hartmand73a1a62008-07-21 20:03:34 -07004447 device_create(st_sysfs_class, &STp->device->sdev_gendev,
4448 MKDEV(SCSI_TAPE_MAJOR,
4449 TAPE_MINOR(dev_num, mode, rew)),
4450 &STp->modes[mode], "%s", name);
Linus Torvalds1da177e2005-04-16 15:20:36 -07004451 if (IS_ERR(st_class_member)) {
Tony Jonesee959b02008-02-22 00:13:36 +01004452 printk(KERN_WARNING "st%d: device_create failed\n",
Linus Torvalds1da177e2005-04-16 15:20:36 -07004453 dev_num);
Jeff Garzik13026a62006-10-04 06:00:38 -04004454 error = PTR_ERR(st_class_member);
Linus Torvalds1da177e2005-04-16 15:20:36 -07004455 goto out;
4456 }
Linus Torvalds1da177e2005-04-16 15:20:36 -07004457
Tony Jonesee959b02008-02-22 00:13:36 +01004458 error = device_create_file(st_class_member,
4459 &dev_attr_defined);
Jeff Garzik13026a62006-10-04 06:00:38 -04004460 if (error) goto out;
Tony Jonesee959b02008-02-22 00:13:36 +01004461 error = device_create_file(st_class_member,
4462 &dev_attr_default_blksize);
Jeff Garzik13026a62006-10-04 06:00:38 -04004463 if (error) goto out;
Tony Jonesee959b02008-02-22 00:13:36 +01004464 error = device_create_file(st_class_member,
4465 &dev_attr_default_density);
Jeff Garzik13026a62006-10-04 06:00:38 -04004466 if (error) goto out;
Tony Jonesee959b02008-02-22 00:13:36 +01004467 error = device_create_file(st_class_member,
4468 &dev_attr_default_compression);
Jeff Garzik13026a62006-10-04 06:00:38 -04004469 if (error) goto out;
Tony Jonesee959b02008-02-22 00:13:36 +01004470 error = device_create_file(st_class_member,
4471 &dev_attr_options);
Kai Makisarab174be02008-02-24 22:29:12 +02004472 if (error) goto out;
Jeff Garzik13026a62006-10-04 06:00:38 -04004473
Linus Torvalds1da177e2005-04-16 15:20:36 -07004474 if (mode == 0 && rew == 0) {
4475 error = sysfs_create_link(&STp->device->sdev_gendev.kobj,
4476 &st_class_member->kobj,
4477 "tape");
4478 if (error) {
4479 printk(KERN_ERR
4480 "st%d: Can't create sysfs link from SCSI device.\n",
4481 dev_num);
Jeff Garzik13026a62006-10-04 06:00:38 -04004482 goto out;
Linus Torvalds1da177e2005-04-16 15:20:36 -07004483 }
4484 }
4485 }
Jeff Garzik13026a62006-10-04 06:00:38 -04004486
4487 return 0;
4488
4489out:
4490 return error;
Linus Torvalds1da177e2005-04-16 15:20:36 -07004491}
4492
Linus Torvalds1da177e2005-04-16 15:20:36 -07004493/* The following functions may be useful for a larger audience. */
4494static int sgl_map_user_pages(struct scatterlist *sgl, const unsigned int max_pages,
4495 unsigned long uaddr, size_t count, int rw)
4496{
James Bottomley07542b82005-08-31 20:27:22 -04004497 unsigned long end = (uaddr + count + PAGE_SIZE - 1) >> PAGE_SHIFT;
4498 unsigned long start = uaddr >> PAGE_SHIFT;
4499 const int nr_pages = end - start;
Linus Torvalds1da177e2005-04-16 15:20:36 -07004500 int res, i, j;
Linus Torvalds1da177e2005-04-16 15:20:36 -07004501 struct page **pages;
4502
Linus Torvalds1da177e2005-04-16 15:20:36 -07004503 /* User attempted Overflow! */
4504 if ((uaddr + count) < uaddr)
4505 return -EINVAL;
4506
4507 /* Too big */
4508 if (nr_pages > max_pages)
4509 return -ENOMEM;
4510
4511 /* Hmm? */
4512 if (count == 0)
4513 return 0;
4514
4515 if ((pages = kmalloc(max_pages * sizeof(*pages), GFP_KERNEL)) == NULL)
4516 return -ENOMEM;
4517
4518 /* Try to fault in all of the necessary pages */
4519 down_read(&current->mm->mmap_sem);
4520 /* rw==READ means read from drive, write into memory area */
4521 res = get_user_pages(
4522 current,
4523 current->mm,
4524 uaddr,
4525 nr_pages,
4526 rw == READ,
4527 0, /* don't force */
4528 pages,
4529 NULL);
4530 up_read(&current->mm->mmap_sem);
4531
4532 /* Errors and no page mapped should return here */
4533 if (res < nr_pages)
4534 goto out_unmap;
4535
4536 for (i=0; i < nr_pages; i++) {
4537 /* FIXME: flush superflous for rw==READ,
4538 * probably wrong function for rw==WRITE
4539 */
4540 flush_dcache_page(pages[i]);
4541 }
4542
4543 /* Populate the scatter/gather list */
Jens Axboe642f1492007-10-24 11:20:47 +02004544 sg_set_page(&sgl[0], pages[0], 0, uaddr & ~PAGE_MASK);
Linus Torvalds1da177e2005-04-16 15:20:36 -07004545 if (nr_pages > 1) {
4546 sgl[0].length = PAGE_SIZE - sgl[0].offset;
4547 count -= sgl[0].length;
4548 for (i=1; i < nr_pages ; i++) {
Jens Axboe642f1492007-10-24 11:20:47 +02004549 sg_set_page(&sgl[i], pages[i],
4550 count < PAGE_SIZE ? count : PAGE_SIZE, 0);;
Linus Torvalds1da177e2005-04-16 15:20:36 -07004551 count -= PAGE_SIZE;
4552 }
4553 }
4554 else {
4555 sgl[0].length = count;
4556 }
4557
4558 kfree(pages);
4559 return nr_pages;
4560
4561 out_unmap:
4562 if (res > 0) {
4563 for (j=0; j < res; j++)
4564 page_cache_release(pages[j]);
Hugh Dickins6bc733e2005-12-01 20:21:57 +00004565 res = 0;
Linus Torvalds1da177e2005-04-16 15:20:36 -07004566 }
4567 kfree(pages);
4568 return res;
4569}
4570
4571
4572/* And unmap them... */
4573static int sgl_unmap_user_pages(struct scatterlist *sgl, const unsigned int nr_pages,
4574 int dirtied)
4575{
4576 int i;
4577
4578 for (i=0; i < nr_pages; i++) {
Jens Axboe45711f12007-10-22 21:19:53 +02004579 struct page *page = sg_page(&sgl[i]);
Nick Pigginb5810032005-10-29 18:16:12 -07004580
Nick Pigginb5810032005-10-29 18:16:12 -07004581 if (dirtied)
4582 SetPageDirty(page);
Linus Torvalds1da177e2005-04-16 15:20:36 -07004583 /* FIXME: cache flush missing for rw==READ
4584 * FIXME: call the correct reference counting function
4585 */
Nick Pigginb5810032005-10-29 18:16:12 -07004586 page_cache_release(page);
Linus Torvalds1da177e2005-04-16 15:20:36 -07004587 }
4588
4589 return 0;
4590}