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