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

Linux Cross Reference
Linux/drivers/ide/osb4.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/osb4.c           Version 0.2     17 Oct 2000
  3  *
  4  *  Copyright (C) 2000 Cobalt Networks, Inc. <asun@cobalt.com>
  5  *  May be copied or modified under the terms of the GNU General Public License
  6  *
  7  *  interface borrowed from alim15x3.c:
  8  *  Copyright (C) 1998-2000 Michel Aubry, Maintainer
  9  *  Copyright (C) 1998-2000 Andrzej Krzysztofowicz, Maintainer
 10  *
 11  *  Copyright (C) 1998-2000 Andre Hedrick <andre@linux-ide.org>
 12  *
 13  *  IDE support for the ServerWorks OSB4 IDE chipset
 14  *
 15  * here's the default lspci:
 16  *
 17  * 00:0f.1 IDE interface: ServerWorks: Unknown device 0211 (prog-if 8a [Master SecP PriP])
 18  *      Control: I/O+ Mem- BusMaster+ SpecCycle- MemWINV- VGASnoop- ParErr- Stepping- SERR+ FastB2B-
 19  *      Status: Cap- 66Mhz- UDF- FastB2B- ParErr- DEVSEL=medium >TAbort- <TAbort- <MAbort- >SERR- <PERR-
 20  *      Latency: 255
 21  *      Region 4: I/O ports at c200
 22  * 00: 66 11 11 02 05 01 00 02 00 8a 01 01 00 ff 80 00
 23  * 10: 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00
 24  * 20: 01 c2 00 00 00 00 00 00 00 00 00 00 00 00 00 00
 25  * 30: 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00
 26  * 40: 99 99 99 99 ff ff ff ff 0c 0c 00 00 00 00 00 00
 27  * 50: 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00
 28  * 60: 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00
 29  * 70: 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00
 30  * 80: 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00
 31  * 90: 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00
 32  * a0: 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00
 33  * b0: 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00
 34  * c0: 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00
 35  * d0: 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00
 36  * e0: 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00
 37  * f0: 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00
 38  *
 39  */
 40 
 41 #include <linux/config.h>
 42 #include <linux/types.h>
 43 #include <linux/kernel.h>
 44 #include <linux/ioport.h>
 45 #include <linux/pci.h>
 46 #include <linux/hdreg.h>
 47 #include <linux/ide.h>
 48 #include <linux/init.h>
 49 
 50 #include <asm/delay.h>
 51 #include <asm/io.h>
 52 
 53 #include "ide_modes.h"
 54 
 55 #define OSB4_DEBUG_DRIVE_INFO           0
 56 
 57 #define DISPLAY_OSB4_TIMINGS
 58 
 59 #if defined(DISPLAY_OSB4_TIMINGS) && defined(CONFIG_PROC_FS)
 60 #include <linux/stat.h>
 61 #include <linux/proc_fs.h>
 62 
 63 static struct pci_dev *bmide_dev;
 64 
 65 static int osb4_get_info(char *, char **, off_t, int);
 66 extern int (*osb4_display_info)(char *, char **, off_t, int); /* ide-proc.c */
 67 extern char *ide_media_verbose(ide_drive_t *);
 68 
 69 static int osb4_get_info (char *buffer, char **addr, off_t offset, int count)
 70 {
 71         char *p = buffer;
 72         u32 bibma = pci_resource_start(bmide_dev, 4);
 73         u16 reg56;
 74         u8  c0 = 0, c1 = 0, reg54;
 75 
 76         pci_read_config_byte(bmide_dev, 0x54, &reg54);
 77         pci_read_config_word(bmide_dev, 0x56, &reg56);
 78 
 79         /*
 80          * at that point bibma+0x2 et bibma+0xa are byte registers
 81          * to investigate:
 82          */
 83         c0 = inb_p((unsigned short)bibma + 0x02);
 84         c1 = inb_p((unsigned short)bibma + 0x0a);
 85 
 86         p += sprintf(p, "\n                                ServerWorks OSB4 Chipset.\n");
 87         p += sprintf(p, "--------------- Primary Channel ---------------- Secondary Channel -------------\n");
 88         p += sprintf(p, "                %sabled                         %sabled\n",
 89                         (c0&0x80) ? "dis" : " en",
 90                         (c1&0x80) ? "dis" : " en");
 91         p += sprintf(p, "--------------- drive0 --------- drive1 -------- drive0 ---------- drive1 ------\n");
 92         p += sprintf(p, "DMA enabled:    %s              %s             %s               %s\n",
 93                         (c0&0x20) ? "yes" : "no ",
 94                         (c0&0x40) ? "yes" : "no ",
 95                         (c1&0x20) ? "yes" : "no ",
 96                         (c1&0x40) ? "yes" : "no " );
 97         p += sprintf(p, "UDMA enabled:   %s              %s             %s               %s\n",
 98                         (reg54 & 0x01) ? "yes" : "no ",
 99                         (reg54 & 0x02) ? "yes" : "no ",
100                         (reg54 & 0x04) ? "yes" : "no ",
101                         (reg54 & 0x08) ? "yes" : "no " );
102         p += sprintf(p, "UDMA enabled:   %s                %s               %s                 %s\n",
103                      (reg56 & 0x0002) ? "2" : ((reg56 & 0x0001) ? "1" : 
104                                                ((reg56 & 0x000f) ? "X" : "")),
105                      (reg56 & 0x0020) ? "2" : ((reg56 & 0x0010) ? "1" : 
106                                                ((reg56 & 0x00f0) ? "X" : "")),
107                      (reg56 & 0x0200) ? "2" : ((reg56 & 0x0100) ? "1" : 
108                                                ((reg56 & 0x0f00) ? "X" : "")),
109                      (reg56 & 0x2000) ? "2" : ((reg56 & 0x1000) ? "1" : 
110                                                ((reg56 & 0xf000) ? "X" : "")));
111         return p-buffer;         /* => must be less than 4k! */
112 }
113 #endif  /* defined(DISPLAY_OSB4_TIMINGS) && defined(CONFIG_PROC_FS) */
114 
115 static byte osb4_revision = 0;
116 
117 byte osb4_proc = 0;
118 
119 extern char *ide_xfer_verbose (byte xfer_rate);
120 
121 static struct pci_dev *isa_dev;
122 
123 static int osb4_tune_chipset (ide_drive_t *drive, byte speed)
124 {
125         byte udma_modes[]       = { 0x00, 0x01, 0x02 };
126         byte dma_modes[]        = { 0x77, 0x21, 0x20 };
127         byte pio_modes[]        = { 0x5d, 0x47, 0x34, 0x22, 0x20 };
128 
129         ide_hwif_t *hwif        = HWIF(drive);
130         struct pci_dev *dev     = hwif->pci_dev;
131         byte unit               = (drive->select.b.unit & 0x01);
132 #ifdef CONFIG_BLK_DEV_IDEDMA
133         unsigned long dma_base  = hwif->dma_base;
134 #endif /* CONFIG_BLK_DEV_IDEDMA */
135         int err;
136 
137         byte drive_pci          = 0x00;
138         byte drive_pci2         = 0x00;
139         byte drive_pci3         = hwif->channel ? 0x57 : 0x56;
140 
141         byte ultra_enable       = 0x00;
142         byte ultra_timing       = 0x00;
143         byte dma_timing         = 0x00;
144         byte pio_timing         = 0x00;
145 
146         byte pio        = ide_get_best_pio_mode(drive, 255, 5, NULL);
147 
148         switch (drive->dn) {
149                 case 0: drive_pci = 0x41; drive_pci2 = 0x45; break;
150                 case 1: drive_pci = 0x40; drive_pci2 = 0x44; break;
151                 case 2: drive_pci = 0x43; drive_pci2 = 0x47; break;
152                 case 3: drive_pci = 0x42; drive_pci2 = 0x46; break;
153                 default:
154                         return -1;
155         }
156 
157         pci_read_config_byte(dev, drive_pci, &pio_timing);
158         pci_read_config_byte(dev, drive_pci2, &dma_timing);
159         pci_read_config_byte(dev, drive_pci3, &ultra_timing);
160         pci_read_config_byte(dev, 0x54, &ultra_enable);
161 
162 #ifdef DEBUG
163         printk("%s: UDMA 0x%02x DMAPIO 0x%02x PIO 0x%02x ",
164                 drive->name, ultra_timing, dma_timing, pio_timing);
165 #endif
166 
167         pio_timing      &= ~0xFF;
168         dma_timing      &= ~0xFF;
169         ultra_timing    &= ~(0x0F << (4*unit));
170         ultra_enable    &= ~(0x01 << drive->dn);
171 
172         switch(speed) {
173                 case XFER_PIO_4:
174                 case XFER_PIO_3:
175                 case XFER_PIO_2:
176                 case XFER_PIO_1:
177                 case XFER_PIO_0:
178                         pio_timing |= pio_modes[speed - XFER_PIO_0];
179                         break;
180 #ifdef CONFIG_BLK_DEV_IDEDMA
181                 case XFER_MW_DMA_2:
182                 case XFER_MW_DMA_1:
183                 case XFER_MW_DMA_0:
184                         pio_timing |= pio_modes[pio];
185                         dma_timing |= dma_modes[speed - XFER_MW_DMA_0];
186                         break;
187 
188 //              case XFER_UDMA_5:
189 //              case XFER_UDMA_4:
190 //              case XFER_UDMA_3:
191                 case XFER_UDMA_2:
192                 case XFER_UDMA_1:
193                 case XFER_UDMA_0:
194                         pio_timing |= pio_modes[pio];
195                         dma_timing |= dma_modes[2];
196                         ultra_timing |= ((udma_modes[speed - XFER_UDMA_0]) << (4*unit));
197                         ultra_enable |= (0x01 << drive->dn);
198 #endif
199                 default:
200                         break;
201         }
202 
203 #ifdef DEBUG
204         printk("%s: UDMA 0x%02x DMAPIO 0x%02x PIO 0x%02x ",
205                 drive->name, ultra_timing, dma_timing, pio_timing);
206 #endif
207 
208 #if OSB4_DEBUG_DRIVE_INFO
209         printk("%s: %s drive%d\n", drive->name, ide_xfer_verbose(speed), drive->dn);
210 #endif /* OSB4_DEBUG_DRIVE_INFO */
211 
212         if (!drive->init_speed)
213                 drive->init_speed = speed;
214 
215         pci_write_config_byte(dev, drive_pci, pio_timing);
216 #ifdef CONFIG_BLK_DEV_IDEDMA
217         pci_write_config_byte(dev, drive_pci2, dma_timing);
218         pci_write_config_byte(dev, drive_pci3, ultra_timing);
219         pci_write_config_byte(dev, 0x54, ultra_enable);
220         
221         if (speed > XFER_PIO_4) {
222                 outb(inb(dma_base+2)|(1<<(5+unit)), dma_base+2);
223         } else {
224                 outb(inb(dma_base+2) & ~(1<<(5+unit)), dma_base+2);
225         }
226 #endif /* CONFIG_BLK_DEV_IDEDMA */
227 
228         err = ide_config_drive_speed(drive, speed);
229         drive->current_speed = speed;
230         return err;
231 }
232 
233 static void config_chipset_for_pio (ide_drive_t *drive)
234 {
235         unsigned short eide_pio_timing[6] = {960, 480, 240, 180, 120, 90};
236         unsigned short xfer_pio = drive->id->eide_pio_modes;
237         byte                    timing, speed, pio;
238 
239         pio = ide_get_best_pio_mode(drive, 255, 5, NULL);
240 
241         if (xfer_pio> 4)
242                 xfer_pio = 0;
243 
244         if (drive->id->eide_pio_iordy > 0) {
245                 for (xfer_pio = 5;
246                         xfer_pio>0 &&
247                         drive->id->eide_pio_iordy>eide_pio_timing[xfer_pio];
248                         xfer_pio--);
249         } else {
250                 xfer_pio = (drive->id->eide_pio_modes & 4) ? 0x05 :
251                            (drive->id->eide_pio_modes & 2) ? 0x04 :
252                            (drive->id->eide_pio_modes & 1) ? 0x03 :
253                            (drive->id->tPIO & 2) ? 0x02 :
254                            (drive->id->tPIO & 1) ? 0x01 : xfer_pio;
255         }
256 
257         timing = (xfer_pio >= pio) ? xfer_pio : pio;
258 
259         switch(timing) {
260                 case 4: speed = XFER_PIO_4;break;
261                 case 3: speed = XFER_PIO_3;break;
262                 case 2: speed = XFER_PIO_2;break;
263                 case 1: speed = XFER_PIO_1;break;
264                 default:
265                         speed = (!drive->id->tPIO) ? XFER_PIO_0 : XFER_PIO_SLOW;
266                         break;
267         }
268         (void) osb4_tune_chipset(drive, speed);
269         drive->current_speed = speed;
270 }
271 
272 static void osb4_tune_drive (ide_drive_t *drive, byte pio)
273 {
274         byte speed;
275         switch(pio) {
276                 case 4:         speed = XFER_PIO_4;break;
277                 case 3:         speed = XFER_PIO_3;break;
278                 case 2:         speed = XFER_PIO_2;break;
279                 case 1:         speed = XFER_PIO_1;break;
280                 default:        speed = XFER_PIO_0;break;
281         }
282         (void) osb4_tune_chipset(drive, speed);
283 }
284 
285 #ifdef CONFIG_BLK_DEV_IDEDMA
286 static int config_chipset_for_dma (ide_drive_t *drive)
287 {
288         struct hd_driveid *id   = drive->id;
289         byte                    speed;
290 
291 #if 0
292         byte udma_66            = eighty_ninty_three(drive);
293         /* need specs to figure out if osb4 is capable of ata/66/100 */
294         int ultra100            = 0;
295         int ultra66             = 0;
296 
297         if ((id->dma_ultra & 0x0020) && (udma_66) && (ultra100)) {
298                 speed = XFER_UDMA_5;
299         } else if (id->dma_ultra & 0x0010) {
300                 speed = ((udma_66) && (ultra66)) ? XFER_UDMA_4 : XFER_UDMA_2;
301         } else if (id->dma_ultra & 0x0008) {
302                 speed = ((udma_66) && (ultra66)) ? XFER_UDMA_3 : XFER_UDMA_1;
303         } else if (id->dma_ultra & 0x0004) {
304 #else
305         if (id->dma_ultra & 0x0004) {
306 #endif
307                 speed = XFER_UDMA_2;
308         } else if (id->dma_ultra & 0x0002) {
309                 speed = XFER_UDMA_1;
310         } else if (id->dma_ultra & 0x0001) {
311                 speed = XFER_UDMA_0;
312         } else if (id->dma_mword & 0x0004) {
313                 speed = XFER_MW_DMA_2;
314         } else if (id->dma_mword & 0x0002) {
315                 speed = XFER_MW_DMA_1;
316         } else if (id->dma_1word & 0x0004) {
317                 speed = XFER_SW_DMA_2;
318         } else {
319                 speed = XFER_PIO_0 + ide_get_best_pio_mode(drive, 255, 5, NULL);
320         }
321 
322         (void) osb4_tune_chipset(drive, speed);
323 
324         return ((int)   ((id->dma_ultra >> 11) & 7) ? ide_dma_on :
325                         ((id->dma_ultra >> 8) & 7) ? ide_dma_on :
326                         ((id->dma_mword >> 8) & 7) ? ide_dma_on :
327                         ((id->dma_1word >> 8) & 7) ? ide_dma_on :
328                                                      ide_dma_off_quietly);
329 }
330 
331 static int config_drive_xfer_rate (ide_drive_t *drive)
332 {
333         struct hd_driveid *id = drive->id;
334         ide_dma_action_t dma_func = ide_dma_on;
335 
336         if (id && (id->capability & 1) && HWIF(drive)->autodma) {
337                 /* Consult the list of known "bad" drives */
338                 if (ide_dmaproc(ide_dma_bad_drive, drive)) {
339                         dma_func = ide_dma_off;
340                         goto fast_ata_pio;
341                 }
342                 dma_func = ide_dma_off_quietly;
343                 if (id->field_valid & 4) {
344                         if (id->dma_ultra & 0x002F) {
345                                 /* Force if Capable UltraDMA */
346                                 dma_func = config_chipset_for_dma(drive);
347                                 if ((id->field_valid & 2) &&
348                                     (dma_func != ide_dma_on))
349                                         goto try_dma_modes;
350                         }
351                 } else if (id->field_valid & 2) {
352 try_dma_modes:
353                         if ((id->dma_mword & 0x0007) ||
354                             (id->dma_1word & 0x007)) {
355                                 /* Force if Capable regular DMA modes */
356                                 dma_func = config_chipset_for_dma(drive);
357                                 if (dma_func != ide_dma_on)
358                                         goto no_dma_set;
359                         }
360                 } else if (ide_dmaproc(ide_dma_good_drive, drive)) {
361                         if (id->eide_dma_time > 150) {
362                                 goto no_dma_set;
363                         }
364                         /* Consult the list of known "good" drives */
365                         dma_func = config_chipset_for_dma(drive);
366                         if (dma_func != ide_dma_on)
367                                 goto no_dma_set;
368                 } else {
369                         goto fast_ata_pio;
370                 }
371         } else if ((id->capability & 8) || (id->field_valid & 2)) {
372 fast_ata_pio:
373                 dma_func = ide_dma_off_quietly;
374 no_dma_set:
375                 config_chipset_for_pio(drive);
376         }
377         return HWIF(drive)->dmaproc(dma_func, drive);
378 }
379 
380 static int osb4_dmaproc(ide_dma_action_t func, ide_drive_t *drive)
381 {
382         switch (func) {
383                 case ide_dma_check:
384                         return config_drive_xfer_rate(drive);
385                 default :
386                         break;
387         }
388         /* Other cases are done by generic IDE-DMA code. */
389         return ide_dmaproc(func, drive);
390 }
391 #endif /* CONFIG_BLK_DEV_IDEDMA */
392 
393 unsigned int __init pci_init_osb4 (struct pci_dev *dev, const char *name)
394 {
395         unsigned int reg64;
396 
397         pci_read_config_byte(dev, PCI_REVISION_ID, &osb4_revision);
398 
399         isa_dev = pci_find_device(PCI_VENDOR_ID_SERVERWORKS, PCI_DEVICE_ID_SERVERWORKS_OSB4, NULL);
400 
401         pci_read_config_dword(isa_dev, 0x64, &reg64);
402 #ifdef DEBUG
403         printk("%s: reg64 == 0x%08x\n", name, reg64);
404 #endif
405         reg64 &= ~0x0000A000;
406 #ifdef CONFIG_SMP
407         reg64 |= 0x00008000;
408 #endif
409         pci_write_config_dword(isa_dev, 0x64, reg64);
410 
411         pci_write_config_byte(dev, PCI_LATENCY_TIMER, 0x40);
412 
413 #if defined(DISPLAY_OSB4_TIMINGS) && defined(CONFIG_PROC_FS)
414         if (!osb4_proc) {
415                 osb4_proc = 1;
416                 bmide_dev = dev;
417                 osb4_display_info = &osb4_get_info;
418         }
419 #endif /* DISPLAY_OSB4_TIMINGS && CONFIG_PROC_FS */
420         return 0;
421 }
422 
423 unsigned int __init ata66_osb4 (ide_hwif_t *hwif)
424 {
425         return 0;
426 }
427 
428 void __init ide_init_osb4 (ide_hwif_t *hwif)
429 {
430         if (!hwif->irq)
431                 hwif->irq = hwif->channel ? 15 : 14;
432 
433         hwif->tuneproc = &osb4_tune_drive;
434         hwif->speedproc = &osb4_tune_chipset;
435 
436 #ifndef CONFIG_BLK_DEV_IDEDMA
437         hwif->drives[0].autotune = 1;
438         hwif->drives[1].autotune = 1;
439         hwif->autodma = 0;
440         return;
441 #else /* CONFIG_BLK_DEV_IDEDMA */
442 
443         if (hwif->dma_base) {
444                 hwif->autodma = 1;
445                 hwif->dmaproc = &osb4_dmaproc;
446         } else {
447                 hwif->autodma = 0;
448                 hwif->drives[0].autotune = 1;
449                 hwif->drives[1].autotune = 1;
450         }
451 #endif /* !CONFIG_BLK_DEV_IDEDMA */
452 }
453 

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