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

Subversion Repositories or1k

[/] [or1k/] [trunk/] [linux/] [linux-2.4/] [drivers/] [ide/] [legacy/] [pdc4030.c] - Blame information for rev 1765

Details | Compare with Previous | View Log

Line No. Rev Author Line
1 1275 phoenix
/*  -*- linux-c -*-
2
 *  linux/drivers/ide/legacy/pdc4030.c          Version 0.90  May 27, 1999
3
 *
4
 *  Copyright (C) 1995-2002  Linus Torvalds & authors (see below)
5
 */
6
 
7
/*
8
 *  Principal Author/Maintainer:  Peter Denison <promise@pnd-pc.demon.co.uk>
9
 *
10
 *  This file provides support for the second port and cache of Promise
11
 *  IDE interfaces, e.g. DC4030VL, DC4030VL-1 and DC4030VL-2.
12
 *
13
 *  Thanks are due to Mark Lord for advice and patiently answering stupid
14
 *  questions, and all those mugs^H^H^H^Hbrave souls who've tested this,
15
 *  especially Andre Hedrick.
16
 *
17
 *  Version 0.01        Initial version, #include'd in ide.c rather than
18
 *                      compiled separately.
19
 *                      Reads use Promise commands, writes as before. Drives
20
 *                      on second channel are read-only.
21
 *  Version 0.02        Writes working on second channel, reads on both
22
 *                      channels. Writes fail under high load. Suspect
23
 *                      transfers of >127 sectors don't work.
24
 *  Version 0.03        Brought into line with ide.c version 5.27.
25
 *                      Other minor changes.
26
 *  Version 0.04        Updated for ide.c version 5.30
27
 *                      Changed initialization strategy
28
 *  Version 0.05        Kernel integration.  -ml
29
 *  Version 0.06        Ooops. Add hwgroup to direct call of ide_intr() -ml
30
 *  Version 0.07        Added support for DC4030 variants
31
 *                      Secondary interface autodetection
32
 *  Version 0.08        Renamed to pdc4030.c
33
 *  Version 0.09        Obsolete - never released - did manual write request
34
 *                      splitting before max_sectors[major][minor] available.
35
 *  Version 0.10        Updated for 2.1 series of kernels
36
 *  Version 0.11        Updated for 2.3 series of kernels
37
 *                      Autodetection code added.
38
 *
39
 *  Version 0.90        Transition to BETA code. No lost/unexpected interrupts
40
 */
41
 
42
/*
43
 * Once you've compiled it in, you'll have to also enable the interface
44
 * setup routine from the kernel command line, as in
45
 *
46
 *      'linux ide0=dc4030' or 'linux ide1=dc4030'
47
 *
48
 * It should now work as a second controller also ('ide1=dc4030') but only
49
 * if you DON'T have BIOS V4.44, which has a bug. If you have this version
50
 * and EPROM programming facilities, you need to fix 4 bytes:
51
 *      2496:   81      81
52
 *      2497:   3E      3E
53
 *      2498:   22      98      *
54
 *      2499:   06      05      *
55
 *      249A:   F0      F0
56
 *      249B:   01      01
57
 *      ...
58
 *      24A7:   81      81
59
 *      24A8:   3E      3E
60
 *      24A9:   22      98      *
61
 *      24AA:   06      05      *
62
 *      24AB:   70      70
63
 *      24AC:   01      01
64
 *
65
 * As of January 1999, Promise Technology Inc. have finally supplied me with
66
 * some technical information which has shed a glimmer of light on some of the
67
 * problems I was having, especially with writes.
68
 *
69
 * There are still potential problems with the robustness and efficiency of
70
 * this driver because I still don't understand what the card is doing with
71
 * interrupts, however, it has been stable for a while with no reports of ill
72
 * effects.
73
 */
74
 
75
#define DEBUG_READ
76
#define DEBUG_WRITE
77
#define __PROMISE_4030
78
 
79
#include <linux/module.h>
80
#include <linux/config.h>
81
#include <linux/types.h>
82
#include <linux/kernel.h>
83
#include <linux/delay.h>
84
#include <linux/timer.h>
85
#include <linux/mm.h>
86
#include <linux/ioport.h>
87
#include <linux/blkdev.h>
88
#include <linux/hdreg.h>
89
#include <linux/ide.h>
90
#include <linux/init.h>
91
 
92
#include <asm/io.h>
93
#include <asm/irq.h>
94
 
95
#include "pdc4030.h"
96
 
97
static ide_startstop_t promise_rw_disk (ide_drive_t *drive, struct request *rq, unsigned long block);
98
 
99
/*
100
 * promise_selectproc() is invoked by ide.c
101
 * in preparation for access to the specified drive.
102
 */
