Fixed MTP to work with TWRP

This commit is contained in:
awab228 2018-06-19 23:16:04 +02:00
commit f6dfaef42e
50820 changed files with 20846062 additions and 0 deletions

9
arch/m68k/emu/Makefile Normal file
View file

@ -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

94
arch/m68k/emu/natfeat.c Normal file
View file

@ -0,0 +1,94 @@
/*
* natfeat.c - ARAnyM hardware support via Native Features (natfeats)
*
* Copyright (c) 2005 Petr Stehlik of ARAnyM dev team
*
* Reworked for Linux by Roman Zippel <zippel@linux-m68k.org>
*
* This software may be used and distributed according to the terms of
* the GNU General Public License (GPL), incorporated herein by reference.
*/
#include <linux/init.h>
#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>
extern long nf_get_id_phys(unsigned long feature_name);
asm("\n"
" .global nf_get_id_phys,nf_call\n"
"nf_get_id_phys:\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_phys,1b\n"
" .long nf_call,1b\n"
" .previous");
EXPORT_SYMBOL_GPL(nf_call);
long nf_get_id(const char *feature_name)
{
/* feature_name may be in vmalloc()ed memory, so make a copy */
char name_copy[32];
size_t n;
n = strlcpy(name_copy, feature_name, sizeof(name_copy));
if (n >= sizeof(name_copy))
return 0;
return nf_get_id_phys(virt_to_phys(name_copy));
}
EXPORT_SYMBOL_GPL(nf_get_id);
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"), virt_to_phys(buf));
va_end(ap);
}
static void nf_poweroff(void)
{
long id = nf_get_id("NF_SHUTDOWN");
if (id)
nf_call(id);
}
void __init 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, virt_to_phys(buf), 256);
buf[255] = 0;
pr_info("NatFeats found (%s, %lu.%lu)\n", buf, version >> 16,
version & 0xffff);
mach_power_off = nf_poweroff;
}

195
arch/m68k/emu/nfblock.c Normal file
View file

