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

Linux Cross Reference
Linux/drivers/ide/ide-features.c

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

  1 /*
  2  * linux/drivers/block/ide-features.c   Version 0.04    June 9, 2000
  3  *
  4  *  Copyright (C) 1999-2000     Linus Torvalds & authors (see below)
  5  *  
  6  *  Copyright (C) 1999-2000     Andre Hedrick <andre@linux-ide.org>
  7  *
  8  *  Extracts if ide.c to address the evolving transfer rate code for
  9  *  the SETFEATURES_XFER callouts.  Various parts of any given function
 10  *  are credited to previous ATA-IDE maintainers.
 11  *
 12  *  Auto-CRC downgrade for Ultra DMA(ing)
 13  *
 14  *  May be copied or modified under the terms of the GNU General Public License
 15  */
 16 
 17 #include <linux/config.h>
 18 #define __NO_VERSION__
 19 #include <linux/module.h>
 20 #include <linux/types.h>
 21 #include <linux/string.h>
 22 #include <linux/kernel.h>
 23 #include <linux/timer.h>
 24 #include <linux/mm.h>
 25 #include <linux/interrupt.h>
 26 #include <linux/major.h>
 27 #include <linux/errno.h>
 28 #include <linux/genhd.h>
 29 #include <linux/blkpg.h>
 30 #include <linux/malloc.h>
 31 #include <linux/pci.h>
 32 #include <linux/delay.h>
 33 #include <linux/hdreg.h>
 34 #include <linux/ide.h>
 35 
 36 #include <asm/byteorder.h>
 37 #include <asm/irq.h>
 38 #include <asm/uaccess.h>
 39 #include <asm/io.h>
 40 #include <asm/bitops.h>
 41 
 42 /*
 43  * A Verbose noise maker for debugging on the attempted transfer rates.
 44  */
 45 char *ide_xfer_verbose (byte xfer_rate)
 46 {
 47         switch(xfer_rate) {
 48                 case XFER_UDMA_7:       return("UDMA 7");
 49                 case XFER_UDMA_6:       return("UDMA 6");
 50                 case XFER_UDMA_5:       return("UDMA 5");
 51                 case XFER_UDMA_4:       return("UDMA 4");
 52                 case XFER_UDMA_3:       return("UDMA 3");
 53                 case XFER_UDMA_2:       return("UDMA 2");
 54                 case XFER_UDMA_1:       return("UDMA 1");
 55                 case XFER_UDMA_0:       return("UDMA 0");
 56                 case XFER_MW_DMA_2:     return("MW DMA 2");
 57                 case XFER_MW_DMA_1:     return("MW DMA 1");
 58                 case XFER_MW_DMA_0:     return("MW DMA 0");
 59                 case XFER_SW_DMA_2:     return("SW DMA 2");
 60                 case XFER_SW_DMA_1:     return("SW DMA 1");
 61                 case XFER_SW_DMA_0:     return("SW DMA 0");
 62                 case XFER_PIO_4:        return("PIO 4");
 63                 case XFER_PIO_3:        return("PIO 3");
 64                 case XFER_PIO_2:        return("PIO 2");
 65                 case XFER_PIO_1:        return("PIO 1");
 66                 case XFER_PIO_0:        return("PIO 0");
 67                 case XFER_PIO_SLOW:     return("PIO SLOW");
 68                 default:                return("XFER ERROR");
 69         }
 70 }
 71 
 72 /*
 73  *
 74  */
 75 char *ide_media_verbose (ide_drive_t *drive)
 76 {
 77         switch (drive->media) {
 78                 case ide_scsi:          return("scsi   ");
 79                 case ide_disk:          return("disk   ");
 80                 case ide_optical:       return("optical");
 81                 case ide_cdrom:         return("cdrom  ");
 82                 case ide_tape:          return("tape   ");
 83                 case ide_floppy:        return("floppy ");
 84                 default:                return("???????");
 85         }
 86 }
 87 
 88 /*
 89  * A Verbose noise maker for debugging on the attempted dmaing calls.
 90  */
 91 char *ide_dmafunc_verbose (ide_dma_action_t dmafunc)
 92 {
 93         switch (dmafunc) {
 94                 case ide_dma_read:              return("ide_dma_read");
 95                 case ide_dma_write:             return("ide_dma_write");
 96                 case ide_dma_begin:             return("ide_dma_begin");
 97                 case ide_dma_end:               return("ide_dma_end:");
 98                 case ide_dma_check:             return("ide_dma_check");
 99                 case ide_dma_on:                return("ide_dma_on");
100                 case ide_dma_off:               return("ide_dma_off");
101                 case ide_dma_off_quietly:       return("ide_dma_off_quietly");
102                 case ide_dma_test_irq:          return("ide_dma_test_irq");
103                 case ide_dma_bad_drive:         return("ide_dma_bad_drive");
104                 case ide_dma_good_drive:        return("ide_dma_good_drive");
105                 case ide_dma_verbose:           return("ide_dma_verbose");
106                 case ide_dma_retune:            return("ide_dma_retune");
107                 case ide_dma_lostirq:           return("ide_dma_lostirq");
108                 case ide_dma_timeout:           return("ide_dma_timeout");
109                 default:                        return("unknown");
110         }
111 }
112 
113 /*
114  *
115  */
116 byte ide_auto_reduce_xfer (ide_drive_t *drive)
117 {
118         if (!drive->crc_count)
119                 return drive->current_speed;
120         drive->crc_count = 0;
121 
122         switch(drive->current_speed) {
123                 case XFER_UDMA_7:       return XFER_UDMA_6;
124                 case XFER_UDMA_6:       return XFER_UDMA_5;
125                 case XFER_UDMA_5:       return XFER_UDMA_4;
126                 case XFER_UDMA_4:       return XFER_UDMA_3;
127                 case XFER_UDMA_3:       return XFER_UDMA_2;
128                 case XFER_UDMA_2:       return XFER_UDMA_1;
129                 case XFER_UDMA_1:       return XFER_UDMA_0;
130                 case XFER_UDMA_0:
131                         if (drive->id->dma_mword & 0x0004) return XFER_MW_DMA_2;
132                         else if (drive->id->dma_mword & 0x0002) return XFER_MW_DMA_1;
133                         else if (drive->id->dma_mword & 0x0001) return XFER_MW_DMA_0;
134                         else return XFER_PIO_4;
135                 case XFER_MW_DMA_2:     return XFER_MW_DMA_1;
136                 case XFER_MW_DMA_1:     return XFER_MW_DMA_0;
137                 case XFER_MW_DMA_0:
138                         if (drive->id->dma_1word & 0x0004) return XFER_SW_DMA_2;
139                         else if (drive->id->dma_1word & 0x0002) return XFER_SW_DMA_1;
140                         else if (drive->id->dma_1word & 0x0001) return XFER_SW_DMA_0;
141                         else return XFER_PIO_4;
142                 case XFER_SW_DMA_2:     return XFER_SW_DMA_1;
143                 case XFER_SW_DMA_1:     return XFER_SW_DMA_0;
144                 case XFER_SW_DMA_0:
145                         {
146                                 return XFER_PIO_4;
147                         }
148                 case XFER_PIO_4:        return XFER_PIO_3;
149                 case XFER_PIO_3:        return XFER_PIO_2;
150                 case XFER_PIO_2:        return XFER_PIO_1;
151                 case XFER_PIO_1:        return XFER_PIO_0;
152                 case XFER_PIO_0:
153                 default:                return XFER_PIO_SLOW;
154         }
155 }
156 
157 /*
158  * Update the 
159  */
160 int ide_driveid_update (ide_drive_t *drive)
161 {
162         /*
163          * Re-read drive->id for possible DMA mode
164          * change (copied from ide-probe.c)
165          */
166         struct hd_driveid *id;
167         unsigned long timeout, flags;
168 
169         SELECT_MASK(HWIF(drive), drive, 1);
170         if (IDE_CONTROL_REG)
171                 OUT_BYTE(drive->ctl,IDE_CONTROL_REG);
172         ide_delay_50ms();
173         OUT_BYTE(WIN_IDENTIFY, IDE_COMMAND_REG);
174         timeout = jiffies + WAIT_WORSTCASE;
175         do {
176                 if (0 < (signed long)(jiffies - timeout)) {
177                         SELECT_MASK(HWIF(drive), drive, 0);
178                         return 0;       /* drive timed-out */
179                 }
180                 ide_delay_50ms();       /* give drive a breather */
181         } while (IN_BYTE(IDE_ALTSTATUS_REG) & BUSY_STAT);
182         ide_delay_50ms();       /* wait for IRQ and DRQ_STAT */
183         if (!OK_STAT(GET_STAT(),DRQ_STAT,BAD_R_STAT)) {
184                 SELECT_MASK(HWIF(drive), drive, 0);
185                 printk("%s: CHECK for good STATUS\n", drive->name);
186                 return 0;
187         }
188         __save_flags(flags);    /* local CPU only */
189         __cli();                /* local CPU only; some systems need this */
190         SELECT_MASK(HWIF(drive), drive, 0);
191         id = kmalloc(SECTOR_WORDS*4, GFP_ATOMIC);
192         ide_input_data(drive, id, SECTOR_WORDS);
193         (void) GET_STAT();      /* clear drive IRQ */
194         ide__sti();             /* local CPU only */
195         __restore_flags(flags); /* local CPU only */
196         ide_fix_driveid(id);
197         if (id) {
198                 drive->id->dma_ultra = id->dma_ultra;
199                 drive->id->dma_mword = id->dma_mword;
200                 drive->id->dma_1word = id->dma_1word;
201                 /* anything more ? */
202                 kfree(id);
203         }
204 
205         return 1;
206 }
207 
208 /*
209  * Verify that we are doing an approved SETFEATURES_XFER with respect
210  * to the hardware being able to support request.  Since some hardware
211  * can improperly report capabilties, we check to see if the host adapter
212  * in combination with the device (usually a disk) properly detect
213  * and acknowledge each end of the ribbon.
214  */
215 int ide_ata66_check (ide_drive_t *drive, byte cmd, byte nsect, byte feature)
216 {
217         if ((cmd == WIN_SETFEATURES) &&
218             (nsect > XFER_UDMA_2) &&
219             (feature == SETFEATURES_XFER)) {
220                 if (!HWIF(drive)->udma_four) {
221                         printk("%s: Speed warnings UDMA 3/4/5 is not functional.\n", HWIF(drive)->name);
222                         return 1;
223                 }
224 #ifndef CONFIG_IDEDMA_IVB
225                 if ((drive->id->hw_config & 0x6000) == 0) {
226 #else /* !CONFIG_IDEDMA_IVB */
227                 if (((drive->id->hw_config & 0x2000) == 0) ||
228                     ((drive->id->hw_config & 0x4000) == 0)) {
229 #endif /* CONFIG_IDEDMA_IVB */
230                         printk("%s: Speed warnings UDMA 3/4/5 is not functional.\n", drive->name);
231                         return 1;
232                 }
233         }
234         return 0;
235 }
236 
237 /*
238  * Backside of HDIO_DRIVE_CMD call of SETFEATURES_XFER.
239  * 1 : Safe to update drive->id DMA registers.
240  * 0 : OOPs not allowed.
241  */
242 int set_transfer (ide_drive_t *drive, byte cmd, byte nsect, byte feature)
243 {
244         if ((cmd == WIN_SETFEATURES) &&
245             (nsect >= XFER_SW_DMA_0) &&
246             (feature == SETFEATURES_XFER) &&
247             (drive->id->dma_ultra ||
248              drive->id->dma_mword ||
249              drive->id->dma_1word))
250                 return 1;
251 
252         return 0;
253 }
254 
255 /*
256  *  All hosts that use the 80c ribbon mus use!
257  */
258 byte eighty_ninty_three (ide_drive_t *drive)
259 {
260         return ((byte) ((HWIF(drive)->udma_four) &&
261 #ifndef CONFIG_IDEDMA_IVB
262                         (drive->id->hw_config & 0x4000) &&
263 #endif /* CONFIG_IDEDMA_IVB */
264                         (drive->id->hw_config & 0x6000)) ? 1 : 0);
265 }
266 
267 /*
268  * Similar to ide_wait_stat(), except it never calls ide_error internally.
269  * This is a kludge to handle the new ide_config_drive_speed() function,
270  * and should not otherwise be used anywhere.  Eventually, the tuneproc's
271  * should be updated to return ide_startstop_t, in which case we can get
272  * rid of this abomination again.  :)   -ml
273  *
274  * It is gone..........
275  *
276  * const char *msg == consider adding for verbose errors.
277  */
278 int ide_config_drive_speed (ide_drive_t *drive, byte speed)
279 {
280         ide_hwif_t *hwif = HWIF(drive);
281         int     i, error = 1;
282         byte stat;
283 
284 #if defined(CONFIG_BLK_DEV_IDEDMA) && !defined(CONFIG_DMA_NONPCI)
285         byte unit = (drive->select.b.unit & 0x01);
286         outb(inb(hwif->dma_base+2) & ~(1<<(5+unit)), hwif->dma_base+2);
287 #endif /* (CONFIG_BLK_DEV_IDEDMA) && !(CONFIG_DMA_NONPCI) */
288 
289         /*
290          * Don't use ide_wait_cmd here - it will
291          * attempt to set_geometry and recalibrate,
292          * but for some reason these don't work at
293          * this point (lost interrupt).
294          */
295         /*
296          * Select the drive, and issue the SETFEATURES command
297          */
298         disable_irq(hwif->irq); /* disable_irq_nosync ?? */
299         udelay(1);
300         SELECT_DRIVE(HWIF(drive), drive);
301         SELECT_MASK(HWIF(drive), drive, 0);
302         udelay(1);
303         if (IDE_CONTROL_REG)
304                 OUT_BYTE(drive->ctl | 2, IDE_CONTROL_REG);
305         OUT_BYTE(speed, IDE_NSECTOR_REG);
306         OUT_BYTE(SETFEATURES_XFER, IDE_FEATURE_REG);
307         OUT_BYTE(WIN_SETFEATURES, IDE_COMMAND_REG);
308         if ((IDE_CONTROL_REG) && (drive->quirk_list == 2))
309                 OUT_BYTE(drive->ctl, IDE_CONTROL_REG);
310         udelay(1);
311         /*
312          * Wait for drive to become non-BUSY
313          */
314         if ((stat = GET_STAT()) & BUSY_STAT) {
315                 unsigned long flags, timeout;
316                 __save_flags(flags);    /* local CPU only */
317                 ide__sti();             /* local CPU only -- for jiffies */
318                 timeout = jiffies + WAIT_CMD;
319                 while ((stat = GET_STAT()) & BUSY_STAT) {
320                         if (0 < (signed long)(jiffies - timeout))
321                                 break;
322                 }
323                 __restore_flags(flags); /* local CPU only */
324         }
325 
326         /*
327          * Allow status to settle, then read it again.
328          * A few rare drives vastly violate the 400ns spec here,
329          * so we'll wait up to 10usec for a "good" status
330          * rather than expensively fail things immediately.
331          * This fix courtesy of Matthew Faupel & Niccolo Rigacci.
332          */
333         for (i = 0; i < 10; i++) {
334                 udelay(1);
335                 if (OK_STAT((stat = GET_STAT()), DRIVE_READY, BUSY_STAT|DRQ_STAT|ERR_STAT)) {
336                         error = 0;
337                         break;
338                 }
339         }
340 
341         SELECT_MASK(HWIF(drive), drive, 0);
342 
343         enable_irq(hwif->irq);
344 
345         if (error) {
346                 (void) ide_dump_status(drive, "set_drive_speed_status", stat);
347                 return error;
348         }
349 
350         drive->id->dma_ultra &= ~0xFF00;
351         drive->id->dma_mword &= ~0x0F00;
352         drive->id->dma_1word &= ~0x0F00;
353 
354 #if defined(CONFIG_BLK_DEV_IDEDMA) && !defined(CONFIG_DMA_NONPCI)
355         if (speed > XFER_PIO_4) {
356                 outb(inb(hwif->dma_base+2)|(1<<(5+unit)), hwif->dma_base+2);
357         } else {
358                 outb(inb(hwif->dma_base+2) & ~(1<<(5+unit)), hwif->dma_base+2);
359         }
360 #endif /* (CONFIG_BLK_DEV_IDEDMA) && !(CONFIG_DMA_NONPCI) */
361 
362         switch(speed) {
363                 case XFER_UDMA_7:   drive->id->dma_ultra |= 0x8080; break;
364                 case XFER_UDMA_6:   drive->id->dma_ultra |= 0x4040; break;
365                 case XFER_UDMA_5:   drive->id->dma_ultra |= 0x2020; break;
366                 case XFER_UDMA_4:   drive->id->dma_ultra |= 0x1010; break;
367                 case XFER_UDMA_3:   drive->id->dma_ultra |= 0x0808; break;
368                 case XFER_UDMA_2:   drive->id->dma_ultra |= 0x0404; break;
369                 case XFER_UDMA_1:   drive->id->dma_ultra |= 0x0202; break;
370                 case XFER_UDMA_0:   drive->id->dma_ultra |= 0x0101; break;
371                 case XFER_MW_DMA_2: drive->id->dma_mword |= 0x0404; break;
372                 case XFER_MW_DMA_1: drive->id->dma_mword |= 0x0202; break;
373                 case XFER_MW_DMA_0: drive->id->dma_mword |= 0x0101; break;
374                 case XFER_SW_DMA_2: drive->id->dma_1word |= 0x0404; break;
375                 case XFER_SW_DMA_1: drive->id->dma_1word |= 0x0202; break;
376                 case XFER_SW_DMA_0: drive->id->dma_1word |= 0x0101; break;
377                 default: break;
378         }
379         return error;
380 }
381 
382 EXPORT_SYMBOL(ide_auto_reduce_xfer);
383 EXPORT_SYMBOL(ide_driveid_update);
384 EXPORT_SYMBOL(ide_ata66_check);
385 EXPORT_SYMBOL(set_transfer);
386 EXPORT_SYMBOL(eighty_ninty_three);
387 EXPORT_SYMBOL(ide_config_drive_speed);
388 

~ [ 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.