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

Linux Cross Reference
Linux/include/asm-sparc64/floppy.h

Version: ~ [ 2.4.0 ] ~
Architecture: ~ [ i386 ] ~ [ alpha ] ~ [ m68k ] ~ [ mips ] ~ [ ppc ] ~ [ sparc ] ~ [ sparc64 ] ~

  1 /* $Id: floppy.h,v 1.28 2000/02/18 13:50:54 davem Exp $
  2  * asm-sparc64/floppy.h: Sparc specific parts of the Floppy driver.
  3  *
  4  * Copyright (C) 1996 David S. Miller (davem@caip.rutgers.edu)
  5  * Copyright (C) 1997 Jakub Jelinek (jj@sunsite.mff.cuni.cz)
  6  *
  7  * Ultra/PCI support added: Sep 1997  Eddie C. Dost  (ecd@skynet.be)
  8  */
  9 
 10 #ifndef __ASM_SPARC64_FLOPPY_H
 11 #define __ASM_SPARC64_FLOPPY_H
 12 
 13 #include <linux/config.h>
 14 #include <linux/init.h>
 15 
 16 #include <asm/page.h>
 17 #include <asm/pgtable.h>
 18 #include <asm/system.h>
 19 #include <asm/idprom.h>
 20 #include <asm/oplib.h>
 21 #include <asm/auxio.h>
 22 #include <asm/sbus.h>
 23 #include <asm/irq.h>
 24 
 25 
 26 /*
 27  * Define this to enable exchanging drive 0 and 1 if only drive 1 is
 28  * probed on PCI machines.
 29  */
 30 #undef PCI_FDC_SWAP_DRIVES
 31 
 32 
 33 /* References:
 34  * 1) Netbsd Sun floppy driver.
 35  * 2) NCR 82077 controller manual
 36  * 3) Intel 82077 controller manual
 37  */
 38 struct sun_flpy_controller {
 39         volatile unsigned char status1_82077; /* Auxiliary Status reg. 1 */
 40         volatile unsigned char status2_82077; /* Auxiliary Status reg. 2 */
 41         volatile unsigned char dor_82077;     /* Digital Output reg. */
 42         volatile unsigned char tapectl_82077; /* Tape Control reg */
 43         volatile unsigned char status_82077;  /* Main Status Register. */
 44 #define drs_82077              status_82077   /* Digital Rate Select reg. */
 45         volatile unsigned char data_82077;    /* Data fifo. */
 46         volatile unsigned char ___unused;
 47         volatile unsigned char dir_82077;     /* Digital Input reg. */
 48 #define dcr_82077              dir_82077      /* Config Control reg. */
 49 };
 50 
 51 /* You'll only ever find one controller on an Ultra anyways. */
 52 static struct sun_flpy_controller *sun_fdc = (struct sun_flpy_controller *)-1;
 53 unsigned long fdc_status;
 54 static struct sbus_dev *floppy_sdev = NULL;
 55 
 56 struct sun_floppy_ops {
 57         unsigned char   (*fd_inb) (unsigned long port);
 58         void            (*fd_outb) (unsigned char value, unsigned long port);
 59         void            (*fd_enable_dma) (void);
 60         void            (*fd_disable_dma) (void);
 61         void            (*fd_set_dma_mode) (int);
 62         void            (*fd_set_dma_addr) (char *);
 63         void            (*fd_set_dma_count) (int);
 64         unsigned int    (*get_dma_residue) (void);
 65         void            (*fd_enable_irq) (void);
 66         void            (*fd_disable_irq) (void);
 67         int             (*fd_request_irq) (void);
 68         void            (*fd_free_irq) (void);
 69         int             (*fd_eject) (int);
 70 };
 71 
 72 static struct sun_floppy_ops sun_fdops;
 73 
 74 #define fd_inb(port)              sun_fdops.fd_inb(port)
 75 #define fd_outb(value,port)       sun_fdops.fd_outb(value,port)
 76 #define fd_enable_dma()           sun_fdops.fd_enable_dma()
 77 #define fd_disable_dma()          sun_fdops.fd_disable_dma()
 78 #define fd_request_dma()          (0) /* nothing... */
 79 #define fd_free_dma()             /* nothing... */
 80 #define fd_clear_dma_ff()         /* nothing... */
 81 #define fd_set_dma_mode(mode)     sun_fdops.fd_set_dma_mode(mode)
 82 #define fd_set_dma_addr(addr)     sun_fdops.fd_set_dma_addr(addr)
 83 #define fd_set_dma_count(count)   sun_fdops.fd_set_dma_count(count)
 84 #define get_dma_residue(x)        sun_fdops.get_dma_residue()
 85 #define fd_enable_irq()           sun_fdops.fd_enable_irq()
 86 #define fd_disable_irq()          sun_fdops.fd_disable_irq()
 87 #define fd_cacheflush(addr, size) /* nothing... */
 88 #define fd_request_irq()          sun_fdops.fd_request_irq()
 89 #define fd_free_irq()             sun_fdops.fd_free_irq()
 90 #define fd_eject(drive)           sun_fdops.fd_eject(drive)
 91 
 92 static int FLOPPY_MOTOR_MASK = 0x10;
 93 
 94 /* Super paranoid... */
 95 #undef HAVE_DISABLE_HLT
 96 
 97 static int sun_floppy_types[2] = { 0, 0 };
 98 
 99 /* Here is where we catch the floppy driver trying to initialize,
100  * therefore this is where we call the PROM device tree probing
101  * routine etc. on the Sparc.
102  */
103 #define FLOPPY0_TYPE            sun_floppy_init()
104 #define FLOPPY1_TYPE            sun_floppy_types[1]
105 
106 #define FDC1                    ((unsigned long)sun_fdc)
107 static int FDC2 =               -1;
108 
109 #define N_FDC    1
110 #define N_DRIVE  8
111 
112 /* No 64k boundary crossing problems on the Sparc. */
113 #define CROSS_64KB(a,s) (0)
114 
115 static unsigned char sun_82077_fd_inb(unsigned long port)
116 {
117         udelay(5);
118         switch(port & 7) {
119         default:
120                 printk("floppy: Asked to read unknown port %lx\n", port);
121                 panic("floppy: Port bolixed.");
122         case 4: /* FD_STATUS */
123                 return sbus_readb(&sun_fdc->status_82077) & ~STATUS_DMA;
124         case 5: /* FD_DATA */
125                 return sbus_readb(&sun_fdc->data_82077);
126         case 7: /* FD_DIR */
127                 /* XXX: Is DCL on 0x80 in sun4m? */
128                 return sbus_readb(&sun_fdc->dir_82077);
129         };
130         panic("sun_82072_fd_inb: How did I get here?");
131 }
132 
133 static void sun_82077_fd_outb(unsigned char value, unsigned long port)
134 {
135         udelay(5);
136         switch(port & 7) {
137         default:
138                 printk("floppy: Asked to write to unknown port %lx\n", port);
139                 panic("floppy: Port bolixed.");
140         case 2: /* FD_DOR */
141                 /* Happily, the 82077 has a real DOR register. */
142                 sbus_writeb(value, &sun_fdc->dor_82077);
143                 break;
144         case 5: /* FD_DATA */
145                 sbus_writeb(value, &sun_fdc->data_82077);
146                 break;
147         case 7: /* FD_DCR */
148                 sbus_writeb(value, &sun_fdc->dcr_82077);
149                 break;
150         case 4: /* FD_STATUS */
151                 sbus_writeb(value, &sun_fdc->status_82077);
152                 break;
153         };
154         return;
155 }
156 
157 /* For pseudo-dma (Sun floppy drives have no real DMA available to
158  * them so we must eat the data fifo bytes directly ourselves) we have
159  * three state variables.  doing_pdma tells our inline low-level
160  * assembly floppy interrupt entry point whether it should sit and eat
161  * bytes from the fifo or just transfer control up to the higher level
162  * floppy interrupt c-code.  I tried very hard but I could not get the
163  * pseudo-dma to work in c-code without getting many overruns and
164  * underruns.  If non-zero, doing_pdma encodes the direction of
165  * the transfer for debugging.  1=read 2=write
166  */
167 char *pdma_vaddr;
168 unsigned long pdma_size;
169 volatile int doing_pdma = 0;
170 
171 /* This is software state */
172 char *pdma_base = 0;
173 unsigned long pdma_areasize;
174 
175 /* Common routines to all controller types on the Sparc. */
176 static __inline__ void virtual_dma_init(void)
177 {
178         /* nothing... */
179 }
180 
181 static void sun_fd_disable_dma(void)
182 {
183         doing_pdma = 0;
184         if (pdma_base) {
185                 mmu_unlockarea(pdma_base, pdma_areasize);
186                 pdma_base = 0;
187         }
188 }
189 
190 static void sun_fd_set_dma_mode(int mode)
191 {
192         switch(mode) {
193         case DMA_MODE_READ:
194                 doing_pdma = 1;
195                 break;
196         case DMA_MODE_WRITE:
197                 doing_pdma = 2;
198                 break;
199         default:
200                 printk("Unknown dma mode %d\n", mode);
201                 panic("floppy: Giving up...");
202         }
203 }
204 
205 static void sun_fd_set_dma_addr(char *buffer)
206 {
207         pdma_vaddr = buffer;
208 }
209 
210 static void sun_fd_set_dma_count(int length)
211 {
212         pdma_size = length;
213 }
214 
215 static void sun_fd_enable_dma(void)
216 {
217         pdma_vaddr = mmu_lockarea(pdma_vaddr, pdma_size);
218         pdma_base = pdma_vaddr;
219         pdma_areasize = pdma_size;
220 }
221 
222 /* Our low-level entry point in arch/sparc/kernel/entry.S */
223 extern void floppy_hardint(int irq, void *unused, struct pt_regs *regs);
224 
225 static int sun_fd_request_irq(void)
226 {
227         static int once = 0;
228         int error;
229 
230         if(!once) {
231                 once = 1;
232 
233                 error = request_fast_irq(FLOPPY_IRQ, floppy_hardint, 
234                                         SA_INTERRUPT, "floppy", NULL);
235 
236                 return ((error == 0) ? 0 : -1);
237         }
238         return 0;
239 }
240 
241 static void sun_fd_enable_irq(void)
242 {
243 }
244 
245 static void sun_fd_disable_irq(void)
246 {
247 }
248 
249 static void sun_fd_free_irq(void)
250 {
251 }
252 
253 static unsigned int sun_get_dma_residue(void)
254 {
255         /* XXX This isn't really correct. XXX */
256         return 0;
257 }
258 
259 static int sun_fd_eject(int drive)
260 {
261         set_dor(0x00, 0xff, 0x90);
262         udelay(500);
263         set_dor(0x00, 0x6f, 0x00);
264         udelay(500);
265         return 0;
266 }
267 
268 #ifdef CONFIG_PCI
269 #include <asm/ebus.h>
270 #include <asm/ns87303.h>
271 
272 static struct linux_ebus_dma *sun_pci_fd_ebus_dma;
273 static struct pci_dev *sun_pci_ebus_dev;
274 static int sun_pci_broken_drive = -1;
275 static unsigned int sun_pci_dma_addr = -1U;
276 static int sun_pci_dma_len, sun_pci_dma_direction;
277 
278 extern void floppy_interrupt(int irq, void *dev_id, struct pt_regs *regs);
279 
280 static unsigned char sun_pci_fd_inb(unsigned long port)
281 {
282         udelay(5);
283         return inb(port);
284 }
285 
286 static void sun_pci_fd_outb(unsigned char val, unsigned long port)
287 {
288         udelay(5);
289         outb(val, port);
290 }
291 
292 static void sun_pci_fd_broken_outb(unsigned char val, unsigned long port)
293 {
294         udelay(5);
295         /*
296          * XXX: Due to SUN's broken floppy connector on AX and AXi
297          *      we need to turn on MOTOR_0 also, if the floppy is
298          *      jumpered to DS1 (like most PC floppies are). I hope
299          *      this does not hurt correct hardware like the AXmp.
300          *      (Eddie, Sep 12 1998).
301          */
302         if (port == ((unsigned long)sun_fdc) + 2) {
303                 if (((val & 0x03) == sun_pci_broken_drive) && (val & 0x20)) {
304                         val |= 0x10;
305                 }
306         }
307         outb(val, port);
308 }
309 
310 #ifdef PCI_FDC_SWAP_DRIVES
311 static void sun_pci_fd_lde_broken_outb(unsigned char val, unsigned long port)
312 {
313         udelay(5);
314         /*
315          * XXX: Due to SUN's broken floppy connector on AX and AXi
316          *      we need to turn on MOTOR_0 also, if the floppy is
317          *      jumpered to DS1 (like most PC floppies are). I hope
318          *      this does not hurt correct hardware like the AXmp.
319          *      (Eddie, Sep 12 1998).
320          */
321         if (port == ((unsigned long)sun_fdc) + 2) {
322                 if (((val & 0x03) == sun_pci_broken_drive) && (val & 0x10)) {
323                         val &= ~(0x03);
324                         val |= 0x21;
325                 }
326         }
327         outb(val, port);
328 }
329 #endif /* PCI_FDC_SWAP_DRIVES */
330 
331 static void sun_pci_fd_reset_dma(void)
332 {
333         unsigned int dcsr;
334 
335         writel(EBUS_DCSR_RESET, &sun_pci_fd_ebus_dma->dcsr);
336         udelay(1);
337         dcsr = EBUS_DCSR_BURST_SZ_16 | EBUS_DCSR_TCI_DIS |
338                EBUS_DCSR_EN_CNT;
339         writel(dcsr, (unsigned long)&sun_pci_fd_ebus_dma->dcsr);
340 }
341 
342 static void sun_pci_fd_enable_dma(void)
343 {
344         unsigned int dcsr;
345 
346         dcsr = readl(&sun_pci_fd_ebus_dma->dcsr);
347         dcsr |= EBUS_DCSR_EN_DMA;
348         writel(dcsr, &sun_pci_fd_ebus_dma->dcsr);
349 }
350 
351 static void sun_pci_fd_disable_dma(void)
352 {
353         unsigned int dcsr;
354 
355         dcsr = readl(&sun_pci_fd_ebus_dma->dcsr);
356         if (dcsr & EBUS_DCSR_EN_DMA) {
357                 while (dcsr & EBUS_DCSR_DRAIN) {
358                         udelay(1);
359                         dcsr = readl(&sun_pci_fd_ebus_dma->dcsr);
360                 }
361                 dcsr &= ~(EBUS_DCSR_EN_DMA);
362                 writel(dcsr, &sun_pci_fd_ebus_dma->dcsr);
363                 if (dcsr & EBUS_DCSR_ERR_PEND) {
364                         sun_pci_fd_reset_dma();
365                         dcsr &= ~(EBUS_DCSR_ERR_PEND);
366                         writel(dcsr, &sun_pci_fd_ebus_dma->dcsr);
367                 }
368         }
369         if (sun_pci_dma_addr != -1U)
370                 pci_unmap_single(sun_pci_ebus_dev,
371                                  sun_pci_dma_addr,
372                                  sun_pci_dma_len,
373                                  sun_pci_dma_direction);
374         sun_pci_dma_addr = -1U;
375 }
376 
377 static void sun_pci_fd_set_dma_mode(int mode)
378 {
379         unsigned int dcsr;
380 
381         dcsr = readl(&sun_pci_fd_ebus_dma->dcsr);
382         if (readl(&sun_pci_fd_ebus_dma->dbcr)) {
383                 sun_pci_fd_reset_dma();
384                 writel(dcsr, &sun_pci_fd_ebus_dma->dcsr);
385         }
386 
387         dcsr |= EBUS_DCSR_EN_CNT | EBUS_DCSR_TC;
388         /*
389          * For EBus WRITE means to system memory, which is
390          * READ for us.
391          */
392         if (mode == DMA_MODE_WRITE) {
393                 dcsr &= ~(EBUS_DCSR_WRITE);
394                 sun_pci_dma_direction = PCI_DMA_TODEVICE;
395         } else {
396                 dcsr |= EBUS_DCSR_WRITE;
397                 sun_pci_dma_direction = PCI_DMA_FROMDEVICE;
398         }
399         writel(dcsr, &sun_pci_fd_ebus_dma->dcsr);
400 }
401 
402 static void sun_pci_fd_set_dma_count(int length)
403 {
404         sun_pci_dma_len = length;
405         writel(length, &sun_pci_fd_ebus_dma->dbcr);
406 }
407 
408 static void sun_pci_fd_set_dma_addr(char *buffer)
409 {
410         unsigned int addr;
411 
412         addr = sun_pci_dma_addr = pci_map_single(sun_pci_ebus_dev,
413                                                  buffer,
414                                                  sun_pci_dma_len,
415                                                  sun_pci_dma_direction);
416         writel(addr, &sun_pci_fd_ebus_dma->dacr);
417 }
418 
419 static unsigned int sun_pci_get_dma_residue(void)
420 {
421         unsigned int dcsr, res;
422 
423         res = readl(&sun_pci_fd_ebus_dma->dbcr);
424         if (res != 0) {
425                 dcsr = readl(&sun_pci_fd_ebus_dma->dcsr);
426                 sun_pci_fd_reset_dma();
427                 writel(dcsr, &sun_pci_fd_ebus_dma->dcsr);
428         }
429         return res;
430 }
431 
432 static void sun_pci_fd_enable_irq(void)
433 {
434         unsigned int dcsr;
435 
436         dcsr = readl(&sun_pci_fd_ebus_dma->dcsr);
437         dcsr |= EBUS_DCSR_INT_EN;
438         writel(dcsr, &sun_pci_fd_ebus_dma->dcsr);
439 }
440 
441 static void sun_pci_fd_disable_irq(void)
442 {
443         unsigned int dcsr;
444 
445         dcsr = readl(&sun_pci_fd_ebus_dma->dcsr);
446         dcsr &= ~(EBUS_DCSR_INT_EN);
447         writel(dcsr, &sun_pci_fd_ebus_dma->dcsr);
448 }
449 
450 static int sun_pci_fd_request_irq(void)
451 {
452         int err;
453 
454         err = request_irq(FLOPPY_IRQ, floppy_interrupt, SA_SHIRQ,
455                           "floppy", sun_fdc);
456         if (err)
457                 return -1;
458         sun_pci_fd_enable_irq();
459         return 0;
460 }
461 
462 static void sun_pci_fd_free_irq(void)
463 {
464         sun_pci_fd_disable_irq();
465         free_irq(FLOPPY_IRQ, sun_fdc);
466 }
467 
468 static int sun_pci_fd_eject(int drive)
469 {
470         return -EINVAL;
471 }
472 
473 
474 /*
475  * Floppy probing, we'd like to use /dev/fd0 for a single Floppy on PCI,
476  * even if this is configured using DS1, thus looks like /dev/fd1 with
477  * the cabling used in Ultras.
478  */
479 #define DOR     (port + 2)
480 #define MSR     (port + 4)
481 #define FIFO    (port + 5)
482 
483 static void sun_pci_fd_out_byte(unsigned long port, unsigned char val,
484                                 unsigned long reg)
485 {
486         unsigned char status;
487         int timeout = 1000;
488 
489         while (!((status = inb(MSR)) & 0x80) && --timeout)
490                 udelay(100);
491         outb(val, reg);
492 }
493 
494 static unsigned char sun_pci_fd_sensei(unsigned long port)
495 {
496         unsigned char result[2] = { 0x70, 0x00 };
497         unsigned char status;
498         int i = 0;
499 
500         sun_pci_fd_out_byte(port, 0x08, FIFO);
501         do {
502                 int timeout = 1000;
503 
504                 while (!((status = inb(MSR)) & 0x80) && --timeout)
505                         udelay(100);
506 
507                 if (!timeout)
508                         break;
509 
510                 if ((status & 0xf0) == 0xd0)
511                         result[i++] = inb(FIFO);
512                 else
513                         break;
514         } while (i < 2);
515 
516         return result[0];
517 }
518 
519 static void sun_pci_fd_reset(unsigned long port)
520 {
521         unsigned char mask = 0x00;
522         unsigned char status;
523         int timeout = 10000;
524 
525         outb(0x80, MSR);
526         do {
527                 status = sun_pci_fd_sensei(port);
528                 if ((status & 0xc0) == 0xc0)
529                         mask |= 1 << (status & 0x03);
530                 else
531                         udelay(100);
532         } while ((mask != 0x0f) && --timeout);
533 }
534 
535 static int sun_pci_fd_test_drive(unsigned long port, int drive)
536 {
537         unsigned char status, data;
538         int timeout = 1000;
539         int ready;
540 
541         sun_pci_fd_reset(port);
542 
543         data = (0x10 << drive) | 0x0c | drive;
544         sun_pci_fd_out_byte(port, data, DOR);
545 
546         sun_pci_fd_out_byte(port, 0x07, FIFO);
547         sun_pci_fd_out_byte(port, drive & 0x03, FIFO);
548 
549         do {
550                 udelay(100);
551                 status = sun_pci_fd_sensei(port);
552         } while (((status & 0xc0) == 0x80) && --timeout);
553 
554         if (!timeout)
555                 ready = 0;
556         else
557                 ready = (status & 0x10) ? 0 : 1;
558 
559         sun_pci_fd_reset(port);
560         return ready;
561 }
562 #undef FIFO
563 #undef MSR
564 #undef DOR
565 
566 #endif /* CONFIG_PCI */
567 
568 static unsigned long __init sun_floppy_init(void)
569 {
570         char state[128];
571         struct sbus_bus *bus;
572         struct sbus_dev *sdev = NULL;
573         static int initialized = 0;
574 
575         if (initialized)
576                 return sun_floppy_types[0];
577         initialized = 1;
578 
579         for_all_sbusdev (sdev, bus) {
580                 if (!strcmp(sdev->prom_name, "SUNW,fdtwo")) 
581                         break;
582         }
583         if(sdev) {
584                 floppy_sdev = sdev;
585                 FLOPPY_IRQ = sdev->irqs[0];
586         } else {
587 #ifdef CONFIG_PCI
588                 struct linux_ebus *ebus;
589                 struct linux_ebus_device *edev = 0;
590                 unsigned long config = 0;
591                 unsigned long auxio_reg;
592 
593                 for_each_ebus(ebus) {
594                         for_each_ebusdev(edev, ebus) {
595                                 if (!strcmp(edev->prom_name, "fdthree"))
596                                         goto ebus_done;
597                         }
598                 }
599         ebus_done:
600                 if (!edev)
601                         return 0;
602 
603                 prom_getproperty(edev->prom_node, "status",
604                                  state, sizeof(state));
605                 if(!strncmp(state, "disabled", 8))
606                         return 0;
607                         
608                 sun_fdc = (struct sun_flpy_controller *)edev->resource[0].start;
609                 FLOPPY_IRQ = edev->irqs[0];
610 
611                 /* Make sure the high density bit is set, some systems
612                  * (most notably Ultra5/Ultra10) come up with it clear.
613                  */
614                 auxio_reg = edev->resource[2].start;
615                 writel(readl(auxio_reg)|0x2, auxio_reg);
616 
617                 sun_pci_ebus_dev = ebus->self;
618 
619                 sun_pci_fd_ebus_dma = (struct linux_ebus_dma *)
620                         edev->resource[1].start;
621                 sun_pci_fd_reset_dma();
622 
623                 sun_fdops.fd_inb = sun_pci_fd_inb;
624                 sun_fdops.fd_outb = sun_pci_fd_outb;
625 
626                 use_virtual_dma = 0;
627                 sun_fdops.fd_enable_dma = sun_pci_fd_enable_dma;
628                 sun_fdops.fd_disable_dma = sun_pci_fd_disable_dma;
629                 sun_fdops.fd_set_dma_mode = sun_pci_fd_set_dma_mode;
630                 sun_fdops.fd_set_dma_addr = sun_pci_fd_set_dma_addr;
631                 sun_fdops.fd_set_dma_count = sun_pci_fd_set_dma_count;
632                 sun_fdops.get_dma_residue = sun_pci_get_dma_residue;
633 
634                 sun_fdops.fd_enable_irq = sun_pci_fd_enable_irq;
635                 sun_fdops.fd_disable_irq = sun_pci_fd_disable_irq;
636                 sun_fdops.fd_request_irq = sun_pci_fd_request_irq;
637                 sun_fdops.fd_free_irq = sun_pci_fd_free_irq;
638 
639                 sun_fdops.fd_eject = sun_pci_fd_eject;
640 
641                 fdc_status = (unsigned long) &sun_fdc->status_82077;
642                 FLOPPY_MOTOR_MASK = 0xf0;
643 
644                 /*
645                  * XXX: Find out on which machines this is really needed.
646                  */
647                 if (1) {
648                         sun_pci_broken_drive = 1;
649                         sun_fdops.fd_outb = sun_pci_fd_broken_outb;
650                 }
651 
652                 allowed_drive_mask = 0;
653                 if (sun_pci_fd_test_drive((unsigned long)sun_fdc, 0))
654                         sun_floppy_types[0] = 4;
655                 if (sun_pci_fd_test_drive((unsigned long)sun_fdc, 1))
656                         sun_floppy_types[1] = 4;
657 
658                 /*
659                  * Find NS87303 SuperIO config registers (through ecpp).
660                  */
661                 for_each_ebus(ebus) {
662                         for_each_ebusdev(edev, ebus) {
663                                 if (!strcmp(edev->prom_name, "ecpp")) {
664                                         config = edev->resource[1].start;
665                                         goto config_done;
666                                 }
667                         }
668                 }
669         config_done:
670 
671                 /*
672                  * Sanity check, is this really the NS87303?
673                  */
674                 switch (config & 0x3ff) {
675                 case 0x02e:
676                 case 0x15c:
677                 case 0x26e:
678                 case 0x398:
679                         break;
680                 default:
681                         config = 0;
682                 }
683 
684                 if (!config)
685                         return sun_floppy_types[0];
686 
687                 /* Enable PC-AT mode. */
688                 ns87303_modify(config, ASC, 0, 0xc0);
689 
690 #ifdef PCI_FDC_SWAP_DRIVES
691                 /*
692                  * If only Floppy 1 is present, swap drives.
693                  */
694                 if (!sun_floppy_types[0] && sun_floppy_types[1]) {
695                         /*
696                          * Set the drive exchange bit in FCR on NS87303,
697                          * make shure other bits are sane before doing so.
698                          */
699                         ns87303_modify(config, FER, FER_EDM, 0);
700                         ns87303_modify(config, ASC, ASC_DRV2_SEL, 0);
701                         ns87303_modify(config, FCR, 0, FCR_LDE);
702 
703                         cfg = sun_floppy_types[0];
704                         sun_floppy_types[0] = sun_floppy_types[1];
705                         sun_floppy_types[1] = cfg;
706 
707                         if (sun_pci_broken_drive != -1) {
708                                 sun_pci_broken_drive = 1 - sun_pci_broken_drive;
709                                 sun_fdops.fd_outb = sun_pci_fd_lde_broken_outb;
710                         }
711                 }
712 #endif /* PCI_FDC_SWAP_DRIVES */
713 
714                 return sun_floppy_types[0];
715 #else
716                 return 0;
717 #endif
718         }
719         prom_getproperty(sdev->prom_node, "status", state, sizeof(state));
720         if(!strncmp(state, "disabled", 8))
721                 return 0;
722 
723         /*
724          * We cannot do sbus_ioremap here: it does request_region,
725          * which the generic floppy driver tries to do once again.
726          * But we must use the sdev resource values as they have
727          * had parent ranges applied.
728          */
729         sun_fdc = (struct sun_flpy_controller *)
730                 (sdev->resource[0].start +
731                  ((sdev->resource[0].flags & 0x1ffUL) << 32UL));
732 
733         /* Last minute sanity check... */
734         if(sbus_readb(&sun_fdc->status1_82077) == 0xff) {
735                 sun_fdc = (struct sun_flpy_controller *)-1;
736                 return 0;
737         }
738 
739         sun_fdops.fd_inb = sun_82077_fd_inb;
740         sun_fdops.fd_outb = sun_82077_fd_outb;
741 
742         can_use_virtual_dma = use_virtual_dma = 1;
743         sun_fdops.fd_enable_dma = sun_fd_enable_dma;
744         sun_fdops.fd_disable_dma = sun_fd_disable_dma;
745         sun_fdops.fd_set_dma_mode = sun_fd_set_dma_mode;
746         sun_fdops.fd_set_dma_addr = sun_fd_set_dma_addr;
747         sun_fdops.fd_set_dma_count = sun_fd_set_dma_count;
748         sun_fdops.get_dma_residue = sun_get_dma_residue;
749 
750         sun_fdops.fd_enable_irq = sun_fd_enable_irq;
751         sun_fdops.fd_disable_irq = sun_fd_disable_irq;
752         sun_fdops.fd_request_irq = sun_fd_request_irq;
753         sun_fdops.fd_free_irq = sun_fd_free_irq;
754 
755         sun_fdops.fd_eject = sun_fd_eject;
756 
757         fdc_status = (unsigned long) &sun_fdc->status_82077;
758 
759         /* Success... */
760         allowed_drive_mask = 0x01;
761         sun_floppy_types[0] = 4;
762         sun_floppy_types[1] = 0;
763 
764         return sun_floppy_types[0];
765 }
766 
767 #endif /* !(__ASM_SPARC64_FLOPPY_H) */
768 

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