OpenCores
URL https://opencores.org/ocsvn/or1k_old/or1k_old/trunk

Subversion Repositories or1k_old

[/] [or1k_old/] [trunk/] [uclinux/] [uClinux-2.0.x/] [drivers/] [block/] [paride/] [pd.c] - Blame information for rev 1782

Details | Compare with Previous | View Log

Line No. Rev Author Line
1 199 simons
/*
2
        pd.c    (c) 1997-8  Grant R. Guenther <grant@torque.net>
3
                            Under the terms of the GNU public license.
4
 
5
 
6
        Special 2.0.34 version.
7
 
8
 
9
 
10
        This is the high-level driver for parallel port IDE hard
11
        drives based on chips supported by the paride module.
12
 
13
        By default, the driver will autoprobe for a single parallel
14
        port IDE drive, but if their individual parameters are
15
        specified, the driver can handle up to 4 drives.
16
 
17
        The behaviour of the pd driver can be altered by setting
18
        some parameters from the insmod command line.  The following
19
        parameters are adjustable:
20
 
21
            drive0      These four arguments can be arrays of
22
            drive1      1-8 integers as follows:
23
            drive2
24
            drive3      <prt>,<pro>,<uni>,<mod>,<geo>,<sby>,<dly>,<slv>
25
 
26
                        Where,
27
 
28
                <prt>   is the base of the parallel port address for
29
                        the corresponding drive.  (required)
30
 
31
                <pro>   is the protocol number for the adapter that
32
                        supports this drive.  These numbers are
33
                        logged by 'paride' when the protocol modules
34
                        are initialised.  (0 if not given)
35
 
36
                <uni>   for those adapters that support chained
37
                        devices, this is the unit selector for the
38
                        chain of devices on the given port.  It should
39
                        be zero for devices that don't support chaining.
40
                        (0 if not given)
41
 
42
                <mod>   this can be -1 to choose the best mode, or one
43
                        of the mode numbers supported by the adapter.
44
                        (-1 if not given)
45
 
46
                <geo>   this defaults to 0 to indicate that the driver
47
                        should use the CHS geometry provided by the drive
48
                        itself.  If set to 1, the driver will provide
49
                        a logical geometry with 64 heads and 32 sectors
50
                        per track, to be consistent with most SCSI
51
                        drivers.  (0 if not given)
52
 
53
                <sby>   set this to zero to disable the power saving
54
                        standby mode, if needed.  (1 if not given)
55
 
56
                <dly>   some parallel ports require the driver to
57
                        go more slowly.  -1 sets a default value that
58
                        should work with the chosen protocol.  Otherwise,
59
                        set this to a small integer, the larger it is
60
                        the slower the port i/o.  In some cases, setting
61
                        this to zero will speed up the device. (default -1)
62
 
63
                <slv>   IDE disks can be jumpered to master or slave.
64
                        Set this to 0 to choose the master drive, 1 to
65
                        choose the slave, -1 (the default) to choose the
66
                        first drive found.
67
 
68
 
69
            major       You may use this parameter to overide the
70
                        default major number (45) that this driver
71
                        will use.  Be sure to change the device
72
                        name as well.
73
 
74
            name        This parameter is a character string that
75
                        contains the name the kernel will use for this
76
                        device (in /proc output, for instance).
77
                        (default "pd")
78
 
79
            cluster     The driver will attempt to aggregate requests
80
                        for adjacent blocks into larger multi-block
81
                        clusters.  The maximum cluster size (in 512
82
                        byte sectors) is set with this parameter.
83
                        (default 64)
84
 
85
            verbose     This parameter controls the amount of logging
86
                        that is done while the driver probes for
87
                        devices.  Set it to 0 for a quiet load, or to 1
88
                        see all the progress messages.  (default 0)
89
 
90
            nice        This parameter controls the driver's use of
91
                        idle CPU time, at the expense of some speed.
92
 
93
        If this driver is built into the kernel, you can use kernel
94
        the following command line parameters, with the same values
95
        as the corresponding module parameters listed above:
96
 
97
            pd.drive0
98
            pd.drive1
99
            pd.drive2
100
            pd.drive3
101
            pd.cluster
102
            pd.nice
103
 
104
        In addition, you can use the parameter pd.disable to disable
105
        the driver entirely.
106
 
107
*/
108
 
109
/* Changes:
110
 
111
        1.01    GRG 1997.01.24  Restored pd_reset()
112
                                Added eject ioctl
113
        1.02    GRG 1998.05.06  SMP spinlock changes,
114
                                Added slave support
115
        1.03    GRG 1998.06.16  Eliminate an Ugh.
116
        1.04s   GRG 1998.09.24  Added jumbo support
117
                                Use HZ in loop timings, extra debugging
118
 
119
*/
120
 
121
#define PD_VERSION      "1.04s"
122
#define PD_MAJOR        45
123
#define PD_NAME         "pd"
124
#define PD_UNITS        4
125
 
126
/* Here are things one can override from the insmod command.
127
   Most are autoprobed by paride unless set here.  Verbose is off
128
   by default.
129
 
130
*/
131
 
132
static int      verbose = 0;
133
static int      major = PD_MAJOR;
134
static char     *name = PD_NAME;
135
static int      cluster = 64;
136
static int      nice = 0;
137
static int      disable = 0;
138
 
