18c2ecf20Sopenharmony_ci/* SPDX-License-Identifier: GPL-2.0 */ 28c2ecf20Sopenharmony_ci/* asm/floppy.h: Sparc specific parts of the Floppy driver. 38c2ecf20Sopenharmony_ci * 48c2ecf20Sopenharmony_ci * Copyright (C) 1995 David S. Miller (davem@davemloft.net) 58c2ecf20Sopenharmony_ci */ 68c2ecf20Sopenharmony_ci 78c2ecf20Sopenharmony_ci#ifndef __ASM_SPARC_FLOPPY_H 88c2ecf20Sopenharmony_ci#define __ASM_SPARC_FLOPPY_H 98c2ecf20Sopenharmony_ci 108c2ecf20Sopenharmony_ci#include <linux/of.h> 118c2ecf20Sopenharmony_ci#include <linux/of_device.h> 128c2ecf20Sopenharmony_ci#include <linux/pgtable.h> 138c2ecf20Sopenharmony_ci 148c2ecf20Sopenharmony_ci#include <asm/idprom.h> 158c2ecf20Sopenharmony_ci#include <asm/oplib.h> 168c2ecf20Sopenharmony_ci#include <asm/auxio.h> 178c2ecf20Sopenharmony_ci#include <asm/setup.h> 188c2ecf20Sopenharmony_ci#include <asm/page.h> 198c2ecf20Sopenharmony_ci#include <asm/irq.h> 208c2ecf20Sopenharmony_ci 218c2ecf20Sopenharmony_ci/* We don't need no stinkin' I/O port allocation crap. */ 228c2ecf20Sopenharmony_ci#undef release_region 238c2ecf20Sopenharmony_ci#undef request_region 248c2ecf20Sopenharmony_ci#define release_region(X, Y) do { } while(0) 258c2ecf20Sopenharmony_ci#define request_region(X, Y, Z) (1) 268c2ecf20Sopenharmony_ci 278c2ecf20Sopenharmony_ci/* References: 288c2ecf20Sopenharmony_ci * 1) Netbsd Sun floppy driver. 298c2ecf20Sopenharmony_ci * 2) NCR 82077 controller manual 308c2ecf20Sopenharmony_ci * 3) Intel 82077 controller manual 318c2ecf20Sopenharmony_ci */ 328c2ecf20Sopenharmony_cistruct sun_flpy_controller { 338c2ecf20Sopenharmony_ci volatile unsigned char status_82072; /* Main Status reg. */ 348c2ecf20Sopenharmony_ci#define dcr_82072 status_82072 /* Digital Control reg. */ 358c2ecf20Sopenharmony_ci#define status1_82077 status_82072 /* Auxiliary Status reg. 1 */ 368c2ecf20Sopenharmony_ci 378c2ecf20Sopenharmony_ci volatile unsigned char data_82072; /* Data fifo. */ 388c2ecf20Sopenharmony_ci#define status2_82077 data_82072 /* Auxiliary Status reg. 2 */ 398c2ecf20Sopenharmony_ci 408c2ecf20Sopenharmony_ci volatile unsigned char dor_82077; /* Digital Output reg. */ 418c2ecf20Sopenharmony_ci volatile unsigned char tapectl_82077; /* What the? Tape control reg? */ 428c2ecf20Sopenharmony_ci 438c2ecf20Sopenharmony_ci volatile unsigned char status_82077; /* Main Status Register. */ 448c2ecf20Sopenharmony_ci#define drs_82077 status_82077 /* Digital Rate Select reg. */ 458c2ecf20Sopenharmony_ci 468c2ecf20Sopenharmony_ci volatile unsigned char data_82077; /* Data fifo. */ 478c2ecf20Sopenharmony_ci volatile unsigned char ___unused; 488c2ecf20Sopenharmony_ci volatile unsigned char dir_82077; /* Digital Input reg. */ 498c2ecf20Sopenharmony_ci#define dcr_82077 dir_82077 /* Config Control reg. */ 508c2ecf20Sopenharmony_ci}; 518c2ecf20Sopenharmony_ci 528c2ecf20Sopenharmony_ci/* You'll only ever find one controller on a SparcStation anyways. */ 538c2ecf20Sopenharmony_cistatic struct sun_flpy_controller *sun_fdc = NULL; 548c2ecf20Sopenharmony_ci 558c2ecf20Sopenharmony_cistruct sun_floppy_ops { 568c2ecf20Sopenharmony_ci unsigned char (*fd_inb)(int port); 578c2ecf20Sopenharmony_ci void (*fd_outb)(unsigned char value, int port); 588c2ecf20Sopenharmony_ci}; 598c2ecf20Sopenharmony_ci 608c2ecf20Sopenharmony_cistatic struct sun_floppy_ops sun_fdops; 618c2ecf20Sopenharmony_ci 628c2ecf20Sopenharmony_ci#define fd_inb(base, reg) sun_fdops.fd_inb(reg) 638c2ecf20Sopenharmony_ci#define fd_outb(value, base, reg) sun_fdops.fd_outb(value, reg) 648c2ecf20Sopenharmony_ci#define fd_enable_dma() sun_fd_enable_dma() 658c2ecf20Sopenharmony_ci#define fd_disable_dma() sun_fd_disable_dma() 668c2ecf20Sopenharmony_ci#define fd_request_dma() (0) /* nothing... */ 678c2ecf20Sopenharmony_ci#define fd_free_dma() /* nothing... */ 688c2ecf20Sopenharmony_ci#define fd_clear_dma_ff() /* nothing... */ 698c2ecf20Sopenharmony_ci#define fd_set_dma_mode(mode) sun_fd_set_dma_mode(mode) 708c2ecf20Sopenharmony_ci#define fd_set_dma_addr(addr) sun_fd_set_dma_addr(addr) 718c2ecf20Sopenharmony_ci#define fd_set_dma_count(count) sun_fd_set_dma_count(count) 728c2ecf20Sopenharmony_ci#define fd_enable_irq() /* nothing... */ 738c2ecf20Sopenharmony_ci#define fd_disable_irq() /* nothing... */ 748c2ecf20Sopenharmony_ci#define fd_request_irq() sun_fd_request_irq() 758c2ecf20Sopenharmony_ci#define fd_free_irq() /* nothing... */ 768c2ecf20Sopenharmony_ci#if 0 /* P3: added by Alain, these cause a MMU corruption. 19960524 XXX */ 778c2ecf20Sopenharmony_ci#define fd_dma_mem_alloc(size) ((unsigned long) vmalloc(size)) 788c2ecf20Sopenharmony_ci#define fd_dma_mem_free(addr,size) (vfree((void *)(addr))) 798c2ecf20Sopenharmony_ci#endif 808c2ecf20Sopenharmony_ci 818c2ecf20Sopenharmony_ci/* XXX This isn't really correct. XXX */ 828c2ecf20Sopenharmony_ci#define get_dma_residue(x) (0) 838c2ecf20Sopenharmony_ci 848c2ecf20Sopenharmony_ci#define FLOPPY0_TYPE 4 858c2ecf20Sopenharmony_ci#define FLOPPY1_TYPE 0 868c2ecf20Sopenharmony_ci 878c2ecf20Sopenharmony_ci/* Super paranoid... */ 888c2ecf20Sopenharmony_ci#undef HAVE_DISABLE_HLT 898c2ecf20Sopenharmony_ci 908c2ecf20Sopenharmony_ci/* Here is where we catch the floppy driver trying to initialize, 918c2ecf20Sopenharmony_ci * therefore this is where we call the PROM device tree probing 928c2ecf20Sopenharmony_ci * routine etc. on the Sparc. 938c2ecf20Sopenharmony_ci */ 948c2ecf20Sopenharmony_ci#define FDC1 sun_floppy_init() 958c2ecf20Sopenharmony_ci 968c2ecf20Sopenharmony_ci#define N_FDC 1 978c2ecf20Sopenharmony_ci#define N_DRIVE 8 988c2ecf20Sopenharmony_ci 998c2ecf20Sopenharmony_ci/* No 64k boundary crossing problems on the Sparc. */ 1008c2ecf20Sopenharmony_ci#define CROSS_64KB(a,s) (0) 1018c2ecf20Sopenharmony_ci 1028c2ecf20Sopenharmony_ci/* Routines unique to each controller type on a Sun. */ 1038c2ecf20Sopenharmony_cistatic void sun_set_dor(unsigned char value, int fdc_82077) 1048c2ecf20Sopenharmony_ci{ 1058c2ecf20Sopenharmony_ci if (fdc_82077) 1068c2ecf20Sopenharmony_ci sun_fdc->dor_82077 = value; 1078c2ecf20Sopenharmony_ci} 1088c2ecf20Sopenharmony_ci 1098c2ecf20Sopenharmony_cistatic unsigned char sun_read_dir(void) 1108c2ecf20Sopenharmony_ci{ 1118c2ecf20Sopenharmony_ci return sun_fdc->dir_82077; 1128c2ecf20Sopenharmony_ci} 1138c2ecf20Sopenharmony_ci 1148c2ecf20Sopenharmony_cistatic unsigned char sun_82072_fd_inb(int port) 1158c2ecf20Sopenharmony_ci{ 1168c2ecf20Sopenharmony_ci udelay(5); 1178c2ecf20Sopenharmony_ci switch (port) { 1188c2ecf20Sopenharmony_ci default: 1198c2ecf20Sopenharmony_ci printk("floppy: Asked to read unknown port %d\n", port); 1208c2ecf20Sopenharmony_ci panic("floppy: Port bolixed."); 1218c2ecf20Sopenharmony_ci case FD_STATUS: 1228c2ecf20Sopenharmony_ci return sun_fdc->status_82072 & ~STATUS_DMA; 1238c2ecf20Sopenharmony_ci case FD_DATA: 1248c2ecf20Sopenharmony_ci return sun_fdc->data_82072; 1258c2ecf20Sopenharmony_ci case FD_DIR: 1268c2ecf20Sopenharmony_ci return sun_read_dir(); 1278c2ecf20Sopenharmony_ci } 1288c2ecf20Sopenharmony_ci panic("sun_82072_fd_inb: How did I get here?"); 1298c2ecf20Sopenharmony_ci} 1308c2ecf20Sopenharmony_ci 1318c2ecf20Sopenharmony_cistatic void sun_82072_fd_outb(unsigned char value, int port) 1328c2ecf20Sopenharmony_ci{ 1338c2ecf20Sopenharmony_ci udelay(5); 1348c2ecf20Sopenharmony_ci switch (port) { 1358c2ecf20Sopenharmony_ci default: 1368c2ecf20Sopenharmony_ci printk("floppy: Asked to write to unknown port %d\n", port); 1378c2ecf20Sopenharmony_ci panic("floppy: Port bolixed."); 1388c2ecf20Sopenharmony_ci case FD_DOR: 1398c2ecf20Sopenharmony_ci sun_set_dor(value, 0); 1408c2ecf20Sopenharmony_ci break; 1418c2ecf20Sopenharmony_ci case FD_DATA: 1428c2ecf20Sopenharmony_ci sun_fdc->data_82072 = value; 1438c2ecf20Sopenharmony_ci break; 1448c2ecf20Sopenharmony_ci case FD_DCR: 1458c2ecf20Sopenharmony_ci sun_fdc->dcr_82072 = value; 1468c2ecf20Sopenharmony_ci break; 1478c2ecf20Sopenharmony_ci case FD_DSR: 1488c2ecf20Sopenharmony_ci sun_fdc->status_82072 = value; 1498c2ecf20Sopenharmony_ci break; 1508c2ecf20Sopenharmony_ci } 1518c2ecf20Sopenharmony_ci return; 1528c2ecf20Sopenharmony_ci} 1538c2ecf20Sopenharmony_ci 1548c2ecf20Sopenharmony_cistatic unsigned char sun_82077_fd_inb(int port) 1558c2ecf20Sopenharmony_ci{ 1568c2ecf20Sopenharmony_ci udelay(5); 1578c2ecf20Sopenharmony_ci switch (port) { 1588c2ecf20Sopenharmony_ci default: 1598c2ecf20Sopenharmony_ci printk("floppy: Asked to read unknown port %d\n", port); 1608c2ecf20Sopenharmony_ci panic("floppy: Port bolixed."); 1618c2ecf20Sopenharmony_ci case FD_SRA: 1628c2ecf20Sopenharmony_ci return sun_fdc->status1_82077; 1638c2ecf20Sopenharmony_ci case FD_SRB: 1648c2ecf20Sopenharmony_ci return sun_fdc->status2_82077; 1658c2ecf20Sopenharmony_ci case FD_DOR: 1668c2ecf20Sopenharmony_ci return sun_fdc->dor_82077; 1678c2ecf20Sopenharmony_ci case FD_TDR: 1688c2ecf20Sopenharmony_ci return sun_fdc->tapectl_82077; 1698c2ecf20Sopenharmony_ci case FD_STATUS: 1708c2ecf20Sopenharmony_ci return sun_fdc->status_82077 & ~STATUS_DMA; 1718c2ecf20Sopenharmony_ci case FD_DATA: 1728c2ecf20Sopenharmony_ci return sun_fdc->data_82077; 1738c2ecf20Sopenharmony_ci case FD_DIR: 1748c2ecf20Sopenharmony_ci return sun_read_dir(); 1758c2ecf20Sopenharmony_ci } 1768c2ecf20Sopenharmony_ci panic("sun_82077_fd_inb: How did I get here?"); 1778c2ecf20Sopenharmony_ci} 1788c2ecf20Sopenharmony_ci 1798c2ecf20Sopenharmony_cistatic void sun_82077_fd_outb(unsigned char value, int port) 1808c2ecf20Sopenharmony_ci{ 1818c2ecf20Sopenharmony_ci udelay(5); 1828c2ecf20Sopenharmony_ci switch (port) { 1838c2ecf20Sopenharmony_ci default: 1848c2ecf20Sopenharmony_ci printk("floppy: Asked to write to unknown port %d\n", port); 1858c2ecf20Sopenharmony_ci panic("floppy: Port bolixed."); 1868c2ecf20Sopenharmony_ci case FD_DOR: 1878c2ecf20Sopenharmony_ci sun_set_dor(value, 1); 1888c2ecf20Sopenharmony_ci break; 1898c2ecf20Sopenharmony_ci case FD_DATA: 1908c2ecf20Sopenharmony_ci sun_fdc->data_82077 = value; 1918c2ecf20Sopenharmony_ci break; 1928c2ecf20Sopenharmony_ci case FD_DCR: 1938c2ecf20Sopenharmony_ci sun_fdc->dcr_82077 = value; 1948c2ecf20Sopenharmony_ci break; 1958c2ecf20Sopenharmony_ci case FD_DSR: 1968c2ecf20Sopenharmony_ci sun_fdc->status_82077 = value; 1978c2ecf20Sopenharmony_ci break; 1988c2ecf20Sopenharmony_ci case FD_TDR: 1998c2ecf20Sopenharmony_ci sun_fdc->tapectl_82077 = value; 2008c2ecf20Sopenharmony_ci break; 2018c2ecf20Sopenharmony_ci } 2028c2ecf20Sopenharmony_ci return; 2038c2ecf20Sopenharmony_ci} 2048c2ecf20Sopenharmony_ci 2058c2ecf20Sopenharmony_ci/* For pseudo-dma (Sun floppy drives have no real DMA available to 2068c2ecf20Sopenharmony_ci * them so we must eat the data fifo bytes directly ourselves) we have 2078c2ecf20Sopenharmony_ci * three state variables. doing_pdma tells our inline low-level 2088c2ecf20Sopenharmony_ci * assembly floppy interrupt entry point whether it should sit and eat 2098c2ecf20Sopenharmony_ci * bytes from the fifo or just transfer control up to the higher level 2108c2ecf20Sopenharmony_ci * floppy interrupt c-code. I tried very hard but I could not get the 2118c2ecf20Sopenharmony_ci * pseudo-dma to work in c-code without getting many overruns and 2128c2ecf20Sopenharmony_ci * underruns. If non-zero, doing_pdma encodes the direction of 2138c2ecf20Sopenharmony_ci * the transfer for debugging. 1=read 2=write 2148c2ecf20Sopenharmony_ci */ 2158c2ecf20Sopenharmony_ci 2168c2ecf20Sopenharmony_ci/* Common routines to all controller types on the Sparc. */ 2178c2ecf20Sopenharmony_cistatic inline void virtual_dma_init(void) 2188c2ecf20Sopenharmony_ci{ 2198c2ecf20Sopenharmony_ci /* nothing... */ 2208c2ecf20Sopenharmony_ci} 2218c2ecf20Sopenharmony_ci 2228c2ecf20Sopenharmony_cistatic inline void sun_fd_disable_dma(void) 2238c2ecf20Sopenharmony_ci{ 2248c2ecf20Sopenharmony_ci doing_pdma = 0; 2258c2ecf20Sopenharmony_ci pdma_base = NULL; 2268c2ecf20Sopenharmony_ci} 2278c2ecf20Sopenharmony_ci 2288c2ecf20Sopenharmony_cistatic inline void sun_fd_set_dma_mode(int mode) 2298c2ecf20Sopenharmony_ci{ 2308c2ecf20Sopenharmony_ci switch(mode) { 2318c2ecf20Sopenharmony_ci case DMA_MODE_READ: 2328c2ecf20Sopenharmony_ci doing_pdma = 1; 2338c2ecf20Sopenharmony_ci break; 2348c2ecf20Sopenharmony_ci case DMA_MODE_WRITE: 2358c2ecf20Sopenharmony_ci doing_pdma = 2; 2368c2ecf20Sopenharmony_ci break; 2378c2ecf20Sopenharmony_ci default: 2388c2ecf20Sopenharmony_ci printk("Unknown dma mode %d\n", mode); 2398c2ecf20Sopenharmony_ci panic("floppy: Giving up..."); 2408c2ecf20Sopenharmony_ci } 2418c2ecf20Sopenharmony_ci} 2428c2ecf20Sopenharmony_ci 2438c2ecf20Sopenharmony_cistatic inline void sun_fd_set_dma_addr(char *buffer) 2448c2ecf20Sopenharmony_ci{ 2458c2ecf20Sopenharmony_ci pdma_vaddr = buffer; 2468c2ecf20Sopenharmony_ci} 2478c2ecf20Sopenharmony_ci 2488c2ecf20Sopenharmony_cistatic inline void sun_fd_set_dma_count(int length) 2498c2ecf20Sopenharmony_ci{ 2508c2ecf20Sopenharmony_ci pdma_size = length; 2518c2ecf20Sopenharmony_ci} 2528c2ecf20Sopenharmony_ci 2538c2ecf20Sopenharmony_cistatic inline void sun_fd_enable_dma(void) 2548c2ecf20Sopenharmony_ci{ 2558c2ecf20Sopenharmony_ci pdma_base = pdma_vaddr; 2568c2ecf20Sopenharmony_ci pdma_areasize = pdma_size; 2578c2ecf20Sopenharmony_ci} 2588c2ecf20Sopenharmony_ci 2598c2ecf20Sopenharmony_ciint sparc_floppy_request_irq(unsigned int irq, irq_handler_t irq_handler); 2608c2ecf20Sopenharmony_ci 2618c2ecf20Sopenharmony_cistatic int sun_fd_request_irq(void) 2628c2ecf20Sopenharmony_ci{ 2638c2ecf20Sopenharmony_ci static int once = 0; 2648c2ecf20Sopenharmony_ci 2658c2ecf20Sopenharmony_ci if (!once) { 2668c2ecf20Sopenharmony_ci once = 1; 2678c2ecf20Sopenharmony_ci return sparc_floppy_request_irq(FLOPPY_IRQ, floppy_interrupt); 2688c2ecf20Sopenharmony_ci } else { 2698c2ecf20Sopenharmony_ci return 0; 2708c2ecf20Sopenharmony_ci } 2718c2ecf20Sopenharmony_ci} 2728c2ecf20Sopenharmony_ci 2738c2ecf20Sopenharmony_cistatic struct linux_prom_registers fd_regs[2]; 2748c2ecf20Sopenharmony_ci 2758c2ecf20Sopenharmony_cistatic int sun_floppy_init(void) 2768c2ecf20Sopenharmony_ci{ 2778c2ecf20Sopenharmony_ci struct platform_device *op; 2788c2ecf20Sopenharmony_ci struct device_node *dp; 2798c2ecf20Sopenharmony_ci struct resource r; 2808c2ecf20Sopenharmony_ci char state[128]; 2818c2ecf20Sopenharmony_ci phandle fd_node; 2828c2ecf20Sopenharmony_ci phandle tnode; 2838c2ecf20Sopenharmony_ci int num_regs; 2848c2ecf20Sopenharmony_ci 2858c2ecf20Sopenharmony_ci use_virtual_dma = 1; 2868c2ecf20Sopenharmony_ci 2878c2ecf20Sopenharmony_ci /* Forget it if we aren't on a machine that could possibly 2888c2ecf20Sopenharmony_ci * ever have a floppy drive. 2898c2ecf20Sopenharmony_ci */ 2908c2ecf20Sopenharmony_ci if (sparc_cpu_model != sun4m) { 2918c2ecf20Sopenharmony_ci /* We certainly don't have a floppy controller. */ 2928c2ecf20Sopenharmony_ci goto no_sun_fdc; 2938c2ecf20Sopenharmony_ci } 2948c2ecf20Sopenharmony_ci /* Well, try to find one. */ 2958c2ecf20Sopenharmony_ci tnode = prom_getchild(prom_root_node); 2968c2ecf20Sopenharmony_ci fd_node = prom_searchsiblings(tnode, "obio"); 2978c2ecf20Sopenharmony_ci if (fd_node != 0) { 2988c2ecf20Sopenharmony_ci tnode = prom_getchild(fd_node); 2998c2ecf20Sopenharmony_ci fd_node = prom_searchsiblings(tnode, "SUNW,fdtwo"); 3008c2ecf20Sopenharmony_ci } else { 3018c2ecf20Sopenharmony_ci fd_node = prom_searchsiblings(tnode, "fd"); 3028c2ecf20Sopenharmony_ci } 3038c2ecf20Sopenharmony_ci if (fd_node == 0) { 3048c2ecf20Sopenharmony_ci goto no_sun_fdc; 3058c2ecf20Sopenharmony_ci } 3068c2ecf20Sopenharmony_ci 3078c2ecf20Sopenharmony_ci /* The sun4m lets us know if the controller is actually usable. */ 3088c2ecf20Sopenharmony_ci if (prom_getproperty(fd_node, "status", state, sizeof(state)) != -1) { 3098c2ecf20Sopenharmony_ci if(!strcmp(state, "disabled")) { 3108c2ecf20Sopenharmony_ci goto no_sun_fdc; 3118c2ecf20Sopenharmony_ci } 3128c2ecf20Sopenharmony_ci } 3138c2ecf20Sopenharmony_ci num_regs = prom_getproperty(fd_node, "reg", (char *) fd_regs, sizeof(fd_regs)); 3148c2ecf20Sopenharmony_ci num_regs = (num_regs / sizeof(fd_regs[0])); 3158c2ecf20Sopenharmony_ci prom_apply_obio_ranges(fd_regs, num_regs); 3168c2ecf20Sopenharmony_ci memset(&r, 0, sizeof(r)); 3178c2ecf20Sopenharmony_ci r.flags = fd_regs[0].which_io; 3188c2ecf20Sopenharmony_ci r.start = fd_regs[0].phys_addr; 3198c2ecf20Sopenharmony_ci sun_fdc = of_ioremap(&r, 0, fd_regs[0].reg_size, "floppy"); 3208c2ecf20Sopenharmony_ci 3218c2ecf20Sopenharmony_ci /* Look up irq in platform_device. 3228c2ecf20Sopenharmony_ci * We try "SUNW,fdtwo" and "fd" 3238c2ecf20Sopenharmony_ci */ 3248c2ecf20Sopenharmony_ci op = NULL; 3258c2ecf20Sopenharmony_ci for_each_node_by_name(dp, "SUNW,fdtwo") { 3268c2ecf20Sopenharmony_ci op = of_find_device_by_node(dp); 3278c2ecf20Sopenharmony_ci if (op) 3288c2ecf20Sopenharmony_ci break; 3298c2ecf20Sopenharmony_ci } 3308c2ecf20Sopenharmony_ci if (!op) { 3318c2ecf20Sopenharmony_ci for_each_node_by_name(dp, "fd") { 3328c2ecf20Sopenharmony_ci op = of_find_device_by_node(dp); 3338c2ecf20Sopenharmony_ci if (op) 3348c2ecf20Sopenharmony_ci break; 3358c2ecf20Sopenharmony_ci } 3368c2ecf20Sopenharmony_ci } 3378c2ecf20Sopenharmony_ci if (!op) 3388c2ecf20Sopenharmony_ci goto no_sun_fdc; 3398c2ecf20Sopenharmony_ci 3408c2ecf20Sopenharmony_ci FLOPPY_IRQ = op->archdata.irqs[0]; 3418c2ecf20Sopenharmony_ci 3428c2ecf20Sopenharmony_ci /* Last minute sanity check... */ 3438c2ecf20Sopenharmony_ci if (sun_fdc->status_82072 == 0xff) { 3448c2ecf20Sopenharmony_ci sun_fdc = NULL; 3458c2ecf20Sopenharmony_ci goto no_sun_fdc; 3468c2ecf20Sopenharmony_ci } 3478c2ecf20Sopenharmony_ci 3488c2ecf20Sopenharmony_ci sun_fdops.fd_inb = sun_82077_fd_inb; 3498c2ecf20Sopenharmony_ci sun_fdops.fd_outb = sun_82077_fd_outb; 3508c2ecf20Sopenharmony_ci fdc_status = &sun_fdc->status_82077; 3518c2ecf20Sopenharmony_ci 3528c2ecf20Sopenharmony_ci if (sun_fdc->dor_82077 == 0x80) { 3538c2ecf20Sopenharmony_ci sun_fdc->dor_82077 = 0x02; 3548c2ecf20Sopenharmony_ci if (sun_fdc->dor_82077 == 0x80) { 3558c2ecf20Sopenharmony_ci sun_fdops.fd_inb = sun_82072_fd_inb; 3568c2ecf20Sopenharmony_ci sun_fdops.fd_outb = sun_82072_fd_outb; 3578c2ecf20Sopenharmony_ci fdc_status = &sun_fdc->status_82072; 3588c2ecf20Sopenharmony_ci } 3598c2ecf20Sopenharmony_ci } 3608c2ecf20Sopenharmony_ci 3618c2ecf20Sopenharmony_ci /* Success... */ 3628c2ecf20Sopenharmony_ci allowed_drive_mask = 0x01; 3638c2ecf20Sopenharmony_ci return (int) sun_fdc; 3648c2ecf20Sopenharmony_ci 3658c2ecf20Sopenharmony_cino_sun_fdc: 3668c2ecf20Sopenharmony_ci return -1; 3678c2ecf20Sopenharmony_ci} 3688c2ecf20Sopenharmony_ci 3698c2ecf20Sopenharmony_cistatic int sparc_eject(void) 3708c2ecf20Sopenharmony_ci{ 3718c2ecf20Sopenharmony_ci set_dor(0x00, 0xff, 0x90); 3728c2ecf20Sopenharmony_ci udelay(500); 3738c2ecf20Sopenharmony_ci set_dor(0x00, 0x6f, 0x00); 3748c2ecf20Sopenharmony_ci udelay(500); 3758c2ecf20Sopenharmony_ci return 0; 3768c2ecf20Sopenharmony_ci} 3778c2ecf20Sopenharmony_ci 3788c2ecf20Sopenharmony_ci#define fd_eject(drive) sparc_eject() 3798c2ecf20Sopenharmony_ci 3808c2ecf20Sopenharmony_ci#define EXTRA_FLOPPY_PARAMS 3818c2ecf20Sopenharmony_ci 3828c2ecf20Sopenharmony_cistatic DEFINE_SPINLOCK(dma_spin_lock); 3838c2ecf20Sopenharmony_ci 3848c2ecf20Sopenharmony_ci#define claim_dma_lock() \ 3858c2ecf20Sopenharmony_ci({ unsigned long flags; \ 3868c2ecf20Sopenharmony_ci spin_lock_irqsave(&dma_spin_lock, flags); \ 3878c2ecf20Sopenharmony_ci flags; \ 3888c2ecf20Sopenharmony_ci}) 3898c2ecf20Sopenharmony_ci 3908c2ecf20Sopenharmony_ci#define release_dma_lock(__flags) \ 3918c2ecf20Sopenharmony_ci spin_unlock_irqrestore(&dma_spin_lock, __flags); 3928c2ecf20Sopenharmony_ci 3938c2ecf20Sopenharmony_ci#endif /* !(__ASM_SPARC_FLOPPY_H) */ 394