Linux kernel & device driver programming

Cross-Referenced Linux and Device Driver Code

[ source navigation ] [ diff markup ] [ identifier search ] [ freetext search ] [ file search ]
Version: [ 2.6.11.8 ] [ 2.6.25 ] [ 2.6.25.8 ] [ 2.6.31.13 ] Architecture: [ i386 ]
  1 /* 
  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 
118 static int verbose = 0;
119 static int major = PT_MAJOR;
120 static char *name = PT_NAME;
121 static int disable = 0;
122 
123 static int drive0[6] = { 0, 0, 0, -1, -1, -1 };
124 static int drive1[6] = { 0, 0, 0, -1, -1, -1 };
125 static int drive2[6] = { 0, 0, 0, -1, -1, -1 };
126 static int drive3[6] = { 0, 0, 0, -1, -1, -1 };
127 
128 static 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>
144 #include <linux/delay.h>
145 #include <linux/slab.h>
146 #include <linux/mtio.h>
147 #include <linux/device.h>
148 #include <linux/sched.h>        /* current, TASK_*, schedule_timeout() */
149 
150 #include <asm/uaccess.h>
151 
152 module_param(verbose, bool, 0);
153 module_param(major, int, 0);
154 module_param(name, charp, 0);
155 module_param_array(drive0, int, NULL, 0);
156 module_param_array(drive1, int, NULL, 0);
157 module_param_array(drive2, int, NULL, 0);
158 module_param_array(drive3, int, NULL, 0);
159 
160 #include "paride.h"
161 
162 #define PT_MAX_RETRIES  5
163 #define PT_TMO          3000    /* interrupt timeout in jiffies */
164 #define PT_SPIN_DEL     50      /* spin delay in micro-seconds  */
165 #define PT_RESET_TMO    30      /* 30 seconds */
166 #define PT_READY_TMO    60      /* 60 seconds */
167 #define PT_REWIND_TMO   1200    /* 20 minutes */
168 
169 #define PT_SPIN         ((1000000/(HZ*PT_SPIN_DEL))*PT_TMO)
170 
171 #define STAT_ERR        0x00001
172 #define STAT_INDEX      0x00002
173 #define STAT_ECC        0x00004
174 #define STAT_DRQ        0x00008
175 #define STAT_SEEK       0x00010
176 #define STAT_WRERR      0x00020
177 #define STAT_READY      0x00040
178 #define STAT_BUSY       0x00080
179 #define STAT_SENSE      0x1f000
180 
181 #define ATAPI_TEST_READY        0x00
182 #define ATAPI_REWIND            0x01
183 #define ATAPI_REQ_SENSE         0x03
184 #define ATAPI_READ_6            0x08
185 #define ATAPI_WRITE_6           0x0a
186 #define ATAPI_WFM               0x10
187 #define ATAPI_IDENTIFY          0x12
188 #define ATAPI_MODE_SENSE        0x1a
189 #define ATAPI_LOG_SENSE         0x4d
190 
191 static int pt_open(struct inode *inode, struct file *file);
192 static int pt_ioctl(struct inode *inode, struct file *file,
193                     unsigned int cmd, unsigned long arg);
194 static int pt_release(struct inode *inode, struct file *file);
195 static ssize_t pt_read(struct file *filp, char __user *buf,
196                        size_t count, loff_t * ppos);
197 static ssize_t pt_write(struct file *filp, const char __user *buf,
198                         size_t count, loff_t * ppos);
199 static int pt_detect(void);
200 
201 /* bits in tape->flags */
202 
203 #define PT_MEDIA        1
204 #define PT_WRITE_OK     2
205 #define PT_REWIND       4
206 #define PT_WRITING      8
207 #define PT_READING     16
208 #define PT_EOF         32
209 
210 #define PT_NAMELEN      8
211 #define PT_BUFSIZE  16384
212 
213 struct pt_unit {
214         struct pi_adapter pia;  /* interface to paride layer */
215         struct pi_adapter *pi;
216         int flags;              /* various state flags */
217         int last_sense;         /* result of last request sense */
218         int drive;              /* drive */
219         atomic_t available;     /* 1 if access is available 0 otherwise */
220         int bs;                 /* block size */
221         int capacity;           /* Size of tape in KB */
222         int present;            /* device present ? */
223         char *bufptr;
224         char name[PT_NAMELEN];  /* pf0, pf1, ... */
225 };
226 
227 static int pt_identify(struct pt_unit *tape);
228 
229 static struct pt_unit pt[PT_UNITS];
230 
231 static char pt_scratch[512];    /* scratch block buffer */
232 
233 /* kernel glue structures */
234 
235 static const struct file_operations pt_fops = {
236         .owner = THIS_MODULE,
237         .read = pt_read,
238         .write = pt_write,
239         .ioctl = pt_ioctl,
240         .open = pt_open,
241         .release = pt_release,
242 };
243 
244 /* sysfs class support */
245 static struct class *pt_class;
246 
247 static inline int status_reg(struct pi_adapter *pi)
248 {
249         return pi_read_regr(pi, 1, 6);
250 }
251 
252 static inline int read_reg(struct pi_adapter *pi, int reg)
253 {
254         return pi_read_regr(pi, 0, reg);
255 }
256 
257 static inline void write_reg(struct pi_adapter *pi, int reg, int val)
258 {
259         pi_write_regr(pi, 0, reg, val);
260 }
261 
262 static inline u8 DRIVE(struct pt_unit *tape)
263 {
264         return 0xa0+0x10*tape->drive;
265 }
266 
267 static int pt_wait(struct pt_unit *tape, int go, int stop, char *fun, char *msg)
268 {
269         int j, r, e, s, p;
270         struct pi_adapter *pi = tape->pi;
271 
272         j = 0;
273         while ((((r = status_reg(pi)) & go) || (stop && (!(r & stop))))
274                && (j++ < PT_SPIN))
275                 udelay(PT_SPIN_DEL);
276 
277         if ((r & (STAT_ERR & stop)) || (j >= PT_SPIN)) {
278                 s = read_reg(pi, 7);
279                 e = read_reg(pi, 1);
280                 p = read_reg(pi, 2);
281                 if (j >= PT_SPIN)
282                         e |= 0x100;
283                 if (fun)
284                         printk("%s: %s %s: alt=0x%x stat=0x%x err=0x%x"
285                                " loop=%d phase=%d\n",
286                                tape->name, fun, msg, r, s, e, j, p);
287                 return (e << 8) + s;
288         }
289         return 0;
290 }
291 
292 static int pt_command(struct pt_unit *tape, char *cmd, int dlen, char *fun)
293 {
294         struct pi_adapter *pi = tape->pi;
295         pi_connect(pi);
296 
297         write_reg(pi, 6, DRIVE(tape));
298 
299         if (pt_wait(tape, STAT_BUSY | STAT_DRQ, 0, fun, "before command")) {
300                 pi_disconnect(pi);
301                 return -1;
302         }
303 
304         write_reg(pi, 4, dlen % 256);
305         write_reg(pi, 5, dlen / 256);
306         write_reg(pi, 7, 0xa0); /* ATAPI packet command */
307 
308         if (pt_wait(tape, STAT_BUSY, STAT_DRQ, fun, "command DRQ")) {
309                 pi_disconnect(pi);
310                 return -1;
311         }
312 
313         if (read_reg(pi, 2) != 1) {
314                 printk("%s: %s: command phase error\n", tape->name, fun);
315                 pi_disconnect(pi);
316                 return -1;
317         }
318 
319         pi_write_block(pi, cmd, 12);
320 
321         return 0;
322 }
323 
324 static int pt_completion(struct pt_unit *tape, char *buf, char *fun)
325 {
326         struct pi_adapter *pi = tape->pi;
327         int r, s, n, p;
328 
329         r = pt_wait(tape, STAT_BUSY, STAT_DRQ | STAT_READY | STAT_ERR,
330                     fun, "completion");
331 
332         if (read_reg(pi, 7) & STAT_DRQ) {
333                 n = (((read_reg(pi, 4) + 256 * read_reg(pi, 5)) +
334                       3) & 0xfffc);
335                 p = read_reg(pi, 2) & 3;
336                 if (p == 0)
337                         pi_write_block(pi, buf, n);
338                 if (p == 2)
339                         pi_read_block(pi, buf, n);
340         }
341 
342         s = pt_wait(tape, STAT_BUSY, STAT_READY | STAT_ERR, fun, "data done");
343 
344         pi_disconnect(pi);
345 
346         return (r ? r : s);
347 }
348 
349 static void pt_req_sense(struct pt_unit *tape, int quiet)
350 {
351         char rs_cmd[12] = { ATAPI_REQ_SENSE, 0, 0, 0, 16, 0, 0, 0, 0, 0, 0, 0 };
352         char buf[16];
353         int r;
354 
355         r = pt_command(tape, rs_cmd, 16, "Request sense");
356         mdelay(1);
357         if (!r)
358                 pt_completion(tape, buf, "Request sense");
359 
360         tape->last_sense = -1;
361         if (!r) {
362                 if (!quiet)
363                         printk("%s: Sense key: %x, ASC: %x, ASQ: %x\n",
364                                tape->name, buf[2] & 0xf, buf[12], buf[13]);
365                 tape->last_sense = (buf[2] & 0xf) | ((buf[12] & 0xff) << 8)
366                     | ((buf[13] & 0xff) << 16);
367         }
368 }
369 
370 static int pt_atapi(struct pt_unit *tape, char *cmd, int dlen, char *buf, char *fun)
371 {
372         int r;
373 
374         r = pt_command(tape, cmd, dlen, fun);
375         mdelay(1);
376         if (!r)
377                 r = pt_completion(tape, buf, fun);
378         if (r)
379                 pt_req_sense(tape, !fun);
380 
381         return r;
382 }
383 
384 static void pt_sleep(int cs)
385 {
386         schedule_timeout_interruptible(cs);
387 }
388 
389 static int pt_poll_dsc(struct pt_unit *tape, int pause, int tmo, char *msg)
390 {
391         struct pi_adapter *pi = tape->pi;
392         int k, e, s;
393 
394         k = 0;
395         e = 0;
396         s = 0;
397         while (k < tmo) {
398                 pt_sleep(pause);
399                 k++;
400                 pi_connect(pi);
401                 write_reg(pi, 6, DRIVE(tape));
402                 s = read_reg(pi, 7);
403                 e = read_reg(pi, 1);
404                 pi_disconnect(pi);
405                 if (s & (STAT_ERR | STAT_SEEK))
406                         break;
407         }
408         if ((k >= tmo) || (s & STAT_ERR)) {
409                 if (k >= tmo)
410                         printk("%s: %s DSC timeout\n", tape->name, msg);
411                 else
412                         printk("%s: %s stat=0x%x err=0x%x\n", tape->name, msg, s,
413                                e);
414                 pt_req_sense(tape, 0);
415                 return 0;
416         }
417         return 1;
418 }
419 
420 static void pt_media_access_cmd(struct pt_unit *tape, int tmo, char *cmd, char *fun)
421 {
422         if (pt_command(tape, cmd, 0, fun)) {
423                 pt_req_sense(tape, 0);
424                 return;
425         }
426         pi_disconnect(tape->pi);
427         pt_poll_dsc(tape, HZ, tmo, fun);
428 }
429 
430 static void pt_rewind(struct pt_unit *tape)
431 {
432         char rw_cmd[12] = { ATAPI_REWIND, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0 };
433 
434         pt_media_access_cmd(tape, PT_REWIND_TMO, rw_cmd, "rewind");
435 }
436 
437 static void pt_write_fm(struct pt_unit *tape)
438 {
439         char wm_cmd[12] = { ATAPI_WFM, 0, 0, 0, 1, 0, 0, 0, 0, 0, 0, 0 };
440 
441         pt_media_access_cmd(tape, PT_TMO, wm_cmd, "write filemark");
442 }
443 
444 #define DBMSG(msg)      ((verbose>1)?(msg):NULL)
445 
446 static int pt_reset(struct pt_unit *tape)
447 {
448         struct pi_adapter *pi = tape->pi;
449         int i, k, flg;
450         int expect[5] = { 1, 1, 1, 0x14, 0xeb };
451 
452         pi_connect(pi);
453         write_reg(pi, 6, DRIVE(tape));
454         write_reg(pi, 7, 8);
455 
456         pt_sleep(20 * HZ / 1000);
457 
458         k = 0;
459         while ((k++ < PT_RESET_TMO) && (status_reg(pi) & STAT_BUSY))
460                 pt_sleep(HZ / 10);
461 
462         flg = 1;
463         for (i = 0; i < 5; i++)
464                 flg &= (read_reg(pi, i + 1) == expect[i]);
465 
466         if (verbose) {
467                 printk("%s: Reset (%d) signature = ", tape->name, k);
468                 for (i = 0; i < 5; i++)
469                         printk("%3x", read_reg(pi, i + 1));
470                 if (!flg)
471                         printk(" (incorrect)");
472                 printk("\n");
473         }
474 
475         pi_disconnect(pi);
476         return flg - 1;
477 }
478 
479 static int pt_ready_wait(struct pt_unit *tape, int tmo)
480 {
481         char tr_cmd[12] = { ATAPI_TEST_READY, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0 };
482         int k, p;
483 
484         k = 0;
485         while (k < tmo) {
486                 tape->last_sense = 0;
487                 pt_atapi(tape, tr_cmd, 0, NULL, DBMSG("test unit ready"));
488                 p = tape->last_sense;
489                 if (!p)
490                         return 0;
491                 if (!(((p & 0xffff) == 0x0402) || ((p & 0xff) == 6)))
492                         return p;
493                 k++;
494                 pt_sleep(HZ);
495         }
496         return 0x000020;        /* timeout */
497 }
498 
499 static void xs(char *buf, char *targ, int offs, int len)
500 {
501         int j, k, l;
502 
503         j = 0;
504         l = 0;
505         for (k = 0; k < len; k++)
506                 if ((buf[k + offs] != 0x20) || (buf[k + offs] != l))
507                         l = targ[j++] = buf[k + offs];
508         if (l == 0x20)
509                 j--;
510         targ[j] = 0;
511 }
512 
513 static int xn(char *buf, int offs, int size)
514 {
515         int v, k;
516 
517         v = 0;
518         for (k = 0; k < size; k++)
519                 v = v * 256 + (buf[k + offs] & 0xff);
520         return v;
521 }
522 
523 static int pt_identify(struct pt_unit *tape)
524 {
525         int dt, s;
526         char *ms[2] = { "master", "slave" };
527         char mf[10], id[18];
528         char id_cmd[12] = { ATAPI_IDENTIFY, 0, 0, 0, 36, 0, 0, 0, 0, 0, 0, 0 };
529         char ms_cmd[12] =
530             { ATAPI_MODE_SENSE, 0, 0x2a, 0, 36, 0, 0, 0, 0, 0, 0, 0 };
531         char ls_cmd[12] =
532             { ATAPI_LOG_SENSE, 0, 0x71, 0, 0, 0, 0, 0, 36, 0, 0, 0 };
533         char buf[36];
534 
535         s = pt_atapi(tape, id_cmd, 36, buf, "identify");
536         if (s)
537                 return -1;
538 
539         dt = buf[0] & 0x1f;
540         if (dt != 1) {
541                 if (verbose)
542                         printk("%s: Drive %d, unsupported type %d\n",
543                                tape->name, tape->drive, dt);
544                 return -1;
545         }
546 
547         xs(buf, mf, 8, 8);
548         xs(buf, id, 16, 16);
549 
550         tape->flags = 0;
551         tape->capacity = 0;
552         tape->bs = 0;
553 
554         if (!pt_ready_wait(tape, PT_READY_TMO))
555                 tape->flags |= PT_MEDIA;
556 
557         if (!pt_atapi(tape, ms_cmd, 36, buf, "mode sense")) {
558                 if (!(buf[2] & 0x80))
559                         tape->flags |= PT_WRITE_OK;
560                 tape->bs = xn(buf, 10, 2);
561         }
562 
563         if (!pt_atapi(tape, ls_cmd, 36, buf, "log sense"))
564                 tape->capacity = xn(buf, 24, 4);
565 
566         printk("%s: %s %s, %s", tape->name, mf, id, ms[tape->drive]);
567         if (!(tape->flags & PT_MEDIA))
568                 printk(", no media\n");
569         else {
570                 if (!(tape->flags & PT_WRITE_OK))
571                         printk(", RO");
572                 printk(", blocksize %d, %d MB\n", tape->bs, tape->capacity / 1024);
573         }
574 
575         return 0;
576 }
577 
578 
579 /*
580  * returns  0, with id set if drive is detected
581  *         -1, if drive detection failed
582  */
583 static int pt_probe(struct pt_unit *tape)
584 {
585         if (tape->drive == -1) {
586                 for (tape->drive = 0; tape->drive <= 1; tape->drive++)
587                         if (!pt_reset(tape))
588                                 return pt_identify(tape);
589         } else {
590                 if (!pt_reset(tape))
591                         return pt_identify(tape);
592         }
593         return -1;
594 }
595 
596 static int pt_detect(void)
597 {
598         struct pt_unit *tape;
599         int specified = 0, found = 0;
600         int unit;
601 
602         printk("%s: %s version %s, major %d\n", name, name, PT_VERSION, major);
603 
604         specified = 0;
605         for (unit = 0; unit < PT_UNITS; unit++) {
606                 struct pt_unit *tape = &pt[unit];
607                 tape->pi = &tape->pia;
608                 atomic_set(&tape->available, 1);
609                 tape->flags = 0;
610                 tape->last_sense = 0;
611                 tape->present = 0;
612                 tape->bufptr = NULL;
613                 tape->drive = DU[D_SLV];
614                 snprintf(tape->name, PT_NAMELEN, "%s%d", name, unit);
615                 if (!DU[D_PRT])
616                         continue;
617                 specified++;
618                 if (pi_init(tape->pi, 0, DU[D_PRT], DU[D_MOD], DU[D_UNI],
619                      DU[D_PRO], DU[D_DLY], pt_scratch, PI_PT,
620                      verbose, tape->name)) {
621                         if (!pt_probe(tape)) {
622                                 tape->present = 1;
623                                 found++;
624                         } else
625                                 pi_release(tape->pi);
626                 }
627         }
628         if (specified == 0) {
629                 tape = pt;
630                 if (pi_init(tape->pi, 1, -1, -1, -1, -1, -1, pt_scratch,
631                             PI_PT, verbose, tape->name)) {
632                         if (!pt_probe(tape)) {
633                                 tape->present = 1;
634                                 found++;
635                         } else
636                                 pi_release(tape->pi);
637                 }
638 
639         }
640         if (found)
641                 return 0;
642 
643         printk("%s: No ATAPI tape drive detected\n", name);
644         return -1;
645 }
646 
647 static int pt_open(struct inode *inode, struct file *file)
648 {
649         int unit = iminor(inode) & 0x7F;
650         struct pt_unit *tape = pt + unit;
651         int err;
652 
653         if (unit >= PT_UNITS || (!tape->present))
654                 return -ENODEV;
655 
656         err = -EBUSY;
657         if (!atomic_dec_and_test(&tape->available))
658                 goto out;
659 
660         pt_identify(tape);
661 
662         err = -ENODEV;
663         if (!(tape->flags & PT_MEDIA))
664                 goto out;
665 
666         err = -EROFS;
667         if ((!(tape->flags & PT_WRITE_OK)) && (file->f_mode & 2))
668                 goto out;
669 
670         if (!(iminor(inode) & 128))
671                 tape->flags |= PT_REWIND;
672 
673         err = -ENOMEM;
674         tape->bufptr = kmalloc(PT_BUFSIZE, GFP_KERNEL);
675         if (tape->bufptr == NULL) {
676                 printk("%s: buffer allocation failed\n", tape->name);
677                 goto out;
678         }
679 
680         file->private_data = tape;
681         return 0;
682 
683 out:
684         atomic_inc(&tape->available);
685         return err;
686 }
687 
688 static int pt_ioctl(struct inode *inode, struct file *file,
689          unsigned int cmd, unsigned long arg)
690 {
691         struct pt_unit *tape = file->private_data;
692         struct mtop __user *p = (void __user *)arg;
693         struct mtop mtop;
694 
695         switch (cmd) {
696         case MTIOCTOP:
697                 if (copy_from_user(&mtop, p, sizeof(struct mtop)))
698                         return -EFAULT;
699 
700                 switch (mtop.mt_op) {
701 
702                 case MTREW:
703                         pt_rewind(tape);
704                         return 0;
705 
706                 case MTWEOF:
707                         pt_write_fm(tape);
708                         return 0;
709 
710                 default:
711                         printk("%s: Unimplemented mt_op %d\n", tape->name,
712                                mtop.mt_op);
713                         return -EINVAL;
714                 }
715 
716         default:
717                 printk("%s: Unimplemented ioctl 0x%x\n", tape->name, cmd);
718                 return -EINVAL;
719 
720         }
721 }
722 
723 static int
724 pt_release(struct inode *inode, struct file *file)
725 {
726         struct pt_unit *tape = file->private_data;
727 
728         if (atomic_read(&tape->available) > 1)
729                 return -EINVAL;
730 
731         if (tape->flags & PT_WRITING)
732                 pt_write_fm(tape);
733 
734         if (tape->flags & PT_REWIND)
735                 pt_rewind(tape);
736 
737         kfree(tape->bufptr);
738         tape->bufptr = NULL;
739 
740         atomic_inc(&tape->available);
741 
742         return 0;
743 
744 }
745 
746 static ssize_t pt_read(struct file *filp, char __user *buf, size_t count, loff_t * ppos)
747 {
748         struct pt_unit *tape = filp->private_data;
749         struct pi_adapter *pi = tape->pi;
750         char rd_cmd[12] = { ATAPI_READ_6, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0 };
751         int k, n, r, p, s, t, b;
752 
753         if (!(tape->flags & (PT_READING | PT_WRITING))) {
754                 tape->flags |= PT_READING;
755                 if (pt_atapi(tape, rd_cmd, 0, NULL, "start read-ahead"))
756                         return -EIO;
757         } else if (tape->flags & PT_WRITING)
758                 return -EIO;
759 
760         if (tape->flags & PT_EOF)
761                 return 0;
762 
763         t = 0;
764 
765         while (count > 0) {
766 
767                 if (!pt_poll_dsc(tape, HZ / 100, PT_TMO, "read"))
768                         return -EIO;
769 
770                 n = count;
771                 if (n > 32768)
772                         n = 32768;      /* max per command */
773                 b = (n - 1 + tape->bs) / tape->bs;
774                 n = b * tape->bs;       /* rounded up to even block */
775 
776                 rd_cmd[4] = b;
777 
778                 r = pt_command(tape, rd_cmd, n, "read");
779 
780                 mdelay(1);
781 
782                 if (r) {
783                         pt_req_sense(tape, 0);
784                         return -EIO;
785                 }
786 
787                 while (1) {
788 
789                         r = pt_wait(tape, STAT_BUSY,
790                                     STAT_DRQ | STAT_ERR | STAT_READY,
791                                     DBMSG("read DRQ"), "");
792 
793                         if (r & STAT_SENSE) {
794                                 pi_disconnect(pi);
795                                 pt_req_sense(tape, 0);
796                                 return -EIO;
797                         }
798 
799                         if (r)
800                                 tape->flags |= PT_EOF;
801 
802                         s = read_reg(pi, 7);
803 
804                         if (!(s & STAT_DRQ))
805                                 break;
806 
807                         n = (read_reg(pi, 4) + 256 * read_reg(pi, 5));
808                         p = (read_reg(pi, 2) & 3);
809                         if (p != 2) {
810                                 pi_disconnect(pi);
811                                 printk("%s: Phase error on read: %d\n", tape->name,
812                                        p);
813                                 return -EIO;
814                         }
815 
816                         while (n > 0) {
817                                 k = n;
818                                 if (k > PT_BUFSIZE)
819                                         k = PT_BUFSIZE;
820                                 pi_read_block(pi, tape->bufptr, k);
821                                 n -= k;
822                                 b = k;
823                                 if (b > count)
824                                         b = count;
825                                 if (copy_to_user(buf + t, tape->bufptr, b)) {
826                                         pi_disconnect(pi);
827                                         return -EFAULT;
828                                 }
829                                 t += b;
830                                 count -= b;
831                         }
832 
833                 }
834                 pi_disconnect(pi);
835                 if (tape->flags & PT_EOF)
836                         break;
837         }
838 
839         return t;
840 
841 }
842 
843 static ssize_t pt_write(struct file *filp, const char __user *buf, size_t count, loff_t * ppos)
844 {
845         struct pt_unit *tape = filp->private_data;
846         struct pi_adapter *pi = tape->pi;
847         char wr_cmd[12] = { ATAPI_WRITE_6, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0 };
848         int k, n, r, p, s, t, b;
849 
850         if (!(tape->flags & PT_WRITE_OK))
851                 return -EROFS;
852 
853         if (!(tape->flags & (PT_READING | PT_WRITING))) {
854                 tape->flags |= PT_WRITING;
855                 if (pt_atapi
856                     (tape, wr_cmd, 0, NULL, "start buffer-available mode"))
857                         return -EIO;
858         } else if (tape->flags & PT_READING)
859                 return -EIO;
860 
861         if (tape->flags & PT_EOF)
862                 return -ENOSPC;
863 
864         t = 0;
865 
866         while (count > 0) {
867 
868                 if (!pt_poll_dsc(tape, HZ / 100, PT_TMO, "write"))
869                         return -EIO;
870 
871                 n = count;
872                 if (n > 32768)
873                         n = 32768;      /* max per command */
874                 b = (n - 1 + tape->bs) / tape->bs;
875                 n = b * tape->bs;       /* rounded up to even block */
876 
877                 wr_cmd[4] = b;
878 
879                 r = pt_command(tape, wr_cmd, n, "write");
880 
881                 mdelay(1);
882 
883                 if (r) {        /* error delivering command only */
884                         pt_req_sense(tape, 0);
885                         return -EIO;
886                 }
887 
888                 while (1) {
889 
890                         r = pt_wait(tape, STAT_BUSY,
891                                     STAT_DRQ | STAT_ERR | STAT_READY,
892                                     DBMSG("write DRQ"), NULL);
893 
894                         if (r & STAT_SENSE) {
895                                 pi_disconnect(pi);
896                                 pt_req_sense(tape, 0);
897                                 return -EIO;
898                         }
899 
900                         if (r)
901                                 tape->flags |= PT_EOF;
902 
903                         s = read_reg(pi, 7);
904 
905                         if (!(s & STAT_DRQ))
906                                 break;
907 
908                         n = (read_reg(pi, 4) + 256 * read_reg(pi, 5));
909                         p = (read_reg(pi, 2) & 3);
910                         if (p != 0) {
911                                 pi_disconnect(pi);
912                                 printk("%s: Phase error on write: %d \n",
913                                        tape->name, p);
914                                 return -EIO;
915                         }
916 
917                         while (n > 0) {
918                                 k = n;
919                                 if (k > PT_BUFSIZE)
920                                         k = PT_BUFSIZE;
921                                 b = k;
922                                 if (b > count)
923                                         b = count;
924                                 if (copy_from_user(tape->bufptr, buf + t, b)) {
925                                         pi_disconnect(pi);
926                                         return -EFAULT;
927                                 }
928                                 pi_write_block(pi, tape->bufptr, k);
929                                 t += b;
930                                 count -= b;
931                                 n -= k;
932                         }
933 
934                 }
935                 pi_disconnect(pi);
936                 if (tape->flags & PT_EOF)
937                         break;
938         }
939 
940         return t;
941 }
942 
943 static int __init pt_init(void)
944 {
945         int unit;
946         int err;
947 
948         if (disable) {
949                 err = -EINVAL;
950                 goto out;
951         }
952 
953         if (pt_detect()) {
954                 err = -ENODEV;
955                 goto out;
956         }
957 
958         err = register_chrdev(major, name, &pt_fops);
959         if (err < 0) {
960                 printk("pt_init: unable to get major number %d\n", major);
961                 for (unit = 0; unit < PT_UNITS; unit++)
962                         if (pt[unit].present)
963                                 pi_release(pt[unit].pi);
964                 goto out;
965         }
966         major = err;
967         pt_class = class_create(THIS_MODULE, "pt");
968         if (IS_ERR(pt_class)) {
969                 err = PTR_ERR(pt_class);
970                 goto out_chrdev;
971         }
972 
973         for (unit = 0; unit < PT_UNITS; unit++)
974                 if (pt[unit].present) {
975                         device_create(pt_class, NULL, MKDEV(major, unit),
976                                       "pt%d", unit);
977                         device_create(pt_class, NULL, MKDEV(major, unit + 128),
978                                       "pt%dn", unit);
979                 }
980         goto out;
981 
982 out_chrdev:
983         unregister_chrdev(major, "pt");
984 out:
985         return err;
986 }
987 
988 static void __exit pt_exit(void)
989 {
990         int unit;
991         for (unit = 0; unit < PT_UNITS; unit++)
992                 if (pt[unit].present) {
993                         device_destroy(pt_class, MKDEV(major, unit));
994                         device_destroy(pt_class, MKDEV(major, unit + 128));
995                 }
996         class_destroy(pt_class);
997         unregister_chrdev(major, name);
998         for (unit = 0; unit < PT_UNITS; unit++)
999                 if (pt[unit].present)
1000                         pi_release(pt[unit].pi);
1001 }
1002 
1003 MODULE_LICENSE("GPL");
1004 module_init(pt_init)
1005 module_exit(pt_exit)
1006 
  This page was automatically generated by the LXR engine.