Skip to content

Commit

Permalink
Merge branch 'for-linus' of git://git.kernel.org/pub/scm/linux/kernel…
Browse files Browse the repository at this point in the history
…/git/geert/linux-m68k

* 'for-linus' of git://git.kernel.org/pub/scm/linux/kernel/git/geert/linux-m68k:
  m68k/block: amiflop - Remove superfluous amiga_chip_alloc() cast
  m68k/atari: ARAnyM - Add support for network access
  m68k/atari: ARAnyM - Add support for console access
  m68k/atari: ARAnyM - Add support for block access
  m68k/atari: Initial ARAnyM support
  m68k: Kconfig - Remove unneeded "default n"
  m68k: Makefiles - Change to new flags variables
  m68k/amiga: Reclaim Chip RAM for PPC exception handlers
  m68k: Allow all kernel traps to be handled via exception fixups
  m68k: Use base_trap_init() to initialize vectors
  m68k: Add helper function handle_kernel_fault()
  • Loading branch information
torvalds committed Mar 17, 2011
2 parents 63a9369 + 059718d commit dc113c1
Show file tree
Hide file tree
Showing 16 changed files with 815 additions and 34 deletions.
33 changes: 31 additions & 2 deletions arch/m68k/Kconfig
Original file line number Diff line number Diff line change
Expand Up @@ -18,11 +18,9 @@ config RWSEM_XCHGADD_ALGORITHM

config ARCH_HAS_ILOG2_U32
bool
default n

config ARCH_HAS_ILOG2_U64
bool
default n

config GENERIC_HWEIGHT
bool
Expand Down Expand Up @@ -242,6 +240,37 @@ config SUN3

If you don't want to compile a kernel exclusively for a Sun 3, say N.

config NATFEAT
bool "ARAnyM emulator support"
depends on ATARI
help
This option enables support for ARAnyM native features, such as
access to a disk image as /dev/hda.

config NFBLOCK
tristate "NatFeat block device support"
depends on BLOCK && NATFEAT
help
Say Y to include support for the ARAnyM NatFeat block device
which allows direct access to the hard drives without using
the hardware emulation.

config NFCON
tristate "NatFeat console driver"
depends on NATFEAT
help
Say Y to include support for the ARAnyM NatFeat console driver
which allows the console output to be redirected to the stderr
output of ARAnyM.

config NFETH
tristate "NatFeat Ethernet support"
depends on NET_ETHERNET && NATFEAT
help
Say Y to include support for the ARAnyM NatFeat network device
which will emulate a regular ethernet device while presenting an
ethertap device to the host system.

comment "Processor type"

config M68020
Expand Down
1 change: 1 addition & 0 deletions arch/m68k/Makefile
Original file line number Diff line number Diff line change
Expand Up @@ -76,6 +76,7 @@ core-$(CONFIG_MVME16x) += arch/m68k/mvme16x/
core-$(CONFIG_BVME6000) += arch/m68k/bvme6000/
core-$(CONFIG_SUN3X) += arch/m68k/sun3x/ arch/m68k/sun3/
core-$(CONFIG_SUN3) += arch/m68k/sun3/ arch/m68k/sun3/prom/
core-$(CONFIG_NATFEAT) += arch/m68k/emu/
core-$(CONFIG_M68040) += arch/m68k/fpsp040/
core-$(CONFIG_M68060) += arch/m68k/ifpsp060/
core-$(CONFIG_M68KFPU_EMU) += arch/m68k/math-emu/
Expand Down
4 changes: 0 additions & 4 deletions arch/m68k/amiga/chipram.c
Original file line number Diff line number Diff line change
Expand Up @@ -33,10 +33,6 @@ void __init amiga_chip_init(void)
if (!AMIGAHW_PRESENT(CHIP_RAM))
return;

/*
* Remove the first 4 pages where PPC exception handlers will be located
*/
amiga_chip_size -= 0x4000;
chipram_res.end = amiga_chip_size-1;
request_resource(&iomem_resource, &chipram_res);

