sun3xflop.h (5757B)
1/* SPDX-License-Identifier: GPL-2.0 */ 2/* sun3xflop.h: Sun3/80 specific parts of the floppy driver. 3 * 4 * Derived partially from asm-sparc/floppy.h, which is: 5 * Copyright (C) 1995 David S. Miller (davem@caip.rutgers.edu) 6 * 7 * Sun3x version 2/4/2000 Sam Creasey (sammy@sammy.net) 8 */ 9 10#ifndef __ASM_SUN3X_FLOPPY_H 11#define __ASM_SUN3X_FLOPPY_H 12 13#include <linux/pgtable.h> 14#include <asm/page.h> 15#include <asm/irq.h> 16#include <asm/sun3x.h> 17 18/* default interrupt vector */ 19#define SUN3X_FDC_IRQ 0x40 20 21/* some constants */ 22#define FCR_TC 0x1 23#define FCR_EJECT 0x2 24#define FCR_MTRON 0x4 25#define FCR_DSEL1 0x8 26#define FCR_DSEL0 0x10 27 28/* We don't need no stinkin' I/O port allocation crap. */ 29#undef release_region 30#undef request_region 31#define release_region(X, Y) do { } while(0) 32#define request_region(X, Y, Z) (1) 33 34struct sun3xflop_private { 35 volatile unsigned char *status_r; 36 volatile unsigned char *data_r; 37 volatile unsigned char *fcr_r; 38 volatile unsigned char *fvr_r; 39 unsigned char fcr; 40} sun3x_fdc; 41 42/* Super paranoid... */ 43#undef HAVE_DISABLE_HLT 44 45/* Routines unique to each controller type on a Sun. */ 46static unsigned char sun3x_82072_fd_inb(int port) 47{ 48 static int once = 0; 49// udelay(5); 50 switch(port & 7) { 51 default: 52 pr_crit("floppy: Asked to read unknown port %d\n", port); 53 panic("floppy: Port bolixed."); 54 case 4: /* FD_STATUS */ 55 return (*sun3x_fdc.status_r) & ~STATUS_DMA; 56 case 5: /* FD_DATA */ 57 return (*sun3x_fdc.data_r); 58 case 7: /* FD_DIR */ 59 /* ugly hack, I can't find a way to actually detect the disk */ 60 if(!once) { 61 once = 1; 62 return 0x80; 63 } 64 return 0; 65 }; 66 panic("sun_82072_fd_inb: How did I get here?"); 67} 68 69static void sun3x_82072_fd_outb(unsigned char value, int port) 70{ 71// udelay(5); 72 switch(port & 7) { 73 default: 74 pr_crit("floppy: Asked to write to unknown port %d\n", port); 75 panic("floppy: Port bolixed."); 76 case 2: /* FD_DOR */ 77 /* Oh geese, 82072 on the Sun has no DOR register, 78 * so we make do with taunting the FCR. 79 * 80 * ASSUMPTIONS: There will only ever be one floppy 81 * drive attached to a Sun controller 82 * and it will be at drive zero. 83 */ 84 85 { 86 unsigned char fcr = sun3x_fdc.fcr; 87 88 if(value & 0x10) { 89 fcr |= (FCR_DSEL0 | FCR_MTRON); 90 } else 91 fcr &= ~(FCR_DSEL0 | FCR_MTRON); 92 93 94 if(fcr != sun3x_fdc.fcr) { 95 *(sun3x_fdc.fcr_r) = fcr; 96 sun3x_fdc.fcr = fcr; 97 } 98 } 99 break; 100 case 5: /* FD_DATA */ 101 *(sun3x_fdc.data_r) = value; 102 break; 103 case 7: /* FD_DCR */ 104 *(sun3x_fdc.status_r) = value; 105 break; 106 case 4: /* FD_STATUS */ 107 *(sun3x_fdc.status_r) = value; 108 break; 109 } 110 return; 111} 112 113 114asmlinkage irqreturn_t sun3xflop_hardint(int irq, void *dev_id) 115{ 116 register unsigned char st; 117 118#undef TRACE_FLPY_INT 119#define NO_FLOPPY_ASSEMBLER 120 121#ifdef TRACE_FLPY_INT 122 static int calls=0; 123 static int bytes=0; 124 static int dma_wait=0; 125#endif 126 if(!doing_pdma) { 127 floppy_interrupt(irq, dev_id); 128 return IRQ_HANDLED; 129 } 130 131// pr_info("doing pdma\n");// st %x\n", sun_fdc->status_82072); 132 133#ifdef TRACE_FLPY_INT 134 if(!calls) 135 bytes = virtual_dma_count; 136#endif 137 138 { 139 register int lcount; 140 register char *lptr; 141 142 for(lcount=virtual_dma_count, lptr=virtual_dma_addr; 143 lcount; lcount--, lptr++) { 144/* st=fd_inb(virtual_dma_port+4) & 0x80 ; */ 145 st = *(sun3x_fdc.status_r); 146/* if(st != 0xa0) */ 147/* break; */ 148 149 if((st & 0x80) == 0) { 150 virtual_dma_count = lcount; 151 virtual_dma_addr = lptr; 152 return IRQ_HANDLED; 153 } 154 155 if((st & 0x20) == 0) 156 break; 157 158 if(virtual_dma_mode) 159/* fd_outb(*lptr, virtual_dma_port+5); */ 160 *(sun3x_fdc.data_r) = *lptr; 161 else 162/* *lptr = fd_inb(virtual_dma_port+5); */ 163 *lptr = *(sun3x_fdc.data_r); 164 } 165 166 virtual_dma_count = lcount; 167 virtual_dma_addr = lptr; 168/* st = fd_inb(virtual_dma_port+4); */ 169 st = *(sun3x_fdc.status_r); 170 } 171 172#ifdef TRACE_FLPY_INT 173 calls++; 174#endif 175// pr_info("st=%02x\n", st); 176 if(st == 0x20) 177 return IRQ_HANDLED; 178 if(!(st & 0x20)) { 179 virtual_dma_residue += virtual_dma_count; 180 virtual_dma_count=0; 181 doing_pdma = 0; 182 183#ifdef TRACE_FLPY_INT 184 pr_info("count=%x, residue=%x calls=%d bytes=%x dma_wait=%d\n", 185 virtual_dma_count, virtual_dma_residue, calls, bytes, 186 dma_wait); 187 calls = 0; 188 dma_wait=0; 189#endif 190 191 floppy_interrupt(irq, dev_id); 192 return IRQ_HANDLED; 193 } 194 195 196#ifdef TRACE_FLPY_INT 197 if(!virtual_dma_count) 198 dma_wait++; 199#endif 200 return IRQ_HANDLED; 201} 202 203static int sun3xflop_request_irq(void) 204{ 205 static int once = 0; 206 int error; 207 208 if(!once) { 209 once = 1; 210 error = request_irq(FLOPPY_IRQ, sun3xflop_hardint, 211 0, "floppy", NULL); 212 return ((error == 0) ? 0 : -1); 213 } else return 0; 214} 215 216static void __init floppy_set_flags(int *ints,int param, int param2); 217 218static int sun3xflop_init(void) 219{ 220 if(FLOPPY_IRQ < 0x40) 221 FLOPPY_IRQ = SUN3X_FDC_IRQ; 222 223 sun3x_fdc.status_r = (volatile unsigned char *)SUN3X_FDC; 224 sun3x_fdc.data_r = (volatile unsigned char *)(SUN3X_FDC+1); 225 sun3x_fdc.fcr_r = (volatile unsigned char *)SUN3X_FDC_FCR; 226 sun3x_fdc.fvr_r = (volatile unsigned char *)SUN3X_FDC_FVR; 227 sun3x_fdc.fcr = 0; 228 229 /* Last minute sanity check... */ 230 if(*sun3x_fdc.status_r == 0xff) { 231 return -1; 232 } 233 234 *sun3x_fdc.fvr_r = FLOPPY_IRQ; 235 236 *sun3x_fdc.fcr_r = FCR_TC; 237 udelay(10); 238 *sun3x_fdc.fcr_r = 0; 239 240 /* Success... */ 241 floppy_set_flags(NULL, 1, FD_BROKEN_DCL); // I don't know how to detect this. 242 allowed_drive_mask = 0x01; 243 return (int) SUN3X_FDC; 244} 245 246/* I'm not precisely sure this eject routine works */ 247static int sun3x_eject(void) 248{ 249 if(MACH_IS_SUN3X) { 250 251 sun3x_fdc.fcr |= (FCR_DSEL0 | FCR_EJECT); 252 *(sun3x_fdc.fcr_r) = sun3x_fdc.fcr; 253 udelay(10); 254 sun3x_fdc.fcr &= ~(FCR_DSEL0 | FCR_EJECT); 255 *(sun3x_fdc.fcr_r) = sun3x_fdc.fcr; 256 } 257 258 return 0; 259} 260 261#define fd_eject(drive) sun3x_eject() 262 263#endif /* !(__ASM_SUN3X_FLOPPY_H) */