mirror of
https://github.com/Dasharo/linux.git
synced 2026-03-06 15:25:10 -08:00
m68k: mac - Add SWIM floppy support
It allows to read data from a floppy, but not to write to, and to eject the floppy (useful on our Mac without eject button). Signed-off-by: Laurent Vivier <Laurent@lvivier.info> Signed-off-by: Geert Uytterhoeven <geert@linux-m68k.org>
This commit is contained in:
committed by
Geert Uytterhoeven
parent
7ad93b42bd
commit
8852ecd974
@@ -22,6 +22,7 @@
|
||||
/* keyb */
|
||||
#include <linux/init.h>
|
||||
#include <linux/vt_kern.h>
|
||||
#include <linux/platform_device.h>
|
||||
|
||||
#define BOOTINFO_COMPAT_1_0
|
||||
#include <asm/setup.h>
|
||||
@@ -43,6 +44,10 @@
|
||||
#include <asm/mac_oss.h>
|
||||
#include <asm/mac_psc.h>
|
||||
|
||||
/* platform device info */
|
||||
|
||||
#define SWIM_IO_SIZE 0x2000 /* SWIM IO resource size */
|
||||
|
||||
/* Mac bootinfo struct */
|
||||
|
||||
struct mac_booter_data mac_bi_data;
|
||||
@@ -870,3 +875,42 @@ static void mac_get_model(char *str)
|
||||
strcpy(str, "Macintosh ");
|
||||
strcat(str, macintosh_config->name);
|
||||
}
|
||||
|
||||
static struct resource swim_resources[1];
|
||||
|
||||
static struct platform_device swim_device = {
|
||||
.name = "swim",
|
||||
.id = -1,
|
||||
.num_resources = ARRAY_SIZE(swim_resources),
|
||||
.resource = swim_resources,
|
||||
};
|
||||
|
||||
static struct platform_device *mac_platform_devices[] __initdata = {
|
||||
&swim_device
|
||||
};
|
||||
|
||||
int __init mac_platform_init(void)
|
||||
{
|
||||
u8 *swim_base;
|
||||
|
||||
switch (macintosh_config->floppy_type) {
|
||||
case MAC_FLOPPY_SWIM_ADDR1:
|
||||
swim_base = (u8 *)(VIA1_BASE + 0x1E000);
|
||||
break;
|
||||
case MAC_FLOPPY_SWIM_ADDR2:
|
||||
swim_base = (u8 *)(VIA1_BASE + 0x16000);
|
||||
break;
|
||||
default:
|
||||
return 0;
|
||||
}
|
||||
|
||||
swim_resources[0].name = "swim-regs";
|
||||
swim_resources[0].start = (resource_size_t)swim_base;
|
||||
swim_resources[0].end = (resource_size_t)(swim_base + SWIM_IO_SIZE);
|
||||
swim_resources[0].flags = IORESOURCE_MEM;
|
||||
|
||||
return platform_add_devices(mac_platform_devices,
|
||||
ARRAY_SIZE(mac_platform_devices));
|
||||
}
|
||||
|
||||
arch_initcall(mac_platform_init);
|
||||
|
||||
@@ -645,3 +645,12 @@ int via_irq_pending(int irq)
|
||||
}
|
||||
return 0;
|
||||
}
|
||||
|
||||
void via1_set_head(int head)
|
||||
{
|
||||
if (head == 0)
|
||||
via1[vBufA] &= ~VIA1A_vHeadSel;
|
||||
else
|
||||
via1[vBufA] |= VIA1A_vHeadSel;
|
||||
}
|
||||
EXPORT_SYMBOL(via1_set_head);
|
||||
|
||||
@@ -45,6 +45,13 @@ config MAC_FLOPPY
|
||||
If you have a SWIM-3 (Super Woz Integrated Machine 3; from Apple)
|
||||
floppy controller, say Y here. Most commonly found in PowerMacs.
|
||||
|
||||
config BLK_DEV_SWIM
|
||||
tristate "Support for SWIM Macintosh floppy"
|
||||
depends on M68K && MAC
|
||||
help
|
||||
You should select this option if you want floppy support
|
||||
and you don't have a II, IIfx, Q900, Q950 or AV series.
|
||||
|
||||
config AMIGA_Z2RAM
|
||||
tristate "Amiga Zorro II ramdisk support"
|
||||
depends on ZORRO
|
||||
|
||||
@@ -6,6 +6,7 @@
|
||||
#
|
||||
|
||||
obj-$(CONFIG_MAC_FLOPPY) += swim3.o
|
||||
obj-$(CONFIG_BLK_DEV_SWIM) += swim_mod.o
|
||||
obj-$(CONFIG_BLK_DEV_FD) += floppy.o
|
||||
obj-$(CONFIG_AMIGA_FLOPPY) += amiflop.o
|
||||
obj-$(CONFIG_PS3_DISK) += ps3disk.o
|
||||
@@ -33,3 +34,5 @@ obj-$(CONFIG_BLK_DEV_UB) += ub.o
|
||||
obj-$(CONFIG_BLK_DEV_HD) += hd.o
|
||||
|
||||
obj-$(CONFIG_XEN_BLKDEV_FRONTEND) += xen-blkfront.o
|
||||
|
||||
swim_mod-objs := swim.o swim_asm.o
|
||||
|
||||
995
drivers/block/swim.c
Normal file
995
drivers/block/swim.c
Normal file
File diff suppressed because it is too large
Load Diff
247
drivers/block/swim_asm.S
Normal file
247
drivers/block/swim_asm.S
Normal file
@@ -0,0 +1,247 @@
|
||||
/*
|
||||
* low-level functions for the SWIM floppy controller
|
||||
*
|
||||
* needs assembly language because is very timing dependent
|
||||
* this controller exists only on macintosh 680x0 based
|
||||
*
|
||||
* Copyright (C) 2004,2008 Laurent Vivier <Laurent@lvivier.info>
|
||||
*
|
||||
* based on Alastair Bridgewater SWIM analysis, 2001
|
||||
* based on netBSD IWM driver (c) 1997, 1998 Hauke Fath.
|
||||
*
|
||||
* This program is free software; you can redistribute it and/or
|
||||
* modify it under the terms of the GNU General Public License
|
||||
* as published by the Free Software Foundation; either version
|
||||
* 2 of the License, or (at your option) any later version.
|
||||
*
|
||||
* 2004-08-21 (lv) - Initial implementation
|
||||
* 2008-11-05 (lv) - add get_swim_mode
|
||||
*/
|
||||
|
||||
.equ write_data, 0x0000
|
||||
.equ write_mark, 0x0200
|
||||
.equ write_CRC, 0x0400
|
||||
.equ write_parameter,0x0600
|
||||
.equ write_phase, 0x0800
|
||||
.equ write_setup, 0x0a00
|
||||
.equ write_mode0, 0x0c00
|
||||
.equ write_mode1, 0x0e00
|
||||
.equ read_data, 0x1000
|
||||
.equ read_mark, 0x1200
|
||||
.equ read_error, 0x1400
|
||||
.equ read_parameter, 0x1600
|
||||
.equ read_phase, 0x1800
|
||||
.equ read_setup, 0x1a00
|
||||
.equ read_status, 0x1c00
|
||||
.equ read_handshake, 0x1e00
|
||||
|
||||
.equ o_side, 0
|
||||
.equ o_track, 1
|
||||
.equ o_sector, 2
|
||||
.equ o_size, 3
|
||||
.equ o_crc0, 4
|
||||
.equ o_crc1, 5
|
||||
|
||||
.equ seek_time, 30000
|
||||
.equ max_retry, 40
|
||||
.equ sector_size, 512
|
||||
|
||||
.global swim_read_sector_header
|
||||
swim_read_sector_header:
|
||||
link %a6, #0
|
||||
moveml %d1-%d5/%a0-%a4,%sp@-
|
||||
movel %a6@(0x0c), %a4
|
||||
bsr mfm_read_addrmark
|
||||
moveml %sp@+, %d1-%d5/%a0-%a4
|
||||
unlk %a6
|
||||
rts
|
||||
|
||||
sector_address_mark:
|
||||
.byte 0xa1, 0xa1, 0xa1, 0xfe
|
||||
sector_data_mark:
|
||||
.byte 0xa1, 0xa1, 0xa1, 0xfb
|
||||
|
||||
mfm_read_addrmark:
|
||||
movel %a6@(0x08), %a3
|
||||
lea %a3@(read_handshake), %a2
|
||||
lea %a3@(read_mark), %a3
|
||||
moveq #-1, %d0
|
||||
movew #seek_time, %d2
|
||||
|
||||
wait_header_init:
|
||||
tstb %a3@(read_error - read_mark)
|
||||
moveb #0x18, %a3@(write_mode0 - read_mark)
|
||||
moveb #0x01, %a3@(write_mode1 - read_mark)
|
||||
moveb #0x01, %a3@(write_mode0 - read_mark)
|
||||
tstb %a3@(read_error - read_mark)
|
||||
moveb #0x08, %a3@(write_mode1 - read_mark)
|
||||
|
||||
lea sector_address_mark, %a0
|
||||
moveq #3, %d1
|
||||
|
||||
wait_addr_mark_byte:
|
||||
|
||||
tstb %a2@
|
||||
dbmi %d2, wait_addr_mark_byte
|
||||
bpl header_exit
|
||||
|
||||
moveb %a3@, %d3
|
||||
cmpb %a0@+, %d3
|
||||
dbne %d1, wait_addr_mark_byte
|
||||
bne wait_header_init
|
||||
|
||||
moveq #max_retry, %d2
|
||||
|
||||
amark0: tstb %a2@
|
||||
dbmi %d2, amark0
|
||||
bpl signal_nonyb
|
||||
|
||||
moveb %a3@, %a4@(o_track)
|
||||
|
||||
moveq #max_retry, %d2
|
||||
|
||||
amark1: tstb %a2@
|
||||
dbmi %d2, amark1
|
||||
bpl signal_nonyb
|
||||
|
||||
moveb %a3@, %a4@(o_side)
|
||||
|
||||
moveq #max_retry, %d2
|
||||
|
||||
amark2: tstb %a2@
|
||||
dbmi %d2, amark2
|
||||
bpl signal_nonyb
|
||||
|
||||
moveb %a3@, %a4@(o_sector)
|
||||
|
||||
moveq #max_retry, %d2
|
||||
|
||||
amark3: tstb %a2@
|
||||
dbmi %d2, amark3
|
||||
bpl signal_nonyb
|
||||
|
||||
moveb %a3@, %a4@(o_size)
|
||||
|
||||
moveq #max_retry, %d2
|
||||
|
||||
crc0: tstb %a2@
|
||||
dbmi %d2, crc0
|
||||
bpl signal_nonyb
|
||||
|
||||
moveb %a3@, %a4@(o_crc0)
|
||||
|
||||
moveq #max_retry, %d2
|
||||
|
||||
crc1: tstb %a2@
|
||||
dbmi %d2, crc1
|
||||
bpl signal_nonyb
|
||||
|
||||
moveb %a3@, %a4@(o_crc1)
|
||||
|
||||
tstb %a3@(read_error - read_mark)
|
||||
|
||||
header_exit:
|
||||
moveq #0, %d0
|
||||
moveb #0x18, %a3@(write_mode0 - read_mark)
|
||||
rts
|
||||
signal_nonyb:
|
||||
moveq #-1, %d0
|
||||
moveb #0x18, %a3@(write_mode0 - read_mark)
|
||||
rts
|
||||
|
||||
.global swim_read_sector_data
|
||||
swim_read_sector_data:
|
||||
link %a6, #0
|
||||
moveml %d1-%d5/%a0-%a5,%sp@-
|
||||
movel %a6@(0x0c), %a4
|
||||
bsr mfm_read_data
|
||||
moveml %sp@+, %d1-%d5/%a0-%a5
|
||||
unlk %a6
|
||||
rts
|
||||
|
||||
mfm_read_data:
|
||||
movel %a6@(0x08), %a3
|
||||
lea %a3@(read_handshake), %a2
|
||||
lea %a3@(read_data), %a5
|
||||
lea %a3@(read_mark), %a3
|
||||
movew #seek_time, %d2
|
||||
|
||||
wait_data_init:
|
||||
tstb %a3@(read_error - read_mark)
|
||||
moveb #0x18, %a3@(write_mode0 - read_mark)
|
||||
moveb #0x01, %a3@(write_mode1 - read_mark)
|
||||
moveb #0x01, %a3@(write_mode0 - read_mark)
|
||||
tstb %a3@(read_error - read_mark)
|
||||
moveb #0x08, %a3@(write_mode1 - read_mark)
|
||||
|
||||
lea sector_data_mark, %a0
|
||||
moveq #3, %d1
|
||||
|
||||
/* wait data address mark */
|
||||
|
||||
wait_data_mark_byte:
|
||||
|
||||
tstb %a2@
|
||||
dbmi %d2, wait_data_mark_byte
|
||||
bpl data_exit
|
||||
|
||||
moveb %a3@, %d3
|
||||
cmpb %a0@+, %d3
|
||||
dbne %d1, wait_data_mark_byte
|
||||
bne wait_data_init
|
||||
|
||||
/* read data */
|
||||
|
||||
tstb %a3@(read_error - read_mark)
|
||||
|
||||
movel #sector_size-1, %d4 /* sector size */
|
||||
read_new_data:
|
||||
movew #max_retry, %d2
|
||||
read_data_loop:
|
||||
moveb %a2@, %d5
|
||||
andb #0xc0, %d5
|
||||
dbne %d2, read_data_loop
|
||||
beq data_exit
|
||||
moveb %a5@, %a4@+
|
||||
andb #0x40, %d5
|
||||
dbne %d4, read_new_data
|
||||
beq exit_loop
|
||||
moveb %a5@, %a4@+
|
||||
dbra %d4, read_new_data
|
||||
exit_loop:
|
||||
|
||||
/* read CRC */
|
||||
|
||||
movew #max_retry, %d2
|
||||
data_crc0:
|
||||
|
||||
tstb %a2@
|
||||
dbmi %d2, data_crc0
|
||||
bpl data_exit
|
||||
|
||||
moveb %a3@, %d5
|
||||
|
||||
moveq #max_retry, %d2
|
||||
|
||||
data_crc1:
|
||||
|
||||
tstb %a2@
|
||||
dbmi %d2, data_crc1
|
||||
bpl data_exit
|
||||
|
||||
moveb %a3@, %d5
|
||||
|
||||
tstb %a3@(read_error - read_mark)
|
||||
|
||||
moveb #0x18, %a3@(write_mode0 - read_mark)
|
||||
|
||||
/* return number of bytes read */
|
||||
|
||||
movel #sector_size, %d0
|
||||
addw #1, %d4
|
||||
subl %d4, %d0
|
||||
rts
|
||||
data_exit:
|
||||
moveb #0x18, %a3@(write_mode0 - read_mark)
|
||||
moveq #-1, %d0
|
||||
rts
|
||||
Reference in New Issue
Block a user