139
static int drive0[8] = {0,0,0,-1,0,1,-1,-1};
140
static int drive1[8] = {0,0,0,-1,0,1,-1,-1};
141
static int drive2[8] = {0,0,0,-1,0,1,-1,-1};
142
static int drive3[8] = {0,0,0,-1,0,1,-1,-1};
143
 
144
static int (*drives[4])[8] = {&drive0,&drive1,&drive2,&drive3};
145
static int pd_drive_count;
146
 
147
#define D_PRT   0
148
#define D_PRO   1
149
#define D_UNI   2
150
#define D_MOD   3
151
#define D_GEO   4
152
#define D_SBY   5
153
#define D_DLY   6
154
#define D_SLV   7
155
 
156
#define DU              (*drives[unit])
157
 
158
/* end of parameters */
159
 
160
#include <linux/module.h>
161
#include <linux/errno.h>
162
#include <linux/fs.h>
163
#include <linux/kernel.h>
164
#include <linux/delay.h>
165
#include <linux/genhd.h>
166
#include <linux/hdreg.h>
167
#include <linux/cdrom.h>        /* for the eject ioctl */
168
 
169
#include "spinlock.h"
170
#include <asm/segment.h>
171
 
172
#ifndef MODULE
173
 
174
#include "setup.h"
175
 
176
static STT pd_stt[7] = {{"drive0",8,drive0},
177
                        {"drive1",8,drive1},
178
                        {"drive2",8,drive2},
179
                        {"drive3",8,drive3},
180
                        {"disable",1,&disable},
181
                        {"cluster",1,&cluster},
182
                        {"nice",1,&nice}};
183
 
184
void pd_setup( char *str, int *ints)
185
 
186
{       generic_setup(pd_stt,7,str);
187
}
188
 
189
#endif
190
 
191
#include "paride.h"
192
 
193
#define PD_BITS    4
194
 
195
/* set up defines for blk.h,  why don't all drivers do it this way ? */
196
 
197
#define MAJOR_NR   major
198
#define DEVICE_NAME "PD"
199
#define DEVICE_REQUEST do_pd_request
200
#define DEVICE_NR(device) (MINOR(device)>>PD_BITS)
201
#define DEVICE_ON(device)
202
#define DEVICE_OFF(device)
203
 
204
#include <linux/blk.h>
205
 
206
#include "pseudo.h"
207
 
208
#define PD_PARTNS       (1<<PD_BITS)
209
#define PD_DEVS         PD_PARTNS*PD_UNITS
210
 
211
/* numbers for "SCSI" geometry */
212
 
213
#define PD_LOG_HEADS    64
214
#define PD_LOG_SECTS    32
215
 
216
#define PD_ID_OFF       54
217
#define PD_ID_LEN       14
218
 
219
#define PD_MAX_RETRIES  5
220
#define PD_TMO          800             /* interrupt timeout in jiffies */
221
#define PD_SPIN_DEL     50              /* spin delay in micro-seconds  */
222
 
223
#define PD_SPIN         (1000000*PD_TMO)/(HZ*PD_SPIN_DEL)
224
 
225
#define STAT_ERR        0x00001
226
#define STAT_INDEX      0x00002
227
#define STAT_ECC        0x00004
228
#define STAT_DRQ        0x00008
229
#define STAT_SEEK       0x00010
230
#define STAT_WRERR      0x00020
231
#define STAT_READY      0x00040
232
#define STAT_BUSY       0x00080
233
 
234
#define ERR_AMNF        0x00100
235
#define ERR_TK0NF       0x00200
236
#define ERR_ABRT        0x00400
237
#define ERR_MCR         0x00800
238
#define ERR_IDNF        0x01000
239
#define ERR_MC          0x02000
240
#define ERR_UNC         0x04000
241
#define ERR_TMO         0x10000
242
 
243
#define IDE_READ                0x20
244
#define IDE_WRITE               0x30
245
#define IDE_READ_VRFY           0x40
246
#define IDE_INIT_DEV_PARMS      0x91
247
#define IDE_STANDBY             0x96
248
#define IDE_ACKCHANGE           0xdb
249
#define IDE_DOORLOCK            0xde
250
#define IDE_DOORUNLOCK          0xdf
251
#define IDE_IDENTIFY            0xec
252
#define IDE_EJECT               0xed
253
 
254
int pd_init(void);
255
void pd_setup(char * str, int * ints);
256
#ifdef MODULE
257
void cleanup_module( void );
258
#endif
259
static void pd_geninit(struct gendisk *ignored);
260
static int pd_open(struct inode *inode, struct file *file);
261
static void do_pd_request(void);
262
static int pd_ioctl(struct inode *inode,struct file *file,
263
                    unsigned int cmd, unsigned long arg);
264
static void pd_release (struct inode *inode, struct file *file);
265
static int pd_revalidate(kdev_t dev);
266
static int pd_detect(void);
267
static void do_pd_read(void);
268
static void do_pd_read_start(void);
269
static void do_pd_write(void);
270
static void do_pd_write_start(void);
271
static void do_pd_read_drq( void );
272
static void do_pd_write_done( void );
273
 
274
static int pd_identify (int unit);
275
static void pd_media_check(int unit);
276
static void pd_doorlock(int unit, int func);
277
static int pd_check_media(kdev_t dev);
278
static void pd_eject( int unit);
279
 
280
static struct hd_struct pd_hd[PD_DEVS];
281
static int pd_sizes[PD_DEVS];
282
static int pd_blocksizes[PD_DEVS];
283
 
