blob: 11341b717bbafe9c586276baa20034ce582e4a55 [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
FUJITA Tomonoriffb43492008-12-05 15:25:21 +0900536static int st_scsi_kern_execute(struct st_request *streq,
537 const unsigned char *cmd, int data_direction,
538 void *buffer, unsigned bufflen, int timeout,
539 int retries)
540{
541 struct scsi_tape *stp = streq->stp;
542 int ret, resid;
543
544 stp->buffer->cmdstat.have_sense = 0;
545 memcpy(streq->cmd, cmd, sizeof(streq->cmd));
546
547 ret = scsi_execute(stp->device, cmd, data_direction, buffer, bufflen,
548 streq->sense, timeout, retries, 0, &resid);
549 if (driver_byte(ret) & DRIVER_ERROR)
550 return -EBUSY;
551
552 stp->buffer->cmdstat.midlevel_result = streq->result = ret;
553 stp->buffer->cmdstat.residual = resid;
554 stp->buffer->syscall_result = st_chk_result(stp, streq);
555
556 return 0;
557}
Linus Torvalds1da177e2005-04-16 15:20:36 -0700558
559/* Handle the write-behind checking (waits for completion). Returns -ENOSPC if
560 write has been correct but EOM early warning reached, -EIO if write ended in
561 error or zero if write successful. Asynchronous writes are used only in
562 variable block mode. */
563static int write_behind_check(struct scsi_tape * STp)
564{
565 int retval = 0;
566 struct st_buffer *STbuffer;
567 struct st_partstat *STps;
568 struct st_cmdstatus *cmdstatp;
Mike Christie8b05b772005-11-08 04:06:44 -0600569 struct st_request *SRpnt;
Linus Torvalds1da177e2005-04-16 15:20:36 -0700570
571 STbuffer = STp->buffer;
572 if (!STbuffer->writing)
573 return 0;
574
575 DEB(
576 if (STp->write_pending)
577 STp->nbr_waits++;
578 else
579 STp->nbr_finished++;
580 ) /* end DEB */
581
582 wait_for_completion(&(STp->wait));
Kai Makisaraf03a5672005-08-02 13:40:47 +0300583 SRpnt = STbuffer->last_SRpnt;
584 STbuffer->last_SRpnt = NULL;
Mike Christie8b05b772005-11-08 04:06:44 -0600585 SRpnt->waiting = NULL;
Linus Torvalds1da177e2005-04-16 15:20:36 -0700586
Kai Makisaraf03a5672005-08-02 13:40:47 +0300587 (STp->buffer)->syscall_result = st_chk_result(STp, SRpnt);
Mike Christie8b05b772005-11-08 04:06:44 -0600588 st_release_request(SRpnt);
Linus Torvalds1da177e2005-04-16 15:20:36 -0700589
590 STbuffer->buffer_bytes -= STbuffer->writing;
591 STps = &(STp->ps[STp->partition]);
592 if (STps->drv_block >= 0) {
593 if (STp->block_size == 0)
594 STps->drv_block++;
595 else
596 STps->drv_block += STbuffer->writing / STp->block_size;
597 }
598
599 cmdstatp = &STbuffer->cmdstat;
600 if (STbuffer->syscall_result) {
601 retval = -EIO;
602 if (cmdstatp->have_sense && !cmdstatp->deferred &&
603 (cmdstatp->flags & SENSE_EOM) &&
604 (cmdstatp->sense_hdr.sense_key == NO_SENSE ||
605 cmdstatp->sense_hdr.sense_key == RECOVERED_ERROR)) {
606 /* EOM at write-behind, has all data been written? */
607 if (!cmdstatp->remainder_valid ||
608 cmdstatp->uremainder64 == 0)
609 retval = -ENOSPC;
610 }
611 if (retval == -EIO)
612 STps->drv_block = -1;
613 }
614 STbuffer->writing = 0;
615
616 DEB(if (debugging && retval)
617 printk(ST_DEB_MSG "%s: Async write error %x, return value %d.\n",
618 tape_name(STp), STbuffer->cmdstat.midlevel_result, retval);) /* end DEB */
619
620 return retval;
621}
622
623
624/* Step over EOF if it has been inadvertently crossed (ioctl not used because
625 it messes up the block number). */
626static int cross_eof(struct scsi_tape * STp, int forward)
627{
Mike Christie8b05b772005-11-08 04:06:44 -0600628 struct st_request *SRpnt;
Linus Torvalds1da177e2005-04-16 15:20:36 -0700629 unsigned char cmd[MAX_COMMAND_SIZE];
630
631 cmd[0] = SPACE;
632 cmd[1] = 0x01; /* Space FileMarks */
633 if (forward) {
634 cmd[2] = cmd[3] = 0;
635 cmd[4] = 1;
636 } else
637 cmd[2] = cmd[3] = cmd[4] = 0xff; /* -1 filemarks */
638 cmd[5] = 0;
639
640 DEBC(printk(ST_DEB_MSG "%s: Stepping over filemark %s.\n",
641 tape_name(STp), forward ? "forward" : "backward"));
642
643 SRpnt = st_do_scsi(NULL, STp, cmd, 0, DMA_NONE,
James Bottomleya02488e2008-11-30 10:36:26 -0600644 STp->device->request_queue->rq_timeout,
645 MAX_RETRIES, 1);
Linus Torvalds1da177e2005-04-16 15:20:36 -0700646 if (!SRpnt)
647 return (STp->buffer)->syscall_result;
648
Mike Christie8b05b772005-11-08 04:06:44 -0600649 st_release_request(SRpnt);
Linus Torvalds1da177e2005-04-16 15:20:36 -0700650 SRpnt = NULL;
651
652 if ((STp->buffer)->cmdstat.midlevel_result != 0)
653 printk(KERN_ERR "%s: Stepping over filemark %s failed.\n",
654 tape_name(STp), forward ? "forward" : "backward");
655
656 return (STp->buffer)->syscall_result;
657}
658
659
660/* Flush the write buffer (never need to write if variable blocksize). */
Adrian Bunk8ef8d592008-04-14 17:17:16 +0300661static int st_flush_write_buffer(struct scsi_tape * STp)
Linus Torvalds1da177e2005-04-16 15:20:36 -0700662{
Kai Makisara786231a2008-07-11 15:06:40 +0300663 int transfer, blks;
Linus Torvalds1da177e2005-04-16 15:20:36 -0700664 int result;
665 unsigned char cmd[MAX_COMMAND_SIZE];
Mike Christie8b05b772005-11-08 04:06:44 -0600666 struct st_request *SRpnt;
Linus Torvalds1da177e2005-04-16 15:20:36 -0700667 struct st_partstat *STps;
668
669 result = write_behind_check(STp);
670 if (result)
671 return result;
672
673 result = 0;
674 if (STp->dirty == 1) {
675
Kai Makisara786231a2008-07-11 15:06:40 +0300676 transfer = STp->buffer->buffer_bytes;
Linus Torvalds1da177e2005-04-16 15:20:36 -0700677 DEBC(printk(ST_DEB_MSG "%s: Flushing %d bytes.\n",
678 tape_name(STp), transfer));
679
Linus Torvalds1da177e2005-04-16 15:20:36 -0700680 memset(cmd, 0, MAX_COMMAND_SIZE);
681 cmd[0] = WRITE_6;
682 cmd[1] = 1;
683 blks = transfer / STp->block_size;
684 cmd[2] = blks >> 16;
685 cmd[3] = blks >> 8;
686 cmd[4] = blks;
687
688 SRpnt = st_do_scsi(NULL, STp, cmd, transfer, DMA_TO_DEVICE,
James Bottomleya02488e2008-11-30 10:36:26 -0600689 STp->device->request_queue->rq_timeout,
690 MAX_WRITE_RETRIES, 1);
Linus Torvalds1da177e2005-04-16 15:20:36 -0700691 if (!SRpnt)
692 return (STp->buffer)->syscall_result;
693
694 STps = &(STp->ps[STp->partition]);
695 if ((STp->buffer)->syscall_result != 0) {
696 struct st_cmdstatus *cmdstatp = &STp->buffer->cmdstat;
697
698 if (cmdstatp->have_sense && !cmdstatp->deferred &&
699 (cmdstatp->flags & SENSE_EOM) &&
700 (cmdstatp->sense_hdr.sense_key == NO_SENSE ||
701 cmdstatp->sense_hdr.sense_key == RECOVERED_ERROR) &&
702 (!cmdstatp->remainder_valid ||
703 cmdstatp->uremainder64 == 0)) { /* All written at EOM early warning */
704 STp->dirty = 0;
705 (STp->buffer)->buffer_bytes = 0;
706 if (STps->drv_block >= 0)
707 STps->drv_block += blks;
708 result = (-ENOSPC);
709 } else {
710 printk(KERN_ERR "%s: Error on flush.\n",
711 tape_name(STp));
712 STps->drv_block = (-1);
713 result = (-EIO);
714 }
715 } else {
716 if (STps->drv_block >= 0)
717 STps->drv_block += blks;
718 STp->dirty = 0;
719 (STp->buffer)->buffer_bytes = 0;
720 }
Mike Christie8b05b772005-11-08 04:06:44 -0600721 st_release_request(SRpnt);
Linus Torvalds1da177e2005-04-16 15:20:36 -0700722 SRpnt = NULL;
723 }
724 return result;
725}
726
727
728/* Flush the tape buffer. The tape will be positioned correctly unless
729 seek_next is true. */
730static int flush_buffer(struct scsi_tape *STp, int seek_next)
731{
732 int backspace, result;
733 struct st_buffer *STbuffer;
734 struct st_partstat *STps;
735
736 STbuffer = STp->buffer;
737
738 /*
739 * If there was a bus reset, block further access
740 * to this device.
741 */
742 if (STp->pos_unknown)
743 return (-EIO);
744
745 if (STp->ready != ST_READY)
746 return 0;
747 STps = &(STp->ps[STp->partition]);
748 if (STps->rw == ST_WRITING) /* Writing */
Adrian Bunk8ef8d592008-04-14 17:17:16 +0300749 return st_flush_write_buffer(STp);
Linus Torvalds1da177e2005-04-16 15:20:36 -0700750
751 if (STp->block_size == 0)
752 return 0;
753
754 backspace = ((STp->buffer)->buffer_bytes +
755 (STp->buffer)->read_pointer) / STp->block_size -
756 ((STp->buffer)->read_pointer + STp->block_size - 1) /
757 STp->block_size;
758 (STp->buffer)->buffer_bytes = 0;
759 (STp->buffer)->read_pointer = 0;
760 result = 0;
761 if (!seek_next) {
762 if (STps->eof == ST_FM_HIT) {
763 result = cross_eof(STp, 0); /* Back over the EOF hit */
764 if (!result)
765 STps->eof = ST_NOEOF;
766 else {
767 if (STps->drv_file >= 0)
768 STps->drv_file++;
769 STps->drv_block = 0;
770 }
771 }
772 if (!result && backspace > 0)
773 result = st_int_ioctl(STp, MTBSR, backspace);
774 } else if (STps->eof == ST_FM_HIT) {
775 if (STps->drv_file >= 0)
776 STps->drv_file++;
777 STps->drv_block = 0;
778 STps->eof = ST_NOEOF;
779 }
780 return result;
781
782}
783
784/* Set the mode parameters */
785static int set_mode_densblk(struct scsi_tape * STp, struct st_modedef * STm)
786{
787 int set_it = 0;
788 unsigned long arg;
789 char *name = tape_name(STp);
790
791 if (!STp->density_changed &&
792 STm->default_density >= 0 &&
793 STm->default_density != STp->density) {
794 arg = STm->default_density;
795 set_it = 1;
796 } else
797 arg = STp->density;
798 arg <<= MT_ST_DENSITY_SHIFT;
799 if (!STp->blksize_changed &&
800 STm->default_blksize >= 0 &&
801 STm->default_blksize != STp->block_size) {
802 arg |= STm->default_blksize;
803 set_it = 1;
804 } else
805 arg |= STp->block_size;
806 if (set_it &&
807 st_int_ioctl(STp, SET_DENS_AND_BLK, arg)) {
808 printk(KERN_WARNING
809 "%s: Can't set default block size to %d bytes and density %x.\n",
810 name, STm->default_blksize, STm->default_density);
811 if (modes_defined)
812 return (-EINVAL);
813 }
814 return 0;
815}
816
817
Mike Christie8b05b772005-11-08 04:06:44 -0600818/* Lock or unlock the drive door. Don't use when st_request allocated. */
Linus Torvalds1da177e2005-04-16 15:20:36 -0700819static int do_door_lock(struct scsi_tape * STp, int do_lock)
820{
821 int retval, cmd;
822 DEB(char *name = tape_name(STp);)
823
824
825 cmd = do_lock ? SCSI_IOCTL_DOORLOCK : SCSI_IOCTL_DOORUNLOCK;
826 DEBC(printk(ST_DEB_MSG "%s: %socking drive door.\n", name,
827 do_lock ? "L" : "Unl"));
828 retval = scsi_ioctl(STp->device, cmd, NULL);
829 if (!retval) {
830 STp->door_locked = do_lock ? ST_LOCKED_EXPLICIT : ST_UNLOCKED;
831 }
832 else {
833 STp->door_locked = ST_LOCK_FAILS;
834 }
835 return retval;
836}
837
838
839/* Set the internal state after reset */
840static void reset_state(struct scsi_tape *STp)
841{
842 int i;
843 struct st_partstat *STps;
844
845 STp->pos_unknown = 0;
846 for (i = 0; i < ST_NBR_PARTITIONS; i++) {
847 STps = &(STp->ps[i]);
848 STps->rw = ST_IDLE;
849 STps->eof = ST_NOEOF;
850 STps->at_sm = 0;
851 STps->last_block_valid = 0;
852 STps->drv_block = -1;
853 STps->drv_file = -1;
854 }
855 if (STp->can_partitions) {
856 STp->partition = find_partition(STp);
857 if (STp->partition < 0)
858 STp->partition = 0;
859 STp->new_partition = STp->partition;
860 }
861}
862
863/* Test if the drive is ready. Returns either one of the codes below or a negative system
864 error code. */
865#define CHKRES_READY 0
866#define CHKRES_NEW_SESSION 1
867#define CHKRES_NOT_READY 2
868#define CHKRES_NO_TAPE 3
869
870#define MAX_ATTENTIONS 10
871
872static int test_ready(struct scsi_tape *STp, int do_wait)
873{
874 int attentions, waits, max_wait, scode;
875 int retval = CHKRES_READY, new_session = 0;
876 unsigned char cmd[MAX_COMMAND_SIZE];
Mike Christie8b05b772005-11-08 04:06:44 -0600877 struct st_request *SRpnt = NULL;
Linus Torvalds1da177e2005-04-16 15:20:36 -0700878 struct st_cmdstatus *cmdstatp = &STp->buffer->cmdstat;
879
880 max_wait = do_wait ? ST_BLOCK_SECONDS : 0;
881
882 for (attentions=waits=0; ; ) {
883 memset((void *) &cmd[0], 0, MAX_COMMAND_SIZE);
884 cmd[0] = TEST_UNIT_READY;
885 SRpnt = st_do_scsi(SRpnt, STp, cmd, 0, DMA_NONE,
886 STp->long_timeout, MAX_READY_RETRIES, 1);
887
888 if (!SRpnt) {
889 retval = (STp->buffer)->syscall_result;
890 break;
891 }
892
893 if (cmdstatp->have_sense) {
894
895 scode = cmdstatp->sense_hdr.sense_key;
896
897 if (scode == UNIT_ATTENTION) { /* New media? */
898 new_session = 1;
899 if (attentions < MAX_ATTENTIONS) {
900 attentions++;
901 continue;
902 }
903 else {
904 retval = (-EIO);
905 break;
906 }
907 }
908
909 if (scode == NOT_READY) {
910 if (waits < max_wait) {
911 if (msleep_interruptible(1000)) {
912 retval = (-EINTR);
913 break;
914 }
915 waits++;
916 continue;
917 }
918 else {
919 if ((STp->device)->scsi_level >= SCSI_2 &&
920 cmdstatp->sense_hdr.asc == 0x3a) /* Check ASC */
921 retval = CHKRES_NO_TAPE;
922 else
923 retval = CHKRES_NOT_READY;
924 break;
925 }
926 }
927 }
928
929 retval = (STp->buffer)->syscall_result;
930 if (!retval)
931 retval = new_session ? CHKRES_NEW_SESSION : CHKRES_READY;
932 break;
933 }
934
935 if (SRpnt != NULL)
Mike Christie8b05b772005-11-08 04:06:44 -0600936 st_release_request(SRpnt);
Linus Torvalds1da177e2005-04-16 15:20:36 -0700937 return retval;
938}
939
940
941/* See if the drive is ready and gather information about the tape. Return values:
942 < 0 negative error code from errno.h
943 0 drive ready
944 1 drive not ready (possibly no tape)
945*/
946static int check_tape(struct scsi_tape *STp, struct file *filp)
947{
948 int i, retval, new_session = 0, do_wait;
949 unsigned char cmd[MAX_COMMAND_SIZE], saved_cleaning;
950 unsigned short st_flags = filp->f_flags;
Mike Christie8b05b772005-11-08 04:06:44 -0600951 struct st_request *SRpnt = NULL;
Linus Torvalds1da177e2005-04-16 15:20:36 -0700952 struct st_modedef *STm;
953 struct st_partstat *STps;
954 char *name = tape_name(STp);
Josef Sipek7ac62072006-12-08 02:37:37 -0800955 struct inode *inode = filp->f_path.dentry->d_inode;
Linus Torvalds1da177e2005-04-16 15:20:36 -0700956 int mode = TAPE_MODE(inode);
957
958 STp->ready = ST_READY;
959
960 if (mode != STp->current_mode) {
961 DEBC(printk(ST_DEB_MSG "%s: Mode change from %d to %d.\n",
962 name, STp->current_mode, mode));
963 new_session = 1;
964 STp->current_mode = mode;
965 }
966 STm = &(STp->modes[STp->current_mode]);
967
968 saved_cleaning = STp->cleaning_req;
969 STp->cleaning_req = 0;
970
971 do_wait = ((filp->f_flags & O_NONBLOCK) == 0);
972 retval = test_ready(STp, do_wait);
973
974 if (retval < 0)
975 goto err_out;
976
977 if (retval == CHKRES_NEW_SESSION) {
978 STp->pos_unknown = 0;
979 STp->partition = STp->new_partition = 0;
980 if (STp->can_partitions)
981 STp->nbr_partitions = 1; /* This guess will be updated later
982 if necessary */
983 for (i = 0; i < ST_NBR_PARTITIONS; i++) {
984 STps = &(STp->ps[i]);
985 STps->rw = ST_IDLE;
986 STps->eof = ST_NOEOF;
987 STps->at_sm = 0;
988 STps->last_block_valid = 0;
989 STps->drv_block = 0;
990 STps->drv_file = 0;
991 }
992 new_session = 1;
993 }
994 else {
995 STp->cleaning_req |= saved_cleaning;
996
997 if (retval == CHKRES_NOT_READY || retval == CHKRES_NO_TAPE) {
998 if (retval == CHKRES_NO_TAPE)
999 STp->ready = ST_NO_TAPE;
1000 else
1001 STp->ready = ST_NOT_READY;
1002
1003 STp->density = 0; /* Clear the erroneous "residue" */
1004 STp->write_prot = 0;
1005 STp->block_size = 0;
1006 STp->ps[0].drv_file = STp->ps[0].drv_block = (-1);
1007 STp->partition = STp->new_partition = 0;
1008 STp->door_locked = ST_UNLOCKED;
1009 return CHKRES_NOT_READY;
1010 }
1011 }
1012
1013 if (STp->omit_blklims)
1014 STp->min_block = STp->max_block = (-1);
1015 else {
1016 memset((void *) &cmd[0], 0, MAX_COMMAND_SIZE);
1017 cmd[0] = READ_BLOCK_LIMITS;
1018
1019 SRpnt = st_do_scsi(SRpnt, STp, cmd, 6, DMA_FROM_DEVICE,
James Bottomleya02488e2008-11-30 10:36:26 -06001020 STp->device->request_queue->rq_timeout,
1021 MAX_READY_RETRIES, 1);
Linus Torvalds1da177e2005-04-16 15:20:36 -07001022 if (!SRpnt) {
1023 retval = (STp->buffer)->syscall_result;
1024 goto err_out;
1025 }
1026
Mike Christie8b05b772005-11-08 04:06:44 -06001027 if (!SRpnt->result && !STp->buffer->cmdstat.have_sense) {
Linus Torvalds1da177e2005-04-16 15:20:36 -07001028 STp->max_block = ((STp->buffer)->b_data[1] << 16) |
1029 ((STp->buffer)->b_data[2] << 8) | (STp->buffer)->b_data[3];
1030 STp->min_block = ((STp->buffer)->b_data[4] << 8) |
1031 (STp->buffer)->b_data[5];
1032 if ( DEB( debugging || ) !STp->inited)
Kai Makisara42252852006-11-07 21:56:38 +02001033 printk(KERN_INFO
Linus Torvalds1da177e2005-04-16 15:20:36 -07001034 "%s: Block limits %d - %d bytes.\n", name,
1035 STp->min_block, STp->max_block);
1036 } else {
1037 STp->min_block = STp->max_block = (-1);
1038 DEBC(printk(ST_DEB_MSG "%s: Can't read block limits.\n",
1039 name));
1040 }
1041 }
1042
1043 memset((void *) &cmd[0], 0, MAX_COMMAND_SIZE);
1044 cmd[0] = MODE_SENSE;
1045 cmd[4] = 12;
1046
1047 SRpnt = st_do_scsi(SRpnt, STp, cmd, 12, DMA_FROM_DEVICE,
James Bottomleya02488e2008-11-30 10:36:26 -06001048 STp->device->request_queue->rq_timeout,
1049 MAX_READY_RETRIES, 1);
Linus Torvalds1da177e2005-04-16 15:20:36 -07001050 if (!SRpnt) {
1051 retval = (STp->buffer)->syscall_result;
1052 goto err_out;
1053 }
1054
1055 if ((STp->buffer)->syscall_result != 0) {
1056 DEBC(printk(ST_DEB_MSG "%s: No Mode Sense.\n", name));
1057 STp->block_size = ST_DEFAULT_BLOCK; /* Educated guess (?) */
1058 (STp->buffer)->syscall_result = 0; /* Prevent error propagation */
1059 STp->drv_write_prot = 0;
1060 } else {
1061 DEBC(printk(ST_DEB_MSG
1062 "%s: Mode sense. Length %d, medium %x, WBS %x, BLL %d\n",
1063 name,
1064 (STp->buffer)->b_data[0], (STp->buffer)->b_data[1],
1065 (STp->buffer)->b_data[2], (STp->buffer)->b_data[3]));
1066
1067 if ((STp->buffer)->b_data[3] >= 8) {
1068 STp->drv_buffer = ((STp->buffer)->b_data[2] >> 4) & 7;
1069 STp->density = (STp->buffer)->b_data[4];
1070 STp->block_size = (STp->buffer)->b_data[9] * 65536 +
1071 (STp->buffer)->b_data[10] * 256 + (STp->buffer)->b_data[11];
1072 DEBC(printk(ST_DEB_MSG
1073 "%s: Density %x, tape length: %x, drv buffer: %d\n",
1074 name, STp->density, (STp->buffer)->b_data[5] * 65536 +
1075 (STp->buffer)->b_data[6] * 256 + (STp->buffer)->b_data[7],
1076 STp->drv_buffer));
1077 }
1078 STp->drv_write_prot = ((STp->buffer)->b_data[2] & 0x80) != 0;
1079 }
Mike Christie8b05b772005-11-08 04:06:44 -06001080 st_release_request(SRpnt);
Linus Torvalds1da177e2005-04-16 15:20:36 -07001081 SRpnt = NULL;
1082 STp->inited = 1;
1083
1084 if (STp->block_size > 0)
1085 (STp->buffer)->buffer_blocks =
1086 (STp->buffer)->buffer_size / STp->block_size;
1087 else
1088 (STp->buffer)->buffer_blocks = 1;
1089 (STp->buffer)->buffer_bytes = (STp->buffer)->read_pointer = 0;
1090
1091 DEBC(printk(ST_DEB_MSG
1092 "%s: Block size: %d, buffer size: %d (%d blocks).\n", name,
1093 STp->block_size, (STp->buffer)->buffer_size,
1094 (STp->buffer)->buffer_blocks));
1095
1096 if (STp->drv_write_prot) {
1097 STp->write_prot = 1;
1098
1099 DEBC(printk(ST_DEB_MSG "%s: Write protected\n", name));
1100
1101 if (do_wait &&
1102 ((st_flags & O_ACCMODE) == O_WRONLY ||
1103 (st_flags & O_ACCMODE) == O_RDWR)) {
1104 retval = (-EROFS);
1105 goto err_out;
1106 }
1107 }
1108
1109 if (STp->can_partitions && STp->nbr_partitions < 1) {
1110 /* This code is reached when the device is opened for the first time
1111 after the driver has been initialized with tape in the drive and the
1112 partition support has been enabled. */
1113 DEBC(printk(ST_DEB_MSG
1114 "%s: Updating partition number in status.\n", name));
1115 if ((STp->partition = find_partition(STp)) < 0) {
1116 retval = STp->partition;
1117 goto err_out;
1118 }
1119 STp->new_partition = STp->partition;
1120 STp->nbr_partitions = 1; /* This guess will be updated when necessary */
1121 }
1122
1123 if (new_session) { /* Change the drive parameters for the new mode */
1124 STp->density_changed = STp->blksize_changed = 0;
1125 STp->compression_changed = 0;
1126 if (!(STm->defaults_for_writes) &&
1127 (retval = set_mode_densblk(STp, STm)) < 0)
1128 goto err_out;
1129
1130 if (STp->default_drvbuffer != 0xff) {
1131 if (st_int_ioctl(STp, MTSETDRVBUFFER, STp->default_drvbuffer))
1132 printk(KERN_WARNING
1133 "%s: Can't set default drive buffering to %d.\n",
1134 name, STp->default_drvbuffer);
1135 }
1136 }
1137
1138 return CHKRES_READY;
1139
1140 err_out:
1141 return retval;
1142}
1143
1144
Jonathan Corbetb3369c62008-05-15 16:08:15 -06001145 /* Open the device. Needs to take the BKL only because of incrementing the SCSI host
Linus Torvalds1da177e2005-04-16 15:20:36 -07001146 module count. */
1147static int st_open(struct inode *inode, struct file *filp)
1148{
1149 int i, retval = (-EIO);
1150 struct scsi_tape *STp;
1151 struct st_partstat *STps;
1152 int dev = TAPE_NR(inode);
1153 char *name;
1154
Jonathan Corbetb3369c62008-05-15 16:08:15 -06001155 lock_kernel();
Linus Torvalds1da177e2005-04-16 15:20:36 -07001156 /*
1157 * We really want to do nonseekable_open(inode, filp); here, but some
1158 * versions of tar incorrectly call lseek on tapes and bail out if that
1159 * fails. So we disallow pread() and pwrite(), but permit lseeks.
1160 */
1161 filp->f_mode &= ~(FMODE_PREAD | FMODE_PWRITE);
1162
Jonathan Corbetb3369c62008-05-15 16:08:15 -06001163 if (!(STp = scsi_tape_get(dev))) {
1164 unlock_kernel();
Kai Makisaraf03a5672005-08-02 13:40:47 +03001165 return -ENXIO;
Jonathan Corbetb3369c62008-05-15 16:08:15 -06001166 }
Kai Makisaraf03a5672005-08-02 13:40:47 +03001167
Linus Torvalds1da177e2005-04-16 15:20:36 -07001168 write_lock(&st_dev_arr_lock);
Linus Torvalds1da177e2005-04-16 15:20:36 -07001169 filp->private_data = STp;
1170 name = tape_name(STp);
1171
1172 if (STp->in_use) {
1173 write_unlock(&st_dev_arr_lock);
Kai Makisaraf03a5672005-08-02 13:40:47 +03001174 scsi_tape_put(STp);
Jonathan Corbetb3369c62008-05-15 16:08:15 -06001175 unlock_kernel();
Linus Torvalds1da177e2005-04-16 15:20:36 -07001176 DEB( printk(ST_DEB_MSG "%s: Device already in use.\n", name); )
1177 return (-EBUSY);
1178 }
1179
Linus Torvalds1da177e2005-04-16 15:20:36 -07001180 STp->in_use = 1;
1181 write_unlock(&st_dev_arr_lock);
1182 STp->rew_at_close = STp->autorew_dev = (iminor(inode) & 0x80) == 0;
1183
1184 if (!scsi_block_when_processing_errors(STp->device)) {
1185 retval = (-ENXIO);
1186 goto err_out;
1187 }
1188
1189 /* See that we have at least a one page buffer available */
1190 if (!enlarge_buffer(STp->buffer, PAGE_SIZE, STp->restr_dma)) {
1191 printk(KERN_WARNING "%s: Can't allocate one page tape buffer.\n",
1192 name);
1193 retval = (-EOVERFLOW);
1194 goto err_out;
1195 }
1196
Kai Makisara40f6b362008-02-24 22:23:24 +02001197 (STp->buffer)->cleared = 0;
Linus Torvalds1da177e2005-04-16 15:20:36 -07001198 (STp->buffer)->writing = 0;
1199 (STp->buffer)->syscall_result = 0;
1200
1201 STp->write_prot = ((filp->f_flags & O_ACCMODE) == O_RDONLY);
1202
1203 STp->dirty = 0;
1204 for (i = 0; i < ST_NBR_PARTITIONS; i++) {
1205 STps = &(STp->ps[i]);
1206 STps->rw = ST_IDLE;
1207 }
Kai Makisara9abe16c2007-02-03 13:21:29 +02001208 STp->try_dio_now = STp->try_dio;
Linus Torvalds1da177e2005-04-16 15:20:36 -07001209 STp->recover_count = 0;
1210 DEB( STp->nbr_waits = STp->nbr_finished = 0;
Kai Makisaradeee13d2008-02-22 20:11:21 +02001211 STp->nbr_requests = STp->nbr_dio = STp->nbr_pages = 0; )
Linus Torvalds1da177e2005-04-16 15:20:36 -07001212
1213 retval = check_tape(STp, filp);
1214 if (retval < 0)
1215 goto err_out;
1216 if ((filp->f_flags & O_NONBLOCK) == 0 &&
1217 retval != CHKRES_READY) {
Kai Makisara413f7322006-10-05 22:59:46 +03001218 if (STp->ready == NO_TAPE)
1219 retval = (-ENOMEDIUM);
1220 else
1221 retval = (-EIO);
Linus Torvalds1da177e2005-04-16 15:20:36 -07001222 goto err_out;
1223 }
Jonathan Corbetb3369c62008-05-15 16:08:15 -06001224 unlock_kernel();
Linus Torvalds1da177e2005-04-16 15:20:36 -07001225 return 0;
1226
1227 err_out:
1228 normalize_buffer(STp->buffer);
1229 STp->in_use = 0;
Kai Makisaraf03a5672005-08-02 13:40:47 +03001230 scsi_tape_put(STp);
Jonathan Corbetb3369c62008-05-15 16:08:15 -06001231 unlock_kernel();
Linus Torvalds1da177e2005-04-16 15:20:36 -07001232 return retval;
1233
1234}
1235
1236
1237/* Flush the tape buffer before close */
Miklos Szeredi75e1fcc2006-06-23 02:05:12 -07001238static int st_flush(struct file *filp, fl_owner_t id)
Linus Torvalds1da177e2005-04-16 15:20:36 -07001239{
1240 int result = 0, result2;
1241 unsigned char cmd[MAX_COMMAND_SIZE];
Mike Christie8b05b772005-11-08 04:06:44 -06001242 struct st_request *SRpnt;
Linus Torvalds1da177e2005-04-16 15:20:36 -07001243 struct scsi_tape *STp = filp->private_data;
1244 struct st_modedef *STm = &(STp->modes[STp->current_mode]);
1245 struct st_partstat *STps = &(STp->ps[STp->partition]);
1246 char *name = tape_name(STp);
1247
1248 if (file_count(filp) > 1)
1249 return 0;
1250
1251 if (STps->rw == ST_WRITING && !STp->pos_unknown) {
Adrian Bunk8ef8d592008-04-14 17:17:16 +03001252 result = st_flush_write_buffer(STp);
Linus Torvalds1da177e2005-04-16 15:20:36 -07001253 if (result != 0 && result != (-ENOSPC))
1254 goto out;
1255 }
1256
1257 if (STp->can_partitions &&
1258 (result2 = switch_partition(STp)) < 0) {
1259 DEBC(printk(ST_DEB_MSG
1260 "%s: switch_partition at close failed.\n", name));
1261 if (result == 0)
1262 result = result2;
1263 goto out;
1264 }
1265
1266 DEBC( if (STp->nbr_requests)
Kai Makisaradeee13d2008-02-22 20:11:21 +02001267 printk(KERN_DEBUG "%s: Number of r/w requests %d, dio used in %d, pages %d.\n",
1268 name, STp->nbr_requests, STp->nbr_dio, STp->nbr_pages));
Linus Torvalds1da177e2005-04-16 15:20:36 -07001269
1270 if (STps->rw == ST_WRITING && !STp->pos_unknown) {
1271 struct st_cmdstatus *cmdstatp = &STp->buffer->cmdstat;
1272
1273 DEBC(printk(ST_DEB_MSG "%s: Async write waits %d, finished %d.\n",
1274 name, STp->nbr_waits, STp->nbr_finished);
1275 )
1276
1277 memset(cmd, 0, MAX_COMMAND_SIZE);
1278 cmd[0] = WRITE_FILEMARKS;
1279 cmd[4] = 1 + STp->two_fm;
1280
1281 SRpnt = st_do_scsi(NULL, STp, cmd, 0, DMA_NONE,
James Bottomleya02488e2008-11-30 10:36:26 -06001282 STp->device->request_queue->rq_timeout,
1283 MAX_WRITE_RETRIES, 1);
Linus Torvalds1da177e2005-04-16 15:20:36 -07001284 if (!SRpnt) {
1285 result = (STp->buffer)->syscall_result;
1286 goto out;
1287 }
1288
1289 if (STp->buffer->syscall_result == 0 ||
1290 (cmdstatp->have_sense && !cmdstatp->deferred &&
1291 (cmdstatp->flags & SENSE_EOM) &&
1292 (cmdstatp->sense_hdr.sense_key == NO_SENSE ||
1293 cmdstatp->sense_hdr.sense_key == RECOVERED_ERROR) &&
1294 (!cmdstatp->remainder_valid || cmdstatp->uremainder64 == 0))) {
1295 /* Write successful at EOM */
Mike Christie8b05b772005-11-08 04:06:44 -06001296 st_release_request(SRpnt);
Linus Torvalds1da177e2005-04-16 15:20:36 -07001297 SRpnt = NULL;
1298 if (STps->drv_file >= 0)
1299 STps->drv_file++;
1300 STps->drv_block = 0;
1301 if (STp->two_fm)
1302 cross_eof(STp, 0);
1303 STps->eof = ST_FM;
1304 }
1305 else { /* Write error */
Mike Christie8b05b772005-11-08 04:06:44 -06001306 st_release_request(SRpnt);
Linus Torvalds1da177e2005-04-16 15:20:36 -07001307 SRpnt = NULL;
1308 printk(KERN_ERR "%s: Error on write filemark.\n", name);
1309 if (result == 0)
1310 result = (-EIO);
1311 }
1312
1313 DEBC(printk(ST_DEB_MSG "%s: Buffer flushed, %d EOF(s) written\n",
1314 name, cmd[4]));
1315 } else if (!STp->rew_at_close) {
1316 STps = &(STp->ps[STp->partition]);
1317 if (!STm->sysv || STps->rw != ST_READING) {
1318 if (STp->can_bsr)
1319 result = flush_buffer(STp, 0);
1320 else if (STps->eof == ST_FM_HIT) {
1321 result = cross_eof(STp, 0);
1322 if (result) {
1323 if (STps->drv_file >= 0)
1324 STps->drv_file++;
1325 STps->drv_block = 0;
1326 STps->eof = ST_FM;
1327 } else
1328 STps->eof = ST_NOEOF;
1329 }
1330 } else if ((STps->eof == ST_NOEOF &&
1331 !(result = cross_eof(STp, 1))) ||
1332 STps->eof == ST_FM_HIT) {
1333 if (STps->drv_file >= 0)
1334 STps->drv_file++;
1335 STps->drv_block = 0;
1336 STps->eof = ST_FM;
1337 }
1338 }
1339
1340 out:
1341 if (STp->rew_at_close) {
1342 result2 = st_int_ioctl(STp, MTREW, 1);
1343 if (result == 0)
1344 result = result2;
1345 }
1346 return result;
1347}
1348
1349
1350/* Close the device and release it. BKL is not needed: this is the only thread
1351 accessing this tape. */
1352static int st_release(struct inode *inode, struct file *filp)
1353{
1354 int result = 0;
1355 struct scsi_tape *STp = filp->private_data;
1356
1357 if (STp->door_locked == ST_LOCKED_AUTO)
1358 do_door_lock(STp, 0);
1359
1360 normalize_buffer(STp->buffer);
1361 write_lock(&st_dev_arr_lock);
1362 STp->in_use = 0;
1363 write_unlock(&st_dev_arr_lock);
Kai Makisaraf03a5672005-08-02 13:40:47 +03001364 scsi_tape_put(STp);
Linus Torvalds1da177e2005-04-16 15:20:36 -07001365
1366 return result;
1367}
1368
1369/* The checks common to both reading and writing */
1370static ssize_t rw_checks(struct scsi_tape *STp, struct file *filp, size_t count)
1371{
1372 ssize_t retval = 0;
1373
1374 /*
1375 * If we are in the middle of error recovery, don't let anyone
1376 * else try and use this device. Also, if error recovery fails, it
1377 * may try and take the device offline, in which case all further
1378 * access to the device is prohibited.
1379 */
1380 if (!scsi_block_when_processing_errors(STp->device)) {
1381 retval = (-ENXIO);
1382 goto out;
1383 }
1384
1385 if (STp->ready != ST_READY) {
1386 if (STp->ready == ST_NO_TAPE)
1387 retval = (-ENOMEDIUM);
1388 else
1389 retval = (-EIO);
1390 goto out;
1391 }
1392
1393 if (! STp->modes[STp->current_mode].defined) {
1394 retval = (-ENXIO);
1395 goto out;
1396 }
1397
1398
1399 /*
1400 * If there was a bus reset, block further access
1401 * to this device.
1402 */
1403 if (STp->pos_unknown) {
1404 retval = (-EIO);
1405 goto out;
1406 }
1407
1408 if (count == 0)
1409 goto out;
1410
1411 DEB(
1412 if (!STp->in_use) {
1413 printk(ST_DEB_MSG "%s: Incorrect device.\n", tape_name(STp));
1414 retval = (-EIO);
1415 goto out;
1416 } ) /* end DEB */
1417
1418 if (STp->can_partitions &&
1419 (retval = switch_partition(STp)) < 0)
1420 goto out;
1421
1422 if (STp->block_size == 0 && STp->max_block > 0 &&
1423 (count < STp->min_block || count > STp->max_block)) {
1424 retval = (-EINVAL);
1425 goto out;
1426 }
1427
1428 if (STp->do_auto_lock && STp->door_locked == ST_UNLOCKED &&
1429 !do_door_lock(STp, 1))
1430 STp->door_locked = ST_LOCKED_AUTO;
1431
1432 out:
1433 return retval;
1434}
1435
1436
1437static int setup_buffering(struct scsi_tape *STp, const char __user *buf,
1438 size_t count, int is_read)
1439{
1440 int i, bufsize, retval = 0;
1441 struct st_buffer *STbp = STp->buffer;
1442
1443 if (is_read)
Kai Makisara9abe16c2007-02-03 13:21:29 +02001444 i = STp->try_dio_now && try_rdio;
Linus Torvalds1da177e2005-04-16 15:20:36 -07001445 else
Kai Makisara9abe16c2007-02-03 13:21:29 +02001446 i = STp->try_dio_now && try_wdio;
Mike Christie8b05b772005-11-08 04:06:44 -06001447
Linus Torvalds1da177e2005-04-16 15:20:36 -07001448 if (i && ((unsigned long)buf & queue_dma_alignment(
1449 STp->device->request_queue)) == 0) {
Mike Christie8b05b772005-11-08 04:06:44 -06001450 i = sgl_map_user_pages(&(STbp->sg[0]), STbp->use_sg,
1451 (unsigned long)buf, count, (is_read ? READ : WRITE));
Linus Torvalds1da177e2005-04-16 15:20:36 -07001452 if (i > 0) {
1453 STbp->do_dio = i;
1454 STbp->buffer_bytes = 0; /* can be used as transfer counter */
1455 }
1456 else
1457 STbp->do_dio = 0; /* fall back to buffering with any error */
1458 STbp->sg_segs = STbp->do_dio;
1459 STbp->frp_sg_current = 0;
1460 DEB(
1461 if (STbp->do_dio) {
1462 STp->nbr_dio++;
1463 STp->nbr_pages += STbp->do_dio;
Linus Torvalds1da177e2005-04-16 15:20:36 -07001464 }
1465 )
1466 } else
1467 STbp->do_dio = 0;
1468 DEB( STp->nbr_requests++; )
1469
1470 if (!STbp->do_dio) {
1471 if (STp->block_size)
1472 bufsize = STp->block_size > st_fixed_buffer_size ?
1473 STp->block_size : st_fixed_buffer_size;
Kai Makisara40f6b362008-02-24 22:23:24 +02001474 else {
Linus Torvalds1da177e2005-04-16 15:20:36 -07001475 bufsize = count;
Kai Makisara40f6b362008-02-24 22:23:24 +02001476 /* Make sure that data from previous user is not leaked even if
1477 HBA does not return correct residual */
1478 if (is_read && STp->sili && !STbp->cleared)
1479 clear_buffer(STbp);
1480 }
1481
Linus Torvalds1da177e2005-04-16 15:20:36 -07001482 if (bufsize > STbp->buffer_size &&
1483 !enlarge_buffer(STbp, bufsize, STp->restr_dma)) {
1484 printk(KERN_WARNING "%s: Can't allocate %d byte tape buffer.\n",
1485 tape_name(STp), bufsize);
1486 retval = (-EOVERFLOW);
1487 goto out;
1488 }
1489 if (STp->block_size)
1490 STbp->buffer_blocks = bufsize / STp->block_size;
1491 }
1492
1493 out:
1494 return retval;
1495}
1496
1497
1498/* Can be called more than once after each setup_buffer() */
Kai Makisara787926b2005-11-13 10:04:44 +02001499static void release_buffering(struct scsi_tape *STp, int is_read)
Linus Torvalds1da177e2005-04-16 15:20:36 -07001500{
1501 struct st_buffer *STbp;
1502
1503 STbp = STp->buffer;
1504 if (STbp->do_dio) {
Kai Makisara787926b2005-11-13 10:04:44 +02001505 sgl_unmap_user_pages(&(STbp->sg[0]), STbp->do_dio, is_read);
Linus Torvalds1da177e2005-04-16 15:20:36 -07001506 STbp->do_dio = 0;
Kai Makisara787926b2005-11-13 10:04:44 +02001507 STbp->sg_segs = 0;
Linus Torvalds1da177e2005-04-16 15:20:36 -07001508 }
1509}
1510
1511
1512/* Write command */
1513static ssize_t
1514st_write(struct file *filp, const char __user *buf, size_t count, loff_t * ppos)
1515{
1516 ssize_t total;
1517 ssize_t i, do_count, blks, transfer;
1518 ssize_t retval;
1519 int undone, retry_eot = 0, scode;
1520 int async_write;
1521 unsigned char cmd[MAX_COMMAND_SIZE];
1522 const char __user *b_point;
Mike Christie8b05b772005-11-08 04:06:44 -06001523 struct st_request *SRpnt = NULL;
Linus Torvalds1da177e2005-04-16 15:20:36 -07001524 struct scsi_tape *STp = filp->private_data;
1525 struct st_modedef *STm;
1526 struct st_partstat *STps;
1527 struct st_buffer *STbp;
1528 char *name = tape_name(STp);
1529
Matthias Kaehlcke28f85002007-07-29 23:38:15 +02001530 if (mutex_lock_interruptible(&STp->lock))
Linus Torvalds1da177e2005-04-16 15:20:36 -07001531 return -ERESTARTSYS;
1532
1533 retval = rw_checks(STp, filp, count);
1534 if (retval || count == 0)
1535 goto out;
1536
1537 /* Write must be integral number of blocks */
1538 if (STp->block_size != 0 && (count % STp->block_size) != 0) {
1539 printk(KERN_WARNING "%s: Write not multiple of tape block size.\n",
1540 name);
1541 retval = (-EINVAL);
1542 goto out;
1543 }
1544
1545 STm = &(STp->modes[STp->current_mode]);
1546 STps = &(STp->ps[STp->partition]);
1547
1548 if (STp->write_prot) {
1549 retval = (-EACCES);
1550 goto out;
1551 }
1552
1553
1554 if (STps->rw == ST_READING) {
1555 retval = flush_buffer(STp, 0);
1556 if (retval)
1557 goto out;
1558 STps->rw = ST_WRITING;
1559 } else if (STps->rw != ST_WRITING &&
1560 STps->drv_file == 0 && STps->drv_block == 0) {
1561 if ((retval = set_mode_densblk(STp, STm)) < 0)
1562 goto out;
1563 if (STm->default_compression != ST_DONT_TOUCH &&
1564 !(STp->compression_changed)) {
1565 if (st_compression(STp, (STm->default_compression == ST_YES))) {
1566 printk(KERN_WARNING "%s: Can't set default compression.\n",
1567 name);
1568 if (modes_defined) {
1569 retval = (-EINVAL);
1570 goto out;
1571 }
1572 }
1573 }
1574 }
1575
1576 STbp = STp->buffer;
1577 i = write_behind_check(STp);
1578 if (i) {
1579 if (i == -ENOSPC)
1580 STps->eof = ST_EOM_OK;
1581 else
1582 STps->eof = ST_EOM_ERROR;
1583 }
1584
1585 if (STps->eof == ST_EOM_OK) {
1586 STps->eof = ST_EOD_1; /* allow next write */
1587 retval = (-ENOSPC);
1588 goto out;
1589 }
1590 else if (STps->eof == ST_EOM_ERROR) {
1591 retval = (-EIO);
1592 goto out;
1593 }
1594
1595 /* Check the buffer readability in cases where copy_user might catch
1596 the problems after some tape movement. */
1597 if (STp->block_size != 0 &&
1598 !STbp->do_dio &&
1599 (copy_from_user(&i, buf, 1) != 0 ||
1600 copy_from_user(&i, buf + count - 1, 1) != 0)) {
1601 retval = (-EFAULT);
1602 goto out;
1603 }
1604
1605 retval = setup_buffering(STp, buf, count, 0);
1606 if (retval)
1607 goto out;
1608
1609 total = count;
1610
1611 memset(cmd, 0, MAX_COMMAND_SIZE);
1612 cmd[0] = WRITE_6;
1613 cmd[1] = (STp->block_size != 0);
1614
1615 STps->rw = ST_WRITING;
1616
1617 b_point = buf;
1618 while (count > 0 && !retry_eot) {
1619
1620 if (STbp->do_dio) {
1621 do_count = count;
1622 }
1623 else {
1624 if (STp->block_size == 0)
1625 do_count = count;
1626 else {
1627 do_count = STbp->buffer_blocks * STp->block_size -
1628 STbp->buffer_bytes;
1629 if (do_count > count)
1630 do_count = count;
1631 }
1632
1633 i = append_to_buffer(b_point, STbp, do_count);
1634 if (i) {
1635 retval = i;
1636 goto out;
1637 }
1638 }
1639 count -= do_count;
1640 b_point += do_count;
1641
1642 async_write = STp->block_size == 0 && !STbp->do_dio &&
1643 STm->do_async_writes && STps->eof < ST_EOM_OK;
1644
1645 if (STp->block_size != 0 && STm->do_buffer_writes &&
Kai Makisara9abe16c2007-02-03 13:21:29 +02001646 !(STp->try_dio_now && try_wdio) && STps->eof < ST_EOM_OK &&
Linus Torvalds1da177e2005-04-16 15:20:36 -07001647 STbp->buffer_bytes < STbp->buffer_size) {
1648 STp->dirty = 1;
1649 /* Don't write a buffer that is not full enough. */
1650 if (!async_write && count == 0)
1651 break;
1652 }
1653
1654 retry_write:
1655 if (STp->block_size == 0)
1656 blks = transfer = do_count;
1657 else {
1658 if (!STbp->do_dio)
1659 blks = STbp->buffer_bytes;
1660 else
1661 blks = do_count;
1662 blks /= STp->block_size;
1663 transfer = blks * STp->block_size;
1664 }
1665 cmd[2] = blks >> 16;
1666 cmd[3] = blks >> 8;
1667 cmd[4] = blks;
1668
1669 SRpnt = st_do_scsi(SRpnt, STp, cmd, transfer, DMA_TO_DEVICE,
James Bottomleya02488e2008-11-30 10:36:26 -06001670 STp->device->request_queue->rq_timeout,
1671 MAX_WRITE_RETRIES, !async_write);
Linus Torvalds1da177e2005-04-16 15:20:36 -07001672 if (!SRpnt) {
1673 retval = STbp->syscall_result;
1674 goto out;
1675 }
Mike Christie8b05b772005-11-08 04:06:44 -06001676 if (async_write && !STbp->syscall_result) {
Linus Torvalds1da177e2005-04-16 15:20:36 -07001677 STbp->writing = transfer;
1678 STp->dirty = !(STbp->writing ==
1679 STbp->buffer_bytes);
1680 SRpnt = NULL; /* Prevent releasing this request! */
1681 DEB( STp->write_pending = 1; )
1682 break;
1683 }
1684
1685 if (STbp->syscall_result != 0) {
1686 struct st_cmdstatus *cmdstatp = &STp->buffer->cmdstat;
1687
1688 DEBC(printk(ST_DEB_MSG "%s: Error on write:\n", name));
1689 if (cmdstatp->have_sense && (cmdstatp->flags & SENSE_EOM)) {
1690 scode = cmdstatp->sense_hdr.sense_key;
1691 if (cmdstatp->remainder_valid)
1692 undone = (int)cmdstatp->uremainder64;
1693 else if (STp->block_size == 0 &&
1694 scode == VOLUME_OVERFLOW)
1695 undone = transfer;
1696 else
1697 undone = 0;
1698 if (STp->block_size != 0)
1699 undone *= STp->block_size;
1700 if (undone <= do_count) {
1701 /* Only data from this write is not written */
1702 count += undone;
Kai Makisara626dcb12008-07-11 15:05:25 +03001703 b_point -= undone;
Linus Torvalds1da177e2005-04-16 15:20:36 -07001704 do_count -= undone;
1705 if (STp->block_size)
1706 blks = (transfer - undone) / STp->block_size;
1707 STps->eof = ST_EOM_OK;
1708 /* Continue in fixed block mode if all written
1709 in this request but still something left to write
1710 (retval left to zero)
1711 */
1712 if (STp->block_size == 0 ||
1713 undone > 0 || count == 0)
1714 retval = (-ENOSPC); /* EOM within current request */
1715 DEBC(printk(ST_DEB_MSG
1716 "%s: EOM with %d bytes unwritten.\n",
1717 name, (int)count));
1718 } else {
1719 /* EOT within data buffered earlier (possible only
1720 in fixed block mode without direct i/o) */
1721 if (!retry_eot && !cmdstatp->deferred &&
1722 (scode == NO_SENSE || scode == RECOVERED_ERROR)) {
1723 move_buffer_data(STp->buffer, transfer - undone);
1724 retry_eot = 1;
1725 if (STps->drv_block >= 0) {
1726 STps->drv_block += (transfer - undone) /
1727 STp->block_size;
1728 }
1729 STps->eof = ST_EOM_OK;
1730 DEBC(printk(ST_DEB_MSG
1731 "%s: Retry write of %d bytes at EOM.\n",
1732 name, STp->buffer->buffer_bytes));
1733 goto retry_write;
1734 }
1735 else {
1736 /* Either error within data buffered by driver or
1737 failed retry */
1738 count -= do_count;
1739 blks = do_count = 0;
1740 STps->eof = ST_EOM_ERROR;
1741 STps->drv_block = (-1); /* Too cautious? */
1742 retval = (-EIO); /* EOM for old data */
1743 DEBC(printk(ST_DEB_MSG
1744 "%s: EOM with lost data.\n",
1745 name));
1746 }
1747 }
1748 } else {
1749 count += do_count;
1750 STps->drv_block = (-1); /* Too cautious? */
Mike Christie8b05b772005-11-08 04:06:44 -06001751 retval = STbp->syscall_result;
Linus Torvalds1da177e2005-04-16 15:20:36 -07001752 }
1753
1754 }
1755
1756 if (STps->drv_block >= 0) {
1757 if (STp->block_size == 0)
1758 STps->drv_block += (do_count > 0);
1759 else
1760 STps->drv_block += blks;
1761 }
1762
1763 STbp->buffer_bytes = 0;
1764 STp->dirty = 0;
1765
1766 if (retval || retry_eot) {
1767 if (count < total)
1768 retval = total - count;
1769 goto out;
1770 }
1771 }
1772
1773 if (STps->eof == ST_EOD_1)
1774 STps->eof = ST_EOM_OK;
1775 else if (STps->eof != ST_EOM_OK)
1776 STps->eof = ST_NOEOF;
1777 retval = total - count;
1778
1779 out:
1780 if (SRpnt != NULL)
Mike Christie8b05b772005-11-08 04:06:44 -06001781 st_release_request(SRpnt);
Kai Makisara787926b2005-11-13 10:04:44 +02001782 release_buffering(STp, 0);
Matthias Kaehlcke28f85002007-07-29 23:38:15 +02001783 mutex_unlock(&STp->lock);
Linus Torvalds1da177e2005-04-16 15:20:36 -07001784
1785 return retval;
1786}
1787
1788/* Read data from the tape. Returns zero in the normal case, one if the
1789 eof status has changed, and the negative error code in case of a
1790 fatal error. Otherwise updates the buffer and the eof state.
1791
1792 Does release user buffer mapping if it is set.
1793*/
1794static long read_tape(struct scsi_tape *STp, long count,
Mike Christie8b05b772005-11-08 04:06:44 -06001795 struct st_request ** aSRpnt)
Linus Torvalds1da177e2005-04-16 15:20:36 -07001796{
1797 int transfer, blks, bytes;
1798 unsigned char cmd[MAX_COMMAND_SIZE];
Mike Christie8b05b772005-11-08 04:06:44 -06001799 struct st_request *SRpnt;
Linus Torvalds1da177e2005-04-16 15:20:36 -07001800 struct st_modedef *STm;
1801 struct st_partstat *STps;
1802 struct st_buffer *STbp;
1803 int retval = 0;
1804 char *name = tape_name(STp);
1805
1806 if (count == 0)
1807 return 0;
1808
1809 STm = &(STp->modes[STp->current_mode]);
1810 STps = &(STp->ps[STp->partition]);
1811 if (STps->eof == ST_FM_HIT)
1812 return 1;
1813 STbp = STp->buffer;
1814
1815 if (STp->block_size == 0)
1816 blks = bytes = count;
1817 else {
Kai Makisara9abe16c2007-02-03 13:21:29 +02001818 if (!(STp->try_dio_now && try_rdio) && STm->do_read_ahead) {
Linus Torvalds1da177e2005-04-16 15:20:36 -07001819 blks = (STp->buffer)->buffer_blocks;
1820 bytes = blks * STp->block_size;
1821 } else {
1822 bytes = count;
1823 if (!STbp->do_dio && bytes > (STp->buffer)->buffer_size)
1824 bytes = (STp->buffer)->buffer_size;
1825 blks = bytes / STp->block_size;
1826 bytes = blks * STp->block_size;
1827 }
1828 }
1829
1830 memset(cmd, 0, MAX_COMMAND_SIZE);
1831 cmd[0] = READ_6;
1832 cmd[1] = (STp->block_size != 0);
Kai Makisara40f6b362008-02-24 22:23:24 +02001833 if (!cmd[1] && STp->sili)
1834 cmd[1] |= 2;
Linus Torvalds1da177e2005-04-16 15:20:36 -07001835 cmd[2] = blks >> 16;
1836 cmd[3] = blks >> 8;
1837 cmd[4] = blks;
1838
1839 SRpnt = *aSRpnt;
1840 SRpnt = st_do_scsi(SRpnt, STp, cmd, bytes, DMA_FROM_DEVICE,
James Bottomleya02488e2008-11-30 10:36:26 -06001841 STp->device->request_queue->rq_timeout,
1842 MAX_RETRIES, 1);
Kai Makisara787926b2005-11-13 10:04:44 +02001843 release_buffering(STp, 1);
Linus Torvalds1da177e2005-04-16 15:20:36 -07001844 *aSRpnt = SRpnt;
1845 if (!SRpnt)
1846 return STbp->syscall_result;
1847
1848 STbp->read_pointer = 0;
1849 STps->at_sm = 0;
1850
1851 /* Something to check */
1852 if (STbp->syscall_result) {
1853 struct st_cmdstatus *cmdstatp = &STp->buffer->cmdstat;
1854
1855 retval = 1;
1856 DEBC(printk(ST_DEB_MSG "%s: Sense: %2x %2x %2x %2x %2x %2x %2x %2x\n",
1857 name,
Mike Christie8b05b772005-11-08 04:06:44 -06001858 SRpnt->sense[0], SRpnt->sense[1],
1859 SRpnt->sense[2], SRpnt->sense[3],
1860 SRpnt->sense[4], SRpnt->sense[5],
1861 SRpnt->sense[6], SRpnt->sense[7]));
Linus Torvalds1da177e2005-04-16 15:20:36 -07001862 if (cmdstatp->have_sense) {
1863
1864 if (cmdstatp->sense_hdr.sense_key == BLANK_CHECK)
1865 cmdstatp->flags &= 0xcf; /* No need for EOM in this case */
1866
1867 if (cmdstatp->flags != 0) { /* EOF, EOM, or ILI */
1868 /* Compute the residual count */
1869 if (cmdstatp->remainder_valid)
1870 transfer = (int)cmdstatp->uremainder64;
1871 else
1872 transfer = 0;
1873 if (STp->block_size == 0 &&
1874 cmdstatp->sense_hdr.sense_key == MEDIUM_ERROR)
1875 transfer = bytes;
1876
1877 if (cmdstatp->flags & SENSE_ILI) { /* ILI */
1878 if (STp->block_size == 0) {
1879 if (transfer <= 0) {
1880 if (transfer < 0)
1881 printk(KERN_NOTICE
1882 "%s: Failed to read %d byte block with %d byte transfer.\n",
1883 name, bytes - transfer, bytes);
1884 if (STps->drv_block >= 0)
1885 STps->drv_block += 1;
1886 STbp->buffer_bytes = 0;
1887 return (-ENOMEM);
1888 }
1889 STbp->buffer_bytes = bytes - transfer;
1890 } else {
Mike Christie8b05b772005-11-08 04:06:44 -06001891 st_release_request(SRpnt);
Linus Torvalds1da177e2005-04-16 15:20:36 -07001892 SRpnt = *aSRpnt = NULL;
1893 if (transfer == blks) { /* We did not get anything, error */
1894 printk(KERN_NOTICE "%s: Incorrect block size.\n", name);
1895 if (STps->drv_block >= 0)
1896 STps->drv_block += blks - transfer + 1;
1897 st_int_ioctl(STp, MTBSR, 1);
1898 return (-EIO);
1899 }
1900 /* We have some data, deliver it */
1901 STbp->buffer_bytes = (blks - transfer) *
1902 STp->block_size;
1903 DEBC(printk(ST_DEB_MSG
1904 "%s: ILI but enough data received %ld %d.\n",
1905 name, count, STbp->buffer_bytes));
1906 if (STps->drv_block >= 0)
1907 STps->drv_block += 1;
1908 if (st_int_ioctl(STp, MTBSR, 1))
1909 return (-EIO);
1910 }
1911 } else if (cmdstatp->flags & SENSE_FMK) { /* FM overrides EOM */
1912 if (STps->eof != ST_FM_HIT)
1913 STps->eof = ST_FM_HIT;
1914 else
1915 STps->eof = ST_EOD_2;
1916 if (STp->block_size == 0)
1917 STbp->buffer_bytes = 0;
1918 else
1919 STbp->buffer_bytes =
1920 bytes - transfer * STp->block_size;
1921 DEBC(printk(ST_DEB_MSG
1922 "%s: EOF detected (%d bytes read).\n",
1923 name, STbp->buffer_bytes));
1924 } else if (cmdstatp->flags & SENSE_EOM) {
1925 if (STps->eof == ST_FM)
1926 STps->eof = ST_EOD_1;
1927 else
1928 STps->eof = ST_EOM_OK;
1929 if (STp->block_size == 0)
1930 STbp->buffer_bytes = bytes - transfer;
1931 else
1932 STbp->buffer_bytes =
1933 bytes - transfer * STp->block_size;
1934
1935 DEBC(printk(ST_DEB_MSG "%s: EOM detected (%d bytes read).\n",
1936 name, STbp->buffer_bytes));
1937 }
1938 }
1939 /* end of EOF, EOM, ILI test */
1940 else { /* nonzero sense key */
1941 DEBC(printk(ST_DEB_MSG
1942 "%s: Tape error while reading.\n", name));
1943 STps->drv_block = (-1);
1944 if (STps->eof == ST_FM &&
1945 cmdstatp->sense_hdr.sense_key == BLANK_CHECK) {
1946 DEBC(printk(ST_DEB_MSG
1947 "%s: Zero returned for first BLANK CHECK after EOF.\n",
1948 name));
1949 STps->eof = ST_EOD_2; /* First BLANK_CHECK after FM */
1950 } else /* Some other extended sense code */
1951 retval = (-EIO);
1952 }
1953
1954 if (STbp->buffer_bytes < 0) /* Caused by bogus sense data */
1955 STbp->buffer_bytes = 0;
1956 }
1957 /* End of extended sense test */
1958 else { /* Non-extended sense */
1959 retval = STbp->syscall_result;
1960 }
1961
1962 }
1963 /* End of error handling */
Kai Makisara40f6b362008-02-24 22:23:24 +02001964 else { /* Read successful */
Linus Torvalds1da177e2005-04-16 15:20:36 -07001965 STbp->buffer_bytes = bytes;
Kai Makisara40f6b362008-02-24 22:23:24 +02001966 if (STp->sili) /* In fixed block mode residual is always zero here */
1967 STbp->buffer_bytes -= STp->buffer->cmdstat.residual;
1968 }
Linus Torvalds1da177e2005-04-16 15:20:36 -07001969
1970 if (STps->drv_block >= 0) {
1971 if (STp->block_size == 0)
1972 STps->drv_block++;
1973 else
1974 STps->drv_block += STbp->buffer_bytes / STp->block_size;
1975 }
1976 return retval;
1977}
1978
1979
1980/* Read command */
1981static ssize_t
1982st_read(struct file *filp, char __user *buf, size_t count, loff_t * ppos)
1983{
1984 ssize_t total;
1985 ssize_t retval = 0;
1986 ssize_t i, transfer;
1987 int special, do_dio = 0;
Mike Christie8b05b772005-11-08 04:06:44 -06001988 struct st_request *SRpnt = NULL;
Linus Torvalds1da177e2005-04-16 15:20:36 -07001989 struct scsi_tape *STp = filp->private_data;
1990 struct st_modedef *STm;
1991 struct st_partstat *STps;
1992 struct st_buffer *STbp = STp->buffer;
1993 DEB( char *name = tape_name(STp); )
1994
Matthias Kaehlcke28f85002007-07-29 23:38:15 +02001995 if (mutex_lock_interruptible(&STp->lock))
Linus Torvalds1da177e2005-04-16 15:20:36 -07001996 return -ERESTARTSYS;
1997
1998 retval = rw_checks(STp, filp, count);
1999 if (retval || count == 0)
2000 goto out;
2001
2002 STm = &(STp->modes[STp->current_mode]);
Kai Makisara9abe16c2007-02-03 13:21:29 +02002003 if (STp->block_size != 0 && (count % STp->block_size) != 0) {
2004 if (!STm->do_read_ahead) {
2005 retval = (-EINVAL); /* Read must be integral number of blocks */
2006 goto out;
2007 }
2008 STp->try_dio_now = 0; /* Direct i/o can't handle split blocks */
Linus Torvalds1da177e2005-04-16 15:20:36 -07002009 }
2010
2011 STps = &(STp->ps[STp->partition]);
2012 if (STps->rw == ST_WRITING) {
2013 retval = flush_buffer(STp, 0);
2014 if (retval)
2015 goto out;
2016 STps->rw = ST_READING;
2017 }
2018 DEB(
2019 if (debugging && STps->eof != ST_NOEOF)
2020 printk(ST_DEB_MSG "%s: EOF/EOM flag up (%d). Bytes %d\n", name,
2021 STps->eof, STbp->buffer_bytes);
2022 ) /* end DEB */
2023
2024 retval = setup_buffering(STp, buf, count, 1);
2025 if (retval)
2026 goto out;
2027 do_dio = STbp->do_dio;
2028
2029 if (STbp->buffer_bytes == 0 &&
2030 STps->eof >= ST_EOD_1) {
2031 if (STps->eof < ST_EOD) {
2032 STps->eof += 1;
2033 retval = 0;
2034 goto out;
2035 }
2036 retval = (-EIO); /* EOM or Blank Check */
2037 goto out;
2038 }
2039
2040 if (do_dio) {
2041 /* Check the buffer writability before any tape movement. Don't alter
2042 buffer data. */
2043 if (copy_from_user(&i, buf, 1) != 0 ||
2044 copy_to_user(buf, &i, 1) != 0 ||
2045 copy_from_user(&i, buf + count - 1, 1) != 0 ||
2046 copy_to_user(buf + count - 1, &i, 1) != 0) {
2047 retval = (-EFAULT);
2048 goto out;
2049 }
2050 }
2051
2052 STps->rw = ST_READING;
2053
2054
2055 /* Loop until enough data in buffer or a special condition found */
2056 for (total = 0, special = 0; total < count && !special;) {
2057
2058 /* Get new data if the buffer is empty */
2059 if (STbp->buffer_bytes == 0) {
2060 special = read_tape(STp, count - total, &SRpnt);
2061 if (special < 0) { /* No need to continue read */
2062 retval = special;
2063 goto out;
2064 }
2065 }
2066
2067 /* Move the data from driver buffer to user buffer */
2068 if (STbp->buffer_bytes > 0) {
2069 DEB(
2070 if (debugging && STps->eof != ST_NOEOF)
2071 printk(ST_DEB_MSG
2072 "%s: EOF up (%d). Left %d, needed %d.\n", name,
2073 STps->eof, STbp->buffer_bytes,
2074 (int)(count - total));
2075 ) /* end DEB */
2076 transfer = STbp->buffer_bytes < count - total ?
2077 STbp->buffer_bytes : count - total;
2078 if (!do_dio) {
2079 i = from_buffer(STbp, buf, transfer);
2080 if (i) {
2081 retval = i;
2082 goto out;
2083 }
2084 }
2085 buf += transfer;
2086 total += transfer;
2087 }
2088
2089 if (STp->block_size == 0)
2090 break; /* Read only one variable length block */
2091
2092 } /* for (total = 0, special = 0;
2093 total < count && !special; ) */
2094
2095 /* Change the eof state if no data from tape or buffer */
2096 if (total == 0) {
2097 if (STps->eof == ST_FM_HIT) {
2098 STps->eof = ST_FM;
2099 STps->drv_block = 0;
2100 if (STps->drv_file >= 0)
2101 STps->drv_file++;
2102 } else if (STps->eof == ST_EOD_1) {
2103 STps->eof = ST_EOD_2;
2104 STps->drv_block = 0;
2105 if (STps->drv_file >= 0)
2106 STps->drv_file++;
2107 } else if (STps->eof == ST_EOD_2)
2108 STps->eof = ST_EOD;
2109 } else if (STps->eof == ST_FM)
2110 STps->eof = ST_NOEOF;
2111 retval = total;
2112
2113 out:
2114 if (SRpnt != NULL) {
Mike Christie8b05b772005-11-08 04:06:44 -06002115 st_release_request(SRpnt);
Linus Torvalds1da177e2005-04-16 15:20:36 -07002116 SRpnt = NULL;
2117 }
2118 if (do_dio) {
Kai Makisara787926b2005-11-13 10:04:44 +02002119 release_buffering(STp, 1);
Linus Torvalds1da177e2005-04-16 15:20:36 -07002120 STbp->buffer_bytes = 0;
2121 }
Matthias Kaehlcke28f85002007-07-29 23:38:15 +02002122 mutex_unlock(&STp->lock);
Linus Torvalds1da177e2005-04-16 15:20:36 -07002123
2124 return retval;
2125}
2126
2127
2128
2129DEB(
2130/* Set the driver options */
2131static void st_log_options(struct scsi_tape * STp, struct st_modedef * STm, char *name)
2132{
2133 if (debugging) {
2134 printk(KERN_INFO
2135 "%s: Mode %d options: buffer writes: %d, async writes: %d, read ahead: %d\n",
2136 name, STp->current_mode, STm->do_buffer_writes, STm->do_async_writes,
2137 STm->do_read_ahead);
2138 printk(KERN_INFO
2139 "%s: can bsr: %d, two FMs: %d, fast mteom: %d, auto lock: %d,\n",
2140 name, STp->can_bsr, STp->two_fm, STp->fast_mteom, STp->do_auto_lock);
2141 printk(KERN_INFO
2142 "%s: defs for wr: %d, no block limits: %d, partitions: %d, s2 log: %d\n",
2143 name, STm->defaults_for_writes, STp->omit_blklims, STp->can_partitions,
2144 STp->scsi2_logical);
2145 printk(KERN_INFO
Kai Makisara40f6b362008-02-24 22:23:24 +02002146 "%s: sysv: %d nowait: %d sili: %d\n", name, STm->sysv, STp->immediate,
2147 STp->sili);
Linus Torvalds1da177e2005-04-16 15:20:36 -07002148 printk(KERN_INFO "%s: debugging: %d\n",
2149 name, debugging);
2150 }
2151}
2152 )
2153
2154
2155static int st_set_options(struct scsi_tape *STp, long options)
2156{
2157 int value;
2158 long code;
2159 struct st_modedef *STm;
2160 char *name = tape_name(STp);
2161 struct cdev *cd0, *cd1;
2162
2163 STm = &(STp->modes[STp->current_mode]);
2164 if (!STm->defined) {
2165 cd0 = STm->cdevs[0]; cd1 = STm->cdevs[1];
2166 memcpy(STm, &(STp->modes[0]), sizeof(struct st_modedef));
2167 STm->cdevs[0] = cd0; STm->cdevs[1] = cd1;
2168 modes_defined = 1;
2169 DEBC(printk(ST_DEB_MSG
2170 "%s: Initialized mode %d definition from mode 0\n",
2171 name, STp->current_mode));
2172 }
2173
2174 code = options & MT_ST_OPTIONS;
2175 if (code == MT_ST_BOOLEANS) {
2176 STm->do_buffer_writes = (options & MT_ST_BUFFER_WRITES) != 0;
2177 STm->do_async_writes = (options & MT_ST_ASYNC_WRITES) != 0;
2178 STm->defaults_for_writes = (options & MT_ST_DEF_WRITES) != 0;
2179 STm->do_read_ahead = (options & MT_ST_READ_AHEAD) != 0;
2180 STp->two_fm = (options & MT_ST_TWO_FM) != 0;
2181 STp->fast_mteom = (options & MT_ST_FAST_MTEOM) != 0;
2182 STp->do_auto_lock = (options & MT_ST_AUTO_LOCK) != 0;
2183 STp->can_bsr = (options & MT_ST_CAN_BSR) != 0;
2184 STp->omit_blklims = (options & MT_ST_NO_BLKLIMS) != 0;
2185 if ((STp->device)->scsi_level >= SCSI_2)
2186 STp->can_partitions = (options & MT_ST_CAN_PARTITIONS) != 0;
2187 STp->scsi2_logical = (options & MT_ST_SCSI2LOGICAL) != 0;
2188 STp->immediate = (options & MT_ST_NOWAIT) != 0;
2189 STm->sysv = (options & MT_ST_SYSV) != 0;
Kai Makisara40f6b362008-02-24 22:23:24 +02002190 STp->sili = (options & MT_ST_SILI) != 0;
Linus Torvalds1da177e2005-04-16 15:20:36 -07002191 DEB( debugging = (options & MT_ST_DEBUGGING) != 0;
2192 st_log_options(STp, STm, name); )
2193 } else if (code == MT_ST_SETBOOLEANS || code == MT_ST_CLEARBOOLEANS) {
2194 value = (code == MT_ST_SETBOOLEANS);
2195 if ((options & MT_ST_BUFFER_WRITES) != 0)
2196 STm->do_buffer_writes = value;
2197 if ((options & MT_ST_ASYNC_WRITES) != 0)
2198 STm->do_async_writes = value;
2199 if ((options & MT_ST_DEF_WRITES) != 0)
2200 STm->defaults_for_writes = value;
2201 if ((options & MT_ST_READ_AHEAD) != 0)
2202 STm->do_read_ahead = value;
2203 if ((options & MT_ST_TWO_FM) != 0)
2204 STp->two_fm = value;
2205 if ((options & MT_ST_FAST_MTEOM) != 0)
2206 STp->fast_mteom = value;
2207 if ((options & MT_ST_AUTO_LOCK) != 0)
2208 STp->do_auto_lock = value;
2209 if ((options & MT_ST_CAN_BSR) != 0)
2210 STp->can_bsr = value;
2211 if ((options & MT_ST_NO_BLKLIMS) != 0)
2212 STp->omit_blklims = value;
2213 if ((STp->device)->scsi_level >= SCSI_2 &&
2214 (options & MT_ST_CAN_PARTITIONS) != 0)
2215 STp->can_partitions = value;
2216 if ((options & MT_ST_SCSI2LOGICAL) != 0)
2217 STp->scsi2_logical = value;
2218 if ((options & MT_ST_NOWAIT) != 0)
2219 STp->immediate = value;
2220 if ((options & MT_ST_SYSV) != 0)
2221 STm->sysv = value;
Kai Makisara40f6b362008-02-24 22:23:24 +02002222 if ((options & MT_ST_SILI) != 0)
2223 STp->sili = value;
Linus Torvalds1da177e2005-04-16 15:20:36 -07002224 DEB(
2225 if ((options & MT_ST_DEBUGGING) != 0)
2226 debugging = value;
2227 st_log_options(STp, STm, name); )
2228 } else if (code == MT_ST_WRITE_THRESHOLD) {
2229 /* Retained for compatibility */
2230 } else if (code == MT_ST_DEF_BLKSIZE) {
2231 value = (options & ~MT_ST_OPTIONS);
2232 if (value == ~MT_ST_OPTIONS) {
2233 STm->default_blksize = (-1);
2234 DEBC( printk(KERN_INFO "%s: Default block size disabled.\n", name));
2235 } else {
2236 STm->default_blksize = value;
2237 DEBC( printk(KERN_INFO "%s: Default block size set to %d bytes.\n",
2238 name, STm->default_blksize));
2239 if (STp->ready == ST_READY) {
2240 STp->blksize_changed = 0;
2241 set_mode_densblk(STp, STm);
2242 }
2243 }
2244 } else if (code == MT_ST_TIMEOUTS) {
2245 value = (options & ~MT_ST_OPTIONS);
2246 if ((value & MT_ST_SET_LONG_TIMEOUT) != 0) {
2247 STp->long_timeout = (value & ~MT_ST_SET_LONG_TIMEOUT) * HZ;
2248 DEBC( printk(KERN_INFO "%s: Long timeout set to %d seconds.\n", name,
2249 (value & ~MT_ST_SET_LONG_TIMEOUT)));
2250 } else {
James Bottomleya02488e2008-11-30 10:36:26 -06002251 blk_queue_rq_timeout(STp->device->request_queue,
2252 value * HZ);
Linus Torvalds1da177e2005-04-16 15:20:36 -07002253 DEBC( printk(KERN_INFO "%s: Normal timeout set to %d seconds.\n",
2254 name, value) );
2255 }
2256 } else if (code == MT_ST_SET_CLN) {
2257 value = (options & ~MT_ST_OPTIONS) & 0xff;
2258 if (value != 0 &&
2259 value < EXTENDED_SENSE_START && value >= SCSI_SENSE_BUFFERSIZE)
2260 return (-EINVAL);
2261 STp->cln_mode = value;
2262 STp->cln_sense_mask = (options >> 8) & 0xff;
2263 STp->cln_sense_value = (options >> 16) & 0xff;
2264 printk(KERN_INFO
2265 "%s: Cleaning request mode %d, mask %02x, value %02x\n",
2266 name, value, STp->cln_sense_mask, STp->cln_sense_value);
2267 } else if (code == MT_ST_DEF_OPTIONS) {
2268 code = (options & ~MT_ST_CLEAR_DEFAULT);
2269 value = (options & MT_ST_CLEAR_DEFAULT);
2270 if (code == MT_ST_DEF_DENSITY) {
2271 if (value == MT_ST_CLEAR_DEFAULT) {
2272 STm->default_density = (-1);
2273 DEBC( printk(KERN_INFO "%s: Density default disabled.\n",
2274 name));
2275 } else {
2276 STm->default_density = value & 0xff;
2277 DEBC( printk(KERN_INFO "%s: Density default set to %x\n",
2278 name, STm->default_density));
2279 if (STp->ready == ST_READY) {
2280 STp->density_changed = 0;
2281 set_mode_densblk(STp, STm);
2282 }
2283 }
2284 } else if (code == MT_ST_DEF_DRVBUFFER) {
2285 if (value == MT_ST_CLEAR_DEFAULT) {
2286 STp->default_drvbuffer = 0xff;
2287 DEBC( printk(KERN_INFO
2288 "%s: Drive buffer default disabled.\n", name));
2289 } else {
2290 STp->default_drvbuffer = value & 7;
2291 DEBC( printk(KERN_INFO
2292 "%s: Drive buffer default set to %x\n",
2293 name, STp->default_drvbuffer));
2294 if (STp->ready == ST_READY)
2295 st_int_ioctl(STp, MTSETDRVBUFFER, STp->default_drvbuffer);
2296 }
2297 } else if (code == MT_ST_DEF_COMPRESSION) {
2298 if (value == MT_ST_CLEAR_DEFAULT) {
2299 STm->default_compression = ST_DONT_TOUCH;
2300 DEBC( printk(KERN_INFO
2301 "%s: Compression default disabled.\n", name));
2302 } else {
2303 if ((value & 0xff00) != 0) {
2304 STp->c_algo = (value & 0xff00) >> 8;
2305 DEBC( printk(KERN_INFO "%s: Compression algorithm set to 0x%x.\n",
2306 name, STp->c_algo));
2307 }
2308 if ((value & 0xff) != 0xff) {
2309 STm->default_compression = (value & 1 ? ST_YES : ST_NO);
2310 DEBC( printk(KERN_INFO "%s: Compression default set to %x\n",
2311 name, (value & 1)));
2312 if (STp->ready == ST_READY) {
2313 STp->compression_changed = 0;
2314 st_compression(STp, (STm->default_compression == ST_YES));
2315 }
2316 }
2317 }
2318 }
2319 } else
2320 return (-EIO);
2321
2322 return 0;
2323}
2324
2325#define MODE_HEADER_LENGTH 4
2326
2327/* Mode header and page byte offsets */
2328#define MH_OFF_DATA_LENGTH 0
2329#define MH_OFF_MEDIUM_TYPE 1
2330#define MH_OFF_DEV_SPECIFIC 2
2331#define MH_OFF_BDESCS_LENGTH 3
2332#define MP_OFF_PAGE_NBR 0
2333#define MP_OFF_PAGE_LENGTH 1
2334
2335/* Mode header and page bit masks */
2336#define MH_BIT_WP 0x80
2337#define MP_MSK_PAGE_NBR 0x3f
2338
2339/* Don't return block descriptors */
2340#define MODE_SENSE_OMIT_BDESCS 0x08
2341
2342#define MODE_SELECT_PAGE_FORMAT 0x10
2343
2344/* Read a mode page into the tape buffer. The block descriptors are included
2345 if incl_block_descs is true. The page control is ored to the page number
2346 parameter, if necessary. */
2347static int read_mode_page(struct scsi_tape *STp, int page, int omit_block_descs)
2348{
2349 unsigned char cmd[MAX_COMMAND_SIZE];
Mike Christie8b05b772005-11-08 04:06:44 -06002350 struct st_request *SRpnt = NULL;
Linus Torvalds1da177e2005-04-16 15:20:36 -07002351
2352 memset(cmd, 0, MAX_COMMAND_SIZE);
2353 cmd[0] = MODE_SENSE;
2354 if (omit_block_descs)
2355 cmd[1] = MODE_SENSE_OMIT_BDESCS;
2356 cmd[2] = page;
2357 cmd[4] = 255;
2358
2359 SRpnt = st_do_scsi(SRpnt, STp, cmd, cmd[4], DMA_FROM_DEVICE,
James Bottomleya02488e2008-11-30 10:36:26 -06002360 STp->device->request_queue->rq_timeout, 0, 1);
Linus Torvalds1da177e2005-04-16 15:20:36 -07002361 if (SRpnt == NULL)
2362 return (STp->buffer)->syscall_result;
2363
Mike Christie8b05b772005-11-08 04:06:44 -06002364 st_release_request(SRpnt);
Linus Torvalds1da177e2005-04-16 15:20:36 -07002365
2366 return (STp->buffer)->syscall_result;
2367}
2368
2369
2370/* Send the mode page in the tape buffer to the drive. Assumes that the mode data
2371 in the buffer is correctly formatted. The long timeout is used if slow is non-zero. */
2372static int write_mode_page(struct scsi_tape *STp, int page, int slow)
2373{
2374 int pgo;
2375 unsigned char cmd[MAX_COMMAND_SIZE];
Mike Christie8b05b772005-11-08 04:06:44 -06002376 struct st_request *SRpnt = NULL;
Linus Torvalds1da177e2005-04-16 15:20:36 -07002377
2378 memset(cmd, 0, MAX_COMMAND_SIZE);
2379 cmd[0] = MODE_SELECT;
2380 cmd[1] = MODE_SELECT_PAGE_FORMAT;
2381 pgo = MODE_HEADER_LENGTH + (STp->buffer)->b_data[MH_OFF_BDESCS_LENGTH];
2382 cmd[4] = pgo + (STp->buffer)->b_data[pgo + MP_OFF_PAGE_LENGTH] + 2;
2383
2384 /* Clear reserved fields */
2385 (STp->buffer)->b_data[MH_OFF_DATA_LENGTH] = 0;
2386 (STp->buffer)->b_data[MH_OFF_MEDIUM_TYPE] = 0;
2387 (STp->buffer)->b_data[MH_OFF_DEV_SPECIFIC] &= ~MH_BIT_WP;
2388 (STp->buffer)->b_data[pgo + MP_OFF_PAGE_NBR] &= MP_MSK_PAGE_NBR;
2389
2390 SRpnt = st_do_scsi(SRpnt, STp, cmd, cmd[4], DMA_TO_DEVICE,
James Bottomleya02488e2008-11-30 10:36:26 -06002391 (slow ? STp->long_timeout : STp->device->request_queue->rq_timeout), 0, 1);
Linus Torvalds1da177e2005-04-16 15:20:36 -07002392 if (SRpnt == NULL)
2393 return (STp->buffer)->syscall_result;
2394
Mike Christie8b05b772005-11-08 04:06:44 -06002395 st_release_request(SRpnt);
Linus Torvalds1da177e2005-04-16 15:20:36 -07002396
2397 return (STp->buffer)->syscall_result;
2398}
2399
2400
2401#define COMPRESSION_PAGE 0x0f
2402#define COMPRESSION_PAGE_LENGTH 16
2403
2404#define CP_OFF_DCE_DCC 2
2405#define CP_OFF_C_ALGO 7
2406
2407#define DCE_MASK 0x80
2408#define DCC_MASK 0x40
2409#define RED_MASK 0x60
2410
2411
2412/* Control the compression with mode page 15. Algorithm not changed if zero.
2413
2414 The block descriptors are read and written because Sony SDT-7000 does not
2415 work without this (suggestion from Michael Schaefer <Michael.Schaefer@dlr.de>).
2416 Including block descriptors should not cause any harm to other drives. */
2417
2418static int st_compression(struct scsi_tape * STp, int state)
2419{
2420 int retval;
2421 int mpoffs; /* Offset to mode page start */
2422 unsigned char *b_data = (STp->buffer)->b_data;
2423 DEB( char *name = tape_name(STp); )
2424
2425 if (STp->ready != ST_READY)
2426 return (-EIO);
2427
2428 /* Read the current page contents */
2429 retval = read_mode_page(STp, COMPRESSION_PAGE, 0);
2430 if (retval) {
2431 DEBC(printk(ST_DEB_MSG "%s: Compression mode page not supported.\n",
2432 name));
2433 return (-EIO);
2434 }
2435
2436 mpoffs = MODE_HEADER_LENGTH + b_data[MH_OFF_BDESCS_LENGTH];
2437 DEBC(printk(ST_DEB_MSG "%s: Compression state is %d.\n", name,
2438 (b_data[mpoffs + CP_OFF_DCE_DCC] & DCE_MASK ? 1 : 0)));
2439
2440 /* Check if compression can be changed */
2441 if ((b_data[mpoffs + CP_OFF_DCE_DCC] & DCC_MASK) == 0) {
2442 DEBC(printk(ST_DEB_MSG "%s: Compression not supported.\n", name));
2443 return (-EIO);
2444 }
2445
2446 /* Do the change */
2447 if (state) {
2448 b_data[mpoffs + CP_OFF_DCE_DCC] |= DCE_MASK;
2449 if (STp->c_algo != 0)
2450 b_data[mpoffs + CP_OFF_C_ALGO] = STp->c_algo;
2451 }
2452 else {
2453 b_data[mpoffs + CP_OFF_DCE_DCC] &= ~DCE_MASK;
2454 if (STp->c_algo != 0)
2455 b_data[mpoffs + CP_OFF_C_ALGO] = 0; /* no compression */
2456 }
2457
2458 retval = write_mode_page(STp, COMPRESSION_PAGE, 0);
2459 if (retval) {
2460 DEBC(printk(ST_DEB_MSG "%s: Compression change failed.\n", name));
2461 return (-EIO);
2462 }
2463 DEBC(printk(ST_DEB_MSG "%s: Compression state changed to %d.\n",
2464 name, state));
2465
2466 STp->compression_changed = 1;
2467 return 0;
2468}
2469
2470
2471/* Process the load and unload commands (does unload if the load code is zero) */
2472static int do_load_unload(struct scsi_tape *STp, struct file *filp, int load_code)
2473{
2474 int retval = (-EIO), timeout;
2475 DEB( char *name = tape_name(STp); )
2476 unsigned char cmd[MAX_COMMAND_SIZE];
2477 struct st_partstat *STps;
Mike Christie8b05b772005-11-08 04:06:44 -06002478 struct st_request *SRpnt;
Linus Torvalds1da177e2005-04-16 15:20:36 -07002479
2480 if (STp->ready != ST_READY && !load_code) {
2481 if (STp->ready == ST_NO_TAPE)
2482 return (-ENOMEDIUM);
2483 else
2484 return (-EIO);
2485 }
2486
2487 memset(cmd, 0, MAX_COMMAND_SIZE);
2488 cmd[0] = START_STOP;
2489 if (load_code)
2490 cmd[4] |= 1;
2491 /*
2492 * If arg >= 1 && arg <= 6 Enhanced load/unload in HP C1553A
2493 */
2494 if (load_code >= 1 + MT_ST_HPLOADER_OFFSET
2495 && load_code <= 6 + MT_ST_HPLOADER_OFFSET) {
2496 DEBC(printk(ST_DEB_MSG "%s: Enhanced %sload slot %2d.\n",
2497 name, (cmd[4]) ? "" : "un",
2498 load_code - MT_ST_HPLOADER_OFFSET));
2499 cmd[3] = load_code - MT_ST_HPLOADER_OFFSET; /* MediaID field of C1553A */
2500 }
2501 if (STp->immediate) {
2502 cmd[1] = 1; /* Don't wait for completion */
James Bottomleya02488e2008-11-30 10:36:26 -06002503 timeout = STp->device->request_queue->rq_timeout;
Linus Torvalds1da177e2005-04-16 15:20:36 -07002504 }
2505 else
2506 timeout = STp->long_timeout;
2507
2508 DEBC(
2509 if (!load_code)
2510 printk(ST_DEB_MSG "%s: Unloading tape.\n", name);
2511 else
2512 printk(ST_DEB_MSG "%s: Loading tape.\n", name);
2513 );
2514
2515 SRpnt = st_do_scsi(NULL, STp, cmd, 0, DMA_NONE,
2516 timeout, MAX_RETRIES, 1);
2517 if (!SRpnt)
2518 return (STp->buffer)->syscall_result;
2519
2520 retval = (STp->buffer)->syscall_result;
Mike Christie8b05b772005-11-08 04:06:44 -06002521 st_release_request(SRpnt);
Linus Torvalds1da177e2005-04-16 15:20:36 -07002522
2523 if (!retval) { /* SCSI command successful */
2524
2525 if (!load_code) {
2526 STp->rew_at_close = 0;
2527 STp->ready = ST_NO_TAPE;
2528 }
2529 else {
2530 STp->rew_at_close = STp->autorew_dev;
2531 retval = check_tape(STp, filp);
2532 if (retval > 0)
2533 retval = 0;
2534 }
2535 }
2536 else {
2537 STps = &(STp->ps[STp->partition]);
2538 STps->drv_file = STps->drv_block = (-1);
2539 }
2540
2541 return retval;
2542}
2543
2544#if DEBUG
2545#define ST_DEB_FORWARD 0
2546#define ST_DEB_BACKWARD 1
2547static void deb_space_print(char *name, int direction, char *units, unsigned char *cmd)
2548{
2549 s32 sc;
2550
2551 sc = cmd[2] & 0x80 ? 0xff000000 : 0;
2552 sc |= (cmd[2] << 16) | (cmd[3] << 8) | cmd[4];
2553 if (direction)
2554 sc = -sc;
2555 printk(ST_DEB_MSG "%s: Spacing tape %s over %d %s.\n", name,
2556 direction ? "backward" : "forward", sc, units);
2557}
2558#endif
2559
2560
2561/* Internal ioctl function */
2562static int st_int_ioctl(struct scsi_tape *STp, unsigned int cmd_in, unsigned long arg)
2563{
2564 int timeout;
2565 long ltmp;
2566 int ioctl_result;
2567 int chg_eof = 1;
2568 unsigned char cmd[MAX_COMMAND_SIZE];
Mike Christie8b05b772005-11-08 04:06:44 -06002569 struct st_request *SRpnt;
Linus Torvalds1da177e2005-04-16 15:20:36 -07002570 struct st_partstat *STps;
2571 int fileno, blkno, at_sm, undone;
2572 int datalen = 0, direction = DMA_NONE;
2573 char *name = tape_name(STp);
2574
2575 WARN_ON(STp->buffer->do_dio != 0);
2576 if (STp->ready != ST_READY) {
2577 if (STp->ready == ST_NO_TAPE)
2578 return (-ENOMEDIUM);
2579 else
2580 return (-EIO);
2581 }
2582 timeout = STp->long_timeout;
2583 STps = &(STp->ps[STp->partition]);
2584 fileno = STps->drv_file;
2585 blkno = STps->drv_block;
2586 at_sm = STps->at_sm;
2587
2588 memset(cmd, 0, MAX_COMMAND_SIZE);
2589 switch (cmd_in) {
2590 case MTFSFM:
2591 chg_eof = 0; /* Changed from the FSF after this */
2592 case MTFSF:
2593 cmd[0] = SPACE;
2594 cmd[1] = 0x01; /* Space FileMarks */
2595 cmd[2] = (arg >> 16);
2596 cmd[3] = (arg >> 8);
2597 cmd[4] = arg;
2598 DEBC(deb_space_print(name, ST_DEB_FORWARD, "filemarks", cmd);)
2599 if (fileno >= 0)
2600 fileno += arg;
2601 blkno = 0;
2602 at_sm &= (arg == 0);
2603 break;
2604 case MTBSFM:
2605 chg_eof = 0; /* Changed from the FSF after this */
2606 case MTBSF:
2607 cmd[0] = SPACE;
2608 cmd[1] = 0x01; /* Space FileMarks */
2609 ltmp = (-arg);
2610 cmd[2] = (ltmp >> 16);
2611 cmd[3] = (ltmp >> 8);
2612 cmd[4] = ltmp;
2613 DEBC(deb_space_print(name, ST_DEB_BACKWARD, "filemarks", cmd);)
2614 if (fileno >= 0)
2615 fileno -= arg;
2616 blkno = (-1); /* We can't know the block number */
2617 at_sm &= (arg == 0);
2618 break;
2619 case MTFSR:
2620 cmd[0] = SPACE;
2621 cmd[1] = 0x00; /* Space Blocks */
2622 cmd[2] = (arg >> 16);
2623 cmd[3] = (arg >> 8);
2624 cmd[4] = arg;
2625 DEBC(deb_space_print(name, ST_DEB_FORWARD, "blocks", cmd);)
2626 if (blkno >= 0)
2627 blkno += arg;
2628 at_sm &= (arg == 0);
2629 break;
2630 case MTBSR:
2631 cmd[0] = SPACE;
2632 cmd[1] = 0x00; /* Space Blocks */
2633 ltmp = (-arg);
2634 cmd[2] = (ltmp >> 16);
2635 cmd[3] = (ltmp >> 8);
2636 cmd[4] = ltmp;
2637 DEBC(deb_space_print(name, ST_DEB_BACKWARD, "blocks", cmd);)
2638 if (blkno >= 0)
2639 blkno -= arg;
2640 at_sm &= (arg == 0);
2641 break;
2642 case MTFSS:
2643 cmd[0] = SPACE;
2644 cmd[1] = 0x04; /* Space Setmarks */
2645 cmd[2] = (arg >> 16);
2646 cmd[3] = (arg >> 8);
2647 cmd[4] = arg;
2648 DEBC(deb_space_print(name, ST_DEB_FORWARD, "setmarks", cmd);)
2649 if (arg != 0) {
2650 blkno = fileno = (-1);
2651 at_sm = 1;
2652 }
2653 break;
2654 case MTBSS:
2655 cmd[0] = SPACE;
2656 cmd[1] = 0x04; /* Space Setmarks */
2657 ltmp = (-arg);
2658 cmd[2] = (ltmp >> 16);
2659 cmd[3] = (ltmp >> 8);
2660 cmd[4] = ltmp;
2661 DEBC(deb_space_print(name, ST_DEB_BACKWARD, "setmarks", cmd);)
2662 if (arg != 0) {
2663 blkno = fileno = (-1);
2664 at_sm = 1;
2665 }
2666 break;
2667 case MTWEOF:
2668 case MTWSM:
2669 if (STp->write_prot)
2670 return (-EACCES);
2671 cmd[0] = WRITE_FILEMARKS;
2672 if (cmd_in == MTWSM)
2673 cmd[1] = 2;
2674 cmd[2] = (arg >> 16);
2675 cmd[3] = (arg >> 8);
2676 cmd[4] = arg;
James Bottomleya02488e2008-11-30 10:36:26 -06002677 timeout = STp->device->request_queue->rq_timeout;
Linus Torvalds1da177e2005-04-16 15:20:36 -07002678 DEBC(
2679 if (cmd_in == MTWEOF)
2680 printk(ST_DEB_MSG "%s: Writing %d filemarks.\n", name,
2681 cmd[2] * 65536 + cmd[3] * 256 + cmd[4]);
2682 else
2683 printk(ST_DEB_MSG "%s: Writing %d setmarks.\n", name,
2684 cmd[2] * 65536 + cmd[3] * 256 + cmd[4]);
2685 )
2686 if (fileno >= 0)
2687 fileno += arg;
2688 blkno = 0;
2689 at_sm = (cmd_in == MTWSM);
2690 break;
2691 case MTREW:
2692 cmd[0] = REZERO_UNIT;
2693 if (STp->immediate) {
2694 cmd[1] = 1; /* Don't wait for completion */
James Bottomleya02488e2008-11-30 10:36:26 -06002695 timeout = STp->device->request_queue->rq_timeout;
Linus Torvalds1da177e2005-04-16 15:20:36 -07002696 }
2697 DEBC(printk(ST_DEB_MSG "%s: Rewinding tape.\n", name));
2698 fileno = blkno = at_sm = 0;
2699 break;
2700 case MTNOP:
2701 DEBC(printk(ST_DEB_MSG "%s: No op on tape.\n", name));
2702 return 0; /* Should do something ? */
2703 break;
2704 case MTRETEN:
2705 cmd[0] = START_STOP;
2706 if (STp->immediate) {
2707 cmd[1] = 1; /* Don't wait for completion */
James Bottomleya02488e2008-11-30 10:36:26 -06002708 timeout = STp->device->request_queue->rq_timeout;
Linus Torvalds1da177e2005-04-16 15:20:36 -07002709 }
2710 cmd[4] = 3;
2711 DEBC(printk(ST_DEB_MSG "%s: Retensioning tape.\n", name));
2712 fileno = blkno = at_sm = 0;
2713 break;
2714 case MTEOM:
2715 if (!STp->fast_mteom) {
2716 /* space to the end of tape */
2717 ioctl_result = st_int_ioctl(STp, MTFSF, 0x7fffff);
2718 fileno = STps->drv_file;
2719 if (STps->eof >= ST_EOD_1)
2720 return 0;
2721 /* The next lines would hide the number of spaced FileMarks
2722 That's why I inserted the previous lines. I had no luck
2723 with detecting EOM with FSF, so we go now to EOM.
2724 Joerg Weule */
2725 } else
2726 fileno = (-1);
2727 cmd[0] = SPACE;
2728 cmd[1] = 3;
2729 DEBC(printk(ST_DEB_MSG "%s: Spacing to end of recorded medium.\n",
2730 name));
2731 blkno = -1;
2732 at_sm = 0;
2733 break;
2734 case MTERASE:
2735 if (STp->write_prot)
2736 return (-EACCES);
2737 cmd[0] = ERASE;
2738 cmd[1] = (arg ? 1 : 0); /* Long erase with non-zero argument */
2739 if (STp->immediate) {
2740 cmd[1] |= 2; /* Don't wait for completion */
James Bottomleya02488e2008-11-30 10:36:26 -06002741 timeout = STp->device->request_queue->rq_timeout;
Linus Torvalds1da177e2005-04-16 15:20:36 -07002742 }
2743 else
2744 timeout = STp->long_timeout * 8;
2745
2746 DEBC(printk(ST_DEB_MSG "%s: Erasing tape.\n", name));
2747 fileno = blkno = at_sm = 0;
2748 break;
2749 case MTSETBLK: /* Set block length */
2750 case MTSETDENSITY: /* Set tape density */
2751 case MTSETDRVBUFFER: /* Set drive buffering */
2752 case SET_DENS_AND_BLK: /* Set density and block size */
2753 chg_eof = 0;
2754 if (STp->dirty || (STp->buffer)->buffer_bytes != 0)
2755 return (-EIO); /* Not allowed if data in buffer */
2756 if ((cmd_in == MTSETBLK || cmd_in == SET_DENS_AND_BLK) &&
2757 (arg & MT_ST_BLKSIZE_MASK) != 0 &&
2758 STp->max_block > 0 &&
2759 ((arg & MT_ST_BLKSIZE_MASK) < STp->min_block ||
2760 (arg & MT_ST_BLKSIZE_MASK) > STp->max_block)) {
2761 printk(KERN_WARNING "%s: Illegal block size.\n", name);
2762 return (-EINVAL);
2763 }
2764 cmd[0] = MODE_SELECT;
2765 if ((STp->use_pf & USE_PF))
2766 cmd[1] = MODE_SELECT_PAGE_FORMAT;
2767 cmd[4] = datalen = 12;
2768 direction = DMA_TO_DEVICE;
2769
2770 memset((STp->buffer)->b_data, 0, 12);
2771 if (cmd_in == MTSETDRVBUFFER)
2772 (STp->buffer)->b_data[2] = (arg & 7) << 4;
2773 else
2774 (STp->buffer)->b_data[2] =
2775 STp->drv_buffer << 4;
2776 (STp->buffer)->b_data[3] = 8; /* block descriptor length */
2777 if (cmd_in == MTSETDENSITY) {
2778 (STp->buffer)->b_data[4] = arg;
2779 STp->density_changed = 1; /* At least we tried ;-) */
2780 } else if (cmd_in == SET_DENS_AND_BLK)
2781 (STp->buffer)->b_data[4] = arg >> 24;
2782 else
2783 (STp->buffer)->b_data[4] = STp->density;
2784 if (cmd_in == MTSETBLK || cmd_in == SET_DENS_AND_BLK) {
2785 ltmp = arg & MT_ST_BLKSIZE_MASK;
2786 if (cmd_in == MTSETBLK)
2787 STp->blksize_changed = 1; /* At least we tried ;-) */
2788 } else
2789 ltmp = STp->block_size;
2790 (STp->buffer)->b_data[9] = (ltmp >> 16);
2791 (STp->buffer)->b_data[10] = (ltmp >> 8);
2792 (STp->buffer)->b_data[11] = ltmp;
James Bottomleya02488e2008-11-30 10:36:26 -06002793 timeout = STp->device->request_queue->rq_timeout;
Linus Torvalds1da177e2005-04-16 15:20:36 -07002794 DEBC(
2795 if (cmd_in == MTSETBLK || cmd_in == SET_DENS_AND_BLK)
2796 printk(ST_DEB_MSG
2797 "%s: Setting block size to %d bytes.\n", name,
2798 (STp->buffer)->b_data[9] * 65536 +
2799 (STp->buffer)->b_data[10] * 256 +
2800 (STp->buffer)->b_data[11]);
2801 if (cmd_in == MTSETDENSITY || cmd_in == SET_DENS_AND_BLK)
2802 printk(ST_DEB_MSG
2803 "%s: Setting density code to %x.\n", name,
2804 (STp->buffer)->b_data[4]);
2805 if (cmd_in == MTSETDRVBUFFER)
2806 printk(ST_DEB_MSG
2807 "%s: Setting drive buffer code to %d.\n", name,
2808 ((STp->buffer)->b_data[2] >> 4) & 7);
2809 )
2810 break;
2811 default:
2812 return (-ENOSYS);
2813 }
2814
2815 SRpnt = st_do_scsi(NULL, STp, cmd, datalen, direction,
2816 timeout, MAX_RETRIES, 1);
2817 if (!SRpnt)
2818 return (STp->buffer)->syscall_result;
2819
2820 ioctl_result = (STp->buffer)->syscall_result;
2821
2822 if (!ioctl_result) { /* SCSI command successful */
Mike Christie8b05b772005-11-08 04:06:44 -06002823 st_release_request(SRpnt);
Linus Torvalds1da177e2005-04-16 15:20:36 -07002824 SRpnt = NULL;
2825 STps->drv_block = blkno;
2826 STps->drv_file = fileno;
2827 STps->at_sm = at_sm;
2828
2829 if (cmd_in == MTBSFM)
2830 ioctl_result = st_int_ioctl(STp, MTFSF, 1);
2831 else if (cmd_in == MTFSFM)
2832 ioctl_result = st_int_ioctl(STp, MTBSF, 1);
2833
2834 if (cmd_in == MTSETBLK || cmd_in == SET_DENS_AND_BLK) {
2835 int old_block_size = STp->block_size;
2836 STp->block_size = arg & MT_ST_BLKSIZE_MASK;
2837 if (STp->block_size != 0) {
2838 if (old_block_size == 0)
2839 normalize_buffer(STp->buffer);
2840 (STp->buffer)->buffer_blocks =
2841 (STp->buffer)->buffer_size / STp->block_size;
2842 }
2843 (STp->buffer)->buffer_bytes = (STp->buffer)->read_pointer = 0;
2844 if (cmd_in == SET_DENS_AND_BLK)
2845 STp->density = arg >> MT_ST_DENSITY_SHIFT;
2846 } else if (cmd_in == MTSETDRVBUFFER)
2847 STp->drv_buffer = (arg & 7);
2848 else if (cmd_in == MTSETDENSITY)
2849 STp->density = arg;
2850
2851 if (cmd_in == MTEOM)
2852 STps->eof = ST_EOD;
2853 else if (cmd_in == MTFSF)
2854 STps->eof = ST_FM;
2855 else if (chg_eof)
2856 STps->eof = ST_NOEOF;
2857
2858 if (cmd_in == MTWEOF)
2859 STps->rw = ST_IDLE;
2860 } else { /* SCSI command was not completely successful. Don't return
2861 from this block without releasing the SCSI command block! */
2862 struct st_cmdstatus *cmdstatp = &STp->buffer->cmdstat;
2863
2864 if (cmdstatp->flags & SENSE_EOM) {
2865 if (cmd_in != MTBSF && cmd_in != MTBSFM &&
2866 cmd_in != MTBSR && cmd_in != MTBSS)
2867 STps->eof = ST_EOM_OK;
2868 STps->drv_block = 0;
2869 }
2870
2871 if (cmdstatp->remainder_valid)
2872 undone = (int)cmdstatp->uremainder64;
2873 else
2874 undone = 0;
2875
2876 if (cmd_in == MTWEOF &&
2877 cmdstatp->have_sense &&
Kai Makisara91614c02007-01-26 00:38:39 +02002878 (cmdstatp->flags & SENSE_EOM)) {
2879 if (cmdstatp->sense_hdr.sense_key == NO_SENSE ||
2880 cmdstatp->sense_hdr.sense_key == RECOVERED_ERROR) {
2881 ioctl_result = 0; /* EOF(s) written successfully at EOM */
2882 STps->eof = ST_NOEOF;
2883 } else { /* Writing EOF(s) failed */
2884 if (fileno >= 0)
2885 fileno -= undone;
2886 if (undone < arg)
2887 STps->eof = ST_NOEOF;
2888 }
Linus Torvalds1da177e2005-04-16 15:20:36 -07002889 STps->drv_file = fileno;
Linus Torvalds1da177e2005-04-16 15:20:36 -07002890 } else if ((cmd_in == MTFSF) || (cmd_in == MTFSFM)) {
2891 if (fileno >= 0)
2892 STps->drv_file = fileno - undone;
2893 else
2894 STps->drv_file = fileno;
2895 STps->drv_block = -1;
2896 STps->eof = ST_NOEOF;
2897 } else if ((cmd_in == MTBSF) || (cmd_in == MTBSFM)) {
2898 if (arg > 0 && undone < 0) /* Some drives get this wrong */
2899 undone = (-undone);
2900 if (STps->drv_file >= 0)
2901 STps->drv_file = fileno + undone;
2902 STps->drv_block = 0;
2903 STps->eof = ST_NOEOF;
2904 } else if (cmd_in == MTFSR) {
2905 if (cmdstatp->flags & SENSE_FMK) { /* Hit filemark */
2906 if (STps->drv_file >= 0)
2907 STps->drv_file++;
2908 STps->drv_block = 0;
2909 STps->eof = ST_FM;
2910 } else {
2911 if (blkno >= undone)
2912 STps->drv_block = blkno - undone;
2913 else
2914 STps->drv_block = (-1);
2915 STps->eof = ST_NOEOF;
2916 }
2917 } else if (cmd_in == MTBSR) {
2918 if (cmdstatp->flags & SENSE_FMK) { /* Hit filemark */
2919 STps->drv_file--;
2920 STps->drv_block = (-1);
2921 } else {
2922 if (arg > 0 && undone < 0) /* Some drives get this wrong */
2923 undone = (-undone);
2924 if (STps->drv_block >= 0)
2925 STps->drv_block = blkno + undone;
2926 }
2927 STps->eof = ST_NOEOF;
2928 } else if (cmd_in == MTEOM) {
2929 STps->drv_file = (-1);
2930 STps->drv_block = (-1);
2931 STps->eof = ST_EOD;
2932 } else if (cmd_in == MTSETBLK ||
2933 cmd_in == MTSETDENSITY ||
2934 cmd_in == MTSETDRVBUFFER ||
2935 cmd_in == SET_DENS_AND_BLK) {
2936 if (cmdstatp->sense_hdr.sense_key == ILLEGAL_REQUEST &&
2937 !(STp->use_pf & PF_TESTED)) {
2938 /* Try the other possible state of Page Format if not
2939 already tried */
2940 STp->use_pf = !STp->use_pf | PF_TESTED;
Mike Christie8b05b772005-11-08 04:06:44 -06002941 st_release_request(SRpnt);
Linus Torvalds1da177e2005-04-16 15:20:36 -07002942 SRpnt = NULL;
2943 return st_int_ioctl(STp, cmd_in, arg);
2944 }
2945 } else if (chg_eof)
2946 STps->eof = ST_NOEOF;
2947
2948 if (cmdstatp->sense_hdr.sense_key == BLANK_CHECK)
2949 STps->eof = ST_EOD;
2950
Mike Christie8b05b772005-11-08 04:06:44 -06002951 st_release_request(SRpnt);
Linus Torvalds1da177e2005-04-16 15:20:36 -07002952 SRpnt = NULL;
2953 }
2954
2955 return ioctl_result;
2956}
2957
2958
2959/* Get the tape position. If bt == 2, arg points into a kernel space mt_loc
2960 structure. */
2961
2962static int get_location(struct scsi_tape *STp, unsigned int *block, int *partition,
2963 int logical)
2964{
2965 int result;
2966 unsigned char scmd[MAX_COMMAND_SIZE];
Mike Christie8b05b772005-11-08 04:06:44 -06002967 struct st_request *SRpnt;
Linus Torvalds1da177e2005-04-16 15:20:36 -07002968 DEB( char *name = tape_name(STp); )
2969
2970 if (STp->ready != ST_READY)
2971 return (-EIO);
2972
2973 memset(scmd, 0, MAX_COMMAND_SIZE);
2974 if ((STp->device)->scsi_level < SCSI_2) {
2975 scmd[0] = QFA_REQUEST_BLOCK;
2976 scmd[4] = 3;
2977 } else {
2978 scmd[0] = READ_POSITION;
2979 if (!logical && !STp->scsi2_logical)
2980 scmd[1] = 1;
2981 }
2982 SRpnt = st_do_scsi(NULL, STp, scmd, 20, DMA_FROM_DEVICE,
James Bottomleya02488e2008-11-30 10:36:26 -06002983 STp->device->request_queue->rq_timeout,
2984 MAX_READY_RETRIES, 1);
Linus Torvalds1da177e2005-04-16 15:20:36 -07002985 if (!SRpnt)
2986 return (STp->buffer)->syscall_result;
2987
2988 if ((STp->buffer)->syscall_result != 0 ||
2989 (STp->device->scsi_level >= SCSI_2 &&
2990 ((STp->buffer)->b_data[0] & 4) != 0)) {
2991 *block = *partition = 0;
2992 DEBC(printk(ST_DEB_MSG "%s: Can't read tape position.\n", name));
2993 result = (-EIO);
2994 } else {
2995 result = 0;
2996 if ((STp->device)->scsi_level < SCSI_2) {
2997 *block = ((STp->buffer)->b_data[0] << 16)
2998 + ((STp->buffer)->b_data[1] << 8)
2999 + (STp->buffer)->b_data[2];
3000 *partition = 0;
3001 } else {
3002 *block = ((STp->buffer)->b_data[4] << 24)
3003 + ((STp->buffer)->b_data[5] << 16)
3004 + ((STp->buffer)->b_data[6] << 8)
3005 + (STp->buffer)->b_data[7];
3006 *partition = (STp->buffer)->b_data[1];
3007 if (((STp->buffer)->b_data[0] & 0x80) &&
3008 (STp->buffer)->b_data[1] == 0) /* BOP of partition 0 */
3009 STp->ps[0].drv_block = STp->ps[0].drv_file = 0;
3010 }
3011 DEBC(printk(ST_DEB_MSG "%s: Got tape pos. blk %d part %d.\n", name,
3012 *block, *partition));
3013 }
Mike Christie8b05b772005-11-08 04:06:44 -06003014 st_release_request(SRpnt);
Linus Torvalds1da177e2005-04-16 15:20:36 -07003015 SRpnt = NULL;
3016
3017 return result;
3018}
3019
3020
3021/* Set the tape block and partition. Negative partition means that only the
3022 block should be set in vendor specific way. */
3023static int set_location(struct scsi_tape *STp, unsigned int block, int partition,
3024 int logical)
3025{
3026 struct st_partstat *STps;
3027 int result, p;
3028 unsigned int blk;
3029 int timeout;
3030 unsigned char scmd[MAX_COMMAND_SIZE];
Mike Christie8b05b772005-11-08 04:06:44 -06003031 struct st_request *SRpnt;
Linus Torvalds1da177e2005-04-16 15:20:36 -07003032 DEB( char *name = tape_name(STp); )
3033
3034 if (STp->ready != ST_READY)
3035 return (-EIO);
3036 timeout = STp->long_timeout;
3037 STps = &(STp->ps[STp->partition]);
3038
3039 DEBC(printk(ST_DEB_MSG "%s: Setting block to %d and partition to %d.\n",
3040 name, block, partition));
3041 DEB(if (partition < 0)
3042 return (-EIO); )
3043
3044 /* Update the location at the partition we are leaving */
3045 if ((!STp->can_partitions && partition != 0) ||
3046 partition >= ST_NBR_PARTITIONS)
3047 return (-EINVAL);
3048 if (partition != STp->partition) {
3049 if (get_location(STp, &blk, &p, 1))
3050 STps->last_block_valid = 0;
3051 else {
3052 STps->last_block_valid = 1;
3053 STps->last_block_visited = blk;
3054 DEBC(printk(ST_DEB_MSG
3055 "%s: Visited block %d for partition %d saved.\n",
3056 name, blk, STp->partition));
3057 }
3058 }
3059
3060 memset(scmd, 0, MAX_COMMAND_SIZE);
3061 if ((STp->device)->scsi_level < SCSI_2) {
3062 scmd[0] = QFA_SEEK_BLOCK;
3063 scmd[2] = (block >> 16);
3064 scmd[3] = (block >> 8);
3065 scmd[4] = block;
3066 scmd[5] = 0;
3067 } else {
3068 scmd[0] = SEEK_10;
3069 scmd[3] = (block >> 24);
3070 scmd[4] = (block >> 16);
3071 scmd[5] = (block >> 8);
3072 scmd[6] = block;
3073 if (!logical && !STp->scsi2_logical)
3074 scmd[1] = 4;
3075 if (STp->partition != partition) {
3076 scmd[1] |= 2;
3077 scmd[8] = partition;
3078 DEBC(printk(ST_DEB_MSG
3079 "%s: Trying to change partition from %d to %d\n",
3080 name, STp->partition, partition));
3081 }
3082 }
3083 if (STp->immediate) {
3084 scmd[1] |= 1; /* Don't wait for completion */
James Bottomleya02488e2008-11-30 10:36:26 -06003085 timeout = STp->device->request_queue->rq_timeout;
Linus Torvalds1da177e2005-04-16 15:20:36 -07003086 }
3087
3088 SRpnt = st_do_scsi(NULL, STp, scmd, 0, DMA_NONE,
3089 timeout, MAX_READY_RETRIES, 1);
3090 if (!SRpnt)
3091 return (STp->buffer)->syscall_result;
3092
3093 STps->drv_block = STps->drv_file = (-1);
3094 STps->eof = ST_NOEOF;
3095 if ((STp->buffer)->syscall_result != 0) {
3096 result = (-EIO);
3097 if (STp->can_partitions &&
3098 (STp->device)->scsi_level >= SCSI_2 &&
3099 (p = find_partition(STp)) >= 0)
3100 STp->partition = p;
3101 } else {
3102 if (STp->can_partitions) {
3103 STp->partition = partition;
3104 STps = &(STp->ps[partition]);
3105 if (!STps->last_block_valid ||
3106 STps->last_block_visited != block) {
3107 STps->at_sm = 0;
3108 STps->rw = ST_IDLE;
3109 }
3110 } else
3111 STps->at_sm = 0;
3112 if (block == 0)
3113 STps->drv_block = STps->drv_file = 0;
3114 result = 0;
3115 }
3116
Mike Christie8b05b772005-11-08 04:06:44 -06003117 st_release_request(SRpnt);
Linus Torvalds1da177e2005-04-16 15:20:36 -07003118 SRpnt = NULL;
3119
3120 return result;
3121}
3122
3123
3124/* Find the current partition number for the drive status. Called from open and
3125 returns either partition number of negative error code. */
3126static int find_partition(struct scsi_tape *STp)
3127{
3128 int i, partition;
3129 unsigned int block;
3130
3131 if ((i = get_location(STp, &block, &partition, 1)) < 0)
3132 return i;
3133 if (partition >= ST_NBR_PARTITIONS)
3134 return (-EIO);
3135 return partition;
3136}
3137
3138
3139/* Change the partition if necessary */
3140static int switch_partition(struct scsi_tape *STp)
3141{
3142 struct st_partstat *STps;
3143
3144 if (STp->partition == STp->new_partition)
3145 return 0;
3146 STps = &(STp->ps[STp->new_partition]);
3147 if (!STps->last_block_valid)
3148 STps->last_block_visited = 0;
3149 return set_location(STp, STps->last_block_visited, STp->new_partition, 1);
3150}
3151
3152/* Functions for reading and writing the medium partition mode page. */
3153
3154#define PART_PAGE 0x11
3155#define PART_PAGE_FIXED_LENGTH 8
3156
3157#define PP_OFF_MAX_ADD_PARTS 2
3158#define PP_OFF_NBR_ADD_PARTS 3
3159#define PP_OFF_FLAGS 4
3160#define PP_OFF_PART_UNITS 6
3161#define PP_OFF_RESERVED 7
3162
3163#define PP_BIT_IDP 0x20
3164#define PP_MSK_PSUM_MB 0x10
3165
3166/* Get the number of partitions on the tape. As a side effect reads the
3167 mode page into the tape buffer. */
3168static int nbr_partitions(struct scsi_tape *STp)
3169{
3170 int result;
3171 DEB( char *name = tape_name(STp); )
3172
3173 if (STp->ready != ST_READY)
3174 return (-EIO);
3175
3176 result = read_mode_page(STp, PART_PAGE, 1);
3177
3178 if (result) {
3179 DEBC(printk(ST_DEB_MSG "%s: Can't read medium partition page.\n",
3180 name));
3181 result = (-EIO);
3182 } else {
3183 result = (STp->buffer)->b_data[MODE_HEADER_LENGTH +
3184 PP_OFF_NBR_ADD_PARTS] + 1;
3185 DEBC(printk(ST_DEB_MSG "%s: Number of partitions %d.\n", name, result));
3186 }
3187
3188 return result;
3189}
3190
3191
3192/* Partition the tape into two partitions if size > 0 or one partition if
3193 size == 0.
3194
3195 The block descriptors are read and written because Sony SDT-7000 does not
3196 work without this (suggestion from Michael Schaefer <Michael.Schaefer@dlr.de>).
3197
3198 My HP C1533A drive returns only one partition size field. This is used to
3199 set the size of partition 1. There is no size field for the default partition.
3200 Michael Schaefer's Sony SDT-7000 returns two descriptors and the second is
3201 used to set the size of partition 1 (this is what the SCSI-3 standard specifies).
3202 The following algorithm is used to accommodate both drives: if the number of
3203 partition size fields is greater than the maximum number of additional partitions
3204 in the mode page, the second field is used. Otherwise the first field is used.
3205
3206 For Seagate DDS drives the page length must be 8 when no partitions is defined
3207 and 10 when 1 partition is defined (information from Eric Lee Green). This is
3208 is acceptable also to some other old drives and enforced if the first partition
3209 size field is used for the first additional partition size.
3210 */
3211static int partition_tape(struct scsi_tape *STp, int size)
3212{
3213 char *name = tape_name(STp);
3214 int result;
3215 int pgo, psd_cnt, psdo;
3216 unsigned char *bp;
3217
3218 result = read_mode_page(STp, PART_PAGE, 0);
3219 if (result) {
3220 DEBC(printk(ST_DEB_MSG "%s: Can't read partition mode page.\n", name));
3221 return result;
3222 }
3223 /* The mode page is in the buffer. Let's modify it and write it. */
3224 bp = (STp->buffer)->b_data;
3225 pgo = MODE_HEADER_LENGTH + bp[MH_OFF_BDESCS_LENGTH];
3226 DEBC(printk(ST_DEB_MSG "%s: Partition page length is %d bytes.\n",
3227 name, bp[pgo + MP_OFF_PAGE_LENGTH] + 2));
3228
3229 psd_cnt = (bp[pgo + MP_OFF_PAGE_LENGTH] + 2 - PART_PAGE_FIXED_LENGTH) / 2;
3230 psdo = pgo + PART_PAGE_FIXED_LENGTH;
3231 if (psd_cnt > bp[pgo + PP_OFF_MAX_ADD_PARTS]) {
3232 bp[psdo] = bp[psdo + 1] = 0xff; /* Rest of the tape */
3233 psdo += 2;
3234 }
3235 memset(bp + psdo, 0, bp[pgo + PP_OFF_NBR_ADD_PARTS] * 2);
3236
3237 DEBC(printk("%s: psd_cnt %d, max.parts %d, nbr_parts %d\n", name,
3238 psd_cnt, bp[pgo + PP_OFF_MAX_ADD_PARTS],
3239 bp[pgo + PP_OFF_NBR_ADD_PARTS]));
3240
3241 if (size <= 0) {
3242 bp[pgo + PP_OFF_NBR_ADD_PARTS] = 0;
3243 if (psd_cnt <= bp[pgo + PP_OFF_MAX_ADD_PARTS])
3244 bp[pgo + MP_OFF_PAGE_LENGTH] = 6;
3245 DEBC(printk(ST_DEB_MSG "%s: Formatting tape with one partition.\n",
3246 name));
3247 } else {
3248 bp[psdo] = (size >> 8) & 0xff;
3249 bp[psdo + 1] = size & 0xff;
3250 bp[pgo + 3] = 1;
3251 if (bp[pgo + MP_OFF_PAGE_LENGTH] < 8)
3252 bp[pgo + MP_OFF_PAGE_LENGTH] = 8;
3253 DEBC(printk(ST_DEB_MSG
3254 "%s: Formatting tape with two partitions (1 = %d MB).\n",
3255 name, size));
3256 }
3257 bp[pgo + PP_OFF_PART_UNITS] = 0;
3258 bp[pgo + PP_OFF_RESERVED] = 0;
3259 bp[pgo + PP_OFF_FLAGS] = PP_BIT_IDP | PP_MSK_PSUM_MB;
3260
3261 result = write_mode_page(STp, PART_PAGE, 1);
3262 if (result) {
3263 printk(KERN_INFO "%s: Partitioning of tape failed.\n", name);
3264 result = (-EIO);
3265 }
3266
3267 return result;
3268}
3269
3270
3271
3272/* The ioctl command */
Kai Makisarafd66c1b2008-01-17 22:45:22 +02003273static long st_ioctl(struct file *file, unsigned int cmd_in, unsigned long arg)
Linus Torvalds1da177e2005-04-16 15:20:36 -07003274{
3275 int i, cmd_nr, cmd_type, bt;
3276 int retval = 0;
3277 unsigned int blk;
3278 struct scsi_tape *STp = file->private_data;
3279 struct st_modedef *STm;
3280 struct st_partstat *STps;
3281 char *name = tape_name(STp);
3282 void __user *p = (void __user *)arg;
3283
Matthias Kaehlcke28f85002007-07-29 23:38:15 +02003284 if (mutex_lock_interruptible(&STp->lock))
Linus Torvalds1da177e2005-04-16 15:20:36 -07003285 return -ERESTARTSYS;
3286
3287 DEB(
3288 if (debugging && !STp->in_use) {
3289 printk(ST_DEB_MSG "%s: Incorrect device.\n", name);
3290 retval = (-EIO);
3291 goto out;
3292 } ) /* end DEB */
3293
3294 STm = &(STp->modes[STp->current_mode]);
3295 STps = &(STp->ps[STp->partition]);
3296
3297 /*
3298 * If we are in the middle of error recovery, don't let anyone
3299 * else try and use this device. Also, if error recovery fails, it
3300 * may try and take the device offline, in which case all further
3301 * access to the device is prohibited.
3302 */
Al Viro83ff6fe2008-03-02 08:15:49 -05003303 retval = scsi_nonblockable_ioctl(STp->device, cmd_in, p,
3304 file->f_flags & O_NDELAY);
Linus Torvalds1da177e2005-04-16 15:20:36 -07003305 if (!scsi_block_when_processing_errors(STp->device) || retval != -ENODEV)
3306 goto out;
3307 retval = 0;
3308
3309 cmd_type = _IOC_TYPE(cmd_in);
3310 cmd_nr = _IOC_NR(cmd_in);
3311
3312 if (cmd_type == _IOC_TYPE(MTIOCTOP) && cmd_nr == _IOC_NR(MTIOCTOP)) {
3313 struct mtop mtc;
3314
3315 if (_IOC_SIZE(cmd_in) != sizeof(mtc)) {
3316 retval = (-EINVAL);
3317 goto out;
3318 }
3319
3320 i = copy_from_user(&mtc, p, sizeof(struct mtop));
3321 if (i) {
3322 retval = (-EFAULT);
3323 goto out;
3324 }
3325
3326 if (mtc.mt_op == MTSETDRVBUFFER && !capable(CAP_SYS_ADMIN)) {
3327 printk(KERN_WARNING
3328 "%s: MTSETDRVBUFFER only allowed for root.\n", name);
3329 retval = (-EPERM);
3330 goto out;
3331 }
3332 if (!STm->defined &&
3333 (mtc.mt_op != MTSETDRVBUFFER &&
3334 (mtc.mt_count & MT_ST_OPTIONS) == 0)) {
3335 retval = (-ENXIO);
3336 goto out;
3337 }
3338
3339 if (!STp->pos_unknown) {
3340
3341 if (STps->eof == ST_FM_HIT) {
3342 if (mtc.mt_op == MTFSF || mtc.mt_op == MTFSFM ||
3343 mtc.mt_op == MTEOM) {
3344 mtc.mt_count -= 1;
3345 if (STps->drv_file >= 0)
3346 STps->drv_file += 1;
3347 } else if (mtc.mt_op == MTBSF || mtc.mt_op == MTBSFM) {
3348 mtc.mt_count += 1;
3349 if (STps->drv_file >= 0)
3350 STps->drv_file += 1;
3351 }
3352 }
3353
3354 if (mtc.mt_op == MTSEEK) {
3355 /* Old position must be restored if partition will be
3356 changed */
3357 i = !STp->can_partitions ||
3358 (STp->new_partition != STp->partition);
3359 } else {
3360 i = mtc.mt_op == MTREW || mtc.mt_op == MTOFFL ||
3361 mtc.mt_op == MTRETEN || mtc.mt_op == MTEOM ||
3362 mtc.mt_op == MTLOCK || mtc.mt_op == MTLOAD ||
3363 mtc.mt_op == MTFSF || mtc.mt_op == MTFSFM ||
3364 mtc.mt_op == MTBSF || mtc.mt_op == MTBSFM ||
3365 mtc.mt_op == MTCOMPRESSION;
3366 }
3367 i = flush_buffer(STp, i);
3368 if (i < 0) {
3369 retval = i;
3370 goto out;
3371 }
3372 if (STps->rw == ST_WRITING &&
3373 (mtc.mt_op == MTREW || mtc.mt_op == MTOFFL ||
3374 mtc.mt_op == MTSEEK ||
3375 mtc.mt_op == MTBSF || mtc.mt_op == MTBSFM)) {
3376 i = st_int_ioctl(STp, MTWEOF, 1);
3377 if (i < 0) {
3378 retval = i;
3379 goto out;
3380 }
3381 if (mtc.mt_op == MTBSF || mtc.mt_op == MTBSFM)
3382 mtc.mt_count++;
3383 STps->rw = ST_IDLE;
3384 }
3385
3386 } else {
3387 /*
3388 * If there was a bus reset, block further access
3389 * to this device. If the user wants to rewind the tape,
3390 * then reset the flag and allow access again.
3391 */
3392 if (mtc.mt_op != MTREW &&
3393 mtc.mt_op != MTOFFL &&
3394 mtc.mt_op != MTRETEN &&
3395 mtc.mt_op != MTERASE &&
3396 mtc.mt_op != MTSEEK &&
3397 mtc.mt_op != MTEOM) {
3398 retval = (-EIO);
3399 goto out;
3400 }
3401 reset_state(STp);
3402 /* remove this when the midlevel properly clears was_reset */
3403 STp->device->was_reset = 0;
3404 }
3405
3406 if (mtc.mt_op != MTNOP && mtc.mt_op != MTSETBLK &&
3407 mtc.mt_op != MTSETDENSITY && mtc.mt_op != MTWSM &&
3408 mtc.mt_op != MTSETDRVBUFFER && mtc.mt_op != MTSETPART)
3409 STps->rw = ST_IDLE; /* Prevent automatic WEOF and fsf */
3410
3411 if (mtc.mt_op == MTOFFL && STp->door_locked != ST_UNLOCKED)
3412 do_door_lock(STp, 0); /* Ignore result! */
3413
3414 if (mtc.mt_op == MTSETDRVBUFFER &&
3415 (mtc.mt_count & MT_ST_OPTIONS) != 0) {
3416 retval = st_set_options(STp, mtc.mt_count);
3417 goto out;
3418 }
3419
3420 if (mtc.mt_op == MTSETPART) {
3421 if (!STp->can_partitions ||
3422 mtc.mt_count < 0 || mtc.mt_count >= ST_NBR_PARTITIONS) {
3423 retval = (-EINVAL);
3424 goto out;
3425 }
3426 if (mtc.mt_count >= STp->nbr_partitions &&
3427 (STp->nbr_partitions = nbr_partitions(STp)) < 0) {
3428 retval = (-EIO);
3429 goto out;
3430 }
3431 if (mtc.mt_count >= STp->nbr_partitions) {
3432 retval = (-EINVAL);
3433 goto out;
3434 }
3435 STp->new_partition = mtc.mt_count;
3436 retval = 0;
3437 goto out;
3438 }
3439
3440 if (mtc.mt_op == MTMKPART) {
3441 if (!STp->can_partitions) {
3442 retval = (-EINVAL);
3443 goto out;
3444 }
3445 if ((i = st_int_ioctl(STp, MTREW, 0)) < 0 ||
3446 (i = partition_tape(STp, mtc.mt_count)) < 0) {
3447 retval = i;
3448 goto out;
3449 }
3450 for (i = 0; i < ST_NBR_PARTITIONS; i++) {
3451 STp->ps[i].rw = ST_IDLE;
3452 STp->ps[i].at_sm = 0;
3453 STp->ps[i].last_block_valid = 0;
3454 }
3455 STp->partition = STp->new_partition = 0;
3456 STp->nbr_partitions = 1; /* Bad guess ?-) */
3457 STps->drv_block = STps->drv_file = 0;
3458 retval = 0;
3459 goto out;
3460 }
3461
3462 if (mtc.mt_op == MTSEEK) {
3463 i = set_location(STp, mtc.mt_count, STp->new_partition, 0);
3464 if (!STp->can_partitions)
3465 STp->ps[0].rw = ST_IDLE;
3466 retval = i;
3467 goto out;
3468 }
3469
3470 if (mtc.mt_op == MTUNLOAD || mtc.mt_op == MTOFFL) {
3471 retval = do_load_unload(STp, file, 0);
3472 goto out;
3473 }
3474
3475 if (mtc.mt_op == MTLOAD) {
3476 retval = do_load_unload(STp, file, max(1, mtc.mt_count));
3477 goto out;
3478 }
3479
3480 if (mtc.mt_op == MTLOCK || mtc.mt_op == MTUNLOCK) {
3481 retval = do_door_lock(STp, (mtc.mt_op == MTLOCK));
3482 goto out;
3483 }
3484
3485 if (STp->can_partitions && STp->ready == ST_READY &&
3486 (i = switch_partition(STp)) < 0) {
3487 retval = i;
3488 goto out;
3489 }
3490
3491 if (mtc.mt_op == MTCOMPRESSION)
3492 retval = st_compression(STp, (mtc.mt_count & 1));
3493 else
3494 retval = st_int_ioctl(STp, mtc.mt_op, mtc.mt_count);
3495 goto out;
3496 }
3497 if (!STm->defined) {
3498 retval = (-ENXIO);
3499 goto out;
3500 }
3501
3502 if ((i = flush_buffer(STp, 0)) < 0) {
3503 retval = i;
3504 goto out;
3505 }
3506 if (STp->can_partitions &&
3507 (i = switch_partition(STp)) < 0) {
3508 retval = i;
3509 goto out;
3510 }
3511
3512 if (cmd_type == _IOC_TYPE(MTIOCGET) && cmd_nr == _IOC_NR(MTIOCGET)) {
3513 struct mtget mt_status;
3514
3515 if (_IOC_SIZE(cmd_in) != sizeof(struct mtget)) {
3516 retval = (-EINVAL);
3517 goto out;
3518 }
3519
3520 mt_status.mt_type = STp->tape_type;
3521 mt_status.mt_dsreg =
3522 ((STp->block_size << MT_ST_BLKSIZE_SHIFT) & MT_ST_BLKSIZE_MASK) |
3523 ((STp->density << MT_ST_DENSITY_SHIFT) & MT_ST_DENSITY_MASK);
3524 mt_status.mt_blkno = STps->drv_block;
3525 mt_status.mt_fileno = STps->drv_file;
3526 if (STp->block_size != 0) {
3527 if (STps->rw == ST_WRITING)
3528 mt_status.mt_blkno +=
3529 (STp->buffer)->buffer_bytes / STp->block_size;
3530 else if (STps->rw == ST_READING)
3531 mt_status.mt_blkno -=
3532 ((STp->buffer)->buffer_bytes +
3533 STp->block_size - 1) / STp->block_size;
3534 }
3535
3536 mt_status.mt_gstat = 0;
3537 if (STp->drv_write_prot)
3538 mt_status.mt_gstat |= GMT_WR_PROT(0xffffffff);
3539 if (mt_status.mt_blkno == 0) {
3540 if (mt_status.mt_fileno == 0)
3541 mt_status.mt_gstat |= GMT_BOT(0xffffffff);
3542 else
3543 mt_status.mt_gstat |= GMT_EOF(0xffffffff);
3544 }
3545 mt_status.mt_erreg = (STp->recover_reg << MT_ST_SOFTERR_SHIFT);
3546 mt_status.mt_resid = STp->partition;
3547 if (STps->eof == ST_EOM_OK || STps->eof == ST_EOM_ERROR)
3548 mt_status.mt_gstat |= GMT_EOT(0xffffffff);
3549 else if (STps->eof >= ST_EOM_OK)
3550 mt_status.mt_gstat |= GMT_EOD(0xffffffff);
3551 if (STp->density == 1)
3552 mt_status.mt_gstat |= GMT_D_800(0xffffffff);
3553 else if (STp->density == 2)
3554 mt_status.mt_gstat |= GMT_D_1600(0xffffffff);
3555 else if (STp->density == 3)
3556 mt_status.mt_gstat |= GMT_D_6250(0xffffffff);
3557 if (STp->ready == ST_READY)
3558 mt_status.mt_gstat |= GMT_ONLINE(0xffffffff);
3559 if (STp->ready == ST_NO_TAPE)
3560 mt_status.mt_gstat |= GMT_DR_OPEN(0xffffffff);
3561 if (STps->at_sm)
3562 mt_status.mt_gstat |= GMT_SM(0xffffffff);
3563 if (STm->do_async_writes ||
3564 (STm->do_buffer_writes && STp->block_size != 0) ||
3565 STp->drv_buffer != 0)
3566 mt_status.mt_gstat |= GMT_IM_REP_EN(0xffffffff);
3567 if (STp->cleaning_req)
3568 mt_status.mt_gstat |= GMT_CLN(0xffffffff);
3569
3570 i = copy_to_user(p, &mt_status, sizeof(struct mtget));
3571 if (i) {
3572 retval = (-EFAULT);
3573 goto out;
3574 }
3575
3576 STp->recover_reg = 0; /* Clear after read */
3577 retval = 0;
3578 goto out;
3579 } /* End of MTIOCGET */
3580 if (cmd_type == _IOC_TYPE(MTIOCPOS) && cmd_nr == _IOC_NR(MTIOCPOS)) {
3581 struct mtpos mt_pos;
3582 if (_IOC_SIZE(cmd_in) != sizeof(struct mtpos)) {
3583 retval = (-EINVAL);
3584 goto out;
3585 }
3586 if ((i = get_location(STp, &blk, &bt, 0)) < 0) {
3587 retval = i;
3588 goto out;
3589 }
3590 mt_pos.mt_blkno = blk;
3591 i = copy_to_user(p, &mt_pos, sizeof(struct mtpos));
3592 if (i)
3593 retval = (-EFAULT);
3594 goto out;
3595 }
Matthias Kaehlcke28f85002007-07-29 23:38:15 +02003596 mutex_unlock(&STp->lock);
Linus Torvalds1da177e2005-04-16 15:20:36 -07003597 switch (cmd_in) {
3598 case SCSI_IOCTL_GET_IDLUN:
3599 case SCSI_IOCTL_GET_BUS_NUMBER:
3600 break;
3601 default:
Kai Makisara 16c4b3e2005-05-01 18:11:55 +03003602 if ((cmd_in == SG_IO ||
3603 cmd_in == SCSI_IOCTL_SEND_COMMAND ||
3604 cmd_in == CDROM_SEND_PACKET) &&
3605 !capable(CAP_SYS_RAWIO))
Linus Torvalds1da177e2005-04-16 15:20:36 -07003606 i = -EPERM;
3607 else
Al Viro74f3c8a2007-08-27 15:38:10 -04003608 i = scsi_cmd_ioctl(STp->disk->queue, STp->disk,
3609 file->f_mode, cmd_in, p);
Linus Torvalds1da177e2005-04-16 15:20:36 -07003610 if (i != -ENOTTY)
3611 return i;
3612 break;
3613 }
Kai Makisara 16c4b3e2005-05-01 18:11:55 +03003614 retval = scsi_ioctl(STp->device, cmd_in, p);
3615 if (!retval && cmd_in == SCSI_IOCTL_STOP_UNIT) { /* unload */
3616 STp->rew_at_close = 0;
3617 STp->ready = ST_NO_TAPE;
3618 }
3619 return retval;
Linus Torvalds1da177e2005-04-16 15:20:36 -07003620
3621 out:
Matthias Kaehlcke28f85002007-07-29 23:38:15 +02003622 mutex_unlock(&STp->lock);
Linus Torvalds1da177e2005-04-16 15:20:36 -07003623 return retval;
3624}
3625
3626#ifdef CONFIG_COMPAT
3627static long st_compat_ioctl(struct file *file, unsigned int cmd, unsigned long arg)
3628{
3629 struct scsi_tape *STp = file->private_data;
3630 struct scsi_device *sdev = STp->device;
3631 int ret = -ENOIOCTLCMD;
3632 if (sdev->host->hostt->compat_ioctl) {
3633
3634 ret = sdev->host->hostt->compat_ioctl(sdev, cmd, (void __user *)arg);
3635
3636 }
3637 return ret;
3638}
3639#endif
3640
3641
3642
3643/* Try to allocate a new tape buffer. Calling function must not hold
3644 dev_arr_lock. */
3645static struct st_buffer *
3646 new_tape_buffer(int from_initialization, int need_dma, int max_sg)
3647{
Mike Christie8b05b772005-11-08 04:06:44 -06003648 int i, got = 0;
Al Viroc53033f2005-10-21 03:22:08 -04003649 gfp_t priority;
Linus Torvalds1da177e2005-04-16 15:20:36 -07003650 struct st_buffer *tb;
3651
3652 if (from_initialization)
3653 priority = GFP_ATOMIC;
3654 else
3655 priority = GFP_KERNEL;
3656
3657 i = sizeof(struct st_buffer) + (max_sg - 1) * sizeof(struct scatterlist) +
3658 max_sg * sizeof(struct st_buf_fragment);
Jes Sorensen24669f752006-01-16 10:31:18 -05003659 tb = kzalloc(i, priority);
Linus Torvalds1da177e2005-04-16 15:20:36 -07003660 if (!tb) {
3661 printk(KERN_NOTICE "st: Can't allocate new tape buffer.\n");
3662 return NULL;
3663 }
Mike Christie8b05b772005-11-08 04:06:44 -06003664 tb->frp_segs = tb->orig_frp_segs = 0;
Linus Torvalds1da177e2005-04-16 15:20:36 -07003665 tb->use_sg = max_sg;
Linus Torvalds1da177e2005-04-16 15:20:36 -07003666 tb->frp = (struct st_buf_fragment *)(&(tb->sg[0]) + max_sg);
3667
Linus Torvalds1da177e2005-04-16 15:20:36 -07003668 tb->dma = need_dma;
3669 tb->buffer_size = got;
FUJITA Tomonoricd816212007-12-15 15:51:55 +09003670 sg_init_table(tb->sg, max_sg);
Linus Torvalds1da177e2005-04-16 15:20:36 -07003671
3672 return tb;
3673}
3674
3675
3676/* Try to allocate enough space in the tape buffer */
3677static int enlarge_buffer(struct st_buffer * STbuffer, int new_size, int need_dma)
3678{
Al Viroc53033f2005-10-21 03:22:08 -04003679 int segs, nbr, max_segs, b_size, order, got;
3680 gfp_t priority;
Linus Torvalds1da177e2005-04-16 15:20:36 -07003681
3682 if (new_size <= STbuffer->buffer_size)
3683 return 1;
3684
3685 if (STbuffer->buffer_size <= PAGE_SIZE)
3686 normalize_buffer(STbuffer); /* Avoid extra segment */
3687
3688 max_segs = STbuffer->use_sg;
3689 nbr = max_segs - STbuffer->frp_segs;
3690 if (nbr <= 0)
3691 return 0;
3692
3693 priority = GFP_KERNEL | __GFP_NOWARN;
3694 if (need_dma)
3695 priority |= GFP_DMA;
Mike Christie8b05b772005-11-08 04:06:44 -06003696 for (b_size = PAGE_SIZE, order=0; order <= 6 &&
Linus Torvalds1da177e2005-04-16 15:20:36 -07003697 b_size < new_size - STbuffer->buffer_size;
3698 order++, b_size *= 2)
3699 ; /* empty */
3700
3701 for (segs = STbuffer->frp_segs, got = STbuffer->buffer_size;
3702 segs < max_segs && got < new_size;) {
3703 STbuffer->frp[segs].page = alloc_pages(priority, order);
3704 if (STbuffer->frp[segs].page == NULL) {
3705 if (new_size - got <= (max_segs - segs) * b_size / 2) {
3706 b_size /= 2; /* Large enough for the rest of the buffers */
3707 order--;
3708 continue;
3709 }
3710 DEB(STbuffer->buffer_size = got);
3711 normalize_buffer(STbuffer);
3712 return 0;
3713 }
3714 STbuffer->frp[segs].length = b_size;
3715 STbuffer->frp_segs += 1;
3716 got += b_size;
3717 STbuffer->buffer_size = got;
Kai Makisara40f6b362008-02-24 22:23:24 +02003718 if (STbuffer->cleared)
3719 memset(page_address(STbuffer->frp[segs].page), 0, b_size);
Linus Torvalds1da177e2005-04-16 15:20:36 -07003720 segs++;
3721 }
3722 STbuffer->b_data = page_address(STbuffer->frp[0].page);
3723
3724 return 1;
3725}
3726
3727
Kai Makisara40f6b362008-02-24 22:23:24 +02003728/* Make sure that no data from previous user is in the internal buffer */
3729static void clear_buffer(struct st_buffer * st_bp)
3730{
3731 int i;
3732
3733 for (i=0; i < st_bp->frp_segs; i++)
3734 memset(page_address(st_bp->frp[i].page), 0, st_bp->frp[i].length);
3735 st_bp->cleared = 1;
3736}
3737
3738
Linus Torvalds1da177e2005-04-16 15:20:36 -07003739/* Release the extra buffer */
3740static void normalize_buffer(struct st_buffer * STbuffer)
3741{
3742 int i, order;
3743
3744 for (i = STbuffer->orig_frp_segs; i < STbuffer->frp_segs; i++) {
3745 order = get_order(STbuffer->frp[i].length);
3746 __free_pages(STbuffer->frp[i].page, order);
3747 STbuffer->buffer_size -= STbuffer->frp[i].length;
3748 }
3749 STbuffer->frp_segs = STbuffer->orig_frp_segs;
3750 STbuffer->frp_sg_current = 0;
Mike Christie8b05b772005-11-08 04:06:44 -06003751 STbuffer->sg_segs = 0;
Linus Torvalds1da177e2005-04-16 15:20:36 -07003752}
3753
3754
3755/* Move data from the user buffer to the tape buffer. Returns zero (success) or
3756 negative error code. */
3757static int append_to_buffer(const char __user *ubp, struct st_buffer * st_bp, int do_count)
3758{
3759 int i, cnt, res, offset;
3760
3761 for (i = 0, offset = st_bp->buffer_bytes;
3762 i < st_bp->frp_segs && offset >= st_bp->frp[i].length; i++)
3763 offset -= st_bp->frp[i].length;
3764 if (i == st_bp->frp_segs) { /* Should never happen */
3765 printk(KERN_WARNING "st: append_to_buffer offset overflow.\n");
3766 return (-EIO);
3767 }
3768 for (; i < st_bp->frp_segs && do_count > 0; i++) {
3769 cnt = st_bp->frp[i].length - offset < do_count ?
3770 st_bp->frp[i].length - offset : do_count;
3771 res = copy_from_user(page_address(st_bp->frp[i].page) + offset, ubp, cnt);
3772 if (res)
3773 return (-EFAULT);
3774 do_count -= cnt;
3775 st_bp->buffer_bytes += cnt;
3776 ubp += cnt;
3777 offset = 0;
3778 }
3779 if (do_count) /* Should never happen */
3780 return (-EIO);
3781
3782 return 0;
3783}
3784
3785
3786/* Move data from the tape buffer to the user buffer. Returns zero (success) or
3787 negative error code. */
3788static int from_buffer(struct st_buffer * st_bp, char __user *ubp, int do_count)
3789{
3790 int i, cnt, res, offset;
3791
3792 for (i = 0, offset = st_bp->read_pointer;
3793 i < st_bp->frp_segs && offset >= st_bp->frp[i].length; i++)
3794 offset -= st_bp->frp[i].length;
3795 if (i == st_bp->frp_segs) { /* Should never happen */
3796 printk(KERN_WARNING "st: from_buffer offset overflow.\n");
3797 return (-EIO);
3798 }
3799 for (; i < st_bp->frp_segs && do_count > 0; i++) {
3800 cnt = st_bp->frp[i].length - offset < do_count ?
3801 st_bp->frp[i].length - offset : do_count;
3802 res = copy_to_user(ubp, page_address(st_bp->frp[i].page) + offset, cnt);
3803 if (res)
3804 return (-EFAULT);
3805 do_count -= cnt;
3806 st_bp->buffer_bytes -= cnt;
3807 st_bp->read_pointer += cnt;
3808 ubp += cnt;
3809 offset = 0;
3810 }
3811 if (do_count) /* Should never happen */
3812 return (-EIO);
3813
3814 return 0;
3815}
3816
3817
3818/* Move data towards start of buffer */
3819static void move_buffer_data(struct st_buffer * st_bp, int offset)
3820{
3821 int src_seg, dst_seg, src_offset = 0, dst_offset;
3822 int count, total;
3823
3824 if (offset == 0)
3825 return;
3826
3827 total=st_bp->buffer_bytes - offset;
3828 for (src_seg=0; src_seg < st_bp->frp_segs; src_seg++) {
3829 src_offset = offset;
3830 if (src_offset < st_bp->frp[src_seg].length)
3831 break;
3832 offset -= st_bp->frp[src_seg].length;
3833 }
3834
3835 st_bp->buffer_bytes = st_bp->read_pointer = total;
3836 for (dst_seg=dst_offset=0; total > 0; ) {
3837 count = min(st_bp->frp[dst_seg].length - dst_offset,
3838 st_bp->frp[src_seg].length - src_offset);
3839 memmove(page_address(st_bp->frp[dst_seg].page) + dst_offset,
3840 page_address(st_bp->frp[src_seg].page) + src_offset, count);
3841 src_offset += count;
3842 if (src_offset >= st_bp->frp[src_seg].length) {
3843 src_seg++;
3844 src_offset = 0;
3845 }
3846 dst_offset += count;
3847 if (dst_offset >= st_bp->frp[dst_seg].length) {
3848 dst_seg++;
3849 dst_offset = 0;
3850 }
3851 total -= count;
3852 }
3853}
3854
3855
3856/* Fill the s/g list up to the length required for this transfer */
3857static void buf_to_sg(struct st_buffer *STbp, unsigned int length)
3858{
3859 int i;
3860 unsigned int count;
3861 struct scatterlist *sg;
3862 struct st_buf_fragment *frp;
3863
3864 if (length == STbp->frp_sg_current)
3865 return; /* work already done */
3866
3867 sg = &(STbp->sg[0]);
3868 frp = STbp->frp;
3869 for (i=count=0; count < length; i++) {
Linus Torvalds1da177e2005-04-16 15:20:36 -07003870 if (length - count > frp[i].length)
Jens Axboe642f1492007-10-24 11:20:47 +02003871 sg_set_page(&sg[i], frp[i].page, frp[i].length, 0);
Linus Torvalds1da177e2005-04-16 15:20:36 -07003872 else
Jens Axboe642f1492007-10-24 11:20:47 +02003873 sg_set_page(&sg[i], frp[i].page, length - count, 0);
Linus Torvalds1da177e2005-04-16 15:20:36 -07003874 count += sg[i].length;
Linus Torvalds1da177e2005-04-16 15:20:36 -07003875 }
3876 STbp->sg_segs = i;
3877 STbp->frp_sg_current = length;
3878}
3879
3880
3881/* Validate the options from command line or module parameters */
3882static void validate_options(void)
3883{
3884 if (buffer_kbs > 0)
3885 st_fixed_buffer_size = buffer_kbs * ST_KILOBYTE;
3886 if (max_sg_segs >= ST_FIRST_SG)
3887 st_max_sg_segs = max_sg_segs;
3888}
3889
3890#ifndef MODULE
3891/* Set the boot options. Syntax is defined in Documenation/scsi/st.txt.
3892 */
3893static int __init st_setup(char *str)
3894{
3895 int i, len, ints[5];
3896 char *stp;
3897
3898 stp = get_options(str, ARRAY_SIZE(ints), ints);
3899
3900 if (ints[0] > 0) {
3901 for (i = 0; i < ints[0] && i < ARRAY_SIZE(parms); i++)
3902 if (parms[i].val)
3903 *parms[i].val = ints[i + 1];
3904 } else {
3905 while (stp != NULL) {
3906 for (i = 0; i < ARRAY_SIZE(parms); i++) {
3907 len = strlen(parms[i].name);
3908 if (!strncmp(stp, parms[i].name, len) &&
3909 (*(stp + len) == ':' || *(stp + len) == '=')) {
3910 if (parms[i].val)
3911 *parms[i].val =
3912 simple_strtoul(stp + len + 1, NULL, 0);
3913 else
3914 printk(KERN_WARNING "st: Obsolete parameter %s\n",
3915 parms[i].name);
3916 break;
3917 }
3918 }
Tobias Klauser6391a112006-06-08 22:23:48 -07003919 if (i >= ARRAY_SIZE(parms))
Linus Torvalds1da177e2005-04-16 15:20:36 -07003920 printk(KERN_WARNING "st: invalid parameter in '%s'\n",
3921 stp);
3922 stp = strchr(stp, ',');
3923 if (stp)
3924 stp++;
3925 }
3926 }
3927
3928 validate_options();
3929
3930 return 1;
3931}
3932
3933__setup("st=", st_setup);
3934
3935#endif
3936
Arjan van de Ven00977a52007-02-12 00:55:34 -08003937static const struct file_operations st_fops =
Linus Torvalds1da177e2005-04-16 15:20:36 -07003938{
3939 .owner = THIS_MODULE,
3940 .read = st_read,
3941 .write = st_write,
Kai Makisarafd66c1b2008-01-17 22:45:22 +02003942 .unlocked_ioctl = st_ioctl,
Linus Torvalds1da177e2005-04-16 15:20:36 -07003943#ifdef CONFIG_COMPAT
3944 .compat_ioctl = st_compat_ioctl,
3945#endif
3946 .open = st_open,
3947 .flush = st_flush,
3948 .release = st_release,
3949};
3950
3951static int st_probe(struct device *dev)
3952{
3953 struct scsi_device *SDp = to_scsi_device(dev);
3954 struct gendisk *disk = NULL;
3955 struct cdev *cdev = NULL;
3956 struct scsi_tape *tpnt = NULL;
3957 struct st_modedef *STm;
3958 struct st_partstat *STps;
3959 struct st_buffer *buffer;
3960 int i, j, mode, dev_num, error;
3961 char *stp;
Linus Torvalds1da177e2005-04-16 15:20:36 -07003962
3963 if (SDp->type != TYPE_TAPE)
3964 return -ENODEV;
3965 if ((stp = st_incompatible(SDp))) {
Jeff Garzik3bf743e2005-10-24 18:04:06 -04003966 sdev_printk(KERN_INFO, SDp, "Found incompatible tape\n");
Linus Torvalds1da177e2005-04-16 15:20:36 -07003967 printk(KERN_INFO "st: The suggested driver is %s.\n", stp);
3968 return -ENODEV;
3969 }
3970
Mike Christie8b05b772005-11-08 04:06:44 -06003971 i = min(SDp->request_queue->max_hw_segments,
3972 SDp->request_queue->max_phys_segments);
Linus Torvalds1da177e2005-04-16 15:20:36 -07003973 if (st_max_sg_segs < i)
3974 i = st_max_sg_segs;
3975 buffer = new_tape_buffer(1, (SDp->host)->unchecked_isa_dma, i);
3976 if (buffer == NULL) {
3977 printk(KERN_ERR
3978 "st: Can't allocate new tape buffer. Device not attached.\n");
3979 goto out;
3980 }
3981
3982 disk = alloc_disk(1);
3983 if (!disk) {
3984 printk(KERN_ERR "st: out of memory. Device not attached.\n");
3985 goto out_buffer_free;
3986 }
3987
3988 write_lock(&st_dev_arr_lock);
3989 if (st_nr_dev >= st_dev_max) {
3990 struct scsi_tape **tmp_da;
3991 int tmp_dev_max;
3992
3993 tmp_dev_max = max(st_nr_dev * 2, 8);
3994 if (tmp_dev_max > ST_MAX_TAPES)
3995 tmp_dev_max = ST_MAX_TAPES;
3996 if (tmp_dev_max <= st_nr_dev) {
3997 write_unlock(&st_dev_arr_lock);
3998 printk(KERN_ERR "st: Too many tape devices (max. %d).\n",
3999 ST_MAX_TAPES);
4000 goto out_put_disk;
4001 }
4002
Jes Sorensen24669f752006-01-16 10:31:18 -05004003 tmp_da = kzalloc(tmp_dev_max * sizeof(struct scsi_tape *), GFP_ATOMIC);
Linus Torvalds1da177e2005-04-16 15:20:36 -07004004 if (tmp_da == NULL) {
4005 write_unlock(&st_dev_arr_lock);
4006 printk(KERN_ERR "st: Can't extend device array.\n");
4007 goto out_put_disk;
4008 }
4009
Linus Torvalds1da177e2005-04-16 15:20:36 -07004010 if (scsi_tapes != NULL) {
4011 memcpy(tmp_da, scsi_tapes,
4012 st_dev_max * sizeof(struct scsi_tape *));
4013 kfree(scsi_tapes);
4014 }
4015 scsi_tapes = tmp_da;
4016
4017 st_dev_max = tmp_dev_max;
4018 }
4019
4020 for (i = 0; i < st_dev_max; i++)
4021 if (scsi_tapes[i] == NULL)
4022 break;
4023 if (i >= st_dev_max)
4024 panic("scsi_devices corrupt (st)");
4025
Jes Sorensen24669f752006-01-16 10:31:18 -05004026 tpnt = kzalloc(sizeof(struct scsi_tape), GFP_ATOMIC);
Linus Torvalds1da177e2005-04-16 15:20:36 -07004027 if (tpnt == NULL) {
4028 write_unlock(&st_dev_arr_lock);
4029 printk(KERN_ERR "st: Can't allocate device descriptor.\n");
4030 goto out_put_disk;
4031 }
Kai Makisaraf03a5672005-08-02 13:40:47 +03004032 kref_init(&tpnt->kref);
Linus Torvalds1da177e2005-04-16 15:20:36 -07004033 tpnt->disk = disk;
4034 sprintf(disk->disk_name, "st%d", i);
4035 disk->private_data = &tpnt->driver;
4036 disk->queue = SDp->request_queue;
4037 tpnt->driver = &st_template;
4038 scsi_tapes[i] = tpnt;
4039 dev_num = i;
4040
4041 tpnt->device = SDp;
4042 if (SDp->scsi_level <= 2)
4043 tpnt->tape_type = MT_ISSCSI1;
4044 else
4045 tpnt->tape_type = MT_ISSCSI2;
4046
4047 tpnt->buffer = buffer;
Kai Makisaraf03a5672005-08-02 13:40:47 +03004048 tpnt->buffer->last_SRpnt = NULL;
Linus Torvalds1da177e2005-04-16 15:20:36 -07004049
4050 tpnt->inited = 0;
4051 tpnt->dirty = 0;
4052 tpnt->in_use = 0;
4053 tpnt->drv_buffer = 1; /* Try buffering if no mode sense */
4054 tpnt->restr_dma = (SDp->host)->unchecked_isa_dma;
4055 tpnt->use_pf = (SDp->scsi_level >= SCSI_2);
4056 tpnt->density = 0;
4057 tpnt->do_auto_lock = ST_AUTO_LOCK;
4058 tpnt->can_bsr = (SDp->scsi_level > 2 ? 1 : ST_IN_FILE_POS); /* BSR mandatory in SCSI3 */
4059 tpnt->can_partitions = 0;
4060 tpnt->two_fm = ST_TWO_FM;
4061 tpnt->fast_mteom = ST_FAST_MTEOM;
4062 tpnt->scsi2_logical = ST_SCSI2LOGICAL;
Kai Makisara40f6b362008-02-24 22:23:24 +02004063 tpnt->sili = ST_SILI;
Linus Torvalds1da177e2005-04-16 15:20:36 -07004064 tpnt->immediate = ST_NOWAIT;
4065 tpnt->default_drvbuffer = 0xff; /* No forced buffering */
4066 tpnt->partition = 0;
4067 tpnt->new_partition = 0;
4068 tpnt->nbr_partitions = 0;
James Bottomleya02488e2008-11-30 10:36:26 -06004069 blk_queue_rq_timeout(tpnt->device->request_queue, ST_TIMEOUT);
Linus Torvalds1da177e2005-04-16 15:20:36 -07004070 tpnt->long_timeout = ST_LONG_TIMEOUT;
4071 tpnt->try_dio = try_direct_io && !SDp->host->unchecked_isa_dma;
4072
Linus Torvalds1da177e2005-04-16 15:20:36 -07004073 for (i = 0; i < ST_NBR_MODES; i++) {
4074 STm = &(tpnt->modes[i]);
4075 STm->defined = 0;
4076 STm->sysv = ST_SYSV;
4077 STm->defaults_for_writes = 0;
4078 STm->do_async_writes = ST_ASYNC_WRITES;
4079 STm->do_buffer_writes = ST_BUFFER_WRITES;
4080 STm->do_read_ahead = ST_READ_AHEAD;
4081 STm->default_compression = ST_DONT_TOUCH;
4082 STm->default_blksize = (-1); /* No forced size */
4083 STm->default_density = (-1); /* No forced density */
4084 }
4085
4086 for (i = 0; i < ST_NBR_PARTITIONS; i++) {
4087 STps = &(tpnt->ps[i]);
4088 STps->rw = ST_IDLE;
4089 STps->eof = ST_NOEOF;
4090 STps->at_sm = 0;
4091 STps->last_block_valid = 0;
4092 STps->drv_block = (-1);
4093 STps->drv_file = (-1);
4094 }
4095
4096 tpnt->current_mode = 0;
4097 tpnt->modes[0].defined = 1;
4098
4099 tpnt->density_changed = tpnt->compression_changed =
4100 tpnt->blksize_changed = 0;
Matthias Kaehlcke28f85002007-07-29 23:38:15 +02004101 mutex_init(&tpnt->lock);
Linus Torvalds1da177e2005-04-16 15:20:36 -07004102
4103 st_nr_dev++;
4104 write_unlock(&st_dev_arr_lock);
4105
4106 for (mode = 0; mode < ST_NBR_MODES; ++mode) {
4107 STm = &(tpnt->modes[mode]);
4108 for (j=0; j < 2; j++) {
4109 cdev = cdev_alloc();
4110 if (!cdev) {
4111 printk(KERN_ERR
4112 "st%d: out of memory. Device not attached.\n",
4113 dev_num);
4114 goto out_free_tape;
4115 }
4116 cdev->owner = THIS_MODULE;
4117 cdev->ops = &st_fops;
4118
4119 error = cdev_add(cdev,
4120 MKDEV(SCSI_TAPE_MAJOR, TAPE_MINOR(dev_num, mode, j)),
4121 1);
4122 if (error) {
4123 printk(KERN_ERR "st%d: Can't add %s-rewind mode %d\n",
4124 dev_num, j ? "non" : "auto", mode);
4125 printk(KERN_ERR "st%d: Device not attached.\n", dev_num);
4126 goto out_free_tape;
4127 }
4128 STm->cdevs[j] = cdev;
4129
4130 }
Jeff Garzik13026a62006-10-04 06:00:38 -04004131 error = do_create_class_files(tpnt, dev_num, mode);
4132 if (error)
4133 goto out_free_tape;
Linus Torvalds1da177e2005-04-16 15:20:36 -07004134 }
4135
Kai Makisara42252852006-11-07 21:56:38 +02004136 sdev_printk(KERN_NOTICE, SDp,
Rene Herman8b1ea242006-05-20 15:00:22 -07004137 "Attached scsi tape %s\n", tape_name(tpnt));
Kai Makisara42252852006-11-07 21:56:38 +02004138 sdev_printk(KERN_INFO, SDp, "%s: try direct i/o: %s (alignment %d B)\n",
4139 tape_name(tpnt), tpnt->try_dio ? "yes" : "no",
4140 queue_dma_alignment(SDp->request_queue) + 1);
Linus Torvalds1da177e2005-04-16 15:20:36 -07004141
4142 return 0;
4143
4144out_free_tape:
4145 for (mode=0; mode < ST_NBR_MODES; mode++) {
4146 STm = &(tpnt->modes[mode]);
4147 sysfs_remove_link(&tpnt->device->sdev_gendev.kobj,
4148 "tape");
4149 for (j=0; j < 2; j++) {
4150 if (STm->cdevs[j]) {
4151 if (cdev == STm->cdevs[j])
4152 cdev = NULL;
Tony Jonesee959b02008-02-22 00:13:36 +01004153 device_destroy(st_sysfs_class,
4154 MKDEV(SCSI_TAPE_MAJOR,
4155 TAPE_MINOR(i, mode, j)));
Linus Torvalds1da177e2005-04-16 15:20:36 -07004156 cdev_del(STm->cdevs[j]);
4157 }
4158 }
4159 }
4160 if (cdev)
4161 cdev_del(cdev);
4162 write_lock(&st_dev_arr_lock);
4163 scsi_tapes[dev_num] = NULL;
4164 st_nr_dev--;
4165 write_unlock(&st_dev_arr_lock);
4166out_put_disk:
4167 put_disk(disk);
Jesper Juhlc9475cb2005-11-07 01:01:26 -08004168 kfree(tpnt);
Linus Torvalds1da177e2005-04-16 15:20:36 -07004169out_buffer_free:
4170 kfree(buffer);
4171out:
4172 return -ENODEV;
4173};
4174
4175
4176static int st_remove(struct device *dev)
4177{
4178 struct scsi_device *SDp = to_scsi_device(dev);
4179 struct scsi_tape *tpnt;
4180 int i, j, mode;
4181
4182 write_lock(&st_dev_arr_lock);
4183 for (i = 0; i < st_dev_max; i++) {
4184 tpnt = scsi_tapes[i];
4185 if (tpnt != NULL && tpnt->device == SDp) {
4186 scsi_tapes[i] = NULL;
4187 st_nr_dev--;
4188 write_unlock(&st_dev_arr_lock);
Linus Torvalds1da177e2005-04-16 15:20:36 -07004189 sysfs_remove_link(&tpnt->device->sdev_gendev.kobj,
4190 "tape");
4191 for (mode = 0; mode < ST_NBR_MODES; ++mode) {
Linus Torvalds1da177e2005-04-16 15:20:36 -07004192 for (j=0; j < 2; j++) {
Tony Jonesee959b02008-02-22 00:13:36 +01004193 device_destroy(st_sysfs_class,
4194 MKDEV(SCSI_TAPE_MAJOR,
4195 TAPE_MINOR(i, mode, j)));
Linus Torvalds1da177e2005-04-16 15:20:36 -07004196 cdev_del(tpnt->modes[mode].cdevs[j]);
4197 tpnt->modes[mode].cdevs[j] = NULL;
4198 }
4199 }
Linus Torvalds1da177e2005-04-16 15:20:36 -07004200
Arjan van de Ven0b950672006-01-11 13:16:10 +01004201 mutex_lock(&st_ref_mutex);
Kai Makisaraf03a5672005-08-02 13:40:47 +03004202 kref_put(&tpnt->kref, scsi_tape_release);
Arjan van de Ven0b950672006-01-11 13:16:10 +01004203 mutex_unlock(&st_ref_mutex);
Linus Torvalds1da177e2005-04-16 15:20:36 -07004204 return 0;
4205 }
4206 }
4207
4208 write_unlock(&st_dev_arr_lock);
4209 return 0;
4210}
4211
Kai Makisaraf03a5672005-08-02 13:40:47 +03004212/**
4213 * scsi_tape_release - Called to free the Scsi_Tape structure
4214 * @kref: pointer to embedded kref
4215 *
Arjan van de Ven0b950672006-01-11 13:16:10 +01004216 * st_ref_mutex must be held entering this routine. Because it is
Kai Makisaraf03a5672005-08-02 13:40:47 +03004217 * called on last put, you should always use the scsi_tape_get()
4218 * scsi_tape_put() helpers which manipulate the semaphore directly
4219 * and never do a direct kref_put().
4220 **/
4221static void scsi_tape_release(struct kref *kref)
4222{
4223 struct scsi_tape *tpnt = to_scsi_tape(kref);
4224 struct gendisk *disk = tpnt->disk;
4225
4226 tpnt->device = NULL;
4227
4228 if (tpnt->buffer) {
4229 tpnt->buffer->orig_frp_segs = 0;
4230 normalize_buffer(tpnt->buffer);
4231 kfree(tpnt->buffer);
4232 }
4233
4234 disk->private_data = NULL;
4235 put_disk(disk);
4236 kfree(tpnt);
4237 return;
4238}
4239
Linus Torvalds1da177e2005-04-16 15:20:36 -07004240static int __init init_st(void)
4241{
Jeff Garzik13026a62006-10-04 06:00:38 -04004242 int err;
4243
Linus Torvalds1da177e2005-04-16 15:20:36 -07004244 validate_options();
4245
Jeff Garzik13026a62006-10-04 06:00:38 -04004246 printk(KERN_INFO "st: Version %s, fixed bufsize %d, s/g segs %d\n",
Linus Torvalds1da177e2005-04-16 15:20:36 -07004247 verstr, st_fixed_buffer_size, st_max_sg_segs);
4248
gregkh@suse.ded2538782005-03-23 09:55:22 -08004249 st_sysfs_class = class_create(THIS_MODULE, "scsi_tape");
Linus Torvalds1da177e2005-04-16 15:20:36 -07004250 if (IS_ERR(st_sysfs_class)) {
Linus Torvalds1da177e2005-04-16 15:20:36 -07004251 printk(KERN_ERR "Unable create sysfs class for SCSI tapes\n");
Jeff Garzik13026a62006-10-04 06:00:38 -04004252 return PTR_ERR(st_sysfs_class);
Linus Torvalds1da177e2005-04-16 15:20:36 -07004253 }
4254
Jeff Garzik13026a62006-10-04 06:00:38 -04004255 err = register_chrdev_region(MKDEV(SCSI_TAPE_MAJOR, 0),
4256 ST_MAX_TAPE_ENTRIES, "st");
4257 if (err) {
4258 printk(KERN_ERR "Unable to get major %d for SCSI tapes\n",
4259 SCSI_TAPE_MAJOR);
4260 goto err_class;
Linus Torvalds1da177e2005-04-16 15:20:36 -07004261 }
Jeff Garzik13026a62006-10-04 06:00:38 -04004262
4263 err = scsi_register_driver(&st_template.gendrv);
4264 if (err)
4265 goto err_chrdev;
4266
Robert P. J. Day405ae7d2007-02-17 19:13:42 +01004267 err = do_create_sysfs_files();
Jeff Garzik13026a62006-10-04 06:00:38 -04004268 if (err)
4269 goto err_scsidrv;
4270
4271 return 0;
4272
4273err_scsidrv:
4274 scsi_unregister_driver(&st_template.gendrv);
4275err_chrdev:
4276 unregister_chrdev_region(MKDEV(SCSI_TAPE_MAJOR, 0),
4277 ST_MAX_TAPE_ENTRIES);
4278err_class:
Kai Makisarac2c96f42005-08-02 12:21:51 +03004279 class_destroy(st_sysfs_class);
Jeff Garzik13026a62006-10-04 06:00:38 -04004280 return err;
Linus Torvalds1da177e2005-04-16 15:20:36 -07004281}
4282
4283static void __exit exit_st(void)
4284{
Robert P. J. Day405ae7d2007-02-17 19:13:42 +01004285 do_remove_sysfs_files();
Linus Torvalds1da177e2005-04-16 15:20:36 -07004286 scsi_unregister_driver(&st_template.gendrv);
4287 unregister_chrdev_region(MKDEV(SCSI_TAPE_MAJOR, 0),
4288 ST_MAX_TAPE_ENTRIES);
Kai Makisarac2c96f42005-08-02 12:21:51 +03004289 class_destroy(st_sysfs_class);
Linus Torvalds1da177e2005-04-16 15:20:36 -07004290 kfree(scsi_tapes);
4291 printk(KERN_INFO "st: Unloaded.\n");
4292}
4293
4294module_init(init_st);
4295module_exit(exit_st);
4296
4297
4298/* The sysfs driver interface. Read-only at the moment */
4299static ssize_t st_try_direct_io_show(struct device_driver *ddp, char *buf)
4300{
4301 return snprintf(buf, PAGE_SIZE, "%d\n", try_direct_io);
4302}
4303static DRIVER_ATTR(try_direct_io, S_IRUGO, st_try_direct_io_show, NULL);
4304
4305static ssize_t st_fixed_buffer_size_show(struct device_driver *ddp, char *buf)
4306{
4307 return snprintf(buf, PAGE_SIZE, "%d\n", st_fixed_buffer_size);
4308}
4309static DRIVER_ATTR(fixed_buffer_size, S_IRUGO, st_fixed_buffer_size_show, NULL);
4310
4311static ssize_t st_max_sg_segs_show(struct device_driver *ddp, char *buf)
4312{
4313 return snprintf(buf, PAGE_SIZE, "%d\n", st_max_sg_segs);
4314}
4315static DRIVER_ATTR(max_sg_segs, S_IRUGO, st_max_sg_segs_show, NULL);
4316
4317static ssize_t st_version_show(struct device_driver *ddd, char *buf)
4318{
4319 return snprintf(buf, PAGE_SIZE, "[%s]\n", verstr);
4320}
4321static DRIVER_ATTR(version, S_IRUGO, st_version_show, NULL);
4322
Robert P. J. Day405ae7d2007-02-17 19:13:42 +01004323static int do_create_sysfs_files(void)
Linus Torvalds1da177e2005-04-16 15:20:36 -07004324{
Robert P. J. Day405ae7d2007-02-17 19:13:42 +01004325 struct device_driver *sysfs = &st_template.gendrv;
Jeff Garzik13026a62006-10-04 06:00:38 -04004326 int err;
Linus Torvalds1da177e2005-04-16 15:20:36 -07004327
Robert P. J. Day405ae7d2007-02-17 19:13:42 +01004328 err = driver_create_file(sysfs, &driver_attr_try_direct_io);
Jeff Garzik13026a62006-10-04 06:00:38 -04004329 if (err)
4330 return err;
Robert P. J. Day405ae7d2007-02-17 19:13:42 +01004331 err = driver_create_file(sysfs, &driver_attr_fixed_buffer_size);
Jeff Garzik13026a62006-10-04 06:00:38 -04004332 if (err)
4333 goto err_try_direct_io;
Robert P. J. Day405ae7d2007-02-17 19:13:42 +01004334 err = driver_create_file(sysfs, &driver_attr_max_sg_segs);
Jeff Garzik13026a62006-10-04 06:00:38 -04004335 if (err)
4336 goto err_attr_fixed_buf;
Robert P. J. Day405ae7d2007-02-17 19:13:42 +01004337 err = driver_create_file(sysfs, &driver_attr_version);
Jeff Garzik13026a62006-10-04 06:00:38 -04004338 if (err)
4339 goto err_attr_max_sg;
4340
4341 return 0;
4342
4343err_attr_max_sg:
Robert P. J. Day405ae7d2007-02-17 19:13:42 +01004344 driver_remove_file(sysfs, &driver_attr_max_sg_segs);
Jeff Garzik13026a62006-10-04 06:00:38 -04004345err_attr_fixed_buf:
Robert P. J. Day405ae7d2007-02-17 19:13:42 +01004346 driver_remove_file(sysfs, &driver_attr_fixed_buffer_size);
Jeff Garzik13026a62006-10-04 06:00:38 -04004347err_try_direct_io:
Robert P. J. Day405ae7d2007-02-17 19:13:42 +01004348 driver_remove_file(sysfs, &driver_attr_try_direct_io);
Jeff Garzik13026a62006-10-04 06:00:38 -04004349 return err;
Linus Torvalds1da177e2005-04-16 15:20:36 -07004350}
4351
Robert P. J. Day405ae7d2007-02-17 19:13:42 +01004352static void do_remove_sysfs_files(void)
Linus Torvalds1da177e2005-04-16 15:20:36 -07004353{
Robert P. J. Day405ae7d2007-02-17 19:13:42 +01004354 struct device_driver *sysfs = &st_template.gendrv;
Linus Torvalds1da177e2005-04-16 15:20:36 -07004355
Robert P. J. Day405ae7d2007-02-17 19:13:42 +01004356 driver_remove_file(sysfs, &driver_attr_version);
4357 driver_remove_file(sysfs, &driver_attr_max_sg_segs);
4358 driver_remove_file(sysfs, &driver_attr_fixed_buffer_size);
4359 driver_remove_file(sysfs, &driver_attr_try_direct_io);
Linus Torvalds1da177e2005-04-16 15:20:36 -07004360}
4361
4362
4363/* The sysfs simple class interface */
Tony Jonesee959b02008-02-22 00:13:36 +01004364static ssize_t
4365st_defined_show(struct device *dev, struct device_attribute *attr, char *buf)
Linus Torvalds1da177e2005-04-16 15:20:36 -07004366{
James Bottomley7d15d6a2008-03-14 14:12:43 -07004367 struct st_modedef *STm = dev_get_drvdata(dev);
Linus Torvalds1da177e2005-04-16 15:20:36 -07004368 ssize_t l = 0;
4369
4370 l = snprintf(buf, PAGE_SIZE, "%d\n", STm->defined);
4371 return l;
4372}
4373
Tony Jonesee959b02008-02-22 00:13:36 +01004374DEVICE_ATTR(defined, S_IRUGO, st_defined_show, NULL);
Linus Torvalds1da177e2005-04-16 15:20:36 -07004375
Tony Jonesee959b02008-02-22 00:13:36 +01004376static ssize_t
4377st_defblk_show(struct device *dev, struct device_attribute *attr, char *buf)
Linus Torvalds1da177e2005-04-16 15:20:36 -07004378{
James Bottomley7d15d6a2008-03-14 14:12:43 -07004379 struct st_modedef *STm = dev_get_drvdata(dev);
Linus Torvalds1da177e2005-04-16 15:20:36 -07004380 ssize_t l = 0;
4381
4382 l = snprintf(buf, PAGE_SIZE, "%d\n", STm->default_blksize);
4383 return l;
4384}
4385
Tony Jonesee959b02008-02-22 00:13:36 +01004386DEVICE_ATTR(default_blksize, S_IRUGO, st_defblk_show, NULL);
Linus Torvalds1da177e2005-04-16 15:20:36 -07004387
Tony Jonesee959b02008-02-22 00:13:36 +01004388static ssize_t
4389st_defdensity_show(struct device *dev, struct device_attribute *attr, char *buf)
Linus Torvalds1da177e2005-04-16 15:20:36 -07004390{
James Bottomley7d15d6a2008-03-14 14:12:43 -07004391 struct st_modedef *STm = dev_get_drvdata(dev);
Linus Torvalds1da177e2005-04-16 15:20:36 -07004392 ssize_t l = 0;
4393 char *fmt;
4394
4395 fmt = STm->default_density >= 0 ? "0x%02x\n" : "%d\n";
4396 l = snprintf(buf, PAGE_SIZE, fmt, STm->default_density);
4397 return l;
4398}
4399
Tony Jonesee959b02008-02-22 00:13:36 +01004400DEVICE_ATTR(default_density, S_IRUGO, st_defdensity_show, NULL);
Linus Torvalds1da177e2005-04-16 15:20:36 -07004401
Tony Jonesee959b02008-02-22 00:13:36 +01004402static ssize_t
4403st_defcompression_show(struct device *dev, struct device_attribute *attr,
4404 char *buf)
Linus Torvalds1da177e2005-04-16 15:20:36 -07004405{
James Bottomley7d15d6a2008-03-14 14:12:43 -07004406 struct st_modedef *STm = dev_get_drvdata(dev);
Linus Torvalds1da177e2005-04-16 15:20:36 -07004407 ssize_t l = 0;
4408
4409 l = snprintf(buf, PAGE_SIZE, "%d\n", STm->default_compression - 1);
4410 return l;
4411}
4412
Tony Jonesee959b02008-02-22 00:13:36 +01004413DEVICE_ATTR(default_compression, S_IRUGO, st_defcompression_show, NULL);
Linus Torvalds1da177e2005-04-16 15:20:36 -07004414
Tony Jonesee959b02008-02-22 00:13:36 +01004415static ssize_t
4416st_options_show(struct device *dev, struct device_attribute *attr, char *buf)
Kai Makisarab174be02008-02-24 22:29:12 +02004417{
James Bottomley7d15d6a2008-03-14 14:12:43 -07004418 struct st_modedef *STm = dev_get_drvdata(dev);
Kai Makisarab174be02008-02-24 22:29:12 +02004419 struct scsi_tape *STp;
4420 int i, j, options;
4421 ssize_t l = 0;
4422
4423 for (i=0; i < st_dev_max; i++) {
4424 for (j=0; j < ST_NBR_MODES; j++)
4425 if (&scsi_tapes[i]->modes[j] == STm)
4426 break;
4427 if (j < ST_NBR_MODES)
4428 break;
4429 }
4430 if (i == st_dev_max)
4431 return 0; /* should never happen */
4432
4433 STp = scsi_tapes[i];
4434
4435 options = STm->do_buffer_writes ? MT_ST_BUFFER_WRITES : 0;
4436 options |= STm->do_async_writes ? MT_ST_ASYNC_WRITES : 0;
4437 options |= STm->do_read_ahead ? MT_ST_READ_AHEAD : 0;
4438 DEB( options |= debugging ? MT_ST_DEBUGGING : 0 );
4439 options |= STp->two_fm ? MT_ST_TWO_FM : 0;
4440 options |= STp->fast_mteom ? MT_ST_FAST_MTEOM : 0;
4441 options |= STm->defaults_for_writes ? MT_ST_DEF_WRITES : 0;
4442 options |= STp->can_bsr ? MT_ST_CAN_BSR : 0;
4443 options |= STp->omit_blklims ? MT_ST_NO_BLKLIMS : 0;
4444 options |= STp->can_partitions ? MT_ST_CAN_PARTITIONS : 0;
4445 options |= STp->scsi2_logical ? MT_ST_SCSI2LOGICAL : 0;
4446 options |= STm->sysv ? MT_ST_SYSV : 0;
4447 options |= STp->immediate ? MT_ST_NOWAIT : 0;
4448 options |= STp->sili ? MT_ST_SILI : 0;
4449
4450 l = snprintf(buf, PAGE_SIZE, "0x%08x\n", options);
4451 return l;
4452}
4453
Tony Jonesee959b02008-02-22 00:13:36 +01004454DEVICE_ATTR(options, S_IRUGO, st_options_show, NULL);
Kai Makisarab174be02008-02-24 22:29:12 +02004455
Jeff Garzik13026a62006-10-04 06:00:38 -04004456static int do_create_class_files(struct scsi_tape *STp, int dev_num, int mode)
Linus Torvalds1da177e2005-04-16 15:20:36 -07004457{
4458 int i, rew, error;
4459 char name[10];
Tony Jonesee959b02008-02-22 00:13:36 +01004460 struct device *st_class_member;
Linus Torvalds1da177e2005-04-16 15:20:36 -07004461
Linus Torvalds1da177e2005-04-16 15:20:36 -07004462 for (rew=0; rew < 2; rew++) {
4463 /* Make sure that the minor numbers corresponding to the four
4464 first modes always get the same names */
4465 i = mode << (4 - ST_NBR_MODE_BITS);
4466 snprintf(name, 10, "%s%s%s", rew ? "n" : "",
4467 STp->disk->disk_name, st_formats[i]);
4468 st_class_member =
Greg Kroah-Hartmand73a1a62008-07-21 20:03:34 -07004469 device_create(st_sysfs_class, &STp->device->sdev_gendev,
4470 MKDEV(SCSI_TAPE_MAJOR,
4471 TAPE_MINOR(dev_num, mode, rew)),
4472 &STp->modes[mode], "%s", name);
Linus Torvalds1da177e2005-04-16 15:20:36 -07004473 if (IS_ERR(st_class_member)) {
Tony Jonesee959b02008-02-22 00:13:36 +01004474 printk(KERN_WARNING "st%d: device_create failed\n",
Linus Torvalds1da177e2005-04-16 15:20:36 -07004475 dev_num);
Jeff Garzik13026a62006-10-04 06:00:38 -04004476 error = PTR_ERR(st_class_member);
Linus Torvalds1da177e2005-04-16 15:20:36 -07004477 goto out;
4478 }
Linus Torvalds1da177e2005-04-16 15:20:36 -07004479
Tony Jonesee959b02008-02-22 00:13:36 +01004480 error = device_create_file(st_class_member,
4481 &dev_attr_defined);
Jeff Garzik13026a62006-10-04 06:00:38 -04004482 if (error) goto out;
Tony Jonesee959b02008-02-22 00:13:36 +01004483 error = device_create_file(st_class_member,
4484 &dev_attr_default_blksize);
Jeff Garzik13026a62006-10-04 06:00:38 -04004485 if (error) goto out;
Tony Jonesee959b02008-02-22 00:13:36 +01004486 error = device_create_file(st_class_member,
4487 &dev_attr_default_density);
Jeff Garzik13026a62006-10-04 06:00:38 -04004488 if (error) goto out;
Tony Jonesee959b02008-02-22 00:13:36 +01004489 error = device_create_file(st_class_member,
4490 &dev_attr_default_compression);
Jeff Garzik13026a62006-10-04 06:00:38 -04004491 if (error) goto out;
Tony Jonesee959b02008-02-22 00:13:36 +01004492 error = device_create_file(st_class_member,
4493 &dev_attr_options);
Kai Makisarab174be02008-02-24 22:29:12 +02004494 if (error) goto out;
Jeff Garzik13026a62006-10-04 06:00:38 -04004495
Linus Torvalds1da177e2005-04-16 15:20:36 -07004496 if (mode == 0 && rew == 0) {
4497 error = sysfs_create_link(&STp->device->sdev_gendev.kobj,
4498 &st_class_member->kobj,
4499 "tape");
4500 if (error) {
4501 printk(KERN_ERR
4502 "st%d: Can't create sysfs link from SCSI device.\n",
4503 dev_num);
Jeff Garzik13026a62006-10-04 06:00:38 -04004504 goto out;
Linus Torvalds1da177e2005-04-16 15:20:36 -07004505 }
4506 }
4507 }
Jeff Garzik13026a62006-10-04 06:00:38 -04004508
4509 return 0;
4510
4511out:
4512 return error;
Linus Torvalds1da177e2005-04-16 15:20:36 -07004513}
4514
Linus Torvalds1da177e2005-04-16 15:20:36 -07004515/* The following functions may be useful for a larger audience. */
4516static int sgl_map_user_pages(struct scatterlist *sgl, const unsigned int max_pages,
4517 unsigned long uaddr, size_t count, int rw)
4518{
James Bottomley07542b82005-08-31 20:27:22 -04004519 unsigned long end = (uaddr + count + PAGE_SIZE - 1) >> PAGE_SHIFT;
4520 unsigned long start = uaddr >> PAGE_SHIFT;
4521 const int nr_pages = end - start;
Linus Torvalds1da177e2005-04-16 15:20:36 -07004522 int res, i, j;
Linus Torvalds1da177e2005-04-16 15:20:36 -07004523 struct page **pages;
4524
Linus Torvalds1da177e2005-04-16 15:20:36 -07004525 /* User attempted Overflow! */
4526 if ((uaddr + count) < uaddr)
4527 return -EINVAL;
4528
4529 /* Too big */
4530 if (nr_pages > max_pages)
4531 return -ENOMEM;
4532
4533 /* Hmm? */
4534 if (count == 0)
4535 return 0;
4536
4537 if ((pages = kmalloc(max_pages * sizeof(*pages), GFP_KERNEL)) == NULL)
4538 return -ENOMEM;
4539
4540 /* Try to fault in all of the necessary pages */
4541 down_read(&current->mm->mmap_sem);
4542 /* rw==READ means read from drive, write into memory area */
4543 res = get_user_pages(
4544 current,
4545 current->mm,
4546 uaddr,
4547 nr_pages,
4548 rw == READ,
4549 0, /* don't force */
4550 pages,
4551 NULL);
4552 up_read(&current->mm->mmap_sem);
4553
4554 /* Errors and no page mapped should return here */
4555 if (res < nr_pages)
4556 goto out_unmap;
4557
4558 for (i=0; i < nr_pages; i++) {
4559 /* FIXME: flush superflous for rw==READ,
4560 * probably wrong function for rw==WRITE
4561 */
4562 flush_dcache_page(pages[i]);
4563 }
4564
4565 /* Populate the scatter/gather list */
Jens Axboe642f1492007-10-24 11:20:47 +02004566 sg_set_page(&sgl[0], pages[0], 0, uaddr & ~PAGE_MASK);
Linus Torvalds1da177e2005-04-16 15:20:36 -07004567 if (nr_pages > 1) {
4568 sgl[0].length = PAGE_SIZE - sgl[0].offset;
4569 count -= sgl[0].length;
4570 for (i=1; i < nr_pages ; i++) {
Jens Axboe642f1492007-10-24 11:20:47 +02004571 sg_set_page(&sgl[i], pages[i],
4572 count < PAGE_SIZE ? count : PAGE_SIZE, 0);;
Linus Torvalds1da177e2005-04-16 15:20:36 -07004573 count -= PAGE_SIZE;
4574 }
4575 }
4576 else {
4577 sgl[0].length = count;
4578 }
4579
4580 kfree(pages);
4581 return nr_pages;
4582
4583 out_unmap:
4584 if (res > 0) {
4585 for (j=0; j < res; j++)
4586 page_cache_release(pages[j]);
Hugh Dickins6bc733e2005-12-01 20:21:57 +00004587 res = 0;
Linus Torvalds1da177e2005-04-16 15:20:36 -07004588 }
4589 kfree(pages);
4590 return res;
4591}
4592
4593
4594/* And unmap them... */
4595static int sgl_unmap_user_pages(struct scatterlist *sgl, const unsigned int nr_pages,
4596 int dirtied)
4597{
4598 int i;
4599
4600 for (i=0; i < nr_pages; i++) {
Jens Axboe45711f12007-10-22 21:19:53 +02004601 struct page *page = sg_page(&sgl[i]);
Nick Pigginb5810032005-10-29 18:16:12 -07004602
Nick Pigginb5810032005-10-29 18:16:12 -07004603 if (dirtied)
4604 SetPageDirty(page);
Linus Torvalds1da177e2005-04-16 15:20:36 -07004605 /* FIXME: cache flush missing for rw==READ
4606 * FIXME: call the correct reference counting function
4607 */
Nick Pigginb5810032005-10-29 18:16:12 -07004608 page_cache_release(page);
Linus Torvalds1da177e2005-04-16 15:20:36 -07004609 }
4610
4611 return 0;
4612}