blob: e41998cb098ebbea2a6243bda198cc463f857a35 [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 Makisara3e51d3c2010-10-09 00:17:56 +030012 Copyright 1992 - 2010 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 Makisara373daac2010-12-20 18:43:39 +020020static const char *verstr = "20101219";
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>
Tejun Heo5a0e3ad2010-03-24 17:04:11 +090030#include <linux/slab.h>
Linus Torvalds1da177e2005-04-16 15:20:36 -070031#include <linux/errno.h>
32#include <linux/mtio.h>
Kai Makisara 16c4b3e2005-05-01 18:11:55 +030033#include <linux/cdrom.h>
Linus Torvalds1da177e2005-04-16 15:20:36 -070034#include <linux/ioctl.h>
35#include <linux/fcntl.h>
36#include <linux/spinlock.h>
37#include <linux/blkdev.h>
38#include <linux/moduleparam.h>
Linus Torvalds1da177e2005-04-16 15:20:36 -070039#include <linux/cdev.h>
40#include <linux/delay.h>
Arjan van de Ven0b950672006-01-11 13:16:10 +010041#include <linux/mutex.h>
Linus Torvalds1da177e2005-04-16 15:20:36 -070042
43#include <asm/uaccess.h>
44#include <asm/dma.h>
Linus Torvalds1da177e2005-04-16 15:20:36 -070045
46#include <scsi/scsi.h>
47#include <scsi/scsi_dbg.h>
48#include <scsi/scsi_device.h>
49#include <scsi/scsi_driver.h>
50#include <scsi/scsi_eh.h>
51#include <scsi/scsi_host.h>
52#include <scsi/scsi_ioctl.h>
Kai Makisara 16c4b3e2005-05-01 18:11:55 +030053#include <scsi/sg.h>
Linus Torvalds1da177e2005-04-16 15:20:36 -070054
55
56/* The driver prints some debugging information on the console if DEBUG
57 is defined and non-zero. */
58#define DEBUG 0
59
60#if DEBUG
61/* The message level for the debug messages is currently set to KERN_NOTICE
62 so that people can easily see the messages. Later when the debugging messages
63 in the drivers are more widely classified, this may be changed to KERN_DEBUG. */
64#define ST_DEB_MSG KERN_NOTICE
65#define DEB(a) a
66#define DEBC(a) if (debugging) { a ; }
67#else
68#define DEB(a)
69#define DEBC(a)
70#endif
71
72#define ST_KILOBYTE 1024
73
74#include "st_options.h"
75#include "st.h"
76
Arnd Bergmann2a48fc02010-06-02 14:28:52 +020077static DEFINE_MUTEX(st_mutex);
Linus Torvalds1da177e2005-04-16 15:20:36 -070078static 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
Linus Torvalds1da177e2005-04-16 15:20:36 -0700185static int enlarge_buffer(struct st_buffer *, int, int);
Kai Makisara40f6b362008-02-24 22:23:24 +0200186static void clear_buffer(struct st_buffer *);
Linus Torvalds1da177e2005-04-16 15:20:36 -0700187static void normalize_buffer(struct st_buffer *);
188static int append_to_buffer(const char __user *, struct st_buffer *, int);
189static int from_buffer(struct st_buffer *, char __user *, int);
190static void move_buffer_data(struct st_buffer *, int);
Linus Torvalds1da177e2005-04-16 15:20:36 -0700191
FUJITA Tomonori66207422008-12-18 14:49:43 +0900192static int sgl_map_user_pages(struct st_buffer *, const unsigned int,
Linus Torvalds1da177e2005-04-16 15:20:36 -0700193 unsigned long, size_t, int);
FUJITA Tomonori66207422008-12-18 14:49:43 +0900194static int sgl_unmap_user_pages(struct st_buffer *, const unsigned int, int);
Linus Torvalds1da177e2005-04-16 15:20:36 -0700195
196static int st_probe(struct device *);
197static int st_remove(struct device *);
Linus Torvalds1da177e2005-04-16 15:20:36 -0700198
Robert P. J. Day405ae7d2007-02-17 19:13:42 +0100199static int do_create_sysfs_files(void);
200static void do_remove_sysfs_files(void);
Jeff Garzik13026a62006-10-04 06:00:38 -0400201static int do_create_class_files(struct scsi_tape *, int, int);
Linus Torvalds1da177e2005-04-16 15:20:36 -0700202
203static struct scsi_driver st_template = {
204 .owner = THIS_MODULE,
205 .gendrv = {
206 .name = "st",
207 .probe = st_probe,
208 .remove = st_remove,
209 },
Linus Torvalds1da177e2005-04-16 15:20:36 -0700210};
211
212static int st_compression(struct scsi_tape *, int);
213
214static int find_partition(struct scsi_tape *);
215static int switch_partition(struct scsi_tape *);
216
217static int st_int_ioctl(struct scsi_tape *, unsigned int, unsigned long);
218
Kai Makisaraf03a5672005-08-02 13:40:47 +0300219static void scsi_tape_release(struct kref *);
220
221#define to_scsi_tape(obj) container_of(obj, struct scsi_tape, kref)
222
Arjan van de Ven0b950672006-01-11 13:16:10 +0100223static DEFINE_MUTEX(st_ref_mutex);
Kai Makisaraf03a5672005-08-02 13:40:47 +0300224
Linus Torvalds1da177e2005-04-16 15:20:36 -0700225
226#include "osst_detect.h"
227#ifndef SIGS_FROM_OSST
228#define SIGS_FROM_OSST \
229 {"OnStream", "SC-", "", "osst"}, \
230 {"OnStream", "DI-", "", "osst"}, \
231 {"OnStream", "DP-", "", "osst"}, \
232 {"OnStream", "USB", "", "osst"}, \
233 {"OnStream", "FW-", "", "osst"}
234#endif
235
Kai Makisaraf03a5672005-08-02 13:40:47 +0300236static struct scsi_tape *scsi_tape_get(int dev)
237{
238 struct scsi_tape *STp = NULL;
239
Arjan van de Ven0b950672006-01-11 13:16:10 +0100240 mutex_lock(&st_ref_mutex);
Kai Makisaraf03a5672005-08-02 13:40:47 +0300241 write_lock(&st_dev_arr_lock);
242
243 if (dev < st_dev_max && scsi_tapes != NULL)
244 STp = scsi_tapes[dev];
245 if (!STp) goto out;
246
247 kref_get(&STp->kref);
248
249 if (!STp->device)
250 goto out_put;
251
252 if (scsi_device_get(STp->device))
253 goto out_put;
254
255 goto out;
256
257out_put:
258 kref_put(&STp->kref, scsi_tape_release);
259 STp = NULL;
260out:
261 write_unlock(&st_dev_arr_lock);
Arjan van de Ven0b950672006-01-11 13:16:10 +0100262 mutex_unlock(&st_ref_mutex);
Kai Makisaraf03a5672005-08-02 13:40:47 +0300263 return STp;
264}
265
266static void scsi_tape_put(struct scsi_tape *STp)
267{
268 struct scsi_device *sdev = STp->device;
269
Arjan van de Ven0b950672006-01-11 13:16:10 +0100270 mutex_lock(&st_ref_mutex);
Kai Makisaraf03a5672005-08-02 13:40:47 +0300271 kref_put(&STp->kref, scsi_tape_release);
272 scsi_device_put(sdev);
Arjan van de Ven0b950672006-01-11 13:16:10 +0100273 mutex_unlock(&st_ref_mutex);
Kai Makisaraf03a5672005-08-02 13:40:47 +0300274}
275
Linus Torvalds1da177e2005-04-16 15:20:36 -0700276struct st_reject_data {
277 char *vendor;
278 char *model;
279 char *rev;
280 char *driver_hint; /* Name of the correct driver, NULL if unknown */
281};
282
283static struct st_reject_data reject_list[] = {
284 /* {"XXX", "Yy-", "", NULL}, example */
285 SIGS_FROM_OSST,
286 {NULL, }};
287
288/* If the device signature is on the list of incompatible drives, the
289 function returns a pointer to the name of the correct driver (if known) */
290static char * st_incompatible(struct scsi_device* SDp)
291{
292 struct st_reject_data *rp;
293
294 for (rp=&(reject_list[0]); rp->vendor != NULL; rp++)
295 if (!strncmp(rp->vendor, SDp->vendor, strlen(rp->vendor)) &&
296 !strncmp(rp->model, SDp->model, strlen(rp->model)) &&
297 !strncmp(rp->rev, SDp->rev, strlen(rp->rev))) {
298 if (rp->driver_hint)
299 return rp->driver_hint;
300 else
301 return "unknown";
302 }
303 return NULL;
304}
305
306
307static inline char *tape_name(struct scsi_tape *tape)
308{
309 return tape->disk->disk_name;
310}
311
312
Mike Christie8b05b772005-11-08 04:06:44 -0600313static void st_analyze_sense(struct st_request *SRpnt, struct st_cmdstatus *s)
Linus Torvalds1da177e2005-04-16 15:20:36 -0700314{
315 const u8 *ucp;
Mike Christie8b05b772005-11-08 04:06:44 -0600316 const u8 *sense = SRpnt->sense;
Linus Torvalds1da177e2005-04-16 15:20:36 -0700317
Mike Christie8b05b772005-11-08 04:06:44 -0600318 s->have_sense = scsi_normalize_sense(SRpnt->sense,
319 SCSI_SENSE_BUFFERSIZE, &s->sense_hdr);
Linus Torvalds1da177e2005-04-16 15:20:36 -0700320 s->flags = 0;
321
322 if (s->have_sense) {
323 s->deferred = 0;
324 s->remainder_valid =
325 scsi_get_sense_info_fld(sense, SCSI_SENSE_BUFFERSIZE, &s->uremainder64);
326 switch (sense[0] & 0x7f) {
327 case 0x71:
328 s->deferred = 1;
329 case 0x70:
330 s->fixed_format = 1;
331 s->flags = sense[2] & 0xe0;
332 break;
333 case 0x73:
334 s->deferred = 1;
335 case 0x72:
336 s->fixed_format = 0;
337 ucp = scsi_sense_desc_find(sense, SCSI_SENSE_BUFFERSIZE, 4);
338 s->flags = ucp ? (ucp[3] & 0xe0) : 0;
339 break;
340 }
341 }
342}
343
344
345/* Convert the result to success code */
Mike Christie8b05b772005-11-08 04:06:44 -0600346static int st_chk_result(struct scsi_tape *STp, struct st_request * SRpnt)
Linus Torvalds1da177e2005-04-16 15:20:36 -0700347{
Mike Christie8b05b772005-11-08 04:06:44 -0600348 int result = SRpnt->result;
Linus Torvalds1da177e2005-04-16 15:20:36 -0700349 u8 scode;
350 DEB(const char *stp;)
351 char *name = tape_name(STp);
352 struct st_cmdstatus *cmdstatp;
353
354 if (!result)
355 return 0;
356
357 cmdstatp = &STp->buffer->cmdstat;
Kai Makisaraf03a5672005-08-02 13:40:47 +0300358 st_analyze_sense(SRpnt, cmdstatp);
Linus Torvalds1da177e2005-04-16 15:20:36 -0700359
360 if (cmdstatp->have_sense)
361 scode = STp->buffer->cmdstat.sense_hdr.sense_key;
362 else
363 scode = 0;
364
365 DEB(
366 if (debugging) {
Mike Christie8b05b772005-11-08 04:06:44 -0600367 printk(ST_DEB_MSG "%s: Error: %x, cmd: %x %x %x %x %x %x\n",
Linus Torvalds1da177e2005-04-16 15:20:36 -0700368 name, result,
Mike Christie8b05b772005-11-08 04:06:44 -0600369 SRpnt->cmd[0], SRpnt->cmd[1], SRpnt->cmd[2],
370 SRpnt->cmd[3], SRpnt->cmd[4], SRpnt->cmd[5]);
Linus Torvalds1da177e2005-04-16 15:20:36 -0700371 if (cmdstatp->have_sense)
Luben Tuikov4e73ea72006-07-07 00:02:18 -0700372 __scsi_print_sense(name, SRpnt->sense, SCSI_SENSE_BUFFERSIZE);
Linus Torvalds1da177e2005-04-16 15:20:36 -0700373 } ) /* end DEB */
374 if (!debugging) { /* Abnormal conditions for tape */
375 if (!cmdstatp->have_sense)
376 printk(KERN_WARNING
Martin K. Petersen1c9fbaf2009-01-04 03:14:11 -0500377 "%s: Error %x (driver bt 0x%x, host bt 0x%x).\n",
378 name, result, driver_byte(result),
379 host_byte(result));
Linus Torvalds1da177e2005-04-16 15:20:36 -0700380 else if (cmdstatp->have_sense &&
381 scode != NO_SENSE &&
382 scode != RECOVERED_ERROR &&
383 /* scode != UNIT_ATTENTION && */
384 scode != BLANK_CHECK &&
385 scode != VOLUME_OVERFLOW &&
Mike Christie8b05b772005-11-08 04:06:44 -0600386 SRpnt->cmd[0] != MODE_SENSE &&
387 SRpnt->cmd[0] != TEST_UNIT_READY) {
Luben Tuikov4e73ea72006-07-07 00:02:18 -0700388
389 __scsi_print_sense(name, SRpnt->sense, SCSI_SENSE_BUFFERSIZE);
Linus Torvalds1da177e2005-04-16 15:20:36 -0700390 }
391 }
392
393 if (cmdstatp->fixed_format &&
394 STp->cln_mode >= EXTENDED_SENSE_START) { /* Only fixed format sense */
395 if (STp->cln_sense_value)
Mike Christie8b05b772005-11-08 04:06:44 -0600396 STp->cleaning_req |= ((SRpnt->sense[STp->cln_mode] &
Linus Torvalds1da177e2005-04-16 15:20:36 -0700397 STp->cln_sense_mask) == STp->cln_sense_value);
398 else
Mike Christie8b05b772005-11-08 04:06:44 -0600399 STp->cleaning_req |= ((SRpnt->sense[STp->cln_mode] &
Linus Torvalds1da177e2005-04-16 15:20:36 -0700400 STp->cln_sense_mask) != 0);
401 }
402 if (cmdstatp->have_sense &&
403 cmdstatp->sense_hdr.asc == 0 && cmdstatp->sense_hdr.ascq == 0x17)
404 STp->cleaning_req = 1; /* ASC and ASCQ => cleaning requested */
405
406 STp->pos_unknown |= STp->device->was_reset;
407
408 if (cmdstatp->have_sense &&
409 scode == RECOVERED_ERROR
410#if ST_RECOVERED_WRITE_FATAL
Mike Christie8b05b772005-11-08 04:06:44 -0600411 && SRpnt->cmd[0] != WRITE_6
412 && SRpnt->cmd[0] != WRITE_FILEMARKS
Linus Torvalds1da177e2005-04-16 15:20:36 -0700413#endif
414 ) {
415 STp->recover_count++;
416 STp->recover_reg++;
417
418 DEB(
419 if (debugging) {
Mike Christie8b05b772005-11-08 04:06:44 -0600420 if (SRpnt->cmd[0] == READ_6)
Linus Torvalds1da177e2005-04-16 15:20:36 -0700421 stp = "read";
Mike Christie8b05b772005-11-08 04:06:44 -0600422 else if (SRpnt->cmd[0] == WRITE_6)
Linus Torvalds1da177e2005-04-16 15:20:36 -0700423 stp = "write";
424 else
425 stp = "ioctl";
426 printk(ST_DEB_MSG "%s: Recovered %s error (%d).\n", name, stp,
427 STp->recover_count);
428 } ) /* end DEB */
429
430 if (cmdstatp->flags == 0)
431 return 0;
432 }
433 return (-EIO);
434}
435
FUJITA Tomonori4deba242008-12-05 15:25:20 +0900436static struct st_request *st_allocate_request(struct scsi_tape *stp)
Mike Christie8b05b772005-11-08 04:06:44 -0600437{
FUJITA Tomonori4deba242008-12-05 15:25:20 +0900438 struct st_request *streq;
439
440 streq = kzalloc(sizeof(*streq), GFP_KERNEL);
441 if (streq)
442 streq->stp = stp;
443 else {
444 DEBC(printk(KERN_ERR "%s: Can't get SCSI request.\n",
445 tape_name(stp)););
446 if (signal_pending(current))
447 stp->buffer->syscall_result = -EINTR;
448 else
449 stp->buffer->syscall_result = -EBUSY;
450 }
451
452 return streq;
Mike Christie8b05b772005-11-08 04:06:44 -0600453}
454
455static void st_release_request(struct st_request *streq)
456{
457 kfree(streq);
Linus Torvalds1da177e2005-04-16 15:20:36 -0700458}
459
FUJITA Tomonori13b53b42008-12-18 14:49:41 +0900460static void st_scsi_execute_end(struct request *req, int uptodate)
461{
462 struct st_request *SRpnt = req->end_io_data;
463 struct scsi_tape *STp = SRpnt->stp;
Petr Uzelc68bf8e2011-10-21 13:31:09 +0200464 struct bio *tmp;
FUJITA Tomonori13b53b42008-12-18 14:49:41 +0900465
466 STp->buffer->cmdstat.midlevel_result = SRpnt->result = req->errors;
Tejun Heoc3a4d782009-05-07 22:24:37 +0900467 STp->buffer->cmdstat.residual = req->resid_len;
FUJITA Tomonori13b53b42008-12-18 14:49:41 +0900468
Petr Uzelc68bf8e2011-10-21 13:31:09 +0200469 tmp = SRpnt->bio;
FUJITA Tomonori13b53b42008-12-18 14:49:41 +0900470 if (SRpnt->waiting)
471 complete(SRpnt->waiting);
472
Petr Uzelc68bf8e2011-10-21 13:31:09 +0200473 blk_rq_unmap_user(tmp);
FUJITA Tomonori13b53b42008-12-18 14:49:41 +0900474 __blk_put_request(req->q, req);
475}
476
477static int st_scsi_execute(struct st_request *SRpnt, const unsigned char *cmd,
478 int data_direction, void *buffer, unsigned bufflen,
479 int timeout, int retries)
480{
481 struct request *req;
482 struct rq_map_data *mdata = &SRpnt->stp->buffer->map_data;
483 int err = 0;
484 int write = (data_direction == DMA_TO_DEVICE);
485
486 req = blk_get_request(SRpnt->stp->device->request_queue, write,
487 GFP_KERNEL);
488 if (!req)
489 return DRIVER_ERROR << 24;
490
491 req->cmd_type = REQ_TYPE_BLOCK_PC;
492 req->cmd_flags |= REQ_QUIET;
493
494 mdata->null_mapped = 1;
495
Kai Makisara02ae2c02008-12-18 14:49:50 +0900496 if (bufflen) {
497 err = blk_rq_map_user(req->q, req, mdata, NULL, bufflen,
498 GFP_KERNEL);
499 if (err) {
500 blk_put_request(req);
501 return DRIVER_ERROR << 24;
502 }
FUJITA Tomonori13b53b42008-12-18 14:49:41 +0900503 }
504
505 SRpnt->bio = req->bio;
506 req->cmd_len = COMMAND_SIZE(cmd[0]);
507 memset(req->cmd, 0, BLK_MAX_CDB);
508 memcpy(req->cmd, cmd, req->cmd_len);
509 req->sense = SRpnt->sense;
510 req->sense_len = 0;
511 req->timeout = timeout;
512 req->retries = retries;
513 req->end_io_data = SRpnt;
514
515 blk_execute_rq_nowait(req->q, NULL, req, 1, st_scsi_execute_end);
516 return 0;
517}
518
Linus Torvalds1da177e2005-04-16 15:20:36 -0700519/* Do the scsi command. Waits until command performed if do_wait is true.
520 Otherwise write_behind_check() is used to check that the command
521 has finished. */
Mike Christie8b05b772005-11-08 04:06:44 -0600522static struct st_request *
523st_do_scsi(struct st_request * SRpnt, struct scsi_tape * STp, unsigned char *cmd,
Linus Torvalds1da177e2005-04-16 15:20:36 -0700524 int bytes, int direction, int timeout, int retries, int do_wait)
525{
Kai Makisaraf03a5672005-08-02 13:40:47 +0300526 struct completion *waiting;
FUJITA Tomonori6d476262008-12-18 14:49:42 +0900527 struct rq_map_data *mdata = &STp->buffer->map_data;
528 int ret;
Linus Torvalds1da177e2005-04-16 15:20:36 -0700529
Kai Makisaraf03a5672005-08-02 13:40:47 +0300530 /* if async, make sure there's no command outstanding */
531 if (!do_wait && ((STp->buffer)->last_SRpnt)) {
532 printk(KERN_ERR "%s: Async command already active.\n",
533 tape_name(STp));
534 if (signal_pending(current))
535 (STp->buffer)->syscall_result = (-EINTR);
536 else
537 (STp->buffer)->syscall_result = (-EBUSY);
538 return NULL;
539 }
540
FUJITA Tomonori4deba242008-12-05 15:25:20 +0900541 if (!SRpnt) {
542 SRpnt = st_allocate_request(STp);
543 if (!SRpnt)
Linus Torvalds1da177e2005-04-16 15:20:36 -0700544 return NULL;
Linus Torvalds1da177e2005-04-16 15:20:36 -0700545 }
546
Kai Makisaraf03a5672005-08-02 13:40:47 +0300547 /* If async IO, set last_SRpnt. This ptr tells write_behind_check
548 which IO is outstanding. It's nulled out when the IO completes. */
549 if (!do_wait)
550 (STp->buffer)->last_SRpnt = SRpnt;
551
552 waiting = &STp->wait;
553 init_completion(waiting);
Mike Christie8b05b772005-11-08 04:06:44 -0600554 SRpnt->waiting = waiting;
555
FUJITA Tomonori66207422008-12-18 14:49:43 +0900556 if (STp->buffer->do_dio) {
FUJITA Tomonoric982c362009-11-26 09:24:13 +0900557 mdata->page_order = 0;
FUJITA Tomonori66207422008-12-18 14:49:43 +0900558 mdata->nr_entries = STp->buffer->sg_segs;
559 mdata->pages = STp->buffer->mapped_pages;
560 } else {
FUJITA Tomonoric982c362009-11-26 09:24:13 +0900561 mdata->page_order = STp->buffer->reserved_page_order;
FUJITA Tomonori6d476262008-12-18 14:49:42 +0900562 mdata->nr_entries =
563 DIV_ROUND_UP(bytes, PAGE_SIZE << mdata->page_order);
FUJITA Tomonoric982c362009-11-26 09:24:13 +0900564 mdata->pages = STp->buffer->reserved_pages;
565 mdata->offset = 0;
FUJITA Tomonori6d476262008-12-18 14:49:42 +0900566 }
567
Mike Christie8b05b772005-11-08 04:06:44 -0600568 memcpy(SRpnt->cmd, cmd, sizeof(SRpnt->cmd));
Linus Torvalds1da177e2005-04-16 15:20:36 -0700569 STp->buffer->cmdstat.have_sense = 0;
Mike Christie8b05b772005-11-08 04:06:44 -0600570 STp->buffer->syscall_result = 0;
Linus Torvalds1da177e2005-04-16 15:20:36 -0700571
FUJITA Tomonori66207422008-12-18 14:49:43 +0900572 ret = st_scsi_execute(SRpnt, cmd, direction, NULL, bytes, timeout,
573 retries);
FUJITA Tomonori6d476262008-12-18 14:49:42 +0900574 if (ret) {
Mike Christie8b05b772005-11-08 04:06:44 -0600575 /* could not allocate the buffer or request was too large */
576 (STp->buffer)->syscall_result = (-EBUSY);
Kai Makisara787926b2005-11-13 10:04:44 +0200577 (STp->buffer)->last_SRpnt = NULL;
FUJITA Tomonori6d476262008-12-18 14:49:42 +0900578 } else if (do_wait) {
Kai Makisaraf03a5672005-08-02 13:40:47 +0300579 wait_for_completion(waiting);
Mike Christie8b05b772005-11-08 04:06:44 -0600580 SRpnt->waiting = NULL;
Linus Torvalds1da177e2005-04-16 15:20:36 -0700581 (STp->buffer)->syscall_result = st_chk_result(STp, SRpnt);
582 }
Mike Christie8b05b772005-11-08 04:06:44 -0600583
Linus Torvalds1da177e2005-04-16 15:20:36 -0700584 return SRpnt;
585}
586
587
588/* Handle the write-behind checking (waits for completion). Returns -ENOSPC if
589 write has been correct but EOM early warning reached, -EIO if write ended in
590 error or zero if write successful. Asynchronous writes are used only in
591 variable block mode. */
592static int write_behind_check(struct scsi_tape * STp)
593{
594 int retval = 0;
595 struct st_buffer *STbuffer;
596 struct st_partstat *STps;
597 struct st_cmdstatus *cmdstatp;
Mike Christie8b05b772005-11-08 04:06:44 -0600598 struct st_request *SRpnt;
Linus Torvalds1da177e2005-04-16 15:20:36 -0700599
600 STbuffer = STp->buffer;
601 if (!STbuffer->writing)
602 return 0;
603
604 DEB(
605 if (STp->write_pending)
606 STp->nbr_waits++;
607 else
608 STp->nbr_finished++;
609 ) /* end DEB */
610
611 wait_for_completion(&(STp->wait));
Kai Makisaraf03a5672005-08-02 13:40:47 +0300612 SRpnt = STbuffer->last_SRpnt;
613 STbuffer->last_SRpnt = NULL;
Mike Christie8b05b772005-11-08 04:06:44 -0600614 SRpnt->waiting = NULL;
Linus Torvalds1da177e2005-04-16 15:20:36 -0700615
Kai Makisaraf03a5672005-08-02 13:40:47 +0300616 (STp->buffer)->syscall_result = st_chk_result(STp, SRpnt);
Mike Christie8b05b772005-11-08 04:06:44 -0600617 st_release_request(SRpnt);
Linus Torvalds1da177e2005-04-16 15:20:36 -0700618
619 STbuffer->buffer_bytes -= STbuffer->writing;
620 STps = &(STp->ps[STp->partition]);
621 if (STps->drv_block >= 0) {
622 if (STp->block_size == 0)
623 STps->drv_block++;
624 else
625 STps->drv_block += STbuffer->writing / STp->block_size;
626 }
627
628 cmdstatp = &STbuffer->cmdstat;
629 if (STbuffer->syscall_result) {
630 retval = -EIO;
631 if (cmdstatp->have_sense && !cmdstatp->deferred &&
632 (cmdstatp->flags & SENSE_EOM) &&
633 (cmdstatp->sense_hdr.sense_key == NO_SENSE ||
634 cmdstatp->sense_hdr.sense_key == RECOVERED_ERROR)) {
635 /* EOM at write-behind, has all data been written? */
636 if (!cmdstatp->remainder_valid ||
637 cmdstatp->uremainder64 == 0)
638 retval = -ENOSPC;
639 }
640 if (retval == -EIO)
641 STps->drv_block = -1;
642 }
643 STbuffer->writing = 0;
644
645 DEB(if (debugging && retval)
646 printk(ST_DEB_MSG "%s: Async write error %x, return value %d.\n",
647 tape_name(STp), STbuffer->cmdstat.midlevel_result, retval);) /* end DEB */
648
649 return retval;
650}
651
652
653/* Step over EOF if it has been inadvertently crossed (ioctl not used because
654 it messes up the block number). */
655static int cross_eof(struct scsi_tape * STp, int forward)
656{
Mike Christie8b05b772005-11-08 04:06:44 -0600657 struct st_request *SRpnt;
Linus Torvalds1da177e2005-04-16 15:20:36 -0700658 unsigned char cmd[MAX_COMMAND_SIZE];
659
660 cmd[0] = SPACE;
661 cmd[1] = 0x01; /* Space FileMarks */
662 if (forward) {
663 cmd[2] = cmd[3] = 0;
664 cmd[4] = 1;
665 } else
666 cmd[2] = cmd[3] = cmd[4] = 0xff; /* -1 filemarks */
667 cmd[5] = 0;
668
669 DEBC(printk(ST_DEB_MSG "%s: Stepping over filemark %s.\n",
670 tape_name(STp), forward ? "forward" : "backward"));
671
Kai Makisara02ae2c02008-12-18 14:49:50 +0900672 SRpnt = st_do_scsi(NULL, STp, cmd, 0, DMA_NONE,
673 STp->device->request_queue->rq_timeout,
674 MAX_RETRIES, 1);
Linus Torvalds1da177e2005-04-16 15:20:36 -0700675 if (!SRpnt)
Kai Makisara02ae2c02008-12-18 14:49:50 +0900676 return (STp->buffer)->syscall_result;
Linus Torvalds1da177e2005-04-16 15:20:36 -0700677
Kai Makisara02ae2c02008-12-18 14:49:50 +0900678 st_release_request(SRpnt);
679 SRpnt = NULL;
Linus Torvalds1da177e2005-04-16 15:20:36 -0700680
681 if ((STp->buffer)->cmdstat.midlevel_result != 0)
682 printk(KERN_ERR "%s: Stepping over filemark %s failed.\n",
683 tape_name(STp), forward ? "forward" : "backward");
684
Kai Makisara02ae2c02008-12-18 14:49:50 +0900685 return (STp->buffer)->syscall_result;
Linus Torvalds1da177e2005-04-16 15:20:36 -0700686}
687
688
689/* Flush the write buffer (never need to write if variable blocksize). */
Adrian Bunk8ef8d592008-04-14 17:17:16 +0300690static int st_flush_write_buffer(struct scsi_tape * STp)
Linus Torvalds1da177e2005-04-16 15:20:36 -0700691{
Kai Makisara786231a2008-07-11 15:06:40 +0300692 int transfer, blks;
Linus Torvalds1da177e2005-04-16 15:20:36 -0700693 int result;
694 unsigned char cmd[MAX_COMMAND_SIZE];
Mike Christie8b05b772005-11-08 04:06:44 -0600695 struct st_request *SRpnt;
Linus Torvalds1da177e2005-04-16 15:20:36 -0700696 struct st_partstat *STps;
697
698 result = write_behind_check(STp);
699 if (result)
700 return result;
701
702 result = 0;
703 if (STp->dirty == 1) {
704
Kai Makisara786231a2008-07-11 15:06:40 +0300705 transfer = STp->buffer->buffer_bytes;
Linus Torvalds1da177e2005-04-16 15:20:36 -0700706 DEBC(printk(ST_DEB_MSG "%s: Flushing %d bytes.\n",
707 tape_name(STp), transfer));
708
Linus Torvalds1da177e2005-04-16 15:20:36 -0700709 memset(cmd, 0, MAX_COMMAND_SIZE);
710 cmd[0] = WRITE_6;
711 cmd[1] = 1;
712 blks = transfer / STp->block_size;
713 cmd[2] = blks >> 16;
714 cmd[3] = blks >> 8;
715 cmd[4] = blks;
716
717 SRpnt = st_do_scsi(NULL, STp, cmd, transfer, DMA_TO_DEVICE,
James Bottomleya02488e2008-11-30 10:36:26 -0600718 STp->device->request_queue->rq_timeout,
719 MAX_WRITE_RETRIES, 1);
Linus Torvalds1da177e2005-04-16 15:20:36 -0700720 if (!SRpnt)
721 return (STp->buffer)->syscall_result;
722
723 STps = &(STp->ps[STp->partition]);
724 if ((STp->buffer)->syscall_result != 0) {
725 struct st_cmdstatus *cmdstatp = &STp->buffer->cmdstat;
726
727 if (cmdstatp->have_sense && !cmdstatp->deferred &&
728 (cmdstatp->flags & SENSE_EOM) &&
729 (cmdstatp->sense_hdr.sense_key == NO_SENSE ||
730 cmdstatp->sense_hdr.sense_key == RECOVERED_ERROR) &&
731 (!cmdstatp->remainder_valid ||
732 cmdstatp->uremainder64 == 0)) { /* All written at EOM early warning */
733 STp->dirty = 0;
734 (STp->buffer)->buffer_bytes = 0;
735 if (STps->drv_block >= 0)
736 STps->drv_block += blks;
737 result = (-ENOSPC);
738 } else {
739 printk(KERN_ERR "%s: Error on flush.\n",
740 tape_name(STp));
741 STps->drv_block = (-1);
742 result = (-EIO);
743 }
744 } else {
745 if (STps->drv_block >= 0)
746 STps->drv_block += blks;
747 STp->dirty = 0;
748 (STp->buffer)->buffer_bytes = 0;
749 }
Mike Christie8b05b772005-11-08 04:06:44 -0600750 st_release_request(SRpnt);
Linus Torvalds1da177e2005-04-16 15:20:36 -0700751 SRpnt = NULL;
752 }
753 return result;
754}
755
756
757/* Flush the tape buffer. The tape will be positioned correctly unless
758 seek_next is true. */
759static int flush_buffer(struct scsi_tape *STp, int seek_next)
760{
761 int backspace, result;
762 struct st_buffer *STbuffer;
763 struct st_partstat *STps;
764
765 STbuffer = STp->buffer;
766
767 /*
768 * If there was a bus reset, block further access
769 * to this device.
770 */
771 if (STp->pos_unknown)
772 return (-EIO);
773
774 if (STp->ready != ST_READY)
775 return 0;
776 STps = &(STp->ps[STp->partition]);
777 if (STps->rw == ST_WRITING) /* Writing */
Adrian Bunk8ef8d592008-04-14 17:17:16 +0300778 return st_flush_write_buffer(STp);
Linus Torvalds1da177e2005-04-16 15:20:36 -0700779
780 if (STp->block_size == 0)
781 return 0;
782
783 backspace = ((STp->buffer)->buffer_bytes +
784 (STp->buffer)->read_pointer) / STp->block_size -
785 ((STp->buffer)->read_pointer + STp->block_size - 1) /
786 STp->block_size;
787 (STp->buffer)->buffer_bytes = 0;
788 (STp->buffer)->read_pointer = 0;
789 result = 0;
790 if (!seek_next) {
791 if (STps->eof == ST_FM_HIT) {
792 result = cross_eof(STp, 0); /* Back over the EOF hit */
793 if (!result)
794 STps->eof = ST_NOEOF;
795 else {
796 if (STps->drv_file >= 0)
797 STps->drv_file++;
798 STps->drv_block = 0;
799 }
800 }
801 if (!result && backspace > 0)
802 result = st_int_ioctl(STp, MTBSR, backspace);
803 } else if (STps->eof == ST_FM_HIT) {
804 if (STps->drv_file >= 0)
805 STps->drv_file++;
806 STps->drv_block = 0;
807 STps->eof = ST_NOEOF;
808 }
809 return result;
810
811}
812
813/* Set the mode parameters */
814static int set_mode_densblk(struct scsi_tape * STp, struct st_modedef * STm)
815{
816 int set_it = 0;
817 unsigned long arg;
818 char *name = tape_name(STp);
819
820 if (!STp->density_changed &&
821 STm->default_density >= 0 &&
822 STm->default_density != STp->density) {
823 arg = STm->default_density;
824 set_it = 1;
825 } else
826 arg = STp->density;
827 arg <<= MT_ST_DENSITY_SHIFT;
828 if (!STp->blksize_changed &&
829 STm->default_blksize >= 0 &&
830 STm->default_blksize != STp->block_size) {
831 arg |= STm->default_blksize;
832 set_it = 1;
833 } else
834 arg |= STp->block_size;
835 if (set_it &&
836 st_int_ioctl(STp, SET_DENS_AND_BLK, arg)) {
837 printk(KERN_WARNING
838 "%s: Can't set default block size to %d bytes and density %x.\n",
839 name, STm->default_blksize, STm->default_density);
840 if (modes_defined)
841 return (-EINVAL);
842 }
843 return 0;
844}
845
846
Mike Christie8b05b772005-11-08 04:06:44 -0600847/* Lock or unlock the drive door. Don't use when st_request allocated. */
Linus Torvalds1da177e2005-04-16 15:20:36 -0700848static int do_door_lock(struct scsi_tape * STp, int do_lock)
849{
850 int retval, cmd;
851 DEB(char *name = tape_name(STp);)
852
853
854 cmd = do_lock ? SCSI_IOCTL_DOORLOCK : SCSI_IOCTL_DOORUNLOCK;
855 DEBC(printk(ST_DEB_MSG "%s: %socking drive door.\n", name,
856 do_lock ? "L" : "Unl"));
857 retval = scsi_ioctl(STp->device, cmd, NULL);
858 if (!retval) {
859 STp->door_locked = do_lock ? ST_LOCKED_EXPLICIT : ST_UNLOCKED;
860 }
861 else {
862 STp->door_locked = ST_LOCK_FAILS;
863 }
864 return retval;
865}
866
867
868/* Set the internal state after reset */
869static void reset_state(struct scsi_tape *STp)
870{
871 int i;
872 struct st_partstat *STps;
873
874 STp->pos_unknown = 0;
875 for (i = 0; i < ST_NBR_PARTITIONS; i++) {
876 STps = &(STp->ps[i]);
877 STps->rw = ST_IDLE;
878 STps->eof = ST_NOEOF;
879 STps->at_sm = 0;
880 STps->last_block_valid = 0;
881 STps->drv_block = -1;
882 STps->drv_file = -1;
883 }
884 if (STp->can_partitions) {
885 STp->partition = find_partition(STp);
886 if (STp->partition < 0)
887 STp->partition = 0;
888 STp->new_partition = STp->partition;
889 }
890}
891
892/* Test if the drive is ready. Returns either one of the codes below or a negative system
893 error code. */
894#define CHKRES_READY 0
895#define CHKRES_NEW_SESSION 1
896#define CHKRES_NOT_READY 2
897#define CHKRES_NO_TAPE 3
898
899#define MAX_ATTENTIONS 10
900
901static int test_ready(struct scsi_tape *STp, int do_wait)
902{
903 int attentions, waits, max_wait, scode;
904 int retval = CHKRES_READY, new_session = 0;
905 unsigned char cmd[MAX_COMMAND_SIZE];
Kai Makisara02ae2c02008-12-18 14:49:50 +0900906 struct st_request *SRpnt = NULL;
Linus Torvalds1da177e2005-04-16 15:20:36 -0700907 struct st_cmdstatus *cmdstatp = &STp->buffer->cmdstat;
908
909 max_wait = do_wait ? ST_BLOCK_SECONDS : 0;
910
911 for (attentions=waits=0; ; ) {
912 memset((void *) &cmd[0], 0, MAX_COMMAND_SIZE);
913 cmd[0] = TEST_UNIT_READY;
Kai Makisara02ae2c02008-12-18 14:49:50 +0900914 SRpnt = st_do_scsi(SRpnt, STp, cmd, 0, DMA_NONE,
915 STp->long_timeout, MAX_READY_RETRIES, 1);
Linus Torvalds1da177e2005-04-16 15:20:36 -0700916
Kai Makisara02ae2c02008-12-18 14:49:50 +0900917 if (!SRpnt) {
918 retval = (STp->buffer)->syscall_result;
Linus Torvalds1da177e2005-04-16 15:20:36 -0700919 break;
Kai Makisara02ae2c02008-12-18 14:49:50 +0900920 }
Linus Torvalds1da177e2005-04-16 15:20:36 -0700921
922 if (cmdstatp->have_sense) {
923
924 scode = cmdstatp->sense_hdr.sense_key;
925
926 if (scode == UNIT_ATTENTION) { /* New media? */
927 new_session = 1;
928 if (attentions < MAX_ATTENTIONS) {
929 attentions++;
930 continue;
931 }
932 else {
933 retval = (-EIO);
934 break;
935 }
936 }
937
938 if (scode == NOT_READY) {
939 if (waits < max_wait) {
940 if (msleep_interruptible(1000)) {
941 retval = (-EINTR);
942 break;
943 }
944 waits++;
945 continue;
946 }
947 else {
948 if ((STp->device)->scsi_level >= SCSI_2 &&
949 cmdstatp->sense_hdr.asc == 0x3a) /* Check ASC */
950 retval = CHKRES_NO_TAPE;
951 else
952 retval = CHKRES_NOT_READY;
953 break;
954 }
955 }
956 }
957
958 retval = (STp->buffer)->syscall_result;
959 if (!retval)
960 retval = new_session ? CHKRES_NEW_SESSION : CHKRES_READY;
961 break;
962 }
963
Kai Makisara02ae2c02008-12-18 14:49:50 +0900964 if (SRpnt != NULL)
965 st_release_request(SRpnt);
Linus Torvalds1da177e2005-04-16 15:20:36 -0700966 return retval;
967}
968
969
970/* See if the drive is ready and gather information about the tape. Return values:
971 < 0 negative error code from errno.h
972 0 drive ready
973 1 drive not ready (possibly no tape)
974*/
975static int check_tape(struct scsi_tape *STp, struct file *filp)
976{
977 int i, retval, new_session = 0, do_wait;
978 unsigned char cmd[MAX_COMMAND_SIZE], saved_cleaning;
979 unsigned short st_flags = filp->f_flags;
Mike Christie8b05b772005-11-08 04:06:44 -0600980 struct st_request *SRpnt = NULL;
Linus Torvalds1da177e2005-04-16 15:20:36 -0700981 struct st_modedef *STm;
982 struct st_partstat *STps;
983 char *name = tape_name(STp);
Josef Sipek7ac62072006-12-08 02:37:37 -0800984 struct inode *inode = filp->f_path.dentry->d_inode;
Linus Torvalds1da177e2005-04-16 15:20:36 -0700985 int mode = TAPE_MODE(inode);
986
987 STp->ready = ST_READY;
988
989 if (mode != STp->current_mode) {
990 DEBC(printk(ST_DEB_MSG "%s: Mode change from %d to %d.\n",
991 name, STp->current_mode, mode));
992 new_session = 1;
993 STp->current_mode = mode;
994 }
995 STm = &(STp->modes[STp->current_mode]);
996
997 saved_cleaning = STp->cleaning_req;
998 STp->cleaning_req = 0;
999
1000 do_wait = ((filp->f_flags & O_NONBLOCK) == 0);
1001 retval = test_ready(STp, do_wait);
1002
1003 if (retval < 0)
1004 goto err_out;
1005
1006 if (retval == CHKRES_NEW_SESSION) {
1007 STp->pos_unknown = 0;
1008 STp->partition = STp->new_partition = 0;
1009 if (STp->can_partitions)
1010 STp->nbr_partitions = 1; /* This guess will be updated later
1011 if necessary */
1012 for (i = 0; i < ST_NBR_PARTITIONS; i++) {
1013 STps = &(STp->ps[i]);
1014 STps->rw = ST_IDLE;
1015 STps->eof = ST_NOEOF;
1016 STps->at_sm = 0;
1017 STps->last_block_valid = 0;
1018 STps->drv_block = 0;
1019 STps->drv_file = 0;
1020 }
1021 new_session = 1;
1022 }
1023 else {
1024 STp->cleaning_req |= saved_cleaning;
1025
1026 if (retval == CHKRES_NOT_READY || retval == CHKRES_NO_TAPE) {
1027 if (retval == CHKRES_NO_TAPE)
1028 STp->ready = ST_NO_TAPE;
1029 else
1030 STp->ready = ST_NOT_READY;
1031
1032 STp->density = 0; /* Clear the erroneous "residue" */
1033 STp->write_prot = 0;
1034 STp->block_size = 0;
1035 STp->ps[0].drv_file = STp->ps[0].drv_block = (-1);
1036 STp->partition = STp->new_partition = 0;
1037 STp->door_locked = ST_UNLOCKED;
1038 return CHKRES_NOT_READY;
1039 }
1040 }
1041
1042 if (STp->omit_blklims)
1043 STp->min_block = STp->max_block = (-1);
1044 else {
1045 memset((void *) &cmd[0], 0, MAX_COMMAND_SIZE);
1046 cmd[0] = READ_BLOCK_LIMITS;
1047
Kai Makisara02ae2c02008-12-18 14:49:50 +09001048 SRpnt = st_do_scsi(SRpnt, STp, cmd, 6, DMA_FROM_DEVICE,
1049 STp->device->request_queue->rq_timeout,
1050 MAX_READY_RETRIES, 1);
1051 if (!SRpnt) {
1052 retval = (STp->buffer)->syscall_result;
Linus Torvalds1da177e2005-04-16 15:20:36 -07001053 goto err_out;
1054 }
1055
Mike Christie8b05b772005-11-08 04:06:44 -06001056 if (!SRpnt->result && !STp->buffer->cmdstat.have_sense) {
Linus Torvalds1da177e2005-04-16 15:20:36 -07001057 STp->max_block = ((STp->buffer)->b_data[1] << 16) |
1058 ((STp->buffer)->b_data[2] << 8) | (STp->buffer)->b_data[3];
1059 STp->min_block = ((STp->buffer)->b_data[4] << 8) |
1060 (STp->buffer)->b_data[5];
1061 if ( DEB( debugging || ) !STp->inited)
Kai Makisara422528542006-11-07 21:56:38 +02001062 printk(KERN_INFO
Linus Torvalds1da177e2005-04-16 15:20:36 -07001063 "%s: Block limits %d - %d bytes.\n", name,
1064 STp->min_block, STp->max_block);
1065 } else {
1066 STp->min_block = STp->max_block = (-1);
1067 DEBC(printk(ST_DEB_MSG "%s: Can't read block limits.\n",
1068 name));
1069 }
1070 }
1071
1072 memset((void *) &cmd[0], 0, MAX_COMMAND_SIZE);
1073 cmd[0] = MODE_SENSE;
1074 cmd[4] = 12;
1075
Kai Makisara02ae2c02008-12-18 14:49:50 +09001076 SRpnt = st_do_scsi(SRpnt, STp, cmd, 12, DMA_FROM_DEVICE,
1077 STp->device->request_queue->rq_timeout,
1078 MAX_READY_RETRIES, 1);
1079 if (!SRpnt) {
1080 retval = (STp->buffer)->syscall_result;
Linus Torvalds1da177e2005-04-16 15:20:36 -07001081 goto err_out;
1082 }
1083
1084 if ((STp->buffer)->syscall_result != 0) {
1085 DEBC(printk(ST_DEB_MSG "%s: No Mode Sense.\n", name));
1086 STp->block_size = ST_DEFAULT_BLOCK; /* Educated guess (?) */
1087 (STp->buffer)->syscall_result = 0; /* Prevent error propagation */
1088 STp->drv_write_prot = 0;
1089 } else {
1090 DEBC(printk(ST_DEB_MSG
1091 "%s: Mode sense. Length %d, medium %x, WBS %x, BLL %d\n",
1092 name,
1093 (STp->buffer)->b_data[0], (STp->buffer)->b_data[1],
1094 (STp->buffer)->b_data[2], (STp->buffer)->b_data[3]));
1095
1096 if ((STp->buffer)->b_data[3] >= 8) {
1097 STp->drv_buffer = ((STp->buffer)->b_data[2] >> 4) & 7;
1098 STp->density = (STp->buffer)->b_data[4];
1099 STp->block_size = (STp->buffer)->b_data[9] * 65536 +
1100 (STp->buffer)->b_data[10] * 256 + (STp->buffer)->b_data[11];
1101 DEBC(printk(ST_DEB_MSG
1102 "%s: Density %x, tape length: %x, drv buffer: %d\n",
1103 name, STp->density, (STp->buffer)->b_data[5] * 65536 +
1104 (STp->buffer)->b_data[6] * 256 + (STp->buffer)->b_data[7],
1105 STp->drv_buffer));
1106 }
1107 STp->drv_write_prot = ((STp->buffer)->b_data[2] & 0x80) != 0;
Lee Duncanc743e442012-03-01 12:41:01 -08001108 if (!STp->drv_buffer && STp->immediate_filemark) {
1109 printk(KERN_WARNING
1110 "%s: non-buffered tape: disabling writing immediate filemarks\n",
1111 name);
1112 STp->immediate_filemark = 0;
1113 }
Linus Torvalds1da177e2005-04-16 15:20:36 -07001114 }
Mike Christie8b05b772005-11-08 04:06:44 -06001115 st_release_request(SRpnt);
Linus Torvalds1da177e2005-04-16 15:20:36 -07001116 SRpnt = NULL;
1117 STp->inited = 1;
1118
1119 if (STp->block_size > 0)
1120 (STp->buffer)->buffer_blocks =
1121 (STp->buffer)->buffer_size / STp->block_size;
1122 else
1123 (STp->buffer)->buffer_blocks = 1;
1124 (STp->buffer)->buffer_bytes = (STp->buffer)->read_pointer = 0;
1125
1126 DEBC(printk(ST_DEB_MSG
1127 "%s: Block size: %d, buffer size: %d (%d blocks).\n", name,
1128 STp->block_size, (STp->buffer)->buffer_size,
1129 (STp->buffer)->buffer_blocks));
1130
1131 if (STp->drv_write_prot) {
1132 STp->write_prot = 1;
1133
1134 DEBC(printk(ST_DEB_MSG "%s: Write protected\n", name));
1135
1136 if (do_wait &&
1137 ((st_flags & O_ACCMODE) == O_WRONLY ||
1138 (st_flags & O_ACCMODE) == O_RDWR)) {
1139 retval = (-EROFS);
1140 goto err_out;
1141 }
1142 }
1143
1144 if (STp->can_partitions && STp->nbr_partitions < 1) {
1145 /* This code is reached when the device is opened for the first time
1146 after the driver has been initialized with tape in the drive and the
1147 partition support has been enabled. */
1148 DEBC(printk(ST_DEB_MSG
1149 "%s: Updating partition number in status.\n", name));
1150 if ((STp->partition = find_partition(STp)) < 0) {
1151 retval = STp->partition;
1152 goto err_out;
1153 }
1154 STp->new_partition = STp->partition;
1155 STp->nbr_partitions = 1; /* This guess will be updated when necessary */
1156 }
1157
1158 if (new_session) { /* Change the drive parameters for the new mode */
1159 STp->density_changed = STp->blksize_changed = 0;
1160 STp->compression_changed = 0;
1161 if (!(STm->defaults_for_writes) &&
1162 (retval = set_mode_densblk(STp, STm)) < 0)
1163 goto err_out;
1164
1165 if (STp->default_drvbuffer != 0xff) {
1166 if (st_int_ioctl(STp, MTSETDRVBUFFER, STp->default_drvbuffer))
1167 printk(KERN_WARNING
1168 "%s: Can't set default drive buffering to %d.\n",
1169 name, STp->default_drvbuffer);
1170 }
1171 }
1172
1173 return CHKRES_READY;
1174
1175 err_out:
1176 return retval;
1177}
1178
1179
Jonathan Corbetb3369c62008-05-15 16:08:15 -06001180 /* Open the device. Needs to take the BKL only because of incrementing the SCSI host
Linus Torvalds1da177e2005-04-16 15:20:36 -07001181 module count. */
1182static int st_open(struct inode *inode, struct file *filp)
1183{
1184 int i, retval = (-EIO);
Oliver Neukum46a243f2012-01-15 00:16:51 +01001185 int resumed = 0;
Linus Torvalds1da177e2005-04-16 15:20:36 -07001186 struct scsi_tape *STp;
1187 struct st_partstat *STps;
1188 int dev = TAPE_NR(inode);
1189 char *name;
1190
Arnd Bergmann2a48fc02010-06-02 14:28:52 +02001191 mutex_lock(&st_mutex);
Linus Torvalds1da177e2005-04-16 15:20:36 -07001192 /*
1193 * We really want to do nonseekable_open(inode, filp); here, but some
1194 * versions of tar incorrectly call lseek on tapes and bail out if that
1195 * fails. So we disallow pread() and pwrite(), but permit lseeks.
1196 */
1197 filp->f_mode &= ~(FMODE_PREAD | FMODE_PWRITE);
1198
Jonathan Corbetb3369c62008-05-15 16:08:15 -06001199 if (!(STp = scsi_tape_get(dev))) {
Arnd Bergmann2a48fc02010-06-02 14:28:52 +02001200 mutex_unlock(&st_mutex);
Kai Makisaraf03a5672005-08-02 13:40:47 +03001201 return -ENXIO;
Jonathan Corbetb3369c62008-05-15 16:08:15 -06001202 }
Kai Makisaraf03a5672005-08-02 13:40:47 +03001203
Linus Torvalds1da177e2005-04-16 15:20:36 -07001204 write_lock(&st_dev_arr_lock);
Linus Torvalds1da177e2005-04-16 15:20:36 -07001205 filp->private_data = STp;
1206 name = tape_name(STp);
1207
1208 if (STp->in_use) {
1209 write_unlock(&st_dev_arr_lock);
Kai Makisaraf03a5672005-08-02 13:40:47 +03001210 scsi_tape_put(STp);
Arnd Bergmann2a48fc02010-06-02 14:28:52 +02001211 mutex_unlock(&st_mutex);
Linus Torvalds1da177e2005-04-16 15:20:36 -07001212 DEB( printk(ST_DEB_MSG "%s: Device already in use.\n", name); )
1213 return (-EBUSY);
1214 }
1215
Linus Torvalds1da177e2005-04-16 15:20:36 -07001216 STp->in_use = 1;
1217 write_unlock(&st_dev_arr_lock);
1218 STp->rew_at_close = STp->autorew_dev = (iminor(inode) & 0x80) == 0;
1219
Oliver Neukum46a243f2012-01-15 00:16:51 +01001220 if (scsi_autopm_get_device(STp->device) < 0) {
1221 retval = -EIO;
1222 goto err_out;
1223 }
1224 resumed = 1;
Linus Torvalds1da177e2005-04-16 15:20:36 -07001225 if (!scsi_block_when_processing_errors(STp->device)) {
1226 retval = (-ENXIO);
1227 goto err_out;
1228 }
1229
1230 /* See that we have at least a one page buffer available */
1231 if (!enlarge_buffer(STp->buffer, PAGE_SIZE, STp->restr_dma)) {
1232 printk(KERN_WARNING "%s: Can't allocate one page tape buffer.\n",
1233 name);
1234 retval = (-EOVERFLOW);
1235 goto err_out;
1236 }
1237
Kai Makisara40f6b362008-02-24 22:23:24 +02001238 (STp->buffer)->cleared = 0;
Linus Torvalds1da177e2005-04-16 15:20:36 -07001239 (STp->buffer)->writing = 0;
1240 (STp->buffer)->syscall_result = 0;
1241
1242 STp->write_prot = ((filp->f_flags & O_ACCMODE) == O_RDONLY);
1243
1244 STp->dirty = 0;
1245 for (i = 0; i < ST_NBR_PARTITIONS; i++) {
1246 STps = &(STp->ps[i]);
1247 STps->rw = ST_IDLE;
1248 }
Kai Makisara9abe16c2007-02-03 13:21:29 +02001249 STp->try_dio_now = STp->try_dio;
Linus Torvalds1da177e2005-04-16 15:20:36 -07001250 STp->recover_count = 0;
1251 DEB( STp->nbr_waits = STp->nbr_finished = 0;
Kai Makisaradeee13d2008-02-22 20:11:21 +02001252 STp->nbr_requests = STp->nbr_dio = STp->nbr_pages = 0; )
Linus Torvalds1da177e2005-04-16 15:20:36 -07001253
1254 retval = check_tape(STp, filp);
1255 if (retval < 0)
1256 goto err_out;
1257 if ((filp->f_flags & O_NONBLOCK) == 0 &&
1258 retval != CHKRES_READY) {
Kai Makisara413f7322006-10-05 22:59:46 +03001259 if (STp->ready == NO_TAPE)
1260 retval = (-ENOMEDIUM);
1261 else
1262 retval = (-EIO);
Linus Torvalds1da177e2005-04-16 15:20:36 -07001263 goto err_out;
1264 }
Arnd Bergmann2a48fc02010-06-02 14:28:52 +02001265 mutex_unlock(&st_mutex);
Linus Torvalds1da177e2005-04-16 15:20:36 -07001266 return 0;
1267
1268 err_out:
1269 normalize_buffer(STp->buffer);
1270 STp->in_use = 0;
Kai Makisaraf03a5672005-08-02 13:40:47 +03001271 scsi_tape_put(STp);
Oliver Neukum46a243f2012-01-15 00:16:51 +01001272 if (resumed)
1273 scsi_autopm_put_device(STp->device);
Arnd Bergmann2a48fc02010-06-02 14:28:52 +02001274 mutex_unlock(&st_mutex);
Linus Torvalds1da177e2005-04-16 15:20:36 -07001275 return retval;
1276
1277}
1278
1279
1280/* Flush the tape buffer before close */
Miklos Szeredi75e1fcc2006-06-23 02:05:12 -07001281static int st_flush(struct file *filp, fl_owner_t id)
Linus Torvalds1da177e2005-04-16 15:20:36 -07001282{
1283 int result = 0, result2;
1284 unsigned char cmd[MAX_COMMAND_SIZE];
Mike Christie8b05b772005-11-08 04:06:44 -06001285 struct st_request *SRpnt;
Linus Torvalds1da177e2005-04-16 15:20:36 -07001286 struct scsi_tape *STp = filp->private_data;
1287 struct st_modedef *STm = &(STp->modes[STp->current_mode]);
1288 struct st_partstat *STps = &(STp->ps[STp->partition]);
1289 char *name = tape_name(STp);
1290
1291 if (file_count(filp) > 1)
1292 return 0;
1293
1294 if (STps->rw == ST_WRITING && !STp->pos_unknown) {
Adrian Bunk8ef8d592008-04-14 17:17:16 +03001295 result = st_flush_write_buffer(STp);
Linus Torvalds1da177e2005-04-16 15:20:36 -07001296 if (result != 0 && result != (-ENOSPC))
1297 goto out;
1298 }
1299
1300 if (STp->can_partitions &&
1301 (result2 = switch_partition(STp)) < 0) {
1302 DEBC(printk(ST_DEB_MSG
1303 "%s: switch_partition at close failed.\n", name));
1304 if (result == 0)
1305 result = result2;
1306 goto out;
1307 }
1308
1309 DEBC( if (STp->nbr_requests)
Kai Makisaradeee13d2008-02-22 20:11:21 +02001310 printk(KERN_DEBUG "%s: Number of r/w requests %d, dio used in %d, pages %d.\n",
1311 name, STp->nbr_requests, STp->nbr_dio, STp->nbr_pages));
Linus Torvalds1da177e2005-04-16 15:20:36 -07001312
1313 if (STps->rw == ST_WRITING && !STp->pos_unknown) {
1314 struct st_cmdstatus *cmdstatp = &STp->buffer->cmdstat;
1315
1316 DEBC(printk(ST_DEB_MSG "%s: Async write waits %d, finished %d.\n",
1317 name, STp->nbr_waits, STp->nbr_finished);
1318 )
1319
1320 memset(cmd, 0, MAX_COMMAND_SIZE);
1321 cmd[0] = WRITE_FILEMARKS;
Lee Duncanc743e442012-03-01 12:41:01 -08001322 if (STp->immediate_filemark)
1323 cmd[1] = 1;
Linus Torvalds1da177e2005-04-16 15:20:36 -07001324 cmd[4] = 1 + STp->two_fm;
1325
Kai Makisara02ae2c02008-12-18 14:49:50 +09001326 SRpnt = st_do_scsi(NULL, STp, cmd, 0, DMA_NONE,
1327 STp->device->request_queue->rq_timeout,
1328 MAX_WRITE_RETRIES, 1);
Linus Torvalds1da177e2005-04-16 15:20:36 -07001329 if (!SRpnt) {
Kai Makisara02ae2c02008-12-18 14:49:50 +09001330 result = (STp->buffer)->syscall_result;
Linus Torvalds1da177e2005-04-16 15:20:36 -07001331 goto out;
1332 }
1333
1334 if (STp->buffer->syscall_result == 0 ||
1335 (cmdstatp->have_sense && !cmdstatp->deferred &&
1336 (cmdstatp->flags & SENSE_EOM) &&
1337 (cmdstatp->sense_hdr.sense_key == NO_SENSE ||
1338 cmdstatp->sense_hdr.sense_key == RECOVERED_ERROR) &&
1339 (!cmdstatp->remainder_valid || cmdstatp->uremainder64 == 0))) {
1340 /* Write successful at EOM */
Mike Christie8b05b772005-11-08 04:06:44 -06001341 st_release_request(SRpnt);
Linus Torvalds1da177e2005-04-16 15:20:36 -07001342 SRpnt = NULL;
1343 if (STps->drv_file >= 0)
1344 STps->drv_file++;
1345 STps->drv_block = 0;
1346 if (STp->two_fm)
1347 cross_eof(STp, 0);
1348 STps->eof = ST_FM;
1349 }
1350 else { /* Write error */
Mike Christie8b05b772005-11-08 04:06:44 -06001351 st_release_request(SRpnt);
Linus Torvalds1da177e2005-04-16 15:20:36 -07001352 SRpnt = NULL;
1353 printk(KERN_ERR "%s: Error on write filemark.\n", name);
1354 if (result == 0)
1355 result = (-EIO);
1356 }
1357
1358 DEBC(printk(ST_DEB_MSG "%s: Buffer flushed, %d EOF(s) written\n",
1359 name, cmd[4]));
1360 } else if (!STp->rew_at_close) {
1361 STps = &(STp->ps[STp->partition]);
1362 if (!STm->sysv || STps->rw != ST_READING) {
1363 if (STp->can_bsr)
1364 result = flush_buffer(STp, 0);
1365 else if (STps->eof == ST_FM_HIT) {
1366 result = cross_eof(STp, 0);
1367 if (result) {
1368 if (STps->drv_file >= 0)
1369 STps->drv_file++;
1370 STps->drv_block = 0;
1371 STps->eof = ST_FM;
1372 } else
1373 STps->eof = ST_NOEOF;
1374 }
1375 } else if ((STps->eof == ST_NOEOF &&
1376 !(result = cross_eof(STp, 1))) ||
1377 STps->eof == ST_FM_HIT) {
1378 if (STps->drv_file >= 0)
1379 STps->drv_file++;
1380 STps->drv_block = 0;
1381 STps->eof = ST_FM;
1382 }
1383 }
1384
1385 out:
1386 if (STp->rew_at_close) {
1387 result2 = st_int_ioctl(STp, MTREW, 1);
1388 if (result == 0)
1389 result = result2;
1390 }
1391 return result;
1392}
1393
1394
1395/* Close the device and release it. BKL is not needed: this is the only thread
1396 accessing this tape. */
1397static int st_release(struct inode *inode, struct file *filp)
1398{
1399 int result = 0;
1400 struct scsi_tape *STp = filp->private_data;
1401
1402 if (STp->door_locked == ST_LOCKED_AUTO)
1403 do_door_lock(STp, 0);
1404
1405 normalize_buffer(STp->buffer);
1406 write_lock(&st_dev_arr_lock);
1407 STp->in_use = 0;
1408 write_unlock(&st_dev_arr_lock);
Oliver Neukum46a243f2012-01-15 00:16:51 +01001409 scsi_autopm_put_device(STp->device);
Kai Makisaraf03a5672005-08-02 13:40:47 +03001410 scsi_tape_put(STp);
Linus Torvalds1da177e2005-04-16 15:20:36 -07001411
1412 return result;
1413}
1414
1415/* The checks common to both reading and writing */
1416static ssize_t rw_checks(struct scsi_tape *STp, struct file *filp, size_t count)
1417{
1418 ssize_t retval = 0;
1419
1420 /*
1421 * If we are in the middle of error recovery, don't let anyone
1422 * else try and use this device. Also, if error recovery fails, it
1423 * may try and take the device offline, in which case all further
1424 * access to the device is prohibited.
1425 */
1426 if (!scsi_block_when_processing_errors(STp->device)) {
1427 retval = (-ENXIO);
1428 goto out;
1429 }
1430
1431 if (STp->ready != ST_READY) {
1432 if (STp->ready == ST_NO_TAPE)
1433 retval = (-ENOMEDIUM);
1434 else
1435 retval = (-EIO);
1436 goto out;
1437 }
1438
1439 if (! STp->modes[STp->current_mode].defined) {
1440 retval = (-ENXIO);
1441 goto out;
1442 }
1443
1444
1445 /*
1446 * If there was a bus reset, block further access
1447 * to this device.
1448 */
1449 if (STp->pos_unknown) {
1450 retval = (-EIO);
1451 goto out;
1452 }
1453
1454 if (count == 0)
1455 goto out;
1456
1457 DEB(
1458 if (!STp->in_use) {
1459 printk(ST_DEB_MSG "%s: Incorrect device.\n", tape_name(STp));
1460 retval = (-EIO);
1461 goto out;
1462 } ) /* end DEB */
1463
1464 if (STp->can_partitions &&
1465 (retval = switch_partition(STp)) < 0)
1466 goto out;
1467
1468 if (STp->block_size == 0 && STp->max_block > 0 &&
1469 (count < STp->min_block || count > STp->max_block)) {
1470 retval = (-EINVAL);
1471 goto out;
1472 }
1473
1474 if (STp->do_auto_lock && STp->door_locked == ST_UNLOCKED &&
1475 !do_door_lock(STp, 1))
1476 STp->door_locked = ST_LOCKED_AUTO;
1477
1478 out:
1479 return retval;
1480}
1481
1482
1483static int setup_buffering(struct scsi_tape *STp, const char __user *buf,
1484 size_t count, int is_read)
1485{
1486 int i, bufsize, retval = 0;
1487 struct st_buffer *STbp = STp->buffer;
1488
1489 if (is_read)
Kai Makisara9abe16c2007-02-03 13:21:29 +02001490 i = STp->try_dio_now && try_rdio;
Linus Torvalds1da177e2005-04-16 15:20:36 -07001491 else
Kai Makisara9abe16c2007-02-03 13:21:29 +02001492 i = STp->try_dio_now && try_wdio;
Mike Christie8b05b772005-11-08 04:06:44 -06001493
Linus Torvalds1da177e2005-04-16 15:20:36 -07001494 if (i && ((unsigned long)buf & queue_dma_alignment(
1495 STp->device->request_queue)) == 0) {
FUJITA Tomonori66207422008-12-18 14:49:43 +09001496 i = sgl_map_user_pages(STbp, STbp->use_sg, (unsigned long)buf,
1497 count, (is_read ? READ : WRITE));
Linus Torvalds1da177e2005-04-16 15:20:36 -07001498 if (i > 0) {
1499 STbp->do_dio = i;
1500 STbp->buffer_bytes = 0; /* can be used as transfer counter */
1501 }
1502 else
1503 STbp->do_dio = 0; /* fall back to buffering with any error */
1504 STbp->sg_segs = STbp->do_dio;
Linus Torvalds1da177e2005-04-16 15:20:36 -07001505 DEB(
1506 if (STbp->do_dio) {
1507 STp->nbr_dio++;
1508 STp->nbr_pages += STbp->do_dio;
Linus Torvalds1da177e2005-04-16 15:20:36 -07001509 }
1510 )
1511 } else
1512 STbp->do_dio = 0;
1513 DEB( STp->nbr_requests++; )
1514
1515 if (!STbp->do_dio) {
1516 if (STp->block_size)
1517 bufsize = STp->block_size > st_fixed_buffer_size ?
1518 STp->block_size : st_fixed_buffer_size;
Kai Makisara40f6b362008-02-24 22:23:24 +02001519 else {
Linus Torvalds1da177e2005-04-16 15:20:36 -07001520 bufsize = count;
Kai Makisara40f6b362008-02-24 22:23:24 +02001521 /* Make sure that data from previous user is not leaked even if
1522 HBA does not return correct residual */
1523 if (is_read && STp->sili && !STbp->cleared)
1524 clear_buffer(STbp);
1525 }
1526
Linus Torvalds1da177e2005-04-16 15:20:36 -07001527 if (bufsize > STbp->buffer_size &&
1528 !enlarge_buffer(STbp, bufsize, STp->restr_dma)) {
1529 printk(KERN_WARNING "%s: Can't allocate %d byte tape buffer.\n",
1530 tape_name(STp), bufsize);
1531 retval = (-EOVERFLOW);
1532 goto out;
1533 }
1534 if (STp->block_size)
1535 STbp->buffer_blocks = bufsize / STp->block_size;
1536 }
1537
1538 out:
1539 return retval;
1540}
1541
1542
1543/* Can be called more than once after each setup_buffer() */
Kai Makisara787926b2005-11-13 10:04:44 +02001544static void release_buffering(struct scsi_tape *STp, int is_read)
Linus Torvalds1da177e2005-04-16 15:20:36 -07001545{
1546 struct st_buffer *STbp;
1547
1548 STbp = STp->buffer;
1549 if (STbp->do_dio) {
FUJITA Tomonori66207422008-12-18 14:49:43 +09001550 sgl_unmap_user_pages(STbp, STbp->do_dio, is_read);
Linus Torvalds1da177e2005-04-16 15:20:36 -07001551 STbp->do_dio = 0;
Kai Makisara787926b2005-11-13 10:04:44 +02001552 STbp->sg_segs = 0;
Linus Torvalds1da177e2005-04-16 15:20:36 -07001553 }
1554}
1555
1556
1557/* Write command */
1558static ssize_t
1559st_write(struct file *filp, const char __user *buf, size_t count, loff_t * ppos)
1560{
1561 ssize_t total;
1562 ssize_t i, do_count, blks, transfer;
1563 ssize_t retval;
1564 int undone, retry_eot = 0, scode;
1565 int async_write;
1566 unsigned char cmd[MAX_COMMAND_SIZE];
1567 const char __user *b_point;
Mike Christie8b05b772005-11-08 04:06:44 -06001568 struct st_request *SRpnt = NULL;
Linus Torvalds1da177e2005-04-16 15:20:36 -07001569 struct scsi_tape *STp = filp->private_data;
1570 struct st_modedef *STm;
1571 struct st_partstat *STps;
1572 struct st_buffer *STbp;
1573 char *name = tape_name(STp);
1574
Matthias Kaehlcke28f85002007-07-29 23:38:15 +02001575 if (mutex_lock_interruptible(&STp->lock))
Linus Torvalds1da177e2005-04-16 15:20:36 -07001576 return -ERESTARTSYS;
1577
1578 retval = rw_checks(STp, filp, count);
1579 if (retval || count == 0)
1580 goto out;
1581
1582 /* Write must be integral number of blocks */
1583 if (STp->block_size != 0 && (count % STp->block_size) != 0) {
1584 printk(KERN_WARNING "%s: Write not multiple of tape block size.\n",
1585 name);
1586 retval = (-EINVAL);
1587 goto out;
1588 }
1589
1590 STm = &(STp->modes[STp->current_mode]);
1591 STps = &(STp->ps[STp->partition]);
1592
1593 if (STp->write_prot) {
1594 retval = (-EACCES);
1595 goto out;
1596 }
1597
1598
1599 if (STps->rw == ST_READING) {
1600 retval = flush_buffer(STp, 0);
1601 if (retval)
1602 goto out;
1603 STps->rw = ST_WRITING;
1604 } else if (STps->rw != ST_WRITING &&
1605 STps->drv_file == 0 && STps->drv_block == 0) {
1606 if ((retval = set_mode_densblk(STp, STm)) < 0)
1607 goto out;
1608 if (STm->default_compression != ST_DONT_TOUCH &&
1609 !(STp->compression_changed)) {
1610 if (st_compression(STp, (STm->default_compression == ST_YES))) {
1611 printk(KERN_WARNING "%s: Can't set default compression.\n",
1612 name);
1613 if (modes_defined) {
1614 retval = (-EINVAL);
1615 goto out;
1616 }
1617 }
1618 }
1619 }
1620
1621 STbp = STp->buffer;
1622 i = write_behind_check(STp);
1623 if (i) {
1624 if (i == -ENOSPC)
1625 STps->eof = ST_EOM_OK;
1626 else
1627 STps->eof = ST_EOM_ERROR;
1628 }
1629
1630 if (STps->eof == ST_EOM_OK) {
1631 STps->eof = ST_EOD_1; /* allow next write */
1632 retval = (-ENOSPC);
1633 goto out;
1634 }
1635 else if (STps->eof == ST_EOM_ERROR) {
1636 retval = (-EIO);
1637 goto out;
1638 }
1639
1640 /* Check the buffer readability in cases where copy_user might catch
1641 the problems after some tape movement. */
1642 if (STp->block_size != 0 &&
1643 !STbp->do_dio &&
1644 (copy_from_user(&i, buf, 1) != 0 ||
1645 copy_from_user(&i, buf + count - 1, 1) != 0)) {
1646 retval = (-EFAULT);
1647 goto out;
1648 }
1649
1650 retval = setup_buffering(STp, buf, count, 0);
1651 if (retval)
1652 goto out;
1653
1654 total = count;
1655
1656 memset(cmd, 0, MAX_COMMAND_SIZE);
1657 cmd[0] = WRITE_6;
1658 cmd[1] = (STp->block_size != 0);
1659
1660 STps->rw = ST_WRITING;
1661
1662 b_point = buf;
1663 while (count > 0 && !retry_eot) {
1664
1665 if (STbp->do_dio) {
1666 do_count = count;
1667 }
1668 else {
1669 if (STp->block_size == 0)
1670 do_count = count;
1671 else {
1672 do_count = STbp->buffer_blocks * STp->block_size -
1673 STbp->buffer_bytes;
1674 if (do_count > count)
1675 do_count = count;
1676 }
1677
1678 i = append_to_buffer(b_point, STbp, do_count);
1679 if (i) {
1680 retval = i;
1681 goto out;
1682 }
1683 }
1684 count -= do_count;
1685 b_point += do_count;
1686
1687 async_write = STp->block_size == 0 && !STbp->do_dio &&
1688 STm->do_async_writes && STps->eof < ST_EOM_OK;
1689
1690 if (STp->block_size != 0 && STm->do_buffer_writes &&
Kai Makisara9abe16c2007-02-03 13:21:29 +02001691 !(STp->try_dio_now && try_wdio) && STps->eof < ST_EOM_OK &&
Linus Torvalds1da177e2005-04-16 15:20:36 -07001692 STbp->buffer_bytes < STbp->buffer_size) {
1693 STp->dirty = 1;
1694 /* Don't write a buffer that is not full enough. */
1695 if (!async_write && count == 0)
1696 break;
1697 }
1698
1699 retry_write:
1700 if (STp->block_size == 0)
1701 blks = transfer = do_count;
1702 else {
1703 if (!STbp->do_dio)
1704 blks = STbp->buffer_bytes;
1705 else
1706 blks = do_count;
1707 blks /= STp->block_size;
1708 transfer = blks * STp->block_size;
1709 }
1710 cmd[2] = blks >> 16;
1711 cmd[3] = blks >> 8;
1712 cmd[4] = blks;
1713
1714 SRpnt = st_do_scsi(SRpnt, STp, cmd, transfer, DMA_TO_DEVICE,
James Bottomleya02488e2008-11-30 10:36:26 -06001715 STp->device->request_queue->rq_timeout,
1716 MAX_WRITE_RETRIES, !async_write);
Linus Torvalds1da177e2005-04-16 15:20:36 -07001717 if (!SRpnt) {
1718 retval = STbp->syscall_result;
1719 goto out;
1720 }
Mike Christie8b05b772005-11-08 04:06:44 -06001721 if (async_write && !STbp->syscall_result) {
Linus Torvalds1da177e2005-04-16 15:20:36 -07001722 STbp->writing = transfer;
1723 STp->dirty = !(STbp->writing ==
1724 STbp->buffer_bytes);
1725 SRpnt = NULL; /* Prevent releasing this request! */
1726 DEB( STp->write_pending = 1; )
1727 break;
1728 }
1729
1730 if (STbp->syscall_result != 0) {
1731 struct st_cmdstatus *cmdstatp = &STp->buffer->cmdstat;
1732
1733 DEBC(printk(ST_DEB_MSG "%s: Error on write:\n", name));
1734 if (cmdstatp->have_sense && (cmdstatp->flags & SENSE_EOM)) {
1735 scode = cmdstatp->sense_hdr.sense_key;
1736 if (cmdstatp->remainder_valid)
1737 undone = (int)cmdstatp->uremainder64;
1738 else if (STp->block_size == 0 &&
1739 scode == VOLUME_OVERFLOW)
1740 undone = transfer;
1741 else
1742 undone = 0;
1743 if (STp->block_size != 0)
1744 undone *= STp->block_size;
1745 if (undone <= do_count) {
1746 /* Only data from this write is not written */
1747 count += undone;
Kai Makisara626dcb12008-07-11 15:05:25 +03001748 b_point -= undone;
Linus Torvalds1da177e2005-04-16 15:20:36 -07001749 do_count -= undone;
1750 if (STp->block_size)
1751 blks = (transfer - undone) / STp->block_size;
1752 STps->eof = ST_EOM_OK;
1753 /* Continue in fixed block mode if all written
1754 in this request but still something left to write
1755 (retval left to zero)
1756 */
1757 if (STp->block_size == 0 ||
1758 undone > 0 || count == 0)
1759 retval = (-ENOSPC); /* EOM within current request */
1760 DEBC(printk(ST_DEB_MSG
1761 "%s: EOM with %d bytes unwritten.\n",
1762 name, (int)count));
1763 } else {
1764 /* EOT within data buffered earlier (possible only
1765 in fixed block mode without direct i/o) */
1766 if (!retry_eot && !cmdstatp->deferred &&
1767 (scode == NO_SENSE || scode == RECOVERED_ERROR)) {
1768 move_buffer_data(STp->buffer, transfer - undone);
1769 retry_eot = 1;
1770 if (STps->drv_block >= 0) {
1771 STps->drv_block += (transfer - undone) /
1772 STp->block_size;
1773 }
1774 STps->eof = ST_EOM_OK;
1775 DEBC(printk(ST_DEB_MSG
1776 "%s: Retry write of %d bytes at EOM.\n",
1777 name, STp->buffer->buffer_bytes));
1778 goto retry_write;
1779 }
1780 else {
1781 /* Either error within data buffered by driver or
1782 failed retry */
1783 count -= do_count;
1784 blks = do_count = 0;
1785 STps->eof = ST_EOM_ERROR;
1786 STps->drv_block = (-1); /* Too cautious? */
1787 retval = (-EIO); /* EOM for old data */
1788 DEBC(printk(ST_DEB_MSG
1789 "%s: EOM with lost data.\n",
1790 name));
1791 }
1792 }
1793 } else {
1794 count += do_count;
1795 STps->drv_block = (-1); /* Too cautious? */
Mike Christie8b05b772005-11-08 04:06:44 -06001796 retval = STbp->syscall_result;
Linus Torvalds1da177e2005-04-16 15:20:36 -07001797 }
1798
1799 }
1800
1801 if (STps->drv_block >= 0) {
1802 if (STp->block_size == 0)
1803 STps->drv_block += (do_count > 0);
1804 else
1805 STps->drv_block += blks;
1806 }
1807
1808 STbp->buffer_bytes = 0;
1809 STp->dirty = 0;
1810
1811 if (retval || retry_eot) {
1812 if (count < total)
1813 retval = total - count;
1814 goto out;
1815 }
1816 }
1817
1818 if (STps->eof == ST_EOD_1)
1819 STps->eof = ST_EOM_OK;
1820 else if (STps->eof != ST_EOM_OK)
1821 STps->eof = ST_NOEOF;
1822 retval = total - count;
1823
1824 out:
1825 if (SRpnt != NULL)
Mike Christie8b05b772005-11-08 04:06:44 -06001826 st_release_request(SRpnt);
Kai Makisara787926b2005-11-13 10:04:44 +02001827 release_buffering(STp, 0);
Matthias Kaehlcke28f85002007-07-29 23:38:15 +02001828 mutex_unlock(&STp->lock);
Linus Torvalds1da177e2005-04-16 15:20:36 -07001829
1830 return retval;
1831}
1832
1833/* Read data from the tape. Returns zero in the normal case, one if the
1834 eof status has changed, and the negative error code in case of a
1835 fatal error. Otherwise updates the buffer and the eof state.
1836
1837 Does release user buffer mapping if it is set.
1838*/
1839static long read_tape(struct scsi_tape *STp, long count,
Mike Christie8b05b772005-11-08 04:06:44 -06001840 struct st_request ** aSRpnt)
Linus Torvalds1da177e2005-04-16 15:20:36 -07001841{
1842 int transfer, blks, bytes;
1843 unsigned char cmd[MAX_COMMAND_SIZE];
Mike Christie8b05b772005-11-08 04:06:44 -06001844 struct st_request *SRpnt;
Linus Torvalds1da177e2005-04-16 15:20:36 -07001845 struct st_modedef *STm;
1846 struct st_partstat *STps;
1847 struct st_buffer *STbp;
1848 int retval = 0;
1849 char *name = tape_name(STp);
1850
1851 if (count == 0)
1852 return 0;
1853
1854 STm = &(STp->modes[STp->current_mode]);
1855 STps = &(STp->ps[STp->partition]);
1856 if (STps->eof == ST_FM_HIT)
1857 return 1;
1858 STbp = STp->buffer;
1859
1860 if (STp->block_size == 0)
1861 blks = bytes = count;
1862 else {
Kai Makisara9abe16c2007-02-03 13:21:29 +02001863 if (!(STp->try_dio_now && try_rdio) && STm->do_read_ahead) {
Linus Torvalds1da177e2005-04-16 15:20:36 -07001864 blks = (STp->buffer)->buffer_blocks;
1865 bytes = blks * STp->block_size;
1866 } else {
1867 bytes = count;
1868 if (!STbp->do_dio && bytes > (STp->buffer)->buffer_size)
1869 bytes = (STp->buffer)->buffer_size;
1870 blks = bytes / STp->block_size;
1871 bytes = blks * STp->block_size;
1872 }
1873 }
1874
1875 memset(cmd, 0, MAX_COMMAND_SIZE);
1876 cmd[0] = READ_6;
1877 cmd[1] = (STp->block_size != 0);
Kai Makisara40f6b362008-02-24 22:23:24 +02001878 if (!cmd[1] && STp->sili)
1879 cmd[1] |= 2;
Linus Torvalds1da177e2005-04-16 15:20:36 -07001880 cmd[2] = blks >> 16;
1881 cmd[3] = blks >> 8;
1882 cmd[4] = blks;
1883
1884 SRpnt = *aSRpnt;
1885 SRpnt = st_do_scsi(SRpnt, STp, cmd, bytes, DMA_FROM_DEVICE,
James Bottomleya02488e2008-11-30 10:36:26 -06001886 STp->device->request_queue->rq_timeout,
1887 MAX_RETRIES, 1);
Kai Makisara787926b2005-11-13 10:04:44 +02001888 release_buffering(STp, 1);
Linus Torvalds1da177e2005-04-16 15:20:36 -07001889 *aSRpnt = SRpnt;
1890 if (!SRpnt)
1891 return STbp->syscall_result;
1892
1893 STbp->read_pointer = 0;
1894 STps->at_sm = 0;
1895
1896 /* Something to check */
1897 if (STbp->syscall_result) {
1898 struct st_cmdstatus *cmdstatp = &STp->buffer->cmdstat;
1899
1900 retval = 1;
1901 DEBC(printk(ST_DEB_MSG "%s: Sense: %2x %2x %2x %2x %2x %2x %2x %2x\n",
1902 name,
Mike Christie8b05b772005-11-08 04:06:44 -06001903 SRpnt->sense[0], SRpnt->sense[1],
1904 SRpnt->sense[2], SRpnt->sense[3],
1905 SRpnt->sense[4], SRpnt->sense[5],
1906 SRpnt->sense[6], SRpnt->sense[7]));
Linus Torvalds1da177e2005-04-16 15:20:36 -07001907 if (cmdstatp->have_sense) {
1908
1909 if (cmdstatp->sense_hdr.sense_key == BLANK_CHECK)
1910 cmdstatp->flags &= 0xcf; /* No need for EOM in this case */
1911
1912 if (cmdstatp->flags != 0) { /* EOF, EOM, or ILI */
1913 /* Compute the residual count */
1914 if (cmdstatp->remainder_valid)
1915 transfer = (int)cmdstatp->uremainder64;
1916 else
1917 transfer = 0;
1918 if (STp->block_size == 0 &&
1919 cmdstatp->sense_hdr.sense_key == MEDIUM_ERROR)
1920 transfer = bytes;
1921
1922 if (cmdstatp->flags & SENSE_ILI) { /* ILI */
1923 if (STp->block_size == 0) {
1924 if (transfer <= 0) {
1925 if (transfer < 0)
1926 printk(KERN_NOTICE
1927 "%s: Failed to read %d byte block with %d byte transfer.\n",
1928 name, bytes - transfer, bytes);
1929 if (STps->drv_block >= 0)
1930 STps->drv_block += 1;
1931 STbp->buffer_bytes = 0;
1932 return (-ENOMEM);
1933 }
1934 STbp->buffer_bytes = bytes - transfer;
1935 } else {
Mike Christie8b05b772005-11-08 04:06:44 -06001936 st_release_request(SRpnt);
Linus Torvalds1da177e2005-04-16 15:20:36 -07001937 SRpnt = *aSRpnt = NULL;
1938 if (transfer == blks) { /* We did not get anything, error */
1939 printk(KERN_NOTICE "%s: Incorrect block size.\n", name);
1940 if (STps->drv_block >= 0)
1941 STps->drv_block += blks - transfer + 1;
1942 st_int_ioctl(STp, MTBSR, 1);
1943 return (-EIO);
1944 }
1945 /* We have some data, deliver it */
1946 STbp->buffer_bytes = (blks - transfer) *
1947 STp->block_size;
1948 DEBC(printk(ST_DEB_MSG
1949 "%s: ILI but enough data received %ld %d.\n",
1950 name, count, STbp->buffer_bytes));
1951 if (STps->drv_block >= 0)
1952 STps->drv_block += 1;
1953 if (st_int_ioctl(STp, MTBSR, 1))
1954 return (-EIO);
1955 }
1956 } else if (cmdstatp->flags & SENSE_FMK) { /* FM overrides EOM */
1957 if (STps->eof != ST_FM_HIT)
1958 STps->eof = ST_FM_HIT;
1959 else
1960 STps->eof = ST_EOD_2;
1961 if (STp->block_size == 0)
1962 STbp->buffer_bytes = 0;
1963 else
1964 STbp->buffer_bytes =
1965 bytes - transfer * STp->block_size;
1966 DEBC(printk(ST_DEB_MSG
1967 "%s: EOF detected (%d bytes read).\n",
1968 name, STbp->buffer_bytes));
1969 } else if (cmdstatp->flags & SENSE_EOM) {
1970 if (STps->eof == ST_FM)
1971 STps->eof = ST_EOD_1;
1972 else
1973 STps->eof = ST_EOM_OK;
1974 if (STp->block_size == 0)
1975 STbp->buffer_bytes = bytes - transfer;
1976 else
1977 STbp->buffer_bytes =
1978 bytes - transfer * STp->block_size;
1979
1980 DEBC(printk(ST_DEB_MSG "%s: EOM detected (%d bytes read).\n",
1981 name, STbp->buffer_bytes));
1982 }
1983 }
1984 /* end of EOF, EOM, ILI test */
1985 else { /* nonzero sense key */
1986 DEBC(printk(ST_DEB_MSG
1987 "%s: Tape error while reading.\n", name));
1988 STps->drv_block = (-1);
1989 if (STps->eof == ST_FM &&
1990 cmdstatp->sense_hdr.sense_key == BLANK_CHECK) {
1991 DEBC(printk(ST_DEB_MSG
1992 "%s: Zero returned for first BLANK CHECK after EOF.\n",
1993 name));
1994 STps->eof = ST_EOD_2; /* First BLANK_CHECK after FM */
1995 } else /* Some other extended sense code */
1996 retval = (-EIO);
1997 }
1998
1999 if (STbp->buffer_bytes < 0) /* Caused by bogus sense data */
2000 STbp->buffer_bytes = 0;
2001 }
2002 /* End of extended sense test */
2003 else { /* Non-extended sense */
2004 retval = STbp->syscall_result;
2005 }
2006
2007 }
2008 /* End of error handling */
Kai Makisara40f6b362008-02-24 22:23:24 +02002009 else { /* Read successful */
Linus Torvalds1da177e2005-04-16 15:20:36 -07002010 STbp->buffer_bytes = bytes;
Kai Makisara40f6b362008-02-24 22:23:24 +02002011 if (STp->sili) /* In fixed block mode residual is always zero here */
2012 STbp->buffer_bytes -= STp->buffer->cmdstat.residual;
2013 }
Linus Torvalds1da177e2005-04-16 15:20:36 -07002014
2015 if (STps->drv_block >= 0) {
2016 if (STp->block_size == 0)
2017 STps->drv_block++;
2018 else
2019 STps->drv_block += STbp->buffer_bytes / STp->block_size;
2020 }
2021 return retval;
2022}
2023
2024
2025/* Read command */
2026static ssize_t
2027st_read(struct file *filp, char __user *buf, size_t count, loff_t * ppos)
2028{
2029 ssize_t total;
2030 ssize_t retval = 0;
2031 ssize_t i, transfer;
2032 int special, do_dio = 0;
Mike Christie8b05b772005-11-08 04:06:44 -06002033 struct st_request *SRpnt = NULL;
Linus Torvalds1da177e2005-04-16 15:20:36 -07002034 struct scsi_tape *STp = filp->private_data;
2035 struct st_modedef *STm;
2036 struct st_partstat *STps;
2037 struct st_buffer *STbp = STp->buffer;
2038 DEB( char *name = tape_name(STp); )
2039
Matthias Kaehlcke28f85002007-07-29 23:38:15 +02002040 if (mutex_lock_interruptible(&STp->lock))
Linus Torvalds1da177e2005-04-16 15:20:36 -07002041 return -ERESTARTSYS;
2042
2043 retval = rw_checks(STp, filp, count);
2044 if (retval || count == 0)
2045 goto out;
2046
2047 STm = &(STp->modes[STp->current_mode]);
Kai Makisara9abe16c2007-02-03 13:21:29 +02002048 if (STp->block_size != 0 && (count % STp->block_size) != 0) {
2049 if (!STm->do_read_ahead) {
2050 retval = (-EINVAL); /* Read must be integral number of blocks */
2051 goto out;
2052 }
2053 STp->try_dio_now = 0; /* Direct i/o can't handle split blocks */
Linus Torvalds1da177e2005-04-16 15:20:36 -07002054 }
2055
2056 STps = &(STp->ps[STp->partition]);
2057 if (STps->rw == ST_WRITING) {
2058 retval = flush_buffer(STp, 0);
2059 if (retval)
2060 goto out;
2061 STps->rw = ST_READING;
2062 }
2063 DEB(
2064 if (debugging && STps->eof != ST_NOEOF)
2065 printk(ST_DEB_MSG "%s: EOF/EOM flag up (%d). Bytes %d\n", name,
2066 STps->eof, STbp->buffer_bytes);
2067 ) /* end DEB */
2068
2069 retval = setup_buffering(STp, buf, count, 1);
2070 if (retval)
2071 goto out;
2072 do_dio = STbp->do_dio;
2073
2074 if (STbp->buffer_bytes == 0 &&
2075 STps->eof >= ST_EOD_1) {
2076 if (STps->eof < ST_EOD) {
2077 STps->eof += 1;
2078 retval = 0;
2079 goto out;
2080 }
2081 retval = (-EIO); /* EOM or Blank Check */
2082 goto out;
2083 }
2084
2085 if (do_dio) {
2086 /* Check the buffer writability before any tape movement. Don't alter
2087 buffer data. */
2088 if (copy_from_user(&i, buf, 1) != 0 ||
2089 copy_to_user(buf, &i, 1) != 0 ||
2090 copy_from_user(&i, buf + count - 1, 1) != 0 ||
2091 copy_to_user(buf + count - 1, &i, 1) != 0) {
2092 retval = (-EFAULT);
2093 goto out;
2094 }
2095 }
2096
2097 STps->rw = ST_READING;
2098
2099
2100 /* Loop until enough data in buffer or a special condition found */
2101 for (total = 0, special = 0; total < count && !special;) {
2102
2103 /* Get new data if the buffer is empty */
2104 if (STbp->buffer_bytes == 0) {
2105 special = read_tape(STp, count - total, &SRpnt);
2106 if (special < 0) { /* No need to continue read */
2107 retval = special;
2108 goto out;
2109 }
2110 }
2111
2112 /* Move the data from driver buffer to user buffer */
2113 if (STbp->buffer_bytes > 0) {
2114 DEB(
2115 if (debugging && STps->eof != ST_NOEOF)
2116 printk(ST_DEB_MSG
2117 "%s: EOF up (%d). Left %d, needed %d.\n", name,
2118 STps->eof, STbp->buffer_bytes,
2119 (int)(count - total));
2120 ) /* end DEB */
2121 transfer = STbp->buffer_bytes < count - total ?
2122 STbp->buffer_bytes : count - total;
2123 if (!do_dio) {
2124 i = from_buffer(STbp, buf, transfer);
2125 if (i) {
2126 retval = i;
2127 goto out;
2128 }
2129 }
2130 buf += transfer;
2131 total += transfer;
2132 }
2133
2134 if (STp->block_size == 0)
2135 break; /* Read only one variable length block */
2136
2137 } /* for (total = 0, special = 0;
2138 total < count && !special; ) */
2139
2140 /* Change the eof state if no data from tape or buffer */
2141 if (total == 0) {
2142 if (STps->eof == ST_FM_HIT) {
2143 STps->eof = ST_FM;
2144 STps->drv_block = 0;
2145 if (STps->drv_file >= 0)
2146 STps->drv_file++;
2147 } else if (STps->eof == ST_EOD_1) {
2148 STps->eof = ST_EOD_2;
2149 STps->drv_block = 0;
2150 if (STps->drv_file >= 0)
2151 STps->drv_file++;
2152 } else if (STps->eof == ST_EOD_2)
2153 STps->eof = ST_EOD;
2154 } else if (STps->eof == ST_FM)
2155 STps->eof = ST_NOEOF;
2156 retval = total;
2157
2158 out:
2159 if (SRpnt != NULL) {
Mike Christie8b05b772005-11-08 04:06:44 -06002160 st_release_request(SRpnt);
Linus Torvalds1da177e2005-04-16 15:20:36 -07002161 SRpnt = NULL;
2162 }
2163 if (do_dio) {
Kai Makisara787926b2005-11-13 10:04:44 +02002164 release_buffering(STp, 1);
Linus Torvalds1da177e2005-04-16 15:20:36 -07002165 STbp->buffer_bytes = 0;
2166 }
Matthias Kaehlcke28f85002007-07-29 23:38:15 +02002167 mutex_unlock(&STp->lock);
Linus Torvalds1da177e2005-04-16 15:20:36 -07002168
2169 return retval;
2170}
2171
2172
2173
2174DEB(
2175/* Set the driver options */
2176static void st_log_options(struct scsi_tape * STp, struct st_modedef * STm, char *name)
2177{
2178 if (debugging) {
2179 printk(KERN_INFO
2180 "%s: Mode %d options: buffer writes: %d, async writes: %d, read ahead: %d\n",
2181 name, STp->current_mode, STm->do_buffer_writes, STm->do_async_writes,
2182 STm->do_read_ahead);
2183 printk(KERN_INFO
2184 "%s: can bsr: %d, two FMs: %d, fast mteom: %d, auto lock: %d,\n",
2185 name, STp->can_bsr, STp->two_fm, STp->fast_mteom, STp->do_auto_lock);
2186 printk(KERN_INFO
2187 "%s: defs for wr: %d, no block limits: %d, partitions: %d, s2 log: %d\n",
2188 name, STm->defaults_for_writes, STp->omit_blklims, STp->can_partitions,
2189 STp->scsi2_logical);
2190 printk(KERN_INFO
Lee Duncanc743e442012-03-01 12:41:01 -08002191 "%s: sysv: %d nowait: %d sili: %d nowait_filemark: %d\n",
2192 name, STm->sysv, STp->immediate, STp->sili,
2193 STp->immediate_filemark);
Linus Torvalds1da177e2005-04-16 15:20:36 -07002194 printk(KERN_INFO "%s: debugging: %d\n",
2195 name, debugging);
2196 }
2197}
2198 )
2199
2200
2201static int st_set_options(struct scsi_tape *STp, long options)
2202{
2203 int value;
2204 long code;
2205 struct st_modedef *STm;
2206 char *name = tape_name(STp);
2207 struct cdev *cd0, *cd1;
2208
2209 STm = &(STp->modes[STp->current_mode]);
2210 if (!STm->defined) {
2211 cd0 = STm->cdevs[0]; cd1 = STm->cdevs[1];
2212 memcpy(STm, &(STp->modes[0]), sizeof(struct st_modedef));
2213 STm->cdevs[0] = cd0; STm->cdevs[1] = cd1;
2214 modes_defined = 1;
2215 DEBC(printk(ST_DEB_MSG
2216 "%s: Initialized mode %d definition from mode 0\n",
2217 name, STp->current_mode));
2218 }
2219
2220 code = options & MT_ST_OPTIONS;
2221 if (code == MT_ST_BOOLEANS) {
2222 STm->do_buffer_writes = (options & MT_ST_BUFFER_WRITES) != 0;
2223 STm->do_async_writes = (options & MT_ST_ASYNC_WRITES) != 0;
2224 STm->defaults_for_writes = (options & MT_ST_DEF_WRITES) != 0;
2225 STm->do_read_ahead = (options & MT_ST_READ_AHEAD) != 0;
2226 STp->two_fm = (options & MT_ST_TWO_FM) != 0;
2227 STp->fast_mteom = (options & MT_ST_FAST_MTEOM) != 0;
2228 STp->do_auto_lock = (options & MT_ST_AUTO_LOCK) != 0;
2229 STp->can_bsr = (options & MT_ST_CAN_BSR) != 0;
2230 STp->omit_blklims = (options & MT_ST_NO_BLKLIMS) != 0;
2231 if ((STp->device)->scsi_level >= SCSI_2)
2232 STp->can_partitions = (options & MT_ST_CAN_PARTITIONS) != 0;
2233 STp->scsi2_logical = (options & MT_ST_SCSI2LOGICAL) != 0;
2234 STp->immediate = (options & MT_ST_NOWAIT) != 0;
Lee Duncanc743e442012-03-01 12:41:01 -08002235 STp->immediate_filemark = (options & MT_ST_NOWAIT_EOF) != 0;
Linus Torvalds1da177e2005-04-16 15:20:36 -07002236 STm->sysv = (options & MT_ST_SYSV) != 0;
Kai Makisara40f6b362008-02-24 22:23:24 +02002237 STp->sili = (options & MT_ST_SILI) != 0;
Linus Torvalds1da177e2005-04-16 15:20:36 -07002238 DEB( debugging = (options & MT_ST_DEBUGGING) != 0;
2239 st_log_options(STp, STm, name); )
2240 } else if (code == MT_ST_SETBOOLEANS || code == MT_ST_CLEARBOOLEANS) {
2241 value = (code == MT_ST_SETBOOLEANS);
2242 if ((options & MT_ST_BUFFER_WRITES) != 0)
2243 STm->do_buffer_writes = value;
2244 if ((options & MT_ST_ASYNC_WRITES) != 0)
2245 STm->do_async_writes = value;
2246 if ((options & MT_ST_DEF_WRITES) != 0)
2247 STm->defaults_for_writes = value;
2248 if ((options & MT_ST_READ_AHEAD) != 0)
2249 STm->do_read_ahead = value;
2250 if ((options & MT_ST_TWO_FM) != 0)
2251 STp->two_fm = value;
2252 if ((options & MT_ST_FAST_MTEOM) != 0)
2253 STp->fast_mteom = value;
2254 if ((options & MT_ST_AUTO_LOCK) != 0)
2255 STp->do_auto_lock = value;
2256 if ((options & MT_ST_CAN_BSR) != 0)
2257 STp->can_bsr = value;
2258 if ((options & MT_ST_NO_BLKLIMS) != 0)
2259 STp->omit_blklims = value;
2260 if ((STp->device)->scsi_level >= SCSI_2 &&
2261 (options & MT_ST_CAN_PARTITIONS) != 0)
2262 STp->can_partitions = value;
2263 if ((options & MT_ST_SCSI2LOGICAL) != 0)
2264 STp->scsi2_logical = value;
2265 if ((options & MT_ST_NOWAIT) != 0)
2266 STp->immediate = value;
Lee Duncanc743e442012-03-01 12:41:01 -08002267 if ((options & MT_ST_NOWAIT_EOF) != 0)
2268 STp->immediate_filemark = value;
Linus Torvalds1da177e2005-04-16 15:20:36 -07002269 if ((options & MT_ST_SYSV) != 0)
2270 STm->sysv = value;
Kai Makisara40f6b362008-02-24 22:23:24 +02002271 if ((options & MT_ST_SILI) != 0)
2272 STp->sili = value;
Linus Torvalds1da177e2005-04-16 15:20:36 -07002273 DEB(
2274 if ((options & MT_ST_DEBUGGING) != 0)
2275 debugging = value;
2276 st_log_options(STp, STm, name); )
2277 } else if (code == MT_ST_WRITE_THRESHOLD) {
2278 /* Retained for compatibility */
2279 } else if (code == MT_ST_DEF_BLKSIZE) {
2280 value = (options & ~MT_ST_OPTIONS);
2281 if (value == ~MT_ST_OPTIONS) {
2282 STm->default_blksize = (-1);
2283 DEBC( printk(KERN_INFO "%s: Default block size disabled.\n", name));
2284 } else {
2285 STm->default_blksize = value;
2286 DEBC( printk(KERN_INFO "%s: Default block size set to %d bytes.\n",
2287 name, STm->default_blksize));
2288 if (STp->ready == ST_READY) {
2289 STp->blksize_changed = 0;
2290 set_mode_densblk(STp, STm);
2291 }
2292 }
2293 } else if (code == MT_ST_TIMEOUTS) {
2294 value = (options & ~MT_ST_OPTIONS);
2295 if ((value & MT_ST_SET_LONG_TIMEOUT) != 0) {
2296 STp->long_timeout = (value & ~MT_ST_SET_LONG_TIMEOUT) * HZ;
2297 DEBC( printk(KERN_INFO "%s: Long timeout set to %d seconds.\n", name,
2298 (value & ~MT_ST_SET_LONG_TIMEOUT)));
2299 } else {
James Bottomleya02488e2008-11-30 10:36:26 -06002300 blk_queue_rq_timeout(STp->device->request_queue,
2301 value * HZ);
Linus Torvalds1da177e2005-04-16 15:20:36 -07002302 DEBC( printk(KERN_INFO "%s: Normal timeout set to %d seconds.\n",
2303 name, value) );
2304 }
2305 } else if (code == MT_ST_SET_CLN) {
2306 value = (options & ~MT_ST_OPTIONS) & 0xff;
2307 if (value != 0 &&
Roel Kluin832151f2009-11-17 14:53:22 -08002308 (value < EXTENDED_SENSE_START ||
2309 value >= SCSI_SENSE_BUFFERSIZE))
Linus Torvalds1da177e2005-04-16 15:20:36 -07002310 return (-EINVAL);
2311 STp->cln_mode = value;
2312 STp->cln_sense_mask = (options >> 8) & 0xff;
2313 STp->cln_sense_value = (options >> 16) & 0xff;
2314 printk(KERN_INFO
2315 "%s: Cleaning request mode %d, mask %02x, value %02x\n",
2316 name, value, STp->cln_sense_mask, STp->cln_sense_value);
2317 } else if (code == MT_ST_DEF_OPTIONS) {
2318 code = (options & ~MT_ST_CLEAR_DEFAULT);
2319 value = (options & MT_ST_CLEAR_DEFAULT);
2320 if (code == MT_ST_DEF_DENSITY) {
2321 if (value == MT_ST_CLEAR_DEFAULT) {
2322 STm->default_density = (-1);
2323 DEBC( printk(KERN_INFO "%s: Density default disabled.\n",
2324 name));
2325 } else {
2326 STm->default_density = value & 0xff;
2327 DEBC( printk(KERN_INFO "%s: Density default set to %x\n",
2328 name, STm->default_density));
2329 if (STp->ready == ST_READY) {
2330 STp->density_changed = 0;
2331 set_mode_densblk(STp, STm);
2332 }
2333 }
2334 } else if (code == MT_ST_DEF_DRVBUFFER) {
2335 if (value == MT_ST_CLEAR_DEFAULT) {
2336 STp->default_drvbuffer = 0xff;
2337 DEBC( printk(KERN_INFO
2338 "%s: Drive buffer default disabled.\n", name));
2339 } else {
2340 STp->default_drvbuffer = value & 7;
2341 DEBC( printk(KERN_INFO
2342 "%s: Drive buffer default set to %x\n",
2343 name, STp->default_drvbuffer));
2344 if (STp->ready == ST_READY)
2345 st_int_ioctl(STp, MTSETDRVBUFFER, STp->default_drvbuffer);
2346 }
2347 } else if (code == MT_ST_DEF_COMPRESSION) {
2348 if (value == MT_ST_CLEAR_DEFAULT) {
2349 STm->default_compression = ST_DONT_TOUCH;
2350 DEBC( printk(KERN_INFO
2351 "%s: Compression default disabled.\n", name));
2352 } else {
2353 if ((value & 0xff00) != 0) {
2354 STp->c_algo = (value & 0xff00) >> 8;
2355 DEBC( printk(KERN_INFO "%s: Compression algorithm set to 0x%x.\n",
2356 name, STp->c_algo));
2357 }
2358 if ((value & 0xff) != 0xff) {
2359 STm->default_compression = (value & 1 ? ST_YES : ST_NO);
2360 DEBC( printk(KERN_INFO "%s: Compression default set to %x\n",
2361 name, (value & 1)));
2362 if (STp->ready == ST_READY) {
2363 STp->compression_changed = 0;
2364 st_compression(STp, (STm->default_compression == ST_YES));
2365 }
2366 }
2367 }
2368 }
2369 } else
2370 return (-EIO);
2371
2372 return 0;
2373}
2374
2375#define MODE_HEADER_LENGTH 4
2376
2377/* Mode header and page byte offsets */
2378#define MH_OFF_DATA_LENGTH 0
2379#define MH_OFF_MEDIUM_TYPE 1
2380#define MH_OFF_DEV_SPECIFIC 2
2381#define MH_OFF_BDESCS_LENGTH 3
2382#define MP_OFF_PAGE_NBR 0
2383#define MP_OFF_PAGE_LENGTH 1
2384
2385/* Mode header and page bit masks */
2386#define MH_BIT_WP 0x80
2387#define MP_MSK_PAGE_NBR 0x3f
2388
2389/* Don't return block descriptors */
2390#define MODE_SENSE_OMIT_BDESCS 0x08
2391
2392#define MODE_SELECT_PAGE_FORMAT 0x10
2393
2394/* Read a mode page into the tape buffer. The block descriptors are included
2395 if incl_block_descs is true. The page control is ored to the page number
2396 parameter, if necessary. */
2397static int read_mode_page(struct scsi_tape *STp, int page, int omit_block_descs)
2398{
2399 unsigned char cmd[MAX_COMMAND_SIZE];
FUJITA Tomonori8ecf0d92008-12-05 15:25:28 +09002400 struct st_request *SRpnt;
Linus Torvalds1da177e2005-04-16 15:20:36 -07002401
2402 memset(cmd, 0, MAX_COMMAND_SIZE);
2403 cmd[0] = MODE_SENSE;
2404 if (omit_block_descs)
2405 cmd[1] = MODE_SENSE_OMIT_BDESCS;
2406 cmd[2] = page;
2407 cmd[4] = 255;
2408
Kai Makisara02ae2c02008-12-18 14:49:50 +09002409 SRpnt = st_do_scsi(NULL, STp, cmd, cmd[4], DMA_FROM_DEVICE,
2410 STp->device->request_queue->rq_timeout, 0, 1);
2411 if (SRpnt == NULL)
2412 return (STp->buffer)->syscall_result;
Linus Torvalds1da177e2005-04-16 15:20:36 -07002413
Mike Christie8b05b772005-11-08 04:06:44 -06002414 st_release_request(SRpnt);
Linus Torvalds1da177e2005-04-16 15:20:36 -07002415
Kai Makisara02ae2c02008-12-18 14:49:50 +09002416 return STp->buffer->syscall_result;
Linus Torvalds1da177e2005-04-16 15:20:36 -07002417}
2418
2419
2420/* Send the mode page in the tape buffer to the drive. Assumes that the mode data
2421 in the buffer is correctly formatted. The long timeout is used if slow is non-zero. */
2422static int write_mode_page(struct scsi_tape *STp, int page, int slow)
2423{
Kai Makisara02ae2c02008-12-18 14:49:50 +09002424 int pgo;
Linus Torvalds1da177e2005-04-16 15:20:36 -07002425 unsigned char cmd[MAX_COMMAND_SIZE];
FUJITA Tomonori18c87012008-12-05 15:25:29 +09002426 struct st_request *SRpnt;
Kai Makisara02ae2c02008-12-18 14:49:50 +09002427 int timeout;
Linus Torvalds1da177e2005-04-16 15:20:36 -07002428
2429 memset(cmd, 0, MAX_COMMAND_SIZE);
2430 cmd[0] = MODE_SELECT;
2431 cmd[1] = MODE_SELECT_PAGE_FORMAT;
2432 pgo = MODE_HEADER_LENGTH + (STp->buffer)->b_data[MH_OFF_BDESCS_LENGTH];
2433 cmd[4] = pgo + (STp->buffer)->b_data[pgo + MP_OFF_PAGE_LENGTH] + 2;
2434
2435 /* Clear reserved fields */
2436 (STp->buffer)->b_data[MH_OFF_DATA_LENGTH] = 0;
2437 (STp->buffer)->b_data[MH_OFF_MEDIUM_TYPE] = 0;
2438 (STp->buffer)->b_data[MH_OFF_DEV_SPECIFIC] &= ~MH_BIT_WP;
2439 (STp->buffer)->b_data[pgo + MP_OFF_PAGE_NBR] &= MP_MSK_PAGE_NBR;
2440
Kai Makisara02ae2c02008-12-18 14:49:50 +09002441 timeout = slow ?
2442 STp->long_timeout : STp->device->request_queue->rq_timeout;
2443 SRpnt = st_do_scsi(NULL, STp, cmd, cmd[4], DMA_TO_DEVICE,
2444 timeout, 0, 1);
2445 if (SRpnt == NULL)
2446 return (STp->buffer)->syscall_result;
Linus Torvalds1da177e2005-04-16 15:20:36 -07002447
Mike Christie8b05b772005-11-08 04:06:44 -06002448 st_release_request(SRpnt);
Linus Torvalds1da177e2005-04-16 15:20:36 -07002449
Kai Makisara02ae2c02008-12-18 14:49:50 +09002450 return STp->buffer->syscall_result;
Linus Torvalds1da177e2005-04-16 15:20:36 -07002451}
2452
2453
2454#define COMPRESSION_PAGE 0x0f
2455#define COMPRESSION_PAGE_LENGTH 16
2456
2457#define CP_OFF_DCE_DCC 2
2458#define CP_OFF_C_ALGO 7
2459
2460#define DCE_MASK 0x80
2461#define DCC_MASK 0x40
2462#define RED_MASK 0x60
2463
2464
2465/* Control the compression with mode page 15. Algorithm not changed if zero.
2466
2467 The block descriptors are read and written because Sony SDT-7000 does not
2468 work without this (suggestion from Michael Schaefer <Michael.Schaefer@dlr.de>).
2469 Including block descriptors should not cause any harm to other drives. */
2470
2471static int st_compression(struct scsi_tape * STp, int state)
2472{
2473 int retval;
2474 int mpoffs; /* Offset to mode page start */
2475 unsigned char *b_data = (STp->buffer)->b_data;
2476 DEB( char *name = tape_name(STp); )
2477
2478 if (STp->ready != ST_READY)
2479 return (-EIO);
2480
2481 /* Read the current page contents */
2482 retval = read_mode_page(STp, COMPRESSION_PAGE, 0);
2483 if (retval) {
2484 DEBC(printk(ST_DEB_MSG "%s: Compression mode page not supported.\n",
2485 name));
2486 return (-EIO);
2487 }
2488
2489 mpoffs = MODE_HEADER_LENGTH + b_data[MH_OFF_BDESCS_LENGTH];
2490 DEBC(printk(ST_DEB_MSG "%s: Compression state is %d.\n", name,
2491 (b_data[mpoffs + CP_OFF_DCE_DCC] & DCE_MASK ? 1 : 0)));
2492
2493 /* Check if compression can be changed */
2494 if ((b_data[mpoffs + CP_OFF_DCE_DCC] & DCC_MASK) == 0) {
2495 DEBC(printk(ST_DEB_MSG "%s: Compression not supported.\n", name));
2496 return (-EIO);
2497 }
2498
2499 /* Do the change */
2500 if (state) {
2501 b_data[mpoffs + CP_OFF_DCE_DCC] |= DCE_MASK;
2502 if (STp->c_algo != 0)
2503 b_data[mpoffs + CP_OFF_C_ALGO] = STp->c_algo;
2504 }
2505 else {
2506 b_data[mpoffs + CP_OFF_DCE_DCC] &= ~DCE_MASK;
2507 if (STp->c_algo != 0)
2508 b_data[mpoffs + CP_OFF_C_ALGO] = 0; /* no compression */
2509 }
2510
2511 retval = write_mode_page(STp, COMPRESSION_PAGE, 0);
2512 if (retval) {
2513 DEBC(printk(ST_DEB_MSG "%s: Compression change failed.\n", name));
2514 return (-EIO);
2515 }
2516 DEBC(printk(ST_DEB_MSG "%s: Compression state changed to %d.\n",
2517 name, state));
2518
2519 STp->compression_changed = 1;
2520 return 0;
2521}
2522
2523
2524/* Process the load and unload commands (does unload if the load code is zero) */
2525static int do_load_unload(struct scsi_tape *STp, struct file *filp, int load_code)
2526{
2527 int retval = (-EIO), timeout;
2528 DEB( char *name = tape_name(STp); )
2529 unsigned char cmd[MAX_COMMAND_SIZE];
2530 struct st_partstat *STps;
Mike Christie8b05b772005-11-08 04:06:44 -06002531 struct st_request *SRpnt;
Linus Torvalds1da177e2005-04-16 15:20:36 -07002532
2533 if (STp->ready != ST_READY && !load_code) {
2534 if (STp->ready == ST_NO_TAPE)
2535 return (-ENOMEDIUM);
2536 else
2537 return (-EIO);
2538 }
2539
2540 memset(cmd, 0, MAX_COMMAND_SIZE);
2541 cmd[0] = START_STOP;
2542 if (load_code)
2543 cmd[4] |= 1;
2544 /*
2545 * If arg >= 1 && arg <= 6 Enhanced load/unload in HP C1553A
2546 */
2547 if (load_code >= 1 + MT_ST_HPLOADER_OFFSET
2548 && load_code <= 6 + MT_ST_HPLOADER_OFFSET) {
2549 DEBC(printk(ST_DEB_MSG "%s: Enhanced %sload slot %2d.\n",
2550 name, (cmd[4]) ? "" : "un",
2551 load_code - MT_ST_HPLOADER_OFFSET));
2552 cmd[3] = load_code - MT_ST_HPLOADER_OFFSET; /* MediaID field of C1553A */
2553 }
2554 if (STp->immediate) {
2555 cmd[1] = 1; /* Don't wait for completion */
James Bottomleya02488e2008-11-30 10:36:26 -06002556 timeout = STp->device->request_queue->rq_timeout;
Linus Torvalds1da177e2005-04-16 15:20:36 -07002557 }
2558 else
2559 timeout = STp->long_timeout;
2560
2561 DEBC(
2562 if (!load_code)
2563 printk(ST_DEB_MSG "%s: Unloading tape.\n", name);
2564 else
2565 printk(ST_DEB_MSG "%s: Loading tape.\n", name);
2566 );
2567
Kai Makisara02ae2c02008-12-18 14:49:50 +09002568 SRpnt = st_do_scsi(NULL, STp, cmd, 0, DMA_NONE,
2569 timeout, MAX_RETRIES, 1);
Linus Torvalds1da177e2005-04-16 15:20:36 -07002570 if (!SRpnt)
Kai Makisara02ae2c02008-12-18 14:49:50 +09002571 return (STp->buffer)->syscall_result;
Linus Torvalds1da177e2005-04-16 15:20:36 -07002572
2573 retval = (STp->buffer)->syscall_result;
Kai Makisara02ae2c02008-12-18 14:49:50 +09002574 st_release_request(SRpnt);
Linus Torvalds1da177e2005-04-16 15:20:36 -07002575
2576 if (!retval) { /* SCSI command successful */
2577
2578 if (!load_code) {
2579 STp->rew_at_close = 0;
2580 STp->ready = ST_NO_TAPE;
2581 }
2582 else {
2583 STp->rew_at_close = STp->autorew_dev;
2584 retval = check_tape(STp, filp);
2585 if (retval > 0)
2586 retval = 0;
2587 }
2588 }
2589 else {
2590 STps = &(STp->ps[STp->partition]);
2591 STps->drv_file = STps->drv_block = (-1);
2592 }
2593
2594 return retval;
2595}
2596
2597#if DEBUG
2598#define ST_DEB_FORWARD 0
2599#define ST_DEB_BACKWARD 1
2600static void deb_space_print(char *name, int direction, char *units, unsigned char *cmd)
2601{
2602 s32 sc;
2603
2604 sc = cmd[2] & 0x80 ? 0xff000000 : 0;
2605 sc |= (cmd[2] << 16) | (cmd[3] << 8) | cmd[4];
2606 if (direction)
2607 sc = -sc;
2608 printk(ST_DEB_MSG "%s: Spacing tape %s over %d %s.\n", name,
2609 direction ? "backward" : "forward", sc, units);
2610}
2611#endif
2612
2613
2614/* Internal ioctl function */
2615static int st_int_ioctl(struct scsi_tape *STp, unsigned int cmd_in, unsigned long arg)
2616{
2617 int timeout;
2618 long ltmp;
2619 int ioctl_result;
2620 int chg_eof = 1;
2621 unsigned char cmd[MAX_COMMAND_SIZE];
Mike Christie8b05b772005-11-08 04:06:44 -06002622 struct st_request *SRpnt;
Linus Torvalds1da177e2005-04-16 15:20:36 -07002623 struct st_partstat *STps;
2624 int fileno, blkno, at_sm, undone;
2625 int datalen = 0, direction = DMA_NONE;
2626 char *name = tape_name(STp);
2627
2628 WARN_ON(STp->buffer->do_dio != 0);
2629 if (STp->ready != ST_READY) {
2630 if (STp->ready == ST_NO_TAPE)
2631 return (-ENOMEDIUM);
2632 else
2633 return (-EIO);
2634 }
2635 timeout = STp->long_timeout;
2636 STps = &(STp->ps[STp->partition]);
2637 fileno = STps->drv_file;
2638 blkno = STps->drv_block;
2639 at_sm = STps->at_sm;
2640
2641 memset(cmd, 0, MAX_COMMAND_SIZE);
2642 switch (cmd_in) {
2643 case MTFSFM:
2644 chg_eof = 0; /* Changed from the FSF after this */
2645 case MTFSF:
2646 cmd[0] = SPACE;
2647 cmd[1] = 0x01; /* Space FileMarks */
2648 cmd[2] = (arg >> 16);
2649 cmd[3] = (arg >> 8);
2650 cmd[4] = arg;
2651 DEBC(deb_space_print(name, ST_DEB_FORWARD, "filemarks", cmd);)
2652 if (fileno >= 0)
2653 fileno += arg;
2654 blkno = 0;
2655 at_sm &= (arg == 0);
2656 break;
2657 case MTBSFM:
2658 chg_eof = 0; /* Changed from the FSF after this */
2659 case MTBSF:
2660 cmd[0] = SPACE;
2661 cmd[1] = 0x01; /* Space FileMarks */
2662 ltmp = (-arg);
2663 cmd[2] = (ltmp >> 16);
2664 cmd[3] = (ltmp >> 8);
2665 cmd[4] = ltmp;
2666 DEBC(deb_space_print(name, ST_DEB_BACKWARD, "filemarks", cmd);)
2667 if (fileno >= 0)
2668 fileno -= arg;
2669 blkno = (-1); /* We can't know the block number */
2670 at_sm &= (arg == 0);
2671 break;
2672 case MTFSR:
2673 cmd[0] = SPACE;
2674 cmd[1] = 0x00; /* Space Blocks */
2675 cmd[2] = (arg >> 16);
2676 cmd[3] = (arg >> 8);
2677 cmd[4] = arg;
2678 DEBC(deb_space_print(name, ST_DEB_FORWARD, "blocks", cmd);)
2679 if (blkno >= 0)
2680 blkno += arg;
2681 at_sm &= (arg == 0);
2682 break;
2683 case MTBSR:
2684 cmd[0] = SPACE;
2685 cmd[1] = 0x00; /* Space Blocks */
2686 ltmp = (-arg);
2687 cmd[2] = (ltmp >> 16);
2688 cmd[3] = (ltmp >> 8);
2689 cmd[4] = ltmp;
2690 DEBC(deb_space_print(name, ST_DEB_BACKWARD, "blocks", cmd);)
2691 if (blkno >= 0)
2692 blkno -= arg;
2693 at_sm &= (arg == 0);
2694 break;
2695 case MTFSS:
2696 cmd[0] = SPACE;
2697 cmd[1] = 0x04; /* Space Setmarks */
2698 cmd[2] = (arg >> 16);
2699 cmd[3] = (arg >> 8);
2700 cmd[4] = arg;
2701 DEBC(deb_space_print(name, ST_DEB_FORWARD, "setmarks", cmd);)
2702 if (arg != 0) {
2703 blkno = fileno = (-1);
2704 at_sm = 1;
2705 }
2706 break;
2707 case MTBSS:
2708 cmd[0] = SPACE;
2709 cmd[1] = 0x04; /* Space Setmarks */
2710 ltmp = (-arg);
2711 cmd[2] = (ltmp >> 16);
2712 cmd[3] = (ltmp >> 8);
2713 cmd[4] = ltmp;
2714 DEBC(deb_space_print(name, ST_DEB_BACKWARD, "setmarks", cmd);)
2715 if (arg != 0) {
2716 blkno = fileno = (-1);
2717 at_sm = 1;
2718 }
2719 break;
2720 case MTWEOF:
Kai Makisara3e51d3c2010-10-09 00:17:56 +03002721 case MTWEOFI:
Linus Torvalds1da177e2005-04-16 15:20:36 -07002722 case MTWSM:
2723 if (STp->write_prot)
2724 return (-EACCES);
2725 cmd[0] = WRITE_FILEMARKS;
2726 if (cmd_in == MTWSM)
2727 cmd[1] = 2;
Lee Duncanc743e442012-03-01 12:41:01 -08002728 if (cmd_in == MTWEOFI ||
2729 (cmd_in == MTWEOF && STp->immediate_filemark))
Kai Makisara3e51d3c2010-10-09 00:17:56 +03002730 cmd[1] |= 1;
Linus Torvalds1da177e2005-04-16 15:20:36 -07002731 cmd[2] = (arg >> 16);
2732 cmd[3] = (arg >> 8);
2733 cmd[4] = arg;
James Bottomleya02488e2008-11-30 10:36:26 -06002734 timeout = STp->device->request_queue->rq_timeout;
Linus Torvalds1da177e2005-04-16 15:20:36 -07002735 DEBC(
Kai Makisara3e51d3c2010-10-09 00:17:56 +03002736 if (cmd_in != MTWSM)
Linus Torvalds1da177e2005-04-16 15:20:36 -07002737 printk(ST_DEB_MSG "%s: Writing %d filemarks.\n", name,
2738 cmd[2] * 65536 + cmd[3] * 256 + cmd[4]);
2739 else
2740 printk(ST_DEB_MSG "%s: Writing %d setmarks.\n", name,
2741 cmd[2] * 65536 + cmd[3] * 256 + cmd[4]);
2742 )
2743 if (fileno >= 0)
2744 fileno += arg;
2745 blkno = 0;
2746 at_sm = (cmd_in == MTWSM);
2747 break;
2748 case MTREW:
2749 cmd[0] = REZERO_UNIT;
2750 if (STp->immediate) {
2751 cmd[1] = 1; /* Don't wait for completion */
James Bottomleya02488e2008-11-30 10:36:26 -06002752 timeout = STp->device->request_queue->rq_timeout;
Linus Torvalds1da177e2005-04-16 15:20:36 -07002753 }
2754 DEBC(printk(ST_DEB_MSG "%s: Rewinding tape.\n", name));
2755 fileno = blkno = at_sm = 0;
2756 break;
2757 case MTNOP:
2758 DEBC(printk(ST_DEB_MSG "%s: No op on tape.\n", name));
2759 return 0; /* Should do something ? */
2760 break;
2761 case MTRETEN:
2762 cmd[0] = START_STOP;
2763 if (STp->immediate) {
2764 cmd[1] = 1; /* Don't wait for completion */
James Bottomleya02488e2008-11-30 10:36:26 -06002765 timeout = STp->device->request_queue->rq_timeout;
Linus Torvalds1da177e2005-04-16 15:20:36 -07002766 }
2767 cmd[4] = 3;
2768 DEBC(printk(ST_DEB_MSG "%s: Retensioning tape.\n", name));
2769 fileno = blkno = at_sm = 0;
2770 break;
2771 case MTEOM:
2772 if (!STp->fast_mteom) {
2773 /* space to the end of tape */
2774 ioctl_result = st_int_ioctl(STp, MTFSF, 0x7fffff);
2775 fileno = STps->drv_file;
2776 if (STps->eof >= ST_EOD_1)
2777 return 0;
2778 /* The next lines would hide the number of spaced FileMarks
2779 That's why I inserted the previous lines. I had no luck
2780 with detecting EOM with FSF, so we go now to EOM.
2781 Joerg Weule */
2782 } else
2783 fileno = (-1);
2784 cmd[0] = SPACE;
2785 cmd[1] = 3;
2786 DEBC(printk(ST_DEB_MSG "%s: Spacing to end of recorded medium.\n",
2787 name));
2788 blkno = -1;
2789 at_sm = 0;
2790 break;
2791 case MTERASE:
2792 if (STp->write_prot)
2793 return (-EACCES);
2794 cmd[0] = ERASE;
2795 cmd[1] = (arg ? 1 : 0); /* Long erase with non-zero argument */
2796 if (STp->immediate) {
2797 cmd[1] |= 2; /* Don't wait for completion */
James Bottomleya02488e2008-11-30 10:36:26 -06002798 timeout = STp->device->request_queue->rq_timeout;
Linus Torvalds1da177e2005-04-16 15:20:36 -07002799 }
2800 else
2801 timeout = STp->long_timeout * 8;
2802
2803 DEBC(printk(ST_DEB_MSG "%s: Erasing tape.\n", name));
2804 fileno = blkno = at_sm = 0;
2805 break;
2806 case MTSETBLK: /* Set block length */
2807 case MTSETDENSITY: /* Set tape density */
2808 case MTSETDRVBUFFER: /* Set drive buffering */
2809 case SET_DENS_AND_BLK: /* Set density and block size */
2810 chg_eof = 0;
2811 if (STp->dirty || (STp->buffer)->buffer_bytes != 0)
2812 return (-EIO); /* Not allowed if data in buffer */
2813 if ((cmd_in == MTSETBLK || cmd_in == SET_DENS_AND_BLK) &&
2814 (arg & MT_ST_BLKSIZE_MASK) != 0 &&
2815 STp->max_block > 0 &&
2816 ((arg & MT_ST_BLKSIZE_MASK) < STp->min_block ||
2817 (arg & MT_ST_BLKSIZE_MASK) > STp->max_block)) {
2818 printk(KERN_WARNING "%s: Illegal block size.\n", name);
2819 return (-EINVAL);
2820 }
2821 cmd[0] = MODE_SELECT;
2822 if ((STp->use_pf & USE_PF))
2823 cmd[1] = MODE_SELECT_PAGE_FORMAT;
2824 cmd[4] = datalen = 12;
2825 direction = DMA_TO_DEVICE;
2826
2827 memset((STp->buffer)->b_data, 0, 12);
2828 if (cmd_in == MTSETDRVBUFFER)
2829 (STp->buffer)->b_data[2] = (arg & 7) << 4;
2830 else
2831 (STp->buffer)->b_data[2] =
2832 STp->drv_buffer << 4;
2833 (STp->buffer)->b_data[3] = 8; /* block descriptor length */
2834 if (cmd_in == MTSETDENSITY) {
2835 (STp->buffer)->b_data[4] = arg;
2836 STp->density_changed = 1; /* At least we tried ;-) */
2837 } else if (cmd_in == SET_DENS_AND_BLK)
2838 (STp->buffer)->b_data[4] = arg >> 24;
2839 else
2840 (STp->buffer)->b_data[4] = STp->density;
2841 if (cmd_in == MTSETBLK || cmd_in == SET_DENS_AND_BLK) {
2842 ltmp = arg & MT_ST_BLKSIZE_MASK;
2843 if (cmd_in == MTSETBLK)
2844 STp->blksize_changed = 1; /* At least we tried ;-) */
2845 } else
2846 ltmp = STp->block_size;
2847 (STp->buffer)->b_data[9] = (ltmp >> 16);
2848 (STp->buffer)->b_data[10] = (ltmp >> 8);
2849 (STp->buffer)->b_data[11] = ltmp;
James Bottomleya02488e2008-11-30 10:36:26 -06002850 timeout = STp->device->request_queue->rq_timeout;
Linus Torvalds1da177e2005-04-16 15:20:36 -07002851 DEBC(
2852 if (cmd_in == MTSETBLK || cmd_in == SET_DENS_AND_BLK)
2853 printk(ST_DEB_MSG
2854 "%s: Setting block size to %d bytes.\n", name,
2855 (STp->buffer)->b_data[9] * 65536 +
2856 (STp->buffer)->b_data[10] * 256 +
2857 (STp->buffer)->b_data[11]);
2858 if (cmd_in == MTSETDENSITY || cmd_in == SET_DENS_AND_BLK)
2859 printk(ST_DEB_MSG
2860 "%s: Setting density code to %x.\n", name,
2861 (STp->buffer)->b_data[4]);
2862 if (cmd_in == MTSETDRVBUFFER)
2863 printk(ST_DEB_MSG
2864 "%s: Setting drive buffer code to %d.\n", name,
2865 ((STp->buffer)->b_data[2] >> 4) & 7);
2866 )
2867 break;
2868 default:
2869 return (-ENOSYS);
2870 }
2871
Kai Makisara02ae2c02008-12-18 14:49:50 +09002872 SRpnt = st_do_scsi(NULL, STp, cmd, datalen, direction,
2873 timeout, MAX_RETRIES, 1);
Linus Torvalds1da177e2005-04-16 15:20:36 -07002874 if (!SRpnt)
2875 return (STp->buffer)->syscall_result;
2876
Kai Makisara02ae2c02008-12-18 14:49:50 +09002877 ioctl_result = (STp->buffer)->syscall_result;
Linus Torvalds1da177e2005-04-16 15:20:36 -07002878
2879 if (!ioctl_result) { /* SCSI command successful */
Mike Christie8b05b772005-11-08 04:06:44 -06002880 st_release_request(SRpnt);
Linus Torvalds1da177e2005-04-16 15:20:36 -07002881 SRpnt = NULL;
2882 STps->drv_block = blkno;
2883 STps->drv_file = fileno;
2884 STps->at_sm = at_sm;
2885
2886 if (cmd_in == MTBSFM)
2887 ioctl_result = st_int_ioctl(STp, MTFSF, 1);
2888 else if (cmd_in == MTFSFM)
2889 ioctl_result = st_int_ioctl(STp, MTBSF, 1);
2890
2891 if (cmd_in == MTSETBLK || cmd_in == SET_DENS_AND_BLK) {
Linus Torvalds1da177e2005-04-16 15:20:36 -07002892 STp->block_size = arg & MT_ST_BLKSIZE_MASK;
2893 if (STp->block_size != 0) {
Linus Torvalds1da177e2005-04-16 15:20:36 -07002894 (STp->buffer)->buffer_blocks =
2895 (STp->buffer)->buffer_size / STp->block_size;
2896 }
2897 (STp->buffer)->buffer_bytes = (STp->buffer)->read_pointer = 0;
2898 if (cmd_in == SET_DENS_AND_BLK)
2899 STp->density = arg >> MT_ST_DENSITY_SHIFT;
2900 } else if (cmd_in == MTSETDRVBUFFER)
2901 STp->drv_buffer = (arg & 7);
2902 else if (cmd_in == MTSETDENSITY)
2903 STp->density = arg;
2904
2905 if (cmd_in == MTEOM)
2906 STps->eof = ST_EOD;
2907 else if (cmd_in == MTFSF)
2908 STps->eof = ST_FM;
2909 else if (chg_eof)
2910 STps->eof = ST_NOEOF;
2911
Kai Makisara3e51d3c2010-10-09 00:17:56 +03002912 if (cmd_in == MTWEOF || cmd_in == MTWEOFI)
2913 STps->rw = ST_IDLE; /* prevent automatic WEOF at close */
Linus Torvalds1da177e2005-04-16 15:20:36 -07002914 } else { /* SCSI command was not completely successful. Don't return
2915 from this block without releasing the SCSI command block! */
2916 struct st_cmdstatus *cmdstatp = &STp->buffer->cmdstat;
2917
2918 if (cmdstatp->flags & SENSE_EOM) {
2919 if (cmd_in != MTBSF && cmd_in != MTBSFM &&
2920 cmd_in != MTBSR && cmd_in != MTBSS)
2921 STps->eof = ST_EOM_OK;
2922 STps->drv_block = 0;
2923 }
2924
2925 if (cmdstatp->remainder_valid)
2926 undone = (int)cmdstatp->uremainder64;
2927 else
2928 undone = 0;
2929
Kai Makisara3e51d3c2010-10-09 00:17:56 +03002930 if ((cmd_in == MTWEOF || cmd_in == MTWEOFI) &&
Linus Torvalds1da177e2005-04-16 15:20:36 -07002931 cmdstatp->have_sense &&
Kai Makisara91614c02007-01-26 00:38:39 +02002932 (cmdstatp->flags & SENSE_EOM)) {
2933 if (cmdstatp->sense_hdr.sense_key == NO_SENSE ||
2934 cmdstatp->sense_hdr.sense_key == RECOVERED_ERROR) {
2935 ioctl_result = 0; /* EOF(s) written successfully at EOM */
2936 STps->eof = ST_NOEOF;
2937 } else { /* Writing EOF(s) failed */
2938 if (fileno >= 0)
2939 fileno -= undone;
2940 if (undone < arg)
2941 STps->eof = ST_NOEOF;
2942 }
Linus Torvalds1da177e2005-04-16 15:20:36 -07002943 STps->drv_file = fileno;
Linus Torvalds1da177e2005-04-16 15:20:36 -07002944 } else if ((cmd_in == MTFSF) || (cmd_in == MTFSFM)) {
2945 if (fileno >= 0)
2946 STps->drv_file = fileno - undone;
2947 else
2948 STps->drv_file = fileno;
2949 STps->drv_block = -1;
2950 STps->eof = ST_NOEOF;
2951 } else if ((cmd_in == MTBSF) || (cmd_in == MTBSFM)) {
2952 if (arg > 0 && undone < 0) /* Some drives get this wrong */
2953 undone = (-undone);
2954 if (STps->drv_file >= 0)
2955 STps->drv_file = fileno + undone;
2956 STps->drv_block = 0;
2957 STps->eof = ST_NOEOF;
2958 } else if (cmd_in == MTFSR) {
2959 if (cmdstatp->flags & SENSE_FMK) { /* Hit filemark */
2960 if (STps->drv_file >= 0)
2961 STps->drv_file++;
2962 STps->drv_block = 0;
2963 STps->eof = ST_FM;
2964 } else {
2965 if (blkno >= undone)
2966 STps->drv_block = blkno - undone;
2967 else
2968 STps->drv_block = (-1);
2969 STps->eof = ST_NOEOF;
2970 }
2971 } else if (cmd_in == MTBSR) {
2972 if (cmdstatp->flags & SENSE_FMK) { /* Hit filemark */
2973 STps->drv_file--;
2974 STps->drv_block = (-1);
2975 } else {
2976 if (arg > 0 && undone < 0) /* Some drives get this wrong */
2977 undone = (-undone);
2978 if (STps->drv_block >= 0)
2979 STps->drv_block = blkno + undone;
2980 }
2981 STps->eof = ST_NOEOF;
2982 } else if (cmd_in == MTEOM) {
2983 STps->drv_file = (-1);
2984 STps->drv_block = (-1);
2985 STps->eof = ST_EOD;
2986 } else if (cmd_in == MTSETBLK ||
2987 cmd_in == MTSETDENSITY ||
2988 cmd_in == MTSETDRVBUFFER ||
2989 cmd_in == SET_DENS_AND_BLK) {
2990 if (cmdstatp->sense_hdr.sense_key == ILLEGAL_REQUEST &&
2991 !(STp->use_pf & PF_TESTED)) {
2992 /* Try the other possible state of Page Format if not
2993 already tried */
Kai Makisara1da20192009-05-02 08:49:34 +03002994 STp->use_pf = (STp->use_pf ^ USE_PF) | PF_TESTED;
Mike Christie8b05b772005-11-08 04:06:44 -06002995 st_release_request(SRpnt);
Linus Torvalds1da177e2005-04-16 15:20:36 -07002996 SRpnt = NULL;
2997 return st_int_ioctl(STp, cmd_in, arg);
2998 }
2999 } else if (chg_eof)
3000 STps->eof = ST_NOEOF;
3001
3002 if (cmdstatp->sense_hdr.sense_key == BLANK_CHECK)
3003 STps->eof = ST_EOD;
3004
Mike Christie8b05b772005-11-08 04:06:44 -06003005 st_release_request(SRpnt);
Linus Torvalds1da177e2005-04-16 15:20:36 -07003006 SRpnt = NULL;
3007 }
3008
3009 return ioctl_result;
3010}
3011
3012
3013/* Get the tape position. If bt == 2, arg points into a kernel space mt_loc
3014 structure. */
3015
3016static int get_location(struct scsi_tape *STp, unsigned int *block, int *partition,
3017 int logical)
3018{
3019 int result;
3020 unsigned char scmd[MAX_COMMAND_SIZE];
Mike Christie8b05b772005-11-08 04:06:44 -06003021 struct st_request *SRpnt;
Linus Torvalds1da177e2005-04-16 15:20:36 -07003022 DEB( char *name = tape_name(STp); )
3023
3024 if (STp->ready != ST_READY)
3025 return (-EIO);
3026
3027 memset(scmd, 0, MAX_COMMAND_SIZE);
3028 if ((STp->device)->scsi_level < SCSI_2) {
3029 scmd[0] = QFA_REQUEST_BLOCK;
3030 scmd[4] = 3;
3031 } else {
3032 scmd[0] = READ_POSITION;
3033 if (!logical && !STp->scsi2_logical)
3034 scmd[1] = 1;
3035 }
Kai Makisara02ae2c02008-12-18 14:49:50 +09003036 SRpnt = st_do_scsi(NULL, STp, scmd, 20, DMA_FROM_DEVICE,
3037 STp->device->request_queue->rq_timeout,
3038 MAX_READY_RETRIES, 1);
Linus Torvalds1da177e2005-04-16 15:20:36 -07003039 if (!SRpnt)
Kai Makisara02ae2c02008-12-18 14:49:50 +09003040 return (STp->buffer)->syscall_result;
Linus Torvalds1da177e2005-04-16 15:20:36 -07003041
3042 if ((STp->buffer)->syscall_result != 0 ||
3043 (STp->device->scsi_level >= SCSI_2 &&
3044 ((STp->buffer)->b_data[0] & 4) != 0)) {
3045 *block = *partition = 0;
3046 DEBC(printk(ST_DEB_MSG "%s: Can't read tape position.\n", name));
3047 result = (-EIO);
3048 } else {
3049 result = 0;
3050 if ((STp->device)->scsi_level < SCSI_2) {
3051 *block = ((STp->buffer)->b_data[0] << 16)
3052 + ((STp->buffer)->b_data[1] << 8)
3053 + (STp->buffer)->b_data[2];
3054 *partition = 0;
3055 } else {
3056 *block = ((STp->buffer)->b_data[4] << 24)
3057 + ((STp->buffer)->b_data[5] << 16)
3058 + ((STp->buffer)->b_data[6] << 8)
3059 + (STp->buffer)->b_data[7];
3060 *partition = (STp->buffer)->b_data[1];
3061 if (((STp->buffer)->b_data[0] & 0x80) &&
3062 (STp->buffer)->b_data[1] == 0) /* BOP of partition 0 */
3063 STp->ps[0].drv_block = STp->ps[0].drv_file = 0;
3064 }
3065 DEBC(printk(ST_DEB_MSG "%s: Got tape pos. blk %d part %d.\n", name,
3066 *block, *partition));
3067 }
Mike Christie8b05b772005-11-08 04:06:44 -06003068 st_release_request(SRpnt);
Linus Torvalds1da177e2005-04-16 15:20:36 -07003069 SRpnt = NULL;
3070
3071 return result;
3072}
3073
3074
3075/* Set the tape block and partition. Negative partition means that only the
3076 block should be set in vendor specific way. */
3077static int set_location(struct scsi_tape *STp, unsigned int block, int partition,
3078 int logical)
3079{
3080 struct st_partstat *STps;
3081 int result, p;
3082 unsigned int blk;
3083 int timeout;
3084 unsigned char scmd[MAX_COMMAND_SIZE];
Mike Christie8b05b772005-11-08 04:06:44 -06003085 struct st_request *SRpnt;
Linus Torvalds1da177e2005-04-16 15:20:36 -07003086 DEB( char *name = tape_name(STp); )
3087
3088 if (STp->ready != ST_READY)
3089 return (-EIO);
3090 timeout = STp->long_timeout;
3091 STps = &(STp->ps[STp->partition]);
3092
3093 DEBC(printk(ST_DEB_MSG "%s: Setting block to %d and partition to %d.\n",
3094 name, block, partition));
3095 DEB(if (partition < 0)
3096 return (-EIO); )
3097
3098 /* Update the location at the partition we are leaving */
3099 if ((!STp->can_partitions && partition != 0) ||
3100 partition >= ST_NBR_PARTITIONS)
3101 return (-EINVAL);
3102 if (partition != STp->partition) {
3103 if (get_location(STp, &blk, &p, 1))
3104 STps->last_block_valid = 0;
3105 else {
3106 STps->last_block_valid = 1;
3107 STps->last_block_visited = blk;
3108 DEBC(printk(ST_DEB_MSG
3109 "%s: Visited block %d for partition %d saved.\n",
3110 name, blk, STp->partition));
3111 }
3112 }
3113
3114 memset(scmd, 0, MAX_COMMAND_SIZE);
3115 if ((STp->device)->scsi_level < SCSI_2) {
3116 scmd[0] = QFA_SEEK_BLOCK;
3117 scmd[2] = (block >> 16);
3118 scmd[3] = (block >> 8);
3119 scmd[4] = block;
3120 scmd[5] = 0;
3121 } else {
3122 scmd[0] = SEEK_10;
3123 scmd[3] = (block >> 24);
3124 scmd[4] = (block >> 16);
3125 scmd[5] = (block >> 8);
3126 scmd[6] = block;
3127 if (!logical && !STp->scsi2_logical)
3128 scmd[1] = 4;
3129 if (STp->partition != partition) {
3130 scmd[1] |= 2;
3131 scmd[8] = partition;
3132 DEBC(printk(ST_DEB_MSG
3133 "%s: Trying to change partition from %d to %d\n",
3134 name, STp->partition, partition));
3135 }
3136 }
3137 if (STp->immediate) {
3138 scmd[1] |= 1; /* Don't wait for completion */
James Bottomleya02488e2008-11-30 10:36:26 -06003139 timeout = STp->device->request_queue->rq_timeout;
Linus Torvalds1da177e2005-04-16 15:20:36 -07003140 }
3141
Kai Makisara02ae2c02008-12-18 14:49:50 +09003142 SRpnt = st_do_scsi(NULL, STp, scmd, 0, DMA_NONE,
3143 timeout, MAX_READY_RETRIES, 1);
Linus Torvalds1da177e2005-04-16 15:20:36 -07003144 if (!SRpnt)
Kai Makisara02ae2c02008-12-18 14:49:50 +09003145 return (STp->buffer)->syscall_result;
Linus Torvalds1da177e2005-04-16 15:20:36 -07003146
3147 STps->drv_block = STps->drv_file = (-1);
3148 STps->eof = ST_NOEOF;
3149 if ((STp->buffer)->syscall_result != 0) {
3150 result = (-EIO);
3151 if (STp->can_partitions &&
3152 (STp->device)->scsi_level >= SCSI_2 &&
3153 (p = find_partition(STp)) >= 0)
3154 STp->partition = p;
3155 } else {
3156 if (STp->can_partitions) {
3157 STp->partition = partition;
3158 STps = &(STp->ps[partition]);
3159 if (!STps->last_block_valid ||
3160 STps->last_block_visited != block) {
3161 STps->at_sm = 0;
3162 STps->rw = ST_IDLE;
3163 }
3164 } else
3165 STps->at_sm = 0;
3166 if (block == 0)
3167 STps->drv_block = STps->drv_file = 0;
3168 result = 0;
3169 }
Kai Makisara02ae2c02008-12-18 14:49:50 +09003170
Mike Christie8b05b772005-11-08 04:06:44 -06003171 st_release_request(SRpnt);
Linus Torvalds1da177e2005-04-16 15:20:36 -07003172 SRpnt = NULL;
3173
3174 return result;
3175}
3176
3177
3178/* Find the current partition number for the drive status. Called from open and
3179 returns either partition number of negative error code. */
3180static int find_partition(struct scsi_tape *STp)
3181{
3182 int i, partition;
3183 unsigned int block;
3184
3185 if ((i = get_location(STp, &block, &partition, 1)) < 0)
3186 return i;
3187 if (partition >= ST_NBR_PARTITIONS)
3188 return (-EIO);
3189 return partition;
3190}
3191
3192
3193/* Change the partition if necessary */
3194static int switch_partition(struct scsi_tape *STp)
3195{
3196 struct st_partstat *STps;
3197
3198 if (STp->partition == STp->new_partition)
3199 return 0;
3200 STps = &(STp->ps[STp->new_partition]);
3201 if (!STps->last_block_valid)
3202 STps->last_block_visited = 0;
3203 return set_location(STp, STps->last_block_visited, STp->new_partition, 1);
3204}
3205
3206/* Functions for reading and writing the medium partition mode page. */
3207
3208#define PART_PAGE 0x11
3209#define PART_PAGE_FIXED_LENGTH 8
3210
3211#define PP_OFF_MAX_ADD_PARTS 2
3212#define PP_OFF_NBR_ADD_PARTS 3
3213#define PP_OFF_FLAGS 4
3214#define PP_OFF_PART_UNITS 6
3215#define PP_OFF_RESERVED 7
3216
3217#define PP_BIT_IDP 0x20
3218#define PP_MSK_PSUM_MB 0x10
3219
3220/* Get the number of partitions on the tape. As a side effect reads the
3221 mode page into the tape buffer. */
3222static int nbr_partitions(struct scsi_tape *STp)
3223{
3224 int result;
3225 DEB( char *name = tape_name(STp); )
3226
3227 if (STp->ready != ST_READY)
3228 return (-EIO);
3229
3230 result = read_mode_page(STp, PART_PAGE, 1);
3231
3232 if (result) {
3233 DEBC(printk(ST_DEB_MSG "%s: Can't read medium partition page.\n",
3234 name));
3235 result = (-EIO);
3236 } else {
3237 result = (STp->buffer)->b_data[MODE_HEADER_LENGTH +
3238 PP_OFF_NBR_ADD_PARTS] + 1;
3239 DEBC(printk(ST_DEB_MSG "%s: Number of partitions %d.\n", name, result));
3240 }
3241
3242 return result;
3243}
3244
3245
3246/* Partition the tape into two partitions if size > 0 or one partition if
3247 size == 0.
3248
3249 The block descriptors are read and written because Sony SDT-7000 does not
3250 work without this (suggestion from Michael Schaefer <Michael.Schaefer@dlr.de>).
3251
3252 My HP C1533A drive returns only one partition size field. This is used to
3253 set the size of partition 1. There is no size field for the default partition.
3254 Michael Schaefer's Sony SDT-7000 returns two descriptors and the second is
3255 used to set the size of partition 1 (this is what the SCSI-3 standard specifies).
3256 The following algorithm is used to accommodate both drives: if the number of
3257 partition size fields is greater than the maximum number of additional partitions
3258 in the mode page, the second field is used. Otherwise the first field is used.
3259
3260 For Seagate DDS drives the page length must be 8 when no partitions is defined
3261 and 10 when 1 partition is defined (information from Eric Lee Green). This is
3262 is acceptable also to some other old drives and enforced if the first partition
3263 size field is used for the first additional partition size.
3264 */
3265static int partition_tape(struct scsi_tape *STp, int size)
3266{
3267 char *name = tape_name(STp);
3268 int result;
3269 int pgo, psd_cnt, psdo;
3270 unsigned char *bp;
3271
3272 result = read_mode_page(STp, PART_PAGE, 0);
3273 if (result) {
3274 DEBC(printk(ST_DEB_MSG "%s: Can't read partition mode page.\n", name));
3275 return result;
3276 }
3277 /* The mode page is in the buffer. Let's modify it and write it. */
3278 bp = (STp->buffer)->b_data;
3279 pgo = MODE_HEADER_LENGTH + bp[MH_OFF_BDESCS_LENGTH];
3280 DEBC(printk(ST_DEB_MSG "%s: Partition page length is %d bytes.\n",
3281 name, bp[pgo + MP_OFF_PAGE_LENGTH] + 2));
3282
3283 psd_cnt = (bp[pgo + MP_OFF_PAGE_LENGTH] + 2 - PART_PAGE_FIXED_LENGTH) / 2;
3284 psdo = pgo + PART_PAGE_FIXED_LENGTH;
3285 if (psd_cnt > bp[pgo + PP_OFF_MAX_ADD_PARTS]) {
3286 bp[psdo] = bp[psdo + 1] = 0xff; /* Rest of the tape */
3287 psdo += 2;
3288 }
3289 memset(bp + psdo, 0, bp[pgo + PP_OFF_NBR_ADD_PARTS] * 2);
3290
3291 DEBC(printk("%s: psd_cnt %d, max.parts %d, nbr_parts %d\n", name,
3292 psd_cnt, bp[pgo + PP_OFF_MAX_ADD_PARTS],
3293 bp[pgo + PP_OFF_NBR_ADD_PARTS]));
3294
3295 if (size <= 0) {
3296 bp[pgo + PP_OFF_NBR_ADD_PARTS] = 0;
3297 if (psd_cnt <= bp[pgo + PP_OFF_MAX_ADD_PARTS])
3298 bp[pgo + MP_OFF_PAGE_LENGTH] = 6;
3299 DEBC(printk(ST_DEB_MSG "%s: Formatting tape with one partition.\n",
3300 name));
3301 } else {
3302 bp[psdo] = (size >> 8) & 0xff;
3303 bp[psdo + 1] = size & 0xff;
3304 bp[pgo + 3] = 1;
3305 if (bp[pgo + MP_OFF_PAGE_LENGTH] < 8)
3306 bp[pgo + MP_OFF_PAGE_LENGTH] = 8;
3307 DEBC(printk(ST_DEB_MSG
3308 "%s: Formatting tape with two partitions (1 = %d MB).\n",
3309 name, size));
3310 }
3311 bp[pgo + PP_OFF_PART_UNITS] = 0;
3312 bp[pgo + PP_OFF_RESERVED] = 0;
3313 bp[pgo + PP_OFF_FLAGS] = PP_BIT_IDP | PP_MSK_PSUM_MB;
3314
3315 result = write_mode_page(STp, PART_PAGE, 1);
3316 if (result) {
3317 printk(KERN_INFO "%s: Partitioning of tape failed.\n", name);
3318 result = (-EIO);
3319 }
3320
3321 return result;
3322}
3323
3324
3325
3326/* The ioctl command */
Kai Makisarafd66c1b2008-01-17 22:45:22 +02003327static long st_ioctl(struct file *file, unsigned int cmd_in, unsigned long arg)
Linus Torvalds1da177e2005-04-16 15:20:36 -07003328{
3329 int i, cmd_nr, cmd_type, bt;
3330 int retval = 0;
3331 unsigned int blk;
3332 struct scsi_tape *STp = file->private_data;
3333 struct st_modedef *STm;
3334 struct st_partstat *STps;
3335 char *name = tape_name(STp);
3336 void __user *p = (void __user *)arg;
3337
Matthias Kaehlcke28f85002007-07-29 23:38:15 +02003338 if (mutex_lock_interruptible(&STp->lock))
Linus Torvalds1da177e2005-04-16 15:20:36 -07003339 return -ERESTARTSYS;
3340
3341 DEB(
3342 if (debugging && !STp->in_use) {
3343 printk(ST_DEB_MSG "%s: Incorrect device.\n", name);
3344 retval = (-EIO);
3345 goto out;
3346 } ) /* end DEB */
3347
3348 STm = &(STp->modes[STp->current_mode]);
3349 STps = &(STp->ps[STp->partition]);
3350
3351 /*
3352 * If we are in the middle of error recovery, don't let anyone
3353 * else try and use this device. Also, if error recovery fails, it
3354 * may try and take the device offline, in which case all further
3355 * access to the device is prohibited.
3356 */
Al Viro83ff6fe2008-03-02 08:15:49 -05003357 retval = scsi_nonblockable_ioctl(STp->device, cmd_in, p,
3358 file->f_flags & O_NDELAY);
Linus Torvalds1da177e2005-04-16 15:20:36 -07003359 if (!scsi_block_when_processing_errors(STp->device) || retval != -ENODEV)
3360 goto out;
3361 retval = 0;
3362
3363 cmd_type = _IOC_TYPE(cmd_in);
3364 cmd_nr = _IOC_NR(cmd_in);
3365
3366 if (cmd_type == _IOC_TYPE(MTIOCTOP) && cmd_nr == _IOC_NR(MTIOCTOP)) {
3367 struct mtop mtc;
3368
3369 if (_IOC_SIZE(cmd_in) != sizeof(mtc)) {
3370 retval = (-EINVAL);
3371 goto out;
3372 }
3373
3374 i = copy_from_user(&mtc, p, sizeof(struct mtop));
3375 if (i) {
3376 retval = (-EFAULT);
3377 goto out;
3378 }
3379
3380 if (mtc.mt_op == MTSETDRVBUFFER && !capable(CAP_SYS_ADMIN)) {
3381 printk(KERN_WARNING
3382 "%s: MTSETDRVBUFFER only allowed for root.\n", name);
3383 retval = (-EPERM);
3384 goto out;
3385 }
3386 if (!STm->defined &&
3387 (mtc.mt_op != MTSETDRVBUFFER &&
3388 (mtc.mt_count & MT_ST_OPTIONS) == 0)) {
3389 retval = (-ENXIO);
3390 goto out;
3391 }
3392
3393 if (!STp->pos_unknown) {
3394
3395 if (STps->eof == ST_FM_HIT) {
3396 if (mtc.mt_op == MTFSF || mtc.mt_op == MTFSFM ||
3397 mtc.mt_op == MTEOM) {
3398 mtc.mt_count -= 1;
3399 if (STps->drv_file >= 0)
3400 STps->drv_file += 1;
3401 } else if (mtc.mt_op == MTBSF || mtc.mt_op == MTBSFM) {
3402 mtc.mt_count += 1;
3403 if (STps->drv_file >= 0)
3404 STps->drv_file += 1;
3405 }
3406 }
3407
3408 if (mtc.mt_op == MTSEEK) {
3409 /* Old position must be restored if partition will be
3410 changed */
3411 i = !STp->can_partitions ||
3412 (STp->new_partition != STp->partition);
3413 } else {
3414 i = mtc.mt_op == MTREW || mtc.mt_op == MTOFFL ||
3415 mtc.mt_op == MTRETEN || mtc.mt_op == MTEOM ||
3416 mtc.mt_op == MTLOCK || mtc.mt_op == MTLOAD ||
3417 mtc.mt_op == MTFSF || mtc.mt_op == MTFSFM ||
3418 mtc.mt_op == MTBSF || mtc.mt_op == MTBSFM ||
3419 mtc.mt_op == MTCOMPRESSION;
3420 }
3421 i = flush_buffer(STp, i);
3422 if (i < 0) {
3423 retval = i;
3424 goto out;
3425 }
3426 if (STps->rw == ST_WRITING &&
3427 (mtc.mt_op == MTREW || mtc.mt_op == MTOFFL ||
3428 mtc.mt_op == MTSEEK ||
3429 mtc.mt_op == MTBSF || mtc.mt_op == MTBSFM)) {
3430 i = st_int_ioctl(STp, MTWEOF, 1);
3431 if (i < 0) {
3432 retval = i;
3433 goto out;
3434 }
3435 if (mtc.mt_op == MTBSF || mtc.mt_op == MTBSFM)
3436 mtc.mt_count++;
3437 STps->rw = ST_IDLE;
3438 }
3439
3440 } else {
3441 /*
3442 * If there was a bus reset, block further access
3443 * to this device. If the user wants to rewind the tape,
3444 * then reset the flag and allow access again.
3445 */
3446 if (mtc.mt_op != MTREW &&
3447 mtc.mt_op != MTOFFL &&
3448 mtc.mt_op != MTRETEN &&
3449 mtc.mt_op != MTERASE &&
3450 mtc.mt_op != MTSEEK &&
3451 mtc.mt_op != MTEOM) {
3452 retval = (-EIO);
3453 goto out;
3454 }
3455 reset_state(STp);
3456 /* remove this when the midlevel properly clears was_reset */
3457 STp->device->was_reset = 0;
3458 }
3459
3460 if (mtc.mt_op != MTNOP && mtc.mt_op != MTSETBLK &&
3461 mtc.mt_op != MTSETDENSITY && mtc.mt_op != MTWSM &&
3462 mtc.mt_op != MTSETDRVBUFFER && mtc.mt_op != MTSETPART)
3463 STps->rw = ST_IDLE; /* Prevent automatic WEOF and fsf */
3464
3465 if (mtc.mt_op == MTOFFL && STp->door_locked != ST_UNLOCKED)
3466 do_door_lock(STp, 0); /* Ignore result! */
3467
3468 if (mtc.mt_op == MTSETDRVBUFFER &&
3469 (mtc.mt_count & MT_ST_OPTIONS) != 0) {
3470 retval = st_set_options(STp, mtc.mt_count);
3471 goto out;
3472 }
3473
3474 if (mtc.mt_op == MTSETPART) {
3475 if (!STp->can_partitions ||
3476 mtc.mt_count < 0 || mtc.mt_count >= ST_NBR_PARTITIONS) {
3477 retval = (-EINVAL);
3478 goto out;
3479 }
3480 if (mtc.mt_count >= STp->nbr_partitions &&
3481 (STp->nbr_partitions = nbr_partitions(STp)) < 0) {
3482 retval = (-EIO);
3483 goto out;
3484 }
3485 if (mtc.mt_count >= STp->nbr_partitions) {
3486 retval = (-EINVAL);
3487 goto out;
3488 }
3489 STp->new_partition = mtc.mt_count;
3490 retval = 0;
3491 goto out;
3492 }
3493
3494 if (mtc.mt_op == MTMKPART) {
3495 if (!STp->can_partitions) {
3496 retval = (-EINVAL);
3497 goto out;
3498 }
3499 if ((i = st_int_ioctl(STp, MTREW, 0)) < 0 ||
3500 (i = partition_tape(STp, mtc.mt_count)) < 0) {
3501 retval = i;
3502 goto out;
3503 }
3504 for (i = 0; i < ST_NBR_PARTITIONS; i++) {
3505 STp->ps[i].rw = ST_IDLE;
3506 STp->ps[i].at_sm = 0;
3507 STp->ps[i].last_block_valid = 0;
3508 }
3509 STp->partition = STp->new_partition = 0;
3510 STp->nbr_partitions = 1; /* Bad guess ?-) */
3511 STps->drv_block = STps->drv_file = 0;
3512 retval = 0;
3513 goto out;
3514 }
3515
3516 if (mtc.mt_op == MTSEEK) {
3517 i = set_location(STp, mtc.mt_count, STp->new_partition, 0);
3518 if (!STp->can_partitions)
3519 STp->ps[0].rw = ST_IDLE;
3520 retval = i;
3521 goto out;
3522 }
3523
3524 if (mtc.mt_op == MTUNLOAD || mtc.mt_op == MTOFFL) {
3525 retval = do_load_unload(STp, file, 0);
3526 goto out;
3527 }
3528
3529 if (mtc.mt_op == MTLOAD) {
3530 retval = do_load_unload(STp, file, max(1, mtc.mt_count));
3531 goto out;
3532 }
3533
3534 if (mtc.mt_op == MTLOCK || mtc.mt_op == MTUNLOCK) {
3535 retval = do_door_lock(STp, (mtc.mt_op == MTLOCK));
3536 goto out;
3537 }
3538
3539 if (STp->can_partitions && STp->ready == ST_READY &&
3540 (i = switch_partition(STp)) < 0) {
3541 retval = i;
3542 goto out;
3543 }
3544
3545 if (mtc.mt_op == MTCOMPRESSION)
3546 retval = st_compression(STp, (mtc.mt_count & 1));
3547 else
3548 retval = st_int_ioctl(STp, mtc.mt_op, mtc.mt_count);
3549 goto out;
3550 }
3551 if (!STm->defined) {
3552 retval = (-ENXIO);
3553 goto out;
3554 }
3555
3556 if ((i = flush_buffer(STp, 0)) < 0) {
3557 retval = i;
3558 goto out;
3559 }
3560 if (STp->can_partitions &&
3561 (i = switch_partition(STp)) < 0) {
3562 retval = i;
3563 goto out;
3564 }
3565
3566 if (cmd_type == _IOC_TYPE(MTIOCGET) && cmd_nr == _IOC_NR(MTIOCGET)) {
3567 struct mtget mt_status;
3568
3569 if (_IOC_SIZE(cmd_in) != sizeof(struct mtget)) {
3570 retval = (-EINVAL);
3571 goto out;
3572 }
3573
3574 mt_status.mt_type = STp->tape_type;
3575 mt_status.mt_dsreg =
3576 ((STp->block_size << MT_ST_BLKSIZE_SHIFT) & MT_ST_BLKSIZE_MASK) |
3577 ((STp->density << MT_ST_DENSITY_SHIFT) & MT_ST_DENSITY_MASK);
3578 mt_status.mt_blkno = STps->drv_block;
3579 mt_status.mt_fileno = STps->drv_file;
3580 if (STp->block_size != 0) {
3581 if (STps->rw == ST_WRITING)
3582 mt_status.mt_blkno +=
3583 (STp->buffer)->buffer_bytes / STp->block_size;
3584 else if (STps->rw == ST_READING)
3585 mt_status.mt_blkno -=
3586 ((STp->buffer)->buffer_bytes +
3587 STp->block_size - 1) / STp->block_size;
3588 }
3589
3590 mt_status.mt_gstat = 0;
3591 if (STp->drv_write_prot)
3592 mt_status.mt_gstat |= GMT_WR_PROT(0xffffffff);
3593 if (mt_status.mt_blkno == 0) {
3594 if (mt_status.mt_fileno == 0)
3595 mt_status.mt_gstat |= GMT_BOT(0xffffffff);
3596 else
3597 mt_status.mt_gstat |= GMT_EOF(0xffffffff);
3598 }
3599 mt_status.mt_erreg = (STp->recover_reg << MT_ST_SOFTERR_SHIFT);
3600 mt_status.mt_resid = STp->partition;
3601 if (STps->eof == ST_EOM_OK || STps->eof == ST_EOM_ERROR)
3602 mt_status.mt_gstat |= GMT_EOT(0xffffffff);
3603 else if (STps->eof >= ST_EOM_OK)
3604 mt_status.mt_gstat |= GMT_EOD(0xffffffff);
3605 if (STp->density == 1)
3606 mt_status.mt_gstat |= GMT_D_800(0xffffffff);
3607 else if (STp->density == 2)
3608 mt_status.mt_gstat |= GMT_D_1600(0xffffffff);
3609 else if (STp->density == 3)
3610 mt_status.mt_gstat |= GMT_D_6250(0xffffffff);
3611 if (STp->ready == ST_READY)
3612 mt_status.mt_gstat |= GMT_ONLINE(0xffffffff);
3613 if (STp->ready == ST_NO_TAPE)
3614 mt_status.mt_gstat |= GMT_DR_OPEN(0xffffffff);
3615 if (STps->at_sm)
3616 mt_status.mt_gstat |= GMT_SM(0xffffffff);
3617 if (STm->do_async_writes ||
3618 (STm->do_buffer_writes && STp->block_size != 0) ||
3619 STp->drv_buffer != 0)
3620 mt_status.mt_gstat |= GMT_IM_REP_EN(0xffffffff);
3621 if (STp->cleaning_req)
3622 mt_status.mt_gstat |= GMT_CLN(0xffffffff);
3623
3624 i = copy_to_user(p, &mt_status, sizeof(struct mtget));
3625 if (i) {
3626 retval = (-EFAULT);
3627 goto out;
3628 }
3629
3630 STp->recover_reg = 0; /* Clear after read */
3631 retval = 0;
3632 goto out;
3633 } /* End of MTIOCGET */
3634 if (cmd_type == _IOC_TYPE(MTIOCPOS) && cmd_nr == _IOC_NR(MTIOCPOS)) {
3635 struct mtpos mt_pos;
3636 if (_IOC_SIZE(cmd_in) != sizeof(struct mtpos)) {
3637 retval = (-EINVAL);
3638 goto out;
3639 }
3640 if ((i = get_location(STp, &blk, &bt, 0)) < 0) {
3641 retval = i;
3642 goto out;
3643 }
3644 mt_pos.mt_blkno = blk;
3645 i = copy_to_user(p, &mt_pos, sizeof(struct mtpos));
3646 if (i)
3647 retval = (-EFAULT);
3648 goto out;
3649 }
Matthias Kaehlcke28f85002007-07-29 23:38:15 +02003650 mutex_unlock(&STp->lock);
Linus Torvalds1da177e2005-04-16 15:20:36 -07003651 switch (cmd_in) {
3652 case SCSI_IOCTL_GET_IDLUN:
3653 case SCSI_IOCTL_GET_BUS_NUMBER:
3654 break;
3655 default:
Kai Makisara 16c4b3e2005-05-01 18:11:55 +03003656 if ((cmd_in == SG_IO ||
3657 cmd_in == SCSI_IOCTL_SEND_COMMAND ||
3658 cmd_in == CDROM_SEND_PACKET) &&
3659 !capable(CAP_SYS_RAWIO))
Linus Torvalds1da177e2005-04-16 15:20:36 -07003660 i = -EPERM;
3661 else
Al Viro74f3c8a2007-08-27 15:38:10 -04003662 i = scsi_cmd_ioctl(STp->disk->queue, STp->disk,
3663 file->f_mode, cmd_in, p);
Linus Torvalds1da177e2005-04-16 15:20:36 -07003664 if (i != -ENOTTY)
3665 return i;
3666 break;
3667 }
Kai Makisara 16c4b3e2005-05-01 18:11:55 +03003668 retval = scsi_ioctl(STp->device, cmd_in, p);
3669 if (!retval && cmd_in == SCSI_IOCTL_STOP_UNIT) { /* unload */
3670 STp->rew_at_close = 0;
3671 STp->ready = ST_NO_TAPE;
3672 }
3673 return retval;
Linus Torvalds1da177e2005-04-16 15:20:36 -07003674
3675 out:
Matthias Kaehlcke28f85002007-07-29 23:38:15 +02003676 mutex_unlock(&STp->lock);
Linus Torvalds1da177e2005-04-16 15:20:36 -07003677 return retval;
3678}
3679
3680#ifdef CONFIG_COMPAT
3681static long st_compat_ioctl(struct file *file, unsigned int cmd, unsigned long arg)
3682{
3683 struct scsi_tape *STp = file->private_data;
3684 struct scsi_device *sdev = STp->device;
3685 int ret = -ENOIOCTLCMD;
3686 if (sdev->host->hostt->compat_ioctl) {
3687
3688 ret = sdev->host->hostt->compat_ioctl(sdev, cmd, (void __user *)arg);
3689
3690 }
3691 return ret;
3692}
3693#endif
3694
3695
3696
3697/* Try to allocate a new tape buffer. Calling function must not hold
3698 dev_arr_lock. */
FUJITA Tomonorif409d6c2008-12-18 14:49:47 +09003699static struct st_buffer *new_tape_buffer(int need_dma, int max_sg)
Linus Torvalds1da177e2005-04-16 15:20:36 -07003700{
Linus Torvalds1da177e2005-04-16 15:20:36 -07003701 struct st_buffer *tb;
3702
FUJITA Tomonorif409d6c2008-12-18 14:49:47 +09003703 tb = kzalloc(sizeof(struct st_buffer), GFP_ATOMIC);
Linus Torvalds1da177e2005-04-16 15:20:36 -07003704 if (!tb) {
3705 printk(KERN_NOTICE "st: Can't allocate new tape buffer.\n");
3706 return NULL;
3707 }
FUJITA Tomonori1ac63cf2008-12-18 14:49:48 +09003708 tb->frp_segs = 0;
Linus Torvalds1da177e2005-04-16 15:20:36 -07003709 tb->use_sg = max_sg;
Linus Torvalds1da177e2005-04-16 15:20:36 -07003710 tb->dma = need_dma;
FUJITA Tomonorif409d6c2008-12-18 14:49:47 +09003711 tb->buffer_size = 0;
Linus Torvalds1da177e2005-04-16 15:20:36 -07003712
FUJITA Tomonorif409d6c2008-12-18 14:49:47 +09003713 tb->reserved_pages = kzalloc(max_sg * sizeof(struct page *),
3714 GFP_ATOMIC);
FUJITA Tomonorid0e1ae32008-12-18 14:49:40 +09003715 if (!tb->reserved_pages) {
3716 kfree(tb);
3717 return NULL;
3718 }
3719
Linus Torvalds1da177e2005-04-16 15:20:36 -07003720 return tb;
3721}
3722
3723
3724/* Try to allocate enough space in the tape buffer */
Kai Makisara8f78fc52008-12-18 14:49:51 +09003725#define ST_MAX_ORDER 6
3726
Linus Torvalds1da177e2005-04-16 15:20:36 -07003727static int enlarge_buffer(struct st_buffer * STbuffer, int new_size, int need_dma)
3728{
Al Viroc53033f2005-10-21 03:22:08 -04003729 int segs, nbr, max_segs, b_size, order, got;
3730 gfp_t priority;
Linus Torvalds1da177e2005-04-16 15:20:36 -07003731
3732 if (new_size <= STbuffer->buffer_size)
3733 return 1;
3734
3735 if (STbuffer->buffer_size <= PAGE_SIZE)
3736 normalize_buffer(STbuffer); /* Avoid extra segment */
3737
3738 max_segs = STbuffer->use_sg;
3739 nbr = max_segs - STbuffer->frp_segs;
3740 if (nbr <= 0)
3741 return 0;
3742
3743 priority = GFP_KERNEL | __GFP_NOWARN;
3744 if (need_dma)
3745 priority |= GFP_DMA;
FUJITA Tomonori9c905962008-12-18 14:49:39 +09003746
FUJITA Tomonori08c95832008-12-18 14:49:45 +09003747 if (STbuffer->cleared)
3748 priority |= __GFP_ZERO;
3749
FUJITA Tomonori9c905962008-12-18 14:49:39 +09003750 if (STbuffer->frp_segs) {
FUJITA Tomonoric982c362009-11-26 09:24:13 +09003751 order = STbuffer->reserved_page_order;
FUJITA Tomonori08c95832008-12-18 14:49:45 +09003752 b_size = PAGE_SIZE << order;
FUJITA Tomonori9c905962008-12-18 14:49:39 +09003753 } else {
3754 for (b_size = PAGE_SIZE, order = 0;
FUJITA Tomonori46081b12010-12-20 18:44:45 +02003755 order < ST_MAX_ORDER &&
3756 max_segs * (PAGE_SIZE << order) < new_size;
Kai Makisara8f78fc52008-12-18 14:49:51 +09003757 order++, b_size *= 2)
FUJITA Tomonori9c905962008-12-18 14:49:39 +09003758 ; /* empty */
Kai Makisara373daac2010-12-20 18:43:39 +02003759 STbuffer->reserved_page_order = order;
FUJITA Tomonori9c905962008-12-18 14:49:39 +09003760 }
Kai Makisara8f78fc52008-12-18 14:49:51 +09003761 if (max_segs * (PAGE_SIZE << order) < new_size) {
3762 if (order == ST_MAX_ORDER)
3763 return 0;
3764 normalize_buffer(STbuffer);
3765 return enlarge_buffer(STbuffer, new_size, need_dma);
3766 }
Linus Torvalds1da177e2005-04-16 15:20:36 -07003767
3768 for (segs = STbuffer->frp_segs, got = STbuffer->buffer_size;
3769 segs < max_segs && got < new_size;) {
FUJITA Tomonori08c95832008-12-18 14:49:45 +09003770 struct page *page;
3771
3772 page = alloc_pages(priority, order);
3773 if (!page) {
Linus Torvalds1da177e2005-04-16 15:20:36 -07003774 DEB(STbuffer->buffer_size = got);
3775 normalize_buffer(STbuffer);
3776 return 0;
3777 }
FUJITA Tomonori08c95832008-12-18 14:49:45 +09003778
Linus Torvalds1da177e2005-04-16 15:20:36 -07003779 STbuffer->frp_segs += 1;
3780 got += b_size;
3781 STbuffer->buffer_size = got;
FUJITA Tomonori08c95832008-12-18 14:49:45 +09003782 STbuffer->reserved_pages[segs] = page;
Linus Torvalds1da177e2005-04-16 15:20:36 -07003783 segs++;
3784 }
FUJITA Tomonori08c95832008-12-18 14:49:45 +09003785 STbuffer->b_data = page_address(STbuffer->reserved_pages[0]);
Linus Torvalds1da177e2005-04-16 15:20:36 -07003786
3787 return 1;
3788}
3789
3790
Kai Makisara40f6b362008-02-24 22:23:24 +02003791/* Make sure that no data from previous user is in the internal buffer */
3792static void clear_buffer(struct st_buffer * st_bp)
3793{
3794 int i;
3795
3796 for (i=0; i < st_bp->frp_segs; i++)
FUJITA Tomonori08c95832008-12-18 14:49:45 +09003797 memset(page_address(st_bp->reserved_pages[i]), 0,
FUJITA Tomonoric982c362009-11-26 09:24:13 +09003798 PAGE_SIZE << st_bp->reserved_page_order);
Kai Makisara40f6b362008-02-24 22:23:24 +02003799 st_bp->cleared = 1;
3800}
3801
3802
Linus Torvalds1da177e2005-04-16 15:20:36 -07003803/* Release the extra buffer */
3804static void normalize_buffer(struct st_buffer * STbuffer)
3805{
FUJITA Tomonoric982c362009-11-26 09:24:13 +09003806 int i, order = STbuffer->reserved_page_order;
Linus Torvalds1da177e2005-04-16 15:20:36 -07003807
FUJITA Tomonori1ac63cf2008-12-18 14:49:48 +09003808 for (i = 0; i < STbuffer->frp_segs; i++) {
FUJITA Tomonori08c95832008-12-18 14:49:45 +09003809 __free_pages(STbuffer->reserved_pages[i], order);
3810 STbuffer->buffer_size -= (PAGE_SIZE << order);
Linus Torvalds1da177e2005-04-16 15:20:36 -07003811 }
FUJITA Tomonori1ac63cf2008-12-18 14:49:48 +09003812 STbuffer->frp_segs = 0;
Mike Christie8b05b772005-11-08 04:06:44 -06003813 STbuffer->sg_segs = 0;
FUJITA Tomonoric982c362009-11-26 09:24:13 +09003814 STbuffer->reserved_page_order = 0;
FUJITA Tomonorid0e1ae32008-12-18 14:49:40 +09003815 STbuffer->map_data.offset = 0;
Linus Torvalds1da177e2005-04-16 15:20:36 -07003816}
3817
3818
3819/* Move data from the user buffer to the tape buffer. Returns zero (success) or
3820 negative error code. */
3821static int append_to_buffer(const char __user *ubp, struct st_buffer * st_bp, int do_count)
3822{
3823 int i, cnt, res, offset;
FUJITA Tomonoric982c362009-11-26 09:24:13 +09003824 int length = PAGE_SIZE << st_bp->reserved_page_order;
Linus Torvalds1da177e2005-04-16 15:20:36 -07003825
3826 for (i = 0, offset = st_bp->buffer_bytes;
FUJITA Tomonori08c95832008-12-18 14:49:45 +09003827 i < st_bp->frp_segs && offset >= length; i++)
3828 offset -= length;
Linus Torvalds1da177e2005-04-16 15:20:36 -07003829 if (i == st_bp->frp_segs) { /* Should never happen */
3830 printk(KERN_WARNING "st: append_to_buffer offset overflow.\n");
3831 return (-EIO);
3832 }
3833 for (; i < st_bp->frp_segs && do_count > 0; i++) {
FUJITA Tomonori08c95832008-12-18 14:49:45 +09003834 struct page *page = st_bp->reserved_pages[i];
3835 cnt = length - offset < do_count ? length - offset : do_count;
3836 res = copy_from_user(page_address(page) + offset, ubp, cnt);
Linus Torvalds1da177e2005-04-16 15:20:36 -07003837 if (res)
3838 return (-EFAULT);
3839 do_count -= cnt;
3840 st_bp->buffer_bytes += cnt;
3841 ubp += cnt;
3842 offset = 0;
3843 }
3844 if (do_count) /* Should never happen */
3845 return (-EIO);
3846
3847 return 0;
3848}
3849
3850
3851/* Move data from the tape buffer to the user buffer. Returns zero (success) or
3852 negative error code. */
3853static int from_buffer(struct st_buffer * st_bp, char __user *ubp, int do_count)
3854{
3855 int i, cnt, res, offset;
FUJITA Tomonoric982c362009-11-26 09:24:13 +09003856 int length = PAGE_SIZE << st_bp->reserved_page_order;
Linus Torvalds1da177e2005-04-16 15:20:36 -07003857
3858 for (i = 0, offset = st_bp->read_pointer;
FUJITA Tomonori08c95832008-12-18 14:49:45 +09003859 i < st_bp->frp_segs && offset >= length; i++)
3860 offset -= length;
Linus Torvalds1da177e2005-04-16 15:20:36 -07003861 if (i == st_bp->frp_segs) { /* Should never happen */
3862 printk(KERN_WARNING "st: from_buffer offset overflow.\n");
3863 return (-EIO);
3864 }
3865 for (; i < st_bp->frp_segs && do_count > 0; i++) {
FUJITA Tomonori08c95832008-12-18 14:49:45 +09003866 struct page *page = st_bp->reserved_pages[i];
3867 cnt = length - offset < do_count ? length - offset : do_count;
3868 res = copy_to_user(ubp, page_address(page) + offset, cnt);
Linus Torvalds1da177e2005-04-16 15:20:36 -07003869 if (res)
3870 return (-EFAULT);
3871 do_count -= cnt;
3872 st_bp->buffer_bytes -= cnt;
3873 st_bp->read_pointer += cnt;
3874 ubp += cnt;
3875 offset = 0;
3876 }
3877 if (do_count) /* Should never happen */
3878 return (-EIO);
3879
3880 return 0;
3881}
3882
3883
3884/* Move data towards start of buffer */
3885static void move_buffer_data(struct st_buffer * st_bp, int offset)
3886{
3887 int src_seg, dst_seg, src_offset = 0, dst_offset;
3888 int count, total;
FUJITA Tomonoric982c362009-11-26 09:24:13 +09003889 int length = PAGE_SIZE << st_bp->reserved_page_order;
Linus Torvalds1da177e2005-04-16 15:20:36 -07003890
3891 if (offset == 0)
3892 return;
3893
3894 total=st_bp->buffer_bytes - offset;
3895 for (src_seg=0; src_seg < st_bp->frp_segs; src_seg++) {
3896 src_offset = offset;
FUJITA Tomonori08c95832008-12-18 14:49:45 +09003897 if (src_offset < length)
Linus Torvalds1da177e2005-04-16 15:20:36 -07003898 break;
FUJITA Tomonori08c95832008-12-18 14:49:45 +09003899 offset -= length;
Linus Torvalds1da177e2005-04-16 15:20:36 -07003900 }
3901
3902 st_bp->buffer_bytes = st_bp->read_pointer = total;
3903 for (dst_seg=dst_offset=0; total > 0; ) {
FUJITA Tomonori08c95832008-12-18 14:49:45 +09003904 struct page *dpage = st_bp->reserved_pages[dst_seg];
3905 struct page *spage = st_bp->reserved_pages[src_seg];
3906
3907 count = min(length - dst_offset, length - src_offset);
3908 memmove(page_address(dpage) + dst_offset,
3909 page_address(spage) + src_offset, count);
Linus Torvalds1da177e2005-04-16 15:20:36 -07003910 src_offset += count;
FUJITA Tomonori08c95832008-12-18 14:49:45 +09003911 if (src_offset >= length) {
Linus Torvalds1da177e2005-04-16 15:20:36 -07003912 src_seg++;
3913 src_offset = 0;
3914 }
3915 dst_offset += count;
FUJITA Tomonori08c95832008-12-18 14:49:45 +09003916 if (dst_offset >= length) {
Linus Torvalds1da177e2005-04-16 15:20:36 -07003917 dst_seg++;
3918 dst_offset = 0;
3919 }
3920 total -= count;
3921 }
3922}
3923
Linus Torvalds1da177e2005-04-16 15:20:36 -07003924/* Validate the options from command line or module parameters */
3925static void validate_options(void)
3926{
3927 if (buffer_kbs > 0)
3928 st_fixed_buffer_size = buffer_kbs * ST_KILOBYTE;
3929 if (max_sg_segs >= ST_FIRST_SG)
3930 st_max_sg_segs = max_sg_segs;
3931}
3932
3933#ifndef MODULE
3934/* Set the boot options. Syntax is defined in Documenation/scsi/st.txt.
3935 */
3936static int __init st_setup(char *str)
3937{
3938 int i, len, ints[5];
3939 char *stp;
3940
3941 stp = get_options(str, ARRAY_SIZE(ints), ints);
3942
3943 if (ints[0] > 0) {
3944 for (i = 0; i < ints[0] && i < ARRAY_SIZE(parms); i++)
3945 if (parms[i].val)
3946 *parms[i].val = ints[i + 1];
3947 } else {
3948 while (stp != NULL) {
3949 for (i = 0; i < ARRAY_SIZE(parms); i++) {
3950 len = strlen(parms[i].name);
3951 if (!strncmp(stp, parms[i].name, len) &&
3952 (*(stp + len) == ':' || *(stp + len) == '=')) {
3953 if (parms[i].val)
3954 *parms[i].val =
3955 simple_strtoul(stp + len + 1, NULL, 0);
3956 else
3957 printk(KERN_WARNING "st: Obsolete parameter %s\n",
3958 parms[i].name);
3959 break;
3960 }
3961 }
Tobias Klauser6391a112006-06-08 22:23:48 -07003962 if (i >= ARRAY_SIZE(parms))
Linus Torvalds1da177e2005-04-16 15:20:36 -07003963 printk(KERN_WARNING "st: invalid parameter in '%s'\n",
3964 stp);
3965 stp = strchr(stp, ',');
3966 if (stp)
3967 stp++;
3968 }
3969 }
3970
3971 validate_options();
3972
3973 return 1;
3974}
3975
3976__setup("st=", st_setup);
3977
3978#endif
3979
Arjan van de Ven00977a52007-02-12 00:55:34 -08003980static const struct file_operations st_fops =
Linus Torvalds1da177e2005-04-16 15:20:36 -07003981{
3982 .owner = THIS_MODULE,
3983 .read = st_read,
3984 .write = st_write,
Kai Makisarafd66c1b2008-01-17 22:45:22 +02003985 .unlocked_ioctl = st_ioctl,
Linus Torvalds1da177e2005-04-16 15:20:36 -07003986#ifdef CONFIG_COMPAT
3987 .compat_ioctl = st_compat_ioctl,
3988#endif
3989 .open = st_open,
3990 .flush = st_flush,
3991 .release = st_release,
Jan Blunckb4d878e2010-05-26 14:44:51 -07003992 .llseek = noop_llseek,
Linus Torvalds1da177e2005-04-16 15:20:36 -07003993};
3994
3995static int st_probe(struct device *dev)
3996{
3997 struct scsi_device *SDp = to_scsi_device(dev);
3998 struct gendisk *disk = NULL;
3999 struct cdev *cdev = NULL;
4000 struct scsi_tape *tpnt = NULL;
4001 struct st_modedef *STm;
4002 struct st_partstat *STps;
4003 struct st_buffer *buffer;
4004 int i, j, mode, dev_num, error;
4005 char *stp;
Linus Torvalds1da177e2005-04-16 15:20:36 -07004006
4007 if (SDp->type != TYPE_TAPE)
4008 return -ENODEV;
4009 if ((stp = st_incompatible(SDp))) {
Jeff Garzik3bf743e2005-10-24 18:04:06 -04004010 sdev_printk(KERN_INFO, SDp, "Found incompatible tape\n");
Linus Torvalds1da177e2005-04-16 15:20:36 -07004011 printk(KERN_INFO "st: The suggested driver is %s.\n", stp);
4012 return -ENODEV;
4013 }
4014
Martin K. Petersen8a783622010-02-26 00:20:39 -05004015 i = queue_max_segments(SDp->request_queue);
Linus Torvalds1da177e2005-04-16 15:20:36 -07004016 if (st_max_sg_segs < i)
4017 i = st_max_sg_segs;
FUJITA Tomonorif409d6c2008-12-18 14:49:47 +09004018 buffer = new_tape_buffer((SDp->host)->unchecked_isa_dma, i);
Linus Torvalds1da177e2005-04-16 15:20:36 -07004019 if (buffer == NULL) {
4020 printk(KERN_ERR
4021 "st: Can't allocate new tape buffer. Device not attached.\n");
4022 goto out;
4023 }
4024
4025 disk = alloc_disk(1);
4026 if (!disk) {
4027 printk(KERN_ERR "st: out of memory. Device not attached.\n");
4028 goto out_buffer_free;
4029 }
4030
4031 write_lock(&st_dev_arr_lock);
4032 if (st_nr_dev >= st_dev_max) {
4033 struct scsi_tape **tmp_da;
4034 int tmp_dev_max;
4035
4036 tmp_dev_max = max(st_nr_dev * 2, 8);
4037 if (tmp_dev_max > ST_MAX_TAPES)
4038 tmp_dev_max = ST_MAX_TAPES;
4039 if (tmp_dev_max <= st_nr_dev) {
4040 write_unlock(&st_dev_arr_lock);
4041 printk(KERN_ERR "st: Too many tape devices (max. %d).\n",
4042 ST_MAX_TAPES);
4043 goto out_put_disk;
4044 }
4045
Jes Sorensen24669f752006-01-16 10:31:18 -05004046 tmp_da = kzalloc(tmp_dev_max * sizeof(struct scsi_tape *), GFP_ATOMIC);
Linus Torvalds1da177e2005-04-16 15:20:36 -07004047 if (tmp_da == NULL) {
4048 write_unlock(&st_dev_arr_lock);
4049 printk(KERN_ERR "st: Can't extend device array.\n");
4050 goto out_put_disk;
4051 }
4052
Linus Torvalds1da177e2005-04-16 15:20:36 -07004053 if (scsi_tapes != NULL) {
4054 memcpy(tmp_da, scsi_tapes,
4055 st_dev_max * sizeof(struct scsi_tape *));
4056 kfree(scsi_tapes);
4057 }
4058 scsi_tapes = tmp_da;
4059
4060 st_dev_max = tmp_dev_max;
4061 }
4062
4063 for (i = 0; i < st_dev_max; i++)
4064 if (scsi_tapes[i] == NULL)
4065 break;
4066 if (i >= st_dev_max)
4067 panic("scsi_devices corrupt (st)");
4068
Jes Sorensen24669f752006-01-16 10:31:18 -05004069 tpnt = kzalloc(sizeof(struct scsi_tape), GFP_ATOMIC);
Linus Torvalds1da177e2005-04-16 15:20:36 -07004070 if (tpnt == NULL) {
4071 write_unlock(&st_dev_arr_lock);
4072 printk(KERN_ERR "st: Can't allocate device descriptor.\n");
4073 goto out_put_disk;
4074 }
Kai Makisaraf03a5672005-08-02 13:40:47 +03004075 kref_init(&tpnt->kref);
Linus Torvalds1da177e2005-04-16 15:20:36 -07004076 tpnt->disk = disk;
4077 sprintf(disk->disk_name, "st%d", i);
4078 disk->private_data = &tpnt->driver;
4079 disk->queue = SDp->request_queue;
4080 tpnt->driver = &st_template;
4081 scsi_tapes[i] = tpnt;
4082 dev_num = i;
4083
4084 tpnt->device = SDp;
4085 if (SDp->scsi_level <= 2)
4086 tpnt->tape_type = MT_ISSCSI1;
4087 else
4088 tpnt->tape_type = MT_ISSCSI2;
4089
4090 tpnt->buffer = buffer;
Kai Makisaraf03a5672005-08-02 13:40:47 +03004091 tpnt->buffer->last_SRpnt = NULL;
Linus Torvalds1da177e2005-04-16 15:20:36 -07004092
4093 tpnt->inited = 0;
4094 tpnt->dirty = 0;
4095 tpnt->in_use = 0;
4096 tpnt->drv_buffer = 1; /* Try buffering if no mode sense */
4097 tpnt->restr_dma = (SDp->host)->unchecked_isa_dma;
4098 tpnt->use_pf = (SDp->scsi_level >= SCSI_2);
4099 tpnt->density = 0;
4100 tpnt->do_auto_lock = ST_AUTO_LOCK;
4101 tpnt->can_bsr = (SDp->scsi_level > 2 ? 1 : ST_IN_FILE_POS); /* BSR mandatory in SCSI3 */
4102 tpnt->can_partitions = 0;
4103 tpnt->two_fm = ST_TWO_FM;
4104 tpnt->fast_mteom = ST_FAST_MTEOM;
4105 tpnt->scsi2_logical = ST_SCSI2LOGICAL;
Kai Makisara40f6b362008-02-24 22:23:24 +02004106 tpnt->sili = ST_SILI;
Linus Torvalds1da177e2005-04-16 15:20:36 -07004107 tpnt->immediate = ST_NOWAIT;
Lee Duncanc743e442012-03-01 12:41:01 -08004108 tpnt->immediate_filemark = 0;
Linus Torvalds1da177e2005-04-16 15:20:36 -07004109 tpnt->default_drvbuffer = 0xff; /* No forced buffering */
4110 tpnt->partition = 0;
4111 tpnt->new_partition = 0;
4112 tpnt->nbr_partitions = 0;
James Bottomleya02488e2008-11-30 10:36:26 -06004113 blk_queue_rq_timeout(tpnt->device->request_queue, ST_TIMEOUT);
Linus Torvalds1da177e2005-04-16 15:20:36 -07004114 tpnt->long_timeout = ST_LONG_TIMEOUT;
4115 tpnt->try_dio = try_direct_io && !SDp->host->unchecked_isa_dma;
4116
Linus Torvalds1da177e2005-04-16 15:20:36 -07004117 for (i = 0; i < ST_NBR_MODES; i++) {
4118 STm = &(tpnt->modes[i]);
4119 STm->defined = 0;
4120 STm->sysv = ST_SYSV;
4121 STm->defaults_for_writes = 0;
4122 STm->do_async_writes = ST_ASYNC_WRITES;
4123 STm->do_buffer_writes = ST_BUFFER_WRITES;
4124 STm->do_read_ahead = ST_READ_AHEAD;
4125 STm->default_compression = ST_DONT_TOUCH;
4126 STm->default_blksize = (-1); /* No forced size */
4127 STm->default_density = (-1); /* No forced density */
4128 }
4129
4130 for (i = 0; i < ST_NBR_PARTITIONS; i++) {
4131 STps = &(tpnt->ps[i]);
4132 STps->rw = ST_IDLE;
4133 STps->eof = ST_NOEOF;
4134 STps->at_sm = 0;
4135 STps->last_block_valid = 0;
4136 STps->drv_block = (-1);
4137 STps->drv_file = (-1);
4138 }
4139
4140 tpnt->current_mode = 0;
4141 tpnt->modes[0].defined = 1;
4142
4143 tpnt->density_changed = tpnt->compression_changed =
4144 tpnt->blksize_changed = 0;
Matthias Kaehlcke28f85002007-07-29 23:38:15 +02004145 mutex_init(&tpnt->lock);
Linus Torvalds1da177e2005-04-16 15:20:36 -07004146
4147 st_nr_dev++;
4148 write_unlock(&st_dev_arr_lock);
4149
4150 for (mode = 0; mode < ST_NBR_MODES; ++mode) {
4151 STm = &(tpnt->modes[mode]);
4152 for (j=0; j < 2; j++) {
4153 cdev = cdev_alloc();
4154 if (!cdev) {
4155 printk(KERN_ERR
4156 "st%d: out of memory. Device not attached.\n",
4157 dev_num);
4158 goto out_free_tape;
4159 }
4160 cdev->owner = THIS_MODULE;
4161 cdev->ops = &st_fops;
4162
4163 error = cdev_add(cdev,
4164 MKDEV(SCSI_TAPE_MAJOR, TAPE_MINOR(dev_num, mode, j)),
4165 1);
4166 if (error) {
4167 printk(KERN_ERR "st%d: Can't add %s-rewind mode %d\n",
4168 dev_num, j ? "non" : "auto", mode);
4169 printk(KERN_ERR "st%d: Device not attached.\n", dev_num);
4170 goto out_free_tape;
4171 }
4172 STm->cdevs[j] = cdev;
4173
4174 }
Jeff Garzik13026a62006-10-04 06:00:38 -04004175 error = do_create_class_files(tpnt, dev_num, mode);
4176 if (error)
4177 goto out_free_tape;
Linus Torvalds1da177e2005-04-16 15:20:36 -07004178 }
Oliver Neukum46a243f2012-01-15 00:16:51 +01004179 scsi_autopm_put_device(SDp);
Linus Torvalds1da177e2005-04-16 15:20:36 -07004180
Kai Makisara422528542006-11-07 21:56:38 +02004181 sdev_printk(KERN_NOTICE, SDp,
Rene Herman8b1ea242006-05-20 15:00:22 -07004182 "Attached scsi tape %s\n", tape_name(tpnt));
Kai Makisara422528542006-11-07 21:56:38 +02004183 sdev_printk(KERN_INFO, SDp, "%s: try direct i/o: %s (alignment %d B)\n",
4184 tape_name(tpnt), tpnt->try_dio ? "yes" : "no",
4185 queue_dma_alignment(SDp->request_queue) + 1);
Linus Torvalds1da177e2005-04-16 15:20:36 -07004186
4187 return 0;
4188
4189out_free_tape:
4190 for (mode=0; mode < ST_NBR_MODES; mode++) {
4191 STm = &(tpnt->modes[mode]);
4192 sysfs_remove_link(&tpnt->device->sdev_gendev.kobj,
4193 "tape");
4194 for (j=0; j < 2; j++) {
4195 if (STm->cdevs[j]) {
4196 if (cdev == STm->cdevs[j])
4197 cdev = NULL;
Tony Jonesee959b02008-02-22 00:13:36 +01004198 device_destroy(st_sysfs_class,
4199 MKDEV(SCSI_TAPE_MAJOR,
4200 TAPE_MINOR(i, mode, j)));
Linus Torvalds1da177e2005-04-16 15:20:36 -07004201 cdev_del(STm->cdevs[j]);
4202 }
4203 }
4204 }
4205 if (cdev)
4206 cdev_del(cdev);
4207 write_lock(&st_dev_arr_lock);
4208 scsi_tapes[dev_num] = NULL;
4209 st_nr_dev--;
4210 write_unlock(&st_dev_arr_lock);
4211out_put_disk:
4212 put_disk(disk);
Jesper Juhlc9475cb2005-11-07 01:01:26 -08004213 kfree(tpnt);
Linus Torvalds1da177e2005-04-16 15:20:36 -07004214out_buffer_free:
4215 kfree(buffer);
4216out:
4217 return -ENODEV;
4218};
4219
4220
4221static int st_remove(struct device *dev)
4222{
4223 struct scsi_device *SDp = to_scsi_device(dev);
4224 struct scsi_tape *tpnt;
4225 int i, j, mode;
4226
Oliver Neukum46a243f2012-01-15 00:16:51 +01004227 scsi_autopm_get_device(SDp);
Linus Torvalds1da177e2005-04-16 15:20:36 -07004228 write_lock(&st_dev_arr_lock);
4229 for (i = 0; i < st_dev_max; i++) {
4230 tpnt = scsi_tapes[i];
4231 if (tpnt != NULL && tpnt->device == SDp) {
4232 scsi_tapes[i] = NULL;
4233 st_nr_dev--;
4234 write_unlock(&st_dev_arr_lock);
Linus Torvalds1da177e2005-04-16 15:20:36 -07004235 sysfs_remove_link(&tpnt->device->sdev_gendev.kobj,
4236 "tape");
4237 for (mode = 0; mode < ST_NBR_MODES; ++mode) {
Linus Torvalds1da177e2005-04-16 15:20:36 -07004238 for (j=0; j < 2; j++) {
Tony Jonesee959b02008-02-22 00:13:36 +01004239 device_destroy(st_sysfs_class,
4240 MKDEV(SCSI_TAPE_MAJOR,
4241 TAPE_MINOR(i, mode, j)));
Linus Torvalds1da177e2005-04-16 15:20:36 -07004242 cdev_del(tpnt->modes[mode].cdevs[j]);
4243 tpnt->modes[mode].cdevs[j] = NULL;
4244 }
4245 }
Linus Torvalds1da177e2005-04-16 15:20:36 -07004246
Arjan van de Ven0b950672006-01-11 13:16:10 +01004247 mutex_lock(&st_ref_mutex);
Kai Makisaraf03a5672005-08-02 13:40:47 +03004248 kref_put(&tpnt->kref, scsi_tape_release);
Arjan van de Ven0b950672006-01-11 13:16:10 +01004249 mutex_unlock(&st_ref_mutex);
Linus Torvalds1da177e2005-04-16 15:20:36 -07004250 return 0;
4251 }
4252 }
4253
4254 write_unlock(&st_dev_arr_lock);
4255 return 0;
4256}
4257
Kai Makisaraf03a5672005-08-02 13:40:47 +03004258/**
4259 * scsi_tape_release - Called to free the Scsi_Tape structure
4260 * @kref: pointer to embedded kref
4261 *
Arjan van de Ven0b950672006-01-11 13:16:10 +01004262 * st_ref_mutex must be held entering this routine. Because it is
Kai Makisaraf03a5672005-08-02 13:40:47 +03004263 * called on last put, you should always use the scsi_tape_get()
4264 * scsi_tape_put() helpers which manipulate the semaphore directly
4265 * and never do a direct kref_put().
4266 **/
4267static void scsi_tape_release(struct kref *kref)
4268{
4269 struct scsi_tape *tpnt = to_scsi_tape(kref);
4270 struct gendisk *disk = tpnt->disk;
4271
4272 tpnt->device = NULL;
4273
4274 if (tpnt->buffer) {
Kai Makisaraf03a5672005-08-02 13:40:47 +03004275 normalize_buffer(tpnt->buffer);
FUJITA Tomonorid0e1ae32008-12-18 14:49:40 +09004276 kfree(tpnt->buffer->reserved_pages);
Kai Makisaraf03a5672005-08-02 13:40:47 +03004277 kfree(tpnt->buffer);
4278 }
4279
4280 disk->private_data = NULL;
4281 put_disk(disk);
4282 kfree(tpnt);
4283 return;
4284}
4285
Linus Torvalds1da177e2005-04-16 15:20:36 -07004286static int __init init_st(void)
4287{
Jeff Garzik13026a62006-10-04 06:00:38 -04004288 int err;
4289
Linus Torvalds1da177e2005-04-16 15:20:36 -07004290 validate_options();
4291
Jeff Garzik13026a62006-10-04 06:00:38 -04004292 printk(KERN_INFO "st: Version %s, fixed bufsize %d, s/g segs %d\n",
Linus Torvalds1da177e2005-04-16 15:20:36 -07004293 verstr, st_fixed_buffer_size, st_max_sg_segs);
4294
gregkh@suse.ded2538782005-03-23 09:55:22 -08004295 st_sysfs_class = class_create(THIS_MODULE, "scsi_tape");
Linus Torvalds1da177e2005-04-16 15:20:36 -07004296 if (IS_ERR(st_sysfs_class)) {
Linus Torvalds1da177e2005-04-16 15:20:36 -07004297 printk(KERN_ERR "Unable create sysfs class for SCSI tapes\n");
Jeff Garzik13026a62006-10-04 06:00:38 -04004298 return PTR_ERR(st_sysfs_class);
Linus Torvalds1da177e2005-04-16 15:20:36 -07004299 }
4300
Jeff Garzik13026a62006-10-04 06:00:38 -04004301 err = register_chrdev_region(MKDEV(SCSI_TAPE_MAJOR, 0),
4302 ST_MAX_TAPE_ENTRIES, "st");
4303 if (err) {
4304 printk(KERN_ERR "Unable to get major %d for SCSI tapes\n",
4305 SCSI_TAPE_MAJOR);
4306 goto err_class;
Linus Torvalds1da177e2005-04-16 15:20:36 -07004307 }
Jeff Garzik13026a62006-10-04 06:00:38 -04004308
4309 err = scsi_register_driver(&st_template.gendrv);
4310 if (err)
4311 goto err_chrdev;
4312
Robert P. J. Day405ae7d2007-02-17 19:13:42 +01004313 err = do_create_sysfs_files();
Jeff Garzik13026a62006-10-04 06:00:38 -04004314 if (err)
4315 goto err_scsidrv;
4316
4317 return 0;
4318
4319err_scsidrv:
4320 scsi_unregister_driver(&st_template.gendrv);
4321err_chrdev:
4322 unregister_chrdev_region(MKDEV(SCSI_TAPE_MAJOR, 0),
4323 ST_MAX_TAPE_ENTRIES);
4324err_class:
Kai Makisarac2c96f42005-08-02 12:21:51 +03004325 class_destroy(st_sysfs_class);
Jeff Garzik13026a62006-10-04 06:00:38 -04004326 return err;
Linus Torvalds1da177e2005-04-16 15:20:36 -07004327}
4328
4329static void __exit exit_st(void)
4330{
Robert P. J. Day405ae7d2007-02-17 19:13:42 +01004331 do_remove_sysfs_files();
Linus Torvalds1da177e2005-04-16 15:20:36 -07004332 scsi_unregister_driver(&st_template.gendrv);
4333 unregister_chrdev_region(MKDEV(SCSI_TAPE_MAJOR, 0),
4334 ST_MAX_TAPE_ENTRIES);
Kai Makisarac2c96f42005-08-02 12:21:51 +03004335 class_destroy(st_sysfs_class);
Linus Torvalds1da177e2005-04-16 15:20:36 -07004336 kfree(scsi_tapes);
4337 printk(KERN_INFO "st: Unloaded.\n");
4338}
4339
4340module_init(init_st);
4341module_exit(exit_st);
4342
4343
4344/* The sysfs driver interface. Read-only at the moment */
4345static ssize_t st_try_direct_io_show(struct device_driver *ddp, char *buf)
4346{
4347 return snprintf(buf, PAGE_SIZE, "%d\n", try_direct_io);
4348}
4349static DRIVER_ATTR(try_direct_io, S_IRUGO, st_try_direct_io_show, NULL);
4350
4351static ssize_t st_fixed_buffer_size_show(struct device_driver *ddp, char *buf)
4352{
4353 return snprintf(buf, PAGE_SIZE, "%d\n", st_fixed_buffer_size);
4354}
4355static DRIVER_ATTR(fixed_buffer_size, S_IRUGO, st_fixed_buffer_size_show, NULL);
4356
4357static ssize_t st_max_sg_segs_show(struct device_driver *ddp, char *buf)
4358{
4359 return snprintf(buf, PAGE_SIZE, "%d\n", st_max_sg_segs);
4360}
4361static DRIVER_ATTR(max_sg_segs, S_IRUGO, st_max_sg_segs_show, NULL);
4362
4363static ssize_t st_version_show(struct device_driver *ddd, char *buf)
4364{
4365 return snprintf(buf, PAGE_SIZE, "[%s]\n", verstr);
4366}
4367static DRIVER_ATTR(version, S_IRUGO, st_version_show, NULL);
4368
Robert P. J. Day405ae7d2007-02-17 19:13:42 +01004369static int do_create_sysfs_files(void)
Linus Torvalds1da177e2005-04-16 15:20:36 -07004370{
Robert P. J. Day405ae7d2007-02-17 19:13:42 +01004371 struct device_driver *sysfs = &st_template.gendrv;
Jeff Garzik13026a62006-10-04 06:00:38 -04004372 int err;
Linus Torvalds1da177e2005-04-16 15:20:36 -07004373
Robert P. J. Day405ae7d2007-02-17 19:13:42 +01004374 err = driver_create_file(sysfs, &driver_attr_try_direct_io);
Jeff Garzik13026a62006-10-04 06:00:38 -04004375 if (err)
4376 return err;
Robert P. J. Day405ae7d2007-02-17 19:13:42 +01004377 err = driver_create_file(sysfs, &driver_attr_fixed_buffer_size);
Jeff Garzik13026a62006-10-04 06:00:38 -04004378 if (err)
4379 goto err_try_direct_io;
Robert P. J. Day405ae7d2007-02-17 19:13:42 +01004380 err = driver_create_file(sysfs, &driver_attr_max_sg_segs);
Jeff Garzik13026a62006-10-04 06:00:38 -04004381 if (err)
4382 goto err_attr_fixed_buf;
Robert P. J. Day405ae7d2007-02-17 19:13:42 +01004383 err = driver_create_file(sysfs, &driver_attr_version);
Jeff Garzik13026a62006-10-04 06:00:38 -04004384 if (err)
4385 goto err_attr_max_sg;
4386
4387 return 0;
4388
4389err_attr_max_sg:
Robert P. J. Day405ae7d2007-02-17 19:13:42 +01004390 driver_remove_file(sysfs, &driver_attr_max_sg_segs);
Jeff Garzik13026a62006-10-04 06:00:38 -04004391err_attr_fixed_buf:
Robert P. J. Day405ae7d2007-02-17 19:13:42 +01004392 driver_remove_file(sysfs, &driver_attr_fixed_buffer_size);
Jeff Garzik13026a62006-10-04 06:00:38 -04004393err_try_direct_io:
Robert P. J. Day405ae7d2007-02-17 19:13:42 +01004394 driver_remove_file(sysfs, &driver_attr_try_direct_io);
Jeff Garzik13026a62006-10-04 06:00:38 -04004395 return err;
Linus Torvalds1da177e2005-04-16 15:20:36 -07004396}
4397
Robert P. J. Day405ae7d2007-02-17 19:13:42 +01004398static void do_remove_sysfs_files(void)
Linus Torvalds1da177e2005-04-16 15:20:36 -07004399{
Robert P. J. Day405ae7d2007-02-17 19:13:42 +01004400 struct device_driver *sysfs = &st_template.gendrv;
Linus Torvalds1da177e2005-04-16 15:20:36 -07004401
Robert P. J. Day405ae7d2007-02-17 19:13:42 +01004402 driver_remove_file(sysfs, &driver_attr_version);
4403 driver_remove_file(sysfs, &driver_attr_max_sg_segs);
4404 driver_remove_file(sysfs, &driver_attr_fixed_buffer_size);
4405 driver_remove_file(sysfs, &driver_attr_try_direct_io);
Linus Torvalds1da177e2005-04-16 15:20:36 -07004406}
4407
4408
4409/* The sysfs simple class interface */
Tony Jonesee959b02008-02-22 00:13:36 +01004410static ssize_t
4411st_defined_show(struct device *dev, struct device_attribute *attr, char *buf)
Linus Torvalds1da177e2005-04-16 15:20:36 -07004412{
James Bottomley7d15d6a2008-03-14 14:12:43 -07004413 struct st_modedef *STm = dev_get_drvdata(dev);
Linus Torvalds1da177e2005-04-16 15:20:36 -07004414 ssize_t l = 0;
4415
4416 l = snprintf(buf, PAGE_SIZE, "%d\n", STm->defined);
4417 return l;
4418}
4419
Tony Jonesee959b02008-02-22 00:13:36 +01004420DEVICE_ATTR(defined, S_IRUGO, st_defined_show, NULL);
Linus Torvalds1da177e2005-04-16 15:20:36 -07004421
Tony Jonesee959b02008-02-22 00:13:36 +01004422static ssize_t
4423st_defblk_show(struct device *dev, struct device_attribute *attr, char *buf)
Linus Torvalds1da177e2005-04-16 15:20:36 -07004424{
James Bottomley7d15d6a2008-03-14 14:12:43 -07004425 struct st_modedef *STm = dev_get_drvdata(dev);
Linus Torvalds1da177e2005-04-16 15:20:36 -07004426 ssize_t l = 0;
4427
4428 l = snprintf(buf, PAGE_SIZE, "%d\n", STm->default_blksize);
4429 return l;
4430}
4431
Tony Jonesee959b02008-02-22 00:13:36 +01004432DEVICE_ATTR(default_blksize, S_IRUGO, st_defblk_show, NULL);
Linus Torvalds1da177e2005-04-16 15:20:36 -07004433
Tony Jonesee959b02008-02-22 00:13:36 +01004434static ssize_t
4435st_defdensity_show(struct device *dev, struct device_attribute *attr, char *buf)
Linus Torvalds1da177e2005-04-16 15:20:36 -07004436{
James Bottomley7d15d6a2008-03-14 14:12:43 -07004437 struct st_modedef *STm = dev_get_drvdata(dev);
Linus Torvalds1da177e2005-04-16 15:20:36 -07004438 ssize_t l = 0;
4439 char *fmt;
4440
4441 fmt = STm->default_density >= 0 ? "0x%02x\n" : "%d\n";
4442 l = snprintf(buf, PAGE_SIZE, fmt, STm->default_density);
4443 return l;
4444}
4445
Tony Jonesee959b02008-02-22 00:13:36 +01004446DEVICE_ATTR(default_density, S_IRUGO, st_defdensity_show, NULL);
Linus Torvalds1da177e2005-04-16 15:20:36 -07004447
Tony Jonesee959b02008-02-22 00:13:36 +01004448static ssize_t
4449st_defcompression_show(struct device *dev, struct device_attribute *attr,
4450 char *buf)
Linus Torvalds1da177e2005-04-16 15:20:36 -07004451{
James Bottomley7d15d6a2008-03-14 14:12:43 -07004452 struct st_modedef *STm = dev_get_drvdata(dev);
Linus Torvalds1da177e2005-04-16 15:20:36 -07004453 ssize_t l = 0;
4454
4455 l = snprintf(buf, PAGE_SIZE, "%d\n", STm->default_compression - 1);
4456 return l;
4457}
4458
Tony Jonesee959b02008-02-22 00:13:36 +01004459DEVICE_ATTR(default_compression, S_IRUGO, st_defcompression_show, NULL);
Linus Torvalds1da177e2005-04-16 15:20:36 -07004460
Tony Jonesee959b02008-02-22 00:13:36 +01004461static ssize_t
4462st_options_show(struct device *dev, struct device_attribute *attr, char *buf)
Kai Makisarab174be02008-02-24 22:29:12 +02004463{
James Bottomley7d15d6a2008-03-14 14:12:43 -07004464 struct st_modedef *STm = dev_get_drvdata(dev);
Kai Makisarab174be02008-02-24 22:29:12 +02004465 struct scsi_tape *STp;
4466 int i, j, options;
4467 ssize_t l = 0;
4468
4469 for (i=0; i < st_dev_max; i++) {
4470 for (j=0; j < ST_NBR_MODES; j++)
4471 if (&scsi_tapes[i]->modes[j] == STm)
4472 break;
4473 if (j < ST_NBR_MODES)
4474 break;
4475 }
4476 if (i == st_dev_max)
4477 return 0; /* should never happen */
4478
4479 STp = scsi_tapes[i];
4480
4481 options = STm->do_buffer_writes ? MT_ST_BUFFER_WRITES : 0;
4482 options |= STm->do_async_writes ? MT_ST_ASYNC_WRITES : 0;
4483 options |= STm->do_read_ahead ? MT_ST_READ_AHEAD : 0;
4484 DEB( options |= debugging ? MT_ST_DEBUGGING : 0 );
4485 options |= STp->two_fm ? MT_ST_TWO_FM : 0;
4486 options |= STp->fast_mteom ? MT_ST_FAST_MTEOM : 0;
4487 options |= STm->defaults_for_writes ? MT_ST_DEF_WRITES : 0;
4488 options |= STp->can_bsr ? MT_ST_CAN_BSR : 0;
4489 options |= STp->omit_blklims ? MT_ST_NO_BLKLIMS : 0;
4490 options |= STp->can_partitions ? MT_ST_CAN_PARTITIONS : 0;
4491 options |= STp->scsi2_logical ? MT_ST_SCSI2LOGICAL : 0;
4492 options |= STm->sysv ? MT_ST_SYSV : 0;
4493 options |= STp->immediate ? MT_ST_NOWAIT : 0;
Lee Duncanc743e442012-03-01 12:41:01 -08004494 options |= STp->immediate_filemark ? MT_ST_NOWAIT_EOF : 0;
Kai Makisarab174be02008-02-24 22:29:12 +02004495 options |= STp->sili ? MT_ST_SILI : 0;
4496
4497 l = snprintf(buf, PAGE_SIZE, "0x%08x\n", options);
4498 return l;
4499}
4500
Tony Jonesee959b02008-02-22 00:13:36 +01004501DEVICE_ATTR(options, S_IRUGO, st_options_show, NULL);
Kai Makisarab174be02008-02-24 22:29:12 +02004502
Jeff Garzik13026a62006-10-04 06:00:38 -04004503static int do_create_class_files(struct scsi_tape *STp, int dev_num, int mode)
Linus Torvalds1da177e2005-04-16 15:20:36 -07004504{
4505 int i, rew, error;
4506 char name[10];
Tony Jonesee959b02008-02-22 00:13:36 +01004507 struct device *st_class_member;
Linus Torvalds1da177e2005-04-16 15:20:36 -07004508
Linus Torvalds1da177e2005-04-16 15:20:36 -07004509 for (rew=0; rew < 2; rew++) {
4510 /* Make sure that the minor numbers corresponding to the four
4511 first modes always get the same names */
4512 i = mode << (4 - ST_NBR_MODE_BITS);
4513 snprintf(name, 10, "%s%s%s", rew ? "n" : "",
4514 STp->disk->disk_name, st_formats[i]);
4515 st_class_member =
Greg Kroah-Hartmand73a1a672008-07-21 20:03:34 -07004516 device_create(st_sysfs_class, &STp->device->sdev_gendev,
4517 MKDEV(SCSI_TAPE_MAJOR,
4518 TAPE_MINOR(dev_num, mode, rew)),
4519 &STp->modes[mode], "%s", name);
Linus Torvalds1da177e2005-04-16 15:20:36 -07004520 if (IS_ERR(st_class_member)) {
Tony Jonesee959b02008-02-22 00:13:36 +01004521 printk(KERN_WARNING "st%d: device_create failed\n",
Linus Torvalds1da177e2005-04-16 15:20:36 -07004522 dev_num);
Jeff Garzik13026a62006-10-04 06:00:38 -04004523 error = PTR_ERR(st_class_member);
Linus Torvalds1da177e2005-04-16 15:20:36 -07004524 goto out;
4525 }
Linus Torvalds1da177e2005-04-16 15:20:36 -07004526
Tony Jonesee959b02008-02-22 00:13:36 +01004527 error = device_create_file(st_class_member,
4528 &dev_attr_defined);
Jeff Garzik13026a62006-10-04 06:00:38 -04004529 if (error) goto out;
Tony Jonesee959b02008-02-22 00:13:36 +01004530 error = device_create_file(st_class_member,
4531 &dev_attr_default_blksize);
Jeff Garzik13026a62006-10-04 06:00:38 -04004532 if (error) goto out;
Tony Jonesee959b02008-02-22 00:13:36 +01004533 error = device_create_file(st_class_member,
4534 &dev_attr_default_density);
Jeff Garzik13026a62006-10-04 06:00:38 -04004535 if (error) goto out;
Tony Jonesee959b02008-02-22 00:13:36 +01004536 error = device_create_file(st_class_member,
4537 &dev_attr_default_compression);
Jeff Garzik13026a62006-10-04 06:00:38 -04004538 if (error) goto out;
Tony Jonesee959b02008-02-22 00:13:36 +01004539 error = device_create_file(st_class_member,
4540 &dev_attr_options);
Kai Makisarab174be02008-02-24 22:29:12 +02004541 if (error) goto out;
Jeff Garzik13026a62006-10-04 06:00:38 -04004542
Linus Torvalds1da177e2005-04-16 15:20:36 -07004543 if (mode == 0 && rew == 0) {
4544 error = sysfs_create_link(&STp->device->sdev_gendev.kobj,
4545 &st_class_member->kobj,
4546 "tape");
4547 if (error) {
4548 printk(KERN_ERR
4549 "st%d: Can't create sysfs link from SCSI device.\n",
4550 dev_num);
Jeff Garzik13026a62006-10-04 06:00:38 -04004551 goto out;
Linus Torvalds1da177e2005-04-16 15:20:36 -07004552 }
4553 }
4554 }
Jeff Garzik13026a62006-10-04 06:00:38 -04004555
4556 return 0;
4557
4558out:
4559 return error;
Linus Torvalds1da177e2005-04-16 15:20:36 -07004560}
4561
Linus Torvalds1da177e2005-04-16 15:20:36 -07004562/* The following functions may be useful for a larger audience. */
FUJITA Tomonori66207422008-12-18 14:49:43 +09004563static int sgl_map_user_pages(struct st_buffer *STbp,
4564 const unsigned int max_pages, unsigned long uaddr,
4565 size_t count, int rw)
Linus Torvalds1da177e2005-04-16 15:20:36 -07004566{
James Bottomley07542b82005-08-31 20:27:22 -04004567 unsigned long end = (uaddr + count + PAGE_SIZE - 1) >> PAGE_SHIFT;
4568 unsigned long start = uaddr >> PAGE_SHIFT;
4569 const int nr_pages = end - start;
Linus Torvalds1da177e2005-04-16 15:20:36 -07004570 int res, i, j;
Linus Torvalds1da177e2005-04-16 15:20:36 -07004571 struct page **pages;
FUJITA Tomonori66207422008-12-18 14:49:43 +09004572 struct rq_map_data *mdata = &STbp->map_data;
Linus Torvalds1da177e2005-04-16 15:20:36 -07004573
Linus Torvalds1da177e2005-04-16 15:20:36 -07004574 /* User attempted Overflow! */
4575 if ((uaddr + count) < uaddr)
4576 return -EINVAL;
4577
4578 /* Too big */
4579 if (nr_pages > max_pages)
4580 return -ENOMEM;
4581
4582 /* Hmm? */
4583 if (count == 0)
4584 return 0;
4585
4586 if ((pages = kmalloc(max_pages * sizeof(*pages), GFP_KERNEL)) == NULL)
4587 return -ENOMEM;
4588
4589 /* Try to fault in all of the necessary pages */
4590 down_read(&current->mm->mmap_sem);
4591 /* rw==READ means read from drive, write into memory area */
4592 res = get_user_pages(
4593 current,
4594 current->mm,
4595 uaddr,
4596 nr_pages,
4597 rw == READ,
4598 0, /* don't force */
4599 pages,
4600 NULL);
4601 up_read(&current->mm->mmap_sem);
4602
4603 /* Errors and no page mapped should return here */
4604 if (res < nr_pages)
4605 goto out_unmap;
4606
4607 for (i=0; i < nr_pages; i++) {
4608 /* FIXME: flush superflous for rw==READ,
4609 * probably wrong function for rw==WRITE
4610 */
4611 flush_dcache_page(pages[i]);
4612 }
4613
FUJITA Tomonori66207422008-12-18 14:49:43 +09004614 mdata->offset = uaddr & ~PAGE_MASK;
FUJITA Tomonori66207422008-12-18 14:49:43 +09004615 STbp->mapped_pages = pages;
Linus Torvalds1da177e2005-04-16 15:20:36 -07004616
Linus Torvalds1da177e2005-04-16 15:20:36 -07004617 return nr_pages;
Linus Torvalds1da177e2005-04-16 15:20:36 -07004618 out_unmap:
4619 if (res > 0) {
4620 for (j=0; j < res; j++)
4621 page_cache_release(pages[j]);
Hugh Dickins6bc733e2005-12-01 20:21:57 +00004622 res = 0;
Linus Torvalds1da177e2005-04-16 15:20:36 -07004623 }
4624 kfree(pages);
4625 return res;
4626}
4627
4628
4629/* And unmap them... */
FUJITA Tomonori66207422008-12-18 14:49:43 +09004630static int sgl_unmap_user_pages(struct st_buffer *STbp,
4631 const unsigned int nr_pages, int dirtied)
Linus Torvalds1da177e2005-04-16 15:20:36 -07004632{
4633 int i;
4634
4635 for (i=0; i < nr_pages; i++) {
FUJITA Tomonori66207422008-12-18 14:49:43 +09004636 struct page *page = STbp->mapped_pages[i];
Nick Pigginb5810032005-10-29 18:16:12 -07004637
Nick Pigginb5810032005-10-29 18:16:12 -07004638 if (dirtied)
4639 SetPageDirty(page);
Linus Torvalds1da177e2005-04-16 15:20:36 -07004640 /* FIXME: cache flush missing for rw==READ
4641 * FIXME: call the correct reference counting function
4642 */
Nick Pigginb5810032005-10-29 18:16:12 -07004643 page_cache_release(page);
Linus Torvalds1da177e2005-04-16 15:20:36 -07004644 }
FUJITA Tomonori66207422008-12-18 14:49:43 +09004645 kfree(STbp->mapped_pages);
4646 STbp->mapped_pages = NULL;
Linus Torvalds1da177e2005-04-16 15:20:36 -07004647
4648 return 0;
4649}