284
#define PD_NAMELEN      8
285
 
286
struct pd_unit {
287
        struct pi_adapter pia;          /* interface to paride layer */
288
        struct pi_adapter *pi;
289
        int access;                     /* count of active opens ... */
290
        int capacity;                   /* Size of this volume in sectors */
291
        int heads;                      /* physical geometry */
292
        int sectors;
293
        int cylinders;
294
        int drive;                      /* master=0 slave=1 */
295
        int changed;                    /* Have we seen a disk change ? */
296
        int removable;                  /* removable media device  ?  */
297
        int standby;
298
        int alt_geom;
299
        int present;
300
        char name[PD_NAMELEN];          /* pda, pdb, etc ... */
301
        };
302
 
303
struct pd_unit pd[PD_UNITS];
304
 
305
/*  'unit' must be defined in all functions - either as a local or a param */
306
 
307
#define PD pd[unit]
308
#define PI PD.pi
309
 
310
static int pd_valid = 1;                /* serialise partition checks */
311
static char pd_scratch[512];            /* scratch block buffer */
312
 
313
/* the variables below are used mainly in the I/O request engine, which
314
   processes only one request at a time.
315
*/
316
 
317
static int pd_retries = 0;              /* i/o error retry count */
318
static int pd_busy = 0;                 /* request being processed ? */
319
static int pd_block;                    /* address of next requested block */
320
static int pd_count;                    /* number of blocks still to do */
321
static int pd_run;                      /* sectors in current cluster */
322
static int pd_cmd;                      /* current command READ/WRITE */
323
static int pd_unit;                     /* unit of current request */
324
static int pd_dev;                      /* minor of current request */
325
static int pd_poffs;                    /* partition offset of current minor */
326
static char * pd_buf;                   /* buffer for request in progress */
327
 
328
static struct wait_queue *pd_wait_open = NULL;
329
 
330
static char *pd_errs[17] = { "ERR","INDEX","ECC","DRQ","SEEK","WRERR",
331
                             "READY","BUSY","AMNF","TK0NF","ABRT","MCR",
332
                             "IDNF","MC","UNC","???","TMO"};
333
 
334
/* kernel glue structures */
335
 
336
static struct gendisk pd_gendisk = {
337
        PD_MAJOR,       /* Major number */
338
        PD_NAME,        /* Major name */
339
        PD_BITS,        /* Bits to shift to get real from partition */
340
        PD_PARTNS,      /* Number of partitions per real */
341
        PD_UNITS,       /* maximum number of real */
342
        pd_geninit,     /* init function */
343
        pd_hd,          /* hd struct */
344
        pd_sizes,       /* block sizes */
345
        0,              /* number */
346
        NULL,           /* internal */
347
        NULL            /* next */
348
};
349
 
350
static struct file_operations pd_fops = {
351
        NULL,                   /* lseek - default */
352
        block_read,             /* read - general block-dev read */
353
        block_write,            /* write - general block-dev write */
354
        NULL,                   /* readdir - bad */
355
        NULL,                   /* select */
356
        pd_ioctl,               /* ioctl */
357
        NULL,                   /* mmap */
358
        pd_open,                /* open */
359
        pd_release,             /* release */
360
        block_fsync,            /* fsync */
361
        NULL,                   /* fasync */
362
        pd_check_media,         /* media change ? */
363
        pd_revalidate           /* revalidate new media */
364
};
365
 
366
void pd_init_units( void )
367
 
368
{       int     unit, j;
369
 
370
        pd_drive_count = 0;
371
        for (unit=0;unit<PD_UNITS;unit++) {
372
                PD.pi = & PD.pia;
373
                PD.access = 0;
374
                PD.changed = 1;
375
                PD.capacity = 0;
376
                PD.drive = DU[D_SLV];
377
                PD.present = 0;
378
                j = 0;
379
                while ((j < PD_NAMELEN-2) && (PD.name[j]=name[j])) j++;
380
                PD.name[j++] = 'a' + unit;
381
                PD.name[j] = 0;
382
                PD.alt_geom = DU[D_GEO];
383
                PD.standby = DU[D_SBY];
384
                if (DU[D_PRT]) pd_drive_count++;
385
        }
386
}
387
 
388
int pd_init (void)
389
 
390
{       int i;
391
 
392
        if (disable) return -1;
393
 
394
        if (register_blkdev(MAJOR_NR,name,&pd_fops)) {
395
                printk("%s: unable to get major number %d\n",
396
                        name,major);
397
                return -1;
398
        }
399
        blk_dev[MAJOR_NR].request_fn = DEVICE_REQUEST;
400
        read_ahead[MAJOR_NR] = 8;       /* 8 sector (4kB) read ahead */
401
 
402
        pd_gendisk.major = major;
403
        pd_gendisk.major_name = name;
404
        pd_gendisk.next = gendisk_head;
405
        gendisk_head = &pd_gendisk;
406
 
407
        for(i=0;i<PD_DEVS;i++) pd_blocksizes[i] = 1024;
408
        blksize_size[MAJOR_NR] = pd_blocksizes;
409
 
410
        printk("%s: %s version %s, major %d, cluster %d, nice %d\n",
411
                name,name,PD_VERSION,major,cluster,nice);
412
 
413
        return 0;
414
}
415
 
416
static void pd_geninit (struct gendisk *ignored)
417
 