103
static void promise_selectproc (ide_drive_t *drive)
104
{
105
        unsigned int number;
106
 
107
        number = (HWIF(drive)->channel << 1) + drive->select.b.unit;
108
        HWIF(drive)->OUTB(number, IDE_FEATURE_REG);
109
}
110
 
111
/*
112
 * pdc4030_cmd handles the set of vendor specific commands that are initiated
113
 * by command F0. They all have the same success/failure notification -
114
 * 'P' (=0x50) on success, 'p' (=0x70) on failure.
115
 */
116
int pdc4030_cmd(ide_drive_t *drive, u8 cmd)
117
{
118
        u32 timeout;
119
        u8 status_val;
120
 
121
        promise_selectproc(drive);      /* redundant? */
122
        HWIF(drive)->OUTB(0xF3, IDE_SECTOR_REG);
123
        HWIF(drive)->OUTB(cmd, IDE_SELECT_REG);
124
        HWIF(drive)->OUTB(PROMISE_EXTENDED_COMMAND, IDE_COMMAND_REG);
125
        timeout = HZ * 10;
126
        timeout += jiffies;
127
        do {
128
                if(time_after(jiffies, timeout)) {
129
                        return 2; /* device timed out */
130
                }
131
                /* Delays at least 10ms to give interface a chance */
132
                mdelay(10);
133
                status_val = HWIF(drive)->INB(IDE_SECTOR_REG);
134
        } while (status_val != 0x50 && status_val != 0x70);
135
 
136
        if(status_val == 0x50)
137
                return 0; /* device returned success */
138
        else
139
                return 1; /* device returned failure */
140
}
141
 
142
/*
143
 * pdc4030_identify sends a vendor-specific IDENTIFY command to the drive
144
 */
145
int pdc4030_identify(ide_drive_t *drive)
146
{
147
        return pdc4030_cmd(drive, PROMISE_IDENTIFY);
148
}
149
 
150
/*
151
 * setup_pdc4030()
152
 * Completes the setup of a Promise DC4030 controller card, once found.
153
 */
