blob: 390689d5fdf35ceb9426a5ca45a31f0bc7975b20 [file] [log] [blame]
Linus Torvalds1da177e2005-04-16 15:20:36 -07001/*
2 SCSI Tape Driver for Linux version 1.1 and newer. See the accompanying
3 file Documentation/scsi/st.txt for more information.
4
5 History:
6 Rewritten from Dwayne Forsyth's SCSI tape driver by Kai Makisara.
7 Contribution and ideas from several people including (in alphabetical
8 order) Klaus Ehrenfried, Eugene Exarevsky, Eric Lee Green, Wolfgang Denk,
9 Steve Hirsch, Andreas Koppenh"ofer, Michael Leodolter, Eyal Lebedinsky,
10 Michael Schaefer, J"org Weule, and Eric Youngdale.
11
Kai Makisarafd66c1b2008-01-17 22:45:22 +020012 Copyright 1992 - 2008 Kai Makisara
Linus Torvalds1da177e2005-04-16 15:20:36 -070013 email Kai.Makisara@kolumbus.fi
14
15 Some small formal changes - aeb, 950809
16
17 Last modified: 18-JAN-1998 Richard Gooch <rgooch@atnf.csiro.au> Devfs support
18 */
19
Kai Makisara626dcb12008-07-11 15:05:25 +030020static const char *verstr = "20080504";
Linus Torvalds1da177e2005-04-16 15:20:36 -070021
22#include <linux/module.h>
23
24#include <linux/fs.h>
25#include <linux/kernel.h>
26#include <linux/sched.h>
27#include <linux/mm.h>
28#include <linux/init.h>
29#include <linux/string.h>
30#include <linux/errno.h>
31#include <linux/mtio.h>
Kai Makisara 16c4b3e2005-05-01 18:11:55 +030032#include <linux/cdrom.h>
Linus Torvalds1da177e2005-04-16 15:20:36 -070033#include <linux/ioctl.h>
34#include <linux/fcntl.h>
35#include <linux/spinlock.h>
36#include <linux/blkdev.h>
37#include <linux/moduleparam.h>
Linus Torvalds1da177e2005-04-16 15:20:36 -070038#include <linux/cdev.h>
39#include <linux/delay.h>
Arjan van de Ven0b950672006-01-11 13:16:10 +010040#include <linux/mutex.h>
Jonathan Corbetb3369c62008-05-15 16:08:15 -060041#include <linux/smp_lock.h>
Linus Torvalds1da177e2005-04-16 15:20:36 -070042
43#include <asm/uaccess.h>
44#include <asm/dma.h>
45#include <asm/system.h>
46
47#include <scsi/scsi.h>
48#include <scsi/scsi_dbg.h>
49#include <scsi/scsi_device.h>
50#include <scsi/scsi_driver.h>
51#include <scsi/scsi_eh.h>
52#include <scsi/scsi_host.h>
53#include <scsi/scsi_ioctl.h>
Kai Makisara 16c4b3e2005-05-01 18:11:55 +030054#include <scsi/sg.h>
Linus Torvalds1da177e2005-04-16 15:20:36 -070055
56
57/* The driver prints some debugging information on the console if DEBUG
58 is defined and non-zero. */
59#define DEBUG 0
60
61#if DEBUG
62/* The message level for the debug messages is currently set to KERN_NOTICE
63 so that people can easily see the messages. Later when the debugging messages
64 in the drivers are more widely classified, this may be changed to KERN_DEBUG. */
65#define ST_DEB_MSG KERN_NOTICE
66#define DEB(a) a
67#define DEBC(a) if (debugging) { a ; }
68#else
69#define DEB(a)
70#define DEBC(a)
71#endif
72
73#define ST_KILOBYTE 1024
74
75#include "st_options.h"
76#include "st.h"
77
78static int buffer_kbs;
79static int max_sg_segs;
80static int try_direct_io = TRY_DIRECT_IO;
81static int try_rdio = 1;
82static int try_wdio = 1;
83
84static int st_dev_max;
85static int st_nr_dev;
86
gregkh@suse.ded2538782005-03-23 09:55:22 -080087static struct class *st_sysfs_class;
Linus Torvalds1da177e2005-04-16 15:20:36 -070088
89MODULE_AUTHOR("Kai Makisara");
Rene Hermanf018fa52006-03-08 00:14:20 -080090MODULE_DESCRIPTION("SCSI tape (st) driver");
Linus Torvalds1da177e2005-04-16 15:20:36 -070091MODULE_LICENSE("GPL");
Rene Hermanf018fa52006-03-08 00:14:20 -080092MODULE_ALIAS_CHARDEV_MAJOR(SCSI_TAPE_MAJOR);
Michael Tokarevd7b8bcb2006-10-27 16:02:37 +040093MODULE_ALIAS_SCSI_DEVICE(TYPE_TAPE);
Linus Torvalds1da177e2005-04-16 15:20:36 -070094
95/* Set 'perm' (4th argument) to 0 to disable module_param's definition
96 * of sysfs parameters (which module_param doesn't yet support).
97 * Sysfs parameters defined explicitly later.
98 */
99module_param_named(buffer_kbs, buffer_kbs, int, 0);
100MODULE_PARM_DESC(buffer_kbs, "Default driver buffer size for fixed block mode (KB; 32)");
101module_param_named(max_sg_segs, max_sg_segs, int, 0);
102MODULE_PARM_DESC(max_sg_segs, "Maximum number of scatter/gather segments to use (256)");
103module_param_named(try_direct_io, try_direct_io, int, 0);
104MODULE_PARM_DESC(try_direct_io, "Try direct I/O between user buffer and tape drive (1)");
105
106/* Extra parameters for testing */
107module_param_named(try_rdio, try_rdio, int, 0);
108MODULE_PARM_DESC(try_rdio, "Try direct read i/o when possible");
109module_param_named(try_wdio, try_wdio, int, 0);
110MODULE_PARM_DESC(try_wdio, "Try direct write i/o when possible");
111
112#ifndef MODULE
113static int write_threshold_kbs; /* retained for compatibility */
114static struct st_dev_parm {
115 char *name;
116 int *val;
117} parms[] __initdata = {
118 {
119 "buffer_kbs", &buffer_kbs
120 },
121 { /* Retained for compatibility with 2.4 */
122 "write_threshold_kbs", &write_threshold_kbs
123 },
124 {
125 "max_sg_segs", NULL
126 },
127 {
128 "try_direct_io", &try_direct_io
129 }
130};
131#endif
132
133/* Restrict the number of modes so that names for all are assigned */
134#if ST_NBR_MODES > 16
135#error "Maximum number of modes is 16"
136#endif
137/* Bit reversed order to get same names for same minors with all
138 mode counts */
Arjan van de Ven0ad78202005-11-28 16:22:25 +0100139static const char *st_formats[] = {
Linus Torvalds1da177e2005-04-16 15:20:36 -0700140 "", "r", "k", "s", "l", "t", "o", "u",
141 "m", "v", "p", "x", "a", "y", "q", "z"};
142
143/* The default definitions have been moved to st_options.h */
144
145#define ST_FIXED_BUFFER_SIZE (ST_FIXED_BUFFER_BLOCKS * ST_KILOBYTE)
146
147/* The buffer size should fit into the 24 bits for length in the
148 6-byte SCSI read and write commands. */
149#if ST_FIXED_BUFFER_SIZE >= (2 << 24 - 1)
150#error "Buffer size should not exceed (2 << 24 - 1) bytes!"
151#endif
152
153static int debugging = DEBUG;
154
155#define MAX_RETRIES 0
156#define MAX_WRITE_RETRIES 0
157#define MAX_READY_RETRIES 0
158#define NO_TAPE NOT_READY
159
160#define ST_TIMEOUT (900 * HZ)
161#define ST_LONG_TIMEOUT (14000 * HZ)
162
163/* Remove mode bits and auto-rewind bit (7) */
164#define TAPE_NR(x) ( ((iminor(x) & ~255) >> (ST_NBR_MODE_BITS + 1)) | \
165 (iminor(x) & ~(-1 << ST_MODE_SHIFT)) )
166#define TAPE_MODE(x) ((iminor(x) & ST_MODE_MASK) >> ST_MODE_SHIFT)
167
168/* Construct the minor number from the device (d), mode (m), and non-rewind (n) data */
169#define TAPE_MINOR(d, m, n) (((d & ~(255 >> (ST_NBR_MODE_BITS + 1))) << (ST_NBR_MODE_BITS + 1)) | \
170 (d & (255 >> (ST_NBR_MODE_BITS + 1))) | (m << ST_MODE_SHIFT) | ((n != 0) << 7) )
171
172/* Internal ioctl to set both density (uppermost 8 bits) and blocksize (lower
173 24 bits) */
174#define SET_DENS_AND_BLK 0x10001
175
176static DEFINE_RWLOCK(st_dev_arr_lock);
177
178static int st_fixed_buffer_size = ST_FIXED_BUFFER_SIZE;
179static int st_max_sg_segs = ST_MAX_SG;
180
181static struct scsi_tape **scsi_tapes = NULL;
182
183static int modes_defined;
184
185static struct st_buffer *new_tape_buffer(int, int, int);
186static int enlarge_buffer(struct st_buffer *, int, int);
Kai Makisara40f6b362008-02-24 22:23:24 +0200187static void clear_buffer(struct st_buffer *);
Linus Torvalds1da177e2005-04-16 15:20:36 -0700188static void normalize_buffer(struct st_buffer *);
189static int append_to_buffer(const char __user *, struct st_buffer *, int);
190static int from_buffer(struct st_buffer *, char __user *, int);
191static void move_buffer_data(struct st_buffer *, int);
192static void buf_to_sg(struct st_buffer *, unsigned int);
193
Linus Torvalds1da177e2005-04-16 15:20:36 -0700194static int sgl_map_user_pages(struct scatterlist *, const unsigned int,
195 unsigned long, size_t, int);
196static int sgl_unmap_user_pages(struct scatterlist *, const unsigned int, int);
197
198static int st_probe(struct device *);
199static int st_remove(struct device *);
Linus Torvalds1da177e2005-04-16 15:20:36 -0700200
Robert P. J. Day405ae7d2007-02-17 19:13:42 +0100201static int do_create_sysfs_files(void);
202static void do_remove_sysfs_files(void);
Jeff Garzik13026a62006-10-04 06:00:38 -0400203static int do_create_class_files(struct scsi_tape *, int, int);
Linus Torvalds1da177e2005-04-16 15:20:36 -0700204
205static struct scsi_driver st_template = {
206 .owner = THIS_MODULE,
207 .gendrv = {
208 .name = "st",
209 .probe = st_probe,
210 .remove = st_remove,
211 },
Linus Torvalds1da177e2005-04-16 15:20:36 -0700212};
213
214static int st_compression(struct scsi_tape *, int);
215
216static int find_partition(struct scsi_tape *);
217static int switch_partition(struct scsi_tape *);
218
219static int st_int_ioctl(struct scsi_tape *, unsigned int, unsigned long);
220
Kai Makisaraf03a5672005-08-02 13:40:47 +0300221static void scsi_tape_release(struct kref *);
222
223#define to_scsi_tape(obj) container_of(obj, struct scsi_tape, kref)
224
Arjan van de Ven0b950672006-01-11 13:16:10 +0100225static DEFINE_MUTEX(st_ref_mutex);
Kai Makisaraf03a5672005-08-02 13:40:47 +0300226
Linus Torvalds1da177e2005-04-16 15:20:36 -0700227
228#include "osst_detect.h"
229#ifndef SIGS_FROM_OSST
230#define SIGS_FROM_OSST \
231 {"OnStream", "SC-", "", "osst"}, \
232 {"OnStream", "DI-", "", "osst"}, \
233 {"OnStream", "DP-", "", "osst"}, \
234 {"OnStream", "USB", "", "osst"}, \
235 {"OnStream", "FW-", "", "osst"}
236#endif
237
Kai Makisaraf03a5672005-08-02 13:40:47 +0300238static struct scsi_tape *scsi_tape_get(int dev)
239{
240 struct scsi_tape *STp = NULL;
241
Arjan van de Ven0b950672006-01-11 13:16:10 +0100242 mutex_lock(&st_ref_mutex);
Kai Makisaraf03a5672005-08-02 13:40:47 +0300243 write_lock(&st_dev_arr_lock);
244
245 if (dev < st_dev_max && scsi_tapes != NULL)
246 STp = scsi_tapes[dev];
247 if (!STp) goto out;
248
249 kref_get(&STp->kref);
250
251 if (!STp->device)
252 goto out_put;
253
254 if (scsi_device_get(STp->device))
255 goto out_put;
256
257 goto out;
258
259out_put:
260 kref_put(&STp->kref, scsi_tape_release);
261 STp = NULL;
262out:
263 write_unlock(&st_dev_arr_lock);
Arjan van de Ven0b950672006-01-11 13:16:10 +0100264 mutex_unlock(&st_ref_mutex);
Kai Makisaraf03a5672005-08-02 13:40:47 +0300265 return STp;
266}
267
268static void scsi_tape_put(struct scsi_tape *STp)
269{
270 struct scsi_device *sdev = STp->device;
271
Arjan van de Ven0b950672006-01-11 13:16:10 +0100272 mutex_lock(&st_ref_mutex);
Kai Makisaraf03a5672005-08-02 13:40:47 +0300273 kref_put(&STp->kref, scsi_tape_release);
274 scsi_device_put(sdev);
Arjan van de Ven0b950672006-01-11 13:16:10 +0100275 mutex_unlock(&st_ref_mutex);
Kai Makisaraf03a5672005-08-02 13:40:47 +0300276}
277
Linus Torvalds1da177e2005-04-16 15:20:36 -0700278struct st_reject_data {
279 char *vendor;
280 char *model;
281 char *rev;
282 char *driver_hint; /* Name of the correct driver, NULL if unknown */
283};
284
285static struct st_reject_data reject_list[] = {
286 /* {"XXX", "Yy-", "", NULL}, example */
287 SIGS_FROM_OSST,
288 {NULL, }};
289
290/* If the device signature is on the list of incompatible drives, the
291 function returns a pointer to the name of the correct driver (if known) */
292static char * st_incompatible(struct scsi_device* SDp)
293{
294 struct st_reject_data *rp;
295
296 for (rp=&(reject_list[0]); rp->vendor != NULL; rp++)
297 if (!strncmp(rp->vendor, SDp->vendor, strlen(rp->vendor)) &&
298 !strncmp(rp->model, SDp->model, strlen(rp->model)) &&
299 !strncmp(rp->rev, SDp->rev, strlen(rp->rev))) {
300 if (rp->driver_hint)
301 return rp->driver_hint;
302 else
303 return "unknown";
304 }
305 return NULL;
306}
307
308
309static inline char *tape_name(struct scsi_tape *tape)
310{
311 return tape->disk->disk_name;
312}
313
314
Mike Christie8b05b772005-11-08 04:06:44 -0600315static void st_analyze_sense(struct st_request *SRpnt, struct st_cmdstatus *s)
Linus Torvalds1da177e2005-04-16 15:20:36 -0700316{
317 const u8 *ucp;
Mike Christie8b05b772005-11-08 04:06:44 -0600318 const u8 *sense = SRpnt->sense;
Linus Torvalds1da177e2005-04-16 15:20:36 -0700319
Mike Christie8b05b772005-11-08 04:06:44 -0600320 s->have_sense = scsi_normalize_sense(SRpnt->sense,
321 SCSI_SENSE_BUFFERSIZE, &s->sense_hdr);
Linus Torvalds1da177e2005-04-16 15:20:36 -0700322 s->flags = 0;
323
324 if (s->have_sense) {
325 s->deferred = 0;
326 s->remainder_valid =
327 scsi_get_sense_info_fld(sense, SCSI_SENSE_BUFFERSIZE, &s->uremainder64);
328 switch (sense[0] & 0x7f) {
329 case 0x71:
330 s->deferred = 1;
331 case 0x70:
332 s->fixed_format = 1;
333 s->flags = sense[2] & 0xe0;
334 break;
335 case 0x73:
336 s->deferred = 1;
337 case 0x72:
338 s->fixed_format = 0;
339 ucp = scsi_sense_desc_find(sense, SCSI_SENSE_BUFFERSIZE, 4);
340 s->flags = ucp ? (ucp[3] & 0xe0) : 0;
341 break;
342 }
343 }
344}
345
346
347/* Convert the result to success code */
Mike Christie8b05b772005-11-08 04:06:44 -0600348static int st_chk_result(struct scsi_tape *STp, struct st_request * SRpnt)
Linus Torvalds1da177e2005-04-16 15:20:36 -0700349{
Mike Christie8b05b772005-11-08 04:06:44 -0600350 int result = SRpnt->result;
Linus Torvalds1da177e2005-04-16 15:20:36 -0700351 u8 scode;
352 DEB(const char *stp;)
353 char *name = tape_name(STp);
354 struct st_cmdstatus *cmdstatp;
355
356 if (!result)
357 return 0;
358
359 cmdstatp = &STp->buffer->cmdstat;
Kai Makisaraf03a5672005-08-02 13:40:47 +0300360 st_analyze_sense(SRpnt, cmdstatp);
Linus Torvalds1da177e2005-04-16 15:20:36 -0700361
362 if (cmdstatp->have_sense)
363 scode = STp->buffer->cmdstat.sense_hdr.sense_key;
364 else
365 scode = 0;
366
367 DEB(
368 if (debugging) {
Mike Christie8b05b772005-11-08 04:06:44 -0600369 printk(ST_DEB_MSG "%s: Error: %x, cmd: %x %x %x %x %x %x\n",
Linus Torvalds1da177e2005-04-16 15:20:36 -0700370 name, result,
Mike Christie8b05b772005-11-08 04:06:44 -0600371 SRpnt->cmd[0], SRpnt->cmd[1], SRpnt->cmd[2],
372 SRpnt->cmd[3], SRpnt->cmd[4], SRpnt->cmd[5]);
Linus Torvalds1da177e2005-04-16 15:20:36 -0700373 if (cmdstatp->have_sense)
Luben Tuikov4e73ea72006-07-07 00:02:18 -0700374 __scsi_print_sense(name, SRpnt->sense, SCSI_SENSE_BUFFERSIZE);
Linus Torvalds1da177e2005-04-16 15:20:36 -0700375 } ) /* end DEB */
376 if (!debugging) { /* Abnormal conditions for tape */
377 if (!cmdstatp->have_sense)
378 printk(KERN_WARNING
379 "%s: Error %x (sugg. bt 0x%x, driver bt 0x%x, host bt 0x%x).\n",
380 name, result, suggestion(result),
381 driver_byte(result) & DRIVER_MASK, host_byte(result));
382 else if (cmdstatp->have_sense &&
383 scode != NO_SENSE &&
384 scode != RECOVERED_ERROR &&
385 /* scode != UNIT_ATTENTION && */
386 scode != BLANK_CHECK &&
387 scode != VOLUME_OVERFLOW &&
Mike Christie8b05b772005-11-08 04:06:44 -0600388 SRpnt->cmd[0] != MODE_SENSE &&
389 SRpnt->cmd[0] != TEST_UNIT_READY) {
Luben Tuikov4e73ea72006-07-07 00:02:18 -0700390
391 __scsi_print_sense(name, SRpnt->sense, SCSI_SENSE_BUFFERSIZE);
Linus Torvalds1da177e2005-04-16 15:20:36 -0700392 }
393 }
394
395 if (cmdstatp->fixed_format &&
396 STp->cln_mode >= EXTENDED_SENSE_START) { /* Only fixed format sense */
397 if (STp->cln_sense_value)
Mike Christie8b05b772005-11-08 04:06:44 -0600398 STp->cleaning_req |= ((SRpnt->sense[STp->cln_mode] &
Linus Torvalds1da177e2005-04-16 15:20:36 -0700399 STp->cln_sense_mask) == STp->cln_sense_value);
400 else
Mike Christie8b05b772005-11-08 04:06:44 -0600401 STp->cleaning_req |= ((SRpnt->sense[STp->cln_mode] &
Linus Torvalds1da177e2005-04-16 15:20:36 -0700402 STp->cln_sense_mask) != 0);
403 }
404 if (cmdstatp->have_sense &&
405 cmdstatp->sense_hdr.asc == 0 && cmdstatp->sense_hdr.ascq == 0x17)
406 STp->cleaning_req = 1; /* ASC and ASCQ => cleaning requested */
407
408 STp->pos_unknown |= STp->device->was_reset;
409
410 if (cmdstatp->have_sense &&
411 scode == RECOVERED_ERROR
412#if ST_RECOVERED_WRITE_FATAL
Mike Christie8b05b772005-11-08 04:06:44 -0600413 && SRpnt->cmd[0] != WRITE_6
414 && SRpnt->cmd[0] != WRITE_FILEMARKS
Linus Torvalds1da177e2005-04-16 15:20:36 -0700415#endif
416 ) {
417 STp->recover_count++;
418 STp->recover_reg++;
419
420 DEB(
421 if (debugging) {
Mike Christie8b05b772005-11-08 04:06:44 -0600422 if (SRpnt->cmd[0] == READ_6)
Linus Torvalds1da177e2005-04-16 15:20:36 -0700423 stp = "read";
Mike Christie8b05b772005-11-08 04:06:44 -0600424 else if (SRpnt->cmd[0] == WRITE_6)
Linus Torvalds1da177e2005-04-16 15:20:36 -0700425 stp = "write";
426 else
427 stp = "ioctl";
428 printk(ST_DEB_MSG "%s: Recovered %s error (%d).\n", name, stp,
429 STp->recover_count);
430 } ) /* end DEB */
431
432 if (cmdstatp->flags == 0)
433 return 0;
434 }
435 return (-EIO);
436}
437
438
439/* Wakeup from interrupt */
Mike Christie8b05b772005-11-08 04:06:44 -0600440static void st_sleep_done(void *data, char *sense, int result, int resid)
Linus Torvalds1da177e2005-04-16 15:20:36 -0700441{
Mike Christie8b05b772005-11-08 04:06:44 -0600442 struct st_request *SRpnt = data;
443 struct scsi_tape *STp = SRpnt->stp;
Linus Torvalds1da177e2005-04-16 15:20:36 -0700444
Mike Christie8b05b772005-11-08 04:06:44 -0600445 memcpy(SRpnt->sense, sense, SCSI_SENSE_BUFFERSIZE);
446 (STp->buffer)->cmdstat.midlevel_result = SRpnt->result = result;
Kai Makisara40f6b362008-02-24 22:23:24 +0200447 (STp->buffer)->cmdstat.residual = resid;
Linus Torvalds1da177e2005-04-16 15:20:36 -0700448 DEB( STp->write_pending = 0; )
449
Mike Christie8b05b772005-11-08 04:06:44 -0600450 if (SRpnt->waiting)
451 complete(SRpnt->waiting);
452}
453
FUJITA Tomonori4deba242008-12-05 15:25:20 +0900454static struct st_request *st_allocate_request(struct scsi_tape *stp)
Mike Christie8b05b772005-11-08 04:06:44 -0600455{
FUJITA Tomonori4deba242008-12-05 15:25:20 +0900456 struct st_request *streq;
457
458 streq = kzalloc(sizeof(*streq), GFP_KERNEL);
459 if (streq)
460 streq->stp = stp;
461 else {
462 DEBC(printk(KERN_ERR "%s: Can't get SCSI request.\n",
463 tape_name(stp)););
464 if (signal_pending(current))
465 stp->buffer->syscall_result = -EINTR;
466 else
467 stp->buffer->syscall_result = -EBUSY;
468 }
469
470 return streq;
Mike Christie8b05b772005-11-08 04:06:44 -0600471}
472
473static void st_release_request(struct st_request *streq)
474{
475 kfree(streq);
Linus Torvalds1da177e2005-04-16 15:20:36 -0700476}
477
FUJITA Tomonori13b53b42008-12-18 14:49:41 +0900478static void st_scsi_execute_end(struct request *req, int uptodate)
479{
480 struct st_request *SRpnt = req->end_io_data;
481 struct scsi_tape *STp = SRpnt->stp;
482
483 STp->buffer->cmdstat.midlevel_result = SRpnt->result = req->errors;
484 STp->buffer->cmdstat.residual = req->data_len;
485
486 if (SRpnt->waiting)
487 complete(SRpnt->waiting);
488
489 blk_rq_unmap_user(SRpnt->bio);
490 __blk_put_request(req->q, req);
491}
492
493static int st_scsi_execute(struct st_request *SRpnt, const unsigned char *cmd,
494 int data_direction, void *buffer, unsigned bufflen,
495 int timeout, int retries)
496{
497 struct request *req;
498 struct rq_map_data *mdata = &SRpnt->stp->buffer->map_data;
499 int err = 0;
500 int write = (data_direction == DMA_TO_DEVICE);
501
502 req = blk_get_request(SRpnt->stp->device->request_queue, write,
503 GFP_KERNEL);
504 if (!req)
505 return DRIVER_ERROR << 24;
506
507 req->cmd_type = REQ_TYPE_BLOCK_PC;
508 req->cmd_flags |= REQ_QUIET;
509
510 mdata->null_mapped = 1;
511
512 err = blk_rq_map_user(req->q, req, mdata, NULL, bufflen, GFP_KERNEL);
513 if (err) {
514 blk_put_request(req);
515 return DRIVER_ERROR << 24;
516 }
517
518 SRpnt->bio = req->bio;
519 req->cmd_len = COMMAND_SIZE(cmd[0]);
520 memset(req->cmd, 0, BLK_MAX_CDB);
521 memcpy(req->cmd, cmd, req->cmd_len);
522 req->sense = SRpnt->sense;
523 req->sense_len = 0;
524 req->timeout = timeout;
525 req->retries = retries;
526 req->end_io_data = SRpnt;
527
528 blk_execute_rq_nowait(req->q, NULL, req, 1, st_scsi_execute_end);
529 return 0;
530}
531
Linus Torvalds1da177e2005-04-16 15:20:36 -0700532/* Do the scsi command. Waits until command performed if do_wait is true.
533 Otherwise write_behind_check() is used to check that the command
534 has finished. */
Mike Christie8b05b772005-11-08 04:06:44 -0600535static struct st_request *
536st_do_scsi(struct st_request * SRpnt, struct scsi_tape * STp, unsigned char *cmd,
Linus Torvalds1da177e2005-04-16 15:20:36 -0700537 int bytes, int direction, int timeout, int retries, int do_wait)
538{
Kai Makisaraf03a5672005-08-02 13:40:47 +0300539 struct completion *waiting;
FUJITA Tomonori6d476262008-12-18 14:49:42 +0900540 struct rq_map_data *mdata = &STp->buffer->map_data;
541 int ret;
Linus Torvalds1da177e2005-04-16 15:20:36 -0700542
Kai Makisaraf03a5672005-08-02 13:40:47 +0300543 /* if async, make sure there's no command outstanding */
544 if (!do_wait && ((STp->buffer)->last_SRpnt)) {
545 printk(KERN_ERR "%s: Async command already active.\n",
546 tape_name(STp));
547 if (signal_pending(current))
548 (STp->buffer)->syscall_result = (-EINTR);
549 else
550 (STp->buffer)->syscall_result = (-EBUSY);
551 return NULL;
552 }
553
FUJITA Tomonori4deba242008-12-05 15:25:20 +0900554 if (!SRpnt) {
555 SRpnt = st_allocate_request(STp);
556 if (!SRpnt)
Linus Torvalds1da177e2005-04-16 15:20:36 -0700557 return NULL;
Linus Torvalds1da177e2005-04-16 15:20:36 -0700558 }
559
Kai Makisaraf03a5672005-08-02 13:40:47 +0300560 /* If async IO, set last_SRpnt. This ptr tells write_behind_check
561 which IO is outstanding. It's nulled out when the IO completes. */
562 if (!do_wait)
563 (STp->buffer)->last_SRpnt = SRpnt;
564
565 waiting = &STp->wait;
566 init_completion(waiting);
Mike Christie8b05b772005-11-08 04:06:44 -0600567 SRpnt->waiting = waiting;
568
FUJITA Tomonori6d476262008-12-18 14:49:42 +0900569 if (!STp->buffer->do_dio) {
Mike Christie8b05b772005-11-08 04:06:44 -0600570 buf_to_sg(STp->buffer, bytes);
571
FUJITA Tomonori6d476262008-12-18 14:49:42 +0900572 mdata->nr_entries =
573 DIV_ROUND_UP(bytes, PAGE_SIZE << mdata->page_order);
574 STp->buffer->map_data.pages = STp->buffer->reserved_pages;
575 STp->buffer->map_data.offset = 0;
576 }
577
Mike Christie8b05b772005-11-08 04:06:44 -0600578 memcpy(SRpnt->cmd, cmd, sizeof(SRpnt->cmd));
Linus Torvalds1da177e2005-04-16 15:20:36 -0700579 STp->buffer->cmdstat.have_sense = 0;
Mike Christie8b05b772005-11-08 04:06:44 -0600580 STp->buffer->syscall_result = 0;
Linus Torvalds1da177e2005-04-16 15:20:36 -0700581
FUJITA Tomonori6d476262008-12-18 14:49:42 +0900582 if (STp->buffer->do_dio)
583 ret = scsi_execute_async(STp->device, cmd, COMMAND_SIZE(cmd[0]),
584 direction, &((STp->buffer)->sg[0]),
585 bytes, (STp->buffer)->sg_segs, timeout,
586 retries, SRpnt, st_sleep_done,
587 GFP_KERNEL);
588 else
589 ret = st_scsi_execute(SRpnt, cmd, direction, NULL, bytes,
590 timeout, retries);
591
592 if (ret) {
Mike Christie8b05b772005-11-08 04:06:44 -0600593 /* could not allocate the buffer or request was too large */
594 (STp->buffer)->syscall_result = (-EBUSY);
Kai Makisara787926b2005-11-13 10:04:44 +0200595 (STp->buffer)->last_SRpnt = NULL;
FUJITA Tomonori6d476262008-12-18 14:49:42 +0900596 } else if (do_wait) {
Kai Makisaraf03a5672005-08-02 13:40:47 +0300597 wait_for_completion(waiting);
Mike Christie8b05b772005-11-08 04:06:44 -0600598 SRpnt->waiting = NULL;
Linus Torvalds1da177e2005-04-16 15:20:36 -0700599 (STp->buffer)->syscall_result = st_chk_result(STp, SRpnt);
600 }
Mike Christie8b05b772005-11-08 04:06:44 -0600601
Linus Torvalds1da177e2005-04-16 15:20:36 -0700602 return SRpnt;
603}
604
FUJITA Tomonoriffb43492008-12-05 15:25:21 +0900605static int st_scsi_kern_execute(struct st_request *streq,
606 const unsigned char *cmd, int data_direction,
607 void *buffer, unsigned bufflen, int timeout,
608 int retries)
609{
610 struct scsi_tape *stp = streq->stp;
611 int ret, resid;
612
613 stp->buffer->cmdstat.have_sense = 0;
614 memcpy(streq->cmd, cmd, sizeof(streq->cmd));
615
616 ret = scsi_execute(stp->device, cmd, data_direction, buffer, bufflen,
617 streq->sense, timeout, retries, 0, &resid);
618 if (driver_byte(ret) & DRIVER_ERROR)
619 return -EBUSY;
620
621 stp->buffer->cmdstat.midlevel_result = streq->result = ret;
622 stp->buffer->cmdstat.residual = resid;
623 stp->buffer->syscall_result = st_chk_result(stp, streq);
624
625 return 0;
626}
Linus Torvalds1da177e2005-04-16 15:20:36 -0700627
628/* Handle the write-behind checking (waits for completion). Returns -ENOSPC if
629 write has been correct but EOM early warning reached, -EIO if write ended in
630 error or zero if write successful. Asynchronous writes are used only in
631 variable block mode. */
632static int write_behind_check(struct scsi_tape * STp)
633{
634 int retval = 0;
635 struct st_buffer *STbuffer;
636 struct st_partstat *STps;
637 struct st_cmdstatus *cmdstatp;
Mike Christie8b05b772005-11-08 04:06:44 -0600638 struct st_request *SRpnt;
Linus Torvalds1da177e2005-04-16 15:20:36 -0700639
640 STbuffer = STp->buffer;
641 if (!STbuffer->writing)
642 return 0;
643
644 DEB(
645 if (STp->write_pending)
646 STp->nbr_waits++;
647 else
648 STp->nbr_finished++;
649 ) /* end DEB */
650
651 wait_for_completion(&(STp->wait));
Kai Makisaraf03a5672005-08-02 13:40:47 +0300652 SRpnt = STbuffer->last_SRpnt;
653 STbuffer->last_SRpnt = NULL;
Mike Christie8b05b772005-11-08 04:06:44 -0600654 SRpnt->waiting = NULL;
Linus Torvalds1da177e2005-04-16 15:20:36 -0700655
Kai Makisaraf03a5672005-08-02 13:40:47 +0300656 (STp->buffer)->syscall_result = st_chk_result(STp, SRpnt);
Mike Christie8b05b772005-11-08 04:06:44 -0600657 st_release_request(SRpnt);
Linus Torvalds1da177e2005-04-16 15:20:36 -0700658
659 STbuffer->buffer_bytes -= STbuffer->writing;
660 STps = &(STp->ps[STp->partition]);
661 if (STps->drv_block >= 0) {
662 if (STp->block_size == 0)
663 STps->drv_block++;
664 else
665 STps->drv_block += STbuffer->writing / STp->block_size;
666 }
667
668 cmdstatp = &STbuffer->cmdstat;
669 if (STbuffer->syscall_result) {
670 retval = -EIO;
671 if (cmdstatp->have_sense && !cmdstatp->deferred &&
672 (cmdstatp->flags & SENSE_EOM) &&
673 (cmdstatp->sense_hdr.sense_key == NO_SENSE ||
674 cmdstatp->sense_hdr.sense_key == RECOVERED_ERROR)) {
675 /* EOM at write-behind, has all data been written? */
676 if (!cmdstatp->remainder_valid ||
677 cmdstatp->uremainder64 == 0)
678 retval = -ENOSPC;
679 }
680 if (retval == -EIO)
681 STps->drv_block = -1;
682 }
683 STbuffer->writing = 0;
684
685 DEB(if (debugging && retval)
686 printk(ST_DEB_MSG "%s: Async write error %x, return value %d.\n",
687 tape_name(STp), STbuffer->cmdstat.midlevel_result, retval);) /* end DEB */
688
689 return retval;
690}
691
692
693/* Step over EOF if it has been inadvertently crossed (ioctl not used because
694 it messes up the block number). */
695static int cross_eof(struct scsi_tape * STp, int forward)
696{
Mike Christie8b05b772005-11-08 04:06:44 -0600697 struct st_request *SRpnt;
Linus Torvalds1da177e2005-04-16 15:20:36 -0700698 unsigned char cmd[MAX_COMMAND_SIZE];
FUJITA Tomonori39ade4b2008-12-05 15:25:25 +0900699 int ret;
Linus Torvalds1da177e2005-04-16 15:20:36 -0700700
701 cmd[0] = SPACE;
702 cmd[1] = 0x01; /* Space FileMarks */
703 if (forward) {
704 cmd[2] = cmd[3] = 0;
705 cmd[4] = 1;
706 } else
707 cmd[2] = cmd[3] = cmd[4] = 0xff; /* -1 filemarks */
708 cmd[5] = 0;
709
710 DEBC(printk(ST_DEB_MSG "%s: Stepping over filemark %s.\n",
711 tape_name(STp), forward ? "forward" : "backward"));
712
FUJITA Tomonori39ade4b2008-12-05 15:25:25 +0900713 SRpnt = st_allocate_request(STp);
Linus Torvalds1da177e2005-04-16 15:20:36 -0700714 if (!SRpnt)
FUJITA Tomonori39ade4b2008-12-05 15:25:25 +0900715 return STp->buffer->syscall_result;
Linus Torvalds1da177e2005-04-16 15:20:36 -0700716
FUJITA Tomonori39ade4b2008-12-05 15:25:25 +0900717 ret = st_scsi_kern_execute(SRpnt, cmd, DMA_NONE, NULL, 0,
718 STp->device->request_queue->rq_timeout,
719 MAX_RETRIES);
720 if (ret)
721 goto out;
722
723 ret = STp->buffer->syscall_result;
Linus Torvalds1da177e2005-04-16 15:20:36 -0700724
725 if ((STp->buffer)->cmdstat.midlevel_result != 0)
726 printk(KERN_ERR "%s: Stepping over filemark %s failed.\n",
727 tape_name(STp), forward ? "forward" : "backward");
728
FUJITA Tomonori39ade4b2008-12-05 15:25:25 +0900729out:
730 st_release_request(SRpnt);
731
732 return ret;
Linus Torvalds1da177e2005-04-16 15:20:36 -0700733}
734
735
736/* Flush the write buffer (never need to write if variable blocksize). */
Adrian Bunk8ef8d592008-04-14 17:17:16 +0300737static int st_flush_write_buffer(struct scsi_tape * STp)
Linus Torvalds1da177e2005-04-16 15:20:36 -0700738{
Kai Makisara786231a2008-07-11 15:06:40 +0300739 int transfer, blks;
Linus Torvalds1da177e2005-04-16 15:20:36 -0700740 int result;
741 unsigned char cmd[MAX_COMMAND_SIZE];
Mike Christie8b05b772005-11-08 04:06:44 -0600742 struct st_request *SRpnt;
Linus Torvalds1da177e2005-04-16 15:20:36 -0700743 struct st_partstat *STps;
744
745 result = write_behind_check(STp);
746 if (result)
747 return result;
748
749 result = 0;
750 if (STp->dirty == 1) {
751
Kai Makisara786231a2008-07-11 15:06:40 +0300752 transfer = STp->buffer->buffer_bytes;
Linus Torvalds1da177e2005-04-16 15:20:36 -0700753 DEBC(printk(ST_DEB_MSG "%s: Flushing %d bytes.\n",
754 tape_name(STp), transfer));
755
Linus Torvalds1da177e2005-04-16 15:20:36 -0700756 memset(cmd, 0, MAX_COMMAND_SIZE);
757 cmd[0] = WRITE_6;
758 cmd[1] = 1;
759 blks = transfer / STp->block_size;
760 cmd[2] = blks >> 16;
761 cmd[3] = blks >> 8;
762 cmd[4] = blks;
763
764 SRpnt = st_do_scsi(NULL, STp, cmd, transfer, DMA_TO_DEVICE,
James Bottomleya02488e2008-11-30 10:36:26 -0600765 STp->device->request_queue->rq_timeout,
766 MAX_WRITE_RETRIES, 1);
Linus Torvalds1da177e2005-04-16 15:20:36 -0700767 if (!SRpnt)
768 return (STp->buffer)->syscall_result;
769
770 STps = &(STp->ps[STp->partition]);
771 if ((STp->buffer)->syscall_result != 0) {
772 struct st_cmdstatus *cmdstatp = &STp->buffer->cmdstat;
773
774 if (cmdstatp->have_sense && !cmdstatp->deferred &&
775 (cmdstatp->flags & SENSE_EOM) &&
776 (cmdstatp->sense_hdr.sense_key == NO_SENSE ||
777 cmdstatp->sense_hdr.sense_key == RECOVERED_ERROR) &&
778 (!cmdstatp->remainder_valid ||
779 cmdstatp->uremainder64 == 0)) { /* All written at EOM early warning */
780 STp->dirty = 0;
781 (STp->buffer)->buffer_bytes = 0;
782 if (STps->drv_block >= 0)
783 STps->drv_block += blks;
784 result = (-ENOSPC);
785 } else {
786 printk(KERN_ERR "%s: Error on flush.\n",
787 tape_name(STp));
788 STps->drv_block = (-1);
789 result = (-EIO);
790 }
791 } else {
792 if (STps->drv_block >= 0)
793 STps->drv_block += blks;
794 STp->dirty = 0;
795 (STp->buffer)->buffer_bytes = 0;
796 }
Mike Christie8b05b772005-11-08 04:06:44 -0600797 st_release_request(SRpnt);
Linus Torvalds1da177e2005-04-16 15:20:36 -0700798 SRpnt = NULL;
799 }
800 return result;
801}
802
803
804/* Flush the tape buffer. The tape will be positioned correctly unless
805 seek_next is true. */
806static int flush_buffer(struct scsi_tape *STp, int seek_next)
807{
808 int backspace, result;
809 struct st_buffer *STbuffer;
810 struct st_partstat *STps;
811
812 STbuffer = STp->buffer;
813
814 /*
815 * If there was a bus reset, block further access
816 * to this device.
817 */
818 if (STp->pos_unknown)
819 return (-EIO);
820
821 if (STp->ready != ST_READY)
822 return 0;
823 STps = &(STp->ps[STp->partition]);
824 if (STps->rw == ST_WRITING) /* Writing */
Adrian Bunk8ef8d592008-04-14 17:17:16 +0300825 return st_flush_write_buffer(STp);
Linus Torvalds1da177e2005-04-16 15:20:36 -0700826
827 if (STp->block_size == 0)
828 return 0;
829
830 backspace = ((STp->buffer)->buffer_bytes +
831 (STp->buffer)->read_pointer) / STp->block_size -
832 ((STp->buffer)->read_pointer + STp->block_size - 1) /
833 STp->block_size;
834 (STp->buffer)->buffer_bytes = 0;
835 (STp->buffer)->read_pointer = 0;
836 result = 0;
837 if (!seek_next) {
838 if (STps->eof == ST_FM_HIT) {
839 result = cross_eof(STp, 0); /* Back over the EOF hit */
840 if (!result)
841 STps->eof = ST_NOEOF;
842 else {
843 if (STps->drv_file >= 0)
844 STps->drv_file++;
845 STps->drv_block = 0;
846 }
847 }
848 if (!result && backspace > 0)
849 result = st_int_ioctl(STp, MTBSR, backspace);
850 } else if (STps->eof == ST_FM_HIT) {
851 if (STps->drv_file >= 0)
852 STps->drv_file++;
853 STps->drv_block = 0;
854 STps->eof = ST_NOEOF;
855 }
856 return result;
857
858}
859
860/* Set the mode parameters */
861static int set_mode_densblk(struct scsi_tape * STp, struct st_modedef * STm)
862{
863 int set_it = 0;
864 unsigned long arg;
865 char *name = tape_name(STp);
866
867 if (!STp->density_changed &&
868 STm->default_density >= 0 &&
869 STm->default_density != STp->density) {
870 arg = STm->default_density;
871 set_it = 1;
872 } else
873 arg = STp->density;
874 arg <<= MT_ST_DENSITY_SHIFT;
875 if (!STp->blksize_changed &&
876 STm->default_blksize >= 0 &&
877 STm->default_blksize != STp->block_size) {
878 arg |= STm->default_blksize;
879 set_it = 1;
880 } else
881 arg |= STp->block_size;
882 if (set_it &&
883 st_int_ioctl(STp, SET_DENS_AND_BLK, arg)) {
884 printk(KERN_WARNING
885 "%s: Can't set default block size to %d bytes and density %x.\n",
886 name, STm->default_blksize, STm->default_density);
887 if (modes_defined)
888 return (-EINVAL);
889 }
890 return 0;
891}
892
893
Mike Christie8b05b772005-11-08 04:06:44 -0600894/* Lock or unlock the drive door. Don't use when st_request allocated. */
Linus Torvalds1da177e2005-04-16 15:20:36 -0700895static int do_door_lock(struct scsi_tape * STp, int do_lock)
896{
897 int retval, cmd;
898 DEB(char *name = tape_name(STp);)
899
900
901 cmd = do_lock ? SCSI_IOCTL_DOORLOCK : SCSI_IOCTL_DOORUNLOCK;
902 DEBC(printk(ST_DEB_MSG "%s: %socking drive door.\n", name,
903 do_lock ? "L" : "Unl"));
904 retval = scsi_ioctl(STp->device, cmd, NULL);
905 if (!retval) {
906 STp->door_locked = do_lock ? ST_LOCKED_EXPLICIT : ST_UNLOCKED;
907 }
908 else {
909 STp->door_locked = ST_LOCK_FAILS;
910 }
911 return retval;
912}
913
914
915/* Set the internal state after reset */
916static void reset_state(struct scsi_tape *STp)
917{
918 int i;
919 struct st_partstat *STps;
920
921 STp->pos_unknown = 0;
922 for (i = 0; i < ST_NBR_PARTITIONS; i++) {
923 STps = &(STp->ps[i]);
924 STps->rw = ST_IDLE;
925 STps->eof = ST_NOEOF;
926 STps->at_sm = 0;
927 STps->last_block_valid = 0;
928 STps->drv_block = -1;
929 STps->drv_file = -1;
930 }
931 if (STp->can_partitions) {
932 STp->partition = find_partition(STp);
933 if (STp->partition < 0)
934 STp->partition = 0;
935 STp->new_partition = STp->partition;
936 }
937}
938
939/* Test if the drive is ready. Returns either one of the codes below or a negative system
940 error code. */
941#define CHKRES_READY 0
942#define CHKRES_NEW_SESSION 1
943#define CHKRES_NOT_READY 2
944#define CHKRES_NO_TAPE 3
945
946#define MAX_ATTENTIONS 10
947
948static int test_ready(struct scsi_tape *STp, int do_wait)
949{
950 int attentions, waits, max_wait, scode;
951 int retval = CHKRES_READY, new_session = 0;
952 unsigned char cmd[MAX_COMMAND_SIZE];
FUJITA Tomonori0944a722008-12-05 15:25:22 +0900953 struct st_request *SRpnt;
Linus Torvalds1da177e2005-04-16 15:20:36 -0700954 struct st_cmdstatus *cmdstatp = &STp->buffer->cmdstat;
955
FUJITA Tomonori0944a722008-12-05 15:25:22 +0900956 SRpnt = st_allocate_request(STp);
957 if (!SRpnt)
958 return STp->buffer->syscall_result;
959
Linus Torvalds1da177e2005-04-16 15:20:36 -0700960 max_wait = do_wait ? ST_BLOCK_SECONDS : 0;
961
962 for (attentions=waits=0; ; ) {
963 memset((void *) &cmd[0], 0, MAX_COMMAND_SIZE);
964 cmd[0] = TEST_UNIT_READY;
Linus Torvalds1da177e2005-04-16 15:20:36 -0700965
FUJITA Tomonori0944a722008-12-05 15:25:22 +0900966 retval = st_scsi_kern_execute(SRpnt, cmd, DMA_NONE, NULL, 0,
967 STp->long_timeout,
968 MAX_READY_RETRIES);
969 if (retval)
Linus Torvalds1da177e2005-04-16 15:20:36 -0700970 break;
Linus Torvalds1da177e2005-04-16 15:20:36 -0700971
972 if (cmdstatp->have_sense) {
973
974 scode = cmdstatp->sense_hdr.sense_key;
975
976 if (scode == UNIT_ATTENTION) { /* New media? */
977 new_session = 1;
978 if (attentions < MAX_ATTENTIONS) {
979 attentions++;
980 continue;
981 }
982 else {
983 retval = (-EIO);
984 break;
985 }
986 }
987
988 if (scode == NOT_READY) {
989 if (waits < max_wait) {
990 if (msleep_interruptible(1000)) {
991 retval = (-EINTR);
992 break;
993 }
994 waits++;
995 continue;
996 }
997 else {
998 if ((STp->device)->scsi_level >= SCSI_2 &&
999 cmdstatp->sense_hdr.asc == 0x3a) /* Check ASC */
1000 retval = CHKRES_NO_TAPE;
1001 else
1002 retval = CHKRES_NOT_READY;
1003 break;
1004 }
1005 }
1006 }
1007
1008 retval = (STp->buffer)->syscall_result;
1009 if (!retval)
1010 retval = new_session ? CHKRES_NEW_SESSION : CHKRES_READY;
1011 break;
1012 }
1013
FUJITA Tomonori0944a722008-12-05 15:25:22 +09001014 st_release_request(SRpnt);
1015
Linus Torvalds1da177e2005-04-16 15:20:36 -07001016 return retval;
1017}
1018
1019
1020/* See if the drive is ready and gather information about the tape. Return values:
1021 < 0 negative error code from errno.h
1022 0 drive ready
1023 1 drive not ready (possibly no tape)
1024*/
1025static int check_tape(struct scsi_tape *STp, struct file *filp)
1026{
1027 int i, retval, new_session = 0, do_wait;
1028 unsigned char cmd[MAX_COMMAND_SIZE], saved_cleaning;
1029 unsigned short st_flags = filp->f_flags;
Mike Christie8b05b772005-11-08 04:06:44 -06001030 struct st_request *SRpnt = NULL;
Linus Torvalds1da177e2005-04-16 15:20:36 -07001031 struct st_modedef *STm;
1032 struct st_partstat *STps;
1033 char *name = tape_name(STp);
Josef Sipek7ac62072006-12-08 02:37:37 -08001034 struct inode *inode = filp->f_path.dentry->d_inode;
Linus Torvalds1da177e2005-04-16 15:20:36 -07001035 int mode = TAPE_MODE(inode);
1036
1037 STp->ready = ST_READY;
1038
1039 if (mode != STp->current_mode) {
1040 DEBC(printk(ST_DEB_MSG "%s: Mode change from %d to %d.\n",
1041 name, STp->current_mode, mode));
1042 new_session = 1;
1043 STp->current_mode = mode;
1044 }
1045 STm = &(STp->modes[STp->current_mode]);
1046
1047 saved_cleaning = STp->cleaning_req;
1048 STp->cleaning_req = 0;
1049
1050 do_wait = ((filp->f_flags & O_NONBLOCK) == 0);
1051 retval = test_ready(STp, do_wait);
1052
1053 if (retval < 0)
1054 goto err_out;
1055
1056 if (retval == CHKRES_NEW_SESSION) {
1057 STp->pos_unknown = 0;
1058 STp->partition = STp->new_partition = 0;
1059 if (STp->can_partitions)
1060 STp->nbr_partitions = 1; /* This guess will be updated later
1061 if necessary */
1062 for (i = 0; i < ST_NBR_PARTITIONS; i++) {
1063 STps = &(STp->ps[i]);
1064 STps->rw = ST_IDLE;
1065 STps->eof = ST_NOEOF;
1066 STps->at_sm = 0;
1067 STps->last_block_valid = 0;
1068 STps->drv_block = 0;
1069 STps->drv_file = 0;
1070 }
1071 new_session = 1;
1072 }
1073 else {
1074 STp->cleaning_req |= saved_cleaning;
1075
1076 if (retval == CHKRES_NOT_READY || retval == CHKRES_NO_TAPE) {
1077 if (retval == CHKRES_NO_TAPE)
1078 STp->ready = ST_NO_TAPE;
1079 else
1080 STp->ready = ST_NOT_READY;
1081
1082 STp->density = 0; /* Clear the erroneous "residue" */
1083 STp->write_prot = 0;
1084 STp->block_size = 0;
1085 STp->ps[0].drv_file = STp->ps[0].drv_block = (-1);
1086 STp->partition = STp->new_partition = 0;
1087 STp->door_locked = ST_UNLOCKED;
1088 return CHKRES_NOT_READY;
1089 }
1090 }
1091
FUJITA Tomonori52107b22008-12-05 15:25:27 +09001092 SRpnt = st_allocate_request(STp);
1093 if (!SRpnt) {
1094 retval = STp->buffer->syscall_result;
1095 goto err_out;
1096 }
1097
Linus Torvalds1da177e2005-04-16 15:20:36 -07001098 if (STp->omit_blklims)
1099 STp->min_block = STp->max_block = (-1);
1100 else {
1101 memset((void *) &cmd[0], 0, MAX_COMMAND_SIZE);
1102 cmd[0] = READ_BLOCK_LIMITS;
1103
FUJITA Tomonori52107b22008-12-05 15:25:27 +09001104 retval = st_scsi_kern_execute(SRpnt, cmd, DMA_FROM_DEVICE,
1105 STp->buffer->b_data, 6,
1106 STp->device->request_queue->rq_timeout,
1107 MAX_READY_RETRIES);
1108 if (retval) {
1109 st_release_request(SRpnt);
Linus Torvalds1da177e2005-04-16 15:20:36 -07001110 goto err_out;
1111 }
1112
Mike Christie8b05b772005-11-08 04:06:44 -06001113 if (!SRpnt->result && !STp->buffer->cmdstat.have_sense) {
Linus Torvalds1da177e2005-04-16 15:20:36 -07001114 STp->max_block = ((STp->buffer)->b_data[1] << 16) |
1115 ((STp->buffer)->b_data[2] << 8) | (STp->buffer)->b_data[3];
1116 STp->min_block = ((STp->buffer)->b_data[4] << 8) |
1117 (STp->buffer)->b_data[5];
1118 if ( DEB( debugging || ) !STp->inited)
Kai Makisara42252852006-11-07 21:56:38 +02001119 printk(KERN_INFO
Linus Torvalds1da177e2005-04-16 15:20:36 -07001120 "%s: Block limits %d - %d bytes.\n", name,
1121 STp->min_block, STp->max_block);
1122 } else {
1123 STp->min_block = STp->max_block = (-1);
1124 DEBC(printk(ST_DEB_MSG "%s: Can't read block limits.\n",
1125 name));
1126 }
1127 }
1128
1129 memset((void *) &cmd[0], 0, MAX_COMMAND_SIZE);
1130 cmd[0] = MODE_SENSE;
1131 cmd[4] = 12;
1132
FUJITA Tomonori52107b22008-12-05 15:25:27 +09001133 retval = st_scsi_kern_execute(SRpnt, cmd, DMA_FROM_DEVICE,
1134 STp->buffer->b_data, 12,
1135 STp->device->request_queue->rq_timeout,
1136 MAX_READY_RETRIES);
1137 if (retval) {
1138 st_release_request(SRpnt);
Linus Torvalds1da177e2005-04-16 15:20:36 -07001139 goto err_out;
1140 }
1141
1142 if ((STp->buffer)->syscall_result != 0) {
1143 DEBC(printk(ST_DEB_MSG "%s: No Mode Sense.\n", name));
1144 STp->block_size = ST_DEFAULT_BLOCK; /* Educated guess (?) */
1145 (STp->buffer)->syscall_result = 0; /* Prevent error propagation */
1146 STp->drv_write_prot = 0;
1147 } else {
1148 DEBC(printk(ST_DEB_MSG
1149 "%s: Mode sense. Length %d, medium %x, WBS %x, BLL %d\n",
1150 name,
1151 (STp->buffer)->b_data[0], (STp->buffer)->b_data[1],
1152 (STp->buffer)->b_data[2], (STp->buffer)->b_data[3]));
1153
1154 if ((STp->buffer)->b_data[3] >= 8) {
1155 STp->drv_buffer = ((STp->buffer)->b_data[2] >> 4) & 7;
1156 STp->density = (STp->buffer)->b_data[4];
1157 STp->block_size = (STp->buffer)->b_data[9] * 65536 +
1158 (STp->buffer)->b_data[10] * 256 + (STp->buffer)->b_data[11];
1159 DEBC(printk(ST_DEB_MSG
1160 "%s: Density %x, tape length: %x, drv buffer: %d\n",
1161 name, STp->density, (STp->buffer)->b_data[5] * 65536 +
1162 (STp->buffer)->b_data[6] * 256 + (STp->buffer)->b_data[7],
1163 STp->drv_buffer));
1164 }
1165 STp->drv_write_prot = ((STp->buffer)->b_data[2] & 0x80) != 0;
1166 }
Mike Christie8b05b772005-11-08 04:06:44 -06001167 st_release_request(SRpnt);
Linus Torvalds1da177e2005-04-16 15:20:36 -07001168 SRpnt = NULL;
1169 STp->inited = 1;
1170
1171 if (STp->block_size > 0)
1172 (STp->buffer)->buffer_blocks =
1173 (STp->buffer)->buffer_size / STp->block_size;
1174 else
1175 (STp->buffer)->buffer_blocks = 1;
1176 (STp->buffer)->buffer_bytes = (STp->buffer)->read_pointer = 0;
1177
1178 DEBC(printk(ST_DEB_MSG
1179 "%s: Block size: %d, buffer size: %d (%d blocks).\n", name,
1180 STp->block_size, (STp->buffer)->buffer_size,
1181 (STp->buffer)->buffer_blocks));
1182
1183 if (STp->drv_write_prot) {
1184 STp->write_prot = 1;
1185
1186 DEBC(printk(ST_DEB_MSG "%s: Write protected\n", name));
1187
1188 if (do_wait &&
1189 ((st_flags & O_ACCMODE) == O_WRONLY ||
1190 (st_flags & O_ACCMODE) == O_RDWR)) {
1191 retval = (-EROFS);
1192 goto err_out;
1193 }
1194 }
1195
1196 if (STp->can_partitions && STp->nbr_partitions < 1) {
1197 /* This code is reached when the device is opened for the first time
1198 after the driver has been initialized with tape in the drive and the
1199 partition support has been enabled. */
1200 DEBC(printk(ST_DEB_MSG
1201 "%s: Updating partition number in status.\n", name));
1202 if ((STp->partition = find_partition(STp)) < 0) {
1203 retval = STp->partition;
1204 goto err_out;
1205 }
1206 STp->new_partition = STp->partition;
1207 STp->nbr_partitions = 1; /* This guess will be updated when necessary */
1208 }
1209
1210 if (new_session) { /* Change the drive parameters for the new mode */
1211 STp->density_changed = STp->blksize_changed = 0;
1212 STp->compression_changed = 0;
1213 if (!(STm->defaults_for_writes) &&
1214 (retval = set_mode_densblk(STp, STm)) < 0)
1215 goto err_out;
1216
1217 if (STp->default_drvbuffer != 0xff) {
1218 if (st_int_ioctl(STp, MTSETDRVBUFFER, STp->default_drvbuffer))
1219 printk(KERN_WARNING
1220 "%s: Can't set default drive buffering to %d.\n",
1221 name, STp->default_drvbuffer);
1222 }
1223 }
1224
1225 return CHKRES_READY;
1226
1227 err_out:
1228 return retval;
1229}
1230
1231
Jonathan Corbetb3369c62008-05-15 16:08:15 -06001232 /* Open the device. Needs to take the BKL only because of incrementing the SCSI host
Linus Torvalds1da177e2005-04-16 15:20:36 -07001233 module count. */
1234static int st_open(struct inode *inode, struct file *filp)
1235{
1236 int i, retval = (-EIO);
1237 struct scsi_tape *STp;
1238 struct st_partstat *STps;
1239 int dev = TAPE_NR(inode);
1240 char *name;
1241
Jonathan Corbetb3369c62008-05-15 16:08:15 -06001242 lock_kernel();
Linus Torvalds1da177e2005-04-16 15:20:36 -07001243 /*
1244 * We really want to do nonseekable_open(inode, filp); here, but some
1245 * versions of tar incorrectly call lseek on tapes and bail out if that
1246 * fails. So we disallow pread() and pwrite(), but permit lseeks.
1247 */
1248 filp->f_mode &= ~(FMODE_PREAD | FMODE_PWRITE);
1249
Jonathan Corbetb3369c62008-05-15 16:08:15 -06001250 if (!(STp = scsi_tape_get(dev))) {
1251 unlock_kernel();
Kai Makisaraf03a5672005-08-02 13:40:47 +03001252 return -ENXIO;
Jonathan Corbetb3369c62008-05-15 16:08:15 -06001253 }
Kai Makisaraf03a5672005-08-02 13:40:47 +03001254
Linus Torvalds1da177e2005-04-16 15:20:36 -07001255 write_lock(&st_dev_arr_lock);
Linus Torvalds1da177e2005-04-16 15:20:36 -07001256 filp->private_data = STp;
1257 name = tape_name(STp);
1258
1259 if (STp->in_use) {
1260 write_unlock(&st_dev_arr_lock);
Kai Makisaraf03a5672005-08-02 13:40:47 +03001261 scsi_tape_put(STp);
Jonathan Corbetb3369c62008-05-15 16:08:15 -06001262 unlock_kernel();
Linus Torvalds1da177e2005-04-16 15:20:36 -07001263 DEB( printk(ST_DEB_MSG "%s: Device already in use.\n", name); )
1264 return (-EBUSY);
1265 }
1266
Linus Torvalds1da177e2005-04-16 15:20:36 -07001267 STp->in_use = 1;
1268 write_unlock(&st_dev_arr_lock);
1269 STp->rew_at_close = STp->autorew_dev = (iminor(inode) & 0x80) == 0;
1270
1271 if (!scsi_block_when_processing_errors(STp->device)) {
1272 retval = (-ENXIO);
1273 goto err_out;
1274 }
1275
1276 /* See that we have at least a one page buffer available */
1277 if (!enlarge_buffer(STp->buffer, PAGE_SIZE, STp->restr_dma)) {
1278 printk(KERN_WARNING "%s: Can't allocate one page tape buffer.\n",
1279 name);
1280 retval = (-EOVERFLOW);
1281 goto err_out;
1282 }
1283
Kai Makisara40f6b362008-02-24 22:23:24 +02001284 (STp->buffer)->cleared = 0;
Linus Torvalds1da177e2005-04-16 15:20:36 -07001285 (STp->buffer)->writing = 0;
1286 (STp->buffer)->syscall_result = 0;
1287
1288 STp->write_prot = ((filp->f_flags & O_ACCMODE) == O_RDONLY);
1289
1290 STp->dirty = 0;
1291 for (i = 0; i < ST_NBR_PARTITIONS; i++) {
1292 STps = &(STp->ps[i]);
1293 STps->rw = ST_IDLE;
1294 }
Kai Makisara9abe16c2007-02-03 13:21:29 +02001295 STp->try_dio_now = STp->try_dio;
Linus Torvalds1da177e2005-04-16 15:20:36 -07001296 STp->recover_count = 0;
1297 DEB( STp->nbr_waits = STp->nbr_finished = 0;
Kai Makisaradeee13d2008-02-22 20:11:21 +02001298 STp->nbr_requests = STp->nbr_dio = STp->nbr_pages = 0; )
Linus Torvalds1da177e2005-04-16 15:20:36 -07001299
1300 retval = check_tape(STp, filp);
1301 if (retval < 0)
1302 goto err_out;
1303 if ((filp->f_flags & O_NONBLOCK) == 0 &&
1304 retval != CHKRES_READY) {
Kai Makisara413f7322006-10-05 22:59:46 +03001305 if (STp->ready == NO_TAPE)
1306 retval = (-ENOMEDIUM);
1307 else
1308 retval = (-EIO);
Linus Torvalds1da177e2005-04-16 15:20:36 -07001309 goto err_out;
1310 }
Jonathan Corbetb3369c62008-05-15 16:08:15 -06001311 unlock_kernel();
Linus Torvalds1da177e2005-04-16 15:20:36 -07001312 return 0;
1313
1314 err_out:
1315 normalize_buffer(STp->buffer);
1316 STp->in_use = 0;
Kai Makisaraf03a5672005-08-02 13:40:47 +03001317 scsi_tape_put(STp);
Jonathan Corbetb3369c62008-05-15 16:08:15 -06001318 unlock_kernel();
Linus Torvalds1da177e2005-04-16 15:20:36 -07001319 return retval;
1320
1321}
1322
1323
1324/* Flush the tape buffer before close */
Miklos Szeredi75e1fcc2006-06-23 02:05:12 -07001325static int st_flush(struct file *filp, fl_owner_t id)
Linus Torvalds1da177e2005-04-16 15:20:36 -07001326{
1327 int result = 0, result2;
1328 unsigned char cmd[MAX_COMMAND_SIZE];
Mike Christie8b05b772005-11-08 04:06:44 -06001329 struct st_request *SRpnt;
Linus Torvalds1da177e2005-04-16 15:20:36 -07001330 struct scsi_tape *STp = filp->private_data;
1331 struct st_modedef *STm = &(STp->modes[STp->current_mode]);
1332 struct st_partstat *STps = &(STp->ps[STp->partition]);
1333 char *name = tape_name(STp);
1334
1335 if (file_count(filp) > 1)
1336 return 0;
1337
1338 if (STps->rw == ST_WRITING && !STp->pos_unknown) {
Adrian Bunk8ef8d592008-04-14 17:17:16 +03001339 result = st_flush_write_buffer(STp);
Linus Torvalds1da177e2005-04-16 15:20:36 -07001340 if (result != 0 && result != (-ENOSPC))
1341 goto out;
1342 }
1343
1344 if (STp->can_partitions &&
1345 (result2 = switch_partition(STp)) < 0) {
1346 DEBC(printk(ST_DEB_MSG
1347 "%s: switch_partition at close failed.\n", name));
1348 if (result == 0)
1349 result = result2;
1350 goto out;
1351 }
1352
1353 DEBC( if (STp->nbr_requests)
Kai Makisaradeee13d2008-02-22 20:11:21 +02001354 printk(KERN_DEBUG "%s: Number of r/w requests %d, dio used in %d, pages %d.\n",
1355 name, STp->nbr_requests, STp->nbr_dio, STp->nbr_pages));
Linus Torvalds1da177e2005-04-16 15:20:36 -07001356
1357 if (STps->rw == ST_WRITING && !STp->pos_unknown) {
1358 struct st_cmdstatus *cmdstatp = &STp->buffer->cmdstat;
1359
1360 DEBC(printk(ST_DEB_MSG "%s: Async write waits %d, finished %d.\n",
1361 name, STp->nbr_waits, STp->nbr_finished);
1362 )
1363
1364 memset(cmd, 0, MAX_COMMAND_SIZE);
1365 cmd[0] = WRITE_FILEMARKS;
1366 cmd[4] = 1 + STp->two_fm;
1367
FUJITA Tomonori212cd8b2008-12-05 15:25:26 +09001368 SRpnt = st_allocate_request(STp);
Linus Torvalds1da177e2005-04-16 15:20:36 -07001369 if (!SRpnt) {
FUJITA Tomonori212cd8b2008-12-05 15:25:26 +09001370 result = STp->buffer->syscall_result;
1371 goto out;
1372 }
1373
1374 result = st_scsi_kern_execute(SRpnt, cmd, DMA_NONE, NULL, 0,
1375 STp->device->request_queue->rq_timeout,
1376 MAX_WRITE_RETRIES);
1377 if (result) {
1378 st_release_request(SRpnt);
Linus Torvalds1da177e2005-04-16 15:20:36 -07001379 goto out;
1380 }
1381
1382 if (STp->buffer->syscall_result == 0 ||
1383 (cmdstatp->have_sense && !cmdstatp->deferred &&
1384 (cmdstatp->flags & SENSE_EOM) &&
1385 (cmdstatp->sense_hdr.sense_key == NO_SENSE ||
1386 cmdstatp->sense_hdr.sense_key == RECOVERED_ERROR) &&
1387 (!cmdstatp->remainder_valid || cmdstatp->uremainder64 == 0))) {
1388 /* Write successful at EOM */
Mike Christie8b05b772005-11-08 04:06:44 -06001389 st_release_request(SRpnt);
Linus Torvalds1da177e2005-04-16 15:20:36 -07001390 SRpnt = NULL;
1391 if (STps->drv_file >= 0)
1392 STps->drv_file++;
1393 STps->drv_block = 0;
1394 if (STp->two_fm)
1395 cross_eof(STp, 0);
1396 STps->eof = ST_FM;
1397 }
1398 else { /* Write error */
Mike Christie8b05b772005-11-08 04:06:44 -06001399 st_release_request(SRpnt);
Linus Torvalds1da177e2005-04-16 15:20:36 -07001400 SRpnt = NULL;
1401 printk(KERN_ERR "%s: Error on write filemark.\n", name);
1402 if (result == 0)
1403 result = (-EIO);
1404 }
1405
1406 DEBC(printk(ST_DEB_MSG "%s: Buffer flushed, %d EOF(s) written\n",
1407 name, cmd[4]));
1408 } else if (!STp->rew_at_close) {
1409 STps = &(STp->ps[STp->partition]);
1410 if (!STm->sysv || STps->rw != ST_READING) {
1411 if (STp->can_bsr)
1412 result = flush_buffer(STp, 0);
1413 else if (STps->eof == ST_FM_HIT) {
1414 result = cross_eof(STp, 0);
1415 if (result) {
1416 if (STps->drv_file >= 0)
1417 STps->drv_file++;
1418 STps->drv_block = 0;
1419 STps->eof = ST_FM;
1420 } else
1421 STps->eof = ST_NOEOF;
1422 }
1423 } else if ((STps->eof == ST_NOEOF &&
1424 !(result = cross_eof(STp, 1))) ||
1425 STps->eof == ST_FM_HIT) {
1426 if (STps->drv_file >= 0)
1427 STps->drv_file++;
1428 STps->drv_block = 0;
1429 STps->eof = ST_FM;
1430 }
1431 }
1432
1433 out:
1434 if (STp->rew_at_close) {
1435 result2 = st_int_ioctl(STp, MTREW, 1);
1436 if (result == 0)
1437 result = result2;
1438 }
1439 return result;
1440}
1441
1442
1443/* Close the device and release it. BKL is not needed: this is the only thread
1444 accessing this tape. */
1445static int st_release(struct inode *inode, struct file *filp)
1446{
1447 int result = 0;
1448 struct scsi_tape *STp = filp->private_data;
1449
1450 if (STp->door_locked == ST_LOCKED_AUTO)
1451 do_door_lock(STp, 0);
1452
1453 normalize_buffer(STp->buffer);
1454 write_lock(&st_dev_arr_lock);
1455 STp->in_use = 0;
1456 write_unlock(&st_dev_arr_lock);
Kai Makisaraf03a5672005-08-02 13:40:47 +03001457 scsi_tape_put(STp);
Linus Torvalds1da177e2005-04-16 15:20:36 -07001458
1459 return result;
1460}
1461
1462/* The checks common to both reading and writing */
1463static ssize_t rw_checks(struct scsi_tape *STp, struct file *filp, size_t count)
1464{
1465 ssize_t retval = 0;
1466
1467 /*
1468 * If we are in the middle of error recovery, don't let anyone
1469 * else try and use this device. Also, if error recovery fails, it
1470 * may try and take the device offline, in which case all further
1471 * access to the device is prohibited.
1472 */
1473 if (!scsi_block_when_processing_errors(STp->device)) {
1474 retval = (-ENXIO);
1475 goto out;
1476 }
1477
1478 if (STp->ready != ST_READY) {
1479 if (STp->ready == ST_NO_TAPE)
1480 retval = (-ENOMEDIUM);
1481 else
1482 retval = (-EIO);
1483 goto out;
1484 }
1485
1486 if (! STp->modes[STp->current_mode].defined) {
1487 retval = (-ENXIO);
1488 goto out;
1489 }
1490
1491
1492 /*
1493 * If there was a bus reset, block further access
1494 * to this device.
1495 */
1496 if (STp->pos_unknown) {
1497 retval = (-EIO);
1498 goto out;
1499 }
1500
1501 if (count == 0)
1502 goto out;
1503
1504 DEB(
1505 if (!STp->in_use) {
1506 printk(ST_DEB_MSG "%s: Incorrect device.\n", tape_name(STp));
1507 retval = (-EIO);
1508 goto out;
1509 } ) /* end DEB */
1510
1511 if (STp->can_partitions &&
1512 (retval = switch_partition(STp)) < 0)
1513 goto out;
1514
1515 if (STp->block_size == 0 && STp->max_block > 0 &&
1516 (count < STp->min_block || count > STp->max_block)) {
1517 retval = (-EINVAL);
1518 goto out;
1519 }
1520
1521 if (STp->do_auto_lock && STp->door_locked == ST_UNLOCKED &&
1522 !do_door_lock(STp, 1))
1523 STp->door_locked = ST_LOCKED_AUTO;
1524
1525 out:
1526 return retval;
1527}
1528
1529
1530static int setup_buffering(struct scsi_tape *STp, const char __user *buf,
1531 size_t count, int is_read)
1532{
1533 int i, bufsize, retval = 0;
1534 struct st_buffer *STbp = STp->buffer;
1535
1536 if (is_read)
Kai Makisara9abe16c2007-02-03 13:21:29 +02001537 i = STp->try_dio_now && try_rdio;
Linus Torvalds1da177e2005-04-16 15:20:36 -07001538 else
Kai Makisara9abe16c2007-02-03 13:21:29 +02001539 i = STp->try_dio_now && try_wdio;
Mike Christie8b05b772005-11-08 04:06:44 -06001540
Linus Torvalds1da177e2005-04-16 15:20:36 -07001541 if (i && ((unsigned long)buf & queue_dma_alignment(
1542 STp->device->request_queue)) == 0) {
Mike Christie8b05b772005-11-08 04:06:44 -06001543 i = sgl_map_user_pages(&(STbp->sg[0]), STbp->use_sg,
1544 (unsigned long)buf, count, (is_read ? READ : WRITE));
Linus Torvalds1da177e2005-04-16 15:20:36 -07001545 if (i > 0) {
1546 STbp->do_dio = i;
1547 STbp->buffer_bytes = 0; /* can be used as transfer counter */
1548 }
1549 else
1550 STbp->do_dio = 0; /* fall back to buffering with any error */
1551 STbp->sg_segs = STbp->do_dio;
1552 STbp->frp_sg_current = 0;
1553 DEB(
1554 if (STbp->do_dio) {
1555 STp->nbr_dio++;
1556 STp->nbr_pages += STbp->do_dio;
Linus Torvalds1da177e2005-04-16 15:20:36 -07001557 }
1558 )
1559 } else
1560 STbp->do_dio = 0;
1561 DEB( STp->nbr_requests++; )
1562
1563 if (!STbp->do_dio) {
1564 if (STp->block_size)
1565 bufsize = STp->block_size > st_fixed_buffer_size ?
1566 STp->block_size : st_fixed_buffer_size;
Kai Makisara40f6b362008-02-24 22:23:24 +02001567 else {
Linus Torvalds1da177e2005-04-16 15:20:36 -07001568 bufsize = count;
Kai Makisara40f6b362008-02-24 22:23:24 +02001569 /* Make sure that data from previous user is not leaked even if
1570 HBA does not return correct residual */
1571 if (is_read && STp->sili && !STbp->cleared)
1572 clear_buffer(STbp);
1573 }
1574
Linus Torvalds1da177e2005-04-16 15:20:36 -07001575 if (bufsize > STbp->buffer_size &&
1576 !enlarge_buffer(STbp, bufsize, STp->restr_dma)) {
1577 printk(KERN_WARNING "%s: Can't allocate %d byte tape buffer.\n",
1578 tape_name(STp), bufsize);
1579 retval = (-EOVERFLOW);
1580 goto out;
1581 }
1582 if (STp->block_size)
1583 STbp->buffer_blocks = bufsize / STp->block_size;
1584 }
1585
1586 out:
1587 return retval;
1588}
1589
1590
1591/* Can be called more than once after each setup_buffer() */
Kai Makisara787926b2005-11-13 10:04:44 +02001592static void release_buffering(struct scsi_tape *STp, int is_read)
Linus Torvalds1da177e2005-04-16 15:20:36 -07001593{
1594 struct st_buffer *STbp;
1595
1596 STbp = STp->buffer;
1597 if (STbp->do_dio) {
Kai Makisara787926b2005-11-13 10:04:44 +02001598 sgl_unmap_user_pages(&(STbp->sg[0]), STbp->do_dio, is_read);
Linus Torvalds1da177e2005-04-16 15:20:36 -07001599 STbp->do_dio = 0;
Kai Makisara787926b2005-11-13 10:04:44 +02001600 STbp->sg_segs = 0;
Linus Torvalds1da177e2005-04-16 15:20:36 -07001601 }
1602}
1603
1604
1605/* Write command */
1606static ssize_t
1607st_write(struct file *filp, const char __user *buf, size_t count, loff_t * ppos)
1608{
1609 ssize_t total;
1610 ssize_t i, do_count, blks, transfer;
1611 ssize_t retval;
1612 int undone, retry_eot = 0, scode;
1613 int async_write;
1614 unsigned char cmd[MAX_COMMAND_SIZE];
1615 const char __user *b_point;
Mike Christie8b05b772005-11-08 04:06:44 -06001616 struct st_request *SRpnt = NULL;
Linus Torvalds1da177e2005-04-16 15:20:36 -07001617 struct scsi_tape *STp = filp->private_data;
1618 struct st_modedef *STm;
1619 struct st_partstat *STps;
1620 struct st_buffer *STbp;
1621 char *name = tape_name(STp);
1622
Matthias Kaehlcke28f85002007-07-29 23:38:15 +02001623 if (mutex_lock_interruptible(&STp->lock))
Linus Torvalds1da177e2005-04-16 15:20:36 -07001624 return -ERESTARTSYS;
1625
1626 retval = rw_checks(STp, filp, count);
1627 if (retval || count == 0)
1628 goto out;
1629
1630 /* Write must be integral number of blocks */
1631 if (STp->block_size != 0 && (count % STp->block_size) != 0) {
1632 printk(KERN_WARNING "%s: Write not multiple of tape block size.\n",
1633 name);
1634 retval = (-EINVAL);
1635 goto out;
1636 }
1637
1638 STm = &(STp->modes[STp->current_mode]);
1639 STps = &(STp->ps[STp->partition]);
1640
1641 if (STp->write_prot) {
1642 retval = (-EACCES);
1643 goto out;
1644 }
1645
1646
1647 if (STps->rw == ST_READING) {
1648 retval = flush_buffer(STp, 0);
1649 if (retval)
1650 goto out;
1651 STps->rw = ST_WRITING;
1652 } else if (STps->rw != ST_WRITING &&
1653 STps->drv_file == 0 && STps->drv_block == 0) {
1654 if ((retval = set_mode_densblk(STp, STm)) < 0)
1655 goto out;
1656 if (STm->default_compression != ST_DONT_TOUCH &&
1657 !(STp->compression_changed)) {
1658 if (st_compression(STp, (STm->default_compression == ST_YES))) {
1659 printk(KERN_WARNING "%s: Can't set default compression.\n",
1660 name);
1661 if (modes_defined) {
1662 retval = (-EINVAL);
1663 goto out;
1664 }
1665 }
1666 }
1667 }
1668
1669 STbp = STp->buffer;
1670 i = write_behind_check(STp);
1671 if (i) {
1672 if (i == -ENOSPC)
1673 STps->eof = ST_EOM_OK;
1674 else
1675 STps->eof = ST_EOM_ERROR;
1676 }
1677
1678 if (STps->eof == ST_EOM_OK) {
1679 STps->eof = ST_EOD_1; /* allow next write */
1680 retval = (-ENOSPC);
1681 goto out;
1682 }
1683 else if (STps->eof == ST_EOM_ERROR) {
1684 retval = (-EIO);
1685 goto out;
1686 }
1687
1688 /* Check the buffer readability in cases where copy_user might catch
1689 the problems after some tape movement. */
1690 if (STp->block_size != 0 &&
1691 !STbp->do_dio &&
1692 (copy_from_user(&i, buf, 1) != 0 ||
1693 copy_from_user(&i, buf + count - 1, 1) != 0)) {
1694 retval = (-EFAULT);
1695 goto out;
1696 }
1697
1698 retval = setup_buffering(STp, buf, count, 0);
1699 if (retval)
1700 goto out;
1701
1702 total = count;
1703
1704 memset(cmd, 0, MAX_COMMAND_SIZE);
1705 cmd[0] = WRITE_6;
1706 cmd[1] = (STp->block_size != 0);
1707
1708 STps->rw = ST_WRITING;
1709
1710 b_point = buf;
1711 while (count > 0 && !retry_eot) {
1712
1713 if (STbp->do_dio) {
1714 do_count = count;
1715 }
1716 else {
1717 if (STp->block_size == 0)
1718 do_count = count;
1719 else {
1720 do_count = STbp->buffer_blocks * STp->block_size -
1721 STbp->buffer_bytes;
1722 if (do_count > count)
1723 do_count = count;
1724 }
1725
1726 i = append_to_buffer(b_point, STbp, do_count);
1727 if (i) {
1728 retval = i;
1729 goto out;
1730 }
1731 }
1732 count -= do_count;
1733 b_point += do_count;
1734
1735 async_write = STp->block_size == 0 && !STbp->do_dio &&
1736 STm->do_async_writes && STps->eof < ST_EOM_OK;
1737
1738 if (STp->block_size != 0 && STm->do_buffer_writes &&
Kai Makisara9abe16c2007-02-03 13:21:29 +02001739 !(STp->try_dio_now && try_wdio) && STps->eof < ST_EOM_OK &&
Linus Torvalds1da177e2005-04-16 15:20:36 -07001740 STbp->buffer_bytes < STbp->buffer_size) {
1741 STp->dirty = 1;
1742 /* Don't write a buffer that is not full enough. */
1743 if (!async_write && count == 0)
1744 break;
1745 }
1746
1747 retry_write:
1748 if (STp->block_size == 0)
1749 blks = transfer = do_count;
1750 else {
1751 if (!STbp->do_dio)
1752 blks = STbp->buffer_bytes;
1753 else
1754 blks = do_count;
1755 blks /= STp->block_size;
1756 transfer = blks * STp->block_size;
1757 }
1758 cmd[2] = blks >> 16;
1759 cmd[3] = blks >> 8;
1760 cmd[4] = blks;
1761
1762 SRpnt = st_do_scsi(SRpnt, STp, cmd, transfer, DMA_TO_DEVICE,
James Bottomleya02488e2008-11-30 10:36:26 -06001763 STp->device->request_queue->rq_timeout,
1764 MAX_WRITE_RETRIES, !async_write);
Linus Torvalds1da177e2005-04-16 15:20:36 -07001765 if (!SRpnt) {
1766 retval = STbp->syscall_result;
1767 goto out;
1768 }
Mike Christie8b05b772005-11-08 04:06:44 -06001769 if (async_write && !STbp->syscall_result) {
Linus Torvalds1da177e2005-04-16 15:20:36 -07001770 STbp->writing = transfer;
1771 STp->dirty = !(STbp->writing ==
1772 STbp->buffer_bytes);
1773 SRpnt = NULL; /* Prevent releasing this request! */
1774 DEB( STp->write_pending = 1; )
1775 break;
1776 }
1777
1778 if (STbp->syscall_result != 0) {
1779 struct st_cmdstatus *cmdstatp = &STp->buffer->cmdstat;
1780
1781 DEBC(printk(ST_DEB_MSG "%s: Error on write:\n", name));
1782 if (cmdstatp->have_sense && (cmdstatp->flags & SENSE_EOM)) {
1783 scode = cmdstatp->sense_hdr.sense_key;
1784 if (cmdstatp->remainder_valid)
1785 undone = (int)cmdstatp->uremainder64;
1786 else if (STp->block_size == 0 &&
1787 scode == VOLUME_OVERFLOW)
1788 undone = transfer;
1789 else
1790 undone = 0;
1791 if (STp->block_size != 0)
1792 undone *= STp->block_size;
1793 if (undone <= do_count) {
1794 /* Only data from this write is not written */
1795 count += undone;
Kai Makisara626dcb12008-07-11 15:05:25 +03001796 b_point -= undone;
Linus Torvalds1da177e2005-04-16 15:20:36 -07001797 do_count -= undone;
1798 if (STp->block_size)
1799 blks = (transfer - undone) / STp->block_size;
1800 STps->eof = ST_EOM_OK;
1801 /* Continue in fixed block mode if all written
1802 in this request but still something left to write
1803 (retval left to zero)
1804 */
1805 if (STp->block_size == 0 ||
1806 undone > 0 || count == 0)
1807 retval = (-ENOSPC); /* EOM within current request */
1808 DEBC(printk(ST_DEB_MSG
1809 "%s: EOM with %d bytes unwritten.\n",
1810 name, (int)count));
1811 } else {
1812 /* EOT within data buffered earlier (possible only
1813 in fixed block mode without direct i/o) */
1814 if (!retry_eot && !cmdstatp->deferred &&
1815 (scode == NO_SENSE || scode == RECOVERED_ERROR)) {
1816 move_buffer_data(STp->buffer, transfer - undone);
1817 retry_eot = 1;
1818 if (STps->drv_block >= 0) {
1819 STps->drv_block += (transfer - undone) /
1820 STp->block_size;
1821 }
1822 STps->eof = ST_EOM_OK;
1823 DEBC(printk(ST_DEB_MSG
1824 "%s: Retry write of %d bytes at EOM.\n",
1825 name, STp->buffer->buffer_bytes));
1826 goto retry_write;
1827 }
1828 else {
1829 /* Either error within data buffered by driver or
1830 failed retry */
1831 count -= do_count;
1832 blks = do_count = 0;
1833 STps->eof = ST_EOM_ERROR;
1834 STps->drv_block = (-1); /* Too cautious? */
1835 retval = (-EIO); /* EOM for old data */
1836 DEBC(printk(ST_DEB_MSG
1837 "%s: EOM with lost data.\n",
1838 name));
1839 }
1840 }
1841 } else {
1842 count += do_count;
1843 STps->drv_block = (-1); /* Too cautious? */
Mike Christie8b05b772005-11-08 04:06:44 -06001844 retval = STbp->syscall_result;
Linus Torvalds1da177e2005-04-16 15:20:36 -07001845 }
1846
1847 }
1848
1849 if (STps->drv_block >= 0) {
1850 if (STp->block_size == 0)
1851 STps->drv_block += (do_count > 0);
1852 else
1853 STps->drv_block += blks;
1854 }
1855
1856 STbp->buffer_bytes = 0;
1857 STp->dirty = 0;
1858
1859 if (retval || retry_eot) {
1860 if (count < total)
1861 retval = total - count;
1862 goto out;
1863 }
1864 }
1865
1866 if (STps->eof == ST_EOD_1)
1867 STps->eof = ST_EOM_OK;
1868 else if (STps->eof != ST_EOM_OK)
1869 STps->eof = ST_NOEOF;
1870 retval = total - count;
1871
1872 out:
1873 if (SRpnt != NULL)
Mike Christie8b05b772005-11-08 04:06:44 -06001874 st_release_request(SRpnt);
Kai Makisara787926b2005-11-13 10:04:44 +02001875 release_buffering(STp, 0);
Matthias Kaehlcke28f85002007-07-29 23:38:15 +02001876 mutex_unlock(&STp->lock);
Linus Torvalds1da177e2005-04-16 15:20:36 -07001877
1878 return retval;
1879}
1880
1881/* Read data from the tape. Returns zero in the normal case, one if the
1882 eof status has changed, and the negative error code in case of a
1883 fatal error. Otherwise updates the buffer and the eof state.
1884
1885 Does release user buffer mapping if it is set.
1886*/
1887static long read_tape(struct scsi_tape *STp, long count,
Mike Christie8b05b772005-11-08 04:06:44 -06001888 struct st_request ** aSRpnt)
Linus Torvalds1da177e2005-04-16 15:20:36 -07001889{
1890 int transfer, blks, bytes;
1891 unsigned char cmd[MAX_COMMAND_SIZE];
Mike Christie8b05b772005-11-08 04:06:44 -06001892 struct st_request *SRpnt;
Linus Torvalds1da177e2005-04-16 15:20:36 -07001893 struct st_modedef *STm;
1894 struct st_partstat *STps;
1895 struct st_buffer *STbp;
1896 int retval = 0;
1897 char *name = tape_name(STp);
1898
1899 if (count == 0)
1900 return 0;
1901
1902 STm = &(STp->modes[STp->current_mode]);
1903 STps = &(STp->ps[STp->partition]);
1904 if (STps->eof == ST_FM_HIT)
1905 return 1;
1906 STbp = STp->buffer;
1907
1908 if (STp->block_size == 0)
1909 blks = bytes = count;
1910 else {
Kai Makisara9abe16c2007-02-03 13:21:29 +02001911 if (!(STp->try_dio_now && try_rdio) && STm->do_read_ahead) {
Linus Torvalds1da177e2005-04-16 15:20:36 -07001912 blks = (STp->buffer)->buffer_blocks;
1913 bytes = blks * STp->block_size;
1914 } else {
1915 bytes = count;
1916 if (!STbp->do_dio && bytes > (STp->buffer)->buffer_size)
1917 bytes = (STp->buffer)->buffer_size;
1918 blks = bytes / STp->block_size;
1919 bytes = blks * STp->block_size;
1920 }
1921 }
1922
1923 memset(cmd, 0, MAX_COMMAND_SIZE);
1924 cmd[0] = READ_6;
1925 cmd[1] = (STp->block_size != 0);
Kai Makisara40f6b362008-02-24 22:23:24 +02001926 if (!cmd[1] && STp->sili)
1927 cmd[1] |= 2;
Linus Torvalds1da177e2005-04-16 15:20:36 -07001928 cmd[2] = blks >> 16;
1929 cmd[3] = blks >> 8;
1930 cmd[4] = blks;
1931
1932 SRpnt = *aSRpnt;
1933 SRpnt = st_do_scsi(SRpnt, STp, cmd, bytes, DMA_FROM_DEVICE,
James Bottomleya02488e2008-11-30 10:36:26 -06001934 STp->device->request_queue->rq_timeout,
1935 MAX_RETRIES, 1);
Kai Makisara787926b2005-11-13 10:04:44 +02001936 release_buffering(STp, 1);
Linus Torvalds1da177e2005-04-16 15:20:36 -07001937 *aSRpnt = SRpnt;
1938 if (!SRpnt)
1939 return STbp->syscall_result;
1940
1941 STbp->read_pointer = 0;
1942 STps->at_sm = 0;
1943
1944 /* Something to check */
1945 if (STbp->syscall_result) {
1946 struct st_cmdstatus *cmdstatp = &STp->buffer->cmdstat;
1947
1948 retval = 1;
1949 DEBC(printk(ST_DEB_MSG "%s: Sense: %2x %2x %2x %2x %2x %2x %2x %2x\n",
1950 name,
Mike Christie8b05b772005-11-08 04:06:44 -06001951 SRpnt->sense[0], SRpnt->sense[1],
1952 SRpnt->sense[2], SRpnt->sense[3],
1953 SRpnt->sense[4], SRpnt->sense[5],
1954 SRpnt->sense[6], SRpnt->sense[7]));
Linus Torvalds1da177e2005-04-16 15:20:36 -07001955 if (cmdstatp->have_sense) {
1956
1957 if (cmdstatp->sense_hdr.sense_key == BLANK_CHECK)
1958 cmdstatp->flags &= 0xcf; /* No need for EOM in this case */
1959
1960 if (cmdstatp->flags != 0) { /* EOF, EOM, or ILI */
1961 /* Compute the residual count */
1962 if (cmdstatp->remainder_valid)
1963 transfer = (int)cmdstatp->uremainder64;
1964 else
1965 transfer = 0;
1966 if (STp->block_size == 0 &&
1967 cmdstatp->sense_hdr.sense_key == MEDIUM_ERROR)
1968 transfer = bytes;
1969
1970 if (cmdstatp->flags & SENSE_ILI) { /* ILI */
1971 if (STp->block_size == 0) {
1972 if (transfer <= 0) {
1973 if (transfer < 0)
1974 printk(KERN_NOTICE
1975 "%s: Failed to read %d byte block with %d byte transfer.\n",
1976 name, bytes - transfer, bytes);
1977 if (STps->drv_block >= 0)
1978 STps->drv_block += 1;
1979 STbp->buffer_bytes = 0;
1980 return (-ENOMEM);
1981 }
1982 STbp->buffer_bytes = bytes - transfer;
1983 } else {
Mike Christie8b05b772005-11-08 04:06:44 -06001984 st_release_request(SRpnt);
Linus Torvalds1da177e2005-04-16 15:20:36 -07001985 SRpnt = *aSRpnt = NULL;
1986 if (transfer == blks) { /* We did not get anything, error */
1987 printk(KERN_NOTICE "%s: Incorrect block size.\n", name);
1988 if (STps->drv_block >= 0)
1989 STps->drv_block += blks - transfer + 1;
1990 st_int_ioctl(STp, MTBSR, 1);
1991 return (-EIO);
1992 }
1993 /* We have some data, deliver it */
1994 STbp->buffer_bytes = (blks - transfer) *
1995 STp->block_size;
1996 DEBC(printk(ST_DEB_MSG
1997 "%s: ILI but enough data received %ld %d.\n",
1998 name, count, STbp->buffer_bytes));
1999 if (STps->drv_block >= 0)
2000 STps->drv_block += 1;
2001 if (st_int_ioctl(STp, MTBSR, 1))
2002 return (-EIO);
2003 }
2004 } else if (cmdstatp->flags & SENSE_FMK) { /* FM overrides EOM */
2005 if (STps->eof != ST_FM_HIT)
2006 STps->eof = ST_FM_HIT;
2007 else
2008 STps->eof = ST_EOD_2;
2009 if (STp->block_size == 0)
2010 STbp->buffer_bytes = 0;
2011 else
2012 STbp->buffer_bytes =
2013 bytes - transfer * STp->block_size;
2014 DEBC(printk(ST_DEB_MSG
2015 "%s: EOF detected (%d bytes read).\n",
2016 name, STbp->buffer_bytes));
2017 } else if (cmdstatp->flags & SENSE_EOM) {
2018 if (STps->eof == ST_FM)
2019 STps->eof = ST_EOD_1;
2020 else
2021 STps->eof = ST_EOM_OK;
2022 if (STp->block_size == 0)
2023 STbp->buffer_bytes = bytes - transfer;
2024 else
2025 STbp->buffer_bytes =
2026 bytes - transfer * STp->block_size;
2027
2028 DEBC(printk(ST_DEB_MSG "%s: EOM detected (%d bytes read).\n",
2029 name, STbp->buffer_bytes));
2030 }
2031 }
2032 /* end of EOF, EOM, ILI test */
2033 else { /* nonzero sense key */
2034 DEBC(printk(ST_DEB_MSG
2035 "%s: Tape error while reading.\n", name));
2036 STps->drv_block = (-1);
2037 if (STps->eof == ST_FM &&
2038 cmdstatp->sense_hdr.sense_key == BLANK_CHECK) {
2039 DEBC(printk(ST_DEB_MSG
2040 "%s: Zero returned for first BLANK CHECK after EOF.\n",
2041 name));
2042 STps->eof = ST_EOD_2; /* First BLANK_CHECK after FM */
2043 } else /* Some other extended sense code */
2044 retval = (-EIO);
2045 }
2046
2047 if (STbp->buffer_bytes < 0) /* Caused by bogus sense data */
2048 STbp->buffer_bytes = 0;
2049 }
2050 /* End of extended sense test */
2051 else { /* Non-extended sense */
2052 retval = STbp->syscall_result;
2053 }
2054
2055 }
2056 /* End of error handling */
Kai Makisara40f6b362008-02-24 22:23:24 +02002057 else { /* Read successful */
Linus Torvalds1da177e2005-04-16 15:20:36 -07002058 STbp->buffer_bytes = bytes;
Kai Makisara40f6b362008-02-24 22:23:24 +02002059 if (STp->sili) /* In fixed block mode residual is always zero here */
2060 STbp->buffer_bytes -= STp->buffer->cmdstat.residual;
2061 }
Linus Torvalds1da177e2005-04-16 15:20:36 -07002062
2063 if (STps->drv_block >= 0) {
2064 if (STp->block_size == 0)
2065 STps->drv_block++;
2066 else
2067 STps->drv_block += STbp->buffer_bytes / STp->block_size;
2068 }
2069 return retval;
2070}
2071
2072
2073/* Read command */
2074static ssize_t
2075st_read(struct file *filp, char __user *buf, size_t count, loff_t * ppos)
2076{
2077 ssize_t total;
2078 ssize_t retval = 0;
2079 ssize_t i, transfer;
2080 int special, do_dio = 0;
Mike Christie8b05b772005-11-08 04:06:44 -06002081 struct st_request *SRpnt = NULL;
Linus Torvalds1da177e2005-04-16 15:20:36 -07002082 struct scsi_tape *STp = filp->private_data;
2083 struct st_modedef *STm;
2084 struct st_partstat *STps;
2085 struct st_buffer *STbp = STp->buffer;
2086 DEB( char *name = tape_name(STp); )
2087
Matthias Kaehlcke28f85002007-07-29 23:38:15 +02002088 if (mutex_lock_interruptible(&STp->lock))
Linus Torvalds1da177e2005-04-16 15:20:36 -07002089 return -ERESTARTSYS;
2090
2091 retval = rw_checks(STp, filp, count);
2092 if (retval || count == 0)
2093 goto out;
2094
2095 STm = &(STp->modes[STp->current_mode]);
Kai Makisara9abe16c2007-02-03 13:21:29 +02002096 if (STp->block_size != 0 && (count % STp->block_size) != 0) {
2097 if (!STm->do_read_ahead) {
2098 retval = (-EINVAL); /* Read must be integral number of blocks */
2099 goto out;
2100 }
2101 STp->try_dio_now = 0; /* Direct i/o can't handle split blocks */
Linus Torvalds1da177e2005-04-16 15:20:36 -07002102 }
2103
2104 STps = &(STp->ps[STp->partition]);
2105 if (STps->rw == ST_WRITING) {
2106 retval = flush_buffer(STp, 0);
2107 if (retval)
2108 goto out;
2109 STps->rw = ST_READING;
2110 }
2111 DEB(
2112 if (debugging && STps->eof != ST_NOEOF)
2113 printk(ST_DEB_MSG "%s: EOF/EOM flag up (%d). Bytes %d\n", name,
2114 STps->eof, STbp->buffer_bytes);
2115 ) /* end DEB */
2116
2117 retval = setup_buffering(STp, buf, count, 1);
2118 if (retval)
2119 goto out;
2120 do_dio = STbp->do_dio;
2121
2122 if (STbp->buffer_bytes == 0 &&
2123 STps->eof >= ST_EOD_1) {
2124 if (STps->eof < ST_EOD) {
2125 STps->eof += 1;
2126 retval = 0;
2127 goto out;
2128 }
2129 retval = (-EIO); /* EOM or Blank Check */
2130 goto out;
2131 }
2132
2133 if (do_dio) {
2134 /* Check the buffer writability before any tape movement. Don't alter
2135 buffer data. */
2136 if (copy_from_user(&i, buf, 1) != 0 ||
2137 copy_to_user(buf, &i, 1) != 0 ||
2138 copy_from_user(&i, buf + count - 1, 1) != 0 ||
2139 copy_to_user(buf + count - 1, &i, 1) != 0) {
2140 retval = (-EFAULT);
2141 goto out;
2142 }
2143 }
2144
2145 STps->rw = ST_READING;
2146
2147
2148 /* Loop until enough data in buffer or a special condition found */
2149 for (total = 0, special = 0; total < count && !special;) {
2150
2151 /* Get new data if the buffer is empty */
2152 if (STbp->buffer_bytes == 0) {
2153 special = read_tape(STp, count - total, &SRpnt);
2154 if (special < 0) { /* No need to continue read */
2155 retval = special;
2156 goto out;
2157 }
2158 }
2159
2160 /* Move the data from driver buffer to user buffer */
2161 if (STbp->buffer_bytes > 0) {
2162 DEB(
2163 if (debugging && STps->eof != ST_NOEOF)
2164 printk(ST_DEB_MSG
2165 "%s: EOF up (%d). Left %d, needed %d.\n", name,
2166 STps->eof, STbp->buffer_bytes,
2167 (int)(count - total));
2168 ) /* end DEB */
2169 transfer = STbp->buffer_bytes < count - total ?
2170 STbp->buffer_bytes : count - total;
2171 if (!do_dio) {
2172 i = from_buffer(STbp, buf, transfer);
2173 if (i) {
2174 retval = i;
2175 goto out;
2176 }
2177 }
2178 buf += transfer;
2179 total += transfer;
2180 }
2181
2182 if (STp->block_size == 0)
2183 break; /* Read only one variable length block */
2184
2185 } /* for (total = 0, special = 0;
2186 total < count && !special; ) */
2187
2188 /* Change the eof state if no data from tape or buffer */
2189 if (total == 0) {
2190 if (STps->eof == ST_FM_HIT) {
2191 STps->eof = ST_FM;
2192 STps->drv_block = 0;
2193 if (STps->drv_file >= 0)
2194 STps->drv_file++;
2195 } else if (STps->eof == ST_EOD_1) {
2196 STps->eof = ST_EOD_2;
2197 STps->drv_block = 0;
2198 if (STps->drv_file >= 0)
2199 STps->drv_file++;
2200 } else if (STps->eof == ST_EOD_2)
2201 STps->eof = ST_EOD;
2202 } else if (STps->eof == ST_FM)
2203 STps->eof = ST_NOEOF;
2204 retval = total;
2205
2206 out:
2207 if (SRpnt != NULL) {
Mike Christie8b05b772005-11-08 04:06:44 -06002208 st_release_request(SRpnt);
Linus Torvalds1da177e2005-04-16 15:20:36 -07002209 SRpnt = NULL;
2210 }
2211 if (do_dio) {
Kai Makisara787926b2005-11-13 10:04:44 +02002212 release_buffering(STp, 1);
Linus Torvalds1da177e2005-04-16 15:20:36 -07002213 STbp->buffer_bytes = 0;
2214 }
Matthias Kaehlcke28f85002007-07-29 23:38:15 +02002215 mutex_unlock(&STp->lock);
Linus Torvalds1da177e2005-04-16 15:20:36 -07002216
2217 return retval;
2218}
2219
2220
2221
2222DEB(
2223/* Set the driver options */
2224static void st_log_options(struct scsi_tape * STp, struct st_modedef * STm, char *name)
2225{
2226 if (debugging) {
2227 printk(KERN_INFO
2228 "%s: Mode %d options: buffer writes: %d, async writes: %d, read ahead: %d\n",
2229 name, STp->current_mode, STm->do_buffer_writes, STm->do_async_writes,
2230 STm->do_read_ahead);
2231 printk(KERN_INFO
2232 "%s: can bsr: %d, two FMs: %d, fast mteom: %d, auto lock: %d,\n",
2233 name, STp->can_bsr, STp->two_fm, STp->fast_mteom, STp->do_auto_lock);
2234 printk(KERN_INFO
2235 "%s: defs for wr: %d, no block limits: %d, partitions: %d, s2 log: %d\n",
2236 name, STm->defaults_for_writes, STp->omit_blklims, STp->can_partitions,
2237 STp->scsi2_logical);
2238 printk(KERN_INFO
Kai Makisara40f6b362008-02-24 22:23:24 +02002239 "%s: sysv: %d nowait: %d sili: %d\n", name, STm->sysv, STp->immediate,
2240 STp->sili);
Linus Torvalds1da177e2005-04-16 15:20:36 -07002241 printk(KERN_INFO "%s: debugging: %d\n",
2242 name, debugging);
2243 }
2244}
2245 )
2246
2247
2248static int st_set_options(struct scsi_tape *STp, long options)
2249{
2250 int value;
2251 long code;
2252 struct st_modedef *STm;
2253 char *name = tape_name(STp);
2254 struct cdev *cd0, *cd1;
2255
2256 STm = &(STp->modes[STp->current_mode]);
2257 if (!STm->defined) {
2258 cd0 = STm->cdevs[0]; cd1 = STm->cdevs[1];
2259 memcpy(STm, &(STp->modes[0]), sizeof(struct st_modedef));
2260 STm->cdevs[0] = cd0; STm->cdevs[1] = cd1;
2261 modes_defined = 1;
2262 DEBC(printk(ST_DEB_MSG
2263 "%s: Initialized mode %d definition from mode 0\n",
2264 name, STp->current_mode));
2265 }
2266
2267 code = options & MT_ST_OPTIONS;
2268 if (code == MT_ST_BOOLEANS) {
2269 STm->do_buffer_writes = (options & MT_ST_BUFFER_WRITES) != 0;
2270 STm->do_async_writes = (options & MT_ST_ASYNC_WRITES) != 0;
2271 STm->defaults_for_writes = (options & MT_ST_DEF_WRITES) != 0;
2272 STm->do_read_ahead = (options & MT_ST_READ_AHEAD) != 0;
2273 STp->two_fm = (options & MT_ST_TWO_FM) != 0;
2274 STp->fast_mteom = (options & MT_ST_FAST_MTEOM) != 0;
2275 STp->do_auto_lock = (options & MT_ST_AUTO_LOCK) != 0;
2276 STp->can_bsr = (options & MT_ST_CAN_BSR) != 0;
2277 STp->omit_blklims = (options & MT_ST_NO_BLKLIMS) != 0;
2278 if ((STp->device)->scsi_level >= SCSI_2)
2279 STp->can_partitions = (options & MT_ST_CAN_PARTITIONS) != 0;
2280 STp->scsi2_logical = (options & MT_ST_SCSI2LOGICAL) != 0;
2281 STp->immediate = (options & MT_ST_NOWAIT) != 0;
2282 STm->sysv = (options & MT_ST_SYSV) != 0;
Kai Makisara40f6b362008-02-24 22:23:24 +02002283 STp->sili = (options & MT_ST_SILI) != 0;
Linus Torvalds1da177e2005-04-16 15:20:36 -07002284 DEB( debugging = (options & MT_ST_DEBUGGING) != 0;
2285 st_log_options(STp, STm, name); )
2286 } else if (code == MT_ST_SETBOOLEANS || code == MT_ST_CLEARBOOLEANS) {
2287 value = (code == MT_ST_SETBOOLEANS);
2288 if ((options & MT_ST_BUFFER_WRITES) != 0)
2289 STm->do_buffer_writes = value;
2290 if ((options & MT_ST_ASYNC_WRITES) != 0)
2291 STm->do_async_writes = value;
2292 if ((options & MT_ST_DEF_WRITES) != 0)
2293 STm->defaults_for_writes = value;
2294 if ((options & MT_ST_READ_AHEAD) != 0)
2295 STm->do_read_ahead = value;
2296 if ((options & MT_ST_TWO_FM) != 0)
2297 STp->two_fm = value;
2298 if ((options & MT_ST_FAST_MTEOM) != 0)
2299 STp->fast_mteom = value;
2300 if ((options & MT_ST_AUTO_LOCK) != 0)
2301 STp->do_auto_lock = value;
2302 if ((options & MT_ST_CAN_BSR) != 0)
2303 STp->can_bsr = value;
2304 if ((options & MT_ST_NO_BLKLIMS) != 0)
2305 STp->omit_blklims = value;
2306 if ((STp->device)->scsi_level >= SCSI_2 &&
2307 (options & MT_ST_CAN_PARTITIONS) != 0)
2308 STp->can_partitions = value;
2309 if ((options & MT_ST_SCSI2LOGICAL) != 0)
2310 STp->scsi2_logical = value;
2311 if ((options & MT_ST_NOWAIT) != 0)
2312 STp->immediate = value;
2313 if ((options & MT_ST_SYSV) != 0)
2314 STm->sysv = value;
Kai Makisara40f6b362008-02-24 22:23:24 +02002315 if ((options & MT_ST_SILI) != 0)
2316 STp->sili = value;
Linus Torvalds1da177e2005-04-16 15:20:36 -07002317 DEB(
2318 if ((options & MT_ST_DEBUGGING) != 0)
2319 debugging = value;
2320 st_log_options(STp, STm, name); )
2321 } else if (code == MT_ST_WRITE_THRESHOLD) {
2322 /* Retained for compatibility */
2323 } else if (code == MT_ST_DEF_BLKSIZE) {
2324 value = (options & ~MT_ST_OPTIONS);
2325 if (value == ~MT_ST_OPTIONS) {
2326 STm->default_blksize = (-1);
2327 DEBC( printk(KERN_INFO "%s: Default block size disabled.\n", name));
2328 } else {
2329 STm->default_blksize = value;
2330 DEBC( printk(KERN_INFO "%s: Default block size set to %d bytes.\n",
2331 name, STm->default_blksize));
2332 if (STp->ready == ST_READY) {
2333 STp->blksize_changed = 0;
2334 set_mode_densblk(STp, STm);
2335 }
2336 }
2337 } else if (code == MT_ST_TIMEOUTS) {
2338 value = (options & ~MT_ST_OPTIONS);
2339 if ((value & MT_ST_SET_LONG_TIMEOUT) != 0) {
2340 STp->long_timeout = (value & ~MT_ST_SET_LONG_TIMEOUT) * HZ;
2341 DEBC( printk(KERN_INFO "%s: Long timeout set to %d seconds.\n", name,
2342 (value & ~MT_ST_SET_LONG_TIMEOUT)));
2343 } else {
James Bottomleya02488e2008-11-30 10:36:26 -06002344 blk_queue_rq_timeout(STp->device->request_queue,
2345 value * HZ);
Linus Torvalds1da177e2005-04-16 15:20:36 -07002346 DEBC( printk(KERN_INFO "%s: Normal timeout set to %d seconds.\n",
2347 name, value) );
2348 }
2349 } else if (code == MT_ST_SET_CLN) {
2350 value = (options & ~MT_ST_OPTIONS) & 0xff;
2351 if (value != 0 &&
2352 value < EXTENDED_SENSE_START && value >= SCSI_SENSE_BUFFERSIZE)
2353 return (-EINVAL);
2354 STp->cln_mode = value;
2355 STp->cln_sense_mask = (options >> 8) & 0xff;
2356 STp->cln_sense_value = (options >> 16) & 0xff;
2357 printk(KERN_INFO
2358 "%s: Cleaning request mode %d, mask %02x, value %02x\n",
2359 name, value, STp->cln_sense_mask, STp->cln_sense_value);
2360 } else if (code == MT_ST_DEF_OPTIONS) {
2361 code = (options & ~MT_ST_CLEAR_DEFAULT);
2362 value = (options & MT_ST_CLEAR_DEFAULT);
2363 if (code == MT_ST_DEF_DENSITY) {
2364 if (value == MT_ST_CLEAR_DEFAULT) {
2365 STm->default_density = (-1);
2366 DEBC( printk(KERN_INFO "%s: Density default disabled.\n",
2367 name));
2368 } else {
2369 STm->default_density = value & 0xff;
2370 DEBC( printk(KERN_INFO "%s: Density default set to %x\n",
2371 name, STm->default_density));
2372 if (STp->ready == ST_READY) {
2373 STp->density_changed = 0;
2374 set_mode_densblk(STp, STm);
2375 }
2376 }
2377 } else if (code == MT_ST_DEF_DRVBUFFER) {
2378 if (value == MT_ST_CLEAR_DEFAULT) {
2379 STp->default_drvbuffer = 0xff;
2380 DEBC( printk(KERN_INFO
2381 "%s: Drive buffer default disabled.\n", name));
2382 } else {
2383 STp->default_drvbuffer = value & 7;
2384 DEBC( printk(KERN_INFO
2385 "%s: Drive buffer default set to %x\n",
2386 name, STp->default_drvbuffer));
2387 if (STp->ready == ST_READY)
2388 st_int_ioctl(STp, MTSETDRVBUFFER, STp->default_drvbuffer);
2389 }
2390 } else if (code == MT_ST_DEF_COMPRESSION) {
2391 if (value == MT_ST_CLEAR_DEFAULT) {
2392 STm->default_compression = ST_DONT_TOUCH;
2393 DEBC( printk(KERN_INFO
2394 "%s: Compression default disabled.\n", name));
2395 } else {
2396 if ((value & 0xff00) != 0) {
2397 STp->c_algo = (value & 0xff00) >> 8;
2398 DEBC( printk(KERN_INFO "%s: Compression algorithm set to 0x%x.\n",
2399 name, STp->c_algo));
2400 }
2401 if ((value & 0xff) != 0xff) {
2402 STm->default_compression = (value & 1 ? ST_YES : ST_NO);
2403 DEBC( printk(KERN_INFO "%s: Compression default set to %x\n",
2404 name, (value & 1)));
2405 if (STp->ready == ST_READY) {
2406 STp->compression_changed = 0;
2407 st_compression(STp, (STm->default_compression == ST_YES));
2408 }
2409 }
2410 }
2411 }
2412 } else
2413 return (-EIO);
2414
2415 return 0;
2416}
2417
2418#define MODE_HEADER_LENGTH 4
2419
2420/* Mode header and page byte offsets */
2421#define MH_OFF_DATA_LENGTH 0
2422#define MH_OFF_MEDIUM_TYPE 1
2423#define MH_OFF_DEV_SPECIFIC 2
2424#define MH_OFF_BDESCS_LENGTH 3
2425#define MP_OFF_PAGE_NBR 0
2426#define MP_OFF_PAGE_LENGTH 1
2427
2428/* Mode header and page bit masks */
2429#define MH_BIT_WP 0x80
2430#define MP_MSK_PAGE_NBR 0x3f
2431
2432/* Don't return block descriptors */
2433#define MODE_SENSE_OMIT_BDESCS 0x08
2434
2435#define MODE_SELECT_PAGE_FORMAT 0x10
2436
2437/* Read a mode page into the tape buffer. The block descriptors are included
2438 if incl_block_descs is true. The page control is ored to the page number
2439 parameter, if necessary. */
2440static int read_mode_page(struct scsi_tape *STp, int page, int omit_block_descs)
2441{
2442 unsigned char cmd[MAX_COMMAND_SIZE];
FUJITA Tomonori8ecf0d92008-12-05 15:25:28 +09002443 struct st_request *SRpnt;
2444 int ret;
Linus Torvalds1da177e2005-04-16 15:20:36 -07002445
2446 memset(cmd, 0, MAX_COMMAND_SIZE);
2447 cmd[0] = MODE_SENSE;
2448 if (omit_block_descs)
2449 cmd[1] = MODE_SENSE_OMIT_BDESCS;
2450 cmd[2] = page;
2451 cmd[4] = 255;
2452
FUJITA Tomonori8ecf0d92008-12-05 15:25:28 +09002453 SRpnt = st_allocate_request(STp);
2454 if (!SRpnt)
2455 return STp->buffer->syscall_result;
Linus Torvalds1da177e2005-04-16 15:20:36 -07002456
FUJITA Tomonori8ecf0d92008-12-05 15:25:28 +09002457 ret = st_scsi_kern_execute(SRpnt, cmd, DMA_FROM_DEVICE,
2458 STp->buffer->b_data, cmd[4],
2459 STp->device->request_queue->rq_timeout,
2460 MAX_RETRIES);
Mike Christie8b05b772005-11-08 04:06:44 -06002461 st_release_request(SRpnt);
Linus Torvalds1da177e2005-04-16 15:20:36 -07002462
FUJITA Tomonori8ecf0d92008-12-05 15:25:28 +09002463 return ret ? : STp->buffer->syscall_result;
Linus Torvalds1da177e2005-04-16 15:20:36 -07002464}
2465
2466
2467/* Send the mode page in the tape buffer to the drive. Assumes that the mode data
2468 in the buffer is correctly formatted. The long timeout is used if slow is non-zero. */
2469static int write_mode_page(struct scsi_tape *STp, int page, int slow)
2470{
FUJITA Tomonori18c87012008-12-05 15:25:29 +09002471 int pgo, timeout, ret = 0;
Linus Torvalds1da177e2005-04-16 15:20:36 -07002472 unsigned char cmd[MAX_COMMAND_SIZE];
FUJITA Tomonori18c87012008-12-05 15:25:29 +09002473 struct st_request *SRpnt;
Linus Torvalds1da177e2005-04-16 15:20:36 -07002474
2475 memset(cmd, 0, MAX_COMMAND_SIZE);
2476 cmd[0] = MODE_SELECT;
2477 cmd[1] = MODE_SELECT_PAGE_FORMAT;
2478 pgo = MODE_HEADER_LENGTH + (STp->buffer)->b_data[MH_OFF_BDESCS_LENGTH];
2479 cmd[4] = pgo + (STp->buffer)->b_data[pgo + MP_OFF_PAGE_LENGTH] + 2;
2480
2481 /* Clear reserved fields */
2482 (STp->buffer)->b_data[MH_OFF_DATA_LENGTH] = 0;
2483 (STp->buffer)->b_data[MH_OFF_MEDIUM_TYPE] = 0;
2484 (STp->buffer)->b_data[MH_OFF_DEV_SPECIFIC] &= ~MH_BIT_WP;
2485 (STp->buffer)->b_data[pgo + MP_OFF_PAGE_NBR] &= MP_MSK_PAGE_NBR;
2486
FUJITA Tomonori18c87012008-12-05 15:25:29 +09002487 SRpnt = st_allocate_request(STp);
2488 if (!SRpnt)
2489 return ret;
2490
2491 timeout = slow ? STp->long_timeout :
2492 STp->device->request_queue->rq_timeout;
2493
2494 ret = st_scsi_kern_execute(SRpnt, cmd, DMA_TO_DEVICE,
2495 STp->buffer->b_data, cmd[4], timeout, 0);
2496 if (!ret)
2497 ret = STp->buffer->syscall_result;
Linus Torvalds1da177e2005-04-16 15:20:36 -07002498
Mike Christie8b05b772005-11-08 04:06:44 -06002499 st_release_request(SRpnt);
Linus Torvalds1da177e2005-04-16 15:20:36 -07002500
FUJITA Tomonori18c87012008-12-05 15:25:29 +09002501 return ret;
Linus Torvalds1da177e2005-04-16 15:20:36 -07002502}
2503
2504
2505#define COMPRESSION_PAGE 0x0f
2506#define COMPRESSION_PAGE_LENGTH 16
2507
2508#define CP_OFF_DCE_DCC 2
2509#define CP_OFF_C_ALGO 7
2510
2511#define DCE_MASK 0x80
2512#define DCC_MASK 0x40
2513#define RED_MASK 0x60
2514
2515
2516/* Control the compression with mode page 15. Algorithm not changed if zero.
2517
2518 The block descriptors are read and written because Sony SDT-7000 does not
2519 work without this (suggestion from Michael Schaefer <Michael.Schaefer@dlr.de>).
2520 Including block descriptors should not cause any harm to other drives. */
2521
2522static int st_compression(struct scsi_tape * STp, int state)
2523{
2524 int retval;
2525 int mpoffs; /* Offset to mode page start */
2526 unsigned char *b_data = (STp->buffer)->b_data;
2527 DEB( char *name = tape_name(STp); )
2528
2529 if (STp->ready != ST_READY)
2530 return (-EIO);
2531
2532 /* Read the current page contents */
2533 retval = read_mode_page(STp, COMPRESSION_PAGE, 0);
2534 if (retval) {
2535 DEBC(printk(ST_DEB_MSG "%s: Compression mode page not supported.\n",
2536 name));
2537 return (-EIO);
2538 }
2539
2540 mpoffs = MODE_HEADER_LENGTH + b_data[MH_OFF_BDESCS_LENGTH];
2541 DEBC(printk(ST_DEB_MSG "%s: Compression state is %d.\n", name,
2542 (b_data[mpoffs + CP_OFF_DCE_DCC] & DCE_MASK ? 1 : 0)));
2543
2544 /* Check if compression can be changed */
2545 if ((b_data[mpoffs + CP_OFF_DCE_DCC] & DCC_MASK) == 0) {
2546 DEBC(printk(ST_DEB_MSG "%s: Compression not supported.\n", name));
2547 return (-EIO);
2548 }
2549
2550 /* Do the change */
2551 if (state) {
2552 b_data[mpoffs + CP_OFF_DCE_DCC] |= DCE_MASK;
2553 if (STp->c_algo != 0)
2554 b_data[mpoffs + CP_OFF_C_ALGO] = STp->c_algo;
2555 }
2556 else {
2557 b_data[mpoffs + CP_OFF_DCE_DCC] &= ~DCE_MASK;
2558 if (STp->c_algo != 0)
2559 b_data[mpoffs + CP_OFF_C_ALGO] = 0; /* no compression */
2560 }
2561
2562 retval = write_mode_page(STp, COMPRESSION_PAGE, 0);
2563 if (retval) {
2564 DEBC(printk(ST_DEB_MSG "%s: Compression change failed.\n", name));
2565 return (-EIO);
2566 }
2567 DEBC(printk(ST_DEB_MSG "%s: Compression state changed to %d.\n",
2568 name, state));
2569
2570 STp->compression_changed = 1;
2571 return 0;
2572}
2573
2574
2575/* Process the load and unload commands (does unload if the load code is zero) */
2576static int do_load_unload(struct scsi_tape *STp, struct file *filp, int load_code)
2577{
2578 int retval = (-EIO), timeout;
2579 DEB( char *name = tape_name(STp); )
2580 unsigned char cmd[MAX_COMMAND_SIZE];
2581 struct st_partstat *STps;
Mike Christie8b05b772005-11-08 04:06:44 -06002582 struct st_request *SRpnt;
Linus Torvalds1da177e2005-04-16 15:20:36 -07002583
2584 if (STp->ready != ST_READY && !load_code) {
2585 if (STp->ready == ST_NO_TAPE)
2586 return (-ENOMEDIUM);
2587 else
2588 return (-EIO);
2589 }
2590
2591 memset(cmd, 0, MAX_COMMAND_SIZE);
2592 cmd[0] = START_STOP;
2593 if (load_code)
2594 cmd[4] |= 1;
2595 /*
2596 * If arg >= 1 && arg <= 6 Enhanced load/unload in HP C1553A
2597 */
2598 if (load_code >= 1 + MT_ST_HPLOADER_OFFSET
2599 && load_code <= 6 + MT_ST_HPLOADER_OFFSET) {
2600 DEBC(printk(ST_DEB_MSG "%s: Enhanced %sload slot %2d.\n",
2601 name, (cmd[4]) ? "" : "un",
2602 load_code - MT_ST_HPLOADER_OFFSET));
2603 cmd[3] = load_code - MT_ST_HPLOADER_OFFSET; /* MediaID field of C1553A */
2604 }
2605 if (STp->immediate) {
2606 cmd[1] = 1; /* Don't wait for completion */
James Bottomleya02488e2008-11-30 10:36:26 -06002607 timeout = STp->device->request_queue->rq_timeout;
Linus Torvalds1da177e2005-04-16 15:20:36 -07002608 }
2609 else
2610 timeout = STp->long_timeout;
2611
2612 DEBC(
2613 if (!load_code)
2614 printk(ST_DEB_MSG "%s: Unloading tape.\n", name);
2615 else
2616 printk(ST_DEB_MSG "%s: Loading tape.\n", name);
2617 );
2618
FUJITA Tomonori15c920a2008-12-05 15:25:24 +09002619 SRpnt = st_allocate_request(STp);
Linus Torvalds1da177e2005-04-16 15:20:36 -07002620 if (!SRpnt)
FUJITA Tomonori15c920a2008-12-05 15:25:24 +09002621 return STp->buffer->syscall_result;
2622
2623 retval = st_scsi_kern_execute(SRpnt, cmd, DMA_NONE, NULL, 0, timeout,
2624 MAX_RETRIES);
2625 if (retval)
2626 goto out;
Linus Torvalds1da177e2005-04-16 15:20:36 -07002627
2628 retval = (STp->buffer)->syscall_result;
Linus Torvalds1da177e2005-04-16 15:20:36 -07002629
2630 if (!retval) { /* SCSI command successful */
2631
2632 if (!load_code) {
2633 STp->rew_at_close = 0;
2634 STp->ready = ST_NO_TAPE;
2635 }
2636 else {
2637 STp->rew_at_close = STp->autorew_dev;
2638 retval = check_tape(STp, filp);
2639 if (retval > 0)
2640 retval = 0;
2641 }
2642 }
2643 else {
2644 STps = &(STp->ps[STp->partition]);
2645 STps->drv_file = STps->drv_block = (-1);
2646 }
FUJITA Tomonori15c920a2008-12-05 15:25:24 +09002647out:
2648 st_release_request(SRpnt);
Linus Torvalds1da177e2005-04-16 15:20:36 -07002649
2650 return retval;
2651}
2652
2653#if DEBUG
2654#define ST_DEB_FORWARD 0
2655#define ST_DEB_BACKWARD 1
2656static void deb_space_print(char *name, int direction, char *units, unsigned char *cmd)
2657{
2658 s32 sc;
2659
2660 sc = cmd[2] & 0x80 ? 0xff000000 : 0;
2661 sc |= (cmd[2] << 16) | (cmd[3] << 8) | cmd[4];
2662 if (direction)
2663 sc = -sc;
2664 printk(ST_DEB_MSG "%s: Spacing tape %s over %d %s.\n", name,
2665 direction ? "backward" : "forward", sc, units);
2666}
2667#endif
2668
2669
2670/* Internal ioctl function */
2671static int st_int_ioctl(struct scsi_tape *STp, unsigned int cmd_in, unsigned long arg)
2672{
2673 int timeout;
2674 long ltmp;
2675 int ioctl_result;
2676 int chg_eof = 1;
2677 unsigned char cmd[MAX_COMMAND_SIZE];
Mike Christie8b05b772005-11-08 04:06:44 -06002678 struct st_request *SRpnt;
Linus Torvalds1da177e2005-04-16 15:20:36 -07002679 struct st_partstat *STps;
2680 int fileno, blkno, at_sm, undone;
2681 int datalen = 0, direction = DMA_NONE;
2682 char *name = tape_name(STp);
2683
2684 WARN_ON(STp->buffer->do_dio != 0);
2685 if (STp->ready != ST_READY) {
2686 if (STp->ready == ST_NO_TAPE)
2687 return (-ENOMEDIUM);
2688 else
2689 return (-EIO);
2690 }
2691 timeout = STp->long_timeout;
2692 STps = &(STp->ps[STp->partition]);
2693 fileno = STps->drv_file;
2694 blkno = STps->drv_block;
2695 at_sm = STps->at_sm;
2696
2697 memset(cmd, 0, MAX_COMMAND_SIZE);
2698 switch (cmd_in) {
2699 case MTFSFM:
2700 chg_eof = 0; /* Changed from the FSF after this */
2701 case MTFSF:
2702 cmd[0] = SPACE;
2703 cmd[1] = 0x01; /* Space FileMarks */
2704 cmd[2] = (arg >> 16);
2705 cmd[3] = (arg >> 8);
2706 cmd[4] = arg;
2707 DEBC(deb_space_print(name, ST_DEB_FORWARD, "filemarks", cmd);)
2708 if (fileno >= 0)
2709 fileno += arg;
2710 blkno = 0;
2711 at_sm &= (arg == 0);
2712 break;
2713 case MTBSFM:
2714 chg_eof = 0; /* Changed from the FSF after this */
2715 case MTBSF:
2716 cmd[0] = SPACE;
2717 cmd[1] = 0x01; /* Space FileMarks */
2718 ltmp = (-arg);
2719 cmd[2] = (ltmp >> 16);
2720 cmd[3] = (ltmp >> 8);
2721 cmd[4] = ltmp;
2722 DEBC(deb_space_print(name, ST_DEB_BACKWARD, "filemarks", cmd);)
2723 if (fileno >= 0)
2724 fileno -= arg;
2725 blkno = (-1); /* We can't know the block number */
2726 at_sm &= (arg == 0);
2727 break;
2728 case MTFSR:
2729 cmd[0] = SPACE;
2730 cmd[1] = 0x00; /* Space Blocks */
2731 cmd[2] = (arg >> 16);
2732 cmd[3] = (arg >> 8);
2733 cmd[4] = arg;
2734 DEBC(deb_space_print(name, ST_DEB_FORWARD, "blocks", cmd);)
2735 if (blkno >= 0)
2736 blkno += arg;
2737 at_sm &= (arg == 0);
2738 break;
2739 case MTBSR:
2740 cmd[0] = SPACE;
2741 cmd[1] = 0x00; /* Space Blocks */
2742 ltmp = (-arg);
2743 cmd[2] = (ltmp >> 16);
2744 cmd[3] = (ltmp >> 8);
2745 cmd[4] = ltmp;
2746 DEBC(deb_space_print(name, ST_DEB_BACKWARD, "blocks", cmd);)
2747 if (blkno >= 0)
2748 blkno -= arg;
2749 at_sm &= (arg == 0);
2750 break;
2751 case MTFSS:
2752 cmd[0] = SPACE;
2753 cmd[1] = 0x04; /* Space Setmarks */
2754 cmd[2] = (arg >> 16);
2755 cmd[3] = (arg >> 8);
2756 cmd[4] = arg;
2757 DEBC(deb_space_print(name, ST_DEB_FORWARD, "setmarks", cmd);)
2758 if (arg != 0) {
2759 blkno = fileno = (-1);
2760 at_sm = 1;
2761 }
2762 break;
2763 case MTBSS:
2764 cmd[0] = SPACE;
2765 cmd[1] = 0x04; /* Space Setmarks */
2766 ltmp = (-arg);
2767 cmd[2] = (ltmp >> 16);
2768 cmd[3] = (ltmp >> 8);
2769 cmd[4] = ltmp;
2770 DEBC(deb_space_print(name, ST_DEB_BACKWARD, "setmarks", cmd);)
2771 if (arg != 0) {
2772 blkno = fileno = (-1);
2773 at_sm = 1;
2774 }
2775 break;
2776 case MTWEOF:
2777 case MTWSM:
2778 if (STp->write_prot)
2779 return (-EACCES);
2780 cmd[0] = WRITE_FILEMARKS;
2781 if (cmd_in == MTWSM)
2782 cmd[1] = 2;
2783 cmd[2] = (arg >> 16);
2784 cmd[3] = (arg >> 8);
2785 cmd[4] = arg;
James Bottomleya02488e2008-11-30 10:36:26 -06002786 timeout = STp->device->request_queue->rq_timeout;
Linus Torvalds1da177e2005-04-16 15:20:36 -07002787 DEBC(
2788 if (cmd_in == MTWEOF)
2789 printk(ST_DEB_MSG "%s: Writing %d filemarks.\n", name,
2790 cmd[2] * 65536 + cmd[3] * 256 + cmd[4]);
2791 else
2792 printk(ST_DEB_MSG "%s: Writing %d setmarks.\n", name,
2793 cmd[2] * 65536 + cmd[3] * 256 + cmd[4]);
2794 )
2795 if (fileno >= 0)
2796 fileno += arg;
2797 blkno = 0;
2798 at_sm = (cmd_in == MTWSM);
2799 break;
2800 case MTREW:
2801 cmd[0] = REZERO_UNIT;
2802 if (STp->immediate) {
2803 cmd[1] = 1; /* Don't wait for completion */
James Bottomleya02488e2008-11-30 10:36:26 -06002804 timeout = STp->device->request_queue->rq_timeout;
Linus Torvalds1da177e2005-04-16 15:20:36 -07002805 }
2806 DEBC(printk(ST_DEB_MSG "%s: Rewinding tape.\n", name));
2807 fileno = blkno = at_sm = 0;
2808 break;
2809 case MTNOP:
2810 DEBC(printk(ST_DEB_MSG "%s: No op on tape.\n", name));
2811 return 0; /* Should do something ? */
2812 break;
2813 case MTRETEN:
2814 cmd[0] = START_STOP;
2815 if (STp->immediate) {
2816 cmd[1] = 1; /* Don't wait for completion */
James Bottomleya02488e2008-11-30 10:36:26 -06002817 timeout = STp->device->request_queue->rq_timeout;
Linus Torvalds1da177e2005-04-16 15:20:36 -07002818 }
2819 cmd[4] = 3;
2820 DEBC(printk(ST_DEB_MSG "%s: Retensioning tape.\n", name));
2821 fileno = blkno = at_sm = 0;
2822 break;
2823 case MTEOM:
2824 if (!STp->fast_mteom) {
2825 /* space to the end of tape */
2826 ioctl_result = st_int_ioctl(STp, MTFSF, 0x7fffff);
2827 fileno = STps->drv_file;
2828 if (STps->eof >= ST_EOD_1)
2829 return 0;
2830 /* The next lines would hide the number of spaced FileMarks
2831 That's why I inserted the previous lines. I had no luck
2832 with detecting EOM with FSF, so we go now to EOM.
2833 Joerg Weule */
2834 } else
2835 fileno = (-1);
2836 cmd[0] = SPACE;
2837 cmd[1] = 3;
2838 DEBC(printk(ST_DEB_MSG "%s: Spacing to end of recorded medium.\n",
2839 name));
2840 blkno = -1;
2841 at_sm = 0;
2842 break;
2843 case MTERASE:
2844 if (STp->write_prot)
2845 return (-EACCES);
2846 cmd[0] = ERASE;
2847 cmd[1] = (arg ? 1 : 0); /* Long erase with non-zero argument */
2848 if (STp->immediate) {
2849 cmd[1] |= 2; /* Don't wait for completion */
James Bottomleya02488e2008-11-30 10:36:26 -06002850 timeout = STp->device->request_queue->rq_timeout;
Linus Torvalds1da177e2005-04-16 15:20:36 -07002851 }
2852 else
2853 timeout = STp->long_timeout * 8;
2854
2855 DEBC(printk(ST_DEB_MSG "%s: Erasing tape.\n", name));
2856 fileno = blkno = at_sm = 0;
2857 break;
2858 case MTSETBLK: /* Set block length */
2859 case MTSETDENSITY: /* Set tape density */
2860 case MTSETDRVBUFFER: /* Set drive buffering */
2861 case SET_DENS_AND_BLK: /* Set density and block size */
2862 chg_eof = 0;
2863 if (STp->dirty || (STp->buffer)->buffer_bytes != 0)
2864 return (-EIO); /* Not allowed if data in buffer */
2865 if ((cmd_in == MTSETBLK || cmd_in == SET_DENS_AND_BLK) &&
2866 (arg & MT_ST_BLKSIZE_MASK) != 0 &&
2867 STp->max_block > 0 &&
2868 ((arg & MT_ST_BLKSIZE_MASK) < STp->min_block ||
2869 (arg & MT_ST_BLKSIZE_MASK) > STp->max_block)) {
2870 printk(KERN_WARNING "%s: Illegal block size.\n", name);
2871 return (-EINVAL);
2872 }
2873 cmd[0] = MODE_SELECT;
2874 if ((STp->use_pf & USE_PF))
2875 cmd[1] = MODE_SELECT_PAGE_FORMAT;
2876 cmd[4] = datalen = 12;
2877 direction = DMA_TO_DEVICE;
2878
2879 memset((STp->buffer)->b_data, 0, 12);
2880 if (cmd_in == MTSETDRVBUFFER)
2881 (STp->buffer)->b_data[2] = (arg & 7) << 4;
2882 else
2883 (STp->buffer)->b_data[2] =
2884 STp->drv_buffer << 4;
2885 (STp->buffer)->b_data[3] = 8; /* block descriptor length */
2886 if (cmd_in == MTSETDENSITY) {
2887 (STp->buffer)->b_data[4] = arg;
2888 STp->density_changed = 1; /* At least we tried ;-) */
2889 } else if (cmd_in == SET_DENS_AND_BLK)
2890 (STp->buffer)->b_data[4] = arg >> 24;
2891 else
2892 (STp->buffer)->b_data[4] = STp->density;
2893 if (cmd_in == MTSETBLK || cmd_in == SET_DENS_AND_BLK) {
2894 ltmp = arg & MT_ST_BLKSIZE_MASK;
2895 if (cmd_in == MTSETBLK)
2896 STp->blksize_changed = 1; /* At least we tried ;-) */
2897 } else
2898 ltmp = STp->block_size;
2899 (STp->buffer)->b_data[9] = (ltmp >> 16);
2900 (STp->buffer)->b_data[10] = (ltmp >> 8);
2901 (STp->buffer)->b_data[11] = ltmp;
James Bottomleya02488e2008-11-30 10:36:26 -06002902 timeout = STp->device->request_queue->rq_timeout;
Linus Torvalds1da177e2005-04-16 15:20:36 -07002903 DEBC(
2904 if (cmd_in == MTSETBLK || cmd_in == SET_DENS_AND_BLK)
2905 printk(ST_DEB_MSG
2906 "%s: Setting block size to %d bytes.\n", name,
2907 (STp->buffer)->b_data[9] * 65536 +
2908 (STp->buffer)->b_data[10] * 256 +
2909 (STp->buffer)->b_data[11]);
2910 if (cmd_in == MTSETDENSITY || cmd_in == SET_DENS_AND_BLK)
2911 printk(ST_DEB_MSG
2912 "%s: Setting density code to %x.\n", name,
2913 (STp->buffer)->b_data[4]);
2914 if (cmd_in == MTSETDRVBUFFER)
2915 printk(ST_DEB_MSG
2916 "%s: Setting drive buffer code to %d.\n", name,
2917 ((STp->buffer)->b_data[2] >> 4) & 7);
2918 )
2919 break;
2920 default:
2921 return (-ENOSYS);
2922 }
2923
FUJITA Tomonoriccc607f2008-12-05 15:25:31 +09002924 SRpnt = st_allocate_request(STp);
Linus Torvalds1da177e2005-04-16 15:20:36 -07002925 if (!SRpnt)
2926 return (STp->buffer)->syscall_result;
2927
FUJITA Tomonoriccc607f2008-12-05 15:25:31 +09002928 ioctl_result = st_scsi_kern_execute(SRpnt, cmd, direction,
2929 STp->buffer->b_data, datalen,
2930 timeout, MAX_RETRIES);
2931 if (!ioctl_result)
2932 ioctl_result = (STp->buffer)->syscall_result;
Linus Torvalds1da177e2005-04-16 15:20:36 -07002933
2934 if (!ioctl_result) { /* SCSI command successful */
Mike Christie8b05b772005-11-08 04:06:44 -06002935 st_release_request(SRpnt);
Linus Torvalds1da177e2005-04-16 15:20:36 -07002936 SRpnt = NULL;
2937 STps->drv_block = blkno;
2938 STps->drv_file = fileno;
2939 STps->at_sm = at_sm;
2940
2941 if (cmd_in == MTBSFM)
2942 ioctl_result = st_int_ioctl(STp, MTFSF, 1);
2943 else if (cmd_in == MTFSFM)
2944 ioctl_result = st_int_ioctl(STp, MTBSF, 1);
2945
2946 if (cmd_in == MTSETBLK || cmd_in == SET_DENS_AND_BLK) {
2947 int old_block_size = STp->block_size;
2948 STp->block_size = arg & MT_ST_BLKSIZE_MASK;
2949 if (STp->block_size != 0) {
2950 if (old_block_size == 0)
2951 normalize_buffer(STp->buffer);
2952 (STp->buffer)->buffer_blocks =
2953 (STp->buffer)->buffer_size / STp->block_size;
2954 }
2955 (STp->buffer)->buffer_bytes = (STp->buffer)->read_pointer = 0;
2956 if (cmd_in == SET_DENS_AND_BLK)
2957 STp->density = arg >> MT_ST_DENSITY_SHIFT;
2958 } else if (cmd_in == MTSETDRVBUFFER)
2959 STp->drv_buffer = (arg & 7);
2960 else if (cmd_in == MTSETDENSITY)
2961 STp->density = arg;
2962
2963 if (cmd_in == MTEOM)
2964 STps->eof = ST_EOD;
2965 else if (cmd_in == MTFSF)
2966 STps->eof = ST_FM;
2967 else if (chg_eof)
2968 STps->eof = ST_NOEOF;
2969
2970 if (cmd_in == MTWEOF)
2971 STps->rw = ST_IDLE;
2972 } else { /* SCSI command was not completely successful. Don't return
2973 from this block without releasing the SCSI command block! */
2974 struct st_cmdstatus *cmdstatp = &STp->buffer->cmdstat;
2975
2976 if (cmdstatp->flags & SENSE_EOM) {
2977 if (cmd_in != MTBSF && cmd_in != MTBSFM &&
2978 cmd_in != MTBSR && cmd_in != MTBSS)
2979 STps->eof = ST_EOM_OK;
2980 STps->drv_block = 0;
2981 }
2982
2983 if (cmdstatp->remainder_valid)
2984 undone = (int)cmdstatp->uremainder64;
2985 else
2986 undone = 0;
2987
2988 if (cmd_in == MTWEOF &&
2989 cmdstatp->have_sense &&
Kai Makisara91614c02007-01-26 00:38:39 +02002990 (cmdstatp->flags & SENSE_EOM)) {
2991 if (cmdstatp->sense_hdr.sense_key == NO_SENSE ||
2992 cmdstatp->sense_hdr.sense_key == RECOVERED_ERROR) {
2993 ioctl_result = 0; /* EOF(s) written successfully at EOM */
2994 STps->eof = ST_NOEOF;
2995 } else { /* Writing EOF(s) failed */
2996 if (fileno >= 0)
2997 fileno -= undone;
2998 if (undone < arg)
2999 STps->eof = ST_NOEOF;
3000 }
Linus Torvalds1da177e2005-04-16 15:20:36 -07003001 STps->drv_file = fileno;
Linus Torvalds1da177e2005-04-16 15:20:36 -07003002 } else if ((cmd_in == MTFSF) || (cmd_in == MTFSFM)) {
3003 if (fileno >= 0)
3004 STps->drv_file = fileno - undone;
3005 else
3006 STps->drv_file = fileno;
3007 STps->drv_block = -1;
3008 STps->eof = ST_NOEOF;
3009 } else if ((cmd_in == MTBSF) || (cmd_in == MTBSFM)) {
3010 if (arg > 0 && undone < 0) /* Some drives get this wrong */
3011 undone = (-undone);
3012 if (STps->drv_file >= 0)
3013 STps->drv_file = fileno + undone;
3014 STps->drv_block = 0;
3015 STps->eof = ST_NOEOF;
3016 } else if (cmd_in == MTFSR) {
3017 if (cmdstatp->flags & SENSE_FMK) { /* Hit filemark */
3018 if (STps->drv_file >= 0)
3019 STps->drv_file++;
3020 STps->drv_block = 0;
3021 STps->eof = ST_FM;
3022 } else {
3023 if (blkno >= undone)
3024 STps->drv_block = blkno - undone;
3025 else
3026 STps->drv_block = (-1);
3027 STps->eof = ST_NOEOF;
3028 }
3029 } else if (cmd_in == MTBSR) {
3030 if (cmdstatp->flags & SENSE_FMK) { /* Hit filemark */
3031 STps->drv_file--;
3032 STps->drv_block = (-1);
3033 } else {
3034 if (arg > 0 && undone < 0) /* Some drives get this wrong */
3035 undone = (-undone);
3036 if (STps->drv_block >= 0)
3037 STps->drv_block = blkno + undone;
3038 }
3039 STps->eof = ST_NOEOF;
3040 } else if (cmd_in == MTEOM) {
3041 STps->drv_file = (-1);
3042 STps->drv_block = (-1);
3043 STps->eof = ST_EOD;
3044 } else if (cmd_in == MTSETBLK ||
3045 cmd_in == MTSETDENSITY ||
3046 cmd_in == MTSETDRVBUFFER ||
3047 cmd_in == SET_DENS_AND_BLK) {
3048 if (cmdstatp->sense_hdr.sense_key == ILLEGAL_REQUEST &&
3049 !(STp->use_pf & PF_TESTED)) {
3050 /* Try the other possible state of Page Format if not
3051 already tried */
3052 STp->use_pf = !STp->use_pf | PF_TESTED;
Mike Christie8b05b772005-11-08 04:06:44 -06003053 st_release_request(SRpnt);
Linus Torvalds1da177e2005-04-16 15:20:36 -07003054 SRpnt = NULL;
3055 return st_int_ioctl(STp, cmd_in, arg);
3056 }
3057 } else if (chg_eof)
3058 STps->eof = ST_NOEOF;
3059
3060 if (cmdstatp->sense_hdr.sense_key == BLANK_CHECK)
3061 STps->eof = ST_EOD;
3062
Mike Christie8b05b772005-11-08 04:06:44 -06003063 st_release_request(SRpnt);
Linus Torvalds1da177e2005-04-16 15:20:36 -07003064 SRpnt = NULL;
3065 }
3066
3067 return ioctl_result;
3068}
3069
3070
3071/* Get the tape position. If bt == 2, arg points into a kernel space mt_loc
3072 structure. */
3073
3074static int get_location(struct scsi_tape *STp, unsigned int *block, int *partition,
3075 int logical)
3076{
3077 int result;
3078 unsigned char scmd[MAX_COMMAND_SIZE];
Mike Christie8b05b772005-11-08 04:06:44 -06003079 struct st_request *SRpnt;
Linus Torvalds1da177e2005-04-16 15:20:36 -07003080 DEB( char *name = tape_name(STp); )
3081
3082 if (STp->ready != ST_READY)
3083 return (-EIO);
3084
3085 memset(scmd, 0, MAX_COMMAND_SIZE);
3086 if ((STp->device)->scsi_level < SCSI_2) {
3087 scmd[0] = QFA_REQUEST_BLOCK;
3088 scmd[4] = 3;
3089 } else {
3090 scmd[0] = READ_POSITION;
3091 if (!logical && !STp->scsi2_logical)
3092 scmd[1] = 1;
3093 }
FUJITA Tomonori7a31ec32008-12-05 15:25:30 +09003094
3095 SRpnt = st_allocate_request(STp);
Linus Torvalds1da177e2005-04-16 15:20:36 -07003096 if (!SRpnt)
FUJITA Tomonori7a31ec32008-12-05 15:25:30 +09003097 return STp->buffer->syscall_result;
3098
3099 result = st_scsi_kern_execute(SRpnt, scmd, DMA_FROM_DEVICE,
3100 STp->buffer->b_data, 20,
3101 STp->device->request_queue->rq_timeout,
3102 MAX_READY_RETRIES);
3103 if (result)
3104 goto out;
Linus Torvalds1da177e2005-04-16 15:20:36 -07003105
3106 if ((STp->buffer)->syscall_result != 0 ||
3107 (STp->device->scsi_level >= SCSI_2 &&
3108 ((STp->buffer)->b_data[0] & 4) != 0)) {
3109 *block = *partition = 0;
3110 DEBC(printk(ST_DEB_MSG "%s: Can't read tape position.\n", name));
3111 result = (-EIO);
3112 } else {
3113 result = 0;
3114 if ((STp->device)->scsi_level < SCSI_2) {
3115 *block = ((STp->buffer)->b_data[0] << 16)
3116 + ((STp->buffer)->b_data[1] << 8)
3117 + (STp->buffer)->b_data[2];
3118 *partition = 0;
3119 } else {
3120 *block = ((STp->buffer)->b_data[4] << 24)
3121 + ((STp->buffer)->b_data[5] << 16)
3122 + ((STp->buffer)->b_data[6] << 8)
3123 + (STp->buffer)->b_data[7];
3124 *partition = (STp->buffer)->b_data[1];
3125 if (((STp->buffer)->b_data[0] & 0x80) &&
3126 (STp->buffer)->b_data[1] == 0) /* BOP of partition 0 */
3127 STp->ps[0].drv_block = STp->ps[0].drv_file = 0;
3128 }
3129 DEBC(printk(ST_DEB_MSG "%s: Got tape pos. blk %d part %d.\n", name,
3130 *block, *partition));
3131 }
FUJITA Tomonori7a31ec32008-12-05 15:25:30 +09003132out:
Mike Christie8b05b772005-11-08 04:06:44 -06003133 st_release_request(SRpnt);
Linus Torvalds1da177e2005-04-16 15:20:36 -07003134 SRpnt = NULL;
3135
3136 return result;
3137}
3138
3139
3140/* Set the tape block and partition. Negative partition means that only the
3141 block should be set in vendor specific way. */
3142static int set_location(struct scsi_tape *STp, unsigned int block, int partition,
3143 int logical)
3144{
3145 struct st_partstat *STps;
3146 int result, p;
3147 unsigned int blk;
3148 int timeout;
3149 unsigned char scmd[MAX_COMMAND_SIZE];
Mike Christie8b05b772005-11-08 04:06:44 -06003150 struct st_request *SRpnt;
Linus Torvalds1da177e2005-04-16 15:20:36 -07003151 DEB( char *name = tape_name(STp); )
3152
3153 if (STp->ready != ST_READY)
3154 return (-EIO);
3155 timeout = STp->long_timeout;
3156 STps = &(STp->ps[STp->partition]);
3157
3158 DEBC(printk(ST_DEB_MSG "%s: Setting block to %d and partition to %d.\n",
3159 name, block, partition));
3160 DEB(if (partition < 0)
3161 return (-EIO); )
3162
3163 /* Update the location at the partition we are leaving */
3164 if ((!STp->can_partitions && partition != 0) ||
3165 partition >= ST_NBR_PARTITIONS)
3166 return (-EINVAL);
3167 if (partition != STp->partition) {
3168 if (get_location(STp, &blk, &p, 1))
3169 STps->last_block_valid = 0;
3170 else {
3171 STps->last_block_valid = 1;
3172 STps->last_block_visited = blk;
3173 DEBC(printk(ST_DEB_MSG
3174 "%s: Visited block %d for partition %d saved.\n",
3175 name, blk, STp->partition));
3176 }
3177 }
3178
3179 memset(scmd, 0, MAX_COMMAND_SIZE);
3180 if ((STp->device)->scsi_level < SCSI_2) {
3181 scmd[0] = QFA_SEEK_BLOCK;
3182 scmd[2] = (block >> 16);
3183 scmd[3] = (block >> 8);
3184 scmd[4] = block;
3185 scmd[5] = 0;
3186 } else {
3187 scmd[0] = SEEK_10;
3188 scmd[3] = (block >> 24);
3189 scmd[4] = (block >> 16);
3190 scmd[5] = (block >> 8);
3191 scmd[6] = block;
3192 if (!logical && !STp->scsi2_logical)
3193 scmd[1] = 4;
3194 if (STp->partition != partition) {
3195 scmd[1] |= 2;
3196 scmd[8] = partition;
3197 DEBC(printk(ST_DEB_MSG
3198 "%s: Trying to change partition from %d to %d\n",
3199 name, STp->partition, partition));
3200 }
3201 }
3202 if (STp->immediate) {
3203 scmd[1] |= 1; /* Don't wait for completion */
James Bottomleya02488e2008-11-30 10:36:26 -06003204 timeout = STp->device->request_queue->rq_timeout;
Linus Torvalds1da177e2005-04-16 15:20:36 -07003205 }
3206
FUJITA Tomonori3c0bf162008-12-05 15:25:23 +09003207 SRpnt = st_allocate_request(STp);
Linus Torvalds1da177e2005-04-16 15:20:36 -07003208 if (!SRpnt)
FUJITA Tomonori3c0bf162008-12-05 15:25:23 +09003209 return STp->buffer->syscall_result;
3210
3211 result = st_scsi_kern_execute(SRpnt, scmd, DMA_NONE, NULL, 0,
3212 timeout, MAX_READY_RETRIES);
3213 if (result)
3214 goto out;
Linus Torvalds1da177e2005-04-16 15:20:36 -07003215
3216 STps->drv_block = STps->drv_file = (-1);
3217 STps->eof = ST_NOEOF;
3218 if ((STp->buffer)->syscall_result != 0) {
3219 result = (-EIO);
3220 if (STp->can_partitions &&
3221 (STp->device)->scsi_level >= SCSI_2 &&
3222 (p = find_partition(STp)) >= 0)
3223 STp->partition = p;
3224 } else {
3225 if (STp->can_partitions) {
3226 STp->partition = partition;
3227 STps = &(STp->ps[partition]);
3228 if (!STps->last_block_valid ||
3229 STps->last_block_visited != block) {
3230 STps->at_sm = 0;
3231 STps->rw = ST_IDLE;
3232 }
3233 } else
3234 STps->at_sm = 0;
3235 if (block == 0)
3236 STps->drv_block = STps->drv_file = 0;
3237 result = 0;
3238 }
FUJITA Tomonori3c0bf162008-12-05 15:25:23 +09003239out:
Mike Christie8b05b772005-11-08 04:06:44 -06003240 st_release_request(SRpnt);
Linus Torvalds1da177e2005-04-16 15:20:36 -07003241 SRpnt = NULL;
3242
3243 return result;
3244}
3245
3246
3247/* Find the current partition number for the drive status. Called from open and
3248 returns either partition number of negative error code. */
3249static int find_partition(struct scsi_tape *STp)
3250{
3251 int i, partition;
3252 unsigned int block;
3253
3254 if ((i = get_location(STp, &block, &partition, 1)) < 0)
3255 return i;
3256 if (partition >= ST_NBR_PARTITIONS)
3257 return (-EIO);
3258 return partition;
3259}
3260
3261
3262/* Change the partition if necessary */
3263static int switch_partition(struct scsi_tape *STp)
3264{
3265 struct st_partstat *STps;
3266
3267 if (STp->partition == STp->new_partition)
3268 return 0;
3269 STps = &(STp->ps[STp->new_partition]);
3270 if (!STps->last_block_valid)
3271 STps->last_block_visited = 0;
3272 return set_location(STp, STps->last_block_visited, STp->new_partition, 1);
3273}
3274
3275/* Functions for reading and writing the medium partition mode page. */
3276
3277#define PART_PAGE 0x11
3278#define PART_PAGE_FIXED_LENGTH 8
3279
3280#define PP_OFF_MAX_ADD_PARTS 2
3281#define PP_OFF_NBR_ADD_PARTS 3
3282#define PP_OFF_FLAGS 4
3283#define PP_OFF_PART_UNITS 6
3284#define PP_OFF_RESERVED 7
3285
3286#define PP_BIT_IDP 0x20
3287#define PP_MSK_PSUM_MB 0x10
3288
3289/* Get the number of partitions on the tape. As a side effect reads the
3290 mode page into the tape buffer. */
3291static int nbr_partitions(struct scsi_tape *STp)
3292{
3293 int result;
3294 DEB( char *name = tape_name(STp); )
3295
3296 if (STp->ready != ST_READY)
3297 return (-EIO);
3298
3299 result = read_mode_page(STp, PART_PAGE, 1);
3300
3301 if (result) {
3302 DEBC(printk(ST_DEB_MSG "%s: Can't read medium partition page.\n",
3303 name));
3304 result = (-EIO);
3305 } else {
3306 result = (STp->buffer)->b_data[MODE_HEADER_LENGTH +
3307 PP_OFF_NBR_ADD_PARTS] + 1;
3308 DEBC(printk(ST_DEB_MSG "%s: Number of partitions %d.\n", name, result));
3309 }
3310
3311 return result;
3312}
3313
3314
3315/* Partition the tape into two partitions if size > 0 or one partition if
3316 size == 0.
3317
3318 The block descriptors are read and written because Sony SDT-7000 does not
3319 work without this (suggestion from Michael Schaefer <Michael.Schaefer@dlr.de>).
3320
3321 My HP C1533A drive returns only one partition size field. This is used to
3322 set the size of partition 1. There is no size field for the default partition.
3323 Michael Schaefer's Sony SDT-7000 returns two descriptors and the second is
3324 used to set the size of partition 1 (this is what the SCSI-3 standard specifies).
3325 The following algorithm is used to accommodate both drives: if the number of
3326 partition size fields is greater than the maximum number of additional partitions
3327 in the mode page, the second field is used. Otherwise the first field is used.
3328
3329 For Seagate DDS drives the page length must be 8 when no partitions is defined
3330 and 10 when 1 partition is defined (information from Eric Lee Green). This is
3331 is acceptable also to some other old drives and enforced if the first partition
3332 size field is used for the first additional partition size.
3333 */
3334static int partition_tape(struct scsi_tape *STp, int size)
3335{
3336 char *name = tape_name(STp);
3337 int result;
3338 int pgo, psd_cnt, psdo;
3339 unsigned char *bp;
3340
3341 result = read_mode_page(STp, PART_PAGE, 0);
3342 if (result) {
3343 DEBC(printk(ST_DEB_MSG "%s: Can't read partition mode page.\n", name));
3344 return result;
3345 }
3346 /* The mode page is in the buffer. Let's modify it and write it. */
3347 bp = (STp->buffer)->b_data;
3348 pgo = MODE_HEADER_LENGTH + bp[MH_OFF_BDESCS_LENGTH];
3349 DEBC(printk(ST_DEB_MSG "%s: Partition page length is %d bytes.\n",
3350 name, bp[pgo + MP_OFF_PAGE_LENGTH] + 2));
3351
3352 psd_cnt = (bp[pgo + MP_OFF_PAGE_LENGTH] + 2 - PART_PAGE_FIXED_LENGTH) / 2;
3353 psdo = pgo + PART_PAGE_FIXED_LENGTH;
3354 if (psd_cnt > bp[pgo + PP_OFF_MAX_ADD_PARTS]) {
3355 bp[psdo] = bp[psdo + 1] = 0xff; /* Rest of the tape */
3356 psdo += 2;
3357 }
3358 memset(bp + psdo, 0, bp[pgo + PP_OFF_NBR_ADD_PARTS] * 2);
3359
3360 DEBC(printk("%s: psd_cnt %d, max.parts %d, nbr_parts %d\n", name,
3361 psd_cnt, bp[pgo + PP_OFF_MAX_ADD_PARTS],
3362 bp[pgo + PP_OFF_NBR_ADD_PARTS]));
3363
3364 if (size <= 0) {
3365 bp[pgo + PP_OFF_NBR_ADD_PARTS] = 0;
3366 if (psd_cnt <= bp[pgo + PP_OFF_MAX_ADD_PARTS])
3367 bp[pgo + MP_OFF_PAGE_LENGTH] = 6;
3368 DEBC(printk(ST_DEB_MSG "%s: Formatting tape with one partition.\n",
3369 name));
3370 } else {
3371 bp[psdo] = (size >> 8) & 0xff;
3372 bp[psdo + 1] = size & 0xff;
3373 bp[pgo + 3] = 1;
3374 if (bp[pgo + MP_OFF_PAGE_LENGTH] < 8)
3375 bp[pgo + MP_OFF_PAGE_LENGTH] = 8;
3376 DEBC(printk(ST_DEB_MSG
3377 "%s: Formatting tape with two partitions (1 = %d MB).\n",
3378 name, size));
3379 }
3380 bp[pgo + PP_OFF_PART_UNITS] = 0;
3381 bp[pgo + PP_OFF_RESERVED] = 0;
3382 bp[pgo + PP_OFF_FLAGS] = PP_BIT_IDP | PP_MSK_PSUM_MB;
3383
3384 result = write_mode_page(STp, PART_PAGE, 1);
3385 if (result) {
3386 printk(KERN_INFO "%s: Partitioning of tape failed.\n", name);
3387 result = (-EIO);
3388 }
3389
3390 return result;
3391}
3392
3393
3394
3395/* The ioctl command */
Kai Makisarafd66c1b2008-01-17 22:45:22 +02003396static long st_ioctl(struct file *file, unsigned int cmd_in, unsigned long arg)
Linus Torvalds1da177e2005-04-16 15:20:36 -07003397{
3398 int i, cmd_nr, cmd_type, bt;
3399 int retval = 0;
3400 unsigned int blk;
3401 struct scsi_tape *STp = file->private_data;
3402 struct st_modedef *STm;
3403 struct st_partstat *STps;
3404 char *name = tape_name(STp);
3405 void __user *p = (void __user *)arg;
3406
Matthias Kaehlcke28f85002007-07-29 23:38:15 +02003407 if (mutex_lock_interruptible(&STp->lock))
Linus Torvalds1da177e2005-04-16 15:20:36 -07003408 return -ERESTARTSYS;
3409
3410 DEB(
3411 if (debugging && !STp->in_use) {
3412 printk(ST_DEB_MSG "%s: Incorrect device.\n", name);
3413 retval = (-EIO);
3414 goto out;
3415 } ) /* end DEB */
3416
3417 STm = &(STp->modes[STp->current_mode]);
3418 STps = &(STp->ps[STp->partition]);
3419
3420 /*
3421 * If we are in the middle of error recovery, don't let anyone
3422 * else try and use this device. Also, if error recovery fails, it
3423 * may try and take the device offline, in which case all further
3424 * access to the device is prohibited.
3425 */
Al Viro83ff6fe2008-03-02 08:15:49 -05003426 retval = scsi_nonblockable_ioctl(STp->device, cmd_in, p,
3427 file->f_flags & O_NDELAY);
Linus Torvalds1da177e2005-04-16 15:20:36 -07003428 if (!scsi_block_when_processing_errors(STp->device) || retval != -ENODEV)
3429 goto out;
3430 retval = 0;
3431
3432 cmd_type = _IOC_TYPE(cmd_in);
3433 cmd_nr = _IOC_NR(cmd_in);
3434
3435 if (cmd_type == _IOC_TYPE(MTIOCTOP) && cmd_nr == _IOC_NR(MTIOCTOP)) {
3436 struct mtop mtc;
3437
3438 if (_IOC_SIZE(cmd_in) != sizeof(mtc)) {
3439 retval = (-EINVAL);
3440 goto out;
3441 }
3442
3443 i = copy_from_user(&mtc, p, sizeof(struct mtop));
3444 if (i) {
3445 retval = (-EFAULT);
3446 goto out;
3447 }
3448
3449 if (mtc.mt_op == MTSETDRVBUFFER && !capable(CAP_SYS_ADMIN)) {
3450 printk(KERN_WARNING
3451 "%s: MTSETDRVBUFFER only allowed for root.\n", name);
3452 retval = (-EPERM);
3453 goto out;
3454 }
3455 if (!STm->defined &&
3456 (mtc.mt_op != MTSETDRVBUFFER &&
3457 (mtc.mt_count & MT_ST_OPTIONS) == 0)) {
3458 retval = (-ENXIO);
3459 goto out;
3460 }
3461
3462 if (!STp->pos_unknown) {
3463
3464 if (STps->eof == ST_FM_HIT) {
3465 if (mtc.mt_op == MTFSF || mtc.mt_op == MTFSFM ||
3466 mtc.mt_op == MTEOM) {
3467 mtc.mt_count -= 1;
3468 if (STps->drv_file >= 0)
3469 STps->drv_file += 1;
3470 } else if (mtc.mt_op == MTBSF || mtc.mt_op == MTBSFM) {
3471 mtc.mt_count += 1;
3472 if (STps->drv_file >= 0)
3473 STps->drv_file += 1;
3474 }
3475 }
3476
3477 if (mtc.mt_op == MTSEEK) {
3478 /* Old position must be restored if partition will be
3479 changed */
3480 i = !STp->can_partitions ||
3481 (STp->new_partition != STp->partition);
3482 } else {
3483 i = mtc.mt_op == MTREW || mtc.mt_op == MTOFFL ||
3484 mtc.mt_op == MTRETEN || mtc.mt_op == MTEOM ||
3485 mtc.mt_op == MTLOCK || mtc.mt_op == MTLOAD ||
3486 mtc.mt_op == MTFSF || mtc.mt_op == MTFSFM ||
3487 mtc.mt_op == MTBSF || mtc.mt_op == MTBSFM ||
3488 mtc.mt_op == MTCOMPRESSION;
3489 }
3490 i = flush_buffer(STp, i);
3491 if (i < 0) {
3492 retval = i;
3493 goto out;
3494 }
3495 if (STps->rw == ST_WRITING &&
3496 (mtc.mt_op == MTREW || mtc.mt_op == MTOFFL ||
3497 mtc.mt_op == MTSEEK ||
3498 mtc.mt_op == MTBSF || mtc.mt_op == MTBSFM)) {
3499 i = st_int_ioctl(STp, MTWEOF, 1);
3500 if (i < 0) {
3501 retval = i;
3502 goto out;
3503 }
3504 if (mtc.mt_op == MTBSF || mtc.mt_op == MTBSFM)
3505 mtc.mt_count++;
3506 STps->rw = ST_IDLE;
3507 }
3508
3509 } else {
3510 /*
3511 * If there was a bus reset, block further access
3512 * to this device. If the user wants to rewind the tape,
3513 * then reset the flag and allow access again.
3514 */
3515 if (mtc.mt_op != MTREW &&
3516 mtc.mt_op != MTOFFL &&
3517 mtc.mt_op != MTRETEN &&
3518 mtc.mt_op != MTERASE &&
3519 mtc.mt_op != MTSEEK &&
3520 mtc.mt_op != MTEOM) {
3521 retval = (-EIO);
3522 goto out;
3523 }
3524 reset_state(STp);
3525 /* remove this when the midlevel properly clears was_reset */
3526 STp->device->was_reset = 0;
3527 }
3528
3529 if (mtc.mt_op != MTNOP && mtc.mt_op != MTSETBLK &&
3530 mtc.mt_op != MTSETDENSITY && mtc.mt_op != MTWSM &&
3531 mtc.mt_op != MTSETDRVBUFFER && mtc.mt_op != MTSETPART)
3532 STps->rw = ST_IDLE; /* Prevent automatic WEOF and fsf */
3533
3534 if (mtc.mt_op == MTOFFL && STp->door_locked != ST_UNLOCKED)
3535 do_door_lock(STp, 0); /* Ignore result! */
3536
3537 if (mtc.mt_op == MTSETDRVBUFFER &&
3538 (mtc.mt_count & MT_ST_OPTIONS) != 0) {
3539 retval = st_set_options(STp, mtc.mt_count);
3540 goto out;
3541 }
3542
3543 if (mtc.mt_op == MTSETPART) {
3544 if (!STp->can_partitions ||
3545 mtc.mt_count < 0 || mtc.mt_count >= ST_NBR_PARTITIONS) {
3546 retval = (-EINVAL);
3547 goto out;
3548 }
3549 if (mtc.mt_count >= STp->nbr_partitions &&
3550 (STp->nbr_partitions = nbr_partitions(STp)) < 0) {
3551 retval = (-EIO);
3552 goto out;
3553 }
3554 if (mtc.mt_count >= STp->nbr_partitions) {
3555 retval = (-EINVAL);
3556 goto out;
3557 }
3558 STp->new_partition = mtc.mt_count;
3559 retval = 0;
3560 goto out;
3561 }
3562
3563 if (mtc.mt_op == MTMKPART) {
3564 if (!STp->can_partitions) {
3565 retval = (-EINVAL);
3566 goto out;
3567 }
3568 if ((i = st_int_ioctl(STp, MTREW, 0)) < 0 ||
3569 (i = partition_tape(STp, mtc.mt_count)) < 0) {
3570 retval = i;
3571 goto out;
3572 }
3573 for (i = 0; i < ST_NBR_PARTITIONS; i++) {
3574 STp->ps[i].rw = ST_IDLE;
3575 STp->ps[i].at_sm = 0;
3576 STp->ps[i].last_block_valid = 0;
3577 }
3578 STp->partition = STp->new_partition = 0;
3579 STp->nbr_partitions = 1; /* Bad guess ?-) */
3580 STps->drv_block = STps->drv_file = 0;
3581 retval = 0;
3582 goto out;
3583 }
3584
3585 if (mtc.mt_op == MTSEEK) {
3586 i = set_location(STp, mtc.mt_count, STp->new_partition, 0);
3587 if (!STp->can_partitions)
3588 STp->ps[0].rw = ST_IDLE;
3589 retval = i;
3590 goto out;
3591 }
3592
3593 if (mtc.mt_op == MTUNLOAD || mtc.mt_op == MTOFFL) {
3594 retval = do_load_unload(STp, file, 0);
3595 goto out;
3596 }
3597
3598 if (mtc.mt_op == MTLOAD) {
3599 retval = do_load_unload(STp, file, max(1, mtc.mt_count));
3600 goto out;
3601 }
3602
3603 if (mtc.mt_op == MTLOCK || mtc.mt_op == MTUNLOCK) {
3604 retval = do_door_lock(STp, (mtc.mt_op == MTLOCK));
3605 goto out;
3606 }
3607
3608 if (STp->can_partitions && STp->ready == ST_READY &&
3609 (i = switch_partition(STp)) < 0) {
3610 retval = i;
3611 goto out;
3612 }
3613
3614 if (mtc.mt_op == MTCOMPRESSION)
3615 retval = st_compression(STp, (mtc.mt_count & 1));
3616 else
3617 retval = st_int_ioctl(STp, mtc.mt_op, mtc.mt_count);
3618 goto out;
3619 }
3620 if (!STm->defined) {
3621 retval = (-ENXIO);
3622 goto out;
3623 }
3624
3625 if ((i = flush_buffer(STp, 0)) < 0) {
3626 retval = i;
3627 goto out;
3628 }
3629 if (STp->can_partitions &&
3630 (i = switch_partition(STp)) < 0) {
3631 retval = i;
3632 goto out;
3633 }
3634
3635 if (cmd_type == _IOC_TYPE(MTIOCGET) && cmd_nr == _IOC_NR(MTIOCGET)) {
3636 struct mtget mt_status;
3637
3638 if (_IOC_SIZE(cmd_in) != sizeof(struct mtget)) {
3639 retval = (-EINVAL);
3640 goto out;
3641 }
3642
3643 mt_status.mt_type = STp->tape_type;
3644 mt_status.mt_dsreg =
3645 ((STp->block_size << MT_ST_BLKSIZE_SHIFT) & MT_ST_BLKSIZE_MASK) |
3646 ((STp->density << MT_ST_DENSITY_SHIFT) & MT_ST_DENSITY_MASK);
3647 mt_status.mt_blkno = STps->drv_block;
3648 mt_status.mt_fileno = STps->drv_file;
3649 if (STp->block_size != 0) {
3650 if (STps->rw == ST_WRITING)
3651 mt_status.mt_blkno +=
3652 (STp->buffer)->buffer_bytes / STp->block_size;
3653 else if (STps->rw == ST_READING)
3654 mt_status.mt_blkno -=
3655 ((STp->buffer)->buffer_bytes +
3656 STp->block_size - 1) / STp->block_size;
3657 }
3658
3659 mt_status.mt_gstat = 0;
3660 if (STp->drv_write_prot)
3661 mt_status.mt_gstat |= GMT_WR_PROT(0xffffffff);
3662 if (mt_status.mt_blkno == 0) {
3663 if (mt_status.mt_fileno == 0)
3664 mt_status.mt_gstat |= GMT_BOT(0xffffffff);
3665 else
3666 mt_status.mt_gstat |= GMT_EOF(0xffffffff);
3667 }
3668 mt_status.mt_erreg = (STp->recover_reg << MT_ST_SOFTERR_SHIFT);
3669 mt_status.mt_resid = STp->partition;
3670 if (STps->eof == ST_EOM_OK || STps->eof == ST_EOM_ERROR)
3671 mt_status.mt_gstat |= GMT_EOT(0xffffffff);
3672 else if (STps->eof >= ST_EOM_OK)
3673 mt_status.mt_gstat |= GMT_EOD(0xffffffff);
3674 if (STp->density == 1)
3675 mt_status.mt_gstat |= GMT_D_800(0xffffffff);
3676 else if (STp->density == 2)
3677 mt_status.mt_gstat |= GMT_D_1600(0xffffffff);
3678 else if (STp->density == 3)
3679 mt_status.mt_gstat |= GMT_D_6250(0xffffffff);
3680 if (STp->ready == ST_READY)
3681 mt_status.mt_gstat |= GMT_ONLINE(0xffffffff);
3682 if (STp->ready == ST_NO_TAPE)
3683 mt_status.mt_gstat |= GMT_DR_OPEN(0xffffffff);
3684 if (STps->at_sm)
3685 mt_status.mt_gstat |= GMT_SM(0xffffffff);
3686 if (STm->do_async_writes ||
3687 (STm->do_buffer_writes && STp->block_size != 0) ||
3688 STp->drv_buffer != 0)
3689 mt_status.mt_gstat |= GMT_IM_REP_EN(0xffffffff);
3690 if (STp->cleaning_req)
3691 mt_status.mt_gstat |= GMT_CLN(0xffffffff);
3692
3693 i = copy_to_user(p, &mt_status, sizeof(struct mtget));
3694 if (i) {
3695 retval = (-EFAULT);
3696 goto out;
3697 }
3698
3699 STp->recover_reg = 0; /* Clear after read */
3700 retval = 0;
3701 goto out;
3702 } /* End of MTIOCGET */
3703 if (cmd_type == _IOC_TYPE(MTIOCPOS) && cmd_nr == _IOC_NR(MTIOCPOS)) {
3704 struct mtpos mt_pos;
3705 if (_IOC_SIZE(cmd_in) != sizeof(struct mtpos)) {
3706 retval = (-EINVAL);
3707 goto out;
3708 }
3709 if ((i = get_location(STp, &blk, &bt, 0)) < 0) {
3710 retval = i;
3711 goto out;
3712 }
3713 mt_pos.mt_blkno = blk;
3714 i = copy_to_user(p, &mt_pos, sizeof(struct mtpos));
3715 if (i)
3716 retval = (-EFAULT);
3717 goto out;
3718 }
Matthias Kaehlcke28f85002007-07-29 23:38:15 +02003719 mutex_unlock(&STp->lock);
Linus Torvalds1da177e2005-04-16 15:20:36 -07003720 switch (cmd_in) {
3721 case SCSI_IOCTL_GET_IDLUN:
3722 case SCSI_IOCTL_GET_BUS_NUMBER:
3723 break;
3724 default:
Kai Makisara 16c4b3e2005-05-01 18:11:55 +03003725 if ((cmd_in == SG_IO ||
3726 cmd_in == SCSI_IOCTL_SEND_COMMAND ||
3727 cmd_in == CDROM_SEND_PACKET) &&
3728 !capable(CAP_SYS_RAWIO))
Linus Torvalds1da177e2005-04-16 15:20:36 -07003729 i = -EPERM;
3730 else
Al Viro74f3c8a2007-08-27 15:38:10 -04003731 i = scsi_cmd_ioctl(STp->disk->queue, STp->disk,
3732 file->f_mode, cmd_in, p);
Linus Torvalds1da177e2005-04-16 15:20:36 -07003733 if (i != -ENOTTY)
3734 return i;
3735 break;
3736 }
Kai Makisara 16c4b3e2005-05-01 18:11:55 +03003737 retval = scsi_ioctl(STp->device, cmd_in, p);
3738 if (!retval && cmd_in == SCSI_IOCTL_STOP_UNIT) { /* unload */
3739 STp->rew_at_close = 0;
3740 STp->ready = ST_NO_TAPE;
3741 }
3742 return retval;
Linus Torvalds1da177e2005-04-16 15:20:36 -07003743
3744 out:
Matthias Kaehlcke28f85002007-07-29 23:38:15 +02003745 mutex_unlock(&STp->lock);
Linus Torvalds1da177e2005-04-16 15:20:36 -07003746 return retval;
3747}
3748
3749#ifdef CONFIG_COMPAT
3750static long st_compat_ioctl(struct file *file, unsigned int cmd, unsigned long arg)
3751{
3752 struct scsi_tape *STp = file->private_data;
3753 struct scsi_device *sdev = STp->device;
3754 int ret = -ENOIOCTLCMD;
3755 if (sdev->host->hostt->compat_ioctl) {
3756
3757 ret = sdev->host->hostt->compat_ioctl(sdev, cmd, (void __user *)arg);
3758
3759 }
3760 return ret;
3761}
3762#endif
3763
3764
3765
3766/* Try to allocate a new tape buffer. Calling function must not hold
3767 dev_arr_lock. */
3768static struct st_buffer *
3769 new_tape_buffer(int from_initialization, int need_dma, int max_sg)
3770{
Mike Christie8b05b772005-11-08 04:06:44 -06003771 int i, got = 0;
Al Viroc53033f2005-10-21 03:22:08 -04003772 gfp_t priority;
Linus Torvalds1da177e2005-04-16 15:20:36 -07003773 struct st_buffer *tb;
3774
3775 if (from_initialization)
3776 priority = GFP_ATOMIC;
3777 else
3778 priority = GFP_KERNEL;
3779
3780 i = sizeof(struct st_buffer) + (max_sg - 1) * sizeof(struct scatterlist) +
3781 max_sg * sizeof(struct st_buf_fragment);
Jes Sorensen24669f752006-01-16 10:31:18 -05003782 tb = kzalloc(i, priority);
Linus Torvalds1da177e2005-04-16 15:20:36 -07003783 if (!tb) {
3784 printk(KERN_NOTICE "st: Can't allocate new tape buffer.\n");
3785 return NULL;
3786 }
Mike Christie8b05b772005-11-08 04:06:44 -06003787 tb->frp_segs = tb->orig_frp_segs = 0;
Linus Torvalds1da177e2005-04-16 15:20:36 -07003788 tb->use_sg = max_sg;
Linus Torvalds1da177e2005-04-16 15:20:36 -07003789 tb->frp = (struct st_buf_fragment *)(&(tb->sg[0]) + max_sg);
3790
Linus Torvalds1da177e2005-04-16 15:20:36 -07003791 tb->dma = need_dma;
3792 tb->buffer_size = got;
FUJITA Tomonoricd816212007-12-15 15:51:55 +09003793 sg_init_table(tb->sg, max_sg);
Linus Torvalds1da177e2005-04-16 15:20:36 -07003794
FUJITA Tomonorid0e1ae32008-12-18 14:49:40 +09003795 tb->reserved_pages = kzalloc(max_sg * sizeof(struct page *), priority);
3796 if (!tb->reserved_pages) {
3797 kfree(tb);
3798 return NULL;
3799 }
3800
Linus Torvalds1da177e2005-04-16 15:20:36 -07003801 return tb;
3802}
3803
3804
3805/* Try to allocate enough space in the tape buffer */
3806static int enlarge_buffer(struct st_buffer * STbuffer, int new_size, int need_dma)
3807{
Al Viroc53033f2005-10-21 03:22:08 -04003808 int segs, nbr, max_segs, b_size, order, got;
3809 gfp_t priority;
Linus Torvalds1da177e2005-04-16 15:20:36 -07003810
3811 if (new_size <= STbuffer->buffer_size)
3812 return 1;
3813
3814 if (STbuffer->buffer_size <= PAGE_SIZE)
3815 normalize_buffer(STbuffer); /* Avoid extra segment */
3816
3817 max_segs = STbuffer->use_sg;
3818 nbr = max_segs - STbuffer->frp_segs;
3819 if (nbr <= 0)
3820 return 0;
3821
3822 priority = GFP_KERNEL | __GFP_NOWARN;
3823 if (need_dma)
3824 priority |= GFP_DMA;
FUJITA Tomonori9c905962008-12-18 14:49:39 +09003825
3826 if (STbuffer->frp_segs) {
3827 b_size = STbuffer->frp[0].length;
3828 order = get_order(b_size);
3829 } else {
3830 for (b_size = PAGE_SIZE, order = 0;
3831 order <= 6 && b_size < new_size; order++, b_size *= 2)
3832 ; /* empty */
3833 }
Linus Torvalds1da177e2005-04-16 15:20:36 -07003834
3835 for (segs = STbuffer->frp_segs, got = STbuffer->buffer_size;
3836 segs < max_segs && got < new_size;) {
3837 STbuffer->frp[segs].page = alloc_pages(priority, order);
3838 if (STbuffer->frp[segs].page == NULL) {
Linus Torvalds1da177e2005-04-16 15:20:36 -07003839 DEB(STbuffer->buffer_size = got);
3840 normalize_buffer(STbuffer);
3841 return 0;
3842 }
3843 STbuffer->frp[segs].length = b_size;
3844 STbuffer->frp_segs += 1;
3845 got += b_size;
3846 STbuffer->buffer_size = got;
Kai Makisara40f6b362008-02-24 22:23:24 +02003847 if (STbuffer->cleared)
3848 memset(page_address(STbuffer->frp[segs].page), 0, b_size);
FUJITA Tomonorid0e1ae32008-12-18 14:49:40 +09003849 STbuffer->reserved_pages[segs] = STbuffer->frp[segs].page;
Linus Torvalds1da177e2005-04-16 15:20:36 -07003850 segs++;
3851 }
3852 STbuffer->b_data = page_address(STbuffer->frp[0].page);
FUJITA Tomonorid0e1ae32008-12-18 14:49:40 +09003853 STbuffer->map_data.page_order = order;
Linus Torvalds1da177e2005-04-16 15:20:36 -07003854
3855 return 1;
3856}
3857
3858
Kai Makisara40f6b362008-02-24 22:23:24 +02003859/* Make sure that no data from previous user is in the internal buffer */
3860static void clear_buffer(struct st_buffer * st_bp)
3861{
3862 int i;
3863
3864 for (i=0; i < st_bp->frp_segs; i++)
3865 memset(page_address(st_bp->frp[i].page), 0, st_bp->frp[i].length);
3866 st_bp->cleared = 1;
3867}
3868
3869
Linus Torvalds1da177e2005-04-16 15:20:36 -07003870/* Release the extra buffer */
3871static void normalize_buffer(struct st_buffer * STbuffer)
3872{
3873 int i, order;
3874
3875 for (i = STbuffer->orig_frp_segs; i < STbuffer->frp_segs; i++) {
3876 order = get_order(STbuffer->frp[i].length);
3877 __free_pages(STbuffer->frp[i].page, order);
3878 STbuffer->buffer_size -= STbuffer->frp[i].length;
3879 }
3880 STbuffer->frp_segs = STbuffer->orig_frp_segs;
3881 STbuffer->frp_sg_current = 0;
Mike Christie8b05b772005-11-08 04:06:44 -06003882 STbuffer->sg_segs = 0;
FUJITA Tomonorid0e1ae32008-12-18 14:49:40 +09003883 STbuffer->map_data.page_order = 0;
3884 STbuffer->map_data.offset = 0;
Linus Torvalds1da177e2005-04-16 15:20:36 -07003885}
3886
3887
3888/* Move data from the user buffer to the tape buffer. Returns zero (success) or
3889 negative error code. */
3890static int append_to_buffer(const char __user *ubp, struct st_buffer * st_bp, int do_count)
3891{
3892 int i, cnt, res, offset;
3893
3894 for (i = 0, offset = st_bp->buffer_bytes;
3895 i < st_bp->frp_segs && offset >= st_bp->frp[i].length; i++)
3896 offset -= st_bp->frp[i].length;
3897 if (i == st_bp->frp_segs) { /* Should never happen */
3898 printk(KERN_WARNING "st: append_to_buffer offset overflow.\n");
3899 return (-EIO);
3900 }
3901 for (; i < st_bp->frp_segs && do_count > 0; i++) {
3902 cnt = st_bp->frp[i].length - offset < do_count ?
3903 st_bp->frp[i].length - offset : do_count;
3904 res = copy_from_user(page_address(st_bp->frp[i].page) + offset, ubp, cnt);
3905 if (res)
3906 return (-EFAULT);
3907 do_count -= cnt;
3908 st_bp->buffer_bytes += cnt;
3909 ubp += cnt;
3910 offset = 0;
3911 }
3912 if (do_count) /* Should never happen */
3913 return (-EIO);
3914
3915 return 0;
3916}
3917
3918
3919/* Move data from the tape buffer to the user buffer. Returns zero (success) or
3920 negative error code. */
3921static int from_buffer(struct st_buffer * st_bp, char __user *ubp, int do_count)
3922{
3923 int i, cnt, res, offset;
3924
3925 for (i = 0, offset = st_bp->read_pointer;
3926 i < st_bp->frp_segs && offset >= st_bp->frp[i].length; i++)
3927 offset -= st_bp->frp[i].length;
3928 if (i == st_bp->frp_segs) { /* Should never happen */
3929 printk(KERN_WARNING "st: from_buffer offset overflow.\n");
3930 return (-EIO);
3931 }
3932 for (; i < st_bp->frp_segs && do_count > 0; i++) {
3933 cnt = st_bp->frp[i].length - offset < do_count ?
3934 st_bp->frp[i].length - offset : do_count;
3935 res = copy_to_user(ubp, page_address(st_bp->frp[i].page) + offset, cnt);
3936 if (res)
3937 return (-EFAULT);
3938 do_count -= cnt;
3939 st_bp->buffer_bytes -= cnt;
3940 st_bp->read_pointer += cnt;
3941 ubp += cnt;
3942 offset = 0;
3943 }
3944 if (do_count) /* Should never happen */
3945 return (-EIO);
3946
3947 return 0;
3948}
3949
3950
3951/* Move data towards start of buffer */
3952static void move_buffer_data(struct st_buffer * st_bp, int offset)
3953{
3954 int src_seg, dst_seg, src_offset = 0, dst_offset;
3955 int count, total;
3956
3957 if (offset == 0)
3958 return;
3959
3960 total=st_bp->buffer_bytes - offset;
3961 for (src_seg=0; src_seg < st_bp->frp_segs; src_seg++) {
3962 src_offset = offset;
3963 if (src_offset < st_bp->frp[src_seg].length)
3964 break;
3965 offset -= st_bp->frp[src_seg].length;
3966 }
3967
3968 st_bp->buffer_bytes = st_bp->read_pointer = total;
3969 for (dst_seg=dst_offset=0; total > 0; ) {
3970 count = min(st_bp->frp[dst_seg].length - dst_offset,
3971 st_bp->frp[src_seg].length - src_offset);
3972 memmove(page_address(st_bp->frp[dst_seg].page) + dst_offset,
3973 page_address(st_bp->frp[src_seg].page) + src_offset, count);
3974 src_offset += count;
3975 if (src_offset >= st_bp->frp[src_seg].length) {
3976 src_seg++;
3977 src_offset = 0;
3978 }
3979 dst_offset += count;
3980 if (dst_offset >= st_bp->frp[dst_seg].length) {
3981 dst_seg++;
3982 dst_offset = 0;
3983 }
3984 total -= count;
3985 }
3986}
3987
3988
3989/* Fill the s/g list up to the length required for this transfer */
3990static void buf_to_sg(struct st_buffer *STbp, unsigned int length)
3991{
3992 int i;
3993 unsigned int count;
3994 struct scatterlist *sg;
3995 struct st_buf_fragment *frp;
3996
3997 if (length == STbp->frp_sg_current)
3998 return; /* work already done */
3999
4000 sg = &(STbp->sg[0]);
4001 frp = STbp->frp;
4002 for (i=count=0; count < length; i++) {
Linus Torvalds1da177e2005-04-16 15:20:36 -07004003 if (length - count > frp[i].length)
Jens Axboe642f1492007-10-24 11:20:47 +02004004 sg_set_page(&sg[i], frp[i].page, frp[i].length, 0);
Linus Torvalds1da177e2005-04-16 15:20:36 -07004005 else
Jens Axboe642f1492007-10-24 11:20:47 +02004006 sg_set_page(&sg[i], frp[i].page, length - count, 0);
Linus Torvalds1da177e2005-04-16 15:20:36 -07004007 count += sg[i].length;
Linus Torvalds1da177e2005-04-16 15:20:36 -07004008 }
4009 STbp->sg_segs = i;
4010 STbp->frp_sg_current = length;
4011}
4012
4013
4014/* Validate the options from command line or module parameters */
4015static void validate_options(void)
4016{
4017 if (buffer_kbs > 0)
4018 st_fixed_buffer_size = buffer_kbs * ST_KILOBYTE;
4019 if (max_sg_segs >= ST_FIRST_SG)
4020 st_max_sg_segs = max_sg_segs;
4021}
4022
4023#ifndef MODULE
4024/* Set the boot options. Syntax is defined in Documenation/scsi/st.txt.
4025 */
4026static int __init st_setup(char *str)
4027{
4028 int i, len, ints[5];
4029 char *stp;
4030
4031 stp = get_options(str, ARRAY_SIZE(ints), ints);
4032
4033 if (ints[0] > 0) {
4034 for (i = 0; i < ints[0] && i < ARRAY_SIZE(parms); i++)
4035 if (parms[i].val)
4036 *parms[i].val = ints[i + 1];
4037 } else {
4038 while (stp != NULL) {
4039 for (i = 0; i < ARRAY_SIZE(parms); i++) {
4040 len = strlen(parms[i].name);
4041 if (!strncmp(stp, parms[i].name, len) &&
4042 (*(stp + len) == ':' || *(stp + len) == '=')) {
4043 if (parms[i].val)
4044 *parms[i].val =
4045 simple_strtoul(stp + len + 1, NULL, 0);
4046 else
4047 printk(KERN_WARNING "st: Obsolete parameter %s\n",
4048 parms[i].name);
4049 break;
4050 }
4051 }
Tobias Klauser6391a112006-06-08 22:23:48 -07004052 if (i >= ARRAY_SIZE(parms))
Linus Torvalds1da177e2005-04-16 15:20:36 -07004053 printk(KERN_WARNING "st: invalid parameter in '%s'\n",
4054 stp);
4055 stp = strchr(stp, ',');
4056 if (stp)
4057 stp++;
4058 }
4059 }
4060
4061 validate_options();
4062
4063 return 1;
4064}
4065
4066__setup("st=", st_setup);
4067
4068#endif
4069
Arjan van de Ven00977a52007-02-12 00:55:34 -08004070static const struct file_operations st_fops =
Linus Torvalds1da177e2005-04-16 15:20:36 -07004071{
4072 .owner = THIS_MODULE,
4073 .read = st_read,
4074 .write = st_write,
Kai Makisarafd66c1b2008-01-17 22:45:22 +02004075 .unlocked_ioctl = st_ioctl,
Linus Torvalds1da177e2005-04-16 15:20:36 -07004076#ifdef CONFIG_COMPAT
4077 .compat_ioctl = st_compat_ioctl,
4078#endif
4079 .open = st_open,
4080 .flush = st_flush,
4081 .release = st_release,
4082};
4083
4084static int st_probe(struct device *dev)
4085{
4086 struct scsi_device *SDp = to_scsi_device(dev);
4087 struct gendisk *disk = NULL;
4088 struct cdev *cdev = NULL;
4089 struct scsi_tape *tpnt = NULL;
4090 struct st_modedef *STm;
4091 struct st_partstat *STps;
4092 struct st_buffer *buffer;
4093 int i, j, mode, dev_num, error;
4094 char *stp;
Linus Torvalds1da177e2005-04-16 15:20:36 -07004095
4096 if (SDp->type != TYPE_TAPE)
4097 return -ENODEV;
4098 if ((stp = st_incompatible(SDp))) {
Jeff Garzik3bf743e2005-10-24 18:04:06 -04004099 sdev_printk(KERN_INFO, SDp, "Found incompatible tape\n");
Linus Torvalds1da177e2005-04-16 15:20:36 -07004100 printk(KERN_INFO "st: The suggested driver is %s.\n", stp);
4101 return -ENODEV;
4102 }
4103
Mike Christie8b05b772005-11-08 04:06:44 -06004104 i = min(SDp->request_queue->max_hw_segments,
4105 SDp->request_queue->max_phys_segments);
Linus Torvalds1da177e2005-04-16 15:20:36 -07004106 if (st_max_sg_segs < i)
4107 i = st_max_sg_segs;
4108 buffer = new_tape_buffer(1, (SDp->host)->unchecked_isa_dma, i);
4109 if (buffer == NULL) {
4110 printk(KERN_ERR
4111 "st: Can't allocate new tape buffer. Device not attached.\n");
4112 goto out;
4113 }
4114
4115 disk = alloc_disk(1);
4116 if (!disk) {
4117 printk(KERN_ERR "st: out of memory. Device not attached.\n");
4118 goto out_buffer_free;
4119 }
4120
4121 write_lock(&st_dev_arr_lock);
4122 if (st_nr_dev >= st_dev_max) {
4123 struct scsi_tape **tmp_da;
4124 int tmp_dev_max;
4125
4126 tmp_dev_max = max(st_nr_dev * 2, 8);
4127 if (tmp_dev_max > ST_MAX_TAPES)
4128 tmp_dev_max = ST_MAX_TAPES;
4129 if (tmp_dev_max <= st_nr_dev) {
4130 write_unlock(&st_dev_arr_lock);
4131 printk(KERN_ERR "st: Too many tape devices (max. %d).\n",
4132 ST_MAX_TAPES);
4133 goto out_put_disk;
4134 }
4135
Jes Sorensen24669f752006-01-16 10:31:18 -05004136 tmp_da = kzalloc(tmp_dev_max * sizeof(struct scsi_tape *), GFP_ATOMIC);
Linus Torvalds1da177e2005-04-16 15:20:36 -07004137 if (tmp_da == NULL) {
4138 write_unlock(&st_dev_arr_lock);
4139 printk(KERN_ERR "st: Can't extend device array.\n");
4140 goto out_put_disk;
4141 }
4142
Linus Torvalds1da177e2005-04-16 15:20:36 -07004143 if (scsi_tapes != NULL) {
4144 memcpy(tmp_da, scsi_tapes,
4145 st_dev_max * sizeof(struct scsi_tape *));
4146 kfree(scsi_tapes);
4147 }
4148 scsi_tapes = tmp_da;
4149
4150 st_dev_max = tmp_dev_max;
4151 }
4152
4153 for (i = 0; i < st_dev_max; i++)
4154 if (scsi_tapes[i] == NULL)
4155 break;
4156 if (i >= st_dev_max)
4157 panic("scsi_devices corrupt (st)");
4158
Jes Sorensen24669f752006-01-16 10:31:18 -05004159 tpnt = kzalloc(sizeof(struct scsi_tape), GFP_ATOMIC);
Linus Torvalds1da177e2005-04-16 15:20:36 -07004160 if (tpnt == NULL) {
4161 write_unlock(&st_dev_arr_lock);
4162 printk(KERN_ERR "st: Can't allocate device descriptor.\n");
4163 goto out_put_disk;
4164 }
Kai Makisaraf03a5672005-08-02 13:40:47 +03004165 kref_init(&tpnt->kref);
Linus Torvalds1da177e2005-04-16 15:20:36 -07004166 tpnt->disk = disk;
4167 sprintf(disk->disk_name, "st%d", i);
4168 disk->private_data = &tpnt->driver;
4169 disk->queue = SDp->request_queue;
4170 tpnt->driver = &st_template;
4171 scsi_tapes[i] = tpnt;
4172 dev_num = i;
4173
4174 tpnt->device = SDp;
4175 if (SDp->scsi_level <= 2)
4176 tpnt->tape_type = MT_ISSCSI1;
4177 else
4178 tpnt->tape_type = MT_ISSCSI2;
4179
4180 tpnt->buffer = buffer;
Kai Makisaraf03a5672005-08-02 13:40:47 +03004181 tpnt->buffer->last_SRpnt = NULL;
Linus Torvalds1da177e2005-04-16 15:20:36 -07004182
4183 tpnt->inited = 0;
4184 tpnt->dirty = 0;
4185 tpnt->in_use = 0;
4186 tpnt->drv_buffer = 1; /* Try buffering if no mode sense */
4187 tpnt->restr_dma = (SDp->host)->unchecked_isa_dma;
4188 tpnt->use_pf = (SDp->scsi_level >= SCSI_2);
4189 tpnt->density = 0;
4190 tpnt->do_auto_lock = ST_AUTO_LOCK;
4191 tpnt->can_bsr = (SDp->scsi_level > 2 ? 1 : ST_IN_FILE_POS); /* BSR mandatory in SCSI3 */
4192 tpnt->can_partitions = 0;
4193 tpnt->two_fm = ST_TWO_FM;
4194 tpnt->fast_mteom = ST_FAST_MTEOM;
4195 tpnt->scsi2_logical = ST_SCSI2LOGICAL;
Kai Makisara40f6b362008-02-24 22:23:24 +02004196 tpnt->sili = ST_SILI;
Linus Torvalds1da177e2005-04-16 15:20:36 -07004197 tpnt->immediate = ST_NOWAIT;
4198 tpnt->default_drvbuffer = 0xff; /* No forced buffering */
4199 tpnt->partition = 0;
4200 tpnt->new_partition = 0;
4201 tpnt->nbr_partitions = 0;
James Bottomleya02488e2008-11-30 10:36:26 -06004202 blk_queue_rq_timeout(tpnt->device->request_queue, ST_TIMEOUT);
Linus Torvalds1da177e2005-04-16 15:20:36 -07004203 tpnt->long_timeout = ST_LONG_TIMEOUT;
4204 tpnt->try_dio = try_direct_io && !SDp->host->unchecked_isa_dma;
4205
Linus Torvalds1da177e2005-04-16 15:20:36 -07004206 for (i = 0; i < ST_NBR_MODES; i++) {
4207 STm = &(tpnt->modes[i]);
4208 STm->defined = 0;
4209 STm->sysv = ST_SYSV;
4210 STm->defaults_for_writes = 0;
4211 STm->do_async_writes = ST_ASYNC_WRITES;
4212 STm->do_buffer_writes = ST_BUFFER_WRITES;
4213 STm->do_read_ahead = ST_READ_AHEAD;
4214 STm->default_compression = ST_DONT_TOUCH;
4215 STm->default_blksize = (-1); /* No forced size */
4216 STm->default_density = (-1); /* No forced density */
4217 }
4218
4219 for (i = 0; i < ST_NBR_PARTITIONS; i++) {
4220 STps = &(tpnt->ps[i]);
4221 STps->rw = ST_IDLE;
4222 STps->eof = ST_NOEOF;
4223 STps->at_sm = 0;
4224 STps->last_block_valid = 0;
4225 STps->drv_block = (-1);
4226 STps->drv_file = (-1);
4227 }
4228
4229 tpnt->current_mode = 0;
4230 tpnt->modes[0].defined = 1;
4231
4232 tpnt->density_changed = tpnt->compression_changed =
4233 tpnt->blksize_changed = 0;
Matthias Kaehlcke28f85002007-07-29 23:38:15 +02004234 mutex_init(&tpnt->lock);
Linus Torvalds1da177e2005-04-16 15:20:36 -07004235
4236 st_nr_dev++;
4237 write_unlock(&st_dev_arr_lock);
4238
4239 for (mode = 0; mode < ST_NBR_MODES; ++mode) {
4240 STm = &(tpnt->modes[mode]);
4241 for (j=0; j < 2; j++) {
4242 cdev = cdev_alloc();
4243 if (!cdev) {
4244 printk(KERN_ERR
4245 "st%d: out of memory. Device not attached.\n",
4246 dev_num);
4247 goto out_free_tape;
4248 }
4249 cdev->owner = THIS_MODULE;
4250 cdev->ops = &st_fops;
4251
4252 error = cdev_add(cdev,
4253 MKDEV(SCSI_TAPE_MAJOR, TAPE_MINOR(dev_num, mode, j)),
4254 1);
4255 if (error) {
4256 printk(KERN_ERR "st%d: Can't add %s-rewind mode %d\n",
4257 dev_num, j ? "non" : "auto", mode);
4258 printk(KERN_ERR "st%d: Device not attached.\n", dev_num);
4259 goto out_free_tape;
4260 }
4261 STm->cdevs[j] = cdev;
4262
4263 }
Jeff Garzik13026a62006-10-04 06:00:38 -04004264 error = do_create_class_files(tpnt, dev_num, mode);
4265 if (error)
4266 goto out_free_tape;
Linus Torvalds1da177e2005-04-16 15:20:36 -07004267 }
4268
Kai Makisara42252852006-11-07 21:56:38 +02004269 sdev_printk(KERN_NOTICE, SDp,
Rene Herman8b1ea242006-05-20 15:00:22 -07004270 "Attached scsi tape %s\n", tape_name(tpnt));
Kai Makisara42252852006-11-07 21:56:38 +02004271 sdev_printk(KERN_INFO, SDp, "%s: try direct i/o: %s (alignment %d B)\n",
4272 tape_name(tpnt), tpnt->try_dio ? "yes" : "no",
4273 queue_dma_alignment(SDp->request_queue) + 1);
Linus Torvalds1da177e2005-04-16 15:20:36 -07004274
4275 return 0;
4276
4277out_free_tape:
4278 for (mode=0; mode < ST_NBR_MODES; mode++) {
4279 STm = &(tpnt->modes[mode]);
4280 sysfs_remove_link(&tpnt->device->sdev_gendev.kobj,
4281 "tape");
4282 for (j=0; j < 2; j++) {
4283 if (STm->cdevs[j]) {
4284 if (cdev == STm->cdevs[j])
4285 cdev = NULL;
Tony Jonesee959b02008-02-22 00:13:36 +01004286 device_destroy(st_sysfs_class,
4287 MKDEV(SCSI_TAPE_MAJOR,
4288 TAPE_MINOR(i, mode, j)));
Linus Torvalds1da177e2005-04-16 15:20:36 -07004289 cdev_del(STm->cdevs[j]);
4290 }
4291 }
4292 }
4293 if (cdev)
4294 cdev_del(cdev);
4295 write_lock(&st_dev_arr_lock);
4296 scsi_tapes[dev_num] = NULL;
4297 st_nr_dev--;
4298 write_unlock(&st_dev_arr_lock);
4299out_put_disk:
4300 put_disk(disk);
Jesper Juhlc9475cb2005-11-07 01:01:26 -08004301 kfree(tpnt);
Linus Torvalds1da177e2005-04-16 15:20:36 -07004302out_buffer_free:
4303 kfree(buffer);
4304out:
4305 return -ENODEV;
4306};
4307
4308
4309static int st_remove(struct device *dev)
4310{
4311 struct scsi_device *SDp = to_scsi_device(dev);
4312 struct scsi_tape *tpnt;
4313 int i, j, mode;
4314
4315 write_lock(&st_dev_arr_lock);
4316 for (i = 0; i < st_dev_max; i++) {
4317 tpnt = scsi_tapes[i];
4318 if (tpnt != NULL && tpnt->device == SDp) {
4319 scsi_tapes[i] = NULL;
4320 st_nr_dev--;
4321 write_unlock(&st_dev_arr_lock);
Linus Torvalds1da177e2005-04-16 15:20:36 -07004322 sysfs_remove_link(&tpnt->device->sdev_gendev.kobj,
4323 "tape");
4324 for (mode = 0; mode < ST_NBR_MODES; ++mode) {
Linus Torvalds1da177e2005-04-16 15:20:36 -07004325 for (j=0; j < 2; j++) {
Tony Jonesee959b02008-02-22 00:13:36 +01004326 device_destroy(st_sysfs_class,
4327 MKDEV(SCSI_TAPE_MAJOR,
4328 TAPE_MINOR(i, mode, j)));
Linus Torvalds1da177e2005-04-16 15:20:36 -07004329 cdev_del(tpnt->modes[mode].cdevs[j]);
4330 tpnt->modes[mode].cdevs[j] = NULL;
4331 }
4332 }
Linus Torvalds1da177e2005-04-16 15:20:36 -07004333
Arjan van de Ven0b950672006-01-11 13:16:10 +01004334 mutex_lock(&st_ref_mutex);
Kai Makisaraf03a5672005-08-02 13:40:47 +03004335 kref_put(&tpnt->kref, scsi_tape_release);
Arjan van de Ven0b950672006-01-11 13:16:10 +01004336 mutex_unlock(&st_ref_mutex);
Linus Torvalds1da177e2005-04-16 15:20:36 -07004337 return 0;
4338 }
4339 }
4340
4341 write_unlock(&st_dev_arr_lock);
4342 return 0;
4343}
4344
Kai Makisaraf03a5672005-08-02 13:40:47 +03004345/**
4346 * scsi_tape_release - Called to free the Scsi_Tape structure
4347 * @kref: pointer to embedded kref
4348 *
Arjan van de Ven0b950672006-01-11 13:16:10 +01004349 * st_ref_mutex must be held entering this routine. Because it is
Kai Makisaraf03a5672005-08-02 13:40:47 +03004350 * called on last put, you should always use the scsi_tape_get()
4351 * scsi_tape_put() helpers which manipulate the semaphore directly
4352 * and never do a direct kref_put().
4353 **/
4354static void scsi_tape_release(struct kref *kref)
4355{
4356 struct scsi_tape *tpnt = to_scsi_tape(kref);
4357 struct gendisk *disk = tpnt->disk;
4358
4359 tpnt->device = NULL;
4360
4361 if (tpnt->buffer) {
4362 tpnt->buffer->orig_frp_segs = 0;
4363 normalize_buffer(tpnt->buffer);
FUJITA Tomonorid0e1ae32008-12-18 14:49:40 +09004364 kfree(tpnt->buffer->reserved_pages);
Kai Makisaraf03a5672005-08-02 13:40:47 +03004365 kfree(tpnt->buffer);
4366 }
4367
4368 disk->private_data = NULL;
4369 put_disk(disk);
4370 kfree(tpnt);
4371 return;
4372}
4373
Linus Torvalds1da177e2005-04-16 15:20:36 -07004374static int __init init_st(void)
4375{
Jeff Garzik13026a62006-10-04 06:00:38 -04004376 int err;
4377
Linus Torvalds1da177e2005-04-16 15:20:36 -07004378 validate_options();
4379
Jeff Garzik13026a62006-10-04 06:00:38 -04004380 printk(KERN_INFO "st: Version %s, fixed bufsize %d, s/g segs %d\n",
Linus Torvalds1da177e2005-04-16 15:20:36 -07004381 verstr, st_fixed_buffer_size, st_max_sg_segs);
4382
gregkh@suse.ded2538782005-03-23 09:55:22 -08004383 st_sysfs_class = class_create(THIS_MODULE, "scsi_tape");
Linus Torvalds1da177e2005-04-16 15:20:36 -07004384 if (IS_ERR(st_sysfs_class)) {
Linus Torvalds1da177e2005-04-16 15:20:36 -07004385 printk(KERN_ERR "Unable create sysfs class for SCSI tapes\n");
Jeff Garzik13026a62006-10-04 06:00:38 -04004386 return PTR_ERR(st_sysfs_class);
Linus Torvalds1da177e2005-04-16 15:20:36 -07004387 }
4388
Jeff Garzik13026a62006-10-04 06:00:38 -04004389 err = register_chrdev_region(MKDEV(SCSI_TAPE_MAJOR, 0),
4390 ST_MAX_TAPE_ENTRIES, "st");
4391 if (err) {
4392 printk(KERN_ERR "Unable to get major %d for SCSI tapes\n",
4393 SCSI_TAPE_MAJOR);
4394 goto err_class;
Linus Torvalds1da177e2005-04-16 15:20:36 -07004395 }
Jeff Garzik13026a62006-10-04 06:00:38 -04004396
4397 err = scsi_register_driver(&st_template.gendrv);
4398 if (err)
4399 goto err_chrdev;
4400
Robert P. J. Day405ae7d2007-02-17 19:13:42 +01004401 err = do_create_sysfs_files();
Jeff Garzik13026a62006-10-04 06:00:38 -04004402 if (err)
4403 goto err_scsidrv;
4404
4405 return 0;
4406
4407err_scsidrv:
4408 scsi_unregister_driver(&st_template.gendrv);
4409err_chrdev:
4410 unregister_chrdev_region(MKDEV(SCSI_TAPE_MAJOR, 0),
4411 ST_MAX_TAPE_ENTRIES);
4412err_class:
Kai Makisarac2c96f42005-08-02 12:21:51 +03004413 class_destroy(st_sysfs_class);
Jeff Garzik13026a62006-10-04 06:00:38 -04004414 return err;
Linus Torvalds1da177e2005-04-16 15:20:36 -07004415}
4416
4417static void __exit exit_st(void)
4418{
Robert P. J. Day405ae7d2007-02-17 19:13:42 +01004419 do_remove_sysfs_files();
Linus Torvalds1da177e2005-04-16 15:20:36 -07004420 scsi_unregister_driver(&st_template.gendrv);
4421 unregister_chrdev_region(MKDEV(SCSI_TAPE_MAJOR, 0),
4422 ST_MAX_TAPE_ENTRIES);
Kai Makisarac2c96f42005-08-02 12:21:51 +03004423 class_destroy(st_sysfs_class);
Linus Torvalds1da177e2005-04-16 15:20:36 -07004424 kfree(scsi_tapes);
4425 printk(KERN_INFO "st: Unloaded.\n");
4426}
4427
4428module_init(init_st);
4429module_exit(exit_st);
4430
4431
4432/* The sysfs driver interface. Read-only at the moment */
4433static ssize_t st_try_direct_io_show(struct device_driver *ddp, char *buf)
4434{
4435 return snprintf(buf, PAGE_SIZE, "%d\n", try_direct_io);
4436}
4437static DRIVER_ATTR(try_direct_io, S_IRUGO, st_try_direct_io_show, NULL);
4438
4439static ssize_t st_fixed_buffer_size_show(struct device_driver *ddp, char *buf)
4440{
4441 return snprintf(buf, PAGE_SIZE, "%d\n", st_fixed_buffer_size);
4442}
4443static DRIVER_ATTR(fixed_buffer_size, S_IRUGO, st_fixed_buffer_size_show, NULL);
4444
4445static ssize_t st_max_sg_segs_show(struct device_driver *ddp, char *buf)
4446{
4447 return snprintf(buf, PAGE_SIZE, "%d\n", st_max_sg_segs);
4448}
4449static DRIVER_ATTR(max_sg_segs, S_IRUGO, st_max_sg_segs_show, NULL);
4450
4451static ssize_t st_version_show(struct device_driver *ddd, char *buf)
4452{
4453 return snprintf(buf, PAGE_SIZE, "[%s]\n", verstr);
4454}
4455static DRIVER_ATTR(version, S_IRUGO, st_version_show, NULL);
4456
Robert P. J. Day405ae7d2007-02-17 19:13:42 +01004457static int do_create_sysfs_files(void)
Linus Torvalds1da177e2005-04-16 15:20:36 -07004458{
Robert P. J. Day405ae7d2007-02-17 19:13:42 +01004459 struct device_driver *sysfs = &st_template.gendrv;
Jeff Garzik13026a62006-10-04 06:00:38 -04004460 int err;
Linus Torvalds1da177e2005-04-16 15:20:36 -07004461
Robert P. J. Day405ae7d2007-02-17 19:13:42 +01004462 err = driver_create_file(sysfs, &driver_attr_try_direct_io);
Jeff Garzik13026a62006-10-04 06:00:38 -04004463 if (err)
4464 return err;
Robert P. J. Day405ae7d2007-02-17 19:13:42 +01004465 err = driver_create_file(sysfs, &driver_attr_fixed_buffer_size);
Jeff Garzik13026a62006-10-04 06:00:38 -04004466 if (err)
4467 goto err_try_direct_io;
Robert P. J. Day405ae7d2007-02-17 19:13:42 +01004468 err = driver_create_file(sysfs, &driver_attr_max_sg_segs);
Jeff Garzik13026a62006-10-04 06:00:38 -04004469 if (err)
4470 goto err_attr_fixed_buf;
Robert P. J. Day405ae7d2007-02-17 19:13:42 +01004471 err = driver_create_file(sysfs, &driver_attr_version);
Jeff Garzik13026a62006-10-04 06:00:38 -04004472 if (err)
4473 goto err_attr_max_sg;
4474
4475 return 0;
4476
4477err_attr_max_sg:
Robert P. J. Day405ae7d2007-02-17 19:13:42 +01004478 driver_remove_file(sysfs, &driver_attr_max_sg_segs);
Jeff Garzik13026a62006-10-04 06:00:38 -04004479err_attr_fixed_buf:
Robert P. J. Day405ae7d2007-02-17 19:13:42 +01004480 driver_remove_file(sysfs, &driver_attr_fixed_buffer_size);
Jeff Garzik13026a62006-10-04 06:00:38 -04004481err_try_direct_io:
Robert P. J. Day405ae7d2007-02-17 19:13:42 +01004482 driver_remove_file(sysfs, &driver_attr_try_direct_io);
Jeff Garzik13026a62006-10-04 06:00:38 -04004483 return err;
Linus Torvalds1da177e2005-04-16 15:20:36 -07004484}
4485
Robert P. J. Day405ae7d2007-02-17 19:13:42 +01004486static void do_remove_sysfs_files(void)
Linus Torvalds1da177e2005-04-16 15:20:36 -07004487{
Robert P. J. Day405ae7d2007-02-17 19:13:42 +01004488 struct device_driver *sysfs = &st_template.gendrv;
Linus Torvalds1da177e2005-04-16 15:20:36 -07004489
Robert P. J. Day405ae7d2007-02-17 19:13:42 +01004490 driver_remove_file(sysfs, &driver_attr_version);
4491 driver_remove_file(sysfs, &driver_attr_max_sg_segs);
4492 driver_remove_file(sysfs, &driver_attr_fixed_buffer_size);
4493 driver_remove_file(sysfs, &driver_attr_try_direct_io);
Linus Torvalds1da177e2005-04-16 15:20:36 -07004494}
4495
4496
4497/* The sysfs simple class interface */
Tony Jonesee959b02008-02-22 00:13:36 +01004498static ssize_t
4499st_defined_show(struct device *dev, struct device_attribute *attr, char *buf)
Linus Torvalds1da177e2005-04-16 15:20:36 -07004500{
James Bottomley7d15d6a2008-03-14 14:12:43 -07004501 struct st_modedef *STm = dev_get_drvdata(dev);
Linus Torvalds1da177e2005-04-16 15:20:36 -07004502 ssize_t l = 0;
4503
4504 l = snprintf(buf, PAGE_SIZE, "%d\n", STm->defined);
4505 return l;
4506}
4507
Tony Jonesee959b02008-02-22 00:13:36 +01004508DEVICE_ATTR(defined, S_IRUGO, st_defined_show, NULL);
Linus Torvalds1da177e2005-04-16 15:20:36 -07004509
Tony Jonesee959b02008-02-22 00:13:36 +01004510static ssize_t
4511st_defblk_show(struct device *dev, struct device_attribute *attr, char *buf)
Linus Torvalds1da177e2005-04-16 15:20:36 -07004512{
James Bottomley7d15d6a2008-03-14 14:12:43 -07004513 struct st_modedef *STm = dev_get_drvdata(dev);
Linus Torvalds1da177e2005-04-16 15:20:36 -07004514 ssize_t l = 0;
4515
4516 l = snprintf(buf, PAGE_SIZE, "%d\n", STm->default_blksize);
4517 return l;
4518}
4519
Tony Jonesee959b02008-02-22 00:13:36 +01004520DEVICE_ATTR(default_blksize, S_IRUGO, st_defblk_show, NULL);
Linus Torvalds1da177e2005-04-16 15:20:36 -07004521
Tony Jonesee959b02008-02-22 00:13:36 +01004522static ssize_t
4523st_defdensity_show(struct device *dev, struct device_attribute *attr, char *buf)
Linus Torvalds1da177e2005-04-16 15:20:36 -07004524{
James Bottomley7d15d6a2008-03-14 14:12:43 -07004525 struct st_modedef *STm = dev_get_drvdata(dev);
Linus Torvalds1da177e2005-04-16 15:20:36 -07004526 ssize_t l = 0;
4527 char *fmt;
4528
4529 fmt = STm->default_density >= 0 ? "0x%02x\n" : "%d\n";
4530 l = snprintf(buf, PAGE_SIZE, fmt, STm->default_density);
4531 return l;
4532}
4533
Tony Jonesee959b02008-02-22 00:13:36 +01004534DEVICE_ATTR(default_density, S_IRUGO, st_defdensity_show, NULL);
Linus Torvalds1da177e2005-04-16 15:20:36 -07004535
Tony Jonesee959b02008-02-22 00:13:36 +01004536static ssize_t
4537st_defcompression_show(struct device *dev, struct device_attribute *attr,
4538 char *buf)
Linus Torvalds1da177e2005-04-16 15:20:36 -07004539{
James Bottomley7d15d6a2008-03-14 14:12:43 -07004540 struct st_modedef *STm = dev_get_drvdata(dev);
Linus Torvalds1da177e2005-04-16 15:20:36 -07004541 ssize_t l = 0;
4542
4543 l = snprintf(buf, PAGE_SIZE, "%d\n", STm->default_compression - 1);
4544 return l;
4545}
4546
Tony Jonesee959b02008-02-22 00:13:36 +01004547DEVICE_ATTR(default_compression, S_IRUGO, st_defcompression_show, NULL);
Linus Torvalds1da177e2005-04-16 15:20:36 -07004548
Tony Jonesee959b02008-02-22 00:13:36 +01004549static ssize_t
4550st_options_show(struct device *dev, struct device_attribute *attr, char *buf)
Kai Makisarab174be02008-02-24 22:29:12 +02004551{
James Bottomley7d15d6a2008-03-14 14:12:43 -07004552 struct st_modedef *STm = dev_get_drvdata(dev);
Kai Makisarab174be02008-02-24 22:29:12 +02004553 struct scsi_tape *STp;
4554 int i, j, options;
4555 ssize_t l = 0;
4556
4557 for (i=0; i < st_dev_max; i++) {
4558 for (j=0; j < ST_NBR_MODES; j++)
4559 if (&scsi_tapes[i]->modes[j] == STm)
4560 break;
4561 if (j < ST_NBR_MODES)
4562 break;
4563 }
4564 if (i == st_dev_max)
4565 return 0; /* should never happen */
4566
4567 STp = scsi_tapes[i];
4568
4569 options = STm->do_buffer_writes ? MT_ST_BUFFER_WRITES : 0;
4570 options |= STm->do_async_writes ? MT_ST_ASYNC_WRITES : 0;
4571 options |= STm->do_read_ahead ? MT_ST_READ_AHEAD : 0;
4572 DEB( options |= debugging ? MT_ST_DEBUGGING : 0 );
4573 options |= STp->two_fm ? MT_ST_TWO_FM : 0;
4574 options |= STp->fast_mteom ? MT_ST_FAST_MTEOM : 0;
4575 options |= STm->defaults_for_writes ? MT_ST_DEF_WRITES : 0;
4576 options |= STp->can_bsr ? MT_ST_CAN_BSR : 0;
4577 options |= STp->omit_blklims ? MT_ST_NO_BLKLIMS : 0;
4578 options |= STp->can_partitions ? MT_ST_CAN_PARTITIONS : 0;
4579 options |= STp->scsi2_logical ? MT_ST_SCSI2LOGICAL : 0;
4580 options |= STm->sysv ? MT_ST_SYSV : 0;
4581 options |= STp->immediate ? MT_ST_NOWAIT : 0;
4582 options |= STp->sili ? MT_ST_SILI : 0;
4583
4584 l = snprintf(buf, PAGE_SIZE, "0x%08x\n", options);
4585 return l;
4586}
4587
Tony Jonesee959b02008-02-22 00:13:36 +01004588DEVICE_ATTR(options, S_IRUGO, st_options_show, NULL);
Kai Makisarab174be02008-02-24 22:29:12 +02004589
Jeff Garzik13026a62006-10-04 06:00:38 -04004590static int do_create_class_files(struct scsi_tape *STp, int dev_num, int mode)
Linus Torvalds1da177e2005-04-16 15:20:36 -07004591{
4592 int i, rew, error;
4593 char name[10];
Tony Jonesee959b02008-02-22 00:13:36 +01004594 struct device *st_class_member;
Linus Torvalds1da177e2005-04-16 15:20:36 -07004595
Linus Torvalds1da177e2005-04-16 15:20:36 -07004596 for (rew=0; rew < 2; rew++) {
4597 /* Make sure that the minor numbers corresponding to the four
4598 first modes always get the same names */
4599 i = mode << (4 - ST_NBR_MODE_BITS);
4600 snprintf(name, 10, "%s%s%s", rew ? "n" : "",
4601 STp->disk->disk_name, st_formats[i]);
4602 st_class_member =
Greg Kroah-Hartmand73a1a62008-07-21 20:03:34 -07004603 device_create(st_sysfs_class, &STp->device->sdev_gendev,
4604 MKDEV(SCSI_TAPE_MAJOR,
4605 TAPE_MINOR(dev_num, mode, rew)),
4606 &STp->modes[mode], "%s", name);
Linus Torvalds1da177e2005-04-16 15:20:36 -07004607 if (IS_ERR(st_class_member)) {
Tony Jonesee959b02008-02-22 00:13:36 +01004608 printk(KERN_WARNING "st%d: device_create failed\n",
Linus Torvalds1da177e2005-04-16 15:20:36 -07004609 dev_num);
Jeff Garzik13026a62006-10-04 06:00:38 -04004610 error = PTR_ERR(st_class_member);
Linus Torvalds1da177e2005-04-16 15:20:36 -07004611 goto out;
4612 }
Linus Torvalds1da177e2005-04-16 15:20:36 -07004613
Tony Jonesee959b02008-02-22 00:13:36 +01004614 error = device_create_file(st_class_member,
4615 &dev_attr_defined);
Jeff Garzik13026a62006-10-04 06:00:38 -04004616 if (error) goto out;
Tony Jonesee959b02008-02-22 00:13:36 +01004617 error = device_create_file(st_class_member,
4618 &dev_attr_default_blksize);
Jeff Garzik13026a62006-10-04 06:00:38 -04004619 if (error) goto out;
Tony Jonesee959b02008-02-22 00:13:36 +01004620 error = device_create_file(st_class_member,
4621 &dev_attr_default_density);
Jeff Garzik13026a62006-10-04 06:00:38 -04004622 if (error) goto out;
Tony Jonesee959b02008-02-22 00:13:36 +01004623 error = device_create_file(st_class_member,
4624 &dev_attr_default_compression);
Jeff Garzik13026a62006-10-04 06:00:38 -04004625 if (error) goto out;
Tony Jonesee959b02008-02-22 00:13:36 +01004626 error = device_create_file(st_class_member,
4627 &dev_attr_options);
Kai Makisarab174be02008-02-24 22:29:12 +02004628 if (error) goto out;
Jeff Garzik13026a62006-10-04 06:00:38 -04004629
Linus Torvalds1da177e2005-04-16 15:20:36 -07004630 if (mode == 0 && rew == 0) {
4631 error = sysfs_create_link(&STp->device->sdev_gendev.kobj,
4632 &st_class_member->kobj,
4633 "tape");
4634 if (error) {
4635 printk(KERN_ERR
4636 "st%d: Can't create sysfs link from SCSI device.\n",
4637 dev_num);
Jeff Garzik13026a62006-10-04 06:00:38 -04004638 goto out;
Linus Torvalds1da177e2005-04-16 15:20:36 -07004639 }
4640 }
4641 }
Jeff Garzik13026a62006-10-04 06:00:38 -04004642
4643 return 0;
4644
4645out:
4646 return error;
Linus Torvalds1da177e2005-04-16 15:20:36 -07004647}
4648
Linus Torvalds1da177e2005-04-16 15:20:36 -07004649/* The following functions may be useful for a larger audience. */
4650static int sgl_map_user_pages(struct scatterlist *sgl, const unsigned int max_pages,
4651 unsigned long uaddr, size_t count, int rw)
4652{
James Bottomley07542b82005-08-31 20:27:22 -04004653 unsigned long end = (uaddr + count + PAGE_SIZE - 1) >> PAGE_SHIFT;
4654 unsigned long start = uaddr >> PAGE_SHIFT;
4655 const int nr_pages = end - start;
Linus Torvalds1da177e2005-04-16 15:20:36 -07004656 int res, i, j;
Linus Torvalds1da177e2005-04-16 15:20:36 -07004657 struct page **pages;
4658
Linus Torvalds1da177e2005-04-16 15:20:36 -07004659 /* User attempted Overflow! */
4660 if ((uaddr + count) < uaddr)
4661 return -EINVAL;
4662
4663 /* Too big */
4664 if (nr_pages > max_pages)
4665 return -ENOMEM;
4666
4667 /* Hmm? */
4668 if (count == 0)
4669 return 0;
4670
4671 if ((pages = kmalloc(max_pages * sizeof(*pages), GFP_KERNEL)) == NULL)
4672 return -ENOMEM;
4673
4674 /* Try to fault in all of the necessary pages */
4675 down_read(&current->mm->mmap_sem);
4676 /* rw==READ means read from drive, write into memory area */
4677 res = get_user_pages(
4678 current,
4679 current->mm,
4680 uaddr,
4681 nr_pages,
4682 rw == READ,
4683 0, /* don't force */
4684 pages,
4685 NULL);
4686 up_read(&current->mm->mmap_sem);
4687
4688 /* Errors and no page mapped should return here */
4689 if (res < nr_pages)
4690 goto out_unmap;
4691
4692 for (i=0; i < nr_pages; i++) {
4693 /* FIXME: flush superflous for rw==READ,
4694 * probably wrong function for rw==WRITE
4695 */
4696 flush_dcache_page(pages[i]);
4697 }
4698
4699 /* Populate the scatter/gather list */
Jens Axboe642f1492007-10-24 11:20:47 +02004700 sg_set_page(&sgl[0], pages[0], 0, uaddr & ~PAGE_MASK);
Linus Torvalds1da177e2005-04-16 15:20:36 -07004701 if (nr_pages > 1) {
4702 sgl[0].length = PAGE_SIZE - sgl[0].offset;
4703 count -= sgl[0].length;
4704 for (i=1; i < nr_pages ; i++) {
Jens Axboe642f1492007-10-24 11:20:47 +02004705 sg_set_page(&sgl[i], pages[i],
4706 count < PAGE_SIZE ? count : PAGE_SIZE, 0);;
Linus Torvalds1da177e2005-04-16 15:20:36 -07004707 count -= PAGE_SIZE;
4708 }
4709 }
4710 else {
4711 sgl[0].length = count;
4712 }
4713
4714 kfree(pages);
4715 return nr_pages;
4716
4717 out_unmap:
4718 if (res > 0) {
4719 for (j=0; j < res; j++)
4720 page_cache_release(pages[j]);
Hugh Dickins6bc733e2005-12-01 20:21:57 +00004721 res = 0;
Linus Torvalds1da177e2005-04-16 15:20:36 -07004722 }
4723 kfree(pages);
4724 return res;
4725}
4726
4727
4728/* And unmap them... */
4729static int sgl_unmap_user_pages(struct scatterlist *sgl, const unsigned int nr_pages,
4730 int dirtied)
4731{
4732 int i;
4733
4734 for (i=0; i < nr_pages; i++) {
Jens Axboe45711f12007-10-22 21:19:53 +02004735 struct page *page = sg_page(&sgl[i]);
Nick Pigginb5810032005-10-29 18:16:12 -07004736
Nick Pigginb5810032005-10-29 18:16:12 -07004737 if (dirtied)
4738 SetPageDirty(page);
Linus Torvalds1da177e2005-04-16 15:20:36 -07004739 /* FIXME: cache flush missing for rw==READ
4740 * FIXME: call the correct reference counting function
4741 */
Nick Pigginb5810032005-10-29 18:16:12 -07004742 page_cache_release(page);
Linus Torvalds1da177e2005-04-16 15:20:36 -07004743 }
4744
4745 return 0;
4746}