linux-old/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
 142#define D_PRT   0
 143#define D_PRO   1
 144#define D_UNI   2
 145#define D_MOD   3
 146#define D_SLV   4
 147#define D_LUN   5
 148#define D_DLY   6
 149
 150#define DU              (*drives[unit])
 151
 152/* end of parameters */
 153
 154
 155#include <linux/module.h>
 156#include <linux/errno.h>
 157#include <linux/fs.h>
 158#include <linux/kernel.h>
 159#include <linux/delay.h>
 160#include <linux/genhd.h>
 161#include <linux/hdreg.h>
 162#include <linux/cdrom.h>
 163#include <linux/spinlock.h>
 164
 165#include <asm/uaccess.h>
 166
 167#ifndef MODULE
 168
 169#include "setup.h"
 170
 171static STT pf_stt[7] = {{"drive0",7,drive0},
 172                        {"drive1",7,drive1},
 173                        {"drive2",7,drive2},
 174                        {"drive3",7,drive3},
 175                        {"disable",1,&disable},
 176                        {"cluster",1,&cluster},
 177                        {"nice",1,&nice}};
 178
 179void pf_setup( char *str, int *ints)
 180
 181{       generic_setup(pf_stt,7,str);
 182}
 183
 184#endif
 185
 186MODULE_PARM(verbose,"i");
 187MODULE_PARM(major,"i");
 188MODULE_PARM(name,"s");
 189MODULE_PARM(cluster,"i");
 190MODULE_PARM(nice,"i");
 191MODULE_PARM(drive0,"1-7i");
 192MODULE_PARM(drive1,"1-7i");
 193MODULE_PARM(drive2,"1-7i");
 194MODULE_PARM(drive3,"1-7i");
 195
 196#include "paride.h"
 197
 198/* set up defines for blk.h,  why don't all drivers do it this way ? */
 199
 200#define MAJOR_NR   major
 201#define DEVICE_NAME "PF"
 202#define DEVICE_REQUEST do_pf_request
 203#define DEVICE_NR(device) MINOR(device)
 204#define DEVICE_ON(device)
 205#define DEVICE_OFF(device)
 206
 207#include <linux/blk.h>
 208#include <linux/blkpg.h>
 209
 210#include "pseudo.h"
 211
 212/* constants for faking geometry numbers */
 213
 214#define PF_FD_MAX       8192            /* use FD geometry under this size */
 215#define PF_FD_HDS       2
 216#define PF_FD_SPT       18
 217#define PF_HD_HDS       64
 218#define PF_HD_SPT       32
 219
 220#define PF_MAX_RETRIES  5
 221#define PF_TMO          800             /* interrupt timeout in jiffies */
 222#define PF_SPIN_DEL     50              /* spin delay in micro-seconds  */
 223
 224#define PF_SPIN         (1000000*PF_TMO)/(HZ*PF_SPIN_DEL)
 225
 226#define STAT_ERR        0x00001
 227#define STAT_INDEX      0x00002
 228#define STAT_ECC        0x00004
 229#define STAT_DRQ        0x00008
 230#define STAT_SEEK       0x00010
 231#define STAT_WRERR      0x00020
 232#define STAT_READY      0x00040
 233#define STAT_BUSY       0x00080
 234
 235#define ATAPI_REQ_SENSE         0x03
 236#define ATAPI_LOCK              0x1e
 237#define ATAPI_DOOR              0x1b
 238#define ATAPI_MODE_SENSE        0x5a
 239#define ATAPI_CAPACITY          0x25
 240#define ATAPI_IDENTIFY          0x12
 241#define ATAPI_READ_10           0x28
 242#define ATAPI_WRITE_10          0x2a
 243
 244int pf_init(void);
 245#ifdef MODULE
 246void cleanup_module( void );
 247#endif
 248static int pf_open(struct inode *inode, struct file *file);
 249static void do_pf_request(request_queue_t * q);
 250static int pf_ioctl(struct inode *inode,struct file *file,
 251                    unsigned int cmd, unsigned long arg);
 252
 253static int pf_release (struct inode *inode, struct file *file);
 254
 255static int pf_detect(void);
 256static void do_pf_read(void);
 257static void do_pf_read_start(void);
 258static void do_pf_write(void);
 259static void do_pf_write_start(void);
 260static void do_pf_read_drq( void );
 261static void do_pf_write_done( void );
 262
 263static int pf_identify (int unit);
 264static void pf_lock(int unit, int func);
 265static void pf_eject(int unit);
 266static int pf_check_media(kdev_t dev);
 267
 268static int pf_blocksizes[PF_UNITS];
 269
 270#define PF_NM           0
 271#define PF_RO           1
 272#define PF_RW           2
 273
 274#define PF_NAMELEN      8
 275
 276struct pf_unit {
 277        struct pi_adapter pia;    /* interface to paride layer */
 278        struct pi_adapter *pi;
 279        int removable;            /* removable media device  ?  */
 280        int media_status;         /* media present ?  WP ? */
 281        int drive;                /* drive */
 282        int lun;
 283        int access;               /* count of active opens ... */
 284        int capacity;             /* Size of this volume in sectors */
 285        int present;              /* device present ? */
 286        char name[PF_NAMELEN];    /* pf0, pf1, ... */
 287        };
 288
 289struct pf_unit pf[PF_UNITS];
 290
 291/*  'unit' must be defined in all functions - either as a local or a param */
 292
 293#define PF pf[unit]
 294#define PI PF.pi
 295
 296static char pf_scratch[512];            /* scratch block buffer */
 297
 298/* the variables below are used mainly in the I/O request engine, which
 299   processes only one request at a time.
 300*/
 301
 302static int pf_retries = 0;              /* i/o error retry count */
 303static int pf_busy = 0;                 /* request being processed ? */
 304static int pf_block;                    /* address of next requested block */
 305static int pf_count;                    /* number of blocks still to do */
 306static int pf_run;                      /* sectors in current cluster */
 307static int pf_cmd;                      /* current command READ/WRITE */
 308static int pf_unit;                     /* unit of current request */
 309static int pf_mask;                     /* stopper for pseudo-int */
 310static char * pf_buf;                   /* buffer for request in progress */
 311
 312/* kernel glue structures */
 313
 314static struct block_device_operations pf_fops = {
 315        owner:                  THIS_MODULE,
 316        open:                   pf_open,
 317        release:                pf_release,
 318        ioctl:                  pf_ioctl,
 319        check_media_change:     pf_check_media,
 320};
 321
 322void pf_init_units( void )
 323
 324{       int     unit, j;
 325
 326        pf_drive_count = 0;
 327        for (unit=0;unit<PF_UNITS;unit++) {
 328                PF.pi = & PF.pia;
 329                PF.access = 0;
 330                PF.media_status = PF_NM;
 331                PF.capacity = 0;
 332                PF.present = 0;
 333                PF.drive = DU[D_SLV];
 334                PF.lun = DU[D_LUN];
 335                j = 0;
 336                while ((j < PF_NAMELEN-2) && (PF.name[j]=name[j])) j++;
 337                PF.name[j++] = '0' + unit;
 338                PF.name[j] = 0;
 339                if (DU[D_PRT]) pf_drive_count++;
 340        }
 341} 
 342
 343static inline int pf_new_segment(request_queue_t *q, struct request *req, int max_segments)
 344{
 345        if (max_segments > cluster)
 346                max_segments = cluster;
 347
 348        if (req->nr_segments < max_segments) {
 349                req->nr_segments++;
 350                return 1;
 351        }
 352        return 0;
 353}
 354
 355static int pf_back_merge_fn(request_queue_t *q, struct request *req, 
 356                            struct buffer_head *bh, int max_segments)
 357{
 358        if (req->bhtail->b_data + req->bhtail->b_size == bh->b_data)
 359                return 1;
 360        return pf_new_segment(q, req, max_segments);
 361}
 362
 363static int pf_front_merge_fn(request_queue_t *q, struct request *req, 
 364                             struct buffer_head *bh, int max_segments)
 365{
 366        if (bh->b_data + bh->b_size == req->bh->b_data)
 367                return 1;
 368        return pf_new_segment(q, req, max_segments);
 369}
 370
 371static int pf_merge_requests_fn(request_queue_t *q, struct request *req,
 372                                struct request *next, int max_segments)
 373{
 374        int total_segments = req->nr_segments + next->nr_segments;
 375        int same_segment;
 376
 377        if (max_segments > cluster)
 378                max_segments = cluster;
 379
 380        same_segment = 0;
 381        if (req->bhtail->b_data + req->bhtail->b_size == next->bh->b_data) {
 382                total_segments--;
 383                same_segment = 1;
 384        }
 385    
 386        if (total_segments > max_segments)
 387                return 0;
 388
 389        req->nr_segments = total_segments;
 390        return 1;
 391}
 392
 393int pf_init (void)      /* preliminary initialisation */
 394
 395{       int i;
 396        request_queue_t * q; 
 397
 398        if (disable) return -1;
 399
 400        pf_init_units();
 401
 402        if (pf_detect()) return -1;
 403        pf_busy = 0;
 404
 405        if (register_blkdev(MAJOR_NR,name,&pf_fops)) {
 406                printk("pf_init: unable to get major number %d\n",
 407                        major);
 408                return -1;
 409        }
 410        q = BLK_DEFAULT_QUEUE(MAJOR_NR);
 411        blk_init_queue(q, DEVICE_REQUEST);
 412        q->back_merge_fn = pf_back_merge_fn;
 413        q->front_merge_fn = pf_front_merge_fn;
 414        q->merge_requests_fn = pf_merge_requests_fn;
 415        read_ahead[MAJOR_NR] = 8;       /* 8 sector (4kB) read ahead */
 416        
 417        for (i=0;i<PF_UNITS;i++) pf_blocksizes[i] = 1024;
 418        blksize_size[MAJOR_NR] = pf_blocksizes;
 419        for (i=0;i<PF_UNITS;i++)
 420                register_disk(NULL, MKDEV(MAJOR_NR, i), 1, &pf_fops, 0);
 421
 422        return 0;
 423}
 424
 425static int pf_open (struct inode *inode, struct file *file)
 426
 427{       int     unit = DEVICE_NR(inode->i_rdev);
 428
 429        if ((unit >= PF_UNITS) || (!PF.present)) return -ENODEV;
 430
 431        pf_identify(unit);
 432
 433        if (PF.media_status == PF_NM)
 434                return -ENODEV;
 435
 436        if ((PF.media_status == PF_RO) && (file ->f_mode & 2))
 437                return -EROFS;
 438
 439        PF.access++;
 440        if (PF.removable) pf_lock(unit,1);
 441
 442        return 0;
 443}
 444
 445static int pf_ioctl(struct inode *inode,struct file *file,
 446                    unsigned int cmd, unsigned long arg)
 447
 448{       int err, unit;
 449        struct hd_geometry *geo = (struct hd_geometry *) arg;
 450
 451        if ((!inode) || (!inode->i_rdev)) return -EINVAL;
 452        unit = DEVICE_NR(inode->i_rdev);
 453        if (unit >= PF_UNITS) return -EINVAL;
 454        if (!PF.present) return -ENODEV;
 455
 456        switch (cmd) {
 457            case CDROMEJECT: 
 458                if (PF.access == 1) {
 459                        pf_eject(unit);
 460                        return 0;
 461                        }
 462            case HDIO_GETGEO:
 463                if (!geo) return -EINVAL;
 464                err = verify_area(VERIFY_WRITE,geo,sizeof(*geo));
 465                if (err) return err;
 466                if (PF.capacity < PF_FD_MAX) {
 467                    put_user(PF.capacity/(PF_FD_HDS*PF_FD_SPT),
 468                                (short *) &geo->cylinders);
 469                    put_user(PF_FD_HDS, (char *) &geo->heads);
 470                    put_user(PF_FD_SPT, (char *) &geo->sectors);
 471                } else {
 472                    put_user(PF.capacity/(PF_HD_HDS*PF_HD_SPT), 
 473                                (short *) &geo->cylinders);
 474                    put_user(PF_HD_HDS, (char *) &geo->heads);
 475                    put_user(PF_HD_SPT, (char *) &geo->sectors);
 476                }
 477                put_user(0,(long *)&geo->start);
 478                return 0;
 479            case BLKGETSIZE:
 480                return put_user(PF.capacity,(long *) arg);
 481            case BLKGETSIZE64:
 482                return put_user((u64)PF.capacity << 9,(u64 *)arg);
 483            case BLKROSET:
 484            case BLKROGET:
 485            case BLKRASET:
 486            case BLKRAGET:
 487            case BLKFLSBUF:
 488                return blk_ioctl(inode->i_rdev, cmd, arg);
 489            default:
 490                return -EINVAL;
 491        }
 492}
 493
 494
 495static int pf_release (struct inode *inode, struct file *file)
 496
 497{       kdev_t devp;
 498        int     unit;
 499
 500        devp = inode->i_rdev;
 501        unit = DEVICE_NR(devp);
 502
 503        if ((unit >= PF_UNITS) || (PF.access <= 0)) 
 504                return -EINVAL;
 505
 506        PF.access--;
 507
 508        if (!PF.access && PF.removable)
 509                pf_lock(unit,0);
 510
 511        return 0;
 512
 513}
 514
 515static int pf_check_media( kdev_t dev)
 516
 517{       return 1;
 518}
 519
 520#ifdef MODULE
 521
 522/* Glue for modules ... */
 523
 524void    cleanup_module(void);
 525
 526int     init_module(void)
 527
 528{       int     err;
 529
 530#ifdef PARIDE_JUMBO
 531       { extern paride_init();
 532         paride_init();
 533       } 
 534#endif
 535
 536        err = pf_init();
 537
 538        return err;
 539}
 540
 541void    cleanup_module(void)
 542
 543{       int unit;
 544
 545        unregister_blkdev(MAJOR_NR,name);
 546
 547        for (unit=0;unit<PF_UNITS;unit++)
 548          if (PF.present) pi_release(PI);
 549}
 550
 551#endif
 552
 553#define WR(c,r,v)       pi_write_regr(PI,c,r,v)
 554#define RR(c,r)         (pi_read_regr(PI,c,r))
 555
 556#define LUN             (0x20*PF.lun)
 557#define DRIVE           (0xa0+0x10*PF.drive)
 558
 559static int pf_wait( int unit, int go, int stop, char * fun, char * msg )
 560
 561{       int j, r, e, s, p;
 562
 563        j = 0;
 564        while ((((r=RR(1,6))&go)||(stop&&(!(r&stop))))&&(j++<PF_SPIN))
 565                udelay(PF_SPIN_DEL);
 566
 567        if ((r&(STAT_ERR&stop))||(j>=PF_SPIN)) {
 568           s = RR(0,7);
 569           e = RR(0,1);
 570           p = RR(0,2);
 571           if (j >= PF_SPIN) e |= 0x100;
 572           if (fun) printk("%s: %s %s: alt=0x%x stat=0x%x err=0x%x"
 573                           " loop=%d phase=%d\n",
 574                            PF.name,fun,msg,r,s,e,j,p);
 575           return (e<<8)+s;
 576        }
 577        return 0;
 578}
 579
 580static int pf_command( int unit, char * cmd, int dlen, char * fun )
 581
 582{       pi_connect(PI);
 583
 584        WR(0,6,DRIVE);
 585
 586        if (pf_wait(unit,STAT_BUSY|STAT_DRQ,0,fun,"before command")) {
 587                pi_disconnect(PI);
 588                return -1;
 589        }
 590
 591        WR(0,4,dlen % 256);
 592        WR(0,5,dlen / 256);
 593        WR(0,7,0xa0);          /* ATAPI packet command */
 594
 595        if (pf_wait(unit,STAT_BUSY,STAT_DRQ,fun,"command DRQ")) {
 596                pi_disconnect(PI);
 597                return -1;
 598        }
 599
 600        if (RR(0,2) != 1) {
 601           printk("%s: %s: command phase error\n",PF.name,fun);
 602           pi_disconnect(PI);
 603           return -1;
 604        }
 605
 606        pi_write_block(PI,cmd,12);
 607
 608        return 0;
 609}
 610
 611static int pf_completion( int unit, char * buf, char * fun )
 612
 613{       int r, s, n;
 614
 615        r = pf_wait(unit,STAT_BUSY,STAT_DRQ|STAT_READY|STAT_ERR,
 616                        fun,"completion");
 617
 618        if ((RR(0,2)&2) && (RR(0,7)&STAT_DRQ)) { 
 619                n = (((RR(0,4)+256*RR(0,5))+3)&0xfffc);
 620                pi_read_block(PI,buf,n);
 621        }
 622
 623        s = pf_wait(unit,STAT_BUSY,STAT_READY|STAT_ERR,fun,"data done");
 624
 625        pi_disconnect(PI); 
 626
 627        return (r?r:s);
 628}
 629
 630static void pf_req_sense( int unit, int quiet )
 631
 632{       char    rs_cmd[12] = { ATAPI_REQ_SENSE,LUN,0,0,16,0,0,0,0,0,0,0 };
 633        char    buf[16];
 634        int     r;
 635
 636        r = pf_command(unit,rs_cmd,16,"Request sense");
 637        mdelay(1);
 638        if (!r) pf_completion(unit,buf,"Request sense");
 639
 640        if ((!r)&&(!quiet)) 
 641                printk("%s: Sense key: %x, ASC: %x, ASQ: %x\n",
 642                       PF.name,buf[2]&0xf,buf[12],buf[13]);
 643}
 644
 645static int pf_atapi( int unit, char * cmd, int dlen, char * buf, char * fun )
 646
 647{       int r;
 648
 649        r = pf_command(unit,cmd,dlen,fun);
 650        mdelay(1);
 651        if (!r) r = pf_completion(unit,buf,fun);
 652        if (r) pf_req_sense(unit,!fun);
 653        
 654        return r;
 655}
 656
 657#define DBMSG(msg)      ((verbose>1)?(msg):NULL)
 658
 659static void pf_lock(int unit, int func)
 660
 661{       char    lo_cmd[12] = { ATAPI_LOCK,LUN,0,0,func,0,0,0,0,0,0,0 };
 662
 663        pf_atapi(unit,lo_cmd,0,pf_scratch,func?"unlock":"lock");
 664}
 665
 666
 667static void pf_eject( int unit )
 668
 669{       char    ej_cmd[12] = { ATAPI_DOOR,LUN,0,0,2,0,0,0,0,0,0,0 };
 670
 671        pf_lock(unit,0);
 672        pf_atapi(unit,ej_cmd,0,pf_scratch,"eject");
 673}
 674
 675#define PF_RESET_TMO   30              /* in tenths of a second */
 676
 677static void pf_sleep( int cs )
 678
 679{       current->state = TASK_INTERRUPTIBLE;
 680        schedule_timeout(cs);
 681}
 682
 683
 684static int pf_reset( int unit )
 685
 686/* the ATAPI standard actually specifies the contents of all 7 registers
 687   after a reset, but the specification is ambiguous concerning the last
 688   two bytes, and different drives interpret the standard differently.
 689*/
 690
 691{       int     i, k, flg;
 692        int     expect[5] = {1,1,1,0x14,0xeb};
 693
 694        pi_connect(PI);
 695        WR(0,6,DRIVE);
 696        WR(0,7,8);
 697
 698        pf_sleep(20*HZ/1000);
 699
 700        k = 0;
 701        while ((k++ < PF_RESET_TMO) && (RR(1,6)&STAT_BUSY))
 702                pf_sleep(HZ/10);
 703
 704        flg = 1;
 705        for(i=0;i<5;i++) flg &= (RR(0,i+1) == expect[i]);
 706
 707        if (verbose) {
 708                printk("%s: Reset (%d) signature = ",PF.name,k);
 709                for (i=0;i<5;i++) printk("%3x",RR(0,i+1));
 710                if (!flg) printk(" (incorrect)");
 711                printk("\n");
 712        }
 713        
 714        pi_disconnect(PI);
 715        return flg-1;   
 716}
 717
 718static void pf_mode_sense( int unit )
 719
 720{       char    ms_cmd[12] = { ATAPI_MODE_SENSE,LUN,0,0,0,0,0,0,8,0,0,0};
 721        char    buf[8];
 722
 723        pf_atapi(unit,ms_cmd,8,buf,DBMSG("mode sense"));
 724        PF.media_status = PF_RW;
 725        if (buf[3] & 0x80) PF.media_status = PF_RO;
 726}
 727
 728static void xs( char *buf, char *targ, int offs, int len )
 729
 730{       int     j,k,l;
 731
 732        j=0; l=0;
 733        for (k=0;k<len;k++) 
 734           if((buf[k+offs]!=0x20)||(buf[k+offs]!=l))
 735                l=targ[j++]=buf[k+offs];
 736        if (l==0x20) j--;
 737        targ[j]=0;
 738}
 739
 740static int xl( char *buf, int offs )
 741
 742{       int     v,k;
 743
 744        v=0; 
 745        for(k=0;k<4;k++) v=v*256+(buf[k+offs]&0xff);
 746        return v;
 747}
 748
 749static void pf_get_capacity( int unit )
 750
 751{       char    rc_cmd[12] = { ATAPI_CAPACITY,LUN,0,0,0,0,0,0,0,0,0,0};
 752        char    buf[8];
 753        int     bs;
 754
 755        if (pf_atapi(unit,rc_cmd,8,buf,DBMSG("get capacity"))) {
 756                PF.media_status = PF_NM;
 757                return;
 758        }
 759        PF.capacity = xl(buf,0) + 1;  
 760        bs = xl(buf,4);
 761        if (bs != 512) {
 762                PF.capacity = 0;
 763                if (verbose) printk("%s: Drive %d, LUN %d,"
 764                                    " unsupported block size %d\n",
 765                                    PF.name,PF.drive,PF.lun,bs);
 766                }
 767}
 768
 769static int pf_identify( int unit )
 770
 771{       int     dt, s;
 772        char    *ms[2] = {"master","slave"};
 773        char    mf[10], id[18];
 774        char    id_cmd[12] = { ATAPI_IDENTIFY,LUN,0,0,36,0,0,0,0,0,0,0};
 775        char    buf[36];
 776
 777        s = pf_atapi(unit,id_cmd,36,buf,"identify");
 778        if (s) return -1;
 779
 780        dt = buf[0] & 0x1f;
 781        if ((dt != 0) && (dt != 7)) {
 782                if (verbose) 
 783                   printk("%s: Drive %d, LUN %d, unsupported type %d\n",
 784                                PF.name,PF.drive,PF.lun,dt);
 785                return -1;
 786        }
 787
 788        xs(buf,mf,8,8);
 789        xs(buf,id,16,16);
 790
 791        PF.removable = (buf[1] & 0x80);
 792
 793        pf_mode_sense(unit);
 794        pf_mode_sense(unit);
 795        pf_mode_sense(unit);
 796
 797        pf_get_capacity(unit);
 798
 799        printk("%s: %s %s, %s LUN %d, type %d",
 800                PF.name,mf,id,ms[PF.drive],PF.lun,dt);
 801        if (PF.removable) printk(", removable");
 802        if (PF.media_status == PF_NM) 
 803                printk(", no media\n");
 804        else {  if (PF.media_status == PF_RO) printk(", RO");
 805                printk(", %d blocks\n",PF.capacity);
 806        }
 807
 808        return 0;
 809}
 810
 811static int pf_probe( int unit )
 812
 813/*      returns  0, with id set if drive is detected
 814                -1, if drive detection failed
 815*/
 816
 817{       if (PF.drive == -1) {
 818           for (PF.drive=0;PF.drive<=1;PF.drive++)
 819                if (!pf_reset(unit)) {
 820                   if (PF.lun != -1) return pf_identify(unit);
 821                   else for (PF.lun=0;PF.lun<8;PF.lun++) 
 822                           if (!pf_identify(unit)) return 0;
 823                }
 824        } else {
 825           if (pf_reset(unit)) return -1;
 826           if (PF.lun != -1) return pf_identify(unit);
 827           for (PF.lun=0;PF.lun<8;PF.lun++) 
 828              if (!pf_identify(unit)) return 0;
 829        }
 830        return -1; 
 831}
 832
 833static int pf_detect( void )
 834
 835{       int     k, unit;
 836
 837        printk("%s: %s version %s, major %d, cluster %d, nice %d\n",
 838                name,name,PF_VERSION,major,cluster,nice);
 839
 840        k = 0;
 841        if (pf_drive_count == 0) {
 842            unit = 0;
 843            if (pi_init(PI,1,-1,-1,-1,-1,-1,pf_scratch,
 844                        PI_PF,verbose,PF.name)) {
 845                if (!pf_probe(unit)) {
 846                        PF.present = 1;
 847                        k++;
 848                } else pi_release(PI);
 849            }
 850
 851        } else for (unit=0;unit<PF_UNITS;unit++) if (DU[D_PRT])
 852            if (pi_init(PI,0,DU[D_PRT],DU[D_MOD],DU[D_UNI],
 853                        DU[D_PRO],DU[D_DLY],pf_scratch,PI_PF,verbose,
 854                        PF.name)) { 
 855                if (!pf_probe(unit)) {
 856                        PF.present = 1;
 857                        k++;
 858                } else pi_release(PI);
 859            }
 860
 861        if (k) return 0;
 862
 863        printk("%s: No ATAPI disk detected\n",name);
 864        return -1;
 865}
 866
 867/* The i/o request engine */
 868
 869static int pf_start( int unit, int cmd, int b, int c )
 870
 871{       int     i;
 872        char    io_cmd[12] = {cmd,LUN,0,0,0,0,0,0,0,0,0,0};
 873
 874        for(i=0;i<4;i++) { 
 875           io_cmd[5-i] = b & 0xff;
 876           b = b >> 8;
 877        }
 878        
 879        io_cmd[8] = c & 0xff;
 880        io_cmd[7] = (c >> 8) & 0xff;
 881
 882        i = pf_command(unit,io_cmd,c*512,"start i/o");
 883
 884        mdelay(1);
 885
 886        return i;       
 887}
 888
 889static int pf_ready( void )
 890
 891{       int     unit = pf_unit;
 892
 893        return (((RR(1,6)&(STAT_BUSY|pf_mask)) == pf_mask));
 894}
 895
 896static void do_pf_request (request_queue_t * q)
 897
 898{       struct buffer_head * bh;
 899        int unit;
 900
 901        if (pf_busy) return;
 902repeat:
 903        if (QUEUE_EMPTY || (CURRENT->rq_status == RQ_INACTIVE)) return;
 904        INIT_REQUEST;
 905
 906        pf_unit = unit = DEVICE_NR(CURRENT->rq_dev);
 907        pf_block = CURRENT->sector;
 908        pf_run = CURRENT->nr_sectors;
 909        pf_count = CURRENT->current_nr_sectors;
 910
 911        bh = CURRENT->bh;
 912
 913        if ((pf_unit >= PF_UNITS) || (pf_block+pf_count > PF.capacity)) {
 914                end_request(0);
 915                goto repeat;
 916        }
 917
 918        pf_cmd = CURRENT->cmd;
 919        pf_buf = CURRENT->buffer;
 920        pf_retries = 0;
 921
 922        pf_busy = 1;
 923        if (pf_cmd == READ) pi_do_claimed(PI,do_pf_read);
 924        else if (pf_cmd == WRITE) pi_do_claimed(PI,do_pf_write);
 925        else {  pf_busy = 0;
 926                end_request(0);
 927                goto repeat;
 928        }
 929}
 930
 931static void pf_next_buf( int unit )
 932
 933{       unsigned long   saved_flags;
 934
 935        spin_lock_irqsave(&io_request_lock,saved_flags);
 936        end_request(1);
 937        if (!pf_run) { spin_unlock_irqrestore(&io_request_lock,saved_flags);
 938                       return; 
 939        }
 940        
 941/* paranoia */
 942
 943        if (QUEUE_EMPTY ||
 944            (CURRENT->cmd != pf_cmd) ||
 945            (DEVICE_NR(CURRENT->rq_dev) != pf_unit) ||
 946            (CURRENT->rq_status == RQ_INACTIVE) ||
 947            (CURRENT->sector != pf_block)) 
 948                printk("%s: OUCH: request list changed unexpectedly\n",
 949                        PF.name);
 950
 951        pf_count = CURRENT->current_nr_sectors;
 952        pf_buf = CURRENT->buffer;
 953        spin_unlock_irqrestore(&io_request_lock,saved_flags);
 954}
 955
 956static void do_pf_read( void )
 957
 958/* detach from the calling context - in case the spinlock is held */
 959
 960{       ps_set_intr(do_pf_read_start,0,0,nice);
 961}
 962
 963static void do_pf_read_start( void )
 964
 965{       int     unit = pf_unit;
 966        unsigned long   saved_flags;
 967
 968        pf_busy = 1;
 969
 970        if (pf_start(unit,ATAPI_READ_10,pf_block,pf_run)) {
 971                pi_disconnect(PI);
 972                if (pf_retries < PF_MAX_RETRIES) {
 973                        pf_retries++;
 974                        pi_do_claimed(PI,do_pf_read_start);
 975                        return;
 976                }
 977                spin_lock_irqsave(&io_request_lock,saved_flags);
 978                end_request(0);
 979                pf_busy = 0;
 980                do_pf_request(NULL);
 981                spin_unlock_irqrestore(&io_request_lock,saved_flags);
 982                return;
 983        }
 984        pf_mask = STAT_DRQ;
 985        ps_set_intr(do_pf_read_drq,pf_ready,PF_TMO,nice);
 986}
 987
 988static void do_pf_read_drq( void )
 989
 990{       int     unit = pf_unit;
 991        unsigned long   saved_flags;
 992        
 993        while (1) {
 994            if (pf_wait(unit,STAT_BUSY,STAT_DRQ|STAT_ERR,
 995                        "read block","completion") & STAT_ERR) {
 996                pi_disconnect(PI);
 997                if (pf_retries < PF_MAX_RETRIES) {
 998                        pf_req_sense(unit,0);
 999                        pf_retries++;
1000                        pi_do_claimed(PI,do_pf_read_start);
1001                        return;
1002                }
1003                spin_lock_irqsave(&io_request_lock,saved_flags);
1004                end_request(0);
1005                pf_busy = 0;
1006                do_pf_request(NULL);
1007                spin_unlock_irqrestore(&io_request_lock,saved_flags);
1008                return;
1009            }
1010            pi_read_block(PI,pf_buf,512);
1011            pf_count--; pf_run--;
1012            pf_buf += 512;
1013            pf_block++;
1014            if (!pf_run) break;
1015            if (!pf_count) pf_next_buf(unit);
1016        }
1017        pi_disconnect(PI);
1018        spin_lock_irqsave(&io_request_lock,saved_flags); 
1019        end_request(1);
1020        pf_busy = 0;
1021        do_pf_request(NULL);
1022        spin_unlock_irqrestore(&io_request_lock,saved_flags);
1023}
1024
1025static void do_pf_write( void )
1026
1027{       ps_set_intr(do_pf_write_start,0,0,nice);
1028}
1029
1030static void do_pf_write_start( void )
1031
1032{       int     unit = pf_unit;
1033        unsigned long   saved_flags;
1034
1035        pf_busy = 1;
1036
1037        if (pf_start(unit,ATAPI_WRITE_10,pf_block,pf_run)) {
1038                pi_disconnect(PI);
1039                if (pf_retries < PF_MAX_RETRIES) {
1040                        pf_retries++;
1041                        pi_do_claimed(PI,do_pf_write_start);
1042                        return;
1043                }
1044                spin_lock_irqsave(&io_request_lock,saved_flags);
1045                end_request(0);
1046                pf_busy = 0;
1047                do_pf_request(NULL);
1048                spin_unlock_irqrestore(&io_request_lock,saved_flags);
1049                return;
1050        }
1051
1052        while (1) {
1053            if (pf_wait(unit,STAT_BUSY,STAT_DRQ|STAT_ERR,
1054                        "write block","data wait") & STAT_ERR) {
1055                pi_disconnect(PI);
1056                if (pf_retries < PF_MAX_RETRIES) {
1057                        pf_retries++;
1058                        pi_do_claimed(PI,do_pf_write_start);
1059                        return;
1060                }
1061                spin_lock_irqsave(&io_request_lock,saved_flags);
1062                end_request(0);
1063                pf_busy = 0;
1064                do_pf_request(NULL);
1065                spin_unlock_irqrestore(&io_request_lock,saved_flags);
1066                return;
1067            }
1068            pi_write_block(PI,pf_buf,512);
1069            pf_count--; pf_run--;
1070            pf_buf += 512;
1071            pf_block++;
1072            if (!pf_run) break;
1073            if (!pf_count) pf_next_buf(unit);
1074        }
1075        pf_mask = 0;
1076        ps_set_intr(do_pf_write_done,pf_ready,PF_TMO,nice);
1077}
1078
1079static void do_pf_write_done( void )
1080
1081{       int     unit = pf_unit;
1082        unsigned long   saved_flags;
1083
1084        if (pf_wait(unit,STAT_BUSY,0,"write block","done") & STAT_ERR) {
1085                pi_disconnect(PI);
1086                if (pf_retries < PF_MAX_RETRIES) {
1087                        pf_retries++;
1088                        pi_do_claimed(PI,do_pf_write_start);
1089                        return;
1090                }
1091                spin_lock_irqsave(&io_request_lock,saved_flags);
1092                end_request(0);
1093                pf_busy = 0;
1094                do_pf_request(NULL);
1095                spin_unlock_irqrestore(&io_request_lock,saved_flags);
1096                return;
1097        }
1098        pi_disconnect(PI);
1099        spin_lock_irqsave(&io_request_lock,saved_flags);
1100        end_request(1);
1101        pf_busy = 0;
1102        do_pf_request(NULL);
1103        spin_unlock_irqrestore(&io_request_lock,saved_flags);
1104}
1105
1106/* end of pf.c */
1107
1108MODULE_LICENSE("GPL");
1109
lxr.linux.no kindly hosted by Redpill Linpro AS, provider of Linux consulting and operations services since 1995.