@ -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,
virt_to_phys(blocks), virt_to_phys(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 void nfhd_make_request(struct request_queue *queue, struct bio *bio)
{
struct nfhd_device *dev = queue->queuedata;
struct bio_vec bvec;
struct bvec_iter iter;
int dir, len, shift;
sector_t sec = bio->bi_iter.bi_sector;
dir = bio_data_dir(bio);
shift = dev->bshift;
bio_for_each_segment(bvec, bio, iter) {
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);
}
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");

169
arch/m68k/emu/nfcon.c Normal file
View file

@ -0,0 +1,169 @@
/*
* ARAnyM console 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/init.h>
#include <linux/console.h>
#include <linux/tty.h>
#include <linux/tty_driver.h>
#include <linux/tty_flip.h>
#include <linux/slab.h>
#include <linux/err.h>
#include <linux/uaccess.h>
#include <linux/io.h>
#include <asm/natfeat.h>
static int stderr_id;
static struct tty_port nfcon_tty_port;
static struct tty_driver *nfcon_tty_driver;
static void nfputs(const char *str, unsigned int count)
{
char buf[68];
unsigned long phys = virt_to_phys(buf);
buf[64] = 0;
while (count > 64) {
memcpy(buf, str, 64);
nf_call(stderr_id, phys);
str += 64;
count -= 64;
}
memcpy(buf, str, count);
buf[count] = 0;
nf_call(stderr_id, phys);
}
static void nfcon_write(struct console *con, const char *str,
unsigned int count)
{
nfputs(str, count);
}
static struct tty_driver *nfcon_device(struct console *con, int *index)
{
*index = 0;
return (con->flags & CON_ENABLED) ? nfcon_tty_driver : NULL;
}
static struct console nf_console = {
.name = "nfcon",
.write = nfcon_write,
.device = nfcon_device,
.flags = CON_PRINTBUFFER,
.index = -1,
};
static int nfcon_tty_open(struct tty_struct *tty, struct file *filp)
{
return 0;
}
static void nfcon_tty_close(struct tty_struct *tty, struct file *filp)
{
}
static int nfcon_tty_write(struct tty_struct *tty, const unsigned char *buf,
int count)
{
nfputs(buf, count);
return count;
}
static int nfcon_tty_put_char(struct tty_struct *tty, unsigned char ch)
{
char temp[2] = { ch, 0 };
nf_call(stderr_id, virt_to_phys(temp));
return 1;
}
static int nfcon_tty_write_room(struct tty_struct *tty)
{
return 64;
}
static const struct tty_operations nfcon_tty_ops = {
.open = nfcon_tty_open,
.close = nfcon_tty_close,
.write = nfcon_tty_write,
.put_char = nfcon_tty_put_char,
.write_room = nfcon_tty_write_room,
};
#ifndef MODULE
static int __init nf_debug_setup(char *arg)
{
if (strcmp(arg, "nfcon"))
return 0;
stderr_id = nf_get_id("NF_STDERR");
if (stderr_id) {
nf_console.flags |= CON_ENABLED;
register_console(&nf_console);
}
return 0;
}
early_param("debug", nf_debug_setup);
#endif /* !MODULE */
static int __init nfcon_init(void)
{
int res;
stderr_id = nf_get_id("NF_STDERR");
if (!stderr_id)
return -ENODEV;
nfcon_tty_driver = alloc_tty_driver(1);
if (!nfcon_tty_driver)
return -ENOMEM;
tty_port_init(&nfcon_tty_port);
nfcon_tty_driver->driver_name = "nfcon";
nfcon_tty_driver->name = "nfcon";
nfcon_tty_driver->type = TTY_DRIVER_TYPE_SYSTEM;
nfcon_tty_driver->subtype = SYSTEM_TYPE_TTY;
nfcon_tty_driver->init_termios = tty_std_termios;
nfcon_tty_driver->flags = TTY_DRIVER_REAL_RAW;
tty_set_operations(nfcon_tty_driver, &nfcon_tty_ops);
tty_port_link_device(&nfcon_tty_port, nfcon_tty_driver, 0);
res = tty_register_driver(nfcon_tty_driver);
if (res) {
pr_err("failed to register nfcon tty driver\n");
put_tty_driver(nfcon_tty_driver);
tty_port_destroy(&nfcon_tty_port);
return res;
}
if (!(nf_console.flags & CON_ENABLED))
register_console(&nf_console);
return 0;
}
static void __exit nfcon_exit(void)
{
unregister_console(&nf_console);
tty_unregister_driver(nfcon_tty_driver);
put_tty_driver(nfcon_tty_driver);
tty_port_destroy(&nfcon_tty_port);
}
module_init(nfcon_init);
module_exit(nfcon_exit);
MODULE_LICENSE("GPL");

271
arch/m68k/emu/nfeth.c Normal file
View file

@ -0,0 +1,271 @@
/*
* atari_nfeth.c - ARAnyM ethernet card driver for GNU/Linux
*
* Copyright (c) 2005 Milan Jurik, Petr Stehlik of ARAnyM dev team
*
* Based on ARAnyM driver for FreeMiNT written by Standa Opichal
*
* This software may be used and distributed according to the terms of
* the GNU General Public License (GPL), incorporated herein by reference.
*/
#define DRV_VERSION "0.3"
#define DRV_RELDATE "10/12/2005"
#define pr_fmt(fmt) KBUILD_MODNAME ": " fmt
#include <linux/netdevice.h>
#include <linux/etherdevice.h>
#include <linux/interrupt.h>
#include <linux/module.h>
#include <asm/natfeat.h>
#include <asm/virtconvert.h>
enum {
GET_VERSION = 0,/* no parameters, return NFAPI_VERSION in d0 */
XIF_INTLEVEL, /* no parameters, return Interrupt Level in d0 */
XIF_IRQ, /* acknowledge interrupt from host */
XIF_START, /* (ethX), called on 'ifup', start receiver thread */
XIF_STOP, /* (ethX), called on 'ifdown', stop the thread */
XIF_READLENGTH, /* (ethX), return size of network data block to read */
XIF_READBLOCK, /* (ethX, buffer, size), read block of network data */
XIF_WRITEBLOCK, /* (ethX, buffer, size), write block of network data */
XIF_GET_MAC, /* (ethX, buffer, size), return MAC HW addr in buffer */
XIF_GET_IPHOST, /* (ethX, buffer, size), return IP address of host */
XIF_GET_IPATARI,/* (ethX, buffer, size), return IP address of atari */
XIF_GET_NETMASK /* (ethX, buffer, size), return IP netmask */
};
#define MAX_UNIT 8
/* These identify the driver base version and may not be removed. */
static const char version[] =
KERN_INFO KBUILD_MODNAME ".c:v" DRV_VERSION " " DRV_RELDATE
" S.Opichal, M.Jurik, P.Stehlik\n"
KERN_INFO " http://aranym.org/\n";
MODULE_AUTHOR("Milan Jurik");
MODULE_DESCRIPTION("Atari NFeth driver");
MODULE_LICENSE("GPL");
/*
MODULE_PARM(nfeth_debug, "i");
MODULE_PARM_DESC(nfeth_debug, "nfeth_debug level (1-2)");
*/
static long nfEtherID;
static int nfEtherIRQ;
struct nfeth_private {
int ethX;
};
static struct net_device *nfeth_dev[MAX_UNIT];
static int nfeth_open(struct net_device *dev)
{
struct nfeth_private *priv = netdev_priv(dev);
int res;
res = nf_call(nfEtherID + XIF_START, priv->ethX);
netdev_dbg(dev, "%s: %d\n", __func__, res);
/* Ready for data */
netif_start_queue(dev);
return 0;
}
static int nfeth_stop(struct net_device *dev)
{
struct nfeth_private *priv = netdev_priv(dev);
/* No more data */
netif_stop_queue(dev);
nf_call(nfEtherID + XIF_STOP, priv->ethX);
return 0;
}
/*
* Read a packet out of the adapter and pass it to the upper layers
*/
static inline void recv_packet(struct net_device *dev)
{
struct nfeth_private *priv = netdev_priv(dev);
unsigned short pktlen;
struct sk_buff *skb;
/* read packet length (excluding 32 bit crc) */
pktlen = nf_call(nfEtherID + XIF_READLENGTH, priv->ethX);
netdev_dbg(dev, "%s: %u\n", __func__, pktlen);
if (!pktlen) {
netdev_dbg(dev, "%s: pktlen == 0\n", __func__);
dev->stats.rx_errors++;
return;
}
skb = dev_alloc_skb(pktlen + 2);
if (!skb) {
netdev_dbg(dev, "%s: out of mem (buf_alloc failed)\n",
__func__);
dev->stats.rx_dropped++;
return;
}
skb->dev = dev;
skb_reserve(skb, 2); /* 16 Byte align */
skb_put(skb, pktlen); /* make room */
nf_call(nfEtherID + XIF_READBLOCK, priv->ethX, virt_to_phys(skb->data),
pktlen);
skb->protocol = eth_type_trans(skb, dev);
netif_rx(skb);
dev->last_rx = jiffies;
dev->stats.rx_packets++;
dev->stats.rx_bytes += pktlen;
/* and enqueue packet */
return;
}
static irqreturn_t nfeth_interrupt(int irq, void *dev_id)
{
int i, m, mask;
mask = nf_call(nfEtherID + XIF_IRQ, 0);
for (i = 0, m = 1; i < MAX_UNIT; m <<= 1, i++) {
if (mask & m && nfeth_dev[i]) {
recv_packet(nfeth_dev[i]);
nf_call(nfEtherID + XIF_IRQ, m);
}
}
return IRQ_HANDLED;
}
static int nfeth_xmit(struct sk_buff *skb, struct net_device *dev)
{
unsigned int len;
char *data, shortpkt[ETH_ZLEN];
struct nfeth_private *priv = netdev_priv(dev);
data = skb->data;
len = skb->len;
if (len < ETH_ZLEN) {
memset(shortpkt, 0, ETH_ZLEN);
memcpy(shortpkt, data, len);
data = shortpkt;
len = ETH_ZLEN;
}
netdev_dbg(dev, "%s: send %u bytes\n", __func__, len);
nf_call(nfEtherID + XIF_WRITEBLOCK, priv->ethX, virt_to_phys(data),
len);
dev->stats.tx_packets++;
dev->stats.tx_bytes += len;
dev_kfree_skb(skb);
return 0;
}
static void nfeth_tx_timeout(struct net_device *dev)
{
dev->stats.tx_errors++;
netif_wake_queue(dev);
}
static const struct net_device_ops nfeth_netdev_ops = {
.ndo_open = nfeth_open,
.ndo_stop = nfeth_stop,
.ndo_start_xmit = nfeth_xmit,
.ndo_tx_timeout = nfeth_tx_timeout,
.ndo_validate_addr = eth_validate_addr,
.ndo_change_mtu = eth_change_mtu,
.ndo_set_mac_address = eth_mac_addr,
};
static struct net_device * __init nfeth_probe(int unit)
{
struct net_device *dev;
struct nfeth_private *priv;
char mac[ETH_ALEN], host_ip[32], local_ip[32];
int err;
if (!nf_call(nfEtherID + XIF_GET_MAC, unit, virt_to_phys(mac),
ETH_ALEN))
return NULL;
dev = alloc_etherdev(sizeof(struct nfeth_private));
if (!dev)
return NULL;
dev->irq = nfEtherIRQ;
dev->netdev_ops = &nfeth_netdev_ops;
memcpy(dev->dev_addr, mac, ETH_ALEN);
priv = netdev_priv(dev);
priv->ethX = unit;
err = register_netdev(dev);
if (err) {
free_netdev(dev);
return NULL;
}
nf_call(nfEtherID + XIF_GET_IPHOST, unit,
virt_to_phys(host_ip), sizeof(host_ip));
nf_call(nfEtherID + XIF_GET_IPATARI, unit,
virt_to_phys(local_ip), sizeof(local_ip));
netdev_info(dev, KBUILD_MODNAME " addr:%s (%s) HWaddr:%pM\n", host_ip,
local_ip, mac);
return dev;
}
static int __init nfeth_init(void)
{
long ver;
int error, i;
nfEtherID = nf_get_id("ETHERNET");
if (!nfEtherID)
return -ENODEV;
ver = nf_call(nfEtherID + GET_VERSION);
pr_info("API %lu\n", ver);
nfEtherIRQ = nf_call(nfEtherID + XIF_INTLEVEL);
error = request_irq(nfEtherIRQ, nfeth_interrupt, IRQF_SHARED,
"eth emu", nfeth_interrupt);
if (error) {
pr_err("request for irq %d failed %d", nfEtherIRQ, error);
return error;
}
for (i = 0; i < MAX_UNIT; i++)
nfeth_dev[i] = nfeth_probe(i);
return 0;
}
static void __exit nfeth_cleanup(void)
{
int i;
for (i = 0; i < MAX_UNIT; i++) {
if (nfeth_dev[i]) {
unregister_netdev(nfeth_dev[0]);
free_netdev(nfeth_dev[0]);
}
}
free_irq(nfEtherIRQ, nfeth_interrupt);
}
module_init(nfeth_init);
module_exit(nfeth_cleanup);