linux/drivers/block/paride/pf.c
<<
>>
Prefs
   1/* 
   2        pf.c    (c) 1997-8  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 disk
   6        drives based on chips supported by the paride module.
   7
   8        By default, the driver will autoprobe for a single parallel
   9        port ATAPI disk drive, but if their individual parameters are
  10        specified, the driver can handle up to 4 drives.
  11
  12        The behaviour of the pf driver can be altered by setting
  13        some parameters from the insmod command line.  The following
  14        parameters are adjustable:
  15
  16            drive0      These four arguments can be arrays of       
  17            drive1      1-7 integers as follows:
  18            drive2
  19            drive3      <prt>,<pro>,<uni>,<mod>,<slv>,<lun>,<dly>
  20
  21                        Where,
  22
  23                <prt>   is the base of the parallel port address for
  24                        the corresponding drive.  (required)
  25
  26                <pro>   is the protocol number for the adapter that
  27                        supports this drive.  These numbers are
  28                        logged by 'paride' when the protocol modules
  29                        are initialised.  (0 if not given)
  30
  31                <uni>   for those adapters that support chained
  32                        devices, this is the unit selector for the
  33                        chain of devices on the given port.  It should
  34                        be zero for devices that don't support chaining.
  35                        (0 if not given)
  36
  37                <mod>   this can be -1 to choose the best mode, or one
  38                        of the mode numbers supported by the adapter.
  39                        (-1 if not given)
  40
  41                <slv>   ATAPI CDroms can be jumpered to master or slave.
  42                        Set this to 0 to choose the master drive, 1 to
  43                        choose the slave, -1 (the default) to choose the
  44                        first drive found.
  45
  46                <lun>   Some ATAPI devices support multiple LUNs.
  47                        One example is the ATAPI PD/CD drive from
  48                        Matshita/Panasonic.  This device has a 
  49                        CD drive on LUN 0 and a PD drive on LUN 1.
  50                        By default, the driver will search for the
  51                        first LUN with a supported device.  Set 
  52                        this parameter to force it to use a specific
  53                        LUN.  (default -1)
  54
  55                <dly>   some parallel ports require the driver to 
  56                        go more slowly.  -1 sets a default value that
  57                        should work with the chosen protocol.  Otherwise,
  58                        set this to a small integer, the larger it is
  59                        the slower the port i/o.  In some cases, setting
  60                        this to zero will speed up the device. (default -1)
  61
  62            major       You may use this parameter to overide the
  63                        default major number (47) that this driver
  64                        will use.  Be sure to change the device
  65                        name as well.
  66
  67            name        This parameter is a character string that
  68                        contains the name the kernel will use for this
  69                        device (in /proc output, for instance).
  70                        (default "pf").
  71
  72            cluster     The driver will attempt to aggregate requests
  73                        for adjacent blocks into larger multi-block
  74                        clusters.  The maximum cluster size (in 512
  75                        byte sectors) is set with this parameter.
  76                        (default 64)
  77
  78            verbose     This parameter controls the amount of logging
  79                        that the driver will do.  Set it to 0 for
  80                        normal operation, 1 to see autoprobe progress
  81                        messages, or 2 to see additional debugging
  82                        output.  (default 0)
  83 
  84            nice        This parameter controls the driver's use of
  85                        idle CPU time, at the expense of some speed.
  86
  87        If this driver is built into the kernel, you can use the
  88        following command line parameters, with the same values
  89        as the corresponding module parameters listed above:
  90
  91            pf.drive0
  92            pf.drive1
  93            pf.drive2
  94            pf.drive3
  95            pf.cluster
  96            pf.nice
  97
  98        In addition, you can use the parameter pf.disable to disable
  99        the driver entirely.
 100
 101*/
 102
 103/* Changes:
 104
 105        1.01    GRG 1998.05.03  Changes for SMP.  Eliminate sti().
 106                                Fix for drives that don't clear STAT_ERR
 107                                until after next CDB delivered.
 108                                Small change in pf_completion to round
 109                                up transfer size.
 110        1.02    GRG 1998.06.16  Eliminated an Ugh
 111        1.03    GRG 1998.08.16  Use HZ in loop timings, extra debugging
 112        1.04    GRG 1998.09.24  Added jumbo support
 113
 114*/
 115
 116#define PF_VERSION      "1.04"
 117#define PF_MAJOR        47
 118#define PF_NAME         "pf"
 119#define PF_UNITS        4
 120
 121/* Here are things one can override from the insmod command.
 122   Most are autoprobed by paride unless set here.  Verbose is off
 123   by default.
 124
 125*/
 126
 127static int verbose = 0;
 128static int major = PF_MAJOR;
 129static char *name = PF_NAME;
 130static int cluster = 64;
 131static int nice = 0;
 132static int disable = 0;
 133
 134static int drive0[7] = { 0, 0, 0, -1, -1, -1, -1 };
 135static int drive1[7] = { 0, 0, 0, -1, -1, -1, -1 };
 136static int drive2[7] = { 0, 0, 0, -1, -1, -1, -1 };
 137static int drive3[7] = { 0, 0, 0, -1, -1, -1, -1 };
 138
 139static int (*drives[4])[7] = {&drive0, &drive1, &drive2, &drive3};
 140static int pf_drive_count;
 141
 142enum {D_PRT, D_PRO, D_UNI, D_MOD, D_SLV, D_LUN, D_DLY};
 143
 144/* end of parameters */
 145
 146#include <linux/module.h>
 147#include <linux/init.h>
 148#include <linux/fs.h>
 149#include <linux/delay.h>
 150#include <linux/hdreg.h>
 151#include <linux/cdrom.h>
 152#include <linux/spinlock.h>
 153#include <linux/blkdev.h>
 154#include <linux/blkpg.h>
 155#include <asm/uaccess.h>
 156
 157static DEFINE_SPINLOCK(pf_spin_lock);
 158
 159module_param(verbose, bool, 0644);
 160module_param(major, int, 0);
 161module_param(name, charp, 0);
 162module_param(cluster, int, 0);
 163module_param(nice, int, 0);
 164module_param_array(drive0, int, NULL, 0);
 165module_param_array(drive1, int, NULL, 0);
 166module_param_array(drive2, int, NULL, 0);
 167module_param_array(drive3, int, NULL, 0);
 168
 169#include "paride.h"
 170#include "pseudo.h"
 171
 172/* constants for faking geometry numbers */
 173
 174#define PF_FD_MAX       8192    /* use FD geometry under this size */
 175#define PF_FD_HDS       2
 176#define PF_FD_SPT       18
 177#define PF_HD_HDS       64
 178#define PF_HD_SPT       32
 179
 180#define PF_MAX_RETRIES  5
 181#define PF_TMO          800     /* interrupt timeout in jiffies */
 182#define PF_SPIN_DEL     50      /* spin delay in micro-seconds  */
 183
 184#define PF_SPIN         (1000000*PF_TMO)/(HZ*PF_SPIN_DEL)
 185
 186#define STAT_ERR        0x00001
 187#define STAT_INDEX      0x00002
 188#define STAT_ECC        0x00004
 189#define STAT_DRQ        0x00008
 190#define STAT_SEEK       0x00010
 191#define STAT_WRERR      0x00020
 192#define STAT_READY      0x00040
 193#define STAT_BUSY       0x00080
 194
 195#define ATAPI_REQ_SENSE         0x03
 196#define ATAPI_LOCK              0x1e
 197#define ATAPI_DOOR              0x1b
 198#define ATAPI_MODE_SENSE        0x5a
 199#define ATAPI_CAPACITY          0x25
 200#define ATAPI_IDENTIFY          0x12
 201#define ATAPI_READ_10           0x28
 202#define ATAPI_WRITE_10          0x2a
 203
 204static int pf_open(struct block_device *bdev, fmode_t mode);
 205static void do_pf_request(struct request_queue * q);
 206static int pf_ioctl(struct block_device *bdev, fmode_t mode,
 207                    unsigned int cmd, unsigned long arg);
 208static int pf_getgeo(struct block_device *bdev, struct hd_geometry *geo);
 209
 210static int pf_release(struct gendisk *disk, fmode_t mode);
 211
 212static int pf_detect(void);
 213static void do_pf_read(void);
 214static void do_pf_read_start(void);
 215static void do_pf_write(void);
 216static void do_pf_write_start(void);
 217static void do_pf_read_drq(void);
 218static void do_pf_write_done(void);
 219
 220#define PF_NM           0
 221#define PF_RO           1
 222#define PF_RW           2
 223
 224#define PF_NAMELEN      8
 225
 226struct pf_unit {
 227        struct pi_adapter pia;  /* interface to paride layer */
 228        struct pi_adapter *pi;
 229        int removable;          /* removable media device  ?  */
 230        int media_status;       /* media present ?  WP ? */
 231        int drive;              /* drive */
 232        int lun;
 233        int access;             /* count of active opens ... */
 234        int present;            /* device present ? */
 235        char name[PF_NAMELEN];  /* pf0, pf1, ... */
 236        struct gendisk *disk;
 237};
 238
 239static struct pf_unit units[PF_UNITS];
 240
 241static int pf_identify(struct pf_unit *pf);
 242static void pf_lock(struct pf_unit *pf, int func);
 243static void pf_eject(struct pf_unit *pf);
 244static int pf_check_media(struct gendisk *disk);
 245
 246static char pf_scratch[512];    /* scratch block buffer */
 247
 248/* the variables below are used mainly in the I/O request engine, which
 249   processes only one request at a time.
 250*/
 251
 252static int pf_retries = 0;      /* i/o error retry count */
 253static int pf_busy = 0;         /* request being processed ? */
 254static struct request *pf_req;  /* current request */
 255static int pf_block;            /* address of next requested block */
 256static int pf_count;            /* number of blocks still to do */
 257static int pf_run;              /* sectors in current cluster */
 258static int pf_cmd;              /* current command READ/WRITE */
 259static struct pf_unit *pf_current;/* unit of current request */
 260static int pf_mask;             /* stopper for pseudo-int */
 261static char *pf_buf;            /* buffer for request in progress */
 262
 263/* kernel glue structures */
 264
 265static const struct block_device_operations pf_fops = {
 266        .owner          = THIS_MODULE,
 267        .open           = pf_open,
 268        .release        = pf_release,
 269        .locked_ioctl   = pf_ioctl,
 270        .getgeo         = pf_getgeo,
 271        .media_changed  = pf_check_media,
 272};
 273
 274static void __init pf_init_units(void)
 275{
 276        struct pf_unit *pf;
 277        int unit;
 278
 279        pf_drive_count = 0;
 280        for (unit = 0, pf = units; unit < PF_UNITS; unit++, pf++) {
 281                struct gendisk *disk = alloc_disk(1);
 282                if (!disk)
 283                        continue;
 284                pf->disk = disk;
 285                pf->pi = &pf->pia;
 286                pf->media_status = PF_NM;
 287                pf->drive = (*drives[unit])[D_SLV];
 288                pf->lun = (*drives[unit])[D_LUN];
 289                snprintf(pf->name, PF_NAMELEN, "%s%d", name, unit);
 290                disk->major = major;
 291                disk->first_minor = unit;
 292                strcpy(disk->disk_name, pf->name);
 293                disk->fops = &pf_fops;
 294                if (!(*drives[unit])[D_PRT])
 295                        pf_drive_count++;
 296        }
 297}
 298
 299static int pf_open(struct block_device *bdev, fmode_t mode)
 300{
 301        struct pf_unit *pf = bdev->bd_disk->private_data;
 302
 303        pf_identify(pf);
 304
 305        if (pf->media_status == PF_NM)
 306                return -ENODEV;
 307
 308        if ((pf->media_status == PF_RO) && (mode & FMODE_WRITE))
 309                return -EROFS;
 310
 311        pf->access++;
 312        if (pf->removable)
 313                pf_lock(pf, 1);
 314
 315        return 0;
 316}
 317
 318static int pf_getgeo(struct block_device *bdev, struct hd_geometry *geo)
 319{
 320        struct pf_unit *pf = bdev->bd_disk->private_data;
 321        sector_t capacity = get_capacity(pf->disk);
 322
 323        if (capacity < PF_FD_MAX) {
 324                geo->cylinders = sector_div(capacity, PF_FD_HDS * PF_FD_SPT);
 325                geo->heads = PF_FD_HDS;
 326                geo->sectors = PF_FD_SPT;
 327        } else {
 328                geo->cylinders = sector_div(capacity, PF_HD_HDS * PF_HD_SPT);
 329                geo->heads = PF_HD_HDS;
 330                geo->sectors = PF_HD_SPT;
 331        }
 332
 333        return 0;
 334}
 335
 336static int pf_ioctl(struct block_device *bdev, fmode_t mode, unsigned int cmd, unsigned long arg)
 337{
 338        struct pf_unit *pf = bdev->bd_disk->private_data;
 339
 340        if (cmd != CDROMEJECT)
 341                return -EINVAL;
 342
 343        if (pf->access != 1)
 344                return -EBUSY;
 345        pf_eject(pf);
 346        return 0;
 347}
 348
 349static int pf_release(struct gendisk *disk, fmode_t mode)
 350{
 351        struct pf_unit *pf = disk->private_data;
 352
 353        if (pf->access <= 0)
 354                return -EINVAL;
 355
 356        pf->access--;
 357
 358        if (!pf->access && pf->removable)
 359                pf_lock(pf, 0);
 360
 361        return 0;
 362
 363}
 364
 365static int pf_check_media(struct gendisk *disk)
 366{
 367        return 1;
 368}
 369
 370static inline int status_reg(struct pf_unit *pf)
 371{
 372        return pi_read_regr(pf->pi, 1, 6);
 373}
 374
 375static inline int read_reg(struct pf_unit *pf, int reg)
 376{
 377        return pi_read_regr(pf->pi, 0, reg);
 378}
 379
 380static inline void write_reg(struct pf_unit *pf, int reg, int val)
 381{
 382        pi_write_regr(pf->pi, 0, reg, val);
 383}
 384
 385static int pf_wait(struct pf_unit *pf, int go, int stop, char *fun, char *msg)
 386{
 387        int j, r, e, s, p;
 388
 389        j = 0;
 390        while ((((r = status_reg(pf)) & go) || (stop && (!(r & stop))))
 391               && (j++ < PF_SPIN))
 392                udelay(PF_SPIN_DEL);
 393
 394        if ((r & (STAT_ERR & stop)) || (j >= PF_SPIN)) {
 395                s = read_reg(pf, 7);
 396                e = read_reg(pf, 1);
 397                p = read_reg(pf, 2);
 398                if (j >= PF_SPIN)
 399                        e |= 0x100;
 400                if (fun)
 401                        printk("%s: %s %s: alt=0x%x stat=0x%x err=0x%x"
 402                               " loop=%d phase=%d\n",
 403                               pf->name, fun, msg, r, s, e, j, p);
 404                return (e << 8) + s;
 405        }
 406        return 0;
 407}
 408
 409static int pf_command(struct pf_unit *pf, char *cmd, int dlen, char *fun)
 410{
 411        pi_connect(pf->pi);
 412
 413        write_reg(pf, 6, 0xa0+0x10*pf->drive);
 414
 415        if (pf_wait(pf, STAT_BUSY | STAT_DRQ, 0, fun, "before command")) {
 416                pi_disconnect(pf->pi);
 417                return -1;
 418        }
 419
 420        write_reg(pf, 4, dlen % 256);
 421        write_reg(pf, 5, dlen / 256);
 422        write_reg(pf, 7, 0xa0); /* ATAPI packet command */
 423
 424        if (pf_wait(pf, STAT_BUSY, STAT_DRQ, fun, "command DRQ")) {
 425                pi_disconnect(pf->pi);
 426                return -1;
 427        }
 428
 429        if (read_reg(pf, 2) != 1) {
 430                printk("%s: %s: command phase error\n", pf->name, fun);
 431                pi_disconnect(pf->pi);
 432                return -1;
 433        }
 434
 435        pi_write_block(pf->pi, cmd, 12);
 436
 437        return 0;
 438}
 439
 440static int pf_completion(struct pf_unit *pf, char *buf, char *fun)
 441{
 442        int r, s, n;
 443
 444        r = pf_wait(pf, STAT_BUSY, STAT_DRQ | STAT_READY | STAT_ERR,
 445                    fun, "completion");
 446
 447        if ((read_reg(pf, 2) & 2) && (read_reg(pf, 7) & STAT_DRQ)) {
 448                n = (((read_reg(pf, 4) + 256 * read_reg(pf, 5)) +
 449                      3) & 0xfffc);
 450                pi_read_block(pf->pi, buf, n);
 451        }
 452
 453        s = pf_wait(pf, STAT_BUSY, STAT_READY | STAT_ERR, fun, "data done");
 454
 455        pi_disconnect(pf->pi);
 456
 457        return (r ? r : s);
 458}
 459
 460static void pf_req_sense(struct pf_unit *pf, int quiet)
 461{
 462        char rs_cmd[12] =
 463            { ATAPI_REQ_SENSE, pf->lun << 5, 0, 0, 16, 0, 0, 0, 0, 0, 0, 0 };
 464        char buf[16];
 465        int r;
 466
 467        r = pf_command(pf, rs_cmd, 16, "Request sense");
 468        mdelay(1);
 469        if (!r)
 470                pf_completion(pf, buf, "Request sense");
 471
 472        if ((!r) && (!quiet))
 473                printk("%s: Sense key: %x, ASC: %x, ASQ: %x\n",
 474                       pf->name, buf[2] & 0xf, buf[12], buf[13]);
 475}
 476
 477static int pf_atapi(struct pf_unit *pf, char *cmd, int dlen, char *buf, char *fun)
 478{
 479        int r;
 480
 481        r = pf_command(pf, cmd, dlen, fun);
 482        mdelay(1);
 483        if (!r)
 484                r = pf_completion(pf, buf, fun);
 485        if (r)
 486                pf_req_sense(pf, !fun);
 487
 488        return r;
 489}
 490
 491static void pf_lock(struct pf_unit *pf, int func)
 492{
 493        char lo_cmd[12] = { ATAPI_LOCK, pf->lun << 5, 0, 0, func, 0, 0, 0, 0, 0, 0, 0 };
 494
 495        pf_atapi(pf, lo_cmd, 0, pf_scratch, func ? "lock" : "unlock");
 496}
 497
 498static void pf_eject(struct pf_unit *pf)
 499{
 500        char ej_cmd[12] = { ATAPI_DOOR, pf->lun << 5, 0, 0, 2, 0, 0, 0, 0, 0, 0, 0 };
 501
 502        pf_lock(pf, 0);
 503        pf_atapi(pf, ej_cmd, 0, pf_scratch, "eject");
 504}
 505
 506#define PF_RESET_TMO   30       /* in tenths of a second */
 507
 508static void pf_sleep(int cs)
 509{
 510        schedule_timeout_interruptible(cs);
 511}
 512
 513/* the ATAPI standard actually specifies the contents of all 7 registers
 514   after a reset, but the specification is ambiguous concerning the last
 515   two bytes, and different drives interpret the standard differently.
 516 */
 517
 518static int pf_reset(struct pf_unit *pf)
 519{
 520        int i, k, flg;
 521        int expect[5] = { 1, 1, 1, 0x14, 0xeb };
 522
 523        pi_connect(pf->pi);
 524        write_reg(pf, 6, 0xa0+0x10*pf->drive);
 525        write_reg(pf, 7, 8);
 526
 527        pf_sleep(20 * HZ / 1000);
 528
 529        k = 0;
 530        while ((k++ < PF_RESET_TMO) && (status_reg(pf) & STAT_BUSY))
 531                pf_sleep(HZ / 10);
 532
 533        flg = 1;
 534        for (i = 0; i < 5; i++)
 535                flg &= (read_reg(pf, i + 1) == expect[i]);
 536
 537        if (verbose) {
 538                printk("%s: Reset (%d) signature = ", pf->name, k);
 539                for (i = 0; i < 5; i++)
 540                        printk("%3x", read_reg(pf, i + 1));
 541                if (!flg)
 542                        printk(" (incorrect)");
 543                printk("\n");
 544        }
 545
 546        pi_disconnect(pf->pi);
 547        return flg - 1;
 548}
 549
 550static void pf_mode_sense(struct pf_unit *pf)
 551{
 552        char ms_cmd[12] =
 553            { ATAPI_MODE_SENSE, pf->lun << 5, 0, 0, 0, 0, 0, 0, 8, 0, 0, 0 };
 554        char buf[8];
 555
 556        pf_atapi(pf, ms_cmd, 8, buf, "mode sense");
 557        pf->media_status = PF_RW;
 558        if (buf[3] & 0x80)
 559                pf->media_status = PF_RO;
 560}
 561
 562static void xs(char *buf, char *targ, int offs, int len)
 563{
 564        int j, k, l;
 565
 566        j = 0;
 567        l = 0;
 568        for (k = 0; k < len; k++)
 569                if ((buf[k + offs] != 0x20) || (buf[k + offs] != l))
 570                        l = targ[j++] = buf[k + offs];
 571        if (l == 0x20)
 572                j--;
 573        targ[j] = 0;
 574}
 575
 576static int xl(char *buf, int offs)
 577{
 578        int v, k;
 579
 580        v = 0;
 581        for (k = 0; k < 4; k++)
 582                v = v * 256 + (buf[k + offs] & 0xff);
 583        return v;
 584}
 585
 586static void pf_get_capacity(struct pf_unit *pf)
 587{
 588        char rc_cmd[12] = { ATAPI_CAPACITY, pf->lun << 5, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0 };
 589        char buf[8];
 590        int bs;
 591
 592        if (pf_atapi(pf, rc_cmd, 8, buf, "get capacity")) {
 593                pf->media_status = PF_NM;
 594                return;
 595        }
 596        set_capacity(pf->disk, xl(buf, 0) + 1);
 597        bs = xl(buf, 4);
 598        if (bs != 512) {
 599                set_capacity(pf->disk, 0);
 600                if (verbose)
 601                        printk("%s: Drive %d, LUN %d,"
 602                               " unsupported block size %d\n",
 603                               pf->name, pf->drive, pf->lun, bs);
 604        }
 605}
 606
 607static int pf_identify(struct pf_unit *pf)
 608{
 609        int dt, s;
 610        char *ms[2] = { "master", "slave" };
 611        char mf[10], id[18];
 612        char id_cmd[12] =
 613            { ATAPI_IDENTIFY, pf->lun << 5, 0, 0, 36, 0, 0, 0, 0, 0, 0, 0 };
 614        char buf[36];
 615
 616        s = pf_atapi(pf, id_cmd, 36, buf, "identify");
 617        if (s)
 618                return -1;
 619
 620        dt = buf[0] & 0x1f;
 621        if ((dt != 0) && (dt != 7)) {
 622                if (verbose)
 623                        printk("%s: Drive %d, LUN %d, unsupported type %d\n",
 624                               pf->name, pf->drive, pf->lun, dt);
 625                return -1;
 626        }
 627
 628        xs(buf, mf, 8, 8);
 629        xs(buf, id, 16, 16);
 630
 631        pf->removable = (buf[1] & 0x80);
 632
 633        pf_mode_sense(pf);
 634        pf_mode_sense(pf);
 635        pf_mode_sense(pf);
 636
 637        pf_get_capacity(pf);
 638
 639        printk("%s: %s %s, %s LUN %d, type %d",
 640               pf->name, mf, id, ms[pf->drive], pf->lun, dt);
 641        if (pf->removable)
 642                printk(", removable");
 643        if (pf->media_status == PF_NM)
 644                printk(", no media\n");
 645        else {
 646                if (pf->media_status == PF_RO)
 647                        printk(", RO");
 648                printk(", %llu blocks\n",
 649                        (unsigned long long)get_capacity(pf->disk));
 650        }
 651        return 0;
 652}
 653
 654/*      returns  0, with id set if drive is detected
 655                -1, if drive detection failed
 656*/
 657static int pf_probe(struct pf_unit *pf)
 658{
 659        if (pf->drive == -1) {
 660                for (pf->drive = 0; pf->drive <= 1; pf->drive++)
 661                        if (!pf_reset(pf)) {
 662                                if (pf->lun != -1)
 663                                        return pf_identify(pf);
 664                                else
 665                                        for (pf->lun = 0; pf->lun < 8; pf->lun++)
 666                                                if (!pf_identify(pf))
 667                                                        return 0;
 668                        }
 669        } else {
 670                if (pf_reset(pf))
 671                        return -1;
 672                if (pf->lun != -1)
 673                        return pf_identify(pf);
 674                for (pf->lun = 0; pf->lun < 8; pf->lun++)
 675                        if (!pf_identify(pf))
 676                                return 0;
 677        }
 678        return -1;
 679}
 680
 681static int pf_detect(void)
 682{
 683        struct pf_unit *pf = units;
 684        int k, unit;
 685
 686        printk("%s: %s version %s, major %d, cluster %d, nice %d\n",
 687               name, name, PF_VERSION, major, cluster, nice);
 688
 689        k = 0;
 690        if (pf_drive_count == 0) {
 691                if (pi_init(pf->pi, 1, -1, -1, -1, -1, -1, pf_scratch, PI_PF,
 692                            verbose, pf->name)) {
 693                        if (!pf_probe(pf) && pf->disk) {
 694                                pf->present = 1;
 695                                k++;
 696                        } else
 697                                pi_release(pf->pi);
 698                }
 699
 700        } else
 701                for (unit = 0; unit < PF_UNITS; unit++, pf++) {
 702                        int *conf = *drives[unit];
 703                        if (!conf[D_PRT])
 704                                continue;
 705                        if (pi_init(pf->pi, 0, conf[D_PRT], conf[D_MOD],
 706                                    conf[D_UNI], conf[D_PRO], conf[D_DLY],
 707                                    pf_scratch, PI_PF, verbose, pf->name)) {
 708                                if (pf->disk && !pf_probe(pf)) {
 709                                        pf->present = 1;
 710                                        k++;
 711                                } else
 712                                        pi_release(pf->pi);
 713                        }
 714                }
 715        if (k)
 716                return 0;
 717
 718        printk("%s: No ATAPI disk detected\n", name);
 719        for (pf = units, unit = 0; unit < PF_UNITS; pf++, unit++)
 720                put_disk(pf->disk);
 721        return -1;
 722}
 723
 724/* The i/o request engine */
 725
 726static int pf_start(struct pf_unit *pf, int cmd, int b, int c)
 727{
 728        int i;
 729        char io_cmd[12] = { cmd, pf->lun << 5, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0 };
 730
 731        for (i = 0; i < 4; i++) {
 732                io_cmd[5 - i] = b & 0xff;
 733                b = b >> 8;
 734        }
 735
 736        io_cmd[8] = c & 0xff;
 737        io_cmd[7] = (c >> 8) & 0xff;
 738
 739        i = pf_command(pf, io_cmd, c * 512, "start i/o");
 740
 741        mdelay(1);
 742
 743        return i;
 744}
 745
 746static int pf_ready(void)
 747{
 748        return (((status_reg(pf_current) & (STAT_BUSY | pf_mask)) == pf_mask));
 749}
 750
 751static struct request_queue *pf_queue;
 752
 753static void pf_end_request(int err)
 754{
 755        if (pf_req && !__blk_end_request_cur(pf_req, err))
 756                pf_req = NULL;
 757}
 758
 759static void do_pf_request(struct request_queue * q)
 760{
 761        if (pf_busy)
 762                return;
 763repeat:
 764        if (!pf_req) {
 765                pf_req = blk_fetch_request(q);
 766                if (!pf_req)
 767                        return;
 768        }
 769
 770        pf_current = pf_req->rq_disk->private_data;
 771        pf_block = blk_rq_pos(pf_req);
 772        pf_run = blk_rq_sectors(pf_req);
 773        pf_count = blk_rq_cur_sectors(pf_req);
 774
 775        if (pf_block + pf_count > get_capacity(pf_req->rq_disk)) {
 776                pf_end_request(-EIO);
 777                goto repeat;
 778        }
 779
 780        pf_cmd = rq_data_dir(pf_req);
 781        pf_buf = pf_req->buffer;
 782        pf_retries = 0;
 783
 784        pf_busy = 1;
 785        if (pf_cmd == READ)
 786                pi_do_claimed(pf_current->pi, do_pf_read);
 787        else if (pf_cmd == WRITE)
 788                pi_do_claimed(pf_current->pi, do_pf_write);
 789        else {
 790                pf_busy = 0;
 791                pf_end_request(-EIO);
 792                goto repeat;
 793        }
 794}
 795
 796static int pf_next_buf(void)
 797{
 798        unsigned long saved_flags;
 799
 800        pf_count--;
 801        pf_run--;
 802        pf_buf += 512;
 803        pf_block++;
 804        if (!pf_run)
 805                return 1;
 806        if (!pf_count) {
 807                spin_lock_irqsave(&pf_spin_lock, saved_flags);
 808                pf_end_request(0);
 809                spin_unlock_irqrestore(&pf_spin_lock, saved_flags);
 810                if (!pf_req)
 811                        return 1;
 812                pf_count = blk_rq_cur_sectors(pf_req);
 813                pf_buf = pf_req->buffer;
 814        }
 815        return 0;
 816}
 817
 818static inline void next_request(int err)
 819{
 820        unsigned long saved_flags;
 821
 822        spin_lock_irqsave(&pf_spin_lock, saved_flags);
 823        pf_end_request(err);
 824        pf_busy = 0;
 825        do_pf_request(pf_queue);
 826        spin_unlock_irqrestore(&pf_spin_lock, saved_flags);
 827}
 828
 829/* detach from the calling context - in case the spinlock is held */
 830static void do_pf_read(void)
 831{
 832        ps_set_intr(do_pf_read_start, NULL, 0, nice);
 833}
 834
 835static void do_pf_read_start(void)
 836{
 837        pf_busy = 1;
 838
 839        if (pf_start(pf_current, ATAPI_READ_10, pf_block, pf_run)) {
 840                pi_disconnect(pf_current->pi);
 841                if (pf_retries < PF_MAX_RETRIES) {
 842                        pf_retries++;
 843                        pi_do_claimed(pf_current->pi, do_pf_read_start);
 844                        return;
 845                }
 846                next_request(-EIO);
 847                return;
 848        }
 849        pf_mask = STAT_DRQ;
 850        ps_set_intr(do_pf_read_drq, pf_ready, PF_TMO, nice);
 851}
 852
 853static void do_pf_read_drq(void)
 854{
 855        while (1) {
 856                if (pf_wait(pf_current, STAT_BUSY, STAT_DRQ | STAT_ERR,
 857                            "read block", "completion") & STAT_ERR) {
 858                        pi_disconnect(pf_current->pi);
 859                        if (pf_retries < PF_MAX_RETRIES) {
 860                                pf_req_sense(pf_current, 0);
 861                                pf_retries++;
 862                                pi_do_claimed(pf_current->pi, do_pf_read_start);
 863                                return;
 864                        }
 865                        next_request(-EIO);
 866                        return;
 867                }
 868                pi_read_block(pf_current->pi, pf_buf, 512);
 869                if (pf_next_buf())
 870                        break;
 871        }
 872        pi_disconnect(pf_current->pi);
 873        next_request(0);
 874}
 875
 876static void do_pf_write(void)
 877{
 878        ps_set_intr(do_pf_write_start, NULL, 0, nice);
 879}
 880
 881static void do_pf_write_start(void)
 882{
 883        pf_busy = 1;
 884
 885        if (pf_start(pf_current, ATAPI_WRITE_10, pf_block, pf_run)) {
 886                pi_disconnect(pf_current->pi);
 887                if (pf_retries < PF_MAX_RETRIES) {
 888                        pf_retries++;
 889                        pi_do_claimed(pf_current->pi, do_pf_write_start);
 890                        return;
 891                }
 892                next_request(-EIO);
 893                return;
 894        }
 895
 896        while (1) {
 897                if (pf_wait(pf_current, STAT_BUSY, STAT_DRQ | STAT_ERR,
 898                            "write block", "data wait") & STAT_ERR) {
 899                        pi_disconnect(pf_current->pi);
 900                        if (pf_retries < PF_MAX_RETRIES) {
 901                                pf_retries++;
 902                                pi_do_claimed(pf_current->pi, do_pf_write_start);
 903                                return;
 904                        }
 905                        next_request(-EIO);
 906                        return;
 907                }
 908                pi_write_block(pf_current->pi, pf_buf, 512);
 909                if (pf_next_buf())
 910                        break;
 911        }
 912        pf_mask = 0;
 913        ps_set_intr(do_pf_write_done, pf_ready, PF_TMO, nice);
 914}
 915
 916static void do_pf_write_done(void)
 917{
 918        if (pf_wait(pf_current, STAT_BUSY, 0, "write block", "done") & STAT_ERR) {
 919                pi_disconnect(pf_current->pi);
 920                if (pf_retries < PF_MAX_RETRIES) {
 921                        pf_retries++;
 922                        pi_do_claimed(pf_current->pi, do_pf_write_start);
 923                        return;
 924                }
 925                next_request(-EIO);
 926                return;
 927        }
 928        pi_disconnect(pf_current->pi);
 929        next_request(0);
 930}
 931
 932static int __init pf_init(void)
 933{                               /* preliminary initialisation */
 934        struct pf_unit *pf;
 935        int unit;
 936
 937        if (disable)
 938                return -EINVAL;
 939
 940        pf_init_units();
 941
 942        if (pf_detect())
 943                return -ENODEV;
 944        pf_busy = 0;
 945
 946        if (register_blkdev(major, name)) {
 947                for (pf = units, unit = 0; unit < PF_UNITS; pf++, unit++)
 948                        put_disk(pf->disk);
 949                return -EBUSY;
 950        }
 951        pf_queue = blk_init_queue(do_pf_request, &pf_spin_lock);
 952        if (!pf_queue) {
 953                unregister_blkdev(major, name);
 954                for (pf = units, unit = 0; unit < PF_UNITS; pf++, unit++)
 955                        put_disk(pf->disk);
 956                return -ENOMEM;
 957        }
 958
 959        blk_queue_max_phys_segments(pf_queue, cluster);
 960        blk_queue_max_hw_segments(pf_queue, cluster);
 961
 962        for (pf = units, unit = 0; unit < PF_UNITS; pf++, unit++) {
 963                struct gendisk *disk = pf->disk;
 964
 965                if (!pf->present)
 966                        continue;
 967                disk->private_data = pf;
 968                disk->queue = pf_queue;
 969                add_disk(disk);
 970        }
 971        return 0;
 972}
 973
 974static void __exit pf_exit(void)
 975{
 976        struct pf_unit *pf;
 977        int unit;
 978        unregister_blkdev(major, name);
 979        for (pf = units, unit = 0; unit < PF_UNITS; pf++, unit++) {
 980                if (!pf->present)
 981                        continue;
 982                del_gendisk(pf->disk);
 983                put_disk(pf->disk);
 984                pi_release(pf->pi);
 985        }
 986        blk_cleanup_queue(pf_queue);
 987}
 988
 989MODULE_LICENSE("GPL");
 990module_init(pf_init)
 991module_exit(pf_exit)
 992