blob: ceca095e5d8d5a00ea66aa14e7200c3a2a65ebbc [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);
Linus Torvalds1da177e2005-04-16 15:20:36 -0700196
197static struct scsi_driver st_template = {
198 .owner = THIS_MODULE,
199 .gendrv = {
200 .name = "st",
201 .probe = st_probe,
202 .remove = st_remove,
203 },
Linus Torvalds1da177e2005-04-16 15:20:36 -0700204};
205
206static int st_compression(struct scsi_tape *, int);
207
208static int find_partition(struct scsi_tape *);
209static int switch_partition(struct scsi_tape *);
210
211static int st_int_ioctl(struct scsi_tape *, unsigned int, unsigned long);
212
Kai Makisaraf03a5672005-08-02 13:40:47 +0300213static void scsi_tape_release(struct kref *);
214
215#define to_scsi_tape(obj) container_of(obj, struct scsi_tape, kref)
216
Arjan van de Ven0b950672006-01-11 13:16:10 +0100217static DEFINE_MUTEX(st_ref_mutex);
Jeff Mahoney6c648d92012-08-18 15:20:39 -0400218static DEFINE_SPINLOCK(st_index_lock);
219static DEFINE_SPINLOCK(st_use_lock);
220static DEFINE_IDR(st_index_idr);
221
Kai Makisaraf03a5672005-08-02 13:40:47 +0300222
Linus Torvalds1da177e2005-04-16 15:20:36 -0700223
224#include "osst_detect.h"
225#ifndef SIGS_FROM_OSST
226#define SIGS_FROM_OSST \
227 {"OnStream", "SC-", "", "osst"}, \
228 {"OnStream", "DI-", "", "osst"}, \
229 {"OnStream", "DP-", "", "osst"}, \
230 {"OnStream", "USB", "", "osst"}, \
231 {"OnStream", "FW-", "", "osst"}
232#endif
233
Kai Makisaraf03a5672005-08-02 13:40:47 +0300234static struct scsi_tape *scsi_tape_get(int dev)
235{
236 struct scsi_tape *STp = NULL;
237
Arjan van de Ven0b950672006-01-11 13:16:10 +0100238 mutex_lock(&st_ref_mutex);
Jeff Mahoney6c648d92012-08-18 15:20:39 -0400239 spin_lock(&st_index_lock);
Kai Makisaraf03a5672005-08-02 13:40:47 +0300240
Jeff Mahoney6c648d92012-08-18 15:20:39 -0400241 STp = idr_find(&st_index_idr, dev);
Kai Makisaraf03a5672005-08-02 13:40:47 +0300242 if (!STp) goto out;
243
244 kref_get(&STp->kref);
245
246 if (!STp->device)
247 goto out_put;
248
249 if (scsi_device_get(STp->device))
250 goto out_put;
251
252 goto out;
253
254out_put:
255 kref_put(&STp->kref, scsi_tape_release);
256 STp = NULL;
257out:
Jeff Mahoney6c648d92012-08-18 15:20:39 -0400258 spin_unlock(&st_index_lock);
Arjan van de Ven0b950672006-01-11 13:16:10 +0100259 mutex_unlock(&st_ref_mutex);
Kai Makisaraf03a5672005-08-02 13:40:47 +0300260 return STp;
261}
262
263static void scsi_tape_put(struct scsi_tape *STp)
264{
265 struct scsi_device *sdev = STp->device;
266
Arjan van de Ven0b950672006-01-11 13:16:10 +0100267 mutex_lock(&st_ref_mutex);
Kai Makisaraf03a5672005-08-02 13:40:47 +0300268 kref_put(&STp->kref, scsi_tape_release);
269 scsi_device_put(sdev);
Arjan van de Ven0b950672006-01-11 13:16:10 +0100270 mutex_unlock(&st_ref_mutex);
Kai Makisaraf03a5672005-08-02 13:40:47 +0300271}
272
Linus Torvalds1da177e2005-04-16 15:20:36 -0700273struct st_reject_data {
274 char *vendor;
275 char *model;
276 char *rev;
277 char *driver_hint; /* Name of the correct driver, NULL if unknown */
278};
279
280static struct st_reject_data reject_list[] = {
281 /* {"XXX", "Yy-", "", NULL}, example */
282 SIGS_FROM_OSST,
283 {NULL, }};
284
285/* If the device signature is on the list of incompatible drives, the
286 function returns a pointer to the name of the correct driver (if known) */
287static char * st_incompatible(struct scsi_device* SDp)
288{
289 struct st_reject_data *rp;
290
291 for (rp=&(reject_list[0]); rp->vendor != NULL; rp++)
292 if (!strncmp(rp->vendor, SDp->vendor, strlen(rp->vendor)) &&
293 !strncmp(rp->model, SDp->model, strlen(rp->model)) &&
294 !strncmp(rp->rev, SDp->rev, strlen(rp->rev))) {
295 if (rp->driver_hint)
296 return rp->driver_hint;
297 else
298 return "unknown";
299 }
300 return NULL;
301}
302
303
304static inline char *tape_name(struct scsi_tape *tape)
305{
306 return tape->disk->disk_name;
307}
308
309
Mike Christie8b05b772005-11-08 04:06:44 -0600310static void st_analyze_sense(struct st_request *SRpnt, struct st_cmdstatus *s)
Linus Torvalds1da177e2005-04-16 15:20:36 -0700311{
312 const u8 *ucp;
Mike Christie8b05b772005-11-08 04:06:44 -0600313 const u8 *sense = SRpnt->sense;
Linus Torvalds1da177e2005-04-16 15:20:36 -0700314
Mike Christie8b05b772005-11-08 04:06:44 -0600315 s->have_sense = scsi_normalize_sense(SRpnt->sense,
316 SCSI_SENSE_BUFFERSIZE, &s->sense_hdr);
Linus Torvalds1da177e2005-04-16 15:20:36 -0700317 s->flags = 0;
318
319 if (s->have_sense) {
320 s->deferred = 0;
321 s->remainder_valid =
322 scsi_get_sense_info_fld(sense, SCSI_SENSE_BUFFERSIZE, &s->uremainder64);
323 switch (sense[0] & 0x7f) {
324 case 0x71:
325 s->deferred = 1;
326 case 0x70:
327 s->fixed_format = 1;
328 s->flags = sense[2] & 0xe0;
329 break;
330 case 0x73:
331 s->deferred = 1;
332 case 0x72:
333 s->fixed_format = 0;
334 ucp = scsi_sense_desc_find(sense, SCSI_SENSE_BUFFERSIZE, 4);
335 s->flags = ucp ? (ucp[3] & 0xe0) : 0;
336 break;
337 }
338 }
339}
340
341
342/* Convert the result to success code */
Mike Christie8b05b772005-11-08 04:06:44 -0600343static int st_chk_result(struct scsi_tape *STp, struct st_request * SRpnt)
Linus Torvalds1da177e2005-04-16 15:20:36 -0700344{
Mike Christie8b05b772005-11-08 04:06:44 -0600345 int result = SRpnt->result;
Linus Torvalds1da177e2005-04-16 15:20:36 -0700346 u8 scode;
347 DEB(const char *stp;)
348 char *name = tape_name(STp);
349 struct st_cmdstatus *cmdstatp;
350
351 if (!result)
352 return 0;
353
354 cmdstatp = &STp->buffer->cmdstat;
Kai Makisaraf03a5672005-08-02 13:40:47 +0300355 st_analyze_sense(SRpnt, cmdstatp);
Linus Torvalds1da177e2005-04-16 15:20:36 -0700356
357 if (cmdstatp->have_sense)
358 scode = STp->buffer->cmdstat.sense_hdr.sense_key;
359 else
360 scode = 0;
361
362 DEB(
363 if (debugging) {
Mike Christie8b05b772005-11-08 04:06:44 -0600364 printk(ST_DEB_MSG "%s: Error: %x, cmd: %x %x %x %x %x %x\n",
Linus Torvalds1da177e2005-04-16 15:20:36 -0700365 name, result,
Mike Christie8b05b772005-11-08 04:06:44 -0600366 SRpnt->cmd[0], SRpnt->cmd[1], SRpnt->cmd[2],
367 SRpnt->cmd[3], SRpnt->cmd[4], SRpnt->cmd[5]);
Linus Torvalds1da177e2005-04-16 15:20:36 -0700368 if (cmdstatp->have_sense)
Luben Tuikov4e73ea72006-07-07 00:02:18 -0700369 __scsi_print_sense(name, SRpnt->sense, SCSI_SENSE_BUFFERSIZE);
Linus Torvalds1da177e2005-04-16 15:20:36 -0700370 } ) /* end DEB */
371 if (!debugging) { /* Abnormal conditions for tape */
372 if (!cmdstatp->have_sense)
373 printk(KERN_WARNING
Martin K. Petersen1c9fbaf2009-01-04 03:14:11 -0500374 "%s: Error %x (driver bt 0x%x, host bt 0x%x).\n",
375 name, result, driver_byte(result),
376 host_byte(result));
Linus Torvalds1da177e2005-04-16 15:20:36 -0700377 else if (cmdstatp->have_sense &&
378 scode != NO_SENSE &&
379 scode != RECOVERED_ERROR &&
380 /* scode != UNIT_ATTENTION && */
381 scode != BLANK_CHECK &&
382 scode != VOLUME_OVERFLOW &&
Mike Christie8b05b772005-11-08 04:06:44 -0600383 SRpnt->cmd[0] != MODE_SENSE &&
384 SRpnt->cmd[0] != TEST_UNIT_READY) {
Luben Tuikov4e73ea72006-07-07 00:02:18 -0700385
386 __scsi_print_sense(name, SRpnt->sense, SCSI_SENSE_BUFFERSIZE);
Linus Torvalds1da177e2005-04-16 15:20:36 -0700387 }
388 }
389
390 if (cmdstatp->fixed_format &&
391 STp->cln_mode >= EXTENDED_SENSE_START) { /* Only fixed format sense */
392 if (STp->cln_sense_value)
Mike Christie8b05b772005-11-08 04:06:44 -0600393 STp->cleaning_req |= ((SRpnt->sense[STp->cln_mode] &
Linus Torvalds1da177e2005-04-16 15:20:36 -0700394 STp->cln_sense_mask) == STp->cln_sense_value);
395 else
Mike Christie8b05b772005-11-08 04:06:44 -0600396 STp->cleaning_req |= ((SRpnt->sense[STp->cln_mode] &
Linus Torvalds1da177e2005-04-16 15:20:36 -0700397 STp->cln_sense_mask) != 0);
398 }
399 if (cmdstatp->have_sense &&
400 cmdstatp->sense_hdr.asc == 0 && cmdstatp->sense_hdr.ascq == 0x17)
401 STp->cleaning_req = 1; /* ASC and ASCQ => cleaning requested */
402
403 STp->pos_unknown |= STp->device->was_reset;
404
405 if (cmdstatp->have_sense &&
406 scode == RECOVERED_ERROR
407#if ST_RECOVERED_WRITE_FATAL
Mike Christie8b05b772005-11-08 04:06:44 -0600408 && SRpnt->cmd[0] != WRITE_6
409 && SRpnt->cmd[0] != WRITE_FILEMARKS
Linus Torvalds1da177e2005-04-16 15:20:36 -0700410#endif
411 ) {
412 STp->recover_count++;
413 STp->recover_reg++;
414
415 DEB(
416 if (debugging) {
Mike Christie8b05b772005-11-08 04:06:44 -0600417 if (SRpnt->cmd[0] == READ_6)
Linus Torvalds1da177e2005-04-16 15:20:36 -0700418 stp = "read";
Mike Christie8b05b772005-11-08 04:06:44 -0600419 else if (SRpnt->cmd[0] == WRITE_6)
Linus Torvalds1da177e2005-04-16 15:20:36 -0700420 stp = "write";
421 else
422 stp = "ioctl";
423 printk(ST_DEB_MSG "%s: Recovered %s error (%d).\n", name, stp,
424 STp->recover_count);
425 } ) /* end DEB */
426
427 if (cmdstatp->flags == 0)
428 return 0;
429 }
430 return (-EIO);
431}
432
FUJITA Tomonori4deba242008-12-05 15:25:20 +0900433static struct st_request *st_allocate_request(struct scsi_tape *stp)
Mike Christie8b05b772005-11-08 04:06:44 -0600434{
FUJITA Tomonori4deba242008-12-05 15:25:20 +0900435 struct st_request *streq;
436
437 streq = kzalloc(sizeof(*streq), GFP_KERNEL);
438 if (streq)
439 streq->stp = stp;
440 else {
441 DEBC(printk(KERN_ERR "%s: Can't get SCSI request.\n",
442 tape_name(stp)););
443 if (signal_pending(current))
444 stp->buffer->syscall_result = -EINTR;
445 else
446 stp->buffer->syscall_result = -EBUSY;
447 }
448
449 return streq;
Mike Christie8b05b772005-11-08 04:06:44 -0600450}
451
452static void st_release_request(struct st_request *streq)
453{
454 kfree(streq);
Linus Torvalds1da177e2005-04-16 15:20:36 -0700455}
456
FUJITA Tomonori13b53b42008-12-18 14:49:41 +0900457static void st_scsi_execute_end(struct request *req, int uptodate)
458{
459 struct st_request *SRpnt = req->end_io_data;
460 struct scsi_tape *STp = SRpnt->stp;
Petr Uzelc68bf8e2011-10-21 13:31:09 +0200461 struct bio *tmp;
FUJITA Tomonori13b53b42008-12-18 14:49:41 +0900462
463 STp->buffer->cmdstat.midlevel_result = SRpnt->result = req->errors;
Tejun Heoc3a4d782009-05-07 22:24:37 +0900464 STp->buffer->cmdstat.residual = req->resid_len;
FUJITA Tomonori13b53b42008-12-18 14:49:41 +0900465
Petr Uzelc68bf8e2011-10-21 13:31:09 +0200466 tmp = SRpnt->bio;
FUJITA Tomonori13b53b42008-12-18 14:49:41 +0900467 if (SRpnt->waiting)
468 complete(SRpnt->waiting);
469
Petr Uzelc68bf8e2011-10-21 13:31:09 +0200470 blk_rq_unmap_user(tmp);
FUJITA Tomonori13b53b42008-12-18 14:49:41 +0900471 __blk_put_request(req->q, req);
472}
473
474static int st_scsi_execute(struct st_request *SRpnt, const unsigned char *cmd,
475 int data_direction, void *buffer, unsigned bufflen,
476 int timeout, int retries)
477{
478 struct request *req;
479 struct rq_map_data *mdata = &SRpnt->stp->buffer->map_data;
480 int err = 0;
481 int write = (data_direction == DMA_TO_DEVICE);
482
483 req = blk_get_request(SRpnt->stp->device->request_queue, write,
484 GFP_KERNEL);
485 if (!req)
486 return DRIVER_ERROR << 24;
487
488 req->cmd_type = REQ_TYPE_BLOCK_PC;
489 req->cmd_flags |= REQ_QUIET;
490
491 mdata->null_mapped = 1;
492
Kai Makisara02ae2c02008-12-18 14:49:50 +0900493 if (bufflen) {
494 err = blk_rq_map_user(req->q, req, mdata, NULL, bufflen,
495 GFP_KERNEL);
496 if (err) {
497 blk_put_request(req);
498 return DRIVER_ERROR << 24;
499 }
FUJITA Tomonori13b53b42008-12-18 14:49:41 +0900500 }
501
502 SRpnt->bio = req->bio;
503 req->cmd_len = COMMAND_SIZE(cmd[0]);
504 memset(req->cmd, 0, BLK_MAX_CDB);
505 memcpy(req->cmd, cmd, req->cmd_len);
506 req->sense = SRpnt->sense;
507 req->sense_len = 0;
508 req->timeout = timeout;
509 req->retries = retries;
510 req->end_io_data = SRpnt;
511
512 blk_execute_rq_nowait(req->q, NULL, req, 1, st_scsi_execute_end);
513 return 0;
514}
515
Linus Torvalds1da177e2005-04-16 15:20:36 -0700516/* Do the scsi command. Waits until command performed if do_wait is true.
517 Otherwise write_behind_check() is used to check that the command
518 has finished. */
Mike Christie8b05b772005-11-08 04:06:44 -0600519static struct st_request *
520st_do_scsi(struct st_request * SRpnt, struct scsi_tape * STp, unsigned char *cmd,
Linus Torvalds1da177e2005-04-16 15:20:36 -0700521 int bytes, int direction, int timeout, int retries, int do_wait)
522{
Kai Makisaraf03a5672005-08-02 13:40:47 +0300523 struct completion *waiting;
FUJITA Tomonori6d476262008-12-18 14:49:42 +0900524 struct rq_map_data *mdata = &STp->buffer->map_data;
525 int ret;
Linus Torvalds1da177e2005-04-16 15:20:36 -0700526
Kai Makisaraf03a5672005-08-02 13:40:47 +0300527 /* if async, make sure there's no command outstanding */
528 if (!do_wait && ((STp->buffer)->last_SRpnt)) {
529 printk(KERN_ERR "%s: Async command already active.\n",
530 tape_name(STp));
531 if (signal_pending(current))
532 (STp->buffer)->syscall_result = (-EINTR);
533 else
534 (STp->buffer)->syscall_result = (-EBUSY);
535 return NULL;
536 }
537
FUJITA Tomonori4deba242008-12-05 15:25:20 +0900538 if (!SRpnt) {
539 SRpnt = st_allocate_request(STp);
540 if (!SRpnt)
Linus Torvalds1da177e2005-04-16 15:20:36 -0700541 return NULL;
Linus Torvalds1da177e2005-04-16 15:20:36 -0700542 }
543
Kai Makisaraf03a5672005-08-02 13:40:47 +0300544 /* If async IO, set last_SRpnt. This ptr tells write_behind_check
545 which IO is outstanding. It's nulled out when the IO completes. */
546 if (!do_wait)
547 (STp->buffer)->last_SRpnt = SRpnt;
548
549 waiting = &STp->wait;
550 init_completion(waiting);
Mike Christie8b05b772005-11-08 04:06:44 -0600551 SRpnt->waiting = waiting;
552
FUJITA Tomonori66207422008-12-18 14:49:43 +0900553 if (STp->buffer->do_dio) {
FUJITA Tomonoric982c362009-11-26 09:24:13 +0900554 mdata->page_order = 0;
FUJITA Tomonori66207422008-12-18 14:49:43 +0900555 mdata->nr_entries = STp->buffer->sg_segs;
556 mdata->pages = STp->buffer->mapped_pages;
557 } else {
FUJITA Tomonoric982c362009-11-26 09:24:13 +0900558 mdata->page_order = STp->buffer->reserved_page_order;
FUJITA Tomonori6d476262008-12-18 14:49:42 +0900559 mdata->nr_entries =
560 DIV_ROUND_UP(bytes, PAGE_SIZE << mdata->page_order);
FUJITA Tomonoric982c362009-11-26 09:24:13 +0900561 mdata->pages = STp->buffer->reserved_pages;
562 mdata->offset = 0;
FUJITA Tomonori6d476262008-12-18 14:49:42 +0900563 }
564
Mike Christie8b05b772005-11-08 04:06:44 -0600565 memcpy(SRpnt->cmd, cmd, sizeof(SRpnt->cmd));
Linus Torvalds1da177e2005-04-16 15:20:36 -0700566 STp->buffer->cmdstat.have_sense = 0;
Mike Christie8b05b772005-11-08 04:06:44 -0600567 STp->buffer->syscall_result = 0;
Linus Torvalds1da177e2005-04-16 15:20:36 -0700568
FUJITA Tomonori66207422008-12-18 14:49:43 +0900569 ret = st_scsi_execute(SRpnt, cmd, direction, NULL, bytes, timeout,
570 retries);
FUJITA Tomonori6d476262008-12-18 14:49:42 +0900571 if (ret) {
Mike Christie8b05b772005-11-08 04:06:44 -0600572 /* could not allocate the buffer or request was too large */
573 (STp->buffer)->syscall_result = (-EBUSY);
Kai Makisara787926b2005-11-13 10:04:44 +0200574 (STp->buffer)->last_SRpnt = NULL;
FUJITA Tomonori6d476262008-12-18 14:49:42 +0900575 } else if (do_wait) {
Kai Makisaraf03a5672005-08-02 13:40:47 +0300576 wait_for_completion(waiting);
Mike Christie8b05b772005-11-08 04:06:44 -0600577 SRpnt->waiting = NULL;
Linus Torvalds1da177e2005-04-16 15:20:36 -0700578 (STp->buffer)->syscall_result = st_chk_result(STp, SRpnt);
579 }
Mike Christie8b05b772005-11-08 04:06:44 -0600580
Linus Torvalds1da177e2005-04-16 15:20:36 -0700581 return SRpnt;
582}
583
584
585/* Handle the write-behind checking (waits for completion). Returns -ENOSPC if
586 write has been correct but EOM early warning reached, -EIO if write ended in
587 error or zero if write successful. Asynchronous writes are used only in
588 variable block mode. */
589static int write_behind_check(struct scsi_tape * STp)
590{
591 int retval = 0;
592 struct st_buffer *STbuffer;
593 struct st_partstat *STps;
594 struct st_cmdstatus *cmdstatp;
Mike Christie8b05b772005-11-08 04:06:44 -0600595 struct st_request *SRpnt;
Linus Torvalds1da177e2005-04-16 15:20:36 -0700596
597 STbuffer = STp->buffer;
598 if (!STbuffer->writing)
599 return 0;
600
601 DEB(
602 if (STp->write_pending)
603 STp->nbr_waits++;
604 else
605 STp->nbr_finished++;
606 ) /* end DEB */
607
608 wait_for_completion(&(STp->wait));
Kai Makisaraf03a5672005-08-02 13:40:47 +0300609 SRpnt = STbuffer->last_SRpnt;
610 STbuffer->last_SRpnt = NULL;
Mike Christie8b05b772005-11-08 04:06:44 -0600611 SRpnt->waiting = NULL;
Linus Torvalds1da177e2005-04-16 15:20:36 -0700612
Kai Makisaraf03a5672005-08-02 13:40:47 +0300613 (STp->buffer)->syscall_result = st_chk_result(STp, SRpnt);
Mike Christie8b05b772005-11-08 04:06:44 -0600614 st_release_request(SRpnt);
Linus Torvalds1da177e2005-04-16 15:20:36 -0700615
616 STbuffer->buffer_bytes -= STbuffer->writing;
617 STps = &(STp->ps[STp->partition]);
618 if (STps->drv_block >= 0) {
619 if (STp->block_size == 0)
620 STps->drv_block++;
621 else
622 STps->drv_block += STbuffer->writing / STp->block_size;
623 }
624
625 cmdstatp = &STbuffer->cmdstat;
626 if (STbuffer->syscall_result) {
627 retval = -EIO;
628 if (cmdstatp->have_sense && !cmdstatp->deferred &&
629 (cmdstatp->flags & SENSE_EOM) &&
630 (cmdstatp->sense_hdr.sense_key == NO_SENSE ||
631 cmdstatp->sense_hdr.sense_key == RECOVERED_ERROR)) {
632 /* EOM at write-behind, has all data been written? */
633 if (!cmdstatp->remainder_valid ||
634 cmdstatp->uremainder64 == 0)
635 retval = -ENOSPC;
636 }
637 if (retval == -EIO)
638 STps->drv_block = -1;
639 }
640 STbuffer->writing = 0;
641
642 DEB(if (debugging && retval)
643 printk(ST_DEB_MSG "%s: Async write error %x, return value %d.\n",
644 tape_name(STp), STbuffer->cmdstat.midlevel_result, retval);) /* end DEB */
645
646 return retval;
647}
648
649
650/* Step over EOF if it has been inadvertently crossed (ioctl not used because
651 it messes up the block number). */
652static int cross_eof(struct scsi_tape * STp, int forward)
653{
Mike Christie8b05b772005-11-08 04:06:44 -0600654 struct st_request *SRpnt;
Linus Torvalds1da177e2005-04-16 15:20:36 -0700655 unsigned char cmd[MAX_COMMAND_SIZE];
656
657 cmd[0] = SPACE;
658 cmd[1] = 0x01; /* Space FileMarks */
659 if (forward) {
660 cmd[2] = cmd[3] = 0;
661 cmd[4] = 1;
662 } else
663 cmd[2] = cmd[3] = cmd[4] = 0xff; /* -1 filemarks */
664 cmd[5] = 0;
665
666 DEBC(printk(ST_DEB_MSG "%s: Stepping over filemark %s.\n",
667 tape_name(STp), forward ? "forward" : "backward"));
668
Kai Makisara02ae2c02008-12-18 14:49:50 +0900669 SRpnt = st_do_scsi(NULL, STp, cmd, 0, DMA_NONE,
670 STp->device->request_queue->rq_timeout,
671 MAX_RETRIES, 1);
Linus Torvalds1da177e2005-04-16 15:20:36 -0700672 if (!SRpnt)
Kai Makisara02ae2c02008-12-18 14:49:50 +0900673 return (STp->buffer)->syscall_result;
Linus Torvalds1da177e2005-04-16 15:20:36 -0700674
Kai Makisara02ae2c02008-12-18 14:49:50 +0900675 st_release_request(SRpnt);
676 SRpnt = NULL;
Linus Torvalds1da177e2005-04-16 15:20:36 -0700677
678 if ((STp->buffer)->cmdstat.midlevel_result != 0)
679 printk(KERN_ERR "%s: Stepping over filemark %s failed.\n",
680 tape_name(STp), forward ? "forward" : "backward");
681
Kai Makisara02ae2c02008-12-18 14:49:50 +0900682 return (STp->buffer)->syscall_result;
Linus Torvalds1da177e2005-04-16 15:20:36 -0700683}
684
685
686/* Flush the write buffer (never need to write if variable blocksize). */
Adrian Bunk8ef8d592008-04-14 17:17:16 +0300687static int st_flush_write_buffer(struct scsi_tape * STp)
Linus Torvalds1da177e2005-04-16 15:20:36 -0700688{
Kai Makisara786231a2008-07-11 15:06:40 +0300689 int transfer, blks;
Linus Torvalds1da177e2005-04-16 15:20:36 -0700690 int result;
691 unsigned char cmd[MAX_COMMAND_SIZE];
Mike Christie8b05b772005-11-08 04:06:44 -0600692 struct st_request *SRpnt;
Linus Torvalds1da177e2005-04-16 15:20:36 -0700693 struct st_partstat *STps;
694
695 result = write_behind_check(STp);
696 if (result)
697 return result;
698
699 result = 0;
700 if (STp->dirty == 1) {
701
Kai Makisara786231a2008-07-11 15:06:40 +0300702 transfer = STp->buffer->buffer_bytes;
Linus Torvalds1da177e2005-04-16 15:20:36 -0700703 DEBC(printk(ST_DEB_MSG "%s: Flushing %d bytes.\n",
704 tape_name(STp), transfer));
705
Linus Torvalds1da177e2005-04-16 15:20:36 -0700706 memset(cmd, 0, MAX_COMMAND_SIZE);
707 cmd[0] = WRITE_6;
708 cmd[1] = 1;
709 blks = transfer / STp->block_size;
710 cmd[2] = blks >> 16;
711 cmd[3] = blks >> 8;
712 cmd[4] = blks;
713
714 SRpnt = st_do_scsi(NULL, STp, cmd, transfer, DMA_TO_DEVICE,
James Bottomleya02488e2008-11-30 10:36:26 -0600715 STp->device->request_queue->rq_timeout,
716 MAX_WRITE_RETRIES, 1);
Linus Torvalds1da177e2005-04-16 15:20:36 -0700717 if (!SRpnt)
718 return (STp->buffer)->syscall_result;
719
720 STps = &(STp->ps[STp->partition]);
721 if ((STp->buffer)->syscall_result != 0) {
722 struct st_cmdstatus *cmdstatp = &STp->buffer->cmdstat;
723
724 if (cmdstatp->have_sense && !cmdstatp->deferred &&
725 (cmdstatp->flags & SENSE_EOM) &&
726 (cmdstatp->sense_hdr.sense_key == NO_SENSE ||
727 cmdstatp->sense_hdr.sense_key == RECOVERED_ERROR) &&
728 (!cmdstatp->remainder_valid ||
729 cmdstatp->uremainder64 == 0)) { /* All written at EOM early warning */
730 STp->dirty = 0;
731 (STp->buffer)->buffer_bytes = 0;
732 if (STps->drv_block >= 0)
733 STps->drv_block += blks;
734 result = (-ENOSPC);
735 } else {
736 printk(KERN_ERR "%s: Error on flush.\n",
737 tape_name(STp));
738 STps->drv_block = (-1);
739 result = (-EIO);
740 }
741 } else {
742 if (STps->drv_block >= 0)
743 STps->drv_block += blks;
744 STp->dirty = 0;
745 (STp->buffer)->buffer_bytes = 0;
746 }
Mike Christie8b05b772005-11-08 04:06:44 -0600747 st_release_request(SRpnt);
Linus Torvalds1da177e2005-04-16 15:20:36 -0700748 SRpnt = NULL;
749 }
750 return result;
751}
752
753
754/* Flush the tape buffer. The tape will be positioned correctly unless
755 seek_next is true. */
756static int flush_buffer(struct scsi_tape *STp, int seek_next)
757{
758 int backspace, result;
759 struct st_buffer *STbuffer;
760 struct st_partstat *STps;
761
762 STbuffer = STp->buffer;
763
764 /*
765 * If there was a bus reset, block further access
766 * to this device.
767 */
768 if (STp->pos_unknown)
769 return (-EIO);
770
771 if (STp->ready != ST_READY)
772 return 0;
773 STps = &(STp->ps[STp->partition]);
774 if (STps->rw == ST_WRITING) /* Writing */
Adrian Bunk8ef8d592008-04-14 17:17:16 +0300775 return st_flush_write_buffer(STp);
Linus Torvalds1da177e2005-04-16 15:20:36 -0700776
777 if (STp->block_size == 0)
778 return 0;
779
780 backspace = ((STp->buffer)->buffer_bytes +
781 (STp->buffer)->read_pointer) / STp->block_size -
782 ((STp->buffer)->read_pointer + STp->block_size - 1) /
783 STp->block_size;
784 (STp->buffer)->buffer_bytes = 0;
785 (STp->buffer)->read_pointer = 0;
786 result = 0;
787 if (!seek_next) {
788 if (STps->eof == ST_FM_HIT) {
789 result = cross_eof(STp, 0); /* Back over the EOF hit */
790 if (!result)
791 STps->eof = ST_NOEOF;
792 else {
793 if (STps->drv_file >= 0)
794 STps->drv_file++;
795 STps->drv_block = 0;
796 }
797 }
798 if (!result && backspace > 0)
799 result = st_int_ioctl(STp, MTBSR, backspace);
800 } else if (STps->eof == ST_FM_HIT) {
801 if (STps->drv_file >= 0)
802 STps->drv_file++;
803 STps->drv_block = 0;
804 STps->eof = ST_NOEOF;
805 }
806 return result;
807
808}
809
810/* Set the mode parameters */
811static int set_mode_densblk(struct scsi_tape * STp, struct st_modedef * STm)
812{
813 int set_it = 0;
814 unsigned long arg;
815 char *name = tape_name(STp);
816
817 if (!STp->density_changed &&
818 STm->default_density >= 0 &&
819 STm->default_density != STp->density) {
820 arg = STm->default_density;
821 set_it = 1;
822 } else
823 arg = STp->density;
824 arg <<= MT_ST_DENSITY_SHIFT;
825 if (!STp->blksize_changed &&
826 STm->default_blksize >= 0 &&
827 STm->default_blksize != STp->block_size) {
828 arg |= STm->default_blksize;
829 set_it = 1;
830 } else
831 arg |= STp->block_size;
832 if (set_it &&
833 st_int_ioctl(STp, SET_DENS_AND_BLK, arg)) {
834 printk(KERN_WARNING
835 "%s: Can't set default block size to %d bytes and density %x.\n",
836 name, STm->default_blksize, STm->default_density);
837 if (modes_defined)
838 return (-EINVAL);
839 }
840 return 0;
841}
842
843
Mike Christie8b05b772005-11-08 04:06:44 -0600844/* Lock or unlock the drive door. Don't use when st_request allocated. */
Linus Torvalds1da177e2005-04-16 15:20:36 -0700845static int do_door_lock(struct scsi_tape * STp, int do_lock)
846{
847 int retval, cmd;
848 DEB(char *name = tape_name(STp);)
849
850
851 cmd = do_lock ? SCSI_IOCTL_DOORLOCK : SCSI_IOCTL_DOORUNLOCK;
852 DEBC(printk(ST_DEB_MSG "%s: %socking drive door.\n", name,
853 do_lock ? "L" : "Unl"));
854 retval = scsi_ioctl(STp->device, cmd, NULL);
855 if (!retval) {
856 STp->door_locked = do_lock ? ST_LOCKED_EXPLICIT : ST_UNLOCKED;
857 }
858 else {
859 STp->door_locked = ST_LOCK_FAILS;
860 }
861 return retval;
862}
863
864
865/* Set the internal state after reset */
866static void reset_state(struct scsi_tape *STp)
867{
868 int i;
869 struct st_partstat *STps;
870
871 STp->pos_unknown = 0;
872 for (i = 0; i < ST_NBR_PARTITIONS; i++) {
873 STps = &(STp->ps[i]);
874 STps->rw = ST_IDLE;
875 STps->eof = ST_NOEOF;
876 STps->at_sm = 0;
877 STps->last_block_valid = 0;
878 STps->drv_block = -1;
879 STps->drv_file = -1;
880 }
881 if (STp->can_partitions) {
882 STp->partition = find_partition(STp);
883 if (STp->partition < 0)
884 STp->partition = 0;
885 STp->new_partition = STp->partition;
886 }
887}
888
889/* Test if the drive is ready. Returns either one of the codes below or a negative system
890 error code. */
891#define CHKRES_READY 0
892#define CHKRES_NEW_SESSION 1
893#define CHKRES_NOT_READY 2
894#define CHKRES_NO_TAPE 3
895
896#define MAX_ATTENTIONS 10
897
898static int test_ready(struct scsi_tape *STp, int do_wait)
899{
900 int attentions, waits, max_wait, scode;
901 int retval = CHKRES_READY, new_session = 0;
902 unsigned char cmd[MAX_COMMAND_SIZE];
Kai Makisara02ae2c02008-12-18 14:49:50 +0900903 struct st_request *SRpnt = NULL;
Linus Torvalds1da177e2005-04-16 15:20:36 -0700904 struct st_cmdstatus *cmdstatp = &STp->buffer->cmdstat;
905
906 max_wait = do_wait ? ST_BLOCK_SECONDS : 0;
907
908 for (attentions=waits=0; ; ) {
909 memset((void *) &cmd[0], 0, MAX_COMMAND_SIZE);
910 cmd[0] = TEST_UNIT_READY;
Kai Makisara02ae2c02008-12-18 14:49:50 +0900911 SRpnt = st_do_scsi(SRpnt, STp, cmd, 0, DMA_NONE,
912 STp->long_timeout, MAX_READY_RETRIES, 1);
Linus Torvalds1da177e2005-04-16 15:20:36 -0700913
Kai Makisara02ae2c02008-12-18 14:49:50 +0900914 if (!SRpnt) {
915 retval = (STp->buffer)->syscall_result;
Linus Torvalds1da177e2005-04-16 15:20:36 -0700916 break;
Kai Makisara02ae2c02008-12-18 14:49:50 +0900917 }
Linus Torvalds1da177e2005-04-16 15:20:36 -0700918
919 if (cmdstatp->have_sense) {
920
921 scode = cmdstatp->sense_hdr.sense_key;
922
923 if (scode == UNIT_ATTENTION) { /* New media? */
924 new_session = 1;
925 if (attentions < MAX_ATTENTIONS) {
926 attentions++;
927 continue;
928 }
929 else {
930 retval = (-EIO);
931 break;
932 }
933 }
934
935 if (scode == NOT_READY) {
936 if (waits < max_wait) {
937 if (msleep_interruptible(1000)) {
938 retval = (-EINTR);
939 break;
940 }
941 waits++;
942 continue;
943 }
944 else {
945 if ((STp->device)->scsi_level >= SCSI_2 &&
946 cmdstatp->sense_hdr.asc == 0x3a) /* Check ASC */
947 retval = CHKRES_NO_TAPE;
948 else
949 retval = CHKRES_NOT_READY;
950 break;
951 }
952 }
953 }
954
955 retval = (STp->buffer)->syscall_result;
956 if (!retval)
957 retval = new_session ? CHKRES_NEW_SESSION : CHKRES_READY;
958 break;
959 }
960
Kai Makisara02ae2c02008-12-18 14:49:50 +0900961 if (SRpnt != NULL)
962 st_release_request(SRpnt);
Linus Torvalds1da177e2005-04-16 15:20:36 -0700963 return retval;
964}
965
966
967/* See if the drive is ready and gather information about the tape. Return values:
968 < 0 negative error code from errno.h
969 0 drive ready
970 1 drive not ready (possibly no tape)
971*/
972static int check_tape(struct scsi_tape *STp, struct file *filp)
973{
974 int i, retval, new_session = 0, do_wait;
975 unsigned char cmd[MAX_COMMAND_SIZE], saved_cleaning;
976 unsigned short st_flags = filp->f_flags;
Mike Christie8b05b772005-11-08 04:06:44 -0600977 struct st_request *SRpnt = NULL;
Linus Torvalds1da177e2005-04-16 15:20:36 -0700978 struct st_modedef *STm;
979 struct st_partstat *STps;
980 char *name = tape_name(STp);
Josef Sipek7ac62072006-12-08 02:37:37 -0800981 struct inode *inode = filp->f_path.dentry->d_inode;
Linus Torvalds1da177e2005-04-16 15:20:36 -0700982 int mode = TAPE_MODE(inode);
983
984 STp->ready = ST_READY;
985
986 if (mode != STp->current_mode) {
987 DEBC(printk(ST_DEB_MSG "%s: Mode change from %d to %d.\n",
988 name, STp->current_mode, mode));
989 new_session = 1;
990 STp->current_mode = mode;
991 }
992 STm = &(STp->modes[STp->current_mode]);
993
994 saved_cleaning = STp->cleaning_req;
995 STp->cleaning_req = 0;
996
997 do_wait = ((filp->f_flags & O_NONBLOCK) == 0);
998 retval = test_ready(STp, do_wait);
999
1000 if (retval < 0)
1001 goto err_out;
1002
1003 if (retval == CHKRES_NEW_SESSION) {
1004 STp->pos_unknown = 0;
1005 STp->partition = STp->new_partition = 0;
1006 if (STp->can_partitions)
1007 STp->nbr_partitions = 1; /* This guess will be updated later
1008 if necessary */
1009 for (i = 0; i < ST_NBR_PARTITIONS; i++) {
1010 STps = &(STp->ps[i]);
1011 STps->rw = ST_IDLE;
1012 STps->eof = ST_NOEOF;
1013 STps->at_sm = 0;
1014 STps->last_block_valid = 0;
1015 STps->drv_block = 0;
1016 STps->drv_file = 0;
1017 }
1018 new_session = 1;
1019 }
1020 else {
1021 STp->cleaning_req |= saved_cleaning;
1022
1023 if (retval == CHKRES_NOT_READY || retval == CHKRES_NO_TAPE) {
1024 if (retval == CHKRES_NO_TAPE)
1025 STp->ready = ST_NO_TAPE;
1026 else
1027 STp->ready = ST_NOT_READY;
1028
1029 STp->density = 0; /* Clear the erroneous "residue" */
1030 STp->write_prot = 0;
1031 STp->block_size = 0;
1032 STp->ps[0].drv_file = STp->ps[0].drv_block = (-1);
1033 STp->partition = STp->new_partition = 0;
1034 STp->door_locked = ST_UNLOCKED;
1035 return CHKRES_NOT_READY;
1036 }
1037 }
1038
1039 if (STp->omit_blklims)
1040 STp->min_block = STp->max_block = (-1);
1041 else {
1042 memset((void *) &cmd[0], 0, MAX_COMMAND_SIZE);
1043 cmd[0] = READ_BLOCK_LIMITS;
1044
Kai Makisara02ae2c02008-12-18 14:49:50 +09001045 SRpnt = st_do_scsi(SRpnt, STp, cmd, 6, DMA_FROM_DEVICE,
1046 STp->device->request_queue->rq_timeout,
1047 MAX_READY_RETRIES, 1);
1048 if (!SRpnt) {
1049 retval = (STp->buffer)->syscall_result;
Linus Torvalds1da177e2005-04-16 15:20:36 -07001050 goto err_out;
1051 }
1052
Mike Christie8b05b772005-11-08 04:06:44 -06001053 if (!SRpnt->result && !STp->buffer->cmdstat.have_sense) {
Linus Torvalds1da177e2005-04-16 15:20:36 -07001054 STp->max_block = ((STp->buffer)->b_data[1] << 16) |
1055 ((STp->buffer)->b_data[2] << 8) | (STp->buffer)->b_data[3];
1056 STp->min_block = ((STp->buffer)->b_data[4] << 8) |
1057 (STp->buffer)->b_data[5];
1058 if ( DEB( debugging || ) !STp->inited)
Kai Makisara42252852006-11-07 21:56:38 +02001059 printk(KERN_INFO
Linus Torvalds1da177e2005-04-16 15:20:36 -07001060 "%s: Block limits %d - %d bytes.\n", name,
1061 STp->min_block, STp->max_block);
1062 } else {
1063 STp->min_block = STp->max_block = (-1);
1064 DEBC(printk(ST_DEB_MSG "%s: Can't read block limits.\n",
1065 name));
1066 }
1067 }
1068
1069 memset((void *) &cmd[0], 0, MAX_COMMAND_SIZE);
1070 cmd[0] = MODE_SENSE;
1071 cmd[4] = 12;
1072
Kai Makisara02ae2c02008-12-18 14:49:50 +09001073 SRpnt = st_do_scsi(SRpnt, STp, cmd, 12, DMA_FROM_DEVICE,
1074 STp->device->request_queue->rq_timeout,
1075 MAX_READY_RETRIES, 1);
1076 if (!SRpnt) {
1077 retval = (STp->buffer)->syscall_result;
Linus Torvalds1da177e2005-04-16 15:20:36 -07001078 goto err_out;
1079 }
1080
1081 if ((STp->buffer)->syscall_result != 0) {
1082 DEBC(printk(ST_DEB_MSG "%s: No Mode Sense.\n", name));
1083 STp->block_size = ST_DEFAULT_BLOCK; /* Educated guess (?) */
1084 (STp->buffer)->syscall_result = 0; /* Prevent error propagation */
1085 STp->drv_write_prot = 0;
1086 } else {
1087 DEBC(printk(ST_DEB_MSG
1088 "%s: Mode sense. Length %d, medium %x, WBS %x, BLL %d\n",
1089 name,
1090 (STp->buffer)->b_data[0], (STp->buffer)->b_data[1],
1091 (STp->buffer)->b_data[2], (STp->buffer)->b_data[3]));
1092
1093 if ((STp->buffer)->b_data[3] >= 8) {
1094 STp->drv_buffer = ((STp->buffer)->b_data[2] >> 4) & 7;
1095 STp->density = (STp->buffer)->b_data[4];
1096 STp->block_size = (STp->buffer)->b_data[9] * 65536 +
1097 (STp->buffer)->b_data[10] * 256 + (STp->buffer)->b_data[11];
1098 DEBC(printk(ST_DEB_MSG
1099 "%s: Density %x, tape length: %x, drv buffer: %d\n",
1100 name, STp->density, (STp->buffer)->b_data[5] * 65536 +
1101 (STp->buffer)->b_data[6] * 256 + (STp->buffer)->b_data[7],
1102 STp->drv_buffer));
1103 }
1104 STp->drv_write_prot = ((STp->buffer)->b_data[2] & 0x80) != 0;
Lee Duncanc743e442012-03-01 12:41:01 -08001105 if (!STp->drv_buffer && STp->immediate_filemark) {
1106 printk(KERN_WARNING
1107 "%s: non-buffered tape: disabling writing immediate filemarks\n",
1108 name);
1109 STp->immediate_filemark = 0;
1110 }
Linus Torvalds1da177e2005-04-16 15:20:36 -07001111 }
Mike Christie8b05b772005-11-08 04:06:44 -06001112 st_release_request(SRpnt);
Linus Torvalds1da177e2005-04-16 15:20:36 -07001113 SRpnt = NULL;
1114 STp->inited = 1;
1115
1116 if (STp->block_size > 0)
1117 (STp->buffer)->buffer_blocks =
1118 (STp->buffer)->buffer_size / STp->block_size;
1119 else
1120 (STp->buffer)->buffer_blocks = 1;
1121 (STp->buffer)->buffer_bytes = (STp->buffer)->read_pointer = 0;
1122
1123 DEBC(printk(ST_DEB_MSG
1124 "%s: Block size: %d, buffer size: %d (%d blocks).\n", name,
1125 STp->block_size, (STp->buffer)->buffer_size,
1126 (STp->buffer)->buffer_blocks));
1127
1128 if (STp->drv_write_prot) {
1129 STp->write_prot = 1;
1130
1131 DEBC(printk(ST_DEB_MSG "%s: Write protected\n", name));
1132
1133 if (do_wait &&
1134 ((st_flags & O_ACCMODE) == O_WRONLY ||
1135 (st_flags & O_ACCMODE) == O_RDWR)) {
1136 retval = (-EROFS);
1137 goto err_out;
1138 }
1139 }
1140
1141 if (STp->can_partitions && STp->nbr_partitions < 1) {
1142 /* This code is reached when the device is opened for the first time
1143 after the driver has been initialized with tape in the drive and the
1144 partition support has been enabled. */
1145 DEBC(printk(ST_DEB_MSG
1146 "%s: Updating partition number in status.\n", name));
1147 if ((STp->partition = find_partition(STp)) < 0) {
1148 retval = STp->partition;
1149 goto err_out;
1150 }
1151 STp->new_partition = STp->partition;
1152 STp->nbr_partitions = 1; /* This guess will be updated when necessary */
1153 }
1154
1155 if (new_session) { /* Change the drive parameters for the new mode */
1156 STp->density_changed = STp->blksize_changed = 0;
1157 STp->compression_changed = 0;
1158 if (!(STm->defaults_for_writes) &&
1159 (retval = set_mode_densblk(STp, STm)) < 0)
1160 goto err_out;
1161
1162 if (STp->default_drvbuffer != 0xff) {
1163 if (st_int_ioctl(STp, MTSETDRVBUFFER, STp->default_drvbuffer))
1164 printk(KERN_WARNING
1165 "%s: Can't set default drive buffering to %d.\n",
1166 name, STp->default_drvbuffer);
1167 }
1168 }
1169
1170 return CHKRES_READY;
1171
1172 err_out:
1173 return retval;
1174}
1175
1176
Jonathan Corbetb3369c62008-05-15 16:08:15 -06001177 /* Open the device. Needs to take the BKL only because of incrementing the SCSI host
Linus Torvalds1da177e2005-04-16 15:20:36 -07001178 module count. */
1179static int st_open(struct inode *inode, struct file *filp)
1180{
1181 int i, retval = (-EIO);
Oliver Neukum46a243f2012-01-15 00:16:51 +01001182 int resumed = 0;
Linus Torvalds1da177e2005-04-16 15:20:36 -07001183 struct scsi_tape *STp;
1184 struct st_partstat *STps;
1185 int dev = TAPE_NR(inode);
1186 char *name;
1187
Arnd Bergmann2a48fc02010-06-02 14:28:52 +02001188 mutex_lock(&st_mutex);
Linus Torvalds1da177e2005-04-16 15:20:36 -07001189 /*
1190 * We really want to do nonseekable_open(inode, filp); here, but some
1191 * versions of tar incorrectly call lseek on tapes and bail out if that
1192 * fails. So we disallow pread() and pwrite(), but permit lseeks.
1193 */
1194 filp->f_mode &= ~(FMODE_PREAD | FMODE_PWRITE);
1195
Jonathan Corbetb3369c62008-05-15 16:08:15 -06001196 if (!(STp = scsi_tape_get(dev))) {
Arnd Bergmann2a48fc02010-06-02 14:28:52 +02001197 mutex_unlock(&st_mutex);
Kai Makisaraf03a5672005-08-02 13:40:47 +03001198 return -ENXIO;
Jonathan Corbetb3369c62008-05-15 16:08:15 -06001199 }
Kai Makisaraf03a5672005-08-02 13:40:47 +03001200
Linus Torvalds1da177e2005-04-16 15:20:36 -07001201 filp->private_data = STp;
1202 name = tape_name(STp);
1203
Jeff Mahoney6c648d92012-08-18 15:20:39 -04001204 spin_lock(&st_use_lock);
Linus Torvalds1da177e2005-04-16 15:20:36 -07001205 if (STp->in_use) {
Jeff Mahoney6c648d92012-08-18 15:20:39 -04001206 spin_unlock(&st_use_lock);
Kai Makisaraf03a5672005-08-02 13:40:47 +03001207 scsi_tape_put(STp);
Arnd Bergmann2a48fc02010-06-02 14:28:52 +02001208 mutex_unlock(&st_mutex);
Linus Torvalds1da177e2005-04-16 15:20:36 -07001209 DEB( printk(ST_DEB_MSG "%s: Device already in use.\n", name); )
1210 return (-EBUSY);
1211 }
1212
Linus Torvalds1da177e2005-04-16 15:20:36 -07001213 STp->in_use = 1;
Jeff Mahoney6c648d92012-08-18 15:20:39 -04001214 spin_unlock(&st_use_lock);
Linus Torvalds1da177e2005-04-16 15:20:36 -07001215 STp->rew_at_close = STp->autorew_dev = (iminor(inode) & 0x80) == 0;
1216
Oliver Neukum46a243f2012-01-15 00:16:51 +01001217 if (scsi_autopm_get_device(STp->device) < 0) {
1218 retval = -EIO;
1219 goto err_out;
1220 }
1221 resumed = 1;
Linus Torvalds1da177e2005-04-16 15:20:36 -07001222 if (!scsi_block_when_processing_errors(STp->device)) {
1223 retval = (-ENXIO);
1224 goto err_out;
1225 }
1226
1227 /* See that we have at least a one page buffer available */
1228 if (!enlarge_buffer(STp->buffer, PAGE_SIZE, STp->restr_dma)) {
1229 printk(KERN_WARNING "%s: Can't allocate one page tape buffer.\n",
1230 name);
1231 retval = (-EOVERFLOW);
1232 goto err_out;
1233 }
1234
Kai Makisara40f6b362008-02-24 22:23:24 +02001235 (STp->buffer)->cleared = 0;
Linus Torvalds1da177e2005-04-16 15:20:36 -07001236 (STp->buffer)->writing = 0;
1237 (STp->buffer)->syscall_result = 0;
1238
1239 STp->write_prot = ((filp->f_flags & O_ACCMODE) == O_RDONLY);
1240
1241 STp->dirty = 0;
1242 for (i = 0; i < ST_NBR_PARTITIONS; i++) {
1243 STps = &(STp->ps[i]);
1244 STps->rw = ST_IDLE;
1245 }
Kai Makisara9abe16c2007-02-03 13:21:29 +02001246 STp->try_dio_now = STp->try_dio;
Linus Torvalds1da177e2005-04-16 15:20:36 -07001247 STp->recover_count = 0;
1248 DEB( STp->nbr_waits = STp->nbr_finished = 0;
Kai Makisaradeee13d2008-02-22 20:11:21 +02001249 STp->nbr_requests = STp->nbr_dio = STp->nbr_pages = 0; )
Linus Torvalds1da177e2005-04-16 15:20:36 -07001250
1251 retval = check_tape(STp, filp);
1252 if (retval < 0)
1253 goto err_out;
1254 if ((filp->f_flags & O_NONBLOCK) == 0 &&
1255 retval != CHKRES_READY) {
Kai Makisara413f7322006-10-05 22:59:46 +03001256 if (STp->ready == NO_TAPE)
1257 retval = (-ENOMEDIUM);
1258 else
1259 retval = (-EIO);
Linus Torvalds1da177e2005-04-16 15:20:36 -07001260 goto err_out;
1261 }
Arnd Bergmann2a48fc02010-06-02 14:28:52 +02001262 mutex_unlock(&st_mutex);
Linus Torvalds1da177e2005-04-16 15:20:36 -07001263 return 0;
1264
1265 err_out:
1266 normalize_buffer(STp->buffer);
1267 STp->in_use = 0;
Kai Makisaraf03a5672005-08-02 13:40:47 +03001268 scsi_tape_put(STp);
Oliver Neukum46a243f2012-01-15 00:16:51 +01001269 if (resumed)
1270 scsi_autopm_put_device(STp->device);
Arnd Bergmann2a48fc02010-06-02 14:28:52 +02001271 mutex_unlock(&st_mutex);
Linus Torvalds1da177e2005-04-16 15:20:36 -07001272 return retval;
1273
1274}
1275
1276
1277/* Flush the tape buffer before close */
Miklos Szeredi75e1fcc2006-06-23 02:05:12 -07001278static int st_flush(struct file *filp, fl_owner_t id)
Linus Torvalds1da177e2005-04-16 15:20:36 -07001279{
1280 int result = 0, result2;
1281 unsigned char cmd[MAX_COMMAND_SIZE];
Mike Christie8b05b772005-11-08 04:06:44 -06001282 struct st_request *SRpnt;
Linus Torvalds1da177e2005-04-16 15:20:36 -07001283 struct scsi_tape *STp = filp->private_data;
1284 struct st_modedef *STm = &(STp->modes[STp->current_mode]);
1285 struct st_partstat *STps = &(STp->ps[STp->partition]);
1286 char *name = tape_name(STp);
1287
1288 if (file_count(filp) > 1)
1289 return 0;
1290
1291 if (STps->rw == ST_WRITING && !STp->pos_unknown) {
Adrian Bunk8ef8d592008-04-14 17:17:16 +03001292 result = st_flush_write_buffer(STp);
Linus Torvalds1da177e2005-04-16 15:20:36 -07001293 if (result != 0 && result != (-ENOSPC))
1294 goto out;
1295 }
1296
1297 if (STp->can_partitions &&
1298 (result2 = switch_partition(STp)) < 0) {
1299 DEBC(printk(ST_DEB_MSG
1300 "%s: switch_partition at close failed.\n", name));
1301 if (result == 0)
1302 result = result2;
1303 goto out;
1304 }
1305
1306 DEBC( if (STp->nbr_requests)
Kai Makisaradeee13d2008-02-22 20:11:21 +02001307 printk(KERN_DEBUG "%s: Number of r/w requests %d, dio used in %d, pages %d.\n",
1308 name, STp->nbr_requests, STp->nbr_dio, STp->nbr_pages));
Linus Torvalds1da177e2005-04-16 15:20:36 -07001309
1310 if (STps->rw == ST_WRITING && !STp->pos_unknown) {
1311 struct st_cmdstatus *cmdstatp = &STp->buffer->cmdstat;
1312
1313 DEBC(printk(ST_DEB_MSG "%s: Async write waits %d, finished %d.\n",
1314 name, STp->nbr_waits, STp->nbr_finished);
1315 )
1316
1317 memset(cmd, 0, MAX_COMMAND_SIZE);
1318 cmd[0] = WRITE_FILEMARKS;
Lee Duncanc743e442012-03-01 12:41:01 -08001319 if (STp->immediate_filemark)
1320 cmd[1] = 1;
Linus Torvalds1da177e2005-04-16 15:20:36 -07001321 cmd[4] = 1 + STp->two_fm;
1322
Kai Makisara02ae2c02008-12-18 14:49:50 +09001323 SRpnt = st_do_scsi(NULL, STp, cmd, 0, DMA_NONE,
1324 STp->device->request_queue->rq_timeout,
1325 MAX_WRITE_RETRIES, 1);
Linus Torvalds1da177e2005-04-16 15:20:36 -07001326 if (!SRpnt) {
Kai Makisara02ae2c02008-12-18 14:49:50 +09001327 result = (STp->buffer)->syscall_result;
Linus Torvalds1da177e2005-04-16 15:20:36 -07001328 goto out;
1329 }
1330
1331 if (STp->buffer->syscall_result == 0 ||
1332 (cmdstatp->have_sense && !cmdstatp->deferred &&
1333 (cmdstatp->flags & SENSE_EOM) &&
1334 (cmdstatp->sense_hdr.sense_key == NO_SENSE ||
1335 cmdstatp->sense_hdr.sense_key == RECOVERED_ERROR) &&
1336 (!cmdstatp->remainder_valid || cmdstatp->uremainder64 == 0))) {
1337 /* Write successful at EOM */
Mike Christie8b05b772005-11-08 04:06:44 -06001338 st_release_request(SRpnt);
Linus Torvalds1da177e2005-04-16 15:20:36 -07001339 SRpnt = NULL;
1340 if (STps->drv_file >= 0)
1341 STps->drv_file++;
1342 STps->drv_block = 0;
1343 if (STp->two_fm)
1344 cross_eof(STp, 0);
1345 STps->eof = ST_FM;
1346 }
1347 else { /* Write error */
Mike Christie8b05b772005-11-08 04:06:44 -06001348 st_release_request(SRpnt);
Linus Torvalds1da177e2005-04-16 15:20:36 -07001349 SRpnt = NULL;
1350 printk(KERN_ERR "%s: Error on write filemark.\n", name);
1351 if (result == 0)
1352 result = (-EIO);
1353 }
1354
1355 DEBC(printk(ST_DEB_MSG "%s: Buffer flushed, %d EOF(s) written\n",
1356 name, cmd[4]));
1357 } else if (!STp->rew_at_close) {
1358 STps = &(STp->ps[STp->partition]);
1359 if (!STm->sysv || STps->rw != ST_READING) {
1360 if (STp->can_bsr)
1361 result = flush_buffer(STp, 0);
1362 else if (STps->eof == ST_FM_HIT) {
1363 result = cross_eof(STp, 0);
1364 if (result) {
1365 if (STps->drv_file >= 0)
1366 STps->drv_file++;
1367 STps->drv_block = 0;
1368 STps->eof = ST_FM;
1369 } else
1370 STps->eof = ST_NOEOF;
1371 }
1372 } else if ((STps->eof == ST_NOEOF &&
1373 !(result = cross_eof(STp, 1))) ||
1374 STps->eof == ST_FM_HIT) {
1375 if (STps->drv_file >= 0)
1376 STps->drv_file++;
1377 STps->drv_block = 0;
1378 STps->eof = ST_FM;
1379 }
1380 }
1381
1382 out:
1383 if (STp->rew_at_close) {
1384 result2 = st_int_ioctl(STp, MTREW, 1);
1385 if (result == 0)
1386 result = result2;
1387 }
1388 return result;
1389}
1390
1391
1392/* Close the device and release it. BKL is not needed: this is the only thread
1393 accessing this tape. */
1394static int st_release(struct inode *inode, struct file *filp)
1395{
1396 int result = 0;
1397 struct scsi_tape *STp = filp->private_data;
1398
1399 if (STp->door_locked == ST_LOCKED_AUTO)
1400 do_door_lock(STp, 0);
1401
1402 normalize_buffer(STp->buffer);
Jeff Mahoney6c648d92012-08-18 15:20:39 -04001403 spin_lock(&st_use_lock);
Linus Torvalds1da177e2005-04-16 15:20:36 -07001404 STp->in_use = 0;
Jeff Mahoney6c648d92012-08-18 15:20:39 -04001405 spin_unlock(&st_use_lock);
Oliver Neukum46a243f2012-01-15 00:16:51 +01001406 scsi_autopm_put_device(STp->device);
Kai Makisaraf03a5672005-08-02 13:40:47 +03001407 scsi_tape_put(STp);
Linus Torvalds1da177e2005-04-16 15:20:36 -07001408
1409 return result;
1410}
1411
1412/* The checks common to both reading and writing */
1413static ssize_t rw_checks(struct scsi_tape *STp, struct file *filp, size_t count)
1414{
1415 ssize_t retval = 0;
1416
1417 /*
1418 * If we are in the middle of error recovery, don't let anyone
1419 * else try and use this device. Also, if error recovery fails, it
1420 * may try and take the device offline, in which case all further
1421 * access to the device is prohibited.
1422 */
1423 if (!scsi_block_when_processing_errors(STp->device)) {
1424 retval = (-ENXIO);
1425 goto out;
1426 }
1427
1428 if (STp->ready != ST_READY) {
1429 if (STp->ready == ST_NO_TAPE)
1430 retval = (-ENOMEDIUM);
1431 else
1432 retval = (-EIO);
1433 goto out;
1434 }
1435
1436 if (! STp->modes[STp->current_mode].defined) {
1437 retval = (-ENXIO);
1438 goto out;
1439 }
1440
1441
1442 /*
1443 * If there was a bus reset, block further access
1444 * to this device.
1445 */
1446 if (STp->pos_unknown) {
1447 retval = (-EIO);
1448 goto out;
1449 }
1450
1451 if (count == 0)
1452 goto out;
1453
1454 DEB(
1455 if (!STp->in_use) {
1456 printk(ST_DEB_MSG "%s: Incorrect device.\n", tape_name(STp));
1457 retval = (-EIO);
1458 goto out;
1459 } ) /* end DEB */
1460
1461 if (STp->can_partitions &&
1462 (retval = switch_partition(STp)) < 0)
1463 goto out;
1464
1465 if (STp->block_size == 0 && STp->max_block > 0 &&
1466 (count < STp->min_block || count > STp->max_block)) {
1467 retval = (-EINVAL);
1468 goto out;
1469 }
1470
1471 if (STp->do_auto_lock && STp->door_locked == ST_UNLOCKED &&
1472 !do_door_lock(STp, 1))
1473 STp->door_locked = ST_LOCKED_AUTO;
1474
1475 out:
1476 return retval;
1477}
1478
1479
1480static int setup_buffering(struct scsi_tape *STp, const char __user *buf,
1481 size_t count, int is_read)
1482{
1483 int i, bufsize, retval = 0;
1484 struct st_buffer *STbp = STp->buffer;
1485
1486 if (is_read)
Kai Makisara9abe16c2007-02-03 13:21:29 +02001487 i = STp->try_dio_now && try_rdio;
Linus Torvalds1da177e2005-04-16 15:20:36 -07001488 else
Kai Makisara9abe16c2007-02-03 13:21:29 +02001489 i = STp->try_dio_now && try_wdio;
Mike Christie8b05b772005-11-08 04:06:44 -06001490
Linus Torvalds1da177e2005-04-16 15:20:36 -07001491 if (i && ((unsigned long)buf & queue_dma_alignment(
1492 STp->device->request_queue)) == 0) {
FUJITA Tomonori66207422008-12-18 14:49:43 +09001493 i = sgl_map_user_pages(STbp, STbp->use_sg, (unsigned long)buf,
1494 count, (is_read ? READ : WRITE));
Linus Torvalds1da177e2005-04-16 15:20:36 -07001495 if (i > 0) {
1496 STbp->do_dio = i;
1497 STbp->buffer_bytes = 0; /* can be used as transfer counter */
1498 }
1499 else
1500 STbp->do_dio = 0; /* fall back to buffering with any error */
1501 STbp->sg_segs = STbp->do_dio;
Linus Torvalds1da177e2005-04-16 15:20:36 -07001502 DEB(
1503 if (STbp->do_dio) {
1504 STp->nbr_dio++;
1505 STp->nbr_pages += STbp->do_dio;
Linus Torvalds1da177e2005-04-16 15:20:36 -07001506 }
1507 )
1508 } else
1509 STbp->do_dio = 0;
1510 DEB( STp->nbr_requests++; )
1511
1512 if (!STbp->do_dio) {
1513 if (STp->block_size)
1514 bufsize = STp->block_size > st_fixed_buffer_size ?
1515 STp->block_size : st_fixed_buffer_size;
Kai Makisara40f6b362008-02-24 22:23:24 +02001516 else {
Linus Torvalds1da177e2005-04-16 15:20:36 -07001517 bufsize = count;
Kai Makisara40f6b362008-02-24 22:23:24 +02001518 /* Make sure that data from previous user is not leaked even if
1519 HBA does not return correct residual */
1520 if (is_read && STp->sili && !STbp->cleared)
1521 clear_buffer(STbp);
1522 }
1523
Linus Torvalds1da177e2005-04-16 15:20:36 -07001524 if (bufsize > STbp->buffer_size &&
1525 !enlarge_buffer(STbp, bufsize, STp->restr_dma)) {
1526 printk(KERN_WARNING "%s: Can't allocate %d byte tape buffer.\n",
1527 tape_name(STp), bufsize);
1528 retval = (-EOVERFLOW);
1529 goto out;
1530 }
1531 if (STp->block_size)
1532 STbp->buffer_blocks = bufsize / STp->block_size;
1533 }
1534
1535 out:
1536 return retval;
1537}
1538
1539
1540/* Can be called more than once after each setup_buffer() */
Kai Makisara787926b2005-11-13 10:04:44 +02001541static void release_buffering(struct scsi_tape *STp, int is_read)
Linus Torvalds1da177e2005-04-16 15:20:36 -07001542{
1543 struct st_buffer *STbp;
1544
1545 STbp = STp->buffer;
1546 if (STbp->do_dio) {
FUJITA Tomonori66207422008-12-18 14:49:43 +09001547 sgl_unmap_user_pages(STbp, STbp->do_dio, is_read);
Linus Torvalds1da177e2005-04-16 15:20:36 -07001548 STbp->do_dio = 0;
Kai Makisara787926b2005-11-13 10:04:44 +02001549 STbp->sg_segs = 0;
Linus Torvalds1da177e2005-04-16 15:20:36 -07001550 }
1551}
1552
1553
1554/* Write command */
1555static ssize_t
1556st_write(struct file *filp, const char __user *buf, size_t count, loff_t * ppos)
1557{
1558 ssize_t total;
1559 ssize_t i, do_count, blks, transfer;
1560 ssize_t retval;
1561 int undone, retry_eot = 0, scode;
1562 int async_write;
1563 unsigned char cmd[MAX_COMMAND_SIZE];
1564 const char __user *b_point;
Mike Christie8b05b772005-11-08 04:06:44 -06001565 struct st_request *SRpnt = NULL;
Linus Torvalds1da177e2005-04-16 15:20:36 -07001566 struct scsi_tape *STp = filp->private_data;
1567 struct st_modedef *STm;
1568 struct st_partstat *STps;
1569 struct st_buffer *STbp;
1570 char *name = tape_name(STp);
1571
Matthias Kaehlcke28f85002007-07-29 23:38:15 +02001572 if (mutex_lock_interruptible(&STp->lock))
Linus Torvalds1da177e2005-04-16 15:20:36 -07001573 return -ERESTARTSYS;
1574
1575 retval = rw_checks(STp, filp, count);
1576 if (retval || count == 0)
1577 goto out;
1578
1579 /* Write must be integral number of blocks */
1580 if (STp->block_size != 0 && (count % STp->block_size) != 0) {
1581 printk(KERN_WARNING "%s: Write not multiple of tape block size.\n",
1582 name);
1583 retval = (-EINVAL);
1584 goto out;
1585 }
1586
1587 STm = &(STp->modes[STp->current_mode]);
1588 STps = &(STp->ps[STp->partition]);
1589
1590 if (STp->write_prot) {
1591 retval = (-EACCES);
1592 goto out;
1593 }
1594
1595
1596 if (STps->rw == ST_READING) {
1597 retval = flush_buffer(STp, 0);
1598 if (retval)
1599 goto out;
1600 STps->rw = ST_WRITING;
1601 } else if (STps->rw != ST_WRITING &&
1602 STps->drv_file == 0 && STps->drv_block == 0) {
1603 if ((retval = set_mode_densblk(STp, STm)) < 0)
1604 goto out;
1605 if (STm->default_compression != ST_DONT_TOUCH &&
1606 !(STp->compression_changed)) {
1607 if (st_compression(STp, (STm->default_compression == ST_YES))) {
1608 printk(KERN_WARNING "%s: Can't set default compression.\n",
1609 name);
1610 if (modes_defined) {
1611 retval = (-EINVAL);
1612 goto out;
1613 }
1614 }
1615 }
1616 }
1617
1618 STbp = STp->buffer;
1619 i = write_behind_check(STp);
1620 if (i) {
1621 if (i == -ENOSPC)
1622 STps->eof = ST_EOM_OK;
1623 else
1624 STps->eof = ST_EOM_ERROR;
1625 }
1626
1627 if (STps->eof == ST_EOM_OK) {
1628 STps->eof = ST_EOD_1; /* allow next write */
1629 retval = (-ENOSPC);
1630 goto out;
1631 }
1632 else if (STps->eof == ST_EOM_ERROR) {
1633 retval = (-EIO);
1634 goto out;
1635 }
1636
1637 /* Check the buffer readability in cases where copy_user might catch
1638 the problems after some tape movement. */
1639 if (STp->block_size != 0 &&
1640 !STbp->do_dio &&
1641 (copy_from_user(&i, buf, 1) != 0 ||
1642 copy_from_user(&i, buf + count - 1, 1) != 0)) {
1643 retval = (-EFAULT);
1644 goto out;
1645 }
1646
1647 retval = setup_buffering(STp, buf, count, 0);
1648 if (retval)
1649 goto out;
1650
1651 total = count;
1652
1653 memset(cmd, 0, MAX_COMMAND_SIZE);
1654 cmd[0] = WRITE_6;
1655 cmd[1] = (STp->block_size != 0);
1656
1657 STps->rw = ST_WRITING;
1658
1659 b_point = buf;
1660 while (count > 0 && !retry_eot) {
1661
1662 if (STbp->do_dio) {
1663 do_count = count;
1664 }
1665 else {
1666 if (STp->block_size == 0)
1667 do_count = count;
1668 else {
1669 do_count = STbp->buffer_blocks * STp->block_size -
1670 STbp->buffer_bytes;
1671 if (do_count > count)
1672 do_count = count;
1673 }
1674
1675 i = append_to_buffer(b_point, STbp, do_count);
1676 if (i) {
1677 retval = i;
1678 goto out;
1679 }
1680 }
1681 count -= do_count;
1682 b_point += do_count;
1683
1684 async_write = STp->block_size == 0 && !STbp->do_dio &&
1685 STm->do_async_writes && STps->eof < ST_EOM_OK;
1686
1687 if (STp->block_size != 0 && STm->do_buffer_writes &&
Kai Makisara9abe16c2007-02-03 13:21:29 +02001688 !(STp->try_dio_now && try_wdio) && STps->eof < ST_EOM_OK &&
Linus Torvalds1da177e2005-04-16 15:20:36 -07001689 STbp->buffer_bytes < STbp->buffer_size) {
1690 STp->dirty = 1;
1691 /* Don't write a buffer that is not full enough. */
1692 if (!async_write && count == 0)
1693 break;
1694 }
1695
1696 retry_write:
1697 if (STp->block_size == 0)
1698 blks = transfer = do_count;
1699 else {
1700 if (!STbp->do_dio)
1701 blks = STbp->buffer_bytes;
1702 else
1703 blks = do_count;
1704 blks /= STp->block_size;
1705 transfer = blks * STp->block_size;
1706 }
1707 cmd[2] = blks >> 16;
1708 cmd[3] = blks >> 8;
1709 cmd[4] = blks;
1710
1711 SRpnt = st_do_scsi(SRpnt, STp, cmd, transfer, DMA_TO_DEVICE,
James Bottomleya02488e2008-11-30 10:36:26 -06001712 STp->device->request_queue->rq_timeout,
1713 MAX_WRITE_RETRIES, !async_write);
Linus Torvalds1da177e2005-04-16 15:20:36 -07001714 if (!SRpnt) {
1715 retval = STbp->syscall_result;
1716 goto out;
1717 }
Mike Christie8b05b772005-11-08 04:06:44 -06001718 if (async_write && !STbp->syscall_result) {
Linus Torvalds1da177e2005-04-16 15:20:36 -07001719 STbp->writing = transfer;
1720 STp->dirty = !(STbp->writing ==
1721 STbp->buffer_bytes);
1722 SRpnt = NULL; /* Prevent releasing this request! */
1723 DEB( STp->write_pending = 1; )
1724 break;
1725 }
1726
1727 if (STbp->syscall_result != 0) {
1728 struct st_cmdstatus *cmdstatp = &STp->buffer->cmdstat;
1729
1730 DEBC(printk(ST_DEB_MSG "%s: Error on write:\n", name));
1731 if (cmdstatp->have_sense && (cmdstatp->flags & SENSE_EOM)) {
1732 scode = cmdstatp->sense_hdr.sense_key;
1733 if (cmdstatp->remainder_valid)
1734 undone = (int)cmdstatp->uremainder64;
1735 else if (STp->block_size == 0 &&
1736 scode == VOLUME_OVERFLOW)
1737 undone = transfer;
1738 else
1739 undone = 0;
1740 if (STp->block_size != 0)
1741 undone *= STp->block_size;
1742 if (undone <= do_count) {
1743 /* Only data from this write is not written */
1744 count += undone;
Kai Makisara626dcb12008-07-11 15:05:25 +03001745 b_point -= undone;
Linus Torvalds1da177e2005-04-16 15:20:36 -07001746 do_count -= undone;
1747 if (STp->block_size)
1748 blks = (transfer - undone) / STp->block_size;
1749 STps->eof = ST_EOM_OK;
1750 /* Continue in fixed block mode if all written
1751 in this request but still something left to write
1752 (retval left to zero)
1753 */
1754 if (STp->block_size == 0 ||
1755 undone > 0 || count == 0)
1756 retval = (-ENOSPC); /* EOM within current request */
1757 DEBC(printk(ST_DEB_MSG
1758 "%s: EOM with %d bytes unwritten.\n",
1759 name, (int)count));
1760 } else {
1761 /* EOT within data buffered earlier (possible only
1762 in fixed block mode without direct i/o) */
1763 if (!retry_eot && !cmdstatp->deferred &&
1764 (scode == NO_SENSE || scode == RECOVERED_ERROR)) {
1765 move_buffer_data(STp->buffer, transfer - undone);
1766 retry_eot = 1;
1767 if (STps->drv_block >= 0) {
1768 STps->drv_block += (transfer - undone) /
1769 STp->block_size;
1770 }
1771 STps->eof = ST_EOM_OK;
1772 DEBC(printk(ST_DEB_MSG
1773 "%s: Retry write of %d bytes at EOM.\n",
1774 name, STp->buffer->buffer_bytes));
1775 goto retry_write;
1776 }
1777 else {
1778 /* Either error within data buffered by driver or
1779 failed retry */
1780 count -= do_count;
1781 blks = do_count = 0;
1782 STps->eof = ST_EOM_ERROR;
1783 STps->drv_block = (-1); /* Too cautious? */
1784 retval = (-EIO); /* EOM for old data */
1785 DEBC(printk(ST_DEB_MSG
1786 "%s: EOM with lost data.\n",
1787 name));
1788 }
1789 }
1790 } else {
1791 count += do_count;
1792 STps->drv_block = (-1); /* Too cautious? */
Mike Christie8b05b772005-11-08 04:06:44 -06001793 retval = STbp->syscall_result;
Linus Torvalds1da177e2005-04-16 15:20:36 -07001794 }
1795
1796 }
1797
1798 if (STps->drv_block >= 0) {
1799 if (STp->block_size == 0)
1800 STps->drv_block += (do_count > 0);
1801 else
1802 STps->drv_block += blks;
1803 }
1804
1805 STbp->buffer_bytes = 0;
1806 STp->dirty = 0;
1807
1808 if (retval || retry_eot) {
1809 if (count < total)
1810 retval = total - count;
1811 goto out;
1812 }
1813 }
1814
1815 if (STps->eof == ST_EOD_1)
1816 STps->eof = ST_EOM_OK;
1817 else if (STps->eof != ST_EOM_OK)
1818 STps->eof = ST_NOEOF;
1819 retval = total - count;
1820
1821 out:
1822 if (SRpnt != NULL)
Mike Christie8b05b772005-11-08 04:06:44 -06001823 st_release_request(SRpnt);
Kai Makisara787926b2005-11-13 10:04:44 +02001824 release_buffering(STp, 0);
Matthias Kaehlcke28f85002007-07-29 23:38:15 +02001825 mutex_unlock(&STp->lock);
Linus Torvalds1da177e2005-04-16 15:20:36 -07001826
1827 return retval;
1828}
1829
1830/* Read data from the tape. Returns zero in the normal case, one if the
1831 eof status has changed, and the negative error code in case of a
1832 fatal error. Otherwise updates the buffer and the eof state.
1833
1834 Does release user buffer mapping if it is set.
1835*/
1836static long read_tape(struct scsi_tape *STp, long count,
Mike Christie8b05b772005-11-08 04:06:44 -06001837 struct st_request ** aSRpnt)
Linus Torvalds1da177e2005-04-16 15:20:36 -07001838{
1839 int transfer, blks, bytes;
1840 unsigned char cmd[MAX_COMMAND_SIZE];
Mike Christie8b05b772005-11-08 04:06:44 -06001841 struct st_request *SRpnt;
Linus Torvalds1da177e2005-04-16 15:20:36 -07001842 struct st_modedef *STm;
1843 struct st_partstat *STps;
1844 struct st_buffer *STbp;
1845 int retval = 0;
1846 char *name = tape_name(STp);
1847
1848 if (count == 0)
1849 return 0;
1850
1851 STm = &(STp->modes[STp->current_mode]);
1852 STps = &(STp->ps[STp->partition]);
1853 if (STps->eof == ST_FM_HIT)
1854 return 1;
1855 STbp = STp->buffer;
1856
1857 if (STp->block_size == 0)
1858 blks = bytes = count;
1859 else {
Kai Makisara9abe16c2007-02-03 13:21:29 +02001860 if (!(STp->try_dio_now && try_rdio) && STm->do_read_ahead) {
Linus Torvalds1da177e2005-04-16 15:20:36 -07001861 blks = (STp->buffer)->buffer_blocks;
1862 bytes = blks * STp->block_size;
1863 } else {
1864 bytes = count;
1865 if (!STbp->do_dio && bytes > (STp->buffer)->buffer_size)
1866 bytes = (STp->buffer)->buffer_size;
1867 blks = bytes / STp->block_size;
1868 bytes = blks * STp->block_size;
1869 }
1870 }
1871
1872 memset(cmd, 0, MAX_COMMAND_SIZE);
1873 cmd[0] = READ_6;
1874 cmd[1] = (STp->block_size != 0);
Kai Makisara40f6b362008-02-24 22:23:24 +02001875 if (!cmd[1] && STp->sili)
1876 cmd[1] |= 2;
Linus Torvalds1da177e2005-04-16 15:20:36 -07001877 cmd[2] = blks >> 16;
1878 cmd[3] = blks >> 8;
1879 cmd[4] = blks;
1880
1881 SRpnt = *aSRpnt;
1882 SRpnt = st_do_scsi(SRpnt, STp, cmd, bytes, DMA_FROM_DEVICE,
James Bottomleya02488e2008-11-30 10:36:26 -06001883 STp->device->request_queue->rq_timeout,
1884 MAX_RETRIES, 1);
Kai Makisara787926b2005-11-13 10:04:44 +02001885 release_buffering(STp, 1);
Linus Torvalds1da177e2005-04-16 15:20:36 -07001886 *aSRpnt = SRpnt;
1887 if (!SRpnt)
1888 return STbp->syscall_result;
1889
1890 STbp->read_pointer = 0;
1891 STps->at_sm = 0;
1892
1893 /* Something to check */
1894 if (STbp->syscall_result) {
1895 struct st_cmdstatus *cmdstatp = &STp->buffer->cmdstat;
1896
1897 retval = 1;
1898 DEBC(printk(ST_DEB_MSG "%s: Sense: %2x %2x %2x %2x %2x %2x %2x %2x\n",
1899 name,
Mike Christie8b05b772005-11-08 04:06:44 -06001900 SRpnt->sense[0], SRpnt->sense[1],
1901 SRpnt->sense[2], SRpnt->sense[3],
1902 SRpnt->sense[4], SRpnt->sense[5],
1903 SRpnt->sense[6], SRpnt->sense[7]));
Linus Torvalds1da177e2005-04-16 15:20:36 -07001904 if (cmdstatp->have_sense) {
1905
1906 if (cmdstatp->sense_hdr.sense_key == BLANK_CHECK)
1907 cmdstatp->flags &= 0xcf; /* No need for EOM in this case */
1908
1909 if (cmdstatp->flags != 0) { /* EOF, EOM, or ILI */
1910 /* Compute the residual count */
1911 if (cmdstatp->remainder_valid)
1912 transfer = (int)cmdstatp->uremainder64;
1913 else
1914 transfer = 0;
1915 if (STp->block_size == 0 &&
1916 cmdstatp->sense_hdr.sense_key == MEDIUM_ERROR)
1917 transfer = bytes;
1918
1919 if (cmdstatp->flags & SENSE_ILI) { /* ILI */
1920 if (STp->block_size == 0) {
1921 if (transfer <= 0) {
1922 if (transfer < 0)
1923 printk(KERN_NOTICE
1924 "%s: Failed to read %d byte block with %d byte transfer.\n",
1925 name, bytes - transfer, bytes);
1926 if (STps->drv_block >= 0)
1927 STps->drv_block += 1;
1928 STbp->buffer_bytes = 0;
1929 return (-ENOMEM);
1930 }
1931 STbp->buffer_bytes = bytes - transfer;
1932 } else {
Mike Christie8b05b772005-11-08 04:06:44 -06001933 st_release_request(SRpnt);
Linus Torvalds1da177e2005-04-16 15:20:36 -07001934 SRpnt = *aSRpnt = NULL;
1935 if (transfer == blks) { /* We did not get anything, error */
1936 printk(KERN_NOTICE "%s: Incorrect block size.\n", name);
1937 if (STps->drv_block >= 0)
1938 STps->drv_block += blks - transfer + 1;
1939 st_int_ioctl(STp, MTBSR, 1);
1940 return (-EIO);
1941 }
1942 /* We have some data, deliver it */
1943 STbp->buffer_bytes = (blks - transfer) *
1944 STp->block_size;
1945 DEBC(printk(ST_DEB_MSG
1946 "%s: ILI but enough data received %ld %d.\n",
1947 name, count, STbp->buffer_bytes));
1948 if (STps->drv_block >= 0)
1949 STps->drv_block += 1;
1950 if (st_int_ioctl(STp, MTBSR, 1))
1951 return (-EIO);
1952 }
1953 } else if (cmdstatp->flags & SENSE_FMK) { /* FM overrides EOM */
1954 if (STps->eof != ST_FM_HIT)
1955 STps->eof = ST_FM_HIT;
1956 else
1957 STps->eof = ST_EOD_2;
1958 if (STp->block_size == 0)
1959 STbp->buffer_bytes = 0;
1960 else
1961 STbp->buffer_bytes =
1962 bytes - transfer * STp->block_size;
1963 DEBC(printk(ST_DEB_MSG
1964 "%s: EOF detected (%d bytes read).\n",
1965 name, STbp->buffer_bytes));
1966 } else if (cmdstatp->flags & SENSE_EOM) {
1967 if (STps->eof == ST_FM)
1968 STps->eof = ST_EOD_1;
1969 else
1970 STps->eof = ST_EOM_OK;
1971 if (STp->block_size == 0)
1972 STbp->buffer_bytes = bytes - transfer;
1973 else
1974 STbp->buffer_bytes =
1975 bytes - transfer * STp->block_size;
1976
1977 DEBC(printk(ST_DEB_MSG "%s: EOM detected (%d bytes read).\n",
1978 name, STbp->buffer_bytes));
1979 }
1980 }
1981 /* end of EOF, EOM, ILI test */
1982 else { /* nonzero sense key */
1983 DEBC(printk(ST_DEB_MSG
1984 "%s: Tape error while reading.\n", name));
1985 STps->drv_block = (-1);
1986 if (STps->eof == ST_FM &&
1987 cmdstatp->sense_hdr.sense_key == BLANK_CHECK) {
1988 DEBC(printk(ST_DEB_MSG
1989 "%s: Zero returned for first BLANK CHECK after EOF.\n",
1990 name));
1991 STps->eof = ST_EOD_2; /* First BLANK_CHECK after FM */
1992 } else /* Some other extended sense code */
1993 retval = (-EIO);
1994 }
1995
1996 if (STbp->buffer_bytes < 0) /* Caused by bogus sense data */
1997 STbp->buffer_bytes = 0;
1998 }
1999 /* End of extended sense test */
2000 else { /* Non-extended sense */
2001 retval = STbp->syscall_result;
2002 }
2003
2004 }
2005 /* End of error handling */
Kai Makisara40f6b362008-02-24 22:23:24 +02002006 else { /* Read successful */
Linus Torvalds1da177e2005-04-16 15:20:36 -07002007 STbp->buffer_bytes = bytes;
Kai Makisara40f6b362008-02-24 22:23:24 +02002008 if (STp->sili) /* In fixed block mode residual is always zero here */
2009 STbp->buffer_bytes -= STp->buffer->cmdstat.residual;
2010 }
Linus Torvalds1da177e2005-04-16 15:20:36 -07002011
2012 if (STps->drv_block >= 0) {
2013 if (STp->block_size == 0)
2014 STps->drv_block++;
2015 else
2016 STps->drv_block += STbp->buffer_bytes / STp->block_size;
2017 }
2018 return retval;
2019}
2020
2021
2022/* Read command */
2023static ssize_t
2024st_read(struct file *filp, char __user *buf, size_t count, loff_t * ppos)
2025{
2026 ssize_t total;
2027 ssize_t retval = 0;
2028 ssize_t i, transfer;
2029 int special, do_dio = 0;
Mike Christie8b05b772005-11-08 04:06:44 -06002030 struct st_request *SRpnt = NULL;
Linus Torvalds1da177e2005-04-16 15:20:36 -07002031 struct scsi_tape *STp = filp->private_data;
2032 struct st_modedef *STm;
2033 struct st_partstat *STps;
2034 struct st_buffer *STbp = STp->buffer;
2035 DEB( char *name = tape_name(STp); )
2036
Matthias Kaehlcke28f85002007-07-29 23:38:15 +02002037 if (mutex_lock_interruptible(&STp->lock))
Linus Torvalds1da177e2005-04-16 15:20:36 -07002038 return -ERESTARTSYS;
2039
2040 retval = rw_checks(STp, filp, count);
2041 if (retval || count == 0)
2042 goto out;
2043
2044 STm = &(STp->modes[STp->current_mode]);
Kai Makisara9abe16c2007-02-03 13:21:29 +02002045 if (STp->block_size != 0 && (count % STp->block_size) != 0) {
2046 if (!STm->do_read_ahead) {
2047 retval = (-EINVAL); /* Read must be integral number of blocks */
2048 goto out;
2049 }
2050 STp->try_dio_now = 0; /* Direct i/o can't handle split blocks */
Linus Torvalds1da177e2005-04-16 15:20:36 -07002051 }
2052
2053 STps = &(STp->ps[STp->partition]);
2054 if (STps->rw == ST_WRITING) {
2055 retval = flush_buffer(STp, 0);
2056 if (retval)
2057 goto out;
2058 STps->rw = ST_READING;
2059 }
2060 DEB(
2061 if (debugging && STps->eof != ST_NOEOF)
2062 printk(ST_DEB_MSG "%s: EOF/EOM flag up (%d). Bytes %d\n", name,
2063 STps->eof, STbp->buffer_bytes);
2064 ) /* end DEB */
2065
2066 retval = setup_buffering(STp, buf, count, 1);
2067 if (retval)
2068 goto out;
2069 do_dio = STbp->do_dio;
2070
2071 if (STbp->buffer_bytes == 0 &&
2072 STps->eof >= ST_EOD_1) {
2073 if (STps->eof < ST_EOD) {
2074 STps->eof += 1;
2075 retval = 0;
2076 goto out;
2077 }
2078 retval = (-EIO); /* EOM or Blank Check */
2079 goto out;
2080 }
2081
2082 if (do_dio) {
2083 /* Check the buffer writability before any tape movement. Don't alter
2084 buffer data. */
2085 if (copy_from_user(&i, buf, 1) != 0 ||
2086 copy_to_user(buf, &i, 1) != 0 ||
2087 copy_from_user(&i, buf + count - 1, 1) != 0 ||
2088 copy_to_user(buf + count - 1, &i, 1) != 0) {
2089 retval = (-EFAULT);
2090 goto out;
2091 }
2092 }
2093
2094 STps->rw = ST_READING;
2095
2096
2097 /* Loop until enough data in buffer or a special condition found */
2098 for (total = 0, special = 0; total < count && !special;) {
2099
2100 /* Get new data if the buffer is empty */
2101 if (STbp->buffer_bytes == 0) {
2102 special = read_tape(STp, count - total, &SRpnt);
2103 if (special < 0) { /* No need to continue read */
2104 retval = special;
2105 goto out;
2106 }
2107 }
2108
2109 /* Move the data from driver buffer to user buffer */
2110 if (STbp->buffer_bytes > 0) {
2111 DEB(
2112 if (debugging && STps->eof != ST_NOEOF)
2113 printk(ST_DEB_MSG
2114 "%s: EOF up (%d). Left %d, needed %d.\n", name,
2115 STps->eof, STbp->buffer_bytes,
2116 (int)(count - total));
2117 ) /* end DEB */
2118 transfer = STbp->buffer_bytes < count - total ?
2119 STbp->buffer_bytes : count - total;
2120 if (!do_dio) {
2121 i = from_buffer(STbp, buf, transfer);
2122 if (i) {
2123 retval = i;
2124 goto out;
2125 }
2126 }
2127 buf += transfer;
2128 total += transfer;
2129 }
2130
2131 if (STp->block_size == 0)
2132 break; /* Read only one variable length block */
2133
2134 } /* for (total = 0, special = 0;
2135 total < count && !special; ) */
2136
2137 /* Change the eof state if no data from tape or buffer */
2138 if (total == 0) {
2139 if (STps->eof == ST_FM_HIT) {
2140 STps->eof = ST_FM;
2141 STps->drv_block = 0;
2142 if (STps->drv_file >= 0)
2143 STps->drv_file++;
2144 } else if (STps->eof == ST_EOD_1) {
2145 STps->eof = ST_EOD_2;
2146 STps->drv_block = 0;
2147 if (STps->drv_file >= 0)
2148 STps->drv_file++;
2149 } else if (STps->eof == ST_EOD_2)
2150 STps->eof = ST_EOD;
2151 } else if (STps->eof == ST_FM)
2152 STps->eof = ST_NOEOF;
2153 retval = total;
2154
2155 out:
2156 if (SRpnt != NULL) {
Mike Christie8b05b772005-11-08 04:06:44 -06002157 st_release_request(SRpnt);
Linus Torvalds1da177e2005-04-16 15:20:36 -07002158 SRpnt = NULL;
2159 }
2160 if (do_dio) {
Kai Makisara787926b2005-11-13 10:04:44 +02002161 release_buffering(STp, 1);
Linus Torvalds1da177e2005-04-16 15:20:36 -07002162 STbp->buffer_bytes = 0;
2163 }
Matthias Kaehlcke28f85002007-07-29 23:38:15 +02002164 mutex_unlock(&STp->lock);
Linus Torvalds1da177e2005-04-16 15:20:36 -07002165
2166 return retval;
2167}
2168
2169
2170
2171DEB(
2172/* Set the driver options */
2173static void st_log_options(struct scsi_tape * STp, struct st_modedef * STm, char *name)
2174{
2175 if (debugging) {
2176 printk(KERN_INFO
2177 "%s: Mode %d options: buffer writes: %d, async writes: %d, read ahead: %d\n",
2178 name, STp->current_mode, STm->do_buffer_writes, STm->do_async_writes,
2179 STm->do_read_ahead);
2180 printk(KERN_INFO
2181 "%s: can bsr: %d, two FMs: %d, fast mteom: %d, auto lock: %d,\n",
2182 name, STp->can_bsr, STp->two_fm, STp->fast_mteom, STp->do_auto_lock);
2183 printk(KERN_INFO
2184 "%s: defs for wr: %d, no block limits: %d, partitions: %d, s2 log: %d\n",
2185 name, STm->defaults_for_writes, STp->omit_blklims, STp->can_partitions,
2186 STp->scsi2_logical);
2187 printk(KERN_INFO
Lee Duncanc743e442012-03-01 12:41:01 -08002188 "%s: sysv: %d nowait: %d sili: %d nowait_filemark: %d\n",
2189 name, STm->sysv, STp->immediate, STp->sili,
2190 STp->immediate_filemark);
Linus Torvalds1da177e2005-04-16 15:20:36 -07002191 printk(KERN_INFO "%s: debugging: %d\n",
2192 name, debugging);
2193 }
2194}
2195 )
2196
2197
2198static int st_set_options(struct scsi_tape *STp, long options)
2199{
2200 int value;
2201 long code;
2202 struct st_modedef *STm;
2203 char *name = tape_name(STp);
2204 struct cdev *cd0, *cd1;
2205
2206 STm = &(STp->modes[STp->current_mode]);
2207 if (!STm->defined) {
2208 cd0 = STm->cdevs[0]; cd1 = STm->cdevs[1];
2209 memcpy(STm, &(STp->modes[0]), sizeof(struct st_modedef));
2210 STm->cdevs[0] = cd0; STm->cdevs[1] = cd1;
2211 modes_defined = 1;
2212 DEBC(printk(ST_DEB_MSG
2213 "%s: Initialized mode %d definition from mode 0\n",
2214 name, STp->current_mode));
2215 }
2216
2217 code = options & MT_ST_OPTIONS;
2218 if (code == MT_ST_BOOLEANS) {
2219 STm->do_buffer_writes = (options & MT_ST_BUFFER_WRITES) != 0;
2220 STm->do_async_writes = (options & MT_ST_ASYNC_WRITES) != 0;
2221 STm->defaults_for_writes = (options & MT_ST_DEF_WRITES) != 0;
2222 STm->do_read_ahead = (options & MT_ST_READ_AHEAD) != 0;
2223 STp->two_fm = (options & MT_ST_TWO_FM) != 0;
2224 STp->fast_mteom = (options & MT_ST_FAST_MTEOM) != 0;
2225 STp->do_auto_lock = (options & MT_ST_AUTO_LOCK) != 0;
2226 STp->can_bsr = (options & MT_ST_CAN_BSR) != 0;
2227 STp->omit_blklims = (options & MT_ST_NO_BLKLIMS) != 0;
2228 if ((STp->device)->scsi_level >= SCSI_2)
2229 STp->can_partitions = (options & MT_ST_CAN_PARTITIONS) != 0;
2230 STp->scsi2_logical = (options & MT_ST_SCSI2LOGICAL) != 0;
2231 STp->immediate = (options & MT_ST_NOWAIT) != 0;
Lee Duncanc743e442012-03-01 12:41:01 -08002232 STp->immediate_filemark = (options & MT_ST_NOWAIT_EOF) != 0;
Linus Torvalds1da177e2005-04-16 15:20:36 -07002233 STm->sysv = (options & MT_ST_SYSV) != 0;
Kai Makisara40f6b362008-02-24 22:23:24 +02002234 STp->sili = (options & MT_ST_SILI) != 0;
Linus Torvalds1da177e2005-04-16 15:20:36 -07002235 DEB( debugging = (options & MT_ST_DEBUGGING) != 0;
2236 st_log_options(STp, STm, name); )
2237 } else if (code == MT_ST_SETBOOLEANS || code == MT_ST_CLEARBOOLEANS) {
2238 value = (code == MT_ST_SETBOOLEANS);
2239 if ((options & MT_ST_BUFFER_WRITES) != 0)
2240 STm->do_buffer_writes = value;
2241 if ((options & MT_ST_ASYNC_WRITES) != 0)
2242 STm->do_async_writes = value;
2243 if ((options & MT_ST_DEF_WRITES) != 0)
2244 STm->defaults_for_writes = value;
2245 if ((options & MT_ST_READ_AHEAD) != 0)
2246 STm->do_read_ahead = value;
2247 if ((options & MT_ST_TWO_FM) != 0)
2248 STp->two_fm = value;
2249 if ((options & MT_ST_FAST_MTEOM) != 0)
2250 STp->fast_mteom = value;
2251 if ((options & MT_ST_AUTO_LOCK) != 0)
2252 STp->do_auto_lock = value;
2253 if ((options & MT_ST_CAN_BSR) != 0)
2254 STp->can_bsr = value;
2255 if ((options & MT_ST_NO_BLKLIMS) != 0)
2256 STp->omit_blklims = value;
2257 if ((STp->device)->scsi_level >= SCSI_2 &&
2258 (options & MT_ST_CAN_PARTITIONS) != 0)
2259 STp->can_partitions = value;
2260 if ((options & MT_ST_SCSI2LOGICAL) != 0)
2261 STp->scsi2_logical = value;
2262 if ((options & MT_ST_NOWAIT) != 0)
2263 STp->immediate = value;
Lee Duncanc743e442012-03-01 12:41:01 -08002264 if ((options & MT_ST_NOWAIT_EOF) != 0)
2265 STp->immediate_filemark = value;
Linus Torvalds1da177e2005-04-16 15:20:36 -07002266 if ((options & MT_ST_SYSV) != 0)
2267 STm->sysv = value;
Kai Makisara40f6b362008-02-24 22:23:24 +02002268 if ((options & MT_ST_SILI) != 0)
2269 STp->sili = value;
Linus Torvalds1da177e2005-04-16 15:20:36 -07002270 DEB(
2271 if ((options & MT_ST_DEBUGGING) != 0)
2272 debugging = value;
2273 st_log_options(STp, STm, name); )
2274 } else if (code == MT_ST_WRITE_THRESHOLD) {
2275 /* Retained for compatibility */
2276 } else if (code == MT_ST_DEF_BLKSIZE) {
2277 value = (options & ~MT_ST_OPTIONS);
2278 if (value == ~MT_ST_OPTIONS) {
2279 STm->default_blksize = (-1);
2280 DEBC( printk(KERN_INFO "%s: Default block size disabled.\n", name));
2281 } else {
2282 STm->default_blksize = value;
2283 DEBC( printk(KERN_INFO "%s: Default block size set to %d bytes.\n",
2284 name, STm->default_blksize));
2285 if (STp->ready == ST_READY) {
2286 STp->blksize_changed = 0;
2287 set_mode_densblk(STp, STm);
2288 }
2289 }
2290 } else if (code == MT_ST_TIMEOUTS) {
2291 value = (options & ~MT_ST_OPTIONS);
2292 if ((value & MT_ST_SET_LONG_TIMEOUT) != 0) {
2293 STp->long_timeout = (value & ~MT_ST_SET_LONG_TIMEOUT) * HZ;
2294 DEBC( printk(KERN_INFO "%s: Long timeout set to %d seconds.\n", name,
2295 (value & ~MT_ST_SET_LONG_TIMEOUT)));
2296 } else {
James Bottomleya02488e2008-11-30 10:36:26 -06002297 blk_queue_rq_timeout(STp->device->request_queue,
2298 value * HZ);
Linus Torvalds1da177e2005-04-16 15:20:36 -07002299 DEBC( printk(KERN_INFO "%s: Normal timeout set to %d seconds.\n",
2300 name, value) );
2301 }
2302 } else if (code == MT_ST_SET_CLN) {
2303 value = (options & ~MT_ST_OPTIONS) & 0xff;
2304 if (value != 0 &&
Roel Kluin832151f2009-11-17 14:53:22 -08002305 (value < EXTENDED_SENSE_START ||
2306 value >= SCSI_SENSE_BUFFERSIZE))
Linus Torvalds1da177e2005-04-16 15:20:36 -07002307 return (-EINVAL);
2308 STp->cln_mode = value;
2309 STp->cln_sense_mask = (options >> 8) & 0xff;
2310 STp->cln_sense_value = (options >> 16) & 0xff;
2311 printk(KERN_INFO
2312 "%s: Cleaning request mode %d, mask %02x, value %02x\n",
2313 name, value, STp->cln_sense_mask, STp->cln_sense_value);
2314 } else if (code == MT_ST_DEF_OPTIONS) {
2315 code = (options & ~MT_ST_CLEAR_DEFAULT);
2316 value = (options & MT_ST_CLEAR_DEFAULT);
2317 if (code == MT_ST_DEF_DENSITY) {
2318 if (value == MT_ST_CLEAR_DEFAULT) {
2319 STm->default_density = (-1);
2320 DEBC( printk(KERN_INFO "%s: Density default disabled.\n",
2321 name));
2322 } else {
2323 STm->default_density = value & 0xff;
2324 DEBC( printk(KERN_INFO "%s: Density default set to %x\n",
2325 name, STm->default_density));
2326 if (STp->ready == ST_READY) {
2327 STp->density_changed = 0;
2328 set_mode_densblk(STp, STm);
2329 }
2330 }
2331 } else if (code == MT_ST_DEF_DRVBUFFER) {
2332 if (value == MT_ST_CLEAR_DEFAULT) {
2333 STp->default_drvbuffer = 0xff;
2334 DEBC( printk(KERN_INFO
2335 "%s: Drive buffer default disabled.\n", name));
2336 } else {
2337 STp->default_drvbuffer = value & 7;
2338 DEBC( printk(KERN_INFO
2339 "%s: Drive buffer default set to %x\n",
2340 name, STp->default_drvbuffer));
2341 if (STp->ready == ST_READY)
2342 st_int_ioctl(STp, MTSETDRVBUFFER, STp->default_drvbuffer);
2343 }
2344 } else if (code == MT_ST_DEF_COMPRESSION) {
2345 if (value == MT_ST_CLEAR_DEFAULT) {
2346 STm->default_compression = ST_DONT_TOUCH;
2347 DEBC( printk(KERN_INFO
2348 "%s: Compression default disabled.\n", name));
2349 } else {
2350 if ((value & 0xff00) != 0) {
2351 STp->c_algo = (value & 0xff00) >> 8;
2352 DEBC( printk(KERN_INFO "%s: Compression algorithm set to 0x%x.\n",
2353 name, STp->c_algo));
2354 }
2355 if ((value & 0xff) != 0xff) {
2356 STm->default_compression = (value & 1 ? ST_YES : ST_NO);
2357 DEBC( printk(KERN_INFO "%s: Compression default set to %x\n",
2358 name, (value & 1)));
2359 if (STp->ready == ST_READY) {
2360 STp->compression_changed = 0;
2361 st_compression(STp, (STm->default_compression == ST_YES));
2362 }
2363 }
2364 }
2365 }
2366 } else
2367 return (-EIO);
2368
2369 return 0;
2370}
2371
2372#define MODE_HEADER_LENGTH 4
2373
2374/* Mode header and page byte offsets */
2375#define MH_OFF_DATA_LENGTH 0
2376#define MH_OFF_MEDIUM_TYPE 1
2377#define MH_OFF_DEV_SPECIFIC 2
2378#define MH_OFF_BDESCS_LENGTH 3
2379#define MP_OFF_PAGE_NBR 0
2380#define MP_OFF_PAGE_LENGTH 1
2381
2382/* Mode header and page bit masks */
2383#define MH_BIT_WP 0x80
2384#define MP_MSK_PAGE_NBR 0x3f
2385
2386/* Don't return block descriptors */
2387#define MODE_SENSE_OMIT_BDESCS 0x08
2388
2389#define MODE_SELECT_PAGE_FORMAT 0x10
2390
2391/* Read a mode page into the tape buffer. The block descriptors are included
2392 if incl_block_descs is true. The page control is ored to the page number
2393 parameter, if necessary. */
2394static int read_mode_page(struct scsi_tape *STp, int page, int omit_block_descs)
2395{
2396 unsigned char cmd[MAX_COMMAND_SIZE];
FUJITA Tomonori8ecf0d92008-12-05 15:25:28 +09002397 struct st_request *SRpnt;
Linus Torvalds1da177e2005-04-16 15:20:36 -07002398
2399 memset(cmd, 0, MAX_COMMAND_SIZE);
2400 cmd[0] = MODE_SENSE;
2401 if (omit_block_descs)
2402 cmd[1] = MODE_SENSE_OMIT_BDESCS;
2403 cmd[2] = page;
2404 cmd[4] = 255;
2405
Kai Makisara02ae2c02008-12-18 14:49:50 +09002406 SRpnt = st_do_scsi(NULL, STp, cmd, cmd[4], DMA_FROM_DEVICE,
2407 STp->device->request_queue->rq_timeout, 0, 1);
2408 if (SRpnt == NULL)
2409 return (STp->buffer)->syscall_result;
Linus Torvalds1da177e2005-04-16 15:20:36 -07002410
Mike Christie8b05b772005-11-08 04:06:44 -06002411 st_release_request(SRpnt);
Linus Torvalds1da177e2005-04-16 15:20:36 -07002412
Kai Makisara02ae2c02008-12-18 14:49:50 +09002413 return STp->buffer->syscall_result;
Linus Torvalds1da177e2005-04-16 15:20:36 -07002414}
2415
2416
2417/* Send the mode page in the tape buffer to the drive. Assumes that the mode data
2418 in the buffer is correctly formatted. The long timeout is used if slow is non-zero. */
2419static int write_mode_page(struct scsi_tape *STp, int page, int slow)
2420{
Kai Makisara02ae2c02008-12-18 14:49:50 +09002421 int pgo;
Linus Torvalds1da177e2005-04-16 15:20:36 -07002422 unsigned char cmd[MAX_COMMAND_SIZE];
FUJITA Tomonori18c87012008-12-05 15:25:29 +09002423 struct st_request *SRpnt;
Kai Makisara02ae2c02008-12-18 14:49:50 +09002424 int timeout;
Linus Torvalds1da177e2005-04-16 15:20:36 -07002425
2426 memset(cmd, 0, MAX_COMMAND_SIZE);
2427 cmd[0] = MODE_SELECT;
2428 cmd[1] = MODE_SELECT_PAGE_FORMAT;
2429 pgo = MODE_HEADER_LENGTH + (STp->buffer)->b_data[MH_OFF_BDESCS_LENGTH];
2430 cmd[4] = pgo + (STp->buffer)->b_data[pgo + MP_OFF_PAGE_LENGTH] + 2;
2431
2432 /* Clear reserved fields */
2433 (STp->buffer)->b_data[MH_OFF_DATA_LENGTH] = 0;
2434 (STp->buffer)->b_data[MH_OFF_MEDIUM_TYPE] = 0;
2435 (STp->buffer)->b_data[MH_OFF_DEV_SPECIFIC] &= ~MH_BIT_WP;
2436 (STp->buffer)->b_data[pgo + MP_OFF_PAGE_NBR] &= MP_MSK_PAGE_NBR;
2437
Kai Makisara02ae2c02008-12-18 14:49:50 +09002438 timeout = slow ?
2439 STp->long_timeout : STp->device->request_queue->rq_timeout;
2440 SRpnt = st_do_scsi(NULL, STp, cmd, cmd[4], DMA_TO_DEVICE,
2441 timeout, 0, 1);
2442 if (SRpnt == NULL)
2443 return (STp->buffer)->syscall_result;
Linus Torvalds1da177e2005-04-16 15:20:36 -07002444
Mike Christie8b05b772005-11-08 04:06:44 -06002445 st_release_request(SRpnt);
Linus Torvalds1da177e2005-04-16 15:20:36 -07002446
Kai Makisara02ae2c02008-12-18 14:49:50 +09002447 return STp->buffer->syscall_result;
Linus Torvalds1da177e2005-04-16 15:20:36 -07002448}
2449
2450
2451#define COMPRESSION_PAGE 0x0f
2452#define COMPRESSION_PAGE_LENGTH 16
2453
2454#define CP_OFF_DCE_DCC 2
2455#define CP_OFF_C_ALGO 7
2456
2457#define DCE_MASK 0x80
2458#define DCC_MASK 0x40
2459#define RED_MASK 0x60
2460
2461
2462/* Control the compression with mode page 15. Algorithm not changed if zero.
2463
2464 The block descriptors are read and written because Sony SDT-7000 does not
2465 work without this (suggestion from Michael Schaefer <Michael.Schaefer@dlr.de>).
2466 Including block descriptors should not cause any harm to other drives. */
2467
2468static int st_compression(struct scsi_tape * STp, int state)
2469{
2470 int retval;
2471 int mpoffs; /* Offset to mode page start */
2472 unsigned char *b_data = (STp->buffer)->b_data;
2473 DEB( char *name = tape_name(STp); )
2474
2475 if (STp->ready != ST_READY)
2476 return (-EIO);
2477
2478 /* Read the current page contents */
2479 retval = read_mode_page(STp, COMPRESSION_PAGE, 0);
2480 if (retval) {
2481 DEBC(printk(ST_DEB_MSG "%s: Compression mode page not supported.\n",
2482 name));
2483 return (-EIO);
2484 }
2485
2486 mpoffs = MODE_HEADER_LENGTH + b_data[MH_OFF_BDESCS_LENGTH];
2487 DEBC(printk(ST_DEB_MSG "%s: Compression state is %d.\n", name,
2488 (b_data[mpoffs + CP_OFF_DCE_DCC] & DCE_MASK ? 1 : 0)));
2489
2490 /* Check if compression can be changed */
2491 if ((b_data[mpoffs + CP_OFF_DCE_DCC] & DCC_MASK) == 0) {
2492 DEBC(printk(ST_DEB_MSG "%s: Compression not supported.\n", name));
2493 return (-EIO);
2494 }
2495
2496 /* Do the change */
2497 if (state) {
2498 b_data[mpoffs + CP_OFF_DCE_DCC] |= DCE_MASK;
2499 if (STp->c_algo != 0)
2500 b_data[mpoffs + CP_OFF_C_ALGO] = STp->c_algo;
2501 }
2502 else {
2503 b_data[mpoffs + CP_OFF_DCE_DCC] &= ~DCE_MASK;
2504 if (STp->c_algo != 0)
2505 b_data[mpoffs + CP_OFF_C_ALGO] = 0; /* no compression */
2506 }
2507
2508 retval = write_mode_page(STp, COMPRESSION_PAGE, 0);
2509 if (retval) {
2510 DEBC(printk(ST_DEB_MSG "%s: Compression change failed.\n", name));
2511 return (-EIO);
2512 }
2513 DEBC(printk(ST_DEB_MSG "%s: Compression state changed to %d.\n",
2514 name, state));
2515
2516 STp->compression_changed = 1;
2517 return 0;
2518}
2519
2520
2521/* Process the load and unload commands (does unload if the load code is zero) */
2522static int do_load_unload(struct scsi_tape *STp, struct file *filp, int load_code)
2523{
2524 int retval = (-EIO), timeout;
2525 DEB( char *name = tape_name(STp); )
2526 unsigned char cmd[MAX_COMMAND_SIZE];
2527 struct st_partstat *STps;
Mike Christie8b05b772005-11-08 04:06:44 -06002528 struct st_request *SRpnt;
Linus Torvalds1da177e2005-04-16 15:20:36 -07002529
2530 if (STp->ready != ST_READY && !load_code) {
2531 if (STp->ready == ST_NO_TAPE)
2532 return (-ENOMEDIUM);
2533 else
2534 return (-EIO);
2535 }
2536
2537 memset(cmd, 0, MAX_COMMAND_SIZE);
2538 cmd[0] = START_STOP;
2539 if (load_code)
2540 cmd[4] |= 1;
2541 /*
2542 * If arg >= 1 && arg <= 6 Enhanced load/unload in HP C1553A
2543 */
2544 if (load_code >= 1 + MT_ST_HPLOADER_OFFSET
2545 && load_code <= 6 + MT_ST_HPLOADER_OFFSET) {
2546 DEBC(printk(ST_DEB_MSG "%s: Enhanced %sload slot %2d.\n",
2547 name, (cmd[4]) ? "" : "un",
2548 load_code - MT_ST_HPLOADER_OFFSET));
2549 cmd[3] = load_code - MT_ST_HPLOADER_OFFSET; /* MediaID field of C1553A */
2550 }
2551 if (STp->immediate) {
2552 cmd[1] = 1; /* Don't wait for completion */
James Bottomleya02488e2008-11-30 10:36:26 -06002553 timeout = STp->device->request_queue->rq_timeout;
Linus Torvalds1da177e2005-04-16 15:20:36 -07002554 }
2555 else
2556 timeout = STp->long_timeout;
2557
2558 DEBC(
2559 if (!load_code)
2560 printk(ST_DEB_MSG "%s: Unloading tape.\n", name);
2561 else
2562 printk(ST_DEB_MSG "%s: Loading tape.\n", name);
2563 );
2564
Kai Makisara02ae2c02008-12-18 14:49:50 +09002565 SRpnt = st_do_scsi(NULL, STp, cmd, 0, DMA_NONE,
2566 timeout, MAX_RETRIES, 1);
Linus Torvalds1da177e2005-04-16 15:20:36 -07002567 if (!SRpnt)
Kai Makisara02ae2c02008-12-18 14:49:50 +09002568 return (STp->buffer)->syscall_result;
Linus Torvalds1da177e2005-04-16 15:20:36 -07002569
2570 retval = (STp->buffer)->syscall_result;
Kai Makisara02ae2c02008-12-18 14:49:50 +09002571 st_release_request(SRpnt);
Linus Torvalds1da177e2005-04-16 15:20:36 -07002572
2573 if (!retval) { /* SCSI command successful */
2574
2575 if (!load_code) {
2576 STp->rew_at_close = 0;
2577 STp->ready = ST_NO_TAPE;
2578 }
2579 else {
2580 STp->rew_at_close = STp->autorew_dev;
2581 retval = check_tape(STp, filp);
2582 if (retval > 0)
2583 retval = 0;
2584 }
2585 }
2586 else {
2587 STps = &(STp->ps[STp->partition]);
2588 STps->drv_file = STps->drv_block = (-1);
2589 }
2590
2591 return retval;
2592}
2593
2594#if DEBUG
2595#define ST_DEB_FORWARD 0
2596#define ST_DEB_BACKWARD 1
2597static void deb_space_print(char *name, int direction, char *units, unsigned char *cmd)
2598{
2599 s32 sc;
2600
2601 sc = cmd[2] & 0x80 ? 0xff000000 : 0;
2602 sc |= (cmd[2] << 16) | (cmd[3] << 8) | cmd[4];
2603 if (direction)
2604 sc = -sc;
2605 printk(ST_DEB_MSG "%s: Spacing tape %s over %d %s.\n", name,
2606 direction ? "backward" : "forward", sc, units);
2607}
2608#endif
2609
2610
2611/* Internal ioctl function */
2612static int st_int_ioctl(struct scsi_tape *STp, unsigned int cmd_in, unsigned long arg)
2613{
2614 int timeout;
2615 long ltmp;
2616 int ioctl_result;
2617 int chg_eof = 1;
2618 unsigned char cmd[MAX_COMMAND_SIZE];
Mike Christie8b05b772005-11-08 04:06:44 -06002619 struct st_request *SRpnt;
Linus Torvalds1da177e2005-04-16 15:20:36 -07002620 struct st_partstat *STps;
2621 int fileno, blkno, at_sm, undone;
2622 int datalen = 0, direction = DMA_NONE;
2623 char *name = tape_name(STp);
2624
2625 WARN_ON(STp->buffer->do_dio != 0);
2626 if (STp->ready != ST_READY) {
2627 if (STp->ready == ST_NO_TAPE)
2628 return (-ENOMEDIUM);
2629 else
2630 return (-EIO);
2631 }
2632 timeout = STp->long_timeout;
2633 STps = &(STp->ps[STp->partition]);
2634 fileno = STps->drv_file;
2635 blkno = STps->drv_block;
2636 at_sm = STps->at_sm;
2637
2638 memset(cmd, 0, MAX_COMMAND_SIZE);
2639 switch (cmd_in) {
2640 case MTFSFM:
2641 chg_eof = 0; /* Changed from the FSF after this */
2642 case MTFSF:
2643 cmd[0] = SPACE;
2644 cmd[1] = 0x01; /* Space FileMarks */
2645 cmd[2] = (arg >> 16);
2646 cmd[3] = (arg >> 8);
2647 cmd[4] = arg;
2648 DEBC(deb_space_print(name, ST_DEB_FORWARD, "filemarks", cmd);)
2649 if (fileno >= 0)
2650 fileno += arg;
2651 blkno = 0;
2652 at_sm &= (arg == 0);
2653 break;
2654 case MTBSFM:
2655 chg_eof = 0; /* Changed from the FSF after this */
2656 case MTBSF:
2657 cmd[0] = SPACE;
2658 cmd[1] = 0x01; /* Space FileMarks */
2659 ltmp = (-arg);
2660 cmd[2] = (ltmp >> 16);
2661 cmd[3] = (ltmp >> 8);
2662 cmd[4] = ltmp;
2663 DEBC(deb_space_print(name, ST_DEB_BACKWARD, "filemarks", cmd);)
2664 if (fileno >= 0)
2665 fileno -= arg;
2666 blkno = (-1); /* We can't know the block number */
2667 at_sm &= (arg == 0);
2668 break;
2669 case MTFSR:
2670 cmd[0] = SPACE;
2671 cmd[1] = 0x00; /* Space Blocks */
2672 cmd[2] = (arg >> 16);
2673 cmd[3] = (arg >> 8);
2674 cmd[4] = arg;
2675 DEBC(deb_space_print(name, ST_DEB_FORWARD, "blocks", cmd);)
2676 if (blkno >= 0)
2677 blkno += arg;
2678 at_sm &= (arg == 0);
2679 break;
2680 case MTBSR:
2681 cmd[0] = SPACE;
2682 cmd[1] = 0x00; /* Space Blocks */
2683 ltmp = (-arg);
2684 cmd[2] = (ltmp >> 16);
2685 cmd[3] = (ltmp >> 8);
2686 cmd[4] = ltmp;
2687 DEBC(deb_space_print(name, ST_DEB_BACKWARD, "blocks", cmd);)
2688 if (blkno >= 0)
2689 blkno -= arg;
2690 at_sm &= (arg == 0);
2691 break;
2692 case MTFSS:
2693 cmd[0] = SPACE;
2694 cmd[1] = 0x04; /* Space Setmarks */
2695 cmd[2] = (arg >> 16);
2696 cmd[3] = (arg >> 8);
2697 cmd[4] = arg;
2698 DEBC(deb_space_print(name, ST_DEB_FORWARD, "setmarks", cmd);)
2699 if (arg != 0) {
2700 blkno = fileno = (-1);
2701 at_sm = 1;
2702 }
2703 break;
2704 case MTBSS:
2705 cmd[0] = SPACE;
2706 cmd[1] = 0x04; /* Space Setmarks */
2707 ltmp = (-arg);
2708 cmd[2] = (ltmp >> 16);
2709 cmd[3] = (ltmp >> 8);
2710 cmd[4] = ltmp;
2711 DEBC(deb_space_print(name, ST_DEB_BACKWARD, "setmarks", cmd);)
2712 if (arg != 0) {
2713 blkno = fileno = (-1);
2714 at_sm = 1;
2715 }
2716 break;
2717 case MTWEOF:
Kai Makisara3e51d3c2010-10-09 00:17:56 +03002718 case MTWEOFI:
Linus Torvalds1da177e2005-04-16 15:20:36 -07002719 case MTWSM:
2720 if (STp->write_prot)
2721 return (-EACCES);
2722 cmd[0] = WRITE_FILEMARKS;
2723 if (cmd_in == MTWSM)
2724 cmd[1] = 2;
Lee Duncanc743e442012-03-01 12:41:01 -08002725 if (cmd_in == MTWEOFI ||
2726 (cmd_in == MTWEOF && STp->immediate_filemark))
Kai Makisara3e51d3c2010-10-09 00:17:56 +03002727 cmd[1] |= 1;
Linus Torvalds1da177e2005-04-16 15:20:36 -07002728 cmd[2] = (arg >> 16);
2729 cmd[3] = (arg >> 8);
2730 cmd[4] = arg;
James Bottomleya02488e2008-11-30 10:36:26 -06002731 timeout = STp->device->request_queue->rq_timeout;
Linus Torvalds1da177e2005-04-16 15:20:36 -07002732 DEBC(
Kai Makisara3e51d3c2010-10-09 00:17:56 +03002733 if (cmd_in != MTWSM)
Linus Torvalds1da177e2005-04-16 15:20:36 -07002734 printk(ST_DEB_MSG "%s: Writing %d filemarks.\n", name,
2735 cmd[2] * 65536 + cmd[3] * 256 + cmd[4]);
2736 else
2737 printk(ST_DEB_MSG "%s: Writing %d setmarks.\n", name,
2738 cmd[2] * 65536 + cmd[3] * 256 + cmd[4]);
2739 )
2740 if (fileno >= 0)
2741 fileno += arg;
2742 blkno = 0;
2743 at_sm = (cmd_in == MTWSM);
2744 break;
2745 case MTREW:
2746 cmd[0] = REZERO_UNIT;
2747 if (STp->immediate) {
2748 cmd[1] = 1; /* Don't wait for completion */
James Bottomleya02488e2008-11-30 10:36:26 -06002749 timeout = STp->device->request_queue->rq_timeout;
Linus Torvalds1da177e2005-04-16 15:20:36 -07002750 }
2751 DEBC(printk(ST_DEB_MSG "%s: Rewinding tape.\n", name));
2752 fileno = blkno = at_sm = 0;
2753 break;
2754 case MTNOP:
2755 DEBC(printk(ST_DEB_MSG "%s: No op on tape.\n", name));
2756 return 0; /* Should do something ? */
2757 break;
2758 case MTRETEN:
2759 cmd[0] = START_STOP;
2760 if (STp->immediate) {
2761 cmd[1] = 1; /* Don't wait for completion */
James Bottomleya02488e2008-11-30 10:36:26 -06002762 timeout = STp->device->request_queue->rq_timeout;
Linus Torvalds1da177e2005-04-16 15:20:36 -07002763 }
2764 cmd[4] = 3;
2765 DEBC(printk(ST_DEB_MSG "%s: Retensioning tape.\n", name));
2766 fileno = blkno = at_sm = 0;
2767 break;
2768 case MTEOM:
2769 if (!STp->fast_mteom) {
2770 /* space to the end of tape */
2771 ioctl_result = st_int_ioctl(STp, MTFSF, 0x7fffff);
2772 fileno = STps->drv_file;
2773 if (STps->eof >= ST_EOD_1)
2774 return 0;
2775 /* The next lines would hide the number of spaced FileMarks
2776 That's why I inserted the previous lines. I had no luck
2777 with detecting EOM with FSF, so we go now to EOM.
2778 Joerg Weule */
2779 } else
2780 fileno = (-1);
2781 cmd[0] = SPACE;
2782 cmd[1] = 3;
2783 DEBC(printk(ST_DEB_MSG "%s: Spacing to end of recorded medium.\n",
2784 name));
2785 blkno = -1;
2786 at_sm = 0;
2787 break;
2788 case MTERASE:
2789 if (STp->write_prot)
2790 return (-EACCES);
2791 cmd[0] = ERASE;
2792 cmd[1] = (arg ? 1 : 0); /* Long erase with non-zero argument */
2793 if (STp->immediate) {
2794 cmd[1] |= 2; /* Don't wait for completion */
James Bottomleya02488e2008-11-30 10:36:26 -06002795 timeout = STp->device->request_queue->rq_timeout;
Linus Torvalds1da177e2005-04-16 15:20:36 -07002796 }
2797 else
2798 timeout = STp->long_timeout * 8;
2799
2800 DEBC(printk(ST_DEB_MSG "%s: Erasing tape.\n", name));
2801 fileno = blkno = at_sm = 0;
2802 break;
2803 case MTSETBLK: /* Set block length */
2804 case MTSETDENSITY: /* Set tape density */
2805 case MTSETDRVBUFFER: /* Set drive buffering */
2806 case SET_DENS_AND_BLK: /* Set density and block size */
2807 chg_eof = 0;
2808 if (STp->dirty || (STp->buffer)->buffer_bytes != 0)
2809 return (-EIO); /* Not allowed if data in buffer */
2810 if ((cmd_in == MTSETBLK || cmd_in == SET_DENS_AND_BLK) &&
2811 (arg & MT_ST_BLKSIZE_MASK) != 0 &&
2812 STp->max_block > 0 &&
2813 ((arg & MT_ST_BLKSIZE_MASK) < STp->min_block ||
2814 (arg & MT_ST_BLKSIZE_MASK) > STp->max_block)) {
2815 printk(KERN_WARNING "%s: Illegal block size.\n", name);
2816 return (-EINVAL);
2817 }
2818 cmd[0] = MODE_SELECT;
2819 if ((STp->use_pf & USE_PF))
2820 cmd[1] = MODE_SELECT_PAGE_FORMAT;
2821 cmd[4] = datalen = 12;
2822 direction = DMA_TO_DEVICE;
2823
2824 memset((STp->buffer)->b_data, 0, 12);
2825 if (cmd_in == MTSETDRVBUFFER)
2826 (STp->buffer)->b_data[2] = (arg & 7) << 4;
2827 else
2828 (STp->buffer)->b_data[2] =
2829 STp->drv_buffer << 4;
2830 (STp->buffer)->b_data[3] = 8; /* block descriptor length */
2831 if (cmd_in == MTSETDENSITY) {
2832 (STp->buffer)->b_data[4] = arg;
2833 STp->density_changed = 1; /* At least we tried ;-) */
2834 } else if (cmd_in == SET_DENS_AND_BLK)
2835 (STp->buffer)->b_data[4] = arg >> 24;
2836 else
2837 (STp->buffer)->b_data[4] = STp->density;
2838 if (cmd_in == MTSETBLK || cmd_in == SET_DENS_AND_BLK) {
2839 ltmp = arg & MT_ST_BLKSIZE_MASK;
2840 if (cmd_in == MTSETBLK)
2841 STp->blksize_changed = 1; /* At least we tried ;-) */
2842 } else
2843 ltmp = STp->block_size;
2844 (STp->buffer)->b_data[9] = (ltmp >> 16);
2845 (STp->buffer)->b_data[10] = (ltmp >> 8);
2846 (STp->buffer)->b_data[11] = ltmp;
James Bottomleya02488e2008-11-30 10:36:26 -06002847 timeout = STp->device->request_queue->rq_timeout;
Linus Torvalds1da177e2005-04-16 15:20:36 -07002848 DEBC(
2849 if (cmd_in == MTSETBLK || cmd_in == SET_DENS_AND_BLK)
2850 printk(ST_DEB_MSG
2851 "%s: Setting block size to %d bytes.\n", name,
2852 (STp->buffer)->b_data[9] * 65536 +
2853 (STp->buffer)->b_data[10] * 256 +
2854 (STp->buffer)->b_data[11]);
2855 if (cmd_in == MTSETDENSITY || cmd_in == SET_DENS_AND_BLK)
2856 printk(ST_DEB_MSG
2857 "%s: Setting density code to %x.\n", name,
2858 (STp->buffer)->b_data[4]);
2859 if (cmd_in == MTSETDRVBUFFER)
2860 printk(ST_DEB_MSG
2861 "%s: Setting drive buffer code to %d.\n", name,
2862 ((STp->buffer)->b_data[2] >> 4) & 7);
2863 )
2864 break;
2865 default:
2866 return (-ENOSYS);
2867 }
2868
Kai Makisara02ae2c02008-12-18 14:49:50 +09002869 SRpnt = st_do_scsi(NULL, STp, cmd, datalen, direction,
2870 timeout, MAX_RETRIES, 1);
Linus Torvalds1da177e2005-04-16 15:20:36 -07002871 if (!SRpnt)
2872 return (STp->buffer)->syscall_result;
2873
Kai Makisara02ae2c02008-12-18 14:49:50 +09002874 ioctl_result = (STp->buffer)->syscall_result;
Linus Torvalds1da177e2005-04-16 15:20:36 -07002875
2876 if (!ioctl_result) { /* SCSI command successful */
Mike Christie8b05b772005-11-08 04:06:44 -06002877 st_release_request(SRpnt);
Linus Torvalds1da177e2005-04-16 15:20:36 -07002878 SRpnt = NULL;
2879 STps->drv_block = blkno;
2880 STps->drv_file = fileno;
2881 STps->at_sm = at_sm;
2882
2883 if (cmd_in == MTBSFM)
2884 ioctl_result = st_int_ioctl(STp, MTFSF, 1);
2885 else if (cmd_in == MTFSFM)
2886 ioctl_result = st_int_ioctl(STp, MTBSF, 1);
2887
2888 if (cmd_in == MTSETBLK || cmd_in == SET_DENS_AND_BLK) {
Linus Torvalds1da177e2005-04-16 15:20:36 -07002889 STp->block_size = arg & MT_ST_BLKSIZE_MASK;
2890 if (STp->block_size != 0) {
Linus Torvalds1da177e2005-04-16 15:20:36 -07002891 (STp->buffer)->buffer_blocks =
2892 (STp->buffer)->buffer_size / STp->block_size;
2893 }
2894 (STp->buffer)->buffer_bytes = (STp->buffer)->read_pointer = 0;
2895 if (cmd_in == SET_DENS_AND_BLK)
2896 STp->density = arg >> MT_ST_DENSITY_SHIFT;
2897 } else if (cmd_in == MTSETDRVBUFFER)
2898 STp->drv_buffer = (arg & 7);
2899 else if (cmd_in == MTSETDENSITY)
2900 STp->density = arg;
2901
2902 if (cmd_in == MTEOM)
2903 STps->eof = ST_EOD;
2904 else if (cmd_in == MTFSF)
2905 STps->eof = ST_FM;
2906 else if (chg_eof)
2907 STps->eof = ST_NOEOF;
2908
Kai Makisara3e51d3c2010-10-09 00:17:56 +03002909 if (cmd_in == MTWEOF || cmd_in == MTWEOFI)
2910 STps->rw = ST_IDLE; /* prevent automatic WEOF at close */
Linus Torvalds1da177e2005-04-16 15:20:36 -07002911 } else { /* SCSI command was not completely successful. Don't return
2912 from this block without releasing the SCSI command block! */
2913 struct st_cmdstatus *cmdstatp = &STp->buffer->cmdstat;
2914
2915 if (cmdstatp->flags & SENSE_EOM) {
2916 if (cmd_in != MTBSF && cmd_in != MTBSFM &&
2917 cmd_in != MTBSR && cmd_in != MTBSS)
2918 STps->eof = ST_EOM_OK;
2919 STps->drv_block = 0;
2920 }
2921
2922 if (cmdstatp->remainder_valid)
2923 undone = (int)cmdstatp->uremainder64;
2924 else
2925 undone = 0;
2926
Kai Makisara3e51d3c2010-10-09 00:17:56 +03002927 if ((cmd_in == MTWEOF || cmd_in == MTWEOFI) &&
Linus Torvalds1da177e2005-04-16 15:20:36 -07002928 cmdstatp->have_sense &&
Kai Makisara91614c02007-01-26 00:38:39 +02002929 (cmdstatp->flags & SENSE_EOM)) {
2930 if (cmdstatp->sense_hdr.sense_key == NO_SENSE ||
2931 cmdstatp->sense_hdr.sense_key == RECOVERED_ERROR) {
2932 ioctl_result = 0; /* EOF(s) written successfully at EOM */
2933 STps->eof = ST_NOEOF;
2934 } else { /* Writing EOF(s) failed */
2935 if (fileno >= 0)
2936 fileno -= undone;
2937 if (undone < arg)
2938 STps->eof = ST_NOEOF;
2939 }
Linus Torvalds1da177e2005-04-16 15:20:36 -07002940 STps->drv_file = fileno;
Linus Torvalds1da177e2005-04-16 15:20:36 -07002941 } else if ((cmd_in == MTFSF) || (cmd_in == MTFSFM)) {
2942 if (fileno >= 0)
2943 STps->drv_file = fileno - undone;
2944 else
2945 STps->drv_file = fileno;
2946 STps->drv_block = -1;
2947 STps->eof = ST_NOEOF;
2948 } else if ((cmd_in == MTBSF) || (cmd_in == MTBSFM)) {
2949 if (arg > 0 && undone < 0) /* Some drives get this wrong */
2950 undone = (-undone);
2951 if (STps->drv_file >= 0)
2952 STps->drv_file = fileno + undone;
2953 STps->drv_block = 0;
2954 STps->eof = ST_NOEOF;
2955 } else if (cmd_in == MTFSR) {
2956 if (cmdstatp->flags & SENSE_FMK) { /* Hit filemark */
2957 if (STps->drv_file >= 0)
2958 STps->drv_file++;
2959 STps->drv_block = 0;
2960 STps->eof = ST_FM;
2961 } else {
2962 if (blkno >= undone)
2963 STps->drv_block = blkno - undone;
2964 else
2965 STps->drv_block = (-1);
2966 STps->eof = ST_NOEOF;
2967 }
2968 } else if (cmd_in == MTBSR) {
2969 if (cmdstatp->flags & SENSE_FMK) { /* Hit filemark */
2970 STps->drv_file--;
2971 STps->drv_block = (-1);
2972 } else {
2973 if (arg > 0 && undone < 0) /* Some drives get this wrong */
2974 undone = (-undone);
2975 if (STps->drv_block >= 0)
2976 STps->drv_block = blkno + undone;
2977 }
2978 STps->eof = ST_NOEOF;
2979 } else if (cmd_in == MTEOM) {
2980 STps->drv_file = (-1);
2981 STps->drv_block = (-1);
2982 STps->eof = ST_EOD;
2983 } else if (cmd_in == MTSETBLK ||
2984 cmd_in == MTSETDENSITY ||
2985 cmd_in == MTSETDRVBUFFER ||
2986 cmd_in == SET_DENS_AND_BLK) {
2987 if (cmdstatp->sense_hdr.sense_key == ILLEGAL_REQUEST &&
2988 !(STp->use_pf & PF_TESTED)) {
2989 /* Try the other possible state of Page Format if not
2990 already tried */
Kai Makisara1da20192009-05-02 08:49:34 +03002991 STp->use_pf = (STp->use_pf ^ USE_PF) | PF_TESTED;
Mike Christie8b05b772005-11-08 04:06:44 -06002992 st_release_request(SRpnt);
Linus Torvalds1da177e2005-04-16 15:20:36 -07002993 SRpnt = NULL;
2994 return st_int_ioctl(STp, cmd_in, arg);
2995 }
2996 } else if (chg_eof)
2997 STps->eof = ST_NOEOF;
2998
2999 if (cmdstatp->sense_hdr.sense_key == BLANK_CHECK)
3000 STps->eof = ST_EOD;
3001
Mike Christie8b05b772005-11-08 04:06:44 -06003002 st_release_request(SRpnt);
Linus Torvalds1da177e2005-04-16 15:20:36 -07003003 SRpnt = NULL;
3004 }
3005
3006 return ioctl_result;
3007}
3008
3009
3010/* Get the tape position. If bt == 2, arg points into a kernel space mt_loc
3011 structure. */
3012
3013static int get_location(struct scsi_tape *STp, unsigned int *block, int *partition,
3014 int logical)
3015{
3016 int result;
3017 unsigned char scmd[MAX_COMMAND_SIZE];
Mike Christie8b05b772005-11-08 04:06:44 -06003018 struct st_request *SRpnt;
Linus Torvalds1da177e2005-04-16 15:20:36 -07003019 DEB( char *name = tape_name(STp); )
3020
3021 if (STp->ready != ST_READY)
3022 return (-EIO);
3023
3024 memset(scmd, 0, MAX_COMMAND_SIZE);
3025 if ((STp->device)->scsi_level < SCSI_2) {
3026 scmd[0] = QFA_REQUEST_BLOCK;
3027 scmd[4] = 3;
3028 } else {
3029 scmd[0] = READ_POSITION;
3030 if (!logical && !STp->scsi2_logical)
3031 scmd[1] = 1;
3032 }
Kai Makisara02ae2c02008-12-18 14:49:50 +09003033 SRpnt = st_do_scsi(NULL, STp, scmd, 20, DMA_FROM_DEVICE,
3034 STp->device->request_queue->rq_timeout,
3035 MAX_READY_RETRIES, 1);
Linus Torvalds1da177e2005-04-16 15:20:36 -07003036 if (!SRpnt)
Kai Makisara02ae2c02008-12-18 14:49:50 +09003037 return (STp->buffer)->syscall_result;
Linus Torvalds1da177e2005-04-16 15:20:36 -07003038
3039 if ((STp->buffer)->syscall_result != 0 ||
3040 (STp->device->scsi_level >= SCSI_2 &&
3041 ((STp->buffer)->b_data[0] & 4) != 0)) {
3042 *block = *partition = 0;
3043 DEBC(printk(ST_DEB_MSG "%s: Can't read tape position.\n", name));
3044 result = (-EIO);
3045 } else {
3046 result = 0;
3047 if ((STp->device)->scsi_level < SCSI_2) {
3048 *block = ((STp->buffer)->b_data[0] << 16)
3049 + ((STp->buffer)->b_data[1] << 8)
3050 + (STp->buffer)->b_data[2];
3051 *partition = 0;
3052 } else {
3053 *block = ((STp->buffer)->b_data[4] << 24)
3054 + ((STp->buffer)->b_data[5] << 16)
3055 + ((STp->buffer)->b_data[6] << 8)
3056 + (STp->buffer)->b_data[7];
3057 *partition = (STp->buffer)->b_data[1];
3058 if (((STp->buffer)->b_data[0] & 0x80) &&
3059 (STp->buffer)->b_data[1] == 0) /* BOP of partition 0 */
3060 STp->ps[0].drv_block = STp->ps[0].drv_file = 0;
3061 }
3062 DEBC(printk(ST_DEB_MSG "%s: Got tape pos. blk %d part %d.\n", name,
3063 *block, *partition));
3064 }
Mike Christie8b05b772005-11-08 04:06:44 -06003065 st_release_request(SRpnt);
Linus Torvalds1da177e2005-04-16 15:20:36 -07003066 SRpnt = NULL;
3067
3068 return result;
3069}
3070
3071
3072/* Set the tape block and partition. Negative partition means that only the
3073 block should be set in vendor specific way. */
3074static int set_location(struct scsi_tape *STp, unsigned int block, int partition,
3075 int logical)
3076{
3077 struct st_partstat *STps;
3078 int result, p;
3079 unsigned int blk;
3080 int timeout;
3081 unsigned char scmd[MAX_COMMAND_SIZE];
Mike Christie8b05b772005-11-08 04:06:44 -06003082 struct st_request *SRpnt;
Linus Torvalds1da177e2005-04-16 15:20:36 -07003083 DEB( char *name = tape_name(STp); )
3084
3085 if (STp->ready != ST_READY)
3086 return (-EIO);
3087 timeout = STp->long_timeout;
3088 STps = &(STp->ps[STp->partition]);
3089
3090 DEBC(printk(ST_DEB_MSG "%s: Setting block to %d and partition to %d.\n",
3091 name, block, partition));
3092 DEB(if (partition < 0)
3093 return (-EIO); )
3094
3095 /* Update the location at the partition we are leaving */
3096 if ((!STp->can_partitions && partition != 0) ||
3097 partition >= ST_NBR_PARTITIONS)
3098 return (-EINVAL);
3099 if (partition != STp->partition) {
3100 if (get_location(STp, &blk, &p, 1))
3101 STps->last_block_valid = 0;
3102 else {
3103 STps->last_block_valid = 1;
3104 STps->last_block_visited = blk;
3105 DEBC(printk(ST_DEB_MSG
3106 "%s: Visited block %d for partition %d saved.\n",
3107 name, blk, STp->partition));
3108 }
3109 }
3110
3111 memset(scmd, 0, MAX_COMMAND_SIZE);
3112 if ((STp->device)->scsi_level < SCSI_2) {
3113 scmd[0] = QFA_SEEK_BLOCK;
3114 scmd[2] = (block >> 16);
3115 scmd[3] = (block >> 8);
3116 scmd[4] = block;
3117 scmd[5] = 0;
3118 } else {
3119 scmd[0] = SEEK_10;
3120 scmd[3] = (block >> 24);
3121 scmd[4] = (block >> 16);
3122 scmd[5] = (block >> 8);
3123 scmd[6] = block;
3124 if (!logical && !STp->scsi2_logical)
3125 scmd[1] = 4;
3126 if (STp->partition != partition) {
3127 scmd[1] |= 2;
3128 scmd[8] = partition;
3129 DEBC(printk(ST_DEB_MSG
3130 "%s: Trying to change partition from %d to %d\n",
3131 name, STp->partition, partition));
3132 }
3133 }
3134 if (STp->immediate) {
3135 scmd[1] |= 1; /* Don't wait for completion */
James Bottomleya02488e2008-11-30 10:36:26 -06003136 timeout = STp->device->request_queue->rq_timeout;
Linus Torvalds1da177e2005-04-16 15:20:36 -07003137 }
3138
Kai Makisara02ae2c02008-12-18 14:49:50 +09003139 SRpnt = st_do_scsi(NULL, STp, scmd, 0, DMA_NONE,
3140 timeout, MAX_READY_RETRIES, 1);
Linus Torvalds1da177e2005-04-16 15:20:36 -07003141 if (!SRpnt)
Kai Makisara02ae2c02008-12-18 14:49:50 +09003142 return (STp->buffer)->syscall_result;
Linus Torvalds1da177e2005-04-16 15:20:36 -07003143
3144 STps->drv_block = STps->drv_file = (-1);
3145 STps->eof = ST_NOEOF;
3146 if ((STp->buffer)->syscall_result != 0) {
3147 result = (-EIO);
3148 if (STp->can_partitions &&
3149 (STp->device)->scsi_level >= SCSI_2 &&
3150 (p = find_partition(STp)) >= 0)
3151 STp->partition = p;
3152 } else {
3153 if (STp->can_partitions) {
3154 STp->partition = partition;
3155 STps = &(STp->ps[partition]);
3156 if (!STps->last_block_valid ||
3157 STps->last_block_visited != block) {
3158 STps->at_sm = 0;
3159 STps->rw = ST_IDLE;
3160 }
3161 } else
3162 STps->at_sm = 0;
3163 if (block == 0)
3164 STps->drv_block = STps->drv_file = 0;
3165 result = 0;
3166 }
Kai Makisara02ae2c02008-12-18 14:49:50 +09003167
Mike Christie8b05b772005-11-08 04:06:44 -06003168 st_release_request(SRpnt);
Linus Torvalds1da177e2005-04-16 15:20:36 -07003169 SRpnt = NULL;
3170
3171 return result;
3172}
3173
3174
3175/* Find the current partition number for the drive status. Called from open and
3176 returns either partition number of negative error code. */
3177static int find_partition(struct scsi_tape *STp)
3178{
3179 int i, partition;
3180 unsigned int block;
3181
3182 if ((i = get_location(STp, &block, &partition, 1)) < 0)
3183 return i;
3184 if (partition >= ST_NBR_PARTITIONS)
3185 return (-EIO);
3186 return partition;
3187}
3188
3189
3190/* Change the partition if necessary */
3191static int switch_partition(struct scsi_tape *STp)
3192{
3193 struct st_partstat *STps;
3194
3195 if (STp->partition == STp->new_partition)
3196 return 0;
3197 STps = &(STp->ps[STp->new_partition]);
3198 if (!STps->last_block_valid)
3199 STps->last_block_visited = 0;
3200 return set_location(STp, STps->last_block_visited, STp->new_partition, 1);
3201}
3202
3203/* Functions for reading and writing the medium partition mode page. */
3204
3205#define PART_PAGE 0x11
3206#define PART_PAGE_FIXED_LENGTH 8
3207
3208#define PP_OFF_MAX_ADD_PARTS 2
3209#define PP_OFF_NBR_ADD_PARTS 3
3210#define PP_OFF_FLAGS 4
3211#define PP_OFF_PART_UNITS 6
3212#define PP_OFF_RESERVED 7
3213
3214#define PP_BIT_IDP 0x20
3215#define PP_MSK_PSUM_MB 0x10
3216
3217/* Get the number of partitions on the tape. As a side effect reads the
3218 mode page into the tape buffer. */
3219static int nbr_partitions(struct scsi_tape *STp)
3220{
3221 int result;
3222 DEB( char *name = tape_name(STp); )
3223
3224 if (STp->ready != ST_READY)
3225 return (-EIO);
3226
3227 result = read_mode_page(STp, PART_PAGE, 1);
3228
3229 if (result) {
3230 DEBC(printk(ST_DEB_MSG "%s: Can't read medium partition page.\n",
3231 name));
3232 result = (-EIO);
3233 } else {
3234 result = (STp->buffer)->b_data[MODE_HEADER_LENGTH +
3235 PP_OFF_NBR_ADD_PARTS] + 1;
3236 DEBC(printk(ST_DEB_MSG "%s: Number of partitions %d.\n", name, result));
3237 }
3238
3239 return result;
3240}
3241
3242
3243/* Partition the tape into two partitions if size > 0 or one partition if
3244 size == 0.
3245
3246 The block descriptors are read and written because Sony SDT-7000 does not
3247 work without this (suggestion from Michael Schaefer <Michael.Schaefer@dlr.de>).
3248
3249 My HP C1533A drive returns only one partition size field. This is used to
3250 set the size of partition 1. There is no size field for the default partition.
3251 Michael Schaefer's Sony SDT-7000 returns two descriptors and the second is
3252 used to set the size of partition 1 (this is what the SCSI-3 standard specifies).
3253 The following algorithm is used to accommodate both drives: if the number of
3254 partition size fields is greater than the maximum number of additional partitions
3255 in the mode page, the second field is used. Otherwise the first field is used.
3256
3257 For Seagate DDS drives the page length must be 8 when no partitions is defined
3258 and 10 when 1 partition is defined (information from Eric Lee Green). This is
3259 is acceptable also to some other old drives and enforced if the first partition
3260 size field is used for the first additional partition size.
3261 */
3262static int partition_tape(struct scsi_tape *STp, int size)
3263{
3264 char *name = tape_name(STp);
3265 int result;
3266 int pgo, psd_cnt, psdo;
3267 unsigned char *bp;
3268
3269 result = read_mode_page(STp, PART_PAGE, 0);
3270 if (result) {
3271 DEBC(printk(ST_DEB_MSG "%s: Can't read partition mode page.\n", name));
3272 return result;
3273 }
3274 /* The mode page is in the buffer. Let's modify it and write it. */
3275 bp = (STp->buffer)->b_data;
3276 pgo = MODE_HEADER_LENGTH + bp[MH_OFF_BDESCS_LENGTH];
3277 DEBC(printk(ST_DEB_MSG "%s: Partition page length is %d bytes.\n",
3278 name, bp[pgo + MP_OFF_PAGE_LENGTH] + 2));
3279
3280 psd_cnt = (bp[pgo + MP_OFF_PAGE_LENGTH] + 2 - PART_PAGE_FIXED_LENGTH) / 2;
3281 psdo = pgo + PART_PAGE_FIXED_LENGTH;
3282 if (psd_cnt > bp[pgo + PP_OFF_MAX_ADD_PARTS]) {
3283 bp[psdo] = bp[psdo + 1] = 0xff; /* Rest of the tape */
3284 psdo += 2;
3285 }
3286 memset(bp + psdo, 0, bp[pgo + PP_OFF_NBR_ADD_PARTS] * 2);
3287
3288 DEBC(printk("%s: psd_cnt %d, max.parts %d, nbr_parts %d\n", name,
3289 psd_cnt, bp[pgo + PP_OFF_MAX_ADD_PARTS],
3290 bp[pgo + PP_OFF_NBR_ADD_PARTS]));
3291
3292 if (size <= 0) {
3293 bp[pgo + PP_OFF_NBR_ADD_PARTS] = 0;
3294 if (psd_cnt <= bp[pgo + PP_OFF_MAX_ADD_PARTS])
3295 bp[pgo + MP_OFF_PAGE_LENGTH] = 6;
3296 DEBC(printk(ST_DEB_MSG "%s: Formatting tape with one partition.\n",
3297 name));
3298 } else {
3299 bp[psdo] = (size >> 8) & 0xff;
3300 bp[psdo + 1] = size & 0xff;
3301 bp[pgo + 3] = 1;
3302 if (bp[pgo + MP_OFF_PAGE_LENGTH] < 8)
3303 bp[pgo + MP_OFF_PAGE_LENGTH] = 8;
3304 DEBC(printk(ST_DEB_MSG
3305 "%s: Formatting tape with two partitions (1 = %d MB).\n",
3306 name, size));
3307 }
3308 bp[pgo + PP_OFF_PART_UNITS] = 0;
3309 bp[pgo + PP_OFF_RESERVED] = 0;
3310 bp[pgo + PP_OFF_FLAGS] = PP_BIT_IDP | PP_MSK_PSUM_MB;
3311
3312 result = write_mode_page(STp, PART_PAGE, 1);
3313 if (result) {
3314 printk(KERN_INFO "%s: Partitioning of tape failed.\n", name);
3315 result = (-EIO);
3316 }
3317
3318 return result;
3319}
3320
3321
3322
3323/* The ioctl command */
Kai Makisarafd66c1b2008-01-17 22:45:22 +02003324static long st_ioctl(struct file *file, unsigned int cmd_in, unsigned long arg)
Linus Torvalds1da177e2005-04-16 15:20:36 -07003325{
3326 int i, cmd_nr, cmd_type, bt;
3327 int retval = 0;
3328 unsigned int blk;
3329 struct scsi_tape *STp = file->private_data;
3330 struct st_modedef *STm;
3331 struct st_partstat *STps;
3332 char *name = tape_name(STp);
3333 void __user *p = (void __user *)arg;
3334
Matthias Kaehlcke28f85002007-07-29 23:38:15 +02003335 if (mutex_lock_interruptible(&STp->lock))
Linus Torvalds1da177e2005-04-16 15:20:36 -07003336 return -ERESTARTSYS;
3337
3338 DEB(
3339 if (debugging && !STp->in_use) {
3340 printk(ST_DEB_MSG "%s: Incorrect device.\n", name);
3341 retval = (-EIO);
3342 goto out;
3343 } ) /* end DEB */
3344
3345 STm = &(STp->modes[STp->current_mode]);
3346 STps = &(STp->ps[STp->partition]);
3347
3348 /*
3349 * If we are in the middle of error recovery, don't let anyone
3350 * else try and use this device. Also, if error recovery fails, it
3351 * may try and take the device offline, in which case all further
3352 * access to the device is prohibited.
3353 */
Al Viro83ff6fe2008-03-02 08:15:49 -05003354 retval = scsi_nonblockable_ioctl(STp->device, cmd_in, p,
3355 file->f_flags & O_NDELAY);
Linus Torvalds1da177e2005-04-16 15:20:36 -07003356 if (!scsi_block_when_processing_errors(STp->device) || retval != -ENODEV)
3357 goto out;
3358 retval = 0;
3359
3360 cmd_type = _IOC_TYPE(cmd_in);
3361 cmd_nr = _IOC_NR(cmd_in);
3362
3363 if (cmd_type == _IOC_TYPE(MTIOCTOP) && cmd_nr == _IOC_NR(MTIOCTOP)) {
3364 struct mtop mtc;
3365
3366 if (_IOC_SIZE(cmd_in) != sizeof(mtc)) {
3367 retval = (-EINVAL);
3368 goto out;
3369 }
3370
3371 i = copy_from_user(&mtc, p, sizeof(struct mtop));
3372 if (i) {
3373 retval = (-EFAULT);
3374 goto out;
3375 }
3376
3377 if (mtc.mt_op == MTSETDRVBUFFER && !capable(CAP_SYS_ADMIN)) {
3378 printk(KERN_WARNING
3379 "%s: MTSETDRVBUFFER only allowed for root.\n", name);
3380 retval = (-EPERM);
3381 goto out;
3382 }
3383 if (!STm->defined &&
3384 (mtc.mt_op != MTSETDRVBUFFER &&
3385 (mtc.mt_count & MT_ST_OPTIONS) == 0)) {
3386 retval = (-ENXIO);
3387 goto out;
3388 }
3389
3390 if (!STp->pos_unknown) {
3391
3392 if (STps->eof == ST_FM_HIT) {
3393 if (mtc.mt_op == MTFSF || mtc.mt_op == MTFSFM ||
3394 mtc.mt_op == MTEOM) {
3395 mtc.mt_count -= 1;
3396 if (STps->drv_file >= 0)
3397 STps->drv_file += 1;
3398 } else if (mtc.mt_op == MTBSF || mtc.mt_op == MTBSFM) {
3399 mtc.mt_count += 1;
3400 if (STps->drv_file >= 0)
3401 STps->drv_file += 1;
3402 }
3403 }
3404
3405 if (mtc.mt_op == MTSEEK) {
3406 /* Old position must be restored if partition will be
3407 changed */
3408 i = !STp->can_partitions ||
3409 (STp->new_partition != STp->partition);
3410 } else {
3411 i = mtc.mt_op == MTREW || mtc.mt_op == MTOFFL ||
3412 mtc.mt_op == MTRETEN || mtc.mt_op == MTEOM ||
3413 mtc.mt_op == MTLOCK || mtc.mt_op == MTLOAD ||
3414 mtc.mt_op == MTFSF || mtc.mt_op == MTFSFM ||
3415 mtc.mt_op == MTBSF || mtc.mt_op == MTBSFM ||
3416 mtc.mt_op == MTCOMPRESSION;
3417 }
3418 i = flush_buffer(STp, i);
3419 if (i < 0) {
3420 retval = i;
3421 goto out;
3422 }
3423 if (STps->rw == ST_WRITING &&
3424 (mtc.mt_op == MTREW || mtc.mt_op == MTOFFL ||
3425 mtc.mt_op == MTSEEK ||
3426 mtc.mt_op == MTBSF || mtc.mt_op == MTBSFM)) {
3427 i = st_int_ioctl(STp, MTWEOF, 1);
3428 if (i < 0) {
3429 retval = i;
3430 goto out;
3431 }
3432 if (mtc.mt_op == MTBSF || mtc.mt_op == MTBSFM)
3433 mtc.mt_count++;
3434 STps->rw = ST_IDLE;
3435 }
3436
3437 } else {
3438 /*
3439 * If there was a bus reset, block further access
3440 * to this device. If the user wants to rewind the tape,
3441 * then reset the flag and allow access again.
3442 */
3443 if (mtc.mt_op != MTREW &&
3444 mtc.mt_op != MTOFFL &&
3445 mtc.mt_op != MTRETEN &&
3446 mtc.mt_op != MTERASE &&
3447 mtc.mt_op != MTSEEK &&
3448 mtc.mt_op != MTEOM) {
3449 retval = (-EIO);
3450 goto out;
3451 }
3452 reset_state(STp);
3453 /* remove this when the midlevel properly clears was_reset */
3454 STp->device->was_reset = 0;
3455 }
3456
3457 if (mtc.mt_op != MTNOP && mtc.mt_op != MTSETBLK &&
3458 mtc.mt_op != MTSETDENSITY && mtc.mt_op != MTWSM &&
3459 mtc.mt_op != MTSETDRVBUFFER && mtc.mt_op != MTSETPART)
3460 STps->rw = ST_IDLE; /* Prevent automatic WEOF and fsf */
3461
3462 if (mtc.mt_op == MTOFFL && STp->door_locked != ST_UNLOCKED)
3463 do_door_lock(STp, 0); /* Ignore result! */
3464
3465 if (mtc.mt_op == MTSETDRVBUFFER &&
3466 (mtc.mt_count & MT_ST_OPTIONS) != 0) {
3467 retval = st_set_options(STp, mtc.mt_count);
3468 goto out;
3469 }
3470
3471 if (mtc.mt_op == MTSETPART) {
3472 if (!STp->can_partitions ||
3473 mtc.mt_count < 0 || mtc.mt_count >= ST_NBR_PARTITIONS) {
3474 retval = (-EINVAL);
3475 goto out;
3476 }
3477 if (mtc.mt_count >= STp->nbr_partitions &&
3478 (STp->nbr_partitions = nbr_partitions(STp)) < 0) {
3479 retval = (-EIO);
3480 goto out;
3481 }
3482 if (mtc.mt_count >= STp->nbr_partitions) {
3483 retval = (-EINVAL);
3484 goto out;
3485 }
3486 STp->new_partition = mtc.mt_count;
3487 retval = 0;
3488 goto out;
3489 }
3490
3491 if (mtc.mt_op == MTMKPART) {
3492 if (!STp->can_partitions) {
3493 retval = (-EINVAL);
3494 goto out;
3495 }
3496 if ((i = st_int_ioctl(STp, MTREW, 0)) < 0 ||
3497 (i = partition_tape(STp, mtc.mt_count)) < 0) {
3498 retval = i;
3499 goto out;
3500 }
3501 for (i = 0; i < ST_NBR_PARTITIONS; i++) {
3502 STp->ps[i].rw = ST_IDLE;
3503 STp->ps[i].at_sm = 0;
3504 STp->ps[i].last_block_valid = 0;
3505 }
3506 STp->partition = STp->new_partition = 0;
3507 STp->nbr_partitions = 1; /* Bad guess ?-) */
3508 STps->drv_block = STps->drv_file = 0;
3509 retval = 0;
3510 goto out;
3511 }
3512
3513 if (mtc.mt_op == MTSEEK) {
3514 i = set_location(STp, mtc.mt_count, STp->new_partition, 0);
3515 if (!STp->can_partitions)
3516 STp->ps[0].rw = ST_IDLE;
3517 retval = i;
3518 goto out;
3519 }
3520
3521 if (mtc.mt_op == MTUNLOAD || mtc.mt_op == MTOFFL) {
3522 retval = do_load_unload(STp, file, 0);
3523 goto out;
3524 }
3525
3526 if (mtc.mt_op == MTLOAD) {
3527 retval = do_load_unload(STp, file, max(1, mtc.mt_count));
3528 goto out;
3529 }
3530
3531 if (mtc.mt_op == MTLOCK || mtc.mt_op == MTUNLOCK) {
3532 retval = do_door_lock(STp, (mtc.mt_op == MTLOCK));
3533 goto out;
3534 }
3535
3536 if (STp->can_partitions && STp->ready == ST_READY &&
3537 (i = switch_partition(STp)) < 0) {
3538 retval = i;
3539 goto out;
3540 }
3541
3542 if (mtc.mt_op == MTCOMPRESSION)
3543 retval = st_compression(STp, (mtc.mt_count & 1));
3544 else
3545 retval = st_int_ioctl(STp, mtc.mt_op, mtc.mt_count);
3546 goto out;
3547 }
3548 if (!STm->defined) {
3549 retval = (-ENXIO);
3550 goto out;
3551 }
3552
3553 if ((i = flush_buffer(STp, 0)) < 0) {
3554 retval = i;
3555 goto out;
3556 }
3557 if (STp->can_partitions &&
3558 (i = switch_partition(STp)) < 0) {
3559 retval = i;
3560 goto out;
3561 }
3562
3563 if (cmd_type == _IOC_TYPE(MTIOCGET) && cmd_nr == _IOC_NR(MTIOCGET)) {
3564 struct mtget mt_status;
3565
3566 if (_IOC_SIZE(cmd_in) != sizeof(struct mtget)) {
3567 retval = (-EINVAL);
3568 goto out;
3569 }
3570
3571 mt_status.mt_type = STp->tape_type;
3572 mt_status.mt_dsreg =
3573 ((STp->block_size << MT_ST_BLKSIZE_SHIFT) & MT_ST_BLKSIZE_MASK) |
3574 ((STp->density << MT_ST_DENSITY_SHIFT) & MT_ST_DENSITY_MASK);
3575 mt_status.mt_blkno = STps->drv_block;
3576 mt_status.mt_fileno = STps->drv_file;
3577 if (STp->block_size != 0) {
3578 if (STps->rw == ST_WRITING)
3579 mt_status.mt_blkno +=
3580 (STp->buffer)->buffer_bytes / STp->block_size;
3581 else if (STps->rw == ST_READING)
3582 mt_status.mt_blkno -=
3583 ((STp->buffer)->buffer_bytes +
3584 STp->block_size - 1) / STp->block_size;
3585 }
3586
3587 mt_status.mt_gstat = 0;
3588 if (STp->drv_write_prot)
3589 mt_status.mt_gstat |= GMT_WR_PROT(0xffffffff);
3590 if (mt_status.mt_blkno == 0) {
3591 if (mt_status.mt_fileno == 0)
3592 mt_status.mt_gstat |= GMT_BOT(0xffffffff);
3593 else
3594 mt_status.mt_gstat |= GMT_EOF(0xffffffff);
3595 }
3596 mt_status.mt_erreg = (STp->recover_reg << MT_ST_SOFTERR_SHIFT);
3597 mt_status.mt_resid = STp->partition;
3598 if (STps->eof == ST_EOM_OK || STps->eof == ST_EOM_ERROR)
3599 mt_status.mt_gstat |= GMT_EOT(0xffffffff);
3600 else if (STps->eof >= ST_EOM_OK)
3601 mt_status.mt_gstat |= GMT_EOD(0xffffffff);
3602 if (STp->density == 1)
3603 mt_status.mt_gstat |= GMT_D_800(0xffffffff);
3604 else if (STp->density == 2)
3605 mt_status.mt_gstat |= GMT_D_1600(0xffffffff);
3606 else if (STp->density == 3)
3607 mt_status.mt_gstat |= GMT_D_6250(0xffffffff);
3608 if (STp->ready == ST_READY)
3609 mt_status.mt_gstat |= GMT_ONLINE(0xffffffff);
3610 if (STp->ready == ST_NO_TAPE)
3611 mt_status.mt_gstat |= GMT_DR_OPEN(0xffffffff);
3612 if (STps->at_sm)
3613 mt_status.mt_gstat |= GMT_SM(0xffffffff);
3614 if (STm->do_async_writes ||
3615 (STm->do_buffer_writes && STp->block_size != 0) ||
3616 STp->drv_buffer != 0)
3617 mt_status.mt_gstat |= GMT_IM_REP_EN(0xffffffff);
3618 if (STp->cleaning_req)
3619 mt_status.mt_gstat |= GMT_CLN(0xffffffff);
3620
3621 i = copy_to_user(p, &mt_status, sizeof(struct mtget));
3622 if (i) {
3623 retval = (-EFAULT);
3624 goto out;
3625 }
3626
3627 STp->recover_reg = 0; /* Clear after read */
3628 retval = 0;
3629 goto out;
3630 } /* End of MTIOCGET */
3631 if (cmd_type == _IOC_TYPE(MTIOCPOS) && cmd_nr == _IOC_NR(MTIOCPOS)) {
3632 struct mtpos mt_pos;
3633 if (_IOC_SIZE(cmd_in) != sizeof(struct mtpos)) {
3634 retval = (-EINVAL);
3635 goto out;
3636 }
3637 if ((i = get_location(STp, &blk, &bt, 0)) < 0) {
3638 retval = i;
3639 goto out;
3640 }
3641 mt_pos.mt_blkno = blk;
3642 i = copy_to_user(p, &mt_pos, sizeof(struct mtpos));
3643 if (i)
3644 retval = (-EFAULT);
3645 goto out;
3646 }
Matthias Kaehlcke28f85002007-07-29 23:38:15 +02003647 mutex_unlock(&STp->lock);
Linus Torvalds1da177e2005-04-16 15:20:36 -07003648 switch (cmd_in) {
3649 case SCSI_IOCTL_GET_IDLUN:
3650 case SCSI_IOCTL_GET_BUS_NUMBER:
3651 break;
3652 default:
Kai Makisara 16c4b3e2005-05-01 18:11:55 +03003653 if ((cmd_in == SG_IO ||
3654 cmd_in == SCSI_IOCTL_SEND_COMMAND ||
3655 cmd_in == CDROM_SEND_PACKET) &&
3656 !capable(CAP_SYS_RAWIO))
Linus Torvalds1da177e2005-04-16 15:20:36 -07003657 i = -EPERM;
3658 else
Al Viro74f3c8a2007-08-27 15:38:10 -04003659 i = scsi_cmd_ioctl(STp->disk->queue, STp->disk,
3660 file->f_mode, cmd_in, p);
Linus Torvalds1da177e2005-04-16 15:20:36 -07003661 if (i != -ENOTTY)
3662 return i;
3663 break;
3664 }
Kai Makisara 16c4b3e2005-05-01 18:11:55 +03003665 retval = scsi_ioctl(STp->device, cmd_in, p);
3666 if (!retval && cmd_in == SCSI_IOCTL_STOP_UNIT) { /* unload */
3667 STp->rew_at_close = 0;
3668 STp->ready = ST_NO_TAPE;
3669 }
3670 return retval;
Linus Torvalds1da177e2005-04-16 15:20:36 -07003671
3672 out:
Matthias Kaehlcke28f85002007-07-29 23:38:15 +02003673 mutex_unlock(&STp->lock);
Linus Torvalds1da177e2005-04-16 15:20:36 -07003674 return retval;
3675}
3676
3677#ifdef CONFIG_COMPAT
3678static long st_compat_ioctl(struct file *file, unsigned int cmd, unsigned long arg)
3679{
3680 struct scsi_tape *STp = file->private_data;
3681 struct scsi_device *sdev = STp->device;
3682 int ret = -ENOIOCTLCMD;
3683 if (sdev->host->hostt->compat_ioctl) {
3684
3685 ret = sdev->host->hostt->compat_ioctl(sdev, cmd, (void __user *)arg);
3686
3687 }
3688 return ret;
3689}
3690#endif
3691
3692
3693
3694/* Try to allocate a new tape buffer. Calling function must not hold
3695 dev_arr_lock. */
FUJITA Tomonorif409d6c2008-12-18 14:49:47 +09003696static struct st_buffer *new_tape_buffer(int need_dma, int max_sg)
Linus Torvalds1da177e2005-04-16 15:20:36 -07003697{
Linus Torvalds1da177e2005-04-16 15:20:36 -07003698 struct st_buffer *tb;
3699
FUJITA Tomonorif409d6c2008-12-18 14:49:47 +09003700 tb = kzalloc(sizeof(struct st_buffer), GFP_ATOMIC);
Linus Torvalds1da177e2005-04-16 15:20:36 -07003701 if (!tb) {
3702 printk(KERN_NOTICE "st: Can't allocate new tape buffer.\n");
3703 return NULL;
3704 }
FUJITA Tomonori1ac63cf2008-12-18 14:49:48 +09003705 tb->frp_segs = 0;
Linus Torvalds1da177e2005-04-16 15:20:36 -07003706 tb->use_sg = max_sg;
Linus Torvalds1da177e2005-04-16 15:20:36 -07003707 tb->dma = need_dma;
FUJITA Tomonorif409d6c2008-12-18 14:49:47 +09003708 tb->buffer_size = 0;
Linus Torvalds1da177e2005-04-16 15:20:36 -07003709
FUJITA Tomonorif409d6c2008-12-18 14:49:47 +09003710 tb->reserved_pages = kzalloc(max_sg * sizeof(struct page *),
3711 GFP_ATOMIC);
FUJITA Tomonorid0e1ae32008-12-18 14:49:40 +09003712 if (!tb->reserved_pages) {
3713 kfree(tb);
3714 return NULL;
3715 }
3716
Linus Torvalds1da177e2005-04-16 15:20:36 -07003717 return tb;
3718}
3719
3720
3721/* Try to allocate enough space in the tape buffer */
Kai Makisara8f78fc52008-12-18 14:49:51 +09003722#define ST_MAX_ORDER 6
3723
Linus Torvalds1da177e2005-04-16 15:20:36 -07003724static int enlarge_buffer(struct st_buffer * STbuffer, int new_size, int need_dma)
3725{
Al Viroc53033f2005-10-21 03:22:08 -04003726 int segs, nbr, max_segs, b_size, order, got;
3727 gfp_t priority;
Linus Torvalds1da177e2005-04-16 15:20:36 -07003728
3729 if (new_size <= STbuffer->buffer_size)
3730 return 1;
3731
3732 if (STbuffer->buffer_size <= PAGE_SIZE)
3733 normalize_buffer(STbuffer); /* Avoid extra segment */
3734
3735 max_segs = STbuffer->use_sg;
3736 nbr = max_segs - STbuffer->frp_segs;
3737 if (nbr <= 0)
3738 return 0;
3739
3740 priority = GFP_KERNEL | __GFP_NOWARN;
3741 if (need_dma)
3742 priority |= GFP_DMA;
FUJITA Tomonori9c905962008-12-18 14:49:39 +09003743
FUJITA Tomonori08c95832008-12-18 14:49:45 +09003744 if (STbuffer->cleared)
3745 priority |= __GFP_ZERO;
3746
FUJITA Tomonori9c905962008-12-18 14:49:39 +09003747 if (STbuffer->frp_segs) {
FUJITA Tomonoric982c362009-11-26 09:24:13 +09003748 order = STbuffer->reserved_page_order;
FUJITA Tomonori08c95832008-12-18 14:49:45 +09003749 b_size = PAGE_SIZE << order;
FUJITA Tomonori9c905962008-12-18 14:49:39 +09003750 } else {
3751 for (b_size = PAGE_SIZE, order = 0;
FUJITA Tomonori46081b12010-12-20 18:44:45 +02003752 order < ST_MAX_ORDER &&
3753 max_segs * (PAGE_SIZE << order) < new_size;
Kai Makisara8f78fc52008-12-18 14:49:51 +09003754 order++, b_size *= 2)
FUJITA Tomonori9c905962008-12-18 14:49:39 +09003755 ; /* empty */
Kai Makisara373daac2010-12-20 18:43:39 +02003756 STbuffer->reserved_page_order = order;
FUJITA Tomonori9c905962008-12-18 14:49:39 +09003757 }
Kai Makisara8f78fc52008-12-18 14:49:51 +09003758 if (max_segs * (PAGE_SIZE << order) < new_size) {
3759 if (order == ST_MAX_ORDER)
3760 return 0;
3761 normalize_buffer(STbuffer);
3762 return enlarge_buffer(STbuffer, new_size, need_dma);
3763 }
Linus Torvalds1da177e2005-04-16 15:20:36 -07003764
3765 for (segs = STbuffer->frp_segs, got = STbuffer->buffer_size;
3766 segs < max_segs && got < new_size;) {
FUJITA Tomonori08c95832008-12-18 14:49:45 +09003767 struct page *page;
3768
3769 page = alloc_pages(priority, order);
3770 if (!page) {
Linus Torvalds1da177e2005-04-16 15:20:36 -07003771 DEB(STbuffer->buffer_size = got);
3772 normalize_buffer(STbuffer);
3773 return 0;
3774 }
FUJITA Tomonori08c95832008-12-18 14:49:45 +09003775
Linus Torvalds1da177e2005-04-16 15:20:36 -07003776 STbuffer->frp_segs += 1;
3777 got += b_size;
3778 STbuffer->buffer_size = got;
FUJITA Tomonori08c95832008-12-18 14:49:45 +09003779 STbuffer->reserved_pages[segs] = page;
Linus Torvalds1da177e2005-04-16 15:20:36 -07003780 segs++;
3781 }
FUJITA Tomonori08c95832008-12-18 14:49:45 +09003782 STbuffer->b_data = page_address(STbuffer->reserved_pages[0]);
Linus Torvalds1da177e2005-04-16 15:20:36 -07003783
3784 return 1;
3785}
3786
3787
Kai Makisara40f6b362008-02-24 22:23:24 +02003788/* Make sure that no data from previous user is in the internal buffer */
3789static void clear_buffer(struct st_buffer * st_bp)
3790{
3791 int i;
3792
3793 for (i=0; i < st_bp->frp_segs; i++)
FUJITA Tomonori08c95832008-12-18 14:49:45 +09003794 memset(page_address(st_bp->reserved_pages[i]), 0,
FUJITA Tomonoric982c362009-11-26 09:24:13 +09003795 PAGE_SIZE << st_bp->reserved_page_order);
Kai Makisara40f6b362008-02-24 22:23:24 +02003796 st_bp->cleared = 1;
3797}
3798
3799
Linus Torvalds1da177e2005-04-16 15:20:36 -07003800/* Release the extra buffer */
3801static void normalize_buffer(struct st_buffer * STbuffer)
3802{
FUJITA Tomonoric982c362009-11-26 09:24:13 +09003803 int i, order = STbuffer->reserved_page_order;
Linus Torvalds1da177e2005-04-16 15:20:36 -07003804
FUJITA Tomonori1ac63cf2008-12-18 14:49:48 +09003805 for (i = 0; i < STbuffer->frp_segs; i++) {
FUJITA Tomonori08c95832008-12-18 14:49:45 +09003806 __free_pages(STbuffer->reserved_pages[i], order);
3807 STbuffer->buffer_size -= (PAGE_SIZE << order);
Linus Torvalds1da177e2005-04-16 15:20:36 -07003808 }
FUJITA Tomonori1ac63cf2008-12-18 14:49:48 +09003809 STbuffer->frp_segs = 0;
Mike Christie8b05b772005-11-08 04:06:44 -06003810 STbuffer->sg_segs = 0;
FUJITA Tomonoric982c362009-11-26 09:24:13 +09003811 STbuffer->reserved_page_order = 0;
FUJITA Tomonorid0e1ae32008-12-18 14:49:40 +09003812 STbuffer->map_data.offset = 0;
Linus Torvalds1da177e2005-04-16 15:20:36 -07003813}
3814
3815
3816/* Move data from the user buffer to the tape buffer. Returns zero (success) or
3817 negative error code. */
3818static int append_to_buffer(const char __user *ubp, struct st_buffer * st_bp, int do_count)
3819{
3820 int i, cnt, res, offset;
FUJITA Tomonoric982c362009-11-26 09:24:13 +09003821 int length = PAGE_SIZE << st_bp->reserved_page_order;
Linus Torvalds1da177e2005-04-16 15:20:36 -07003822
3823 for (i = 0, offset = st_bp->buffer_bytes;
FUJITA Tomonori08c95832008-12-18 14:49:45 +09003824 i < st_bp->frp_segs && offset >= length; i++)
3825 offset -= length;
Linus Torvalds1da177e2005-04-16 15:20:36 -07003826 if (i == st_bp->frp_segs) { /* Should never happen */
3827 printk(KERN_WARNING "st: append_to_buffer offset overflow.\n");
3828 return (-EIO);
3829 }
3830 for (; i < st_bp->frp_segs && do_count > 0; i++) {
FUJITA Tomonori08c95832008-12-18 14:49:45 +09003831 struct page *page = st_bp->reserved_pages[i];
3832 cnt = length - offset < do_count ? length - offset : do_count;
3833 res = copy_from_user(page_address(page) + offset, ubp, cnt);
Linus Torvalds1da177e2005-04-16 15:20:36 -07003834 if (res)
3835 return (-EFAULT);
3836 do_count -= cnt;
3837 st_bp->buffer_bytes += cnt;
3838 ubp += cnt;
3839 offset = 0;
3840 }
3841 if (do_count) /* Should never happen */
3842 return (-EIO);
3843
3844 return 0;
3845}
3846
3847
3848/* Move data from the tape buffer to the user buffer. Returns zero (success) or
3849 negative error code. */
3850static int from_buffer(struct st_buffer * st_bp, char __user *ubp, int do_count)
3851{
3852 int i, cnt, res, offset;
FUJITA Tomonoric982c362009-11-26 09:24:13 +09003853 int length = PAGE_SIZE << st_bp->reserved_page_order;
Linus Torvalds1da177e2005-04-16 15:20:36 -07003854
3855 for (i = 0, offset = st_bp->read_pointer;
FUJITA Tomonori08c95832008-12-18 14:49:45 +09003856 i < st_bp->frp_segs && offset >= length; i++)
3857 offset -= length;
Linus Torvalds1da177e2005-04-16 15:20:36 -07003858 if (i == st_bp->frp_segs) { /* Should never happen */
3859 printk(KERN_WARNING "st: from_buffer offset overflow.\n");
3860 return (-EIO);
3861 }
3862 for (; i < st_bp->frp_segs && do_count > 0; i++) {
FUJITA Tomonori08c95832008-12-18 14:49:45 +09003863 struct page *page = st_bp->reserved_pages[i];
3864 cnt = length - offset < do_count ? length - offset : do_count;
3865 res = copy_to_user(ubp, page_address(page) + offset, cnt);
Linus Torvalds1da177e2005-04-16 15:20:36 -07003866 if (res)
3867 return (-EFAULT);
3868 do_count -= cnt;
3869 st_bp->buffer_bytes -= cnt;
3870 st_bp->read_pointer += cnt;
3871 ubp += cnt;
3872 offset = 0;
3873 }
3874 if (do_count) /* Should never happen */
3875 return (-EIO);
3876
3877 return 0;
3878}
3879
3880
3881/* Move data towards start of buffer */
3882static void move_buffer_data(struct st_buffer * st_bp, int offset)
3883{
3884 int src_seg, dst_seg, src_offset = 0, dst_offset;
3885 int count, total;
FUJITA Tomonoric982c362009-11-26 09:24:13 +09003886 int length = PAGE_SIZE << st_bp->reserved_page_order;
Linus Torvalds1da177e2005-04-16 15:20:36 -07003887
3888 if (offset == 0)
3889 return;
3890
3891 total=st_bp->buffer_bytes - offset;
3892 for (src_seg=0; src_seg < st_bp->frp_segs; src_seg++) {
3893 src_offset = offset;
FUJITA Tomonori08c95832008-12-18 14:49:45 +09003894 if (src_offset < length)
Linus Torvalds1da177e2005-04-16 15:20:36 -07003895 break;
FUJITA Tomonori08c95832008-12-18 14:49:45 +09003896 offset -= length;
Linus Torvalds1da177e2005-04-16 15:20:36 -07003897 }
3898
3899 st_bp->buffer_bytes = st_bp->read_pointer = total;
3900 for (dst_seg=dst_offset=0; total > 0; ) {
FUJITA Tomonori08c95832008-12-18 14:49:45 +09003901 struct page *dpage = st_bp->reserved_pages[dst_seg];
3902 struct page *spage = st_bp->reserved_pages[src_seg];
3903
3904 count = min(length - dst_offset, length - src_offset);
3905 memmove(page_address(dpage) + dst_offset,
3906 page_address(spage) + src_offset, count);
Linus Torvalds1da177e2005-04-16 15:20:36 -07003907 src_offset += count;
FUJITA Tomonori08c95832008-12-18 14:49:45 +09003908 if (src_offset >= length) {
Linus Torvalds1da177e2005-04-16 15:20:36 -07003909 src_seg++;
3910 src_offset = 0;
3911 }
3912 dst_offset += count;
FUJITA Tomonori08c95832008-12-18 14:49:45 +09003913 if (dst_offset >= length) {
Linus Torvalds1da177e2005-04-16 15:20:36 -07003914 dst_seg++;
3915 dst_offset = 0;
3916 }
3917 total -= count;
3918 }
3919}
3920
Linus Torvalds1da177e2005-04-16 15:20:36 -07003921/* Validate the options from command line or module parameters */
3922static void validate_options(void)
3923{
3924 if (buffer_kbs > 0)
3925 st_fixed_buffer_size = buffer_kbs * ST_KILOBYTE;
3926 if (max_sg_segs >= ST_FIRST_SG)
3927 st_max_sg_segs = max_sg_segs;
3928}
3929
3930#ifndef MODULE
3931/* Set the boot options. Syntax is defined in Documenation/scsi/st.txt.
3932 */
3933static int __init st_setup(char *str)
3934{
3935 int i, len, ints[5];
3936 char *stp;
3937
3938 stp = get_options(str, ARRAY_SIZE(ints), ints);
3939
3940 if (ints[0] > 0) {
3941 for (i = 0; i < ints[0] && i < ARRAY_SIZE(parms); i++)
3942 if (parms[i].val)
3943 *parms[i].val = ints[i + 1];
3944 } else {
3945 while (stp != NULL) {
3946 for (i = 0; i < ARRAY_SIZE(parms); i++) {
3947 len = strlen(parms[i].name);
3948 if (!strncmp(stp, parms[i].name, len) &&
3949 (*(stp + len) == ':' || *(stp + len) == '=')) {
3950 if (parms[i].val)
3951 *parms[i].val =
3952 simple_strtoul(stp + len + 1, NULL, 0);
3953 else
3954 printk(KERN_WARNING "st: Obsolete parameter %s\n",
3955 parms[i].name);
3956 break;
3957 }
3958 }
Tobias Klauser6391a112006-06-08 22:23:48 -07003959 if (i >= ARRAY_SIZE(parms))
Linus Torvalds1da177e2005-04-16 15:20:36 -07003960 printk(KERN_WARNING "st: invalid parameter in '%s'\n",
3961 stp);
3962 stp = strchr(stp, ',');
3963 if (stp)
3964 stp++;
3965 }
3966 }
3967
3968 validate_options();
3969
3970 return 1;
3971}
3972
3973__setup("st=", st_setup);
3974
3975#endif
3976
Arjan van de Ven00977a52007-02-12 00:55:34 -08003977static const struct file_operations st_fops =
Linus Torvalds1da177e2005-04-16 15:20:36 -07003978{
3979 .owner = THIS_MODULE,
3980 .read = st_read,
3981 .write = st_write,
Kai Makisarafd66c1b2008-01-17 22:45:22 +02003982 .unlocked_ioctl = st_ioctl,
Linus Torvalds1da177e2005-04-16 15:20:36 -07003983#ifdef CONFIG_COMPAT
3984 .compat_ioctl = st_compat_ioctl,
3985#endif
3986 .open = st_open,
3987 .flush = st_flush,
3988 .release = st_release,
Jan Blunckb4d878e2010-05-26 14:44:51 -07003989 .llseek = noop_llseek,
Linus Torvalds1da177e2005-04-16 15:20:36 -07003990};
3991
Jeff Mahoney26898af2012-08-18 15:20:40 -04003992static int create_one_cdev(struct scsi_tape *tape, int mode, int rew)
3993{
3994 int i, error;
3995 dev_t cdev_devno;
3996 struct cdev *cdev;
3997 struct device *dev;
3998 struct st_modedef *STm = &(tape->modes[mode]);
3999 char name[10];
4000 int dev_num = tape->index;
4001
4002 cdev_devno = MKDEV(SCSI_TAPE_MAJOR, TAPE_MINOR(dev_num, mode, rew));
4003
4004 cdev = cdev_alloc();
4005 if (!cdev) {
4006 pr_err("st%d: out of memory. Device not attached.\n", dev_num);
4007 error = -ENOMEM;
4008 goto out;
4009 }
4010 cdev->owner = THIS_MODULE;
4011 cdev->ops = &st_fops;
4012
4013 error = cdev_add(cdev, cdev_devno, 1);
4014 if (error) {
4015 pr_err("st%d: Can't add %s-rewind mode %d\n", dev_num,
4016 rew ? "non" : "auto", mode);
4017 pr_err("st%d: Device not attached.\n", dev_num);
4018 goto out_free;
4019 }
4020 STm->cdevs[rew] = cdev;
4021
4022 i = mode << (4 - ST_NBR_MODE_BITS);
4023 snprintf(name, 10, "%s%s%s", rew ? "n" : "",
4024 tape->disk->disk_name, st_formats[i]);
4025
4026 dev = device_create(&st_sysfs_class, &tape->device->sdev_gendev,
4027 cdev_devno, &tape->modes[mode], "%s", name);
4028 if (IS_ERR(dev)) {
4029 pr_err("st%d: device_create failed\n", dev_num);
4030 error = PTR_ERR(dev);
4031 goto out_free;
4032 }
4033
4034 STm->devs[rew] = dev;
4035
4036 return 0;
4037out_free:
4038 cdev_del(STm->cdevs[rew]);
4039 STm->cdevs[rew] = NULL;
4040out:
4041 return error;
4042}
4043
4044static int create_cdevs(struct scsi_tape *tape)
4045{
4046 int mode, error;
4047 for (mode = 0; mode < ST_NBR_MODES; ++mode) {
4048 error = create_one_cdev(tape, mode, 0);
4049 if (error)
4050 return error;
4051 error = create_one_cdev(tape, mode, 1);
4052 if (error)
4053 return error;
4054 }
4055
4056 return sysfs_create_link(&tape->device->sdev_gendev.kobj,
4057 &tape->modes[0].devs[0]->kobj, "tape");
4058}
4059
4060static void remove_cdevs(struct scsi_tape *tape)
4061{
4062 int mode, rew;
4063 sysfs_remove_link(&tape->device->sdev_gendev.kobj, "tape");
4064 for (mode = 0; mode < ST_NBR_MODES; mode++) {
4065 struct st_modedef *STm = &(tape->modes[mode]);
4066 for (rew = 0; rew < 2; rew++) {
4067 if (STm->cdevs[rew])
4068 cdev_del(STm->cdevs[rew]);
4069 if (STm->devs[rew])
4070 device_unregister(STm->devs[rew]);
4071 }
4072 }
4073}
4074
Linus Torvalds1da177e2005-04-16 15:20:36 -07004075static int st_probe(struct device *dev)
4076{
4077 struct scsi_device *SDp = to_scsi_device(dev);
4078 struct gendisk *disk = NULL;
Linus Torvalds1da177e2005-04-16 15:20:36 -07004079 struct scsi_tape *tpnt = NULL;
4080 struct st_modedef *STm;
4081 struct st_partstat *STps;
4082 struct st_buffer *buffer;
Jeff Mahoney26898af2012-08-18 15:20:40 -04004083 int i, dev_num, error;
Linus Torvalds1da177e2005-04-16 15:20:36 -07004084 char *stp;
Linus Torvalds1da177e2005-04-16 15:20:36 -07004085
4086 if (SDp->type != TYPE_TAPE)
4087 return -ENODEV;
4088 if ((stp = st_incompatible(SDp))) {
Jeff Garzik3bf743e2005-10-24 18:04:06 -04004089 sdev_printk(KERN_INFO, SDp, "Found incompatible tape\n");
Linus Torvalds1da177e2005-04-16 15:20:36 -07004090 printk(KERN_INFO "st: The suggested driver is %s.\n", stp);
4091 return -ENODEV;
4092 }
4093
Martin K. Petersen8a783622010-02-26 00:20:39 -05004094 i = queue_max_segments(SDp->request_queue);
Linus Torvalds1da177e2005-04-16 15:20:36 -07004095 if (st_max_sg_segs < i)
4096 i = st_max_sg_segs;
FUJITA Tomonorif409d6c2008-12-18 14:49:47 +09004097 buffer = new_tape_buffer((SDp->host)->unchecked_isa_dma, i);
Linus Torvalds1da177e2005-04-16 15:20:36 -07004098 if (buffer == NULL) {
4099 printk(KERN_ERR
4100 "st: Can't allocate new tape buffer. Device not attached.\n");
4101 goto out;
4102 }
4103
4104 disk = alloc_disk(1);
4105 if (!disk) {
4106 printk(KERN_ERR "st: out of memory. Device not attached.\n");
4107 goto out_buffer_free;
4108 }
4109
Jes Sorensen24669f752006-01-16 10:31:18 -05004110 tpnt = kzalloc(sizeof(struct scsi_tape), GFP_ATOMIC);
Linus Torvalds1da177e2005-04-16 15:20:36 -07004111 if (tpnt == NULL) {
Linus Torvalds1da177e2005-04-16 15:20:36 -07004112 printk(KERN_ERR "st: Can't allocate device descriptor.\n");
4113 goto out_put_disk;
4114 }
Kai Makisaraf03a5672005-08-02 13:40:47 +03004115 kref_init(&tpnt->kref);
Linus Torvalds1da177e2005-04-16 15:20:36 -07004116 tpnt->disk = disk;
Linus Torvalds1da177e2005-04-16 15:20:36 -07004117 disk->private_data = &tpnt->driver;
4118 disk->queue = SDp->request_queue;
4119 tpnt->driver = &st_template;
Linus Torvalds1da177e2005-04-16 15:20:36 -07004120
4121 tpnt->device = SDp;
4122 if (SDp->scsi_level <= 2)
4123 tpnt->tape_type = MT_ISSCSI1;
4124 else
4125 tpnt->tape_type = MT_ISSCSI2;
4126
4127 tpnt->buffer = buffer;
Kai Makisaraf03a5672005-08-02 13:40:47 +03004128 tpnt->buffer->last_SRpnt = NULL;
Linus Torvalds1da177e2005-04-16 15:20:36 -07004129
4130 tpnt->inited = 0;
4131 tpnt->dirty = 0;
4132 tpnt->in_use = 0;
4133 tpnt->drv_buffer = 1; /* Try buffering if no mode sense */
4134 tpnt->restr_dma = (SDp->host)->unchecked_isa_dma;
4135 tpnt->use_pf = (SDp->scsi_level >= SCSI_2);
4136 tpnt->density = 0;
4137 tpnt->do_auto_lock = ST_AUTO_LOCK;
4138 tpnt->can_bsr = (SDp->scsi_level > 2 ? 1 : ST_IN_FILE_POS); /* BSR mandatory in SCSI3 */
4139 tpnt->can_partitions = 0;
4140 tpnt->two_fm = ST_TWO_FM;
4141 tpnt->fast_mteom = ST_FAST_MTEOM;
4142 tpnt->scsi2_logical = ST_SCSI2LOGICAL;
Kai Makisara40f6b362008-02-24 22:23:24 +02004143 tpnt->sili = ST_SILI;
Linus Torvalds1da177e2005-04-16 15:20:36 -07004144 tpnt->immediate = ST_NOWAIT;
Lee Duncanc743e442012-03-01 12:41:01 -08004145 tpnt->immediate_filemark = 0;
Linus Torvalds1da177e2005-04-16 15:20:36 -07004146 tpnt->default_drvbuffer = 0xff; /* No forced buffering */
4147 tpnt->partition = 0;
4148 tpnt->new_partition = 0;
4149 tpnt->nbr_partitions = 0;
James Bottomleya02488e2008-11-30 10:36:26 -06004150 blk_queue_rq_timeout(tpnt->device->request_queue, ST_TIMEOUT);
Linus Torvalds1da177e2005-04-16 15:20:36 -07004151 tpnt->long_timeout = ST_LONG_TIMEOUT;
4152 tpnt->try_dio = try_direct_io && !SDp->host->unchecked_isa_dma;
4153
Linus Torvalds1da177e2005-04-16 15:20:36 -07004154 for (i = 0; i < ST_NBR_MODES; i++) {
4155 STm = &(tpnt->modes[i]);
4156 STm->defined = 0;
4157 STm->sysv = ST_SYSV;
4158 STm->defaults_for_writes = 0;
4159 STm->do_async_writes = ST_ASYNC_WRITES;
4160 STm->do_buffer_writes = ST_BUFFER_WRITES;
4161 STm->do_read_ahead = ST_READ_AHEAD;
4162 STm->default_compression = ST_DONT_TOUCH;
4163 STm->default_blksize = (-1); /* No forced size */
4164 STm->default_density = (-1); /* No forced density */
Jeff Mahoney6c648d92012-08-18 15:20:39 -04004165 STm->tape = tpnt;
Linus Torvalds1da177e2005-04-16 15:20:36 -07004166 }
4167
4168 for (i = 0; i < ST_NBR_PARTITIONS; i++) {
4169 STps = &(tpnt->ps[i]);
4170 STps->rw = ST_IDLE;
4171 STps->eof = ST_NOEOF;
4172 STps->at_sm = 0;
4173 STps->last_block_valid = 0;
4174 STps->drv_block = (-1);
4175 STps->drv_file = (-1);
4176 }
4177
4178 tpnt->current_mode = 0;
4179 tpnt->modes[0].defined = 1;
4180
4181 tpnt->density_changed = tpnt->compression_changed =
4182 tpnt->blksize_changed = 0;
Matthias Kaehlcke28f85002007-07-29 23:38:15 +02004183 mutex_init(&tpnt->lock);
Linus Torvalds1da177e2005-04-16 15:20:36 -07004184
Jeff Mahoney6c648d92012-08-18 15:20:39 -04004185 if (!idr_pre_get(&st_index_idr, GFP_KERNEL)) {
4186 pr_warn("st: idr expansion failed\n");
4187 error = -ENOMEM;
4188 goto out_put_disk;
4189 }
4190
4191 spin_lock(&st_index_lock);
4192 error = idr_get_new(&st_index_idr, tpnt, &dev_num);
4193 spin_unlock(&st_index_lock);
4194 if (error) {
4195 pr_warn("st: idr allocation failed: %d\n", error);
4196 goto out_put_disk;
4197 }
4198
4199 if (dev_num > ST_MAX_TAPES) {
4200 pr_err("st: Too many tape devices (max. %d).\n", ST_MAX_TAPES);
4201 goto out_put_index;
4202 }
4203
4204 tpnt->index = dev_num;
4205 sprintf(disk->disk_name, "st%d", dev_num);
4206
4207 dev_set_drvdata(dev, tpnt);
Linus Torvalds1da177e2005-04-16 15:20:36 -07004208
Linus Torvalds1da177e2005-04-16 15:20:36 -07004209
Jeff Mahoney26898af2012-08-18 15:20:40 -04004210 error = create_cdevs(tpnt);
4211 if (error)
4212 goto out_remove_devs;
Oliver Neukum46a243f2012-01-15 00:16:51 +01004213 scsi_autopm_put_device(SDp);
Linus Torvalds1da177e2005-04-16 15:20:36 -07004214
Kai Makisara42252852006-11-07 21:56:38 +02004215 sdev_printk(KERN_NOTICE, SDp,
Rene Herman8b1ea242006-05-20 15:00:22 -07004216 "Attached scsi tape %s\n", tape_name(tpnt));
Kai Makisara42252852006-11-07 21:56:38 +02004217 sdev_printk(KERN_INFO, SDp, "%s: try direct i/o: %s (alignment %d B)\n",
4218 tape_name(tpnt), tpnt->try_dio ? "yes" : "no",
4219 queue_dma_alignment(SDp->request_queue) + 1);
Linus Torvalds1da177e2005-04-16 15:20:36 -07004220
4221 return 0;
4222
Jeff Mahoney26898af2012-08-18 15:20:40 -04004223out_remove_devs:
4224 remove_cdevs(tpnt);
Jeff Mahoney6c648d92012-08-18 15:20:39 -04004225out_put_index:
4226 spin_lock(&st_index_lock);
4227 idr_remove(&st_index_idr, dev_num);
4228 spin_unlock(&st_index_lock);
Linus Torvalds1da177e2005-04-16 15:20:36 -07004229out_put_disk:
4230 put_disk(disk);
Jesper Juhlc9475cb2005-11-07 01:01:26 -08004231 kfree(tpnt);
Linus Torvalds1da177e2005-04-16 15:20:36 -07004232out_buffer_free:
4233 kfree(buffer);
4234out:
4235 return -ENODEV;
4236};
4237
4238
4239static int st_remove(struct device *dev)
4240{
Jeff Mahoney6c648d92012-08-18 15:20:39 -04004241 struct scsi_tape *tpnt = dev_get_drvdata(dev);
Jeff Mahoney6c648d92012-08-18 15:20:39 -04004242 int index = tpnt->index;
Linus Torvalds1da177e2005-04-16 15:20:36 -07004243
Jeff Mahoney6c648d92012-08-18 15:20:39 -04004244 scsi_autopm_get_device(to_scsi_device(dev));
Jeff Mahoney26898af2012-08-18 15:20:40 -04004245 remove_cdevs(tpnt);
Linus Torvalds1da177e2005-04-16 15:20:36 -07004246
Jeff Mahoney6c648d92012-08-18 15:20:39 -04004247 mutex_lock(&st_ref_mutex);
4248 kref_put(&tpnt->kref, scsi_tape_release);
4249 mutex_unlock(&st_ref_mutex);
4250 spin_lock(&st_index_lock);
4251 idr_remove(&st_index_idr, index);
4252 spin_unlock(&st_index_lock);
Linus Torvalds1da177e2005-04-16 15:20:36 -07004253 return 0;
4254}
4255
Kai Makisaraf03a5672005-08-02 13:40:47 +03004256/**
4257 * scsi_tape_release - Called to free the Scsi_Tape structure
4258 * @kref: pointer to embedded kref
4259 *
Arjan van de Ven0b950672006-01-11 13:16:10 +01004260 * st_ref_mutex must be held entering this routine. Because it is
Kai Makisaraf03a5672005-08-02 13:40:47 +03004261 * called on last put, you should always use the scsi_tape_get()
4262 * scsi_tape_put() helpers which manipulate the semaphore directly
4263 * and never do a direct kref_put().
4264 **/
4265static void scsi_tape_release(struct kref *kref)
4266{
4267 struct scsi_tape *tpnt = to_scsi_tape(kref);
4268 struct gendisk *disk = tpnt->disk;
4269
4270 tpnt->device = NULL;
4271
4272 if (tpnt->buffer) {
Kai Makisaraf03a5672005-08-02 13:40:47 +03004273 normalize_buffer(tpnt->buffer);
FUJITA Tomonorid0e1ae32008-12-18 14:49:40 +09004274 kfree(tpnt->buffer->reserved_pages);
Kai Makisaraf03a5672005-08-02 13:40:47 +03004275 kfree(tpnt->buffer);
4276 }
4277
4278 disk->private_data = NULL;
4279 put_disk(disk);
4280 kfree(tpnt);
4281 return;
4282}
4283
Jeff Mahoneyaf237822012-08-18 15:20:37 -04004284static struct class st_sysfs_class = {
4285 .name = "scsi_tape",
4286 .dev_attrs = st_dev_attrs,
4287};
4288
Linus Torvalds1da177e2005-04-16 15:20:36 -07004289static int __init init_st(void)
4290{
Jeff Garzik13026a62006-10-04 06:00:38 -04004291 int err;
4292
Linus Torvalds1da177e2005-04-16 15:20:36 -07004293 validate_options();
4294
Jeff Garzik13026a62006-10-04 06:00:38 -04004295 printk(KERN_INFO "st: Version %s, fixed bufsize %d, s/g segs %d\n",
Linus Torvalds1da177e2005-04-16 15:20:36 -07004296 verstr, st_fixed_buffer_size, st_max_sg_segs);
4297
Jeff Mahoneyaf237822012-08-18 15:20:37 -04004298 err = class_register(&st_sysfs_class);
4299 if (err) {
4300 pr_err("Unable register sysfs class for SCSI tapes\n");
4301 return err;
Linus Torvalds1da177e2005-04-16 15:20:36 -07004302 }
4303
Jeff Garzik13026a62006-10-04 06:00:38 -04004304 err = register_chrdev_region(MKDEV(SCSI_TAPE_MAJOR, 0),
4305 ST_MAX_TAPE_ENTRIES, "st");
4306 if (err) {
4307 printk(KERN_ERR "Unable to get major %d for SCSI tapes\n",
4308 SCSI_TAPE_MAJOR);
4309 goto err_class;
Linus Torvalds1da177e2005-04-16 15:20:36 -07004310 }
Jeff Garzik13026a62006-10-04 06:00:38 -04004311
4312 err = scsi_register_driver(&st_template.gendrv);
4313 if (err)
4314 goto err_chrdev;
4315
Robert P. J. Day405ae7d2007-02-17 19:13:42 +01004316 err = do_create_sysfs_files();
Jeff Garzik13026a62006-10-04 06:00:38 -04004317 if (err)
4318 goto err_scsidrv;
4319
4320 return 0;
4321
4322err_scsidrv:
4323 scsi_unregister_driver(&st_template.gendrv);
4324err_chrdev:
4325 unregister_chrdev_region(MKDEV(SCSI_TAPE_MAJOR, 0),
4326 ST_MAX_TAPE_ENTRIES);
4327err_class:
Jeff Mahoneyaf237822012-08-18 15:20:37 -04004328 class_unregister(&st_sysfs_class);
Jeff Garzik13026a62006-10-04 06:00:38 -04004329 return err;
Linus Torvalds1da177e2005-04-16 15:20:36 -07004330}
4331
4332static void __exit exit_st(void)
4333{
Robert P. J. Day405ae7d2007-02-17 19:13:42 +01004334 do_remove_sysfs_files();
Linus Torvalds1da177e2005-04-16 15:20:36 -07004335 scsi_unregister_driver(&st_template.gendrv);
4336 unregister_chrdev_region(MKDEV(SCSI_TAPE_MAJOR, 0),
4337 ST_MAX_TAPE_ENTRIES);
Jeff Mahoneyaf237822012-08-18 15:20:37 -04004338 class_unregister(&st_sysfs_class);
Linus Torvalds1da177e2005-04-16 15:20:36 -07004339 printk(KERN_INFO "st: Unloaded.\n");
4340}
4341
4342module_init(init_st);
4343module_exit(exit_st);
4344
4345
4346/* The sysfs driver interface. Read-only at the moment */
4347static ssize_t st_try_direct_io_show(struct device_driver *ddp, char *buf)
4348{
4349 return snprintf(buf, PAGE_SIZE, "%d\n", try_direct_io);
4350}
4351static DRIVER_ATTR(try_direct_io, S_IRUGO, st_try_direct_io_show, NULL);
4352
4353static ssize_t st_fixed_buffer_size_show(struct device_driver *ddp, char *buf)
4354{
4355 return snprintf(buf, PAGE_SIZE, "%d\n", st_fixed_buffer_size);
4356}
4357static DRIVER_ATTR(fixed_buffer_size, S_IRUGO, st_fixed_buffer_size_show, NULL);
4358
4359static ssize_t st_max_sg_segs_show(struct device_driver *ddp, char *buf)
4360{
4361 return snprintf(buf, PAGE_SIZE, "%d\n", st_max_sg_segs);
4362}
4363static DRIVER_ATTR(max_sg_segs, S_IRUGO, st_max_sg_segs_show, NULL);
4364
4365static ssize_t st_version_show(struct device_driver *ddd, char *buf)
4366{
4367 return snprintf(buf, PAGE_SIZE, "[%s]\n", verstr);
4368}
4369static DRIVER_ATTR(version, S_IRUGO, st_version_show, NULL);
4370
Robert P. J. Day405ae7d2007-02-17 19:13:42 +01004371static int do_create_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;
Jeff Garzik13026a62006-10-04 06:00:38 -04004374 int err;
Linus Torvalds1da177e2005-04-16 15:20:36 -07004375
Robert P. J. Day405ae7d2007-02-17 19:13:42 +01004376 err = driver_create_file(sysfs, &driver_attr_try_direct_io);
Jeff Garzik13026a62006-10-04 06:00:38 -04004377 if (err)
4378 return err;
Robert P. J. Day405ae7d2007-02-17 19:13:42 +01004379 err = driver_create_file(sysfs, &driver_attr_fixed_buffer_size);
Jeff Garzik13026a62006-10-04 06:00:38 -04004380 if (err)
4381 goto err_try_direct_io;
Robert P. J. Day405ae7d2007-02-17 19:13:42 +01004382 err = driver_create_file(sysfs, &driver_attr_max_sg_segs);
Jeff Garzik13026a62006-10-04 06:00:38 -04004383 if (err)
4384 goto err_attr_fixed_buf;
Robert P. J. Day405ae7d2007-02-17 19:13:42 +01004385 err = driver_create_file(sysfs, &driver_attr_version);
Jeff Garzik13026a62006-10-04 06:00:38 -04004386 if (err)
4387 goto err_attr_max_sg;
4388
4389 return 0;
4390
4391err_attr_max_sg:
Robert P. J. Day405ae7d2007-02-17 19:13:42 +01004392 driver_remove_file(sysfs, &driver_attr_max_sg_segs);
Jeff Garzik13026a62006-10-04 06:00:38 -04004393err_attr_fixed_buf:
Robert P. J. Day405ae7d2007-02-17 19:13:42 +01004394 driver_remove_file(sysfs, &driver_attr_fixed_buffer_size);
Jeff Garzik13026a62006-10-04 06:00:38 -04004395err_try_direct_io:
Robert P. J. Day405ae7d2007-02-17 19:13:42 +01004396 driver_remove_file(sysfs, &driver_attr_try_direct_io);
Jeff Garzik13026a62006-10-04 06:00:38 -04004397 return err;
Linus Torvalds1da177e2005-04-16 15:20:36 -07004398}
4399
Robert P. J. Day405ae7d2007-02-17 19:13:42 +01004400static void do_remove_sysfs_files(void)
Linus Torvalds1da177e2005-04-16 15:20:36 -07004401{
Robert P. J. Day405ae7d2007-02-17 19:13:42 +01004402 struct device_driver *sysfs = &st_template.gendrv;
Linus Torvalds1da177e2005-04-16 15:20:36 -07004403
Robert P. J. Day405ae7d2007-02-17 19:13:42 +01004404 driver_remove_file(sysfs, &driver_attr_version);
4405 driver_remove_file(sysfs, &driver_attr_max_sg_segs);
4406 driver_remove_file(sysfs, &driver_attr_fixed_buffer_size);
4407 driver_remove_file(sysfs, &driver_attr_try_direct_io);
Linus Torvalds1da177e2005-04-16 15:20:36 -07004408}
4409
Linus Torvalds1da177e2005-04-16 15:20:36 -07004410/* The sysfs simple class interface */
Tony Jonesee959b02008-02-22 00:13:36 +01004411static ssize_t
Jeff Mahoneyaf237822012-08-18 15:20:37 -04004412defined_show(struct device *dev, struct device_attribute *attr, char *buf)
Linus Torvalds1da177e2005-04-16 15:20:36 -07004413{
James Bottomley7d15d6a2008-03-14 14:12:43 -07004414 struct st_modedef *STm = dev_get_drvdata(dev);
Linus Torvalds1da177e2005-04-16 15:20:36 -07004415 ssize_t l = 0;
4416
4417 l = snprintf(buf, PAGE_SIZE, "%d\n", STm->defined);
4418 return l;
4419}
4420
Tony Jonesee959b02008-02-22 00:13:36 +01004421static ssize_t
Jeff Mahoneyaf237822012-08-18 15:20:37 -04004422default_blksize_show(struct device *dev, struct device_attribute *attr,
4423 char *buf)
Linus Torvalds1da177e2005-04-16 15:20:36 -07004424{
James Bottomley7d15d6a2008-03-14 14:12:43 -07004425 struct st_modedef *STm = dev_get_drvdata(dev);
Linus Torvalds1da177e2005-04-16 15:20:36 -07004426 ssize_t l = 0;
4427
4428 l = snprintf(buf, PAGE_SIZE, "%d\n", STm->default_blksize);
4429 return l;
4430}
4431
Linus Torvalds1da177e2005-04-16 15:20:36 -07004432
Tony Jonesee959b02008-02-22 00:13:36 +01004433static ssize_t
Jeff Mahoneyaf237822012-08-18 15:20:37 -04004434default_density_show(struct device *dev, struct device_attribute *attr,
4435 char *buf)
Linus Torvalds1da177e2005-04-16 15:20:36 -07004436{
James Bottomley7d15d6a2008-03-14 14:12:43 -07004437 struct st_modedef *STm = dev_get_drvdata(dev);
Linus Torvalds1da177e2005-04-16 15:20:36 -07004438 ssize_t l = 0;
4439 char *fmt;
4440
4441 fmt = STm->default_density >= 0 ? "0x%02x\n" : "%d\n";
4442 l = snprintf(buf, PAGE_SIZE, fmt, STm->default_density);
4443 return l;
4444}
4445
Tony Jonesee959b02008-02-22 00:13:36 +01004446static ssize_t
Jeff Mahoneyaf237822012-08-18 15:20:37 -04004447default_compression_show(struct device *dev, struct device_attribute *attr,
4448 char *buf)
Linus Torvalds1da177e2005-04-16 15:20:36 -07004449{
James Bottomley7d15d6a2008-03-14 14:12:43 -07004450 struct st_modedef *STm = dev_get_drvdata(dev);
Linus Torvalds1da177e2005-04-16 15:20:36 -07004451 ssize_t l = 0;
4452
4453 l = snprintf(buf, PAGE_SIZE, "%d\n", STm->default_compression - 1);
4454 return l;
4455}
4456
Tony Jonesee959b02008-02-22 00:13:36 +01004457static ssize_t
Jeff Mahoneyaf237822012-08-18 15:20:37 -04004458options_show(struct device *dev, struct device_attribute *attr, char *buf)
Kai Makisarab174be02008-02-24 22:29:12 +02004459{
James Bottomley7d15d6a2008-03-14 14:12:43 -07004460 struct st_modedef *STm = dev_get_drvdata(dev);
Jeff Mahoney6c648d92012-08-18 15:20:39 -04004461 struct scsi_tape *STp = STm->tape;
4462 int options;
Kai Makisarab174be02008-02-24 22:29:12 +02004463 ssize_t l = 0;
4464
Kai Makisarab174be02008-02-24 22:29:12 +02004465 options = STm->do_buffer_writes ? MT_ST_BUFFER_WRITES : 0;
4466 options |= STm->do_async_writes ? MT_ST_ASYNC_WRITES : 0;
4467 options |= STm->do_read_ahead ? MT_ST_READ_AHEAD : 0;
4468 DEB( options |= debugging ? MT_ST_DEBUGGING : 0 );
4469 options |= STp->two_fm ? MT_ST_TWO_FM : 0;
4470 options |= STp->fast_mteom ? MT_ST_FAST_MTEOM : 0;
4471 options |= STm->defaults_for_writes ? MT_ST_DEF_WRITES : 0;
4472 options |= STp->can_bsr ? MT_ST_CAN_BSR : 0;
4473 options |= STp->omit_blklims ? MT_ST_NO_BLKLIMS : 0;
4474 options |= STp->can_partitions ? MT_ST_CAN_PARTITIONS : 0;
4475 options |= STp->scsi2_logical ? MT_ST_SCSI2LOGICAL : 0;
4476 options |= STm->sysv ? MT_ST_SYSV : 0;
4477 options |= STp->immediate ? MT_ST_NOWAIT : 0;
Lee Duncanc743e442012-03-01 12:41:01 -08004478 options |= STp->immediate_filemark ? MT_ST_NOWAIT_EOF : 0;
Kai Makisarab174be02008-02-24 22:29:12 +02004479 options |= STp->sili ? MT_ST_SILI : 0;
4480
4481 l = snprintf(buf, PAGE_SIZE, "0x%08x\n", options);
4482 return l;
4483}
4484
Jeff Mahoneyaf237822012-08-18 15:20:37 -04004485static struct device_attribute st_dev_attrs[] = {
4486 __ATTR_RO(defined),
4487 __ATTR_RO(default_blksize),
4488 __ATTR_RO(default_density),
4489 __ATTR_RO(default_compression),
4490 __ATTR_RO(options),
4491 __ATTR_NULL,
4492};
Kai Makisarab174be02008-02-24 22:29:12 +02004493
Linus Torvalds1da177e2005-04-16 15:20:36 -07004494/* The following functions may be useful for a larger audience. */
FUJITA Tomonori66207422008-12-18 14:49:43 +09004495static int sgl_map_user_pages(struct st_buffer *STbp,
4496 const unsigned int max_pages, unsigned long uaddr,
4497 size_t count, int rw)
Linus Torvalds1da177e2005-04-16 15:20:36 -07004498{
James Bottomley07542b82005-08-31 20:27:22 -04004499 unsigned long end = (uaddr + count + PAGE_SIZE - 1) >> PAGE_SHIFT;
4500 unsigned long start = uaddr >> PAGE_SHIFT;
4501 const int nr_pages = end - start;
Linus Torvalds1da177e2005-04-16 15:20:36 -07004502 int res, i, j;
Linus Torvalds1da177e2005-04-16 15:20:36 -07004503 struct page **pages;
FUJITA Tomonori66207422008-12-18 14:49:43 +09004504 struct rq_map_data *mdata = &STbp->map_data;
Linus Torvalds1da177e2005-04-16 15:20:36 -07004505
Linus Torvalds1da177e2005-04-16 15:20:36 -07004506 /* User attempted Overflow! */
4507 if ((uaddr + count) < uaddr)
4508 return -EINVAL;
4509
4510 /* Too big */
4511 if (nr_pages > max_pages)
4512 return -ENOMEM;
4513
4514 /* Hmm? */
4515 if (count == 0)
4516 return 0;
4517
4518 if ((pages = kmalloc(max_pages * sizeof(*pages), GFP_KERNEL)) == NULL)
4519 return -ENOMEM;
4520
4521 /* Try to fault in all of the necessary pages */
4522 down_read(&current->mm->mmap_sem);
4523 /* rw==READ means read from drive, write into memory area */
4524 res = get_user_pages(
4525 current,
4526 current->mm,
4527 uaddr,
4528 nr_pages,
4529 rw == READ,
4530 0, /* don't force */
4531 pages,
4532 NULL);
4533 up_read(&current->mm->mmap_sem);
4534
4535 /* Errors and no page mapped should return here */
4536 if (res < nr_pages)
4537 goto out_unmap;
4538
4539 for (i=0; i < nr_pages; i++) {
4540 /* FIXME: flush superflous for rw==READ,
4541 * probably wrong function for rw==WRITE
4542 */
4543 flush_dcache_page(pages[i]);
4544 }
4545
FUJITA Tomonori66207422008-12-18 14:49:43 +09004546 mdata->offset = uaddr & ~PAGE_MASK;
FUJITA Tomonori66207422008-12-18 14:49:43 +09004547 STbp->mapped_pages = pages;
Linus Torvalds1da177e2005-04-16 15:20:36 -07004548
Linus Torvalds1da177e2005-04-16 15:20:36 -07004549 return nr_pages;
Linus Torvalds1da177e2005-04-16 15:20:36 -07004550 out_unmap:
4551 if (res > 0) {
4552 for (j=0; j < res; j++)
4553 page_cache_release(pages[j]);
Hugh Dickins6bc733e2005-12-01 20:21:57 +00004554 res = 0;
Linus Torvalds1da177e2005-04-16 15:20:36 -07004555 }
4556 kfree(pages);
4557 return res;
4558}
4559
4560
4561/* And unmap them... */
FUJITA Tomonori66207422008-12-18 14:49:43 +09004562static int sgl_unmap_user_pages(struct st_buffer *STbp,
4563 const unsigned int nr_pages, int dirtied)
Linus Torvalds1da177e2005-04-16 15:20:36 -07004564{
4565 int i;
4566
4567 for (i=0; i < nr_pages; i++) {
FUJITA Tomonori66207422008-12-18 14:49:43 +09004568 struct page *page = STbp->mapped_pages[i];
Nick Pigginb5810032005-10-29 18:16:12 -07004569
Nick Pigginb5810032005-10-29 18:16:12 -07004570 if (dirtied)
4571 SetPageDirty(page);
Linus Torvalds1da177e2005-04-16 15:20:36 -07004572 /* FIXME: cache flush missing for rw==READ
4573 * FIXME: call the correct reference counting function
4574 */
Nick Pigginb5810032005-10-29 18:16:12 -07004575 page_cache_release(page);
Linus Torvalds1da177e2005-04-16 15:20:36 -07004576 }
FUJITA Tomonori66207422008-12-18 14:49:43 +09004577 kfree(STbp->mapped_pages);
4578 STbp->mapped_pages = NULL;
Linus Torvalds1da177e2005-04-16 15:20:36 -07004579
4580 return 0;
4581}