418
{       pd_init_units();
419
        pd_gendisk.nr_real = pd_detect();
420
 
421
#ifdef MODULE
422
        if (!pd_gendisk.nr_real) cleanup_module();
423
#endif
424
 
425
}
426
 
427
static int pd_open (struct inode *inode, struct file *file)
428
 
429
{       int unit = DEVICE_NR(inode->i_rdev);
430
 
431
        if ((unit >= PD_UNITS) || (!PD.present)) return -ENODEV;
432
 
433
        MOD_INC_USE_COUNT;
434
 
435
        while (!pd_valid) sleep_on(&pd_wait_open);
436
 
437
        PD.access++;
438
 
439
        if (PD.removable) {
440
                pd_media_check(unit);
441
                pd_doorlock(unit,IDE_DOORLOCK);
442
        }
443
        return 0;
444
}
445
 
446
static int pd_ioctl(struct inode *inode,struct file *file,
447
                    unsigned int cmd, unsigned long arg)
448
 
449
{       struct hd_geometry *geo = (struct hd_geometry *) arg;
450
        int dev, err, unit;
451
 
452
        if ((!inode) || (!inode->i_rdev)) return -EINVAL;
453
        dev = MINOR(inode->i_rdev);
454
        unit = DEVICE_NR(inode->i_rdev);
455
        if (dev >= PD_DEVS) return -EINVAL;
456
        if (!PD.present) return -ENODEV;
457
 
458
        switch (cmd) {
459
            case CDROMEJECT:
460
                if (PD.access == 1) pd_eject(unit);
461
                return 0;
462
            case HDIO_GETGEO:
463
                if (!geo) return -EINVAL;
464
                err = verify_area(VERIFY_WRITE,geo,sizeof(*geo));
465
                if (err) return err;
466
 
467
                if (PD.alt_geom) {
468
                    put_user(PD.capacity/(PD_LOG_HEADS*PD_LOG_SECTS),
469
                                (short *) &geo->cylinders);
470
                    put_user(PD_LOG_HEADS, (char *) &geo->heads);
471
                    put_user(PD_LOG_SECTS, (char *) &geo->sectors);
472
                } else {
473
                    put_user(PD.cylinders, (short *) &geo->cylinders);
474
                    put_user(PD.heads, (char *) &geo->heads);
475
                    put_user(PD.sectors, (char *) &geo->sectors);
476
                }
477
                put_user(pd_hd[dev].start_sect,(long *)&geo->start);
478
                return 0;
479
            case BLKRASET:
480
                if(!suser()) return -EACCES;
481
                if(!(inode->i_rdev)) return -EINVAL;
482
                if(arg > 0xff) return -EINVAL;
483
                read_ahead[MAJOR(inode->i_rdev)] = arg;
484
                return 0;
485
            case BLKRAGET:
486
                if (!arg) return -EINVAL;
487
                err = verify_area(VERIFY_WRITE,(long *) arg,sizeof(long));
488
                if (err) return (err);
489
                put_user(read_ahead[MAJOR(inode->i_rdev)],(long *) arg);
490
                return (0);
491
            case BLKGETSIZE:
492
                if (!arg) return -EINVAL;
493
                err = verify_area(VERIFY_WRITE,(long *) arg,sizeof(long));
494
                if (err) return (err);
495
                put_user(pd_hd[dev].nr_sects,(long *) arg);
496
                return (0);
497
            case BLKFLSBUF:
498
                if(!suser())  return -EACCES;
499
                if(!(inode->i_rdev)) return -EINVAL;
500
                fsync_dev(inode->i_rdev);
501
                invalidate_buffers(inode->i_rdev);
502
                return 0;
503
            case BLKRRPART:
504
                if (!suser()) return -EACCES;
505
                return pd_revalidate(inode->i_rdev);
506
            RO_IOCTLS(inode->i_rdev,arg);
507
            default:
508
                return -EINVAL;
509
        }
510
}
511
 
512
static void pd_release (struct inode *inode, struct file *file)
513
 
514
{       kdev_t devp;
515
        int     unit;
516
 
517
        devp = inode->i_rdev;
518
        unit = DEVICE_NR(devp);
519
 
520
        if ((unit >= PD_UNITS) || (PD.access <= 0))
521
                return;
522
 
523
        PD.access--;
524
 
525
        if (!PD.access)  {
526
                fsync_dev(devp);
527
 
528
                invalidate_inodes(devp);
529
 
530
                invalidate_buffers(devp);
531
                if (PD.removable) pd_doorlock(unit,IDE_DOORUNLOCK);
532
        }
533
 
534
        MOD_DEC_USE_COUNT;
535
 
536
}
537
 
538
static int pd_check_media( kdev_t dev)
539
 
540
{       int r, unit;
541
 
542
        unit = DEVICE_NR(dev);
543
        if ((unit >= PD_UNITS) || (!PD.present)) return -ENODEV;
544
        if (!PD.removable) return 0;
545
        pd_media_check(unit);
546
        r = PD.changed;
547
        PD.changed = 0;
548
        return r;
549
}
550
 
551
static int pd_revalidate(kdev_t dev)
552
 