Expand Down
9 changes: 9 additions & 0 deletions arch/m68k/emu/Makefile
Original file line number Diff line number Diff line change
@@ -0,0 +1,9 @@
#
# Makefile for Linux arch/m68k/emu source directory
#

obj-y += natfeat.o

obj-$(CONFIG_NFBLOCK) += nfblock.o
obj-$(CONFIG_NFCON) += nfcon.o
obj-$(CONFIG_NFETH) += nfeth.o
78 changes: 78 additions & 0 deletions arch/m68k/emu/natfeat.c
Original file line number Diff line number Diff line change
@@ -0,0 +1,78 @@
/*
* natfeat.c - ARAnyM hardware support via Native Features (natfeats)
*
* Copyright (c) 2005 Petr Stehlik of ARAnyM dev team
*
* Reworked for Linux by Roman Zippel <[email protected]>
*
* This software may be used and distributed according to the terms of
* the GNU General Public License (GPL), incorporated herein by reference.
*/

#include <linux/types.h>
#include <linux/console.h>
#include <linux/string.h>
#include <linux/kernel.h>
#include <linux/module.h>
#include <linux/io.h>
#include <asm/machdep.h>
#include <asm/natfeat.h>

asm("\n"
" .global nf_get_id,nf_call\n"
"nf_get_id:\n"
" .short 0x7300\n"
" rts\n"
"nf_call:\n"
" .short 0x7301\n"
" rts\n"
"1: moveq.l #0,%d0\n"
" rts\n"
" .section __ex_table,\"a\"\n"
" .long nf_get_id,1b\n"
" .long nf_call,1b\n"
" .previous");
EXPORT_SYMBOL_GPL(nf_get_id);
EXPORT_SYMBOL_GPL(nf_call);

void nfprint(const char *fmt, ...)
{
static char buf[256];
va_list ap;
int n;

va_start(ap, fmt);
n = vsnprintf(buf, 256, fmt, ap);
nf_call(nf_get_id("NF_STDERR"), buf);
va_end(ap);
}

static void nf_poweroff(void)
{
long id = nf_get_id("NF_SHUTDOWN");

if (id)
nf_call(id);
}

void nf_init(void)
{
unsigned long id, version;
char buf[256];

id = nf_get_id("NF_VERSION");
if (!id)
return;
version = nf_call(id);

id = nf_get_id("NF_NAME");
if (!id)
return;
nf_call(id, buf, 256);
buf[255] = 0;

pr_info("NatFeats found (%s, %lu.%lu)\n", buf, version >> 16,
version & 0xffff);

mach_power_off = nf_poweroff;
}
195 changes: 195 additions & 0 deletions arch/m68k/emu/nfblock.c
Original file line number Diff line number Diff line change
@@ -0,0 +1,195 @@
/*
* ARAnyM block device driver
*
* This file is subject to the terms and conditions of the GNU General Public
* License. See the file COPYING in the main directory of this archive
* for more details.
*/

#include <linux/module.h>
#include <linux/moduleparam.h>
#include <linux/init.h>

#include <linux/kernel.h>
#include <linux/errno.h>
#include <linux/types.h>
#include <linux/genhd.h>
#include <linux/blkdev.h>
#include <linux/hdreg.h>
#include <linux/slab.h>

#include <asm/natfeat.h>

static long nfhd_id;

enum {
/* emulation entry points */
NFHD_READ_WRITE = 10,
NFHD_GET_CAPACITY = 14,

/* skip ACSI devices */
NFHD_DEV_OFFSET = 8,
};

static inline s32 nfhd_read_write(u32 major, u32 minor, u32 rwflag, u32 recno,
u32 count, u32 buf)
{
return nf_call(nfhd_id + NFHD_READ_WRITE, major, minor, rwflag, recno,
count, buf);
}

static inline s32 nfhd_get_capacity(u32 major, u32 minor, u32 *blocks,
u32 *blocksize)
{
return nf_call(nfhd_id + NFHD_GET_CAPACITY, major, minor, blocks,
blocksize);
}

static LIST_HEAD(nfhd_list);

