blob: 7d2e036c75c17581101e2254740a5d814a6b0a2c [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 Tokarevd7b8bcb02006-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)
Hannes Reinecked811b842014-10-24 14:26:45 +0200384 __scsi_print_sense(STp->device, name,
385 SRpnt->sense, SCSI_SENSE_BUFFERSIZE);
Linus Torvalds1da177e2005-04-16 15:20:36 -0700386 } ) /* end DEB */
387 if (!debugging) { /* Abnormal conditions for tape */
388 if (!cmdstatp->have_sense)
Hannes Reineckeb30d8bc2014-06-25 16:39:57 +0200389 st_printk(KERN_WARNING, STp,
390 "Error %x (driver bt 0x%x, host bt 0x%x).\n",
391 result, driver_byte(result), host_byte(result));
Linus Torvalds1da177e2005-04-16 15:20:36 -0700392 else if (cmdstatp->have_sense &&
393 scode != NO_SENSE &&
394 scode != RECOVERED_ERROR &&
395 /* scode != UNIT_ATTENTION && */
396 scode != BLANK_CHECK &&
397 scode != VOLUME_OVERFLOW &&
Mike Christie8b05b772005-11-08 04:06:44 -0600398 SRpnt->cmd[0] != MODE_SENSE &&
399 SRpnt->cmd[0] != TEST_UNIT_READY) {
Luben Tuikov4e73ea72006-07-07 00:02:18 -0700400
Hannes Reinecked811b842014-10-24 14:26:45 +0200401 __scsi_print_sense(STp->device, name,
402 SRpnt->sense, SCSI_SENSE_BUFFERSIZE);
Linus Torvalds1da177e2005-04-16 15:20:36 -0700403 }
404 }
405
406 if (cmdstatp->fixed_format &&
407 STp->cln_mode >= EXTENDED_SENSE_START) { /* Only fixed format sense */
408 if (STp->cln_sense_value)
Mike Christie8b05b772005-11-08 04:06:44 -0600409 STp->cleaning_req |= ((SRpnt->sense[STp->cln_mode] &
Linus Torvalds1da177e2005-04-16 15:20:36 -0700410 STp->cln_sense_mask) == STp->cln_sense_value);
411 else
Mike Christie8b05b772005-11-08 04:06:44 -0600412 STp->cleaning_req |= ((SRpnt->sense[STp->cln_mode] &
Linus Torvalds1da177e2005-04-16 15:20:36 -0700413 STp->cln_sense_mask) != 0);
414 }
415 if (cmdstatp->have_sense &&
416 cmdstatp->sense_hdr.asc == 0 && cmdstatp->sense_hdr.ascq == 0x17)
417 STp->cleaning_req = 1; /* ASC and ASCQ => cleaning requested */
418
419 STp->pos_unknown |= STp->device->was_reset;
420
421 if (cmdstatp->have_sense &&
422 scode == RECOVERED_ERROR
423#if ST_RECOVERED_WRITE_FATAL
Mike Christie8b05b772005-11-08 04:06:44 -0600424 && SRpnt->cmd[0] != WRITE_6
425 && SRpnt->cmd[0] != WRITE_FILEMARKS
Linus Torvalds1da177e2005-04-16 15:20:36 -0700426#endif
427 ) {
428 STp->recover_count++;
429 STp->recover_reg++;
430
Hannes Reineckeb30d8bc2014-06-25 16:39:57 +0200431 DEB(
Linus Torvalds1da177e2005-04-16 15:20:36 -0700432 if (debugging) {
Mike Christie8b05b772005-11-08 04:06:44 -0600433 if (SRpnt->cmd[0] == READ_6)
Linus Torvalds1da177e2005-04-16 15:20:36 -0700434 stp = "read";
Mike Christie8b05b772005-11-08 04:06:44 -0600435 else if (SRpnt->cmd[0] == WRITE_6)
Linus Torvalds1da177e2005-04-16 15:20:36 -0700436 stp = "write";
437 else
438 stp = "ioctl";
Hannes Reineckeb30d8bc2014-06-25 16:39:57 +0200439 st_printk(ST_DEB_MSG, STp,
440 "Recovered %s error (%d).\n",
441 stp, STp->recover_count);
Linus Torvalds1da177e2005-04-16 15:20:36 -0700442 } ) /* end DEB */
443
444 if (cmdstatp->flags == 0)
445 return 0;
446 }
447 return (-EIO);
448}
449
FUJITA Tomonori4deba242008-12-05 15:25:20 +0900450static struct st_request *st_allocate_request(struct scsi_tape *stp)
Mike Christie8b05b772005-11-08 04:06:44 -0600451{
FUJITA Tomonori4deba242008-12-05 15:25:20 +0900452 struct st_request *streq;
453
454 streq = kzalloc(sizeof(*streq), GFP_KERNEL);
455 if (streq)
456 streq->stp = stp;
457 else {
Hannes Reineckeb30d8bc2014-06-25 16:39:57 +0200458 st_printk(KERN_ERR, stp,
459 "Can't get SCSI request.\n");
FUJITA Tomonori4deba242008-12-05 15:25:20 +0900460 if (signal_pending(current))
461 stp->buffer->syscall_result = -EINTR;
462 else
463 stp->buffer->syscall_result = -EBUSY;
464 }
465
466 return streq;
Mike Christie8b05b772005-11-08 04:06:44 -0600467}
468
469static void st_release_request(struct st_request *streq)
470{
471 kfree(streq);
Linus Torvalds1da177e2005-04-16 15:20:36 -0700472}
473
FUJITA Tomonori13b53b42008-12-18 14:49:41 +0900474static void st_scsi_execute_end(struct request *req, int uptodate)
475{
476 struct st_request *SRpnt = req->end_io_data;
477 struct scsi_tape *STp = SRpnt->stp;
Petr Uzelc68bf8e2011-10-21 13:31:09 +0200478 struct bio *tmp;
FUJITA Tomonori13b53b42008-12-18 14:49:41 +0900479
480 STp->buffer->cmdstat.midlevel_result = SRpnt->result = req->errors;
Tejun Heoc3a4d782009-05-07 22:24:37 +0900481 STp->buffer->cmdstat.residual = req->resid_len;
FUJITA Tomonori13b53b42008-12-18 14:49:41 +0900482
Petr Uzelc68bf8e2011-10-21 13:31:09 +0200483 tmp = SRpnt->bio;
FUJITA Tomonori13b53b42008-12-18 14:49:41 +0900484 if (SRpnt->waiting)
485 complete(SRpnt->waiting);
486
Petr Uzelc68bf8e2011-10-21 13:31:09 +0200487 blk_rq_unmap_user(tmp);
FUJITA Tomonori13b53b42008-12-18 14:49:41 +0900488 __blk_put_request(req->q, req);
489}
490
491static int st_scsi_execute(struct st_request *SRpnt, const unsigned char *cmd,
492 int data_direction, void *buffer, unsigned bufflen,
493 int timeout, int retries)
494{
495 struct request *req;
496 struct rq_map_data *mdata = &SRpnt->stp->buffer->map_data;
497 int err = 0;
498 int write = (data_direction == DMA_TO_DEVICE);
499
500 req = blk_get_request(SRpnt->stp->device->request_queue, write,
501 GFP_KERNEL);
Joe Lawrencea492f072014-08-28 08:15:21 -0600502 if (IS_ERR(req))
FUJITA Tomonori13b53b42008-12-18 14:49:41 +0900503 return DRIVER_ERROR << 24;
504
Jens Axboef27b0872014-06-06 07:57:37 -0600505 blk_rq_set_block_pc(req);
FUJITA Tomonori13b53b42008-12-18 14:49:41 +0900506 req->cmd_flags |= REQ_QUIET;
507
508 mdata->null_mapped = 1;
509
Kai Makisara02ae2c02008-12-18 14:49:50 +0900510 if (bufflen) {
511 err = blk_rq_map_user(req->q, req, mdata, NULL, bufflen,
512 GFP_KERNEL);
513 if (err) {
514 blk_put_request(req);
515 return DRIVER_ERROR << 24;
516 }
FUJITA Tomonori13b53b42008-12-18 14:49:41 +0900517 }
518
519 SRpnt->bio = req->bio;
520 req->cmd_len = COMMAND_SIZE(cmd[0]);
521 memset(req->cmd, 0, BLK_MAX_CDB);
522 memcpy(req->cmd, cmd, req->cmd_len);
523 req->sense = SRpnt->sense;
524 req->sense_len = 0;
525 req->timeout = timeout;
526 req->retries = retries;
527 req->end_io_data = SRpnt;
528
529 blk_execute_rq_nowait(req->q, NULL, req, 1, st_scsi_execute_end);
530 return 0;
531}
532
Linus Torvalds1da177e2005-04-16 15:20:36 -0700533/* Do the scsi command. Waits until command performed if do_wait is true.
534 Otherwise write_behind_check() is used to check that the command
535 has finished. */
Mike Christie8b05b772005-11-08 04:06:44 -0600536static struct st_request *
537st_do_scsi(struct st_request * SRpnt, struct scsi_tape * STp, unsigned char *cmd,
Linus Torvalds1da177e2005-04-16 15:20:36 -0700538 int bytes, int direction, int timeout, int retries, int do_wait)
539{
Kai Makisaraf03a5672005-08-02 13:40:47 +0300540 struct completion *waiting;
FUJITA Tomonori6d476262008-12-18 14:49:42 +0900541 struct rq_map_data *mdata = &STp->buffer->map_data;
542 int ret;
Linus Torvalds1da177e2005-04-16 15:20:36 -0700543
Kai Makisaraf03a5672005-08-02 13:40:47 +0300544 /* if async, make sure there's no command outstanding */
545 if (!do_wait && ((STp->buffer)->last_SRpnt)) {
Hannes Reineckeb30d8bc2014-06-25 16:39:57 +0200546 st_printk(KERN_ERR, STp,
547 "Async command already active.\n");
Kai Makisaraf03a5672005-08-02 13:40:47 +0300548 if (signal_pending(current))
549 (STp->buffer)->syscall_result = (-EINTR);
550 else
551 (STp->buffer)->syscall_result = (-EBUSY);
552 return NULL;
553 }
554
FUJITA Tomonori4deba242008-12-05 15:25:20 +0900555 if (!SRpnt) {
556 SRpnt = st_allocate_request(STp);
557 if (!SRpnt)
Linus Torvalds1da177e2005-04-16 15:20:36 -0700558 return NULL;
Linus Torvalds1da177e2005-04-16 15:20:36 -0700559 }
560
Kai Makisaraf03a5672005-08-02 13:40:47 +0300561 /* If async IO, set last_SRpnt. This ptr tells write_behind_check
562 which IO is outstanding. It's nulled out when the IO completes. */
563 if (!do_wait)
564 (STp->buffer)->last_SRpnt = SRpnt;
565
566 waiting = &STp->wait;
567 init_completion(waiting);
Mike Christie8b05b772005-11-08 04:06:44 -0600568 SRpnt->waiting = waiting;
569
FUJITA Tomonori66207422008-12-18 14:49:43 +0900570 if (STp->buffer->do_dio) {
FUJITA Tomonoric982c362009-11-26 09:24:13 +0900571 mdata->page_order = 0;
FUJITA Tomonori66207422008-12-18 14:49:43 +0900572 mdata->nr_entries = STp->buffer->sg_segs;
573 mdata->pages = STp->buffer->mapped_pages;
574 } else {
FUJITA Tomonoric982c362009-11-26 09:24:13 +0900575 mdata->page_order = STp->buffer->reserved_page_order;
FUJITA Tomonori6d476262008-12-18 14:49:42 +0900576 mdata->nr_entries =
577 DIV_ROUND_UP(bytes, PAGE_SIZE << mdata->page_order);
FUJITA Tomonoric982c362009-11-26 09:24:13 +0900578 mdata->pages = STp->buffer->reserved_pages;
579 mdata->offset = 0;
FUJITA Tomonori6d476262008-12-18 14:49:42 +0900580 }
581
Mike Christie8b05b772005-11-08 04:06:44 -0600582 memcpy(SRpnt->cmd, cmd, sizeof(SRpnt->cmd));
Linus Torvalds1da177e2005-04-16 15:20:36 -0700583 STp->buffer->cmdstat.have_sense = 0;
Mike Christie8b05b772005-11-08 04:06:44 -0600584 STp->buffer->syscall_result = 0;
Linus Torvalds1da177e2005-04-16 15:20:36 -0700585
FUJITA Tomonori66207422008-12-18 14:49:43 +0900586 ret = st_scsi_execute(SRpnt, cmd, direction, NULL, bytes, timeout,
587 retries);
FUJITA Tomonori6d476262008-12-18 14:49:42 +0900588 if (ret) {
Mike Christie8b05b772005-11-08 04:06:44 -0600589 /* could not allocate the buffer or request was too large */
590 (STp->buffer)->syscall_result = (-EBUSY);
Kai Makisara787926b2005-11-13 10:04:44 +0200591 (STp->buffer)->last_SRpnt = NULL;
FUJITA Tomonori6d476262008-12-18 14:49:42 +0900592 } else if (do_wait) {
Kai Makisaraf03a5672005-08-02 13:40:47 +0300593 wait_for_completion(waiting);
Mike Christie8b05b772005-11-08 04:06:44 -0600594 SRpnt->waiting = NULL;
Linus Torvalds1da177e2005-04-16 15:20:36 -0700595 (STp->buffer)->syscall_result = st_chk_result(STp, SRpnt);
596 }
Mike Christie8b05b772005-11-08 04:06:44 -0600597
Linus Torvalds1da177e2005-04-16 15:20:36 -0700598 return SRpnt;
599}
600
601
602/* Handle the write-behind checking (waits for completion). Returns -ENOSPC if
603 write has been correct but EOM early warning reached, -EIO if write ended in
604 error or zero if write successful. Asynchronous writes are used only in
605 variable block mode. */
606static int write_behind_check(struct scsi_tape * STp)
607{
608 int retval = 0;
609 struct st_buffer *STbuffer;
610 struct st_partstat *STps;
611 struct st_cmdstatus *cmdstatp;
Mike Christie8b05b772005-11-08 04:06:44 -0600612 struct st_request *SRpnt;
Linus Torvalds1da177e2005-04-16 15:20:36 -0700613
614 STbuffer = STp->buffer;
615 if (!STbuffer->writing)
616 return 0;
617
Hannes Reineckeb30d8bc2014-06-25 16:39:57 +0200618 DEB(
Linus Torvalds1da177e2005-04-16 15:20:36 -0700619 if (STp->write_pending)
620 STp->nbr_waits++;
621 else
622 STp->nbr_finished++;
Hannes Reineckeb30d8bc2014-06-25 16:39:57 +0200623 ) /* end DEB */
Linus Torvalds1da177e2005-04-16 15:20:36 -0700624
625 wait_for_completion(&(STp->wait));
Kai Makisaraf03a5672005-08-02 13:40:47 +0300626 SRpnt = STbuffer->last_SRpnt;
627 STbuffer->last_SRpnt = NULL;
Mike Christie8b05b772005-11-08 04:06:44 -0600628 SRpnt->waiting = NULL;
Linus Torvalds1da177e2005-04-16 15:20:36 -0700629
Kai Makisaraf03a5672005-08-02 13:40:47 +0300630 (STp->buffer)->syscall_result = st_chk_result(STp, SRpnt);
Mike Christie8b05b772005-11-08 04:06:44 -0600631 st_release_request(SRpnt);
Linus Torvalds1da177e2005-04-16 15:20:36 -0700632
633 STbuffer->buffer_bytes -= STbuffer->writing;
634 STps = &(STp->ps[STp->partition]);
635 if (STps->drv_block >= 0) {
636 if (STp->block_size == 0)
637 STps->drv_block++;
638 else
639 STps->drv_block += STbuffer->writing / STp->block_size;
640 }
641
642 cmdstatp = &STbuffer->cmdstat;
643 if (STbuffer->syscall_result) {
644 retval = -EIO;
645 if (cmdstatp->have_sense && !cmdstatp->deferred &&
646 (cmdstatp->flags & SENSE_EOM) &&
647 (cmdstatp->sense_hdr.sense_key == NO_SENSE ||
648 cmdstatp->sense_hdr.sense_key == RECOVERED_ERROR)) {
649 /* EOM at write-behind, has all data been written? */
650 if (!cmdstatp->remainder_valid ||
651 cmdstatp->uremainder64 == 0)
652 retval = -ENOSPC;
653 }
654 if (retval == -EIO)
655 STps->drv_block = -1;
656 }
657 STbuffer->writing = 0;
658
659 DEB(if (debugging && retval)
Hannes Reineckeb30d8bc2014-06-25 16:39:57 +0200660 st_printk(ST_DEB_MSG, STp,
661 "Async write error %x, return value %d.\n",
662 STbuffer->cmdstat.midlevel_result, retval);) /* end DEB */
Linus Torvalds1da177e2005-04-16 15:20:36 -0700663
664 return retval;
665}
666
667
668/* Step over EOF if it has been inadvertently crossed (ioctl not used because
669 it messes up the block number). */
670static int cross_eof(struct scsi_tape * STp, int forward)
671{
Mike Christie8b05b772005-11-08 04:06:44 -0600672 struct st_request *SRpnt;
Linus Torvalds1da177e2005-04-16 15:20:36 -0700673 unsigned char cmd[MAX_COMMAND_SIZE];
674
675 cmd[0] = SPACE;
676 cmd[1] = 0x01; /* Space FileMarks */
677 if (forward) {
678 cmd[2] = cmd[3] = 0;
679 cmd[4] = 1;
680 } else
681 cmd[2] = cmd[3] = cmd[4] = 0xff; /* -1 filemarks */
682 cmd[5] = 0;
683
Hannes Reineckeb30d8bc2014-06-25 16:39:57 +0200684 DEBC_printk(STp, "Stepping over filemark %s.\n",
685 forward ? "forward" : "backward");
Linus Torvalds1da177e2005-04-16 15:20:36 -0700686
Kai Makisara02ae2c02008-12-18 14:49:50 +0900687 SRpnt = st_do_scsi(NULL, STp, cmd, 0, DMA_NONE,
688 STp->device->request_queue->rq_timeout,
689 MAX_RETRIES, 1);
Linus Torvalds1da177e2005-04-16 15:20:36 -0700690 if (!SRpnt)
Kai Makisara02ae2c02008-12-18 14:49:50 +0900691 return (STp->buffer)->syscall_result;
Linus Torvalds1da177e2005-04-16 15:20:36 -0700692
Kai Makisara02ae2c02008-12-18 14:49:50 +0900693 st_release_request(SRpnt);
694 SRpnt = NULL;
Linus Torvalds1da177e2005-04-16 15:20:36 -0700695
696 if ((STp->buffer)->cmdstat.midlevel_result != 0)
Hannes Reineckeb30d8bc2014-06-25 16:39:57 +0200697 st_printk(KERN_ERR, STp,
698 "Stepping over filemark %s failed.\n",
699 forward ? "forward" : "backward");
Linus Torvalds1da177e2005-04-16 15:20:36 -0700700
Kai Makisara02ae2c02008-12-18 14:49:50 +0900701 return (STp->buffer)->syscall_result;
Linus Torvalds1da177e2005-04-16 15:20:36 -0700702}
703
704
705/* Flush the write buffer (never need to write if variable blocksize). */
Adrian Bunk8ef8d592008-04-14 17:17:16 +0300706static int st_flush_write_buffer(struct scsi_tape * STp)
Linus Torvalds1da177e2005-04-16 15:20:36 -0700707{
Kai Makisara786231a2008-07-11 15:06:40 +0300708 int transfer, blks;
Linus Torvalds1da177e2005-04-16 15:20:36 -0700709 int result;
710 unsigned char cmd[MAX_COMMAND_SIZE];
Mike Christie8b05b772005-11-08 04:06:44 -0600711 struct st_request *SRpnt;
Linus Torvalds1da177e2005-04-16 15:20:36 -0700712 struct st_partstat *STps;
713
714 result = write_behind_check(STp);
715 if (result)
716 return result;
717
718 result = 0;
719 if (STp->dirty == 1) {
720
Kai Makisara786231a2008-07-11 15:06:40 +0300721 transfer = STp->buffer->buffer_bytes;
Hannes Reineckeb30d8bc2014-06-25 16:39:57 +0200722 DEBC_printk(STp, "Flushing %d bytes.\n", transfer);
Linus Torvalds1da177e2005-04-16 15:20:36 -0700723
Linus Torvalds1da177e2005-04-16 15:20:36 -0700724 memset(cmd, 0, MAX_COMMAND_SIZE);
725 cmd[0] = WRITE_6;
726 cmd[1] = 1;
727 blks = transfer / STp->block_size;
728 cmd[2] = blks >> 16;
729 cmd[3] = blks >> 8;
730 cmd[4] = blks;
731
732 SRpnt = st_do_scsi(NULL, STp, cmd, transfer, DMA_TO_DEVICE,
James Bottomleya02488e2008-11-30 10:36:26 -0600733 STp->device->request_queue->rq_timeout,
734 MAX_WRITE_RETRIES, 1);
Linus Torvalds1da177e2005-04-16 15:20:36 -0700735 if (!SRpnt)
736 return (STp->buffer)->syscall_result;
737
738 STps = &(STp->ps[STp->partition]);
739 if ((STp->buffer)->syscall_result != 0) {
740 struct st_cmdstatus *cmdstatp = &STp->buffer->cmdstat;
741
742 if (cmdstatp->have_sense && !cmdstatp->deferred &&
743 (cmdstatp->flags & SENSE_EOM) &&
744 (cmdstatp->sense_hdr.sense_key == NO_SENSE ||
745 cmdstatp->sense_hdr.sense_key == RECOVERED_ERROR) &&
746 (!cmdstatp->remainder_valid ||
747 cmdstatp->uremainder64 == 0)) { /* All written at EOM early warning */
748 STp->dirty = 0;
749 (STp->buffer)->buffer_bytes = 0;
750 if (STps->drv_block >= 0)
751 STps->drv_block += blks;
752 result = (-ENOSPC);
753 } else {
Hannes Reineckeb30d8bc2014-06-25 16:39:57 +0200754 st_printk(KERN_ERR, STp, "Error on flush.\n");
Linus Torvalds1da177e2005-04-16 15:20:36 -0700755 STps->drv_block = (-1);
756 result = (-EIO);
757 }
758 } else {
759 if (STps->drv_block >= 0)
760 STps->drv_block += blks;
761 STp->dirty = 0;
762 (STp->buffer)->buffer_bytes = 0;
763 }
Mike Christie8b05b772005-11-08 04:06:44 -0600764 st_release_request(SRpnt);
Linus Torvalds1da177e2005-04-16 15:20:36 -0700765 SRpnt = NULL;
766 }
767 return result;
768}
769
770
771/* Flush the tape buffer. The tape will be positioned correctly unless
772 seek_next is true. */
773static int flush_buffer(struct scsi_tape *STp, int seek_next)
774{
775 int backspace, result;
776 struct st_buffer *STbuffer;
777 struct st_partstat *STps;
778
779 STbuffer = STp->buffer;
780
781 /*
782 * If there was a bus reset, block further access
783 * to this device.
784 */
785 if (STp->pos_unknown)
786 return (-EIO);
787
788 if (STp->ready != ST_READY)
789 return 0;
790 STps = &(STp->ps[STp->partition]);
791 if (STps->rw == ST_WRITING) /* Writing */
Adrian Bunk8ef8d592008-04-14 17:17:16 +0300792 return st_flush_write_buffer(STp);
Linus Torvalds1da177e2005-04-16 15:20:36 -0700793
794 if (STp->block_size == 0)
795 return 0;
796
797 backspace = ((STp->buffer)->buffer_bytes +
798 (STp->buffer)->read_pointer) / STp->block_size -
799 ((STp->buffer)->read_pointer + STp->block_size - 1) /
800 STp->block_size;
801 (STp->buffer)->buffer_bytes = 0;
802 (STp->buffer)->read_pointer = 0;
803 result = 0;
804 if (!seek_next) {
805 if (STps->eof == ST_FM_HIT) {
806 result = cross_eof(STp, 0); /* Back over the EOF hit */
807 if (!result)
808 STps->eof = ST_NOEOF;
809 else {
810 if (STps->drv_file >= 0)
811 STps->drv_file++;
812 STps->drv_block = 0;
813 }
814 }
815 if (!result && backspace > 0)
816 result = st_int_ioctl(STp, MTBSR, backspace);
817 } else if (STps->eof == ST_FM_HIT) {
818 if (STps->drv_file >= 0)
819 STps->drv_file++;
820 STps->drv_block = 0;
821 STps->eof = ST_NOEOF;
822 }
823 return result;
824
825}
826
827/* Set the mode parameters */
828static int set_mode_densblk(struct scsi_tape * STp, struct st_modedef * STm)
829{
830 int set_it = 0;
831 unsigned long arg;
Linus Torvalds1da177e2005-04-16 15:20:36 -0700832
833 if (!STp->density_changed &&
834 STm->default_density >= 0 &&
835 STm->default_density != STp->density) {
836 arg = STm->default_density;
837 set_it = 1;
838 } else
839 arg = STp->density;
840 arg <<= MT_ST_DENSITY_SHIFT;
841 if (!STp->blksize_changed &&
842 STm->default_blksize >= 0 &&
843 STm->default_blksize != STp->block_size) {
844 arg |= STm->default_blksize;
845 set_it = 1;
846 } else
847 arg |= STp->block_size;
848 if (set_it &&
849 st_int_ioctl(STp, SET_DENS_AND_BLK, arg)) {
Hannes Reineckeb30d8bc2014-06-25 16:39:57 +0200850 st_printk(KERN_WARNING, STp,
851 "Can't set default block size to %d bytes "
852 "and density %x.\n",
853 STm->default_blksize, STm->default_density);
Linus Torvalds1da177e2005-04-16 15:20:36 -0700854 if (modes_defined)
855 return (-EINVAL);
856 }
857 return 0;
858}
859
860
Mike Christie8b05b772005-11-08 04:06:44 -0600861/* Lock or unlock the drive door. Don't use when st_request allocated. */
Linus Torvalds1da177e2005-04-16 15:20:36 -0700862static int do_door_lock(struct scsi_tape * STp, int do_lock)
863{
864 int retval, cmd;
Linus Torvalds1da177e2005-04-16 15:20:36 -0700865
866 cmd = do_lock ? SCSI_IOCTL_DOORLOCK : SCSI_IOCTL_DOORUNLOCK;
Hannes Reineckeb30d8bc2014-06-25 16:39:57 +0200867 DEBC_printk(STp, "%socking drive door.\n", do_lock ? "L" : "Unl");
Linus Torvalds1da177e2005-04-16 15:20:36 -0700868 retval = scsi_ioctl(STp->device, cmd, NULL);
869 if (!retval) {
870 STp->door_locked = do_lock ? ST_LOCKED_EXPLICIT : ST_UNLOCKED;
871 }
872 else {
873 STp->door_locked = ST_LOCK_FAILS;
874 }
875 return retval;
876}
877
878
879/* Set the internal state after reset */
880static void reset_state(struct scsi_tape *STp)
881{
882 int i;
883 struct st_partstat *STps;
884
885 STp->pos_unknown = 0;
886 for (i = 0; i < ST_NBR_PARTITIONS; i++) {
887 STps = &(STp->ps[i]);
888 STps->rw = ST_IDLE;
889 STps->eof = ST_NOEOF;
890 STps->at_sm = 0;
891 STps->last_block_valid = 0;
892 STps->drv_block = -1;
893 STps->drv_file = -1;
894 }
895 if (STp->can_partitions) {
896 STp->partition = find_partition(STp);
897 if (STp->partition < 0)
898 STp->partition = 0;
899 STp->new_partition = STp->partition;
900 }
901}
902
903/* Test if the drive is ready. Returns either one of the codes below or a negative system
904 error code. */
905#define CHKRES_READY 0
906#define CHKRES_NEW_SESSION 1
907#define CHKRES_NOT_READY 2
908#define CHKRES_NO_TAPE 3
909
910#define MAX_ATTENTIONS 10
911
912static int test_ready(struct scsi_tape *STp, int do_wait)
913{
914 int attentions, waits, max_wait, scode;
915 int retval = CHKRES_READY, new_session = 0;
916 unsigned char cmd[MAX_COMMAND_SIZE];
Kai Makisara02ae2c02008-12-18 14:49:50 +0900917 struct st_request *SRpnt = NULL;
Linus Torvalds1da177e2005-04-16 15:20:36 -0700918 struct st_cmdstatus *cmdstatp = &STp->buffer->cmdstat;
919
920 max_wait = do_wait ? ST_BLOCK_SECONDS : 0;
921
922 for (attentions=waits=0; ; ) {
923 memset((void *) &cmd[0], 0, MAX_COMMAND_SIZE);
924 cmd[0] = TEST_UNIT_READY;
Kai Makisara02ae2c02008-12-18 14:49:50 +0900925 SRpnt = st_do_scsi(SRpnt, STp, cmd, 0, DMA_NONE,
926 STp->long_timeout, MAX_READY_RETRIES, 1);
Linus Torvalds1da177e2005-04-16 15:20:36 -0700927
Kai Makisara02ae2c02008-12-18 14:49:50 +0900928 if (!SRpnt) {
929 retval = (STp->buffer)->syscall_result;
Linus Torvalds1da177e2005-04-16 15:20:36 -0700930 break;
Kai Makisara02ae2c02008-12-18 14:49:50 +0900931 }
Linus Torvalds1da177e2005-04-16 15:20:36 -0700932
933 if (cmdstatp->have_sense) {
934
935 scode = cmdstatp->sense_hdr.sense_key;
936
937 if (scode == UNIT_ATTENTION) { /* New media? */
938 new_session = 1;
939 if (attentions < MAX_ATTENTIONS) {
940 attentions++;
941 continue;
942 }
943 else {
944 retval = (-EIO);
945 break;
946 }
947 }
948
949 if (scode == NOT_READY) {
950 if (waits < max_wait) {
951 if (msleep_interruptible(1000)) {
952 retval = (-EINTR);
953 break;
954 }
955 waits++;
956 continue;
957 }
958 else {
959 if ((STp->device)->scsi_level >= SCSI_2 &&
960 cmdstatp->sense_hdr.asc == 0x3a) /* Check ASC */
961 retval = CHKRES_NO_TAPE;
962 else
963 retval = CHKRES_NOT_READY;
964 break;
965 }
966 }
967 }
968
969 retval = (STp->buffer)->syscall_result;
970 if (!retval)
971 retval = new_session ? CHKRES_NEW_SESSION : CHKRES_READY;
972 break;
973 }
974
Kai Makisara02ae2c02008-12-18 14:49:50 +0900975 if (SRpnt != NULL)
976 st_release_request(SRpnt);
Linus Torvalds1da177e2005-04-16 15:20:36 -0700977 return retval;
978}
979
980
981/* See if the drive is ready and gather information about the tape. Return values:
982 < 0 negative error code from errno.h
983 0 drive ready
984 1 drive not ready (possibly no tape)
985*/
986static int check_tape(struct scsi_tape *STp, struct file *filp)
987{
988 int i, retval, new_session = 0, do_wait;
989 unsigned char cmd[MAX_COMMAND_SIZE], saved_cleaning;
990 unsigned short st_flags = filp->f_flags;
Mike Christie8b05b772005-11-08 04:06:44 -0600991 struct st_request *SRpnt = NULL;
Linus Torvalds1da177e2005-04-16 15:20:36 -0700992 struct st_modedef *STm;
993 struct st_partstat *STps;
Al Viro496ad9a2013-01-23 17:07:38 -0500994 struct inode *inode = file_inode(filp);
Linus Torvalds1da177e2005-04-16 15:20:36 -0700995 int mode = TAPE_MODE(inode);
996
997 STp->ready = ST_READY;
998
999 if (mode != STp->current_mode) {
Hannes Reineckeb30d8bc2014-06-25 16:39:57 +02001000 DEBC_printk(STp, "Mode change from %d to %d.\n",
1001 STp->current_mode, mode);
Linus Torvalds1da177e2005-04-16 15:20:36 -07001002 new_session = 1;
1003 STp->current_mode = mode;
1004 }
1005 STm = &(STp->modes[STp->current_mode]);
1006
1007 saved_cleaning = STp->cleaning_req;
1008 STp->cleaning_req = 0;
1009
1010 do_wait = ((filp->f_flags & O_NONBLOCK) == 0);
1011 retval = test_ready(STp, do_wait);
1012
1013 if (retval < 0)
1014 goto err_out;
1015
1016 if (retval == CHKRES_NEW_SESSION) {
1017 STp->pos_unknown = 0;
1018 STp->partition = STp->new_partition = 0;
1019 if (STp->can_partitions)
1020 STp->nbr_partitions = 1; /* This guess will be updated later
1021 if necessary */
1022 for (i = 0; i < ST_NBR_PARTITIONS; i++) {
1023 STps = &(STp->ps[i]);
1024 STps->rw = ST_IDLE;
1025 STps->eof = ST_NOEOF;
1026 STps->at_sm = 0;
1027 STps->last_block_valid = 0;
1028 STps->drv_block = 0;
1029 STps->drv_file = 0;
1030 }
1031 new_session = 1;
1032 }
1033 else {
1034 STp->cleaning_req |= saved_cleaning;
1035
1036 if (retval == CHKRES_NOT_READY || retval == CHKRES_NO_TAPE) {
1037 if (retval == CHKRES_NO_TAPE)
1038 STp->ready = ST_NO_TAPE;
1039 else
1040 STp->ready = ST_NOT_READY;
1041
1042 STp->density = 0; /* Clear the erroneous "residue" */
1043 STp->write_prot = 0;
1044 STp->block_size = 0;
1045 STp->ps[0].drv_file = STp->ps[0].drv_block = (-1);
1046 STp->partition = STp->new_partition = 0;
1047 STp->door_locked = ST_UNLOCKED;
1048 return CHKRES_NOT_READY;
1049 }
1050 }
1051
1052 if (STp->omit_blklims)
1053 STp->min_block = STp->max_block = (-1);
1054 else {
1055 memset((void *) &cmd[0], 0, MAX_COMMAND_SIZE);
1056 cmd[0] = READ_BLOCK_LIMITS;
1057
Kai Makisara02ae2c02008-12-18 14:49:50 +09001058 SRpnt = st_do_scsi(SRpnt, STp, cmd, 6, DMA_FROM_DEVICE,
1059 STp->device->request_queue->rq_timeout,
1060 MAX_READY_RETRIES, 1);
1061 if (!SRpnt) {
1062 retval = (STp->buffer)->syscall_result;
Linus Torvalds1da177e2005-04-16 15:20:36 -07001063 goto err_out;
1064 }
1065
Mike Christie8b05b772005-11-08 04:06:44 -06001066 if (!SRpnt->result && !STp->buffer->cmdstat.have_sense) {
Linus Torvalds1da177e2005-04-16 15:20:36 -07001067 STp->max_block = ((STp->buffer)->b_data[1] << 16) |
1068 ((STp->buffer)->b_data[2] << 8) | (STp->buffer)->b_data[3];
1069 STp->min_block = ((STp->buffer)->b_data[4] << 8) |
1070 (STp->buffer)->b_data[5];
1071 if ( DEB( debugging || ) !STp->inited)
Hannes Reineckeb30d8bc2014-06-25 16:39:57 +02001072 st_printk(KERN_INFO, STp,
1073 "Block limits %d - %d bytes.\n",
1074 STp->min_block, STp->max_block);
Linus Torvalds1da177e2005-04-16 15:20:36 -07001075 } else {
1076 STp->min_block = STp->max_block = (-1);
Hannes Reineckeb30d8bc2014-06-25 16:39:57 +02001077 DEBC_printk(STp, "Can't read block limits.\n");
Linus Torvalds1da177e2005-04-16 15:20:36 -07001078 }
1079 }
1080
1081 memset((void *) &cmd[0], 0, MAX_COMMAND_SIZE);
1082 cmd[0] = MODE_SENSE;
1083 cmd[4] = 12;
1084
Kai Makisara02ae2c02008-12-18 14:49:50 +09001085 SRpnt = st_do_scsi(SRpnt, STp, cmd, 12, DMA_FROM_DEVICE,
1086 STp->device->request_queue->rq_timeout,
1087 MAX_READY_RETRIES, 1);
1088 if (!SRpnt) {
1089 retval = (STp->buffer)->syscall_result;
Linus Torvalds1da177e2005-04-16 15:20:36 -07001090 goto err_out;
1091 }
1092
1093 if ((STp->buffer)->syscall_result != 0) {
Hannes Reineckeb30d8bc2014-06-25 16:39:57 +02001094 DEBC_printk(STp, "No Mode Sense.\n");
Linus Torvalds1da177e2005-04-16 15:20:36 -07001095 STp->block_size = ST_DEFAULT_BLOCK; /* Educated guess (?) */
1096 (STp->buffer)->syscall_result = 0; /* Prevent error propagation */
1097 STp->drv_write_prot = 0;
1098 } else {
Hannes Reineckeb30d8bc2014-06-25 16:39:57 +02001099 DEBC_printk(STp,"Mode sense. Length %d, "
1100 "medium %x, WBS %x, BLL %d\n",
1101 (STp->buffer)->b_data[0],
1102 (STp->buffer)->b_data[1],
1103 (STp->buffer)->b_data[2],
1104 (STp->buffer)->b_data[3]);
Linus Torvalds1da177e2005-04-16 15:20:36 -07001105
1106 if ((STp->buffer)->b_data[3] >= 8) {
1107 STp->drv_buffer = ((STp->buffer)->b_data[2] >> 4) & 7;
1108 STp->density = (STp->buffer)->b_data[4];
1109 STp->block_size = (STp->buffer)->b_data[9] * 65536 +
1110 (STp->buffer)->b_data[10] * 256 + (STp->buffer)->b_data[11];
Hannes Reineckeb30d8bc2014-06-25 16:39:57 +02001111 DEBC_printk(STp, "Density %x, tape length: %x, "
1112 "drv buffer: %d\n",
1113 STp->density,
1114 (STp->buffer)->b_data[5] * 65536 +
1115 (STp->buffer)->b_data[6] * 256 +
1116 (STp->buffer)->b_data[7],
1117 STp->drv_buffer);
Linus Torvalds1da177e2005-04-16 15:20:36 -07001118 }
1119 STp->drv_write_prot = ((STp->buffer)->b_data[2] & 0x80) != 0;
Lee Duncanc743e442012-03-01 12:41:01 -08001120 if (!STp->drv_buffer && STp->immediate_filemark) {
Hannes Reineckeb30d8bc2014-06-25 16:39:57 +02001121 st_printk(KERN_WARNING, STp,
1122 "non-buffered tape: disabling "
1123 "writing immediate filemarks\n");
Lee Duncanc743e442012-03-01 12:41:01 -08001124 STp->immediate_filemark = 0;
1125 }
Linus Torvalds1da177e2005-04-16 15:20:36 -07001126 }
Mike Christie8b05b772005-11-08 04:06:44 -06001127 st_release_request(SRpnt);
Linus Torvalds1da177e2005-04-16 15:20:36 -07001128 SRpnt = NULL;
Hannes Reineckeb30d8bc2014-06-25 16:39:57 +02001129 STp->inited = 1;
Linus Torvalds1da177e2005-04-16 15:20:36 -07001130
1131 if (STp->block_size > 0)
1132 (STp->buffer)->buffer_blocks =
Hannes Reineckeb30d8bc2014-06-25 16:39:57 +02001133 (STp->buffer)->buffer_size / STp->block_size;
Linus Torvalds1da177e2005-04-16 15:20:36 -07001134 else
1135 (STp->buffer)->buffer_blocks = 1;
1136 (STp->buffer)->buffer_bytes = (STp->buffer)->read_pointer = 0;
1137
Hannes Reineckeb30d8bc2014-06-25 16:39:57 +02001138 DEBC_printk(STp, "Block size: %d, buffer size: %d (%d blocks).\n",
1139 STp->block_size, (STp->buffer)->buffer_size,
1140 (STp->buffer)->buffer_blocks);
Linus Torvalds1da177e2005-04-16 15:20:36 -07001141
1142 if (STp->drv_write_prot) {
1143 STp->write_prot = 1;
1144
Hannes Reineckeb30d8bc2014-06-25 16:39:57 +02001145 DEBC_printk(STp, "Write protected\n");
Linus Torvalds1da177e2005-04-16 15:20:36 -07001146
1147 if (do_wait &&
1148 ((st_flags & O_ACCMODE) == O_WRONLY ||
1149 (st_flags & O_ACCMODE) == O_RDWR)) {
1150 retval = (-EROFS);
1151 goto err_out;
1152 }
1153 }
1154
1155 if (STp->can_partitions && STp->nbr_partitions < 1) {
1156 /* This code is reached when the device is opened for the first time
1157 after the driver has been initialized with tape in the drive and the
1158 partition support has been enabled. */
Hannes Reineckeb30d8bc2014-06-25 16:39:57 +02001159 DEBC_printk(STp, "Updating partition number in status.\n");
Linus Torvalds1da177e2005-04-16 15:20:36 -07001160 if ((STp->partition = find_partition(STp)) < 0) {
1161 retval = STp->partition;
1162 goto err_out;
1163 }
1164 STp->new_partition = STp->partition;
1165 STp->nbr_partitions = 1; /* This guess will be updated when necessary */
1166 }
1167
1168 if (new_session) { /* Change the drive parameters for the new mode */
1169 STp->density_changed = STp->blksize_changed = 0;
1170 STp->compression_changed = 0;
1171 if (!(STm->defaults_for_writes) &&
1172 (retval = set_mode_densblk(STp, STm)) < 0)
1173 goto err_out;
1174
1175 if (STp->default_drvbuffer != 0xff) {
1176 if (st_int_ioctl(STp, MTSETDRVBUFFER, STp->default_drvbuffer))
Hannes Reineckeb30d8bc2014-06-25 16:39:57 +02001177 st_printk(KERN_WARNING, STp,
1178 "Can't set default drive "
1179 "buffering to %d.\n",
1180 STp->default_drvbuffer);
Linus Torvalds1da177e2005-04-16 15:20:36 -07001181 }
1182 }
1183
1184 return CHKRES_READY;
1185
1186 err_out:
1187 return retval;
1188}
1189
1190
Jonathan Corbetb3369c62008-05-15 16:08:15 -06001191 /* Open the device. Needs to take the BKL only because of incrementing the SCSI host
Linus Torvalds1da177e2005-04-16 15:20:36 -07001192 module count. */
1193static int st_open(struct inode *inode, struct file *filp)
1194{
1195 int i, retval = (-EIO);
Oliver Neukum46a243f2012-01-15 00:16:51 +01001196 int resumed = 0;
Linus Torvalds1da177e2005-04-16 15:20:36 -07001197 struct scsi_tape *STp;
1198 struct st_partstat *STps;
1199 int dev = TAPE_NR(inode);
Linus Torvalds1da177e2005-04-16 15:20:36 -07001200
1201 /*
1202 * We really want to do nonseekable_open(inode, filp); here, but some
1203 * versions of tar incorrectly call lseek on tapes and bail out if that
1204 * fails. So we disallow pread() and pwrite(), but permit lseeks.
1205 */
1206 filp->f_mode &= ~(FMODE_PREAD | FMODE_PWRITE);
1207
Jonathan Corbetb3369c62008-05-15 16:08:15 -06001208 if (!(STp = scsi_tape_get(dev))) {
Kai Makisaraf03a5672005-08-02 13:40:47 +03001209 return -ENXIO;
Jonathan Corbetb3369c62008-05-15 16:08:15 -06001210 }
Kai Makisaraf03a5672005-08-02 13:40:47 +03001211
Linus Torvalds1da177e2005-04-16 15:20:36 -07001212 filp->private_data = STp;
Linus Torvalds1da177e2005-04-16 15:20:36 -07001213
Jeff Mahoney6c648d92012-08-18 15:20:39 -04001214 spin_lock(&st_use_lock);
Linus Torvalds1da177e2005-04-16 15:20:36 -07001215 if (STp->in_use) {
Jeff Mahoney6c648d92012-08-18 15:20:39 -04001216 spin_unlock(&st_use_lock);
Kai Makisaraf03a5672005-08-02 13:40:47 +03001217 scsi_tape_put(STp);
Hannes Reineckeb30d8bc2014-06-25 16:39:57 +02001218 DEBC_printk(STp, "Device already in use.\n");
Linus Torvalds1da177e2005-04-16 15:20:36 -07001219 return (-EBUSY);
1220 }
1221
Linus Torvalds1da177e2005-04-16 15:20:36 -07001222 STp->in_use = 1;
Jeff Mahoney6c648d92012-08-18 15:20:39 -04001223 spin_unlock(&st_use_lock);
Linus Torvalds1da177e2005-04-16 15:20:36 -07001224 STp->rew_at_close = STp->autorew_dev = (iminor(inode) & 0x80) == 0;
1225
Oliver Neukum46a243f2012-01-15 00:16:51 +01001226 if (scsi_autopm_get_device(STp->device) < 0) {
1227 retval = -EIO;
1228 goto err_out;
1229 }
1230 resumed = 1;
Linus Torvalds1da177e2005-04-16 15:20:36 -07001231 if (!scsi_block_when_processing_errors(STp->device)) {
1232 retval = (-ENXIO);
1233 goto err_out;
1234 }
1235
1236 /* See that we have at least a one page buffer available */
1237 if (!enlarge_buffer(STp->buffer, PAGE_SIZE, STp->restr_dma)) {
Hannes Reineckeb30d8bc2014-06-25 16:39:57 +02001238 st_printk(KERN_WARNING, STp,
1239 "Can't allocate one page tape buffer.\n");
Linus Torvalds1da177e2005-04-16 15:20:36 -07001240 retval = (-EOVERFLOW);
1241 goto err_out;
1242 }
1243
Kai Makisara40f6b362008-02-24 22:23:24 +02001244 (STp->buffer)->cleared = 0;
Linus Torvalds1da177e2005-04-16 15:20:36 -07001245 (STp->buffer)->writing = 0;
1246 (STp->buffer)->syscall_result = 0;
1247
1248 STp->write_prot = ((filp->f_flags & O_ACCMODE) == O_RDONLY);
1249
1250 STp->dirty = 0;
1251 for (i = 0; i < ST_NBR_PARTITIONS; i++) {
1252 STps = &(STp->ps[i]);
1253 STps->rw = ST_IDLE;
1254 }
Kai Makisara9abe16c2007-02-03 13:21:29 +02001255 STp->try_dio_now = STp->try_dio;
Linus Torvalds1da177e2005-04-16 15:20:36 -07001256 STp->recover_count = 0;
1257 DEB( STp->nbr_waits = STp->nbr_finished = 0;
Kai Makisaradeee13d2008-02-22 20:11:21 +02001258 STp->nbr_requests = STp->nbr_dio = STp->nbr_pages = 0; )
Linus Torvalds1da177e2005-04-16 15:20:36 -07001259
1260 retval = check_tape(STp, filp);
1261 if (retval < 0)
1262 goto err_out;
1263 if ((filp->f_flags & O_NONBLOCK) == 0 &&
1264 retval != CHKRES_READY) {
Kai Makisara413f7322006-10-05 22:59:46 +03001265 if (STp->ready == NO_TAPE)
1266 retval = (-ENOMEDIUM);
1267 else
1268 retval = (-EIO);
Linus Torvalds1da177e2005-04-16 15:20:36 -07001269 goto err_out;
1270 }
1271 return 0;
1272
1273 err_out:
1274 normalize_buffer(STp->buffer);
Hannes Reinecke0644f532012-09-10 15:36:44 -07001275 spin_lock(&st_use_lock);
Linus Torvalds1da177e2005-04-16 15:20:36 -07001276 STp->in_use = 0;
Hannes Reinecke0644f532012-09-10 15:36:44 -07001277 spin_unlock(&st_use_lock);
Kai Makisaraf03a5672005-08-02 13:40:47 +03001278 scsi_tape_put(STp);
Oliver Neukum46a243f2012-01-15 00:16:51 +01001279 if (resumed)
1280 scsi_autopm_put_device(STp->device);
Linus Torvalds1da177e2005-04-16 15:20:36 -07001281 return retval;
1282
1283}
1284
1285
1286/* Flush the tape buffer before close */
Miklos Szeredi75e1fcc2006-06-23 02:05:12 -07001287static int st_flush(struct file *filp, fl_owner_t id)
Linus Torvalds1da177e2005-04-16 15:20:36 -07001288{
1289 int result = 0, result2;
1290 unsigned char cmd[MAX_COMMAND_SIZE];
Mike Christie8b05b772005-11-08 04:06:44 -06001291 struct st_request *SRpnt;
Linus Torvalds1da177e2005-04-16 15:20:36 -07001292 struct scsi_tape *STp = filp->private_data;
1293 struct st_modedef *STm = &(STp->modes[STp->current_mode]);
1294 struct st_partstat *STps = &(STp->ps[STp->partition]);
Linus Torvalds1da177e2005-04-16 15:20:36 -07001295
1296 if (file_count(filp) > 1)
1297 return 0;
1298
1299 if (STps->rw == ST_WRITING && !STp->pos_unknown) {
Adrian Bunk8ef8d592008-04-14 17:17:16 +03001300 result = st_flush_write_buffer(STp);
Linus Torvalds1da177e2005-04-16 15:20:36 -07001301 if (result != 0 && result != (-ENOSPC))
1302 goto out;
1303 }
1304
1305 if (STp->can_partitions &&
1306 (result2 = switch_partition(STp)) < 0) {
Hannes Reineckeb30d8bc2014-06-25 16:39:57 +02001307 DEBC_printk(STp, "switch_partition at close failed.\n");
Linus Torvalds1da177e2005-04-16 15:20:36 -07001308 if (result == 0)
1309 result = result2;
1310 goto out;
1311 }
1312
1313 DEBC( if (STp->nbr_requests)
Hannes Reineckeb30d8bc2014-06-25 16:39:57 +02001314 st_printk(KERN_DEBUG, STp,
1315 "Number of r/w requests %d, dio used in %d, "
1316 "pages %d.\n", STp->nbr_requests, STp->nbr_dio,
1317 STp->nbr_pages));
Linus Torvalds1da177e2005-04-16 15:20:36 -07001318
1319 if (STps->rw == ST_WRITING && !STp->pos_unknown) {
1320 struct st_cmdstatus *cmdstatp = &STp->buffer->cmdstat;
1321
Hannes Reineckeb30d8bc2014-06-25 16:39:57 +02001322#if DEBUG
1323 DEBC_printk(STp, "Async write waits %d, finished %d.\n",
1324 STp->nbr_waits, STp->nbr_finished);
1325#endif
Linus Torvalds1da177e2005-04-16 15:20:36 -07001326 memset(cmd, 0, MAX_COMMAND_SIZE);
1327 cmd[0] = WRITE_FILEMARKS;
Lee Duncanc743e442012-03-01 12:41:01 -08001328 if (STp->immediate_filemark)
1329 cmd[1] = 1;
Linus Torvalds1da177e2005-04-16 15:20:36 -07001330 cmd[4] = 1 + STp->two_fm;
1331
Kai Makisara02ae2c02008-12-18 14:49:50 +09001332 SRpnt = st_do_scsi(NULL, STp, cmd, 0, DMA_NONE,
1333 STp->device->request_queue->rq_timeout,
1334 MAX_WRITE_RETRIES, 1);
Linus Torvalds1da177e2005-04-16 15:20:36 -07001335 if (!SRpnt) {
Kai Makisara02ae2c02008-12-18 14:49:50 +09001336 result = (STp->buffer)->syscall_result;
Linus Torvalds1da177e2005-04-16 15:20:36 -07001337 goto out;
1338 }
1339
1340 if (STp->buffer->syscall_result == 0 ||
1341 (cmdstatp->have_sense && !cmdstatp->deferred &&
1342 (cmdstatp->flags & SENSE_EOM) &&
1343 (cmdstatp->sense_hdr.sense_key == NO_SENSE ||
1344 cmdstatp->sense_hdr.sense_key == RECOVERED_ERROR) &&
1345 (!cmdstatp->remainder_valid || cmdstatp->uremainder64 == 0))) {
1346 /* Write successful at EOM */
Mike Christie8b05b772005-11-08 04:06:44 -06001347 st_release_request(SRpnt);
Linus Torvalds1da177e2005-04-16 15:20:36 -07001348 SRpnt = NULL;
1349 if (STps->drv_file >= 0)
1350 STps->drv_file++;
1351 STps->drv_block = 0;
1352 if (STp->two_fm)
1353 cross_eof(STp, 0);
1354 STps->eof = ST_FM;
1355 }
1356 else { /* Write error */
Mike Christie8b05b772005-11-08 04:06:44 -06001357 st_release_request(SRpnt);
Linus Torvalds1da177e2005-04-16 15:20:36 -07001358 SRpnt = NULL;
Hannes Reineckeb30d8bc2014-06-25 16:39:57 +02001359 st_printk(KERN_ERR, STp,
1360 "Error on write filemark.\n");
Linus Torvalds1da177e2005-04-16 15:20:36 -07001361 if (result == 0)
1362 result = (-EIO);
1363 }
1364
Hannes Reineckeb30d8bc2014-06-25 16:39:57 +02001365 DEBC_printk(STp, "Buffer flushed, %d EOF(s) written\n", cmd[4]);
Linus Torvalds1da177e2005-04-16 15:20:36 -07001366 } else if (!STp->rew_at_close) {
1367 STps = &(STp->ps[STp->partition]);
1368 if (!STm->sysv || STps->rw != ST_READING) {
1369 if (STp->can_bsr)
1370 result = flush_buffer(STp, 0);
1371 else if (STps->eof == ST_FM_HIT) {
1372 result = cross_eof(STp, 0);
1373 if (result) {
1374 if (STps->drv_file >= 0)
1375 STps->drv_file++;
1376 STps->drv_block = 0;
1377 STps->eof = ST_FM;
1378 } else
1379 STps->eof = ST_NOEOF;
1380 }
1381 } else if ((STps->eof == ST_NOEOF &&
1382 !(result = cross_eof(STp, 1))) ||
1383 STps->eof == ST_FM_HIT) {
1384 if (STps->drv_file >= 0)
1385 STps->drv_file++;
1386 STps->drv_block = 0;
1387 STps->eof = ST_FM;
1388 }
1389 }
1390
1391 out:
1392 if (STp->rew_at_close) {
1393 result2 = st_int_ioctl(STp, MTREW, 1);
1394 if (result == 0)
1395 result = result2;
1396 }
1397 return result;
1398}
1399
1400
1401/* Close the device and release it. BKL is not needed: this is the only thread
1402 accessing this tape. */
1403static int st_release(struct inode *inode, struct file *filp)
1404{
1405 int result = 0;
1406 struct scsi_tape *STp = filp->private_data;
1407
1408 if (STp->door_locked == ST_LOCKED_AUTO)
1409 do_door_lock(STp, 0);
1410
1411 normalize_buffer(STp->buffer);
Jeff Mahoney6c648d92012-08-18 15:20:39 -04001412 spin_lock(&st_use_lock);
Linus Torvalds1da177e2005-04-16 15:20:36 -07001413 STp->in_use = 0;
Jeff Mahoney6c648d92012-08-18 15:20:39 -04001414 spin_unlock(&st_use_lock);
Oliver Neukum46a243f2012-01-15 00:16:51 +01001415 scsi_autopm_put_device(STp->device);
Kai Makisaraf03a5672005-08-02 13:40:47 +03001416 scsi_tape_put(STp);
Linus Torvalds1da177e2005-04-16 15:20:36 -07001417
1418 return result;
1419}
1420
1421/* The checks common to both reading and writing */
1422static ssize_t rw_checks(struct scsi_tape *STp, struct file *filp, size_t count)
1423{
1424 ssize_t retval = 0;
1425
1426 /*
1427 * If we are in the middle of error recovery, don't let anyone
1428 * else try and use this device. Also, if error recovery fails, it
1429 * may try and take the device offline, in which case all further
1430 * access to the device is prohibited.
1431 */
1432 if (!scsi_block_when_processing_errors(STp->device)) {
1433 retval = (-ENXIO);
1434 goto out;
1435 }
1436
1437 if (STp->ready != ST_READY) {
1438 if (STp->ready == ST_NO_TAPE)
1439 retval = (-ENOMEDIUM);
1440 else
1441 retval = (-EIO);
1442 goto out;
1443 }
1444
1445 if (! STp->modes[STp->current_mode].defined) {
1446 retval = (-ENXIO);
1447 goto out;
1448 }
1449
1450
1451 /*
1452 * If there was a bus reset, block further access
1453 * to this device.
1454 */
1455 if (STp->pos_unknown) {
1456 retval = (-EIO);
1457 goto out;
1458 }
1459
1460 if (count == 0)
1461 goto out;
1462
Hannes Reineckeb30d8bc2014-06-25 16:39:57 +02001463 DEB(
Linus Torvalds1da177e2005-04-16 15:20:36 -07001464 if (!STp->in_use) {
Hannes Reineckeb30d8bc2014-06-25 16:39:57 +02001465 st_printk(ST_DEB_MSG, STp,
1466 "Incorrect device.\n");
Linus Torvalds1da177e2005-04-16 15:20:36 -07001467 retval = (-EIO);
1468 goto out;
1469 } ) /* end DEB */
1470
1471 if (STp->can_partitions &&
1472 (retval = switch_partition(STp)) < 0)
1473 goto out;
1474
1475 if (STp->block_size == 0 && STp->max_block > 0 &&
1476 (count < STp->min_block || count > STp->max_block)) {
1477 retval = (-EINVAL);
1478 goto out;
1479 }
1480
1481 if (STp->do_auto_lock && STp->door_locked == ST_UNLOCKED &&
1482 !do_door_lock(STp, 1))
1483 STp->door_locked = ST_LOCKED_AUTO;
1484
1485 out:
1486 return retval;
1487}
1488
1489
1490static int setup_buffering(struct scsi_tape *STp, const char __user *buf,
1491 size_t count, int is_read)
1492{
1493 int i, bufsize, retval = 0;
1494 struct st_buffer *STbp = STp->buffer;
1495
1496 if (is_read)
Kai Makisara9abe16c2007-02-03 13:21:29 +02001497 i = STp->try_dio_now && try_rdio;
Linus Torvalds1da177e2005-04-16 15:20:36 -07001498 else
Kai Makisara9abe16c2007-02-03 13:21:29 +02001499 i = STp->try_dio_now && try_wdio;
Mike Christie8b05b772005-11-08 04:06:44 -06001500
Linus Torvalds1da177e2005-04-16 15:20:36 -07001501 if (i && ((unsigned long)buf & queue_dma_alignment(
1502 STp->device->request_queue)) == 0) {
FUJITA Tomonori66207422008-12-18 14:49:43 +09001503 i = sgl_map_user_pages(STbp, STbp->use_sg, (unsigned long)buf,
1504 count, (is_read ? READ : WRITE));
Linus Torvalds1da177e2005-04-16 15:20:36 -07001505 if (i > 0) {
1506 STbp->do_dio = i;
1507 STbp->buffer_bytes = 0; /* can be used as transfer counter */
1508 }
1509 else
1510 STbp->do_dio = 0; /* fall back to buffering with any error */
1511 STbp->sg_segs = STbp->do_dio;
Linus Torvalds1da177e2005-04-16 15:20:36 -07001512 DEB(
1513 if (STbp->do_dio) {
1514 STp->nbr_dio++;
1515 STp->nbr_pages += STbp->do_dio;
Linus Torvalds1da177e2005-04-16 15:20:36 -07001516 }
1517 )
1518 } else
1519 STbp->do_dio = 0;
1520 DEB( STp->nbr_requests++; )
1521
1522 if (!STbp->do_dio) {
1523 if (STp->block_size)
1524 bufsize = STp->block_size > st_fixed_buffer_size ?
1525 STp->block_size : st_fixed_buffer_size;
Kai Makisara40f6b362008-02-24 22:23:24 +02001526 else {
Linus Torvalds1da177e2005-04-16 15:20:36 -07001527 bufsize = count;
Kai Makisara40f6b362008-02-24 22:23:24 +02001528 /* Make sure that data from previous user is not leaked even if
1529 HBA does not return correct residual */
1530 if (is_read && STp->sili && !STbp->cleared)
1531 clear_buffer(STbp);
1532 }
1533
Linus Torvalds1da177e2005-04-16 15:20:36 -07001534 if (bufsize > STbp->buffer_size &&
1535 !enlarge_buffer(STbp, bufsize, STp->restr_dma)) {
Hannes Reineckeb30d8bc2014-06-25 16:39:57 +02001536 st_printk(KERN_WARNING, STp,
1537 "Can't allocate %d byte tape buffer.\n",
1538 bufsize);
Linus Torvalds1da177e2005-04-16 15:20:36 -07001539 retval = (-EOVERFLOW);
1540 goto out;
1541 }
1542 if (STp->block_size)
1543 STbp->buffer_blocks = bufsize / STp->block_size;
1544 }
1545
1546 out:
1547 return retval;
1548}
1549
1550
1551/* Can be called more than once after each setup_buffer() */
Kai Makisara787926b2005-11-13 10:04:44 +02001552static void release_buffering(struct scsi_tape *STp, int is_read)
Linus Torvalds1da177e2005-04-16 15:20:36 -07001553{
1554 struct st_buffer *STbp;
1555
1556 STbp = STp->buffer;
1557 if (STbp->do_dio) {
FUJITA Tomonori66207422008-12-18 14:49:43 +09001558 sgl_unmap_user_pages(STbp, STbp->do_dio, is_read);
Linus Torvalds1da177e2005-04-16 15:20:36 -07001559 STbp->do_dio = 0;
Kai Makisara787926b2005-11-13 10:04:44 +02001560 STbp->sg_segs = 0;
Linus Torvalds1da177e2005-04-16 15:20:36 -07001561 }
1562}
1563
1564
1565/* Write command */
1566static ssize_t
1567st_write(struct file *filp, const char __user *buf, size_t count, loff_t * ppos)
1568{
1569 ssize_t total;
1570 ssize_t i, do_count, blks, transfer;
1571 ssize_t retval;
1572 int undone, retry_eot = 0, scode;
1573 int async_write;
1574 unsigned char cmd[MAX_COMMAND_SIZE];
1575 const char __user *b_point;
Mike Christie8b05b772005-11-08 04:06:44 -06001576 struct st_request *SRpnt = NULL;
Linus Torvalds1da177e2005-04-16 15:20:36 -07001577 struct scsi_tape *STp = filp->private_data;
1578 struct st_modedef *STm;
1579 struct st_partstat *STps;
1580 struct st_buffer *STbp;
Linus Torvalds1da177e2005-04-16 15:20:36 -07001581
Matthias Kaehlcke28f85002007-07-29 23:38:15 +02001582 if (mutex_lock_interruptible(&STp->lock))
Linus Torvalds1da177e2005-04-16 15:20:36 -07001583 return -ERESTARTSYS;
1584
1585 retval = rw_checks(STp, filp, count);
1586 if (retval || count == 0)
1587 goto out;
1588
1589 /* Write must be integral number of blocks */
1590 if (STp->block_size != 0 && (count % STp->block_size) != 0) {
Hannes Reineckeb30d8bc2014-06-25 16:39:57 +02001591 st_printk(KERN_WARNING, STp,
1592 "Write not multiple of tape block size.\n");
Linus Torvalds1da177e2005-04-16 15:20:36 -07001593 retval = (-EINVAL);
1594 goto out;
1595 }
1596
1597 STm = &(STp->modes[STp->current_mode]);
1598 STps = &(STp->ps[STp->partition]);
1599
1600 if (STp->write_prot) {
1601 retval = (-EACCES);
1602 goto out;
1603 }
1604
1605
1606 if (STps->rw == ST_READING) {
1607 retval = flush_buffer(STp, 0);
1608 if (retval)
1609 goto out;
1610 STps->rw = ST_WRITING;
1611 } else if (STps->rw != ST_WRITING &&
1612 STps->drv_file == 0 && STps->drv_block == 0) {
1613 if ((retval = set_mode_densblk(STp, STm)) < 0)
1614 goto out;
1615 if (STm->default_compression != ST_DONT_TOUCH &&
1616 !(STp->compression_changed)) {
1617 if (st_compression(STp, (STm->default_compression == ST_YES))) {
Hannes Reineckeb30d8bc2014-06-25 16:39:57 +02001618 st_printk(KERN_WARNING, STp,
1619 "Can't set default compression.\n");
Linus Torvalds1da177e2005-04-16 15:20:36 -07001620 if (modes_defined) {
1621 retval = (-EINVAL);
1622 goto out;
1623 }
1624 }
1625 }
1626 }
1627
1628 STbp = STp->buffer;
1629 i = write_behind_check(STp);
1630 if (i) {
1631 if (i == -ENOSPC)
1632 STps->eof = ST_EOM_OK;
1633 else
1634 STps->eof = ST_EOM_ERROR;
1635 }
1636
1637 if (STps->eof == ST_EOM_OK) {
1638 STps->eof = ST_EOD_1; /* allow next write */
1639 retval = (-ENOSPC);
1640 goto out;
1641 }
1642 else if (STps->eof == ST_EOM_ERROR) {
1643 retval = (-EIO);
1644 goto out;
1645 }
1646
1647 /* Check the buffer readability in cases where copy_user might catch
1648 the problems after some tape movement. */
1649 if (STp->block_size != 0 &&
1650 !STbp->do_dio &&
1651 (copy_from_user(&i, buf, 1) != 0 ||
1652 copy_from_user(&i, buf + count - 1, 1) != 0)) {
1653 retval = (-EFAULT);
1654 goto out;
1655 }
1656
1657 retval = setup_buffering(STp, buf, count, 0);
1658 if (retval)
1659 goto out;
1660
1661 total = count;
1662
1663 memset(cmd, 0, MAX_COMMAND_SIZE);
1664 cmd[0] = WRITE_6;
1665 cmd[1] = (STp->block_size != 0);
1666
1667 STps->rw = ST_WRITING;
1668
1669 b_point = buf;
1670 while (count > 0 && !retry_eot) {
1671
1672 if (STbp->do_dio) {
1673 do_count = count;
1674 }
1675 else {
1676 if (STp->block_size == 0)
1677 do_count = count;
1678 else {
1679 do_count = STbp->buffer_blocks * STp->block_size -
1680 STbp->buffer_bytes;
1681 if (do_count > count)
1682 do_count = count;
1683 }
1684
1685 i = append_to_buffer(b_point, STbp, do_count);
1686 if (i) {
1687 retval = i;
1688 goto out;
1689 }
1690 }
1691 count -= do_count;
1692 b_point += do_count;
1693
1694 async_write = STp->block_size == 0 && !STbp->do_dio &&
1695 STm->do_async_writes && STps->eof < ST_EOM_OK;
1696
1697 if (STp->block_size != 0 && STm->do_buffer_writes &&
Kai Makisara9abe16c2007-02-03 13:21:29 +02001698 !(STp->try_dio_now && try_wdio) && STps->eof < ST_EOM_OK &&
Linus Torvalds1da177e2005-04-16 15:20:36 -07001699 STbp->buffer_bytes < STbp->buffer_size) {
1700 STp->dirty = 1;
1701 /* Don't write a buffer that is not full enough. */
1702 if (!async_write && count == 0)
1703 break;
1704 }
1705
1706 retry_write:
1707 if (STp->block_size == 0)
1708 blks = transfer = do_count;
1709 else {
1710 if (!STbp->do_dio)
1711 blks = STbp->buffer_bytes;
1712 else
1713 blks = do_count;
1714 blks /= STp->block_size;
1715 transfer = blks * STp->block_size;
1716 }
1717 cmd[2] = blks >> 16;
1718 cmd[3] = blks >> 8;
1719 cmd[4] = blks;
1720
1721 SRpnt = st_do_scsi(SRpnt, STp, cmd, transfer, DMA_TO_DEVICE,
James Bottomleya02488e2008-11-30 10:36:26 -06001722 STp->device->request_queue->rq_timeout,
1723 MAX_WRITE_RETRIES, !async_write);
Linus Torvalds1da177e2005-04-16 15:20:36 -07001724 if (!SRpnt) {
1725 retval = STbp->syscall_result;
1726 goto out;
1727 }
Mike Christie8b05b772005-11-08 04:06:44 -06001728 if (async_write && !STbp->syscall_result) {
Linus Torvalds1da177e2005-04-16 15:20:36 -07001729 STbp->writing = transfer;
1730 STp->dirty = !(STbp->writing ==
1731 STbp->buffer_bytes);
1732 SRpnt = NULL; /* Prevent releasing this request! */
1733 DEB( STp->write_pending = 1; )
1734 break;
1735 }
1736
1737 if (STbp->syscall_result != 0) {
1738 struct st_cmdstatus *cmdstatp = &STp->buffer->cmdstat;
1739
Hannes Reineckeb30d8bc2014-06-25 16:39:57 +02001740 DEBC_printk(STp, "Error on write:\n");
Linus Torvalds1da177e2005-04-16 15:20:36 -07001741 if (cmdstatp->have_sense && (cmdstatp->flags & SENSE_EOM)) {
1742 scode = cmdstatp->sense_hdr.sense_key;
1743 if (cmdstatp->remainder_valid)
1744 undone = (int)cmdstatp->uremainder64;
1745 else if (STp->block_size == 0 &&
1746 scode == VOLUME_OVERFLOW)
1747 undone = transfer;
1748 else
1749 undone = 0;
1750 if (STp->block_size != 0)
1751 undone *= STp->block_size;
1752 if (undone <= do_count) {
1753 /* Only data from this write is not written */
1754 count += undone;
Kai Makisara626dcb12008-07-11 15:05:25 +03001755 b_point -= undone;
Linus Torvalds1da177e2005-04-16 15:20:36 -07001756 do_count -= undone;
1757 if (STp->block_size)
1758 blks = (transfer - undone) / STp->block_size;
1759 STps->eof = ST_EOM_OK;
1760 /* Continue in fixed block mode if all written
1761 in this request but still something left to write
1762 (retval left to zero)
1763 */
1764 if (STp->block_size == 0 ||
1765 undone > 0 || count == 0)
1766 retval = (-ENOSPC); /* EOM within current request */
Hannes Reineckeb30d8bc2014-06-25 16:39:57 +02001767 DEBC_printk(STp, "EOM with %d "
1768 "bytes unwritten.\n",
1769 (int)count);
Linus Torvalds1da177e2005-04-16 15:20:36 -07001770 } else {
1771 /* EOT within data buffered earlier (possible only
1772 in fixed block mode without direct i/o) */
1773 if (!retry_eot && !cmdstatp->deferred &&
1774 (scode == NO_SENSE || scode == RECOVERED_ERROR)) {
1775 move_buffer_data(STp->buffer, transfer - undone);
1776 retry_eot = 1;
1777 if (STps->drv_block >= 0) {
1778 STps->drv_block += (transfer - undone) /
1779 STp->block_size;
1780 }
1781 STps->eof = ST_EOM_OK;
Hannes Reineckeb30d8bc2014-06-25 16:39:57 +02001782 DEBC_printk(STp, "Retry "
1783 "write of %d "
1784 "bytes at EOM.\n",
1785 STp->buffer->buffer_bytes);
Linus Torvalds1da177e2005-04-16 15:20:36 -07001786 goto retry_write;
1787 }
1788 else {
1789 /* Either error within data buffered by driver or
1790 failed retry */
1791 count -= do_count;
1792 blks = do_count = 0;
1793 STps->eof = ST_EOM_ERROR;
1794 STps->drv_block = (-1); /* Too cautious? */
1795 retval = (-EIO); /* EOM for old data */
Hannes Reineckeb30d8bc2014-06-25 16:39:57 +02001796 DEBC_printk(STp, "EOM with "
1797 "lost data.\n");
Linus Torvalds1da177e2005-04-16 15:20:36 -07001798 }
1799 }
1800 } else {
1801 count += do_count;
1802 STps->drv_block = (-1); /* Too cautious? */
Mike Christie8b05b772005-11-08 04:06:44 -06001803 retval = STbp->syscall_result;
Linus Torvalds1da177e2005-04-16 15:20:36 -07001804 }
1805
1806 }
1807
1808 if (STps->drv_block >= 0) {
1809 if (STp->block_size == 0)
1810 STps->drv_block += (do_count > 0);
1811 else
1812 STps->drv_block += blks;
1813 }
1814
1815 STbp->buffer_bytes = 0;
1816 STp->dirty = 0;
1817
1818 if (retval || retry_eot) {
1819 if (count < total)
1820 retval = total - count;
1821 goto out;
1822 }
1823 }
1824
1825 if (STps->eof == ST_EOD_1)
1826 STps->eof = ST_EOM_OK;
1827 else if (STps->eof != ST_EOM_OK)
1828 STps->eof = ST_NOEOF;
1829 retval = total - count;
1830
1831 out:
1832 if (SRpnt != NULL)
Mike Christie8b05b772005-11-08 04:06:44 -06001833 st_release_request(SRpnt);
Kai Makisara787926b2005-11-13 10:04:44 +02001834 release_buffering(STp, 0);
Matthias Kaehlcke28f85002007-07-29 23:38:15 +02001835 mutex_unlock(&STp->lock);
Linus Torvalds1da177e2005-04-16 15:20:36 -07001836
1837 return retval;
1838}
1839
1840/* Read data from the tape. Returns zero in the normal case, one if the
1841 eof status has changed, and the negative error code in case of a
1842 fatal error. Otherwise updates the buffer and the eof state.
1843
1844 Does release user buffer mapping if it is set.
1845*/
1846static long read_tape(struct scsi_tape *STp, long count,
Mike Christie8b05b772005-11-08 04:06:44 -06001847 struct st_request ** aSRpnt)
Linus Torvalds1da177e2005-04-16 15:20:36 -07001848{
1849 int transfer, blks, bytes;
1850 unsigned char cmd[MAX_COMMAND_SIZE];
Mike Christie8b05b772005-11-08 04:06:44 -06001851 struct st_request *SRpnt;
Linus Torvalds1da177e2005-04-16 15:20:36 -07001852 struct st_modedef *STm;
1853 struct st_partstat *STps;
1854 struct st_buffer *STbp;
1855 int retval = 0;
Linus Torvalds1da177e2005-04-16 15:20:36 -07001856
1857 if (count == 0)
1858 return 0;
1859
1860 STm = &(STp->modes[STp->current_mode]);
1861 STps = &(STp->ps[STp->partition]);
1862 if (STps->eof == ST_FM_HIT)
1863 return 1;
1864 STbp = STp->buffer;
1865
1866 if (STp->block_size == 0)
1867 blks = bytes = count;
1868 else {
Kai Makisara9abe16c2007-02-03 13:21:29 +02001869 if (!(STp->try_dio_now && try_rdio) && STm->do_read_ahead) {
Linus Torvalds1da177e2005-04-16 15:20:36 -07001870 blks = (STp->buffer)->buffer_blocks;
1871 bytes = blks * STp->block_size;
1872 } else {
1873 bytes = count;
1874 if (!STbp->do_dio && bytes > (STp->buffer)->buffer_size)
1875 bytes = (STp->buffer)->buffer_size;
1876 blks = bytes / STp->block_size;
1877 bytes = blks * STp->block_size;
1878 }
1879 }
1880
1881 memset(cmd, 0, MAX_COMMAND_SIZE);
1882 cmd[0] = READ_6;
1883 cmd[1] = (STp->block_size != 0);
Kai Makisara40f6b362008-02-24 22:23:24 +02001884 if (!cmd[1] && STp->sili)
1885 cmd[1] |= 2;
Linus Torvalds1da177e2005-04-16 15:20:36 -07001886 cmd[2] = blks >> 16;
1887 cmd[3] = blks >> 8;
1888 cmd[4] = blks;
1889
1890 SRpnt = *aSRpnt;
1891 SRpnt = st_do_scsi(SRpnt, STp, cmd, bytes, DMA_FROM_DEVICE,
James Bottomleya02488e2008-11-30 10:36:26 -06001892 STp->device->request_queue->rq_timeout,
1893 MAX_RETRIES, 1);
Kai Makisara787926b2005-11-13 10:04:44 +02001894 release_buffering(STp, 1);
Linus Torvalds1da177e2005-04-16 15:20:36 -07001895 *aSRpnt = SRpnt;
1896 if (!SRpnt)
1897 return STbp->syscall_result;
1898
1899 STbp->read_pointer = 0;
1900 STps->at_sm = 0;
1901
1902 /* Something to check */
1903 if (STbp->syscall_result) {
1904 struct st_cmdstatus *cmdstatp = &STp->buffer->cmdstat;
1905
1906 retval = 1;
Hannes Reineckeb30d8bc2014-06-25 16:39:57 +02001907 DEBC_printk(STp,
1908 "Sense: %2x %2x %2x %2x %2x %2x %2x %2x\n",
1909 SRpnt->sense[0], SRpnt->sense[1],
1910 SRpnt->sense[2], SRpnt->sense[3],
1911 SRpnt->sense[4], SRpnt->sense[5],
1912 SRpnt->sense[6], SRpnt->sense[7]);
Linus Torvalds1da177e2005-04-16 15:20:36 -07001913 if (cmdstatp->have_sense) {
1914
1915 if (cmdstatp->sense_hdr.sense_key == BLANK_CHECK)
1916 cmdstatp->flags &= 0xcf; /* No need for EOM in this case */
1917
1918 if (cmdstatp->flags != 0) { /* EOF, EOM, or ILI */
1919 /* Compute the residual count */
1920 if (cmdstatp->remainder_valid)
1921 transfer = (int)cmdstatp->uremainder64;
1922 else
1923 transfer = 0;
1924 if (STp->block_size == 0 &&
1925 cmdstatp->sense_hdr.sense_key == MEDIUM_ERROR)
1926 transfer = bytes;
1927
1928 if (cmdstatp->flags & SENSE_ILI) { /* ILI */
Hannes Reineckeb30d8bc2014-06-25 16:39:57 +02001929 if (STp->block_size == 0 &&
1930 transfer < 0) {
1931 st_printk(KERN_NOTICE, STp,
1932 "Failed to read %d "
1933 "byte block with %d "
1934 "byte transfer.\n",
1935 bytes - transfer,
1936 bytes);
1937 if (STps->drv_block >= 0)
1938 STps->drv_block += 1;
1939 STbp->buffer_bytes = 0;
1940 return (-ENOMEM);
1941 } else if (STp->block_size == 0) {
Linus Torvalds1da177e2005-04-16 15:20:36 -07001942 STbp->buffer_bytes = bytes - transfer;
1943 } else {
Mike Christie8b05b772005-11-08 04:06:44 -06001944 st_release_request(SRpnt);
Linus Torvalds1da177e2005-04-16 15:20:36 -07001945 SRpnt = *aSRpnt = NULL;
1946 if (transfer == blks) { /* We did not get anything, error */
Hannes Reineckeb30d8bc2014-06-25 16:39:57 +02001947 st_printk(KERN_NOTICE, STp,
1948 "Incorrect "
1949 "block size.\n");
Linus Torvalds1da177e2005-04-16 15:20:36 -07001950 if (STps->drv_block >= 0)
1951 STps->drv_block += blks - transfer + 1;
1952 st_int_ioctl(STp, MTBSR, 1);
1953 return (-EIO);
1954 }
1955 /* We have some data, deliver it */
1956 STbp->buffer_bytes = (blks - transfer) *
1957 STp->block_size;
Hannes Reineckeb30d8bc2014-06-25 16:39:57 +02001958 DEBC_printk(STp, "ILI but "
1959 "enough data "
1960 "received %ld "
1961 "%d.\n", count,
1962 STbp->buffer_bytes);
Linus Torvalds1da177e2005-04-16 15:20:36 -07001963 if (STps->drv_block >= 0)
1964 STps->drv_block += 1;
1965 if (st_int_ioctl(STp, MTBSR, 1))
1966 return (-EIO);
1967 }
1968 } else if (cmdstatp->flags & SENSE_FMK) { /* FM overrides EOM */
1969 if (STps->eof != ST_FM_HIT)
1970 STps->eof = ST_FM_HIT;
1971 else
1972 STps->eof = ST_EOD_2;
1973 if (STp->block_size == 0)
1974 STbp->buffer_bytes = 0;
1975 else
1976 STbp->buffer_bytes =
1977 bytes - transfer * STp->block_size;
Hannes Reineckeb30d8bc2014-06-25 16:39:57 +02001978 DEBC_printk(STp, "EOF detected (%d "
1979 "bytes read).\n",
1980 STbp->buffer_bytes);
Linus Torvalds1da177e2005-04-16 15:20:36 -07001981 } else if (cmdstatp->flags & SENSE_EOM) {
1982 if (STps->eof == ST_FM)
1983 STps->eof = ST_EOD_1;
1984 else
1985 STps->eof = ST_EOM_OK;
1986 if (STp->block_size == 0)
1987 STbp->buffer_bytes = bytes - transfer;
1988 else
1989 STbp->buffer_bytes =
1990 bytes - transfer * STp->block_size;
1991
Hannes Reineckeb30d8bc2014-06-25 16:39:57 +02001992 DEBC_printk(STp, "EOM detected (%d "
1993 "bytes read).\n",
1994 STbp->buffer_bytes);
Linus Torvalds1da177e2005-04-16 15:20:36 -07001995 }
1996 }
Hannes Reineckeb30d8bc2014-06-25 16:39:57 +02001997 /* end of EOF, EOM, ILI test */
Linus Torvalds1da177e2005-04-16 15:20:36 -07001998 else { /* nonzero sense key */
Hannes Reineckeb30d8bc2014-06-25 16:39:57 +02001999 DEBC_printk(STp, "Tape error while reading.\n");
Linus Torvalds1da177e2005-04-16 15:20:36 -07002000 STps->drv_block = (-1);
2001 if (STps->eof == ST_FM &&
2002 cmdstatp->sense_hdr.sense_key == BLANK_CHECK) {
Hannes Reineckeb30d8bc2014-06-25 16:39:57 +02002003 DEBC_printk(STp, "Zero returned for "
2004 "first BLANK CHECK "
2005 "after EOF.\n");
Linus Torvalds1da177e2005-04-16 15:20:36 -07002006 STps->eof = ST_EOD_2; /* First BLANK_CHECK after FM */
2007 } else /* Some other extended sense code */
2008 retval = (-EIO);
2009 }
2010
2011 if (STbp->buffer_bytes < 0) /* Caused by bogus sense data */
2012 STbp->buffer_bytes = 0;
2013 }
Hannes Reineckeb30d8bc2014-06-25 16:39:57 +02002014 /* End of extended sense test */
Linus Torvalds1da177e2005-04-16 15:20:36 -07002015 else { /* Non-extended sense */
2016 retval = STbp->syscall_result;
2017 }
2018
2019 }
Hannes Reineckeb30d8bc2014-06-25 16:39:57 +02002020 /* End of error handling */
Kai Makisara40f6b362008-02-24 22:23:24 +02002021 else { /* Read successful */
Linus Torvalds1da177e2005-04-16 15:20:36 -07002022 STbp->buffer_bytes = bytes;
Kai Makisara40f6b362008-02-24 22:23:24 +02002023 if (STp->sili) /* In fixed block mode residual is always zero here */
2024 STbp->buffer_bytes -= STp->buffer->cmdstat.residual;
2025 }
Linus Torvalds1da177e2005-04-16 15:20:36 -07002026
2027 if (STps->drv_block >= 0) {
2028 if (STp->block_size == 0)
2029 STps->drv_block++;
2030 else
2031 STps->drv_block += STbp->buffer_bytes / STp->block_size;
2032 }
2033 return retval;
2034}
2035
2036
2037/* Read command */
2038static ssize_t
2039st_read(struct file *filp, char __user *buf, size_t count, loff_t * ppos)
2040{
2041 ssize_t total;
2042 ssize_t retval = 0;
2043 ssize_t i, transfer;
2044 int special, do_dio = 0;
Mike Christie8b05b772005-11-08 04:06:44 -06002045 struct st_request *SRpnt = NULL;
Linus Torvalds1da177e2005-04-16 15:20:36 -07002046 struct scsi_tape *STp = filp->private_data;
2047 struct st_modedef *STm;
2048 struct st_partstat *STps;
2049 struct st_buffer *STbp = STp->buffer;
Linus Torvalds1da177e2005-04-16 15:20:36 -07002050
Matthias Kaehlcke28f85002007-07-29 23:38:15 +02002051 if (mutex_lock_interruptible(&STp->lock))
Linus Torvalds1da177e2005-04-16 15:20:36 -07002052 return -ERESTARTSYS;
2053
2054 retval = rw_checks(STp, filp, count);
2055 if (retval || count == 0)
2056 goto out;
2057
2058 STm = &(STp->modes[STp->current_mode]);
Kai Makisara9abe16c2007-02-03 13:21:29 +02002059 if (STp->block_size != 0 && (count % STp->block_size) != 0) {
2060 if (!STm->do_read_ahead) {
2061 retval = (-EINVAL); /* Read must be integral number of blocks */
2062 goto out;
2063 }
2064 STp->try_dio_now = 0; /* Direct i/o can't handle split blocks */
Linus Torvalds1da177e2005-04-16 15:20:36 -07002065 }
2066
2067 STps = &(STp->ps[STp->partition]);
2068 if (STps->rw == ST_WRITING) {
2069 retval = flush_buffer(STp, 0);
2070 if (retval)
2071 goto out;
2072 STps->rw = ST_READING;
2073 }
Hannes Reineckeb30d8bc2014-06-25 16:39:57 +02002074 DEB(
Linus Torvalds1da177e2005-04-16 15:20:36 -07002075 if (debugging && STps->eof != ST_NOEOF)
Hannes Reineckeb30d8bc2014-06-25 16:39:57 +02002076 st_printk(ST_DEB_MSG, STp,
2077 "EOF/EOM flag up (%d). Bytes %d\n",
2078 STps->eof, STbp->buffer_bytes);
2079 ) /* end DEB */
Linus Torvalds1da177e2005-04-16 15:20:36 -07002080
2081 retval = setup_buffering(STp, buf, count, 1);
2082 if (retval)
2083 goto out;
2084 do_dio = STbp->do_dio;
2085
2086 if (STbp->buffer_bytes == 0 &&
2087 STps->eof >= ST_EOD_1) {
2088 if (STps->eof < ST_EOD) {
2089 STps->eof += 1;
2090 retval = 0;
2091 goto out;
2092 }
2093 retval = (-EIO); /* EOM or Blank Check */
2094 goto out;
2095 }
2096
2097 if (do_dio) {
2098 /* Check the buffer writability before any tape movement. Don't alter
2099 buffer data. */
2100 if (copy_from_user(&i, buf, 1) != 0 ||
2101 copy_to_user(buf, &i, 1) != 0 ||
2102 copy_from_user(&i, buf + count - 1, 1) != 0 ||
2103 copy_to_user(buf + count - 1, &i, 1) != 0) {
2104 retval = (-EFAULT);
2105 goto out;
2106 }
2107 }
2108
2109 STps->rw = ST_READING;
2110
2111
2112 /* Loop until enough data in buffer or a special condition found */
2113 for (total = 0, special = 0; total < count && !special;) {
2114
2115 /* Get new data if the buffer is empty */
2116 if (STbp->buffer_bytes == 0) {
2117 special = read_tape(STp, count - total, &SRpnt);
2118 if (special < 0) { /* No need to continue read */
2119 retval = special;
2120 goto out;
2121 }
2122 }
2123
2124 /* Move the data from driver buffer to user buffer */
2125 if (STbp->buffer_bytes > 0) {
Hannes Reineckeb30d8bc2014-06-25 16:39:57 +02002126 DEB(
Linus Torvalds1da177e2005-04-16 15:20:36 -07002127 if (debugging && STps->eof != ST_NOEOF)
Hannes Reineckeb30d8bc2014-06-25 16:39:57 +02002128 st_printk(ST_DEB_MSG, STp,
2129 "EOF up (%d). Left %d, needed %d.\n",
2130 STps->eof, STbp->buffer_bytes,
2131 (int)(count - total));
2132 ) /* end DEB */
Linus Torvalds1da177e2005-04-16 15:20:36 -07002133 transfer = STbp->buffer_bytes < count - total ?
2134 STbp->buffer_bytes : count - total;
2135 if (!do_dio) {
2136 i = from_buffer(STbp, buf, transfer);
2137 if (i) {
2138 retval = i;
2139 goto out;
2140 }
2141 }
2142 buf += transfer;
2143 total += transfer;
2144 }
2145
2146 if (STp->block_size == 0)
2147 break; /* Read only one variable length block */
2148
2149 } /* for (total = 0, special = 0;
2150 total < count && !special; ) */
2151
2152 /* Change the eof state if no data from tape or buffer */
2153 if (total == 0) {
2154 if (STps->eof == ST_FM_HIT) {
2155 STps->eof = ST_FM;
2156 STps->drv_block = 0;
2157 if (STps->drv_file >= 0)
2158 STps->drv_file++;
2159 } else if (STps->eof == ST_EOD_1) {
2160 STps->eof = ST_EOD_2;
2161 STps->drv_block = 0;
2162 if (STps->drv_file >= 0)
2163 STps->drv_file++;
2164 } else if (STps->eof == ST_EOD_2)
2165 STps->eof = ST_EOD;
2166 } else if (STps->eof == ST_FM)
2167 STps->eof = ST_NOEOF;
2168 retval = total;
2169
2170 out:
2171 if (SRpnt != NULL) {
Mike Christie8b05b772005-11-08 04:06:44 -06002172 st_release_request(SRpnt);
Linus Torvalds1da177e2005-04-16 15:20:36 -07002173 SRpnt = NULL;
2174 }
2175 if (do_dio) {
Kai Makisara787926b2005-11-13 10:04:44 +02002176 release_buffering(STp, 1);
Linus Torvalds1da177e2005-04-16 15:20:36 -07002177 STbp->buffer_bytes = 0;
2178 }
Matthias Kaehlcke28f85002007-07-29 23:38:15 +02002179 mutex_unlock(&STp->lock);
Linus Torvalds1da177e2005-04-16 15:20:36 -07002180
2181 return retval;
2182}
2183
2184
2185
2186DEB(
2187/* Set the driver options */
Hannes Reineckeb30d8bc2014-06-25 16:39:57 +02002188static void st_log_options(struct scsi_tape * STp, struct st_modedef * STm)
Linus Torvalds1da177e2005-04-16 15:20:36 -07002189{
2190 if (debugging) {
Hannes Reineckeb30d8bc2014-06-25 16:39:57 +02002191 st_printk(KERN_INFO, STp,
2192 "Mode %d options: buffer writes: %d, "
2193 "async writes: %d, read ahead: %d\n",
2194 STp->current_mode, STm->do_buffer_writes,
2195 STm->do_async_writes, STm->do_read_ahead);
2196 st_printk(KERN_INFO, STp,
2197 " can bsr: %d, two FMs: %d, "
2198 "fast mteom: %d, auto lock: %d,\n",
2199 STp->can_bsr, STp->two_fm, STp->fast_mteom,
2200 STp->do_auto_lock);
2201 st_printk(KERN_INFO, STp,
2202 " defs for wr: %d, no block limits: %d, "
2203 "partitions: %d, s2 log: %d\n",
2204 STm->defaults_for_writes, STp->omit_blklims,
2205 STp->can_partitions, STp->scsi2_logical);
2206 st_printk(KERN_INFO, STp,
2207 " sysv: %d nowait: %d sili: %d "
2208 "nowait_filemark: %d\n",
2209 STm->sysv, STp->immediate, STp->sili,
2210 STp->immediate_filemark);
2211 st_printk(KERN_INFO, STp, " debugging: %d\n", debugging);
Linus Torvalds1da177e2005-04-16 15:20:36 -07002212 }
2213}
2214 )
2215
2216
2217static int st_set_options(struct scsi_tape *STp, long options)
2218{
2219 int value;
2220 long code;
2221 struct st_modedef *STm;
Linus Torvalds1da177e2005-04-16 15:20:36 -07002222 struct cdev *cd0, *cd1;
Maurizio Lombardid6216c42014-02-11 22:22:47 +01002223 struct device *d0, *d1;
Linus Torvalds1da177e2005-04-16 15:20:36 -07002224
2225 STm = &(STp->modes[STp->current_mode]);
2226 if (!STm->defined) {
Maurizio Lombardid6216c42014-02-11 22:22:47 +01002227 cd0 = STm->cdevs[0];
2228 cd1 = STm->cdevs[1];
2229 d0 = STm->devs[0];
2230 d1 = STm->devs[1];
Linus Torvalds1da177e2005-04-16 15:20:36 -07002231 memcpy(STm, &(STp->modes[0]), sizeof(struct st_modedef));
Maurizio Lombardid6216c42014-02-11 22:22:47 +01002232 STm->cdevs[0] = cd0;
2233 STm->cdevs[1] = cd1;
2234 STm->devs[0] = d0;
2235 STm->devs[1] = d1;
Linus Torvalds1da177e2005-04-16 15:20:36 -07002236 modes_defined = 1;
Hannes Reineckeb30d8bc2014-06-25 16:39:57 +02002237 DEBC_printk(STp, "Initialized mode %d definition from mode 0\n",
2238 STp->current_mode);
Linus Torvalds1da177e2005-04-16 15:20:36 -07002239 }
2240
2241 code = options & MT_ST_OPTIONS;
2242 if (code == MT_ST_BOOLEANS) {
2243 STm->do_buffer_writes = (options & MT_ST_BUFFER_WRITES) != 0;
2244 STm->do_async_writes = (options & MT_ST_ASYNC_WRITES) != 0;
2245 STm->defaults_for_writes = (options & MT_ST_DEF_WRITES) != 0;
2246 STm->do_read_ahead = (options & MT_ST_READ_AHEAD) != 0;
2247 STp->two_fm = (options & MT_ST_TWO_FM) != 0;
2248 STp->fast_mteom = (options & MT_ST_FAST_MTEOM) != 0;
2249 STp->do_auto_lock = (options & MT_ST_AUTO_LOCK) != 0;
2250 STp->can_bsr = (options & MT_ST_CAN_BSR) != 0;
2251 STp->omit_blklims = (options & MT_ST_NO_BLKLIMS) != 0;
2252 if ((STp->device)->scsi_level >= SCSI_2)
2253 STp->can_partitions = (options & MT_ST_CAN_PARTITIONS) != 0;
2254 STp->scsi2_logical = (options & MT_ST_SCSI2LOGICAL) != 0;
2255 STp->immediate = (options & MT_ST_NOWAIT) != 0;
Lee Duncanc743e442012-03-01 12:41:01 -08002256 STp->immediate_filemark = (options & MT_ST_NOWAIT_EOF) != 0;
Linus Torvalds1da177e2005-04-16 15:20:36 -07002257 STm->sysv = (options & MT_ST_SYSV) != 0;
Kai Makisara40f6b362008-02-24 22:23:24 +02002258 STp->sili = (options & MT_ST_SILI) != 0;
Linus Torvalds1da177e2005-04-16 15:20:36 -07002259 DEB( debugging = (options & MT_ST_DEBUGGING) != 0;
Hannes Reineckeb30d8bc2014-06-25 16:39:57 +02002260 st_log_options(STp, STm); )
Linus Torvalds1da177e2005-04-16 15:20:36 -07002261 } else if (code == MT_ST_SETBOOLEANS || code == MT_ST_CLEARBOOLEANS) {
2262 value = (code == MT_ST_SETBOOLEANS);
2263 if ((options & MT_ST_BUFFER_WRITES) != 0)
2264 STm->do_buffer_writes = value;
2265 if ((options & MT_ST_ASYNC_WRITES) != 0)
2266 STm->do_async_writes = value;
2267 if ((options & MT_ST_DEF_WRITES) != 0)
2268 STm->defaults_for_writes = value;
2269 if ((options & MT_ST_READ_AHEAD) != 0)
2270 STm->do_read_ahead = value;
2271 if ((options & MT_ST_TWO_FM) != 0)
2272 STp->two_fm = value;
2273 if ((options & MT_ST_FAST_MTEOM) != 0)
2274 STp->fast_mteom = value;
2275 if ((options & MT_ST_AUTO_LOCK) != 0)
2276 STp->do_auto_lock = value;
2277 if ((options & MT_ST_CAN_BSR) != 0)
2278 STp->can_bsr = value;
2279 if ((options & MT_ST_NO_BLKLIMS) != 0)
2280 STp->omit_blklims = value;
2281 if ((STp->device)->scsi_level >= SCSI_2 &&
2282 (options & MT_ST_CAN_PARTITIONS) != 0)
2283 STp->can_partitions = value;
2284 if ((options & MT_ST_SCSI2LOGICAL) != 0)
2285 STp->scsi2_logical = value;
2286 if ((options & MT_ST_NOWAIT) != 0)
2287 STp->immediate = value;
Lee Duncanc743e442012-03-01 12:41:01 -08002288 if ((options & MT_ST_NOWAIT_EOF) != 0)
2289 STp->immediate_filemark = value;
Linus Torvalds1da177e2005-04-16 15:20:36 -07002290 if ((options & MT_ST_SYSV) != 0)
2291 STm->sysv = value;
Kai Makisara40f6b362008-02-24 22:23:24 +02002292 if ((options & MT_ST_SILI) != 0)
2293 STp->sili = value;
Hannes Reineckeb30d8bc2014-06-25 16:39:57 +02002294 DEB(
Linus Torvalds1da177e2005-04-16 15:20:36 -07002295 if ((options & MT_ST_DEBUGGING) != 0)
2296 debugging = value;
Hannes Reineckeb30d8bc2014-06-25 16:39:57 +02002297 st_log_options(STp, STm); )
Linus Torvalds1da177e2005-04-16 15:20:36 -07002298 } else if (code == MT_ST_WRITE_THRESHOLD) {
2299 /* Retained for compatibility */
2300 } else if (code == MT_ST_DEF_BLKSIZE) {
2301 value = (options & ~MT_ST_OPTIONS);
2302 if (value == ~MT_ST_OPTIONS) {
2303 STm->default_blksize = (-1);
Hannes Reineckeb30d8bc2014-06-25 16:39:57 +02002304 DEBC_printk(STp, "Default block size disabled.\n");
Linus Torvalds1da177e2005-04-16 15:20:36 -07002305 } else {
2306 STm->default_blksize = value;
Hannes Reineckeb30d8bc2014-06-25 16:39:57 +02002307 DEBC_printk(STp,"Default block size set to "
2308 "%d bytes.\n", STm->default_blksize);
Linus Torvalds1da177e2005-04-16 15:20:36 -07002309 if (STp->ready == ST_READY) {
2310 STp->blksize_changed = 0;
2311 set_mode_densblk(STp, STm);
2312 }
2313 }
2314 } else if (code == MT_ST_TIMEOUTS) {
2315 value = (options & ~MT_ST_OPTIONS);
2316 if ((value & MT_ST_SET_LONG_TIMEOUT) != 0) {
2317 STp->long_timeout = (value & ~MT_ST_SET_LONG_TIMEOUT) * HZ;
Hannes Reineckeb30d8bc2014-06-25 16:39:57 +02002318 DEBC_printk(STp, "Long timeout set to %d seconds.\n",
2319 (value & ~MT_ST_SET_LONG_TIMEOUT));
Linus Torvalds1da177e2005-04-16 15:20:36 -07002320 } else {
James Bottomleya02488e2008-11-30 10:36:26 -06002321 blk_queue_rq_timeout(STp->device->request_queue,
2322 value * HZ);
Hannes Reineckeb30d8bc2014-06-25 16:39:57 +02002323 DEBC_printk(STp, "Normal timeout set to %d seconds.\n",
2324 value);
Linus Torvalds1da177e2005-04-16 15:20:36 -07002325 }
2326 } else if (code == MT_ST_SET_CLN) {
2327 value = (options & ~MT_ST_OPTIONS) & 0xff;
2328 if (value != 0 &&
Roel Kluin832151f2009-11-17 14:53:22 -08002329 (value < EXTENDED_SENSE_START ||
2330 value >= SCSI_SENSE_BUFFERSIZE))
Linus Torvalds1da177e2005-04-16 15:20:36 -07002331 return (-EINVAL);
2332 STp->cln_mode = value;
2333 STp->cln_sense_mask = (options >> 8) & 0xff;
2334 STp->cln_sense_value = (options >> 16) & 0xff;
Hannes Reineckeb30d8bc2014-06-25 16:39:57 +02002335 st_printk(KERN_INFO, STp,
2336 "Cleaning request mode %d, mask %02x, value %02x\n",
2337 value, STp->cln_sense_mask, STp->cln_sense_value);
Linus Torvalds1da177e2005-04-16 15:20:36 -07002338 } else if (code == MT_ST_DEF_OPTIONS) {
2339 code = (options & ~MT_ST_CLEAR_DEFAULT);
2340 value = (options & MT_ST_CLEAR_DEFAULT);
2341 if (code == MT_ST_DEF_DENSITY) {
2342 if (value == MT_ST_CLEAR_DEFAULT) {
2343 STm->default_density = (-1);
Hannes Reineckeb30d8bc2014-06-25 16:39:57 +02002344 DEBC_printk(STp,
2345 "Density default disabled.\n");
Linus Torvalds1da177e2005-04-16 15:20:36 -07002346 } else {
2347 STm->default_density = value & 0xff;
Hannes Reineckeb30d8bc2014-06-25 16:39:57 +02002348 DEBC_printk(STp, "Density default set to %x\n",
2349 STm->default_density);
Linus Torvalds1da177e2005-04-16 15:20:36 -07002350 if (STp->ready == ST_READY) {
2351 STp->density_changed = 0;
2352 set_mode_densblk(STp, STm);
2353 }
2354 }
2355 } else if (code == MT_ST_DEF_DRVBUFFER) {
2356 if (value == MT_ST_CLEAR_DEFAULT) {
2357 STp->default_drvbuffer = 0xff;
Hannes Reineckeb30d8bc2014-06-25 16:39:57 +02002358 DEBC_printk(STp,
2359 "Drive buffer default disabled.\n");
Linus Torvalds1da177e2005-04-16 15:20:36 -07002360 } else {
2361 STp->default_drvbuffer = value & 7;
Hannes Reineckeb30d8bc2014-06-25 16:39:57 +02002362 DEBC_printk(STp,
2363 "Drive buffer default set to %x\n",
2364 STp->default_drvbuffer);
Linus Torvalds1da177e2005-04-16 15:20:36 -07002365 if (STp->ready == ST_READY)
2366 st_int_ioctl(STp, MTSETDRVBUFFER, STp->default_drvbuffer);
2367 }
2368 } else if (code == MT_ST_DEF_COMPRESSION) {
2369 if (value == MT_ST_CLEAR_DEFAULT) {
2370 STm->default_compression = ST_DONT_TOUCH;
Hannes Reineckeb30d8bc2014-06-25 16:39:57 +02002371 DEBC_printk(STp,
2372 "Compression default disabled.\n");
Linus Torvalds1da177e2005-04-16 15:20:36 -07002373 } else {
2374 if ((value & 0xff00) != 0) {
2375 STp->c_algo = (value & 0xff00) >> 8;
Hannes Reineckeb30d8bc2014-06-25 16:39:57 +02002376 DEBC_printk(STp, "Compression "
2377 "algorithm set to 0x%x.\n",
2378 STp->c_algo);
Linus Torvalds1da177e2005-04-16 15:20:36 -07002379 }
2380 if ((value & 0xff) != 0xff) {
2381 STm->default_compression = (value & 1 ? ST_YES : ST_NO);
Hannes Reineckeb30d8bc2014-06-25 16:39:57 +02002382 DEBC_printk(STp, "Compression default "
2383 "set to %x\n",
2384 (value & 1));
Linus Torvalds1da177e2005-04-16 15:20:36 -07002385 if (STp->ready == ST_READY) {
2386 STp->compression_changed = 0;
2387 st_compression(STp, (STm->default_compression == ST_YES));
2388 }
2389 }
2390 }
2391 }
2392 } else
2393 return (-EIO);
2394
2395 return 0;
2396}
2397
2398#define MODE_HEADER_LENGTH 4
2399
2400/* Mode header and page byte offsets */
2401#define MH_OFF_DATA_LENGTH 0
2402#define MH_OFF_MEDIUM_TYPE 1
2403#define MH_OFF_DEV_SPECIFIC 2
2404#define MH_OFF_BDESCS_LENGTH 3
2405#define MP_OFF_PAGE_NBR 0
2406#define MP_OFF_PAGE_LENGTH 1
2407
2408/* Mode header and page bit masks */
2409#define MH_BIT_WP 0x80
2410#define MP_MSK_PAGE_NBR 0x3f
2411
2412/* Don't return block descriptors */
2413#define MODE_SENSE_OMIT_BDESCS 0x08
2414
2415#define MODE_SELECT_PAGE_FORMAT 0x10
2416
2417/* Read a mode page into the tape buffer. The block descriptors are included
2418 if incl_block_descs is true. The page control is ored to the page number
2419 parameter, if necessary. */
2420static int read_mode_page(struct scsi_tape *STp, int page, int omit_block_descs)
2421{
2422 unsigned char cmd[MAX_COMMAND_SIZE];
FUJITA Tomonori8ecf0d92008-12-05 15:25:28 +09002423 struct st_request *SRpnt;
Linus Torvalds1da177e2005-04-16 15:20:36 -07002424
2425 memset(cmd, 0, MAX_COMMAND_SIZE);
2426 cmd[0] = MODE_SENSE;
2427 if (omit_block_descs)
2428 cmd[1] = MODE_SENSE_OMIT_BDESCS;
2429 cmd[2] = page;
2430 cmd[4] = 255;
2431
Kai Makisara02ae2c02008-12-18 14:49:50 +09002432 SRpnt = st_do_scsi(NULL, STp, cmd, cmd[4], DMA_FROM_DEVICE,
2433 STp->device->request_queue->rq_timeout, 0, 1);
2434 if (SRpnt == NULL)
2435 return (STp->buffer)->syscall_result;
Linus Torvalds1da177e2005-04-16 15:20:36 -07002436
Mike Christie8b05b772005-11-08 04:06:44 -06002437 st_release_request(SRpnt);
Linus Torvalds1da177e2005-04-16 15:20:36 -07002438
Kai Makisara02ae2c02008-12-18 14:49:50 +09002439 return STp->buffer->syscall_result;
Linus Torvalds1da177e2005-04-16 15:20:36 -07002440}
2441
2442
2443/* Send the mode page in the tape buffer to the drive. Assumes that the mode data
2444 in the buffer is correctly formatted. The long timeout is used if slow is non-zero. */
2445static int write_mode_page(struct scsi_tape *STp, int page, int slow)
2446{
Kai Makisara02ae2c02008-12-18 14:49:50 +09002447 int pgo;
Linus Torvalds1da177e2005-04-16 15:20:36 -07002448 unsigned char cmd[MAX_COMMAND_SIZE];
FUJITA Tomonori18c87012008-12-05 15:25:29 +09002449 struct st_request *SRpnt;
Kai Makisara02ae2c02008-12-18 14:49:50 +09002450 int timeout;
Linus Torvalds1da177e2005-04-16 15:20:36 -07002451
2452 memset(cmd, 0, MAX_COMMAND_SIZE);
2453 cmd[0] = MODE_SELECT;
2454 cmd[1] = MODE_SELECT_PAGE_FORMAT;
2455 pgo = MODE_HEADER_LENGTH + (STp->buffer)->b_data[MH_OFF_BDESCS_LENGTH];
2456 cmd[4] = pgo + (STp->buffer)->b_data[pgo + MP_OFF_PAGE_LENGTH] + 2;
2457
2458 /* Clear reserved fields */
2459 (STp->buffer)->b_data[MH_OFF_DATA_LENGTH] = 0;
2460 (STp->buffer)->b_data[MH_OFF_MEDIUM_TYPE] = 0;
2461 (STp->buffer)->b_data[MH_OFF_DEV_SPECIFIC] &= ~MH_BIT_WP;
2462 (STp->buffer)->b_data[pgo + MP_OFF_PAGE_NBR] &= MP_MSK_PAGE_NBR;
2463
Kai Makisara02ae2c02008-12-18 14:49:50 +09002464 timeout = slow ?
2465 STp->long_timeout : STp->device->request_queue->rq_timeout;
2466 SRpnt = st_do_scsi(NULL, STp, cmd, cmd[4], DMA_TO_DEVICE,
2467 timeout, 0, 1);
2468 if (SRpnt == NULL)
2469 return (STp->buffer)->syscall_result;
Linus Torvalds1da177e2005-04-16 15:20:36 -07002470
Mike Christie8b05b772005-11-08 04:06:44 -06002471 st_release_request(SRpnt);
Linus Torvalds1da177e2005-04-16 15:20:36 -07002472
Kai Makisara02ae2c02008-12-18 14:49:50 +09002473 return STp->buffer->syscall_result;
Linus Torvalds1da177e2005-04-16 15:20:36 -07002474}
2475
2476
2477#define COMPRESSION_PAGE 0x0f
2478#define COMPRESSION_PAGE_LENGTH 16
2479
2480#define CP_OFF_DCE_DCC 2
2481#define CP_OFF_C_ALGO 7
2482
2483#define DCE_MASK 0x80
2484#define DCC_MASK 0x40
2485#define RED_MASK 0x60
2486
2487
2488/* Control the compression with mode page 15. Algorithm not changed if zero.
2489
2490 The block descriptors are read and written because Sony SDT-7000 does not
2491 work without this (suggestion from Michael Schaefer <Michael.Schaefer@dlr.de>).
2492 Including block descriptors should not cause any harm to other drives. */
2493
2494static int st_compression(struct scsi_tape * STp, int state)
2495{
2496 int retval;
2497 int mpoffs; /* Offset to mode page start */
2498 unsigned char *b_data = (STp->buffer)->b_data;
Linus Torvalds1da177e2005-04-16 15:20:36 -07002499
2500 if (STp->ready != ST_READY)
2501 return (-EIO);
2502
2503 /* Read the current page contents */
2504 retval = read_mode_page(STp, COMPRESSION_PAGE, 0);
2505 if (retval) {
Hannes Reineckeb30d8bc2014-06-25 16:39:57 +02002506 DEBC_printk(STp, "Compression mode page not supported.\n");
Linus Torvalds1da177e2005-04-16 15:20:36 -07002507 return (-EIO);
2508 }
2509
2510 mpoffs = MODE_HEADER_LENGTH + b_data[MH_OFF_BDESCS_LENGTH];
Hannes Reineckeb30d8bc2014-06-25 16:39:57 +02002511 DEBC_printk(STp, "Compression state is %d.\n",
2512 (b_data[mpoffs + CP_OFF_DCE_DCC] & DCE_MASK ? 1 : 0));
Linus Torvalds1da177e2005-04-16 15:20:36 -07002513
2514 /* Check if compression can be changed */
2515 if ((b_data[mpoffs + CP_OFF_DCE_DCC] & DCC_MASK) == 0) {
Hannes Reineckeb30d8bc2014-06-25 16:39:57 +02002516 DEBC_printk(STp, "Compression not supported.\n");
Linus Torvalds1da177e2005-04-16 15:20:36 -07002517 return (-EIO);
2518 }
2519
2520 /* Do the change */
2521 if (state) {
2522 b_data[mpoffs + CP_OFF_DCE_DCC] |= DCE_MASK;
2523 if (STp->c_algo != 0)
2524 b_data[mpoffs + CP_OFF_C_ALGO] = STp->c_algo;
2525 }
2526 else {
2527 b_data[mpoffs + CP_OFF_DCE_DCC] &= ~DCE_MASK;
2528 if (STp->c_algo != 0)
2529 b_data[mpoffs + CP_OFF_C_ALGO] = 0; /* no compression */
2530 }
2531
2532 retval = write_mode_page(STp, COMPRESSION_PAGE, 0);
2533 if (retval) {
Hannes Reineckeb30d8bc2014-06-25 16:39:57 +02002534 DEBC_printk(STp, "Compression change failed.\n");
Linus Torvalds1da177e2005-04-16 15:20:36 -07002535 return (-EIO);
2536 }
Hannes Reineckeb30d8bc2014-06-25 16:39:57 +02002537 DEBC_printk(STp, "Compression state changed to %d.\n", state);
Linus Torvalds1da177e2005-04-16 15:20:36 -07002538
2539 STp->compression_changed = 1;
2540 return 0;
2541}
2542
2543
2544/* Process the load and unload commands (does unload if the load code is zero) */
2545static int do_load_unload(struct scsi_tape *STp, struct file *filp, int load_code)
2546{
2547 int retval = (-EIO), timeout;
Linus Torvalds1da177e2005-04-16 15:20:36 -07002548 unsigned char cmd[MAX_COMMAND_SIZE];
2549 struct st_partstat *STps;
Mike Christie8b05b772005-11-08 04:06:44 -06002550 struct st_request *SRpnt;
Linus Torvalds1da177e2005-04-16 15:20:36 -07002551
2552 if (STp->ready != ST_READY && !load_code) {
2553 if (STp->ready == ST_NO_TAPE)
2554 return (-ENOMEDIUM);
2555 else
2556 return (-EIO);
2557 }
2558
2559 memset(cmd, 0, MAX_COMMAND_SIZE);
2560 cmd[0] = START_STOP;
2561 if (load_code)
2562 cmd[4] |= 1;
2563 /*
2564 * If arg >= 1 && arg <= 6 Enhanced load/unload in HP C1553A
2565 */
2566 if (load_code >= 1 + MT_ST_HPLOADER_OFFSET
2567 && load_code <= 6 + MT_ST_HPLOADER_OFFSET) {
Hannes Reineckeb30d8bc2014-06-25 16:39:57 +02002568 DEBC_printk(STp, " Enhanced %sload slot %2d.\n",
2569 (cmd[4]) ? "" : "un",
2570 load_code - MT_ST_HPLOADER_OFFSET);
Linus Torvalds1da177e2005-04-16 15:20:36 -07002571 cmd[3] = load_code - MT_ST_HPLOADER_OFFSET; /* MediaID field of C1553A */
2572 }
2573 if (STp->immediate) {
2574 cmd[1] = 1; /* Don't wait for completion */
James Bottomleya02488e2008-11-30 10:36:26 -06002575 timeout = STp->device->request_queue->rq_timeout;
Linus Torvalds1da177e2005-04-16 15:20:36 -07002576 }
2577 else
2578 timeout = STp->long_timeout;
2579
2580 DEBC(
2581 if (!load_code)
Hannes Reineckeb30d8bc2014-06-25 16:39:57 +02002582 st_printk(ST_DEB_MSG, STp, "Unloading tape.\n");
Linus Torvalds1da177e2005-04-16 15:20:36 -07002583 else
Hannes Reineckeb30d8bc2014-06-25 16:39:57 +02002584 st_printk(ST_DEB_MSG, STp, "Loading tape.\n");
Linus Torvalds1da177e2005-04-16 15:20:36 -07002585 );
2586
Kai Makisara02ae2c02008-12-18 14:49:50 +09002587 SRpnt = st_do_scsi(NULL, STp, cmd, 0, DMA_NONE,
2588 timeout, MAX_RETRIES, 1);
Linus Torvalds1da177e2005-04-16 15:20:36 -07002589 if (!SRpnt)
Kai Makisara02ae2c02008-12-18 14:49:50 +09002590 return (STp->buffer)->syscall_result;
Linus Torvalds1da177e2005-04-16 15:20:36 -07002591
2592 retval = (STp->buffer)->syscall_result;
Kai Makisara02ae2c02008-12-18 14:49:50 +09002593 st_release_request(SRpnt);
Linus Torvalds1da177e2005-04-16 15:20:36 -07002594
2595 if (!retval) { /* SCSI command successful */
2596
2597 if (!load_code) {
2598 STp->rew_at_close = 0;
2599 STp->ready = ST_NO_TAPE;
2600 }
2601 else {
2602 STp->rew_at_close = STp->autorew_dev;
2603 retval = check_tape(STp, filp);
2604 if (retval > 0)
2605 retval = 0;
2606 }
2607 }
2608 else {
2609 STps = &(STp->ps[STp->partition]);
2610 STps->drv_file = STps->drv_block = (-1);
2611 }
2612
2613 return retval;
2614}
2615
2616#if DEBUG
2617#define ST_DEB_FORWARD 0
2618#define ST_DEB_BACKWARD 1
Hannes Reineckeb30d8bc2014-06-25 16:39:57 +02002619static void deb_space_print(struct scsi_tape *STp, int direction, char *units, unsigned char *cmd)
Linus Torvalds1da177e2005-04-16 15:20:36 -07002620{
2621 s32 sc;
2622
Hannes Reineckeb30d8bc2014-06-25 16:39:57 +02002623 if (!debugging)
2624 return;
2625
Linus Torvalds1da177e2005-04-16 15:20:36 -07002626 sc = cmd[2] & 0x80 ? 0xff000000 : 0;
2627 sc |= (cmd[2] << 16) | (cmd[3] << 8) | cmd[4];
2628 if (direction)
2629 sc = -sc;
Hannes Reineckeb30d8bc2014-06-25 16:39:57 +02002630 st_printk(ST_DEB_MSG, STp, "Spacing tape %s over %d %s.\n",
2631 direction ? "backward" : "forward", sc, units);
Linus Torvalds1da177e2005-04-16 15:20:36 -07002632}
Hannes Reineckeb30d8bc2014-06-25 16:39:57 +02002633#else
2634#define ST_DEB_FORWARD 0
2635#define ST_DEB_BACKWARD 1
2636static void deb_space_print(struct scsi_tape *STp, int direction, char *units, unsigned char *cmd) {}
Linus Torvalds1da177e2005-04-16 15:20:36 -07002637#endif
2638
2639
2640/* Internal ioctl function */
2641static int st_int_ioctl(struct scsi_tape *STp, unsigned int cmd_in, unsigned long arg)
2642{
2643 int timeout;
2644 long ltmp;
2645 int ioctl_result;
2646 int chg_eof = 1;
2647 unsigned char cmd[MAX_COMMAND_SIZE];
Mike Christie8b05b772005-11-08 04:06:44 -06002648 struct st_request *SRpnt;
Linus Torvalds1da177e2005-04-16 15:20:36 -07002649 struct st_partstat *STps;
2650 int fileno, blkno, at_sm, undone;
2651 int datalen = 0, direction = DMA_NONE;
Linus Torvalds1da177e2005-04-16 15:20:36 -07002652
2653 WARN_ON(STp->buffer->do_dio != 0);
2654 if (STp->ready != ST_READY) {
2655 if (STp->ready == ST_NO_TAPE)
2656 return (-ENOMEDIUM);
2657 else
2658 return (-EIO);
2659 }
2660 timeout = STp->long_timeout;
2661 STps = &(STp->ps[STp->partition]);
2662 fileno = STps->drv_file;
2663 blkno = STps->drv_block;
2664 at_sm = STps->at_sm;
2665
2666 memset(cmd, 0, MAX_COMMAND_SIZE);
2667 switch (cmd_in) {
2668 case MTFSFM:
2669 chg_eof = 0; /* Changed from the FSF after this */
2670 case MTFSF:
2671 cmd[0] = SPACE;
2672 cmd[1] = 0x01; /* Space FileMarks */
2673 cmd[2] = (arg >> 16);
2674 cmd[3] = (arg >> 8);
2675 cmd[4] = arg;
Hannes Reineckeb30d8bc2014-06-25 16:39:57 +02002676 deb_space_print(STp, ST_DEB_FORWARD, "filemarks", cmd);
Linus Torvalds1da177e2005-04-16 15:20:36 -07002677 if (fileno >= 0)
2678 fileno += arg;
2679 blkno = 0;
2680 at_sm &= (arg == 0);
2681 break;
2682 case MTBSFM:
2683 chg_eof = 0; /* Changed from the FSF after this */
2684 case MTBSF:
2685 cmd[0] = SPACE;
2686 cmd[1] = 0x01; /* Space FileMarks */
2687 ltmp = (-arg);
2688 cmd[2] = (ltmp >> 16);
2689 cmd[3] = (ltmp >> 8);
2690 cmd[4] = ltmp;
Hannes Reineckeb30d8bc2014-06-25 16:39:57 +02002691 deb_space_print(STp, ST_DEB_BACKWARD, "filemarks", cmd);
Linus Torvalds1da177e2005-04-16 15:20:36 -07002692 if (fileno >= 0)
2693 fileno -= arg;
2694 blkno = (-1); /* We can't know the block number */
2695 at_sm &= (arg == 0);
2696 break;
2697 case MTFSR:
2698 cmd[0] = SPACE;
2699 cmd[1] = 0x00; /* Space Blocks */
2700 cmd[2] = (arg >> 16);
2701 cmd[3] = (arg >> 8);
2702 cmd[4] = arg;
Hannes Reineckeb30d8bc2014-06-25 16:39:57 +02002703 deb_space_print(STp, ST_DEB_FORWARD, "blocks", cmd);
Linus Torvalds1da177e2005-04-16 15:20:36 -07002704 if (blkno >= 0)
2705 blkno += arg;
2706 at_sm &= (arg == 0);
2707 break;
2708 case MTBSR:
2709 cmd[0] = SPACE;
2710 cmd[1] = 0x00; /* Space Blocks */
2711 ltmp = (-arg);
2712 cmd[2] = (ltmp >> 16);
2713 cmd[3] = (ltmp >> 8);
2714 cmd[4] = ltmp;
Hannes Reineckeb30d8bc2014-06-25 16:39:57 +02002715 deb_space_print(STp, ST_DEB_BACKWARD, "blocks", cmd);
Linus Torvalds1da177e2005-04-16 15:20:36 -07002716 if (blkno >= 0)
2717 blkno -= arg;
2718 at_sm &= (arg == 0);
2719 break;
2720 case MTFSS:
2721 cmd[0] = SPACE;
2722 cmd[1] = 0x04; /* Space Setmarks */
2723 cmd[2] = (arg >> 16);
2724 cmd[3] = (arg >> 8);
2725 cmd[4] = arg;
Hannes Reineckeb30d8bc2014-06-25 16:39:57 +02002726 deb_space_print(STp, ST_DEB_FORWARD, "setmarks", cmd);
Linus Torvalds1da177e2005-04-16 15:20:36 -07002727 if (arg != 0) {
2728 blkno = fileno = (-1);
2729 at_sm = 1;
2730 }
2731 break;
2732 case MTBSS:
2733 cmd[0] = SPACE;
2734 cmd[1] = 0x04; /* Space Setmarks */
2735 ltmp = (-arg);
2736 cmd[2] = (ltmp >> 16);
2737 cmd[3] = (ltmp >> 8);
2738 cmd[4] = ltmp;
Hannes Reineckeb30d8bc2014-06-25 16:39:57 +02002739 deb_space_print(STp, ST_DEB_BACKWARD, "setmarks", cmd);
Linus Torvalds1da177e2005-04-16 15:20:36 -07002740 if (arg != 0) {
2741 blkno = fileno = (-1);
2742 at_sm = 1;
2743 }
2744 break;
2745 case MTWEOF:
Kai Makisara3e51d3c2010-10-09 00:17:56 +03002746 case MTWEOFI:
Linus Torvalds1da177e2005-04-16 15:20:36 -07002747 case MTWSM:
2748 if (STp->write_prot)
2749 return (-EACCES);
2750 cmd[0] = WRITE_FILEMARKS;
2751 if (cmd_in == MTWSM)
2752 cmd[1] = 2;
Lee Duncanc743e442012-03-01 12:41:01 -08002753 if (cmd_in == MTWEOFI ||
2754 (cmd_in == MTWEOF && STp->immediate_filemark))
Kai Makisara3e51d3c2010-10-09 00:17:56 +03002755 cmd[1] |= 1;
Linus Torvalds1da177e2005-04-16 15:20:36 -07002756 cmd[2] = (arg >> 16);
2757 cmd[3] = (arg >> 8);
2758 cmd[4] = arg;
James Bottomleya02488e2008-11-30 10:36:26 -06002759 timeout = STp->device->request_queue->rq_timeout;
Hannes Reineckeb30d8bc2014-06-25 16:39:57 +02002760 DEBC(
2761 if (cmd_in != MTWSM)
2762 st_printk(ST_DEB_MSG, STp,
2763 "Writing %d filemarks.\n",
2764 cmd[2] * 65536 +
2765 cmd[3] * 256 +
2766 cmd[4]);
2767 else
2768 st_printk(ST_DEB_MSG, STp,
2769 "Writing %d setmarks.\n",
2770 cmd[2] * 65536 +
2771 cmd[3] * 256 +
2772 cmd[4]);
Linus Torvalds1da177e2005-04-16 15:20:36 -07002773 )
2774 if (fileno >= 0)
2775 fileno += arg;
2776 blkno = 0;
2777 at_sm = (cmd_in == MTWSM);
2778 break;
2779 case MTREW:
2780 cmd[0] = REZERO_UNIT;
2781 if (STp->immediate) {
2782 cmd[1] = 1; /* Don't wait for completion */
James Bottomleya02488e2008-11-30 10:36:26 -06002783 timeout = STp->device->request_queue->rq_timeout;
Linus Torvalds1da177e2005-04-16 15:20:36 -07002784 }
Hannes Reineckeb30d8bc2014-06-25 16:39:57 +02002785 DEBC_printk(STp, "Rewinding tape.\n");
Linus Torvalds1da177e2005-04-16 15:20:36 -07002786 fileno = blkno = at_sm = 0;
2787 break;
2788 case MTNOP:
Hannes Reineckeb30d8bc2014-06-25 16:39:57 +02002789 DEBC_printk(STp, "No op on tape.\n");
Linus Torvalds1da177e2005-04-16 15:20:36 -07002790 return 0; /* Should do something ? */
2791 break;
2792 case MTRETEN:
2793 cmd[0] = START_STOP;
2794 if (STp->immediate) {
2795 cmd[1] = 1; /* Don't wait for completion */
James Bottomleya02488e2008-11-30 10:36:26 -06002796 timeout = STp->device->request_queue->rq_timeout;
Linus Torvalds1da177e2005-04-16 15:20:36 -07002797 }
2798 cmd[4] = 3;
Hannes Reineckeb30d8bc2014-06-25 16:39:57 +02002799 DEBC_printk(STp, "Retensioning tape.\n");
Linus Torvalds1da177e2005-04-16 15:20:36 -07002800 fileno = blkno = at_sm = 0;
2801 break;
2802 case MTEOM:
2803 if (!STp->fast_mteom) {
2804 /* space to the end of tape */
2805 ioctl_result = st_int_ioctl(STp, MTFSF, 0x7fffff);
2806 fileno = STps->drv_file;
2807 if (STps->eof >= ST_EOD_1)
2808 return 0;
2809 /* The next lines would hide the number of spaced FileMarks
2810 That's why I inserted the previous lines. I had no luck
2811 with detecting EOM with FSF, so we go now to EOM.
2812 Joerg Weule */
2813 } else
2814 fileno = (-1);
2815 cmd[0] = SPACE;
2816 cmd[1] = 3;
Hannes Reineckeb30d8bc2014-06-25 16:39:57 +02002817 DEBC_printk(STp, "Spacing to end of recorded medium.\n");
Linus Torvalds1da177e2005-04-16 15:20:36 -07002818 blkno = -1;
2819 at_sm = 0;
2820 break;
2821 case MTERASE:
2822 if (STp->write_prot)
2823 return (-EACCES);
2824 cmd[0] = ERASE;
2825 cmd[1] = (arg ? 1 : 0); /* Long erase with non-zero argument */
2826 if (STp->immediate) {
2827 cmd[1] |= 2; /* Don't wait for completion */
James Bottomleya02488e2008-11-30 10:36:26 -06002828 timeout = STp->device->request_queue->rq_timeout;
Linus Torvalds1da177e2005-04-16 15:20:36 -07002829 }
2830 else
2831 timeout = STp->long_timeout * 8;
2832
Hannes Reineckeb30d8bc2014-06-25 16:39:57 +02002833 DEBC_printk(STp, "Erasing tape.\n");
Linus Torvalds1da177e2005-04-16 15:20:36 -07002834 fileno = blkno = at_sm = 0;
2835 break;
2836 case MTSETBLK: /* Set block length */
2837 case MTSETDENSITY: /* Set tape density */
2838 case MTSETDRVBUFFER: /* Set drive buffering */
2839 case SET_DENS_AND_BLK: /* Set density and block size */
2840 chg_eof = 0;
2841 if (STp->dirty || (STp->buffer)->buffer_bytes != 0)
2842 return (-EIO); /* Not allowed if data in buffer */
2843 if ((cmd_in == MTSETBLK || cmd_in == SET_DENS_AND_BLK) &&
2844 (arg & MT_ST_BLKSIZE_MASK) != 0 &&
2845 STp->max_block > 0 &&
2846 ((arg & MT_ST_BLKSIZE_MASK) < STp->min_block ||
2847 (arg & MT_ST_BLKSIZE_MASK) > STp->max_block)) {
Hannes Reineckeb30d8bc2014-06-25 16:39:57 +02002848 st_printk(KERN_WARNING, STp, "Illegal block size.\n");
Linus Torvalds1da177e2005-04-16 15:20:36 -07002849 return (-EINVAL);
2850 }
2851 cmd[0] = MODE_SELECT;
2852 if ((STp->use_pf & USE_PF))
2853 cmd[1] = MODE_SELECT_PAGE_FORMAT;
2854 cmd[4] = datalen = 12;
2855 direction = DMA_TO_DEVICE;
2856
2857 memset((STp->buffer)->b_data, 0, 12);
2858 if (cmd_in == MTSETDRVBUFFER)
2859 (STp->buffer)->b_data[2] = (arg & 7) << 4;
2860 else
2861 (STp->buffer)->b_data[2] =
2862 STp->drv_buffer << 4;
2863 (STp->buffer)->b_data[3] = 8; /* block descriptor length */
2864 if (cmd_in == MTSETDENSITY) {
2865 (STp->buffer)->b_data[4] = arg;
2866 STp->density_changed = 1; /* At least we tried ;-) */
2867 } else if (cmd_in == SET_DENS_AND_BLK)
2868 (STp->buffer)->b_data[4] = arg >> 24;
2869 else
2870 (STp->buffer)->b_data[4] = STp->density;
2871 if (cmd_in == MTSETBLK || cmd_in == SET_DENS_AND_BLK) {
2872 ltmp = arg & MT_ST_BLKSIZE_MASK;
2873 if (cmd_in == MTSETBLK)
2874 STp->blksize_changed = 1; /* At least we tried ;-) */
2875 } else
2876 ltmp = STp->block_size;
2877 (STp->buffer)->b_data[9] = (ltmp >> 16);
2878 (STp->buffer)->b_data[10] = (ltmp >> 8);
2879 (STp->buffer)->b_data[11] = ltmp;
James Bottomleya02488e2008-11-30 10:36:26 -06002880 timeout = STp->device->request_queue->rq_timeout;
Hannes Reineckeb30d8bc2014-06-25 16:39:57 +02002881 DEBC(
Linus Torvalds1da177e2005-04-16 15:20:36 -07002882 if (cmd_in == MTSETBLK || cmd_in == SET_DENS_AND_BLK)
Hannes Reineckeb30d8bc2014-06-25 16:39:57 +02002883 st_printk(ST_DEB_MSG, STp,
2884 "Setting block size to %d bytes.\n",
2885 (STp->buffer)->b_data[9] * 65536 +
2886 (STp->buffer)->b_data[10] * 256 +
2887 (STp->buffer)->b_data[11]);
Linus Torvalds1da177e2005-04-16 15:20:36 -07002888 if (cmd_in == MTSETDENSITY || cmd_in == SET_DENS_AND_BLK)
Hannes Reineckeb30d8bc2014-06-25 16:39:57 +02002889 st_printk(ST_DEB_MSG, STp,
2890 "Setting density code to %x.\n",
2891 (STp->buffer)->b_data[4]);
Linus Torvalds1da177e2005-04-16 15:20:36 -07002892 if (cmd_in == MTSETDRVBUFFER)
Hannes Reineckeb30d8bc2014-06-25 16:39:57 +02002893 st_printk(ST_DEB_MSG, STp,
2894 "Setting drive buffer code to %d.\n",
2895 ((STp->buffer)->b_data[2] >> 4) & 7);
Linus Torvalds1da177e2005-04-16 15:20:36 -07002896 )
2897 break;
2898 default:
2899 return (-ENOSYS);
2900 }
2901
Kai Makisara02ae2c02008-12-18 14:49:50 +09002902 SRpnt = st_do_scsi(NULL, STp, cmd, datalen, direction,
2903 timeout, MAX_RETRIES, 1);
Linus Torvalds1da177e2005-04-16 15:20:36 -07002904 if (!SRpnt)
2905 return (STp->buffer)->syscall_result;
2906
Kai Makisara02ae2c02008-12-18 14:49:50 +09002907 ioctl_result = (STp->buffer)->syscall_result;
Linus Torvalds1da177e2005-04-16 15:20:36 -07002908
2909 if (!ioctl_result) { /* SCSI command successful */
Mike Christie8b05b772005-11-08 04:06:44 -06002910 st_release_request(SRpnt);
Linus Torvalds1da177e2005-04-16 15:20:36 -07002911 SRpnt = NULL;
2912 STps->drv_block = blkno;
2913 STps->drv_file = fileno;
2914 STps->at_sm = at_sm;
2915
2916 if (cmd_in == MTBSFM)
2917 ioctl_result = st_int_ioctl(STp, MTFSF, 1);
2918 else if (cmd_in == MTFSFM)
2919 ioctl_result = st_int_ioctl(STp, MTBSF, 1);
2920
2921 if (cmd_in == MTSETBLK || cmd_in == SET_DENS_AND_BLK) {
Linus Torvalds1da177e2005-04-16 15:20:36 -07002922 STp->block_size = arg & MT_ST_BLKSIZE_MASK;
2923 if (STp->block_size != 0) {
Linus Torvalds1da177e2005-04-16 15:20:36 -07002924 (STp->buffer)->buffer_blocks =
2925 (STp->buffer)->buffer_size / STp->block_size;
2926 }
2927 (STp->buffer)->buffer_bytes = (STp->buffer)->read_pointer = 0;
2928 if (cmd_in == SET_DENS_AND_BLK)
2929 STp->density = arg >> MT_ST_DENSITY_SHIFT;
2930 } else if (cmd_in == MTSETDRVBUFFER)
2931 STp->drv_buffer = (arg & 7);
2932 else if (cmd_in == MTSETDENSITY)
2933 STp->density = arg;
2934
2935 if (cmd_in == MTEOM)
2936 STps->eof = ST_EOD;
2937 else if (cmd_in == MTFSF)
2938 STps->eof = ST_FM;
2939 else if (chg_eof)
2940 STps->eof = ST_NOEOF;
2941
Kai Makisara3e51d3c2010-10-09 00:17:56 +03002942 if (cmd_in == MTWEOF || cmd_in == MTWEOFI)
2943 STps->rw = ST_IDLE; /* prevent automatic WEOF at close */
Linus Torvalds1da177e2005-04-16 15:20:36 -07002944 } else { /* SCSI command was not completely successful. Don't return
2945 from this block without releasing the SCSI command block! */
2946 struct st_cmdstatus *cmdstatp = &STp->buffer->cmdstat;
2947
2948 if (cmdstatp->flags & SENSE_EOM) {
2949 if (cmd_in != MTBSF && cmd_in != MTBSFM &&
2950 cmd_in != MTBSR && cmd_in != MTBSS)
2951 STps->eof = ST_EOM_OK;
2952 STps->drv_block = 0;
2953 }
2954
2955 if (cmdstatp->remainder_valid)
2956 undone = (int)cmdstatp->uremainder64;
2957 else
2958 undone = 0;
2959
Kai Makisara3e51d3c2010-10-09 00:17:56 +03002960 if ((cmd_in == MTWEOF || cmd_in == MTWEOFI) &&
Linus Torvalds1da177e2005-04-16 15:20:36 -07002961 cmdstatp->have_sense &&
Kai Makisara91614c02007-01-26 00:38:39 +02002962 (cmdstatp->flags & SENSE_EOM)) {
2963 if (cmdstatp->sense_hdr.sense_key == NO_SENSE ||
2964 cmdstatp->sense_hdr.sense_key == RECOVERED_ERROR) {
2965 ioctl_result = 0; /* EOF(s) written successfully at EOM */
2966 STps->eof = ST_NOEOF;
2967 } else { /* Writing EOF(s) failed */
2968 if (fileno >= 0)
2969 fileno -= undone;
2970 if (undone < arg)
2971 STps->eof = ST_NOEOF;
2972 }
Linus Torvalds1da177e2005-04-16 15:20:36 -07002973 STps->drv_file = fileno;
Linus Torvalds1da177e2005-04-16 15:20:36 -07002974 } else if ((cmd_in == MTFSF) || (cmd_in == MTFSFM)) {
2975 if (fileno >= 0)
2976 STps->drv_file = fileno - undone;
2977 else
2978 STps->drv_file = fileno;
2979 STps->drv_block = -1;
2980 STps->eof = ST_NOEOF;
2981 } else if ((cmd_in == MTBSF) || (cmd_in == MTBSFM)) {
2982 if (arg > 0 && undone < 0) /* Some drives get this wrong */
2983 undone = (-undone);
2984 if (STps->drv_file >= 0)
2985 STps->drv_file = fileno + undone;
2986 STps->drv_block = 0;
2987 STps->eof = ST_NOEOF;
2988 } else if (cmd_in == MTFSR) {
2989 if (cmdstatp->flags & SENSE_FMK) { /* Hit filemark */
2990 if (STps->drv_file >= 0)
2991 STps->drv_file++;
2992 STps->drv_block = 0;
2993 STps->eof = ST_FM;
2994 } else {
2995 if (blkno >= undone)
2996 STps->drv_block = blkno - undone;
2997 else
2998 STps->drv_block = (-1);
2999 STps->eof = ST_NOEOF;
3000 }
3001 } else if (cmd_in == MTBSR) {
3002 if (cmdstatp->flags & SENSE_FMK) { /* Hit filemark */
3003 STps->drv_file--;
3004 STps->drv_block = (-1);
3005 } else {
3006 if (arg > 0 && undone < 0) /* Some drives get this wrong */
3007 undone = (-undone);
3008 if (STps->drv_block >= 0)
3009 STps->drv_block = blkno + undone;
3010 }
3011 STps->eof = ST_NOEOF;
3012 } else if (cmd_in == MTEOM) {
3013 STps->drv_file = (-1);
3014 STps->drv_block = (-1);
3015 STps->eof = ST_EOD;
3016 } else if (cmd_in == MTSETBLK ||
3017 cmd_in == MTSETDENSITY ||
3018 cmd_in == MTSETDRVBUFFER ||
3019 cmd_in == SET_DENS_AND_BLK) {
3020 if (cmdstatp->sense_hdr.sense_key == ILLEGAL_REQUEST &&
3021 !(STp->use_pf & PF_TESTED)) {
3022 /* Try the other possible state of Page Format if not
3023 already tried */
Kai Makisara1da20192009-05-02 08:49:34 +03003024 STp->use_pf = (STp->use_pf ^ USE_PF) | PF_TESTED;
Mike Christie8b05b772005-11-08 04:06:44 -06003025 st_release_request(SRpnt);
Linus Torvalds1da177e2005-04-16 15:20:36 -07003026 SRpnt = NULL;
3027 return st_int_ioctl(STp, cmd_in, arg);
3028 }
3029 } else if (chg_eof)
3030 STps->eof = ST_NOEOF;
3031
3032 if (cmdstatp->sense_hdr.sense_key == BLANK_CHECK)
3033 STps->eof = ST_EOD;
3034
Mike Christie8b05b772005-11-08 04:06:44 -06003035 st_release_request(SRpnt);
Linus Torvalds1da177e2005-04-16 15:20:36 -07003036 SRpnt = NULL;
3037 }
3038
3039 return ioctl_result;
3040}
3041
3042
3043/* Get the tape position. If bt == 2, arg points into a kernel space mt_loc
3044 structure. */
3045
3046static int get_location(struct scsi_tape *STp, unsigned int *block, int *partition,
3047 int logical)
3048{
3049 int result;
3050 unsigned char scmd[MAX_COMMAND_SIZE];
Mike Christie8b05b772005-11-08 04:06:44 -06003051 struct st_request *SRpnt;
Linus Torvalds1da177e2005-04-16 15:20:36 -07003052
3053 if (STp->ready != ST_READY)
3054 return (-EIO);
3055
3056 memset(scmd, 0, MAX_COMMAND_SIZE);
3057 if ((STp->device)->scsi_level < SCSI_2) {
3058 scmd[0] = QFA_REQUEST_BLOCK;
3059 scmd[4] = 3;
3060 } else {
3061 scmd[0] = READ_POSITION;
3062 if (!logical && !STp->scsi2_logical)
3063 scmd[1] = 1;
3064 }
Kai Makisara02ae2c02008-12-18 14:49:50 +09003065 SRpnt = st_do_scsi(NULL, STp, scmd, 20, DMA_FROM_DEVICE,
3066 STp->device->request_queue->rq_timeout,
3067 MAX_READY_RETRIES, 1);
Linus Torvalds1da177e2005-04-16 15:20:36 -07003068 if (!SRpnt)
Kai Makisara02ae2c02008-12-18 14:49:50 +09003069 return (STp->buffer)->syscall_result;
Linus Torvalds1da177e2005-04-16 15:20:36 -07003070
3071 if ((STp->buffer)->syscall_result != 0 ||
3072 (STp->device->scsi_level >= SCSI_2 &&
3073 ((STp->buffer)->b_data[0] & 4) != 0)) {
3074 *block = *partition = 0;
Hannes Reineckeb30d8bc2014-06-25 16:39:57 +02003075 DEBC_printk(STp, " Can't read tape position.\n");
Linus Torvalds1da177e2005-04-16 15:20:36 -07003076 result = (-EIO);
3077 } else {
3078 result = 0;
3079 if ((STp->device)->scsi_level < SCSI_2) {
3080 *block = ((STp->buffer)->b_data[0] << 16)
3081 + ((STp->buffer)->b_data[1] << 8)
3082 + (STp->buffer)->b_data[2];
3083 *partition = 0;
3084 } else {
3085 *block = ((STp->buffer)->b_data[4] << 24)
3086 + ((STp->buffer)->b_data[5] << 16)
3087 + ((STp->buffer)->b_data[6] << 8)
3088 + (STp->buffer)->b_data[7];
3089 *partition = (STp->buffer)->b_data[1];
3090 if (((STp->buffer)->b_data[0] & 0x80) &&
3091 (STp->buffer)->b_data[1] == 0) /* BOP of partition 0 */
3092 STp->ps[0].drv_block = STp->ps[0].drv_file = 0;
3093 }
Hannes Reineckeb30d8bc2014-06-25 16:39:57 +02003094 DEBC_printk(STp, "Got tape pos. blk %d part %d.\n",
3095 *block, *partition);
Linus Torvalds1da177e2005-04-16 15:20:36 -07003096 }
Mike Christie8b05b772005-11-08 04:06:44 -06003097 st_release_request(SRpnt);
Linus Torvalds1da177e2005-04-16 15:20:36 -07003098 SRpnt = NULL;
3099
3100 return result;
3101}
3102
3103
3104/* Set the tape block and partition. Negative partition means that only the
3105 block should be set in vendor specific way. */
3106static int set_location(struct scsi_tape *STp, unsigned int block, int partition,
3107 int logical)
3108{
3109 struct st_partstat *STps;
3110 int result, p;
3111 unsigned int blk;
3112 int timeout;
3113 unsigned char scmd[MAX_COMMAND_SIZE];
Mike Christie8b05b772005-11-08 04:06:44 -06003114 struct st_request *SRpnt;
Linus Torvalds1da177e2005-04-16 15:20:36 -07003115
3116 if (STp->ready != ST_READY)
3117 return (-EIO);
3118 timeout = STp->long_timeout;
3119 STps = &(STp->ps[STp->partition]);
3120
Hannes Reineckeb30d8bc2014-06-25 16:39:57 +02003121 DEBC_printk(STp, "Setting block to %d and partition to %d.\n",
3122 block, partition);
Linus Torvalds1da177e2005-04-16 15:20:36 -07003123 DEB(if (partition < 0)
3124 return (-EIO); )
3125
3126 /* Update the location at the partition we are leaving */
3127 if ((!STp->can_partitions && partition != 0) ||
3128 partition >= ST_NBR_PARTITIONS)
3129 return (-EINVAL);
3130 if (partition != STp->partition) {
3131 if (get_location(STp, &blk, &p, 1))
3132 STps->last_block_valid = 0;
3133 else {
3134 STps->last_block_valid = 1;
3135 STps->last_block_visited = blk;
Hannes Reineckeb30d8bc2014-06-25 16:39:57 +02003136 DEBC_printk(STp, "Visited block %d for "
3137 "partition %d saved.\n",
3138 blk, STp->partition);
Linus Torvalds1da177e2005-04-16 15:20:36 -07003139 }
3140 }
3141
3142 memset(scmd, 0, MAX_COMMAND_SIZE);
3143 if ((STp->device)->scsi_level < SCSI_2) {
3144 scmd[0] = QFA_SEEK_BLOCK;
3145 scmd[2] = (block >> 16);
3146 scmd[3] = (block >> 8);
3147 scmd[4] = block;
3148 scmd[5] = 0;
3149 } else {
3150 scmd[0] = SEEK_10;
3151 scmd[3] = (block >> 24);
3152 scmd[4] = (block >> 16);
3153 scmd[5] = (block >> 8);
3154 scmd[6] = block;
3155 if (!logical && !STp->scsi2_logical)
3156 scmd[1] = 4;
3157 if (STp->partition != partition) {
3158 scmd[1] |= 2;
3159 scmd[8] = partition;
Hannes Reineckeb30d8bc2014-06-25 16:39:57 +02003160 DEBC_printk(STp, "Trying to change partition "
3161 "from %d to %d\n", STp->partition,
3162 partition);
Linus Torvalds1da177e2005-04-16 15:20:36 -07003163 }
3164 }
3165 if (STp->immediate) {
3166 scmd[1] |= 1; /* Don't wait for completion */
James Bottomleya02488e2008-11-30 10:36:26 -06003167 timeout = STp->device->request_queue->rq_timeout;
Linus Torvalds1da177e2005-04-16 15:20:36 -07003168 }
3169
Kai Makisara02ae2c02008-12-18 14:49:50 +09003170 SRpnt = st_do_scsi(NULL, STp, scmd, 0, DMA_NONE,
3171 timeout, MAX_READY_RETRIES, 1);
Linus Torvalds1da177e2005-04-16 15:20:36 -07003172 if (!SRpnt)
Kai Makisara02ae2c02008-12-18 14:49:50 +09003173 return (STp->buffer)->syscall_result;
Linus Torvalds1da177e2005-04-16 15:20:36 -07003174
3175 STps->drv_block = STps->drv_file = (-1);
3176 STps->eof = ST_NOEOF;
3177 if ((STp->buffer)->syscall_result != 0) {
3178 result = (-EIO);
3179 if (STp->can_partitions &&
3180 (STp->device)->scsi_level >= SCSI_2 &&
3181 (p = find_partition(STp)) >= 0)
3182 STp->partition = p;
3183 } else {
3184 if (STp->can_partitions) {
3185 STp->partition = partition;
3186 STps = &(STp->ps[partition]);
3187 if (!STps->last_block_valid ||
3188 STps->last_block_visited != block) {
3189 STps->at_sm = 0;
3190 STps->rw = ST_IDLE;
3191 }
3192 } else
3193 STps->at_sm = 0;
3194 if (block == 0)
3195 STps->drv_block = STps->drv_file = 0;
3196 result = 0;
3197 }
Kai Makisara02ae2c02008-12-18 14:49:50 +09003198
Mike Christie8b05b772005-11-08 04:06:44 -06003199 st_release_request(SRpnt);
Linus Torvalds1da177e2005-04-16 15:20:36 -07003200 SRpnt = NULL;
3201
3202 return result;
3203}
3204
3205
3206/* Find the current partition number for the drive status. Called from open and
3207 returns either partition number of negative error code. */
3208static int find_partition(struct scsi_tape *STp)
3209{
3210 int i, partition;
3211 unsigned int block;
3212
3213 if ((i = get_location(STp, &block, &partition, 1)) < 0)
3214 return i;
3215 if (partition >= ST_NBR_PARTITIONS)
3216 return (-EIO);
3217 return partition;
3218}
3219
3220
3221/* Change the partition if necessary */
3222static int switch_partition(struct scsi_tape *STp)
3223{
3224 struct st_partstat *STps;
3225
3226 if (STp->partition == STp->new_partition)
3227 return 0;
3228 STps = &(STp->ps[STp->new_partition]);
3229 if (!STps->last_block_valid)
3230 STps->last_block_visited = 0;
3231 return set_location(STp, STps->last_block_visited, STp->new_partition, 1);
3232}
3233
3234/* Functions for reading and writing the medium partition mode page. */
3235
3236#define PART_PAGE 0x11
3237#define PART_PAGE_FIXED_LENGTH 8
3238
3239#define PP_OFF_MAX_ADD_PARTS 2
3240#define PP_OFF_NBR_ADD_PARTS 3
3241#define PP_OFF_FLAGS 4
3242#define PP_OFF_PART_UNITS 6
3243#define PP_OFF_RESERVED 7
3244
3245#define PP_BIT_IDP 0x20
3246#define PP_MSK_PSUM_MB 0x10
3247
3248/* Get the number of partitions on the tape. As a side effect reads the
3249 mode page into the tape buffer. */
3250static int nbr_partitions(struct scsi_tape *STp)
3251{
3252 int result;
Linus Torvalds1da177e2005-04-16 15:20:36 -07003253
3254 if (STp->ready != ST_READY)
3255 return (-EIO);
3256
3257 result = read_mode_page(STp, PART_PAGE, 1);
3258
3259 if (result) {
Hannes Reineckeb30d8bc2014-06-25 16:39:57 +02003260 DEBC_printk(STp, "Can't read medium partition page.\n");
Linus Torvalds1da177e2005-04-16 15:20:36 -07003261 result = (-EIO);
3262 } else {
3263 result = (STp->buffer)->b_data[MODE_HEADER_LENGTH +
3264 PP_OFF_NBR_ADD_PARTS] + 1;
Hannes Reineckeb30d8bc2014-06-25 16:39:57 +02003265 DEBC_printk(STp, "Number of partitions %d.\n", result);
Linus Torvalds1da177e2005-04-16 15:20:36 -07003266 }
3267
3268 return result;
3269}
3270
3271
3272/* Partition the tape into two partitions if size > 0 or one partition if
3273 size == 0.
3274
3275 The block descriptors are read and written because Sony SDT-7000 does not
3276 work without this (suggestion from Michael Schaefer <Michael.Schaefer@dlr.de>).
3277
3278 My HP C1533A drive returns only one partition size field. This is used to
3279 set the size of partition 1. There is no size field for the default partition.
3280 Michael Schaefer's Sony SDT-7000 returns two descriptors and the second is
3281 used to set the size of partition 1 (this is what the SCSI-3 standard specifies).
3282 The following algorithm is used to accommodate both drives: if the number of
3283 partition size fields is greater than the maximum number of additional partitions
3284 in the mode page, the second field is used. Otherwise the first field is used.
3285
3286 For Seagate DDS drives the page length must be 8 when no partitions is defined
3287 and 10 when 1 partition is defined (information from Eric Lee Green). This is
3288 is acceptable also to some other old drives and enforced if the first partition
3289 size field is used for the first additional partition size.
3290 */
3291static int partition_tape(struct scsi_tape *STp, int size)
3292{
Linus Torvalds1da177e2005-04-16 15:20:36 -07003293 int result;
3294 int pgo, psd_cnt, psdo;
3295 unsigned char *bp;
3296
3297 result = read_mode_page(STp, PART_PAGE, 0);
3298 if (result) {
Hannes Reineckeb30d8bc2014-06-25 16:39:57 +02003299 DEBC_printk(STp, "Can't read partition mode page.\n");
Linus Torvalds1da177e2005-04-16 15:20:36 -07003300 return result;
3301 }
3302 /* The mode page is in the buffer. Let's modify it and write it. */
3303 bp = (STp->buffer)->b_data;
3304 pgo = MODE_HEADER_LENGTH + bp[MH_OFF_BDESCS_LENGTH];
Hannes Reineckeb30d8bc2014-06-25 16:39:57 +02003305 DEBC_printk(STp, "Partition page length is %d bytes.\n",
3306 bp[pgo + MP_OFF_PAGE_LENGTH] + 2);
Linus Torvalds1da177e2005-04-16 15:20:36 -07003307
3308 psd_cnt = (bp[pgo + MP_OFF_PAGE_LENGTH] + 2 - PART_PAGE_FIXED_LENGTH) / 2;
3309 psdo = pgo + PART_PAGE_FIXED_LENGTH;
3310 if (psd_cnt > bp[pgo + PP_OFF_MAX_ADD_PARTS]) {
3311 bp[psdo] = bp[psdo + 1] = 0xff; /* Rest of the tape */
3312 psdo += 2;
3313 }
3314 memset(bp + psdo, 0, bp[pgo + PP_OFF_NBR_ADD_PARTS] * 2);
3315
Hannes Reineckeb30d8bc2014-06-25 16:39:57 +02003316 DEBC_printk(STp, "psd_cnt %d, max.parts %d, nbr_parts %d\n",
Linus Torvalds1da177e2005-04-16 15:20:36 -07003317 psd_cnt, bp[pgo + PP_OFF_MAX_ADD_PARTS],
Hannes Reineckeb30d8bc2014-06-25 16:39:57 +02003318 bp[pgo + PP_OFF_NBR_ADD_PARTS]);
Linus Torvalds1da177e2005-04-16 15:20:36 -07003319
3320 if (size <= 0) {
3321 bp[pgo + PP_OFF_NBR_ADD_PARTS] = 0;
3322 if (psd_cnt <= bp[pgo + PP_OFF_MAX_ADD_PARTS])
3323 bp[pgo + MP_OFF_PAGE_LENGTH] = 6;
Hannes Reineckeb30d8bc2014-06-25 16:39:57 +02003324 DEBC_printk(STp, "Formatting tape with one partition.\n");
Linus Torvalds1da177e2005-04-16 15:20:36 -07003325 } else {
3326 bp[psdo] = (size >> 8) & 0xff;
3327 bp[psdo + 1] = size & 0xff;
3328 bp[pgo + 3] = 1;
3329 if (bp[pgo + MP_OFF_PAGE_LENGTH] < 8)
3330 bp[pgo + MP_OFF_PAGE_LENGTH] = 8;
Hannes Reineckeb30d8bc2014-06-25 16:39:57 +02003331 DEBC_printk(STp, "Formatting tape with two partitions "
3332 "(1 = %d MB).\n", size);
Linus Torvalds1da177e2005-04-16 15:20:36 -07003333 }
3334 bp[pgo + PP_OFF_PART_UNITS] = 0;
3335 bp[pgo + PP_OFF_RESERVED] = 0;
3336 bp[pgo + PP_OFF_FLAGS] = PP_BIT_IDP | PP_MSK_PSUM_MB;
3337
3338 result = write_mode_page(STp, PART_PAGE, 1);
3339 if (result) {
Hannes Reineckeb30d8bc2014-06-25 16:39:57 +02003340 st_printk(KERN_INFO, STp, "Partitioning of tape failed.\n");
Linus Torvalds1da177e2005-04-16 15:20:36 -07003341 result = (-EIO);
3342 }
3343
3344 return result;
3345}
3346
3347
3348
3349/* The ioctl command */
Kai Makisarafd66c1b2008-01-17 22:45:22 +02003350static long st_ioctl(struct file *file, unsigned int cmd_in, unsigned long arg)
Linus Torvalds1da177e2005-04-16 15:20:36 -07003351{
3352 int i, cmd_nr, cmd_type, bt;
3353 int retval = 0;
3354 unsigned int blk;
3355 struct scsi_tape *STp = file->private_data;
3356 struct st_modedef *STm;
3357 struct st_partstat *STps;
Linus Torvalds1da177e2005-04-16 15:20:36 -07003358 void __user *p = (void __user *)arg;
3359
Matthias Kaehlcke28f85002007-07-29 23:38:15 +02003360 if (mutex_lock_interruptible(&STp->lock))
Linus Torvalds1da177e2005-04-16 15:20:36 -07003361 return -ERESTARTSYS;
3362
Hannes Reineckeb30d8bc2014-06-25 16:39:57 +02003363 DEB(
Linus Torvalds1da177e2005-04-16 15:20:36 -07003364 if (debugging && !STp->in_use) {
Hannes Reineckeb30d8bc2014-06-25 16:39:57 +02003365 st_printk(ST_DEB_MSG, STp, "Incorrect device.\n");
Linus Torvalds1da177e2005-04-16 15:20:36 -07003366 retval = (-EIO);
3367 goto out;
3368 } ) /* end DEB */
3369
3370 STm = &(STp->modes[STp->current_mode]);
3371 STps = &(STp->ps[STp->partition]);
3372
3373 /*
3374 * If we are in the middle of error recovery, don't let anyone
3375 * else try and use this device. Also, if error recovery fails, it
3376 * may try and take the device offline, in which case all further
3377 * access to the device is prohibited.
3378 */
Christoph Hellwig906d15f2014-10-11 16:25:31 +02003379 retval = scsi_ioctl_block_when_processing_errors(STp->device, cmd_in,
3380 file->f_flags & O_NDELAY);
3381 if (retval)
Linus Torvalds1da177e2005-04-16 15:20:36 -07003382 goto out;
Linus Torvalds1da177e2005-04-16 15:20:36 -07003383
3384 cmd_type = _IOC_TYPE(cmd_in);
3385 cmd_nr = _IOC_NR(cmd_in);
3386
3387 if (cmd_type == _IOC_TYPE(MTIOCTOP) && cmd_nr == _IOC_NR(MTIOCTOP)) {
3388 struct mtop mtc;
3389
3390 if (_IOC_SIZE(cmd_in) != sizeof(mtc)) {
3391 retval = (-EINVAL);
3392 goto out;
3393 }
3394
3395 i = copy_from_user(&mtc, p, sizeof(struct mtop));
3396 if (i) {
3397 retval = (-EFAULT);
3398 goto out;
3399 }
3400
3401 if (mtc.mt_op == MTSETDRVBUFFER && !capable(CAP_SYS_ADMIN)) {
Hannes Reineckeb30d8bc2014-06-25 16:39:57 +02003402 st_printk(KERN_WARNING, STp,
3403 "MTSETDRVBUFFER only allowed for root.\n");
Linus Torvalds1da177e2005-04-16 15:20:36 -07003404 retval = (-EPERM);
3405 goto out;
3406 }
3407 if (!STm->defined &&
3408 (mtc.mt_op != MTSETDRVBUFFER &&
3409 (mtc.mt_count & MT_ST_OPTIONS) == 0)) {
3410 retval = (-ENXIO);
3411 goto out;
3412 }
3413
3414 if (!STp->pos_unknown) {
3415
3416 if (STps->eof == ST_FM_HIT) {
3417 if (mtc.mt_op == MTFSF || mtc.mt_op == MTFSFM ||
3418 mtc.mt_op == MTEOM) {
3419 mtc.mt_count -= 1;
3420 if (STps->drv_file >= 0)
3421 STps->drv_file += 1;
3422 } else if (mtc.mt_op == MTBSF || mtc.mt_op == MTBSFM) {
3423 mtc.mt_count += 1;
3424 if (STps->drv_file >= 0)
3425 STps->drv_file += 1;
3426 }
3427 }
3428
3429 if (mtc.mt_op == MTSEEK) {
3430 /* Old position must be restored if partition will be
3431 changed */
3432 i = !STp->can_partitions ||
3433 (STp->new_partition != STp->partition);
3434 } else {
3435 i = mtc.mt_op == MTREW || mtc.mt_op == MTOFFL ||
3436 mtc.mt_op == MTRETEN || mtc.mt_op == MTEOM ||
3437 mtc.mt_op == MTLOCK || mtc.mt_op == MTLOAD ||
3438 mtc.mt_op == MTFSF || mtc.mt_op == MTFSFM ||
3439 mtc.mt_op == MTBSF || mtc.mt_op == MTBSFM ||
3440 mtc.mt_op == MTCOMPRESSION;
3441 }
3442 i = flush_buffer(STp, i);
3443 if (i < 0) {
3444 retval = i;
3445 goto out;
3446 }
3447 if (STps->rw == ST_WRITING &&
3448 (mtc.mt_op == MTREW || mtc.mt_op == MTOFFL ||
3449 mtc.mt_op == MTSEEK ||
3450 mtc.mt_op == MTBSF || mtc.mt_op == MTBSFM)) {
3451 i = st_int_ioctl(STp, MTWEOF, 1);
3452 if (i < 0) {
3453 retval = i;
3454 goto out;
3455 }
3456 if (mtc.mt_op == MTBSF || mtc.mt_op == MTBSFM)
3457 mtc.mt_count++;
3458 STps->rw = ST_IDLE;
3459 }
3460
3461 } else {
3462 /*
3463 * If there was a bus reset, block further access
3464 * to this device. If the user wants to rewind the tape,
3465 * then reset the flag and allow access again.
3466 */
3467 if (mtc.mt_op != MTREW &&
3468 mtc.mt_op != MTOFFL &&
3469 mtc.mt_op != MTRETEN &&
3470 mtc.mt_op != MTERASE &&
3471 mtc.mt_op != MTSEEK &&
3472 mtc.mt_op != MTEOM) {
3473 retval = (-EIO);
3474 goto out;
3475 }
3476 reset_state(STp);
3477 /* remove this when the midlevel properly clears was_reset */
3478 STp->device->was_reset = 0;
3479 }
3480
3481 if (mtc.mt_op != MTNOP && mtc.mt_op != MTSETBLK &&
3482 mtc.mt_op != MTSETDENSITY && mtc.mt_op != MTWSM &&
3483 mtc.mt_op != MTSETDRVBUFFER && mtc.mt_op != MTSETPART)
3484 STps->rw = ST_IDLE; /* Prevent automatic WEOF and fsf */
3485
3486 if (mtc.mt_op == MTOFFL && STp->door_locked != ST_UNLOCKED)
3487 do_door_lock(STp, 0); /* Ignore result! */
3488
3489 if (mtc.mt_op == MTSETDRVBUFFER &&
3490 (mtc.mt_count & MT_ST_OPTIONS) != 0) {
3491 retval = st_set_options(STp, mtc.mt_count);
3492 goto out;
3493 }
3494
3495 if (mtc.mt_op == MTSETPART) {
3496 if (!STp->can_partitions ||
3497 mtc.mt_count < 0 || mtc.mt_count >= ST_NBR_PARTITIONS) {
3498 retval = (-EINVAL);
3499 goto out;
3500 }
3501 if (mtc.mt_count >= STp->nbr_partitions &&
3502 (STp->nbr_partitions = nbr_partitions(STp)) < 0) {
3503 retval = (-EIO);
3504 goto out;
3505 }
3506 if (mtc.mt_count >= STp->nbr_partitions) {
3507 retval = (-EINVAL);
3508 goto out;
3509 }
3510 STp->new_partition = mtc.mt_count;
3511 retval = 0;
3512 goto out;
3513 }
3514
3515 if (mtc.mt_op == MTMKPART) {
3516 if (!STp->can_partitions) {
3517 retval = (-EINVAL);
3518 goto out;
3519 }
3520 if ((i = st_int_ioctl(STp, MTREW, 0)) < 0 ||
3521 (i = partition_tape(STp, mtc.mt_count)) < 0) {
3522 retval = i;
3523 goto out;
3524 }
3525 for (i = 0; i < ST_NBR_PARTITIONS; i++) {
3526 STp->ps[i].rw = ST_IDLE;
3527 STp->ps[i].at_sm = 0;
3528 STp->ps[i].last_block_valid = 0;
3529 }
3530 STp->partition = STp->new_partition = 0;
3531 STp->nbr_partitions = 1; /* Bad guess ?-) */
3532 STps->drv_block = STps->drv_file = 0;
3533 retval = 0;
3534 goto out;
3535 }
3536
3537 if (mtc.mt_op == MTSEEK) {
3538 i = set_location(STp, mtc.mt_count, STp->new_partition, 0);
3539 if (!STp->can_partitions)
3540 STp->ps[0].rw = ST_IDLE;
3541 retval = i;
3542 goto out;
3543 }
3544
3545 if (mtc.mt_op == MTUNLOAD || mtc.mt_op == MTOFFL) {
3546 retval = do_load_unload(STp, file, 0);
3547 goto out;
3548 }
3549
3550 if (mtc.mt_op == MTLOAD) {
3551 retval = do_load_unload(STp, file, max(1, mtc.mt_count));
3552 goto out;
3553 }
3554
3555 if (mtc.mt_op == MTLOCK || mtc.mt_op == MTUNLOCK) {
3556 retval = do_door_lock(STp, (mtc.mt_op == MTLOCK));
3557 goto out;
3558 }
3559
3560 if (STp->can_partitions && STp->ready == ST_READY &&
3561 (i = switch_partition(STp)) < 0) {
3562 retval = i;
3563 goto out;
3564 }
3565
3566 if (mtc.mt_op == MTCOMPRESSION)
3567 retval = st_compression(STp, (mtc.mt_count & 1));
3568 else
3569 retval = st_int_ioctl(STp, mtc.mt_op, mtc.mt_count);
3570 goto out;
3571 }
3572 if (!STm->defined) {
3573 retval = (-ENXIO);
3574 goto out;
3575 }
3576
3577 if ((i = flush_buffer(STp, 0)) < 0) {
3578 retval = i;
3579 goto out;
3580 }
3581 if (STp->can_partitions &&
3582 (i = switch_partition(STp)) < 0) {
3583 retval = i;
3584 goto out;
3585 }
3586
3587 if (cmd_type == _IOC_TYPE(MTIOCGET) && cmd_nr == _IOC_NR(MTIOCGET)) {
3588 struct mtget mt_status;
3589
3590 if (_IOC_SIZE(cmd_in) != sizeof(struct mtget)) {
3591 retval = (-EINVAL);
3592 goto out;
3593 }
3594
3595 mt_status.mt_type = STp->tape_type;
3596 mt_status.mt_dsreg =
3597 ((STp->block_size << MT_ST_BLKSIZE_SHIFT) & MT_ST_BLKSIZE_MASK) |
3598 ((STp->density << MT_ST_DENSITY_SHIFT) & MT_ST_DENSITY_MASK);
3599 mt_status.mt_blkno = STps->drv_block;
3600 mt_status.mt_fileno = STps->drv_file;
3601 if (STp->block_size != 0) {
3602 if (STps->rw == ST_WRITING)
3603 mt_status.mt_blkno +=
3604 (STp->buffer)->buffer_bytes / STp->block_size;
3605 else if (STps->rw == ST_READING)
3606 mt_status.mt_blkno -=
3607 ((STp->buffer)->buffer_bytes +
3608 STp->block_size - 1) / STp->block_size;
3609 }
3610
3611 mt_status.mt_gstat = 0;
3612 if (STp->drv_write_prot)
3613 mt_status.mt_gstat |= GMT_WR_PROT(0xffffffff);
3614 if (mt_status.mt_blkno == 0) {
3615 if (mt_status.mt_fileno == 0)
3616 mt_status.mt_gstat |= GMT_BOT(0xffffffff);
3617 else
3618 mt_status.mt_gstat |= GMT_EOF(0xffffffff);
3619 }
3620 mt_status.mt_erreg = (STp->recover_reg << MT_ST_SOFTERR_SHIFT);
3621 mt_status.mt_resid = STp->partition;
3622 if (STps->eof == ST_EOM_OK || STps->eof == ST_EOM_ERROR)
3623 mt_status.mt_gstat |= GMT_EOT(0xffffffff);
3624 else if (STps->eof >= ST_EOM_OK)
3625 mt_status.mt_gstat |= GMT_EOD(0xffffffff);
3626 if (STp->density == 1)
3627 mt_status.mt_gstat |= GMT_D_800(0xffffffff);
3628 else if (STp->density == 2)
3629 mt_status.mt_gstat |= GMT_D_1600(0xffffffff);
3630 else if (STp->density == 3)
3631 mt_status.mt_gstat |= GMT_D_6250(0xffffffff);
3632 if (STp->ready == ST_READY)
3633 mt_status.mt_gstat |= GMT_ONLINE(0xffffffff);
3634 if (STp->ready == ST_NO_TAPE)
3635 mt_status.mt_gstat |= GMT_DR_OPEN(0xffffffff);
3636 if (STps->at_sm)
3637 mt_status.mt_gstat |= GMT_SM(0xffffffff);
3638 if (STm->do_async_writes ||
3639 (STm->do_buffer_writes && STp->block_size != 0) ||
3640 STp->drv_buffer != 0)
3641 mt_status.mt_gstat |= GMT_IM_REP_EN(0xffffffff);
3642 if (STp->cleaning_req)
3643 mt_status.mt_gstat |= GMT_CLN(0xffffffff);
3644
3645 i = copy_to_user(p, &mt_status, sizeof(struct mtget));
3646 if (i) {
3647 retval = (-EFAULT);
3648 goto out;
3649 }
3650
3651 STp->recover_reg = 0; /* Clear after read */
3652 retval = 0;
3653 goto out;
3654 } /* End of MTIOCGET */
3655 if (cmd_type == _IOC_TYPE(MTIOCPOS) && cmd_nr == _IOC_NR(MTIOCPOS)) {
3656 struct mtpos mt_pos;
3657 if (_IOC_SIZE(cmd_in) != sizeof(struct mtpos)) {
3658 retval = (-EINVAL);
3659 goto out;
3660 }
3661 if ((i = get_location(STp, &blk, &bt, 0)) < 0) {
3662 retval = i;
3663 goto out;
3664 }
3665 mt_pos.mt_blkno = blk;
3666 i = copy_to_user(p, &mt_pos, sizeof(struct mtpos));
3667 if (i)
3668 retval = (-EFAULT);
3669 goto out;
3670 }
Matthias Kaehlcke28f85002007-07-29 23:38:15 +02003671 mutex_unlock(&STp->lock);
Linus Torvalds1da177e2005-04-16 15:20:36 -07003672 switch (cmd_in) {
3673 case SCSI_IOCTL_GET_IDLUN:
3674 case SCSI_IOCTL_GET_BUS_NUMBER:
3675 break;
3676 default:
Kai Makisara 16c4b3e2005-05-01 18:11:55 +03003677 if ((cmd_in == SG_IO ||
3678 cmd_in == SCSI_IOCTL_SEND_COMMAND ||
3679 cmd_in == CDROM_SEND_PACKET) &&
3680 !capable(CAP_SYS_RAWIO))
Linus Torvalds1da177e2005-04-16 15:20:36 -07003681 i = -EPERM;
3682 else
Al Viro74f3c8a2007-08-27 15:38:10 -04003683 i = scsi_cmd_ioctl(STp->disk->queue, STp->disk,
3684 file->f_mode, cmd_in, p);
Linus Torvalds1da177e2005-04-16 15:20:36 -07003685 if (i != -ENOTTY)
3686 return i;
3687 break;
3688 }
Kai Makisara 16c4b3e2005-05-01 18:11:55 +03003689 retval = scsi_ioctl(STp->device, cmd_in, p);
3690 if (!retval && cmd_in == SCSI_IOCTL_STOP_UNIT) { /* unload */
3691 STp->rew_at_close = 0;
3692 STp->ready = ST_NO_TAPE;
3693 }
3694 return retval;
Linus Torvalds1da177e2005-04-16 15:20:36 -07003695
3696 out:
Matthias Kaehlcke28f85002007-07-29 23:38:15 +02003697 mutex_unlock(&STp->lock);
Linus Torvalds1da177e2005-04-16 15:20:36 -07003698 return retval;
3699}
3700
3701#ifdef CONFIG_COMPAT
3702static long st_compat_ioctl(struct file *file, unsigned int cmd, unsigned long arg)
3703{
3704 struct scsi_tape *STp = file->private_data;
3705 struct scsi_device *sdev = STp->device;
3706 int ret = -ENOIOCTLCMD;
3707 if (sdev->host->hostt->compat_ioctl) {
3708
3709 ret = sdev->host->hostt->compat_ioctl(sdev, cmd, (void __user *)arg);
3710
3711 }
3712 return ret;
3713}
3714#endif
3715
3716
3717
3718/* Try to allocate a new tape buffer. Calling function must not hold
3719 dev_arr_lock. */
FUJITA Tomonorif409d6c2008-12-18 14:49:47 +09003720static struct st_buffer *new_tape_buffer(int need_dma, int max_sg)
Linus Torvalds1da177e2005-04-16 15:20:36 -07003721{
Linus Torvalds1da177e2005-04-16 15:20:36 -07003722 struct st_buffer *tb;
3723
FUJITA Tomonorif409d6c2008-12-18 14:49:47 +09003724 tb = kzalloc(sizeof(struct st_buffer), GFP_ATOMIC);
Linus Torvalds1da177e2005-04-16 15:20:36 -07003725 if (!tb) {
3726 printk(KERN_NOTICE "st: Can't allocate new tape buffer.\n");
3727 return NULL;
3728 }
FUJITA Tomonori1ac63cf2008-12-18 14:49:48 +09003729 tb->frp_segs = 0;
Linus Torvalds1da177e2005-04-16 15:20:36 -07003730 tb->use_sg = max_sg;
Linus Torvalds1da177e2005-04-16 15:20:36 -07003731 tb->dma = need_dma;
FUJITA Tomonorif409d6c2008-12-18 14:49:47 +09003732 tb->buffer_size = 0;
Linus Torvalds1da177e2005-04-16 15:20:36 -07003733
FUJITA Tomonorif409d6c2008-12-18 14:49:47 +09003734 tb->reserved_pages = kzalloc(max_sg * sizeof(struct page *),
3735 GFP_ATOMIC);
FUJITA Tomonorid0e1ae32008-12-18 14:49:40 +09003736 if (!tb->reserved_pages) {
3737 kfree(tb);
3738 return NULL;
3739 }
3740
Linus Torvalds1da177e2005-04-16 15:20:36 -07003741 return tb;
3742}
3743
3744
3745/* Try to allocate enough space in the tape buffer */
Kai Makisara8f78fc52008-12-18 14:49:51 +09003746#define ST_MAX_ORDER 6
3747
Linus Torvalds1da177e2005-04-16 15:20:36 -07003748static int enlarge_buffer(struct st_buffer * STbuffer, int new_size, int need_dma)
3749{
Bodo Stroesser769989a2013-12-02 18:52:10 +01003750 int segs, max_segs, b_size, order, got;
Al Viroc53033f2005-10-21 03:22:08 -04003751 gfp_t priority;
Linus Torvalds1da177e2005-04-16 15:20:36 -07003752
3753 if (new_size <= STbuffer->buffer_size)
3754 return 1;
3755
3756 if (STbuffer->buffer_size <= PAGE_SIZE)
3757 normalize_buffer(STbuffer); /* Avoid extra segment */
3758
3759 max_segs = STbuffer->use_sg;
Linus Torvalds1da177e2005-04-16 15:20:36 -07003760
3761 priority = GFP_KERNEL | __GFP_NOWARN;
3762 if (need_dma)
3763 priority |= GFP_DMA;
FUJITA Tomonori9c905962008-12-18 14:49:39 +09003764
FUJITA Tomonori08c95832008-12-18 14:49:45 +09003765 if (STbuffer->cleared)
3766 priority |= __GFP_ZERO;
3767
FUJITA Tomonori9c905962008-12-18 14:49:39 +09003768 if (STbuffer->frp_segs) {
FUJITA Tomonoric982c362009-11-26 09:24:13 +09003769 order = STbuffer->reserved_page_order;
FUJITA Tomonori08c95832008-12-18 14:49:45 +09003770 b_size = PAGE_SIZE << order;
FUJITA Tomonori9c905962008-12-18 14:49:39 +09003771 } else {
3772 for (b_size = PAGE_SIZE, order = 0;
FUJITA Tomonori46081b12010-12-20 18:44:45 +02003773 order < ST_MAX_ORDER &&
3774 max_segs * (PAGE_SIZE << order) < new_size;
Kai Makisara8f78fc52008-12-18 14:49:51 +09003775 order++, b_size *= 2)
FUJITA Tomonori9c905962008-12-18 14:49:39 +09003776 ; /* empty */
Kai Makisara373daac2010-12-20 18:43:39 +02003777 STbuffer->reserved_page_order = order;
FUJITA Tomonori9c905962008-12-18 14:49:39 +09003778 }
Kai Makisara8f78fc52008-12-18 14:49:51 +09003779 if (max_segs * (PAGE_SIZE << order) < new_size) {
3780 if (order == ST_MAX_ORDER)
3781 return 0;
3782 normalize_buffer(STbuffer);
3783 return enlarge_buffer(STbuffer, new_size, need_dma);
3784 }
Linus Torvalds1da177e2005-04-16 15:20:36 -07003785
3786 for (segs = STbuffer->frp_segs, got = STbuffer->buffer_size;
3787 segs < max_segs && got < new_size;) {
FUJITA Tomonori08c95832008-12-18 14:49:45 +09003788 struct page *page;
3789
3790 page = alloc_pages(priority, order);
3791 if (!page) {
Linus Torvalds1da177e2005-04-16 15:20:36 -07003792 DEB(STbuffer->buffer_size = got);
3793 normalize_buffer(STbuffer);
3794 return 0;
3795 }
FUJITA Tomonori08c95832008-12-18 14:49:45 +09003796
Linus Torvalds1da177e2005-04-16 15:20:36 -07003797 STbuffer->frp_segs += 1;
3798 got += b_size;
3799 STbuffer->buffer_size = got;
FUJITA Tomonori08c95832008-12-18 14:49:45 +09003800 STbuffer->reserved_pages[segs] = page;
Linus Torvalds1da177e2005-04-16 15:20:36 -07003801 segs++;
3802 }
FUJITA Tomonori08c95832008-12-18 14:49:45 +09003803 STbuffer->b_data = page_address(STbuffer->reserved_pages[0]);
Linus Torvalds1da177e2005-04-16 15:20:36 -07003804
3805 return 1;
3806}
3807
3808
Kai Makisara40f6b362008-02-24 22:23:24 +02003809/* Make sure that no data from previous user is in the internal buffer */
3810static void clear_buffer(struct st_buffer * st_bp)
3811{
3812 int i;
3813
3814 for (i=0; i < st_bp->frp_segs; i++)
FUJITA Tomonori08c95832008-12-18 14:49:45 +09003815 memset(page_address(st_bp->reserved_pages[i]), 0,
FUJITA Tomonoric982c362009-11-26 09:24:13 +09003816 PAGE_SIZE << st_bp->reserved_page_order);
Kai Makisara40f6b362008-02-24 22:23:24 +02003817 st_bp->cleared = 1;
3818}
3819
3820
Linus Torvalds1da177e2005-04-16 15:20:36 -07003821/* Release the extra buffer */
3822static void normalize_buffer(struct st_buffer * STbuffer)
3823{
FUJITA Tomonoric982c362009-11-26 09:24:13 +09003824 int i, order = STbuffer->reserved_page_order;
Linus Torvalds1da177e2005-04-16 15:20:36 -07003825
FUJITA Tomonori1ac63cf2008-12-18 14:49:48 +09003826 for (i = 0; i < STbuffer->frp_segs; i++) {
FUJITA Tomonori08c95832008-12-18 14:49:45 +09003827 __free_pages(STbuffer->reserved_pages[i], order);
3828 STbuffer->buffer_size -= (PAGE_SIZE << order);
Linus Torvalds1da177e2005-04-16 15:20:36 -07003829 }
FUJITA Tomonori1ac63cf2008-12-18 14:49:48 +09003830 STbuffer->frp_segs = 0;
Mike Christie8b05b772005-11-08 04:06:44 -06003831 STbuffer->sg_segs = 0;
FUJITA Tomonoric982c362009-11-26 09:24:13 +09003832 STbuffer->reserved_page_order = 0;
FUJITA Tomonorid0e1ae32008-12-18 14:49:40 +09003833 STbuffer->map_data.offset = 0;
Linus Torvalds1da177e2005-04-16 15:20:36 -07003834}
3835
3836
3837/* Move data from the user buffer to the tape buffer. Returns zero (success) or
3838 negative error code. */
3839static int append_to_buffer(const char __user *ubp, struct st_buffer * st_bp, int do_count)
3840{
3841 int i, cnt, res, offset;
FUJITA Tomonoric982c362009-11-26 09:24:13 +09003842 int length = PAGE_SIZE << st_bp->reserved_page_order;
Linus Torvalds1da177e2005-04-16 15:20:36 -07003843
3844 for (i = 0, offset = st_bp->buffer_bytes;
FUJITA Tomonori08c95832008-12-18 14:49:45 +09003845 i < st_bp->frp_segs && offset >= length; i++)
3846 offset -= length;
Linus Torvalds1da177e2005-04-16 15:20:36 -07003847 if (i == st_bp->frp_segs) { /* Should never happen */
3848 printk(KERN_WARNING "st: append_to_buffer offset overflow.\n");
3849 return (-EIO);
3850 }
3851 for (; i < st_bp->frp_segs && do_count > 0; i++) {
FUJITA Tomonori08c95832008-12-18 14:49:45 +09003852 struct page *page = st_bp->reserved_pages[i];
3853 cnt = length - offset < do_count ? length - offset : do_count;
3854 res = copy_from_user(page_address(page) + offset, ubp, cnt);
Linus Torvalds1da177e2005-04-16 15:20:36 -07003855 if (res)
3856 return (-EFAULT);
3857 do_count -= cnt;
3858 st_bp->buffer_bytes += cnt;
3859 ubp += cnt;
3860 offset = 0;
3861 }
3862 if (do_count) /* Should never happen */
3863 return (-EIO);
3864
3865 return 0;
3866}
3867
3868
3869/* Move data from the tape buffer to the user buffer. Returns zero (success) or
3870 negative error code. */
3871static int from_buffer(struct st_buffer * st_bp, char __user *ubp, int do_count)
3872{
3873 int i, cnt, res, offset;
FUJITA Tomonoric982c362009-11-26 09:24:13 +09003874 int length = PAGE_SIZE << st_bp->reserved_page_order;
Linus Torvalds1da177e2005-04-16 15:20:36 -07003875
3876 for (i = 0, offset = st_bp->read_pointer;
FUJITA Tomonori08c95832008-12-18 14:49:45 +09003877 i < st_bp->frp_segs && offset >= length; i++)
3878 offset -= length;
Linus Torvalds1da177e2005-04-16 15:20:36 -07003879 if (i == st_bp->frp_segs) { /* Should never happen */
3880 printk(KERN_WARNING "st: from_buffer offset overflow.\n");
3881 return (-EIO);
3882 }
3883 for (; i < st_bp->frp_segs && do_count > 0; i++) {
FUJITA Tomonori08c95832008-12-18 14:49:45 +09003884 struct page *page = st_bp->reserved_pages[i];
3885 cnt = length - offset < do_count ? length - offset : do_count;
3886 res = copy_to_user(ubp, page_address(page) + offset, cnt);
Linus Torvalds1da177e2005-04-16 15:20:36 -07003887 if (res)
3888 return (-EFAULT);
3889 do_count -= cnt;
3890 st_bp->buffer_bytes -= cnt;
3891 st_bp->read_pointer += cnt;
3892 ubp += cnt;
3893 offset = 0;
3894 }
3895 if (do_count) /* Should never happen */
3896 return (-EIO);
3897
3898 return 0;
3899}
3900
3901
3902/* Move data towards start of buffer */
3903static void move_buffer_data(struct st_buffer * st_bp, int offset)
3904{
3905 int src_seg, dst_seg, src_offset = 0, dst_offset;
3906 int count, total;
FUJITA Tomonoric982c362009-11-26 09:24:13 +09003907 int length = PAGE_SIZE << st_bp->reserved_page_order;
Linus Torvalds1da177e2005-04-16 15:20:36 -07003908
3909 if (offset == 0)
3910 return;
3911
3912 total=st_bp->buffer_bytes - offset;
3913 for (src_seg=0; src_seg < st_bp->frp_segs; src_seg++) {
3914 src_offset = offset;
FUJITA Tomonori08c95832008-12-18 14:49:45 +09003915 if (src_offset < length)
Linus Torvalds1da177e2005-04-16 15:20:36 -07003916 break;
FUJITA Tomonori08c95832008-12-18 14:49:45 +09003917 offset -= length;
Linus Torvalds1da177e2005-04-16 15:20:36 -07003918 }
3919
3920 st_bp->buffer_bytes = st_bp->read_pointer = total;
3921 for (dst_seg=dst_offset=0; total > 0; ) {
FUJITA Tomonori08c95832008-12-18 14:49:45 +09003922 struct page *dpage = st_bp->reserved_pages[dst_seg];
3923 struct page *spage = st_bp->reserved_pages[src_seg];
3924
3925 count = min(length - dst_offset, length - src_offset);
3926 memmove(page_address(dpage) + dst_offset,
3927 page_address(spage) + src_offset, count);
Linus Torvalds1da177e2005-04-16 15:20:36 -07003928 src_offset += count;
FUJITA Tomonori08c95832008-12-18 14:49:45 +09003929 if (src_offset >= length) {
Linus Torvalds1da177e2005-04-16 15:20:36 -07003930 src_seg++;
3931 src_offset = 0;
3932 }
3933 dst_offset += count;
FUJITA Tomonori08c95832008-12-18 14:49:45 +09003934 if (dst_offset >= length) {
Linus Torvalds1da177e2005-04-16 15:20:36 -07003935 dst_seg++;
3936 dst_offset = 0;
3937 }
3938 total -= count;
3939 }
3940}
3941
Linus Torvalds1da177e2005-04-16 15:20:36 -07003942/* Validate the options from command line or module parameters */
3943static void validate_options(void)
3944{
3945 if (buffer_kbs > 0)
3946 st_fixed_buffer_size = buffer_kbs * ST_KILOBYTE;
3947 if (max_sg_segs >= ST_FIRST_SG)
3948 st_max_sg_segs = max_sg_segs;
3949}
3950
3951#ifndef MODULE
3952/* Set the boot options. Syntax is defined in Documenation/scsi/st.txt.
3953 */
3954static int __init st_setup(char *str)
3955{
3956 int i, len, ints[5];
3957 char *stp;
3958
3959 stp = get_options(str, ARRAY_SIZE(ints), ints);
3960
3961 if (ints[0] > 0) {
3962 for (i = 0; i < ints[0] && i < ARRAY_SIZE(parms); i++)
3963 if (parms[i].val)
3964 *parms[i].val = ints[i + 1];
3965 } else {
3966 while (stp != NULL) {
3967 for (i = 0; i < ARRAY_SIZE(parms); i++) {
3968 len = strlen(parms[i].name);
3969 if (!strncmp(stp, parms[i].name, len) &&
3970 (*(stp + len) == ':' || *(stp + len) == '=')) {
3971 if (parms[i].val)
3972 *parms[i].val =
3973 simple_strtoul(stp + len + 1, NULL, 0);
3974 else
3975 printk(KERN_WARNING "st: Obsolete parameter %s\n",
3976 parms[i].name);
3977 break;
3978 }
3979 }
Tobias Klauser6391a112006-06-08 22:23:48 -07003980 if (i >= ARRAY_SIZE(parms))
Linus Torvalds1da177e2005-04-16 15:20:36 -07003981 printk(KERN_WARNING "st: invalid parameter in '%s'\n",
3982 stp);
3983 stp = strchr(stp, ',');
3984 if (stp)
3985 stp++;
3986 }
3987 }
3988
3989 validate_options();
3990
3991 return 1;
3992}
3993
3994__setup("st=", st_setup);
3995
3996#endif
3997
Arjan van de Ven00977a52007-02-12 00:55:34 -08003998static const struct file_operations st_fops =
Linus Torvalds1da177e2005-04-16 15:20:36 -07003999{
4000 .owner = THIS_MODULE,
4001 .read = st_read,
4002 .write = st_write,
Kai Makisarafd66c1b2008-01-17 22:45:22 +02004003 .unlocked_ioctl = st_ioctl,
Linus Torvalds1da177e2005-04-16 15:20:36 -07004004#ifdef CONFIG_COMPAT
4005 .compat_ioctl = st_compat_ioctl,
4006#endif
4007 .open = st_open,
4008 .flush = st_flush,
4009 .release = st_release,
Jan Blunckb4d878e2010-05-26 14:44:51 -07004010 .llseek = noop_llseek,
Linus Torvalds1da177e2005-04-16 15:20:36 -07004011};
4012
Jeff Mahoney26898af2012-08-18 15:20:40 -04004013static int create_one_cdev(struct scsi_tape *tape, int mode, int rew)
4014{
4015 int i, error;
4016 dev_t cdev_devno;
4017 struct cdev *cdev;
4018 struct device *dev;
4019 struct st_modedef *STm = &(tape->modes[mode]);
4020 char name[10];
4021 int dev_num = tape->index;
4022
4023 cdev_devno = MKDEV(SCSI_TAPE_MAJOR, TAPE_MINOR(dev_num, mode, rew));
4024
4025 cdev = cdev_alloc();
4026 if (!cdev) {
4027 pr_err("st%d: out of memory. Device not attached.\n", dev_num);
4028 error = -ENOMEM;
4029 goto out;
4030 }
4031 cdev->owner = THIS_MODULE;
4032 cdev->ops = &st_fops;
4033
4034 error = cdev_add(cdev, cdev_devno, 1);
4035 if (error) {
4036 pr_err("st%d: Can't add %s-rewind mode %d\n", dev_num,
4037 rew ? "non" : "auto", mode);
4038 pr_err("st%d: Device not attached.\n", dev_num);
4039 goto out_free;
4040 }
4041 STm->cdevs[rew] = cdev;
4042
4043 i = mode << (4 - ST_NBR_MODE_BITS);
4044 snprintf(name, 10, "%s%s%s", rew ? "n" : "",
4045 tape->disk->disk_name, st_formats[i]);
4046
4047 dev = device_create(&st_sysfs_class, &tape->device->sdev_gendev,
4048 cdev_devno, &tape->modes[mode], "%s", name);
4049 if (IS_ERR(dev)) {
4050 pr_err("st%d: device_create failed\n", dev_num);
4051 error = PTR_ERR(dev);
4052 goto out_free;
4053 }
4054
4055 STm->devs[rew] = dev;
4056
4057 return 0;
4058out_free:
4059 cdev_del(STm->cdevs[rew]);
4060 STm->cdevs[rew] = NULL;
4061out:
4062 return error;
4063}
4064
4065static int create_cdevs(struct scsi_tape *tape)
4066{
4067 int mode, error;
4068 for (mode = 0; mode < ST_NBR_MODES; ++mode) {
4069 error = create_one_cdev(tape, mode, 0);
4070 if (error)
4071 return error;
4072 error = create_one_cdev(tape, mode, 1);
4073 if (error)
4074 return error;
4075 }
4076
4077 return sysfs_create_link(&tape->device->sdev_gendev.kobj,
4078 &tape->modes[0].devs[0]->kobj, "tape");
4079}
4080
4081static void remove_cdevs(struct scsi_tape *tape)
4082{
4083 int mode, rew;
4084 sysfs_remove_link(&tape->device->sdev_gendev.kobj, "tape");
4085 for (mode = 0; mode < ST_NBR_MODES; mode++) {
4086 struct st_modedef *STm = &(tape->modes[mode]);
4087 for (rew = 0; rew < 2; rew++) {
4088 if (STm->cdevs[rew])
4089 cdev_del(STm->cdevs[rew]);
4090 if (STm->devs[rew])
4091 device_unregister(STm->devs[rew]);
4092 }
4093 }
4094}
4095
Linus Torvalds1da177e2005-04-16 15:20:36 -07004096static int st_probe(struct device *dev)
4097{
4098 struct scsi_device *SDp = to_scsi_device(dev);
4099 struct gendisk *disk = NULL;
Linus Torvalds1da177e2005-04-16 15:20:36 -07004100 struct scsi_tape *tpnt = NULL;
4101 struct st_modedef *STm;
4102 struct st_partstat *STps;
4103 struct st_buffer *buffer;
Tejun Heob98c52b2013-02-27 17:04:42 -08004104 int i, error;
Linus Torvalds1da177e2005-04-16 15:20:36 -07004105 char *stp;
Linus Torvalds1da177e2005-04-16 15:20:36 -07004106
4107 if (SDp->type != TYPE_TAPE)
4108 return -ENODEV;
4109 if ((stp = st_incompatible(SDp))) {
Jeff Garzik3bf743e2005-10-24 18:04:06 -04004110 sdev_printk(KERN_INFO, SDp, "Found incompatible tape\n");
Hannes Reineckeb30d8bc2014-06-25 16:39:57 +02004111 sdev_printk(KERN_INFO, SDp,
4112 "st: The suggested driver is %s.\n", stp);
Linus Torvalds1da177e2005-04-16 15:20:36 -07004113 return -ENODEV;
4114 }
4115
Subhash Jadavani6fe8c1d2014-09-10 14:54:09 +03004116 scsi_autopm_get_device(SDp);
Martin K. Petersen8a783622010-02-26 00:20:39 -05004117 i = queue_max_segments(SDp->request_queue);
Linus Torvalds1da177e2005-04-16 15:20:36 -07004118 if (st_max_sg_segs < i)
4119 i = st_max_sg_segs;
FUJITA Tomonorif409d6c2008-12-18 14:49:47 +09004120 buffer = new_tape_buffer((SDp->host)->unchecked_isa_dma, i);
Linus Torvalds1da177e2005-04-16 15:20:36 -07004121 if (buffer == NULL) {
Hannes Reineckeb30d8bc2014-06-25 16:39:57 +02004122 sdev_printk(KERN_ERR, SDp,
4123 "st: Can't allocate new tape buffer. "
4124 "Device not attached.\n");
Linus Torvalds1da177e2005-04-16 15:20:36 -07004125 goto out;
4126 }
4127
4128 disk = alloc_disk(1);
4129 if (!disk) {
Hannes Reineckeb30d8bc2014-06-25 16:39:57 +02004130 sdev_printk(KERN_ERR, SDp,
4131 "st: out of memory. Device not attached.\n");
Linus Torvalds1da177e2005-04-16 15:20:36 -07004132 goto out_buffer_free;
4133 }
4134
Jes Sorensen24669f752006-01-16 10:31:18 -05004135 tpnt = kzalloc(sizeof(struct scsi_tape), GFP_ATOMIC);
Linus Torvalds1da177e2005-04-16 15:20:36 -07004136 if (tpnt == NULL) {
Hannes Reineckeb30d8bc2014-06-25 16:39:57 +02004137 sdev_printk(KERN_ERR, SDp,
4138 "st: Can't allocate device descriptor.\n");
Linus Torvalds1da177e2005-04-16 15:20:36 -07004139 goto out_put_disk;
4140 }
Kai Makisaraf03a5672005-08-02 13:40:47 +03004141 kref_init(&tpnt->kref);
Linus Torvalds1da177e2005-04-16 15:20:36 -07004142 tpnt->disk = disk;
Linus Torvalds1da177e2005-04-16 15:20:36 -07004143 disk->private_data = &tpnt->driver;
4144 disk->queue = SDp->request_queue;
Joe Lawrence2b5bebc2013-03-05 10:57:56 -05004145 /* SCSI tape doesn't register this gendisk via add_disk(). Manually
4146 * take queue reference that release_disk() expects. */
4147 if (!blk_get_queue(disk->queue))
4148 goto out_put_disk;
Linus Torvalds1da177e2005-04-16 15:20:36 -07004149 tpnt->driver = &st_template;
Linus Torvalds1da177e2005-04-16 15:20:36 -07004150
4151 tpnt->device = SDp;
4152 if (SDp->scsi_level <= 2)
4153 tpnt->tape_type = MT_ISSCSI1;
4154 else
4155 tpnt->tape_type = MT_ISSCSI2;
4156
4157 tpnt->buffer = buffer;
Kai Makisaraf03a5672005-08-02 13:40:47 +03004158 tpnt->buffer->last_SRpnt = NULL;
Linus Torvalds1da177e2005-04-16 15:20:36 -07004159
4160 tpnt->inited = 0;
4161 tpnt->dirty = 0;
4162 tpnt->in_use = 0;
4163 tpnt->drv_buffer = 1; /* Try buffering if no mode sense */
4164 tpnt->restr_dma = (SDp->host)->unchecked_isa_dma;
4165 tpnt->use_pf = (SDp->scsi_level >= SCSI_2);
4166 tpnt->density = 0;
4167 tpnt->do_auto_lock = ST_AUTO_LOCK;
4168 tpnt->can_bsr = (SDp->scsi_level > 2 ? 1 : ST_IN_FILE_POS); /* BSR mandatory in SCSI3 */
4169 tpnt->can_partitions = 0;
4170 tpnt->two_fm = ST_TWO_FM;
4171 tpnt->fast_mteom = ST_FAST_MTEOM;
4172 tpnt->scsi2_logical = ST_SCSI2LOGICAL;
Kai Makisara40f6b362008-02-24 22:23:24 +02004173 tpnt->sili = ST_SILI;
Linus Torvalds1da177e2005-04-16 15:20:36 -07004174 tpnt->immediate = ST_NOWAIT;
Lee Duncanc743e442012-03-01 12:41:01 -08004175 tpnt->immediate_filemark = 0;
Linus Torvalds1da177e2005-04-16 15:20:36 -07004176 tpnt->default_drvbuffer = 0xff; /* No forced buffering */
4177 tpnt->partition = 0;
4178 tpnt->new_partition = 0;
4179 tpnt->nbr_partitions = 0;
James Bottomleya02488e2008-11-30 10:36:26 -06004180 blk_queue_rq_timeout(tpnt->device->request_queue, ST_TIMEOUT);
Linus Torvalds1da177e2005-04-16 15:20:36 -07004181 tpnt->long_timeout = ST_LONG_TIMEOUT;
4182 tpnt->try_dio = try_direct_io && !SDp->host->unchecked_isa_dma;
4183
Linus Torvalds1da177e2005-04-16 15:20:36 -07004184 for (i = 0; i < ST_NBR_MODES; i++) {
4185 STm = &(tpnt->modes[i]);
4186 STm->defined = 0;
4187 STm->sysv = ST_SYSV;
4188 STm->defaults_for_writes = 0;
4189 STm->do_async_writes = ST_ASYNC_WRITES;
4190 STm->do_buffer_writes = ST_BUFFER_WRITES;
4191 STm->do_read_ahead = ST_READ_AHEAD;
4192 STm->default_compression = ST_DONT_TOUCH;
4193 STm->default_blksize = (-1); /* No forced size */
4194 STm->default_density = (-1); /* No forced density */
Jeff Mahoney6c648d92012-08-18 15:20:39 -04004195 STm->tape = tpnt;
Linus Torvalds1da177e2005-04-16 15:20:36 -07004196 }
4197
4198 for (i = 0; i < ST_NBR_PARTITIONS; i++) {
4199 STps = &(tpnt->ps[i]);
4200 STps->rw = ST_IDLE;
4201 STps->eof = ST_NOEOF;
4202 STps->at_sm = 0;
4203 STps->last_block_valid = 0;
4204 STps->drv_block = (-1);
4205 STps->drv_file = (-1);
4206 }
4207
4208 tpnt->current_mode = 0;
4209 tpnt->modes[0].defined = 1;
4210
4211 tpnt->density_changed = tpnt->compression_changed =
4212 tpnt->blksize_changed = 0;
Matthias Kaehlcke28f85002007-07-29 23:38:15 +02004213 mutex_init(&tpnt->lock);
Linus Torvalds1da177e2005-04-16 15:20:36 -07004214
Tejun Heob98c52b2013-02-27 17:04:42 -08004215 idr_preload(GFP_KERNEL);
Jeff Mahoney6c648d92012-08-18 15:20:39 -04004216 spin_lock(&st_index_lock);
Tejun Heob98c52b2013-02-27 17:04:42 -08004217 error = idr_alloc(&st_index_idr, tpnt, 0, ST_MAX_TAPES + 1, GFP_NOWAIT);
Jeff Mahoney6c648d92012-08-18 15:20:39 -04004218 spin_unlock(&st_index_lock);
Tejun Heob98c52b2013-02-27 17:04:42 -08004219 idr_preload_end();
4220 if (error < 0) {
Jeff Mahoney6c648d92012-08-18 15:20:39 -04004221 pr_warn("st: idr allocation failed: %d\n", error);
Joe Lawrence2b5bebc2013-03-05 10:57:56 -05004222 goto out_put_queue;
Jeff Mahoney6c648d92012-08-18 15:20:39 -04004223 }
Tejun Heob98c52b2013-02-27 17:04:42 -08004224 tpnt->index = error;
4225 sprintf(disk->disk_name, "st%d", tpnt->index);
Jeff Mahoney6c648d92012-08-18 15:20:39 -04004226
4227 dev_set_drvdata(dev, tpnt);
Linus Torvalds1da177e2005-04-16 15:20:36 -07004228
Linus Torvalds1da177e2005-04-16 15:20:36 -07004229
Jeff Mahoney26898af2012-08-18 15:20:40 -04004230 error = create_cdevs(tpnt);
4231 if (error)
4232 goto out_remove_devs;
Oliver Neukum46a243f2012-01-15 00:16:51 +01004233 scsi_autopm_put_device(SDp);
Linus Torvalds1da177e2005-04-16 15:20:36 -07004234
Kai Makisara422528542006-11-07 21:56:38 +02004235 sdev_printk(KERN_NOTICE, SDp,
Rene Herman8b1ea242006-05-20 15:00:22 -07004236 "Attached scsi tape %s\n", tape_name(tpnt));
Kai Makisara422528542006-11-07 21:56:38 +02004237 sdev_printk(KERN_INFO, SDp, "%s: try direct i/o: %s (alignment %d B)\n",
4238 tape_name(tpnt), tpnt->try_dio ? "yes" : "no",
4239 queue_dma_alignment(SDp->request_queue) + 1);
Linus Torvalds1da177e2005-04-16 15:20:36 -07004240
4241 return 0;
4242
Jeff Mahoney26898af2012-08-18 15:20:40 -04004243out_remove_devs:
4244 remove_cdevs(tpnt);
Jeff Mahoney6c648d92012-08-18 15:20:39 -04004245 spin_lock(&st_index_lock);
Tejun Heob98c52b2013-02-27 17:04:42 -08004246 idr_remove(&st_index_idr, tpnt->index);
Jeff Mahoney6c648d92012-08-18 15:20:39 -04004247 spin_unlock(&st_index_lock);
Joe Lawrence2b5bebc2013-03-05 10:57:56 -05004248out_put_queue:
4249 blk_put_queue(disk->queue);
Linus Torvalds1da177e2005-04-16 15:20:36 -07004250out_put_disk:
4251 put_disk(disk);
Jesper Juhlc9475cb2005-11-07 01:01:26 -08004252 kfree(tpnt);
Linus Torvalds1da177e2005-04-16 15:20:36 -07004253out_buffer_free:
4254 kfree(buffer);
4255out:
Subhash Jadavani6fe8c1d2014-09-10 14:54:09 +03004256 scsi_autopm_put_device(SDp);
Linus Torvalds1da177e2005-04-16 15:20:36 -07004257 return -ENODEV;
4258};
4259
4260
4261static int st_remove(struct device *dev)
4262{
Jeff Mahoney6c648d92012-08-18 15:20:39 -04004263 struct scsi_tape *tpnt = dev_get_drvdata(dev);
Jeff Mahoney6c648d92012-08-18 15:20:39 -04004264 int index = tpnt->index;
Linus Torvalds1da177e2005-04-16 15:20:36 -07004265
Jeff Mahoney6c648d92012-08-18 15:20:39 -04004266 scsi_autopm_get_device(to_scsi_device(dev));
Jeff Mahoney26898af2012-08-18 15:20:40 -04004267 remove_cdevs(tpnt);
Linus Torvalds1da177e2005-04-16 15:20:36 -07004268
Jeff Mahoney6c648d92012-08-18 15:20:39 -04004269 mutex_lock(&st_ref_mutex);
4270 kref_put(&tpnt->kref, scsi_tape_release);
4271 mutex_unlock(&st_ref_mutex);
4272 spin_lock(&st_index_lock);
4273 idr_remove(&st_index_idr, index);
4274 spin_unlock(&st_index_lock);
Linus Torvalds1da177e2005-04-16 15:20:36 -07004275 return 0;
4276}
4277
Kai Makisaraf03a5672005-08-02 13:40:47 +03004278/**
4279 * scsi_tape_release - Called to free the Scsi_Tape structure
4280 * @kref: pointer to embedded kref
4281 *
Arjan van de Ven0b950672006-01-11 13:16:10 +01004282 * st_ref_mutex must be held entering this routine. Because it is
Kai Makisaraf03a5672005-08-02 13:40:47 +03004283 * called on last put, you should always use the scsi_tape_get()
4284 * scsi_tape_put() helpers which manipulate the semaphore directly
4285 * and never do a direct kref_put().
4286 **/
4287static void scsi_tape_release(struct kref *kref)
4288{
4289 struct scsi_tape *tpnt = to_scsi_tape(kref);
4290 struct gendisk *disk = tpnt->disk;
4291
4292 tpnt->device = NULL;
4293
4294 if (tpnt->buffer) {
Kai Makisaraf03a5672005-08-02 13:40:47 +03004295 normalize_buffer(tpnt->buffer);
FUJITA Tomonorid0e1ae32008-12-18 14:49:40 +09004296 kfree(tpnt->buffer->reserved_pages);
Kai Makisaraf03a5672005-08-02 13:40:47 +03004297 kfree(tpnt->buffer);
4298 }
4299
4300 disk->private_data = NULL;
4301 put_disk(disk);
4302 kfree(tpnt);
4303 return;
4304}
4305
Jeff Mahoneyaf237822012-08-18 15:20:37 -04004306static struct class st_sysfs_class = {
4307 .name = "scsi_tape",
Greg Kroah-Hartmanc69c6be2013-07-24 15:05:29 -07004308 .dev_groups = st_dev_groups,
Jeff Mahoneyaf237822012-08-18 15:20:37 -04004309};
4310
Linus Torvalds1da177e2005-04-16 15:20:36 -07004311static int __init init_st(void)
4312{
Jeff Garzik13026a62006-10-04 06:00:38 -04004313 int err;
4314
Linus Torvalds1da177e2005-04-16 15:20:36 -07004315 validate_options();
4316
Jeff Garzik13026a62006-10-04 06:00:38 -04004317 printk(KERN_INFO "st: Version %s, fixed bufsize %d, s/g segs %d\n",
Linus Torvalds1da177e2005-04-16 15:20:36 -07004318 verstr, st_fixed_buffer_size, st_max_sg_segs);
4319
Laurence Oberman2bec7082014-10-19 09:44:25 -04004320 debugging = (debug_flag > 0) ? debug_flag : NO_DEBUG;
4321 if (debugging) {
4322 printk(KERN_INFO "st: Debugging enabled debug_flag = %d\n",
4323 debugging);
4324 }
4325
Jeff Mahoneyaf237822012-08-18 15:20:37 -04004326 err = class_register(&st_sysfs_class);
4327 if (err) {
4328 pr_err("Unable register sysfs class for SCSI tapes\n");
4329 return err;
Linus Torvalds1da177e2005-04-16 15:20:36 -07004330 }
4331
Jeff Garzik13026a62006-10-04 06:00:38 -04004332 err = register_chrdev_region(MKDEV(SCSI_TAPE_MAJOR, 0),
4333 ST_MAX_TAPE_ENTRIES, "st");
4334 if (err) {
4335 printk(KERN_ERR "Unable to get major %d for SCSI tapes\n",
4336 SCSI_TAPE_MAJOR);
4337 goto err_class;
Linus Torvalds1da177e2005-04-16 15:20:36 -07004338 }
Jeff Garzik13026a62006-10-04 06:00:38 -04004339
4340 err = scsi_register_driver(&st_template.gendrv);
4341 if (err)
4342 goto err_chrdev;
4343
Robert P. J. Day405ae7d2007-02-17 19:13:42 +01004344 err = do_create_sysfs_files();
Jeff Garzik13026a62006-10-04 06:00:38 -04004345 if (err)
4346 goto err_scsidrv;
4347
4348 return 0;
4349
4350err_scsidrv:
4351 scsi_unregister_driver(&st_template.gendrv);
4352err_chrdev:
4353 unregister_chrdev_region(MKDEV(SCSI_TAPE_MAJOR, 0),
4354 ST_MAX_TAPE_ENTRIES);
4355err_class:
Jeff Mahoneyaf237822012-08-18 15:20:37 -04004356 class_unregister(&st_sysfs_class);
Jeff Garzik13026a62006-10-04 06:00:38 -04004357 return err;
Linus Torvalds1da177e2005-04-16 15:20:36 -07004358}
4359
4360static void __exit exit_st(void)
4361{
Robert P. J. Day405ae7d2007-02-17 19:13:42 +01004362 do_remove_sysfs_files();
Linus Torvalds1da177e2005-04-16 15:20:36 -07004363 scsi_unregister_driver(&st_template.gendrv);
4364 unregister_chrdev_region(MKDEV(SCSI_TAPE_MAJOR, 0),
4365 ST_MAX_TAPE_ENTRIES);
Jeff Mahoneyaf237822012-08-18 15:20:37 -04004366 class_unregister(&st_sysfs_class);
Linus Torvalds1da177e2005-04-16 15:20:36 -07004367 printk(KERN_INFO "st: Unloaded.\n");
4368}
4369
4370module_init(init_st);
4371module_exit(exit_st);
4372
4373
4374/* The sysfs driver interface. Read-only at the moment */
4375static ssize_t st_try_direct_io_show(struct device_driver *ddp, char *buf)
4376{
4377 return snprintf(buf, PAGE_SIZE, "%d\n", try_direct_io);
4378}
4379static DRIVER_ATTR(try_direct_io, S_IRUGO, st_try_direct_io_show, NULL);
4380
4381static ssize_t st_fixed_buffer_size_show(struct device_driver *ddp, char *buf)
4382{
4383 return snprintf(buf, PAGE_SIZE, "%d\n", st_fixed_buffer_size);
4384}
4385static DRIVER_ATTR(fixed_buffer_size, S_IRUGO, st_fixed_buffer_size_show, NULL);
4386
4387static ssize_t st_max_sg_segs_show(struct device_driver *ddp, char *buf)
4388{
4389 return snprintf(buf, PAGE_SIZE, "%d\n", st_max_sg_segs);
4390}
4391static DRIVER_ATTR(max_sg_segs, S_IRUGO, st_max_sg_segs_show, NULL);
4392
4393static ssize_t st_version_show(struct device_driver *ddd, char *buf)
4394{
4395 return snprintf(buf, PAGE_SIZE, "[%s]\n", verstr);
4396}
4397static DRIVER_ATTR(version, S_IRUGO, st_version_show, NULL);
4398
Robert P. J. Day405ae7d2007-02-17 19:13:42 +01004399static int do_create_sysfs_files(void)
Linus Torvalds1da177e2005-04-16 15:20:36 -07004400{
Robert P. J. Day405ae7d2007-02-17 19:13:42 +01004401 struct device_driver *sysfs = &st_template.gendrv;
Jeff Garzik13026a62006-10-04 06:00:38 -04004402 int err;
Linus Torvalds1da177e2005-04-16 15:20:36 -07004403
Robert P. J. Day405ae7d2007-02-17 19:13:42 +01004404 err = driver_create_file(sysfs, &driver_attr_try_direct_io);
Jeff Garzik13026a62006-10-04 06:00:38 -04004405 if (err)
4406 return err;
Robert P. J. Day405ae7d2007-02-17 19:13:42 +01004407 err = driver_create_file(sysfs, &driver_attr_fixed_buffer_size);
Jeff Garzik13026a62006-10-04 06:00:38 -04004408 if (err)
4409 goto err_try_direct_io;
Robert P. J. Day405ae7d2007-02-17 19:13:42 +01004410 err = driver_create_file(sysfs, &driver_attr_max_sg_segs);
Jeff Garzik13026a62006-10-04 06:00:38 -04004411 if (err)
4412 goto err_attr_fixed_buf;
Robert P. J. Day405ae7d2007-02-17 19:13:42 +01004413 err = driver_create_file(sysfs, &driver_attr_version);
Jeff Garzik13026a62006-10-04 06:00:38 -04004414 if (err)
4415 goto err_attr_max_sg;
4416
4417 return 0;
4418
4419err_attr_max_sg:
Robert P. J. Day405ae7d2007-02-17 19:13:42 +01004420 driver_remove_file(sysfs, &driver_attr_max_sg_segs);
Jeff Garzik13026a62006-10-04 06:00:38 -04004421err_attr_fixed_buf:
Robert P. J. Day405ae7d2007-02-17 19:13:42 +01004422 driver_remove_file(sysfs, &driver_attr_fixed_buffer_size);
Jeff Garzik13026a62006-10-04 06:00:38 -04004423err_try_direct_io:
Robert P. J. Day405ae7d2007-02-17 19:13:42 +01004424 driver_remove_file(sysfs, &driver_attr_try_direct_io);
Jeff Garzik13026a62006-10-04 06:00:38 -04004425 return err;
Linus Torvalds1da177e2005-04-16 15:20:36 -07004426}
4427
Robert P. J. Day405ae7d2007-02-17 19:13:42 +01004428static void do_remove_sysfs_files(void)
Linus Torvalds1da177e2005-04-16 15:20:36 -07004429{
Robert P. J. Day405ae7d2007-02-17 19:13:42 +01004430 struct device_driver *sysfs = &st_template.gendrv;
Linus Torvalds1da177e2005-04-16 15:20:36 -07004431
Robert P. J. Day405ae7d2007-02-17 19:13:42 +01004432 driver_remove_file(sysfs, &driver_attr_version);
4433 driver_remove_file(sysfs, &driver_attr_max_sg_segs);
4434 driver_remove_file(sysfs, &driver_attr_fixed_buffer_size);
4435 driver_remove_file(sysfs, &driver_attr_try_direct_io);
Linus Torvalds1da177e2005-04-16 15:20:36 -07004436}
4437
Linus Torvalds1da177e2005-04-16 15:20:36 -07004438/* The sysfs simple class interface */
Tony Jonesee959b02008-02-22 00:13:36 +01004439static ssize_t
Jeff Mahoneyaf237822012-08-18 15:20:37 -04004440defined_show(struct device *dev, struct device_attribute *attr, char *buf)
Linus Torvalds1da177e2005-04-16 15:20:36 -07004441{
James Bottomley7d15d6a2008-03-14 14:12:43 -07004442 struct st_modedef *STm = dev_get_drvdata(dev);
Linus Torvalds1da177e2005-04-16 15:20:36 -07004443 ssize_t l = 0;
4444
4445 l = snprintf(buf, PAGE_SIZE, "%d\n", STm->defined);
4446 return l;
4447}
Greg Kroah-Hartmanc69c6be2013-07-24 15:05:29 -07004448static DEVICE_ATTR_RO(defined);
Linus Torvalds1da177e2005-04-16 15:20:36 -07004449
Tony Jonesee959b02008-02-22 00:13:36 +01004450static ssize_t
Jeff Mahoneyaf237822012-08-18 15:20:37 -04004451default_blksize_show(struct device *dev, struct device_attribute *attr,
4452 char *buf)
Linus Torvalds1da177e2005-04-16 15:20:36 -07004453{
James Bottomley7d15d6a2008-03-14 14:12:43 -07004454 struct st_modedef *STm = dev_get_drvdata(dev);
Linus Torvalds1da177e2005-04-16 15:20:36 -07004455 ssize_t l = 0;
4456
4457 l = snprintf(buf, PAGE_SIZE, "%d\n", STm->default_blksize);
4458 return l;
4459}
Greg Kroah-Hartmanc69c6be2013-07-24 15:05:29 -07004460static DEVICE_ATTR_RO(default_blksize);
Linus Torvalds1da177e2005-04-16 15:20:36 -07004461
Tony Jonesee959b02008-02-22 00:13:36 +01004462static ssize_t
Jeff Mahoneyaf237822012-08-18 15:20:37 -04004463default_density_show(struct device *dev, struct device_attribute *attr,
4464 char *buf)
Linus Torvalds1da177e2005-04-16 15:20:36 -07004465{
James Bottomley7d15d6a2008-03-14 14:12:43 -07004466 struct st_modedef *STm = dev_get_drvdata(dev);
Linus Torvalds1da177e2005-04-16 15:20:36 -07004467 ssize_t l = 0;
4468 char *fmt;
4469
4470 fmt = STm->default_density >= 0 ? "0x%02x\n" : "%d\n";
4471 l = snprintf(buf, PAGE_SIZE, fmt, STm->default_density);
4472 return l;
4473}
Greg Kroah-Hartmanc69c6be2013-07-24 15:05:29 -07004474static DEVICE_ATTR_RO(default_density);
Linus Torvalds1da177e2005-04-16 15:20:36 -07004475
Tony Jonesee959b02008-02-22 00:13:36 +01004476static ssize_t
Jeff Mahoneyaf237822012-08-18 15:20:37 -04004477default_compression_show(struct device *dev, struct device_attribute *attr,
4478 char *buf)
Linus Torvalds1da177e2005-04-16 15:20:36 -07004479{
James Bottomley7d15d6a2008-03-14 14:12:43 -07004480 struct st_modedef *STm = dev_get_drvdata(dev);
Linus Torvalds1da177e2005-04-16 15:20:36 -07004481 ssize_t l = 0;
4482
4483 l = snprintf(buf, PAGE_SIZE, "%d\n", STm->default_compression - 1);
4484 return l;
4485}
Greg Kroah-Hartmanc69c6be2013-07-24 15:05:29 -07004486static DEVICE_ATTR_RO(default_compression);
Linus Torvalds1da177e2005-04-16 15:20:36 -07004487
Tony Jonesee959b02008-02-22 00:13:36 +01004488static ssize_t
Jeff Mahoneyaf237822012-08-18 15:20:37 -04004489options_show(struct device *dev, struct device_attribute *attr, char *buf)
Kai Makisarab174be02008-02-24 22:29:12 +02004490{
James Bottomley7d15d6a2008-03-14 14:12:43 -07004491 struct st_modedef *STm = dev_get_drvdata(dev);
Jeff Mahoney6c648d92012-08-18 15:20:39 -04004492 struct scsi_tape *STp = STm->tape;
4493 int options;
Kai Makisarab174be02008-02-24 22:29:12 +02004494 ssize_t l = 0;
4495
Kai Makisarab174be02008-02-24 22:29:12 +02004496 options = STm->do_buffer_writes ? MT_ST_BUFFER_WRITES : 0;
4497 options |= STm->do_async_writes ? MT_ST_ASYNC_WRITES : 0;
4498 options |= STm->do_read_ahead ? MT_ST_READ_AHEAD : 0;
4499 DEB( options |= debugging ? MT_ST_DEBUGGING : 0 );
4500 options |= STp->two_fm ? MT_ST_TWO_FM : 0;
4501 options |= STp->fast_mteom ? MT_ST_FAST_MTEOM : 0;
4502 options |= STm->defaults_for_writes ? MT_ST_DEF_WRITES : 0;
4503 options |= STp->can_bsr ? MT_ST_CAN_BSR : 0;
4504 options |= STp->omit_blklims ? MT_ST_NO_BLKLIMS : 0;
4505 options |= STp->can_partitions ? MT_ST_CAN_PARTITIONS : 0;
4506 options |= STp->scsi2_logical ? MT_ST_SCSI2LOGICAL : 0;
4507 options |= STm->sysv ? MT_ST_SYSV : 0;
4508 options |= STp->immediate ? MT_ST_NOWAIT : 0;
Lee Duncanc743e442012-03-01 12:41:01 -08004509 options |= STp->immediate_filemark ? MT_ST_NOWAIT_EOF : 0;
Kai Makisarab174be02008-02-24 22:29:12 +02004510 options |= STp->sili ? MT_ST_SILI : 0;
4511
4512 l = snprintf(buf, PAGE_SIZE, "0x%08x\n", options);
4513 return l;
4514}
Greg Kroah-Hartmanc69c6be2013-07-24 15:05:29 -07004515static DEVICE_ATTR_RO(options);
Kai Makisarab174be02008-02-24 22:29:12 +02004516
Greg Kroah-Hartmanc69c6be2013-07-24 15:05:29 -07004517static struct attribute *st_dev_attrs[] = {
4518 &dev_attr_defined.attr,
4519 &dev_attr_default_blksize.attr,
4520 &dev_attr_default_density.attr,
4521 &dev_attr_default_compression.attr,
4522 &dev_attr_options.attr,
4523 NULL,
Jeff Mahoneyaf237822012-08-18 15:20:37 -04004524};
Greg Kroah-Hartmanc69c6be2013-07-24 15:05:29 -07004525ATTRIBUTE_GROUPS(st_dev);
Kai Makisarab174be02008-02-24 22:29:12 +02004526
Linus Torvalds1da177e2005-04-16 15:20:36 -07004527/* The following functions may be useful for a larger audience. */
FUJITA Tomonori66207422008-12-18 14:49:43 +09004528static int sgl_map_user_pages(struct st_buffer *STbp,
4529 const unsigned int max_pages, unsigned long uaddr,
4530 size_t count, int rw)
Linus Torvalds1da177e2005-04-16 15:20:36 -07004531{
James Bottomley07542b82005-08-31 20:27:22 -04004532 unsigned long end = (uaddr + count + PAGE_SIZE - 1) >> PAGE_SHIFT;
4533 unsigned long start = uaddr >> PAGE_SHIFT;
4534 const int nr_pages = end - start;
Linus Torvalds1da177e2005-04-16 15:20:36 -07004535 int res, i, j;
Linus Torvalds1da177e2005-04-16 15:20:36 -07004536 struct page **pages;
FUJITA Tomonori66207422008-12-18 14:49:43 +09004537 struct rq_map_data *mdata = &STbp->map_data;
Linus Torvalds1da177e2005-04-16 15:20:36 -07004538
Linus Torvalds1da177e2005-04-16 15:20:36 -07004539 /* User attempted Overflow! */
4540 if ((uaddr + count) < uaddr)
4541 return -EINVAL;
4542
4543 /* Too big */
4544 if (nr_pages > max_pages)
4545 return -ENOMEM;
4546
4547 /* Hmm? */
4548 if (count == 0)
4549 return 0;
4550
4551 if ((pages = kmalloc(max_pages * sizeof(*pages), GFP_KERNEL)) == NULL)
4552 return -ENOMEM;
4553
4554 /* Try to fault in all of the necessary pages */
4555 down_read(&current->mm->mmap_sem);
4556 /* rw==READ means read from drive, write into memory area */
4557 res = get_user_pages(
4558 current,
4559 current->mm,
4560 uaddr,
4561 nr_pages,
4562 rw == READ,
4563 0, /* don't force */
4564 pages,
4565 NULL);
4566 up_read(&current->mm->mmap_sem);
4567
4568 /* Errors and no page mapped should return here */
4569 if (res < nr_pages)
4570 goto out_unmap;
4571
4572 for (i=0; i < nr_pages; i++) {
4573 /* FIXME: flush superflous for rw==READ,
4574 * probably wrong function for rw==WRITE
4575 */
4576 flush_dcache_page(pages[i]);
4577 }
4578
FUJITA Tomonori66207422008-12-18 14:49:43 +09004579 mdata->offset = uaddr & ~PAGE_MASK;
FUJITA Tomonori66207422008-12-18 14:49:43 +09004580 STbp->mapped_pages = pages;
Linus Torvalds1da177e2005-04-16 15:20:36 -07004581
Linus Torvalds1da177e2005-04-16 15:20:36 -07004582 return nr_pages;
Linus Torvalds1da177e2005-04-16 15:20:36 -07004583 out_unmap:
4584 if (res > 0) {
4585 for (j=0; j < res; j++)
4586 page_cache_release(pages[j]);
Hugh Dickins6bc733e2005-12-01 20:21:57 +00004587 res = 0;
Linus Torvalds1da177e2005-04-16 15:20:36 -07004588 }
4589 kfree(pages);
4590 return res;
4591}
4592
4593
4594/* And unmap them... */
FUJITA Tomonori66207422008-12-18 14:49:43 +09004595static int sgl_unmap_user_pages(struct st_buffer *STbp,
4596 const unsigned int nr_pages, int dirtied)
Linus Torvalds1da177e2005-04-16 15:20:36 -07004597{
4598 int i;
4599
4600 for (i=0; i < nr_pages; i++) {
FUJITA Tomonori66207422008-12-18 14:49:43 +09004601 struct page *page = STbp->mapped_pages[i];
Nick Pigginb5810032005-10-29 18:16:12 -07004602
Nick Pigginb5810032005-10-29 18:16:12 -07004603 if (dirtied)
4604 SetPageDirty(page);
Linus Torvalds1da177e2005-04-16 15:20:36 -07004605 /* FIXME: cache flush missing for rw==READ
4606 * FIXME: call the correct reference counting function
4607 */
Nick Pigginb5810032005-10-29 18:16:12 -07004608 page_cache_release(page);
Linus Torvalds1da177e2005-04-16 15:20:36 -07004609 }
FUJITA Tomonori66207422008-12-18 14:49:43 +09004610 kfree(STbp->mapped_pages);
4611 STbp->mapped_pages = NULL;
Linus Torvalds1da177e2005-04-16 15:20:36 -07004612
4613 return 0;
4614}