154
int __init setup_pdc4030(ide_hwif_t *hwif)
155
{
156
        ide_drive_t *drive;
157
        ide_hwif_t *hwif2;
158
        struct dc_ident ident;
159
        int i;
160
        ide_startstop_t startstop;
161
 
162
        if (!hwif) return 0;
163
 
164
        drive = &hwif->drives[0];
165
        hwif2 = &ide_hwifs[hwif->index+1];
166
        if (hwif->chipset == ide_pdc4030) /* we've already been found ! */
167
                return 1;
168
 
169
        if (hwif->INB(IDE_NSECTOR_REG) == 0xFF ||
170
            hwif->INB(IDE_SECTOR_REG) == 0xFF) {
171
                return 0;
172
        }
173
        if (IDE_CONTROL_REG)
174
                hwif->OUTB(0x08, IDE_CONTROL_REG);
175
        if (pdc4030_cmd(drive,PROMISE_GET_CONFIG)) {
176
                return 0;
177
        }
178
        if (ide_wait_stat(&startstop, drive,DATA_READY,BAD_W_STAT,WAIT_DRQ)) {
179
                printk(KERN_INFO
180
                        "%s: Failed Promise read config!\n",hwif->name);
181
                return 0;
182
        }
183
        hwif->ata_input_data(drive, &ident, SECTOR_WORDS);
184
        if (ident.id[1] != 'P' || ident.id[0] != 'T') {
185
                return 0;
186
        }
187
        printk(KERN_INFO "%s: Promise caching controller, ",hwif->name);
188
        switch(ident.type) {
189
                case 0x43:      printk("DC4030VL-2, "); break;
190
                case 0x41:      printk("DC4030VL-1, "); break;
191
                case 0x40:      printk("DC4030VL, "); break;
192
                default:
193
                        printk("unknown - type 0x%02x - please report!\n"
194
                               ,ident.type);
195
                        printk("Please e-mail the following data to "
196
                               "promise@pnd-pc.demon.co.uk along with\n"
197
                               "a description of your card and drives:\n");
198
                        for (i=0; i < 0x90; i++) {
199
                                printk("%02x ", ((unsigned char *)&ident)[i]);
200
                                if ((i & 0x0f) == 0x0f) printk("\n");
201
                        }
202
                        return 0;
203
        }
204
        printk("%dKB cache, ",(int)ident.cache_mem);
205
        switch(ident.irq) {
206
            case 0x00: hwif->irq = 14; break;
207
            case 0x01: hwif->irq = 12; break;
208
            default:   hwif->irq = 15; break;
209
        }
210
        printk("on IRQ %d\n",hwif->irq);
211
 
212
        /*
213
         * Once found and identified, we set up the next hwif in the array
214
         * (hwif2 = ide_hwifs[hwif->index+1]) with the same io ports, irq
215
         * and other settings as the main hwif. This gives us two "mated"
216
         * hwifs pointing to the Promise card.
217
         *
218
         * We also have to shift the default values for the remaining
219
         * interfaces "up by one" to make room for the second interface on the
220
         * same set of values.
221
         */
222
 
223
        hwif->chipset   = hwif2->chipset = ide_pdc4030;
224
        hwif->mate      = hwif2;
225
        hwif2->mate     = hwif;
226
        hwif2->channel  = 1;
227
        hwif->rqsize    = hwif2->rqsize = 127;
228
        hwif->addressing = hwif2->addressing = 1;
229
        hwif->selectproc = hwif2->selectproc = &promise_selectproc;
230
        hwif->serialized = hwif2->serialized = 1;
231
        /* DC4030 hosted drives need their own identify... */
232
        hwif->identify = hwif2->identify = &pdc4030_identify;
233
 
234
        /* Shift the remaining interfaces up by one */
235
        for (i=MAX_HWIFS-1 ; i > hwif->index+1 ; i--) {
236
                ide_hwif_t *h = &ide_hwifs[i];
237
 
238
#ifdef DEBUG
239
                printk(KERN_DEBUG "pdc4030: Shifting i/f %d values to i/f %d\n",i-1,i);
240
#endif /* DEBUG */
241
                ide_init_hwif_ports(&h->hw, (h-1)->io_ports[IDE_DATA_OFFSET], 0, NULL);
242
                memcpy(h->io_ports, h->hw.io_ports, sizeof(h->io_ports));
243
                h->noprobe = (h-1)->noprobe;
244
        }
245
        ide_init_hwif_ports(&hwif2->hw, hwif->io_ports[IDE_DATA_OFFSET], 0, NULL);
246
        memcpy(hwif2->io_ports, hwif->hw.io_ports, sizeof(hwif2->io_ports));
247
        hwif2->irq = hwif->irq;
248
        hwif2->hw.irq = hwif->hw.irq = hwif->irq;
249
        for (i=0; i<2 ; i++) {
250
                hwif->drives[i].io_32bit = 3;
251
                hwif2->drives[i].io_32bit = 3;
252
                hwif->drives[i].keep_settings = 1;
253
                hwif2->drives[i].keep_settings = 1;
254
                if (!ident.current_tm[i].cyl)
255
                        hwif->drives[i].noprobe = 1;
256
                if (!ident.current_tm[i+2].cyl)
257
                        hwif2->drives[i].noprobe = 1;
258
        }
259
 
260
        /* Now override the normal ide disk read/write */
261
        hwif->rw_disk = promise_rw_disk;
262
        hwif2->rw_disk = promise_rw_disk;
263
 
264
#ifndef HWIF_PROBE_CLASSIC_METHOD
265
        probe_hwif_init(&ide_hwifs[hwif->index]);
266
        probe_hwif_init(&ide_hwifs[hwif2->index]);
267
#endif /* HWIF_PROBE_CLASSIC_METHOD */
268
 
269
        return 1;
270
}
271
 
272
/*
273
 * detect_pdc4030()
274
 * Tests for the presence of a DC4030 Promise card on this interface
275
 * Returns: 1 if found, 0 if not found
276
 */
277
int __init detect_pdc4030(ide_hwif_t *hwif)
278
{
279
        ide_drive_t *drive = &hwif->drives[0];
280
 
281
        if (IDE_DATA_REG == 0) { /* Skip test for non-existent interface */
282
                return 0;
283
        }
284
        hwif->OUTB(0xF3, IDE_SECTOR_REG);
285
        hwif->OUTB(0x14, IDE_SELECT_REG);
286
        hwif->OUTB(PROMISE_EXTENDED_COMMAND, IDE_COMMAND_REG);
287
 
288
        ide_delay_50ms();
289
 
290
        if (hwif->INB(IDE_ERROR_REG) == 'P' &&
291
            hwif->INB(IDE_NSECTOR_REG) == 'T' &&
292
            hwif->INB(IDE_SECTOR_REG) == 'I') {
293
                return 1;
294
        } else {
295
                return 0;
296
        }
297
}
298
 
299
 
300
#ifndef MODULE
301
void __init ide_probe_for_pdc4030(void)
302
#else
303
int ide_probe_for_pdc4030(void)
304
#endif
305
{
306
        unsigned int    index;
307
        ide_hwif_t      *hwif;
308
 
309
        for (index = 0; index < MAX_HWIFS; index++) {
310
                hwif = &ide_hwifs[index];
311
                if (hwif->chipset == ide_unknown && detect_pdc4030(hwif)) {
312
#ifndef MODULE
313
                        setup_pdc4030(hwif);
314
#else
315
                        return setup_pdc4030(hwif);
316
#endif
317
                }
318
        }
319
#ifdef MODULE
320
        return 0;
321
#endif
322
}
323
 
