blob: 052622fdba0286e460cf8d4a664f18a7fa0a18d0 [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>
Jeff Mahoney6c648d92012-08-18 15:20:39 -040040#include <linux/idr.h>
Linus Torvalds1da177e2005-04-16 15:20:36 -070041#include <linux/delay.h>
Arjan van de Ven0b950672006-01-11 13:16:10 +010042#include <linux/mutex.h>
Linus Torvalds1da177e2005-04-16 15:20:36 -070043
44#include <asm/uaccess.h>
45#include <asm/dma.h>
Linus Torvalds1da177e2005-04-16 15:20:36 -070046
47#include <scsi/scsi.h>
48#include <scsi/scsi_dbg.h>
49#include <scsi/scsi_device.h>
50#include <scsi/scsi_driver.h>
51#include <scsi/scsi_eh.h>
52#include <scsi/scsi_host.h>
53#include <scsi/scsi_ioctl.h>
Kai Makisara 16c4b3e2005-05-01 18:11:55 +030054#include <scsi/sg.h>
Linus Torvalds1da177e2005-04-16 15:20:36 -070055
56
57/* The driver prints some debugging information on the console if DEBUG
58 is defined and non-zero. */
59#define DEBUG 0
60
61#if DEBUG
62/* The message level for the debug messages is currently set to KERN_NOTICE
63 so that people can easily see the messages. Later when the debugging messages
64 in the drivers are more widely classified, this may be changed to KERN_DEBUG. */
65#define ST_DEB_MSG KERN_NOTICE
66#define DEB(a) a
67#define DEBC(a) if (debugging) { a ; }
68#else
69#define DEB(a)
70#define DEBC(a)
71#endif
72
73#define ST_KILOBYTE 1024
74
75#include "st_options.h"
76#include "st.h"
77
Arnd Bergmann2a48fc02010-06-02 14:28:52 +020078static DEFINE_MUTEX(st_mutex);
Linus Torvalds1da177e2005-04-16 15:20:36 -070079static int buffer_kbs;
80static int max_sg_segs;
81static int try_direct_io = TRY_DIRECT_IO;
82static int try_rdio = 1;
83static int try_wdio = 1;
84
Jeff Mahoneyaf237822012-08-18 15:20:37 -040085static struct class st_sysfs_class;
86static struct device_attribute st_dev_attrs[];
Linus Torvalds1da177e2005-04-16 15:20:36 -070087
88MODULE_AUTHOR("Kai Makisara");
Rene Hermanf018fa52006-03-08 00:14:20 -080089MODULE_DESCRIPTION("SCSI tape (st) driver");
Linus Torvalds1da177e2005-04-16 15:20:36 -070090MODULE_LICENSE("GPL");
Rene Hermanf018fa52006-03-08 00:14:20 -080091MODULE_ALIAS_CHARDEV_MAJOR(SCSI_TAPE_MAJOR);
Michael Tokarevd7b8bcb2006-10-27 16:02:37 +040092MODULE_ALIAS_SCSI_DEVICE(TYPE_TAPE);
Linus Torvalds1da177e2005-04-16 15:20:36 -070093
94/* Set 'perm' (4th argument) to 0 to disable module_param's definition
95 * of sysfs parameters (which module_param doesn't yet support).
96 * Sysfs parameters defined explicitly later.
97 */
98module_param_named(buffer_kbs, buffer_kbs, int, 0);
99MODULE_PARM_DESC(buffer_kbs, "Default driver buffer size for fixed block mode (KB; 32)");
100module_param_named(max_sg_segs, max_sg_segs, int, 0);
101MODULE_PARM_DESC(max_sg_segs, "Maximum number of scatter/gather segments to use (256)");
102module_param_named(try_direct_io, try_direct_io, int, 0);
103MODULE_PARM_DESC(try_direct_io, "Try direct I/O between user buffer and tape drive (1)");
104
105/* Extra parameters for testing */
106module_param_named(try_rdio, try_rdio, int, 0);
107MODULE_PARM_DESC(try_rdio, "Try direct read i/o when possible");
108module_param_named(try_wdio, try_wdio, int, 0);
109MODULE_PARM_DESC(try_wdio, "Try direct write i/o when possible");
110
111#ifndef MODULE
112static int write_threshold_kbs; /* retained for compatibility */
113static struct st_dev_parm {
114 char *name;
115 int *val;
116} parms[] __initdata = {
117 {
118 "buffer_kbs", &buffer_kbs
119 },
120 { /* Retained for compatibility with 2.4 */
121 "write_threshold_kbs", &write_threshold_kbs
122 },
123 {
124 "max_sg_segs", NULL
125 },
126 {
127 "try_direct_io", &try_direct_io
128 }
129};
130#endif
131
132/* Restrict the number of modes so that names for all are assigned */
133#if ST_NBR_MODES > 16
134#error "Maximum number of modes is 16"
135#endif
136/* Bit reversed order to get same names for same minors with all
137 mode counts */
Arjan van de Ven0ad78202005-11-28 16:22:25 +0100138static const char *st_formats[] = {
Linus Torvalds1da177e2005-04-16 15:20:36 -0700139 "", "r", "k", "s", "l", "t", "o", "u",
140 "m", "v", "p", "x", "a", "y", "q", "z"};
141
142/* The default definitions have been moved to st_options.h */
143
144#define ST_FIXED_BUFFER_SIZE (ST_FIXED_BUFFER_BLOCKS * ST_KILOBYTE)
145
146/* The buffer size should fit into the 24 bits for length in the
147 6-byte SCSI read and write commands. */
148#if ST_FIXED_BUFFER_SIZE >= (2 << 24 - 1)
149#error "Buffer size should not exceed (2 << 24 - 1) bytes!"
150#endif
151
152static int debugging = DEBUG;
153
154#define MAX_RETRIES 0
155#define MAX_WRITE_RETRIES 0
156#define MAX_READY_RETRIES 0
157#define NO_TAPE NOT_READY
158
159#define ST_TIMEOUT (900 * HZ)
160#define ST_LONG_TIMEOUT (14000 * HZ)
161
162/* Remove mode bits and auto-rewind bit (7) */
163#define TAPE_NR(x) ( ((iminor(x) & ~255) >> (ST_NBR_MODE_BITS + 1)) | \
164 (iminor(x) & ~(-1 << ST_MODE_SHIFT)) )
165#define TAPE_MODE(x) ((iminor(x) & ST_MODE_MASK) >> ST_MODE_SHIFT)
166
167/* Construct the minor number from the device (d), mode (m), and non-rewind (n) data */
168#define TAPE_MINOR(d, m, n) (((d & ~(255 >> (ST_NBR_MODE_BITS + 1))) << (ST_NBR_MODE_BITS + 1)) | \
169 (d & (255 >> (ST_NBR_MODE_BITS + 1))) | (m << ST_MODE_SHIFT) | ((n != 0) << 7) )
170
171/* Internal ioctl to set both density (uppermost 8 bits) and blocksize (lower
172 24 bits) */
173#define SET_DENS_AND_BLK 0x10001
174
Linus Torvalds1da177e2005-04-16 15:20:36 -0700175static int st_fixed_buffer_size = ST_FIXED_BUFFER_SIZE;
176static int st_max_sg_segs = ST_MAX_SG;
177
Linus Torvalds1da177e2005-04-16 15:20:36 -0700178static int modes_defined;
179
Linus Torvalds1da177e2005-04-16 15:20:36 -0700180static int enlarge_buffer(struct st_buffer *, int, int);
Kai Makisara40f6b362008-02-24 22:23:24 +0200181static void clear_buffer(struct st_buffer *);
Linus Torvalds1da177e2005-04-16 15:20:36 -0700182static void normalize_buffer(struct st_buffer *);
183static int append_to_buffer(const char __user *, struct st_buffer *, int);
184static int from_buffer(struct st_buffer *, char __user *, int);
185static void move_buffer_data(struct st_buffer *, int);
Linus Torvalds1da177e2005-04-16 15:20:36 -0700186
FUJITA Tomonori66207422008-12-18 14:49:43 +0900187static int sgl_map_user_pages(struct st_buffer *, const unsigned int,
Linus Torvalds1da177e2005-04-16 15:20:36 -0700188 unsigned long, size_t, int);
FUJITA Tomonori66207422008-12-18 14:49:43 +0900189static int sgl_unmap_user_pages(struct st_buffer *, const unsigned int, int);
Linus Torvalds1da177e2005-04-16 15:20:36 -0700190
191static int st_probe(struct device *);
192static int st_remove(struct device *);
Linus Torvalds1da177e2005-04-16 15:20:36 -0700193
Robert P. J. Day405ae7d2007-02-17 19:13:42 +0100194static int do_create_sysfs_files(void);
195static void do_remove_sysfs_files(void);
Jeff Garzik13026a62006-10-04 06:00:38 -0400196static int do_create_class_files(struct scsi_tape *, int, int);
Linus Torvalds1da177e2005-04-16 15:20:36 -0700197
198static struct scsi_driver st_template = {
199 .owner = THIS_MODULE,
200 .gendrv = {
201 .name = "st",
202 .probe = st_probe,
203 .remove = st_remove,
204 },
Linus Torvalds1da177e2005-04-16 15:20:36 -0700205};
206
207static int st_compression(struct scsi_tape *, int);
208
209static int find_partition(struct scsi_tape *);
210static int switch_partition(struct scsi_tape *);
211
212static int st_int_ioctl(struct scsi_tape *, unsigned int, unsigned long);
213
Kai Makisaraf03a5672005-08-02 13:40:47 +0300214static void scsi_tape_release(struct kref *);
215
216#define to_scsi_tape(obj) container_of(obj, struct scsi_tape, kref)
217
Arjan van de Ven0b950672006-01-11 13:16:10 +0100218static DEFINE_MUTEX(st_ref_mutex);
Jeff Mahoney6c648d92012-08-18 15:20:39 -0400219static DEFINE_SPINLOCK(st_index_lock);
220static DEFINE_SPINLOCK(st_use_lock);
221static DEFINE_IDR(st_index_idr);
222
Kai Makisaraf03a5672005-08-02 13:40:47 +0300223
Linus Torvalds1da177e2005-04-16 15:20:36 -0700224
225#include "osst_detect.h"
226#ifndef SIGS_FROM_OSST
227#define SIGS_FROM_OSST \
228 {"OnStream", "SC-", "", "osst"}, \
229 {"OnStream", "DI-", "", "osst"}, \
230 {"OnStream", "DP-", "", "osst"}, \
231 {"OnStream", "USB", "", "osst"}, \
232 {"OnStream", "FW-", "", "osst"}
233#endif
234
Kai Makisaraf03a5672005-08-02 13:40:47 +0300235static struct scsi_tape *scsi_tape_get(int dev)
236{
237 struct scsi_tape *STp = NULL;
238
Arjan van de Ven0b950672006-01-11 13:16:10 +0100239 mutex_lock(&st_ref_mutex);
Jeff Mahoney6c648d92012-08-18 15:20:39 -0400240 spin_lock(&st_index_lock);
Kai Makisaraf03a5672005-08-02 13:40:47 +0300241
Jeff Mahoney6c648d92012-08-18 15:20:39 -0400242 STp = idr_find(&st_index_idr, dev);
Kai Makisaraf03a5672005-08-02 13:40:47 +0300243 if (!STp) goto out;
244
245 kref_get(&STp->kref);
246
247 if (!STp->device)
248 goto out_put;
249
250 if (scsi_device_get(STp->device))
251 goto out_put;
252
253 goto out;
254
255out_put:
256 kref_put(&STp->kref, scsi_tape_release);
257 STp = NULL;
258out:
Jeff Mahoney6c648d92012-08-18 15:20:39 -0400259 spin_unlock(&st_index_lock);
Arjan van de Ven0b950672006-01-11 13:16:10 +0100260 mutex_unlock(&st_ref_mutex);
Kai Makisaraf03a5672005-08-02 13:40:47 +0300261 return STp;
262}
263
264static void scsi_tape_put(struct scsi_tape *STp)
265{
266 struct scsi_device *sdev = STp->device;
267
Arjan van de Ven0b950672006-01-11 13:16:10 +0100268 mutex_lock(&st_ref_mutex);
Kai Makisaraf03a5672005-08-02 13:40:47 +0300269 kref_put(&STp->kref, scsi_tape_release);
270 scsi_device_put(sdev);
Arjan van de Ven0b950672006-01-11 13:16:10 +0100271 mutex_unlock(&st_ref_mutex);
Kai Makisaraf03a5672005-08-02 13:40:47 +0300272}
273
Linus Torvalds1da177e2005-04-16 15:20:36 -0700274struct st_reject_data {
275 char *vendor;
276 char *model;
277 char *rev;
278 char *driver_hint; /* Name of the correct driver, NULL if unknown */
279};
280
281static struct st_reject_data reject_list[] = {
282 /* {"XXX", "Yy-", "", NULL}, example */
283 SIGS_FROM_OSST,
284 {NULL, }};
285
286/* If the device signature is on the list of incompatible drives, the
287 function returns a pointer to the name of the correct driver (if known) */
288static char * st_incompatible(struct scsi_device* SDp)
289{
290 struct st_reject_data *rp;
291
292 for (rp=&(reject_list[0]); rp->vendor != NULL; rp++)
293 if (!strncmp(rp->vendor, SDp->vendor, strlen(rp->vendor)) &&
294 !strncmp(rp->model, SDp->model, strlen(rp->model)) &&
295 !strncmp(rp->rev, SDp->rev, strlen(rp->rev))) {
296 if (rp->driver_hint)
297 return rp->driver_hint;
298 else
299 return "unknown";
300 }
301 return NULL;
302}
303
304
305static inline char *tape_name(struct scsi_tape *tape)
306{
307 return tape->disk->disk_name;
308}
309
310
Mike Christie8b05b772005-11-08 04:06:44 -0600311static void st_analyze_sense(struct st_request *SRpnt, struct st_cmdstatus *s)
Linus Torvalds1da177e2005-04-16 15:20:36 -0700312{
313 const u8 *ucp;
Mike Christie8b05b772005-11-08 04:06:44 -0600314 const u8 *sense = SRpnt->sense;
Linus Torvalds1da177e2005-04-16 15:20:36 -0700315
Mike Christie8b05b772005-11-08 04:06:44 -0600316 s->have_sense = scsi_normalize_sense(SRpnt->sense,
317 SCSI_SENSE_BUFFERSIZE, &s->sense_hdr);
Linus Torvalds1da177e2005-04-16 15:20:36 -0700318 s->flags = 0;
319
320 if (s->have_sense) {
321 s->deferred = 0;
322 s->remainder_valid =
323 scsi_get_sense_info_fld(sense, SCSI_SENSE_BUFFERSIZE, &s->uremainder64);
324 switch (sense[0] & 0x7f) {
325 case 0x71:
326 s->deferred = 1;
327 case 0x70:
328 s->fixed_format = 1;
329 s->flags = sense[2] & 0xe0;
330 break;
331 case 0x73:
332 s->deferred = 1;
333 case 0x72:
334 s->fixed_format = 0;
335 ucp = scsi_sense_desc_find(sense, SCSI_SENSE_BUFFERSIZE, 4);
336 s->flags = ucp ? (ucp[3] & 0xe0) : 0;
337 break;
338 }
339 }
340}
341
342
343/* Convert the result to success code */
Mike Christie8b05b772005-11-08 04:06:44 -0600344static int st_chk_result(struct scsi_tape *STp, struct st_request * SRpnt)
Linus Torvalds1da177e2005-04-16 15:20:36 -0700345{
Mike Christie8b05b772005-11-08 04:06:44 -0600346 int result = SRpnt->result;
Linus Torvalds1da177e2005-04-16 15:20:36 -0700347 u8 scode;
348 DEB(const char *stp;)
349 char *name = tape_name(STp);
350 struct st_cmdstatus *cmdstatp;
351
352 if (!result)
353 return 0;
354
355 cmdstatp = &STp->buffer->cmdstat;
Kai Makisaraf03a5672005-08-02 13:40:47 +0300356 st_analyze_sense(SRpnt, cmdstatp);
Linus Torvalds1da177e2005-04-16 15:20:36 -0700357
358 if (cmdstatp->have_sense)
359 scode = STp->buffer->cmdstat.sense_hdr.sense_key;
360 else
361 scode = 0;
362
363 DEB(
364 if (debugging) {
Mike Christie8b05b772005-11-08 04:06:44 -0600365 printk(ST_DEB_MSG "%s: Error: %x, cmd: %x %x %x %x %x %x\n",
Linus Torvalds1da177e2005-04-16 15:20:36 -0700366 name, result,
Mike Christie8b05b772005-11-08 04:06:44 -0600367 SRpnt->cmd[0], SRpnt->cmd[1], SRpnt->cmd[2],
368 SRpnt->cmd[3], SRpnt->cmd[4], SRpnt->cmd[5]);
Linus Torvalds1da177e2005-04-16 15:20:36 -0700369 if (cmdstatp->have_sense)
Luben Tuikov4e73ea72006-07-07 00:02:18 -0700370 __scsi_print_sense(name, SRpnt->sense, SCSI_SENSE_BUFFERSIZE);
Linus Torvalds1da177e2005-04-16 15:20:36 -0700371 } ) /* end DEB */
372 if (!debugging) { /* Abnormal conditions for tape */
373 if (!cmdstatp->have_sense)
374 printk(KERN_WARNING
Martin K. Petersen1c9fbaf2009-01-04 03:14:11 -0500375 "%s: Error %x (driver bt 0x%x, host bt 0x%x).\n",
376 name, result, driver_byte(result),
377 host_byte(result));
Linus Torvalds1da177e2005-04-16 15:20:36 -0700378 else if (cmdstatp->have_sense &&
379 scode != NO_SENSE &&
380 scode != RECOVERED_ERROR &&
381 /* scode != UNIT_ATTENTION && */
382 scode != BLANK_CHECK &&
383 scode != VOLUME_OVERFLOW &&
Mike Christie8b05b772005-11-08 04:06:44 -0600384 SRpnt->cmd[0] != MODE_SENSE &&
385 SRpnt->cmd[0] != TEST_UNIT_READY) {
Luben Tuikov4e73ea72006-07-07 00:02:18 -0700386
387 __scsi_print_sense(name, SRpnt->sense, SCSI_SENSE_BUFFERSIZE);
Linus Torvalds1da177e2005-04-16 15:20:36 -0700388 }
389 }
390
391 if (cmdstatp->fixed_format &&
392 STp->cln_mode >= EXTENDED_SENSE_START) { /* Only fixed format sense */
393 if (STp->cln_sense_value)
Mike Christie8b05b772005-11-08 04:06:44 -0600394 STp->cleaning_req |= ((SRpnt->sense[STp->cln_mode] &
Linus Torvalds1da177e2005-04-16 15:20:36 -0700395 STp->cln_sense_mask) == STp->cln_sense_value);
396 else
Mike Christie8b05b772005-11-08 04:06:44 -0600397 STp->cleaning_req |= ((SRpnt->sense[STp->cln_mode] &
Linus Torvalds1da177e2005-04-16 15:20:36 -0700398 STp->cln_sense_mask) != 0);
399 }
400 if (cmdstatp->have_sense &&
401 cmdstatp->sense_hdr.asc == 0 && cmdstatp->sense_hdr.ascq == 0x17)
402 STp->cleaning_req = 1; /* ASC and ASCQ => cleaning requested */
403
404 STp->pos_unknown |= STp->device->was_reset;
405
406 if (cmdstatp->have_sense &&
407 scode == RECOVERED_ERROR
408#if ST_RECOVERED_WRITE_FATAL
Mike Christie8b05b772005-11-08 04:06:44 -0600409 && SRpnt->cmd[0] != WRITE_6
410 && SRpnt->cmd[0] != WRITE_FILEMARKS
Linus Torvalds1da177e2005-04-16 15:20:36 -0700411#endif
412 ) {
413 STp->recover_count++;
414 STp->recover_reg++;
415
416 DEB(
417 if (debugging) {
Mike Christie8b05b772005-11-08 04:06:44 -0600418 if (SRpnt->cmd[0] == READ_6)
Linus Torvalds1da177e2005-04-16 15:20:36 -0700419 stp = "read";
Mike Christie8b05b772005-11-08 04:06:44 -0600420 else if (SRpnt->cmd[0] == WRITE_6)
Linus Torvalds1da177e2005-04-16 15:20:36 -0700421 stp = "write";
422 else
423 stp = "ioctl";
424 printk(ST_DEB_MSG "%s: Recovered %s error (%d).\n", name, stp,
425 STp->recover_count);
426 } ) /* end DEB */
427
428 if (cmdstatp->flags == 0)
429 return 0;
430 }
431 return (-EIO);
432}
433
FUJITA Tomonori4deba242008-12-05 15:25:20 +0900434static struct st_request *st_allocate_request(struct scsi_tape *stp)
Mike Christie8b05b772005-11-08 04:06:44 -0600435{
FUJITA Tomonori4deba242008-12-05 15:25:20 +0900436 struct st_request *streq;
437
438 streq = kzalloc(sizeof(*streq), GFP_KERNEL);
439 if (streq)
440 streq->stp = stp;
441 else {
442 DEBC(printk(KERN_ERR "%s: Can't get SCSI request.\n",
443 tape_name(stp)););
444 if (signal_pending(current))
445 stp->buffer->syscall_result = -EINTR;
446 else
447 stp->buffer->syscall_result = -EBUSY;
448 }
449
450 return streq;
Mike Christie8b05b772005-11-08 04:06:44 -0600451}
452
453static void st_release_request(struct st_request *streq)
454{
455 kfree(streq);
Linus Torvalds1da177e2005-04-16 15:20:36 -0700456}
457
FUJITA Tomonori13b53b42008-12-18 14:49:41 +0900458static void st_scsi_execute_end(struct request *req, int uptodate)
459{
460 struct st_request *SRpnt = req->end_io_data;
461 struct scsi_tape *STp = SRpnt->stp;
Petr Uzelc68bf8e2011-10-21 13:31:09 +0200462 struct bio *tmp;
FUJITA Tomonori13b53b42008-12-18 14:49:41 +0900463
464 STp->buffer->cmdstat.midlevel_result = SRpnt->result = req->errors;
Tejun Heoc3a4d782009-05-07 22:24:37 +0900465 STp->buffer->cmdstat.residual = req->resid_len;
FUJITA Tomonori13b53b42008-12-18 14:49:41 +0900466
Petr Uzelc68bf8e2011-10-21 13:31:09 +0200467 tmp = SRpnt->bio;
FUJITA Tomonori13b53b42008-12-18 14:49:41 +0900468 if (SRpnt->waiting)
469 complete(SRpnt->waiting);
470
Petr Uzelc68bf8e2011-10-21 13:31:09 +0200471 blk_rq_unmap_user(tmp);
FUJITA Tomonori13b53b42008-12-18 14:49:41 +0900472 __blk_put_request(req->q, req);
473}
474
475static int st_scsi_execute(struct st_request *SRpnt, const unsigned char *cmd,
476 int data_direction, void *buffer, unsigned bufflen,
477 int timeout, int retries)
478{
479 struct request *req;
480 struct rq_map_data *mdata = &SRpnt->stp->buffer->map_data;
481 int err = 0;
482 int write = (data_direction == DMA_TO_DEVICE);
483
484 req = blk_get_request(SRpnt->stp->device->request_queue, write,
485 GFP_KERNEL);
486 if (!req)
487 return DRIVER_ERROR << 24;
488
489 req->cmd_type = REQ_TYPE_BLOCK_PC;
490 req->cmd_flags |= REQ_QUIET;
491
492 mdata->null_mapped = 1;
493
Kai Makisara02ae2c02008-12-18 14:49:50 +0900494 if (bufflen) {
495 err = blk_rq_map_user(req->q, req, mdata, NULL, bufflen,
496 GFP_KERNEL);
497 if (err) {
498 blk_put_request(req);
499 return DRIVER_ERROR << 24;
500 }
FUJITA Tomonori13b53b42008-12-18 14:49:41 +0900501 }
502
503 SRpnt->bio = req->bio;
504 req->cmd_len = COMMAND_SIZE(cmd[0]);
505 memset(req->cmd, 0, BLK_MAX_CDB);
506 memcpy(req->cmd, cmd, req->cmd_len);
507 req->sense = SRpnt->sense;
508 req->sense_len = 0;
509 req->timeout = timeout;
510 req->retries = retries;
511 req->end_io_data = SRpnt;
512
513 blk_execute_rq_nowait(req->q, NULL, req, 1, st_scsi_execute_end);
514 return 0;
515}
516
Linus Torvalds1da177e2005-04-16 15:20:36 -0700517/* Do the scsi command. Waits until command performed if do_wait is true.
518 Otherwise write_behind_check() is used to check that the command
519 has finished. */
Mike Christie8b05b772005-11-08 04:06:44 -0600520static struct st_request *
521st_do_scsi(struct st_request * SRpnt, struct scsi_tape * STp, unsigned char *cmd,
Linus Torvalds1da177e2005-04-16 15:20:36 -0700522 int bytes, int direction, int timeout, int retries, int do_wait)
523{
Kai Makisaraf03a5672005-08-02 13:40:47 +0300524 struct completion *waiting;
FUJITA Tomonori6d476262008-12-18 14:49:42 +0900525 struct rq_map_data *mdata = &STp->buffer->map_data;
526 int ret;
Linus Torvalds1da177e2005-04-16 15:20:36 -0700527
Kai Makisaraf03a5672005-08-02 13:40:47 +0300528 /* if async, make sure there's no command outstanding */
529 if (!do_wait && ((STp->buffer)->last_SRpnt)) {
530 printk(KERN_ERR "%s: Async command already active.\n",
531 tape_name(STp));
532 if (signal_pending(current))
533 (STp->buffer)->syscall_result = (-EINTR);
534 else
535 (STp->buffer)->syscall_result = (-EBUSY);
536 return NULL;
537 }
538
FUJITA Tomonori4deba242008-12-05 15:25:20 +0900539 if (!SRpnt) {
540 SRpnt = st_allocate_request(STp);
541 if (!SRpnt)
Linus Torvalds1da177e2005-04-16 15:20:36 -0700542 return NULL;
Linus Torvalds1da177e2005-04-16 15:20:36 -0700543 }
544
Kai Makisaraf03a5672005-08-02 13:40:47 +0300545 /* If async IO, set last_SRpnt. This ptr tells write_behind_check
546 which IO is outstanding. It's nulled out when the IO completes. */
547 if (!do_wait)
548 (STp->buffer)->last_SRpnt = SRpnt;
549
550 waiting = &STp->wait;
551 init_completion(waiting);
Mike Christie8b05b772005-11-08 04:06:44 -0600552 SRpnt->waiting = waiting;
553
FUJITA Tomonori66207422008-12-18 14:49:43 +0900554 if (STp->buffer->do_dio) {
FUJITA Tomonoric982c362009-11-26 09:24:13 +0900555 mdata->page_order = 0;
FUJITA Tomonori66207422008-12-18 14:49:43 +0900556 mdata->nr_entries = STp->buffer->sg_segs;
557 mdata->pages = STp->buffer->mapped_pages;
558 } else {
FUJITA Tomonoric982c362009-11-26 09:24:13 +0900559 mdata->page_order = STp->buffer->reserved_page_order;
FUJITA Tomonori6d476262008-12-18 14:49:42 +0900560 mdata->nr_entries =
561 DIV_ROUND_UP(bytes, PAGE_SIZE << mdata->page_order);
FUJITA Tomonoric982c362009-11-26 09:24:13 +0900562 mdata->pages = STp->buffer->reserved_pages;
563 mdata->offset = 0;
FUJITA Tomonori6d476262008-12-18 14:49:42 +0900564 }
565
Mike Christie8b05b772005-11-08 04:06:44 -0600566 memcpy(SRpnt->cmd, cmd, sizeof(SRpnt->cmd));
Linus Torvalds1da177e2005-04-16 15:20:36 -0700567 STp->buffer->cmdstat.have_sense = 0;
Mike Christie8b05b772005-11-08 04:06:44 -0600568 STp->buffer->syscall_result = 0;
Linus Torvalds1da177e2005-04-16 15:20:36 -0700569
FUJITA Tomonori66207422008-12-18 14:49:43 +0900570 ret = st_scsi_execute(SRpnt, cmd, direction, NULL, bytes, timeout,
571 retries);
FUJITA Tomonori6d476262008-12-18 14:49:42 +0900572 if (ret) {
Mike Christie8b05b772005-11-08 04:06:44 -0600573 /* could not allocate the buffer or request was too large */
574 (STp->buffer)->syscall_result = (-EBUSY);
Kai Makisara787926b2005-11-13 10:04:44 +0200575 (STp->buffer)->last_SRpnt = NULL;
FUJITA Tomonori6d476262008-12-18 14:49:42 +0900576 } else if (do_wait) {
Kai Makisaraf03a5672005-08-02 13:40:47 +0300577 wait_for_completion(waiting);
Mike Christie8b05b772005-11-08 04:06:44 -0600578 SRpnt->waiting = NULL;
Linus Torvalds1da177e2005-04-16 15:20:36 -0700579 (STp->buffer)->syscall_result = st_chk_result(STp, SRpnt);
580 }
Mike Christie8b05b772005-11-08 04:06:44 -0600581
Linus Torvalds1da177e2005-04-16 15:20:36 -0700582 return SRpnt;
583}
584
585
586/* Handle the write-behind checking (waits for completion). Returns -ENOSPC if
587 write has been correct but EOM early warning reached, -EIO if write ended in
588 error or zero if write successful. Asynchronous writes are used only in
589 variable block mode. */
590static int write_behind_check(struct scsi_tape * STp)
591{
592 int retval = 0;
593 struct st_buffer *STbuffer;
594 struct st_partstat *STps;
595 struct st_cmdstatus *cmdstatp;
Mike Christie8b05b772005-11-08 04:06:44 -0600596 struct st_request *SRpnt;
Linus Torvalds1da177e2005-04-16 15:20:36 -0700597
598 STbuffer = STp->buffer;
599 if (!STbuffer->writing)
600 return 0;
601
602 DEB(
603 if (STp->write_pending)
604 STp->nbr_waits++;
605 else
606 STp->nbr_finished++;
607 ) /* end DEB */
608
609 wait_for_completion(&(STp->wait));
Kai Makisaraf03a5672005-08-02 13:40:47 +0300610 SRpnt = STbuffer->last_SRpnt;
611 STbuffer->last_SRpnt = NULL;
Mike Christie8b05b772005-11-08 04:06:44 -0600612 SRpnt->waiting = NULL;
Linus Torvalds1da177e2005-04-16 15:20:36 -0700613
Kai Makisaraf03a5672005-08-02 13:40:47 +0300614 (STp->buffer)->syscall_result = st_chk_result(STp, SRpnt);
Mike Christie8b05b772005-11-08 04:06:44 -0600615 st_release_request(SRpnt);
Linus Torvalds1da177e2005-04-16 15:20:36 -0700616
617 STbuffer->buffer_bytes -= STbuffer->writing;
618 STps = &(STp->ps[STp->partition]);
619 if (STps->drv_block >= 0) {
620 if (STp->block_size == 0)
621 STps->drv_block++;
622 else
623 STps->drv_block += STbuffer->writing / STp->block_size;
624 }
625
626 cmdstatp = &STbuffer->cmdstat;
627 if (STbuffer->syscall_result) {
628 retval = -EIO;
629 if (cmdstatp->have_sense && !cmdstatp->deferred &&
630 (cmdstatp->flags & SENSE_EOM) &&
631 (cmdstatp->sense_hdr.sense_key == NO_SENSE ||
632 cmdstatp->sense_hdr.sense_key == RECOVERED_ERROR)) {
633 /* EOM at write-behind, has all data been written? */
634 if (!cmdstatp->remainder_valid ||
635 cmdstatp->uremainder64 == 0)
636 retval = -ENOSPC;
637 }
638 if (retval == -EIO)
639 STps->drv_block = -1;
640 }
641 STbuffer->writing = 0;
642
643 DEB(if (debugging && retval)
644 printk(ST_DEB_MSG "%s: Async write error %x, return value %d.\n",
645 tape_name(STp), STbuffer->cmdstat.midlevel_result, retval);) /* end DEB */
646
647 return retval;
648}
649
650
651/* Step over EOF if it has been inadvertently crossed (ioctl not used because
652 it messes up the block number). */
653static int cross_eof(struct scsi_tape * STp, int forward)
654{
Mike Christie8b05b772005-11-08 04:06:44 -0600655 struct st_request *SRpnt;
Linus Torvalds1da177e2005-04-16 15:20:36 -0700656 unsigned char cmd[MAX_COMMAND_SIZE];
657
658 cmd[0] = SPACE;
659 cmd[1] = 0x01; /* Space FileMarks */
660 if (forward) {
661 cmd[2] = cmd[3] = 0;
662 cmd[4] = 1;
663 } else
664 cmd[2] = cmd[3] = cmd[4] = 0xff; /* -1 filemarks */
665 cmd[5] = 0;
666
667 DEBC(printk(ST_DEB_MSG "%s: Stepping over filemark %s.\n",
668 tape_name(STp), forward ? "forward" : "backward"));
669
Kai Makisara02ae2c02008-12-18 14:49:50 +0900670 SRpnt = st_do_scsi(NULL, STp, cmd, 0, DMA_NONE,
671 STp->device->request_queue->rq_timeout,
672 MAX_RETRIES, 1);
Linus Torvalds1da177e2005-04-16 15:20:36 -0700673 if (!SRpnt)
Kai Makisara02ae2c02008-12-18 14:49:50 +0900674 return (STp->buffer)->syscall_result;
Linus Torvalds1da177e2005-04-16 15:20:36 -0700675
Kai Makisara02ae2c02008-12-18 14:49:50 +0900676 st_release_request(SRpnt);
677 SRpnt = NULL;
Linus Torvalds1da177e2005-04-16 15:20:36 -0700678
679 if ((STp->buffer)->cmdstat.midlevel_result != 0)
680 printk(KERN_ERR "%s: Stepping over filemark %s failed.\n",
681 tape_name(STp), forward ? "forward" : "backward");
682
Kai Makisara02ae2c02008-12-18 14:49:50 +0900683 return (STp->buffer)->syscall_result;
Linus Torvalds1da177e2005-04-16 15:20:36 -0700684}
685
686
687/* Flush the write buffer (never need to write if variable blocksize). */
Adrian Bunk8ef8d592008-04-14 17:17:16 +0300688static int st_flush_write_buffer(struct scsi_tape * STp)
Linus Torvalds1da177e2005-04-16 15:20:36 -0700689{
Kai Makisara786231a2008-07-11 15:06:40 +0300690 int transfer, blks;
Linus Torvalds1da177e2005-04-16 15:20:36 -0700691 int result;
692 unsigned char cmd[MAX_COMMAND_SIZE];
Mike Christie8b05b772005-11-08 04:06:44 -0600693 struct st_request *SRpnt;
Linus Torvalds1da177e2005-04-16 15:20:36 -0700694 struct st_partstat *STps;
695
696 result = write_behind_check(STp);
697 if (result)
698 return result;
699
700 result = 0;
701 if (STp->dirty == 1) {
702
Kai Makisara786231a2008-07-11 15:06:40 +0300703 transfer = STp->buffer->buffer_bytes;
Linus Torvalds1da177e2005-04-16 15:20:36 -0700704 DEBC(printk(ST_DEB_MSG "%s: Flushing %d bytes.\n",
705 tape_name(STp), transfer));
706
Linus Torvalds1da177e2005-04-16 15:20:36 -0700707 memset(cmd, 0, MAX_COMMAND_SIZE);
708 cmd[0] = WRITE_6;
709 cmd[1] = 1;
710 blks = transfer / STp->block_size;
711 cmd[2] = blks >> 16;
712 cmd[3] = blks >> 8;
713 cmd[4] = blks;
714
715 SRpnt = st_do_scsi(NULL, STp, cmd, transfer, DMA_TO_DEVICE,
James Bottomleya02488e2008-11-30 10:36:26 -0600716 STp->device->request_queue->rq_timeout,
717 MAX_WRITE_RETRIES, 1);
Linus Torvalds1da177e2005-04-16 15:20:36 -0700718 if (!SRpnt)
719 return (STp->buffer)->syscall_result;
720
721 STps = &(STp->ps[STp->partition]);
722 if ((STp->buffer)->syscall_result != 0) {
723 struct st_cmdstatus *cmdstatp = &STp->buffer->cmdstat;
724
725 if (cmdstatp->have_sense && !cmdstatp->deferred &&
726 (cmdstatp->flags & SENSE_EOM) &&
727 (cmdstatp->sense_hdr.sense_key == NO_SENSE ||
728 cmdstatp->sense_hdr.sense_key == RECOVERED_ERROR) &&
729 (!cmdstatp->remainder_valid ||
730 cmdstatp->uremainder64 == 0)) { /* All written at EOM early warning */
731 STp->dirty = 0;
732 (STp->buffer)->buffer_bytes = 0;
733 if (STps->drv_block >= 0)
734 STps->drv_block += blks;
735 result = (-ENOSPC);
736 } else {
737 printk(KERN_ERR "%s: Error on flush.\n",
738 tape_name(STp));
739 STps->drv_block = (-1);
740 result = (-EIO);
741 }
742 } else {
743 if (STps->drv_block >= 0)
744 STps->drv_block += blks;
745 STp->dirty = 0;
746 (STp->buffer)->buffer_bytes = 0;
747 }
Mike Christie8b05b772005-11-08 04:06:44 -0600748 st_release_request(SRpnt);
Linus Torvalds1da177e2005-04-16 15:20:36 -0700749 SRpnt = NULL;
750 }
751 return result;
752}
753
754
755/* Flush the tape buffer. The tape will be positioned correctly unless
756 seek_next is true. */
757static int flush_buffer(struct scsi_tape *STp, int seek_next)
758{
759 int backspace, result;
760 struct st_buffer *STbuffer;
761 struct st_partstat *STps;
762
763 STbuffer = STp->buffer;
764
765 /*
766 * If there was a bus reset, block further access
767 * to this device.
768 */
769 if (STp->pos_unknown)
770 return (-EIO);
771
772 if (STp->ready != ST_READY)
773 return 0;
774 STps = &(STp->ps[STp->partition]);
775 if (STps->rw == ST_WRITING) /* Writing */
Adrian Bunk8ef8d592008-04-14 17:17:16 +0300776 return st_flush_write_buffer(STp);
Linus Torvalds1da177e2005-04-16 15:20:36 -0700777
778 if (STp->block_size == 0)
779 return 0;
780
781 backspace = ((STp->buffer)->buffer_bytes +
782 (STp->buffer)->read_pointer) / STp->block_size -
783 ((STp->buffer)->read_pointer + STp->block_size - 1) /
784 STp->block_size;
785 (STp->buffer)->buffer_bytes = 0;
786 (STp->buffer)->read_pointer = 0;
787 result = 0;
788 if (!seek_next) {
789 if (STps->eof == ST_FM_HIT) {
790 result = cross_eof(STp, 0); /* Back over the EOF hit */
791 if (!result)
792 STps->eof = ST_NOEOF;
793 else {
794 if (STps->drv_file >= 0)
795 STps->drv_file++;
796 STps->drv_block = 0;
797 }
798 }
799 if (!result && backspace > 0)
800 result = st_int_ioctl(STp, MTBSR, backspace);
801 } else if (STps->eof == ST_FM_HIT) {
802 if (STps->drv_file >= 0)
803 STps->drv_file++;
804 STps->drv_block = 0;
805 STps->eof = ST_NOEOF;
806 }
807 return result;
808
809}
810
811/* Set the mode parameters */
812static int set_mode_densblk(struct scsi_tape * STp, struct st_modedef * STm)
813{
814 int set_it = 0;
815 unsigned long arg;
816 char *name = tape_name(STp);
817
818 if (!STp->density_changed &&
819 STm->default_density >= 0 &&
820 STm->default_density != STp->density) {
821 arg = STm->default_density;
822 set_it = 1;
823 } else
824 arg = STp->density;
825 arg <<= MT_ST_DENSITY_SHIFT;
826 if (!STp->blksize_changed &&
827 STm->default_blksize >= 0 &&
828 STm->default_blksize != STp->block_size) {
829 arg |= STm->default_blksize;
830 set_it = 1;
831 } else
832 arg |= STp->block_size;
833 if (set_it &&
834 st_int_ioctl(STp, SET_DENS_AND_BLK, arg)) {
835 printk(KERN_WARNING
836 "%s: Can't set default block size to %d bytes and density %x.\n",
837 name, STm->default_blksize, STm->default_density);
838 if (modes_defined)
839 return (-EINVAL);
840 }
841 return 0;
842}
843
844
Mike Christie8b05b772005-11-08 04:06:44 -0600845/* Lock or unlock the drive door. Don't use when st_request allocated. */
Linus Torvalds1da177e2005-04-16 15:20:36 -0700846static int do_door_lock(struct scsi_tape * STp, int do_lock)
847{
848 int retval, cmd;
849 DEB(char *name = tape_name(STp);)
850
851
852 cmd = do_lock ? SCSI_IOCTL_DOORLOCK : SCSI_IOCTL_DOORUNLOCK;
853 DEBC(printk(ST_DEB_MSG "%s: %socking drive door.\n", name,
854 do_lock ? "L" : "Unl"));
855 retval = scsi_ioctl(STp->device, cmd, NULL);
856 if (!retval) {
857 STp->door_locked = do_lock ? ST_LOCKED_EXPLICIT : ST_UNLOCKED;
858 }
859 else {
860 STp->door_locked = ST_LOCK_FAILS;
861 }
862 return retval;
863}
864
865
866/* Set the internal state after reset */
867static void reset_state(struct scsi_tape *STp)
868{
869 int i;
870 struct st_partstat *STps;
871
872 STp->pos_unknown = 0;
873 for (i = 0; i < ST_NBR_PARTITIONS; i++) {
874 STps = &(STp->ps[i]);
875 STps->rw = ST_IDLE;
876 STps->eof = ST_NOEOF;
877 STps->at_sm = 0;
878 STps->last_block_valid = 0;
879 STps->drv_block = -1;
880 STps->drv_file = -1;
881 }
882 if (STp->can_partitions) {
883 STp->partition = find_partition(STp);
884 if (STp->partition < 0)
885 STp->partition = 0;
886 STp->new_partition = STp->partition;
887 }
888}
889
890/* Test if the drive is ready. Returns either one of the codes below or a negative system
891 error code. */
892#define CHKRES_READY 0
893#define CHKRES_NEW_SESSION 1
894#define CHKRES_NOT_READY 2
895#define CHKRES_NO_TAPE 3
896
897#define MAX_ATTENTIONS 10
898
899static int test_ready(struct scsi_tape *STp, int do_wait)
900{
901 int attentions, waits, max_wait, scode;
902 int retval = CHKRES_READY, new_session = 0;
903 unsigned char cmd[MAX_COMMAND_SIZE];
Kai Makisara02ae2c02008-12-18 14:49:50 +0900904 struct st_request *SRpnt = NULL;
Linus Torvalds1da177e2005-04-16 15:20:36 -0700905 struct st_cmdstatus *cmdstatp = &STp->buffer->cmdstat;
906
907 max_wait = do_wait ? ST_BLOCK_SECONDS : 0;
908
909 for (attentions=waits=0; ; ) {
910 memset((void *) &cmd[0], 0, MAX_COMMAND_SIZE);
911 cmd[0] = TEST_UNIT_READY;
Kai Makisara02ae2c02008-12-18 14:49:50 +0900912 SRpnt = st_do_scsi(SRpnt, STp, cmd, 0, DMA_NONE,
913 STp->long_timeout, MAX_READY_RETRIES, 1);
Linus Torvalds1da177e2005-04-16 15:20:36 -0700914
Kai Makisara02ae2c02008-12-18 14:49:50 +0900915 if (!SRpnt) {
916 retval = (STp->buffer)->syscall_result;
Linus Torvalds1da177e2005-04-16 15:20:36 -0700917 break;
Kai Makisara02ae2c02008-12-18 14:49:50 +0900918 }
Linus Torvalds1da177e2005-04-16 15:20:36 -0700919
920 if (cmdstatp->have_sense) {
921
922 scode = cmdstatp->sense_hdr.sense_key;
923
924 if (scode == UNIT_ATTENTION) { /* New media? */
925 new_session = 1;
926 if (attentions < MAX_ATTENTIONS) {
927 attentions++;
928 continue;
929 }
930 else {
931 retval = (-EIO);
932 break;
933 }
934 }
935
936 if (scode == NOT_READY) {
937 if (waits < max_wait) {
938 if (msleep_interruptible(1000)) {
939 retval = (-EINTR);
940 break;
941 }
942 waits++;
943 continue;
944 }
945 else {
946 if ((STp->device)->scsi_level >= SCSI_2 &&
947 cmdstatp->sense_hdr.asc == 0x3a) /* Check ASC */
948 retval = CHKRES_NO_TAPE;
949 else
950 retval = CHKRES_NOT_READY;
951 break;
952 }
953 }
954 }
955
956 retval = (STp->buffer)->syscall_result;
957 if (!retval)
958 retval = new_session ? CHKRES_NEW_SESSION : CHKRES_READY;
959 break;
960 }
961
Kai Makisara02ae2c02008-12-18 14:49:50 +0900962 if (SRpnt != NULL)
963 st_release_request(SRpnt);
Linus Torvalds1da177e2005-04-16 15:20:36 -0700964 return retval;
965}
966
967
968/* See if the drive is ready and gather information about the tape. Return values:
969 < 0 negative error code from errno.h
970 0 drive ready
971 1 drive not ready (possibly no tape)
972*/
973static int check_tape(struct scsi_tape *STp, struct file *filp)
974{
975 int i, retval, new_session = 0, do_wait;
976 unsigned char cmd[MAX_COMMAND_SIZE], saved_cleaning;
977 unsigned short st_flags = filp->f_flags;
Mike Christie8b05b772005-11-08 04:06:44 -0600978 struct st_request *SRpnt = NULL;
Linus Torvalds1da177e2005-04-16 15:20:36 -0700979 struct st_modedef *STm;
980 struct st_partstat *STps;
981 char *name = tape_name(STp);
Josef Sipek7ac62072006-12-08 02:37:37 -0800982 struct inode *inode = filp->f_path.dentry->d_inode;
Linus Torvalds1da177e2005-04-16 15:20:36 -0700983 int mode = TAPE_MODE(inode);
984
985 STp->ready = ST_READY;
986
987 if (mode != STp->current_mode) {
988 DEBC(printk(ST_DEB_MSG "%s: Mode change from %d to %d.\n",
989 name, STp->current_mode, mode));
990 new_session = 1;
991 STp->current_mode = mode;
992 }
993 STm = &(STp->modes[STp->current_mode]);
994
995 saved_cleaning = STp->cleaning_req;
996 STp->cleaning_req = 0;
997
998 do_wait = ((filp->f_flags & O_NONBLOCK) == 0);
999 retval = test_ready(STp, do_wait);
1000
1001 if (retval < 0)
1002 goto err_out;
1003
1004 if (retval == CHKRES_NEW_SESSION) {
1005 STp->pos_unknown = 0;
1006 STp->partition = STp->new_partition = 0;
1007 if (STp->can_partitions)
1008 STp->nbr_partitions = 1; /* This guess will be updated later
1009 if necessary */
1010 for (i = 0; i < ST_NBR_PARTITIONS; i++) {
1011 STps = &(STp->ps[i]);
1012 STps->rw = ST_IDLE;
1013 STps->eof = ST_NOEOF;
1014 STps->at_sm = 0;
1015 STps->last_block_valid = 0;
1016 STps->drv_block = 0;
1017 STps->drv_file = 0;
1018 }
1019 new_session = 1;
1020 }
1021 else {
1022 STp->cleaning_req |= saved_cleaning;
1023
1024 if (retval == CHKRES_NOT_READY || retval == CHKRES_NO_TAPE) {
1025 if (retval == CHKRES_NO_TAPE)
1026 STp->ready = ST_NO_TAPE;
1027 else
1028 STp->ready = ST_NOT_READY;
1029
1030 STp->density = 0; /* Clear the erroneous "residue" */
1031 STp->write_prot = 0;
1032 STp->block_size = 0;
1033 STp->ps[0].drv_file = STp->ps[0].drv_block = (-1);
1034 STp->partition = STp->new_partition = 0;
1035 STp->door_locked = ST_UNLOCKED;
1036 return CHKRES_NOT_READY;
1037 }
1038 }
1039
1040 if (STp->omit_blklims)
1041 STp->min_block = STp->max_block = (-1);
1042 else {
1043 memset((void *) &cmd[0], 0, MAX_COMMAND_SIZE);
1044 cmd[0] = READ_BLOCK_LIMITS;
1045
Kai Makisara02ae2c02008-12-18 14:49:50 +09001046 SRpnt = st_do_scsi(SRpnt, STp, cmd, 6, DMA_FROM_DEVICE,
1047 STp->device->request_queue->rq_timeout,
1048 MAX_READY_RETRIES, 1);
1049 if (!SRpnt) {
1050 retval = (STp->buffer)->syscall_result;
Linus Torvalds1da177e2005-04-16 15:20:36 -07001051 goto err_out;
1052 }
1053
Mike Christie8b05b772005-11-08 04:06:44 -06001054 if (!SRpnt->result && !STp->buffer->cmdstat.have_sense) {
Linus Torvalds1da177e2005-04-16 15:20:36 -07001055 STp->max_block = ((STp->buffer)->b_data[1] << 16) |
1056 ((STp->buffer)->b_data[2] << 8) | (STp->buffer)->b_data[3];
1057 STp->min_block = ((STp->buffer)->b_data[4] << 8) |
1058 (STp->buffer)->b_data[5];
1059 if ( DEB( debugging || ) !STp->inited)
Kai Makisara422528542006-11-07 21:56:38 +02001060 printk(KERN_INFO
Linus Torvalds1da177e2005-04-16 15:20:36 -07001061 "%s: Block limits %d - %d bytes.\n", name,
1062 STp->min_block, STp->max_block);
1063 } else {
1064 STp->min_block = STp->max_block = (-1);
1065 DEBC(printk(ST_DEB_MSG "%s: Can't read block limits.\n",
1066 name));
1067 }
1068 }
1069
1070 memset((void *) &cmd[0], 0, MAX_COMMAND_SIZE);
1071 cmd[0] = MODE_SENSE;
1072 cmd[4] = 12;
1073
Kai Makisara02ae2c02008-12-18 14:49:50 +09001074 SRpnt = st_do_scsi(SRpnt, STp, cmd, 12, DMA_FROM_DEVICE,
1075 STp->device->request_queue->rq_timeout,
1076 MAX_READY_RETRIES, 1);
1077 if (!SRpnt) {
1078 retval = (STp->buffer)->syscall_result;
Linus Torvalds1da177e2005-04-16 15:20:36 -07001079 goto err_out;
1080 }
1081
1082 if ((STp->buffer)->syscall_result != 0) {
1083 DEBC(printk(ST_DEB_MSG "%s: No Mode Sense.\n", name));
1084 STp->block_size = ST_DEFAULT_BLOCK; /* Educated guess (?) */
1085 (STp->buffer)->syscall_result = 0; /* Prevent error propagation */
1086 STp->drv_write_prot = 0;
1087 } else {
1088 DEBC(printk(ST_DEB_MSG
1089 "%s: Mode sense. Length %d, medium %x, WBS %x, BLL %d\n",
1090 name,
1091 (STp->buffer)->b_data[0], (STp->buffer)->b_data[1],
1092 (STp->buffer)->b_data[2], (STp->buffer)->b_data[3]));
1093
1094 if ((STp->buffer)->b_data[3] >= 8) {
1095 STp->drv_buffer = ((STp->buffer)->b_data[2] >> 4) & 7;
1096 STp->density = (STp->buffer)->b_data[4];
1097 STp->block_size = (STp->buffer)->b_data[9] * 65536 +
1098 (STp->buffer)->b_data[10] * 256 + (STp->buffer)->b_data[11];
1099 DEBC(printk(ST_DEB_MSG
1100 "%s: Density %x, tape length: %x, drv buffer: %d\n",
1101 name, STp->density, (STp->buffer)->b_data[5] * 65536 +
1102 (STp->buffer)->b_data[6] * 256 + (STp->buffer)->b_data[7],
1103 STp->drv_buffer));
1104 }
1105 STp->drv_write_prot = ((STp->buffer)->b_data[2] & 0x80) != 0;
Lee Duncanc743e442012-03-01 12:41:01 -08001106 if (!STp->drv_buffer && STp->immediate_filemark) {
1107 printk(KERN_WARNING
1108 "%s: non-buffered tape: disabling writing immediate filemarks\n",
1109 name);
1110 STp->immediate_filemark = 0;
1111 }
Linus Torvalds1da177e2005-04-16 15:20:36 -07001112 }
Mike Christie8b05b772005-11-08 04:06:44 -06001113 st_release_request(SRpnt);
Linus Torvalds1da177e2005-04-16 15:20:36 -07001114 SRpnt = NULL;
1115 STp->inited = 1;
1116
1117 if (STp->block_size > 0)
1118 (STp->buffer)->buffer_blocks =
1119 (STp->buffer)->buffer_size / STp->block_size;
1120 else
1121 (STp->buffer)->buffer_blocks = 1;
1122 (STp->buffer)->buffer_bytes = (STp->buffer)->read_pointer = 0;
1123
1124 DEBC(printk(ST_DEB_MSG
1125 "%s: Block size: %d, buffer size: %d (%d blocks).\n", name,
1126 STp->block_size, (STp->buffer)->buffer_size,
1127 (STp->buffer)->buffer_blocks));
1128
1129 if (STp->drv_write_prot) {
1130 STp->write_prot = 1;
1131
1132 DEBC(printk(ST_DEB_MSG "%s: Write protected\n", name));
1133
1134 if (do_wait &&
1135 ((st_flags & O_ACCMODE) == O_WRONLY ||
1136 (st_flags & O_ACCMODE) == O_RDWR)) {
1137 retval = (-EROFS);
1138 goto err_out;
1139 }
1140 }
1141
1142 if (STp->can_partitions && STp->nbr_partitions < 1) {
1143 /* This code is reached when the device is opened for the first time
1144 after the driver has been initialized with tape in the drive and the
1145 partition support has been enabled. */
1146 DEBC(printk(ST_DEB_MSG
1147 "%s: Updating partition number in status.\n", name));
1148 if ((STp->partition = find_partition(STp)) < 0) {
1149 retval = STp->partition;
1150 goto err_out;
1151 }
1152 STp->new_partition = STp->partition;
1153 STp->nbr_partitions = 1; /* This guess will be updated when necessary */
1154 }
1155
1156 if (new_session) { /* Change the drive parameters for the new mode */
1157 STp->density_changed = STp->blksize_changed = 0;
1158 STp->compression_changed = 0;
1159 if (!(STm->defaults_for_writes) &&
1160 (retval = set_mode_densblk(STp, STm)) < 0)
1161 goto err_out;
1162
1163 if (STp->default_drvbuffer != 0xff) {
1164 if (st_int_ioctl(STp, MTSETDRVBUFFER, STp->default_drvbuffer))
1165 printk(KERN_WARNING
1166 "%s: Can't set default drive buffering to %d.\n",
1167 name, STp->default_drvbuffer);
1168 }
1169 }
1170
1171 return CHKRES_READY;
1172
1173 err_out:
1174 return retval;
1175}
1176
1177
Jonathan Corbetb3369c62008-05-15 16:08:15 -06001178 /* Open the device. Needs to take the BKL only because of incrementing the SCSI host
Linus Torvalds1da177e2005-04-16 15:20:36 -07001179 module count. */
1180static int st_open(struct inode *inode, struct file *filp)
1181{
1182 int i, retval = (-EIO);
Oliver Neukum46a243f2012-01-15 00:16:51 +01001183 int resumed = 0;
Linus Torvalds1da177e2005-04-16 15:20:36 -07001184 struct scsi_tape *STp;
1185 struct st_partstat *STps;
1186 int dev = TAPE_NR(inode);
1187 char *name;
1188
Arnd Bergmann2a48fc02010-06-02 14:28:52 +02001189 mutex_lock(&st_mutex);
Linus Torvalds1da177e2005-04-16 15:20:36 -07001190 /*
1191 * We really want to do nonseekable_open(inode, filp); here, but some
1192 * versions of tar incorrectly call lseek on tapes and bail out if that
1193 * fails. So we disallow pread() and pwrite(), but permit lseeks.
1194 */
1195 filp->f_mode &= ~(FMODE_PREAD | FMODE_PWRITE);
1196
Jonathan Corbetb3369c62008-05-15 16:08:15 -06001197 if (!(STp = scsi_tape_get(dev))) {
Arnd Bergmann2a48fc02010-06-02 14:28:52 +02001198 mutex_unlock(&st_mutex);
Kai Makisaraf03a5672005-08-02 13:40:47 +03001199 return -ENXIO;
Jonathan Corbetb3369c62008-05-15 16:08:15 -06001200 }
Kai Makisaraf03a5672005-08-02 13:40:47 +03001201
Linus Torvalds1da177e2005-04-16 15:20:36 -07001202 filp->private_data = STp;
1203 name = tape_name(STp);
1204
Jeff Mahoney6c648d92012-08-18 15:20:39 -04001205 spin_lock(&st_use_lock);
Linus Torvalds1da177e2005-04-16 15:20:36 -07001206 if (STp->in_use) {
Jeff Mahoney6c648d92012-08-18 15:20:39 -04001207 spin_unlock(&st_use_lock);
Kai Makisaraf03a5672005-08-02 13:40:47 +03001208 scsi_tape_put(STp);
Arnd Bergmann2a48fc02010-06-02 14:28:52 +02001209 mutex_unlock(&st_mutex);
Linus Torvalds1da177e2005-04-16 15:20:36 -07001210 DEB( printk(ST_DEB_MSG "%s: Device already in use.\n", name); )
1211 return (-EBUSY);
1212 }
1213
Linus Torvalds1da177e2005-04-16 15:20:36 -07001214 STp->in_use = 1;
Jeff Mahoney6c648d92012-08-18 15:20:39 -04001215 spin_unlock(&st_use_lock);
Linus Torvalds1da177e2005-04-16 15:20:36 -07001216 STp->rew_at_close = STp->autorew_dev = (iminor(inode) & 0x80) == 0;
1217
Oliver Neukum46a243f2012-01-15 00:16:51 +01001218 if (scsi_autopm_get_device(STp->device) < 0) {
1219 retval = -EIO;
1220 goto err_out;
1221 }
1222 resumed = 1;
Linus Torvalds1da177e2005-04-16 15:20:36 -07001223 if (!scsi_block_when_processing_errors(STp->device)) {
1224 retval = (-ENXIO);
1225 goto err_out;
1226 }
1227
1228 /* See that we have at least a one page buffer available */
1229 if (!enlarge_buffer(STp->buffer, PAGE_SIZE, STp->restr_dma)) {
1230 printk(KERN_WARNING "%s: Can't allocate one page tape buffer.\n",
1231 name);
1232 retval = (-EOVERFLOW);
1233 goto err_out;
1234 }
1235
Kai Makisara40f6b362008-02-24 22:23:24 +02001236 (STp->buffer)->cleared = 0;
Linus Torvalds1da177e2005-04-16 15:20:36 -07001237 (STp->buffer)->writing = 0;
1238 (STp->buffer)->syscall_result = 0;
1239
1240 STp->write_prot = ((filp->f_flags & O_ACCMODE) == O_RDONLY);
1241
1242 STp->dirty = 0;
1243 for (i = 0; i < ST_NBR_PARTITIONS; i++) {
1244 STps = &(STp->ps[i]);
1245 STps->rw = ST_IDLE;
1246 }
Kai Makisara9abe16c2007-02-03 13:21:29 +02001247 STp->try_dio_now = STp->try_dio;
Linus Torvalds1da177e2005-04-16 15:20:36 -07001248 STp->recover_count = 0;
1249 DEB( STp->nbr_waits = STp->nbr_finished = 0;
Kai Makisaradeee13d2008-02-22 20:11:21 +02001250 STp->nbr_requests = STp->nbr_dio = STp->nbr_pages = 0; )
Linus Torvalds1da177e2005-04-16 15:20:36 -07001251
1252 retval = check_tape(STp, filp);
1253 if (retval < 0)
1254 goto err_out;
1255 if ((filp->f_flags & O_NONBLOCK) == 0 &&
1256 retval != CHKRES_READY) {
Kai Makisara413f7322006-10-05 22:59:46 +03001257 if (STp->ready == NO_TAPE)
1258 retval = (-ENOMEDIUM);
1259 else
1260 retval = (-EIO);
Linus Torvalds1da177e2005-04-16 15:20:36 -07001261 goto err_out;
1262 }
Arnd Bergmann2a48fc02010-06-02 14:28:52 +02001263 mutex_unlock(&st_mutex);
Linus Torvalds1da177e2005-04-16 15:20:36 -07001264 return 0;
1265
1266 err_out:
1267 normalize_buffer(STp->buffer);
1268 STp->in_use = 0;
Kai Makisaraf03a5672005-08-02 13:40:47 +03001269 scsi_tape_put(STp);
Oliver Neukum46a243f2012-01-15 00:16:51 +01001270 if (resumed)
1271 scsi_autopm_put_device(STp->device);
Arnd Bergmann2a48fc02010-06-02 14:28:52 +02001272 mutex_unlock(&st_mutex);
Linus Torvalds1da177e2005-04-16 15:20:36 -07001273 return retval;
1274
1275}
1276
1277
1278/* Flush the tape buffer before close */
Miklos Szeredi75e1fcc2006-06-23 02:05:12 -07001279static int st_flush(struct file *filp, fl_owner_t id)
Linus Torvalds1da177e2005-04-16 15:20:36 -07001280{
1281 int result = 0, result2;
1282 unsigned char cmd[MAX_COMMAND_SIZE];
Mike Christie8b05b772005-11-08 04:06:44 -06001283 struct st_request *SRpnt;
Linus Torvalds1da177e2005-04-16 15:20:36 -07001284 struct scsi_tape *STp = filp->private_data;
1285 struct st_modedef *STm = &(STp->modes[STp->current_mode]);
1286 struct st_partstat *STps = &(STp->ps[STp->partition]);
1287 char *name = tape_name(STp);
1288
1289 if (file_count(filp) > 1)
1290 return 0;
1291
1292 if (STps->rw == ST_WRITING && !STp->pos_unknown) {
Adrian Bunk8ef8d592008-04-14 17:17:16 +03001293 result = st_flush_write_buffer(STp);
Linus Torvalds1da177e2005-04-16 15:20:36 -07001294 if (result != 0 && result != (-ENOSPC))
1295 goto out;
1296 }
1297
1298 if (STp->can_partitions &&
1299 (result2 = switch_partition(STp)) < 0) {
1300 DEBC(printk(ST_DEB_MSG
1301 "%s: switch_partition at close failed.\n", name));
1302 if (result == 0)
1303 result = result2;
1304 goto out;
1305 }
1306
1307 DEBC( if (STp->nbr_requests)
Kai Makisaradeee13d2008-02-22 20:11:21 +02001308 printk(KERN_DEBUG "%s: Number of r/w requests %d, dio used in %d, pages %d.\n",
1309 name, STp->nbr_requests, STp->nbr_dio, STp->nbr_pages));
Linus Torvalds1da177e2005-04-16 15:20:36 -07001310
1311 if (STps->rw == ST_WRITING && !STp->pos_unknown) {
1312 struct st_cmdstatus *cmdstatp = &STp->buffer->cmdstat;
1313
1314 DEBC(printk(ST_DEB_MSG "%s: Async write waits %d, finished %d.\n",
1315 name, STp->nbr_waits, STp->nbr_finished);
1316 )
1317
1318 memset(cmd, 0, MAX_COMMAND_SIZE);
1319 cmd[0] = WRITE_FILEMARKS;
Lee Duncanc743e442012-03-01 12:41:01 -08001320 if (STp->immediate_filemark)
1321 cmd[1] = 1;
Linus Torvalds1da177e2005-04-16 15:20:36 -07001322 cmd[4] = 1 + STp->two_fm;
1323
Kai Makisara02ae2c02008-12-18 14:49:50 +09001324 SRpnt = st_do_scsi(NULL, STp, cmd, 0, DMA_NONE,
1325 STp->device->request_queue->rq_timeout,
1326 MAX_WRITE_RETRIES, 1);
Linus Torvalds1da177e2005-04-16 15:20:36 -07001327 if (!SRpnt) {
Kai Makisara02ae2c02008-12-18 14:49:50 +09001328 result = (STp->buffer)->syscall_result;
Linus Torvalds1da177e2005-04-16 15:20:36 -07001329 goto out;
1330 }
1331
1332 if (STp->buffer->syscall_result == 0 ||
1333 (cmdstatp->have_sense && !cmdstatp->deferred &&
1334 (cmdstatp->flags & SENSE_EOM) &&
1335 (cmdstatp->sense_hdr.sense_key == NO_SENSE ||
1336 cmdstatp->sense_hdr.sense_key == RECOVERED_ERROR) &&
1337 (!cmdstatp->remainder_valid || cmdstatp->uremainder64 == 0))) {
1338 /* Write successful at EOM */
Mike Christie8b05b772005-11-08 04:06:44 -06001339 st_release_request(SRpnt);
Linus Torvalds1da177e2005-04-16 15:20:36 -07001340 SRpnt = NULL;
1341 if (STps->drv_file >= 0)
1342 STps->drv_file++;
1343 STps->drv_block = 0;
1344 if (STp->two_fm)
1345 cross_eof(STp, 0);
1346 STps->eof = ST_FM;
1347 }
1348 else { /* Write error */
Mike Christie8b05b772005-11-08 04:06:44 -06001349 st_release_request(SRpnt);
Linus Torvalds1da177e2005-04-16 15:20:36 -07001350 SRpnt = NULL;
1351 printk(KERN_ERR "%s: Error on write filemark.\n", name);
1352 if (result == 0)
1353 result = (-EIO);
1354 }
1355
1356 DEBC(printk(ST_DEB_MSG "%s: Buffer flushed, %d EOF(s) written\n",
1357 name, cmd[4]));
1358 } else if (!STp->rew_at_close) {
1359 STps = &(STp->ps[STp->partition]);
1360 if (!STm->sysv || STps->rw != ST_READING) {
1361 if (STp->can_bsr)
1362 result = flush_buffer(STp, 0);
1363 else if (STps->eof == ST_FM_HIT) {
1364 result = cross_eof(STp, 0);
1365 if (result) {
1366 if (STps->drv_file >= 0)
1367 STps->drv_file++;
1368 STps->drv_block = 0;
1369 STps->eof = ST_FM;
1370 } else
1371 STps->eof = ST_NOEOF;
1372 }
1373 } else if ((STps->eof == ST_NOEOF &&
1374 !(result = cross_eof(STp, 1))) ||
1375 STps->eof == ST_FM_HIT) {
1376 if (STps->drv_file >= 0)
1377 STps->drv_file++;
1378 STps->drv_block = 0;
1379 STps->eof = ST_FM;
1380 }
1381 }
1382
1383 out:
1384 if (STp->rew_at_close) {
1385 result2 = st_int_ioctl(STp, MTREW, 1);
1386 if (result == 0)
1387 result = result2;
1388 }
1389 return result;
1390}
1391
1392
1393/* Close the device and release it. BKL is not needed: this is the only thread
1394 accessing this tape. */
1395static int st_release(struct inode *inode, struct file *filp)
1396{
1397 int result = 0;
1398 struct scsi_tape *STp = filp->private_data;
1399
1400 if (STp->door_locked == ST_LOCKED_AUTO)
1401 do_door_lock(STp, 0);
1402
1403 normalize_buffer(STp->buffer);
Jeff Mahoney6c648d92012-08-18 15:20:39 -04001404 spin_lock(&st_use_lock);
Linus Torvalds1da177e2005-04-16 15:20:36 -07001405 STp->in_use = 0;
Jeff Mahoney6c648d92012-08-18 15:20:39 -04001406 spin_unlock(&st_use_lock);
Oliver Neukum46a243f2012-01-15 00:16:51 +01001407 scsi_autopm_put_device(STp->device);
Kai Makisaraf03a5672005-08-02 13:40:47 +03001408 scsi_tape_put(STp);
Linus Torvalds1da177e2005-04-16 15:20:36 -07001409
1410 return result;
1411}
1412
1413/* The checks common to both reading and writing */
1414static ssize_t rw_checks(struct scsi_tape *STp, struct file *filp, size_t count)
1415{
1416 ssize_t retval = 0;
1417
1418 /*
1419 * If we are in the middle of error recovery, don't let anyone
1420 * else try and use this device. Also, if error recovery fails, it
1421 * may try and take the device offline, in which case all further
1422 * access to the device is prohibited.
1423 */
1424 if (!scsi_block_when_processing_errors(STp->device)) {
1425 retval = (-ENXIO);
1426 goto out;
1427 }
1428
1429 if (STp->ready != ST_READY) {
1430 if (STp->ready == ST_NO_TAPE)
1431 retval = (-ENOMEDIUM);
1432 else
1433 retval = (-EIO);
1434 goto out;
1435 }
1436
1437 if (! STp->modes[STp->current_mode].defined) {
1438 retval = (-ENXIO);
1439 goto out;
1440 }
1441
1442
1443 /*
1444 * If there was a bus reset, block further access
1445 * to this device.
1446 */
1447 if (STp->pos_unknown) {
1448 retval = (-EIO);
1449 goto out;
1450 }
1451
1452 if (count == 0)
1453 goto out;
1454
1455 DEB(
1456 if (!STp->in_use) {
1457 printk(ST_DEB_MSG "%s: Incorrect device.\n", tape_name(STp));
1458 retval = (-EIO);
1459 goto out;
1460 } ) /* end DEB */
1461
1462 if (STp->can_partitions &&
1463 (retval = switch_partition(STp)) < 0)
1464 goto out;
1465
1466 if (STp->block_size == 0 && STp->max_block > 0 &&
1467 (count < STp->min_block || count > STp->max_block)) {
1468 retval = (-EINVAL);
1469 goto out;
1470 }
1471
1472 if (STp->do_auto_lock && STp->door_locked == ST_UNLOCKED &&
1473 !do_door_lock(STp, 1))
1474 STp->door_locked = ST_LOCKED_AUTO;
1475
1476 out:
1477 return retval;
1478}
1479
1480
1481static int setup_buffering(struct scsi_tape *STp, const char __user *buf,
1482 size_t count, int is_read)
1483{
1484 int i, bufsize, retval = 0;
1485 struct st_buffer *STbp = STp->buffer;
1486
1487 if (is_read)
Kai Makisara9abe16c2007-02-03 13:21:29 +02001488 i = STp->try_dio_now && try_rdio;
Linus Torvalds1da177e2005-04-16 15:20:36 -07001489 else
Kai Makisara9abe16c2007-02-03 13:21:29 +02001490 i = STp->try_dio_now && try_wdio;
Mike Christie8b05b772005-11-08 04:06:44 -06001491
Linus Torvalds1da177e2005-04-16 15:20:36 -07001492 if (i && ((unsigned long)buf & queue_dma_alignment(
1493 STp->device->request_queue)) == 0) {
FUJITA Tomonori66207422008-12-18 14:49:43 +09001494 i = sgl_map_user_pages(STbp, STbp->use_sg, (unsigned long)buf,
1495 count, (is_read ? READ : WRITE));
Linus Torvalds1da177e2005-04-16 15:20:36 -07001496 if (i > 0) {
1497 STbp->do_dio = i;
1498 STbp->buffer_bytes = 0; /* can be used as transfer counter */
1499 }
1500 else
1501 STbp->do_dio = 0; /* fall back to buffering with any error */
1502 STbp->sg_segs = STbp->do_dio;
Linus Torvalds1da177e2005-04-16 15:20:36 -07001503 DEB(
1504 if (STbp->do_dio) {
1505 STp->nbr_dio++;
1506 STp->nbr_pages += STbp->do_dio;
Linus Torvalds1da177e2005-04-16 15:20:36 -07001507 }
1508 )
1509 } else
1510 STbp->do_dio = 0;
1511 DEB( STp->nbr_requests++; )
1512
1513 if (!STbp->do_dio) {
1514 if (STp->block_size)
1515 bufsize = STp->block_size > st_fixed_buffer_size ?
1516 STp->block_size : st_fixed_buffer_size;
Kai Makisara40f6b362008-02-24 22:23:24 +02001517 else {
Linus Torvalds1da177e2005-04-16 15:20:36 -07001518 bufsize = count;
Kai Makisara40f6b362008-02-24 22:23:24 +02001519 /* Make sure that data from previous user is not leaked even if
1520 HBA does not return correct residual */
1521 if (is_read && STp->sili && !STbp->cleared)
1522 clear_buffer(STbp);
1523 }
1524
Linus Torvalds1da177e2005-04-16 15:20:36 -07001525 if (bufsize > STbp->buffer_size &&
1526 !enlarge_buffer(STbp, bufsize, STp->restr_dma)) {
1527 printk(KERN_WARNING "%s: Can't allocate %d byte tape buffer.\n",
1528 tape_name(STp), bufsize);
1529 retval = (-EOVERFLOW);
1530 goto out;
1531 }
1532 if (STp->block_size)
1533 STbp->buffer_blocks = bufsize / STp->block_size;
1534 }
1535
1536 out:
1537 return retval;
1538}
1539
1540
1541/* Can be called more than once after each setup_buffer() */
Kai Makisara787926b2005-11-13 10:04:44 +02001542static void release_buffering(struct scsi_tape *STp, int is_read)
Linus Torvalds1da177e2005-04-16 15:20:36 -07001543{
1544 struct st_buffer *STbp;
1545
1546 STbp = STp->buffer;
1547 if (STbp->do_dio) {
FUJITA Tomonori66207422008-12-18 14:49:43 +09001548 sgl_unmap_user_pages(STbp, STbp->do_dio, is_read);
Linus Torvalds1da177e2005-04-16 15:20:36 -07001549 STbp->do_dio = 0;
Kai Makisara787926b2005-11-13 10:04:44 +02001550 STbp->sg_segs = 0;
Linus Torvalds1da177e2005-04-16 15:20:36 -07001551 }
1552}
1553
1554
1555/* Write command */
1556static ssize_t
1557st_write(struct file *filp, const char __user *buf, size_t count, loff_t * ppos)
1558{
1559 ssize_t total;
1560 ssize_t i, do_count, blks, transfer;
1561 ssize_t retval;
1562 int undone, retry_eot = 0, scode;
1563 int async_write;
1564 unsigned char cmd[MAX_COMMAND_SIZE];
1565 const char __user *b_point;
Mike Christie8b05b772005-11-08 04:06:44 -06001566 struct st_request *SRpnt = NULL;
Linus Torvalds1da177e2005-04-16 15:20:36 -07001567 struct scsi_tape *STp = filp->private_data;
1568 struct st_modedef *STm;
1569 struct st_partstat *STps;
1570 struct st_buffer *STbp;
1571 char *name = tape_name(STp);
1572
Matthias Kaehlcke28f85002007-07-29 23:38:15 +02001573 if (mutex_lock_interruptible(&STp->lock))
Linus Torvalds1da177e2005-04-16 15:20:36 -07001574 return -ERESTARTSYS;
1575
1576 retval = rw_checks(STp, filp, count);
1577 if (retval || count == 0)
1578 goto out;
1579
1580 /* Write must be integral number of blocks */
1581 if (STp->block_size != 0 && (count % STp->block_size) != 0) {
1582 printk(KERN_WARNING "%s: Write not multiple of tape block size.\n",
1583 name);
1584 retval = (-EINVAL);
1585 goto out;
1586 }
1587
1588 STm = &(STp->modes[STp->current_mode]);
1589 STps = &(STp->ps[STp->partition]);
1590
1591 if (STp->write_prot) {
1592 retval = (-EACCES);
1593 goto out;
1594 }
1595
1596
1597 if (STps->rw == ST_READING) {
1598 retval = flush_buffer(STp, 0);
1599 if (retval)
1600 goto out;
1601 STps->rw = ST_WRITING;
1602 } else if (STps->rw != ST_WRITING &&
1603 STps->drv_file == 0 && STps->drv_block == 0) {
1604 if ((retval = set_mode_densblk(STp, STm)) < 0)
1605 goto out;
1606 if (STm->default_compression != ST_DONT_TOUCH &&
1607 !(STp->compression_changed)) {
1608 if (st_compression(STp, (STm->default_compression == ST_YES))) {
1609 printk(KERN_WARNING "%s: Can't set default compression.\n",
1610 name);
1611 if (modes_defined) {
1612 retval = (-EINVAL);
1613 goto out;
1614 }
1615 }
1616 }
1617 }
1618
1619 STbp = STp->buffer;
1620 i = write_behind_check(STp);
1621 if (i) {
1622 if (i == -ENOSPC)
1623 STps->eof = ST_EOM_OK;
1624 else
1625 STps->eof = ST_EOM_ERROR;
1626 }
1627
1628 if (STps->eof == ST_EOM_OK) {
1629 STps->eof = ST_EOD_1; /* allow next write */
1630 retval = (-ENOSPC);
1631 goto out;
1632 }
1633 else if (STps->eof == ST_EOM_ERROR) {
1634 retval = (-EIO);
1635 goto out;
1636 }
1637
1638 /* Check the buffer readability in cases where copy_user might catch
1639 the problems after some tape movement. */
1640 if (STp->block_size != 0 &&
1641 !STbp->do_dio &&
1642 (copy_from_user(&i, buf, 1) != 0 ||
1643 copy_from_user(&i, buf + count - 1, 1) != 0)) {
1644 retval = (-EFAULT);
1645 goto out;
1646 }
1647
1648 retval = setup_buffering(STp, buf, count, 0);
1649 if (retval)
1650 goto out;
1651
1652 total = count;
1653
1654 memset(cmd, 0, MAX_COMMAND_SIZE);
1655 cmd[0] = WRITE_6;
1656 cmd[1] = (STp->block_size != 0);
1657
1658 STps->rw = ST_WRITING;
1659
1660 b_point = buf;
1661 while (count > 0 && !retry_eot) {
1662
1663 if (STbp->do_dio) {
1664 do_count = count;
1665 }
1666 else {
1667 if (STp->block_size == 0)
1668 do_count = count;
1669 else {
1670 do_count = STbp->buffer_blocks * STp->block_size -
1671 STbp->buffer_bytes;
1672 if (do_count > count)
1673 do_count = count;
1674 }
1675
1676 i = append_to_buffer(b_point, STbp, do_count);
1677 if (i) {
1678 retval = i;
1679 goto out;
1680 }
1681 }
1682 count -= do_count;
1683 b_point += do_count;
1684
1685 async_write = STp->block_size == 0 && !STbp->do_dio &&
1686 STm->do_async_writes && STps->eof < ST_EOM_OK;
1687
1688 if (STp->block_size != 0 && STm->do_buffer_writes &&
Kai Makisara9abe16c2007-02-03 13:21:29 +02001689 !(STp->try_dio_now && try_wdio) && STps->eof < ST_EOM_OK &&
Linus Torvalds1da177e2005-04-16 15:20:36 -07001690 STbp->buffer_bytes < STbp->buffer_size) {
1691 STp->dirty = 1;
1692 /* Don't write a buffer that is not full enough. */
1693 if (!async_write && count == 0)
1694 break;
1695 }
1696
1697 retry_write:
1698 if (STp->block_size == 0)
1699 blks = transfer = do_count;
1700 else {
1701 if (!STbp->do_dio)
1702 blks = STbp->buffer_bytes;
1703 else
1704 blks = do_count;
1705 blks /= STp->block_size;
1706 transfer = blks * STp->block_size;
1707 }
1708 cmd[2] = blks >> 16;
1709 cmd[3] = blks >> 8;
1710 cmd[4] = blks;
1711
1712 SRpnt = st_do_scsi(SRpnt, STp, cmd, transfer, DMA_TO_DEVICE,
James Bottomleya02488e2008-11-30 10:36:26 -06001713 STp->device->request_queue->rq_timeout,
1714 MAX_WRITE_RETRIES, !async_write);
Linus Torvalds1da177e2005-04-16 15:20:36 -07001715 if (!SRpnt) {
1716 retval = STbp->syscall_result;
1717 goto out;
1718 }
Mike Christie8b05b772005-11-08 04:06:44 -06001719 if (async_write && !STbp->syscall_result) {
Linus Torvalds1da177e2005-04-16 15:20:36 -07001720 STbp->writing = transfer;
1721 STp->dirty = !(STbp->writing ==
1722 STbp->buffer_bytes);
1723 SRpnt = NULL; /* Prevent releasing this request! */
1724 DEB( STp->write_pending = 1; )
1725 break;
1726 }
1727
1728 if (STbp->syscall_result != 0) {
1729 struct st_cmdstatus *cmdstatp = &STp->buffer->cmdstat;
1730
1731 DEBC(printk(ST_DEB_MSG "%s: Error on write:\n", name));
1732 if (cmdstatp->have_sense && (cmdstatp->flags & SENSE_EOM)) {
1733 scode = cmdstatp->sense_hdr.sense_key;
1734 if (cmdstatp->remainder_valid)
1735 undone = (int)cmdstatp->uremainder64;
1736 else if (STp->block_size == 0 &&
1737 scode == VOLUME_OVERFLOW)
1738 undone = transfer;
1739 else
1740 undone = 0;
1741 if (STp->block_size != 0)
1742 undone *= STp->block_size;
1743 if (undone <= do_count) {
1744 /* Only data from this write is not written */
1745 count += undone;
Kai Makisara626dcb12008-07-11 15:05:25 +03001746 b_point -= undone;
Linus Torvalds1da177e2005-04-16 15:20:36 -07001747 do_count -= undone;
1748 if (STp->block_size)
1749 blks = (transfer - undone) / STp->block_size;
1750 STps->eof = ST_EOM_OK;
1751 /* Continue in fixed block mode if all written
1752 in this request but still something left to write
1753 (retval left to zero)
1754 */
1755 if (STp->block_size == 0 ||
1756 undone > 0 || count == 0)
1757 retval = (-ENOSPC); /* EOM within current request */
1758 DEBC(printk(ST_DEB_MSG
1759 "%s: EOM with %d bytes unwritten.\n",
1760 name, (int)count));
1761 } else {
1762 /* EOT within data buffered earlier (possible only
1763 in fixed block mode without direct i/o) */
1764 if (!retry_eot && !cmdstatp->deferred &&
1765 (scode == NO_SENSE || scode == RECOVERED_ERROR)) {
1766 move_buffer_data(STp->buffer, transfer - undone);
1767 retry_eot = 1;
1768 if (STps->drv_block >= 0) {
1769 STps->drv_block += (transfer - undone) /
1770 STp->block_size;
1771 }
1772 STps->eof = ST_EOM_OK;
1773 DEBC(printk(ST_DEB_MSG
1774 "%s: Retry write of %d bytes at EOM.\n",
1775 name, STp->buffer->buffer_bytes));
1776 goto retry_write;
1777 }
1778 else {
1779 /* Either error within data buffered by driver or
1780 failed retry */
1781 count -= do_count;
1782 blks = do_count = 0;
1783 STps->eof = ST_EOM_ERROR;
1784 STps->drv_block = (-1); /* Too cautious? */
1785 retval = (-EIO); /* EOM for old data */
1786 DEBC(printk(ST_DEB_MSG
1787 "%s: EOM with lost data.\n",
1788 name));
1789 }
1790 }
1791 } else {
1792 count += do_count;
1793 STps->drv_block = (-1); /* Too cautious? */
Mike Christie8b05b772005-11-08 04:06:44 -06001794 retval = STbp->syscall_result;
Linus Torvalds1da177e2005-04-16 15:20:36 -07001795 }
1796
1797 }
1798
1799 if (STps->drv_block >= 0) {
1800 if (STp->block_size == 0)
1801 STps->drv_block += (do_count > 0);
1802 else
1803 STps->drv_block += blks;
1804 }
1805
1806 STbp->buffer_bytes = 0;
1807 STp->dirty = 0;
1808
1809 if (retval || retry_eot) {
1810 if (count < total)
1811 retval = total - count;
1812 goto out;
1813 }
1814 }
1815
1816 if (STps->eof == ST_EOD_1)
1817 STps->eof = ST_EOM_OK;
1818 else if (STps->eof != ST_EOM_OK)
1819 STps->eof = ST_NOEOF;
1820 retval = total - count;
1821
1822 out:
1823 if (SRpnt != NULL)
Mike Christie8b05b772005-11-08 04:06:44 -06001824 st_release_request(SRpnt);
Kai Makisara787926b2005-11-13 10:04:44 +02001825 release_buffering(STp, 0);
Matthias Kaehlcke28f85002007-07-29 23:38:15 +02001826 mutex_unlock(&STp->lock);
Linus Torvalds1da177e2005-04-16 15:20:36 -07001827
1828 return retval;
1829}
1830
1831/* Read data from the tape. Returns zero in the normal case, one if the
1832 eof status has changed, and the negative error code in case of a
1833 fatal error. Otherwise updates the buffer and the eof state.
1834
1835 Does release user buffer mapping if it is set.
1836*/
1837static long read_tape(struct scsi_tape *STp, long count,
Mike Christie8b05b772005-11-08 04:06:44 -06001838 struct st_request ** aSRpnt)
Linus Torvalds1da177e2005-04-16 15:20:36 -07001839{
1840 int transfer, blks, bytes;
1841 unsigned char cmd[MAX_COMMAND_SIZE];
Mike Christie8b05b772005-11-08 04:06:44 -06001842 struct st_request *SRpnt;
Linus Torvalds1da177e2005-04-16 15:20:36 -07001843 struct st_modedef *STm;
1844 struct st_partstat *STps;
1845 struct st_buffer *STbp;
1846 int retval = 0;
1847 char *name = tape_name(STp);
1848
1849 if (count == 0)
1850 return 0;
1851
1852 STm = &(STp->modes[STp->current_mode]);
1853 STps = &(STp->ps[STp->partition]);
1854 if (STps->eof == ST_FM_HIT)
1855 return 1;
1856 STbp = STp->buffer;
1857
1858 if (STp->block_size == 0)
1859 blks = bytes = count;
1860 else {
Kai Makisara9abe16c2007-02-03 13:21:29 +02001861 if (!(STp->try_dio_now && try_rdio) && STm->do_read_ahead) {
Linus Torvalds1da177e2005-04-16 15:20:36 -07001862 blks = (STp->buffer)->buffer_blocks;
1863 bytes = blks * STp->block_size;
1864 } else {
1865 bytes = count;
1866 if (!STbp->do_dio && bytes > (STp->buffer)->buffer_size)
1867 bytes = (STp->buffer)->buffer_size;
1868 blks = bytes / STp->block_size;
1869 bytes = blks * STp->block_size;
1870 }
1871 }
1872
1873 memset(cmd, 0, MAX_COMMAND_SIZE);
1874 cmd[0] = READ_6;
1875 cmd[1] = (STp->block_size != 0);
Kai Makisara40f6b362008-02-24 22:23:24 +02001876 if (!cmd[1] && STp->sili)
1877 cmd[1] |= 2;
Linus Torvalds1da177e2005-04-16 15:20:36 -07001878 cmd[2] = blks >> 16;
1879 cmd[3] = blks >> 8;
1880 cmd[4] = blks;
1881
1882 SRpnt = *aSRpnt;
1883 SRpnt = st_do_scsi(SRpnt, STp, cmd, bytes, DMA_FROM_DEVICE,
James Bottomleya02488e2008-11-30 10:36:26 -06001884 STp->device->request_queue->rq_timeout,
1885 MAX_RETRIES, 1);
Kai Makisara787926b2005-11-13 10:04:44 +02001886 release_buffering(STp, 1);
Linus Torvalds1da177e2005-04-16 15:20:36 -07001887 *aSRpnt = SRpnt;
1888 if (!SRpnt)
1889 return STbp->syscall_result;
1890
1891 STbp->read_pointer = 0;
1892 STps->at_sm = 0;
1893
1894 /* Something to check */
1895 if (STbp->syscall_result) {
1896 struct st_cmdstatus *cmdstatp = &STp->buffer->cmdstat;
1897
1898 retval = 1;
1899 DEBC(printk(ST_DEB_MSG "%s: Sense: %2x %2x %2x %2x %2x %2x %2x %2x\n",
1900 name,
Mike Christie8b05b772005-11-08 04:06:44 -06001901 SRpnt->sense[0], SRpnt->sense[1],
1902 SRpnt->sense[2], SRpnt->sense[3],
1903 SRpnt->sense[4], SRpnt->sense[5],
1904 SRpnt->sense[6], SRpnt->sense[7]));
Linus Torvalds1da177e2005-04-16 15:20:36 -07001905 if (cmdstatp->have_sense) {
1906
1907 if (cmdstatp->sense_hdr.sense_key == BLANK_CHECK)
1908 cmdstatp->flags &= 0xcf; /* No need for EOM in this case */
1909
1910 if (cmdstatp->flags != 0) { /* EOF, EOM, or ILI */
1911 /* Compute the residual count */
1912 if (cmdstatp->remainder_valid)
1913 transfer = (int)cmdstatp->uremainder64;
1914 else
1915 transfer = 0;
1916 if (STp->block_size == 0 &&
1917 cmdstatp->sense_hdr.sense_key == MEDIUM_ERROR)
1918 transfer = bytes;
1919
1920 if (cmdstatp->flags & SENSE_ILI) { /* ILI */
1921 if (STp->block_size == 0) {
1922 if (transfer <= 0) {
1923 if (transfer < 0)
1924 printk(KERN_NOTICE
1925 "%s: Failed to read %d byte block with %d byte transfer.\n",
1926 name, bytes - transfer, bytes);
1927 if (STps->drv_block >= 0)
1928 STps->drv_block += 1;
1929 STbp->buffer_bytes = 0;
1930 return (-ENOMEM);
1931 }
1932 STbp->buffer_bytes = bytes - transfer;
1933 } else {
Mike Christie8b05b772005-11-08 04:06:44 -06001934 st_release_request(SRpnt);
Linus Torvalds1da177e2005-04-16 15:20:36 -07001935 SRpnt = *aSRpnt = NULL;
1936 if (transfer == blks) { /* We did not get anything, error */
1937 printk(KERN_NOTICE "%s: Incorrect block size.\n", name);
1938 if (STps->drv_block >= 0)
1939 STps->drv_block += blks - transfer + 1;
1940 st_int_ioctl(STp, MTBSR, 1);
1941 return (-EIO);
1942 }
1943 /* We have some data, deliver it */
1944 STbp->buffer_bytes = (blks - transfer) *
1945 STp->block_size;
1946 DEBC(printk(ST_DEB_MSG
1947 "%s: ILI but enough data received %ld %d.\n",
1948 name, count, STbp->buffer_bytes));
1949 if (STps->drv_block >= 0)
1950 STps->drv_block += 1;
1951 if (st_int_ioctl(STp, MTBSR, 1))
1952 return (-EIO);
1953 }
1954 } else if (cmdstatp->flags & SENSE_FMK) { /* FM overrides EOM */
1955 if (STps->eof != ST_FM_HIT)
1956 STps->eof = ST_FM_HIT;
1957 else
1958 STps->eof = ST_EOD_2;
1959 if (STp->block_size == 0)
1960 STbp->buffer_bytes = 0;
1961 else
1962 STbp->buffer_bytes =
1963 bytes - transfer * STp->block_size;
1964 DEBC(printk(ST_DEB_MSG
1965 "%s: EOF detected (%d bytes read).\n",
1966 name, STbp->buffer_bytes));
1967 } else if (cmdstatp->flags & SENSE_EOM) {
1968 if (STps->eof == ST_FM)
1969 STps->eof = ST_EOD_1;
1970 else
1971 STps->eof = ST_EOM_OK;
1972 if (STp->block_size == 0)
1973 STbp->buffer_bytes = bytes - transfer;
1974 else
1975 STbp->buffer_bytes =
1976 bytes - transfer * STp->block_size;
1977
1978 DEBC(printk(ST_DEB_MSG "%s: EOM detected (%d bytes read).\n",
1979 name, STbp->buffer_bytes));
1980 }
1981 }
1982 /* end of EOF, EOM, ILI test */
1983 else { /* nonzero sense key */
1984 DEBC(printk(ST_DEB_MSG
1985 "%s: Tape error while reading.\n", name));
1986 STps->drv_block = (-1);
1987 if (STps->eof == ST_FM &&
1988 cmdstatp->sense_hdr.sense_key == BLANK_CHECK) {
1989 DEBC(printk(ST_DEB_MSG
1990 "%s: Zero returned for first BLANK CHECK after EOF.\n",
1991 name));
1992 STps->eof = ST_EOD_2; /* First BLANK_CHECK after FM */
1993 } else /* Some other extended sense code */
1994 retval = (-EIO);
1995 }
1996
1997 if (STbp->buffer_bytes < 0) /* Caused by bogus sense data */
1998 STbp->buffer_bytes = 0;
1999 }
2000 /* End of extended sense test */
2001 else { /* Non-extended sense */
2002 retval = STbp->syscall_result;
2003 }
2004
2005 }
2006 /* End of error handling */
Kai Makisara40f6b362008-02-24 22:23:24 +02002007 else { /* Read successful */
Linus Torvalds1da177e2005-04-16 15:20:36 -07002008 STbp->buffer_bytes = bytes;
Kai Makisara40f6b362008-02-24 22:23:24 +02002009 if (STp->sili) /* In fixed block mode residual is always zero here */
2010 STbp->buffer_bytes -= STp->buffer->cmdstat.residual;
2011 }
Linus Torvalds1da177e2005-04-16 15:20:36 -07002012
2013 if (STps->drv_block >= 0) {
2014 if (STp->block_size == 0)
2015 STps->drv_block++;
2016 else
2017 STps->drv_block += STbp->buffer_bytes / STp->block_size;
2018 }
2019 return retval;
2020}
2021
2022
2023/* Read command */
2024static ssize_t
2025st_read(struct file *filp, char __user *buf, size_t count, loff_t * ppos)
2026{
2027 ssize_t total;
2028 ssize_t retval = 0;
2029 ssize_t i, transfer;
2030 int special, do_dio = 0;
Mike Christie8b05b772005-11-08 04:06:44 -06002031 struct st_request *SRpnt = NULL;
Linus Torvalds1da177e2005-04-16 15:20:36 -07002032 struct scsi_tape *STp = filp->private_data;
2033 struct st_modedef *STm;
2034 struct st_partstat *STps;
2035 struct st_buffer *STbp = STp->buffer;
2036 DEB( char *name = tape_name(STp); )
2037
Matthias Kaehlcke28f85002007-07-29 23:38:15 +02002038 if (mutex_lock_interruptible(&STp->lock))
Linus Torvalds1da177e2005-04-16 15:20:36 -07002039 return -ERESTARTSYS;
2040
2041 retval = rw_checks(STp, filp, count);
2042 if (retval || count == 0)
2043 goto out;
2044
2045 STm = &(STp->modes[STp->current_mode]);
Kai Makisara9abe16c2007-02-03 13:21:29 +02002046 if (STp->block_size != 0 && (count % STp->block_size) != 0) {
2047 if (!STm->do_read_ahead) {
2048 retval = (-EINVAL); /* Read must be integral number of blocks */
2049 goto out;
2050 }
2051 STp->try_dio_now = 0; /* Direct i/o can't handle split blocks */
Linus Torvalds1da177e2005-04-16 15:20:36 -07002052 }
2053
2054 STps = &(STp->ps[STp->partition]);
2055 if (STps->rw == ST_WRITING) {
2056 retval = flush_buffer(STp, 0);
2057 if (retval)
2058 goto out;
2059 STps->rw = ST_READING;
2060 }
2061 DEB(
2062 if (debugging && STps->eof != ST_NOEOF)
2063 printk(ST_DEB_MSG "%s: EOF/EOM flag up (%d). Bytes %d\n", name,
2064 STps->eof, STbp->buffer_bytes);
2065 ) /* end DEB */
2066
2067 retval = setup_buffering(STp, buf, count, 1);
2068 if (retval)
2069 goto out;
2070 do_dio = STbp->do_dio;
2071
2072 if (STbp->buffer_bytes == 0 &&
2073 STps->eof >= ST_EOD_1) {
2074 if (STps->eof < ST_EOD) {
2075 STps->eof += 1;
2076 retval = 0;
2077 goto out;
2078 }
2079 retval = (-EIO); /* EOM or Blank Check */
2080 goto out;
2081 }
2082
2083 if (do_dio) {
2084 /* Check the buffer writability before any tape movement. Don't alter
2085 buffer data. */
2086 if (copy_from_user(&i, buf, 1) != 0 ||
2087 copy_to_user(buf, &i, 1) != 0 ||
2088 copy_from_user(&i, buf + count - 1, 1) != 0 ||
2089 copy_to_user(buf + count - 1, &i, 1) != 0) {
2090 retval = (-EFAULT);
2091 goto out;
2092 }
2093 }
2094
2095 STps->rw = ST_READING;
2096
2097
2098 /* Loop until enough data in buffer or a special condition found */
2099 for (total = 0, special = 0; total < count && !special;) {
2100
2101 /* Get new data if the buffer is empty */
2102 if (STbp->buffer_bytes == 0) {
2103 special = read_tape(STp, count - total, &SRpnt);
2104 if (special < 0) { /* No need to continue read */
2105 retval = special;
2106 goto out;
2107 }
2108 }
2109
2110 /* Move the data from driver buffer to user buffer */
2111 if (STbp->buffer_bytes > 0) {
2112 DEB(
2113 if (debugging && STps->eof != ST_NOEOF)
2114 printk(ST_DEB_MSG
2115 "%s: EOF up (%d). Left %d, needed %d.\n", name,
2116 STps->eof, STbp->buffer_bytes,
2117 (int)(count - total));
2118 ) /* end DEB */
2119 transfer = STbp->buffer_bytes < count - total ?
2120 STbp->buffer_bytes : count - total;
2121 if (!do_dio) {
2122 i = from_buffer(STbp, buf, transfer);
2123 if (i) {
2124 retval = i;
2125 goto out;
2126 }
2127 }
2128 buf += transfer;
2129 total += transfer;
2130 }
2131
2132 if (STp->block_size == 0)
2133 break; /* Read only one variable length block */
2134
2135 } /* for (total = 0, special = 0;
2136 total < count && !special; ) */
2137
2138 /* Change the eof state if no data from tape or buffer */
2139 if (total == 0) {
2140 if (STps->eof == ST_FM_HIT) {
2141 STps->eof = ST_FM;
2142 STps->drv_block = 0;
2143 if (STps->drv_file >= 0)
2144 STps->drv_file++;
2145 } else if (STps->eof == ST_EOD_1) {
2146 STps->eof = ST_EOD_2;
2147 STps->drv_block = 0;
2148 if (STps->drv_file >= 0)
2149 STps->drv_file++;
2150 } else if (STps->eof == ST_EOD_2)
2151 STps->eof = ST_EOD;
2152 } else if (STps->eof == ST_FM)
2153 STps->eof = ST_NOEOF;
2154 retval = total;
2155
2156 out:
2157 if (SRpnt != NULL) {
Mike Christie8b05b772005-11-08 04:06:44 -06002158 st_release_request(SRpnt);
Linus Torvalds1da177e2005-04-16 15:20:36 -07002159 SRpnt = NULL;
2160 }
2161 if (do_dio) {
Kai Makisara787926b2005-11-13 10:04:44 +02002162 release_buffering(STp, 1);
Linus Torvalds1da177e2005-04-16 15:20:36 -07002163 STbp->buffer_bytes = 0;
2164 }
Matthias Kaehlcke28f85002007-07-29 23:38:15 +02002165 mutex_unlock(&STp->lock);
Linus Torvalds1da177e2005-04-16 15:20:36 -07002166
2167 return retval;
2168}
2169
2170
2171
2172DEB(
2173/* Set the driver options */
2174static void st_log_options(struct scsi_tape * STp, struct st_modedef * STm, char *name)
2175{
2176 if (debugging) {
2177 printk(KERN_INFO
2178 "%s: Mode %d options: buffer writes: %d, async writes: %d, read ahead: %d\n",
2179 name, STp->current_mode, STm->do_buffer_writes, STm->do_async_writes,
2180 STm->do_read_ahead);
2181 printk(KERN_INFO
2182 "%s: can bsr: %d, two FMs: %d, fast mteom: %d, auto lock: %d,\n",
2183 name, STp->can_bsr, STp->two_fm, STp->fast_mteom, STp->do_auto_lock);
2184 printk(KERN_INFO
2185 "%s: defs for wr: %d, no block limits: %d, partitions: %d, s2 log: %d\n",
2186 name, STm->defaults_for_writes, STp->omit_blklims, STp->can_partitions,
2187 STp->scsi2_logical);
2188 printk(KERN_INFO
Lee Duncanc743e442012-03-01 12:41:01 -08002189 "%s: sysv: %d nowait: %d sili: %d nowait_filemark: %d\n",
2190 name, STm->sysv, STp->immediate, STp->sili,
2191 STp->immediate_filemark);
Linus Torvalds1da177e2005-04-16 15:20:36 -07002192 printk(KERN_INFO "%s: debugging: %d\n",
2193 name, debugging);
2194 }
2195}
2196 )
2197
2198
2199static int st_set_options(struct scsi_tape *STp, long options)
2200{
2201 int value;
2202 long code;
2203 struct st_modedef *STm;
2204 char *name = tape_name(STp);
2205 struct cdev *cd0, *cd1;
2206
2207 STm = &(STp->modes[STp->current_mode]);
2208 if (!STm->defined) {
2209 cd0 = STm->cdevs[0]; cd1 = STm->cdevs[1];
2210 memcpy(STm, &(STp->modes[0]), sizeof(struct st_modedef));
2211 STm->cdevs[0] = cd0; STm->cdevs[1] = cd1;
2212 modes_defined = 1;
2213 DEBC(printk(ST_DEB_MSG
2214 "%s: Initialized mode %d definition from mode 0\n",
2215 name, STp->current_mode));
2216 }
2217
2218 code = options & MT_ST_OPTIONS;
2219 if (code == MT_ST_BOOLEANS) {
2220 STm->do_buffer_writes = (options & MT_ST_BUFFER_WRITES) != 0;
2221 STm->do_async_writes = (options & MT_ST_ASYNC_WRITES) != 0;
2222 STm->defaults_for_writes = (options & MT_ST_DEF_WRITES) != 0;
2223 STm->do_read_ahead = (options & MT_ST_READ_AHEAD) != 0;
2224 STp->two_fm = (options & MT_ST_TWO_FM) != 0;
2225 STp->fast_mteom = (options & MT_ST_FAST_MTEOM) != 0;
2226 STp->do_auto_lock = (options & MT_ST_AUTO_LOCK) != 0;
2227 STp->can_bsr = (options & MT_ST_CAN_BSR) != 0;
2228 STp->omit_blklims = (options & MT_ST_NO_BLKLIMS) != 0;
2229 if ((STp->device)->scsi_level >= SCSI_2)
2230 STp->can_partitions = (options & MT_ST_CAN_PARTITIONS) != 0;
2231 STp->scsi2_logical = (options & MT_ST_SCSI2LOGICAL) != 0;
2232 STp->immediate = (options & MT_ST_NOWAIT) != 0;
Lee Duncanc743e442012-03-01 12:41:01 -08002233 STp->immediate_filemark = (options & MT_ST_NOWAIT_EOF) != 0;
Linus Torvalds1da177e2005-04-16 15:20:36 -07002234 STm->sysv = (options & MT_ST_SYSV) != 0;
Kai Makisara40f6b362008-02-24 22:23:24 +02002235 STp->sili = (options & MT_ST_SILI) != 0;
Linus Torvalds1da177e2005-04-16 15:20:36 -07002236 DEB( debugging = (options & MT_ST_DEBUGGING) != 0;
2237 st_log_options(STp, STm, name); )
2238 } else if (code == MT_ST_SETBOOLEANS || code == MT_ST_CLEARBOOLEANS) {
2239 value = (code == MT_ST_SETBOOLEANS);
2240 if ((options & MT_ST_BUFFER_WRITES) != 0)
2241 STm->do_buffer_writes = value;
2242 if ((options & MT_ST_ASYNC_WRITES) != 0)
2243 STm->do_async_writes = value;
2244 if ((options & MT_ST_DEF_WRITES) != 0)
2245 STm->defaults_for_writes = value;
2246 if ((options & MT_ST_READ_AHEAD) != 0)
2247 STm->do_read_ahead = value;
2248 if ((options & MT_ST_TWO_FM) != 0)
2249 STp->two_fm = value;
2250 if ((options & MT_ST_FAST_MTEOM) != 0)
2251 STp->fast_mteom = value;
2252 if ((options & MT_ST_AUTO_LOCK) != 0)
2253 STp->do_auto_lock = value;
2254 if ((options & MT_ST_CAN_BSR) != 0)
2255 STp->can_bsr = value;
2256 if ((options & MT_ST_NO_BLKLIMS) != 0)
2257 STp->omit_blklims = value;
2258 if ((STp->device)->scsi_level >= SCSI_2 &&
2259 (options & MT_ST_CAN_PARTITIONS) != 0)
2260 STp->can_partitions = value;
2261 if ((options & MT_ST_SCSI2LOGICAL) != 0)
2262 STp->scsi2_logical = value;
2263 if ((options & MT_ST_NOWAIT) != 0)
2264 STp->immediate = value;
Lee Duncanc743e442012-03-01 12:41:01 -08002265 if ((options & MT_ST_NOWAIT_EOF) != 0)
2266 STp->immediate_filemark = value;
Linus Torvalds1da177e2005-04-16 15:20:36 -07002267 if ((options & MT_ST_SYSV) != 0)
2268 STm->sysv = value;
Kai Makisara40f6b362008-02-24 22:23:24 +02002269 if ((options & MT_ST_SILI) != 0)
2270 STp->sili = value;
Linus Torvalds1da177e2005-04-16 15:20:36 -07002271 DEB(
2272 if ((options & MT_ST_DEBUGGING) != 0)
2273 debugging = value;
2274 st_log_options(STp, STm, name); )
2275 } else if (code == MT_ST_WRITE_THRESHOLD) {
2276 /* Retained for compatibility */
2277 } else if (code == MT_ST_DEF_BLKSIZE) {
2278 value = (options & ~MT_ST_OPTIONS);
2279 if (value == ~MT_ST_OPTIONS) {
2280 STm->default_blksize = (-1);
2281 DEBC( printk(KERN_INFO "%s: Default block size disabled.\n", name));
2282 } else {
2283 STm->default_blksize = value;
2284 DEBC( printk(KERN_INFO "%s: Default block size set to %d bytes.\n",
2285 name, STm->default_blksize));
2286 if (STp->ready == ST_READY) {
2287 STp->blksize_changed = 0;
2288 set_mode_densblk(STp, STm);
2289 }
2290 }
2291 } else if (code == MT_ST_TIMEOUTS) {
2292 value = (options & ~MT_ST_OPTIONS);
2293 if ((value & MT_ST_SET_LONG_TIMEOUT) != 0) {
2294 STp->long_timeout = (value & ~MT_ST_SET_LONG_TIMEOUT) * HZ;
2295 DEBC( printk(KERN_INFO "%s: Long timeout set to %d seconds.\n", name,
2296 (value & ~MT_ST_SET_LONG_TIMEOUT)));
2297 } else {
James Bottomleya02488e2008-11-30 10:36:26 -06002298 blk_queue_rq_timeout(STp->device->request_queue,
2299 value * HZ);
Linus Torvalds1da177e2005-04-16 15:20:36 -07002300 DEBC( printk(KERN_INFO "%s: Normal timeout set to %d seconds.\n",
2301 name, value) );
2302 }
2303 } else if (code == MT_ST_SET_CLN) {
2304 value = (options & ~MT_ST_OPTIONS) & 0xff;
2305 if (value != 0 &&
Roel Kluin832151f2009-11-17 14:53:22 -08002306 (value < EXTENDED_SENSE_START ||
2307 value >= SCSI_SENSE_BUFFERSIZE))
Linus Torvalds1da177e2005-04-16 15:20:36 -07002308 return (-EINVAL);
2309 STp->cln_mode = value;
2310 STp->cln_sense_mask = (options >> 8) & 0xff;
2311 STp->cln_sense_value = (options >> 16) & 0xff;
2312 printk(KERN_INFO
2313 "%s: Cleaning request mode %d, mask %02x, value %02x\n",
2314 name, value, STp->cln_sense_mask, STp->cln_sense_value);
2315 } else if (code == MT_ST_DEF_OPTIONS) {
2316 code = (options & ~MT_ST_CLEAR_DEFAULT);
2317 value = (options & MT_ST_CLEAR_DEFAULT);
2318 if (code == MT_ST_DEF_DENSITY) {
2319 if (value == MT_ST_CLEAR_DEFAULT) {
2320 STm->default_density = (-1);
2321 DEBC( printk(KERN_INFO "%s: Density default disabled.\n",
2322 name));
2323 } else {
2324 STm->default_density = value & 0xff;
2325 DEBC( printk(KERN_INFO "%s: Density default set to %x\n",
2326 name, STm->default_density));
2327 if (STp->ready == ST_READY) {
2328 STp->density_changed = 0;
2329 set_mode_densblk(STp, STm);
2330 }
2331 }
2332 } else if (code == MT_ST_DEF_DRVBUFFER) {
2333 if (value == MT_ST_CLEAR_DEFAULT) {
2334 STp->default_drvbuffer = 0xff;
2335 DEBC( printk(KERN_INFO
2336 "%s: Drive buffer default disabled.\n", name));
2337 } else {
2338 STp->default_drvbuffer = value & 7;
2339 DEBC( printk(KERN_INFO
2340 "%s: Drive buffer default set to %x\n",
2341 name, STp->default_drvbuffer));
2342 if (STp->ready == ST_READY)
2343 st_int_ioctl(STp, MTSETDRVBUFFER, STp->default_drvbuffer);
2344 }
2345 } else if (code == MT_ST_DEF_COMPRESSION) {
2346 if (value == MT_ST_CLEAR_DEFAULT) {
2347 STm->default_compression = ST_DONT_TOUCH;
2348 DEBC( printk(KERN_INFO
2349 "%s: Compression default disabled.\n", name));
2350 } else {
2351 if ((value & 0xff00) != 0) {
2352 STp->c_algo = (value & 0xff00) >> 8;
2353 DEBC( printk(KERN_INFO "%s: Compression algorithm set to 0x%x.\n",
2354 name, STp->c_algo));
2355 }
2356 if ((value & 0xff) != 0xff) {
2357 STm->default_compression = (value & 1 ? ST_YES : ST_NO);
2358 DEBC( printk(KERN_INFO "%s: Compression default set to %x\n",
2359 name, (value & 1)));
2360 if (STp->ready == ST_READY) {
2361 STp->compression_changed = 0;
2362 st_compression(STp, (STm->default_compression == ST_YES));
2363 }
2364 }
2365 }
2366 }
2367 } else
2368 return (-EIO);
2369
2370 return 0;
2371}
2372
2373#define MODE_HEADER_LENGTH 4
2374
2375/* Mode header and page byte offsets */
2376#define MH_OFF_DATA_LENGTH 0
2377#define MH_OFF_MEDIUM_TYPE 1
2378#define MH_OFF_DEV_SPECIFIC 2
2379#define MH_OFF_BDESCS_LENGTH 3
2380#define MP_OFF_PAGE_NBR 0
2381#define MP_OFF_PAGE_LENGTH 1
2382
2383/* Mode header and page bit masks */
2384#define MH_BIT_WP 0x80
2385#define MP_MSK_PAGE_NBR 0x3f
2386
2387/* Don't return block descriptors */
2388#define MODE_SENSE_OMIT_BDESCS 0x08
2389
2390#define MODE_SELECT_PAGE_FORMAT 0x10
2391
2392/* Read a mode page into the tape buffer. The block descriptors are included
2393 if incl_block_descs is true. The page control is ored to the page number
2394 parameter, if necessary. */
2395static int read_mode_page(struct scsi_tape *STp, int page, int omit_block_descs)
2396{
2397 unsigned char cmd[MAX_COMMAND_SIZE];
FUJITA Tomonori8ecf0d92008-12-05 15:25:28 +09002398 struct st_request *SRpnt;
Linus Torvalds1da177e2005-04-16 15:20:36 -07002399
2400 memset(cmd, 0, MAX_COMMAND_SIZE);
2401 cmd[0] = MODE_SENSE;
2402 if (omit_block_descs)
2403 cmd[1] = MODE_SENSE_OMIT_BDESCS;
2404 cmd[2] = page;
2405 cmd[4] = 255;
2406
Kai Makisara02ae2c02008-12-18 14:49:50 +09002407 SRpnt = st_do_scsi(NULL, STp, cmd, cmd[4], DMA_FROM_DEVICE,
2408 STp->device->request_queue->rq_timeout, 0, 1);
2409 if (SRpnt == NULL)
2410 return (STp->buffer)->syscall_result;
Linus Torvalds1da177e2005-04-16 15:20:36 -07002411
Mike Christie8b05b772005-11-08 04:06:44 -06002412 st_release_request(SRpnt);
Linus Torvalds1da177e2005-04-16 15:20:36 -07002413
Kai Makisara02ae2c02008-12-18 14:49:50 +09002414 return STp->buffer->syscall_result;
Linus Torvalds1da177e2005-04-16 15:20:36 -07002415}
2416
2417
2418/* Send the mode page in the tape buffer to the drive. Assumes that the mode data
2419 in the buffer is correctly formatted. The long timeout is used if slow is non-zero. */
2420static int write_mode_page(struct scsi_tape *STp, int page, int slow)
2421{
Kai Makisara02ae2c02008-12-18 14:49:50 +09002422 int pgo;
Linus Torvalds1da177e2005-04-16 15:20:36 -07002423 unsigned char cmd[MAX_COMMAND_SIZE];
FUJITA Tomonori18c87012008-12-05 15:25:29 +09002424 struct st_request *SRpnt;
Kai Makisara02ae2c02008-12-18 14:49:50 +09002425 int timeout;
Linus Torvalds1da177e2005-04-16 15:20:36 -07002426
2427 memset(cmd, 0, MAX_COMMAND_SIZE);
2428 cmd[0] = MODE_SELECT;
2429 cmd[1] = MODE_SELECT_PAGE_FORMAT;
2430 pgo = MODE_HEADER_LENGTH + (STp->buffer)->b_data[MH_OFF_BDESCS_LENGTH];
2431 cmd[4] = pgo + (STp->buffer)->b_data[pgo + MP_OFF_PAGE_LENGTH] + 2;
2432
2433 /* Clear reserved fields */
2434 (STp->buffer)->b_data[MH_OFF_DATA_LENGTH] = 0;
2435 (STp->buffer)->b_data[MH_OFF_MEDIUM_TYPE] = 0;
2436 (STp->buffer)->b_data[MH_OFF_DEV_SPECIFIC] &= ~MH_BIT_WP;
2437 (STp->buffer)->b_data[pgo + MP_OFF_PAGE_NBR] &= MP_MSK_PAGE_NBR;
2438
Kai Makisara02ae2c02008-12-18 14:49:50 +09002439 timeout = slow ?
2440 STp->long_timeout : STp->device->request_queue->rq_timeout;
2441 SRpnt = st_do_scsi(NULL, STp, cmd, cmd[4], DMA_TO_DEVICE,
2442 timeout, 0, 1);
2443 if (SRpnt == NULL)
2444 return (STp->buffer)->syscall_result;
Linus Torvalds1da177e2005-04-16 15:20:36 -07002445
Mike Christie8b05b772005-11-08 04:06:44 -06002446 st_release_request(SRpnt);
Linus Torvalds1da177e2005-04-16 15:20:36 -07002447
Kai Makisara02ae2c02008-12-18 14:49:50 +09002448 return STp->buffer->syscall_result;
Linus Torvalds1da177e2005-04-16 15:20:36 -07002449}
2450
2451
2452#define COMPRESSION_PAGE 0x0f
2453#define COMPRESSION_PAGE_LENGTH 16
2454
2455#define CP_OFF_DCE_DCC 2
2456#define CP_OFF_C_ALGO 7
2457
2458#define DCE_MASK 0x80
2459#define DCC_MASK 0x40
2460#define RED_MASK 0x60
2461
2462
2463/* Control the compression with mode page 15. Algorithm not changed if zero.
2464
2465 The block descriptors are read and written because Sony SDT-7000 does not
2466 work without this (suggestion from Michael Schaefer <Michael.Schaefer@dlr.de>).
2467 Including block descriptors should not cause any harm to other drives. */
2468
2469static int st_compression(struct scsi_tape * STp, int state)
2470{
2471 int retval;
2472 int mpoffs; /* Offset to mode page start */
2473 unsigned char *b_data = (STp->buffer)->b_data;
2474 DEB( char *name = tape_name(STp); )
2475
2476 if (STp->ready != ST_READY)
2477 return (-EIO);
2478
2479 /* Read the current page contents */
2480 retval = read_mode_page(STp, COMPRESSION_PAGE, 0);
2481 if (retval) {
2482 DEBC(printk(ST_DEB_MSG "%s: Compression mode page not supported.\n",
2483 name));
2484 return (-EIO);
2485 }
2486
2487 mpoffs = MODE_HEADER_LENGTH + b_data[MH_OFF_BDESCS_LENGTH];
2488 DEBC(printk(ST_DEB_MSG "%s: Compression state is %d.\n", name,
2489 (b_data[mpoffs + CP_OFF_DCE_DCC] & DCE_MASK ? 1 : 0)));
2490
2491 /* Check if compression can be changed */
2492 if ((b_data[mpoffs + CP_OFF_DCE_DCC] & DCC_MASK) == 0) {
2493 DEBC(printk(ST_DEB_MSG "%s: Compression not supported.\n", name));
2494 return (-EIO);
2495 }
2496
2497 /* Do the change */
2498 if (state) {
2499 b_data[mpoffs + CP_OFF_DCE_DCC] |= DCE_MASK;
2500 if (STp->c_algo != 0)
2501 b_data[mpoffs + CP_OFF_C_ALGO] = STp->c_algo;
2502 }
2503 else {
2504 b_data[mpoffs + CP_OFF_DCE_DCC] &= ~DCE_MASK;
2505 if (STp->c_algo != 0)
2506 b_data[mpoffs + CP_OFF_C_ALGO] = 0; /* no compression */
2507 }
2508
2509 retval = write_mode_page(STp, COMPRESSION_PAGE, 0);
2510 if (retval) {
2511 DEBC(printk(ST_DEB_MSG "%s: Compression change failed.\n", name));
2512 return (-EIO);
2513 }
2514 DEBC(printk(ST_DEB_MSG "%s: Compression state changed to %d.\n",
2515 name, state));
2516
2517 STp->compression_changed = 1;
2518 return 0;
2519}
2520
2521
2522/* Process the load and unload commands (does unload if the load code is zero) */
2523static int do_load_unload(struct scsi_tape *STp, struct file *filp, int load_code)
2524{
2525 int retval = (-EIO), timeout;
2526 DEB( char *name = tape_name(STp); )
2527 unsigned char cmd[MAX_COMMAND_SIZE];
2528 struct st_partstat *STps;
Mike Christie8b05b772005-11-08 04:06:44 -06002529 struct st_request *SRpnt;
Linus Torvalds1da177e2005-04-16 15:20:36 -07002530
2531 if (STp->ready != ST_READY && !load_code) {
2532 if (STp->ready == ST_NO_TAPE)
2533 return (-ENOMEDIUM);
2534 else
2535 return (-EIO);
2536 }
2537
2538 memset(cmd, 0, MAX_COMMAND_SIZE);
2539 cmd[0] = START_STOP;
2540 if (load_code)
2541 cmd[4] |= 1;
2542 /*
2543 * If arg >= 1 && arg <= 6 Enhanced load/unload in HP C1553A
2544 */
2545 if (load_code >= 1 + MT_ST_HPLOADER_OFFSET
2546 && load_code <= 6 + MT_ST_HPLOADER_OFFSET) {
2547 DEBC(printk(ST_DEB_MSG "%s: Enhanced %sload slot %2d.\n",
2548 name, (cmd[4]) ? "" : "un",
2549 load_code - MT_ST_HPLOADER_OFFSET));
2550 cmd[3] = load_code - MT_ST_HPLOADER_OFFSET; /* MediaID field of C1553A */
2551 }
2552 if (STp->immediate) {
2553 cmd[1] = 1; /* Don't wait for completion */
James Bottomleya02488e2008-11-30 10:36:26 -06002554 timeout = STp->device->request_queue->rq_timeout;
Linus Torvalds1da177e2005-04-16 15:20:36 -07002555 }
2556 else
2557 timeout = STp->long_timeout;
2558
2559 DEBC(
2560 if (!load_code)
2561 printk(ST_DEB_MSG "%s: Unloading tape.\n", name);
2562 else
2563 printk(ST_DEB_MSG "%s: Loading tape.\n", name);
2564 );
2565
Kai Makisara02ae2c02008-12-18 14:49:50 +09002566 SRpnt = st_do_scsi(NULL, STp, cmd, 0, DMA_NONE,
2567 timeout, MAX_RETRIES, 1);
Linus Torvalds1da177e2005-04-16 15:20:36 -07002568 if (!SRpnt)
Kai Makisara02ae2c02008-12-18 14:49:50 +09002569 return (STp->buffer)->syscall_result;
Linus Torvalds1da177e2005-04-16 15:20:36 -07002570
2571 retval = (STp->buffer)->syscall_result;
Kai Makisara02ae2c02008-12-18 14:49:50 +09002572 st_release_request(SRpnt);
Linus Torvalds1da177e2005-04-16 15:20:36 -07002573
2574 if (!retval) { /* SCSI command successful */
2575
2576 if (!load_code) {
2577 STp->rew_at_close = 0;
2578 STp->ready = ST_NO_TAPE;
2579 }
2580 else {
2581 STp->rew_at_close = STp->autorew_dev;
2582 retval = check_tape(STp, filp);
2583 if (retval > 0)
2584 retval = 0;
2585 }
2586 }
2587 else {
2588 STps = &(STp->ps[STp->partition]);
2589 STps->drv_file = STps->drv_block = (-1);
2590 }
2591
2592 return retval;
2593}
2594
2595#if DEBUG
2596#define ST_DEB_FORWARD 0
2597#define ST_DEB_BACKWARD 1
2598static void deb_space_print(char *name, int direction, char *units, unsigned char *cmd)
2599{
2600 s32 sc;
2601
2602 sc = cmd[2] & 0x80 ? 0xff000000 : 0;
2603 sc |= (cmd[2] << 16) | (cmd[3] << 8) | cmd[4];
2604 if (direction)
2605 sc = -sc;
2606 printk(ST_DEB_MSG "%s: Spacing tape %s over %d %s.\n", name,
2607 direction ? "backward" : "forward", sc, units);
2608}
2609#endif
2610
2611
2612/* Internal ioctl function */
2613static int st_int_ioctl(struct scsi_tape *STp, unsigned int cmd_in, unsigned long arg)
2614{
2615 int timeout;
2616 long ltmp;
2617 int ioctl_result;
2618 int chg_eof = 1;
2619 unsigned char cmd[MAX_COMMAND_SIZE];
Mike Christie8b05b772005-11-08 04:06:44 -06002620 struct st_request *SRpnt;
Linus Torvalds1da177e2005-04-16 15:20:36 -07002621 struct st_partstat *STps;
2622 int fileno, blkno, at_sm, undone;
2623 int datalen = 0, direction = DMA_NONE;
2624 char *name = tape_name(STp);
2625
2626 WARN_ON(STp->buffer->do_dio != 0);
2627 if (STp->ready != ST_READY) {
2628 if (STp->ready == ST_NO_TAPE)
2629 return (-ENOMEDIUM);
2630 else
2631 return (-EIO);
2632 }
2633 timeout = STp->long_timeout;
2634 STps = &(STp->ps[STp->partition]);
2635 fileno = STps->drv_file;
2636 blkno = STps->drv_block;
2637 at_sm = STps->at_sm;
2638
2639 memset(cmd, 0, MAX_COMMAND_SIZE);
2640 switch (cmd_in) {
2641 case MTFSFM:
2642 chg_eof = 0; /* Changed from the FSF after this */
2643 case MTFSF:
2644 cmd[0] = SPACE;
2645 cmd[1] = 0x01; /* Space FileMarks */
2646 cmd[2] = (arg >> 16);
2647 cmd[3] = (arg >> 8);
2648 cmd[4] = arg;
2649 DEBC(deb_space_print(name, ST_DEB_FORWARD, "filemarks", cmd);)
2650 if (fileno >= 0)
2651 fileno += arg;
2652 blkno = 0;
2653 at_sm &= (arg == 0);
2654 break;
2655 case MTBSFM:
2656 chg_eof = 0; /* Changed from the FSF after this */
2657 case MTBSF:
2658 cmd[0] = SPACE;
2659 cmd[1] = 0x01; /* Space FileMarks */
2660 ltmp = (-arg);
2661 cmd[2] = (ltmp >> 16);
2662 cmd[3] = (ltmp >> 8);
2663 cmd[4] = ltmp;
2664 DEBC(deb_space_print(name, ST_DEB_BACKWARD, "filemarks", cmd);)
2665 if (fileno >= 0)
2666 fileno -= arg;
2667 blkno = (-1); /* We can't know the block number */
2668 at_sm &= (arg == 0);
2669 break;
2670 case MTFSR:
2671 cmd[0] = SPACE;
2672 cmd[1] = 0x00; /* Space Blocks */
2673 cmd[2] = (arg >> 16);
2674 cmd[3] = (arg >> 8);
2675 cmd[4] = arg;
2676 DEBC(deb_space_print(name, ST_DEB_FORWARD, "blocks", cmd);)
2677 if (blkno >= 0)
2678 blkno += arg;
2679 at_sm &= (arg == 0);
2680 break;
2681 case MTBSR:
2682 cmd[0] = SPACE;
2683 cmd[1] = 0x00; /* Space Blocks */
2684 ltmp = (-arg);
2685 cmd[2] = (ltmp >> 16);
2686 cmd[3] = (ltmp >> 8);
2687 cmd[4] = ltmp;
2688 DEBC(deb_space_print(name, ST_DEB_BACKWARD, "blocks", cmd);)
2689 if (blkno >= 0)
2690 blkno -= arg;
2691 at_sm &= (arg == 0);
2692 break;
2693 case MTFSS:
2694 cmd[0] = SPACE;
2695 cmd[1] = 0x04; /* Space Setmarks */
2696 cmd[2] = (arg >> 16);
2697 cmd[3] = (arg >> 8);
2698 cmd[4] = arg;
2699 DEBC(deb_space_print(name, ST_DEB_FORWARD, "setmarks", cmd);)
2700 if (arg != 0) {
2701 blkno = fileno = (-1);
2702 at_sm = 1;
2703 }
2704 break;
2705 case MTBSS:
2706 cmd[0] = SPACE;
2707 cmd[1] = 0x04; /* Space Setmarks */
2708 ltmp = (-arg);
2709 cmd[2] = (ltmp >> 16);
2710 cmd[3] = (ltmp >> 8);
2711 cmd[4] = ltmp;
2712 DEBC(deb_space_print(name, ST_DEB_BACKWARD, "setmarks", cmd);)
2713 if (arg != 0) {
2714 blkno = fileno = (-1);
2715 at_sm = 1;
2716 }
2717 break;
2718 case MTWEOF:
Kai Makisara3e51d3c2010-10-09 00:17:56 +03002719 case MTWEOFI:
Linus Torvalds1da177e2005-04-16 15:20:36 -07002720 case MTWSM:
2721 if (STp->write_prot)
2722 return (-EACCES);
2723 cmd[0] = WRITE_FILEMARKS;
2724 if (cmd_in == MTWSM)
2725 cmd[1] = 2;
Lee Duncanc743e442012-03-01 12:41:01 -08002726 if (cmd_in == MTWEOFI ||
2727 (cmd_in == MTWEOF && STp->immediate_filemark))
Kai Makisara3e51d3c2010-10-09 00:17:56 +03002728 cmd[1] |= 1;
Linus Torvalds1da177e2005-04-16 15:20:36 -07002729 cmd[2] = (arg >> 16);
2730 cmd[3] = (arg >> 8);
2731 cmd[4] = arg;
James Bottomleya02488e2008-11-30 10:36:26 -06002732 timeout = STp->device->request_queue->rq_timeout;
Linus Torvalds1da177e2005-04-16 15:20:36 -07002733 DEBC(
Kai Makisara3e51d3c2010-10-09 00:17:56 +03002734 if (cmd_in != MTWSM)
Linus Torvalds1da177e2005-04-16 15:20:36 -07002735 printk(ST_DEB_MSG "%s: Writing %d filemarks.\n", name,
2736 cmd[2] * 65536 + cmd[3] * 256 + cmd[4]);
2737 else
2738 printk(ST_DEB_MSG "%s: Writing %d setmarks.\n", name,
2739 cmd[2] * 65536 + cmd[3] * 256 + cmd[4]);
2740 )
2741 if (fileno >= 0)
2742 fileno += arg;
2743 blkno = 0;
2744 at_sm = (cmd_in == MTWSM);
2745 break;
2746 case MTREW:
2747 cmd[0] = REZERO_UNIT;
2748 if (STp->immediate) {
2749 cmd[1] = 1; /* Don't wait for completion */
James Bottomleya02488e2008-11-30 10:36:26 -06002750 timeout = STp->device->request_queue->rq_timeout;
Linus Torvalds1da177e2005-04-16 15:20:36 -07002751 }
2752 DEBC(printk(ST_DEB_MSG "%s: Rewinding tape.\n", name));
2753 fileno = blkno = at_sm = 0;
2754 break;
2755 case MTNOP:
2756 DEBC(printk(ST_DEB_MSG "%s: No op on tape.\n", name));
2757 return 0; /* Should do something ? */
2758 break;
2759 case MTRETEN:
2760 cmd[0] = START_STOP;
2761 if (STp->immediate) {
2762 cmd[1] = 1; /* Don't wait for completion */
James Bottomleya02488e2008-11-30 10:36:26 -06002763 timeout = STp->device->request_queue->rq_timeout;
Linus Torvalds1da177e2005-04-16 15:20:36 -07002764 }
2765 cmd[4] = 3;
2766 DEBC(printk(ST_DEB_MSG "%s: Retensioning tape.\n", name));
2767 fileno = blkno = at_sm = 0;
2768 break;
2769 case MTEOM:
2770 if (!STp->fast_mteom) {
2771 /* space to the end of tape */
2772 ioctl_result = st_int_ioctl(STp, MTFSF, 0x7fffff);
2773 fileno = STps->drv_file;
2774 if (STps->eof >= ST_EOD_1)
2775 return 0;
2776 /* The next lines would hide the number of spaced FileMarks
2777 That's why I inserted the previous lines. I had no luck
2778 with detecting EOM with FSF, so we go now to EOM.
2779 Joerg Weule */
2780 } else
2781 fileno = (-1);
2782 cmd[0] = SPACE;
2783 cmd[1] = 3;
2784 DEBC(printk(ST_DEB_MSG "%s: Spacing to end of recorded medium.\n",
2785 name));
2786 blkno = -1;
2787 at_sm = 0;
2788 break;
2789 case MTERASE:
2790 if (STp->write_prot)
2791 return (-EACCES);
2792 cmd[0] = ERASE;
2793 cmd[1] = (arg ? 1 : 0); /* Long erase with non-zero argument */
2794 if (STp->immediate) {
2795 cmd[1] |= 2; /* Don't wait for completion */
James Bottomleya02488e2008-11-30 10:36:26 -06002796 timeout = STp->device->request_queue->rq_timeout;
Linus Torvalds1da177e2005-04-16 15:20:36 -07002797 }
2798 else
2799 timeout = STp->long_timeout * 8;
2800
2801 DEBC(printk(ST_DEB_MSG "%s: Erasing tape.\n", name));
2802 fileno = blkno = at_sm = 0;
2803 break;
2804 case MTSETBLK: /* Set block length */
2805 case MTSETDENSITY: /* Set tape density */
2806 case MTSETDRVBUFFER: /* Set drive buffering */
2807 case SET_DENS_AND_BLK: /* Set density and block size */
2808 chg_eof = 0;
2809 if (STp->dirty || (STp->buffer)->buffer_bytes != 0)
2810 return (-EIO); /* Not allowed if data in buffer */
2811 if ((cmd_in == MTSETBLK || cmd_in == SET_DENS_AND_BLK) &&
2812 (arg & MT_ST_BLKSIZE_MASK) != 0 &&
2813 STp->max_block > 0 &&
2814 ((arg & MT_ST_BLKSIZE_MASK) < STp->min_block ||
2815 (arg & MT_ST_BLKSIZE_MASK) > STp->max_block)) {
2816 printk(KERN_WARNING "%s: Illegal block size.\n", name);
2817 return (-EINVAL);
2818 }
2819 cmd[0] = MODE_SELECT;
2820 if ((STp->use_pf & USE_PF))
2821 cmd[1] = MODE_SELECT_PAGE_FORMAT;
2822 cmd[4] = datalen = 12;
2823 direction = DMA_TO_DEVICE;
2824
2825 memset((STp->buffer)->b_data, 0, 12);
2826 if (cmd_in == MTSETDRVBUFFER)
2827 (STp->buffer)->b_data[2] = (arg & 7) << 4;
2828 else
2829 (STp->buffer)->b_data[2] =
2830 STp->drv_buffer << 4;
2831 (STp->buffer)->b_data[3] = 8; /* block descriptor length */
2832 if (cmd_in == MTSETDENSITY) {
2833 (STp->buffer)->b_data[4] = arg;
2834 STp->density_changed = 1; /* At least we tried ;-) */
2835 } else if (cmd_in == SET_DENS_AND_BLK)
2836 (STp->buffer)->b_data[4] = arg >> 24;
2837 else
2838 (STp->buffer)->b_data[4] = STp->density;
2839 if (cmd_in == MTSETBLK || cmd_in == SET_DENS_AND_BLK) {
2840 ltmp = arg & MT_ST_BLKSIZE_MASK;
2841 if (cmd_in == MTSETBLK)
2842 STp->blksize_changed = 1; /* At least we tried ;-) */
2843 } else
2844 ltmp = STp->block_size;
2845 (STp->buffer)->b_data[9] = (ltmp >> 16);
2846 (STp->buffer)->b_data[10] = (ltmp >> 8);
2847 (STp->buffer)->b_data[11] = ltmp;
James Bottomleya02488e2008-11-30 10:36:26 -06002848 timeout = STp->device->request_queue->rq_timeout;
Linus Torvalds1da177e2005-04-16 15:20:36 -07002849 DEBC(
2850 if (cmd_in == MTSETBLK || cmd_in == SET_DENS_AND_BLK)
2851 printk(ST_DEB_MSG
2852 "%s: Setting block size to %d bytes.\n", name,
2853 (STp->buffer)->b_data[9] * 65536 +
2854 (STp->buffer)->b_data[10] * 256 +
2855 (STp->buffer)->b_data[11]);
2856 if (cmd_in == MTSETDENSITY || cmd_in == SET_DENS_AND_BLK)
2857 printk(ST_DEB_MSG
2858 "%s: Setting density code to %x.\n", name,
2859 (STp->buffer)->b_data[4]);
2860 if (cmd_in == MTSETDRVBUFFER)
2861 printk(ST_DEB_MSG
2862 "%s: Setting drive buffer code to %d.\n", name,
2863 ((STp->buffer)->b_data[2] >> 4) & 7);
2864 )
2865 break;
2866 default:
2867 return (-ENOSYS);
2868 }
2869
Kai Makisara02ae2c02008-12-18 14:49:50 +09002870 SRpnt = st_do_scsi(NULL, STp, cmd, datalen, direction,
2871 timeout, MAX_RETRIES, 1);
Linus Torvalds1da177e2005-04-16 15:20:36 -07002872 if (!SRpnt)
2873 return (STp->buffer)->syscall_result;
2874
Kai Makisara02ae2c02008-12-18 14:49:50 +09002875 ioctl_result = (STp->buffer)->syscall_result;
Linus Torvalds1da177e2005-04-16 15:20:36 -07002876
2877 if (!ioctl_result) { /* SCSI command successful */
Mike Christie8b05b772005-11-08 04:06:44 -06002878 st_release_request(SRpnt);
Linus Torvalds1da177e2005-04-16 15:20:36 -07002879 SRpnt = NULL;
2880 STps->drv_block = blkno;
2881 STps->drv_file = fileno;
2882 STps->at_sm = at_sm;
2883
2884 if (cmd_in == MTBSFM)
2885 ioctl_result = st_int_ioctl(STp, MTFSF, 1);
2886 else if (cmd_in == MTFSFM)
2887 ioctl_result = st_int_ioctl(STp, MTBSF, 1);
2888
2889 if (cmd_in == MTSETBLK || cmd_in == SET_DENS_AND_BLK) {
Linus Torvalds1da177e2005-04-16 15:20:36 -07002890 STp->block_size = arg & MT_ST_BLKSIZE_MASK;
2891 if (STp->block_size != 0) {
Linus Torvalds1da177e2005-04-16 15:20:36 -07002892 (STp->buffer)->buffer_blocks =
2893 (STp->buffer)->buffer_size / STp->block_size;
2894 }
2895 (STp->buffer)->buffer_bytes = (STp->buffer)->read_pointer = 0;
2896 if (cmd_in == SET_DENS_AND_BLK)
2897 STp->density = arg >> MT_ST_DENSITY_SHIFT;
2898 } else if (cmd_in == MTSETDRVBUFFER)
2899 STp->drv_buffer = (arg & 7);
2900 else if (cmd_in == MTSETDENSITY)
2901 STp->density = arg;
2902
2903 if (cmd_in == MTEOM)
2904 STps->eof = ST_EOD;
2905 else if (cmd_in == MTFSF)
2906 STps->eof = ST_FM;
2907 else if (chg_eof)
2908 STps->eof = ST_NOEOF;
2909
Kai Makisara3e51d3c2010-10-09 00:17:56 +03002910 if (cmd_in == MTWEOF || cmd_in == MTWEOFI)
2911 STps->rw = ST_IDLE; /* prevent automatic WEOF at close */
Linus Torvalds1da177e2005-04-16 15:20:36 -07002912 } else { /* SCSI command was not completely successful. Don't return
2913 from this block without releasing the SCSI command block! */
2914 struct st_cmdstatus *cmdstatp = &STp->buffer->cmdstat;
2915
2916 if (cmdstatp->flags & SENSE_EOM) {
2917 if (cmd_in != MTBSF && cmd_in != MTBSFM &&
2918 cmd_in != MTBSR && cmd_in != MTBSS)
2919 STps->eof = ST_EOM_OK;
2920 STps->drv_block = 0;
2921 }
2922
2923 if (cmdstatp->remainder_valid)
2924 undone = (int)cmdstatp->uremainder64;
2925 else
2926 undone = 0;
2927
Kai Makisara3e51d3c2010-10-09 00:17:56 +03002928 if ((cmd_in == MTWEOF || cmd_in == MTWEOFI) &&
Linus Torvalds1da177e2005-04-16 15:20:36 -07002929 cmdstatp->have_sense &&
Kai Makisara91614c02007-01-26 00:38:39 +02002930 (cmdstatp->flags & SENSE_EOM)) {
2931 if (cmdstatp->sense_hdr.sense_key == NO_SENSE ||
2932 cmdstatp->sense_hdr.sense_key == RECOVERED_ERROR) {
2933 ioctl_result = 0; /* EOF(s) written successfully at EOM */
2934 STps->eof = ST_NOEOF;
2935 } else { /* Writing EOF(s) failed */
2936 if (fileno >= 0)
2937 fileno -= undone;
2938 if (undone < arg)
2939 STps->eof = ST_NOEOF;
2940 }
Linus Torvalds1da177e2005-04-16 15:20:36 -07002941 STps->drv_file = fileno;
Linus Torvalds1da177e2005-04-16 15:20:36 -07002942 } else if ((cmd_in == MTFSF) || (cmd_in == MTFSFM)) {
2943 if (fileno >= 0)
2944 STps->drv_file = fileno - undone;
2945 else
2946 STps->drv_file = fileno;
2947 STps->drv_block = -1;
2948 STps->eof = ST_NOEOF;
2949 } else if ((cmd_in == MTBSF) || (cmd_in == MTBSFM)) {
2950 if (arg > 0 && undone < 0) /* Some drives get this wrong */
2951 undone = (-undone);
2952 if (STps->drv_file >= 0)
2953 STps->drv_file = fileno + undone;
2954 STps->drv_block = 0;
2955 STps->eof = ST_NOEOF;
2956 } else if (cmd_in == MTFSR) {
2957 if (cmdstatp->flags & SENSE_FMK) { /* Hit filemark */
2958 if (STps->drv_file >= 0)
2959 STps->drv_file++;
2960 STps->drv_block = 0;
2961 STps->eof = ST_FM;
2962 } else {
2963 if (blkno >= undone)
2964 STps->drv_block = blkno - undone;
2965 else
2966 STps->drv_block = (-1);
2967 STps->eof = ST_NOEOF;
2968 }
2969 } else if (cmd_in == MTBSR) {
2970 if (cmdstatp->flags & SENSE_FMK) { /* Hit filemark */
2971 STps->drv_file--;
2972 STps->drv_block = (-1);
2973 } else {
2974 if (arg > 0 && undone < 0) /* Some drives get this wrong */
2975 undone = (-undone);
2976 if (STps->drv_block >= 0)
2977 STps->drv_block = blkno + undone;
2978 }
2979 STps->eof = ST_NOEOF;
2980 } else if (cmd_in == MTEOM) {
2981 STps->drv_file = (-1);
2982 STps->drv_block = (-1);
2983 STps->eof = ST_EOD;
2984 } else if (cmd_in == MTSETBLK ||
2985 cmd_in == MTSETDENSITY ||
2986 cmd_in == MTSETDRVBUFFER ||
2987 cmd_in == SET_DENS_AND_BLK) {
2988 if (cmdstatp->sense_hdr.sense_key == ILLEGAL_REQUEST &&
2989 !(STp->use_pf & PF_TESTED)) {
2990 /* Try the other possible state of Page Format if not
2991 already tried */
Kai Makisara1da20192009-05-02 08:49:34 +03002992 STp->use_pf = (STp->use_pf ^ USE_PF) | PF_TESTED;
Mike Christie8b05b772005-11-08 04:06:44 -06002993 st_release_request(SRpnt);
Linus Torvalds1da177e2005-04-16 15:20:36 -07002994 SRpnt = NULL;
2995 return st_int_ioctl(STp, cmd_in, arg);
2996 }
2997 } else if (chg_eof)
2998 STps->eof = ST_NOEOF;
2999
3000 if (cmdstatp->sense_hdr.sense_key == BLANK_CHECK)
3001 STps->eof = ST_EOD;
3002
Mike Christie8b05b772005-11-08 04:06:44 -06003003 st_release_request(SRpnt);
Linus Torvalds1da177e2005-04-16 15:20:36 -07003004 SRpnt = NULL;
3005 }
3006
3007 return ioctl_result;
3008}
3009
3010
3011/* Get the tape position. If bt == 2, arg points into a kernel space mt_loc
3012 structure. */
3013
3014static int get_location(struct scsi_tape *STp, unsigned int *block, int *partition,
3015 int logical)
3016{
3017 int result;
3018 unsigned char scmd[MAX_COMMAND_SIZE];
Mike Christie8b05b772005-11-08 04:06:44 -06003019 struct st_request *SRpnt;
Linus Torvalds1da177e2005-04-16 15:20:36 -07003020 DEB( char *name = tape_name(STp); )
3021
3022 if (STp->ready != ST_READY)
3023 return (-EIO);
3024
3025 memset(scmd, 0, MAX_COMMAND_SIZE);
3026 if ((STp->device)->scsi_level < SCSI_2) {
3027 scmd[0] = QFA_REQUEST_BLOCK;
3028 scmd[4] = 3;
3029 } else {
3030 scmd[0] = READ_POSITION;
3031 if (!logical && !STp->scsi2_logical)
3032 scmd[1] = 1;
3033 }
Kai Makisara02ae2c02008-12-18 14:49:50 +09003034 SRpnt = st_do_scsi(NULL, STp, scmd, 20, DMA_FROM_DEVICE,
3035 STp->device->request_queue->rq_timeout,
3036 MAX_READY_RETRIES, 1);
Linus Torvalds1da177e2005-04-16 15:20:36 -07003037 if (!SRpnt)
Kai Makisara02ae2c02008-12-18 14:49:50 +09003038 return (STp->buffer)->syscall_result;
Linus Torvalds1da177e2005-04-16 15:20:36 -07003039
3040 if ((STp->buffer)->syscall_result != 0 ||
3041 (STp->device->scsi_level >= SCSI_2 &&
3042 ((STp->buffer)->b_data[0] & 4) != 0)) {
3043 *block = *partition = 0;
3044 DEBC(printk(ST_DEB_MSG "%s: Can't read tape position.\n", name));
3045 result = (-EIO);
3046 } else {
3047 result = 0;
3048 if ((STp->device)->scsi_level < SCSI_2) {
3049 *block = ((STp->buffer)->b_data[0] << 16)
3050 + ((STp->buffer)->b_data[1] << 8)
3051 + (STp->buffer)->b_data[2];
3052 *partition = 0;
3053 } else {
3054 *block = ((STp->buffer)->b_data[4] << 24)
3055 + ((STp->buffer)->b_data[5] << 16)
3056 + ((STp->buffer)->b_data[6] << 8)
3057 + (STp->buffer)->b_data[7];
3058 *partition = (STp->buffer)->b_data[1];
3059 if (((STp->buffer)->b_data[0] & 0x80) &&
3060 (STp->buffer)->b_data[1] == 0) /* BOP of partition 0 */
3061 STp->ps[0].drv_block = STp->ps[0].drv_file = 0;
3062 }
3063 DEBC(printk(ST_DEB_MSG "%s: Got tape pos. blk %d part %d.\n", name,
3064 *block, *partition));
3065 }
Mike Christie8b05b772005-11-08 04:06:44 -06003066 st_release_request(SRpnt);
Linus Torvalds1da177e2005-04-16 15:20:36 -07003067 SRpnt = NULL;
3068
3069 return result;
3070}
3071
3072
3073/* Set the tape block and partition. Negative partition means that only the
3074 block should be set in vendor specific way. */
3075static int set_location(struct scsi_tape *STp, unsigned int block, int partition,
3076 int logical)
3077{
3078 struct st_partstat *STps;
3079 int result, p;
3080 unsigned int blk;
3081 int timeout;
3082 unsigned char scmd[MAX_COMMAND_SIZE];
Mike Christie8b05b772005-11-08 04:06:44 -06003083 struct st_request *SRpnt;
Linus Torvalds1da177e2005-04-16 15:20:36 -07003084 DEB( char *name = tape_name(STp); )
3085
3086 if (STp->ready != ST_READY)
3087 return (-EIO);
3088 timeout = STp->long_timeout;
3089 STps = &(STp->ps[STp->partition]);
3090
3091 DEBC(printk(ST_DEB_MSG "%s: Setting block to %d and partition to %d.\n",
3092 name, block, partition));
3093 DEB(if (partition < 0)
3094 return (-EIO); )
3095
3096 /* Update the location at the partition we are leaving */
3097 if ((!STp->can_partitions && partition != 0) ||
3098 partition >= ST_NBR_PARTITIONS)
3099 return (-EINVAL);
3100 if (partition != STp->partition) {
3101 if (get_location(STp, &blk, &p, 1))
3102 STps->last_block_valid = 0;
3103 else {
3104 STps->last_block_valid = 1;
3105 STps->last_block_visited = blk;
3106 DEBC(printk(ST_DEB_MSG
3107 "%s: Visited block %d for partition %d saved.\n",
3108 name, blk, STp->partition));
3109 }
3110 }
3111
3112 memset(scmd, 0, MAX_COMMAND_SIZE);
3113 if ((STp->device)->scsi_level < SCSI_2) {
3114 scmd[0] = QFA_SEEK_BLOCK;
3115 scmd[2] = (block >> 16);
3116 scmd[3] = (block >> 8);
3117 scmd[4] = block;
3118 scmd[5] = 0;
3119 } else {
3120 scmd[0] = SEEK_10;
3121 scmd[3] = (block >> 24);
3122 scmd[4] = (block >> 16);
3123 scmd[5] = (block >> 8);
3124 scmd[6] = block;
3125 if (!logical && !STp->scsi2_logical)
3126 scmd[1] = 4;
3127 if (STp->partition != partition) {
3128 scmd[1] |= 2;
3129 scmd[8] = partition;
3130 DEBC(printk(ST_DEB_MSG
3131 "%s: Trying to change partition from %d to %d\n",
3132 name, STp->partition, partition));
3133 }
3134 }
3135 if (STp->immediate) {
3136 scmd[1] |= 1; /* Don't wait for completion */
James Bottomleya02488e2008-11-30 10:36:26 -06003137 timeout = STp->device->request_queue->rq_timeout;
Linus Torvalds1da177e2005-04-16 15:20:36 -07003138 }
3139
Kai Makisara02ae2c02008-12-18 14:49:50 +09003140 SRpnt = st_do_scsi(NULL, STp, scmd, 0, DMA_NONE,
3141 timeout, MAX_READY_RETRIES, 1);
Linus Torvalds1da177e2005-04-16 15:20:36 -07003142 if (!SRpnt)
Kai Makisara02ae2c02008-12-18 14:49:50 +09003143 return (STp->buffer)->syscall_result;
Linus Torvalds1da177e2005-04-16 15:20:36 -07003144
3145 STps->drv_block = STps->drv_file = (-1);
3146 STps->eof = ST_NOEOF;
3147 if ((STp->buffer)->syscall_result != 0) {
3148 result = (-EIO);
3149 if (STp->can_partitions &&
3150 (STp->device)->scsi_level >= SCSI_2 &&
3151 (p = find_partition(STp)) >= 0)
3152 STp->partition = p;
3153 } else {
3154 if (STp->can_partitions) {
3155 STp->partition = partition;
3156 STps = &(STp->ps[partition]);
3157 if (!STps->last_block_valid ||
3158 STps->last_block_visited != block) {
3159 STps->at_sm = 0;
3160 STps->rw = ST_IDLE;
3161 }
3162 } else
3163 STps->at_sm = 0;
3164 if (block == 0)
3165 STps->drv_block = STps->drv_file = 0;
3166 result = 0;
3167 }
Kai Makisara02ae2c02008-12-18 14:49:50 +09003168
Mike Christie8b05b772005-11-08 04:06:44 -06003169 st_release_request(SRpnt);
Linus Torvalds1da177e2005-04-16 15:20:36 -07003170 SRpnt = NULL;
3171
3172 return result;
3173}
3174
3175
3176/* Find the current partition number for the drive status. Called from open and
3177 returns either partition number of negative error code. */
3178static int find_partition(struct scsi_tape *STp)
3179{
3180 int i, partition;
3181 unsigned int block;
3182
3183 if ((i = get_location(STp, &block, &partition, 1)) < 0)
3184 return i;
3185 if (partition >= ST_NBR_PARTITIONS)
3186 return (-EIO);
3187 return partition;
3188}
3189
3190
3191/* Change the partition if necessary */
3192static int switch_partition(struct scsi_tape *STp)
3193{
3194 struct st_partstat *STps;
3195
3196 if (STp->partition == STp->new_partition)
3197 return 0;
3198 STps = &(STp->ps[STp->new_partition]);
3199 if (!STps->last_block_valid)
3200 STps->last_block_visited = 0;
3201 return set_location(STp, STps->last_block_visited, STp->new_partition, 1);
3202}
3203
3204/* Functions for reading and writing the medium partition mode page. */
3205
3206#define PART_PAGE 0x11
3207#define PART_PAGE_FIXED_LENGTH 8
3208
3209#define PP_OFF_MAX_ADD_PARTS 2
3210#define PP_OFF_NBR_ADD_PARTS 3
3211#define PP_OFF_FLAGS 4
3212#define PP_OFF_PART_UNITS 6
3213#define PP_OFF_RESERVED 7
3214
3215#define PP_BIT_IDP 0x20
3216#define PP_MSK_PSUM_MB 0x10
3217
3218/* Get the number of partitions on the tape. As a side effect reads the
3219 mode page into the tape buffer. */
3220static int nbr_partitions(struct scsi_tape *STp)
3221{
3222 int result;
3223 DEB( char *name = tape_name(STp); )
3224
3225 if (STp->ready != ST_READY)
3226 return (-EIO);
3227
3228 result = read_mode_page(STp, PART_PAGE, 1);
3229
3230 if (result) {
3231 DEBC(printk(ST_DEB_MSG "%s: Can't read medium partition page.\n",
3232 name));
3233 result = (-EIO);
3234 } else {
3235 result = (STp->buffer)->b_data[MODE_HEADER_LENGTH +
3236 PP_OFF_NBR_ADD_PARTS] + 1;
3237 DEBC(printk(ST_DEB_MSG "%s: Number of partitions %d.\n", name, result));
3238 }
3239
3240 return result;
3241}
3242
3243
3244/* Partition the tape into two partitions if size > 0 or one partition if
3245 size == 0.
3246
3247 The block descriptors are read and written because Sony SDT-7000 does not
3248 work without this (suggestion from Michael Schaefer <Michael.Schaefer@dlr.de>).
3249
3250 My HP C1533A drive returns only one partition size field. This is used to
3251 set the size of partition 1. There is no size field for the default partition.
3252 Michael Schaefer's Sony SDT-7000 returns two descriptors and the second is
3253 used to set the size of partition 1 (this is what the SCSI-3 standard specifies).
3254 The following algorithm is used to accommodate both drives: if the number of
3255 partition size fields is greater than the maximum number of additional partitions
3256 in the mode page, the second field is used. Otherwise the first field is used.
3257
3258 For Seagate DDS drives the page length must be 8 when no partitions is defined
3259 and 10 when 1 partition is defined (information from Eric Lee Green). This is
3260 is acceptable also to some other old drives and enforced if the first partition
3261 size field is used for the first additional partition size.
3262 */
3263static int partition_tape(struct scsi_tape *STp, int size)
3264{
3265 char *name = tape_name(STp);
3266 int result;
3267 int pgo, psd_cnt, psdo;
3268 unsigned char *bp;
3269
3270 result = read_mode_page(STp, PART_PAGE, 0);
3271 if (result) {
3272 DEBC(printk(ST_DEB_MSG "%s: Can't read partition mode page.\n", name));
3273 return result;
3274 }
3275 /* The mode page is in the buffer. Let's modify it and write it. */
3276 bp = (STp->buffer)->b_data;
3277 pgo = MODE_HEADER_LENGTH + bp[MH_OFF_BDESCS_LENGTH];
3278 DEBC(printk(ST_DEB_MSG "%s: Partition page length is %d bytes.\n",
3279 name, bp[pgo + MP_OFF_PAGE_LENGTH] + 2));
3280
3281 psd_cnt = (bp[pgo + MP_OFF_PAGE_LENGTH] + 2 - PART_PAGE_FIXED_LENGTH) / 2;
3282 psdo = pgo + PART_PAGE_FIXED_LENGTH;
3283 if (psd_cnt > bp[pgo + PP_OFF_MAX_ADD_PARTS]) {
3284 bp[psdo] = bp[psdo + 1] = 0xff; /* Rest of the tape */
3285 psdo += 2;
3286 }
3287 memset(bp + psdo, 0, bp[pgo + PP_OFF_NBR_ADD_PARTS] * 2);
3288
3289 DEBC(printk("%s: psd_cnt %d, max.parts %d, nbr_parts %d\n", name,
3290 psd_cnt, bp[pgo + PP_OFF_MAX_ADD_PARTS],
3291 bp[pgo + PP_OFF_NBR_ADD_PARTS]));
3292
3293 if (size <= 0) {
3294 bp[pgo + PP_OFF_NBR_ADD_PARTS] = 0;
3295 if (psd_cnt <= bp[pgo + PP_OFF_MAX_ADD_PARTS])
3296 bp[pgo + MP_OFF_PAGE_LENGTH] = 6;
3297 DEBC(printk(ST_DEB_MSG "%s: Formatting tape with one partition.\n",
3298 name));
3299 } else {
3300 bp[psdo] = (size >> 8) & 0xff;
3301 bp[psdo + 1] = size & 0xff;
3302 bp[pgo + 3] = 1;
3303 if (bp[pgo + MP_OFF_PAGE_LENGTH] < 8)
3304 bp[pgo + MP_OFF_PAGE_LENGTH] = 8;
3305 DEBC(printk(ST_DEB_MSG
3306 "%s: Formatting tape with two partitions (1 = %d MB).\n",
3307 name, size));
3308 }
3309 bp[pgo + PP_OFF_PART_UNITS] = 0;
3310 bp[pgo + PP_OFF_RESERVED] = 0;
3311 bp[pgo + PP_OFF_FLAGS] = PP_BIT_IDP | PP_MSK_PSUM_MB;
3312
3313 result = write_mode_page(STp, PART_PAGE, 1);
3314 if (result) {
3315 printk(KERN_INFO "%s: Partitioning of tape failed.\n", name);
3316 result = (-EIO);
3317 }
3318
3319 return result;
3320}
3321
3322
3323
3324/* The ioctl command */
Kai Makisarafd66c1b2008-01-17 22:45:22 +02003325static long st_ioctl(struct file *file, unsigned int cmd_in, unsigned long arg)
Linus Torvalds1da177e2005-04-16 15:20:36 -07003326{
3327 int i, cmd_nr, cmd_type, bt;
3328 int retval = 0;
3329 unsigned int blk;
3330 struct scsi_tape *STp = file->private_data;
3331 struct st_modedef *STm;
3332 struct st_partstat *STps;
3333 char *name = tape_name(STp);
3334 void __user *p = (void __user *)arg;
3335
Matthias Kaehlcke28f85002007-07-29 23:38:15 +02003336 if (mutex_lock_interruptible(&STp->lock))
Linus Torvalds1da177e2005-04-16 15:20:36 -07003337 return -ERESTARTSYS;
3338
3339 DEB(
3340 if (debugging && !STp->in_use) {
3341 printk(ST_DEB_MSG "%s: Incorrect device.\n", name);
3342 retval = (-EIO);
3343 goto out;
3344 } ) /* end DEB */
3345
3346 STm = &(STp->modes[STp->current_mode]);
3347 STps = &(STp->ps[STp->partition]);
3348
3349 /*
3350 * If we are in the middle of error recovery, don't let anyone
3351 * else try and use this device. Also, if error recovery fails, it
3352 * may try and take the device offline, in which case all further
3353 * access to the device is prohibited.
3354 */
Al Viro83ff6fe2008-03-02 08:15:49 -05003355 retval = scsi_nonblockable_ioctl(STp->device, cmd_in, p,
3356 file->f_flags & O_NDELAY);
Linus Torvalds1da177e2005-04-16 15:20:36 -07003357 if (!scsi_block_when_processing_errors(STp->device) || retval != -ENODEV)
3358 goto out;
3359 retval = 0;
3360
3361 cmd_type = _IOC_TYPE(cmd_in);
3362 cmd_nr = _IOC_NR(cmd_in);
3363
3364 if (cmd_type == _IOC_TYPE(MTIOCTOP) && cmd_nr == _IOC_NR(MTIOCTOP)) {
3365 struct mtop mtc;
3366
3367 if (_IOC_SIZE(cmd_in) != sizeof(mtc)) {
3368 retval = (-EINVAL);
3369 goto out;
3370 }
3371
3372 i = copy_from_user(&mtc, p, sizeof(struct mtop));
3373 if (i) {
3374 retval = (-EFAULT);
3375 goto out;
3376 }
3377
3378 if (mtc.mt_op == MTSETDRVBUFFER && !capable(CAP_SYS_ADMIN)) {
3379 printk(KERN_WARNING
3380 "%s: MTSETDRVBUFFER only allowed for root.\n", name);
3381 retval = (-EPERM);
3382 goto out;
3383 }
3384 if (!STm->defined &&
3385 (mtc.mt_op != MTSETDRVBUFFER &&
3386 (mtc.mt_count & MT_ST_OPTIONS) == 0)) {
3387 retval = (-ENXIO);
3388 goto out;
3389 }
3390
3391 if (!STp->pos_unknown) {
3392
3393 if (STps->eof == ST_FM_HIT) {
3394 if (mtc.mt_op == MTFSF || mtc.mt_op == MTFSFM ||
3395 mtc.mt_op == MTEOM) {
3396 mtc.mt_count -= 1;
3397 if (STps->drv_file >= 0)
3398 STps->drv_file += 1;
3399 } else if (mtc.mt_op == MTBSF || mtc.mt_op == MTBSFM) {
3400 mtc.mt_count += 1;
3401 if (STps->drv_file >= 0)
3402 STps->drv_file += 1;
3403 }
3404 }
3405
3406 if (mtc.mt_op == MTSEEK) {
3407 /* Old position must be restored if partition will be
3408 changed */
3409 i = !STp->can_partitions ||
3410 (STp->new_partition != STp->partition);
3411 } else {
3412 i = mtc.mt_op == MTREW || mtc.mt_op == MTOFFL ||
3413 mtc.mt_op == MTRETEN || mtc.mt_op == MTEOM ||
3414 mtc.mt_op == MTLOCK || mtc.mt_op == MTLOAD ||
3415 mtc.mt_op == MTFSF || mtc.mt_op == MTFSFM ||
3416 mtc.mt_op == MTBSF || mtc.mt_op == MTBSFM ||
3417 mtc.mt_op == MTCOMPRESSION;
3418 }
3419 i = flush_buffer(STp, i);
3420 if (i < 0) {
3421 retval = i;
3422 goto out;
3423 }
3424 if (STps->rw == ST_WRITING &&
3425 (mtc.mt_op == MTREW || mtc.mt_op == MTOFFL ||
3426 mtc.mt_op == MTSEEK ||
3427 mtc.mt_op == MTBSF || mtc.mt_op == MTBSFM)) {
3428 i = st_int_ioctl(STp, MTWEOF, 1);
3429 if (i < 0) {
3430 retval = i;
3431 goto out;
3432 }
3433 if (mtc.mt_op == MTBSF || mtc.mt_op == MTBSFM)
3434 mtc.mt_count++;
3435 STps->rw = ST_IDLE;
3436 }
3437
3438 } else {
3439 /*
3440 * If there was a bus reset, block further access
3441 * to this device. If the user wants to rewind the tape,
3442 * then reset the flag and allow access again.
3443 */
3444 if (mtc.mt_op != MTREW &&
3445 mtc.mt_op != MTOFFL &&
3446 mtc.mt_op != MTRETEN &&
3447 mtc.mt_op != MTERASE &&
3448 mtc.mt_op != MTSEEK &&
3449 mtc.mt_op != MTEOM) {
3450 retval = (-EIO);
3451 goto out;
3452 }
3453 reset_state(STp);
3454 /* remove this when the midlevel properly clears was_reset */
3455 STp->device->was_reset = 0;
3456 }
3457
3458 if (mtc.mt_op != MTNOP && mtc.mt_op != MTSETBLK &&
3459 mtc.mt_op != MTSETDENSITY && mtc.mt_op != MTWSM &&
3460 mtc.mt_op != MTSETDRVBUFFER && mtc.mt_op != MTSETPART)
3461 STps->rw = ST_IDLE; /* Prevent automatic WEOF and fsf */
3462
3463 if (mtc.mt_op == MTOFFL && STp->door_locked != ST_UNLOCKED)
3464 do_door_lock(STp, 0); /* Ignore result! */
3465
3466 if (mtc.mt_op == MTSETDRVBUFFER &&
3467 (mtc.mt_count & MT_ST_OPTIONS) != 0) {
3468 retval = st_set_options(STp, mtc.mt_count);
3469 goto out;
3470 }
3471
3472 if (mtc.mt_op == MTSETPART) {
3473 if (!STp->can_partitions ||
3474 mtc.mt_count < 0 || mtc.mt_count >= ST_NBR_PARTITIONS) {
3475 retval = (-EINVAL);
3476 goto out;
3477 }
3478 if (mtc.mt_count >= STp->nbr_partitions &&
3479 (STp->nbr_partitions = nbr_partitions(STp)) < 0) {
3480 retval = (-EIO);
3481 goto out;
3482 }
3483 if (mtc.mt_count >= STp->nbr_partitions) {
3484 retval = (-EINVAL);
3485 goto out;
3486 }
3487 STp->new_partition = mtc.mt_count;
3488 retval = 0;
3489 goto out;
3490 }
3491
3492 if (mtc.mt_op == MTMKPART) {
3493 if (!STp->can_partitions) {
3494 retval = (-EINVAL);
3495 goto out;
3496 }
3497 if ((i = st_int_ioctl(STp, MTREW, 0)) < 0 ||
3498 (i = partition_tape(STp, mtc.mt_count)) < 0) {
3499 retval = i;
3500 goto out;
3501 }
3502 for (i = 0; i < ST_NBR_PARTITIONS; i++) {
3503 STp->ps[i].rw = ST_IDLE;
3504 STp->ps[i].at_sm = 0;
3505 STp->ps[i].last_block_valid = 0;
3506 }
3507 STp->partition = STp->new_partition = 0;
3508 STp->nbr_partitions = 1; /* Bad guess ?-) */
3509 STps->drv_block = STps->drv_file = 0;
3510 retval = 0;
3511 goto out;
3512 }
3513
3514 if (mtc.mt_op == MTSEEK) {
3515 i = set_location(STp, mtc.mt_count, STp->new_partition, 0);
3516 if (!STp->can_partitions)
3517 STp->ps[0].rw = ST_IDLE;
3518 retval = i;
3519 goto out;
3520 }
3521
3522 if (mtc.mt_op == MTUNLOAD || mtc.mt_op == MTOFFL) {
3523 retval = do_load_unload(STp, file, 0);
3524 goto out;
3525 }
3526
3527 if (mtc.mt_op == MTLOAD) {
3528 retval = do_load_unload(STp, file, max(1, mtc.mt_count));
3529 goto out;
3530 }
3531
3532 if (mtc.mt_op == MTLOCK || mtc.mt_op == MTUNLOCK) {
3533 retval = do_door_lock(STp, (mtc.mt_op == MTLOCK));
3534 goto out;
3535 }
3536
3537 if (STp->can_partitions && STp->ready == ST_READY &&
3538 (i = switch_partition(STp)) < 0) {
3539 retval = i;
3540 goto out;
3541 }
3542
3543 if (mtc.mt_op == MTCOMPRESSION)
3544 retval = st_compression(STp, (mtc.mt_count & 1));
3545 else
3546 retval = st_int_ioctl(STp, mtc.mt_op, mtc.mt_count);
3547 goto out;
3548 }
3549 if (!STm->defined) {
3550 retval = (-ENXIO);
3551 goto out;
3552 }
3553
3554 if ((i = flush_buffer(STp, 0)) < 0) {
3555 retval = i;
3556 goto out;
3557 }
3558 if (STp->can_partitions &&
3559 (i = switch_partition(STp)) < 0) {
3560 retval = i;
3561 goto out;
3562 }
3563
3564 if (cmd_type == _IOC_TYPE(MTIOCGET) && cmd_nr == _IOC_NR(MTIOCGET)) {
3565 struct mtget mt_status;
3566
3567 if (_IOC_SIZE(cmd_in) != sizeof(struct mtget)) {
3568 retval = (-EINVAL);
3569 goto out;
3570 }
3571
3572 mt_status.mt_type = STp->tape_type;
3573 mt_status.mt_dsreg =
3574 ((STp->block_size << MT_ST_BLKSIZE_SHIFT) & MT_ST_BLKSIZE_MASK) |
3575 ((STp->density << MT_ST_DENSITY_SHIFT) & MT_ST_DENSITY_MASK);
3576 mt_status.mt_blkno = STps->drv_block;
3577 mt_status.mt_fileno = STps->drv_file;
3578 if (STp->block_size != 0) {
3579 if (STps->rw == ST_WRITING)
3580 mt_status.mt_blkno +=
3581 (STp->buffer)->buffer_bytes / STp->block_size;
3582 else if (STps->rw == ST_READING)
3583 mt_status.mt_blkno -=
3584 ((STp->buffer)->buffer_bytes +
3585 STp->block_size - 1) / STp->block_size;
3586 }
3587
3588 mt_status.mt_gstat = 0;
3589 if (STp->drv_write_prot)
3590 mt_status.mt_gstat |= GMT_WR_PROT(0xffffffff);
3591 if (mt_status.mt_blkno == 0) {
3592 if (mt_status.mt_fileno == 0)
3593 mt_status.mt_gstat |= GMT_BOT(0xffffffff);
3594 else
3595 mt_status.mt_gstat |= GMT_EOF(0xffffffff);
3596 }
3597 mt_status.mt_erreg = (STp->recover_reg << MT_ST_SOFTERR_SHIFT);
3598 mt_status.mt_resid = STp->partition;
3599 if (STps->eof == ST_EOM_OK || STps->eof == ST_EOM_ERROR)
3600 mt_status.mt_gstat |= GMT_EOT(0xffffffff);
3601 else if (STps->eof >= ST_EOM_OK)
3602 mt_status.mt_gstat |= GMT_EOD(0xffffffff);
3603 if (STp->density == 1)
3604 mt_status.mt_gstat |= GMT_D_800(0xffffffff);
3605 else if (STp->density == 2)
3606 mt_status.mt_gstat |= GMT_D_1600(0xffffffff);
3607 else if (STp->density == 3)
3608 mt_status.mt_gstat |= GMT_D_6250(0xffffffff);
3609 if (STp->ready == ST_READY)
3610 mt_status.mt_gstat |= GMT_ONLINE(0xffffffff);
3611 if (STp->ready == ST_NO_TAPE)
3612 mt_status.mt_gstat |= GMT_DR_OPEN(0xffffffff);
3613 if (STps->at_sm)
3614 mt_status.mt_gstat |= GMT_SM(0xffffffff);
3615 if (STm->do_async_writes ||
3616 (STm->do_buffer_writes && STp->block_size != 0) ||
3617 STp->drv_buffer != 0)
3618 mt_status.mt_gstat |= GMT_IM_REP_EN(0xffffffff);
3619 if (STp->cleaning_req)
3620 mt_status.mt_gstat |= GMT_CLN(0xffffffff);
3621
3622 i = copy_to_user(p, &mt_status, sizeof(struct mtget));
3623 if (i) {
3624 retval = (-EFAULT);
3625 goto out;
3626 }
3627
3628 STp->recover_reg = 0; /* Clear after read */
3629 retval = 0;
3630 goto out;
3631 } /* End of MTIOCGET */
3632 if (cmd_type == _IOC_TYPE(MTIOCPOS) && cmd_nr == _IOC_NR(MTIOCPOS)) {
3633 struct mtpos mt_pos;
3634 if (_IOC_SIZE(cmd_in) != sizeof(struct mtpos)) {
3635 retval = (-EINVAL);
3636 goto out;
3637 }
3638 if ((i = get_location(STp, &blk, &bt, 0)) < 0) {
3639 retval = i;
3640 goto out;
3641 }
3642 mt_pos.mt_blkno = blk;
3643 i = copy_to_user(p, &mt_pos, sizeof(struct mtpos));
3644 if (i)
3645 retval = (-EFAULT);
3646 goto out;
3647 }
Matthias Kaehlcke28f85002007-07-29 23:38:15 +02003648 mutex_unlock(&STp->lock);
Linus Torvalds1da177e2005-04-16 15:20:36 -07003649 switch (cmd_in) {
3650 case SCSI_IOCTL_GET_IDLUN:
3651 case SCSI_IOCTL_GET_BUS_NUMBER:
3652 break;
3653 default:
Kai Makisara 16c4b3e2005-05-01 18:11:55 +03003654 if ((cmd_in == SG_IO ||
3655 cmd_in == SCSI_IOCTL_SEND_COMMAND ||
3656 cmd_in == CDROM_SEND_PACKET) &&
3657 !capable(CAP_SYS_RAWIO))
Linus Torvalds1da177e2005-04-16 15:20:36 -07003658 i = -EPERM;
3659 else
Al Viro74f3c8a2007-08-27 15:38:10 -04003660 i = scsi_cmd_ioctl(STp->disk->queue, STp->disk,
3661 file->f_mode, cmd_in, p);
Linus Torvalds1da177e2005-04-16 15:20:36 -07003662 if (i != -ENOTTY)
3663 return i;
3664 break;
3665 }
Kai Makisara 16c4b3e2005-05-01 18:11:55 +03003666 retval = scsi_ioctl(STp->device, cmd_in, p);
3667 if (!retval && cmd_in == SCSI_IOCTL_STOP_UNIT) { /* unload */
3668 STp->rew_at_close = 0;
3669 STp->ready = ST_NO_TAPE;
3670 }
3671 return retval;
Linus Torvalds1da177e2005-04-16 15:20:36 -07003672
3673 out:
Matthias Kaehlcke28f85002007-07-29 23:38:15 +02003674 mutex_unlock(&STp->lock);
Linus Torvalds1da177e2005-04-16 15:20:36 -07003675 return retval;
3676}
3677
3678#ifdef CONFIG_COMPAT
3679static long st_compat_ioctl(struct file *file, unsigned int cmd, unsigned long arg)
3680{
3681 struct scsi_tape *STp = file->private_data;
3682 struct scsi_device *sdev = STp->device;
3683 int ret = -ENOIOCTLCMD;
3684 if (sdev->host->hostt->compat_ioctl) {
3685
3686 ret = sdev->host->hostt->compat_ioctl(sdev, cmd, (void __user *)arg);
3687
3688 }
3689 return ret;
3690}
3691#endif
3692
3693
3694
3695/* Try to allocate a new tape buffer. Calling function must not hold
3696 dev_arr_lock. */
FUJITA Tomonorif409d6c2008-12-18 14:49:47 +09003697static struct st_buffer *new_tape_buffer(int need_dma, int max_sg)
Linus Torvalds1da177e2005-04-16 15:20:36 -07003698{
Linus Torvalds1da177e2005-04-16 15:20:36 -07003699 struct st_buffer *tb;
3700
FUJITA Tomonorif409d6c2008-12-18 14:49:47 +09003701 tb = kzalloc(sizeof(struct st_buffer), GFP_ATOMIC);
Linus Torvalds1da177e2005-04-16 15:20:36 -07003702 if (!tb) {
3703 printk(KERN_NOTICE "st: Can't allocate new tape buffer.\n");
3704 return NULL;
3705 }
FUJITA Tomonori1ac63cf2008-12-18 14:49:48 +09003706 tb->frp_segs = 0;
Linus Torvalds1da177e2005-04-16 15:20:36 -07003707 tb->use_sg = max_sg;
Linus Torvalds1da177e2005-04-16 15:20:36 -07003708 tb->dma = need_dma;
FUJITA Tomonorif409d6c2008-12-18 14:49:47 +09003709 tb->buffer_size = 0;
Linus Torvalds1da177e2005-04-16 15:20:36 -07003710
FUJITA Tomonorif409d6c2008-12-18 14:49:47 +09003711 tb->reserved_pages = kzalloc(max_sg * sizeof(struct page *),
3712 GFP_ATOMIC);
FUJITA Tomonorid0e1ae32008-12-18 14:49:40 +09003713 if (!tb->reserved_pages) {
3714 kfree(tb);
3715 return NULL;
3716 }
3717
Linus Torvalds1da177e2005-04-16 15:20:36 -07003718 return tb;
3719}
3720
3721
3722/* Try to allocate enough space in the tape buffer */
Kai Makisara8f78fc52008-12-18 14:49:51 +09003723#define ST_MAX_ORDER 6
3724
Linus Torvalds1da177e2005-04-16 15:20:36 -07003725static int enlarge_buffer(struct st_buffer * STbuffer, int new_size, int need_dma)
3726{
Al Viroc53033f2005-10-21 03:22:08 -04003727 int segs, nbr, max_segs, b_size, order, got;
3728 gfp_t priority;
Linus Torvalds1da177e2005-04-16 15:20:36 -07003729
3730 if (new_size <= STbuffer->buffer_size)
3731 return 1;
3732
3733 if (STbuffer->buffer_size <= PAGE_SIZE)
3734 normalize_buffer(STbuffer); /* Avoid extra segment */
3735
3736 max_segs = STbuffer->use_sg;
3737 nbr = max_segs - STbuffer->frp_segs;
3738 if (nbr <= 0)
3739 return 0;
3740
3741 priority = GFP_KERNEL | __GFP_NOWARN;
3742 if (need_dma)
3743 priority |= GFP_DMA;
FUJITA Tomonori9c905962008-12-18 14:49:39 +09003744
FUJITA Tomonori08c95832008-12-18 14:49:45 +09003745 if (STbuffer->cleared)
3746 priority |= __GFP_ZERO;
3747
FUJITA Tomonori9c905962008-12-18 14:49:39 +09003748 if (STbuffer->frp_segs) {
FUJITA Tomonoric982c362009-11-26 09:24:13 +09003749 order = STbuffer->reserved_page_order;
FUJITA Tomonori08c95832008-12-18 14:49:45 +09003750 b_size = PAGE_SIZE << order;
FUJITA Tomonori9c905962008-12-18 14:49:39 +09003751 } else {
3752 for (b_size = PAGE_SIZE, order = 0;
FUJITA Tomonori46081b12010-12-20 18:44:45 +02003753 order < ST_MAX_ORDER &&
3754 max_segs * (PAGE_SIZE << order) < new_size;
Kai Makisara8f78fc52008-12-18 14:49:51 +09003755 order++, b_size *= 2)
FUJITA Tomonori9c905962008-12-18 14:49:39 +09003756 ; /* empty */
Kai Makisara373daac2010-12-20 18:43:39 +02003757 STbuffer->reserved_page_order = order;
FUJITA Tomonori9c905962008-12-18 14:49:39 +09003758 }
Kai Makisara8f78fc52008-12-18 14:49:51 +09003759 if (max_segs * (PAGE_SIZE << order) < new_size) {
3760 if (order == ST_MAX_ORDER)
3761 return 0;
3762 normalize_buffer(STbuffer);
3763 return enlarge_buffer(STbuffer, new_size, need_dma);
3764 }
Linus Torvalds1da177e2005-04-16 15:20:36 -07003765
3766 for (segs = STbuffer->frp_segs, got = STbuffer->buffer_size;
3767 segs < max_segs && got < new_size;) {
FUJITA Tomonori08c95832008-12-18 14:49:45 +09003768 struct page *page;
3769
3770 page = alloc_pages(priority, order);
3771 if (!page) {
Linus Torvalds1da177e2005-04-16 15:20:36 -07003772 DEB(STbuffer->buffer_size = got);
3773 normalize_buffer(STbuffer);
3774 return 0;
3775 }
FUJITA Tomonori08c95832008-12-18 14:49:45 +09003776
Linus Torvalds1da177e2005-04-16 15:20:36 -07003777 STbuffer->frp_segs += 1;
3778 got += b_size;
3779 STbuffer->buffer_size = got;
FUJITA Tomonori08c95832008-12-18 14:49:45 +09003780 STbuffer->reserved_pages[segs] = page;
Linus Torvalds1da177e2005-04-16 15:20:36 -07003781 segs++;
3782 }
FUJITA Tomonori08c95832008-12-18 14:49:45 +09003783 STbuffer->b_data = page_address(STbuffer->reserved_pages[0]);
Linus Torvalds1da177e2005-04-16 15:20:36 -07003784
3785 return 1;
3786}
3787
3788
Kai Makisara40f6b362008-02-24 22:23:24 +02003789/* Make sure that no data from previous user is in the internal buffer */
3790static void clear_buffer(struct st_buffer * st_bp)
3791{
3792 int i;
3793
3794 for (i=0; i < st_bp->frp_segs; i++)
FUJITA Tomonori08c95832008-12-18 14:49:45 +09003795 memset(page_address(st_bp->reserved_pages[i]), 0,
FUJITA Tomonoric982c362009-11-26 09:24:13 +09003796 PAGE_SIZE << st_bp->reserved_page_order);
Kai Makisara40f6b362008-02-24 22:23:24 +02003797 st_bp->cleared = 1;
3798}
3799
3800
Linus Torvalds1da177e2005-04-16 15:20:36 -07003801/* Release the extra buffer */
3802static void normalize_buffer(struct st_buffer * STbuffer)
3803{
FUJITA Tomonoric982c362009-11-26 09:24:13 +09003804 int i, order = STbuffer->reserved_page_order;
Linus Torvalds1da177e2005-04-16 15:20:36 -07003805
FUJITA Tomonori1ac63cf2008-12-18 14:49:48 +09003806 for (i = 0; i < STbuffer->frp_segs; i++) {
FUJITA Tomonori08c95832008-12-18 14:49:45 +09003807 __free_pages(STbuffer->reserved_pages[i], order);
3808 STbuffer->buffer_size -= (PAGE_SIZE << order);
Linus Torvalds1da177e2005-04-16 15:20:36 -07003809 }
FUJITA Tomonori1ac63cf2008-12-18 14:49:48 +09003810 STbuffer->frp_segs = 0;
Mike Christie8b05b772005-11-08 04:06:44 -06003811 STbuffer->sg_segs = 0;
FUJITA Tomonoric982c362009-11-26 09:24:13 +09003812 STbuffer->reserved_page_order = 0;
FUJITA Tomonorid0e1ae32008-12-18 14:49:40 +09003813 STbuffer->map_data.offset = 0;
Linus Torvalds1da177e2005-04-16 15:20:36 -07003814}
3815
3816
3817/* Move data from the user buffer to the tape buffer. Returns zero (success) or
3818 negative error code. */
3819static int append_to_buffer(const char __user *ubp, struct st_buffer * st_bp, int do_count)
3820{
3821 int i, cnt, res, offset;
FUJITA Tomonoric982c362009-11-26 09:24:13 +09003822 int length = PAGE_SIZE << st_bp->reserved_page_order;
Linus Torvalds1da177e2005-04-16 15:20:36 -07003823
3824 for (i = 0, offset = st_bp->buffer_bytes;
FUJITA Tomonori08c95832008-12-18 14:49:45 +09003825 i < st_bp->frp_segs && offset >= length; i++)
3826 offset -= length;
Linus Torvalds1da177e2005-04-16 15:20:36 -07003827 if (i == st_bp->frp_segs) { /* Should never happen */
3828 printk(KERN_WARNING "st: append_to_buffer offset overflow.\n");
3829 return (-EIO);
3830 }
3831 for (; i < st_bp->frp_segs && do_count > 0; i++) {
FUJITA Tomonori08c95832008-12-18 14:49:45 +09003832 struct page *page = st_bp->reserved_pages[i];
3833 cnt = length - offset < do_count ? length - offset : do_count;
3834 res = copy_from_user(page_address(page) + offset, ubp, cnt);
Linus Torvalds1da177e2005-04-16 15:20:36 -07003835 if (res)
3836 return (-EFAULT);
3837 do_count -= cnt;
3838 st_bp->buffer_bytes += cnt;
3839 ubp += cnt;
3840 offset = 0;
3841 }
3842 if (do_count) /* Should never happen */
3843 return (-EIO);
3844
3845 return 0;
3846}
3847
3848
3849/* Move data from the tape buffer to the user buffer. Returns zero (success) or
3850 negative error code. */
3851static int from_buffer(struct st_buffer * st_bp, char __user *ubp, int do_count)
3852{
3853 int i, cnt, res, offset;
FUJITA Tomonoric982c362009-11-26 09:24:13 +09003854 int length = PAGE_SIZE << st_bp->reserved_page_order;
Linus Torvalds1da177e2005-04-16 15:20:36 -07003855
3856 for (i = 0, offset = st_bp->read_pointer;
FUJITA Tomonori08c95832008-12-18 14:49:45 +09003857 i < st_bp->frp_segs && offset >= length; i++)
3858 offset -= length;
Linus Torvalds1da177e2005-04-16 15:20:36 -07003859 if (i == st_bp->frp_segs) { /* Should never happen */
3860 printk(KERN_WARNING "st: from_buffer offset overflow.\n");
3861 return (-EIO);
3862 }
3863 for (; i < st_bp->frp_segs && do_count > 0; i++) {
FUJITA Tomonori08c95832008-12-18 14:49:45 +09003864 struct page *page = st_bp->reserved_pages[i];
3865 cnt = length - offset < do_count ? length - offset : do_count;
3866 res = copy_to_user(ubp, page_address(page) + offset, cnt);
Linus Torvalds1da177e2005-04-16 15:20:36 -07003867 if (res)
3868 return (-EFAULT);
3869 do_count -= cnt;
3870 st_bp->buffer_bytes -= cnt;
3871 st_bp->read_pointer += cnt;
3872 ubp += cnt;
3873 offset = 0;
3874 }
3875 if (do_count) /* Should never happen */
3876 return (-EIO);
3877
3878 return 0;
3879}
3880
3881
3882/* Move data towards start of buffer */
3883static void move_buffer_data(struct st_buffer * st_bp, int offset)
3884{
3885 int src_seg, dst_seg, src_offset = 0, dst_offset;
3886 int count, total;
FUJITA Tomonoric982c362009-11-26 09:24:13 +09003887 int length = PAGE_SIZE << st_bp->reserved_page_order;
Linus Torvalds1da177e2005-04-16 15:20:36 -07003888
3889 if (offset == 0)
3890 return;
3891
3892 total=st_bp->buffer_bytes - offset;
3893 for (src_seg=0; src_seg < st_bp->frp_segs; src_seg++) {
3894 src_offset = offset;
FUJITA Tomonori08c95832008-12-18 14:49:45 +09003895 if (src_offset < length)
Linus Torvalds1da177e2005-04-16 15:20:36 -07003896 break;
FUJITA Tomonori08c95832008-12-18 14:49:45 +09003897 offset -= length;
Linus Torvalds1da177e2005-04-16 15:20:36 -07003898 }
3899
3900 st_bp->buffer_bytes = st_bp->read_pointer = total;
3901 for (dst_seg=dst_offset=0; total > 0; ) {
FUJITA Tomonori08c95832008-12-18 14:49:45 +09003902 struct page *dpage = st_bp->reserved_pages[dst_seg];
3903 struct page *spage = st_bp->reserved_pages[src_seg];
3904
3905 count = min(length - dst_offset, length - src_offset);
3906 memmove(page_address(dpage) + dst_offset,
3907 page_address(spage) + src_offset, count);
Linus Torvalds1da177e2005-04-16 15:20:36 -07003908 src_offset += count;
FUJITA Tomonori08c95832008-12-18 14:49:45 +09003909 if (src_offset >= length) {
Linus Torvalds1da177e2005-04-16 15:20:36 -07003910 src_seg++;
3911 src_offset = 0;
3912 }
3913 dst_offset += count;
FUJITA Tomonori08c95832008-12-18 14:49:45 +09003914 if (dst_offset >= length) {
Linus Torvalds1da177e2005-04-16 15:20:36 -07003915 dst_seg++;
3916 dst_offset = 0;
3917 }
3918 total -= count;
3919 }
3920}
3921
Linus Torvalds1da177e2005-04-16 15:20:36 -07003922/* Validate the options from command line or module parameters */
3923static void validate_options(void)
3924{
3925 if (buffer_kbs > 0)
3926 st_fixed_buffer_size = buffer_kbs * ST_KILOBYTE;
3927 if (max_sg_segs >= ST_FIRST_SG)
3928 st_max_sg_segs = max_sg_segs;
3929}
3930
3931#ifndef MODULE
3932/* Set the boot options. Syntax is defined in Documenation/scsi/st.txt.
3933 */
3934static int __init st_setup(char *str)
3935{
3936 int i, len, ints[5];
3937 char *stp;
3938
3939 stp = get_options(str, ARRAY_SIZE(ints), ints);
3940
3941 if (ints[0] > 0) {
3942 for (i = 0; i < ints[0] && i < ARRAY_SIZE(parms); i++)
3943 if (parms[i].val)
3944 *parms[i].val = ints[i + 1];
3945 } else {
3946 while (stp != NULL) {
3947 for (i = 0; i < ARRAY_SIZE(parms); i++) {
3948 len = strlen(parms[i].name);
3949 if (!strncmp(stp, parms[i].name, len) &&
3950 (*(stp + len) == ':' || *(stp + len) == '=')) {
3951 if (parms[i].val)
3952 *parms[i].val =
3953 simple_strtoul(stp + len + 1, NULL, 0);
3954 else
3955 printk(KERN_WARNING "st: Obsolete parameter %s\n",
3956 parms[i].name);
3957 break;
3958 }
3959 }
Tobias Klauser6391a112006-06-08 22:23:48 -07003960 if (i >= ARRAY_SIZE(parms))
Linus Torvalds1da177e2005-04-16 15:20:36 -07003961 printk(KERN_WARNING "st: invalid parameter in '%s'\n",
3962 stp);
3963 stp = strchr(stp, ',');
3964 if (stp)
3965 stp++;
3966 }
3967 }
3968
3969 validate_options();
3970
3971 return 1;
3972}
3973
3974__setup("st=", st_setup);
3975
3976#endif
3977
Arjan van de Ven00977a52007-02-12 00:55:34 -08003978static const struct file_operations st_fops =
Linus Torvalds1da177e2005-04-16 15:20:36 -07003979{
3980 .owner = THIS_MODULE,
3981 .read = st_read,
3982 .write = st_write,
Kai Makisarafd66c1b2008-01-17 22:45:22 +02003983 .unlocked_ioctl = st_ioctl,
Linus Torvalds1da177e2005-04-16 15:20:36 -07003984#ifdef CONFIG_COMPAT
3985 .compat_ioctl = st_compat_ioctl,
3986#endif
3987 .open = st_open,
3988 .flush = st_flush,
3989 .release = st_release,
Jan Blunckb4d878e2010-05-26 14:44:51 -07003990 .llseek = noop_llseek,
Linus Torvalds1da177e2005-04-16 15:20:36 -07003991};
3992
3993static int st_probe(struct device *dev)
3994{
3995 struct scsi_device *SDp = to_scsi_device(dev);
3996 struct gendisk *disk = NULL;
3997 struct cdev *cdev = NULL;
3998 struct scsi_tape *tpnt = NULL;
3999 struct st_modedef *STm;
4000 struct st_partstat *STps;
4001 struct st_buffer *buffer;
4002 int i, j, mode, dev_num, error;
4003 char *stp;
Linus Torvalds1da177e2005-04-16 15:20:36 -07004004
4005 if (SDp->type != TYPE_TAPE)
4006 return -ENODEV;
4007 if ((stp = st_incompatible(SDp))) {
Jeff Garzik3bf743e2005-10-24 18:04:06 -04004008 sdev_printk(KERN_INFO, SDp, "Found incompatible tape\n");
Linus Torvalds1da177e2005-04-16 15:20:36 -07004009 printk(KERN_INFO "st: The suggested driver is %s.\n", stp);
4010 return -ENODEV;
4011 }
4012
Martin K. Petersen8a783622010-02-26 00:20:39 -05004013 i = queue_max_segments(SDp->request_queue);
Linus Torvalds1da177e2005-04-16 15:20:36 -07004014 if (st_max_sg_segs < i)
4015 i = st_max_sg_segs;
FUJITA Tomonorif409d6c2008-12-18 14:49:47 +09004016 buffer = new_tape_buffer((SDp->host)->unchecked_isa_dma, i);
Linus Torvalds1da177e2005-04-16 15:20:36 -07004017 if (buffer == NULL) {
4018 printk(KERN_ERR
4019 "st: Can't allocate new tape buffer. Device not attached.\n");
4020 goto out;
4021 }
4022
4023 disk = alloc_disk(1);
4024 if (!disk) {
4025 printk(KERN_ERR "st: out of memory. Device not attached.\n");
4026 goto out_buffer_free;
4027 }
4028
Jes Sorensen24669f752006-01-16 10:31:18 -05004029 tpnt = kzalloc(sizeof(struct scsi_tape), GFP_ATOMIC);
Linus Torvalds1da177e2005-04-16 15:20:36 -07004030 if (tpnt == NULL) {
Linus Torvalds1da177e2005-04-16 15:20:36 -07004031 printk(KERN_ERR "st: Can't allocate device descriptor.\n");
4032 goto out_put_disk;
4033 }
Kai Makisaraf03a5672005-08-02 13:40:47 +03004034 kref_init(&tpnt->kref);
Linus Torvalds1da177e2005-04-16 15:20:36 -07004035 tpnt->disk = disk;
Linus Torvalds1da177e2005-04-16 15:20:36 -07004036 disk->private_data = &tpnt->driver;
4037 disk->queue = SDp->request_queue;
4038 tpnt->driver = &st_template;
Linus Torvalds1da177e2005-04-16 15:20:36 -07004039
4040 tpnt->device = SDp;
4041 if (SDp->scsi_level <= 2)
4042 tpnt->tape_type = MT_ISSCSI1;
4043 else
4044 tpnt->tape_type = MT_ISSCSI2;
4045
4046 tpnt->buffer = buffer;
Kai Makisaraf03a5672005-08-02 13:40:47 +03004047 tpnt->buffer->last_SRpnt = NULL;
Linus Torvalds1da177e2005-04-16 15:20:36 -07004048
4049 tpnt->inited = 0;
4050 tpnt->dirty = 0;
4051 tpnt->in_use = 0;
4052 tpnt->drv_buffer = 1; /* Try buffering if no mode sense */
4053 tpnt->restr_dma = (SDp->host)->unchecked_isa_dma;
4054 tpnt->use_pf = (SDp->scsi_level >= SCSI_2);
4055 tpnt->density = 0;
4056 tpnt->do_auto_lock = ST_AUTO_LOCK;
4057 tpnt->can_bsr = (SDp->scsi_level > 2 ? 1 : ST_IN_FILE_POS); /* BSR mandatory in SCSI3 */
4058 tpnt->can_partitions = 0;
4059 tpnt->two_fm = ST_TWO_FM;
4060 tpnt->fast_mteom = ST_FAST_MTEOM;
4061 tpnt->scsi2_logical = ST_SCSI2LOGICAL;
Kai Makisara40f6b362008-02-24 22:23:24 +02004062 tpnt->sili = ST_SILI;
Linus Torvalds1da177e2005-04-16 15:20:36 -07004063 tpnt->immediate = ST_NOWAIT;
Lee Duncanc743e442012-03-01 12:41:01 -08004064 tpnt->immediate_filemark = 0;
Linus Torvalds1da177e2005-04-16 15:20:36 -07004065 tpnt->default_drvbuffer = 0xff; /* No forced buffering */
4066 tpnt->partition = 0;
4067 tpnt->new_partition = 0;
4068 tpnt->nbr_partitions = 0;
James Bottomleya02488e2008-11-30 10:36:26 -06004069 blk_queue_rq_timeout(tpnt->device->request_queue, ST_TIMEOUT);
Linus Torvalds1da177e2005-04-16 15:20:36 -07004070 tpnt->long_timeout = ST_LONG_TIMEOUT;
4071 tpnt->try_dio = try_direct_io && !SDp->host->unchecked_isa_dma;
4072
Linus Torvalds1da177e2005-04-16 15:20:36 -07004073 for (i = 0; i < ST_NBR_MODES; i++) {
4074 STm = &(tpnt->modes[i]);
4075 STm->defined = 0;
4076 STm->sysv = ST_SYSV;
4077 STm->defaults_for_writes = 0;
4078 STm->do_async_writes = ST_ASYNC_WRITES;
4079 STm->do_buffer_writes = ST_BUFFER_WRITES;
4080 STm->do_read_ahead = ST_READ_AHEAD;
4081 STm->default_compression = ST_DONT_TOUCH;
4082 STm->default_blksize = (-1); /* No forced size */
4083 STm->default_density = (-1); /* No forced density */
Jeff Mahoney6c648d92012-08-18 15:20:39 -04004084 STm->tape = tpnt;
Linus Torvalds1da177e2005-04-16 15:20:36 -07004085 }
4086
4087 for (i = 0; i < ST_NBR_PARTITIONS; i++) {
4088 STps = &(tpnt->ps[i]);
4089 STps->rw = ST_IDLE;
4090 STps->eof = ST_NOEOF;
4091 STps->at_sm = 0;
4092 STps->last_block_valid = 0;
4093 STps->drv_block = (-1);
4094 STps->drv_file = (-1);
4095 }
4096
4097 tpnt->current_mode = 0;
4098 tpnt->modes[0].defined = 1;
4099
4100 tpnt->density_changed = tpnt->compression_changed =
4101 tpnt->blksize_changed = 0;
Matthias Kaehlcke28f85002007-07-29 23:38:15 +02004102 mutex_init(&tpnt->lock);
Linus Torvalds1da177e2005-04-16 15:20:36 -07004103
Jeff Mahoney6c648d92012-08-18 15:20:39 -04004104 if (!idr_pre_get(&st_index_idr, GFP_KERNEL)) {
4105 pr_warn("st: idr expansion failed\n");
4106 error = -ENOMEM;
4107 goto out_put_disk;
4108 }
4109
4110 spin_lock(&st_index_lock);
4111 error = idr_get_new(&st_index_idr, tpnt, &dev_num);
4112 spin_unlock(&st_index_lock);
4113 if (error) {
4114 pr_warn("st: idr allocation failed: %d\n", error);
4115 goto out_put_disk;
4116 }
4117
4118 if (dev_num > ST_MAX_TAPES) {
4119 pr_err("st: Too many tape devices (max. %d).\n", ST_MAX_TAPES);
4120 goto out_put_index;
4121 }
4122
4123 tpnt->index = dev_num;
4124 sprintf(disk->disk_name, "st%d", dev_num);
4125
4126 dev_set_drvdata(dev, tpnt);
Linus Torvalds1da177e2005-04-16 15:20:36 -07004127
4128 for (mode = 0; mode < ST_NBR_MODES; ++mode) {
4129 STm = &(tpnt->modes[mode]);
4130 for (j=0; j < 2; j++) {
4131 cdev = cdev_alloc();
4132 if (!cdev) {
4133 printk(KERN_ERR
4134 "st%d: out of memory. Device not attached.\n",
4135 dev_num);
Jeff Mahoneye3f2a9c2012-08-18 15:20:38 -04004136 cdev_del(cdev);
Linus Torvalds1da177e2005-04-16 15:20:36 -07004137 goto out_free_tape;
4138 }
4139 cdev->owner = THIS_MODULE;
4140 cdev->ops = &st_fops;
4141
4142 error = cdev_add(cdev,
4143 MKDEV(SCSI_TAPE_MAJOR, TAPE_MINOR(dev_num, mode, j)),
4144 1);
4145 if (error) {
4146 printk(KERN_ERR "st%d: Can't add %s-rewind mode %d\n",
4147 dev_num, j ? "non" : "auto", mode);
4148 printk(KERN_ERR "st%d: Device not attached.\n", dev_num);
4149 goto out_free_tape;
4150 }
4151 STm->cdevs[j] = cdev;
4152
4153 }
Jeff Garzik13026a62006-10-04 06:00:38 -04004154 error = do_create_class_files(tpnt, dev_num, mode);
4155 if (error)
4156 goto out_free_tape;
Linus Torvalds1da177e2005-04-16 15:20:36 -07004157 }
Oliver Neukum46a243f2012-01-15 00:16:51 +01004158 scsi_autopm_put_device(SDp);
Linus Torvalds1da177e2005-04-16 15:20:36 -07004159
Kai Makisara422528542006-11-07 21:56:38 +02004160 sdev_printk(KERN_NOTICE, SDp,
Rene Herman8b1ea242006-05-20 15:00:22 -07004161 "Attached scsi tape %s\n", tape_name(tpnt));
Kai Makisara422528542006-11-07 21:56:38 +02004162 sdev_printk(KERN_INFO, SDp, "%s: try direct i/o: %s (alignment %d B)\n",
4163 tape_name(tpnt), tpnt->try_dio ? "yes" : "no",
4164 queue_dma_alignment(SDp->request_queue) + 1);
Linus Torvalds1da177e2005-04-16 15:20:36 -07004165
4166 return 0;
4167
4168out_free_tape:
Jeff Mahoney6c648d92012-08-18 15:20:39 -04004169 sysfs_remove_link(&tpnt->device->sdev_gendev.kobj,
4170 "tape");
Linus Torvalds1da177e2005-04-16 15:20:36 -07004171 for (mode=0; mode < ST_NBR_MODES; mode++) {
4172 STm = &(tpnt->modes[mode]);
Linus Torvalds1da177e2005-04-16 15:20:36 -07004173 for (j=0; j < 2; j++) {
4174 if (STm->cdevs[j]) {
Jeff Mahoneye3f2a9c2012-08-18 15:20:38 -04004175 device_destroy(&st_sysfs_class,
4176 MKDEV(SCSI_TAPE_MAJOR,
4177 TAPE_MINOR(i, mode, j)));
Linus Torvalds1da177e2005-04-16 15:20:36 -07004178 cdev_del(STm->cdevs[j]);
4179 }
4180 }
4181 }
Jeff Mahoney6c648d92012-08-18 15:20:39 -04004182out_put_index:
4183 spin_lock(&st_index_lock);
4184 idr_remove(&st_index_idr, dev_num);
4185 spin_unlock(&st_index_lock);
Linus Torvalds1da177e2005-04-16 15:20:36 -07004186out_put_disk:
4187 put_disk(disk);
Jesper Juhlc9475cb2005-11-07 01:01:26 -08004188 kfree(tpnt);
Linus Torvalds1da177e2005-04-16 15:20:36 -07004189out_buffer_free:
4190 kfree(buffer);
4191out:
4192 return -ENODEV;
4193};
4194
4195
4196static int st_remove(struct device *dev)
4197{
Jeff Mahoney6c648d92012-08-18 15:20:39 -04004198 struct scsi_tape *tpnt = dev_get_drvdata(dev);
4199 int rew, mode;
4200 dev_t cdev_devno;
4201 struct cdev *cdev;
4202 int index = tpnt->index;
Linus Torvalds1da177e2005-04-16 15:20:36 -07004203
Jeff Mahoney6c648d92012-08-18 15:20:39 -04004204 scsi_autopm_get_device(to_scsi_device(dev));
4205 sysfs_remove_link(&tpnt->device->sdev_gendev.kobj, "tape");
4206 for (mode = 0; mode < ST_NBR_MODES; ++mode) {
4207 for (rew = 0; rew < 2; rew++) {
4208 cdev = tpnt->modes[mode].cdevs[rew];
4209 if (!cdev)
4210 continue;
4211 cdev_devno = cdev->dev;
4212 device_destroy(&st_sysfs_class, cdev_devno);
4213 cdev_del(tpnt->modes[mode].cdevs[rew]);
4214 tpnt->modes[mode].cdevs[rew] = NULL;
Linus Torvalds1da177e2005-04-16 15:20:36 -07004215 }
4216 }
4217
Jeff Mahoney6c648d92012-08-18 15:20:39 -04004218 mutex_lock(&st_ref_mutex);
4219 kref_put(&tpnt->kref, scsi_tape_release);
4220 mutex_unlock(&st_ref_mutex);
4221 spin_lock(&st_index_lock);
4222 idr_remove(&st_index_idr, index);
4223 spin_unlock(&st_index_lock);
Linus Torvalds1da177e2005-04-16 15:20:36 -07004224 return 0;
4225}
4226
Kai Makisaraf03a5672005-08-02 13:40:47 +03004227/**
4228 * scsi_tape_release - Called to free the Scsi_Tape structure
4229 * @kref: pointer to embedded kref
4230 *
Arjan van de Ven0b950672006-01-11 13:16:10 +01004231 * st_ref_mutex must be held entering this routine. Because it is
Kai Makisaraf03a5672005-08-02 13:40:47 +03004232 * called on last put, you should always use the scsi_tape_get()
4233 * scsi_tape_put() helpers which manipulate the semaphore directly
4234 * and never do a direct kref_put().
4235 **/
4236static void scsi_tape_release(struct kref *kref)
4237{
4238 struct scsi_tape *tpnt = to_scsi_tape(kref);
4239 struct gendisk *disk = tpnt->disk;
4240
4241 tpnt->device = NULL;
4242
4243 if (tpnt->buffer) {
Kai Makisaraf03a5672005-08-02 13:40:47 +03004244 normalize_buffer(tpnt->buffer);
FUJITA Tomonorid0e1ae32008-12-18 14:49:40 +09004245 kfree(tpnt->buffer->reserved_pages);
Kai Makisaraf03a5672005-08-02 13:40:47 +03004246 kfree(tpnt->buffer);
4247 }
4248
4249 disk->private_data = NULL;
4250 put_disk(disk);
4251 kfree(tpnt);
4252 return;
4253}
4254
Jeff Mahoneyaf237822012-08-18 15:20:37 -04004255static struct class st_sysfs_class = {
4256 .name = "scsi_tape",
4257 .dev_attrs = st_dev_attrs,
4258};
4259
Linus Torvalds1da177e2005-04-16 15:20:36 -07004260static int __init init_st(void)
4261{
Jeff Garzik13026a62006-10-04 06:00:38 -04004262 int err;
4263
Linus Torvalds1da177e2005-04-16 15:20:36 -07004264 validate_options();
4265
Jeff Garzik13026a62006-10-04 06:00:38 -04004266 printk(KERN_INFO "st: Version %s, fixed bufsize %d, s/g segs %d\n",
Linus Torvalds1da177e2005-04-16 15:20:36 -07004267 verstr, st_fixed_buffer_size, st_max_sg_segs);
4268
Jeff Mahoneyaf237822012-08-18 15:20:37 -04004269 err = class_register(&st_sysfs_class);
4270 if (err) {
4271 pr_err("Unable register sysfs class for SCSI tapes\n");
4272 return err;
Linus Torvalds1da177e2005-04-16 15:20:36 -07004273 }
4274
Jeff Garzik13026a62006-10-04 06:00:38 -04004275 err = register_chrdev_region(MKDEV(SCSI_TAPE_MAJOR, 0),
4276 ST_MAX_TAPE_ENTRIES, "st");
4277 if (err) {
4278 printk(KERN_ERR "Unable to get major %d for SCSI tapes\n",
4279 SCSI_TAPE_MAJOR);
4280 goto err_class;
Linus Torvalds1da177e2005-04-16 15:20:36 -07004281 }
Jeff Garzik13026a62006-10-04 06:00:38 -04004282
4283 err = scsi_register_driver(&st_template.gendrv);
4284 if (err)
4285 goto err_chrdev;
4286
Robert P. J. Day405ae7d2007-02-17 19:13:42 +01004287 err = do_create_sysfs_files();
Jeff Garzik13026a62006-10-04 06:00:38 -04004288 if (err)
4289 goto err_scsidrv;
4290
4291 return 0;
4292
4293err_scsidrv:
4294 scsi_unregister_driver(&st_template.gendrv);
4295err_chrdev:
4296 unregister_chrdev_region(MKDEV(SCSI_TAPE_MAJOR, 0),
4297 ST_MAX_TAPE_ENTRIES);
4298err_class:
Jeff Mahoneyaf237822012-08-18 15:20:37 -04004299 class_unregister(&st_sysfs_class);
Jeff Garzik13026a62006-10-04 06:00:38 -04004300 return err;
Linus Torvalds1da177e2005-04-16 15:20:36 -07004301}
4302
4303static void __exit exit_st(void)
4304{
Robert P. J. Day405ae7d2007-02-17 19:13:42 +01004305 do_remove_sysfs_files();
Linus Torvalds1da177e2005-04-16 15:20:36 -07004306 scsi_unregister_driver(&st_template.gendrv);
4307 unregister_chrdev_region(MKDEV(SCSI_TAPE_MAJOR, 0),
4308 ST_MAX_TAPE_ENTRIES);
Jeff Mahoneyaf237822012-08-18 15:20:37 -04004309 class_unregister(&st_sysfs_class);
Linus Torvalds1da177e2005-04-16 15:20:36 -07004310 printk(KERN_INFO "st: Unloaded.\n");
4311}
4312
4313module_init(init_st);
4314module_exit(exit_st);
4315
4316
4317/* The sysfs driver interface. Read-only at the moment */
4318static ssize_t st_try_direct_io_show(struct device_driver *ddp, char *buf)
4319{
4320 return snprintf(buf, PAGE_SIZE, "%d\n", try_direct_io);
4321}
4322static DRIVER_ATTR(try_direct_io, S_IRUGO, st_try_direct_io_show, NULL);
4323
4324static ssize_t st_fixed_buffer_size_show(struct device_driver *ddp, char *buf)
4325{
4326 return snprintf(buf, PAGE_SIZE, "%d\n", st_fixed_buffer_size);
4327}
4328static DRIVER_ATTR(fixed_buffer_size, S_IRUGO, st_fixed_buffer_size_show, NULL);
4329
4330static ssize_t st_max_sg_segs_show(struct device_driver *ddp, char *buf)
4331{
4332 return snprintf(buf, PAGE_SIZE, "%d\n", st_max_sg_segs);
4333}
4334static DRIVER_ATTR(max_sg_segs, S_IRUGO, st_max_sg_segs_show, NULL);
4335
4336static ssize_t st_version_show(struct device_driver *ddd, char *buf)
4337{
4338 return snprintf(buf, PAGE_SIZE, "[%s]\n", verstr);
4339}
4340static DRIVER_ATTR(version, S_IRUGO, st_version_show, NULL);
4341
Robert P. J. Day405ae7d2007-02-17 19:13:42 +01004342static int do_create_sysfs_files(void)
Linus Torvalds1da177e2005-04-16 15:20:36 -07004343{
Robert P. J. Day405ae7d2007-02-17 19:13:42 +01004344 struct device_driver *sysfs = &st_template.gendrv;
Jeff Garzik13026a62006-10-04 06:00:38 -04004345 int err;
Linus Torvalds1da177e2005-04-16 15:20:36 -07004346
Robert P. J. Day405ae7d2007-02-17 19:13:42 +01004347 err = driver_create_file(sysfs, &driver_attr_try_direct_io);
Jeff Garzik13026a62006-10-04 06:00:38 -04004348 if (err)
4349 return err;
Robert P. J. Day405ae7d2007-02-17 19:13:42 +01004350 err = driver_create_file(sysfs, &driver_attr_fixed_buffer_size);
Jeff Garzik13026a62006-10-04 06:00:38 -04004351 if (err)
4352 goto err_try_direct_io;
Robert P. J. Day405ae7d2007-02-17 19:13:42 +01004353 err = driver_create_file(sysfs, &driver_attr_max_sg_segs);
Jeff Garzik13026a62006-10-04 06:00:38 -04004354 if (err)
4355 goto err_attr_fixed_buf;
Robert P. J. Day405ae7d2007-02-17 19:13:42 +01004356 err = driver_create_file(sysfs, &driver_attr_version);
Jeff Garzik13026a62006-10-04 06:00:38 -04004357 if (err)
4358 goto err_attr_max_sg;
4359
4360 return 0;
4361
4362err_attr_max_sg:
Robert P. J. Day405ae7d2007-02-17 19:13:42 +01004363 driver_remove_file(sysfs, &driver_attr_max_sg_segs);
Jeff Garzik13026a62006-10-04 06:00:38 -04004364err_attr_fixed_buf:
Robert P. J. Day405ae7d2007-02-17 19:13:42 +01004365 driver_remove_file(sysfs, &driver_attr_fixed_buffer_size);
Jeff Garzik13026a62006-10-04 06:00:38 -04004366err_try_direct_io:
Robert P. J. Day405ae7d2007-02-17 19:13:42 +01004367 driver_remove_file(sysfs, &driver_attr_try_direct_io);
Jeff Garzik13026a62006-10-04 06:00:38 -04004368 return err;
Linus Torvalds1da177e2005-04-16 15:20:36 -07004369}
4370
Robert P. J. Day405ae7d2007-02-17 19:13:42 +01004371static void do_remove_sysfs_files(void)
Linus Torvalds1da177e2005-04-16 15:20:36 -07004372{
Robert P. J. Day405ae7d2007-02-17 19:13:42 +01004373 struct device_driver *sysfs = &st_template.gendrv;
Linus Torvalds1da177e2005-04-16 15:20:36 -07004374
Robert P. J. Day405ae7d2007-02-17 19:13:42 +01004375 driver_remove_file(sysfs, &driver_attr_version);
4376 driver_remove_file(sysfs, &driver_attr_max_sg_segs);
4377 driver_remove_file(sysfs, &driver_attr_fixed_buffer_size);
4378 driver_remove_file(sysfs, &driver_attr_try_direct_io);
Linus Torvalds1da177e2005-04-16 15:20:36 -07004379}
4380
Linus Torvalds1da177e2005-04-16 15:20:36 -07004381/* The sysfs simple class interface */
Tony Jonesee959b02008-02-22 00:13:36 +01004382static ssize_t
Jeff Mahoneyaf237822012-08-18 15:20:37 -04004383defined_show(struct device *dev, struct device_attribute *attr, char *buf)
Linus Torvalds1da177e2005-04-16 15:20:36 -07004384{
James Bottomley7d15d6a2008-03-14 14:12:43 -07004385 struct st_modedef *STm = dev_get_drvdata(dev);
Linus Torvalds1da177e2005-04-16 15:20:36 -07004386 ssize_t l = 0;
4387
4388 l = snprintf(buf, PAGE_SIZE, "%d\n", STm->defined);
4389 return l;
4390}
4391
Tony Jonesee959b02008-02-22 00:13:36 +01004392static ssize_t
Jeff Mahoneyaf237822012-08-18 15:20:37 -04004393default_blksize_show(struct device *dev, struct device_attribute *attr,
4394 char *buf)
Linus Torvalds1da177e2005-04-16 15:20:36 -07004395{
James Bottomley7d15d6a2008-03-14 14:12:43 -07004396 struct st_modedef *STm = dev_get_drvdata(dev);
Linus Torvalds1da177e2005-04-16 15:20:36 -07004397 ssize_t l = 0;
4398
4399 l = snprintf(buf, PAGE_SIZE, "%d\n", STm->default_blksize);
4400 return l;
4401}
4402
Linus Torvalds1da177e2005-04-16 15:20:36 -07004403
Tony Jonesee959b02008-02-22 00:13:36 +01004404static ssize_t
Jeff Mahoneyaf237822012-08-18 15:20:37 -04004405default_density_show(struct device *dev, struct device_attribute *attr,
4406 char *buf)
Linus Torvalds1da177e2005-04-16 15:20:36 -07004407{
James Bottomley7d15d6a2008-03-14 14:12:43 -07004408 struct st_modedef *STm = dev_get_drvdata(dev);
Linus Torvalds1da177e2005-04-16 15:20:36 -07004409 ssize_t l = 0;
4410 char *fmt;
4411
4412 fmt = STm->default_density >= 0 ? "0x%02x\n" : "%d\n";
4413 l = snprintf(buf, PAGE_SIZE, fmt, STm->default_density);
4414 return l;
4415}
4416
Tony Jonesee959b02008-02-22 00:13:36 +01004417static ssize_t
Jeff Mahoneyaf237822012-08-18 15:20:37 -04004418default_compression_show(struct device *dev, struct device_attribute *attr,
4419 char *buf)
Linus Torvalds1da177e2005-04-16 15:20:36 -07004420{
James Bottomley7d15d6a2008-03-14 14:12:43 -07004421 struct st_modedef *STm = dev_get_drvdata(dev);
Linus Torvalds1da177e2005-04-16 15:20:36 -07004422 ssize_t l = 0;
4423
4424 l = snprintf(buf, PAGE_SIZE, "%d\n", STm->default_compression - 1);
4425 return l;
4426}
4427
Tony Jonesee959b02008-02-22 00:13:36 +01004428static ssize_t
Jeff Mahoneyaf237822012-08-18 15:20:37 -04004429options_show(struct device *dev, struct device_attribute *attr, char *buf)
Kai Makisarab174be02008-02-24 22:29:12 +02004430{
James Bottomley7d15d6a2008-03-14 14:12:43 -07004431 struct st_modedef *STm = dev_get_drvdata(dev);
Jeff Mahoney6c648d92012-08-18 15:20:39 -04004432 struct scsi_tape *STp = STm->tape;
4433 int options;
Kai Makisarab174be02008-02-24 22:29:12 +02004434 ssize_t l = 0;
4435
Kai Makisarab174be02008-02-24 22:29:12 +02004436 options = STm->do_buffer_writes ? MT_ST_BUFFER_WRITES : 0;
4437 options |= STm->do_async_writes ? MT_ST_ASYNC_WRITES : 0;
4438 options |= STm->do_read_ahead ? MT_ST_READ_AHEAD : 0;
4439 DEB( options |= debugging ? MT_ST_DEBUGGING : 0 );
4440 options |= STp->two_fm ? MT_ST_TWO_FM : 0;
4441 options |= STp->fast_mteom ? MT_ST_FAST_MTEOM : 0;
4442 options |= STm->defaults_for_writes ? MT_ST_DEF_WRITES : 0;
4443 options |= STp->can_bsr ? MT_ST_CAN_BSR : 0;
4444 options |= STp->omit_blklims ? MT_ST_NO_BLKLIMS : 0;
4445 options |= STp->can_partitions ? MT_ST_CAN_PARTITIONS : 0;
4446 options |= STp->scsi2_logical ? MT_ST_SCSI2LOGICAL : 0;
4447 options |= STm->sysv ? MT_ST_SYSV : 0;
4448 options |= STp->immediate ? MT_ST_NOWAIT : 0;
Lee Duncanc743e442012-03-01 12:41:01 -08004449 options |= STp->immediate_filemark ? MT_ST_NOWAIT_EOF : 0;
Kai Makisarab174be02008-02-24 22:29:12 +02004450 options |= STp->sili ? MT_ST_SILI : 0;
4451
4452 l = snprintf(buf, PAGE_SIZE, "0x%08x\n", options);
4453 return l;
4454}
4455
Jeff Mahoneyaf237822012-08-18 15:20:37 -04004456static struct device_attribute st_dev_attrs[] = {
4457 __ATTR_RO(defined),
4458 __ATTR_RO(default_blksize),
4459 __ATTR_RO(default_density),
4460 __ATTR_RO(default_compression),
4461 __ATTR_RO(options),
4462 __ATTR_NULL,
4463};
Kai Makisarab174be02008-02-24 22:29:12 +02004464
Jeff Garzik13026a62006-10-04 06:00:38 -04004465static int do_create_class_files(struct scsi_tape *STp, int dev_num, int mode)
Linus Torvalds1da177e2005-04-16 15:20:36 -07004466{
4467 int i, rew, error;
4468 char name[10];
Tony Jonesee959b02008-02-22 00:13:36 +01004469 struct device *st_class_member;
Linus Torvalds1da177e2005-04-16 15:20:36 -07004470
Linus Torvalds1da177e2005-04-16 15:20:36 -07004471 for (rew=0; rew < 2; rew++) {
4472 /* Make sure that the minor numbers corresponding to the four
4473 first modes always get the same names */
4474 i = mode << (4 - ST_NBR_MODE_BITS);
4475 snprintf(name, 10, "%s%s%s", rew ? "n" : "",
4476 STp->disk->disk_name, st_formats[i]);
4477 st_class_member =
Jeff Mahoneyaf237822012-08-18 15:20:37 -04004478 device_create(&st_sysfs_class,
4479 &STp->device->sdev_gendev,
Greg Kroah-Hartmand73a1a672008-07-21 20:03:34 -07004480 MKDEV(SCSI_TAPE_MAJOR,
4481 TAPE_MINOR(dev_num, mode, rew)),
4482 &STp->modes[mode], "%s", name);
Linus Torvalds1da177e2005-04-16 15:20:36 -07004483 if (IS_ERR(st_class_member)) {
Tony Jonesee959b02008-02-22 00:13:36 +01004484 printk(KERN_WARNING "st%d: device_create failed\n",
Linus Torvalds1da177e2005-04-16 15:20:36 -07004485 dev_num);
Jeff Garzik13026a62006-10-04 06:00:38 -04004486 error = PTR_ERR(st_class_member);
Linus Torvalds1da177e2005-04-16 15:20:36 -07004487 goto out;
4488 }
Linus Torvalds1da177e2005-04-16 15:20:36 -07004489
Linus Torvalds1da177e2005-04-16 15:20:36 -07004490 if (mode == 0 && rew == 0) {
4491 error = sysfs_create_link(&STp->device->sdev_gendev.kobj,
4492 &st_class_member->kobj,
4493 "tape");
4494 if (error) {
4495 printk(KERN_ERR
4496 "st%d: Can't create sysfs link from SCSI device.\n",
4497 dev_num);
Jeff Garzik13026a62006-10-04 06:00:38 -04004498 goto out;
Linus Torvalds1da177e2005-04-16 15:20:36 -07004499 }
4500 }
4501 }
Jeff Garzik13026a62006-10-04 06:00:38 -04004502
4503 return 0;
4504
4505out:
4506 return error;
Linus Torvalds1da177e2005-04-16 15:20:36 -07004507}
4508
Linus Torvalds1da177e2005-04-16 15:20:36 -07004509/* The following functions may be useful for a larger audience. */
FUJITA Tomonori66207422008-12-18 14:49:43 +09004510static int sgl_map_user_pages(struct st_buffer *STbp,
4511 const unsigned int max_pages, unsigned long uaddr,
4512 size_t count, int rw)
Linus Torvalds1da177e2005-04-16 15:20:36 -07004513{
James Bottomley07542b82005-08-31 20:27:22 -04004514 unsigned long end = (uaddr + count + PAGE_SIZE - 1) >> PAGE_SHIFT;
4515 unsigned long start = uaddr >> PAGE_SHIFT;
4516 const int nr_pages = end - start;
Linus Torvalds1da177e2005-04-16 15:20:36 -07004517 int res, i, j;
Linus Torvalds1da177e2005-04-16 15:20:36 -07004518 struct page **pages;
FUJITA Tomonori66207422008-12-18 14:49:43 +09004519 struct rq_map_data *mdata = &STbp->map_data;
Linus Torvalds1da177e2005-04-16 15:20:36 -07004520
Linus Torvalds1da177e2005-04-16 15:20:36 -07004521 /* User attempted Overflow! */
4522 if ((uaddr + count) < uaddr)
4523 return -EINVAL;
4524
4525 /* Too big */
4526 if (nr_pages > max_pages)
4527 return -ENOMEM;
4528
4529 /* Hmm? */
4530 if (count == 0)
4531 return 0;
4532
4533 if ((pages = kmalloc(max_pages * sizeof(*pages), GFP_KERNEL)) == NULL)
4534 return -ENOMEM;
4535
4536 /* Try to fault in all of the necessary pages */
4537 down_read(&current->mm->mmap_sem);
4538 /* rw==READ means read from drive, write into memory area */
4539 res = get_user_pages(
4540 current,
4541 current->mm,
4542 uaddr,
4543 nr_pages,
4544 rw == READ,
4545 0, /* don't force */
4546 pages,
4547 NULL);
4548 up_read(&current->mm->mmap_sem);
4549
4550 /* Errors and no page mapped should return here */
4551 if (res < nr_pages)
4552 goto out_unmap;
4553
4554 for (i=0; i < nr_pages; i++) {
4555 /* FIXME: flush superflous for rw==READ,
4556 * probably wrong function for rw==WRITE
4557 */
4558 flush_dcache_page(pages[i]);
4559 }
4560
FUJITA Tomonori66207422008-12-18 14:49:43 +09004561 mdata->offset = uaddr & ~PAGE_MASK;
FUJITA Tomonori66207422008-12-18 14:49:43 +09004562 STbp->mapped_pages = pages;
Linus Torvalds1da177e2005-04-16 15:20:36 -07004563
Linus Torvalds1da177e2005-04-16 15:20:36 -07004564 return nr_pages;
Linus Torvalds1da177e2005-04-16 15:20:36 -07004565 out_unmap:
4566 if (res > 0) {
4567 for (j=0; j < res; j++)
4568 page_cache_release(pages[j]);
Hugh Dickins6bc733e2005-12-01 20:21:57 +00004569 res = 0;
Linus Torvalds1da177e2005-04-16 15:20:36 -07004570 }
4571 kfree(pages);
4572 return res;
4573}
4574
4575
4576/* And unmap them... */
FUJITA Tomonori66207422008-12-18 14:49:43 +09004577static int sgl_unmap_user_pages(struct st_buffer *STbp,
4578 const unsigned int nr_pages, int dirtied)
Linus Torvalds1da177e2005-04-16 15:20:36 -07004579{
4580 int i;
4581
4582 for (i=0; i < nr_pages; i++) {
FUJITA Tomonori66207422008-12-18 14:49:43 +09004583 struct page *page = STbp->mapped_pages[i];
Nick Pigginb5810032005-10-29 18:16:12 -07004584
Nick Pigginb5810032005-10-29 18:16:12 -07004585 if (dirtied)
4586 SetPageDirty(page);
Linus Torvalds1da177e2005-04-16 15:20:36 -07004587 /* FIXME: cache flush missing for rw==READ
4588 * FIXME: call the correct reference counting function
4589 */
Nick Pigginb5810032005-10-29 18:16:12 -07004590 page_cache_release(page);
Linus Torvalds1da177e2005-04-16 15:20:36 -07004591 }
FUJITA Tomonori66207422008-12-18 14:49:43 +09004592 kfree(STbp->mapped_pages);
4593 STbp->mapped_pages = NULL;
Linus Torvalds1da177e2005-04-16 15:20:36 -07004594
4595 return 0;
4596}