linux/drivers/block/paride/pt.c
<<
>>
Prefs
   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
 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>
 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
 152module_param(verbose, bool, 0);
 153module_param(major, int, 0);
 154module_param(name, charp, 0);
 155module_param_array(drive0, int, NULL, 0);
 156module_param_array(drive1, int, NULL, 0);
 157module_param_array(drive2, int, NULL, 0);
 158module_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
 191static int pt_open(struct inode *inode, struct file *file);
 192static int pt_ioctl(struct inode *inode, struct file *file,
 193                    unsigned int cmd, unsigned long arg);
 194static int pt_release(struct inode *inode, struct file *file);
 195static ssize_t pt_read(struct file *filp, char __user *buf,
 196                       size_t count, loff_t * ppos);
 197static ssize_t pt_write(struct file *filp, const char __user *buf,
 198                        size_t count, loff_t * ppos);
 199static 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
 213struct 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
 227static int pt_identify(struct pt_unit *tape);
 228
 229static struct pt_unit pt[PT_UNITS];
 230
 231static char pt_scratch[512];    /* scratch block buffer */
 232
 233/* kernel glue structures */
 234
 235static 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 */
 245static struct class *pt_class;
 246
 247static inline int status_reg(struct pi_adapter *pi)
 248{
 249        return pi_read_regr(pi, 1, 6);
 250}
 251
 252static inline int read_reg(struct pi_adapter *pi, int reg)
 253{
 254        return pi_read_regr(pi, 0, reg);
 255}
 256
 257static inline void write_reg(struct pi_adapter *pi, int reg, int val)
 258{
 259        pi_write_regr(pi, 0, reg, val);
 260}
 261
 262static inline u8 DRIVE(struct pt_unit *tape)
 263{
 264        return 0xa0+0x10*tape->drive;
 265}
 266
 267static 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
 292static 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
 324static 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
 349static 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
 370static 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
 384static void pt_sleep(int cs)
 385{
 386        schedule_timeout_interruptible(cs);
 387}
 388
 389static 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
 420static 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
 430static 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
 437static 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
 446static 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
 479static 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
 499static 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
 513static 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
 523static 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 */
 583static 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
 596static 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
 647static 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
 683out:
 684        atomic_inc(&tape->available);
 685        return err;
 686}
 687
 688static 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
 723static int
 724pt_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
 746static 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
 843static 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
 943static 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                        class_device_create(pt_class, NULL, MKDEV(major, unit),
 976                                        NULL, "pt%d", unit);
 977                        class_device_create(pt_class, NULL, MKDEV(major, unit + 128),
 978                                        NULL, "pt%dn", unit);
 979                }
 980        goto out;
 981
 982out_chrdev:
 983        unregister_chrdev(major, "pt");
 984out:
 985        return err;
 986}
 987
 988static void __exit pt_exit(void)
 989{
 990        int unit;
 991        for (unit = 0; unit < PT_UNITS; unit++)
 992                if (pt[unit].present) {
 993                        class_device_destroy(pt_class, MKDEV(major, unit));
 994                        class_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
1003MODULE_LICENSE("GPL");
1004module_init(pt_init)
1005module_exit(pt_exit)
1006
lxr.linux.no kindly hosted by Redpill Linpro AS, provider of Linux consulting and operations services since 1995.