324
void __init release_pdc4030(ide_hwif_t *hwif, ide_hwif_t *mate)
325
{
326
        hwif->chipset = ide_unknown;
327
        hwif->selectproc = NULL;
328
        hwif->serialized = 0;
329
        hwif->drives[0].io_32bit = 0;
330
        hwif->drives[1].io_32bit = 0;
331
        hwif->drives[0].keep_settings = 0;
332
        hwif->drives[1].keep_settings = 0;
333
        hwif->drives[0].noprobe = 0;
334
        hwif->drives[1].noprobe = 0;
335
 
336
        if (mate != NULL) {
337
                mate->chipset = ide_unknown;
338
                mate->selectproc = NULL;
339
                mate->serialized = 0;
340
                mate->drives[0].io_32bit = 0;
341
                mate->drives[1].io_32bit = 0;
342
                mate->drives[0].keep_settings = 0;
343
                mate->drives[1].keep_settings = 0;
344
                mate->drives[0].noprobe = 0;
345
                mate->drives[1].noprobe = 0;
346
        }
347
}
348
 
349
#ifndef MODULE
350
/*
351
 * init_pdc4030:
352
 *
353
 * called by ide.c when parsing command line
354
 */
355
 
356
void __init init_pdc4030(void)
357
{
358
        ide_register_driver(ide_probe_for_pdc4030);
359
}
360
 
361
#else
362
 
363
MODULE_AUTHOR("Peter Denison");
364
MODULE_DESCRIPTION("Support of Promise 4030 VLB series IDE chipsets");
365
MODULE_LICENSE("GPL");
366
 
367
int __init pdc4030_mod_init(void)
368
{
369
        if (!ide_probe_for_pdc4030())
370
                return -ENODEV;
371
        return 0;
372
}
373
module_init(pdc4030_mod_init);
374
 
375
void __init pdc4030_mod_exit(void)
376
{
377
        unsigned int    index;
378
        ide_hwif_t      *hwif;
379
 
380
        for (index = 0; index < MAX_HWIFS; index++) {
381
                hwif = &ide_hwifs[index];
382
                if (hwif->chipset == ide_pdc4030) {
383
                        ide_hwif_t *mate = &ide_hwifs[hwif->index+1];
384
                        if (mate->chipset == ide_pdc4030)
385
                                release_pdc4030(hwif, mate);
386
                        else
387
                                release_pdc4030(hwif, NULL);
388
                }
389
        }
390
}
391
module_exit(pdc4030_mod_exit);
392
#endif
393
 
394
/*
395
 * promise_read_intr() is the handler for disk read/multread interrupts
396
 */
