blob: c959bdc55f4f765d7a02c096a6b1be64ca30c0c8 [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
454static struct st_request *st_allocate_request(void)
455{
456 return kzalloc(sizeof(struct st_request), GFP_KERNEL);
457}
458
459static void st_release_request(struct st_request *streq)
460{
461 kfree(streq);
Linus Torvalds1da177e2005-04-16 15:20:36 -0700462}
463
464/* Do the scsi command. Waits until command performed if do_wait is true.
465 Otherwise write_behind_check() is used to check that the command
466 has finished. */
Mike Christie8b05b772005-11-08 04:06:44 -0600467static struct st_request *
468st_do_scsi(struct st_request * SRpnt, struct scsi_tape * STp, unsigned char *cmd,
Linus Torvalds1da177e2005-04-16 15:20:36 -0700469 int bytes, int direction, int timeout, int retries, int do_wait)
470{
Kai Makisaraf03a5672005-08-02 13:40:47 +0300471 struct completion *waiting;
Linus Torvalds1da177e2005-04-16 15:20:36 -0700472
Kai Makisaraf03a5672005-08-02 13:40:47 +0300473 /* if async, make sure there's no command outstanding */
474 if (!do_wait && ((STp->buffer)->last_SRpnt)) {
475 printk(KERN_ERR "%s: Async command already active.\n",
476 tape_name(STp));
477 if (signal_pending(current))
478 (STp->buffer)->syscall_result = (-EINTR);
479 else
480 (STp->buffer)->syscall_result = (-EBUSY);
481 return NULL;
482 }
483
Linus Torvalds1da177e2005-04-16 15:20:36 -0700484 if (SRpnt == NULL) {
Mike Christie8b05b772005-11-08 04:06:44 -0600485 SRpnt = st_allocate_request();
Linus Torvalds1da177e2005-04-16 15:20:36 -0700486 if (SRpnt == NULL) {
487 DEBC( printk(KERN_ERR "%s: Can't get SCSI request.\n",
488 tape_name(STp)); );
489 if (signal_pending(current))
490 (STp->buffer)->syscall_result = (-EINTR);
491 else
492 (STp->buffer)->syscall_result = (-EBUSY);
493 return NULL;
494 }
Mike Christie8b05b772005-11-08 04:06:44 -0600495 SRpnt->stp = STp;
Linus Torvalds1da177e2005-04-16 15:20:36 -0700496 }
497
Kai Makisaraf03a5672005-08-02 13:40:47 +0300498 /* If async IO, set last_SRpnt. This ptr tells write_behind_check
499 which IO is outstanding. It's nulled out when the IO completes. */
500 if (!do_wait)
501 (STp->buffer)->last_SRpnt = SRpnt;
502
503 waiting = &STp->wait;
504 init_completion(waiting);
Mike Christie8b05b772005-11-08 04:06:44 -0600505 SRpnt->waiting = waiting;
506
507 if (!STp->buffer->do_dio)
508 buf_to_sg(STp->buffer, bytes);
509
510 memcpy(SRpnt->cmd, cmd, sizeof(SRpnt->cmd));
Linus Torvalds1da177e2005-04-16 15:20:36 -0700511 STp->buffer->cmdstat.have_sense = 0;
Mike Christie8b05b772005-11-08 04:06:44 -0600512 STp->buffer->syscall_result = 0;
Linus Torvalds1da177e2005-04-16 15:20:36 -0700513
brking@us.ibm.combb1d1072006-01-23 15:03:22 -0600514 if (scsi_execute_async(STp->device, cmd, COMMAND_SIZE(cmd[0]), direction,
Mike Christie8b05b772005-11-08 04:06:44 -0600515 &((STp->buffer)->sg[0]), bytes, (STp->buffer)->sg_segs,
Kai Makisara787926b2005-11-13 10:04:44 +0200516 timeout, retries, SRpnt, st_sleep_done, GFP_KERNEL)) {
Mike Christie8b05b772005-11-08 04:06:44 -0600517 /* could not allocate the buffer or request was too large */
518 (STp->buffer)->syscall_result = (-EBUSY);
Kai Makisara787926b2005-11-13 10:04:44 +0200519 (STp->buffer)->last_SRpnt = NULL;
520 }
Mike Christie8b05b772005-11-08 04:06:44 -0600521 else if (do_wait) {
Kai Makisaraf03a5672005-08-02 13:40:47 +0300522 wait_for_completion(waiting);
Mike Christie8b05b772005-11-08 04:06:44 -0600523 SRpnt->waiting = NULL;
Linus Torvalds1da177e2005-04-16 15:20:36 -0700524 (STp->buffer)->syscall_result = st_chk_result(STp, SRpnt);
525 }
Mike Christie8b05b772005-11-08 04:06:44 -0600526
Linus Torvalds1da177e2005-04-16 15:20:36 -0700527 return SRpnt;
528}
529
530
531/* Handle the write-behind checking (waits for completion). Returns -ENOSPC if
532 write has been correct but EOM early warning reached, -EIO if write ended in
533 error or zero if write successful. Asynchronous writes are used only in
534 variable block mode. */
535static int write_behind_check(struct scsi_tape * STp)
536{
537 int retval = 0;
538 struct st_buffer *STbuffer;
539 struct st_partstat *STps;
540 struct st_cmdstatus *cmdstatp;
Mike Christie8b05b772005-11-08 04:06:44 -0600541 struct st_request *SRpnt;
Linus Torvalds1da177e2005-04-16 15:20:36 -0700542
543 STbuffer = STp->buffer;
544 if (!STbuffer->writing)
545 return 0;
546
547 DEB(
548 if (STp->write_pending)
549 STp->nbr_waits++;
550 else
551 STp->nbr_finished++;
552 ) /* end DEB */
553
554 wait_for_completion(&(STp->wait));
Kai Makisaraf03a5672005-08-02 13:40:47 +0300555 SRpnt = STbuffer->last_SRpnt;
556 STbuffer->last_SRpnt = NULL;
Mike Christie8b05b772005-11-08 04:06:44 -0600557 SRpnt->waiting = NULL;
Linus Torvalds1da177e2005-04-16 15:20:36 -0700558
Kai Makisaraf03a5672005-08-02 13:40:47 +0300559 (STp->buffer)->syscall_result = st_chk_result(STp, SRpnt);
Mike Christie8b05b772005-11-08 04:06:44 -0600560 st_release_request(SRpnt);
Linus Torvalds1da177e2005-04-16 15:20:36 -0700561
562 STbuffer->buffer_bytes -= STbuffer->writing;
563 STps = &(STp->ps[STp->partition]);
564 if (STps->drv_block >= 0) {
565 if (STp->block_size == 0)
566 STps->drv_block++;
567 else
568 STps->drv_block += STbuffer->writing / STp->block_size;
569 }
570
571 cmdstatp = &STbuffer->cmdstat;
572 if (STbuffer->syscall_result) {
573 retval = -EIO;
574 if (cmdstatp->have_sense && !cmdstatp->deferred &&
575 (cmdstatp->flags & SENSE_EOM) &&
576 (cmdstatp->sense_hdr.sense_key == NO_SENSE ||
577 cmdstatp->sense_hdr.sense_key == RECOVERED_ERROR)) {
578 /* EOM at write-behind, has all data been written? */
579 if (!cmdstatp->remainder_valid ||
580 cmdstatp->uremainder64 == 0)
581 retval = -ENOSPC;
582 }
583 if (retval == -EIO)
584 STps->drv_block = -1;
585 }
586 STbuffer->writing = 0;
587
588 DEB(if (debugging && retval)
589 printk(ST_DEB_MSG "%s: Async write error %x, return value %d.\n",
590 tape_name(STp), STbuffer->cmdstat.midlevel_result, retval);) /* end DEB */
591
592 return retval;
593}
594
595
596/* Step over EOF if it has been inadvertently crossed (ioctl not used because
597 it messes up the block number). */
598static int cross_eof(struct scsi_tape * STp, int forward)
599{
Mike Christie8b05b772005-11-08 04:06:44 -0600600 struct st_request *SRpnt;
Linus Torvalds1da177e2005-04-16 15:20:36 -0700601 unsigned char cmd[MAX_COMMAND_SIZE];
602
603 cmd[0] = SPACE;
604 cmd[1] = 0x01; /* Space FileMarks */
605 if (forward) {
606 cmd[2] = cmd[3] = 0;
607 cmd[4] = 1;
608 } else
609 cmd[2] = cmd[3] = cmd[4] = 0xff; /* -1 filemarks */
610 cmd[5] = 0;
611
612 DEBC(printk(ST_DEB_MSG "%s: Stepping over filemark %s.\n",
613 tape_name(STp), forward ? "forward" : "backward"));
614
615 SRpnt = st_do_scsi(NULL, STp, cmd, 0, DMA_NONE,
616 STp->device->timeout, MAX_RETRIES, 1);
617 if (!SRpnt)
618 return (STp->buffer)->syscall_result;
619
Mike Christie8b05b772005-11-08 04:06:44 -0600620 st_release_request(SRpnt);
Linus Torvalds1da177e2005-04-16 15:20:36 -0700621 SRpnt = NULL;
622
623 if ((STp->buffer)->cmdstat.midlevel_result != 0)
624 printk(KERN_ERR "%s: Stepping over filemark %s failed.\n",
625 tape_name(STp), forward ? "forward" : "backward");
626
627 return (STp->buffer)->syscall_result;
628}
629
630
631/* Flush the write buffer (never need to write if variable blocksize). */
Adrian Bunk8ef8d592008-04-14 17:17:16 +0300632static int st_flush_write_buffer(struct scsi_tape * STp)
Linus Torvalds1da177e2005-04-16 15:20:36 -0700633{
Kai Makisara786231a2008-07-11 15:06:40 +0300634 int transfer, blks;
Linus Torvalds1da177e2005-04-16 15:20:36 -0700635 int result;
636 unsigned char cmd[MAX_COMMAND_SIZE];
Mike Christie8b05b772005-11-08 04:06:44 -0600637 struct st_request *SRpnt;
Linus Torvalds1da177e2005-04-16 15:20:36 -0700638 struct st_partstat *STps;
639
640 result = write_behind_check(STp);
641 if (result)
642 return result;
643
644 result = 0;
645 if (STp->dirty == 1) {
646
Kai Makisara786231a2008-07-11 15:06:40 +0300647 transfer = STp->buffer->buffer_bytes;
Linus Torvalds1da177e2005-04-16 15:20:36 -0700648 DEBC(printk(ST_DEB_MSG "%s: Flushing %d bytes.\n",
649 tape_name(STp), transfer));
650
Linus Torvalds1da177e2005-04-16 15:20:36 -0700651 memset(cmd, 0, MAX_COMMAND_SIZE);
652 cmd[0] = WRITE_6;
653 cmd[1] = 1;
654 blks = transfer / STp->block_size;
655 cmd[2] = blks >> 16;
656 cmd[3] = blks >> 8;
657 cmd[4] = blks;
658
659 SRpnt = st_do_scsi(NULL, STp, cmd, transfer, DMA_TO_DEVICE,
660 STp->device->timeout, MAX_WRITE_RETRIES, 1);
661 if (!SRpnt)
662 return (STp->buffer)->syscall_result;
663
664 STps = &(STp->ps[STp->partition]);
665 if ((STp->buffer)->syscall_result != 0) {
666 struct st_cmdstatus *cmdstatp = &STp->buffer->cmdstat;
667
668 if (cmdstatp->have_sense && !cmdstatp->deferred &&
669 (cmdstatp->flags & SENSE_EOM) &&
670 (cmdstatp->sense_hdr.sense_key == NO_SENSE ||
671 cmdstatp->sense_hdr.sense_key == RECOVERED_ERROR) &&
672 (!cmdstatp->remainder_valid ||
673 cmdstatp->uremainder64 == 0)) { /* All written at EOM early warning */
674 STp->dirty = 0;
675 (STp->buffer)->buffer_bytes = 0;
676 if (STps->drv_block >= 0)
677 STps->drv_block += blks;
678 result = (-ENOSPC);
679 } else {
680 printk(KERN_ERR "%s: Error on flush.\n",
681 tape_name(STp));
682 STps->drv_block = (-1);
683 result = (-EIO);
684 }
685 } else {
686 if (STps->drv_block >= 0)
687 STps->drv_block += blks;
688 STp->dirty = 0;
689 (STp->buffer)->buffer_bytes = 0;
690 }
Mike Christie8b05b772005-11-08 04:06:44 -0600691 st_release_request(SRpnt);
Linus Torvalds1da177e2005-04-16 15:20:36 -0700692 SRpnt = NULL;
693 }
694 return result;
695}
696
697
698/* Flush the tape buffer. The tape will be positioned correctly unless
699 seek_next is true. */
700static int flush_buffer(struct scsi_tape *STp, int seek_next)
701{
702 int backspace, result;
703 struct st_buffer *STbuffer;
704 struct st_partstat *STps;
705
706 STbuffer = STp->buffer;
707
708 /*
709 * If there was a bus reset, block further access
710 * to this device.
711 */
712 if (STp->pos_unknown)
713 return (-EIO);
714
715 if (STp->ready != ST_READY)
716 return 0;
717 STps = &(STp->ps[STp->partition]);
718 if (STps->rw == ST_WRITING) /* Writing */
Adrian Bunk8ef8d592008-04-14 17:17:16 +0300719 return st_flush_write_buffer(STp);
Linus Torvalds1da177e2005-04-16 15:20:36 -0700720
721 if (STp->block_size == 0)
722 return 0;
723
724 backspace = ((STp->buffer)->buffer_bytes +
725 (STp->buffer)->read_pointer) / STp->block_size -
726 ((STp->buffer)->read_pointer + STp->block_size - 1) /
727 STp->block_size;
728 (STp->buffer)->buffer_bytes = 0;
729 (STp->buffer)->read_pointer = 0;
730 result = 0;
731 if (!seek_next) {
732 if (STps->eof == ST_FM_HIT) {
733 result = cross_eof(STp, 0); /* Back over the EOF hit */
734 if (!result)
735 STps->eof = ST_NOEOF;
736 else {
737 if (STps->drv_file >= 0)
738 STps->drv_file++;
739 STps->drv_block = 0;
740 }
741 }
742 if (!result && backspace > 0)
743 result = st_int_ioctl(STp, MTBSR, backspace);
744 } else if (STps->eof == ST_FM_HIT) {
745 if (STps->drv_file >= 0)
746 STps->drv_file++;
747 STps->drv_block = 0;
748 STps->eof = ST_NOEOF;
749 }
750 return result;
751
752}
753
754/* Set the mode parameters */
755static int set_mode_densblk(struct scsi_tape * STp, struct st_modedef * STm)
756{
757 int set_it = 0;
758 unsigned long arg;
759 char *name = tape_name(STp);
760
761 if (!STp->density_changed &&
762 STm->default_density >= 0 &&
763 STm->default_density != STp->density) {
764 arg = STm->default_density;
765 set_it = 1;
766 } else
767 arg = STp->density;
768 arg <<= MT_ST_DENSITY_SHIFT;
769 if (!STp->blksize_changed &&
770 STm->default_blksize >= 0 &&
771 STm->default_blksize != STp->block_size) {
772 arg |= STm->default_blksize;
773 set_it = 1;
774 } else
775 arg |= STp->block_size;
776 if (set_it &&
777 st_int_ioctl(STp, SET_DENS_AND_BLK, arg)) {
778 printk(KERN_WARNING
779 "%s: Can't set default block size to %d bytes and density %x.\n",
780 name, STm->default_blksize, STm->default_density);
781 if (modes_defined)
782 return (-EINVAL);
783 }
784 return 0;
785}
786
787
Mike Christie8b05b772005-11-08 04:06:44 -0600788/* Lock or unlock the drive door. Don't use when st_request allocated. */
Linus Torvalds1da177e2005-04-16 15:20:36 -0700789static int do_door_lock(struct scsi_tape * STp, int do_lock)
790{
791 int retval, cmd;
792 DEB(char *name = tape_name(STp);)
793
794
795 cmd = do_lock ? SCSI_IOCTL_DOORLOCK : SCSI_IOCTL_DOORUNLOCK;
796 DEBC(printk(ST_DEB_MSG "%s: %socking drive door.\n", name,
797 do_lock ? "L" : "Unl"));
798 retval = scsi_ioctl(STp->device, cmd, NULL);
799 if (!retval) {
800 STp->door_locked = do_lock ? ST_LOCKED_EXPLICIT : ST_UNLOCKED;
801 }
802 else {
803 STp->door_locked = ST_LOCK_FAILS;
804 }
805 return retval;
806}
807
808
809/* Set the internal state after reset */
810static void reset_state(struct scsi_tape *STp)
811{
812 int i;
813 struct st_partstat *STps;
814
815 STp->pos_unknown = 0;
816 for (i = 0; i < ST_NBR_PARTITIONS; i++) {
817 STps = &(STp->ps[i]);
818 STps->rw = ST_IDLE;
819 STps->eof = ST_NOEOF;
820 STps->at_sm = 0;
821 STps->last_block_valid = 0;
822 STps->drv_block = -1;
823 STps->drv_file = -1;
824 }
825 if (STp->can_partitions) {
826 STp->partition = find_partition(STp);
827 if (STp->partition < 0)
828 STp->partition = 0;
829 STp->new_partition = STp->partition;
830 }
831}
832
833/* Test if the drive is ready. Returns either one of the codes below or a negative system
834 error code. */
835#define CHKRES_READY 0
836#define CHKRES_NEW_SESSION 1
837#define CHKRES_NOT_READY 2
838#define CHKRES_NO_TAPE 3
839
840#define MAX_ATTENTIONS 10
841
842static int test_ready(struct scsi_tape *STp, int do_wait)
843{
844 int attentions, waits, max_wait, scode;
845 int retval = CHKRES_READY, new_session = 0;
846 unsigned char cmd[MAX_COMMAND_SIZE];
Mike Christie8b05b772005-11-08 04:06:44 -0600847 struct st_request *SRpnt = NULL;
Linus Torvalds1da177e2005-04-16 15:20:36 -0700848 struct st_cmdstatus *cmdstatp = &STp->buffer->cmdstat;
849
850 max_wait = do_wait ? ST_BLOCK_SECONDS : 0;
851
852 for (attentions=waits=0; ; ) {
853 memset((void *) &cmd[0], 0, MAX_COMMAND_SIZE);
854 cmd[0] = TEST_UNIT_READY;
855 SRpnt = st_do_scsi(SRpnt, STp, cmd, 0, DMA_NONE,
856 STp->long_timeout, MAX_READY_RETRIES, 1);
857
858 if (!SRpnt) {
859 retval = (STp->buffer)->syscall_result;
860 break;
861 }
862
863 if (cmdstatp->have_sense) {
864
865 scode = cmdstatp->sense_hdr.sense_key;
866
867 if (scode == UNIT_ATTENTION) { /* New media? */
868 new_session = 1;
869 if (attentions < MAX_ATTENTIONS) {
870 attentions++;
871 continue;
872 }
873 else {
874 retval = (-EIO);
875 break;
876 }
877 }
878
879 if (scode == NOT_READY) {
880 if (waits < max_wait) {
881 if (msleep_interruptible(1000)) {
882 retval = (-EINTR);
883 break;
884 }
885 waits++;
886 continue;
887 }
888 else {
889 if ((STp->device)->scsi_level >= SCSI_2 &&
890 cmdstatp->sense_hdr.asc == 0x3a) /* Check ASC */
891 retval = CHKRES_NO_TAPE;
892 else
893 retval = CHKRES_NOT_READY;
894 break;
895 }
896 }
897 }
898
899 retval = (STp->buffer)->syscall_result;
900 if (!retval)
901 retval = new_session ? CHKRES_NEW_SESSION : CHKRES_READY;
902 break;
903 }
904
905 if (SRpnt != NULL)
Mike Christie8b05b772005-11-08 04:06:44 -0600906 st_release_request(SRpnt);
Linus Torvalds1da177e2005-04-16 15:20:36 -0700907 return retval;
908}
909
910
911/* See if the drive is ready and gather information about the tape. Return values:
912 < 0 negative error code from errno.h
913 0 drive ready
914 1 drive not ready (possibly no tape)
915*/
916static int check_tape(struct scsi_tape *STp, struct file *filp)
917{
918 int i, retval, new_session = 0, do_wait;
919 unsigned char cmd[MAX_COMMAND_SIZE], saved_cleaning;
920 unsigned short st_flags = filp->f_flags;
Mike Christie8b05b772005-11-08 04:06:44 -0600921 struct st_request *SRpnt = NULL;
Linus Torvalds1da177e2005-04-16 15:20:36 -0700922 struct st_modedef *STm;
923 struct st_partstat *STps;
924 char *name = tape_name(STp);
Josef Sipek7ac62072006-12-08 02:37:37 -0800925 struct inode *inode = filp->f_path.dentry->d_inode;
Linus Torvalds1da177e2005-04-16 15:20:36 -0700926 int mode = TAPE_MODE(inode);
927
928 STp->ready = ST_READY;
929
930 if (mode != STp->current_mode) {
931 DEBC(printk(ST_DEB_MSG "%s: Mode change from %d to %d.\n",
932 name, STp->current_mode, mode));
933 new_session = 1;
934 STp->current_mode = mode;
935 }
936 STm = &(STp->modes[STp->current_mode]);
937
938 saved_cleaning = STp->cleaning_req;
939 STp->cleaning_req = 0;
940
941 do_wait = ((filp->f_flags & O_NONBLOCK) == 0);
942 retval = test_ready(STp, do_wait);
943
944 if (retval < 0)
945 goto err_out;
946
947 if (retval == CHKRES_NEW_SESSION) {
948 STp->pos_unknown = 0;
949 STp->partition = STp->new_partition = 0;
950 if (STp->can_partitions)
951 STp->nbr_partitions = 1; /* This guess will be updated later
952 if necessary */
953 for (i = 0; i < ST_NBR_PARTITIONS; i++) {
954 STps = &(STp->ps[i]);
955 STps->rw = ST_IDLE;
956 STps->eof = ST_NOEOF;
957 STps->at_sm = 0;
958 STps->last_block_valid = 0;
959 STps->drv_block = 0;
960 STps->drv_file = 0;
961 }
962 new_session = 1;
963 }
964 else {
965 STp->cleaning_req |= saved_cleaning;
966
967 if (retval == CHKRES_NOT_READY || retval == CHKRES_NO_TAPE) {
968 if (retval == CHKRES_NO_TAPE)
969 STp->ready = ST_NO_TAPE;
970 else
971 STp->ready = ST_NOT_READY;
972
973 STp->density = 0; /* Clear the erroneous "residue" */
974 STp->write_prot = 0;
975 STp->block_size = 0;
976 STp->ps[0].drv_file = STp->ps[0].drv_block = (-1);
977 STp->partition = STp->new_partition = 0;
978 STp->door_locked = ST_UNLOCKED;
979 return CHKRES_NOT_READY;
980 }
981 }
982
983 if (STp->omit_blklims)
984 STp->min_block = STp->max_block = (-1);
985 else {
986 memset((void *) &cmd[0], 0, MAX_COMMAND_SIZE);
987 cmd[0] = READ_BLOCK_LIMITS;
988
989 SRpnt = st_do_scsi(SRpnt, STp, cmd, 6, DMA_FROM_DEVICE,
990 STp->device->timeout, MAX_READY_RETRIES, 1);
991 if (!SRpnt) {
992 retval = (STp->buffer)->syscall_result;
993 goto err_out;
994 }
995
Mike Christie8b05b772005-11-08 04:06:44 -0600996 if (!SRpnt->result && !STp->buffer->cmdstat.have_sense) {
Linus Torvalds1da177e2005-04-16 15:20:36 -0700997 STp->max_block = ((STp->buffer)->b_data[1] << 16) |
998 ((STp->buffer)->b_data[2] << 8) | (STp->buffer)->b_data[3];
999 STp->min_block = ((STp->buffer)->b_data[4] << 8) |
1000 (STp->buffer)->b_data[5];
1001 if ( DEB( debugging || ) !STp->inited)
Kai Makisara42252852006-11-07 21:56:38 +02001002 printk(KERN_INFO
Linus Torvalds1da177e2005-04-16 15:20:36 -07001003 "%s: Block limits %d - %d bytes.\n", name,
1004 STp->min_block, STp->max_block);
1005 } else {
1006 STp->min_block = STp->max_block = (-1);
1007 DEBC(printk(ST_DEB_MSG "%s: Can't read block limits.\n",
1008 name));
1009 }
1010 }
1011
1012 memset((void *) &cmd[0], 0, MAX_COMMAND_SIZE);
1013 cmd[0] = MODE_SENSE;
1014 cmd[4] = 12;
1015
1016 SRpnt = st_do_scsi(SRpnt, STp, cmd, 12, DMA_FROM_DEVICE,
1017 STp->device->timeout, MAX_READY_RETRIES, 1);
1018 if (!SRpnt) {
1019 retval = (STp->buffer)->syscall_result;
1020 goto err_out;
1021 }
1022
1023 if ((STp->buffer)->syscall_result != 0) {
1024 DEBC(printk(ST_DEB_MSG "%s: No Mode Sense.\n", name));
1025 STp->block_size = ST_DEFAULT_BLOCK; /* Educated guess (?) */
1026 (STp->buffer)->syscall_result = 0; /* Prevent error propagation */
1027 STp->drv_write_prot = 0;
1028 } else {
1029 DEBC(printk(ST_DEB_MSG
1030 "%s: Mode sense. Length %d, medium %x, WBS %x, BLL %d\n",
1031 name,
1032 (STp->buffer)->b_data[0], (STp->buffer)->b_data[1],
1033 (STp->buffer)->b_data[2], (STp->buffer)->b_data[3]));
1034
1035 if ((STp->buffer)->b_data[3] >= 8) {
1036 STp->drv_buffer = ((STp->buffer)->b_data[2] >> 4) & 7;
1037 STp->density = (STp->buffer)->b_data[4];
1038 STp->block_size = (STp->buffer)->b_data[9] * 65536 +
1039 (STp->buffer)->b_data[10] * 256 + (STp->buffer)->b_data[11];
1040 DEBC(printk(ST_DEB_MSG
1041 "%s: Density %x, tape length: %x, drv buffer: %d\n",
1042 name, STp->density, (STp->buffer)->b_data[5] * 65536 +
1043 (STp->buffer)->b_data[6] * 256 + (STp->buffer)->b_data[7],
1044 STp->drv_buffer));
1045 }
1046 STp->drv_write_prot = ((STp->buffer)->b_data[2] & 0x80) != 0;
1047 }
Mike Christie8b05b772005-11-08 04:06:44 -06001048 st_release_request(SRpnt);
Linus Torvalds1da177e2005-04-16 15:20:36 -07001049 SRpnt = NULL;
1050 STp->inited = 1;
1051
1052 if (STp->block_size > 0)
1053 (STp->buffer)->buffer_blocks =
1054 (STp->buffer)->buffer_size / STp->block_size;
1055 else
1056 (STp->buffer)->buffer_blocks = 1;
1057 (STp->buffer)->buffer_bytes = (STp->buffer)->read_pointer = 0;
1058
1059 DEBC(printk(ST_DEB_MSG
1060 "%s: Block size: %d, buffer size: %d (%d blocks).\n", name,
1061 STp->block_size, (STp->buffer)->buffer_size,
1062 (STp->buffer)->buffer_blocks));
1063
1064 if (STp->drv_write_prot) {
1065 STp->write_prot = 1;
1066
1067 DEBC(printk(ST_DEB_MSG "%s: Write protected\n", name));
1068
1069 if (do_wait &&
1070 ((st_flags & O_ACCMODE) == O_WRONLY ||
1071 (st_flags & O_ACCMODE) == O_RDWR)) {
1072 retval = (-EROFS);
1073 goto err_out;
1074 }
1075 }
1076
1077 if (STp->can_partitions && STp->nbr_partitions < 1) {
1078 /* This code is reached when the device is opened for the first time
1079 after the driver has been initialized with tape in the drive and the
1080 partition support has been enabled. */
1081 DEBC(printk(ST_DEB_MSG
1082 "%s: Updating partition number in status.\n", name));
1083 if ((STp->partition = find_partition(STp)) < 0) {
1084 retval = STp->partition;
1085 goto err_out;
1086 }
1087 STp->new_partition = STp->partition;
1088 STp->nbr_partitions = 1; /* This guess will be updated when necessary */
1089 }
1090
1091 if (new_session) { /* Change the drive parameters for the new mode */
1092 STp->density_changed = STp->blksize_changed = 0;
1093 STp->compression_changed = 0;
1094 if (!(STm->defaults_for_writes) &&
1095 (retval = set_mode_densblk(STp, STm)) < 0)
1096 goto err_out;
1097
1098 if (STp->default_drvbuffer != 0xff) {
1099 if (st_int_ioctl(STp, MTSETDRVBUFFER, STp->default_drvbuffer))
1100 printk(KERN_WARNING
1101 "%s: Can't set default drive buffering to %d.\n",
1102 name, STp->default_drvbuffer);
1103 }
1104 }
1105
1106 return CHKRES_READY;
1107
1108 err_out:
1109 return retval;
1110}
1111
1112
Jonathan Corbetb3369c62008-05-15 16:08:15 -06001113 /* Open the device. Needs to take the BKL only because of incrementing the SCSI host
Linus Torvalds1da177e2005-04-16 15:20:36 -07001114 module count. */
1115static int st_open(struct inode *inode, struct file *filp)
1116{
1117 int i, retval = (-EIO);
1118 struct scsi_tape *STp;
1119 struct st_partstat *STps;
1120 int dev = TAPE_NR(inode);
1121 char *name;
1122
Jonathan Corbetb3369c62008-05-15 16:08:15 -06001123 lock_kernel();
Linus Torvalds1da177e2005-04-16 15:20:36 -07001124 /*
1125 * We really want to do nonseekable_open(inode, filp); here, but some
1126 * versions of tar incorrectly call lseek on tapes and bail out if that
1127 * fails. So we disallow pread() and pwrite(), but permit lseeks.
1128 */
1129 filp->f_mode &= ~(FMODE_PREAD | FMODE_PWRITE);
1130
Jonathan Corbetb3369c62008-05-15 16:08:15 -06001131 if (!(STp = scsi_tape_get(dev))) {
1132 unlock_kernel();
Kai Makisaraf03a5672005-08-02 13:40:47 +03001133 return -ENXIO;
Jonathan Corbetb3369c62008-05-15 16:08:15 -06001134 }
Kai Makisaraf03a5672005-08-02 13:40:47 +03001135
Linus Torvalds1da177e2005-04-16 15:20:36 -07001136 write_lock(&st_dev_arr_lock);
Linus Torvalds1da177e2005-04-16 15:20:36 -07001137 filp->private_data = STp;
1138 name = tape_name(STp);
1139
1140 if (STp->in_use) {
1141 write_unlock(&st_dev_arr_lock);
Kai Makisaraf03a5672005-08-02 13:40:47 +03001142 scsi_tape_put(STp);
Jonathan Corbetb3369c62008-05-15 16:08:15 -06001143 unlock_kernel();
Linus Torvalds1da177e2005-04-16 15:20:36 -07001144 DEB( printk(ST_DEB_MSG "%s: Device already in use.\n", name); )
1145 return (-EBUSY);
1146 }
1147
Linus Torvalds1da177e2005-04-16 15:20:36 -07001148 STp->in_use = 1;
1149 write_unlock(&st_dev_arr_lock);
1150 STp->rew_at_close = STp->autorew_dev = (iminor(inode) & 0x80) == 0;
1151
1152 if (!scsi_block_when_processing_errors(STp->device)) {
1153 retval = (-ENXIO);
1154 goto err_out;
1155 }
1156
1157 /* See that we have at least a one page buffer available */
1158 if (!enlarge_buffer(STp->buffer, PAGE_SIZE, STp->restr_dma)) {
1159 printk(KERN_WARNING "%s: Can't allocate one page tape buffer.\n",
1160 name);
1161 retval = (-EOVERFLOW);
1162 goto err_out;
1163 }
1164
Kai Makisara40f6b362008-02-24 22:23:24 +02001165 (STp->buffer)->cleared = 0;
Linus Torvalds1da177e2005-04-16 15:20:36 -07001166 (STp->buffer)->writing = 0;
1167 (STp->buffer)->syscall_result = 0;
1168
1169 STp->write_prot = ((filp->f_flags & O_ACCMODE) == O_RDONLY);
1170
1171 STp->dirty = 0;
1172 for (i = 0; i < ST_NBR_PARTITIONS; i++) {
1173 STps = &(STp->ps[i]);
1174 STps->rw = ST_IDLE;
1175 }
Kai Makisara9abe16c2007-02-03 13:21:29 +02001176 STp->try_dio_now = STp->try_dio;
Linus Torvalds1da177e2005-04-16 15:20:36 -07001177 STp->recover_count = 0;
1178 DEB( STp->nbr_waits = STp->nbr_finished = 0;
Kai Makisaradeee13d2008-02-22 20:11:21 +02001179 STp->nbr_requests = STp->nbr_dio = STp->nbr_pages = 0; )
Linus Torvalds1da177e2005-04-16 15:20:36 -07001180
1181 retval = check_tape(STp, filp);
1182 if (retval < 0)
1183 goto err_out;
1184 if ((filp->f_flags & O_NONBLOCK) == 0 &&
1185 retval != CHKRES_READY) {
Kai Makisara413f7322006-10-05 22:59:46 +03001186 if (STp->ready == NO_TAPE)
1187 retval = (-ENOMEDIUM);
1188 else
1189 retval = (-EIO);
Linus Torvalds1da177e2005-04-16 15:20:36 -07001190 goto err_out;
1191 }
Jonathan Corbetb3369c62008-05-15 16:08:15 -06001192 unlock_kernel();
Linus Torvalds1da177e2005-04-16 15:20:36 -07001193 return 0;
1194
1195 err_out:
1196 normalize_buffer(STp->buffer);
1197 STp->in_use = 0;
Kai Makisaraf03a5672005-08-02 13:40:47 +03001198 scsi_tape_put(STp);
Jonathan Corbetb3369c62008-05-15 16:08:15 -06001199 unlock_kernel();
Linus Torvalds1da177e2005-04-16 15:20:36 -07001200 return retval;
1201
1202}
1203
1204
1205/* Flush the tape buffer before close */
Miklos Szeredi75e1fcc2006-06-23 02:05:12 -07001206static int st_flush(struct file *filp, fl_owner_t id)
Linus Torvalds1da177e2005-04-16 15:20:36 -07001207{
1208 int result = 0, result2;
1209 unsigned char cmd[MAX_COMMAND_SIZE];
Mike Christie8b05b772005-11-08 04:06:44 -06001210 struct st_request *SRpnt;
Linus Torvalds1da177e2005-04-16 15:20:36 -07001211 struct scsi_tape *STp = filp->private_data;
1212 struct st_modedef *STm = &(STp->modes[STp->current_mode]);
1213 struct st_partstat *STps = &(STp->ps[STp->partition]);
1214 char *name = tape_name(STp);
1215
1216 if (file_count(filp) > 1)
1217 return 0;
1218
1219 if (STps->rw == ST_WRITING && !STp->pos_unknown) {
Adrian Bunk8ef8d592008-04-14 17:17:16 +03001220 result = st_flush_write_buffer(STp);
Linus Torvalds1da177e2005-04-16 15:20:36 -07001221 if (result != 0 && result != (-ENOSPC))
1222 goto out;
1223 }
1224
1225 if (STp->can_partitions &&
1226 (result2 = switch_partition(STp)) < 0) {
1227 DEBC(printk(ST_DEB_MSG
1228 "%s: switch_partition at close failed.\n", name));
1229 if (result == 0)
1230 result = result2;
1231 goto out;
1232 }
1233
1234 DEBC( if (STp->nbr_requests)
Kai Makisaradeee13d2008-02-22 20:11:21 +02001235 printk(KERN_DEBUG "%s: Number of r/w requests %d, dio used in %d, pages %d.\n",
1236 name, STp->nbr_requests, STp->nbr_dio, STp->nbr_pages));
Linus Torvalds1da177e2005-04-16 15:20:36 -07001237
1238 if (STps->rw == ST_WRITING && !STp->pos_unknown) {
1239 struct st_cmdstatus *cmdstatp = &STp->buffer->cmdstat;
1240
1241 DEBC(printk(ST_DEB_MSG "%s: Async write waits %d, finished %d.\n",
1242 name, STp->nbr_waits, STp->nbr_finished);
1243 )
1244
1245 memset(cmd, 0, MAX_COMMAND_SIZE);
1246 cmd[0] = WRITE_FILEMARKS;
1247 cmd[4] = 1 + STp->two_fm;
1248
1249 SRpnt = st_do_scsi(NULL, STp, cmd, 0, DMA_NONE,
1250 STp->device->timeout, MAX_WRITE_RETRIES, 1);
1251 if (!SRpnt) {
1252 result = (STp->buffer)->syscall_result;
1253 goto out;
1254 }
1255
1256 if (STp->buffer->syscall_result == 0 ||
1257 (cmdstatp->have_sense && !cmdstatp->deferred &&
1258 (cmdstatp->flags & SENSE_EOM) &&
1259 (cmdstatp->sense_hdr.sense_key == NO_SENSE ||
1260 cmdstatp->sense_hdr.sense_key == RECOVERED_ERROR) &&
1261 (!cmdstatp->remainder_valid || cmdstatp->uremainder64 == 0))) {
1262 /* Write successful at EOM */
Mike Christie8b05b772005-11-08 04:06:44 -06001263 st_release_request(SRpnt);
Linus Torvalds1da177e2005-04-16 15:20:36 -07001264 SRpnt = NULL;
1265 if (STps->drv_file >= 0)
1266 STps->drv_file++;
1267 STps->drv_block = 0;
1268 if (STp->two_fm)
1269 cross_eof(STp, 0);
1270 STps->eof = ST_FM;
1271 }
1272 else { /* Write error */
Mike Christie8b05b772005-11-08 04:06:44 -06001273 st_release_request(SRpnt);
Linus Torvalds1da177e2005-04-16 15:20:36 -07001274 SRpnt = NULL;
1275 printk(KERN_ERR "%s: Error on write filemark.\n", name);
1276 if (result == 0)
1277 result = (-EIO);
1278 }
1279
1280 DEBC(printk(ST_DEB_MSG "%s: Buffer flushed, %d EOF(s) written\n",
1281 name, cmd[4]));
1282 } else if (!STp->rew_at_close) {
1283 STps = &(STp->ps[STp->partition]);
1284 if (!STm->sysv || STps->rw != ST_READING) {
1285 if (STp->can_bsr)
1286 result = flush_buffer(STp, 0);
1287 else if (STps->eof == ST_FM_HIT) {
1288 result = cross_eof(STp, 0);
1289 if (result) {
1290 if (STps->drv_file >= 0)
1291 STps->drv_file++;
1292 STps->drv_block = 0;
1293 STps->eof = ST_FM;
1294 } else
1295 STps->eof = ST_NOEOF;
1296 }
1297 } else if ((STps->eof == ST_NOEOF &&
1298 !(result = cross_eof(STp, 1))) ||
1299 STps->eof == ST_FM_HIT) {
1300 if (STps->drv_file >= 0)
1301 STps->drv_file++;
1302 STps->drv_block = 0;
1303 STps->eof = ST_FM;
1304 }
1305 }
1306
1307 out:
1308 if (STp->rew_at_close) {
1309 result2 = st_int_ioctl(STp, MTREW, 1);
1310 if (result == 0)
1311 result = result2;
1312 }
1313 return result;
1314}
1315
1316
1317/* Close the device and release it. BKL is not needed: this is the only thread
1318 accessing this tape. */
1319static int st_release(struct inode *inode, struct file *filp)
1320{
1321 int result = 0;
1322 struct scsi_tape *STp = filp->private_data;
1323
1324 if (STp->door_locked == ST_LOCKED_AUTO)
1325 do_door_lock(STp, 0);
1326
1327 normalize_buffer(STp->buffer);
1328 write_lock(&st_dev_arr_lock);
1329 STp->in_use = 0;
1330 write_unlock(&st_dev_arr_lock);
Kai Makisaraf03a5672005-08-02 13:40:47 +03001331 scsi_tape_put(STp);
Linus Torvalds1da177e2005-04-16 15:20:36 -07001332
1333 return result;
1334}
1335
1336/* The checks common to both reading and writing */
1337static ssize_t rw_checks(struct scsi_tape *STp, struct file *filp, size_t count)
1338{
1339 ssize_t retval = 0;
1340
1341 /*
1342 * If we are in the middle of error recovery, don't let anyone
1343 * else try and use this device. Also, if error recovery fails, it
1344 * may try and take the device offline, in which case all further
1345 * access to the device is prohibited.
1346 */
1347 if (!scsi_block_when_processing_errors(STp->device)) {
1348 retval = (-ENXIO);
1349 goto out;
1350 }
1351
1352 if (STp->ready != ST_READY) {
1353 if (STp->ready == ST_NO_TAPE)
1354 retval = (-ENOMEDIUM);
1355 else
1356 retval = (-EIO);
1357 goto out;
1358 }
1359
1360 if (! STp->modes[STp->current_mode].defined) {
1361 retval = (-ENXIO);
1362 goto out;
1363 }
1364
1365
1366 /*
1367 * If there was a bus reset, block further access
1368 * to this device.
1369 */
1370 if (STp->pos_unknown) {
1371 retval = (-EIO);
1372 goto out;
1373 }
1374
1375 if (count == 0)
1376 goto out;
1377
1378 DEB(
1379 if (!STp->in_use) {
1380 printk(ST_DEB_MSG "%s: Incorrect device.\n", tape_name(STp));
1381 retval = (-EIO);
1382 goto out;
1383 } ) /* end DEB */
1384
1385 if (STp->can_partitions &&
1386 (retval = switch_partition(STp)) < 0)
1387 goto out;
1388
1389 if (STp->block_size == 0 && STp->max_block > 0 &&
1390 (count < STp->min_block || count > STp->max_block)) {
1391 retval = (-EINVAL);
1392 goto out;
1393 }
1394
1395 if (STp->do_auto_lock && STp->door_locked == ST_UNLOCKED &&
1396 !do_door_lock(STp, 1))
1397 STp->door_locked = ST_LOCKED_AUTO;
1398
1399 out:
1400 return retval;
1401}
1402
1403
1404static int setup_buffering(struct scsi_tape *STp, const char __user *buf,
1405 size_t count, int is_read)
1406{
1407 int i, bufsize, retval = 0;
1408 struct st_buffer *STbp = STp->buffer;
1409
1410 if (is_read)
Kai Makisara9abe16c2007-02-03 13:21:29 +02001411 i = STp->try_dio_now && try_rdio;
Linus Torvalds1da177e2005-04-16 15:20:36 -07001412 else
Kai Makisara9abe16c2007-02-03 13:21:29 +02001413 i = STp->try_dio_now && try_wdio;
Mike Christie8b05b772005-11-08 04:06:44 -06001414
Linus Torvalds1da177e2005-04-16 15:20:36 -07001415 if (i && ((unsigned long)buf & queue_dma_alignment(
1416 STp->device->request_queue)) == 0) {
Mike Christie8b05b772005-11-08 04:06:44 -06001417 i = sgl_map_user_pages(&(STbp->sg[0]), STbp->use_sg,
1418 (unsigned long)buf, count, (is_read ? READ : WRITE));
Linus Torvalds1da177e2005-04-16 15:20:36 -07001419 if (i > 0) {
1420 STbp->do_dio = i;
1421 STbp->buffer_bytes = 0; /* can be used as transfer counter */
1422 }
1423 else
1424 STbp->do_dio = 0; /* fall back to buffering with any error */
1425 STbp->sg_segs = STbp->do_dio;
1426 STbp->frp_sg_current = 0;
1427 DEB(
1428 if (STbp->do_dio) {
1429 STp->nbr_dio++;
1430 STp->nbr_pages += STbp->do_dio;
Linus Torvalds1da177e2005-04-16 15:20:36 -07001431 }
1432 )
1433 } else
1434 STbp->do_dio = 0;
1435 DEB( STp->nbr_requests++; )
1436
1437 if (!STbp->do_dio) {
1438 if (STp->block_size)
1439 bufsize = STp->block_size > st_fixed_buffer_size ?
1440 STp->block_size : st_fixed_buffer_size;
Kai Makisara40f6b362008-02-24 22:23:24 +02001441 else {
Linus Torvalds1da177e2005-04-16 15:20:36 -07001442 bufsize = count;
Kai Makisara40f6b362008-02-24 22:23:24 +02001443 /* Make sure that data from previous user is not leaked even if
1444 HBA does not return correct residual */
1445 if (is_read && STp->sili && !STbp->cleared)
1446 clear_buffer(STbp);
1447 }
1448
Linus Torvalds1da177e2005-04-16 15:20:36 -07001449 if (bufsize > STbp->buffer_size &&
1450 !enlarge_buffer(STbp, bufsize, STp->restr_dma)) {
1451 printk(KERN_WARNING "%s: Can't allocate %d byte tape buffer.\n",
1452 tape_name(STp), bufsize);
1453 retval = (-EOVERFLOW);
1454 goto out;
1455 }
1456 if (STp->block_size)
1457 STbp->buffer_blocks = bufsize / STp->block_size;
1458 }
1459
1460 out:
1461 return retval;
1462}
1463
1464
1465/* Can be called more than once after each setup_buffer() */
Kai Makisara787926b2005-11-13 10:04:44 +02001466static void release_buffering(struct scsi_tape *STp, int is_read)
Linus Torvalds1da177e2005-04-16 15:20:36 -07001467{
1468 struct st_buffer *STbp;
1469
1470 STbp = STp->buffer;
1471 if (STbp->do_dio) {
Kai Makisara787926b2005-11-13 10:04:44 +02001472 sgl_unmap_user_pages(&(STbp->sg[0]), STbp->do_dio, is_read);
Linus Torvalds1da177e2005-04-16 15:20:36 -07001473 STbp->do_dio = 0;
Kai Makisara787926b2005-11-13 10:04:44 +02001474 STbp->sg_segs = 0;
Linus Torvalds1da177e2005-04-16 15:20:36 -07001475 }
1476}
1477
1478
1479/* Write command */
1480static ssize_t
1481st_write(struct file *filp, const char __user *buf, size_t count, loff_t * ppos)
1482{
1483 ssize_t total;
1484 ssize_t i, do_count, blks, transfer;
1485 ssize_t retval;
1486 int undone, retry_eot = 0, scode;
1487 int async_write;
1488 unsigned char cmd[MAX_COMMAND_SIZE];
1489 const char __user *b_point;
Mike Christie8b05b772005-11-08 04:06:44 -06001490 struct st_request *SRpnt = NULL;
Linus Torvalds1da177e2005-04-16 15:20:36 -07001491 struct scsi_tape *STp = filp->private_data;
1492 struct st_modedef *STm;
1493 struct st_partstat *STps;
1494 struct st_buffer *STbp;
1495 char *name = tape_name(STp);
1496
Matthias Kaehlcke28f85002007-07-29 23:38:15 +02001497 if (mutex_lock_interruptible(&STp->lock))
Linus Torvalds1da177e2005-04-16 15:20:36 -07001498 return -ERESTARTSYS;
1499
1500 retval = rw_checks(STp, filp, count);
1501 if (retval || count == 0)
1502 goto out;
1503
1504 /* Write must be integral number of blocks */
1505 if (STp->block_size != 0 && (count % STp->block_size) != 0) {
1506 printk(KERN_WARNING "%s: Write not multiple of tape block size.\n",
1507 name);
1508 retval = (-EINVAL);
1509 goto out;
1510 }
1511
1512 STm = &(STp->modes[STp->current_mode]);
1513 STps = &(STp->ps[STp->partition]);
1514
1515 if (STp->write_prot) {
1516 retval = (-EACCES);
1517 goto out;
1518 }
1519
1520
1521 if (STps->rw == ST_READING) {
1522 retval = flush_buffer(STp, 0);
1523 if (retval)
1524 goto out;
1525 STps->rw = ST_WRITING;
1526 } else if (STps->rw != ST_WRITING &&
1527 STps->drv_file == 0 && STps->drv_block == 0) {
1528 if ((retval = set_mode_densblk(STp, STm)) < 0)
1529 goto out;
1530 if (STm->default_compression != ST_DONT_TOUCH &&
1531 !(STp->compression_changed)) {
1532 if (st_compression(STp, (STm->default_compression == ST_YES))) {
1533 printk(KERN_WARNING "%s: Can't set default compression.\n",
1534 name);
1535 if (modes_defined) {
1536 retval = (-EINVAL);
1537 goto out;
1538 }
1539 }
1540 }
1541 }
1542
1543 STbp = STp->buffer;
1544 i = write_behind_check(STp);
1545 if (i) {
1546 if (i == -ENOSPC)
1547 STps->eof = ST_EOM_OK;
1548 else
1549 STps->eof = ST_EOM_ERROR;
1550 }
1551
1552 if (STps->eof == ST_EOM_OK) {
1553 STps->eof = ST_EOD_1; /* allow next write */
1554 retval = (-ENOSPC);
1555 goto out;
1556 }
1557 else if (STps->eof == ST_EOM_ERROR) {
1558 retval = (-EIO);
1559 goto out;
1560 }
1561
1562 /* Check the buffer readability in cases where copy_user might catch
1563 the problems after some tape movement. */
1564 if (STp->block_size != 0 &&
1565 !STbp->do_dio &&
1566 (copy_from_user(&i, buf, 1) != 0 ||
1567 copy_from_user(&i, buf + count - 1, 1) != 0)) {
1568 retval = (-EFAULT);
1569 goto out;
1570 }
1571
1572 retval = setup_buffering(STp, buf, count, 0);
1573 if (retval)
1574 goto out;
1575
1576 total = count;
1577
1578 memset(cmd, 0, MAX_COMMAND_SIZE);
1579 cmd[0] = WRITE_6;
1580 cmd[1] = (STp->block_size != 0);
1581
1582 STps->rw = ST_WRITING;
1583
1584 b_point = buf;
1585 while (count > 0 && !retry_eot) {
1586
1587 if (STbp->do_dio) {
1588 do_count = count;
1589 }
1590 else {
1591 if (STp->block_size == 0)
1592 do_count = count;
1593 else {
1594 do_count = STbp->buffer_blocks * STp->block_size -
1595 STbp->buffer_bytes;
1596 if (do_count > count)
1597 do_count = count;
1598 }
1599
1600 i = append_to_buffer(b_point, STbp, do_count);
1601 if (i) {
1602 retval = i;
1603 goto out;
1604 }
1605 }
1606 count -= do_count;
1607 b_point += do_count;
1608
1609 async_write = STp->block_size == 0 && !STbp->do_dio &&
1610 STm->do_async_writes && STps->eof < ST_EOM_OK;
1611
1612 if (STp->block_size != 0 && STm->do_buffer_writes &&
Kai Makisara9abe16c2007-02-03 13:21:29 +02001613 !(STp->try_dio_now && try_wdio) && STps->eof < ST_EOM_OK &&
Linus Torvalds1da177e2005-04-16 15:20:36 -07001614 STbp->buffer_bytes < STbp->buffer_size) {
1615 STp->dirty = 1;
1616 /* Don't write a buffer that is not full enough. */
1617 if (!async_write && count == 0)
1618 break;
1619 }
1620
1621 retry_write:
1622 if (STp->block_size == 0)
1623 blks = transfer = do_count;
1624 else {
1625 if (!STbp->do_dio)
1626 blks = STbp->buffer_bytes;
1627 else
1628 blks = do_count;
1629 blks /= STp->block_size;
1630 transfer = blks * STp->block_size;
1631 }
1632 cmd[2] = blks >> 16;
1633 cmd[3] = blks >> 8;
1634 cmd[4] = blks;
1635
1636 SRpnt = st_do_scsi(SRpnt, STp, cmd, transfer, DMA_TO_DEVICE,
1637 STp->device->timeout, MAX_WRITE_RETRIES, !async_write);
1638 if (!SRpnt) {
1639 retval = STbp->syscall_result;
1640 goto out;
1641 }
Mike Christie8b05b772005-11-08 04:06:44 -06001642 if (async_write && !STbp->syscall_result) {
Linus Torvalds1da177e2005-04-16 15:20:36 -07001643 STbp->writing = transfer;
1644 STp->dirty = !(STbp->writing ==
1645 STbp->buffer_bytes);
1646 SRpnt = NULL; /* Prevent releasing this request! */
1647 DEB( STp->write_pending = 1; )
1648 break;
1649 }
1650
1651 if (STbp->syscall_result != 0) {
1652 struct st_cmdstatus *cmdstatp = &STp->buffer->cmdstat;
1653
1654 DEBC(printk(ST_DEB_MSG "%s: Error on write:\n", name));
1655 if (cmdstatp->have_sense && (cmdstatp->flags & SENSE_EOM)) {
1656 scode = cmdstatp->sense_hdr.sense_key;
1657 if (cmdstatp->remainder_valid)
1658 undone = (int)cmdstatp->uremainder64;
1659 else if (STp->block_size == 0 &&
1660 scode == VOLUME_OVERFLOW)
1661 undone = transfer;
1662 else
1663 undone = 0;
1664 if (STp->block_size != 0)
1665 undone *= STp->block_size;
1666 if (undone <= do_count) {
1667 /* Only data from this write is not written */
1668 count += undone;
Kai Makisara626dcb12008-07-11 15:05:25 +03001669 b_point -= undone;
Linus Torvalds1da177e2005-04-16 15:20:36 -07001670 do_count -= undone;
1671 if (STp->block_size)
1672 blks = (transfer - undone) / STp->block_size;
1673 STps->eof = ST_EOM_OK;
1674 /* Continue in fixed block mode if all written
1675 in this request but still something left to write
1676 (retval left to zero)
1677 */
1678 if (STp->block_size == 0 ||
1679 undone > 0 || count == 0)
1680 retval = (-ENOSPC); /* EOM within current request */
1681 DEBC(printk(ST_DEB_MSG
1682 "%s: EOM with %d bytes unwritten.\n",
1683 name, (int)count));
1684 } else {
1685 /* EOT within data buffered earlier (possible only
1686 in fixed block mode without direct i/o) */
1687 if (!retry_eot && !cmdstatp->deferred &&
1688 (scode == NO_SENSE || scode == RECOVERED_ERROR)) {
1689 move_buffer_data(STp->buffer, transfer - undone);
1690 retry_eot = 1;
1691 if (STps->drv_block >= 0) {
1692 STps->drv_block += (transfer - undone) /
1693 STp->block_size;
1694 }
1695 STps->eof = ST_EOM_OK;
1696 DEBC(printk(ST_DEB_MSG
1697 "%s: Retry write of %d bytes at EOM.\n",
1698 name, STp->buffer->buffer_bytes));
1699 goto retry_write;
1700 }
1701 else {
1702 /* Either error within data buffered by driver or
1703 failed retry */
1704 count -= do_count;
1705 blks = do_count = 0;
1706 STps->eof = ST_EOM_ERROR;
1707 STps->drv_block = (-1); /* Too cautious? */
1708 retval = (-EIO); /* EOM for old data */
1709 DEBC(printk(ST_DEB_MSG
1710 "%s: EOM with lost data.\n",
1711 name));
1712 }
1713 }
1714 } else {
1715 count += do_count;
1716 STps->drv_block = (-1); /* Too cautious? */
Mike Christie8b05b772005-11-08 04:06:44 -06001717 retval = STbp->syscall_result;
Linus Torvalds1da177e2005-04-16 15:20:36 -07001718 }
1719
1720 }
1721
1722 if (STps->drv_block >= 0) {
1723 if (STp->block_size == 0)
1724 STps->drv_block += (do_count > 0);
1725 else
1726 STps->drv_block += blks;
1727 }
1728
1729 STbp->buffer_bytes = 0;
1730 STp->dirty = 0;
1731
1732 if (retval || retry_eot) {
1733 if (count < total)
1734 retval = total - count;
1735 goto out;
1736 }
1737 }
1738
1739 if (STps->eof == ST_EOD_1)
1740 STps->eof = ST_EOM_OK;
1741 else if (STps->eof != ST_EOM_OK)
1742 STps->eof = ST_NOEOF;
1743 retval = total - count;
1744
1745 out:
1746 if (SRpnt != NULL)
Mike Christie8b05b772005-11-08 04:06:44 -06001747 st_release_request(SRpnt);
Kai Makisara787926b2005-11-13 10:04:44 +02001748 release_buffering(STp, 0);
Matthias Kaehlcke28f85002007-07-29 23:38:15 +02001749 mutex_unlock(&STp->lock);
Linus Torvalds1da177e2005-04-16 15:20:36 -07001750
1751 return retval;
1752}
1753
1754/* Read data from the tape. Returns zero in the normal case, one if the
1755 eof status has changed, and the negative error code in case of a
1756 fatal error. Otherwise updates the buffer and the eof state.
1757
1758 Does release user buffer mapping if it is set.
1759*/
1760static long read_tape(struct scsi_tape *STp, long count,
Mike Christie8b05b772005-11-08 04:06:44 -06001761 struct st_request ** aSRpnt)
Linus Torvalds1da177e2005-04-16 15:20:36 -07001762{
1763 int transfer, blks, bytes;
1764 unsigned char cmd[MAX_COMMAND_SIZE];
Mike Christie8b05b772005-11-08 04:06:44 -06001765 struct st_request *SRpnt;
Linus Torvalds1da177e2005-04-16 15:20:36 -07001766 struct st_modedef *STm;
1767 struct st_partstat *STps;
1768 struct st_buffer *STbp;
1769 int retval = 0;
1770 char *name = tape_name(STp);
1771
1772 if (count == 0)
1773 return 0;
1774
1775 STm = &(STp->modes[STp->current_mode]);
1776 STps = &(STp->ps[STp->partition]);
1777 if (STps->eof == ST_FM_HIT)
1778 return 1;
1779 STbp = STp->buffer;
1780
1781 if (STp->block_size == 0)
1782 blks = bytes = count;
1783 else {
Kai Makisara9abe16c2007-02-03 13:21:29 +02001784 if (!(STp->try_dio_now && try_rdio) && STm->do_read_ahead) {
Linus Torvalds1da177e2005-04-16 15:20:36 -07001785 blks = (STp->buffer)->buffer_blocks;
1786 bytes = blks * STp->block_size;
1787 } else {
1788 bytes = count;
1789 if (!STbp->do_dio && bytes > (STp->buffer)->buffer_size)
1790 bytes = (STp->buffer)->buffer_size;
1791 blks = bytes / STp->block_size;
1792 bytes = blks * STp->block_size;
1793 }
1794 }
1795
1796 memset(cmd, 0, MAX_COMMAND_SIZE);
1797 cmd[0] = READ_6;
1798 cmd[1] = (STp->block_size != 0);
Kai Makisara40f6b362008-02-24 22:23:24 +02001799 if (!cmd[1] && STp->sili)
1800 cmd[1] |= 2;
Linus Torvalds1da177e2005-04-16 15:20:36 -07001801 cmd[2] = blks >> 16;
1802 cmd[3] = blks >> 8;
1803 cmd[4] = blks;
1804
1805 SRpnt = *aSRpnt;
1806 SRpnt = st_do_scsi(SRpnt, STp, cmd, bytes, DMA_FROM_DEVICE,
1807 STp->device->timeout, MAX_RETRIES, 1);
Kai Makisara787926b2005-11-13 10:04:44 +02001808 release_buffering(STp, 1);
Linus Torvalds1da177e2005-04-16 15:20:36 -07001809 *aSRpnt = SRpnt;
1810 if (!SRpnt)
1811 return STbp->syscall_result;
1812
1813 STbp->read_pointer = 0;
1814 STps->at_sm = 0;
1815
1816 /* Something to check */
1817 if (STbp->syscall_result) {
1818 struct st_cmdstatus *cmdstatp = &STp->buffer->cmdstat;
1819
1820 retval = 1;
1821 DEBC(printk(ST_DEB_MSG "%s: Sense: %2x %2x %2x %2x %2x %2x %2x %2x\n",
1822 name,
Mike Christie8b05b772005-11-08 04:06:44 -06001823 SRpnt->sense[0], SRpnt->sense[1],
1824 SRpnt->sense[2], SRpnt->sense[3],
1825 SRpnt->sense[4], SRpnt->sense[5],
1826 SRpnt->sense[6], SRpnt->sense[7]));
Linus Torvalds1da177e2005-04-16 15:20:36 -07001827 if (cmdstatp->have_sense) {
1828
1829 if (cmdstatp->sense_hdr.sense_key == BLANK_CHECK)
1830 cmdstatp->flags &= 0xcf; /* No need for EOM in this case */
1831
1832 if (cmdstatp->flags != 0) { /* EOF, EOM, or ILI */
1833 /* Compute the residual count */
1834 if (cmdstatp->remainder_valid)
1835 transfer = (int)cmdstatp->uremainder64;
1836 else
1837 transfer = 0;
1838 if (STp->block_size == 0 &&
1839 cmdstatp->sense_hdr.sense_key == MEDIUM_ERROR)
1840 transfer = bytes;
1841
1842 if (cmdstatp->flags & SENSE_ILI) { /* ILI */
1843 if (STp->block_size == 0) {
1844 if (transfer <= 0) {
1845 if (transfer < 0)
1846 printk(KERN_NOTICE
1847 "%s: Failed to read %d byte block with %d byte transfer.\n",
1848 name, bytes - transfer, bytes);
1849 if (STps->drv_block >= 0)
1850 STps->drv_block += 1;
1851 STbp->buffer_bytes = 0;
1852 return (-ENOMEM);
1853 }
1854 STbp->buffer_bytes = bytes - transfer;
1855 } else {
Mike Christie8b05b772005-11-08 04:06:44 -06001856 st_release_request(SRpnt);
Linus Torvalds1da177e2005-04-16 15:20:36 -07001857 SRpnt = *aSRpnt = NULL;
1858 if (transfer == blks) { /* We did not get anything, error */
1859 printk(KERN_NOTICE "%s: Incorrect block size.\n", name);
1860 if (STps->drv_block >= 0)
1861 STps->drv_block += blks - transfer + 1;
1862 st_int_ioctl(STp, MTBSR, 1);
1863 return (-EIO);
1864 }
1865 /* We have some data, deliver it */
1866 STbp->buffer_bytes = (blks - transfer) *
1867 STp->block_size;
1868 DEBC(printk(ST_DEB_MSG
1869 "%s: ILI but enough data received %ld %d.\n",
1870 name, count, STbp->buffer_bytes));
1871 if (STps->drv_block >= 0)
1872 STps->drv_block += 1;
1873 if (st_int_ioctl(STp, MTBSR, 1))
1874 return (-EIO);
1875 }
1876 } else if (cmdstatp->flags & SENSE_FMK) { /* FM overrides EOM */
1877 if (STps->eof != ST_FM_HIT)
1878 STps->eof = ST_FM_HIT;
1879 else
1880 STps->eof = ST_EOD_2;
1881 if (STp->block_size == 0)
1882 STbp->buffer_bytes = 0;
1883 else
1884 STbp->buffer_bytes =
1885 bytes - transfer * STp->block_size;
1886 DEBC(printk(ST_DEB_MSG
1887 "%s: EOF detected (%d bytes read).\n",
1888 name, STbp->buffer_bytes));
1889 } else if (cmdstatp->flags & SENSE_EOM) {
1890 if (STps->eof == ST_FM)
1891 STps->eof = ST_EOD_1;
1892 else
1893 STps->eof = ST_EOM_OK;
1894 if (STp->block_size == 0)
1895 STbp->buffer_bytes = bytes - transfer;
1896 else
1897 STbp->buffer_bytes =
1898 bytes - transfer * STp->block_size;
1899
1900 DEBC(printk(ST_DEB_MSG "%s: EOM detected (%d bytes read).\n",
1901 name, STbp->buffer_bytes));
1902 }
1903 }
1904 /* end of EOF, EOM, ILI test */
1905 else { /* nonzero sense key */
1906 DEBC(printk(ST_DEB_MSG
1907 "%s: Tape error while reading.\n", name));
1908 STps->drv_block = (-1);
1909 if (STps->eof == ST_FM &&
1910 cmdstatp->sense_hdr.sense_key == BLANK_CHECK) {
1911 DEBC(printk(ST_DEB_MSG
1912 "%s: Zero returned for first BLANK CHECK after EOF.\n",
1913 name));
1914 STps->eof = ST_EOD_2; /* First BLANK_CHECK after FM */
1915 } else /* Some other extended sense code */
1916 retval = (-EIO);
1917 }
1918
1919 if (STbp->buffer_bytes < 0) /* Caused by bogus sense data */
1920 STbp->buffer_bytes = 0;
1921 }
1922 /* End of extended sense test */
1923 else { /* Non-extended sense */
1924 retval = STbp->syscall_result;
1925 }
1926
1927 }
1928 /* End of error handling */
Kai Makisara40f6b362008-02-24 22:23:24 +02001929 else { /* Read successful */
Linus Torvalds1da177e2005-04-16 15:20:36 -07001930 STbp->buffer_bytes = bytes;
Kai Makisara40f6b362008-02-24 22:23:24 +02001931 if (STp->sili) /* In fixed block mode residual is always zero here */
1932 STbp->buffer_bytes -= STp->buffer->cmdstat.residual;
1933 }
Linus Torvalds1da177e2005-04-16 15:20:36 -07001934
1935 if (STps->drv_block >= 0) {
1936 if (STp->block_size == 0)
1937 STps->drv_block++;
1938 else
1939 STps->drv_block += STbp->buffer_bytes / STp->block_size;
1940 }
1941 return retval;
1942}
1943
1944
1945/* Read command */
1946static ssize_t
1947st_read(struct file *filp, char __user *buf, size_t count, loff_t * ppos)
1948{
1949 ssize_t total;
1950 ssize_t retval = 0;
1951 ssize_t i, transfer;
1952 int special, do_dio = 0;
Mike Christie8b05b772005-11-08 04:06:44 -06001953 struct st_request *SRpnt = NULL;
Linus Torvalds1da177e2005-04-16 15:20:36 -07001954 struct scsi_tape *STp = filp->private_data;
1955 struct st_modedef *STm;
1956 struct st_partstat *STps;
1957 struct st_buffer *STbp = STp->buffer;
1958 DEB( char *name = tape_name(STp); )
1959
Matthias Kaehlcke28f85002007-07-29 23:38:15 +02001960 if (mutex_lock_interruptible(&STp->lock))
Linus Torvalds1da177e2005-04-16 15:20:36 -07001961 return -ERESTARTSYS;
1962
1963 retval = rw_checks(STp, filp, count);
1964 if (retval || count == 0)
1965 goto out;
1966
1967 STm = &(STp->modes[STp->current_mode]);
Kai Makisara9abe16c2007-02-03 13:21:29 +02001968 if (STp->block_size != 0 && (count % STp->block_size) != 0) {
1969 if (!STm->do_read_ahead) {
1970 retval = (-EINVAL); /* Read must be integral number of blocks */
1971 goto out;
1972 }
1973 STp->try_dio_now = 0; /* Direct i/o can't handle split blocks */
Linus Torvalds1da177e2005-04-16 15:20:36 -07001974 }
1975
1976 STps = &(STp->ps[STp->partition]);
1977 if (STps->rw == ST_WRITING) {
1978 retval = flush_buffer(STp, 0);
1979 if (retval)
1980 goto out;
1981 STps->rw = ST_READING;
1982 }
1983 DEB(
1984 if (debugging && STps->eof != ST_NOEOF)
1985 printk(ST_DEB_MSG "%s: EOF/EOM flag up (%d). Bytes %d\n", name,
1986 STps->eof, STbp->buffer_bytes);
1987 ) /* end DEB */
1988
1989 retval = setup_buffering(STp, buf, count, 1);
1990 if (retval)
1991 goto out;
1992 do_dio = STbp->do_dio;
1993
1994 if (STbp->buffer_bytes == 0 &&
1995 STps->eof >= ST_EOD_1) {
1996 if (STps->eof < ST_EOD) {
1997 STps->eof += 1;
1998 retval = 0;
1999 goto out;
2000 }
2001 retval = (-EIO); /* EOM or Blank Check */
2002 goto out;
2003 }
2004
2005 if (do_dio) {
2006 /* Check the buffer writability before any tape movement. Don't alter
2007 buffer data. */
2008 if (copy_from_user(&i, buf, 1) != 0 ||
2009 copy_to_user(buf, &i, 1) != 0 ||
2010 copy_from_user(&i, buf + count - 1, 1) != 0 ||
2011 copy_to_user(buf + count - 1, &i, 1) != 0) {
2012 retval = (-EFAULT);
2013 goto out;
2014 }
2015 }
2016
2017 STps->rw = ST_READING;
2018
2019
2020 /* Loop until enough data in buffer or a special condition found */
2021 for (total = 0, special = 0; total < count && !special;) {
2022
2023 /* Get new data if the buffer is empty */
2024 if (STbp->buffer_bytes == 0) {
2025 special = read_tape(STp, count - total, &SRpnt);
2026 if (special < 0) { /* No need to continue read */
2027 retval = special;
2028 goto out;
2029 }
2030 }
2031
2032 /* Move the data from driver buffer to user buffer */
2033 if (STbp->buffer_bytes > 0) {
2034 DEB(
2035 if (debugging && STps->eof != ST_NOEOF)
2036 printk(ST_DEB_MSG
2037 "%s: EOF up (%d). Left %d, needed %d.\n", name,
2038 STps->eof, STbp->buffer_bytes,
2039 (int)(count - total));
2040 ) /* end DEB */
2041 transfer = STbp->buffer_bytes < count - total ?
2042 STbp->buffer_bytes : count - total;
2043 if (!do_dio) {
2044 i = from_buffer(STbp, buf, transfer);
2045 if (i) {
2046 retval = i;
2047 goto out;
2048 }
2049 }
2050 buf += transfer;
2051 total += transfer;
2052 }
2053
2054 if (STp->block_size == 0)
2055 break; /* Read only one variable length block */
2056
2057 } /* for (total = 0, special = 0;
2058 total < count && !special; ) */
2059
2060 /* Change the eof state if no data from tape or buffer */
2061 if (total == 0) {
2062 if (STps->eof == ST_FM_HIT) {
2063 STps->eof = ST_FM;
2064 STps->drv_block = 0;
2065 if (STps->drv_file >= 0)
2066 STps->drv_file++;
2067 } else if (STps->eof == ST_EOD_1) {
2068 STps->eof = ST_EOD_2;
2069 STps->drv_block = 0;
2070 if (STps->drv_file >= 0)
2071 STps->drv_file++;
2072 } else if (STps->eof == ST_EOD_2)
2073 STps->eof = ST_EOD;
2074 } else if (STps->eof == ST_FM)
2075 STps->eof = ST_NOEOF;
2076 retval = total;
2077
2078 out:
2079 if (SRpnt != NULL) {
Mike Christie8b05b772005-11-08 04:06:44 -06002080 st_release_request(SRpnt);
Linus Torvalds1da177e2005-04-16 15:20:36 -07002081 SRpnt = NULL;
2082 }
2083 if (do_dio) {
Kai Makisara787926b2005-11-13 10:04:44 +02002084 release_buffering(STp, 1);
Linus Torvalds1da177e2005-04-16 15:20:36 -07002085 STbp->buffer_bytes = 0;
2086 }
Matthias Kaehlcke28f85002007-07-29 23:38:15 +02002087 mutex_unlock(&STp->lock);
Linus Torvalds1da177e2005-04-16 15:20:36 -07002088
2089 return retval;
2090}
2091
2092
2093
2094DEB(
2095/* Set the driver options */
2096static void st_log_options(struct scsi_tape * STp, struct st_modedef * STm, char *name)
2097{
2098 if (debugging) {
2099 printk(KERN_INFO
2100 "%s: Mode %d options: buffer writes: %d, async writes: %d, read ahead: %d\n",
2101 name, STp->current_mode, STm->do_buffer_writes, STm->do_async_writes,
2102 STm->do_read_ahead);
2103 printk(KERN_INFO
2104 "%s: can bsr: %d, two FMs: %d, fast mteom: %d, auto lock: %d,\n",
2105 name, STp->can_bsr, STp->two_fm, STp->fast_mteom, STp->do_auto_lock);
2106 printk(KERN_INFO
2107 "%s: defs for wr: %d, no block limits: %d, partitions: %d, s2 log: %d\n",
2108 name, STm->defaults_for_writes, STp->omit_blklims, STp->can_partitions,
2109 STp->scsi2_logical);
2110 printk(KERN_INFO
Kai Makisara40f6b362008-02-24 22:23:24 +02002111 "%s: sysv: %d nowait: %d sili: %d\n", name, STm->sysv, STp->immediate,
2112 STp->sili);
Linus Torvalds1da177e2005-04-16 15:20:36 -07002113 printk(KERN_INFO "%s: debugging: %d\n",
2114 name, debugging);
2115 }
2116}
2117 )
2118
2119
2120static int st_set_options(struct scsi_tape *STp, long options)
2121{
2122 int value;
2123 long code;
2124 struct st_modedef *STm;
2125 char *name = tape_name(STp);
2126 struct cdev *cd0, *cd1;
2127
2128 STm = &(STp->modes[STp->current_mode]);
2129 if (!STm->defined) {
2130 cd0 = STm->cdevs[0]; cd1 = STm->cdevs[1];
2131 memcpy(STm, &(STp->modes[0]), sizeof(struct st_modedef));
2132 STm->cdevs[0] = cd0; STm->cdevs[1] = cd1;
2133 modes_defined = 1;
2134 DEBC(printk(ST_DEB_MSG
2135 "%s: Initialized mode %d definition from mode 0\n",
2136 name, STp->current_mode));
2137 }
2138
2139 code = options & MT_ST_OPTIONS;
2140 if (code == MT_ST_BOOLEANS) {
2141 STm->do_buffer_writes = (options & MT_ST_BUFFER_WRITES) != 0;
2142 STm->do_async_writes = (options & MT_ST_ASYNC_WRITES) != 0;
2143 STm->defaults_for_writes = (options & MT_ST_DEF_WRITES) != 0;
2144 STm->do_read_ahead = (options & MT_ST_READ_AHEAD) != 0;
2145 STp->two_fm = (options & MT_ST_TWO_FM) != 0;
2146 STp->fast_mteom = (options & MT_ST_FAST_MTEOM) != 0;
2147 STp->do_auto_lock = (options & MT_ST_AUTO_LOCK) != 0;
2148 STp->can_bsr = (options & MT_ST_CAN_BSR) != 0;
2149 STp->omit_blklims = (options & MT_ST_NO_BLKLIMS) != 0;
2150 if ((STp->device)->scsi_level >= SCSI_2)
2151 STp->can_partitions = (options & MT_ST_CAN_PARTITIONS) != 0;
2152 STp->scsi2_logical = (options & MT_ST_SCSI2LOGICAL) != 0;
2153 STp->immediate = (options & MT_ST_NOWAIT) != 0;
2154 STm->sysv = (options & MT_ST_SYSV) != 0;
Kai Makisara40f6b362008-02-24 22:23:24 +02002155 STp->sili = (options & MT_ST_SILI) != 0;
Linus Torvalds1da177e2005-04-16 15:20:36 -07002156 DEB( debugging = (options & MT_ST_DEBUGGING) != 0;
2157 st_log_options(STp, STm, name); )
2158 } else if (code == MT_ST_SETBOOLEANS || code == MT_ST_CLEARBOOLEANS) {
2159 value = (code == MT_ST_SETBOOLEANS);
2160 if ((options & MT_ST_BUFFER_WRITES) != 0)
2161 STm->do_buffer_writes = value;
2162 if ((options & MT_ST_ASYNC_WRITES) != 0)
2163 STm->do_async_writes = value;
2164 if ((options & MT_ST_DEF_WRITES) != 0)
2165 STm->defaults_for_writes = value;
2166 if ((options & MT_ST_READ_AHEAD) != 0)
2167 STm->do_read_ahead = value;
2168 if ((options & MT_ST_TWO_FM) != 0)
2169 STp->two_fm = value;
2170 if ((options & MT_ST_FAST_MTEOM) != 0)
2171 STp->fast_mteom = value;
2172 if ((options & MT_ST_AUTO_LOCK) != 0)
2173 STp->do_auto_lock = value;
2174 if ((options & MT_ST_CAN_BSR) != 0)
2175 STp->can_bsr = value;
2176 if ((options & MT_ST_NO_BLKLIMS) != 0)
2177 STp->omit_blklims = value;
2178 if ((STp->device)->scsi_level >= SCSI_2 &&
2179 (options & MT_ST_CAN_PARTITIONS) != 0)
2180 STp->can_partitions = value;
2181 if ((options & MT_ST_SCSI2LOGICAL) != 0)
2182 STp->scsi2_logical = value;
2183 if ((options & MT_ST_NOWAIT) != 0)
2184 STp->immediate = value;
2185 if ((options & MT_ST_SYSV) != 0)
2186 STm->sysv = value;
Kai Makisara40f6b362008-02-24 22:23:24 +02002187 if ((options & MT_ST_SILI) != 0)
2188 STp->sili = value;
Linus Torvalds1da177e2005-04-16 15:20:36 -07002189 DEB(
2190 if ((options & MT_ST_DEBUGGING) != 0)
2191 debugging = value;
2192 st_log_options(STp, STm, name); )
2193 } else if (code == MT_ST_WRITE_THRESHOLD) {
2194 /* Retained for compatibility */
2195 } else if (code == MT_ST_DEF_BLKSIZE) {
2196 value = (options & ~MT_ST_OPTIONS);
2197 if (value == ~MT_ST_OPTIONS) {
2198 STm->default_blksize = (-1);
2199 DEBC( printk(KERN_INFO "%s: Default block size disabled.\n", name));
2200 } else {
2201 STm->default_blksize = value;
2202 DEBC( printk(KERN_INFO "%s: Default block size set to %d bytes.\n",
2203 name, STm->default_blksize));
2204 if (STp->ready == ST_READY) {
2205 STp->blksize_changed = 0;
2206 set_mode_densblk(STp, STm);
2207 }
2208 }
2209 } else if (code == MT_ST_TIMEOUTS) {
2210 value = (options & ~MT_ST_OPTIONS);
2211 if ((value & MT_ST_SET_LONG_TIMEOUT) != 0) {
2212 STp->long_timeout = (value & ~MT_ST_SET_LONG_TIMEOUT) * HZ;
2213 DEBC( printk(KERN_INFO "%s: Long timeout set to %d seconds.\n", name,
2214 (value & ~MT_ST_SET_LONG_TIMEOUT)));
2215 } else {
2216 STp->device->timeout = value * HZ;
2217 DEBC( printk(KERN_INFO "%s: Normal timeout set to %d seconds.\n",
2218 name, value) );
2219 }
2220 } else if (code == MT_ST_SET_CLN) {
2221 value = (options & ~MT_ST_OPTIONS) & 0xff;
2222 if (value != 0 &&
2223 value < EXTENDED_SENSE_START && value >= SCSI_SENSE_BUFFERSIZE)
2224 return (-EINVAL);
2225 STp->cln_mode = value;
2226 STp->cln_sense_mask = (options >> 8) & 0xff;
2227 STp->cln_sense_value = (options >> 16) & 0xff;
2228 printk(KERN_INFO
2229 "%s: Cleaning request mode %d, mask %02x, value %02x\n",
2230 name, value, STp->cln_sense_mask, STp->cln_sense_value);
2231 } else if (code == MT_ST_DEF_OPTIONS) {
2232 code = (options & ~MT_ST_CLEAR_DEFAULT);
2233 value = (options & MT_ST_CLEAR_DEFAULT);
2234 if (code == MT_ST_DEF_DENSITY) {
2235 if (value == MT_ST_CLEAR_DEFAULT) {
2236 STm->default_density = (-1);
2237 DEBC( printk(KERN_INFO "%s: Density default disabled.\n",
2238 name));
2239 } else {
2240 STm->default_density = value & 0xff;
2241 DEBC( printk(KERN_INFO "%s: Density default set to %x\n",
2242 name, STm->default_density));
2243 if (STp->ready == ST_READY) {
2244 STp->density_changed = 0;
2245 set_mode_densblk(STp, STm);
2246 }
2247 }
2248 } else if (code == MT_ST_DEF_DRVBUFFER) {
2249 if (value == MT_ST_CLEAR_DEFAULT) {
2250 STp->default_drvbuffer = 0xff;
2251 DEBC( printk(KERN_INFO
2252 "%s: Drive buffer default disabled.\n", name));
2253 } else {
2254 STp->default_drvbuffer = value & 7;
2255 DEBC( printk(KERN_INFO
2256 "%s: Drive buffer default set to %x\n",
2257 name, STp->default_drvbuffer));
2258 if (STp->ready == ST_READY)
2259 st_int_ioctl(STp, MTSETDRVBUFFER, STp->default_drvbuffer);
2260 }
2261 } else if (code == MT_ST_DEF_COMPRESSION) {
2262 if (value == MT_ST_CLEAR_DEFAULT) {
2263 STm->default_compression = ST_DONT_TOUCH;
2264 DEBC( printk(KERN_INFO
2265 "%s: Compression default disabled.\n", name));
2266 } else {
2267 if ((value & 0xff00) != 0) {
2268 STp->c_algo = (value & 0xff00) >> 8;
2269 DEBC( printk(KERN_INFO "%s: Compression algorithm set to 0x%x.\n",
2270 name, STp->c_algo));
2271 }
2272 if ((value & 0xff) != 0xff) {
2273 STm->default_compression = (value & 1 ? ST_YES : ST_NO);
2274 DEBC( printk(KERN_INFO "%s: Compression default set to %x\n",
2275 name, (value & 1)));
2276 if (STp->ready == ST_READY) {
2277 STp->compression_changed = 0;
2278 st_compression(STp, (STm->default_compression == ST_YES));
2279 }
2280 }
2281 }
2282 }
2283 } else
2284 return (-EIO);
2285
2286 return 0;
2287}
2288
2289#define MODE_HEADER_LENGTH 4
2290
2291/* Mode header and page byte offsets */
2292#define MH_OFF_DATA_LENGTH 0
2293#define MH_OFF_MEDIUM_TYPE 1
2294#define MH_OFF_DEV_SPECIFIC 2
2295#define MH_OFF_BDESCS_LENGTH 3
2296#define MP_OFF_PAGE_NBR 0
2297#define MP_OFF_PAGE_LENGTH 1
2298
2299/* Mode header and page bit masks */
2300#define MH_BIT_WP 0x80
2301#define MP_MSK_PAGE_NBR 0x3f
2302
2303/* Don't return block descriptors */
2304#define MODE_SENSE_OMIT_BDESCS 0x08
2305
2306#define MODE_SELECT_PAGE_FORMAT 0x10
2307
2308/* Read a mode page into the tape buffer. The block descriptors are included
2309 if incl_block_descs is true. The page control is ored to the page number
2310 parameter, if necessary. */
2311static int read_mode_page(struct scsi_tape *STp, int page, int omit_block_descs)
2312{
2313 unsigned char cmd[MAX_COMMAND_SIZE];
Mike Christie8b05b772005-11-08 04:06:44 -06002314 struct st_request *SRpnt = NULL;
Linus Torvalds1da177e2005-04-16 15:20:36 -07002315
2316 memset(cmd, 0, MAX_COMMAND_SIZE);
2317 cmd[0] = MODE_SENSE;
2318 if (omit_block_descs)
2319 cmd[1] = MODE_SENSE_OMIT_BDESCS;
2320 cmd[2] = page;
2321 cmd[4] = 255;
2322
2323 SRpnt = st_do_scsi(SRpnt, STp, cmd, cmd[4], DMA_FROM_DEVICE,
2324 STp->device->timeout, 0, 1);
2325 if (SRpnt == NULL)
2326 return (STp->buffer)->syscall_result;
2327
Mike Christie8b05b772005-11-08 04:06:44 -06002328 st_release_request(SRpnt);
Linus Torvalds1da177e2005-04-16 15:20:36 -07002329
2330 return (STp->buffer)->syscall_result;
2331}
2332
2333
2334/* Send the mode page in the tape buffer to the drive. Assumes that the mode data
2335 in the buffer is correctly formatted. The long timeout is used if slow is non-zero. */
2336static int write_mode_page(struct scsi_tape *STp, int page, int slow)
2337{
2338 int pgo;
2339 unsigned char cmd[MAX_COMMAND_SIZE];
Mike Christie8b05b772005-11-08 04:06:44 -06002340 struct st_request *SRpnt = NULL;
Linus Torvalds1da177e2005-04-16 15:20:36 -07002341
2342 memset(cmd, 0, MAX_COMMAND_SIZE);
2343 cmd[0] = MODE_SELECT;
2344 cmd[1] = MODE_SELECT_PAGE_FORMAT;
2345 pgo = MODE_HEADER_LENGTH + (STp->buffer)->b_data[MH_OFF_BDESCS_LENGTH];
2346 cmd[4] = pgo + (STp->buffer)->b_data[pgo + MP_OFF_PAGE_LENGTH] + 2;
2347
2348 /* Clear reserved fields */
2349 (STp->buffer)->b_data[MH_OFF_DATA_LENGTH] = 0;
2350 (STp->buffer)->b_data[MH_OFF_MEDIUM_TYPE] = 0;
2351 (STp->buffer)->b_data[MH_OFF_DEV_SPECIFIC] &= ~MH_BIT_WP;
2352 (STp->buffer)->b_data[pgo + MP_OFF_PAGE_NBR] &= MP_MSK_PAGE_NBR;
2353
2354 SRpnt = st_do_scsi(SRpnt, STp, cmd, cmd[4], DMA_TO_DEVICE,
2355 (slow ? STp->long_timeout : STp->device->timeout), 0, 1);
2356 if (SRpnt == NULL)
2357 return (STp->buffer)->syscall_result;
2358
Mike Christie8b05b772005-11-08 04:06:44 -06002359 st_release_request(SRpnt);
Linus Torvalds1da177e2005-04-16 15:20:36 -07002360
2361 return (STp->buffer)->syscall_result;
2362}
2363
2364
2365#define COMPRESSION_PAGE 0x0f
2366#define COMPRESSION_PAGE_LENGTH 16
2367
2368#define CP_OFF_DCE_DCC 2
2369#define CP_OFF_C_ALGO 7
2370
2371#define DCE_MASK 0x80
2372#define DCC_MASK 0x40
2373#define RED_MASK 0x60
2374
2375
2376/* Control the compression with mode page 15. Algorithm not changed if zero.
2377
2378 The block descriptors are read and written because Sony SDT-7000 does not
2379 work without this (suggestion from Michael Schaefer <Michael.Schaefer@dlr.de>).
2380 Including block descriptors should not cause any harm to other drives. */
2381
2382static int st_compression(struct scsi_tape * STp, int state)
2383{
2384 int retval;
2385 int mpoffs; /* Offset to mode page start */
2386 unsigned char *b_data = (STp->buffer)->b_data;
2387 DEB( char *name = tape_name(STp); )
2388
2389 if (STp->ready != ST_READY)
2390 return (-EIO);
2391
2392 /* Read the current page contents */
2393 retval = read_mode_page(STp, COMPRESSION_PAGE, 0);
2394 if (retval) {
2395 DEBC(printk(ST_DEB_MSG "%s: Compression mode page not supported.\n",
2396 name));
2397 return (-EIO);
2398 }
2399
2400 mpoffs = MODE_HEADER_LENGTH + b_data[MH_OFF_BDESCS_LENGTH];
2401 DEBC(printk(ST_DEB_MSG "%s: Compression state is %d.\n", name,
2402 (b_data[mpoffs + CP_OFF_DCE_DCC] & DCE_MASK ? 1 : 0)));
2403
2404 /* Check if compression can be changed */
2405 if ((b_data[mpoffs + CP_OFF_DCE_DCC] & DCC_MASK) == 0) {
2406 DEBC(printk(ST_DEB_MSG "%s: Compression not supported.\n", name));
2407 return (-EIO);
2408 }
2409
2410 /* Do the change */
2411 if (state) {
2412 b_data[mpoffs + CP_OFF_DCE_DCC] |= DCE_MASK;
2413 if (STp->c_algo != 0)
2414 b_data[mpoffs + CP_OFF_C_ALGO] = STp->c_algo;
2415 }
2416 else {
2417 b_data[mpoffs + CP_OFF_DCE_DCC] &= ~DCE_MASK;
2418 if (STp->c_algo != 0)
2419 b_data[mpoffs + CP_OFF_C_ALGO] = 0; /* no compression */
2420 }
2421
2422 retval = write_mode_page(STp, COMPRESSION_PAGE, 0);
2423 if (retval) {
2424 DEBC(printk(ST_DEB_MSG "%s: Compression change failed.\n", name));
2425 return (-EIO);
2426 }
2427 DEBC(printk(ST_DEB_MSG "%s: Compression state changed to %d.\n",
2428 name, state));
2429
2430 STp->compression_changed = 1;
2431 return 0;
2432}
2433
2434
2435/* Process the load and unload commands (does unload if the load code is zero) */
2436static int do_load_unload(struct scsi_tape *STp, struct file *filp, int load_code)
2437{
2438 int retval = (-EIO), timeout;
2439 DEB( char *name = tape_name(STp); )
2440 unsigned char cmd[MAX_COMMAND_SIZE];
2441 struct st_partstat *STps;
Mike Christie8b05b772005-11-08 04:06:44 -06002442 struct st_request *SRpnt;
Linus Torvalds1da177e2005-04-16 15:20:36 -07002443
2444 if (STp->ready != ST_READY && !load_code) {
2445 if (STp->ready == ST_NO_TAPE)
2446 return (-ENOMEDIUM);
2447 else
2448 return (-EIO);
2449 }
2450
2451 memset(cmd, 0, MAX_COMMAND_SIZE);
2452 cmd[0] = START_STOP;
2453 if (load_code)
2454 cmd[4] |= 1;
2455 /*
2456 * If arg >= 1 && arg <= 6 Enhanced load/unload in HP C1553A
2457 */
2458 if (load_code >= 1 + MT_ST_HPLOADER_OFFSET
2459 && load_code <= 6 + MT_ST_HPLOADER_OFFSET) {
2460 DEBC(printk(ST_DEB_MSG "%s: Enhanced %sload slot %2d.\n",
2461 name, (cmd[4]) ? "" : "un",
2462 load_code - MT_ST_HPLOADER_OFFSET));
2463 cmd[3] = load_code - MT_ST_HPLOADER_OFFSET; /* MediaID field of C1553A */
2464 }
2465 if (STp->immediate) {
2466 cmd[1] = 1; /* Don't wait for completion */
2467 timeout = STp->device->timeout;
2468 }
2469 else
2470 timeout = STp->long_timeout;
2471
2472 DEBC(
2473 if (!load_code)
2474 printk(ST_DEB_MSG "%s: Unloading tape.\n", name);
2475 else
2476 printk(ST_DEB_MSG "%s: Loading tape.\n", name);
2477 );
2478
2479 SRpnt = st_do_scsi(NULL, STp, cmd, 0, DMA_NONE,
2480 timeout, MAX_RETRIES, 1);
2481 if (!SRpnt)
2482 return (STp->buffer)->syscall_result;
2483
2484 retval = (STp->buffer)->syscall_result;
Mike Christie8b05b772005-11-08 04:06:44 -06002485 st_release_request(SRpnt);
Linus Torvalds1da177e2005-04-16 15:20:36 -07002486
2487 if (!retval) { /* SCSI command successful */
2488
2489 if (!load_code) {
2490 STp->rew_at_close = 0;
2491 STp->ready = ST_NO_TAPE;
2492 }
2493 else {
2494 STp->rew_at_close = STp->autorew_dev;
2495 retval = check_tape(STp, filp);
2496 if (retval > 0)
2497 retval = 0;
2498 }
2499 }
2500 else {
2501 STps = &(STp->ps[STp->partition]);
2502 STps->drv_file = STps->drv_block = (-1);
2503 }
2504
2505 return retval;
2506}
2507
2508#if DEBUG
2509#define ST_DEB_FORWARD 0
2510#define ST_DEB_BACKWARD 1
2511static void deb_space_print(char *name, int direction, char *units, unsigned char *cmd)
2512{
2513 s32 sc;
2514
2515 sc = cmd[2] & 0x80 ? 0xff000000 : 0;
2516 sc |= (cmd[2] << 16) | (cmd[3] << 8) | cmd[4];
2517 if (direction)
2518 sc = -sc;
2519 printk(ST_DEB_MSG "%s: Spacing tape %s over %d %s.\n", name,
2520 direction ? "backward" : "forward", sc, units);
2521}
2522#endif
2523
2524
2525/* Internal ioctl function */
2526static int st_int_ioctl(struct scsi_tape *STp, unsigned int cmd_in, unsigned long arg)
2527{
2528 int timeout;
2529 long ltmp;
2530 int ioctl_result;
2531 int chg_eof = 1;
2532 unsigned char cmd[MAX_COMMAND_SIZE];
Mike Christie8b05b772005-11-08 04:06:44 -06002533 struct st_request *SRpnt;
Linus Torvalds1da177e2005-04-16 15:20:36 -07002534 struct st_partstat *STps;
2535 int fileno, blkno, at_sm, undone;
2536 int datalen = 0, direction = DMA_NONE;
2537 char *name = tape_name(STp);
2538
2539 WARN_ON(STp->buffer->do_dio != 0);
2540 if (STp->ready != ST_READY) {
2541 if (STp->ready == ST_NO_TAPE)
2542 return (-ENOMEDIUM);
2543 else
2544 return (-EIO);
2545 }
2546 timeout = STp->long_timeout;
2547 STps = &(STp->ps[STp->partition]);
2548 fileno = STps->drv_file;
2549 blkno = STps->drv_block;
2550 at_sm = STps->at_sm;
2551
2552 memset(cmd, 0, MAX_COMMAND_SIZE);
2553 switch (cmd_in) {
2554 case MTFSFM:
2555 chg_eof = 0; /* Changed from the FSF after this */
2556 case MTFSF:
2557 cmd[0] = SPACE;
2558 cmd[1] = 0x01; /* Space FileMarks */
2559 cmd[2] = (arg >> 16);
2560 cmd[3] = (arg >> 8);
2561 cmd[4] = arg;
2562 DEBC(deb_space_print(name, ST_DEB_FORWARD, "filemarks", cmd);)
2563 if (fileno >= 0)
2564 fileno += arg;
2565 blkno = 0;
2566 at_sm &= (arg == 0);
2567 break;
2568 case MTBSFM:
2569 chg_eof = 0; /* Changed from the FSF after this */
2570 case MTBSF:
2571 cmd[0] = SPACE;
2572 cmd[1] = 0x01; /* Space FileMarks */
2573 ltmp = (-arg);
2574 cmd[2] = (ltmp >> 16);
2575 cmd[3] = (ltmp >> 8);
2576 cmd[4] = ltmp;
2577 DEBC(deb_space_print(name, ST_DEB_BACKWARD, "filemarks", cmd);)
2578 if (fileno >= 0)
2579 fileno -= arg;
2580 blkno = (-1); /* We can't know the block number */
2581 at_sm &= (arg == 0);
2582 break;
2583 case MTFSR:
2584 cmd[0] = SPACE;
2585 cmd[1] = 0x00; /* Space Blocks */
2586 cmd[2] = (arg >> 16);
2587 cmd[3] = (arg >> 8);
2588 cmd[4] = arg;
2589 DEBC(deb_space_print(name, ST_DEB_FORWARD, "blocks", cmd);)
2590 if (blkno >= 0)
2591 blkno += arg;
2592 at_sm &= (arg == 0);
2593 break;
2594 case MTBSR:
2595 cmd[0] = SPACE;
2596 cmd[1] = 0x00; /* Space Blocks */
2597 ltmp = (-arg);
2598 cmd[2] = (ltmp >> 16);
2599 cmd[3] = (ltmp >> 8);
2600 cmd[4] = ltmp;
2601 DEBC(deb_space_print(name, ST_DEB_BACKWARD, "blocks", cmd);)
2602 if (blkno >= 0)
2603 blkno -= arg;
2604 at_sm &= (arg == 0);
2605 break;
2606 case MTFSS:
2607 cmd[0] = SPACE;
2608 cmd[1] = 0x04; /* Space Setmarks */
2609 cmd[2] = (arg >> 16);
2610 cmd[3] = (arg >> 8);
2611 cmd[4] = arg;
2612 DEBC(deb_space_print(name, ST_DEB_FORWARD, "setmarks", cmd);)
2613 if (arg != 0) {
2614 blkno = fileno = (-1);
2615 at_sm = 1;
2616 }
2617 break;
2618 case MTBSS:
2619 cmd[0] = SPACE;
2620 cmd[1] = 0x04; /* Space Setmarks */
2621 ltmp = (-arg);
2622 cmd[2] = (ltmp >> 16);
2623 cmd[3] = (ltmp >> 8);
2624 cmd[4] = ltmp;
2625 DEBC(deb_space_print(name, ST_DEB_BACKWARD, "setmarks", cmd);)
2626 if (arg != 0) {
2627 blkno = fileno = (-1);
2628 at_sm = 1;
2629 }
2630 break;
2631 case MTWEOF:
2632 case MTWSM:
2633 if (STp->write_prot)
2634 return (-EACCES);
2635 cmd[0] = WRITE_FILEMARKS;
2636 if (cmd_in == MTWSM)
2637 cmd[1] = 2;
2638 cmd[2] = (arg >> 16);
2639 cmd[3] = (arg >> 8);
2640 cmd[4] = arg;
2641 timeout = STp->device->timeout;
2642 DEBC(
2643 if (cmd_in == MTWEOF)
2644 printk(ST_DEB_MSG "%s: Writing %d filemarks.\n", name,
2645 cmd[2] * 65536 + cmd[3] * 256 + cmd[4]);
2646 else
2647 printk(ST_DEB_MSG "%s: Writing %d setmarks.\n", name,
2648 cmd[2] * 65536 + cmd[3] * 256 + cmd[4]);
2649 )
2650 if (fileno >= 0)
2651 fileno += arg;
2652 blkno = 0;
2653 at_sm = (cmd_in == MTWSM);
2654 break;
2655 case MTREW:
2656 cmd[0] = REZERO_UNIT;
2657 if (STp->immediate) {
2658 cmd[1] = 1; /* Don't wait for completion */
2659 timeout = STp->device->timeout;
2660 }
2661 DEBC(printk(ST_DEB_MSG "%s: Rewinding tape.\n", name));
2662 fileno = blkno = at_sm = 0;
2663 break;
2664 case MTNOP:
2665 DEBC(printk(ST_DEB_MSG "%s: No op on tape.\n", name));
2666 return 0; /* Should do something ? */
2667 break;
2668 case MTRETEN:
2669 cmd[0] = START_STOP;
2670 if (STp->immediate) {
2671 cmd[1] = 1; /* Don't wait for completion */
2672 timeout = STp->device->timeout;
2673 }
2674 cmd[4] = 3;
2675 DEBC(printk(ST_DEB_MSG "%s: Retensioning tape.\n", name));
2676 fileno = blkno = at_sm = 0;
2677 break;
2678 case MTEOM:
2679 if (!STp->fast_mteom) {
2680 /* space to the end of tape */
2681 ioctl_result = st_int_ioctl(STp, MTFSF, 0x7fffff);
2682 fileno = STps->drv_file;
2683 if (STps->eof >= ST_EOD_1)
2684 return 0;
2685 /* The next lines would hide the number of spaced FileMarks
2686 That's why I inserted the previous lines. I had no luck
2687 with detecting EOM with FSF, so we go now to EOM.
2688 Joerg Weule */
2689 } else
2690 fileno = (-1);
2691 cmd[0] = SPACE;
2692 cmd[1] = 3;
2693 DEBC(printk(ST_DEB_MSG "%s: Spacing to end of recorded medium.\n",
2694 name));
2695 blkno = -1;
2696 at_sm = 0;
2697 break;
2698 case MTERASE:
2699 if (STp->write_prot)
2700 return (-EACCES);
2701 cmd[0] = ERASE;
2702 cmd[1] = (arg ? 1 : 0); /* Long erase with non-zero argument */
2703 if (STp->immediate) {
2704 cmd[1] |= 2; /* Don't wait for completion */
2705 timeout = STp->device->timeout;
2706 }
2707 else
2708 timeout = STp->long_timeout * 8;
2709
2710 DEBC(printk(ST_DEB_MSG "%s: Erasing tape.\n", name));
2711 fileno = blkno = at_sm = 0;
2712 break;
2713 case MTSETBLK: /* Set block length */
2714 case MTSETDENSITY: /* Set tape density */
2715 case MTSETDRVBUFFER: /* Set drive buffering */
2716 case SET_DENS_AND_BLK: /* Set density and block size */
2717 chg_eof = 0;
2718 if (STp->dirty || (STp->buffer)->buffer_bytes != 0)
2719 return (-EIO); /* Not allowed if data in buffer */
2720 if ((cmd_in == MTSETBLK || cmd_in == SET_DENS_AND_BLK) &&
2721 (arg & MT_ST_BLKSIZE_MASK) != 0 &&
2722 STp->max_block > 0 &&
2723 ((arg & MT_ST_BLKSIZE_MASK) < STp->min_block ||
2724 (arg & MT_ST_BLKSIZE_MASK) > STp->max_block)) {
2725 printk(KERN_WARNING "%s: Illegal block size.\n", name);
2726 return (-EINVAL);
2727 }
2728 cmd[0] = MODE_SELECT;
2729 if ((STp->use_pf & USE_PF))
2730 cmd[1] = MODE_SELECT_PAGE_FORMAT;
2731 cmd[4] = datalen = 12;
2732 direction = DMA_TO_DEVICE;
2733
2734 memset((STp->buffer)->b_data, 0, 12);
2735 if (cmd_in == MTSETDRVBUFFER)
2736 (STp->buffer)->b_data[2] = (arg & 7) << 4;
2737 else
2738 (STp->buffer)->b_data[2] =
2739 STp->drv_buffer << 4;
2740 (STp->buffer)->b_data[3] = 8; /* block descriptor length */
2741 if (cmd_in == MTSETDENSITY) {
2742 (STp->buffer)->b_data[4] = arg;
2743 STp->density_changed = 1; /* At least we tried ;-) */
2744 } else if (cmd_in == SET_DENS_AND_BLK)
2745 (STp->buffer)->b_data[4] = arg >> 24;
2746 else
2747 (STp->buffer)->b_data[4] = STp->density;
2748 if (cmd_in == MTSETBLK || cmd_in == SET_DENS_AND_BLK) {
2749 ltmp = arg & MT_ST_BLKSIZE_MASK;
2750 if (cmd_in == MTSETBLK)
2751 STp->blksize_changed = 1; /* At least we tried ;-) */
2752 } else
2753 ltmp = STp->block_size;
2754 (STp->buffer)->b_data[9] = (ltmp >> 16);
2755 (STp->buffer)->b_data[10] = (ltmp >> 8);
2756 (STp->buffer)->b_data[11] = ltmp;
2757 timeout = STp->device->timeout;
2758 DEBC(
2759 if (cmd_in == MTSETBLK || cmd_in == SET_DENS_AND_BLK)
2760 printk(ST_DEB_MSG
2761 "%s: Setting block size to %d bytes.\n", name,
2762 (STp->buffer)->b_data[9] * 65536 +
2763 (STp->buffer)->b_data[10] * 256 +
2764 (STp->buffer)->b_data[11]);
2765 if (cmd_in == MTSETDENSITY || cmd_in == SET_DENS_AND_BLK)
2766 printk(ST_DEB_MSG
2767 "%s: Setting density code to %x.\n", name,
2768 (STp->buffer)->b_data[4]);
2769 if (cmd_in == MTSETDRVBUFFER)
2770 printk(ST_DEB_MSG
2771 "%s: Setting drive buffer code to %d.\n", name,
2772 ((STp->buffer)->b_data[2] >> 4) & 7);
2773 )
2774 break;
2775 default:
2776 return (-ENOSYS);
2777 }
2778
2779 SRpnt = st_do_scsi(NULL, STp, cmd, datalen, direction,
2780 timeout, MAX_RETRIES, 1);
2781 if (!SRpnt)
2782 return (STp->buffer)->syscall_result;
2783
2784 ioctl_result = (STp->buffer)->syscall_result;
2785
2786 if (!ioctl_result) { /* SCSI command successful */
Mike Christie8b05b772005-11-08 04:06:44 -06002787 st_release_request(SRpnt);
Linus Torvalds1da177e2005-04-16 15:20:36 -07002788 SRpnt = NULL;
2789 STps->drv_block = blkno;
2790 STps->drv_file = fileno;
2791 STps->at_sm = at_sm;
2792
2793 if (cmd_in == MTBSFM)
2794 ioctl_result = st_int_ioctl(STp, MTFSF, 1);
2795 else if (cmd_in == MTFSFM)
2796 ioctl_result = st_int_ioctl(STp, MTBSF, 1);
2797
2798 if (cmd_in == MTSETBLK || cmd_in == SET_DENS_AND_BLK) {
2799 int old_block_size = STp->block_size;
2800 STp->block_size = arg & MT_ST_BLKSIZE_MASK;
2801 if (STp->block_size != 0) {
2802 if (old_block_size == 0)
2803 normalize_buffer(STp->buffer);
2804 (STp->buffer)->buffer_blocks =
2805 (STp->buffer)->buffer_size / STp->block_size;
2806 }
2807 (STp->buffer)->buffer_bytes = (STp->buffer)->read_pointer = 0;
2808 if (cmd_in == SET_DENS_AND_BLK)
2809 STp->density = arg >> MT_ST_DENSITY_SHIFT;
2810 } else if (cmd_in == MTSETDRVBUFFER)
2811 STp->drv_buffer = (arg & 7);
2812 else if (cmd_in == MTSETDENSITY)
2813 STp->density = arg;
2814
2815 if (cmd_in == MTEOM)
2816 STps->eof = ST_EOD;
2817 else if (cmd_in == MTFSF)
2818 STps->eof = ST_FM;
2819 else if (chg_eof)
2820 STps->eof = ST_NOEOF;
2821
2822 if (cmd_in == MTWEOF)
2823 STps->rw = ST_IDLE;
2824 } else { /* SCSI command was not completely successful. Don't return
2825 from this block without releasing the SCSI command block! */
2826 struct st_cmdstatus *cmdstatp = &STp->buffer->cmdstat;
2827
2828 if (cmdstatp->flags & SENSE_EOM) {
2829 if (cmd_in != MTBSF && cmd_in != MTBSFM &&
2830 cmd_in != MTBSR && cmd_in != MTBSS)
2831 STps->eof = ST_EOM_OK;
2832 STps->drv_block = 0;
2833 }
2834
2835 if (cmdstatp->remainder_valid)
2836 undone = (int)cmdstatp->uremainder64;
2837 else
2838 undone = 0;
2839
2840 if (cmd_in == MTWEOF &&
2841 cmdstatp->have_sense &&
Kai Makisara91614c02007-01-26 00:38:39 +02002842 (cmdstatp->flags & SENSE_EOM)) {
2843 if (cmdstatp->sense_hdr.sense_key == NO_SENSE ||
2844 cmdstatp->sense_hdr.sense_key == RECOVERED_ERROR) {
2845 ioctl_result = 0; /* EOF(s) written successfully at EOM */
2846 STps->eof = ST_NOEOF;
2847 } else { /* Writing EOF(s) failed */
2848 if (fileno >= 0)
2849 fileno -= undone;
2850 if (undone < arg)
2851 STps->eof = ST_NOEOF;
2852 }
Linus Torvalds1da177e2005-04-16 15:20:36 -07002853 STps->drv_file = fileno;
Linus Torvalds1da177e2005-04-16 15:20:36 -07002854 } else if ((cmd_in == MTFSF) || (cmd_in == MTFSFM)) {
2855 if (fileno >= 0)
2856 STps->drv_file = fileno - undone;
2857 else
2858 STps->drv_file = fileno;
2859 STps->drv_block = -1;
2860 STps->eof = ST_NOEOF;
2861 } else if ((cmd_in == MTBSF) || (cmd_in == MTBSFM)) {
2862 if (arg > 0 && undone < 0) /* Some drives get this wrong */
2863 undone = (-undone);
2864 if (STps->drv_file >= 0)
2865 STps->drv_file = fileno + undone;
2866 STps->drv_block = 0;
2867 STps->eof = ST_NOEOF;
2868 } else if (cmd_in == MTFSR) {
2869 if (cmdstatp->flags & SENSE_FMK) { /* Hit filemark */
2870 if (STps->drv_file >= 0)
2871 STps->drv_file++;
2872 STps->drv_block = 0;
2873 STps->eof = ST_FM;
2874 } else {
2875 if (blkno >= undone)
2876 STps->drv_block = blkno - undone;
2877 else
2878 STps->drv_block = (-1);
2879 STps->eof = ST_NOEOF;
2880 }
2881 } else if (cmd_in == MTBSR) {
2882 if (cmdstatp->flags & SENSE_FMK) { /* Hit filemark */
2883 STps->drv_file--;
2884 STps->drv_block = (-1);
2885 } else {
2886 if (arg > 0 && undone < 0) /* Some drives get this wrong */
2887 undone = (-undone);
2888 if (STps->drv_block >= 0)
2889 STps->drv_block = blkno + undone;
2890 }
2891 STps->eof = ST_NOEOF;
2892 } else if (cmd_in == MTEOM) {
2893 STps->drv_file = (-1);
2894 STps->drv_block = (-1);
2895 STps->eof = ST_EOD;
2896 } else if (cmd_in == MTSETBLK ||
2897 cmd_in == MTSETDENSITY ||
2898 cmd_in == MTSETDRVBUFFER ||
2899 cmd_in == SET_DENS_AND_BLK) {
2900 if (cmdstatp->sense_hdr.sense_key == ILLEGAL_REQUEST &&
2901 !(STp->use_pf & PF_TESTED)) {
2902 /* Try the other possible state of Page Format if not
2903 already tried */
2904 STp->use_pf = !STp->use_pf | PF_TESTED;
Mike Christie8b05b772005-11-08 04:06:44 -06002905 st_release_request(SRpnt);
Linus Torvalds1da177e2005-04-16 15:20:36 -07002906 SRpnt = NULL;
2907 return st_int_ioctl(STp, cmd_in, arg);
2908 }
2909 } else if (chg_eof)
2910 STps->eof = ST_NOEOF;
2911
2912 if (cmdstatp->sense_hdr.sense_key == BLANK_CHECK)
2913 STps->eof = ST_EOD;
2914
Mike Christie8b05b772005-11-08 04:06:44 -06002915 st_release_request(SRpnt);
Linus Torvalds1da177e2005-04-16 15:20:36 -07002916 SRpnt = NULL;
2917 }
2918
2919 return ioctl_result;
2920}
2921
2922
2923/* Get the tape position. If bt == 2, arg points into a kernel space mt_loc
2924 structure. */
2925
2926static int get_location(struct scsi_tape *STp, unsigned int *block, int *partition,
2927 int logical)
2928{
2929 int result;
2930 unsigned char scmd[MAX_COMMAND_SIZE];
Mike Christie8b05b772005-11-08 04:06:44 -06002931 struct st_request *SRpnt;
Linus Torvalds1da177e2005-04-16 15:20:36 -07002932 DEB( char *name = tape_name(STp); )
2933
2934 if (STp->ready != ST_READY)
2935 return (-EIO);
2936
2937 memset(scmd, 0, MAX_COMMAND_SIZE);
2938 if ((STp->device)->scsi_level < SCSI_2) {
2939 scmd[0] = QFA_REQUEST_BLOCK;
2940 scmd[4] = 3;
2941 } else {
2942 scmd[0] = READ_POSITION;
2943 if (!logical && !STp->scsi2_logical)
2944 scmd[1] = 1;
2945 }
2946 SRpnt = st_do_scsi(NULL, STp, scmd, 20, DMA_FROM_DEVICE,
2947 STp->device->timeout, MAX_READY_RETRIES, 1);
2948 if (!SRpnt)
2949 return (STp->buffer)->syscall_result;
2950
2951 if ((STp->buffer)->syscall_result != 0 ||
2952 (STp->device->scsi_level >= SCSI_2 &&
2953 ((STp->buffer)->b_data[0] & 4) != 0)) {
2954 *block = *partition = 0;
2955 DEBC(printk(ST_DEB_MSG "%s: Can't read tape position.\n", name));
2956 result = (-EIO);
2957 } else {
2958 result = 0;
2959 if ((STp->device)->scsi_level < SCSI_2) {
2960 *block = ((STp->buffer)->b_data[0] << 16)
2961 + ((STp->buffer)->b_data[1] << 8)
2962 + (STp->buffer)->b_data[2];
2963 *partition = 0;
2964 } else {
2965 *block = ((STp->buffer)->b_data[4] << 24)
2966 + ((STp->buffer)->b_data[5] << 16)
2967 + ((STp->buffer)->b_data[6] << 8)
2968 + (STp->buffer)->b_data[7];
2969 *partition = (STp->buffer)->b_data[1];
2970 if (((STp->buffer)->b_data[0] & 0x80) &&
2971 (STp->buffer)->b_data[1] == 0) /* BOP of partition 0 */
2972 STp->ps[0].drv_block = STp->ps[0].drv_file = 0;
2973 }
2974 DEBC(printk(ST_DEB_MSG "%s: Got tape pos. blk %d part %d.\n", name,
2975 *block, *partition));
2976 }
Mike Christie8b05b772005-11-08 04:06:44 -06002977 st_release_request(SRpnt);
Linus Torvalds1da177e2005-04-16 15:20:36 -07002978 SRpnt = NULL;
2979
2980 return result;
2981}
2982
2983
2984/* Set the tape block and partition. Negative partition means that only the
2985 block should be set in vendor specific way. */
2986static int set_location(struct scsi_tape *STp, unsigned int block, int partition,
2987 int logical)
2988{
2989 struct st_partstat *STps;
2990 int result, p;
2991 unsigned int blk;
2992 int timeout;
2993 unsigned char scmd[MAX_COMMAND_SIZE];
Mike Christie8b05b772005-11-08 04:06:44 -06002994 struct st_request *SRpnt;
Linus Torvalds1da177e2005-04-16 15:20:36 -07002995 DEB( char *name = tape_name(STp); )
2996
2997 if (STp->ready != ST_READY)
2998 return (-EIO);
2999 timeout = STp->long_timeout;
3000 STps = &(STp->ps[STp->partition]);
3001
3002 DEBC(printk(ST_DEB_MSG "%s: Setting block to %d and partition to %d.\n",
3003 name, block, partition));
3004 DEB(if (partition < 0)
3005 return (-EIO); )
3006
3007 /* Update the location at the partition we are leaving */
3008 if ((!STp->can_partitions && partition != 0) ||
3009 partition >= ST_NBR_PARTITIONS)
3010 return (-EINVAL);
3011 if (partition != STp->partition) {
3012 if (get_location(STp, &blk, &p, 1))
3013 STps->last_block_valid = 0;
3014 else {
3015 STps->last_block_valid = 1;
3016 STps->last_block_visited = blk;
3017 DEBC(printk(ST_DEB_MSG
3018 "%s: Visited block %d for partition %d saved.\n",
3019 name, blk, STp->partition));
3020 }
3021 }
3022
3023 memset(scmd, 0, MAX_COMMAND_SIZE);
3024 if ((STp->device)->scsi_level < SCSI_2) {
3025 scmd[0] = QFA_SEEK_BLOCK;
3026 scmd[2] = (block >> 16);
3027 scmd[3] = (block >> 8);
3028 scmd[4] = block;
3029 scmd[5] = 0;
3030 } else {
3031 scmd[0] = SEEK_10;
3032 scmd[3] = (block >> 24);
3033 scmd[4] = (block >> 16);
3034 scmd[5] = (block >> 8);
3035 scmd[6] = block;
3036 if (!logical && !STp->scsi2_logical)
3037 scmd[1] = 4;
3038 if (STp->partition != partition) {
3039 scmd[1] |= 2;
3040 scmd[8] = partition;
3041 DEBC(printk(ST_DEB_MSG
3042 "%s: Trying to change partition from %d to %d\n",
3043 name, STp->partition, partition));
3044 }
3045 }
3046 if (STp->immediate) {
3047 scmd[1] |= 1; /* Don't wait for completion */
3048 timeout = STp->device->timeout;
3049 }
3050
3051 SRpnt = st_do_scsi(NULL, STp, scmd, 0, DMA_NONE,
3052 timeout, MAX_READY_RETRIES, 1);
3053 if (!SRpnt)
3054 return (STp->buffer)->syscall_result;
3055
3056 STps->drv_block = STps->drv_file = (-1);
3057 STps->eof = ST_NOEOF;
3058 if ((STp->buffer)->syscall_result != 0) {
3059 result = (-EIO);
3060 if (STp->can_partitions &&
3061 (STp->device)->scsi_level >= SCSI_2 &&
3062 (p = find_partition(STp)) >= 0)
3063 STp->partition = p;
3064 } else {
3065 if (STp->can_partitions) {
3066 STp->partition = partition;
3067 STps = &(STp->ps[partition]);
3068 if (!STps->last_block_valid ||
3069 STps->last_block_visited != block) {
3070 STps->at_sm = 0;
3071 STps->rw = ST_IDLE;
3072 }
3073 } else
3074 STps->at_sm = 0;
3075 if (block == 0)
3076 STps->drv_block = STps->drv_file = 0;
3077 result = 0;
3078 }
3079
Mike Christie8b05b772005-11-08 04:06:44 -06003080 st_release_request(SRpnt);
Linus Torvalds1da177e2005-04-16 15:20:36 -07003081 SRpnt = NULL;
3082
3083 return result;
3084}
3085
3086
3087/* Find the current partition number for the drive status. Called from open and
3088 returns either partition number of negative error code. */
3089static int find_partition(struct scsi_tape *STp)
3090{
3091 int i, partition;
3092 unsigned int block;
3093
3094 if ((i = get_location(STp, &block, &partition, 1)) < 0)
3095 return i;
3096 if (partition >= ST_NBR_PARTITIONS)
3097 return (-EIO);
3098 return partition;
3099}
3100
3101
3102/* Change the partition if necessary */
3103static int switch_partition(struct scsi_tape *STp)
3104{
3105 struct st_partstat *STps;
3106
3107 if (STp->partition == STp->new_partition)
3108 return 0;
3109 STps = &(STp->ps[STp->new_partition]);
3110 if (!STps->last_block_valid)
3111 STps->last_block_visited = 0;
3112 return set_location(STp, STps->last_block_visited, STp->new_partition, 1);
3113}
3114
3115/* Functions for reading and writing the medium partition mode page. */
3116
3117#define PART_PAGE 0x11
3118#define PART_PAGE_FIXED_LENGTH 8
3119
3120#define PP_OFF_MAX_ADD_PARTS 2
3121#define PP_OFF_NBR_ADD_PARTS 3
3122#define PP_OFF_FLAGS 4
3123#define PP_OFF_PART_UNITS 6
3124#define PP_OFF_RESERVED 7
3125
3126#define PP_BIT_IDP 0x20
3127#define PP_MSK_PSUM_MB 0x10
3128
3129/* Get the number of partitions on the tape. As a side effect reads the
3130 mode page into the tape buffer. */
3131static int nbr_partitions(struct scsi_tape *STp)
3132{
3133 int result;
3134 DEB( char *name = tape_name(STp); )
3135
3136 if (STp->ready != ST_READY)
3137 return (-EIO);
3138
3139 result = read_mode_page(STp, PART_PAGE, 1);
3140
3141 if (result) {
3142 DEBC(printk(ST_DEB_MSG "%s: Can't read medium partition page.\n",
3143 name));
3144 result = (-EIO);
3145 } else {
3146 result = (STp->buffer)->b_data[MODE_HEADER_LENGTH +
3147 PP_OFF_NBR_ADD_PARTS] + 1;
3148 DEBC(printk(ST_DEB_MSG "%s: Number of partitions %d.\n", name, result));
3149 }
3150
3151 return result;
3152}
3153
3154
3155/* Partition the tape into two partitions if size > 0 or one partition if
3156 size == 0.
3157
3158 The block descriptors are read and written because Sony SDT-7000 does not
3159 work without this (suggestion from Michael Schaefer <Michael.Schaefer@dlr.de>).
3160
3161 My HP C1533A drive returns only one partition size field. This is used to
3162 set the size of partition 1. There is no size field for the default partition.
3163 Michael Schaefer's Sony SDT-7000 returns two descriptors and the second is
3164 used to set the size of partition 1 (this is what the SCSI-3 standard specifies).
3165 The following algorithm is used to accommodate both drives: if the number of
3166 partition size fields is greater than the maximum number of additional partitions
3167 in the mode page, the second field is used. Otherwise the first field is used.
3168
3169 For Seagate DDS drives the page length must be 8 when no partitions is defined
3170 and 10 when 1 partition is defined (information from Eric Lee Green). This is
3171 is acceptable also to some other old drives and enforced if the first partition
3172 size field is used for the first additional partition size.
3173 */
3174static int partition_tape(struct scsi_tape *STp, int size)
3175{
3176 char *name = tape_name(STp);
3177 int result;
3178 int pgo, psd_cnt, psdo;
3179 unsigned char *bp;
3180
3181 result = read_mode_page(STp, PART_PAGE, 0);
3182 if (result) {
3183 DEBC(printk(ST_DEB_MSG "%s: Can't read partition mode page.\n", name));
3184 return result;
3185 }
3186 /* The mode page is in the buffer. Let's modify it and write it. */
3187 bp = (STp->buffer)->b_data;
3188 pgo = MODE_HEADER_LENGTH + bp[MH_OFF_BDESCS_LENGTH];
3189 DEBC(printk(ST_DEB_MSG "%s: Partition page length is %d bytes.\n",
3190 name, bp[pgo + MP_OFF_PAGE_LENGTH] + 2));
3191
3192 psd_cnt = (bp[pgo + MP_OFF_PAGE_LENGTH] + 2 - PART_PAGE_FIXED_LENGTH) / 2;
3193 psdo = pgo + PART_PAGE_FIXED_LENGTH;
3194 if (psd_cnt > bp[pgo + PP_OFF_MAX_ADD_PARTS]) {
3195 bp[psdo] = bp[psdo + 1] = 0xff; /* Rest of the tape */
3196 psdo += 2;
3197 }
3198 memset(bp + psdo, 0, bp[pgo + PP_OFF_NBR_ADD_PARTS] * 2);
3199
3200 DEBC(printk("%s: psd_cnt %d, max.parts %d, nbr_parts %d\n", name,
3201 psd_cnt, bp[pgo + PP_OFF_MAX_ADD_PARTS],
3202 bp[pgo + PP_OFF_NBR_ADD_PARTS]));
3203
3204 if (size <= 0) {
3205 bp[pgo + PP_OFF_NBR_ADD_PARTS] = 0;
3206 if (psd_cnt <= bp[pgo + PP_OFF_MAX_ADD_PARTS])
3207 bp[pgo + MP_OFF_PAGE_LENGTH] = 6;
3208 DEBC(printk(ST_DEB_MSG "%s: Formatting tape with one partition.\n",
3209 name));
3210 } else {
3211 bp[psdo] = (size >> 8) & 0xff;
3212 bp[psdo + 1] = size & 0xff;
3213 bp[pgo + 3] = 1;
3214 if (bp[pgo + MP_OFF_PAGE_LENGTH] < 8)
3215 bp[pgo + MP_OFF_PAGE_LENGTH] = 8;
3216 DEBC(printk(ST_DEB_MSG
3217 "%s: Formatting tape with two partitions (1 = %d MB).\n",
3218 name, size));
3219 }
3220 bp[pgo + PP_OFF_PART_UNITS] = 0;
3221 bp[pgo + PP_OFF_RESERVED] = 0;
3222 bp[pgo + PP_OFF_FLAGS] = PP_BIT_IDP | PP_MSK_PSUM_MB;
3223
3224 result = write_mode_page(STp, PART_PAGE, 1);
3225 if (result) {
3226 printk(KERN_INFO "%s: Partitioning of tape failed.\n", name);
3227 result = (-EIO);
3228 }
3229
3230 return result;
3231}
3232
3233
3234
3235/* The ioctl command */
Kai Makisarafd66c1b2008-01-17 22:45:22 +02003236static long st_ioctl(struct file *file, unsigned int cmd_in, unsigned long arg)
Linus Torvalds1da177e2005-04-16 15:20:36 -07003237{
3238 int i, cmd_nr, cmd_type, bt;
3239 int retval = 0;
3240 unsigned int blk;
3241 struct scsi_tape *STp = file->private_data;
3242 struct st_modedef *STm;
3243 struct st_partstat *STps;
3244 char *name = tape_name(STp);
3245 void __user *p = (void __user *)arg;
3246
Matthias Kaehlcke28f85002007-07-29 23:38:15 +02003247 if (mutex_lock_interruptible(&STp->lock))
Linus Torvalds1da177e2005-04-16 15:20:36 -07003248 return -ERESTARTSYS;
3249
3250 DEB(
3251 if (debugging && !STp->in_use) {
3252 printk(ST_DEB_MSG "%s: Incorrect device.\n", name);
3253 retval = (-EIO);
3254 goto out;
3255 } ) /* end DEB */
3256
3257 STm = &(STp->modes[STp->current_mode]);
3258 STps = &(STp->ps[STp->partition]);
3259
3260 /*
3261 * If we are in the middle of error recovery, don't let anyone
3262 * else try and use this device. Also, if error recovery fails, it
3263 * may try and take the device offline, in which case all further
3264 * access to the device is prohibited.
3265 */
Al Viro83ff6fe2008-03-02 08:15:49 -05003266 retval = scsi_nonblockable_ioctl(STp->device, cmd_in, p,
3267 file->f_flags & O_NDELAY);
Linus Torvalds1da177e2005-04-16 15:20:36 -07003268 if (!scsi_block_when_processing_errors(STp->device) || retval != -ENODEV)
3269 goto out;
3270 retval = 0;
3271
3272 cmd_type = _IOC_TYPE(cmd_in);
3273 cmd_nr = _IOC_NR(cmd_in);
3274
3275 if (cmd_type == _IOC_TYPE(MTIOCTOP) && cmd_nr == _IOC_NR(MTIOCTOP)) {
3276 struct mtop mtc;
3277
3278 if (_IOC_SIZE(cmd_in) != sizeof(mtc)) {
3279 retval = (-EINVAL);
3280 goto out;
3281 }
3282
3283 i = copy_from_user(&mtc, p, sizeof(struct mtop));
3284 if (i) {
3285 retval = (-EFAULT);
3286 goto out;
3287 }
3288
3289 if (mtc.mt_op == MTSETDRVBUFFER && !capable(CAP_SYS_ADMIN)) {
3290 printk(KERN_WARNING
3291 "%s: MTSETDRVBUFFER only allowed for root.\n", name);
3292 retval = (-EPERM);
3293 goto out;
3294 }
3295 if (!STm->defined &&
3296 (mtc.mt_op != MTSETDRVBUFFER &&
3297 (mtc.mt_count & MT_ST_OPTIONS) == 0)) {
3298 retval = (-ENXIO);
3299 goto out;
3300 }
3301
3302 if (!STp->pos_unknown) {
3303
3304 if (STps->eof == ST_FM_HIT) {
3305 if (mtc.mt_op == MTFSF || mtc.mt_op == MTFSFM ||
3306 mtc.mt_op == MTEOM) {
3307 mtc.mt_count -= 1;
3308 if (STps->drv_file >= 0)
3309 STps->drv_file += 1;
3310 } else if (mtc.mt_op == MTBSF || mtc.mt_op == MTBSFM) {
3311 mtc.mt_count += 1;
3312 if (STps->drv_file >= 0)
3313 STps->drv_file += 1;
3314 }
3315 }
3316
3317 if (mtc.mt_op == MTSEEK) {
3318 /* Old position must be restored if partition will be
3319 changed */
3320 i = !STp->can_partitions ||
3321 (STp->new_partition != STp->partition);
3322 } else {
3323 i = mtc.mt_op == MTREW || mtc.mt_op == MTOFFL ||
3324 mtc.mt_op == MTRETEN || mtc.mt_op == MTEOM ||
3325 mtc.mt_op == MTLOCK || mtc.mt_op == MTLOAD ||
3326 mtc.mt_op == MTFSF || mtc.mt_op == MTFSFM ||
3327 mtc.mt_op == MTBSF || mtc.mt_op == MTBSFM ||
3328 mtc.mt_op == MTCOMPRESSION;
3329 }
3330 i = flush_buffer(STp, i);
3331 if (i < 0) {
3332 retval = i;
3333 goto out;
3334 }
3335 if (STps->rw == ST_WRITING &&
3336 (mtc.mt_op == MTREW || mtc.mt_op == MTOFFL ||
3337 mtc.mt_op == MTSEEK ||
3338 mtc.mt_op == MTBSF || mtc.mt_op == MTBSFM)) {
3339 i = st_int_ioctl(STp, MTWEOF, 1);
3340 if (i < 0) {
3341 retval = i;
3342 goto out;
3343 }
3344 if (mtc.mt_op == MTBSF || mtc.mt_op == MTBSFM)
3345 mtc.mt_count++;
3346 STps->rw = ST_IDLE;
3347 }
3348
3349 } else {
3350 /*
3351 * If there was a bus reset, block further access
3352 * to this device. If the user wants to rewind the tape,
3353 * then reset the flag and allow access again.
3354 */
3355 if (mtc.mt_op != MTREW &&
3356 mtc.mt_op != MTOFFL &&
3357 mtc.mt_op != MTRETEN &&
3358 mtc.mt_op != MTERASE &&
3359 mtc.mt_op != MTSEEK &&
3360 mtc.mt_op != MTEOM) {
3361 retval = (-EIO);
3362 goto out;
3363 }
3364 reset_state(STp);
3365 /* remove this when the midlevel properly clears was_reset */
3366 STp->device->was_reset = 0;
3367 }
3368
3369 if (mtc.mt_op != MTNOP && mtc.mt_op != MTSETBLK &&
3370 mtc.mt_op != MTSETDENSITY && mtc.mt_op != MTWSM &&
3371 mtc.mt_op != MTSETDRVBUFFER && mtc.mt_op != MTSETPART)
3372 STps->rw = ST_IDLE; /* Prevent automatic WEOF and fsf */
3373
3374 if (mtc.mt_op == MTOFFL && STp->door_locked != ST_UNLOCKED)
3375 do_door_lock(STp, 0); /* Ignore result! */
3376
3377 if (mtc.mt_op == MTSETDRVBUFFER &&
3378 (mtc.mt_count & MT_ST_OPTIONS) != 0) {
3379 retval = st_set_options(STp, mtc.mt_count);
3380 goto out;
3381 }
3382
3383 if (mtc.mt_op == MTSETPART) {
3384 if (!STp->can_partitions ||
3385 mtc.mt_count < 0 || mtc.mt_count >= ST_NBR_PARTITIONS) {
3386 retval = (-EINVAL);
3387 goto out;
3388 }
3389 if (mtc.mt_count >= STp->nbr_partitions &&
3390 (STp->nbr_partitions = nbr_partitions(STp)) < 0) {
3391 retval = (-EIO);
3392 goto out;
3393 }
3394 if (mtc.mt_count >= STp->nbr_partitions) {
3395 retval = (-EINVAL);
3396 goto out;
3397 }
3398 STp->new_partition = mtc.mt_count;
3399 retval = 0;
3400 goto out;
3401 }
3402
3403 if (mtc.mt_op == MTMKPART) {
3404 if (!STp->can_partitions) {
3405 retval = (-EINVAL);
3406 goto out;
3407 }
3408 if ((i = st_int_ioctl(STp, MTREW, 0)) < 0 ||
3409 (i = partition_tape(STp, mtc.mt_count)) < 0) {
3410 retval = i;
3411 goto out;
3412 }
3413 for (i = 0; i < ST_NBR_PARTITIONS; i++) {
3414 STp->ps[i].rw = ST_IDLE;
3415 STp->ps[i].at_sm = 0;
3416 STp->ps[i].last_block_valid = 0;
3417 }
3418 STp->partition = STp->new_partition = 0;
3419 STp->nbr_partitions = 1; /* Bad guess ?-) */
3420 STps->drv_block = STps->drv_file = 0;
3421 retval = 0;
3422 goto out;
3423 }
3424
3425 if (mtc.mt_op == MTSEEK) {
3426 i = set_location(STp, mtc.mt_count, STp->new_partition, 0);
3427 if (!STp->can_partitions)
3428 STp->ps[0].rw = ST_IDLE;
3429 retval = i;
3430 goto out;
3431 }
3432
3433 if (mtc.mt_op == MTUNLOAD || mtc.mt_op == MTOFFL) {
3434 retval = do_load_unload(STp, file, 0);
3435 goto out;
3436 }
3437
3438 if (mtc.mt_op == MTLOAD) {
3439 retval = do_load_unload(STp, file, max(1, mtc.mt_count));
3440 goto out;
3441 }
3442
3443 if (mtc.mt_op == MTLOCK || mtc.mt_op == MTUNLOCK) {
3444 retval = do_door_lock(STp, (mtc.mt_op == MTLOCK));
3445 goto out;
3446 }
3447
3448 if (STp->can_partitions && STp->ready == ST_READY &&
3449 (i = switch_partition(STp)) < 0) {
3450 retval = i;
3451 goto out;
3452 }
3453
3454 if (mtc.mt_op == MTCOMPRESSION)
3455 retval = st_compression(STp, (mtc.mt_count & 1));
3456 else
3457 retval = st_int_ioctl(STp, mtc.mt_op, mtc.mt_count);
3458 goto out;
3459 }
3460 if (!STm->defined) {
3461 retval = (-ENXIO);
3462 goto out;
3463 }
3464
3465 if ((i = flush_buffer(STp, 0)) < 0) {
3466 retval = i;
3467 goto out;
3468 }
3469 if (STp->can_partitions &&
3470 (i = switch_partition(STp)) < 0) {
3471 retval = i;
3472 goto out;
3473 }
3474
3475 if (cmd_type == _IOC_TYPE(MTIOCGET) && cmd_nr == _IOC_NR(MTIOCGET)) {
3476 struct mtget mt_status;
3477
3478 if (_IOC_SIZE(cmd_in) != sizeof(struct mtget)) {
3479 retval = (-EINVAL);
3480 goto out;
3481 }
3482
3483 mt_status.mt_type = STp->tape_type;
3484 mt_status.mt_dsreg =
3485 ((STp->block_size << MT_ST_BLKSIZE_SHIFT) & MT_ST_BLKSIZE_MASK) |
3486 ((STp->density << MT_ST_DENSITY_SHIFT) & MT_ST_DENSITY_MASK);
3487 mt_status.mt_blkno = STps->drv_block;
3488 mt_status.mt_fileno = STps->drv_file;
3489 if (STp->block_size != 0) {
3490 if (STps->rw == ST_WRITING)
3491 mt_status.mt_blkno +=
3492 (STp->buffer)->buffer_bytes / STp->block_size;
3493 else if (STps->rw == ST_READING)
3494 mt_status.mt_blkno -=
3495 ((STp->buffer)->buffer_bytes +
3496 STp->block_size - 1) / STp->block_size;
3497 }
3498
3499 mt_status.mt_gstat = 0;
3500 if (STp->drv_write_prot)
3501 mt_status.mt_gstat |= GMT_WR_PROT(0xffffffff);
3502 if (mt_status.mt_blkno == 0) {
3503 if (mt_status.mt_fileno == 0)
3504 mt_status.mt_gstat |= GMT_BOT(0xffffffff);
3505 else
3506 mt_status.mt_gstat |= GMT_EOF(0xffffffff);
3507 }
3508 mt_status.mt_erreg = (STp->recover_reg << MT_ST_SOFTERR_SHIFT);
3509 mt_status.mt_resid = STp->partition;
3510 if (STps->eof == ST_EOM_OK || STps->eof == ST_EOM_ERROR)
3511 mt_status.mt_gstat |= GMT_EOT(0xffffffff);
3512 else if (STps->eof >= ST_EOM_OK)
3513 mt_status.mt_gstat |= GMT_EOD(0xffffffff);
3514 if (STp->density == 1)
3515 mt_status.mt_gstat |= GMT_D_800(0xffffffff);
3516 else if (STp->density == 2)
3517 mt_status.mt_gstat |= GMT_D_1600(0xffffffff);
3518 else if (STp->density == 3)
3519 mt_status.mt_gstat |= GMT_D_6250(0xffffffff);
3520 if (STp->ready == ST_READY)
3521 mt_status.mt_gstat |= GMT_ONLINE(0xffffffff);
3522 if (STp->ready == ST_NO_TAPE)
3523 mt_status.mt_gstat |= GMT_DR_OPEN(0xffffffff);
3524 if (STps->at_sm)
3525 mt_status.mt_gstat |= GMT_SM(0xffffffff);
3526 if (STm->do_async_writes ||
3527 (STm->do_buffer_writes && STp->block_size != 0) ||
3528 STp->drv_buffer != 0)
3529 mt_status.mt_gstat |= GMT_IM_REP_EN(0xffffffff);
3530 if (STp->cleaning_req)
3531 mt_status.mt_gstat |= GMT_CLN(0xffffffff);
3532
3533 i = copy_to_user(p, &mt_status, sizeof(struct mtget));
3534 if (i) {
3535 retval = (-EFAULT);
3536 goto out;
3537 }
3538
3539 STp->recover_reg = 0; /* Clear after read */
3540 retval = 0;
3541 goto out;
3542 } /* End of MTIOCGET */
3543 if (cmd_type == _IOC_TYPE(MTIOCPOS) && cmd_nr == _IOC_NR(MTIOCPOS)) {
3544 struct mtpos mt_pos;
3545 if (_IOC_SIZE(cmd_in) != sizeof(struct mtpos)) {
3546 retval = (-EINVAL);
3547 goto out;
3548 }
3549 if ((i = get_location(STp, &blk, &bt, 0)) < 0) {
3550 retval = i;
3551 goto out;
3552 }
3553 mt_pos.mt_blkno = blk;
3554 i = copy_to_user(p, &mt_pos, sizeof(struct mtpos));
3555 if (i)
3556 retval = (-EFAULT);
3557 goto out;
3558 }
Matthias Kaehlcke28f85002007-07-29 23:38:15 +02003559 mutex_unlock(&STp->lock);
Linus Torvalds1da177e2005-04-16 15:20:36 -07003560 switch (cmd_in) {
3561 case SCSI_IOCTL_GET_IDLUN:
3562 case SCSI_IOCTL_GET_BUS_NUMBER:
3563 break;
3564 default:
Kai Makisara 16c4b3e2005-05-01 18:11:55 +03003565 if ((cmd_in == SG_IO ||
3566 cmd_in == SCSI_IOCTL_SEND_COMMAND ||
3567 cmd_in == CDROM_SEND_PACKET) &&
3568 !capable(CAP_SYS_RAWIO))
Linus Torvalds1da177e2005-04-16 15:20:36 -07003569 i = -EPERM;
3570 else
Al Viro74f3c8a2007-08-27 15:38:10 -04003571 i = scsi_cmd_ioctl(STp->disk->queue, STp->disk,
3572 file->f_mode, cmd_in, p);
Linus Torvalds1da177e2005-04-16 15:20:36 -07003573 if (i != -ENOTTY)
3574 return i;
3575 break;
3576 }
Kai Makisara 16c4b3e2005-05-01 18:11:55 +03003577 retval = scsi_ioctl(STp->device, cmd_in, p);
3578 if (!retval && cmd_in == SCSI_IOCTL_STOP_UNIT) { /* unload */
3579 STp->rew_at_close = 0;
3580 STp->ready = ST_NO_TAPE;
3581 }
3582 return retval;
Linus Torvalds1da177e2005-04-16 15:20:36 -07003583
3584 out:
Matthias Kaehlcke28f85002007-07-29 23:38:15 +02003585 mutex_unlock(&STp->lock);
Linus Torvalds1da177e2005-04-16 15:20:36 -07003586 return retval;
3587}
3588
3589#ifdef CONFIG_COMPAT
3590static long st_compat_ioctl(struct file *file, unsigned int cmd, unsigned long arg)
3591{
3592 struct scsi_tape *STp = file->private_data;
3593 struct scsi_device *sdev = STp->device;
3594 int ret = -ENOIOCTLCMD;
3595 if (sdev->host->hostt->compat_ioctl) {
3596
3597 ret = sdev->host->hostt->compat_ioctl(sdev, cmd, (void __user *)arg);
3598
3599 }
3600 return ret;
3601}
3602#endif
3603
3604
3605
3606/* Try to allocate a new tape buffer. Calling function must not hold
3607 dev_arr_lock. */
3608static struct st_buffer *
3609 new_tape_buffer(int from_initialization, int need_dma, int max_sg)
3610{
Mike Christie8b05b772005-11-08 04:06:44 -06003611 int i, got = 0;
Al Viroc53033f2005-10-21 03:22:08 -04003612 gfp_t priority;
Linus Torvalds1da177e2005-04-16 15:20:36 -07003613 struct st_buffer *tb;
3614
3615 if (from_initialization)
3616 priority = GFP_ATOMIC;
3617 else
3618 priority = GFP_KERNEL;
3619
3620 i = sizeof(struct st_buffer) + (max_sg - 1) * sizeof(struct scatterlist) +
3621 max_sg * sizeof(struct st_buf_fragment);
Jes Sorensen24669f752006-01-16 10:31:18 -05003622 tb = kzalloc(i, priority);
Linus Torvalds1da177e2005-04-16 15:20:36 -07003623 if (!tb) {
3624 printk(KERN_NOTICE "st: Can't allocate new tape buffer.\n");
3625 return NULL;
3626 }
Mike Christie8b05b772005-11-08 04:06:44 -06003627 tb->frp_segs = tb->orig_frp_segs = 0;
Linus Torvalds1da177e2005-04-16 15:20:36 -07003628 tb->use_sg = max_sg;
Linus Torvalds1da177e2005-04-16 15:20:36 -07003629 tb->frp = (struct st_buf_fragment *)(&(tb->sg[0]) + max_sg);
3630
Linus Torvalds1da177e2005-04-16 15:20:36 -07003631 tb->dma = need_dma;
3632 tb->buffer_size = got;
FUJITA Tomonoricd816212007-12-15 15:51:55 +09003633 sg_init_table(tb->sg, max_sg);
Linus Torvalds1da177e2005-04-16 15:20:36 -07003634
3635 return tb;
3636}
3637
3638
3639/* Try to allocate enough space in the tape buffer */
3640static int enlarge_buffer(struct st_buffer * STbuffer, int new_size, int need_dma)
3641{
Al Viroc53033f2005-10-21 03:22:08 -04003642 int segs, nbr, max_segs, b_size, order, got;
3643 gfp_t priority;
Linus Torvalds1da177e2005-04-16 15:20:36 -07003644
3645 if (new_size <= STbuffer->buffer_size)
3646 return 1;
3647
3648 if (STbuffer->buffer_size <= PAGE_SIZE)
3649 normalize_buffer(STbuffer); /* Avoid extra segment */
3650
3651 max_segs = STbuffer->use_sg;
3652 nbr = max_segs - STbuffer->frp_segs;
3653 if (nbr <= 0)
3654 return 0;
3655
3656 priority = GFP_KERNEL | __GFP_NOWARN;
3657 if (need_dma)
3658 priority |= GFP_DMA;
Mike Christie8b05b772005-11-08 04:06:44 -06003659 for (b_size = PAGE_SIZE, order=0; order <= 6 &&
Linus Torvalds1da177e2005-04-16 15:20:36 -07003660 b_size < new_size - STbuffer->buffer_size;
3661 order++, b_size *= 2)
3662 ; /* empty */
3663
3664 for (segs = STbuffer->frp_segs, got = STbuffer->buffer_size;
3665 segs < max_segs && got < new_size;) {
3666 STbuffer->frp[segs].page = alloc_pages(priority, order);
3667 if (STbuffer->frp[segs].page == NULL) {
3668 if (new_size - got <= (max_segs - segs) * b_size / 2) {
3669 b_size /= 2; /* Large enough for the rest of the buffers */
3670 order--;
3671 continue;
3672 }
3673 DEB(STbuffer->buffer_size = got);
3674 normalize_buffer(STbuffer);
3675 return 0;
3676 }
3677 STbuffer->frp[segs].length = b_size;
3678 STbuffer->frp_segs += 1;
3679 got += b_size;
3680 STbuffer->buffer_size = got;
Kai Makisara40f6b362008-02-24 22:23:24 +02003681 if (STbuffer->cleared)
3682 memset(page_address(STbuffer->frp[segs].page), 0, b_size);
Linus Torvalds1da177e2005-04-16 15:20:36 -07003683 segs++;
3684 }
3685 STbuffer->b_data = page_address(STbuffer->frp[0].page);
3686
3687 return 1;
3688}
3689
3690
Kai Makisara40f6b362008-02-24 22:23:24 +02003691/* Make sure that no data from previous user is in the internal buffer */
3692static void clear_buffer(struct st_buffer * st_bp)
3693{
3694 int i;
3695
3696 for (i=0; i < st_bp->frp_segs; i++)
3697 memset(page_address(st_bp->frp[i].page), 0, st_bp->frp[i].length);
3698 st_bp->cleared = 1;
3699}
3700
3701
Linus Torvalds1da177e2005-04-16 15:20:36 -07003702/* Release the extra buffer */
3703static void normalize_buffer(struct st_buffer * STbuffer)
3704{
3705 int i, order;
3706
3707 for (i = STbuffer->orig_frp_segs; i < STbuffer->frp_segs; i++) {
3708 order = get_order(STbuffer->frp[i].length);
3709 __free_pages(STbuffer->frp[i].page, order);
3710 STbuffer->buffer_size -= STbuffer->frp[i].length;
3711 }
3712 STbuffer->frp_segs = STbuffer->orig_frp_segs;
3713 STbuffer->frp_sg_current = 0;
Mike Christie8b05b772005-11-08 04:06:44 -06003714 STbuffer->sg_segs = 0;
Linus Torvalds1da177e2005-04-16 15:20:36 -07003715}
3716
3717
3718/* Move data from the user buffer to the tape buffer. Returns zero (success) or
3719 negative error code. */
3720static int append_to_buffer(const char __user *ubp, struct st_buffer * st_bp, int do_count)
3721{
3722 int i, cnt, res, offset;
3723
3724 for (i = 0, offset = st_bp->buffer_bytes;
3725 i < st_bp->frp_segs && offset >= st_bp->frp[i].length; i++)
3726 offset -= st_bp->frp[i].length;
3727 if (i == st_bp->frp_segs) { /* Should never happen */
3728 printk(KERN_WARNING "st: append_to_buffer offset overflow.\n");
3729 return (-EIO);
3730 }
3731 for (; i < st_bp->frp_segs && do_count > 0; i++) {
3732 cnt = st_bp->frp[i].length - offset < do_count ?
3733 st_bp->frp[i].length - offset : do_count;
3734 res = copy_from_user(page_address(st_bp->frp[i].page) + offset, ubp, cnt);
3735 if (res)
3736 return (-EFAULT);
3737 do_count -= cnt;
3738 st_bp->buffer_bytes += cnt;
3739 ubp += cnt;
3740 offset = 0;
3741 }
3742 if (do_count) /* Should never happen */
3743 return (-EIO);
3744
3745 return 0;
3746}
3747
3748
3749/* Move data from the tape buffer to the user buffer. Returns zero (success) or
3750 negative error code. */
3751static int from_buffer(struct st_buffer * st_bp, char __user *ubp, int do_count)
3752{
3753 int i, cnt, res, offset;
3754
3755 for (i = 0, offset = st_bp->read_pointer;
3756 i < st_bp->frp_segs && offset >= st_bp->frp[i].length; i++)
3757 offset -= st_bp->frp[i].length;
3758 if (i == st_bp->frp_segs) { /* Should never happen */
3759 printk(KERN_WARNING "st: from_buffer offset overflow.\n");
3760 return (-EIO);
3761 }
3762 for (; i < st_bp->frp_segs && do_count > 0; i++) {
3763 cnt = st_bp->frp[i].length - offset < do_count ?
3764 st_bp->frp[i].length - offset : do_count;
3765 res = copy_to_user(ubp, page_address(st_bp->frp[i].page) + offset, cnt);
3766 if (res)
3767 return (-EFAULT);
3768 do_count -= cnt;
3769 st_bp->buffer_bytes -= cnt;
3770 st_bp->read_pointer += cnt;
3771 ubp += cnt;
3772 offset = 0;
3773 }
3774 if (do_count) /* Should never happen */
3775 return (-EIO);
3776
3777 return 0;
3778}
3779
3780
3781/* Move data towards start of buffer */
3782static void move_buffer_data(struct st_buffer * st_bp, int offset)
3783{
3784 int src_seg, dst_seg, src_offset = 0, dst_offset;
3785 int count, total;
3786
3787 if (offset == 0)
3788 return;
3789
3790 total=st_bp->buffer_bytes - offset;
3791 for (src_seg=0; src_seg < st_bp->frp_segs; src_seg++) {
3792 src_offset = offset;
3793 if (src_offset < st_bp->frp[src_seg].length)
3794 break;
3795 offset -= st_bp->frp[src_seg].length;
3796 }
3797
3798 st_bp->buffer_bytes = st_bp->read_pointer = total;
3799 for (dst_seg=dst_offset=0; total > 0; ) {
3800 count = min(st_bp->frp[dst_seg].length - dst_offset,
3801 st_bp->frp[src_seg].length - src_offset);
3802 memmove(page_address(st_bp->frp[dst_seg].page) + dst_offset,
3803 page_address(st_bp->frp[src_seg].page) + src_offset, count);
3804 src_offset += count;
3805 if (src_offset >= st_bp->frp[src_seg].length) {
3806 src_seg++;
3807 src_offset = 0;
3808 }
3809 dst_offset += count;
3810 if (dst_offset >= st_bp->frp[dst_seg].length) {
3811 dst_seg++;
3812 dst_offset = 0;
3813 }
3814 total -= count;
3815 }
3816}
3817
3818
3819/* Fill the s/g list up to the length required for this transfer */
3820static void buf_to_sg(struct st_buffer *STbp, unsigned int length)
3821{
3822 int i;
3823 unsigned int count;
3824 struct scatterlist *sg;
3825 struct st_buf_fragment *frp;
3826
3827 if (length == STbp->frp_sg_current)
3828 return; /* work already done */
3829
3830 sg = &(STbp->sg[0]);
3831 frp = STbp->frp;
3832 for (i=count=0; count < length; i++) {
Linus Torvalds1da177e2005-04-16 15:20:36 -07003833 if (length - count > frp[i].length)
Jens Axboe642f1492007-10-24 11:20:47 +02003834 sg_set_page(&sg[i], frp[i].page, frp[i].length, 0);
Linus Torvalds1da177e2005-04-16 15:20:36 -07003835 else
Jens Axboe642f1492007-10-24 11:20:47 +02003836 sg_set_page(&sg[i], frp[i].page, length - count, 0);
Linus Torvalds1da177e2005-04-16 15:20:36 -07003837 count += sg[i].length;
Linus Torvalds1da177e2005-04-16 15:20:36 -07003838 }
3839 STbp->sg_segs = i;
3840 STbp->frp_sg_current = length;
3841}
3842
3843
3844/* Validate the options from command line or module parameters */
3845static void validate_options(void)
3846{
3847 if (buffer_kbs > 0)
3848 st_fixed_buffer_size = buffer_kbs * ST_KILOBYTE;
3849 if (max_sg_segs >= ST_FIRST_SG)
3850 st_max_sg_segs = max_sg_segs;
3851}
3852
3853#ifndef MODULE
3854/* Set the boot options. Syntax is defined in Documenation/scsi/st.txt.
3855 */
3856static int __init st_setup(char *str)
3857{
3858 int i, len, ints[5];
3859 char *stp;
3860
3861 stp = get_options(str, ARRAY_SIZE(ints), ints);
3862
3863 if (ints[0] > 0) {
3864 for (i = 0; i < ints[0] && i < ARRAY_SIZE(parms); i++)
3865 if (parms[i].val)
3866 *parms[i].val = ints[i + 1];
3867 } else {
3868 while (stp != NULL) {
3869 for (i = 0; i < ARRAY_SIZE(parms); i++) {
3870 len = strlen(parms[i].name);
3871 if (!strncmp(stp, parms[i].name, len) &&
3872 (*(stp + len) == ':' || *(stp + len) == '=')) {
3873 if (parms[i].val)
3874 *parms[i].val =
3875 simple_strtoul(stp + len + 1, NULL, 0);
3876 else
3877 printk(KERN_WARNING "st: Obsolete parameter %s\n",
3878 parms[i].name);
3879 break;
3880 }
3881 }
Tobias Klauser6391a112006-06-08 22:23:48 -07003882 if (i >= ARRAY_SIZE(parms))
Linus Torvalds1da177e2005-04-16 15:20:36 -07003883 printk(KERN_WARNING "st: invalid parameter in '%s'\n",
3884 stp);
3885 stp = strchr(stp, ',');
3886 if (stp)
3887 stp++;
3888 }
3889 }
3890
3891 validate_options();
3892
3893 return 1;
3894}
3895
3896__setup("st=", st_setup);
3897
3898#endif
3899
Arjan van de Ven00977a52007-02-12 00:55:34 -08003900static const struct file_operations st_fops =
Linus Torvalds1da177e2005-04-16 15:20:36 -07003901{
3902 .owner = THIS_MODULE,
3903 .read = st_read,
3904 .write = st_write,
Kai Makisarafd66c1b2008-01-17 22:45:22 +02003905 .unlocked_ioctl = st_ioctl,
Linus Torvalds1da177e2005-04-16 15:20:36 -07003906#ifdef CONFIG_COMPAT
3907 .compat_ioctl = st_compat_ioctl,
3908#endif
3909 .open = st_open,
3910 .flush = st_flush,
3911 .release = st_release,
3912};
3913
3914static int st_probe(struct device *dev)
3915{
3916 struct scsi_device *SDp = to_scsi_device(dev);
3917 struct gendisk *disk = NULL;
3918 struct cdev *cdev = NULL;
3919 struct scsi_tape *tpnt = NULL;
3920 struct st_modedef *STm;
3921 struct st_partstat *STps;
3922 struct st_buffer *buffer;
3923 int i, j, mode, dev_num, error;
3924 char *stp;
Linus Torvalds1da177e2005-04-16 15:20:36 -07003925
3926 if (SDp->type != TYPE_TAPE)
3927 return -ENODEV;
3928 if ((stp = st_incompatible(SDp))) {
Jeff Garzik3bf743e2005-10-24 18:04:06 -04003929 sdev_printk(KERN_INFO, SDp, "Found incompatible tape\n");
Linus Torvalds1da177e2005-04-16 15:20:36 -07003930 printk(KERN_INFO "st: The suggested driver is %s.\n", stp);
3931 return -ENODEV;
3932 }
3933
Mike Christie8b05b772005-11-08 04:06:44 -06003934 i = min(SDp->request_queue->max_hw_segments,
3935 SDp->request_queue->max_phys_segments);
Linus Torvalds1da177e2005-04-16 15:20:36 -07003936 if (st_max_sg_segs < i)
3937 i = st_max_sg_segs;
3938 buffer = new_tape_buffer(1, (SDp->host)->unchecked_isa_dma, i);
3939 if (buffer == NULL) {
3940 printk(KERN_ERR
3941 "st: Can't allocate new tape buffer. Device not attached.\n");
3942 goto out;
3943 }
3944
3945 disk = alloc_disk(1);
3946 if (!disk) {
3947 printk(KERN_ERR "st: out of memory. Device not attached.\n");
3948 goto out_buffer_free;
3949 }
3950
3951 write_lock(&st_dev_arr_lock);
3952 if (st_nr_dev >= st_dev_max) {
3953 struct scsi_tape **tmp_da;
3954 int tmp_dev_max;
3955
3956 tmp_dev_max = max(st_nr_dev * 2, 8);
3957 if (tmp_dev_max > ST_MAX_TAPES)
3958 tmp_dev_max = ST_MAX_TAPES;
3959 if (tmp_dev_max <= st_nr_dev) {
3960 write_unlock(&st_dev_arr_lock);
3961 printk(KERN_ERR "st: Too many tape devices (max. %d).\n",
3962 ST_MAX_TAPES);
3963 goto out_put_disk;
3964 }
3965
Jes Sorensen24669f752006-01-16 10:31:18 -05003966 tmp_da = kzalloc(tmp_dev_max * sizeof(struct scsi_tape *), GFP_ATOMIC);
Linus Torvalds1da177e2005-04-16 15:20:36 -07003967 if (tmp_da == NULL) {
3968 write_unlock(&st_dev_arr_lock);
3969 printk(KERN_ERR "st: Can't extend device array.\n");
3970 goto out_put_disk;
3971 }
3972
Linus Torvalds1da177e2005-04-16 15:20:36 -07003973 if (scsi_tapes != NULL) {
3974 memcpy(tmp_da, scsi_tapes,
3975 st_dev_max * sizeof(struct scsi_tape *));
3976 kfree(scsi_tapes);
3977 }
3978 scsi_tapes = tmp_da;
3979
3980 st_dev_max = tmp_dev_max;
3981 }
3982
3983 for (i = 0; i < st_dev_max; i++)
3984 if (scsi_tapes[i] == NULL)
3985 break;
3986 if (i >= st_dev_max)
3987 panic("scsi_devices corrupt (st)");
3988
Jes Sorensen24669f752006-01-16 10:31:18 -05003989 tpnt = kzalloc(sizeof(struct scsi_tape), GFP_ATOMIC);
Linus Torvalds1da177e2005-04-16 15:20:36 -07003990 if (tpnt == NULL) {
3991 write_unlock(&st_dev_arr_lock);
3992 printk(KERN_ERR "st: Can't allocate device descriptor.\n");
3993 goto out_put_disk;
3994 }
Kai Makisaraf03a5672005-08-02 13:40:47 +03003995 kref_init(&tpnt->kref);
Linus Torvalds1da177e2005-04-16 15:20:36 -07003996 tpnt->disk = disk;
3997 sprintf(disk->disk_name, "st%d", i);
3998 disk->private_data = &tpnt->driver;
3999 disk->queue = SDp->request_queue;
4000 tpnt->driver = &st_template;
4001 scsi_tapes[i] = tpnt;
4002 dev_num = i;
4003
4004 tpnt->device = SDp;
4005 if (SDp->scsi_level <= 2)
4006 tpnt->tape_type = MT_ISSCSI1;
4007 else
4008 tpnt->tape_type = MT_ISSCSI2;
4009
4010 tpnt->buffer = buffer;
Kai Makisaraf03a5672005-08-02 13:40:47 +03004011 tpnt->buffer->last_SRpnt = NULL;
Linus Torvalds1da177e2005-04-16 15:20:36 -07004012
4013 tpnt->inited = 0;
4014 tpnt->dirty = 0;
4015 tpnt->in_use = 0;
4016 tpnt->drv_buffer = 1; /* Try buffering if no mode sense */
4017 tpnt->restr_dma = (SDp->host)->unchecked_isa_dma;
4018 tpnt->use_pf = (SDp->scsi_level >= SCSI_2);
4019 tpnt->density = 0;
4020 tpnt->do_auto_lock = ST_AUTO_LOCK;
4021 tpnt->can_bsr = (SDp->scsi_level > 2 ? 1 : ST_IN_FILE_POS); /* BSR mandatory in SCSI3 */
4022 tpnt->can_partitions = 0;
4023 tpnt->two_fm = ST_TWO_FM;
4024 tpnt->fast_mteom = ST_FAST_MTEOM;
4025 tpnt->scsi2_logical = ST_SCSI2LOGICAL;
Kai Makisara40f6b362008-02-24 22:23:24 +02004026 tpnt->sili = ST_SILI;
Linus Torvalds1da177e2005-04-16 15:20:36 -07004027 tpnt->immediate = ST_NOWAIT;
4028 tpnt->default_drvbuffer = 0xff; /* No forced buffering */
4029 tpnt->partition = 0;
4030 tpnt->new_partition = 0;
4031 tpnt->nbr_partitions = 0;
4032 tpnt->device->timeout = ST_TIMEOUT;
4033 tpnt->long_timeout = ST_LONG_TIMEOUT;
4034 tpnt->try_dio = try_direct_io && !SDp->host->unchecked_isa_dma;
4035
Linus Torvalds1da177e2005-04-16 15:20:36 -07004036 for (i = 0; i < ST_NBR_MODES; i++) {
4037 STm = &(tpnt->modes[i]);
4038 STm->defined = 0;
4039 STm->sysv = ST_SYSV;
4040 STm->defaults_for_writes = 0;
4041 STm->do_async_writes = ST_ASYNC_WRITES;
4042 STm->do_buffer_writes = ST_BUFFER_WRITES;
4043 STm->do_read_ahead = ST_READ_AHEAD;
4044 STm->default_compression = ST_DONT_TOUCH;
4045 STm->default_blksize = (-1); /* No forced size */
4046 STm->default_density = (-1); /* No forced density */
4047 }
4048
4049 for (i = 0; i < ST_NBR_PARTITIONS; i++) {
4050 STps = &(tpnt->ps[i]);
4051 STps->rw = ST_IDLE;
4052 STps->eof = ST_NOEOF;
4053 STps->at_sm = 0;
4054 STps->last_block_valid = 0;
4055 STps->drv_block = (-1);
4056 STps->drv_file = (-1);
4057 }
4058
4059 tpnt->current_mode = 0;
4060 tpnt->modes[0].defined = 1;
4061
4062 tpnt->density_changed = tpnt->compression_changed =
4063 tpnt->blksize_changed = 0;
Matthias Kaehlcke28f85002007-07-29 23:38:15 +02004064 mutex_init(&tpnt->lock);
Linus Torvalds1da177e2005-04-16 15:20:36 -07004065
4066 st_nr_dev++;
4067 write_unlock(&st_dev_arr_lock);
4068
4069 for (mode = 0; mode < ST_NBR_MODES; ++mode) {
4070 STm = &(tpnt->modes[mode]);
4071 for (j=0; j < 2; j++) {
4072 cdev = cdev_alloc();
4073 if (!cdev) {
4074 printk(KERN_ERR
4075 "st%d: out of memory. Device not attached.\n",
4076 dev_num);
4077 goto out_free_tape;
4078 }
4079 cdev->owner = THIS_MODULE;
4080 cdev->ops = &st_fops;
4081
4082 error = cdev_add(cdev,
4083 MKDEV(SCSI_TAPE_MAJOR, TAPE_MINOR(dev_num, mode, j)),
4084 1);
4085 if (error) {
4086 printk(KERN_ERR "st%d: Can't add %s-rewind mode %d\n",
4087 dev_num, j ? "non" : "auto", mode);
4088 printk(KERN_ERR "st%d: Device not attached.\n", dev_num);
4089 goto out_free_tape;
4090 }
4091 STm->cdevs[j] = cdev;
4092
4093 }
Jeff Garzik13026a62006-10-04 06:00:38 -04004094 error = do_create_class_files(tpnt, dev_num, mode);
4095 if (error)
4096 goto out_free_tape;
Linus Torvalds1da177e2005-04-16 15:20:36 -07004097 }
4098
Kai Makisara42252852006-11-07 21:56:38 +02004099 sdev_printk(KERN_NOTICE, SDp,
Rene Herman8b1ea242006-05-20 15:00:22 -07004100 "Attached scsi tape %s\n", tape_name(tpnt));
Kai Makisara42252852006-11-07 21:56:38 +02004101 sdev_printk(KERN_INFO, SDp, "%s: try direct i/o: %s (alignment %d B)\n",
4102 tape_name(tpnt), tpnt->try_dio ? "yes" : "no",
4103 queue_dma_alignment(SDp->request_queue) + 1);
Linus Torvalds1da177e2005-04-16 15:20:36 -07004104
4105 return 0;
4106
4107out_free_tape:
4108 for (mode=0; mode < ST_NBR_MODES; mode++) {
4109 STm = &(tpnt->modes[mode]);
4110 sysfs_remove_link(&tpnt->device->sdev_gendev.kobj,
4111 "tape");
4112 for (j=0; j < 2; j++) {
4113 if (STm->cdevs[j]) {
4114 if (cdev == STm->cdevs[j])
4115 cdev = NULL;
Tony Jonesee959b02008-02-22 00:13:36 +01004116 device_destroy(st_sysfs_class,
4117 MKDEV(SCSI_TAPE_MAJOR,
4118 TAPE_MINOR(i, mode, j)));
Linus Torvalds1da177e2005-04-16 15:20:36 -07004119 cdev_del(STm->cdevs[j]);
4120 }
4121 }
4122 }
4123 if (cdev)
4124 cdev_del(cdev);
4125 write_lock(&st_dev_arr_lock);
4126 scsi_tapes[dev_num] = NULL;
4127 st_nr_dev--;
4128 write_unlock(&st_dev_arr_lock);
4129out_put_disk:
4130 put_disk(disk);
Jesper Juhlc9475cb2005-11-07 01:01:26 -08004131 kfree(tpnt);
Linus Torvalds1da177e2005-04-16 15:20:36 -07004132out_buffer_free:
4133 kfree(buffer);
4134out:
4135 return -ENODEV;
4136};
4137
4138
4139static int st_remove(struct device *dev)
4140{
4141 struct scsi_device *SDp = to_scsi_device(dev);
4142 struct scsi_tape *tpnt;
4143 int i, j, mode;
4144
4145 write_lock(&st_dev_arr_lock);
4146 for (i = 0; i < st_dev_max; i++) {
4147 tpnt = scsi_tapes[i];
4148 if (tpnt != NULL && tpnt->device == SDp) {
4149 scsi_tapes[i] = NULL;
4150 st_nr_dev--;
4151 write_unlock(&st_dev_arr_lock);
Linus Torvalds1da177e2005-04-16 15:20:36 -07004152 sysfs_remove_link(&tpnt->device->sdev_gendev.kobj,
4153 "tape");
4154 for (mode = 0; mode < ST_NBR_MODES; ++mode) {
Linus Torvalds1da177e2005-04-16 15:20:36 -07004155 for (j=0; j < 2; j++) {
Tony Jonesee959b02008-02-22 00:13:36 +01004156 device_destroy(st_sysfs_class,
4157 MKDEV(SCSI_TAPE_MAJOR,
4158 TAPE_MINOR(i, mode, j)));
Linus Torvalds1da177e2005-04-16 15:20:36 -07004159 cdev_del(tpnt->modes[mode].cdevs[j]);
4160 tpnt->modes[mode].cdevs[j] = NULL;
4161 }
4162 }
Linus Torvalds1da177e2005-04-16 15:20:36 -07004163
Arjan van de Ven0b950672006-01-11 13:16:10 +01004164 mutex_lock(&st_ref_mutex);
Kai Makisaraf03a5672005-08-02 13:40:47 +03004165 kref_put(&tpnt->kref, scsi_tape_release);
Arjan van de Ven0b950672006-01-11 13:16:10 +01004166 mutex_unlock(&st_ref_mutex);
Linus Torvalds1da177e2005-04-16 15:20:36 -07004167 return 0;
4168 }
4169 }
4170
4171 write_unlock(&st_dev_arr_lock);
4172 return 0;
4173}
4174
Kai Makisaraf03a5672005-08-02 13:40:47 +03004175/**
4176 * scsi_tape_release - Called to free the Scsi_Tape structure
4177 * @kref: pointer to embedded kref
4178 *
Arjan van de Ven0b950672006-01-11 13:16:10 +01004179 * st_ref_mutex must be held entering this routine. Because it is
Kai Makisaraf03a5672005-08-02 13:40:47 +03004180 * called on last put, you should always use the scsi_tape_get()
4181 * scsi_tape_put() helpers which manipulate the semaphore directly
4182 * and never do a direct kref_put().
4183 **/
4184static void scsi_tape_release(struct kref *kref)
4185{
4186 struct scsi_tape *tpnt = to_scsi_tape(kref);
4187 struct gendisk *disk = tpnt->disk;
4188
4189 tpnt->device = NULL;
4190
4191 if (tpnt->buffer) {
4192 tpnt->buffer->orig_frp_segs = 0;
4193 normalize_buffer(tpnt->buffer);
4194 kfree(tpnt->buffer);
4195 }
4196
4197 disk->private_data = NULL;
4198 put_disk(disk);
4199 kfree(tpnt);
4200 return;
4201}
4202
Linus Torvalds1da177e2005-04-16 15:20:36 -07004203static int __init init_st(void)
4204{
Jeff Garzik13026a62006-10-04 06:00:38 -04004205 int err;
4206
Linus Torvalds1da177e2005-04-16 15:20:36 -07004207 validate_options();
4208
Jeff Garzik13026a62006-10-04 06:00:38 -04004209 printk(KERN_INFO "st: Version %s, fixed bufsize %d, s/g segs %d\n",
Linus Torvalds1da177e2005-04-16 15:20:36 -07004210 verstr, st_fixed_buffer_size, st_max_sg_segs);
4211
gregkh@suse.ded2538782005-03-23 09:55:22 -08004212 st_sysfs_class = class_create(THIS_MODULE, "scsi_tape");
Linus Torvalds1da177e2005-04-16 15:20:36 -07004213 if (IS_ERR(st_sysfs_class)) {
Linus Torvalds1da177e2005-04-16 15:20:36 -07004214 printk(KERN_ERR "Unable create sysfs class for SCSI tapes\n");
Jeff Garzik13026a62006-10-04 06:00:38 -04004215 return PTR_ERR(st_sysfs_class);
Linus Torvalds1da177e2005-04-16 15:20:36 -07004216 }
4217
Jeff Garzik13026a62006-10-04 06:00:38 -04004218 err = register_chrdev_region(MKDEV(SCSI_TAPE_MAJOR, 0),
4219 ST_MAX_TAPE_ENTRIES, "st");
4220 if (err) {
4221 printk(KERN_ERR "Unable to get major %d for SCSI tapes\n",
4222 SCSI_TAPE_MAJOR);
4223 goto err_class;
Linus Torvalds1da177e2005-04-16 15:20:36 -07004224 }
Jeff Garzik13026a62006-10-04 06:00:38 -04004225
4226 err = scsi_register_driver(&st_template.gendrv);
4227 if (err)
4228 goto err_chrdev;
4229
Robert P. J. Day405ae7d2007-02-17 19:13:42 +01004230 err = do_create_sysfs_files();
Jeff Garzik13026a62006-10-04 06:00:38 -04004231 if (err)
4232 goto err_scsidrv;
4233
4234 return 0;
4235
4236err_scsidrv:
4237 scsi_unregister_driver(&st_template.gendrv);
4238err_chrdev:
4239 unregister_chrdev_region(MKDEV(SCSI_TAPE_MAJOR, 0),
4240 ST_MAX_TAPE_ENTRIES);
4241err_class:
Kai Makisarac2c96f42005-08-02 12:21:51 +03004242 class_destroy(st_sysfs_class);
Jeff Garzik13026a62006-10-04 06:00:38 -04004243 return err;
Linus Torvalds1da177e2005-04-16 15:20:36 -07004244}
4245
4246static void __exit exit_st(void)
4247{
Robert P. J. Day405ae7d2007-02-17 19:13:42 +01004248 do_remove_sysfs_files();
Linus Torvalds1da177e2005-04-16 15:20:36 -07004249 scsi_unregister_driver(&st_template.gendrv);
4250 unregister_chrdev_region(MKDEV(SCSI_TAPE_MAJOR, 0),
4251 ST_MAX_TAPE_ENTRIES);
Kai Makisarac2c96f42005-08-02 12:21:51 +03004252 class_destroy(st_sysfs_class);
Linus Torvalds1da177e2005-04-16 15:20:36 -07004253 kfree(scsi_tapes);
4254 printk(KERN_INFO "st: Unloaded.\n");
4255}
4256
4257module_init(init_st);
4258module_exit(exit_st);
4259
4260
4261/* The sysfs driver interface. Read-only at the moment */
4262static ssize_t st_try_direct_io_show(struct device_driver *ddp, char *buf)
4263{
4264 return snprintf(buf, PAGE_SIZE, "%d\n", try_direct_io);
4265}
4266static DRIVER_ATTR(try_direct_io, S_IRUGO, st_try_direct_io_show, NULL);
4267
4268static ssize_t st_fixed_buffer_size_show(struct device_driver *ddp, char *buf)
4269{
4270 return snprintf(buf, PAGE_SIZE, "%d\n", st_fixed_buffer_size);
4271}
4272static DRIVER_ATTR(fixed_buffer_size, S_IRUGO, st_fixed_buffer_size_show, NULL);
4273
4274static ssize_t st_max_sg_segs_show(struct device_driver *ddp, char *buf)
4275{
4276 return snprintf(buf, PAGE_SIZE, "%d\n", st_max_sg_segs);
4277}
4278static DRIVER_ATTR(max_sg_segs, S_IRUGO, st_max_sg_segs_show, NULL);
4279
4280static ssize_t st_version_show(struct device_driver *ddd, char *buf)
4281{
4282 return snprintf(buf, PAGE_SIZE, "[%s]\n", verstr);
4283}
4284static DRIVER_ATTR(version, S_IRUGO, st_version_show, NULL);
4285
Robert P. J. Day405ae7d2007-02-17 19:13:42 +01004286static int do_create_sysfs_files(void)
Linus Torvalds1da177e2005-04-16 15:20:36 -07004287{
Robert P. J. Day405ae7d2007-02-17 19:13:42 +01004288 struct device_driver *sysfs = &st_template.gendrv;
Jeff Garzik13026a62006-10-04 06:00:38 -04004289 int err;
Linus Torvalds1da177e2005-04-16 15:20:36 -07004290
Robert P. J. Day405ae7d2007-02-17 19:13:42 +01004291 err = driver_create_file(sysfs, &driver_attr_try_direct_io);
Jeff Garzik13026a62006-10-04 06:00:38 -04004292 if (err)
4293 return err;
Robert P. J. Day405ae7d2007-02-17 19:13:42 +01004294 err = driver_create_file(sysfs, &driver_attr_fixed_buffer_size);
Jeff Garzik13026a62006-10-04 06:00:38 -04004295 if (err)
4296 goto err_try_direct_io;
Robert P. J. Day405ae7d2007-02-17 19:13:42 +01004297 err = driver_create_file(sysfs, &driver_attr_max_sg_segs);
Jeff Garzik13026a62006-10-04 06:00:38 -04004298 if (err)
4299 goto err_attr_fixed_buf;
Robert P. J. Day405ae7d2007-02-17 19:13:42 +01004300 err = driver_create_file(sysfs, &driver_attr_version);
Jeff Garzik13026a62006-10-04 06:00:38 -04004301 if (err)
4302 goto err_attr_max_sg;
4303
4304 return 0;
4305
4306err_attr_max_sg:
Robert P. J. Day405ae7d2007-02-17 19:13:42 +01004307 driver_remove_file(sysfs, &driver_attr_max_sg_segs);
Jeff Garzik13026a62006-10-04 06:00:38 -04004308err_attr_fixed_buf:
Robert P. J. Day405ae7d2007-02-17 19:13:42 +01004309 driver_remove_file(sysfs, &driver_attr_fixed_buffer_size);
Jeff Garzik13026a62006-10-04 06:00:38 -04004310err_try_direct_io:
Robert P. J. Day405ae7d2007-02-17 19:13:42 +01004311 driver_remove_file(sysfs, &driver_attr_try_direct_io);
Jeff Garzik13026a62006-10-04 06:00:38 -04004312 return err;
Linus Torvalds1da177e2005-04-16 15:20:36 -07004313}
4314
Robert P. J. Day405ae7d2007-02-17 19:13:42 +01004315static void do_remove_sysfs_files(void)
Linus Torvalds1da177e2005-04-16 15:20:36 -07004316{
Robert P. J. Day405ae7d2007-02-17 19:13:42 +01004317 struct device_driver *sysfs = &st_template.gendrv;
Linus Torvalds1da177e2005-04-16 15:20:36 -07004318
Robert P. J. Day405ae7d2007-02-17 19:13:42 +01004319 driver_remove_file(sysfs, &driver_attr_version);
4320 driver_remove_file(sysfs, &driver_attr_max_sg_segs);
4321 driver_remove_file(sysfs, &driver_attr_fixed_buffer_size);
4322 driver_remove_file(sysfs, &driver_attr_try_direct_io);
Linus Torvalds1da177e2005-04-16 15:20:36 -07004323}
4324
4325
4326/* The sysfs simple class interface */
Tony Jonesee959b02008-02-22 00:13:36 +01004327static ssize_t
4328st_defined_show(struct device *dev, struct device_attribute *attr, char *buf)
Linus Torvalds1da177e2005-04-16 15:20:36 -07004329{
James Bottomley7d15d6a2008-03-14 14:12:43 -07004330 struct st_modedef *STm = dev_get_drvdata(dev);
Linus Torvalds1da177e2005-04-16 15:20:36 -07004331 ssize_t l = 0;
4332
4333 l = snprintf(buf, PAGE_SIZE, "%d\n", STm->defined);
4334 return l;
4335}
4336
Tony Jonesee959b02008-02-22 00:13:36 +01004337DEVICE_ATTR(defined, S_IRUGO, st_defined_show, NULL);
Linus Torvalds1da177e2005-04-16 15:20:36 -07004338
Tony Jonesee959b02008-02-22 00:13:36 +01004339static ssize_t
4340st_defblk_show(struct device *dev, struct device_attribute *attr, char *buf)
Linus Torvalds1da177e2005-04-16 15:20:36 -07004341{
James Bottomley7d15d6a2008-03-14 14:12:43 -07004342 struct st_modedef *STm = dev_get_drvdata(dev);
Linus Torvalds1da177e2005-04-16 15:20:36 -07004343 ssize_t l = 0;
4344
4345 l = snprintf(buf, PAGE_SIZE, "%d\n", STm->default_blksize);
4346 return l;
4347}
4348
Tony Jonesee959b02008-02-22 00:13:36 +01004349DEVICE_ATTR(default_blksize, S_IRUGO, st_defblk_show, NULL);
Linus Torvalds1da177e2005-04-16 15:20:36 -07004350
Tony Jonesee959b02008-02-22 00:13:36 +01004351static ssize_t
4352st_defdensity_show(struct device *dev, struct device_attribute *attr, char *buf)
Linus Torvalds1da177e2005-04-16 15:20:36 -07004353{
James Bottomley7d15d6a2008-03-14 14:12:43 -07004354 struct st_modedef *STm = dev_get_drvdata(dev);
Linus Torvalds1da177e2005-04-16 15:20:36 -07004355 ssize_t l = 0;
4356 char *fmt;
4357
4358 fmt = STm->default_density >= 0 ? "0x%02x\n" : "%d\n";
4359 l = snprintf(buf, PAGE_SIZE, fmt, STm->default_density);
4360 return l;
4361}
4362
Tony Jonesee959b02008-02-22 00:13:36 +01004363DEVICE_ATTR(default_density, S_IRUGO, st_defdensity_show, NULL);
Linus Torvalds1da177e2005-04-16 15:20:36 -07004364
Tony Jonesee959b02008-02-22 00:13:36 +01004365static ssize_t
4366st_defcompression_show(struct device *dev, struct device_attribute *attr,
4367 char *buf)
Linus Torvalds1da177e2005-04-16 15:20:36 -07004368{
James Bottomley7d15d6a2008-03-14 14:12:43 -07004369 struct st_modedef *STm = dev_get_drvdata(dev);
Linus Torvalds1da177e2005-04-16 15:20:36 -07004370 ssize_t l = 0;
4371
4372 l = snprintf(buf, PAGE_SIZE, "%d\n", STm->default_compression - 1);
4373 return l;
4374}
4375
Tony Jonesee959b02008-02-22 00:13:36 +01004376DEVICE_ATTR(default_compression, S_IRUGO, st_defcompression_show, NULL);
Linus Torvalds1da177e2005-04-16 15:20:36 -07004377
Tony Jonesee959b02008-02-22 00:13:36 +01004378static ssize_t
4379st_options_show(struct device *dev, struct device_attribute *attr, char *buf)
Kai Makisarab174be02008-02-24 22:29:12 +02004380{
James Bottomley7d15d6a2008-03-14 14:12:43 -07004381 struct st_modedef *STm = dev_get_drvdata(dev);
Kai Makisarab174be02008-02-24 22:29:12 +02004382 struct scsi_tape *STp;
4383 int i, j, options;
4384 ssize_t l = 0;
4385
4386 for (i=0; i < st_dev_max; i++) {
4387 for (j=0; j < ST_NBR_MODES; j++)
4388 if (&scsi_tapes[i]->modes[j] == STm)
4389 break;
4390 if (j < ST_NBR_MODES)
4391 break;
4392 }
4393 if (i == st_dev_max)
4394 return 0; /* should never happen */
4395
4396 STp = scsi_tapes[i];
4397
4398 options = STm->do_buffer_writes ? MT_ST_BUFFER_WRITES : 0;
4399 options |= STm->do_async_writes ? MT_ST_ASYNC_WRITES : 0;
4400 options |= STm->do_read_ahead ? MT_ST_READ_AHEAD : 0;
4401 DEB( options |= debugging ? MT_ST_DEBUGGING : 0 );
4402 options |= STp->two_fm ? MT_ST_TWO_FM : 0;
4403 options |= STp->fast_mteom ? MT_ST_FAST_MTEOM : 0;
4404 options |= STm->defaults_for_writes ? MT_ST_DEF_WRITES : 0;
4405 options |= STp->can_bsr ? MT_ST_CAN_BSR : 0;
4406 options |= STp->omit_blklims ? MT_ST_NO_BLKLIMS : 0;
4407 options |= STp->can_partitions ? MT_ST_CAN_PARTITIONS : 0;
4408 options |= STp->scsi2_logical ? MT_ST_SCSI2LOGICAL : 0;
4409 options |= STm->sysv ? MT_ST_SYSV : 0;
4410 options |= STp->immediate ? MT_ST_NOWAIT : 0;
4411 options |= STp->sili ? MT_ST_SILI : 0;
4412
4413 l = snprintf(buf, PAGE_SIZE, "0x%08x\n", options);
4414 return l;
4415}
4416
Tony Jonesee959b02008-02-22 00:13:36 +01004417DEVICE_ATTR(options, S_IRUGO, st_options_show, NULL);
Kai Makisarab174be02008-02-24 22:29:12 +02004418
Jeff Garzik13026a62006-10-04 06:00:38 -04004419static int do_create_class_files(struct scsi_tape *STp, int dev_num, int mode)
Linus Torvalds1da177e2005-04-16 15:20:36 -07004420{
4421 int i, rew, error;
4422 char name[10];
Tony Jonesee959b02008-02-22 00:13:36 +01004423 struct device *st_class_member;
Linus Torvalds1da177e2005-04-16 15:20:36 -07004424
Linus Torvalds1da177e2005-04-16 15:20:36 -07004425 for (rew=0; rew < 2; rew++) {
4426 /* Make sure that the minor numbers corresponding to the four
4427 first modes always get the same names */
4428 i = mode << (4 - ST_NBR_MODE_BITS);
4429 snprintf(name, 10, "%s%s%s", rew ? "n" : "",
4430 STp->disk->disk_name, st_formats[i]);
4431 st_class_member =
Greg Kroah-Hartmand73a1a62008-07-21 20:03:34 -07004432 device_create(st_sysfs_class, &STp->device->sdev_gendev,
4433 MKDEV(SCSI_TAPE_MAJOR,
4434 TAPE_MINOR(dev_num, mode, rew)),
4435 &STp->modes[mode], "%s", name);
Linus Torvalds1da177e2005-04-16 15:20:36 -07004436 if (IS_ERR(st_class_member)) {
Tony Jonesee959b02008-02-22 00:13:36 +01004437 printk(KERN_WARNING "st%d: device_create failed\n",
Linus Torvalds1da177e2005-04-16 15:20:36 -07004438 dev_num);
Jeff Garzik13026a62006-10-04 06:00:38 -04004439 error = PTR_ERR(st_class_member);
Linus Torvalds1da177e2005-04-16 15:20:36 -07004440 goto out;
4441 }
Linus Torvalds1da177e2005-04-16 15:20:36 -07004442
Tony Jonesee959b02008-02-22 00:13:36 +01004443 error = device_create_file(st_class_member,
4444 &dev_attr_defined);
Jeff Garzik13026a62006-10-04 06:00:38 -04004445 if (error) goto out;
Tony Jonesee959b02008-02-22 00:13:36 +01004446 error = device_create_file(st_class_member,
4447 &dev_attr_default_blksize);
Jeff Garzik13026a62006-10-04 06:00:38 -04004448 if (error) goto out;
Tony Jonesee959b02008-02-22 00:13:36 +01004449 error = device_create_file(st_class_member,
4450 &dev_attr_default_density);
Jeff Garzik13026a62006-10-04 06:00:38 -04004451 if (error) goto out;
Tony Jonesee959b02008-02-22 00:13:36 +01004452 error = device_create_file(st_class_member,
4453 &dev_attr_default_compression);
Jeff Garzik13026a62006-10-04 06:00:38 -04004454 if (error) goto out;
Tony Jonesee959b02008-02-22 00:13:36 +01004455 error = device_create_file(st_class_member,
4456 &dev_attr_options);
Kai Makisarab174be02008-02-24 22:29:12 +02004457 if (error) goto out;
Jeff Garzik13026a62006-10-04 06:00:38 -04004458
Linus Torvalds1da177e2005-04-16 15:20:36 -07004459 if (mode == 0 && rew == 0) {
4460 error = sysfs_create_link(&STp->device->sdev_gendev.kobj,
4461 &st_class_member->kobj,
4462 "tape");
4463 if (error) {
4464 printk(KERN_ERR
4465 "st%d: Can't create sysfs link from SCSI device.\n",
4466 dev_num);
Jeff Garzik13026a62006-10-04 06:00:38 -04004467 goto out;
Linus Torvalds1da177e2005-04-16 15:20:36 -07004468 }
4469 }
4470 }
Jeff Garzik13026a62006-10-04 06:00:38 -04004471
4472 return 0;
4473
4474out:
4475 return error;
Linus Torvalds1da177e2005-04-16 15:20:36 -07004476}
4477
Linus Torvalds1da177e2005-04-16 15:20:36 -07004478/* The following functions may be useful for a larger audience. */
4479static int sgl_map_user_pages(struct scatterlist *sgl, const unsigned int max_pages,
4480 unsigned long uaddr, size_t count, int rw)
4481{
James Bottomley07542b82005-08-31 20:27:22 -04004482 unsigned long end = (uaddr + count + PAGE_SIZE - 1) >> PAGE_SHIFT;
4483 unsigned long start = uaddr >> PAGE_SHIFT;
4484 const int nr_pages = end - start;
Linus Torvalds1da177e2005-04-16 15:20:36 -07004485 int res, i, j;
Linus Torvalds1da177e2005-04-16 15:20:36 -07004486 struct page **pages;
4487
Linus Torvalds1da177e2005-04-16 15:20:36 -07004488 /* User attempted Overflow! */
4489 if ((uaddr + count) < uaddr)
4490 return -EINVAL;
4491
4492 /* Too big */
4493 if (nr_pages > max_pages)
4494 return -ENOMEM;
4495
4496 /* Hmm? */
4497 if (count == 0)
4498 return 0;
4499
4500 if ((pages = kmalloc(max_pages * sizeof(*pages), GFP_KERNEL)) == NULL)
4501 return -ENOMEM;
4502
4503 /* Try to fault in all of the necessary pages */
4504 down_read(&current->mm->mmap_sem);
4505 /* rw==READ means read from drive, write into memory area */
4506 res = get_user_pages(
4507 current,
4508 current->mm,
4509 uaddr,
4510 nr_pages,
4511 rw == READ,
4512 0, /* don't force */
4513 pages,
4514 NULL);
4515 up_read(&current->mm->mmap_sem);
4516
4517 /* Errors and no page mapped should return here */
4518 if (res < nr_pages)
4519 goto out_unmap;
4520
4521 for (i=0; i < nr_pages; i++) {
4522 /* FIXME: flush superflous for rw==READ,
4523 * probably wrong function for rw==WRITE
4524 */
4525 flush_dcache_page(pages[i]);
4526 }
4527
4528 /* Populate the scatter/gather list */
Jens Axboe642f1492007-10-24 11:20:47 +02004529 sg_set_page(&sgl[0], pages[0], 0, uaddr & ~PAGE_MASK);
Linus Torvalds1da177e2005-04-16 15:20:36 -07004530 if (nr_pages > 1) {
4531 sgl[0].length = PAGE_SIZE - sgl[0].offset;
4532 count -= sgl[0].length;
4533 for (i=1; i < nr_pages ; i++) {
Jens Axboe642f1492007-10-24 11:20:47 +02004534 sg_set_page(&sgl[i], pages[i],
4535 count < PAGE_SIZE ? count : PAGE_SIZE, 0);;
Linus Torvalds1da177e2005-04-16 15:20:36 -07004536 count -= PAGE_SIZE;
4537 }
4538 }
4539 else {
4540 sgl[0].length = count;
4541 }
4542
4543 kfree(pages);
4544 return nr_pages;
4545
4546 out_unmap:
4547 if (res > 0) {
4548 for (j=0; j < res; j++)
4549 page_cache_release(pages[j]);
Hugh Dickins6bc733e2005-12-01 20:21:57 +00004550 res = 0;
Linus Torvalds1da177e2005-04-16 15:20:36 -07004551 }
4552 kfree(pages);
4553 return res;
4554}
4555
4556
4557/* And unmap them... */
4558static int sgl_unmap_user_pages(struct scatterlist *sgl, const unsigned int nr_pages,
4559 int dirtied)
4560{
4561 int i;
4562
4563 for (i=0; i < nr_pages; i++) {
Jens Axboe45711f12007-10-22 21:19:53 +02004564 struct page *page = sg_page(&sgl[i]);
Nick Pigginb5810032005-10-29 18:16:12 -07004565
Nick Pigginb5810032005-10-29 18:16:12 -07004566 if (dirtied)
4567 SetPageDirty(page);
Linus Torvalds1da177e2005-04-16 15:20:36 -07004568 /* FIXME: cache flush missing for rw==READ
4569 * FIXME: call the correct reference counting function
4570 */
Nick Pigginb5810032005-10-29 18:16:12 -07004571 page_cache_release(page);
Linus Torvalds1da177e2005-04-16 15:20:36 -07004572 }
4573
4574 return 0;
4575}