blob: 1cfd217f8904d49e5c516eddb52c2104f41f56ca [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);
Linus Torvalds1da177e2005-04-16 15:20:36 -0700192
FUJITA Tomonori66207422008-12-18 14:49:43 +0900193static int sgl_map_user_pages(struct st_buffer *, const unsigned int,
Linus Torvalds1da177e2005-04-16 15:20:36 -0700194 unsigned long, size_t, int);
FUJITA Tomonori66207422008-12-18 14:49:43 +0900195static int sgl_unmap_user_pages(struct st_buffer *, const unsigned int, int);
Linus Torvalds1da177e2005-04-16 15:20:36 -0700196
197static int st_probe(struct device *);
198static int st_remove(struct device *);
Linus Torvalds1da177e2005-04-16 15:20:36 -0700199
Robert P. J. Day405ae7d2007-02-17 19:13:42 +0100200static int do_create_sysfs_files(void);
201static void do_remove_sysfs_files(void);
Jeff Garzik13026a62006-10-04 06:00:38 -0400202static int do_create_class_files(struct scsi_tape *, int, int);
Linus Torvalds1da177e2005-04-16 15:20:36 -0700203
204static struct scsi_driver st_template = {
205 .owner = THIS_MODULE,
206 .gendrv = {
207 .name = "st",
208 .probe = st_probe,
209 .remove = st_remove,
210 },
Linus Torvalds1da177e2005-04-16 15:20:36 -0700211};
212
213static int st_compression(struct scsi_tape *, int);
214
215static int find_partition(struct scsi_tape *);
216static int switch_partition(struct scsi_tape *);
217
218static int st_int_ioctl(struct scsi_tape *, unsigned int, unsigned long);
219
Kai Makisaraf03a5672005-08-02 13:40:47 +0300220static void scsi_tape_release(struct kref *);
221
222#define to_scsi_tape(obj) container_of(obj, struct scsi_tape, kref)
223
Arjan van de Ven0b950672006-01-11 13:16:10 +0100224static DEFINE_MUTEX(st_ref_mutex);
Kai Makisaraf03a5672005-08-02 13:40:47 +0300225
Linus Torvalds1da177e2005-04-16 15:20:36 -0700226
227#include "osst_detect.h"
228#ifndef SIGS_FROM_OSST
229#define SIGS_FROM_OSST \
230 {"OnStream", "SC-", "", "osst"}, \
231 {"OnStream", "DI-", "", "osst"}, \
232 {"OnStream", "DP-", "", "osst"}, \
233 {"OnStream", "USB", "", "osst"}, \
234 {"OnStream", "FW-", "", "osst"}
235#endif
236
Kai Makisaraf03a5672005-08-02 13:40:47 +0300237static struct scsi_tape *scsi_tape_get(int dev)
238{
239 struct scsi_tape *STp = NULL;
240
Arjan van de Ven0b950672006-01-11 13:16:10 +0100241 mutex_lock(&st_ref_mutex);
Kai Makisaraf03a5672005-08-02 13:40:47 +0300242 write_lock(&st_dev_arr_lock);
243
244 if (dev < st_dev_max && scsi_tapes != NULL)
245 STp = scsi_tapes[dev];
246 if (!STp) goto out;
247
248 kref_get(&STp->kref);
249
250 if (!STp->device)
251 goto out_put;
252
253 if (scsi_device_get(STp->device))
254 goto out_put;
255
256 goto out;
257
258out_put:
259 kref_put(&STp->kref, scsi_tape_release);
260 STp = NULL;
261out:
262 write_unlock(&st_dev_arr_lock);
Arjan van de Ven0b950672006-01-11 13:16:10 +0100263 mutex_unlock(&st_ref_mutex);
Kai Makisaraf03a5672005-08-02 13:40:47 +0300264 return STp;
265}
266
267static void scsi_tape_put(struct scsi_tape *STp)
268{
269 struct scsi_device *sdev = STp->device;
270
Arjan van de Ven0b950672006-01-11 13:16:10 +0100271 mutex_lock(&st_ref_mutex);
Kai Makisaraf03a5672005-08-02 13:40:47 +0300272 kref_put(&STp->kref, scsi_tape_release);
273 scsi_device_put(sdev);
Arjan van de Ven0b950672006-01-11 13:16:10 +0100274 mutex_unlock(&st_ref_mutex);
Kai Makisaraf03a5672005-08-02 13:40:47 +0300275}
276
Linus Torvalds1da177e2005-04-16 15:20:36 -0700277struct st_reject_data {
278 char *vendor;
279 char *model;
280 char *rev;
281 char *driver_hint; /* Name of the correct driver, NULL if unknown */
282};
283
284static struct st_reject_data reject_list[] = {
285 /* {"XXX", "Yy-", "", NULL}, example */
286 SIGS_FROM_OSST,
287 {NULL, }};
288
289/* If the device signature is on the list of incompatible drives, the
290 function returns a pointer to the name of the correct driver (if known) */
291static char * st_incompatible(struct scsi_device* SDp)
292{
293 struct st_reject_data *rp;
294
295 for (rp=&(reject_list[0]); rp->vendor != NULL; rp++)
296 if (!strncmp(rp->vendor, SDp->vendor, strlen(rp->vendor)) &&
297 !strncmp(rp->model, SDp->model, strlen(rp->model)) &&
298 !strncmp(rp->rev, SDp->rev, strlen(rp->rev))) {
299 if (rp->driver_hint)
300 return rp->driver_hint;
301 else
302 return "unknown";
303 }
304 return NULL;
305}
306
307
308static inline char *tape_name(struct scsi_tape *tape)
309{
310 return tape->disk->disk_name;
311}
312
313
Mike Christie8b05b772005-11-08 04:06:44 -0600314static void st_analyze_sense(struct st_request *SRpnt, struct st_cmdstatus *s)
Linus Torvalds1da177e2005-04-16 15:20:36 -0700315{
316 const u8 *ucp;
Mike Christie8b05b772005-11-08 04:06:44 -0600317 const u8 *sense = SRpnt->sense;
Linus Torvalds1da177e2005-04-16 15:20:36 -0700318
Mike Christie8b05b772005-11-08 04:06:44 -0600319 s->have_sense = scsi_normalize_sense(SRpnt->sense,
320 SCSI_SENSE_BUFFERSIZE, &s->sense_hdr);
Linus Torvalds1da177e2005-04-16 15:20:36 -0700321 s->flags = 0;
322
323 if (s->have_sense) {
324 s->deferred = 0;
325 s->remainder_valid =
326 scsi_get_sense_info_fld(sense, SCSI_SENSE_BUFFERSIZE, &s->uremainder64);
327 switch (sense[0] & 0x7f) {
328 case 0x71:
329 s->deferred = 1;
330 case 0x70:
331 s->fixed_format = 1;
332 s->flags = sense[2] & 0xe0;
333 break;
334 case 0x73:
335 s->deferred = 1;
336 case 0x72:
337 s->fixed_format = 0;
338 ucp = scsi_sense_desc_find(sense, SCSI_SENSE_BUFFERSIZE, 4);
339 s->flags = ucp ? (ucp[3] & 0xe0) : 0;
340 break;
341 }
342 }
343}
344
345
346/* Convert the result to success code */
Mike Christie8b05b772005-11-08 04:06:44 -0600347static int st_chk_result(struct scsi_tape *STp, struct st_request * SRpnt)
Linus Torvalds1da177e2005-04-16 15:20:36 -0700348{
Mike Christie8b05b772005-11-08 04:06:44 -0600349 int result = SRpnt->result;
Linus Torvalds1da177e2005-04-16 15:20:36 -0700350 u8 scode;
351 DEB(const char *stp;)
352 char *name = tape_name(STp);
353 struct st_cmdstatus *cmdstatp;
354
355 if (!result)
356 return 0;
357
358 cmdstatp = &STp->buffer->cmdstat;
Kai Makisaraf03a5672005-08-02 13:40:47 +0300359 st_analyze_sense(SRpnt, cmdstatp);
Linus Torvalds1da177e2005-04-16 15:20:36 -0700360
361 if (cmdstatp->have_sense)
362 scode = STp->buffer->cmdstat.sense_hdr.sense_key;
363 else
364 scode = 0;
365
366 DEB(
367 if (debugging) {
Mike Christie8b05b772005-11-08 04:06:44 -0600368 printk(ST_DEB_MSG "%s: Error: %x, cmd: %x %x %x %x %x %x\n",
Linus Torvalds1da177e2005-04-16 15:20:36 -0700369 name, result,
Mike Christie8b05b772005-11-08 04:06:44 -0600370 SRpnt->cmd[0], SRpnt->cmd[1], SRpnt->cmd[2],
371 SRpnt->cmd[3], SRpnt->cmd[4], SRpnt->cmd[5]);
Linus Torvalds1da177e2005-04-16 15:20:36 -0700372 if (cmdstatp->have_sense)
Luben Tuikov4e73ea72006-07-07 00:02:18 -0700373 __scsi_print_sense(name, SRpnt->sense, SCSI_SENSE_BUFFERSIZE);
Linus Torvalds1da177e2005-04-16 15:20:36 -0700374 } ) /* end DEB */
375 if (!debugging) { /* Abnormal conditions for tape */
376 if (!cmdstatp->have_sense)
377 printk(KERN_WARNING
378 "%s: Error %x (sugg. bt 0x%x, driver bt 0x%x, host bt 0x%x).\n",
379 name, result, suggestion(result),
380 driver_byte(result) & DRIVER_MASK, host_byte(result));
381 else if (cmdstatp->have_sense &&
382 scode != NO_SENSE &&
383 scode != RECOVERED_ERROR &&
384 /* scode != UNIT_ATTENTION && */
385 scode != BLANK_CHECK &&
386 scode != VOLUME_OVERFLOW &&
Mike Christie8b05b772005-11-08 04:06:44 -0600387 SRpnt->cmd[0] != MODE_SENSE &&
388 SRpnt->cmd[0] != TEST_UNIT_READY) {
Luben Tuikov4e73ea72006-07-07 00:02:18 -0700389
390 __scsi_print_sense(name, SRpnt->sense, SCSI_SENSE_BUFFERSIZE);
Linus Torvalds1da177e2005-04-16 15:20:36 -0700391 }
392 }
393
394 if (cmdstatp->fixed_format &&
395 STp->cln_mode >= EXTENDED_SENSE_START) { /* Only fixed format sense */
396 if (STp->cln_sense_value)
Mike Christie8b05b772005-11-08 04:06:44 -0600397 STp->cleaning_req |= ((SRpnt->sense[STp->cln_mode] &
Linus Torvalds1da177e2005-04-16 15:20:36 -0700398 STp->cln_sense_mask) == STp->cln_sense_value);
399 else
Mike Christie8b05b772005-11-08 04:06:44 -0600400 STp->cleaning_req |= ((SRpnt->sense[STp->cln_mode] &
Linus Torvalds1da177e2005-04-16 15:20:36 -0700401 STp->cln_sense_mask) != 0);
402 }
403 if (cmdstatp->have_sense &&
404 cmdstatp->sense_hdr.asc == 0 && cmdstatp->sense_hdr.ascq == 0x17)
405 STp->cleaning_req = 1; /* ASC and ASCQ => cleaning requested */
406
407 STp->pos_unknown |= STp->device->was_reset;
408
409 if (cmdstatp->have_sense &&
410 scode == RECOVERED_ERROR
411#if ST_RECOVERED_WRITE_FATAL
Mike Christie8b05b772005-11-08 04:06:44 -0600412 && SRpnt->cmd[0] != WRITE_6
413 && SRpnt->cmd[0] != WRITE_FILEMARKS
Linus Torvalds1da177e2005-04-16 15:20:36 -0700414#endif
415 ) {
416 STp->recover_count++;
417 STp->recover_reg++;
418
419 DEB(
420 if (debugging) {
Mike Christie8b05b772005-11-08 04:06:44 -0600421 if (SRpnt->cmd[0] == READ_6)
Linus Torvalds1da177e2005-04-16 15:20:36 -0700422 stp = "read";
Mike Christie8b05b772005-11-08 04:06:44 -0600423 else if (SRpnt->cmd[0] == WRITE_6)
Linus Torvalds1da177e2005-04-16 15:20:36 -0700424 stp = "write";
425 else
426 stp = "ioctl";
427 printk(ST_DEB_MSG "%s: Recovered %s error (%d).\n", name, stp,
428 STp->recover_count);
429 } ) /* end DEB */
430
431 if (cmdstatp->flags == 0)
432 return 0;
433 }
434 return (-EIO);
435}
436
FUJITA Tomonori4deba242008-12-05 15:25:20 +0900437static struct st_request *st_allocate_request(struct scsi_tape *stp)
Mike Christie8b05b772005-11-08 04:06:44 -0600438{
FUJITA Tomonori4deba242008-12-05 15:25:20 +0900439 struct st_request *streq;
440
441 streq = kzalloc(sizeof(*streq), GFP_KERNEL);
442 if (streq)
443 streq->stp = stp;
444 else {
445 DEBC(printk(KERN_ERR "%s: Can't get SCSI request.\n",
446 tape_name(stp)););
447 if (signal_pending(current))
448 stp->buffer->syscall_result = -EINTR;
449 else
450 stp->buffer->syscall_result = -EBUSY;
451 }
452
453 return streq;
Mike Christie8b05b772005-11-08 04:06:44 -0600454}
455
456static void st_release_request(struct st_request *streq)
457{
458 kfree(streq);
Linus Torvalds1da177e2005-04-16 15:20:36 -0700459}
460
FUJITA Tomonori13b53b42008-12-18 14:49:41 +0900461static void st_scsi_execute_end(struct request *req, int uptodate)
462{
463 struct st_request *SRpnt = req->end_io_data;
464 struct scsi_tape *STp = SRpnt->stp;
465
466 STp->buffer->cmdstat.midlevel_result = SRpnt->result = req->errors;
467 STp->buffer->cmdstat.residual = req->data_len;
468
469 if (SRpnt->waiting)
470 complete(SRpnt->waiting);
471
472 blk_rq_unmap_user(SRpnt->bio);
473 __blk_put_request(req->q, req);
474}
475
476static int st_scsi_execute(struct st_request *SRpnt, const unsigned char *cmd,
477 int data_direction, void *buffer, unsigned bufflen,
478 int timeout, int retries)
479{
480 struct request *req;
481 struct rq_map_data *mdata = &SRpnt->stp->buffer->map_data;
482 int err = 0;
483 int write = (data_direction == DMA_TO_DEVICE);
484
485 req = blk_get_request(SRpnt->stp->device->request_queue, write,
486 GFP_KERNEL);
487 if (!req)
488 return DRIVER_ERROR << 24;
489
490 req->cmd_type = REQ_TYPE_BLOCK_PC;
491 req->cmd_flags |= REQ_QUIET;
492
493 mdata->null_mapped = 1;
494
495 err = blk_rq_map_user(req->q, req, mdata, NULL, bufflen, GFP_KERNEL);
496 if (err) {
497 blk_put_request(req);
498 return DRIVER_ERROR << 24;
499 }
500
501 SRpnt->bio = req->bio;
502 req->cmd_len = COMMAND_SIZE(cmd[0]);
503 memset(req->cmd, 0, BLK_MAX_CDB);
504 memcpy(req->cmd, cmd, req->cmd_len);
505 req->sense = SRpnt->sense;
506 req->sense_len = 0;
507 req->timeout = timeout;
508 req->retries = retries;
509 req->end_io_data = SRpnt;
510
511 blk_execute_rq_nowait(req->q, NULL, req, 1, st_scsi_execute_end);
512 return 0;
513}
514
Linus Torvalds1da177e2005-04-16 15:20:36 -0700515/* Do the scsi command. Waits until command performed if do_wait is true.
516 Otherwise write_behind_check() is used to check that the command
517 has finished. */
Mike Christie8b05b772005-11-08 04:06:44 -0600518static struct st_request *
519st_do_scsi(struct st_request * SRpnt, struct scsi_tape * STp, unsigned char *cmd,
Linus Torvalds1da177e2005-04-16 15:20:36 -0700520 int bytes, int direction, int timeout, int retries, int do_wait)
521{
Kai Makisaraf03a5672005-08-02 13:40:47 +0300522 struct completion *waiting;
FUJITA Tomonori6d476262008-12-18 14:49:42 +0900523 struct rq_map_data *mdata = &STp->buffer->map_data;
524 int ret;
Linus Torvalds1da177e2005-04-16 15:20:36 -0700525
Kai Makisaraf03a5672005-08-02 13:40:47 +0300526 /* if async, make sure there's no command outstanding */
527 if (!do_wait && ((STp->buffer)->last_SRpnt)) {
528 printk(KERN_ERR "%s: Async command already active.\n",
529 tape_name(STp));
530 if (signal_pending(current))
531 (STp->buffer)->syscall_result = (-EINTR);
532 else
533 (STp->buffer)->syscall_result = (-EBUSY);
534 return NULL;
535 }
536
FUJITA Tomonori4deba242008-12-05 15:25:20 +0900537 if (!SRpnt) {
538 SRpnt = st_allocate_request(STp);
539 if (!SRpnt)
Linus Torvalds1da177e2005-04-16 15:20:36 -0700540 return NULL;
Linus Torvalds1da177e2005-04-16 15:20:36 -0700541 }
542
Kai Makisaraf03a5672005-08-02 13:40:47 +0300543 /* If async IO, set last_SRpnt. This ptr tells write_behind_check
544 which IO is outstanding. It's nulled out when the IO completes. */
545 if (!do_wait)
546 (STp->buffer)->last_SRpnt = SRpnt;
547
548 waiting = &STp->wait;
549 init_completion(waiting);
Mike Christie8b05b772005-11-08 04:06:44 -0600550 SRpnt->waiting = waiting;
551
FUJITA Tomonori66207422008-12-18 14:49:43 +0900552 if (STp->buffer->do_dio) {
553 mdata->nr_entries = STp->buffer->sg_segs;
554 mdata->pages = STp->buffer->mapped_pages;
555 } else {
FUJITA Tomonori6d476262008-12-18 14:49:42 +0900556 mdata->nr_entries =
557 DIV_ROUND_UP(bytes, PAGE_SIZE << mdata->page_order);
558 STp->buffer->map_data.pages = STp->buffer->reserved_pages;
559 STp->buffer->map_data.offset = 0;
560 }
561
Mike Christie8b05b772005-11-08 04:06:44 -0600562 memcpy(SRpnt->cmd, cmd, sizeof(SRpnt->cmd));
Linus Torvalds1da177e2005-04-16 15:20:36 -0700563 STp->buffer->cmdstat.have_sense = 0;
Mike Christie8b05b772005-11-08 04:06:44 -0600564 STp->buffer->syscall_result = 0;
Linus Torvalds1da177e2005-04-16 15:20:36 -0700565
FUJITA Tomonori66207422008-12-18 14:49:43 +0900566 ret = st_scsi_execute(SRpnt, cmd, direction, NULL, bytes, timeout,
567 retries);
FUJITA Tomonori6d476262008-12-18 14:49:42 +0900568 if (ret) {
Mike Christie8b05b772005-11-08 04:06:44 -0600569 /* could not allocate the buffer or request was too large */
570 (STp->buffer)->syscall_result = (-EBUSY);
Kai Makisara787926b2005-11-13 10:04:44 +0200571 (STp->buffer)->last_SRpnt = NULL;
FUJITA Tomonori6d476262008-12-18 14:49:42 +0900572 } else if (do_wait) {
Kai Makisaraf03a5672005-08-02 13:40:47 +0300573 wait_for_completion(waiting);
Mike Christie8b05b772005-11-08 04:06:44 -0600574 SRpnt->waiting = NULL;
Linus Torvalds1da177e2005-04-16 15:20:36 -0700575 (STp->buffer)->syscall_result = st_chk_result(STp, SRpnt);
576 }
Mike Christie8b05b772005-11-08 04:06:44 -0600577
Linus Torvalds1da177e2005-04-16 15:20:36 -0700578 return SRpnt;
579}
580
FUJITA Tomonoriffb43492008-12-05 15:25:21 +0900581static int st_scsi_kern_execute(struct st_request *streq,
582 const unsigned char *cmd, int data_direction,
583 void *buffer, unsigned bufflen, int timeout,
584 int retries)
585{
586 struct scsi_tape *stp = streq->stp;
587 int ret, resid;
588
589 stp->buffer->cmdstat.have_sense = 0;
590 memcpy(streq->cmd, cmd, sizeof(streq->cmd));
591
592 ret = scsi_execute(stp->device, cmd, data_direction, buffer, bufflen,
593 streq->sense, timeout, retries, 0, &resid);
594 if (driver_byte(ret) & DRIVER_ERROR)
595 return -EBUSY;
596
597 stp->buffer->cmdstat.midlevel_result = streq->result = ret;
598 stp->buffer->cmdstat.residual = resid;
599 stp->buffer->syscall_result = st_chk_result(stp, streq);
600
601 return 0;
602}
Linus Torvalds1da177e2005-04-16 15:20:36 -0700603
604/* Handle the write-behind checking (waits for completion). Returns -ENOSPC if
605 write has been correct but EOM early warning reached, -EIO if write ended in
606 error or zero if write successful. Asynchronous writes are used only in
607 variable block mode. */
608static int write_behind_check(struct scsi_tape * STp)
609{
610 int retval = 0;
611 struct st_buffer *STbuffer;
612 struct st_partstat *STps;
613 struct st_cmdstatus *cmdstatp;
Mike Christie8b05b772005-11-08 04:06:44 -0600614 struct st_request *SRpnt;
Linus Torvalds1da177e2005-04-16 15:20:36 -0700615
616 STbuffer = STp->buffer;
617 if (!STbuffer->writing)
618 return 0;
619
620 DEB(
621 if (STp->write_pending)
622 STp->nbr_waits++;
623 else
624 STp->nbr_finished++;
625 ) /* end DEB */
626
627 wait_for_completion(&(STp->wait));
Kai Makisaraf03a5672005-08-02 13:40:47 +0300628 SRpnt = STbuffer->last_SRpnt;
629 STbuffer->last_SRpnt = NULL;
Mike Christie8b05b772005-11-08 04:06:44 -0600630 SRpnt->waiting = NULL;
Linus Torvalds1da177e2005-04-16 15:20:36 -0700631
Kai Makisaraf03a5672005-08-02 13:40:47 +0300632 (STp->buffer)->syscall_result = st_chk_result(STp, SRpnt);
Mike Christie8b05b772005-11-08 04:06:44 -0600633 st_release_request(SRpnt);
Linus Torvalds1da177e2005-04-16 15:20:36 -0700634
635 STbuffer->buffer_bytes -= STbuffer->writing;
636 STps = &(STp->ps[STp->partition]);
637 if (STps->drv_block >= 0) {
638 if (STp->block_size == 0)
639 STps->drv_block++;
640 else
641 STps->drv_block += STbuffer->writing / STp->block_size;
642 }
643
644 cmdstatp = &STbuffer->cmdstat;
645 if (STbuffer->syscall_result) {
646 retval = -EIO;
647 if (cmdstatp->have_sense && !cmdstatp->deferred &&
648 (cmdstatp->flags & SENSE_EOM) &&
649 (cmdstatp->sense_hdr.sense_key == NO_SENSE ||
650 cmdstatp->sense_hdr.sense_key == RECOVERED_ERROR)) {
651 /* EOM at write-behind, has all data been written? */
652 if (!cmdstatp->remainder_valid ||
653 cmdstatp->uremainder64 == 0)
654 retval = -ENOSPC;
655 }
656 if (retval == -EIO)
657 STps->drv_block = -1;
658 }
659 STbuffer->writing = 0;
660
661 DEB(if (debugging && retval)
662 printk(ST_DEB_MSG "%s: Async write error %x, return value %d.\n",
663 tape_name(STp), STbuffer->cmdstat.midlevel_result, retval);) /* end DEB */
664
665 return retval;
666}
667
668
669/* Step over EOF if it has been inadvertently crossed (ioctl not used because
670 it messes up the block number). */
671static int cross_eof(struct scsi_tape * STp, int forward)
672{
Mike Christie8b05b772005-11-08 04:06:44 -0600673 struct st_request *SRpnt;
Linus Torvalds1da177e2005-04-16 15:20:36 -0700674 unsigned char cmd[MAX_COMMAND_SIZE];
FUJITA Tomonori39ade4b2008-12-05 15:25:25 +0900675 int ret;
Linus Torvalds1da177e2005-04-16 15:20:36 -0700676
677 cmd[0] = SPACE;
678 cmd[1] = 0x01; /* Space FileMarks */
679 if (forward) {
680 cmd[2] = cmd[3] = 0;
681 cmd[4] = 1;
682 } else
683 cmd[2] = cmd[3] = cmd[4] = 0xff; /* -1 filemarks */
684 cmd[5] = 0;
685
686 DEBC(printk(ST_DEB_MSG "%s: Stepping over filemark %s.\n",
687 tape_name(STp), forward ? "forward" : "backward"));
688
FUJITA Tomonori39ade4b2008-12-05 15:25:25 +0900689 SRpnt = st_allocate_request(STp);
Linus Torvalds1da177e2005-04-16 15:20:36 -0700690 if (!SRpnt)
FUJITA Tomonori39ade4b2008-12-05 15:25:25 +0900691 return STp->buffer->syscall_result;
Linus Torvalds1da177e2005-04-16 15:20:36 -0700692
FUJITA Tomonori39ade4b2008-12-05 15:25:25 +0900693 ret = st_scsi_kern_execute(SRpnt, cmd, DMA_NONE, NULL, 0,
694 STp->device->request_queue->rq_timeout,
695 MAX_RETRIES);
696 if (ret)
697 goto out;
698
699 ret = STp->buffer->syscall_result;
Linus Torvalds1da177e2005-04-16 15:20:36 -0700700
701 if ((STp->buffer)->cmdstat.midlevel_result != 0)
702 printk(KERN_ERR "%s: Stepping over filemark %s failed.\n",
703 tape_name(STp), forward ? "forward" : "backward");
704
FUJITA Tomonori39ade4b2008-12-05 15:25:25 +0900705out:
706 st_release_request(SRpnt);
707
708 return ret;
Linus Torvalds1da177e2005-04-16 15:20:36 -0700709}
710
711
712/* Flush the write buffer (never need to write if variable blocksize). */
Adrian Bunk8ef8d592008-04-14 17:17:16 +0300713static int st_flush_write_buffer(struct scsi_tape * STp)
Linus Torvalds1da177e2005-04-16 15:20:36 -0700714{
Kai Makisara786231a2008-07-11 15:06:40 +0300715 int transfer, blks;
Linus Torvalds1da177e2005-04-16 15:20:36 -0700716 int result;
717 unsigned char cmd[MAX_COMMAND_SIZE];
Mike Christie8b05b772005-11-08 04:06:44 -0600718 struct st_request *SRpnt;
Linus Torvalds1da177e2005-04-16 15:20:36 -0700719 struct st_partstat *STps;
720
721 result = write_behind_check(STp);
722 if (result)
723 return result;
724
725 result = 0;
726 if (STp->dirty == 1) {
727
Kai Makisara786231a2008-07-11 15:06:40 +0300728 transfer = STp->buffer->buffer_bytes;
Linus Torvalds1da177e2005-04-16 15:20:36 -0700729 DEBC(printk(ST_DEB_MSG "%s: Flushing %d bytes.\n",
730 tape_name(STp), transfer));
731
Linus Torvalds1da177e2005-04-16 15:20:36 -0700732 memset(cmd, 0, MAX_COMMAND_SIZE);
733 cmd[0] = WRITE_6;
734 cmd[1] = 1;
735 blks = transfer / STp->block_size;
736 cmd[2] = blks >> 16;
737 cmd[3] = blks >> 8;
738 cmd[4] = blks;
739
740 SRpnt = st_do_scsi(NULL, STp, cmd, transfer, DMA_TO_DEVICE,
James Bottomleya02488e2008-11-30 10:36:26 -0600741 STp->device->request_queue->rq_timeout,
742 MAX_WRITE_RETRIES, 1);
Linus Torvalds1da177e2005-04-16 15:20:36 -0700743 if (!SRpnt)
744 return (STp->buffer)->syscall_result;
745
746 STps = &(STp->ps[STp->partition]);
747 if ((STp->buffer)->syscall_result != 0) {
748 struct st_cmdstatus *cmdstatp = &STp->buffer->cmdstat;
749
750 if (cmdstatp->have_sense && !cmdstatp->deferred &&
751 (cmdstatp->flags & SENSE_EOM) &&
752 (cmdstatp->sense_hdr.sense_key == NO_SENSE ||
753 cmdstatp->sense_hdr.sense_key == RECOVERED_ERROR) &&
754 (!cmdstatp->remainder_valid ||
755 cmdstatp->uremainder64 == 0)) { /* All written at EOM early warning */
756 STp->dirty = 0;
757 (STp->buffer)->buffer_bytes = 0;
758 if (STps->drv_block >= 0)
759 STps->drv_block += blks;
760 result = (-ENOSPC);
761 } else {
762 printk(KERN_ERR "%s: Error on flush.\n",
763 tape_name(STp));
764 STps->drv_block = (-1);
765 result = (-EIO);
766 }
767 } else {
768 if (STps->drv_block >= 0)
769 STps->drv_block += blks;
770 STp->dirty = 0;
771 (STp->buffer)->buffer_bytes = 0;
772 }
Mike Christie8b05b772005-11-08 04:06:44 -0600773 st_release_request(SRpnt);
Linus Torvalds1da177e2005-04-16 15:20:36 -0700774 SRpnt = NULL;
775 }
776 return result;
777}
778
779
780/* Flush the tape buffer. The tape will be positioned correctly unless
781 seek_next is true. */
782static int flush_buffer(struct scsi_tape *STp, int seek_next)
783{
784 int backspace, result;
785 struct st_buffer *STbuffer;
786 struct st_partstat *STps;
787
788 STbuffer = STp->buffer;
789
790 /*
791 * If there was a bus reset, block further access
792 * to this device.
793 */
794 if (STp->pos_unknown)
795 return (-EIO);
796
797 if (STp->ready != ST_READY)
798 return 0;
799 STps = &(STp->ps[STp->partition]);
800 if (STps->rw == ST_WRITING) /* Writing */
Adrian Bunk8ef8d592008-04-14 17:17:16 +0300801 return st_flush_write_buffer(STp);
Linus Torvalds1da177e2005-04-16 15:20:36 -0700802
803 if (STp->block_size == 0)
804 return 0;
805
806 backspace = ((STp->buffer)->buffer_bytes +
807 (STp->buffer)->read_pointer) / STp->block_size -
808 ((STp->buffer)->read_pointer + STp->block_size - 1) /
809 STp->block_size;
810 (STp->buffer)->buffer_bytes = 0;
811 (STp->buffer)->read_pointer = 0;
812 result = 0;
813 if (!seek_next) {
814 if (STps->eof == ST_FM_HIT) {
815 result = cross_eof(STp, 0); /* Back over the EOF hit */
816 if (!result)
817 STps->eof = ST_NOEOF;
818 else {
819 if (STps->drv_file >= 0)
820 STps->drv_file++;
821 STps->drv_block = 0;
822 }
823 }
824 if (!result && backspace > 0)
825 result = st_int_ioctl(STp, MTBSR, backspace);
826 } else if (STps->eof == ST_FM_HIT) {
827 if (STps->drv_file >= 0)
828 STps->drv_file++;
829 STps->drv_block = 0;
830 STps->eof = ST_NOEOF;
831 }
832 return result;
833
834}
835
836/* Set the mode parameters */
837static int set_mode_densblk(struct scsi_tape * STp, struct st_modedef * STm)
838{
839 int set_it = 0;
840 unsigned long arg;
841 char *name = tape_name(STp);
842
843 if (!STp->density_changed &&
844 STm->default_density >= 0 &&
845 STm->default_density != STp->density) {
846 arg = STm->default_density;
847 set_it = 1;
848 } else
849 arg = STp->density;
850 arg <<= MT_ST_DENSITY_SHIFT;
851 if (!STp->blksize_changed &&
852 STm->default_blksize >= 0 &&
853 STm->default_blksize != STp->block_size) {
854 arg |= STm->default_blksize;
855 set_it = 1;
856 } else
857 arg |= STp->block_size;
858 if (set_it &&
859 st_int_ioctl(STp, SET_DENS_AND_BLK, arg)) {
860 printk(KERN_WARNING
861 "%s: Can't set default block size to %d bytes and density %x.\n",
862 name, STm->default_blksize, STm->default_density);
863 if (modes_defined)
864 return (-EINVAL);
865 }
866 return 0;
867}
868
869
Mike Christie8b05b772005-11-08 04:06:44 -0600870/* Lock or unlock the drive door. Don't use when st_request allocated. */
Linus Torvalds1da177e2005-04-16 15:20:36 -0700871static int do_door_lock(struct scsi_tape * STp, int do_lock)
872{
873 int retval, cmd;
874 DEB(char *name = tape_name(STp);)
875
876
877 cmd = do_lock ? SCSI_IOCTL_DOORLOCK : SCSI_IOCTL_DOORUNLOCK;
878 DEBC(printk(ST_DEB_MSG "%s: %socking drive door.\n", name,
879 do_lock ? "L" : "Unl"));
880 retval = scsi_ioctl(STp->device, cmd, NULL);
881 if (!retval) {
882 STp->door_locked = do_lock ? ST_LOCKED_EXPLICIT : ST_UNLOCKED;
883 }
884 else {
885 STp->door_locked = ST_LOCK_FAILS;
886 }
887 return retval;
888}
889
890
891/* Set the internal state after reset */
892static void reset_state(struct scsi_tape *STp)
893{
894 int i;
895 struct st_partstat *STps;
896
897 STp->pos_unknown = 0;
898 for (i = 0; i < ST_NBR_PARTITIONS; i++) {
899 STps = &(STp->ps[i]);
900 STps->rw = ST_IDLE;
901 STps->eof = ST_NOEOF;
902 STps->at_sm = 0;
903 STps->last_block_valid = 0;
904 STps->drv_block = -1;
905 STps->drv_file = -1;
906 }
907 if (STp->can_partitions) {
908 STp->partition = find_partition(STp);
909 if (STp->partition < 0)
910 STp->partition = 0;
911 STp->new_partition = STp->partition;
912 }
913}
914
915/* Test if the drive is ready. Returns either one of the codes below or a negative system
916 error code. */
917#define CHKRES_READY 0
918#define CHKRES_NEW_SESSION 1
919#define CHKRES_NOT_READY 2
920#define CHKRES_NO_TAPE 3
921
922#define MAX_ATTENTIONS 10
923
924static int test_ready(struct scsi_tape *STp, int do_wait)
925{
926 int attentions, waits, max_wait, scode;
927 int retval = CHKRES_READY, new_session = 0;
928 unsigned char cmd[MAX_COMMAND_SIZE];
FUJITA Tomonori0944a722008-12-05 15:25:22 +0900929 struct st_request *SRpnt;
Linus Torvalds1da177e2005-04-16 15:20:36 -0700930 struct st_cmdstatus *cmdstatp = &STp->buffer->cmdstat;
931
FUJITA Tomonori0944a722008-12-05 15:25:22 +0900932 SRpnt = st_allocate_request(STp);
933 if (!SRpnt)
934 return STp->buffer->syscall_result;
935
Linus Torvalds1da177e2005-04-16 15:20:36 -0700936 max_wait = do_wait ? ST_BLOCK_SECONDS : 0;
937
938 for (attentions=waits=0; ; ) {
939 memset((void *) &cmd[0], 0, MAX_COMMAND_SIZE);
940 cmd[0] = TEST_UNIT_READY;
Linus Torvalds1da177e2005-04-16 15:20:36 -0700941
FUJITA Tomonori0944a722008-12-05 15:25:22 +0900942 retval = st_scsi_kern_execute(SRpnt, cmd, DMA_NONE, NULL, 0,
943 STp->long_timeout,
944 MAX_READY_RETRIES);
945 if (retval)
Linus Torvalds1da177e2005-04-16 15:20:36 -0700946 break;
Linus Torvalds1da177e2005-04-16 15:20:36 -0700947
948 if (cmdstatp->have_sense) {
949
950 scode = cmdstatp->sense_hdr.sense_key;
951
952 if (scode == UNIT_ATTENTION) { /* New media? */
953 new_session = 1;
954 if (attentions < MAX_ATTENTIONS) {
955 attentions++;
956 continue;
957 }
958 else {
959 retval = (-EIO);
960 break;
961 }
962 }
963
964 if (scode == NOT_READY) {
965 if (waits < max_wait) {
966 if (msleep_interruptible(1000)) {
967 retval = (-EINTR);
968 break;
969 }
970 waits++;
971 continue;
972 }
973 else {
974 if ((STp->device)->scsi_level >= SCSI_2 &&
975 cmdstatp->sense_hdr.asc == 0x3a) /* Check ASC */
976 retval = CHKRES_NO_TAPE;
977 else
978 retval = CHKRES_NOT_READY;
979 break;
980 }
981 }
982 }
983
984 retval = (STp->buffer)->syscall_result;
985 if (!retval)
986 retval = new_session ? CHKRES_NEW_SESSION : CHKRES_READY;
987 break;
988 }
989
FUJITA Tomonori0944a722008-12-05 15:25:22 +0900990 st_release_request(SRpnt);
991
Linus Torvalds1da177e2005-04-16 15:20:36 -0700992 return retval;
993}
994
995
996/* See if the drive is ready and gather information about the tape. Return values:
997 < 0 negative error code from errno.h
998 0 drive ready
999 1 drive not ready (possibly no tape)
1000*/
1001static int check_tape(struct scsi_tape *STp, struct file *filp)
1002{
1003 int i, retval, new_session = 0, do_wait;
1004 unsigned char cmd[MAX_COMMAND_SIZE], saved_cleaning;
1005 unsigned short st_flags = filp->f_flags;
Mike Christie8b05b772005-11-08 04:06:44 -06001006 struct st_request *SRpnt = NULL;
Linus Torvalds1da177e2005-04-16 15:20:36 -07001007 struct st_modedef *STm;
1008 struct st_partstat *STps;
1009 char *name = tape_name(STp);
Josef Sipek7ac62072006-12-08 02:37:37 -08001010 struct inode *inode = filp->f_path.dentry->d_inode;
Linus Torvalds1da177e2005-04-16 15:20:36 -07001011 int mode = TAPE_MODE(inode);
1012
1013 STp->ready = ST_READY;
1014
1015 if (mode != STp->current_mode) {
1016 DEBC(printk(ST_DEB_MSG "%s: Mode change from %d to %d.\n",
1017 name, STp->current_mode, mode));
1018 new_session = 1;
1019 STp->current_mode = mode;
1020 }
1021 STm = &(STp->modes[STp->current_mode]);
1022
1023 saved_cleaning = STp->cleaning_req;
1024 STp->cleaning_req = 0;
1025
1026 do_wait = ((filp->f_flags & O_NONBLOCK) == 0);
1027 retval = test_ready(STp, do_wait);
1028
1029 if (retval < 0)
1030 goto err_out;
1031
1032 if (retval == CHKRES_NEW_SESSION) {
1033 STp->pos_unknown = 0;
1034 STp->partition = STp->new_partition = 0;
1035 if (STp->can_partitions)
1036 STp->nbr_partitions = 1; /* This guess will be updated later
1037 if necessary */
1038 for (i = 0; i < ST_NBR_PARTITIONS; i++) {
1039 STps = &(STp->ps[i]);
1040 STps->rw = ST_IDLE;
1041 STps->eof = ST_NOEOF;
1042 STps->at_sm = 0;
1043 STps->last_block_valid = 0;
1044 STps->drv_block = 0;
1045 STps->drv_file = 0;
1046 }
1047 new_session = 1;
1048 }
1049 else {
1050 STp->cleaning_req |= saved_cleaning;
1051
1052 if (retval == CHKRES_NOT_READY || retval == CHKRES_NO_TAPE) {
1053 if (retval == CHKRES_NO_TAPE)
1054 STp->ready = ST_NO_TAPE;
1055 else
1056 STp->ready = ST_NOT_READY;
1057
1058 STp->density = 0; /* Clear the erroneous "residue" */
1059 STp->write_prot = 0;
1060 STp->block_size = 0;
1061 STp->ps[0].drv_file = STp->ps[0].drv_block = (-1);
1062 STp->partition = STp->new_partition = 0;
1063 STp->door_locked = ST_UNLOCKED;
1064 return CHKRES_NOT_READY;
1065 }
1066 }
1067
FUJITA Tomonori52107b22008-12-05 15:25:27 +09001068 SRpnt = st_allocate_request(STp);
1069 if (!SRpnt) {
1070 retval = STp->buffer->syscall_result;
1071 goto err_out;
1072 }
1073
Linus Torvalds1da177e2005-04-16 15:20:36 -07001074 if (STp->omit_blklims)
1075 STp->min_block = STp->max_block = (-1);
1076 else {
1077 memset((void *) &cmd[0], 0, MAX_COMMAND_SIZE);
1078 cmd[0] = READ_BLOCK_LIMITS;
1079
FUJITA Tomonori52107b22008-12-05 15:25:27 +09001080 retval = st_scsi_kern_execute(SRpnt, cmd, DMA_FROM_DEVICE,
1081 STp->buffer->b_data, 6,
1082 STp->device->request_queue->rq_timeout,
1083 MAX_READY_RETRIES);
1084 if (retval) {
1085 st_release_request(SRpnt);
Linus Torvalds1da177e2005-04-16 15:20:36 -07001086 goto err_out;
1087 }
1088
Mike Christie8b05b772005-11-08 04:06:44 -06001089 if (!SRpnt->result && !STp->buffer->cmdstat.have_sense) {
Linus Torvalds1da177e2005-04-16 15:20:36 -07001090 STp->max_block = ((STp->buffer)->b_data[1] << 16) |
1091 ((STp->buffer)->b_data[2] << 8) | (STp->buffer)->b_data[3];
1092 STp->min_block = ((STp->buffer)->b_data[4] << 8) |
1093 (STp->buffer)->b_data[5];
1094 if ( DEB( debugging || ) !STp->inited)
Kai Makisara42252852006-11-07 21:56:38 +02001095 printk(KERN_INFO
Linus Torvalds1da177e2005-04-16 15:20:36 -07001096 "%s: Block limits %d - %d bytes.\n", name,
1097 STp->min_block, STp->max_block);
1098 } else {
1099 STp->min_block = STp->max_block = (-1);
1100 DEBC(printk(ST_DEB_MSG "%s: Can't read block limits.\n",
1101 name));
1102 }
1103 }
1104
1105 memset((void *) &cmd[0], 0, MAX_COMMAND_SIZE);
1106 cmd[0] = MODE_SENSE;
1107 cmd[4] = 12;
1108
FUJITA Tomonori52107b22008-12-05 15:25:27 +09001109 retval = st_scsi_kern_execute(SRpnt, cmd, DMA_FROM_DEVICE,
1110 STp->buffer->b_data, 12,
1111 STp->device->request_queue->rq_timeout,
1112 MAX_READY_RETRIES);
1113 if (retval) {
1114 st_release_request(SRpnt);
Linus Torvalds1da177e2005-04-16 15:20:36 -07001115 goto err_out;
1116 }
1117
1118 if ((STp->buffer)->syscall_result != 0) {
1119 DEBC(printk(ST_DEB_MSG "%s: No Mode Sense.\n", name));
1120 STp->block_size = ST_DEFAULT_BLOCK; /* Educated guess (?) */
1121 (STp->buffer)->syscall_result = 0; /* Prevent error propagation */
1122 STp->drv_write_prot = 0;
1123 } else {
1124 DEBC(printk(ST_DEB_MSG
1125 "%s: Mode sense. Length %d, medium %x, WBS %x, BLL %d\n",
1126 name,
1127 (STp->buffer)->b_data[0], (STp->buffer)->b_data[1],
1128 (STp->buffer)->b_data[2], (STp->buffer)->b_data[3]));
1129
1130 if ((STp->buffer)->b_data[3] >= 8) {
1131 STp->drv_buffer = ((STp->buffer)->b_data[2] >> 4) & 7;
1132 STp->density = (STp->buffer)->b_data[4];
1133 STp->block_size = (STp->buffer)->b_data[9] * 65536 +
1134 (STp->buffer)->b_data[10] * 256 + (STp->buffer)->b_data[11];
1135 DEBC(printk(ST_DEB_MSG
1136 "%s: Density %x, tape length: %x, drv buffer: %d\n",
1137 name, STp->density, (STp->buffer)->b_data[5] * 65536 +
1138 (STp->buffer)->b_data[6] * 256 + (STp->buffer)->b_data[7],
1139 STp->drv_buffer));
1140 }
1141 STp->drv_write_prot = ((STp->buffer)->b_data[2] & 0x80) != 0;
1142 }
Mike Christie8b05b772005-11-08 04:06:44 -06001143 st_release_request(SRpnt);
Linus Torvalds1da177e2005-04-16 15:20:36 -07001144 SRpnt = NULL;
1145 STp->inited = 1;
1146
1147 if (STp->block_size > 0)
1148 (STp->buffer)->buffer_blocks =
1149 (STp->buffer)->buffer_size / STp->block_size;
1150 else
1151 (STp->buffer)->buffer_blocks = 1;
1152 (STp->buffer)->buffer_bytes = (STp->buffer)->read_pointer = 0;
1153
1154 DEBC(printk(ST_DEB_MSG
1155 "%s: Block size: %d, buffer size: %d (%d blocks).\n", name,
1156 STp->block_size, (STp->buffer)->buffer_size,
1157 (STp->buffer)->buffer_blocks));
1158
1159 if (STp->drv_write_prot) {
1160 STp->write_prot = 1;
1161
1162 DEBC(printk(ST_DEB_MSG "%s: Write protected\n", name));
1163
1164 if (do_wait &&
1165 ((st_flags & O_ACCMODE) == O_WRONLY ||
1166 (st_flags & O_ACCMODE) == O_RDWR)) {
1167 retval = (-EROFS);
1168 goto err_out;
1169 }
1170 }
1171
1172 if (STp->can_partitions && STp->nbr_partitions < 1) {
1173 /* This code is reached when the device is opened for the first time
1174 after the driver has been initialized with tape in the drive and the
1175 partition support has been enabled. */
1176 DEBC(printk(ST_DEB_MSG
1177 "%s: Updating partition number in status.\n", name));
1178 if ((STp->partition = find_partition(STp)) < 0) {
1179 retval = STp->partition;
1180 goto err_out;
1181 }
1182 STp->new_partition = STp->partition;
1183 STp->nbr_partitions = 1; /* This guess will be updated when necessary */
1184 }
1185
1186 if (new_session) { /* Change the drive parameters for the new mode */
1187 STp->density_changed = STp->blksize_changed = 0;
1188 STp->compression_changed = 0;
1189 if (!(STm->defaults_for_writes) &&
1190 (retval = set_mode_densblk(STp, STm)) < 0)
1191 goto err_out;
1192
1193 if (STp->default_drvbuffer != 0xff) {
1194 if (st_int_ioctl(STp, MTSETDRVBUFFER, STp->default_drvbuffer))
1195 printk(KERN_WARNING
1196 "%s: Can't set default drive buffering to %d.\n",
1197 name, STp->default_drvbuffer);
1198 }
1199 }
1200
1201 return CHKRES_READY;
1202
1203 err_out:
1204 return retval;
1205}
1206
1207
Jonathan Corbetb3369c62008-05-15 16:08:15 -06001208 /* Open the device. Needs to take the BKL only because of incrementing the SCSI host
Linus Torvalds1da177e2005-04-16 15:20:36 -07001209 module count. */
1210static int st_open(struct inode *inode, struct file *filp)
1211{
1212 int i, retval = (-EIO);
1213 struct scsi_tape *STp;
1214 struct st_partstat *STps;
1215 int dev = TAPE_NR(inode);
1216 char *name;
1217
Jonathan Corbetb3369c62008-05-15 16:08:15 -06001218 lock_kernel();
Linus Torvalds1da177e2005-04-16 15:20:36 -07001219 /*
1220 * We really want to do nonseekable_open(inode, filp); here, but some
1221 * versions of tar incorrectly call lseek on tapes and bail out if that
1222 * fails. So we disallow pread() and pwrite(), but permit lseeks.
1223 */
1224 filp->f_mode &= ~(FMODE_PREAD | FMODE_PWRITE);
1225
Jonathan Corbetb3369c62008-05-15 16:08:15 -06001226 if (!(STp = scsi_tape_get(dev))) {
1227 unlock_kernel();
Kai Makisaraf03a5672005-08-02 13:40:47 +03001228 return -ENXIO;
Jonathan Corbetb3369c62008-05-15 16:08:15 -06001229 }
Kai Makisaraf03a5672005-08-02 13:40:47 +03001230
Linus Torvalds1da177e2005-04-16 15:20:36 -07001231 write_lock(&st_dev_arr_lock);
Linus Torvalds1da177e2005-04-16 15:20:36 -07001232 filp->private_data = STp;
1233 name = tape_name(STp);
1234
1235 if (STp->in_use) {
1236 write_unlock(&st_dev_arr_lock);
Kai Makisaraf03a5672005-08-02 13:40:47 +03001237 scsi_tape_put(STp);
Jonathan Corbetb3369c62008-05-15 16:08:15 -06001238 unlock_kernel();
Linus Torvalds1da177e2005-04-16 15:20:36 -07001239 DEB( printk(ST_DEB_MSG "%s: Device already in use.\n", name); )
1240 return (-EBUSY);
1241 }
1242
Linus Torvalds1da177e2005-04-16 15:20:36 -07001243 STp->in_use = 1;
1244 write_unlock(&st_dev_arr_lock);
1245 STp->rew_at_close = STp->autorew_dev = (iminor(inode) & 0x80) == 0;
1246
1247 if (!scsi_block_when_processing_errors(STp->device)) {
1248 retval = (-ENXIO);
1249 goto err_out;
1250 }
1251
1252 /* See that we have at least a one page buffer available */
1253 if (!enlarge_buffer(STp->buffer, PAGE_SIZE, STp->restr_dma)) {
1254 printk(KERN_WARNING "%s: Can't allocate one page tape buffer.\n",
1255 name);
1256 retval = (-EOVERFLOW);
1257 goto err_out;
1258 }
1259
Kai Makisara40f6b362008-02-24 22:23:24 +02001260 (STp->buffer)->cleared = 0;
Linus Torvalds1da177e2005-04-16 15:20:36 -07001261 (STp->buffer)->writing = 0;
1262 (STp->buffer)->syscall_result = 0;
1263
1264 STp->write_prot = ((filp->f_flags & O_ACCMODE) == O_RDONLY);
1265
1266 STp->dirty = 0;
1267 for (i = 0; i < ST_NBR_PARTITIONS; i++) {
1268 STps = &(STp->ps[i]);
1269 STps->rw = ST_IDLE;
1270 }
Kai Makisara9abe16c2007-02-03 13:21:29 +02001271 STp->try_dio_now = STp->try_dio;
Linus Torvalds1da177e2005-04-16 15:20:36 -07001272 STp->recover_count = 0;
1273 DEB( STp->nbr_waits = STp->nbr_finished = 0;
Kai Makisaradeee13d2008-02-22 20:11:21 +02001274 STp->nbr_requests = STp->nbr_dio = STp->nbr_pages = 0; )
Linus Torvalds1da177e2005-04-16 15:20:36 -07001275
1276 retval = check_tape(STp, filp);
1277 if (retval < 0)
1278 goto err_out;
1279 if ((filp->f_flags & O_NONBLOCK) == 0 &&
1280 retval != CHKRES_READY) {
Kai Makisara413f7322006-10-05 22:59:46 +03001281 if (STp->ready == NO_TAPE)
1282 retval = (-ENOMEDIUM);
1283 else
1284 retval = (-EIO);
Linus Torvalds1da177e2005-04-16 15:20:36 -07001285 goto err_out;
1286 }
Jonathan Corbetb3369c62008-05-15 16:08:15 -06001287 unlock_kernel();
Linus Torvalds1da177e2005-04-16 15:20:36 -07001288 return 0;
1289
1290 err_out:
1291 normalize_buffer(STp->buffer);
1292 STp->in_use = 0;
Kai Makisaraf03a5672005-08-02 13:40:47 +03001293 scsi_tape_put(STp);
Jonathan Corbetb3369c62008-05-15 16:08:15 -06001294 unlock_kernel();
Linus Torvalds1da177e2005-04-16 15:20:36 -07001295 return retval;
1296
1297}
1298
1299
1300/* Flush the tape buffer before close */
Miklos Szeredi75e1fcc2006-06-23 02:05:12 -07001301static int st_flush(struct file *filp, fl_owner_t id)
Linus Torvalds1da177e2005-04-16 15:20:36 -07001302{
1303 int result = 0, result2;
1304 unsigned char cmd[MAX_COMMAND_SIZE];
Mike Christie8b05b772005-11-08 04:06:44 -06001305 struct st_request *SRpnt;
Linus Torvalds1da177e2005-04-16 15:20:36 -07001306 struct scsi_tape *STp = filp->private_data;
1307 struct st_modedef *STm = &(STp->modes[STp->current_mode]);
1308 struct st_partstat *STps = &(STp->ps[STp->partition]);
1309 char *name = tape_name(STp);
1310
1311 if (file_count(filp) > 1)
1312 return 0;
1313
1314 if (STps->rw == ST_WRITING && !STp->pos_unknown) {
Adrian Bunk8ef8d592008-04-14 17:17:16 +03001315 result = st_flush_write_buffer(STp);
Linus Torvalds1da177e2005-04-16 15:20:36 -07001316 if (result != 0 && result != (-ENOSPC))
1317 goto out;
1318 }
1319
1320 if (STp->can_partitions &&
1321 (result2 = switch_partition(STp)) < 0) {
1322 DEBC(printk(ST_DEB_MSG
1323 "%s: switch_partition at close failed.\n", name));
1324 if (result == 0)
1325 result = result2;
1326 goto out;
1327 }
1328
1329 DEBC( if (STp->nbr_requests)
Kai Makisaradeee13d2008-02-22 20:11:21 +02001330 printk(KERN_DEBUG "%s: Number of r/w requests %d, dio used in %d, pages %d.\n",
1331 name, STp->nbr_requests, STp->nbr_dio, STp->nbr_pages));
Linus Torvalds1da177e2005-04-16 15:20:36 -07001332
1333 if (STps->rw == ST_WRITING && !STp->pos_unknown) {
1334 struct st_cmdstatus *cmdstatp = &STp->buffer->cmdstat;
1335
1336 DEBC(printk(ST_DEB_MSG "%s: Async write waits %d, finished %d.\n",
1337 name, STp->nbr_waits, STp->nbr_finished);
1338 )
1339
1340 memset(cmd, 0, MAX_COMMAND_SIZE);
1341 cmd[0] = WRITE_FILEMARKS;
1342 cmd[4] = 1 + STp->two_fm;
1343
FUJITA Tomonori212cd8b2008-12-05 15:25:26 +09001344 SRpnt = st_allocate_request(STp);
Linus Torvalds1da177e2005-04-16 15:20:36 -07001345 if (!SRpnt) {
FUJITA Tomonori212cd8b2008-12-05 15:25:26 +09001346 result = STp->buffer->syscall_result;
1347 goto out;
1348 }
1349
1350 result = st_scsi_kern_execute(SRpnt, cmd, DMA_NONE, NULL, 0,
1351 STp->device->request_queue->rq_timeout,
1352 MAX_WRITE_RETRIES);
1353 if (result) {
1354 st_release_request(SRpnt);
Linus Torvalds1da177e2005-04-16 15:20:36 -07001355 goto out;
1356 }
1357
1358 if (STp->buffer->syscall_result == 0 ||
1359 (cmdstatp->have_sense && !cmdstatp->deferred &&
1360 (cmdstatp->flags & SENSE_EOM) &&
1361 (cmdstatp->sense_hdr.sense_key == NO_SENSE ||
1362 cmdstatp->sense_hdr.sense_key == RECOVERED_ERROR) &&
1363 (!cmdstatp->remainder_valid || cmdstatp->uremainder64 == 0))) {
1364 /* Write successful at EOM */
Mike Christie8b05b772005-11-08 04:06:44 -06001365 st_release_request(SRpnt);
Linus Torvalds1da177e2005-04-16 15:20:36 -07001366 SRpnt = NULL;
1367 if (STps->drv_file >= 0)
1368 STps->drv_file++;
1369 STps->drv_block = 0;
1370 if (STp->two_fm)
1371 cross_eof(STp, 0);
1372 STps->eof = ST_FM;
1373 }
1374 else { /* Write error */
Mike Christie8b05b772005-11-08 04:06:44 -06001375 st_release_request(SRpnt);
Linus Torvalds1da177e2005-04-16 15:20:36 -07001376 SRpnt = NULL;
1377 printk(KERN_ERR "%s: Error on write filemark.\n", name);
1378 if (result == 0)
1379 result = (-EIO);
1380 }
1381
1382 DEBC(printk(ST_DEB_MSG "%s: Buffer flushed, %d EOF(s) written\n",
1383 name, cmd[4]));
1384 } else if (!STp->rew_at_close) {
1385 STps = &(STp->ps[STp->partition]);
1386 if (!STm->sysv || STps->rw != ST_READING) {
1387 if (STp->can_bsr)
1388 result = flush_buffer(STp, 0);
1389 else if (STps->eof == ST_FM_HIT) {
1390 result = cross_eof(STp, 0);
1391 if (result) {
1392 if (STps->drv_file >= 0)
1393 STps->drv_file++;
1394 STps->drv_block = 0;
1395 STps->eof = ST_FM;
1396 } else
1397 STps->eof = ST_NOEOF;
1398 }
1399 } else if ((STps->eof == ST_NOEOF &&
1400 !(result = cross_eof(STp, 1))) ||
1401 STps->eof == ST_FM_HIT) {
1402 if (STps->drv_file >= 0)
1403 STps->drv_file++;
1404 STps->drv_block = 0;
1405 STps->eof = ST_FM;
1406 }
1407 }
1408
1409 out:
1410 if (STp->rew_at_close) {
1411 result2 = st_int_ioctl(STp, MTREW, 1);
1412 if (result == 0)
1413 result = result2;
1414 }
1415 return result;
1416}
1417
1418
1419/* Close the device and release it. BKL is not needed: this is the only thread
1420 accessing this tape. */
1421static int st_release(struct inode *inode, struct file *filp)
1422{
1423 int result = 0;
1424 struct scsi_tape *STp = filp->private_data;
1425
1426 if (STp->door_locked == ST_LOCKED_AUTO)
1427 do_door_lock(STp, 0);
1428
1429 normalize_buffer(STp->buffer);
1430 write_lock(&st_dev_arr_lock);
1431 STp->in_use = 0;
1432 write_unlock(&st_dev_arr_lock);
Kai Makisaraf03a5672005-08-02 13:40:47 +03001433 scsi_tape_put(STp);
Linus Torvalds1da177e2005-04-16 15:20:36 -07001434
1435 return result;
1436}
1437
1438/* The checks common to both reading and writing */
1439static ssize_t rw_checks(struct scsi_tape *STp, struct file *filp, size_t count)
1440{
1441 ssize_t retval = 0;
1442
1443 /*
1444 * If we are in the middle of error recovery, don't let anyone
1445 * else try and use this device. Also, if error recovery fails, it
1446 * may try and take the device offline, in which case all further
1447 * access to the device is prohibited.
1448 */
1449 if (!scsi_block_when_processing_errors(STp->device)) {
1450 retval = (-ENXIO);
1451 goto out;
1452 }
1453
1454 if (STp->ready != ST_READY) {
1455 if (STp->ready == ST_NO_TAPE)
1456 retval = (-ENOMEDIUM);
1457 else
1458 retval = (-EIO);
1459 goto out;
1460 }
1461
1462 if (! STp->modes[STp->current_mode].defined) {
1463 retval = (-ENXIO);
1464 goto out;
1465 }
1466
1467
1468 /*
1469 * If there was a bus reset, block further access
1470 * to this device.
1471 */
1472 if (STp->pos_unknown) {
1473 retval = (-EIO);
1474 goto out;
1475 }
1476
1477 if (count == 0)
1478 goto out;
1479
1480 DEB(
1481 if (!STp->in_use) {
1482 printk(ST_DEB_MSG "%s: Incorrect device.\n", tape_name(STp));
1483 retval = (-EIO);
1484 goto out;
1485 } ) /* end DEB */
1486
1487 if (STp->can_partitions &&
1488 (retval = switch_partition(STp)) < 0)
1489 goto out;
1490
1491 if (STp->block_size == 0 && STp->max_block > 0 &&
1492 (count < STp->min_block || count > STp->max_block)) {
1493 retval = (-EINVAL);
1494 goto out;
1495 }
1496
1497 if (STp->do_auto_lock && STp->door_locked == ST_UNLOCKED &&
1498 !do_door_lock(STp, 1))
1499 STp->door_locked = ST_LOCKED_AUTO;
1500
1501 out:
1502 return retval;
1503}
1504
1505
1506static int setup_buffering(struct scsi_tape *STp, const char __user *buf,
1507 size_t count, int is_read)
1508{
1509 int i, bufsize, retval = 0;
1510 struct st_buffer *STbp = STp->buffer;
1511
1512 if (is_read)
Kai Makisara9abe16c2007-02-03 13:21:29 +02001513 i = STp->try_dio_now && try_rdio;
Linus Torvalds1da177e2005-04-16 15:20:36 -07001514 else
Kai Makisara9abe16c2007-02-03 13:21:29 +02001515 i = STp->try_dio_now && try_wdio;
Mike Christie8b05b772005-11-08 04:06:44 -06001516
Linus Torvalds1da177e2005-04-16 15:20:36 -07001517 if (i && ((unsigned long)buf & queue_dma_alignment(
1518 STp->device->request_queue)) == 0) {
FUJITA Tomonori66207422008-12-18 14:49:43 +09001519 i = sgl_map_user_pages(STbp, STbp->use_sg, (unsigned long)buf,
1520 count, (is_read ? READ : WRITE));
Linus Torvalds1da177e2005-04-16 15:20:36 -07001521 if (i > 0) {
1522 STbp->do_dio = i;
1523 STbp->buffer_bytes = 0; /* can be used as transfer counter */
1524 }
1525 else
1526 STbp->do_dio = 0; /* fall back to buffering with any error */
1527 STbp->sg_segs = STbp->do_dio;
1528 STbp->frp_sg_current = 0;
1529 DEB(
1530 if (STbp->do_dio) {
1531 STp->nbr_dio++;
1532 STp->nbr_pages += STbp->do_dio;
Linus Torvalds1da177e2005-04-16 15:20:36 -07001533 }
1534 )
1535 } else
1536 STbp->do_dio = 0;
1537 DEB( STp->nbr_requests++; )
1538
1539 if (!STbp->do_dio) {
1540 if (STp->block_size)
1541 bufsize = STp->block_size > st_fixed_buffer_size ?
1542 STp->block_size : st_fixed_buffer_size;
Kai Makisara40f6b362008-02-24 22:23:24 +02001543 else {
Linus Torvalds1da177e2005-04-16 15:20:36 -07001544 bufsize = count;
Kai Makisara40f6b362008-02-24 22:23:24 +02001545 /* Make sure that data from previous user is not leaked even if
1546 HBA does not return correct residual */
1547 if (is_read && STp->sili && !STbp->cleared)
1548 clear_buffer(STbp);
1549 }
1550
Linus Torvalds1da177e2005-04-16 15:20:36 -07001551 if (bufsize > STbp->buffer_size &&
1552 !enlarge_buffer(STbp, bufsize, STp->restr_dma)) {
1553 printk(KERN_WARNING "%s: Can't allocate %d byte tape buffer.\n",
1554 tape_name(STp), bufsize);
1555 retval = (-EOVERFLOW);
1556 goto out;
1557 }
1558 if (STp->block_size)
1559 STbp->buffer_blocks = bufsize / STp->block_size;
1560 }
1561
1562 out:
1563 return retval;
1564}
1565
1566
1567/* Can be called more than once after each setup_buffer() */
Kai Makisara787926b2005-11-13 10:04:44 +02001568static void release_buffering(struct scsi_tape *STp, int is_read)
Linus Torvalds1da177e2005-04-16 15:20:36 -07001569{
1570 struct st_buffer *STbp;
1571
1572 STbp = STp->buffer;
1573 if (STbp->do_dio) {
FUJITA Tomonori66207422008-12-18 14:49:43 +09001574 sgl_unmap_user_pages(STbp, STbp->do_dio, is_read);
Linus Torvalds1da177e2005-04-16 15:20:36 -07001575 STbp->do_dio = 0;
Kai Makisara787926b2005-11-13 10:04:44 +02001576 STbp->sg_segs = 0;
Linus Torvalds1da177e2005-04-16 15:20:36 -07001577 }
1578}
1579
1580
1581/* Write command */
1582static ssize_t
1583st_write(struct file *filp, const char __user *buf, size_t count, loff_t * ppos)
1584{
1585 ssize_t total;
1586 ssize_t i, do_count, blks, transfer;
1587 ssize_t retval;
1588 int undone, retry_eot = 0, scode;
1589 int async_write;
1590 unsigned char cmd[MAX_COMMAND_SIZE];
1591 const char __user *b_point;
Mike Christie8b05b772005-11-08 04:06:44 -06001592 struct st_request *SRpnt = NULL;
Linus Torvalds1da177e2005-04-16 15:20:36 -07001593 struct scsi_tape *STp = filp->private_data;
1594 struct st_modedef *STm;
1595 struct st_partstat *STps;
1596 struct st_buffer *STbp;
1597 char *name = tape_name(STp);
1598
Matthias Kaehlcke28f85002007-07-29 23:38:15 +02001599 if (mutex_lock_interruptible(&STp->lock))
Linus Torvalds1da177e2005-04-16 15:20:36 -07001600 return -ERESTARTSYS;
1601
1602 retval = rw_checks(STp, filp, count);
1603 if (retval || count == 0)
1604 goto out;
1605
1606 /* Write must be integral number of blocks */
1607 if (STp->block_size != 0 && (count % STp->block_size) != 0) {
1608 printk(KERN_WARNING "%s: Write not multiple of tape block size.\n",
1609 name);
1610 retval = (-EINVAL);
1611 goto out;
1612 }
1613
1614 STm = &(STp->modes[STp->current_mode]);
1615 STps = &(STp->ps[STp->partition]);
1616
1617 if (STp->write_prot) {
1618 retval = (-EACCES);
1619 goto out;
1620 }
1621
1622
1623 if (STps->rw == ST_READING) {
1624 retval = flush_buffer(STp, 0);
1625 if (retval)
1626 goto out;
1627 STps->rw = ST_WRITING;
1628 } else if (STps->rw != ST_WRITING &&
1629 STps->drv_file == 0 && STps->drv_block == 0) {
1630 if ((retval = set_mode_densblk(STp, STm)) < 0)
1631 goto out;
1632 if (STm->default_compression != ST_DONT_TOUCH &&
1633 !(STp->compression_changed)) {
1634 if (st_compression(STp, (STm->default_compression == ST_YES))) {
1635 printk(KERN_WARNING "%s: Can't set default compression.\n",
1636 name);
1637 if (modes_defined) {
1638 retval = (-EINVAL);
1639 goto out;
1640 }
1641 }
1642 }
1643 }
1644
1645 STbp = STp->buffer;
1646 i = write_behind_check(STp);
1647 if (i) {
1648 if (i == -ENOSPC)
1649 STps->eof = ST_EOM_OK;
1650 else
1651 STps->eof = ST_EOM_ERROR;
1652 }
1653
1654 if (STps->eof == ST_EOM_OK) {
1655 STps->eof = ST_EOD_1; /* allow next write */
1656 retval = (-ENOSPC);
1657 goto out;
1658 }
1659 else if (STps->eof == ST_EOM_ERROR) {
1660 retval = (-EIO);
1661 goto out;
1662 }
1663
1664 /* Check the buffer readability in cases where copy_user might catch
1665 the problems after some tape movement. */
1666 if (STp->block_size != 0 &&
1667 !STbp->do_dio &&
1668 (copy_from_user(&i, buf, 1) != 0 ||
1669 copy_from_user(&i, buf + count - 1, 1) != 0)) {
1670 retval = (-EFAULT);
1671 goto out;
1672 }
1673
1674 retval = setup_buffering(STp, buf, count, 0);
1675 if (retval)
1676 goto out;
1677
1678 total = count;
1679
1680 memset(cmd, 0, MAX_COMMAND_SIZE);
1681 cmd[0] = WRITE_6;
1682 cmd[1] = (STp->block_size != 0);
1683
1684 STps->rw = ST_WRITING;
1685
1686 b_point = buf;
1687 while (count > 0 && !retry_eot) {
1688
1689 if (STbp->do_dio) {
1690 do_count = count;
1691 }
1692 else {
1693 if (STp->block_size == 0)
1694 do_count = count;
1695 else {
1696 do_count = STbp->buffer_blocks * STp->block_size -
1697 STbp->buffer_bytes;
1698 if (do_count > count)
1699 do_count = count;
1700 }
1701
1702 i = append_to_buffer(b_point, STbp, do_count);
1703 if (i) {
1704 retval = i;
1705 goto out;
1706 }
1707 }
1708 count -= do_count;
1709 b_point += do_count;
1710
1711 async_write = STp->block_size == 0 && !STbp->do_dio &&
1712 STm->do_async_writes && STps->eof < ST_EOM_OK;
1713
1714 if (STp->block_size != 0 && STm->do_buffer_writes &&
Kai Makisara9abe16c2007-02-03 13:21:29 +02001715 !(STp->try_dio_now && try_wdio) && STps->eof < ST_EOM_OK &&
Linus Torvalds1da177e2005-04-16 15:20:36 -07001716 STbp->buffer_bytes < STbp->buffer_size) {
1717 STp->dirty = 1;
1718 /* Don't write a buffer that is not full enough. */
1719 if (!async_write && count == 0)
1720 break;
1721 }
1722
1723 retry_write:
1724 if (STp->block_size == 0)
1725 blks = transfer = do_count;
1726 else {
1727 if (!STbp->do_dio)
1728 blks = STbp->buffer_bytes;
1729 else
1730 blks = do_count;
1731 blks /= STp->block_size;
1732 transfer = blks * STp->block_size;
1733 }
1734 cmd[2] = blks >> 16;
1735 cmd[3] = blks >> 8;
1736 cmd[4] = blks;
1737
1738 SRpnt = st_do_scsi(SRpnt, STp, cmd, transfer, DMA_TO_DEVICE,
James Bottomleya02488e2008-11-30 10:36:26 -06001739 STp->device->request_queue->rq_timeout,
1740 MAX_WRITE_RETRIES, !async_write);
Linus Torvalds1da177e2005-04-16 15:20:36 -07001741 if (!SRpnt) {
1742 retval = STbp->syscall_result;
1743 goto out;
1744 }
Mike Christie8b05b772005-11-08 04:06:44 -06001745 if (async_write && !STbp->syscall_result) {
Linus Torvalds1da177e2005-04-16 15:20:36 -07001746 STbp->writing = transfer;
1747 STp->dirty = !(STbp->writing ==
1748 STbp->buffer_bytes);
1749 SRpnt = NULL; /* Prevent releasing this request! */
1750 DEB( STp->write_pending = 1; )
1751 break;
1752 }
1753
1754 if (STbp->syscall_result != 0) {
1755 struct st_cmdstatus *cmdstatp = &STp->buffer->cmdstat;
1756
1757 DEBC(printk(ST_DEB_MSG "%s: Error on write:\n", name));
1758 if (cmdstatp->have_sense && (cmdstatp->flags & SENSE_EOM)) {
1759 scode = cmdstatp->sense_hdr.sense_key;
1760 if (cmdstatp->remainder_valid)
1761 undone = (int)cmdstatp->uremainder64;
1762 else if (STp->block_size == 0 &&
1763 scode == VOLUME_OVERFLOW)
1764 undone = transfer;
1765 else
1766 undone = 0;
1767 if (STp->block_size != 0)
1768 undone *= STp->block_size;
1769 if (undone <= do_count) {
1770 /* Only data from this write is not written */
1771 count += undone;
Kai Makisara626dcb12008-07-11 15:05:25 +03001772 b_point -= undone;
Linus Torvalds1da177e2005-04-16 15:20:36 -07001773 do_count -= undone;
1774 if (STp->block_size)
1775 blks = (transfer - undone) / STp->block_size;
1776 STps->eof = ST_EOM_OK;
1777 /* Continue in fixed block mode if all written
1778 in this request but still something left to write
1779 (retval left to zero)
1780 */
1781 if (STp->block_size == 0 ||
1782 undone > 0 || count == 0)
1783 retval = (-ENOSPC); /* EOM within current request */
1784 DEBC(printk(ST_DEB_MSG
1785 "%s: EOM with %d bytes unwritten.\n",
1786 name, (int)count));
1787 } else {
1788 /* EOT within data buffered earlier (possible only
1789 in fixed block mode without direct i/o) */
1790 if (!retry_eot && !cmdstatp->deferred &&
1791 (scode == NO_SENSE || scode == RECOVERED_ERROR)) {
1792 move_buffer_data(STp->buffer, transfer - undone);
1793 retry_eot = 1;
1794 if (STps->drv_block >= 0) {
1795 STps->drv_block += (transfer - undone) /
1796 STp->block_size;
1797 }
1798 STps->eof = ST_EOM_OK;
1799 DEBC(printk(ST_DEB_MSG
1800 "%s: Retry write of %d bytes at EOM.\n",
1801 name, STp->buffer->buffer_bytes));
1802 goto retry_write;
1803 }
1804 else {
1805 /* Either error within data buffered by driver or
1806 failed retry */
1807 count -= do_count;
1808 blks = do_count = 0;
1809 STps->eof = ST_EOM_ERROR;
1810 STps->drv_block = (-1); /* Too cautious? */
1811 retval = (-EIO); /* EOM for old data */
1812 DEBC(printk(ST_DEB_MSG
1813 "%s: EOM with lost data.\n",
1814 name));
1815 }
1816 }
1817 } else {
1818 count += do_count;
1819 STps->drv_block = (-1); /* Too cautious? */
Mike Christie8b05b772005-11-08 04:06:44 -06001820 retval = STbp->syscall_result;
Linus Torvalds1da177e2005-04-16 15:20:36 -07001821 }
1822
1823 }
1824
1825 if (STps->drv_block >= 0) {
1826 if (STp->block_size == 0)
1827 STps->drv_block += (do_count > 0);
1828 else
1829 STps->drv_block += blks;
1830 }
1831
1832 STbp->buffer_bytes = 0;
1833 STp->dirty = 0;
1834
1835 if (retval || retry_eot) {
1836 if (count < total)
1837 retval = total - count;
1838 goto out;
1839 }
1840 }
1841
1842 if (STps->eof == ST_EOD_1)
1843 STps->eof = ST_EOM_OK;
1844 else if (STps->eof != ST_EOM_OK)
1845 STps->eof = ST_NOEOF;
1846 retval = total - count;
1847
1848 out:
1849 if (SRpnt != NULL)
Mike Christie8b05b772005-11-08 04:06:44 -06001850 st_release_request(SRpnt);
Kai Makisara787926b2005-11-13 10:04:44 +02001851 release_buffering(STp, 0);
Matthias Kaehlcke28f85002007-07-29 23:38:15 +02001852 mutex_unlock(&STp->lock);
Linus Torvalds1da177e2005-04-16 15:20:36 -07001853
1854 return retval;
1855}
1856
1857/* Read data from the tape. Returns zero in the normal case, one if the
1858 eof status has changed, and the negative error code in case of a
1859 fatal error. Otherwise updates the buffer and the eof state.
1860
1861 Does release user buffer mapping if it is set.
1862*/
1863static long read_tape(struct scsi_tape *STp, long count,
Mike Christie8b05b772005-11-08 04:06:44 -06001864 struct st_request ** aSRpnt)
Linus Torvalds1da177e2005-04-16 15:20:36 -07001865{
1866 int transfer, blks, bytes;
1867 unsigned char cmd[MAX_COMMAND_SIZE];
Mike Christie8b05b772005-11-08 04:06:44 -06001868 struct st_request *SRpnt;
Linus Torvalds1da177e2005-04-16 15:20:36 -07001869 struct st_modedef *STm;
1870 struct st_partstat *STps;
1871 struct st_buffer *STbp;
1872 int retval = 0;
1873 char *name = tape_name(STp);
1874
1875 if (count == 0)
1876 return 0;
1877
1878 STm = &(STp->modes[STp->current_mode]);
1879 STps = &(STp->ps[STp->partition]);
1880 if (STps->eof == ST_FM_HIT)
1881 return 1;
1882 STbp = STp->buffer;
1883
1884 if (STp->block_size == 0)
1885 blks = bytes = count;
1886 else {
Kai Makisara9abe16c2007-02-03 13:21:29 +02001887 if (!(STp->try_dio_now && try_rdio) && STm->do_read_ahead) {
Linus Torvalds1da177e2005-04-16 15:20:36 -07001888 blks = (STp->buffer)->buffer_blocks;
1889 bytes = blks * STp->block_size;
1890 } else {
1891 bytes = count;
1892 if (!STbp->do_dio && bytes > (STp->buffer)->buffer_size)
1893 bytes = (STp->buffer)->buffer_size;
1894 blks = bytes / STp->block_size;
1895 bytes = blks * STp->block_size;
1896 }
1897 }
1898
1899 memset(cmd, 0, MAX_COMMAND_SIZE);
1900 cmd[0] = READ_6;
1901 cmd[1] = (STp->block_size != 0);
Kai Makisara40f6b362008-02-24 22:23:24 +02001902 if (!cmd[1] && STp->sili)
1903 cmd[1] |= 2;
Linus Torvalds1da177e2005-04-16 15:20:36 -07001904 cmd[2] = blks >> 16;
1905 cmd[3] = blks >> 8;
1906 cmd[4] = blks;
1907
1908 SRpnt = *aSRpnt;
1909 SRpnt = st_do_scsi(SRpnt, STp, cmd, bytes, DMA_FROM_DEVICE,
James Bottomleya02488e2008-11-30 10:36:26 -06001910 STp->device->request_queue->rq_timeout,
1911 MAX_RETRIES, 1);
Kai Makisara787926b2005-11-13 10:04:44 +02001912 release_buffering(STp, 1);
Linus Torvalds1da177e2005-04-16 15:20:36 -07001913 *aSRpnt = SRpnt;
1914 if (!SRpnt)
1915 return STbp->syscall_result;
1916
1917 STbp->read_pointer = 0;
1918 STps->at_sm = 0;
1919
1920 /* Something to check */
1921 if (STbp->syscall_result) {
1922 struct st_cmdstatus *cmdstatp = &STp->buffer->cmdstat;
1923
1924 retval = 1;
1925 DEBC(printk(ST_DEB_MSG "%s: Sense: %2x %2x %2x %2x %2x %2x %2x %2x\n",
1926 name,
Mike Christie8b05b772005-11-08 04:06:44 -06001927 SRpnt->sense[0], SRpnt->sense[1],
1928 SRpnt->sense[2], SRpnt->sense[3],
1929 SRpnt->sense[4], SRpnt->sense[5],
1930 SRpnt->sense[6], SRpnt->sense[7]));
Linus Torvalds1da177e2005-04-16 15:20:36 -07001931 if (cmdstatp->have_sense) {
1932
1933 if (cmdstatp->sense_hdr.sense_key == BLANK_CHECK)
1934 cmdstatp->flags &= 0xcf; /* No need for EOM in this case */
1935
1936 if (cmdstatp->flags != 0) { /* EOF, EOM, or ILI */
1937 /* Compute the residual count */
1938 if (cmdstatp->remainder_valid)
1939 transfer = (int)cmdstatp->uremainder64;
1940 else
1941 transfer = 0;
1942 if (STp->block_size == 0 &&
1943 cmdstatp->sense_hdr.sense_key == MEDIUM_ERROR)
1944 transfer = bytes;
1945
1946 if (cmdstatp->flags & SENSE_ILI) { /* ILI */
1947 if (STp->block_size == 0) {
1948 if (transfer <= 0) {
1949 if (transfer < 0)
1950 printk(KERN_NOTICE
1951 "%s: Failed to read %d byte block with %d byte transfer.\n",
1952 name, bytes - transfer, bytes);
1953 if (STps->drv_block >= 0)
1954 STps->drv_block += 1;
1955 STbp->buffer_bytes = 0;
1956 return (-ENOMEM);
1957 }
1958 STbp->buffer_bytes = bytes - transfer;
1959 } else {
Mike Christie8b05b772005-11-08 04:06:44 -06001960 st_release_request(SRpnt);
Linus Torvalds1da177e2005-04-16 15:20:36 -07001961 SRpnt = *aSRpnt = NULL;
1962 if (transfer == blks) { /* We did not get anything, error */
1963 printk(KERN_NOTICE "%s: Incorrect block size.\n", name);
1964 if (STps->drv_block >= 0)
1965 STps->drv_block += blks - transfer + 1;
1966 st_int_ioctl(STp, MTBSR, 1);
1967 return (-EIO);
1968 }
1969 /* We have some data, deliver it */
1970 STbp->buffer_bytes = (blks - transfer) *
1971 STp->block_size;
1972 DEBC(printk(ST_DEB_MSG
1973 "%s: ILI but enough data received %ld %d.\n",
1974 name, count, STbp->buffer_bytes));
1975 if (STps->drv_block >= 0)
1976 STps->drv_block += 1;
1977 if (st_int_ioctl(STp, MTBSR, 1))
1978 return (-EIO);
1979 }
1980 } else if (cmdstatp->flags & SENSE_FMK) { /* FM overrides EOM */
1981 if (STps->eof != ST_FM_HIT)
1982 STps->eof = ST_FM_HIT;
1983 else
1984 STps->eof = ST_EOD_2;
1985 if (STp->block_size == 0)
1986 STbp->buffer_bytes = 0;
1987 else
1988 STbp->buffer_bytes =
1989 bytes - transfer * STp->block_size;
1990 DEBC(printk(ST_DEB_MSG
1991 "%s: EOF detected (%d bytes read).\n",
1992 name, STbp->buffer_bytes));
1993 } else if (cmdstatp->flags & SENSE_EOM) {
1994 if (STps->eof == ST_FM)
1995 STps->eof = ST_EOD_1;
1996 else
1997 STps->eof = ST_EOM_OK;
1998 if (STp->block_size == 0)
1999 STbp->buffer_bytes = bytes - transfer;
2000 else
2001 STbp->buffer_bytes =
2002 bytes - transfer * STp->block_size;
2003
2004 DEBC(printk(ST_DEB_MSG "%s: EOM detected (%d bytes read).\n",
2005 name, STbp->buffer_bytes));
2006 }
2007 }
2008 /* end of EOF, EOM, ILI test */
2009 else { /* nonzero sense key */
2010 DEBC(printk(ST_DEB_MSG
2011 "%s: Tape error while reading.\n", name));
2012 STps->drv_block = (-1);
2013 if (STps->eof == ST_FM &&
2014 cmdstatp->sense_hdr.sense_key == BLANK_CHECK) {
2015 DEBC(printk(ST_DEB_MSG
2016 "%s: Zero returned for first BLANK CHECK after EOF.\n",
2017 name));
2018 STps->eof = ST_EOD_2; /* First BLANK_CHECK after FM */
2019 } else /* Some other extended sense code */
2020 retval = (-EIO);
2021 }
2022
2023 if (STbp->buffer_bytes < 0) /* Caused by bogus sense data */
2024 STbp->buffer_bytes = 0;
2025 }
2026 /* End of extended sense test */
2027 else { /* Non-extended sense */
2028 retval = STbp->syscall_result;
2029 }
2030
2031 }
2032 /* End of error handling */
Kai Makisara40f6b362008-02-24 22:23:24 +02002033 else { /* Read successful */
Linus Torvalds1da177e2005-04-16 15:20:36 -07002034 STbp->buffer_bytes = bytes;
Kai Makisara40f6b362008-02-24 22:23:24 +02002035 if (STp->sili) /* In fixed block mode residual is always zero here */
2036 STbp->buffer_bytes -= STp->buffer->cmdstat.residual;
2037 }
Linus Torvalds1da177e2005-04-16 15:20:36 -07002038
2039 if (STps->drv_block >= 0) {
2040 if (STp->block_size == 0)
2041 STps->drv_block++;
2042 else
2043 STps->drv_block += STbp->buffer_bytes / STp->block_size;
2044 }
2045 return retval;
2046}
2047
2048
2049/* Read command */
2050static ssize_t
2051st_read(struct file *filp, char __user *buf, size_t count, loff_t * ppos)
2052{
2053 ssize_t total;
2054 ssize_t retval = 0;
2055 ssize_t i, transfer;
2056 int special, do_dio = 0;
Mike Christie8b05b772005-11-08 04:06:44 -06002057 struct st_request *SRpnt = NULL;
Linus Torvalds1da177e2005-04-16 15:20:36 -07002058 struct scsi_tape *STp = filp->private_data;
2059 struct st_modedef *STm;
2060 struct st_partstat *STps;
2061 struct st_buffer *STbp = STp->buffer;
2062 DEB( char *name = tape_name(STp); )
2063
Matthias Kaehlcke28f85002007-07-29 23:38:15 +02002064 if (mutex_lock_interruptible(&STp->lock))
Linus Torvalds1da177e2005-04-16 15:20:36 -07002065 return -ERESTARTSYS;
2066
2067 retval = rw_checks(STp, filp, count);
2068 if (retval || count == 0)
2069 goto out;
2070
2071 STm = &(STp->modes[STp->current_mode]);
Kai Makisara9abe16c2007-02-03 13:21:29 +02002072 if (STp->block_size != 0 && (count % STp->block_size) != 0) {
2073 if (!STm->do_read_ahead) {
2074 retval = (-EINVAL); /* Read must be integral number of blocks */
2075 goto out;
2076 }
2077 STp->try_dio_now = 0; /* Direct i/o can't handle split blocks */
Linus Torvalds1da177e2005-04-16 15:20:36 -07002078 }
2079
2080 STps = &(STp->ps[STp->partition]);
2081 if (STps->rw == ST_WRITING) {
2082 retval = flush_buffer(STp, 0);
2083 if (retval)
2084 goto out;
2085 STps->rw = ST_READING;
2086 }
2087 DEB(
2088 if (debugging && STps->eof != ST_NOEOF)
2089 printk(ST_DEB_MSG "%s: EOF/EOM flag up (%d). Bytes %d\n", name,
2090 STps->eof, STbp->buffer_bytes);
2091 ) /* end DEB */
2092
2093 retval = setup_buffering(STp, buf, count, 1);
2094 if (retval)
2095 goto out;
2096 do_dio = STbp->do_dio;
2097
2098 if (STbp->buffer_bytes == 0 &&
2099 STps->eof >= ST_EOD_1) {
2100 if (STps->eof < ST_EOD) {
2101 STps->eof += 1;
2102 retval = 0;
2103 goto out;
2104 }
2105 retval = (-EIO); /* EOM or Blank Check */
2106 goto out;
2107 }
2108
2109 if (do_dio) {
2110 /* Check the buffer writability before any tape movement. Don't alter
2111 buffer data. */
2112 if (copy_from_user(&i, buf, 1) != 0 ||
2113 copy_to_user(buf, &i, 1) != 0 ||
2114 copy_from_user(&i, buf + count - 1, 1) != 0 ||
2115 copy_to_user(buf + count - 1, &i, 1) != 0) {
2116 retval = (-EFAULT);
2117 goto out;
2118 }
2119 }
2120
2121 STps->rw = ST_READING;
2122
2123
2124 /* Loop until enough data in buffer or a special condition found */
2125 for (total = 0, special = 0; total < count && !special;) {
2126
2127 /* Get new data if the buffer is empty */
2128 if (STbp->buffer_bytes == 0) {
2129 special = read_tape(STp, count - total, &SRpnt);
2130 if (special < 0) { /* No need to continue read */
2131 retval = special;
2132 goto out;
2133 }
2134 }
2135
2136 /* Move the data from driver buffer to user buffer */
2137 if (STbp->buffer_bytes > 0) {
2138 DEB(
2139 if (debugging && STps->eof != ST_NOEOF)
2140 printk(ST_DEB_MSG
2141 "%s: EOF up (%d). Left %d, needed %d.\n", name,
2142 STps->eof, STbp->buffer_bytes,
2143 (int)(count - total));
2144 ) /* end DEB */
2145 transfer = STbp->buffer_bytes < count - total ?
2146 STbp->buffer_bytes : count - total;
2147 if (!do_dio) {
2148 i = from_buffer(STbp, buf, transfer);
2149 if (i) {
2150 retval = i;
2151 goto out;
2152 }
2153 }
2154 buf += transfer;
2155 total += transfer;
2156 }
2157
2158 if (STp->block_size == 0)
2159 break; /* Read only one variable length block */
2160
2161 } /* for (total = 0, special = 0;
2162 total < count && !special; ) */
2163
2164 /* Change the eof state if no data from tape or buffer */
2165 if (total == 0) {
2166 if (STps->eof == ST_FM_HIT) {
2167 STps->eof = ST_FM;
2168 STps->drv_block = 0;
2169 if (STps->drv_file >= 0)
2170 STps->drv_file++;
2171 } else if (STps->eof == ST_EOD_1) {
2172 STps->eof = ST_EOD_2;
2173 STps->drv_block = 0;
2174 if (STps->drv_file >= 0)
2175 STps->drv_file++;
2176 } else if (STps->eof == ST_EOD_2)
2177 STps->eof = ST_EOD;
2178 } else if (STps->eof == ST_FM)
2179 STps->eof = ST_NOEOF;
2180 retval = total;
2181
2182 out:
2183 if (SRpnt != NULL) {
Mike Christie8b05b772005-11-08 04:06:44 -06002184 st_release_request(SRpnt);
Linus Torvalds1da177e2005-04-16 15:20:36 -07002185 SRpnt = NULL;
2186 }
2187 if (do_dio) {
Kai Makisara787926b2005-11-13 10:04:44 +02002188 release_buffering(STp, 1);
Linus Torvalds1da177e2005-04-16 15:20:36 -07002189 STbp->buffer_bytes = 0;
2190 }
Matthias Kaehlcke28f85002007-07-29 23:38:15 +02002191 mutex_unlock(&STp->lock);
Linus Torvalds1da177e2005-04-16 15:20:36 -07002192
2193 return retval;
2194}
2195
2196
2197
2198DEB(
2199/* Set the driver options */
2200static void st_log_options(struct scsi_tape * STp, struct st_modedef * STm, char *name)
2201{
2202 if (debugging) {
2203 printk(KERN_INFO
2204 "%s: Mode %d options: buffer writes: %d, async writes: %d, read ahead: %d\n",
2205 name, STp->current_mode, STm->do_buffer_writes, STm->do_async_writes,
2206 STm->do_read_ahead);
2207 printk(KERN_INFO
2208 "%s: can bsr: %d, two FMs: %d, fast mteom: %d, auto lock: %d,\n",
2209 name, STp->can_bsr, STp->two_fm, STp->fast_mteom, STp->do_auto_lock);
2210 printk(KERN_INFO
2211 "%s: defs for wr: %d, no block limits: %d, partitions: %d, s2 log: %d\n",
2212 name, STm->defaults_for_writes, STp->omit_blklims, STp->can_partitions,
2213 STp->scsi2_logical);
2214 printk(KERN_INFO
Kai Makisara40f6b362008-02-24 22:23:24 +02002215 "%s: sysv: %d nowait: %d sili: %d\n", name, STm->sysv, STp->immediate,
2216 STp->sili);
Linus Torvalds1da177e2005-04-16 15:20:36 -07002217 printk(KERN_INFO "%s: debugging: %d\n",
2218 name, debugging);
2219 }
2220}
2221 )
2222
2223
2224static int st_set_options(struct scsi_tape *STp, long options)
2225{
2226 int value;
2227 long code;
2228 struct st_modedef *STm;
2229 char *name = tape_name(STp);
2230 struct cdev *cd0, *cd1;
2231
2232 STm = &(STp->modes[STp->current_mode]);
2233 if (!STm->defined) {
2234 cd0 = STm->cdevs[0]; cd1 = STm->cdevs[1];
2235 memcpy(STm, &(STp->modes[0]), sizeof(struct st_modedef));
2236 STm->cdevs[0] = cd0; STm->cdevs[1] = cd1;
2237 modes_defined = 1;
2238 DEBC(printk(ST_DEB_MSG
2239 "%s: Initialized mode %d definition from mode 0\n",
2240 name, STp->current_mode));
2241 }
2242
2243 code = options & MT_ST_OPTIONS;
2244 if (code == MT_ST_BOOLEANS) {
2245 STm->do_buffer_writes = (options & MT_ST_BUFFER_WRITES) != 0;
2246 STm->do_async_writes = (options & MT_ST_ASYNC_WRITES) != 0;
2247 STm->defaults_for_writes = (options & MT_ST_DEF_WRITES) != 0;
2248 STm->do_read_ahead = (options & MT_ST_READ_AHEAD) != 0;
2249 STp->two_fm = (options & MT_ST_TWO_FM) != 0;
2250 STp->fast_mteom = (options & MT_ST_FAST_MTEOM) != 0;
2251 STp->do_auto_lock = (options & MT_ST_AUTO_LOCK) != 0;
2252 STp->can_bsr = (options & MT_ST_CAN_BSR) != 0;
2253 STp->omit_blklims = (options & MT_ST_NO_BLKLIMS) != 0;
2254 if ((STp->device)->scsi_level >= SCSI_2)
2255 STp->can_partitions = (options & MT_ST_CAN_PARTITIONS) != 0;
2256 STp->scsi2_logical = (options & MT_ST_SCSI2LOGICAL) != 0;
2257 STp->immediate = (options & MT_ST_NOWAIT) != 0;
2258 STm->sysv = (options & MT_ST_SYSV) != 0;
Kai Makisara40f6b362008-02-24 22:23:24 +02002259 STp->sili = (options & MT_ST_SILI) != 0;
Linus Torvalds1da177e2005-04-16 15:20:36 -07002260 DEB( debugging = (options & MT_ST_DEBUGGING) != 0;
2261 st_log_options(STp, STm, name); )
2262 } else if (code == MT_ST_SETBOOLEANS || code == MT_ST_CLEARBOOLEANS) {
2263 value = (code == MT_ST_SETBOOLEANS);
2264 if ((options & MT_ST_BUFFER_WRITES) != 0)
2265 STm->do_buffer_writes = value;
2266 if ((options & MT_ST_ASYNC_WRITES) != 0)
2267 STm->do_async_writes = value;
2268 if ((options & MT_ST_DEF_WRITES) != 0)
2269 STm->defaults_for_writes = value;
2270 if ((options & MT_ST_READ_AHEAD) != 0)
2271 STm->do_read_ahead = value;
2272 if ((options & MT_ST_TWO_FM) != 0)
2273 STp->two_fm = value;
2274 if ((options & MT_ST_FAST_MTEOM) != 0)
2275 STp->fast_mteom = value;
2276 if ((options & MT_ST_AUTO_LOCK) != 0)
2277 STp->do_auto_lock = value;
2278 if ((options & MT_ST_CAN_BSR) != 0)
2279 STp->can_bsr = value;
2280 if ((options & MT_ST_NO_BLKLIMS) != 0)
2281 STp->omit_blklims = value;
2282 if ((STp->device)->scsi_level >= SCSI_2 &&
2283 (options & MT_ST_CAN_PARTITIONS) != 0)
2284 STp->can_partitions = value;
2285 if ((options & MT_ST_SCSI2LOGICAL) != 0)
2286 STp->scsi2_logical = value;
2287 if ((options & MT_ST_NOWAIT) != 0)
2288 STp->immediate = value;
2289 if ((options & MT_ST_SYSV) != 0)
2290 STm->sysv = value;
Kai Makisara40f6b362008-02-24 22:23:24 +02002291 if ((options & MT_ST_SILI) != 0)
2292 STp->sili = value;
Linus Torvalds1da177e2005-04-16 15:20:36 -07002293 DEB(
2294 if ((options & MT_ST_DEBUGGING) != 0)
2295 debugging = value;
2296 st_log_options(STp, STm, name); )
2297 } else if (code == MT_ST_WRITE_THRESHOLD) {
2298 /* Retained for compatibility */
2299 } else if (code == MT_ST_DEF_BLKSIZE) {
2300 value = (options & ~MT_ST_OPTIONS);
2301 if (value == ~MT_ST_OPTIONS) {
2302 STm->default_blksize = (-1);
2303 DEBC( printk(KERN_INFO "%s: Default block size disabled.\n", name));
2304 } else {
2305 STm->default_blksize = value;
2306 DEBC( printk(KERN_INFO "%s: Default block size set to %d bytes.\n",
2307 name, STm->default_blksize));
2308 if (STp->ready == ST_READY) {
2309 STp->blksize_changed = 0;
2310 set_mode_densblk(STp, STm);
2311 }
2312 }
2313 } else if (code == MT_ST_TIMEOUTS) {
2314 value = (options & ~MT_ST_OPTIONS);
2315 if ((value & MT_ST_SET_LONG_TIMEOUT) != 0) {
2316 STp->long_timeout = (value & ~MT_ST_SET_LONG_TIMEOUT) * HZ;
2317 DEBC( printk(KERN_INFO "%s: Long timeout set to %d seconds.\n", name,
2318 (value & ~MT_ST_SET_LONG_TIMEOUT)));
2319 } else {
James Bottomleya02488e2008-11-30 10:36:26 -06002320 blk_queue_rq_timeout(STp->device->request_queue,
2321 value * HZ);
Linus Torvalds1da177e2005-04-16 15:20:36 -07002322 DEBC( printk(KERN_INFO "%s: Normal timeout set to %d seconds.\n",
2323 name, value) );
2324 }
2325 } else if (code == MT_ST_SET_CLN) {
2326 value = (options & ~MT_ST_OPTIONS) & 0xff;
2327 if (value != 0 &&
2328 value < EXTENDED_SENSE_START && value >= SCSI_SENSE_BUFFERSIZE)
2329 return (-EINVAL);
2330 STp->cln_mode = value;
2331 STp->cln_sense_mask = (options >> 8) & 0xff;
2332 STp->cln_sense_value = (options >> 16) & 0xff;
2333 printk(KERN_INFO
2334 "%s: Cleaning request mode %d, mask %02x, value %02x\n",
2335 name, value, STp->cln_sense_mask, STp->cln_sense_value);
2336 } else if (code == MT_ST_DEF_OPTIONS) {
2337 code = (options & ~MT_ST_CLEAR_DEFAULT);
2338 value = (options & MT_ST_CLEAR_DEFAULT);
2339 if (code == MT_ST_DEF_DENSITY) {
2340 if (value == MT_ST_CLEAR_DEFAULT) {
2341 STm->default_density = (-1);
2342 DEBC( printk(KERN_INFO "%s: Density default disabled.\n",
2343 name));
2344 } else {
2345 STm->default_density = value & 0xff;
2346 DEBC( printk(KERN_INFO "%s: Density default set to %x\n",
2347 name, STm->default_density));
2348 if (STp->ready == ST_READY) {
2349 STp->density_changed = 0;
2350 set_mode_densblk(STp, STm);
2351 }
2352 }
2353 } else if (code == MT_ST_DEF_DRVBUFFER) {
2354 if (value == MT_ST_CLEAR_DEFAULT) {
2355 STp->default_drvbuffer = 0xff;
2356 DEBC( printk(KERN_INFO
2357 "%s: Drive buffer default disabled.\n", name));
2358 } else {
2359 STp->default_drvbuffer = value & 7;
2360 DEBC( printk(KERN_INFO
2361 "%s: Drive buffer default set to %x\n",
2362 name, STp->default_drvbuffer));
2363 if (STp->ready == ST_READY)
2364 st_int_ioctl(STp, MTSETDRVBUFFER, STp->default_drvbuffer);
2365 }
2366 } else if (code == MT_ST_DEF_COMPRESSION) {
2367 if (value == MT_ST_CLEAR_DEFAULT) {
2368 STm->default_compression = ST_DONT_TOUCH;
2369 DEBC( printk(KERN_INFO
2370 "%s: Compression default disabled.\n", name));
2371 } else {
2372 if ((value & 0xff00) != 0) {
2373 STp->c_algo = (value & 0xff00) >> 8;
2374 DEBC( printk(KERN_INFO "%s: Compression algorithm set to 0x%x.\n",
2375 name, STp->c_algo));
2376 }
2377 if ((value & 0xff) != 0xff) {
2378 STm->default_compression = (value & 1 ? ST_YES : ST_NO);
2379 DEBC( printk(KERN_INFO "%s: Compression default set to %x\n",
2380 name, (value & 1)));
2381 if (STp->ready == ST_READY) {
2382 STp->compression_changed = 0;
2383 st_compression(STp, (STm->default_compression == ST_YES));
2384 }
2385 }
2386 }
2387 }
2388 } else
2389 return (-EIO);
2390
2391 return 0;
2392}
2393
2394#define MODE_HEADER_LENGTH 4
2395
2396/* Mode header and page byte offsets */
2397#define MH_OFF_DATA_LENGTH 0
2398#define MH_OFF_MEDIUM_TYPE 1
2399#define MH_OFF_DEV_SPECIFIC 2
2400#define MH_OFF_BDESCS_LENGTH 3
2401#define MP_OFF_PAGE_NBR 0
2402#define MP_OFF_PAGE_LENGTH 1
2403
2404/* Mode header and page bit masks */
2405#define MH_BIT_WP 0x80
2406#define MP_MSK_PAGE_NBR 0x3f
2407
2408/* Don't return block descriptors */
2409#define MODE_SENSE_OMIT_BDESCS 0x08
2410
2411#define MODE_SELECT_PAGE_FORMAT 0x10
2412
2413/* Read a mode page into the tape buffer. The block descriptors are included
2414 if incl_block_descs is true. The page control is ored to the page number
2415 parameter, if necessary. */
2416static int read_mode_page(struct scsi_tape *STp, int page, int omit_block_descs)
2417{
2418 unsigned char cmd[MAX_COMMAND_SIZE];
FUJITA Tomonori8ecf0d92008-12-05 15:25:28 +09002419 struct st_request *SRpnt;
2420 int ret;
Linus Torvalds1da177e2005-04-16 15:20:36 -07002421
2422 memset(cmd, 0, MAX_COMMAND_SIZE);
2423 cmd[0] = MODE_SENSE;
2424 if (omit_block_descs)
2425 cmd[1] = MODE_SENSE_OMIT_BDESCS;
2426 cmd[2] = page;
2427 cmd[4] = 255;
2428
FUJITA Tomonori8ecf0d92008-12-05 15:25:28 +09002429 SRpnt = st_allocate_request(STp);
2430 if (!SRpnt)
2431 return STp->buffer->syscall_result;
Linus Torvalds1da177e2005-04-16 15:20:36 -07002432
FUJITA Tomonori8ecf0d92008-12-05 15:25:28 +09002433 ret = st_scsi_kern_execute(SRpnt, cmd, DMA_FROM_DEVICE,
2434 STp->buffer->b_data, cmd[4],
2435 STp->device->request_queue->rq_timeout,
2436 MAX_RETRIES);
Mike Christie8b05b772005-11-08 04:06:44 -06002437 st_release_request(SRpnt);
Linus Torvalds1da177e2005-04-16 15:20:36 -07002438
FUJITA Tomonori8ecf0d92008-12-05 15:25:28 +09002439 return ret ? : STp->buffer->syscall_result;
Linus Torvalds1da177e2005-04-16 15:20:36 -07002440}
2441
2442
2443/* Send the mode page in the tape buffer to the drive. Assumes that the mode data
2444 in the buffer is correctly formatted. The long timeout is used if slow is non-zero. */
2445static int write_mode_page(struct scsi_tape *STp, int page, int slow)
2446{
FUJITA Tomonori18c87012008-12-05 15:25:29 +09002447 int pgo, timeout, ret = 0;
Linus Torvalds1da177e2005-04-16 15:20:36 -07002448 unsigned char cmd[MAX_COMMAND_SIZE];
FUJITA Tomonori18c87012008-12-05 15:25:29 +09002449 struct st_request *SRpnt;
Linus Torvalds1da177e2005-04-16 15:20:36 -07002450
2451 memset(cmd, 0, MAX_COMMAND_SIZE);
2452 cmd[0] = MODE_SELECT;
2453 cmd[1] = MODE_SELECT_PAGE_FORMAT;
2454 pgo = MODE_HEADER_LENGTH + (STp->buffer)->b_data[MH_OFF_BDESCS_LENGTH];
2455 cmd[4] = pgo + (STp->buffer)->b_data[pgo + MP_OFF_PAGE_LENGTH] + 2;
2456
2457 /* Clear reserved fields */
2458 (STp->buffer)->b_data[MH_OFF_DATA_LENGTH] = 0;
2459 (STp->buffer)->b_data[MH_OFF_MEDIUM_TYPE] = 0;
2460 (STp->buffer)->b_data[MH_OFF_DEV_SPECIFIC] &= ~MH_BIT_WP;
2461 (STp->buffer)->b_data[pgo + MP_OFF_PAGE_NBR] &= MP_MSK_PAGE_NBR;
2462
FUJITA Tomonori18c87012008-12-05 15:25:29 +09002463 SRpnt = st_allocate_request(STp);
2464 if (!SRpnt)
2465 return ret;
2466
2467 timeout = slow ? STp->long_timeout :
2468 STp->device->request_queue->rq_timeout;
2469
2470 ret = st_scsi_kern_execute(SRpnt, cmd, DMA_TO_DEVICE,
2471 STp->buffer->b_data, cmd[4], timeout, 0);
2472 if (!ret)
2473 ret = STp->buffer->syscall_result;
Linus Torvalds1da177e2005-04-16 15:20:36 -07002474
Mike Christie8b05b772005-11-08 04:06:44 -06002475 st_release_request(SRpnt);
Linus Torvalds1da177e2005-04-16 15:20:36 -07002476
FUJITA Tomonori18c87012008-12-05 15:25:29 +09002477 return ret;
Linus Torvalds1da177e2005-04-16 15:20:36 -07002478}
2479
2480
2481#define COMPRESSION_PAGE 0x0f
2482#define COMPRESSION_PAGE_LENGTH 16
2483
2484#define CP_OFF_DCE_DCC 2
2485#define CP_OFF_C_ALGO 7
2486
2487#define DCE_MASK 0x80
2488#define DCC_MASK 0x40
2489#define RED_MASK 0x60
2490
2491
2492/* Control the compression with mode page 15. Algorithm not changed if zero.
2493
2494 The block descriptors are read and written because Sony SDT-7000 does not
2495 work without this (suggestion from Michael Schaefer <Michael.Schaefer@dlr.de>).
2496 Including block descriptors should not cause any harm to other drives. */
2497
2498static int st_compression(struct scsi_tape * STp, int state)
2499{
2500 int retval;
2501 int mpoffs; /* Offset to mode page start */
2502 unsigned char *b_data = (STp->buffer)->b_data;
2503 DEB( char *name = tape_name(STp); )
2504
2505 if (STp->ready != ST_READY)
2506 return (-EIO);
2507
2508 /* Read the current page contents */
2509 retval = read_mode_page(STp, COMPRESSION_PAGE, 0);
2510 if (retval) {
2511 DEBC(printk(ST_DEB_MSG "%s: Compression mode page not supported.\n",
2512 name));
2513 return (-EIO);
2514 }
2515
2516 mpoffs = MODE_HEADER_LENGTH + b_data[MH_OFF_BDESCS_LENGTH];
2517 DEBC(printk(ST_DEB_MSG "%s: Compression state is %d.\n", name,
2518 (b_data[mpoffs + CP_OFF_DCE_DCC] & DCE_MASK ? 1 : 0)));
2519
2520 /* Check if compression can be changed */
2521 if ((b_data[mpoffs + CP_OFF_DCE_DCC] & DCC_MASK) == 0) {
2522 DEBC(printk(ST_DEB_MSG "%s: Compression not supported.\n", name));
2523 return (-EIO);
2524 }
2525
2526 /* Do the change */
2527 if (state) {
2528 b_data[mpoffs + CP_OFF_DCE_DCC] |= DCE_MASK;
2529 if (STp->c_algo != 0)
2530 b_data[mpoffs + CP_OFF_C_ALGO] = STp->c_algo;
2531 }
2532 else {
2533 b_data[mpoffs + CP_OFF_DCE_DCC] &= ~DCE_MASK;
2534 if (STp->c_algo != 0)
2535 b_data[mpoffs + CP_OFF_C_ALGO] = 0; /* no compression */
2536 }
2537
2538 retval = write_mode_page(STp, COMPRESSION_PAGE, 0);
2539 if (retval) {
2540 DEBC(printk(ST_DEB_MSG "%s: Compression change failed.\n", name));
2541 return (-EIO);
2542 }
2543 DEBC(printk(ST_DEB_MSG "%s: Compression state changed to %d.\n",
2544 name, state));
2545
2546 STp->compression_changed = 1;
2547 return 0;
2548}
2549
2550
2551/* Process the load and unload commands (does unload if the load code is zero) */
2552static int do_load_unload(struct scsi_tape *STp, struct file *filp, int load_code)
2553{
2554 int retval = (-EIO), timeout;
2555 DEB( char *name = tape_name(STp); )
2556 unsigned char cmd[MAX_COMMAND_SIZE];
2557 struct st_partstat *STps;
Mike Christie8b05b772005-11-08 04:06:44 -06002558 struct st_request *SRpnt;
Linus Torvalds1da177e2005-04-16 15:20:36 -07002559
2560 if (STp->ready != ST_READY && !load_code) {
2561 if (STp->ready == ST_NO_TAPE)
2562 return (-ENOMEDIUM);
2563 else
2564 return (-EIO);
2565 }
2566
2567 memset(cmd, 0, MAX_COMMAND_SIZE);
2568 cmd[0] = START_STOP;
2569 if (load_code)
2570 cmd[4] |= 1;
2571 /*
2572 * If arg >= 1 && arg <= 6 Enhanced load/unload in HP C1553A
2573 */
2574 if (load_code >= 1 + MT_ST_HPLOADER_OFFSET
2575 && load_code <= 6 + MT_ST_HPLOADER_OFFSET) {
2576 DEBC(printk(ST_DEB_MSG "%s: Enhanced %sload slot %2d.\n",
2577 name, (cmd[4]) ? "" : "un",
2578 load_code - MT_ST_HPLOADER_OFFSET));
2579 cmd[3] = load_code - MT_ST_HPLOADER_OFFSET; /* MediaID field of C1553A */
2580 }
2581 if (STp->immediate) {
2582 cmd[1] = 1; /* Don't wait for completion */
James Bottomleya02488e2008-11-30 10:36:26 -06002583 timeout = STp->device->request_queue->rq_timeout;
Linus Torvalds1da177e2005-04-16 15:20:36 -07002584 }
2585 else
2586 timeout = STp->long_timeout;
2587
2588 DEBC(
2589 if (!load_code)
2590 printk(ST_DEB_MSG "%s: Unloading tape.\n", name);
2591 else
2592 printk(ST_DEB_MSG "%s: Loading tape.\n", name);
2593 );
2594
FUJITA Tomonori15c920a2008-12-05 15:25:24 +09002595 SRpnt = st_allocate_request(STp);
Linus Torvalds1da177e2005-04-16 15:20:36 -07002596 if (!SRpnt)
FUJITA Tomonori15c920a2008-12-05 15:25:24 +09002597 return STp->buffer->syscall_result;
2598
2599 retval = st_scsi_kern_execute(SRpnt, cmd, DMA_NONE, NULL, 0, timeout,
2600 MAX_RETRIES);
2601 if (retval)
2602 goto out;
Linus Torvalds1da177e2005-04-16 15:20:36 -07002603
2604 retval = (STp->buffer)->syscall_result;
Linus Torvalds1da177e2005-04-16 15:20:36 -07002605
2606 if (!retval) { /* SCSI command successful */
2607
2608 if (!load_code) {
2609 STp->rew_at_close = 0;
2610 STp->ready = ST_NO_TAPE;
2611 }
2612 else {
2613 STp->rew_at_close = STp->autorew_dev;
2614 retval = check_tape(STp, filp);
2615 if (retval > 0)
2616 retval = 0;
2617 }
2618 }
2619 else {
2620 STps = &(STp->ps[STp->partition]);
2621 STps->drv_file = STps->drv_block = (-1);
2622 }
FUJITA Tomonori15c920a2008-12-05 15:25:24 +09002623out:
2624 st_release_request(SRpnt);
Linus Torvalds1da177e2005-04-16 15:20:36 -07002625
2626 return retval;
2627}
2628
2629#if DEBUG
2630#define ST_DEB_FORWARD 0
2631#define ST_DEB_BACKWARD 1
2632static void deb_space_print(char *name, int direction, char *units, unsigned char *cmd)
2633{
2634 s32 sc;
2635
2636 sc = cmd[2] & 0x80 ? 0xff000000 : 0;
2637 sc |= (cmd[2] << 16) | (cmd[3] << 8) | cmd[4];
2638 if (direction)
2639 sc = -sc;
2640 printk(ST_DEB_MSG "%s: Spacing tape %s over %d %s.\n", name,
2641 direction ? "backward" : "forward", sc, units);
2642}
2643#endif
2644
2645
2646/* Internal ioctl function */
2647static int st_int_ioctl(struct scsi_tape *STp, unsigned int cmd_in, unsigned long arg)
2648{
2649 int timeout;
2650 long ltmp;
2651 int ioctl_result;
2652 int chg_eof = 1;
2653 unsigned char cmd[MAX_COMMAND_SIZE];
Mike Christie8b05b772005-11-08 04:06:44 -06002654 struct st_request *SRpnt;
Linus Torvalds1da177e2005-04-16 15:20:36 -07002655 struct st_partstat *STps;
2656 int fileno, blkno, at_sm, undone;
2657 int datalen = 0, direction = DMA_NONE;
2658 char *name = tape_name(STp);
2659
2660 WARN_ON(STp->buffer->do_dio != 0);
2661 if (STp->ready != ST_READY) {
2662 if (STp->ready == ST_NO_TAPE)
2663 return (-ENOMEDIUM);
2664 else
2665 return (-EIO);
2666 }
2667 timeout = STp->long_timeout;
2668 STps = &(STp->ps[STp->partition]);
2669 fileno = STps->drv_file;
2670 blkno = STps->drv_block;
2671 at_sm = STps->at_sm;
2672
2673 memset(cmd, 0, MAX_COMMAND_SIZE);
2674 switch (cmd_in) {
2675 case MTFSFM:
2676 chg_eof = 0; /* Changed from the FSF after this */
2677 case MTFSF:
2678 cmd[0] = SPACE;
2679 cmd[1] = 0x01; /* Space FileMarks */
2680 cmd[2] = (arg >> 16);
2681 cmd[3] = (arg >> 8);
2682 cmd[4] = arg;
2683 DEBC(deb_space_print(name, ST_DEB_FORWARD, "filemarks", cmd);)
2684 if (fileno >= 0)
2685 fileno += arg;
2686 blkno = 0;
2687 at_sm &= (arg == 0);
2688 break;
2689 case MTBSFM:
2690 chg_eof = 0; /* Changed from the FSF after this */
2691 case MTBSF:
2692 cmd[0] = SPACE;
2693 cmd[1] = 0x01; /* Space FileMarks */
2694 ltmp = (-arg);
2695 cmd[2] = (ltmp >> 16);
2696 cmd[3] = (ltmp >> 8);
2697 cmd[4] = ltmp;
2698 DEBC(deb_space_print(name, ST_DEB_BACKWARD, "filemarks", cmd);)
2699 if (fileno >= 0)
2700 fileno -= arg;
2701 blkno = (-1); /* We can't know the block number */
2702 at_sm &= (arg == 0);
2703 break;
2704 case MTFSR:
2705 cmd[0] = SPACE;
2706 cmd[1] = 0x00; /* Space Blocks */
2707 cmd[2] = (arg >> 16);
2708 cmd[3] = (arg >> 8);
2709 cmd[4] = arg;
2710 DEBC(deb_space_print(name, ST_DEB_FORWARD, "blocks", cmd);)
2711 if (blkno >= 0)
2712 blkno += arg;
2713 at_sm &= (arg == 0);
2714 break;
2715 case MTBSR:
2716 cmd[0] = SPACE;
2717 cmd[1] = 0x00; /* Space Blocks */
2718 ltmp = (-arg);
2719 cmd[2] = (ltmp >> 16);
2720 cmd[3] = (ltmp >> 8);
2721 cmd[4] = ltmp;
2722 DEBC(deb_space_print(name, ST_DEB_BACKWARD, "blocks", cmd);)
2723 if (blkno >= 0)
2724 blkno -= arg;
2725 at_sm &= (arg == 0);
2726 break;
2727 case MTFSS:
2728 cmd[0] = SPACE;
2729 cmd[1] = 0x04; /* Space Setmarks */
2730 cmd[2] = (arg >> 16);
2731 cmd[3] = (arg >> 8);
2732 cmd[4] = arg;
2733 DEBC(deb_space_print(name, ST_DEB_FORWARD, "setmarks", cmd);)
2734 if (arg != 0) {
2735 blkno = fileno = (-1);
2736 at_sm = 1;
2737 }
2738 break;
2739 case MTBSS:
2740 cmd[0] = SPACE;
2741 cmd[1] = 0x04; /* Space Setmarks */
2742 ltmp = (-arg);
2743 cmd[2] = (ltmp >> 16);
2744 cmd[3] = (ltmp >> 8);
2745 cmd[4] = ltmp;
2746 DEBC(deb_space_print(name, ST_DEB_BACKWARD, "setmarks", cmd);)
2747 if (arg != 0) {
2748 blkno = fileno = (-1);
2749 at_sm = 1;
2750 }
2751 break;
2752 case MTWEOF:
2753 case MTWSM:
2754 if (STp->write_prot)
2755 return (-EACCES);
2756 cmd[0] = WRITE_FILEMARKS;
2757 if (cmd_in == MTWSM)
2758 cmd[1] = 2;
2759 cmd[2] = (arg >> 16);
2760 cmd[3] = (arg >> 8);
2761 cmd[4] = arg;
James Bottomleya02488e2008-11-30 10:36:26 -06002762 timeout = STp->device->request_queue->rq_timeout;
Linus Torvalds1da177e2005-04-16 15:20:36 -07002763 DEBC(
2764 if (cmd_in == MTWEOF)
2765 printk(ST_DEB_MSG "%s: Writing %d filemarks.\n", name,
2766 cmd[2] * 65536 + cmd[3] * 256 + cmd[4]);
2767 else
2768 printk(ST_DEB_MSG "%s: Writing %d setmarks.\n", name,
2769 cmd[2] * 65536 + cmd[3] * 256 + cmd[4]);
2770 )
2771 if (fileno >= 0)
2772 fileno += arg;
2773 blkno = 0;
2774 at_sm = (cmd_in == MTWSM);
2775 break;
2776 case MTREW:
2777 cmd[0] = REZERO_UNIT;
2778 if (STp->immediate) {
2779 cmd[1] = 1; /* Don't wait for completion */
James Bottomleya02488e2008-11-30 10:36:26 -06002780 timeout = STp->device->request_queue->rq_timeout;
Linus Torvalds1da177e2005-04-16 15:20:36 -07002781 }
2782 DEBC(printk(ST_DEB_MSG "%s: Rewinding tape.\n", name));
2783 fileno = blkno = at_sm = 0;
2784 break;
2785 case MTNOP:
2786 DEBC(printk(ST_DEB_MSG "%s: No op on tape.\n", name));
2787 return 0; /* Should do something ? */
2788 break;
2789 case MTRETEN:
2790 cmd[0] = START_STOP;
2791 if (STp->immediate) {
2792 cmd[1] = 1; /* Don't wait for completion */
James Bottomleya02488e2008-11-30 10:36:26 -06002793 timeout = STp->device->request_queue->rq_timeout;
Linus Torvalds1da177e2005-04-16 15:20:36 -07002794 }
2795 cmd[4] = 3;
2796 DEBC(printk(ST_DEB_MSG "%s: Retensioning tape.\n", name));
2797 fileno = blkno = at_sm = 0;
2798 break;
2799 case MTEOM:
2800 if (!STp->fast_mteom) {
2801 /* space to the end of tape */
2802 ioctl_result = st_int_ioctl(STp, MTFSF, 0x7fffff);
2803 fileno = STps->drv_file;
2804 if (STps->eof >= ST_EOD_1)
2805 return 0;
2806 /* The next lines would hide the number of spaced FileMarks
2807 That's why I inserted the previous lines. I had no luck
2808 with detecting EOM with FSF, so we go now to EOM.
2809 Joerg Weule */
2810 } else
2811 fileno = (-1);
2812 cmd[0] = SPACE;
2813 cmd[1] = 3;
2814 DEBC(printk(ST_DEB_MSG "%s: Spacing to end of recorded medium.\n",
2815 name));
2816 blkno = -1;
2817 at_sm = 0;
2818 break;
2819 case MTERASE:
2820 if (STp->write_prot)
2821 return (-EACCES);
2822 cmd[0] = ERASE;
2823 cmd[1] = (arg ? 1 : 0); /* Long erase with non-zero argument */
2824 if (STp->immediate) {
2825 cmd[1] |= 2; /* Don't wait for completion */
James Bottomleya02488e2008-11-30 10:36:26 -06002826 timeout = STp->device->request_queue->rq_timeout;
Linus Torvalds1da177e2005-04-16 15:20:36 -07002827 }
2828 else
2829 timeout = STp->long_timeout * 8;
2830
2831 DEBC(printk(ST_DEB_MSG "%s: Erasing tape.\n", name));
2832 fileno = blkno = at_sm = 0;
2833 break;
2834 case MTSETBLK: /* Set block length */
2835 case MTSETDENSITY: /* Set tape density */
2836 case MTSETDRVBUFFER: /* Set drive buffering */
2837 case SET_DENS_AND_BLK: /* Set density and block size */
2838 chg_eof = 0;
2839 if (STp->dirty || (STp->buffer)->buffer_bytes != 0)
2840 return (-EIO); /* Not allowed if data in buffer */
2841 if ((cmd_in == MTSETBLK || cmd_in == SET_DENS_AND_BLK) &&
2842 (arg & MT_ST_BLKSIZE_MASK) != 0 &&
2843 STp->max_block > 0 &&
2844 ((arg & MT_ST_BLKSIZE_MASK) < STp->min_block ||
2845 (arg & MT_ST_BLKSIZE_MASK) > STp->max_block)) {
2846 printk(KERN_WARNING "%s: Illegal block size.\n", name);
2847 return (-EINVAL);
2848 }
2849 cmd[0] = MODE_SELECT;
2850 if ((STp->use_pf & USE_PF))
2851 cmd[1] = MODE_SELECT_PAGE_FORMAT;
2852 cmd[4] = datalen = 12;
2853 direction = DMA_TO_DEVICE;
2854
2855 memset((STp->buffer)->b_data, 0, 12);
2856 if (cmd_in == MTSETDRVBUFFER)
2857 (STp->buffer)->b_data[2] = (arg & 7) << 4;
2858 else
2859 (STp->buffer)->b_data[2] =
2860 STp->drv_buffer << 4;
2861 (STp->buffer)->b_data[3] = 8; /* block descriptor length */
2862 if (cmd_in == MTSETDENSITY) {
2863 (STp->buffer)->b_data[4] = arg;
2864 STp->density_changed = 1; /* At least we tried ;-) */
2865 } else if (cmd_in == SET_DENS_AND_BLK)
2866 (STp->buffer)->b_data[4] = arg >> 24;
2867 else
2868 (STp->buffer)->b_data[4] = STp->density;
2869 if (cmd_in == MTSETBLK || cmd_in == SET_DENS_AND_BLK) {
2870 ltmp = arg & MT_ST_BLKSIZE_MASK;
2871 if (cmd_in == MTSETBLK)
2872 STp->blksize_changed = 1; /* At least we tried ;-) */
2873 } else
2874 ltmp = STp->block_size;
2875 (STp->buffer)->b_data[9] = (ltmp >> 16);
2876 (STp->buffer)->b_data[10] = (ltmp >> 8);
2877 (STp->buffer)->b_data[11] = ltmp;
James Bottomleya02488e2008-11-30 10:36:26 -06002878 timeout = STp->device->request_queue->rq_timeout;
Linus Torvalds1da177e2005-04-16 15:20:36 -07002879 DEBC(
2880 if (cmd_in == MTSETBLK || cmd_in == SET_DENS_AND_BLK)
2881 printk(ST_DEB_MSG
2882 "%s: Setting block size to %d bytes.\n", name,
2883 (STp->buffer)->b_data[9] * 65536 +
2884 (STp->buffer)->b_data[10] * 256 +
2885 (STp->buffer)->b_data[11]);
2886 if (cmd_in == MTSETDENSITY || cmd_in == SET_DENS_AND_BLK)
2887 printk(ST_DEB_MSG
2888 "%s: Setting density code to %x.\n", name,
2889 (STp->buffer)->b_data[4]);
2890 if (cmd_in == MTSETDRVBUFFER)
2891 printk(ST_DEB_MSG
2892 "%s: Setting drive buffer code to %d.\n", name,
2893 ((STp->buffer)->b_data[2] >> 4) & 7);
2894 )
2895 break;
2896 default:
2897 return (-ENOSYS);
2898 }
2899
FUJITA Tomonoriccc607f2008-12-05 15:25:31 +09002900 SRpnt = st_allocate_request(STp);
Linus Torvalds1da177e2005-04-16 15:20:36 -07002901 if (!SRpnt)
2902 return (STp->buffer)->syscall_result;
2903
FUJITA Tomonoriccc607f2008-12-05 15:25:31 +09002904 ioctl_result = st_scsi_kern_execute(SRpnt, cmd, direction,
2905 STp->buffer->b_data, datalen,
2906 timeout, MAX_RETRIES);
2907 if (!ioctl_result)
2908 ioctl_result = (STp->buffer)->syscall_result;
Linus Torvalds1da177e2005-04-16 15:20:36 -07002909
2910 if (!ioctl_result) { /* SCSI command successful */
Mike Christie8b05b772005-11-08 04:06:44 -06002911 st_release_request(SRpnt);
Linus Torvalds1da177e2005-04-16 15:20:36 -07002912 SRpnt = NULL;
2913 STps->drv_block = blkno;
2914 STps->drv_file = fileno;
2915 STps->at_sm = at_sm;
2916
2917 if (cmd_in == MTBSFM)
2918 ioctl_result = st_int_ioctl(STp, MTFSF, 1);
2919 else if (cmd_in == MTFSFM)
2920 ioctl_result = st_int_ioctl(STp, MTBSF, 1);
2921
2922 if (cmd_in == MTSETBLK || cmd_in == SET_DENS_AND_BLK) {
2923 int old_block_size = STp->block_size;
2924 STp->block_size = arg & MT_ST_BLKSIZE_MASK;
2925 if (STp->block_size != 0) {
2926 if (old_block_size == 0)
2927 normalize_buffer(STp->buffer);
2928 (STp->buffer)->buffer_blocks =
2929 (STp->buffer)->buffer_size / STp->block_size;
2930 }
2931 (STp->buffer)->buffer_bytes = (STp->buffer)->read_pointer = 0;
2932 if (cmd_in == SET_DENS_AND_BLK)
2933 STp->density = arg >> MT_ST_DENSITY_SHIFT;
2934 } else if (cmd_in == MTSETDRVBUFFER)
2935 STp->drv_buffer = (arg & 7);
2936 else if (cmd_in == MTSETDENSITY)
2937 STp->density = arg;
2938
2939 if (cmd_in == MTEOM)
2940 STps->eof = ST_EOD;
2941 else if (cmd_in == MTFSF)
2942 STps->eof = ST_FM;
2943 else if (chg_eof)
2944 STps->eof = ST_NOEOF;
2945
2946 if (cmd_in == MTWEOF)
2947 STps->rw = ST_IDLE;
2948 } else { /* SCSI command was not completely successful. Don't return
2949 from this block without releasing the SCSI command block! */
2950 struct st_cmdstatus *cmdstatp = &STp->buffer->cmdstat;
2951
2952 if (cmdstatp->flags & SENSE_EOM) {
2953 if (cmd_in != MTBSF && cmd_in != MTBSFM &&
2954 cmd_in != MTBSR && cmd_in != MTBSS)
2955 STps->eof = ST_EOM_OK;
2956 STps->drv_block = 0;
2957 }
2958
2959 if (cmdstatp->remainder_valid)
2960 undone = (int)cmdstatp->uremainder64;
2961 else
2962 undone = 0;
2963
2964 if (cmd_in == MTWEOF &&
2965 cmdstatp->have_sense &&
Kai Makisara91614c02007-01-26 00:38:39 +02002966 (cmdstatp->flags & SENSE_EOM)) {
2967 if (cmdstatp->sense_hdr.sense_key == NO_SENSE ||
2968 cmdstatp->sense_hdr.sense_key == RECOVERED_ERROR) {
2969 ioctl_result = 0; /* EOF(s) written successfully at EOM */
2970 STps->eof = ST_NOEOF;
2971 } else { /* Writing EOF(s) failed */
2972 if (fileno >= 0)
2973 fileno -= undone;
2974 if (undone < arg)
2975 STps->eof = ST_NOEOF;
2976 }
Linus Torvalds1da177e2005-04-16 15:20:36 -07002977 STps->drv_file = fileno;
Linus Torvalds1da177e2005-04-16 15:20:36 -07002978 } else if ((cmd_in == MTFSF) || (cmd_in == MTFSFM)) {
2979 if (fileno >= 0)
2980 STps->drv_file = fileno - undone;
2981 else
2982 STps->drv_file = fileno;
2983 STps->drv_block = -1;
2984 STps->eof = ST_NOEOF;
2985 } else if ((cmd_in == MTBSF) || (cmd_in == MTBSFM)) {
2986 if (arg > 0 && undone < 0) /* Some drives get this wrong */
2987 undone = (-undone);
2988 if (STps->drv_file >= 0)
2989 STps->drv_file = fileno + undone;
2990 STps->drv_block = 0;
2991 STps->eof = ST_NOEOF;
2992 } else if (cmd_in == MTFSR) {
2993 if (cmdstatp->flags & SENSE_FMK) { /* Hit filemark */
2994 if (STps->drv_file >= 0)
2995 STps->drv_file++;
2996 STps->drv_block = 0;
2997 STps->eof = ST_FM;
2998 } else {
2999 if (blkno >= undone)
3000 STps->drv_block = blkno - undone;
3001 else
3002 STps->drv_block = (-1);
3003 STps->eof = ST_NOEOF;
3004 }
3005 } else if (cmd_in == MTBSR) {
3006 if (cmdstatp->flags & SENSE_FMK) { /* Hit filemark */
3007 STps->drv_file--;
3008 STps->drv_block = (-1);
3009 } else {
3010 if (arg > 0 && undone < 0) /* Some drives get this wrong */
3011 undone = (-undone);
3012 if (STps->drv_block >= 0)
3013 STps->drv_block = blkno + undone;
3014 }
3015 STps->eof = ST_NOEOF;
3016 } else if (cmd_in == MTEOM) {
3017 STps->drv_file = (-1);
3018 STps->drv_block = (-1);
3019 STps->eof = ST_EOD;
3020 } else if (cmd_in == MTSETBLK ||
3021 cmd_in == MTSETDENSITY ||
3022 cmd_in == MTSETDRVBUFFER ||
3023 cmd_in == SET_DENS_AND_BLK) {
3024 if (cmdstatp->sense_hdr.sense_key == ILLEGAL_REQUEST &&
3025 !(STp->use_pf & PF_TESTED)) {
3026 /* Try the other possible state of Page Format if not
3027 already tried */
3028 STp->use_pf = !STp->use_pf | PF_TESTED;
Mike Christie8b05b772005-11-08 04:06:44 -06003029 st_release_request(SRpnt);
Linus Torvalds1da177e2005-04-16 15:20:36 -07003030 SRpnt = NULL;
3031 return st_int_ioctl(STp, cmd_in, arg);
3032 }
3033 } else if (chg_eof)
3034 STps->eof = ST_NOEOF;
3035
3036 if (cmdstatp->sense_hdr.sense_key == BLANK_CHECK)
3037 STps->eof = ST_EOD;
3038
Mike Christie8b05b772005-11-08 04:06:44 -06003039 st_release_request(SRpnt);
Linus Torvalds1da177e2005-04-16 15:20:36 -07003040 SRpnt = NULL;
3041 }
3042
3043 return ioctl_result;
3044}
3045
3046
3047/* Get the tape position. If bt == 2, arg points into a kernel space mt_loc
3048 structure. */
3049
3050static int get_location(struct scsi_tape *STp, unsigned int *block, int *partition,
3051 int logical)
3052{
3053 int result;
3054 unsigned char scmd[MAX_COMMAND_SIZE];
Mike Christie8b05b772005-11-08 04:06:44 -06003055 struct st_request *SRpnt;
Linus Torvalds1da177e2005-04-16 15:20:36 -07003056 DEB( char *name = tape_name(STp); )
3057
3058 if (STp->ready != ST_READY)
3059 return (-EIO);
3060
3061 memset(scmd, 0, MAX_COMMAND_SIZE);
3062 if ((STp->device)->scsi_level < SCSI_2) {
3063 scmd[0] = QFA_REQUEST_BLOCK;
3064 scmd[4] = 3;
3065 } else {
3066 scmd[0] = READ_POSITION;
3067 if (!logical && !STp->scsi2_logical)
3068 scmd[1] = 1;
3069 }
FUJITA Tomonori7a31ec32008-12-05 15:25:30 +09003070
3071 SRpnt = st_allocate_request(STp);
Linus Torvalds1da177e2005-04-16 15:20:36 -07003072 if (!SRpnt)
FUJITA Tomonori7a31ec32008-12-05 15:25:30 +09003073 return STp->buffer->syscall_result;
3074
3075 result = st_scsi_kern_execute(SRpnt, scmd, DMA_FROM_DEVICE,
3076 STp->buffer->b_data, 20,
3077 STp->device->request_queue->rq_timeout,
3078 MAX_READY_RETRIES);
3079 if (result)
3080 goto out;
Linus Torvalds1da177e2005-04-16 15:20:36 -07003081
3082 if ((STp->buffer)->syscall_result != 0 ||
3083 (STp->device->scsi_level >= SCSI_2 &&
3084 ((STp->buffer)->b_data[0] & 4) != 0)) {
3085 *block = *partition = 0;
3086 DEBC(printk(ST_DEB_MSG "%s: Can't read tape position.\n", name));
3087 result = (-EIO);
3088 } else {
3089 result = 0;
3090 if ((STp->device)->scsi_level < SCSI_2) {
3091 *block = ((STp->buffer)->b_data[0] << 16)
3092 + ((STp->buffer)->b_data[1] << 8)
3093 + (STp->buffer)->b_data[2];
3094 *partition = 0;
3095 } else {
3096 *block = ((STp->buffer)->b_data[4] << 24)
3097 + ((STp->buffer)->b_data[5] << 16)
3098 + ((STp->buffer)->b_data[6] << 8)
3099 + (STp->buffer)->b_data[7];
3100 *partition = (STp->buffer)->b_data[1];
3101 if (((STp->buffer)->b_data[0] & 0x80) &&
3102 (STp->buffer)->b_data[1] == 0) /* BOP of partition 0 */
3103 STp->ps[0].drv_block = STp->ps[0].drv_file = 0;
3104 }
3105 DEBC(printk(ST_DEB_MSG "%s: Got tape pos. blk %d part %d.\n", name,
3106 *block, *partition));
3107 }
FUJITA Tomonori7a31ec32008-12-05 15:25:30 +09003108out:
Mike Christie8b05b772005-11-08 04:06:44 -06003109 st_release_request(SRpnt);
Linus Torvalds1da177e2005-04-16 15:20:36 -07003110 SRpnt = NULL;
3111
3112 return result;
3113}
3114
3115
3116/* Set the tape block and partition. Negative partition means that only the
3117 block should be set in vendor specific way. */
3118static int set_location(struct scsi_tape *STp, unsigned int block, int partition,
3119 int logical)
3120{
3121 struct st_partstat *STps;
3122 int result, p;
3123 unsigned int blk;
3124 int timeout;
3125 unsigned char scmd[MAX_COMMAND_SIZE];
Mike Christie8b05b772005-11-08 04:06:44 -06003126 struct st_request *SRpnt;
Linus Torvalds1da177e2005-04-16 15:20:36 -07003127 DEB( char *name = tape_name(STp); )
3128
3129 if (STp->ready != ST_READY)
3130 return (-EIO);
3131 timeout = STp->long_timeout;
3132 STps = &(STp->ps[STp->partition]);
3133
3134 DEBC(printk(ST_DEB_MSG "%s: Setting block to %d and partition to %d.\n",
3135 name, block, partition));
3136 DEB(if (partition < 0)
3137 return (-EIO); )
3138
3139 /* Update the location at the partition we are leaving */
3140 if ((!STp->can_partitions && partition != 0) ||
3141 partition >= ST_NBR_PARTITIONS)
3142 return (-EINVAL);
3143 if (partition != STp->partition) {
3144 if (get_location(STp, &blk, &p, 1))
3145 STps->last_block_valid = 0;
3146 else {
3147 STps->last_block_valid = 1;
3148 STps->last_block_visited = blk;
3149 DEBC(printk(ST_DEB_MSG
3150 "%s: Visited block %d for partition %d saved.\n",
3151 name, blk, STp->partition));
3152 }
3153 }
3154
3155 memset(scmd, 0, MAX_COMMAND_SIZE);
3156 if ((STp->device)->scsi_level < SCSI_2) {
3157 scmd[0] = QFA_SEEK_BLOCK;
3158 scmd[2] = (block >> 16);
3159 scmd[3] = (block >> 8);
3160 scmd[4] = block;
3161 scmd[5] = 0;
3162 } else {
3163 scmd[0] = SEEK_10;
3164 scmd[3] = (block >> 24);
3165 scmd[4] = (block >> 16);
3166 scmd[5] = (block >> 8);
3167 scmd[6] = block;
3168 if (!logical && !STp->scsi2_logical)
3169 scmd[1] = 4;
3170 if (STp->partition != partition) {
3171 scmd[1] |= 2;
3172 scmd[8] = partition;
3173 DEBC(printk(ST_DEB_MSG
3174 "%s: Trying to change partition from %d to %d\n",
3175 name, STp->partition, partition));
3176 }
3177 }
3178 if (STp->immediate) {
3179 scmd[1] |= 1; /* Don't wait for completion */
James Bottomleya02488e2008-11-30 10:36:26 -06003180 timeout = STp->device->request_queue->rq_timeout;
Linus Torvalds1da177e2005-04-16 15:20:36 -07003181 }
3182
FUJITA Tomonori3c0bf162008-12-05 15:25:23 +09003183 SRpnt = st_allocate_request(STp);
Linus Torvalds1da177e2005-04-16 15:20:36 -07003184 if (!SRpnt)
FUJITA Tomonori3c0bf162008-12-05 15:25:23 +09003185 return STp->buffer->syscall_result;
3186
3187 result = st_scsi_kern_execute(SRpnt, scmd, DMA_NONE, NULL, 0,
3188 timeout, MAX_READY_RETRIES);
3189 if (result)
3190 goto out;
Linus Torvalds1da177e2005-04-16 15:20:36 -07003191
3192 STps->drv_block = STps->drv_file = (-1);
3193 STps->eof = ST_NOEOF;
3194 if ((STp->buffer)->syscall_result != 0) {
3195 result = (-EIO);
3196 if (STp->can_partitions &&
3197 (STp->device)->scsi_level >= SCSI_2 &&
3198 (p = find_partition(STp)) >= 0)
3199 STp->partition = p;
3200 } else {
3201 if (STp->can_partitions) {
3202 STp->partition = partition;
3203 STps = &(STp->ps[partition]);
3204 if (!STps->last_block_valid ||
3205 STps->last_block_visited != block) {
3206 STps->at_sm = 0;
3207 STps->rw = ST_IDLE;
3208 }
3209 } else
3210 STps->at_sm = 0;
3211 if (block == 0)
3212 STps->drv_block = STps->drv_file = 0;
3213 result = 0;
3214 }
FUJITA Tomonori3c0bf162008-12-05 15:25:23 +09003215out:
Mike Christie8b05b772005-11-08 04:06:44 -06003216 st_release_request(SRpnt);
Linus Torvalds1da177e2005-04-16 15:20:36 -07003217 SRpnt = NULL;
3218
3219 return result;
3220}
3221
3222
3223/* Find the current partition number for the drive status. Called from open and
3224 returns either partition number of negative error code. */
3225static int find_partition(struct scsi_tape *STp)
3226{
3227 int i, partition;
3228 unsigned int block;
3229
3230 if ((i = get_location(STp, &block, &partition, 1)) < 0)
3231 return i;
3232 if (partition >= ST_NBR_PARTITIONS)
3233 return (-EIO);
3234 return partition;
3235}
3236
3237
3238/* Change the partition if necessary */
3239static int switch_partition(struct scsi_tape *STp)
3240{
3241 struct st_partstat *STps;
3242
3243 if (STp->partition == STp->new_partition)
3244 return 0;
3245 STps = &(STp->ps[STp->new_partition]);
3246 if (!STps->last_block_valid)
3247 STps->last_block_visited = 0;
3248 return set_location(STp, STps->last_block_visited, STp->new_partition, 1);
3249}
3250
3251/* Functions for reading and writing the medium partition mode page. */
3252
3253#define PART_PAGE 0x11
3254#define PART_PAGE_FIXED_LENGTH 8
3255
3256#define PP_OFF_MAX_ADD_PARTS 2
3257#define PP_OFF_NBR_ADD_PARTS 3
3258#define PP_OFF_FLAGS 4
3259#define PP_OFF_PART_UNITS 6
3260#define PP_OFF_RESERVED 7
3261
3262#define PP_BIT_IDP 0x20
3263#define PP_MSK_PSUM_MB 0x10
3264
3265/* Get the number of partitions on the tape. As a side effect reads the
3266 mode page into the tape buffer. */
3267static int nbr_partitions(struct scsi_tape *STp)
3268{
3269 int result;
3270 DEB( char *name = tape_name(STp); )
3271
3272 if (STp->ready != ST_READY)
3273 return (-EIO);
3274
3275 result = read_mode_page(STp, PART_PAGE, 1);
3276
3277 if (result) {
3278 DEBC(printk(ST_DEB_MSG "%s: Can't read medium partition page.\n",
3279 name));
3280 result = (-EIO);
3281 } else {
3282 result = (STp->buffer)->b_data[MODE_HEADER_LENGTH +
3283 PP_OFF_NBR_ADD_PARTS] + 1;
3284 DEBC(printk(ST_DEB_MSG "%s: Number of partitions %d.\n", name, result));
3285 }
3286
3287 return result;
3288}
3289
3290
3291/* Partition the tape into two partitions if size > 0 or one partition if
3292 size == 0.
3293
3294 The block descriptors are read and written because Sony SDT-7000 does not
3295 work without this (suggestion from Michael Schaefer <Michael.Schaefer@dlr.de>).
3296
3297 My HP C1533A drive returns only one partition size field. This is used to
3298 set the size of partition 1. There is no size field for the default partition.
3299 Michael Schaefer's Sony SDT-7000 returns two descriptors and the second is
3300 used to set the size of partition 1 (this is what the SCSI-3 standard specifies).
3301 The following algorithm is used to accommodate both drives: if the number of
3302 partition size fields is greater than the maximum number of additional partitions
3303 in the mode page, the second field is used. Otherwise the first field is used.
3304
3305 For Seagate DDS drives the page length must be 8 when no partitions is defined
3306 and 10 when 1 partition is defined (information from Eric Lee Green). This is
3307 is acceptable also to some other old drives and enforced if the first partition
3308 size field is used for the first additional partition size.
3309 */
3310static int partition_tape(struct scsi_tape *STp, int size)
3311{
3312 char *name = tape_name(STp);
3313 int result;
3314 int pgo, psd_cnt, psdo;
3315 unsigned char *bp;
3316
3317 result = read_mode_page(STp, PART_PAGE, 0);
3318 if (result) {
3319 DEBC(printk(ST_DEB_MSG "%s: Can't read partition mode page.\n", name));
3320 return result;
3321 }
3322 /* The mode page is in the buffer. Let's modify it and write it. */
3323 bp = (STp->buffer)->b_data;
3324 pgo = MODE_HEADER_LENGTH + bp[MH_OFF_BDESCS_LENGTH];
3325 DEBC(printk(ST_DEB_MSG "%s: Partition page length is %d bytes.\n",
3326 name, bp[pgo + MP_OFF_PAGE_LENGTH] + 2));
3327
3328 psd_cnt = (bp[pgo + MP_OFF_PAGE_LENGTH] + 2 - PART_PAGE_FIXED_LENGTH) / 2;
3329 psdo = pgo + PART_PAGE_FIXED_LENGTH;
3330 if (psd_cnt > bp[pgo + PP_OFF_MAX_ADD_PARTS]) {
3331 bp[psdo] = bp[psdo + 1] = 0xff; /* Rest of the tape */
3332 psdo += 2;
3333 }
3334 memset(bp + psdo, 0, bp[pgo + PP_OFF_NBR_ADD_PARTS] * 2);
3335
3336 DEBC(printk("%s: psd_cnt %d, max.parts %d, nbr_parts %d\n", name,
3337 psd_cnt, bp[pgo + PP_OFF_MAX_ADD_PARTS],
3338 bp[pgo + PP_OFF_NBR_ADD_PARTS]));
3339
3340 if (size <= 0) {
3341 bp[pgo + PP_OFF_NBR_ADD_PARTS] = 0;
3342 if (psd_cnt <= bp[pgo + PP_OFF_MAX_ADD_PARTS])
3343 bp[pgo + MP_OFF_PAGE_LENGTH] = 6;
3344 DEBC(printk(ST_DEB_MSG "%s: Formatting tape with one partition.\n",
3345 name));
3346 } else {
3347 bp[psdo] = (size >> 8) & 0xff;
3348 bp[psdo + 1] = size & 0xff;
3349 bp[pgo + 3] = 1;
3350 if (bp[pgo + MP_OFF_PAGE_LENGTH] < 8)
3351 bp[pgo + MP_OFF_PAGE_LENGTH] = 8;
3352 DEBC(printk(ST_DEB_MSG
3353 "%s: Formatting tape with two partitions (1 = %d MB).\n",
3354 name, size));
3355 }
3356 bp[pgo + PP_OFF_PART_UNITS] = 0;
3357 bp[pgo + PP_OFF_RESERVED] = 0;
3358 bp[pgo + PP_OFF_FLAGS] = PP_BIT_IDP | PP_MSK_PSUM_MB;
3359
3360 result = write_mode_page(STp, PART_PAGE, 1);
3361 if (result) {
3362 printk(KERN_INFO "%s: Partitioning of tape failed.\n", name);
3363 result = (-EIO);
3364 }
3365
3366 return result;
3367}
3368
3369
3370
3371/* The ioctl command */
Kai Makisarafd66c1b2008-01-17 22:45:22 +02003372static long st_ioctl(struct file *file, unsigned int cmd_in, unsigned long arg)
Linus Torvalds1da177e2005-04-16 15:20:36 -07003373{
3374 int i, cmd_nr, cmd_type, bt;
3375 int retval = 0;
3376 unsigned int blk;
3377 struct scsi_tape *STp = file->private_data;
3378 struct st_modedef *STm;
3379 struct st_partstat *STps;
3380 char *name = tape_name(STp);
3381 void __user *p = (void __user *)arg;
3382
Matthias Kaehlcke28f85002007-07-29 23:38:15 +02003383 if (mutex_lock_interruptible(&STp->lock))
Linus Torvalds1da177e2005-04-16 15:20:36 -07003384 return -ERESTARTSYS;
3385
3386 DEB(
3387 if (debugging && !STp->in_use) {
3388 printk(ST_DEB_MSG "%s: Incorrect device.\n", name);
3389 retval = (-EIO);
3390 goto out;
3391 } ) /* end DEB */
3392
3393 STm = &(STp->modes[STp->current_mode]);
3394 STps = &(STp->ps[STp->partition]);
3395
3396 /*
3397 * If we are in the middle of error recovery, don't let anyone
3398 * else try and use this device. Also, if error recovery fails, it
3399 * may try and take the device offline, in which case all further
3400 * access to the device is prohibited.
3401 */
Al Viro83ff6fe2008-03-02 08:15:49 -05003402 retval = scsi_nonblockable_ioctl(STp->device, cmd_in, p,
3403 file->f_flags & O_NDELAY);
Linus Torvalds1da177e2005-04-16 15:20:36 -07003404 if (!scsi_block_when_processing_errors(STp->device) || retval != -ENODEV)
3405 goto out;
3406 retval = 0;
3407
3408 cmd_type = _IOC_TYPE(cmd_in);
3409 cmd_nr = _IOC_NR(cmd_in);
3410
3411 if (cmd_type == _IOC_TYPE(MTIOCTOP) && cmd_nr == _IOC_NR(MTIOCTOP)) {
3412 struct mtop mtc;
3413
3414 if (_IOC_SIZE(cmd_in) != sizeof(mtc)) {
3415 retval = (-EINVAL);
3416 goto out;
3417 }
3418
3419 i = copy_from_user(&mtc, p, sizeof(struct mtop));
3420 if (i) {
3421 retval = (-EFAULT);
3422 goto out;
3423 }
3424
3425 if (mtc.mt_op == MTSETDRVBUFFER && !capable(CAP_SYS_ADMIN)) {
3426 printk(KERN_WARNING
3427 "%s: MTSETDRVBUFFER only allowed for root.\n", name);
3428 retval = (-EPERM);
3429 goto out;
3430 }
3431 if (!STm->defined &&
3432 (mtc.mt_op != MTSETDRVBUFFER &&
3433 (mtc.mt_count & MT_ST_OPTIONS) == 0)) {
3434 retval = (-ENXIO);
3435 goto out;
3436 }
3437
3438 if (!STp->pos_unknown) {
3439
3440 if (STps->eof == ST_FM_HIT) {
3441 if (mtc.mt_op == MTFSF || mtc.mt_op == MTFSFM ||
3442 mtc.mt_op == MTEOM) {
3443 mtc.mt_count -= 1;
3444 if (STps->drv_file >= 0)
3445 STps->drv_file += 1;
3446 } else if (mtc.mt_op == MTBSF || mtc.mt_op == MTBSFM) {
3447 mtc.mt_count += 1;
3448 if (STps->drv_file >= 0)
3449 STps->drv_file += 1;
3450 }
3451 }
3452
3453 if (mtc.mt_op == MTSEEK) {
3454 /* Old position must be restored if partition will be
3455 changed */
3456 i = !STp->can_partitions ||
3457 (STp->new_partition != STp->partition);
3458 } else {
3459 i = mtc.mt_op == MTREW || mtc.mt_op == MTOFFL ||
3460 mtc.mt_op == MTRETEN || mtc.mt_op == MTEOM ||
3461 mtc.mt_op == MTLOCK || mtc.mt_op == MTLOAD ||
3462 mtc.mt_op == MTFSF || mtc.mt_op == MTFSFM ||
3463 mtc.mt_op == MTBSF || mtc.mt_op == MTBSFM ||
3464 mtc.mt_op == MTCOMPRESSION;
3465 }
3466 i = flush_buffer(STp, i);
3467 if (i < 0) {
3468 retval = i;
3469 goto out;
3470 }
3471 if (STps->rw == ST_WRITING &&
3472 (mtc.mt_op == MTREW || mtc.mt_op == MTOFFL ||
3473 mtc.mt_op == MTSEEK ||
3474 mtc.mt_op == MTBSF || mtc.mt_op == MTBSFM)) {
3475 i = st_int_ioctl(STp, MTWEOF, 1);
3476 if (i < 0) {
3477 retval = i;
3478 goto out;
3479 }
3480 if (mtc.mt_op == MTBSF || mtc.mt_op == MTBSFM)
3481 mtc.mt_count++;
3482 STps->rw = ST_IDLE;
3483 }
3484
3485 } else {
3486 /*
3487 * If there was a bus reset, block further access
3488 * to this device. If the user wants to rewind the tape,
3489 * then reset the flag and allow access again.
3490 */
3491 if (mtc.mt_op != MTREW &&
3492 mtc.mt_op != MTOFFL &&
3493 mtc.mt_op != MTRETEN &&
3494 mtc.mt_op != MTERASE &&
3495 mtc.mt_op != MTSEEK &&
3496 mtc.mt_op != MTEOM) {
3497 retval = (-EIO);
3498 goto out;
3499 }
3500 reset_state(STp);
3501 /* remove this when the midlevel properly clears was_reset */
3502 STp->device->was_reset = 0;
3503 }
3504
3505 if (mtc.mt_op != MTNOP && mtc.mt_op != MTSETBLK &&
3506 mtc.mt_op != MTSETDENSITY && mtc.mt_op != MTWSM &&
3507 mtc.mt_op != MTSETDRVBUFFER && mtc.mt_op != MTSETPART)
3508 STps->rw = ST_IDLE; /* Prevent automatic WEOF and fsf */
3509
3510 if (mtc.mt_op == MTOFFL && STp->door_locked != ST_UNLOCKED)
3511 do_door_lock(STp, 0); /* Ignore result! */
3512
3513 if (mtc.mt_op == MTSETDRVBUFFER &&
3514 (mtc.mt_count & MT_ST_OPTIONS) != 0) {
3515 retval = st_set_options(STp, mtc.mt_count);
3516 goto out;
3517 }
3518
3519 if (mtc.mt_op == MTSETPART) {
3520 if (!STp->can_partitions ||
3521 mtc.mt_count < 0 || mtc.mt_count >= ST_NBR_PARTITIONS) {
3522 retval = (-EINVAL);
3523 goto out;
3524 }
3525 if (mtc.mt_count >= STp->nbr_partitions &&
3526 (STp->nbr_partitions = nbr_partitions(STp)) < 0) {
3527 retval = (-EIO);
3528 goto out;
3529 }
3530 if (mtc.mt_count >= STp->nbr_partitions) {
3531 retval = (-EINVAL);
3532 goto out;
3533 }
3534 STp->new_partition = mtc.mt_count;
3535 retval = 0;
3536 goto out;
3537 }
3538
3539 if (mtc.mt_op == MTMKPART) {
3540 if (!STp->can_partitions) {
3541 retval = (-EINVAL);
3542 goto out;
3543 }
3544 if ((i = st_int_ioctl(STp, MTREW, 0)) < 0 ||
3545 (i = partition_tape(STp, mtc.mt_count)) < 0) {
3546 retval = i;
3547 goto out;
3548 }
3549 for (i = 0; i < ST_NBR_PARTITIONS; i++) {
3550 STp->ps[i].rw = ST_IDLE;
3551 STp->ps[i].at_sm = 0;
3552 STp->ps[i].last_block_valid = 0;
3553 }
3554 STp->partition = STp->new_partition = 0;
3555 STp->nbr_partitions = 1; /* Bad guess ?-) */
3556 STps->drv_block = STps->drv_file = 0;
3557 retval = 0;
3558 goto out;
3559 }
3560
3561 if (mtc.mt_op == MTSEEK) {
3562 i = set_location(STp, mtc.mt_count, STp->new_partition, 0);
3563 if (!STp->can_partitions)
3564 STp->ps[0].rw = ST_IDLE;
3565 retval = i;
3566 goto out;
3567 }
3568
3569 if (mtc.mt_op == MTUNLOAD || mtc.mt_op == MTOFFL) {
3570 retval = do_load_unload(STp, file, 0);
3571 goto out;
3572 }
3573
3574 if (mtc.mt_op == MTLOAD) {
3575 retval = do_load_unload(STp, file, max(1, mtc.mt_count));
3576 goto out;
3577 }
3578
3579 if (mtc.mt_op == MTLOCK || mtc.mt_op == MTUNLOCK) {
3580 retval = do_door_lock(STp, (mtc.mt_op == MTLOCK));
3581 goto out;
3582 }
3583
3584 if (STp->can_partitions && STp->ready == ST_READY &&
3585 (i = switch_partition(STp)) < 0) {
3586 retval = i;
3587 goto out;
3588 }
3589
3590 if (mtc.mt_op == MTCOMPRESSION)
3591 retval = st_compression(STp, (mtc.mt_count & 1));
3592 else
3593 retval = st_int_ioctl(STp, mtc.mt_op, mtc.mt_count);
3594 goto out;
3595 }
3596 if (!STm->defined) {
3597 retval = (-ENXIO);
3598 goto out;
3599 }
3600
3601 if ((i = flush_buffer(STp, 0)) < 0) {
3602 retval = i;
3603 goto out;
3604 }
3605 if (STp->can_partitions &&
3606 (i = switch_partition(STp)) < 0) {
3607 retval = i;
3608 goto out;
3609 }
3610
3611 if (cmd_type == _IOC_TYPE(MTIOCGET) && cmd_nr == _IOC_NR(MTIOCGET)) {
3612 struct mtget mt_status;
3613
3614 if (_IOC_SIZE(cmd_in) != sizeof(struct mtget)) {
3615 retval = (-EINVAL);
3616 goto out;
3617 }
3618
3619 mt_status.mt_type = STp->tape_type;
3620 mt_status.mt_dsreg =
3621 ((STp->block_size << MT_ST_BLKSIZE_SHIFT) & MT_ST_BLKSIZE_MASK) |
3622 ((STp->density << MT_ST_DENSITY_SHIFT) & MT_ST_DENSITY_MASK);
3623 mt_status.mt_blkno = STps->drv_block;
3624 mt_status.mt_fileno = STps->drv_file;
3625 if (STp->block_size != 0) {
3626 if (STps->rw == ST_WRITING)
3627 mt_status.mt_blkno +=
3628 (STp->buffer)->buffer_bytes / STp->block_size;
3629 else if (STps->rw == ST_READING)
3630 mt_status.mt_blkno -=
3631 ((STp->buffer)->buffer_bytes +
3632 STp->block_size - 1) / STp->block_size;
3633 }
3634
3635 mt_status.mt_gstat = 0;
3636 if (STp->drv_write_prot)
3637 mt_status.mt_gstat |= GMT_WR_PROT(0xffffffff);
3638 if (mt_status.mt_blkno == 0) {
3639 if (mt_status.mt_fileno == 0)
3640 mt_status.mt_gstat |= GMT_BOT(0xffffffff);
3641 else
3642 mt_status.mt_gstat |= GMT_EOF(0xffffffff);
3643 }
3644 mt_status.mt_erreg = (STp->recover_reg << MT_ST_SOFTERR_SHIFT);
3645 mt_status.mt_resid = STp->partition;
3646 if (STps->eof == ST_EOM_OK || STps->eof == ST_EOM_ERROR)
3647 mt_status.mt_gstat |= GMT_EOT(0xffffffff);
3648 else if (STps->eof >= ST_EOM_OK)
3649 mt_status.mt_gstat |= GMT_EOD(0xffffffff);
3650 if (STp->density == 1)
3651 mt_status.mt_gstat |= GMT_D_800(0xffffffff);
3652 else if (STp->density == 2)
3653 mt_status.mt_gstat |= GMT_D_1600(0xffffffff);
3654 else if (STp->density == 3)
3655 mt_status.mt_gstat |= GMT_D_6250(0xffffffff);
3656 if (STp->ready == ST_READY)
3657 mt_status.mt_gstat |= GMT_ONLINE(0xffffffff);
3658 if (STp->ready == ST_NO_TAPE)
3659 mt_status.mt_gstat |= GMT_DR_OPEN(0xffffffff);
3660 if (STps->at_sm)
3661 mt_status.mt_gstat |= GMT_SM(0xffffffff);
3662 if (STm->do_async_writes ||
3663 (STm->do_buffer_writes && STp->block_size != 0) ||
3664 STp->drv_buffer != 0)
3665 mt_status.mt_gstat |= GMT_IM_REP_EN(0xffffffff);
3666 if (STp->cleaning_req)
3667 mt_status.mt_gstat |= GMT_CLN(0xffffffff);
3668
3669 i = copy_to_user(p, &mt_status, sizeof(struct mtget));
3670 if (i) {
3671 retval = (-EFAULT);
3672 goto out;
3673 }
3674
3675 STp->recover_reg = 0; /* Clear after read */
3676 retval = 0;
3677 goto out;
3678 } /* End of MTIOCGET */
3679 if (cmd_type == _IOC_TYPE(MTIOCPOS) && cmd_nr == _IOC_NR(MTIOCPOS)) {
3680 struct mtpos mt_pos;
3681 if (_IOC_SIZE(cmd_in) != sizeof(struct mtpos)) {
3682 retval = (-EINVAL);
3683 goto out;
3684 }
3685 if ((i = get_location(STp, &blk, &bt, 0)) < 0) {
3686 retval = i;
3687 goto out;
3688 }
3689 mt_pos.mt_blkno = blk;
3690 i = copy_to_user(p, &mt_pos, sizeof(struct mtpos));
3691 if (i)
3692 retval = (-EFAULT);
3693 goto out;
3694 }
Matthias Kaehlcke28f85002007-07-29 23:38:15 +02003695 mutex_unlock(&STp->lock);
Linus Torvalds1da177e2005-04-16 15:20:36 -07003696 switch (cmd_in) {
3697 case SCSI_IOCTL_GET_IDLUN:
3698 case SCSI_IOCTL_GET_BUS_NUMBER:
3699 break;
3700 default:
Kai Makisara 16c4b3e2005-05-01 18:11:55 +03003701 if ((cmd_in == SG_IO ||
3702 cmd_in == SCSI_IOCTL_SEND_COMMAND ||
3703 cmd_in == CDROM_SEND_PACKET) &&
3704 !capable(CAP_SYS_RAWIO))
Linus Torvalds1da177e2005-04-16 15:20:36 -07003705 i = -EPERM;
3706 else
Al Viro74f3c8a2007-08-27 15:38:10 -04003707 i = scsi_cmd_ioctl(STp->disk->queue, STp->disk,
3708 file->f_mode, cmd_in, p);
Linus Torvalds1da177e2005-04-16 15:20:36 -07003709 if (i != -ENOTTY)
3710 return i;
3711 break;
3712 }
Kai Makisara 16c4b3e2005-05-01 18:11:55 +03003713 retval = scsi_ioctl(STp->device, cmd_in, p);
3714 if (!retval && cmd_in == SCSI_IOCTL_STOP_UNIT) { /* unload */
3715 STp->rew_at_close = 0;
3716 STp->ready = ST_NO_TAPE;
3717 }
3718 return retval;
Linus Torvalds1da177e2005-04-16 15:20:36 -07003719
3720 out:
Matthias Kaehlcke28f85002007-07-29 23:38:15 +02003721 mutex_unlock(&STp->lock);
Linus Torvalds1da177e2005-04-16 15:20:36 -07003722 return retval;
3723}
3724
3725#ifdef CONFIG_COMPAT
3726static long st_compat_ioctl(struct file *file, unsigned int cmd, unsigned long arg)
3727{
3728 struct scsi_tape *STp = file->private_data;
3729 struct scsi_device *sdev = STp->device;
3730 int ret = -ENOIOCTLCMD;
3731 if (sdev->host->hostt->compat_ioctl) {
3732
3733 ret = sdev->host->hostt->compat_ioctl(sdev, cmd, (void __user *)arg);
3734
3735 }
3736 return ret;
3737}
3738#endif
3739
3740
3741
3742/* Try to allocate a new tape buffer. Calling function must not hold
3743 dev_arr_lock. */
3744static struct st_buffer *
3745 new_tape_buffer(int from_initialization, int need_dma, int max_sg)
3746{
Mike Christie8b05b772005-11-08 04:06:44 -06003747 int i, got = 0;
Al Viroc53033f2005-10-21 03:22:08 -04003748 gfp_t priority;
Linus Torvalds1da177e2005-04-16 15:20:36 -07003749 struct st_buffer *tb;
3750
3751 if (from_initialization)
3752 priority = GFP_ATOMIC;
3753 else
3754 priority = GFP_KERNEL;
3755
FUJITA Tomonori08c95832008-12-18 14:49:45 +09003756 i = sizeof(struct st_buffer) +
3757 (max_sg - 1) * sizeof(struct scatterlist);
3758
Jes Sorensen24669f752006-01-16 10:31:18 -05003759 tb = kzalloc(i, priority);
Linus Torvalds1da177e2005-04-16 15:20:36 -07003760 if (!tb) {
3761 printk(KERN_NOTICE "st: Can't allocate new tape buffer.\n");
3762 return NULL;
3763 }
Mike Christie8b05b772005-11-08 04:06:44 -06003764 tb->frp_segs = tb->orig_frp_segs = 0;
Linus Torvalds1da177e2005-04-16 15:20:36 -07003765 tb->use_sg = max_sg;
Linus Torvalds1da177e2005-04-16 15:20:36 -07003766
Linus Torvalds1da177e2005-04-16 15:20:36 -07003767 tb->dma = need_dma;
3768 tb->buffer_size = got;
FUJITA Tomonoricd816212007-12-15 15:51:55 +09003769 sg_init_table(tb->sg, max_sg);
Linus Torvalds1da177e2005-04-16 15:20:36 -07003770
FUJITA Tomonorid0e1ae32008-12-18 14:49:40 +09003771 tb->reserved_pages = kzalloc(max_sg * sizeof(struct page *), priority);
3772 if (!tb->reserved_pages) {
3773 kfree(tb);
3774 return NULL;
3775 }
3776
Linus Torvalds1da177e2005-04-16 15:20:36 -07003777 return tb;
3778}
3779
3780
3781/* Try to allocate enough space in the tape buffer */
3782static int enlarge_buffer(struct st_buffer * STbuffer, int new_size, int need_dma)
3783{
Al Viroc53033f2005-10-21 03:22:08 -04003784 int segs, nbr, max_segs, b_size, order, got;
3785 gfp_t priority;
Linus Torvalds1da177e2005-04-16 15:20:36 -07003786
3787 if (new_size <= STbuffer->buffer_size)
3788 return 1;
3789
3790 if (STbuffer->buffer_size <= PAGE_SIZE)
3791 normalize_buffer(STbuffer); /* Avoid extra segment */
3792
3793 max_segs = STbuffer->use_sg;
3794 nbr = max_segs - STbuffer->frp_segs;
3795 if (nbr <= 0)
3796 return 0;
3797
3798 priority = GFP_KERNEL | __GFP_NOWARN;
3799 if (need_dma)
3800 priority |= GFP_DMA;
FUJITA Tomonori9c905962008-12-18 14:49:39 +09003801
FUJITA Tomonori08c95832008-12-18 14:49:45 +09003802 if (STbuffer->cleared)
3803 priority |= __GFP_ZERO;
3804
FUJITA Tomonori9c905962008-12-18 14:49:39 +09003805 if (STbuffer->frp_segs) {
FUJITA Tomonori08c95832008-12-18 14:49:45 +09003806 order = STbuffer->map_data.page_order;
3807 b_size = PAGE_SIZE << order;
FUJITA Tomonori9c905962008-12-18 14:49:39 +09003808 } else {
3809 for (b_size = PAGE_SIZE, order = 0;
3810 order <= 6 && b_size < new_size; order++, b_size *= 2)
3811 ; /* empty */
3812 }
Linus Torvalds1da177e2005-04-16 15:20:36 -07003813
3814 for (segs = STbuffer->frp_segs, got = STbuffer->buffer_size;
3815 segs < max_segs && got < new_size;) {
FUJITA Tomonori08c95832008-12-18 14:49:45 +09003816 struct page *page;
3817
3818 page = alloc_pages(priority, order);
3819 if (!page) {
Linus Torvalds1da177e2005-04-16 15:20:36 -07003820 DEB(STbuffer->buffer_size = got);
3821 normalize_buffer(STbuffer);
3822 return 0;
3823 }
FUJITA Tomonori08c95832008-12-18 14:49:45 +09003824
Linus Torvalds1da177e2005-04-16 15:20:36 -07003825 STbuffer->frp_segs += 1;
3826 got += b_size;
3827 STbuffer->buffer_size = got;
FUJITA Tomonori08c95832008-12-18 14:49:45 +09003828 STbuffer->reserved_pages[segs] = page;
Linus Torvalds1da177e2005-04-16 15:20:36 -07003829 segs++;
3830 }
FUJITA Tomonori08c95832008-12-18 14:49:45 +09003831 STbuffer->b_data = page_address(STbuffer->reserved_pages[0]);
FUJITA Tomonorid0e1ae32008-12-18 14:49:40 +09003832 STbuffer->map_data.page_order = order;
Linus Torvalds1da177e2005-04-16 15:20:36 -07003833
3834 return 1;
3835}
3836
3837
Kai Makisara40f6b362008-02-24 22:23:24 +02003838/* Make sure that no data from previous user is in the internal buffer */
3839static void clear_buffer(struct st_buffer * st_bp)
3840{
3841 int i;
3842
3843 for (i=0; i < st_bp->frp_segs; i++)
FUJITA Tomonori08c95832008-12-18 14:49:45 +09003844 memset(page_address(st_bp->reserved_pages[i]), 0,
3845 PAGE_SIZE << st_bp->map_data.page_order);
Kai Makisara40f6b362008-02-24 22:23:24 +02003846 st_bp->cleared = 1;
3847}
3848
3849
Linus Torvalds1da177e2005-04-16 15:20:36 -07003850/* Release the extra buffer */
3851static void normalize_buffer(struct st_buffer * STbuffer)
3852{
FUJITA Tomonori08c95832008-12-18 14:49:45 +09003853 int i, order = STbuffer->map_data.page_order;
Linus Torvalds1da177e2005-04-16 15:20:36 -07003854
3855 for (i = STbuffer->orig_frp_segs; i < STbuffer->frp_segs; i++) {
FUJITA Tomonori08c95832008-12-18 14:49:45 +09003856 __free_pages(STbuffer->reserved_pages[i], order);
3857 STbuffer->buffer_size -= (PAGE_SIZE << order);
Linus Torvalds1da177e2005-04-16 15:20:36 -07003858 }
3859 STbuffer->frp_segs = STbuffer->orig_frp_segs;
3860 STbuffer->frp_sg_current = 0;
Mike Christie8b05b772005-11-08 04:06:44 -06003861 STbuffer->sg_segs = 0;
FUJITA Tomonorid0e1ae32008-12-18 14:49:40 +09003862 STbuffer->map_data.page_order = 0;
3863 STbuffer->map_data.offset = 0;
Linus Torvalds1da177e2005-04-16 15:20:36 -07003864}
3865
3866
3867/* Move data from the user buffer to the tape buffer. Returns zero (success) or
3868 negative error code. */
3869static int append_to_buffer(const char __user *ubp, struct st_buffer * st_bp, int do_count)
3870{
3871 int i, cnt, res, offset;
FUJITA Tomonori08c95832008-12-18 14:49:45 +09003872 int length = PAGE_SIZE << st_bp->map_data.page_order;
Linus Torvalds1da177e2005-04-16 15:20:36 -07003873
3874 for (i = 0, offset = st_bp->buffer_bytes;
FUJITA Tomonori08c95832008-12-18 14:49:45 +09003875 i < st_bp->frp_segs && offset >= length; i++)
3876 offset -= length;
Linus Torvalds1da177e2005-04-16 15:20:36 -07003877 if (i == st_bp->frp_segs) { /* Should never happen */
3878 printk(KERN_WARNING "st: append_to_buffer offset overflow.\n");
3879 return (-EIO);
3880 }
3881 for (; i < st_bp->frp_segs && do_count > 0; i++) {
FUJITA Tomonori08c95832008-12-18 14:49:45 +09003882 struct page *page = st_bp->reserved_pages[i];
3883 cnt = length - offset < do_count ? length - offset : do_count;
3884 res = copy_from_user(page_address(page) + offset, ubp, cnt);
Linus Torvalds1da177e2005-04-16 15:20:36 -07003885 if (res)
3886 return (-EFAULT);
3887 do_count -= cnt;
3888 st_bp->buffer_bytes += cnt;
3889 ubp += cnt;
3890 offset = 0;
3891 }
3892 if (do_count) /* Should never happen */
3893 return (-EIO);
3894
3895 return 0;
3896}
3897
3898
3899/* Move data from the tape buffer to the user buffer. Returns zero (success) or
3900 negative error code. */
3901static int from_buffer(struct st_buffer * st_bp, char __user *ubp, int do_count)
3902{
3903 int i, cnt, res, offset;
FUJITA Tomonori08c95832008-12-18 14:49:45 +09003904 int length = PAGE_SIZE << st_bp->map_data.page_order;
Linus Torvalds1da177e2005-04-16 15:20:36 -07003905
3906 for (i = 0, offset = st_bp->read_pointer;
FUJITA Tomonori08c95832008-12-18 14:49:45 +09003907 i < st_bp->frp_segs && offset >= length; i++)
3908 offset -= length;
Linus Torvalds1da177e2005-04-16 15:20:36 -07003909 if (i == st_bp->frp_segs) { /* Should never happen */
3910 printk(KERN_WARNING "st: from_buffer offset overflow.\n");
3911 return (-EIO);
3912 }
3913 for (; i < st_bp->frp_segs && do_count > 0; i++) {
FUJITA Tomonori08c95832008-12-18 14:49:45 +09003914 struct page *page = st_bp->reserved_pages[i];
3915 cnt = length - offset < do_count ? length - offset : do_count;
3916 res = copy_to_user(ubp, page_address(page) + offset, cnt);
Linus Torvalds1da177e2005-04-16 15:20:36 -07003917 if (res)
3918 return (-EFAULT);
3919 do_count -= cnt;
3920 st_bp->buffer_bytes -= cnt;
3921 st_bp->read_pointer += cnt;
3922 ubp += cnt;
3923 offset = 0;
3924 }
3925 if (do_count) /* Should never happen */
3926 return (-EIO);
3927
3928 return 0;
3929}
3930
3931
3932/* Move data towards start of buffer */
3933static void move_buffer_data(struct st_buffer * st_bp, int offset)
3934{
3935 int src_seg, dst_seg, src_offset = 0, dst_offset;
3936 int count, total;
FUJITA Tomonori08c95832008-12-18 14:49:45 +09003937 int length = PAGE_SIZE << st_bp->map_data.page_order;
Linus Torvalds1da177e2005-04-16 15:20:36 -07003938
3939 if (offset == 0)
3940 return;
3941
3942 total=st_bp->buffer_bytes - offset;
3943 for (src_seg=0; src_seg < st_bp->frp_segs; src_seg++) {
3944 src_offset = offset;
FUJITA Tomonori08c95832008-12-18 14:49:45 +09003945 if (src_offset < length)
Linus Torvalds1da177e2005-04-16 15:20:36 -07003946 break;
FUJITA Tomonori08c95832008-12-18 14:49:45 +09003947 offset -= length;
Linus Torvalds1da177e2005-04-16 15:20:36 -07003948 }
3949
3950 st_bp->buffer_bytes = st_bp->read_pointer = total;
3951 for (dst_seg=dst_offset=0; total > 0; ) {
FUJITA Tomonori08c95832008-12-18 14:49:45 +09003952 struct page *dpage = st_bp->reserved_pages[dst_seg];
3953 struct page *spage = st_bp->reserved_pages[src_seg];
3954
3955 count = min(length - dst_offset, length - src_offset);
3956 memmove(page_address(dpage) + dst_offset,
3957 page_address(spage) + src_offset, count);
Linus Torvalds1da177e2005-04-16 15:20:36 -07003958 src_offset += count;
FUJITA Tomonori08c95832008-12-18 14:49:45 +09003959 if (src_offset >= length) {
Linus Torvalds1da177e2005-04-16 15:20:36 -07003960 src_seg++;
3961 src_offset = 0;
3962 }
3963 dst_offset += count;
FUJITA Tomonori08c95832008-12-18 14:49:45 +09003964 if (dst_offset >= length) {
Linus Torvalds1da177e2005-04-16 15:20:36 -07003965 dst_seg++;
3966 dst_offset = 0;
3967 }
3968 total -= count;
3969 }
3970}
3971
Linus Torvalds1da177e2005-04-16 15:20:36 -07003972/* Validate the options from command line or module parameters */
3973static void validate_options(void)
3974{
3975 if (buffer_kbs > 0)
3976 st_fixed_buffer_size = buffer_kbs * ST_KILOBYTE;
3977 if (max_sg_segs >= ST_FIRST_SG)
3978 st_max_sg_segs = max_sg_segs;
3979}
3980
3981#ifndef MODULE
3982/* Set the boot options. Syntax is defined in Documenation/scsi/st.txt.
3983 */
3984static int __init st_setup(char *str)
3985{
3986 int i, len, ints[5];
3987 char *stp;
3988
3989 stp = get_options(str, ARRAY_SIZE(ints), ints);
3990
3991 if (ints[0] > 0) {
3992 for (i = 0; i < ints[0] && i < ARRAY_SIZE(parms); i++)
3993 if (parms[i].val)
3994 *parms[i].val = ints[i + 1];
3995 } else {
3996 while (stp != NULL) {
3997 for (i = 0; i < ARRAY_SIZE(parms); i++) {
3998 len = strlen(parms[i].name);
3999 if (!strncmp(stp, parms[i].name, len) &&
4000 (*(stp + len) == ':' || *(stp + len) == '=')) {
4001 if (parms[i].val)
4002 *parms[i].val =
4003 simple_strtoul(stp + len + 1, NULL, 0);
4004 else
4005 printk(KERN_WARNING "st: Obsolete parameter %s\n",
4006 parms[i].name);
4007 break;
4008 }
4009 }
Tobias Klauser6391a112006-06-08 22:23:48 -07004010 if (i >= ARRAY_SIZE(parms))
Linus Torvalds1da177e2005-04-16 15:20:36 -07004011 printk(KERN_WARNING "st: invalid parameter in '%s'\n",
4012 stp);
4013 stp = strchr(stp, ',');
4014 if (stp)
4015 stp++;
4016 }
4017 }
4018
4019 validate_options();
4020
4021 return 1;
4022}
4023
4024__setup("st=", st_setup);
4025
4026#endif
4027
Arjan van de Ven00977a52007-02-12 00:55:34 -08004028static const struct file_operations st_fops =
Linus Torvalds1da177e2005-04-16 15:20:36 -07004029{
4030 .owner = THIS_MODULE,
4031 .read = st_read,
4032 .write = st_write,
Kai Makisarafd66c1b2008-01-17 22:45:22 +02004033 .unlocked_ioctl = st_ioctl,
Linus Torvalds1da177e2005-04-16 15:20:36 -07004034#ifdef CONFIG_COMPAT
4035 .compat_ioctl = st_compat_ioctl,
4036#endif
4037 .open = st_open,
4038 .flush = st_flush,
4039 .release = st_release,
4040};
4041
4042static int st_probe(struct device *dev)
4043{
4044 struct scsi_device *SDp = to_scsi_device(dev);
4045 struct gendisk *disk = NULL;
4046 struct cdev *cdev = NULL;
4047 struct scsi_tape *tpnt = NULL;
4048 struct st_modedef *STm;
4049 struct st_partstat *STps;
4050 struct st_buffer *buffer;
4051 int i, j, mode, dev_num, error;
4052 char *stp;
Linus Torvalds1da177e2005-04-16 15:20:36 -07004053
4054 if (SDp->type != TYPE_TAPE)
4055 return -ENODEV;
4056 if ((stp = st_incompatible(SDp))) {
Jeff Garzik3bf743e2005-10-24 18:04:06 -04004057 sdev_printk(KERN_INFO, SDp, "Found incompatible tape\n");
Linus Torvalds1da177e2005-04-16 15:20:36 -07004058 printk(KERN_INFO "st: The suggested driver is %s.\n", stp);
4059 return -ENODEV;
4060 }
4061
Mike Christie8b05b772005-11-08 04:06:44 -06004062 i = min(SDp->request_queue->max_hw_segments,
4063 SDp->request_queue->max_phys_segments);
Linus Torvalds1da177e2005-04-16 15:20:36 -07004064 if (st_max_sg_segs < i)
4065 i = st_max_sg_segs;
4066 buffer = new_tape_buffer(1, (SDp->host)->unchecked_isa_dma, i);
4067 if (buffer == NULL) {
4068 printk(KERN_ERR
4069 "st: Can't allocate new tape buffer. Device not attached.\n");
4070 goto out;
4071 }
4072
4073 disk = alloc_disk(1);
4074 if (!disk) {
4075 printk(KERN_ERR "st: out of memory. Device not attached.\n");
4076 goto out_buffer_free;
4077 }
4078
4079 write_lock(&st_dev_arr_lock);
4080 if (st_nr_dev >= st_dev_max) {
4081 struct scsi_tape **tmp_da;
4082 int tmp_dev_max;
4083
4084 tmp_dev_max = max(st_nr_dev * 2, 8);
4085 if (tmp_dev_max > ST_MAX_TAPES)
4086 tmp_dev_max = ST_MAX_TAPES;
4087 if (tmp_dev_max <= st_nr_dev) {
4088 write_unlock(&st_dev_arr_lock);
4089 printk(KERN_ERR "st: Too many tape devices (max. %d).\n",
4090 ST_MAX_TAPES);
4091 goto out_put_disk;
4092 }
4093
Jes Sorensen24669f752006-01-16 10:31:18 -05004094 tmp_da = kzalloc(tmp_dev_max * sizeof(struct scsi_tape *), GFP_ATOMIC);
Linus Torvalds1da177e2005-04-16 15:20:36 -07004095 if (tmp_da == NULL) {
4096 write_unlock(&st_dev_arr_lock);
4097 printk(KERN_ERR "st: Can't extend device array.\n");
4098 goto out_put_disk;
4099 }
4100
Linus Torvalds1da177e2005-04-16 15:20:36 -07004101 if (scsi_tapes != NULL) {
4102 memcpy(tmp_da, scsi_tapes,
4103 st_dev_max * sizeof(struct scsi_tape *));
4104 kfree(scsi_tapes);
4105 }
4106 scsi_tapes = tmp_da;
4107
4108 st_dev_max = tmp_dev_max;
4109 }
4110
4111 for (i = 0; i < st_dev_max; i++)
4112 if (scsi_tapes[i] == NULL)
4113 break;
4114 if (i >= st_dev_max)
4115 panic("scsi_devices corrupt (st)");
4116
Jes Sorensen24669f752006-01-16 10:31:18 -05004117 tpnt = kzalloc(sizeof(struct scsi_tape), GFP_ATOMIC);
Linus Torvalds1da177e2005-04-16 15:20:36 -07004118 if (tpnt == NULL) {
4119 write_unlock(&st_dev_arr_lock);
4120 printk(KERN_ERR "st: Can't allocate device descriptor.\n");
4121 goto out_put_disk;
4122 }
Kai Makisaraf03a5672005-08-02 13:40:47 +03004123 kref_init(&tpnt->kref);
Linus Torvalds1da177e2005-04-16 15:20:36 -07004124 tpnt->disk = disk;
4125 sprintf(disk->disk_name, "st%d", i);
4126 disk->private_data = &tpnt->driver;
4127 disk->queue = SDp->request_queue;
4128 tpnt->driver = &st_template;
4129 scsi_tapes[i] = tpnt;
4130 dev_num = i;
4131
4132 tpnt->device = SDp;
4133 if (SDp->scsi_level <= 2)
4134 tpnt->tape_type = MT_ISSCSI1;
4135 else
4136 tpnt->tape_type = MT_ISSCSI2;
4137
4138 tpnt->buffer = buffer;
Kai Makisaraf03a5672005-08-02 13:40:47 +03004139 tpnt->buffer->last_SRpnt = NULL;
Linus Torvalds1da177e2005-04-16 15:20:36 -07004140
4141 tpnt->inited = 0;
4142 tpnt->dirty = 0;
4143 tpnt->in_use = 0;
4144 tpnt->drv_buffer = 1; /* Try buffering if no mode sense */
4145 tpnt->restr_dma = (SDp->host)->unchecked_isa_dma;
4146 tpnt->use_pf = (SDp->scsi_level >= SCSI_2);
4147 tpnt->density = 0;
4148 tpnt->do_auto_lock = ST_AUTO_LOCK;
4149 tpnt->can_bsr = (SDp->scsi_level > 2 ? 1 : ST_IN_FILE_POS); /* BSR mandatory in SCSI3 */
4150 tpnt->can_partitions = 0;
4151 tpnt->two_fm = ST_TWO_FM;
4152 tpnt->fast_mteom = ST_FAST_MTEOM;
4153 tpnt->scsi2_logical = ST_SCSI2LOGICAL;
Kai Makisara40f6b362008-02-24 22:23:24 +02004154 tpnt->sili = ST_SILI;
Linus Torvalds1da177e2005-04-16 15:20:36 -07004155 tpnt->immediate = ST_NOWAIT;
4156 tpnt->default_drvbuffer = 0xff; /* No forced buffering */
4157 tpnt->partition = 0;
4158 tpnt->new_partition = 0;
4159 tpnt->nbr_partitions = 0;
James Bottomleya02488e2008-11-30 10:36:26 -06004160 blk_queue_rq_timeout(tpnt->device->request_queue, ST_TIMEOUT);
Linus Torvalds1da177e2005-04-16 15:20:36 -07004161 tpnt->long_timeout = ST_LONG_TIMEOUT;
4162 tpnt->try_dio = try_direct_io && !SDp->host->unchecked_isa_dma;
4163
Linus Torvalds1da177e2005-04-16 15:20:36 -07004164 for (i = 0; i < ST_NBR_MODES; i++) {
4165 STm = &(tpnt->modes[i]);
4166 STm->defined = 0;
4167 STm->sysv = ST_SYSV;
4168 STm->defaults_for_writes = 0;
4169 STm->do_async_writes = ST_ASYNC_WRITES;
4170 STm->do_buffer_writes = ST_BUFFER_WRITES;
4171 STm->do_read_ahead = ST_READ_AHEAD;
4172 STm->default_compression = ST_DONT_TOUCH;
4173 STm->default_blksize = (-1); /* No forced size */
4174 STm->default_density = (-1); /* No forced density */
4175 }
4176
4177 for (i = 0; i < ST_NBR_PARTITIONS; i++) {
4178 STps = &(tpnt->ps[i]);
4179 STps->rw = ST_IDLE;
4180 STps->eof = ST_NOEOF;
4181 STps->at_sm = 0;
4182 STps->last_block_valid = 0;
4183 STps->drv_block = (-1);
4184 STps->drv_file = (-1);
4185 }
4186
4187 tpnt->current_mode = 0;
4188 tpnt->modes[0].defined = 1;
4189
4190 tpnt->density_changed = tpnt->compression_changed =
4191 tpnt->blksize_changed = 0;
Matthias Kaehlcke28f85002007-07-29 23:38:15 +02004192 mutex_init(&tpnt->lock);
Linus Torvalds1da177e2005-04-16 15:20:36 -07004193
4194 st_nr_dev++;
4195 write_unlock(&st_dev_arr_lock);
4196
4197 for (mode = 0; mode < ST_NBR_MODES; ++mode) {
4198 STm = &(tpnt->modes[mode]);
4199 for (j=0; j < 2; j++) {
4200 cdev = cdev_alloc();
4201 if (!cdev) {
4202 printk(KERN_ERR
4203 "st%d: out of memory. Device not attached.\n",
4204 dev_num);
4205 goto out_free_tape;
4206 }
4207 cdev->owner = THIS_MODULE;
4208 cdev->ops = &st_fops;
4209
4210 error = cdev_add(cdev,
4211 MKDEV(SCSI_TAPE_MAJOR, TAPE_MINOR(dev_num, mode, j)),
4212 1);
4213 if (error) {
4214 printk(KERN_ERR "st%d: Can't add %s-rewind mode %d\n",
4215 dev_num, j ? "non" : "auto", mode);
4216 printk(KERN_ERR "st%d: Device not attached.\n", dev_num);
4217 goto out_free_tape;
4218 }
4219 STm->cdevs[j] = cdev;
4220
4221 }
Jeff Garzik13026a62006-10-04 06:00:38 -04004222 error = do_create_class_files(tpnt, dev_num, mode);
4223 if (error)
4224 goto out_free_tape;
Linus Torvalds1da177e2005-04-16 15:20:36 -07004225 }
4226
Kai Makisara42252852006-11-07 21:56:38 +02004227 sdev_printk(KERN_NOTICE, SDp,
Rene Herman8b1ea242006-05-20 15:00:22 -07004228 "Attached scsi tape %s\n", tape_name(tpnt));
Kai Makisara42252852006-11-07 21:56:38 +02004229 sdev_printk(KERN_INFO, SDp, "%s: try direct i/o: %s (alignment %d B)\n",
4230 tape_name(tpnt), tpnt->try_dio ? "yes" : "no",
4231 queue_dma_alignment(SDp->request_queue) + 1);
Linus Torvalds1da177e2005-04-16 15:20:36 -07004232
4233 return 0;
4234
4235out_free_tape:
4236 for (mode=0; mode < ST_NBR_MODES; mode++) {
4237 STm = &(tpnt->modes[mode]);
4238 sysfs_remove_link(&tpnt->device->sdev_gendev.kobj,
4239 "tape");
4240 for (j=0; j < 2; j++) {
4241 if (STm->cdevs[j]) {
4242 if (cdev == STm->cdevs[j])
4243 cdev = NULL;
Tony Jonesee959b02008-02-22 00:13:36 +01004244 device_destroy(st_sysfs_class,
4245 MKDEV(SCSI_TAPE_MAJOR,
4246 TAPE_MINOR(i, mode, j)));
Linus Torvalds1da177e2005-04-16 15:20:36 -07004247 cdev_del(STm->cdevs[j]);
4248 }
4249 }
4250 }
4251 if (cdev)
4252 cdev_del(cdev);
4253 write_lock(&st_dev_arr_lock);
4254 scsi_tapes[dev_num] = NULL;
4255 st_nr_dev--;
4256 write_unlock(&st_dev_arr_lock);
4257out_put_disk:
4258 put_disk(disk);
Jesper Juhlc9475cb2005-11-07 01:01:26 -08004259 kfree(tpnt);
Linus Torvalds1da177e2005-04-16 15:20:36 -07004260out_buffer_free:
4261 kfree(buffer);
4262out:
4263 return -ENODEV;
4264};
4265
4266
4267static int st_remove(struct device *dev)
4268{
4269 struct scsi_device *SDp = to_scsi_device(dev);
4270 struct scsi_tape *tpnt;
4271 int i, j, mode;
4272
4273 write_lock(&st_dev_arr_lock);
4274 for (i = 0; i < st_dev_max; i++) {
4275 tpnt = scsi_tapes[i];
4276 if (tpnt != NULL && tpnt->device == SDp) {
4277 scsi_tapes[i] = NULL;
4278 st_nr_dev--;
4279 write_unlock(&st_dev_arr_lock);
Linus Torvalds1da177e2005-04-16 15:20:36 -07004280 sysfs_remove_link(&tpnt->device->sdev_gendev.kobj,
4281 "tape");
4282 for (mode = 0; mode < ST_NBR_MODES; ++mode) {
Linus Torvalds1da177e2005-04-16 15:20:36 -07004283 for (j=0; j < 2; j++) {
Tony Jonesee959b02008-02-22 00:13:36 +01004284 device_destroy(st_sysfs_class,
4285 MKDEV(SCSI_TAPE_MAJOR,
4286 TAPE_MINOR(i, mode, j)));
Linus Torvalds1da177e2005-04-16 15:20:36 -07004287 cdev_del(tpnt->modes[mode].cdevs[j]);
4288 tpnt->modes[mode].cdevs[j] = NULL;
4289 }
4290 }
Linus Torvalds1da177e2005-04-16 15:20:36 -07004291
Arjan van de Ven0b950672006-01-11 13:16:10 +01004292 mutex_lock(&st_ref_mutex);
Kai Makisaraf03a5672005-08-02 13:40:47 +03004293 kref_put(&tpnt->kref, scsi_tape_release);
Arjan van de Ven0b950672006-01-11 13:16:10 +01004294 mutex_unlock(&st_ref_mutex);
Linus Torvalds1da177e2005-04-16 15:20:36 -07004295 return 0;
4296 }
4297 }
4298
4299 write_unlock(&st_dev_arr_lock);
4300 return 0;
4301}
4302
Kai Makisaraf03a5672005-08-02 13:40:47 +03004303/**
4304 * scsi_tape_release - Called to free the Scsi_Tape structure
4305 * @kref: pointer to embedded kref
4306 *
Arjan van de Ven0b950672006-01-11 13:16:10 +01004307 * st_ref_mutex must be held entering this routine. Because it is
Kai Makisaraf03a5672005-08-02 13:40:47 +03004308 * called on last put, you should always use the scsi_tape_get()
4309 * scsi_tape_put() helpers which manipulate the semaphore directly
4310 * and never do a direct kref_put().
4311 **/
4312static void scsi_tape_release(struct kref *kref)
4313{
4314 struct scsi_tape *tpnt = to_scsi_tape(kref);
4315 struct gendisk *disk = tpnt->disk;
4316
4317 tpnt->device = NULL;
4318
4319 if (tpnt->buffer) {
4320 tpnt->buffer->orig_frp_segs = 0;
4321 normalize_buffer(tpnt->buffer);
FUJITA Tomonorid0e1ae32008-12-18 14:49:40 +09004322 kfree(tpnt->buffer->reserved_pages);
Kai Makisaraf03a5672005-08-02 13:40:47 +03004323 kfree(tpnt->buffer);
4324 }
4325
4326 disk->private_data = NULL;
4327 put_disk(disk);
4328 kfree(tpnt);
4329 return;
4330}
4331
Linus Torvalds1da177e2005-04-16 15:20:36 -07004332static int __init init_st(void)
4333{
Jeff Garzik13026a62006-10-04 06:00:38 -04004334 int err;
4335
Linus Torvalds1da177e2005-04-16 15:20:36 -07004336 validate_options();
4337
Jeff Garzik13026a62006-10-04 06:00:38 -04004338 printk(KERN_INFO "st: Version %s, fixed bufsize %d, s/g segs %d\n",
Linus Torvalds1da177e2005-04-16 15:20:36 -07004339 verstr, st_fixed_buffer_size, st_max_sg_segs);
4340
gregkh@suse.ded2538782005-03-23 09:55:22 -08004341 st_sysfs_class = class_create(THIS_MODULE, "scsi_tape");
Linus Torvalds1da177e2005-04-16 15:20:36 -07004342 if (IS_ERR(st_sysfs_class)) {
Linus Torvalds1da177e2005-04-16 15:20:36 -07004343 printk(KERN_ERR "Unable create sysfs class for SCSI tapes\n");
Jeff Garzik13026a62006-10-04 06:00:38 -04004344 return PTR_ERR(st_sysfs_class);
Linus Torvalds1da177e2005-04-16 15:20:36 -07004345 }
4346
Jeff Garzik13026a62006-10-04 06:00:38 -04004347 err = register_chrdev_region(MKDEV(SCSI_TAPE_MAJOR, 0),
4348 ST_MAX_TAPE_ENTRIES, "st");
4349 if (err) {
4350 printk(KERN_ERR "Unable to get major %d for SCSI tapes\n",
4351 SCSI_TAPE_MAJOR);
4352 goto err_class;
Linus Torvalds1da177e2005-04-16 15:20:36 -07004353 }
Jeff Garzik13026a62006-10-04 06:00:38 -04004354
4355 err = scsi_register_driver(&st_template.gendrv);
4356 if (err)
4357 goto err_chrdev;
4358
Robert P. J. Day405ae7d2007-02-17 19:13:42 +01004359 err = do_create_sysfs_files();
Jeff Garzik13026a62006-10-04 06:00:38 -04004360 if (err)
4361 goto err_scsidrv;
4362
4363 return 0;
4364
4365err_scsidrv:
4366 scsi_unregister_driver(&st_template.gendrv);
4367err_chrdev:
4368 unregister_chrdev_region(MKDEV(SCSI_TAPE_MAJOR, 0),
4369 ST_MAX_TAPE_ENTRIES);
4370err_class:
Kai Makisarac2c96f42005-08-02 12:21:51 +03004371 class_destroy(st_sysfs_class);
Jeff Garzik13026a62006-10-04 06:00:38 -04004372 return err;
Linus Torvalds1da177e2005-04-16 15:20:36 -07004373}
4374
4375static void __exit exit_st(void)
4376{
Robert P. J. Day405ae7d2007-02-17 19:13:42 +01004377 do_remove_sysfs_files();
Linus Torvalds1da177e2005-04-16 15:20:36 -07004378 scsi_unregister_driver(&st_template.gendrv);
4379 unregister_chrdev_region(MKDEV(SCSI_TAPE_MAJOR, 0),
4380 ST_MAX_TAPE_ENTRIES);
Kai Makisarac2c96f42005-08-02 12:21:51 +03004381 class_destroy(st_sysfs_class);
Linus Torvalds1da177e2005-04-16 15:20:36 -07004382 kfree(scsi_tapes);
4383 printk(KERN_INFO "st: Unloaded.\n");
4384}
4385
4386module_init(init_st);
4387module_exit(exit_st);
4388
4389
4390/* The sysfs driver interface. Read-only at the moment */
4391static ssize_t st_try_direct_io_show(struct device_driver *ddp, char *buf)
4392{
4393 return snprintf(buf, PAGE_SIZE, "%d\n", try_direct_io);
4394}
4395static DRIVER_ATTR(try_direct_io, S_IRUGO, st_try_direct_io_show, NULL);
4396
4397static ssize_t st_fixed_buffer_size_show(struct device_driver *ddp, char *buf)
4398{
4399 return snprintf(buf, PAGE_SIZE, "%d\n", st_fixed_buffer_size);
4400}
4401static DRIVER_ATTR(fixed_buffer_size, S_IRUGO, st_fixed_buffer_size_show, NULL);
4402
4403static ssize_t st_max_sg_segs_show(struct device_driver *ddp, char *buf)
4404{
4405 return snprintf(buf, PAGE_SIZE, "%d\n", st_max_sg_segs);
4406}
4407static DRIVER_ATTR(max_sg_segs, S_IRUGO, st_max_sg_segs_show, NULL);
4408
4409static ssize_t st_version_show(struct device_driver *ddd, char *buf)
4410{
4411 return snprintf(buf, PAGE_SIZE, "[%s]\n", verstr);
4412}
4413static DRIVER_ATTR(version, S_IRUGO, st_version_show, NULL);
4414
Robert P. J. Day405ae7d2007-02-17 19:13:42 +01004415static int do_create_sysfs_files(void)
Linus Torvalds1da177e2005-04-16 15:20:36 -07004416{
Robert P. J. Day405ae7d2007-02-17 19:13:42 +01004417 struct device_driver *sysfs = &st_template.gendrv;
Jeff Garzik13026a62006-10-04 06:00:38 -04004418 int err;
Linus Torvalds1da177e2005-04-16 15:20:36 -07004419
Robert P. J. Day405ae7d2007-02-17 19:13:42 +01004420 err = driver_create_file(sysfs, &driver_attr_try_direct_io);
Jeff Garzik13026a62006-10-04 06:00:38 -04004421 if (err)
4422 return err;
Robert P. J. Day405ae7d2007-02-17 19:13:42 +01004423 err = driver_create_file(sysfs, &driver_attr_fixed_buffer_size);
Jeff Garzik13026a62006-10-04 06:00:38 -04004424 if (err)
4425 goto err_try_direct_io;
Robert P. J. Day405ae7d2007-02-17 19:13:42 +01004426 err = driver_create_file(sysfs, &driver_attr_max_sg_segs);
Jeff Garzik13026a62006-10-04 06:00:38 -04004427 if (err)
4428 goto err_attr_fixed_buf;
Robert P. J. Day405ae7d2007-02-17 19:13:42 +01004429 err = driver_create_file(sysfs, &driver_attr_version);
Jeff Garzik13026a62006-10-04 06:00:38 -04004430 if (err)
4431 goto err_attr_max_sg;
4432
4433 return 0;
4434
4435err_attr_max_sg:
Robert P. J. Day405ae7d2007-02-17 19:13:42 +01004436 driver_remove_file(sysfs, &driver_attr_max_sg_segs);
Jeff Garzik13026a62006-10-04 06:00:38 -04004437err_attr_fixed_buf:
Robert P. J. Day405ae7d2007-02-17 19:13:42 +01004438 driver_remove_file(sysfs, &driver_attr_fixed_buffer_size);
Jeff Garzik13026a62006-10-04 06:00:38 -04004439err_try_direct_io:
Robert P. J. Day405ae7d2007-02-17 19:13:42 +01004440 driver_remove_file(sysfs, &driver_attr_try_direct_io);
Jeff Garzik13026a62006-10-04 06:00:38 -04004441 return err;
Linus Torvalds1da177e2005-04-16 15:20:36 -07004442}
4443
Robert P. J. Day405ae7d2007-02-17 19:13:42 +01004444static void do_remove_sysfs_files(void)
Linus Torvalds1da177e2005-04-16 15:20:36 -07004445{
Robert P. J. Day405ae7d2007-02-17 19:13:42 +01004446 struct device_driver *sysfs = &st_template.gendrv;
Linus Torvalds1da177e2005-04-16 15:20:36 -07004447
Robert P. J. Day405ae7d2007-02-17 19:13:42 +01004448 driver_remove_file(sysfs, &driver_attr_version);
4449 driver_remove_file(sysfs, &driver_attr_max_sg_segs);
4450 driver_remove_file(sysfs, &driver_attr_fixed_buffer_size);
4451 driver_remove_file(sysfs, &driver_attr_try_direct_io);
Linus Torvalds1da177e2005-04-16 15:20:36 -07004452}
4453
4454
4455/* The sysfs simple class interface */
Tony Jonesee959b02008-02-22 00:13:36 +01004456static ssize_t
4457st_defined_show(struct device *dev, struct device_attribute *attr, char *buf)
Linus Torvalds1da177e2005-04-16 15:20:36 -07004458{
James Bottomley7d15d6a2008-03-14 14:12:43 -07004459 struct st_modedef *STm = dev_get_drvdata(dev);
Linus Torvalds1da177e2005-04-16 15:20:36 -07004460 ssize_t l = 0;
4461
4462 l = snprintf(buf, PAGE_SIZE, "%d\n", STm->defined);
4463 return l;
4464}
4465
Tony Jonesee959b02008-02-22 00:13:36 +01004466DEVICE_ATTR(defined, S_IRUGO, st_defined_show, NULL);
Linus Torvalds1da177e2005-04-16 15:20:36 -07004467
Tony Jonesee959b02008-02-22 00:13:36 +01004468static ssize_t
4469st_defblk_show(struct device *dev, struct device_attribute *attr, char *buf)
Linus Torvalds1da177e2005-04-16 15:20:36 -07004470{
James Bottomley7d15d6a2008-03-14 14:12:43 -07004471 struct st_modedef *STm = dev_get_drvdata(dev);
Linus Torvalds1da177e2005-04-16 15:20:36 -07004472 ssize_t l = 0;
4473
4474 l = snprintf(buf, PAGE_SIZE, "%d\n", STm->default_blksize);
4475 return l;
4476}
4477
Tony Jonesee959b02008-02-22 00:13:36 +01004478DEVICE_ATTR(default_blksize, S_IRUGO, st_defblk_show, NULL);
Linus Torvalds1da177e2005-04-16 15:20:36 -07004479
Tony Jonesee959b02008-02-22 00:13:36 +01004480static ssize_t
4481st_defdensity_show(struct device *dev, struct device_attribute *attr, char *buf)
Linus Torvalds1da177e2005-04-16 15:20:36 -07004482{
James Bottomley7d15d6a2008-03-14 14:12:43 -07004483 struct st_modedef *STm = dev_get_drvdata(dev);
Linus Torvalds1da177e2005-04-16 15:20:36 -07004484 ssize_t l = 0;
4485 char *fmt;
4486
4487 fmt = STm->default_density >= 0 ? "0x%02x\n" : "%d\n";
4488 l = snprintf(buf, PAGE_SIZE, fmt, STm->default_density);
4489 return l;
4490}
4491
Tony Jonesee959b02008-02-22 00:13:36 +01004492DEVICE_ATTR(default_density, S_IRUGO, st_defdensity_show, NULL);
Linus Torvalds1da177e2005-04-16 15:20:36 -07004493
Tony Jonesee959b02008-02-22 00:13:36 +01004494static ssize_t
4495st_defcompression_show(struct device *dev, struct device_attribute *attr,
4496 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_compression - 1);
4502 return l;
4503}
4504
Tony Jonesee959b02008-02-22 00:13:36 +01004505DEVICE_ATTR(default_compression, S_IRUGO, st_defcompression_show, NULL);
Linus Torvalds1da177e2005-04-16 15:20:36 -07004506
Tony Jonesee959b02008-02-22 00:13:36 +01004507static ssize_t
4508st_options_show(struct device *dev, struct device_attribute *attr, char *buf)
Kai Makisarab174be02008-02-24 22:29:12 +02004509{
James Bottomley7d15d6a2008-03-14 14:12:43 -07004510 struct st_modedef *STm = dev_get_drvdata(dev);
Kai Makisarab174be02008-02-24 22:29:12 +02004511 struct scsi_tape *STp;
4512 int i, j, options;
4513 ssize_t l = 0;
4514
4515 for (i=0; i < st_dev_max; i++) {
4516 for (j=0; j < ST_NBR_MODES; j++)
4517 if (&scsi_tapes[i]->modes[j] == STm)
4518 break;
4519 if (j < ST_NBR_MODES)
4520 break;
4521 }
4522 if (i == st_dev_max)
4523 return 0; /* should never happen */
4524
4525 STp = scsi_tapes[i];
4526
4527 options = STm->do_buffer_writes ? MT_ST_BUFFER_WRITES : 0;
4528 options |= STm->do_async_writes ? MT_ST_ASYNC_WRITES : 0;
4529 options |= STm->do_read_ahead ? MT_ST_READ_AHEAD : 0;
4530 DEB( options |= debugging ? MT_ST_DEBUGGING : 0 );
4531 options |= STp->two_fm ? MT_ST_TWO_FM : 0;
4532 options |= STp->fast_mteom ? MT_ST_FAST_MTEOM : 0;
4533 options |= STm->defaults_for_writes ? MT_ST_DEF_WRITES : 0;
4534 options |= STp->can_bsr ? MT_ST_CAN_BSR : 0;
4535 options |= STp->omit_blklims ? MT_ST_NO_BLKLIMS : 0;
4536 options |= STp->can_partitions ? MT_ST_CAN_PARTITIONS : 0;
4537 options |= STp->scsi2_logical ? MT_ST_SCSI2LOGICAL : 0;
4538 options |= STm->sysv ? MT_ST_SYSV : 0;
4539 options |= STp->immediate ? MT_ST_NOWAIT : 0;
4540 options |= STp->sili ? MT_ST_SILI : 0;
4541
4542 l = snprintf(buf, PAGE_SIZE, "0x%08x\n", options);
4543 return l;
4544}
4545
Tony Jonesee959b02008-02-22 00:13:36 +01004546DEVICE_ATTR(options, S_IRUGO, st_options_show, NULL);
Kai Makisarab174be02008-02-24 22:29:12 +02004547
Jeff Garzik13026a62006-10-04 06:00:38 -04004548static int do_create_class_files(struct scsi_tape *STp, int dev_num, int mode)
Linus Torvalds1da177e2005-04-16 15:20:36 -07004549{
4550 int i, rew, error;
4551 char name[10];
Tony Jonesee959b02008-02-22 00:13:36 +01004552 struct device *st_class_member;
Linus Torvalds1da177e2005-04-16 15:20:36 -07004553
Linus Torvalds1da177e2005-04-16 15:20:36 -07004554 for (rew=0; rew < 2; rew++) {
4555 /* Make sure that the minor numbers corresponding to the four
4556 first modes always get the same names */
4557 i = mode << (4 - ST_NBR_MODE_BITS);
4558 snprintf(name, 10, "%s%s%s", rew ? "n" : "",
4559 STp->disk->disk_name, st_formats[i]);
4560 st_class_member =
Greg Kroah-Hartmand73a1a62008-07-21 20:03:34 -07004561 device_create(st_sysfs_class, &STp->device->sdev_gendev,
4562 MKDEV(SCSI_TAPE_MAJOR,
4563 TAPE_MINOR(dev_num, mode, rew)),
4564 &STp->modes[mode], "%s", name);
Linus Torvalds1da177e2005-04-16 15:20:36 -07004565 if (IS_ERR(st_class_member)) {
Tony Jonesee959b02008-02-22 00:13:36 +01004566 printk(KERN_WARNING "st%d: device_create failed\n",
Linus Torvalds1da177e2005-04-16 15:20:36 -07004567 dev_num);
Jeff Garzik13026a62006-10-04 06:00:38 -04004568 error = PTR_ERR(st_class_member);
Linus Torvalds1da177e2005-04-16 15:20:36 -07004569 goto out;
4570 }
Linus Torvalds1da177e2005-04-16 15:20:36 -07004571
Tony Jonesee959b02008-02-22 00:13:36 +01004572 error = device_create_file(st_class_member,
4573 &dev_attr_defined);
Jeff Garzik13026a62006-10-04 06:00:38 -04004574 if (error) goto out;
Tony Jonesee959b02008-02-22 00:13:36 +01004575 error = device_create_file(st_class_member,
4576 &dev_attr_default_blksize);
Jeff Garzik13026a62006-10-04 06:00:38 -04004577 if (error) goto out;
Tony Jonesee959b02008-02-22 00:13:36 +01004578 error = device_create_file(st_class_member,
4579 &dev_attr_default_density);
Jeff Garzik13026a62006-10-04 06:00:38 -04004580 if (error) goto out;
Tony Jonesee959b02008-02-22 00:13:36 +01004581 error = device_create_file(st_class_member,
4582 &dev_attr_default_compression);
Jeff Garzik13026a62006-10-04 06:00:38 -04004583 if (error) goto out;
Tony Jonesee959b02008-02-22 00:13:36 +01004584 error = device_create_file(st_class_member,
4585 &dev_attr_options);
Kai Makisarab174be02008-02-24 22:29:12 +02004586 if (error) goto out;
Jeff Garzik13026a62006-10-04 06:00:38 -04004587
Linus Torvalds1da177e2005-04-16 15:20:36 -07004588 if (mode == 0 && rew == 0) {
4589 error = sysfs_create_link(&STp->device->sdev_gendev.kobj,
4590 &st_class_member->kobj,
4591 "tape");
4592 if (error) {
4593 printk(KERN_ERR
4594 "st%d: Can't create sysfs link from SCSI device.\n",
4595 dev_num);
Jeff Garzik13026a62006-10-04 06:00:38 -04004596 goto out;
Linus Torvalds1da177e2005-04-16 15:20:36 -07004597 }
4598 }
4599 }
Jeff Garzik13026a62006-10-04 06:00:38 -04004600
4601 return 0;
4602
4603out:
4604 return error;
Linus Torvalds1da177e2005-04-16 15:20:36 -07004605}
4606
Linus Torvalds1da177e2005-04-16 15:20:36 -07004607/* The following functions may be useful for a larger audience. */
FUJITA Tomonori66207422008-12-18 14:49:43 +09004608static int sgl_map_user_pages(struct st_buffer *STbp,
4609 const unsigned int max_pages, unsigned long uaddr,
4610 size_t count, int rw)
Linus Torvalds1da177e2005-04-16 15:20:36 -07004611{
James Bottomley07542b82005-08-31 20:27:22 -04004612 unsigned long end = (uaddr + count + PAGE_SIZE - 1) >> PAGE_SHIFT;
4613 unsigned long start = uaddr >> PAGE_SHIFT;
4614 const int nr_pages = end - start;
Linus Torvalds1da177e2005-04-16 15:20:36 -07004615 int res, i, j;
Linus Torvalds1da177e2005-04-16 15:20:36 -07004616 struct page **pages;
FUJITA Tomonori66207422008-12-18 14:49:43 +09004617 struct rq_map_data *mdata = &STbp->map_data;
Linus Torvalds1da177e2005-04-16 15:20:36 -07004618
Linus Torvalds1da177e2005-04-16 15:20:36 -07004619 /* User attempted Overflow! */
4620 if ((uaddr + count) < uaddr)
4621 return -EINVAL;
4622
4623 /* Too big */
4624 if (nr_pages > max_pages)
4625 return -ENOMEM;
4626
4627 /* Hmm? */
4628 if (count == 0)
4629 return 0;
4630
4631 if ((pages = kmalloc(max_pages * sizeof(*pages), GFP_KERNEL)) == NULL)
4632 return -ENOMEM;
4633
4634 /* Try to fault in all of the necessary pages */
4635 down_read(&current->mm->mmap_sem);
4636 /* rw==READ means read from drive, write into memory area */
4637 res = get_user_pages(
4638 current,
4639 current->mm,
4640 uaddr,
4641 nr_pages,
4642 rw == READ,
4643 0, /* don't force */
4644 pages,
4645 NULL);
4646 up_read(&current->mm->mmap_sem);
4647
4648 /* Errors and no page mapped should return here */
4649 if (res < nr_pages)
4650 goto out_unmap;
4651
4652 for (i=0; i < nr_pages; i++) {
4653 /* FIXME: flush superflous for rw==READ,
4654 * probably wrong function for rw==WRITE
4655 */
4656 flush_dcache_page(pages[i]);
4657 }
4658
FUJITA Tomonori66207422008-12-18 14:49:43 +09004659 mdata->offset = uaddr & ~PAGE_MASK;
4660 mdata->page_order = 0;
4661 STbp->mapped_pages = pages;
Linus Torvalds1da177e2005-04-16 15:20:36 -07004662
Linus Torvalds1da177e2005-04-16 15:20:36 -07004663 return nr_pages;
Linus Torvalds1da177e2005-04-16 15:20:36 -07004664 out_unmap:
4665 if (res > 0) {
4666 for (j=0; j < res; j++)
4667 page_cache_release(pages[j]);
Hugh Dickins6bc733e2005-12-01 20:21:57 +00004668 res = 0;
Linus Torvalds1da177e2005-04-16 15:20:36 -07004669 }
4670 kfree(pages);
4671 return res;
4672}
4673
4674
4675/* And unmap them... */
FUJITA Tomonori66207422008-12-18 14:49:43 +09004676static int sgl_unmap_user_pages(struct st_buffer *STbp,
4677 const unsigned int nr_pages, int dirtied)
Linus Torvalds1da177e2005-04-16 15:20:36 -07004678{
4679 int i;
4680
4681 for (i=0; i < nr_pages; i++) {
FUJITA Tomonori66207422008-12-18 14:49:43 +09004682 struct page *page = STbp->mapped_pages[i];
Nick Pigginb5810032005-10-29 18:16:12 -07004683
Nick Pigginb5810032005-10-29 18:16:12 -07004684 if (dirtied)
4685 SetPageDirty(page);
Linus Torvalds1da177e2005-04-16 15:20:36 -07004686 /* FIXME: cache flush missing for rw==READ
4687 * FIXME: call the correct reference counting function
4688 */
Nick Pigginb5810032005-10-29 18:16:12 -07004689 page_cache_release(page);
Linus Torvalds1da177e2005-04-16 15:20:36 -07004690 }
FUJITA Tomonori66207422008-12-18 14:49:43 +09004691 kfree(STbp->mapped_pages);
4692 STbp->mapped_pages = NULL;
Linus Torvalds1da177e2005-04-16 15:20:36 -07004693
4694 return 0;
4695}