397
static ide_startstop_t promise_read_intr (ide_drive_t *drive)
398
{
399
        int total_remaining;
400
        unsigned int sectors_left, sectors_avail, nsect;
401
        struct request *rq;
402
        ata_status_t status;
403
#ifdef CONFIG_IDE_TASKFILE_IO
404
        unsigned long flags;
405
        char *to;
406
#endif /* CONFIG_IDE_TASKFILE_IO */
407
 
408
        status.all = HWIF(drive)->INB(IDE_STATUS_REG);
409
        if (!OK_STAT(status.all, DATA_READY, BAD_R_STAT))
410
                return DRIVER(drive)->error(drive,
411
                        "promise_read_intr", status.all);
412
 
413
read_again:
414
        do {
415
                sectors_left = HWIF(drive)->INB(IDE_NSECTOR_REG);
416
                HWIF(drive)->INB(IDE_SECTOR_REG);
417
        } while (HWIF(drive)->INB(IDE_NSECTOR_REG) != sectors_left);
418
        rq = HWGROUP(drive)->rq;
419
        sectors_avail = rq->nr_sectors - sectors_left;
420
        if (!sectors_avail)
421
                goto read_again;
422
 
423
read_next:
424
        rq = HWGROUP(drive)->rq;
425
        nsect = rq->current_nr_sectors;
426
        if (nsect > sectors_avail)
427
                nsect = sectors_avail;
428
        sectors_avail -= nsect;
429
#ifdef CONFIG_IDE_TASKFILE_IO
430
        to = ide_map_buffer(rq, &flags);
431
        HWIF(drive)->ata_input_data(drive, to, nsect * SECTOR_WORDS);
432
#else /* !CONFIG_IDE_TASKFILE_IO */
433
        HWIF(drive)->ata_input_data(drive, rq->buffer, nsect * SECTOR_WORDS);
434
#endif /* CONFIG_IDE_TASKFILE_IO */
435
 
436
#ifdef DEBUG_READ
437
        printk(KERN_DEBUG "%s:  promise_read: sectors(%ld-%ld), "
438
               "buf=0x%08lx, rem=%ld\n", drive->name, rq->sector,
439
               rq->sector+nsect-1,
440
#ifdef CONFIG_IDE_TASKFILE_IO
441
                (unsigned long) to,
442
#else /* !CONFIG_IDE_TASKFILE_IO */
443
                (unsigned long) rq->buffer,
444
#endif /* CONFIG_IDE_TASKFILE_IO */
445
               rq->nr_sectors-nsect);
446
#endif /* DEBUG_READ */
447
 
448
#ifdef CONFIG_IDE_TASKFILE_IO
449
        ide_unmap_buffer(to, &flags);
450
#else /* !CONFIG_IDE_TASKFILE_IO */
451
        rq->buffer += nsect<<9;
452
#endif /* CONFIG_IDE_TASKFILE_IO */
453
        rq->sector += nsect;
454
        rq->errors = 0;
455
        rq->nr_sectors -= nsect;
456
        total_remaining = rq->nr_sectors;
457
        if ((rq->current_nr_sectors -= nsect) <= 0) {
458
                DRIVER(drive)->end_request(drive, 1);
459
        }
460
/*
461
 * Now the data has been read in, do the following:
462
 *
463
 * if there are still sectors left in the request,
464
 *   if we know there are still sectors available from the interface,
465
 *     go back and read the next bit of the request.
466
 *   else if DRQ is asserted, there are more sectors available, so
467
 *     go back and find out how many, then read them in.
468
 *   else if BUSY is asserted, we are going to get an interrupt, so
469
 *     set the handler for the interrupt and just return
470
 */
471
        if (total_remaining > 0) {
472
                if (sectors_avail)
473
                        goto read_next;
474
                status.all = HWIF(drive)->INB(IDE_STATUS_REG);
475
                if (status.b.drq)
476
                        goto read_again;
477
                if (status.b.bsy) {
478
                        if (HWGROUP(drive)->handler != NULL)
479
                                BUG();
480
                        ide_set_handler(drive,
481
                                        &promise_read_intr,
482
                                        WAIT_CMD,
483
                                        NULL);
484
#ifdef DEBUG_READ
485
                        printk(KERN_DEBUG "%s: promise_read: waiting for"
486
                               "interrupt\n", drive->name);
487
#endif /* DEBUG_READ */
488
                        return ide_started;
489
                }
490
                printk(KERN_ERR "%s: Eeek! promise_read_intr: sectors left "
491
                       "!DRQ !BUSY\n", drive->name);
492
                return DRIVER(drive)->error(drive,
493
                                "promise read intr", status.all);
494
        }
495
        return ide_stopped;
496
}
497
 
498
/*
499
 * promise_complete_pollfunc()
500
 * This is the polling function for waiting (nicely!) until drive stops
501
 * being busy. It is invoked at the end of a write, after the previous poll
502
 * has finished.
503
 *
504
 * Once not busy, the end request is called.
505
 */
506
static ide_startstop_t promise_complete_pollfunc(ide_drive_t *drive)
507
{
508
        ide_hwgroup_t *hwgroup = HWGROUP(drive);
509
        struct request *rq = hwgroup->rq;
510
        int i;
511
 
512
        if ((HWIF(drive)->INB(IDE_STATUS_REG)) & BUSY_STAT) {
513
                if (time_before(jiffies, hwgroup->poll_timeout)) {
514
                        if (hwgroup->handler != NULL)
515
                                BUG();
516
                        ide_set_handler(drive,
517
                                        &promise_complete_pollfunc,
518
                                        HZ/100,
519
                                        NULL);
520
                        return ide_started; /* continue polling... */
521
                }
522
                hwgroup->poll_timeout = 0;
523
                printk(KERN_ERR "%s: completion timeout - still busy!\n",
524
                       drive->name);
525
                return DRIVER(drive)->error(drive, "busy timeout",
526
                                HWIF(drive)->INB(IDE_STATUS_REG));
527
        }
528
 
529
        hwgroup->poll_timeout = 0;
530
#ifdef DEBUG_WRITE
531
        printk(KERN_DEBUG "%s: Write complete - end_request\n", drive->name);
532
#endif /* DEBUG_WRITE */
533
        for (i = rq->nr_sectors; i > 0; ) {
534
                i -= rq->current_nr_sectors;
535
                DRIVER(drive)->end_request(drive, 1);
536
        }
537
        return ide_stopped;
538
}
539
 
540
/*
541
 * promise_multwrite() transfers a block of up to mcount sectors of data
542
 * to a drive as part of a disk multiple-sector write operation.
543
 *
544
 * Returns 0 on success.
545
 *
546
 * Note that we may be called from two contexts - the do_rw_disk context
547
 * and IRQ context. The IRQ can happen any time after we've output the
548
 * full "mcount" number of sectors, so we must make sure we update the
549
 * state _before_ we output the final part of the data!
550
 */