553
{       int p, unit, minor;
554
        long flags;
555
        kdev_t devp;
556
 
557
        unit = DEVICE_NR(dev);
558
        if ((unit >= PD_UNITS) || (!PD.present)) return -ENODEV;
559
 
560
        save_flags(flags);
561
        cli();
562
        if (PD.access > 1) {
563
                restore_flags(flags);
564
                return -EBUSY;
565
        }
566
        pd_valid = 0;
567
        restore_flags(flags);
568
 
569
        for (p=(PD_PARTNS-1);p>=0;p--) {
570
                minor = p + unit*PD_PARTNS;
571
                devp = MKDEV(MAJOR_NR, minor);
572
                fsync_dev(devp);
573
 
574
                invalidate_inodes(devp);
575
 
576
                invalidate_buffers(devp);
577
                pd_hd[minor].start_sect = 0;
578
                pd_hd[minor].nr_sects = 0;
579
        }
580
 
581
        pd_identify(unit);
582
        resetup_one_dev(&pd_gendisk,unit);
583
 
584
        pd_valid = 1;
585
        wake_up(&pd_wait_open);
586
 
587
        return 0;
588
}
589
 
590
#ifdef MODULE
591
 
592
/* Glue for modules ... */
593
 
594
void    cleanup_module(void);
595
 
596
int     init_module(void)
597
 
598
{       int     err, unit;
599
 
600
#ifdef PARIDE_JUMBO
601
       { extern paride_init();
602
         paride_init();
603
       }
604
#endif
605
 
606
        err = pd_init();
607
        if (err) return err;
608
 
609
        pd_geninit(&pd_gendisk);
610
 
611
        if (!pd_gendisk.nr_real)  return -1;
612
 
613
        pd_valid = 0;
614
        for (unit=0;unit<PD_UNITS;unit++)
615
          if (PD.present) resetup_one_dev(&pd_gendisk,unit);
616
        pd_valid = 1;
617
 
618
        return 0;
619
}
620
 
621
void    cleanup_module(void)
622
 
623
{       struct gendisk **gdp;
624
        int unit;
625
 
626
        unregister_blkdev(MAJOR_NR,name);
627
 
628
        for(gdp=&gendisk_head;*gdp;gdp=&((*gdp)->next))
629
                if (*gdp == &pd_gendisk) break;
630
        if (*gdp) *gdp = (*gdp)->next;
631
 
632
        for (unit=0;unit<PD_UNITS;unit++)
633
           if (PD.present) pi_release(PI);
634
}
635
 
636
#endif
637
 
638
#define WR(c,r,v)       pi_write_regr(PI,c,r,v)
639
#define RR(c,r)         (pi_read_regr(PI,c,r))
640
 
641
#define DRIVE           (0xa0+0x10*PD.drive)
642
 
643
/*  ide command interface */
644
 
645
static void pd_print_error( int unit, char * msg, int status )
646
 
647
{       int     i;
648
 
649
        printk("%s: %s: status = 0x%x =",PD.name,msg,status);
650
        for(i=0;i<18;i++) if (status & (1<<i)) printk(" %s",pd_errs[i]);
651
        printk("\n");
652
}
653
 
654
static void pd_reset( int unit )    /* called only for MASTER drive */
655
 
656
{       pi_connect(PI);
657
        WR(1,6,4);
658
        udelay(50);
659
        WR(1,6,0);
660
        pi_disconnect(PI);
661
        udelay(250);
662
}
663
 
664
#define DBMSG(msg)    ((verbose>1)?(msg):NULL)
665
 
666
static int pd_wait_for( int unit, int w, char * msg )    /* polled wait */
667
 
668
{       int     k, r, e;
669
 
670
        k=0;
671
        while(k < PD_SPIN) {
672
            r = RR(1,6);
673
            k++;
674
            if (((r & w) == w) && !(r & STAT_BUSY)) break;
675
            udelay(PD_SPIN_DEL);
676
        }
677
        e = (RR(0,1)<<8) + RR(0,7);
678
        if (k >= PD_SPIN)  e |= ERR_TMO;
679
        if ((e & (STAT_ERR|ERR_TMO)) && (msg != NULL))
680
                pd_print_error(unit,msg,e);
681
        return e;
682
}
683
 
684
static void pd_send_command( int unit, int n, int s, int h,
685
                             int c0, int c1, int func )
686
 
687
{
688
        WR(0,6,DRIVE+h);
689
        WR(0,1,0);                /* the IDE task file */
690
        WR(0,2,n);
691
        WR(0,3,s);
692
        WR(0,4,c0);
693
        WR(0,5,c1);
694
        WR(0,7,func);
695
 
696
        udelay(1);
697
}
698
 
699
static void pd_ide_command( int unit, int func, int block, int count )
700
 
701
/* Don't use this call if the capacity is zero. */
702
 
703
{       int c1, c0, h, s;
704
 
705
        s  = ( block % PD.sectors) + 1;
706
        h  = ( block / PD.sectors) % PD.heads;
707
        c0 = ( block / (PD.sectors*PD.heads)) % 256;
708
        c1 = ( block / (PD.sectors*PD.heads*256));
709
 
710
        pd_send_command(unit,count,s,h,c0,c1,func);
711
}
712
 
713
/* According to the ATA standard, the default CHS geometry should be
714
   available following a reset.  Some Western Digital drives come up
715
   in a mode where only LBA addresses are accepted until the device
716
   parameters are initialised.
717
*/
718
 
719
static void pd_init_dev_parms( int unit )
720
 
