blob: 084a967b2e782b811a9d8b577207760436be6c4b [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;
Linus Torvalds1da177e2005-04-16 15:20:36 -0700540
Kai Makisaraf03a5672005-08-02 13:40:47 +0300541 /* if async, make sure there's no command outstanding */
542 if (!do_wait && ((STp->buffer)->last_SRpnt)) {
543 printk(KERN_ERR "%s: Async command already active.\n",
544 tape_name(STp));
545 if (signal_pending(current))
546 (STp->buffer)->syscall_result = (-EINTR);
547 else
548 (STp->buffer)->syscall_result = (-EBUSY);
549 return NULL;
550 }
551
FUJITA Tomonori4deba242008-12-05 15:25:20 +0900552 if (!SRpnt) {
553 SRpnt = st_allocate_request(STp);
554 if (!SRpnt)
Linus Torvalds1da177e2005-04-16 15:20:36 -0700555 return NULL;
Linus Torvalds1da177e2005-04-16 15:20:36 -0700556 }
557
Kai Makisaraf03a5672005-08-02 13:40:47 +0300558 /* If async IO, set last_SRpnt. This ptr tells write_behind_check
559 which IO is outstanding. It's nulled out when the IO completes. */
560 if (!do_wait)
561 (STp->buffer)->last_SRpnt = SRpnt;
562
563 waiting = &STp->wait;
564 init_completion(waiting);
Mike Christie8b05b772005-11-08 04:06:44 -0600565 SRpnt->waiting = waiting;
566
567 if (!STp->buffer->do_dio)
568 buf_to_sg(STp->buffer, bytes);
569
570 memcpy(SRpnt->cmd, cmd, sizeof(SRpnt->cmd));
Linus Torvalds1da177e2005-04-16 15:20:36 -0700571 STp->buffer->cmdstat.have_sense = 0;
Mike Christie8b05b772005-11-08 04:06:44 -0600572 STp->buffer->syscall_result = 0;
Linus Torvalds1da177e2005-04-16 15:20:36 -0700573
brking@us.ibm.combb1d1072006-01-23 15:03:22 -0600574 if (scsi_execute_async(STp->device, cmd, COMMAND_SIZE(cmd[0]), direction,
Mike Christie8b05b772005-11-08 04:06:44 -0600575 &((STp->buffer)->sg[0]), bytes, (STp->buffer)->sg_segs,
Kai Makisara787926b2005-11-13 10:04:44 +0200576 timeout, retries, SRpnt, st_sleep_done, GFP_KERNEL)) {
Mike Christie8b05b772005-11-08 04:06:44 -0600577 /* could not allocate the buffer or request was too large */
578 (STp->buffer)->syscall_result = (-EBUSY);
Kai Makisara787926b2005-11-13 10:04:44 +0200579 (STp->buffer)->last_SRpnt = NULL;
580 }
Mike Christie8b05b772005-11-08 04:06:44 -0600581 else if (do_wait) {
Kai Makisaraf03a5672005-08-02 13:40:47 +0300582 wait_for_completion(waiting);
Mike Christie8b05b772005-11-08 04:06:44 -0600583 SRpnt->waiting = NULL;
Linus Torvalds1da177e2005-04-16 15:20:36 -0700584 (STp->buffer)->syscall_result = st_chk_result(STp, SRpnt);
585 }
Mike Christie8b05b772005-11-08 04:06:44 -0600586
Linus Torvalds1da177e2005-04-16 15:20:36 -0700587 return SRpnt;
588}
589
FUJITA Tomonoriffb43492008-12-05 15:25:21 +0900590static int st_scsi_kern_execute(struct st_request *streq,
591 const unsigned char *cmd, int data_direction,
592 void *buffer, unsigned bufflen, int timeout,
593 int retries)
594{
595 struct scsi_tape *stp = streq->stp;
596 int ret, resid;
597
598 stp->buffer->cmdstat.have_sense = 0;
599 memcpy(streq->cmd, cmd, sizeof(streq->cmd));
600
601 ret = scsi_execute(stp->device, cmd, data_direction, buffer, bufflen,
602 streq->sense, timeout, retries, 0, &resid);
603 if (driver_byte(ret) & DRIVER_ERROR)
604 return -EBUSY;
605
606 stp->buffer->cmdstat.midlevel_result = streq->result = ret;
607 stp->buffer->cmdstat.residual = resid;
608 stp->buffer->syscall_result = st_chk_result(stp, streq);
609
610 return 0;
611}
Linus Torvalds1da177e2005-04-16 15:20:36 -0700612
613/* Handle the write-behind checking (waits for completion). Returns -ENOSPC if
614 write has been correct but EOM early warning reached, -EIO if write ended in
615 error or zero if write successful. Asynchronous writes are used only in
616 variable block mode. */
617static int write_behind_check(struct scsi_tape * STp)
618{
619 int retval = 0;
620 struct st_buffer *STbuffer;
621 struct st_partstat *STps;
622 struct st_cmdstatus *cmdstatp;
Mike Christie8b05b772005-11-08 04:06:44 -0600623 struct st_request *SRpnt;
Linus Torvalds1da177e2005-04-16 15:20:36 -0700624
625 STbuffer = STp->buffer;
626 if (!STbuffer->writing)
627 return 0;
628
629 DEB(
630 if (STp->write_pending)
631 STp->nbr_waits++;
632 else
633 STp->nbr_finished++;
634 ) /* end DEB */
635
636 wait_for_completion(&(STp->wait));
Kai Makisaraf03a5672005-08-02 13:40:47 +0300637 SRpnt = STbuffer->last_SRpnt;
638 STbuffer->last_SRpnt = NULL;
Mike Christie8b05b772005-11-08 04:06:44 -0600639 SRpnt->waiting = NULL;
Linus Torvalds1da177e2005-04-16 15:20:36 -0700640
Kai Makisaraf03a5672005-08-02 13:40:47 +0300641 (STp->buffer)->syscall_result = st_chk_result(STp, SRpnt);
Mike Christie8b05b772005-11-08 04:06:44 -0600642 st_release_request(SRpnt);
Linus Torvalds1da177e2005-04-16 15:20:36 -0700643
644 STbuffer->buffer_bytes -= STbuffer->writing;
645 STps = &(STp->ps[STp->partition]);
646 if (STps->drv_block >= 0) {
647 if (STp->block_size == 0)
648 STps->drv_block++;
649 else
650 STps->drv_block += STbuffer->writing / STp->block_size;
651 }
652
653 cmdstatp = &STbuffer->cmdstat;
654 if (STbuffer->syscall_result) {
655 retval = -EIO;
656 if (cmdstatp->have_sense && !cmdstatp->deferred &&
657 (cmdstatp->flags & SENSE_EOM) &&
658 (cmdstatp->sense_hdr.sense_key == NO_SENSE ||
659 cmdstatp->sense_hdr.sense_key == RECOVERED_ERROR)) {
660 /* EOM at write-behind, has all data been written? */
661 if (!cmdstatp->remainder_valid ||
662 cmdstatp->uremainder64 == 0)
663 retval = -ENOSPC;
664 }
665 if (retval == -EIO)
666 STps->drv_block = -1;
667 }
668 STbuffer->writing = 0;
669
670 DEB(if (debugging && retval)
671 printk(ST_DEB_MSG "%s: Async write error %x, return value %d.\n",
672 tape_name(STp), STbuffer->cmdstat.midlevel_result, retval);) /* end DEB */
673
674 return retval;
675}
676
677
678/* Step over EOF if it has been inadvertently crossed (ioctl not used because
679 it messes up the block number). */
680static int cross_eof(struct scsi_tape * STp, int forward)
681{
Mike Christie8b05b772005-11-08 04:06:44 -0600682 struct st_request *SRpnt;
Linus Torvalds1da177e2005-04-16 15:20:36 -0700683 unsigned char cmd[MAX_COMMAND_SIZE];
FUJITA Tomonori39ade4b2008-12-05 15:25:25 +0900684 int ret;
Linus Torvalds1da177e2005-04-16 15:20:36 -0700685
686 cmd[0] = SPACE;
687 cmd[1] = 0x01; /* Space FileMarks */
688 if (forward) {
689 cmd[2] = cmd[3] = 0;
690 cmd[4] = 1;
691 } else
692 cmd[2] = cmd[3] = cmd[4] = 0xff; /* -1 filemarks */
693 cmd[5] = 0;
694
695 DEBC(printk(ST_DEB_MSG "%s: Stepping over filemark %s.\n",
696 tape_name(STp), forward ? "forward" : "backward"));
697
FUJITA Tomonori39ade4b2008-12-05 15:25:25 +0900698 SRpnt = st_allocate_request(STp);
Linus Torvalds1da177e2005-04-16 15:20:36 -0700699 if (!SRpnt)
FUJITA Tomonori39ade4b2008-12-05 15:25:25 +0900700 return STp->buffer->syscall_result;
Linus Torvalds1da177e2005-04-16 15:20:36 -0700701
FUJITA Tomonori39ade4b2008-12-05 15:25:25 +0900702 ret = st_scsi_kern_execute(SRpnt, cmd, DMA_NONE, NULL, 0,
703 STp->device->request_queue->rq_timeout,
704 MAX_RETRIES);
705 if (ret)
706 goto out;
707
708 ret = STp->buffer->syscall_result;
Linus Torvalds1da177e2005-04-16 15:20:36 -0700709
710 if ((STp->buffer)->cmdstat.midlevel_result != 0)
711 printk(KERN_ERR "%s: Stepping over filemark %s failed.\n",
712 tape_name(STp), forward ? "forward" : "backward");
713
FUJITA Tomonori39ade4b2008-12-05 15:25:25 +0900714out:
715 st_release_request(SRpnt);
716
717 return ret;
Linus Torvalds1da177e2005-04-16 15:20:36 -0700718}
719
720
721/* Flush the write buffer (never need to write if variable blocksize). */
Adrian Bunk8ef8d592008-04-14 17:17:16 +0300722static int st_flush_write_buffer(struct scsi_tape * STp)
Linus Torvalds1da177e2005-04-16 15:20:36 -0700723{
Kai Makisara786231a2008-07-11 15:06:40 +0300724 int transfer, blks;
Linus Torvalds1da177e2005-04-16 15:20:36 -0700725 int result;
726 unsigned char cmd[MAX_COMMAND_SIZE];
Mike Christie8b05b772005-11-08 04:06:44 -0600727 struct st_request *SRpnt;
Linus Torvalds1da177e2005-04-16 15:20:36 -0700728 struct st_partstat *STps;
729
730 result = write_behind_check(STp);
731 if (result)
732 return result;
733
734 result = 0;
735 if (STp->dirty == 1) {
736
Kai Makisara786231a2008-07-11 15:06:40 +0300737 transfer = STp->buffer->buffer_bytes;
Linus Torvalds1da177e2005-04-16 15:20:36 -0700738 DEBC(printk(ST_DEB_MSG "%s: Flushing %d bytes.\n",
739 tape_name(STp), transfer));
740
Linus Torvalds1da177e2005-04-16 15:20:36 -0700741 memset(cmd, 0, MAX_COMMAND_SIZE);
742 cmd[0] = WRITE_6;
743 cmd[1] = 1;
744 blks = transfer / STp->block_size;
745 cmd[2] = blks >> 16;
746 cmd[3] = blks >> 8;
747 cmd[4] = blks;
748
749 SRpnt = st_do_scsi(NULL, STp, cmd, transfer, DMA_TO_DEVICE,
James Bottomleya02488e2008-11-30 10:36:26 -0600750 STp->device->request_queue->rq_timeout,
751 MAX_WRITE_RETRIES, 1);
Linus Torvalds1da177e2005-04-16 15:20:36 -0700752 if (!SRpnt)
753 return (STp->buffer)->syscall_result;
754
755 STps = &(STp->ps[STp->partition]);
756 if ((STp->buffer)->syscall_result != 0) {
757 struct st_cmdstatus *cmdstatp = &STp->buffer->cmdstat;
758
759 if (cmdstatp->have_sense && !cmdstatp->deferred &&
760 (cmdstatp->flags & SENSE_EOM) &&
761 (cmdstatp->sense_hdr.sense_key == NO_SENSE ||
762 cmdstatp->sense_hdr.sense_key == RECOVERED_ERROR) &&
763 (!cmdstatp->remainder_valid ||
764 cmdstatp->uremainder64 == 0)) { /* All written at EOM early warning */
765 STp->dirty = 0;
766 (STp->buffer)->buffer_bytes = 0;
767 if (STps->drv_block >= 0)
768 STps->drv_block += blks;
769 result = (-ENOSPC);
770 } else {
771 printk(KERN_ERR "%s: Error on flush.\n",
772 tape_name(STp));
773 STps->drv_block = (-1);
774 result = (-EIO);
775 }
776 } else {
777 if (STps->drv_block >= 0)
778 STps->drv_block += blks;
779 STp->dirty = 0;
780 (STp->buffer)->buffer_bytes = 0;
781 }
Mike Christie8b05b772005-11-08 04:06:44 -0600782 st_release_request(SRpnt);
Linus Torvalds1da177e2005-04-16 15:20:36 -0700783 SRpnt = NULL;
784 }
785 return result;
786}
787
788
789/* Flush the tape buffer. The tape will be positioned correctly unless
790 seek_next is true. */
791static int flush_buffer(struct scsi_tape *STp, int seek_next)
792{
793 int backspace, result;
794 struct st_buffer *STbuffer;
795 struct st_partstat *STps;
796
797 STbuffer = STp->buffer;
798
799 /*
800 * If there was a bus reset, block further access
801 * to this device.
802 */
803 if (STp->pos_unknown)
804 return (-EIO);
805
806 if (STp->ready != ST_READY)
807 return 0;
808 STps = &(STp->ps[STp->partition]);
809 if (STps->rw == ST_WRITING) /* Writing */
Adrian Bunk8ef8d592008-04-14 17:17:16 +0300810 return st_flush_write_buffer(STp);
Linus Torvalds1da177e2005-04-16 15:20:36 -0700811
812 if (STp->block_size == 0)
813 return 0;
814
815 backspace = ((STp->buffer)->buffer_bytes +
816 (STp->buffer)->read_pointer) / STp->block_size -
817 ((STp->buffer)->read_pointer + STp->block_size - 1) /
818 STp->block_size;
819 (STp->buffer)->buffer_bytes = 0;
820 (STp->buffer)->read_pointer = 0;
821 result = 0;
822 if (!seek_next) {
823 if (STps->eof == ST_FM_HIT) {
824 result = cross_eof(STp, 0); /* Back over the EOF hit */
825 if (!result)
826 STps->eof = ST_NOEOF;
827 else {
828 if (STps->drv_file >= 0)
829 STps->drv_file++;
830 STps->drv_block = 0;
831 }
832 }
833 if (!result && backspace > 0)
834 result = st_int_ioctl(STp, MTBSR, backspace);
835 } else if (STps->eof == ST_FM_HIT) {
836 if (STps->drv_file >= 0)
837 STps->drv_file++;
838 STps->drv_block = 0;
839 STps->eof = ST_NOEOF;
840 }
841 return result;
842
843}
844
845/* Set the mode parameters */
846static int set_mode_densblk(struct scsi_tape * STp, struct st_modedef * STm)
847{
848 int set_it = 0;
849 unsigned long arg;
850 char *name = tape_name(STp);
851
852 if (!STp->density_changed &&
853 STm->default_density >= 0 &&
854 STm->default_density != STp->density) {
855 arg = STm->default_density;
856 set_it = 1;
857 } else
858 arg = STp->density;
859 arg <<= MT_ST_DENSITY_SHIFT;
860 if (!STp->blksize_changed &&
861 STm->default_blksize >= 0 &&
862 STm->default_blksize != STp->block_size) {
863 arg |= STm->default_blksize;
864 set_it = 1;
865 } else
866 arg |= STp->block_size;
867 if (set_it &&
868 st_int_ioctl(STp, SET_DENS_AND_BLK, arg)) {
869 printk(KERN_WARNING
870 "%s: Can't set default block size to %d bytes and density %x.\n",
871 name, STm->default_blksize, STm->default_density);
872 if (modes_defined)
873 return (-EINVAL);
874 }
875 return 0;
876}
877
878
Mike Christie8b05b772005-11-08 04:06:44 -0600879/* Lock or unlock the drive door. Don't use when st_request allocated. */
Linus Torvalds1da177e2005-04-16 15:20:36 -0700880static int do_door_lock(struct scsi_tape * STp, int do_lock)
881{
882 int retval, cmd;
883 DEB(char *name = tape_name(STp);)
884
885
886 cmd = do_lock ? SCSI_IOCTL_DOORLOCK : SCSI_IOCTL_DOORUNLOCK;
887 DEBC(printk(ST_DEB_MSG "%s: %socking drive door.\n", name,
888 do_lock ? "L" : "Unl"));
889 retval = scsi_ioctl(STp->device, cmd, NULL);
890 if (!retval) {
891 STp->door_locked = do_lock ? ST_LOCKED_EXPLICIT : ST_UNLOCKED;
892 }
893 else {
894 STp->door_locked = ST_LOCK_FAILS;
895 }
896 return retval;
897}
898
899
900/* Set the internal state after reset */
901static void reset_state(struct scsi_tape *STp)
902{
903 int i;
904 struct st_partstat *STps;
905
906 STp->pos_unknown = 0;
907 for (i = 0; i < ST_NBR_PARTITIONS; i++) {
908 STps = &(STp->ps[i]);
909 STps->rw = ST_IDLE;
910 STps->eof = ST_NOEOF;
911 STps->at_sm = 0;
912 STps->last_block_valid = 0;
913 STps->drv_block = -1;
914 STps->drv_file = -1;
915 }
916 if (STp->can_partitions) {
917 STp->partition = find_partition(STp);
918 if (STp->partition < 0)
919 STp->partition = 0;
920 STp->new_partition = STp->partition;
921 }
922}
923
924/* Test if the drive is ready. Returns either one of the codes below or a negative system
925 error code. */
926#define CHKRES_READY 0
927#define CHKRES_NEW_SESSION 1
928#define CHKRES_NOT_READY 2
929#define CHKRES_NO_TAPE 3
930
931#define MAX_ATTENTIONS 10
932
933static int test_ready(struct scsi_tape *STp, int do_wait)
934{
935 int attentions, waits, max_wait, scode;
936 int retval = CHKRES_READY, new_session = 0;
937 unsigned char cmd[MAX_COMMAND_SIZE];
FUJITA Tomonori0944a722008-12-05 15:25:22 +0900938 struct st_request *SRpnt;
Linus Torvalds1da177e2005-04-16 15:20:36 -0700939 struct st_cmdstatus *cmdstatp = &STp->buffer->cmdstat;
940
FUJITA Tomonori0944a722008-12-05 15:25:22 +0900941 SRpnt = st_allocate_request(STp);
942 if (!SRpnt)
943 return STp->buffer->syscall_result;
944
Linus Torvalds1da177e2005-04-16 15:20:36 -0700945 max_wait = do_wait ? ST_BLOCK_SECONDS : 0;
946
947 for (attentions=waits=0; ; ) {
948 memset((void *) &cmd[0], 0, MAX_COMMAND_SIZE);
949 cmd[0] = TEST_UNIT_READY;
Linus Torvalds1da177e2005-04-16 15:20:36 -0700950
FUJITA Tomonori0944a722008-12-05 15:25:22 +0900951 retval = st_scsi_kern_execute(SRpnt, cmd, DMA_NONE, NULL, 0,
952 STp->long_timeout,
953 MAX_READY_RETRIES);
954 if (retval)
Linus Torvalds1da177e2005-04-16 15:20:36 -0700955 break;
Linus Torvalds1da177e2005-04-16 15:20:36 -0700956
957 if (cmdstatp->have_sense) {
958
959 scode = cmdstatp->sense_hdr.sense_key;
960
961 if (scode == UNIT_ATTENTION) { /* New media? */
962 new_session = 1;
963 if (attentions < MAX_ATTENTIONS) {
964 attentions++;
965 continue;
966 }
967 else {
968 retval = (-EIO);
969 break;
970 }
971 }
972
973 if (scode == NOT_READY) {
974 if (waits < max_wait) {
975 if (msleep_interruptible(1000)) {
976 retval = (-EINTR);
977 break;
978 }
979 waits++;
980 continue;
981 }
982 else {
983 if ((STp->device)->scsi_level >= SCSI_2 &&
984 cmdstatp->sense_hdr.asc == 0x3a) /* Check ASC */
985 retval = CHKRES_NO_TAPE;
986 else
987 retval = CHKRES_NOT_READY;
988 break;
989 }
990 }
991 }
992
993 retval = (STp->buffer)->syscall_result;
994 if (!retval)
995 retval = new_session ? CHKRES_NEW_SESSION : CHKRES_READY;
996 break;
997 }
998
FUJITA Tomonori0944a722008-12-05 15:25:22 +0900999 st_release_request(SRpnt);
1000
Linus Torvalds1da177e2005-04-16 15:20:36 -07001001 return retval;
1002}
1003
1004
1005/* See if the drive is ready and gather information about the tape. Return values:
1006 < 0 negative error code from errno.h
1007 0 drive ready
1008 1 drive not ready (possibly no tape)
1009*/
1010static int check_tape(struct scsi_tape *STp, struct file *filp)
1011{
1012 int i, retval, new_session = 0, do_wait;
1013 unsigned char cmd[MAX_COMMAND_SIZE], saved_cleaning;
1014 unsigned short st_flags = filp->f_flags;
Mike Christie8b05b772005-11-08 04:06:44 -06001015 struct st_request *SRpnt = NULL;
Linus Torvalds1da177e2005-04-16 15:20:36 -07001016 struct st_modedef *STm;
1017 struct st_partstat *STps;
1018 char *name = tape_name(STp);
Josef Sipek7ac62072006-12-08 02:37:37 -08001019 struct inode *inode = filp->f_path.dentry->d_inode;
Linus Torvalds1da177e2005-04-16 15:20:36 -07001020 int mode = TAPE_MODE(inode);
1021
1022 STp->ready = ST_READY;
1023
1024 if (mode != STp->current_mode) {
1025 DEBC(printk(ST_DEB_MSG "%s: Mode change from %d to %d.\n",
1026 name, STp->current_mode, mode));
1027 new_session = 1;
1028 STp->current_mode = mode;
1029 }
1030 STm = &(STp->modes[STp->current_mode]);
1031
1032 saved_cleaning = STp->cleaning_req;
1033 STp->cleaning_req = 0;
1034
1035 do_wait = ((filp->f_flags & O_NONBLOCK) == 0);
1036 retval = test_ready(STp, do_wait);
1037
1038 if (retval < 0)
1039 goto err_out;
1040
1041 if (retval == CHKRES_NEW_SESSION) {
1042 STp->pos_unknown = 0;
1043 STp->partition = STp->new_partition = 0;
1044 if (STp->can_partitions)
1045 STp->nbr_partitions = 1; /* This guess will be updated later
1046 if necessary */
1047 for (i = 0; i < ST_NBR_PARTITIONS; i++) {
1048 STps = &(STp->ps[i]);
1049 STps->rw = ST_IDLE;
1050 STps->eof = ST_NOEOF;
1051 STps->at_sm = 0;
1052 STps->last_block_valid = 0;
1053 STps->drv_block = 0;
1054 STps->drv_file = 0;
1055 }
1056 new_session = 1;
1057 }
1058 else {
1059 STp->cleaning_req |= saved_cleaning;
1060
1061 if (retval == CHKRES_NOT_READY || retval == CHKRES_NO_TAPE) {
1062 if (retval == CHKRES_NO_TAPE)
1063 STp->ready = ST_NO_TAPE;
1064 else
1065 STp->ready = ST_NOT_READY;
1066
1067 STp->density = 0; /* Clear the erroneous "residue" */
1068 STp->write_prot = 0;
1069 STp->block_size = 0;
1070 STp->ps[0].drv_file = STp->ps[0].drv_block = (-1);
1071 STp->partition = STp->new_partition = 0;
1072 STp->door_locked = ST_UNLOCKED;
1073 return CHKRES_NOT_READY;
1074 }
1075 }
1076
FUJITA Tomonori52107b22008-12-05 15:25:27 +09001077 SRpnt = st_allocate_request(STp);
1078 if (!SRpnt) {
1079 retval = STp->buffer->syscall_result;
1080 goto err_out;
1081 }
1082
Linus Torvalds1da177e2005-04-16 15:20:36 -07001083 if (STp->omit_blklims)
1084 STp->min_block = STp->max_block = (-1);
1085 else {
1086 memset((void *) &cmd[0], 0, MAX_COMMAND_SIZE);
1087 cmd[0] = READ_BLOCK_LIMITS;
1088
FUJITA Tomonori52107b22008-12-05 15:25:27 +09001089 retval = st_scsi_kern_execute(SRpnt, cmd, DMA_FROM_DEVICE,
1090 STp->buffer->b_data, 6,
1091 STp->device->request_queue->rq_timeout,
1092 MAX_READY_RETRIES);
1093 if (retval) {
1094 st_release_request(SRpnt);
Linus Torvalds1da177e2005-04-16 15:20:36 -07001095 goto err_out;
1096 }
1097
Mike Christie8b05b772005-11-08 04:06:44 -06001098 if (!SRpnt->result && !STp->buffer->cmdstat.have_sense) {
Linus Torvalds1da177e2005-04-16 15:20:36 -07001099 STp->max_block = ((STp->buffer)->b_data[1] << 16) |
1100 ((STp->buffer)->b_data[2] << 8) | (STp->buffer)->b_data[3];
1101 STp->min_block = ((STp->buffer)->b_data[4] << 8) |
1102 (STp->buffer)->b_data[5];
1103 if ( DEB( debugging || ) !STp->inited)
Kai Makisara42252852006-11-07 21:56:38 +02001104 printk(KERN_INFO
Linus Torvalds1da177e2005-04-16 15:20:36 -07001105 "%s: Block limits %d - %d bytes.\n", name,
1106 STp->min_block, STp->max_block);
1107 } else {
1108 STp->min_block = STp->max_block = (-1);
1109 DEBC(printk(ST_DEB_MSG "%s: Can't read block limits.\n",
1110 name));
1111 }
1112 }
1113
1114 memset((void *) &cmd[0], 0, MAX_COMMAND_SIZE);
1115 cmd[0] = MODE_SENSE;
1116 cmd[4] = 12;
1117
FUJITA Tomonori52107b22008-12-05 15:25:27 +09001118 retval = st_scsi_kern_execute(SRpnt, cmd, DMA_FROM_DEVICE,
1119 STp->buffer->b_data, 12,
1120 STp->device->request_queue->rq_timeout,
1121 MAX_READY_RETRIES);
1122 if (retval) {
1123 st_release_request(SRpnt);
Linus Torvalds1da177e2005-04-16 15:20:36 -07001124 goto err_out;
1125 }
1126
1127 if ((STp->buffer)->syscall_result != 0) {
1128 DEBC(printk(ST_DEB_MSG "%s: No Mode Sense.\n", name));
1129 STp->block_size = ST_DEFAULT_BLOCK; /* Educated guess (?) */
1130 (STp->buffer)->syscall_result = 0; /* Prevent error propagation */
1131 STp->drv_write_prot = 0;
1132 } else {
1133 DEBC(printk(ST_DEB_MSG
1134 "%s: Mode sense. Length %d, medium %x, WBS %x, BLL %d\n",
1135 name,
1136 (STp->buffer)->b_data[0], (STp->buffer)->b_data[1],
1137 (STp->buffer)->b_data[2], (STp->buffer)->b_data[3]));
1138
1139 if ((STp->buffer)->b_data[3] >= 8) {
1140 STp->drv_buffer = ((STp->buffer)->b_data[2] >> 4) & 7;
1141 STp->density = (STp->buffer)->b_data[4];
1142 STp->block_size = (STp->buffer)->b_data[9] * 65536 +
1143 (STp->buffer)->b_data[10] * 256 + (STp->buffer)->b_data[11];
1144 DEBC(printk(ST_DEB_MSG
1145 "%s: Density %x, tape length: %x, drv buffer: %d\n",
1146 name, STp->density, (STp->buffer)->b_data[5] * 65536 +
1147 (STp->buffer)->b_data[6] * 256 + (STp->buffer)->b_data[7],
1148 STp->drv_buffer));
1149 }
1150 STp->drv_write_prot = ((STp->buffer)->b_data[2] & 0x80) != 0;
1151 }
Mike Christie8b05b772005-11-08 04:06:44 -06001152 st_release_request(SRpnt);
Linus Torvalds1da177e2005-04-16 15:20:36 -07001153 SRpnt = NULL;
1154 STp->inited = 1;
1155
1156 if (STp->block_size > 0)
1157 (STp->buffer)->buffer_blocks =
1158 (STp->buffer)->buffer_size / STp->block_size;
1159 else
1160 (STp->buffer)->buffer_blocks = 1;
1161 (STp->buffer)->buffer_bytes = (STp->buffer)->read_pointer = 0;
1162
1163 DEBC(printk(ST_DEB_MSG
1164 "%s: Block size: %d, buffer size: %d (%d blocks).\n", name,
1165 STp->block_size, (STp->buffer)->buffer_size,
1166 (STp->buffer)->buffer_blocks));
1167
1168 if (STp->drv_write_prot) {
1169 STp->write_prot = 1;
1170
1171 DEBC(printk(ST_DEB_MSG "%s: Write protected\n", name));
1172
1173 if (do_wait &&
1174 ((st_flags & O_ACCMODE) == O_WRONLY ||
1175 (st_flags & O_ACCMODE) == O_RDWR)) {
1176 retval = (-EROFS);
1177 goto err_out;
1178 }
1179 }
1180
1181 if (STp->can_partitions && STp->nbr_partitions < 1) {
1182 /* This code is reached when the device is opened for the first time
1183 after the driver has been initialized with tape in the drive and the
1184 partition support has been enabled. */
1185 DEBC(printk(ST_DEB_MSG
1186 "%s: Updating partition number in status.\n", name));
1187 if ((STp->partition = find_partition(STp)) < 0) {
1188 retval = STp->partition;
1189 goto err_out;
1190 }
1191 STp->new_partition = STp->partition;
1192 STp->nbr_partitions = 1; /* This guess will be updated when necessary */
1193 }
1194
1195 if (new_session) { /* Change the drive parameters for the new mode */
1196 STp->density_changed = STp->blksize_changed = 0;
1197 STp->compression_changed = 0;
1198 if (!(STm->defaults_for_writes) &&
1199 (retval = set_mode_densblk(STp, STm)) < 0)
1200 goto err_out;
1201
1202 if (STp->default_drvbuffer != 0xff) {
1203 if (st_int_ioctl(STp, MTSETDRVBUFFER, STp->default_drvbuffer))
1204 printk(KERN_WARNING
1205 "%s: Can't set default drive buffering to %d.\n",
1206 name, STp->default_drvbuffer);
1207 }
1208 }
1209
1210 return CHKRES_READY;
1211
1212 err_out:
1213 return retval;
1214}
1215
1216
Jonathan Corbetb3369c62008-05-15 16:08:15 -06001217 /* Open the device. Needs to take the BKL only because of incrementing the SCSI host
Linus Torvalds1da177e2005-04-16 15:20:36 -07001218 module count. */
1219static int st_open(struct inode *inode, struct file *filp)
1220{
1221 int i, retval = (-EIO);
1222 struct scsi_tape *STp;
1223 struct st_partstat *STps;
1224 int dev = TAPE_NR(inode);
1225 char *name;
1226
Jonathan Corbetb3369c62008-05-15 16:08:15 -06001227 lock_kernel();
Linus Torvalds1da177e2005-04-16 15:20:36 -07001228 /*
1229 * We really want to do nonseekable_open(inode, filp); here, but some
1230 * versions of tar incorrectly call lseek on tapes and bail out if that
1231 * fails. So we disallow pread() and pwrite(), but permit lseeks.
1232 */
1233 filp->f_mode &= ~(FMODE_PREAD | FMODE_PWRITE);
1234
Jonathan Corbetb3369c62008-05-15 16:08:15 -06001235 if (!(STp = scsi_tape_get(dev))) {
1236 unlock_kernel();
Kai Makisaraf03a5672005-08-02 13:40:47 +03001237 return -ENXIO;
Jonathan Corbetb3369c62008-05-15 16:08:15 -06001238 }
Kai Makisaraf03a5672005-08-02 13:40:47 +03001239
Linus Torvalds1da177e2005-04-16 15:20:36 -07001240 write_lock(&st_dev_arr_lock);
Linus Torvalds1da177e2005-04-16 15:20:36 -07001241 filp->private_data = STp;
1242 name = tape_name(STp);
1243
1244 if (STp->in_use) {
1245 write_unlock(&st_dev_arr_lock);
Kai Makisaraf03a5672005-08-02 13:40:47 +03001246 scsi_tape_put(STp);
Jonathan Corbetb3369c62008-05-15 16:08:15 -06001247 unlock_kernel();
Linus Torvalds1da177e2005-04-16 15:20:36 -07001248 DEB( printk(ST_DEB_MSG "%s: Device already in use.\n", name); )
1249 return (-EBUSY);
1250 }
1251
Linus Torvalds1da177e2005-04-16 15:20:36 -07001252 STp->in_use = 1;
1253 write_unlock(&st_dev_arr_lock);
1254 STp->rew_at_close = STp->autorew_dev = (iminor(inode) & 0x80) == 0;
1255
1256 if (!scsi_block_when_processing_errors(STp->device)) {
1257 retval = (-ENXIO);
1258 goto err_out;
1259 }
1260
1261 /* See that we have at least a one page buffer available */
1262 if (!enlarge_buffer(STp->buffer, PAGE_SIZE, STp->restr_dma)) {
1263 printk(KERN_WARNING "%s: Can't allocate one page tape buffer.\n",
1264 name);
1265 retval = (-EOVERFLOW);
1266 goto err_out;
1267 }
1268
Kai Makisara40f6b362008-02-24 22:23:24 +02001269 (STp->buffer)->cleared = 0;
Linus Torvalds1da177e2005-04-16 15:20:36 -07001270 (STp->buffer)->writing = 0;
1271 (STp->buffer)->syscall_result = 0;
1272
1273 STp->write_prot = ((filp->f_flags & O_ACCMODE) == O_RDONLY);
1274
1275 STp->dirty = 0;
1276 for (i = 0; i < ST_NBR_PARTITIONS; i++) {
1277 STps = &(STp->ps[i]);
1278 STps->rw = ST_IDLE;
1279 }
Kai Makisara9abe16c2007-02-03 13:21:29 +02001280 STp->try_dio_now = STp->try_dio;
Linus Torvalds1da177e2005-04-16 15:20:36 -07001281 STp->recover_count = 0;
1282 DEB( STp->nbr_waits = STp->nbr_finished = 0;
Kai Makisaradeee13d2008-02-22 20:11:21 +02001283 STp->nbr_requests = STp->nbr_dio = STp->nbr_pages = 0; )
Linus Torvalds1da177e2005-04-16 15:20:36 -07001284
1285 retval = check_tape(STp, filp);
1286 if (retval < 0)
1287 goto err_out;
1288 if ((filp->f_flags & O_NONBLOCK) == 0 &&
1289 retval != CHKRES_READY) {
Kai Makisara413f7322006-10-05 22:59:46 +03001290 if (STp->ready == NO_TAPE)
1291 retval = (-ENOMEDIUM);
1292 else
1293 retval = (-EIO);
Linus Torvalds1da177e2005-04-16 15:20:36 -07001294 goto err_out;
1295 }
Jonathan Corbetb3369c62008-05-15 16:08:15 -06001296 unlock_kernel();
Linus Torvalds1da177e2005-04-16 15:20:36 -07001297 return 0;
1298
1299 err_out:
1300 normalize_buffer(STp->buffer);
1301 STp->in_use = 0;
Kai Makisaraf03a5672005-08-02 13:40:47 +03001302 scsi_tape_put(STp);
Jonathan Corbetb3369c62008-05-15 16:08:15 -06001303 unlock_kernel();
Linus Torvalds1da177e2005-04-16 15:20:36 -07001304 return retval;
1305
1306}
1307
1308
1309/* Flush the tape buffer before close */
Miklos Szeredi75e1fcc2006-06-23 02:05:12 -07001310static int st_flush(struct file *filp, fl_owner_t id)
Linus Torvalds1da177e2005-04-16 15:20:36 -07001311{
1312 int result = 0, result2;
1313 unsigned char cmd[MAX_COMMAND_SIZE];
Mike Christie8b05b772005-11-08 04:06:44 -06001314 struct st_request *SRpnt;
Linus Torvalds1da177e2005-04-16 15:20:36 -07001315 struct scsi_tape *STp = filp->private_data;
1316 struct st_modedef *STm = &(STp->modes[STp->current_mode]);
1317 struct st_partstat *STps = &(STp->ps[STp->partition]);
1318 char *name = tape_name(STp);
1319
1320 if (file_count(filp) > 1)
1321 return 0;
1322
1323 if (STps->rw == ST_WRITING && !STp->pos_unknown) {
Adrian Bunk8ef8d592008-04-14 17:17:16 +03001324 result = st_flush_write_buffer(STp);
Linus Torvalds1da177e2005-04-16 15:20:36 -07001325 if (result != 0 && result != (-ENOSPC))
1326 goto out;
1327 }
1328
1329 if (STp->can_partitions &&
1330 (result2 = switch_partition(STp)) < 0) {
1331 DEBC(printk(ST_DEB_MSG
1332 "%s: switch_partition at close failed.\n", name));
1333 if (result == 0)
1334 result = result2;
1335 goto out;
1336 }
1337
1338 DEBC( if (STp->nbr_requests)
Kai Makisaradeee13d2008-02-22 20:11:21 +02001339 printk(KERN_DEBUG "%s: Number of r/w requests %d, dio used in %d, pages %d.\n",
1340 name, STp->nbr_requests, STp->nbr_dio, STp->nbr_pages));
Linus Torvalds1da177e2005-04-16 15:20:36 -07001341
1342 if (STps->rw == ST_WRITING && !STp->pos_unknown) {
1343 struct st_cmdstatus *cmdstatp = &STp->buffer->cmdstat;
1344
1345 DEBC(printk(ST_DEB_MSG "%s: Async write waits %d, finished %d.\n",
1346 name, STp->nbr_waits, STp->nbr_finished);
1347 )
1348
1349 memset(cmd, 0, MAX_COMMAND_SIZE);
1350 cmd[0] = WRITE_FILEMARKS;
1351 cmd[4] = 1 + STp->two_fm;
1352
FUJITA Tomonori212cd8b2008-12-05 15:25:26 +09001353 SRpnt = st_allocate_request(STp);
Linus Torvalds1da177e2005-04-16 15:20:36 -07001354 if (!SRpnt) {
FUJITA Tomonori212cd8b2008-12-05 15:25:26 +09001355 result = STp->buffer->syscall_result;
1356 goto out;
1357 }
1358
1359 result = st_scsi_kern_execute(SRpnt, cmd, DMA_NONE, NULL, 0,
1360 STp->device->request_queue->rq_timeout,
1361 MAX_WRITE_RETRIES);
1362 if (result) {
1363 st_release_request(SRpnt);
Linus Torvalds1da177e2005-04-16 15:20:36 -07001364 goto out;
1365 }
1366
1367 if (STp->buffer->syscall_result == 0 ||
1368 (cmdstatp->have_sense && !cmdstatp->deferred &&
1369 (cmdstatp->flags & SENSE_EOM) &&
1370 (cmdstatp->sense_hdr.sense_key == NO_SENSE ||
1371 cmdstatp->sense_hdr.sense_key == RECOVERED_ERROR) &&
1372 (!cmdstatp->remainder_valid || cmdstatp->uremainder64 == 0))) {
1373 /* Write successful at EOM */
Mike Christie8b05b772005-11-08 04:06:44 -06001374 st_release_request(SRpnt);
Linus Torvalds1da177e2005-04-16 15:20:36 -07001375 SRpnt = NULL;
1376 if (STps->drv_file >= 0)
1377 STps->drv_file++;
1378 STps->drv_block = 0;
1379 if (STp->two_fm)
1380 cross_eof(STp, 0);
1381 STps->eof = ST_FM;
1382 }
1383 else { /* Write error */
Mike Christie8b05b772005-11-08 04:06:44 -06001384 st_release_request(SRpnt);
Linus Torvalds1da177e2005-04-16 15:20:36 -07001385 SRpnt = NULL;
1386 printk(KERN_ERR "%s: Error on write filemark.\n", name);
1387 if (result == 0)
1388 result = (-EIO);
1389 }
1390
1391 DEBC(printk(ST_DEB_MSG "%s: Buffer flushed, %d EOF(s) written\n",
1392 name, cmd[4]));
1393 } else if (!STp->rew_at_close) {
1394 STps = &(STp->ps[STp->partition]);
1395 if (!STm->sysv || STps->rw != ST_READING) {
1396 if (STp->can_bsr)
1397 result = flush_buffer(STp, 0);
1398 else if (STps->eof == ST_FM_HIT) {
1399 result = cross_eof(STp, 0);
1400 if (result) {
1401 if (STps->drv_file >= 0)
1402 STps->drv_file++;
1403 STps->drv_block = 0;
1404 STps->eof = ST_FM;
1405 } else
1406 STps->eof = ST_NOEOF;
1407 }
1408 } else if ((STps->eof == ST_NOEOF &&
1409 !(result = cross_eof(STp, 1))) ||
1410 STps->eof == ST_FM_HIT) {
1411 if (STps->drv_file >= 0)
1412 STps->drv_file++;
1413 STps->drv_block = 0;
1414 STps->eof = ST_FM;
1415 }
1416 }
1417
1418 out:
1419 if (STp->rew_at_close) {
1420 result2 = st_int_ioctl(STp, MTREW, 1);
1421 if (result == 0)
1422 result = result2;
1423 }
1424 return result;
1425}
1426
1427
1428/* Close the device and release it. BKL is not needed: this is the only thread
1429 accessing this tape. */
1430static int st_release(struct inode *inode, struct file *filp)
1431{
1432 int result = 0;
1433 struct scsi_tape *STp = filp->private_data;
1434
1435 if (STp->door_locked == ST_LOCKED_AUTO)
1436 do_door_lock(STp, 0);
1437
1438 normalize_buffer(STp->buffer);
1439 write_lock(&st_dev_arr_lock);
1440 STp->in_use = 0;
1441 write_unlock(&st_dev_arr_lock);
Kai Makisaraf03a5672005-08-02 13:40:47 +03001442 scsi_tape_put(STp);
Linus Torvalds1da177e2005-04-16 15:20:36 -07001443
1444 return result;
1445}
1446
1447/* The checks common to both reading and writing */
1448static ssize_t rw_checks(struct scsi_tape *STp, struct file *filp, size_t count)
1449{
1450 ssize_t retval = 0;
1451
1452 /*
1453 * If we are in the middle of error recovery, don't let anyone
1454 * else try and use this device. Also, if error recovery fails, it
1455 * may try and take the device offline, in which case all further
1456 * access to the device is prohibited.
1457 */
1458 if (!scsi_block_when_processing_errors(STp->device)) {
1459 retval = (-ENXIO);
1460 goto out;
1461 }
1462
1463 if (STp->ready != ST_READY) {
1464 if (STp->ready == ST_NO_TAPE)
1465 retval = (-ENOMEDIUM);
1466 else
1467 retval = (-EIO);
1468 goto out;
1469 }
1470
1471 if (! STp->modes[STp->current_mode].defined) {
1472 retval = (-ENXIO);
1473 goto out;
1474 }
1475
1476
1477 /*
1478 * If there was a bus reset, block further access
1479 * to this device.
1480 */
1481 if (STp->pos_unknown) {
1482 retval = (-EIO);
1483 goto out;
1484 }
1485
1486 if (count == 0)
1487 goto out;
1488
1489 DEB(
1490 if (!STp->in_use) {
1491 printk(ST_DEB_MSG "%s: Incorrect device.\n", tape_name(STp));
1492 retval = (-EIO);
1493 goto out;
1494 } ) /* end DEB */
1495
1496 if (STp->can_partitions &&
1497 (retval = switch_partition(STp)) < 0)
1498 goto out;
1499
1500 if (STp->block_size == 0 && STp->max_block > 0 &&
1501 (count < STp->min_block || count > STp->max_block)) {
1502 retval = (-EINVAL);
1503 goto out;
1504 }
1505
1506 if (STp->do_auto_lock && STp->door_locked == ST_UNLOCKED &&
1507 !do_door_lock(STp, 1))
1508 STp->door_locked = ST_LOCKED_AUTO;
1509
1510 out:
1511 return retval;
1512}
1513
1514
1515static int setup_buffering(struct scsi_tape *STp, const char __user *buf,
1516 size_t count, int is_read)
1517{
1518 int i, bufsize, retval = 0;
1519 struct st_buffer *STbp = STp->buffer;
1520
1521 if (is_read)
Kai Makisara9abe16c2007-02-03 13:21:29 +02001522 i = STp->try_dio_now && try_rdio;
Linus Torvalds1da177e2005-04-16 15:20:36 -07001523 else
Kai Makisara9abe16c2007-02-03 13:21:29 +02001524 i = STp->try_dio_now && try_wdio;
Mike Christie8b05b772005-11-08 04:06:44 -06001525
Linus Torvalds1da177e2005-04-16 15:20:36 -07001526 if (i && ((unsigned long)buf & queue_dma_alignment(
1527 STp->device->request_queue)) == 0) {
Mike Christie8b05b772005-11-08 04:06:44 -06001528 i = sgl_map_user_pages(&(STbp->sg[0]), STbp->use_sg,
1529 (unsigned long)buf, count, (is_read ? READ : WRITE));
Linus Torvalds1da177e2005-04-16 15:20:36 -07001530 if (i > 0) {
1531 STbp->do_dio = i;
1532 STbp->buffer_bytes = 0; /* can be used as transfer counter */
1533 }
1534 else
1535 STbp->do_dio = 0; /* fall back to buffering with any error */
1536 STbp->sg_segs = STbp->do_dio;
1537 STbp->frp_sg_current = 0;
1538 DEB(
1539 if (STbp->do_dio) {
1540 STp->nbr_dio++;
1541 STp->nbr_pages += STbp->do_dio;
Linus Torvalds1da177e2005-04-16 15:20:36 -07001542 }
1543 )
1544 } else
1545 STbp->do_dio = 0;
1546 DEB( STp->nbr_requests++; )
1547
1548 if (!STbp->do_dio) {
1549 if (STp->block_size)
1550 bufsize = STp->block_size > st_fixed_buffer_size ?
1551 STp->block_size : st_fixed_buffer_size;
Kai Makisara40f6b362008-02-24 22:23:24 +02001552 else {
Linus Torvalds1da177e2005-04-16 15:20:36 -07001553 bufsize = count;
Kai Makisara40f6b362008-02-24 22:23:24 +02001554 /* Make sure that data from previous user is not leaked even if
1555 HBA does not return correct residual */
1556 if (is_read && STp->sili && !STbp->cleared)
1557 clear_buffer(STbp);
1558 }
1559
Linus Torvalds1da177e2005-04-16 15:20:36 -07001560 if (bufsize > STbp->buffer_size &&
1561 !enlarge_buffer(STbp, bufsize, STp->restr_dma)) {
1562 printk(KERN_WARNING "%s: Can't allocate %d byte tape buffer.\n",
1563 tape_name(STp), bufsize);
1564 retval = (-EOVERFLOW);
1565 goto out;
1566 }
1567 if (STp->block_size)
1568 STbp->buffer_blocks = bufsize / STp->block_size;
1569 }
1570
1571 out:
1572 return retval;
1573}
1574
1575
1576/* Can be called more than once after each setup_buffer() */
Kai Makisara787926b2005-11-13 10:04:44 +02001577static void release_buffering(struct scsi_tape *STp, int is_read)
Linus Torvalds1da177e2005-04-16 15:20:36 -07001578{
1579 struct st_buffer *STbp;
1580
1581 STbp = STp->buffer;
1582 if (STbp->do_dio) {
Kai Makisara787926b2005-11-13 10:04:44 +02001583 sgl_unmap_user_pages(&(STbp->sg[0]), STbp->do_dio, is_read);
Linus Torvalds1da177e2005-04-16 15:20:36 -07001584 STbp->do_dio = 0;
Kai Makisara787926b2005-11-13 10:04:44 +02001585 STbp->sg_segs = 0;
Linus Torvalds1da177e2005-04-16 15:20:36 -07001586 }
1587}
1588
1589
1590/* Write command */
1591static ssize_t
1592st_write(struct file *filp, const char __user *buf, size_t count, loff_t * ppos)
1593{
1594 ssize_t total;
1595 ssize_t i, do_count, blks, transfer;
1596 ssize_t retval;
1597 int undone, retry_eot = 0, scode;
1598 int async_write;
1599 unsigned char cmd[MAX_COMMAND_SIZE];
1600 const char __user *b_point;
Mike Christie8b05b772005-11-08 04:06:44 -06001601 struct st_request *SRpnt = NULL;
Linus Torvalds1da177e2005-04-16 15:20:36 -07001602 struct scsi_tape *STp = filp->private_data;
1603 struct st_modedef *STm;
1604 struct st_partstat *STps;
1605 struct st_buffer *STbp;
1606 char *name = tape_name(STp);
1607
Matthias Kaehlcke28f85002007-07-29 23:38:15 +02001608 if (mutex_lock_interruptible(&STp->lock))
Linus Torvalds1da177e2005-04-16 15:20:36 -07001609 return -ERESTARTSYS;
1610
1611 retval = rw_checks(STp, filp, count);
1612 if (retval || count == 0)
1613 goto out;
1614
1615 /* Write must be integral number of blocks */
1616 if (STp->block_size != 0 && (count % STp->block_size) != 0) {
1617 printk(KERN_WARNING "%s: Write not multiple of tape block size.\n",
1618 name);
1619 retval = (-EINVAL);
1620 goto out;
1621 }
1622
1623 STm = &(STp->modes[STp->current_mode]);
1624 STps = &(STp->ps[STp->partition]);
1625
1626 if (STp->write_prot) {
1627 retval = (-EACCES);
1628 goto out;
1629 }
1630
1631
1632 if (STps->rw == ST_READING) {
1633 retval = flush_buffer(STp, 0);
1634 if (retval)
1635 goto out;
1636 STps->rw = ST_WRITING;
1637 } else if (STps->rw != ST_WRITING &&
1638 STps->drv_file == 0 && STps->drv_block == 0) {
1639 if ((retval = set_mode_densblk(STp, STm)) < 0)
1640 goto out;
1641 if (STm->default_compression != ST_DONT_TOUCH &&
1642 !(STp->compression_changed)) {
1643 if (st_compression(STp, (STm->default_compression == ST_YES))) {
1644 printk(KERN_WARNING "%s: Can't set default compression.\n",
1645 name);
1646 if (modes_defined) {
1647 retval = (-EINVAL);
1648 goto out;
1649 }
1650 }
1651 }
1652 }
1653
1654 STbp = STp->buffer;
1655 i = write_behind_check(STp);
1656 if (i) {
1657 if (i == -ENOSPC)
1658 STps->eof = ST_EOM_OK;
1659 else
1660 STps->eof = ST_EOM_ERROR;
1661 }
1662
1663 if (STps->eof == ST_EOM_OK) {
1664 STps->eof = ST_EOD_1; /* allow next write */
1665 retval = (-ENOSPC);
1666 goto out;
1667 }
1668 else if (STps->eof == ST_EOM_ERROR) {
1669 retval = (-EIO);
1670 goto out;
1671 }
1672
1673 /* Check the buffer readability in cases where copy_user might catch
1674 the problems after some tape movement. */
1675 if (STp->block_size != 0 &&
1676 !STbp->do_dio &&
1677 (copy_from_user(&i, buf, 1) != 0 ||
1678 copy_from_user(&i, buf + count - 1, 1) != 0)) {
1679 retval = (-EFAULT);
1680 goto out;
1681 }
1682
1683 retval = setup_buffering(STp, buf, count, 0);
1684 if (retval)
1685 goto out;
1686
1687 total = count;
1688
1689 memset(cmd, 0, MAX_COMMAND_SIZE);
1690 cmd[0] = WRITE_6;
1691 cmd[1] = (STp->block_size != 0);
1692
1693 STps->rw = ST_WRITING;
1694
1695 b_point = buf;
1696 while (count > 0 && !retry_eot) {
1697
1698 if (STbp->do_dio) {
1699 do_count = count;
1700 }
1701 else {
1702 if (STp->block_size == 0)
1703 do_count = count;
1704 else {
1705 do_count = STbp->buffer_blocks * STp->block_size -
1706 STbp->buffer_bytes;
1707 if (do_count > count)
1708 do_count = count;
1709 }
1710
1711 i = append_to_buffer(b_point, STbp, do_count);
1712 if (i) {
1713 retval = i;
1714 goto out;
1715 }
1716 }
1717 count -= do_count;
1718 b_point += do_count;
1719
1720 async_write = STp->block_size == 0 && !STbp->do_dio &&
1721 STm->do_async_writes && STps->eof < ST_EOM_OK;
1722
1723 if (STp->block_size != 0 && STm->do_buffer_writes &&
Kai Makisara9abe16c2007-02-03 13:21:29 +02001724 !(STp->try_dio_now && try_wdio) && STps->eof < ST_EOM_OK &&
Linus Torvalds1da177e2005-04-16 15:20:36 -07001725 STbp->buffer_bytes < STbp->buffer_size) {
1726 STp->dirty = 1;
1727 /* Don't write a buffer that is not full enough. */
1728 if (!async_write && count == 0)
1729 break;
1730 }
1731
1732 retry_write:
1733 if (STp->block_size == 0)
1734 blks = transfer = do_count;
1735 else {
1736 if (!STbp->do_dio)
1737 blks = STbp->buffer_bytes;
1738 else
1739 blks = do_count;
1740 blks /= STp->block_size;
1741 transfer = blks * STp->block_size;
1742 }
1743 cmd[2] = blks >> 16;
1744 cmd[3] = blks >> 8;
1745 cmd[4] = blks;
1746
1747 SRpnt = st_do_scsi(SRpnt, STp, cmd, transfer, DMA_TO_DEVICE,
James Bottomleya02488e2008-11-30 10:36:26 -06001748 STp->device->request_queue->rq_timeout,
1749 MAX_WRITE_RETRIES, !async_write);
Linus Torvalds1da177e2005-04-16 15:20:36 -07001750 if (!SRpnt) {
1751 retval = STbp->syscall_result;
1752 goto out;
1753 }
Mike Christie8b05b772005-11-08 04:06:44 -06001754 if (async_write && !STbp->syscall_result) {
Linus Torvalds1da177e2005-04-16 15:20:36 -07001755 STbp->writing = transfer;
1756 STp->dirty = !(STbp->writing ==
1757 STbp->buffer_bytes);
1758 SRpnt = NULL; /* Prevent releasing this request! */
1759 DEB( STp->write_pending = 1; )
1760 break;
1761 }
1762
1763 if (STbp->syscall_result != 0) {
1764 struct st_cmdstatus *cmdstatp = &STp->buffer->cmdstat;
1765
1766 DEBC(printk(ST_DEB_MSG "%s: Error on write:\n", name));
1767 if (cmdstatp->have_sense && (cmdstatp->flags & SENSE_EOM)) {
1768 scode = cmdstatp->sense_hdr.sense_key;
1769 if (cmdstatp->remainder_valid)
1770 undone = (int)cmdstatp->uremainder64;
1771 else if (STp->block_size == 0 &&
1772 scode == VOLUME_OVERFLOW)
1773 undone = transfer;
1774 else
1775 undone = 0;
1776 if (STp->block_size != 0)
1777 undone *= STp->block_size;
1778 if (undone <= do_count) {
1779 /* Only data from this write is not written */
1780 count += undone;
Kai Makisara626dcb12008-07-11 15:05:25 +03001781 b_point -= undone;
Linus Torvalds1da177e2005-04-16 15:20:36 -07001782 do_count -= undone;
1783 if (STp->block_size)
1784 blks = (transfer - undone) / STp->block_size;
1785 STps->eof = ST_EOM_OK;
1786 /* Continue in fixed block mode if all written
1787 in this request but still something left to write
1788 (retval left to zero)
1789 */
1790 if (STp->block_size == 0 ||
1791 undone > 0 || count == 0)
1792 retval = (-ENOSPC); /* EOM within current request */
1793 DEBC(printk(ST_DEB_MSG
1794 "%s: EOM with %d bytes unwritten.\n",
1795 name, (int)count));
1796 } else {
1797 /* EOT within data buffered earlier (possible only
1798 in fixed block mode without direct i/o) */
1799 if (!retry_eot && !cmdstatp->deferred &&
1800 (scode == NO_SENSE || scode == RECOVERED_ERROR)) {
1801 move_buffer_data(STp->buffer, transfer - undone);
1802 retry_eot = 1;
1803 if (STps->drv_block >= 0) {
1804 STps->drv_block += (transfer - undone) /
1805 STp->block_size;
1806 }
1807 STps->eof = ST_EOM_OK;
1808 DEBC(printk(ST_DEB_MSG
1809 "%s: Retry write of %d bytes at EOM.\n",
1810 name, STp->buffer->buffer_bytes));
1811 goto retry_write;
1812 }
1813 else {
1814 /* Either error within data buffered by driver or
1815 failed retry */
1816 count -= do_count;
1817 blks = do_count = 0;
1818 STps->eof = ST_EOM_ERROR;
1819 STps->drv_block = (-1); /* Too cautious? */
1820 retval = (-EIO); /* EOM for old data */
1821 DEBC(printk(ST_DEB_MSG
1822 "%s: EOM with lost data.\n",
1823 name));
1824 }
1825 }
1826 } else {
1827 count += do_count;
1828 STps->drv_block = (-1); /* Too cautious? */
Mike Christie8b05b772005-11-08 04:06:44 -06001829 retval = STbp->syscall_result;
Linus Torvalds1da177e2005-04-16 15:20:36 -07001830 }
1831
1832 }
1833
1834 if (STps->drv_block >= 0) {
1835 if (STp->block_size == 0)
1836 STps->drv_block += (do_count > 0);
1837 else
1838 STps->drv_block += blks;
1839 }
1840
1841 STbp->buffer_bytes = 0;
1842 STp->dirty = 0;
1843
1844 if (retval || retry_eot) {
1845 if (count < total)
1846 retval = total - count;
1847 goto out;
1848 }
1849 }
1850
1851 if (STps->eof == ST_EOD_1)
1852 STps->eof = ST_EOM_OK;
1853 else if (STps->eof != ST_EOM_OK)
1854 STps->eof = ST_NOEOF;
1855 retval = total - count;
1856
1857 out:
1858 if (SRpnt != NULL)
Mike Christie8b05b772005-11-08 04:06:44 -06001859 st_release_request(SRpnt);
Kai Makisara787926b2005-11-13 10:04:44 +02001860 release_buffering(STp, 0);
Matthias Kaehlcke28f85002007-07-29 23:38:15 +02001861 mutex_unlock(&STp->lock);
Linus Torvalds1da177e2005-04-16 15:20:36 -07001862
1863 return retval;
1864}
1865
1866/* Read data from the tape. Returns zero in the normal case, one if the
1867 eof status has changed, and the negative error code in case of a
1868 fatal error. Otherwise updates the buffer and the eof state.
1869
1870 Does release user buffer mapping if it is set.
1871*/
1872static long read_tape(struct scsi_tape *STp, long count,
Mike Christie8b05b772005-11-08 04:06:44 -06001873 struct st_request ** aSRpnt)
Linus Torvalds1da177e2005-04-16 15:20:36 -07001874{
1875 int transfer, blks, bytes;
1876 unsigned char cmd[MAX_COMMAND_SIZE];
Mike Christie8b05b772005-11-08 04:06:44 -06001877 struct st_request *SRpnt;
Linus Torvalds1da177e2005-04-16 15:20:36 -07001878 struct st_modedef *STm;
1879 struct st_partstat *STps;
1880 struct st_buffer *STbp;
1881 int retval = 0;
1882 char *name = tape_name(STp);
1883
1884 if (count == 0)
1885 return 0;
1886
1887 STm = &(STp->modes[STp->current_mode]);
1888 STps = &(STp->ps[STp->partition]);
1889 if (STps->eof == ST_FM_HIT)
1890 return 1;
1891 STbp = STp->buffer;
1892
1893 if (STp->block_size == 0)
1894 blks = bytes = count;
1895 else {
Kai Makisara9abe16c2007-02-03 13:21:29 +02001896 if (!(STp->try_dio_now && try_rdio) && STm->do_read_ahead) {
Linus Torvalds1da177e2005-04-16 15:20:36 -07001897 blks = (STp->buffer)->buffer_blocks;
1898 bytes = blks * STp->block_size;
1899 } else {
1900 bytes = count;
1901 if (!STbp->do_dio && bytes > (STp->buffer)->buffer_size)
1902 bytes = (STp->buffer)->buffer_size;
1903 blks = bytes / STp->block_size;
1904 bytes = blks * STp->block_size;
1905 }
1906 }
1907
1908 memset(cmd, 0, MAX_COMMAND_SIZE);
1909 cmd[0] = READ_6;
1910 cmd[1] = (STp->block_size != 0);
Kai Makisara40f6b362008-02-24 22:23:24 +02001911 if (!cmd[1] && STp->sili)
1912 cmd[1] |= 2;
Linus Torvalds1da177e2005-04-16 15:20:36 -07001913 cmd[2] = blks >> 16;
1914 cmd[3] = blks >> 8;
1915 cmd[4] = blks;
1916
1917 SRpnt = *aSRpnt;
1918 SRpnt = st_do_scsi(SRpnt, STp, cmd, bytes, DMA_FROM_DEVICE,
James Bottomleya02488e2008-11-30 10:36:26 -06001919 STp->device->request_queue->rq_timeout,
1920 MAX_RETRIES, 1);
Kai Makisara787926b2005-11-13 10:04:44 +02001921 release_buffering(STp, 1);
Linus Torvalds1da177e2005-04-16 15:20:36 -07001922 *aSRpnt = SRpnt;
1923 if (!SRpnt)
1924 return STbp->syscall_result;
1925
1926 STbp->read_pointer = 0;
1927 STps->at_sm = 0;
1928
1929 /* Something to check */
1930 if (STbp->syscall_result) {
1931 struct st_cmdstatus *cmdstatp = &STp->buffer->cmdstat;
1932
1933 retval = 1;
1934 DEBC(printk(ST_DEB_MSG "%s: Sense: %2x %2x %2x %2x %2x %2x %2x %2x\n",
1935 name,
Mike Christie8b05b772005-11-08 04:06:44 -06001936 SRpnt->sense[0], SRpnt->sense[1],
1937 SRpnt->sense[2], SRpnt->sense[3],
1938 SRpnt->sense[4], SRpnt->sense[5],
1939 SRpnt->sense[6], SRpnt->sense[7]));
Linus Torvalds1da177e2005-04-16 15:20:36 -07001940 if (cmdstatp->have_sense) {
1941
1942 if (cmdstatp->sense_hdr.sense_key == BLANK_CHECK)
1943 cmdstatp->flags &= 0xcf; /* No need for EOM in this case */
1944
1945 if (cmdstatp->flags != 0) { /* EOF, EOM, or ILI */
1946 /* Compute the residual count */
1947 if (cmdstatp->remainder_valid)
1948 transfer = (int)cmdstatp->uremainder64;
1949 else
1950 transfer = 0;
1951 if (STp->block_size == 0 &&
1952 cmdstatp->sense_hdr.sense_key == MEDIUM_ERROR)
1953 transfer = bytes;
1954
1955 if (cmdstatp->flags & SENSE_ILI) { /* ILI */
1956 if (STp->block_size == 0) {
1957 if (transfer <= 0) {
1958 if (transfer < 0)
1959 printk(KERN_NOTICE
1960 "%s: Failed to read %d byte block with %d byte transfer.\n",
1961 name, bytes - transfer, bytes);
1962 if (STps->drv_block >= 0)
1963 STps->drv_block += 1;
1964 STbp->buffer_bytes = 0;
1965 return (-ENOMEM);
1966 }
1967 STbp->buffer_bytes = bytes - transfer;
1968 } else {
Mike Christie8b05b772005-11-08 04:06:44 -06001969 st_release_request(SRpnt);
Linus Torvalds1da177e2005-04-16 15:20:36 -07001970 SRpnt = *aSRpnt = NULL;
1971 if (transfer == blks) { /* We did not get anything, error */
1972 printk(KERN_NOTICE "%s: Incorrect block size.\n", name);
1973 if (STps->drv_block >= 0)
1974 STps->drv_block += blks - transfer + 1;
1975 st_int_ioctl(STp, MTBSR, 1);
1976 return (-EIO);
1977 }
1978 /* We have some data, deliver it */
1979 STbp->buffer_bytes = (blks - transfer) *
1980 STp->block_size;
1981 DEBC(printk(ST_DEB_MSG
1982 "%s: ILI but enough data received %ld %d.\n",
1983 name, count, STbp->buffer_bytes));
1984 if (STps->drv_block >= 0)
1985 STps->drv_block += 1;
1986 if (st_int_ioctl(STp, MTBSR, 1))
1987 return (-EIO);
1988 }
1989 } else if (cmdstatp->flags & SENSE_FMK) { /* FM overrides EOM */
1990 if (STps->eof != ST_FM_HIT)
1991 STps->eof = ST_FM_HIT;
1992 else
1993 STps->eof = ST_EOD_2;
1994 if (STp->block_size == 0)
1995 STbp->buffer_bytes = 0;
1996 else
1997 STbp->buffer_bytes =
1998 bytes - transfer * STp->block_size;
1999 DEBC(printk(ST_DEB_MSG
2000 "%s: EOF detected (%d bytes read).\n",
2001 name, STbp->buffer_bytes));
2002 } else if (cmdstatp->flags & SENSE_EOM) {
2003 if (STps->eof == ST_FM)
2004 STps->eof = ST_EOD_1;
2005 else
2006 STps->eof = ST_EOM_OK;
2007 if (STp->block_size == 0)
2008 STbp->buffer_bytes = bytes - transfer;
2009 else
2010 STbp->buffer_bytes =
2011 bytes - transfer * STp->block_size;
2012
2013 DEBC(printk(ST_DEB_MSG "%s: EOM detected (%d bytes read).\n",
2014 name, STbp->buffer_bytes));
2015 }
2016 }
2017 /* end of EOF, EOM, ILI test */
2018 else { /* nonzero sense key */
2019 DEBC(printk(ST_DEB_MSG
2020 "%s: Tape error while reading.\n", name));
2021 STps->drv_block = (-1);
2022 if (STps->eof == ST_FM &&
2023 cmdstatp->sense_hdr.sense_key == BLANK_CHECK) {
2024 DEBC(printk(ST_DEB_MSG
2025 "%s: Zero returned for first BLANK CHECK after EOF.\n",
2026 name));
2027 STps->eof = ST_EOD_2; /* First BLANK_CHECK after FM */
2028 } else /* Some other extended sense code */
2029 retval = (-EIO);
2030 }
2031
2032 if (STbp->buffer_bytes < 0) /* Caused by bogus sense data */
2033 STbp->buffer_bytes = 0;
2034 }
2035 /* End of extended sense test */
2036 else { /* Non-extended sense */
2037 retval = STbp->syscall_result;
2038 }
2039
2040 }
2041 /* End of error handling */
Kai Makisara40f6b362008-02-24 22:23:24 +02002042 else { /* Read successful */
Linus Torvalds1da177e2005-04-16 15:20:36 -07002043 STbp->buffer_bytes = bytes;
Kai Makisara40f6b362008-02-24 22:23:24 +02002044 if (STp->sili) /* In fixed block mode residual is always zero here */
2045 STbp->buffer_bytes -= STp->buffer->cmdstat.residual;
2046 }
Linus Torvalds1da177e2005-04-16 15:20:36 -07002047
2048 if (STps->drv_block >= 0) {
2049 if (STp->block_size == 0)
2050 STps->drv_block++;
2051 else
2052 STps->drv_block += STbp->buffer_bytes / STp->block_size;
2053 }
2054 return retval;
2055}
2056
2057
2058/* Read command */
2059static ssize_t
2060st_read(struct file *filp, char __user *buf, size_t count, loff_t * ppos)
2061{
2062 ssize_t total;
2063 ssize_t retval = 0;
2064 ssize_t i, transfer;
2065 int special, do_dio = 0;
Mike Christie8b05b772005-11-08 04:06:44 -06002066 struct st_request *SRpnt = NULL;
Linus Torvalds1da177e2005-04-16 15:20:36 -07002067 struct scsi_tape *STp = filp->private_data;
2068 struct st_modedef *STm;
2069 struct st_partstat *STps;
2070 struct st_buffer *STbp = STp->buffer;
2071 DEB( char *name = tape_name(STp); )
2072
Matthias Kaehlcke28f85002007-07-29 23:38:15 +02002073 if (mutex_lock_interruptible(&STp->lock))
Linus Torvalds1da177e2005-04-16 15:20:36 -07002074 return -ERESTARTSYS;
2075
2076 retval = rw_checks(STp, filp, count);
2077 if (retval || count == 0)
2078 goto out;
2079
2080 STm = &(STp->modes[STp->current_mode]);
Kai Makisara9abe16c2007-02-03 13:21:29 +02002081 if (STp->block_size != 0 && (count % STp->block_size) != 0) {
2082 if (!STm->do_read_ahead) {
2083 retval = (-EINVAL); /* Read must be integral number of blocks */
2084 goto out;
2085 }
2086 STp->try_dio_now = 0; /* Direct i/o can't handle split blocks */
Linus Torvalds1da177e2005-04-16 15:20:36 -07002087 }
2088
2089 STps = &(STp->ps[STp->partition]);
2090 if (STps->rw == ST_WRITING) {
2091 retval = flush_buffer(STp, 0);
2092 if (retval)
2093 goto out;
2094 STps->rw = ST_READING;
2095 }
2096 DEB(
2097 if (debugging && STps->eof != ST_NOEOF)
2098 printk(ST_DEB_MSG "%s: EOF/EOM flag up (%d). Bytes %d\n", name,
2099 STps->eof, STbp->buffer_bytes);
2100 ) /* end DEB */
2101
2102 retval = setup_buffering(STp, buf, count, 1);
2103 if (retval)
2104 goto out;
2105 do_dio = STbp->do_dio;
2106
2107 if (STbp->buffer_bytes == 0 &&
2108 STps->eof >= ST_EOD_1) {
2109 if (STps->eof < ST_EOD) {
2110 STps->eof += 1;
2111 retval = 0;
2112 goto out;
2113 }
2114 retval = (-EIO); /* EOM or Blank Check */
2115 goto out;
2116 }
2117
2118 if (do_dio) {
2119 /* Check the buffer writability before any tape movement. Don't alter
2120 buffer data. */
2121 if (copy_from_user(&i, buf, 1) != 0 ||
2122 copy_to_user(buf, &i, 1) != 0 ||
2123 copy_from_user(&i, buf + count - 1, 1) != 0 ||
2124 copy_to_user(buf + count - 1, &i, 1) != 0) {
2125 retval = (-EFAULT);
2126 goto out;
2127 }
2128 }
2129
2130 STps->rw = ST_READING;
2131
2132
2133 /* Loop until enough data in buffer or a special condition found */
2134 for (total = 0, special = 0; total < count && !special;) {
2135
2136 /* Get new data if the buffer is empty */
2137 if (STbp->buffer_bytes == 0) {
2138 special = read_tape(STp, count - total, &SRpnt);
2139 if (special < 0) { /* No need to continue read */
2140 retval = special;
2141 goto out;
2142 }
2143 }
2144
2145 /* Move the data from driver buffer to user buffer */
2146 if (STbp->buffer_bytes > 0) {
2147 DEB(
2148 if (debugging && STps->eof != ST_NOEOF)
2149 printk(ST_DEB_MSG
2150 "%s: EOF up (%d). Left %d, needed %d.\n", name,
2151 STps->eof, STbp->buffer_bytes,
2152 (int)(count - total));
2153 ) /* end DEB */
2154 transfer = STbp->buffer_bytes < count - total ?
2155 STbp->buffer_bytes : count - total;
2156 if (!do_dio) {
2157 i = from_buffer(STbp, buf, transfer);
2158 if (i) {
2159 retval = i;
2160 goto out;
2161 }
2162 }
2163 buf += transfer;
2164 total += transfer;
2165 }
2166
2167 if (STp->block_size == 0)
2168 break; /* Read only one variable length block */
2169
2170 } /* for (total = 0, special = 0;
2171 total < count && !special; ) */
2172
2173 /* Change the eof state if no data from tape or buffer */
2174 if (total == 0) {
2175 if (STps->eof == ST_FM_HIT) {
2176 STps->eof = ST_FM;
2177 STps->drv_block = 0;
2178 if (STps->drv_file >= 0)
2179 STps->drv_file++;
2180 } else if (STps->eof == ST_EOD_1) {
2181 STps->eof = ST_EOD_2;
2182 STps->drv_block = 0;
2183 if (STps->drv_file >= 0)
2184 STps->drv_file++;
2185 } else if (STps->eof == ST_EOD_2)
2186 STps->eof = ST_EOD;
2187 } else if (STps->eof == ST_FM)
2188 STps->eof = ST_NOEOF;
2189 retval = total;
2190
2191 out:
2192 if (SRpnt != NULL) {
Mike Christie8b05b772005-11-08 04:06:44 -06002193 st_release_request(SRpnt);
Linus Torvalds1da177e2005-04-16 15:20:36 -07002194 SRpnt = NULL;
2195 }
2196 if (do_dio) {
Kai Makisara787926b2005-11-13 10:04:44 +02002197 release_buffering(STp, 1);
Linus Torvalds1da177e2005-04-16 15:20:36 -07002198 STbp->buffer_bytes = 0;
2199 }
Matthias Kaehlcke28f85002007-07-29 23:38:15 +02002200 mutex_unlock(&STp->lock);
Linus Torvalds1da177e2005-04-16 15:20:36 -07002201
2202 return retval;
2203}
2204
2205
2206
2207DEB(
2208/* Set the driver options */
2209static void st_log_options(struct scsi_tape * STp, struct st_modedef * STm, char *name)
2210{
2211 if (debugging) {
2212 printk(KERN_INFO
2213 "%s: Mode %d options: buffer writes: %d, async writes: %d, read ahead: %d\n",
2214 name, STp->current_mode, STm->do_buffer_writes, STm->do_async_writes,
2215 STm->do_read_ahead);
2216 printk(KERN_INFO
2217 "%s: can bsr: %d, two FMs: %d, fast mteom: %d, auto lock: %d,\n",
2218 name, STp->can_bsr, STp->two_fm, STp->fast_mteom, STp->do_auto_lock);
2219 printk(KERN_INFO
2220 "%s: defs for wr: %d, no block limits: %d, partitions: %d, s2 log: %d\n",
2221 name, STm->defaults_for_writes, STp->omit_blklims, STp->can_partitions,
2222 STp->scsi2_logical);
2223 printk(KERN_INFO
Kai Makisara40f6b362008-02-24 22:23:24 +02002224 "%s: sysv: %d nowait: %d sili: %d\n", name, STm->sysv, STp->immediate,
2225 STp->sili);
Linus Torvalds1da177e2005-04-16 15:20:36 -07002226 printk(KERN_INFO "%s: debugging: %d\n",
2227 name, debugging);
2228 }
2229}
2230 )
2231
2232
2233static int st_set_options(struct scsi_tape *STp, long options)
2234{
2235 int value;
2236 long code;
2237 struct st_modedef *STm;
2238 char *name = tape_name(STp);
2239 struct cdev *cd0, *cd1;
2240
2241 STm = &(STp->modes[STp->current_mode]);
2242 if (!STm->defined) {
2243 cd0 = STm->cdevs[0]; cd1 = STm->cdevs[1];
2244 memcpy(STm, &(STp->modes[0]), sizeof(struct st_modedef));
2245 STm->cdevs[0] = cd0; STm->cdevs[1] = cd1;
2246 modes_defined = 1;
2247 DEBC(printk(ST_DEB_MSG
2248 "%s: Initialized mode %d definition from mode 0\n",
2249 name, STp->current_mode));
2250 }
2251
2252 code = options & MT_ST_OPTIONS;
2253 if (code == MT_ST_BOOLEANS) {
2254 STm->do_buffer_writes = (options & MT_ST_BUFFER_WRITES) != 0;
2255 STm->do_async_writes = (options & MT_ST_ASYNC_WRITES) != 0;
2256 STm->defaults_for_writes = (options & MT_ST_DEF_WRITES) != 0;
2257 STm->do_read_ahead = (options & MT_ST_READ_AHEAD) != 0;
2258 STp->two_fm = (options & MT_ST_TWO_FM) != 0;
2259 STp->fast_mteom = (options & MT_ST_FAST_MTEOM) != 0;
2260 STp->do_auto_lock = (options & MT_ST_AUTO_LOCK) != 0;
2261 STp->can_bsr = (options & MT_ST_CAN_BSR) != 0;
2262 STp->omit_blklims = (options & MT_ST_NO_BLKLIMS) != 0;
2263 if ((STp->device)->scsi_level >= SCSI_2)
2264 STp->can_partitions = (options & MT_ST_CAN_PARTITIONS) != 0;
2265 STp->scsi2_logical = (options & MT_ST_SCSI2LOGICAL) != 0;
2266 STp->immediate = (options & MT_ST_NOWAIT) != 0;
2267 STm->sysv = (options & MT_ST_SYSV) != 0;
Kai Makisara40f6b362008-02-24 22:23:24 +02002268 STp->sili = (options & MT_ST_SILI) != 0;
Linus Torvalds1da177e2005-04-16 15:20:36 -07002269 DEB( debugging = (options & MT_ST_DEBUGGING) != 0;
2270 st_log_options(STp, STm, name); )
2271 } else if (code == MT_ST_SETBOOLEANS || code == MT_ST_CLEARBOOLEANS) {
2272 value = (code == MT_ST_SETBOOLEANS);
2273 if ((options & MT_ST_BUFFER_WRITES) != 0)
2274 STm->do_buffer_writes = value;
2275 if ((options & MT_ST_ASYNC_WRITES) != 0)
2276 STm->do_async_writes = value;
2277 if ((options & MT_ST_DEF_WRITES) != 0)
2278 STm->defaults_for_writes = value;
2279 if ((options & MT_ST_READ_AHEAD) != 0)
2280 STm->do_read_ahead = value;
2281 if ((options & MT_ST_TWO_FM) != 0)
2282 STp->two_fm = value;
2283 if ((options & MT_ST_FAST_MTEOM) != 0)
2284 STp->fast_mteom = value;
2285 if ((options & MT_ST_AUTO_LOCK) != 0)
2286 STp->do_auto_lock = value;
2287 if ((options & MT_ST_CAN_BSR) != 0)
2288 STp->can_bsr = value;
2289 if ((options & MT_ST_NO_BLKLIMS) != 0)
2290 STp->omit_blklims = value;
2291 if ((STp->device)->scsi_level >= SCSI_2 &&
2292 (options & MT_ST_CAN_PARTITIONS) != 0)
2293 STp->can_partitions = value;
2294 if ((options & MT_ST_SCSI2LOGICAL) != 0)
2295 STp->scsi2_logical = value;
2296 if ((options & MT_ST_NOWAIT) != 0)
2297 STp->immediate = value;
2298 if ((options & MT_ST_SYSV) != 0)
2299 STm->sysv = value;
Kai Makisara40f6b362008-02-24 22:23:24 +02002300 if ((options & MT_ST_SILI) != 0)
2301 STp->sili = value;
Linus Torvalds1da177e2005-04-16 15:20:36 -07002302 DEB(
2303 if ((options & MT_ST_DEBUGGING) != 0)
2304 debugging = value;
2305 st_log_options(STp, STm, name); )
2306 } else if (code == MT_ST_WRITE_THRESHOLD) {
2307 /* Retained for compatibility */
2308 } else if (code == MT_ST_DEF_BLKSIZE) {
2309 value = (options & ~MT_ST_OPTIONS);
2310 if (value == ~MT_ST_OPTIONS) {
2311 STm->default_blksize = (-1);
2312 DEBC( printk(KERN_INFO "%s: Default block size disabled.\n", name));
2313 } else {
2314 STm->default_blksize = value;
2315 DEBC( printk(KERN_INFO "%s: Default block size set to %d bytes.\n",
2316 name, STm->default_blksize));
2317 if (STp->ready == ST_READY) {
2318 STp->blksize_changed = 0;
2319 set_mode_densblk(STp, STm);
2320 }
2321 }
2322 } else if (code == MT_ST_TIMEOUTS) {
2323 value = (options & ~MT_ST_OPTIONS);
2324 if ((value & MT_ST_SET_LONG_TIMEOUT) != 0) {
2325 STp->long_timeout = (value & ~MT_ST_SET_LONG_TIMEOUT) * HZ;
2326 DEBC( printk(KERN_INFO "%s: Long timeout set to %d seconds.\n", name,
2327 (value & ~MT_ST_SET_LONG_TIMEOUT)));
2328 } else {
James Bottomleya02488e2008-11-30 10:36:26 -06002329 blk_queue_rq_timeout(STp->device->request_queue,
2330 value * HZ);
Linus Torvalds1da177e2005-04-16 15:20:36 -07002331 DEBC( printk(KERN_INFO "%s: Normal timeout set to %d seconds.\n",
2332 name, value) );
2333 }
2334 } else if (code == MT_ST_SET_CLN) {
2335 value = (options & ~MT_ST_OPTIONS) & 0xff;
2336 if (value != 0 &&
2337 value < EXTENDED_SENSE_START && value >= SCSI_SENSE_BUFFERSIZE)
2338 return (-EINVAL);
2339 STp->cln_mode = value;
2340 STp->cln_sense_mask = (options >> 8) & 0xff;
2341 STp->cln_sense_value = (options >> 16) & 0xff;
2342 printk(KERN_INFO
2343 "%s: Cleaning request mode %d, mask %02x, value %02x\n",
2344 name, value, STp->cln_sense_mask, STp->cln_sense_value);
2345 } else if (code == MT_ST_DEF_OPTIONS) {
2346 code = (options & ~MT_ST_CLEAR_DEFAULT);
2347 value = (options & MT_ST_CLEAR_DEFAULT);
2348 if (code == MT_ST_DEF_DENSITY) {
2349 if (value == MT_ST_CLEAR_DEFAULT) {
2350 STm->default_density = (-1);
2351 DEBC( printk(KERN_INFO "%s: Density default disabled.\n",
2352 name));
2353 } else {
2354 STm->default_density = value & 0xff;
2355 DEBC( printk(KERN_INFO "%s: Density default set to %x\n",
2356 name, STm->default_density));
2357 if (STp->ready == ST_READY) {
2358 STp->density_changed = 0;
2359 set_mode_densblk(STp, STm);
2360 }
2361 }
2362 } else if (code == MT_ST_DEF_DRVBUFFER) {
2363 if (value == MT_ST_CLEAR_DEFAULT) {
2364 STp->default_drvbuffer = 0xff;
2365 DEBC( printk(KERN_INFO
2366 "%s: Drive buffer default disabled.\n", name));
2367 } else {
2368 STp->default_drvbuffer = value & 7;
2369 DEBC( printk(KERN_INFO
2370 "%s: Drive buffer default set to %x\n",
2371 name, STp->default_drvbuffer));
2372 if (STp->ready == ST_READY)
2373 st_int_ioctl(STp, MTSETDRVBUFFER, STp->default_drvbuffer);
2374 }
2375 } else if (code == MT_ST_DEF_COMPRESSION) {
2376 if (value == MT_ST_CLEAR_DEFAULT) {
2377 STm->default_compression = ST_DONT_TOUCH;
2378 DEBC( printk(KERN_INFO
2379 "%s: Compression default disabled.\n", name));
2380 } else {
2381 if ((value & 0xff00) != 0) {
2382 STp->c_algo = (value & 0xff00) >> 8;
2383 DEBC( printk(KERN_INFO "%s: Compression algorithm set to 0x%x.\n",
2384 name, STp->c_algo));
2385 }
2386 if ((value & 0xff) != 0xff) {
2387 STm->default_compression = (value & 1 ? ST_YES : ST_NO);
2388 DEBC( printk(KERN_INFO "%s: Compression default set to %x\n",
2389 name, (value & 1)));
2390 if (STp->ready == ST_READY) {
2391 STp->compression_changed = 0;
2392 st_compression(STp, (STm->default_compression == ST_YES));
2393 }
2394 }
2395 }
2396 }
2397 } else
2398 return (-EIO);
2399
2400 return 0;
2401}
2402
2403#define MODE_HEADER_LENGTH 4
2404
2405/* Mode header and page byte offsets */
2406#define MH_OFF_DATA_LENGTH 0
2407#define MH_OFF_MEDIUM_TYPE 1
2408#define MH_OFF_DEV_SPECIFIC 2
2409#define MH_OFF_BDESCS_LENGTH 3
2410#define MP_OFF_PAGE_NBR 0
2411#define MP_OFF_PAGE_LENGTH 1
2412
2413/* Mode header and page bit masks */
2414#define MH_BIT_WP 0x80
2415#define MP_MSK_PAGE_NBR 0x3f
2416
2417/* Don't return block descriptors */
2418#define MODE_SENSE_OMIT_BDESCS 0x08
2419
2420#define MODE_SELECT_PAGE_FORMAT 0x10
2421
2422/* Read a mode page into the tape buffer. The block descriptors are included
2423 if incl_block_descs is true. The page control is ored to the page number
2424 parameter, if necessary. */
2425static int read_mode_page(struct scsi_tape *STp, int page, int omit_block_descs)
2426{
2427 unsigned char cmd[MAX_COMMAND_SIZE];
FUJITA Tomonori8ecf0d92008-12-05 15:25:28 +09002428 struct st_request *SRpnt;
2429 int ret;
Linus Torvalds1da177e2005-04-16 15:20:36 -07002430
2431 memset(cmd, 0, MAX_COMMAND_SIZE);
2432 cmd[0] = MODE_SENSE;
2433 if (omit_block_descs)
2434 cmd[1] = MODE_SENSE_OMIT_BDESCS;
2435 cmd[2] = page;
2436 cmd[4] = 255;
2437
FUJITA Tomonori8ecf0d92008-12-05 15:25:28 +09002438 SRpnt = st_allocate_request(STp);
2439 if (!SRpnt)
2440 return STp->buffer->syscall_result;
Linus Torvalds1da177e2005-04-16 15:20:36 -07002441
FUJITA Tomonori8ecf0d92008-12-05 15:25:28 +09002442 ret = st_scsi_kern_execute(SRpnt, cmd, DMA_FROM_DEVICE,
2443 STp->buffer->b_data, cmd[4],
2444 STp->device->request_queue->rq_timeout,
2445 MAX_RETRIES);
Mike Christie8b05b772005-11-08 04:06:44 -06002446 st_release_request(SRpnt);
Linus Torvalds1da177e2005-04-16 15:20:36 -07002447
FUJITA Tomonori8ecf0d92008-12-05 15:25:28 +09002448 return ret ? : STp->buffer->syscall_result;
Linus Torvalds1da177e2005-04-16 15:20:36 -07002449}
2450
2451
2452/* Send the mode page in the tape buffer to the drive. Assumes that the mode data
2453 in the buffer is correctly formatted. The long timeout is used if slow is non-zero. */
2454static int write_mode_page(struct scsi_tape *STp, int page, int slow)
2455{
FUJITA Tomonori18c87012008-12-05 15:25:29 +09002456 int pgo, timeout, ret = 0;
Linus Torvalds1da177e2005-04-16 15:20:36 -07002457 unsigned char cmd[MAX_COMMAND_SIZE];
FUJITA Tomonori18c87012008-12-05 15:25:29 +09002458 struct st_request *SRpnt;
Linus Torvalds1da177e2005-04-16 15:20:36 -07002459
2460 memset(cmd, 0, MAX_COMMAND_SIZE);
2461 cmd[0] = MODE_SELECT;
2462 cmd[1] = MODE_SELECT_PAGE_FORMAT;
2463 pgo = MODE_HEADER_LENGTH + (STp->buffer)->b_data[MH_OFF_BDESCS_LENGTH];
2464 cmd[4] = pgo + (STp->buffer)->b_data[pgo + MP_OFF_PAGE_LENGTH] + 2;
2465
2466 /* Clear reserved fields */
2467 (STp->buffer)->b_data[MH_OFF_DATA_LENGTH] = 0;
2468 (STp->buffer)->b_data[MH_OFF_MEDIUM_TYPE] = 0;
2469 (STp->buffer)->b_data[MH_OFF_DEV_SPECIFIC] &= ~MH_BIT_WP;
2470 (STp->buffer)->b_data[pgo + MP_OFF_PAGE_NBR] &= MP_MSK_PAGE_NBR;
2471
FUJITA Tomonori18c87012008-12-05 15:25:29 +09002472 SRpnt = st_allocate_request(STp);
2473 if (!SRpnt)
2474 return ret;
2475
2476 timeout = slow ? STp->long_timeout :
2477 STp->device->request_queue->rq_timeout;
2478
2479 ret = st_scsi_kern_execute(SRpnt, cmd, DMA_TO_DEVICE,
2480 STp->buffer->b_data, cmd[4], timeout, 0);
2481 if (!ret)
2482 ret = STp->buffer->syscall_result;
Linus Torvalds1da177e2005-04-16 15:20:36 -07002483
Mike Christie8b05b772005-11-08 04:06:44 -06002484 st_release_request(SRpnt);
Linus Torvalds1da177e2005-04-16 15:20:36 -07002485
FUJITA Tomonori18c87012008-12-05 15:25:29 +09002486 return ret;
Linus Torvalds1da177e2005-04-16 15:20:36 -07002487}
2488
2489
2490#define COMPRESSION_PAGE 0x0f
2491#define COMPRESSION_PAGE_LENGTH 16
2492
2493#define CP_OFF_DCE_DCC 2
2494#define CP_OFF_C_ALGO 7
2495
2496#define DCE_MASK 0x80
2497#define DCC_MASK 0x40
2498#define RED_MASK 0x60
2499
2500
2501/* Control the compression with mode page 15. Algorithm not changed if zero.
2502
2503 The block descriptors are read and written because Sony SDT-7000 does not
2504 work without this (suggestion from Michael Schaefer <Michael.Schaefer@dlr.de>).
2505 Including block descriptors should not cause any harm to other drives. */
2506
2507static int st_compression(struct scsi_tape * STp, int state)
2508{
2509 int retval;
2510 int mpoffs; /* Offset to mode page start */
2511 unsigned char *b_data = (STp->buffer)->b_data;
2512 DEB( char *name = tape_name(STp); )
2513
2514 if (STp->ready != ST_READY)
2515 return (-EIO);
2516
2517 /* Read the current page contents */
2518 retval = read_mode_page(STp, COMPRESSION_PAGE, 0);
2519 if (retval) {
2520 DEBC(printk(ST_DEB_MSG "%s: Compression mode page not supported.\n",
2521 name));
2522 return (-EIO);
2523 }
2524
2525 mpoffs = MODE_HEADER_LENGTH + b_data[MH_OFF_BDESCS_LENGTH];
2526 DEBC(printk(ST_DEB_MSG "%s: Compression state is %d.\n", name,
2527 (b_data[mpoffs + CP_OFF_DCE_DCC] & DCE_MASK ? 1 : 0)));
2528
2529 /* Check if compression can be changed */
2530 if ((b_data[mpoffs + CP_OFF_DCE_DCC] & DCC_MASK) == 0) {
2531 DEBC(printk(ST_DEB_MSG "%s: Compression not supported.\n", name));
2532 return (-EIO);
2533 }
2534
2535 /* Do the change */
2536 if (state) {
2537 b_data[mpoffs + CP_OFF_DCE_DCC] |= DCE_MASK;
2538 if (STp->c_algo != 0)
2539 b_data[mpoffs + CP_OFF_C_ALGO] = STp->c_algo;
2540 }
2541 else {
2542 b_data[mpoffs + CP_OFF_DCE_DCC] &= ~DCE_MASK;
2543 if (STp->c_algo != 0)
2544 b_data[mpoffs + CP_OFF_C_ALGO] = 0; /* no compression */
2545 }
2546
2547 retval = write_mode_page(STp, COMPRESSION_PAGE, 0);
2548 if (retval) {
2549 DEBC(printk(ST_DEB_MSG "%s: Compression change failed.\n", name));
2550 return (-EIO);
2551 }
2552 DEBC(printk(ST_DEB_MSG "%s: Compression state changed to %d.\n",
2553 name, state));
2554
2555 STp->compression_changed = 1;
2556 return 0;
2557}
2558
2559
2560/* Process the load and unload commands (does unload if the load code is zero) */
2561static int do_load_unload(struct scsi_tape *STp, struct file *filp, int load_code)
2562{
2563 int retval = (-EIO), timeout;
2564 DEB( char *name = tape_name(STp); )
2565 unsigned char cmd[MAX_COMMAND_SIZE];
2566 struct st_partstat *STps;
Mike Christie8b05b772005-11-08 04:06:44 -06002567 struct st_request *SRpnt;
Linus Torvalds1da177e2005-04-16 15:20:36 -07002568
2569 if (STp->ready != ST_READY && !load_code) {
2570 if (STp->ready == ST_NO_TAPE)
2571 return (-ENOMEDIUM);
2572 else
2573 return (-EIO);
2574 }
2575
2576 memset(cmd, 0, MAX_COMMAND_SIZE);
2577 cmd[0] = START_STOP;
2578 if (load_code)
2579 cmd[4] |= 1;
2580 /*
2581 * If arg >= 1 && arg <= 6 Enhanced load/unload in HP C1553A
2582 */
2583 if (load_code >= 1 + MT_ST_HPLOADER_OFFSET
2584 && load_code <= 6 + MT_ST_HPLOADER_OFFSET) {
2585 DEBC(printk(ST_DEB_MSG "%s: Enhanced %sload slot %2d.\n",
2586 name, (cmd[4]) ? "" : "un",
2587 load_code - MT_ST_HPLOADER_OFFSET));
2588 cmd[3] = load_code - MT_ST_HPLOADER_OFFSET; /* MediaID field of C1553A */
2589 }
2590 if (STp->immediate) {
2591 cmd[1] = 1; /* Don't wait for completion */
James Bottomleya02488e2008-11-30 10:36:26 -06002592 timeout = STp->device->request_queue->rq_timeout;
Linus Torvalds1da177e2005-04-16 15:20:36 -07002593 }
2594 else
2595 timeout = STp->long_timeout;
2596
2597 DEBC(
2598 if (!load_code)
2599 printk(ST_DEB_MSG "%s: Unloading tape.\n", name);
2600 else
2601 printk(ST_DEB_MSG "%s: Loading tape.\n", name);
2602 );
2603
FUJITA Tomonori15c920a2008-12-05 15:25:24 +09002604 SRpnt = st_allocate_request(STp);
Linus Torvalds1da177e2005-04-16 15:20:36 -07002605 if (!SRpnt)
FUJITA Tomonori15c920a2008-12-05 15:25:24 +09002606 return STp->buffer->syscall_result;
2607
2608 retval = st_scsi_kern_execute(SRpnt, cmd, DMA_NONE, NULL, 0, timeout,
2609 MAX_RETRIES);
2610 if (retval)
2611 goto out;
Linus Torvalds1da177e2005-04-16 15:20:36 -07002612
2613 retval = (STp->buffer)->syscall_result;
Linus Torvalds1da177e2005-04-16 15:20:36 -07002614
2615 if (!retval) { /* SCSI command successful */
2616
2617 if (!load_code) {
2618 STp->rew_at_close = 0;
2619 STp->ready = ST_NO_TAPE;
2620 }
2621 else {
2622 STp->rew_at_close = STp->autorew_dev;
2623 retval = check_tape(STp, filp);
2624 if (retval > 0)
2625 retval = 0;
2626 }
2627 }
2628 else {
2629 STps = &(STp->ps[STp->partition]);
2630 STps->drv_file = STps->drv_block = (-1);
2631 }
FUJITA Tomonori15c920a2008-12-05 15:25:24 +09002632out:
2633 st_release_request(SRpnt);
Linus Torvalds1da177e2005-04-16 15:20:36 -07002634
2635 return retval;
2636}
2637
2638#if DEBUG
2639#define ST_DEB_FORWARD 0
2640#define ST_DEB_BACKWARD 1
2641static void deb_space_print(char *name, int direction, char *units, unsigned char *cmd)
2642{
2643 s32 sc;
2644
2645 sc = cmd[2] & 0x80 ? 0xff000000 : 0;
2646 sc |= (cmd[2] << 16) | (cmd[3] << 8) | cmd[4];
2647 if (direction)
2648 sc = -sc;
2649 printk(ST_DEB_MSG "%s: Spacing tape %s over %d %s.\n", name,
2650 direction ? "backward" : "forward", sc, units);
2651}
2652#endif
2653
2654
2655/* Internal ioctl function */
2656static int st_int_ioctl(struct scsi_tape *STp, unsigned int cmd_in, unsigned long arg)
2657{
2658 int timeout;
2659 long ltmp;
2660 int ioctl_result;
2661 int chg_eof = 1;
2662 unsigned char cmd[MAX_COMMAND_SIZE];
Mike Christie8b05b772005-11-08 04:06:44 -06002663 struct st_request *SRpnt;
Linus Torvalds1da177e2005-04-16 15:20:36 -07002664 struct st_partstat *STps;
2665 int fileno, blkno, at_sm, undone;
2666 int datalen = 0, direction = DMA_NONE;
2667 char *name = tape_name(STp);
2668
2669 WARN_ON(STp->buffer->do_dio != 0);
2670 if (STp->ready != ST_READY) {
2671 if (STp->ready == ST_NO_TAPE)
2672 return (-ENOMEDIUM);
2673 else
2674 return (-EIO);
2675 }
2676 timeout = STp->long_timeout;
2677 STps = &(STp->ps[STp->partition]);
2678 fileno = STps->drv_file;
2679 blkno = STps->drv_block;
2680 at_sm = STps->at_sm;
2681
2682 memset(cmd, 0, MAX_COMMAND_SIZE);
2683 switch (cmd_in) {
2684 case MTFSFM:
2685 chg_eof = 0; /* Changed from the FSF after this */
2686 case MTFSF:
2687 cmd[0] = SPACE;
2688 cmd[1] = 0x01; /* Space FileMarks */
2689 cmd[2] = (arg >> 16);
2690 cmd[3] = (arg >> 8);
2691 cmd[4] = arg;
2692 DEBC(deb_space_print(name, ST_DEB_FORWARD, "filemarks", cmd);)
2693 if (fileno >= 0)
2694 fileno += arg;
2695 blkno = 0;
2696 at_sm &= (arg == 0);
2697 break;
2698 case MTBSFM:
2699 chg_eof = 0; /* Changed from the FSF after this */
2700 case MTBSF:
2701 cmd[0] = SPACE;
2702 cmd[1] = 0x01; /* Space FileMarks */
2703 ltmp = (-arg);
2704 cmd[2] = (ltmp >> 16);
2705 cmd[3] = (ltmp >> 8);
2706 cmd[4] = ltmp;
2707 DEBC(deb_space_print(name, ST_DEB_BACKWARD, "filemarks", cmd);)
2708 if (fileno >= 0)
2709 fileno -= arg;
2710 blkno = (-1); /* We can't know the block number */
2711 at_sm &= (arg == 0);
2712 break;
2713 case MTFSR:
2714 cmd[0] = SPACE;
2715 cmd[1] = 0x00; /* Space Blocks */
2716 cmd[2] = (arg >> 16);
2717 cmd[3] = (arg >> 8);
2718 cmd[4] = arg;
2719 DEBC(deb_space_print(name, ST_DEB_FORWARD, "blocks", cmd);)
2720 if (blkno >= 0)
2721 blkno += arg;
2722 at_sm &= (arg == 0);
2723 break;
2724 case MTBSR:
2725 cmd[0] = SPACE;
2726 cmd[1] = 0x00; /* Space Blocks */
2727 ltmp = (-arg);
2728 cmd[2] = (ltmp >> 16);
2729 cmd[3] = (ltmp >> 8);
2730 cmd[4] = ltmp;
2731 DEBC(deb_space_print(name, ST_DEB_BACKWARD, "blocks", cmd);)
2732 if (blkno >= 0)
2733 blkno -= arg;
2734 at_sm &= (arg == 0);
2735 break;
2736 case MTFSS:
2737 cmd[0] = SPACE;
2738 cmd[1] = 0x04; /* Space Setmarks */
2739 cmd[2] = (arg >> 16);
2740 cmd[3] = (arg >> 8);
2741 cmd[4] = arg;
2742 DEBC(deb_space_print(name, ST_DEB_FORWARD, "setmarks", cmd);)
2743 if (arg != 0) {
2744 blkno = fileno = (-1);
2745 at_sm = 1;
2746 }
2747 break;
2748 case MTBSS:
2749 cmd[0] = SPACE;
2750 cmd[1] = 0x04; /* Space Setmarks */
2751 ltmp = (-arg);
2752 cmd[2] = (ltmp >> 16);
2753 cmd[3] = (ltmp >> 8);
2754 cmd[4] = ltmp;
2755 DEBC(deb_space_print(name, ST_DEB_BACKWARD, "setmarks", cmd);)
2756 if (arg != 0) {
2757 blkno = fileno = (-1);
2758 at_sm = 1;
2759 }
2760 break;
2761 case MTWEOF:
2762 case MTWSM:
2763 if (STp->write_prot)
2764 return (-EACCES);
2765 cmd[0] = WRITE_FILEMARKS;
2766 if (cmd_in == MTWSM)
2767 cmd[1] = 2;
2768 cmd[2] = (arg >> 16);
2769 cmd[3] = (arg >> 8);
2770 cmd[4] = arg;
James Bottomleya02488e2008-11-30 10:36:26 -06002771 timeout = STp->device->request_queue->rq_timeout;
Linus Torvalds1da177e2005-04-16 15:20:36 -07002772 DEBC(
2773 if (cmd_in == MTWEOF)
2774 printk(ST_DEB_MSG "%s: Writing %d filemarks.\n", name,
2775 cmd[2] * 65536 + cmd[3] * 256 + cmd[4]);
2776 else
2777 printk(ST_DEB_MSG "%s: Writing %d setmarks.\n", name,
2778 cmd[2] * 65536 + cmd[3] * 256 + cmd[4]);
2779 )
2780 if (fileno >= 0)
2781 fileno += arg;
2782 blkno = 0;
2783 at_sm = (cmd_in == MTWSM);
2784 break;
2785 case MTREW:
2786 cmd[0] = REZERO_UNIT;
2787 if (STp->immediate) {
2788 cmd[1] = 1; /* Don't wait for completion */
James Bottomleya02488e2008-11-30 10:36:26 -06002789 timeout = STp->device->request_queue->rq_timeout;
Linus Torvalds1da177e2005-04-16 15:20:36 -07002790 }
2791 DEBC(printk(ST_DEB_MSG "%s: Rewinding tape.\n", name));
2792 fileno = blkno = at_sm = 0;
2793 break;
2794 case MTNOP:
2795 DEBC(printk(ST_DEB_MSG "%s: No op on tape.\n", name));
2796 return 0; /* Should do something ? */
2797 break;
2798 case MTRETEN:
2799 cmd[0] = START_STOP;
2800 if (STp->immediate) {
2801 cmd[1] = 1; /* Don't wait for completion */
James Bottomleya02488e2008-11-30 10:36:26 -06002802 timeout = STp->device->request_queue->rq_timeout;
Linus Torvalds1da177e2005-04-16 15:20:36 -07002803 }
2804 cmd[4] = 3;
2805 DEBC(printk(ST_DEB_MSG "%s: Retensioning tape.\n", name));
2806 fileno = blkno = at_sm = 0;
2807 break;
2808 case MTEOM:
2809 if (!STp->fast_mteom) {
2810 /* space to the end of tape */
2811 ioctl_result = st_int_ioctl(STp, MTFSF, 0x7fffff);
2812 fileno = STps->drv_file;
2813 if (STps->eof >= ST_EOD_1)
2814 return 0;
2815 /* The next lines would hide the number of spaced FileMarks
2816 That's why I inserted the previous lines. I had no luck
2817 with detecting EOM with FSF, so we go now to EOM.
2818 Joerg Weule */
2819 } else
2820 fileno = (-1);
2821 cmd[0] = SPACE;
2822 cmd[1] = 3;
2823 DEBC(printk(ST_DEB_MSG "%s: Spacing to end of recorded medium.\n",
2824 name));
2825 blkno = -1;
2826 at_sm = 0;
2827 break;
2828 case MTERASE:
2829 if (STp->write_prot)
2830 return (-EACCES);
2831 cmd[0] = ERASE;
2832 cmd[1] = (arg ? 1 : 0); /* Long erase with non-zero argument */
2833 if (STp->immediate) {
2834 cmd[1] |= 2; /* Don't wait for completion */
James Bottomleya02488e2008-11-30 10:36:26 -06002835 timeout = STp->device->request_queue->rq_timeout;
Linus Torvalds1da177e2005-04-16 15:20:36 -07002836 }
2837 else
2838 timeout = STp->long_timeout * 8;
2839
2840 DEBC(printk(ST_DEB_MSG "%s: Erasing tape.\n", name));
2841 fileno = blkno = at_sm = 0;
2842 break;
2843 case MTSETBLK: /* Set block length */
2844 case MTSETDENSITY: /* Set tape density */
2845 case MTSETDRVBUFFER: /* Set drive buffering */
2846 case SET_DENS_AND_BLK: /* Set density and block size */
2847 chg_eof = 0;
2848 if (STp->dirty || (STp->buffer)->buffer_bytes != 0)
2849 return (-EIO); /* Not allowed if data in buffer */
2850 if ((cmd_in == MTSETBLK || cmd_in == SET_DENS_AND_BLK) &&
2851 (arg & MT_ST_BLKSIZE_MASK) != 0 &&
2852 STp->max_block > 0 &&
2853 ((arg & MT_ST_BLKSIZE_MASK) < STp->min_block ||
2854 (arg & MT_ST_BLKSIZE_MASK) > STp->max_block)) {
2855 printk(KERN_WARNING "%s: Illegal block size.\n", name);
2856 return (-EINVAL);
2857 }
2858 cmd[0] = MODE_SELECT;
2859 if ((STp->use_pf & USE_PF))
2860 cmd[1] = MODE_SELECT_PAGE_FORMAT;
2861 cmd[4] = datalen = 12;
2862 direction = DMA_TO_DEVICE;
2863
2864 memset((STp->buffer)->b_data, 0, 12);
2865 if (cmd_in == MTSETDRVBUFFER)
2866 (STp->buffer)->b_data[2] = (arg & 7) << 4;
2867 else
2868 (STp->buffer)->b_data[2] =
2869 STp->drv_buffer << 4;
2870 (STp->buffer)->b_data[3] = 8; /* block descriptor length */
2871 if (cmd_in == MTSETDENSITY) {
2872 (STp->buffer)->b_data[4] = arg;
2873 STp->density_changed = 1; /* At least we tried ;-) */
2874 } else if (cmd_in == SET_DENS_AND_BLK)
2875 (STp->buffer)->b_data[4] = arg >> 24;
2876 else
2877 (STp->buffer)->b_data[4] = STp->density;
2878 if (cmd_in == MTSETBLK || cmd_in == SET_DENS_AND_BLK) {
2879 ltmp = arg & MT_ST_BLKSIZE_MASK;
2880 if (cmd_in == MTSETBLK)
2881 STp->blksize_changed = 1; /* At least we tried ;-) */
2882 } else
2883 ltmp = STp->block_size;
2884 (STp->buffer)->b_data[9] = (ltmp >> 16);
2885 (STp->buffer)->b_data[10] = (ltmp >> 8);
2886 (STp->buffer)->b_data[11] = ltmp;
James Bottomleya02488e2008-11-30 10:36:26 -06002887 timeout = STp->device->request_queue->rq_timeout;
Linus Torvalds1da177e2005-04-16 15:20:36 -07002888 DEBC(
2889 if (cmd_in == MTSETBLK || cmd_in == SET_DENS_AND_BLK)
2890 printk(ST_DEB_MSG
2891 "%s: Setting block size to %d bytes.\n", name,
2892 (STp->buffer)->b_data[9] * 65536 +
2893 (STp->buffer)->b_data[10] * 256 +
2894 (STp->buffer)->b_data[11]);
2895 if (cmd_in == MTSETDENSITY || cmd_in == SET_DENS_AND_BLK)
2896 printk(ST_DEB_MSG
2897 "%s: Setting density code to %x.\n", name,
2898 (STp->buffer)->b_data[4]);
2899 if (cmd_in == MTSETDRVBUFFER)
2900 printk(ST_DEB_MSG
2901 "%s: Setting drive buffer code to %d.\n", name,
2902 ((STp->buffer)->b_data[2] >> 4) & 7);
2903 )
2904 break;
2905 default:
2906 return (-ENOSYS);
2907 }
2908
FUJITA Tomonoriccc607f2008-12-05 15:25:31 +09002909 SRpnt = st_allocate_request(STp);
Linus Torvalds1da177e2005-04-16 15:20:36 -07002910 if (!SRpnt)
2911 return (STp->buffer)->syscall_result;
2912
FUJITA Tomonoriccc607f2008-12-05 15:25:31 +09002913 ioctl_result = st_scsi_kern_execute(SRpnt, cmd, direction,
2914 STp->buffer->b_data, datalen,
2915 timeout, MAX_RETRIES);
2916 if (!ioctl_result)
2917 ioctl_result = (STp->buffer)->syscall_result;
Linus Torvalds1da177e2005-04-16 15:20:36 -07002918
2919 if (!ioctl_result) { /* SCSI command successful */
Mike Christie8b05b772005-11-08 04:06:44 -06002920 st_release_request(SRpnt);
Linus Torvalds1da177e2005-04-16 15:20:36 -07002921 SRpnt = NULL;
2922 STps->drv_block = blkno;
2923 STps->drv_file = fileno;
2924 STps->at_sm = at_sm;
2925
2926 if (cmd_in == MTBSFM)
2927 ioctl_result = st_int_ioctl(STp, MTFSF, 1);
2928 else if (cmd_in == MTFSFM)
2929 ioctl_result = st_int_ioctl(STp, MTBSF, 1);
2930
2931 if (cmd_in == MTSETBLK || cmd_in == SET_DENS_AND_BLK) {
2932 int old_block_size = STp->block_size;
2933 STp->block_size = arg & MT_ST_BLKSIZE_MASK;
2934 if (STp->block_size != 0) {
2935 if (old_block_size == 0)
2936 normalize_buffer(STp->buffer);
2937 (STp->buffer)->buffer_blocks =
2938 (STp->buffer)->buffer_size / STp->block_size;
2939 }
2940 (STp->buffer)->buffer_bytes = (STp->buffer)->read_pointer = 0;
2941 if (cmd_in == SET_DENS_AND_BLK)
2942 STp->density = arg >> MT_ST_DENSITY_SHIFT;
2943 } else if (cmd_in == MTSETDRVBUFFER)
2944 STp->drv_buffer = (arg & 7);
2945 else if (cmd_in == MTSETDENSITY)
2946 STp->density = arg;
2947
2948 if (cmd_in == MTEOM)
2949 STps->eof = ST_EOD;
2950 else if (cmd_in == MTFSF)
2951 STps->eof = ST_FM;
2952 else if (chg_eof)
2953 STps->eof = ST_NOEOF;
2954
2955 if (cmd_in == MTWEOF)
2956 STps->rw = ST_IDLE;
2957 } else { /* SCSI command was not completely successful. Don't return
2958 from this block without releasing the SCSI command block! */
2959 struct st_cmdstatus *cmdstatp = &STp->buffer->cmdstat;
2960
2961 if (cmdstatp->flags & SENSE_EOM) {
2962 if (cmd_in != MTBSF && cmd_in != MTBSFM &&
2963 cmd_in != MTBSR && cmd_in != MTBSS)
2964 STps->eof = ST_EOM_OK;
2965 STps->drv_block = 0;
2966 }
2967
2968 if (cmdstatp->remainder_valid)
2969 undone = (int)cmdstatp->uremainder64;
2970 else
2971 undone = 0;
2972
2973 if (cmd_in == MTWEOF &&
2974 cmdstatp->have_sense &&
Kai Makisara91614c02007-01-26 00:38:39 +02002975 (cmdstatp->flags & SENSE_EOM)) {
2976 if (cmdstatp->sense_hdr.sense_key == NO_SENSE ||
2977 cmdstatp->sense_hdr.sense_key == RECOVERED_ERROR) {
2978 ioctl_result = 0; /* EOF(s) written successfully at EOM */
2979 STps->eof = ST_NOEOF;
2980 } else { /* Writing EOF(s) failed */
2981 if (fileno >= 0)
2982 fileno -= undone;
2983 if (undone < arg)
2984 STps->eof = ST_NOEOF;
2985 }
Linus Torvalds1da177e2005-04-16 15:20:36 -07002986 STps->drv_file = fileno;
Linus Torvalds1da177e2005-04-16 15:20:36 -07002987 } else if ((cmd_in == MTFSF) || (cmd_in == MTFSFM)) {
2988 if (fileno >= 0)
2989 STps->drv_file = fileno - undone;
2990 else
2991 STps->drv_file = fileno;
2992 STps->drv_block = -1;
2993 STps->eof = ST_NOEOF;
2994 } else if ((cmd_in == MTBSF) || (cmd_in == MTBSFM)) {
2995 if (arg > 0 && undone < 0) /* Some drives get this wrong */
2996 undone = (-undone);
2997 if (STps->drv_file >= 0)
2998 STps->drv_file = fileno + undone;
2999 STps->drv_block = 0;
3000 STps->eof = ST_NOEOF;
3001 } else if (cmd_in == MTFSR) {
3002 if (cmdstatp->flags & SENSE_FMK) { /* Hit filemark */
3003 if (STps->drv_file >= 0)
3004 STps->drv_file++;
3005 STps->drv_block = 0;
3006 STps->eof = ST_FM;
3007 } else {
3008 if (blkno >= undone)
3009 STps->drv_block = blkno - undone;
3010 else
3011 STps->drv_block = (-1);
3012 STps->eof = ST_NOEOF;
3013 }
3014 } else if (cmd_in == MTBSR) {
3015 if (cmdstatp->flags & SENSE_FMK) { /* Hit filemark */
3016 STps->drv_file--;
3017 STps->drv_block = (-1);
3018 } else {
3019 if (arg > 0 && undone < 0) /* Some drives get this wrong */
3020 undone = (-undone);
3021 if (STps->drv_block >= 0)
3022 STps->drv_block = blkno + undone;
3023 }
3024 STps->eof = ST_NOEOF;
3025 } else if (cmd_in == MTEOM) {
3026 STps->drv_file = (-1);
3027 STps->drv_block = (-1);
3028 STps->eof = ST_EOD;
3029 } else if (cmd_in == MTSETBLK ||
3030 cmd_in == MTSETDENSITY ||
3031 cmd_in == MTSETDRVBUFFER ||
3032 cmd_in == SET_DENS_AND_BLK) {
3033 if (cmdstatp->sense_hdr.sense_key == ILLEGAL_REQUEST &&
3034 !(STp->use_pf & PF_TESTED)) {
3035 /* Try the other possible state of Page Format if not
3036 already tried */
3037 STp->use_pf = !STp->use_pf | PF_TESTED;
Mike Christie8b05b772005-11-08 04:06:44 -06003038 st_release_request(SRpnt);
Linus Torvalds1da177e2005-04-16 15:20:36 -07003039 SRpnt = NULL;
3040 return st_int_ioctl(STp, cmd_in, arg);
3041 }
3042 } else if (chg_eof)
3043 STps->eof = ST_NOEOF;
3044
3045 if (cmdstatp->sense_hdr.sense_key == BLANK_CHECK)
3046 STps->eof = ST_EOD;
3047
Mike Christie8b05b772005-11-08 04:06:44 -06003048 st_release_request(SRpnt);
Linus Torvalds1da177e2005-04-16 15:20:36 -07003049 SRpnt = NULL;
3050 }
3051
3052 return ioctl_result;
3053}
3054
3055
3056/* Get the tape position. If bt == 2, arg points into a kernel space mt_loc
3057 structure. */
3058
3059static int get_location(struct scsi_tape *STp, unsigned int *block, int *partition,
3060 int logical)
3061{
3062 int result;
3063 unsigned char scmd[MAX_COMMAND_SIZE];
Mike Christie8b05b772005-11-08 04:06:44 -06003064 struct st_request *SRpnt;
Linus Torvalds1da177e2005-04-16 15:20:36 -07003065 DEB( char *name = tape_name(STp); )
3066
3067 if (STp->ready != ST_READY)
3068 return (-EIO);
3069
3070 memset(scmd, 0, MAX_COMMAND_SIZE);
3071 if ((STp->device)->scsi_level < SCSI_2) {
3072 scmd[0] = QFA_REQUEST_BLOCK;
3073 scmd[4] = 3;
3074 } else {
3075 scmd[0] = READ_POSITION;
3076 if (!logical && !STp->scsi2_logical)
3077 scmd[1] = 1;
3078 }
FUJITA Tomonori7a31ec32008-12-05 15:25:30 +09003079
3080 SRpnt = st_allocate_request(STp);
Linus Torvalds1da177e2005-04-16 15:20:36 -07003081 if (!SRpnt)
FUJITA Tomonori7a31ec32008-12-05 15:25:30 +09003082 return STp->buffer->syscall_result;
3083
3084 result = st_scsi_kern_execute(SRpnt, scmd, DMA_FROM_DEVICE,
3085 STp->buffer->b_data, 20,
3086 STp->device->request_queue->rq_timeout,
3087 MAX_READY_RETRIES);
3088 if (result)
3089 goto out;
Linus Torvalds1da177e2005-04-16 15:20:36 -07003090
3091 if ((STp->buffer)->syscall_result != 0 ||
3092 (STp->device->scsi_level >= SCSI_2 &&
3093 ((STp->buffer)->b_data[0] & 4) != 0)) {
3094 *block = *partition = 0;
3095 DEBC(printk(ST_DEB_MSG "%s: Can't read tape position.\n", name));
3096 result = (-EIO);
3097 } else {
3098 result = 0;
3099 if ((STp->device)->scsi_level < SCSI_2) {
3100 *block = ((STp->buffer)->b_data[0] << 16)
3101 + ((STp->buffer)->b_data[1] << 8)
3102 + (STp->buffer)->b_data[2];
3103 *partition = 0;
3104 } else {
3105 *block = ((STp->buffer)->b_data[4] << 24)
3106 + ((STp->buffer)->b_data[5] << 16)
3107 + ((STp->buffer)->b_data[6] << 8)
3108 + (STp->buffer)->b_data[7];
3109 *partition = (STp->buffer)->b_data[1];
3110 if (((STp->buffer)->b_data[0] & 0x80) &&
3111 (STp->buffer)->b_data[1] == 0) /* BOP of partition 0 */
3112 STp->ps[0].drv_block = STp->ps[0].drv_file = 0;
3113 }
3114 DEBC(printk(ST_DEB_MSG "%s: Got tape pos. blk %d part %d.\n", name,
3115 *block, *partition));
3116 }
FUJITA Tomonori7a31ec32008-12-05 15:25:30 +09003117out:
Mike Christie8b05b772005-11-08 04:06:44 -06003118 st_release_request(SRpnt);
Linus Torvalds1da177e2005-04-16 15:20:36 -07003119 SRpnt = NULL;
3120
3121 return result;
3122}
3123
3124
3125/* Set the tape block and partition. Negative partition means that only the
3126 block should be set in vendor specific way. */
3127static int set_location(struct scsi_tape *STp, unsigned int block, int partition,
3128 int logical)
3129{
3130 struct st_partstat *STps;
3131 int result, p;
3132 unsigned int blk;
3133 int timeout;
3134 unsigned char scmd[MAX_COMMAND_SIZE];
Mike Christie8b05b772005-11-08 04:06:44 -06003135 struct st_request *SRpnt;
Linus Torvalds1da177e2005-04-16 15:20:36 -07003136 DEB( char *name = tape_name(STp); )
3137
3138 if (STp->ready != ST_READY)
3139 return (-EIO);
3140 timeout = STp->long_timeout;
3141 STps = &(STp->ps[STp->partition]);
3142
3143 DEBC(printk(ST_DEB_MSG "%s: Setting block to %d and partition to %d.\n",
3144 name, block, partition));
3145 DEB(if (partition < 0)
3146 return (-EIO); )
3147
3148 /* Update the location at the partition we are leaving */
3149 if ((!STp->can_partitions && partition != 0) ||
3150 partition >= ST_NBR_PARTITIONS)
3151 return (-EINVAL);
3152 if (partition != STp->partition) {
3153 if (get_location(STp, &blk, &p, 1))
3154 STps->last_block_valid = 0;
3155 else {
3156 STps->last_block_valid = 1;
3157 STps->last_block_visited = blk;
3158 DEBC(printk(ST_DEB_MSG
3159 "%s: Visited block %d for partition %d saved.\n",
3160 name, blk, STp->partition));
3161 }
3162 }
3163
3164 memset(scmd, 0, MAX_COMMAND_SIZE);
3165 if ((STp->device)->scsi_level < SCSI_2) {
3166 scmd[0] = QFA_SEEK_BLOCK;
3167 scmd[2] = (block >> 16);
3168 scmd[3] = (block >> 8);
3169 scmd[4] = block;
3170 scmd[5] = 0;
3171 } else {
3172 scmd[0] = SEEK_10;
3173 scmd[3] = (block >> 24);
3174 scmd[4] = (block >> 16);
3175 scmd[5] = (block >> 8);
3176 scmd[6] = block;
3177 if (!logical && !STp->scsi2_logical)
3178 scmd[1] = 4;
3179 if (STp->partition != partition) {
3180 scmd[1] |= 2;
3181 scmd[8] = partition;
3182 DEBC(printk(ST_DEB_MSG
3183 "%s: Trying to change partition from %d to %d\n",
3184 name, STp->partition, partition));
3185 }
3186 }
3187 if (STp->immediate) {
3188 scmd[1] |= 1; /* Don't wait for completion */
James Bottomleya02488e2008-11-30 10:36:26 -06003189 timeout = STp->device->request_queue->rq_timeout;
Linus Torvalds1da177e2005-04-16 15:20:36 -07003190 }
3191
FUJITA Tomonori3c0bf162008-12-05 15:25:23 +09003192 SRpnt = st_allocate_request(STp);
Linus Torvalds1da177e2005-04-16 15:20:36 -07003193 if (!SRpnt)
FUJITA Tomonori3c0bf162008-12-05 15:25:23 +09003194 return STp->buffer->syscall_result;
3195
3196 result = st_scsi_kern_execute(SRpnt, scmd, DMA_NONE, NULL, 0,
3197 timeout, MAX_READY_RETRIES);
3198 if (result)
3199 goto out;
Linus Torvalds1da177e2005-04-16 15:20:36 -07003200
3201 STps->drv_block = STps->drv_file = (-1);
3202 STps->eof = ST_NOEOF;
3203 if ((STp->buffer)->syscall_result != 0) {
3204 result = (-EIO);
3205 if (STp->can_partitions &&
3206 (STp->device)->scsi_level >= SCSI_2 &&
3207 (p = find_partition(STp)) >= 0)
3208 STp->partition = p;
3209 } else {
3210 if (STp->can_partitions) {
3211 STp->partition = partition;
3212 STps = &(STp->ps[partition]);
3213 if (!STps->last_block_valid ||
3214 STps->last_block_visited != block) {
3215 STps->at_sm = 0;
3216 STps->rw = ST_IDLE;
3217 }
3218 } else
3219 STps->at_sm = 0;
3220 if (block == 0)
3221 STps->drv_block = STps->drv_file = 0;
3222 result = 0;
3223 }
FUJITA Tomonori3c0bf162008-12-05 15:25:23 +09003224out:
Mike Christie8b05b772005-11-08 04:06:44 -06003225 st_release_request(SRpnt);
Linus Torvalds1da177e2005-04-16 15:20:36 -07003226 SRpnt = NULL;
3227
3228 return result;
3229}
3230
3231
3232/* Find the current partition number for the drive status. Called from open and
3233 returns either partition number of negative error code. */
3234static int find_partition(struct scsi_tape *STp)
3235{
3236 int i, partition;
3237 unsigned int block;
3238
3239 if ((i = get_location(STp, &block, &partition, 1)) < 0)
3240 return i;
3241 if (partition >= ST_NBR_PARTITIONS)
3242 return (-EIO);
3243 return partition;
3244}
3245
3246
3247/* Change the partition if necessary */
3248static int switch_partition(struct scsi_tape *STp)
3249{
3250 struct st_partstat *STps;
3251
3252 if (STp->partition == STp->new_partition)
3253 return 0;
3254 STps = &(STp->ps[STp->new_partition]);
3255 if (!STps->last_block_valid)
3256 STps->last_block_visited = 0;
3257 return set_location(STp, STps->last_block_visited, STp->new_partition, 1);
3258}
3259
3260/* Functions for reading and writing the medium partition mode page. */
3261
3262#define PART_PAGE 0x11
3263#define PART_PAGE_FIXED_LENGTH 8
3264
3265#define PP_OFF_MAX_ADD_PARTS 2
3266#define PP_OFF_NBR_ADD_PARTS 3
3267#define PP_OFF_FLAGS 4
3268#define PP_OFF_PART_UNITS 6
3269#define PP_OFF_RESERVED 7
3270
3271#define PP_BIT_IDP 0x20
3272#define PP_MSK_PSUM_MB 0x10
3273
3274/* Get the number of partitions on the tape. As a side effect reads the
3275 mode page into the tape buffer. */
3276static int nbr_partitions(struct scsi_tape *STp)
3277{
3278 int result;
3279 DEB( char *name = tape_name(STp); )
3280
3281 if (STp->ready != ST_READY)
3282 return (-EIO);
3283
3284 result = read_mode_page(STp, PART_PAGE, 1);
3285
3286 if (result) {
3287 DEBC(printk(ST_DEB_MSG "%s: Can't read medium partition page.\n",
3288 name));
3289 result = (-EIO);
3290 } else {
3291 result = (STp->buffer)->b_data[MODE_HEADER_LENGTH +
3292 PP_OFF_NBR_ADD_PARTS] + 1;
3293 DEBC(printk(ST_DEB_MSG "%s: Number of partitions %d.\n", name, result));
3294 }
3295
3296 return result;
3297}
3298
3299
3300/* Partition the tape into two partitions if size > 0 or one partition if
3301 size == 0.
3302
3303 The block descriptors are read and written because Sony SDT-7000 does not
3304 work without this (suggestion from Michael Schaefer <Michael.Schaefer@dlr.de>).
3305
3306 My HP C1533A drive returns only one partition size field. This is used to
3307 set the size of partition 1. There is no size field for the default partition.
3308 Michael Schaefer's Sony SDT-7000 returns two descriptors and the second is
3309 used to set the size of partition 1 (this is what the SCSI-3 standard specifies).
3310 The following algorithm is used to accommodate both drives: if the number of
3311 partition size fields is greater than the maximum number of additional partitions
3312 in the mode page, the second field is used. Otherwise the first field is used.
3313
3314 For Seagate DDS drives the page length must be 8 when no partitions is defined
3315 and 10 when 1 partition is defined (information from Eric Lee Green). This is
3316 is acceptable also to some other old drives and enforced if the first partition
3317 size field is used for the first additional partition size.
3318 */
3319static int partition_tape(struct scsi_tape *STp, int size)
3320{
3321 char *name = tape_name(STp);
3322 int result;
3323 int pgo, psd_cnt, psdo;
3324 unsigned char *bp;
3325
3326 result = read_mode_page(STp, PART_PAGE, 0);
3327 if (result) {
3328 DEBC(printk(ST_DEB_MSG "%s: Can't read partition mode page.\n", name));
3329 return result;
3330 }
3331 /* The mode page is in the buffer. Let's modify it and write it. */
3332 bp = (STp->buffer)->b_data;
3333 pgo = MODE_HEADER_LENGTH + bp[MH_OFF_BDESCS_LENGTH];
3334 DEBC(printk(ST_DEB_MSG "%s: Partition page length is %d bytes.\n",
3335 name, bp[pgo + MP_OFF_PAGE_LENGTH] + 2));
3336
3337 psd_cnt = (bp[pgo + MP_OFF_PAGE_LENGTH] + 2 - PART_PAGE_FIXED_LENGTH) / 2;
3338 psdo = pgo + PART_PAGE_FIXED_LENGTH;
3339 if (psd_cnt > bp[pgo + PP_OFF_MAX_ADD_PARTS]) {
3340 bp[psdo] = bp[psdo + 1] = 0xff; /* Rest of the tape */
3341 psdo += 2;
3342 }
3343 memset(bp + psdo, 0, bp[pgo + PP_OFF_NBR_ADD_PARTS] * 2);
3344
3345 DEBC(printk("%s: psd_cnt %d, max.parts %d, nbr_parts %d\n", name,
3346 psd_cnt, bp[pgo + PP_OFF_MAX_ADD_PARTS],
3347 bp[pgo + PP_OFF_NBR_ADD_PARTS]));
3348
3349 if (size <= 0) {
3350 bp[pgo + PP_OFF_NBR_ADD_PARTS] = 0;
3351 if (psd_cnt <= bp[pgo + PP_OFF_MAX_ADD_PARTS])
3352 bp[pgo + MP_OFF_PAGE_LENGTH] = 6;
3353 DEBC(printk(ST_DEB_MSG "%s: Formatting tape with one partition.\n",
3354 name));
3355 } else {
3356 bp[psdo] = (size >> 8) & 0xff;
3357 bp[psdo + 1] = size & 0xff;
3358 bp[pgo + 3] = 1;
3359 if (bp[pgo + MP_OFF_PAGE_LENGTH] < 8)
3360 bp[pgo + MP_OFF_PAGE_LENGTH] = 8;
3361 DEBC(printk(ST_DEB_MSG
3362 "%s: Formatting tape with two partitions (1 = %d MB).\n",
3363 name, size));
3364 }
3365 bp[pgo + PP_OFF_PART_UNITS] = 0;
3366 bp[pgo + PP_OFF_RESERVED] = 0;
3367 bp[pgo + PP_OFF_FLAGS] = PP_BIT_IDP | PP_MSK_PSUM_MB;
3368
3369 result = write_mode_page(STp, PART_PAGE, 1);
3370 if (result) {
3371 printk(KERN_INFO "%s: Partitioning of tape failed.\n", name);
3372 result = (-EIO);
3373 }
3374
3375 return result;
3376}
3377
3378
3379
3380/* The ioctl command */
Kai Makisarafd66c1b2008-01-17 22:45:22 +02003381static long st_ioctl(struct file *file, unsigned int cmd_in, unsigned long arg)
Linus Torvalds1da177e2005-04-16 15:20:36 -07003382{
3383 int i, cmd_nr, cmd_type, bt;
3384 int retval = 0;
3385 unsigned int blk;
3386 struct scsi_tape *STp = file->private_data;
3387 struct st_modedef *STm;
3388 struct st_partstat *STps;
3389 char *name = tape_name(STp);
3390 void __user *p = (void __user *)arg;
3391
Matthias Kaehlcke28f85002007-07-29 23:38:15 +02003392 if (mutex_lock_interruptible(&STp->lock))
Linus Torvalds1da177e2005-04-16 15:20:36 -07003393 return -ERESTARTSYS;
3394
3395 DEB(
3396 if (debugging && !STp->in_use) {
3397 printk(ST_DEB_MSG "%s: Incorrect device.\n", name);
3398 retval = (-EIO);
3399 goto out;
3400 } ) /* end DEB */
3401
3402 STm = &(STp->modes[STp->current_mode]);
3403 STps = &(STp->ps[STp->partition]);
3404
3405 /*
3406 * If we are in the middle of error recovery, don't let anyone
3407 * else try and use this device. Also, if error recovery fails, it
3408 * may try and take the device offline, in which case all further
3409 * access to the device is prohibited.
3410 */
Al Viro83ff6fe2008-03-02 08:15:49 -05003411 retval = scsi_nonblockable_ioctl(STp->device, cmd_in, p,
3412 file->f_flags & O_NDELAY);
Linus Torvalds1da177e2005-04-16 15:20:36 -07003413 if (!scsi_block_when_processing_errors(STp->device) || retval != -ENODEV)
3414 goto out;
3415 retval = 0;
3416
3417 cmd_type = _IOC_TYPE(cmd_in);
3418 cmd_nr = _IOC_NR(cmd_in);
3419
3420 if (cmd_type == _IOC_TYPE(MTIOCTOP) && cmd_nr == _IOC_NR(MTIOCTOP)) {
3421 struct mtop mtc;
3422
3423 if (_IOC_SIZE(cmd_in) != sizeof(mtc)) {
3424 retval = (-EINVAL);
3425 goto out;
3426 }
3427
3428 i = copy_from_user(&mtc, p, sizeof(struct mtop));
3429 if (i) {
3430 retval = (-EFAULT);
3431 goto out;
3432 }
3433
3434 if (mtc.mt_op == MTSETDRVBUFFER && !capable(CAP_SYS_ADMIN)) {
3435 printk(KERN_WARNING
3436 "%s: MTSETDRVBUFFER only allowed for root.\n", name);
3437 retval = (-EPERM);
3438 goto out;
3439 }
3440 if (!STm->defined &&
3441 (mtc.mt_op != MTSETDRVBUFFER &&
3442 (mtc.mt_count & MT_ST_OPTIONS) == 0)) {
3443 retval = (-ENXIO);
3444 goto out;
3445 }
3446
3447 if (!STp->pos_unknown) {
3448
3449 if (STps->eof == ST_FM_HIT) {
3450 if (mtc.mt_op == MTFSF || mtc.mt_op == MTFSFM ||
3451 mtc.mt_op == MTEOM) {
3452 mtc.mt_count -= 1;
3453 if (STps->drv_file >= 0)
3454 STps->drv_file += 1;
3455 } else if (mtc.mt_op == MTBSF || mtc.mt_op == MTBSFM) {
3456 mtc.mt_count += 1;
3457 if (STps->drv_file >= 0)
3458 STps->drv_file += 1;
3459 }
3460 }
3461
3462 if (mtc.mt_op == MTSEEK) {
3463 /* Old position must be restored if partition will be
3464 changed */
3465 i = !STp->can_partitions ||
3466 (STp->new_partition != STp->partition);
3467 } else {
3468 i = mtc.mt_op == MTREW || mtc.mt_op == MTOFFL ||
3469 mtc.mt_op == MTRETEN || mtc.mt_op == MTEOM ||
3470 mtc.mt_op == MTLOCK || mtc.mt_op == MTLOAD ||
3471 mtc.mt_op == MTFSF || mtc.mt_op == MTFSFM ||
3472 mtc.mt_op == MTBSF || mtc.mt_op == MTBSFM ||
3473 mtc.mt_op == MTCOMPRESSION;
3474 }
3475 i = flush_buffer(STp, i);
3476 if (i < 0) {
3477 retval = i;
3478 goto out;
3479 }
3480 if (STps->rw == ST_WRITING &&
3481 (mtc.mt_op == MTREW || mtc.mt_op == MTOFFL ||
3482 mtc.mt_op == MTSEEK ||
3483 mtc.mt_op == MTBSF || mtc.mt_op == MTBSFM)) {
3484 i = st_int_ioctl(STp, MTWEOF, 1);
3485 if (i < 0) {
3486 retval = i;
3487 goto out;
3488 }
3489 if (mtc.mt_op == MTBSF || mtc.mt_op == MTBSFM)
3490 mtc.mt_count++;
3491 STps->rw = ST_IDLE;
3492 }
3493
3494 } else {
3495 /*
3496 * If there was a bus reset, block further access
3497 * to this device. If the user wants to rewind the tape,
3498 * then reset the flag and allow access again.
3499 */
3500 if (mtc.mt_op != MTREW &&
3501 mtc.mt_op != MTOFFL &&
3502 mtc.mt_op != MTRETEN &&
3503 mtc.mt_op != MTERASE &&
3504 mtc.mt_op != MTSEEK &&
3505 mtc.mt_op != MTEOM) {
3506 retval = (-EIO);
3507 goto out;
3508 }
3509 reset_state(STp);
3510 /* remove this when the midlevel properly clears was_reset */
3511 STp->device->was_reset = 0;
3512 }
3513
3514 if (mtc.mt_op != MTNOP && mtc.mt_op != MTSETBLK &&
3515 mtc.mt_op != MTSETDENSITY && mtc.mt_op != MTWSM &&
3516 mtc.mt_op != MTSETDRVBUFFER && mtc.mt_op != MTSETPART)
3517 STps->rw = ST_IDLE; /* Prevent automatic WEOF and fsf */
3518
3519 if (mtc.mt_op == MTOFFL && STp->door_locked != ST_UNLOCKED)
3520 do_door_lock(STp, 0); /* Ignore result! */
3521
3522 if (mtc.mt_op == MTSETDRVBUFFER &&
3523 (mtc.mt_count & MT_ST_OPTIONS) != 0) {
3524 retval = st_set_options(STp, mtc.mt_count);
3525 goto out;
3526 }
3527
3528 if (mtc.mt_op == MTSETPART) {
3529 if (!STp->can_partitions ||
3530 mtc.mt_count < 0 || mtc.mt_count >= ST_NBR_PARTITIONS) {
3531 retval = (-EINVAL);
3532 goto out;
3533 }
3534 if (mtc.mt_count >= STp->nbr_partitions &&
3535 (STp->nbr_partitions = nbr_partitions(STp)) < 0) {
3536 retval = (-EIO);
3537 goto out;
3538 }
3539 if (mtc.mt_count >= STp->nbr_partitions) {
3540 retval = (-EINVAL);
3541 goto out;
3542 }
3543 STp->new_partition = mtc.mt_count;
3544 retval = 0;
3545 goto out;
3546 }
3547
3548 if (mtc.mt_op == MTMKPART) {
3549 if (!STp->can_partitions) {
3550 retval = (-EINVAL);
3551 goto out;
3552 }
3553 if ((i = st_int_ioctl(STp, MTREW, 0)) < 0 ||
3554 (i = partition_tape(STp, mtc.mt_count)) < 0) {
3555 retval = i;
3556 goto out;
3557 }
3558 for (i = 0; i < ST_NBR_PARTITIONS; i++) {
3559 STp->ps[i].rw = ST_IDLE;
3560 STp->ps[i].at_sm = 0;
3561 STp->ps[i].last_block_valid = 0;
3562 }
3563 STp->partition = STp->new_partition = 0;
3564 STp->nbr_partitions = 1; /* Bad guess ?-) */
3565 STps->drv_block = STps->drv_file = 0;
3566 retval = 0;
3567 goto out;
3568 }
3569
3570 if (mtc.mt_op == MTSEEK) {
3571 i = set_location(STp, mtc.mt_count, STp->new_partition, 0);
3572 if (!STp->can_partitions)
3573 STp->ps[0].rw = ST_IDLE;
3574 retval = i;
3575 goto out;
3576 }
3577
3578 if (mtc.mt_op == MTUNLOAD || mtc.mt_op == MTOFFL) {
3579 retval = do_load_unload(STp, file, 0);
3580 goto out;
3581 }
3582
3583 if (mtc.mt_op == MTLOAD) {
3584 retval = do_load_unload(STp, file, max(1, mtc.mt_count));
3585 goto out;
3586 }
3587
3588 if (mtc.mt_op == MTLOCK || mtc.mt_op == MTUNLOCK) {
3589 retval = do_door_lock(STp, (mtc.mt_op == MTLOCK));
3590 goto out;
3591 }
3592
3593 if (STp->can_partitions && STp->ready == ST_READY &&
3594 (i = switch_partition(STp)) < 0) {
3595 retval = i;
3596 goto out;
3597 }
3598
3599 if (mtc.mt_op == MTCOMPRESSION)
3600 retval = st_compression(STp, (mtc.mt_count & 1));
3601 else
3602 retval = st_int_ioctl(STp, mtc.mt_op, mtc.mt_count);
3603 goto out;
3604 }
3605 if (!STm->defined) {
3606 retval = (-ENXIO);
3607 goto out;
3608 }
3609
3610 if ((i = flush_buffer(STp, 0)) < 0) {
3611 retval = i;
3612 goto out;
3613 }
3614 if (STp->can_partitions &&
3615 (i = switch_partition(STp)) < 0) {
3616 retval = i;
3617 goto out;
3618 }
3619
3620 if (cmd_type == _IOC_TYPE(MTIOCGET) && cmd_nr == _IOC_NR(MTIOCGET)) {
3621 struct mtget mt_status;
3622
3623 if (_IOC_SIZE(cmd_in) != sizeof(struct mtget)) {
3624 retval = (-EINVAL);
3625 goto out;
3626 }
3627
3628 mt_status.mt_type = STp->tape_type;
3629 mt_status.mt_dsreg =
3630 ((STp->block_size << MT_ST_BLKSIZE_SHIFT) & MT_ST_BLKSIZE_MASK) |
3631 ((STp->density << MT_ST_DENSITY_SHIFT) & MT_ST_DENSITY_MASK);
3632 mt_status.mt_blkno = STps->drv_block;
3633 mt_status.mt_fileno = STps->drv_file;
3634 if (STp->block_size != 0) {
3635 if (STps->rw == ST_WRITING)
3636 mt_status.mt_blkno +=
3637 (STp->buffer)->buffer_bytes / STp->block_size;
3638 else if (STps->rw == ST_READING)
3639 mt_status.mt_blkno -=
3640 ((STp->buffer)->buffer_bytes +
3641 STp->block_size - 1) / STp->block_size;
3642 }
3643
3644 mt_status.mt_gstat = 0;
3645 if (STp->drv_write_prot)
3646 mt_status.mt_gstat |= GMT_WR_PROT(0xffffffff);
3647 if (mt_status.mt_blkno == 0) {
3648 if (mt_status.mt_fileno == 0)
3649 mt_status.mt_gstat |= GMT_BOT(0xffffffff);
3650 else
3651 mt_status.mt_gstat |= GMT_EOF(0xffffffff);
3652 }
3653 mt_status.mt_erreg = (STp->recover_reg << MT_ST_SOFTERR_SHIFT);
3654 mt_status.mt_resid = STp->partition;
3655 if (STps->eof == ST_EOM_OK || STps->eof == ST_EOM_ERROR)
3656 mt_status.mt_gstat |= GMT_EOT(0xffffffff);
3657 else if (STps->eof >= ST_EOM_OK)
3658 mt_status.mt_gstat |= GMT_EOD(0xffffffff);
3659 if (STp->density == 1)
3660 mt_status.mt_gstat |= GMT_D_800(0xffffffff);
3661 else if (STp->density == 2)
3662 mt_status.mt_gstat |= GMT_D_1600(0xffffffff);
3663 else if (STp->density == 3)
3664 mt_status.mt_gstat |= GMT_D_6250(0xffffffff);
3665 if (STp->ready == ST_READY)
3666 mt_status.mt_gstat |= GMT_ONLINE(0xffffffff);
3667 if (STp->ready == ST_NO_TAPE)
3668 mt_status.mt_gstat |= GMT_DR_OPEN(0xffffffff);
3669 if (STps->at_sm)
3670 mt_status.mt_gstat |= GMT_SM(0xffffffff);
3671 if (STm->do_async_writes ||
3672 (STm->do_buffer_writes && STp->block_size != 0) ||
3673 STp->drv_buffer != 0)
3674 mt_status.mt_gstat |= GMT_IM_REP_EN(0xffffffff);
3675 if (STp->cleaning_req)
3676 mt_status.mt_gstat |= GMT_CLN(0xffffffff);
3677
3678 i = copy_to_user(p, &mt_status, sizeof(struct mtget));
3679 if (i) {
3680 retval = (-EFAULT);
3681 goto out;
3682 }
3683
3684 STp->recover_reg = 0; /* Clear after read */
3685 retval = 0;
3686 goto out;
3687 } /* End of MTIOCGET */
3688 if (cmd_type == _IOC_TYPE(MTIOCPOS) && cmd_nr == _IOC_NR(MTIOCPOS)) {
3689 struct mtpos mt_pos;
3690 if (_IOC_SIZE(cmd_in) != sizeof(struct mtpos)) {
3691 retval = (-EINVAL);
3692 goto out;
3693 }
3694 if ((i = get_location(STp, &blk, &bt, 0)) < 0) {
3695 retval = i;
3696 goto out;
3697 }
3698 mt_pos.mt_blkno = blk;
3699 i = copy_to_user(p, &mt_pos, sizeof(struct mtpos));
3700 if (i)
3701 retval = (-EFAULT);
3702 goto out;
3703 }
Matthias Kaehlcke28f85002007-07-29 23:38:15 +02003704 mutex_unlock(&STp->lock);
Linus Torvalds1da177e2005-04-16 15:20:36 -07003705 switch (cmd_in) {
3706 case SCSI_IOCTL_GET_IDLUN:
3707 case SCSI_IOCTL_GET_BUS_NUMBER:
3708 break;
3709 default:
Kai Makisara 16c4b3e2005-05-01 18:11:55 +03003710 if ((cmd_in == SG_IO ||
3711 cmd_in == SCSI_IOCTL_SEND_COMMAND ||
3712 cmd_in == CDROM_SEND_PACKET) &&
3713 !capable(CAP_SYS_RAWIO))
Linus Torvalds1da177e2005-04-16 15:20:36 -07003714 i = -EPERM;
3715 else
Al Viro74f3c8a2007-08-27 15:38:10 -04003716 i = scsi_cmd_ioctl(STp->disk->queue, STp->disk,
3717 file->f_mode, cmd_in, p);
Linus Torvalds1da177e2005-04-16 15:20:36 -07003718 if (i != -ENOTTY)
3719 return i;
3720 break;
3721 }
Kai Makisara 16c4b3e2005-05-01 18:11:55 +03003722 retval = scsi_ioctl(STp->device, cmd_in, p);
3723 if (!retval && cmd_in == SCSI_IOCTL_STOP_UNIT) { /* unload */
3724 STp->rew_at_close = 0;
3725 STp->ready = ST_NO_TAPE;
3726 }
3727 return retval;
Linus Torvalds1da177e2005-04-16 15:20:36 -07003728
3729 out:
Matthias Kaehlcke28f85002007-07-29 23:38:15 +02003730 mutex_unlock(&STp->lock);
Linus Torvalds1da177e2005-04-16 15:20:36 -07003731 return retval;
3732}
3733
3734#ifdef CONFIG_COMPAT
3735static long st_compat_ioctl(struct file *file, unsigned int cmd, unsigned long arg)
3736{
3737 struct scsi_tape *STp = file->private_data;
3738 struct scsi_device *sdev = STp->device;
3739 int ret = -ENOIOCTLCMD;
3740 if (sdev->host->hostt->compat_ioctl) {
3741
3742 ret = sdev->host->hostt->compat_ioctl(sdev, cmd, (void __user *)arg);
3743
3744 }
3745 return ret;
3746}
3747#endif
3748
3749
3750
3751/* Try to allocate a new tape buffer. Calling function must not hold
3752 dev_arr_lock. */
3753static struct st_buffer *
3754 new_tape_buffer(int from_initialization, int need_dma, int max_sg)
3755{
Mike Christie8b05b772005-11-08 04:06:44 -06003756 int i, got = 0;
Al Viroc53033f2005-10-21 03:22:08 -04003757 gfp_t priority;
Linus Torvalds1da177e2005-04-16 15:20:36 -07003758 struct st_buffer *tb;
3759
3760 if (from_initialization)
3761 priority = GFP_ATOMIC;
3762 else
3763 priority = GFP_KERNEL;
3764
3765 i = sizeof(struct st_buffer) + (max_sg - 1) * sizeof(struct scatterlist) +
3766 max_sg * sizeof(struct st_buf_fragment);
Jes Sorensen24669f752006-01-16 10:31:18 -05003767 tb = kzalloc(i, priority);
Linus Torvalds1da177e2005-04-16 15:20:36 -07003768 if (!tb) {
3769 printk(KERN_NOTICE "st: Can't allocate new tape buffer.\n");
3770 return NULL;
3771 }
Mike Christie8b05b772005-11-08 04:06:44 -06003772 tb->frp_segs = tb->orig_frp_segs = 0;
Linus Torvalds1da177e2005-04-16 15:20:36 -07003773 tb->use_sg = max_sg;
Linus Torvalds1da177e2005-04-16 15:20:36 -07003774 tb->frp = (struct st_buf_fragment *)(&(tb->sg[0]) + max_sg);
3775
Linus Torvalds1da177e2005-04-16 15:20:36 -07003776 tb->dma = need_dma;
3777 tb->buffer_size = got;
FUJITA Tomonoricd816212007-12-15 15:51:55 +09003778 sg_init_table(tb->sg, max_sg);
Linus Torvalds1da177e2005-04-16 15:20:36 -07003779
FUJITA Tomonorid0e1ae32008-12-18 14:49:40 +09003780 tb->reserved_pages = kzalloc(max_sg * sizeof(struct page *), priority);
3781 if (!tb->reserved_pages) {
3782 kfree(tb);
3783 return NULL;
3784 }
3785
Linus Torvalds1da177e2005-04-16 15:20:36 -07003786 return tb;
3787}
3788
3789
3790/* Try to allocate enough space in the tape buffer */
3791static int enlarge_buffer(struct st_buffer * STbuffer, int new_size, int need_dma)
3792{
Al Viroc53033f2005-10-21 03:22:08 -04003793 int segs, nbr, max_segs, b_size, order, got;
3794 gfp_t priority;
Linus Torvalds1da177e2005-04-16 15:20:36 -07003795
3796 if (new_size <= STbuffer->buffer_size)
3797 return 1;
3798
3799 if (STbuffer->buffer_size <= PAGE_SIZE)
3800 normalize_buffer(STbuffer); /* Avoid extra segment */
3801
3802 max_segs = STbuffer->use_sg;
3803 nbr = max_segs - STbuffer->frp_segs;
3804 if (nbr <= 0)
3805 return 0;
3806
3807 priority = GFP_KERNEL | __GFP_NOWARN;
3808 if (need_dma)
3809 priority |= GFP_DMA;
FUJITA Tomonori9c905962008-12-18 14:49:39 +09003810
3811 if (STbuffer->frp_segs) {
3812 b_size = STbuffer->frp[0].length;
3813 order = get_order(b_size);
3814 } else {
3815 for (b_size = PAGE_SIZE, order = 0;
3816 order <= 6 && b_size < new_size; order++, b_size *= 2)
3817 ; /* empty */
3818 }
Linus Torvalds1da177e2005-04-16 15:20:36 -07003819
3820 for (segs = STbuffer->frp_segs, got = STbuffer->buffer_size;
3821 segs < max_segs && got < new_size;) {
3822 STbuffer->frp[segs].page = alloc_pages(priority, order);
3823 if (STbuffer->frp[segs].page == NULL) {
Linus Torvalds1da177e2005-04-16 15:20:36 -07003824 DEB(STbuffer->buffer_size = got);
3825 normalize_buffer(STbuffer);
3826 return 0;
3827 }
3828 STbuffer->frp[segs].length = b_size;
3829 STbuffer->frp_segs += 1;
3830 got += b_size;
3831 STbuffer->buffer_size = got;
Kai Makisara40f6b362008-02-24 22:23:24 +02003832 if (STbuffer->cleared)
3833 memset(page_address(STbuffer->frp[segs].page), 0, b_size);
FUJITA Tomonorid0e1ae32008-12-18 14:49:40 +09003834 STbuffer->reserved_pages[segs] = STbuffer->frp[segs].page;
Linus Torvalds1da177e2005-04-16 15:20:36 -07003835 segs++;
3836 }
3837 STbuffer->b_data = page_address(STbuffer->frp[0].page);
FUJITA Tomonorid0e1ae32008-12-18 14:49:40 +09003838 STbuffer->map_data.page_order = order;
Linus Torvalds1da177e2005-04-16 15:20:36 -07003839
3840 return 1;
3841}
3842
3843
Kai Makisara40f6b362008-02-24 22:23:24 +02003844/* Make sure that no data from previous user is in the internal buffer */
3845static void clear_buffer(struct st_buffer * st_bp)
3846{
3847 int i;
3848
3849 for (i=0; i < st_bp->frp_segs; i++)
3850 memset(page_address(st_bp->frp[i].page), 0, st_bp->frp[i].length);
3851 st_bp->cleared = 1;
3852}
3853
3854
Linus Torvalds1da177e2005-04-16 15:20:36 -07003855/* Release the extra buffer */
3856static void normalize_buffer(struct st_buffer * STbuffer)
3857{
3858 int i, order;
3859
3860 for (i = STbuffer->orig_frp_segs; i < STbuffer->frp_segs; i++) {
3861 order = get_order(STbuffer->frp[i].length);
3862 __free_pages(STbuffer->frp[i].page, order);
3863 STbuffer->buffer_size -= STbuffer->frp[i].length;
3864 }
3865 STbuffer->frp_segs = STbuffer->orig_frp_segs;
3866 STbuffer->frp_sg_current = 0;
Mike Christie8b05b772005-11-08 04:06:44 -06003867 STbuffer->sg_segs = 0;
FUJITA Tomonorid0e1ae32008-12-18 14:49:40 +09003868 STbuffer->map_data.page_order = 0;
3869 STbuffer->map_data.offset = 0;
Linus Torvalds1da177e2005-04-16 15:20:36 -07003870}
3871
3872
3873/* Move data from the user buffer to the tape buffer. Returns zero (success) or
3874 negative error code. */
3875static int append_to_buffer(const char __user *ubp, struct st_buffer * st_bp, int do_count)
3876{
3877 int i, cnt, res, offset;
3878
3879 for (i = 0, offset = st_bp->buffer_bytes;
3880 i < st_bp->frp_segs && offset >= st_bp->frp[i].length; i++)
3881 offset -= st_bp->frp[i].length;
3882 if (i == st_bp->frp_segs) { /* Should never happen */
3883 printk(KERN_WARNING "st: append_to_buffer offset overflow.\n");
3884 return (-EIO);
3885 }
3886 for (; i < st_bp->frp_segs && do_count > 0; i++) {
3887 cnt = st_bp->frp[i].length - offset < do_count ?
3888 st_bp->frp[i].length - offset : do_count;
3889 res = copy_from_user(page_address(st_bp->frp[i].page) + offset, ubp, cnt);
3890 if (res)
3891 return (-EFAULT);
3892 do_count -= cnt;
3893 st_bp->buffer_bytes += cnt;
3894 ubp += cnt;
3895 offset = 0;
3896 }
3897 if (do_count) /* Should never happen */
3898 return (-EIO);
3899
3900 return 0;
3901}
3902
3903
3904/* Move data from the tape buffer to the user buffer. Returns zero (success) or
3905 negative error code. */
3906static int from_buffer(struct st_buffer * st_bp, char __user *ubp, int do_count)
3907{
3908 int i, cnt, res, offset;
3909
3910 for (i = 0, offset = st_bp->read_pointer;
3911 i < st_bp->frp_segs && offset >= st_bp->frp[i].length; i++)
3912 offset -= st_bp->frp[i].length;
3913 if (i == st_bp->frp_segs) { /* Should never happen */
3914 printk(KERN_WARNING "st: from_buffer offset overflow.\n");
3915 return (-EIO);
3916 }
3917 for (; i < st_bp->frp_segs && do_count > 0; i++) {
3918 cnt = st_bp->frp[i].length - offset < do_count ?
3919 st_bp->frp[i].length - offset : do_count;
3920 res = copy_to_user(ubp, page_address(st_bp->frp[i].page) + offset, cnt);
3921 if (res)
3922 return (-EFAULT);
3923 do_count -= cnt;
3924 st_bp->buffer_bytes -= cnt;
3925 st_bp->read_pointer += cnt;
3926 ubp += cnt;
3927 offset = 0;
3928 }
3929 if (do_count) /* Should never happen */
3930 return (-EIO);
3931
3932 return 0;
3933}
3934
3935
3936/* Move data towards start of buffer */
3937static void move_buffer_data(struct st_buffer * st_bp, int offset)
3938{
3939 int src_seg, dst_seg, src_offset = 0, dst_offset;
3940 int count, total;
3941
3942 if (offset == 0)
3943 return;
3944
3945 total=st_bp->buffer_bytes - offset;
3946 for (src_seg=0; src_seg < st_bp->frp_segs; src_seg++) {
3947 src_offset = offset;
3948 if (src_offset < st_bp->frp[src_seg].length)
3949 break;
3950 offset -= st_bp->frp[src_seg].length;
3951 }
3952
3953 st_bp->buffer_bytes = st_bp->read_pointer = total;
3954 for (dst_seg=dst_offset=0; total > 0; ) {
3955 count = min(st_bp->frp[dst_seg].length - dst_offset,
3956 st_bp->frp[src_seg].length - src_offset);
3957 memmove(page_address(st_bp->frp[dst_seg].page) + dst_offset,
3958 page_address(st_bp->frp[src_seg].page) + src_offset, count);
3959 src_offset += count;
3960 if (src_offset >= st_bp->frp[src_seg].length) {
3961 src_seg++;
3962 src_offset = 0;
3963 }
3964 dst_offset += count;
3965 if (dst_offset >= st_bp->frp[dst_seg].length) {
3966 dst_seg++;
3967 dst_offset = 0;
3968 }
3969 total -= count;
3970 }
3971}
3972
3973
3974/* Fill the s/g list up to the length required for this transfer */
3975static void buf_to_sg(struct st_buffer *STbp, unsigned int length)
3976{
3977 int i;
3978 unsigned int count;
3979 struct scatterlist *sg;
3980 struct st_buf_fragment *frp;
3981
3982 if (length == STbp->frp_sg_current)
3983 return; /* work already done */
3984
3985 sg = &(STbp->sg[0]);
3986 frp = STbp->frp;
3987 for (i=count=0; count < length; i++) {
Linus Torvalds1da177e2005-04-16 15:20:36 -07003988 if (length - count > frp[i].length)
Jens Axboe642f1492007-10-24 11:20:47 +02003989 sg_set_page(&sg[i], frp[i].page, frp[i].length, 0);
Linus Torvalds1da177e2005-04-16 15:20:36 -07003990 else
Jens Axboe642f1492007-10-24 11:20:47 +02003991 sg_set_page(&sg[i], frp[i].page, length - count, 0);
Linus Torvalds1da177e2005-04-16 15:20:36 -07003992 count += sg[i].length;
Linus Torvalds1da177e2005-04-16 15:20:36 -07003993 }
3994 STbp->sg_segs = i;
3995 STbp->frp_sg_current = length;
3996}
3997
3998
3999/* Validate the options from command line or module parameters */
4000static void validate_options(void)
4001{
4002 if (buffer_kbs > 0)
4003 st_fixed_buffer_size = buffer_kbs * ST_KILOBYTE;
4004 if (max_sg_segs >= ST_FIRST_SG)
4005 st_max_sg_segs = max_sg_segs;
4006}
4007
4008#ifndef MODULE
4009/* Set the boot options. Syntax is defined in Documenation/scsi/st.txt.
4010 */
4011static int __init st_setup(char *str)
4012{
4013 int i, len, ints[5];
4014 char *stp;
4015
4016 stp = get_options(str, ARRAY_SIZE(ints), ints);
4017
4018 if (ints[0] > 0) {
4019 for (i = 0; i < ints[0] && i < ARRAY_SIZE(parms); i++)
4020 if (parms[i].val)
4021 *parms[i].val = ints[i + 1];
4022 } else {
4023 while (stp != NULL) {
4024 for (i = 0; i < ARRAY_SIZE(parms); i++) {
4025 len = strlen(parms[i].name);
4026 if (!strncmp(stp, parms[i].name, len) &&
4027 (*(stp + len) == ':' || *(stp + len) == '=')) {
4028 if (parms[i].val)
4029 *parms[i].val =
4030 simple_strtoul(stp + len + 1, NULL, 0);
4031 else
4032 printk(KERN_WARNING "st: Obsolete parameter %s\n",
4033 parms[i].name);
4034 break;
4035 }
4036 }
Tobias Klauser6391a112006-06-08 22:23:48 -07004037 if (i >= ARRAY_SIZE(parms))
Linus Torvalds1da177e2005-04-16 15:20:36 -07004038 printk(KERN_WARNING "st: invalid parameter in '%s'\n",
4039 stp);
4040 stp = strchr(stp, ',');
4041 if (stp)
4042 stp++;
4043 }
4044 }
4045
4046 validate_options();
4047
4048 return 1;
4049}
4050
4051__setup("st=", st_setup);
4052
4053#endif
4054
Arjan van de Ven00977a52007-02-12 00:55:34 -08004055static const struct file_operations st_fops =
Linus Torvalds1da177e2005-04-16 15:20:36 -07004056{
4057 .owner = THIS_MODULE,
4058 .read = st_read,
4059 .write = st_write,
Kai Makisarafd66c1b2008-01-17 22:45:22 +02004060 .unlocked_ioctl = st_ioctl,
Linus Torvalds1da177e2005-04-16 15:20:36 -07004061#ifdef CONFIG_COMPAT
4062 .compat_ioctl = st_compat_ioctl,
4063#endif
4064 .open = st_open,
4065 .flush = st_flush,
4066 .release = st_release,
4067};
4068
4069static int st_probe(struct device *dev)
4070{
4071 struct scsi_device *SDp = to_scsi_device(dev);
4072 struct gendisk *disk = NULL;
4073 struct cdev *cdev = NULL;
4074 struct scsi_tape *tpnt = NULL;
4075 struct st_modedef *STm;
4076 struct st_partstat *STps;
4077 struct st_buffer *buffer;
4078 int i, j, mode, dev_num, error;
4079 char *stp;
Linus Torvalds1da177e2005-04-16 15:20:36 -07004080
4081 if (SDp->type != TYPE_TAPE)
4082 return -ENODEV;
4083 if ((stp = st_incompatible(SDp))) {
Jeff Garzik3bf743e2005-10-24 18:04:06 -04004084 sdev_printk(KERN_INFO, SDp, "Found incompatible tape\n");
Linus Torvalds1da177e2005-04-16 15:20:36 -07004085 printk(KERN_INFO "st: The suggested driver is %s.\n", stp);
4086 return -ENODEV;
4087 }
4088
Mike Christie8b05b772005-11-08 04:06:44 -06004089 i = min(SDp->request_queue->max_hw_segments,
4090 SDp->request_queue->max_phys_segments);
Linus Torvalds1da177e2005-04-16 15:20:36 -07004091 if (st_max_sg_segs < i)
4092 i = st_max_sg_segs;
4093 buffer = new_tape_buffer(1, (SDp->host)->unchecked_isa_dma, i);
4094 if (buffer == NULL) {
4095 printk(KERN_ERR
4096 "st: Can't allocate new tape buffer. Device not attached.\n");
4097 goto out;
4098 }
4099
4100 disk = alloc_disk(1);
4101 if (!disk) {
4102 printk(KERN_ERR "st: out of memory. Device not attached.\n");
4103 goto out_buffer_free;
4104 }
4105
4106 write_lock(&st_dev_arr_lock);
4107 if (st_nr_dev >= st_dev_max) {
4108 struct scsi_tape **tmp_da;
4109 int tmp_dev_max;
4110
4111 tmp_dev_max = max(st_nr_dev * 2, 8);
4112 if (tmp_dev_max > ST_MAX_TAPES)
4113 tmp_dev_max = ST_MAX_TAPES;
4114 if (tmp_dev_max <= st_nr_dev) {
4115 write_unlock(&st_dev_arr_lock);
4116 printk(KERN_ERR "st: Too many tape devices (max. %d).\n",
4117 ST_MAX_TAPES);
4118 goto out_put_disk;
4119 }
4120
Jes Sorensen24669f752006-01-16 10:31:18 -05004121 tmp_da = kzalloc(tmp_dev_max * sizeof(struct scsi_tape *), GFP_ATOMIC);
Linus Torvalds1da177e2005-04-16 15:20:36 -07004122 if (tmp_da == NULL) {
4123 write_unlock(&st_dev_arr_lock);
4124 printk(KERN_ERR "st: Can't extend device array.\n");
4125 goto out_put_disk;
4126 }
4127
Linus Torvalds1da177e2005-04-16 15:20:36 -07004128 if (scsi_tapes != NULL) {
4129 memcpy(tmp_da, scsi_tapes,
4130 st_dev_max * sizeof(struct scsi_tape *));
4131 kfree(scsi_tapes);
4132 }
4133 scsi_tapes = tmp_da;
4134
4135 st_dev_max = tmp_dev_max;
4136 }
4137
4138 for (i = 0; i < st_dev_max; i++)
4139 if (scsi_tapes[i] == NULL)
4140 break;
4141 if (i >= st_dev_max)
4142 panic("scsi_devices corrupt (st)");
4143
Jes Sorensen24669f752006-01-16 10:31:18 -05004144 tpnt = kzalloc(sizeof(struct scsi_tape), GFP_ATOMIC);
Linus Torvalds1da177e2005-04-16 15:20:36 -07004145 if (tpnt == NULL) {
4146 write_unlock(&st_dev_arr_lock);
4147 printk(KERN_ERR "st: Can't allocate device descriptor.\n");
4148 goto out_put_disk;
4149 }
Kai Makisaraf03a5672005-08-02 13:40:47 +03004150 kref_init(&tpnt->kref);
Linus Torvalds1da177e2005-04-16 15:20:36 -07004151 tpnt->disk = disk;
4152 sprintf(disk->disk_name, "st%d", i);
4153 disk->private_data = &tpnt->driver;
4154 disk->queue = SDp->request_queue;
4155 tpnt->driver = &st_template;
4156 scsi_tapes[i] = tpnt;
4157 dev_num = i;
4158
4159 tpnt->device = SDp;
4160 if (SDp->scsi_level <= 2)
4161 tpnt->tape_type = MT_ISSCSI1;
4162 else
4163 tpnt->tape_type = MT_ISSCSI2;
4164
4165 tpnt->buffer = buffer;
Kai Makisaraf03a5672005-08-02 13:40:47 +03004166 tpnt->buffer->last_SRpnt = NULL;
Linus Torvalds1da177e2005-04-16 15:20:36 -07004167
4168 tpnt->inited = 0;
4169 tpnt->dirty = 0;
4170 tpnt->in_use = 0;
4171 tpnt->drv_buffer = 1; /* Try buffering if no mode sense */
4172 tpnt->restr_dma = (SDp->host)->unchecked_isa_dma;
4173 tpnt->use_pf = (SDp->scsi_level >= SCSI_2);
4174 tpnt->density = 0;
4175 tpnt->do_auto_lock = ST_AUTO_LOCK;
4176 tpnt->can_bsr = (SDp->scsi_level > 2 ? 1 : ST_IN_FILE_POS); /* BSR mandatory in SCSI3 */
4177 tpnt->can_partitions = 0;
4178 tpnt->two_fm = ST_TWO_FM;
4179 tpnt->fast_mteom = ST_FAST_MTEOM;
4180 tpnt->scsi2_logical = ST_SCSI2LOGICAL;
Kai Makisara40f6b362008-02-24 22:23:24 +02004181 tpnt->sili = ST_SILI;
Linus Torvalds1da177e2005-04-16 15:20:36 -07004182 tpnt->immediate = ST_NOWAIT;
4183 tpnt->default_drvbuffer = 0xff; /* No forced buffering */
4184 tpnt->partition = 0;
4185 tpnt->new_partition = 0;
4186 tpnt->nbr_partitions = 0;
James Bottomleya02488e2008-11-30 10:36:26 -06004187 blk_queue_rq_timeout(tpnt->device->request_queue, ST_TIMEOUT);
Linus Torvalds1da177e2005-04-16 15:20:36 -07004188 tpnt->long_timeout = ST_LONG_TIMEOUT;
4189 tpnt->try_dio = try_direct_io && !SDp->host->unchecked_isa_dma;
4190
Linus Torvalds1da177e2005-04-16 15:20:36 -07004191 for (i = 0; i < ST_NBR_MODES; i++) {
4192 STm = &(tpnt->modes[i]);
4193 STm->defined = 0;
4194 STm->sysv = ST_SYSV;
4195 STm->defaults_for_writes = 0;
4196 STm->do_async_writes = ST_ASYNC_WRITES;
4197 STm->do_buffer_writes = ST_BUFFER_WRITES;
4198 STm->do_read_ahead = ST_READ_AHEAD;
4199 STm->default_compression = ST_DONT_TOUCH;
4200 STm->default_blksize = (-1); /* No forced size */
4201 STm->default_density = (-1); /* No forced density */
4202 }
4203
4204 for (i = 0; i < ST_NBR_PARTITIONS; i++) {
4205 STps = &(tpnt->ps[i]);
4206 STps->rw = ST_IDLE;
4207 STps->eof = ST_NOEOF;
4208 STps->at_sm = 0;
4209 STps->last_block_valid = 0;
4210 STps->drv_block = (-1);
4211 STps->drv_file = (-1);
4212 }
4213
4214 tpnt->current_mode = 0;
4215 tpnt->modes[0].defined = 1;
4216
4217 tpnt->density_changed = tpnt->compression_changed =
4218 tpnt->blksize_changed = 0;
Matthias Kaehlcke28f85002007-07-29 23:38:15 +02004219 mutex_init(&tpnt->lock);
Linus Torvalds1da177e2005-04-16 15:20:36 -07004220
4221 st_nr_dev++;
4222 write_unlock(&st_dev_arr_lock);
4223
4224 for (mode = 0; mode < ST_NBR_MODES; ++mode) {
4225 STm = &(tpnt->modes[mode]);
4226 for (j=0; j < 2; j++) {
4227 cdev = cdev_alloc();
4228 if (!cdev) {
4229 printk(KERN_ERR
4230 "st%d: out of memory. Device not attached.\n",
4231 dev_num);
4232 goto out_free_tape;
4233 }
4234 cdev->owner = THIS_MODULE;
4235 cdev->ops = &st_fops;
4236
4237 error = cdev_add(cdev,
4238 MKDEV(SCSI_TAPE_MAJOR, TAPE_MINOR(dev_num, mode, j)),
4239 1);
4240 if (error) {
4241 printk(KERN_ERR "st%d: Can't add %s-rewind mode %d\n",
4242 dev_num, j ? "non" : "auto", mode);
4243 printk(KERN_ERR "st%d: Device not attached.\n", dev_num);
4244 goto out_free_tape;
4245 }
4246 STm->cdevs[j] = cdev;
4247
4248 }
Jeff Garzik13026a62006-10-04 06:00:38 -04004249 error = do_create_class_files(tpnt, dev_num, mode);
4250 if (error)
4251 goto out_free_tape;
Linus Torvalds1da177e2005-04-16 15:20:36 -07004252 }
4253
Kai Makisara42252852006-11-07 21:56:38 +02004254 sdev_printk(KERN_NOTICE, SDp,
Rene Herman8b1ea242006-05-20 15:00:22 -07004255 "Attached scsi tape %s\n", tape_name(tpnt));
Kai Makisara42252852006-11-07 21:56:38 +02004256 sdev_printk(KERN_INFO, SDp, "%s: try direct i/o: %s (alignment %d B)\n",
4257 tape_name(tpnt), tpnt->try_dio ? "yes" : "no",
4258 queue_dma_alignment(SDp->request_queue) + 1);
Linus Torvalds1da177e2005-04-16 15:20:36 -07004259
4260 return 0;
4261
4262out_free_tape:
4263 for (mode=0; mode < ST_NBR_MODES; mode++) {
4264 STm = &(tpnt->modes[mode]);
4265 sysfs_remove_link(&tpnt->device->sdev_gendev.kobj,
4266 "tape");
4267 for (j=0; j < 2; j++) {
4268 if (STm->cdevs[j]) {
4269 if (cdev == STm->cdevs[j])
4270 cdev = NULL;
Tony Jonesee959b02008-02-22 00:13:36 +01004271 device_destroy(st_sysfs_class,
4272 MKDEV(SCSI_TAPE_MAJOR,
4273 TAPE_MINOR(i, mode, j)));
Linus Torvalds1da177e2005-04-16 15:20:36 -07004274 cdev_del(STm->cdevs[j]);
4275 }
4276 }
4277 }
4278 if (cdev)
4279 cdev_del(cdev);
4280 write_lock(&st_dev_arr_lock);
4281 scsi_tapes[dev_num] = NULL;
4282 st_nr_dev--;
4283 write_unlock(&st_dev_arr_lock);
4284out_put_disk:
4285 put_disk(disk);
Jesper Juhlc9475cb2005-11-07 01:01:26 -08004286 kfree(tpnt);
Linus Torvalds1da177e2005-04-16 15:20:36 -07004287out_buffer_free:
4288 kfree(buffer);
4289out:
4290 return -ENODEV;
4291};
4292
4293
4294static int st_remove(struct device *dev)
4295{
4296 struct scsi_device *SDp = to_scsi_device(dev);
4297 struct scsi_tape *tpnt;
4298 int i, j, mode;
4299
4300 write_lock(&st_dev_arr_lock);
4301 for (i = 0; i < st_dev_max; i++) {
4302 tpnt = scsi_tapes[i];
4303 if (tpnt != NULL && tpnt->device == SDp) {
4304 scsi_tapes[i] = NULL;
4305 st_nr_dev--;
4306 write_unlock(&st_dev_arr_lock);
Linus Torvalds1da177e2005-04-16 15:20:36 -07004307 sysfs_remove_link(&tpnt->device->sdev_gendev.kobj,
4308 "tape");
4309 for (mode = 0; mode < ST_NBR_MODES; ++mode) {
Linus Torvalds1da177e2005-04-16 15:20:36 -07004310 for (j=0; j < 2; j++) {
Tony Jonesee959b02008-02-22 00:13:36 +01004311 device_destroy(st_sysfs_class,
4312 MKDEV(SCSI_TAPE_MAJOR,
4313 TAPE_MINOR(i, mode, j)));
Linus Torvalds1da177e2005-04-16 15:20:36 -07004314 cdev_del(tpnt->modes[mode].cdevs[j]);
4315 tpnt->modes[mode].cdevs[j] = NULL;
4316 }
4317 }
Linus Torvalds1da177e2005-04-16 15:20:36 -07004318
Arjan van de Ven0b950672006-01-11 13:16:10 +01004319 mutex_lock(&st_ref_mutex);
Kai Makisaraf03a5672005-08-02 13:40:47 +03004320 kref_put(&tpnt->kref, scsi_tape_release);
Arjan van de Ven0b950672006-01-11 13:16:10 +01004321 mutex_unlock(&st_ref_mutex);
Linus Torvalds1da177e2005-04-16 15:20:36 -07004322 return 0;
4323 }
4324 }
4325
4326 write_unlock(&st_dev_arr_lock);
4327 return 0;
4328}
4329
Kai Makisaraf03a5672005-08-02 13:40:47 +03004330/**
4331 * scsi_tape_release - Called to free the Scsi_Tape structure
4332 * @kref: pointer to embedded kref
4333 *
Arjan van de Ven0b950672006-01-11 13:16:10 +01004334 * st_ref_mutex must be held entering this routine. Because it is
Kai Makisaraf03a5672005-08-02 13:40:47 +03004335 * called on last put, you should always use the scsi_tape_get()
4336 * scsi_tape_put() helpers which manipulate the semaphore directly
4337 * and never do a direct kref_put().
4338 **/
4339static void scsi_tape_release(struct kref *kref)
4340{
4341 struct scsi_tape *tpnt = to_scsi_tape(kref);
4342 struct gendisk *disk = tpnt->disk;
4343
4344 tpnt->device = NULL;
4345
4346 if (tpnt->buffer) {
4347 tpnt->buffer->orig_frp_segs = 0;
4348 normalize_buffer(tpnt->buffer);
FUJITA Tomonorid0e1ae32008-12-18 14:49:40 +09004349 kfree(tpnt->buffer->reserved_pages);
Kai Makisaraf03a5672005-08-02 13:40:47 +03004350 kfree(tpnt->buffer);
4351 }
4352
4353 disk->private_data = NULL;
4354 put_disk(disk);
4355 kfree(tpnt);
4356 return;
4357}
4358
Linus Torvalds1da177e2005-04-16 15:20:36 -07004359static int __init init_st(void)
4360{
Jeff Garzik13026a62006-10-04 06:00:38 -04004361 int err;
4362
Linus Torvalds1da177e2005-04-16 15:20:36 -07004363 validate_options();
4364
Jeff Garzik13026a62006-10-04 06:00:38 -04004365 printk(KERN_INFO "st: Version %s, fixed bufsize %d, s/g segs %d\n",
Linus Torvalds1da177e2005-04-16 15:20:36 -07004366 verstr, st_fixed_buffer_size, st_max_sg_segs);
4367
gregkh@suse.ded2538782005-03-23 09:55:22 -08004368 st_sysfs_class = class_create(THIS_MODULE, "scsi_tape");
Linus Torvalds1da177e2005-04-16 15:20:36 -07004369 if (IS_ERR(st_sysfs_class)) {
Linus Torvalds1da177e2005-04-16 15:20:36 -07004370 printk(KERN_ERR "Unable create sysfs class for SCSI tapes\n");
Jeff Garzik13026a62006-10-04 06:00:38 -04004371 return PTR_ERR(st_sysfs_class);
Linus Torvalds1da177e2005-04-16 15:20:36 -07004372 }
4373
Jeff Garzik13026a62006-10-04 06:00:38 -04004374 err = register_chrdev_region(MKDEV(SCSI_TAPE_MAJOR, 0),
4375 ST_MAX_TAPE_ENTRIES, "st");
4376 if (err) {
4377 printk(KERN_ERR "Unable to get major %d for SCSI tapes\n",
4378 SCSI_TAPE_MAJOR);
4379 goto err_class;
Linus Torvalds1da177e2005-04-16 15:20:36 -07004380 }
Jeff Garzik13026a62006-10-04 06:00:38 -04004381
4382 err = scsi_register_driver(&st_template.gendrv);
4383 if (err)
4384 goto err_chrdev;
4385
Robert P. J. Day405ae7d2007-02-17 19:13:42 +01004386 err = do_create_sysfs_files();
Jeff Garzik13026a62006-10-04 06:00:38 -04004387 if (err)
4388 goto err_scsidrv;
4389
4390 return 0;
4391
4392err_scsidrv:
4393 scsi_unregister_driver(&st_template.gendrv);
4394err_chrdev:
4395 unregister_chrdev_region(MKDEV(SCSI_TAPE_MAJOR, 0),
4396 ST_MAX_TAPE_ENTRIES);
4397err_class:
Kai Makisarac2c96f42005-08-02 12:21:51 +03004398 class_destroy(st_sysfs_class);
Jeff Garzik13026a62006-10-04 06:00:38 -04004399 return err;
Linus Torvalds1da177e2005-04-16 15:20:36 -07004400}
4401
4402static void __exit exit_st(void)
4403{
Robert P. J. Day405ae7d2007-02-17 19:13:42 +01004404 do_remove_sysfs_files();
Linus Torvalds1da177e2005-04-16 15:20:36 -07004405 scsi_unregister_driver(&st_template.gendrv);
4406 unregister_chrdev_region(MKDEV(SCSI_TAPE_MAJOR, 0),
4407 ST_MAX_TAPE_ENTRIES);
Kai Makisarac2c96f42005-08-02 12:21:51 +03004408 class_destroy(st_sysfs_class);
Linus Torvalds1da177e2005-04-16 15:20:36 -07004409 kfree(scsi_tapes);
4410 printk(KERN_INFO "st: Unloaded.\n");
4411}
4412
4413module_init(init_st);
4414module_exit(exit_st);
4415
4416
4417/* The sysfs driver interface. Read-only at the moment */
4418static ssize_t st_try_direct_io_show(struct device_driver *ddp, char *buf)
4419{
4420 return snprintf(buf, PAGE_SIZE, "%d\n", try_direct_io);
4421}
4422static DRIVER_ATTR(try_direct_io, S_IRUGO, st_try_direct_io_show, NULL);
4423
4424static ssize_t st_fixed_buffer_size_show(struct device_driver *ddp, char *buf)
4425{
4426 return snprintf(buf, PAGE_SIZE, "%d\n", st_fixed_buffer_size);
4427}
4428static DRIVER_ATTR(fixed_buffer_size, S_IRUGO, st_fixed_buffer_size_show, NULL);
4429
4430static ssize_t st_max_sg_segs_show(struct device_driver *ddp, char *buf)
4431{
4432 return snprintf(buf, PAGE_SIZE, "%d\n", st_max_sg_segs);
4433}
4434static DRIVER_ATTR(max_sg_segs, S_IRUGO, st_max_sg_segs_show, NULL);
4435
4436static ssize_t st_version_show(struct device_driver *ddd, char *buf)
4437{
4438 return snprintf(buf, PAGE_SIZE, "[%s]\n", verstr);
4439}
4440static DRIVER_ATTR(version, S_IRUGO, st_version_show, NULL);
4441
Robert P. J. Day405ae7d2007-02-17 19:13:42 +01004442static int do_create_sysfs_files(void)
Linus Torvalds1da177e2005-04-16 15:20:36 -07004443{
Robert P. J. Day405ae7d2007-02-17 19:13:42 +01004444 struct device_driver *sysfs = &st_template.gendrv;
Jeff Garzik13026a62006-10-04 06:00:38 -04004445 int err;
Linus Torvalds1da177e2005-04-16 15:20:36 -07004446
Robert P. J. Day405ae7d2007-02-17 19:13:42 +01004447 err = driver_create_file(sysfs, &driver_attr_try_direct_io);
Jeff Garzik13026a62006-10-04 06:00:38 -04004448 if (err)
4449 return err;
Robert P. J. Day405ae7d2007-02-17 19:13:42 +01004450 err = driver_create_file(sysfs, &driver_attr_fixed_buffer_size);
Jeff Garzik13026a62006-10-04 06:00:38 -04004451 if (err)
4452 goto err_try_direct_io;
Robert P. J. Day405ae7d2007-02-17 19:13:42 +01004453 err = driver_create_file(sysfs, &driver_attr_max_sg_segs);
Jeff Garzik13026a62006-10-04 06:00:38 -04004454 if (err)
4455 goto err_attr_fixed_buf;
Robert P. J. Day405ae7d2007-02-17 19:13:42 +01004456 err = driver_create_file(sysfs, &driver_attr_version);
Jeff Garzik13026a62006-10-04 06:00:38 -04004457 if (err)
4458 goto err_attr_max_sg;
4459
4460 return 0;
4461
4462err_attr_max_sg:
Robert P. J. Day405ae7d2007-02-17 19:13:42 +01004463 driver_remove_file(sysfs, &driver_attr_max_sg_segs);
Jeff Garzik13026a62006-10-04 06:00:38 -04004464err_attr_fixed_buf:
Robert P. J. Day405ae7d2007-02-17 19:13:42 +01004465 driver_remove_file(sysfs, &driver_attr_fixed_buffer_size);
Jeff Garzik13026a62006-10-04 06:00:38 -04004466err_try_direct_io:
Robert P. J. Day405ae7d2007-02-17 19:13:42 +01004467 driver_remove_file(sysfs, &driver_attr_try_direct_io);
Jeff Garzik13026a62006-10-04 06:00:38 -04004468 return err;
Linus Torvalds1da177e2005-04-16 15:20:36 -07004469}
4470
Robert P. J. Day405ae7d2007-02-17 19:13:42 +01004471static void do_remove_sysfs_files(void)
Linus Torvalds1da177e2005-04-16 15:20:36 -07004472{
Robert P. J. Day405ae7d2007-02-17 19:13:42 +01004473 struct device_driver *sysfs = &st_template.gendrv;
Linus Torvalds1da177e2005-04-16 15:20:36 -07004474
Robert P. J. Day405ae7d2007-02-17 19:13:42 +01004475 driver_remove_file(sysfs, &driver_attr_version);
4476 driver_remove_file(sysfs, &driver_attr_max_sg_segs);
4477 driver_remove_file(sysfs, &driver_attr_fixed_buffer_size);
4478 driver_remove_file(sysfs, &driver_attr_try_direct_io);
Linus Torvalds1da177e2005-04-16 15:20:36 -07004479}
4480
4481
4482/* The sysfs simple class interface */
Tony Jonesee959b02008-02-22 00:13:36 +01004483static ssize_t
4484st_defined_show(struct device *dev, struct device_attribute *attr, char *buf)
Linus Torvalds1da177e2005-04-16 15:20:36 -07004485{
James Bottomley7d15d6a2008-03-14 14:12:43 -07004486 struct st_modedef *STm = dev_get_drvdata(dev);
Linus Torvalds1da177e2005-04-16 15:20:36 -07004487 ssize_t l = 0;
4488
4489 l = snprintf(buf, PAGE_SIZE, "%d\n", STm->defined);
4490 return l;
4491}
4492
Tony Jonesee959b02008-02-22 00:13:36 +01004493DEVICE_ATTR(defined, S_IRUGO, st_defined_show, NULL);
Linus Torvalds1da177e2005-04-16 15:20:36 -07004494
Tony Jonesee959b02008-02-22 00:13:36 +01004495static ssize_t
4496st_defblk_show(struct device *dev, struct device_attribute *attr, char *buf)
Linus Torvalds1da177e2005-04-16 15:20:36 -07004497{
James Bottomley7d15d6a2008-03-14 14:12:43 -07004498 struct st_modedef *STm = dev_get_drvdata(dev);
Linus Torvalds1da177e2005-04-16 15:20:36 -07004499 ssize_t l = 0;
4500
4501 l = snprintf(buf, PAGE_SIZE, "%d\n", STm->default_blksize);
4502 return l;
4503}
4504
Tony Jonesee959b02008-02-22 00:13:36 +01004505DEVICE_ATTR(default_blksize, S_IRUGO, st_defblk_show, NULL);
Linus Torvalds1da177e2005-04-16 15:20:36 -07004506
Tony Jonesee959b02008-02-22 00:13:36 +01004507static ssize_t
4508st_defdensity_show(struct device *dev, struct device_attribute *attr, char *buf)
Linus Torvalds1da177e2005-04-16 15:20:36 -07004509{
James Bottomley7d15d6a2008-03-14 14:12:43 -07004510 struct st_modedef *STm = dev_get_drvdata(dev);
Linus Torvalds1da177e2005-04-16 15:20:36 -07004511 ssize_t l = 0;
4512 char *fmt;
4513
4514 fmt = STm->default_density >= 0 ? "0x%02x\n" : "%d\n";
4515 l = snprintf(buf, PAGE_SIZE, fmt, STm->default_density);
4516 return l;
4517}
4518
Tony Jonesee959b02008-02-22 00:13:36 +01004519DEVICE_ATTR(default_density, S_IRUGO, st_defdensity_show, NULL);
Linus Torvalds1da177e2005-04-16 15:20:36 -07004520
Tony Jonesee959b02008-02-22 00:13:36 +01004521static ssize_t
4522st_defcompression_show(struct device *dev, struct device_attribute *attr,
4523 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
4528 l = snprintf(buf, PAGE_SIZE, "%d\n", STm->default_compression - 1);
4529 return l;
4530}
4531
Tony Jonesee959b02008-02-22 00:13:36 +01004532DEVICE_ATTR(default_compression, S_IRUGO, st_defcompression_show, NULL);
Linus Torvalds1da177e2005-04-16 15:20:36 -07004533
Tony Jonesee959b02008-02-22 00:13:36 +01004534static ssize_t
4535st_options_show(struct device *dev, struct device_attribute *attr, char *buf)
Kai Makisarab174be02008-02-24 22:29:12 +02004536{
James Bottomley7d15d6a2008-03-14 14:12:43 -07004537 struct st_modedef *STm = dev_get_drvdata(dev);
Kai Makisarab174be02008-02-24 22:29:12 +02004538 struct scsi_tape *STp;
4539 int i, j, options;
4540 ssize_t l = 0;
4541
4542 for (i=0; i < st_dev_max; i++) {
4543 for (j=0; j < ST_NBR_MODES; j++)
4544 if (&scsi_tapes[i]->modes[j] == STm)
4545 break;
4546 if (j < ST_NBR_MODES)
4547 break;
4548 }
4549 if (i == st_dev_max)
4550 return 0; /* should never happen */
4551
4552 STp = scsi_tapes[i];
4553
4554 options = STm->do_buffer_writes ? MT_ST_BUFFER_WRITES : 0;
4555 options |= STm->do_async_writes ? MT_ST_ASYNC_WRITES : 0;
4556 options |= STm->do_read_ahead ? MT_ST_READ_AHEAD : 0;
4557 DEB( options |= debugging ? MT_ST_DEBUGGING : 0 );
4558 options |= STp->two_fm ? MT_ST_TWO_FM : 0;
4559 options |= STp->fast_mteom ? MT_ST_FAST_MTEOM : 0;
4560 options |= STm->defaults_for_writes ? MT_ST_DEF_WRITES : 0;
4561 options |= STp->can_bsr ? MT_ST_CAN_BSR : 0;
4562 options |= STp->omit_blklims ? MT_ST_NO_BLKLIMS : 0;
4563 options |= STp->can_partitions ? MT_ST_CAN_PARTITIONS : 0;
4564 options |= STp->scsi2_logical ? MT_ST_SCSI2LOGICAL : 0;
4565 options |= STm->sysv ? MT_ST_SYSV : 0;
4566 options |= STp->immediate ? MT_ST_NOWAIT : 0;
4567 options |= STp->sili ? MT_ST_SILI : 0;
4568
4569 l = snprintf(buf, PAGE_SIZE, "0x%08x\n", options);
4570 return l;
4571}
4572
Tony Jonesee959b02008-02-22 00:13:36 +01004573DEVICE_ATTR(options, S_IRUGO, st_options_show, NULL);
Kai Makisarab174be02008-02-24 22:29:12 +02004574
Jeff Garzik13026a62006-10-04 06:00:38 -04004575static int do_create_class_files(struct scsi_tape *STp, int dev_num, int mode)
Linus Torvalds1da177e2005-04-16 15:20:36 -07004576{
4577 int i, rew, error;
4578 char name[10];
Tony Jonesee959b02008-02-22 00:13:36 +01004579 struct device *st_class_member;
Linus Torvalds1da177e2005-04-16 15:20:36 -07004580
Linus Torvalds1da177e2005-04-16 15:20:36 -07004581 for (rew=0; rew < 2; rew++) {
4582 /* Make sure that the minor numbers corresponding to the four
4583 first modes always get the same names */
4584 i = mode << (4 - ST_NBR_MODE_BITS);
4585 snprintf(name, 10, "%s%s%s", rew ? "n" : "",
4586 STp->disk->disk_name, st_formats[i]);
4587 st_class_member =
Greg Kroah-Hartmand73a1a62008-07-21 20:03:34 -07004588 device_create(st_sysfs_class, &STp->device->sdev_gendev,
4589 MKDEV(SCSI_TAPE_MAJOR,
4590 TAPE_MINOR(dev_num, mode, rew)),
4591 &STp->modes[mode], "%s", name);
Linus Torvalds1da177e2005-04-16 15:20:36 -07004592 if (IS_ERR(st_class_member)) {
Tony Jonesee959b02008-02-22 00:13:36 +01004593 printk(KERN_WARNING "st%d: device_create failed\n",
Linus Torvalds1da177e2005-04-16 15:20:36 -07004594 dev_num);
Jeff Garzik13026a62006-10-04 06:00:38 -04004595 error = PTR_ERR(st_class_member);
Linus Torvalds1da177e2005-04-16 15:20:36 -07004596 goto out;
4597 }
Linus Torvalds1da177e2005-04-16 15:20:36 -07004598
Tony Jonesee959b02008-02-22 00:13:36 +01004599 error = device_create_file(st_class_member,
4600 &dev_attr_defined);
Jeff Garzik13026a62006-10-04 06:00:38 -04004601 if (error) goto out;
Tony Jonesee959b02008-02-22 00:13:36 +01004602 error = device_create_file(st_class_member,
4603 &dev_attr_default_blksize);
Jeff Garzik13026a62006-10-04 06:00:38 -04004604 if (error) goto out;
Tony Jonesee959b02008-02-22 00:13:36 +01004605 error = device_create_file(st_class_member,
4606 &dev_attr_default_density);
Jeff Garzik13026a62006-10-04 06:00:38 -04004607 if (error) goto out;
Tony Jonesee959b02008-02-22 00:13:36 +01004608 error = device_create_file(st_class_member,
4609 &dev_attr_default_compression);
Jeff Garzik13026a62006-10-04 06:00:38 -04004610 if (error) goto out;
Tony Jonesee959b02008-02-22 00:13:36 +01004611 error = device_create_file(st_class_member,
4612 &dev_attr_options);
Kai Makisarab174be02008-02-24 22:29:12 +02004613 if (error) goto out;
Jeff Garzik13026a62006-10-04 06:00:38 -04004614
Linus Torvalds1da177e2005-04-16 15:20:36 -07004615 if (mode == 0 && rew == 0) {
4616 error = sysfs_create_link(&STp->device->sdev_gendev.kobj,
4617 &st_class_member->kobj,
4618 "tape");
4619 if (error) {
4620 printk(KERN_ERR
4621 "st%d: Can't create sysfs link from SCSI device.\n",
4622 dev_num);
Jeff Garzik13026a62006-10-04 06:00:38 -04004623 goto out;
Linus Torvalds1da177e2005-04-16 15:20:36 -07004624 }
4625 }
4626 }
Jeff Garzik13026a62006-10-04 06:00:38 -04004627
4628 return 0;
4629
4630out:
4631 return error;
Linus Torvalds1da177e2005-04-16 15:20:36 -07004632}
4633
Linus Torvalds1da177e2005-04-16 15:20:36 -07004634/* The following functions may be useful for a larger audience. */
4635static int sgl_map_user_pages(struct scatterlist *sgl, const unsigned int max_pages,
4636 unsigned long uaddr, size_t count, int rw)
4637{
James Bottomley07542b82005-08-31 20:27:22 -04004638 unsigned long end = (uaddr + count + PAGE_SIZE - 1) >> PAGE_SHIFT;
4639 unsigned long start = uaddr >> PAGE_SHIFT;
4640 const int nr_pages = end - start;
Linus Torvalds1da177e2005-04-16 15:20:36 -07004641 int res, i, j;
Linus Torvalds1da177e2005-04-16 15:20:36 -07004642 struct page **pages;
4643
Linus Torvalds1da177e2005-04-16 15:20:36 -07004644 /* User attempted Overflow! */
4645 if ((uaddr + count) < uaddr)
4646 return -EINVAL;
4647
4648 /* Too big */
4649 if (nr_pages > max_pages)
4650 return -ENOMEM;
4651
4652 /* Hmm? */
4653 if (count == 0)
4654 return 0;
4655
4656 if ((pages = kmalloc(max_pages * sizeof(*pages), GFP_KERNEL)) == NULL)
4657 return -ENOMEM;
4658
4659 /* Try to fault in all of the necessary pages */
4660 down_read(&current->mm->mmap_sem);
4661 /* rw==READ means read from drive, write into memory area */
4662 res = get_user_pages(
4663 current,
4664 current->mm,
4665 uaddr,
4666 nr_pages,
4667 rw == READ,
4668 0, /* don't force */
4669 pages,
4670 NULL);
4671 up_read(&current->mm->mmap_sem);
4672
4673 /* Errors and no page mapped should return here */
4674 if (res < nr_pages)
4675 goto out_unmap;
4676
4677 for (i=0; i < nr_pages; i++) {
4678 /* FIXME: flush superflous for rw==READ,
4679 * probably wrong function for rw==WRITE
4680 */
4681 flush_dcache_page(pages[i]);
4682 }
4683
4684 /* Populate the scatter/gather list */
Jens Axboe642f1492007-10-24 11:20:47 +02004685 sg_set_page(&sgl[0], pages[0], 0, uaddr & ~PAGE_MASK);
Linus Torvalds1da177e2005-04-16 15:20:36 -07004686 if (nr_pages > 1) {
4687 sgl[0].length = PAGE_SIZE - sgl[0].offset;
4688 count -= sgl[0].length;
4689 for (i=1; i < nr_pages ; i++) {
Jens Axboe642f1492007-10-24 11:20:47 +02004690 sg_set_page(&sgl[i], pages[i],
4691 count < PAGE_SIZE ? count : PAGE_SIZE, 0);;
Linus Torvalds1da177e2005-04-16 15:20:36 -07004692 count -= PAGE_SIZE;
4693 }
4694 }
4695 else {
4696 sgl[0].length = count;
4697 }
4698
4699 kfree(pages);
4700 return nr_pages;
4701
4702 out_unmap:
4703 if (res > 0) {
4704 for (j=0; j < res; j++)
4705 page_cache_release(pages[j]);
Hugh Dickins6bc733e2005-12-01 20:21:57 +00004706 res = 0;
Linus Torvalds1da177e2005-04-16 15:20:36 -07004707 }
4708 kfree(pages);
4709 return res;
4710}
4711
4712
4713/* And unmap them... */
4714static int sgl_unmap_user_pages(struct scatterlist *sgl, const unsigned int nr_pages,
4715 int dirtied)
4716{
4717 int i;
4718
4719 for (i=0; i < nr_pages; i++) {
Jens Axboe45711f12007-10-22 21:19:53 +02004720 struct page *page = sg_page(&sgl[i]);
Nick Pigginb5810032005-10-29 18:16:12 -07004721
Nick Pigginb5810032005-10-29 18:16:12 -07004722 if (dirtied)
4723 SetPageDirty(page);
Linus Torvalds1da177e2005-04-16 15:20:36 -07004724 /* FIXME: cache flush missing for rw==READ
4725 * FIXME: call the correct reference counting function
4726 */
Nick Pigginb5810032005-10-29 18:16:12 -07004727 page_cache_release(page);
Linus Torvalds1da177e2005-04-16 15:20:36 -07004728 }
4729
4730 return 0;
4731}