blob: 7179f79d746838f24640ac7c59fadb41a1c5f024 [file] [log] [blame]
Linus Torvalds1da177e2005-04-16 15:20:36 -07001/*
2 pt.c (c) 1998 Grant R. Guenther <grant@torque.net>
3 Under the terms of the GNU General Public License.
4
5 This is the high-level driver for parallel port ATAPI tape
6 drives based on chips supported by the paride module.
7
8 The driver implements both rewinding and non-rewinding
9 devices, filemarks, and the rewind ioctl. It allocates
10 a small internal "bounce buffer" for each open device, but
11 otherwise expects buffering and blocking to be done at the
12 user level. As with most block-structured tapes, short
13 writes are padded to full tape blocks, so reading back a file
14 may return more data than was actually written.
15
16 By default, the driver will autoprobe for a single parallel
17 port ATAPI tape drive, but if their individual parameters are
18 specified, the driver can handle up to 4 drives.
19
20 The rewinding devices are named /dev/pt0, /dev/pt1, ...
21 while the non-rewinding devices are /dev/npt0, /dev/npt1, etc.
22
23 The behaviour of the pt driver can be altered by setting
24 some parameters from the insmod command line. The following
25 parameters are adjustable:
26
27 drive0 These four arguments can be arrays of
28 drive1 1-6 integers as follows:
29 drive2
30 drive3 <prt>,<pro>,<uni>,<mod>,<slv>,<dly>
31
32 Where,
33
34 <prt> is the base of the parallel port address for
35 the corresponding drive. (required)
36
37 <pro> is the protocol number for the adapter that
38 supports this drive. These numbers are
39 logged by 'paride' when the protocol modules
40 are initialised. (0 if not given)
41
42 <uni> for those adapters that support chained
43 devices, this is the unit selector for the
44 chain of devices on the given port. It should
45 be zero for devices that don't support chaining.
46 (0 if not given)
47
48 <mod> this can be -1 to choose the best mode, or one
49 of the mode numbers supported by the adapter.
50 (-1 if not given)
51
52 <slv> ATAPI devices can be jumpered to master or slave.
53 Set this to 0 to choose the master drive, 1 to
54 choose the slave, -1 (the default) to choose the
55 first drive found.
56
57 <dly> some parallel ports require the driver to
58 go more slowly. -1 sets a default value that
59 should work with the chosen protocol. Otherwise,
60 set this to a small integer, the larger it is
61 the slower the port i/o. In some cases, setting
62 this to zero will speed up the device. (default -1)
63
64 major You may use this parameter to overide the
65 default major number (96) that this driver
66 will use. Be sure to change the device
67 name as well.
68
69 name This parameter is a character string that
70 contains the name the kernel will use for this
71 device (in /proc output, for instance).
72 (default "pt").
73
74 verbose This parameter controls the amount of logging
75 that the driver will do. Set it to 0 for
76 normal operation, 1 to see autoprobe progress
77 messages, or 2 to see additional debugging
78 output. (default 0)
79
80 If this driver is built into the kernel, you can use
81 the following command line parameters, with the same values
82 as the corresponding module parameters listed above:
83
84 pt.drive0
85 pt.drive1
86 pt.drive2
87 pt.drive3
88
89 In addition, you can use the parameter pt.disable to disable
90 the driver entirely.
91
92*/
93
94/* Changes:
95
96 1.01 GRG 1998.05.06 Round up transfer size, fix ready_wait,
97 loosed interpretation of ATAPI standard
98 for clearing error status.
99 Eliminate sti();
100 1.02 GRG 1998.06.16 Eliminate an Ugh.
101 1.03 GRG 1998.08.15 Adjusted PT_TMO, use HZ in loop timing,
102 extra debugging
103 1.04 GRG 1998.09.24 Repair minor coding error, added jumbo support
104
105*/
106
107#define PT_VERSION "1.04"
108#define PT_MAJOR 96
109#define PT_NAME "pt"
110#define PT_UNITS 4
111
112/* Here are things one can override from the insmod command.
113 Most are autoprobed by paride unless set here. Verbose is on
114 by default.
115
116*/
117
118static int verbose = 0;
119static int major = PT_MAJOR;
120static char *name = PT_NAME;
121static int disable = 0;
122
123static int drive0[6] = { 0, 0, 0, -1, -1, -1 };
124static int drive1[6] = { 0, 0, 0, -1, -1, -1 };
125static int drive2[6] = { 0, 0, 0, -1, -1, -1 };
126static int drive3[6] = { 0, 0, 0, -1, -1, -1 };
127
128static int (*drives[4])[6] = {&drive0, &drive1, &drive2, &drive3};
129
130#define D_PRT 0
131#define D_PRO 1
132#define D_UNI 2
133#define D_MOD 3
134#define D_SLV 4
135#define D_DLY 5
136
137#define DU (*drives[unit])
138
139/* end of parameters */
140
141#include <linux/module.h>
142#include <linux/init.h>
143#include <linux/fs.h>
Linus Torvalds1da177e2005-04-16 15:20:36 -0700144#include <linux/delay.h>
145#include <linux/slab.h>
146#include <linux/mtio.h>
147#include <linux/device.h>
Tim Schmielau4e57b682005-10-30 15:03:48 -0800148#include <linux/sched.h> /* current, TASK_*, schedule_timeout() */
Arnd Bergmann613655f2010-06-02 14:28:52 +0200149#include <linux/mutex.h>
Linus Torvalds1da177e2005-04-16 15:20:36 -0700150
151#include <asm/uaccess.h>
152
153module_param(verbose, bool, 0);
154module_param(major, int, 0);
155module_param(name, charp, 0);
156module_param_array(drive0, int, NULL, 0);
157module_param_array(drive1, int, NULL, 0);
158module_param_array(drive2, int, NULL, 0);
159module_param_array(drive3, int, NULL, 0);
160
161#include "paride.h"
162
163#define PT_MAX_RETRIES 5
164#define PT_TMO 3000 /* interrupt timeout in jiffies */
165#define PT_SPIN_DEL 50 /* spin delay in micro-seconds */
166#define PT_RESET_TMO 30 /* 30 seconds */
167#define PT_READY_TMO 60 /* 60 seconds */
168#define PT_REWIND_TMO 1200 /* 20 minutes */
169
170#define PT_SPIN ((1000000/(HZ*PT_SPIN_DEL))*PT_TMO)
171
172#define STAT_ERR 0x00001
173#define STAT_INDEX 0x00002
174#define STAT_ECC 0x00004
175#define STAT_DRQ 0x00008
176#define STAT_SEEK 0x00010
177#define STAT_WRERR 0x00020
178#define STAT_READY 0x00040
179#define STAT_BUSY 0x00080
180#define STAT_SENSE 0x1f000
181
182#define ATAPI_TEST_READY 0x00
183#define ATAPI_REWIND 0x01
184#define ATAPI_REQ_SENSE 0x03
185#define ATAPI_READ_6 0x08
186#define ATAPI_WRITE_6 0x0a
187#define ATAPI_WFM 0x10
188#define ATAPI_IDENTIFY 0x12
189#define ATAPI_MODE_SENSE 0x1a
190#define ATAPI_LOG_SENSE 0x4d
191
Arnd Bergmann613655f2010-06-02 14:28:52 +0200192static DEFINE_MUTEX(pt_mutex);
Linus Torvalds1da177e2005-04-16 15:20:36 -0700193static int pt_open(struct inode *inode, struct file *file);
Alan Coxbe1fd702008-07-04 09:51:21 +0200194static long pt_ioctl(struct file *file, unsigned int cmd, unsigned long arg);
Linus Torvalds1da177e2005-04-16 15:20:36 -0700195static int pt_release(struct inode *inode, struct file *file);
196static ssize_t pt_read(struct file *filp, char __user *buf,
197 size_t count, loff_t * ppos);
198static ssize_t pt_write(struct file *filp, const char __user *buf,
199 size_t count, loff_t * ppos);
200static int pt_detect(void);
201
202/* bits in tape->flags */
203
204#define PT_MEDIA 1
205#define PT_WRITE_OK 2
206#define PT_REWIND 4
207#define PT_WRITING 8
208#define PT_READING 16
209#define PT_EOF 32
210
211#define PT_NAMELEN 8
212#define PT_BUFSIZE 16384
213
214struct pt_unit {
215 struct pi_adapter pia; /* interface to paride layer */
216 struct pi_adapter *pi;
217 int flags; /* various state flags */
218 int last_sense; /* result of last request sense */
219 int drive; /* drive */
220 atomic_t available; /* 1 if access is available 0 otherwise */
221 int bs; /* block size */
222 int capacity; /* Size of tape in KB */
223 int present; /* device present ? */
224 char *bufptr;
225 char name[PT_NAMELEN]; /* pf0, pf1, ... */
226};
227
228static int pt_identify(struct pt_unit *tape);
229
230static struct pt_unit pt[PT_UNITS];
231
232static char pt_scratch[512]; /* scratch block buffer */
233
234/* kernel glue structures */
235
Arjan van de Ven2b8693c2007-02-12 00:55:32 -0800236static const struct file_operations pt_fops = {
Linus Torvalds1da177e2005-04-16 15:20:36 -0700237 .owner = THIS_MODULE,
238 .read = pt_read,
239 .write = pt_write,
Alan Coxbe1fd702008-07-04 09:51:21 +0200240 .unlocked_ioctl = pt_ioctl,
Linus Torvalds1da177e2005-04-16 15:20:36 -0700241 .open = pt_open,
242 .release = pt_release,
Arnd Bergmann6038f372010-08-15 18:52:59 +0200243 .llseek = noop_llseek,
Linus Torvalds1da177e2005-04-16 15:20:36 -0700244};
245
246/* sysfs class support */
gregkh@suse.dedeb36972005-03-23 09:52:10 -0800247static struct class *pt_class;
Linus Torvalds1da177e2005-04-16 15:20:36 -0700248
249static inline int status_reg(struct pi_adapter *pi)
250{
251 return pi_read_regr(pi, 1, 6);
252}
253
254static inline int read_reg(struct pi_adapter *pi, int reg)
255{
256 return pi_read_regr(pi, 0, reg);
257}
258
259static inline void write_reg(struct pi_adapter *pi, int reg, int val)
260{
261 pi_write_regr(pi, 0, reg, val);
262}
263
264static inline u8 DRIVE(struct pt_unit *tape)
265{
266 return 0xa0+0x10*tape->drive;
267}
268
269static int pt_wait(struct pt_unit *tape, int go, int stop, char *fun, char *msg)
270{
271 int j, r, e, s, p;
272 struct pi_adapter *pi = tape->pi;
273
274 j = 0;
275 while ((((r = status_reg(pi)) & go) || (stop && (!(r & stop))))
276 && (j++ < PT_SPIN))
277 udelay(PT_SPIN_DEL);
278
Roel Kluinc12ec0a2010-03-11 14:09:47 -0800279 if ((r & (STAT_ERR & stop)) || (j > PT_SPIN)) {
Linus Torvalds1da177e2005-04-16 15:20:36 -0700280 s = read_reg(pi, 7);
281 e = read_reg(pi, 1);
282 p = read_reg(pi, 2);
Roel Kluinc12ec0a2010-03-11 14:09:47 -0800283 if (j > PT_SPIN)
Linus Torvalds1da177e2005-04-16 15:20:36 -0700284 e |= 0x100;
285 if (fun)
286 printk("%s: %s %s: alt=0x%x stat=0x%x err=0x%x"
287 " loop=%d phase=%d\n",
288 tape->name, fun, msg, r, s, e, j, p);
289 return (e << 8) + s;
290 }
291 return 0;
292}
293
294static int pt_command(struct pt_unit *tape, char *cmd, int dlen, char *fun)
295{
296 struct pi_adapter *pi = tape->pi;
297 pi_connect(pi);
298
299 write_reg(pi, 6, DRIVE(tape));
300
301 if (pt_wait(tape, STAT_BUSY | STAT_DRQ, 0, fun, "before command")) {
302 pi_disconnect(pi);
303 return -1;
304 }
305
306 write_reg(pi, 4, dlen % 256);
307 write_reg(pi, 5, dlen / 256);
308 write_reg(pi, 7, 0xa0); /* ATAPI packet command */
309
310 if (pt_wait(tape, STAT_BUSY, STAT_DRQ, fun, "command DRQ")) {
311 pi_disconnect(pi);
312 return -1;
313 }
314
315 if (read_reg(pi, 2) != 1) {
316 printk("%s: %s: command phase error\n", tape->name, fun);
317 pi_disconnect(pi);
318 return -1;
319 }
320
321 pi_write_block(pi, cmd, 12);
322
323 return 0;
324}
325
326static int pt_completion(struct pt_unit *tape, char *buf, char *fun)
327{
328 struct pi_adapter *pi = tape->pi;
329 int r, s, n, p;
330
331 r = pt_wait(tape, STAT_BUSY, STAT_DRQ | STAT_READY | STAT_ERR,
332 fun, "completion");
333
334 if (read_reg(pi, 7) & STAT_DRQ) {
335 n = (((read_reg(pi, 4) + 256 * read_reg(pi, 5)) +
336 3) & 0xfffc);
337 p = read_reg(pi, 2) & 3;
338 if (p == 0)
339 pi_write_block(pi, buf, n);
340 if (p == 2)
341 pi_read_block(pi, buf, n);
342 }
343
344 s = pt_wait(tape, STAT_BUSY, STAT_READY | STAT_ERR, fun, "data done");
345
346 pi_disconnect(pi);
347
348 return (r ? r : s);
349}
350
351static void pt_req_sense(struct pt_unit *tape, int quiet)
352{
353 char rs_cmd[12] = { ATAPI_REQ_SENSE, 0, 0, 0, 16, 0, 0, 0, 0, 0, 0, 0 };
354 char buf[16];
355 int r;
356
357 r = pt_command(tape, rs_cmd, 16, "Request sense");
358 mdelay(1);
359 if (!r)
360 pt_completion(tape, buf, "Request sense");
361
362 tape->last_sense = -1;
363 if (!r) {
364 if (!quiet)
365 printk("%s: Sense key: %x, ASC: %x, ASQ: %x\n",
366 tape->name, buf[2] & 0xf, buf[12], buf[13]);
367 tape->last_sense = (buf[2] & 0xf) | ((buf[12] & 0xff) << 8)
368 | ((buf[13] & 0xff) << 16);
369 }
370}
371
372static int pt_atapi(struct pt_unit *tape, char *cmd, int dlen, char *buf, char *fun)
373{
374 int r;
375
376 r = pt_command(tape, cmd, dlen, fun);
377 mdelay(1);
378 if (!r)
379 r = pt_completion(tape, buf, fun);
380 if (r)
381 pt_req_sense(tape, !fun);
382
383 return r;
384}
385
386static void pt_sleep(int cs)
387{
Nishanth Aravamudan86e84862005-09-10 00:27:28 -0700388 schedule_timeout_interruptible(cs);
Linus Torvalds1da177e2005-04-16 15:20:36 -0700389}
390
391static int pt_poll_dsc(struct pt_unit *tape, int pause, int tmo, char *msg)
392{
393 struct pi_adapter *pi = tape->pi;
394 int k, e, s;
395
396 k = 0;
397 e = 0;
398 s = 0;
399 while (k < tmo) {
400 pt_sleep(pause);
401 k++;
402 pi_connect(pi);
403 write_reg(pi, 6, DRIVE(tape));
404 s = read_reg(pi, 7);
405 e = read_reg(pi, 1);
406 pi_disconnect(pi);
407 if (s & (STAT_ERR | STAT_SEEK))
408 break;
409 }
410 if ((k >= tmo) || (s & STAT_ERR)) {
411 if (k >= tmo)
412 printk("%s: %s DSC timeout\n", tape->name, msg);
413 else
414 printk("%s: %s stat=0x%x err=0x%x\n", tape->name, msg, s,
415 e);
416 pt_req_sense(tape, 0);
417 return 0;
418 }
419 return 1;
420}
421
422static void pt_media_access_cmd(struct pt_unit *tape, int tmo, char *cmd, char *fun)
423{
424 if (pt_command(tape, cmd, 0, fun)) {
425 pt_req_sense(tape, 0);
426 return;
427 }
428 pi_disconnect(tape->pi);
429 pt_poll_dsc(tape, HZ, tmo, fun);
430}
431
432static void pt_rewind(struct pt_unit *tape)
433{
434 char rw_cmd[12] = { ATAPI_REWIND, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0 };
435
436 pt_media_access_cmd(tape, PT_REWIND_TMO, rw_cmd, "rewind");
437}
438
439static void pt_write_fm(struct pt_unit *tape)
440{
441 char wm_cmd[12] = { ATAPI_WFM, 0, 0, 0, 1, 0, 0, 0, 0, 0, 0, 0 };
442
443 pt_media_access_cmd(tape, PT_TMO, wm_cmd, "write filemark");
444}
445
446#define DBMSG(msg) ((verbose>1)?(msg):NULL)
447
448static int pt_reset(struct pt_unit *tape)
449{
450 struct pi_adapter *pi = tape->pi;
451 int i, k, flg;
452 int expect[5] = { 1, 1, 1, 0x14, 0xeb };
453
454 pi_connect(pi);
455 write_reg(pi, 6, DRIVE(tape));
456 write_reg(pi, 7, 8);
457
458 pt_sleep(20 * HZ / 1000);
459
460 k = 0;
461 while ((k++ < PT_RESET_TMO) && (status_reg(pi) & STAT_BUSY))
462 pt_sleep(HZ / 10);
463
464 flg = 1;
465 for (i = 0; i < 5; i++)
466 flg &= (read_reg(pi, i + 1) == expect[i]);
467
468 if (verbose) {
469 printk("%s: Reset (%d) signature = ", tape->name, k);
470 for (i = 0; i < 5; i++)
471 printk("%3x", read_reg(pi, i + 1));
472 if (!flg)
473 printk(" (incorrect)");
474 printk("\n");
475 }
476
477 pi_disconnect(pi);
478 return flg - 1;
479}
480
481static int pt_ready_wait(struct pt_unit *tape, int tmo)
482{
483 char tr_cmd[12] = { ATAPI_TEST_READY, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0 };
484 int k, p;
485
486 k = 0;
487 while (k < tmo) {
488 tape->last_sense = 0;
489 pt_atapi(tape, tr_cmd, 0, NULL, DBMSG("test unit ready"));
490 p = tape->last_sense;
491 if (!p)
492 return 0;
493 if (!(((p & 0xffff) == 0x0402) || ((p & 0xff) == 6)))
494 return p;
495 k++;
496 pt_sleep(HZ);
497 }
498 return 0x000020; /* timeout */
499}
500
501static void xs(char *buf, char *targ, int offs, int len)
502{
503 int j, k, l;
504
505 j = 0;
506 l = 0;
507 for (k = 0; k < len; k++)
508 if ((buf[k + offs] != 0x20) || (buf[k + offs] != l))
509 l = targ[j++] = buf[k + offs];
510 if (l == 0x20)
511 j--;
512 targ[j] = 0;
513}
514
515static int xn(char *buf, int offs, int size)
516{
517 int v, k;
518
519 v = 0;
520 for (k = 0; k < size; k++)
521 v = v * 256 + (buf[k + offs] & 0xff);
522 return v;
523}
524
525static int pt_identify(struct pt_unit *tape)
526{
527 int dt, s;
528 char *ms[2] = { "master", "slave" };
529 char mf[10], id[18];
530 char id_cmd[12] = { ATAPI_IDENTIFY, 0, 0, 0, 36, 0, 0, 0, 0, 0, 0, 0 };
531 char ms_cmd[12] =
532 { ATAPI_MODE_SENSE, 0, 0x2a, 0, 36, 0, 0, 0, 0, 0, 0, 0 };
533 char ls_cmd[12] =
534 { ATAPI_LOG_SENSE, 0, 0x71, 0, 0, 0, 0, 0, 36, 0, 0, 0 };
535 char buf[36];
536
537 s = pt_atapi(tape, id_cmd, 36, buf, "identify");
538 if (s)
539 return -1;
540
541 dt = buf[0] & 0x1f;
542 if (dt != 1) {
543 if (verbose)
544 printk("%s: Drive %d, unsupported type %d\n",
545 tape->name, tape->drive, dt);
546 return -1;
547 }
548
549 xs(buf, mf, 8, 8);
550 xs(buf, id, 16, 16);
551
552 tape->flags = 0;
553 tape->capacity = 0;
554 tape->bs = 0;
555
556 if (!pt_ready_wait(tape, PT_READY_TMO))
557 tape->flags |= PT_MEDIA;
558
559 if (!pt_atapi(tape, ms_cmd, 36, buf, "mode sense")) {
560 if (!(buf[2] & 0x80))
561 tape->flags |= PT_WRITE_OK;
562 tape->bs = xn(buf, 10, 2);
563 }
564
565 if (!pt_atapi(tape, ls_cmd, 36, buf, "log sense"))
566 tape->capacity = xn(buf, 24, 4);
567
568 printk("%s: %s %s, %s", tape->name, mf, id, ms[tape->drive]);
569 if (!(tape->flags & PT_MEDIA))
570 printk(", no media\n");
571 else {
572 if (!(tape->flags & PT_WRITE_OK))
573 printk(", RO");
574 printk(", blocksize %d, %d MB\n", tape->bs, tape->capacity / 1024);
575 }
576
577 return 0;
578}
579
580
581/*
582 * returns 0, with id set if drive is detected
583 * -1, if drive detection failed
584 */
585static int pt_probe(struct pt_unit *tape)
586{
587 if (tape->drive == -1) {
588 for (tape->drive = 0; tape->drive <= 1; tape->drive++)
589 if (!pt_reset(tape))
590 return pt_identify(tape);
591 } else {
592 if (!pt_reset(tape))
593 return pt_identify(tape);
594 }
595 return -1;
596}
597
598static int pt_detect(void)
599{
600 struct pt_unit *tape;
601 int specified = 0, found = 0;
602 int unit;
603
604 printk("%s: %s version %s, major %d\n", name, name, PT_VERSION, major);
605
606 specified = 0;
607 for (unit = 0; unit < PT_UNITS; unit++) {
608 struct pt_unit *tape = &pt[unit];
609 tape->pi = &tape->pia;
610 atomic_set(&tape->available, 1);
611 tape->flags = 0;
612 tape->last_sense = 0;
613 tape->present = 0;
614 tape->bufptr = NULL;
615 tape->drive = DU[D_SLV];
616 snprintf(tape->name, PT_NAMELEN, "%s%d", name, unit);
617 if (!DU[D_PRT])
618 continue;
619 specified++;
620 if (pi_init(tape->pi, 0, DU[D_PRT], DU[D_MOD], DU[D_UNI],
621 DU[D_PRO], DU[D_DLY], pt_scratch, PI_PT,
622 verbose, tape->name)) {
623 if (!pt_probe(tape)) {
624 tape->present = 1;
625 found++;
626 } else
627 pi_release(tape->pi);
628 }
629 }
630 if (specified == 0) {
631 tape = pt;
632 if (pi_init(tape->pi, 1, -1, -1, -1, -1, -1, pt_scratch,
633 PI_PT, verbose, tape->name)) {
634 if (!pt_probe(tape)) {
635 tape->present = 1;
636 found++;
637 } else
638 pi_release(tape->pi);
639 }
640
641 }
642 if (found)
643 return 0;
644
645 printk("%s: No ATAPI tape drive detected\n", name);
646 return -1;
647}
648
649static int pt_open(struct inode *inode, struct file *file)
650{
651 int unit = iminor(inode) & 0x7F;
652 struct pt_unit *tape = pt + unit;
653 int err;
654
Arnd Bergmann613655f2010-06-02 14:28:52 +0200655 mutex_lock(&pt_mutex);
Jonathan Corbetea2959a2008-05-15 10:07:56 -0600656 if (unit >= PT_UNITS || (!tape->present)) {
Arnd Bergmann613655f2010-06-02 14:28:52 +0200657 mutex_unlock(&pt_mutex);
Linus Torvalds1da177e2005-04-16 15:20:36 -0700658 return -ENODEV;
Jonathan Corbetea2959a2008-05-15 10:07:56 -0600659 }
Linus Torvalds1da177e2005-04-16 15:20:36 -0700660
661 err = -EBUSY;
662 if (!atomic_dec_and_test(&tape->available))
663 goto out;
664
665 pt_identify(tape);
666
667 err = -ENODEV;
Alexey Dobriyaneaa0ff12008-02-06 01:36:06 -0800668 if (!(tape->flags & PT_MEDIA))
Linus Torvalds1da177e2005-04-16 15:20:36 -0700669 goto out;
670
671 err = -EROFS;
Al Viroaeb5d722008-09-02 15:28:45 -0400672 if ((!(tape->flags & PT_WRITE_OK)) && (file->f_mode & FMODE_WRITE))
Linus Torvalds1da177e2005-04-16 15:20:36 -0700673 goto out;
674
675 if (!(iminor(inode) & 128))
676 tape->flags |= PT_REWIND;
677
678 err = -ENOMEM;
679 tape->bufptr = kmalloc(PT_BUFSIZE, GFP_KERNEL);
680 if (tape->bufptr == NULL) {
681 printk("%s: buffer allocation failed\n", tape->name);
682 goto out;
683 }
684
685 file->private_data = tape;
Arnd Bergmann613655f2010-06-02 14:28:52 +0200686 mutex_unlock(&pt_mutex);
Linus Torvalds1da177e2005-04-16 15:20:36 -0700687 return 0;
688
689out:
690 atomic_inc(&tape->available);
Arnd Bergmann613655f2010-06-02 14:28:52 +0200691 mutex_unlock(&pt_mutex);
Linus Torvalds1da177e2005-04-16 15:20:36 -0700692 return err;
693}
694
Alan Coxbe1fd702008-07-04 09:51:21 +0200695static long pt_ioctl(struct file *file, unsigned int cmd, unsigned long arg)
Linus Torvalds1da177e2005-04-16 15:20:36 -0700696{
697 struct pt_unit *tape = file->private_data;
698 struct mtop __user *p = (void __user *)arg;
699 struct mtop mtop;
700
701 switch (cmd) {
702 case MTIOCTOP:
703 if (copy_from_user(&mtop, p, sizeof(struct mtop)))
704 return -EFAULT;
705
706 switch (mtop.mt_op) {
707
708 case MTREW:
Arnd Bergmann613655f2010-06-02 14:28:52 +0200709 mutex_lock(&pt_mutex);
Linus Torvalds1da177e2005-04-16 15:20:36 -0700710 pt_rewind(tape);
Arnd Bergmann613655f2010-06-02 14:28:52 +0200711 mutex_unlock(&pt_mutex);
Linus Torvalds1da177e2005-04-16 15:20:36 -0700712 return 0;
713
714 case MTWEOF:
Arnd Bergmann613655f2010-06-02 14:28:52 +0200715 mutex_lock(&pt_mutex);
Linus Torvalds1da177e2005-04-16 15:20:36 -0700716 pt_write_fm(tape);
Arnd Bergmann613655f2010-06-02 14:28:52 +0200717 mutex_unlock(&pt_mutex);
Linus Torvalds1da177e2005-04-16 15:20:36 -0700718 return 0;
719
720 default:
Alan Coxbe1fd702008-07-04 09:51:21 +0200721 /* FIXME: rate limit ?? */
722 printk(KERN_DEBUG "%s: Unimplemented mt_op %d\n", tape->name,
Linus Torvalds1da177e2005-04-16 15:20:36 -0700723 mtop.mt_op);
724 return -EINVAL;
725 }
726
727 default:
Alan Coxbe1fd702008-07-04 09:51:21 +0200728 return -ENOTTY;
Linus Torvalds1da177e2005-04-16 15:20:36 -0700729 }
730}
731
732static int
733pt_release(struct inode *inode, struct file *file)
734{
735 struct pt_unit *tape = file->private_data;
736
737 if (atomic_read(&tape->available) > 1)
738 return -EINVAL;
739
740 if (tape->flags & PT_WRITING)
741 pt_write_fm(tape);
742
743 if (tape->flags & PT_REWIND)
744 pt_rewind(tape);
745
746 kfree(tape->bufptr);
747 tape->bufptr = NULL;
748
749 atomic_inc(&tape->available);
750
751 return 0;
752
753}
754
755static ssize_t pt_read(struct file *filp, char __user *buf, size_t count, loff_t * ppos)
756{
757 struct pt_unit *tape = filp->private_data;
758 struct pi_adapter *pi = tape->pi;
759 char rd_cmd[12] = { ATAPI_READ_6, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0 };
760 int k, n, r, p, s, t, b;
761
762 if (!(tape->flags & (PT_READING | PT_WRITING))) {
763 tape->flags |= PT_READING;
764 if (pt_atapi(tape, rd_cmd, 0, NULL, "start read-ahead"))
765 return -EIO;
766 } else if (tape->flags & PT_WRITING)
767 return -EIO;
768
769 if (tape->flags & PT_EOF)
770 return 0;
771
772 t = 0;
773
774 while (count > 0) {
775
776 if (!pt_poll_dsc(tape, HZ / 100, PT_TMO, "read"))
777 return -EIO;
778
779 n = count;
780 if (n > 32768)
781 n = 32768; /* max per command */
782 b = (n - 1 + tape->bs) / tape->bs;
783 n = b * tape->bs; /* rounded up to even block */
784
785 rd_cmd[4] = b;
786
787 r = pt_command(tape, rd_cmd, n, "read");
788
789 mdelay(1);
790
791 if (r) {
792 pt_req_sense(tape, 0);
793 return -EIO;
794 }
795
796 while (1) {
797
798 r = pt_wait(tape, STAT_BUSY,
799 STAT_DRQ | STAT_ERR | STAT_READY,
800 DBMSG("read DRQ"), "");
801
802 if (r & STAT_SENSE) {
803 pi_disconnect(pi);
804 pt_req_sense(tape, 0);
805 return -EIO;
806 }
807
808 if (r)
809 tape->flags |= PT_EOF;
810
811 s = read_reg(pi, 7);
812
813 if (!(s & STAT_DRQ))
814 break;
815
816 n = (read_reg(pi, 4) + 256 * read_reg(pi, 5));
817 p = (read_reg(pi, 2) & 3);
818 if (p != 2) {
819 pi_disconnect(pi);
820 printk("%s: Phase error on read: %d\n", tape->name,
821 p);
822 return -EIO;
823 }
824
825 while (n > 0) {
826 k = n;
827 if (k > PT_BUFSIZE)
828 k = PT_BUFSIZE;
829 pi_read_block(pi, tape->bufptr, k);
830 n -= k;
831 b = k;
832 if (b > count)
833 b = count;
834 if (copy_to_user(buf + t, tape->bufptr, b)) {
835 pi_disconnect(pi);
836 return -EFAULT;
837 }
838 t += b;
839 count -= b;
840 }
841
842 }
843 pi_disconnect(pi);
844 if (tape->flags & PT_EOF)
845 break;
846 }
847
848 return t;
849
850}
851
852static ssize_t pt_write(struct file *filp, const char __user *buf, size_t count, loff_t * ppos)
853{
854 struct pt_unit *tape = filp->private_data;
855 struct pi_adapter *pi = tape->pi;
856 char wr_cmd[12] = { ATAPI_WRITE_6, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0 };
857 int k, n, r, p, s, t, b;
858
859 if (!(tape->flags & PT_WRITE_OK))
860 return -EROFS;
861
862 if (!(tape->flags & (PT_READING | PT_WRITING))) {
863 tape->flags |= PT_WRITING;
864 if (pt_atapi
865 (tape, wr_cmd, 0, NULL, "start buffer-available mode"))
866 return -EIO;
867 } else if (tape->flags & PT_READING)
868 return -EIO;
869
870 if (tape->flags & PT_EOF)
871 return -ENOSPC;
872
873 t = 0;
874
875 while (count > 0) {
876
877 if (!pt_poll_dsc(tape, HZ / 100, PT_TMO, "write"))
878 return -EIO;
879
880 n = count;
881 if (n > 32768)
882 n = 32768; /* max per command */
883 b = (n - 1 + tape->bs) / tape->bs;
884 n = b * tape->bs; /* rounded up to even block */
885
886 wr_cmd[4] = b;
887
888 r = pt_command(tape, wr_cmd, n, "write");
889
890 mdelay(1);
891
892 if (r) { /* error delivering command only */
893 pt_req_sense(tape, 0);
894 return -EIO;
895 }
896
897 while (1) {
898
899 r = pt_wait(tape, STAT_BUSY,
900 STAT_DRQ | STAT_ERR | STAT_READY,
901 DBMSG("write DRQ"), NULL);
902
903 if (r & STAT_SENSE) {
904 pi_disconnect(pi);
905 pt_req_sense(tape, 0);
906 return -EIO;
907 }
908
909 if (r)
910 tape->flags |= PT_EOF;
911
912 s = read_reg(pi, 7);
913
914 if (!(s & STAT_DRQ))
915 break;
916
917 n = (read_reg(pi, 4) + 256 * read_reg(pi, 5));
918 p = (read_reg(pi, 2) & 3);
919 if (p != 0) {
920 pi_disconnect(pi);
921 printk("%s: Phase error on write: %d \n",
922 tape->name, p);
923 return -EIO;
924 }
925
926 while (n > 0) {
927 k = n;
928 if (k > PT_BUFSIZE)
929 k = PT_BUFSIZE;
930 b = k;
931 if (b > count)
932 b = count;
933 if (copy_from_user(tape->bufptr, buf + t, b)) {
934 pi_disconnect(pi);
935 return -EFAULT;
936 }
937 pi_write_block(pi, tape->bufptr, k);
938 t += b;
939 count -= b;
940 n -= k;
941 }
942
943 }
944 pi_disconnect(pi);
945 if (tape->flags & PT_EOF)
946 break;
947 }
948
949 return t;
950}
951
952static int __init pt_init(void)
953{
Andrew Morton829d5f62006-03-28 01:56:18 -0800954 int unit;
955 int err;
Linus Torvalds1da177e2005-04-16 15:20:36 -0700956
957 if (disable) {
Akinobu Mita8bca98c2006-12-06 20:36:43 -0800958 err = -EINVAL;
Linus Torvalds1da177e2005-04-16 15:20:36 -0700959 goto out;
960 }
961
962 if (pt_detect()) {
Akinobu Mita8bca98c2006-12-06 20:36:43 -0800963 err = -ENODEV;
Linus Torvalds1da177e2005-04-16 15:20:36 -0700964 goto out;
965 }
966
Andrew Morton829d5f62006-03-28 01:56:18 -0800967 err = register_chrdev(major, name, &pt_fops);
968 if (err < 0) {
Linus Torvalds1da177e2005-04-16 15:20:36 -0700969 printk("pt_init: unable to get major number %d\n", major);
970 for (unit = 0; unit < PT_UNITS; unit++)
971 if (pt[unit].present)
972 pi_release(pt[unit].pi);
Linus Torvalds1da177e2005-04-16 15:20:36 -0700973 goto out;
974 }
Andrew Morton829d5f62006-03-28 01:56:18 -0800975 major = err;
gregkh@suse.dedeb36972005-03-23 09:52:10 -0800976 pt_class = class_create(THIS_MODULE, "pt");
Linus Torvalds1da177e2005-04-16 15:20:36 -0700977 if (IS_ERR(pt_class)) {
978 err = PTR_ERR(pt_class);
979 goto out_chrdev;
980 }
981
Linus Torvalds1da177e2005-04-16 15:20:36 -0700982 for (unit = 0; unit < PT_UNITS; unit++)
983 if (pt[unit].present) {
Greg Kroah-Hartman1ff9f542008-07-21 20:03:34 -0700984 device_create(pt_class, NULL, MKDEV(major, unit), NULL,
985 "pt%d", unit);
986 device_create(pt_class, NULL, MKDEV(major, unit + 128),
987 NULL, "pt%dn", unit);
Linus Torvalds1da177e2005-04-16 15:20:36 -0700988 }
989 goto out;
990
Linus Torvalds1da177e2005-04-16 15:20:36 -0700991out_chrdev:
992 unregister_chrdev(major, "pt");
993out:
994 return err;
995}
996
997static void __exit pt_exit(void)
998{
999 int unit;
1000 for (unit = 0; unit < PT_UNITS; unit++)
1001 if (pt[unit].present) {
Tony Jonesaa275822007-09-25 02:03:03 +02001002 device_destroy(pt_class, MKDEV(major, unit));
1003 device_destroy(pt_class, MKDEV(major, unit + 128));
Linus Torvalds1da177e2005-04-16 15:20:36 -07001004 }
gregkh@suse.dedeb36972005-03-23 09:52:10 -08001005 class_destroy(pt_class);
Linus Torvalds1da177e2005-04-16 15:20:36 -07001006 unregister_chrdev(major, name);
1007 for (unit = 0; unit < PT_UNITS; unit++)
1008 if (pt[unit].present)
1009 pi_release(pt[unit].pi);
1010}
1011
1012MODULE_LICENSE("GPL");
1013module_init(pt_init)
1014module_exit(pt_exit)