static int major_num;
module_param(major_num, int, 0);

struct nfhd_device {
struct list_head list;
int id;
u32 blocks, bsize;
int bshift;
struct request_queue *queue;
struct gendisk *disk;
};

static int nfhd_make_request(struct request_queue *queue, struct bio *bio)
{
struct nfhd_device *dev = queue->queuedata;
struct bio_vec *bvec;
int i, dir, len, shift;
sector_t sec = bio->bi_sector;

dir = bio_data_dir(bio);
shift = dev->bshift;
bio_for_each_segment(bvec, bio, i) {
len = bvec->bv_len;
len >>= 9;
nfhd_read_write(dev->id, 0, dir, sec >> shift, len >> shift,
bvec_to_phys(bvec));
sec += len;
}
bio_endio(bio, 0);
return 0;
}

static int nfhd_getgeo(struct block_device *bdev, struct hd_geometry *geo)
{
struct nfhd_device *dev = bdev->bd_disk->private_data;

geo->cylinders = dev->blocks >> (6 - dev->bshift);
geo->heads = 4;
geo->sectors = 16;

return 0;
}

static const struct block_device_operations nfhd_ops = {
.owner = THIS_MODULE,
.getgeo = nfhd_getgeo,
};

static int __init nfhd_init_one(int id, u32 blocks, u32 bsize)
{
struct nfhd_device *dev;
int dev_id = id - NFHD_DEV_OFFSET;

pr_info("nfhd%u: found device with %u blocks (%u bytes)\n", dev_id,
blocks, bsize);

if (bsize < 512 || (bsize & (bsize - 1))) {
pr_warn("nfhd%u: invalid block size\n", dev_id);
return -EINVAL;
}

dev = kmalloc(sizeof(struct nfhd_device), GFP_KERNEL);
if (!dev)
goto out;

dev->id = id;
dev->blocks = blocks;
dev->bsize = bsize;
dev->bshift = ffs(bsize) - 10;

dev->queue = blk_alloc_queue(GFP_KERNEL);
if (dev->queue == NULL)
goto free_dev;

dev->queue->queuedata = dev;
blk_queue_make_request(dev->queue, nfhd_make_request);
blk_queue_logical_block_size(dev->queue, bsize);

dev->disk = alloc_disk(16);
if (!dev->disk)
goto free_queue;

dev->disk->major = major_num;
dev->disk->first_minor = dev_id * 16;
dev->disk->fops = &nfhd_ops;
dev->disk->private_data = dev;
sprintf(dev->disk->disk_name, "nfhd%u", dev_id);
set_capacity(dev->disk, (sector_t)blocks * (bsize / 512));
dev->disk->queue = dev->queue;

add_disk(dev->disk);

list_add_tail(&dev->list, &nfhd_list);

return 0;

free_queue:
blk_cleanup_queue(dev->queue);
free_dev:
kfree(dev);
out:
return -ENOMEM;
}

static int __init nfhd_init(void)
{
u32 blocks, bsize;
int i;

nfhd_id = nf_get_id("XHDI");
if (!nfhd_id)
return -ENODEV;

major_num = register_blkdev(major_num, "nfhd");
if (major_num <= 0) {
pr_warn("nfhd: unable to get major number\n");
return major_num;
}

for (i = NFHD_DEV_OFFSET; i < 24; i++) {
if (nfhd_get_capacity(i, 0, &blocks, &bsize))
continue;
nfhd_init_one(i, blocks, bsize);
}

return 0;
}

static void __exit nfhd_exit(void)
{
struct nfhd_device *dev, *next;

list_for_each_entry_safe(dev, next, &nfhd_list, list) {
list_del(&dev->list);
del_gendisk(dev->disk);
put_disk(dev->disk);
blk_cleanup_queue(dev->queue);
kfree(dev);
}
unregister_blkdev(major_num, "nfhd");
}

module_init(nfhd_init);
module_exit(nfhd_exit);

MODULE_LICENSE("GPL");
Loading

0 comments on commit dc113c1

Please sign in to comment.