blob: 36ab023793ca1e0c57f24fbe3b301326c77cf34b [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 Makisara3e51d3c2010-10-09 00:17:56 +030012 Copyright 1992 - 2010 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 Makisara373daac2010-12-20 18:43:39 +020020static const char *verstr = "20101219";
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>
Tejun Heo5a0e3ad2010-03-24 17:04:11 +090030#include <linux/slab.h>
Linus Torvalds1da177e2005-04-16 15:20:36 -070031#include <linux/errno.h>
32#include <linux/mtio.h>
Kai Makisara 16c4b3e2005-05-01 18:11:55 +030033#include <linux/cdrom.h>
Linus Torvalds1da177e2005-04-16 15:20:36 -070034#include <linux/ioctl.h>
35#include <linux/fcntl.h>
36#include <linux/spinlock.h>
37#include <linux/blkdev.h>
38#include <linux/moduleparam.h>
Linus Torvalds1da177e2005-04-16 15:20:36 -070039#include <linux/cdev.h>
Jeff Mahoney6c648d92012-08-18 15:20:39 -040040#include <linux/idr.h>
Linus Torvalds1da177e2005-04-16 15:20:36 -070041#include <linux/delay.h>
Arjan van de Ven0b950672006-01-11 13:16:10 +010042#include <linux/mutex.h>
Linus Torvalds1da177e2005-04-16 15:20:36 -070043
44#include <asm/uaccess.h>
45#include <asm/dma.h>
Linus Torvalds1da177e2005-04-16 15:20:36 -070046
47#include <scsi/scsi.h>
48#include <scsi/scsi_dbg.h>
49#include <scsi/scsi_device.h>
50#include <scsi/scsi_driver.h>
51#include <scsi/scsi_eh.h>
52#include <scsi/scsi_host.h>
53#include <scsi/scsi_ioctl.h>
Kai Makisara 16c4b3e2005-05-01 18:11:55 +030054#include <scsi/sg.h>
Linus Torvalds1da177e2005-04-16 15:20:36 -070055
56
57/* The driver prints some debugging information on the console if DEBUG
58 is defined and non-zero. */
Laurence Oberman2bec7082014-10-19 09:44:25 -040059#define DEBUG 1
60#define NO_DEBUG 0
Linus Torvalds1da177e2005-04-16 15:20:36 -070061
Hannes Reineckeb30d8bc2014-06-25 16:39:57 +020062#define ST_DEB_MSG KERN_NOTICE
Linus Torvalds1da177e2005-04-16 15:20:36 -070063#if DEBUG
64/* The message level for the debug messages is currently set to KERN_NOTICE
65 so that people can easily see the messages. Later when the debugging messages
66 in the drivers are more widely classified, this may be changed to KERN_DEBUG. */
Linus Torvalds1da177e2005-04-16 15:20:36 -070067#define DEB(a) a
68#define DEBC(a) if (debugging) { a ; }
69#else
70#define DEB(a)
71#define DEBC(a)
72#endif
73
74#define ST_KILOBYTE 1024
75
76#include "st_options.h"
77#include "st.h"
78
79static int buffer_kbs;
80static int max_sg_segs;
81static int try_direct_io = TRY_DIRECT_IO;
82static int try_rdio = 1;
83static int try_wdio = 1;
Laurence Oberman2bec7082014-10-19 09:44:25 -040084static int debug_flag;
Linus Torvalds1da177e2005-04-16 15:20:36 -070085
Jeff Mahoneyaf237822012-08-18 15:20:37 -040086static struct class st_sysfs_class;
Greg Kroah-Hartmanc69c6be2013-07-24 15:05:29 -070087static const struct attribute_group *st_dev_groups[];
Linus Torvalds1da177e2005-04-16 15:20:36 -070088
89MODULE_AUTHOR("Kai Makisara");
Rene Hermanf018fa52006-03-08 00:14:20 -080090MODULE_DESCRIPTION("SCSI tape (st) driver");
Linus Torvalds1da177e2005-04-16 15:20:36 -070091MODULE_LICENSE("GPL");
Rene Hermanf018fa52006-03-08 00:14:20 -080092MODULE_ALIAS_CHARDEV_MAJOR(SCSI_TAPE_MAJOR);
Michael Tokarevd7b8bcb2006-10-27 16:02:37 +040093MODULE_ALIAS_SCSI_DEVICE(TYPE_TAPE);
Linus Torvalds1da177e2005-04-16 15:20:36 -070094
95/* Set 'perm' (4th argument) to 0 to disable module_param's definition
96 * of sysfs parameters (which module_param doesn't yet support).
97 * Sysfs parameters defined explicitly later.
98 */
99module_param_named(buffer_kbs, buffer_kbs, int, 0);
100MODULE_PARM_DESC(buffer_kbs, "Default driver buffer size for fixed block mode (KB; 32)");
101module_param_named(max_sg_segs, max_sg_segs, int, 0);
102MODULE_PARM_DESC(max_sg_segs, "Maximum number of scatter/gather segments to use (256)");
103module_param_named(try_direct_io, try_direct_io, int, 0);
104MODULE_PARM_DESC(try_direct_io, "Try direct I/O between user buffer and tape drive (1)");
Laurence Oberman2bec7082014-10-19 09:44:25 -0400105module_param_named(debug_flag, debug_flag, int, 0);
106MODULE_PARM_DESC(debug_flag, "Enable DEBUG, same as setting debugging=1");
107
Linus Torvalds1da177e2005-04-16 15:20:36 -0700108
109/* Extra parameters for testing */
110module_param_named(try_rdio, try_rdio, int, 0);
111MODULE_PARM_DESC(try_rdio, "Try direct read i/o when possible");
112module_param_named(try_wdio, try_wdio, int, 0);
113MODULE_PARM_DESC(try_wdio, "Try direct write i/o when possible");
114
115#ifndef MODULE
116static int write_threshold_kbs; /* retained for compatibility */
117static struct st_dev_parm {
118 char *name;
119 int *val;
120} parms[] __initdata = {
121 {
122 "buffer_kbs", &buffer_kbs
123 },
124 { /* Retained for compatibility with 2.4 */
125 "write_threshold_kbs", &write_threshold_kbs
126 },
127 {
128 "max_sg_segs", NULL
129 },
130 {
131 "try_direct_io", &try_direct_io
Laurence Oberman2bec7082014-10-19 09:44:25 -0400132 },
133 {
134 "debug_flag", &debug_flag
Linus Torvalds1da177e2005-04-16 15:20:36 -0700135 }
136};
137#endif
138
139/* Restrict the number of modes so that names for all are assigned */
140#if ST_NBR_MODES > 16
141#error "Maximum number of modes is 16"
142#endif
143/* Bit reversed order to get same names for same minors with all
144 mode counts */
Arjan van de Ven0ad78202005-11-28 16:22:25 +0100145static const char *st_formats[] = {
Linus Torvalds1da177e2005-04-16 15:20:36 -0700146 "", "r", "k", "s", "l", "t", "o", "u",
147 "m", "v", "p", "x", "a", "y", "q", "z"};
148
149/* The default definitions have been moved to st_options.h */
150
151#define ST_FIXED_BUFFER_SIZE (ST_FIXED_BUFFER_BLOCKS * ST_KILOBYTE)
152
153/* The buffer size should fit into the 24 bits for length in the
154 6-byte SCSI read and write commands. */
155#if ST_FIXED_BUFFER_SIZE >= (2 << 24 - 1)
156#error "Buffer size should not exceed (2 << 24 - 1) bytes!"
157#endif
158
159static int debugging = DEBUG;
160
161#define MAX_RETRIES 0
162#define MAX_WRITE_RETRIES 0
163#define MAX_READY_RETRIES 0
164#define NO_TAPE NOT_READY
165
166#define ST_TIMEOUT (900 * HZ)
167#define ST_LONG_TIMEOUT (14000 * HZ)
168
169/* Remove mode bits and auto-rewind bit (7) */
170#define TAPE_NR(x) ( ((iminor(x) & ~255) >> (ST_NBR_MODE_BITS + 1)) | \
171 (iminor(x) & ~(-1 << ST_MODE_SHIFT)) )
172#define TAPE_MODE(x) ((iminor(x) & ST_MODE_MASK) >> ST_MODE_SHIFT)
173
174/* Construct the minor number from the device (d), mode (m), and non-rewind (n) data */
175#define TAPE_MINOR(d, m, n) (((d & ~(255 >> (ST_NBR_MODE_BITS + 1))) << (ST_NBR_MODE_BITS + 1)) | \
176 (d & (255 >> (ST_NBR_MODE_BITS + 1))) | (m << ST_MODE_SHIFT) | ((n != 0) << 7) )
177
178/* Internal ioctl to set both density (uppermost 8 bits) and blocksize (lower
179 24 bits) */
180#define SET_DENS_AND_BLK 0x10001
181
Linus Torvalds1da177e2005-04-16 15:20:36 -0700182static int st_fixed_buffer_size = ST_FIXED_BUFFER_SIZE;
183static int st_max_sg_segs = ST_MAX_SG;
184
Linus Torvalds1da177e2005-04-16 15:20:36 -0700185static int modes_defined;
186
Linus Torvalds1da177e2005-04-16 15:20:36 -0700187static int enlarge_buffer(struct st_buffer *, int, int);
Kai Makisara40f6b362008-02-24 22:23:24 +0200188static void clear_buffer(struct st_buffer *);
Linus Torvalds1da177e2005-04-16 15:20:36 -0700189static void normalize_buffer(struct st_buffer *);
190static int append_to_buffer(const char __user *, struct st_buffer *, int);
191static int from_buffer(struct st_buffer *, char __user *, int);
192static void move_buffer_data(struct st_buffer *, int);
Linus Torvalds1da177e2005-04-16 15:20:36 -0700193
FUJITA Tomonori66207422008-12-18 14:49:43 +0900194static int sgl_map_user_pages(struct st_buffer *, const unsigned int,
Linus Torvalds1da177e2005-04-16 15:20:36 -0700195 unsigned long, size_t, int);
FUJITA Tomonori66207422008-12-18 14:49:43 +0900196static int sgl_unmap_user_pages(struct st_buffer *, const unsigned int, int);
Linus Torvalds1da177e2005-04-16 15:20:36 -0700197
198static int st_probe(struct device *);
199static int st_remove(struct device *);
Linus Torvalds1da177e2005-04-16 15:20:36 -0700200
Robert P. J. Day405ae7d2007-02-17 19:13:42 +0100201static int do_create_sysfs_files(void);
202static void do_remove_sysfs_files(void);
Linus Torvalds1da177e2005-04-16 15:20:36 -0700203
204static struct scsi_driver st_template = {
205 .owner = THIS_MODULE,
206 .gendrv = {
207 .name = "st",
208 .probe = st_probe,
209 .remove = st_remove,
210 },
Linus Torvalds1da177e2005-04-16 15:20:36 -0700211};
212
213static int st_compression(struct scsi_tape *, int);
214
215static int find_partition(struct scsi_tape *);
216static int switch_partition(struct scsi_tape *);
217
218static int st_int_ioctl(struct scsi_tape *, unsigned int, unsigned long);
219
Kai Makisaraf03a5672005-08-02 13:40:47 +0300220static void scsi_tape_release(struct kref *);
221
222#define to_scsi_tape(obj) container_of(obj, struct scsi_tape, kref)
223
Arjan van de Ven0b950672006-01-11 13:16:10 +0100224static DEFINE_MUTEX(st_ref_mutex);
Jeff Mahoney6c648d92012-08-18 15:20:39 -0400225static DEFINE_SPINLOCK(st_index_lock);
226static DEFINE_SPINLOCK(st_use_lock);
227static DEFINE_IDR(st_index_idr);
228
Kai Makisaraf03a5672005-08-02 13:40:47 +0300229
Linus Torvalds1da177e2005-04-16 15:20:36 -0700230
231#include "osst_detect.h"
232#ifndef SIGS_FROM_OSST
233#define SIGS_FROM_OSST \
234 {"OnStream", "SC-", "", "osst"}, \
235 {"OnStream", "DI-", "", "osst"}, \
236 {"OnStream", "DP-", "", "osst"}, \
237 {"OnStream", "USB", "", "osst"}, \
238 {"OnStream", "FW-", "", "osst"}
239#endif
240
Kai Makisaraf03a5672005-08-02 13:40:47 +0300241static struct scsi_tape *scsi_tape_get(int dev)
242{
243 struct scsi_tape *STp = NULL;
244
Arjan van de Ven0b950672006-01-11 13:16:10 +0100245 mutex_lock(&st_ref_mutex);
Jeff Mahoney6c648d92012-08-18 15:20:39 -0400246 spin_lock(&st_index_lock);
Kai Makisaraf03a5672005-08-02 13:40:47 +0300247
Jeff Mahoney6c648d92012-08-18 15:20:39 -0400248 STp = idr_find(&st_index_idr, dev);
Kai Makisaraf03a5672005-08-02 13:40:47 +0300249 if (!STp) goto out;
250
251 kref_get(&STp->kref);
252
253 if (!STp->device)
254 goto out_put;
255
256 if (scsi_device_get(STp->device))
257 goto out_put;
258
259 goto out;
260
261out_put:
262 kref_put(&STp->kref, scsi_tape_release);
263 STp = NULL;
264out:
Jeff Mahoney6c648d92012-08-18 15:20:39 -0400265 spin_unlock(&st_index_lock);
Arjan van de Ven0b950672006-01-11 13:16:10 +0100266 mutex_unlock(&st_ref_mutex);
Kai Makisaraf03a5672005-08-02 13:40:47 +0300267 return STp;
268}
269
270static void scsi_tape_put(struct scsi_tape *STp)
271{
272 struct scsi_device *sdev = STp->device;
273
Arjan van de Ven0b950672006-01-11 13:16:10 +0100274 mutex_lock(&st_ref_mutex);
Kai Makisaraf03a5672005-08-02 13:40:47 +0300275 kref_put(&STp->kref, scsi_tape_release);
276 scsi_device_put(sdev);
Arjan van de Ven0b950672006-01-11 13:16:10 +0100277 mutex_unlock(&st_ref_mutex);
Kai Makisaraf03a5672005-08-02 13:40:47 +0300278}
279
Linus Torvalds1da177e2005-04-16 15:20:36 -0700280struct st_reject_data {
281 char *vendor;
282 char *model;
283 char *rev;
284 char *driver_hint; /* Name of the correct driver, NULL if unknown */
285};
286
287static struct st_reject_data reject_list[] = {
288 /* {"XXX", "Yy-", "", NULL}, example */
289 SIGS_FROM_OSST,
290 {NULL, }};
291
292/* If the device signature is on the list of incompatible drives, the
293 function returns a pointer to the name of the correct driver (if known) */
294static char * st_incompatible(struct scsi_device* SDp)
295{
296 struct st_reject_data *rp;
297
298 for (rp=&(reject_list[0]); rp->vendor != NULL; rp++)
299 if (!strncmp(rp->vendor, SDp->vendor, strlen(rp->vendor)) &&
300 !strncmp(rp->model, SDp->model, strlen(rp->model)) &&
301 !strncmp(rp->rev, SDp->rev, strlen(rp->rev))) {
302 if (rp->driver_hint)
303 return rp->driver_hint;
304 else
305 return "unknown";
306 }
307 return NULL;
308}
309
310
311static inline char *tape_name(struct scsi_tape *tape)
312{
313 return tape->disk->disk_name;
314}
315
Hannes Reineckeb30d8bc2014-06-25 16:39:57 +0200316#define st_printk(prefix, t, fmt, a...) \
Hannes Reinecke22e0d992014-10-24 14:26:44 +0200317 sdev_prefix_printk(prefix, (t)->device, tape_name(t), fmt, ##a)
Hannes Reineckeb30d8bc2014-06-25 16:39:57 +0200318#ifdef DEBUG
319#define DEBC_printk(t, fmt, a...) \
320 if (debugging) { st_printk(ST_DEB_MSG, t, fmt, ##a ); }
321#else
322#define DEBC_printk(t, fmt, a...)
323#endif
Linus Torvalds1da177e2005-04-16 15:20:36 -0700324
Mike Christie8b05b772005-11-08 04:06:44 -0600325static void st_analyze_sense(struct st_request *SRpnt, struct st_cmdstatus *s)
Linus Torvalds1da177e2005-04-16 15:20:36 -0700326{
327 const u8 *ucp;
Mike Christie8b05b772005-11-08 04:06:44 -0600328 const u8 *sense = SRpnt->sense;
Linus Torvalds1da177e2005-04-16 15:20:36 -0700329
Mike Christie8b05b772005-11-08 04:06:44 -0600330 s->have_sense = scsi_normalize_sense(SRpnt->sense,
331 SCSI_SENSE_BUFFERSIZE, &s->sense_hdr);
Linus Torvalds1da177e2005-04-16 15:20:36 -0700332 s->flags = 0;
333
334 if (s->have_sense) {
335 s->deferred = 0;
336 s->remainder_valid =
337 scsi_get_sense_info_fld(sense, SCSI_SENSE_BUFFERSIZE, &s->uremainder64);
338 switch (sense[0] & 0x7f) {
339 case 0x71:
340 s->deferred = 1;
341 case 0x70:
342 s->fixed_format = 1;
343 s->flags = sense[2] & 0xe0;
344 break;
345 case 0x73:
346 s->deferred = 1;
347 case 0x72:
348 s->fixed_format = 0;
349 ucp = scsi_sense_desc_find(sense, SCSI_SENSE_BUFFERSIZE, 4);
350 s->flags = ucp ? (ucp[3] & 0xe0) : 0;
351 break;
352 }
353 }
354}
355
356
357/* Convert the result to success code */
Mike Christie8b05b772005-11-08 04:06:44 -0600358static int st_chk_result(struct scsi_tape *STp, struct st_request * SRpnt)
Linus Torvalds1da177e2005-04-16 15:20:36 -0700359{
Mike Christie8b05b772005-11-08 04:06:44 -0600360 int result = SRpnt->result;
Linus Torvalds1da177e2005-04-16 15:20:36 -0700361 u8 scode;
362 DEB(const char *stp;)
363 char *name = tape_name(STp);
364 struct st_cmdstatus *cmdstatp;
365
366 if (!result)
367 return 0;
368
369 cmdstatp = &STp->buffer->cmdstat;
Kai Makisaraf03a5672005-08-02 13:40:47 +0300370 st_analyze_sense(SRpnt, cmdstatp);
Linus Torvalds1da177e2005-04-16 15:20:36 -0700371
372 if (cmdstatp->have_sense)
373 scode = STp->buffer->cmdstat.sense_hdr.sense_key;
374 else
375 scode = 0;
376
Hannes Reineckeb30d8bc2014-06-25 16:39:57 +0200377 DEB(
378 if (debugging) {
379 st_printk(ST_DEB_MSG, STp,
380 "Error: %x, cmd: %x %x %x %x %x %x\n", result,
381 SRpnt->cmd[0], SRpnt->cmd[1], SRpnt->cmd[2],
382 SRpnt->cmd[3], SRpnt->cmd[4], SRpnt->cmd[5]);
Linus Torvalds1da177e2005-04-16 15:20:36 -0700383 if (cmdstatp->have_sense)
Luben Tuikov4e73ea72006-07-07 00:02:18 -0700384 __scsi_print_sense(name, SRpnt->sense, SCSI_SENSE_BUFFERSIZE);
Linus Torvalds1da177e2005-04-16 15:20:36 -0700385 } ) /* end DEB */
386 if (!debugging) { /* Abnormal conditions for tape */
387 if (!cmdstatp->have_sense)
Hannes Reineckeb30d8bc2014-06-25 16:39:57 +0200388 st_printk(KERN_WARNING, STp,
389 "Error %x (driver bt 0x%x, host bt 0x%x).\n",
390 result, driver_byte(result), host_byte(result));
Linus Torvalds1da177e2005-04-16 15:20:36 -0700391 else if (cmdstatp->have_sense &&
392 scode != NO_SENSE &&
393 scode != RECOVERED_ERROR &&
394 /* scode != UNIT_ATTENTION && */
395 scode != BLANK_CHECK &&
396 scode != VOLUME_OVERFLOW &&
Mike Christie8b05b772005-11-08 04:06:44 -0600397 SRpnt->cmd[0] != MODE_SENSE &&
398 SRpnt->cmd[0] != TEST_UNIT_READY) {
Luben Tuikov4e73ea72006-07-07 00:02:18 -0700399
400 __scsi_print_sense(name, SRpnt->sense, SCSI_SENSE_BUFFERSIZE);
Linus Torvalds1da177e2005-04-16 15:20:36 -0700401 }
402 }
403
404 if (cmdstatp->fixed_format &&
405 STp->cln_mode >= EXTENDED_SENSE_START) { /* Only fixed format sense */
406 if (STp->cln_sense_value)
Mike Christie8b05b772005-11-08 04:06:44 -0600407 STp->cleaning_req |= ((SRpnt->sense[STp->cln_mode] &
Linus Torvalds1da177e2005-04-16 15:20:36 -0700408 STp->cln_sense_mask) == STp->cln_sense_value);
409 else
Mike Christie8b05b772005-11-08 04:06:44 -0600410 STp->cleaning_req |= ((SRpnt->sense[STp->cln_mode] &
Linus Torvalds1da177e2005-04-16 15:20:36 -0700411 STp->cln_sense_mask) != 0);
412 }
413 if (cmdstatp->have_sense &&
414 cmdstatp->sense_hdr.asc == 0 && cmdstatp->sense_hdr.ascq == 0x17)
415 STp->cleaning_req = 1; /* ASC and ASCQ => cleaning requested */
416
417 STp->pos_unknown |= STp->device->was_reset;
418
419 if (cmdstatp->have_sense &&
420 scode == RECOVERED_ERROR
421#if ST_RECOVERED_WRITE_FATAL
Mike Christie8b05b772005-11-08 04:06:44 -0600422 && SRpnt->cmd[0] != WRITE_6
423 && SRpnt->cmd[0] != WRITE_FILEMARKS
Linus Torvalds1da177e2005-04-16 15:20:36 -0700424#endif
425 ) {
426 STp->recover_count++;
427 STp->recover_reg++;
428
Hannes Reineckeb30d8bc2014-06-25 16:39:57 +0200429 DEB(
Linus Torvalds1da177e2005-04-16 15:20:36 -0700430 if (debugging) {
Mike Christie8b05b772005-11-08 04:06:44 -0600431 if (SRpnt->cmd[0] == READ_6)
Linus Torvalds1da177e2005-04-16 15:20:36 -0700432 stp = "read";
Mike Christie8b05b772005-11-08 04:06:44 -0600433 else if (SRpnt->cmd[0] == WRITE_6)
Linus Torvalds1da177e2005-04-16 15:20:36 -0700434 stp = "write";
435 else
436 stp = "ioctl";
Hannes Reineckeb30d8bc2014-06-25 16:39:57 +0200437 st_printk(ST_DEB_MSG, STp,
438 "Recovered %s error (%d).\n",
439 stp, STp->recover_count);
Linus Torvalds1da177e2005-04-16 15:20:36 -0700440 } ) /* end DEB */
441
442 if (cmdstatp->flags == 0)
443 return 0;
444 }
445 return (-EIO);
446}
447
FUJITA Tomonori4deba242008-12-05 15:25:20 +0900448static struct st_request *st_allocate_request(struct scsi_tape *stp)
Mike Christie8b05b772005-11-08 04:06:44 -0600449{
FUJITA Tomonori4deba242008-12-05 15:25:20 +0900450 struct st_request *streq;
451
452 streq = kzalloc(sizeof(*streq), GFP_KERNEL);
453 if (streq)
454 streq->stp = stp;
455 else {
Hannes Reineckeb30d8bc2014-06-25 16:39:57 +0200456 st_printk(KERN_ERR, stp,
457 "Can't get SCSI request.\n");
FUJITA Tomonori4deba242008-12-05 15:25:20 +0900458 if (signal_pending(current))
459 stp->buffer->syscall_result = -EINTR;
460 else
461 stp->buffer->syscall_result = -EBUSY;
462 }
463
464 return streq;
Mike Christie8b05b772005-11-08 04:06:44 -0600465}
466
467static void st_release_request(struct st_request *streq)
468{
469 kfree(streq);
Linus Torvalds1da177e2005-04-16 15:20:36 -0700470}
471
FUJITA Tomonori13b53b42008-12-18 14:49:41 +0900472static void st_scsi_execute_end(struct request *req, int uptodate)
473{
474 struct st_request *SRpnt = req->end_io_data;
475 struct scsi_tape *STp = SRpnt->stp;
Petr Uzelc68bf8e2011-10-21 13:31:09 +0200476 struct bio *tmp;
FUJITA Tomonori13b53b42008-12-18 14:49:41 +0900477
478 STp->buffer->cmdstat.midlevel_result = SRpnt->result = req->errors;
Tejun Heoc3a4d782009-05-07 22:24:37 +0900479 STp->buffer->cmdstat.residual = req->resid_len;
FUJITA Tomonori13b53b42008-12-18 14:49:41 +0900480
Petr Uzelc68bf8e2011-10-21 13:31:09 +0200481 tmp = SRpnt->bio;
FUJITA Tomonori13b53b42008-12-18 14:49:41 +0900482 if (SRpnt->waiting)
483 complete(SRpnt->waiting);
484
Petr Uzelc68bf8e2011-10-21 13:31:09 +0200485 blk_rq_unmap_user(tmp);
FUJITA Tomonori13b53b42008-12-18 14:49:41 +0900486 __blk_put_request(req->q, req);
487}
488
489static int st_scsi_execute(struct st_request *SRpnt, const unsigned char *cmd,
490 int data_direction, void *buffer, unsigned bufflen,
491 int timeout, int retries)
492{
493 struct request *req;
494 struct rq_map_data *mdata = &SRpnt->stp->buffer->map_data;
495 int err = 0;
496 int write = (data_direction == DMA_TO_DEVICE);
497
498 req = blk_get_request(SRpnt->stp->device->request_queue, write,
499 GFP_KERNEL);
Joe Lawrencea492f072014-08-28 08:15:21 -0600500 if (IS_ERR(req))
FUJITA Tomonori13b53b42008-12-18 14:49:41 +0900501 return DRIVER_ERROR << 24;
502
Jens Axboef27b0872014-06-06 07:57:37 -0600503 blk_rq_set_block_pc(req);
FUJITA Tomonori13b53b42008-12-18 14:49:41 +0900504 req->cmd_flags |= REQ_QUIET;
505
506 mdata->null_mapped = 1;
507
Kai Makisara02ae2c02008-12-18 14:49:50 +0900508 if (bufflen) {
509 err = blk_rq_map_user(req->q, req, mdata, NULL, bufflen,
510 GFP_KERNEL);
511 if (err) {
512 blk_put_request(req);
513 return DRIVER_ERROR << 24;
514 }
FUJITA Tomonori13b53b42008-12-18 14:49:41 +0900515 }
516
517 SRpnt->bio = req->bio;
518 req->cmd_len = COMMAND_SIZE(cmd[0]);
519 memset(req->cmd, 0, BLK_MAX_CDB);
520 memcpy(req->cmd, cmd, req->cmd_len);
521 req->sense = SRpnt->sense;
522 req->sense_len = 0;
523 req->timeout = timeout;
524 req->retries = retries;
525 req->end_io_data = SRpnt;
526
527 blk_execute_rq_nowait(req->q, NULL, req, 1, st_scsi_execute_end);
528 return 0;
529}
530
Linus Torvalds1da177e2005-04-16 15:20:36 -0700531/* Do the scsi command. Waits until command performed if do_wait is true.
532 Otherwise write_behind_check() is used to check that the command
533 has finished. */
Mike Christie8b05b772005-11-08 04:06:44 -0600534static struct st_request *
535st_do_scsi(struct st_request * SRpnt, struct scsi_tape * STp, unsigned char *cmd,
Linus Torvalds1da177e2005-04-16 15:20:36 -0700536 int bytes, int direction, int timeout, int retries, int do_wait)
537{
Kai Makisaraf03a5672005-08-02 13:40:47 +0300538 struct completion *waiting;
FUJITA Tomonori6d476262008-12-18 14:49:42 +0900539 struct rq_map_data *mdata = &STp->buffer->map_data;
540 int ret;
Linus Torvalds1da177e2005-04-16 15:20:36 -0700541
Kai Makisaraf03a5672005-08-02 13:40:47 +0300542 /* if async, make sure there's no command outstanding */
543 if (!do_wait && ((STp->buffer)->last_SRpnt)) {
Hannes Reineckeb30d8bc2014-06-25 16:39:57 +0200544 st_printk(KERN_ERR, STp,
545 "Async command already active.\n");
Kai Makisaraf03a5672005-08-02 13:40:47 +0300546 if (signal_pending(current))
547 (STp->buffer)->syscall_result = (-EINTR);
548 else
549 (STp->buffer)->syscall_result = (-EBUSY);
550 return NULL;
551 }
552
FUJITA Tomonori4deba242008-12-05 15:25:20 +0900553 if (!SRpnt) {
554 SRpnt = st_allocate_request(STp);
555 if (!SRpnt)
Linus Torvalds1da177e2005-04-16 15:20:36 -0700556 return NULL;
Linus Torvalds1da177e2005-04-16 15:20:36 -0700557 }
558
Kai Makisaraf03a5672005-08-02 13:40:47 +0300559 /* If async IO, set last_SRpnt. This ptr tells write_behind_check
560 which IO is outstanding. It's nulled out when the IO completes. */
561 if (!do_wait)
562 (STp->buffer)->last_SRpnt = SRpnt;
563
564 waiting = &STp->wait;
565 init_completion(waiting);
Mike Christie8b05b772005-11-08 04:06:44 -0600566 SRpnt->waiting = waiting;
567
FUJITA Tomonori66207422008-12-18 14:49:43 +0900568 if (STp->buffer->do_dio) {
FUJITA Tomonoric982c362009-11-26 09:24:13 +0900569 mdata->page_order = 0;
FUJITA Tomonori66207422008-12-18 14:49:43 +0900570 mdata->nr_entries = STp->buffer->sg_segs;
571 mdata->pages = STp->buffer->mapped_pages;
572 } else {
FUJITA Tomonoric982c362009-11-26 09:24:13 +0900573 mdata->page_order = STp->buffer->reserved_page_order;
FUJITA Tomonori6d476262008-12-18 14:49:42 +0900574 mdata->nr_entries =
575 DIV_ROUND_UP(bytes, PAGE_SIZE << mdata->page_order);
FUJITA Tomonoric982c362009-11-26 09:24:13 +0900576 mdata->pages = STp->buffer->reserved_pages;
577 mdata->offset = 0;
FUJITA Tomonori6d476262008-12-18 14:49:42 +0900578 }
579
Mike Christie8b05b772005-11-08 04:06:44 -0600580 memcpy(SRpnt->cmd, cmd, sizeof(SRpnt->cmd));
Linus Torvalds1da177e2005-04-16 15:20:36 -0700581 STp->buffer->cmdstat.have_sense = 0;
Mike Christie8b05b772005-11-08 04:06:44 -0600582 STp->buffer->syscall_result = 0;
Linus Torvalds1da177e2005-04-16 15:20:36 -0700583
FUJITA Tomonori66207422008-12-18 14:49:43 +0900584 ret = st_scsi_execute(SRpnt, cmd, direction, NULL, bytes, timeout,
585 retries);
FUJITA Tomonori6d476262008-12-18 14:49:42 +0900586 if (ret) {
Mike Christie8b05b772005-11-08 04:06:44 -0600587 /* could not allocate the buffer or request was too large */
588 (STp->buffer)->syscall_result = (-EBUSY);
Kai Makisara787926b2005-11-13 10:04:44 +0200589 (STp->buffer)->last_SRpnt = NULL;
FUJITA Tomonori6d476262008-12-18 14:49:42 +0900590 } else if (do_wait) {
Kai Makisaraf03a5672005-08-02 13:40:47 +0300591 wait_for_completion(waiting);
Mike Christie8b05b772005-11-08 04:06:44 -0600592 SRpnt->waiting = NULL;
Linus Torvalds1da177e2005-04-16 15:20:36 -0700593 (STp->buffer)->syscall_result = st_chk_result(STp, SRpnt);
594 }
Mike Christie8b05b772005-11-08 04:06:44 -0600595
Linus Torvalds1da177e2005-04-16 15:20:36 -0700596 return SRpnt;
597}
598
599
600/* Handle the write-behind checking (waits for completion). Returns -ENOSPC if
601 write has been correct but EOM early warning reached, -EIO if write ended in
602 error or zero if write successful. Asynchronous writes are used only in
603 variable block mode. */
604static int write_behind_check(struct scsi_tape * STp)
605{
606 int retval = 0;
607 struct st_buffer *STbuffer;
608 struct st_partstat *STps;
609 struct st_cmdstatus *cmdstatp;
Mike Christie8b05b772005-11-08 04:06:44 -0600610 struct st_request *SRpnt;
Linus Torvalds1da177e2005-04-16 15:20:36 -0700611
612 STbuffer = STp->buffer;
613 if (!STbuffer->writing)
614 return 0;
615
Hannes Reineckeb30d8bc2014-06-25 16:39:57 +0200616 DEB(
Linus Torvalds1da177e2005-04-16 15:20:36 -0700617 if (STp->write_pending)
618 STp->nbr_waits++;
619 else
620 STp->nbr_finished++;
Hannes Reineckeb30d8bc2014-06-25 16:39:57 +0200621 ) /* end DEB */
Linus Torvalds1da177e2005-04-16 15:20:36 -0700622
623 wait_for_completion(&(STp->wait));
Kai Makisaraf03a5672005-08-02 13:40:47 +0300624 SRpnt = STbuffer->last_SRpnt;
625 STbuffer->last_SRpnt = NULL;
Mike Christie8b05b772005-11-08 04:06:44 -0600626 SRpnt->waiting = NULL;
Linus Torvalds1da177e2005-04-16 15:20:36 -0700627
Kai Makisaraf03a5672005-08-02 13:40:47 +0300628 (STp->buffer)->syscall_result = st_chk_result(STp, SRpnt);
Mike Christie8b05b772005-11-08 04:06:44 -0600629 st_release_request(SRpnt);
Linus Torvalds1da177e2005-04-16 15:20:36 -0700630
631 STbuffer->buffer_bytes -= STbuffer->writing;
632 STps = &(STp->ps[STp->partition]);
633 if (STps->drv_block >= 0) {
634 if (STp->block_size == 0)
635 STps->drv_block++;
636 else
637 STps->drv_block += STbuffer->writing / STp->block_size;
638 }
639
640 cmdstatp = &STbuffer->cmdstat;
641 if (STbuffer->syscall_result) {
642 retval = -EIO;
643 if (cmdstatp->have_sense && !cmdstatp->deferred &&
644 (cmdstatp->flags & SENSE_EOM) &&
645 (cmdstatp->sense_hdr.sense_key == NO_SENSE ||
646 cmdstatp->sense_hdr.sense_key == RECOVERED_ERROR)) {
647 /* EOM at write-behind, has all data been written? */
648 if (!cmdstatp->remainder_valid ||
649 cmdstatp->uremainder64 == 0)
650 retval = -ENOSPC;
651 }
652 if (retval == -EIO)
653 STps->drv_block = -1;
654 }
655 STbuffer->writing = 0;
656
657 DEB(if (debugging && retval)
Hannes Reineckeb30d8bc2014-06-25 16:39:57 +0200658 st_printk(ST_DEB_MSG, STp,
659 "Async write error %x, return value %d.\n",
660 STbuffer->cmdstat.midlevel_result, retval);) /* end DEB */
Linus Torvalds1da177e2005-04-16 15:20:36 -0700661
662 return retval;
663}
664
665
666/* Step over EOF if it has been inadvertently crossed (ioctl not used because
667 it messes up the block number). */
668static int cross_eof(struct scsi_tape * STp, int forward)
669{
Mike Christie8b05b772005-11-08 04:06:44 -0600670 struct st_request *SRpnt;
Linus Torvalds1da177e2005-04-16 15:20:36 -0700671 unsigned char cmd[MAX_COMMAND_SIZE];
672
673 cmd[0] = SPACE;
674 cmd[1] = 0x01; /* Space FileMarks */
675 if (forward) {
676 cmd[2] = cmd[3] = 0;
677 cmd[4] = 1;
678 } else
679 cmd[2] = cmd[3] = cmd[4] = 0xff; /* -1 filemarks */
680 cmd[5] = 0;
681
Hannes Reineckeb30d8bc2014-06-25 16:39:57 +0200682 DEBC_printk(STp, "Stepping over filemark %s.\n",
683 forward ? "forward" : "backward");
Linus Torvalds1da177e2005-04-16 15:20:36 -0700684
Kai Makisara02ae2c02008-12-18 14:49:50 +0900685 SRpnt = st_do_scsi(NULL, STp, cmd, 0, DMA_NONE,
686 STp->device->request_queue->rq_timeout,
687 MAX_RETRIES, 1);
Linus Torvalds1da177e2005-04-16 15:20:36 -0700688 if (!SRpnt)
Kai Makisara02ae2c02008-12-18 14:49:50 +0900689 return (STp->buffer)->syscall_result;
Linus Torvalds1da177e2005-04-16 15:20:36 -0700690
Kai Makisara02ae2c02008-12-18 14:49:50 +0900691 st_release_request(SRpnt);
692 SRpnt = NULL;
Linus Torvalds1da177e2005-04-16 15:20:36 -0700693
694 if ((STp->buffer)->cmdstat.midlevel_result != 0)
Hannes Reineckeb30d8bc2014-06-25 16:39:57 +0200695 st_printk(KERN_ERR, STp,
696 "Stepping over filemark %s failed.\n",
697 forward ? "forward" : "backward");
Linus Torvalds1da177e2005-04-16 15:20:36 -0700698
Kai Makisara02ae2c02008-12-18 14:49:50 +0900699 return (STp->buffer)->syscall_result;
Linus Torvalds1da177e2005-04-16 15:20:36 -0700700}
701
702
703/* Flush the write buffer (never need to write if variable blocksize). */
Adrian Bunk8ef8d592008-04-14 17:17:16 +0300704static int st_flush_write_buffer(struct scsi_tape * STp)
Linus Torvalds1da177e2005-04-16 15:20:36 -0700705{
Kai Makisara786231a2008-07-11 15:06:40 +0300706 int transfer, blks;
Linus Torvalds1da177e2005-04-16 15:20:36 -0700707 int result;
708 unsigned char cmd[MAX_COMMAND_SIZE];
Mike Christie8b05b772005-11-08 04:06:44 -0600709 struct st_request *SRpnt;
Linus Torvalds1da177e2005-04-16 15:20:36 -0700710 struct st_partstat *STps;
711
712 result = write_behind_check(STp);
713 if (result)
714 return result;
715
716 result = 0;
717 if (STp->dirty == 1) {
718
Kai Makisara786231a2008-07-11 15:06:40 +0300719 transfer = STp->buffer->buffer_bytes;
Hannes Reineckeb30d8bc2014-06-25 16:39:57 +0200720 DEBC_printk(STp, "Flushing %d bytes.\n", transfer);
Linus Torvalds1da177e2005-04-16 15:20:36 -0700721
Linus Torvalds1da177e2005-04-16 15:20:36 -0700722 memset(cmd, 0, MAX_COMMAND_SIZE);
723 cmd[0] = WRITE_6;
724 cmd[1] = 1;
725 blks = transfer / STp->block_size;
726 cmd[2] = blks >> 16;
727 cmd[3] = blks >> 8;
728 cmd[4] = blks;
729
730 SRpnt = st_do_scsi(NULL, STp, cmd, transfer, DMA_TO_DEVICE,
James Bottomleya02488e2008-11-30 10:36:26 -0600731 STp->device->request_queue->rq_timeout,
732 MAX_WRITE_RETRIES, 1);
Linus Torvalds1da177e2005-04-16 15:20:36 -0700733 if (!SRpnt)
734 return (STp->buffer)->syscall_result;
735
736 STps = &(STp->ps[STp->partition]);
737 if ((STp->buffer)->syscall_result != 0) {
738 struct st_cmdstatus *cmdstatp = &STp->buffer->cmdstat;
739
740 if (cmdstatp->have_sense && !cmdstatp->deferred &&
741 (cmdstatp->flags & SENSE_EOM) &&
742 (cmdstatp->sense_hdr.sense_key == NO_SENSE ||
743 cmdstatp->sense_hdr.sense_key == RECOVERED_ERROR) &&
744 (!cmdstatp->remainder_valid ||
745 cmdstatp->uremainder64 == 0)) { /* All written at EOM early warning */
746 STp->dirty = 0;
747 (STp->buffer)->buffer_bytes = 0;
748 if (STps->drv_block >= 0)
749 STps->drv_block += blks;
750 result = (-ENOSPC);
751 } else {
Hannes Reineckeb30d8bc2014-06-25 16:39:57 +0200752 st_printk(KERN_ERR, STp, "Error on flush.\n");
Linus Torvalds1da177e2005-04-16 15:20:36 -0700753 STps->drv_block = (-1);
754 result = (-EIO);
755 }
756 } else {
757 if (STps->drv_block >= 0)
758 STps->drv_block += blks;
759 STp->dirty = 0;
760 (STp->buffer)->buffer_bytes = 0;
761 }
Mike Christie8b05b772005-11-08 04:06:44 -0600762 st_release_request(SRpnt);
Linus Torvalds1da177e2005-04-16 15:20:36 -0700763 SRpnt = NULL;
764 }
765 return result;
766}
767
768
769/* Flush the tape buffer. The tape will be positioned correctly unless
770 seek_next is true. */
771static int flush_buffer(struct scsi_tape *STp, int seek_next)
772{
773 int backspace, result;
774 struct st_buffer *STbuffer;
775 struct st_partstat *STps;
776
777 STbuffer = STp->buffer;
778
779 /*
780 * If there was a bus reset, block further access
781 * to this device.
782 */
783 if (STp->pos_unknown)
784 return (-EIO);
785
786 if (STp->ready != ST_READY)
787 return 0;
788 STps = &(STp->ps[STp->partition]);
789 if (STps->rw == ST_WRITING) /* Writing */
Adrian Bunk8ef8d592008-04-14 17:17:16 +0300790 return st_flush_write_buffer(STp);
Linus Torvalds1da177e2005-04-16 15:20:36 -0700791
792 if (STp->block_size == 0)
793 return 0;
794
795 backspace = ((STp->buffer)->buffer_bytes +
796 (STp->buffer)->read_pointer) / STp->block_size -
797 ((STp->buffer)->read_pointer + STp->block_size - 1) /
798 STp->block_size;
799 (STp->buffer)->buffer_bytes = 0;
800 (STp->buffer)->read_pointer = 0;
801 result = 0;
802 if (!seek_next) {
803 if (STps->eof == ST_FM_HIT) {
804 result = cross_eof(STp, 0); /* Back over the EOF hit */
805 if (!result)
806 STps->eof = ST_NOEOF;
807 else {
808 if (STps->drv_file >= 0)
809 STps->drv_file++;
810 STps->drv_block = 0;
811 }
812 }
813 if (!result && backspace > 0)
814 result = st_int_ioctl(STp, MTBSR, backspace);
815 } else if (STps->eof == ST_FM_HIT) {
816 if (STps->drv_file >= 0)
817 STps->drv_file++;
818 STps->drv_block = 0;
819 STps->eof = ST_NOEOF;
820 }
821 return result;
822
823}
824
825/* Set the mode parameters */
826static int set_mode_densblk(struct scsi_tape * STp, struct st_modedef * STm)
827{
828 int set_it = 0;
829 unsigned long arg;
Linus Torvalds1da177e2005-04-16 15:20:36 -0700830
831 if (!STp->density_changed &&
832 STm->default_density >= 0 &&
833 STm->default_density != STp->density) {
834 arg = STm->default_density;
835 set_it = 1;
836 } else
837 arg = STp->density;
838 arg <<= MT_ST_DENSITY_SHIFT;
839 if (!STp->blksize_changed &&
840 STm->default_blksize >= 0 &&
841 STm->default_blksize != STp->block_size) {
842 arg |= STm->default_blksize;
843 set_it = 1;
844 } else
845 arg |= STp->block_size;
846 if (set_it &&
847 st_int_ioctl(STp, SET_DENS_AND_BLK, arg)) {
Hannes Reineckeb30d8bc2014-06-25 16:39:57 +0200848 st_printk(KERN_WARNING, STp,
849 "Can't set default block size to %d bytes "
850 "and density %x.\n",
851 STm->default_blksize, STm->default_density);
Linus Torvalds1da177e2005-04-16 15:20:36 -0700852 if (modes_defined)
853 return (-EINVAL);
854 }
855 return 0;
856}
857
858
Mike Christie8b05b772005-11-08 04:06:44 -0600859/* Lock or unlock the drive door. Don't use when st_request allocated. */
Linus Torvalds1da177e2005-04-16 15:20:36 -0700860static int do_door_lock(struct scsi_tape * STp, int do_lock)
861{
862 int retval, cmd;
Linus Torvalds1da177e2005-04-16 15:20:36 -0700863
864 cmd = do_lock ? SCSI_IOCTL_DOORLOCK : SCSI_IOCTL_DOORUNLOCK;
Hannes Reineckeb30d8bc2014-06-25 16:39:57 +0200865 DEBC_printk(STp, "%socking drive door.\n", do_lock ? "L" : "Unl");
Linus Torvalds1da177e2005-04-16 15:20:36 -0700866 retval = scsi_ioctl(STp->device, cmd, NULL);
867 if (!retval) {
868 STp->door_locked = do_lock ? ST_LOCKED_EXPLICIT : ST_UNLOCKED;
869 }
870 else {
871 STp->door_locked = ST_LOCK_FAILS;
872 }
873 return retval;
874}
875
876
877/* Set the internal state after reset */
878static void reset_state(struct scsi_tape *STp)
879{
880 int i;
881 struct st_partstat *STps;
882
883 STp->pos_unknown = 0;
884 for (i = 0; i < ST_NBR_PARTITIONS; i++) {
885 STps = &(STp->ps[i]);
886 STps->rw = ST_IDLE;
887 STps->eof = ST_NOEOF;
888 STps->at_sm = 0;
889 STps->last_block_valid = 0;
890 STps->drv_block = -1;
891 STps->drv_file = -1;
892 }
893 if (STp->can_partitions) {
894 STp->partition = find_partition(STp);
895 if (STp->partition < 0)
896 STp->partition = 0;
897 STp->new_partition = STp->partition;
898 }
899}
900
901/* Test if the drive is ready. Returns either one of the codes below or a negative system
902 error code. */
903#define CHKRES_READY 0
904#define CHKRES_NEW_SESSION 1
905#define CHKRES_NOT_READY 2
906#define CHKRES_NO_TAPE 3
907
908#define MAX_ATTENTIONS 10
909
910static int test_ready(struct scsi_tape *STp, int do_wait)
911{
912 int attentions, waits, max_wait, scode;
913 int retval = CHKRES_READY, new_session = 0;
914 unsigned char cmd[MAX_COMMAND_SIZE];
Kai Makisara02ae2c02008-12-18 14:49:50 +0900915 struct st_request *SRpnt = NULL;
Linus Torvalds1da177e2005-04-16 15:20:36 -0700916 struct st_cmdstatus *cmdstatp = &STp->buffer->cmdstat;
917
918 max_wait = do_wait ? ST_BLOCK_SECONDS : 0;
919
920 for (attentions=waits=0; ; ) {
921 memset((void *) &cmd[0], 0, MAX_COMMAND_SIZE);
922 cmd[0] = TEST_UNIT_READY;
Kai Makisara02ae2c02008-12-18 14:49:50 +0900923 SRpnt = st_do_scsi(SRpnt, STp, cmd, 0, DMA_NONE,
924 STp->long_timeout, MAX_READY_RETRIES, 1);
Linus Torvalds1da177e2005-04-16 15:20:36 -0700925
Kai Makisara02ae2c02008-12-18 14:49:50 +0900926 if (!SRpnt) {
927 retval = (STp->buffer)->syscall_result;
Linus Torvalds1da177e2005-04-16 15:20:36 -0700928 break;
Kai Makisara02ae2c02008-12-18 14:49:50 +0900929 }
Linus Torvalds1da177e2005-04-16 15:20:36 -0700930
931 if (cmdstatp->have_sense) {
932
933 scode = cmdstatp->sense_hdr.sense_key;
934
935 if (scode == UNIT_ATTENTION) { /* New media? */
936 new_session = 1;
937 if (attentions < MAX_ATTENTIONS) {
938 attentions++;
939 continue;
940 }
941 else {
942 retval = (-EIO);
943 break;
944 }
945 }
946
947 if (scode == NOT_READY) {
948 if (waits < max_wait) {
949 if (msleep_interruptible(1000)) {
950 retval = (-EINTR);
951 break;
952 }
953 waits++;
954 continue;
955 }
956 else {
957 if ((STp->device)->scsi_level >= SCSI_2 &&
958 cmdstatp->sense_hdr.asc == 0x3a) /* Check ASC */
959 retval = CHKRES_NO_TAPE;
960 else
961 retval = CHKRES_NOT_READY;
962 break;
963 }
964 }
965 }
966
967 retval = (STp->buffer)->syscall_result;
968 if (!retval)
969 retval = new_session ? CHKRES_NEW_SESSION : CHKRES_READY;
970 break;
971 }
972
Kai Makisara02ae2c02008-12-18 14:49:50 +0900973 if (SRpnt != NULL)
974 st_release_request(SRpnt);
Linus Torvalds1da177e2005-04-16 15:20:36 -0700975 return retval;
976}
977
978
979/* See if the drive is ready and gather information about the tape. Return values:
980 < 0 negative error code from errno.h
981 0 drive ready
982 1 drive not ready (possibly no tape)
983*/
984static int check_tape(struct scsi_tape *STp, struct file *filp)
985{
986 int i, retval, new_session = 0, do_wait;
987 unsigned char cmd[MAX_COMMAND_SIZE], saved_cleaning;
988 unsigned short st_flags = filp->f_flags;
Mike Christie8b05b772005-11-08 04:06:44 -0600989 struct st_request *SRpnt = NULL;
Linus Torvalds1da177e2005-04-16 15:20:36 -0700990 struct st_modedef *STm;
991 struct st_partstat *STps;
Al Viro496ad9a2013-01-23 17:07:38 -0500992 struct inode *inode = file_inode(filp);
Linus Torvalds1da177e2005-04-16 15:20:36 -0700993 int mode = TAPE_MODE(inode);
994
995 STp->ready = ST_READY;
996
997 if (mode != STp->current_mode) {
Hannes Reineckeb30d8bc2014-06-25 16:39:57 +0200998 DEBC_printk(STp, "Mode change from %d to %d.\n",
999 STp->current_mode, mode);
Linus Torvalds1da177e2005-04-16 15:20:36 -07001000 new_session = 1;
1001 STp->current_mode = mode;
1002 }
1003 STm = &(STp->modes[STp->current_mode]);
1004
1005 saved_cleaning = STp->cleaning_req;
1006 STp->cleaning_req = 0;
1007
1008 do_wait = ((filp->f_flags & O_NONBLOCK) == 0);
1009 retval = test_ready(STp, do_wait);
1010
1011 if (retval < 0)
1012 goto err_out;
1013
1014 if (retval == CHKRES_NEW_SESSION) {
1015 STp->pos_unknown = 0;
1016 STp->partition = STp->new_partition = 0;
1017 if (STp->can_partitions)
1018 STp->nbr_partitions = 1; /* This guess will be updated later
1019 if necessary */
1020 for (i = 0; i < ST_NBR_PARTITIONS; i++) {
1021 STps = &(STp->ps[i]);
1022 STps->rw = ST_IDLE;
1023 STps->eof = ST_NOEOF;
1024 STps->at_sm = 0;
1025 STps->last_block_valid = 0;
1026 STps->drv_block = 0;
1027 STps->drv_file = 0;
1028 }
1029 new_session = 1;
1030 }
1031 else {
1032 STp->cleaning_req |= saved_cleaning;
1033
1034 if (retval == CHKRES_NOT_READY || retval == CHKRES_NO_TAPE) {
1035 if (retval == CHKRES_NO_TAPE)
1036 STp->ready = ST_NO_TAPE;
1037 else
1038 STp->ready = ST_NOT_READY;
1039
1040 STp->density = 0; /* Clear the erroneous "residue" */
1041 STp->write_prot = 0;
1042 STp->block_size = 0;
1043 STp->ps[0].drv_file = STp->ps[0].drv_block = (-1);
1044 STp->partition = STp->new_partition = 0;
1045 STp->door_locked = ST_UNLOCKED;
1046 return CHKRES_NOT_READY;
1047 }
1048 }
1049
1050 if (STp->omit_blklims)
1051 STp->min_block = STp->max_block = (-1);
1052 else {
1053 memset((void *) &cmd[0], 0, MAX_COMMAND_SIZE);
1054 cmd[0] = READ_BLOCK_LIMITS;
1055
Kai Makisara02ae2c02008-12-18 14:49:50 +09001056 SRpnt = st_do_scsi(SRpnt, STp, cmd, 6, DMA_FROM_DEVICE,
1057 STp->device->request_queue->rq_timeout,
1058 MAX_READY_RETRIES, 1);
1059 if (!SRpnt) {
1060 retval = (STp->buffer)->syscall_result;
Linus Torvalds1da177e2005-04-16 15:20:36 -07001061 goto err_out;
1062 }
1063
Mike Christie8b05b772005-11-08 04:06:44 -06001064 if (!SRpnt->result && !STp->buffer->cmdstat.have_sense) {
Linus Torvalds1da177e2005-04-16 15:20:36 -07001065 STp->max_block = ((STp->buffer)->b_data[1] << 16) |
1066 ((STp->buffer)->b_data[2] << 8) | (STp->buffer)->b_data[3];
1067 STp->min_block = ((STp->buffer)->b_data[4] << 8) |
1068 (STp->buffer)->b_data[5];
1069 if ( DEB( debugging || ) !STp->inited)
Hannes Reineckeb30d8bc2014-06-25 16:39:57 +02001070 st_printk(KERN_INFO, STp,
1071 "Block limits %d - %d bytes.\n",
1072 STp->min_block, STp->max_block);
Linus Torvalds1da177e2005-04-16 15:20:36 -07001073 } else {
1074 STp->min_block = STp->max_block = (-1);
Hannes Reineckeb30d8bc2014-06-25 16:39:57 +02001075 DEBC_printk(STp, "Can't read block limits.\n");
Linus Torvalds1da177e2005-04-16 15:20:36 -07001076 }
1077 }
1078
1079 memset((void *) &cmd[0], 0, MAX_COMMAND_SIZE);
1080 cmd[0] = MODE_SENSE;
1081 cmd[4] = 12;
1082
Kai Makisara02ae2c02008-12-18 14:49:50 +09001083 SRpnt = st_do_scsi(SRpnt, STp, cmd, 12, DMA_FROM_DEVICE,
1084 STp->device->request_queue->rq_timeout,
1085 MAX_READY_RETRIES, 1);
1086 if (!SRpnt) {
1087 retval = (STp->buffer)->syscall_result;
Linus Torvalds1da177e2005-04-16 15:20:36 -07001088 goto err_out;
1089 }
1090
1091 if ((STp->buffer)->syscall_result != 0) {
Hannes Reineckeb30d8bc2014-06-25 16:39:57 +02001092 DEBC_printk(STp, "No Mode Sense.\n");
Linus Torvalds1da177e2005-04-16 15:20:36 -07001093 STp->block_size = ST_DEFAULT_BLOCK; /* Educated guess (?) */
1094 (STp->buffer)->syscall_result = 0; /* Prevent error propagation */
1095 STp->drv_write_prot = 0;
1096 } else {
Hannes Reineckeb30d8bc2014-06-25 16:39:57 +02001097 DEBC_printk(STp,"Mode sense. Length %d, "
1098 "medium %x, WBS %x, BLL %d\n",
1099 (STp->buffer)->b_data[0],
1100 (STp->buffer)->b_data[1],
1101 (STp->buffer)->b_data[2],
1102 (STp->buffer)->b_data[3]);
Linus Torvalds1da177e2005-04-16 15:20:36 -07001103
1104 if ((STp->buffer)->b_data[3] >= 8) {
1105 STp->drv_buffer = ((STp->buffer)->b_data[2] >> 4) & 7;
1106 STp->density = (STp->buffer)->b_data[4];
1107 STp->block_size = (STp->buffer)->b_data[9] * 65536 +
1108 (STp->buffer)->b_data[10] * 256 + (STp->buffer)->b_data[11];
Hannes Reineckeb30d8bc2014-06-25 16:39:57 +02001109 DEBC_printk(STp, "Density %x, tape length: %x, "
1110 "drv buffer: %d\n",
1111 STp->density,
1112 (STp->buffer)->b_data[5] * 65536 +
1113 (STp->buffer)->b_data[6] * 256 +
1114 (STp->buffer)->b_data[7],
1115 STp->drv_buffer);
Linus Torvalds1da177e2005-04-16 15:20:36 -07001116 }
1117 STp->drv_write_prot = ((STp->buffer)->b_data[2] & 0x80) != 0;
Lee Duncanc743e442012-03-01 12:41:01 -08001118 if (!STp->drv_buffer && STp->immediate_filemark) {
Hannes Reineckeb30d8bc2014-06-25 16:39:57 +02001119 st_printk(KERN_WARNING, STp,
1120 "non-buffered tape: disabling "
1121 "writing immediate filemarks\n");
Lee Duncanc743e442012-03-01 12:41:01 -08001122 STp->immediate_filemark = 0;
1123 }
Linus Torvalds1da177e2005-04-16 15:20:36 -07001124 }
Mike Christie8b05b772005-11-08 04:06:44 -06001125 st_release_request(SRpnt);
Linus Torvalds1da177e2005-04-16 15:20:36 -07001126 SRpnt = NULL;
Hannes Reineckeb30d8bc2014-06-25 16:39:57 +02001127 STp->inited = 1;
Linus Torvalds1da177e2005-04-16 15:20:36 -07001128
1129 if (STp->block_size > 0)
1130 (STp->buffer)->buffer_blocks =
Hannes Reineckeb30d8bc2014-06-25 16:39:57 +02001131 (STp->buffer)->buffer_size / STp->block_size;
Linus Torvalds1da177e2005-04-16 15:20:36 -07001132 else
1133 (STp->buffer)->buffer_blocks = 1;
1134 (STp->buffer)->buffer_bytes = (STp->buffer)->read_pointer = 0;
1135
Hannes Reineckeb30d8bc2014-06-25 16:39:57 +02001136 DEBC_printk(STp, "Block size: %d, buffer size: %d (%d blocks).\n",
1137 STp->block_size, (STp->buffer)->buffer_size,
1138 (STp->buffer)->buffer_blocks);
Linus Torvalds1da177e2005-04-16 15:20:36 -07001139
1140 if (STp->drv_write_prot) {
1141 STp->write_prot = 1;
1142
Hannes Reineckeb30d8bc2014-06-25 16:39:57 +02001143 DEBC_printk(STp, "Write protected\n");
Linus Torvalds1da177e2005-04-16 15:20:36 -07001144
1145 if (do_wait &&
1146 ((st_flags & O_ACCMODE) == O_WRONLY ||
1147 (st_flags & O_ACCMODE) == O_RDWR)) {
1148 retval = (-EROFS);
1149 goto err_out;
1150 }
1151 }
1152
1153 if (STp->can_partitions && STp->nbr_partitions < 1) {
1154 /* This code is reached when the device is opened for the first time
1155 after the driver has been initialized with tape in the drive and the
1156 partition support has been enabled. */
Hannes Reineckeb30d8bc2014-06-25 16:39:57 +02001157 DEBC_printk(STp, "Updating partition number in status.\n");
Linus Torvalds1da177e2005-04-16 15:20:36 -07001158 if ((STp->partition = find_partition(STp)) < 0) {
1159 retval = STp->partition;
1160 goto err_out;
1161 }
1162 STp->new_partition = STp->partition;
1163 STp->nbr_partitions = 1; /* This guess will be updated when necessary */
1164 }
1165
1166 if (new_session) { /* Change the drive parameters for the new mode */
1167 STp->density_changed = STp->blksize_changed = 0;
1168 STp->compression_changed = 0;
1169 if (!(STm->defaults_for_writes) &&
1170 (retval = set_mode_densblk(STp, STm)) < 0)
1171 goto err_out;
1172
1173 if (STp->default_drvbuffer != 0xff) {
1174 if (st_int_ioctl(STp, MTSETDRVBUFFER, STp->default_drvbuffer))
Hannes Reineckeb30d8bc2014-06-25 16:39:57 +02001175 st_printk(KERN_WARNING, STp,
1176 "Can't set default drive "
1177 "buffering to %d.\n",
1178 STp->default_drvbuffer);
Linus Torvalds1da177e2005-04-16 15:20:36 -07001179 }
1180 }
1181
1182 return CHKRES_READY;
1183
1184 err_out:
1185 return retval;
1186}
1187
1188
Jonathan Corbetb3369c62008-05-15 16:08:15 -06001189 /* Open the device. Needs to take the BKL only because of incrementing the SCSI host
Linus Torvalds1da177e2005-04-16 15:20:36 -07001190 module count. */
1191static int st_open(struct inode *inode, struct file *filp)
1192{
1193 int i, retval = (-EIO);
Oliver Neukum46a243f2012-01-15 00:16:51 +01001194 int resumed = 0;
Linus Torvalds1da177e2005-04-16 15:20:36 -07001195 struct scsi_tape *STp;
1196 struct st_partstat *STps;
1197 int dev = TAPE_NR(inode);
Linus Torvalds1da177e2005-04-16 15:20:36 -07001198
1199 /*
1200 * We really want to do nonseekable_open(inode, filp); here, but some
1201 * versions of tar incorrectly call lseek on tapes and bail out if that
1202 * fails. So we disallow pread() and pwrite(), but permit lseeks.
1203 */
1204 filp->f_mode &= ~(FMODE_PREAD | FMODE_PWRITE);
1205
Jonathan Corbetb3369c62008-05-15 16:08:15 -06001206 if (!(STp = scsi_tape_get(dev))) {
Kai Makisaraf03a5672005-08-02 13:40:47 +03001207 return -ENXIO;
Jonathan Corbetb3369c62008-05-15 16:08:15 -06001208 }
Kai Makisaraf03a5672005-08-02 13:40:47 +03001209
Linus Torvalds1da177e2005-04-16 15:20:36 -07001210 filp->private_data = STp;
Linus Torvalds1da177e2005-04-16 15:20:36 -07001211
Jeff Mahoney6c648d92012-08-18 15:20:39 -04001212 spin_lock(&st_use_lock);
Linus Torvalds1da177e2005-04-16 15:20:36 -07001213 if (STp->in_use) {
Jeff Mahoney6c648d92012-08-18 15:20:39 -04001214 spin_unlock(&st_use_lock);
Kai Makisaraf03a5672005-08-02 13:40:47 +03001215 scsi_tape_put(STp);
Hannes Reineckeb30d8bc2014-06-25 16:39:57 +02001216 DEBC_printk(STp, "Device already in use.\n");
Linus Torvalds1da177e2005-04-16 15:20:36 -07001217 return (-EBUSY);
1218 }
1219
Linus Torvalds1da177e2005-04-16 15:20:36 -07001220 STp->in_use = 1;
Jeff Mahoney6c648d92012-08-18 15:20:39 -04001221 spin_unlock(&st_use_lock);
Linus Torvalds1da177e2005-04-16 15:20:36 -07001222 STp->rew_at_close = STp->autorew_dev = (iminor(inode) & 0x80) == 0;
1223
Oliver Neukum46a243f2012-01-15 00:16:51 +01001224 if (scsi_autopm_get_device(STp->device) < 0) {
1225 retval = -EIO;
1226 goto err_out;
1227 }
1228 resumed = 1;
Linus Torvalds1da177e2005-04-16 15:20:36 -07001229 if (!scsi_block_when_processing_errors(STp->device)) {
1230 retval = (-ENXIO);
1231 goto err_out;
1232 }
1233
1234 /* See that we have at least a one page buffer available */
1235 if (!enlarge_buffer(STp->buffer, PAGE_SIZE, STp->restr_dma)) {
Hannes Reineckeb30d8bc2014-06-25 16:39:57 +02001236 st_printk(KERN_WARNING, STp,
1237 "Can't allocate one page tape buffer.\n");
Linus Torvalds1da177e2005-04-16 15:20:36 -07001238 retval = (-EOVERFLOW);
1239 goto err_out;
1240 }
1241
Kai Makisara40f6b362008-02-24 22:23:24 +02001242 (STp->buffer)->cleared = 0;
Linus Torvalds1da177e2005-04-16 15:20:36 -07001243 (STp->buffer)->writing = 0;
1244 (STp->buffer)->syscall_result = 0;
1245
1246 STp->write_prot = ((filp->f_flags & O_ACCMODE) == O_RDONLY);
1247
1248 STp->dirty = 0;
1249 for (i = 0; i < ST_NBR_PARTITIONS; i++) {
1250 STps = &(STp->ps[i]);
1251 STps->rw = ST_IDLE;
1252 }
Kai Makisara9abe16c2007-02-03 13:21:29 +02001253 STp->try_dio_now = STp->try_dio;
Linus Torvalds1da177e2005-04-16 15:20:36 -07001254 STp->recover_count = 0;
1255 DEB( STp->nbr_waits = STp->nbr_finished = 0;
Kai Makisaradeee13d2008-02-22 20:11:21 +02001256 STp->nbr_requests = STp->nbr_dio = STp->nbr_pages = 0; )
Linus Torvalds1da177e2005-04-16 15:20:36 -07001257
1258 retval = check_tape(STp, filp);
1259 if (retval < 0)
1260 goto err_out;
1261 if ((filp->f_flags & O_NONBLOCK) == 0 &&
1262 retval != CHKRES_READY) {
Kai Makisara413f7322006-10-05 22:59:46 +03001263 if (STp->ready == NO_TAPE)
1264 retval = (-ENOMEDIUM);
1265 else
1266 retval = (-EIO);
Linus Torvalds1da177e2005-04-16 15:20:36 -07001267 goto err_out;
1268 }
1269 return 0;
1270
1271 err_out:
1272 normalize_buffer(STp->buffer);
Hannes Reinecke0644f532012-09-10 15:36:44 -07001273 spin_lock(&st_use_lock);
Linus Torvalds1da177e2005-04-16 15:20:36 -07001274 STp->in_use = 0;
Hannes Reinecke0644f532012-09-10 15:36:44 -07001275 spin_unlock(&st_use_lock);
Kai Makisaraf03a5672005-08-02 13:40:47 +03001276 scsi_tape_put(STp);
Oliver Neukum46a243f2012-01-15 00:16:51 +01001277 if (resumed)
1278 scsi_autopm_put_device(STp->device);
Linus Torvalds1da177e2005-04-16 15:20:36 -07001279 return retval;
1280
1281}
1282
1283
1284/* Flush the tape buffer before close */
Miklos Szeredi75e1fcc2006-06-23 02:05:12 -07001285static int st_flush(struct file *filp, fl_owner_t id)
Linus Torvalds1da177e2005-04-16 15:20:36 -07001286{
1287 int result = 0, result2;
1288 unsigned char cmd[MAX_COMMAND_SIZE];
Mike Christie8b05b772005-11-08 04:06:44 -06001289 struct st_request *SRpnt;
Linus Torvalds1da177e2005-04-16 15:20:36 -07001290 struct scsi_tape *STp = filp->private_data;
1291 struct st_modedef *STm = &(STp->modes[STp->current_mode]);
1292 struct st_partstat *STps = &(STp->ps[STp->partition]);
Linus Torvalds1da177e2005-04-16 15:20:36 -07001293
1294 if (file_count(filp) > 1)
1295 return 0;
1296
1297 if (STps->rw == ST_WRITING && !STp->pos_unknown) {
Adrian Bunk8ef8d592008-04-14 17:17:16 +03001298 result = st_flush_write_buffer(STp);
Linus Torvalds1da177e2005-04-16 15:20:36 -07001299 if (result != 0 && result != (-ENOSPC))
1300 goto out;
1301 }
1302
1303 if (STp->can_partitions &&
1304 (result2 = switch_partition(STp)) < 0) {
Hannes Reineckeb30d8bc2014-06-25 16:39:57 +02001305 DEBC_printk(STp, "switch_partition at close failed.\n");
Linus Torvalds1da177e2005-04-16 15:20:36 -07001306 if (result == 0)
1307 result = result2;
1308 goto out;
1309 }
1310
1311 DEBC( if (STp->nbr_requests)
Hannes Reineckeb30d8bc2014-06-25 16:39:57 +02001312 st_printk(KERN_DEBUG, STp,
1313 "Number of r/w requests %d, dio used in %d, "
1314 "pages %d.\n", STp->nbr_requests, STp->nbr_dio,
1315 STp->nbr_pages));
Linus Torvalds1da177e2005-04-16 15:20:36 -07001316
1317 if (STps->rw == ST_WRITING && !STp->pos_unknown) {
1318 struct st_cmdstatus *cmdstatp = &STp->buffer->cmdstat;
1319
Hannes Reineckeb30d8bc2014-06-25 16:39:57 +02001320#if DEBUG
1321 DEBC_printk(STp, "Async write waits %d, finished %d.\n",
1322 STp->nbr_waits, STp->nbr_finished);
1323#endif
Linus Torvalds1da177e2005-04-16 15:20:36 -07001324 memset(cmd, 0, MAX_COMMAND_SIZE);
1325 cmd[0] = WRITE_FILEMARKS;
Lee Duncanc743e442012-03-01 12:41:01 -08001326 if (STp->immediate_filemark)
1327 cmd[1] = 1;
Linus Torvalds1da177e2005-04-16 15:20:36 -07001328 cmd[4] = 1 + STp->two_fm;
1329
Kai Makisara02ae2c02008-12-18 14:49:50 +09001330 SRpnt = st_do_scsi(NULL, STp, cmd, 0, DMA_NONE,
1331 STp->device->request_queue->rq_timeout,
1332 MAX_WRITE_RETRIES, 1);
Linus Torvalds1da177e2005-04-16 15:20:36 -07001333 if (!SRpnt) {
Kai Makisara02ae2c02008-12-18 14:49:50 +09001334 result = (STp->buffer)->syscall_result;
Linus Torvalds1da177e2005-04-16 15:20:36 -07001335 goto out;
1336 }
1337
1338 if (STp->buffer->syscall_result == 0 ||
1339 (cmdstatp->have_sense && !cmdstatp->deferred &&
1340 (cmdstatp->flags & SENSE_EOM) &&
1341 (cmdstatp->sense_hdr.sense_key == NO_SENSE ||
1342 cmdstatp->sense_hdr.sense_key == RECOVERED_ERROR) &&
1343 (!cmdstatp->remainder_valid || cmdstatp->uremainder64 == 0))) {
1344 /* Write successful at EOM */
Mike Christie8b05b772005-11-08 04:06:44 -06001345 st_release_request(SRpnt);
Linus Torvalds1da177e2005-04-16 15:20:36 -07001346 SRpnt = NULL;
1347 if (STps->drv_file >= 0)
1348 STps->drv_file++;
1349 STps->drv_block = 0;
1350 if (STp->two_fm)
1351 cross_eof(STp, 0);
1352 STps->eof = ST_FM;
1353 }
1354 else { /* Write error */
Mike Christie8b05b772005-11-08 04:06:44 -06001355 st_release_request(SRpnt);
Linus Torvalds1da177e2005-04-16 15:20:36 -07001356 SRpnt = NULL;
Hannes Reineckeb30d8bc2014-06-25 16:39:57 +02001357 st_printk(KERN_ERR, STp,
1358 "Error on write filemark.\n");
Linus Torvalds1da177e2005-04-16 15:20:36 -07001359 if (result == 0)
1360 result = (-EIO);
1361 }
1362
Hannes Reineckeb30d8bc2014-06-25 16:39:57 +02001363 DEBC_printk(STp, "Buffer flushed, %d EOF(s) written\n", cmd[4]);
Linus Torvalds1da177e2005-04-16 15:20:36 -07001364 } else if (!STp->rew_at_close) {
1365 STps = &(STp->ps[STp->partition]);
1366 if (!STm->sysv || STps->rw != ST_READING) {
1367 if (STp->can_bsr)
1368 result = flush_buffer(STp, 0);
1369 else if (STps->eof == ST_FM_HIT) {
1370 result = cross_eof(STp, 0);
1371 if (result) {
1372 if (STps->drv_file >= 0)
1373 STps->drv_file++;
1374 STps->drv_block = 0;
1375 STps->eof = ST_FM;
1376 } else
1377 STps->eof = ST_NOEOF;
1378 }
1379 } else if ((STps->eof == ST_NOEOF &&
1380 !(result = cross_eof(STp, 1))) ||
1381 STps->eof == ST_FM_HIT) {
1382 if (STps->drv_file >= 0)
1383 STps->drv_file++;
1384 STps->drv_block = 0;
1385 STps->eof = ST_FM;
1386 }
1387 }
1388
1389 out:
1390 if (STp->rew_at_close) {
1391 result2 = st_int_ioctl(STp, MTREW, 1);
1392 if (result == 0)
1393 result = result2;
1394 }
1395 return result;
1396}
1397
1398
1399/* Close the device and release it. BKL is not needed: this is the only thread
1400 accessing this tape. */
1401static int st_release(struct inode *inode, struct file *filp)
1402{
1403 int result = 0;
1404 struct scsi_tape *STp = filp->private_data;
1405
1406 if (STp->door_locked == ST_LOCKED_AUTO)
1407 do_door_lock(STp, 0);
1408
1409 normalize_buffer(STp->buffer);
Jeff Mahoney6c648d92012-08-18 15:20:39 -04001410 spin_lock(&st_use_lock);
Linus Torvalds1da177e2005-04-16 15:20:36 -07001411 STp->in_use = 0;
Jeff Mahoney6c648d92012-08-18 15:20:39 -04001412 spin_unlock(&st_use_lock);
Oliver Neukum46a243f2012-01-15 00:16:51 +01001413 scsi_autopm_put_device(STp->device);
Kai Makisaraf03a5672005-08-02 13:40:47 +03001414 scsi_tape_put(STp);
Linus Torvalds1da177e2005-04-16 15:20:36 -07001415
1416 return result;
1417}
1418
1419/* The checks common to both reading and writing */
1420static ssize_t rw_checks(struct scsi_tape *STp, struct file *filp, size_t count)
1421{
1422 ssize_t retval = 0;
1423
1424 /*
1425 * If we are in the middle of error recovery, don't let anyone
1426 * else try and use this device. Also, if error recovery fails, it
1427 * may try and take the device offline, in which case all further
1428 * access to the device is prohibited.
1429 */
1430 if (!scsi_block_when_processing_errors(STp->device)) {
1431 retval = (-ENXIO);
1432 goto out;
1433 }
1434
1435 if (STp->ready != ST_READY) {
1436 if (STp->ready == ST_NO_TAPE)
1437 retval = (-ENOMEDIUM);
1438 else
1439 retval = (-EIO);
1440 goto out;
1441 }
1442
1443 if (! STp->modes[STp->current_mode].defined) {
1444 retval = (-ENXIO);
1445 goto out;
1446 }
1447
1448
1449 /*
1450 * If there was a bus reset, block further access
1451 * to this device.
1452 */
1453 if (STp->pos_unknown) {
1454 retval = (-EIO);
1455 goto out;
1456 }
1457
1458 if (count == 0)
1459 goto out;
1460
Hannes Reineckeb30d8bc2014-06-25 16:39:57 +02001461 DEB(
Linus Torvalds1da177e2005-04-16 15:20:36 -07001462 if (!STp->in_use) {
Hannes Reineckeb30d8bc2014-06-25 16:39:57 +02001463 st_printk(ST_DEB_MSG, STp,
1464 "Incorrect device.\n");
Linus Torvalds1da177e2005-04-16 15:20:36 -07001465 retval = (-EIO);
1466 goto out;
1467 } ) /* end DEB */
1468
1469 if (STp->can_partitions &&
1470 (retval = switch_partition(STp)) < 0)
1471 goto out;
1472
1473 if (STp->block_size == 0 && STp->max_block > 0 &&
1474 (count < STp->min_block || count > STp->max_block)) {
1475 retval = (-EINVAL);
1476 goto out;
1477 }
1478
1479 if (STp->do_auto_lock && STp->door_locked == ST_UNLOCKED &&
1480 !do_door_lock(STp, 1))
1481 STp->door_locked = ST_LOCKED_AUTO;
1482
1483 out:
1484 return retval;
1485}
1486
1487
1488static int setup_buffering(struct scsi_tape *STp, const char __user *buf,
1489 size_t count, int is_read)
1490{
1491 int i, bufsize, retval = 0;
1492 struct st_buffer *STbp = STp->buffer;
1493
1494 if (is_read)
Kai Makisara9abe16c2007-02-03 13:21:29 +02001495 i = STp->try_dio_now && try_rdio;
Linus Torvalds1da177e2005-04-16 15:20:36 -07001496 else
Kai Makisara9abe16c2007-02-03 13:21:29 +02001497 i = STp->try_dio_now && try_wdio;
Mike Christie8b05b772005-11-08 04:06:44 -06001498
Linus Torvalds1da177e2005-04-16 15:20:36 -07001499 if (i && ((unsigned long)buf & queue_dma_alignment(
1500 STp->device->request_queue)) == 0) {
FUJITA Tomonori66207422008-12-18 14:49:43 +09001501 i = sgl_map_user_pages(STbp, STbp->use_sg, (unsigned long)buf,
1502 count, (is_read ? READ : WRITE));
Linus Torvalds1da177e2005-04-16 15:20:36 -07001503 if (i > 0) {
1504 STbp->do_dio = i;
1505 STbp->buffer_bytes = 0; /* can be used as transfer counter */
1506 }
1507 else
1508 STbp->do_dio = 0; /* fall back to buffering with any error */
1509 STbp->sg_segs = STbp->do_dio;
Linus Torvalds1da177e2005-04-16 15:20:36 -07001510 DEB(
1511 if (STbp->do_dio) {
1512 STp->nbr_dio++;
1513 STp->nbr_pages += STbp->do_dio;
Linus Torvalds1da177e2005-04-16 15:20:36 -07001514 }
1515 )
1516 } else
1517 STbp->do_dio = 0;
1518 DEB( STp->nbr_requests++; )
1519
1520 if (!STbp->do_dio) {
1521 if (STp->block_size)
1522 bufsize = STp->block_size > st_fixed_buffer_size ?
1523 STp->block_size : st_fixed_buffer_size;
Kai Makisara40f6b362008-02-24 22:23:24 +02001524 else {
Linus Torvalds1da177e2005-04-16 15:20:36 -07001525 bufsize = count;
Kai Makisara40f6b362008-02-24 22:23:24 +02001526 /* Make sure that data from previous user is not leaked even if
1527 HBA does not return correct residual */
1528 if (is_read && STp->sili && !STbp->cleared)
1529 clear_buffer(STbp);
1530 }
1531
Linus Torvalds1da177e2005-04-16 15:20:36 -07001532 if (bufsize > STbp->buffer_size &&
1533 !enlarge_buffer(STbp, bufsize, STp->restr_dma)) {
Hannes Reineckeb30d8bc2014-06-25 16:39:57 +02001534 st_printk(KERN_WARNING, STp,
1535 "Can't allocate %d byte tape buffer.\n",
1536 bufsize);
Linus Torvalds1da177e2005-04-16 15:20:36 -07001537 retval = (-EOVERFLOW);
1538 goto out;
1539 }
1540 if (STp->block_size)
1541 STbp->buffer_blocks = bufsize / STp->block_size;
1542 }
1543
1544 out:
1545 return retval;
1546}
1547
1548
1549/* Can be called more than once after each setup_buffer() */
Kai Makisara787926b2005-11-13 10:04:44 +02001550static void release_buffering(struct scsi_tape *STp, int is_read)
Linus Torvalds1da177e2005-04-16 15:20:36 -07001551{
1552 struct st_buffer *STbp;
1553
1554 STbp = STp->buffer;
1555 if (STbp->do_dio) {
FUJITA Tomonori66207422008-12-18 14:49:43 +09001556 sgl_unmap_user_pages(STbp, STbp->do_dio, is_read);
Linus Torvalds1da177e2005-04-16 15:20:36 -07001557 STbp->do_dio = 0;
Kai Makisara787926b2005-11-13 10:04:44 +02001558 STbp->sg_segs = 0;
Linus Torvalds1da177e2005-04-16 15:20:36 -07001559 }
1560}
1561
1562
1563/* Write command */
1564static ssize_t
1565st_write(struct file *filp, const char __user *buf, size_t count, loff_t * ppos)
1566{
1567 ssize_t total;
1568 ssize_t i, do_count, blks, transfer;
1569 ssize_t retval;
1570 int undone, retry_eot = 0, scode;
1571 int async_write;
1572 unsigned char cmd[MAX_COMMAND_SIZE];
1573 const char __user *b_point;
Mike Christie8b05b772005-11-08 04:06:44 -06001574 struct st_request *SRpnt = NULL;
Linus Torvalds1da177e2005-04-16 15:20:36 -07001575 struct scsi_tape *STp = filp->private_data;
1576 struct st_modedef *STm;
1577 struct st_partstat *STps;
1578 struct st_buffer *STbp;
Linus Torvalds1da177e2005-04-16 15:20:36 -07001579
Matthias Kaehlcke28f85002007-07-29 23:38:15 +02001580 if (mutex_lock_interruptible(&STp->lock))
Linus Torvalds1da177e2005-04-16 15:20:36 -07001581 return -ERESTARTSYS;
1582
1583 retval = rw_checks(STp, filp, count);
1584 if (retval || count == 0)
1585 goto out;
1586
1587 /* Write must be integral number of blocks */
1588 if (STp->block_size != 0 && (count % STp->block_size) != 0) {
Hannes Reineckeb30d8bc2014-06-25 16:39:57 +02001589 st_printk(KERN_WARNING, STp,
1590 "Write not multiple of tape block size.\n");
Linus Torvalds1da177e2005-04-16 15:20:36 -07001591 retval = (-EINVAL);
1592 goto out;
1593 }
1594
1595 STm = &(STp->modes[STp->current_mode]);
1596 STps = &(STp->ps[STp->partition]);
1597
1598 if (STp->write_prot) {
1599 retval = (-EACCES);
1600 goto out;
1601 }
1602
1603
1604 if (STps->rw == ST_READING) {
1605 retval = flush_buffer(STp, 0);
1606 if (retval)
1607 goto out;
1608 STps->rw = ST_WRITING;
1609 } else if (STps->rw != ST_WRITING &&
1610 STps->drv_file == 0 && STps->drv_block == 0) {
1611 if ((retval = set_mode_densblk(STp, STm)) < 0)
1612 goto out;
1613 if (STm->default_compression != ST_DONT_TOUCH &&
1614 !(STp->compression_changed)) {
1615 if (st_compression(STp, (STm->default_compression == ST_YES))) {
Hannes Reineckeb30d8bc2014-06-25 16:39:57 +02001616 st_printk(KERN_WARNING, STp,
1617 "Can't set default compression.\n");
Linus Torvalds1da177e2005-04-16 15:20:36 -07001618 if (modes_defined) {
1619 retval = (-EINVAL);
1620 goto out;
1621 }
1622 }
1623 }
1624 }
1625
1626 STbp = STp->buffer;
1627 i = write_behind_check(STp);
1628 if (i) {
1629 if (i == -ENOSPC)
1630 STps->eof = ST_EOM_OK;
1631 else
1632 STps->eof = ST_EOM_ERROR;
1633 }
1634
1635 if (STps->eof == ST_EOM_OK) {
1636 STps->eof = ST_EOD_1; /* allow next write */
1637 retval = (-ENOSPC);
1638 goto out;
1639 }
1640 else if (STps->eof == ST_EOM_ERROR) {
1641 retval = (-EIO);
1642 goto out;
1643 }
1644
1645 /* Check the buffer readability in cases where copy_user might catch
1646 the problems after some tape movement. */
1647 if (STp->block_size != 0 &&
1648 !STbp->do_dio &&
1649 (copy_from_user(&i, buf, 1) != 0 ||
1650 copy_from_user(&i, buf + count - 1, 1) != 0)) {
1651 retval = (-EFAULT);
1652 goto out;
1653 }
1654
1655 retval = setup_buffering(STp, buf, count, 0);
1656 if (retval)
1657 goto out;
1658
1659 total = count;
1660
1661 memset(cmd, 0, MAX_COMMAND_SIZE);
1662 cmd[0] = WRITE_6;
1663 cmd[1] = (STp->block_size != 0);
1664
1665 STps->rw = ST_WRITING;
1666
1667 b_point = buf;
1668 while (count > 0 && !retry_eot) {
1669
1670 if (STbp->do_dio) {
1671 do_count = count;
1672 }
1673 else {
1674 if (STp->block_size == 0)
1675 do_count = count;
1676 else {
1677 do_count = STbp->buffer_blocks * STp->block_size -
1678 STbp->buffer_bytes;
1679 if (do_count > count)
1680 do_count = count;
1681 }
1682
1683 i = append_to_buffer(b_point, STbp, do_count);
1684 if (i) {
1685 retval = i;
1686 goto out;
1687 }
1688 }
1689 count -= do_count;
1690 b_point += do_count;
1691
1692 async_write = STp->block_size == 0 && !STbp->do_dio &&
1693 STm->do_async_writes && STps->eof < ST_EOM_OK;
1694
1695 if (STp->block_size != 0 && STm->do_buffer_writes &&
Kai Makisara9abe16c2007-02-03 13:21:29 +02001696 !(STp->try_dio_now && try_wdio) && STps->eof < ST_EOM_OK &&
Linus Torvalds1da177e2005-04-16 15:20:36 -07001697 STbp->buffer_bytes < STbp->buffer_size) {
1698 STp->dirty = 1;
1699 /* Don't write a buffer that is not full enough. */
1700 if (!async_write && count == 0)
1701 break;
1702 }
1703
1704 retry_write:
1705 if (STp->block_size == 0)
1706 blks = transfer = do_count;
1707 else {
1708 if (!STbp->do_dio)
1709 blks = STbp->buffer_bytes;
1710 else
1711 blks = do_count;
1712 blks /= STp->block_size;
1713 transfer = blks * STp->block_size;
1714 }
1715 cmd[2] = blks >> 16;
1716 cmd[3] = blks >> 8;
1717 cmd[4] = blks;
1718
1719 SRpnt = st_do_scsi(SRpnt, STp, cmd, transfer, DMA_TO_DEVICE,
James Bottomleya02488e2008-11-30 10:36:26 -06001720 STp->device->request_queue->rq_timeout,
1721 MAX_WRITE_RETRIES, !async_write);
Linus Torvalds1da177e2005-04-16 15:20:36 -07001722 if (!SRpnt) {
1723 retval = STbp->syscall_result;
1724 goto out;
1725 }
Mike Christie8b05b772005-11-08 04:06:44 -06001726 if (async_write && !STbp->syscall_result) {
Linus Torvalds1da177e2005-04-16 15:20:36 -07001727 STbp->writing = transfer;
1728 STp->dirty = !(STbp->writing ==
1729 STbp->buffer_bytes);
1730 SRpnt = NULL; /* Prevent releasing this request! */
1731 DEB( STp->write_pending = 1; )
1732 break;
1733 }
1734
1735 if (STbp->syscall_result != 0) {
1736 struct st_cmdstatus *cmdstatp = &STp->buffer->cmdstat;
1737
Hannes Reineckeb30d8bc2014-06-25 16:39:57 +02001738 DEBC_printk(STp, "Error on write:\n");
Linus Torvalds1da177e2005-04-16 15:20:36 -07001739 if (cmdstatp->have_sense && (cmdstatp->flags & SENSE_EOM)) {
1740 scode = cmdstatp->sense_hdr.sense_key;
1741 if (cmdstatp->remainder_valid)
1742 undone = (int)cmdstatp->uremainder64;
1743 else if (STp->block_size == 0 &&
1744 scode == VOLUME_OVERFLOW)
1745 undone = transfer;
1746 else
1747 undone = 0;
1748 if (STp->block_size != 0)
1749 undone *= STp->block_size;
1750 if (undone <= do_count) {
1751 /* Only data from this write is not written */
1752 count += undone;
Kai Makisara626dcb12008-07-11 15:05:25 +03001753 b_point -= undone;
Linus Torvalds1da177e2005-04-16 15:20:36 -07001754 do_count -= undone;
1755 if (STp->block_size)
1756 blks = (transfer - undone) / STp->block_size;
1757 STps->eof = ST_EOM_OK;
1758 /* Continue in fixed block mode if all written
1759 in this request but still something left to write
1760 (retval left to zero)
1761 */
1762 if (STp->block_size == 0 ||
1763 undone > 0 || count == 0)
1764 retval = (-ENOSPC); /* EOM within current request */
Hannes Reineckeb30d8bc2014-06-25 16:39:57 +02001765 DEBC_printk(STp, "EOM with %d "
1766 "bytes unwritten.\n",
1767 (int)count);
Linus Torvalds1da177e2005-04-16 15:20:36 -07001768 } else {
1769 /* EOT within data buffered earlier (possible only
1770 in fixed block mode without direct i/o) */
1771 if (!retry_eot && !cmdstatp->deferred &&
1772 (scode == NO_SENSE || scode == RECOVERED_ERROR)) {
1773 move_buffer_data(STp->buffer, transfer - undone);
1774 retry_eot = 1;
1775 if (STps->drv_block >= 0) {
1776 STps->drv_block += (transfer - undone) /
1777 STp->block_size;
1778 }
1779 STps->eof = ST_EOM_OK;
Hannes Reineckeb30d8bc2014-06-25 16:39:57 +02001780 DEBC_printk(STp, "Retry "
1781 "write of %d "
1782 "bytes at EOM.\n",
1783 STp->buffer->buffer_bytes);
Linus Torvalds1da177e2005-04-16 15:20:36 -07001784 goto retry_write;
1785 }
1786 else {
1787 /* Either error within data buffered by driver or
1788 failed retry */
1789 count -= do_count;
1790 blks = do_count = 0;
1791 STps->eof = ST_EOM_ERROR;
1792 STps->drv_block = (-1); /* Too cautious? */
1793 retval = (-EIO); /* EOM for old data */
Hannes Reineckeb30d8bc2014-06-25 16:39:57 +02001794 DEBC_printk(STp, "EOM with "
1795 "lost data.\n");
Linus Torvalds1da177e2005-04-16 15:20:36 -07001796 }
1797 }
1798 } else {
1799 count += do_count;
1800 STps->drv_block = (-1); /* Too cautious? */
Mike Christie8b05b772005-11-08 04:06:44 -06001801 retval = STbp->syscall_result;
Linus Torvalds1da177e2005-04-16 15:20:36 -07001802 }
1803
1804 }
1805
1806 if (STps->drv_block >= 0) {
1807 if (STp->block_size == 0)
1808 STps->drv_block += (do_count > 0);
1809 else
1810 STps->drv_block += blks;
1811 }
1812
1813 STbp->buffer_bytes = 0;
1814 STp->dirty = 0;
1815
1816 if (retval || retry_eot) {
1817 if (count < total)
1818 retval = total - count;
1819 goto out;
1820 }
1821 }
1822
1823 if (STps->eof == ST_EOD_1)
1824 STps->eof = ST_EOM_OK;
1825 else if (STps->eof != ST_EOM_OK)
1826 STps->eof = ST_NOEOF;
1827 retval = total - count;
1828
1829 out:
1830 if (SRpnt != NULL)
Mike Christie8b05b772005-11-08 04:06:44 -06001831 st_release_request(SRpnt);
Kai Makisara787926b2005-11-13 10:04:44 +02001832 release_buffering(STp, 0);
Matthias Kaehlcke28f85002007-07-29 23:38:15 +02001833 mutex_unlock(&STp->lock);
Linus Torvalds1da177e2005-04-16 15:20:36 -07001834
1835 return retval;
1836}
1837
1838/* Read data from the tape. Returns zero in the normal case, one if the
1839 eof status has changed, and the negative error code in case of a
1840 fatal error. Otherwise updates the buffer and the eof state.
1841
1842 Does release user buffer mapping if it is set.
1843*/
1844static long read_tape(struct scsi_tape *STp, long count,
Mike Christie8b05b772005-11-08 04:06:44 -06001845 struct st_request ** aSRpnt)
Linus Torvalds1da177e2005-04-16 15:20:36 -07001846{
1847 int transfer, blks, bytes;
1848 unsigned char cmd[MAX_COMMAND_SIZE];
Mike Christie8b05b772005-11-08 04:06:44 -06001849 struct st_request *SRpnt;
Linus Torvalds1da177e2005-04-16 15:20:36 -07001850 struct st_modedef *STm;
1851 struct st_partstat *STps;
1852 struct st_buffer *STbp;
1853 int retval = 0;
Linus Torvalds1da177e2005-04-16 15:20:36 -07001854
1855 if (count == 0)
1856 return 0;
1857
1858 STm = &(STp->modes[STp->current_mode]);
1859 STps = &(STp->ps[STp->partition]);
1860 if (STps->eof == ST_FM_HIT)
1861 return 1;
1862 STbp = STp->buffer;
1863
1864 if (STp->block_size == 0)
1865 blks = bytes = count;
1866 else {
Kai Makisara9abe16c2007-02-03 13:21:29 +02001867 if (!(STp->try_dio_now && try_rdio) && STm->do_read_ahead) {
Linus Torvalds1da177e2005-04-16 15:20:36 -07001868 blks = (STp->buffer)->buffer_blocks;
1869 bytes = blks * STp->block_size;
1870 } else {
1871 bytes = count;
1872 if (!STbp->do_dio && bytes > (STp->buffer)->buffer_size)
1873 bytes = (STp->buffer)->buffer_size;
1874 blks = bytes / STp->block_size;
1875 bytes = blks * STp->block_size;
1876 }
1877 }
1878
1879 memset(cmd, 0, MAX_COMMAND_SIZE);
1880 cmd[0] = READ_6;
1881 cmd[1] = (STp->block_size != 0);
Kai Makisara40f6b362008-02-24 22:23:24 +02001882 if (!cmd[1] && STp->sili)
1883 cmd[1] |= 2;
Linus Torvalds1da177e2005-04-16 15:20:36 -07001884 cmd[2] = blks >> 16;
1885 cmd[3] = blks >> 8;
1886 cmd[4] = blks;
1887
1888 SRpnt = *aSRpnt;
1889 SRpnt = st_do_scsi(SRpnt, STp, cmd, bytes, DMA_FROM_DEVICE,
James Bottomleya02488e2008-11-30 10:36:26 -06001890 STp->device->request_queue->rq_timeout,
1891 MAX_RETRIES, 1);
Kai Makisara787926b2005-11-13 10:04:44 +02001892 release_buffering(STp, 1);
Linus Torvalds1da177e2005-04-16 15:20:36 -07001893 *aSRpnt = SRpnt;
1894 if (!SRpnt)
1895 return STbp->syscall_result;
1896
1897 STbp->read_pointer = 0;
1898 STps->at_sm = 0;
1899
1900 /* Something to check */
1901 if (STbp->syscall_result) {
1902 struct st_cmdstatus *cmdstatp = &STp->buffer->cmdstat;
1903
1904 retval = 1;
Hannes Reineckeb30d8bc2014-06-25 16:39:57 +02001905 DEBC_printk(STp,
1906 "Sense: %2x %2x %2x %2x %2x %2x %2x %2x\n",
1907 SRpnt->sense[0], SRpnt->sense[1],
1908 SRpnt->sense[2], SRpnt->sense[3],
1909 SRpnt->sense[4], SRpnt->sense[5],
1910 SRpnt->sense[6], SRpnt->sense[7]);
Linus Torvalds1da177e2005-04-16 15:20:36 -07001911 if (cmdstatp->have_sense) {
1912
1913 if (cmdstatp->sense_hdr.sense_key == BLANK_CHECK)
1914 cmdstatp->flags &= 0xcf; /* No need for EOM in this case */
1915
1916 if (cmdstatp->flags != 0) { /* EOF, EOM, or ILI */
1917 /* Compute the residual count */
1918 if (cmdstatp->remainder_valid)
1919 transfer = (int)cmdstatp->uremainder64;
1920 else
1921 transfer = 0;
1922 if (STp->block_size == 0 &&
1923 cmdstatp->sense_hdr.sense_key == MEDIUM_ERROR)
1924 transfer = bytes;
1925
1926 if (cmdstatp->flags & SENSE_ILI) { /* ILI */
Hannes Reineckeb30d8bc2014-06-25 16:39:57 +02001927 if (STp->block_size == 0 &&
1928 transfer < 0) {
1929 st_printk(KERN_NOTICE, STp,
1930 "Failed to read %d "
1931 "byte block with %d "
1932 "byte transfer.\n",
1933 bytes - transfer,
1934 bytes);
1935 if (STps->drv_block >= 0)
1936 STps->drv_block += 1;
1937 STbp->buffer_bytes = 0;
1938 return (-ENOMEM);
1939 } else if (STp->block_size == 0) {
Linus Torvalds1da177e2005-04-16 15:20:36 -07001940 STbp->buffer_bytes = bytes - transfer;
1941 } else {
Mike Christie8b05b772005-11-08 04:06:44 -06001942 st_release_request(SRpnt);
Linus Torvalds1da177e2005-04-16 15:20:36 -07001943 SRpnt = *aSRpnt = NULL;
1944 if (transfer == blks) { /* We did not get anything, error */
Hannes Reineckeb30d8bc2014-06-25 16:39:57 +02001945 st_printk(KERN_NOTICE, STp,
1946 "Incorrect "
1947 "block size.\n");
Linus Torvalds1da177e2005-04-16 15:20:36 -07001948 if (STps->drv_block >= 0)
1949 STps->drv_block += blks - transfer + 1;
1950 st_int_ioctl(STp, MTBSR, 1);
1951 return (-EIO);
1952 }
1953 /* We have some data, deliver it */
1954 STbp->buffer_bytes = (blks - transfer) *
1955 STp->block_size;
Hannes Reineckeb30d8bc2014-06-25 16:39:57 +02001956 DEBC_printk(STp, "ILI but "
1957 "enough data "
1958 "received %ld "
1959 "%d.\n", count,
1960 STbp->buffer_bytes);
Linus Torvalds1da177e2005-04-16 15:20:36 -07001961 if (STps->drv_block >= 0)
1962 STps->drv_block += 1;
1963 if (st_int_ioctl(STp, MTBSR, 1))
1964 return (-EIO);
1965 }
1966 } else if (cmdstatp->flags & SENSE_FMK) { /* FM overrides EOM */
1967 if (STps->eof != ST_FM_HIT)
1968 STps->eof = ST_FM_HIT;
1969 else
1970 STps->eof = ST_EOD_2;
1971 if (STp->block_size == 0)
1972 STbp->buffer_bytes = 0;
1973 else
1974 STbp->buffer_bytes =
1975 bytes - transfer * STp->block_size;
Hannes Reineckeb30d8bc2014-06-25 16:39:57 +02001976 DEBC_printk(STp, "EOF detected (%d "
1977 "bytes read).\n",
1978 STbp->buffer_bytes);
Linus Torvalds1da177e2005-04-16 15:20:36 -07001979 } else if (cmdstatp->flags & SENSE_EOM) {
1980 if (STps->eof == ST_FM)
1981 STps->eof = ST_EOD_1;
1982 else
1983 STps->eof = ST_EOM_OK;
1984 if (STp->block_size == 0)
1985 STbp->buffer_bytes = bytes - transfer;
1986 else
1987 STbp->buffer_bytes =
1988 bytes - transfer * STp->block_size;
1989
Hannes Reineckeb30d8bc2014-06-25 16:39:57 +02001990 DEBC_printk(STp, "EOM detected (%d "
1991 "bytes read).\n",
1992 STbp->buffer_bytes);
Linus Torvalds1da177e2005-04-16 15:20:36 -07001993 }
1994 }
Hannes Reineckeb30d8bc2014-06-25 16:39:57 +02001995 /* end of EOF, EOM, ILI test */
Linus Torvalds1da177e2005-04-16 15:20:36 -07001996 else { /* nonzero sense key */
Hannes Reineckeb30d8bc2014-06-25 16:39:57 +02001997 DEBC_printk(STp, "Tape error while reading.\n");
Linus Torvalds1da177e2005-04-16 15:20:36 -07001998 STps->drv_block = (-1);
1999 if (STps->eof == ST_FM &&
2000 cmdstatp->sense_hdr.sense_key == BLANK_CHECK) {
Hannes Reineckeb30d8bc2014-06-25 16:39:57 +02002001 DEBC_printk(STp, "Zero returned for "
2002 "first BLANK CHECK "
2003 "after EOF.\n");
Linus Torvalds1da177e2005-04-16 15:20:36 -07002004 STps->eof = ST_EOD_2; /* First BLANK_CHECK after FM */
2005 } else /* Some other extended sense code */
2006 retval = (-EIO);
2007 }
2008
2009 if (STbp->buffer_bytes < 0) /* Caused by bogus sense data */
2010 STbp->buffer_bytes = 0;
2011 }
Hannes Reineckeb30d8bc2014-06-25 16:39:57 +02002012 /* End of extended sense test */
Linus Torvalds1da177e2005-04-16 15:20:36 -07002013 else { /* Non-extended sense */
2014 retval = STbp->syscall_result;
2015 }
2016
2017 }
Hannes Reineckeb30d8bc2014-06-25 16:39:57 +02002018 /* End of error handling */
Kai Makisara40f6b362008-02-24 22:23:24 +02002019 else { /* Read successful */
Linus Torvalds1da177e2005-04-16 15:20:36 -07002020 STbp->buffer_bytes = bytes;
Kai Makisara40f6b362008-02-24 22:23:24 +02002021 if (STp->sili) /* In fixed block mode residual is always zero here */
2022 STbp->buffer_bytes -= STp->buffer->cmdstat.residual;
2023 }
Linus Torvalds1da177e2005-04-16 15:20:36 -07002024
2025 if (STps->drv_block >= 0) {
2026 if (STp->block_size == 0)
2027 STps->drv_block++;
2028 else
2029 STps->drv_block += STbp->buffer_bytes / STp->block_size;
2030 }
2031 return retval;
2032}
2033
2034
2035/* Read command */
2036static ssize_t
2037st_read(struct file *filp, char __user *buf, size_t count, loff_t * ppos)
2038{
2039 ssize_t total;
2040 ssize_t retval = 0;
2041 ssize_t i, transfer;
2042 int special, do_dio = 0;
Mike Christie8b05b772005-11-08 04:06:44 -06002043 struct st_request *SRpnt = NULL;
Linus Torvalds1da177e2005-04-16 15:20:36 -07002044 struct scsi_tape *STp = filp->private_data;
2045 struct st_modedef *STm;
2046 struct st_partstat *STps;
2047 struct st_buffer *STbp = STp->buffer;
Linus Torvalds1da177e2005-04-16 15:20:36 -07002048
Matthias Kaehlcke28f85002007-07-29 23:38:15 +02002049 if (mutex_lock_interruptible(&STp->lock))
Linus Torvalds1da177e2005-04-16 15:20:36 -07002050 return -ERESTARTSYS;
2051
2052 retval = rw_checks(STp, filp, count);
2053 if (retval || count == 0)
2054 goto out;
2055
2056 STm = &(STp->modes[STp->current_mode]);
Kai Makisara9abe16c2007-02-03 13:21:29 +02002057 if (STp->block_size != 0 && (count % STp->block_size) != 0) {
2058 if (!STm->do_read_ahead) {
2059 retval = (-EINVAL); /* Read must be integral number of blocks */
2060 goto out;
2061 }
2062 STp->try_dio_now = 0; /* Direct i/o can't handle split blocks */
Linus Torvalds1da177e2005-04-16 15:20:36 -07002063 }
2064
2065 STps = &(STp->ps[STp->partition]);
2066 if (STps->rw == ST_WRITING) {
2067 retval = flush_buffer(STp, 0);
2068 if (retval)
2069 goto out;
2070 STps->rw = ST_READING;
2071 }
Hannes Reineckeb30d8bc2014-06-25 16:39:57 +02002072 DEB(
Linus Torvalds1da177e2005-04-16 15:20:36 -07002073 if (debugging && STps->eof != ST_NOEOF)
Hannes Reineckeb30d8bc2014-06-25 16:39:57 +02002074 st_printk(ST_DEB_MSG, STp,
2075 "EOF/EOM flag up (%d). Bytes %d\n",
2076 STps->eof, STbp->buffer_bytes);
2077 ) /* end DEB */
Linus Torvalds1da177e2005-04-16 15:20:36 -07002078
2079 retval = setup_buffering(STp, buf, count, 1);
2080 if (retval)
2081 goto out;
2082 do_dio = STbp->do_dio;
2083
2084 if (STbp->buffer_bytes == 0 &&
2085 STps->eof >= ST_EOD_1) {
2086 if (STps->eof < ST_EOD) {
2087 STps->eof += 1;
2088 retval = 0;
2089 goto out;
2090 }
2091 retval = (-EIO); /* EOM or Blank Check */
2092 goto out;
2093 }
2094
2095 if (do_dio) {
2096 /* Check the buffer writability before any tape movement. Don't alter
2097 buffer data. */
2098 if (copy_from_user(&i, buf, 1) != 0 ||
2099 copy_to_user(buf, &i, 1) != 0 ||
2100 copy_from_user(&i, buf + count - 1, 1) != 0 ||
2101 copy_to_user(buf + count - 1, &i, 1) != 0) {
2102 retval = (-EFAULT);
2103 goto out;
2104 }
2105 }
2106
2107 STps->rw = ST_READING;
2108
2109
2110 /* Loop until enough data in buffer or a special condition found */
2111 for (total = 0, special = 0; total < count && !special;) {
2112
2113 /* Get new data if the buffer is empty */
2114 if (STbp->buffer_bytes == 0) {
2115 special = read_tape(STp, count - total, &SRpnt);
2116 if (special < 0) { /* No need to continue read */
2117 retval = special;
2118 goto out;
2119 }
2120 }
2121
2122 /* Move the data from driver buffer to user buffer */
2123 if (STbp->buffer_bytes > 0) {
Hannes Reineckeb30d8bc2014-06-25 16:39:57 +02002124 DEB(
Linus Torvalds1da177e2005-04-16 15:20:36 -07002125 if (debugging && STps->eof != ST_NOEOF)
Hannes Reineckeb30d8bc2014-06-25 16:39:57 +02002126 st_printk(ST_DEB_MSG, STp,
2127 "EOF up (%d). Left %d, needed %d.\n",
2128 STps->eof, STbp->buffer_bytes,
2129 (int)(count - total));
2130 ) /* end DEB */
Linus Torvalds1da177e2005-04-16 15:20:36 -07002131 transfer = STbp->buffer_bytes < count - total ?
2132 STbp->buffer_bytes : count - total;
2133 if (!do_dio) {
2134 i = from_buffer(STbp, buf, transfer);
2135 if (i) {
2136 retval = i;
2137 goto out;
2138 }
2139 }
2140 buf += transfer;
2141 total += transfer;
2142 }
2143
2144 if (STp->block_size == 0)
2145 break; /* Read only one variable length block */
2146
2147 } /* for (total = 0, special = 0;
2148 total < count && !special; ) */
2149
2150 /* Change the eof state if no data from tape or buffer */
2151 if (total == 0) {
2152 if (STps->eof == ST_FM_HIT) {
2153 STps->eof = ST_FM;
2154 STps->drv_block = 0;
2155 if (STps->drv_file >= 0)
2156 STps->drv_file++;
2157 } else if (STps->eof == ST_EOD_1) {
2158 STps->eof = ST_EOD_2;
2159 STps->drv_block = 0;
2160 if (STps->drv_file >= 0)
2161 STps->drv_file++;
2162 } else if (STps->eof == ST_EOD_2)
2163 STps->eof = ST_EOD;
2164 } else if (STps->eof == ST_FM)
2165 STps->eof = ST_NOEOF;
2166 retval = total;
2167
2168 out:
2169 if (SRpnt != NULL) {
Mike Christie8b05b772005-11-08 04:06:44 -06002170 st_release_request(SRpnt);
Linus Torvalds1da177e2005-04-16 15:20:36 -07002171 SRpnt = NULL;
2172 }
2173 if (do_dio) {
Kai Makisara787926b2005-11-13 10:04:44 +02002174 release_buffering(STp, 1);
Linus Torvalds1da177e2005-04-16 15:20:36 -07002175 STbp->buffer_bytes = 0;
2176 }
Matthias Kaehlcke28f85002007-07-29 23:38:15 +02002177 mutex_unlock(&STp->lock);
Linus Torvalds1da177e2005-04-16 15:20:36 -07002178
2179 return retval;
2180}
2181
2182
2183
2184DEB(
2185/* Set the driver options */
Hannes Reineckeb30d8bc2014-06-25 16:39:57 +02002186static void st_log_options(struct scsi_tape * STp, struct st_modedef * STm)
Linus Torvalds1da177e2005-04-16 15:20:36 -07002187{
2188 if (debugging) {
Hannes Reineckeb30d8bc2014-06-25 16:39:57 +02002189 st_printk(KERN_INFO, STp,
2190 "Mode %d options: buffer writes: %d, "
2191 "async writes: %d, read ahead: %d\n",
2192 STp->current_mode, STm->do_buffer_writes,
2193 STm->do_async_writes, STm->do_read_ahead);
2194 st_printk(KERN_INFO, STp,
2195 " can bsr: %d, two FMs: %d, "
2196 "fast mteom: %d, auto lock: %d,\n",
2197 STp->can_bsr, STp->two_fm, STp->fast_mteom,
2198 STp->do_auto_lock);
2199 st_printk(KERN_INFO, STp,
2200 " defs for wr: %d, no block limits: %d, "
2201 "partitions: %d, s2 log: %d\n",
2202 STm->defaults_for_writes, STp->omit_blklims,
2203 STp->can_partitions, STp->scsi2_logical);
2204 st_printk(KERN_INFO, STp,
2205 " sysv: %d nowait: %d sili: %d "
2206 "nowait_filemark: %d\n",
2207 STm->sysv, STp->immediate, STp->sili,
2208 STp->immediate_filemark);
2209 st_printk(KERN_INFO, STp, " debugging: %d\n", debugging);
Linus Torvalds1da177e2005-04-16 15:20:36 -07002210 }
2211}
2212 )
2213
2214
2215static int st_set_options(struct scsi_tape *STp, long options)
2216{
2217 int value;
2218 long code;
2219 struct st_modedef *STm;
Linus Torvalds1da177e2005-04-16 15:20:36 -07002220 struct cdev *cd0, *cd1;
Maurizio Lombardid6216c42014-02-11 22:22:47 +01002221 struct device *d0, *d1;
Linus Torvalds1da177e2005-04-16 15:20:36 -07002222
2223 STm = &(STp->modes[STp->current_mode]);
2224 if (!STm->defined) {
Maurizio Lombardid6216c42014-02-11 22:22:47 +01002225 cd0 = STm->cdevs[0];
2226 cd1 = STm->cdevs[1];
2227 d0 = STm->devs[0];
2228 d1 = STm->devs[1];
Linus Torvalds1da177e2005-04-16 15:20:36 -07002229 memcpy(STm, &(STp->modes[0]), sizeof(struct st_modedef));
Maurizio Lombardid6216c42014-02-11 22:22:47 +01002230 STm->cdevs[0] = cd0;
2231 STm->cdevs[1] = cd1;
2232 STm->devs[0] = d0;
2233 STm->devs[1] = d1;
Linus Torvalds1da177e2005-04-16 15:20:36 -07002234 modes_defined = 1;
Hannes Reineckeb30d8bc2014-06-25 16:39:57 +02002235 DEBC_printk(STp, "Initialized mode %d definition from mode 0\n",
2236 STp->current_mode);
Linus Torvalds1da177e2005-04-16 15:20:36 -07002237 }
2238
2239 code = options & MT_ST_OPTIONS;
2240 if (code == MT_ST_BOOLEANS) {
2241 STm->do_buffer_writes = (options & MT_ST_BUFFER_WRITES) != 0;
2242 STm->do_async_writes = (options & MT_ST_ASYNC_WRITES) != 0;
2243 STm->defaults_for_writes = (options & MT_ST_DEF_WRITES) != 0;
2244 STm->do_read_ahead = (options & MT_ST_READ_AHEAD) != 0;
2245 STp->two_fm = (options & MT_ST_TWO_FM) != 0;
2246 STp->fast_mteom = (options & MT_ST_FAST_MTEOM) != 0;
2247 STp->do_auto_lock = (options & MT_ST_AUTO_LOCK) != 0;
2248 STp->can_bsr = (options & MT_ST_CAN_BSR) != 0;
2249 STp->omit_blklims = (options & MT_ST_NO_BLKLIMS) != 0;
2250 if ((STp->device)->scsi_level >= SCSI_2)
2251 STp->can_partitions = (options & MT_ST_CAN_PARTITIONS) != 0;
2252 STp->scsi2_logical = (options & MT_ST_SCSI2LOGICAL) != 0;
2253 STp->immediate = (options & MT_ST_NOWAIT) != 0;
Lee Duncanc743e442012-03-01 12:41:01 -08002254 STp->immediate_filemark = (options & MT_ST_NOWAIT_EOF) != 0;
Linus Torvalds1da177e2005-04-16 15:20:36 -07002255 STm->sysv = (options & MT_ST_SYSV) != 0;
Kai Makisara40f6b362008-02-24 22:23:24 +02002256 STp->sili = (options & MT_ST_SILI) != 0;
Linus Torvalds1da177e2005-04-16 15:20:36 -07002257 DEB( debugging = (options & MT_ST_DEBUGGING) != 0;
Hannes Reineckeb30d8bc2014-06-25 16:39:57 +02002258 st_log_options(STp, STm); )
Linus Torvalds1da177e2005-04-16 15:20:36 -07002259 } else if (code == MT_ST_SETBOOLEANS || code == MT_ST_CLEARBOOLEANS) {
2260 value = (code == MT_ST_SETBOOLEANS);
2261 if ((options & MT_ST_BUFFER_WRITES) != 0)
2262 STm->do_buffer_writes = value;
2263 if ((options & MT_ST_ASYNC_WRITES) != 0)
2264 STm->do_async_writes = value;
2265 if ((options & MT_ST_DEF_WRITES) != 0)
2266 STm->defaults_for_writes = value;
2267 if ((options & MT_ST_READ_AHEAD) != 0)
2268 STm->do_read_ahead = value;
2269 if ((options & MT_ST_TWO_FM) != 0)
2270 STp->two_fm = value;
2271 if ((options & MT_ST_FAST_MTEOM) != 0)
2272 STp->fast_mteom = value;
2273 if ((options & MT_ST_AUTO_LOCK) != 0)
2274 STp->do_auto_lock = value;
2275 if ((options & MT_ST_CAN_BSR) != 0)
2276 STp->can_bsr = value;
2277 if ((options & MT_ST_NO_BLKLIMS) != 0)
2278 STp->omit_blklims = value;
2279 if ((STp->device)->scsi_level >= SCSI_2 &&
2280 (options & MT_ST_CAN_PARTITIONS) != 0)
2281 STp->can_partitions = value;
2282 if ((options & MT_ST_SCSI2LOGICAL) != 0)
2283 STp->scsi2_logical = value;
2284 if ((options & MT_ST_NOWAIT) != 0)
2285 STp->immediate = value;
Lee Duncanc743e442012-03-01 12:41:01 -08002286 if ((options & MT_ST_NOWAIT_EOF) != 0)
2287 STp->immediate_filemark = value;
Linus Torvalds1da177e2005-04-16 15:20:36 -07002288 if ((options & MT_ST_SYSV) != 0)
2289 STm->sysv = value;
Kai Makisara40f6b362008-02-24 22:23:24 +02002290 if ((options & MT_ST_SILI) != 0)
2291 STp->sili = value;
Hannes Reineckeb30d8bc2014-06-25 16:39:57 +02002292 DEB(
Linus Torvalds1da177e2005-04-16 15:20:36 -07002293 if ((options & MT_ST_DEBUGGING) != 0)
2294 debugging = value;
Hannes Reineckeb30d8bc2014-06-25 16:39:57 +02002295 st_log_options(STp, STm); )
Linus Torvalds1da177e2005-04-16 15:20:36 -07002296 } else if (code == MT_ST_WRITE_THRESHOLD) {
2297 /* Retained for compatibility */
2298 } else if (code == MT_ST_DEF_BLKSIZE) {
2299 value = (options & ~MT_ST_OPTIONS);
2300 if (value == ~MT_ST_OPTIONS) {
2301 STm->default_blksize = (-1);
Hannes Reineckeb30d8bc2014-06-25 16:39:57 +02002302 DEBC_printk(STp, "Default block size disabled.\n");
Linus Torvalds1da177e2005-04-16 15:20:36 -07002303 } else {
2304 STm->default_blksize = value;
Hannes Reineckeb30d8bc2014-06-25 16:39:57 +02002305 DEBC_printk(STp,"Default block size set to "
2306 "%d bytes.\n", STm->default_blksize);
Linus Torvalds1da177e2005-04-16 15:20:36 -07002307 if (STp->ready == ST_READY) {
2308 STp->blksize_changed = 0;
2309 set_mode_densblk(STp, STm);
2310 }
2311 }
2312 } else if (code == MT_ST_TIMEOUTS) {
2313 value = (options & ~MT_ST_OPTIONS);
2314 if ((value & MT_ST_SET_LONG_TIMEOUT) != 0) {
2315 STp->long_timeout = (value & ~MT_ST_SET_LONG_TIMEOUT) * HZ;
Hannes Reineckeb30d8bc2014-06-25 16:39:57 +02002316 DEBC_printk(STp, "Long timeout set to %d seconds.\n",
2317 (value & ~MT_ST_SET_LONG_TIMEOUT));
Linus Torvalds1da177e2005-04-16 15:20:36 -07002318 } else {
James Bottomleya02488e2008-11-30 10:36:26 -06002319 blk_queue_rq_timeout(STp->device->request_queue,
2320 value * HZ);
Hannes Reineckeb30d8bc2014-06-25 16:39:57 +02002321 DEBC_printk(STp, "Normal timeout set to %d seconds.\n",
2322 value);
Linus Torvalds1da177e2005-04-16 15:20:36 -07002323 }
2324 } else if (code == MT_ST_SET_CLN) {
2325 value = (options & ~MT_ST_OPTIONS) & 0xff;
2326 if (value != 0 &&
Roel Kluin832151f2009-11-17 14:53:22 -08002327 (value < EXTENDED_SENSE_START ||
2328 value >= SCSI_SENSE_BUFFERSIZE))
Linus Torvalds1da177e2005-04-16 15:20:36 -07002329 return (-EINVAL);
2330 STp->cln_mode = value;
2331 STp->cln_sense_mask = (options >> 8) & 0xff;
2332 STp->cln_sense_value = (options >> 16) & 0xff;
Hannes Reineckeb30d8bc2014-06-25 16:39:57 +02002333 st_printk(KERN_INFO, STp,
2334 "Cleaning request mode %d, mask %02x, value %02x\n",
2335 value, STp->cln_sense_mask, STp->cln_sense_value);
Linus Torvalds1da177e2005-04-16 15:20:36 -07002336 } else if (code == MT_ST_DEF_OPTIONS) {
2337 code = (options & ~MT_ST_CLEAR_DEFAULT);
2338 value = (options & MT_ST_CLEAR_DEFAULT);
2339 if (code == MT_ST_DEF_DENSITY) {
2340 if (value == MT_ST_CLEAR_DEFAULT) {
2341 STm->default_density = (-1);
Hannes Reineckeb30d8bc2014-06-25 16:39:57 +02002342 DEBC_printk(STp,
2343 "Density default disabled.\n");
Linus Torvalds1da177e2005-04-16 15:20:36 -07002344 } else {
2345 STm->default_density = value & 0xff;
Hannes Reineckeb30d8bc2014-06-25 16:39:57 +02002346 DEBC_printk(STp, "Density default set to %x\n",
2347 STm->default_density);
Linus Torvalds1da177e2005-04-16 15:20:36 -07002348 if (STp->ready == ST_READY) {
2349 STp->density_changed = 0;
2350 set_mode_densblk(STp, STm);
2351 }
2352 }
2353 } else if (code == MT_ST_DEF_DRVBUFFER) {
2354 if (value == MT_ST_CLEAR_DEFAULT) {
2355 STp->default_drvbuffer = 0xff;
Hannes Reineckeb30d8bc2014-06-25 16:39:57 +02002356 DEBC_printk(STp,
2357 "Drive buffer default disabled.\n");
Linus Torvalds1da177e2005-04-16 15:20:36 -07002358 } else {
2359 STp->default_drvbuffer = value & 7;
Hannes Reineckeb30d8bc2014-06-25 16:39:57 +02002360 DEBC_printk(STp,
2361 "Drive buffer default set to %x\n",
2362 STp->default_drvbuffer);
Linus Torvalds1da177e2005-04-16 15:20:36 -07002363 if (STp->ready == ST_READY)
2364 st_int_ioctl(STp, MTSETDRVBUFFER, STp->default_drvbuffer);
2365 }
2366 } else if (code == MT_ST_DEF_COMPRESSION) {
2367 if (value == MT_ST_CLEAR_DEFAULT) {
2368 STm->default_compression = ST_DONT_TOUCH;
Hannes Reineckeb30d8bc2014-06-25 16:39:57 +02002369 DEBC_printk(STp,
2370 "Compression default disabled.\n");
Linus Torvalds1da177e2005-04-16 15:20:36 -07002371 } else {
2372 if ((value & 0xff00) != 0) {
2373 STp->c_algo = (value & 0xff00) >> 8;
Hannes Reineckeb30d8bc2014-06-25 16:39:57 +02002374 DEBC_printk(STp, "Compression "
2375 "algorithm set to 0x%x.\n",
2376 STp->c_algo);
Linus Torvalds1da177e2005-04-16 15:20:36 -07002377 }
2378 if ((value & 0xff) != 0xff) {
2379 STm->default_compression = (value & 1 ? ST_YES : ST_NO);
Hannes Reineckeb30d8bc2014-06-25 16:39:57 +02002380 DEBC_printk(STp, "Compression default "
2381 "set to %x\n",
2382 (value & 1));
Linus Torvalds1da177e2005-04-16 15:20:36 -07002383 if (STp->ready == ST_READY) {
2384 STp->compression_changed = 0;
2385 st_compression(STp, (STm->default_compression == ST_YES));
2386 }
2387 }
2388 }
2389 }
2390 } else
2391 return (-EIO);
2392
2393 return 0;
2394}
2395
2396#define MODE_HEADER_LENGTH 4
2397
2398/* Mode header and page byte offsets */
2399#define MH_OFF_DATA_LENGTH 0
2400#define MH_OFF_MEDIUM_TYPE 1
2401#define MH_OFF_DEV_SPECIFIC 2
2402#define MH_OFF_BDESCS_LENGTH 3
2403#define MP_OFF_PAGE_NBR 0
2404#define MP_OFF_PAGE_LENGTH 1
2405
2406/* Mode header and page bit masks */
2407#define MH_BIT_WP 0x80
2408#define MP_MSK_PAGE_NBR 0x3f
2409
2410/* Don't return block descriptors */
2411#define MODE_SENSE_OMIT_BDESCS 0x08
2412
2413#define MODE_SELECT_PAGE_FORMAT 0x10
2414
2415/* Read a mode page into the tape buffer. The block descriptors are included
2416 if incl_block_descs is true. The page control is ored to the page number
2417 parameter, if necessary. */
2418static int read_mode_page(struct scsi_tape *STp, int page, int omit_block_descs)
2419{
2420 unsigned char cmd[MAX_COMMAND_SIZE];
FUJITA Tomonori8ecf0d92008-12-05 15:25:28 +09002421 struct st_request *SRpnt;
Linus Torvalds1da177e2005-04-16 15:20:36 -07002422
2423 memset(cmd, 0, MAX_COMMAND_SIZE);
2424 cmd[0] = MODE_SENSE;
2425 if (omit_block_descs)
2426 cmd[1] = MODE_SENSE_OMIT_BDESCS;
2427 cmd[2] = page;
2428 cmd[4] = 255;
2429
Kai Makisara02ae2c02008-12-18 14:49:50 +09002430 SRpnt = st_do_scsi(NULL, STp, cmd, cmd[4], DMA_FROM_DEVICE,
2431 STp->device->request_queue->rq_timeout, 0, 1);
2432 if (SRpnt == NULL)
2433 return (STp->buffer)->syscall_result;
Linus Torvalds1da177e2005-04-16 15:20:36 -07002434
Mike Christie8b05b772005-11-08 04:06:44 -06002435 st_release_request(SRpnt);
Linus Torvalds1da177e2005-04-16 15:20:36 -07002436
Kai Makisara02ae2c02008-12-18 14:49:50 +09002437 return STp->buffer->syscall_result;
Linus Torvalds1da177e2005-04-16 15:20:36 -07002438}
2439
2440
2441/* Send the mode page in the tape buffer to the drive. Assumes that the mode data
2442 in the buffer is correctly formatted. The long timeout is used if slow is non-zero. */
2443static int write_mode_page(struct scsi_tape *STp, int page, int slow)
2444{
Kai Makisara02ae2c02008-12-18 14:49:50 +09002445 int pgo;
Linus Torvalds1da177e2005-04-16 15:20:36 -07002446 unsigned char cmd[MAX_COMMAND_SIZE];
FUJITA Tomonori18c87012008-12-05 15:25:29 +09002447 struct st_request *SRpnt;
Kai Makisara02ae2c02008-12-18 14:49:50 +09002448 int timeout;
Linus Torvalds1da177e2005-04-16 15:20:36 -07002449
2450 memset(cmd, 0, MAX_COMMAND_SIZE);
2451 cmd[0] = MODE_SELECT;
2452 cmd[1] = MODE_SELECT_PAGE_FORMAT;
2453 pgo = MODE_HEADER_LENGTH + (STp->buffer)->b_data[MH_OFF_BDESCS_LENGTH];
2454 cmd[4] = pgo + (STp->buffer)->b_data[pgo + MP_OFF_PAGE_LENGTH] + 2;
2455
2456 /* Clear reserved fields */
2457 (STp->buffer)->b_data[MH_OFF_DATA_LENGTH] = 0;
2458 (STp->buffer)->b_data[MH_OFF_MEDIUM_TYPE] = 0;
2459 (STp->buffer)->b_data[MH_OFF_DEV_SPECIFIC] &= ~MH_BIT_WP;
2460 (STp->buffer)->b_data[pgo + MP_OFF_PAGE_NBR] &= MP_MSK_PAGE_NBR;
2461
Kai Makisara02ae2c02008-12-18 14:49:50 +09002462 timeout = slow ?
2463 STp->long_timeout : STp->device->request_queue->rq_timeout;
2464 SRpnt = st_do_scsi(NULL, STp, cmd, cmd[4], DMA_TO_DEVICE,
2465 timeout, 0, 1);
2466 if (SRpnt == NULL)
2467 return (STp->buffer)->syscall_result;
Linus Torvalds1da177e2005-04-16 15:20:36 -07002468
Mike Christie8b05b772005-11-08 04:06:44 -06002469 st_release_request(SRpnt);
Linus Torvalds1da177e2005-04-16 15:20:36 -07002470
Kai Makisara02ae2c02008-12-18 14:49:50 +09002471 return STp->buffer->syscall_result;
Linus Torvalds1da177e2005-04-16 15:20:36 -07002472}
2473
2474
2475#define COMPRESSION_PAGE 0x0f
2476#define COMPRESSION_PAGE_LENGTH 16
2477
2478#define CP_OFF_DCE_DCC 2
2479#define CP_OFF_C_ALGO 7
2480
2481#define DCE_MASK 0x80
2482#define DCC_MASK 0x40
2483#define RED_MASK 0x60
2484
2485
2486/* Control the compression with mode page 15. Algorithm not changed if zero.
2487
2488 The block descriptors are read and written because Sony SDT-7000 does not
2489 work without this (suggestion from Michael Schaefer <Michael.Schaefer@dlr.de>).
2490 Including block descriptors should not cause any harm to other drives. */
2491
2492static int st_compression(struct scsi_tape * STp, int state)
2493{
2494 int retval;
2495 int mpoffs; /* Offset to mode page start */
2496 unsigned char *b_data = (STp->buffer)->b_data;
Linus Torvalds1da177e2005-04-16 15:20:36 -07002497
2498 if (STp->ready != ST_READY)
2499 return (-EIO);
2500
2501 /* Read the current page contents */
2502 retval = read_mode_page(STp, COMPRESSION_PAGE, 0);
2503 if (retval) {
Hannes Reineckeb30d8bc2014-06-25 16:39:57 +02002504 DEBC_printk(STp, "Compression mode page not supported.\n");
Linus Torvalds1da177e2005-04-16 15:20:36 -07002505 return (-EIO);
2506 }
2507
2508 mpoffs = MODE_HEADER_LENGTH + b_data[MH_OFF_BDESCS_LENGTH];
Hannes Reineckeb30d8bc2014-06-25 16:39:57 +02002509 DEBC_printk(STp, "Compression state is %d.\n",
2510 (b_data[mpoffs + CP_OFF_DCE_DCC] & DCE_MASK ? 1 : 0));
Linus Torvalds1da177e2005-04-16 15:20:36 -07002511
2512 /* Check if compression can be changed */
2513 if ((b_data[mpoffs + CP_OFF_DCE_DCC] & DCC_MASK) == 0) {
Hannes Reineckeb30d8bc2014-06-25 16:39:57 +02002514 DEBC_printk(STp, "Compression not supported.\n");
Linus Torvalds1da177e2005-04-16 15:20:36 -07002515 return (-EIO);
2516 }
2517
2518 /* Do the change */
2519 if (state) {
2520 b_data[mpoffs + CP_OFF_DCE_DCC] |= DCE_MASK;
2521 if (STp->c_algo != 0)
2522 b_data[mpoffs + CP_OFF_C_ALGO] = STp->c_algo;
2523 }
2524 else {
2525 b_data[mpoffs + CP_OFF_DCE_DCC] &= ~DCE_MASK;
2526 if (STp->c_algo != 0)
2527 b_data[mpoffs + CP_OFF_C_ALGO] = 0; /* no compression */
2528 }
2529
2530 retval = write_mode_page(STp, COMPRESSION_PAGE, 0);
2531 if (retval) {
Hannes Reineckeb30d8bc2014-06-25 16:39:57 +02002532 DEBC_printk(STp, "Compression change failed.\n");
Linus Torvalds1da177e2005-04-16 15:20:36 -07002533 return (-EIO);
2534 }
Hannes Reineckeb30d8bc2014-06-25 16:39:57 +02002535 DEBC_printk(STp, "Compression state changed to %d.\n", state);
Linus Torvalds1da177e2005-04-16 15:20:36 -07002536
2537 STp->compression_changed = 1;
2538 return 0;
2539}
2540
2541
2542/* Process the load and unload commands (does unload if the load code is zero) */
2543static int do_load_unload(struct scsi_tape *STp, struct file *filp, int load_code)
2544{
2545 int retval = (-EIO), timeout;
Linus Torvalds1da177e2005-04-16 15:20:36 -07002546 unsigned char cmd[MAX_COMMAND_SIZE];
2547 struct st_partstat *STps;
Mike Christie8b05b772005-11-08 04:06:44 -06002548 struct st_request *SRpnt;
Linus Torvalds1da177e2005-04-16 15:20:36 -07002549
2550 if (STp->ready != ST_READY && !load_code) {
2551 if (STp->ready == ST_NO_TAPE)
2552 return (-ENOMEDIUM);
2553 else
2554 return (-EIO);
2555 }
2556
2557 memset(cmd, 0, MAX_COMMAND_SIZE);
2558 cmd[0] = START_STOP;
2559 if (load_code)
2560 cmd[4] |= 1;
2561 /*
2562 * If arg >= 1 && arg <= 6 Enhanced load/unload in HP C1553A
2563 */
2564 if (load_code >= 1 + MT_ST_HPLOADER_OFFSET
2565 && load_code <= 6 + MT_ST_HPLOADER_OFFSET) {
Hannes Reineckeb30d8bc2014-06-25 16:39:57 +02002566 DEBC_printk(STp, " Enhanced %sload slot %2d.\n",
2567 (cmd[4]) ? "" : "un",
2568 load_code - MT_ST_HPLOADER_OFFSET);
Linus Torvalds1da177e2005-04-16 15:20:36 -07002569 cmd[3] = load_code - MT_ST_HPLOADER_OFFSET; /* MediaID field of C1553A */
2570 }
2571 if (STp->immediate) {
2572 cmd[1] = 1; /* Don't wait for completion */
James Bottomleya02488e2008-11-30 10:36:26 -06002573 timeout = STp->device->request_queue->rq_timeout;
Linus Torvalds1da177e2005-04-16 15:20:36 -07002574 }
2575 else
2576 timeout = STp->long_timeout;
2577
2578 DEBC(
2579 if (!load_code)
Hannes Reineckeb30d8bc2014-06-25 16:39:57 +02002580 st_printk(ST_DEB_MSG, STp, "Unloading tape.\n");
Linus Torvalds1da177e2005-04-16 15:20:36 -07002581 else
Hannes Reineckeb30d8bc2014-06-25 16:39:57 +02002582 st_printk(ST_DEB_MSG, STp, "Loading tape.\n");
Linus Torvalds1da177e2005-04-16 15:20:36 -07002583 );
2584
Kai Makisara02ae2c02008-12-18 14:49:50 +09002585 SRpnt = st_do_scsi(NULL, STp, cmd, 0, DMA_NONE,
2586 timeout, MAX_RETRIES, 1);
Linus Torvalds1da177e2005-04-16 15:20:36 -07002587 if (!SRpnt)
Kai Makisara02ae2c02008-12-18 14:49:50 +09002588 return (STp->buffer)->syscall_result;
Linus Torvalds1da177e2005-04-16 15:20:36 -07002589
2590 retval = (STp->buffer)->syscall_result;
Kai Makisara02ae2c02008-12-18 14:49:50 +09002591 st_release_request(SRpnt);
Linus Torvalds1da177e2005-04-16 15:20:36 -07002592
2593 if (!retval) { /* SCSI command successful */
2594
2595 if (!load_code) {
2596 STp->rew_at_close = 0;
2597 STp->ready = ST_NO_TAPE;
2598 }
2599 else {
2600 STp->rew_at_close = STp->autorew_dev;
2601 retval = check_tape(STp, filp);
2602 if (retval > 0)
2603 retval = 0;
2604 }
2605 }
2606 else {
2607 STps = &(STp->ps[STp->partition]);
2608 STps->drv_file = STps->drv_block = (-1);
2609 }
2610
2611 return retval;
2612}
2613
2614#if DEBUG
2615#define ST_DEB_FORWARD 0
2616#define ST_DEB_BACKWARD 1
Hannes Reineckeb30d8bc2014-06-25 16:39:57 +02002617static void deb_space_print(struct scsi_tape *STp, int direction, char *units, unsigned char *cmd)
Linus Torvalds1da177e2005-04-16 15:20:36 -07002618{
2619 s32 sc;
2620
Hannes Reineckeb30d8bc2014-06-25 16:39:57 +02002621 if (!debugging)
2622 return;
2623
Linus Torvalds1da177e2005-04-16 15:20:36 -07002624 sc = cmd[2] & 0x80 ? 0xff000000 : 0;
2625 sc |= (cmd[2] << 16) | (cmd[3] << 8) | cmd[4];
2626 if (direction)
2627 sc = -sc;
Hannes Reineckeb30d8bc2014-06-25 16:39:57 +02002628 st_printk(ST_DEB_MSG, STp, "Spacing tape %s over %d %s.\n",
2629 direction ? "backward" : "forward", sc, units);
Linus Torvalds1da177e2005-04-16 15:20:36 -07002630}
Hannes Reineckeb30d8bc2014-06-25 16:39:57 +02002631#else
2632#define ST_DEB_FORWARD 0
2633#define ST_DEB_BACKWARD 1
2634static void deb_space_print(struct scsi_tape *STp, int direction, char *units, unsigned char *cmd) {}
Linus Torvalds1da177e2005-04-16 15:20:36 -07002635#endif
2636
2637
2638/* Internal ioctl function */
2639static int st_int_ioctl(struct scsi_tape *STp, unsigned int cmd_in, unsigned long arg)
2640{
2641 int timeout;
2642 long ltmp;
2643 int ioctl_result;
2644 int chg_eof = 1;
2645 unsigned char cmd[MAX_COMMAND_SIZE];
Mike Christie8b05b772005-11-08 04:06:44 -06002646 struct st_request *SRpnt;
Linus Torvalds1da177e2005-04-16 15:20:36 -07002647 struct st_partstat *STps;
2648 int fileno, blkno, at_sm, undone;
2649 int datalen = 0, direction = DMA_NONE;
Linus Torvalds1da177e2005-04-16 15:20:36 -07002650
2651 WARN_ON(STp->buffer->do_dio != 0);
2652 if (STp->ready != ST_READY) {
2653 if (STp->ready == ST_NO_TAPE)
2654 return (-ENOMEDIUM);
2655 else
2656 return (-EIO);
2657 }
2658 timeout = STp->long_timeout;
2659 STps = &(STp->ps[STp->partition]);
2660 fileno = STps->drv_file;
2661 blkno = STps->drv_block;
2662 at_sm = STps->at_sm;
2663
2664 memset(cmd, 0, MAX_COMMAND_SIZE);
2665 switch (cmd_in) {
2666 case MTFSFM:
2667 chg_eof = 0; /* Changed from the FSF after this */
2668 case MTFSF:
2669 cmd[0] = SPACE;
2670 cmd[1] = 0x01; /* Space FileMarks */
2671 cmd[2] = (arg >> 16);
2672 cmd[3] = (arg >> 8);
2673 cmd[4] = arg;
Hannes Reineckeb30d8bc2014-06-25 16:39:57 +02002674 deb_space_print(STp, ST_DEB_FORWARD, "filemarks", cmd);
Linus Torvalds1da177e2005-04-16 15:20:36 -07002675 if (fileno >= 0)
2676 fileno += arg;
2677 blkno = 0;
2678 at_sm &= (arg == 0);
2679 break;
2680 case MTBSFM:
2681 chg_eof = 0; /* Changed from the FSF after this */
2682 case MTBSF:
2683 cmd[0] = SPACE;
2684 cmd[1] = 0x01; /* Space FileMarks */
2685 ltmp = (-arg);
2686 cmd[2] = (ltmp >> 16);
2687 cmd[3] = (ltmp >> 8);
2688 cmd[4] = ltmp;
Hannes Reineckeb30d8bc2014-06-25 16:39:57 +02002689 deb_space_print(STp, ST_DEB_BACKWARD, "filemarks", cmd);
Linus Torvalds1da177e2005-04-16 15:20:36 -07002690 if (fileno >= 0)
2691 fileno -= arg;
2692 blkno = (-1); /* We can't know the block number */
2693 at_sm &= (arg == 0);
2694 break;
2695 case MTFSR:
2696 cmd[0] = SPACE;
2697 cmd[1] = 0x00; /* Space Blocks */
2698 cmd[2] = (arg >> 16);
2699 cmd[3] = (arg >> 8);
2700 cmd[4] = arg;
Hannes Reineckeb30d8bc2014-06-25 16:39:57 +02002701 deb_space_print(STp, ST_DEB_FORWARD, "blocks", cmd);
Linus Torvalds1da177e2005-04-16 15:20:36 -07002702 if (blkno >= 0)
2703 blkno += arg;
2704 at_sm &= (arg == 0);
2705 break;
2706 case MTBSR:
2707 cmd[0] = SPACE;
2708 cmd[1] = 0x00; /* Space Blocks */
2709 ltmp = (-arg);
2710 cmd[2] = (ltmp >> 16);
2711 cmd[3] = (ltmp >> 8);
2712 cmd[4] = ltmp;
Hannes Reineckeb30d8bc2014-06-25 16:39:57 +02002713 deb_space_print(STp, ST_DEB_BACKWARD, "blocks", cmd);
Linus Torvalds1da177e2005-04-16 15:20:36 -07002714 if (blkno >= 0)
2715 blkno -= arg;
2716 at_sm &= (arg == 0);
2717 break;
2718 case MTFSS:
2719 cmd[0] = SPACE;
2720 cmd[1] = 0x04; /* Space Setmarks */
2721 cmd[2] = (arg >> 16);
2722 cmd[3] = (arg >> 8);
2723 cmd[4] = arg;
Hannes Reineckeb30d8bc2014-06-25 16:39:57 +02002724 deb_space_print(STp, ST_DEB_FORWARD, "setmarks", cmd);
Linus Torvalds1da177e2005-04-16 15:20:36 -07002725 if (arg != 0) {
2726 blkno = fileno = (-1);
2727 at_sm = 1;
2728 }
2729 break;
2730 case MTBSS:
2731 cmd[0] = SPACE;
2732 cmd[1] = 0x04; /* Space Setmarks */
2733 ltmp = (-arg);
2734 cmd[2] = (ltmp >> 16);
2735 cmd[3] = (ltmp >> 8);
2736 cmd[4] = ltmp;
Hannes Reineckeb30d8bc2014-06-25 16:39:57 +02002737 deb_space_print(STp, ST_DEB_BACKWARD, "setmarks", cmd);
Linus Torvalds1da177e2005-04-16 15:20:36 -07002738 if (arg != 0) {
2739 blkno = fileno = (-1);
2740 at_sm = 1;
2741 }
2742 break;
2743 case MTWEOF:
Kai Makisara3e51d3c2010-10-09 00:17:56 +03002744 case MTWEOFI:
Linus Torvalds1da177e2005-04-16 15:20:36 -07002745 case MTWSM:
2746 if (STp->write_prot)
2747 return (-EACCES);
2748 cmd[0] = WRITE_FILEMARKS;
2749 if (cmd_in == MTWSM)
2750 cmd[1] = 2;
Lee Duncanc743e442012-03-01 12:41:01 -08002751 if (cmd_in == MTWEOFI ||
2752 (cmd_in == MTWEOF && STp->immediate_filemark))
Kai Makisara3e51d3c2010-10-09 00:17:56 +03002753 cmd[1] |= 1;
Linus Torvalds1da177e2005-04-16 15:20:36 -07002754 cmd[2] = (arg >> 16);
2755 cmd[3] = (arg >> 8);
2756 cmd[4] = arg;
James Bottomleya02488e2008-11-30 10:36:26 -06002757 timeout = STp->device->request_queue->rq_timeout;
Hannes Reineckeb30d8bc2014-06-25 16:39:57 +02002758 DEBC(
2759 if (cmd_in != MTWSM)
2760 st_printk(ST_DEB_MSG, STp,
2761 "Writing %d filemarks.\n",
2762 cmd[2] * 65536 +
2763 cmd[3] * 256 +
2764 cmd[4]);
2765 else
2766 st_printk(ST_DEB_MSG, STp,
2767 "Writing %d setmarks.\n",
2768 cmd[2] * 65536 +
2769 cmd[3] * 256 +
2770 cmd[4]);
Linus Torvalds1da177e2005-04-16 15:20:36 -07002771 )
2772 if (fileno >= 0)
2773 fileno += arg;
2774 blkno = 0;
2775 at_sm = (cmd_in == MTWSM);
2776 break;
2777 case MTREW:
2778 cmd[0] = REZERO_UNIT;
2779 if (STp->immediate) {
2780 cmd[1] = 1; /* Don't wait for completion */
James Bottomleya02488e2008-11-30 10:36:26 -06002781 timeout = STp->device->request_queue->rq_timeout;
Linus Torvalds1da177e2005-04-16 15:20:36 -07002782 }
Hannes Reineckeb30d8bc2014-06-25 16:39:57 +02002783 DEBC_printk(STp, "Rewinding tape.\n");
Linus Torvalds1da177e2005-04-16 15:20:36 -07002784 fileno = blkno = at_sm = 0;
2785 break;
2786 case MTNOP:
Hannes Reineckeb30d8bc2014-06-25 16:39:57 +02002787 DEBC_printk(STp, "No op on tape.\n");
Linus Torvalds1da177e2005-04-16 15:20:36 -07002788 return 0; /* Should do something ? */
2789 break;
2790 case MTRETEN:
2791 cmd[0] = START_STOP;
2792 if (STp->immediate) {
2793 cmd[1] = 1; /* Don't wait for completion */
James Bottomleya02488e2008-11-30 10:36:26 -06002794 timeout = STp->device->request_queue->rq_timeout;
Linus Torvalds1da177e2005-04-16 15:20:36 -07002795 }
2796 cmd[4] = 3;
Hannes Reineckeb30d8bc2014-06-25 16:39:57 +02002797 DEBC_printk(STp, "Retensioning tape.\n");
Linus Torvalds1da177e2005-04-16 15:20:36 -07002798 fileno = blkno = at_sm = 0;
2799 break;
2800 case MTEOM:
2801 if (!STp->fast_mteom) {
2802 /* space to the end of tape */
2803 ioctl_result = st_int_ioctl(STp, MTFSF, 0x7fffff);
2804 fileno = STps->drv_file;
2805 if (STps->eof >= ST_EOD_1)
2806 return 0;
2807 /* The next lines would hide the number of spaced FileMarks
2808 That's why I inserted the previous lines. I had no luck
2809 with detecting EOM with FSF, so we go now to EOM.
2810 Joerg Weule */
2811 } else
2812 fileno = (-1);
2813 cmd[0] = SPACE;
2814 cmd[1] = 3;
Hannes Reineckeb30d8bc2014-06-25 16:39:57 +02002815 DEBC_printk(STp, "Spacing to end of recorded medium.\n");
Linus Torvalds1da177e2005-04-16 15:20:36 -07002816 blkno = -1;
2817 at_sm = 0;
2818 break;
2819 case MTERASE:
2820 if (STp->write_prot)
2821 return (-EACCES);
2822 cmd[0] = ERASE;
2823 cmd[1] = (arg ? 1 : 0); /* Long erase with non-zero argument */
2824 if (STp->immediate) {
2825 cmd[1] |= 2; /* Don't wait for completion */
James Bottomleya02488e2008-11-30 10:36:26 -06002826 timeout = STp->device->request_queue->rq_timeout;
Linus Torvalds1da177e2005-04-16 15:20:36 -07002827 }
2828 else
2829 timeout = STp->long_timeout * 8;
2830
Hannes Reineckeb30d8bc2014-06-25 16:39:57 +02002831 DEBC_printk(STp, "Erasing tape.\n");
Linus Torvalds1da177e2005-04-16 15:20:36 -07002832 fileno = blkno = at_sm = 0;
2833 break;
2834 case MTSETBLK: /* Set block length */
2835 case MTSETDENSITY: /* Set tape density */
2836 case MTSETDRVBUFFER: /* Set drive buffering */
2837 case SET_DENS_AND_BLK: /* Set density and block size */
2838 chg_eof = 0;
2839 if (STp->dirty || (STp->buffer)->buffer_bytes != 0)
2840 return (-EIO); /* Not allowed if data in buffer */
2841 if ((cmd_in == MTSETBLK || cmd_in == SET_DENS_AND_BLK) &&
2842 (arg & MT_ST_BLKSIZE_MASK) != 0 &&
2843 STp->max_block > 0 &&
2844 ((arg & MT_ST_BLKSIZE_MASK) < STp->min_block ||
2845 (arg & MT_ST_BLKSIZE_MASK) > STp->max_block)) {
Hannes Reineckeb30d8bc2014-06-25 16:39:57 +02002846 st_printk(KERN_WARNING, STp, "Illegal block size.\n");
Linus Torvalds1da177e2005-04-16 15:20:36 -07002847 return (-EINVAL);
2848 }
2849 cmd[0] = MODE_SELECT;
2850 if ((STp->use_pf & USE_PF))
2851 cmd[1] = MODE_SELECT_PAGE_FORMAT;
2852 cmd[4] = datalen = 12;
2853 direction = DMA_TO_DEVICE;
2854
2855 memset((STp->buffer)->b_data, 0, 12);
2856 if (cmd_in == MTSETDRVBUFFER)
2857 (STp->buffer)->b_data[2] = (arg & 7) << 4;
2858 else
2859 (STp->buffer)->b_data[2] =
2860 STp->drv_buffer << 4;
2861 (STp->buffer)->b_data[3] = 8; /* block descriptor length */
2862 if (cmd_in == MTSETDENSITY) {
2863 (STp->buffer)->b_data[4] = arg;
2864 STp->density_changed = 1; /* At least we tried ;-) */
2865 } else if (cmd_in == SET_DENS_AND_BLK)
2866 (STp->buffer)->b_data[4] = arg >> 24;
2867 else
2868 (STp->buffer)->b_data[4] = STp->density;
2869 if (cmd_in == MTSETBLK || cmd_in == SET_DENS_AND_BLK) {
2870 ltmp = arg & MT_ST_BLKSIZE_MASK;
2871 if (cmd_in == MTSETBLK)
2872 STp->blksize_changed = 1; /* At least we tried ;-) */
2873 } else
2874 ltmp = STp->block_size;
2875 (STp->buffer)->b_data[9] = (ltmp >> 16);
2876 (STp->buffer)->b_data[10] = (ltmp >> 8);
2877 (STp->buffer)->b_data[11] = ltmp;
James Bottomleya02488e2008-11-30 10:36:26 -06002878 timeout = STp->device->request_queue->rq_timeout;
Hannes Reineckeb30d8bc2014-06-25 16:39:57 +02002879 DEBC(
Linus Torvalds1da177e2005-04-16 15:20:36 -07002880 if (cmd_in == MTSETBLK || cmd_in == SET_DENS_AND_BLK)
Hannes Reineckeb30d8bc2014-06-25 16:39:57 +02002881 st_printk(ST_DEB_MSG, STp,
2882 "Setting block size to %d bytes.\n",
2883 (STp->buffer)->b_data[9] * 65536 +
2884 (STp->buffer)->b_data[10] * 256 +
2885 (STp->buffer)->b_data[11]);
Linus Torvalds1da177e2005-04-16 15:20:36 -07002886 if (cmd_in == MTSETDENSITY || cmd_in == SET_DENS_AND_BLK)
Hannes Reineckeb30d8bc2014-06-25 16:39:57 +02002887 st_printk(ST_DEB_MSG, STp,
2888 "Setting density code to %x.\n",
2889 (STp->buffer)->b_data[4]);
Linus Torvalds1da177e2005-04-16 15:20:36 -07002890 if (cmd_in == MTSETDRVBUFFER)
Hannes Reineckeb30d8bc2014-06-25 16:39:57 +02002891 st_printk(ST_DEB_MSG, STp,
2892 "Setting drive buffer code to %d.\n",
2893 ((STp->buffer)->b_data[2] >> 4) & 7);
Linus Torvalds1da177e2005-04-16 15:20:36 -07002894 )
2895 break;
2896 default:
2897 return (-ENOSYS);
2898 }
2899
Kai Makisara02ae2c02008-12-18 14:49:50 +09002900 SRpnt = st_do_scsi(NULL, STp, cmd, datalen, direction,
2901 timeout, MAX_RETRIES, 1);
Linus Torvalds1da177e2005-04-16 15:20:36 -07002902 if (!SRpnt)
2903 return (STp->buffer)->syscall_result;
2904
Kai Makisara02ae2c02008-12-18 14:49:50 +09002905 ioctl_result = (STp->buffer)->syscall_result;
Linus Torvalds1da177e2005-04-16 15:20:36 -07002906
2907 if (!ioctl_result) { /* SCSI command successful */
Mike Christie8b05b772005-11-08 04:06:44 -06002908 st_release_request(SRpnt);
Linus Torvalds1da177e2005-04-16 15:20:36 -07002909 SRpnt = NULL;
2910 STps->drv_block = blkno;
2911 STps->drv_file = fileno;
2912 STps->at_sm = at_sm;
2913
2914 if (cmd_in == MTBSFM)
2915 ioctl_result = st_int_ioctl(STp, MTFSF, 1);
2916 else if (cmd_in == MTFSFM)
2917 ioctl_result = st_int_ioctl(STp, MTBSF, 1);
2918
2919 if (cmd_in == MTSETBLK || cmd_in == SET_DENS_AND_BLK) {
Linus Torvalds1da177e2005-04-16 15:20:36 -07002920 STp->block_size = arg & MT_ST_BLKSIZE_MASK;
2921 if (STp->block_size != 0) {
Linus Torvalds1da177e2005-04-16 15:20:36 -07002922 (STp->buffer)->buffer_blocks =
2923 (STp->buffer)->buffer_size / STp->block_size;
2924 }
2925 (STp->buffer)->buffer_bytes = (STp->buffer)->read_pointer = 0;
2926 if (cmd_in == SET_DENS_AND_BLK)
2927 STp->density = arg >> MT_ST_DENSITY_SHIFT;
2928 } else if (cmd_in == MTSETDRVBUFFER)
2929 STp->drv_buffer = (arg & 7);
2930 else if (cmd_in == MTSETDENSITY)
2931 STp->density = arg;
2932
2933 if (cmd_in == MTEOM)
2934 STps->eof = ST_EOD;
2935 else if (cmd_in == MTFSF)
2936 STps->eof = ST_FM;
2937 else if (chg_eof)
2938 STps->eof = ST_NOEOF;
2939
Kai Makisara3e51d3c2010-10-09 00:17:56 +03002940 if (cmd_in == MTWEOF || cmd_in == MTWEOFI)
2941 STps->rw = ST_IDLE; /* prevent automatic WEOF at close */
Linus Torvalds1da177e2005-04-16 15:20:36 -07002942 } else { /* SCSI command was not completely successful. Don't return
2943 from this block without releasing the SCSI command block! */
2944 struct st_cmdstatus *cmdstatp = &STp->buffer->cmdstat;
2945
2946 if (cmdstatp->flags & SENSE_EOM) {
2947 if (cmd_in != MTBSF && cmd_in != MTBSFM &&
2948 cmd_in != MTBSR && cmd_in != MTBSS)
2949 STps->eof = ST_EOM_OK;
2950 STps->drv_block = 0;
2951 }
2952
2953 if (cmdstatp->remainder_valid)
2954 undone = (int)cmdstatp->uremainder64;
2955 else
2956 undone = 0;
2957
Kai Makisara3e51d3c2010-10-09 00:17:56 +03002958 if ((cmd_in == MTWEOF || cmd_in == MTWEOFI) &&
Linus Torvalds1da177e2005-04-16 15:20:36 -07002959 cmdstatp->have_sense &&
Kai Makisara91614c02007-01-26 00:38:39 +02002960 (cmdstatp->flags & SENSE_EOM)) {
2961 if (cmdstatp->sense_hdr.sense_key == NO_SENSE ||
2962 cmdstatp->sense_hdr.sense_key == RECOVERED_ERROR) {
2963 ioctl_result = 0; /* EOF(s) written successfully at EOM */
2964 STps->eof = ST_NOEOF;
2965 } else { /* Writing EOF(s) failed */
2966 if (fileno >= 0)
2967 fileno -= undone;
2968 if (undone < arg)
2969 STps->eof = ST_NOEOF;
2970 }
Linus Torvalds1da177e2005-04-16 15:20:36 -07002971 STps->drv_file = fileno;
Linus Torvalds1da177e2005-04-16 15:20:36 -07002972 } else if ((cmd_in == MTFSF) || (cmd_in == MTFSFM)) {
2973 if (fileno >= 0)
2974 STps->drv_file = fileno - undone;
2975 else
2976 STps->drv_file = fileno;
2977 STps->drv_block = -1;
2978 STps->eof = ST_NOEOF;
2979 } else if ((cmd_in == MTBSF) || (cmd_in == MTBSFM)) {
2980 if (arg > 0 && undone < 0) /* Some drives get this wrong */
2981 undone = (-undone);
2982 if (STps->drv_file >= 0)
2983 STps->drv_file = fileno + undone;
2984 STps->drv_block = 0;
2985 STps->eof = ST_NOEOF;
2986 } else if (cmd_in == MTFSR) {
2987 if (cmdstatp->flags & SENSE_FMK) { /* Hit filemark */
2988 if (STps->drv_file >= 0)
2989 STps->drv_file++;
2990 STps->drv_block = 0;
2991 STps->eof = ST_FM;
2992 } else {
2993 if (blkno >= undone)
2994 STps->drv_block = blkno - undone;
2995 else
2996 STps->drv_block = (-1);
2997 STps->eof = ST_NOEOF;
2998 }
2999 } else if (cmd_in == MTBSR) {
3000 if (cmdstatp->flags & SENSE_FMK) { /* Hit filemark */
3001 STps->drv_file--;
3002 STps->drv_block = (-1);
3003 } else {
3004 if (arg > 0 && undone < 0) /* Some drives get this wrong */
3005 undone = (-undone);
3006 if (STps->drv_block >= 0)
3007 STps->drv_block = blkno + undone;
3008 }
3009 STps->eof = ST_NOEOF;
3010 } else if (cmd_in == MTEOM) {
3011 STps->drv_file = (-1);
3012 STps->drv_block = (-1);
3013 STps->eof = ST_EOD;
3014 } else if (cmd_in == MTSETBLK ||
3015 cmd_in == MTSETDENSITY ||
3016 cmd_in == MTSETDRVBUFFER ||
3017 cmd_in == SET_DENS_AND_BLK) {
3018 if (cmdstatp->sense_hdr.sense_key == ILLEGAL_REQUEST &&
3019 !(STp->use_pf & PF_TESTED)) {
3020 /* Try the other possible state of Page Format if not
3021 already tried */
Kai Makisara1da20192009-05-02 08:49:34 +03003022 STp->use_pf = (STp->use_pf ^ USE_PF) | PF_TESTED;
Mike Christie8b05b772005-11-08 04:06:44 -06003023 st_release_request(SRpnt);
Linus Torvalds1da177e2005-04-16 15:20:36 -07003024 SRpnt = NULL;
3025 return st_int_ioctl(STp, cmd_in, arg);
3026 }
3027 } else if (chg_eof)
3028 STps->eof = ST_NOEOF;
3029
3030 if (cmdstatp->sense_hdr.sense_key == BLANK_CHECK)
3031 STps->eof = ST_EOD;
3032
Mike Christie8b05b772005-11-08 04:06:44 -06003033 st_release_request(SRpnt);
Linus Torvalds1da177e2005-04-16 15:20:36 -07003034 SRpnt = NULL;
3035 }
3036
3037 return ioctl_result;
3038}
3039
3040
3041/* Get the tape position. If bt == 2, arg points into a kernel space mt_loc
3042 structure. */
3043
3044static int get_location(struct scsi_tape *STp, unsigned int *block, int *partition,
3045 int logical)
3046{
3047 int result;
3048 unsigned char scmd[MAX_COMMAND_SIZE];
Mike Christie8b05b772005-11-08 04:06:44 -06003049 struct st_request *SRpnt;
Linus Torvalds1da177e2005-04-16 15:20:36 -07003050
3051 if (STp->ready != ST_READY)
3052 return (-EIO);
3053
3054 memset(scmd, 0, MAX_COMMAND_SIZE);
3055 if ((STp->device)->scsi_level < SCSI_2) {
3056 scmd[0] = QFA_REQUEST_BLOCK;
3057 scmd[4] = 3;
3058 } else {
3059 scmd[0] = READ_POSITION;
3060 if (!logical && !STp->scsi2_logical)
3061 scmd[1] = 1;
3062 }
Kai Makisara02ae2c02008-12-18 14:49:50 +09003063 SRpnt = st_do_scsi(NULL, STp, scmd, 20, DMA_FROM_DEVICE,
3064 STp->device->request_queue->rq_timeout,
3065 MAX_READY_RETRIES, 1);
Linus Torvalds1da177e2005-04-16 15:20:36 -07003066 if (!SRpnt)
Kai Makisara02ae2c02008-12-18 14:49:50 +09003067 return (STp->buffer)->syscall_result;
Linus Torvalds1da177e2005-04-16 15:20:36 -07003068
3069 if ((STp->buffer)->syscall_result != 0 ||
3070 (STp->device->scsi_level >= SCSI_2 &&
3071 ((STp->buffer)->b_data[0] & 4) != 0)) {
3072 *block = *partition = 0;
Hannes Reineckeb30d8bc2014-06-25 16:39:57 +02003073 DEBC_printk(STp, " Can't read tape position.\n");
Linus Torvalds1da177e2005-04-16 15:20:36 -07003074 result = (-EIO);
3075 } else {
3076 result = 0;
3077 if ((STp->device)->scsi_level < SCSI_2) {
3078 *block = ((STp->buffer)->b_data[0] << 16)
3079 + ((STp->buffer)->b_data[1] << 8)
3080 + (STp->buffer)->b_data[2];
3081 *partition = 0;
3082 } else {
3083 *block = ((STp->buffer)->b_data[4] << 24)
3084 + ((STp->buffer)->b_data[5] << 16)
3085 + ((STp->buffer)->b_data[6] << 8)
3086 + (STp->buffer)->b_data[7];
3087 *partition = (STp->buffer)->b_data[1];
3088 if (((STp->buffer)->b_data[0] & 0x80) &&
3089 (STp->buffer)->b_data[1] == 0) /* BOP of partition 0 */
3090 STp->ps[0].drv_block = STp->ps[0].drv_file = 0;
3091 }
Hannes Reineckeb30d8bc2014-06-25 16:39:57 +02003092 DEBC_printk(STp, "Got tape pos. blk %d part %d.\n",
3093 *block, *partition);
Linus Torvalds1da177e2005-04-16 15:20:36 -07003094 }
Mike Christie8b05b772005-11-08 04:06:44 -06003095 st_release_request(SRpnt);
Linus Torvalds1da177e2005-04-16 15:20:36 -07003096 SRpnt = NULL;
3097
3098 return result;
3099}
3100
3101
3102/* Set the tape block and partition. Negative partition means that only the
3103 block should be set in vendor specific way. */
3104static int set_location(struct scsi_tape *STp, unsigned int block, int partition,
3105 int logical)
3106{
3107 struct st_partstat *STps;
3108 int result, p;
3109 unsigned int blk;
3110 int timeout;
3111 unsigned char scmd[MAX_COMMAND_SIZE];
Mike Christie8b05b772005-11-08 04:06:44 -06003112 struct st_request *SRpnt;
Linus Torvalds1da177e2005-04-16 15:20:36 -07003113
3114 if (STp->ready != ST_READY)
3115 return (-EIO);
3116 timeout = STp->long_timeout;
3117 STps = &(STp->ps[STp->partition]);
3118
Hannes Reineckeb30d8bc2014-06-25 16:39:57 +02003119 DEBC_printk(STp, "Setting block to %d and partition to %d.\n",
3120 block, partition);
Linus Torvalds1da177e2005-04-16 15:20:36 -07003121 DEB(if (partition < 0)
3122 return (-EIO); )
3123
3124 /* Update the location at the partition we are leaving */
3125 if ((!STp->can_partitions && partition != 0) ||
3126 partition >= ST_NBR_PARTITIONS)
3127 return (-EINVAL);
3128 if (partition != STp->partition) {
3129 if (get_location(STp, &blk, &p, 1))
3130 STps->last_block_valid = 0;
3131 else {
3132 STps->last_block_valid = 1;
3133 STps->last_block_visited = blk;
Hannes Reineckeb30d8bc2014-06-25 16:39:57 +02003134 DEBC_printk(STp, "Visited block %d for "
3135 "partition %d saved.\n",
3136 blk, STp->partition);
Linus Torvalds1da177e2005-04-16 15:20:36 -07003137 }
3138 }
3139
3140 memset(scmd, 0, MAX_COMMAND_SIZE);
3141 if ((STp->device)->scsi_level < SCSI_2) {
3142 scmd[0] = QFA_SEEK_BLOCK;
3143 scmd[2] = (block >> 16);
3144 scmd[3] = (block >> 8);
3145 scmd[4] = block;
3146 scmd[5] = 0;
3147 } else {
3148 scmd[0] = SEEK_10;
3149 scmd[3] = (block >> 24);
3150 scmd[4] = (block >> 16);
3151 scmd[5] = (block >> 8);
3152 scmd[6] = block;
3153 if (!logical && !STp->scsi2_logical)
3154 scmd[1] = 4;
3155 if (STp->partition != partition) {
3156 scmd[1] |= 2;
3157 scmd[8] = partition;
Hannes Reineckeb30d8bc2014-06-25 16:39:57 +02003158 DEBC_printk(STp, "Trying to change partition "
3159 "from %d to %d\n", STp->partition,
3160 partition);
Linus Torvalds1da177e2005-04-16 15:20:36 -07003161 }
3162 }
3163 if (STp->immediate) {
3164 scmd[1] |= 1; /* Don't wait for completion */
James Bottomleya02488e2008-11-30 10:36:26 -06003165 timeout = STp->device->request_queue->rq_timeout;
Linus Torvalds1da177e2005-04-16 15:20:36 -07003166 }
3167
Kai Makisara02ae2c02008-12-18 14:49:50 +09003168 SRpnt = st_do_scsi(NULL, STp, scmd, 0, DMA_NONE,
3169 timeout, MAX_READY_RETRIES, 1);
Linus Torvalds1da177e2005-04-16 15:20:36 -07003170 if (!SRpnt)
Kai Makisara02ae2c02008-12-18 14:49:50 +09003171 return (STp->buffer)->syscall_result;
Linus Torvalds1da177e2005-04-16 15:20:36 -07003172
3173 STps->drv_block = STps->drv_file = (-1);
3174 STps->eof = ST_NOEOF;
3175 if ((STp->buffer)->syscall_result != 0) {
3176 result = (-EIO);
3177 if (STp->can_partitions &&
3178 (STp->device)->scsi_level >= SCSI_2 &&
3179 (p = find_partition(STp)) >= 0)
3180 STp->partition = p;
3181 } else {
3182 if (STp->can_partitions) {
3183 STp->partition = partition;
3184 STps = &(STp->ps[partition]);
3185 if (!STps->last_block_valid ||
3186 STps->last_block_visited != block) {
3187 STps->at_sm = 0;
3188 STps->rw = ST_IDLE;
3189 }
3190 } else
3191 STps->at_sm = 0;
3192 if (block == 0)
3193 STps->drv_block = STps->drv_file = 0;
3194 result = 0;
3195 }
Kai Makisara02ae2c02008-12-18 14:49:50 +09003196
Mike Christie8b05b772005-11-08 04:06:44 -06003197 st_release_request(SRpnt);
Linus Torvalds1da177e2005-04-16 15:20:36 -07003198 SRpnt = NULL;
3199
3200 return result;
3201}
3202
3203
3204/* Find the current partition number for the drive status. Called from open and
3205 returns either partition number of negative error code. */
3206static int find_partition(struct scsi_tape *STp)
3207{
3208 int i, partition;
3209 unsigned int block;
3210
3211 if ((i = get_location(STp, &block, &partition, 1)) < 0)
3212 return i;
3213 if (partition >= ST_NBR_PARTITIONS)
3214 return (-EIO);
3215 return partition;
3216}
3217
3218
3219/* Change the partition if necessary */
3220static int switch_partition(struct scsi_tape *STp)
3221{
3222 struct st_partstat *STps;
3223
3224 if (STp->partition == STp->new_partition)
3225 return 0;
3226 STps = &(STp->ps[STp->new_partition]);
3227 if (!STps->last_block_valid)
3228 STps->last_block_visited = 0;
3229 return set_location(STp, STps->last_block_visited, STp->new_partition, 1);
3230}
3231
3232/* Functions for reading and writing the medium partition mode page. */
3233
3234#define PART_PAGE 0x11
3235#define PART_PAGE_FIXED_LENGTH 8
3236
3237#define PP_OFF_MAX_ADD_PARTS 2
3238#define PP_OFF_NBR_ADD_PARTS 3
3239#define PP_OFF_FLAGS 4
3240#define PP_OFF_PART_UNITS 6
3241#define PP_OFF_RESERVED 7
3242
3243#define PP_BIT_IDP 0x20
3244#define PP_MSK_PSUM_MB 0x10
3245
3246/* Get the number of partitions on the tape. As a side effect reads the
3247 mode page into the tape buffer. */
3248static int nbr_partitions(struct scsi_tape *STp)
3249{
3250 int result;
Linus Torvalds1da177e2005-04-16 15:20:36 -07003251
3252 if (STp->ready != ST_READY)
3253 return (-EIO);
3254
3255 result = read_mode_page(STp, PART_PAGE, 1);
3256
3257 if (result) {
Hannes Reineckeb30d8bc2014-06-25 16:39:57 +02003258 DEBC_printk(STp, "Can't read medium partition page.\n");
Linus Torvalds1da177e2005-04-16 15:20:36 -07003259 result = (-EIO);
3260 } else {
3261 result = (STp->buffer)->b_data[MODE_HEADER_LENGTH +
3262 PP_OFF_NBR_ADD_PARTS] + 1;
Hannes Reineckeb30d8bc2014-06-25 16:39:57 +02003263 DEBC_printk(STp, "Number of partitions %d.\n", result);
Linus Torvalds1da177e2005-04-16 15:20:36 -07003264 }
3265
3266 return result;
3267}
3268
3269
3270/* Partition the tape into two partitions if size > 0 or one partition if
3271 size == 0.
3272
3273 The block descriptors are read and written because Sony SDT-7000 does not
3274 work without this (suggestion from Michael Schaefer <Michael.Schaefer@dlr.de>).
3275
3276 My HP C1533A drive returns only one partition size field. This is used to
3277 set the size of partition 1. There is no size field for the default partition.
3278 Michael Schaefer's Sony SDT-7000 returns two descriptors and the second is
3279 used to set the size of partition 1 (this is what the SCSI-3 standard specifies).
3280 The following algorithm is used to accommodate both drives: if the number of
3281 partition size fields is greater than the maximum number of additional partitions
3282 in the mode page, the second field is used. Otherwise the first field is used.
3283
3284 For Seagate DDS drives the page length must be 8 when no partitions is defined
3285 and 10 when 1 partition is defined (information from Eric Lee Green). This is
3286 is acceptable also to some other old drives and enforced if the first partition
3287 size field is used for the first additional partition size.
3288 */
3289static int partition_tape(struct scsi_tape *STp, int size)
3290{
Linus Torvalds1da177e2005-04-16 15:20:36 -07003291 int result;
3292 int pgo, psd_cnt, psdo;
3293 unsigned char *bp;
3294
3295 result = read_mode_page(STp, PART_PAGE, 0);
3296 if (result) {
Hannes Reineckeb30d8bc2014-06-25 16:39:57 +02003297 DEBC_printk(STp, "Can't read partition mode page.\n");
Linus Torvalds1da177e2005-04-16 15:20:36 -07003298 return result;
3299 }
3300 /* The mode page is in the buffer. Let's modify it and write it. */
3301 bp = (STp->buffer)->b_data;
3302 pgo = MODE_HEADER_LENGTH + bp[MH_OFF_BDESCS_LENGTH];
Hannes Reineckeb30d8bc2014-06-25 16:39:57 +02003303 DEBC_printk(STp, "Partition page length is %d bytes.\n",
3304 bp[pgo + MP_OFF_PAGE_LENGTH] + 2);
Linus Torvalds1da177e2005-04-16 15:20:36 -07003305
3306 psd_cnt = (bp[pgo + MP_OFF_PAGE_LENGTH] + 2 - PART_PAGE_FIXED_LENGTH) / 2;
3307 psdo = pgo + PART_PAGE_FIXED_LENGTH;
3308 if (psd_cnt > bp[pgo + PP_OFF_MAX_ADD_PARTS]) {
3309 bp[psdo] = bp[psdo + 1] = 0xff; /* Rest of the tape */
3310 psdo += 2;
3311 }
3312 memset(bp + psdo, 0, bp[pgo + PP_OFF_NBR_ADD_PARTS] * 2);
3313
Hannes Reineckeb30d8bc2014-06-25 16:39:57 +02003314 DEBC_printk(STp, "psd_cnt %d, max.parts %d, nbr_parts %d\n",
Linus Torvalds1da177e2005-04-16 15:20:36 -07003315 psd_cnt, bp[pgo + PP_OFF_MAX_ADD_PARTS],
Hannes Reineckeb30d8bc2014-06-25 16:39:57 +02003316 bp[pgo + PP_OFF_NBR_ADD_PARTS]);
Linus Torvalds1da177e2005-04-16 15:20:36 -07003317
3318 if (size <= 0) {
3319 bp[pgo + PP_OFF_NBR_ADD_PARTS] = 0;
3320 if (psd_cnt <= bp[pgo + PP_OFF_MAX_ADD_PARTS])
3321 bp[pgo + MP_OFF_PAGE_LENGTH] = 6;
Hannes Reineckeb30d8bc2014-06-25 16:39:57 +02003322 DEBC_printk(STp, "Formatting tape with one partition.\n");
Linus Torvalds1da177e2005-04-16 15:20:36 -07003323 } else {
3324 bp[psdo] = (size >> 8) & 0xff;
3325 bp[psdo + 1] = size & 0xff;
3326 bp[pgo + 3] = 1;
3327 if (bp[pgo + MP_OFF_PAGE_LENGTH] < 8)
3328 bp[pgo + MP_OFF_PAGE_LENGTH] = 8;
Hannes Reineckeb30d8bc2014-06-25 16:39:57 +02003329 DEBC_printk(STp, "Formatting tape with two partitions "
3330 "(1 = %d MB).\n", size);
Linus Torvalds1da177e2005-04-16 15:20:36 -07003331 }
3332 bp[pgo + PP_OFF_PART_UNITS] = 0;
3333 bp[pgo + PP_OFF_RESERVED] = 0;
3334 bp[pgo + PP_OFF_FLAGS] = PP_BIT_IDP | PP_MSK_PSUM_MB;
3335
3336 result = write_mode_page(STp, PART_PAGE, 1);
3337 if (result) {
Hannes Reineckeb30d8bc2014-06-25 16:39:57 +02003338 st_printk(KERN_INFO, STp, "Partitioning of tape failed.\n");
Linus Torvalds1da177e2005-04-16 15:20:36 -07003339 result = (-EIO);
3340 }
3341
3342 return result;
3343}
3344
3345
3346
3347/* The ioctl command */
Kai Makisarafd66c1b2008-01-17 22:45:22 +02003348static long st_ioctl(struct file *file, unsigned int cmd_in, unsigned long arg)
Linus Torvalds1da177e2005-04-16 15:20:36 -07003349{
3350 int i, cmd_nr, cmd_type, bt;
3351 int retval = 0;
3352 unsigned int blk;
3353 struct scsi_tape *STp = file->private_data;
3354 struct st_modedef *STm;
3355 struct st_partstat *STps;
Linus Torvalds1da177e2005-04-16 15:20:36 -07003356 void __user *p = (void __user *)arg;
3357
Matthias Kaehlcke28f85002007-07-29 23:38:15 +02003358 if (mutex_lock_interruptible(&STp->lock))
Linus Torvalds1da177e2005-04-16 15:20:36 -07003359 return -ERESTARTSYS;
3360
Hannes Reineckeb30d8bc2014-06-25 16:39:57 +02003361 DEB(
Linus Torvalds1da177e2005-04-16 15:20:36 -07003362 if (debugging && !STp->in_use) {
Hannes Reineckeb30d8bc2014-06-25 16:39:57 +02003363 st_printk(ST_DEB_MSG, STp, "Incorrect device.\n");
Linus Torvalds1da177e2005-04-16 15:20:36 -07003364 retval = (-EIO);
3365 goto out;
3366 } ) /* end DEB */
3367
3368 STm = &(STp->modes[STp->current_mode]);
3369 STps = &(STp->ps[STp->partition]);
3370
3371 /*
3372 * If we are in the middle of error recovery, don't let anyone
3373 * else try and use this device. Also, if error recovery fails, it
3374 * may try and take the device offline, in which case all further
3375 * access to the device is prohibited.
3376 */
Al Viro83ff6fe2008-03-02 08:15:49 -05003377 retval = scsi_nonblockable_ioctl(STp->device, cmd_in, p,
3378 file->f_flags & O_NDELAY);
Linus Torvalds1da177e2005-04-16 15:20:36 -07003379 if (!scsi_block_when_processing_errors(STp->device) || retval != -ENODEV)
3380 goto out;
3381 retval = 0;
3382
3383 cmd_type = _IOC_TYPE(cmd_in);
3384 cmd_nr = _IOC_NR(cmd_in);
3385
3386 if (cmd_type == _IOC_TYPE(MTIOCTOP) && cmd_nr == _IOC_NR(MTIOCTOP)) {
3387 struct mtop mtc;
3388
3389 if (_IOC_SIZE(cmd_in) != sizeof(mtc)) {
3390 retval = (-EINVAL);
3391 goto out;
3392 }
3393
3394 i = copy_from_user(&mtc, p, sizeof(struct mtop));
3395 if (i) {
3396 retval = (-EFAULT);
3397 goto out;
3398 }
3399
3400 if (mtc.mt_op == MTSETDRVBUFFER && !capable(CAP_SYS_ADMIN)) {
Hannes Reineckeb30d8bc2014-06-25 16:39:57 +02003401 st_printk(KERN_WARNING, STp,
3402 "MTSETDRVBUFFER only allowed for root.\n");
Linus Torvalds1da177e2005-04-16 15:20:36 -07003403 retval = (-EPERM);
3404 goto out;
3405 }
3406 if (!STm->defined &&
3407 (mtc.mt_op != MTSETDRVBUFFER &&
3408 (mtc.mt_count & MT_ST_OPTIONS) == 0)) {
3409 retval = (-ENXIO);
3410 goto out;
3411 }
3412
3413 if (!STp->pos_unknown) {
3414
3415 if (STps->eof == ST_FM_HIT) {
3416 if (mtc.mt_op == MTFSF || mtc.mt_op == MTFSFM ||
3417 mtc.mt_op == MTEOM) {
3418 mtc.mt_count -= 1;
3419 if (STps->drv_file >= 0)
3420 STps->drv_file += 1;
3421 } else if (mtc.mt_op == MTBSF || mtc.mt_op == MTBSFM) {
3422 mtc.mt_count += 1;
3423 if (STps->drv_file >= 0)
3424 STps->drv_file += 1;
3425 }
3426 }
3427
3428 if (mtc.mt_op == MTSEEK) {
3429 /* Old position must be restored if partition will be
3430 changed */
3431 i = !STp->can_partitions ||
3432 (STp->new_partition != STp->partition);
3433 } else {
3434 i = mtc.mt_op == MTREW || mtc.mt_op == MTOFFL ||
3435 mtc.mt_op == MTRETEN || mtc.mt_op == MTEOM ||
3436 mtc.mt_op == MTLOCK || mtc.mt_op == MTLOAD ||
3437 mtc.mt_op == MTFSF || mtc.mt_op == MTFSFM ||
3438 mtc.mt_op == MTBSF || mtc.mt_op == MTBSFM ||
3439 mtc.mt_op == MTCOMPRESSION;
3440 }
3441 i = flush_buffer(STp, i);
3442 if (i < 0) {
3443 retval = i;
3444 goto out;
3445 }
3446 if (STps->rw == ST_WRITING &&
3447 (mtc.mt_op == MTREW || mtc.mt_op == MTOFFL ||
3448 mtc.mt_op == MTSEEK ||
3449 mtc.mt_op == MTBSF || mtc.mt_op == MTBSFM)) {
3450 i = st_int_ioctl(STp, MTWEOF, 1);
3451 if (i < 0) {
3452 retval = i;
3453 goto out;
3454 }
3455 if (mtc.mt_op == MTBSF || mtc.mt_op == MTBSFM)
3456 mtc.mt_count++;
3457 STps->rw = ST_IDLE;
3458 }
3459
3460 } else {
3461 /*
3462 * If there was a bus reset, block further access
3463 * to this device. If the user wants to rewind the tape,
3464 * then reset the flag and allow access again.
3465 */
3466 if (mtc.mt_op != MTREW &&
3467 mtc.mt_op != MTOFFL &&
3468 mtc.mt_op != MTRETEN &&
3469 mtc.mt_op != MTERASE &&
3470 mtc.mt_op != MTSEEK &&
3471 mtc.mt_op != MTEOM) {
3472 retval = (-EIO);
3473 goto out;
3474 }
3475 reset_state(STp);
3476 /* remove this when the midlevel properly clears was_reset */
3477 STp->device->was_reset = 0;
3478 }
3479
3480 if (mtc.mt_op != MTNOP && mtc.mt_op != MTSETBLK &&
3481 mtc.mt_op != MTSETDENSITY && mtc.mt_op != MTWSM &&
3482 mtc.mt_op != MTSETDRVBUFFER && mtc.mt_op != MTSETPART)
3483 STps->rw = ST_IDLE; /* Prevent automatic WEOF and fsf */
3484
3485 if (mtc.mt_op == MTOFFL && STp->door_locked != ST_UNLOCKED)
3486 do_door_lock(STp, 0); /* Ignore result! */
3487
3488 if (mtc.mt_op == MTSETDRVBUFFER &&
3489 (mtc.mt_count & MT_ST_OPTIONS) != 0) {
3490 retval = st_set_options(STp, mtc.mt_count);
3491 goto out;
3492 }
3493
3494 if (mtc.mt_op == MTSETPART) {
3495 if (!STp->can_partitions ||
3496 mtc.mt_count < 0 || mtc.mt_count >= ST_NBR_PARTITIONS) {
3497 retval = (-EINVAL);
3498 goto out;
3499 }
3500 if (mtc.mt_count >= STp->nbr_partitions &&
3501 (STp->nbr_partitions = nbr_partitions(STp)) < 0) {
3502 retval = (-EIO);
3503 goto out;
3504 }
3505 if (mtc.mt_count >= STp->nbr_partitions) {
3506 retval = (-EINVAL);
3507 goto out;
3508 }
3509 STp->new_partition = mtc.mt_count;
3510 retval = 0;
3511 goto out;
3512 }
3513
3514 if (mtc.mt_op == MTMKPART) {
3515 if (!STp->can_partitions) {
3516 retval = (-EINVAL);
3517 goto out;
3518 }
3519 if ((i = st_int_ioctl(STp, MTREW, 0)) < 0 ||
3520 (i = partition_tape(STp, mtc.mt_count)) < 0) {
3521 retval = i;
3522 goto out;
3523 }
3524 for (i = 0; i < ST_NBR_PARTITIONS; i++) {
3525 STp->ps[i].rw = ST_IDLE;
3526 STp->ps[i].at_sm = 0;
3527 STp->ps[i].last_block_valid = 0;
3528 }
3529 STp->partition = STp->new_partition = 0;
3530 STp->nbr_partitions = 1; /* Bad guess ?-) */
3531 STps->drv_block = STps->drv_file = 0;
3532 retval = 0;
3533 goto out;
3534 }
3535
3536 if (mtc.mt_op == MTSEEK) {
3537 i = set_location(STp, mtc.mt_count, STp->new_partition, 0);
3538 if (!STp->can_partitions)
3539 STp->ps[0].rw = ST_IDLE;
3540 retval = i;
3541 goto out;
3542 }
3543
3544 if (mtc.mt_op == MTUNLOAD || mtc.mt_op == MTOFFL) {
3545 retval = do_load_unload(STp, file, 0);
3546 goto out;
3547 }
3548
3549 if (mtc.mt_op == MTLOAD) {
3550 retval = do_load_unload(STp, file, max(1, mtc.mt_count));
3551 goto out;
3552 }
3553
3554 if (mtc.mt_op == MTLOCK || mtc.mt_op == MTUNLOCK) {
3555 retval = do_door_lock(STp, (mtc.mt_op == MTLOCK));
3556 goto out;
3557 }
3558
3559 if (STp->can_partitions && STp->ready == ST_READY &&
3560 (i = switch_partition(STp)) < 0) {
3561 retval = i;
3562 goto out;
3563 }
3564
3565 if (mtc.mt_op == MTCOMPRESSION)
3566 retval = st_compression(STp, (mtc.mt_count & 1));
3567 else
3568 retval = st_int_ioctl(STp, mtc.mt_op, mtc.mt_count);
3569 goto out;
3570 }
3571 if (!STm->defined) {
3572 retval = (-ENXIO);
3573 goto out;
3574 }
3575
3576 if ((i = flush_buffer(STp, 0)) < 0) {
3577 retval = i;
3578 goto out;
3579 }
3580 if (STp->can_partitions &&
3581 (i = switch_partition(STp)) < 0) {
3582 retval = i;
3583 goto out;
3584 }
3585
3586 if (cmd_type == _IOC_TYPE(MTIOCGET) && cmd_nr == _IOC_NR(MTIOCGET)) {
3587 struct mtget mt_status;
3588
3589 if (_IOC_SIZE(cmd_in) != sizeof(struct mtget)) {
3590 retval = (-EINVAL);
3591 goto out;
3592 }
3593
3594 mt_status.mt_type = STp->tape_type;
3595 mt_status.mt_dsreg =
3596 ((STp->block_size << MT_ST_BLKSIZE_SHIFT) & MT_ST_BLKSIZE_MASK) |
3597 ((STp->density << MT_ST_DENSITY_SHIFT) & MT_ST_DENSITY_MASK);
3598 mt_status.mt_blkno = STps->drv_block;
3599 mt_status.mt_fileno = STps->drv_file;
3600 if (STp->block_size != 0) {
3601 if (STps->rw == ST_WRITING)
3602 mt_status.mt_blkno +=
3603 (STp->buffer)->buffer_bytes / STp->block_size;
3604 else if (STps->rw == ST_READING)
3605 mt_status.mt_blkno -=
3606 ((STp->buffer)->buffer_bytes +
3607 STp->block_size - 1) / STp->block_size;
3608 }
3609
3610 mt_status.mt_gstat = 0;
3611 if (STp->drv_write_prot)
3612 mt_status.mt_gstat |= GMT_WR_PROT(0xffffffff);
3613 if (mt_status.mt_blkno == 0) {
3614 if (mt_status.mt_fileno == 0)
3615 mt_status.mt_gstat |= GMT_BOT(0xffffffff);
3616 else
3617 mt_status.mt_gstat |= GMT_EOF(0xffffffff);
3618 }
3619 mt_status.mt_erreg = (STp->recover_reg << MT_ST_SOFTERR_SHIFT);
3620 mt_status.mt_resid = STp->partition;
3621 if (STps->eof == ST_EOM_OK || STps->eof == ST_EOM_ERROR)
3622 mt_status.mt_gstat |= GMT_EOT(0xffffffff);
3623 else if (STps->eof >= ST_EOM_OK)
3624 mt_status.mt_gstat |= GMT_EOD(0xffffffff);
3625 if (STp->density == 1)
3626 mt_status.mt_gstat |= GMT_D_800(0xffffffff);
3627 else if (STp->density == 2)
3628 mt_status.mt_gstat |= GMT_D_1600(0xffffffff);
3629 else if (STp->density == 3)
3630 mt_status.mt_gstat |= GMT_D_6250(0xffffffff);
3631 if (STp->ready == ST_READY)
3632 mt_status.mt_gstat |= GMT_ONLINE(0xffffffff);
3633 if (STp->ready == ST_NO_TAPE)
3634 mt_status.mt_gstat |= GMT_DR_OPEN(0xffffffff);
3635 if (STps->at_sm)
3636 mt_status.mt_gstat |= GMT_SM(0xffffffff);
3637 if (STm->do_async_writes ||
3638 (STm->do_buffer_writes && STp->block_size != 0) ||
3639 STp->drv_buffer != 0)
3640 mt_status.mt_gstat |= GMT_IM_REP_EN(0xffffffff);
3641 if (STp->cleaning_req)
3642 mt_status.mt_gstat |= GMT_CLN(0xffffffff);
3643
3644 i = copy_to_user(p, &mt_status, sizeof(struct mtget));
3645 if (i) {
3646 retval = (-EFAULT);
3647 goto out;
3648 }
3649
3650 STp->recover_reg = 0; /* Clear after read */
3651 retval = 0;
3652 goto out;
3653 } /* End of MTIOCGET */
3654 if (cmd_type == _IOC_TYPE(MTIOCPOS) && cmd_nr == _IOC_NR(MTIOCPOS)) {
3655 struct mtpos mt_pos;
3656 if (_IOC_SIZE(cmd_in) != sizeof(struct mtpos)) {
3657 retval = (-EINVAL);
3658 goto out;
3659 }
3660 if ((i = get_location(STp, &blk, &bt, 0)) < 0) {
3661 retval = i;
3662 goto out;
3663 }
3664 mt_pos.mt_blkno = blk;
3665 i = copy_to_user(p, &mt_pos, sizeof(struct mtpos));
3666 if (i)
3667 retval = (-EFAULT);
3668 goto out;
3669 }
Matthias Kaehlcke28f85002007-07-29 23:38:15 +02003670 mutex_unlock(&STp->lock);
Linus Torvalds1da177e2005-04-16 15:20:36 -07003671 switch (cmd_in) {
3672 case SCSI_IOCTL_GET_IDLUN:
3673 case SCSI_IOCTL_GET_BUS_NUMBER:
3674 break;
3675 default:
Kai Makisara 16c4b3e2005-05-01 18:11:55 +03003676 if ((cmd_in == SG_IO ||
3677 cmd_in == SCSI_IOCTL_SEND_COMMAND ||
3678 cmd_in == CDROM_SEND_PACKET) &&
3679 !capable(CAP_SYS_RAWIO))
Linus Torvalds1da177e2005-04-16 15:20:36 -07003680 i = -EPERM;
3681 else
Al Viro74f3c8a2007-08-27 15:38:10 -04003682 i = scsi_cmd_ioctl(STp->disk->queue, STp->disk,
3683 file->f_mode, cmd_in, p);
Linus Torvalds1da177e2005-04-16 15:20:36 -07003684 if (i != -ENOTTY)
3685 return i;
3686 break;
3687 }
Kai Makisara 16c4b3e2005-05-01 18:11:55 +03003688 retval = scsi_ioctl(STp->device, cmd_in, p);
3689 if (!retval && cmd_in == SCSI_IOCTL_STOP_UNIT) { /* unload */
3690 STp->rew_at_close = 0;
3691 STp->ready = ST_NO_TAPE;
3692 }
3693 return retval;
Linus Torvalds1da177e2005-04-16 15:20:36 -07003694
3695 out:
Matthias Kaehlcke28f85002007-07-29 23:38:15 +02003696 mutex_unlock(&STp->lock);
Linus Torvalds1da177e2005-04-16 15:20:36 -07003697 return retval;
3698}
3699
3700#ifdef CONFIG_COMPAT
3701static long st_compat_ioctl(struct file *file, unsigned int cmd, unsigned long arg)
3702{
3703 struct scsi_tape *STp = file->private_data;
3704 struct scsi_device *sdev = STp->device;
3705 int ret = -ENOIOCTLCMD;
3706 if (sdev->host->hostt->compat_ioctl) {
3707
3708 ret = sdev->host->hostt->compat_ioctl(sdev, cmd, (void __user *)arg);
3709
3710 }
3711 return ret;
3712}
3713#endif
3714
3715
3716
3717/* Try to allocate a new tape buffer. Calling function must not hold
3718 dev_arr_lock. */
FUJITA Tomonorif409d6c2008-12-18 14:49:47 +09003719static struct st_buffer *new_tape_buffer(int need_dma, int max_sg)
Linus Torvalds1da177e2005-04-16 15:20:36 -07003720{
Linus Torvalds1da177e2005-04-16 15:20:36 -07003721 struct st_buffer *tb;
3722
FUJITA Tomonorif409d6c2008-12-18 14:49:47 +09003723 tb = kzalloc(sizeof(struct st_buffer), GFP_ATOMIC);
Linus Torvalds1da177e2005-04-16 15:20:36 -07003724 if (!tb) {
3725 printk(KERN_NOTICE "st: Can't allocate new tape buffer.\n");
3726 return NULL;
3727 }
FUJITA Tomonori1ac63cf2008-12-18 14:49:48 +09003728 tb->frp_segs = 0;
Linus Torvalds1da177e2005-04-16 15:20:36 -07003729 tb->use_sg = max_sg;
Linus Torvalds1da177e2005-04-16 15:20:36 -07003730 tb->dma = need_dma;
FUJITA Tomonorif409d6c2008-12-18 14:49:47 +09003731 tb->buffer_size = 0;
Linus Torvalds1da177e2005-04-16 15:20:36 -07003732
FUJITA Tomonorif409d6c2008-12-18 14:49:47 +09003733 tb->reserved_pages = kzalloc(max_sg * sizeof(struct page *),
3734 GFP_ATOMIC);
FUJITA Tomonorid0e1ae32008-12-18 14:49:40 +09003735 if (!tb->reserved_pages) {
3736 kfree(tb);
3737 return NULL;
3738 }
3739
Linus Torvalds1da177e2005-04-16 15:20:36 -07003740 return tb;
3741}
3742
3743
3744/* Try to allocate enough space in the tape buffer */
Kai Makisara8f78fc52008-12-18 14:49:51 +09003745#define ST_MAX_ORDER 6
3746
Linus Torvalds1da177e2005-04-16 15:20:36 -07003747static int enlarge_buffer(struct st_buffer * STbuffer, int new_size, int need_dma)
3748{
Bodo Stroesser769989a2013-12-02 18:52:10 +01003749 int segs, max_segs, b_size, order, got;
Al Viroc53033f2005-10-21 03:22:08 -04003750 gfp_t priority;
Linus Torvalds1da177e2005-04-16 15:20:36 -07003751
3752 if (new_size <= STbuffer->buffer_size)
3753 return 1;
3754
3755 if (STbuffer->buffer_size <= PAGE_SIZE)
3756 normalize_buffer(STbuffer); /* Avoid extra segment */
3757
3758 max_segs = STbuffer->use_sg;
Linus Torvalds1da177e2005-04-16 15:20:36 -07003759
3760 priority = GFP_KERNEL | __GFP_NOWARN;
3761 if (need_dma)
3762 priority |= GFP_DMA;
FUJITA Tomonori9c905962008-12-18 14:49:39 +09003763
FUJITA Tomonori08c95832008-12-18 14:49:45 +09003764 if (STbuffer->cleared)
3765 priority |= __GFP_ZERO;
3766
FUJITA Tomonori9c905962008-12-18 14:49:39 +09003767 if (STbuffer->frp_segs) {
FUJITA Tomonoric982c362009-11-26 09:24:13 +09003768 order = STbuffer->reserved_page_order;
FUJITA Tomonori08c95832008-12-18 14:49:45 +09003769 b_size = PAGE_SIZE << order;
FUJITA Tomonori9c905962008-12-18 14:49:39 +09003770 } else {
3771 for (b_size = PAGE_SIZE, order = 0;
FUJITA Tomonori46081b12010-12-20 18:44:45 +02003772 order < ST_MAX_ORDER &&
3773 max_segs * (PAGE_SIZE << order) < new_size;
Kai Makisara8f78fc52008-12-18 14:49:51 +09003774 order++, b_size *= 2)
FUJITA Tomonori9c905962008-12-18 14:49:39 +09003775 ; /* empty */
Kai Makisara373daac2010-12-20 18:43:39 +02003776 STbuffer->reserved_page_order = order;
FUJITA Tomonori9c905962008-12-18 14:49:39 +09003777 }
Kai Makisara8f78fc52008-12-18 14:49:51 +09003778 if (max_segs * (PAGE_SIZE << order) < new_size) {
3779 if (order == ST_MAX_ORDER)
3780 return 0;
3781 normalize_buffer(STbuffer);
3782 return enlarge_buffer(STbuffer, new_size, need_dma);
3783 }
Linus Torvalds1da177e2005-04-16 15:20:36 -07003784
3785 for (segs = STbuffer->frp_segs, got = STbuffer->buffer_size;
3786 segs < max_segs && got < new_size;) {
FUJITA Tomonori08c95832008-12-18 14:49:45 +09003787 struct page *page;
3788
3789 page = alloc_pages(priority, order);
3790 if (!page) {
Linus Torvalds1da177e2005-04-16 15:20:36 -07003791 DEB(STbuffer->buffer_size = got);
3792 normalize_buffer(STbuffer);
3793 return 0;
3794 }
FUJITA Tomonori08c95832008-12-18 14:49:45 +09003795
Linus Torvalds1da177e2005-04-16 15:20:36 -07003796 STbuffer->frp_segs += 1;
3797 got += b_size;
3798 STbuffer->buffer_size = got;
FUJITA Tomonori08c95832008-12-18 14:49:45 +09003799 STbuffer->reserved_pages[segs] = page;
Linus Torvalds1da177e2005-04-16 15:20:36 -07003800 segs++;
3801 }
FUJITA Tomonori08c95832008-12-18 14:49:45 +09003802 STbuffer->b_data = page_address(STbuffer->reserved_pages[0]);
Linus Torvalds1da177e2005-04-16 15:20:36 -07003803
3804 return 1;
3805}
3806
3807
Kai Makisara40f6b362008-02-24 22:23:24 +02003808/* Make sure that no data from previous user is in the internal buffer */
3809static void clear_buffer(struct st_buffer * st_bp)
3810{
3811 int i;
3812
3813 for (i=0; i < st_bp->frp_segs; i++)
FUJITA Tomonori08c95832008-12-18 14:49:45 +09003814 memset(page_address(st_bp->reserved_pages[i]), 0,
FUJITA Tomonoric982c362009-11-26 09:24:13 +09003815 PAGE_SIZE << st_bp->reserved_page_order);
Kai Makisara40f6b362008-02-24 22:23:24 +02003816 st_bp->cleared = 1;
3817}
3818
3819
Linus Torvalds1da177e2005-04-16 15:20:36 -07003820/* Release the extra buffer */
3821static void normalize_buffer(struct st_buffer * STbuffer)
3822{
FUJITA Tomonoric982c362009-11-26 09:24:13 +09003823 int i, order = STbuffer->reserved_page_order;
Linus Torvalds1da177e2005-04-16 15:20:36 -07003824
FUJITA Tomonori1ac63cf2008-12-18 14:49:48 +09003825 for (i = 0; i < STbuffer->frp_segs; i++) {
FUJITA Tomonori08c95832008-12-18 14:49:45 +09003826 __free_pages(STbuffer->reserved_pages[i], order);
3827 STbuffer->buffer_size -= (PAGE_SIZE << order);
Linus Torvalds1da177e2005-04-16 15:20:36 -07003828 }
FUJITA Tomonori1ac63cf2008-12-18 14:49:48 +09003829 STbuffer->frp_segs = 0;
Mike Christie8b05b772005-11-08 04:06:44 -06003830 STbuffer->sg_segs = 0;
FUJITA Tomonoric982c362009-11-26 09:24:13 +09003831 STbuffer->reserved_page_order = 0;
FUJITA Tomonorid0e1ae32008-12-18 14:49:40 +09003832 STbuffer->map_data.offset = 0;
Linus Torvalds1da177e2005-04-16 15:20:36 -07003833}
3834
3835
3836/* Move data from the user buffer to the tape buffer. Returns zero (success) or
3837 negative error code. */
3838static int append_to_buffer(const char __user *ubp, struct st_buffer * st_bp, int do_count)
3839{
3840 int i, cnt, res, offset;
FUJITA Tomonoric982c362009-11-26 09:24:13 +09003841 int length = PAGE_SIZE << st_bp->reserved_page_order;
Linus Torvalds1da177e2005-04-16 15:20:36 -07003842
3843 for (i = 0, offset = st_bp->buffer_bytes;
FUJITA Tomonori08c95832008-12-18 14:49:45 +09003844 i < st_bp->frp_segs && offset >= length; i++)
3845 offset -= length;
Linus Torvalds1da177e2005-04-16 15:20:36 -07003846 if (i == st_bp->frp_segs) { /* Should never happen */
3847 printk(KERN_WARNING "st: append_to_buffer offset overflow.\n");
3848 return (-EIO);
3849 }
3850 for (; i < st_bp->frp_segs && do_count > 0; i++) {
FUJITA Tomonori08c95832008-12-18 14:49:45 +09003851 struct page *page = st_bp->reserved_pages[i];
3852 cnt = length - offset < do_count ? length - offset : do_count;
3853 res = copy_from_user(page_address(page) + offset, ubp, cnt);
Linus Torvalds1da177e2005-04-16 15:20:36 -07003854 if (res)
3855 return (-EFAULT);
3856 do_count -= cnt;
3857 st_bp->buffer_bytes += cnt;
3858 ubp += cnt;
3859 offset = 0;
3860 }
3861 if (do_count) /* Should never happen */
3862 return (-EIO);
3863
3864 return 0;
3865}
3866
3867
3868/* Move data from the tape buffer to the user buffer. Returns zero (success) or
3869 negative error code. */
3870static int from_buffer(struct st_buffer * st_bp, char __user *ubp, int do_count)
3871{
3872 int i, cnt, res, offset;
FUJITA Tomonoric982c362009-11-26 09:24:13 +09003873 int length = PAGE_SIZE << st_bp->reserved_page_order;
Linus Torvalds1da177e2005-04-16 15:20:36 -07003874
3875 for (i = 0, offset = st_bp->read_pointer;
FUJITA Tomonori08c95832008-12-18 14:49:45 +09003876 i < st_bp->frp_segs && offset >= length; i++)
3877 offset -= length;
Linus Torvalds1da177e2005-04-16 15:20:36 -07003878 if (i == st_bp->frp_segs) { /* Should never happen */
3879 printk(KERN_WARNING "st: from_buffer offset overflow.\n");
3880 return (-EIO);
3881 }
3882 for (; i < st_bp->frp_segs && do_count > 0; i++) {
FUJITA Tomonori08c95832008-12-18 14:49:45 +09003883 struct page *page = st_bp->reserved_pages[i];
3884 cnt = length - offset < do_count ? length - offset : do_count;
3885 res = copy_to_user(ubp, page_address(page) + offset, cnt);
Linus Torvalds1da177e2005-04-16 15:20:36 -07003886 if (res)
3887 return (-EFAULT);
3888 do_count -= cnt;
3889 st_bp->buffer_bytes -= cnt;
3890 st_bp->read_pointer += cnt;
3891 ubp += cnt;
3892 offset = 0;
3893 }
3894 if (do_count) /* Should never happen */
3895 return (-EIO);
3896
3897 return 0;
3898}
3899
3900
3901/* Move data towards start of buffer */
3902static void move_buffer_data(struct st_buffer * st_bp, int offset)
3903{
3904 int src_seg, dst_seg, src_offset = 0, dst_offset;
3905 int count, total;
FUJITA Tomonoric982c362009-11-26 09:24:13 +09003906 int length = PAGE_SIZE << st_bp->reserved_page_order;
Linus Torvalds1da177e2005-04-16 15:20:36 -07003907
3908 if (offset == 0)
3909 return;
3910
3911 total=st_bp->buffer_bytes - offset;
3912 for (src_seg=0; src_seg < st_bp->frp_segs; src_seg++) {
3913 src_offset = offset;
FUJITA Tomonori08c95832008-12-18 14:49:45 +09003914 if (src_offset < length)
Linus Torvalds1da177e2005-04-16 15:20:36 -07003915 break;
FUJITA Tomonori08c95832008-12-18 14:49:45 +09003916 offset -= length;
Linus Torvalds1da177e2005-04-16 15:20:36 -07003917 }
3918
3919 st_bp->buffer_bytes = st_bp->read_pointer = total;
3920 for (dst_seg=dst_offset=0; total > 0; ) {
FUJITA Tomonori08c95832008-12-18 14:49:45 +09003921 struct page *dpage = st_bp->reserved_pages[dst_seg];
3922 struct page *spage = st_bp->reserved_pages[src_seg];
3923
3924 count = min(length - dst_offset, length - src_offset);
3925 memmove(page_address(dpage) + dst_offset,
3926 page_address(spage) + src_offset, count);
Linus Torvalds1da177e2005-04-16 15:20:36 -07003927 src_offset += count;
FUJITA Tomonori08c95832008-12-18 14:49:45 +09003928 if (src_offset >= length) {
Linus Torvalds1da177e2005-04-16 15:20:36 -07003929 src_seg++;
3930 src_offset = 0;
3931 }
3932 dst_offset += count;
FUJITA Tomonori08c95832008-12-18 14:49:45 +09003933 if (dst_offset >= length) {
Linus Torvalds1da177e2005-04-16 15:20:36 -07003934 dst_seg++;
3935 dst_offset = 0;
3936 }
3937 total -= count;
3938 }
3939}
3940
Linus Torvalds1da177e2005-04-16 15:20:36 -07003941/* Validate the options from command line or module parameters */
3942static void validate_options(void)
3943{
3944 if (buffer_kbs > 0)
3945 st_fixed_buffer_size = buffer_kbs * ST_KILOBYTE;
3946 if (max_sg_segs >= ST_FIRST_SG)
3947 st_max_sg_segs = max_sg_segs;
3948}
3949
3950#ifndef MODULE
3951/* Set the boot options. Syntax is defined in Documenation/scsi/st.txt.
3952 */
3953static int __init st_setup(char *str)
3954{
3955 int i, len, ints[5];
3956 char *stp;
3957
3958 stp = get_options(str, ARRAY_SIZE(ints), ints);
3959
3960 if (ints[0] > 0) {
3961 for (i = 0; i < ints[0] && i < ARRAY_SIZE(parms); i++)
3962 if (parms[i].val)
3963 *parms[i].val = ints[i + 1];
3964 } else {
3965 while (stp != NULL) {
3966 for (i = 0; i < ARRAY_SIZE(parms); i++) {
3967 len = strlen(parms[i].name);
3968 if (!strncmp(stp, parms[i].name, len) &&
3969 (*(stp + len) == ':' || *(stp + len) == '=')) {
3970 if (parms[i].val)
3971 *parms[i].val =
3972 simple_strtoul(stp + len + 1, NULL, 0);
3973 else
3974 printk(KERN_WARNING "st: Obsolete parameter %s\n",
3975 parms[i].name);
3976 break;
3977 }
3978 }
Tobias Klauser6391a112006-06-08 22:23:48 -07003979 if (i >= ARRAY_SIZE(parms))
Linus Torvalds1da177e2005-04-16 15:20:36 -07003980 printk(KERN_WARNING "st: invalid parameter in '%s'\n",
3981 stp);
3982 stp = strchr(stp, ',');
3983 if (stp)
3984 stp++;
3985 }
3986 }
3987
3988 validate_options();
3989
3990 return 1;
3991}
3992
3993__setup("st=", st_setup);
3994
3995#endif
3996
Arjan van de Ven00977a52007-02-12 00:55:34 -08003997static const struct file_operations st_fops =
Linus Torvalds1da177e2005-04-16 15:20:36 -07003998{
3999 .owner = THIS_MODULE,
4000 .read = st_read,
4001 .write = st_write,
Kai Makisarafd66c1b2008-01-17 22:45:22 +02004002 .unlocked_ioctl = st_ioctl,
Linus Torvalds1da177e2005-04-16 15:20:36 -07004003#ifdef CONFIG_COMPAT
4004 .compat_ioctl = st_compat_ioctl,
4005#endif
4006 .open = st_open,
4007 .flush = st_flush,
4008 .release = st_release,
Jan Blunckb4d878e2010-05-26 14:44:51 -07004009 .llseek = noop_llseek,
Linus Torvalds1da177e2005-04-16 15:20:36 -07004010};
4011
Jeff Mahoney26898af2012-08-18 15:20:40 -04004012static int create_one_cdev(struct scsi_tape *tape, int mode, int rew)
4013{
4014 int i, error;
4015 dev_t cdev_devno;
4016 struct cdev *cdev;
4017 struct device *dev;
4018 struct st_modedef *STm = &(tape->modes[mode]);
4019 char name[10];
4020 int dev_num = tape->index;
4021
4022 cdev_devno = MKDEV(SCSI_TAPE_MAJOR, TAPE_MINOR(dev_num, mode, rew));
4023
4024 cdev = cdev_alloc();
4025 if (!cdev) {
4026 pr_err("st%d: out of memory. Device not attached.\n", dev_num);
4027 error = -ENOMEM;
4028 goto out;
4029 }
4030 cdev->owner = THIS_MODULE;
4031 cdev->ops = &st_fops;
4032
4033 error = cdev_add(cdev, cdev_devno, 1);
4034 if (error) {
4035 pr_err("st%d: Can't add %s-rewind mode %d\n", dev_num,
4036 rew ? "non" : "auto", mode);
4037 pr_err("st%d: Device not attached.\n", dev_num);
4038 goto out_free;
4039 }
4040 STm->cdevs[rew] = cdev;
4041
4042 i = mode << (4 - ST_NBR_MODE_BITS);
4043 snprintf(name, 10, "%s%s%s", rew ? "n" : "",
4044 tape->disk->disk_name, st_formats[i]);
4045
4046 dev = device_create(&st_sysfs_class, &tape->device->sdev_gendev,
4047 cdev_devno, &tape->modes[mode], "%s", name);
4048 if (IS_ERR(dev)) {
4049 pr_err("st%d: device_create failed\n", dev_num);
4050 error = PTR_ERR(dev);
4051 goto out_free;
4052 }
4053
4054 STm->devs[rew] = dev;
4055
4056 return 0;
4057out_free:
4058 cdev_del(STm->cdevs[rew]);
4059 STm->cdevs[rew] = NULL;
4060out:
4061 return error;
4062}
4063
4064static int create_cdevs(struct scsi_tape *tape)
4065{
4066 int mode, error;
4067 for (mode = 0; mode < ST_NBR_MODES; ++mode) {
4068 error = create_one_cdev(tape, mode, 0);
4069 if (error)
4070 return error;
4071 error = create_one_cdev(tape, mode, 1);
4072 if (error)
4073 return error;
4074 }
4075
4076 return sysfs_create_link(&tape->device->sdev_gendev.kobj,
4077 &tape->modes[0].devs[0]->kobj, "tape");
4078}
4079
4080static void remove_cdevs(struct scsi_tape *tape)
4081{
4082 int mode, rew;
4083 sysfs_remove_link(&tape->device->sdev_gendev.kobj, "tape");
4084 for (mode = 0; mode < ST_NBR_MODES; mode++) {
4085 struct st_modedef *STm = &(tape->modes[mode]);
4086 for (rew = 0; rew < 2; rew++) {
4087 if (STm->cdevs[rew])
4088 cdev_del(STm->cdevs[rew]);
4089 if (STm->devs[rew])
4090 device_unregister(STm->devs[rew]);
4091 }
4092 }
4093}
4094
Linus Torvalds1da177e2005-04-16 15:20:36 -07004095static int st_probe(struct device *dev)
4096{
4097 struct scsi_device *SDp = to_scsi_device(dev);
4098 struct gendisk *disk = NULL;
Linus Torvalds1da177e2005-04-16 15:20:36 -07004099 struct scsi_tape *tpnt = NULL;
4100 struct st_modedef *STm;
4101 struct st_partstat *STps;
4102 struct st_buffer *buffer;
Tejun Heob98c52b2013-02-27 17:04:42 -08004103 int i, error;
Linus Torvalds1da177e2005-04-16 15:20:36 -07004104 char *stp;
Linus Torvalds1da177e2005-04-16 15:20:36 -07004105
4106 if (SDp->type != TYPE_TAPE)
4107 return -ENODEV;
4108 if ((stp = st_incompatible(SDp))) {
Jeff Garzik3bf743e2005-10-24 18:04:06 -04004109 sdev_printk(KERN_INFO, SDp, "Found incompatible tape\n");
Hannes Reineckeb30d8bc2014-06-25 16:39:57 +02004110 sdev_printk(KERN_INFO, SDp,
4111 "st: The suggested driver is %s.\n", stp);
Linus Torvalds1da177e2005-04-16 15:20:36 -07004112 return -ENODEV;
4113 }
4114
Subhash Jadavani6fe8c1d2014-09-10 14:54:09 +03004115 scsi_autopm_get_device(SDp);
Martin K. Petersen8a783622010-02-26 00:20:39 -05004116 i = queue_max_segments(SDp->request_queue);
Linus Torvalds1da177e2005-04-16 15:20:36 -07004117 if (st_max_sg_segs < i)
4118 i = st_max_sg_segs;
FUJITA Tomonorif409d6c2008-12-18 14:49:47 +09004119 buffer = new_tape_buffer((SDp->host)->unchecked_isa_dma, i);
Linus Torvalds1da177e2005-04-16 15:20:36 -07004120 if (buffer == NULL) {
Hannes Reineckeb30d8bc2014-06-25 16:39:57 +02004121 sdev_printk(KERN_ERR, SDp,
4122 "st: Can't allocate new tape buffer. "
4123 "Device not attached.\n");
Linus Torvalds1da177e2005-04-16 15:20:36 -07004124 goto out;
4125 }
4126
4127 disk = alloc_disk(1);
4128 if (!disk) {
Hannes Reineckeb30d8bc2014-06-25 16:39:57 +02004129 sdev_printk(KERN_ERR, SDp,
4130 "st: out of memory. Device not attached.\n");
Linus Torvalds1da177e2005-04-16 15:20:36 -07004131 goto out_buffer_free;
4132 }
4133
Jes Sorensen24669f752006-01-16 10:31:18 -05004134 tpnt = kzalloc(sizeof(struct scsi_tape), GFP_ATOMIC);
Linus Torvalds1da177e2005-04-16 15:20:36 -07004135 if (tpnt == NULL) {
Hannes Reineckeb30d8bc2014-06-25 16:39:57 +02004136 sdev_printk(KERN_ERR, SDp,
4137 "st: Can't allocate device descriptor.\n");
Linus Torvalds1da177e2005-04-16 15:20:36 -07004138 goto out_put_disk;
4139 }
Kai Makisaraf03a5672005-08-02 13:40:47 +03004140 kref_init(&tpnt->kref);
Linus Torvalds1da177e2005-04-16 15:20:36 -07004141 tpnt->disk = disk;
Linus Torvalds1da177e2005-04-16 15:20:36 -07004142 disk->private_data = &tpnt->driver;
4143 disk->queue = SDp->request_queue;
Joe Lawrence2b5bebc2013-03-05 10:57:56 -05004144 /* SCSI tape doesn't register this gendisk via add_disk(). Manually
4145 * take queue reference that release_disk() expects. */
4146 if (!blk_get_queue(disk->queue))
4147 goto out_put_disk;
Linus Torvalds1da177e2005-04-16 15:20:36 -07004148 tpnt->driver = &st_template;
Linus Torvalds1da177e2005-04-16 15:20:36 -07004149
4150 tpnt->device = SDp;
4151 if (SDp->scsi_level <= 2)
4152 tpnt->tape_type = MT_ISSCSI1;
4153 else
4154 tpnt->tape_type = MT_ISSCSI2;
4155
4156 tpnt->buffer = buffer;
Kai Makisaraf03a5672005-08-02 13:40:47 +03004157 tpnt->buffer->last_SRpnt = NULL;
Linus Torvalds1da177e2005-04-16 15:20:36 -07004158
4159 tpnt->inited = 0;
4160 tpnt->dirty = 0;
4161 tpnt->in_use = 0;
4162 tpnt->drv_buffer = 1; /* Try buffering if no mode sense */
4163 tpnt->restr_dma = (SDp->host)->unchecked_isa_dma;
4164 tpnt->use_pf = (SDp->scsi_level >= SCSI_2);
4165 tpnt->density = 0;
4166 tpnt->do_auto_lock = ST_AUTO_LOCK;
4167 tpnt->can_bsr = (SDp->scsi_level > 2 ? 1 : ST_IN_FILE_POS); /* BSR mandatory in SCSI3 */
4168 tpnt->can_partitions = 0;
4169 tpnt->two_fm = ST_TWO_FM;
4170 tpnt->fast_mteom = ST_FAST_MTEOM;
4171 tpnt->scsi2_logical = ST_SCSI2LOGICAL;
Kai Makisara40f6b362008-02-24 22:23:24 +02004172 tpnt->sili = ST_SILI;
Linus Torvalds1da177e2005-04-16 15:20:36 -07004173 tpnt->immediate = ST_NOWAIT;
Lee Duncanc743e442012-03-01 12:41:01 -08004174 tpnt->immediate_filemark = 0;
Linus Torvalds1da177e2005-04-16 15:20:36 -07004175 tpnt->default_drvbuffer = 0xff; /* No forced buffering */
4176 tpnt->partition = 0;
4177 tpnt->new_partition = 0;
4178 tpnt->nbr_partitions = 0;
James Bottomleya02488e2008-11-30 10:36:26 -06004179 blk_queue_rq_timeout(tpnt->device->request_queue, ST_TIMEOUT);
Linus Torvalds1da177e2005-04-16 15:20:36 -07004180 tpnt->long_timeout = ST_LONG_TIMEOUT;
4181 tpnt->try_dio = try_direct_io && !SDp->host->unchecked_isa_dma;
4182
Linus Torvalds1da177e2005-04-16 15:20:36 -07004183 for (i = 0; i < ST_NBR_MODES; i++) {
4184 STm = &(tpnt->modes[i]);
4185 STm->defined = 0;
4186 STm->sysv = ST_SYSV;
4187 STm->defaults_for_writes = 0;
4188 STm->do_async_writes = ST_ASYNC_WRITES;
4189 STm->do_buffer_writes = ST_BUFFER_WRITES;
4190 STm->do_read_ahead = ST_READ_AHEAD;
4191 STm->default_compression = ST_DONT_TOUCH;
4192 STm->default_blksize = (-1); /* No forced size */
4193 STm->default_density = (-1); /* No forced density */
Jeff Mahoney6c648d92012-08-18 15:20:39 -04004194 STm->tape = tpnt;
Linus Torvalds1da177e2005-04-16 15:20:36 -07004195 }
4196
4197 for (i = 0; i < ST_NBR_PARTITIONS; i++) {
4198 STps = &(tpnt->ps[i]);
4199 STps->rw = ST_IDLE;
4200 STps->eof = ST_NOEOF;
4201 STps->at_sm = 0;
4202 STps->last_block_valid = 0;
4203 STps->drv_block = (-1);
4204 STps->drv_file = (-1);
4205 }
4206
4207 tpnt->current_mode = 0;
4208 tpnt->modes[0].defined = 1;
4209
4210 tpnt->density_changed = tpnt->compression_changed =
4211 tpnt->blksize_changed = 0;
Matthias Kaehlcke28f85002007-07-29 23:38:15 +02004212 mutex_init(&tpnt->lock);
Linus Torvalds1da177e2005-04-16 15:20:36 -07004213
Tejun Heob98c52b2013-02-27 17:04:42 -08004214 idr_preload(GFP_KERNEL);
Jeff Mahoney6c648d92012-08-18 15:20:39 -04004215 spin_lock(&st_index_lock);
Tejun Heob98c52b2013-02-27 17:04:42 -08004216 error = idr_alloc(&st_index_idr, tpnt, 0, ST_MAX_TAPES + 1, GFP_NOWAIT);
Jeff Mahoney6c648d92012-08-18 15:20:39 -04004217 spin_unlock(&st_index_lock);
Tejun Heob98c52b2013-02-27 17:04:42 -08004218 idr_preload_end();
4219 if (error < 0) {
Jeff Mahoney6c648d92012-08-18 15:20:39 -04004220 pr_warn("st: idr allocation failed: %d\n", error);
Joe Lawrence2b5bebc2013-03-05 10:57:56 -05004221 goto out_put_queue;
Jeff Mahoney6c648d92012-08-18 15:20:39 -04004222 }
Tejun Heob98c52b2013-02-27 17:04:42 -08004223 tpnt->index = error;
4224 sprintf(disk->disk_name, "st%d", tpnt->index);
Jeff Mahoney6c648d92012-08-18 15:20:39 -04004225
4226 dev_set_drvdata(dev, tpnt);
Linus Torvalds1da177e2005-04-16 15:20:36 -07004227
Linus Torvalds1da177e2005-04-16 15:20:36 -07004228
Jeff Mahoney26898af2012-08-18 15:20:40 -04004229 error = create_cdevs(tpnt);
4230 if (error)
4231 goto out_remove_devs;
Oliver Neukum46a243f2012-01-15 00:16:51 +01004232 scsi_autopm_put_device(SDp);
Linus Torvalds1da177e2005-04-16 15:20:36 -07004233
Kai Makisara42252852006-11-07 21:56:38 +02004234 sdev_printk(KERN_NOTICE, SDp,
Rene Herman8b1ea242006-05-20 15:00:22 -07004235 "Attached scsi tape %s\n", tape_name(tpnt));
Kai Makisara42252852006-11-07 21:56:38 +02004236 sdev_printk(KERN_INFO, SDp, "%s: try direct i/o: %s (alignment %d B)\n",
4237 tape_name(tpnt), tpnt->try_dio ? "yes" : "no",
4238 queue_dma_alignment(SDp->request_queue) + 1);
Linus Torvalds1da177e2005-04-16 15:20:36 -07004239
4240 return 0;
4241
Jeff Mahoney26898af2012-08-18 15:20:40 -04004242out_remove_devs:
4243 remove_cdevs(tpnt);
Jeff Mahoney6c648d92012-08-18 15:20:39 -04004244 spin_lock(&st_index_lock);
Tejun Heob98c52b2013-02-27 17:04:42 -08004245 idr_remove(&st_index_idr, tpnt->index);
Jeff Mahoney6c648d92012-08-18 15:20:39 -04004246 spin_unlock(&st_index_lock);
Joe Lawrence2b5bebc2013-03-05 10:57:56 -05004247out_put_queue:
4248 blk_put_queue(disk->queue);
Linus Torvalds1da177e2005-04-16 15:20:36 -07004249out_put_disk:
4250 put_disk(disk);
Jesper Juhlc9475cb2005-11-07 01:01:26 -08004251 kfree(tpnt);
Linus Torvalds1da177e2005-04-16 15:20:36 -07004252out_buffer_free:
4253 kfree(buffer);
4254out:
Subhash Jadavani6fe8c1d2014-09-10 14:54:09 +03004255 scsi_autopm_put_device(SDp);
Linus Torvalds1da177e2005-04-16 15:20:36 -07004256 return -ENODEV;
4257};
4258
4259
4260static int st_remove(struct device *dev)
4261{
Jeff Mahoney6c648d92012-08-18 15:20:39 -04004262 struct scsi_tape *tpnt = dev_get_drvdata(dev);
Jeff Mahoney6c648d92012-08-18 15:20:39 -04004263 int index = tpnt->index;
Linus Torvalds1da177e2005-04-16 15:20:36 -07004264
Jeff Mahoney6c648d92012-08-18 15:20:39 -04004265 scsi_autopm_get_device(to_scsi_device(dev));
Jeff Mahoney26898af2012-08-18 15:20:40 -04004266 remove_cdevs(tpnt);
Linus Torvalds1da177e2005-04-16 15:20:36 -07004267
Jeff Mahoney6c648d92012-08-18 15:20:39 -04004268 mutex_lock(&st_ref_mutex);
4269 kref_put(&tpnt->kref, scsi_tape_release);
4270 mutex_unlock(&st_ref_mutex);
4271 spin_lock(&st_index_lock);
4272 idr_remove(&st_index_idr, index);
4273 spin_unlock(&st_index_lock);
Linus Torvalds1da177e2005-04-16 15:20:36 -07004274 return 0;
4275}
4276
Kai Makisaraf03a5672005-08-02 13:40:47 +03004277/**
4278 * scsi_tape_release - Called to free the Scsi_Tape structure
4279 * @kref: pointer to embedded kref
4280 *
Arjan van de Ven0b950672006-01-11 13:16:10 +01004281 * st_ref_mutex must be held entering this routine. Because it is
Kai Makisaraf03a5672005-08-02 13:40:47 +03004282 * called on last put, you should always use the scsi_tape_get()
4283 * scsi_tape_put() helpers which manipulate the semaphore directly
4284 * and never do a direct kref_put().
4285 **/
4286static void scsi_tape_release(struct kref *kref)
4287{
4288 struct scsi_tape *tpnt = to_scsi_tape(kref);
4289 struct gendisk *disk = tpnt->disk;
4290
4291 tpnt->device = NULL;
4292
4293 if (tpnt->buffer) {
Kai Makisaraf03a5672005-08-02 13:40:47 +03004294 normalize_buffer(tpnt->buffer);
FUJITA Tomonorid0e1ae32008-12-18 14:49:40 +09004295 kfree(tpnt->buffer->reserved_pages);
Kai Makisaraf03a5672005-08-02 13:40:47 +03004296 kfree(tpnt->buffer);
4297 }
4298
4299 disk->private_data = NULL;
4300 put_disk(disk);
4301 kfree(tpnt);
4302 return;
4303}
4304
Jeff Mahoneyaf237822012-08-18 15:20:37 -04004305static struct class st_sysfs_class = {
4306 .name = "scsi_tape",
Greg Kroah-Hartmanc69c6be2013-07-24 15:05:29 -07004307 .dev_groups = st_dev_groups,
Jeff Mahoneyaf237822012-08-18 15:20:37 -04004308};
4309
Linus Torvalds1da177e2005-04-16 15:20:36 -07004310static int __init init_st(void)
4311{
Jeff Garzik13026a62006-10-04 06:00:38 -04004312 int err;
4313
Linus Torvalds1da177e2005-04-16 15:20:36 -07004314 validate_options();
4315
Jeff Garzik13026a62006-10-04 06:00:38 -04004316 printk(KERN_INFO "st: Version %s, fixed bufsize %d, s/g segs %d\n",
Linus Torvalds1da177e2005-04-16 15:20:36 -07004317 verstr, st_fixed_buffer_size, st_max_sg_segs);
4318
Laurence Oberman2bec7082014-10-19 09:44:25 -04004319 debugging = (debug_flag > 0) ? debug_flag : NO_DEBUG;
4320 if (debugging) {
4321 printk(KERN_INFO "st: Debugging enabled debug_flag = %d\n",
4322 debugging);
4323 }
4324
Jeff Mahoneyaf237822012-08-18 15:20:37 -04004325 err = class_register(&st_sysfs_class);
4326 if (err) {
4327 pr_err("Unable register sysfs class for SCSI tapes\n");
4328 return err;
Linus Torvalds1da177e2005-04-16 15:20:36 -07004329 }
4330
Jeff Garzik13026a62006-10-04 06:00:38 -04004331 err = register_chrdev_region(MKDEV(SCSI_TAPE_MAJOR, 0),
4332 ST_MAX_TAPE_ENTRIES, "st");
4333 if (err) {
4334 printk(KERN_ERR "Unable to get major %d for SCSI tapes\n",
4335 SCSI_TAPE_MAJOR);
4336 goto err_class;
Linus Torvalds1da177e2005-04-16 15:20:36 -07004337 }
Jeff Garzik13026a62006-10-04 06:00:38 -04004338
4339 err = scsi_register_driver(&st_template.gendrv);
4340 if (err)
4341 goto err_chrdev;
4342
Robert P. J. Day405ae7d2007-02-17 19:13:42 +01004343 err = do_create_sysfs_files();
Jeff Garzik13026a62006-10-04 06:00:38 -04004344 if (err)
4345 goto err_scsidrv;
4346
4347 return 0;
4348
4349err_scsidrv:
4350 scsi_unregister_driver(&st_template.gendrv);
4351err_chrdev:
4352 unregister_chrdev_region(MKDEV(SCSI_TAPE_MAJOR, 0),
4353 ST_MAX_TAPE_ENTRIES);
4354err_class:
Jeff Mahoneyaf237822012-08-18 15:20:37 -04004355 class_unregister(&st_sysfs_class);
Jeff Garzik13026a62006-10-04 06:00:38 -04004356 return err;
Linus Torvalds1da177e2005-04-16 15:20:36 -07004357}
4358
4359static void __exit exit_st(void)
4360{
Robert P. J. Day405ae7d2007-02-17 19:13:42 +01004361 do_remove_sysfs_files();
Linus Torvalds1da177e2005-04-16 15:20:36 -07004362 scsi_unregister_driver(&st_template.gendrv);
4363 unregister_chrdev_region(MKDEV(SCSI_TAPE_MAJOR, 0),
4364 ST_MAX_TAPE_ENTRIES);
Jeff Mahoneyaf237822012-08-18 15:20:37 -04004365 class_unregister(&st_sysfs_class);
Linus Torvalds1da177e2005-04-16 15:20:36 -07004366 printk(KERN_INFO "st: Unloaded.\n");
4367}
4368
4369module_init(init_st);
4370module_exit(exit_st);
4371
4372
4373/* The sysfs driver interface. Read-only at the moment */
4374static ssize_t st_try_direct_io_show(struct device_driver *ddp, char *buf)
4375{
4376 return snprintf(buf, PAGE_SIZE, "%d\n", try_direct_io);
4377}
4378static DRIVER_ATTR(try_direct_io, S_IRUGO, st_try_direct_io_show, NULL);
4379
4380static ssize_t st_fixed_buffer_size_show(struct device_driver *ddp, char *buf)
4381{
4382 return snprintf(buf, PAGE_SIZE, "%d\n", st_fixed_buffer_size);
4383}
4384static DRIVER_ATTR(fixed_buffer_size, S_IRUGO, st_fixed_buffer_size_show, NULL);
4385
4386static ssize_t st_max_sg_segs_show(struct device_driver *ddp, char *buf)
4387{
4388 return snprintf(buf, PAGE_SIZE, "%d\n", st_max_sg_segs);
4389}
4390static DRIVER_ATTR(max_sg_segs, S_IRUGO, st_max_sg_segs_show, NULL);
4391
4392static ssize_t st_version_show(struct device_driver *ddd, char *buf)
4393{
4394 return snprintf(buf, PAGE_SIZE, "[%s]\n", verstr);
4395}
4396static DRIVER_ATTR(version, S_IRUGO, st_version_show, NULL);
4397
Robert P. J. Day405ae7d2007-02-17 19:13:42 +01004398static int do_create_sysfs_files(void)
Linus Torvalds1da177e2005-04-16 15:20:36 -07004399{
Robert P. J. Day405ae7d2007-02-17 19:13:42 +01004400 struct device_driver *sysfs = &st_template.gendrv;
Jeff Garzik13026a62006-10-04 06:00:38 -04004401 int err;
Linus Torvalds1da177e2005-04-16 15:20:36 -07004402
Robert P. J. Day405ae7d2007-02-17 19:13:42 +01004403 err = driver_create_file(sysfs, &driver_attr_try_direct_io);
Jeff Garzik13026a62006-10-04 06:00:38 -04004404 if (err)
4405 return err;
Robert P. J. Day405ae7d2007-02-17 19:13:42 +01004406 err = driver_create_file(sysfs, &driver_attr_fixed_buffer_size);
Jeff Garzik13026a62006-10-04 06:00:38 -04004407 if (err)
4408 goto err_try_direct_io;
Robert P. J. Day405ae7d2007-02-17 19:13:42 +01004409 err = driver_create_file(sysfs, &driver_attr_max_sg_segs);
Jeff Garzik13026a62006-10-04 06:00:38 -04004410 if (err)
4411 goto err_attr_fixed_buf;
Robert P. J. Day405ae7d2007-02-17 19:13:42 +01004412 err = driver_create_file(sysfs, &driver_attr_version);
Jeff Garzik13026a62006-10-04 06:00:38 -04004413 if (err)
4414 goto err_attr_max_sg;
4415
4416 return 0;
4417
4418err_attr_max_sg:
Robert P. J. Day405ae7d2007-02-17 19:13:42 +01004419 driver_remove_file(sysfs, &driver_attr_max_sg_segs);
Jeff Garzik13026a62006-10-04 06:00:38 -04004420err_attr_fixed_buf:
Robert P. J. Day405ae7d2007-02-17 19:13:42 +01004421 driver_remove_file(sysfs, &driver_attr_fixed_buffer_size);
Jeff Garzik13026a62006-10-04 06:00:38 -04004422err_try_direct_io:
Robert P. J. Day405ae7d2007-02-17 19:13:42 +01004423 driver_remove_file(sysfs, &driver_attr_try_direct_io);
Jeff Garzik13026a62006-10-04 06:00:38 -04004424 return err;
Linus Torvalds1da177e2005-04-16 15:20:36 -07004425}
4426
Robert P. J. Day405ae7d2007-02-17 19:13:42 +01004427static void do_remove_sysfs_files(void)
Linus Torvalds1da177e2005-04-16 15:20:36 -07004428{
Robert P. J. Day405ae7d2007-02-17 19:13:42 +01004429 struct device_driver *sysfs = &st_template.gendrv;
Linus Torvalds1da177e2005-04-16 15:20:36 -07004430
Robert P. J. Day405ae7d2007-02-17 19:13:42 +01004431 driver_remove_file(sysfs, &driver_attr_version);
4432 driver_remove_file(sysfs, &driver_attr_max_sg_segs);
4433 driver_remove_file(sysfs, &driver_attr_fixed_buffer_size);
4434 driver_remove_file(sysfs, &driver_attr_try_direct_io);
Linus Torvalds1da177e2005-04-16 15:20:36 -07004435}
4436
Linus Torvalds1da177e2005-04-16 15:20:36 -07004437/* The sysfs simple class interface */
Tony Jonesee959b02008-02-22 00:13:36 +01004438static ssize_t
Jeff Mahoneyaf237822012-08-18 15:20:37 -04004439defined_show(struct device *dev, struct device_attribute *attr, char *buf)
Linus Torvalds1da177e2005-04-16 15:20:36 -07004440{
James Bottomley7d15d6a2008-03-14 14:12:43 -07004441 struct st_modedef *STm = dev_get_drvdata(dev);
Linus Torvalds1da177e2005-04-16 15:20:36 -07004442 ssize_t l = 0;
4443
4444 l = snprintf(buf, PAGE_SIZE, "%d\n", STm->defined);
4445 return l;
4446}
Greg Kroah-Hartmanc69c6be2013-07-24 15:05:29 -07004447static DEVICE_ATTR_RO(defined);
Linus Torvalds1da177e2005-04-16 15:20:36 -07004448
Tony Jonesee959b02008-02-22 00:13:36 +01004449static ssize_t
Jeff Mahoneyaf237822012-08-18 15:20:37 -04004450default_blksize_show(struct device *dev, struct device_attribute *attr,
4451 char *buf)
Linus Torvalds1da177e2005-04-16 15:20:36 -07004452{
James Bottomley7d15d6a2008-03-14 14:12:43 -07004453 struct st_modedef *STm = dev_get_drvdata(dev);
Linus Torvalds1da177e2005-04-16 15:20:36 -07004454 ssize_t l = 0;
4455
4456 l = snprintf(buf, PAGE_SIZE, "%d\n", STm->default_blksize);
4457 return l;
4458}
Greg Kroah-Hartmanc69c6be2013-07-24 15:05:29 -07004459static DEVICE_ATTR_RO(default_blksize);
Linus Torvalds1da177e2005-04-16 15:20:36 -07004460
Tony Jonesee959b02008-02-22 00:13:36 +01004461static ssize_t
Jeff Mahoneyaf237822012-08-18 15:20:37 -04004462default_density_show(struct device *dev, struct device_attribute *attr,
4463 char *buf)
Linus Torvalds1da177e2005-04-16 15:20:36 -07004464{
James Bottomley7d15d6a2008-03-14 14:12:43 -07004465 struct st_modedef *STm = dev_get_drvdata(dev);
Linus Torvalds1da177e2005-04-16 15:20:36 -07004466 ssize_t l = 0;
4467 char *fmt;
4468
4469 fmt = STm->default_density >= 0 ? "0x%02x\n" : "%d\n";
4470 l = snprintf(buf, PAGE_SIZE, fmt, STm->default_density);
4471 return l;
4472}
Greg Kroah-Hartmanc69c6be2013-07-24 15:05:29 -07004473static DEVICE_ATTR_RO(default_density);
Linus Torvalds1da177e2005-04-16 15:20:36 -07004474
Tony Jonesee959b02008-02-22 00:13:36 +01004475static ssize_t
Jeff Mahoneyaf237822012-08-18 15:20:37 -04004476default_compression_show(struct device *dev, struct device_attribute *attr,
4477 char *buf)
Linus Torvalds1da177e2005-04-16 15:20:36 -07004478{
James Bottomley7d15d6a2008-03-14 14:12:43 -07004479 struct st_modedef *STm = dev_get_drvdata(dev);
Linus Torvalds1da177e2005-04-16 15:20:36 -07004480 ssize_t l = 0;
4481
4482 l = snprintf(buf, PAGE_SIZE, "%d\n", STm->default_compression - 1);
4483 return l;
4484}
Greg Kroah-Hartmanc69c6be2013-07-24 15:05:29 -07004485static DEVICE_ATTR_RO(default_compression);
Linus Torvalds1da177e2005-04-16 15:20:36 -07004486
Tony Jonesee959b02008-02-22 00:13:36 +01004487static ssize_t
Jeff Mahoneyaf237822012-08-18 15:20:37 -04004488options_show(struct device *dev, struct device_attribute *attr, char *buf)
Kai Makisarab174be02008-02-24 22:29:12 +02004489{
James Bottomley7d15d6a2008-03-14 14:12:43 -07004490 struct st_modedef *STm = dev_get_drvdata(dev);
Jeff Mahoney6c648d92012-08-18 15:20:39 -04004491 struct scsi_tape *STp = STm->tape;
4492 int options;
Kai Makisarab174be02008-02-24 22:29:12 +02004493 ssize_t l = 0;
4494
Kai Makisarab174be02008-02-24 22:29:12 +02004495 options = STm->do_buffer_writes ? MT_ST_BUFFER_WRITES : 0;
4496 options |= STm->do_async_writes ? MT_ST_ASYNC_WRITES : 0;
4497 options |= STm->do_read_ahead ? MT_ST_READ_AHEAD : 0;
4498 DEB( options |= debugging ? MT_ST_DEBUGGING : 0 );
4499 options |= STp->two_fm ? MT_ST_TWO_FM : 0;
4500 options |= STp->fast_mteom ? MT_ST_FAST_MTEOM : 0;
4501 options |= STm->defaults_for_writes ? MT_ST_DEF_WRITES : 0;
4502 options |= STp->can_bsr ? MT_ST_CAN_BSR : 0;
4503 options |= STp->omit_blklims ? MT_ST_NO_BLKLIMS : 0;
4504 options |= STp->can_partitions ? MT_ST_CAN_PARTITIONS : 0;
4505 options |= STp->scsi2_logical ? MT_ST_SCSI2LOGICAL : 0;
4506 options |= STm->sysv ? MT_ST_SYSV : 0;
4507 options |= STp->immediate ? MT_ST_NOWAIT : 0;
Lee Duncanc743e442012-03-01 12:41:01 -08004508 options |= STp->immediate_filemark ? MT_ST_NOWAIT_EOF : 0;
Kai Makisarab174be02008-02-24 22:29:12 +02004509 options |= STp->sili ? MT_ST_SILI : 0;
4510
4511 l = snprintf(buf, PAGE_SIZE, "0x%08x\n", options);
4512 return l;
4513}
Greg Kroah-Hartmanc69c6be2013-07-24 15:05:29 -07004514static DEVICE_ATTR_RO(options);
Kai Makisarab174be02008-02-24 22:29:12 +02004515
Greg Kroah-Hartmanc69c6be2013-07-24 15:05:29 -07004516static struct attribute *st_dev_attrs[] = {
4517 &dev_attr_defined.attr,
4518 &dev_attr_default_blksize.attr,
4519 &dev_attr_default_density.attr,
4520 &dev_attr_default_compression.attr,
4521 &dev_attr_options.attr,
4522 NULL,
Jeff Mahoneyaf237822012-08-18 15:20:37 -04004523};
Greg Kroah-Hartmanc69c6be2013-07-24 15:05:29 -07004524ATTRIBUTE_GROUPS(st_dev);
Kai Makisarab174be02008-02-24 22:29:12 +02004525
Linus Torvalds1da177e2005-04-16 15:20:36 -07004526/* The following functions may be useful for a larger audience. */
FUJITA Tomonori66207422008-12-18 14:49:43 +09004527static int sgl_map_user_pages(struct st_buffer *STbp,
4528 const unsigned int max_pages, unsigned long uaddr,
4529 size_t count, int rw)
Linus Torvalds1da177e2005-04-16 15:20:36 -07004530{
James Bottomley07542b82005-08-31 20:27:22 -04004531 unsigned long end = (uaddr + count + PAGE_SIZE - 1) >> PAGE_SHIFT;
4532 unsigned long start = uaddr >> PAGE_SHIFT;
4533 const int nr_pages = end - start;
Linus Torvalds1da177e2005-04-16 15:20:36 -07004534 int res, i, j;
Linus Torvalds1da177e2005-04-16 15:20:36 -07004535 struct page **pages;
FUJITA Tomonori66207422008-12-18 14:49:43 +09004536 struct rq_map_data *mdata = &STbp->map_data;
Linus Torvalds1da177e2005-04-16 15:20:36 -07004537
Linus Torvalds1da177e2005-04-16 15:20:36 -07004538 /* User attempted Overflow! */
4539 if ((uaddr + count) < uaddr)
4540 return -EINVAL;
4541
4542 /* Too big */
4543 if (nr_pages > max_pages)
4544 return -ENOMEM;
4545
4546 /* Hmm? */
4547 if (count == 0)
4548 return 0;
4549
4550 if ((pages = kmalloc(max_pages * sizeof(*pages), GFP_KERNEL)) == NULL)
4551 return -ENOMEM;
4552
4553 /* Try to fault in all of the necessary pages */
4554 down_read(&current->mm->mmap_sem);
4555 /* rw==READ means read from drive, write into memory area */
4556 res = get_user_pages(
4557 current,
4558 current->mm,
4559 uaddr,
4560 nr_pages,
4561 rw == READ,
4562 0, /* don't force */
4563 pages,
4564 NULL);
4565 up_read(&current->mm->mmap_sem);
4566
4567 /* Errors and no page mapped should return here */
4568 if (res < nr_pages)
4569 goto out_unmap;
4570
4571 for (i=0; i < nr_pages; i++) {
4572 /* FIXME: flush superflous for rw==READ,
4573 * probably wrong function for rw==WRITE
4574 */
4575 flush_dcache_page(pages[i]);
4576 }
4577
FUJITA Tomonori66207422008-12-18 14:49:43 +09004578 mdata->offset = uaddr & ~PAGE_MASK;
FUJITA Tomonori66207422008-12-18 14:49:43 +09004579 STbp->mapped_pages = pages;
Linus Torvalds1da177e2005-04-16 15:20:36 -07004580
Linus Torvalds1da177e2005-04-16 15:20:36 -07004581 return nr_pages;
Linus Torvalds1da177e2005-04-16 15:20:36 -07004582 out_unmap:
4583 if (res > 0) {
4584 for (j=0; j < res; j++)
4585 page_cache_release(pages[j]);
Hugh Dickins6bc733e2005-12-01 20:21:57 +00004586 res = 0;
Linus Torvalds1da177e2005-04-16 15:20:36 -07004587 }
4588 kfree(pages);
4589 return res;
4590}
4591
4592
4593/* And unmap them... */
FUJITA Tomonori66207422008-12-18 14:49:43 +09004594static int sgl_unmap_user_pages(struct st_buffer *STbp,
4595 const unsigned int nr_pages, int dirtied)
Linus Torvalds1da177e2005-04-16 15:20:36 -07004596{
4597 int i;
4598
4599 for (i=0; i < nr_pages; i++) {
FUJITA Tomonori66207422008-12-18 14:49:43 +09004600 struct page *page = STbp->mapped_pages[i];
Nick Pigginb5810032005-10-29 18:16:12 -07004601
Nick Pigginb5810032005-10-29 18:16:12 -07004602 if (dirtied)
4603 SetPageDirty(page);
Linus Torvalds1da177e2005-04-16 15:20:36 -07004604 /* FIXME: cache flush missing for rw==READ
4605 * FIXME: call the correct reference counting function
4606 */
Nick Pigginb5810032005-10-29 18:16:12 -07004607 page_cache_release(page);
Linus Torvalds1da177e2005-04-16 15:20:36 -07004608 }
FUJITA Tomonori66207422008-12-18 14:49:43 +09004609 kfree(STbp->mapped_pages);
4610 STbp->mapped_pages = NULL;
Linus Torvalds1da177e2005-04-16 15:20:36 -07004611
4612 return 0;
4613}