721
{       pi_connect(PI);
722
        pd_wait_for(unit,0,DBMSG("before init_dev_parms"));
723
        pd_send_command(unit,PD.sectors,0,PD.heads-1,0,0,IDE_INIT_DEV_PARMS);
724
        udelay(300);
725
        pd_wait_for(unit,0,"Initialise device parameters");
726
        pi_disconnect(PI);
727
}
728
 
729
static void pd_doorlock( int unit, int func )
730
 
731
{       pi_connect(PI);
732
        if (pd_wait_for(unit,STAT_READY,"Lock") & STAT_ERR) {
733
                pi_disconnect(PI);
734
                return;
735
        }
736
        pd_send_command(unit,1,0,0,0,0,func);
737
        pd_wait_for(unit,STAT_READY,"Lock done");
738
        pi_disconnect(PI);
739
}
740
 
741
static void pd_eject( int unit )
742
 
743
{       pi_connect(PI);
744
        pd_wait_for(unit,0,DBMSG("before unlock on eject"));
745
        pd_send_command(unit,1,0,0,0,0,IDE_DOORUNLOCK);
746
        pd_wait_for(unit,0,DBMSG("after unlock on eject"));
747
        pd_wait_for(unit,0,DBMSG("before eject"));
748
        pd_send_command(unit,0,0,0,0,0,IDE_EJECT);
749
        pd_wait_for(unit,0,DBMSG("after eject"));
750
        pi_disconnect(PI);
751
}
752
 
753
static void pd_media_check( int unit )
754
 
755
{       int     r;
756
 
757
        pi_connect(PI);
758
        r = pd_wait_for(unit,STAT_READY,DBMSG("before media_check"));
759
        if (!(r & STAT_ERR)) {
760
                pd_send_command(unit,1,1,0,0,0,IDE_READ_VRFY);
761
                r = pd_wait_for(unit,STAT_READY,DBMSG("RDY after READ_VRFY"));
762
        } else PD.changed = 1;   /* say changed if other error */
763
        if (r & ERR_MC) {
764
                PD.changed = 1;
765
                pd_send_command(unit,1,0,0,0,0,IDE_ACKCHANGE);
766
                pd_wait_for(unit,STAT_READY,DBMSG("RDY after ACKCHANGE"));
767
                pd_send_command(unit,1,1,0,0,0,IDE_READ_VRFY);
768
                r = pd_wait_for(unit,STAT_READY,DBMSG("RDY after VRFY"));
769
        }
770
        pi_disconnect(PI);
771
 
772
}
773
 
774
static void pd_standby_off( int unit )
775
 
776
{       pi_connect(PI);
777
        pd_wait_for(unit,0,DBMSG("before STANDBY"));
778
        pd_send_command(unit,0,0,0,0,0,IDE_STANDBY);
779
        pd_wait_for(unit,0,DBMSG("after STANDBY"));
780
        pi_disconnect(PI);
781
}
782
 
783
#define  word_val(n) ((pd_scratch[2*n]&0xff)+256*(pd_scratch[2*n+1]&0xff))
784
 
785
static int pd_identify( int unit )
786
 
787
{       int     j;
788
        char id[PD_ID_LEN+1];
789
 
790
/* WARNING:  here there may be dragons.  reset() applies to both drives,
791
   but we call it only on probing the MASTER. This should allow most
792
   common configurations to work, but be warned that a reset can clear
793
   settings on the SLAVE drive.
794
*/
795
 
796
        if (PD.drive == 0) pd_reset(unit);
797
 
798
        pi_connect(PI);
799
        WR(0,6,DRIVE);
800
        pd_wait_for(unit,0,DBMSG("before IDENT"));
801
        pd_send_command(unit,1,0,0,0,0,IDE_IDENTIFY);
802
 
803
        if (pd_wait_for(unit,STAT_DRQ,DBMSG("IDENT DRQ")) & STAT_ERR) {
804
                pi_disconnect(PI);
805
                return 0;
806
        }
807
        pi_read_block(PI,pd_scratch,512);
808
        pi_disconnect(PI);
809
        PD.sectors = word_val(6);
810
        PD.heads = word_val(3);
811
        PD.cylinders  = word_val(1);
812
        PD.capacity = PD.sectors*PD.heads*PD.cylinders;
813
 
814
        for(j=0;j<PD_ID_LEN;j++) id[j^1] = pd_scratch[j+PD_ID_OFF];
815
        j = PD_ID_LEN-1;
816
        while ((j >= 0) && (id[j] <= 0x20)) j--;
817
        j++; id[j] = 0;
818
 
819
        PD.removable = (word_val(0) & 0x80);
820
 
821
        printk("%s: %s, %s, %d blocks [%dM], (%d/%d/%d), %s media\n",
822
                    PD.name,id,
823
                    PD.drive?"slave":"master",
824
                    PD.capacity,PD.capacity/2048,
825
                    PD.cylinders,PD.heads,PD.sectors,
826
                    PD.removable?"removable":"fixed");
827
 
828
        if (PD.capacity) pd_init_dev_parms(unit);
829
        if (!PD.standby) pd_standby_off(unit);
830
 
831
        pd_hd[unit<<PD_BITS].nr_sects = PD.capacity;
832
        pd_hd[unit<<PD_BITS].start_sect = 0;
833
 
834
        return 1;
835
}
836
 
837
static int pd_probe_drive( int unit )
838
 
