blob: 9262cdfa4b232f8fd33a03d523db87a77e3cfa8e [file] [log] [blame]
Linus Torvalds1da177e2005-04-16 15:20:36 -07001/*
2 SCSI Tape Driver for Linux version 1.1 and newer. See the accompanying
3 file Documentation/scsi/st.txt for more information.
4
5 History:
6 Rewritten from Dwayne Forsyth's SCSI tape driver by Kai Makisara.
7 Contribution and ideas from several people including (in alphabetical
8 order) Klaus Ehrenfried, Eugene Exarevsky, Eric Lee Green, Wolfgang Denk,
9 Steve Hirsch, Andreas Koppenh"ofer, Michael Leodolter, Eyal Lebedinsky,
10 Michael Schaefer, J"org Weule, and Eric Youngdale.
11
Kai Makisara3e51d3c2010-10-09 00:17:56 +030012 Copyright 1992 - 2010 Kai Makisara
Linus Torvalds1da177e2005-04-16 15:20:36 -070013 email Kai.Makisara@kolumbus.fi
14
15 Some small formal changes - aeb, 950809
16
17 Last modified: 18-JAN-1998 Richard Gooch <rgooch@atnf.csiro.au> Devfs support
18 */
19
Kai Makisara373daac2010-12-20 18:43:39 +020020static const char *verstr = "20101219";
Linus Torvalds1da177e2005-04-16 15:20:36 -070021
22#include <linux/module.h>
23
24#include <linux/fs.h>
25#include <linux/kernel.h>
26#include <linux/sched.h>
27#include <linux/mm.h>
28#include <linux/init.h>
29#include <linux/string.h>
Tejun Heo5a0e3ad2010-03-24 17:04:11 +090030#include <linux/slab.h>
Linus Torvalds1da177e2005-04-16 15:20:36 -070031#include <linux/errno.h>
32#include <linux/mtio.h>
Kai Makisara 16c4b3e2005-05-01 18:11:55 +030033#include <linux/cdrom.h>
Linus Torvalds1da177e2005-04-16 15:20:36 -070034#include <linux/ioctl.h>
35#include <linux/fcntl.h>
36#include <linux/spinlock.h>
37#include <linux/blkdev.h>
38#include <linux/moduleparam.h>
Linus Torvalds1da177e2005-04-16 15:20:36 -070039#include <linux/cdev.h>
40#include <linux/delay.h>
Arjan van de Ven0b950672006-01-11 13:16:10 +010041#include <linux/mutex.h>
Linus Torvalds1da177e2005-04-16 15:20:36 -070042
43#include <asm/uaccess.h>
44#include <asm/dma.h>
45#include <asm/system.h>
46
47#include <scsi/scsi.h>
48#include <scsi/scsi_dbg.h>
49#include <scsi/scsi_device.h>
50#include <scsi/scsi_driver.h>
51#include <scsi/scsi_eh.h>
52#include <scsi/scsi_host.h>
53#include <scsi/scsi_ioctl.h>
Kai Makisara 16c4b3e2005-05-01 18:11:55 +030054#include <scsi/sg.h>
Linus Torvalds1da177e2005-04-16 15:20:36 -070055
56
57/* The driver prints some debugging information on the console if DEBUG
58 is defined and non-zero. */
59#define DEBUG 0
60
61#if DEBUG
62/* The message level for the debug messages is currently set to KERN_NOTICE
63 so that people can easily see the messages. Later when the debugging messages
64 in the drivers are more widely classified, this may be changed to KERN_DEBUG. */
65#define ST_DEB_MSG KERN_NOTICE
66#define DEB(a) a
67#define DEBC(a) if (debugging) { a ; }
68#else
69#define DEB(a)
70#define DEBC(a)
71#endif
72
73#define ST_KILOBYTE 1024
74
75#include "st_options.h"
76#include "st.h"
77
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
85static int st_dev_max;
86static int st_nr_dev;
87
gregkh@suse.ded2538782005-03-23 09:55:22 -080088static struct class *st_sysfs_class;
Linus Torvalds1da177e2005-04-16 15:20:36 -070089
90MODULE_AUTHOR("Kai Makisara");
Rene Hermanf018fa52006-03-08 00:14:20 -080091MODULE_DESCRIPTION("SCSI tape (st) driver");
Linus Torvalds1da177e2005-04-16 15:20:36 -070092MODULE_LICENSE("GPL");
Rene Hermanf018fa52006-03-08 00:14:20 -080093MODULE_ALIAS_CHARDEV_MAJOR(SCSI_TAPE_MAJOR);
Michael Tokarevd7b8bcb2006-10-27 16:02:37 +040094MODULE_ALIAS_SCSI_DEVICE(TYPE_TAPE);
Linus Torvalds1da177e2005-04-16 15:20:36 -070095
96/* Set 'perm' (4th argument) to 0 to disable module_param's definition
97 * of sysfs parameters (which module_param doesn't yet support).
98 * Sysfs parameters defined explicitly later.
99 */
100module_param_named(buffer_kbs, buffer_kbs, int, 0);
101MODULE_PARM_DESC(buffer_kbs, "Default driver buffer size for fixed block mode (KB; 32)");
102module_param_named(max_sg_segs, max_sg_segs, int, 0);
103MODULE_PARM_DESC(max_sg_segs, "Maximum number of scatter/gather segments to use (256)");
104module_param_named(try_direct_io, try_direct_io, int, 0);
105MODULE_PARM_DESC(try_direct_io, "Try direct I/O between user buffer and tape drive (1)");
106
107/* Extra parameters for testing */
108module_param_named(try_rdio, try_rdio, int, 0);
109MODULE_PARM_DESC(try_rdio, "Try direct read i/o when possible");
110module_param_named(try_wdio, try_wdio, int, 0);
111MODULE_PARM_DESC(try_wdio, "Try direct write i/o when possible");
112
113#ifndef MODULE
114static int write_threshold_kbs; /* retained for compatibility */
115static struct st_dev_parm {
116 char *name;
117 int *val;
118} parms[] __initdata = {
119 {
120 "buffer_kbs", &buffer_kbs
121 },
122 { /* Retained for compatibility with 2.4 */
123 "write_threshold_kbs", &write_threshold_kbs
124 },
125 {
126 "max_sg_segs", NULL
127 },
128 {
129 "try_direct_io", &try_direct_io
130 }
131};
132#endif
133
134/* Restrict the number of modes so that names for all are assigned */
135#if ST_NBR_MODES > 16
136#error "Maximum number of modes is 16"
137#endif
138/* Bit reversed order to get same names for same minors with all
139 mode counts */
Arjan van de Ven0ad78202005-11-28 16:22:25 +0100140static const char *st_formats[] = {
Linus Torvalds1da177e2005-04-16 15:20:36 -0700141 "", "r", "k", "s", "l", "t", "o", "u",
142 "m", "v", "p", "x", "a", "y", "q", "z"};
143
144/* The default definitions have been moved to st_options.h */
145
146#define ST_FIXED_BUFFER_SIZE (ST_FIXED_BUFFER_BLOCKS * ST_KILOBYTE)
147
148/* The buffer size should fit into the 24 bits for length in the
149 6-byte SCSI read and write commands. */
150#if ST_FIXED_BUFFER_SIZE >= (2 << 24 - 1)
151#error "Buffer size should not exceed (2 << 24 - 1) bytes!"
152#endif
153
154static int debugging = DEBUG;
155
156#define MAX_RETRIES 0
157#define MAX_WRITE_RETRIES 0
158#define MAX_READY_RETRIES 0
159#define NO_TAPE NOT_READY
160
161#define ST_TIMEOUT (900 * HZ)
162#define ST_LONG_TIMEOUT (14000 * HZ)
163
164/* Remove mode bits and auto-rewind bit (7) */
165#define TAPE_NR(x) ( ((iminor(x) & ~255) >> (ST_NBR_MODE_BITS + 1)) | \
166 (iminor(x) & ~(-1 << ST_MODE_SHIFT)) )
167#define TAPE_MODE(x) ((iminor(x) & ST_MODE_MASK) >> ST_MODE_SHIFT)
168
169/* Construct the minor number from the device (d), mode (m), and non-rewind (n) data */
170#define TAPE_MINOR(d, m, n) (((d & ~(255 >> (ST_NBR_MODE_BITS + 1))) << (ST_NBR_MODE_BITS + 1)) | \
171 (d & (255 >> (ST_NBR_MODE_BITS + 1))) | (m << ST_MODE_SHIFT) | ((n != 0) << 7) )
172
173/* Internal ioctl to set both density (uppermost 8 bits) and blocksize (lower
174 24 bits) */
175#define SET_DENS_AND_BLK 0x10001
176
177static DEFINE_RWLOCK(st_dev_arr_lock);
178
179static int st_fixed_buffer_size = ST_FIXED_BUFFER_SIZE;
180static int st_max_sg_segs = ST_MAX_SG;
181
182static struct scsi_tape **scsi_tapes = NULL;
183
184static int modes_defined;
185
Linus Torvalds1da177e2005-04-16 15:20:36 -0700186static int enlarge_buffer(struct st_buffer *, int, int);
Kai Makisara40f6b362008-02-24 22:23:24 +0200187static void clear_buffer(struct st_buffer *);
Linus Torvalds1da177e2005-04-16 15:20:36 -0700188static void normalize_buffer(struct st_buffer *);
189static int append_to_buffer(const char __user *, struct st_buffer *, int);
190static int from_buffer(struct st_buffer *, char __user *, int);
191static void move_buffer_data(struct st_buffer *, int);
Linus Torvalds1da177e2005-04-16 15:20:36 -0700192
FUJITA Tomonori66207422008-12-18 14:49:43 +0900193static int sgl_map_user_pages(struct st_buffer *, const unsigned int,
Linus Torvalds1da177e2005-04-16 15:20:36 -0700194 unsigned long, size_t, int);
FUJITA Tomonori66207422008-12-18 14:49:43 +0900195static int sgl_unmap_user_pages(struct st_buffer *, const unsigned int, int);
Linus Torvalds1da177e2005-04-16 15:20:36 -0700196
197static int st_probe(struct device *);
198static int st_remove(struct device *);
Linus Torvalds1da177e2005-04-16 15:20:36 -0700199
Robert P. J. Day405ae7d2007-02-17 19:13:42 +0100200static int do_create_sysfs_files(void);
201static void do_remove_sysfs_files(void);
Jeff Garzik13026a62006-10-04 06:00:38 -0400202static int do_create_class_files(struct scsi_tape *, int, int);
Linus Torvalds1da177e2005-04-16 15:20:36 -0700203
204static struct scsi_driver st_template = {
205 .owner = THIS_MODULE,
206 .gendrv = {
207 .name = "st",
208 .probe = st_probe,
209 .remove = st_remove,
210 },
Linus Torvalds1da177e2005-04-16 15:20:36 -0700211};
212
213static int st_compression(struct scsi_tape *, int);
214
215static int find_partition(struct scsi_tape *);
216static int switch_partition(struct scsi_tape *);
217
218static int st_int_ioctl(struct scsi_tape *, unsigned int, unsigned long);
219
Kai Makisaraf03a5672005-08-02 13:40:47 +0300220static void scsi_tape_release(struct kref *);
221
222#define to_scsi_tape(obj) container_of(obj, struct scsi_tape, kref)
223
Arjan van de Ven0b950672006-01-11 13:16:10 +0100224static DEFINE_MUTEX(st_ref_mutex);
Kai Makisaraf03a5672005-08-02 13:40:47 +0300225
Linus Torvalds1da177e2005-04-16 15:20:36 -0700226
227#include "osst_detect.h"
228#ifndef SIGS_FROM_OSST
229#define SIGS_FROM_OSST \
230 {"OnStream", "SC-", "", "osst"}, \
231 {"OnStream", "DI-", "", "osst"}, \
232 {"OnStream", "DP-", "", "osst"}, \
233 {"OnStream", "USB", "", "osst"}, \
234 {"OnStream", "FW-", "", "osst"}
235#endif
236
Kai Makisaraf03a5672005-08-02 13:40:47 +0300237static struct scsi_tape *scsi_tape_get(int dev)
238{
239 struct scsi_tape *STp = NULL;
240
Arjan van de Ven0b950672006-01-11 13:16:10 +0100241 mutex_lock(&st_ref_mutex);
Kai Makisaraf03a5672005-08-02 13:40:47 +0300242 write_lock(&st_dev_arr_lock);
243
244 if (dev < st_dev_max && scsi_tapes != NULL)
245 STp = scsi_tapes[dev];
246 if (!STp) goto out;
247
248 kref_get(&STp->kref);
249
250 if (!STp->device)
251 goto out_put;
252
253 if (scsi_device_get(STp->device))
254 goto out_put;
255
256 goto out;
257
258out_put:
259 kref_put(&STp->kref, scsi_tape_release);
260 STp = NULL;
261out:
262 write_unlock(&st_dev_arr_lock);
Arjan van de Ven0b950672006-01-11 13:16:10 +0100263 mutex_unlock(&st_ref_mutex);
Kai Makisaraf03a5672005-08-02 13:40:47 +0300264 return STp;
265}
266
267static void scsi_tape_put(struct scsi_tape *STp)
268{
269 struct scsi_device *sdev = STp->device;
270
Arjan van de Ven0b950672006-01-11 13:16:10 +0100271 mutex_lock(&st_ref_mutex);
Kai Makisaraf03a5672005-08-02 13:40:47 +0300272 kref_put(&STp->kref, scsi_tape_release);
273 scsi_device_put(sdev);
Arjan van de Ven0b950672006-01-11 13:16:10 +0100274 mutex_unlock(&st_ref_mutex);
Kai Makisaraf03a5672005-08-02 13:40:47 +0300275}
276
Linus Torvalds1da177e2005-04-16 15:20:36 -0700277struct st_reject_data {
278 char *vendor;
279 char *model;
280 char *rev;
281 char *driver_hint; /* Name of the correct driver, NULL if unknown */
282};
283
284static struct st_reject_data reject_list[] = {
285 /* {"XXX", "Yy-", "", NULL}, example */
286 SIGS_FROM_OSST,
287 {NULL, }};
288
289/* If the device signature is on the list of incompatible drives, the
290 function returns a pointer to the name of the correct driver (if known) */
291static char * st_incompatible(struct scsi_device* SDp)
292{
293 struct st_reject_data *rp;
294
295 for (rp=&(reject_list[0]); rp->vendor != NULL; rp++)
296 if (!strncmp(rp->vendor, SDp->vendor, strlen(rp->vendor)) &&
297 !strncmp(rp->model, SDp->model, strlen(rp->model)) &&
298 !strncmp(rp->rev, SDp->rev, strlen(rp->rev))) {
299 if (rp->driver_hint)
300 return rp->driver_hint;
301 else
302 return "unknown";
303 }
304 return NULL;
305}
306
307
308static inline char *tape_name(struct scsi_tape *tape)
309{
310 return tape->disk->disk_name;
311}
312
313
Mike Christie8b05b772005-11-08 04:06:44 -0600314static void st_analyze_sense(struct st_request *SRpnt, struct st_cmdstatus *s)
Linus Torvalds1da177e2005-04-16 15:20:36 -0700315{
316 const u8 *ucp;
Mike Christie8b05b772005-11-08 04:06:44 -0600317 const u8 *sense = SRpnt->sense;
Linus Torvalds1da177e2005-04-16 15:20:36 -0700318
Mike Christie8b05b772005-11-08 04:06:44 -0600319 s->have_sense = scsi_normalize_sense(SRpnt->sense,
320 SCSI_SENSE_BUFFERSIZE, &s->sense_hdr);
Linus Torvalds1da177e2005-04-16 15:20:36 -0700321 s->flags = 0;
322
323 if (s->have_sense) {
324 s->deferred = 0;
325 s->remainder_valid =
326 scsi_get_sense_info_fld(sense, SCSI_SENSE_BUFFERSIZE, &s->uremainder64);
327 switch (sense[0] & 0x7f) {
328 case 0x71:
329 s->deferred = 1;
330 case 0x70:
331 s->fixed_format = 1;
332 s->flags = sense[2] & 0xe0;
333 break;
334 case 0x73:
335 s->deferred = 1;
336 case 0x72:
337 s->fixed_format = 0;
338 ucp = scsi_sense_desc_find(sense, SCSI_SENSE_BUFFERSIZE, 4);
339 s->flags = ucp ? (ucp[3] & 0xe0) : 0;
340 break;
341 }
342 }
343}
344
345
346/* Convert the result to success code */
Mike Christie8b05b772005-11-08 04:06:44 -0600347static int st_chk_result(struct scsi_tape *STp, struct st_request * SRpnt)
Linus Torvalds1da177e2005-04-16 15:20:36 -0700348{
Mike Christie8b05b772005-11-08 04:06:44 -0600349 int result = SRpnt->result;
Linus Torvalds1da177e2005-04-16 15:20:36 -0700350 u8 scode;
351 DEB(const char *stp;)
352 char *name = tape_name(STp);
353 struct st_cmdstatus *cmdstatp;
354
355 if (!result)
356 return 0;
357
358 cmdstatp = &STp->buffer->cmdstat;
Kai Makisaraf03a5672005-08-02 13:40:47 +0300359 st_analyze_sense(SRpnt, cmdstatp);
Linus Torvalds1da177e2005-04-16 15:20:36 -0700360
361 if (cmdstatp->have_sense)
362 scode = STp->buffer->cmdstat.sense_hdr.sense_key;
363 else
364 scode = 0;
365
366 DEB(
367 if (debugging) {
Mike Christie8b05b772005-11-08 04:06:44 -0600368 printk(ST_DEB_MSG "%s: Error: %x, cmd: %x %x %x %x %x %x\n",
Linus Torvalds1da177e2005-04-16 15:20:36 -0700369 name, result,
Mike Christie8b05b772005-11-08 04:06:44 -0600370 SRpnt->cmd[0], SRpnt->cmd[1], SRpnt->cmd[2],
371 SRpnt->cmd[3], SRpnt->cmd[4], SRpnt->cmd[5]);
Linus Torvalds1da177e2005-04-16 15:20:36 -0700372 if (cmdstatp->have_sense)
Luben Tuikov4e73ea72006-07-07 00:02:18 -0700373 __scsi_print_sense(name, SRpnt->sense, SCSI_SENSE_BUFFERSIZE);
Linus Torvalds1da177e2005-04-16 15:20:36 -0700374 } ) /* end DEB */
375 if (!debugging) { /* Abnormal conditions for tape */
376 if (!cmdstatp->have_sense)
377 printk(KERN_WARNING
Martin K. Petersen1c9fbaf2009-01-04 03:14:11 -0500378 "%s: Error %x (driver bt 0x%x, host bt 0x%x).\n",
379 name, result, driver_byte(result),
380 host_byte(result));
Linus Torvalds1da177e2005-04-16 15:20:36 -0700381 else if (cmdstatp->have_sense &&
382 scode != NO_SENSE &&
383 scode != RECOVERED_ERROR &&
384 /* scode != UNIT_ATTENTION && */
385 scode != BLANK_CHECK &&
386 scode != VOLUME_OVERFLOW &&
Mike Christie8b05b772005-11-08 04:06:44 -0600387 SRpnt->cmd[0] != MODE_SENSE &&
388 SRpnt->cmd[0] != TEST_UNIT_READY) {
Luben Tuikov4e73ea72006-07-07 00:02:18 -0700389
390 __scsi_print_sense(name, SRpnt->sense, SCSI_SENSE_BUFFERSIZE);
Linus Torvalds1da177e2005-04-16 15:20:36 -0700391 }
392 }
393
394 if (cmdstatp->fixed_format &&
395 STp->cln_mode >= EXTENDED_SENSE_START) { /* Only fixed format sense */
396 if (STp->cln_sense_value)
Mike Christie8b05b772005-11-08 04:06:44 -0600397 STp->cleaning_req |= ((SRpnt->sense[STp->cln_mode] &
Linus Torvalds1da177e2005-04-16 15:20:36 -0700398 STp->cln_sense_mask) == STp->cln_sense_value);
399 else
Mike Christie8b05b772005-11-08 04:06:44 -0600400 STp->cleaning_req |= ((SRpnt->sense[STp->cln_mode] &
Linus Torvalds1da177e2005-04-16 15:20:36 -0700401 STp->cln_sense_mask) != 0);
402 }
403 if (cmdstatp->have_sense &&
404 cmdstatp->sense_hdr.asc == 0 && cmdstatp->sense_hdr.ascq == 0x17)
405 STp->cleaning_req = 1; /* ASC and ASCQ => cleaning requested */
406
407 STp->pos_unknown |= STp->device->was_reset;
408
409 if (cmdstatp->have_sense &&
410 scode == RECOVERED_ERROR
411#if ST_RECOVERED_WRITE_FATAL
Mike Christie8b05b772005-11-08 04:06:44 -0600412 && SRpnt->cmd[0] != WRITE_6
413 && SRpnt->cmd[0] != WRITE_FILEMARKS
Linus Torvalds1da177e2005-04-16 15:20:36 -0700414#endif
415 ) {
416 STp->recover_count++;
417 STp->recover_reg++;
418
419 DEB(
420 if (debugging) {
Mike Christie8b05b772005-11-08 04:06:44 -0600421 if (SRpnt->cmd[0] == READ_6)
Linus Torvalds1da177e2005-04-16 15:20:36 -0700422 stp = "read";
Mike Christie8b05b772005-11-08 04:06:44 -0600423 else if (SRpnt->cmd[0] == WRITE_6)
Linus Torvalds1da177e2005-04-16 15:20:36 -0700424 stp = "write";
425 else
426 stp = "ioctl";
427 printk(ST_DEB_MSG "%s: Recovered %s error (%d).\n", name, stp,
428 STp->recover_count);
429 } ) /* end DEB */
430
431 if (cmdstatp->flags == 0)
432 return 0;
433 }
434 return (-EIO);
435}
436
FUJITA Tomonori4deba242008-12-05 15:25:20 +0900437static struct st_request *st_allocate_request(struct scsi_tape *stp)
Mike Christie8b05b772005-11-08 04:06:44 -0600438{
FUJITA Tomonori4deba242008-12-05 15:25:20 +0900439 struct st_request *streq;
440
441 streq = kzalloc(sizeof(*streq), GFP_KERNEL);
442 if (streq)
443 streq->stp = stp;
444 else {
445 DEBC(printk(KERN_ERR "%s: Can't get SCSI request.\n",
446 tape_name(stp)););
447 if (signal_pending(current))
448 stp->buffer->syscall_result = -EINTR;
449 else
450 stp->buffer->syscall_result = -EBUSY;
451 }
452
453 return streq;
Mike Christie8b05b772005-11-08 04:06:44 -0600454}
455
456static void st_release_request(struct st_request *streq)
457{
458 kfree(streq);
Linus Torvalds1da177e2005-04-16 15:20:36 -0700459}
460
FUJITA Tomonori13b53b42008-12-18 14:49:41 +0900461static void st_scsi_execute_end(struct request *req, int uptodate)
462{
463 struct st_request *SRpnt = req->end_io_data;
464 struct scsi_tape *STp = SRpnt->stp;
Petr Uzelc68bf8e2011-10-21 13:31:09 +0200465 struct bio *tmp;
FUJITA Tomonori13b53b42008-12-18 14:49:41 +0900466
467 STp->buffer->cmdstat.midlevel_result = SRpnt->result = req->errors;
Tejun Heoc3a4d782009-05-07 22:24:37 +0900468 STp->buffer->cmdstat.residual = req->resid_len;
FUJITA Tomonori13b53b42008-12-18 14:49:41 +0900469
Petr Uzelc68bf8e2011-10-21 13:31:09 +0200470 tmp = SRpnt->bio;
FUJITA Tomonori13b53b42008-12-18 14:49:41 +0900471 if (SRpnt->waiting)
472 complete(SRpnt->waiting);
473
Petr Uzelc68bf8e2011-10-21 13:31:09 +0200474 blk_rq_unmap_user(tmp);
FUJITA Tomonori13b53b42008-12-18 14:49:41 +0900475 __blk_put_request(req->q, req);
476}
477
478static int st_scsi_execute(struct st_request *SRpnt, const unsigned char *cmd,
479 int data_direction, void *buffer, unsigned bufflen,
480 int timeout, int retries)
481{
482 struct request *req;
483 struct rq_map_data *mdata = &SRpnt->stp->buffer->map_data;
484 int err = 0;
485 int write = (data_direction == DMA_TO_DEVICE);
486
487 req = blk_get_request(SRpnt->stp->device->request_queue, write,
488 GFP_KERNEL);
489 if (!req)
490 return DRIVER_ERROR << 24;
491
492 req->cmd_type = REQ_TYPE_BLOCK_PC;
493 req->cmd_flags |= REQ_QUIET;
494
495 mdata->null_mapped = 1;
496
Kai Makisara02ae2c02008-12-18 14:49:50 +0900497 if (bufflen) {
498 err = blk_rq_map_user(req->q, req, mdata, NULL, bufflen,
499 GFP_KERNEL);
500 if (err) {
501 blk_put_request(req);
502 return DRIVER_ERROR << 24;
503 }
FUJITA Tomonori13b53b42008-12-18 14:49:41 +0900504 }
505
506 SRpnt->bio = req->bio;
507 req->cmd_len = COMMAND_SIZE(cmd[0]);
508 memset(req->cmd, 0, BLK_MAX_CDB);
509 memcpy(req->cmd, cmd, req->cmd_len);
510 req->sense = SRpnt->sense;
511 req->sense_len = 0;
512 req->timeout = timeout;
513 req->retries = retries;
514 req->end_io_data = SRpnt;
515
516 blk_execute_rq_nowait(req->q, NULL, req, 1, st_scsi_execute_end);
517 return 0;
518}
519
Linus Torvalds1da177e2005-04-16 15:20:36 -0700520/* Do the scsi command. Waits until command performed if do_wait is true.
521 Otherwise write_behind_check() is used to check that the command
522 has finished. */
Mike Christie8b05b772005-11-08 04:06:44 -0600523static struct st_request *
524st_do_scsi(struct st_request * SRpnt, struct scsi_tape * STp, unsigned char *cmd,
Linus Torvalds1da177e2005-04-16 15:20:36 -0700525 int bytes, int direction, int timeout, int retries, int do_wait)
526{
Kai Makisaraf03a5672005-08-02 13:40:47 +0300527 struct completion *waiting;
FUJITA Tomonori6d476262008-12-18 14:49:42 +0900528 struct rq_map_data *mdata = &STp->buffer->map_data;
529 int ret;
Linus Torvalds1da177e2005-04-16 15:20:36 -0700530
Kai Makisaraf03a5672005-08-02 13:40:47 +0300531 /* if async, make sure there's no command outstanding */
532 if (!do_wait && ((STp->buffer)->last_SRpnt)) {
533 printk(KERN_ERR "%s: Async command already active.\n",
534 tape_name(STp));
535 if (signal_pending(current))
536 (STp->buffer)->syscall_result = (-EINTR);
537 else
538 (STp->buffer)->syscall_result = (-EBUSY);
539 return NULL;
540 }
541
FUJITA Tomonori4deba242008-12-05 15:25:20 +0900542 if (!SRpnt) {
543 SRpnt = st_allocate_request(STp);
544 if (!SRpnt)
Linus Torvalds1da177e2005-04-16 15:20:36 -0700545 return NULL;
Linus Torvalds1da177e2005-04-16 15:20:36 -0700546 }
547
Kai Makisaraf03a5672005-08-02 13:40:47 +0300548 /* If async IO, set last_SRpnt. This ptr tells write_behind_check
549 which IO is outstanding. It's nulled out when the IO completes. */
550 if (!do_wait)
551 (STp->buffer)->last_SRpnt = SRpnt;
552
553 waiting = &STp->wait;
554 init_completion(waiting);
Mike Christie8b05b772005-11-08 04:06:44 -0600555 SRpnt->waiting = waiting;
556
FUJITA Tomonori66207422008-12-18 14:49:43 +0900557 if (STp->buffer->do_dio) {
FUJITA Tomonoric982c362009-11-26 09:24:13 +0900558 mdata->page_order = 0;
FUJITA Tomonori66207422008-12-18 14:49:43 +0900559 mdata->nr_entries = STp->buffer->sg_segs;
560 mdata->pages = STp->buffer->mapped_pages;
561 } else {
FUJITA Tomonoric982c362009-11-26 09:24:13 +0900562 mdata->page_order = STp->buffer->reserved_page_order;
FUJITA Tomonori6d476262008-12-18 14:49:42 +0900563 mdata->nr_entries =
564 DIV_ROUND_UP(bytes, PAGE_SIZE << mdata->page_order);
FUJITA Tomonoric982c362009-11-26 09:24:13 +0900565 mdata->pages = STp->buffer->reserved_pages;
566 mdata->offset = 0;
FUJITA Tomonori6d476262008-12-18 14:49:42 +0900567 }
568
Mike Christie8b05b772005-11-08 04:06:44 -0600569 memcpy(SRpnt->cmd, cmd, sizeof(SRpnt->cmd));
Linus Torvalds1da177e2005-04-16 15:20:36 -0700570 STp->buffer->cmdstat.have_sense = 0;
Mike Christie8b05b772005-11-08 04:06:44 -0600571 STp->buffer->syscall_result = 0;
Linus Torvalds1da177e2005-04-16 15:20:36 -0700572
FUJITA Tomonori66207422008-12-18 14:49:43 +0900573 ret = st_scsi_execute(SRpnt, cmd, direction, NULL, bytes, timeout,
574 retries);
FUJITA Tomonori6d476262008-12-18 14:49:42 +0900575 if (ret) {
Mike Christie8b05b772005-11-08 04:06:44 -0600576 /* could not allocate the buffer or request was too large */
577 (STp->buffer)->syscall_result = (-EBUSY);
Kai Makisara787926b2005-11-13 10:04:44 +0200578 (STp->buffer)->last_SRpnt = NULL;
FUJITA Tomonori6d476262008-12-18 14:49:42 +0900579 } else if (do_wait) {
Kai Makisaraf03a5672005-08-02 13:40:47 +0300580 wait_for_completion(waiting);
Mike Christie8b05b772005-11-08 04:06:44 -0600581 SRpnt->waiting = NULL;
Linus Torvalds1da177e2005-04-16 15:20:36 -0700582 (STp->buffer)->syscall_result = st_chk_result(STp, SRpnt);
583 }
Mike Christie8b05b772005-11-08 04:06:44 -0600584
Linus Torvalds1da177e2005-04-16 15:20:36 -0700585 return SRpnt;
586}
587
588
589/* Handle the write-behind checking (waits for completion). Returns -ENOSPC if
590 write has been correct but EOM early warning reached, -EIO if write ended in
591 error or zero if write successful. Asynchronous writes are used only in
592 variable block mode. */
593static int write_behind_check(struct scsi_tape * STp)
594{
595 int retval = 0;
596 struct st_buffer *STbuffer;
597 struct st_partstat *STps;
598 struct st_cmdstatus *cmdstatp;
Mike Christie8b05b772005-11-08 04:06:44 -0600599 struct st_request *SRpnt;
Linus Torvalds1da177e2005-04-16 15:20:36 -0700600
601 STbuffer = STp->buffer;
602 if (!STbuffer->writing)
603 return 0;
604
605 DEB(
606 if (STp->write_pending)
607 STp->nbr_waits++;
608 else
609 STp->nbr_finished++;
610 ) /* end DEB */
611
612 wait_for_completion(&(STp->wait));
Kai Makisaraf03a5672005-08-02 13:40:47 +0300613 SRpnt = STbuffer->last_SRpnt;
614 STbuffer->last_SRpnt = NULL;
Mike Christie8b05b772005-11-08 04:06:44 -0600615 SRpnt->waiting = NULL;
Linus Torvalds1da177e2005-04-16 15:20:36 -0700616
Kai Makisaraf03a5672005-08-02 13:40:47 +0300617 (STp->buffer)->syscall_result = st_chk_result(STp, SRpnt);
Mike Christie8b05b772005-11-08 04:06:44 -0600618 st_release_request(SRpnt);
Linus Torvalds1da177e2005-04-16 15:20:36 -0700619
620 STbuffer->buffer_bytes -= STbuffer->writing;
621 STps = &(STp->ps[STp->partition]);
622 if (STps->drv_block >= 0) {
623 if (STp->block_size == 0)
624 STps->drv_block++;
625 else
626 STps->drv_block += STbuffer->writing / STp->block_size;
627 }
628
629 cmdstatp = &STbuffer->cmdstat;
630 if (STbuffer->syscall_result) {
631 retval = -EIO;
632 if (cmdstatp->have_sense && !cmdstatp->deferred &&
633 (cmdstatp->flags & SENSE_EOM) &&
634 (cmdstatp->sense_hdr.sense_key == NO_SENSE ||
635 cmdstatp->sense_hdr.sense_key == RECOVERED_ERROR)) {
636 /* EOM at write-behind, has all data been written? */
637 if (!cmdstatp->remainder_valid ||
638 cmdstatp->uremainder64 == 0)
639 retval = -ENOSPC;
640 }
641 if (retval == -EIO)
642 STps->drv_block = -1;
643 }
644 STbuffer->writing = 0;
645
646 DEB(if (debugging && retval)
647 printk(ST_DEB_MSG "%s: Async write error %x, return value %d.\n",
648 tape_name(STp), STbuffer->cmdstat.midlevel_result, retval);) /* end DEB */
649
650 return retval;
651}
652
653
654/* Step over EOF if it has been inadvertently crossed (ioctl not used because
655 it messes up the block number). */
656static int cross_eof(struct scsi_tape * STp, int forward)
657{
Mike Christie8b05b772005-11-08 04:06:44 -0600658 struct st_request *SRpnt;
Linus Torvalds1da177e2005-04-16 15:20:36 -0700659 unsigned char cmd[MAX_COMMAND_SIZE];
660
661 cmd[0] = SPACE;
662 cmd[1] = 0x01; /* Space FileMarks */
663 if (forward) {
664 cmd[2] = cmd[3] = 0;
665 cmd[4] = 1;
666 } else
667 cmd[2] = cmd[3] = cmd[4] = 0xff; /* -1 filemarks */
668 cmd[5] = 0;
669
670 DEBC(printk(ST_DEB_MSG "%s: Stepping over filemark %s.\n",
671 tape_name(STp), forward ? "forward" : "backward"));
672
Kai Makisara02ae2c02008-12-18 14:49:50 +0900673 SRpnt = st_do_scsi(NULL, STp, cmd, 0, DMA_NONE,
674 STp->device->request_queue->rq_timeout,
675 MAX_RETRIES, 1);
Linus Torvalds1da177e2005-04-16 15:20:36 -0700676 if (!SRpnt)
Kai Makisara02ae2c02008-12-18 14:49:50 +0900677 return (STp->buffer)->syscall_result;
Linus Torvalds1da177e2005-04-16 15:20:36 -0700678
Kai Makisara02ae2c02008-12-18 14:49:50 +0900679 st_release_request(SRpnt);
680 SRpnt = NULL;
Linus Torvalds1da177e2005-04-16 15:20:36 -0700681
682 if ((STp->buffer)->cmdstat.midlevel_result != 0)
683 printk(KERN_ERR "%s: Stepping over filemark %s failed.\n",
684 tape_name(STp), forward ? "forward" : "backward");
685
Kai Makisara02ae2c02008-12-18 14:49:50 +0900686 return (STp->buffer)->syscall_result;
Linus Torvalds1da177e2005-04-16 15:20:36 -0700687}
688
689
690/* Flush the write buffer (never need to write if variable blocksize). */
Adrian Bunk8ef8d592008-04-14 17:17:16 +0300691static int st_flush_write_buffer(struct scsi_tape * STp)
Linus Torvalds1da177e2005-04-16 15:20:36 -0700692{
Kai Makisara786231a2008-07-11 15:06:40 +0300693 int transfer, blks;
Linus Torvalds1da177e2005-04-16 15:20:36 -0700694 int result;
695 unsigned char cmd[MAX_COMMAND_SIZE];
Mike Christie8b05b772005-11-08 04:06:44 -0600696 struct st_request *SRpnt;
Linus Torvalds1da177e2005-04-16 15:20:36 -0700697 struct st_partstat *STps;
698
699 result = write_behind_check(STp);
700 if (result)
701 return result;
702
703 result = 0;
704 if (STp->dirty == 1) {
705
Kai Makisara786231a2008-07-11 15:06:40 +0300706 transfer = STp->buffer->buffer_bytes;
Linus Torvalds1da177e2005-04-16 15:20:36 -0700707 DEBC(printk(ST_DEB_MSG "%s: Flushing %d bytes.\n",
708 tape_name(STp), transfer));
709
Linus Torvalds1da177e2005-04-16 15:20:36 -0700710 memset(cmd, 0, MAX_COMMAND_SIZE);
711 cmd[0] = WRITE_6;
712 cmd[1] = 1;
713 blks = transfer / STp->block_size;
714 cmd[2] = blks >> 16;
715 cmd[3] = blks >> 8;
716 cmd[4] = blks;
717
718 SRpnt = st_do_scsi(NULL, STp, cmd, transfer, DMA_TO_DEVICE,
James Bottomleya02488e2008-11-30 10:36:26 -0600719 STp->device->request_queue->rq_timeout,
720 MAX_WRITE_RETRIES, 1);
Linus Torvalds1da177e2005-04-16 15:20:36 -0700721 if (!SRpnt)
722 return (STp->buffer)->syscall_result;
723
724 STps = &(STp->ps[STp->partition]);
725 if ((STp->buffer)->syscall_result != 0) {
726 struct st_cmdstatus *cmdstatp = &STp->buffer->cmdstat;
727
728 if (cmdstatp->have_sense && !cmdstatp->deferred &&
729 (cmdstatp->flags & SENSE_EOM) &&
730 (cmdstatp->sense_hdr.sense_key == NO_SENSE ||
731 cmdstatp->sense_hdr.sense_key == RECOVERED_ERROR) &&
732 (!cmdstatp->remainder_valid ||
733 cmdstatp->uremainder64 == 0)) { /* All written at EOM early warning */
734 STp->dirty = 0;
735 (STp->buffer)->buffer_bytes = 0;
736 if (STps->drv_block >= 0)
737 STps->drv_block += blks;
738 result = (-ENOSPC);
739 } else {
740 printk(KERN_ERR "%s: Error on flush.\n",
741 tape_name(STp));
742 STps->drv_block = (-1);
743 result = (-EIO);
744 }
745 } else {
746 if (STps->drv_block >= 0)
747 STps->drv_block += blks;
748 STp->dirty = 0;
749 (STp->buffer)->buffer_bytes = 0;
750 }
Mike Christie8b05b772005-11-08 04:06:44 -0600751 st_release_request(SRpnt);
Linus Torvalds1da177e2005-04-16 15:20:36 -0700752 SRpnt = NULL;
753 }
754 return result;
755}
756
757
758/* Flush the tape buffer. The tape will be positioned correctly unless
759 seek_next is true. */
760static int flush_buffer(struct scsi_tape *STp, int seek_next)
761{
762 int backspace, result;
763 struct st_buffer *STbuffer;
764 struct st_partstat *STps;
765
766 STbuffer = STp->buffer;
767
768 /*
769 * If there was a bus reset, block further access
770 * to this device.
771 */
772 if (STp->pos_unknown)
773 return (-EIO);
774
775 if (STp->ready != ST_READY)
776 return 0;
777 STps = &(STp->ps[STp->partition]);
778 if (STps->rw == ST_WRITING) /* Writing */
Adrian Bunk8ef8d592008-04-14 17:17:16 +0300779 return st_flush_write_buffer(STp);
Linus Torvalds1da177e2005-04-16 15:20:36 -0700780
781 if (STp->block_size == 0)
782 return 0;
783
784 backspace = ((STp->buffer)->buffer_bytes +
785 (STp->buffer)->read_pointer) / STp->block_size -
786 ((STp->buffer)->read_pointer + STp->block_size - 1) /
787 STp->block_size;
788 (STp->buffer)->buffer_bytes = 0;
789 (STp->buffer)->read_pointer = 0;
790 result = 0;
791 if (!seek_next) {
792 if (STps->eof == ST_FM_HIT) {
793 result = cross_eof(STp, 0); /* Back over the EOF hit */
794 if (!result)
795 STps->eof = ST_NOEOF;
796 else {
797 if (STps->drv_file >= 0)
798 STps->drv_file++;
799 STps->drv_block = 0;
800 }
801 }
802 if (!result && backspace > 0)
803 result = st_int_ioctl(STp, MTBSR, backspace);
804 } else if (STps->eof == ST_FM_HIT) {
805 if (STps->drv_file >= 0)
806 STps->drv_file++;
807 STps->drv_block = 0;
808 STps->eof = ST_NOEOF;
809 }
810 return result;
811
812}
813
814/* Set the mode parameters */
815static int set_mode_densblk(struct scsi_tape * STp, struct st_modedef * STm)
816{
817 int set_it = 0;
818 unsigned long arg;
819 char *name = tape_name(STp);
820
821 if (!STp->density_changed &&
822 STm->default_density >= 0 &&
823 STm->default_density != STp->density) {
824 arg = STm->default_density;
825 set_it = 1;
826 } else
827 arg = STp->density;
828 arg <<= MT_ST_DENSITY_SHIFT;
829 if (!STp->blksize_changed &&
830 STm->default_blksize >= 0 &&
831 STm->default_blksize != STp->block_size) {
832 arg |= STm->default_blksize;
833 set_it = 1;
834 } else
835 arg |= STp->block_size;
836 if (set_it &&
837 st_int_ioctl(STp, SET_DENS_AND_BLK, arg)) {
838 printk(KERN_WARNING
839 "%s: Can't set default block size to %d bytes and density %x.\n",
840 name, STm->default_blksize, STm->default_density);
841 if (modes_defined)
842 return (-EINVAL);
843 }
844 return 0;
845}
846
847
Mike Christie8b05b772005-11-08 04:06:44 -0600848/* Lock or unlock the drive door. Don't use when st_request allocated. */
Linus Torvalds1da177e2005-04-16 15:20:36 -0700849static int do_door_lock(struct scsi_tape * STp, int do_lock)
850{
851 int retval, cmd;
852 DEB(char *name = tape_name(STp);)
853
854
855 cmd = do_lock ? SCSI_IOCTL_DOORLOCK : SCSI_IOCTL_DOORUNLOCK;
856 DEBC(printk(ST_DEB_MSG "%s: %socking drive door.\n", name,
857 do_lock ? "L" : "Unl"));
858 retval = scsi_ioctl(STp->device, cmd, NULL);
859 if (!retval) {
860 STp->door_locked = do_lock ? ST_LOCKED_EXPLICIT : ST_UNLOCKED;
861 }
862 else {
863 STp->door_locked = ST_LOCK_FAILS;
864 }
865 return retval;
866}
867
868
869/* Set the internal state after reset */
870static void reset_state(struct scsi_tape *STp)
871{
872 int i;
873 struct st_partstat *STps;
874
875 STp->pos_unknown = 0;
876 for (i = 0; i < ST_NBR_PARTITIONS; i++) {
877 STps = &(STp->ps[i]);
878 STps->rw = ST_IDLE;
879 STps->eof = ST_NOEOF;
880 STps->at_sm = 0;
881 STps->last_block_valid = 0;
882 STps->drv_block = -1;
883 STps->drv_file = -1;
884 }
885 if (STp->can_partitions) {
886 STp->partition = find_partition(STp);
887 if (STp->partition < 0)
888 STp->partition = 0;
889 STp->new_partition = STp->partition;
890 }
891}
892
893/* Test if the drive is ready. Returns either one of the codes below or a negative system
894 error code. */
895#define CHKRES_READY 0
896#define CHKRES_NEW_SESSION 1
897#define CHKRES_NOT_READY 2
898#define CHKRES_NO_TAPE 3
899
900#define MAX_ATTENTIONS 10
901
902static int test_ready(struct scsi_tape *STp, int do_wait)
903{
904 int attentions, waits, max_wait, scode;
905 int retval = CHKRES_READY, new_session = 0;
906 unsigned char cmd[MAX_COMMAND_SIZE];
Kai Makisara02ae2c02008-12-18 14:49:50 +0900907 struct st_request *SRpnt = NULL;
Linus Torvalds1da177e2005-04-16 15:20:36 -0700908 struct st_cmdstatus *cmdstatp = &STp->buffer->cmdstat;
909
910 max_wait = do_wait ? ST_BLOCK_SECONDS : 0;
911
912 for (attentions=waits=0; ; ) {
913 memset((void *) &cmd[0], 0, MAX_COMMAND_SIZE);
914 cmd[0] = TEST_UNIT_READY;
Kai Makisara02ae2c02008-12-18 14:49:50 +0900915 SRpnt = st_do_scsi(SRpnt, STp, cmd, 0, DMA_NONE,
916 STp->long_timeout, MAX_READY_RETRIES, 1);
Linus Torvalds1da177e2005-04-16 15:20:36 -0700917
Kai Makisara02ae2c02008-12-18 14:49:50 +0900918 if (!SRpnt) {
919 retval = (STp->buffer)->syscall_result;
Linus Torvalds1da177e2005-04-16 15:20:36 -0700920 break;
Kai Makisara02ae2c02008-12-18 14:49:50 +0900921 }
Linus Torvalds1da177e2005-04-16 15:20:36 -0700922
923 if (cmdstatp->have_sense) {
924
925 scode = cmdstatp->sense_hdr.sense_key;
926
927 if (scode == UNIT_ATTENTION) { /* New media? */
928 new_session = 1;
929 if (attentions < MAX_ATTENTIONS) {
930 attentions++;
931 continue;
932 }
933 else {
934 retval = (-EIO);
935 break;
936 }
937 }
938
939 if (scode == NOT_READY) {
940 if (waits < max_wait) {
941 if (msleep_interruptible(1000)) {
942 retval = (-EINTR);
943 break;
944 }
945 waits++;
946 continue;
947 }
948 else {
949 if ((STp->device)->scsi_level >= SCSI_2 &&
950 cmdstatp->sense_hdr.asc == 0x3a) /* Check ASC */
951 retval = CHKRES_NO_TAPE;
952 else
953 retval = CHKRES_NOT_READY;
954 break;
955 }
956 }
957 }
958
959 retval = (STp->buffer)->syscall_result;
960 if (!retval)
961 retval = new_session ? CHKRES_NEW_SESSION : CHKRES_READY;
962 break;
963 }
964
Kai Makisara02ae2c02008-12-18 14:49:50 +0900965 if (SRpnt != NULL)
966 st_release_request(SRpnt);
Linus Torvalds1da177e2005-04-16 15:20:36 -0700967 return retval;
968}
969
970
971/* See if the drive is ready and gather information about the tape. Return values:
972 < 0 negative error code from errno.h
973 0 drive ready
974 1 drive not ready (possibly no tape)
975*/
976static int check_tape(struct scsi_tape *STp, struct file *filp)
977{
978 int i, retval, new_session = 0, do_wait;
979 unsigned char cmd[MAX_COMMAND_SIZE], saved_cleaning;
980 unsigned short st_flags = filp->f_flags;
Mike Christie8b05b772005-11-08 04:06:44 -0600981 struct st_request *SRpnt = NULL;
Linus Torvalds1da177e2005-04-16 15:20:36 -0700982 struct st_modedef *STm;
983 struct st_partstat *STps;
984 char *name = tape_name(STp);
Josef Sipek7ac62072006-12-08 02:37:37 -0800985 struct inode *inode = filp->f_path.dentry->d_inode;
Linus Torvalds1da177e2005-04-16 15:20:36 -0700986 int mode = TAPE_MODE(inode);
987
988 STp->ready = ST_READY;
989
990 if (mode != STp->current_mode) {
991 DEBC(printk(ST_DEB_MSG "%s: Mode change from %d to %d.\n",
992 name, STp->current_mode, mode));
993 new_session = 1;
994 STp->current_mode = mode;
995 }
996 STm = &(STp->modes[STp->current_mode]);
997
998 saved_cleaning = STp->cleaning_req;
999 STp->cleaning_req = 0;
1000
1001 do_wait = ((filp->f_flags & O_NONBLOCK) == 0);
1002 retval = test_ready(STp, do_wait);
1003
1004 if (retval < 0)
1005 goto err_out;
1006
1007 if (retval == CHKRES_NEW_SESSION) {
1008 STp->pos_unknown = 0;
1009 STp->partition = STp->new_partition = 0;
1010 if (STp->can_partitions)
1011 STp->nbr_partitions = 1; /* This guess will be updated later
1012 if necessary */
1013 for (i = 0; i < ST_NBR_PARTITIONS; i++) {
1014 STps = &(STp->ps[i]);
1015 STps->rw = ST_IDLE;
1016 STps->eof = ST_NOEOF;
1017 STps->at_sm = 0;
1018 STps->last_block_valid = 0;
1019 STps->drv_block = 0;
1020 STps->drv_file = 0;
1021 }
1022 new_session = 1;
1023 }
1024 else {
1025 STp->cleaning_req |= saved_cleaning;
1026
1027 if (retval == CHKRES_NOT_READY || retval == CHKRES_NO_TAPE) {
1028 if (retval == CHKRES_NO_TAPE)
1029 STp->ready = ST_NO_TAPE;
1030 else
1031 STp->ready = ST_NOT_READY;
1032
1033 STp->density = 0; /* Clear the erroneous "residue" */
1034 STp->write_prot = 0;
1035 STp->block_size = 0;
1036 STp->ps[0].drv_file = STp->ps[0].drv_block = (-1);
1037 STp->partition = STp->new_partition = 0;
1038 STp->door_locked = ST_UNLOCKED;
1039 return CHKRES_NOT_READY;
1040 }
1041 }
1042
1043 if (STp->omit_blklims)
1044 STp->min_block = STp->max_block = (-1);
1045 else {
1046 memset((void *) &cmd[0], 0, MAX_COMMAND_SIZE);
1047 cmd[0] = READ_BLOCK_LIMITS;
1048
Kai Makisara02ae2c02008-12-18 14:49:50 +09001049 SRpnt = st_do_scsi(SRpnt, STp, cmd, 6, DMA_FROM_DEVICE,
1050 STp->device->request_queue->rq_timeout,
1051 MAX_READY_RETRIES, 1);
1052 if (!SRpnt) {
1053 retval = (STp->buffer)->syscall_result;
Linus Torvalds1da177e2005-04-16 15:20:36 -07001054 goto err_out;
1055 }
1056
Mike Christie8b05b772005-11-08 04:06:44 -06001057 if (!SRpnt->result && !STp->buffer->cmdstat.have_sense) {
Linus Torvalds1da177e2005-04-16 15:20:36 -07001058 STp->max_block = ((STp->buffer)->b_data[1] << 16) |
1059 ((STp->buffer)->b_data[2] << 8) | (STp->buffer)->b_data[3];
1060 STp->min_block = ((STp->buffer)->b_data[4] << 8) |
1061 (STp->buffer)->b_data[5];
1062 if ( DEB( debugging || ) !STp->inited)
Kai Makisara42252852006-11-07 21:56:38 +02001063 printk(KERN_INFO
Linus Torvalds1da177e2005-04-16 15:20:36 -07001064 "%s: Block limits %d - %d bytes.\n", name,
1065 STp->min_block, STp->max_block);
1066 } else {
1067 STp->min_block = STp->max_block = (-1);
1068 DEBC(printk(ST_DEB_MSG "%s: Can't read block limits.\n",
1069 name));
1070 }
1071 }
1072
1073 memset((void *) &cmd[0], 0, MAX_COMMAND_SIZE);
1074 cmd[0] = MODE_SENSE;
1075 cmd[4] = 12;
1076
Kai Makisara02ae2c02008-12-18 14:49:50 +09001077 SRpnt = st_do_scsi(SRpnt, STp, cmd, 12, DMA_FROM_DEVICE,
1078 STp->device->request_queue->rq_timeout,
1079 MAX_READY_RETRIES, 1);
1080 if (!SRpnt) {
1081 retval = (STp->buffer)->syscall_result;
Linus Torvalds1da177e2005-04-16 15:20:36 -07001082 goto err_out;
1083 }
1084
1085 if ((STp->buffer)->syscall_result != 0) {
1086 DEBC(printk(ST_DEB_MSG "%s: No Mode Sense.\n", name));
1087 STp->block_size = ST_DEFAULT_BLOCK; /* Educated guess (?) */
1088 (STp->buffer)->syscall_result = 0; /* Prevent error propagation */
1089 STp->drv_write_prot = 0;
1090 } else {
1091 DEBC(printk(ST_DEB_MSG
1092 "%s: Mode sense. Length %d, medium %x, WBS %x, BLL %d\n",
1093 name,
1094 (STp->buffer)->b_data[0], (STp->buffer)->b_data[1],
1095 (STp->buffer)->b_data[2], (STp->buffer)->b_data[3]));
1096
1097 if ((STp->buffer)->b_data[3] >= 8) {
1098 STp->drv_buffer = ((STp->buffer)->b_data[2] >> 4) & 7;
1099 STp->density = (STp->buffer)->b_data[4];
1100 STp->block_size = (STp->buffer)->b_data[9] * 65536 +
1101 (STp->buffer)->b_data[10] * 256 + (STp->buffer)->b_data[11];
1102 DEBC(printk(ST_DEB_MSG
1103 "%s: Density %x, tape length: %x, drv buffer: %d\n",
1104 name, STp->density, (STp->buffer)->b_data[5] * 65536 +
1105 (STp->buffer)->b_data[6] * 256 + (STp->buffer)->b_data[7],
1106 STp->drv_buffer));
1107 }
1108 STp->drv_write_prot = ((STp->buffer)->b_data[2] & 0x80) != 0;
1109 }
Mike Christie8b05b772005-11-08 04:06:44 -06001110 st_release_request(SRpnt);
Linus Torvalds1da177e2005-04-16 15:20:36 -07001111 SRpnt = NULL;
1112 STp->inited = 1;
1113
1114 if (STp->block_size > 0)
1115 (STp->buffer)->buffer_blocks =
1116 (STp->buffer)->buffer_size / STp->block_size;
1117 else
1118 (STp->buffer)->buffer_blocks = 1;
1119 (STp->buffer)->buffer_bytes = (STp->buffer)->read_pointer = 0;
1120
1121 DEBC(printk(ST_DEB_MSG
1122 "%s: Block size: %d, buffer size: %d (%d blocks).\n", name,
1123 STp->block_size, (STp->buffer)->buffer_size,
1124 (STp->buffer)->buffer_blocks));
1125
1126 if (STp->drv_write_prot) {
1127 STp->write_prot = 1;
1128
1129 DEBC(printk(ST_DEB_MSG "%s: Write protected\n", name));
1130
1131 if (do_wait &&
1132 ((st_flags & O_ACCMODE) == O_WRONLY ||
1133 (st_flags & O_ACCMODE) == O_RDWR)) {
1134 retval = (-EROFS);
1135 goto err_out;
1136 }
1137 }
1138
1139 if (STp->can_partitions && STp->nbr_partitions < 1) {
1140 /* This code is reached when the device is opened for the first time
1141 after the driver has been initialized with tape in the drive and the
1142 partition support has been enabled. */
1143 DEBC(printk(ST_DEB_MSG
1144 "%s: Updating partition number in status.\n", name));
1145 if ((STp->partition = find_partition(STp)) < 0) {
1146 retval = STp->partition;
1147 goto err_out;
1148 }
1149 STp->new_partition = STp->partition;
1150 STp->nbr_partitions = 1; /* This guess will be updated when necessary */
1151 }
1152
1153 if (new_session) { /* Change the drive parameters for the new mode */
1154 STp->density_changed = STp->blksize_changed = 0;
1155 STp->compression_changed = 0;
1156 if (!(STm->defaults_for_writes) &&
1157 (retval = set_mode_densblk(STp, STm)) < 0)
1158 goto err_out;
1159
1160 if (STp->default_drvbuffer != 0xff) {
1161 if (st_int_ioctl(STp, MTSETDRVBUFFER, STp->default_drvbuffer))
1162 printk(KERN_WARNING
1163 "%s: Can't set default drive buffering to %d.\n",
1164 name, STp->default_drvbuffer);
1165 }
1166 }
1167
1168 return CHKRES_READY;
1169
1170 err_out:
1171 return retval;
1172}
1173
1174
Jonathan Corbetb3369c62008-05-15 16:08:15 -06001175 /* Open the device. Needs to take the BKL only because of incrementing the SCSI host
Linus Torvalds1da177e2005-04-16 15:20:36 -07001176 module count. */
1177static int st_open(struct inode *inode, struct file *filp)
1178{
1179 int i, retval = (-EIO);
Oliver Neukum46a243f2012-01-15 00:16:51 +01001180 int resumed = 0;
Linus Torvalds1da177e2005-04-16 15:20:36 -07001181 struct scsi_tape *STp;
1182 struct st_partstat *STps;
1183 int dev = TAPE_NR(inode);
1184 char *name;
1185
Arnd Bergmann2a48fc02010-06-02 14:28:52 +02001186 mutex_lock(&st_mutex);
Linus Torvalds1da177e2005-04-16 15:20:36 -07001187 /*
1188 * We really want to do nonseekable_open(inode, filp); here, but some
1189 * versions of tar incorrectly call lseek on tapes and bail out if that
1190 * fails. So we disallow pread() and pwrite(), but permit lseeks.
1191 */
1192 filp->f_mode &= ~(FMODE_PREAD | FMODE_PWRITE);
1193
Jonathan Corbetb3369c62008-05-15 16:08:15 -06001194 if (!(STp = scsi_tape_get(dev))) {
Arnd Bergmann2a48fc02010-06-02 14:28:52 +02001195 mutex_unlock(&st_mutex);
Kai Makisaraf03a5672005-08-02 13:40:47 +03001196 return -ENXIO;
Jonathan Corbetb3369c62008-05-15 16:08:15 -06001197 }
Kai Makisaraf03a5672005-08-02 13:40:47 +03001198
Linus Torvalds1da177e2005-04-16 15:20:36 -07001199 write_lock(&st_dev_arr_lock);
Linus Torvalds1da177e2005-04-16 15:20:36 -07001200 filp->private_data = STp;
1201 name = tape_name(STp);
1202
1203 if (STp->in_use) {
1204 write_unlock(&st_dev_arr_lock);
Kai Makisaraf03a5672005-08-02 13:40:47 +03001205 scsi_tape_put(STp);
Arnd Bergmann2a48fc02010-06-02 14:28:52 +02001206 mutex_unlock(&st_mutex);
Linus Torvalds1da177e2005-04-16 15:20:36 -07001207 DEB( printk(ST_DEB_MSG "%s: Device already in use.\n", name); )
1208 return (-EBUSY);
1209 }
1210
Linus Torvalds1da177e2005-04-16 15:20:36 -07001211 STp->in_use = 1;
1212 write_unlock(&st_dev_arr_lock);
1213 STp->rew_at_close = STp->autorew_dev = (iminor(inode) & 0x80) == 0;
1214
Oliver Neukum46a243f2012-01-15 00:16:51 +01001215 if (scsi_autopm_get_device(STp->device) < 0) {
1216 retval = -EIO;
1217 goto err_out;
1218 }
1219 resumed = 1;
Linus Torvalds1da177e2005-04-16 15:20:36 -07001220 if (!scsi_block_when_processing_errors(STp->device)) {
1221 retval = (-ENXIO);
1222 goto err_out;
1223 }
1224
1225 /* See that we have at least a one page buffer available */
1226 if (!enlarge_buffer(STp->buffer, PAGE_SIZE, STp->restr_dma)) {
1227 printk(KERN_WARNING "%s: Can't allocate one page tape buffer.\n",
1228 name);
1229 retval = (-EOVERFLOW);
1230 goto err_out;
1231 }
1232
Kai Makisara40f6b362008-02-24 22:23:24 +02001233 (STp->buffer)->cleared = 0;
Linus Torvalds1da177e2005-04-16 15:20:36 -07001234 (STp->buffer)->writing = 0;
1235 (STp->buffer)->syscall_result = 0;
1236
1237 STp->write_prot = ((filp->f_flags & O_ACCMODE) == O_RDONLY);
1238
1239 STp->dirty = 0;
1240 for (i = 0; i < ST_NBR_PARTITIONS; i++) {
1241 STps = &(STp->ps[i]);
1242 STps->rw = ST_IDLE;
1243 }
Kai Makisara9abe16c2007-02-03 13:21:29 +02001244 STp->try_dio_now = STp->try_dio;
Linus Torvalds1da177e2005-04-16 15:20:36 -07001245 STp->recover_count = 0;
1246 DEB( STp->nbr_waits = STp->nbr_finished = 0;
Kai Makisaradeee13d2008-02-22 20:11:21 +02001247 STp->nbr_requests = STp->nbr_dio = STp->nbr_pages = 0; )
Linus Torvalds1da177e2005-04-16 15:20:36 -07001248
1249 retval = check_tape(STp, filp);
1250 if (retval < 0)
1251 goto err_out;
1252 if ((filp->f_flags & O_NONBLOCK) == 0 &&
1253 retval != CHKRES_READY) {
Kai Makisara413f7322006-10-05 22:59:46 +03001254 if (STp->ready == NO_TAPE)
1255 retval = (-ENOMEDIUM);
1256 else
1257 retval = (-EIO);
Linus Torvalds1da177e2005-04-16 15:20:36 -07001258 goto err_out;
1259 }
Arnd Bergmann2a48fc02010-06-02 14:28:52 +02001260 mutex_unlock(&st_mutex);
Linus Torvalds1da177e2005-04-16 15:20:36 -07001261 return 0;
1262
1263 err_out:
1264 normalize_buffer(STp->buffer);
1265 STp->in_use = 0;
Kai Makisaraf03a5672005-08-02 13:40:47 +03001266 scsi_tape_put(STp);
Oliver Neukum46a243f2012-01-15 00:16:51 +01001267 if (resumed)
1268 scsi_autopm_put_device(STp->device);
Arnd Bergmann2a48fc02010-06-02 14:28:52 +02001269 mutex_unlock(&st_mutex);
Linus Torvalds1da177e2005-04-16 15:20:36 -07001270 return retval;
1271
1272}
1273
1274
1275/* Flush the tape buffer before close */
Miklos Szeredi75e1fcc2006-06-23 02:05:12 -07001276static int st_flush(struct file *filp, fl_owner_t id)
Linus Torvalds1da177e2005-04-16 15:20:36 -07001277{
1278 int result = 0, result2;
1279 unsigned char cmd[MAX_COMMAND_SIZE];
Mike Christie8b05b772005-11-08 04:06:44 -06001280 struct st_request *SRpnt;
Linus Torvalds1da177e2005-04-16 15:20:36 -07001281 struct scsi_tape *STp = filp->private_data;
1282 struct st_modedef *STm = &(STp->modes[STp->current_mode]);
1283 struct st_partstat *STps = &(STp->ps[STp->partition]);
1284 char *name = tape_name(STp);
1285
1286 if (file_count(filp) > 1)
1287 return 0;
1288
1289 if (STps->rw == ST_WRITING && !STp->pos_unknown) {
Adrian Bunk8ef8d592008-04-14 17:17:16 +03001290 result = st_flush_write_buffer(STp);
Linus Torvalds1da177e2005-04-16 15:20:36 -07001291 if (result != 0 && result != (-ENOSPC))
1292 goto out;
1293 }
1294
1295 if (STp->can_partitions &&
1296 (result2 = switch_partition(STp)) < 0) {
1297 DEBC(printk(ST_DEB_MSG
1298 "%s: switch_partition at close failed.\n", name));
1299 if (result == 0)
1300 result = result2;
1301 goto out;
1302 }
1303
1304 DEBC( if (STp->nbr_requests)
Kai Makisaradeee13d2008-02-22 20:11:21 +02001305 printk(KERN_DEBUG "%s: Number of r/w requests %d, dio used in %d, pages %d.\n",
1306 name, STp->nbr_requests, STp->nbr_dio, STp->nbr_pages));
Linus Torvalds1da177e2005-04-16 15:20:36 -07001307
1308 if (STps->rw == ST_WRITING && !STp->pos_unknown) {
1309 struct st_cmdstatus *cmdstatp = &STp->buffer->cmdstat;
1310
1311 DEBC(printk(ST_DEB_MSG "%s: Async write waits %d, finished %d.\n",
1312 name, STp->nbr_waits, STp->nbr_finished);
1313 )
1314
1315 memset(cmd, 0, MAX_COMMAND_SIZE);
1316 cmd[0] = WRITE_FILEMARKS;
1317 cmd[4] = 1 + STp->two_fm;
1318
Kai Makisara02ae2c02008-12-18 14:49:50 +09001319 SRpnt = st_do_scsi(NULL, STp, cmd, 0, DMA_NONE,
1320 STp->device->request_queue->rq_timeout,
1321 MAX_WRITE_RETRIES, 1);
Linus Torvalds1da177e2005-04-16 15:20:36 -07001322 if (!SRpnt) {
Kai Makisara02ae2c02008-12-18 14:49:50 +09001323 result = (STp->buffer)->syscall_result;
Linus Torvalds1da177e2005-04-16 15:20:36 -07001324 goto out;
1325 }
1326
1327 if (STp->buffer->syscall_result == 0 ||
1328 (cmdstatp->have_sense && !cmdstatp->deferred &&
1329 (cmdstatp->flags & SENSE_EOM) &&
1330 (cmdstatp->sense_hdr.sense_key == NO_SENSE ||
1331 cmdstatp->sense_hdr.sense_key == RECOVERED_ERROR) &&
1332 (!cmdstatp->remainder_valid || cmdstatp->uremainder64 == 0))) {
1333 /* Write successful at EOM */
Mike Christie8b05b772005-11-08 04:06:44 -06001334 st_release_request(SRpnt);
Linus Torvalds1da177e2005-04-16 15:20:36 -07001335 SRpnt = NULL;
1336 if (STps->drv_file >= 0)
1337 STps->drv_file++;
1338 STps->drv_block = 0;
1339 if (STp->two_fm)
1340 cross_eof(STp, 0);
1341 STps->eof = ST_FM;
1342 }
1343 else { /* Write error */
Mike Christie8b05b772005-11-08 04:06:44 -06001344 st_release_request(SRpnt);
Linus Torvalds1da177e2005-04-16 15:20:36 -07001345 SRpnt = NULL;
1346 printk(KERN_ERR "%s: Error on write filemark.\n", name);
1347 if (result == 0)
1348 result = (-EIO);
1349 }
1350
1351 DEBC(printk(ST_DEB_MSG "%s: Buffer flushed, %d EOF(s) written\n",
1352 name, cmd[4]));
1353 } else if (!STp->rew_at_close) {
1354 STps = &(STp->ps[STp->partition]);
1355 if (!STm->sysv || STps->rw != ST_READING) {
1356 if (STp->can_bsr)
1357 result = flush_buffer(STp, 0);
1358 else if (STps->eof == ST_FM_HIT) {
1359 result = cross_eof(STp, 0);
1360 if (result) {
1361 if (STps->drv_file >= 0)
1362 STps->drv_file++;
1363 STps->drv_block = 0;
1364 STps->eof = ST_FM;
1365 } else
1366 STps->eof = ST_NOEOF;
1367 }
1368 } else if ((STps->eof == ST_NOEOF &&
1369 !(result = cross_eof(STp, 1))) ||
1370 STps->eof == ST_FM_HIT) {
1371 if (STps->drv_file >= 0)
1372 STps->drv_file++;
1373 STps->drv_block = 0;
1374 STps->eof = ST_FM;
1375 }
1376 }
1377
1378 out:
1379 if (STp->rew_at_close) {
1380 result2 = st_int_ioctl(STp, MTREW, 1);
1381 if (result == 0)
1382 result = result2;
1383 }
1384 return result;
1385}
1386
1387
1388/* Close the device and release it. BKL is not needed: this is the only thread
1389 accessing this tape. */
1390static int st_release(struct inode *inode, struct file *filp)
1391{
1392 int result = 0;
1393 struct scsi_tape *STp = filp->private_data;
1394
1395 if (STp->door_locked == ST_LOCKED_AUTO)
1396 do_door_lock(STp, 0);
1397
1398 normalize_buffer(STp->buffer);
1399 write_lock(&st_dev_arr_lock);
1400 STp->in_use = 0;
1401 write_unlock(&st_dev_arr_lock);
Oliver Neukum46a243f2012-01-15 00:16:51 +01001402 scsi_autopm_put_device(STp->device);
Kai Makisaraf03a5672005-08-02 13:40:47 +03001403 scsi_tape_put(STp);
Linus Torvalds1da177e2005-04-16 15:20:36 -07001404
1405 return result;
1406}
1407
1408/* The checks common to both reading and writing */
1409static ssize_t rw_checks(struct scsi_tape *STp, struct file *filp, size_t count)
1410{
1411 ssize_t retval = 0;
1412
1413 /*
1414 * If we are in the middle of error recovery, don't let anyone
1415 * else try and use this device. Also, if error recovery fails, it
1416 * may try and take the device offline, in which case all further
1417 * access to the device is prohibited.
1418 */
1419 if (!scsi_block_when_processing_errors(STp->device)) {
1420 retval = (-ENXIO);
1421 goto out;
1422 }
1423
1424 if (STp->ready != ST_READY) {
1425 if (STp->ready == ST_NO_TAPE)
1426 retval = (-ENOMEDIUM);
1427 else
1428 retval = (-EIO);
1429 goto out;
1430 }
1431
1432 if (! STp->modes[STp->current_mode].defined) {
1433 retval = (-ENXIO);
1434 goto out;
1435 }
1436
1437
1438 /*
1439 * If there was a bus reset, block further access
1440 * to this device.
1441 */
1442 if (STp->pos_unknown) {
1443 retval = (-EIO);
1444 goto out;
1445 }
1446
1447 if (count == 0)
1448 goto out;
1449
1450 DEB(
1451 if (!STp->in_use) {
1452 printk(ST_DEB_MSG "%s: Incorrect device.\n", tape_name(STp));
1453 retval = (-EIO);
1454 goto out;
1455 } ) /* end DEB */
1456
1457 if (STp->can_partitions &&
1458 (retval = switch_partition(STp)) < 0)
1459 goto out;
1460
1461 if (STp->block_size == 0 && STp->max_block > 0 &&
1462 (count < STp->min_block || count > STp->max_block)) {
1463 retval = (-EINVAL);
1464 goto out;
1465 }
1466
1467 if (STp->do_auto_lock && STp->door_locked == ST_UNLOCKED &&
1468 !do_door_lock(STp, 1))
1469 STp->door_locked = ST_LOCKED_AUTO;
1470
1471 out:
1472 return retval;
1473}
1474
1475
1476static int setup_buffering(struct scsi_tape *STp, const char __user *buf,
1477 size_t count, int is_read)
1478{
1479 int i, bufsize, retval = 0;
1480 struct st_buffer *STbp = STp->buffer;
1481
1482 if (is_read)
Kai Makisara9abe16c2007-02-03 13:21:29 +02001483 i = STp->try_dio_now && try_rdio;
Linus Torvalds1da177e2005-04-16 15:20:36 -07001484 else
Kai Makisara9abe16c2007-02-03 13:21:29 +02001485 i = STp->try_dio_now && try_wdio;
Mike Christie8b05b772005-11-08 04:06:44 -06001486
Linus Torvalds1da177e2005-04-16 15:20:36 -07001487 if (i && ((unsigned long)buf & queue_dma_alignment(
1488 STp->device->request_queue)) == 0) {
FUJITA Tomonori66207422008-12-18 14:49:43 +09001489 i = sgl_map_user_pages(STbp, STbp->use_sg, (unsigned long)buf,
1490 count, (is_read ? READ : WRITE));
Linus Torvalds1da177e2005-04-16 15:20:36 -07001491 if (i > 0) {
1492 STbp->do_dio = i;
1493 STbp->buffer_bytes = 0; /* can be used as transfer counter */
1494 }
1495 else
1496 STbp->do_dio = 0; /* fall back to buffering with any error */
1497 STbp->sg_segs = STbp->do_dio;
Linus Torvalds1da177e2005-04-16 15:20:36 -07001498 DEB(
1499 if (STbp->do_dio) {
1500 STp->nbr_dio++;
1501 STp->nbr_pages += STbp->do_dio;
Linus Torvalds1da177e2005-04-16 15:20:36 -07001502 }
1503 )
1504 } else
1505 STbp->do_dio = 0;
1506 DEB( STp->nbr_requests++; )
1507
1508 if (!STbp->do_dio) {
1509 if (STp->block_size)
1510 bufsize = STp->block_size > st_fixed_buffer_size ?
1511 STp->block_size : st_fixed_buffer_size;
Kai Makisara40f6b362008-02-24 22:23:24 +02001512 else {
Linus Torvalds1da177e2005-04-16 15:20:36 -07001513 bufsize = count;
Kai Makisara40f6b362008-02-24 22:23:24 +02001514 /* Make sure that data from previous user is not leaked even if
1515 HBA does not return correct residual */
1516 if (is_read && STp->sili && !STbp->cleared)
1517 clear_buffer(STbp);
1518 }
1519
Linus Torvalds1da177e2005-04-16 15:20:36 -07001520 if (bufsize > STbp->buffer_size &&
1521 !enlarge_buffer(STbp, bufsize, STp->restr_dma)) {
1522 printk(KERN_WARNING "%s: Can't allocate %d byte tape buffer.\n",
1523 tape_name(STp), bufsize);
1524 retval = (-EOVERFLOW);
1525 goto out;
1526 }
1527 if (STp->block_size)
1528 STbp->buffer_blocks = bufsize / STp->block_size;
1529 }
1530
1531 out:
1532 return retval;
1533}
1534
1535
1536/* Can be called more than once after each setup_buffer() */
Kai Makisara787926b2005-11-13 10:04:44 +02001537static void release_buffering(struct scsi_tape *STp, int is_read)
Linus Torvalds1da177e2005-04-16 15:20:36 -07001538{
1539 struct st_buffer *STbp;
1540
1541 STbp = STp->buffer;
1542 if (STbp->do_dio) {
FUJITA Tomonori66207422008-12-18 14:49:43 +09001543 sgl_unmap_user_pages(STbp, STbp->do_dio, is_read);
Linus Torvalds1da177e2005-04-16 15:20:36 -07001544 STbp->do_dio = 0;
Kai Makisara787926b2005-11-13 10:04:44 +02001545 STbp->sg_segs = 0;
Linus Torvalds1da177e2005-04-16 15:20:36 -07001546 }
1547}
1548
1549
1550/* Write command */
1551static ssize_t
1552st_write(struct file *filp, const char __user *buf, size_t count, loff_t * ppos)
1553{
1554 ssize_t total;
1555 ssize_t i, do_count, blks, transfer;
1556 ssize_t retval;
1557 int undone, retry_eot = 0, scode;
1558 int async_write;
1559 unsigned char cmd[MAX_COMMAND_SIZE];
1560 const char __user *b_point;
Mike Christie8b05b772005-11-08 04:06:44 -06001561 struct st_request *SRpnt = NULL;
Linus Torvalds1da177e2005-04-16 15:20:36 -07001562 struct scsi_tape *STp = filp->private_data;
1563 struct st_modedef *STm;
1564 struct st_partstat *STps;
1565 struct st_buffer *STbp;
1566 char *name = tape_name(STp);
1567
Matthias Kaehlcke28f85002007-07-29 23:38:15 +02001568 if (mutex_lock_interruptible(&STp->lock))
Linus Torvalds1da177e2005-04-16 15:20:36 -07001569 return -ERESTARTSYS;
1570
1571 retval = rw_checks(STp, filp, count);
1572 if (retval || count == 0)
1573 goto out;
1574
1575 /* Write must be integral number of blocks */
1576 if (STp->block_size != 0 && (count % STp->block_size) != 0) {
1577 printk(KERN_WARNING "%s: Write not multiple of tape block size.\n",
1578 name);
1579 retval = (-EINVAL);
1580 goto out;
1581 }
1582
1583 STm = &(STp->modes[STp->current_mode]);
1584 STps = &(STp->ps[STp->partition]);
1585
1586 if (STp->write_prot) {
1587 retval = (-EACCES);
1588 goto out;
1589 }
1590
1591
1592 if (STps->rw == ST_READING) {
1593 retval = flush_buffer(STp, 0);
1594 if (retval)
1595 goto out;
1596 STps->rw = ST_WRITING;
1597 } else if (STps->rw != ST_WRITING &&
1598 STps->drv_file == 0 && STps->drv_block == 0) {
1599 if ((retval = set_mode_densblk(STp, STm)) < 0)
1600 goto out;
1601 if (STm->default_compression != ST_DONT_TOUCH &&
1602 !(STp->compression_changed)) {
1603 if (st_compression(STp, (STm->default_compression == ST_YES))) {
1604 printk(KERN_WARNING "%s: Can't set default compression.\n",
1605 name);
1606 if (modes_defined) {
1607 retval = (-EINVAL);
1608 goto out;
1609 }
1610 }
1611 }
1612 }
1613
1614 STbp = STp->buffer;
1615 i = write_behind_check(STp);
1616 if (i) {
1617 if (i == -ENOSPC)
1618 STps->eof = ST_EOM_OK;
1619 else
1620 STps->eof = ST_EOM_ERROR;
1621 }
1622
1623 if (STps->eof == ST_EOM_OK) {
1624 STps->eof = ST_EOD_1; /* allow next write */
1625 retval = (-ENOSPC);
1626 goto out;
1627 }
1628 else if (STps->eof == ST_EOM_ERROR) {
1629 retval = (-EIO);
1630 goto out;
1631 }
1632
1633 /* Check the buffer readability in cases where copy_user might catch
1634 the problems after some tape movement. */
1635 if (STp->block_size != 0 &&
1636 !STbp->do_dio &&
1637 (copy_from_user(&i, buf, 1) != 0 ||
1638 copy_from_user(&i, buf + count - 1, 1) != 0)) {
1639 retval = (-EFAULT);
1640 goto out;
1641 }
1642
1643 retval = setup_buffering(STp, buf, count, 0);
1644 if (retval)
1645 goto out;
1646
1647 total = count;
1648
1649 memset(cmd, 0, MAX_COMMAND_SIZE);
1650 cmd[0] = WRITE_6;
1651 cmd[1] = (STp->block_size != 0);
1652
1653 STps->rw = ST_WRITING;
1654
1655 b_point = buf;
1656 while (count > 0 && !retry_eot) {
1657
1658 if (STbp->do_dio) {
1659 do_count = count;
1660 }
1661 else {
1662 if (STp->block_size == 0)
1663 do_count = count;
1664 else {
1665 do_count = STbp->buffer_blocks * STp->block_size -
1666 STbp->buffer_bytes;
1667 if (do_count > count)
1668 do_count = count;
1669 }
1670
1671 i = append_to_buffer(b_point, STbp, do_count);
1672 if (i) {
1673 retval = i;
1674 goto out;
1675 }
1676 }
1677 count -= do_count;
1678 b_point += do_count;
1679
1680 async_write = STp->block_size == 0 && !STbp->do_dio &&
1681 STm->do_async_writes && STps->eof < ST_EOM_OK;
1682
1683 if (STp->block_size != 0 && STm->do_buffer_writes &&
Kai Makisara9abe16c2007-02-03 13:21:29 +02001684 !(STp->try_dio_now && try_wdio) && STps->eof < ST_EOM_OK &&
Linus Torvalds1da177e2005-04-16 15:20:36 -07001685 STbp->buffer_bytes < STbp->buffer_size) {
1686 STp->dirty = 1;
1687 /* Don't write a buffer that is not full enough. */
1688 if (!async_write && count == 0)
1689 break;
1690 }
1691
1692 retry_write:
1693 if (STp->block_size == 0)
1694 blks = transfer = do_count;
1695 else {
1696 if (!STbp->do_dio)
1697 blks = STbp->buffer_bytes;
1698 else
1699 blks = do_count;
1700 blks /= STp->block_size;
1701 transfer = blks * STp->block_size;
1702 }
1703 cmd[2] = blks >> 16;
1704 cmd[3] = blks >> 8;
1705 cmd[4] = blks;
1706
1707 SRpnt = st_do_scsi(SRpnt, STp, cmd, transfer, DMA_TO_DEVICE,
James Bottomleya02488e2008-11-30 10:36:26 -06001708 STp->device->request_queue->rq_timeout,
1709 MAX_WRITE_RETRIES, !async_write);
Linus Torvalds1da177e2005-04-16 15:20:36 -07001710 if (!SRpnt) {
1711 retval = STbp->syscall_result;
1712 goto out;
1713 }
Mike Christie8b05b772005-11-08 04:06:44 -06001714 if (async_write && !STbp->syscall_result) {
Linus Torvalds1da177e2005-04-16 15:20:36 -07001715 STbp->writing = transfer;
1716 STp->dirty = !(STbp->writing ==
1717 STbp->buffer_bytes);
1718 SRpnt = NULL; /* Prevent releasing this request! */
1719 DEB( STp->write_pending = 1; )
1720 break;
1721 }
1722
1723 if (STbp->syscall_result != 0) {
1724 struct st_cmdstatus *cmdstatp = &STp->buffer->cmdstat;
1725
1726 DEBC(printk(ST_DEB_MSG "%s: Error on write:\n", name));
1727 if (cmdstatp->have_sense && (cmdstatp->flags & SENSE_EOM)) {
1728 scode = cmdstatp->sense_hdr.sense_key;
1729 if (cmdstatp->remainder_valid)
1730 undone = (int)cmdstatp->uremainder64;
1731 else if (STp->block_size == 0 &&
1732 scode == VOLUME_OVERFLOW)
1733 undone = transfer;
1734 else
1735 undone = 0;
1736 if (STp->block_size != 0)
1737 undone *= STp->block_size;
1738 if (undone <= do_count) {
1739 /* Only data from this write is not written */
1740 count += undone;
Kai Makisara626dcb12008-07-11 15:05:25 +03001741 b_point -= undone;
Linus Torvalds1da177e2005-04-16 15:20:36 -07001742 do_count -= undone;
1743 if (STp->block_size)
1744 blks = (transfer - undone) / STp->block_size;
1745 STps->eof = ST_EOM_OK;
1746 /* Continue in fixed block mode if all written
1747 in this request but still something left to write
1748 (retval left to zero)
1749 */
1750 if (STp->block_size == 0 ||
1751 undone > 0 || count == 0)
1752 retval = (-ENOSPC); /* EOM within current request */
1753 DEBC(printk(ST_DEB_MSG
1754 "%s: EOM with %d bytes unwritten.\n",
1755 name, (int)count));
1756 } else {
1757 /* EOT within data buffered earlier (possible only
1758 in fixed block mode without direct i/o) */
1759 if (!retry_eot && !cmdstatp->deferred &&
1760 (scode == NO_SENSE || scode == RECOVERED_ERROR)) {
1761 move_buffer_data(STp->buffer, transfer - undone);
1762 retry_eot = 1;
1763 if (STps->drv_block >= 0) {
1764 STps->drv_block += (transfer - undone) /
1765 STp->block_size;
1766 }
1767 STps->eof = ST_EOM_OK;
1768 DEBC(printk(ST_DEB_MSG
1769 "%s: Retry write of %d bytes at EOM.\n",
1770 name, STp->buffer->buffer_bytes));
1771 goto retry_write;
1772 }
1773 else {
1774 /* Either error within data buffered by driver or
1775 failed retry */
1776 count -= do_count;
1777 blks = do_count = 0;
1778 STps->eof = ST_EOM_ERROR;
1779 STps->drv_block = (-1); /* Too cautious? */
1780 retval = (-EIO); /* EOM for old data */
1781 DEBC(printk(ST_DEB_MSG
1782 "%s: EOM with lost data.\n",
1783 name));
1784 }
1785 }
1786 } else {
1787 count += do_count;
1788 STps->drv_block = (-1); /* Too cautious? */
Mike Christie8b05b772005-11-08 04:06:44 -06001789 retval = STbp->syscall_result;
Linus Torvalds1da177e2005-04-16 15:20:36 -07001790 }
1791
1792 }
1793
1794 if (STps->drv_block >= 0) {
1795 if (STp->block_size == 0)
1796 STps->drv_block += (do_count > 0);
1797 else
1798 STps->drv_block += blks;
1799 }
1800
1801 STbp->buffer_bytes = 0;
1802 STp->dirty = 0;
1803
1804 if (retval || retry_eot) {
1805 if (count < total)
1806 retval = total - count;
1807 goto out;
1808 }
1809 }
1810
1811 if (STps->eof == ST_EOD_1)
1812 STps->eof = ST_EOM_OK;
1813 else if (STps->eof != ST_EOM_OK)
1814 STps->eof = ST_NOEOF;
1815 retval = total - count;
1816
1817 out:
1818 if (SRpnt != NULL)
Mike Christie8b05b772005-11-08 04:06:44 -06001819 st_release_request(SRpnt);
Kai Makisara787926b2005-11-13 10:04:44 +02001820 release_buffering(STp, 0);
Matthias Kaehlcke28f85002007-07-29 23:38:15 +02001821 mutex_unlock(&STp->lock);
Linus Torvalds1da177e2005-04-16 15:20:36 -07001822
1823 return retval;
1824}
1825
1826/* Read data from the tape. Returns zero in the normal case, one if the
1827 eof status has changed, and the negative error code in case of a
1828 fatal error. Otherwise updates the buffer and the eof state.
1829
1830 Does release user buffer mapping if it is set.
1831*/
1832static long read_tape(struct scsi_tape *STp, long count,
Mike Christie8b05b772005-11-08 04:06:44 -06001833 struct st_request ** aSRpnt)
Linus Torvalds1da177e2005-04-16 15:20:36 -07001834{
1835 int transfer, blks, bytes;
1836 unsigned char cmd[MAX_COMMAND_SIZE];
Mike Christie8b05b772005-11-08 04:06:44 -06001837 struct st_request *SRpnt;
Linus Torvalds1da177e2005-04-16 15:20:36 -07001838 struct st_modedef *STm;
1839 struct st_partstat *STps;
1840 struct st_buffer *STbp;
1841 int retval = 0;
1842 char *name = tape_name(STp);
1843
1844 if (count == 0)
1845 return 0;
1846
1847 STm = &(STp->modes[STp->current_mode]);
1848 STps = &(STp->ps[STp->partition]);
1849 if (STps->eof == ST_FM_HIT)
1850 return 1;
1851 STbp = STp->buffer;
1852
1853 if (STp->block_size == 0)
1854 blks = bytes = count;
1855 else {
Kai Makisara9abe16c2007-02-03 13:21:29 +02001856 if (!(STp->try_dio_now && try_rdio) && STm->do_read_ahead) {
Linus Torvalds1da177e2005-04-16 15:20:36 -07001857 blks = (STp->buffer)->buffer_blocks;
1858 bytes = blks * STp->block_size;
1859 } else {
1860 bytes = count;
1861 if (!STbp->do_dio && bytes > (STp->buffer)->buffer_size)
1862 bytes = (STp->buffer)->buffer_size;
1863 blks = bytes / STp->block_size;
1864 bytes = blks * STp->block_size;
1865 }
1866 }
1867
1868 memset(cmd, 0, MAX_COMMAND_SIZE);
1869 cmd[0] = READ_6;
1870 cmd[1] = (STp->block_size != 0);
Kai Makisara40f6b362008-02-24 22:23:24 +02001871 if (!cmd[1] && STp->sili)
1872 cmd[1] |= 2;
Linus Torvalds1da177e2005-04-16 15:20:36 -07001873 cmd[2] = blks >> 16;
1874 cmd[3] = blks >> 8;
1875 cmd[4] = blks;
1876
1877 SRpnt = *aSRpnt;
1878 SRpnt = st_do_scsi(SRpnt, STp, cmd, bytes, DMA_FROM_DEVICE,
James Bottomleya02488e2008-11-30 10:36:26 -06001879 STp->device->request_queue->rq_timeout,
1880 MAX_RETRIES, 1);
Kai Makisara787926b2005-11-13 10:04:44 +02001881 release_buffering(STp, 1);
Linus Torvalds1da177e2005-04-16 15:20:36 -07001882 *aSRpnt = SRpnt;
1883 if (!SRpnt)
1884 return STbp->syscall_result;
1885
1886 STbp->read_pointer = 0;
1887 STps->at_sm = 0;
1888
1889 /* Something to check */
1890 if (STbp->syscall_result) {
1891 struct st_cmdstatus *cmdstatp = &STp->buffer->cmdstat;
1892
1893 retval = 1;
1894 DEBC(printk(ST_DEB_MSG "%s: Sense: %2x %2x %2x %2x %2x %2x %2x %2x\n",
1895 name,
Mike Christie8b05b772005-11-08 04:06:44 -06001896 SRpnt->sense[0], SRpnt->sense[1],
1897 SRpnt->sense[2], SRpnt->sense[3],
1898 SRpnt->sense[4], SRpnt->sense[5],
1899 SRpnt->sense[6], SRpnt->sense[7]));
Linus Torvalds1da177e2005-04-16 15:20:36 -07001900 if (cmdstatp->have_sense) {
1901
1902 if (cmdstatp->sense_hdr.sense_key == BLANK_CHECK)
1903 cmdstatp->flags &= 0xcf; /* No need for EOM in this case */
1904
1905 if (cmdstatp->flags != 0) { /* EOF, EOM, or ILI */
1906 /* Compute the residual count */
1907 if (cmdstatp->remainder_valid)
1908 transfer = (int)cmdstatp->uremainder64;
1909 else
1910 transfer = 0;
1911 if (STp->block_size == 0 &&
1912 cmdstatp->sense_hdr.sense_key == MEDIUM_ERROR)
1913 transfer = bytes;
1914
1915 if (cmdstatp->flags & SENSE_ILI) { /* ILI */
1916 if (STp->block_size == 0) {
1917 if (transfer <= 0) {
1918 if (transfer < 0)
1919 printk(KERN_NOTICE
1920 "%s: Failed to read %d byte block with %d byte transfer.\n",
1921 name, bytes - transfer, bytes);
1922 if (STps->drv_block >= 0)
1923 STps->drv_block += 1;
1924 STbp->buffer_bytes = 0;
1925 return (-ENOMEM);
1926 }
1927 STbp->buffer_bytes = bytes - transfer;
1928 } else {
Mike Christie8b05b772005-11-08 04:06:44 -06001929 st_release_request(SRpnt);
Linus Torvalds1da177e2005-04-16 15:20:36 -07001930 SRpnt = *aSRpnt = NULL;
1931 if (transfer == blks) { /* We did not get anything, error */
1932 printk(KERN_NOTICE "%s: Incorrect block size.\n", name);
1933 if (STps->drv_block >= 0)
1934 STps->drv_block += blks - transfer + 1;
1935 st_int_ioctl(STp, MTBSR, 1);
1936 return (-EIO);
1937 }
1938 /* We have some data, deliver it */
1939 STbp->buffer_bytes = (blks - transfer) *
1940 STp->block_size;
1941 DEBC(printk(ST_DEB_MSG
1942 "%s: ILI but enough data received %ld %d.\n",
1943 name, count, STbp->buffer_bytes));
1944 if (STps->drv_block >= 0)
1945 STps->drv_block += 1;
1946 if (st_int_ioctl(STp, MTBSR, 1))
1947 return (-EIO);
1948 }
1949 } else if (cmdstatp->flags & SENSE_FMK) { /* FM overrides EOM */
1950 if (STps->eof != ST_FM_HIT)
1951 STps->eof = ST_FM_HIT;
1952 else
1953 STps->eof = ST_EOD_2;
1954 if (STp->block_size == 0)
1955 STbp->buffer_bytes = 0;
1956 else
1957 STbp->buffer_bytes =
1958 bytes - transfer * STp->block_size;
1959 DEBC(printk(ST_DEB_MSG
1960 "%s: EOF detected (%d bytes read).\n",
1961 name, STbp->buffer_bytes));
1962 } else if (cmdstatp->flags & SENSE_EOM) {
1963 if (STps->eof == ST_FM)
1964 STps->eof = ST_EOD_1;
1965 else
1966 STps->eof = ST_EOM_OK;
1967 if (STp->block_size == 0)
1968 STbp->buffer_bytes = bytes - transfer;
1969 else
1970 STbp->buffer_bytes =
1971 bytes - transfer * STp->block_size;
1972
1973 DEBC(printk(ST_DEB_MSG "%s: EOM detected (%d bytes read).\n",
1974 name, STbp->buffer_bytes));
1975 }
1976 }
1977 /* end of EOF, EOM, ILI test */
1978 else { /* nonzero sense key */
1979 DEBC(printk(ST_DEB_MSG
1980 "%s: Tape error while reading.\n", name));
1981 STps->drv_block = (-1);
1982 if (STps->eof == ST_FM &&
1983 cmdstatp->sense_hdr.sense_key == BLANK_CHECK) {
1984 DEBC(printk(ST_DEB_MSG
1985 "%s: Zero returned for first BLANK CHECK after EOF.\n",
1986 name));
1987 STps->eof = ST_EOD_2; /* First BLANK_CHECK after FM */
1988 } else /* Some other extended sense code */
1989 retval = (-EIO);
1990 }
1991
1992 if (STbp->buffer_bytes < 0) /* Caused by bogus sense data */
1993 STbp->buffer_bytes = 0;
1994 }
1995 /* End of extended sense test */
1996 else { /* Non-extended sense */
1997 retval = STbp->syscall_result;
1998 }
1999
2000 }
2001 /* End of error handling */
Kai Makisara40f6b362008-02-24 22:23:24 +02002002 else { /* Read successful */
Linus Torvalds1da177e2005-04-16 15:20:36 -07002003 STbp->buffer_bytes = bytes;
Kai Makisara40f6b362008-02-24 22:23:24 +02002004 if (STp->sili) /* In fixed block mode residual is always zero here */
2005 STbp->buffer_bytes -= STp->buffer->cmdstat.residual;
2006 }
Linus Torvalds1da177e2005-04-16 15:20:36 -07002007
2008 if (STps->drv_block >= 0) {
2009 if (STp->block_size == 0)
2010 STps->drv_block++;
2011 else
2012 STps->drv_block += STbp->buffer_bytes / STp->block_size;
2013 }
2014 return retval;
2015}
2016
2017
2018/* Read command */
2019static ssize_t
2020st_read(struct file *filp, char __user *buf, size_t count, loff_t * ppos)
2021{
2022 ssize_t total;
2023 ssize_t retval = 0;
2024 ssize_t i, transfer;
2025 int special, do_dio = 0;
Mike Christie8b05b772005-11-08 04:06:44 -06002026 struct st_request *SRpnt = NULL;
Linus Torvalds1da177e2005-04-16 15:20:36 -07002027 struct scsi_tape *STp = filp->private_data;
2028 struct st_modedef *STm;
2029 struct st_partstat *STps;
2030 struct st_buffer *STbp = STp->buffer;
2031 DEB( char *name = tape_name(STp); )
2032
Matthias Kaehlcke28f85002007-07-29 23:38:15 +02002033 if (mutex_lock_interruptible(&STp->lock))
Linus Torvalds1da177e2005-04-16 15:20:36 -07002034 return -ERESTARTSYS;
2035
2036 retval = rw_checks(STp, filp, count);
2037 if (retval || count == 0)
2038 goto out;
2039
2040 STm = &(STp->modes[STp->current_mode]);
Kai Makisara9abe16c2007-02-03 13:21:29 +02002041 if (STp->block_size != 0 && (count % STp->block_size) != 0) {
2042 if (!STm->do_read_ahead) {
2043 retval = (-EINVAL); /* Read must be integral number of blocks */
2044 goto out;
2045 }
2046 STp->try_dio_now = 0; /* Direct i/o can't handle split blocks */
Linus Torvalds1da177e2005-04-16 15:20:36 -07002047 }
2048
2049 STps = &(STp->ps[STp->partition]);
2050 if (STps->rw == ST_WRITING) {
2051 retval = flush_buffer(STp, 0);
2052 if (retval)
2053 goto out;
2054 STps->rw = ST_READING;
2055 }
2056 DEB(
2057 if (debugging && STps->eof != ST_NOEOF)
2058 printk(ST_DEB_MSG "%s: EOF/EOM flag up (%d). Bytes %d\n", name,
2059 STps->eof, STbp->buffer_bytes);
2060 ) /* end DEB */
2061
2062 retval = setup_buffering(STp, buf, count, 1);
2063 if (retval)
2064 goto out;
2065 do_dio = STbp->do_dio;
2066
2067 if (STbp->buffer_bytes == 0 &&
2068 STps->eof >= ST_EOD_1) {
2069 if (STps->eof < ST_EOD) {
2070 STps->eof += 1;
2071 retval = 0;
2072 goto out;
2073 }
2074 retval = (-EIO); /* EOM or Blank Check */
2075 goto out;
2076 }
2077
2078 if (do_dio) {
2079 /* Check the buffer writability before any tape movement. Don't alter
2080 buffer data. */
2081 if (copy_from_user(&i, buf, 1) != 0 ||
2082 copy_to_user(buf, &i, 1) != 0 ||
2083 copy_from_user(&i, buf + count - 1, 1) != 0 ||
2084 copy_to_user(buf + count - 1, &i, 1) != 0) {
2085 retval = (-EFAULT);
2086 goto out;
2087 }
2088 }
2089
2090 STps->rw = ST_READING;
2091
2092
2093 /* Loop until enough data in buffer or a special condition found */
2094 for (total = 0, special = 0; total < count && !special;) {
2095
2096 /* Get new data if the buffer is empty */
2097 if (STbp->buffer_bytes == 0) {
2098 special = read_tape(STp, count - total, &SRpnt);
2099 if (special < 0) { /* No need to continue read */
2100 retval = special;
2101 goto out;
2102 }
2103 }
2104
2105 /* Move the data from driver buffer to user buffer */
2106 if (STbp->buffer_bytes > 0) {
2107 DEB(
2108 if (debugging && STps->eof != ST_NOEOF)
2109 printk(ST_DEB_MSG
2110 "%s: EOF up (%d). Left %d, needed %d.\n", name,
2111 STps->eof, STbp->buffer_bytes,
2112 (int)(count - total));
2113 ) /* end DEB */
2114 transfer = STbp->buffer_bytes < count - total ?
2115 STbp->buffer_bytes : count - total;
2116 if (!do_dio) {
2117 i = from_buffer(STbp, buf, transfer);
2118 if (i) {
2119 retval = i;
2120 goto out;
2121 }
2122 }
2123 buf += transfer;
2124 total += transfer;
2125 }
2126
2127 if (STp->block_size == 0)
2128 break; /* Read only one variable length block */
2129
2130 } /* for (total = 0, special = 0;
2131 total < count && !special; ) */
2132
2133 /* Change the eof state if no data from tape or buffer */
2134 if (total == 0) {
2135 if (STps->eof == ST_FM_HIT) {
2136 STps->eof = ST_FM;
2137 STps->drv_block = 0;
2138 if (STps->drv_file >= 0)
2139 STps->drv_file++;
2140 } else if (STps->eof == ST_EOD_1) {
2141 STps->eof = ST_EOD_2;
2142 STps->drv_block = 0;
2143 if (STps->drv_file >= 0)
2144 STps->drv_file++;
2145 } else if (STps->eof == ST_EOD_2)
2146 STps->eof = ST_EOD;
2147 } else if (STps->eof == ST_FM)
2148 STps->eof = ST_NOEOF;
2149 retval = total;
2150
2151 out:
2152 if (SRpnt != NULL) {
Mike Christie8b05b772005-11-08 04:06:44 -06002153 st_release_request(SRpnt);
Linus Torvalds1da177e2005-04-16 15:20:36 -07002154 SRpnt = NULL;
2155 }
2156 if (do_dio) {
Kai Makisara787926b2005-11-13 10:04:44 +02002157 release_buffering(STp, 1);
Linus Torvalds1da177e2005-04-16 15:20:36 -07002158 STbp->buffer_bytes = 0;
2159 }
Matthias Kaehlcke28f85002007-07-29 23:38:15 +02002160 mutex_unlock(&STp->lock);
Linus Torvalds1da177e2005-04-16 15:20:36 -07002161
2162 return retval;
2163}
2164
2165
2166
2167DEB(
2168/* Set the driver options */
2169static void st_log_options(struct scsi_tape * STp, struct st_modedef * STm, char *name)
2170{
2171 if (debugging) {
2172 printk(KERN_INFO
2173 "%s: Mode %d options: buffer writes: %d, async writes: %d, read ahead: %d\n",
2174 name, STp->current_mode, STm->do_buffer_writes, STm->do_async_writes,
2175 STm->do_read_ahead);
2176 printk(KERN_INFO
2177 "%s: can bsr: %d, two FMs: %d, fast mteom: %d, auto lock: %d,\n",
2178 name, STp->can_bsr, STp->two_fm, STp->fast_mteom, STp->do_auto_lock);
2179 printk(KERN_INFO
2180 "%s: defs for wr: %d, no block limits: %d, partitions: %d, s2 log: %d\n",
2181 name, STm->defaults_for_writes, STp->omit_blklims, STp->can_partitions,
2182 STp->scsi2_logical);
2183 printk(KERN_INFO
Kai Makisara40f6b362008-02-24 22:23:24 +02002184 "%s: sysv: %d nowait: %d sili: %d\n", name, STm->sysv, STp->immediate,
2185 STp->sili);
Linus Torvalds1da177e2005-04-16 15:20:36 -07002186 printk(KERN_INFO "%s: debugging: %d\n",
2187 name, debugging);
2188 }
2189}
2190 )
2191
2192
2193static int st_set_options(struct scsi_tape *STp, long options)
2194{
2195 int value;
2196 long code;
2197 struct st_modedef *STm;
2198 char *name = tape_name(STp);
2199 struct cdev *cd0, *cd1;
2200
2201 STm = &(STp->modes[STp->current_mode]);
2202 if (!STm->defined) {
2203 cd0 = STm->cdevs[0]; cd1 = STm->cdevs[1];
2204 memcpy(STm, &(STp->modes[0]), sizeof(struct st_modedef));
2205 STm->cdevs[0] = cd0; STm->cdevs[1] = cd1;
2206 modes_defined = 1;
2207 DEBC(printk(ST_DEB_MSG
2208 "%s: Initialized mode %d definition from mode 0\n",
2209 name, STp->current_mode));
2210 }
2211
2212 code = options & MT_ST_OPTIONS;
2213 if (code == MT_ST_BOOLEANS) {
2214 STm->do_buffer_writes = (options & MT_ST_BUFFER_WRITES) != 0;
2215 STm->do_async_writes = (options & MT_ST_ASYNC_WRITES) != 0;
2216 STm->defaults_for_writes = (options & MT_ST_DEF_WRITES) != 0;
2217 STm->do_read_ahead = (options & MT_ST_READ_AHEAD) != 0;
2218 STp->two_fm = (options & MT_ST_TWO_FM) != 0;
2219 STp->fast_mteom = (options & MT_ST_FAST_MTEOM) != 0;
2220 STp->do_auto_lock = (options & MT_ST_AUTO_LOCK) != 0;
2221 STp->can_bsr = (options & MT_ST_CAN_BSR) != 0;
2222 STp->omit_blklims = (options & MT_ST_NO_BLKLIMS) != 0;
2223 if ((STp->device)->scsi_level >= SCSI_2)
2224 STp->can_partitions = (options & MT_ST_CAN_PARTITIONS) != 0;
2225 STp->scsi2_logical = (options & MT_ST_SCSI2LOGICAL) != 0;
2226 STp->immediate = (options & MT_ST_NOWAIT) != 0;
2227 STm->sysv = (options & MT_ST_SYSV) != 0;
Kai Makisara40f6b362008-02-24 22:23:24 +02002228 STp->sili = (options & MT_ST_SILI) != 0;
Linus Torvalds1da177e2005-04-16 15:20:36 -07002229 DEB( debugging = (options & MT_ST_DEBUGGING) != 0;
2230 st_log_options(STp, STm, name); )
2231 } else if (code == MT_ST_SETBOOLEANS || code == MT_ST_CLEARBOOLEANS) {
2232 value = (code == MT_ST_SETBOOLEANS);
2233 if ((options & MT_ST_BUFFER_WRITES) != 0)
2234 STm->do_buffer_writes = value;
2235 if ((options & MT_ST_ASYNC_WRITES) != 0)
2236 STm->do_async_writes = value;
2237 if ((options & MT_ST_DEF_WRITES) != 0)
2238 STm->defaults_for_writes = value;
2239 if ((options & MT_ST_READ_AHEAD) != 0)
2240 STm->do_read_ahead = value;
2241 if ((options & MT_ST_TWO_FM) != 0)
2242 STp->two_fm = value;
2243 if ((options & MT_ST_FAST_MTEOM) != 0)
2244 STp->fast_mteom = value;
2245 if ((options & MT_ST_AUTO_LOCK) != 0)
2246 STp->do_auto_lock = value;
2247 if ((options & MT_ST_CAN_BSR) != 0)
2248 STp->can_bsr = value;
2249 if ((options & MT_ST_NO_BLKLIMS) != 0)
2250 STp->omit_blklims = value;
2251 if ((STp->device)->scsi_level >= SCSI_2 &&
2252 (options & MT_ST_CAN_PARTITIONS) != 0)
2253 STp->can_partitions = value;
2254 if ((options & MT_ST_SCSI2LOGICAL) != 0)
2255 STp->scsi2_logical = value;
2256 if ((options & MT_ST_NOWAIT) != 0)
2257 STp->immediate = value;
2258 if ((options & MT_ST_SYSV) != 0)
2259 STm->sysv = value;
Kai Makisara40f6b362008-02-24 22:23:24 +02002260 if ((options & MT_ST_SILI) != 0)
2261 STp->sili = value;
Linus Torvalds1da177e2005-04-16 15:20:36 -07002262 DEB(
2263 if ((options & MT_ST_DEBUGGING) != 0)
2264 debugging = value;
2265 st_log_options(STp, STm, name); )
2266 } else if (code == MT_ST_WRITE_THRESHOLD) {
2267 /* Retained for compatibility */
2268 } else if (code == MT_ST_DEF_BLKSIZE) {
2269 value = (options & ~MT_ST_OPTIONS);
2270 if (value == ~MT_ST_OPTIONS) {
2271 STm->default_blksize = (-1);
2272 DEBC( printk(KERN_INFO "%s: Default block size disabled.\n", name));
2273 } else {
2274 STm->default_blksize = value;
2275 DEBC( printk(KERN_INFO "%s: Default block size set to %d bytes.\n",
2276 name, STm->default_blksize));
2277 if (STp->ready == ST_READY) {
2278 STp->blksize_changed = 0;
2279 set_mode_densblk(STp, STm);
2280 }
2281 }
2282 } else if (code == MT_ST_TIMEOUTS) {
2283 value = (options & ~MT_ST_OPTIONS);
2284 if ((value & MT_ST_SET_LONG_TIMEOUT) != 0) {
2285 STp->long_timeout = (value & ~MT_ST_SET_LONG_TIMEOUT) * HZ;
2286 DEBC( printk(KERN_INFO "%s: Long timeout set to %d seconds.\n", name,
2287 (value & ~MT_ST_SET_LONG_TIMEOUT)));
2288 } else {
James Bottomleya02488e2008-11-30 10:36:26 -06002289 blk_queue_rq_timeout(STp->device->request_queue,
2290 value * HZ);
Linus Torvalds1da177e2005-04-16 15:20:36 -07002291 DEBC( printk(KERN_INFO "%s: Normal timeout set to %d seconds.\n",
2292 name, value) );
2293 }
2294 } else if (code == MT_ST_SET_CLN) {
2295 value = (options & ~MT_ST_OPTIONS) & 0xff;
2296 if (value != 0 &&
Roel Kluin832151f2009-11-17 14:53:22 -08002297 (value < EXTENDED_SENSE_START ||
2298 value >= SCSI_SENSE_BUFFERSIZE))
Linus Torvalds1da177e2005-04-16 15:20:36 -07002299 return (-EINVAL);
2300 STp->cln_mode = value;
2301 STp->cln_sense_mask = (options >> 8) & 0xff;
2302 STp->cln_sense_value = (options >> 16) & 0xff;
2303 printk(KERN_INFO
2304 "%s: Cleaning request mode %d, mask %02x, value %02x\n",
2305 name, value, STp->cln_sense_mask, STp->cln_sense_value);
2306 } else if (code == MT_ST_DEF_OPTIONS) {
2307 code = (options & ~MT_ST_CLEAR_DEFAULT);
2308 value = (options & MT_ST_CLEAR_DEFAULT);
2309 if (code == MT_ST_DEF_DENSITY) {
2310 if (value == MT_ST_CLEAR_DEFAULT) {
2311 STm->default_density = (-1);
2312 DEBC( printk(KERN_INFO "%s: Density default disabled.\n",
2313 name));
2314 } else {
2315 STm->default_density = value & 0xff;
2316 DEBC( printk(KERN_INFO "%s: Density default set to %x\n",
2317 name, STm->default_density));
2318 if (STp->ready == ST_READY) {
2319 STp->density_changed = 0;
2320 set_mode_densblk(STp, STm);
2321 }
2322 }
2323 } else if (code == MT_ST_DEF_DRVBUFFER) {
2324 if (value == MT_ST_CLEAR_DEFAULT) {
2325 STp->default_drvbuffer = 0xff;
2326 DEBC( printk(KERN_INFO
2327 "%s: Drive buffer default disabled.\n", name));
2328 } else {
2329 STp->default_drvbuffer = value & 7;
2330 DEBC( printk(KERN_INFO
2331 "%s: Drive buffer default set to %x\n",
2332 name, STp->default_drvbuffer));
2333 if (STp->ready == ST_READY)
2334 st_int_ioctl(STp, MTSETDRVBUFFER, STp->default_drvbuffer);
2335 }
2336 } else if (code == MT_ST_DEF_COMPRESSION) {
2337 if (value == MT_ST_CLEAR_DEFAULT) {
2338 STm->default_compression = ST_DONT_TOUCH;
2339 DEBC( printk(KERN_INFO
2340 "%s: Compression default disabled.\n", name));
2341 } else {
2342 if ((value & 0xff00) != 0) {
2343 STp->c_algo = (value & 0xff00) >> 8;
2344 DEBC( printk(KERN_INFO "%s: Compression algorithm set to 0x%x.\n",
2345 name, STp->c_algo));
2346 }
2347 if ((value & 0xff) != 0xff) {
2348 STm->default_compression = (value & 1 ? ST_YES : ST_NO);
2349 DEBC( printk(KERN_INFO "%s: Compression default set to %x\n",
2350 name, (value & 1)));
2351 if (STp->ready == ST_READY) {
2352 STp->compression_changed = 0;
2353 st_compression(STp, (STm->default_compression == ST_YES));
2354 }
2355 }
2356 }
2357 }
2358 } else
2359 return (-EIO);
2360
2361 return 0;
2362}
2363
2364#define MODE_HEADER_LENGTH 4
2365
2366/* Mode header and page byte offsets */
2367#define MH_OFF_DATA_LENGTH 0
2368#define MH_OFF_MEDIUM_TYPE 1
2369#define MH_OFF_DEV_SPECIFIC 2
2370#define MH_OFF_BDESCS_LENGTH 3
2371#define MP_OFF_PAGE_NBR 0
2372#define MP_OFF_PAGE_LENGTH 1
2373
2374/* Mode header and page bit masks */
2375#define MH_BIT_WP 0x80
2376#define MP_MSK_PAGE_NBR 0x3f
2377
2378/* Don't return block descriptors */
2379#define MODE_SENSE_OMIT_BDESCS 0x08
2380
2381#define MODE_SELECT_PAGE_FORMAT 0x10
2382
2383/* Read a mode page into the tape buffer. The block descriptors are included
2384 if incl_block_descs is true. The page control is ored to the page number
2385 parameter, if necessary. */
2386static int read_mode_page(struct scsi_tape *STp, int page, int omit_block_descs)
2387{
2388 unsigned char cmd[MAX_COMMAND_SIZE];
FUJITA Tomonori8ecf0d92008-12-05 15:25:28 +09002389 struct st_request *SRpnt;
Linus Torvalds1da177e2005-04-16 15:20:36 -07002390
2391 memset(cmd, 0, MAX_COMMAND_SIZE);
2392 cmd[0] = MODE_SENSE;
2393 if (omit_block_descs)
2394 cmd[1] = MODE_SENSE_OMIT_BDESCS;
2395 cmd[2] = page;
2396 cmd[4] = 255;
2397
Kai Makisara02ae2c02008-12-18 14:49:50 +09002398 SRpnt = st_do_scsi(NULL, STp, cmd, cmd[4], DMA_FROM_DEVICE,
2399 STp->device->request_queue->rq_timeout, 0, 1);
2400 if (SRpnt == NULL)
2401 return (STp->buffer)->syscall_result;
Linus Torvalds1da177e2005-04-16 15:20:36 -07002402
Mike Christie8b05b772005-11-08 04:06:44 -06002403 st_release_request(SRpnt);
Linus Torvalds1da177e2005-04-16 15:20:36 -07002404
Kai Makisara02ae2c02008-12-18 14:49:50 +09002405 return STp->buffer->syscall_result;
Linus Torvalds1da177e2005-04-16 15:20:36 -07002406}
2407
2408
2409/* Send the mode page in the tape buffer to the drive. Assumes that the mode data
2410 in the buffer is correctly formatted. The long timeout is used if slow is non-zero. */
2411static int write_mode_page(struct scsi_tape *STp, int page, int slow)
2412{
Kai Makisara02ae2c02008-12-18 14:49:50 +09002413 int pgo;
Linus Torvalds1da177e2005-04-16 15:20:36 -07002414 unsigned char cmd[MAX_COMMAND_SIZE];
FUJITA Tomonori18c87012008-12-05 15:25:29 +09002415 struct st_request *SRpnt;
Kai Makisara02ae2c02008-12-18 14:49:50 +09002416 int timeout;
Linus Torvalds1da177e2005-04-16 15:20:36 -07002417
2418 memset(cmd, 0, MAX_COMMAND_SIZE);
2419 cmd[0] = MODE_SELECT;
2420 cmd[1] = MODE_SELECT_PAGE_FORMAT;
2421 pgo = MODE_HEADER_LENGTH + (STp->buffer)->b_data[MH_OFF_BDESCS_LENGTH];
2422 cmd[4] = pgo + (STp->buffer)->b_data[pgo + MP_OFF_PAGE_LENGTH] + 2;
2423
2424 /* Clear reserved fields */
2425 (STp->buffer)->b_data[MH_OFF_DATA_LENGTH] = 0;
2426 (STp->buffer)->b_data[MH_OFF_MEDIUM_TYPE] = 0;
2427 (STp->buffer)->b_data[MH_OFF_DEV_SPECIFIC] &= ~MH_BIT_WP;
2428 (STp->buffer)->b_data[pgo + MP_OFF_PAGE_NBR] &= MP_MSK_PAGE_NBR;
2429
Kai Makisara02ae2c02008-12-18 14:49:50 +09002430 timeout = slow ?
2431 STp->long_timeout : STp->device->request_queue->rq_timeout;
2432 SRpnt = st_do_scsi(NULL, STp, cmd, cmd[4], DMA_TO_DEVICE,
2433 timeout, 0, 1);
2434 if (SRpnt == NULL)
2435 return (STp->buffer)->syscall_result;
Linus Torvalds1da177e2005-04-16 15:20:36 -07002436
Mike Christie8b05b772005-11-08 04:06:44 -06002437 st_release_request(SRpnt);
Linus Torvalds1da177e2005-04-16 15:20:36 -07002438
Kai Makisara02ae2c02008-12-18 14:49:50 +09002439 return STp->buffer->syscall_result;
Linus Torvalds1da177e2005-04-16 15:20:36 -07002440}
2441
2442
2443#define COMPRESSION_PAGE 0x0f
2444#define COMPRESSION_PAGE_LENGTH 16
2445
2446#define CP_OFF_DCE_DCC 2
2447#define CP_OFF_C_ALGO 7
2448
2449#define DCE_MASK 0x80
2450#define DCC_MASK 0x40
2451#define RED_MASK 0x60
2452
2453
2454/* Control the compression with mode page 15. Algorithm not changed if zero.
2455
2456 The block descriptors are read and written because Sony SDT-7000 does not
2457 work without this (suggestion from Michael Schaefer <Michael.Schaefer@dlr.de>).
2458 Including block descriptors should not cause any harm to other drives. */
2459
2460static int st_compression(struct scsi_tape * STp, int state)
2461{
2462 int retval;
2463 int mpoffs; /* Offset to mode page start */
2464 unsigned char *b_data = (STp->buffer)->b_data;
2465 DEB( char *name = tape_name(STp); )
2466
2467 if (STp->ready != ST_READY)
2468 return (-EIO);
2469
2470 /* Read the current page contents */
2471 retval = read_mode_page(STp, COMPRESSION_PAGE, 0);
2472 if (retval) {
2473 DEBC(printk(ST_DEB_MSG "%s: Compression mode page not supported.\n",
2474 name));
2475 return (-EIO);
2476 }
2477
2478 mpoffs = MODE_HEADER_LENGTH + b_data[MH_OFF_BDESCS_LENGTH];
2479 DEBC(printk(ST_DEB_MSG "%s: Compression state is %d.\n", name,
2480 (b_data[mpoffs + CP_OFF_DCE_DCC] & DCE_MASK ? 1 : 0)));
2481
2482 /* Check if compression can be changed */
2483 if ((b_data[mpoffs + CP_OFF_DCE_DCC] & DCC_MASK) == 0) {
2484 DEBC(printk(ST_DEB_MSG "%s: Compression not supported.\n", name));
2485 return (-EIO);
2486 }
2487
2488 /* Do the change */
2489 if (state) {
2490 b_data[mpoffs + CP_OFF_DCE_DCC] |= DCE_MASK;
2491 if (STp->c_algo != 0)
2492 b_data[mpoffs + CP_OFF_C_ALGO] = STp->c_algo;
2493 }
2494 else {
2495 b_data[mpoffs + CP_OFF_DCE_DCC] &= ~DCE_MASK;
2496 if (STp->c_algo != 0)
2497 b_data[mpoffs + CP_OFF_C_ALGO] = 0; /* no compression */
2498 }
2499
2500 retval = write_mode_page(STp, COMPRESSION_PAGE, 0);
2501 if (retval) {
2502 DEBC(printk(ST_DEB_MSG "%s: Compression change failed.\n", name));
2503 return (-EIO);
2504 }
2505 DEBC(printk(ST_DEB_MSG "%s: Compression state changed to %d.\n",
2506 name, state));
2507
2508 STp->compression_changed = 1;
2509 return 0;
2510}
2511
2512
2513/* Process the load and unload commands (does unload if the load code is zero) */
2514static int do_load_unload(struct scsi_tape *STp, struct file *filp, int load_code)
2515{
2516 int retval = (-EIO), timeout;
2517 DEB( char *name = tape_name(STp); )
2518 unsigned char cmd[MAX_COMMAND_SIZE];
2519 struct st_partstat *STps;
Mike Christie8b05b772005-11-08 04:06:44 -06002520 struct st_request *SRpnt;
Linus Torvalds1da177e2005-04-16 15:20:36 -07002521
2522 if (STp->ready != ST_READY && !load_code) {
2523 if (STp->ready == ST_NO_TAPE)
2524 return (-ENOMEDIUM);
2525 else
2526 return (-EIO);
2527 }
2528
2529 memset(cmd, 0, MAX_COMMAND_SIZE);
2530 cmd[0] = START_STOP;
2531 if (load_code)
2532 cmd[4] |= 1;
2533 /*
2534 * If arg >= 1 && arg <= 6 Enhanced load/unload in HP C1553A
2535 */
2536 if (load_code >= 1 + MT_ST_HPLOADER_OFFSET
2537 && load_code <= 6 + MT_ST_HPLOADER_OFFSET) {
2538 DEBC(printk(ST_DEB_MSG "%s: Enhanced %sload slot %2d.\n",
2539 name, (cmd[4]) ? "" : "un",
2540 load_code - MT_ST_HPLOADER_OFFSET));
2541 cmd[3] = load_code - MT_ST_HPLOADER_OFFSET; /* MediaID field of C1553A */
2542 }
2543 if (STp->immediate) {
2544 cmd[1] = 1; /* Don't wait for completion */
James Bottomleya02488e2008-11-30 10:36:26 -06002545 timeout = STp->device->request_queue->rq_timeout;
Linus Torvalds1da177e2005-04-16 15:20:36 -07002546 }
2547 else
2548 timeout = STp->long_timeout;
2549
2550 DEBC(
2551 if (!load_code)
2552 printk(ST_DEB_MSG "%s: Unloading tape.\n", name);
2553 else
2554 printk(ST_DEB_MSG "%s: Loading tape.\n", name);
2555 );
2556
Kai Makisara02ae2c02008-12-18 14:49:50 +09002557 SRpnt = st_do_scsi(NULL, STp, cmd, 0, DMA_NONE,
2558 timeout, MAX_RETRIES, 1);
Linus Torvalds1da177e2005-04-16 15:20:36 -07002559 if (!SRpnt)
Kai Makisara02ae2c02008-12-18 14:49:50 +09002560 return (STp->buffer)->syscall_result;
Linus Torvalds1da177e2005-04-16 15:20:36 -07002561
2562 retval = (STp->buffer)->syscall_result;
Kai Makisara02ae2c02008-12-18 14:49:50 +09002563 st_release_request(SRpnt);
Linus Torvalds1da177e2005-04-16 15:20:36 -07002564
2565 if (!retval) { /* SCSI command successful */
2566
2567 if (!load_code) {
2568 STp->rew_at_close = 0;
2569 STp->ready = ST_NO_TAPE;
2570 }
2571 else {
2572 STp->rew_at_close = STp->autorew_dev;
2573 retval = check_tape(STp, filp);
2574 if (retval > 0)
2575 retval = 0;
2576 }
2577 }
2578 else {
2579 STps = &(STp->ps[STp->partition]);
2580 STps->drv_file = STps->drv_block = (-1);
2581 }
2582
2583 return retval;
2584}
2585
2586#if DEBUG
2587#define ST_DEB_FORWARD 0
2588#define ST_DEB_BACKWARD 1
2589static void deb_space_print(char *name, int direction, char *units, unsigned char *cmd)
2590{
2591 s32 sc;
2592
2593 sc = cmd[2] & 0x80 ? 0xff000000 : 0;
2594 sc |= (cmd[2] << 16) | (cmd[3] << 8) | cmd[4];
2595 if (direction)
2596 sc = -sc;
2597 printk(ST_DEB_MSG "%s: Spacing tape %s over %d %s.\n", name,
2598 direction ? "backward" : "forward", sc, units);
2599}
2600#endif
2601
2602
2603/* Internal ioctl function */
2604static int st_int_ioctl(struct scsi_tape *STp, unsigned int cmd_in, unsigned long arg)
2605{
2606 int timeout;
2607 long ltmp;
2608 int ioctl_result;
2609 int chg_eof = 1;
2610 unsigned char cmd[MAX_COMMAND_SIZE];
Mike Christie8b05b772005-11-08 04:06:44 -06002611 struct st_request *SRpnt;
Linus Torvalds1da177e2005-04-16 15:20:36 -07002612 struct st_partstat *STps;
2613 int fileno, blkno, at_sm, undone;
2614 int datalen = 0, direction = DMA_NONE;
2615 char *name = tape_name(STp);
2616
2617 WARN_ON(STp->buffer->do_dio != 0);
2618 if (STp->ready != ST_READY) {
2619 if (STp->ready == ST_NO_TAPE)
2620 return (-ENOMEDIUM);
2621 else
2622 return (-EIO);
2623 }
2624 timeout = STp->long_timeout;
2625 STps = &(STp->ps[STp->partition]);
2626 fileno = STps->drv_file;
2627 blkno = STps->drv_block;
2628 at_sm = STps->at_sm;
2629
2630 memset(cmd, 0, MAX_COMMAND_SIZE);
2631 switch (cmd_in) {
2632 case MTFSFM:
2633 chg_eof = 0; /* Changed from the FSF after this */
2634 case MTFSF:
2635 cmd[0] = SPACE;
2636 cmd[1] = 0x01; /* Space FileMarks */
2637 cmd[2] = (arg >> 16);
2638 cmd[3] = (arg >> 8);
2639 cmd[4] = arg;
2640 DEBC(deb_space_print(name, ST_DEB_FORWARD, "filemarks", cmd);)
2641 if (fileno >= 0)
2642 fileno += arg;
2643 blkno = 0;
2644 at_sm &= (arg == 0);
2645 break;
2646 case MTBSFM:
2647 chg_eof = 0; /* Changed from the FSF after this */
2648 case MTBSF:
2649 cmd[0] = SPACE;
2650 cmd[1] = 0x01; /* Space FileMarks */
2651 ltmp = (-arg);
2652 cmd[2] = (ltmp >> 16);
2653 cmd[3] = (ltmp >> 8);
2654 cmd[4] = ltmp;
2655 DEBC(deb_space_print(name, ST_DEB_BACKWARD, "filemarks", cmd);)
2656 if (fileno >= 0)
2657 fileno -= arg;
2658 blkno = (-1); /* We can't know the block number */
2659 at_sm &= (arg == 0);
2660 break;
2661 case MTFSR:
2662 cmd[0] = SPACE;
2663 cmd[1] = 0x00; /* Space Blocks */
2664 cmd[2] = (arg >> 16);
2665 cmd[3] = (arg >> 8);
2666 cmd[4] = arg;
2667 DEBC(deb_space_print(name, ST_DEB_FORWARD, "blocks", cmd);)
2668 if (blkno >= 0)
2669 blkno += arg;
2670 at_sm &= (arg == 0);
2671 break;
2672 case MTBSR:
2673 cmd[0] = SPACE;
2674 cmd[1] = 0x00; /* Space Blocks */
2675 ltmp = (-arg);
2676 cmd[2] = (ltmp >> 16);
2677 cmd[3] = (ltmp >> 8);
2678 cmd[4] = ltmp;
2679 DEBC(deb_space_print(name, ST_DEB_BACKWARD, "blocks", cmd);)
2680 if (blkno >= 0)
2681 blkno -= arg;
2682 at_sm &= (arg == 0);
2683 break;
2684 case MTFSS:
2685 cmd[0] = SPACE;
2686 cmd[1] = 0x04; /* Space Setmarks */
2687 cmd[2] = (arg >> 16);
2688 cmd[3] = (arg >> 8);
2689 cmd[4] = arg;
2690 DEBC(deb_space_print(name, ST_DEB_FORWARD, "setmarks", cmd);)
2691 if (arg != 0) {
2692 blkno = fileno = (-1);
2693 at_sm = 1;
2694 }
2695 break;
2696 case MTBSS:
2697 cmd[0] = SPACE;
2698 cmd[1] = 0x04; /* Space Setmarks */
2699 ltmp = (-arg);
2700 cmd[2] = (ltmp >> 16);
2701 cmd[3] = (ltmp >> 8);
2702 cmd[4] = ltmp;
2703 DEBC(deb_space_print(name, ST_DEB_BACKWARD, "setmarks", cmd);)
2704 if (arg != 0) {
2705 blkno = fileno = (-1);
2706 at_sm = 1;
2707 }
2708 break;
2709 case MTWEOF:
Kai Makisara3e51d3c2010-10-09 00:17:56 +03002710 case MTWEOFI:
Linus Torvalds1da177e2005-04-16 15:20:36 -07002711 case MTWSM:
2712 if (STp->write_prot)
2713 return (-EACCES);
2714 cmd[0] = WRITE_FILEMARKS;
2715 if (cmd_in == MTWSM)
2716 cmd[1] = 2;
Kai Makisara3e51d3c2010-10-09 00:17:56 +03002717 if (cmd_in == MTWEOFI)
2718 cmd[1] |= 1;
Linus Torvalds1da177e2005-04-16 15:20:36 -07002719 cmd[2] = (arg >> 16);
2720 cmd[3] = (arg >> 8);
2721 cmd[4] = arg;
James Bottomleya02488e2008-11-30 10:36:26 -06002722 timeout = STp->device->request_queue->rq_timeout;
Linus Torvalds1da177e2005-04-16 15:20:36 -07002723 DEBC(
Kai Makisara3e51d3c2010-10-09 00:17:56 +03002724 if (cmd_in != MTWSM)
Linus Torvalds1da177e2005-04-16 15:20:36 -07002725 printk(ST_DEB_MSG "%s: Writing %d filemarks.\n", name,
2726 cmd[2] * 65536 + cmd[3] * 256 + cmd[4]);
2727 else
2728 printk(ST_DEB_MSG "%s: Writing %d setmarks.\n", name,
2729 cmd[2] * 65536 + cmd[3] * 256 + cmd[4]);
2730 )
2731 if (fileno >= 0)
2732 fileno += arg;
2733 blkno = 0;
2734 at_sm = (cmd_in == MTWSM);
2735 break;
2736 case MTREW:
2737 cmd[0] = REZERO_UNIT;
2738 if (STp->immediate) {
2739 cmd[1] = 1; /* Don't wait for completion */
James Bottomleya02488e2008-11-30 10:36:26 -06002740 timeout = STp->device->request_queue->rq_timeout;
Linus Torvalds1da177e2005-04-16 15:20:36 -07002741 }
2742 DEBC(printk(ST_DEB_MSG "%s: Rewinding tape.\n", name));
2743 fileno = blkno = at_sm = 0;
2744 break;
2745 case MTNOP:
2746 DEBC(printk(ST_DEB_MSG "%s: No op on tape.\n", name));
2747 return 0; /* Should do something ? */
2748 break;
2749 case MTRETEN:
2750 cmd[0] = START_STOP;
2751 if (STp->immediate) {
2752 cmd[1] = 1; /* Don't wait for completion */
James Bottomleya02488e2008-11-30 10:36:26 -06002753 timeout = STp->device->request_queue->rq_timeout;
Linus Torvalds1da177e2005-04-16 15:20:36 -07002754 }
2755 cmd[4] = 3;
2756 DEBC(printk(ST_DEB_MSG "%s: Retensioning tape.\n", name));
2757 fileno = blkno = at_sm = 0;
2758 break;
2759 case MTEOM:
2760 if (!STp->fast_mteom) {
2761 /* space to the end of tape */
2762 ioctl_result = st_int_ioctl(STp, MTFSF, 0x7fffff);
2763 fileno = STps->drv_file;
2764 if (STps->eof >= ST_EOD_1)
2765 return 0;
2766 /* The next lines would hide the number of spaced FileMarks
2767 That's why I inserted the previous lines. I had no luck
2768 with detecting EOM with FSF, so we go now to EOM.
2769 Joerg Weule */
2770 } else
2771 fileno = (-1);
2772 cmd[0] = SPACE;
2773 cmd[1] = 3;
2774 DEBC(printk(ST_DEB_MSG "%s: Spacing to end of recorded medium.\n",
2775 name));
2776 blkno = -1;
2777 at_sm = 0;
2778 break;
2779 case MTERASE:
2780 if (STp->write_prot)
2781 return (-EACCES);
2782 cmd[0] = ERASE;
2783 cmd[1] = (arg ? 1 : 0); /* Long erase with non-zero argument */
2784 if (STp->immediate) {
2785 cmd[1] |= 2; /* Don't wait for completion */
James Bottomleya02488e2008-11-30 10:36:26 -06002786 timeout = STp->device->request_queue->rq_timeout;
Linus Torvalds1da177e2005-04-16 15:20:36 -07002787 }
2788 else
2789 timeout = STp->long_timeout * 8;
2790
2791 DEBC(printk(ST_DEB_MSG "%s: Erasing tape.\n", name));
2792 fileno = blkno = at_sm = 0;
2793 break;
2794 case MTSETBLK: /* Set block length */
2795 case MTSETDENSITY: /* Set tape density */
2796 case MTSETDRVBUFFER: /* Set drive buffering */
2797 case SET_DENS_AND_BLK: /* Set density and block size */
2798 chg_eof = 0;
2799 if (STp->dirty || (STp->buffer)->buffer_bytes != 0)
2800 return (-EIO); /* Not allowed if data in buffer */
2801 if ((cmd_in == MTSETBLK || cmd_in == SET_DENS_AND_BLK) &&
2802 (arg & MT_ST_BLKSIZE_MASK) != 0 &&
2803 STp->max_block > 0 &&
2804 ((arg & MT_ST_BLKSIZE_MASK) < STp->min_block ||
2805 (arg & MT_ST_BLKSIZE_MASK) > STp->max_block)) {
2806 printk(KERN_WARNING "%s: Illegal block size.\n", name);
2807 return (-EINVAL);
2808 }
2809 cmd[0] = MODE_SELECT;
2810 if ((STp->use_pf & USE_PF))
2811 cmd[1] = MODE_SELECT_PAGE_FORMAT;
2812 cmd[4] = datalen = 12;
2813 direction = DMA_TO_DEVICE;
2814
2815 memset((STp->buffer)->b_data, 0, 12);
2816 if (cmd_in == MTSETDRVBUFFER)
2817 (STp->buffer)->b_data[2] = (arg & 7) << 4;
2818 else
2819 (STp->buffer)->b_data[2] =
2820 STp->drv_buffer << 4;
2821 (STp->buffer)->b_data[3] = 8; /* block descriptor length */
2822 if (cmd_in == MTSETDENSITY) {
2823 (STp->buffer)->b_data[4] = arg;
2824 STp->density_changed = 1; /* At least we tried ;-) */
2825 } else if (cmd_in == SET_DENS_AND_BLK)
2826 (STp->buffer)->b_data[4] = arg >> 24;
2827 else
2828 (STp->buffer)->b_data[4] = STp->density;
2829 if (cmd_in == MTSETBLK || cmd_in == SET_DENS_AND_BLK) {
2830 ltmp = arg & MT_ST_BLKSIZE_MASK;
2831 if (cmd_in == MTSETBLK)
2832 STp->blksize_changed = 1; /* At least we tried ;-) */
2833 } else
2834 ltmp = STp->block_size;
2835 (STp->buffer)->b_data[9] = (ltmp >> 16);
2836 (STp->buffer)->b_data[10] = (ltmp >> 8);
2837 (STp->buffer)->b_data[11] = ltmp;
James Bottomleya02488e2008-11-30 10:36:26 -06002838 timeout = STp->device->request_queue->rq_timeout;
Linus Torvalds1da177e2005-04-16 15:20:36 -07002839 DEBC(
2840 if (cmd_in == MTSETBLK || cmd_in == SET_DENS_AND_BLK)
2841 printk(ST_DEB_MSG
2842 "%s: Setting block size to %d bytes.\n", name,
2843 (STp->buffer)->b_data[9] * 65536 +
2844 (STp->buffer)->b_data[10] * 256 +
2845 (STp->buffer)->b_data[11]);
2846 if (cmd_in == MTSETDENSITY || cmd_in == SET_DENS_AND_BLK)
2847 printk(ST_DEB_MSG
2848 "%s: Setting density code to %x.\n", name,
2849 (STp->buffer)->b_data[4]);
2850 if (cmd_in == MTSETDRVBUFFER)
2851 printk(ST_DEB_MSG
2852 "%s: Setting drive buffer code to %d.\n", name,
2853 ((STp->buffer)->b_data[2] >> 4) & 7);
2854 )
2855 break;
2856 default:
2857 return (-ENOSYS);
2858 }
2859
Kai Makisara02ae2c02008-12-18 14:49:50 +09002860 SRpnt = st_do_scsi(NULL, STp, cmd, datalen, direction,
2861 timeout, MAX_RETRIES, 1);
Linus Torvalds1da177e2005-04-16 15:20:36 -07002862 if (!SRpnt)
2863 return (STp->buffer)->syscall_result;
2864
Kai Makisara02ae2c02008-12-18 14:49:50 +09002865 ioctl_result = (STp->buffer)->syscall_result;
Linus Torvalds1da177e2005-04-16 15:20:36 -07002866
2867 if (!ioctl_result) { /* SCSI command successful */
Mike Christie8b05b772005-11-08 04:06:44 -06002868 st_release_request(SRpnt);
Linus Torvalds1da177e2005-04-16 15:20:36 -07002869 SRpnt = NULL;
2870 STps->drv_block = blkno;
2871 STps->drv_file = fileno;
2872 STps->at_sm = at_sm;
2873
2874 if (cmd_in == MTBSFM)
2875 ioctl_result = st_int_ioctl(STp, MTFSF, 1);
2876 else if (cmd_in == MTFSFM)
2877 ioctl_result = st_int_ioctl(STp, MTBSF, 1);
2878
2879 if (cmd_in == MTSETBLK || cmd_in == SET_DENS_AND_BLK) {
Linus Torvalds1da177e2005-04-16 15:20:36 -07002880 STp->block_size = arg & MT_ST_BLKSIZE_MASK;
2881 if (STp->block_size != 0) {
Linus Torvalds1da177e2005-04-16 15:20:36 -07002882 (STp->buffer)->buffer_blocks =
2883 (STp->buffer)->buffer_size / STp->block_size;
2884 }
2885 (STp->buffer)->buffer_bytes = (STp->buffer)->read_pointer = 0;
2886 if (cmd_in == SET_DENS_AND_BLK)
2887 STp->density = arg >> MT_ST_DENSITY_SHIFT;
2888 } else if (cmd_in == MTSETDRVBUFFER)
2889 STp->drv_buffer = (arg & 7);
2890 else if (cmd_in == MTSETDENSITY)
2891 STp->density = arg;
2892
2893 if (cmd_in == MTEOM)
2894 STps->eof = ST_EOD;
2895 else if (cmd_in == MTFSF)
2896 STps->eof = ST_FM;
2897 else if (chg_eof)
2898 STps->eof = ST_NOEOF;
2899
Kai Makisara3e51d3c2010-10-09 00:17:56 +03002900 if (cmd_in == MTWEOF || cmd_in == MTWEOFI)
2901 STps->rw = ST_IDLE; /* prevent automatic WEOF at close */
Linus Torvalds1da177e2005-04-16 15:20:36 -07002902 } else { /* SCSI command was not completely successful. Don't return
2903 from this block without releasing the SCSI command block! */
2904 struct st_cmdstatus *cmdstatp = &STp->buffer->cmdstat;
2905
2906 if (cmdstatp->flags & SENSE_EOM) {
2907 if (cmd_in != MTBSF && cmd_in != MTBSFM &&
2908 cmd_in != MTBSR && cmd_in != MTBSS)
2909 STps->eof = ST_EOM_OK;
2910 STps->drv_block = 0;
2911 }
2912
2913 if (cmdstatp->remainder_valid)
2914 undone = (int)cmdstatp->uremainder64;
2915 else
2916 undone = 0;
2917
Kai Makisara3e51d3c2010-10-09 00:17:56 +03002918 if ((cmd_in == MTWEOF || cmd_in == MTWEOFI) &&
Linus Torvalds1da177e2005-04-16 15:20:36 -07002919 cmdstatp->have_sense &&
Kai Makisara91614c02007-01-26 00:38:39 +02002920 (cmdstatp->flags & SENSE_EOM)) {
2921 if (cmdstatp->sense_hdr.sense_key == NO_SENSE ||
2922 cmdstatp->sense_hdr.sense_key == RECOVERED_ERROR) {
2923 ioctl_result = 0; /* EOF(s) written successfully at EOM */
2924 STps->eof = ST_NOEOF;
2925 } else { /* Writing EOF(s) failed */
2926 if (fileno >= 0)
2927 fileno -= undone;
2928 if (undone < arg)
2929 STps->eof = ST_NOEOF;
2930 }
Linus Torvalds1da177e2005-04-16 15:20:36 -07002931 STps->drv_file = fileno;
Linus Torvalds1da177e2005-04-16 15:20:36 -07002932 } else if ((cmd_in == MTFSF) || (cmd_in == MTFSFM)) {
2933 if (fileno >= 0)
2934 STps->drv_file = fileno - undone;
2935 else
2936 STps->drv_file = fileno;
2937 STps->drv_block = -1;
2938 STps->eof = ST_NOEOF;
2939 } else if ((cmd_in == MTBSF) || (cmd_in == MTBSFM)) {
2940 if (arg > 0 && undone < 0) /* Some drives get this wrong */
2941 undone = (-undone);
2942 if (STps->drv_file >= 0)
2943 STps->drv_file = fileno + undone;
2944 STps->drv_block = 0;
2945 STps->eof = ST_NOEOF;
2946 } else if (cmd_in == MTFSR) {
2947 if (cmdstatp->flags & SENSE_FMK) { /* Hit filemark */
2948 if (STps->drv_file >= 0)
2949 STps->drv_file++;
2950 STps->drv_block = 0;
2951 STps->eof = ST_FM;
2952 } else {
2953 if (blkno >= undone)
2954 STps->drv_block = blkno - undone;
2955 else
2956 STps->drv_block = (-1);
2957 STps->eof = ST_NOEOF;
2958 }
2959 } else if (cmd_in == MTBSR) {
2960 if (cmdstatp->flags & SENSE_FMK) { /* Hit filemark */
2961 STps->drv_file--;
2962 STps->drv_block = (-1);
2963 } else {
2964 if (arg > 0 && undone < 0) /* Some drives get this wrong */
2965 undone = (-undone);
2966 if (STps->drv_block >= 0)
2967 STps->drv_block = blkno + undone;
2968 }
2969 STps->eof = ST_NOEOF;
2970 } else if (cmd_in == MTEOM) {
2971 STps->drv_file = (-1);
2972 STps->drv_block = (-1);
2973 STps->eof = ST_EOD;
2974 } else if (cmd_in == MTSETBLK ||
2975 cmd_in == MTSETDENSITY ||
2976 cmd_in == MTSETDRVBUFFER ||
2977 cmd_in == SET_DENS_AND_BLK) {
2978 if (cmdstatp->sense_hdr.sense_key == ILLEGAL_REQUEST &&
2979 !(STp->use_pf & PF_TESTED)) {
2980 /* Try the other possible state of Page Format if not
2981 already tried */
Kai Makisara1da20192009-05-02 08:49:34 +03002982 STp->use_pf = (STp->use_pf ^ USE_PF) | PF_TESTED;
Mike Christie8b05b772005-11-08 04:06:44 -06002983 st_release_request(SRpnt);
Linus Torvalds1da177e2005-04-16 15:20:36 -07002984 SRpnt = NULL;
2985 return st_int_ioctl(STp, cmd_in, arg);
2986 }
2987 } else if (chg_eof)
2988 STps->eof = ST_NOEOF;
2989
2990 if (cmdstatp->sense_hdr.sense_key == BLANK_CHECK)
2991 STps->eof = ST_EOD;
2992
Mike Christie8b05b772005-11-08 04:06:44 -06002993 st_release_request(SRpnt);
Linus Torvalds1da177e2005-04-16 15:20:36 -07002994 SRpnt = NULL;
2995 }
2996
2997 return ioctl_result;
2998}
2999
3000
3001/* Get the tape position. If bt == 2, arg points into a kernel space mt_loc
3002 structure. */
3003
3004static int get_location(struct scsi_tape *STp, unsigned int *block, int *partition,
3005 int logical)
3006{
3007 int result;
3008 unsigned char scmd[MAX_COMMAND_SIZE];
Mike Christie8b05b772005-11-08 04:06:44 -06003009 struct st_request *SRpnt;
Linus Torvalds1da177e2005-04-16 15:20:36 -07003010 DEB( char *name = tape_name(STp); )
3011
3012 if (STp->ready != ST_READY)
3013 return (-EIO);
3014
3015 memset(scmd, 0, MAX_COMMAND_SIZE);
3016 if ((STp->device)->scsi_level < SCSI_2) {
3017 scmd[0] = QFA_REQUEST_BLOCK;
3018 scmd[4] = 3;
3019 } else {
3020 scmd[0] = READ_POSITION;
3021 if (!logical && !STp->scsi2_logical)
3022 scmd[1] = 1;
3023 }
Kai Makisara02ae2c02008-12-18 14:49:50 +09003024 SRpnt = st_do_scsi(NULL, STp, scmd, 20, DMA_FROM_DEVICE,
3025 STp->device->request_queue->rq_timeout,
3026 MAX_READY_RETRIES, 1);
Linus Torvalds1da177e2005-04-16 15:20:36 -07003027 if (!SRpnt)
Kai Makisara02ae2c02008-12-18 14:49:50 +09003028 return (STp->buffer)->syscall_result;
Linus Torvalds1da177e2005-04-16 15:20:36 -07003029
3030 if ((STp->buffer)->syscall_result != 0 ||
3031 (STp->device->scsi_level >= SCSI_2 &&
3032 ((STp->buffer)->b_data[0] & 4) != 0)) {
3033 *block = *partition = 0;
3034 DEBC(printk(ST_DEB_MSG "%s: Can't read tape position.\n", name));
3035 result = (-EIO);
3036 } else {
3037 result = 0;
3038 if ((STp->device)->scsi_level < SCSI_2) {
3039 *block = ((STp->buffer)->b_data[0] << 16)
3040 + ((STp->buffer)->b_data[1] << 8)
3041 + (STp->buffer)->b_data[2];
3042 *partition = 0;
3043 } else {
3044 *block = ((STp->buffer)->b_data[4] << 24)
3045 + ((STp->buffer)->b_data[5] << 16)
3046 + ((STp->buffer)->b_data[6] << 8)
3047 + (STp->buffer)->b_data[7];
3048 *partition = (STp->buffer)->b_data[1];
3049 if (((STp->buffer)->b_data[0] & 0x80) &&
3050 (STp->buffer)->b_data[1] == 0) /* BOP of partition 0 */
3051 STp->ps[0].drv_block = STp->ps[0].drv_file = 0;
3052 }
3053 DEBC(printk(ST_DEB_MSG "%s: Got tape pos. blk %d part %d.\n", name,
3054 *block, *partition));
3055 }
Mike Christie8b05b772005-11-08 04:06:44 -06003056 st_release_request(SRpnt);
Linus Torvalds1da177e2005-04-16 15:20:36 -07003057 SRpnt = NULL;
3058
3059 return result;
3060}
3061
3062
3063/* Set the tape block and partition. Negative partition means that only the
3064 block should be set in vendor specific way. */
3065static int set_location(struct scsi_tape *STp, unsigned int block, int partition,
3066 int logical)
3067{
3068 struct st_partstat *STps;
3069 int result, p;
3070 unsigned int blk;
3071 int timeout;
3072 unsigned char scmd[MAX_COMMAND_SIZE];
Mike Christie8b05b772005-11-08 04:06:44 -06003073 struct st_request *SRpnt;
Linus Torvalds1da177e2005-04-16 15:20:36 -07003074 DEB( char *name = tape_name(STp); )
3075
3076 if (STp->ready != ST_READY)
3077 return (-EIO);
3078 timeout = STp->long_timeout;
3079 STps = &(STp->ps[STp->partition]);
3080
3081 DEBC(printk(ST_DEB_MSG "%s: Setting block to %d and partition to %d.\n",
3082 name, block, partition));
3083 DEB(if (partition < 0)
3084 return (-EIO); )
3085
3086 /* Update the location at the partition we are leaving */
3087 if ((!STp->can_partitions && partition != 0) ||
3088 partition >= ST_NBR_PARTITIONS)
3089 return (-EINVAL);
3090 if (partition != STp->partition) {
3091 if (get_location(STp, &blk, &p, 1))
3092 STps->last_block_valid = 0;
3093 else {
3094 STps->last_block_valid = 1;
3095 STps->last_block_visited = blk;
3096 DEBC(printk(ST_DEB_MSG
3097 "%s: Visited block %d for partition %d saved.\n",
3098 name, blk, STp->partition));
3099 }
3100 }
3101
3102 memset(scmd, 0, MAX_COMMAND_SIZE);
3103 if ((STp->device)->scsi_level < SCSI_2) {
3104 scmd[0] = QFA_SEEK_BLOCK;
3105 scmd[2] = (block >> 16);
3106 scmd[3] = (block >> 8);
3107 scmd[4] = block;
3108 scmd[5] = 0;
3109 } else {
3110 scmd[0] = SEEK_10;
3111 scmd[3] = (block >> 24);
3112 scmd[4] = (block >> 16);
3113 scmd[5] = (block >> 8);
3114 scmd[6] = block;
3115 if (!logical && !STp->scsi2_logical)
3116 scmd[1] = 4;
3117 if (STp->partition != partition) {
3118 scmd[1] |= 2;
3119 scmd[8] = partition;
3120 DEBC(printk(ST_DEB_MSG
3121 "%s: Trying to change partition from %d to %d\n",
3122 name, STp->partition, partition));
3123 }
3124 }
3125 if (STp->immediate) {
3126 scmd[1] |= 1; /* Don't wait for completion */
James Bottomleya02488e2008-11-30 10:36:26 -06003127 timeout = STp->device->request_queue->rq_timeout;
Linus Torvalds1da177e2005-04-16 15:20:36 -07003128 }
3129
Kai Makisara02ae2c02008-12-18 14:49:50 +09003130 SRpnt = st_do_scsi(NULL, STp, scmd, 0, DMA_NONE,
3131 timeout, MAX_READY_RETRIES, 1);
Linus Torvalds1da177e2005-04-16 15:20:36 -07003132 if (!SRpnt)
Kai Makisara02ae2c02008-12-18 14:49:50 +09003133 return (STp->buffer)->syscall_result;
Linus Torvalds1da177e2005-04-16 15:20:36 -07003134
3135 STps->drv_block = STps->drv_file = (-1);
3136 STps->eof = ST_NOEOF;
3137 if ((STp->buffer)->syscall_result != 0) {
3138 result = (-EIO);
3139 if (STp->can_partitions &&
3140 (STp->device)->scsi_level >= SCSI_2 &&
3141 (p = find_partition(STp)) >= 0)
3142 STp->partition = p;
3143 } else {
3144 if (STp->can_partitions) {
3145 STp->partition = partition;
3146 STps = &(STp->ps[partition]);
3147 if (!STps->last_block_valid ||
3148 STps->last_block_visited != block) {
3149 STps->at_sm = 0;
3150 STps->rw = ST_IDLE;
3151 }
3152 } else
3153 STps->at_sm = 0;
3154 if (block == 0)
3155 STps->drv_block = STps->drv_file = 0;
3156 result = 0;
3157 }
Kai Makisara02ae2c02008-12-18 14:49:50 +09003158
Mike Christie8b05b772005-11-08 04:06:44 -06003159 st_release_request(SRpnt);
Linus Torvalds1da177e2005-04-16 15:20:36 -07003160 SRpnt = NULL;
3161
3162 return result;
3163}
3164
3165
3166/* Find the current partition number for the drive status. Called from open and
3167 returns either partition number of negative error code. */
3168static int find_partition(struct scsi_tape *STp)
3169{
3170 int i, partition;
3171 unsigned int block;
3172
3173 if ((i = get_location(STp, &block, &partition, 1)) < 0)
3174 return i;
3175 if (partition >= ST_NBR_PARTITIONS)
3176 return (-EIO);
3177 return partition;
3178}
3179
3180
3181/* Change the partition if necessary */
3182static int switch_partition(struct scsi_tape *STp)
3183{
3184 struct st_partstat *STps;
3185
3186 if (STp->partition == STp->new_partition)
3187 return 0;
3188 STps = &(STp->ps[STp->new_partition]);
3189 if (!STps->last_block_valid)
3190 STps->last_block_visited = 0;
3191 return set_location(STp, STps->last_block_visited, STp->new_partition, 1);
3192}
3193
3194/* Functions for reading and writing the medium partition mode page. */
3195
3196#define PART_PAGE 0x11
3197#define PART_PAGE_FIXED_LENGTH 8
3198
3199#define PP_OFF_MAX_ADD_PARTS 2
3200#define PP_OFF_NBR_ADD_PARTS 3
3201#define PP_OFF_FLAGS 4
3202#define PP_OFF_PART_UNITS 6
3203#define PP_OFF_RESERVED 7
3204
3205#define PP_BIT_IDP 0x20
3206#define PP_MSK_PSUM_MB 0x10
3207
3208/* Get the number of partitions on the tape. As a side effect reads the
3209 mode page into the tape buffer. */
3210static int nbr_partitions(struct scsi_tape *STp)
3211{
3212 int result;
3213 DEB( char *name = tape_name(STp); )
3214
3215 if (STp->ready != ST_READY)
3216 return (-EIO);
3217
3218 result = read_mode_page(STp, PART_PAGE, 1);
3219
3220 if (result) {
3221 DEBC(printk(ST_DEB_MSG "%s: Can't read medium partition page.\n",
3222 name));
3223 result = (-EIO);
3224 } else {
3225 result = (STp->buffer)->b_data[MODE_HEADER_LENGTH +
3226 PP_OFF_NBR_ADD_PARTS] + 1;
3227 DEBC(printk(ST_DEB_MSG "%s: Number of partitions %d.\n", name, result));
3228 }
3229
3230 return result;
3231}
3232
3233
3234/* Partition the tape into two partitions if size > 0 or one partition if
3235 size == 0.
3236
3237 The block descriptors are read and written because Sony SDT-7000 does not
3238 work without this (suggestion from Michael Schaefer <Michael.Schaefer@dlr.de>).
3239
3240 My HP C1533A drive returns only one partition size field. This is used to
3241 set the size of partition 1. There is no size field for the default partition.
3242 Michael Schaefer's Sony SDT-7000 returns two descriptors and the second is
3243 used to set the size of partition 1 (this is what the SCSI-3 standard specifies).
3244 The following algorithm is used to accommodate both drives: if the number of
3245 partition size fields is greater than the maximum number of additional partitions
3246 in the mode page, the second field is used. Otherwise the first field is used.
3247
3248 For Seagate DDS drives the page length must be 8 when no partitions is defined
3249 and 10 when 1 partition is defined (information from Eric Lee Green). This is
3250 is acceptable also to some other old drives and enforced if the first partition
3251 size field is used for the first additional partition size.
3252 */
3253static int partition_tape(struct scsi_tape *STp, int size)
3254{
3255 char *name = tape_name(STp);
3256 int result;
3257 int pgo, psd_cnt, psdo;
3258 unsigned char *bp;
3259
3260 result = read_mode_page(STp, PART_PAGE, 0);
3261 if (result) {
3262 DEBC(printk(ST_DEB_MSG "%s: Can't read partition mode page.\n", name));
3263 return result;
3264 }
3265 /* The mode page is in the buffer. Let's modify it and write it. */
3266 bp = (STp->buffer)->b_data;
3267 pgo = MODE_HEADER_LENGTH + bp[MH_OFF_BDESCS_LENGTH];
3268 DEBC(printk(ST_DEB_MSG "%s: Partition page length is %d bytes.\n",
3269 name, bp[pgo + MP_OFF_PAGE_LENGTH] + 2));
3270
3271 psd_cnt = (bp[pgo + MP_OFF_PAGE_LENGTH] + 2 - PART_PAGE_FIXED_LENGTH) / 2;
3272 psdo = pgo + PART_PAGE_FIXED_LENGTH;
3273 if (psd_cnt > bp[pgo + PP_OFF_MAX_ADD_PARTS]) {
3274 bp[psdo] = bp[psdo + 1] = 0xff; /* Rest of the tape */
3275 psdo += 2;
3276 }
3277 memset(bp + psdo, 0, bp[pgo + PP_OFF_NBR_ADD_PARTS] * 2);
3278
3279 DEBC(printk("%s: psd_cnt %d, max.parts %d, nbr_parts %d\n", name,
3280 psd_cnt, bp[pgo + PP_OFF_MAX_ADD_PARTS],
3281 bp[pgo + PP_OFF_NBR_ADD_PARTS]));
3282
3283 if (size <= 0) {
3284 bp[pgo + PP_OFF_NBR_ADD_PARTS] = 0;
3285 if (psd_cnt <= bp[pgo + PP_OFF_MAX_ADD_PARTS])
3286 bp[pgo + MP_OFF_PAGE_LENGTH] = 6;
3287 DEBC(printk(ST_DEB_MSG "%s: Formatting tape with one partition.\n",
3288 name));
3289 } else {
3290 bp[psdo] = (size >> 8) & 0xff;
3291 bp[psdo + 1] = size & 0xff;
3292 bp[pgo + 3] = 1;
3293 if (bp[pgo + MP_OFF_PAGE_LENGTH] < 8)
3294 bp[pgo + MP_OFF_PAGE_LENGTH] = 8;
3295 DEBC(printk(ST_DEB_MSG
3296 "%s: Formatting tape with two partitions (1 = %d MB).\n",
3297 name, size));
3298 }
3299 bp[pgo + PP_OFF_PART_UNITS] = 0;
3300 bp[pgo + PP_OFF_RESERVED] = 0;
3301 bp[pgo + PP_OFF_FLAGS] = PP_BIT_IDP | PP_MSK_PSUM_MB;
3302
3303 result = write_mode_page(STp, PART_PAGE, 1);
3304 if (result) {
3305 printk(KERN_INFO "%s: Partitioning of tape failed.\n", name);
3306 result = (-EIO);
3307 }
3308
3309 return result;
3310}
3311
3312
3313
3314/* The ioctl command */
Kai Makisarafd66c1b2008-01-17 22:45:22 +02003315static long st_ioctl(struct file *file, unsigned int cmd_in, unsigned long arg)
Linus Torvalds1da177e2005-04-16 15:20:36 -07003316{
3317 int i, cmd_nr, cmd_type, bt;
3318 int retval = 0;
3319 unsigned int blk;
3320 struct scsi_tape *STp = file->private_data;
3321 struct st_modedef *STm;
3322 struct st_partstat *STps;
3323 char *name = tape_name(STp);
3324 void __user *p = (void __user *)arg;
3325
Matthias Kaehlcke28f85002007-07-29 23:38:15 +02003326 if (mutex_lock_interruptible(&STp->lock))
Linus Torvalds1da177e2005-04-16 15:20:36 -07003327 return -ERESTARTSYS;
3328
3329 DEB(
3330 if (debugging && !STp->in_use) {
3331 printk(ST_DEB_MSG "%s: Incorrect device.\n", name);
3332 retval = (-EIO);
3333 goto out;
3334 } ) /* end DEB */
3335
3336 STm = &(STp->modes[STp->current_mode]);
3337 STps = &(STp->ps[STp->partition]);
3338
3339 /*
3340 * If we are in the middle of error recovery, don't let anyone
3341 * else try and use this device. Also, if error recovery fails, it
3342 * may try and take the device offline, in which case all further
3343 * access to the device is prohibited.
3344 */
Al Viro83ff6fe2008-03-02 08:15:49 -05003345 retval = scsi_nonblockable_ioctl(STp->device, cmd_in, p,
3346 file->f_flags & O_NDELAY);
Linus Torvalds1da177e2005-04-16 15:20:36 -07003347 if (!scsi_block_when_processing_errors(STp->device) || retval != -ENODEV)
3348 goto out;
3349 retval = 0;
3350
3351 cmd_type = _IOC_TYPE(cmd_in);
3352 cmd_nr = _IOC_NR(cmd_in);
3353
3354 if (cmd_type == _IOC_TYPE(MTIOCTOP) && cmd_nr == _IOC_NR(MTIOCTOP)) {
3355 struct mtop mtc;
3356
3357 if (_IOC_SIZE(cmd_in) != sizeof(mtc)) {
3358 retval = (-EINVAL);
3359 goto out;
3360 }
3361
3362 i = copy_from_user(&mtc, p, sizeof(struct mtop));
3363 if (i) {
3364 retval = (-EFAULT);
3365 goto out;
3366 }
3367
3368 if (mtc.mt_op == MTSETDRVBUFFER && !capable(CAP_SYS_ADMIN)) {
3369 printk(KERN_WARNING
3370 "%s: MTSETDRVBUFFER only allowed for root.\n", name);
3371 retval = (-EPERM);
3372 goto out;
3373 }
3374 if (!STm->defined &&
3375 (mtc.mt_op != MTSETDRVBUFFER &&
3376 (mtc.mt_count & MT_ST_OPTIONS) == 0)) {
3377 retval = (-ENXIO);
3378 goto out;
3379 }
3380
3381 if (!STp->pos_unknown) {
3382
3383 if (STps->eof == ST_FM_HIT) {
3384 if (mtc.mt_op == MTFSF || mtc.mt_op == MTFSFM ||
3385 mtc.mt_op == MTEOM) {
3386 mtc.mt_count -= 1;
3387 if (STps->drv_file >= 0)
3388 STps->drv_file += 1;
3389 } else if (mtc.mt_op == MTBSF || mtc.mt_op == MTBSFM) {
3390 mtc.mt_count += 1;
3391 if (STps->drv_file >= 0)
3392 STps->drv_file += 1;
3393 }
3394 }
3395
3396 if (mtc.mt_op == MTSEEK) {
3397 /* Old position must be restored if partition will be
3398 changed */
3399 i = !STp->can_partitions ||
3400 (STp->new_partition != STp->partition);
3401 } else {
3402 i = mtc.mt_op == MTREW || mtc.mt_op == MTOFFL ||
3403 mtc.mt_op == MTRETEN || mtc.mt_op == MTEOM ||
3404 mtc.mt_op == MTLOCK || mtc.mt_op == MTLOAD ||
3405 mtc.mt_op == MTFSF || mtc.mt_op == MTFSFM ||
3406 mtc.mt_op == MTBSF || mtc.mt_op == MTBSFM ||
3407 mtc.mt_op == MTCOMPRESSION;
3408 }
3409 i = flush_buffer(STp, i);
3410 if (i < 0) {
3411 retval = i;
3412 goto out;
3413 }
3414 if (STps->rw == ST_WRITING &&
3415 (mtc.mt_op == MTREW || mtc.mt_op == MTOFFL ||
3416 mtc.mt_op == MTSEEK ||
3417 mtc.mt_op == MTBSF || mtc.mt_op == MTBSFM)) {
3418 i = st_int_ioctl(STp, MTWEOF, 1);
3419 if (i < 0) {
3420 retval = i;
3421 goto out;
3422 }
3423 if (mtc.mt_op == MTBSF || mtc.mt_op == MTBSFM)
3424 mtc.mt_count++;
3425 STps->rw = ST_IDLE;
3426 }
3427
3428 } else {
3429 /*
3430 * If there was a bus reset, block further access
3431 * to this device. If the user wants to rewind the tape,
3432 * then reset the flag and allow access again.
3433 */
3434 if (mtc.mt_op != MTREW &&
3435 mtc.mt_op != MTOFFL &&
3436 mtc.mt_op != MTRETEN &&
3437 mtc.mt_op != MTERASE &&
3438 mtc.mt_op != MTSEEK &&
3439 mtc.mt_op != MTEOM) {
3440 retval = (-EIO);
3441 goto out;
3442 }
3443 reset_state(STp);
3444 /* remove this when the midlevel properly clears was_reset */
3445 STp->device->was_reset = 0;
3446 }
3447
3448 if (mtc.mt_op != MTNOP && mtc.mt_op != MTSETBLK &&
3449 mtc.mt_op != MTSETDENSITY && mtc.mt_op != MTWSM &&
3450 mtc.mt_op != MTSETDRVBUFFER && mtc.mt_op != MTSETPART)
3451 STps->rw = ST_IDLE; /* Prevent automatic WEOF and fsf */
3452
3453 if (mtc.mt_op == MTOFFL && STp->door_locked != ST_UNLOCKED)
3454 do_door_lock(STp, 0); /* Ignore result! */
3455
3456 if (mtc.mt_op == MTSETDRVBUFFER &&
3457 (mtc.mt_count & MT_ST_OPTIONS) != 0) {
3458 retval = st_set_options(STp, mtc.mt_count);
3459 goto out;
3460 }
3461
3462 if (mtc.mt_op == MTSETPART) {
3463 if (!STp->can_partitions ||
3464 mtc.mt_count < 0 || mtc.mt_count >= ST_NBR_PARTITIONS) {
3465 retval = (-EINVAL);
3466 goto out;
3467 }
3468 if (mtc.mt_count >= STp->nbr_partitions &&
3469 (STp->nbr_partitions = nbr_partitions(STp)) < 0) {
3470 retval = (-EIO);
3471 goto out;
3472 }
3473 if (mtc.mt_count >= STp->nbr_partitions) {
3474 retval = (-EINVAL);
3475 goto out;
3476 }
3477 STp->new_partition = mtc.mt_count;
3478 retval = 0;
3479 goto out;
3480 }
3481
3482 if (mtc.mt_op == MTMKPART) {
3483 if (!STp->can_partitions) {
3484 retval = (-EINVAL);
3485 goto out;
3486 }
3487 if ((i = st_int_ioctl(STp, MTREW, 0)) < 0 ||
3488 (i = partition_tape(STp, mtc.mt_count)) < 0) {
3489 retval = i;
3490 goto out;
3491 }
3492 for (i = 0; i < ST_NBR_PARTITIONS; i++) {
3493 STp->ps[i].rw = ST_IDLE;
3494 STp->ps[i].at_sm = 0;
3495 STp->ps[i].last_block_valid = 0;
3496 }
3497 STp->partition = STp->new_partition = 0;
3498 STp->nbr_partitions = 1; /* Bad guess ?-) */
3499 STps->drv_block = STps->drv_file = 0;
3500 retval = 0;
3501 goto out;
3502 }
3503
3504 if (mtc.mt_op == MTSEEK) {
3505 i = set_location(STp, mtc.mt_count, STp->new_partition, 0);
3506 if (!STp->can_partitions)
3507 STp->ps[0].rw = ST_IDLE;
3508 retval = i;
3509 goto out;
3510 }
3511
3512 if (mtc.mt_op == MTUNLOAD || mtc.mt_op == MTOFFL) {
3513 retval = do_load_unload(STp, file, 0);
3514 goto out;
3515 }
3516
3517 if (mtc.mt_op == MTLOAD) {
3518 retval = do_load_unload(STp, file, max(1, mtc.mt_count));
3519 goto out;
3520 }
3521
3522 if (mtc.mt_op == MTLOCK || mtc.mt_op == MTUNLOCK) {
3523 retval = do_door_lock(STp, (mtc.mt_op == MTLOCK));
3524 goto out;
3525 }
3526
3527 if (STp->can_partitions && STp->ready == ST_READY &&
3528 (i = switch_partition(STp)) < 0) {
3529 retval = i;
3530 goto out;
3531 }
3532
3533 if (mtc.mt_op == MTCOMPRESSION)
3534 retval = st_compression(STp, (mtc.mt_count & 1));
3535 else
3536 retval = st_int_ioctl(STp, mtc.mt_op, mtc.mt_count);
3537 goto out;
3538 }
3539 if (!STm->defined) {
3540 retval = (-ENXIO);
3541 goto out;
3542 }
3543
3544 if ((i = flush_buffer(STp, 0)) < 0) {
3545 retval = i;
3546 goto out;
3547 }
3548 if (STp->can_partitions &&
3549 (i = switch_partition(STp)) < 0) {
3550 retval = i;
3551 goto out;
3552 }
3553
3554 if (cmd_type == _IOC_TYPE(MTIOCGET) && cmd_nr == _IOC_NR(MTIOCGET)) {
3555 struct mtget mt_status;
3556
3557 if (_IOC_SIZE(cmd_in) != sizeof(struct mtget)) {
3558 retval = (-EINVAL);
3559 goto out;
3560 }
3561
3562 mt_status.mt_type = STp->tape_type;
3563 mt_status.mt_dsreg =
3564 ((STp->block_size << MT_ST_BLKSIZE_SHIFT) & MT_ST_BLKSIZE_MASK) |
3565 ((STp->density << MT_ST_DENSITY_SHIFT) & MT_ST_DENSITY_MASK);
3566 mt_status.mt_blkno = STps->drv_block;
3567 mt_status.mt_fileno = STps->drv_file;
3568 if (STp->block_size != 0) {
3569 if (STps->rw == ST_WRITING)
3570 mt_status.mt_blkno +=
3571 (STp->buffer)->buffer_bytes / STp->block_size;
3572 else if (STps->rw == ST_READING)
3573 mt_status.mt_blkno -=
3574 ((STp->buffer)->buffer_bytes +
3575 STp->block_size - 1) / STp->block_size;
3576 }
3577
3578 mt_status.mt_gstat = 0;
3579 if (STp->drv_write_prot)
3580 mt_status.mt_gstat |= GMT_WR_PROT(0xffffffff);
3581 if (mt_status.mt_blkno == 0) {
3582 if (mt_status.mt_fileno == 0)
3583 mt_status.mt_gstat |= GMT_BOT(0xffffffff);
3584 else
3585 mt_status.mt_gstat |= GMT_EOF(0xffffffff);
3586 }
3587 mt_status.mt_erreg = (STp->recover_reg << MT_ST_SOFTERR_SHIFT);
3588 mt_status.mt_resid = STp->partition;
3589 if (STps->eof == ST_EOM_OK || STps->eof == ST_EOM_ERROR)
3590 mt_status.mt_gstat |= GMT_EOT(0xffffffff);
3591 else if (STps->eof >= ST_EOM_OK)
3592 mt_status.mt_gstat |= GMT_EOD(0xffffffff);
3593 if (STp->density == 1)
3594 mt_status.mt_gstat |= GMT_D_800(0xffffffff);
3595 else if (STp->density == 2)
3596 mt_status.mt_gstat |= GMT_D_1600(0xffffffff);
3597 else if (STp->density == 3)
3598 mt_status.mt_gstat |= GMT_D_6250(0xffffffff);
3599 if (STp->ready == ST_READY)
3600 mt_status.mt_gstat |= GMT_ONLINE(0xffffffff);
3601 if (STp->ready == ST_NO_TAPE)
3602 mt_status.mt_gstat |= GMT_DR_OPEN(0xffffffff);
3603 if (STps->at_sm)
3604 mt_status.mt_gstat |= GMT_SM(0xffffffff);
3605 if (STm->do_async_writes ||
3606 (STm->do_buffer_writes && STp->block_size != 0) ||
3607 STp->drv_buffer != 0)
3608 mt_status.mt_gstat |= GMT_IM_REP_EN(0xffffffff);
3609 if (STp->cleaning_req)
3610 mt_status.mt_gstat |= GMT_CLN(0xffffffff);
3611
3612 i = copy_to_user(p, &mt_status, sizeof(struct mtget));
3613 if (i) {
3614 retval = (-EFAULT);
3615 goto out;
3616 }
3617
3618 STp->recover_reg = 0; /* Clear after read */
3619 retval = 0;
3620 goto out;
3621 } /* End of MTIOCGET */
3622 if (cmd_type == _IOC_TYPE(MTIOCPOS) && cmd_nr == _IOC_NR(MTIOCPOS)) {
3623 struct mtpos mt_pos;
3624 if (_IOC_SIZE(cmd_in) != sizeof(struct mtpos)) {
3625 retval = (-EINVAL);
3626 goto out;
3627 }
3628 if ((i = get_location(STp, &blk, &bt, 0)) < 0) {
3629 retval = i;
3630 goto out;
3631 }
3632 mt_pos.mt_blkno = blk;
3633 i = copy_to_user(p, &mt_pos, sizeof(struct mtpos));
3634 if (i)
3635 retval = (-EFAULT);
3636 goto out;
3637 }
Matthias Kaehlcke28f85002007-07-29 23:38:15 +02003638 mutex_unlock(&STp->lock);
Linus Torvalds1da177e2005-04-16 15:20:36 -07003639 switch (cmd_in) {
3640 case SCSI_IOCTL_GET_IDLUN:
3641 case SCSI_IOCTL_GET_BUS_NUMBER:
3642 break;
3643 default:
Kai Makisara 16c4b3e2005-05-01 18:11:55 +03003644 if ((cmd_in == SG_IO ||
3645 cmd_in == SCSI_IOCTL_SEND_COMMAND ||
3646 cmd_in == CDROM_SEND_PACKET) &&
3647 !capable(CAP_SYS_RAWIO))
Linus Torvalds1da177e2005-04-16 15:20:36 -07003648 i = -EPERM;
3649 else
Al Viro74f3c8a2007-08-27 15:38:10 -04003650 i = scsi_cmd_ioctl(STp->disk->queue, STp->disk,
3651 file->f_mode, cmd_in, p);
Linus Torvalds1da177e2005-04-16 15:20:36 -07003652 if (i != -ENOTTY)
3653 return i;
3654 break;
3655 }
Kai Makisara 16c4b3e2005-05-01 18:11:55 +03003656 retval = scsi_ioctl(STp->device, cmd_in, p);
3657 if (!retval && cmd_in == SCSI_IOCTL_STOP_UNIT) { /* unload */
3658 STp->rew_at_close = 0;
3659 STp->ready = ST_NO_TAPE;
3660 }
3661 return retval;
Linus Torvalds1da177e2005-04-16 15:20:36 -07003662
3663 out:
Matthias Kaehlcke28f85002007-07-29 23:38:15 +02003664 mutex_unlock(&STp->lock);
Linus Torvalds1da177e2005-04-16 15:20:36 -07003665 return retval;
3666}
3667
3668#ifdef CONFIG_COMPAT
3669static long st_compat_ioctl(struct file *file, unsigned int cmd, unsigned long arg)
3670{
3671 struct scsi_tape *STp = file->private_data;
3672 struct scsi_device *sdev = STp->device;
3673 int ret = -ENOIOCTLCMD;
3674 if (sdev->host->hostt->compat_ioctl) {
3675
3676 ret = sdev->host->hostt->compat_ioctl(sdev, cmd, (void __user *)arg);
3677
3678 }
3679 return ret;
3680}
3681#endif
3682
3683
3684
3685/* Try to allocate a new tape buffer. Calling function must not hold
3686 dev_arr_lock. */
FUJITA Tomonorif409d6c2008-12-18 14:49:47 +09003687static struct st_buffer *new_tape_buffer(int need_dma, int max_sg)
Linus Torvalds1da177e2005-04-16 15:20:36 -07003688{
Linus Torvalds1da177e2005-04-16 15:20:36 -07003689 struct st_buffer *tb;
3690
FUJITA Tomonorif409d6c2008-12-18 14:49:47 +09003691 tb = kzalloc(sizeof(struct st_buffer), GFP_ATOMIC);
Linus Torvalds1da177e2005-04-16 15:20:36 -07003692 if (!tb) {
3693 printk(KERN_NOTICE "st: Can't allocate new tape buffer.\n");
3694 return NULL;
3695 }
FUJITA Tomonori1ac63cf2008-12-18 14:49:48 +09003696 tb->frp_segs = 0;
Linus Torvalds1da177e2005-04-16 15:20:36 -07003697 tb->use_sg = max_sg;
Linus Torvalds1da177e2005-04-16 15:20:36 -07003698 tb->dma = need_dma;
FUJITA Tomonorif409d6c2008-12-18 14:49:47 +09003699 tb->buffer_size = 0;
Linus Torvalds1da177e2005-04-16 15:20:36 -07003700
FUJITA Tomonorif409d6c2008-12-18 14:49:47 +09003701 tb->reserved_pages = kzalloc(max_sg * sizeof(struct page *),
3702 GFP_ATOMIC);
FUJITA Tomonorid0e1ae32008-12-18 14:49:40 +09003703 if (!tb->reserved_pages) {
3704 kfree(tb);
3705 return NULL;
3706 }
3707
Linus Torvalds1da177e2005-04-16 15:20:36 -07003708 return tb;
3709}
3710
3711
3712/* Try to allocate enough space in the tape buffer */
Kai Makisara8f78fc52008-12-18 14:49:51 +09003713#define ST_MAX_ORDER 6
3714
Linus Torvalds1da177e2005-04-16 15:20:36 -07003715static int enlarge_buffer(struct st_buffer * STbuffer, int new_size, int need_dma)
3716{
Al Viroc53033f2005-10-21 03:22:08 -04003717 int segs, nbr, max_segs, b_size, order, got;
3718 gfp_t priority;
Linus Torvalds1da177e2005-04-16 15:20:36 -07003719
3720 if (new_size <= STbuffer->buffer_size)
3721 return 1;
3722
3723 if (STbuffer->buffer_size <= PAGE_SIZE)
3724 normalize_buffer(STbuffer); /* Avoid extra segment */
3725
3726 max_segs = STbuffer->use_sg;
3727 nbr = max_segs - STbuffer->frp_segs;
3728 if (nbr <= 0)
3729 return 0;
3730
3731 priority = GFP_KERNEL | __GFP_NOWARN;
3732 if (need_dma)
3733 priority |= GFP_DMA;
FUJITA Tomonori9c905962008-12-18 14:49:39 +09003734
FUJITA Tomonori08c95832008-12-18 14:49:45 +09003735 if (STbuffer->cleared)
3736 priority |= __GFP_ZERO;
3737
FUJITA Tomonori9c905962008-12-18 14:49:39 +09003738 if (STbuffer->frp_segs) {
FUJITA Tomonoric982c362009-11-26 09:24:13 +09003739 order = STbuffer->reserved_page_order;
FUJITA Tomonori08c95832008-12-18 14:49:45 +09003740 b_size = PAGE_SIZE << order;
FUJITA Tomonori9c905962008-12-18 14:49:39 +09003741 } else {
3742 for (b_size = PAGE_SIZE, order = 0;
FUJITA Tomonori46081b12010-12-20 18:44:45 +02003743 order < ST_MAX_ORDER &&
3744 max_segs * (PAGE_SIZE << order) < new_size;
Kai Makisara8f78fc52008-12-18 14:49:51 +09003745 order++, b_size *= 2)
FUJITA Tomonori9c905962008-12-18 14:49:39 +09003746 ; /* empty */
Kai Makisara373daac2010-12-20 18:43:39 +02003747 STbuffer->reserved_page_order = order;
FUJITA Tomonori9c905962008-12-18 14:49:39 +09003748 }
Kai Makisara8f78fc52008-12-18 14:49:51 +09003749 if (max_segs * (PAGE_SIZE << order) < new_size) {
3750 if (order == ST_MAX_ORDER)
3751 return 0;
3752 normalize_buffer(STbuffer);
3753 return enlarge_buffer(STbuffer, new_size, need_dma);
3754 }
Linus Torvalds1da177e2005-04-16 15:20:36 -07003755
3756 for (segs = STbuffer->frp_segs, got = STbuffer->buffer_size;
3757 segs < max_segs && got < new_size;) {
FUJITA Tomonori08c95832008-12-18 14:49:45 +09003758 struct page *page;
3759
3760 page = alloc_pages(priority, order);
3761 if (!page) {
Linus Torvalds1da177e2005-04-16 15:20:36 -07003762 DEB(STbuffer->buffer_size = got);
3763 normalize_buffer(STbuffer);
3764 return 0;
3765 }
FUJITA Tomonori08c95832008-12-18 14:49:45 +09003766
Linus Torvalds1da177e2005-04-16 15:20:36 -07003767 STbuffer->frp_segs += 1;
3768 got += b_size;
3769 STbuffer->buffer_size = got;
FUJITA Tomonori08c95832008-12-18 14:49:45 +09003770 STbuffer->reserved_pages[segs] = page;
Linus Torvalds1da177e2005-04-16 15:20:36 -07003771 segs++;
3772 }
FUJITA Tomonori08c95832008-12-18 14:49:45 +09003773 STbuffer->b_data = page_address(STbuffer->reserved_pages[0]);
Linus Torvalds1da177e2005-04-16 15:20:36 -07003774
3775 return 1;
3776}
3777
3778
Kai Makisara40f6b362008-02-24 22:23:24 +02003779/* Make sure that no data from previous user is in the internal buffer */
3780static void clear_buffer(struct st_buffer * st_bp)
3781{
3782 int i;
3783
3784 for (i=0; i < st_bp->frp_segs; i++)
FUJITA Tomonori08c95832008-12-18 14:49:45 +09003785 memset(page_address(st_bp->reserved_pages[i]), 0,
FUJITA Tomonoric982c362009-11-26 09:24:13 +09003786 PAGE_SIZE << st_bp->reserved_page_order);
Kai Makisara40f6b362008-02-24 22:23:24 +02003787 st_bp->cleared = 1;
3788}
3789
3790
Linus Torvalds1da177e2005-04-16 15:20:36 -07003791/* Release the extra buffer */
3792static void normalize_buffer(struct st_buffer * STbuffer)
3793{
FUJITA Tomonoric982c362009-11-26 09:24:13 +09003794 int i, order = STbuffer->reserved_page_order;
Linus Torvalds1da177e2005-04-16 15:20:36 -07003795
FUJITA Tomonori1ac63cf2008-12-18 14:49:48 +09003796 for (i = 0; i < STbuffer->frp_segs; i++) {
FUJITA Tomonori08c95832008-12-18 14:49:45 +09003797 __free_pages(STbuffer->reserved_pages[i], order);
3798 STbuffer->buffer_size -= (PAGE_SIZE << order);
Linus Torvalds1da177e2005-04-16 15:20:36 -07003799 }
FUJITA Tomonori1ac63cf2008-12-18 14:49:48 +09003800 STbuffer->frp_segs = 0;
Mike Christie8b05b772005-11-08 04:06:44 -06003801 STbuffer->sg_segs = 0;
FUJITA Tomonoric982c362009-11-26 09:24:13 +09003802 STbuffer->reserved_page_order = 0;
FUJITA Tomonorid0e1ae32008-12-18 14:49:40 +09003803 STbuffer->map_data.offset = 0;
Linus Torvalds1da177e2005-04-16 15:20:36 -07003804}
3805
3806
3807/* Move data from the user buffer to the tape buffer. Returns zero (success) or
3808 negative error code. */
3809static int append_to_buffer(const char __user *ubp, struct st_buffer * st_bp, int do_count)
3810{
3811 int i, cnt, res, offset;
FUJITA Tomonoric982c362009-11-26 09:24:13 +09003812 int length = PAGE_SIZE << st_bp->reserved_page_order;
Linus Torvalds1da177e2005-04-16 15:20:36 -07003813
3814 for (i = 0, offset = st_bp->buffer_bytes;
FUJITA Tomonori08c95832008-12-18 14:49:45 +09003815 i < st_bp->frp_segs && offset >= length; i++)
3816 offset -= length;
Linus Torvalds1da177e2005-04-16 15:20:36 -07003817 if (i == st_bp->frp_segs) { /* Should never happen */
3818 printk(KERN_WARNING "st: append_to_buffer offset overflow.\n");
3819 return (-EIO);
3820 }
3821 for (; i < st_bp->frp_segs && do_count > 0; i++) {
FUJITA Tomonori08c95832008-12-18 14:49:45 +09003822 struct page *page = st_bp->reserved_pages[i];
3823 cnt = length - offset < do_count ? length - offset : do_count;
3824 res = copy_from_user(page_address(page) + offset, ubp, cnt);
Linus Torvalds1da177e2005-04-16 15:20:36 -07003825 if (res)
3826 return (-EFAULT);
3827 do_count -= cnt;
3828 st_bp->buffer_bytes += cnt;
3829 ubp += cnt;
3830 offset = 0;
3831 }
3832 if (do_count) /* Should never happen */
3833 return (-EIO);
3834
3835 return 0;
3836}
3837
3838
3839/* Move data from the tape buffer to the user buffer. Returns zero (success) or
3840 negative error code. */
3841static int from_buffer(struct st_buffer * st_bp, char __user *ubp, int do_count)
3842{
3843 int i, cnt, res, offset;
FUJITA Tomonoric982c362009-11-26 09:24:13 +09003844 int length = PAGE_SIZE << st_bp->reserved_page_order;
Linus Torvalds1da177e2005-04-16 15:20:36 -07003845
3846 for (i = 0, offset = st_bp->read_pointer;
FUJITA Tomonori08c95832008-12-18 14:49:45 +09003847 i < st_bp->frp_segs && offset >= length; i++)
3848 offset -= length;
Linus Torvalds1da177e2005-04-16 15:20:36 -07003849 if (i == st_bp->frp_segs) { /* Should never happen */
3850 printk(KERN_WARNING "st: from_buffer offset overflow.\n");
3851 return (-EIO);
3852 }
3853 for (; i < st_bp->frp_segs && do_count > 0; i++) {
FUJITA Tomonori08c95832008-12-18 14:49:45 +09003854 struct page *page = st_bp->reserved_pages[i];
3855 cnt = length - offset < do_count ? length - offset : do_count;
3856 res = copy_to_user(ubp, page_address(page) + offset, cnt);
Linus Torvalds1da177e2005-04-16 15:20:36 -07003857 if (res)
3858 return (-EFAULT);
3859 do_count -= cnt;
3860 st_bp->buffer_bytes -= cnt;
3861 st_bp->read_pointer += cnt;
3862 ubp += cnt;
3863 offset = 0;
3864 }
3865 if (do_count) /* Should never happen */
3866 return (-EIO);
3867
3868 return 0;
3869}
3870
3871
3872/* Move data towards start of buffer */
3873static void move_buffer_data(struct st_buffer * st_bp, int offset)
3874{
3875 int src_seg, dst_seg, src_offset = 0, dst_offset;
3876 int count, total;
FUJITA Tomonoric982c362009-11-26 09:24:13 +09003877 int length = PAGE_SIZE << st_bp->reserved_page_order;
Linus Torvalds1da177e2005-04-16 15:20:36 -07003878
3879 if (offset == 0)
3880 return;
3881
3882 total=st_bp->buffer_bytes - offset;
3883 for (src_seg=0; src_seg < st_bp->frp_segs; src_seg++) {
3884 src_offset = offset;
FUJITA Tomonori08c95832008-12-18 14:49:45 +09003885 if (src_offset < length)
Linus Torvalds1da177e2005-04-16 15:20:36 -07003886 break;
FUJITA Tomonori08c95832008-12-18 14:49:45 +09003887 offset -= length;
Linus Torvalds1da177e2005-04-16 15:20:36 -07003888 }
3889
3890 st_bp->buffer_bytes = st_bp->read_pointer = total;
3891 for (dst_seg=dst_offset=0; total > 0; ) {
FUJITA Tomonori08c95832008-12-18 14:49:45 +09003892 struct page *dpage = st_bp->reserved_pages[dst_seg];
3893 struct page *spage = st_bp->reserved_pages[src_seg];
3894
3895 count = min(length - dst_offset, length - src_offset);
3896 memmove(page_address(dpage) + dst_offset,
3897 page_address(spage) + src_offset, count);
Linus Torvalds1da177e2005-04-16 15:20:36 -07003898 src_offset += count;
FUJITA Tomonori08c95832008-12-18 14:49:45 +09003899 if (src_offset >= length) {
Linus Torvalds1da177e2005-04-16 15:20:36 -07003900 src_seg++;
3901 src_offset = 0;
3902 }
3903 dst_offset += count;
FUJITA Tomonori08c95832008-12-18 14:49:45 +09003904 if (dst_offset >= length) {
Linus Torvalds1da177e2005-04-16 15:20:36 -07003905 dst_seg++;
3906 dst_offset = 0;
3907 }
3908 total -= count;
3909 }
3910}
3911
Linus Torvalds1da177e2005-04-16 15:20:36 -07003912/* Validate the options from command line or module parameters */
3913static void validate_options(void)
3914{
3915 if (buffer_kbs > 0)
3916 st_fixed_buffer_size = buffer_kbs * ST_KILOBYTE;
3917 if (max_sg_segs >= ST_FIRST_SG)
3918 st_max_sg_segs = max_sg_segs;
3919}
3920
3921#ifndef MODULE
3922/* Set the boot options. Syntax is defined in Documenation/scsi/st.txt.
3923 */
3924static int __init st_setup(char *str)
3925{
3926 int i, len, ints[5];
3927 char *stp;
3928
3929 stp = get_options(str, ARRAY_SIZE(ints), ints);
3930
3931 if (ints[0] > 0) {
3932 for (i = 0; i < ints[0] && i < ARRAY_SIZE(parms); i++)
3933 if (parms[i].val)
3934 *parms[i].val = ints[i + 1];
3935 } else {
3936 while (stp != NULL) {
3937 for (i = 0; i < ARRAY_SIZE(parms); i++) {
3938 len = strlen(parms[i].name);
3939 if (!strncmp(stp, parms[i].name, len) &&
3940 (*(stp + len) == ':' || *(stp + len) == '=')) {
3941 if (parms[i].val)
3942 *parms[i].val =
3943 simple_strtoul(stp + len + 1, NULL, 0);
3944 else
3945 printk(KERN_WARNING "st: Obsolete parameter %s\n",
3946 parms[i].name);
3947 break;
3948 }
3949 }
Tobias Klauser6391a112006-06-08 22:23:48 -07003950 if (i >= ARRAY_SIZE(parms))
Linus Torvalds1da177e2005-04-16 15:20:36 -07003951 printk(KERN_WARNING "st: invalid parameter in '%s'\n",
3952 stp);
3953 stp = strchr(stp, ',');
3954 if (stp)
3955 stp++;
3956 }
3957 }
3958
3959 validate_options();
3960
3961 return 1;
3962}
3963
3964__setup("st=", st_setup);
3965
3966#endif
3967
Arjan van de Ven00977a52007-02-12 00:55:34 -08003968static const struct file_operations st_fops =
Linus Torvalds1da177e2005-04-16 15:20:36 -07003969{
3970 .owner = THIS_MODULE,
3971 .read = st_read,
3972 .write = st_write,
Kai Makisarafd66c1b2008-01-17 22:45:22 +02003973 .unlocked_ioctl = st_ioctl,
Linus Torvalds1da177e2005-04-16 15:20:36 -07003974#ifdef CONFIG_COMPAT
3975 .compat_ioctl = st_compat_ioctl,
3976#endif
3977 .open = st_open,
3978 .flush = st_flush,
3979 .release = st_release,
Jan Blunckb4d878e2010-05-26 14:44:51 -07003980 .llseek = noop_llseek,
Linus Torvalds1da177e2005-04-16 15:20:36 -07003981};
3982
3983static int st_probe(struct device *dev)
3984{
3985 struct scsi_device *SDp = to_scsi_device(dev);
3986 struct gendisk *disk = NULL;
3987 struct cdev *cdev = NULL;
3988 struct scsi_tape *tpnt = NULL;
3989 struct st_modedef *STm;
3990 struct st_partstat *STps;
3991 struct st_buffer *buffer;
3992 int i, j, mode, dev_num, error;
3993 char *stp;
Linus Torvalds1da177e2005-04-16 15:20:36 -07003994
3995 if (SDp->type != TYPE_TAPE)
3996 return -ENODEV;
3997 if ((stp = st_incompatible(SDp))) {
Jeff Garzik3bf743e2005-10-24 18:04:06 -04003998 sdev_printk(KERN_INFO, SDp, "Found incompatible tape\n");
Linus Torvalds1da177e2005-04-16 15:20:36 -07003999 printk(KERN_INFO "st: The suggested driver is %s.\n", stp);
4000 return -ENODEV;
4001 }
4002
Martin K. Petersen8a783622010-02-26 00:20:39 -05004003 i = queue_max_segments(SDp->request_queue);
Linus Torvalds1da177e2005-04-16 15:20:36 -07004004 if (st_max_sg_segs < i)
4005 i = st_max_sg_segs;
FUJITA Tomonorif409d6c2008-12-18 14:49:47 +09004006 buffer = new_tape_buffer((SDp->host)->unchecked_isa_dma, i);
Linus Torvalds1da177e2005-04-16 15:20:36 -07004007 if (buffer == NULL) {
4008 printk(KERN_ERR
4009 "st: Can't allocate new tape buffer. Device not attached.\n");
4010 goto out;
4011 }
4012
4013 disk = alloc_disk(1);
4014 if (!disk) {
4015 printk(KERN_ERR "st: out of memory. Device not attached.\n");
4016 goto out_buffer_free;
4017 }
4018
4019 write_lock(&st_dev_arr_lock);
4020 if (st_nr_dev >= st_dev_max) {
4021 struct scsi_tape **tmp_da;
4022 int tmp_dev_max;
4023
4024 tmp_dev_max = max(st_nr_dev * 2, 8);
4025 if (tmp_dev_max > ST_MAX_TAPES)
4026 tmp_dev_max = ST_MAX_TAPES;
4027 if (tmp_dev_max <= st_nr_dev) {
4028 write_unlock(&st_dev_arr_lock);
4029 printk(KERN_ERR "st: Too many tape devices (max. %d).\n",
4030 ST_MAX_TAPES);
4031 goto out_put_disk;
4032 }
4033
Jes Sorensen24669f752006-01-16 10:31:18 -05004034 tmp_da = kzalloc(tmp_dev_max * sizeof(struct scsi_tape *), GFP_ATOMIC);
Linus Torvalds1da177e2005-04-16 15:20:36 -07004035 if (tmp_da == NULL) {
4036 write_unlock(&st_dev_arr_lock);
4037 printk(KERN_ERR "st: Can't extend device array.\n");
4038 goto out_put_disk;
4039 }
4040
Linus Torvalds1da177e2005-04-16 15:20:36 -07004041 if (scsi_tapes != NULL) {
4042 memcpy(tmp_da, scsi_tapes,
4043 st_dev_max * sizeof(struct scsi_tape *));
4044 kfree(scsi_tapes);
4045 }
4046 scsi_tapes = tmp_da;
4047
4048 st_dev_max = tmp_dev_max;
4049 }
4050
4051 for (i = 0; i < st_dev_max; i++)
4052 if (scsi_tapes[i] == NULL)
4053 break;
4054 if (i >= st_dev_max)
4055 panic("scsi_devices corrupt (st)");
4056
Jes Sorensen24669f752006-01-16 10:31:18 -05004057 tpnt = kzalloc(sizeof(struct scsi_tape), GFP_ATOMIC);
Linus Torvalds1da177e2005-04-16 15:20:36 -07004058 if (tpnt == NULL) {
4059 write_unlock(&st_dev_arr_lock);
4060 printk(KERN_ERR "st: Can't allocate device descriptor.\n");
4061 goto out_put_disk;
4062 }
Kai Makisaraf03a5672005-08-02 13:40:47 +03004063 kref_init(&tpnt->kref);
Linus Torvalds1da177e2005-04-16 15:20:36 -07004064 tpnt->disk = disk;
4065 sprintf(disk->disk_name, "st%d", i);
4066 disk->private_data = &tpnt->driver;
4067 disk->queue = SDp->request_queue;
4068 tpnt->driver = &st_template;
4069 scsi_tapes[i] = tpnt;
4070 dev_num = i;
4071
4072 tpnt->device = SDp;
4073 if (SDp->scsi_level <= 2)
4074 tpnt->tape_type = MT_ISSCSI1;
4075 else
4076 tpnt->tape_type = MT_ISSCSI2;
4077
4078 tpnt->buffer = buffer;
Kai Makisaraf03a5672005-08-02 13:40:47 +03004079 tpnt->buffer->last_SRpnt = NULL;
Linus Torvalds1da177e2005-04-16 15:20:36 -07004080
4081 tpnt->inited = 0;
4082 tpnt->dirty = 0;
4083 tpnt->in_use = 0;
4084 tpnt->drv_buffer = 1; /* Try buffering if no mode sense */
4085 tpnt->restr_dma = (SDp->host)->unchecked_isa_dma;
4086 tpnt->use_pf = (SDp->scsi_level >= SCSI_2);
4087 tpnt->density = 0;
4088 tpnt->do_auto_lock = ST_AUTO_LOCK;
4089 tpnt->can_bsr = (SDp->scsi_level > 2 ? 1 : ST_IN_FILE_POS); /* BSR mandatory in SCSI3 */
4090 tpnt->can_partitions = 0;
4091 tpnt->two_fm = ST_TWO_FM;
4092 tpnt->fast_mteom = ST_FAST_MTEOM;
4093 tpnt->scsi2_logical = ST_SCSI2LOGICAL;
Kai Makisara40f6b362008-02-24 22:23:24 +02004094 tpnt->sili = ST_SILI;
Linus Torvalds1da177e2005-04-16 15:20:36 -07004095 tpnt->immediate = ST_NOWAIT;
4096 tpnt->default_drvbuffer = 0xff; /* No forced buffering */
4097 tpnt->partition = 0;
4098 tpnt->new_partition = 0;
4099 tpnt->nbr_partitions = 0;
James Bottomleya02488e2008-11-30 10:36:26 -06004100 blk_queue_rq_timeout(tpnt->device->request_queue, ST_TIMEOUT);
Linus Torvalds1da177e2005-04-16 15:20:36 -07004101 tpnt->long_timeout = ST_LONG_TIMEOUT;
4102 tpnt->try_dio = try_direct_io && !SDp->host->unchecked_isa_dma;
4103
Linus Torvalds1da177e2005-04-16 15:20:36 -07004104 for (i = 0; i < ST_NBR_MODES; i++) {
4105 STm = &(tpnt->modes[i]);
4106 STm->defined = 0;
4107 STm->sysv = ST_SYSV;
4108 STm->defaults_for_writes = 0;
4109 STm->do_async_writes = ST_ASYNC_WRITES;
4110 STm->do_buffer_writes = ST_BUFFER_WRITES;
4111 STm->do_read_ahead = ST_READ_AHEAD;
4112 STm->default_compression = ST_DONT_TOUCH;
4113 STm->default_blksize = (-1); /* No forced size */
4114 STm->default_density = (-1); /* No forced density */
4115 }
4116
4117 for (i = 0; i < ST_NBR_PARTITIONS; i++) {
4118 STps = &(tpnt->ps[i]);
4119 STps->rw = ST_IDLE;
4120 STps->eof = ST_NOEOF;
4121 STps->at_sm = 0;
4122 STps->last_block_valid = 0;
4123 STps->drv_block = (-1);
4124 STps->drv_file = (-1);
4125 }
4126
4127 tpnt->current_mode = 0;
4128 tpnt->modes[0].defined = 1;
4129
4130 tpnt->density_changed = tpnt->compression_changed =
4131 tpnt->blksize_changed = 0;
Matthias Kaehlcke28f85002007-07-29 23:38:15 +02004132 mutex_init(&tpnt->lock);
Linus Torvalds1da177e2005-04-16 15:20:36 -07004133
4134 st_nr_dev++;
4135 write_unlock(&st_dev_arr_lock);
4136
4137 for (mode = 0; mode < ST_NBR_MODES; ++mode) {
4138 STm = &(tpnt->modes[mode]);
4139 for (j=0; j < 2; j++) {
4140 cdev = cdev_alloc();
4141 if (!cdev) {
4142 printk(KERN_ERR
4143 "st%d: out of memory. Device not attached.\n",
4144 dev_num);
4145 goto out_free_tape;
4146 }
4147 cdev->owner = THIS_MODULE;
4148 cdev->ops = &st_fops;
4149
4150 error = cdev_add(cdev,
4151 MKDEV(SCSI_TAPE_MAJOR, TAPE_MINOR(dev_num, mode, j)),
4152 1);
4153 if (error) {
4154 printk(KERN_ERR "st%d: Can't add %s-rewind mode %d\n",
4155 dev_num, j ? "non" : "auto", mode);
4156 printk(KERN_ERR "st%d: Device not attached.\n", dev_num);
4157 goto out_free_tape;
4158 }
4159 STm->cdevs[j] = cdev;
4160
4161 }
Jeff Garzik13026a62006-10-04 06:00:38 -04004162 error = do_create_class_files(tpnt, dev_num, mode);
4163 if (error)
4164 goto out_free_tape;
Linus Torvalds1da177e2005-04-16 15:20:36 -07004165 }
Oliver Neukum46a243f2012-01-15 00:16:51 +01004166 scsi_autopm_put_device(SDp);
Linus Torvalds1da177e2005-04-16 15:20:36 -07004167
Kai Makisara42252852006-11-07 21:56:38 +02004168 sdev_printk(KERN_NOTICE, SDp,
Rene Herman8b1ea242006-05-20 15:00:22 -07004169 "Attached scsi tape %s\n", tape_name(tpnt));
Kai Makisara42252852006-11-07 21:56:38 +02004170 sdev_printk(KERN_INFO, SDp, "%s: try direct i/o: %s (alignment %d B)\n",
4171 tape_name(tpnt), tpnt->try_dio ? "yes" : "no",
4172 queue_dma_alignment(SDp->request_queue) + 1);
Linus Torvalds1da177e2005-04-16 15:20:36 -07004173
4174 return 0;
4175
4176out_free_tape:
4177 for (mode=0; mode < ST_NBR_MODES; mode++) {
4178 STm = &(tpnt->modes[mode]);
4179 sysfs_remove_link(&tpnt->device->sdev_gendev.kobj,
4180 "tape");
4181 for (j=0; j < 2; j++) {
4182 if (STm->cdevs[j]) {
4183 if (cdev == STm->cdevs[j])
4184 cdev = NULL;
Tony Jonesee959b02008-02-22 00:13:36 +01004185 device_destroy(st_sysfs_class,
4186 MKDEV(SCSI_TAPE_MAJOR,
4187 TAPE_MINOR(i, mode, j)));
Linus Torvalds1da177e2005-04-16 15:20:36 -07004188 cdev_del(STm->cdevs[j]);
4189 }
4190 }
4191 }
4192 if (cdev)
4193 cdev_del(cdev);
4194 write_lock(&st_dev_arr_lock);
4195 scsi_tapes[dev_num] = NULL;
4196 st_nr_dev--;
4197 write_unlock(&st_dev_arr_lock);
4198out_put_disk:
4199 put_disk(disk);
Jesper Juhlc9475cb2005-11-07 01:01:26 -08004200 kfree(tpnt);
Linus Torvalds1da177e2005-04-16 15:20:36 -07004201out_buffer_free:
4202 kfree(buffer);
4203out:
4204 return -ENODEV;
4205};
4206
4207
4208static int st_remove(struct device *dev)
4209{
4210 struct scsi_device *SDp = to_scsi_device(dev);
4211 struct scsi_tape *tpnt;
4212 int i, j, mode;
4213
Oliver Neukum46a243f2012-01-15 00:16:51 +01004214 scsi_autopm_get_device(SDp);
Linus Torvalds1da177e2005-04-16 15:20:36 -07004215 write_lock(&st_dev_arr_lock);
4216 for (i = 0; i < st_dev_max; i++) {
4217 tpnt = scsi_tapes[i];
4218 if (tpnt != NULL && tpnt->device == SDp) {
4219 scsi_tapes[i] = NULL;
4220 st_nr_dev--;
4221 write_unlock(&st_dev_arr_lock);
Linus Torvalds1da177e2005-04-16 15:20:36 -07004222 sysfs_remove_link(&tpnt->device->sdev_gendev.kobj,
4223 "tape");
4224 for (mode = 0; mode < ST_NBR_MODES; ++mode) {
Linus Torvalds1da177e2005-04-16 15:20:36 -07004225 for (j=0; j < 2; j++) {
Tony Jonesee959b02008-02-22 00:13:36 +01004226 device_destroy(st_sysfs_class,
4227 MKDEV(SCSI_TAPE_MAJOR,
4228 TAPE_MINOR(i, mode, j)));
Linus Torvalds1da177e2005-04-16 15:20:36 -07004229 cdev_del(tpnt->modes[mode].cdevs[j]);
4230 tpnt->modes[mode].cdevs[j] = NULL;
4231 }
4232 }
Linus Torvalds1da177e2005-04-16 15:20:36 -07004233
Arjan van de Ven0b950672006-01-11 13:16:10 +01004234 mutex_lock(&st_ref_mutex);
Kai Makisaraf03a5672005-08-02 13:40:47 +03004235 kref_put(&tpnt->kref, scsi_tape_release);
Arjan van de Ven0b950672006-01-11 13:16:10 +01004236 mutex_unlock(&st_ref_mutex);
Linus Torvalds1da177e2005-04-16 15:20:36 -07004237 return 0;
4238 }
4239 }
4240
4241 write_unlock(&st_dev_arr_lock);
4242 return 0;
4243}
4244
Kai Makisaraf03a5672005-08-02 13:40:47 +03004245/**
4246 * scsi_tape_release - Called to free the Scsi_Tape structure
4247 * @kref: pointer to embedded kref
4248 *
Arjan van de Ven0b950672006-01-11 13:16:10 +01004249 * st_ref_mutex must be held entering this routine. Because it is
Kai Makisaraf03a5672005-08-02 13:40:47 +03004250 * called on last put, you should always use the scsi_tape_get()
4251 * scsi_tape_put() helpers which manipulate the semaphore directly
4252 * and never do a direct kref_put().
4253 **/
4254static void scsi_tape_release(struct kref *kref)
4255{
4256 struct scsi_tape *tpnt = to_scsi_tape(kref);
4257 struct gendisk *disk = tpnt->disk;
4258
4259 tpnt->device = NULL;
4260
4261 if (tpnt->buffer) {
Kai Makisaraf03a5672005-08-02 13:40:47 +03004262 normalize_buffer(tpnt->buffer);
FUJITA Tomonorid0e1ae32008-12-18 14:49:40 +09004263 kfree(tpnt->buffer->reserved_pages);
Kai Makisaraf03a5672005-08-02 13:40:47 +03004264 kfree(tpnt->buffer);
4265 }
4266
4267 disk->private_data = NULL;
4268 put_disk(disk);
4269 kfree(tpnt);
4270 return;
4271}
4272
Linus Torvalds1da177e2005-04-16 15:20:36 -07004273static int __init init_st(void)
4274{
Jeff Garzik13026a62006-10-04 06:00:38 -04004275 int err;
4276
Linus Torvalds1da177e2005-04-16 15:20:36 -07004277 validate_options();
4278
Jeff Garzik13026a62006-10-04 06:00:38 -04004279 printk(KERN_INFO "st: Version %s, fixed bufsize %d, s/g segs %d\n",
Linus Torvalds1da177e2005-04-16 15:20:36 -07004280 verstr, st_fixed_buffer_size, st_max_sg_segs);
4281
gregkh@suse.ded2538782005-03-23 09:55:22 -08004282 st_sysfs_class = class_create(THIS_MODULE, "scsi_tape");
Linus Torvalds1da177e2005-04-16 15:20:36 -07004283 if (IS_ERR(st_sysfs_class)) {
Linus Torvalds1da177e2005-04-16 15:20:36 -07004284 printk(KERN_ERR "Unable create sysfs class for SCSI tapes\n");
Jeff Garzik13026a62006-10-04 06:00:38 -04004285 return PTR_ERR(st_sysfs_class);
Linus Torvalds1da177e2005-04-16 15:20:36 -07004286 }
4287
Jeff Garzik13026a62006-10-04 06:00:38 -04004288 err = register_chrdev_region(MKDEV(SCSI_TAPE_MAJOR, 0),
4289 ST_MAX_TAPE_ENTRIES, "st");
4290 if (err) {
4291 printk(KERN_ERR "Unable to get major %d for SCSI tapes\n",
4292 SCSI_TAPE_MAJOR);
4293 goto err_class;
Linus Torvalds1da177e2005-04-16 15:20:36 -07004294 }
Jeff Garzik13026a62006-10-04 06:00:38 -04004295
4296 err = scsi_register_driver(&st_template.gendrv);
4297 if (err)
4298 goto err_chrdev;
4299
Robert P. J. Day405ae7d2007-02-17 19:13:42 +01004300 err = do_create_sysfs_files();
Jeff Garzik13026a62006-10-04 06:00:38 -04004301 if (err)
4302 goto err_scsidrv;
4303
4304 return 0;
4305
4306err_scsidrv:
4307 scsi_unregister_driver(&st_template.gendrv);
4308err_chrdev:
4309 unregister_chrdev_region(MKDEV(SCSI_TAPE_MAJOR, 0),
4310 ST_MAX_TAPE_ENTRIES);
4311err_class:
Kai Makisarac2c96f42005-08-02 12:21:51 +03004312 class_destroy(st_sysfs_class);
Jeff Garzik13026a62006-10-04 06:00:38 -04004313 return err;
Linus Torvalds1da177e2005-04-16 15:20:36 -07004314}
4315
4316static void __exit exit_st(void)
4317{
Robert P. J. Day405ae7d2007-02-17 19:13:42 +01004318 do_remove_sysfs_files();
Linus Torvalds1da177e2005-04-16 15:20:36 -07004319 scsi_unregister_driver(&st_template.gendrv);
4320 unregister_chrdev_region(MKDEV(SCSI_TAPE_MAJOR, 0),
4321 ST_MAX_TAPE_ENTRIES);
Kai Makisarac2c96f42005-08-02 12:21:51 +03004322 class_destroy(st_sysfs_class);
Linus Torvalds1da177e2005-04-16 15:20:36 -07004323 kfree(scsi_tapes);
4324 printk(KERN_INFO "st: Unloaded.\n");
4325}
4326
4327module_init(init_st);
4328module_exit(exit_st);
4329
4330
4331/* The sysfs driver interface. Read-only at the moment */
4332static ssize_t st_try_direct_io_show(struct device_driver *ddp, char *buf)
4333{
4334 return snprintf(buf, PAGE_SIZE, "%d\n", try_direct_io);
4335}
4336static DRIVER_ATTR(try_direct_io, S_IRUGO, st_try_direct_io_show, NULL);
4337
4338static ssize_t st_fixed_buffer_size_show(struct device_driver *ddp, char *buf)
4339{
4340 return snprintf(buf, PAGE_SIZE, "%d\n", st_fixed_buffer_size);
4341}
4342static DRIVER_ATTR(fixed_buffer_size, S_IRUGO, st_fixed_buffer_size_show, NULL);
4343
4344static ssize_t st_max_sg_segs_show(struct device_driver *ddp, char *buf)
4345{
4346 return snprintf(buf, PAGE_SIZE, "%d\n", st_max_sg_segs);
4347}
4348static DRIVER_ATTR(max_sg_segs, S_IRUGO, st_max_sg_segs_show, NULL);
4349
4350static ssize_t st_version_show(struct device_driver *ddd, char *buf)
4351{
4352 return snprintf(buf, PAGE_SIZE, "[%s]\n", verstr);
4353}
4354static DRIVER_ATTR(version, S_IRUGO, st_version_show, NULL);
4355
Robert P. J. Day405ae7d2007-02-17 19:13:42 +01004356static int do_create_sysfs_files(void)
Linus Torvalds1da177e2005-04-16 15:20:36 -07004357{
Robert P. J. Day405ae7d2007-02-17 19:13:42 +01004358 struct device_driver *sysfs = &st_template.gendrv;
Jeff Garzik13026a62006-10-04 06:00:38 -04004359 int err;
Linus Torvalds1da177e2005-04-16 15:20:36 -07004360
Robert P. J. Day405ae7d2007-02-17 19:13:42 +01004361 err = driver_create_file(sysfs, &driver_attr_try_direct_io);
Jeff Garzik13026a62006-10-04 06:00:38 -04004362 if (err)
4363 return err;
Robert P. J. Day405ae7d2007-02-17 19:13:42 +01004364 err = driver_create_file(sysfs, &driver_attr_fixed_buffer_size);
Jeff Garzik13026a62006-10-04 06:00:38 -04004365 if (err)
4366 goto err_try_direct_io;
Robert P. J. Day405ae7d2007-02-17 19:13:42 +01004367 err = driver_create_file(sysfs, &driver_attr_max_sg_segs);
Jeff Garzik13026a62006-10-04 06:00:38 -04004368 if (err)
4369 goto err_attr_fixed_buf;
Robert P. J. Day405ae7d2007-02-17 19:13:42 +01004370 err = driver_create_file(sysfs, &driver_attr_version);
Jeff Garzik13026a62006-10-04 06:00:38 -04004371 if (err)
4372 goto err_attr_max_sg;
4373
4374 return 0;
4375
4376err_attr_max_sg:
Robert P. J. Day405ae7d2007-02-17 19:13:42 +01004377 driver_remove_file(sysfs, &driver_attr_max_sg_segs);
Jeff Garzik13026a62006-10-04 06:00:38 -04004378err_attr_fixed_buf:
Robert P. J. Day405ae7d2007-02-17 19:13:42 +01004379 driver_remove_file(sysfs, &driver_attr_fixed_buffer_size);
Jeff Garzik13026a62006-10-04 06:00:38 -04004380err_try_direct_io:
Robert P. J. Day405ae7d2007-02-17 19:13:42 +01004381 driver_remove_file(sysfs, &driver_attr_try_direct_io);
Jeff Garzik13026a62006-10-04 06:00:38 -04004382 return err;
Linus Torvalds1da177e2005-04-16 15:20:36 -07004383}
4384
Robert P. J. Day405ae7d2007-02-17 19:13:42 +01004385static void do_remove_sysfs_files(void)
Linus Torvalds1da177e2005-04-16 15:20:36 -07004386{
Robert P. J. Day405ae7d2007-02-17 19:13:42 +01004387 struct device_driver *sysfs = &st_template.gendrv;
Linus Torvalds1da177e2005-04-16 15:20:36 -07004388
Robert P. J. Day405ae7d2007-02-17 19:13:42 +01004389 driver_remove_file(sysfs, &driver_attr_version);
4390 driver_remove_file(sysfs, &driver_attr_max_sg_segs);
4391 driver_remove_file(sysfs, &driver_attr_fixed_buffer_size);
4392 driver_remove_file(sysfs, &driver_attr_try_direct_io);
Linus Torvalds1da177e2005-04-16 15:20:36 -07004393}
4394
4395
4396/* The sysfs simple class interface */
Tony Jonesee959b02008-02-22 00:13:36 +01004397static ssize_t
4398st_defined_show(struct device *dev, struct device_attribute *attr, char *buf)
Linus Torvalds1da177e2005-04-16 15:20:36 -07004399{
James Bottomley7d15d6a2008-03-14 14:12:43 -07004400 struct st_modedef *STm = dev_get_drvdata(dev);
Linus Torvalds1da177e2005-04-16 15:20:36 -07004401 ssize_t l = 0;
4402
4403 l = snprintf(buf, PAGE_SIZE, "%d\n", STm->defined);
4404 return l;
4405}
4406
Tony Jonesee959b02008-02-22 00:13:36 +01004407DEVICE_ATTR(defined, S_IRUGO, st_defined_show, NULL);
Linus Torvalds1da177e2005-04-16 15:20:36 -07004408
Tony Jonesee959b02008-02-22 00:13:36 +01004409static ssize_t
4410st_defblk_show(struct device *dev, struct device_attribute *attr, char *buf)
Linus Torvalds1da177e2005-04-16 15:20:36 -07004411{
James Bottomley7d15d6a2008-03-14 14:12:43 -07004412 struct st_modedef *STm = dev_get_drvdata(dev);
Linus Torvalds1da177e2005-04-16 15:20:36 -07004413 ssize_t l = 0;
4414
4415 l = snprintf(buf, PAGE_SIZE, "%d\n", STm->default_blksize);
4416 return l;
4417}
4418
Tony Jonesee959b02008-02-22 00:13:36 +01004419DEVICE_ATTR(default_blksize, S_IRUGO, st_defblk_show, NULL);
Linus Torvalds1da177e2005-04-16 15:20:36 -07004420
Tony Jonesee959b02008-02-22 00:13:36 +01004421static ssize_t
4422st_defdensity_show(struct device *dev, struct device_attribute *attr, char *buf)
Linus Torvalds1da177e2005-04-16 15:20:36 -07004423{
James Bottomley7d15d6a2008-03-14 14:12:43 -07004424 struct st_modedef *STm = dev_get_drvdata(dev);
Linus Torvalds1da177e2005-04-16 15:20:36 -07004425 ssize_t l = 0;
4426 char *fmt;
4427
4428 fmt = STm->default_density >= 0 ? "0x%02x\n" : "%d\n";
4429 l = snprintf(buf, PAGE_SIZE, fmt, STm->default_density);
4430 return l;
4431}
4432
Tony Jonesee959b02008-02-22 00:13:36 +01004433DEVICE_ATTR(default_density, S_IRUGO, st_defdensity_show, NULL);
Linus Torvalds1da177e2005-04-16 15:20:36 -07004434
Tony Jonesee959b02008-02-22 00:13:36 +01004435static ssize_t
4436st_defcompression_show(struct device *dev, struct device_attribute *attr,
4437 char *buf)
Linus Torvalds1da177e2005-04-16 15:20:36 -07004438{
James Bottomley7d15d6a2008-03-14 14:12:43 -07004439 struct st_modedef *STm = dev_get_drvdata(dev);
Linus Torvalds1da177e2005-04-16 15:20:36 -07004440 ssize_t l = 0;
4441
4442 l = snprintf(buf, PAGE_SIZE, "%d\n", STm->default_compression - 1);
4443 return l;
4444}
4445
Tony Jonesee959b02008-02-22 00:13:36 +01004446DEVICE_ATTR(default_compression, S_IRUGO, st_defcompression_show, NULL);
Linus Torvalds1da177e2005-04-16 15:20:36 -07004447
Tony Jonesee959b02008-02-22 00:13:36 +01004448static ssize_t
4449st_options_show(struct device *dev, struct device_attribute *attr, char *buf)
Kai Makisarab174be02008-02-24 22:29:12 +02004450{
James Bottomley7d15d6a2008-03-14 14:12:43 -07004451 struct st_modedef *STm = dev_get_drvdata(dev);
Kai Makisarab174be02008-02-24 22:29:12 +02004452 struct scsi_tape *STp;
4453 int i, j, options;
4454 ssize_t l = 0;
4455
4456 for (i=0; i < st_dev_max; i++) {
4457 for (j=0; j < ST_NBR_MODES; j++)
4458 if (&scsi_tapes[i]->modes[j] == STm)
4459 break;
4460 if (j < ST_NBR_MODES)
4461 break;
4462 }
4463 if (i == st_dev_max)
4464 return 0; /* should never happen */
4465
4466 STp = scsi_tapes[i];
4467
4468 options = STm->do_buffer_writes ? MT_ST_BUFFER_WRITES : 0;
4469 options |= STm->do_async_writes ? MT_ST_ASYNC_WRITES : 0;
4470 options |= STm->do_read_ahead ? MT_ST_READ_AHEAD : 0;
4471 DEB( options |= debugging ? MT_ST_DEBUGGING : 0 );
4472 options |= STp->two_fm ? MT_ST_TWO_FM : 0;
4473 options |= STp->fast_mteom ? MT_ST_FAST_MTEOM : 0;
4474 options |= STm->defaults_for_writes ? MT_ST_DEF_WRITES : 0;
4475 options |= STp->can_bsr ? MT_ST_CAN_BSR : 0;
4476 options |= STp->omit_blklims ? MT_ST_NO_BLKLIMS : 0;
4477 options |= STp->can_partitions ? MT_ST_CAN_PARTITIONS : 0;
4478 options |= STp->scsi2_logical ? MT_ST_SCSI2LOGICAL : 0;
4479 options |= STm->sysv ? MT_ST_SYSV : 0;
4480 options |= STp->immediate ? MT_ST_NOWAIT : 0;
4481 options |= STp->sili ? MT_ST_SILI : 0;
4482
4483 l = snprintf(buf, PAGE_SIZE, "0x%08x\n", options);
4484 return l;
4485}
4486
Tony Jonesee959b02008-02-22 00:13:36 +01004487DEVICE_ATTR(options, S_IRUGO, st_options_show, NULL);
Kai Makisarab174be02008-02-24 22:29:12 +02004488
Jeff Garzik13026a62006-10-04 06:00:38 -04004489static int do_create_class_files(struct scsi_tape *STp, int dev_num, int mode)
Linus Torvalds1da177e2005-04-16 15:20:36 -07004490{
4491 int i, rew, error;
4492 char name[10];
Tony Jonesee959b02008-02-22 00:13:36 +01004493 struct device *st_class_member;
Linus Torvalds1da177e2005-04-16 15:20:36 -07004494
Linus Torvalds1da177e2005-04-16 15:20:36 -07004495 for (rew=0; rew < 2; rew++) {
4496 /* Make sure that the minor numbers corresponding to the four
4497 first modes always get the same names */
4498 i = mode << (4 - ST_NBR_MODE_BITS);
4499 snprintf(name, 10, "%s%s%s", rew ? "n" : "",
4500 STp->disk->disk_name, st_formats[i]);
4501 st_class_member =
Greg Kroah-Hartmand73a1a62008-07-21 20:03:34 -07004502 device_create(st_sysfs_class, &STp->device->sdev_gendev,
4503 MKDEV(SCSI_TAPE_MAJOR,
4504 TAPE_MINOR(dev_num, mode, rew)),
4505 &STp->modes[mode], "%s", name);
Linus Torvalds1da177e2005-04-16 15:20:36 -07004506 if (IS_ERR(st_class_member)) {
Tony Jonesee959b02008-02-22 00:13:36 +01004507 printk(KERN_WARNING "st%d: device_create failed\n",
Linus Torvalds1da177e2005-04-16 15:20:36 -07004508 dev_num);
Jeff Garzik13026a62006-10-04 06:00:38 -04004509 error = PTR_ERR(st_class_member);
Linus Torvalds1da177e2005-04-16 15:20:36 -07004510 goto out;
4511 }
Linus Torvalds1da177e2005-04-16 15:20:36 -07004512
Tony Jonesee959b02008-02-22 00:13:36 +01004513 error = device_create_file(st_class_member,
4514 &dev_attr_defined);
Jeff Garzik13026a62006-10-04 06:00:38 -04004515 if (error) goto out;
Tony Jonesee959b02008-02-22 00:13:36 +01004516 error = device_create_file(st_class_member,
4517 &dev_attr_default_blksize);
Jeff Garzik13026a62006-10-04 06:00:38 -04004518 if (error) goto out;
Tony Jonesee959b02008-02-22 00:13:36 +01004519 error = device_create_file(st_class_member,
4520 &dev_attr_default_density);
Jeff Garzik13026a62006-10-04 06:00:38 -04004521 if (error) goto out;
Tony Jonesee959b02008-02-22 00:13:36 +01004522 error = device_create_file(st_class_member,
4523 &dev_attr_default_compression);
Jeff Garzik13026a62006-10-04 06:00:38 -04004524 if (error) goto out;
Tony Jonesee959b02008-02-22 00:13:36 +01004525 error = device_create_file(st_class_member,
4526 &dev_attr_options);
Kai Makisarab174be02008-02-24 22:29:12 +02004527 if (error) goto out;
Jeff Garzik13026a62006-10-04 06:00:38 -04004528
Linus Torvalds1da177e2005-04-16 15:20:36 -07004529 if (mode == 0 && rew == 0) {
4530 error = sysfs_create_link(&STp->device->sdev_gendev.kobj,
4531 &st_class_member->kobj,
4532 "tape");
4533 if (error) {
4534 printk(KERN_ERR
4535 "st%d: Can't create sysfs link from SCSI device.\n",
4536 dev_num);
Jeff Garzik13026a62006-10-04 06:00:38 -04004537 goto out;
Linus Torvalds1da177e2005-04-16 15:20:36 -07004538 }
4539 }
4540 }
Jeff Garzik13026a62006-10-04 06:00:38 -04004541
4542 return 0;
4543
4544out:
4545 return error;
Linus Torvalds1da177e2005-04-16 15:20:36 -07004546}
4547
Linus Torvalds1da177e2005-04-16 15:20:36 -07004548/* The following functions may be useful for a larger audience. */
FUJITA Tomonori66207422008-12-18 14:49:43 +09004549static int sgl_map_user_pages(struct st_buffer *STbp,
4550 const unsigned int max_pages, unsigned long uaddr,
4551 size_t count, int rw)
Linus Torvalds1da177e2005-04-16 15:20:36 -07004552{
James Bottomley07542b82005-08-31 20:27:22 -04004553 unsigned long end = (uaddr + count + PAGE_SIZE - 1) >> PAGE_SHIFT;
4554 unsigned long start = uaddr >> PAGE_SHIFT;
4555 const int nr_pages = end - start;
Linus Torvalds1da177e2005-04-16 15:20:36 -07004556 int res, i, j;
Linus Torvalds1da177e2005-04-16 15:20:36 -07004557 struct page **pages;
FUJITA Tomonori66207422008-12-18 14:49:43 +09004558 struct rq_map_data *mdata = &STbp->map_data;
Linus Torvalds1da177e2005-04-16 15:20:36 -07004559
Linus Torvalds1da177e2005-04-16 15:20:36 -07004560 /* User attempted Overflow! */
4561 if ((uaddr + count) < uaddr)
4562 return -EINVAL;
4563
4564 /* Too big */
4565 if (nr_pages > max_pages)
4566 return -ENOMEM;
4567
4568 /* Hmm? */
4569 if (count == 0)
4570 return 0;
4571
4572 if ((pages = kmalloc(max_pages * sizeof(*pages), GFP_KERNEL)) == NULL)
4573 return -ENOMEM;
4574
4575 /* Try to fault in all of the necessary pages */
4576 down_read(&current->mm->mmap_sem);
4577 /* rw==READ means read from drive, write into memory area */
4578 res = get_user_pages(
4579 current,
4580 current->mm,
4581 uaddr,
4582 nr_pages,
4583 rw == READ,
4584 0, /* don't force */
4585 pages,
4586 NULL);
4587 up_read(&current->mm->mmap_sem);
4588
4589 /* Errors and no page mapped should return here */
4590 if (res < nr_pages)
4591 goto out_unmap;
4592
4593 for (i=0; i < nr_pages; i++) {
4594 /* FIXME: flush superflous for rw==READ,
4595 * probably wrong function for rw==WRITE
4596 */
4597 flush_dcache_page(pages[i]);
4598 }
4599
FUJITA Tomonori66207422008-12-18 14:49:43 +09004600 mdata->offset = uaddr & ~PAGE_MASK;
FUJITA Tomonori66207422008-12-18 14:49:43 +09004601 STbp->mapped_pages = pages;
Linus Torvalds1da177e2005-04-16 15:20:36 -07004602
Linus Torvalds1da177e2005-04-16 15:20:36 -07004603 return nr_pages;
Linus Torvalds1da177e2005-04-16 15:20:36 -07004604 out_unmap:
4605 if (res > 0) {
4606 for (j=0; j < res; j++)
4607 page_cache_release(pages[j]);
Hugh Dickins6bc733e2005-12-01 20:21:57 +00004608 res = 0;
Linus Torvalds1da177e2005-04-16 15:20:36 -07004609 }
4610 kfree(pages);
4611 return res;
4612}
4613
4614
4615/* And unmap them... */
FUJITA Tomonori66207422008-12-18 14:49:43 +09004616static int sgl_unmap_user_pages(struct st_buffer *STbp,
4617 const unsigned int nr_pages, int dirtied)
Linus Torvalds1da177e2005-04-16 15:20:36 -07004618{
4619 int i;
4620
4621 for (i=0; i < nr_pages; i++) {
FUJITA Tomonori66207422008-12-18 14:49:43 +09004622 struct page *page = STbp->mapped_pages[i];
Nick Pigginb5810032005-10-29 18:16:12 -07004623
Nick Pigginb5810032005-10-29 18:16:12 -07004624 if (dirtied)
4625 SetPageDirty(page);
Linus Torvalds1da177e2005-04-16 15:20:36 -07004626 /* FIXME: cache flush missing for rw==READ
4627 * FIXME: call the correct reference counting function
4628 */
Nick Pigginb5810032005-10-29 18:16:12 -07004629 page_cache_release(page);
Linus Torvalds1da177e2005-04-16 15:20:36 -07004630 }
FUJITA Tomonori66207422008-12-18 14:49:43 +09004631 kfree(STbp->mapped_pages);
4632 STbp->mapped_pages = NULL;
Linus Torvalds1da177e2005-04-16 15:20:36 -07004633
4634 return 0;
4635}