551
int promise_multwrite (ide_drive_t *drive, unsigned int mcount)
552
{
553
        ide_hwgroup_t *hwgroup  = HWGROUP(drive);
554
        struct request *rq      = &hwgroup->wrq;
555
 
556
        do {
557
                char *buffer;
558
                int nsect = rq->current_nr_sectors;
559
#ifdef CONFIG_IDE_TASKFILE_IO
560
                unsigned long flags;
561
#endif /* CONFIG_IDE_TASKFILE_IO */
562
 
563
                if (nsect > mcount)
564
                        nsect = mcount;
565
                mcount -= nsect;
566
#ifdef CONFIG_IDE_TASKFILE_IO
567
                buffer = ide_map_buffer(rq, &flags);
568
                rq->sector += nsect;
569
#else /* !CONFIG_IDE_TASKFILE_IO */
570
                buffer = rq->buffer;
571
 
572
                rq->sector += nsect;
573
                rq->buffer += nsect << 9;
574
#endif /* CONFIG_IDE_TASKFILE_IO */
575
                rq->nr_sectors -= nsect;
576
                rq->current_nr_sectors -= nsect;
577
 
578
                /* Do we move to the next bh after this? */
579
                if (!rq->current_nr_sectors) {
580
                        struct buffer_head *bh = rq->bh->b_reqnext;
581
 
582
                        /* end early early we ran out of requests */
583
                        if (!bh) {
584
                                mcount = 0;
585
                        } else {
586
                                rq->bh                  = bh;
587
                                rq->current_nr_sectors  = bh->b_size >> 9;
588
                                rq->hard_cur_sectors = rq->current_nr_sectors;
589
                                rq->buffer              = bh->b_data;
590
                        }
591
                }
592
 
593
                /*
594
                 * Ok, we're all setup for the interrupt
595
                 * re-entering us on the last transfer.
596
                 */
597
                taskfile_output_data(drive, buffer, nsect<<7);
598
#ifdef CONFIG_IDE_TASKFILE_IO
599
                ide_unmap_buffer(buffer, &flags);
600
#endif /* CONFIG_IDE_TASKFILE_IO */
601
        } while (mcount);
602
 
603
        return 0;
604
}
605
 
606
/*
607
 * promise_write_pollfunc() is the handler for disk write completion polling.
608
 */
609
static ide_startstop_t promise_write_pollfunc (ide_drive_t *drive)
610
{
611
        ide_hwgroup_t *hwgroup = HWGROUP(drive);
612
 
613
        if (HWIF(drive)->INB(IDE_NSECTOR_REG) != 0) {
614
                if (time_before(jiffies, hwgroup->poll_timeout)) {
615
                        if (hwgroup->handler != NULL)
616
                                BUG();
617
                        ide_set_handler(drive,
618
                                        &promise_write_pollfunc,
619
                                        HZ/100,
620
                                        NULL);
621
                        return ide_started; /* continue polling... */
622
                }
623
                hwgroup->poll_timeout = 0;
624
                printk(KERN_ERR "%s: write timed-out!\n",drive->name);
625
                return DRIVER(drive)->error(drive, "write timeout",
626
                                HWIF(drive)->INB(IDE_STATUS_REG));
627
        }
628
 
629
        /*
630
         * Now write out last 4 sectors and poll for not BUSY
631
         */
632
        promise_multwrite(drive, 4);
633
        hwgroup->poll_timeout = jiffies + WAIT_WORSTCASE;
634
        if (hwgroup->handler != NULL)
635
                BUG();
636
        ide_set_handler(drive, &promise_complete_pollfunc, HZ/100, NULL);
637
#ifdef DEBUG_WRITE
638
        printk(KERN_DEBUG "%s: Done last 4 sectors - status = %02x\n",
639
                drive->name, HWIF(drive)->INB(IDE_STATUS_REG));
640
#endif /* DEBUG_WRITE */
641
        return ide_started;
642
}
643
 
644
/*
645
 * promise_write() transfers a block of one or more sectors of data to a
646
 * drive as part of a disk write operation. All but 4 sectors are transferred
647
 * in the first attempt, then the interface is polled (nicely!) for completion
648
 * before the final 4 sectors are transferred. There is no interrupt generated
649
 * on writes (at least on the DC4030VL-2), we just have to poll for NOT BUSY.
650
 */
