blob: 50dbe14db37bb837de1db7512eef618e74ac9ef8 [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
Linus Torvalds1da177e2005-04-16 15:20:36 -0700185static int enlarge_buffer(struct st_buffer *, int, int);
Kai Makisara40f6b362008-02-24 22:23:24 +0200186static void clear_buffer(struct st_buffer *);
Linus Torvalds1da177e2005-04-16 15:20:36 -0700187static void normalize_buffer(struct st_buffer *);
188static int append_to_buffer(const char __user *, struct st_buffer *, int);
189static int from_buffer(struct st_buffer *, char __user *, int);
190static void move_buffer_data(struct st_buffer *, int);
Linus Torvalds1da177e2005-04-16 15:20:36 -0700191
FUJITA Tomonori66207422008-12-18 14:49:43 +0900192static int sgl_map_user_pages(struct st_buffer *, const unsigned int,
Linus Torvalds1da177e2005-04-16 15:20:36 -0700193 unsigned long, size_t, int);
FUJITA Tomonori66207422008-12-18 14:49:43 +0900194static int sgl_unmap_user_pages(struct st_buffer *, const unsigned int, int);
Linus Torvalds1da177e2005-04-16 15:20:36 -0700195
196static int st_probe(struct device *);
197static int st_remove(struct device *);
Linus Torvalds1da177e2005-04-16 15:20:36 -0700198
Robert P. J. Day405ae7d2007-02-17 19:13:42 +0100199static int do_create_sysfs_files(void);
200static void do_remove_sysfs_files(void);
Jeff Garzik13026a62006-10-04 06:00:38 -0400201static int do_create_class_files(struct scsi_tape *, int, int);
Linus Torvalds1da177e2005-04-16 15:20:36 -0700202
203static struct scsi_driver st_template = {
204 .owner = THIS_MODULE,
205 .gendrv = {
206 .name = "st",
207 .probe = st_probe,
208 .remove = st_remove,
209 },
Linus Torvalds1da177e2005-04-16 15:20:36 -0700210};
211
212static int st_compression(struct scsi_tape *, int);
213
214static int find_partition(struct scsi_tape *);
215static int switch_partition(struct scsi_tape *);
216
217static int st_int_ioctl(struct scsi_tape *, unsigned int, unsigned long);
218
Kai Makisaraf03a5672005-08-02 13:40:47 +0300219static void scsi_tape_release(struct kref *);
220
221#define to_scsi_tape(obj) container_of(obj, struct scsi_tape, kref)
222
Arjan van de Ven0b950672006-01-11 13:16:10 +0100223static DEFINE_MUTEX(st_ref_mutex);
Kai Makisaraf03a5672005-08-02 13:40:47 +0300224
Linus Torvalds1da177e2005-04-16 15:20:36 -0700225
226#include "osst_detect.h"
227#ifndef SIGS_FROM_OSST
228#define SIGS_FROM_OSST \
229 {"OnStream", "SC-", "", "osst"}, \
230 {"OnStream", "DI-", "", "osst"}, \
231 {"OnStream", "DP-", "", "osst"}, \
232 {"OnStream", "USB", "", "osst"}, \
233 {"OnStream", "FW-", "", "osst"}
234#endif
235
Kai Makisaraf03a5672005-08-02 13:40:47 +0300236static struct scsi_tape *scsi_tape_get(int dev)
237{
238 struct scsi_tape *STp = NULL;
239
Arjan van de Ven0b950672006-01-11 13:16:10 +0100240 mutex_lock(&st_ref_mutex);
Kai Makisaraf03a5672005-08-02 13:40:47 +0300241 write_lock(&st_dev_arr_lock);
242
243 if (dev < st_dev_max && scsi_tapes != NULL)
244 STp = scsi_tapes[dev];
245 if (!STp) goto out;
246
247 kref_get(&STp->kref);
248
249 if (!STp->device)
250 goto out_put;
251
252 if (scsi_device_get(STp->device))
253 goto out_put;
254
255 goto out;
256
257out_put:
258 kref_put(&STp->kref, scsi_tape_release);
259 STp = NULL;
260out:
261 write_unlock(&st_dev_arr_lock);
Arjan van de Ven0b950672006-01-11 13:16:10 +0100262 mutex_unlock(&st_ref_mutex);
Kai Makisaraf03a5672005-08-02 13:40:47 +0300263 return STp;
264}
265
266static void scsi_tape_put(struct scsi_tape *STp)
267{
268 struct scsi_device *sdev = STp->device;
269
Arjan van de Ven0b950672006-01-11 13:16:10 +0100270 mutex_lock(&st_ref_mutex);
Kai Makisaraf03a5672005-08-02 13:40:47 +0300271 kref_put(&STp->kref, scsi_tape_release);
272 scsi_device_put(sdev);
Arjan van de Ven0b950672006-01-11 13:16:10 +0100273 mutex_unlock(&st_ref_mutex);
Kai Makisaraf03a5672005-08-02 13:40:47 +0300274}
275
Linus Torvalds1da177e2005-04-16 15:20:36 -0700276struct st_reject_data {
277 char *vendor;
278 char *model;
279 char *rev;
280 char *driver_hint; /* Name of the correct driver, NULL if unknown */
281};
282
283static struct st_reject_data reject_list[] = {
284 /* {"XXX", "Yy-", "", NULL}, example */
285 SIGS_FROM_OSST,
286 {NULL, }};
287
288/* If the device signature is on the list of incompatible drives, the
289 function returns a pointer to the name of the correct driver (if known) */
290static char * st_incompatible(struct scsi_device* SDp)
291{
292 struct st_reject_data *rp;
293
294 for (rp=&(reject_list[0]); rp->vendor != NULL; rp++)
295 if (!strncmp(rp->vendor, SDp->vendor, strlen(rp->vendor)) &&
296 !strncmp(rp->model, SDp->model, strlen(rp->model)) &&
297 !strncmp(rp->rev, SDp->rev, strlen(rp->rev))) {
298 if (rp->driver_hint)
299 return rp->driver_hint;
300 else
301 return "unknown";
302 }
303 return NULL;
304}
305
306
307static inline char *tape_name(struct scsi_tape *tape)
308{
309 return tape->disk->disk_name;
310}
311
312
Mike Christie8b05b772005-11-08 04:06:44 -0600313static void st_analyze_sense(struct st_request *SRpnt, struct st_cmdstatus *s)
Linus Torvalds1da177e2005-04-16 15:20:36 -0700314{
315 const u8 *ucp;
Mike Christie8b05b772005-11-08 04:06:44 -0600316 const u8 *sense = SRpnt->sense;
Linus Torvalds1da177e2005-04-16 15:20:36 -0700317
Mike Christie8b05b772005-11-08 04:06:44 -0600318 s->have_sense = scsi_normalize_sense(SRpnt->sense,
319 SCSI_SENSE_BUFFERSIZE, &s->sense_hdr);
Linus Torvalds1da177e2005-04-16 15:20:36 -0700320 s->flags = 0;
321
322 if (s->have_sense) {
323 s->deferred = 0;
324 s->remainder_valid =
325 scsi_get_sense_info_fld(sense, SCSI_SENSE_BUFFERSIZE, &s->uremainder64);
326 switch (sense[0] & 0x7f) {
327 case 0x71:
328 s->deferred = 1;
329 case 0x70:
330 s->fixed_format = 1;
331 s->flags = sense[2] & 0xe0;
332 break;
333 case 0x73:
334 s->deferred = 1;
335 case 0x72:
336 s->fixed_format = 0;
337 ucp = scsi_sense_desc_find(sense, SCSI_SENSE_BUFFERSIZE, 4);
338 s->flags = ucp ? (ucp[3] & 0xe0) : 0;
339 break;
340 }
341 }
342}
343
344
345/* Convert the result to success code */
Mike Christie8b05b772005-11-08 04:06:44 -0600346static int st_chk_result(struct scsi_tape *STp, struct st_request * SRpnt)
Linus Torvalds1da177e2005-04-16 15:20:36 -0700347{
Mike Christie8b05b772005-11-08 04:06:44 -0600348 int result = SRpnt->result;
Linus Torvalds1da177e2005-04-16 15:20:36 -0700349 u8 scode;
350 DEB(const char *stp;)
351 char *name = tape_name(STp);
352 struct st_cmdstatus *cmdstatp;
353
354 if (!result)
355 return 0;
356
357 cmdstatp = &STp->buffer->cmdstat;
Kai Makisaraf03a5672005-08-02 13:40:47 +0300358 st_analyze_sense(SRpnt, cmdstatp);
Linus Torvalds1da177e2005-04-16 15:20:36 -0700359
360 if (cmdstatp->have_sense)
361 scode = STp->buffer->cmdstat.sense_hdr.sense_key;
362 else
363 scode = 0;
364
365 DEB(
366 if (debugging) {
Mike Christie8b05b772005-11-08 04:06:44 -0600367 printk(ST_DEB_MSG "%s: Error: %x, cmd: %x %x %x %x %x %x\n",
Linus Torvalds1da177e2005-04-16 15:20:36 -0700368 name, result,
Mike Christie8b05b772005-11-08 04:06:44 -0600369 SRpnt->cmd[0], SRpnt->cmd[1], SRpnt->cmd[2],
370 SRpnt->cmd[3], SRpnt->cmd[4], SRpnt->cmd[5]);
Linus Torvalds1da177e2005-04-16 15:20:36 -0700371 if (cmdstatp->have_sense)
Luben Tuikov4e73ea72006-07-07 00:02:18 -0700372 __scsi_print_sense(name, SRpnt->sense, SCSI_SENSE_BUFFERSIZE);
Linus Torvalds1da177e2005-04-16 15:20:36 -0700373 } ) /* end DEB */
374 if (!debugging) { /* Abnormal conditions for tape */
375 if (!cmdstatp->have_sense)
376 printk(KERN_WARNING
377 "%s: Error %x (sugg. bt 0x%x, driver bt 0x%x, host bt 0x%x).\n",
378 name, result, suggestion(result),
379 driver_byte(result) & DRIVER_MASK, host_byte(result));
380 else if (cmdstatp->have_sense &&
381 scode != NO_SENSE &&
382 scode != RECOVERED_ERROR &&
383 /* scode != UNIT_ATTENTION && */
384 scode != BLANK_CHECK &&
385 scode != VOLUME_OVERFLOW &&
Mike Christie8b05b772005-11-08 04:06:44 -0600386 SRpnt->cmd[0] != MODE_SENSE &&
387 SRpnt->cmd[0] != TEST_UNIT_READY) {
Luben Tuikov4e73ea72006-07-07 00:02:18 -0700388
389 __scsi_print_sense(name, SRpnt->sense, SCSI_SENSE_BUFFERSIZE);
Linus Torvalds1da177e2005-04-16 15:20:36 -0700390 }
391 }
392
393 if (cmdstatp->fixed_format &&
394 STp->cln_mode >= EXTENDED_SENSE_START) { /* Only fixed format sense */
395 if (STp->cln_sense_value)
Mike Christie8b05b772005-11-08 04:06:44 -0600396 STp->cleaning_req |= ((SRpnt->sense[STp->cln_mode] &
Linus Torvalds1da177e2005-04-16 15:20:36 -0700397 STp->cln_sense_mask) == STp->cln_sense_value);
398 else
Mike Christie8b05b772005-11-08 04:06:44 -0600399 STp->cleaning_req |= ((SRpnt->sense[STp->cln_mode] &
Linus Torvalds1da177e2005-04-16 15:20:36 -0700400 STp->cln_sense_mask) != 0);
401 }
402 if (cmdstatp->have_sense &&
403 cmdstatp->sense_hdr.asc == 0 && cmdstatp->sense_hdr.ascq == 0x17)
404 STp->cleaning_req = 1; /* ASC and ASCQ => cleaning requested */
405
406 STp->pos_unknown |= STp->device->was_reset;
407
408 if (cmdstatp->have_sense &&
409 scode == RECOVERED_ERROR
410#if ST_RECOVERED_WRITE_FATAL
Mike Christie8b05b772005-11-08 04:06:44 -0600411 && SRpnt->cmd[0] != WRITE_6
412 && SRpnt->cmd[0] != WRITE_FILEMARKS
Linus Torvalds1da177e2005-04-16 15:20:36 -0700413#endif
414 ) {
415 STp->recover_count++;
416 STp->recover_reg++;
417
418 DEB(
419 if (debugging) {
Mike Christie8b05b772005-11-08 04:06:44 -0600420 if (SRpnt->cmd[0] == READ_6)
Linus Torvalds1da177e2005-04-16 15:20:36 -0700421 stp = "read";
Mike Christie8b05b772005-11-08 04:06:44 -0600422 else if (SRpnt->cmd[0] == WRITE_6)
Linus Torvalds1da177e2005-04-16 15:20:36 -0700423 stp = "write";
424 else
425 stp = "ioctl";
426 printk(ST_DEB_MSG "%s: Recovered %s error (%d).\n", name, stp,
427 STp->recover_count);
428 } ) /* end DEB */
429
430 if (cmdstatp->flags == 0)
431 return 0;
432 }
433 return (-EIO);
434}
435
FUJITA Tomonori4deba242008-12-05 15:25:20 +0900436static struct st_request *st_allocate_request(struct scsi_tape *stp)
Mike Christie8b05b772005-11-08 04:06:44 -0600437{
FUJITA Tomonori4deba242008-12-05 15:25:20 +0900438 struct st_request *streq;
439
440 streq = kzalloc(sizeof(*streq), GFP_KERNEL);
441 if (streq)
442 streq->stp = stp;
443 else {
444 DEBC(printk(KERN_ERR "%s: Can't get SCSI request.\n",
445 tape_name(stp)););
446 if (signal_pending(current))
447 stp->buffer->syscall_result = -EINTR;
448 else
449 stp->buffer->syscall_result = -EBUSY;
450 }
451
452 return streq;
Mike Christie8b05b772005-11-08 04:06:44 -0600453}
454
455static void st_release_request(struct st_request *streq)
456{
457 kfree(streq);
Linus Torvalds1da177e2005-04-16 15:20:36 -0700458}
459
FUJITA Tomonori13b53b42008-12-18 14:49:41 +0900460static void st_scsi_execute_end(struct request *req, int uptodate)
461{
462 struct st_request *SRpnt = req->end_io_data;
463 struct scsi_tape *STp = SRpnt->stp;
464
465 STp->buffer->cmdstat.midlevel_result = SRpnt->result = req->errors;
466 STp->buffer->cmdstat.residual = req->data_len;
467
468 if (SRpnt->waiting)
469 complete(SRpnt->waiting);
470
471 blk_rq_unmap_user(SRpnt->bio);
472 __blk_put_request(req->q, req);
473}
474
475static int st_scsi_execute(struct st_request *SRpnt, const unsigned char *cmd,
476 int data_direction, void *buffer, unsigned bufflen,
477 int timeout, int retries)
478{
479 struct request *req;
480 struct rq_map_data *mdata = &SRpnt->stp->buffer->map_data;
481 int err = 0;
482 int write = (data_direction == DMA_TO_DEVICE);
483
484 req = blk_get_request(SRpnt->stp->device->request_queue, write,
485 GFP_KERNEL);
486 if (!req)
487 return DRIVER_ERROR << 24;
488
489 req->cmd_type = REQ_TYPE_BLOCK_PC;
490 req->cmd_flags |= REQ_QUIET;
491
492 mdata->null_mapped = 1;
493
494 err = blk_rq_map_user(req->q, req, mdata, NULL, bufflen, GFP_KERNEL);
495 if (err) {
496 blk_put_request(req);
497 return DRIVER_ERROR << 24;
498 }
499
500 SRpnt->bio = req->bio;
501 req->cmd_len = COMMAND_SIZE(cmd[0]);
502 memset(req->cmd, 0, BLK_MAX_CDB);
503 memcpy(req->cmd, cmd, req->cmd_len);
504 req->sense = SRpnt->sense;
505 req->sense_len = 0;
506 req->timeout = timeout;
507 req->retries = retries;
508 req->end_io_data = SRpnt;
509
510 blk_execute_rq_nowait(req->q, NULL, req, 1, st_scsi_execute_end);
511 return 0;
512}
513
Linus Torvalds1da177e2005-04-16 15:20:36 -0700514/* Do the scsi command. Waits until command performed if do_wait is true.
515 Otherwise write_behind_check() is used to check that the command
516 has finished. */
Mike Christie8b05b772005-11-08 04:06:44 -0600517static struct st_request *
518st_do_scsi(struct st_request * SRpnt, struct scsi_tape * STp, unsigned char *cmd,
Linus Torvalds1da177e2005-04-16 15:20:36 -0700519 int bytes, int direction, int timeout, int retries, int do_wait)
520{
Kai Makisaraf03a5672005-08-02 13:40:47 +0300521 struct completion *waiting;
FUJITA Tomonori6d476262008-12-18 14:49:42 +0900522 struct rq_map_data *mdata = &STp->buffer->map_data;
523 int ret;
Linus Torvalds1da177e2005-04-16 15:20:36 -0700524
Kai Makisaraf03a5672005-08-02 13:40:47 +0300525 /* if async, make sure there's no command outstanding */
526 if (!do_wait && ((STp->buffer)->last_SRpnt)) {
527 printk(KERN_ERR "%s: Async command already active.\n",
528 tape_name(STp));
529 if (signal_pending(current))
530 (STp->buffer)->syscall_result = (-EINTR);
531 else
532 (STp->buffer)->syscall_result = (-EBUSY);
533 return NULL;
534 }
535
FUJITA Tomonori4deba242008-12-05 15:25:20 +0900536 if (!SRpnt) {
537 SRpnt = st_allocate_request(STp);
538 if (!SRpnt)
Linus Torvalds1da177e2005-04-16 15:20:36 -0700539 return NULL;
Linus Torvalds1da177e2005-04-16 15:20:36 -0700540 }
541
Kai Makisaraf03a5672005-08-02 13:40:47 +0300542 /* If async IO, set last_SRpnt. This ptr tells write_behind_check
543 which IO is outstanding. It's nulled out when the IO completes. */
544 if (!do_wait)
545 (STp->buffer)->last_SRpnt = SRpnt;
546
547 waiting = &STp->wait;
548 init_completion(waiting);
Mike Christie8b05b772005-11-08 04:06:44 -0600549 SRpnt->waiting = waiting;
550
FUJITA Tomonori66207422008-12-18 14:49:43 +0900551 if (STp->buffer->do_dio) {
552 mdata->nr_entries = STp->buffer->sg_segs;
553 mdata->pages = STp->buffer->mapped_pages;
554 } else {
FUJITA Tomonori6d476262008-12-18 14:49:42 +0900555 mdata->nr_entries =
556 DIV_ROUND_UP(bytes, PAGE_SIZE << mdata->page_order);
557 STp->buffer->map_data.pages = STp->buffer->reserved_pages;
558 STp->buffer->map_data.offset = 0;
559 }
560
Mike Christie8b05b772005-11-08 04:06:44 -0600561 memcpy(SRpnt->cmd, cmd, sizeof(SRpnt->cmd));
Linus Torvalds1da177e2005-04-16 15:20:36 -0700562 STp->buffer->cmdstat.have_sense = 0;
Mike Christie8b05b772005-11-08 04:06:44 -0600563 STp->buffer->syscall_result = 0;
Linus Torvalds1da177e2005-04-16 15:20:36 -0700564
FUJITA Tomonori66207422008-12-18 14:49:43 +0900565 ret = st_scsi_execute(SRpnt, cmd, direction, NULL, bytes, timeout,
566 retries);
FUJITA Tomonori6d476262008-12-18 14:49:42 +0900567 if (ret) {
Mike Christie8b05b772005-11-08 04:06:44 -0600568 /* could not allocate the buffer or request was too large */
569 (STp->buffer)->syscall_result = (-EBUSY);
Kai Makisara787926b2005-11-13 10:04:44 +0200570 (STp->buffer)->last_SRpnt = NULL;
FUJITA Tomonori6d476262008-12-18 14:49:42 +0900571 } else if (do_wait) {
Kai Makisaraf03a5672005-08-02 13:40:47 +0300572 wait_for_completion(waiting);
Mike Christie8b05b772005-11-08 04:06:44 -0600573 SRpnt->waiting = NULL;
Linus Torvalds1da177e2005-04-16 15:20:36 -0700574 (STp->buffer)->syscall_result = st_chk_result(STp, SRpnt);
575 }
Mike Christie8b05b772005-11-08 04:06:44 -0600576
Linus Torvalds1da177e2005-04-16 15:20:36 -0700577 return SRpnt;
578}
579
FUJITA Tomonoriffb43492008-12-05 15:25:21 +0900580static int st_scsi_kern_execute(struct st_request *streq,
581 const unsigned char *cmd, int data_direction,
582 void *buffer, unsigned bufflen, int timeout,
583 int retries)
584{
585 struct scsi_tape *stp = streq->stp;
586 int ret, resid;
587
588 stp->buffer->cmdstat.have_sense = 0;
589 memcpy(streq->cmd, cmd, sizeof(streq->cmd));
590
591 ret = scsi_execute(stp->device, cmd, data_direction, buffer, bufflen,
592 streq->sense, timeout, retries, 0, &resid);
593 if (driver_byte(ret) & DRIVER_ERROR)
594 return -EBUSY;
595
596 stp->buffer->cmdstat.midlevel_result = streq->result = ret;
597 stp->buffer->cmdstat.residual = resid;
598 stp->buffer->syscall_result = st_chk_result(stp, streq);
599
600 return 0;
601}
Linus Torvalds1da177e2005-04-16 15:20:36 -0700602
603/* Handle the write-behind checking (waits for completion). Returns -ENOSPC if
604 write has been correct but EOM early warning reached, -EIO if write ended in
605 error or zero if write successful. Asynchronous writes are used only in
606 variable block mode. */
607static int write_behind_check(struct scsi_tape * STp)
608{
609 int retval = 0;
610 struct st_buffer *STbuffer;
611 struct st_partstat *STps;
612 struct st_cmdstatus *cmdstatp;
Mike Christie8b05b772005-11-08 04:06:44 -0600613 struct st_request *SRpnt;
Linus Torvalds1da177e2005-04-16 15:20:36 -0700614
615 STbuffer = STp->buffer;
616 if (!STbuffer->writing)
617 return 0;
618
619 DEB(
620 if (STp->write_pending)
621 STp->nbr_waits++;
622 else
623 STp->nbr_finished++;
624 ) /* end DEB */
625
626 wait_for_completion(&(STp->wait));
Kai Makisaraf03a5672005-08-02 13:40:47 +0300627 SRpnt = STbuffer->last_SRpnt;
628 STbuffer->last_SRpnt = NULL;
Mike Christie8b05b772005-11-08 04:06:44 -0600629 SRpnt->waiting = NULL;
Linus Torvalds1da177e2005-04-16 15:20:36 -0700630
Kai Makisaraf03a5672005-08-02 13:40:47 +0300631 (STp->buffer)->syscall_result = st_chk_result(STp, SRpnt);
Mike Christie8b05b772005-11-08 04:06:44 -0600632 st_release_request(SRpnt);
Linus Torvalds1da177e2005-04-16 15:20:36 -0700633
634 STbuffer->buffer_bytes -= STbuffer->writing;
635 STps = &(STp->ps[STp->partition]);
636 if (STps->drv_block >= 0) {
637 if (STp->block_size == 0)
638 STps->drv_block++;
639 else
640 STps->drv_block += STbuffer->writing / STp->block_size;
641 }
642
643 cmdstatp = &STbuffer->cmdstat;
644 if (STbuffer->syscall_result) {
645 retval = -EIO;
646 if (cmdstatp->have_sense && !cmdstatp->deferred &&
647 (cmdstatp->flags & SENSE_EOM) &&
648 (cmdstatp->sense_hdr.sense_key == NO_SENSE ||
649 cmdstatp->sense_hdr.sense_key == RECOVERED_ERROR)) {
650 /* EOM at write-behind, has all data been written? */
651 if (!cmdstatp->remainder_valid ||
652 cmdstatp->uremainder64 == 0)
653 retval = -ENOSPC;
654 }
655 if (retval == -EIO)
656 STps->drv_block = -1;
657 }
658 STbuffer->writing = 0;
659
660 DEB(if (debugging && retval)
661 printk(ST_DEB_MSG "%s: Async write error %x, return value %d.\n",
662 tape_name(STp), STbuffer->cmdstat.midlevel_result, retval);) /* end DEB */
663
664 return retval;
665}
666
667
668/* Step over EOF if it has been inadvertently crossed (ioctl not used because
669 it messes up the block number). */
670static int cross_eof(struct scsi_tape * STp, int forward)
671{
Mike Christie8b05b772005-11-08 04:06:44 -0600672 struct st_request *SRpnt;
Linus Torvalds1da177e2005-04-16 15:20:36 -0700673 unsigned char cmd[MAX_COMMAND_SIZE];
FUJITA Tomonori39ade4b2008-12-05 15:25:25 +0900674 int ret;
Linus Torvalds1da177e2005-04-16 15:20:36 -0700675
676 cmd[0] = SPACE;
677 cmd[1] = 0x01; /* Space FileMarks */
678 if (forward) {
679 cmd[2] = cmd[3] = 0;
680 cmd[4] = 1;
681 } else
682 cmd[2] = cmd[3] = cmd[4] = 0xff; /* -1 filemarks */
683 cmd[5] = 0;
684
685 DEBC(printk(ST_DEB_MSG "%s: Stepping over filemark %s.\n",
686 tape_name(STp), forward ? "forward" : "backward"));
687
FUJITA Tomonori39ade4b2008-12-05 15:25:25 +0900688 SRpnt = st_allocate_request(STp);
Linus Torvalds1da177e2005-04-16 15:20:36 -0700689 if (!SRpnt)
FUJITA Tomonori39ade4b2008-12-05 15:25:25 +0900690 return STp->buffer->syscall_result;
Linus Torvalds1da177e2005-04-16 15:20:36 -0700691
FUJITA Tomonori39ade4b2008-12-05 15:25:25 +0900692 ret = st_scsi_kern_execute(SRpnt, cmd, DMA_NONE, NULL, 0,
693 STp->device->request_queue->rq_timeout,
694 MAX_RETRIES);
695 if (ret)
696 goto out;
697
698 ret = STp->buffer->syscall_result;
Linus Torvalds1da177e2005-04-16 15:20:36 -0700699
700 if ((STp->buffer)->cmdstat.midlevel_result != 0)
701 printk(KERN_ERR "%s: Stepping over filemark %s failed.\n",
702 tape_name(STp), forward ? "forward" : "backward");
703
FUJITA Tomonori39ade4b2008-12-05 15:25:25 +0900704out:
705 st_release_request(SRpnt);
706
707 return ret;
Linus Torvalds1da177e2005-04-16 15:20:36 -0700708}
709
710
711/* Flush the write buffer (never need to write if variable blocksize). */
Adrian Bunk8ef8d592008-04-14 17:17:16 +0300712static int st_flush_write_buffer(struct scsi_tape * STp)
Linus Torvalds1da177e2005-04-16 15:20:36 -0700713{
Kai Makisara786231a2008-07-11 15:06:40 +0300714 int transfer, blks;
Linus Torvalds1da177e2005-04-16 15:20:36 -0700715 int result;
716 unsigned char cmd[MAX_COMMAND_SIZE];
Mike Christie8b05b772005-11-08 04:06:44 -0600717 struct st_request *SRpnt;
Linus Torvalds1da177e2005-04-16 15:20:36 -0700718 struct st_partstat *STps;
719
720 result = write_behind_check(STp);
721 if (result)
722 return result;
723
724 result = 0;
725 if (STp->dirty == 1) {
726
Kai Makisara786231a2008-07-11 15:06:40 +0300727 transfer = STp->buffer->buffer_bytes;
Linus Torvalds1da177e2005-04-16 15:20:36 -0700728 DEBC(printk(ST_DEB_MSG "%s: Flushing %d bytes.\n",
729 tape_name(STp), transfer));
730
Linus Torvalds1da177e2005-04-16 15:20:36 -0700731 memset(cmd, 0, MAX_COMMAND_SIZE);
732 cmd[0] = WRITE_6;
733 cmd[1] = 1;
734 blks = transfer / STp->block_size;
735 cmd[2] = blks >> 16;
736 cmd[3] = blks >> 8;
737 cmd[4] = blks;
738
739 SRpnt = st_do_scsi(NULL, STp, cmd, transfer, DMA_TO_DEVICE,
James Bottomleya02488e2008-11-30 10:36:26 -0600740 STp->device->request_queue->rq_timeout,
741 MAX_WRITE_RETRIES, 1);
Linus Torvalds1da177e2005-04-16 15:20:36 -0700742 if (!SRpnt)
743 return (STp->buffer)->syscall_result;
744
745 STps = &(STp->ps[STp->partition]);
746 if ((STp->buffer)->syscall_result != 0) {
747 struct st_cmdstatus *cmdstatp = &STp->buffer->cmdstat;
748
749 if (cmdstatp->have_sense && !cmdstatp->deferred &&
750 (cmdstatp->flags & SENSE_EOM) &&
751 (cmdstatp->sense_hdr.sense_key == NO_SENSE ||
752 cmdstatp->sense_hdr.sense_key == RECOVERED_ERROR) &&
753 (!cmdstatp->remainder_valid ||
754 cmdstatp->uremainder64 == 0)) { /* All written at EOM early warning */
755 STp->dirty = 0;
756 (STp->buffer)->buffer_bytes = 0;
757 if (STps->drv_block >= 0)
758 STps->drv_block += blks;
759 result = (-ENOSPC);
760 } else {
761 printk(KERN_ERR "%s: Error on flush.\n",
762 tape_name(STp));
763 STps->drv_block = (-1);
764 result = (-EIO);
765 }
766 } else {
767 if (STps->drv_block >= 0)
768 STps->drv_block += blks;
769 STp->dirty = 0;
770 (STp->buffer)->buffer_bytes = 0;
771 }
Mike Christie8b05b772005-11-08 04:06:44 -0600772 st_release_request(SRpnt);
Linus Torvalds1da177e2005-04-16 15:20:36 -0700773 SRpnt = NULL;
774 }
775 return result;
776}
777
778
779/* Flush the tape buffer. The tape will be positioned correctly unless
780 seek_next is true. */
781static int flush_buffer(struct scsi_tape *STp, int seek_next)
782{
783 int backspace, result;
784 struct st_buffer *STbuffer;
785 struct st_partstat *STps;
786
787 STbuffer = STp->buffer;
788
789 /*
790 * If there was a bus reset, block further access
791 * to this device.
792 */
793 if (STp->pos_unknown)
794 return (-EIO);
795
796 if (STp->ready != ST_READY)
797 return 0;
798 STps = &(STp->ps[STp->partition]);
799 if (STps->rw == ST_WRITING) /* Writing */
Adrian Bunk8ef8d592008-04-14 17:17:16 +0300800 return st_flush_write_buffer(STp);
Linus Torvalds1da177e2005-04-16 15:20:36 -0700801
802 if (STp->block_size == 0)
803 return 0;
804
805 backspace = ((STp->buffer)->buffer_bytes +
806 (STp->buffer)->read_pointer) / STp->block_size -
807 ((STp->buffer)->read_pointer + STp->block_size - 1) /
808 STp->block_size;
809 (STp->buffer)->buffer_bytes = 0;
810 (STp->buffer)->read_pointer = 0;
811 result = 0;
812 if (!seek_next) {
813 if (STps->eof == ST_FM_HIT) {
814 result = cross_eof(STp, 0); /* Back over the EOF hit */
815 if (!result)
816 STps->eof = ST_NOEOF;
817 else {
818 if (STps->drv_file >= 0)
819 STps->drv_file++;
820 STps->drv_block = 0;
821 }
822 }
823 if (!result && backspace > 0)
824 result = st_int_ioctl(STp, MTBSR, backspace);
825 } else if (STps->eof == ST_FM_HIT) {
826 if (STps->drv_file >= 0)
827 STps->drv_file++;
828 STps->drv_block = 0;
829 STps->eof = ST_NOEOF;
830 }
831 return result;
832
833}
834
835/* Set the mode parameters */
836static int set_mode_densblk(struct scsi_tape * STp, struct st_modedef * STm)
837{
838 int set_it = 0;
839 unsigned long arg;
840 char *name = tape_name(STp);
841
842 if (!STp->density_changed &&
843 STm->default_density >= 0 &&
844 STm->default_density != STp->density) {
845 arg = STm->default_density;
846 set_it = 1;
847 } else
848 arg = STp->density;
849 arg <<= MT_ST_DENSITY_SHIFT;
850 if (!STp->blksize_changed &&
851 STm->default_blksize >= 0 &&
852 STm->default_blksize != STp->block_size) {
853 arg |= STm->default_blksize;
854 set_it = 1;
855 } else
856 arg |= STp->block_size;
857 if (set_it &&
858 st_int_ioctl(STp, SET_DENS_AND_BLK, arg)) {
859 printk(KERN_WARNING
860 "%s: Can't set default block size to %d bytes and density %x.\n",
861 name, STm->default_blksize, STm->default_density);
862 if (modes_defined)
863 return (-EINVAL);
864 }
865 return 0;
866}
867
868
Mike Christie8b05b772005-11-08 04:06:44 -0600869/* Lock or unlock the drive door. Don't use when st_request allocated. */
Linus Torvalds1da177e2005-04-16 15:20:36 -0700870static int do_door_lock(struct scsi_tape * STp, int do_lock)
871{
872 int retval, cmd;
873 DEB(char *name = tape_name(STp);)
874
875
876 cmd = do_lock ? SCSI_IOCTL_DOORLOCK : SCSI_IOCTL_DOORUNLOCK;
877 DEBC(printk(ST_DEB_MSG "%s: %socking drive door.\n", name,
878 do_lock ? "L" : "Unl"));
879 retval = scsi_ioctl(STp->device, cmd, NULL);
880 if (!retval) {
881 STp->door_locked = do_lock ? ST_LOCKED_EXPLICIT : ST_UNLOCKED;
882 }
883 else {
884 STp->door_locked = ST_LOCK_FAILS;
885 }
886 return retval;
887}
888
889
890/* Set the internal state after reset */
891static void reset_state(struct scsi_tape *STp)
892{
893 int i;
894 struct st_partstat *STps;
895
896 STp->pos_unknown = 0;
897 for (i = 0; i < ST_NBR_PARTITIONS; i++) {
898 STps = &(STp->ps[i]);
899 STps->rw = ST_IDLE;
900 STps->eof = ST_NOEOF;
901 STps->at_sm = 0;
902 STps->last_block_valid = 0;
903 STps->drv_block = -1;
904 STps->drv_file = -1;
905 }
906 if (STp->can_partitions) {
907 STp->partition = find_partition(STp);
908 if (STp->partition < 0)
909 STp->partition = 0;
910 STp->new_partition = STp->partition;
911 }
912}
913
914/* Test if the drive is ready. Returns either one of the codes below or a negative system
915 error code. */
916#define CHKRES_READY 0
917#define CHKRES_NEW_SESSION 1
918#define CHKRES_NOT_READY 2
919#define CHKRES_NO_TAPE 3
920
921#define MAX_ATTENTIONS 10
922
923static int test_ready(struct scsi_tape *STp, int do_wait)
924{
925 int attentions, waits, max_wait, scode;
926 int retval = CHKRES_READY, new_session = 0;
927 unsigned char cmd[MAX_COMMAND_SIZE];
FUJITA Tomonori0944a722008-12-05 15:25:22 +0900928 struct st_request *SRpnt;
Linus Torvalds1da177e2005-04-16 15:20:36 -0700929 struct st_cmdstatus *cmdstatp = &STp->buffer->cmdstat;
930
FUJITA Tomonori0944a722008-12-05 15:25:22 +0900931 SRpnt = st_allocate_request(STp);
932 if (!SRpnt)
933 return STp->buffer->syscall_result;
934
Linus Torvalds1da177e2005-04-16 15:20:36 -0700935 max_wait = do_wait ? ST_BLOCK_SECONDS : 0;
936
937 for (attentions=waits=0; ; ) {
938 memset((void *) &cmd[0], 0, MAX_COMMAND_SIZE);
939 cmd[0] = TEST_UNIT_READY;
Linus Torvalds1da177e2005-04-16 15:20:36 -0700940
FUJITA Tomonori0944a722008-12-05 15:25:22 +0900941 retval = st_scsi_kern_execute(SRpnt, cmd, DMA_NONE, NULL, 0,
942 STp->long_timeout,
943 MAX_READY_RETRIES);
944 if (retval)
Linus Torvalds1da177e2005-04-16 15:20:36 -0700945 break;
Linus Torvalds1da177e2005-04-16 15:20:36 -0700946
947 if (cmdstatp->have_sense) {
948
949 scode = cmdstatp->sense_hdr.sense_key;
950
951 if (scode == UNIT_ATTENTION) { /* New media? */
952 new_session = 1;
953 if (attentions < MAX_ATTENTIONS) {
954 attentions++;
955 continue;
956 }
957 else {
958 retval = (-EIO);
959 break;
960 }
961 }
962
963 if (scode == NOT_READY) {
964 if (waits < max_wait) {
965 if (msleep_interruptible(1000)) {
966 retval = (-EINTR);
967 break;
968 }
969 waits++;
970 continue;
971 }
972 else {
973 if ((STp->device)->scsi_level >= SCSI_2 &&
974 cmdstatp->sense_hdr.asc == 0x3a) /* Check ASC */
975 retval = CHKRES_NO_TAPE;
976 else
977 retval = CHKRES_NOT_READY;
978 break;
979 }
980 }
981 }
982
983 retval = (STp->buffer)->syscall_result;
984 if (!retval)
985 retval = new_session ? CHKRES_NEW_SESSION : CHKRES_READY;
986 break;
987 }
988
FUJITA Tomonori0944a722008-12-05 15:25:22 +0900989 st_release_request(SRpnt);
990
Linus Torvalds1da177e2005-04-16 15:20:36 -0700991 return retval;
992}
993
994
995/* See if the drive is ready and gather information about the tape. Return values:
996 < 0 negative error code from errno.h
997 0 drive ready
998 1 drive not ready (possibly no tape)
999*/
1000static int check_tape(struct scsi_tape *STp, struct file *filp)
1001{
1002 int i, retval, new_session = 0, do_wait;
1003 unsigned char cmd[MAX_COMMAND_SIZE], saved_cleaning;
1004 unsigned short st_flags = filp->f_flags;
Mike Christie8b05b772005-11-08 04:06:44 -06001005 struct st_request *SRpnt = NULL;
Linus Torvalds1da177e2005-04-16 15:20:36 -07001006 struct st_modedef *STm;
1007 struct st_partstat *STps;
1008 char *name = tape_name(STp);
Josef Sipek7ac62072006-12-08 02:37:37 -08001009 struct inode *inode = filp->f_path.dentry->d_inode;
Linus Torvalds1da177e2005-04-16 15:20:36 -07001010 int mode = TAPE_MODE(inode);
1011
1012 STp->ready = ST_READY;
1013
1014 if (mode != STp->current_mode) {
1015 DEBC(printk(ST_DEB_MSG "%s: Mode change from %d to %d.\n",
1016 name, STp->current_mode, mode));
1017 new_session = 1;
1018 STp->current_mode = mode;
1019 }
1020 STm = &(STp->modes[STp->current_mode]);
1021
1022 saved_cleaning = STp->cleaning_req;
1023 STp->cleaning_req = 0;
1024
1025 do_wait = ((filp->f_flags & O_NONBLOCK) == 0);
1026 retval = test_ready(STp, do_wait);
1027
1028 if (retval < 0)
1029 goto err_out;
1030
1031 if (retval == CHKRES_NEW_SESSION) {
1032 STp->pos_unknown = 0;
1033 STp->partition = STp->new_partition = 0;
1034 if (STp->can_partitions)
1035 STp->nbr_partitions = 1; /* This guess will be updated later
1036 if necessary */
1037 for (i = 0; i < ST_NBR_PARTITIONS; i++) {
1038 STps = &(STp->ps[i]);
1039 STps->rw = ST_IDLE;
1040 STps->eof = ST_NOEOF;
1041 STps->at_sm = 0;
1042 STps->last_block_valid = 0;
1043 STps->drv_block = 0;
1044 STps->drv_file = 0;
1045 }
1046 new_session = 1;
1047 }
1048 else {
1049 STp->cleaning_req |= saved_cleaning;
1050
1051 if (retval == CHKRES_NOT_READY || retval == CHKRES_NO_TAPE) {
1052 if (retval == CHKRES_NO_TAPE)
1053 STp->ready = ST_NO_TAPE;
1054 else
1055 STp->ready = ST_NOT_READY;
1056
1057 STp->density = 0; /* Clear the erroneous "residue" */
1058 STp->write_prot = 0;
1059 STp->block_size = 0;
1060 STp->ps[0].drv_file = STp->ps[0].drv_block = (-1);
1061 STp->partition = STp->new_partition = 0;
1062 STp->door_locked = ST_UNLOCKED;
1063 return CHKRES_NOT_READY;
1064 }
1065 }
1066
FUJITA Tomonori52107b22008-12-05 15:25:27 +09001067 SRpnt = st_allocate_request(STp);
1068 if (!SRpnt) {
1069 retval = STp->buffer->syscall_result;
1070 goto err_out;
1071 }
1072
Linus Torvalds1da177e2005-04-16 15:20:36 -07001073 if (STp->omit_blklims)
1074 STp->min_block = STp->max_block = (-1);
1075 else {
1076 memset((void *) &cmd[0], 0, MAX_COMMAND_SIZE);
1077 cmd[0] = READ_BLOCK_LIMITS;
1078
FUJITA Tomonori52107b22008-12-05 15:25:27 +09001079 retval = st_scsi_kern_execute(SRpnt, cmd, DMA_FROM_DEVICE,
1080 STp->buffer->b_data, 6,
1081 STp->device->request_queue->rq_timeout,
1082 MAX_READY_RETRIES);
1083 if (retval) {
1084 st_release_request(SRpnt);
Linus Torvalds1da177e2005-04-16 15:20:36 -07001085 goto err_out;
1086 }
1087
Mike Christie8b05b772005-11-08 04:06:44 -06001088 if (!SRpnt->result && !STp->buffer->cmdstat.have_sense) {
Linus Torvalds1da177e2005-04-16 15:20:36 -07001089 STp->max_block = ((STp->buffer)->b_data[1] << 16) |
1090 ((STp->buffer)->b_data[2] << 8) | (STp->buffer)->b_data[3];
1091 STp->min_block = ((STp->buffer)->b_data[4] << 8) |
1092 (STp->buffer)->b_data[5];
1093 if ( DEB( debugging || ) !STp->inited)
Kai Makisara42252852006-11-07 21:56:38 +02001094 printk(KERN_INFO
Linus Torvalds1da177e2005-04-16 15:20:36 -07001095 "%s: Block limits %d - %d bytes.\n", name,
1096 STp->min_block, STp->max_block);
1097 } else {
1098 STp->min_block = STp->max_block = (-1);
1099 DEBC(printk(ST_DEB_MSG "%s: Can't read block limits.\n",
1100 name));
1101 }
1102 }
1103
1104 memset((void *) &cmd[0], 0, MAX_COMMAND_SIZE);
1105 cmd[0] = MODE_SENSE;
1106 cmd[4] = 12;
1107
FUJITA Tomonori52107b22008-12-05 15:25:27 +09001108 retval = st_scsi_kern_execute(SRpnt, cmd, DMA_FROM_DEVICE,
1109 STp->buffer->b_data, 12,
1110 STp->device->request_queue->rq_timeout,
1111 MAX_READY_RETRIES);
1112 if (retval) {
1113 st_release_request(SRpnt);
Linus Torvalds1da177e2005-04-16 15:20:36 -07001114 goto err_out;
1115 }
1116
1117 if ((STp->buffer)->syscall_result != 0) {
1118 DEBC(printk(ST_DEB_MSG "%s: No Mode Sense.\n", name));
1119 STp->block_size = ST_DEFAULT_BLOCK; /* Educated guess (?) */
1120 (STp->buffer)->syscall_result = 0; /* Prevent error propagation */
1121 STp->drv_write_prot = 0;
1122 } else {
1123 DEBC(printk(ST_DEB_MSG
1124 "%s: Mode sense. Length %d, medium %x, WBS %x, BLL %d\n",
1125 name,
1126 (STp->buffer)->b_data[0], (STp->buffer)->b_data[1],
1127 (STp->buffer)->b_data[2], (STp->buffer)->b_data[3]));
1128
1129 if ((STp->buffer)->b_data[3] >= 8) {
1130 STp->drv_buffer = ((STp->buffer)->b_data[2] >> 4) & 7;
1131 STp->density = (STp->buffer)->b_data[4];
1132 STp->block_size = (STp->buffer)->b_data[9] * 65536 +
1133 (STp->buffer)->b_data[10] * 256 + (STp->buffer)->b_data[11];
1134 DEBC(printk(ST_DEB_MSG
1135 "%s: Density %x, tape length: %x, drv buffer: %d\n",
1136 name, STp->density, (STp->buffer)->b_data[5] * 65536 +
1137 (STp->buffer)->b_data[6] * 256 + (STp->buffer)->b_data[7],
1138 STp->drv_buffer));
1139 }
1140 STp->drv_write_prot = ((STp->buffer)->b_data[2] & 0x80) != 0;
1141 }
Mike Christie8b05b772005-11-08 04:06:44 -06001142 st_release_request(SRpnt);
Linus Torvalds1da177e2005-04-16 15:20:36 -07001143 SRpnt = NULL;
1144 STp->inited = 1;
1145
1146 if (STp->block_size > 0)
1147 (STp->buffer)->buffer_blocks =
1148 (STp->buffer)->buffer_size / STp->block_size;
1149 else
1150 (STp->buffer)->buffer_blocks = 1;
1151 (STp->buffer)->buffer_bytes = (STp->buffer)->read_pointer = 0;
1152
1153 DEBC(printk(ST_DEB_MSG
1154 "%s: Block size: %d, buffer size: %d (%d blocks).\n", name,
1155 STp->block_size, (STp->buffer)->buffer_size,
1156 (STp->buffer)->buffer_blocks));
1157
1158 if (STp->drv_write_prot) {
1159 STp->write_prot = 1;
1160
1161 DEBC(printk(ST_DEB_MSG "%s: Write protected\n", name));
1162
1163 if (do_wait &&
1164 ((st_flags & O_ACCMODE) == O_WRONLY ||
1165 (st_flags & O_ACCMODE) == O_RDWR)) {
1166 retval = (-EROFS);
1167 goto err_out;
1168 }
1169 }
1170
1171 if (STp->can_partitions && STp->nbr_partitions < 1) {
1172 /* This code is reached when the device is opened for the first time
1173 after the driver has been initialized with tape in the drive and the
1174 partition support has been enabled. */
1175 DEBC(printk(ST_DEB_MSG
1176 "%s: Updating partition number in status.\n", name));
1177 if ((STp->partition = find_partition(STp)) < 0) {
1178 retval = STp->partition;
1179 goto err_out;
1180 }
1181 STp->new_partition = STp->partition;
1182 STp->nbr_partitions = 1; /* This guess will be updated when necessary */
1183 }
1184
1185 if (new_session) { /* Change the drive parameters for the new mode */
1186 STp->density_changed = STp->blksize_changed = 0;
1187 STp->compression_changed = 0;
1188 if (!(STm->defaults_for_writes) &&
1189 (retval = set_mode_densblk(STp, STm)) < 0)
1190 goto err_out;
1191
1192 if (STp->default_drvbuffer != 0xff) {
1193 if (st_int_ioctl(STp, MTSETDRVBUFFER, STp->default_drvbuffer))
1194 printk(KERN_WARNING
1195 "%s: Can't set default drive buffering to %d.\n",
1196 name, STp->default_drvbuffer);
1197 }
1198 }
1199
1200 return CHKRES_READY;
1201
1202 err_out:
1203 return retval;
1204}
1205
1206
Jonathan Corbetb3369c62008-05-15 16:08:15 -06001207 /* Open the device. Needs to take the BKL only because of incrementing the SCSI host
Linus Torvalds1da177e2005-04-16 15:20:36 -07001208 module count. */
1209static int st_open(struct inode *inode, struct file *filp)
1210{
1211 int i, retval = (-EIO);
1212 struct scsi_tape *STp;
1213 struct st_partstat *STps;
1214 int dev = TAPE_NR(inode);
1215 char *name;
1216
Jonathan Corbetb3369c62008-05-15 16:08:15 -06001217 lock_kernel();
Linus Torvalds1da177e2005-04-16 15:20:36 -07001218 /*
1219 * We really want to do nonseekable_open(inode, filp); here, but some
1220 * versions of tar incorrectly call lseek on tapes and bail out if that
1221 * fails. So we disallow pread() and pwrite(), but permit lseeks.
1222 */
1223 filp->f_mode &= ~(FMODE_PREAD | FMODE_PWRITE);
1224
Jonathan Corbetb3369c62008-05-15 16:08:15 -06001225 if (!(STp = scsi_tape_get(dev))) {
1226 unlock_kernel();
Kai Makisaraf03a5672005-08-02 13:40:47 +03001227 return -ENXIO;
Jonathan Corbetb3369c62008-05-15 16:08:15 -06001228 }
Kai Makisaraf03a5672005-08-02 13:40:47 +03001229
Linus Torvalds1da177e2005-04-16 15:20:36 -07001230 write_lock(&st_dev_arr_lock);
Linus Torvalds1da177e2005-04-16 15:20:36 -07001231 filp->private_data = STp;
1232 name = tape_name(STp);
1233
1234 if (STp->in_use) {
1235 write_unlock(&st_dev_arr_lock);
Kai Makisaraf03a5672005-08-02 13:40:47 +03001236 scsi_tape_put(STp);
Jonathan Corbetb3369c62008-05-15 16:08:15 -06001237 unlock_kernel();
Linus Torvalds1da177e2005-04-16 15:20:36 -07001238 DEB( printk(ST_DEB_MSG "%s: Device already in use.\n", name); )
1239 return (-EBUSY);
1240 }
1241
Linus Torvalds1da177e2005-04-16 15:20:36 -07001242 STp->in_use = 1;
1243 write_unlock(&st_dev_arr_lock);
1244 STp->rew_at_close = STp->autorew_dev = (iminor(inode) & 0x80) == 0;
1245
1246 if (!scsi_block_when_processing_errors(STp->device)) {
1247 retval = (-ENXIO);
1248 goto err_out;
1249 }
1250
1251 /* See that we have at least a one page buffer available */
1252 if (!enlarge_buffer(STp->buffer, PAGE_SIZE, STp->restr_dma)) {
1253 printk(KERN_WARNING "%s: Can't allocate one page tape buffer.\n",
1254 name);
1255 retval = (-EOVERFLOW);
1256 goto err_out;
1257 }
1258
Kai Makisara40f6b362008-02-24 22:23:24 +02001259 (STp->buffer)->cleared = 0;
Linus Torvalds1da177e2005-04-16 15:20:36 -07001260 (STp->buffer)->writing = 0;
1261 (STp->buffer)->syscall_result = 0;
1262
1263 STp->write_prot = ((filp->f_flags & O_ACCMODE) == O_RDONLY);
1264
1265 STp->dirty = 0;
1266 for (i = 0; i < ST_NBR_PARTITIONS; i++) {
1267 STps = &(STp->ps[i]);
1268 STps->rw = ST_IDLE;
1269 }
Kai Makisara9abe16c2007-02-03 13:21:29 +02001270 STp->try_dio_now = STp->try_dio;
Linus Torvalds1da177e2005-04-16 15:20:36 -07001271 STp->recover_count = 0;
1272 DEB( STp->nbr_waits = STp->nbr_finished = 0;
Kai Makisaradeee13d2008-02-22 20:11:21 +02001273 STp->nbr_requests = STp->nbr_dio = STp->nbr_pages = 0; )
Linus Torvalds1da177e2005-04-16 15:20:36 -07001274
1275 retval = check_tape(STp, filp);
1276 if (retval < 0)
1277 goto err_out;
1278 if ((filp->f_flags & O_NONBLOCK) == 0 &&
1279 retval != CHKRES_READY) {
Kai Makisara413f7322006-10-05 22:59:46 +03001280 if (STp->ready == NO_TAPE)
1281 retval = (-ENOMEDIUM);
1282 else
1283 retval = (-EIO);
Linus Torvalds1da177e2005-04-16 15:20:36 -07001284 goto err_out;
1285 }
Jonathan Corbetb3369c62008-05-15 16:08:15 -06001286 unlock_kernel();
Linus Torvalds1da177e2005-04-16 15:20:36 -07001287 return 0;
1288
1289 err_out:
1290 normalize_buffer(STp->buffer);
1291 STp->in_use = 0;
Kai Makisaraf03a5672005-08-02 13:40:47 +03001292 scsi_tape_put(STp);
Jonathan Corbetb3369c62008-05-15 16:08:15 -06001293 unlock_kernel();
Linus Torvalds1da177e2005-04-16 15:20:36 -07001294 return retval;
1295
1296}
1297
1298
1299/* Flush the tape buffer before close */
Miklos Szeredi75e1fcc2006-06-23 02:05:12 -07001300static int st_flush(struct file *filp, fl_owner_t id)
Linus Torvalds1da177e2005-04-16 15:20:36 -07001301{
1302 int result = 0, result2;
1303 unsigned char cmd[MAX_COMMAND_SIZE];
Mike Christie8b05b772005-11-08 04:06:44 -06001304 struct st_request *SRpnt;
Linus Torvalds1da177e2005-04-16 15:20:36 -07001305 struct scsi_tape *STp = filp->private_data;
1306 struct st_modedef *STm = &(STp->modes[STp->current_mode]);
1307 struct st_partstat *STps = &(STp->ps[STp->partition]);
1308 char *name = tape_name(STp);
1309
1310 if (file_count(filp) > 1)
1311 return 0;
1312
1313 if (STps->rw == ST_WRITING && !STp->pos_unknown) {
Adrian Bunk8ef8d592008-04-14 17:17:16 +03001314 result = st_flush_write_buffer(STp);
Linus Torvalds1da177e2005-04-16 15:20:36 -07001315 if (result != 0 && result != (-ENOSPC))
1316 goto out;
1317 }
1318
1319 if (STp->can_partitions &&
1320 (result2 = switch_partition(STp)) < 0) {
1321 DEBC(printk(ST_DEB_MSG
1322 "%s: switch_partition at close failed.\n", name));
1323 if (result == 0)
1324 result = result2;
1325 goto out;
1326 }
1327
1328 DEBC( if (STp->nbr_requests)
Kai Makisaradeee13d2008-02-22 20:11:21 +02001329 printk(KERN_DEBUG "%s: Number of r/w requests %d, dio used in %d, pages %d.\n",
1330 name, STp->nbr_requests, STp->nbr_dio, STp->nbr_pages));
Linus Torvalds1da177e2005-04-16 15:20:36 -07001331
1332 if (STps->rw == ST_WRITING && !STp->pos_unknown) {
1333 struct st_cmdstatus *cmdstatp = &STp->buffer->cmdstat;
1334
1335 DEBC(printk(ST_DEB_MSG "%s: Async write waits %d, finished %d.\n",
1336 name, STp->nbr_waits, STp->nbr_finished);
1337 )
1338
1339 memset(cmd, 0, MAX_COMMAND_SIZE);
1340 cmd[0] = WRITE_FILEMARKS;
1341 cmd[4] = 1 + STp->two_fm;
1342
FUJITA Tomonori212cd8b2008-12-05 15:25:26 +09001343 SRpnt = st_allocate_request(STp);
Linus Torvalds1da177e2005-04-16 15:20:36 -07001344 if (!SRpnt) {
FUJITA Tomonori212cd8b2008-12-05 15:25:26 +09001345 result = STp->buffer->syscall_result;
1346 goto out;
1347 }
1348
1349 result = st_scsi_kern_execute(SRpnt, cmd, DMA_NONE, NULL, 0,
1350 STp->device->request_queue->rq_timeout,
1351 MAX_WRITE_RETRIES);
1352 if (result) {
1353 st_release_request(SRpnt);
Linus Torvalds1da177e2005-04-16 15:20:36 -07001354 goto out;
1355 }
1356
1357 if (STp->buffer->syscall_result == 0 ||
1358 (cmdstatp->have_sense && !cmdstatp->deferred &&
1359 (cmdstatp->flags & SENSE_EOM) &&
1360 (cmdstatp->sense_hdr.sense_key == NO_SENSE ||
1361 cmdstatp->sense_hdr.sense_key == RECOVERED_ERROR) &&
1362 (!cmdstatp->remainder_valid || cmdstatp->uremainder64 == 0))) {
1363 /* Write successful at EOM */
Mike Christie8b05b772005-11-08 04:06:44 -06001364 st_release_request(SRpnt);
Linus Torvalds1da177e2005-04-16 15:20:36 -07001365 SRpnt = NULL;
1366 if (STps->drv_file >= 0)
1367 STps->drv_file++;
1368 STps->drv_block = 0;
1369 if (STp->two_fm)
1370 cross_eof(STp, 0);
1371 STps->eof = ST_FM;
1372 }
1373 else { /* Write error */
Mike Christie8b05b772005-11-08 04:06:44 -06001374 st_release_request(SRpnt);
Linus Torvalds1da177e2005-04-16 15:20:36 -07001375 SRpnt = NULL;
1376 printk(KERN_ERR "%s: Error on write filemark.\n", name);
1377 if (result == 0)
1378 result = (-EIO);
1379 }
1380
1381 DEBC(printk(ST_DEB_MSG "%s: Buffer flushed, %d EOF(s) written\n",
1382 name, cmd[4]));
1383 } else if (!STp->rew_at_close) {
1384 STps = &(STp->ps[STp->partition]);
1385 if (!STm->sysv || STps->rw != ST_READING) {
1386 if (STp->can_bsr)
1387 result = flush_buffer(STp, 0);
1388 else if (STps->eof == ST_FM_HIT) {
1389 result = cross_eof(STp, 0);
1390 if (result) {
1391 if (STps->drv_file >= 0)
1392 STps->drv_file++;
1393 STps->drv_block = 0;
1394 STps->eof = ST_FM;
1395 } else
1396 STps->eof = ST_NOEOF;
1397 }
1398 } else if ((STps->eof == ST_NOEOF &&
1399 !(result = cross_eof(STp, 1))) ||
1400 STps->eof == ST_FM_HIT) {
1401 if (STps->drv_file >= 0)
1402 STps->drv_file++;
1403 STps->drv_block = 0;
1404 STps->eof = ST_FM;
1405 }
1406 }
1407
1408 out:
1409 if (STp->rew_at_close) {
1410 result2 = st_int_ioctl(STp, MTREW, 1);
1411 if (result == 0)
1412 result = result2;
1413 }
1414 return result;
1415}
1416
1417
1418/* Close the device and release it. BKL is not needed: this is the only thread
1419 accessing this tape. */
1420static int st_release(struct inode *inode, struct file *filp)
1421{
1422 int result = 0;
1423 struct scsi_tape *STp = filp->private_data;
1424
1425 if (STp->door_locked == ST_LOCKED_AUTO)
1426 do_door_lock(STp, 0);
1427
1428 normalize_buffer(STp->buffer);
1429 write_lock(&st_dev_arr_lock);
1430 STp->in_use = 0;
1431 write_unlock(&st_dev_arr_lock);
Kai Makisaraf03a5672005-08-02 13:40:47 +03001432 scsi_tape_put(STp);
Linus Torvalds1da177e2005-04-16 15:20:36 -07001433
1434 return result;
1435}
1436
1437/* The checks common to both reading and writing */
1438static ssize_t rw_checks(struct scsi_tape *STp, struct file *filp, size_t count)
1439{
1440 ssize_t retval = 0;
1441
1442 /*
1443 * If we are in the middle of error recovery, don't let anyone
1444 * else try and use this device. Also, if error recovery fails, it
1445 * may try and take the device offline, in which case all further
1446 * access to the device is prohibited.
1447 */
1448 if (!scsi_block_when_processing_errors(STp->device)) {
1449 retval = (-ENXIO);
1450 goto out;
1451 }
1452
1453 if (STp->ready != ST_READY) {
1454 if (STp->ready == ST_NO_TAPE)
1455 retval = (-ENOMEDIUM);
1456 else
1457 retval = (-EIO);
1458 goto out;
1459 }
1460
1461 if (! STp->modes[STp->current_mode].defined) {
1462 retval = (-ENXIO);
1463 goto out;
1464 }
1465
1466
1467 /*
1468 * If there was a bus reset, block further access
1469 * to this device.
1470 */
1471 if (STp->pos_unknown) {
1472 retval = (-EIO);
1473 goto out;
1474 }
1475
1476 if (count == 0)
1477 goto out;
1478
1479 DEB(
1480 if (!STp->in_use) {
1481 printk(ST_DEB_MSG "%s: Incorrect device.\n", tape_name(STp));
1482 retval = (-EIO);
1483 goto out;
1484 } ) /* end DEB */
1485
1486 if (STp->can_partitions &&
1487 (retval = switch_partition(STp)) < 0)
1488 goto out;
1489
1490 if (STp->block_size == 0 && STp->max_block > 0 &&
1491 (count < STp->min_block || count > STp->max_block)) {
1492 retval = (-EINVAL);
1493 goto out;
1494 }
1495
1496 if (STp->do_auto_lock && STp->door_locked == ST_UNLOCKED &&
1497 !do_door_lock(STp, 1))
1498 STp->door_locked = ST_LOCKED_AUTO;
1499
1500 out:
1501 return retval;
1502}
1503
1504
1505static int setup_buffering(struct scsi_tape *STp, const char __user *buf,
1506 size_t count, int is_read)
1507{
1508 int i, bufsize, retval = 0;
1509 struct st_buffer *STbp = STp->buffer;
1510
1511 if (is_read)
Kai Makisara9abe16c2007-02-03 13:21:29 +02001512 i = STp->try_dio_now && try_rdio;
Linus Torvalds1da177e2005-04-16 15:20:36 -07001513 else
Kai Makisara9abe16c2007-02-03 13:21:29 +02001514 i = STp->try_dio_now && try_wdio;
Mike Christie8b05b772005-11-08 04:06:44 -06001515
Linus Torvalds1da177e2005-04-16 15:20:36 -07001516 if (i && ((unsigned long)buf & queue_dma_alignment(
1517 STp->device->request_queue)) == 0) {
FUJITA Tomonori66207422008-12-18 14:49:43 +09001518 i = sgl_map_user_pages(STbp, STbp->use_sg, (unsigned long)buf,
1519 count, (is_read ? READ : WRITE));
Linus Torvalds1da177e2005-04-16 15:20:36 -07001520 if (i > 0) {
1521 STbp->do_dio = i;
1522 STbp->buffer_bytes = 0; /* can be used as transfer counter */
1523 }
1524 else
1525 STbp->do_dio = 0; /* fall back to buffering with any error */
1526 STbp->sg_segs = STbp->do_dio;
1527 STbp->frp_sg_current = 0;
1528 DEB(
1529 if (STbp->do_dio) {
1530 STp->nbr_dio++;
1531 STp->nbr_pages += STbp->do_dio;
Linus Torvalds1da177e2005-04-16 15:20:36 -07001532 }
1533 )
1534 } else
1535 STbp->do_dio = 0;
1536 DEB( STp->nbr_requests++; )
1537
1538 if (!STbp->do_dio) {
1539 if (STp->block_size)
1540 bufsize = STp->block_size > st_fixed_buffer_size ?
1541 STp->block_size : st_fixed_buffer_size;
Kai Makisara40f6b362008-02-24 22:23:24 +02001542 else {
Linus Torvalds1da177e2005-04-16 15:20:36 -07001543 bufsize = count;
Kai Makisara40f6b362008-02-24 22:23:24 +02001544 /* Make sure that data from previous user is not leaked even if
1545 HBA does not return correct residual */
1546 if (is_read && STp->sili && !STbp->cleared)
1547 clear_buffer(STbp);
1548 }
1549
Linus Torvalds1da177e2005-04-16 15:20:36 -07001550 if (bufsize > STbp->buffer_size &&
1551 !enlarge_buffer(STbp, bufsize, STp->restr_dma)) {
1552 printk(KERN_WARNING "%s: Can't allocate %d byte tape buffer.\n",
1553 tape_name(STp), bufsize);
1554 retval = (-EOVERFLOW);
1555 goto out;
1556 }
1557 if (STp->block_size)
1558 STbp->buffer_blocks = bufsize / STp->block_size;
1559 }
1560
1561 out:
1562 return retval;
1563}
1564
1565
1566/* Can be called more than once after each setup_buffer() */
Kai Makisara787926b2005-11-13 10:04:44 +02001567static void release_buffering(struct scsi_tape *STp, int is_read)
Linus Torvalds1da177e2005-04-16 15:20:36 -07001568{
1569 struct st_buffer *STbp;
1570
1571 STbp = STp->buffer;
1572 if (STbp->do_dio) {
FUJITA Tomonori66207422008-12-18 14:49:43 +09001573 sgl_unmap_user_pages(STbp, STbp->do_dio, is_read);
Linus Torvalds1da177e2005-04-16 15:20:36 -07001574 STbp->do_dio = 0;
Kai Makisara787926b2005-11-13 10:04:44 +02001575 STbp->sg_segs = 0;
Linus Torvalds1da177e2005-04-16 15:20:36 -07001576 }
1577}
1578
1579
1580/* Write command */
1581static ssize_t
1582st_write(struct file *filp, const char __user *buf, size_t count, loff_t * ppos)
1583{
1584 ssize_t total;
1585 ssize_t i, do_count, blks, transfer;
1586 ssize_t retval;
1587 int undone, retry_eot = 0, scode;
1588 int async_write;
1589 unsigned char cmd[MAX_COMMAND_SIZE];
1590 const char __user *b_point;
Mike Christie8b05b772005-11-08 04:06:44 -06001591 struct st_request *SRpnt = NULL;
Linus Torvalds1da177e2005-04-16 15:20:36 -07001592 struct scsi_tape *STp = filp->private_data;
1593 struct st_modedef *STm;
1594 struct st_partstat *STps;
1595 struct st_buffer *STbp;
1596 char *name = tape_name(STp);
1597
Matthias Kaehlcke28f85002007-07-29 23:38:15 +02001598 if (mutex_lock_interruptible(&STp->lock))
Linus Torvalds1da177e2005-04-16 15:20:36 -07001599 return -ERESTARTSYS;
1600
1601 retval = rw_checks(STp, filp, count);
1602 if (retval || count == 0)
1603 goto out;
1604
1605 /* Write must be integral number of blocks */
1606 if (STp->block_size != 0 && (count % STp->block_size) != 0) {
1607 printk(KERN_WARNING "%s: Write not multiple of tape block size.\n",
1608 name);
1609 retval = (-EINVAL);
1610 goto out;
1611 }
1612
1613 STm = &(STp->modes[STp->current_mode]);
1614 STps = &(STp->ps[STp->partition]);
1615
1616 if (STp->write_prot) {
1617 retval = (-EACCES);
1618 goto out;
1619 }
1620
1621
1622 if (STps->rw == ST_READING) {
1623 retval = flush_buffer(STp, 0);
1624 if (retval)
1625 goto out;
1626 STps->rw = ST_WRITING;
1627 } else if (STps->rw != ST_WRITING &&
1628 STps->drv_file == 0 && STps->drv_block == 0) {
1629 if ((retval = set_mode_densblk(STp, STm)) < 0)
1630 goto out;
1631 if (STm->default_compression != ST_DONT_TOUCH &&
1632 !(STp->compression_changed)) {
1633 if (st_compression(STp, (STm->default_compression == ST_YES))) {
1634 printk(KERN_WARNING "%s: Can't set default compression.\n",
1635 name);
1636 if (modes_defined) {
1637 retval = (-EINVAL);
1638 goto out;
1639 }
1640 }
1641 }
1642 }
1643
1644 STbp = STp->buffer;
1645 i = write_behind_check(STp);
1646 if (i) {
1647 if (i == -ENOSPC)
1648 STps->eof = ST_EOM_OK;
1649 else
1650 STps->eof = ST_EOM_ERROR;
1651 }
1652
1653 if (STps->eof == ST_EOM_OK) {
1654 STps->eof = ST_EOD_1; /* allow next write */
1655 retval = (-ENOSPC);
1656 goto out;
1657 }
1658 else if (STps->eof == ST_EOM_ERROR) {
1659 retval = (-EIO);
1660 goto out;
1661 }
1662
1663 /* Check the buffer readability in cases where copy_user might catch
1664 the problems after some tape movement. */
1665 if (STp->block_size != 0 &&
1666 !STbp->do_dio &&
1667 (copy_from_user(&i, buf, 1) != 0 ||
1668 copy_from_user(&i, buf + count - 1, 1) != 0)) {
1669 retval = (-EFAULT);
1670 goto out;
1671 }
1672
1673 retval = setup_buffering(STp, buf, count, 0);
1674 if (retval)
1675 goto out;
1676
1677 total = count;
1678
1679 memset(cmd, 0, MAX_COMMAND_SIZE);
1680 cmd[0] = WRITE_6;
1681 cmd[1] = (STp->block_size != 0);
1682
1683 STps->rw = ST_WRITING;
1684
1685 b_point = buf;
1686 while (count > 0 && !retry_eot) {
1687
1688 if (STbp->do_dio) {
1689 do_count = count;
1690 }
1691 else {
1692 if (STp->block_size == 0)
1693 do_count = count;
1694 else {
1695 do_count = STbp->buffer_blocks * STp->block_size -
1696 STbp->buffer_bytes;
1697 if (do_count > count)
1698 do_count = count;
1699 }
1700
1701 i = append_to_buffer(b_point, STbp, do_count);
1702 if (i) {
1703 retval = i;
1704 goto out;
1705 }
1706 }
1707 count -= do_count;
1708 b_point += do_count;
1709
1710 async_write = STp->block_size == 0 && !STbp->do_dio &&
1711 STm->do_async_writes && STps->eof < ST_EOM_OK;
1712
1713 if (STp->block_size != 0 && STm->do_buffer_writes &&
Kai Makisara9abe16c2007-02-03 13:21:29 +02001714 !(STp->try_dio_now && try_wdio) && STps->eof < ST_EOM_OK &&
Linus Torvalds1da177e2005-04-16 15:20:36 -07001715 STbp->buffer_bytes < STbp->buffer_size) {
1716 STp->dirty = 1;
1717 /* Don't write a buffer that is not full enough. */
1718 if (!async_write && count == 0)
1719 break;
1720 }
1721
1722 retry_write:
1723 if (STp->block_size == 0)
1724 blks = transfer = do_count;
1725 else {
1726 if (!STbp->do_dio)
1727 blks = STbp->buffer_bytes;
1728 else
1729 blks = do_count;
1730 blks /= STp->block_size;
1731 transfer = blks * STp->block_size;
1732 }
1733 cmd[2] = blks >> 16;
1734 cmd[3] = blks >> 8;
1735 cmd[4] = blks;
1736
1737 SRpnt = st_do_scsi(SRpnt, STp, cmd, transfer, DMA_TO_DEVICE,
James Bottomleya02488e2008-11-30 10:36:26 -06001738 STp->device->request_queue->rq_timeout,
1739 MAX_WRITE_RETRIES, !async_write);
Linus Torvalds1da177e2005-04-16 15:20:36 -07001740 if (!SRpnt) {
1741 retval = STbp->syscall_result;
1742 goto out;
1743 }
Mike Christie8b05b772005-11-08 04:06:44 -06001744 if (async_write && !STbp->syscall_result) {
Linus Torvalds1da177e2005-04-16 15:20:36 -07001745 STbp->writing = transfer;
1746 STp->dirty = !(STbp->writing ==
1747 STbp->buffer_bytes);
1748 SRpnt = NULL; /* Prevent releasing this request! */
1749 DEB( STp->write_pending = 1; )
1750 break;
1751 }
1752
1753 if (STbp->syscall_result != 0) {
1754 struct st_cmdstatus *cmdstatp = &STp->buffer->cmdstat;
1755
1756 DEBC(printk(ST_DEB_MSG "%s: Error on write:\n", name));
1757 if (cmdstatp->have_sense && (cmdstatp->flags & SENSE_EOM)) {
1758 scode = cmdstatp->sense_hdr.sense_key;
1759 if (cmdstatp->remainder_valid)
1760 undone = (int)cmdstatp->uremainder64;
1761 else if (STp->block_size == 0 &&
1762 scode == VOLUME_OVERFLOW)
1763 undone = transfer;
1764 else
1765 undone = 0;
1766 if (STp->block_size != 0)
1767 undone *= STp->block_size;
1768 if (undone <= do_count) {
1769 /* Only data from this write is not written */
1770 count += undone;
Kai Makisara626dcb12008-07-11 15:05:25 +03001771 b_point -= undone;
Linus Torvalds1da177e2005-04-16 15:20:36 -07001772 do_count -= undone;
1773 if (STp->block_size)
1774 blks = (transfer - undone) / STp->block_size;
1775 STps->eof = ST_EOM_OK;
1776 /* Continue in fixed block mode if all written
1777 in this request but still something left to write
1778 (retval left to zero)
1779 */
1780 if (STp->block_size == 0 ||
1781 undone > 0 || count == 0)
1782 retval = (-ENOSPC); /* EOM within current request */
1783 DEBC(printk(ST_DEB_MSG
1784 "%s: EOM with %d bytes unwritten.\n",
1785 name, (int)count));
1786 } else {
1787 /* EOT within data buffered earlier (possible only
1788 in fixed block mode without direct i/o) */
1789 if (!retry_eot && !cmdstatp->deferred &&
1790 (scode == NO_SENSE || scode == RECOVERED_ERROR)) {
1791 move_buffer_data(STp->buffer, transfer - undone);
1792 retry_eot = 1;
1793 if (STps->drv_block >= 0) {
1794 STps->drv_block += (transfer - undone) /
1795 STp->block_size;
1796 }
1797 STps->eof = ST_EOM_OK;
1798 DEBC(printk(ST_DEB_MSG
1799 "%s: Retry write of %d bytes at EOM.\n",
1800 name, STp->buffer->buffer_bytes));
1801 goto retry_write;
1802 }
1803 else {
1804 /* Either error within data buffered by driver or
1805 failed retry */
1806 count -= do_count;
1807 blks = do_count = 0;
1808 STps->eof = ST_EOM_ERROR;
1809 STps->drv_block = (-1); /* Too cautious? */
1810 retval = (-EIO); /* EOM for old data */
1811 DEBC(printk(ST_DEB_MSG
1812 "%s: EOM with lost data.\n",
1813 name));
1814 }
1815 }
1816 } else {
1817 count += do_count;
1818 STps->drv_block = (-1); /* Too cautious? */
Mike Christie8b05b772005-11-08 04:06:44 -06001819 retval = STbp->syscall_result;
Linus Torvalds1da177e2005-04-16 15:20:36 -07001820 }
1821
1822 }
1823
1824 if (STps->drv_block >= 0) {
1825 if (STp->block_size == 0)
1826 STps->drv_block += (do_count > 0);
1827 else
1828 STps->drv_block += blks;
1829 }
1830
1831 STbp->buffer_bytes = 0;
1832 STp->dirty = 0;
1833
1834 if (retval || retry_eot) {
1835 if (count < total)
1836 retval = total - count;
1837 goto out;
1838 }
1839 }
1840
1841 if (STps->eof == ST_EOD_1)
1842 STps->eof = ST_EOM_OK;
1843 else if (STps->eof != ST_EOM_OK)
1844 STps->eof = ST_NOEOF;
1845 retval = total - count;
1846
1847 out:
1848 if (SRpnt != NULL)
Mike Christie8b05b772005-11-08 04:06:44 -06001849 st_release_request(SRpnt);
Kai Makisara787926b2005-11-13 10:04:44 +02001850 release_buffering(STp, 0);
Matthias Kaehlcke28f85002007-07-29 23:38:15 +02001851 mutex_unlock(&STp->lock);
Linus Torvalds1da177e2005-04-16 15:20:36 -07001852
1853 return retval;
1854}
1855
1856/* Read data from the tape. Returns zero in the normal case, one if the
1857 eof status has changed, and the negative error code in case of a
1858 fatal error. Otherwise updates the buffer and the eof state.
1859
1860 Does release user buffer mapping if it is set.
1861*/
1862static long read_tape(struct scsi_tape *STp, long count,
Mike Christie8b05b772005-11-08 04:06:44 -06001863 struct st_request ** aSRpnt)
Linus Torvalds1da177e2005-04-16 15:20:36 -07001864{
1865 int transfer, blks, bytes;
1866 unsigned char cmd[MAX_COMMAND_SIZE];
Mike Christie8b05b772005-11-08 04:06:44 -06001867 struct st_request *SRpnt;
Linus Torvalds1da177e2005-04-16 15:20:36 -07001868 struct st_modedef *STm;
1869 struct st_partstat *STps;
1870 struct st_buffer *STbp;
1871 int retval = 0;
1872 char *name = tape_name(STp);
1873
1874 if (count == 0)
1875 return 0;
1876
1877 STm = &(STp->modes[STp->current_mode]);
1878 STps = &(STp->ps[STp->partition]);
1879 if (STps->eof == ST_FM_HIT)
1880 return 1;
1881 STbp = STp->buffer;
1882
1883 if (STp->block_size == 0)
1884 blks = bytes = count;
1885 else {
Kai Makisara9abe16c2007-02-03 13:21:29 +02001886 if (!(STp->try_dio_now && try_rdio) && STm->do_read_ahead) {
Linus Torvalds1da177e2005-04-16 15:20:36 -07001887 blks = (STp->buffer)->buffer_blocks;
1888 bytes = blks * STp->block_size;
1889 } else {
1890 bytes = count;
1891 if (!STbp->do_dio && bytes > (STp->buffer)->buffer_size)
1892 bytes = (STp->buffer)->buffer_size;
1893 blks = bytes / STp->block_size;
1894 bytes = blks * STp->block_size;
1895 }
1896 }
1897
1898 memset(cmd, 0, MAX_COMMAND_SIZE);
1899 cmd[0] = READ_6;
1900 cmd[1] = (STp->block_size != 0);
Kai Makisara40f6b362008-02-24 22:23:24 +02001901 if (!cmd[1] && STp->sili)
1902 cmd[1] |= 2;
Linus Torvalds1da177e2005-04-16 15:20:36 -07001903 cmd[2] = blks >> 16;
1904 cmd[3] = blks >> 8;
1905 cmd[4] = blks;
1906
1907 SRpnt = *aSRpnt;
1908 SRpnt = st_do_scsi(SRpnt, STp, cmd, bytes, DMA_FROM_DEVICE,
James Bottomleya02488e2008-11-30 10:36:26 -06001909 STp->device->request_queue->rq_timeout,
1910 MAX_RETRIES, 1);
Kai Makisara787926b2005-11-13 10:04:44 +02001911 release_buffering(STp, 1);
Linus Torvalds1da177e2005-04-16 15:20:36 -07001912 *aSRpnt = SRpnt;
1913 if (!SRpnt)
1914 return STbp->syscall_result;
1915
1916 STbp->read_pointer = 0;
1917 STps->at_sm = 0;
1918
1919 /* Something to check */
1920 if (STbp->syscall_result) {
1921 struct st_cmdstatus *cmdstatp = &STp->buffer->cmdstat;
1922
1923 retval = 1;
1924 DEBC(printk(ST_DEB_MSG "%s: Sense: %2x %2x %2x %2x %2x %2x %2x %2x\n",
1925 name,
Mike Christie8b05b772005-11-08 04:06:44 -06001926 SRpnt->sense[0], SRpnt->sense[1],
1927 SRpnt->sense[2], SRpnt->sense[3],
1928 SRpnt->sense[4], SRpnt->sense[5],
1929 SRpnt->sense[6], SRpnt->sense[7]));
Linus Torvalds1da177e2005-04-16 15:20:36 -07001930 if (cmdstatp->have_sense) {
1931
1932 if (cmdstatp->sense_hdr.sense_key == BLANK_CHECK)
1933 cmdstatp->flags &= 0xcf; /* No need for EOM in this case */
1934
1935 if (cmdstatp->flags != 0) { /* EOF, EOM, or ILI */
1936 /* Compute the residual count */
1937 if (cmdstatp->remainder_valid)
1938 transfer = (int)cmdstatp->uremainder64;
1939 else
1940 transfer = 0;
1941 if (STp->block_size == 0 &&
1942 cmdstatp->sense_hdr.sense_key == MEDIUM_ERROR)
1943 transfer = bytes;
1944
1945 if (cmdstatp->flags & SENSE_ILI) { /* ILI */
1946 if (STp->block_size == 0) {
1947 if (transfer <= 0) {
1948 if (transfer < 0)
1949 printk(KERN_NOTICE
1950 "%s: Failed to read %d byte block with %d byte transfer.\n",
1951 name, bytes - transfer, bytes);
1952 if (STps->drv_block >= 0)
1953 STps->drv_block += 1;
1954 STbp->buffer_bytes = 0;
1955 return (-ENOMEM);
1956 }
1957 STbp->buffer_bytes = bytes - transfer;
1958 } else {
Mike Christie8b05b772005-11-08 04:06:44 -06001959 st_release_request(SRpnt);
Linus Torvalds1da177e2005-04-16 15:20:36 -07001960 SRpnt = *aSRpnt = NULL;
1961 if (transfer == blks) { /* We did not get anything, error */
1962 printk(KERN_NOTICE "%s: Incorrect block size.\n", name);
1963 if (STps->drv_block >= 0)
1964 STps->drv_block += blks - transfer + 1;
1965 st_int_ioctl(STp, MTBSR, 1);
1966 return (-EIO);
1967 }
1968 /* We have some data, deliver it */
1969 STbp->buffer_bytes = (blks - transfer) *
1970 STp->block_size;
1971 DEBC(printk(ST_DEB_MSG
1972 "%s: ILI but enough data received %ld %d.\n",
1973 name, count, STbp->buffer_bytes));
1974 if (STps->drv_block >= 0)
1975 STps->drv_block += 1;
1976 if (st_int_ioctl(STp, MTBSR, 1))
1977 return (-EIO);
1978 }
1979 } else if (cmdstatp->flags & SENSE_FMK) { /* FM overrides EOM */
1980 if (STps->eof != ST_FM_HIT)
1981 STps->eof = ST_FM_HIT;
1982 else
1983 STps->eof = ST_EOD_2;
1984 if (STp->block_size == 0)
1985 STbp->buffer_bytes = 0;
1986 else
1987 STbp->buffer_bytes =
1988 bytes - transfer * STp->block_size;
1989 DEBC(printk(ST_DEB_MSG
1990 "%s: EOF detected (%d bytes read).\n",
1991 name, STbp->buffer_bytes));
1992 } else if (cmdstatp->flags & SENSE_EOM) {
1993 if (STps->eof == ST_FM)
1994 STps->eof = ST_EOD_1;
1995 else
1996 STps->eof = ST_EOM_OK;
1997 if (STp->block_size == 0)
1998 STbp->buffer_bytes = bytes - transfer;
1999 else
2000 STbp->buffer_bytes =
2001 bytes - transfer * STp->block_size;
2002
2003 DEBC(printk(ST_DEB_MSG "%s: EOM detected (%d bytes read).\n",
2004 name, STbp->buffer_bytes));
2005 }
2006 }
2007 /* end of EOF, EOM, ILI test */
2008 else { /* nonzero sense key */
2009 DEBC(printk(ST_DEB_MSG
2010 "%s: Tape error while reading.\n", name));
2011 STps->drv_block = (-1);
2012 if (STps->eof == ST_FM &&
2013 cmdstatp->sense_hdr.sense_key == BLANK_CHECK) {
2014 DEBC(printk(ST_DEB_MSG
2015 "%s: Zero returned for first BLANK CHECK after EOF.\n",
2016 name));
2017 STps->eof = ST_EOD_2; /* First BLANK_CHECK after FM */
2018 } else /* Some other extended sense code */
2019 retval = (-EIO);
2020 }
2021
2022 if (STbp->buffer_bytes < 0) /* Caused by bogus sense data */
2023 STbp->buffer_bytes = 0;
2024 }
2025 /* End of extended sense test */
2026 else { /* Non-extended sense */
2027 retval = STbp->syscall_result;
2028 }
2029
2030 }
2031 /* End of error handling */
Kai Makisara40f6b362008-02-24 22:23:24 +02002032 else { /* Read successful */
Linus Torvalds1da177e2005-04-16 15:20:36 -07002033 STbp->buffer_bytes = bytes;
Kai Makisara40f6b362008-02-24 22:23:24 +02002034 if (STp->sili) /* In fixed block mode residual is always zero here */
2035 STbp->buffer_bytes -= STp->buffer->cmdstat.residual;
2036 }
Linus Torvalds1da177e2005-04-16 15:20:36 -07002037
2038 if (STps->drv_block >= 0) {
2039 if (STp->block_size == 0)
2040 STps->drv_block++;
2041 else
2042 STps->drv_block += STbp->buffer_bytes / STp->block_size;
2043 }
2044 return retval;
2045}
2046
2047
2048/* Read command */
2049static ssize_t
2050st_read(struct file *filp, char __user *buf, size_t count, loff_t * ppos)
2051{
2052 ssize_t total;
2053 ssize_t retval = 0;
2054 ssize_t i, transfer;
2055 int special, do_dio = 0;
Mike Christie8b05b772005-11-08 04:06:44 -06002056 struct st_request *SRpnt = NULL;
Linus Torvalds1da177e2005-04-16 15:20:36 -07002057 struct scsi_tape *STp = filp->private_data;
2058 struct st_modedef *STm;
2059 struct st_partstat *STps;
2060 struct st_buffer *STbp = STp->buffer;
2061 DEB( char *name = tape_name(STp); )
2062
Matthias Kaehlcke28f85002007-07-29 23:38:15 +02002063 if (mutex_lock_interruptible(&STp->lock))
Linus Torvalds1da177e2005-04-16 15:20:36 -07002064 return -ERESTARTSYS;
2065
2066 retval = rw_checks(STp, filp, count);
2067 if (retval || count == 0)
2068 goto out;
2069
2070 STm = &(STp->modes[STp->current_mode]);
Kai Makisara9abe16c2007-02-03 13:21:29 +02002071 if (STp->block_size != 0 && (count % STp->block_size) != 0) {
2072 if (!STm->do_read_ahead) {
2073 retval = (-EINVAL); /* Read must be integral number of blocks */
2074 goto out;
2075 }
2076 STp->try_dio_now = 0; /* Direct i/o can't handle split blocks */
Linus Torvalds1da177e2005-04-16 15:20:36 -07002077 }
2078
2079 STps = &(STp->ps[STp->partition]);
2080 if (STps->rw == ST_WRITING) {
2081 retval = flush_buffer(STp, 0);
2082 if (retval)
2083 goto out;
2084 STps->rw = ST_READING;
2085 }
2086 DEB(
2087 if (debugging && STps->eof != ST_NOEOF)
2088 printk(ST_DEB_MSG "%s: EOF/EOM flag up (%d). Bytes %d\n", name,
2089 STps->eof, STbp->buffer_bytes);
2090 ) /* end DEB */
2091
2092 retval = setup_buffering(STp, buf, count, 1);
2093 if (retval)
2094 goto out;
2095 do_dio = STbp->do_dio;
2096
2097 if (STbp->buffer_bytes == 0 &&
2098 STps->eof >= ST_EOD_1) {
2099 if (STps->eof < ST_EOD) {
2100 STps->eof += 1;
2101 retval = 0;
2102 goto out;
2103 }
2104 retval = (-EIO); /* EOM or Blank Check */
2105 goto out;
2106 }
2107
2108 if (do_dio) {
2109 /* Check the buffer writability before any tape movement. Don't alter
2110 buffer data. */
2111 if (copy_from_user(&i, buf, 1) != 0 ||
2112 copy_to_user(buf, &i, 1) != 0 ||
2113 copy_from_user(&i, buf + count - 1, 1) != 0 ||
2114 copy_to_user(buf + count - 1, &i, 1) != 0) {
2115 retval = (-EFAULT);
2116 goto out;
2117 }
2118 }
2119
2120 STps->rw = ST_READING;
2121
2122
2123 /* Loop until enough data in buffer or a special condition found */
2124 for (total = 0, special = 0; total < count && !special;) {
2125
2126 /* Get new data if the buffer is empty */
2127 if (STbp->buffer_bytes == 0) {
2128 special = read_tape(STp, count - total, &SRpnt);
2129 if (special < 0) { /* No need to continue read */
2130 retval = special;
2131 goto out;
2132 }
2133 }
2134
2135 /* Move the data from driver buffer to user buffer */
2136 if (STbp->buffer_bytes > 0) {
2137 DEB(
2138 if (debugging && STps->eof != ST_NOEOF)
2139 printk(ST_DEB_MSG
2140 "%s: EOF up (%d). Left %d, needed %d.\n", name,
2141 STps->eof, STbp->buffer_bytes,
2142 (int)(count - total));
2143 ) /* end DEB */
2144 transfer = STbp->buffer_bytes < count - total ?
2145 STbp->buffer_bytes : count - total;
2146 if (!do_dio) {
2147 i = from_buffer(STbp, buf, transfer);
2148 if (i) {
2149 retval = i;
2150 goto out;
2151 }
2152 }
2153 buf += transfer;
2154 total += transfer;
2155 }
2156
2157 if (STp->block_size == 0)
2158 break; /* Read only one variable length block */
2159
2160 } /* for (total = 0, special = 0;
2161 total < count && !special; ) */
2162
2163 /* Change the eof state if no data from tape or buffer */
2164 if (total == 0) {
2165 if (STps->eof == ST_FM_HIT) {
2166 STps->eof = ST_FM;
2167 STps->drv_block = 0;
2168 if (STps->drv_file >= 0)
2169 STps->drv_file++;
2170 } else if (STps->eof == ST_EOD_1) {
2171 STps->eof = ST_EOD_2;
2172 STps->drv_block = 0;
2173 if (STps->drv_file >= 0)
2174 STps->drv_file++;
2175 } else if (STps->eof == ST_EOD_2)
2176 STps->eof = ST_EOD;
2177 } else if (STps->eof == ST_FM)
2178 STps->eof = ST_NOEOF;
2179 retval = total;
2180
2181 out:
2182 if (SRpnt != NULL) {
Mike Christie8b05b772005-11-08 04:06:44 -06002183 st_release_request(SRpnt);
Linus Torvalds1da177e2005-04-16 15:20:36 -07002184 SRpnt = NULL;
2185 }
2186 if (do_dio) {
Kai Makisara787926b2005-11-13 10:04:44 +02002187 release_buffering(STp, 1);
Linus Torvalds1da177e2005-04-16 15:20:36 -07002188 STbp->buffer_bytes = 0;
2189 }
Matthias Kaehlcke28f85002007-07-29 23:38:15 +02002190 mutex_unlock(&STp->lock);
Linus Torvalds1da177e2005-04-16 15:20:36 -07002191
2192 return retval;
2193}
2194
2195
2196
2197DEB(
2198/* Set the driver options */
2199static void st_log_options(struct scsi_tape * STp, struct st_modedef * STm, char *name)
2200{
2201 if (debugging) {
2202 printk(KERN_INFO
2203 "%s: Mode %d options: buffer writes: %d, async writes: %d, read ahead: %d\n",
2204 name, STp->current_mode, STm->do_buffer_writes, STm->do_async_writes,
2205 STm->do_read_ahead);
2206 printk(KERN_INFO
2207 "%s: can bsr: %d, two FMs: %d, fast mteom: %d, auto lock: %d,\n",
2208 name, STp->can_bsr, STp->two_fm, STp->fast_mteom, STp->do_auto_lock);
2209 printk(KERN_INFO
2210 "%s: defs for wr: %d, no block limits: %d, partitions: %d, s2 log: %d\n",
2211 name, STm->defaults_for_writes, STp->omit_blklims, STp->can_partitions,
2212 STp->scsi2_logical);
2213 printk(KERN_INFO
Kai Makisara40f6b362008-02-24 22:23:24 +02002214 "%s: sysv: %d nowait: %d sili: %d\n", name, STm->sysv, STp->immediate,
2215 STp->sili);
Linus Torvalds1da177e2005-04-16 15:20:36 -07002216 printk(KERN_INFO "%s: debugging: %d\n",
2217 name, debugging);
2218 }
2219}
2220 )
2221
2222
2223static int st_set_options(struct scsi_tape *STp, long options)
2224{
2225 int value;
2226 long code;
2227 struct st_modedef *STm;
2228 char *name = tape_name(STp);
2229 struct cdev *cd0, *cd1;
2230
2231 STm = &(STp->modes[STp->current_mode]);
2232 if (!STm->defined) {
2233 cd0 = STm->cdevs[0]; cd1 = STm->cdevs[1];
2234 memcpy(STm, &(STp->modes[0]), sizeof(struct st_modedef));
2235 STm->cdevs[0] = cd0; STm->cdevs[1] = cd1;
2236 modes_defined = 1;
2237 DEBC(printk(ST_DEB_MSG
2238 "%s: Initialized mode %d definition from mode 0\n",
2239 name, STp->current_mode));
2240 }
2241
2242 code = options & MT_ST_OPTIONS;
2243 if (code == MT_ST_BOOLEANS) {
2244 STm->do_buffer_writes = (options & MT_ST_BUFFER_WRITES) != 0;
2245 STm->do_async_writes = (options & MT_ST_ASYNC_WRITES) != 0;
2246 STm->defaults_for_writes = (options & MT_ST_DEF_WRITES) != 0;
2247 STm->do_read_ahead = (options & MT_ST_READ_AHEAD) != 0;
2248 STp->two_fm = (options & MT_ST_TWO_FM) != 0;
2249 STp->fast_mteom = (options & MT_ST_FAST_MTEOM) != 0;
2250 STp->do_auto_lock = (options & MT_ST_AUTO_LOCK) != 0;
2251 STp->can_bsr = (options & MT_ST_CAN_BSR) != 0;
2252 STp->omit_blklims = (options & MT_ST_NO_BLKLIMS) != 0;
2253 if ((STp->device)->scsi_level >= SCSI_2)
2254 STp->can_partitions = (options & MT_ST_CAN_PARTITIONS) != 0;
2255 STp->scsi2_logical = (options & MT_ST_SCSI2LOGICAL) != 0;
2256 STp->immediate = (options & MT_ST_NOWAIT) != 0;
2257 STm->sysv = (options & MT_ST_SYSV) != 0;
Kai Makisara40f6b362008-02-24 22:23:24 +02002258 STp->sili = (options & MT_ST_SILI) != 0;
Linus Torvalds1da177e2005-04-16 15:20:36 -07002259 DEB( debugging = (options & MT_ST_DEBUGGING) != 0;
2260 st_log_options(STp, STm, name); )
2261 } else if (code == MT_ST_SETBOOLEANS || code == MT_ST_CLEARBOOLEANS) {
2262 value = (code == MT_ST_SETBOOLEANS);
2263 if ((options & MT_ST_BUFFER_WRITES) != 0)
2264 STm->do_buffer_writes = value;
2265 if ((options & MT_ST_ASYNC_WRITES) != 0)
2266 STm->do_async_writes = value;
2267 if ((options & MT_ST_DEF_WRITES) != 0)
2268 STm->defaults_for_writes = value;
2269 if ((options & MT_ST_READ_AHEAD) != 0)
2270 STm->do_read_ahead = value;
2271 if ((options & MT_ST_TWO_FM) != 0)
2272 STp->two_fm = value;
2273 if ((options & MT_ST_FAST_MTEOM) != 0)
2274 STp->fast_mteom = value;
2275 if ((options & MT_ST_AUTO_LOCK) != 0)
2276 STp->do_auto_lock = value;
2277 if ((options & MT_ST_CAN_BSR) != 0)
2278 STp->can_bsr = value;
2279 if ((options & MT_ST_NO_BLKLIMS) != 0)
2280 STp->omit_blklims = value;
2281 if ((STp->device)->scsi_level >= SCSI_2 &&
2282 (options & MT_ST_CAN_PARTITIONS) != 0)
2283 STp->can_partitions = value;
2284 if ((options & MT_ST_SCSI2LOGICAL) != 0)
2285 STp->scsi2_logical = value;
2286 if ((options & MT_ST_NOWAIT) != 0)
2287 STp->immediate = value;
2288 if ((options & MT_ST_SYSV) != 0)
2289 STm->sysv = value;
Kai Makisara40f6b362008-02-24 22:23:24 +02002290 if ((options & MT_ST_SILI) != 0)
2291 STp->sili = value;
Linus Torvalds1da177e2005-04-16 15:20:36 -07002292 DEB(
2293 if ((options & MT_ST_DEBUGGING) != 0)
2294 debugging = value;
2295 st_log_options(STp, STm, name); )
2296 } else if (code == MT_ST_WRITE_THRESHOLD) {
2297 /* Retained for compatibility */
2298 } else if (code == MT_ST_DEF_BLKSIZE) {
2299 value = (options & ~MT_ST_OPTIONS);
2300 if (value == ~MT_ST_OPTIONS) {
2301 STm->default_blksize = (-1);
2302 DEBC( printk(KERN_INFO "%s: Default block size disabled.\n", name));
2303 } else {
2304 STm->default_blksize = value;
2305 DEBC( printk(KERN_INFO "%s: Default block size set to %d bytes.\n",
2306 name, STm->default_blksize));
2307 if (STp->ready == ST_READY) {
2308 STp->blksize_changed = 0;
2309 set_mode_densblk(STp, STm);
2310 }
2311 }
2312 } else if (code == MT_ST_TIMEOUTS) {
2313 value = (options & ~MT_ST_OPTIONS);
2314 if ((value & MT_ST_SET_LONG_TIMEOUT) != 0) {
2315 STp->long_timeout = (value & ~MT_ST_SET_LONG_TIMEOUT) * HZ;
2316 DEBC( printk(KERN_INFO "%s: Long timeout set to %d seconds.\n", name,
2317 (value & ~MT_ST_SET_LONG_TIMEOUT)));
2318 } else {
James Bottomleya02488e2008-11-30 10:36:26 -06002319 blk_queue_rq_timeout(STp->device->request_queue,
2320 value * HZ);
Linus Torvalds1da177e2005-04-16 15:20:36 -07002321 DEBC( printk(KERN_INFO "%s: Normal timeout set to %d seconds.\n",
2322 name, value) );
2323 }
2324 } else if (code == MT_ST_SET_CLN) {
2325 value = (options & ~MT_ST_OPTIONS) & 0xff;
2326 if (value != 0 &&
2327 value < EXTENDED_SENSE_START && value >= SCSI_SENSE_BUFFERSIZE)
2328 return (-EINVAL);
2329 STp->cln_mode = value;
2330 STp->cln_sense_mask = (options >> 8) & 0xff;
2331 STp->cln_sense_value = (options >> 16) & 0xff;
2332 printk(KERN_INFO
2333 "%s: Cleaning request mode %d, mask %02x, value %02x\n",
2334 name, value, STp->cln_sense_mask, STp->cln_sense_value);
2335 } else if (code == MT_ST_DEF_OPTIONS) {
2336 code = (options & ~MT_ST_CLEAR_DEFAULT);
2337 value = (options & MT_ST_CLEAR_DEFAULT);
2338 if (code == MT_ST_DEF_DENSITY) {
2339 if (value == MT_ST_CLEAR_DEFAULT) {
2340 STm->default_density = (-1);
2341 DEBC( printk(KERN_INFO "%s: Density default disabled.\n",
2342 name));
2343 } else {
2344 STm->default_density = value & 0xff;
2345 DEBC( printk(KERN_INFO "%s: Density default set to %x\n",
2346 name, STm->default_density));
2347 if (STp->ready == ST_READY) {
2348 STp->density_changed = 0;
2349 set_mode_densblk(STp, STm);
2350 }
2351 }
2352 } else if (code == MT_ST_DEF_DRVBUFFER) {
2353 if (value == MT_ST_CLEAR_DEFAULT) {
2354 STp->default_drvbuffer = 0xff;
2355 DEBC( printk(KERN_INFO
2356 "%s: Drive buffer default disabled.\n", name));
2357 } else {
2358 STp->default_drvbuffer = value & 7;
2359 DEBC( printk(KERN_INFO
2360 "%s: Drive buffer default set to %x\n",
2361 name, STp->default_drvbuffer));
2362 if (STp->ready == ST_READY)
2363 st_int_ioctl(STp, MTSETDRVBUFFER, STp->default_drvbuffer);
2364 }
2365 } else if (code == MT_ST_DEF_COMPRESSION) {
2366 if (value == MT_ST_CLEAR_DEFAULT) {
2367 STm->default_compression = ST_DONT_TOUCH;
2368 DEBC( printk(KERN_INFO
2369 "%s: Compression default disabled.\n", name));
2370 } else {
2371 if ((value & 0xff00) != 0) {
2372 STp->c_algo = (value & 0xff00) >> 8;
2373 DEBC( printk(KERN_INFO "%s: Compression algorithm set to 0x%x.\n",
2374 name, STp->c_algo));
2375 }
2376 if ((value & 0xff) != 0xff) {
2377 STm->default_compression = (value & 1 ? ST_YES : ST_NO);
2378 DEBC( printk(KERN_INFO "%s: Compression default set to %x\n",
2379 name, (value & 1)));
2380 if (STp->ready == ST_READY) {
2381 STp->compression_changed = 0;
2382 st_compression(STp, (STm->default_compression == ST_YES));
2383 }
2384 }
2385 }
2386 }
2387 } else
2388 return (-EIO);
2389
2390 return 0;
2391}
2392
2393#define MODE_HEADER_LENGTH 4
2394
2395/* Mode header and page byte offsets */
2396#define MH_OFF_DATA_LENGTH 0
2397#define MH_OFF_MEDIUM_TYPE 1
2398#define MH_OFF_DEV_SPECIFIC 2
2399#define MH_OFF_BDESCS_LENGTH 3
2400#define MP_OFF_PAGE_NBR 0
2401#define MP_OFF_PAGE_LENGTH 1
2402
2403/* Mode header and page bit masks */
2404#define MH_BIT_WP 0x80
2405#define MP_MSK_PAGE_NBR 0x3f
2406
2407/* Don't return block descriptors */
2408#define MODE_SENSE_OMIT_BDESCS 0x08
2409
2410#define MODE_SELECT_PAGE_FORMAT 0x10
2411
2412/* Read a mode page into the tape buffer. The block descriptors are included
2413 if incl_block_descs is true. The page control is ored to the page number
2414 parameter, if necessary. */
2415static int read_mode_page(struct scsi_tape *STp, int page, int omit_block_descs)
2416{
2417 unsigned char cmd[MAX_COMMAND_SIZE];
FUJITA Tomonori8ecf0d92008-12-05 15:25:28 +09002418 struct st_request *SRpnt;
2419 int ret;
Linus Torvalds1da177e2005-04-16 15:20:36 -07002420
2421 memset(cmd, 0, MAX_COMMAND_SIZE);
2422 cmd[0] = MODE_SENSE;
2423 if (omit_block_descs)
2424 cmd[1] = MODE_SENSE_OMIT_BDESCS;
2425 cmd[2] = page;
2426 cmd[4] = 255;
2427
FUJITA Tomonori8ecf0d92008-12-05 15:25:28 +09002428 SRpnt = st_allocate_request(STp);
2429 if (!SRpnt)
2430 return STp->buffer->syscall_result;
Linus Torvalds1da177e2005-04-16 15:20:36 -07002431
FUJITA Tomonori8ecf0d92008-12-05 15:25:28 +09002432 ret = st_scsi_kern_execute(SRpnt, cmd, DMA_FROM_DEVICE,
2433 STp->buffer->b_data, cmd[4],
2434 STp->device->request_queue->rq_timeout,
2435 MAX_RETRIES);
Mike Christie8b05b772005-11-08 04:06:44 -06002436 st_release_request(SRpnt);
Linus Torvalds1da177e2005-04-16 15:20:36 -07002437
FUJITA Tomonori8ecf0d92008-12-05 15:25:28 +09002438 return ret ? : STp->buffer->syscall_result;
Linus Torvalds1da177e2005-04-16 15:20:36 -07002439}
2440
2441
2442/* Send the mode page in the tape buffer to the drive. Assumes that the mode data
2443 in the buffer is correctly formatted. The long timeout is used if slow is non-zero. */
2444static int write_mode_page(struct scsi_tape *STp, int page, int slow)
2445{
FUJITA Tomonori18c87012008-12-05 15:25:29 +09002446 int pgo, timeout, ret = 0;
Linus Torvalds1da177e2005-04-16 15:20:36 -07002447 unsigned char cmd[MAX_COMMAND_SIZE];
FUJITA Tomonori18c87012008-12-05 15:25:29 +09002448 struct st_request *SRpnt;
Linus Torvalds1da177e2005-04-16 15:20:36 -07002449
2450 memset(cmd, 0, MAX_COMMAND_SIZE);
2451 cmd[0] = MODE_SELECT;
2452 cmd[1] = MODE_SELECT_PAGE_FORMAT;
2453 pgo = MODE_HEADER_LENGTH + (STp->buffer)->b_data[MH_OFF_BDESCS_LENGTH];
2454 cmd[4] = pgo + (STp->buffer)->b_data[pgo + MP_OFF_PAGE_LENGTH] + 2;
2455
2456 /* Clear reserved fields */
2457 (STp->buffer)->b_data[MH_OFF_DATA_LENGTH] = 0;
2458 (STp->buffer)->b_data[MH_OFF_MEDIUM_TYPE] = 0;
2459 (STp->buffer)->b_data[MH_OFF_DEV_SPECIFIC] &= ~MH_BIT_WP;
2460 (STp->buffer)->b_data[pgo + MP_OFF_PAGE_NBR] &= MP_MSK_PAGE_NBR;
2461
FUJITA Tomonori18c87012008-12-05 15:25:29 +09002462 SRpnt = st_allocate_request(STp);
2463 if (!SRpnt)
2464 return ret;
2465
2466 timeout = slow ? STp->long_timeout :
2467 STp->device->request_queue->rq_timeout;
2468
2469 ret = st_scsi_kern_execute(SRpnt, cmd, DMA_TO_DEVICE,
2470 STp->buffer->b_data, cmd[4], timeout, 0);
2471 if (!ret)
2472 ret = STp->buffer->syscall_result;
Linus Torvalds1da177e2005-04-16 15:20:36 -07002473
Mike Christie8b05b772005-11-08 04:06:44 -06002474 st_release_request(SRpnt);
Linus Torvalds1da177e2005-04-16 15:20:36 -07002475
FUJITA Tomonori18c87012008-12-05 15:25:29 +09002476 return ret;
Linus Torvalds1da177e2005-04-16 15:20:36 -07002477}
2478
2479
2480#define COMPRESSION_PAGE 0x0f
2481#define COMPRESSION_PAGE_LENGTH 16
2482
2483#define CP_OFF_DCE_DCC 2
2484#define CP_OFF_C_ALGO 7
2485
2486#define DCE_MASK 0x80
2487#define DCC_MASK 0x40
2488#define RED_MASK 0x60
2489
2490
2491/* Control the compression with mode page 15. Algorithm not changed if zero.
2492
2493 The block descriptors are read and written because Sony SDT-7000 does not
2494 work without this (suggestion from Michael Schaefer <Michael.Schaefer@dlr.de>).
2495 Including block descriptors should not cause any harm to other drives. */
2496
2497static int st_compression(struct scsi_tape * STp, int state)
2498{
2499 int retval;
2500 int mpoffs; /* Offset to mode page start */
2501 unsigned char *b_data = (STp->buffer)->b_data;
2502 DEB( char *name = tape_name(STp); )
2503
2504 if (STp->ready != ST_READY)
2505 return (-EIO);
2506
2507 /* Read the current page contents */
2508 retval = read_mode_page(STp, COMPRESSION_PAGE, 0);
2509 if (retval) {
2510 DEBC(printk(ST_DEB_MSG "%s: Compression mode page not supported.\n",
2511 name));
2512 return (-EIO);
2513 }
2514
2515 mpoffs = MODE_HEADER_LENGTH + b_data[MH_OFF_BDESCS_LENGTH];
2516 DEBC(printk(ST_DEB_MSG "%s: Compression state is %d.\n", name,
2517 (b_data[mpoffs + CP_OFF_DCE_DCC] & DCE_MASK ? 1 : 0)));
2518
2519 /* Check if compression can be changed */
2520 if ((b_data[mpoffs + CP_OFF_DCE_DCC] & DCC_MASK) == 0) {
2521 DEBC(printk(ST_DEB_MSG "%s: Compression not supported.\n", name));
2522 return (-EIO);
2523 }
2524
2525 /* Do the change */
2526 if (state) {
2527 b_data[mpoffs + CP_OFF_DCE_DCC] |= DCE_MASK;
2528 if (STp->c_algo != 0)
2529 b_data[mpoffs + CP_OFF_C_ALGO] = STp->c_algo;
2530 }
2531 else {
2532 b_data[mpoffs + CP_OFF_DCE_DCC] &= ~DCE_MASK;
2533 if (STp->c_algo != 0)
2534 b_data[mpoffs + CP_OFF_C_ALGO] = 0; /* no compression */
2535 }
2536
2537 retval = write_mode_page(STp, COMPRESSION_PAGE, 0);
2538 if (retval) {
2539 DEBC(printk(ST_DEB_MSG "%s: Compression change failed.\n", name));
2540 return (-EIO);
2541 }
2542 DEBC(printk(ST_DEB_MSG "%s: Compression state changed to %d.\n",
2543 name, state));
2544
2545 STp->compression_changed = 1;
2546 return 0;
2547}
2548
2549
2550/* Process the load and unload commands (does unload if the load code is zero) */
2551static int do_load_unload(struct scsi_tape *STp, struct file *filp, int load_code)
2552{
2553 int retval = (-EIO), timeout;
2554 DEB( char *name = tape_name(STp); )
2555 unsigned char cmd[MAX_COMMAND_SIZE];
2556 struct st_partstat *STps;
Mike Christie8b05b772005-11-08 04:06:44 -06002557 struct st_request *SRpnt;
Linus Torvalds1da177e2005-04-16 15:20:36 -07002558
2559 if (STp->ready != ST_READY && !load_code) {
2560 if (STp->ready == ST_NO_TAPE)
2561 return (-ENOMEDIUM);
2562 else
2563 return (-EIO);
2564 }
2565
2566 memset(cmd, 0, MAX_COMMAND_SIZE);
2567 cmd[0] = START_STOP;
2568 if (load_code)
2569 cmd[4] |= 1;
2570 /*
2571 * If arg >= 1 && arg <= 6 Enhanced load/unload in HP C1553A
2572 */
2573 if (load_code >= 1 + MT_ST_HPLOADER_OFFSET
2574 && load_code <= 6 + MT_ST_HPLOADER_OFFSET) {
2575 DEBC(printk(ST_DEB_MSG "%s: Enhanced %sload slot %2d.\n",
2576 name, (cmd[4]) ? "" : "un",
2577 load_code - MT_ST_HPLOADER_OFFSET));
2578 cmd[3] = load_code - MT_ST_HPLOADER_OFFSET; /* MediaID field of C1553A */
2579 }
2580 if (STp->immediate) {
2581 cmd[1] = 1; /* Don't wait for completion */
James Bottomleya02488e2008-11-30 10:36:26 -06002582 timeout = STp->device->request_queue->rq_timeout;
Linus Torvalds1da177e2005-04-16 15:20:36 -07002583 }
2584 else
2585 timeout = STp->long_timeout;
2586
2587 DEBC(
2588 if (!load_code)
2589 printk(ST_DEB_MSG "%s: Unloading tape.\n", name);
2590 else
2591 printk(ST_DEB_MSG "%s: Loading tape.\n", name);
2592 );
2593
FUJITA Tomonori15c920a2008-12-05 15:25:24 +09002594 SRpnt = st_allocate_request(STp);
Linus Torvalds1da177e2005-04-16 15:20:36 -07002595 if (!SRpnt)
FUJITA Tomonori15c920a2008-12-05 15:25:24 +09002596 return STp->buffer->syscall_result;
2597
2598 retval = st_scsi_kern_execute(SRpnt, cmd, DMA_NONE, NULL, 0, timeout,
2599 MAX_RETRIES);
2600 if (retval)
2601 goto out;
Linus Torvalds1da177e2005-04-16 15:20:36 -07002602
2603 retval = (STp->buffer)->syscall_result;
Linus Torvalds1da177e2005-04-16 15:20:36 -07002604
2605 if (!retval) { /* SCSI command successful */
2606
2607 if (!load_code) {
2608 STp->rew_at_close = 0;
2609 STp->ready = ST_NO_TAPE;
2610 }
2611 else {
2612 STp->rew_at_close = STp->autorew_dev;
2613 retval = check_tape(STp, filp);
2614 if (retval > 0)
2615 retval = 0;
2616 }
2617 }
2618 else {
2619 STps = &(STp->ps[STp->partition]);
2620 STps->drv_file = STps->drv_block = (-1);
2621 }
FUJITA Tomonori15c920a2008-12-05 15:25:24 +09002622out:
2623 st_release_request(SRpnt);
Linus Torvalds1da177e2005-04-16 15:20:36 -07002624
2625 return retval;
2626}
2627
2628#if DEBUG
2629#define ST_DEB_FORWARD 0
2630#define ST_DEB_BACKWARD 1
2631static void deb_space_print(char *name, int direction, char *units, unsigned char *cmd)
2632{
2633 s32 sc;
2634
2635 sc = cmd[2] & 0x80 ? 0xff000000 : 0;
2636 sc |= (cmd[2] << 16) | (cmd[3] << 8) | cmd[4];
2637 if (direction)
2638 sc = -sc;
2639 printk(ST_DEB_MSG "%s: Spacing tape %s over %d %s.\n", name,
2640 direction ? "backward" : "forward", sc, units);
2641}
2642#endif
2643
2644
2645/* Internal ioctl function */
2646static int st_int_ioctl(struct scsi_tape *STp, unsigned int cmd_in, unsigned long arg)
2647{
2648 int timeout;
2649 long ltmp;
2650 int ioctl_result;
2651 int chg_eof = 1;
2652 unsigned char cmd[MAX_COMMAND_SIZE];
Mike Christie8b05b772005-11-08 04:06:44 -06002653 struct st_request *SRpnt;
Linus Torvalds1da177e2005-04-16 15:20:36 -07002654 struct st_partstat *STps;
2655 int fileno, blkno, at_sm, undone;
2656 int datalen = 0, direction = DMA_NONE;
2657 char *name = tape_name(STp);
2658
2659 WARN_ON(STp->buffer->do_dio != 0);
2660 if (STp->ready != ST_READY) {
2661 if (STp->ready == ST_NO_TAPE)
2662 return (-ENOMEDIUM);
2663 else
2664 return (-EIO);
2665 }
2666 timeout = STp->long_timeout;
2667 STps = &(STp->ps[STp->partition]);
2668 fileno = STps->drv_file;
2669 blkno = STps->drv_block;
2670 at_sm = STps->at_sm;
2671
2672 memset(cmd, 0, MAX_COMMAND_SIZE);
2673 switch (cmd_in) {
2674 case MTFSFM:
2675 chg_eof = 0; /* Changed from the FSF after this */
2676 case MTFSF:
2677 cmd[0] = SPACE;
2678 cmd[1] = 0x01; /* Space FileMarks */
2679 cmd[2] = (arg >> 16);
2680 cmd[3] = (arg >> 8);
2681 cmd[4] = arg;
2682 DEBC(deb_space_print(name, ST_DEB_FORWARD, "filemarks", cmd);)
2683 if (fileno >= 0)
2684 fileno += arg;
2685 blkno = 0;
2686 at_sm &= (arg == 0);
2687 break;
2688 case MTBSFM:
2689 chg_eof = 0; /* Changed from the FSF after this */
2690 case MTBSF:
2691 cmd[0] = SPACE;
2692 cmd[1] = 0x01; /* Space FileMarks */
2693 ltmp = (-arg);
2694 cmd[2] = (ltmp >> 16);
2695 cmd[3] = (ltmp >> 8);
2696 cmd[4] = ltmp;
2697 DEBC(deb_space_print(name, ST_DEB_BACKWARD, "filemarks", cmd);)
2698 if (fileno >= 0)
2699 fileno -= arg;
2700 blkno = (-1); /* We can't know the block number */
2701 at_sm &= (arg == 0);
2702 break;
2703 case MTFSR:
2704 cmd[0] = SPACE;
2705 cmd[1] = 0x00; /* Space Blocks */
2706 cmd[2] = (arg >> 16);
2707 cmd[3] = (arg >> 8);
2708 cmd[4] = arg;
2709 DEBC(deb_space_print(name, ST_DEB_FORWARD, "blocks", cmd);)
2710 if (blkno >= 0)
2711 blkno += arg;
2712 at_sm &= (arg == 0);
2713 break;
2714 case MTBSR:
2715 cmd[0] = SPACE;
2716 cmd[1] = 0x00; /* Space Blocks */
2717 ltmp = (-arg);
2718 cmd[2] = (ltmp >> 16);
2719 cmd[3] = (ltmp >> 8);
2720 cmd[4] = ltmp;
2721 DEBC(deb_space_print(name, ST_DEB_BACKWARD, "blocks", cmd);)
2722 if (blkno >= 0)
2723 blkno -= arg;
2724 at_sm &= (arg == 0);
2725 break;
2726 case MTFSS:
2727 cmd[0] = SPACE;
2728 cmd[1] = 0x04; /* Space Setmarks */
2729 cmd[2] = (arg >> 16);
2730 cmd[3] = (arg >> 8);
2731 cmd[4] = arg;
2732 DEBC(deb_space_print(name, ST_DEB_FORWARD, "setmarks", cmd);)
2733 if (arg != 0) {
2734 blkno = fileno = (-1);
2735 at_sm = 1;
2736 }
2737 break;
2738 case MTBSS:
2739 cmd[0] = SPACE;
2740 cmd[1] = 0x04; /* Space Setmarks */
2741 ltmp = (-arg);
2742 cmd[2] = (ltmp >> 16);
2743 cmd[3] = (ltmp >> 8);
2744 cmd[4] = ltmp;
2745 DEBC(deb_space_print(name, ST_DEB_BACKWARD, "setmarks", cmd);)
2746 if (arg != 0) {
2747 blkno = fileno = (-1);
2748 at_sm = 1;
2749 }
2750 break;
2751 case MTWEOF:
2752 case MTWSM:
2753 if (STp->write_prot)
2754 return (-EACCES);
2755 cmd[0] = WRITE_FILEMARKS;
2756 if (cmd_in == MTWSM)
2757 cmd[1] = 2;
2758 cmd[2] = (arg >> 16);
2759 cmd[3] = (arg >> 8);
2760 cmd[4] = arg;
James Bottomleya02488e2008-11-30 10:36:26 -06002761 timeout = STp->device->request_queue->rq_timeout;
Linus Torvalds1da177e2005-04-16 15:20:36 -07002762 DEBC(
2763 if (cmd_in == MTWEOF)
2764 printk(ST_DEB_MSG "%s: Writing %d filemarks.\n", name,
2765 cmd[2] * 65536 + cmd[3] * 256 + cmd[4]);
2766 else
2767 printk(ST_DEB_MSG "%s: Writing %d setmarks.\n", name,
2768 cmd[2] * 65536 + cmd[3] * 256 + cmd[4]);
2769 )
2770 if (fileno >= 0)
2771 fileno += arg;
2772 blkno = 0;
2773 at_sm = (cmd_in == MTWSM);
2774 break;
2775 case MTREW:
2776 cmd[0] = REZERO_UNIT;
2777 if (STp->immediate) {
2778 cmd[1] = 1; /* Don't wait for completion */
James Bottomleya02488e2008-11-30 10:36:26 -06002779 timeout = STp->device->request_queue->rq_timeout;
Linus Torvalds1da177e2005-04-16 15:20:36 -07002780 }
2781 DEBC(printk(ST_DEB_MSG "%s: Rewinding tape.\n", name));
2782 fileno = blkno = at_sm = 0;
2783 break;
2784 case MTNOP:
2785 DEBC(printk(ST_DEB_MSG "%s: No op on tape.\n", name));
2786 return 0; /* Should do something ? */
2787 break;
2788 case MTRETEN:
2789 cmd[0] = START_STOP;
2790 if (STp->immediate) {
2791 cmd[1] = 1; /* Don't wait for completion */
James Bottomleya02488e2008-11-30 10:36:26 -06002792 timeout = STp->device->request_queue->rq_timeout;
Linus Torvalds1da177e2005-04-16 15:20:36 -07002793 }
2794 cmd[4] = 3;
2795 DEBC(printk(ST_DEB_MSG "%s: Retensioning tape.\n", name));
2796 fileno = blkno = at_sm = 0;
2797 break;
2798 case MTEOM:
2799 if (!STp->fast_mteom) {
2800 /* space to the end of tape */
2801 ioctl_result = st_int_ioctl(STp, MTFSF, 0x7fffff);
2802 fileno = STps->drv_file;
2803 if (STps->eof >= ST_EOD_1)
2804 return 0;
2805 /* The next lines would hide the number of spaced FileMarks
2806 That's why I inserted the previous lines. I had no luck
2807 with detecting EOM with FSF, so we go now to EOM.
2808 Joerg Weule */
2809 } else
2810 fileno = (-1);
2811 cmd[0] = SPACE;
2812 cmd[1] = 3;
2813 DEBC(printk(ST_DEB_MSG "%s: Spacing to end of recorded medium.\n",
2814 name));
2815 blkno = -1;
2816 at_sm = 0;
2817 break;
2818 case MTERASE:
2819 if (STp->write_prot)
2820 return (-EACCES);
2821 cmd[0] = ERASE;
2822 cmd[1] = (arg ? 1 : 0); /* Long erase with non-zero argument */
2823 if (STp->immediate) {
2824 cmd[1] |= 2; /* Don't wait for completion */
James Bottomleya02488e2008-11-30 10:36:26 -06002825 timeout = STp->device->request_queue->rq_timeout;
Linus Torvalds1da177e2005-04-16 15:20:36 -07002826 }
2827 else
2828 timeout = STp->long_timeout * 8;
2829
2830 DEBC(printk(ST_DEB_MSG "%s: Erasing tape.\n", name));
2831 fileno = blkno = at_sm = 0;
2832 break;
2833 case MTSETBLK: /* Set block length */
2834 case MTSETDENSITY: /* Set tape density */
2835 case MTSETDRVBUFFER: /* Set drive buffering */
2836 case SET_DENS_AND_BLK: /* Set density and block size */
2837 chg_eof = 0;
2838 if (STp->dirty || (STp->buffer)->buffer_bytes != 0)
2839 return (-EIO); /* Not allowed if data in buffer */
2840 if ((cmd_in == MTSETBLK || cmd_in == SET_DENS_AND_BLK) &&
2841 (arg & MT_ST_BLKSIZE_MASK) != 0 &&
2842 STp->max_block > 0 &&
2843 ((arg & MT_ST_BLKSIZE_MASK) < STp->min_block ||
2844 (arg & MT_ST_BLKSIZE_MASK) > STp->max_block)) {
2845 printk(KERN_WARNING "%s: Illegal block size.\n", name);
2846 return (-EINVAL);
2847 }
2848 cmd[0] = MODE_SELECT;
2849 if ((STp->use_pf & USE_PF))
2850 cmd[1] = MODE_SELECT_PAGE_FORMAT;
2851 cmd[4] = datalen = 12;
2852 direction = DMA_TO_DEVICE;
2853
2854 memset((STp->buffer)->b_data, 0, 12);
2855 if (cmd_in == MTSETDRVBUFFER)
2856 (STp->buffer)->b_data[2] = (arg & 7) << 4;
2857 else
2858 (STp->buffer)->b_data[2] =
2859 STp->drv_buffer << 4;
2860 (STp->buffer)->b_data[3] = 8; /* block descriptor length */
2861 if (cmd_in == MTSETDENSITY) {
2862 (STp->buffer)->b_data[4] = arg;
2863 STp->density_changed = 1; /* At least we tried ;-) */
2864 } else if (cmd_in == SET_DENS_AND_BLK)
2865 (STp->buffer)->b_data[4] = arg >> 24;
2866 else
2867 (STp->buffer)->b_data[4] = STp->density;
2868 if (cmd_in == MTSETBLK || cmd_in == SET_DENS_AND_BLK) {
2869 ltmp = arg & MT_ST_BLKSIZE_MASK;
2870 if (cmd_in == MTSETBLK)
2871 STp->blksize_changed = 1; /* At least we tried ;-) */
2872 } else
2873 ltmp = STp->block_size;
2874 (STp->buffer)->b_data[9] = (ltmp >> 16);
2875 (STp->buffer)->b_data[10] = (ltmp >> 8);
2876 (STp->buffer)->b_data[11] = ltmp;
James Bottomleya02488e2008-11-30 10:36:26 -06002877 timeout = STp->device->request_queue->rq_timeout;
Linus Torvalds1da177e2005-04-16 15:20:36 -07002878 DEBC(
2879 if (cmd_in == MTSETBLK || cmd_in == SET_DENS_AND_BLK)
2880 printk(ST_DEB_MSG
2881 "%s: Setting block size to %d bytes.\n", name,
2882 (STp->buffer)->b_data[9] * 65536 +
2883 (STp->buffer)->b_data[10] * 256 +
2884 (STp->buffer)->b_data[11]);
2885 if (cmd_in == MTSETDENSITY || cmd_in == SET_DENS_AND_BLK)
2886 printk(ST_DEB_MSG
2887 "%s: Setting density code to %x.\n", name,
2888 (STp->buffer)->b_data[4]);
2889 if (cmd_in == MTSETDRVBUFFER)
2890 printk(ST_DEB_MSG
2891 "%s: Setting drive buffer code to %d.\n", name,
2892 ((STp->buffer)->b_data[2] >> 4) & 7);
2893 )
2894 break;
2895 default:
2896 return (-ENOSYS);
2897 }
2898
FUJITA Tomonoriccc607f2008-12-05 15:25:31 +09002899 SRpnt = st_allocate_request(STp);
Linus Torvalds1da177e2005-04-16 15:20:36 -07002900 if (!SRpnt)
2901 return (STp->buffer)->syscall_result;
2902
FUJITA Tomonoriccc607f2008-12-05 15:25:31 +09002903 ioctl_result = st_scsi_kern_execute(SRpnt, cmd, direction,
2904 STp->buffer->b_data, datalen,
2905 timeout, MAX_RETRIES);
2906 if (!ioctl_result)
2907 ioctl_result = (STp->buffer)->syscall_result;
Linus Torvalds1da177e2005-04-16 15:20:36 -07002908
2909 if (!ioctl_result) { /* SCSI command successful */
Mike Christie8b05b772005-11-08 04:06:44 -06002910 st_release_request(SRpnt);
Linus Torvalds1da177e2005-04-16 15:20:36 -07002911 SRpnt = NULL;
2912 STps->drv_block = blkno;
2913 STps->drv_file = fileno;
2914 STps->at_sm = at_sm;
2915
2916 if (cmd_in == MTBSFM)
2917 ioctl_result = st_int_ioctl(STp, MTFSF, 1);
2918 else if (cmd_in == MTFSFM)
2919 ioctl_result = st_int_ioctl(STp, MTBSF, 1);
2920
2921 if (cmd_in == MTSETBLK || cmd_in == SET_DENS_AND_BLK) {
2922 int old_block_size = STp->block_size;
2923 STp->block_size = arg & MT_ST_BLKSIZE_MASK;
2924 if (STp->block_size != 0) {
2925 if (old_block_size == 0)
2926 normalize_buffer(STp->buffer);
2927 (STp->buffer)->buffer_blocks =
2928 (STp->buffer)->buffer_size / STp->block_size;
2929 }
2930 (STp->buffer)->buffer_bytes = (STp->buffer)->read_pointer = 0;
2931 if (cmd_in == SET_DENS_AND_BLK)
2932 STp->density = arg >> MT_ST_DENSITY_SHIFT;
2933 } else if (cmd_in == MTSETDRVBUFFER)
2934 STp->drv_buffer = (arg & 7);
2935 else if (cmd_in == MTSETDENSITY)
2936 STp->density = arg;
2937
2938 if (cmd_in == MTEOM)
2939 STps->eof = ST_EOD;
2940 else if (cmd_in == MTFSF)
2941 STps->eof = ST_FM;
2942 else if (chg_eof)
2943 STps->eof = ST_NOEOF;
2944
2945 if (cmd_in == MTWEOF)
2946 STps->rw = ST_IDLE;
2947 } else { /* SCSI command was not completely successful. Don't return
2948 from this block without releasing the SCSI command block! */
2949 struct st_cmdstatus *cmdstatp = &STp->buffer->cmdstat;
2950
2951 if (cmdstatp->flags & SENSE_EOM) {
2952 if (cmd_in != MTBSF && cmd_in != MTBSFM &&
2953 cmd_in != MTBSR && cmd_in != MTBSS)
2954 STps->eof = ST_EOM_OK;
2955 STps->drv_block = 0;
2956 }
2957
2958 if (cmdstatp->remainder_valid)
2959 undone = (int)cmdstatp->uremainder64;
2960 else
2961 undone = 0;
2962
2963 if (cmd_in == MTWEOF &&
2964 cmdstatp->have_sense &&
Kai Makisara91614c02007-01-26 00:38:39 +02002965 (cmdstatp->flags & SENSE_EOM)) {
2966 if (cmdstatp->sense_hdr.sense_key == NO_SENSE ||
2967 cmdstatp->sense_hdr.sense_key == RECOVERED_ERROR) {
2968 ioctl_result = 0; /* EOF(s) written successfully at EOM */
2969 STps->eof = ST_NOEOF;
2970 } else { /* Writing EOF(s) failed */
2971 if (fileno >= 0)
2972 fileno -= undone;
2973 if (undone < arg)
2974 STps->eof = ST_NOEOF;
2975 }
Linus Torvalds1da177e2005-04-16 15:20:36 -07002976 STps->drv_file = fileno;
Linus Torvalds1da177e2005-04-16 15:20:36 -07002977 } else if ((cmd_in == MTFSF) || (cmd_in == MTFSFM)) {
2978 if (fileno >= 0)
2979 STps->drv_file = fileno - undone;
2980 else
2981 STps->drv_file = fileno;
2982 STps->drv_block = -1;
2983 STps->eof = ST_NOEOF;
2984 } else if ((cmd_in == MTBSF) || (cmd_in == MTBSFM)) {
2985 if (arg > 0 && undone < 0) /* Some drives get this wrong */
2986 undone = (-undone);
2987 if (STps->drv_file >= 0)
2988 STps->drv_file = fileno + undone;
2989 STps->drv_block = 0;
2990 STps->eof = ST_NOEOF;
2991 } else if (cmd_in == MTFSR) {
2992 if (cmdstatp->flags & SENSE_FMK) { /* Hit filemark */
2993 if (STps->drv_file >= 0)
2994 STps->drv_file++;
2995 STps->drv_block = 0;
2996 STps->eof = ST_FM;
2997 } else {
2998 if (blkno >= undone)
2999 STps->drv_block = blkno - undone;
3000 else
3001 STps->drv_block = (-1);
3002 STps->eof = ST_NOEOF;
3003 }
3004 } else if (cmd_in == MTBSR) {
3005 if (cmdstatp->flags & SENSE_FMK) { /* Hit filemark */
3006 STps->drv_file--;
3007 STps->drv_block = (-1);
3008 } else {
3009 if (arg > 0 && undone < 0) /* Some drives get this wrong */
3010 undone = (-undone);
3011 if (STps->drv_block >= 0)
3012 STps->drv_block = blkno + undone;
3013 }
3014 STps->eof = ST_NOEOF;
3015 } else if (cmd_in == MTEOM) {
3016 STps->drv_file = (-1);
3017 STps->drv_block = (-1);
3018 STps->eof = ST_EOD;
3019 } else if (cmd_in == MTSETBLK ||
3020 cmd_in == MTSETDENSITY ||
3021 cmd_in == MTSETDRVBUFFER ||
3022 cmd_in == SET_DENS_AND_BLK) {
3023 if (cmdstatp->sense_hdr.sense_key == ILLEGAL_REQUEST &&
3024 !(STp->use_pf & PF_TESTED)) {
3025 /* Try the other possible state of Page Format if not
3026 already tried */
3027 STp->use_pf = !STp->use_pf | PF_TESTED;
Mike Christie8b05b772005-11-08 04:06:44 -06003028 st_release_request(SRpnt);
Linus Torvalds1da177e2005-04-16 15:20:36 -07003029 SRpnt = NULL;
3030 return st_int_ioctl(STp, cmd_in, arg);
3031 }
3032 } else if (chg_eof)
3033 STps->eof = ST_NOEOF;
3034
3035 if (cmdstatp->sense_hdr.sense_key == BLANK_CHECK)
3036 STps->eof = ST_EOD;
3037
Mike Christie8b05b772005-11-08 04:06:44 -06003038 st_release_request(SRpnt);
Linus Torvalds1da177e2005-04-16 15:20:36 -07003039 SRpnt = NULL;
3040 }
3041
3042 return ioctl_result;
3043}
3044
3045
3046/* Get the tape position. If bt == 2, arg points into a kernel space mt_loc
3047 structure. */
3048
3049static int get_location(struct scsi_tape *STp, unsigned int *block, int *partition,
3050 int logical)
3051{
3052 int result;
3053 unsigned char scmd[MAX_COMMAND_SIZE];
Mike Christie8b05b772005-11-08 04:06:44 -06003054 struct st_request *SRpnt;
Linus Torvalds1da177e2005-04-16 15:20:36 -07003055 DEB( char *name = tape_name(STp); )
3056
3057 if (STp->ready != ST_READY)
3058 return (-EIO);
3059
3060 memset(scmd, 0, MAX_COMMAND_SIZE);
3061 if ((STp->device)->scsi_level < SCSI_2) {
3062 scmd[0] = QFA_REQUEST_BLOCK;
3063 scmd[4] = 3;
3064 } else {
3065 scmd[0] = READ_POSITION;
3066 if (!logical && !STp->scsi2_logical)
3067 scmd[1] = 1;
3068 }
FUJITA Tomonori7a31ec32008-12-05 15:25:30 +09003069
3070 SRpnt = st_allocate_request(STp);
Linus Torvalds1da177e2005-04-16 15:20:36 -07003071 if (!SRpnt)
FUJITA Tomonori7a31ec32008-12-05 15:25:30 +09003072 return STp->buffer->syscall_result;
3073
3074 result = st_scsi_kern_execute(SRpnt, scmd, DMA_FROM_DEVICE,
3075 STp->buffer->b_data, 20,
3076 STp->device->request_queue->rq_timeout,
3077 MAX_READY_RETRIES);
3078 if (result)
3079 goto out;
Linus Torvalds1da177e2005-04-16 15:20:36 -07003080
3081 if ((STp->buffer)->syscall_result != 0 ||
3082 (STp->device->scsi_level >= SCSI_2 &&
3083 ((STp->buffer)->b_data[0] & 4) != 0)) {
3084 *block = *partition = 0;
3085 DEBC(printk(ST_DEB_MSG "%s: Can't read tape position.\n", name));
3086 result = (-EIO);
3087 } else {
3088 result = 0;
3089 if ((STp->device)->scsi_level < SCSI_2) {
3090 *block = ((STp->buffer)->b_data[0] << 16)
3091 + ((STp->buffer)->b_data[1] << 8)
3092 + (STp->buffer)->b_data[2];
3093 *partition = 0;
3094 } else {
3095 *block = ((STp->buffer)->b_data[4] << 24)
3096 + ((STp->buffer)->b_data[5] << 16)
3097 + ((STp->buffer)->b_data[6] << 8)
3098 + (STp->buffer)->b_data[7];
3099 *partition = (STp->buffer)->b_data[1];
3100 if (((STp->buffer)->b_data[0] & 0x80) &&
3101 (STp->buffer)->b_data[1] == 0) /* BOP of partition 0 */
3102 STp->ps[0].drv_block = STp->ps[0].drv_file = 0;
3103 }
3104 DEBC(printk(ST_DEB_MSG "%s: Got tape pos. blk %d part %d.\n", name,
3105 *block, *partition));
3106 }
FUJITA Tomonori7a31ec32008-12-05 15:25:30 +09003107out:
Mike Christie8b05b772005-11-08 04:06:44 -06003108 st_release_request(SRpnt);
Linus Torvalds1da177e2005-04-16 15:20:36 -07003109 SRpnt = NULL;
3110
3111 return result;
3112}
3113
3114
3115/* Set the tape block and partition. Negative partition means that only the
3116 block should be set in vendor specific way. */
3117static int set_location(struct scsi_tape *STp, unsigned int block, int partition,
3118 int logical)
3119{
3120 struct st_partstat *STps;
3121 int result, p;
3122 unsigned int blk;
3123 int timeout;
3124 unsigned char scmd[MAX_COMMAND_SIZE];
Mike Christie8b05b772005-11-08 04:06:44 -06003125 struct st_request *SRpnt;
Linus Torvalds1da177e2005-04-16 15:20:36 -07003126 DEB( char *name = tape_name(STp); )
3127
3128 if (STp->ready != ST_READY)
3129 return (-EIO);
3130 timeout = STp->long_timeout;
3131 STps = &(STp->ps[STp->partition]);
3132
3133 DEBC(printk(ST_DEB_MSG "%s: Setting block to %d and partition to %d.\n",
3134 name, block, partition));
3135 DEB(if (partition < 0)
3136 return (-EIO); )
3137
3138 /* Update the location at the partition we are leaving */
3139 if ((!STp->can_partitions && partition != 0) ||
3140 partition >= ST_NBR_PARTITIONS)
3141 return (-EINVAL);
3142 if (partition != STp->partition) {
3143 if (get_location(STp, &blk, &p, 1))
3144 STps->last_block_valid = 0;
3145 else {
3146 STps->last_block_valid = 1;
3147 STps->last_block_visited = blk;
3148 DEBC(printk(ST_DEB_MSG
3149 "%s: Visited block %d for partition %d saved.\n",
3150 name, blk, STp->partition));
3151 }
3152 }
3153
3154 memset(scmd, 0, MAX_COMMAND_SIZE);
3155 if ((STp->device)->scsi_level < SCSI_2) {
3156 scmd[0] = QFA_SEEK_BLOCK;
3157 scmd[2] = (block >> 16);
3158 scmd[3] = (block >> 8);
3159 scmd[4] = block;
3160 scmd[5] = 0;
3161 } else {
3162 scmd[0] = SEEK_10;
3163 scmd[3] = (block >> 24);
3164 scmd[4] = (block >> 16);
3165 scmd[5] = (block >> 8);
3166 scmd[6] = block;
3167 if (!logical && !STp->scsi2_logical)
3168 scmd[1] = 4;
3169 if (STp->partition != partition) {
3170 scmd[1] |= 2;
3171 scmd[8] = partition;
3172 DEBC(printk(ST_DEB_MSG
3173 "%s: Trying to change partition from %d to %d\n",
3174 name, STp->partition, partition));
3175 }
3176 }
3177 if (STp->immediate) {
3178 scmd[1] |= 1; /* Don't wait for completion */
James Bottomleya02488e2008-11-30 10:36:26 -06003179 timeout = STp->device->request_queue->rq_timeout;
Linus Torvalds1da177e2005-04-16 15:20:36 -07003180 }
3181
FUJITA Tomonori3c0bf162008-12-05 15:25:23 +09003182 SRpnt = st_allocate_request(STp);
Linus Torvalds1da177e2005-04-16 15:20:36 -07003183 if (!SRpnt)
FUJITA Tomonori3c0bf162008-12-05 15:25:23 +09003184 return STp->buffer->syscall_result;
3185
3186 result = st_scsi_kern_execute(SRpnt, scmd, DMA_NONE, NULL, 0,
3187 timeout, MAX_READY_RETRIES);
3188 if (result)
3189 goto out;
Linus Torvalds1da177e2005-04-16 15:20:36 -07003190
3191 STps->drv_block = STps->drv_file = (-1);
3192 STps->eof = ST_NOEOF;
3193 if ((STp->buffer)->syscall_result != 0) {
3194 result = (-EIO);
3195 if (STp->can_partitions &&
3196 (STp->device)->scsi_level >= SCSI_2 &&
3197 (p = find_partition(STp)) >= 0)
3198 STp->partition = p;
3199 } else {
3200 if (STp->can_partitions) {
3201 STp->partition = partition;
3202 STps = &(STp->ps[partition]);
3203 if (!STps->last_block_valid ||
3204 STps->last_block_visited != block) {
3205 STps->at_sm = 0;
3206 STps->rw = ST_IDLE;
3207 }
3208 } else
3209 STps->at_sm = 0;
3210 if (block == 0)
3211 STps->drv_block = STps->drv_file = 0;
3212 result = 0;
3213 }
FUJITA Tomonori3c0bf162008-12-05 15:25:23 +09003214out:
Mike Christie8b05b772005-11-08 04:06:44 -06003215 st_release_request(SRpnt);
Linus Torvalds1da177e2005-04-16 15:20:36 -07003216 SRpnt = NULL;
3217
3218 return result;
3219}
3220
3221
3222/* Find the current partition number for the drive status. Called from open and
3223 returns either partition number of negative error code. */
3224static int find_partition(struct scsi_tape *STp)
3225{
3226 int i, partition;
3227 unsigned int block;
3228
3229 if ((i = get_location(STp, &block, &partition, 1)) < 0)
3230 return i;
3231 if (partition >= ST_NBR_PARTITIONS)
3232 return (-EIO);
3233 return partition;
3234}
3235
3236
3237/* Change the partition if necessary */
3238static int switch_partition(struct scsi_tape *STp)
3239{
3240 struct st_partstat *STps;
3241
3242 if (STp->partition == STp->new_partition)
3243 return 0;
3244 STps = &(STp->ps[STp->new_partition]);
3245 if (!STps->last_block_valid)
3246 STps->last_block_visited = 0;
3247 return set_location(STp, STps->last_block_visited, STp->new_partition, 1);
3248}
3249
3250/* Functions for reading and writing the medium partition mode page. */
3251
3252#define PART_PAGE 0x11
3253#define PART_PAGE_FIXED_LENGTH 8
3254
3255#define PP_OFF_MAX_ADD_PARTS 2
3256#define PP_OFF_NBR_ADD_PARTS 3
3257#define PP_OFF_FLAGS 4
3258#define PP_OFF_PART_UNITS 6
3259#define PP_OFF_RESERVED 7
3260
3261#define PP_BIT_IDP 0x20
3262#define PP_MSK_PSUM_MB 0x10
3263
3264/* Get the number of partitions on the tape. As a side effect reads the
3265 mode page into the tape buffer. */
3266static int nbr_partitions(struct scsi_tape *STp)
3267{
3268 int result;
3269 DEB( char *name = tape_name(STp); )
3270
3271 if (STp->ready != ST_READY)
3272 return (-EIO);
3273
3274 result = read_mode_page(STp, PART_PAGE, 1);
3275
3276 if (result) {
3277 DEBC(printk(ST_DEB_MSG "%s: Can't read medium partition page.\n",
3278 name));
3279 result = (-EIO);
3280 } else {
3281 result = (STp->buffer)->b_data[MODE_HEADER_LENGTH +
3282 PP_OFF_NBR_ADD_PARTS] + 1;
3283 DEBC(printk(ST_DEB_MSG "%s: Number of partitions %d.\n", name, result));
3284 }
3285
3286 return result;
3287}
3288
3289
3290/* Partition the tape into two partitions if size > 0 or one partition if
3291 size == 0.
3292
3293 The block descriptors are read and written because Sony SDT-7000 does not
3294 work without this (suggestion from Michael Schaefer <Michael.Schaefer@dlr.de>).
3295
3296 My HP C1533A drive returns only one partition size field. This is used to
3297 set the size of partition 1. There is no size field for the default partition.
3298 Michael Schaefer's Sony SDT-7000 returns two descriptors and the second is
3299 used to set the size of partition 1 (this is what the SCSI-3 standard specifies).
3300 The following algorithm is used to accommodate both drives: if the number of
3301 partition size fields is greater than the maximum number of additional partitions
3302 in the mode page, the second field is used. Otherwise the first field is used.
3303
3304 For Seagate DDS drives the page length must be 8 when no partitions is defined
3305 and 10 when 1 partition is defined (information from Eric Lee Green). This is
3306 is acceptable also to some other old drives and enforced if the first partition
3307 size field is used for the first additional partition size.
3308 */
3309static int partition_tape(struct scsi_tape *STp, int size)
3310{
3311 char *name = tape_name(STp);
3312 int result;
3313 int pgo, psd_cnt, psdo;
3314 unsigned char *bp;
3315
3316 result = read_mode_page(STp, PART_PAGE, 0);
3317 if (result) {
3318 DEBC(printk(ST_DEB_MSG "%s: Can't read partition mode page.\n", name));
3319 return result;
3320 }
3321 /* The mode page is in the buffer. Let's modify it and write it. */
3322 bp = (STp->buffer)->b_data;
3323 pgo = MODE_HEADER_LENGTH + bp[MH_OFF_BDESCS_LENGTH];
3324 DEBC(printk(ST_DEB_MSG "%s: Partition page length is %d bytes.\n",
3325 name, bp[pgo + MP_OFF_PAGE_LENGTH] + 2));
3326
3327 psd_cnt = (bp[pgo + MP_OFF_PAGE_LENGTH] + 2 - PART_PAGE_FIXED_LENGTH) / 2;
3328 psdo = pgo + PART_PAGE_FIXED_LENGTH;
3329 if (psd_cnt > bp[pgo + PP_OFF_MAX_ADD_PARTS]) {
3330 bp[psdo] = bp[psdo + 1] = 0xff; /* Rest of the tape */
3331 psdo += 2;
3332 }
3333 memset(bp + psdo, 0, bp[pgo + PP_OFF_NBR_ADD_PARTS] * 2);
3334
3335 DEBC(printk("%s: psd_cnt %d, max.parts %d, nbr_parts %d\n", name,
3336 psd_cnt, bp[pgo + PP_OFF_MAX_ADD_PARTS],
3337 bp[pgo + PP_OFF_NBR_ADD_PARTS]));
3338
3339 if (size <= 0) {
3340 bp[pgo + PP_OFF_NBR_ADD_PARTS] = 0;
3341 if (psd_cnt <= bp[pgo + PP_OFF_MAX_ADD_PARTS])
3342 bp[pgo + MP_OFF_PAGE_LENGTH] = 6;
3343 DEBC(printk(ST_DEB_MSG "%s: Formatting tape with one partition.\n",
3344 name));
3345 } else {
3346 bp[psdo] = (size >> 8) & 0xff;
3347 bp[psdo + 1] = size & 0xff;
3348 bp[pgo + 3] = 1;
3349 if (bp[pgo + MP_OFF_PAGE_LENGTH] < 8)
3350 bp[pgo + MP_OFF_PAGE_LENGTH] = 8;
3351 DEBC(printk(ST_DEB_MSG
3352 "%s: Formatting tape with two partitions (1 = %d MB).\n",
3353 name, size));
3354 }
3355 bp[pgo + PP_OFF_PART_UNITS] = 0;
3356 bp[pgo + PP_OFF_RESERVED] = 0;
3357 bp[pgo + PP_OFF_FLAGS] = PP_BIT_IDP | PP_MSK_PSUM_MB;
3358
3359 result = write_mode_page(STp, PART_PAGE, 1);
3360 if (result) {
3361 printk(KERN_INFO "%s: Partitioning of tape failed.\n", name);
3362 result = (-EIO);
3363 }
3364
3365 return result;
3366}
3367
3368
3369
3370/* The ioctl command */
Kai Makisarafd66c1b2008-01-17 22:45:22 +02003371static long st_ioctl(struct file *file, unsigned int cmd_in, unsigned long arg)
Linus Torvalds1da177e2005-04-16 15:20:36 -07003372{
3373 int i, cmd_nr, cmd_type, bt;
3374 int retval = 0;
3375 unsigned int blk;
3376 struct scsi_tape *STp = file->private_data;
3377 struct st_modedef *STm;
3378 struct st_partstat *STps;
3379 char *name = tape_name(STp);
3380 void __user *p = (void __user *)arg;
3381
Matthias Kaehlcke28f85002007-07-29 23:38:15 +02003382 if (mutex_lock_interruptible(&STp->lock))
Linus Torvalds1da177e2005-04-16 15:20:36 -07003383 return -ERESTARTSYS;
3384
3385 DEB(
3386 if (debugging && !STp->in_use) {
3387 printk(ST_DEB_MSG "%s: Incorrect device.\n", name);
3388 retval = (-EIO);
3389 goto out;
3390 } ) /* end DEB */
3391
3392 STm = &(STp->modes[STp->current_mode]);
3393 STps = &(STp->ps[STp->partition]);
3394
3395 /*
3396 * If we are in the middle of error recovery, don't let anyone
3397 * else try and use this device. Also, if error recovery fails, it
3398 * may try and take the device offline, in which case all further
3399 * access to the device is prohibited.
3400 */
Al Viro83ff6fe2008-03-02 08:15:49 -05003401 retval = scsi_nonblockable_ioctl(STp->device, cmd_in, p,
3402 file->f_flags & O_NDELAY);
Linus Torvalds1da177e2005-04-16 15:20:36 -07003403 if (!scsi_block_when_processing_errors(STp->device) || retval != -ENODEV)
3404 goto out;
3405 retval = 0;
3406
3407 cmd_type = _IOC_TYPE(cmd_in);
3408 cmd_nr = _IOC_NR(cmd_in);
3409
3410 if (cmd_type == _IOC_TYPE(MTIOCTOP) && cmd_nr == _IOC_NR(MTIOCTOP)) {
3411 struct mtop mtc;
3412
3413 if (_IOC_SIZE(cmd_in) != sizeof(mtc)) {
3414 retval = (-EINVAL);
3415 goto out;
3416 }
3417
3418 i = copy_from_user(&mtc, p, sizeof(struct mtop));
3419 if (i) {
3420 retval = (-EFAULT);
3421 goto out;
3422 }
3423
3424 if (mtc.mt_op == MTSETDRVBUFFER && !capable(CAP_SYS_ADMIN)) {
3425 printk(KERN_WARNING
3426 "%s: MTSETDRVBUFFER only allowed for root.\n", name);
3427 retval = (-EPERM);
3428 goto out;
3429 }
3430 if (!STm->defined &&
3431 (mtc.mt_op != MTSETDRVBUFFER &&
3432 (mtc.mt_count & MT_ST_OPTIONS) == 0)) {
3433 retval = (-ENXIO);
3434 goto out;
3435 }
3436
3437 if (!STp->pos_unknown) {
3438
3439 if (STps->eof == ST_FM_HIT) {
3440 if (mtc.mt_op == MTFSF || mtc.mt_op == MTFSFM ||
3441 mtc.mt_op == MTEOM) {
3442 mtc.mt_count -= 1;
3443 if (STps->drv_file >= 0)
3444 STps->drv_file += 1;
3445 } else if (mtc.mt_op == MTBSF || mtc.mt_op == MTBSFM) {
3446 mtc.mt_count += 1;
3447 if (STps->drv_file >= 0)
3448 STps->drv_file += 1;
3449 }
3450 }
3451
3452 if (mtc.mt_op == MTSEEK) {
3453 /* Old position must be restored if partition will be
3454 changed */
3455 i = !STp->can_partitions ||
3456 (STp->new_partition != STp->partition);
3457 } else {
3458 i = mtc.mt_op == MTREW || mtc.mt_op == MTOFFL ||
3459 mtc.mt_op == MTRETEN || mtc.mt_op == MTEOM ||
3460 mtc.mt_op == MTLOCK || mtc.mt_op == MTLOAD ||
3461 mtc.mt_op == MTFSF || mtc.mt_op == MTFSFM ||
3462 mtc.mt_op == MTBSF || mtc.mt_op == MTBSFM ||
3463 mtc.mt_op == MTCOMPRESSION;
3464 }
3465 i = flush_buffer(STp, i);
3466 if (i < 0) {
3467 retval = i;
3468 goto out;
3469 }
3470 if (STps->rw == ST_WRITING &&
3471 (mtc.mt_op == MTREW || mtc.mt_op == MTOFFL ||
3472 mtc.mt_op == MTSEEK ||
3473 mtc.mt_op == MTBSF || mtc.mt_op == MTBSFM)) {
3474 i = st_int_ioctl(STp, MTWEOF, 1);
3475 if (i < 0) {
3476 retval = i;
3477 goto out;
3478 }
3479 if (mtc.mt_op == MTBSF || mtc.mt_op == MTBSFM)
3480 mtc.mt_count++;
3481 STps->rw = ST_IDLE;
3482 }
3483
3484 } else {
3485 /*
3486 * If there was a bus reset, block further access
3487 * to this device. If the user wants to rewind the tape,
3488 * then reset the flag and allow access again.
3489 */
3490 if (mtc.mt_op != MTREW &&
3491 mtc.mt_op != MTOFFL &&
3492 mtc.mt_op != MTRETEN &&
3493 mtc.mt_op != MTERASE &&
3494 mtc.mt_op != MTSEEK &&
3495 mtc.mt_op != MTEOM) {
3496 retval = (-EIO);
3497 goto out;
3498 }
3499 reset_state(STp);
3500 /* remove this when the midlevel properly clears was_reset */
3501 STp->device->was_reset = 0;
3502 }
3503
3504 if (mtc.mt_op != MTNOP && mtc.mt_op != MTSETBLK &&
3505 mtc.mt_op != MTSETDENSITY && mtc.mt_op != MTWSM &&
3506 mtc.mt_op != MTSETDRVBUFFER && mtc.mt_op != MTSETPART)
3507 STps->rw = ST_IDLE; /* Prevent automatic WEOF and fsf */
3508
3509 if (mtc.mt_op == MTOFFL && STp->door_locked != ST_UNLOCKED)
3510 do_door_lock(STp, 0); /* Ignore result! */
3511
3512 if (mtc.mt_op == MTSETDRVBUFFER &&
3513 (mtc.mt_count & MT_ST_OPTIONS) != 0) {
3514 retval = st_set_options(STp, mtc.mt_count);
3515 goto out;
3516 }
3517
3518 if (mtc.mt_op == MTSETPART) {
3519 if (!STp->can_partitions ||
3520 mtc.mt_count < 0 || mtc.mt_count >= ST_NBR_PARTITIONS) {
3521 retval = (-EINVAL);
3522 goto out;
3523 }
3524 if (mtc.mt_count >= STp->nbr_partitions &&
3525 (STp->nbr_partitions = nbr_partitions(STp)) < 0) {
3526 retval = (-EIO);
3527 goto out;
3528 }
3529 if (mtc.mt_count >= STp->nbr_partitions) {
3530 retval = (-EINVAL);
3531 goto out;
3532 }
3533 STp->new_partition = mtc.mt_count;
3534 retval = 0;
3535 goto out;
3536 }
3537
3538 if (mtc.mt_op == MTMKPART) {
3539 if (!STp->can_partitions) {
3540 retval = (-EINVAL);
3541 goto out;
3542 }
3543 if ((i = st_int_ioctl(STp, MTREW, 0)) < 0 ||
3544 (i = partition_tape(STp, mtc.mt_count)) < 0) {
3545 retval = i;
3546 goto out;
3547 }
3548 for (i = 0; i < ST_NBR_PARTITIONS; i++) {
3549 STp->ps[i].rw = ST_IDLE;
3550 STp->ps[i].at_sm = 0;
3551 STp->ps[i].last_block_valid = 0;
3552 }
3553 STp->partition = STp->new_partition = 0;
3554 STp->nbr_partitions = 1; /* Bad guess ?-) */
3555 STps->drv_block = STps->drv_file = 0;
3556 retval = 0;
3557 goto out;
3558 }
3559
3560 if (mtc.mt_op == MTSEEK) {
3561 i = set_location(STp, mtc.mt_count, STp->new_partition, 0);
3562 if (!STp->can_partitions)
3563 STp->ps[0].rw = ST_IDLE;
3564 retval = i;
3565 goto out;
3566 }
3567
3568 if (mtc.mt_op == MTUNLOAD || mtc.mt_op == MTOFFL) {
3569 retval = do_load_unload(STp, file, 0);
3570 goto out;
3571 }
3572
3573 if (mtc.mt_op == MTLOAD) {
3574 retval = do_load_unload(STp, file, max(1, mtc.mt_count));
3575 goto out;
3576 }
3577
3578 if (mtc.mt_op == MTLOCK || mtc.mt_op == MTUNLOCK) {
3579 retval = do_door_lock(STp, (mtc.mt_op == MTLOCK));
3580 goto out;
3581 }
3582
3583 if (STp->can_partitions && STp->ready == ST_READY &&
3584 (i = switch_partition(STp)) < 0) {
3585 retval = i;
3586 goto out;
3587 }
3588
3589 if (mtc.mt_op == MTCOMPRESSION)
3590 retval = st_compression(STp, (mtc.mt_count & 1));
3591 else
3592 retval = st_int_ioctl(STp, mtc.mt_op, mtc.mt_count);
3593 goto out;
3594 }
3595 if (!STm->defined) {
3596 retval = (-ENXIO);
3597 goto out;
3598 }
3599
3600 if ((i = flush_buffer(STp, 0)) < 0) {
3601 retval = i;
3602 goto out;
3603 }
3604 if (STp->can_partitions &&
3605 (i = switch_partition(STp)) < 0) {
3606 retval = i;
3607 goto out;
3608 }
3609
3610 if (cmd_type == _IOC_TYPE(MTIOCGET) && cmd_nr == _IOC_NR(MTIOCGET)) {
3611 struct mtget mt_status;
3612
3613 if (_IOC_SIZE(cmd_in) != sizeof(struct mtget)) {
3614 retval = (-EINVAL);
3615 goto out;
3616 }
3617
3618 mt_status.mt_type = STp->tape_type;
3619 mt_status.mt_dsreg =
3620 ((STp->block_size << MT_ST_BLKSIZE_SHIFT) & MT_ST_BLKSIZE_MASK) |
3621 ((STp->density << MT_ST_DENSITY_SHIFT) & MT_ST_DENSITY_MASK);
3622 mt_status.mt_blkno = STps->drv_block;
3623 mt_status.mt_fileno = STps->drv_file;
3624 if (STp->block_size != 0) {
3625 if (STps->rw == ST_WRITING)
3626 mt_status.mt_blkno +=
3627 (STp->buffer)->buffer_bytes / STp->block_size;
3628 else if (STps->rw == ST_READING)
3629 mt_status.mt_blkno -=
3630 ((STp->buffer)->buffer_bytes +
3631 STp->block_size - 1) / STp->block_size;
3632 }
3633
3634 mt_status.mt_gstat = 0;
3635 if (STp->drv_write_prot)
3636 mt_status.mt_gstat |= GMT_WR_PROT(0xffffffff);
3637 if (mt_status.mt_blkno == 0) {
3638 if (mt_status.mt_fileno == 0)
3639 mt_status.mt_gstat |= GMT_BOT(0xffffffff);
3640 else
3641 mt_status.mt_gstat |= GMT_EOF(0xffffffff);
3642 }
3643 mt_status.mt_erreg = (STp->recover_reg << MT_ST_SOFTERR_SHIFT);
3644 mt_status.mt_resid = STp->partition;
3645 if (STps->eof == ST_EOM_OK || STps->eof == ST_EOM_ERROR)
3646 mt_status.mt_gstat |= GMT_EOT(0xffffffff);
3647 else if (STps->eof >= ST_EOM_OK)
3648 mt_status.mt_gstat |= GMT_EOD(0xffffffff);
3649 if (STp->density == 1)
3650 mt_status.mt_gstat |= GMT_D_800(0xffffffff);
3651 else if (STp->density == 2)
3652 mt_status.mt_gstat |= GMT_D_1600(0xffffffff);
3653 else if (STp->density == 3)
3654 mt_status.mt_gstat |= GMT_D_6250(0xffffffff);
3655 if (STp->ready == ST_READY)
3656 mt_status.mt_gstat |= GMT_ONLINE(0xffffffff);
3657 if (STp->ready == ST_NO_TAPE)
3658 mt_status.mt_gstat |= GMT_DR_OPEN(0xffffffff);
3659 if (STps->at_sm)
3660 mt_status.mt_gstat |= GMT_SM(0xffffffff);
3661 if (STm->do_async_writes ||
3662 (STm->do_buffer_writes && STp->block_size != 0) ||
3663 STp->drv_buffer != 0)
3664 mt_status.mt_gstat |= GMT_IM_REP_EN(0xffffffff);
3665 if (STp->cleaning_req)
3666 mt_status.mt_gstat |= GMT_CLN(0xffffffff);
3667
3668 i = copy_to_user(p, &mt_status, sizeof(struct mtget));
3669 if (i) {
3670 retval = (-EFAULT);
3671 goto out;
3672 }
3673
3674 STp->recover_reg = 0; /* Clear after read */
3675 retval = 0;
3676 goto out;
3677 } /* End of MTIOCGET */
3678 if (cmd_type == _IOC_TYPE(MTIOCPOS) && cmd_nr == _IOC_NR(MTIOCPOS)) {
3679 struct mtpos mt_pos;
3680 if (_IOC_SIZE(cmd_in) != sizeof(struct mtpos)) {
3681 retval = (-EINVAL);
3682 goto out;
3683 }
3684 if ((i = get_location(STp, &blk, &bt, 0)) < 0) {
3685 retval = i;
3686 goto out;
3687 }
3688 mt_pos.mt_blkno = blk;
3689 i = copy_to_user(p, &mt_pos, sizeof(struct mtpos));
3690 if (i)
3691 retval = (-EFAULT);
3692 goto out;
3693 }
Matthias Kaehlcke28f85002007-07-29 23:38:15 +02003694 mutex_unlock(&STp->lock);
Linus Torvalds1da177e2005-04-16 15:20:36 -07003695 switch (cmd_in) {
3696 case SCSI_IOCTL_GET_IDLUN:
3697 case SCSI_IOCTL_GET_BUS_NUMBER:
3698 break;
3699 default:
Kai Makisara 16c4b3e2005-05-01 18:11:55 +03003700 if ((cmd_in == SG_IO ||
3701 cmd_in == SCSI_IOCTL_SEND_COMMAND ||
3702 cmd_in == CDROM_SEND_PACKET) &&
3703 !capable(CAP_SYS_RAWIO))
Linus Torvalds1da177e2005-04-16 15:20:36 -07003704 i = -EPERM;
3705 else
Al Viro74f3c8a2007-08-27 15:38:10 -04003706 i = scsi_cmd_ioctl(STp->disk->queue, STp->disk,
3707 file->f_mode, cmd_in, p);
Linus Torvalds1da177e2005-04-16 15:20:36 -07003708 if (i != -ENOTTY)
3709 return i;
3710 break;
3711 }
Kai Makisara 16c4b3e2005-05-01 18:11:55 +03003712 retval = scsi_ioctl(STp->device, cmd_in, p);
3713 if (!retval && cmd_in == SCSI_IOCTL_STOP_UNIT) { /* unload */
3714 STp->rew_at_close = 0;
3715 STp->ready = ST_NO_TAPE;
3716 }
3717 return retval;
Linus Torvalds1da177e2005-04-16 15:20:36 -07003718
3719 out:
Matthias Kaehlcke28f85002007-07-29 23:38:15 +02003720 mutex_unlock(&STp->lock);
Linus Torvalds1da177e2005-04-16 15:20:36 -07003721 return retval;
3722}
3723
3724#ifdef CONFIG_COMPAT
3725static long st_compat_ioctl(struct file *file, unsigned int cmd, unsigned long arg)
3726{
3727 struct scsi_tape *STp = file->private_data;
3728 struct scsi_device *sdev = STp->device;
3729 int ret = -ENOIOCTLCMD;
3730 if (sdev->host->hostt->compat_ioctl) {
3731
3732 ret = sdev->host->hostt->compat_ioctl(sdev, cmd, (void __user *)arg);
3733
3734 }
3735 return ret;
3736}
3737#endif
3738
3739
3740
3741/* Try to allocate a new tape buffer. Calling function must not hold
3742 dev_arr_lock. */
FUJITA Tomonorif409d6c2008-12-18 14:49:47 +09003743static struct st_buffer *new_tape_buffer(int need_dma, int max_sg)
Linus Torvalds1da177e2005-04-16 15:20:36 -07003744{
Linus Torvalds1da177e2005-04-16 15:20:36 -07003745 struct st_buffer *tb;
3746
FUJITA Tomonorif409d6c2008-12-18 14:49:47 +09003747 tb = kzalloc(sizeof(struct st_buffer), GFP_ATOMIC);
Linus Torvalds1da177e2005-04-16 15:20:36 -07003748 if (!tb) {
3749 printk(KERN_NOTICE "st: Can't allocate new tape buffer.\n");
3750 return NULL;
3751 }
FUJITA Tomonori1ac63cf2008-12-18 14:49:48 +09003752 tb->frp_segs = 0;
Linus Torvalds1da177e2005-04-16 15:20:36 -07003753 tb->use_sg = max_sg;
Linus Torvalds1da177e2005-04-16 15:20:36 -07003754 tb->dma = need_dma;
FUJITA Tomonorif409d6c2008-12-18 14:49:47 +09003755 tb->buffer_size = 0;
Linus Torvalds1da177e2005-04-16 15:20:36 -07003756
FUJITA Tomonorif409d6c2008-12-18 14:49:47 +09003757 tb->reserved_pages = kzalloc(max_sg * sizeof(struct page *),
3758 GFP_ATOMIC);
FUJITA Tomonorid0e1ae32008-12-18 14:49:40 +09003759 if (!tb->reserved_pages) {
3760 kfree(tb);
3761 return NULL;
3762 }
3763
Linus Torvalds1da177e2005-04-16 15:20:36 -07003764 return tb;
3765}
3766
3767
3768/* Try to allocate enough space in the tape buffer */
3769static int enlarge_buffer(struct st_buffer * STbuffer, int new_size, int need_dma)
3770{
Al Viroc53033f2005-10-21 03:22:08 -04003771 int segs, nbr, max_segs, b_size, order, got;
3772 gfp_t priority;
Linus Torvalds1da177e2005-04-16 15:20:36 -07003773
3774 if (new_size <= STbuffer->buffer_size)
3775 return 1;
3776
3777 if (STbuffer->buffer_size <= PAGE_SIZE)
3778 normalize_buffer(STbuffer); /* Avoid extra segment */
3779
3780 max_segs = STbuffer->use_sg;
3781 nbr = max_segs - STbuffer->frp_segs;
3782 if (nbr <= 0)
3783 return 0;
3784
3785 priority = GFP_KERNEL | __GFP_NOWARN;
3786 if (need_dma)
3787 priority |= GFP_DMA;
FUJITA Tomonori9c905962008-12-18 14:49:39 +09003788
FUJITA Tomonori08c95832008-12-18 14:49:45 +09003789 if (STbuffer->cleared)
3790 priority |= __GFP_ZERO;
3791
FUJITA Tomonori9c905962008-12-18 14:49:39 +09003792 if (STbuffer->frp_segs) {
FUJITA Tomonori08c95832008-12-18 14:49:45 +09003793 order = STbuffer->map_data.page_order;
3794 b_size = PAGE_SIZE << order;
FUJITA Tomonori9c905962008-12-18 14:49:39 +09003795 } else {
3796 for (b_size = PAGE_SIZE, order = 0;
3797 order <= 6 && b_size < new_size; order++, b_size *= 2)
3798 ; /* empty */
3799 }
Linus Torvalds1da177e2005-04-16 15:20:36 -07003800
3801 for (segs = STbuffer->frp_segs, got = STbuffer->buffer_size;
3802 segs < max_segs && got < new_size;) {
FUJITA Tomonori08c95832008-12-18 14:49:45 +09003803 struct page *page;
3804
3805 page = alloc_pages(priority, order);
3806 if (!page) {
Linus Torvalds1da177e2005-04-16 15:20:36 -07003807 DEB(STbuffer->buffer_size = got);
3808 normalize_buffer(STbuffer);
3809 return 0;
3810 }
FUJITA Tomonori08c95832008-12-18 14:49:45 +09003811
Linus Torvalds1da177e2005-04-16 15:20:36 -07003812 STbuffer->frp_segs += 1;
3813 got += b_size;
3814 STbuffer->buffer_size = got;
FUJITA Tomonori08c95832008-12-18 14:49:45 +09003815 STbuffer->reserved_pages[segs] = page;
Linus Torvalds1da177e2005-04-16 15:20:36 -07003816 segs++;
3817 }
FUJITA Tomonori08c95832008-12-18 14:49:45 +09003818 STbuffer->b_data = page_address(STbuffer->reserved_pages[0]);
FUJITA Tomonorid0e1ae32008-12-18 14:49:40 +09003819 STbuffer->map_data.page_order = order;
Linus Torvalds1da177e2005-04-16 15:20:36 -07003820
3821 return 1;
3822}
3823
3824
Kai Makisara40f6b362008-02-24 22:23:24 +02003825/* Make sure that no data from previous user is in the internal buffer */
3826static void clear_buffer(struct st_buffer * st_bp)
3827{
3828 int i;
3829
3830 for (i=0; i < st_bp->frp_segs; i++)
FUJITA Tomonori08c95832008-12-18 14:49:45 +09003831 memset(page_address(st_bp->reserved_pages[i]), 0,
3832 PAGE_SIZE << st_bp->map_data.page_order);
Kai Makisara40f6b362008-02-24 22:23:24 +02003833 st_bp->cleared = 1;
3834}
3835
3836
Linus Torvalds1da177e2005-04-16 15:20:36 -07003837/* Release the extra buffer */
3838static void normalize_buffer(struct st_buffer * STbuffer)
3839{
FUJITA Tomonori08c95832008-12-18 14:49:45 +09003840 int i, order = STbuffer->map_data.page_order;
Linus Torvalds1da177e2005-04-16 15:20:36 -07003841
FUJITA Tomonori1ac63cf2008-12-18 14:49:48 +09003842 for (i = 0; i < STbuffer->frp_segs; i++) {
FUJITA Tomonori08c95832008-12-18 14:49:45 +09003843 __free_pages(STbuffer->reserved_pages[i], order);
3844 STbuffer->buffer_size -= (PAGE_SIZE << order);
Linus Torvalds1da177e2005-04-16 15:20:36 -07003845 }
FUJITA Tomonori1ac63cf2008-12-18 14:49:48 +09003846 STbuffer->frp_segs = 0;
Linus Torvalds1da177e2005-04-16 15:20:36 -07003847 STbuffer->frp_sg_current = 0;
Mike Christie8b05b772005-11-08 04:06:44 -06003848 STbuffer->sg_segs = 0;
FUJITA Tomonorid0e1ae32008-12-18 14:49:40 +09003849 STbuffer->map_data.page_order = 0;
3850 STbuffer->map_data.offset = 0;
Linus Torvalds1da177e2005-04-16 15:20:36 -07003851}
3852
3853
3854/* Move data from the user buffer to the tape buffer. Returns zero (success) or
3855 negative error code. */
3856static int append_to_buffer(const char __user *ubp, struct st_buffer * st_bp, int do_count)
3857{
3858 int i, cnt, res, offset;
FUJITA Tomonori08c95832008-12-18 14:49:45 +09003859 int length = PAGE_SIZE << st_bp->map_data.page_order;
Linus Torvalds1da177e2005-04-16 15:20:36 -07003860
3861 for (i = 0, offset = st_bp->buffer_bytes;
FUJITA Tomonori08c95832008-12-18 14:49:45 +09003862 i < st_bp->frp_segs && offset >= length; i++)
3863 offset -= length;
Linus Torvalds1da177e2005-04-16 15:20:36 -07003864 if (i == st_bp->frp_segs) { /* Should never happen */
3865 printk(KERN_WARNING "st: append_to_buffer offset overflow.\n");
3866 return (-EIO);
3867 }
3868 for (; i < st_bp->frp_segs && do_count > 0; i++) {
FUJITA Tomonori08c95832008-12-18 14:49:45 +09003869 struct page *page = st_bp->reserved_pages[i];
3870 cnt = length - offset < do_count ? length - offset : do_count;
3871 res = copy_from_user(page_address(page) + offset, ubp, cnt);
Linus Torvalds1da177e2005-04-16 15:20:36 -07003872 if (res)
3873 return (-EFAULT);
3874 do_count -= cnt;
3875 st_bp->buffer_bytes += cnt;
3876 ubp += cnt;
3877 offset = 0;
3878 }
3879 if (do_count) /* Should never happen */
3880 return (-EIO);
3881
3882 return 0;
3883}
3884
3885
3886/* Move data from the tape buffer to the user buffer. Returns zero (success) or
3887 negative error code. */
3888static int from_buffer(struct st_buffer * st_bp, char __user *ubp, int do_count)
3889{
3890 int i, cnt, res, offset;
FUJITA Tomonori08c95832008-12-18 14:49:45 +09003891 int length = PAGE_SIZE << st_bp->map_data.page_order;
Linus Torvalds1da177e2005-04-16 15:20:36 -07003892
3893 for (i = 0, offset = st_bp->read_pointer;
FUJITA Tomonori08c95832008-12-18 14:49:45 +09003894 i < st_bp->frp_segs && offset >= length; i++)
3895 offset -= length;
Linus Torvalds1da177e2005-04-16 15:20:36 -07003896 if (i == st_bp->frp_segs) { /* Should never happen */
3897 printk(KERN_WARNING "st: from_buffer offset overflow.\n");
3898 return (-EIO);
3899 }
3900 for (; i < st_bp->frp_segs && do_count > 0; i++) {
FUJITA Tomonori08c95832008-12-18 14:49:45 +09003901 struct page *page = st_bp->reserved_pages[i];
3902 cnt = length - offset < do_count ? length - offset : do_count;
3903 res = copy_to_user(ubp, page_address(page) + offset, cnt);
Linus Torvalds1da177e2005-04-16 15:20:36 -07003904 if (res)
3905 return (-EFAULT);
3906 do_count -= cnt;
3907 st_bp->buffer_bytes -= cnt;
3908 st_bp->read_pointer += cnt;
3909 ubp += cnt;
3910 offset = 0;
3911 }
3912 if (do_count) /* Should never happen */
3913 return (-EIO);
3914
3915 return 0;
3916}
3917
3918
3919/* Move data towards start of buffer */
3920static void move_buffer_data(struct st_buffer * st_bp, int offset)
3921{
3922 int src_seg, dst_seg, src_offset = 0, dst_offset;
3923 int count, total;
FUJITA Tomonori08c95832008-12-18 14:49:45 +09003924 int length = PAGE_SIZE << st_bp->map_data.page_order;
Linus Torvalds1da177e2005-04-16 15:20:36 -07003925
3926 if (offset == 0)
3927 return;
3928
3929 total=st_bp->buffer_bytes - offset;
3930 for (src_seg=0; src_seg < st_bp->frp_segs; src_seg++) {
3931 src_offset = offset;
FUJITA Tomonori08c95832008-12-18 14:49:45 +09003932 if (src_offset < length)
Linus Torvalds1da177e2005-04-16 15:20:36 -07003933 break;
FUJITA Tomonori08c95832008-12-18 14:49:45 +09003934 offset -= length;
Linus Torvalds1da177e2005-04-16 15:20:36 -07003935 }
3936
3937 st_bp->buffer_bytes = st_bp->read_pointer = total;
3938 for (dst_seg=dst_offset=0; total > 0; ) {
FUJITA Tomonori08c95832008-12-18 14:49:45 +09003939 struct page *dpage = st_bp->reserved_pages[dst_seg];
3940 struct page *spage = st_bp->reserved_pages[src_seg];
3941
3942 count = min(length - dst_offset, length - src_offset);
3943 memmove(page_address(dpage) + dst_offset,
3944 page_address(spage) + src_offset, count);
Linus Torvalds1da177e2005-04-16 15:20:36 -07003945 src_offset += count;
FUJITA Tomonori08c95832008-12-18 14:49:45 +09003946 if (src_offset >= length) {
Linus Torvalds1da177e2005-04-16 15:20:36 -07003947 src_seg++;
3948 src_offset = 0;
3949 }
3950 dst_offset += count;
FUJITA Tomonori08c95832008-12-18 14:49:45 +09003951 if (dst_offset >= length) {
Linus Torvalds1da177e2005-04-16 15:20:36 -07003952 dst_seg++;
3953 dst_offset = 0;
3954 }
3955 total -= count;
3956 }
3957}
3958
Linus Torvalds1da177e2005-04-16 15:20:36 -07003959/* Validate the options from command line or module parameters */
3960static void validate_options(void)
3961{
3962 if (buffer_kbs > 0)
3963 st_fixed_buffer_size = buffer_kbs * ST_KILOBYTE;
3964 if (max_sg_segs >= ST_FIRST_SG)
3965 st_max_sg_segs = max_sg_segs;
3966}
3967
3968#ifndef MODULE
3969/* Set the boot options. Syntax is defined in Documenation/scsi/st.txt.
3970 */
3971static int __init st_setup(char *str)
3972{
3973 int i, len, ints[5];
3974 char *stp;
3975
3976 stp = get_options(str, ARRAY_SIZE(ints), ints);
3977
3978 if (ints[0] > 0) {
3979 for (i = 0; i < ints[0] && i < ARRAY_SIZE(parms); i++)
3980 if (parms[i].val)
3981 *parms[i].val = ints[i + 1];
3982 } else {
3983 while (stp != NULL) {
3984 for (i = 0; i < ARRAY_SIZE(parms); i++) {
3985 len = strlen(parms[i].name);
3986 if (!strncmp(stp, parms[i].name, len) &&
3987 (*(stp + len) == ':' || *(stp + len) == '=')) {
3988 if (parms[i].val)
3989 *parms[i].val =
3990 simple_strtoul(stp + len + 1, NULL, 0);
3991 else
3992 printk(KERN_WARNING "st: Obsolete parameter %s\n",
3993 parms[i].name);
3994 break;
3995 }
3996 }
Tobias Klauser6391a112006-06-08 22:23:48 -07003997 if (i >= ARRAY_SIZE(parms))
Linus Torvalds1da177e2005-04-16 15:20:36 -07003998 printk(KERN_WARNING "st: invalid parameter in '%s'\n",
3999 stp);
4000 stp = strchr(stp, ',');
4001 if (stp)
4002 stp++;
4003 }
4004 }
4005
4006 validate_options();
4007
4008 return 1;
4009}
4010
4011__setup("st=", st_setup);
4012
4013#endif
4014
Arjan van de Ven00977a52007-02-12 00:55:34 -08004015static const struct file_operations st_fops =
Linus Torvalds1da177e2005-04-16 15:20:36 -07004016{
4017 .owner = THIS_MODULE,
4018 .read = st_read,
4019 .write = st_write,
Kai Makisarafd66c1b2008-01-17 22:45:22 +02004020 .unlocked_ioctl = st_ioctl,
Linus Torvalds1da177e2005-04-16 15:20:36 -07004021#ifdef CONFIG_COMPAT
4022 .compat_ioctl = st_compat_ioctl,
4023#endif
4024 .open = st_open,
4025 .flush = st_flush,
4026 .release = st_release,
4027};
4028
4029static int st_probe(struct device *dev)
4030{
4031 struct scsi_device *SDp = to_scsi_device(dev);
4032 struct gendisk *disk = NULL;
4033 struct cdev *cdev = NULL;
4034 struct scsi_tape *tpnt = NULL;
4035 struct st_modedef *STm;
4036 struct st_partstat *STps;
4037 struct st_buffer *buffer;
4038 int i, j, mode, dev_num, error;
4039 char *stp;
Linus Torvalds1da177e2005-04-16 15:20:36 -07004040
4041 if (SDp->type != TYPE_TAPE)
4042 return -ENODEV;
4043 if ((stp = st_incompatible(SDp))) {
Jeff Garzik3bf743e2005-10-24 18:04:06 -04004044 sdev_printk(KERN_INFO, SDp, "Found incompatible tape\n");
Linus Torvalds1da177e2005-04-16 15:20:36 -07004045 printk(KERN_INFO "st: The suggested driver is %s.\n", stp);
4046 return -ENODEV;
4047 }
4048
Mike Christie8b05b772005-11-08 04:06:44 -06004049 i = min(SDp->request_queue->max_hw_segments,
4050 SDp->request_queue->max_phys_segments);
Linus Torvalds1da177e2005-04-16 15:20:36 -07004051 if (st_max_sg_segs < i)
4052 i = st_max_sg_segs;
FUJITA Tomonorif409d6c2008-12-18 14:49:47 +09004053 buffer = new_tape_buffer((SDp->host)->unchecked_isa_dma, i);
Linus Torvalds1da177e2005-04-16 15:20:36 -07004054 if (buffer == NULL) {
4055 printk(KERN_ERR
4056 "st: Can't allocate new tape buffer. Device not attached.\n");
4057 goto out;
4058 }
4059
4060 disk = alloc_disk(1);
4061 if (!disk) {
4062 printk(KERN_ERR "st: out of memory. Device not attached.\n");
4063 goto out_buffer_free;
4064 }
4065
4066 write_lock(&st_dev_arr_lock);
4067 if (st_nr_dev >= st_dev_max) {
4068 struct scsi_tape **tmp_da;
4069 int tmp_dev_max;
4070
4071 tmp_dev_max = max(st_nr_dev * 2, 8);
4072 if (tmp_dev_max > ST_MAX_TAPES)
4073 tmp_dev_max = ST_MAX_TAPES;
4074 if (tmp_dev_max <= st_nr_dev) {
4075 write_unlock(&st_dev_arr_lock);
4076 printk(KERN_ERR "st: Too many tape devices (max. %d).\n",
4077 ST_MAX_TAPES);
4078 goto out_put_disk;
4079 }
4080
Jes Sorensen24669f752006-01-16 10:31:18 -05004081 tmp_da = kzalloc(tmp_dev_max * sizeof(struct scsi_tape *), GFP_ATOMIC);
Linus Torvalds1da177e2005-04-16 15:20:36 -07004082 if (tmp_da == NULL) {
4083 write_unlock(&st_dev_arr_lock);
4084 printk(KERN_ERR "st: Can't extend device array.\n");
4085 goto out_put_disk;
4086 }
4087
Linus Torvalds1da177e2005-04-16 15:20:36 -07004088 if (scsi_tapes != NULL) {
4089 memcpy(tmp_da, scsi_tapes,
4090 st_dev_max * sizeof(struct scsi_tape *));
4091 kfree(scsi_tapes);
4092 }
4093 scsi_tapes = tmp_da;
4094
4095 st_dev_max = tmp_dev_max;
4096 }
4097
4098 for (i = 0; i < st_dev_max; i++)
4099 if (scsi_tapes[i] == NULL)
4100 break;
4101 if (i >= st_dev_max)
4102 panic("scsi_devices corrupt (st)");
4103
Jes Sorensen24669f752006-01-16 10:31:18 -05004104 tpnt = kzalloc(sizeof(struct scsi_tape), GFP_ATOMIC);
Linus Torvalds1da177e2005-04-16 15:20:36 -07004105 if (tpnt == NULL) {
4106 write_unlock(&st_dev_arr_lock);
4107 printk(KERN_ERR "st: Can't allocate device descriptor.\n");
4108 goto out_put_disk;
4109 }
Kai Makisaraf03a5672005-08-02 13:40:47 +03004110 kref_init(&tpnt->kref);
Linus Torvalds1da177e2005-04-16 15:20:36 -07004111 tpnt->disk = disk;
4112 sprintf(disk->disk_name, "st%d", i);
4113 disk->private_data = &tpnt->driver;
4114 disk->queue = SDp->request_queue;
4115 tpnt->driver = &st_template;
4116 scsi_tapes[i] = tpnt;
4117 dev_num = i;
4118
4119 tpnt->device = SDp;
4120 if (SDp->scsi_level <= 2)
4121 tpnt->tape_type = MT_ISSCSI1;
4122 else
4123 tpnt->tape_type = MT_ISSCSI2;
4124
4125 tpnt->buffer = buffer;
Kai Makisaraf03a5672005-08-02 13:40:47 +03004126 tpnt->buffer->last_SRpnt = NULL;
Linus Torvalds1da177e2005-04-16 15:20:36 -07004127
4128 tpnt->inited = 0;
4129 tpnt->dirty = 0;
4130 tpnt->in_use = 0;
4131 tpnt->drv_buffer = 1; /* Try buffering if no mode sense */
4132 tpnt->restr_dma = (SDp->host)->unchecked_isa_dma;
4133 tpnt->use_pf = (SDp->scsi_level >= SCSI_2);
4134 tpnt->density = 0;
4135 tpnt->do_auto_lock = ST_AUTO_LOCK;
4136 tpnt->can_bsr = (SDp->scsi_level > 2 ? 1 : ST_IN_FILE_POS); /* BSR mandatory in SCSI3 */
4137 tpnt->can_partitions = 0;
4138 tpnt->two_fm = ST_TWO_FM;
4139 tpnt->fast_mteom = ST_FAST_MTEOM;
4140 tpnt->scsi2_logical = ST_SCSI2LOGICAL;
Kai Makisara40f6b362008-02-24 22:23:24 +02004141 tpnt->sili = ST_SILI;
Linus Torvalds1da177e2005-04-16 15:20:36 -07004142 tpnt->immediate = ST_NOWAIT;
4143 tpnt->default_drvbuffer = 0xff; /* No forced buffering */
4144 tpnt->partition = 0;
4145 tpnt->new_partition = 0;
4146 tpnt->nbr_partitions = 0;
James Bottomleya02488e2008-11-30 10:36:26 -06004147 blk_queue_rq_timeout(tpnt->device->request_queue, ST_TIMEOUT);
Linus Torvalds1da177e2005-04-16 15:20:36 -07004148 tpnt->long_timeout = ST_LONG_TIMEOUT;
4149 tpnt->try_dio = try_direct_io && !SDp->host->unchecked_isa_dma;
4150
Linus Torvalds1da177e2005-04-16 15:20:36 -07004151 for (i = 0; i < ST_NBR_MODES; i++) {
4152 STm = &(tpnt->modes[i]);
4153 STm->defined = 0;
4154 STm->sysv = ST_SYSV;
4155 STm->defaults_for_writes = 0;
4156 STm->do_async_writes = ST_ASYNC_WRITES;
4157 STm->do_buffer_writes = ST_BUFFER_WRITES;
4158 STm->do_read_ahead = ST_READ_AHEAD;
4159 STm->default_compression = ST_DONT_TOUCH;
4160 STm->default_blksize = (-1); /* No forced size */
4161 STm->default_density = (-1); /* No forced density */
4162 }
4163
4164 for (i = 0; i < ST_NBR_PARTITIONS; i++) {
4165 STps = &(tpnt->ps[i]);
4166 STps->rw = ST_IDLE;
4167 STps->eof = ST_NOEOF;
4168 STps->at_sm = 0;
4169 STps->last_block_valid = 0;
4170 STps->drv_block = (-1);
4171 STps->drv_file = (-1);
4172 }
4173
4174 tpnt->current_mode = 0;
4175 tpnt->modes[0].defined = 1;
4176
4177 tpnt->density_changed = tpnt->compression_changed =
4178 tpnt->blksize_changed = 0;
Matthias Kaehlcke28f85002007-07-29 23:38:15 +02004179 mutex_init(&tpnt->lock);
Linus Torvalds1da177e2005-04-16 15:20:36 -07004180
4181 st_nr_dev++;
4182 write_unlock(&st_dev_arr_lock);
4183
4184 for (mode = 0; mode < ST_NBR_MODES; ++mode) {
4185 STm = &(tpnt->modes[mode]);
4186 for (j=0; j < 2; j++) {
4187 cdev = cdev_alloc();
4188 if (!cdev) {
4189 printk(KERN_ERR
4190 "st%d: out of memory. Device not attached.\n",
4191 dev_num);
4192 goto out_free_tape;
4193 }
4194 cdev->owner = THIS_MODULE;
4195 cdev->ops = &st_fops;
4196
4197 error = cdev_add(cdev,
4198 MKDEV(SCSI_TAPE_MAJOR, TAPE_MINOR(dev_num, mode, j)),
4199 1);
4200 if (error) {
4201 printk(KERN_ERR "st%d: Can't add %s-rewind mode %d\n",
4202 dev_num, j ? "non" : "auto", mode);
4203 printk(KERN_ERR "st%d: Device not attached.\n", dev_num);
4204 goto out_free_tape;
4205 }
4206 STm->cdevs[j] = cdev;
4207
4208 }
Jeff Garzik13026a62006-10-04 06:00:38 -04004209 error = do_create_class_files(tpnt, dev_num, mode);
4210 if (error)
4211 goto out_free_tape;
Linus Torvalds1da177e2005-04-16 15:20:36 -07004212 }
4213
Kai Makisara42252852006-11-07 21:56:38 +02004214 sdev_printk(KERN_NOTICE, SDp,
Rene Herman8b1ea242006-05-20 15:00:22 -07004215 "Attached scsi tape %s\n", tape_name(tpnt));
Kai Makisara42252852006-11-07 21:56:38 +02004216 sdev_printk(KERN_INFO, SDp, "%s: try direct i/o: %s (alignment %d B)\n",
4217 tape_name(tpnt), tpnt->try_dio ? "yes" : "no",
4218 queue_dma_alignment(SDp->request_queue) + 1);
Linus Torvalds1da177e2005-04-16 15:20:36 -07004219
4220 return 0;
4221
4222out_free_tape:
4223 for (mode=0; mode < ST_NBR_MODES; mode++) {
4224 STm = &(tpnt->modes[mode]);
4225 sysfs_remove_link(&tpnt->device->sdev_gendev.kobj,
4226 "tape");
4227 for (j=0; j < 2; j++) {
4228 if (STm->cdevs[j]) {
4229 if (cdev == STm->cdevs[j])
4230 cdev = NULL;
Tony Jonesee959b02008-02-22 00:13:36 +01004231 device_destroy(st_sysfs_class,
4232 MKDEV(SCSI_TAPE_MAJOR,
4233 TAPE_MINOR(i, mode, j)));
Linus Torvalds1da177e2005-04-16 15:20:36 -07004234 cdev_del(STm->cdevs[j]);
4235 }
4236 }
4237 }
4238 if (cdev)
4239 cdev_del(cdev);
4240 write_lock(&st_dev_arr_lock);
4241 scsi_tapes[dev_num] = NULL;
4242 st_nr_dev--;
4243 write_unlock(&st_dev_arr_lock);
4244out_put_disk:
4245 put_disk(disk);
Jesper Juhlc9475cb2005-11-07 01:01:26 -08004246 kfree(tpnt);
Linus Torvalds1da177e2005-04-16 15:20:36 -07004247out_buffer_free:
4248 kfree(buffer);
4249out:
4250 return -ENODEV;
4251};
4252
4253
4254static int st_remove(struct device *dev)
4255{
4256 struct scsi_device *SDp = to_scsi_device(dev);
4257 struct scsi_tape *tpnt;
4258 int i, j, mode;
4259
4260 write_lock(&st_dev_arr_lock);
4261 for (i = 0; i < st_dev_max; i++) {
4262 tpnt = scsi_tapes[i];
4263 if (tpnt != NULL && tpnt->device == SDp) {
4264 scsi_tapes[i] = NULL;
4265 st_nr_dev--;
4266 write_unlock(&st_dev_arr_lock);
Linus Torvalds1da177e2005-04-16 15:20:36 -07004267 sysfs_remove_link(&tpnt->device->sdev_gendev.kobj,
4268 "tape");
4269 for (mode = 0; mode < ST_NBR_MODES; ++mode) {
Linus Torvalds1da177e2005-04-16 15:20:36 -07004270 for (j=0; j < 2; j++) {
Tony Jonesee959b02008-02-22 00:13:36 +01004271 device_destroy(st_sysfs_class,
4272 MKDEV(SCSI_TAPE_MAJOR,
4273 TAPE_MINOR(i, mode, j)));
Linus Torvalds1da177e2005-04-16 15:20:36 -07004274 cdev_del(tpnt->modes[mode].cdevs[j]);
4275 tpnt->modes[mode].cdevs[j] = NULL;
4276 }
4277 }
Linus Torvalds1da177e2005-04-16 15:20:36 -07004278
Arjan van de Ven0b950672006-01-11 13:16:10 +01004279 mutex_lock(&st_ref_mutex);
Kai Makisaraf03a5672005-08-02 13:40:47 +03004280 kref_put(&tpnt->kref, scsi_tape_release);
Arjan van de Ven0b950672006-01-11 13:16:10 +01004281 mutex_unlock(&st_ref_mutex);
Linus Torvalds1da177e2005-04-16 15:20:36 -07004282 return 0;
4283 }
4284 }
4285
4286 write_unlock(&st_dev_arr_lock);
4287 return 0;
4288}
4289
Kai Makisaraf03a5672005-08-02 13:40:47 +03004290/**
4291 * scsi_tape_release - Called to free the Scsi_Tape structure
4292 * @kref: pointer to embedded kref
4293 *
Arjan van de Ven0b950672006-01-11 13:16:10 +01004294 * st_ref_mutex must be held entering this routine. Because it is
Kai Makisaraf03a5672005-08-02 13:40:47 +03004295 * called on last put, you should always use the scsi_tape_get()
4296 * scsi_tape_put() helpers which manipulate the semaphore directly
4297 * and never do a direct kref_put().
4298 **/
4299static void scsi_tape_release(struct kref *kref)
4300{
4301 struct scsi_tape *tpnt = to_scsi_tape(kref);
4302 struct gendisk *disk = tpnt->disk;
4303
4304 tpnt->device = NULL;
4305
4306 if (tpnt->buffer) {
Kai Makisaraf03a5672005-08-02 13:40:47 +03004307 normalize_buffer(tpnt->buffer);
FUJITA Tomonorid0e1ae32008-12-18 14:49:40 +09004308 kfree(tpnt->buffer->reserved_pages);
Kai Makisaraf03a5672005-08-02 13:40:47 +03004309 kfree(tpnt->buffer);
4310 }
4311
4312 disk->private_data = NULL;
4313 put_disk(disk);
4314 kfree(tpnt);
4315 return;
4316}
4317
Linus Torvalds1da177e2005-04-16 15:20:36 -07004318static int __init init_st(void)
4319{
Jeff Garzik13026a62006-10-04 06:00:38 -04004320 int err;
4321
Linus Torvalds1da177e2005-04-16 15:20:36 -07004322 validate_options();
4323
Jeff Garzik13026a62006-10-04 06:00:38 -04004324 printk(KERN_INFO "st: Version %s, fixed bufsize %d, s/g segs %d\n",
Linus Torvalds1da177e2005-04-16 15:20:36 -07004325 verstr, st_fixed_buffer_size, st_max_sg_segs);
4326
gregkh@suse.ded2538782005-03-23 09:55:22 -08004327 st_sysfs_class = class_create(THIS_MODULE, "scsi_tape");
Linus Torvalds1da177e2005-04-16 15:20:36 -07004328 if (IS_ERR(st_sysfs_class)) {
Linus Torvalds1da177e2005-04-16 15:20:36 -07004329 printk(KERN_ERR "Unable create sysfs class for SCSI tapes\n");
Jeff Garzik13026a62006-10-04 06:00:38 -04004330 return PTR_ERR(st_sysfs_class);
Linus Torvalds1da177e2005-04-16 15:20:36 -07004331 }
4332
Jeff Garzik13026a62006-10-04 06:00:38 -04004333 err = register_chrdev_region(MKDEV(SCSI_TAPE_MAJOR, 0),
4334 ST_MAX_TAPE_ENTRIES, "st");
4335 if (err) {
4336 printk(KERN_ERR "Unable to get major %d for SCSI tapes\n",
4337 SCSI_TAPE_MAJOR);
4338 goto err_class;
Linus Torvalds1da177e2005-04-16 15:20:36 -07004339 }
Jeff Garzik13026a62006-10-04 06:00:38 -04004340
4341 err = scsi_register_driver(&st_template.gendrv);
4342 if (err)
4343 goto err_chrdev;
4344
Robert P. J. Day405ae7d2007-02-17 19:13:42 +01004345 err = do_create_sysfs_files();
Jeff Garzik13026a62006-10-04 06:00:38 -04004346 if (err)
4347 goto err_scsidrv;
4348
4349 return 0;
4350
4351err_scsidrv:
4352 scsi_unregister_driver(&st_template.gendrv);
4353err_chrdev:
4354 unregister_chrdev_region(MKDEV(SCSI_TAPE_MAJOR, 0),
4355 ST_MAX_TAPE_ENTRIES);
4356err_class:
Kai Makisarac2c96f42005-08-02 12:21:51 +03004357 class_destroy(st_sysfs_class);
Jeff Garzik13026a62006-10-04 06:00:38 -04004358 return err;
Linus Torvalds1da177e2005-04-16 15:20:36 -07004359}
4360
4361static void __exit exit_st(void)
4362{
Robert P. J. Day405ae7d2007-02-17 19:13:42 +01004363 do_remove_sysfs_files();
Linus Torvalds1da177e2005-04-16 15:20:36 -07004364 scsi_unregister_driver(&st_template.gendrv);
4365 unregister_chrdev_region(MKDEV(SCSI_TAPE_MAJOR, 0),
4366 ST_MAX_TAPE_ENTRIES);
Kai Makisarac2c96f42005-08-02 12:21:51 +03004367 class_destroy(st_sysfs_class);
Linus Torvalds1da177e2005-04-16 15:20:36 -07004368 kfree(scsi_tapes);
4369 printk(KERN_INFO "st: Unloaded.\n");
4370}
4371
4372module_init(init_st);
4373module_exit(exit_st);
4374
4375
4376/* The sysfs driver interface. Read-only at the moment */
4377static ssize_t st_try_direct_io_show(struct device_driver *ddp, char *buf)
4378{
4379 return snprintf(buf, PAGE_SIZE, "%d\n", try_direct_io);
4380}
4381static DRIVER_ATTR(try_direct_io, S_IRUGO, st_try_direct_io_show, NULL);
4382
4383static ssize_t st_fixed_buffer_size_show(struct device_driver *ddp, char *buf)
4384{
4385 return snprintf(buf, PAGE_SIZE, "%d\n", st_fixed_buffer_size);
4386}
4387static DRIVER_ATTR(fixed_buffer_size, S_IRUGO, st_fixed_buffer_size_show, NULL);
4388
4389static ssize_t st_max_sg_segs_show(struct device_driver *ddp, char *buf)
4390{
4391 return snprintf(buf, PAGE_SIZE, "%d\n", st_max_sg_segs);
4392}
4393static DRIVER_ATTR(max_sg_segs, S_IRUGO, st_max_sg_segs_show, NULL);
4394
4395static ssize_t st_version_show(struct device_driver *ddd, char *buf)
4396{
4397 return snprintf(buf, PAGE_SIZE, "[%s]\n", verstr);
4398}
4399static DRIVER_ATTR(version, S_IRUGO, st_version_show, NULL);
4400
Robert P. J. Day405ae7d2007-02-17 19:13:42 +01004401static int do_create_sysfs_files(void)
Linus Torvalds1da177e2005-04-16 15:20:36 -07004402{
Robert P. J. Day405ae7d2007-02-17 19:13:42 +01004403 struct device_driver *sysfs = &st_template.gendrv;
Jeff Garzik13026a62006-10-04 06:00:38 -04004404 int err;
Linus Torvalds1da177e2005-04-16 15:20:36 -07004405
Robert P. J. Day405ae7d2007-02-17 19:13:42 +01004406 err = driver_create_file(sysfs, &driver_attr_try_direct_io);
Jeff Garzik13026a62006-10-04 06:00:38 -04004407 if (err)
4408 return err;
Robert P. J. Day405ae7d2007-02-17 19:13:42 +01004409 err = driver_create_file(sysfs, &driver_attr_fixed_buffer_size);
Jeff Garzik13026a62006-10-04 06:00:38 -04004410 if (err)
4411 goto err_try_direct_io;
Robert P. J. Day405ae7d2007-02-17 19:13:42 +01004412 err = driver_create_file(sysfs, &driver_attr_max_sg_segs);
Jeff Garzik13026a62006-10-04 06:00:38 -04004413 if (err)
4414 goto err_attr_fixed_buf;
Robert P. J. Day405ae7d2007-02-17 19:13:42 +01004415 err = driver_create_file(sysfs, &driver_attr_version);
Jeff Garzik13026a62006-10-04 06:00:38 -04004416 if (err)
4417 goto err_attr_max_sg;
4418
4419 return 0;
4420
4421err_attr_max_sg:
Robert P. J. Day405ae7d2007-02-17 19:13:42 +01004422 driver_remove_file(sysfs, &driver_attr_max_sg_segs);
Jeff Garzik13026a62006-10-04 06:00:38 -04004423err_attr_fixed_buf:
Robert P. J. Day405ae7d2007-02-17 19:13:42 +01004424 driver_remove_file(sysfs, &driver_attr_fixed_buffer_size);
Jeff Garzik13026a62006-10-04 06:00:38 -04004425err_try_direct_io:
Robert P. J. Day405ae7d2007-02-17 19:13:42 +01004426 driver_remove_file(sysfs, &driver_attr_try_direct_io);
Jeff Garzik13026a62006-10-04 06:00:38 -04004427 return err;
Linus Torvalds1da177e2005-04-16 15:20:36 -07004428}
4429
Robert P. J. Day405ae7d2007-02-17 19:13:42 +01004430static void do_remove_sysfs_files(void)
Linus Torvalds1da177e2005-04-16 15:20:36 -07004431{
Robert P. J. Day405ae7d2007-02-17 19:13:42 +01004432 struct device_driver *sysfs = &st_template.gendrv;
Linus Torvalds1da177e2005-04-16 15:20:36 -07004433
Robert P. J. Day405ae7d2007-02-17 19:13:42 +01004434 driver_remove_file(sysfs, &driver_attr_version);
4435 driver_remove_file(sysfs, &driver_attr_max_sg_segs);
4436 driver_remove_file(sysfs, &driver_attr_fixed_buffer_size);
4437 driver_remove_file(sysfs, &driver_attr_try_direct_io);
Linus Torvalds1da177e2005-04-16 15:20:36 -07004438}
4439
4440
4441/* The sysfs simple class interface */
Tony Jonesee959b02008-02-22 00:13:36 +01004442static ssize_t
4443st_defined_show(struct device *dev, struct device_attribute *attr, char *buf)
Linus Torvalds1da177e2005-04-16 15:20:36 -07004444{
James Bottomley7d15d6a2008-03-14 14:12:43 -07004445 struct st_modedef *STm = dev_get_drvdata(dev);
Linus Torvalds1da177e2005-04-16 15:20:36 -07004446 ssize_t l = 0;
4447
4448 l = snprintf(buf, PAGE_SIZE, "%d\n", STm->defined);
4449 return l;
4450}
4451
Tony Jonesee959b02008-02-22 00:13:36 +01004452DEVICE_ATTR(defined, S_IRUGO, st_defined_show, NULL);
Linus Torvalds1da177e2005-04-16 15:20:36 -07004453
Tony Jonesee959b02008-02-22 00:13:36 +01004454static ssize_t
4455st_defblk_show(struct device *dev, struct device_attribute *attr, char *buf)
Linus Torvalds1da177e2005-04-16 15:20:36 -07004456{
James Bottomley7d15d6a2008-03-14 14:12:43 -07004457 struct st_modedef *STm = dev_get_drvdata(dev);
Linus Torvalds1da177e2005-04-16 15:20:36 -07004458 ssize_t l = 0;
4459
4460 l = snprintf(buf, PAGE_SIZE, "%d\n", STm->default_blksize);
4461 return l;
4462}
4463
Tony Jonesee959b02008-02-22 00:13:36 +01004464DEVICE_ATTR(default_blksize, S_IRUGO, st_defblk_show, NULL);
Linus Torvalds1da177e2005-04-16 15:20:36 -07004465
Tony Jonesee959b02008-02-22 00:13:36 +01004466static ssize_t
4467st_defdensity_show(struct device *dev, struct device_attribute *attr, char *buf)
Linus Torvalds1da177e2005-04-16 15:20:36 -07004468{
James Bottomley7d15d6a2008-03-14 14:12:43 -07004469 struct st_modedef *STm = dev_get_drvdata(dev);
Linus Torvalds1da177e2005-04-16 15:20:36 -07004470 ssize_t l = 0;
4471 char *fmt;
4472
4473 fmt = STm->default_density >= 0 ? "0x%02x\n" : "%d\n";
4474 l = snprintf(buf, PAGE_SIZE, fmt, STm->default_density);
4475 return l;
4476}
4477
Tony Jonesee959b02008-02-22 00:13:36 +01004478DEVICE_ATTR(default_density, S_IRUGO, st_defdensity_show, NULL);
Linus Torvalds1da177e2005-04-16 15:20:36 -07004479
Tony Jonesee959b02008-02-22 00:13:36 +01004480static ssize_t
4481st_defcompression_show(struct device *dev, struct device_attribute *attr,
4482 char *buf)
Linus Torvalds1da177e2005-04-16 15:20:36 -07004483{
James Bottomley7d15d6a2008-03-14 14:12:43 -07004484 struct st_modedef *STm = dev_get_drvdata(dev);
Linus Torvalds1da177e2005-04-16 15:20:36 -07004485 ssize_t l = 0;
4486
4487 l = snprintf(buf, PAGE_SIZE, "%d\n", STm->default_compression - 1);
4488 return l;
4489}
4490
Tony Jonesee959b02008-02-22 00:13:36 +01004491DEVICE_ATTR(default_compression, S_IRUGO, st_defcompression_show, NULL);
Linus Torvalds1da177e2005-04-16 15:20:36 -07004492
Tony Jonesee959b02008-02-22 00:13:36 +01004493static ssize_t
4494st_options_show(struct device *dev, struct device_attribute *attr, char *buf)
Kai Makisarab174be02008-02-24 22:29:12 +02004495{
James Bottomley7d15d6a2008-03-14 14:12:43 -07004496 struct st_modedef *STm = dev_get_drvdata(dev);
Kai Makisarab174be02008-02-24 22:29:12 +02004497 struct scsi_tape *STp;
4498 int i, j, options;
4499 ssize_t l = 0;
4500
4501 for (i=0; i < st_dev_max; i++) {
4502 for (j=0; j < ST_NBR_MODES; j++)
4503 if (&scsi_tapes[i]->modes[j] == STm)
4504 break;
4505 if (j < ST_NBR_MODES)
4506 break;
4507 }
4508 if (i == st_dev_max)
4509 return 0; /* should never happen */
4510
4511 STp = scsi_tapes[i];
4512
4513 options = STm->do_buffer_writes ? MT_ST_BUFFER_WRITES : 0;
4514 options |= STm->do_async_writes ? MT_ST_ASYNC_WRITES : 0;
4515 options |= STm->do_read_ahead ? MT_ST_READ_AHEAD : 0;
4516 DEB( options |= debugging ? MT_ST_DEBUGGING : 0 );
4517 options |= STp->two_fm ? MT_ST_TWO_FM : 0;
4518 options |= STp->fast_mteom ? MT_ST_FAST_MTEOM : 0;
4519 options |= STm->defaults_for_writes ? MT_ST_DEF_WRITES : 0;
4520 options |= STp->can_bsr ? MT_ST_CAN_BSR : 0;
4521 options |= STp->omit_blklims ? MT_ST_NO_BLKLIMS : 0;
4522 options |= STp->can_partitions ? MT_ST_CAN_PARTITIONS : 0;
4523 options |= STp->scsi2_logical ? MT_ST_SCSI2LOGICAL : 0;
4524 options |= STm->sysv ? MT_ST_SYSV : 0;
4525 options |= STp->immediate ? MT_ST_NOWAIT : 0;
4526 options |= STp->sili ? MT_ST_SILI : 0;
4527
4528 l = snprintf(buf, PAGE_SIZE, "0x%08x\n", options);
4529 return l;
4530}
4531
Tony Jonesee959b02008-02-22 00:13:36 +01004532DEVICE_ATTR(options, S_IRUGO, st_options_show, NULL);
Kai Makisarab174be02008-02-24 22:29:12 +02004533
Jeff Garzik13026a62006-10-04 06:00:38 -04004534static int do_create_class_files(struct scsi_tape *STp, int dev_num, int mode)
Linus Torvalds1da177e2005-04-16 15:20:36 -07004535{
4536 int i, rew, error;
4537 char name[10];
Tony Jonesee959b02008-02-22 00:13:36 +01004538 struct device *st_class_member;
Linus Torvalds1da177e2005-04-16 15:20:36 -07004539
Linus Torvalds1da177e2005-04-16 15:20:36 -07004540 for (rew=0; rew < 2; rew++) {
4541 /* Make sure that the minor numbers corresponding to the four
4542 first modes always get the same names */
4543 i = mode << (4 - ST_NBR_MODE_BITS);
4544 snprintf(name, 10, "%s%s%s", rew ? "n" : "",
4545 STp->disk->disk_name, st_formats[i]);
4546 st_class_member =
Greg Kroah-Hartmand73a1a62008-07-21 20:03:34 -07004547 device_create(st_sysfs_class, &STp->device->sdev_gendev,
4548 MKDEV(SCSI_TAPE_MAJOR,
4549 TAPE_MINOR(dev_num, mode, rew)),
4550 &STp->modes[mode], "%s", name);
Linus Torvalds1da177e2005-04-16 15:20:36 -07004551 if (IS_ERR(st_class_member)) {
Tony Jonesee959b02008-02-22 00:13:36 +01004552 printk(KERN_WARNING "st%d: device_create failed\n",
Linus Torvalds1da177e2005-04-16 15:20:36 -07004553 dev_num);
Jeff Garzik13026a62006-10-04 06:00:38 -04004554 error = PTR_ERR(st_class_member);
Linus Torvalds1da177e2005-04-16 15:20:36 -07004555 goto out;
4556 }
Linus Torvalds1da177e2005-04-16 15:20:36 -07004557
Tony Jonesee959b02008-02-22 00:13:36 +01004558 error = device_create_file(st_class_member,
4559 &dev_attr_defined);
Jeff Garzik13026a62006-10-04 06:00:38 -04004560 if (error) goto out;
Tony Jonesee959b02008-02-22 00:13:36 +01004561 error = device_create_file(st_class_member,
4562 &dev_attr_default_blksize);
Jeff Garzik13026a62006-10-04 06:00:38 -04004563 if (error) goto out;
Tony Jonesee959b02008-02-22 00:13:36 +01004564 error = device_create_file(st_class_member,
4565 &dev_attr_default_density);
Jeff Garzik13026a62006-10-04 06:00:38 -04004566 if (error) goto out;
Tony Jonesee959b02008-02-22 00:13:36 +01004567 error = device_create_file(st_class_member,
4568 &dev_attr_default_compression);
Jeff Garzik13026a62006-10-04 06:00:38 -04004569 if (error) goto out;
Tony Jonesee959b02008-02-22 00:13:36 +01004570 error = device_create_file(st_class_member,
4571 &dev_attr_options);
Kai Makisarab174be02008-02-24 22:29:12 +02004572 if (error) goto out;
Jeff Garzik13026a62006-10-04 06:00:38 -04004573
Linus Torvalds1da177e2005-04-16 15:20:36 -07004574 if (mode == 0 && rew == 0) {
4575 error = sysfs_create_link(&STp->device->sdev_gendev.kobj,
4576 &st_class_member->kobj,
4577 "tape");
4578 if (error) {
4579 printk(KERN_ERR
4580 "st%d: Can't create sysfs link from SCSI device.\n",
4581 dev_num);
Jeff Garzik13026a62006-10-04 06:00:38 -04004582 goto out;
Linus Torvalds1da177e2005-04-16 15:20:36 -07004583 }
4584 }
4585 }
Jeff Garzik13026a62006-10-04 06:00:38 -04004586
4587 return 0;
4588
4589out:
4590 return error;
Linus Torvalds1da177e2005-04-16 15:20:36 -07004591}
4592
Linus Torvalds1da177e2005-04-16 15:20:36 -07004593/* The following functions may be useful for a larger audience. */
FUJITA Tomonori66207422008-12-18 14:49:43 +09004594static int sgl_map_user_pages(struct st_buffer *STbp,
4595 const unsigned int max_pages, unsigned long uaddr,
4596 size_t count, int rw)
Linus Torvalds1da177e2005-04-16 15:20:36 -07004597{
James Bottomley07542b82005-08-31 20:27:22 -04004598 unsigned long end = (uaddr + count + PAGE_SIZE - 1) >> PAGE_SHIFT;
4599 unsigned long start = uaddr >> PAGE_SHIFT;
4600 const int nr_pages = end - start;
Linus Torvalds1da177e2005-04-16 15:20:36 -07004601 int res, i, j;
Linus Torvalds1da177e2005-04-16 15:20:36 -07004602 struct page **pages;
FUJITA Tomonori66207422008-12-18 14:49:43 +09004603 struct rq_map_data *mdata = &STbp->map_data;
Linus Torvalds1da177e2005-04-16 15:20:36 -07004604
Linus Torvalds1da177e2005-04-16 15:20:36 -07004605 /* User attempted Overflow! */
4606 if ((uaddr + count) < uaddr)
4607 return -EINVAL;
4608
4609 /* Too big */
4610 if (nr_pages > max_pages)
4611 return -ENOMEM;
4612
4613 /* Hmm? */
4614 if (count == 0)
4615 return 0;
4616
4617 if ((pages = kmalloc(max_pages * sizeof(*pages), GFP_KERNEL)) == NULL)
4618 return -ENOMEM;
4619
4620 /* Try to fault in all of the necessary pages */
4621 down_read(&current->mm->mmap_sem);
4622 /* rw==READ means read from drive, write into memory area */
4623 res = get_user_pages(
4624 current,
4625 current->mm,
4626 uaddr,
4627 nr_pages,
4628 rw == READ,
4629 0, /* don't force */
4630 pages,
4631 NULL);
4632 up_read(&current->mm->mmap_sem);
4633
4634 /* Errors and no page mapped should return here */
4635 if (res < nr_pages)
4636 goto out_unmap;
4637
4638 for (i=0; i < nr_pages; i++) {
4639 /* FIXME: flush superflous for rw==READ,
4640 * probably wrong function for rw==WRITE
4641 */
4642 flush_dcache_page(pages[i]);
4643 }
4644
FUJITA Tomonori66207422008-12-18 14:49:43 +09004645 mdata->offset = uaddr & ~PAGE_MASK;
4646 mdata->page_order = 0;
4647 STbp->mapped_pages = pages;
Linus Torvalds1da177e2005-04-16 15:20:36 -07004648
Linus Torvalds1da177e2005-04-16 15:20:36 -07004649 return nr_pages;
Linus Torvalds1da177e2005-04-16 15:20:36 -07004650 out_unmap:
4651 if (res > 0) {
4652 for (j=0; j < res; j++)
4653 page_cache_release(pages[j]);
Hugh Dickins6bc733e2005-12-01 20:21:57 +00004654 res = 0;
Linus Torvalds1da177e2005-04-16 15:20:36 -07004655 }
4656 kfree(pages);
4657 return res;
4658}
4659
4660
4661/* And unmap them... */
FUJITA Tomonori66207422008-12-18 14:49:43 +09004662static int sgl_unmap_user_pages(struct st_buffer *STbp,
4663 const unsigned int nr_pages, int dirtied)
Linus Torvalds1da177e2005-04-16 15:20:36 -07004664{
4665 int i;
4666
4667 for (i=0; i < nr_pages; i++) {
FUJITA Tomonori66207422008-12-18 14:49:43 +09004668 struct page *page = STbp->mapped_pages[i];
Nick Pigginb5810032005-10-29 18:16:12 -07004669
Nick Pigginb5810032005-10-29 18:16:12 -07004670 if (dirtied)
4671 SetPageDirty(page);
Linus Torvalds1da177e2005-04-16 15:20:36 -07004672 /* FIXME: cache flush missing for rw==READ
4673 * FIXME: call the correct reference counting function
4674 */
Nick Pigginb5810032005-10-29 18:16:12 -07004675 page_cache_release(page);
Linus Torvalds1da177e2005-04-16 15:20:36 -07004676 }
FUJITA Tomonori66207422008-12-18 14:49:43 +09004677 kfree(STbp->mapped_pages);
4678 STbp->mapped_pages = NULL;
Linus Torvalds1da177e2005-04-16 15:20:36 -07004679
4680 return 0;
4681}