839
{       if (PD.drive == -1) {
840
          for (PD.drive=0;PD.drive<=1;PD.drive++)
841
             if (pd_identify(unit)) return 1;
842
          return 0;
843
          }
844
        else return pd_identify(unit);
845
}
846
 
847
static int pd_detect( void )
848
 
849
{       int     k, unit;
850
 
851
        k = 0;
852
        if (pd_drive_count == 0) {  /* nothing spec'd - so autoprobe for 1 */
853
            unit = 0;
854
            if (pi_init(PI,1,-1,-1,-1,-1,-1,pd_scratch,
855
                     PI_PD,verbose,PD.name)) {
856
                if (pd_probe_drive(unit)) {
857
                        PD.present = 1;
858
                        k = 1;
859
                } else pi_release(PI);
860
            }
861
 
862
        } else for (unit=0;unit<PD_UNITS;unit++) if (DU[D_PRT])
863
            if (pi_init(PI,0,DU[D_PRT],DU[D_MOD],DU[D_UNI],
864
                        DU[D_PRO],DU[D_DLY],pd_scratch,
865
                        PI_PD,verbose,PD.name)) {
866
                if (pd_probe_drive(unit)) {
867
                        PD.present = 1;
868
                        k = unit+1;
869
                } else pi_release(PI);
870
            }
871
 
872
/* We lie about the number of drives found, as the generic partition
873
   scanner assumes that the drives are numbered sequentially from 0.
874
   This can result in some bogus error messages if non-sequential
875
   drive numbers are used.
876
*/
877
 
878
        if (k) return k;
879
 
880
        printk("%s: no valid drive found\n",name);
881
        return 0;
882
}
883
 
884
/* The i/o request engine */
885
 
886
static int pd_ready( void )
887
 
888
{       int unit = pd_unit;
889
 
890
        return (!(RR(1,6) & STAT_BUSY)) ;
891
}
892
 
893
static void do_pd_request (void)
894
 
895
{       struct buffer_head * bh;
896
        struct request * req;
897
        int     unit;
898
 
899
        if (pd_busy) return;
900
repeat:
901
        if ((!CURRENT) || (CURRENT->rq_status == RQ_INACTIVE)) return;
902
        INIT_REQUEST;
903
 
904
        pd_dev = MINOR(CURRENT->rq_dev);
905
        pd_unit = unit = DEVICE_NR(CURRENT->rq_dev);
906
        pd_block = CURRENT->sector;
907
        pd_count = CURRENT->nr_sectors;
908
 
909
        bh = CURRENT->bh;
910
        req = CURRENT;
911
        if (bh->b_reqnext)
912
                printk("%s: OUCH: b_reqnext != NULL\n",PD.name);
913
 
914
        if ((pd_dev >= PD_DEVS) ||
915
            ((pd_block+pd_count) > pd_hd[pd_dev].nr_sects)) {
916
                end_request(0);
917
                goto repeat;
918
        }
919
 
920
        pd_cmd = CURRENT->cmd;
921
        pd_run = pd_count;
922
        while ((pd_run <= cluster) &&
923
               (req = req->next) &&
924
               (pd_block+pd_run == req->sector) &&
925
               (pd_cmd == req->cmd) &&
926
               (pd_dev == MINOR(req->rq_dev)))
927
                        pd_run += req->nr_sectors;
928
 
929
        pd_poffs = pd_hd[pd_dev].start_sect;
930
        pd_block += pd_poffs;
931
        pd_buf = CURRENT->buffer;
932
        pd_retries = 0;
933
 
934
        pd_busy = 1;
935
        if (pd_cmd == READ) pi_do_claimed(PI,do_pd_read);
936
        else if (pd_cmd == WRITE) pi_do_claimed(PI,do_pd_write);
937
        else {  pd_busy = 0;
938
                end_request(0);
939
                goto repeat;
940
        }
941
}
942
 
943
static void pd_next_buf( int unit )
944
 
945
{       long    saved_flags;
946
 
947
        spin_lock_irqsave(&io_request_lock,saved_flags);
948
        end_request(1);
949
        if (!pd_run) {  spin_unlock_irqrestore(&io_request_lock,saved_flags);
950
                        return;
951
        }
952
 
953
/* paranoia */
954
 
955
        if ((!CURRENT) ||
956
            (CURRENT->cmd != pd_cmd) ||
957
            (MINOR(CURRENT->rq_dev) != pd_dev) ||
958
            (CURRENT->rq_status == RQ_INACTIVE) ||
959
            (CURRENT->sector+pd_poffs != pd_block))
960
                printk("%s: OUCH: request list changed unexpectedly\n",
961
                        PD.name);
962
 
963
        pd_count = CURRENT->nr_sectors;
964
        pd_buf = CURRENT->buffer;
965
        spin_unlock_irqrestore(&io_request_lock,saved_flags);
966
}
967
 
968
static void do_pd_read( void )
969
 
970
{       ps_set_intr(do_pd_read_start,0,0,nice);
971
}
972
 
973
static void do_pd_read_start( void )
974
 