651
static ide_startstop_t promise_write (ide_drive_t *drive)
652
{
653
        ide_hwgroup_t *hwgroup = HWGROUP(drive);
654
        struct request *rq = &hwgroup->wrq;
655
 
656
#ifdef DEBUG_WRITE
657
        printk(KERN_DEBUG "%s: promise_write: sectors(%ld-%ld), "
658
               "buffer=%p\n", drive->name, rq->sector,
659
               rq->sector + rq->nr_sectors - 1, rq->buffer);
660
#endif /* DEBUG_WRITE */
661
 
662
        /*
663
         * If there are more than 4 sectors to transfer, do n-4 then go into
664
         * the polling strategy as defined above.
665
         */
666
        if (rq->nr_sectors > 4) {
667
                if (promise_multwrite(drive, rq->nr_sectors - 4))
668
                        return ide_stopped;
669
                hwgroup->poll_timeout = jiffies + WAIT_WORSTCASE;
670
                if (hwgroup->handler != NULL)   /* paranoia check */
671
                        BUG();
672
                ide_set_handler (drive, &promise_write_pollfunc, HZ/100, NULL);
673
                return ide_started;
674
        } else {
675
        /*
676
         * There are 4 or fewer sectors to transfer, do them all in one go
677
         * and wait for NOT BUSY.
678
         */
679
                if (promise_multwrite(drive, rq->nr_sectors))
680
                        return ide_stopped;
681
                hwgroup->poll_timeout = jiffies + WAIT_WORSTCASE;
682
                if (hwgroup->handler != NULL)
683
                        BUG();
684
                ide_set_handler(drive,
685
                                &promise_complete_pollfunc,
686
                                HZ/100,
687
                                NULL);
688
 
689
#ifdef DEBUG_WRITE
690
                printk(KERN_DEBUG "%s: promise_write: <= 4 sectors, "
691
                        "status = %02x\n", drive->name,
692
                        HWIF(drive)->INB(IDE_STATUS_REG));
693
#endif /* DEBUG_WRITE */
694
                return ide_started;
695
        }
696
}
697
 
698
/*
699
 * do_pdc4030_io() is called from promise_rw_disk, having had the block number
700
 * already set up. It issues a READ or WRITE command to the Promise
701
 * controller, assuming LBA has been used to set up the block number.
702
 */
