~ [ source navigation ] ~ [ diff markup ] ~ [ identifier search ] ~ [ freetext search ] ~ [ file search ] ~

Linux Cross Reference
Linux/drivers/ide/pdc4030.c

Version: ~ [ 2.2.5 ] ~ [ 2.4.1 ] ~ [ 2.4.9 ] ~ [ 2.6.17.10 ] ~
Architecture: ~ [ i386 ] ~ [ alpha ] ~ [ m68k ] ~ [ mips ] ~ [ ppc ] ~ [ sparc ] ~ [ sparc64 ] ~

  1 /*  -*- linux-c -*-
  2  *  linux/drivers/ide/pdc4030.c         Version 0.90  May 27, 1999
  3  *
  4  *  Copyright (C) 1995-1999  Linus Torvalds & authors (see below)
  5  */
  6 
  7 /*
  8  *  Principal Author/Maintainer:  peterd@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 problems with the robustness and efficiency of this driver
 70  * because I still don't understand what the card is doing with interrupts.
 71  */
 72 
 73 #define DEBUG_READ
 74 #define DEBUG_WRITE
 75 
 76 #include <linux/types.h>
 77 #include <linux/kernel.h>
 78 #include <linux/delay.h>
 79 #include <linux/timer.h>
 80 #include <linux/mm.h>
 81 #include <linux/ioport.h>
 82 #include <linux/blkdev.h>
 83 #include <linux/hdreg.h>
 84 #include <linux/ide.h>
 85 #include <linux/init.h>
 86 
 87 #include <asm/io.h>
 88 #include <asm/irq.h>
 89 
 90 #include "pdc4030.h"
 91 
 92 /*
 93  * promise_selectproc() is invoked by ide.c
 94  * in preparation for access to the specified drive.
 95  */
 96 static void promise_selectproc (ide_drive_t *drive)
 97 {
 98         unsigned int number;
 99 
100         number = (HWIF(drive)->channel << 1) + drive->select.b.unit;
101         OUT_BYTE(number,IDE_FEATURE_REG);
102 }
103 
104 /*
105  * pdc4030_cmd handles the set of vendor specific commands that are initiated
106  * by command F0. They all have the same success/failure notification -
107  * 'P' (=0x50) on success, 'p' (=0x70) on failure.
108  */
109 int pdc4030_cmd(ide_drive_t *drive, byte cmd)
110 {
111         unsigned long timeout, timer;
112         byte status_val;
113 
114         promise_selectproc(drive);      /* redundant? */
115         OUT_BYTE(0xF3,IDE_SECTOR_REG);
116         OUT_BYTE(cmd,IDE_SELECT_REG);
117         OUT_BYTE(PROMISE_EXTENDED_COMMAND,IDE_COMMAND_REG);
118         timeout = HZ * 10;
119         timeout += jiffies;
120         do {
121                 if(time_after(jiffies, timeout)) {
122                         return 2; /* device timed out */
123                 }
124                 /* This is out of delay_10ms() */
125                 /* Delays at least 10ms to give interface a chance */
126                 timer = jiffies + (HZ + 99)/100 + 1;
127                 while (time_after(timer, jiffies));
128                 status_val = IN_BYTE(IDE_SECTOR_REG);
129         } while (status_val != 0x50 && status_val != 0x70);
130 
131         if(status_val == 0x50)
132                 return 0; /* device returned success */
133         else
134                 return 1; /* device returned failure */
135 }
136 
137 /*
138  * pdc4030_identify sends a vendor-specific IDENTIFY command to the drive
139  */
140 int pdc4030_identify(ide_drive_t *drive)
141 {
142         return pdc4030_cmd(drive, PROMISE_IDENTIFY);
143 }
144 
145 int enable_promise_support = 0;
146 
147 void __init init_pdc4030 (void)
148 {
149         enable_promise_support = 1;
150 }
151 
152 /*
153  * setup_pdc4030()
154  * Completes the setup of a Promise DC4030 controller card, once found.
155  */
156 int __init setup_pdc4030 (ide_hwif_t *hwif)
157 {
158         ide_drive_t *drive;
159         ide_hwif_t *hwif2;
160         struct dc_ident ident;
161         int i;
162         ide_startstop_t startstop;
163         
164         if (!hwif) return 0;
165 
166         drive = &hwif->drives[0];
167         hwif2 = &ide_hwifs[hwif->index+1];
168         if (hwif->chipset == ide_pdc4030) /* we've already been found ! */
169                 return 1;
170 
171         if (IN_BYTE(IDE_NSECTOR_REG) == 0xFF || IN_BYTE(IDE_SECTOR_REG) == 0xFF) {
172                 return 0;
173         }
174         if (IDE_CONTROL_REG)
175                 OUT_BYTE(0x08,IDE_CONTROL_REG);
176         if (pdc4030_cmd(drive,PROMISE_GET_CONFIG)) {
177                 return 0;
178         }
179         if (ide_wait_stat(&startstop, drive,DATA_READY,BAD_W_STAT,WAIT_DRQ)) {
180                 printk(KERN_INFO
181                         "%s: Failed Promise read config!\n",hwif->name);
182                 return 0;
183         }
184         ide_input_data(drive,&ident,SECTOR_WORDS);
185         if (ident.id[1] != 'P' || ident.id[0] != 'T') {
186                 return 0;
187         }
188         printk(KERN_INFO "%s: Promise caching controller, ",hwif->name);
189         switch(ident.type) {
190                 case 0x43:      printk("DC4030VL-2, "); break;
191                 case 0x41:      printk("DC4030VL-1, "); break;
192                 case 0x40:      printk("DC4030VL, "); break;
193                 default:
194                         printk("unknown - type 0x%02x - please report!\n"
195                                ,ident.type);
196                         printk("Please e-mail the following data to "
197                                "promise@pnd-pc.demon.co.uk along with\n"
198                                "a description of your card and drives:\n");
199                         for (i=0; i < 0x90; i++) {
200                                 printk("%02x ", ((unsigned char *)&ident)[i]);
201                                 if ((i & 0x0f) == 0x0f) printk("\n");
202                         }
203                         return 0;
204         }
205         printk("%dKB cache, ",(int)ident.cache_mem);
206         switch(ident.irq) {
207             case 0x00: hwif->irq = 14; break;
208             case 0x01: hwif->irq = 12; break;
209             default:   hwif->irq = 15; break;
210         }
211         printk("on IRQ %d\n",hwif->irq);
212 
213         /*
214          * Once found and identified, we set up the next hwif in the array
215          * (hwif2 = ide_hwifs[hwif->index+1]) with the same io ports, irq
216          * and other settings as the main hwif. This gives us two "mated"
217          * hwifs pointing to the Promise card.
218          *
219          * We also have to shift the default values for the remaining
220          * interfaces "up by one" to make room for the second interface on the
221          * same set of values.
222          */
223 
224         hwif->chipset   = hwif2->chipset = ide_pdc4030;
225         hwif->mate      = hwif2;
226         hwif2->mate     = hwif;
227         hwif2->channel  = 1;
228         hwif->selectproc = hwif2->selectproc = &promise_selectproc;
229         hwif->serialized = hwif2->serialized = 1;
230 
231 /* Shift the remaining interfaces down by one */
232         for (i=MAX_HWIFS-1 ; i > hwif->index+1 ; i--) {
233                 ide_hwif_t *h = &ide_hwifs[i];
234 
235 #ifdef DEBUG
236                 printk(KERN_DEBUG "Shifting i/f %d values to i/f %d\n",i-1,i);
237 #endif
238                 ide_init_hwif_ports(&h->hw, (h-1)->io_ports[IDE_DATA_OFFSET], 0, NULL);
239                 memcpy(h->io_ports, h->hw.io_ports, sizeof(h->io_ports));
240                 h->noprobe = (h-1)->noprobe;
241         }
242         ide_init_hwif_ports(&hwif2->hw, hwif->io_ports[IDE_DATA_OFFSET], 0, NULL);
243         memcpy(hwif2->io_ports, hwif->hw.io_ports, sizeof(hwif2->io_ports));
244         hwif2->irq = hwif->irq;
245         hwif2->hw.irq = hwif->hw.irq = hwif->irq;
246         for (i=0; i<2 ; i++) {
247                 hwif->drives[i].io_32bit = 3;
248                 hwif2->drives[i].io_32bit = 3;
249                 hwif->drives[i].keep_settings = 1;
250                 hwif2->drives[i].keep_settings = 1;
251                 if (!ident.current_tm[i].cyl)
252                         hwif->drives[i].noprobe = 1;
253                 if (!ident.current_tm[i+2].cyl)
254                         hwif2->drives[i].noprobe = 1;
255         }
256         return 1;
257 }
258 
259 /*
260  * detect_pdc4030()
261  * Tests for the presence of a DC4030 Promise card on this interface
262  * Returns: 1 if found, 0 if not found
263  */
264 int __init detect_pdc4030(ide_hwif_t *hwif)
265 {
266         ide_drive_t *drive = &hwif->drives[0];
267 
268         if (IDE_DATA_REG == 0) { /* Skip test for non-existent interface */
269                 return 0;
270         }
271         OUT_BYTE(0xF3, IDE_SECTOR_REG);
272         OUT_BYTE(0x14, IDE_SELECT_REG);
273         OUT_BYTE(PROMISE_EXTENDED_COMMAND, IDE_COMMAND_REG);
274         
275         ide_delay_50ms();
276 
277         if (IN_BYTE(IDE_ERROR_REG) == 'P' &&
278             IN_BYTE(IDE_NSECTOR_REG) == 'T' &&
279             IN_BYTE(IDE_SECTOR_REG) == 'I') {
280                 return 1;
281         } else {
282                 return 0;
283         }
284 }
285 
286 void __init ide_probe_for_pdc4030(void)
287 {
288         unsigned int    index;
289         ide_hwif_t      *hwif;
290 
291         if (enable_promise_support == 0)
292                 return;
293         for (index = 0; index < MAX_HWIFS; index++) {
294                 hwif = &ide_hwifs[index];
295                 if (hwif->chipset == ide_unknown && detect_pdc4030(hwif)) {
296                         setup_pdc4030(hwif);
297                 }
298         }
299 }
300 
301 
302 
303 /*
304  * promise_read_intr() is the handler for disk read/multread interrupts
305  */
306 static ide_startstop_t promise_read_intr (ide_drive_t *drive)
307 {
308         byte stat;
309         int total_remaining;
310         unsigned int sectors_left, sectors_avail, nsect;
311         struct request *rq;
312 
313         if (!OK_STAT(stat=GET_STAT(),DATA_READY,BAD_R_STAT)) {
314                 return ide_error(drive, "promise_read_intr", stat);
315         }
316 
317 read_again:
318         do {
319                 sectors_left = IN_BYTE(IDE_NSECTOR_REG);
320                 IN_BYTE(IDE_SECTOR_REG);
321         } while (IN_BYTE(IDE_NSECTOR_REG) != sectors_left);
322         rq = HWGROUP(drive)->rq;
323         sectors_avail = rq->nr_sectors - sectors_left;
324         if (!sectors_avail)
325                 goto read_again;
326 
327 read_next:
328         rq = HWGROUP(drive)->rq;
329         nsect = rq->current_nr_sectors;
330         if (nsect > sectors_avail)
331                 nsect = sectors_avail;
332         sectors_avail -= nsect;
333         ide_input_data(drive, rq->buffer, nsect * SECTOR_WORDS);
334 #ifdef DEBUG_READ
335         printk(KERN_DEBUG "%s:  promise_read: sectors(%ld-%ld), "
336                "buf=0x%08lx, rem=%ld\n", drive->name, rq->sector,
337                rq->sector+nsect-1, (unsigned long) rq->buffer,
338                rq->nr_sectors-nsect);
339 #endif
340         rq->sector += nsect;
341         rq->buffer += nsect<<9;
342         rq->errors = 0;
343         rq->nr_sectors -= nsect;
344         total_remaining = rq->nr_sectors;
345         if ((rq->current_nr_sectors -= nsect) <= 0) {
346                 ide_end_request(1, HWGROUP(drive));
347         }
348 /*
349  * Now the data has been read in, do the following:
350  * 
351  * if there are still sectors left in the request, 
352  *   if we know there are still sectors available from the interface,
353  *     go back and read the next bit of the request.
354  *   else if DRQ is asserted, there are more sectors available, so
355  *     go back and find out how many, then read them in.
356  *   else if BUSY is asserted, we are going to get an interrupt, so
357  *     set the handler for the interrupt and just return
358  */
359         if (total_remaining > 0) {
360                 if (sectors_avail)
361                         goto read_next;
362                 stat = GET_STAT();
363                 if (stat & DRQ_STAT)
364                         goto read_again;
365                 if (stat & BUSY_STAT) {
366                         ide_set_handler (drive, &promise_read_intr, WAIT_CMD, NULL);
367 #ifdef DEBUG_READ
368                         printk(KERN_DEBUG "%s: promise_read: waiting for"
369                                "interrupt\n", drive->name);
370 #endif 
371                         return ide_started;
372                 }
373                 printk(KERN_ERR "%s: Eeek! promise_read_intr: sectors left "
374                        "!DRQ !BUSY\n", drive->name);
375                 return ide_error(drive, "promise read intr", stat);
376         }
377         return ide_stopped;
378 }
379 
380 /*
381  * promise_complete_pollfunc()
382  * This is the polling function for waiting (nicely!) until drive stops
383  * being busy. It is invoked at the end of a write, after the previous poll
384  * has finished.
385  *
386  * Once not busy, the end request is called.
387  */
388 static ide_startstop_t promise_complete_pollfunc(ide_drive_t *drive)
389 {
390         ide_hwgroup_t *hwgroup = HWGROUP(drive);
391         struct request *rq = hwgroup->rq;
392         int i;
393 
394         if (GET_STAT() & BUSY_STAT) {
395                 if (time_before(jiffies, hwgroup->poll_timeout)) {
396                         ide_set_handler(drive, &promise_complete_pollfunc, HZ/100, NULL);
397                         return ide_started; /* continue polling... */
398                 }
399                 hwgroup->poll_timeout = 0;
400                 printk(KERN_ERR "%s: completion timeout - still busy!\n",
401                        drive->name);
402                 return ide_error(drive, "busy timeout", GET_STAT());
403         }
404 
405         hwgroup->poll_timeout = 0;
406 #ifdef DEBUG_WRITE
407         printk(KERN_DEBUG "%s: Write complete - end_request\n", drive->name);
408 #endif
409         for (i = rq->nr_sectors; i > 0; ) {
410                 i -= rq->current_nr_sectors;
411                 ide_end_request(1, hwgroup);
412         }
413         return ide_stopped;
414 }
415 
416 /*
417  * promise_write_pollfunc() is the handler for disk write completion polling.
418  */
419 static ide_startstop_t promise_write_pollfunc (ide_drive_t *drive)
420 {
421         ide_hwgroup_t *hwgroup = HWGROUP(drive);
422 
423         if (IN_BYTE(IDE_NSECTOR_REG) != 0) {
424                 if (time_before(jiffies, hwgroup->poll_timeout)) {
425                         ide_set_handler (drive, &promise_write_pollfunc, HZ/100, NULL);
426                         return ide_started; /* continue polling... */
427                 }
428                 hwgroup->poll_timeout = 0;
429                 printk(KERN_ERR "%s: write timed-out!\n",drive->name);
430                 return ide_error (drive, "write timeout", GET_STAT());
431         }
432 
433         /*
434          * Now write out last 4 sectors and poll for not BUSY
435          */
436         ide_multwrite(drive, 4);
437         hwgroup->poll_timeout = jiffies + WAIT_WORSTCASE;
438         ide_set_handler(drive, &promise_complete_pollfunc, HZ/100, NULL);
439 #ifdef DEBUG_WRITE
440         printk(KERN_DEBUG "%s: Done last 4 sectors - status = %02x\n",
441                 drive->name, GET_STAT());
442 #endif
443         return ide_started;
444 }
445 
446 /*
447  * promise_write() transfers a block of one or more sectors of data to a
448  * drive as part of a disk write operation. All but 4 sectors are transfered
449  * in the first attempt, then the interface is polled (nicely!) for completion
450  * before the final 4 sectors are transfered. There is no interrupt generated
451  * on writes (at least on the DC4030VL-2), we just have to poll for NOT BUSY.
452  */
453 static ide_startstop_t promise_write (ide_drive_t *drive)
454 {
455         ide_hwgroup_t *hwgroup = HWGROUP(drive);
456         struct request *rq = &hwgroup->wrq;
457 
458 #ifdef DEBUG_WRITE
459         printk(KERN_DEBUG "%s: promise_write: sectors(%ld-%ld), "
460                "buffer=0x%08x\n", drive->name, rq->sector,
461                rq->sector + rq->nr_sectors - 1, (unsigned int)rq->buffer);
462 #endif
463 
464         /*
465          * If there are more than 4 sectors to transfer, do n-4 then go into
466          * the polling strategy as defined above.
467          */
468         if (rq->nr_sectors > 4) {
469                 if (ide_multwrite(drive, rq->nr_sectors - 4))
470                         return ide_stopped;
471                 hwgroup->poll_timeout = jiffies + WAIT_WORSTCASE;
472                 ide_set_handler (drive, &promise_write_pollfunc, HZ/100, NULL);
473                 return ide_started;
474         } else {
475         /*
476          * There are 4 or fewer sectors to transfer, do them all in one go
477          * and wait for NOT BUSY.
478          */
479                 if (ide_multwrite(drive, rq->nr_sectors))
480                         return ide_stopped;
481                 hwgroup->poll_timeout = jiffies + WAIT_WORSTCASE;
482                 ide_set_handler(drive, &promise_complete_pollfunc, HZ/100, NULL);
483 #ifdef DEBUG_WRITE
484                 printk(KERN_DEBUG "%s: promise_write: <= 4 sectors, "
485                         "status = %02x\n", drive->name, GET_STAT());
486 #endif
487                 return ide_started;
488         }
489 }
490 
491 /*
492  * do_pdc4030_io() is called from do_rw_disk, having had the block number
493  * already set up. It issues a READ or WRITE command to the Promise
494  * controller, assuming LBA has been used to set up the block number.
495  */
496 ide_startstop_t do_pdc4030_io (ide_drive_t *drive, struct request *rq)
497 {
498         unsigned long timeout;
499         byte stat;
500 
501         if (rq->cmd == READ) {
502                 OUT_BYTE(PROMISE_READ, IDE_COMMAND_REG);
503 /*
504  * The card's behaviour is odd at this point. If the data is
505  * available, DRQ will be true, and no interrupt will be
506  * generated by the card. If this is the case, we need to call the 
507  * "interrupt" handler (promise_read_intr) directly. Otherwise, if
508  * an interrupt is going to occur, bit0 of the SELECT register will
509  * be high, so we can set the handler the just return and be interrupted.
510  * If neither of these is the case, we wait for up to 50ms (badly I'm
511  * afraid!) until one of them is.
512  */
513                 timeout = jiffies + HZ/20; /* 50ms wait */
514                 do {
515                         stat=GET_STAT();
516                         if (stat & DRQ_STAT) {
517                                 udelay(1);
518                                 return promise_read_intr(drive);
519                         }
520                         if (IN_BYTE(IDE_SELECT_REG) & 0x01) {
521 #ifdef DEBUG_READ
522                                 printk(KERN_DEBUG "%s: read: waiting for "
523                                                   "interrupt\n", drive->name);
524 #endif
525                                 ide_set_handler(drive, &promise_read_intr, WAIT_CMD, NULL);
526                                 return ide_started;
527                         }
528                         udelay(1);
529                 } while (time_before(jiffies, timeout));
530 
531                 printk(KERN_ERR "%s: reading: No DRQ and not waiting - Odd!\n",
532                         drive->name);
533                 return ide_stopped;
534         } else if (rq->cmd == WRITE) {
535                 ide_startstop_t startstop;
536                 OUT_BYTE(PROMISE_WRITE, IDE_COMMAND_REG);
537                 if (ide_wait_stat(&startstop, drive, DATA_READY, drive->bad_wstat, WAIT_DRQ)) {
538                         printk(KERN_ERR "%s: no DRQ after issuing "
539                                "PROMISE_WRITE\n", drive->name);
540                         return startstop;
541                 }
542                 if (!drive->unmask)
543                         __cli();        /* local CPU only */
544                 HWGROUP(drive)->wrq = *rq; /* scratchpad */
545                 return promise_write(drive);
546 
547         } else {
548                 printk("KERN_WARNING %s: bad command: %d\n",
549                        drive->name, rq->cmd);
550                 ide_end_request(0, HWGROUP(drive));
551                 return ide_stopped;
552         }
553 }
554 

~ [ source navigation ] ~ [ diff markup ] ~ [ identifier search ] ~ [ freetext search ] ~ [ file search ] ~

This page was automatically generated by the LXR engine.
Visit the LXR main site for more information.