[SPARC]: Fix floppy on some sun4c systems.
Add in code to support an 82077 FDC on sun4c systems. There is a problem with spurious interrupts but it does apear to work. Testing on my SS2 (82072A FDC) shows that the floppy driver is not 100% with sun4c any way (any spurious interrupt kills it, requiring a reboot to recover). Signed-off-by: Mark Fortescue <mark@mtfhpc.demon.co.uk> Signed-off-by: David S. Miller <davem@davemloft.net>
This commit is contained in:
parent
a2d6ea0180
commit
b65f0755fd
1 changed files with 50 additions and 30 deletions
|
@ -101,6 +101,29 @@ static struct sun_floppy_ops sun_fdops;
|
|||
#define CROSS_64KB(a,s) (0)
|
||||
|
||||
/* Routines unique to each controller type on a Sun. */
|
||||
static void sun_set_dor(unsigned char value, int fdc_82077)
|
||||
{
|
||||
if (sparc_cpu_model == sun4c) {
|
||||
unsigned int bits = 0;
|
||||
if (value & 0x10)
|
||||
bits |= AUXIO_FLPY_DSEL;
|
||||
if ((value & 0x80) == 0)
|
||||
bits |= AUXIO_FLPY_EJCT;
|
||||
set_auxio(bits, (~bits) & (AUXIO_FLPY_DSEL|AUXIO_FLPY_EJCT));
|
||||
}
|
||||
if (fdc_82077) {
|
||||
sun_fdc->dor_82077 = value;
|
||||
}
|
||||
}
|
||||
|
||||
static unsigned char sun_read_dir(void)
|
||||
{
|
||||
if (sparc_cpu_model == sun4c)
|
||||
return (get_auxio() & AUXIO_FLPY_DCHG) ? 0x80 : 0;
|
||||
else
|
||||
return sun_fdc->dir_82077;
|
||||
}
|
||||
|
||||
static unsigned char sun_82072_fd_inb(int port)
|
||||
{
|
||||
udelay(5);
|
||||
|
@ -113,7 +136,7 @@ static unsigned char sun_82072_fd_inb(int port)
|
|||
case 5: /* FD_DATA */
|
||||
return sun_fdc->data_82072;
|
||||
case 7: /* FD_DIR */
|
||||
return (get_auxio() & AUXIO_FLPY_DCHG)? 0x80: 0;
|
||||
return sun_read_dir();
|
||||
};
|
||||
panic("sun_82072_fd_inb: How did I get here?");
|
||||
}
|
||||
|
@ -126,20 +149,7 @@ static void sun_82072_fd_outb(unsigned char value, int port)
|
|||
printk("floppy: Asked to write to unknown port %d\n", port);
|
||||
panic("floppy: Port bolixed.");
|
||||
case 2: /* FD_DOR */
|
||||
/* Oh geese, 82072 on the Sun has no DOR register,
|
||||
* the functionality is implemented via the AUXIO
|
||||
* I/O register. So we must emulate the behavior.
|
||||
*
|
||||
* ASSUMPTIONS: There will only ever be one floppy
|
||||
* drive attached to a Sun controller
|
||||
* and it will be at drive zero.
|
||||
*/
|
||||
{
|
||||
unsigned bits = 0;
|
||||
if (value & 0x10) bits |= AUXIO_FLPY_DSEL;
|
||||
if ((value & 0x80) == 0) bits |= AUXIO_FLPY_EJCT;
|
||||
set_auxio(bits, (~bits) & (AUXIO_FLPY_DSEL|AUXIO_FLPY_EJCT));
|
||||
}
|
||||
sun_set_dor(value, 0);
|
||||
break;
|
||||
case 5: /* FD_DATA */
|
||||
sun_fdc->data_82072 = value;
|
||||
|
@ -161,15 +171,22 @@ static unsigned char sun_82077_fd_inb(int port)
|
|||
default:
|
||||
printk("floppy: Asked to read unknown port %d\n", port);
|
||||
panic("floppy: Port bolixed.");
|
||||
case 0: /* FD_STATUS_0 */
|
||||
return sun_fdc->status1_82077;
|
||||
case 1: /* FD_STATUS_1 */
|
||||
return sun_fdc->status2_82077;
|
||||
case 2: /* FD_DOR */
|
||||
return sun_fdc->dor_82077;
|
||||
case 3: /* FD_TDR */
|
||||
return sun_fdc->tapectl_82077;
|
||||
case 4: /* FD_STATUS */
|
||||
return sun_fdc->status_82077 & ~STATUS_DMA;
|
||||
case 5: /* FD_DATA */
|
||||
return sun_fdc->data_82077;
|
||||
case 7: /* FD_DIR */
|
||||
/* XXX: Is DCL on 0x80 in sun4m? */
|
||||
return sun_fdc->dir_82077;
|
||||
return sun_read_dir();
|
||||
};
|
||||
panic("sun_82072_fd_inb: How did I get here?");
|
||||
panic("sun_82077_fd_inb: How did I get here?");
|
||||
}
|
||||
|
||||
static void sun_82077_fd_outb(unsigned char value, int port)
|
||||
|
@ -180,8 +197,7 @@ static void sun_82077_fd_outb(unsigned char value, int port)
|
|||
printk("floppy: Asked to write to unknown port %d\n", port);
|
||||
panic("floppy: Port bolixed.");
|
||||
case 2: /* FD_DOR */
|
||||
/* Happily, the 82077 has a real DOR register. */
|
||||
sun_fdc->dor_82077 = value;
|
||||
sun_set_dor(value, 1);
|
||||
break;
|
||||
case 5: /* FD_DATA */
|
||||
sun_fdc->data_82077 = value;
|
||||
|
@ -192,6 +208,9 @@ static void sun_82077_fd_outb(unsigned char value, int port)
|
|||
case 4: /* FD_STATUS */
|
||||
sun_fdc->status_82077 = value;
|
||||
break;
|
||||
case 3: /* FD_TDR */
|
||||
sun_fdc->tapectl_82077 = value;
|
||||
break;
|
||||
};
|
||||
return;
|
||||
}
|
||||
|
@ -332,16 +351,17 @@ static int sun_floppy_init(void)
|
|||
goto no_sun_fdc;
|
||||
}
|
||||
|
||||
if(sparc_cpu_model == sun4c) {
|
||||
sun_fdops.fd_inb = sun_82072_fd_inb;
|
||||
sun_fdops.fd_outb = sun_82072_fd_outb;
|
||||
fdc_status = &sun_fdc->status_82072;
|
||||
/* printk("AUXIO @0x%lx\n", auxio_register); */ /* P3 */
|
||||
} else {
|
||||
sun_fdops.fd_inb = sun_82077_fd_inb;
|
||||
sun_fdops.fd_outb = sun_82077_fd_outb;
|
||||
fdc_status = &sun_fdc->status_82077;
|
||||
/* printk("DOR @0x%p\n", &sun_fdc->dor_82077); */ /* P3 */
|
||||
sun_fdops.fd_inb = sun_82077_fd_inb;
|
||||
sun_fdops.fd_outb = sun_82077_fd_outb;
|
||||
fdc_status = &sun_fdc->status_82077;
|
||||
|
||||
if (sun_fdc->dor_82077 == 0x80) {
|
||||
sun_fdc->dor_82077 = 0x02;
|
||||
if (sun_fdc->dor_82077 == 0x80) {
|
||||
sun_fdops.fd_inb = sun_82072_fd_inb;
|
||||
sun_fdops.fd_outb = sun_82072_fd_outb;
|
||||
fdc_status = &sun_fdc->status_82072;
|
||||
}
|
||||
}
|
||||
|
||||
/* Success... */
|
||||
|
|
Loading…
Reference in a new issue