975
{       int     unit = pd_unit;
976
        long    saved_flags;
977
 
978
        pd_busy = 1;
979
 
980
        pi_connect(PI);
981
        if (pd_wait_for(unit,STAT_READY,"do_pd_read") & STAT_ERR) {
982
                pi_disconnect(PI);
983
                if (pd_retries < PD_MAX_RETRIES) {
984
                        pd_retries++;
985
                        pi_do_claimed(PI,do_pd_read_start);
986
                        return;
987
                }
988
                spin_lock_irqsave(&io_request_lock,saved_flags);
989
                end_request(0);
990
                pd_busy = 0;
991
                do_pd_request();
992
                spin_unlock_irqrestore(&io_request_lock,saved_flags);
993
                return;
994
        }
995
        pd_ide_command(unit,IDE_READ,pd_block,pd_run);
996
        ps_set_intr(do_pd_read_drq,pd_ready,PD_TMO,nice);
997
}
998
 
999
static void do_pd_read_drq( void )
1000
 
1001
{       int     unit = pd_unit;
1002
        long    saved_flags;
1003
 
1004
        while (1) {
1005
            if (pd_wait_for(unit,STAT_DRQ,"do_pd_read_drq") & STAT_ERR) {
1006
                pi_disconnect(PI);
1007
                if (pd_retries < PD_MAX_RETRIES) {
1008
                        pd_retries++;
1009
                        pi_do_claimed(PI,do_pd_read_start);
1010
                        return;
1011
                }
1012
                spin_lock_irqsave(&io_request_lock,saved_flags);
1013
                end_request(0);
1014
                pd_busy = 0;
1015
                do_pd_request();
1016
                spin_unlock_irqrestore(&io_request_lock,saved_flags);
1017
                return;
1018
            }
1019
            pi_read_block(PI,pd_buf,512);
1020
            pd_count--; pd_run--;
1021
            pd_buf += 512;
1022
            pd_block++;
1023
            if (!pd_run) break;
1024
            if (!pd_count) pd_next_buf(unit);
1025
        }
1026
        pi_disconnect(PI);
1027
        spin_lock_irqsave(&io_request_lock,saved_flags);
1028
        end_request(1);
1029
        pd_busy = 0;
1030
        do_pd_request();
1031
        spin_unlock_irqrestore(&io_request_lock,saved_flags);
1032
}
1033
 
1034
static void do_pd_write( void )
1035
 
1036
{        ps_set_intr(do_pd_write_start,0,0,nice);
1037
}
1038
 
1039
static void do_pd_write_start( void )
1040
 
1041
{       int     unit = pd_unit;
1042
        long    saved_flags;
1043
 
1044
        pd_busy = 1;
1045
 
1046
        pi_connect(PI);
1047
        if (pd_wait_for(unit,STAT_READY,"do_pd_write") & STAT_ERR) {
1048
                pi_disconnect(PI);
1049
                if (pd_retries < PD_MAX_RETRIES) {
1050
                        pd_retries++;
1051
                        pi_do_claimed(PI,do_pd_write_start);
1052
                        return;
1053
                }
1054
                spin_lock_irqsave(&io_request_lock,saved_flags);
1055
                end_request(0);
1056
                pd_busy = 0;
1057
                do_pd_request();
1058
                spin_unlock_irqrestore(&io_request_lock,saved_flags);
1059
                return;
1060
        }
1061
        pd_ide_command(unit,IDE_WRITE,pd_block,pd_run);
1062
        while (1) {
1063
            if (pd_wait_for(unit,STAT_DRQ,"do_pd_write_drq") & STAT_ERR) {
1064
                pi_disconnect(PI);
1065
                if (pd_retries < PD_MAX_RETRIES) {
1066
                        pd_retries++;
1067
                        pi_do_claimed(PI,do_pd_write_start);
1068
                        return;
1069
                }
1070
                spin_lock_irqsave(&io_request_lock,saved_flags);
1071
                end_request(0);
1072
                pd_busy = 0;
1073
                do_pd_request();
1074
                spin_unlock_irqrestore(&io_request_lock,saved_flags);
1075
                return;
1076
            }
1077
            pi_write_block(PI,pd_buf,512);
1078
            pd_count--; pd_run--;
1079
            pd_buf += 512;
1080
            pd_block++;
1081
            if (!pd_run) break;
1082
            if (!pd_count) pd_next_buf(unit);
1083
        }
1084
        ps_set_intr(do_pd_write_done,pd_ready,PD_TMO,nice);
1085
}
1086
 
1087
static void do_pd_write_done( void )
1088
 
1089
{       int     unit = pd_unit;
1090
        long    saved_flags;
1091
 
1092
        if (pd_wait_for(unit,STAT_READY,"do_pd_write_done") & STAT_ERR) {
1093
                pi_disconnect(PI);
1094
                if (pd_retries < PD_MAX_RETRIES) {
1095
                        pd_retries++;
1096
                        pi_do_claimed(PI,do_pd_write_start);
1097
                        return;
1098
                }
1099
                spin_lock_irqsave(&io_request_lock,saved_flags);
1100
                end_request(0);
1101
                pd_busy = 0;
1102
                do_pd_request();
1103
                spin_unlock_irqrestore(&io_request_lock,saved_flags);
1104
                return;
1105
        }
1106
        pi_disconnect(PI);
1107
        spin_lock_irqsave(&io_request_lock,saved_flags);
1108
        end_request(1);
1109
        pd_busy = 0;
1110
        do_pd_request();
1111
        spin_unlock_irqrestore(&io_request_lock,saved_flags);
1112
}
1113
 
1114
/* end of pd.c */
1115
 

powered by: WebSVN 2.1.0

© copyright 1999-2024 OpenCores.org, equivalent to Oliscience, all rights reserved. OpenCores®, registered trademark.