blob: 73c44cbdea478411d5edad39f308fb97f942f2fb [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 Makisara9abe16c2007-02-03 13:21:29 +020012 Copyright 1992 - 2007 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 Makisara9abe16c2007-02-03 13:21:29 +020020static const char *verstr = "20070203";
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>
Linus Torvalds1da177e2005-04-16 15:20:36 -070041
42#include <asm/uaccess.h>
43#include <asm/dma.h>
44#include <asm/system.h>
45
46#include <scsi/scsi.h>
47#include <scsi/scsi_dbg.h>
48#include <scsi/scsi_device.h>
49#include <scsi/scsi_driver.h>
50#include <scsi/scsi_eh.h>
51#include <scsi/scsi_host.h>
52#include <scsi/scsi_ioctl.h>
Kai Makisara 16c4b3e2005-05-01 18:11:55 +030053#include <scsi/sg.h>
Linus Torvalds1da177e2005-04-16 15:20:36 -070054
55
56/* The driver prints some debugging information on the console if DEBUG
57 is defined and non-zero. */
58#define DEBUG 0
59
60#if DEBUG
61/* The message level for the debug messages is currently set to KERN_NOTICE
62 so that people can easily see the messages. Later when the debugging messages
63 in the drivers are more widely classified, this may be changed to KERN_DEBUG. */
64#define ST_DEB_MSG KERN_NOTICE
65#define DEB(a) a
66#define DEBC(a) if (debugging) { a ; }
67#else
68#define DEB(a)
69#define DEBC(a)
70#endif
71
72#define ST_KILOBYTE 1024
73
74#include "st_options.h"
75#include "st.h"
76
77static int buffer_kbs;
78static int max_sg_segs;
79static int try_direct_io = TRY_DIRECT_IO;
80static int try_rdio = 1;
81static int try_wdio = 1;
82
83static int st_dev_max;
84static int st_nr_dev;
85
gregkh@suse.ded2538782005-03-23 09:55:22 -080086static struct class *st_sysfs_class;
Linus Torvalds1da177e2005-04-16 15:20:36 -070087
88MODULE_AUTHOR("Kai Makisara");
Rene Hermanf018fa52006-03-08 00:14:20 -080089MODULE_DESCRIPTION("SCSI tape (st) driver");
Linus Torvalds1da177e2005-04-16 15:20:36 -070090MODULE_LICENSE("GPL");
Rene Hermanf018fa52006-03-08 00:14:20 -080091MODULE_ALIAS_CHARDEV_MAJOR(SCSI_TAPE_MAJOR);
Michael Tokarevd7b8bcb2006-10-27 16:02:37 +040092MODULE_ALIAS_SCSI_DEVICE(TYPE_TAPE);
Linus Torvalds1da177e2005-04-16 15:20:36 -070093
94/* Set 'perm' (4th argument) to 0 to disable module_param's definition
95 * of sysfs parameters (which module_param doesn't yet support).
96 * Sysfs parameters defined explicitly later.
97 */
98module_param_named(buffer_kbs, buffer_kbs, int, 0);
99MODULE_PARM_DESC(buffer_kbs, "Default driver buffer size for fixed block mode (KB; 32)");
100module_param_named(max_sg_segs, max_sg_segs, int, 0);
101MODULE_PARM_DESC(max_sg_segs, "Maximum number of scatter/gather segments to use (256)");
102module_param_named(try_direct_io, try_direct_io, int, 0);
103MODULE_PARM_DESC(try_direct_io, "Try direct I/O between user buffer and tape drive (1)");
104
105/* Extra parameters for testing */
106module_param_named(try_rdio, try_rdio, int, 0);
107MODULE_PARM_DESC(try_rdio, "Try direct read i/o when possible");
108module_param_named(try_wdio, try_wdio, int, 0);
109MODULE_PARM_DESC(try_wdio, "Try direct write i/o when possible");
110
111#ifndef MODULE
112static int write_threshold_kbs; /* retained for compatibility */
113static struct st_dev_parm {
114 char *name;
115 int *val;
116} parms[] __initdata = {
117 {
118 "buffer_kbs", &buffer_kbs
119 },
120 { /* Retained for compatibility with 2.4 */
121 "write_threshold_kbs", &write_threshold_kbs
122 },
123 {
124 "max_sg_segs", NULL
125 },
126 {
127 "try_direct_io", &try_direct_io
128 }
129};
130#endif
131
132/* Restrict the number of modes so that names for all are assigned */
133#if ST_NBR_MODES > 16
134#error "Maximum number of modes is 16"
135#endif
136/* Bit reversed order to get same names for same minors with all
137 mode counts */
Arjan van de Ven0ad78202005-11-28 16:22:25 +0100138static const char *st_formats[] = {
Linus Torvalds1da177e2005-04-16 15:20:36 -0700139 "", "r", "k", "s", "l", "t", "o", "u",
140 "m", "v", "p", "x", "a", "y", "q", "z"};
141
142/* The default definitions have been moved to st_options.h */
143
144#define ST_FIXED_BUFFER_SIZE (ST_FIXED_BUFFER_BLOCKS * ST_KILOBYTE)
145
146/* The buffer size should fit into the 24 bits for length in the
147 6-byte SCSI read and write commands. */
148#if ST_FIXED_BUFFER_SIZE >= (2 << 24 - 1)
149#error "Buffer size should not exceed (2 << 24 - 1) bytes!"
150#endif
151
152static int debugging = DEBUG;
153
154#define MAX_RETRIES 0
155#define MAX_WRITE_RETRIES 0
156#define MAX_READY_RETRIES 0
157#define NO_TAPE NOT_READY
158
159#define ST_TIMEOUT (900 * HZ)
160#define ST_LONG_TIMEOUT (14000 * HZ)
161
162/* Remove mode bits and auto-rewind bit (7) */
163#define TAPE_NR(x) ( ((iminor(x) & ~255) >> (ST_NBR_MODE_BITS + 1)) | \
164 (iminor(x) & ~(-1 << ST_MODE_SHIFT)) )
165#define TAPE_MODE(x) ((iminor(x) & ST_MODE_MASK) >> ST_MODE_SHIFT)
166
167/* Construct the minor number from the device (d), mode (m), and non-rewind (n) data */
168#define TAPE_MINOR(d, m, n) (((d & ~(255 >> (ST_NBR_MODE_BITS + 1))) << (ST_NBR_MODE_BITS + 1)) | \
169 (d & (255 >> (ST_NBR_MODE_BITS + 1))) | (m << ST_MODE_SHIFT) | ((n != 0) << 7) )
170
171/* Internal ioctl to set both density (uppermost 8 bits) and blocksize (lower
172 24 bits) */
173#define SET_DENS_AND_BLK 0x10001
174
175static DEFINE_RWLOCK(st_dev_arr_lock);
176
177static int st_fixed_buffer_size = ST_FIXED_BUFFER_SIZE;
178static int st_max_sg_segs = ST_MAX_SG;
179
180static struct scsi_tape **scsi_tapes = NULL;
181
182static int modes_defined;
183
184static struct st_buffer *new_tape_buffer(int, int, int);
185static int enlarge_buffer(struct st_buffer *, int, int);
186static void normalize_buffer(struct st_buffer *);
187static int append_to_buffer(const char __user *, struct st_buffer *, int);
188static int from_buffer(struct st_buffer *, char __user *, int);
189static void move_buffer_data(struct st_buffer *, int);
190static void buf_to_sg(struct st_buffer *, unsigned int);
191
Linus Torvalds1da177e2005-04-16 15:20:36 -0700192static int sgl_map_user_pages(struct scatterlist *, const unsigned int,
193 unsigned long, size_t, int);
194static int sgl_unmap_user_pages(struct scatterlist *, const unsigned int, int);
195
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
436
437/* Wakeup from interrupt */
Mike Christie8b05b772005-11-08 04:06:44 -0600438static void st_sleep_done(void *data, char *sense, int result, int resid)
Linus Torvalds1da177e2005-04-16 15:20:36 -0700439{
Mike Christie8b05b772005-11-08 04:06:44 -0600440 struct st_request *SRpnt = data;
441 struct scsi_tape *STp = SRpnt->stp;
Linus Torvalds1da177e2005-04-16 15:20:36 -0700442
Mike Christie8b05b772005-11-08 04:06:44 -0600443 memcpy(SRpnt->sense, sense, SCSI_SENSE_BUFFERSIZE);
444 (STp->buffer)->cmdstat.midlevel_result = SRpnt->result = result;
Linus Torvalds1da177e2005-04-16 15:20:36 -0700445 DEB( STp->write_pending = 0; )
446
Mike Christie8b05b772005-11-08 04:06:44 -0600447 if (SRpnt->waiting)
448 complete(SRpnt->waiting);
449}
450
451static struct st_request *st_allocate_request(void)
452{
453 return kzalloc(sizeof(struct st_request), GFP_KERNEL);
454}
455
456static void st_release_request(struct st_request *streq)
457{
458 kfree(streq);
Linus Torvalds1da177e2005-04-16 15:20:36 -0700459}
460
461/* Do the scsi command. Waits until command performed if do_wait is true.
462 Otherwise write_behind_check() is used to check that the command
463 has finished. */
Mike Christie8b05b772005-11-08 04:06:44 -0600464static struct st_request *
465st_do_scsi(struct st_request * SRpnt, struct scsi_tape * STp, unsigned char *cmd,
Linus Torvalds1da177e2005-04-16 15:20:36 -0700466 int bytes, int direction, int timeout, int retries, int do_wait)
467{
Kai Makisaraf03a5672005-08-02 13:40:47 +0300468 struct completion *waiting;
Linus Torvalds1da177e2005-04-16 15:20:36 -0700469
Kai Makisaraf03a5672005-08-02 13:40:47 +0300470 /* if async, make sure there's no command outstanding */
471 if (!do_wait && ((STp->buffer)->last_SRpnt)) {
472 printk(KERN_ERR "%s: Async command already active.\n",
473 tape_name(STp));
474 if (signal_pending(current))
475 (STp->buffer)->syscall_result = (-EINTR);
476 else
477 (STp->buffer)->syscall_result = (-EBUSY);
478 return NULL;
479 }
480
Linus Torvalds1da177e2005-04-16 15:20:36 -0700481 if (SRpnt == NULL) {
Mike Christie8b05b772005-11-08 04:06:44 -0600482 SRpnt = st_allocate_request();
Linus Torvalds1da177e2005-04-16 15:20:36 -0700483 if (SRpnt == NULL) {
484 DEBC( printk(KERN_ERR "%s: Can't get SCSI request.\n",
485 tape_name(STp)); );
486 if (signal_pending(current))
487 (STp->buffer)->syscall_result = (-EINTR);
488 else
489 (STp->buffer)->syscall_result = (-EBUSY);
490 return NULL;
491 }
Mike Christie8b05b772005-11-08 04:06:44 -0600492 SRpnt->stp = STp;
Linus Torvalds1da177e2005-04-16 15:20:36 -0700493 }
494
Kai Makisaraf03a5672005-08-02 13:40:47 +0300495 /* If async IO, set last_SRpnt. This ptr tells write_behind_check
496 which IO is outstanding. It's nulled out when the IO completes. */
497 if (!do_wait)
498 (STp->buffer)->last_SRpnt = SRpnt;
499
500 waiting = &STp->wait;
501 init_completion(waiting);
Mike Christie8b05b772005-11-08 04:06:44 -0600502 SRpnt->waiting = waiting;
503
504 if (!STp->buffer->do_dio)
505 buf_to_sg(STp->buffer, bytes);
506
507 memcpy(SRpnt->cmd, cmd, sizeof(SRpnt->cmd));
Linus Torvalds1da177e2005-04-16 15:20:36 -0700508 STp->buffer->cmdstat.have_sense = 0;
Mike Christie8b05b772005-11-08 04:06:44 -0600509 STp->buffer->syscall_result = 0;
Linus Torvalds1da177e2005-04-16 15:20:36 -0700510
brking@us.ibm.combb1d1072006-01-23 15:03:22 -0600511 if (scsi_execute_async(STp->device, cmd, COMMAND_SIZE(cmd[0]), direction,
Mike Christie8b05b772005-11-08 04:06:44 -0600512 &((STp->buffer)->sg[0]), bytes, (STp->buffer)->sg_segs,
Kai Makisara787926b2005-11-13 10:04:44 +0200513 timeout, retries, SRpnt, st_sleep_done, GFP_KERNEL)) {
Mike Christie8b05b772005-11-08 04:06:44 -0600514 /* could not allocate the buffer or request was too large */
515 (STp->buffer)->syscall_result = (-EBUSY);
Kai Makisara787926b2005-11-13 10:04:44 +0200516 (STp->buffer)->last_SRpnt = NULL;
517 }
Mike Christie8b05b772005-11-08 04:06:44 -0600518 else if (do_wait) {
Kai Makisaraf03a5672005-08-02 13:40:47 +0300519 wait_for_completion(waiting);
Mike Christie8b05b772005-11-08 04:06:44 -0600520 SRpnt->waiting = NULL;
Linus Torvalds1da177e2005-04-16 15:20:36 -0700521 (STp->buffer)->syscall_result = st_chk_result(STp, SRpnt);
522 }
Mike Christie8b05b772005-11-08 04:06:44 -0600523
Linus Torvalds1da177e2005-04-16 15:20:36 -0700524 return SRpnt;
525}
526
527
528/* Handle the write-behind checking (waits for completion). Returns -ENOSPC if
529 write has been correct but EOM early warning reached, -EIO if write ended in
530 error or zero if write successful. Asynchronous writes are used only in
531 variable block mode. */
532static int write_behind_check(struct scsi_tape * STp)
533{
534 int retval = 0;
535 struct st_buffer *STbuffer;
536 struct st_partstat *STps;
537 struct st_cmdstatus *cmdstatp;
Mike Christie8b05b772005-11-08 04:06:44 -0600538 struct st_request *SRpnt;
Linus Torvalds1da177e2005-04-16 15:20:36 -0700539
540 STbuffer = STp->buffer;
541 if (!STbuffer->writing)
542 return 0;
543
544 DEB(
545 if (STp->write_pending)
546 STp->nbr_waits++;
547 else
548 STp->nbr_finished++;
549 ) /* end DEB */
550
551 wait_for_completion(&(STp->wait));
Kai Makisaraf03a5672005-08-02 13:40:47 +0300552 SRpnt = STbuffer->last_SRpnt;
553 STbuffer->last_SRpnt = NULL;
Mike Christie8b05b772005-11-08 04:06:44 -0600554 SRpnt->waiting = NULL;
Linus Torvalds1da177e2005-04-16 15:20:36 -0700555
Kai Makisaraf03a5672005-08-02 13:40:47 +0300556 (STp->buffer)->syscall_result = st_chk_result(STp, SRpnt);
Mike Christie8b05b772005-11-08 04:06:44 -0600557 st_release_request(SRpnt);
Linus Torvalds1da177e2005-04-16 15:20:36 -0700558
559 STbuffer->buffer_bytes -= STbuffer->writing;
560 STps = &(STp->ps[STp->partition]);
561 if (STps->drv_block >= 0) {
562 if (STp->block_size == 0)
563 STps->drv_block++;
564 else
565 STps->drv_block += STbuffer->writing / STp->block_size;
566 }
567
568 cmdstatp = &STbuffer->cmdstat;
569 if (STbuffer->syscall_result) {
570 retval = -EIO;
571 if (cmdstatp->have_sense && !cmdstatp->deferred &&
572 (cmdstatp->flags & SENSE_EOM) &&
573 (cmdstatp->sense_hdr.sense_key == NO_SENSE ||
574 cmdstatp->sense_hdr.sense_key == RECOVERED_ERROR)) {
575 /* EOM at write-behind, has all data been written? */
576 if (!cmdstatp->remainder_valid ||
577 cmdstatp->uremainder64 == 0)
578 retval = -ENOSPC;
579 }
580 if (retval == -EIO)
581 STps->drv_block = -1;
582 }
583 STbuffer->writing = 0;
584
585 DEB(if (debugging && retval)
586 printk(ST_DEB_MSG "%s: Async write error %x, return value %d.\n",
587 tape_name(STp), STbuffer->cmdstat.midlevel_result, retval);) /* end DEB */
588
589 return retval;
590}
591
592
593/* Step over EOF if it has been inadvertently crossed (ioctl not used because
594 it messes up the block number). */
595static int cross_eof(struct scsi_tape * STp, int forward)
596{
Mike Christie8b05b772005-11-08 04:06:44 -0600597 struct st_request *SRpnt;
Linus Torvalds1da177e2005-04-16 15:20:36 -0700598 unsigned char cmd[MAX_COMMAND_SIZE];
599
600 cmd[0] = SPACE;
601 cmd[1] = 0x01; /* Space FileMarks */
602 if (forward) {
603 cmd[2] = cmd[3] = 0;
604 cmd[4] = 1;
605 } else
606 cmd[2] = cmd[3] = cmd[4] = 0xff; /* -1 filemarks */
607 cmd[5] = 0;
608
609 DEBC(printk(ST_DEB_MSG "%s: Stepping over filemark %s.\n",
610 tape_name(STp), forward ? "forward" : "backward"));
611
612 SRpnt = st_do_scsi(NULL, STp, cmd, 0, DMA_NONE,
613 STp->device->timeout, MAX_RETRIES, 1);
614 if (!SRpnt)
615 return (STp->buffer)->syscall_result;
616
Mike Christie8b05b772005-11-08 04:06:44 -0600617 st_release_request(SRpnt);
Linus Torvalds1da177e2005-04-16 15:20:36 -0700618 SRpnt = NULL;
619
620 if ((STp->buffer)->cmdstat.midlevel_result != 0)
621 printk(KERN_ERR "%s: Stepping over filemark %s failed.\n",
622 tape_name(STp), forward ? "forward" : "backward");
623
624 return (STp->buffer)->syscall_result;
625}
626
627
628/* Flush the write buffer (never need to write if variable blocksize). */
629static int flush_write_buffer(struct scsi_tape * STp)
630{
631 int offset, transfer, blks;
632 int result;
633 unsigned char cmd[MAX_COMMAND_SIZE];
Mike Christie8b05b772005-11-08 04:06:44 -0600634 struct st_request *SRpnt;
Linus Torvalds1da177e2005-04-16 15:20:36 -0700635 struct st_partstat *STps;
636
637 result = write_behind_check(STp);
638 if (result)
639 return result;
640
641 result = 0;
642 if (STp->dirty == 1) {
643
644 offset = (STp->buffer)->buffer_bytes;
645 transfer = ((offset + STp->block_size - 1) /
646 STp->block_size) * STp->block_size;
647 DEBC(printk(ST_DEB_MSG "%s: Flushing %d bytes.\n",
648 tape_name(STp), transfer));
649
650 memset((STp->buffer)->b_data + offset, 0, transfer - offset);
651
652 memset(cmd, 0, MAX_COMMAND_SIZE);
653 cmd[0] = WRITE_6;
654 cmd[1] = 1;
655 blks = transfer / STp->block_size;
656 cmd[2] = blks >> 16;
657 cmd[3] = blks >> 8;
658 cmd[4] = blks;
659
660 SRpnt = st_do_scsi(NULL, STp, cmd, transfer, DMA_TO_DEVICE,
661 STp->device->timeout, MAX_WRITE_RETRIES, 1);
662 if (!SRpnt)
663 return (STp->buffer)->syscall_result;
664
665 STps = &(STp->ps[STp->partition]);
666 if ((STp->buffer)->syscall_result != 0) {
667 struct st_cmdstatus *cmdstatp = &STp->buffer->cmdstat;
668
669 if (cmdstatp->have_sense && !cmdstatp->deferred &&
670 (cmdstatp->flags & SENSE_EOM) &&
671 (cmdstatp->sense_hdr.sense_key == NO_SENSE ||
672 cmdstatp->sense_hdr.sense_key == RECOVERED_ERROR) &&
673 (!cmdstatp->remainder_valid ||
674 cmdstatp->uremainder64 == 0)) { /* All written at EOM early warning */
675 STp->dirty = 0;
676 (STp->buffer)->buffer_bytes = 0;
677 if (STps->drv_block >= 0)
678 STps->drv_block += blks;
679 result = (-ENOSPC);
680 } else {
681 printk(KERN_ERR "%s: Error on flush.\n",
682 tape_name(STp));
683 STps->drv_block = (-1);
684 result = (-EIO);
685 }
686 } else {
687 if (STps->drv_block >= 0)
688 STps->drv_block += blks;
689 STp->dirty = 0;
690 (STp->buffer)->buffer_bytes = 0;
691 }
Mike Christie8b05b772005-11-08 04:06:44 -0600692 st_release_request(SRpnt);
Linus Torvalds1da177e2005-04-16 15:20:36 -0700693 SRpnt = NULL;
694 }
695 return result;
696}
697
698
699/* Flush the tape buffer. The tape will be positioned correctly unless
700 seek_next is true. */
701static int flush_buffer(struct scsi_tape *STp, int seek_next)
702{
703 int backspace, result;
704 struct st_buffer *STbuffer;
705 struct st_partstat *STps;
706
707 STbuffer = STp->buffer;
708
709 /*
710 * If there was a bus reset, block further access
711 * to this device.
712 */
713 if (STp->pos_unknown)
714 return (-EIO);
715
716 if (STp->ready != ST_READY)
717 return 0;
718 STps = &(STp->ps[STp->partition]);
719 if (STps->rw == ST_WRITING) /* Writing */
720 return flush_write_buffer(STp);
721
722 if (STp->block_size == 0)
723 return 0;
724
725 backspace = ((STp->buffer)->buffer_bytes +
726 (STp->buffer)->read_pointer) / STp->block_size -
727 ((STp->buffer)->read_pointer + STp->block_size - 1) /
728 STp->block_size;
729 (STp->buffer)->buffer_bytes = 0;
730 (STp->buffer)->read_pointer = 0;
731 result = 0;
732 if (!seek_next) {
733 if (STps->eof == ST_FM_HIT) {
734 result = cross_eof(STp, 0); /* Back over the EOF hit */
735 if (!result)
736 STps->eof = ST_NOEOF;
737 else {
738 if (STps->drv_file >= 0)
739 STps->drv_file++;
740 STps->drv_block = 0;
741 }
742 }
743 if (!result && backspace > 0)
744 result = st_int_ioctl(STp, MTBSR, backspace);
745 } else if (STps->eof == ST_FM_HIT) {
746 if (STps->drv_file >= 0)
747 STps->drv_file++;
748 STps->drv_block = 0;
749 STps->eof = ST_NOEOF;
750 }
751 return result;
752
753}
754
755/* Set the mode parameters */
756static int set_mode_densblk(struct scsi_tape * STp, struct st_modedef * STm)
757{
758 int set_it = 0;
759 unsigned long arg;
760 char *name = tape_name(STp);
761
762 if (!STp->density_changed &&
763 STm->default_density >= 0 &&
764 STm->default_density != STp->density) {
765 arg = STm->default_density;
766 set_it = 1;
767 } else
768 arg = STp->density;
769 arg <<= MT_ST_DENSITY_SHIFT;
770 if (!STp->blksize_changed &&
771 STm->default_blksize >= 0 &&
772 STm->default_blksize != STp->block_size) {
773 arg |= STm->default_blksize;
774 set_it = 1;
775 } else
776 arg |= STp->block_size;
777 if (set_it &&
778 st_int_ioctl(STp, SET_DENS_AND_BLK, arg)) {
779 printk(KERN_WARNING
780 "%s: Can't set default block size to %d bytes and density %x.\n",
781 name, STm->default_blksize, STm->default_density);
782 if (modes_defined)
783 return (-EINVAL);
784 }
785 return 0;
786}
787
788
Mike Christie8b05b772005-11-08 04:06:44 -0600789/* Lock or unlock the drive door. Don't use when st_request allocated. */
Linus Torvalds1da177e2005-04-16 15:20:36 -0700790static int do_door_lock(struct scsi_tape * STp, int do_lock)
791{
792 int retval, cmd;
793 DEB(char *name = tape_name(STp);)
794
795
796 cmd = do_lock ? SCSI_IOCTL_DOORLOCK : SCSI_IOCTL_DOORUNLOCK;
797 DEBC(printk(ST_DEB_MSG "%s: %socking drive door.\n", name,
798 do_lock ? "L" : "Unl"));
799 retval = scsi_ioctl(STp->device, cmd, NULL);
800 if (!retval) {
801 STp->door_locked = do_lock ? ST_LOCKED_EXPLICIT : ST_UNLOCKED;
802 }
803 else {
804 STp->door_locked = ST_LOCK_FAILS;
805 }
806 return retval;
807}
808
809
810/* Set the internal state after reset */
811static void reset_state(struct scsi_tape *STp)
812{
813 int i;
814 struct st_partstat *STps;
815
816 STp->pos_unknown = 0;
817 for (i = 0; i < ST_NBR_PARTITIONS; i++) {
818 STps = &(STp->ps[i]);
819 STps->rw = ST_IDLE;
820 STps->eof = ST_NOEOF;
821 STps->at_sm = 0;
822 STps->last_block_valid = 0;
823 STps->drv_block = -1;
824 STps->drv_file = -1;
825 }
826 if (STp->can_partitions) {
827 STp->partition = find_partition(STp);
828 if (STp->partition < 0)
829 STp->partition = 0;
830 STp->new_partition = STp->partition;
831 }
832}
833
834/* Test if the drive is ready. Returns either one of the codes below or a negative system
835 error code. */
836#define CHKRES_READY 0
837#define CHKRES_NEW_SESSION 1
838#define CHKRES_NOT_READY 2
839#define CHKRES_NO_TAPE 3
840
841#define MAX_ATTENTIONS 10
842
843static int test_ready(struct scsi_tape *STp, int do_wait)
844{
845 int attentions, waits, max_wait, scode;
846 int retval = CHKRES_READY, new_session = 0;
847 unsigned char cmd[MAX_COMMAND_SIZE];
Mike Christie8b05b772005-11-08 04:06:44 -0600848 struct st_request *SRpnt = NULL;
Linus Torvalds1da177e2005-04-16 15:20:36 -0700849 struct st_cmdstatus *cmdstatp = &STp->buffer->cmdstat;
850
851 max_wait = do_wait ? ST_BLOCK_SECONDS : 0;
852
853 for (attentions=waits=0; ; ) {
854 memset((void *) &cmd[0], 0, MAX_COMMAND_SIZE);
855 cmd[0] = TEST_UNIT_READY;
856 SRpnt = st_do_scsi(SRpnt, STp, cmd, 0, DMA_NONE,
857 STp->long_timeout, MAX_READY_RETRIES, 1);
858
859 if (!SRpnt) {
860 retval = (STp->buffer)->syscall_result;
861 break;
862 }
863
864 if (cmdstatp->have_sense) {
865
866 scode = cmdstatp->sense_hdr.sense_key;
867
868 if (scode == UNIT_ATTENTION) { /* New media? */
869 new_session = 1;
870 if (attentions < MAX_ATTENTIONS) {
871 attentions++;
872 continue;
873 }
874 else {
875 retval = (-EIO);
876 break;
877 }
878 }
879
880 if (scode == NOT_READY) {
881 if (waits < max_wait) {
882 if (msleep_interruptible(1000)) {
883 retval = (-EINTR);
884 break;
885 }
886 waits++;
887 continue;
888 }
889 else {
890 if ((STp->device)->scsi_level >= SCSI_2 &&
891 cmdstatp->sense_hdr.asc == 0x3a) /* Check ASC */
892 retval = CHKRES_NO_TAPE;
893 else
894 retval = CHKRES_NOT_READY;
895 break;
896 }
897 }
898 }
899
900 retval = (STp->buffer)->syscall_result;
901 if (!retval)
902 retval = new_session ? CHKRES_NEW_SESSION : CHKRES_READY;
903 break;
904 }
905
906 if (SRpnt != NULL)
Mike Christie8b05b772005-11-08 04:06:44 -0600907 st_release_request(SRpnt);
Linus Torvalds1da177e2005-04-16 15:20:36 -0700908 return retval;
909}
910
911
912/* See if the drive is ready and gather information about the tape. Return values:
913 < 0 negative error code from errno.h
914 0 drive ready
915 1 drive not ready (possibly no tape)
916*/
917static int check_tape(struct scsi_tape *STp, struct file *filp)
918{
919 int i, retval, new_session = 0, do_wait;
920 unsigned char cmd[MAX_COMMAND_SIZE], saved_cleaning;
921 unsigned short st_flags = filp->f_flags;
Mike Christie8b05b772005-11-08 04:06:44 -0600922 struct st_request *SRpnt = NULL;
Linus Torvalds1da177e2005-04-16 15:20:36 -0700923 struct st_modedef *STm;
924 struct st_partstat *STps;
925 char *name = tape_name(STp);
Josef Sipek7ac62072006-12-08 02:37:37 -0800926 struct inode *inode = filp->f_path.dentry->d_inode;
Linus Torvalds1da177e2005-04-16 15:20:36 -0700927 int mode = TAPE_MODE(inode);
928
929 STp->ready = ST_READY;
930
931 if (mode != STp->current_mode) {
932 DEBC(printk(ST_DEB_MSG "%s: Mode change from %d to %d.\n",
933 name, STp->current_mode, mode));
934 new_session = 1;
935 STp->current_mode = mode;
936 }
937 STm = &(STp->modes[STp->current_mode]);
938
939 saved_cleaning = STp->cleaning_req;
940 STp->cleaning_req = 0;
941
942 do_wait = ((filp->f_flags & O_NONBLOCK) == 0);
943 retval = test_ready(STp, do_wait);
944
945 if (retval < 0)
946 goto err_out;
947
948 if (retval == CHKRES_NEW_SESSION) {
949 STp->pos_unknown = 0;
950 STp->partition = STp->new_partition = 0;
951 if (STp->can_partitions)
952 STp->nbr_partitions = 1; /* This guess will be updated later
953 if necessary */
954 for (i = 0; i < ST_NBR_PARTITIONS; i++) {
955 STps = &(STp->ps[i]);
956 STps->rw = ST_IDLE;
957 STps->eof = ST_NOEOF;
958 STps->at_sm = 0;
959 STps->last_block_valid = 0;
960 STps->drv_block = 0;
961 STps->drv_file = 0;
962 }
963 new_session = 1;
964 }
965 else {
966 STp->cleaning_req |= saved_cleaning;
967
968 if (retval == CHKRES_NOT_READY || retval == CHKRES_NO_TAPE) {
969 if (retval == CHKRES_NO_TAPE)
970 STp->ready = ST_NO_TAPE;
971 else
972 STp->ready = ST_NOT_READY;
973
974 STp->density = 0; /* Clear the erroneous "residue" */
975 STp->write_prot = 0;
976 STp->block_size = 0;
977 STp->ps[0].drv_file = STp->ps[0].drv_block = (-1);
978 STp->partition = STp->new_partition = 0;
979 STp->door_locked = ST_UNLOCKED;
980 return CHKRES_NOT_READY;
981 }
982 }
983
984 if (STp->omit_blklims)
985 STp->min_block = STp->max_block = (-1);
986 else {
987 memset((void *) &cmd[0], 0, MAX_COMMAND_SIZE);
988 cmd[0] = READ_BLOCK_LIMITS;
989
990 SRpnt = st_do_scsi(SRpnt, STp, cmd, 6, DMA_FROM_DEVICE,
991 STp->device->timeout, MAX_READY_RETRIES, 1);
992 if (!SRpnt) {
993 retval = (STp->buffer)->syscall_result;
994 goto err_out;
995 }
996
Mike Christie8b05b772005-11-08 04:06:44 -0600997 if (!SRpnt->result && !STp->buffer->cmdstat.have_sense) {
Linus Torvalds1da177e2005-04-16 15:20:36 -0700998 STp->max_block = ((STp->buffer)->b_data[1] << 16) |
999 ((STp->buffer)->b_data[2] << 8) | (STp->buffer)->b_data[3];
1000 STp->min_block = ((STp->buffer)->b_data[4] << 8) |
1001 (STp->buffer)->b_data[5];
1002 if ( DEB( debugging || ) !STp->inited)
Kai Makisara42252852006-11-07 21:56:38 +02001003 printk(KERN_INFO
Linus Torvalds1da177e2005-04-16 15:20:36 -07001004 "%s: Block limits %d - %d bytes.\n", name,
1005 STp->min_block, STp->max_block);
1006 } else {
1007 STp->min_block = STp->max_block = (-1);
1008 DEBC(printk(ST_DEB_MSG "%s: Can't read block limits.\n",
1009 name));
1010 }
1011 }
1012
1013 memset((void *) &cmd[0], 0, MAX_COMMAND_SIZE);
1014 cmd[0] = MODE_SENSE;
1015 cmd[4] = 12;
1016
1017 SRpnt = st_do_scsi(SRpnt, STp, cmd, 12, DMA_FROM_DEVICE,
1018 STp->device->timeout, MAX_READY_RETRIES, 1);
1019 if (!SRpnt) {
1020 retval = (STp->buffer)->syscall_result;
1021 goto err_out;
1022 }
1023
1024 if ((STp->buffer)->syscall_result != 0) {
1025 DEBC(printk(ST_DEB_MSG "%s: No Mode Sense.\n", name));
1026 STp->block_size = ST_DEFAULT_BLOCK; /* Educated guess (?) */
1027 (STp->buffer)->syscall_result = 0; /* Prevent error propagation */
1028 STp->drv_write_prot = 0;
1029 } else {
1030 DEBC(printk(ST_DEB_MSG
1031 "%s: Mode sense. Length %d, medium %x, WBS %x, BLL %d\n",
1032 name,
1033 (STp->buffer)->b_data[0], (STp->buffer)->b_data[1],
1034 (STp->buffer)->b_data[2], (STp->buffer)->b_data[3]));
1035
1036 if ((STp->buffer)->b_data[3] >= 8) {
1037 STp->drv_buffer = ((STp->buffer)->b_data[2] >> 4) & 7;
1038 STp->density = (STp->buffer)->b_data[4];
1039 STp->block_size = (STp->buffer)->b_data[9] * 65536 +
1040 (STp->buffer)->b_data[10] * 256 + (STp->buffer)->b_data[11];
1041 DEBC(printk(ST_DEB_MSG
1042 "%s: Density %x, tape length: %x, drv buffer: %d\n",
1043 name, STp->density, (STp->buffer)->b_data[5] * 65536 +
1044 (STp->buffer)->b_data[6] * 256 + (STp->buffer)->b_data[7],
1045 STp->drv_buffer));
1046 }
1047 STp->drv_write_prot = ((STp->buffer)->b_data[2] & 0x80) != 0;
1048 }
Mike Christie8b05b772005-11-08 04:06:44 -06001049 st_release_request(SRpnt);
Linus Torvalds1da177e2005-04-16 15:20:36 -07001050 SRpnt = NULL;
1051 STp->inited = 1;
1052
1053 if (STp->block_size > 0)
1054 (STp->buffer)->buffer_blocks =
1055 (STp->buffer)->buffer_size / STp->block_size;
1056 else
1057 (STp->buffer)->buffer_blocks = 1;
1058 (STp->buffer)->buffer_bytes = (STp->buffer)->read_pointer = 0;
1059
1060 DEBC(printk(ST_DEB_MSG
1061 "%s: Block size: %d, buffer size: %d (%d blocks).\n", name,
1062 STp->block_size, (STp->buffer)->buffer_size,
1063 (STp->buffer)->buffer_blocks));
1064
1065 if (STp->drv_write_prot) {
1066 STp->write_prot = 1;
1067
1068 DEBC(printk(ST_DEB_MSG "%s: Write protected\n", name));
1069
1070 if (do_wait &&
1071 ((st_flags & O_ACCMODE) == O_WRONLY ||
1072 (st_flags & O_ACCMODE) == O_RDWR)) {
1073 retval = (-EROFS);
1074 goto err_out;
1075 }
1076 }
1077
1078 if (STp->can_partitions && STp->nbr_partitions < 1) {
1079 /* This code is reached when the device is opened for the first time
1080 after the driver has been initialized with tape in the drive and the
1081 partition support has been enabled. */
1082 DEBC(printk(ST_DEB_MSG
1083 "%s: Updating partition number in status.\n", name));
1084 if ((STp->partition = find_partition(STp)) < 0) {
1085 retval = STp->partition;
1086 goto err_out;
1087 }
1088 STp->new_partition = STp->partition;
1089 STp->nbr_partitions = 1; /* This guess will be updated when necessary */
1090 }
1091
1092 if (new_session) { /* Change the drive parameters for the new mode */
1093 STp->density_changed = STp->blksize_changed = 0;
1094 STp->compression_changed = 0;
1095 if (!(STm->defaults_for_writes) &&
1096 (retval = set_mode_densblk(STp, STm)) < 0)
1097 goto err_out;
1098
1099 if (STp->default_drvbuffer != 0xff) {
1100 if (st_int_ioctl(STp, MTSETDRVBUFFER, STp->default_drvbuffer))
1101 printk(KERN_WARNING
1102 "%s: Can't set default drive buffering to %d.\n",
1103 name, STp->default_drvbuffer);
1104 }
1105 }
1106
1107 return CHKRES_READY;
1108
1109 err_out:
1110 return retval;
1111}
1112
1113
1114 /* Open the device. Needs to be called with BKL only because of incrementing the SCSI host
1115 module count. */
1116static int st_open(struct inode *inode, struct file *filp)
1117{
1118 int i, retval = (-EIO);
1119 struct scsi_tape *STp;
1120 struct st_partstat *STps;
1121 int dev = TAPE_NR(inode);
1122 char *name;
1123
1124 /*
1125 * We really want to do nonseekable_open(inode, filp); here, but some
1126 * versions of tar incorrectly call lseek on tapes and bail out if that
1127 * fails. So we disallow pread() and pwrite(), but permit lseeks.
1128 */
1129 filp->f_mode &= ~(FMODE_PREAD | FMODE_PWRITE);
1130
Kai Makisaraf03a5672005-08-02 13:40:47 +03001131 if (!(STp = scsi_tape_get(dev)))
1132 return -ENXIO;
1133
Linus Torvalds1da177e2005-04-16 15:20:36 -07001134 write_lock(&st_dev_arr_lock);
Linus Torvalds1da177e2005-04-16 15:20:36 -07001135 filp->private_data = STp;
1136 name = tape_name(STp);
1137
1138 if (STp->in_use) {
1139 write_unlock(&st_dev_arr_lock);
Kai Makisaraf03a5672005-08-02 13:40:47 +03001140 scsi_tape_put(STp);
Linus Torvalds1da177e2005-04-16 15:20:36 -07001141 DEB( printk(ST_DEB_MSG "%s: Device already in use.\n", name); )
1142 return (-EBUSY);
1143 }
1144
Linus Torvalds1da177e2005-04-16 15:20:36 -07001145 STp->in_use = 1;
1146 write_unlock(&st_dev_arr_lock);
1147 STp->rew_at_close = STp->autorew_dev = (iminor(inode) & 0x80) == 0;
1148
1149 if (!scsi_block_when_processing_errors(STp->device)) {
1150 retval = (-ENXIO);
1151 goto err_out;
1152 }
1153
1154 /* See that we have at least a one page buffer available */
1155 if (!enlarge_buffer(STp->buffer, PAGE_SIZE, STp->restr_dma)) {
1156 printk(KERN_WARNING "%s: Can't allocate one page tape buffer.\n",
1157 name);
1158 retval = (-EOVERFLOW);
1159 goto err_out;
1160 }
1161
1162 (STp->buffer)->writing = 0;
1163 (STp->buffer)->syscall_result = 0;
1164
1165 STp->write_prot = ((filp->f_flags & O_ACCMODE) == O_RDONLY);
1166
1167 STp->dirty = 0;
1168 for (i = 0; i < ST_NBR_PARTITIONS; i++) {
1169 STps = &(STp->ps[i]);
1170 STps->rw = ST_IDLE;
1171 }
Kai Makisara9abe16c2007-02-03 13:21:29 +02001172 STp->try_dio_now = STp->try_dio;
Linus Torvalds1da177e2005-04-16 15:20:36 -07001173 STp->recover_count = 0;
1174 DEB( STp->nbr_waits = STp->nbr_finished = 0;
1175 STp->nbr_requests = STp->nbr_dio = STp->nbr_pages = STp->nbr_combinable = 0; )
1176
1177 retval = check_tape(STp, filp);
1178 if (retval < 0)
1179 goto err_out;
1180 if ((filp->f_flags & O_NONBLOCK) == 0 &&
1181 retval != CHKRES_READY) {
Kai Makisara413f7322006-10-05 22:59:46 +03001182 if (STp->ready == NO_TAPE)
1183 retval = (-ENOMEDIUM);
1184 else
1185 retval = (-EIO);
Linus Torvalds1da177e2005-04-16 15:20:36 -07001186 goto err_out;
1187 }
1188 return 0;
1189
1190 err_out:
1191 normalize_buffer(STp->buffer);
1192 STp->in_use = 0;
Kai Makisaraf03a5672005-08-02 13:40:47 +03001193 scsi_tape_put(STp);
Linus Torvalds1da177e2005-04-16 15:20:36 -07001194 return retval;
1195
1196}
1197
1198
1199/* Flush the tape buffer before close */
Miklos Szeredi75e1fcc2006-06-23 02:05:12 -07001200static int st_flush(struct file *filp, fl_owner_t id)
Linus Torvalds1da177e2005-04-16 15:20:36 -07001201{
1202 int result = 0, result2;
1203 unsigned char cmd[MAX_COMMAND_SIZE];
Mike Christie8b05b772005-11-08 04:06:44 -06001204 struct st_request *SRpnt;
Linus Torvalds1da177e2005-04-16 15:20:36 -07001205 struct scsi_tape *STp = filp->private_data;
1206 struct st_modedef *STm = &(STp->modes[STp->current_mode]);
1207 struct st_partstat *STps = &(STp->ps[STp->partition]);
1208 char *name = tape_name(STp);
1209
1210 if (file_count(filp) > 1)
1211 return 0;
1212
1213 if (STps->rw == ST_WRITING && !STp->pos_unknown) {
1214 result = flush_write_buffer(STp);
1215 if (result != 0 && result != (-ENOSPC))
1216 goto out;
1217 }
1218
1219 if (STp->can_partitions &&
1220 (result2 = switch_partition(STp)) < 0) {
1221 DEBC(printk(ST_DEB_MSG
1222 "%s: switch_partition at close failed.\n", name));
1223 if (result == 0)
1224 result = result2;
1225 goto out;
1226 }
1227
1228 DEBC( if (STp->nbr_requests)
Kai Makisara42252852006-11-07 21:56:38 +02001229 printk(KERN_DEBUG "%s: Number of r/w requests %d, dio used in %d, pages %d (%d).\n",
Linus Torvalds1da177e2005-04-16 15:20:36 -07001230 name, STp->nbr_requests, STp->nbr_dio, STp->nbr_pages, STp->nbr_combinable));
1231
1232 if (STps->rw == ST_WRITING && !STp->pos_unknown) {
1233 struct st_cmdstatus *cmdstatp = &STp->buffer->cmdstat;
1234
1235 DEBC(printk(ST_DEB_MSG "%s: Async write waits %d, finished %d.\n",
1236 name, STp->nbr_waits, STp->nbr_finished);
1237 )
1238
1239 memset(cmd, 0, MAX_COMMAND_SIZE);
1240 cmd[0] = WRITE_FILEMARKS;
1241 cmd[4] = 1 + STp->two_fm;
1242
1243 SRpnt = st_do_scsi(NULL, STp, cmd, 0, DMA_NONE,
1244 STp->device->timeout, MAX_WRITE_RETRIES, 1);
1245 if (!SRpnt) {
1246 result = (STp->buffer)->syscall_result;
1247 goto out;
1248 }
1249
1250 if (STp->buffer->syscall_result == 0 ||
1251 (cmdstatp->have_sense && !cmdstatp->deferred &&
1252 (cmdstatp->flags & SENSE_EOM) &&
1253 (cmdstatp->sense_hdr.sense_key == NO_SENSE ||
1254 cmdstatp->sense_hdr.sense_key == RECOVERED_ERROR) &&
1255 (!cmdstatp->remainder_valid || cmdstatp->uremainder64 == 0))) {
1256 /* Write successful at EOM */
Mike Christie8b05b772005-11-08 04:06:44 -06001257 st_release_request(SRpnt);
Linus Torvalds1da177e2005-04-16 15:20:36 -07001258 SRpnt = NULL;
1259 if (STps->drv_file >= 0)
1260 STps->drv_file++;
1261 STps->drv_block = 0;
1262 if (STp->two_fm)
1263 cross_eof(STp, 0);
1264 STps->eof = ST_FM;
1265 }
1266 else { /* Write error */
Mike Christie8b05b772005-11-08 04:06:44 -06001267 st_release_request(SRpnt);
Linus Torvalds1da177e2005-04-16 15:20:36 -07001268 SRpnt = NULL;
1269 printk(KERN_ERR "%s: Error on write filemark.\n", name);
1270 if (result == 0)
1271 result = (-EIO);
1272 }
1273
1274 DEBC(printk(ST_DEB_MSG "%s: Buffer flushed, %d EOF(s) written\n",
1275 name, cmd[4]));
1276 } else if (!STp->rew_at_close) {
1277 STps = &(STp->ps[STp->partition]);
1278 if (!STm->sysv || STps->rw != ST_READING) {
1279 if (STp->can_bsr)
1280 result = flush_buffer(STp, 0);
1281 else if (STps->eof == ST_FM_HIT) {
1282 result = cross_eof(STp, 0);
1283 if (result) {
1284 if (STps->drv_file >= 0)
1285 STps->drv_file++;
1286 STps->drv_block = 0;
1287 STps->eof = ST_FM;
1288 } else
1289 STps->eof = ST_NOEOF;
1290 }
1291 } else if ((STps->eof == ST_NOEOF &&
1292 !(result = cross_eof(STp, 1))) ||
1293 STps->eof == ST_FM_HIT) {
1294 if (STps->drv_file >= 0)
1295 STps->drv_file++;
1296 STps->drv_block = 0;
1297 STps->eof = ST_FM;
1298 }
1299 }
1300
1301 out:
1302 if (STp->rew_at_close) {
1303 result2 = st_int_ioctl(STp, MTREW, 1);
1304 if (result == 0)
1305 result = result2;
1306 }
1307 return result;
1308}
1309
1310
1311/* Close the device and release it. BKL is not needed: this is the only thread
1312 accessing this tape. */
1313static int st_release(struct inode *inode, struct file *filp)
1314{
1315 int result = 0;
1316 struct scsi_tape *STp = filp->private_data;
1317
1318 if (STp->door_locked == ST_LOCKED_AUTO)
1319 do_door_lock(STp, 0);
1320
1321 normalize_buffer(STp->buffer);
1322 write_lock(&st_dev_arr_lock);
1323 STp->in_use = 0;
1324 write_unlock(&st_dev_arr_lock);
Kai Makisaraf03a5672005-08-02 13:40:47 +03001325 scsi_tape_put(STp);
Linus Torvalds1da177e2005-04-16 15:20:36 -07001326
1327 return result;
1328}
1329
1330/* The checks common to both reading and writing */
1331static ssize_t rw_checks(struct scsi_tape *STp, struct file *filp, size_t count)
1332{
1333 ssize_t retval = 0;
1334
1335 /*
1336 * If we are in the middle of error recovery, don't let anyone
1337 * else try and use this device. Also, if error recovery fails, it
1338 * may try and take the device offline, in which case all further
1339 * access to the device is prohibited.
1340 */
1341 if (!scsi_block_when_processing_errors(STp->device)) {
1342 retval = (-ENXIO);
1343 goto out;
1344 }
1345
1346 if (STp->ready != ST_READY) {
1347 if (STp->ready == ST_NO_TAPE)
1348 retval = (-ENOMEDIUM);
1349 else
1350 retval = (-EIO);
1351 goto out;
1352 }
1353
1354 if (! STp->modes[STp->current_mode].defined) {
1355 retval = (-ENXIO);
1356 goto out;
1357 }
1358
1359
1360 /*
1361 * If there was a bus reset, block further access
1362 * to this device.
1363 */
1364 if (STp->pos_unknown) {
1365 retval = (-EIO);
1366 goto out;
1367 }
1368
1369 if (count == 0)
1370 goto out;
1371
1372 DEB(
1373 if (!STp->in_use) {
1374 printk(ST_DEB_MSG "%s: Incorrect device.\n", tape_name(STp));
1375 retval = (-EIO);
1376 goto out;
1377 } ) /* end DEB */
1378
1379 if (STp->can_partitions &&
1380 (retval = switch_partition(STp)) < 0)
1381 goto out;
1382
1383 if (STp->block_size == 0 && STp->max_block > 0 &&
1384 (count < STp->min_block || count > STp->max_block)) {
1385 retval = (-EINVAL);
1386 goto out;
1387 }
1388
1389 if (STp->do_auto_lock && STp->door_locked == ST_UNLOCKED &&
1390 !do_door_lock(STp, 1))
1391 STp->door_locked = ST_LOCKED_AUTO;
1392
1393 out:
1394 return retval;
1395}
1396
1397
1398static int setup_buffering(struct scsi_tape *STp, const char __user *buf,
1399 size_t count, int is_read)
1400{
1401 int i, bufsize, retval = 0;
1402 struct st_buffer *STbp = STp->buffer;
1403
1404 if (is_read)
Kai Makisara9abe16c2007-02-03 13:21:29 +02001405 i = STp->try_dio_now && try_rdio;
Linus Torvalds1da177e2005-04-16 15:20:36 -07001406 else
Kai Makisara9abe16c2007-02-03 13:21:29 +02001407 i = STp->try_dio_now && try_wdio;
Mike Christie8b05b772005-11-08 04:06:44 -06001408
Linus Torvalds1da177e2005-04-16 15:20:36 -07001409 if (i && ((unsigned long)buf & queue_dma_alignment(
1410 STp->device->request_queue)) == 0) {
Mike Christie8b05b772005-11-08 04:06:44 -06001411 i = sgl_map_user_pages(&(STbp->sg[0]), STbp->use_sg,
1412 (unsigned long)buf, count, (is_read ? READ : WRITE));
Linus Torvalds1da177e2005-04-16 15:20:36 -07001413 if (i > 0) {
1414 STbp->do_dio = i;
1415 STbp->buffer_bytes = 0; /* can be used as transfer counter */
1416 }
1417 else
1418 STbp->do_dio = 0; /* fall back to buffering with any error */
1419 STbp->sg_segs = STbp->do_dio;
1420 STbp->frp_sg_current = 0;
1421 DEB(
1422 if (STbp->do_dio) {
1423 STp->nbr_dio++;
1424 STp->nbr_pages += STbp->do_dio;
1425 for (i=1; i < STbp->do_dio; i++)
1426 if (page_to_pfn(STbp->sg[i].page) == page_to_pfn(STbp->sg[i-1].page) + 1)
1427 STp->nbr_combinable++;
1428 }
1429 )
1430 } else
1431 STbp->do_dio = 0;
1432 DEB( STp->nbr_requests++; )
1433
1434 if (!STbp->do_dio) {
1435 if (STp->block_size)
1436 bufsize = STp->block_size > st_fixed_buffer_size ?
1437 STp->block_size : st_fixed_buffer_size;
1438 else
1439 bufsize = count;
1440 if (bufsize > STbp->buffer_size &&
1441 !enlarge_buffer(STbp, bufsize, STp->restr_dma)) {
1442 printk(KERN_WARNING "%s: Can't allocate %d byte tape buffer.\n",
1443 tape_name(STp), bufsize);
1444 retval = (-EOVERFLOW);
1445 goto out;
1446 }
1447 if (STp->block_size)
1448 STbp->buffer_blocks = bufsize / STp->block_size;
1449 }
1450
1451 out:
1452 return retval;
1453}
1454
1455
1456/* Can be called more than once after each setup_buffer() */
Kai Makisara787926b2005-11-13 10:04:44 +02001457static void release_buffering(struct scsi_tape *STp, int is_read)
Linus Torvalds1da177e2005-04-16 15:20:36 -07001458{
1459 struct st_buffer *STbp;
1460
1461 STbp = STp->buffer;
1462 if (STbp->do_dio) {
Kai Makisara787926b2005-11-13 10:04:44 +02001463 sgl_unmap_user_pages(&(STbp->sg[0]), STbp->do_dio, is_read);
Linus Torvalds1da177e2005-04-16 15:20:36 -07001464 STbp->do_dio = 0;
Kai Makisara787926b2005-11-13 10:04:44 +02001465 STbp->sg_segs = 0;
Linus Torvalds1da177e2005-04-16 15:20:36 -07001466 }
1467}
1468
1469
1470/* Write command */
1471static ssize_t
1472st_write(struct file *filp, const char __user *buf, size_t count, loff_t * ppos)
1473{
1474 ssize_t total;
1475 ssize_t i, do_count, blks, transfer;
1476 ssize_t retval;
1477 int undone, retry_eot = 0, scode;
1478 int async_write;
1479 unsigned char cmd[MAX_COMMAND_SIZE];
1480 const char __user *b_point;
Mike Christie8b05b772005-11-08 04:06:44 -06001481 struct st_request *SRpnt = NULL;
Linus Torvalds1da177e2005-04-16 15:20:36 -07001482 struct scsi_tape *STp = filp->private_data;
1483 struct st_modedef *STm;
1484 struct st_partstat *STps;
1485 struct st_buffer *STbp;
1486 char *name = tape_name(STp);
1487
Matthias Kaehlcke28f85002007-07-29 23:38:15 +02001488 if (mutex_lock_interruptible(&STp->lock))
Linus Torvalds1da177e2005-04-16 15:20:36 -07001489 return -ERESTARTSYS;
1490
1491 retval = rw_checks(STp, filp, count);
1492 if (retval || count == 0)
1493 goto out;
1494
1495 /* Write must be integral number of blocks */
1496 if (STp->block_size != 0 && (count % STp->block_size) != 0) {
1497 printk(KERN_WARNING "%s: Write not multiple of tape block size.\n",
1498 name);
1499 retval = (-EINVAL);
1500 goto out;
1501 }
1502
1503 STm = &(STp->modes[STp->current_mode]);
1504 STps = &(STp->ps[STp->partition]);
1505
1506 if (STp->write_prot) {
1507 retval = (-EACCES);
1508 goto out;
1509 }
1510
1511
1512 if (STps->rw == ST_READING) {
1513 retval = flush_buffer(STp, 0);
1514 if (retval)
1515 goto out;
1516 STps->rw = ST_WRITING;
1517 } else if (STps->rw != ST_WRITING &&
1518 STps->drv_file == 0 && STps->drv_block == 0) {
1519 if ((retval = set_mode_densblk(STp, STm)) < 0)
1520 goto out;
1521 if (STm->default_compression != ST_DONT_TOUCH &&
1522 !(STp->compression_changed)) {
1523 if (st_compression(STp, (STm->default_compression == ST_YES))) {
1524 printk(KERN_WARNING "%s: Can't set default compression.\n",
1525 name);
1526 if (modes_defined) {
1527 retval = (-EINVAL);
1528 goto out;
1529 }
1530 }
1531 }
1532 }
1533
1534 STbp = STp->buffer;
1535 i = write_behind_check(STp);
1536 if (i) {
1537 if (i == -ENOSPC)
1538 STps->eof = ST_EOM_OK;
1539 else
1540 STps->eof = ST_EOM_ERROR;
1541 }
1542
1543 if (STps->eof == ST_EOM_OK) {
1544 STps->eof = ST_EOD_1; /* allow next write */
1545 retval = (-ENOSPC);
1546 goto out;
1547 }
1548 else if (STps->eof == ST_EOM_ERROR) {
1549 retval = (-EIO);
1550 goto out;
1551 }
1552
1553 /* Check the buffer readability in cases where copy_user might catch
1554 the problems after some tape movement. */
1555 if (STp->block_size != 0 &&
1556 !STbp->do_dio &&
1557 (copy_from_user(&i, buf, 1) != 0 ||
1558 copy_from_user(&i, buf + count - 1, 1) != 0)) {
1559 retval = (-EFAULT);
1560 goto out;
1561 }
1562
1563 retval = setup_buffering(STp, buf, count, 0);
1564 if (retval)
1565 goto out;
1566
1567 total = count;
1568
1569 memset(cmd, 0, MAX_COMMAND_SIZE);
1570 cmd[0] = WRITE_6;
1571 cmd[1] = (STp->block_size != 0);
1572
1573 STps->rw = ST_WRITING;
1574
1575 b_point = buf;
1576 while (count > 0 && !retry_eot) {
1577
1578 if (STbp->do_dio) {
1579 do_count = count;
1580 }
1581 else {
1582 if (STp->block_size == 0)
1583 do_count = count;
1584 else {
1585 do_count = STbp->buffer_blocks * STp->block_size -
1586 STbp->buffer_bytes;
1587 if (do_count > count)
1588 do_count = count;
1589 }
1590
1591 i = append_to_buffer(b_point, STbp, do_count);
1592 if (i) {
1593 retval = i;
1594 goto out;
1595 }
1596 }
1597 count -= do_count;
1598 b_point += do_count;
1599
1600 async_write = STp->block_size == 0 && !STbp->do_dio &&
1601 STm->do_async_writes && STps->eof < ST_EOM_OK;
1602
1603 if (STp->block_size != 0 && STm->do_buffer_writes &&
Kai Makisara9abe16c2007-02-03 13:21:29 +02001604 !(STp->try_dio_now && try_wdio) && STps->eof < ST_EOM_OK &&
Linus Torvalds1da177e2005-04-16 15:20:36 -07001605 STbp->buffer_bytes < STbp->buffer_size) {
1606 STp->dirty = 1;
1607 /* Don't write a buffer that is not full enough. */
1608 if (!async_write && count == 0)
1609 break;
1610 }
1611
1612 retry_write:
1613 if (STp->block_size == 0)
1614 blks = transfer = do_count;
1615 else {
1616 if (!STbp->do_dio)
1617 blks = STbp->buffer_bytes;
1618 else
1619 blks = do_count;
1620 blks /= STp->block_size;
1621 transfer = blks * STp->block_size;
1622 }
1623 cmd[2] = blks >> 16;
1624 cmd[3] = blks >> 8;
1625 cmd[4] = blks;
1626
1627 SRpnt = st_do_scsi(SRpnt, STp, cmd, transfer, DMA_TO_DEVICE,
1628 STp->device->timeout, MAX_WRITE_RETRIES, !async_write);
1629 if (!SRpnt) {
1630 retval = STbp->syscall_result;
1631 goto out;
1632 }
Mike Christie8b05b772005-11-08 04:06:44 -06001633 if (async_write && !STbp->syscall_result) {
Linus Torvalds1da177e2005-04-16 15:20:36 -07001634 STbp->writing = transfer;
1635 STp->dirty = !(STbp->writing ==
1636 STbp->buffer_bytes);
1637 SRpnt = NULL; /* Prevent releasing this request! */
1638 DEB( STp->write_pending = 1; )
1639 break;
1640 }
1641
1642 if (STbp->syscall_result != 0) {
1643 struct st_cmdstatus *cmdstatp = &STp->buffer->cmdstat;
1644
1645 DEBC(printk(ST_DEB_MSG "%s: Error on write:\n", name));
1646 if (cmdstatp->have_sense && (cmdstatp->flags & SENSE_EOM)) {
1647 scode = cmdstatp->sense_hdr.sense_key;
1648 if (cmdstatp->remainder_valid)
1649 undone = (int)cmdstatp->uremainder64;
1650 else if (STp->block_size == 0 &&
1651 scode == VOLUME_OVERFLOW)
1652 undone = transfer;
1653 else
1654 undone = 0;
1655 if (STp->block_size != 0)
1656 undone *= STp->block_size;
1657 if (undone <= do_count) {
1658 /* Only data from this write is not written */
1659 count += undone;
1660 do_count -= undone;
1661 if (STp->block_size)
1662 blks = (transfer - undone) / STp->block_size;
1663 STps->eof = ST_EOM_OK;
1664 /* Continue in fixed block mode if all written
1665 in this request but still something left to write
1666 (retval left to zero)
1667 */
1668 if (STp->block_size == 0 ||
1669 undone > 0 || count == 0)
1670 retval = (-ENOSPC); /* EOM within current request */
1671 DEBC(printk(ST_DEB_MSG
1672 "%s: EOM with %d bytes unwritten.\n",
1673 name, (int)count));
1674 } else {
1675 /* EOT within data buffered earlier (possible only
1676 in fixed block mode without direct i/o) */
1677 if (!retry_eot && !cmdstatp->deferred &&
1678 (scode == NO_SENSE || scode == RECOVERED_ERROR)) {
1679 move_buffer_data(STp->buffer, transfer - undone);
1680 retry_eot = 1;
1681 if (STps->drv_block >= 0) {
1682 STps->drv_block += (transfer - undone) /
1683 STp->block_size;
1684 }
1685 STps->eof = ST_EOM_OK;
1686 DEBC(printk(ST_DEB_MSG
1687 "%s: Retry write of %d bytes at EOM.\n",
1688 name, STp->buffer->buffer_bytes));
1689 goto retry_write;
1690 }
1691 else {
1692 /* Either error within data buffered by driver or
1693 failed retry */
1694 count -= do_count;
1695 blks = do_count = 0;
1696 STps->eof = ST_EOM_ERROR;
1697 STps->drv_block = (-1); /* Too cautious? */
1698 retval = (-EIO); /* EOM for old data */
1699 DEBC(printk(ST_DEB_MSG
1700 "%s: EOM with lost data.\n",
1701 name));
1702 }
1703 }
1704 } else {
1705 count += do_count;
1706 STps->drv_block = (-1); /* Too cautious? */
Mike Christie8b05b772005-11-08 04:06:44 -06001707 retval = STbp->syscall_result;
Linus Torvalds1da177e2005-04-16 15:20:36 -07001708 }
1709
1710 }
1711
1712 if (STps->drv_block >= 0) {
1713 if (STp->block_size == 0)
1714 STps->drv_block += (do_count > 0);
1715 else
1716 STps->drv_block += blks;
1717 }
1718
1719 STbp->buffer_bytes = 0;
1720 STp->dirty = 0;
1721
1722 if (retval || retry_eot) {
1723 if (count < total)
1724 retval = total - count;
1725 goto out;
1726 }
1727 }
1728
1729 if (STps->eof == ST_EOD_1)
1730 STps->eof = ST_EOM_OK;
1731 else if (STps->eof != ST_EOM_OK)
1732 STps->eof = ST_NOEOF;
1733 retval = total - count;
1734
1735 out:
1736 if (SRpnt != NULL)
Mike Christie8b05b772005-11-08 04:06:44 -06001737 st_release_request(SRpnt);
Kai Makisara787926b2005-11-13 10:04:44 +02001738 release_buffering(STp, 0);
Matthias Kaehlcke28f85002007-07-29 23:38:15 +02001739 mutex_unlock(&STp->lock);
Linus Torvalds1da177e2005-04-16 15:20:36 -07001740
1741 return retval;
1742}
1743
1744/* Read data from the tape. Returns zero in the normal case, one if the
1745 eof status has changed, and the negative error code in case of a
1746 fatal error. Otherwise updates the buffer and the eof state.
1747
1748 Does release user buffer mapping if it is set.
1749*/
1750static long read_tape(struct scsi_tape *STp, long count,
Mike Christie8b05b772005-11-08 04:06:44 -06001751 struct st_request ** aSRpnt)
Linus Torvalds1da177e2005-04-16 15:20:36 -07001752{
1753 int transfer, blks, bytes;
1754 unsigned char cmd[MAX_COMMAND_SIZE];
Mike Christie8b05b772005-11-08 04:06:44 -06001755 struct st_request *SRpnt;
Linus Torvalds1da177e2005-04-16 15:20:36 -07001756 struct st_modedef *STm;
1757 struct st_partstat *STps;
1758 struct st_buffer *STbp;
1759 int retval = 0;
1760 char *name = tape_name(STp);
1761
1762 if (count == 0)
1763 return 0;
1764
1765 STm = &(STp->modes[STp->current_mode]);
1766 STps = &(STp->ps[STp->partition]);
1767 if (STps->eof == ST_FM_HIT)
1768 return 1;
1769 STbp = STp->buffer;
1770
1771 if (STp->block_size == 0)
1772 blks = bytes = count;
1773 else {
Kai Makisara9abe16c2007-02-03 13:21:29 +02001774 if (!(STp->try_dio_now && try_rdio) && STm->do_read_ahead) {
Linus Torvalds1da177e2005-04-16 15:20:36 -07001775 blks = (STp->buffer)->buffer_blocks;
1776 bytes = blks * STp->block_size;
1777 } else {
1778 bytes = count;
1779 if (!STbp->do_dio && bytes > (STp->buffer)->buffer_size)
1780 bytes = (STp->buffer)->buffer_size;
1781 blks = bytes / STp->block_size;
1782 bytes = blks * STp->block_size;
1783 }
1784 }
1785
1786 memset(cmd, 0, MAX_COMMAND_SIZE);
1787 cmd[0] = READ_6;
1788 cmd[1] = (STp->block_size != 0);
1789 cmd[2] = blks >> 16;
1790 cmd[3] = blks >> 8;
1791 cmd[4] = blks;
1792
1793 SRpnt = *aSRpnt;
1794 SRpnt = st_do_scsi(SRpnt, STp, cmd, bytes, DMA_FROM_DEVICE,
1795 STp->device->timeout, MAX_RETRIES, 1);
Kai Makisara787926b2005-11-13 10:04:44 +02001796 release_buffering(STp, 1);
Linus Torvalds1da177e2005-04-16 15:20:36 -07001797 *aSRpnt = SRpnt;
1798 if (!SRpnt)
1799 return STbp->syscall_result;
1800
1801 STbp->read_pointer = 0;
1802 STps->at_sm = 0;
1803
1804 /* Something to check */
1805 if (STbp->syscall_result) {
1806 struct st_cmdstatus *cmdstatp = &STp->buffer->cmdstat;
1807
1808 retval = 1;
1809 DEBC(printk(ST_DEB_MSG "%s: Sense: %2x %2x %2x %2x %2x %2x %2x %2x\n",
1810 name,
Mike Christie8b05b772005-11-08 04:06:44 -06001811 SRpnt->sense[0], SRpnt->sense[1],
1812 SRpnt->sense[2], SRpnt->sense[3],
1813 SRpnt->sense[4], SRpnt->sense[5],
1814 SRpnt->sense[6], SRpnt->sense[7]));
Linus Torvalds1da177e2005-04-16 15:20:36 -07001815 if (cmdstatp->have_sense) {
1816
1817 if (cmdstatp->sense_hdr.sense_key == BLANK_CHECK)
1818 cmdstatp->flags &= 0xcf; /* No need for EOM in this case */
1819
1820 if (cmdstatp->flags != 0) { /* EOF, EOM, or ILI */
1821 /* Compute the residual count */
1822 if (cmdstatp->remainder_valid)
1823 transfer = (int)cmdstatp->uremainder64;
1824 else
1825 transfer = 0;
1826 if (STp->block_size == 0 &&
1827 cmdstatp->sense_hdr.sense_key == MEDIUM_ERROR)
1828 transfer = bytes;
1829
1830 if (cmdstatp->flags & SENSE_ILI) { /* ILI */
1831 if (STp->block_size == 0) {
1832 if (transfer <= 0) {
1833 if (transfer < 0)
1834 printk(KERN_NOTICE
1835 "%s: Failed to read %d byte block with %d byte transfer.\n",
1836 name, bytes - transfer, bytes);
1837 if (STps->drv_block >= 0)
1838 STps->drv_block += 1;
1839 STbp->buffer_bytes = 0;
1840 return (-ENOMEM);
1841 }
1842 STbp->buffer_bytes = bytes - transfer;
1843 } else {
Mike Christie8b05b772005-11-08 04:06:44 -06001844 st_release_request(SRpnt);
Linus Torvalds1da177e2005-04-16 15:20:36 -07001845 SRpnt = *aSRpnt = NULL;
1846 if (transfer == blks) { /* We did not get anything, error */
1847 printk(KERN_NOTICE "%s: Incorrect block size.\n", name);
1848 if (STps->drv_block >= 0)
1849 STps->drv_block += blks - transfer + 1;
1850 st_int_ioctl(STp, MTBSR, 1);
1851 return (-EIO);
1852 }
1853 /* We have some data, deliver it */
1854 STbp->buffer_bytes = (blks - transfer) *
1855 STp->block_size;
1856 DEBC(printk(ST_DEB_MSG
1857 "%s: ILI but enough data received %ld %d.\n",
1858 name, count, STbp->buffer_bytes));
1859 if (STps->drv_block >= 0)
1860 STps->drv_block += 1;
1861 if (st_int_ioctl(STp, MTBSR, 1))
1862 return (-EIO);
1863 }
1864 } else if (cmdstatp->flags & SENSE_FMK) { /* FM overrides EOM */
1865 if (STps->eof != ST_FM_HIT)
1866 STps->eof = ST_FM_HIT;
1867 else
1868 STps->eof = ST_EOD_2;
1869 if (STp->block_size == 0)
1870 STbp->buffer_bytes = 0;
1871 else
1872 STbp->buffer_bytes =
1873 bytes - transfer * STp->block_size;
1874 DEBC(printk(ST_DEB_MSG
1875 "%s: EOF detected (%d bytes read).\n",
1876 name, STbp->buffer_bytes));
1877 } else if (cmdstatp->flags & SENSE_EOM) {
1878 if (STps->eof == ST_FM)
1879 STps->eof = ST_EOD_1;
1880 else
1881 STps->eof = ST_EOM_OK;
1882 if (STp->block_size == 0)
1883 STbp->buffer_bytes = bytes - transfer;
1884 else
1885 STbp->buffer_bytes =
1886 bytes - transfer * STp->block_size;
1887
1888 DEBC(printk(ST_DEB_MSG "%s: EOM detected (%d bytes read).\n",
1889 name, STbp->buffer_bytes));
1890 }
1891 }
1892 /* end of EOF, EOM, ILI test */
1893 else { /* nonzero sense key */
1894 DEBC(printk(ST_DEB_MSG
1895 "%s: Tape error while reading.\n", name));
1896 STps->drv_block = (-1);
1897 if (STps->eof == ST_FM &&
1898 cmdstatp->sense_hdr.sense_key == BLANK_CHECK) {
1899 DEBC(printk(ST_DEB_MSG
1900 "%s: Zero returned for first BLANK CHECK after EOF.\n",
1901 name));
1902 STps->eof = ST_EOD_2; /* First BLANK_CHECK after FM */
1903 } else /* Some other extended sense code */
1904 retval = (-EIO);
1905 }
1906
1907 if (STbp->buffer_bytes < 0) /* Caused by bogus sense data */
1908 STbp->buffer_bytes = 0;
1909 }
1910 /* End of extended sense test */
1911 else { /* Non-extended sense */
1912 retval = STbp->syscall_result;
1913 }
1914
1915 }
1916 /* End of error handling */
1917 else /* Read successful */
1918 STbp->buffer_bytes = bytes;
1919
1920 if (STps->drv_block >= 0) {
1921 if (STp->block_size == 0)
1922 STps->drv_block++;
1923 else
1924 STps->drv_block += STbp->buffer_bytes / STp->block_size;
1925 }
1926 return retval;
1927}
1928
1929
1930/* Read command */
1931static ssize_t
1932st_read(struct file *filp, char __user *buf, size_t count, loff_t * ppos)
1933{
1934 ssize_t total;
1935 ssize_t retval = 0;
1936 ssize_t i, transfer;
1937 int special, do_dio = 0;
Mike Christie8b05b772005-11-08 04:06:44 -06001938 struct st_request *SRpnt = NULL;
Linus Torvalds1da177e2005-04-16 15:20:36 -07001939 struct scsi_tape *STp = filp->private_data;
1940 struct st_modedef *STm;
1941 struct st_partstat *STps;
1942 struct st_buffer *STbp = STp->buffer;
1943 DEB( char *name = tape_name(STp); )
1944
Matthias Kaehlcke28f85002007-07-29 23:38:15 +02001945 if (mutex_lock_interruptible(&STp->lock))
Linus Torvalds1da177e2005-04-16 15:20:36 -07001946 return -ERESTARTSYS;
1947
1948 retval = rw_checks(STp, filp, count);
1949 if (retval || count == 0)
1950 goto out;
1951
1952 STm = &(STp->modes[STp->current_mode]);
Kai Makisara9abe16c2007-02-03 13:21:29 +02001953 if (STp->block_size != 0 && (count % STp->block_size) != 0) {
1954 if (!STm->do_read_ahead) {
1955 retval = (-EINVAL); /* Read must be integral number of blocks */
1956 goto out;
1957 }
1958 STp->try_dio_now = 0; /* Direct i/o can't handle split blocks */
Linus Torvalds1da177e2005-04-16 15:20:36 -07001959 }
1960
1961 STps = &(STp->ps[STp->partition]);
1962 if (STps->rw == ST_WRITING) {
1963 retval = flush_buffer(STp, 0);
1964 if (retval)
1965 goto out;
1966 STps->rw = ST_READING;
1967 }
1968 DEB(
1969 if (debugging && STps->eof != ST_NOEOF)
1970 printk(ST_DEB_MSG "%s: EOF/EOM flag up (%d). Bytes %d\n", name,
1971 STps->eof, STbp->buffer_bytes);
1972 ) /* end DEB */
1973
1974 retval = setup_buffering(STp, buf, count, 1);
1975 if (retval)
1976 goto out;
1977 do_dio = STbp->do_dio;
1978
1979 if (STbp->buffer_bytes == 0 &&
1980 STps->eof >= ST_EOD_1) {
1981 if (STps->eof < ST_EOD) {
1982 STps->eof += 1;
1983 retval = 0;
1984 goto out;
1985 }
1986 retval = (-EIO); /* EOM or Blank Check */
1987 goto out;
1988 }
1989
1990 if (do_dio) {
1991 /* Check the buffer writability before any tape movement. Don't alter
1992 buffer data. */
1993 if (copy_from_user(&i, buf, 1) != 0 ||
1994 copy_to_user(buf, &i, 1) != 0 ||
1995 copy_from_user(&i, buf + count - 1, 1) != 0 ||
1996 copy_to_user(buf + count - 1, &i, 1) != 0) {
1997 retval = (-EFAULT);
1998 goto out;
1999 }
2000 }
2001
2002 STps->rw = ST_READING;
2003
2004
2005 /* Loop until enough data in buffer or a special condition found */
2006 for (total = 0, special = 0; total < count && !special;) {
2007
2008 /* Get new data if the buffer is empty */
2009 if (STbp->buffer_bytes == 0) {
2010 special = read_tape(STp, count - total, &SRpnt);
2011 if (special < 0) { /* No need to continue read */
2012 retval = special;
2013 goto out;
2014 }
2015 }
2016
2017 /* Move the data from driver buffer to user buffer */
2018 if (STbp->buffer_bytes > 0) {
2019 DEB(
2020 if (debugging && STps->eof != ST_NOEOF)
2021 printk(ST_DEB_MSG
2022 "%s: EOF up (%d). Left %d, needed %d.\n", name,
2023 STps->eof, STbp->buffer_bytes,
2024 (int)(count - total));
2025 ) /* end DEB */
2026 transfer = STbp->buffer_bytes < count - total ?
2027 STbp->buffer_bytes : count - total;
2028 if (!do_dio) {
2029 i = from_buffer(STbp, buf, transfer);
2030 if (i) {
2031 retval = i;
2032 goto out;
2033 }
2034 }
2035 buf += transfer;
2036 total += transfer;
2037 }
2038
2039 if (STp->block_size == 0)
2040 break; /* Read only one variable length block */
2041
2042 } /* for (total = 0, special = 0;
2043 total < count && !special; ) */
2044
2045 /* Change the eof state if no data from tape or buffer */
2046 if (total == 0) {
2047 if (STps->eof == ST_FM_HIT) {
2048 STps->eof = ST_FM;
2049 STps->drv_block = 0;
2050 if (STps->drv_file >= 0)
2051 STps->drv_file++;
2052 } else if (STps->eof == ST_EOD_1) {
2053 STps->eof = ST_EOD_2;
2054 STps->drv_block = 0;
2055 if (STps->drv_file >= 0)
2056 STps->drv_file++;
2057 } else if (STps->eof == ST_EOD_2)
2058 STps->eof = ST_EOD;
2059 } else if (STps->eof == ST_FM)
2060 STps->eof = ST_NOEOF;
2061 retval = total;
2062
2063 out:
2064 if (SRpnt != NULL) {
Mike Christie8b05b772005-11-08 04:06:44 -06002065 st_release_request(SRpnt);
Linus Torvalds1da177e2005-04-16 15:20:36 -07002066 SRpnt = NULL;
2067 }
2068 if (do_dio) {
Kai Makisara787926b2005-11-13 10:04:44 +02002069 release_buffering(STp, 1);
Linus Torvalds1da177e2005-04-16 15:20:36 -07002070 STbp->buffer_bytes = 0;
2071 }
Matthias Kaehlcke28f85002007-07-29 23:38:15 +02002072 mutex_unlock(&STp->lock);
Linus Torvalds1da177e2005-04-16 15:20:36 -07002073
2074 return retval;
2075}
2076
2077
2078
2079DEB(
2080/* Set the driver options */
2081static void st_log_options(struct scsi_tape * STp, struct st_modedef * STm, char *name)
2082{
2083 if (debugging) {
2084 printk(KERN_INFO
2085 "%s: Mode %d options: buffer writes: %d, async writes: %d, read ahead: %d\n",
2086 name, STp->current_mode, STm->do_buffer_writes, STm->do_async_writes,
2087 STm->do_read_ahead);
2088 printk(KERN_INFO
2089 "%s: can bsr: %d, two FMs: %d, fast mteom: %d, auto lock: %d,\n",
2090 name, STp->can_bsr, STp->two_fm, STp->fast_mteom, STp->do_auto_lock);
2091 printk(KERN_INFO
2092 "%s: defs for wr: %d, no block limits: %d, partitions: %d, s2 log: %d\n",
2093 name, STm->defaults_for_writes, STp->omit_blklims, STp->can_partitions,
2094 STp->scsi2_logical);
2095 printk(KERN_INFO
2096 "%s: sysv: %d nowait: %d\n", name, STm->sysv, STp->immediate);
2097 printk(KERN_INFO "%s: debugging: %d\n",
2098 name, debugging);
2099 }
2100}
2101 )
2102
2103
2104static int st_set_options(struct scsi_tape *STp, long options)
2105{
2106 int value;
2107 long code;
2108 struct st_modedef *STm;
2109 char *name = tape_name(STp);
2110 struct cdev *cd0, *cd1;
2111
2112 STm = &(STp->modes[STp->current_mode]);
2113 if (!STm->defined) {
2114 cd0 = STm->cdevs[0]; cd1 = STm->cdevs[1];
2115 memcpy(STm, &(STp->modes[0]), sizeof(struct st_modedef));
2116 STm->cdevs[0] = cd0; STm->cdevs[1] = cd1;
2117 modes_defined = 1;
2118 DEBC(printk(ST_DEB_MSG
2119 "%s: Initialized mode %d definition from mode 0\n",
2120 name, STp->current_mode));
2121 }
2122
2123 code = options & MT_ST_OPTIONS;
2124 if (code == MT_ST_BOOLEANS) {
2125 STm->do_buffer_writes = (options & MT_ST_BUFFER_WRITES) != 0;
2126 STm->do_async_writes = (options & MT_ST_ASYNC_WRITES) != 0;
2127 STm->defaults_for_writes = (options & MT_ST_DEF_WRITES) != 0;
2128 STm->do_read_ahead = (options & MT_ST_READ_AHEAD) != 0;
2129 STp->two_fm = (options & MT_ST_TWO_FM) != 0;
2130 STp->fast_mteom = (options & MT_ST_FAST_MTEOM) != 0;
2131 STp->do_auto_lock = (options & MT_ST_AUTO_LOCK) != 0;
2132 STp->can_bsr = (options & MT_ST_CAN_BSR) != 0;
2133 STp->omit_blklims = (options & MT_ST_NO_BLKLIMS) != 0;
2134 if ((STp->device)->scsi_level >= SCSI_2)
2135 STp->can_partitions = (options & MT_ST_CAN_PARTITIONS) != 0;
2136 STp->scsi2_logical = (options & MT_ST_SCSI2LOGICAL) != 0;
2137 STp->immediate = (options & MT_ST_NOWAIT) != 0;
2138 STm->sysv = (options & MT_ST_SYSV) != 0;
2139 DEB( debugging = (options & MT_ST_DEBUGGING) != 0;
2140 st_log_options(STp, STm, name); )
2141 } else if (code == MT_ST_SETBOOLEANS || code == MT_ST_CLEARBOOLEANS) {
2142 value = (code == MT_ST_SETBOOLEANS);
2143 if ((options & MT_ST_BUFFER_WRITES) != 0)
2144 STm->do_buffer_writes = value;
2145 if ((options & MT_ST_ASYNC_WRITES) != 0)
2146 STm->do_async_writes = value;
2147 if ((options & MT_ST_DEF_WRITES) != 0)
2148 STm->defaults_for_writes = value;
2149 if ((options & MT_ST_READ_AHEAD) != 0)
2150 STm->do_read_ahead = value;
2151 if ((options & MT_ST_TWO_FM) != 0)
2152 STp->two_fm = value;
2153 if ((options & MT_ST_FAST_MTEOM) != 0)
2154 STp->fast_mteom = value;
2155 if ((options & MT_ST_AUTO_LOCK) != 0)
2156 STp->do_auto_lock = value;
2157 if ((options & MT_ST_CAN_BSR) != 0)
2158 STp->can_bsr = value;
2159 if ((options & MT_ST_NO_BLKLIMS) != 0)
2160 STp->omit_blklims = value;
2161 if ((STp->device)->scsi_level >= SCSI_2 &&
2162 (options & MT_ST_CAN_PARTITIONS) != 0)
2163 STp->can_partitions = value;
2164 if ((options & MT_ST_SCSI2LOGICAL) != 0)
2165 STp->scsi2_logical = value;
2166 if ((options & MT_ST_NOWAIT) != 0)
2167 STp->immediate = value;
2168 if ((options & MT_ST_SYSV) != 0)
2169 STm->sysv = value;
2170 DEB(
2171 if ((options & MT_ST_DEBUGGING) != 0)
2172 debugging = value;
2173 st_log_options(STp, STm, name); )
2174 } else if (code == MT_ST_WRITE_THRESHOLD) {
2175 /* Retained for compatibility */
2176 } else if (code == MT_ST_DEF_BLKSIZE) {
2177 value = (options & ~MT_ST_OPTIONS);
2178 if (value == ~MT_ST_OPTIONS) {
2179 STm->default_blksize = (-1);
2180 DEBC( printk(KERN_INFO "%s: Default block size disabled.\n", name));
2181 } else {
2182 STm->default_blksize = value;
2183 DEBC( printk(KERN_INFO "%s: Default block size set to %d bytes.\n",
2184 name, STm->default_blksize));
2185 if (STp->ready == ST_READY) {
2186 STp->blksize_changed = 0;
2187 set_mode_densblk(STp, STm);
2188 }
2189 }
2190 } else if (code == MT_ST_TIMEOUTS) {
2191 value = (options & ~MT_ST_OPTIONS);
2192 if ((value & MT_ST_SET_LONG_TIMEOUT) != 0) {
2193 STp->long_timeout = (value & ~MT_ST_SET_LONG_TIMEOUT) * HZ;
2194 DEBC( printk(KERN_INFO "%s: Long timeout set to %d seconds.\n", name,
2195 (value & ~MT_ST_SET_LONG_TIMEOUT)));
2196 } else {
2197 STp->device->timeout = value * HZ;
2198 DEBC( printk(KERN_INFO "%s: Normal timeout set to %d seconds.\n",
2199 name, value) );
2200 }
2201 } else if (code == MT_ST_SET_CLN) {
2202 value = (options & ~MT_ST_OPTIONS) & 0xff;
2203 if (value != 0 &&
2204 value < EXTENDED_SENSE_START && value >= SCSI_SENSE_BUFFERSIZE)
2205 return (-EINVAL);
2206 STp->cln_mode = value;
2207 STp->cln_sense_mask = (options >> 8) & 0xff;
2208 STp->cln_sense_value = (options >> 16) & 0xff;
2209 printk(KERN_INFO
2210 "%s: Cleaning request mode %d, mask %02x, value %02x\n",
2211 name, value, STp->cln_sense_mask, STp->cln_sense_value);
2212 } else if (code == MT_ST_DEF_OPTIONS) {
2213 code = (options & ~MT_ST_CLEAR_DEFAULT);
2214 value = (options & MT_ST_CLEAR_DEFAULT);
2215 if (code == MT_ST_DEF_DENSITY) {
2216 if (value == MT_ST_CLEAR_DEFAULT) {
2217 STm->default_density = (-1);
2218 DEBC( printk(KERN_INFO "%s: Density default disabled.\n",
2219 name));
2220 } else {
2221 STm->default_density = value & 0xff;
2222 DEBC( printk(KERN_INFO "%s: Density default set to %x\n",
2223 name, STm->default_density));
2224 if (STp->ready == ST_READY) {
2225 STp->density_changed = 0;
2226 set_mode_densblk(STp, STm);
2227 }
2228 }
2229 } else if (code == MT_ST_DEF_DRVBUFFER) {
2230 if (value == MT_ST_CLEAR_DEFAULT) {
2231 STp->default_drvbuffer = 0xff;
2232 DEBC( printk(KERN_INFO
2233 "%s: Drive buffer default disabled.\n", name));
2234 } else {
2235 STp->default_drvbuffer = value & 7;
2236 DEBC( printk(KERN_INFO
2237 "%s: Drive buffer default set to %x\n",
2238 name, STp->default_drvbuffer));
2239 if (STp->ready == ST_READY)
2240 st_int_ioctl(STp, MTSETDRVBUFFER, STp->default_drvbuffer);
2241 }
2242 } else if (code == MT_ST_DEF_COMPRESSION) {
2243 if (value == MT_ST_CLEAR_DEFAULT) {
2244 STm->default_compression = ST_DONT_TOUCH;
2245 DEBC( printk(KERN_INFO
2246 "%s: Compression default disabled.\n", name));
2247 } else {
2248 if ((value & 0xff00) != 0) {
2249 STp->c_algo = (value & 0xff00) >> 8;
2250 DEBC( printk(KERN_INFO "%s: Compression algorithm set to 0x%x.\n",
2251 name, STp->c_algo));
2252 }
2253 if ((value & 0xff) != 0xff) {
2254 STm->default_compression = (value & 1 ? ST_YES : ST_NO);
2255 DEBC( printk(KERN_INFO "%s: Compression default set to %x\n",
2256 name, (value & 1)));
2257 if (STp->ready == ST_READY) {
2258 STp->compression_changed = 0;
2259 st_compression(STp, (STm->default_compression == ST_YES));
2260 }
2261 }
2262 }
2263 }
2264 } else
2265 return (-EIO);
2266
2267 return 0;
2268}
2269
2270#define MODE_HEADER_LENGTH 4
2271
2272/* Mode header and page byte offsets */
2273#define MH_OFF_DATA_LENGTH 0
2274#define MH_OFF_MEDIUM_TYPE 1
2275#define MH_OFF_DEV_SPECIFIC 2
2276#define MH_OFF_BDESCS_LENGTH 3
2277#define MP_OFF_PAGE_NBR 0
2278#define MP_OFF_PAGE_LENGTH 1
2279
2280/* Mode header and page bit masks */
2281#define MH_BIT_WP 0x80
2282#define MP_MSK_PAGE_NBR 0x3f
2283
2284/* Don't return block descriptors */
2285#define MODE_SENSE_OMIT_BDESCS 0x08
2286
2287#define MODE_SELECT_PAGE_FORMAT 0x10
2288
2289/* Read a mode page into the tape buffer. The block descriptors are included
2290 if incl_block_descs is true. The page control is ored to the page number
2291 parameter, if necessary. */
2292static int read_mode_page(struct scsi_tape *STp, int page, int omit_block_descs)
2293{
2294 unsigned char cmd[MAX_COMMAND_SIZE];
Mike Christie8b05b772005-11-08 04:06:44 -06002295 struct st_request *SRpnt = NULL;
Linus Torvalds1da177e2005-04-16 15:20:36 -07002296
2297 memset(cmd, 0, MAX_COMMAND_SIZE);
2298 cmd[0] = MODE_SENSE;
2299 if (omit_block_descs)
2300 cmd[1] = MODE_SENSE_OMIT_BDESCS;
2301 cmd[2] = page;
2302 cmd[4] = 255;
2303
2304 SRpnt = st_do_scsi(SRpnt, STp, cmd, cmd[4], DMA_FROM_DEVICE,
2305 STp->device->timeout, 0, 1);
2306 if (SRpnt == NULL)
2307 return (STp->buffer)->syscall_result;
2308
Mike Christie8b05b772005-11-08 04:06:44 -06002309 st_release_request(SRpnt);
Linus Torvalds1da177e2005-04-16 15:20:36 -07002310
2311 return (STp->buffer)->syscall_result;
2312}
2313
2314
2315/* Send the mode page in the tape buffer to the drive. Assumes that the mode data
2316 in the buffer is correctly formatted. The long timeout is used if slow is non-zero. */
2317static int write_mode_page(struct scsi_tape *STp, int page, int slow)
2318{
2319 int pgo;
2320 unsigned char cmd[MAX_COMMAND_SIZE];
Mike Christie8b05b772005-11-08 04:06:44 -06002321 struct st_request *SRpnt = NULL;
Linus Torvalds1da177e2005-04-16 15:20:36 -07002322
2323 memset(cmd, 0, MAX_COMMAND_SIZE);
2324 cmd[0] = MODE_SELECT;
2325 cmd[1] = MODE_SELECT_PAGE_FORMAT;
2326 pgo = MODE_HEADER_LENGTH + (STp->buffer)->b_data[MH_OFF_BDESCS_LENGTH];
2327 cmd[4] = pgo + (STp->buffer)->b_data[pgo + MP_OFF_PAGE_LENGTH] + 2;
2328
2329 /* Clear reserved fields */
2330 (STp->buffer)->b_data[MH_OFF_DATA_LENGTH] = 0;
2331 (STp->buffer)->b_data[MH_OFF_MEDIUM_TYPE] = 0;
2332 (STp->buffer)->b_data[MH_OFF_DEV_SPECIFIC] &= ~MH_BIT_WP;
2333 (STp->buffer)->b_data[pgo + MP_OFF_PAGE_NBR] &= MP_MSK_PAGE_NBR;
2334
2335 SRpnt = st_do_scsi(SRpnt, STp, cmd, cmd[4], DMA_TO_DEVICE,
2336 (slow ? STp->long_timeout : STp->device->timeout), 0, 1);
2337 if (SRpnt == NULL)
2338 return (STp->buffer)->syscall_result;
2339
Mike Christie8b05b772005-11-08 04:06:44 -06002340 st_release_request(SRpnt);
Linus Torvalds1da177e2005-04-16 15:20:36 -07002341
2342 return (STp->buffer)->syscall_result;
2343}
2344
2345
2346#define COMPRESSION_PAGE 0x0f
2347#define COMPRESSION_PAGE_LENGTH 16
2348
2349#define CP_OFF_DCE_DCC 2
2350#define CP_OFF_C_ALGO 7
2351
2352#define DCE_MASK 0x80
2353#define DCC_MASK 0x40
2354#define RED_MASK 0x60
2355
2356
2357/* Control the compression with mode page 15. Algorithm not changed if zero.
2358
2359 The block descriptors are read and written because Sony SDT-7000 does not
2360 work without this (suggestion from Michael Schaefer <Michael.Schaefer@dlr.de>).
2361 Including block descriptors should not cause any harm to other drives. */
2362
2363static int st_compression(struct scsi_tape * STp, int state)
2364{
2365 int retval;
2366 int mpoffs; /* Offset to mode page start */
2367 unsigned char *b_data = (STp->buffer)->b_data;
2368 DEB( char *name = tape_name(STp); )
2369
2370 if (STp->ready != ST_READY)
2371 return (-EIO);
2372
2373 /* Read the current page contents */
2374 retval = read_mode_page(STp, COMPRESSION_PAGE, 0);
2375 if (retval) {
2376 DEBC(printk(ST_DEB_MSG "%s: Compression mode page not supported.\n",
2377 name));
2378 return (-EIO);
2379 }
2380
2381 mpoffs = MODE_HEADER_LENGTH + b_data[MH_OFF_BDESCS_LENGTH];
2382 DEBC(printk(ST_DEB_MSG "%s: Compression state is %d.\n", name,
2383 (b_data[mpoffs + CP_OFF_DCE_DCC] & DCE_MASK ? 1 : 0)));
2384
2385 /* Check if compression can be changed */
2386 if ((b_data[mpoffs + CP_OFF_DCE_DCC] & DCC_MASK) == 0) {
2387 DEBC(printk(ST_DEB_MSG "%s: Compression not supported.\n", name));
2388 return (-EIO);
2389 }
2390
2391 /* Do the change */
2392 if (state) {
2393 b_data[mpoffs + CP_OFF_DCE_DCC] |= DCE_MASK;
2394 if (STp->c_algo != 0)
2395 b_data[mpoffs + CP_OFF_C_ALGO] = STp->c_algo;
2396 }
2397 else {
2398 b_data[mpoffs + CP_OFF_DCE_DCC] &= ~DCE_MASK;
2399 if (STp->c_algo != 0)
2400 b_data[mpoffs + CP_OFF_C_ALGO] = 0; /* no compression */
2401 }
2402
2403 retval = write_mode_page(STp, COMPRESSION_PAGE, 0);
2404 if (retval) {
2405 DEBC(printk(ST_DEB_MSG "%s: Compression change failed.\n", name));
2406 return (-EIO);
2407 }
2408 DEBC(printk(ST_DEB_MSG "%s: Compression state changed to %d.\n",
2409 name, state));
2410
2411 STp->compression_changed = 1;
2412 return 0;
2413}
2414
2415
2416/* Process the load and unload commands (does unload if the load code is zero) */
2417static int do_load_unload(struct scsi_tape *STp, struct file *filp, int load_code)
2418{
2419 int retval = (-EIO), timeout;
2420 DEB( char *name = tape_name(STp); )
2421 unsigned char cmd[MAX_COMMAND_SIZE];
2422 struct st_partstat *STps;
Mike Christie8b05b772005-11-08 04:06:44 -06002423 struct st_request *SRpnt;
Linus Torvalds1da177e2005-04-16 15:20:36 -07002424
2425 if (STp->ready != ST_READY && !load_code) {
2426 if (STp->ready == ST_NO_TAPE)
2427 return (-ENOMEDIUM);
2428 else
2429 return (-EIO);
2430 }
2431
2432 memset(cmd, 0, MAX_COMMAND_SIZE);
2433 cmd[0] = START_STOP;
2434 if (load_code)
2435 cmd[4] |= 1;
2436 /*
2437 * If arg >= 1 && arg <= 6 Enhanced load/unload in HP C1553A
2438 */
2439 if (load_code >= 1 + MT_ST_HPLOADER_OFFSET
2440 && load_code <= 6 + MT_ST_HPLOADER_OFFSET) {
2441 DEBC(printk(ST_DEB_MSG "%s: Enhanced %sload slot %2d.\n",
2442 name, (cmd[4]) ? "" : "un",
2443 load_code - MT_ST_HPLOADER_OFFSET));
2444 cmd[3] = load_code - MT_ST_HPLOADER_OFFSET; /* MediaID field of C1553A */
2445 }
2446 if (STp->immediate) {
2447 cmd[1] = 1; /* Don't wait for completion */
2448 timeout = STp->device->timeout;
2449 }
2450 else
2451 timeout = STp->long_timeout;
2452
2453 DEBC(
2454 if (!load_code)
2455 printk(ST_DEB_MSG "%s: Unloading tape.\n", name);
2456 else
2457 printk(ST_DEB_MSG "%s: Loading tape.\n", name);
2458 );
2459
2460 SRpnt = st_do_scsi(NULL, STp, cmd, 0, DMA_NONE,
2461 timeout, MAX_RETRIES, 1);
2462 if (!SRpnt)
2463 return (STp->buffer)->syscall_result;
2464
2465 retval = (STp->buffer)->syscall_result;
Mike Christie8b05b772005-11-08 04:06:44 -06002466 st_release_request(SRpnt);
Linus Torvalds1da177e2005-04-16 15:20:36 -07002467
2468 if (!retval) { /* SCSI command successful */
2469
2470 if (!load_code) {
2471 STp->rew_at_close = 0;
2472 STp->ready = ST_NO_TAPE;
2473 }
2474 else {
2475 STp->rew_at_close = STp->autorew_dev;
2476 retval = check_tape(STp, filp);
2477 if (retval > 0)
2478 retval = 0;
2479 }
2480 }
2481 else {
2482 STps = &(STp->ps[STp->partition]);
2483 STps->drv_file = STps->drv_block = (-1);
2484 }
2485
2486 return retval;
2487}
2488
2489#if DEBUG
2490#define ST_DEB_FORWARD 0
2491#define ST_DEB_BACKWARD 1
2492static void deb_space_print(char *name, int direction, char *units, unsigned char *cmd)
2493{
2494 s32 sc;
2495
2496 sc = cmd[2] & 0x80 ? 0xff000000 : 0;
2497 sc |= (cmd[2] << 16) | (cmd[3] << 8) | cmd[4];
2498 if (direction)
2499 sc = -sc;
2500 printk(ST_DEB_MSG "%s: Spacing tape %s over %d %s.\n", name,
2501 direction ? "backward" : "forward", sc, units);
2502}
2503#endif
2504
2505
2506/* Internal ioctl function */
2507static int st_int_ioctl(struct scsi_tape *STp, unsigned int cmd_in, unsigned long arg)
2508{
2509 int timeout;
2510 long ltmp;
2511 int ioctl_result;
2512 int chg_eof = 1;
2513 unsigned char cmd[MAX_COMMAND_SIZE];
Mike Christie8b05b772005-11-08 04:06:44 -06002514 struct st_request *SRpnt;
Linus Torvalds1da177e2005-04-16 15:20:36 -07002515 struct st_partstat *STps;
2516 int fileno, blkno, at_sm, undone;
2517 int datalen = 0, direction = DMA_NONE;
2518 char *name = tape_name(STp);
2519
2520 WARN_ON(STp->buffer->do_dio != 0);
2521 if (STp->ready != ST_READY) {
2522 if (STp->ready == ST_NO_TAPE)
2523 return (-ENOMEDIUM);
2524 else
2525 return (-EIO);
2526 }
2527 timeout = STp->long_timeout;
2528 STps = &(STp->ps[STp->partition]);
2529 fileno = STps->drv_file;
2530 blkno = STps->drv_block;
2531 at_sm = STps->at_sm;
2532
2533 memset(cmd, 0, MAX_COMMAND_SIZE);
2534 switch (cmd_in) {
2535 case MTFSFM:
2536 chg_eof = 0; /* Changed from the FSF after this */
2537 case MTFSF:
2538 cmd[0] = SPACE;
2539 cmd[1] = 0x01; /* Space FileMarks */
2540 cmd[2] = (arg >> 16);
2541 cmd[3] = (arg >> 8);
2542 cmd[4] = arg;
2543 DEBC(deb_space_print(name, ST_DEB_FORWARD, "filemarks", cmd);)
2544 if (fileno >= 0)
2545 fileno += arg;
2546 blkno = 0;
2547 at_sm &= (arg == 0);
2548 break;
2549 case MTBSFM:
2550 chg_eof = 0; /* Changed from the FSF after this */
2551 case MTBSF:
2552 cmd[0] = SPACE;
2553 cmd[1] = 0x01; /* Space FileMarks */
2554 ltmp = (-arg);
2555 cmd[2] = (ltmp >> 16);
2556 cmd[3] = (ltmp >> 8);
2557 cmd[4] = ltmp;
2558 DEBC(deb_space_print(name, ST_DEB_BACKWARD, "filemarks", cmd);)
2559 if (fileno >= 0)
2560 fileno -= arg;
2561 blkno = (-1); /* We can't know the block number */
2562 at_sm &= (arg == 0);
2563 break;
2564 case MTFSR:
2565 cmd[0] = SPACE;
2566 cmd[1] = 0x00; /* Space Blocks */
2567 cmd[2] = (arg >> 16);
2568 cmd[3] = (arg >> 8);
2569 cmd[4] = arg;
2570 DEBC(deb_space_print(name, ST_DEB_FORWARD, "blocks", cmd);)
2571 if (blkno >= 0)
2572 blkno += arg;
2573 at_sm &= (arg == 0);
2574 break;
2575 case MTBSR:
2576 cmd[0] = SPACE;
2577 cmd[1] = 0x00; /* Space Blocks */
2578 ltmp = (-arg);
2579 cmd[2] = (ltmp >> 16);
2580 cmd[3] = (ltmp >> 8);
2581 cmd[4] = ltmp;
2582 DEBC(deb_space_print(name, ST_DEB_BACKWARD, "blocks", cmd);)
2583 if (blkno >= 0)
2584 blkno -= arg;
2585 at_sm &= (arg == 0);
2586 break;
2587 case MTFSS:
2588 cmd[0] = SPACE;
2589 cmd[1] = 0x04; /* Space Setmarks */
2590 cmd[2] = (arg >> 16);
2591 cmd[3] = (arg >> 8);
2592 cmd[4] = arg;
2593 DEBC(deb_space_print(name, ST_DEB_FORWARD, "setmarks", cmd);)
2594 if (arg != 0) {
2595 blkno = fileno = (-1);
2596 at_sm = 1;
2597 }
2598 break;
2599 case MTBSS:
2600 cmd[0] = SPACE;
2601 cmd[1] = 0x04; /* Space Setmarks */
2602 ltmp = (-arg);
2603 cmd[2] = (ltmp >> 16);
2604 cmd[3] = (ltmp >> 8);
2605 cmd[4] = ltmp;
2606 DEBC(deb_space_print(name, ST_DEB_BACKWARD, "setmarks", cmd);)
2607 if (arg != 0) {
2608 blkno = fileno = (-1);
2609 at_sm = 1;
2610 }
2611 break;
2612 case MTWEOF:
2613 case MTWSM:
2614 if (STp->write_prot)
2615 return (-EACCES);
2616 cmd[0] = WRITE_FILEMARKS;
2617 if (cmd_in == MTWSM)
2618 cmd[1] = 2;
2619 cmd[2] = (arg >> 16);
2620 cmd[3] = (arg >> 8);
2621 cmd[4] = arg;
2622 timeout = STp->device->timeout;
2623 DEBC(
2624 if (cmd_in == MTWEOF)
2625 printk(ST_DEB_MSG "%s: Writing %d filemarks.\n", name,
2626 cmd[2] * 65536 + cmd[3] * 256 + cmd[4]);
2627 else
2628 printk(ST_DEB_MSG "%s: Writing %d setmarks.\n", name,
2629 cmd[2] * 65536 + cmd[3] * 256 + cmd[4]);
2630 )
2631 if (fileno >= 0)
2632 fileno += arg;
2633 blkno = 0;
2634 at_sm = (cmd_in == MTWSM);
2635 break;
2636 case MTREW:
2637 cmd[0] = REZERO_UNIT;
2638 if (STp->immediate) {
2639 cmd[1] = 1; /* Don't wait for completion */
2640 timeout = STp->device->timeout;
2641 }
2642 DEBC(printk(ST_DEB_MSG "%s: Rewinding tape.\n", name));
2643 fileno = blkno = at_sm = 0;
2644 break;
2645 case MTNOP:
2646 DEBC(printk(ST_DEB_MSG "%s: No op on tape.\n", name));
2647 return 0; /* Should do something ? */
2648 break;
2649 case MTRETEN:
2650 cmd[0] = START_STOP;
2651 if (STp->immediate) {
2652 cmd[1] = 1; /* Don't wait for completion */
2653 timeout = STp->device->timeout;
2654 }
2655 cmd[4] = 3;
2656 DEBC(printk(ST_DEB_MSG "%s: Retensioning tape.\n", name));
2657 fileno = blkno = at_sm = 0;
2658 break;
2659 case MTEOM:
2660 if (!STp->fast_mteom) {
2661 /* space to the end of tape */
2662 ioctl_result = st_int_ioctl(STp, MTFSF, 0x7fffff);
2663 fileno = STps->drv_file;
2664 if (STps->eof >= ST_EOD_1)
2665 return 0;
2666 /* The next lines would hide the number of spaced FileMarks
2667 That's why I inserted the previous lines. I had no luck
2668 with detecting EOM with FSF, so we go now to EOM.
2669 Joerg Weule */
2670 } else
2671 fileno = (-1);
2672 cmd[0] = SPACE;
2673 cmd[1] = 3;
2674 DEBC(printk(ST_DEB_MSG "%s: Spacing to end of recorded medium.\n",
2675 name));
2676 blkno = -1;
2677 at_sm = 0;
2678 break;
2679 case MTERASE:
2680 if (STp->write_prot)
2681 return (-EACCES);
2682 cmd[0] = ERASE;
2683 cmd[1] = (arg ? 1 : 0); /* Long erase with non-zero argument */
2684 if (STp->immediate) {
2685 cmd[1] |= 2; /* Don't wait for completion */
2686 timeout = STp->device->timeout;
2687 }
2688 else
2689 timeout = STp->long_timeout * 8;
2690
2691 DEBC(printk(ST_DEB_MSG "%s: Erasing tape.\n", name));
2692 fileno = blkno = at_sm = 0;
2693 break;
2694 case MTSETBLK: /* Set block length */
2695 case MTSETDENSITY: /* Set tape density */
2696 case MTSETDRVBUFFER: /* Set drive buffering */
2697 case SET_DENS_AND_BLK: /* Set density and block size */
2698 chg_eof = 0;
2699 if (STp->dirty || (STp->buffer)->buffer_bytes != 0)
2700 return (-EIO); /* Not allowed if data in buffer */
2701 if ((cmd_in == MTSETBLK || cmd_in == SET_DENS_AND_BLK) &&
2702 (arg & MT_ST_BLKSIZE_MASK) != 0 &&
2703 STp->max_block > 0 &&
2704 ((arg & MT_ST_BLKSIZE_MASK) < STp->min_block ||
2705 (arg & MT_ST_BLKSIZE_MASK) > STp->max_block)) {
2706 printk(KERN_WARNING "%s: Illegal block size.\n", name);
2707 return (-EINVAL);
2708 }
2709 cmd[0] = MODE_SELECT;
2710 if ((STp->use_pf & USE_PF))
2711 cmd[1] = MODE_SELECT_PAGE_FORMAT;
2712 cmd[4] = datalen = 12;
2713 direction = DMA_TO_DEVICE;
2714
2715 memset((STp->buffer)->b_data, 0, 12);
2716 if (cmd_in == MTSETDRVBUFFER)
2717 (STp->buffer)->b_data[2] = (arg & 7) << 4;
2718 else
2719 (STp->buffer)->b_data[2] =
2720 STp->drv_buffer << 4;
2721 (STp->buffer)->b_data[3] = 8; /* block descriptor length */
2722 if (cmd_in == MTSETDENSITY) {
2723 (STp->buffer)->b_data[4] = arg;
2724 STp->density_changed = 1; /* At least we tried ;-) */
2725 } else if (cmd_in == SET_DENS_AND_BLK)
2726 (STp->buffer)->b_data[4] = arg >> 24;
2727 else
2728 (STp->buffer)->b_data[4] = STp->density;
2729 if (cmd_in == MTSETBLK || cmd_in == SET_DENS_AND_BLK) {
2730 ltmp = arg & MT_ST_BLKSIZE_MASK;
2731 if (cmd_in == MTSETBLK)
2732 STp->blksize_changed = 1; /* At least we tried ;-) */
2733 } else
2734 ltmp = STp->block_size;
2735 (STp->buffer)->b_data[9] = (ltmp >> 16);
2736 (STp->buffer)->b_data[10] = (ltmp >> 8);
2737 (STp->buffer)->b_data[11] = ltmp;
2738 timeout = STp->device->timeout;
2739 DEBC(
2740 if (cmd_in == MTSETBLK || cmd_in == SET_DENS_AND_BLK)
2741 printk(ST_DEB_MSG
2742 "%s: Setting block size to %d bytes.\n", name,
2743 (STp->buffer)->b_data[9] * 65536 +
2744 (STp->buffer)->b_data[10] * 256 +
2745 (STp->buffer)->b_data[11]);
2746 if (cmd_in == MTSETDENSITY || cmd_in == SET_DENS_AND_BLK)
2747 printk(ST_DEB_MSG
2748 "%s: Setting density code to %x.\n", name,
2749 (STp->buffer)->b_data[4]);
2750 if (cmd_in == MTSETDRVBUFFER)
2751 printk(ST_DEB_MSG
2752 "%s: Setting drive buffer code to %d.\n", name,
2753 ((STp->buffer)->b_data[2] >> 4) & 7);
2754 )
2755 break;
2756 default:
2757 return (-ENOSYS);
2758 }
2759
2760 SRpnt = st_do_scsi(NULL, STp, cmd, datalen, direction,
2761 timeout, MAX_RETRIES, 1);
2762 if (!SRpnt)
2763 return (STp->buffer)->syscall_result;
2764
2765 ioctl_result = (STp->buffer)->syscall_result;
2766
2767 if (!ioctl_result) { /* SCSI command successful */
Mike Christie8b05b772005-11-08 04:06:44 -06002768 st_release_request(SRpnt);
Linus Torvalds1da177e2005-04-16 15:20:36 -07002769 SRpnt = NULL;
2770 STps->drv_block = blkno;
2771 STps->drv_file = fileno;
2772 STps->at_sm = at_sm;
2773
2774 if (cmd_in == MTBSFM)
2775 ioctl_result = st_int_ioctl(STp, MTFSF, 1);
2776 else if (cmd_in == MTFSFM)
2777 ioctl_result = st_int_ioctl(STp, MTBSF, 1);
2778
2779 if (cmd_in == MTSETBLK || cmd_in == SET_DENS_AND_BLK) {
2780 int old_block_size = STp->block_size;
2781 STp->block_size = arg & MT_ST_BLKSIZE_MASK;
2782 if (STp->block_size != 0) {
2783 if (old_block_size == 0)
2784 normalize_buffer(STp->buffer);
2785 (STp->buffer)->buffer_blocks =
2786 (STp->buffer)->buffer_size / STp->block_size;
2787 }
2788 (STp->buffer)->buffer_bytes = (STp->buffer)->read_pointer = 0;
2789 if (cmd_in == SET_DENS_AND_BLK)
2790 STp->density = arg >> MT_ST_DENSITY_SHIFT;
2791 } else if (cmd_in == MTSETDRVBUFFER)
2792 STp->drv_buffer = (arg & 7);
2793 else if (cmd_in == MTSETDENSITY)
2794 STp->density = arg;
2795
2796 if (cmd_in == MTEOM)
2797 STps->eof = ST_EOD;
2798 else if (cmd_in == MTFSF)
2799 STps->eof = ST_FM;
2800 else if (chg_eof)
2801 STps->eof = ST_NOEOF;
2802
2803 if (cmd_in == MTWEOF)
2804 STps->rw = ST_IDLE;
2805 } else { /* SCSI command was not completely successful. Don't return
2806 from this block without releasing the SCSI command block! */
2807 struct st_cmdstatus *cmdstatp = &STp->buffer->cmdstat;
2808
2809 if (cmdstatp->flags & SENSE_EOM) {
2810 if (cmd_in != MTBSF && cmd_in != MTBSFM &&
2811 cmd_in != MTBSR && cmd_in != MTBSS)
2812 STps->eof = ST_EOM_OK;
2813 STps->drv_block = 0;
2814 }
2815
2816 if (cmdstatp->remainder_valid)
2817 undone = (int)cmdstatp->uremainder64;
2818 else
2819 undone = 0;
2820
2821 if (cmd_in == MTWEOF &&
2822 cmdstatp->have_sense &&
Kai Makisara91614c02007-01-26 00:38:39 +02002823 (cmdstatp->flags & SENSE_EOM)) {
2824 if (cmdstatp->sense_hdr.sense_key == NO_SENSE ||
2825 cmdstatp->sense_hdr.sense_key == RECOVERED_ERROR) {
2826 ioctl_result = 0; /* EOF(s) written successfully at EOM */
2827 STps->eof = ST_NOEOF;
2828 } else { /* Writing EOF(s) failed */
2829 if (fileno >= 0)
2830 fileno -= undone;
2831 if (undone < arg)
2832 STps->eof = ST_NOEOF;
2833 }
Linus Torvalds1da177e2005-04-16 15:20:36 -07002834 STps->drv_file = fileno;
Linus Torvalds1da177e2005-04-16 15:20:36 -07002835 } else if ((cmd_in == MTFSF) || (cmd_in == MTFSFM)) {
2836 if (fileno >= 0)
2837 STps->drv_file = fileno - undone;
2838 else
2839 STps->drv_file = fileno;
2840 STps->drv_block = -1;
2841 STps->eof = ST_NOEOF;
2842 } else if ((cmd_in == MTBSF) || (cmd_in == MTBSFM)) {
2843 if (arg > 0 && undone < 0) /* Some drives get this wrong */
2844 undone = (-undone);
2845 if (STps->drv_file >= 0)
2846 STps->drv_file = fileno + undone;
2847 STps->drv_block = 0;
2848 STps->eof = ST_NOEOF;
2849 } else if (cmd_in == MTFSR) {
2850 if (cmdstatp->flags & SENSE_FMK) { /* Hit filemark */
2851 if (STps->drv_file >= 0)
2852 STps->drv_file++;
2853 STps->drv_block = 0;
2854 STps->eof = ST_FM;
2855 } else {
2856 if (blkno >= undone)
2857 STps->drv_block = blkno - undone;
2858 else
2859 STps->drv_block = (-1);
2860 STps->eof = ST_NOEOF;
2861 }
2862 } else if (cmd_in == MTBSR) {
2863 if (cmdstatp->flags & SENSE_FMK) { /* Hit filemark */
2864 STps->drv_file--;
2865 STps->drv_block = (-1);
2866 } else {
2867 if (arg > 0 && undone < 0) /* Some drives get this wrong */
2868 undone = (-undone);
2869 if (STps->drv_block >= 0)
2870 STps->drv_block = blkno + undone;
2871 }
2872 STps->eof = ST_NOEOF;
2873 } else if (cmd_in == MTEOM) {
2874 STps->drv_file = (-1);
2875 STps->drv_block = (-1);
2876 STps->eof = ST_EOD;
2877 } else if (cmd_in == MTSETBLK ||
2878 cmd_in == MTSETDENSITY ||
2879 cmd_in == MTSETDRVBUFFER ||
2880 cmd_in == SET_DENS_AND_BLK) {
2881 if (cmdstatp->sense_hdr.sense_key == ILLEGAL_REQUEST &&
2882 !(STp->use_pf & PF_TESTED)) {
2883 /* Try the other possible state of Page Format if not
2884 already tried */
2885 STp->use_pf = !STp->use_pf | PF_TESTED;
Mike Christie8b05b772005-11-08 04:06:44 -06002886 st_release_request(SRpnt);
Linus Torvalds1da177e2005-04-16 15:20:36 -07002887 SRpnt = NULL;
2888 return st_int_ioctl(STp, cmd_in, arg);
2889 }
2890 } else if (chg_eof)
2891 STps->eof = ST_NOEOF;
2892
2893 if (cmdstatp->sense_hdr.sense_key == BLANK_CHECK)
2894 STps->eof = ST_EOD;
2895
Mike Christie8b05b772005-11-08 04:06:44 -06002896 st_release_request(SRpnt);
Linus Torvalds1da177e2005-04-16 15:20:36 -07002897 SRpnt = NULL;
2898 }
2899
2900 return ioctl_result;
2901}
2902
2903
2904/* Get the tape position. If bt == 2, arg points into a kernel space mt_loc
2905 structure. */
2906
2907static int get_location(struct scsi_tape *STp, unsigned int *block, int *partition,
2908 int logical)
2909{
2910 int result;
2911 unsigned char scmd[MAX_COMMAND_SIZE];
Mike Christie8b05b772005-11-08 04:06:44 -06002912 struct st_request *SRpnt;
Linus Torvalds1da177e2005-04-16 15:20:36 -07002913 DEB( char *name = tape_name(STp); )
2914
2915 if (STp->ready != ST_READY)
2916 return (-EIO);
2917
2918 memset(scmd, 0, MAX_COMMAND_SIZE);
2919 if ((STp->device)->scsi_level < SCSI_2) {
2920 scmd[0] = QFA_REQUEST_BLOCK;
2921 scmd[4] = 3;
2922 } else {
2923 scmd[0] = READ_POSITION;
2924 if (!logical && !STp->scsi2_logical)
2925 scmd[1] = 1;
2926 }
2927 SRpnt = st_do_scsi(NULL, STp, scmd, 20, DMA_FROM_DEVICE,
2928 STp->device->timeout, MAX_READY_RETRIES, 1);
2929 if (!SRpnt)
2930 return (STp->buffer)->syscall_result;
2931
2932 if ((STp->buffer)->syscall_result != 0 ||
2933 (STp->device->scsi_level >= SCSI_2 &&
2934 ((STp->buffer)->b_data[0] & 4) != 0)) {
2935 *block = *partition = 0;
2936 DEBC(printk(ST_DEB_MSG "%s: Can't read tape position.\n", name));
2937 result = (-EIO);
2938 } else {
2939 result = 0;
2940 if ((STp->device)->scsi_level < SCSI_2) {
2941 *block = ((STp->buffer)->b_data[0] << 16)
2942 + ((STp->buffer)->b_data[1] << 8)
2943 + (STp->buffer)->b_data[2];
2944 *partition = 0;
2945 } else {
2946 *block = ((STp->buffer)->b_data[4] << 24)
2947 + ((STp->buffer)->b_data[5] << 16)
2948 + ((STp->buffer)->b_data[6] << 8)
2949 + (STp->buffer)->b_data[7];
2950 *partition = (STp->buffer)->b_data[1];
2951 if (((STp->buffer)->b_data[0] & 0x80) &&
2952 (STp->buffer)->b_data[1] == 0) /* BOP of partition 0 */
2953 STp->ps[0].drv_block = STp->ps[0].drv_file = 0;
2954 }
2955 DEBC(printk(ST_DEB_MSG "%s: Got tape pos. blk %d part %d.\n", name,
2956 *block, *partition));
2957 }
Mike Christie8b05b772005-11-08 04:06:44 -06002958 st_release_request(SRpnt);
Linus Torvalds1da177e2005-04-16 15:20:36 -07002959 SRpnt = NULL;
2960
2961 return result;
2962}
2963
2964
2965/* Set the tape block and partition. Negative partition means that only the
2966 block should be set in vendor specific way. */
2967static int set_location(struct scsi_tape *STp, unsigned int block, int partition,
2968 int logical)
2969{
2970 struct st_partstat *STps;
2971 int result, p;
2972 unsigned int blk;
2973 int timeout;
2974 unsigned char scmd[MAX_COMMAND_SIZE];
Mike Christie8b05b772005-11-08 04:06:44 -06002975 struct st_request *SRpnt;
Linus Torvalds1da177e2005-04-16 15:20:36 -07002976 DEB( char *name = tape_name(STp); )
2977
2978 if (STp->ready != ST_READY)
2979 return (-EIO);
2980 timeout = STp->long_timeout;
2981 STps = &(STp->ps[STp->partition]);
2982
2983 DEBC(printk(ST_DEB_MSG "%s: Setting block to %d and partition to %d.\n",
2984 name, block, partition));
2985 DEB(if (partition < 0)
2986 return (-EIO); )
2987
2988 /* Update the location at the partition we are leaving */
2989 if ((!STp->can_partitions && partition != 0) ||
2990 partition >= ST_NBR_PARTITIONS)
2991 return (-EINVAL);
2992 if (partition != STp->partition) {
2993 if (get_location(STp, &blk, &p, 1))
2994 STps->last_block_valid = 0;
2995 else {
2996 STps->last_block_valid = 1;
2997 STps->last_block_visited = blk;
2998 DEBC(printk(ST_DEB_MSG
2999 "%s: Visited block %d for partition %d saved.\n",
3000 name, blk, STp->partition));
3001 }
3002 }
3003
3004 memset(scmd, 0, MAX_COMMAND_SIZE);
3005 if ((STp->device)->scsi_level < SCSI_2) {
3006 scmd[0] = QFA_SEEK_BLOCK;
3007 scmd[2] = (block >> 16);
3008 scmd[3] = (block >> 8);
3009 scmd[4] = block;
3010 scmd[5] = 0;
3011 } else {
3012 scmd[0] = SEEK_10;
3013 scmd[3] = (block >> 24);
3014 scmd[4] = (block >> 16);
3015 scmd[5] = (block >> 8);
3016 scmd[6] = block;
3017 if (!logical && !STp->scsi2_logical)
3018 scmd[1] = 4;
3019 if (STp->partition != partition) {
3020 scmd[1] |= 2;
3021 scmd[8] = partition;
3022 DEBC(printk(ST_DEB_MSG
3023 "%s: Trying to change partition from %d to %d\n",
3024 name, STp->partition, partition));
3025 }
3026 }
3027 if (STp->immediate) {
3028 scmd[1] |= 1; /* Don't wait for completion */
3029 timeout = STp->device->timeout;
3030 }
3031
3032 SRpnt = st_do_scsi(NULL, STp, scmd, 0, DMA_NONE,
3033 timeout, MAX_READY_RETRIES, 1);
3034 if (!SRpnt)
3035 return (STp->buffer)->syscall_result;
3036
3037 STps->drv_block = STps->drv_file = (-1);
3038 STps->eof = ST_NOEOF;
3039 if ((STp->buffer)->syscall_result != 0) {
3040 result = (-EIO);
3041 if (STp->can_partitions &&
3042 (STp->device)->scsi_level >= SCSI_2 &&
3043 (p = find_partition(STp)) >= 0)
3044 STp->partition = p;
3045 } else {
3046 if (STp->can_partitions) {
3047 STp->partition = partition;
3048 STps = &(STp->ps[partition]);
3049 if (!STps->last_block_valid ||
3050 STps->last_block_visited != block) {
3051 STps->at_sm = 0;
3052 STps->rw = ST_IDLE;
3053 }
3054 } else
3055 STps->at_sm = 0;
3056 if (block == 0)
3057 STps->drv_block = STps->drv_file = 0;
3058 result = 0;
3059 }
3060
Mike Christie8b05b772005-11-08 04:06:44 -06003061 st_release_request(SRpnt);
Linus Torvalds1da177e2005-04-16 15:20:36 -07003062 SRpnt = NULL;
3063
3064 return result;
3065}
3066
3067
3068/* Find the current partition number for the drive status. Called from open and
3069 returns either partition number of negative error code. */
3070static int find_partition(struct scsi_tape *STp)
3071{
3072 int i, partition;
3073 unsigned int block;
3074
3075 if ((i = get_location(STp, &block, &partition, 1)) < 0)
3076 return i;
3077 if (partition >= ST_NBR_PARTITIONS)
3078 return (-EIO);
3079 return partition;
3080}
3081
3082
3083/* Change the partition if necessary */
3084static int switch_partition(struct scsi_tape *STp)
3085{
3086 struct st_partstat *STps;
3087
3088 if (STp->partition == STp->new_partition)
3089 return 0;
3090 STps = &(STp->ps[STp->new_partition]);
3091 if (!STps->last_block_valid)
3092 STps->last_block_visited = 0;
3093 return set_location(STp, STps->last_block_visited, STp->new_partition, 1);
3094}
3095
3096/* Functions for reading and writing the medium partition mode page. */
3097
3098#define PART_PAGE 0x11
3099#define PART_PAGE_FIXED_LENGTH 8
3100
3101#define PP_OFF_MAX_ADD_PARTS 2
3102#define PP_OFF_NBR_ADD_PARTS 3
3103#define PP_OFF_FLAGS 4
3104#define PP_OFF_PART_UNITS 6
3105#define PP_OFF_RESERVED 7
3106
3107#define PP_BIT_IDP 0x20
3108#define PP_MSK_PSUM_MB 0x10
3109
3110/* Get the number of partitions on the tape. As a side effect reads the
3111 mode page into the tape buffer. */
3112static int nbr_partitions(struct scsi_tape *STp)
3113{
3114 int result;
3115 DEB( char *name = tape_name(STp); )
3116
3117 if (STp->ready != ST_READY)
3118 return (-EIO);
3119
3120 result = read_mode_page(STp, PART_PAGE, 1);
3121
3122 if (result) {
3123 DEBC(printk(ST_DEB_MSG "%s: Can't read medium partition page.\n",
3124 name));
3125 result = (-EIO);
3126 } else {
3127 result = (STp->buffer)->b_data[MODE_HEADER_LENGTH +
3128 PP_OFF_NBR_ADD_PARTS] + 1;
3129 DEBC(printk(ST_DEB_MSG "%s: Number of partitions %d.\n", name, result));
3130 }
3131
3132 return result;
3133}
3134
3135
3136/* Partition the tape into two partitions if size > 0 or one partition if
3137 size == 0.
3138
3139 The block descriptors are read and written because Sony SDT-7000 does not
3140 work without this (suggestion from Michael Schaefer <Michael.Schaefer@dlr.de>).
3141
3142 My HP C1533A drive returns only one partition size field. This is used to
3143 set the size of partition 1. There is no size field for the default partition.
3144 Michael Schaefer's Sony SDT-7000 returns two descriptors and the second is
3145 used to set the size of partition 1 (this is what the SCSI-3 standard specifies).
3146 The following algorithm is used to accommodate both drives: if the number of
3147 partition size fields is greater than the maximum number of additional partitions
3148 in the mode page, the second field is used. Otherwise the first field is used.
3149
3150 For Seagate DDS drives the page length must be 8 when no partitions is defined
3151 and 10 when 1 partition is defined (information from Eric Lee Green). This is
3152 is acceptable also to some other old drives and enforced if the first partition
3153 size field is used for the first additional partition size.
3154 */
3155static int partition_tape(struct scsi_tape *STp, int size)
3156{
3157 char *name = tape_name(STp);
3158 int result;
3159 int pgo, psd_cnt, psdo;
3160 unsigned char *bp;
3161
3162 result = read_mode_page(STp, PART_PAGE, 0);
3163 if (result) {
3164 DEBC(printk(ST_DEB_MSG "%s: Can't read partition mode page.\n", name));
3165 return result;
3166 }
3167 /* The mode page is in the buffer. Let's modify it and write it. */
3168 bp = (STp->buffer)->b_data;
3169 pgo = MODE_HEADER_LENGTH + bp[MH_OFF_BDESCS_LENGTH];
3170 DEBC(printk(ST_DEB_MSG "%s: Partition page length is %d bytes.\n",
3171 name, bp[pgo + MP_OFF_PAGE_LENGTH] + 2));
3172
3173 psd_cnt = (bp[pgo + MP_OFF_PAGE_LENGTH] + 2 - PART_PAGE_FIXED_LENGTH) / 2;
3174 psdo = pgo + PART_PAGE_FIXED_LENGTH;
3175 if (psd_cnt > bp[pgo + PP_OFF_MAX_ADD_PARTS]) {
3176 bp[psdo] = bp[psdo + 1] = 0xff; /* Rest of the tape */
3177 psdo += 2;
3178 }
3179 memset(bp + psdo, 0, bp[pgo + PP_OFF_NBR_ADD_PARTS] * 2);
3180
3181 DEBC(printk("%s: psd_cnt %d, max.parts %d, nbr_parts %d\n", name,
3182 psd_cnt, bp[pgo + PP_OFF_MAX_ADD_PARTS],
3183 bp[pgo + PP_OFF_NBR_ADD_PARTS]));
3184
3185 if (size <= 0) {
3186 bp[pgo + PP_OFF_NBR_ADD_PARTS] = 0;
3187 if (psd_cnt <= bp[pgo + PP_OFF_MAX_ADD_PARTS])
3188 bp[pgo + MP_OFF_PAGE_LENGTH] = 6;
3189 DEBC(printk(ST_DEB_MSG "%s: Formatting tape with one partition.\n",
3190 name));
3191 } else {
3192 bp[psdo] = (size >> 8) & 0xff;
3193 bp[psdo + 1] = size & 0xff;
3194 bp[pgo + 3] = 1;
3195 if (bp[pgo + MP_OFF_PAGE_LENGTH] < 8)
3196 bp[pgo + MP_OFF_PAGE_LENGTH] = 8;
3197 DEBC(printk(ST_DEB_MSG
3198 "%s: Formatting tape with two partitions (1 = %d MB).\n",
3199 name, size));
3200 }
3201 bp[pgo + PP_OFF_PART_UNITS] = 0;
3202 bp[pgo + PP_OFF_RESERVED] = 0;
3203 bp[pgo + PP_OFF_FLAGS] = PP_BIT_IDP | PP_MSK_PSUM_MB;
3204
3205 result = write_mode_page(STp, PART_PAGE, 1);
3206 if (result) {
3207 printk(KERN_INFO "%s: Partitioning of tape failed.\n", name);
3208 result = (-EIO);
3209 }
3210
3211 return result;
3212}
3213
3214
3215
3216/* The ioctl command */
3217static int st_ioctl(struct inode *inode, struct file *file,
3218 unsigned int cmd_in, unsigned long arg)
3219{
3220 int i, cmd_nr, cmd_type, bt;
3221 int retval = 0;
3222 unsigned int blk;
3223 struct scsi_tape *STp = file->private_data;
3224 struct st_modedef *STm;
3225 struct st_partstat *STps;
3226 char *name = tape_name(STp);
3227 void __user *p = (void __user *)arg;
3228
Matthias Kaehlcke28f85002007-07-29 23:38:15 +02003229 if (mutex_lock_interruptible(&STp->lock))
Linus Torvalds1da177e2005-04-16 15:20:36 -07003230 return -ERESTARTSYS;
3231
3232 DEB(
3233 if (debugging && !STp->in_use) {
3234 printk(ST_DEB_MSG "%s: Incorrect device.\n", name);
3235 retval = (-EIO);
3236 goto out;
3237 } ) /* end DEB */
3238
3239 STm = &(STp->modes[STp->current_mode]);
3240 STps = &(STp->ps[STp->partition]);
3241
3242 /*
3243 * If we are in the middle of error recovery, don't let anyone
3244 * else try and use this device. Also, if error recovery fails, it
3245 * may try and take the device offline, in which case all further
3246 * access to the device is prohibited.
3247 */
3248 retval = scsi_nonblockable_ioctl(STp->device, cmd_in, p, file);
3249 if (!scsi_block_when_processing_errors(STp->device) || retval != -ENODEV)
3250 goto out;
3251 retval = 0;
3252
3253 cmd_type = _IOC_TYPE(cmd_in);
3254 cmd_nr = _IOC_NR(cmd_in);
3255
3256 if (cmd_type == _IOC_TYPE(MTIOCTOP) && cmd_nr == _IOC_NR(MTIOCTOP)) {
3257 struct mtop mtc;
3258
3259 if (_IOC_SIZE(cmd_in) != sizeof(mtc)) {
3260 retval = (-EINVAL);
3261 goto out;
3262 }
3263
3264 i = copy_from_user(&mtc, p, sizeof(struct mtop));
3265 if (i) {
3266 retval = (-EFAULT);
3267 goto out;
3268 }
3269
3270 if (mtc.mt_op == MTSETDRVBUFFER && !capable(CAP_SYS_ADMIN)) {
3271 printk(KERN_WARNING
3272 "%s: MTSETDRVBUFFER only allowed for root.\n", name);
3273 retval = (-EPERM);
3274 goto out;
3275 }
3276 if (!STm->defined &&
3277 (mtc.mt_op != MTSETDRVBUFFER &&
3278 (mtc.mt_count & MT_ST_OPTIONS) == 0)) {
3279 retval = (-ENXIO);
3280 goto out;
3281 }
3282
3283 if (!STp->pos_unknown) {
3284
3285 if (STps->eof == ST_FM_HIT) {
3286 if (mtc.mt_op == MTFSF || mtc.mt_op == MTFSFM ||
3287 mtc.mt_op == MTEOM) {
3288 mtc.mt_count -= 1;
3289 if (STps->drv_file >= 0)
3290 STps->drv_file += 1;
3291 } else if (mtc.mt_op == MTBSF || mtc.mt_op == MTBSFM) {
3292 mtc.mt_count += 1;
3293 if (STps->drv_file >= 0)
3294 STps->drv_file += 1;
3295 }
3296 }
3297
3298 if (mtc.mt_op == MTSEEK) {
3299 /* Old position must be restored if partition will be
3300 changed */
3301 i = !STp->can_partitions ||
3302 (STp->new_partition != STp->partition);
3303 } else {
3304 i = mtc.mt_op == MTREW || mtc.mt_op == MTOFFL ||
3305 mtc.mt_op == MTRETEN || mtc.mt_op == MTEOM ||
3306 mtc.mt_op == MTLOCK || mtc.mt_op == MTLOAD ||
3307 mtc.mt_op == MTFSF || mtc.mt_op == MTFSFM ||
3308 mtc.mt_op == MTBSF || mtc.mt_op == MTBSFM ||
3309 mtc.mt_op == MTCOMPRESSION;
3310 }
3311 i = flush_buffer(STp, i);
3312 if (i < 0) {
3313 retval = i;
3314 goto out;
3315 }
3316 if (STps->rw == ST_WRITING &&
3317 (mtc.mt_op == MTREW || mtc.mt_op == MTOFFL ||
3318 mtc.mt_op == MTSEEK ||
3319 mtc.mt_op == MTBSF || mtc.mt_op == MTBSFM)) {
3320 i = st_int_ioctl(STp, MTWEOF, 1);
3321 if (i < 0) {
3322 retval = i;
3323 goto out;
3324 }
3325 if (mtc.mt_op == MTBSF || mtc.mt_op == MTBSFM)
3326 mtc.mt_count++;
3327 STps->rw = ST_IDLE;
3328 }
3329
3330 } else {
3331 /*
3332 * If there was a bus reset, block further access
3333 * to this device. If the user wants to rewind the tape,
3334 * then reset the flag and allow access again.
3335 */
3336 if (mtc.mt_op != MTREW &&
3337 mtc.mt_op != MTOFFL &&
3338 mtc.mt_op != MTRETEN &&
3339 mtc.mt_op != MTERASE &&
3340 mtc.mt_op != MTSEEK &&
3341 mtc.mt_op != MTEOM) {
3342 retval = (-EIO);
3343 goto out;
3344 }
3345 reset_state(STp);
3346 /* remove this when the midlevel properly clears was_reset */
3347 STp->device->was_reset = 0;
3348 }
3349
3350 if (mtc.mt_op != MTNOP && mtc.mt_op != MTSETBLK &&
3351 mtc.mt_op != MTSETDENSITY && mtc.mt_op != MTWSM &&
3352 mtc.mt_op != MTSETDRVBUFFER && mtc.mt_op != MTSETPART)
3353 STps->rw = ST_IDLE; /* Prevent automatic WEOF and fsf */
3354
3355 if (mtc.mt_op == MTOFFL && STp->door_locked != ST_UNLOCKED)
3356 do_door_lock(STp, 0); /* Ignore result! */
3357
3358 if (mtc.mt_op == MTSETDRVBUFFER &&
3359 (mtc.mt_count & MT_ST_OPTIONS) != 0) {
3360 retval = st_set_options(STp, mtc.mt_count);
3361 goto out;
3362 }
3363
3364 if (mtc.mt_op == MTSETPART) {
3365 if (!STp->can_partitions ||
3366 mtc.mt_count < 0 || mtc.mt_count >= ST_NBR_PARTITIONS) {
3367 retval = (-EINVAL);
3368 goto out;
3369 }
3370 if (mtc.mt_count >= STp->nbr_partitions &&
3371 (STp->nbr_partitions = nbr_partitions(STp)) < 0) {
3372 retval = (-EIO);
3373 goto out;
3374 }
3375 if (mtc.mt_count >= STp->nbr_partitions) {
3376 retval = (-EINVAL);
3377 goto out;
3378 }
3379 STp->new_partition = mtc.mt_count;
3380 retval = 0;
3381 goto out;
3382 }
3383
3384 if (mtc.mt_op == MTMKPART) {
3385 if (!STp->can_partitions) {
3386 retval = (-EINVAL);
3387 goto out;
3388 }
3389 if ((i = st_int_ioctl(STp, MTREW, 0)) < 0 ||
3390 (i = partition_tape(STp, mtc.mt_count)) < 0) {
3391 retval = i;
3392 goto out;
3393 }
3394 for (i = 0; i < ST_NBR_PARTITIONS; i++) {
3395 STp->ps[i].rw = ST_IDLE;
3396 STp->ps[i].at_sm = 0;
3397 STp->ps[i].last_block_valid = 0;
3398 }
3399 STp->partition = STp->new_partition = 0;
3400 STp->nbr_partitions = 1; /* Bad guess ?-) */
3401 STps->drv_block = STps->drv_file = 0;
3402 retval = 0;
3403 goto out;
3404 }
3405
3406 if (mtc.mt_op == MTSEEK) {
3407 i = set_location(STp, mtc.mt_count, STp->new_partition, 0);
3408 if (!STp->can_partitions)
3409 STp->ps[0].rw = ST_IDLE;
3410 retval = i;
3411 goto out;
3412 }
3413
3414 if (mtc.mt_op == MTUNLOAD || mtc.mt_op == MTOFFL) {
3415 retval = do_load_unload(STp, file, 0);
3416 goto out;
3417 }
3418
3419 if (mtc.mt_op == MTLOAD) {
3420 retval = do_load_unload(STp, file, max(1, mtc.mt_count));
3421 goto out;
3422 }
3423
3424 if (mtc.mt_op == MTLOCK || mtc.mt_op == MTUNLOCK) {
3425 retval = do_door_lock(STp, (mtc.mt_op == MTLOCK));
3426 goto out;
3427 }
3428
3429 if (STp->can_partitions && STp->ready == ST_READY &&
3430 (i = switch_partition(STp)) < 0) {
3431 retval = i;
3432 goto out;
3433 }
3434
3435 if (mtc.mt_op == MTCOMPRESSION)
3436 retval = st_compression(STp, (mtc.mt_count & 1));
3437 else
3438 retval = st_int_ioctl(STp, mtc.mt_op, mtc.mt_count);
3439 goto out;
3440 }
3441 if (!STm->defined) {
3442 retval = (-ENXIO);
3443 goto out;
3444 }
3445
3446 if ((i = flush_buffer(STp, 0)) < 0) {
3447 retval = i;
3448 goto out;
3449 }
3450 if (STp->can_partitions &&
3451 (i = switch_partition(STp)) < 0) {
3452 retval = i;
3453 goto out;
3454 }
3455
3456 if (cmd_type == _IOC_TYPE(MTIOCGET) && cmd_nr == _IOC_NR(MTIOCGET)) {
3457 struct mtget mt_status;
3458
3459 if (_IOC_SIZE(cmd_in) != sizeof(struct mtget)) {
3460 retval = (-EINVAL);
3461 goto out;
3462 }
3463
3464 mt_status.mt_type = STp->tape_type;
3465 mt_status.mt_dsreg =
3466 ((STp->block_size << MT_ST_BLKSIZE_SHIFT) & MT_ST_BLKSIZE_MASK) |
3467 ((STp->density << MT_ST_DENSITY_SHIFT) & MT_ST_DENSITY_MASK);
3468 mt_status.mt_blkno = STps->drv_block;
3469 mt_status.mt_fileno = STps->drv_file;
3470 if (STp->block_size != 0) {
3471 if (STps->rw == ST_WRITING)
3472 mt_status.mt_blkno +=
3473 (STp->buffer)->buffer_bytes / STp->block_size;
3474 else if (STps->rw == ST_READING)
3475 mt_status.mt_blkno -=
3476 ((STp->buffer)->buffer_bytes +
3477 STp->block_size - 1) / STp->block_size;
3478 }
3479
3480 mt_status.mt_gstat = 0;
3481 if (STp->drv_write_prot)
3482 mt_status.mt_gstat |= GMT_WR_PROT(0xffffffff);
3483 if (mt_status.mt_blkno == 0) {
3484 if (mt_status.mt_fileno == 0)
3485 mt_status.mt_gstat |= GMT_BOT(0xffffffff);
3486 else
3487 mt_status.mt_gstat |= GMT_EOF(0xffffffff);
3488 }
3489 mt_status.mt_erreg = (STp->recover_reg << MT_ST_SOFTERR_SHIFT);
3490 mt_status.mt_resid = STp->partition;
3491 if (STps->eof == ST_EOM_OK || STps->eof == ST_EOM_ERROR)
3492 mt_status.mt_gstat |= GMT_EOT(0xffffffff);
3493 else if (STps->eof >= ST_EOM_OK)
3494 mt_status.mt_gstat |= GMT_EOD(0xffffffff);
3495 if (STp->density == 1)
3496 mt_status.mt_gstat |= GMT_D_800(0xffffffff);
3497 else if (STp->density == 2)
3498 mt_status.mt_gstat |= GMT_D_1600(0xffffffff);
3499 else if (STp->density == 3)
3500 mt_status.mt_gstat |= GMT_D_6250(0xffffffff);
3501 if (STp->ready == ST_READY)
3502 mt_status.mt_gstat |= GMT_ONLINE(0xffffffff);
3503 if (STp->ready == ST_NO_TAPE)
3504 mt_status.mt_gstat |= GMT_DR_OPEN(0xffffffff);
3505 if (STps->at_sm)
3506 mt_status.mt_gstat |= GMT_SM(0xffffffff);
3507 if (STm->do_async_writes ||
3508 (STm->do_buffer_writes && STp->block_size != 0) ||
3509 STp->drv_buffer != 0)
3510 mt_status.mt_gstat |= GMT_IM_REP_EN(0xffffffff);
3511 if (STp->cleaning_req)
3512 mt_status.mt_gstat |= GMT_CLN(0xffffffff);
3513
3514 i = copy_to_user(p, &mt_status, sizeof(struct mtget));
3515 if (i) {
3516 retval = (-EFAULT);
3517 goto out;
3518 }
3519
3520 STp->recover_reg = 0; /* Clear after read */
3521 retval = 0;
3522 goto out;
3523 } /* End of MTIOCGET */
3524 if (cmd_type == _IOC_TYPE(MTIOCPOS) && cmd_nr == _IOC_NR(MTIOCPOS)) {
3525 struct mtpos mt_pos;
3526 if (_IOC_SIZE(cmd_in) != sizeof(struct mtpos)) {
3527 retval = (-EINVAL);
3528 goto out;
3529 }
3530 if ((i = get_location(STp, &blk, &bt, 0)) < 0) {
3531 retval = i;
3532 goto out;
3533 }
3534 mt_pos.mt_blkno = blk;
3535 i = copy_to_user(p, &mt_pos, sizeof(struct mtpos));
3536 if (i)
3537 retval = (-EFAULT);
3538 goto out;
3539 }
Matthias Kaehlcke28f85002007-07-29 23:38:15 +02003540 mutex_unlock(&STp->lock);
Linus Torvalds1da177e2005-04-16 15:20:36 -07003541 switch (cmd_in) {
3542 case SCSI_IOCTL_GET_IDLUN:
3543 case SCSI_IOCTL_GET_BUS_NUMBER:
3544 break;
3545 default:
Kai Makisara 16c4b3e2005-05-01 18:11:55 +03003546 if ((cmd_in == SG_IO ||
3547 cmd_in == SCSI_IOCTL_SEND_COMMAND ||
3548 cmd_in == CDROM_SEND_PACKET) &&
3549 !capable(CAP_SYS_RAWIO))
Linus Torvalds1da177e2005-04-16 15:20:36 -07003550 i = -EPERM;
3551 else
FUJITA Tomonori45e79a32007-07-09 12:39:20 +02003552 i = scsi_cmd_ioctl(file, STp->disk->queue,
3553 STp->disk, cmd_in, p);
Linus Torvalds1da177e2005-04-16 15:20:36 -07003554 if (i != -ENOTTY)
3555 return i;
3556 break;
3557 }
Kai Makisara 16c4b3e2005-05-01 18:11:55 +03003558 retval = scsi_ioctl(STp->device, cmd_in, p);
3559 if (!retval && cmd_in == SCSI_IOCTL_STOP_UNIT) { /* unload */
3560 STp->rew_at_close = 0;
3561 STp->ready = ST_NO_TAPE;
3562 }
3563 return retval;
Linus Torvalds1da177e2005-04-16 15:20:36 -07003564
3565 out:
Matthias Kaehlcke28f85002007-07-29 23:38:15 +02003566 mutex_unlock(&STp->lock);
Linus Torvalds1da177e2005-04-16 15:20:36 -07003567 return retval;
3568}
3569
3570#ifdef CONFIG_COMPAT
3571static long st_compat_ioctl(struct file *file, unsigned int cmd, unsigned long arg)
3572{
3573 struct scsi_tape *STp = file->private_data;
3574 struct scsi_device *sdev = STp->device;
3575 int ret = -ENOIOCTLCMD;
3576 if (sdev->host->hostt->compat_ioctl) {
3577
3578 ret = sdev->host->hostt->compat_ioctl(sdev, cmd, (void __user *)arg);
3579
3580 }
3581 return ret;
3582}
3583#endif
3584
3585
3586
3587/* Try to allocate a new tape buffer. Calling function must not hold
3588 dev_arr_lock. */
3589static struct st_buffer *
3590 new_tape_buffer(int from_initialization, int need_dma, int max_sg)
3591{
Mike Christie8b05b772005-11-08 04:06:44 -06003592 int i, got = 0;
Al Viroc53033f2005-10-21 03:22:08 -04003593 gfp_t priority;
Linus Torvalds1da177e2005-04-16 15:20:36 -07003594 struct st_buffer *tb;
3595
3596 if (from_initialization)
3597 priority = GFP_ATOMIC;
3598 else
3599 priority = GFP_KERNEL;
3600
3601 i = sizeof(struct st_buffer) + (max_sg - 1) * sizeof(struct scatterlist) +
3602 max_sg * sizeof(struct st_buf_fragment);
Jes Sorensen24669f752006-01-16 10:31:18 -05003603 tb = kzalloc(i, priority);
Linus Torvalds1da177e2005-04-16 15:20:36 -07003604 if (!tb) {
3605 printk(KERN_NOTICE "st: Can't allocate new tape buffer.\n");
3606 return NULL;
3607 }
Mike Christie8b05b772005-11-08 04:06:44 -06003608 tb->frp_segs = tb->orig_frp_segs = 0;
Linus Torvalds1da177e2005-04-16 15:20:36 -07003609 tb->use_sg = max_sg;
Linus Torvalds1da177e2005-04-16 15:20:36 -07003610 tb->frp = (struct st_buf_fragment *)(&(tb->sg[0]) + max_sg);
3611
Linus Torvalds1da177e2005-04-16 15:20:36 -07003612 tb->dma = need_dma;
3613 tb->buffer_size = got;
3614
3615 return tb;
3616}
3617
3618
3619/* Try to allocate enough space in the tape buffer */
3620static int enlarge_buffer(struct st_buffer * STbuffer, int new_size, int need_dma)
3621{
Al Viroc53033f2005-10-21 03:22:08 -04003622 int segs, nbr, max_segs, b_size, order, got;
3623 gfp_t priority;
Linus Torvalds1da177e2005-04-16 15:20:36 -07003624
3625 if (new_size <= STbuffer->buffer_size)
3626 return 1;
3627
3628 if (STbuffer->buffer_size <= PAGE_SIZE)
3629 normalize_buffer(STbuffer); /* Avoid extra segment */
3630
3631 max_segs = STbuffer->use_sg;
3632 nbr = max_segs - STbuffer->frp_segs;
3633 if (nbr <= 0)
3634 return 0;
3635
3636 priority = GFP_KERNEL | __GFP_NOWARN;
3637 if (need_dma)
3638 priority |= GFP_DMA;
Mike Christie8b05b772005-11-08 04:06:44 -06003639 for (b_size = PAGE_SIZE, order=0; order <= 6 &&
Linus Torvalds1da177e2005-04-16 15:20:36 -07003640 b_size < new_size - STbuffer->buffer_size;
3641 order++, b_size *= 2)
3642 ; /* empty */
3643
3644 for (segs = STbuffer->frp_segs, got = STbuffer->buffer_size;
3645 segs < max_segs && got < new_size;) {
3646 STbuffer->frp[segs].page = alloc_pages(priority, order);
3647 if (STbuffer->frp[segs].page == NULL) {
3648 if (new_size - got <= (max_segs - segs) * b_size / 2) {
3649 b_size /= 2; /* Large enough for the rest of the buffers */
3650 order--;
3651 continue;
3652 }
3653 DEB(STbuffer->buffer_size = got);
3654 normalize_buffer(STbuffer);
3655 return 0;
3656 }
3657 STbuffer->frp[segs].length = b_size;
3658 STbuffer->frp_segs += 1;
3659 got += b_size;
3660 STbuffer->buffer_size = got;
3661 segs++;
3662 }
3663 STbuffer->b_data = page_address(STbuffer->frp[0].page);
3664
3665 return 1;
3666}
3667
3668
3669/* Release the extra buffer */
3670static void normalize_buffer(struct st_buffer * STbuffer)
3671{
3672 int i, order;
3673
3674 for (i = STbuffer->orig_frp_segs; i < STbuffer->frp_segs; i++) {
3675 order = get_order(STbuffer->frp[i].length);
3676 __free_pages(STbuffer->frp[i].page, order);
3677 STbuffer->buffer_size -= STbuffer->frp[i].length;
3678 }
3679 STbuffer->frp_segs = STbuffer->orig_frp_segs;
3680 STbuffer->frp_sg_current = 0;
Mike Christie8b05b772005-11-08 04:06:44 -06003681 STbuffer->sg_segs = 0;
Linus Torvalds1da177e2005-04-16 15:20:36 -07003682}
3683
3684
3685/* Move data from the user buffer to the tape buffer. Returns zero (success) or
3686 negative error code. */
3687static int append_to_buffer(const char __user *ubp, struct st_buffer * st_bp, int do_count)
3688{
3689 int i, cnt, res, offset;
3690
3691 for (i = 0, offset = st_bp->buffer_bytes;
3692 i < st_bp->frp_segs && offset >= st_bp->frp[i].length; i++)
3693 offset -= st_bp->frp[i].length;
3694 if (i == st_bp->frp_segs) { /* Should never happen */
3695 printk(KERN_WARNING "st: append_to_buffer offset overflow.\n");
3696 return (-EIO);
3697 }
3698 for (; i < st_bp->frp_segs && do_count > 0; i++) {
3699 cnt = st_bp->frp[i].length - offset < do_count ?
3700 st_bp->frp[i].length - offset : do_count;
3701 res = copy_from_user(page_address(st_bp->frp[i].page) + offset, ubp, cnt);
3702 if (res)
3703 return (-EFAULT);
3704 do_count -= cnt;
3705 st_bp->buffer_bytes += cnt;
3706 ubp += cnt;
3707 offset = 0;
3708 }
3709 if (do_count) /* Should never happen */
3710 return (-EIO);
3711
3712 return 0;
3713}
3714
3715
3716/* Move data from the tape buffer to the user buffer. Returns zero (success) or
3717 negative error code. */
3718static int from_buffer(struct st_buffer * st_bp, char __user *ubp, int do_count)
3719{
3720 int i, cnt, res, offset;
3721
3722 for (i = 0, offset = st_bp->read_pointer;
3723 i < st_bp->frp_segs && offset >= st_bp->frp[i].length; i++)
3724 offset -= st_bp->frp[i].length;
3725 if (i == st_bp->frp_segs) { /* Should never happen */
3726 printk(KERN_WARNING "st: from_buffer offset overflow.\n");
3727 return (-EIO);
3728 }
3729 for (; i < st_bp->frp_segs && do_count > 0; i++) {
3730 cnt = st_bp->frp[i].length - offset < do_count ?
3731 st_bp->frp[i].length - offset : do_count;
3732 res = copy_to_user(ubp, page_address(st_bp->frp[i].page) + offset, cnt);
3733 if (res)
3734 return (-EFAULT);
3735 do_count -= cnt;
3736 st_bp->buffer_bytes -= cnt;
3737 st_bp->read_pointer += cnt;
3738 ubp += cnt;
3739 offset = 0;
3740 }
3741 if (do_count) /* Should never happen */
3742 return (-EIO);
3743
3744 return 0;
3745}
3746
3747
3748/* Move data towards start of buffer */
3749static void move_buffer_data(struct st_buffer * st_bp, int offset)
3750{
3751 int src_seg, dst_seg, src_offset = 0, dst_offset;
3752 int count, total;
3753
3754 if (offset == 0)
3755 return;
3756
3757 total=st_bp->buffer_bytes - offset;
3758 for (src_seg=0; src_seg < st_bp->frp_segs; src_seg++) {
3759 src_offset = offset;
3760 if (src_offset < st_bp->frp[src_seg].length)
3761 break;
3762 offset -= st_bp->frp[src_seg].length;
3763 }
3764
3765 st_bp->buffer_bytes = st_bp->read_pointer = total;
3766 for (dst_seg=dst_offset=0; total > 0; ) {
3767 count = min(st_bp->frp[dst_seg].length - dst_offset,
3768 st_bp->frp[src_seg].length - src_offset);
3769 memmove(page_address(st_bp->frp[dst_seg].page) + dst_offset,
3770 page_address(st_bp->frp[src_seg].page) + src_offset, count);
3771 src_offset += count;
3772 if (src_offset >= st_bp->frp[src_seg].length) {
3773 src_seg++;
3774 src_offset = 0;
3775 }
3776 dst_offset += count;
3777 if (dst_offset >= st_bp->frp[dst_seg].length) {
3778 dst_seg++;
3779 dst_offset = 0;
3780 }
3781 total -= count;
3782 }
3783}
3784
3785
3786/* Fill the s/g list up to the length required for this transfer */
3787static void buf_to_sg(struct st_buffer *STbp, unsigned int length)
3788{
3789 int i;
3790 unsigned int count;
3791 struct scatterlist *sg;
3792 struct st_buf_fragment *frp;
3793
3794 if (length == STbp->frp_sg_current)
3795 return; /* work already done */
3796
3797 sg = &(STbp->sg[0]);
3798 frp = STbp->frp;
3799 for (i=count=0; count < length; i++) {
3800 sg[i].page = frp[i].page;
3801 if (length - count > frp[i].length)
3802 sg[i].length = frp[i].length;
3803 else
3804 sg[i].length = length - count;
3805 count += sg[i].length;
3806 sg[i].offset = 0;
3807 }
3808 STbp->sg_segs = i;
3809 STbp->frp_sg_current = length;
3810}
3811
3812
3813/* Validate the options from command line or module parameters */
3814static void validate_options(void)
3815{
3816 if (buffer_kbs > 0)
3817 st_fixed_buffer_size = buffer_kbs * ST_KILOBYTE;
3818 if (max_sg_segs >= ST_FIRST_SG)
3819 st_max_sg_segs = max_sg_segs;
3820}
3821
3822#ifndef MODULE
3823/* Set the boot options. Syntax is defined in Documenation/scsi/st.txt.
3824 */
3825static int __init st_setup(char *str)
3826{
3827 int i, len, ints[5];
3828 char *stp;
3829
3830 stp = get_options(str, ARRAY_SIZE(ints), ints);
3831
3832 if (ints[0] > 0) {
3833 for (i = 0; i < ints[0] && i < ARRAY_SIZE(parms); i++)
3834 if (parms[i].val)
3835 *parms[i].val = ints[i + 1];
3836 } else {
3837 while (stp != NULL) {
3838 for (i = 0; i < ARRAY_SIZE(parms); i++) {
3839 len = strlen(parms[i].name);
3840 if (!strncmp(stp, parms[i].name, len) &&
3841 (*(stp + len) == ':' || *(stp + len) == '=')) {
3842 if (parms[i].val)
3843 *parms[i].val =
3844 simple_strtoul(stp + len + 1, NULL, 0);
3845 else
3846 printk(KERN_WARNING "st: Obsolete parameter %s\n",
3847 parms[i].name);
3848 break;
3849 }
3850 }
Tobias Klauser6391a112006-06-08 22:23:48 -07003851 if (i >= ARRAY_SIZE(parms))
Linus Torvalds1da177e2005-04-16 15:20:36 -07003852 printk(KERN_WARNING "st: invalid parameter in '%s'\n",
3853 stp);
3854 stp = strchr(stp, ',');
3855 if (stp)
3856 stp++;
3857 }
3858 }
3859
3860 validate_options();
3861
3862 return 1;
3863}
3864
3865__setup("st=", st_setup);
3866
3867#endif
3868
Arjan van de Ven00977a52007-02-12 00:55:34 -08003869static const struct file_operations st_fops =
Linus Torvalds1da177e2005-04-16 15:20:36 -07003870{
3871 .owner = THIS_MODULE,
3872 .read = st_read,
3873 .write = st_write,
3874 .ioctl = st_ioctl,
3875#ifdef CONFIG_COMPAT
3876 .compat_ioctl = st_compat_ioctl,
3877#endif
3878 .open = st_open,
3879 .flush = st_flush,
3880 .release = st_release,
3881};
3882
3883static int st_probe(struct device *dev)
3884{
3885 struct scsi_device *SDp = to_scsi_device(dev);
3886 struct gendisk *disk = NULL;
3887 struct cdev *cdev = NULL;
3888 struct scsi_tape *tpnt = NULL;
3889 struct st_modedef *STm;
3890 struct st_partstat *STps;
3891 struct st_buffer *buffer;
3892 int i, j, mode, dev_num, error;
3893 char *stp;
Linus Torvalds1da177e2005-04-16 15:20:36 -07003894
3895 if (SDp->type != TYPE_TAPE)
3896 return -ENODEV;
3897 if ((stp = st_incompatible(SDp))) {
Jeff Garzik3bf743e2005-10-24 18:04:06 -04003898 sdev_printk(KERN_INFO, SDp, "Found incompatible tape\n");
Linus Torvalds1da177e2005-04-16 15:20:36 -07003899 printk(KERN_INFO "st: The suggested driver is %s.\n", stp);
3900 return -ENODEV;
3901 }
3902
Mike Christie8b05b772005-11-08 04:06:44 -06003903 i = min(SDp->request_queue->max_hw_segments,
3904 SDp->request_queue->max_phys_segments);
Linus Torvalds1da177e2005-04-16 15:20:36 -07003905 if (st_max_sg_segs < i)
3906 i = st_max_sg_segs;
3907 buffer = new_tape_buffer(1, (SDp->host)->unchecked_isa_dma, i);
3908 if (buffer == NULL) {
3909 printk(KERN_ERR
3910 "st: Can't allocate new tape buffer. Device not attached.\n");
3911 goto out;
3912 }
3913
3914 disk = alloc_disk(1);
3915 if (!disk) {
3916 printk(KERN_ERR "st: out of memory. Device not attached.\n");
3917 goto out_buffer_free;
3918 }
3919
3920 write_lock(&st_dev_arr_lock);
3921 if (st_nr_dev >= st_dev_max) {
3922 struct scsi_tape **tmp_da;
3923 int tmp_dev_max;
3924
3925 tmp_dev_max = max(st_nr_dev * 2, 8);
3926 if (tmp_dev_max > ST_MAX_TAPES)
3927 tmp_dev_max = ST_MAX_TAPES;
3928 if (tmp_dev_max <= st_nr_dev) {
3929 write_unlock(&st_dev_arr_lock);
3930 printk(KERN_ERR "st: Too many tape devices (max. %d).\n",
3931 ST_MAX_TAPES);
3932 goto out_put_disk;
3933 }
3934
Jes Sorensen24669f752006-01-16 10:31:18 -05003935 tmp_da = kzalloc(tmp_dev_max * sizeof(struct scsi_tape *), GFP_ATOMIC);
Linus Torvalds1da177e2005-04-16 15:20:36 -07003936 if (tmp_da == NULL) {
3937 write_unlock(&st_dev_arr_lock);
3938 printk(KERN_ERR "st: Can't extend device array.\n");
3939 goto out_put_disk;
3940 }
3941
Linus Torvalds1da177e2005-04-16 15:20:36 -07003942 if (scsi_tapes != NULL) {
3943 memcpy(tmp_da, scsi_tapes,
3944 st_dev_max * sizeof(struct scsi_tape *));
3945 kfree(scsi_tapes);
3946 }
3947 scsi_tapes = tmp_da;
3948
3949 st_dev_max = tmp_dev_max;
3950 }
3951
3952 for (i = 0; i < st_dev_max; i++)
3953 if (scsi_tapes[i] == NULL)
3954 break;
3955 if (i >= st_dev_max)
3956 panic("scsi_devices corrupt (st)");
3957
Jes Sorensen24669f752006-01-16 10:31:18 -05003958 tpnt = kzalloc(sizeof(struct scsi_tape), GFP_ATOMIC);
Linus Torvalds1da177e2005-04-16 15:20:36 -07003959 if (tpnt == NULL) {
3960 write_unlock(&st_dev_arr_lock);
3961 printk(KERN_ERR "st: Can't allocate device descriptor.\n");
3962 goto out_put_disk;
3963 }
Kai Makisaraf03a5672005-08-02 13:40:47 +03003964 kref_init(&tpnt->kref);
Linus Torvalds1da177e2005-04-16 15:20:36 -07003965 tpnt->disk = disk;
3966 sprintf(disk->disk_name, "st%d", i);
3967 disk->private_data = &tpnt->driver;
3968 disk->queue = SDp->request_queue;
3969 tpnt->driver = &st_template;
3970 scsi_tapes[i] = tpnt;
3971 dev_num = i;
3972
3973 tpnt->device = SDp;
3974 if (SDp->scsi_level <= 2)
3975 tpnt->tape_type = MT_ISSCSI1;
3976 else
3977 tpnt->tape_type = MT_ISSCSI2;
3978
3979 tpnt->buffer = buffer;
Kai Makisaraf03a5672005-08-02 13:40:47 +03003980 tpnt->buffer->last_SRpnt = NULL;
Linus Torvalds1da177e2005-04-16 15:20:36 -07003981
3982 tpnt->inited = 0;
3983 tpnt->dirty = 0;
3984 tpnt->in_use = 0;
3985 tpnt->drv_buffer = 1; /* Try buffering if no mode sense */
3986 tpnt->restr_dma = (SDp->host)->unchecked_isa_dma;
3987 tpnt->use_pf = (SDp->scsi_level >= SCSI_2);
3988 tpnt->density = 0;
3989 tpnt->do_auto_lock = ST_AUTO_LOCK;
3990 tpnt->can_bsr = (SDp->scsi_level > 2 ? 1 : ST_IN_FILE_POS); /* BSR mandatory in SCSI3 */
3991 tpnt->can_partitions = 0;
3992 tpnt->two_fm = ST_TWO_FM;
3993 tpnt->fast_mteom = ST_FAST_MTEOM;
3994 tpnt->scsi2_logical = ST_SCSI2LOGICAL;
3995 tpnt->immediate = ST_NOWAIT;
3996 tpnt->default_drvbuffer = 0xff; /* No forced buffering */
3997 tpnt->partition = 0;
3998 tpnt->new_partition = 0;
3999 tpnt->nbr_partitions = 0;
4000 tpnt->device->timeout = ST_TIMEOUT;
4001 tpnt->long_timeout = ST_LONG_TIMEOUT;
4002 tpnt->try_dio = try_direct_io && !SDp->host->unchecked_isa_dma;
4003
Linus Torvalds1da177e2005-04-16 15:20:36 -07004004 for (i = 0; i < ST_NBR_MODES; i++) {
4005 STm = &(tpnt->modes[i]);
4006 STm->defined = 0;
4007 STm->sysv = ST_SYSV;
4008 STm->defaults_for_writes = 0;
4009 STm->do_async_writes = ST_ASYNC_WRITES;
4010 STm->do_buffer_writes = ST_BUFFER_WRITES;
4011 STm->do_read_ahead = ST_READ_AHEAD;
4012 STm->default_compression = ST_DONT_TOUCH;
4013 STm->default_blksize = (-1); /* No forced size */
4014 STm->default_density = (-1); /* No forced density */
4015 }
4016
4017 for (i = 0; i < ST_NBR_PARTITIONS; i++) {
4018 STps = &(tpnt->ps[i]);
4019 STps->rw = ST_IDLE;
4020 STps->eof = ST_NOEOF;
4021 STps->at_sm = 0;
4022 STps->last_block_valid = 0;
4023 STps->drv_block = (-1);
4024 STps->drv_file = (-1);
4025 }
4026
4027 tpnt->current_mode = 0;
4028 tpnt->modes[0].defined = 1;
4029
4030 tpnt->density_changed = tpnt->compression_changed =
4031 tpnt->blksize_changed = 0;
Matthias Kaehlcke28f85002007-07-29 23:38:15 +02004032 mutex_init(&tpnt->lock);
Linus Torvalds1da177e2005-04-16 15:20:36 -07004033
4034 st_nr_dev++;
4035 write_unlock(&st_dev_arr_lock);
4036
4037 for (mode = 0; mode < ST_NBR_MODES; ++mode) {
4038 STm = &(tpnt->modes[mode]);
4039 for (j=0; j < 2; j++) {
4040 cdev = cdev_alloc();
4041 if (!cdev) {
4042 printk(KERN_ERR
4043 "st%d: out of memory. Device not attached.\n",
4044 dev_num);
4045 goto out_free_tape;
4046 }
4047 cdev->owner = THIS_MODULE;
4048 cdev->ops = &st_fops;
4049
4050 error = cdev_add(cdev,
4051 MKDEV(SCSI_TAPE_MAJOR, TAPE_MINOR(dev_num, mode, j)),
4052 1);
4053 if (error) {
4054 printk(KERN_ERR "st%d: Can't add %s-rewind mode %d\n",
4055 dev_num, j ? "non" : "auto", mode);
4056 printk(KERN_ERR "st%d: Device not attached.\n", dev_num);
4057 goto out_free_tape;
4058 }
4059 STm->cdevs[j] = cdev;
4060
4061 }
Jeff Garzik13026a62006-10-04 06:00:38 -04004062 error = do_create_class_files(tpnt, dev_num, mode);
4063 if (error)
4064 goto out_free_tape;
Linus Torvalds1da177e2005-04-16 15:20:36 -07004065 }
4066
Kai Makisara42252852006-11-07 21:56:38 +02004067 sdev_printk(KERN_NOTICE, SDp,
Rene Herman8b1ea242006-05-20 15:00:22 -07004068 "Attached scsi tape %s\n", tape_name(tpnt));
Kai Makisara42252852006-11-07 21:56:38 +02004069 sdev_printk(KERN_INFO, SDp, "%s: try direct i/o: %s (alignment %d B)\n",
4070 tape_name(tpnt), tpnt->try_dio ? "yes" : "no",
4071 queue_dma_alignment(SDp->request_queue) + 1);
Linus Torvalds1da177e2005-04-16 15:20:36 -07004072
4073 return 0;
4074
4075out_free_tape:
4076 for (mode=0; mode < ST_NBR_MODES; mode++) {
4077 STm = &(tpnt->modes[mode]);
4078 sysfs_remove_link(&tpnt->device->sdev_gendev.kobj,
4079 "tape");
4080 for (j=0; j < 2; j++) {
4081 if (STm->cdevs[j]) {
4082 if (cdev == STm->cdevs[j])
4083 cdev = NULL;
gregkh@suse.ded2538782005-03-23 09:55:22 -08004084 class_device_destroy(st_sysfs_class,
4085 MKDEV(SCSI_TAPE_MAJOR,
4086 TAPE_MINOR(i, mode, j)));
Linus Torvalds1da177e2005-04-16 15:20:36 -07004087 cdev_del(STm->cdevs[j]);
4088 }
4089 }
4090 }
4091 if (cdev)
4092 cdev_del(cdev);
4093 write_lock(&st_dev_arr_lock);
4094 scsi_tapes[dev_num] = NULL;
4095 st_nr_dev--;
4096 write_unlock(&st_dev_arr_lock);
4097out_put_disk:
4098 put_disk(disk);
Jesper Juhlc9475cb2005-11-07 01:01:26 -08004099 kfree(tpnt);
Linus Torvalds1da177e2005-04-16 15:20:36 -07004100out_buffer_free:
4101 kfree(buffer);
4102out:
4103 return -ENODEV;
4104};
4105
4106
4107static int st_remove(struct device *dev)
4108{
4109 struct scsi_device *SDp = to_scsi_device(dev);
4110 struct scsi_tape *tpnt;
4111 int i, j, mode;
4112
4113 write_lock(&st_dev_arr_lock);
4114 for (i = 0; i < st_dev_max; i++) {
4115 tpnt = scsi_tapes[i];
4116 if (tpnt != NULL && tpnt->device == SDp) {
4117 scsi_tapes[i] = NULL;
4118 st_nr_dev--;
4119 write_unlock(&st_dev_arr_lock);
Linus Torvalds1da177e2005-04-16 15:20:36 -07004120 sysfs_remove_link(&tpnt->device->sdev_gendev.kobj,
4121 "tape");
4122 for (mode = 0; mode < ST_NBR_MODES; ++mode) {
Linus Torvalds1da177e2005-04-16 15:20:36 -07004123 for (j=0; j < 2; j++) {
gregkh@suse.ded2538782005-03-23 09:55:22 -08004124 class_device_destroy(st_sysfs_class,
4125 MKDEV(SCSI_TAPE_MAJOR,
4126 TAPE_MINOR(i, mode, j)));
Linus Torvalds1da177e2005-04-16 15:20:36 -07004127 cdev_del(tpnt->modes[mode].cdevs[j]);
4128 tpnt->modes[mode].cdevs[j] = NULL;
4129 }
4130 }
Linus Torvalds1da177e2005-04-16 15:20:36 -07004131
Arjan van de Ven0b950672006-01-11 13:16:10 +01004132 mutex_lock(&st_ref_mutex);
Kai Makisaraf03a5672005-08-02 13:40:47 +03004133 kref_put(&tpnt->kref, scsi_tape_release);
Arjan van de Ven0b950672006-01-11 13:16:10 +01004134 mutex_unlock(&st_ref_mutex);
Linus Torvalds1da177e2005-04-16 15:20:36 -07004135 return 0;
4136 }
4137 }
4138
4139 write_unlock(&st_dev_arr_lock);
4140 return 0;
4141}
4142
Kai Makisaraf03a5672005-08-02 13:40:47 +03004143/**
4144 * scsi_tape_release - Called to free the Scsi_Tape structure
4145 * @kref: pointer to embedded kref
4146 *
Arjan van de Ven0b950672006-01-11 13:16:10 +01004147 * st_ref_mutex must be held entering this routine. Because it is
Kai Makisaraf03a5672005-08-02 13:40:47 +03004148 * called on last put, you should always use the scsi_tape_get()
4149 * scsi_tape_put() helpers which manipulate the semaphore directly
4150 * and never do a direct kref_put().
4151 **/
4152static void scsi_tape_release(struct kref *kref)
4153{
4154 struct scsi_tape *tpnt = to_scsi_tape(kref);
4155 struct gendisk *disk = tpnt->disk;
4156
4157 tpnt->device = NULL;
4158
4159 if (tpnt->buffer) {
4160 tpnt->buffer->orig_frp_segs = 0;
4161 normalize_buffer(tpnt->buffer);
4162 kfree(tpnt->buffer);
4163 }
4164
4165 disk->private_data = NULL;
4166 put_disk(disk);
4167 kfree(tpnt);
4168 return;
4169}
4170
Linus Torvalds1da177e2005-04-16 15:20:36 -07004171static int __init init_st(void)
4172{
Jeff Garzik13026a62006-10-04 06:00:38 -04004173 int err;
4174
Linus Torvalds1da177e2005-04-16 15:20:36 -07004175 validate_options();
4176
Jeff Garzik13026a62006-10-04 06:00:38 -04004177 printk(KERN_INFO "st: Version %s, fixed bufsize %d, s/g segs %d\n",
Linus Torvalds1da177e2005-04-16 15:20:36 -07004178 verstr, st_fixed_buffer_size, st_max_sg_segs);
4179
gregkh@suse.ded2538782005-03-23 09:55:22 -08004180 st_sysfs_class = class_create(THIS_MODULE, "scsi_tape");
Linus Torvalds1da177e2005-04-16 15:20:36 -07004181 if (IS_ERR(st_sysfs_class)) {
Linus Torvalds1da177e2005-04-16 15:20:36 -07004182 printk(KERN_ERR "Unable create sysfs class for SCSI tapes\n");
Jeff Garzik13026a62006-10-04 06:00:38 -04004183 return PTR_ERR(st_sysfs_class);
Linus Torvalds1da177e2005-04-16 15:20:36 -07004184 }
4185
Jeff Garzik13026a62006-10-04 06:00:38 -04004186 err = register_chrdev_region(MKDEV(SCSI_TAPE_MAJOR, 0),
4187 ST_MAX_TAPE_ENTRIES, "st");
4188 if (err) {
4189 printk(KERN_ERR "Unable to get major %d for SCSI tapes\n",
4190 SCSI_TAPE_MAJOR);
4191 goto err_class;
Linus Torvalds1da177e2005-04-16 15:20:36 -07004192 }
Jeff Garzik13026a62006-10-04 06:00:38 -04004193
4194 err = scsi_register_driver(&st_template.gendrv);
4195 if (err)
4196 goto err_chrdev;
4197
Robert P. J. Day405ae7d2007-02-17 19:13:42 +01004198 err = do_create_sysfs_files();
Jeff Garzik13026a62006-10-04 06:00:38 -04004199 if (err)
4200 goto err_scsidrv;
4201
4202 return 0;
4203
4204err_scsidrv:
4205 scsi_unregister_driver(&st_template.gendrv);
4206err_chrdev:
4207 unregister_chrdev_region(MKDEV(SCSI_TAPE_MAJOR, 0),
4208 ST_MAX_TAPE_ENTRIES);
4209err_class:
Kai Makisarac2c96f42005-08-02 12:21:51 +03004210 class_destroy(st_sysfs_class);
Jeff Garzik13026a62006-10-04 06:00:38 -04004211 return err;
Linus Torvalds1da177e2005-04-16 15:20:36 -07004212}
4213
4214static void __exit exit_st(void)
4215{
Robert P. J. Day405ae7d2007-02-17 19:13:42 +01004216 do_remove_sysfs_files();
Linus Torvalds1da177e2005-04-16 15:20:36 -07004217 scsi_unregister_driver(&st_template.gendrv);
4218 unregister_chrdev_region(MKDEV(SCSI_TAPE_MAJOR, 0),
4219 ST_MAX_TAPE_ENTRIES);
Kai Makisarac2c96f42005-08-02 12:21:51 +03004220 class_destroy(st_sysfs_class);
Linus Torvalds1da177e2005-04-16 15:20:36 -07004221 kfree(scsi_tapes);
4222 printk(KERN_INFO "st: Unloaded.\n");
4223}
4224
4225module_init(init_st);
4226module_exit(exit_st);
4227
4228
4229/* The sysfs driver interface. Read-only at the moment */
4230static ssize_t st_try_direct_io_show(struct device_driver *ddp, char *buf)
4231{
4232 return snprintf(buf, PAGE_SIZE, "%d\n", try_direct_io);
4233}
4234static DRIVER_ATTR(try_direct_io, S_IRUGO, st_try_direct_io_show, NULL);
4235
4236static ssize_t st_fixed_buffer_size_show(struct device_driver *ddp, char *buf)
4237{
4238 return snprintf(buf, PAGE_SIZE, "%d\n", st_fixed_buffer_size);
4239}
4240static DRIVER_ATTR(fixed_buffer_size, S_IRUGO, st_fixed_buffer_size_show, NULL);
4241
4242static ssize_t st_max_sg_segs_show(struct device_driver *ddp, char *buf)
4243{
4244 return snprintf(buf, PAGE_SIZE, "%d\n", st_max_sg_segs);
4245}
4246static DRIVER_ATTR(max_sg_segs, S_IRUGO, st_max_sg_segs_show, NULL);
4247
4248static ssize_t st_version_show(struct device_driver *ddd, char *buf)
4249{
4250 return snprintf(buf, PAGE_SIZE, "[%s]\n", verstr);
4251}
4252static DRIVER_ATTR(version, S_IRUGO, st_version_show, NULL);
4253
Robert P. J. Day405ae7d2007-02-17 19:13:42 +01004254static int do_create_sysfs_files(void)
Linus Torvalds1da177e2005-04-16 15:20:36 -07004255{
Robert P. J. Day405ae7d2007-02-17 19:13:42 +01004256 struct device_driver *sysfs = &st_template.gendrv;
Jeff Garzik13026a62006-10-04 06:00:38 -04004257 int err;
Linus Torvalds1da177e2005-04-16 15:20:36 -07004258
Robert P. J. Day405ae7d2007-02-17 19:13:42 +01004259 err = driver_create_file(sysfs, &driver_attr_try_direct_io);
Jeff Garzik13026a62006-10-04 06:00:38 -04004260 if (err)
4261 return err;
Robert P. J. Day405ae7d2007-02-17 19:13:42 +01004262 err = driver_create_file(sysfs, &driver_attr_fixed_buffer_size);
Jeff Garzik13026a62006-10-04 06:00:38 -04004263 if (err)
4264 goto err_try_direct_io;
Robert P. J. Day405ae7d2007-02-17 19:13:42 +01004265 err = driver_create_file(sysfs, &driver_attr_max_sg_segs);
Jeff Garzik13026a62006-10-04 06:00:38 -04004266 if (err)
4267 goto err_attr_fixed_buf;
Robert P. J. Day405ae7d2007-02-17 19:13:42 +01004268 err = driver_create_file(sysfs, &driver_attr_version);
Jeff Garzik13026a62006-10-04 06:00:38 -04004269 if (err)
4270 goto err_attr_max_sg;
4271
4272 return 0;
4273
4274err_attr_max_sg:
Robert P. J. Day405ae7d2007-02-17 19:13:42 +01004275 driver_remove_file(sysfs, &driver_attr_max_sg_segs);
Jeff Garzik13026a62006-10-04 06:00:38 -04004276err_attr_fixed_buf:
Robert P. J. Day405ae7d2007-02-17 19:13:42 +01004277 driver_remove_file(sysfs, &driver_attr_fixed_buffer_size);
Jeff Garzik13026a62006-10-04 06:00:38 -04004278err_try_direct_io:
Robert P. J. Day405ae7d2007-02-17 19:13:42 +01004279 driver_remove_file(sysfs, &driver_attr_try_direct_io);
Jeff Garzik13026a62006-10-04 06:00:38 -04004280 return err;
Linus Torvalds1da177e2005-04-16 15:20:36 -07004281}
4282
Robert P. J. Day405ae7d2007-02-17 19:13:42 +01004283static void do_remove_sysfs_files(void)
Linus Torvalds1da177e2005-04-16 15:20:36 -07004284{
Robert P. J. Day405ae7d2007-02-17 19:13:42 +01004285 struct device_driver *sysfs = &st_template.gendrv;
Linus Torvalds1da177e2005-04-16 15:20:36 -07004286
Robert P. J. Day405ae7d2007-02-17 19:13:42 +01004287 driver_remove_file(sysfs, &driver_attr_version);
4288 driver_remove_file(sysfs, &driver_attr_max_sg_segs);
4289 driver_remove_file(sysfs, &driver_attr_fixed_buffer_size);
4290 driver_remove_file(sysfs, &driver_attr_try_direct_io);
Linus Torvalds1da177e2005-04-16 15:20:36 -07004291}
4292
4293
4294/* The sysfs simple class interface */
4295static ssize_t st_defined_show(struct class_device *class_dev, char *buf)
4296{
4297 struct st_modedef *STm = (struct st_modedef *)class_get_devdata(class_dev);
4298 ssize_t l = 0;
4299
4300 l = snprintf(buf, PAGE_SIZE, "%d\n", STm->defined);
4301 return l;
4302}
4303
4304CLASS_DEVICE_ATTR(defined, S_IRUGO, st_defined_show, NULL);
4305
4306static ssize_t st_defblk_show(struct class_device *class_dev, char *buf)
4307{
4308 struct st_modedef *STm = (struct st_modedef *)class_get_devdata(class_dev);
4309 ssize_t l = 0;
4310
4311 l = snprintf(buf, PAGE_SIZE, "%d\n", STm->default_blksize);
4312 return l;
4313}
4314
4315CLASS_DEVICE_ATTR(default_blksize, S_IRUGO, st_defblk_show, NULL);
4316
4317static ssize_t st_defdensity_show(struct class_device *class_dev, char *buf)
4318{
4319 struct st_modedef *STm = (struct st_modedef *)class_get_devdata(class_dev);
4320 ssize_t l = 0;
4321 char *fmt;
4322
4323 fmt = STm->default_density >= 0 ? "0x%02x\n" : "%d\n";
4324 l = snprintf(buf, PAGE_SIZE, fmt, STm->default_density);
4325 return l;
4326}
4327
4328CLASS_DEVICE_ATTR(default_density, S_IRUGO, st_defdensity_show, NULL);
4329
4330static ssize_t st_defcompression_show(struct class_device *class_dev, char *buf)
4331{
4332 struct st_modedef *STm = (struct st_modedef *)class_get_devdata(class_dev);
4333 ssize_t l = 0;
4334
4335 l = snprintf(buf, PAGE_SIZE, "%d\n", STm->default_compression - 1);
4336 return l;
4337}
4338
4339CLASS_DEVICE_ATTR(default_compression, S_IRUGO, st_defcompression_show, NULL);
4340
Jeff Garzik13026a62006-10-04 06:00:38 -04004341static int do_create_class_files(struct scsi_tape *STp, int dev_num, int mode)
Linus Torvalds1da177e2005-04-16 15:20:36 -07004342{
4343 int i, rew, error;
4344 char name[10];
4345 struct class_device *st_class_member;
4346
Linus Torvalds1da177e2005-04-16 15:20:36 -07004347 for (rew=0; rew < 2; rew++) {
4348 /* Make sure that the minor numbers corresponding to the four
4349 first modes always get the same names */
4350 i = mode << (4 - ST_NBR_MODE_BITS);
4351 snprintf(name, 10, "%s%s%s", rew ? "n" : "",
4352 STp->disk->disk_name, st_formats[i]);
4353 st_class_member =
Greg Kroah-Hartman53f46542005-10-27 22:25:43 -07004354 class_device_create(st_sysfs_class, NULL,
gregkh@suse.ded2538782005-03-23 09:55:22 -08004355 MKDEV(SCSI_TAPE_MAJOR,
4356 TAPE_MINOR(dev_num, mode, rew)),
4357 &STp->device->sdev_gendev, "%s", name);
Linus Torvalds1da177e2005-04-16 15:20:36 -07004358 if (IS_ERR(st_class_member)) {
gregkh@suse.ded2538782005-03-23 09:55:22 -08004359 printk(KERN_WARNING "st%d: class_device_create failed\n",
Linus Torvalds1da177e2005-04-16 15:20:36 -07004360 dev_num);
Jeff Garzik13026a62006-10-04 06:00:38 -04004361 error = PTR_ERR(st_class_member);
Linus Torvalds1da177e2005-04-16 15:20:36 -07004362 goto out;
4363 }
4364 class_set_devdata(st_class_member, &STp->modes[mode]);
4365
Jeff Garzik13026a62006-10-04 06:00:38 -04004366 error = class_device_create_file(st_class_member,
4367 &class_device_attr_defined);
4368 if (error) goto out;
4369 error = class_device_create_file(st_class_member,
4370 &class_device_attr_default_blksize);
4371 if (error) goto out;
4372 error = class_device_create_file(st_class_member,
4373 &class_device_attr_default_density);
4374 if (error) goto out;
4375 error = class_device_create_file(st_class_member,
4376 &class_device_attr_default_compression);
4377 if (error) goto out;
4378
Linus Torvalds1da177e2005-04-16 15:20:36 -07004379 if (mode == 0 && rew == 0) {
4380 error = sysfs_create_link(&STp->device->sdev_gendev.kobj,
4381 &st_class_member->kobj,
4382 "tape");
4383 if (error) {
4384 printk(KERN_ERR
4385 "st%d: Can't create sysfs link from SCSI device.\n",
4386 dev_num);
Jeff Garzik13026a62006-10-04 06:00:38 -04004387 goto out;
Linus Torvalds1da177e2005-04-16 15:20:36 -07004388 }
4389 }
4390 }
Jeff Garzik13026a62006-10-04 06:00:38 -04004391
4392 return 0;
4393
4394out:
4395 return error;
Linus Torvalds1da177e2005-04-16 15:20:36 -07004396}
4397
Linus Torvalds1da177e2005-04-16 15:20:36 -07004398/* The following functions may be useful for a larger audience. */
4399static int sgl_map_user_pages(struct scatterlist *sgl, const unsigned int max_pages,
4400 unsigned long uaddr, size_t count, int rw)
4401{
James Bottomley07542b82005-08-31 20:27:22 -04004402 unsigned long end = (uaddr + count + PAGE_SIZE - 1) >> PAGE_SHIFT;
4403 unsigned long start = uaddr >> PAGE_SHIFT;
4404 const int nr_pages = end - start;
Linus Torvalds1da177e2005-04-16 15:20:36 -07004405 int res, i, j;
Linus Torvalds1da177e2005-04-16 15:20:36 -07004406 struct page **pages;
4407
Linus Torvalds1da177e2005-04-16 15:20:36 -07004408 /* User attempted Overflow! */
4409 if ((uaddr + count) < uaddr)
4410 return -EINVAL;
4411
4412 /* Too big */
4413 if (nr_pages > max_pages)
4414 return -ENOMEM;
4415
4416 /* Hmm? */
4417 if (count == 0)
4418 return 0;
4419
4420 if ((pages = kmalloc(max_pages * sizeof(*pages), GFP_KERNEL)) == NULL)
4421 return -ENOMEM;
4422
4423 /* Try to fault in all of the necessary pages */
4424 down_read(&current->mm->mmap_sem);
4425 /* rw==READ means read from drive, write into memory area */
4426 res = get_user_pages(
4427 current,
4428 current->mm,
4429 uaddr,
4430 nr_pages,
4431 rw == READ,
4432 0, /* don't force */
4433 pages,
4434 NULL);
4435 up_read(&current->mm->mmap_sem);
4436
4437 /* Errors and no page mapped should return here */
4438 if (res < nr_pages)
4439 goto out_unmap;
4440
4441 for (i=0; i < nr_pages; i++) {
4442 /* FIXME: flush superflous for rw==READ,
4443 * probably wrong function for rw==WRITE
4444 */
4445 flush_dcache_page(pages[i]);
4446 }
4447
4448 /* Populate the scatter/gather list */
4449 sgl[0].page = pages[0];
4450 sgl[0].offset = uaddr & ~PAGE_MASK;
4451 if (nr_pages > 1) {
4452 sgl[0].length = PAGE_SIZE - sgl[0].offset;
4453 count -= sgl[0].length;
4454 for (i=1; i < nr_pages ; i++) {
4455 sgl[i].offset = 0;
4456 sgl[i].page = pages[i];
4457 sgl[i].length = count < PAGE_SIZE ? count : PAGE_SIZE;
4458 count -= PAGE_SIZE;
4459 }
4460 }
4461 else {
4462 sgl[0].length = count;
4463 }
4464
4465 kfree(pages);
4466 return nr_pages;
4467
4468 out_unmap:
4469 if (res > 0) {
4470 for (j=0; j < res; j++)
4471 page_cache_release(pages[j]);
Hugh Dickins6bc733e2005-12-01 20:21:57 +00004472 res = 0;
Linus Torvalds1da177e2005-04-16 15:20:36 -07004473 }
4474 kfree(pages);
4475 return res;
4476}
4477
4478
4479/* And unmap them... */
4480static int sgl_unmap_user_pages(struct scatterlist *sgl, const unsigned int nr_pages,
4481 int dirtied)
4482{
4483 int i;
4484
4485 for (i=0; i < nr_pages; i++) {
Nick Pigginb5810032005-10-29 18:16:12 -07004486 struct page *page = sgl[i].page;
4487
Nick Pigginb5810032005-10-29 18:16:12 -07004488 if (dirtied)
4489 SetPageDirty(page);
Linus Torvalds1da177e2005-04-16 15:20:36 -07004490 /* FIXME: cache flush missing for rw==READ
4491 * FIXME: call the correct reference counting function
4492 */
Nick Pigginb5810032005-10-29 18:16:12 -07004493 page_cache_release(page);
Linus Torvalds1da177e2005-04-16 15:20:36 -07004494 }
4495
4496 return 0;
4497}