root/arch/sparc/include/asm/floppy_64.h

/* [<][>][^][v][top][bottom][index][help] */

INCLUDED FROM


DEFINITIONS

This source file includes following definitions.
  1. sun_82077_fd_inb
  2. sun_82077_fd_outb
  3. sun_fd_disable_dma
  4. sun_fd_set_dma_mode
  5. sun_fd_set_dma_addr
  6. sun_fd_set_dma_count
  7. sun_fd_enable_dma
  8. sparc_floppy_irq
  9. sun_fd_request_irq
  10. sun_fd_free_irq
  11. sun_get_dma_residue
  12. sun_fd_eject
  13. sun_pci_fd_inb
  14. sun_pci_fd_outb
  15. sun_pci_fd_broken_outb
  16. sun_pci_fd_lde_broken_outb
  17. sun_pci_fd_enable_dma
  18. sun_pci_fd_disable_dma
  19. sun_pci_fd_set_dma_mode
  20. sun_pci_fd_set_dma_count
  21. sun_pci_fd_set_dma_addr
  22. sun_pci_get_dma_residue
  23. sun_pci_fd_request_irq
  24. sun_pci_fd_free_irq
  25. sun_pci_fd_eject
  26. sun_pci_fd_dma_callback
  27. sun_pci_fd_out_byte
  28. sun_pci_fd_sensei
  29. sun_pci_fd_reset
  30. sun_pci_fd_test_drive
  31. ebus_fdthree_p
  32. sun_floppy_init

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

/* [<][>][^][v][top][bottom][index][help] */