703
#ifndef CONFIG_IDE_TASKFILE_IO
704
ide_startstop_t do_pdc4030_io (ide_drive_t *drive, struct request *rq)
705
{
706
#else /* CONFIG_IDE_TASKFILE_IO */
707
ide_startstop_t do_pdc4030_io (ide_drive_t *drive, ide_task_t *task)
708
{
709
        struct request *rq      = HWGROUP(drive)->rq;
710
        task_struct_t *taskfile = (task_struct_t *) task->tfRegister;
711
#endif /* CONFIG_IDE_TASKFILE_IO */
712
        ide_startstop_t startstop;
713
        unsigned long timeout;
714
        u8 stat = 0;
715
 
716
#ifdef CONFIG_IDE_TASKFILE_IO
717
        if (IDE_CONTROL_REG)
718
                HWIF(drive)->OUTB(drive->ctl, IDE_CONTROL_REG); /* clear nIEN */
719
        SELECT_MASK(drive, 0);
720
        HWIF(drive)->OUTB(taskfile->feature, IDE_FEATURE_REG);
721
        HWIF(drive)->OUTB(taskfile->sector_count, IDE_NSECTOR_REG);
722
        /* refers to number of sectors to transfer */
723
        HWIF(drive)->OUTB(taskfile->sector_number, IDE_SECTOR_REG);
724
        /* refers to sector offset or start sector */
725
        HWIF(drive)->OUTB(taskfile->low_cylinder, IDE_LCYL_REG);
726
        HWIF(drive)->OUTB(taskfile->high_cylinder, IDE_HCYL_REG);
727
        HWIF(drive)->OUTB(taskfile->device_head, IDE_SELECT_REG);
728
        HWIF(drive)->OUTB(taskfile->command, IDE_COMMAND_REG);
729
#endif /* CONFIG_IDE_TASKFILE_IO */
730
 
731
        switch(rq->cmd) {
732
        case READ:
733
#ifndef CONFIG_IDE_TASKFILE_IO
734
                HWIF(drive)->OUTB(PROMISE_READ, IDE_COMMAND_REG);
735
#endif /* CONFIG_IDE_TASKFILE_IO */
736
/*
737
 * The card's behaviour is odd at this point. If the data is
738
 * available, DRQ will be true, and no interrupt will be
739
 * generated by the card. If this is the case, we need to call the
740
 * "interrupt" handler (promise_read_intr) directly. Otherwise, if
741
 * an interrupt is going to occur, bit0 of the SELECT register will
742
 * be high, so we can set the handler the just return and be interrupted.
743
 * If neither of these is the case, we wait for up to 50ms (badly I'm
744
 * afraid!) until one of them is.
745
 */
746
                timeout = jiffies + HZ/20; /* 50ms wait */
747
                do {
748
                        stat = HWIF(drive)->INB(IDE_STATUS_REG);
749
                        if (stat & DRQ_STAT) {
750
                                udelay(1);
751
                                return promise_read_intr(drive);
752
                        }
753
                        if (HWIF(drive)->INB(IDE_SELECT_REG) & 0x01) {
754
#ifdef DEBUG_READ
755
                                printk(KERN_DEBUG "%s: read: waiting for "
756
                                                "interrupt\n", drive->name);
757
#endif /* DEBUG_READ */
758
                                ide_set_handler(drive,
759
                                                &promise_read_intr,
760
                                                WAIT_CMD,
761
                                                NULL);
762
                                return ide_started;
763
                        }
764
                        udelay(1);
765
                } while (time_before(jiffies, timeout));
766
 
767
                printk(KERN_ERR "%s: reading: No DRQ and not "
768
                                "waiting - Odd!\n", drive->name);
769
                return ide_stopped;
770
        case WRITE:
771
#ifndef CONFIG_IDE_TASKFILE_IO
772
                HWIF(drive)->OUTB(PROMISE_WRITE, IDE_COMMAND_REG);
773
#endif /* CONFIG_IDE_TASKFILE_IO */
774
                if (ide_wait_stat(&startstop, drive, DATA_READY,
775
                                drive->bad_wstat, WAIT_DRQ)) {
776
                        printk(KERN_ERR "%s: no DRQ after issuing "
777
                                "PROMISE_WRITE\n", drive->name);
778
                        return startstop;
779
                }
780
                if (!drive->unmask)
781
                        local_irq_disable();
782
                HWGROUP(drive)->wrq = *rq; /* scratchpad */
783
                return promise_write(drive);
784
        default:
785
                printk("KERN_WARNING %s: bad command: %d\n",
786
                        drive->name, rq->cmd);
787
                DRIVER(drive)->end_request(drive, 0);
788
                return ide_stopped;
789
        }
790
}
791
 
792
static ide_startstop_t promise_rw_disk (ide_drive_t *drive, struct request *rq, unsigned long block)
793
{
794
        /* The four drives on the two logical (one physical) interfaces
795
           are distinguished by writing the drive number (0-3) to the
796
           Feature register.
797
           FIXME: Is promise_selectproc now redundant??
798
        */
799
        int drive_number = (HWIF(drive)->channel << 1) + drive->select.b.unit;
800
#ifndef CONFIG_IDE_TASKFILE_IO
801
        ide_hwif_t *hwif = HWIF(drive);
802
 
803
        BUG_ON(rq->nr_sectors > 127);
804
 
805
        if (IDE_CONTROL_REG)
806
                hwif->OUTB(drive->ctl, IDE_CONTROL_REG);
807
 
808
#ifdef DEBUG
809
        printk("%s: %sing: LBAsect=%ld, sectors=%ld, "
810
                "buffer=0x%08lx\n", drive->name,
811
                (rq->cmd==READ)?"read":"writ", block,
812
                rq->nr_sectors, (unsigned long) rq->buffer);
813
#endif
814
        hwif->OUTB(drive_number, IDE_FEATURE_REG);
815
        hwif->OUTB(rq->nr_sectors, IDE_NSECTOR_REG);
816
        hwif->OUTB(block,IDE_SECTOR_REG);
817
        hwif->OUTB(block>>=8,IDE_LCYL_REG);
818
        hwif->OUTB(block>>=8,IDE_HCYL_REG);
819
        hwif->OUTB(((block>>8)&0x0f)|drive->select.all,IDE_SELECT_REG);
820
 
821
        return do_pdc4030_io(drive, rq);
822
 
823
#else /* CONFIG_IDE_TASKFILE_IO */
824
 
825
        struct hd_drive_task_hdr        taskfile;
826
        ide_task_t                      args;
827
 
828
        memset(&taskfile, 0, sizeof(struct hd_drive_task_hdr));
829
 
830
        taskfile.feature        = drive_number;
831
        taskfile.sector_count   = rq->nr_sectors;
832
        taskfile.sector_number  = block;
833
        taskfile.low_cylinder   = (block>>=8);
834
        taskfile.high_cylinder  = (block>>=8);
835
        taskfile.device_head    = ((block>>8)&0x0f)|drive->select.all;
836
        taskfile.command        = (rq->cmd==READ)?PROMISE_READ:PROMISE_WRITE;
837
 
838
        memcpy(args.tfRegister, &taskfile, sizeof(struct hd_drive_task_hdr));
839
        memset(args.hobRegister, 0, sizeof(struct hd_drive_hob_hdr));
840
        /* We can't call ide_cmd_type_parser here, since it won't understand
841
           our command, but that doesn't matter, since we don't use the
842
           generic interrupt handlers either. Setup the bits of args that we
843
           do need.
844
        */
845
        args.handler            = NULL;
846
        args.rq                 = (struct request *) rq;
847
        rq->special             = (ide_task_t *)&args;
848
 
849
        return do_pdc4030_io(drive, &args);
850
#endif /* CONFIG_IDE_TASKFILE_IO */
851
}

powered by: WebSVN 2.1.0

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