Commit 48a97054 authored by Jeff Garzik's avatar Jeff Garzik

Merge redhat.com:/spare/repo/netdev-2.6/misc

into redhat.com:/spare/repo/net-drivers-2.5
parents 2b65a560 627f8b57
...@@ -40,7 +40,7 @@ config IEEE1394_OUI_DB ...@@ -40,7 +40,7 @@ config IEEE1394_OUI_DB
help help
If you say Y here, then an OUI list (vendor unique ID's) will be If you say Y here, then an OUI list (vendor unique ID's) will be
compiled into the ieee1394 module. This doesn't really do much compiled into the ieee1394 module. This doesn't really do much
accept being able to display the vendor of a hardware node. The except being able to display the vendor of a hardware node. The
downside is that it adds about 300k to the size of the module, downside is that it adds about 300k to the size of the module,
or kernel (depending on whether you compile ieee1394 as a or kernel (depending on whether you compile ieee1394 as a
module, or static in the kernel). module, or static in the kernel).
......
...@@ -82,6 +82,7 @@ ...@@ -82,6 +82,7 @@
#include <linux/poll.h> #include <linux/poll.h>
#include <linux/ioctl32.h> #include <linux/ioctl32.h>
#include <linux/compat.h> #include <linux/compat.h>
#include <linux/cdev.h>
#include <asm/uaccess.h> #include <asm/uaccess.h>
#include <asm/atomic.h> #include <asm/atomic.h>
...@@ -1196,6 +1197,7 @@ static int amdtp_release(struct inode *inode, struct file *file) ...@@ -1196,6 +1197,7 @@ static int amdtp_release(struct inode *inode, struct file *file)
return 0; return 0;
} }
static struct cdev amdtp_cdev;
static struct file_operations amdtp_fops = static struct file_operations amdtp_fops =
{ {
.owner = THIS_MODULE, .owner = THIS_MODULE,
...@@ -1262,12 +1264,11 @@ MODULE_LICENSE("GPL"); ...@@ -1262,12 +1264,11 @@ MODULE_LICENSE("GPL");
static int __init amdtp_init_module (void) static int __init amdtp_init_module (void)
{ {
int ret; cdev_init(&amdtp_cdev, &amdtp_fops);
amdtp_cdev.owner = THIS_MODULE;
ret = ieee1394_register_chardev(IEEE1394_MINOR_BLOCK_AMDTP, kobject_set_name(&amdtp_cdev.kobj, "amdtp");
THIS_MODULE, &amdtp_fops); if (cdev_add(&amdtp_cdev, IEEE1394_AMDTP_DEV, 16)) {
if (ret) { HPSB_ERR("amdtp: unable to add char device");
HPSB_ERR("amdtp: unable to get minor device block");
return -EIO; return -EIO;
} }
...@@ -1276,12 +1277,15 @@ static int __init amdtp_init_module (void) ...@@ -1276,12 +1277,15 @@ static int __init amdtp_init_module (void)
hpsb_register_highlevel(&amdtp_highlevel); hpsb_register_highlevel(&amdtp_highlevel);
#ifdef CONFIG_COMPAT #ifdef CONFIG_COMPAT
{
int ret;
ret = register_ioctl32_conversion(AMDTP_IOC_CHANNEL, NULL); ret = register_ioctl32_conversion(AMDTP_IOC_CHANNEL, NULL);
ret |= register_ioctl32_conversion(AMDTP_IOC_PLUG, NULL); ret |= register_ioctl32_conversion(AMDTP_IOC_PLUG, NULL);
ret |= register_ioctl32_conversion(AMDTP_IOC_PING, NULL); ret |= register_ioctl32_conversion(AMDTP_IOC_PING, NULL);
ret |= register_ioctl32_conversion(AMDTP_IOC_ZAP, NULL); ret |= register_ioctl32_conversion(AMDTP_IOC_ZAP, NULL);
if (ret) if (ret)
HPSB_ERR("amdtp: Error registering ioctl32 translations"); HPSB_ERR("amdtp: Error registering ioctl32 translations");
}
#endif #endif
HPSB_INFO("Loaded AMDTP driver"); HPSB_INFO("Loaded AMDTP driver");
...@@ -1304,10 +1308,12 @@ static void __exit amdtp_exit_module (void) ...@@ -1304,10 +1308,12 @@ static void __exit amdtp_exit_module (void)
hpsb_unregister_highlevel(&amdtp_highlevel); hpsb_unregister_highlevel(&amdtp_highlevel);
devfs_remove("amdtp"); devfs_remove("amdtp");
ieee1394_unregister_chardev(IEEE1394_MINOR_BLOCK_AMDTP); cdev_unmap(IEEE1394_AMDTP_DEV, 16);
cdev_del(&amdtp_cdev);
HPSB_INFO("Unloaded AMDTP driver"); HPSB_INFO("Unloaded AMDTP driver");
} }
module_init(amdtp_init_module); module_init(amdtp_init_module);
module_exit(amdtp_exit_module); module_exit(amdtp_exit_module);
MODULE_ALIAS_CHARDEV(IEEE1394_MAJOR, IEEE1394_MINOR_BLOCK_AMDTP * 16);
...@@ -77,6 +77,25 @@ enum { ...@@ -77,6 +77,25 @@ enum {
static struct hpsb_highlevel cmp_highlevel; static struct hpsb_highlevel cmp_highlevel;
static void cmp_add_host(struct hpsb_host *host);
static void cmp_host_reset(struct hpsb_host *host);
static int pcr_read(struct hpsb_host *host, int nodeid, quadlet_t *buf,
u64 addr, size_t length, u16 flags);
static int pcr_lock(struct hpsb_host *host, int nodeid, quadlet_t *store,
u64 addr, quadlet_t data, quadlet_t arg, int extcode, u16 flags);
static struct hpsb_highlevel cmp_highlevel = {
.name = "cmp",
.add_host = cmp_add_host,
.host_reset = cmp_host_reset,
};
static struct hpsb_address_ops pcr_ops = {
.read = pcr_read,
.lock = pcr_lock,
};
struct cmp_pcr * struct cmp_pcr *
cmp_register_opcr(struct hpsb_host *host, int opcr_number, int payload, cmp_register_opcr(struct hpsb_host *host, int opcr_number, int payload,
void (*update)(struct cmp_pcr *pcr, void *data), void (*update)(struct cmp_pcr *pcr, void *data),
...@@ -137,6 +156,10 @@ static void cmp_add_host(struct hpsb_host *host) ...@@ -137,6 +156,10 @@ static void cmp_add_host(struct hpsb_host *host)
return; return;
} }
hpsb_register_addrspace(&cmp_highlevel, host, &pcr_ops,
CSR_REGISTER_BASE + CSR_PCR_MAP,
CSR_REGISTER_BASE + CSR_PCR_MAP_END);
ch->host = host; ch->host = host;
ch->u.ompr.rate = IEEE1394_SPEED_100; ch->u.ompr.rate = IEEE1394_SPEED_100;
ch->u.ompr.bcast_channel_base = 63; ch->u.ompr.bcast_channel_base = 63;
...@@ -258,17 +281,6 @@ static int pcr_lock(struct hpsb_host *host, int nodeid, quadlet_t *store, ...@@ -258,17 +281,6 @@ static int pcr_lock(struct hpsb_host *host, int nodeid, quadlet_t *store,
} }
static struct hpsb_highlevel cmp_highlevel = {
.name = "cmp",
.add_host = cmp_add_host,
.host_reset = cmp_host_reset,
};
static struct hpsb_address_ops pcr_ops = {
.read = pcr_read,
.lock = pcr_lock,
};
/* Module interface */ /* Module interface */
MODULE_AUTHOR("Kristian Hogsberg <hogsberg@users.sf.net>"); MODULE_AUTHOR("Kristian Hogsberg <hogsberg@users.sf.net>");
...@@ -283,10 +295,6 @@ static int __init cmp_init_module (void) ...@@ -283,10 +295,6 @@ static int __init cmp_init_module (void)
{ {
hpsb_register_highlevel (&cmp_highlevel); hpsb_register_highlevel (&cmp_highlevel);
hpsb_register_addrspace(&cmp_highlevel, &pcr_ops,
CSR_REGISTER_BASE + CSR_PCR_MAP,
CSR_REGISTER_BASE + CSR_PCR_MAP_END);
HPSB_INFO("Loaded CMP driver"); HPSB_INFO("Loaded CMP driver");
return 0; return 0;
......
...@@ -35,6 +35,43 @@ static int fcp = 1; ...@@ -35,6 +35,43 @@ static int fcp = 1;
module_param(fcp, int, 0444); module_param(fcp, int, 0444);
MODULE_PARM_DESC(fcp, "Map FCP registers (default = 1, disable = 0)."); MODULE_PARM_DESC(fcp, "Map FCP registers (default = 1, disable = 0).");
static void add_host(struct hpsb_host *host);
static void host_reset(struct hpsb_host *host);
static int read_maps(struct hpsb_host *host, int nodeid, quadlet_t *buffer,
u64 addr, size_t length, u16 fl);
static int write_fcp(struct hpsb_host *host, int nodeid, int dest,
quadlet_t *data, u64 addr, size_t length, u16 flags);
static int read_regs(struct hpsb_host *host, int nodeid, quadlet_t *buf,
u64 addr, size_t length, u16 flags);
static int write_regs(struct hpsb_host *host, int nodeid, int destid,
quadlet_t *data, u64 addr, size_t length, u16 flags);
static int lock_regs(struct hpsb_host *host, int nodeid, quadlet_t *store,
u64 addr, quadlet_t data, quadlet_t arg, int extcode, u16 fl);
static int lock64_regs(struct hpsb_host *host, int nodeid, octlet_t * store,
u64 addr, octlet_t data, octlet_t arg, int extcode, u16 fl);
static struct hpsb_highlevel csr_highlevel = {
.name = "standard registers",
.add_host = add_host,
.host_reset = host_reset,
};
static struct hpsb_address_ops map_ops = {
.read = read_maps,
};
static struct hpsb_address_ops fcp_ops = {
.write = write_fcp,
};
static struct hpsb_address_ops reg_ops = {
.read = read_regs,
.write = write_regs,
.lock = lock_regs,
.lock64 = lock64_regs,
};
static u16 csr_crc16(unsigned *data, int length) static u16 csr_crc16(unsigned *data, int length)
{ {
int check=0, i; int check=0, i;
...@@ -125,6 +162,24 @@ static inline void calculate_expire(struct csr_control *csr) ...@@ -125,6 +162,24 @@ static inline void calculate_expire(struct csr_control *csr)
static void add_host(struct hpsb_host *host) static void add_host(struct hpsb_host *host)
{ {
hpsb_register_addrspace(&csr_highlevel, host, &reg_ops,
CSR_REGISTER_BASE,
CSR_REGISTER_BASE + CSR_CONFIG_ROM);
hpsb_register_addrspace(&csr_highlevel, host, &map_ops,
CSR_REGISTER_BASE + CSR_CONFIG_ROM,
CSR_REGISTER_BASE + CSR_CONFIG_ROM_END);
if (fcp) {
hpsb_register_addrspace(&csr_highlevel, host, &fcp_ops,
CSR_REGISTER_BASE + CSR_FCP_COMMAND,
CSR_REGISTER_BASE + CSR_FCP_END);
}
hpsb_register_addrspace(&csr_highlevel, host, &map_ops,
CSR_REGISTER_BASE + CSR_TOPOLOGY_MAP,
CSR_REGISTER_BASE + CSR_TOPOLOGY_MAP_END);
hpsb_register_addrspace(&csr_highlevel, host, &map_ops,
CSR_REGISTER_BASE + CSR_SPEED_MAP,
CSR_REGISTER_BASE + CSR_SPEED_MAP_END);
host->csr.lock = SPIN_LOCK_UNLOCKED; host->csr.lock = SPIN_LOCK_UNLOCKED;
host->csr.rom_size = host->driver->get_rom(host, &host->csr.rom); host->csr.rom_size = host->driver->get_rom(host, &host->csr.rom);
...@@ -684,48 +739,10 @@ static int write_fcp(struct hpsb_host *host, int nodeid, int dest, ...@@ -684,48 +739,10 @@ static int write_fcp(struct hpsb_host *host, int nodeid, int dest,
} }
static struct hpsb_highlevel csr_highlevel = {
.name = "standard registers",
.add_host = add_host,
.host_reset = host_reset,
};
static struct hpsb_address_ops map_ops = {
.read = read_maps,
};
static struct hpsb_address_ops fcp_ops = {
.write = write_fcp,
};
static struct hpsb_address_ops reg_ops = {
.read = read_regs,
.write = write_regs,
.lock = lock_regs,
.lock64 = lock64_regs,
};
void init_csr(void) void init_csr(void)
{ {
hpsb_register_highlevel(&csr_highlevel); hpsb_register_highlevel(&csr_highlevel);
hpsb_register_addrspace(&csr_highlevel, &reg_ops, CSR_REGISTER_BASE,
CSR_REGISTER_BASE + CSR_CONFIG_ROM);
hpsb_register_addrspace(&csr_highlevel, &map_ops,
CSR_REGISTER_BASE + CSR_CONFIG_ROM,
CSR_REGISTER_BASE + CSR_CONFIG_ROM_END);
if (fcp) {
hpsb_register_addrspace(&csr_highlevel, &fcp_ops,
CSR_REGISTER_BASE + CSR_FCP_COMMAND,
CSR_REGISTER_BASE + CSR_FCP_END);
}
hpsb_register_addrspace(&csr_highlevel, &map_ops,
CSR_REGISTER_BASE + CSR_TOPOLOGY_MAP,
CSR_REGISTER_BASE + CSR_TOPOLOGY_MAP_END);
hpsb_register_addrspace(&csr_highlevel, &map_ops,
CSR_REGISTER_BASE + CSR_SPEED_MAP,
CSR_REGISTER_BASE + CSR_SPEED_MAP_END);
} }
void cleanup_csr(void) void cleanup_csr(void)
......
...@@ -110,6 +110,7 @@ ...@@ -110,6 +110,7 @@
#include <linux/string.h> #include <linux/string.h>
#include <linux/ioctl32.h> #include <linux/ioctl32.h>
#include <linux/compat.h> #include <linux/compat.h>
#include <linux/cdev.h>
#include "ieee1394.h" #include "ieee1394.h"
#include "ieee1394_types.h" #include "ieee1394_types.h"
...@@ -2165,6 +2166,7 @@ static void ir_tasklet_func(unsigned long data) ...@@ -2165,6 +2166,7 @@ static void ir_tasklet_func(unsigned long data)
spin_unlock(&video->spinlock); spin_unlock(&video->spinlock);
} }
static struct cdev dv1394_cdev;
static struct file_operations dv1394_fops= static struct file_operations dv1394_fops=
{ {
.owner = THIS_MODULE, .owner = THIS_MODULE,
...@@ -2607,17 +2609,17 @@ static void __exit dv1394_exit_module(void) ...@@ -2607,17 +2609,17 @@ static void __exit dv1394_exit_module(void)
hpsb_unregister_protocol(&dv1394_driver); hpsb_unregister_protocol(&dv1394_driver);
hpsb_unregister_highlevel(&dv1394_highlevel); hpsb_unregister_highlevel(&dv1394_highlevel);
ieee1394_unregister_chardev(IEEE1394_MINOR_BLOCK_DV1394); cdev_unmap(IEEE1394_DV1394_DEV, 16);
cdev_del(&dv1394_cdev);
devfs_remove("ieee1394/dv"); devfs_remove("ieee1394/dv");
} }
static int __init dv1394_init_module(void) static int __init dv1394_init_module(void)
{ {
int ret; cdev_init(&dv1394_cdev, &dv1394_fops);
dv1394_cdev.owner = THIS_MODULE;
ret = ieee1394_register_chardev(IEEE1394_MINOR_BLOCK_DV1394, kobject_set_name(&dv1394_cdev.kobj, "dv1394");
THIS_MODULE, &dv1394_fops); if (cdev_add(&dv1394_cdev, IEEE1394_DV1394_DEV, 16)) {
if (ret) {
printk(KERN_ERR "dv1394: unable to register character device\n"); printk(KERN_ERR "dv1394: unable to register character device\n");
return -EIO; return -EIO;
} }
...@@ -2629,6 +2631,9 @@ static int __init dv1394_init_module(void) ...@@ -2629,6 +2631,9 @@ static int __init dv1394_init_module(void)
hpsb_register_protocol(&dv1394_driver); hpsb_register_protocol(&dv1394_driver);
#ifdef CONFIG_COMPAT #ifdef CONFIG_COMPAT
{
int ret;
/* First compatible ones */ /* First compatible ones */
ret = register_ioctl32_conversion(DV1394_IOC_SHUTDOWN, NULL); ret = register_ioctl32_conversion(DV1394_IOC_SHUTDOWN, NULL);
ret |= register_ioctl32_conversion(DV1394_IOC_SUBMIT_FRAMES, NULL); ret |= register_ioctl32_conversion(DV1394_IOC_SUBMIT_FRAMES, NULL);
...@@ -2641,6 +2646,7 @@ static int __init dv1394_init_module(void) ...@@ -2641,6 +2646,7 @@ static int __init dv1394_init_module(void)
ret |= register_ioctl32_conversion(DV1394_IOC32_GET_STATUS, handle_dv1394_get_status); ret |= register_ioctl32_conversion(DV1394_IOC32_GET_STATUS, handle_dv1394_get_status);
if (ret) if (ret)
printk(KERN_ERR "dv1394: Error registering ioctl32 translations\n"); printk(KERN_ERR "dv1394: Error registering ioctl32 translations\n");
}
#endif #endif
return 0; return 0;
...@@ -2648,3 +2654,4 @@ static int __init dv1394_init_module(void) ...@@ -2648,3 +2654,4 @@ static int __init dv1394_init_module(void)
module_init(dv1394_init_module); module_init(dv1394_init_module);
module_exit(dv1394_exit_module); module_exit(dv1394_exit_module);
MODULE_ALIAS_CHARDEV(IEEE1394_MAJOR, IEEE1394_MINOR_BLOCK_DV1394 * 16);
...@@ -89,7 +89,7 @@ ...@@ -89,7 +89,7 @@
#define TRACE() printk(KERN_ERR "%s:%s[%d] ---- TRACE\n", driver_name, __FUNCTION__, __LINE__) #define TRACE() printk(KERN_ERR "%s:%s[%d] ---- TRACE\n", driver_name, __FUNCTION__, __LINE__)
static char version[] __devinitdata = static char version[] __devinitdata =
"$Rev: 1079 $ Ben Collins <bcollins@debian.org>"; "$Rev: 1096 $ Ben Collins <bcollins@debian.org>";
struct fragment_info { struct fragment_info {
struct list_head list; struct list_head list;
...@@ -168,6 +168,26 @@ static void ether1394_iso(struct hpsb_iso *iso); ...@@ -168,6 +168,26 @@ static void ether1394_iso(struct hpsb_iso *iso);
static int ether1394_do_ioctl(struct net_device *dev, struct ifreq *ifr, int cmd); static int ether1394_do_ioctl(struct net_device *dev, struct ifreq *ifr, int cmd);
static int ether1394_ethtool_ioctl(struct net_device *dev, void *useraddr); static int ether1394_ethtool_ioctl(struct net_device *dev, void *useraddr);
static int ether1394_write(struct hpsb_host *host, int srcid, int destid,
quadlet_t *data, u64 addr, size_t len, u16 flags);
static void ether1394_add_host (struct hpsb_host *host);
static void ether1394_remove_host (struct hpsb_host *host);
static void ether1394_host_reset (struct hpsb_host *host);
/* Function for incoming 1394 packets */
static struct hpsb_address_ops addr_ops = {
.write = ether1394_write,
};
/* Ieee1394 highlevel driver functions */
static struct hpsb_highlevel eth1394_highlevel = {
.name = driver_name,
.add_host = ether1394_add_host,
.remove_host = ether1394_remove_host,
.host_reset = ether1394_host_reset,
};
static void eth1394_iso_shutdown(struct eth1394_priv *priv) static void eth1394_iso_shutdown(struct eth1394_priv *priv)
{ {
priv->bc_state = ETHER1394_BC_CLOSED; priv->bc_state = ETHER1394_BC_CLOSED;
...@@ -420,6 +440,10 @@ static void ether1394_add_host (struct hpsb_host *host) ...@@ -420,6 +440,10 @@ static void ether1394_add_host (struct hpsb_host *host)
struct eth1394_priv *priv; struct eth1394_priv *priv;
static int version_printed = 0; static int version_printed = 0;
hpsb_register_addrspace(&eth1394_highlevel, host, &addr_ops,
ETHER1394_REGION_ADDR,
ETHER1394_REGION_ADDR_END);
if (version_printed++ == 0) if (version_printed++ == 0)
ETH1394_PRINT_G (KERN_INFO, "%s\n", version); ETH1394_PRINT_G (KERN_INFO, "%s\n", version);
...@@ -1599,7 +1623,7 @@ static int ether1394_ethtool_ioctl(struct net_device *dev, void *useraddr) ...@@ -1599,7 +1623,7 @@ static int ether1394_ethtool_ioctl(struct net_device *dev, void *useraddr)
case ETHTOOL_GDRVINFO: { case ETHTOOL_GDRVINFO: {
struct ethtool_drvinfo info = { ETHTOOL_GDRVINFO }; struct ethtool_drvinfo info = { ETHTOOL_GDRVINFO };
strcpy (info.driver, driver_name); strcpy (info.driver, driver_name);
strcpy (info.version, "$Rev: 1079 $"); strcpy (info.version, "$Rev: 1096 $");
/* FIXME XXX provide sane businfo */ /* FIXME XXX provide sane businfo */
strcpy (info.bus_info, "ieee1394"); strcpy (info.bus_info, "ieee1394");
if (copy_to_user (useraddr, &info, sizeof (info))) if (copy_to_user (useraddr, &info, sizeof (info)))
...@@ -1619,18 +1643,6 @@ static int ether1394_ethtool_ioctl(struct net_device *dev, void *useraddr) ...@@ -1619,18 +1643,6 @@ static int ether1394_ethtool_ioctl(struct net_device *dev, void *useraddr)
return 0; return 0;
} }
/* Function for incoming 1394 packets */
static struct hpsb_address_ops addr_ops = {
.write = ether1394_write,
};
/* Ieee1394 highlevel driver functions */
static struct hpsb_highlevel eth1394_highlevel = {
.name = driver_name,
.add_host = ether1394_add_host,
.remove_host = ether1394_remove_host,
.host_reset = ether1394_host_reset,
};
static int __init ether1394_init_module (void) static int __init ether1394_init_module (void)
{ {
...@@ -1640,9 +1652,6 @@ static int __init ether1394_init_module (void) ...@@ -1640,9 +1652,6 @@ static int __init ether1394_init_module (void)
/* Register ourselves as a highlevel driver */ /* Register ourselves as a highlevel driver */
hpsb_register_highlevel(&eth1394_highlevel); hpsb_register_highlevel(&eth1394_highlevel);
hpsb_register_addrspace(&eth1394_highlevel, &addr_ops, ETHER1394_REGION_ADDR,
ETHER1394_REGION_ADDR_END);
return 0; return 0;
} }
......
...@@ -39,7 +39,10 @@ struct hl_host_info { ...@@ -39,7 +39,10 @@ struct hl_host_info {
static LIST_HEAD(hl_drivers); static LIST_HEAD(hl_drivers);
static rwlock_t hl_drivers_lock = RW_LOCK_UNLOCKED; static DECLARE_RWSEM(hl_drivers_sem);
static LIST_HEAD(hl_irqs);
static rwlock_t hl_irqs_lock = RW_LOCK_UNLOCKED;
static LIST_HEAD(addr_space); static LIST_HEAD(addr_space);
static rwlock_t addr_space_lock = RW_LOCK_UNLOCKED; static rwlock_t addr_space_lock = RW_LOCK_UNLOCKED;
...@@ -239,20 +242,22 @@ static int highlevel_for_each_host_reg(struct hpsb_host *host, void *__data) ...@@ -239,20 +242,22 @@ static int highlevel_for_each_host_reg(struct hpsb_host *host, void *__data)
void hpsb_register_highlevel(struct hpsb_highlevel *hl) void hpsb_register_highlevel(struct hpsb_highlevel *hl)
{ {
unsigned long flags;
INIT_LIST_HEAD(&hl->addr_list); INIT_LIST_HEAD(&hl->addr_list);
INIT_LIST_HEAD(&hl->host_info_list); INIT_LIST_HEAD(&hl->host_info_list);
rwlock_init(&hl->host_info_lock); rwlock_init(&hl->host_info_lock);
write_lock_irqsave(&hl_drivers_lock, flags); down_write(&hl_drivers_sem);
list_add_tail(&hl->hl_list, &hl_drivers); list_add_tail(&hl->hl_list, &hl_drivers);
write_unlock_irqrestore(&hl_drivers_lock, flags); up_write(&hl_drivers_sem);
if (hl->add_host) if (hl->add_host)
nodemgr_for_each_host(hl, highlevel_for_each_host_reg); nodemgr_for_each_host(hl, highlevel_for_each_host_reg);
write_lock(&hl_irqs_lock);
list_add_tail(&hl->irq_list, &hl_irqs);
write_unlock(&hl_irqs_lock);
return; return;
} }
...@@ -280,15 +285,19 @@ void hpsb_unregister_highlevel(struct hpsb_highlevel *hl) ...@@ -280,15 +285,19 @@ void hpsb_unregister_highlevel(struct hpsb_highlevel *hl)
} }
write_unlock_irqrestore(&addr_space_lock, flags); write_unlock_irqrestore(&addr_space_lock, flags);
write_lock_irqsave(&hl_drivers_lock, flags); write_lock(&hl_irqs_lock);
list_del(&hl->irq_list);
write_unlock(&hl_irqs_lock);
down_write(&hl_drivers_sem);
list_del(&hl->hl_list); list_del(&hl->hl_list);
write_unlock_irqrestore(&hl_drivers_lock, flags); up_write(&hl_drivers_sem);
if (hl->remove_host) if (hl->remove_host)
nodemgr_for_each_host(hl, highlevel_for_each_host_unreg); nodemgr_for_each_host(hl, highlevel_for_each_host_unreg);
} }
int hpsb_register_addrspace(struct hpsb_highlevel *hl, int hpsb_register_addrspace(struct hpsb_highlevel *hl, struct hpsb_host *host,
struct hpsb_address_ops *ops, u64 start, u64 end) struct hpsb_address_ops *ops, u64 start, u64 end)
{ {
struct hpsb_address_serve *as; struct hpsb_address_serve *as;
...@@ -314,7 +323,7 @@ int hpsb_register_addrspace(struct hpsb_highlevel *hl, ...@@ -314,7 +323,7 @@ int hpsb_register_addrspace(struct hpsb_highlevel *hl,
as->end = end; as->end = end;
write_lock_irqsave(&addr_space_lock, flags); write_lock_irqsave(&addr_space_lock, flags);
entry = addr_space.next; entry = host->addr_space.next;
while (list_entry(entry, struct hpsb_address_serve, as_list)->end while (list_entry(entry, struct hpsb_address_serve, as_list)->end
<= start) { <= start) {
...@@ -336,7 +345,8 @@ int hpsb_register_addrspace(struct hpsb_highlevel *hl, ...@@ -336,7 +345,8 @@ int hpsb_register_addrspace(struct hpsb_highlevel *hl,
return retval; return retval;
} }
int hpsb_unregister_addrspace(struct hpsb_highlevel *hl, u64 start) int hpsb_unregister_addrspace(struct hpsb_highlevel *hl, struct hpsb_host *host,
u64 start)
{ {
int retval = 0; int retval = 0;
struct hpsb_address_serve *as; struct hpsb_address_serve *as;
...@@ -350,7 +360,7 @@ int hpsb_unregister_addrspace(struct hpsb_highlevel *hl, u64 start) ...@@ -350,7 +360,7 @@ int hpsb_unregister_addrspace(struct hpsb_highlevel *hl, u64 start)
while (entry != &hl->addr_list) { while (entry != &hl->addr_list) {
as = list_entry(entry, struct hpsb_address_serve, addr_list); as = list_entry(entry, struct hpsb_address_serve, addr_list);
entry = entry->next; entry = entry->next;
if (as->start == start) { if (as->start == start && as->host == host) {
list_del(&as->as_list); list_del(&as->as_list);
list_del(&as->addr_list); list_del(&as->addr_list);
kfree(as); kfree(as);
...@@ -395,89 +405,82 @@ void hpsb_unlisten_channel(struct hpsb_highlevel *hl, struct hpsb_host *host, ...@@ -395,89 +405,82 @@ void hpsb_unlisten_channel(struct hpsb_highlevel *hl, struct hpsb_host *host,
void highlevel_add_host(struct hpsb_host *host) void highlevel_add_host(struct hpsb_host *host)
{ {
struct list_head *entry;
struct hpsb_highlevel *hl; struct hpsb_highlevel *hl;
read_lock(&hl_drivers_lock); down_read(&hl_drivers_sem);
list_for_each(entry, &hl_drivers) { list_for_each_entry(hl, &hl_drivers, hl_list) {
hl = list_entry(entry, struct hpsb_highlevel, hl_list);
if (hl->add_host) if (hl->add_host)
hl->add_host(host); hl->add_host(host);
} }
read_unlock(&hl_drivers_lock); up_read(&hl_drivers_sem);
} }
void highlevel_remove_host(struct hpsb_host *host) void highlevel_remove_host(struct hpsb_host *host)
{ {
struct list_head *entry;
struct hpsb_highlevel *hl; struct hpsb_highlevel *hl;
struct list_head *lh, *next;
struct hpsb_address_serve *as;
unsigned long flags;
read_lock(&hl_drivers_lock); down_read(&hl_drivers_sem);
list_for_each(entry, &hl_drivers) { list_for_each_entry(hl, &hl_drivers, hl_list) {
hl = list_entry(entry, struct hpsb_highlevel, hl_list);
if (hl->remove_host) { if (hl->remove_host) {
hl->remove_host(host); hl->remove_host(host);
hpsb_destroy_hostinfo(hl, host); hpsb_destroy_hostinfo(hl, host);
} }
} }
read_unlock(&hl_drivers_lock); up_read(&hl_drivers_sem);
/* Free up 1394 address space left behind by high level drivers. */
write_lock_irqsave(&addr_space_lock, flags);
list_for_each_safe (lh, next, &host->addr_space) {
as = list_entry(lh, struct hpsb_address_serve, as_list);
if (!list_empty(&as->addr_list)) {
list_del(&as->addr_list);
kfree(as);
}
}
write_unlock_irqrestore(&addr_space_lock, flags);
} }
void highlevel_host_reset(struct hpsb_host *host) void highlevel_host_reset(struct hpsb_host *host)
{ {
struct list_head *entry;
struct hpsb_highlevel *hl; struct hpsb_highlevel *hl;
read_lock(&hl_drivers_lock); read_lock(&hl_irqs_lock);
list_for_each(entry, &hl_drivers) { list_for_each_entry(hl, &hl_irqs, hl_list) {
hl = list_entry(entry, struct hpsb_highlevel, hl_list);
if (hl->host_reset) if (hl->host_reset)
hl->host_reset(host); hl->host_reset(host);
} }
read_unlock(&hl_drivers_lock); read_unlock(&hl_irqs_lock);
} }
void highlevel_iso_receive(struct hpsb_host *host, void *data, void highlevel_iso_receive(struct hpsb_host *host, void *data, size_t length)
size_t length)
{ {
struct list_head *entry;
struct hpsb_highlevel *hl; struct hpsb_highlevel *hl;
int channel = (((quadlet_t *)data)[0] >> 8) & 0x3f; int channel = (((quadlet_t *)data)[0] >> 8) & 0x3f;
read_lock(&hl_drivers_lock); read_lock(&hl_irqs_lock);
entry = hl_drivers.next; list_for_each_entry(hl, &hl_irqs, irq_list) {
if (hl->iso_receive)
while (entry != &hl_drivers) {
hl = list_entry(entry, struct hpsb_highlevel, hl_list);
if (hl->iso_receive) {
hl->iso_receive(host, channel, data, length); hl->iso_receive(host, channel, data, length);
} }
entry = entry->next; read_unlock(&hl_irqs_lock);
}
read_unlock(&hl_drivers_lock);
} }
void highlevel_fcp_request(struct hpsb_host *host, int nodeid, int direction, void highlevel_fcp_request(struct hpsb_host *host, int nodeid, int direction,
void *data, size_t length) void *data, size_t length)
{ {
struct list_head *entry;
struct hpsb_highlevel *hl; struct hpsb_highlevel *hl;
int cts = ((quadlet_t *)data)[0] >> 4; int cts = ((quadlet_t *)data)[0] >> 4;
read_lock(&hl_drivers_lock); read_lock(&hl_irqs_lock);
entry = hl_drivers.next; list_for_each_entry(hl, &hl_irqs, irq_list) {
if (hl->fcp_request)
while (entry != &hl_drivers) {
hl = list_entry(entry, struct hpsb_highlevel, hl_list);
if (hl->fcp_request) {
hl->fcp_request(host, nodeid, direction, cts, data, hl->fcp_request(host, nodeid, direction, cts, data,
length); length);
} }
entry = entry->next; read_unlock(&hl_irqs_lock);
}
read_unlock(&hl_drivers_lock);
} }
int highlevel_read(struct hpsb_host *host, int nodeid, void *data, int highlevel_read(struct hpsb_host *host, int nodeid, void *data,
...@@ -490,7 +493,7 @@ int highlevel_read(struct hpsb_host *host, int nodeid, void *data, ...@@ -490,7 +493,7 @@ int highlevel_read(struct hpsb_host *host, int nodeid, void *data,
read_lock(&addr_space_lock); read_lock(&addr_space_lock);
entry = addr_space.next; entry = host->addr_space.next;
as = list_entry(entry, struct hpsb_address_serve, as_list); as = list_entry(entry, struct hpsb_address_serve, as_list);
while (as->start <= addr) { while (as->start <= addr) {
...@@ -536,7 +539,7 @@ int highlevel_write(struct hpsb_host *host, int nodeid, int destid, ...@@ -536,7 +539,7 @@ int highlevel_write(struct hpsb_host *host, int nodeid, int destid,
read_lock(&addr_space_lock); read_lock(&addr_space_lock);
entry = addr_space.next; entry = host->addr_space.next;
as = list_entry(entry, struct hpsb_address_serve, as_list); as = list_entry(entry, struct hpsb_address_serve, as_list);
while (as->start <= addr) { while (as->start <= addr) {
...@@ -582,7 +585,7 @@ int highlevel_lock(struct hpsb_host *host, int nodeid, quadlet_t *store, ...@@ -582,7 +585,7 @@ int highlevel_lock(struct hpsb_host *host, int nodeid, quadlet_t *store,
read_lock(&addr_space_lock); read_lock(&addr_space_lock);
entry = addr_space.next; entry = host->addr_space.next;
as = list_entry(entry, struct hpsb_address_serve, as_list); as = list_entry(entry, struct hpsb_address_serve, as_list);
while (as->start <= addr) { while (as->start <= addr) {
...@@ -615,7 +618,7 @@ int highlevel_lock64(struct hpsb_host *host, int nodeid, octlet_t *store, ...@@ -615,7 +618,7 @@ int highlevel_lock64(struct hpsb_host *host, int nodeid, octlet_t *store,
read_lock(&addr_space_lock); read_lock(&addr_space_lock);
entry = addr_space.next; entry = host->addr_space.next;
as = list_entry(entry, struct hpsb_address_serve, as_list); as = list_entry(entry, struct hpsb_address_serve, as_list);
while (as->start <= addr) { while (as->start <= addr) {
...@@ -640,7 +643,7 @@ int highlevel_lock64(struct hpsb_host *host, int nodeid, octlet_t *store, ...@@ -640,7 +643,7 @@ int highlevel_lock64(struct hpsb_host *host, int nodeid, octlet_t *store,
return rcode; return rcode;
} }
void init_hpsb_highlevel(void) void init_hpsb_highlevel(struct hpsb_host *host)
{ {
INIT_LIST_HEAD(&dummy_zero_addr.as_list); INIT_LIST_HEAD(&dummy_zero_addr.as_list);
INIT_LIST_HEAD(&dummy_zero_addr.addr_list); INIT_LIST_HEAD(&dummy_zero_addr.addr_list);
...@@ -652,6 +655,6 @@ void init_hpsb_highlevel(void) ...@@ -652,6 +655,6 @@ void init_hpsb_highlevel(void)
dummy_zero_addr.start = dummy_zero_addr.end = 0; dummy_zero_addr.start = dummy_zero_addr.end = 0;
dummy_max_addr.start = dummy_max_addr.end = ((u64) 1) << 48; dummy_max_addr.start = dummy_max_addr.end = ((u64) 1) << 48;
list_add_tail(&dummy_zero_addr.as_list, &addr_space); list_add_tail(&dummy_zero_addr.as_list, &host->addr_space);
list_add_tail(&dummy_max_addr.as_list, &addr_space); list_add_tail(&dummy_max_addr.as_list, &host->addr_space);
} }
...@@ -10,6 +10,8 @@ struct hpsb_address_serve { ...@@ -10,6 +10,8 @@ struct hpsb_address_serve {
struct hpsb_address_ops *op; struct hpsb_address_ops *op;
struct hpsb_host *host;
/* first address handled and first address behind, quadlet aligned */ /* first address handled and first address behind, quadlet aligned */
u64 start, end; u64 start, end;
}; };
...@@ -36,9 +38,9 @@ struct hpsb_highlevel { ...@@ -36,9 +38,9 @@ struct hpsb_highlevel {
* hpsb_unregister_highlevel once for each host. */ * hpsb_unregister_highlevel once for each host. */
void (*remove_host) (struct hpsb_host *host); void (*remove_host) (struct hpsb_host *host);
/* Host experienced bus reset with possible configuration changes. Note /* Host experienced bus reset with possible configuration changes.
* that this one may occur during interrupt/bottom half handling. You * Note that this one may occur during interrupt/bottom half handling.
* can not expect to be able to do stock hpsb_reads. */ * You can not expect to be able to do stock hpsb_reads. */
void (*host_reset) (struct hpsb_host *host); void (*host_reset) (struct hpsb_host *host);
/* An isochronous packet was received. Channel contains the channel /* An isochronous packet was received. Channel contains the channel
...@@ -50,13 +52,14 @@ struct hpsb_highlevel { ...@@ -50,13 +52,14 @@ struct hpsb_highlevel {
/* A write request was received on either the FCP_COMMAND (direction = /* A write request was received on either the FCP_COMMAND (direction =
* 0) or the FCP_RESPONSE (direction = 1) register. The cts arg * 0) or the FCP_RESPONSE (direction = 1) register. The cts arg
* contains the cts field (first byte of data). * contains the cts field (first byte of data). */
*/
void (*fcp_request) (struct hpsb_host *host, int nodeid, int direction, void (*fcp_request) (struct hpsb_host *host, int nodeid, int direction,
int cts, u8 *data, size_t length); int cts, u8 *data, size_t length);
/* These are initialized by the subsystem when the
* hpsb_higlevel is registered. */
struct list_head hl_list; struct list_head hl_list;
struct list_head irq_list;
struct list_head addr_list; struct list_head addr_list;
struct list_head host_info_list; struct list_head host_info_list;
...@@ -137,10 +140,11 @@ void hpsb_unregister_highlevel(struct hpsb_highlevel *hl); ...@@ -137,10 +140,11 @@ void hpsb_unregister_highlevel(struct hpsb_highlevel *hl);
* It returns true for successful allocation. There is no unregister function, * It returns true for successful allocation. There is no unregister function,
* all address spaces are deallocated together with the hpsb_highlevel. * all address spaces are deallocated together with the hpsb_highlevel.
*/ */
int hpsb_register_addrspace(struct hpsb_highlevel *hl, int hpsb_register_addrspace(struct hpsb_highlevel *hl, struct hpsb_host *host,
struct hpsb_address_ops *ops, u64 start, u64 end); struct hpsb_address_ops *ops, u64 start, u64 end);
int hpsb_unregister_addrspace(struct hpsb_highlevel *hl, u64 start); int hpsb_unregister_addrspace(struct hpsb_highlevel *hl, struct hpsb_host *host,
u64 start);
/* /*
* Enable or disable receving a certain isochronous channel through the * Enable or disable receving a certain isochronous channel through the
...@@ -179,6 +183,6 @@ int hpsb_set_hostinfo(struct hpsb_highlevel *hl, struct hpsb_host *host, void *d ...@@ -179,6 +183,6 @@ int hpsb_set_hostinfo(struct hpsb_highlevel *hl, struct hpsb_host *host, void *d
struct hpsb_host *hpsb_get_host_bykey(struct hpsb_highlevel *hl, unsigned long key); struct hpsb_host *hpsb_get_host_bykey(struct hpsb_highlevel *hl, unsigned long key);
/* Initialize the highlevel system */ /* Initialize the highlevel system */
void init_hpsb_highlevel(void); void init_hpsb_highlevel(struct hpsb_host *host);
#endif /* IEEE1394_HIGHLEVEL_H */ #endif /* IEEE1394_HIGHLEVEL_H */
...@@ -89,6 +89,8 @@ struct hpsb_host *hpsb_alloc_host(struct hpsb_host_driver *drv, size_t extra, ...@@ -89,6 +89,8 @@ struct hpsb_host *hpsb_alloc_host(struct hpsb_host_driver *drv, size_t extra,
INIT_LIST_HEAD(&h->pending_packets); INIT_LIST_HEAD(&h->pending_packets);
spin_lock_init(&h->pending_pkt_lock); spin_lock_init(&h->pending_pkt_lock);
INIT_LIST_HEAD(&h->addr_space);
for (i = 0; i < ARRAY_SIZE(h->tpool); i++) for (i = 0; i < ARRAY_SIZE(h->tpool); i++)
HPSB_TPOOL_INIT(&h->tpool[i]); HPSB_TPOOL_INIT(&h->tpool[i]);
......
...@@ -69,6 +69,8 @@ struct hpsb_host { ...@@ -69,6 +69,8 @@ struct hpsb_host {
int id; int id;
struct device device; struct device device;
struct list_head addr_space;
}; };
......
...@@ -993,186 +993,11 @@ void abort_timedouts(unsigned long __opaque) ...@@ -993,186 +993,11 @@ void abort_timedouts(unsigned long __opaque)
} }
/*
* character device dispatching (see ieee1394_core.h)
* Dan Maas <dmaas@dcine.com>
*/
static struct {
struct file_operations *file_ops;
struct module *module;
} ieee1394_chardevs[16];
static rwlock_t ieee1394_chardevs_lock = RW_LOCK_UNLOCKED;
static int ieee1394_dispatch_open(struct inode *inode, struct file *file);
static struct file_operations ieee1394_chardev_ops = {
.owner =THIS_MODULE,
.open = ieee1394_dispatch_open,
};
/* claim a block of minor numbers */
int ieee1394_register_chardev(int blocknum,
struct module *module,
struct file_operations *file_ops)
{
int retval;
if ( (blocknum < 0) || (blocknum > 15) )
return -EINVAL;
write_lock(&ieee1394_chardevs_lock);
if (ieee1394_chardevs[blocknum].file_ops == NULL) {
/* grab the minor block */
ieee1394_chardevs[blocknum].file_ops = file_ops;
ieee1394_chardevs[blocknum].module = module;
retval = 0;
} else {
/* block already taken */
retval = -EBUSY;
}
write_unlock(&ieee1394_chardevs_lock);
return retval;
}
/* release a block of minor numbers */
void ieee1394_unregister_chardev(int blocknum)
{
if ( (blocknum < 0) || (blocknum > 15) )
return;
write_lock(&ieee1394_chardevs_lock);
if (ieee1394_chardevs[blocknum].file_ops) {
ieee1394_chardevs[blocknum].file_ops = NULL;
ieee1394_chardevs[blocknum].module = NULL;
}
write_unlock(&ieee1394_chardevs_lock);
}
/*
ieee1394_get_chardev() - look up and acquire a character device
driver that has previously registered using ieee1394_register_chardev()
On success, returns 1 and sets module and file_ops to the driver.
The module will have an incremented reference count.
On failure, returns 0.
The module will NOT have an incremented reference count.
*/
static int ieee1394_get_chardev(int blocknum,
struct module **module,
struct file_operations **file_ops)
{
int ret = 0;
if ((blocknum < 0) || (blocknum > 15))
return ret;
read_lock(&ieee1394_chardevs_lock);
*module = ieee1394_chardevs[blocknum].module;
*file_ops = ieee1394_chardevs[blocknum].file_ops;
if (*file_ops == NULL)
goto out;
if (!try_module_get(*module))
goto out;
/* success! */
ret = 1;
out:
read_unlock(&ieee1394_chardevs_lock);
return ret;
}
/* the point of entry for open() on any ieee1394 character device */
static int ieee1394_dispatch_open(struct inode *inode, struct file *file)
{
struct file_operations *file_ops;
struct module *module;
int blocknum;
int retval;
/*
Maintaining correct module reference counts is tricky here!
The key thing to remember is that the VFS increments the
reference count of ieee1394 before it calls
ieee1394_dispatch_open().
If the open() succeeds, then we need to transfer this extra
reference to the task-specific driver module (e.g. raw1394).
The VFS will deref the driver module automatically when the
file is later released.
If the open() fails, then the VFS will drop the
reference count of whatever module file->f_op->owner points
to, immediately after this function returns.
*/
/* shift away lower four bits of the minor
to get the index of the ieee1394_driver
we want */
blocknum = (iminor(inode) >> 4) & 0xF;
/* look up the driver */
if (ieee1394_get_chardev(blocknum, &module, &file_ops) == 0)
return -ENODEV;
/* redirect all subsequent requests to the driver's
own file_operations */
file->f_op = file_ops;
/* at this point BOTH ieee1394 and the task-specific driver have
an extra reference */
/* follow through with the open() */
retval = file_ops->open(inode, file);
if (retval == 0) {
/* If the open() succeeded, then ieee1394 will be left
* with an extra module reference, so we discard it here.
*
* The task-specific driver still has the extra reference
* given to it by ieee1394_get_chardev(). This extra
* reference prevents the module from unloading while the
* file is open, and will be dropped by the VFS when the
* file is released. */
module_put(THIS_MODULE);
} else {
/* point the file's f_ops back to ieee1394. The VFS will then
decrement ieee1394's reference count immediately after this
function returns. */
file->f_op = &ieee1394_chardev_ops;
/* If the open() failed, then we need to drop the extra
* reference we gave to the task-specific driver. */
module_put(module);
}
return retval;
}
static int __init ieee1394_init(void) static int __init ieee1394_init(void)
{ {
devfs_mk_dir("ieee1394"); devfs_mk_dir("ieee1394");
if (register_chrdev(IEEE1394_MAJOR, "ieee1394", &ieee1394_chardev_ops)) {
if (register_chrdev_region(IEEE1394_CORE_DEV, 256, "ieee1394")) {
HPSB_ERR("unable to register character device major %d!\n", IEEE1394_MAJOR); HPSB_ERR("unable to register character device major %d!\n", IEEE1394_MAJOR);
return -ENODEV; return -ENODEV;
} }
...@@ -1184,7 +1009,6 @@ static int __init ieee1394_init(void) ...@@ -1184,7 +1009,6 @@ static int __init ieee1394_init(void)
bus_register(&ieee1394_bus_type); bus_register(&ieee1394_bus_type);
init_hpsb_highlevel();
init_csr(); init_csr();
if (!disable_nodemgr) if (!disable_nodemgr)
...@@ -1206,7 +1030,7 @@ static void __exit ieee1394_cleanup(void) ...@@ -1206,7 +1030,7 @@ static void __exit ieee1394_cleanup(void)
kmem_cache_destroy(hpsb_packet_cache); kmem_cache_destroy(hpsb_packet_cache);
unregister_chrdev(IEEE1394_MAJOR, "ieee1394"); unregister_chrdev_region(IEEE1394_CORE_DEV, 256);
devfs_remove("ieee1394"); devfs_remove("ieee1394");
} }
...@@ -1234,8 +1058,6 @@ EXPORT_SYMBOL(hpsb_selfid_received); ...@@ -1234,8 +1058,6 @@ EXPORT_SYMBOL(hpsb_selfid_received);
EXPORT_SYMBOL(hpsb_selfid_complete); EXPORT_SYMBOL(hpsb_selfid_complete);
EXPORT_SYMBOL(hpsb_packet_sent); EXPORT_SYMBOL(hpsb_packet_sent);
EXPORT_SYMBOL(hpsb_packet_received); EXPORT_SYMBOL(hpsb_packet_received);
EXPORT_SYMBOL(ieee1394_register_chardev);
EXPORT_SYMBOL(ieee1394_unregister_chardev);
/** ieee1394_transactions.c **/ /** ieee1394_transactions.c **/
EXPORT_SYMBOL(hpsb_get_tlabel); EXPORT_SYMBOL(hpsb_get_tlabel);
......
...@@ -176,9 +176,9 @@ void hpsb_packet_received(struct hpsb_host *host, quadlet_t *data, size_t size, ...@@ -176,9 +176,9 @@ void hpsb_packet_received(struct hpsb_host *host, quadlet_t *data, size_t size,
* task-specific interfaces (raw1394, video1394, dv1394, etc) in * task-specific interfaces (raw1394, video1394, dv1394, etc) in
* blocks of 16. * blocks of 16.
* *
* The core ieee1394.o modules handles the initial open() for all * The core ieee1394.o module allocates the device number region
* character devices on major 171; it then dispatches to the * 171:0-255, the various drivers must then cdev_add() their cdev
* appropriate task-specific driver. * objects to handle their respective sub-regions.
* *
* Minor device number block allocations: * Minor device number block allocations:
* *
...@@ -199,29 +199,19 @@ void hpsb_packet_received(struct hpsb_host *host, quadlet_t *data, size_t size, ...@@ -199,29 +199,19 @@ void hpsb_packet_received(struct hpsb_host *host, quadlet_t *data, size_t size,
#define IEEE1394_MINOR_BLOCK_AMDTP 3 #define IEEE1394_MINOR_BLOCK_AMDTP 3
#define IEEE1394_MINOR_BLOCK_EXPERIMENTAL 15 #define IEEE1394_MINOR_BLOCK_EXPERIMENTAL 15
#define IEEE1394_CORE_DEV MKDEV(IEEE1394_MAJOR, 0)
#define IEEE1394_RAW1394_DEV MKDEV(IEEE1394_MAJOR, IEEE1394_MINOR_BLOCK_RAW1394 * 16)
#define IEEE1394_VIDEO1394_DEV MKDEV(IEEE1394_MAJOR, IEEE1394_MINOR_BLOCK_VIDEO1394 * 16)
#define IEEE1394_DV1394_DEV MKDEV(IEEE1394_MAJOR, IEEE1394_MINOR_BLOCK_DV1394 * 16)
#define IEEE1394_AMDTP_DEV MKDEV(IEEE1394_MAJOR, IEEE1394_MINOR_BLOCK_AMDTP * 16)
#define IEEE1394_EXPERIMENTAL_DEV MKDEV(IEEE1394_MAJOR, IEEE1394_MINOR_BLOCK_EXPERIMENTAL * 16)
/* return the index (within a minor number block) of a file */ /* return the index (within a minor number block) of a file */
static inline unsigned char ieee1394_file_to_instance(struct file *file) static inline unsigned char ieee1394_file_to_instance(struct file *file)
{ {
unsigned char minor = iminor(file->f_dentry->d_inode); return file->f_dentry->d_inode->i_cindex;
/* return lower 4 bits */
return minor & 0xF;
} }
/*
* Task-specific drivers should call ieee1394_register_chardev() to
* request a block of 16 minor numbers.
*
* Returns 0 if the request was successful, -EBUSY if the block was
* already taken.
*/
int ieee1394_register_chardev(int blocknum, /* 0-15 */
struct module *module, /* THIS_MODULE */
struct file_operations *file_ops);
/* release a block of minor numbers */
void ieee1394_unregister_chardev(int blocknum);
/* Our sysfs bus entry */ /* Our sysfs bus entry */
extern struct bus_type ieee1394_bus_type; extern struct bus_type ieee1394_bus_type;
......
...@@ -161,7 +161,7 @@ printk(level "%s: " fmt "\n" , OHCI1394_DRIVER_NAME , ## args) ...@@ -161,7 +161,7 @@ printk(level "%s: " fmt "\n" , OHCI1394_DRIVER_NAME , ## args)
printk(level "%s: fw-host%d: " fmt "\n" , OHCI1394_DRIVER_NAME, card , ## args) printk(level "%s: fw-host%d: " fmt "\n" , OHCI1394_DRIVER_NAME, card , ## args)
static char version[] __devinitdata = static char version[] __devinitdata =
"$Rev: 1087 $ Ben Collins <bcollins@debian.org>"; "$Rev: 1097 $ Ben Collins <bcollins@debian.org>";
/* Module Parameters */ /* Module Parameters */
static int phys_dma = 1; static int phys_dma = 1;
...@@ -174,6 +174,7 @@ static void dma_trm_reset(struct dma_trm_ctx *d); ...@@ -174,6 +174,7 @@ static void dma_trm_reset(struct dma_trm_ctx *d);
static int alloc_dma_rcv_ctx(struct ti_ohci *ohci, struct dma_rcv_ctx *d, static int alloc_dma_rcv_ctx(struct ti_ohci *ohci, struct dma_rcv_ctx *d,
enum context_type type, int ctx, int num_desc, enum context_type type, int ctx, int num_desc,
int buf_size, int split_buf_size, int context_base); int buf_size, int split_buf_size, int context_base);
static void stop_dma_rcv_ctx(struct dma_rcv_ctx *d);
static void free_dma_rcv_ctx(struct dma_rcv_ctx *d); static void free_dma_rcv_ctx(struct dma_rcv_ctx *d);
static int alloc_dma_trm_ctx(struct ti_ohci *ohci, struct dma_trm_ctx *d, static int alloc_dma_trm_ctx(struct ti_ohci *ohci, struct dma_trm_ctx *d,
...@@ -358,7 +359,7 @@ static void ohci_soft_reset(struct ti_ohci *ohci) { ...@@ -358,7 +359,7 @@ static void ohci_soft_reset(struct ti_ohci *ohci) {
reg_write(ohci, OHCI1394_HCControlSet, OHCI1394_HCControl_softReset); reg_write(ohci, OHCI1394_HCControlSet, OHCI1394_HCControl_softReset);
for (i = 0; i < OHCI_LOOP_COUNT; i++) { for (i = 0; i < OHCI_LOOP_COUNT; i++) {
if (!reg_read(ohci, OHCI1394_HCControlSet) & OHCI1394_HCControl_softReset) if (!(reg_read(ohci, OHCI1394_HCControlSet) & OHCI1394_HCControl_softReset))
break; break;
mdelay(1); mdelay(1);
} }
...@@ -1077,6 +1078,7 @@ static int ohci_devctl(struct hpsb_host *host, enum devctl_cmd cmd, int arg) ...@@ -1077,6 +1078,7 @@ static int ohci_devctl(struct hpsb_host *host, enum devctl_cmd cmd, int arg)
DBGMSG(ohci->id, "Listening disabled on channel %d", arg); DBGMSG(ohci->id, "Listening disabled on channel %d", arg);
if (ohci->ir_legacy_channels == 0) { if (ohci->ir_legacy_channels == 0) {
stop_dma_rcv_ctx(&ohci->ir_legacy_context);
free_dma_rcv_ctx(&ohci->ir_legacy_context); free_dma_rcv_ctx(&ohci->ir_legacy_context);
DBGMSG(ohci->id, "ISO receive legacy context deactivated"); DBGMSG(ohci->id, "ISO receive legacy context deactivated");
} }
...@@ -2249,6 +2251,14 @@ static irqreturn_t ohci_irq_handler(int irq, void *dev_id, ...@@ -2249,6 +2251,14 @@ static irqreturn_t ohci_irq_handler(int irq, void *dev_id,
if (!event) if (!event)
return IRQ_NONE; return IRQ_NONE;
/* If event is ~(u32)0 cardbus card was ejected. In this case
* we just return, and clean up in the ohci1394_pci_remove
* function. */
if (event == ~(u32) 0) {
DBGMSG(ohci->id, "Device removed.");
return IRQ_NONE;
}
DBGMSG(ohci->id, "IntEvent: %08x", event); DBGMSG(ohci->id, "IntEvent: %08x", event);
if (event & OHCI1394_unrecoverableError) { if (event & OHCI1394_unrecoverableError) {
...@@ -2811,15 +2821,8 @@ static void dma_trm_tasklet (unsigned long data) ...@@ -2811,15 +2821,8 @@ static void dma_trm_tasklet (unsigned long data)
spin_unlock_irqrestore(&d->lock, flags); spin_unlock_irqrestore(&d->lock, flags);
} }
static void free_dma_rcv_ctx(struct dma_rcv_ctx *d) static void stop_dma_rcv_ctx(struct dma_rcv_ctx *d)
{ {
int i;
if (d->ohci == NULL)
return;
DBGMSG(d->ohci->id, "Freeing dma_rcv_ctx %d", d->ctx);
if (d->ctrlClear) { if (d->ctrlClear) {
ohci1394_stop_context(d->ohci, d->ctrlClear, NULL); ohci1394_stop_context(d->ohci, d->ctrlClear, NULL);
...@@ -2831,6 +2834,17 @@ static void free_dma_rcv_ctx(struct dma_rcv_ctx *d) ...@@ -2831,6 +2834,17 @@ static void free_dma_rcv_ctx(struct dma_rcv_ctx *d)
tasklet_kill(&d->task); tasklet_kill(&d->task);
} }
} }
}
static void free_dma_rcv_ctx(struct dma_rcv_ctx *d)
{
int i;
if (d->ohci == NULL)
return;
DBGMSG(d->ohci->id, "Freeing dma_rcv_ctx %d", d->ctx);
if (d->buf_cpu) { if (d->buf_cpu) {
for (i=0; i<d->num_desc; i++) for (i=0; i<d->num_desc; i++)
...@@ -2982,19 +2996,6 @@ static void free_dma_trm_ctx(struct dma_trm_ctx *d) ...@@ -2982,19 +2996,6 @@ static void free_dma_trm_ctx(struct dma_trm_ctx *d)
DBGMSG(d->ohci->id, "Freeing dma_trm_ctx %d", d->ctx); DBGMSG(d->ohci->id, "Freeing dma_trm_ctx %d", d->ctx);
if (d->ctrlClear) {
ohci1394_stop_context(d->ohci, d->ctrlClear, NULL);
if (d->type == DMA_CTX_ISO) {
/* disable interrupts */
reg_write(d->ohci, OHCI1394_IsoXmitIntMaskClear, 1 << d->ctx);
ohci1394_unregister_iso_tasklet(d->ohci,
&d->ohci->it_legacy_tasklet);
} else {
tasklet_kill(&d->task);
}
}
if (d->prg_cpu) { if (d->prg_cpu) {
for (i=0; i<d->num_desc; i++) for (i=0; i<d->num_desc; i++)
if (d->prg_cpu[i] && d->prg_bus[i]) { if (d->prg_cpu[i] && d->prg_bus[i]) {
...@@ -3511,6 +3512,8 @@ static void ohci1394_pci_remove(struct pci_dev *pdev) ...@@ -3511,6 +3512,8 @@ static void ohci1394_pci_remove(struct pci_dev *pdev)
free_irq(ohci->dev->irq, ohci); free_irq(ohci->dev->irq, ohci);
case OHCI_INIT_HAVE_TXRX_BUFFERS__MAYBE: case OHCI_INIT_HAVE_TXRX_BUFFERS__MAYBE:
/* The ohci_soft_reset() stops all DMA contexts, so we
* dont need to do this. */
/* Free AR dma */ /* Free AR dma */
free_dma_rcv_ctx(&ohci->ar_req_context); free_dma_rcv_ctx(&ohci->ar_req_context);
free_dma_rcv_ctx(&ohci->ar_resp_context); free_dma_rcv_ctx(&ohci->ar_resp_context);
......
This diff is collapsed.
...@@ -38,6 +38,7 @@ ...@@ -38,6 +38,7 @@
#include <linux/smp_lock.h> #include <linux/smp_lock.h>
#include <linux/interrupt.h> #include <linux/interrupt.h>
#include <linux/vmalloc.h> #include <linux/vmalloc.h>
#include <linux/cdev.h>
#include <asm/uaccess.h> #include <asm/uaccess.h>
#include <asm/atomic.h> #include <asm/atomic.h>
#include <linux/devfs_fs_kernel.h> #include <linux/devfs_fs_kernel.h>
...@@ -1695,7 +1696,7 @@ static int arm_register(struct file_info *fi, struct pending_request *req) ...@@ -1695,7 +1696,7 @@ static int arm_register(struct file_info *fi, struct pending_request *req)
spin_unlock_irqrestore(&host_info_lock, flags); spin_unlock_irqrestore(&host_info_lock, flags);
return sizeof(struct raw1394_request); return sizeof(struct raw1394_request);
} }
retval = hpsb_register_addrspace(&raw1394_highlevel, &arm_ops, req->req.address, retval = hpsb_register_addrspace(&raw1394_highlevel, fi->host, &arm_ops, req->req.address,
req->req.address + req->req.length); req->req.address + req->req.length);
if (retval) { if (retval) {
/* INSERT ENTRY */ /* INSERT ENTRY */
...@@ -1782,7 +1783,7 @@ static int arm_unregister(struct file_info *fi, struct pending_request *req) ...@@ -1782,7 +1783,7 @@ static int arm_unregister(struct file_info *fi, struct pending_request *req)
spin_unlock_irqrestore(&host_info_lock, flags); spin_unlock_irqrestore(&host_info_lock, flags);
return sizeof(struct raw1394_request); return sizeof(struct raw1394_request);
} }
retval = hpsb_unregister_addrspace(&raw1394_highlevel, addr->start); retval = hpsb_unregister_addrspace(&raw1394_highlevel, fi->host, addr->start);
if (!retval) { if (!retval) {
printk(KERN_ERR "raw1394: arm_Unregister failed -> EINVAL\n"); printk(KERN_ERR "raw1394: arm_Unregister failed -> EINVAL\n");
spin_unlock_irqrestore(&host_info_lock, flags); spin_unlock_irqrestore(&host_info_lock, flags);
...@@ -2464,10 +2465,6 @@ static int raw1394_open(struct inode *inode, struct file *file) ...@@ -2464,10 +2465,6 @@ static int raw1394_open(struct inode *inode, struct file *file)
{ {
struct file_info *fi; struct file_info *fi;
if (ieee1394_file_to_instance(file) > 0) {
return -ENXIO;
}
fi = kmalloc(sizeof(struct file_info), SLAB_KERNEL); fi = kmalloc(sizeof(struct file_info), SLAB_KERNEL);
if (fi == NULL) if (fi == NULL)
return -ENOMEM; return -ENOMEM;
...@@ -2554,7 +2551,7 @@ static int raw1394_release(struct inode *inode, struct file *file) ...@@ -2554,7 +2551,7 @@ static int raw1394_release(struct inode *inode, struct file *file)
} }
if (!another_host) { if (!another_host) {
DBGMSG("raw1394_release: call hpsb_arm_unregister"); DBGMSG("raw1394_release: call hpsb_arm_unregister");
retval = hpsb_unregister_addrspace(&raw1394_highlevel, addr->start); retval = hpsb_unregister_addrspace(&raw1394_highlevel, fi->host, addr->start);
if (!retval) { if (!retval) {
++fail; ++fail;
printk(KERN_ERR "raw1394_release arm_Unregister failed\n"); printk(KERN_ERR "raw1394_release arm_Unregister failed\n");
...@@ -2646,7 +2643,8 @@ static struct hpsb_highlevel raw1394_highlevel = { ...@@ -2646,7 +2643,8 @@ static struct hpsb_highlevel raw1394_highlevel = {
.fcp_request = fcp_request, .fcp_request = fcp_request,
}; };
static struct file_operations file_ops = { static struct cdev raw1394_cdev;
static struct file_operations raw1394_fops = {
.owner = THIS_MODULE, .owner = THIS_MODULE,
.read = raw1394_read, .read = raw1394_read,
.write = raw1394_write, .write = raw1394_write,
...@@ -2664,8 +2662,10 @@ static int __init init_raw1394(void) ...@@ -2664,8 +2662,10 @@ static int __init init_raw1394(void)
devfs_mk_cdev(MKDEV(IEEE1394_MAJOR, IEEE1394_MINOR_BLOCK_RAW1394 * 16), devfs_mk_cdev(MKDEV(IEEE1394_MAJOR, IEEE1394_MINOR_BLOCK_RAW1394 * 16),
S_IFCHR | S_IRUSR | S_IWUSR, RAW1394_DEVICE_NAME); S_IFCHR | S_IRUSR | S_IWUSR, RAW1394_DEVICE_NAME);
if (ieee1394_register_chardev(IEEE1394_MINOR_BLOCK_RAW1394, cdev_init(&raw1394_cdev, &raw1394_fops);
THIS_MODULE, &file_ops)) { raw1394_cdev.owner = THIS_MODULE;
kobject_set_name(&raw1394_cdev.kobj, RAW1394_DEVICE_NAME);
if (cdev_add(&raw1394_cdev, IEEE1394_RAW1394_DEV, 1)) {
HPSB_ERR("raw1394 failed to register minor device block"); HPSB_ERR("raw1394 failed to register minor device block");
devfs_remove(RAW1394_DEVICE_NAME); devfs_remove(RAW1394_DEVICE_NAME);
hpsb_unregister_highlevel(&raw1394_highlevel); hpsb_unregister_highlevel(&raw1394_highlevel);
...@@ -2682,7 +2682,8 @@ static int __init init_raw1394(void) ...@@ -2682,7 +2682,8 @@ static int __init init_raw1394(void)
static void __exit cleanup_raw1394(void) static void __exit cleanup_raw1394(void)
{ {
hpsb_unregister_protocol(&raw1394_driver); hpsb_unregister_protocol(&raw1394_driver);
ieee1394_unregister_chardev(IEEE1394_MINOR_BLOCK_RAW1394); cdev_unmap(IEEE1394_RAW1394_DEV, 1);
cdev_del(&raw1394_cdev);
devfs_remove(RAW1394_DEVICE_NAME); devfs_remove(RAW1394_DEVICE_NAME);
hpsb_unregister_highlevel(&raw1394_highlevel); hpsb_unregister_highlevel(&raw1394_highlevel);
} }
...@@ -2690,3 +2691,4 @@ static void __exit cleanup_raw1394(void) ...@@ -2690,3 +2691,4 @@ static void __exit cleanup_raw1394(void)
module_init(init_raw1394); module_init(init_raw1394);
module_exit(cleanup_raw1394); module_exit(cleanup_raw1394);
MODULE_LICENSE("GPL"); MODULE_LICENSE("GPL");
MODULE_ALIAS_CHARDEV(IEEE1394_MAJOR, IEEE1394_MINOR_BLOCK_RAW1394 * 16);
...@@ -77,7 +77,7 @@ ...@@ -77,7 +77,7 @@
#include "sbp2.h" #include "sbp2.h"
static char version[] __devinitdata = static char version[] __devinitdata =
"$Rev: 1082 $ Ben Collins <bcollins@debian.org>"; "$Rev: 1096 $ Ben Collins <bcollins@debian.org>";
/* /*
* Module load parameter definitions * Module load parameter definitions
...@@ -712,6 +712,18 @@ static struct sbp2scsi_host_info *sbp2_add_host(struct hpsb_host *host) ...@@ -712,6 +712,18 @@ static struct sbp2scsi_host_info *sbp2_add_host(struct hpsb_host *host)
return NULL; return NULL;
} }
/* Register our sbp2 status address space... */
hpsb_register_addrspace(&sbp2_highlevel, host, &sbp2_ops,
SBP2_STATUS_FIFO_ADDRESS,
SBP2_STATUS_FIFO_ADDRESS +
SBP2_STATUS_FIFO_ENTRY_TO_OFFSET(SBP2SCSI_MAX_SCSI_IDS+1));
/* Handle data movement if physical dma is not enabled/supported
* on host controller */
#ifdef CONFIG_IEEE1394_SBP2_PHYS_DMA
hpsb_register_addrspace(&sbp2_highlevel, host, &sbp2_physdma_ops, 0x0ULL, 0xfffffffcULL);
#endif
hi = hpsb_create_hostinfo(&sbp2_highlevel, host, sizeof(*hi)); hi = hpsb_create_hostinfo(&sbp2_highlevel, host, sizeof(*hi));
if (!hi) { if (!hi) {
SBP2_ERR("failed to allocate hostinfo"); SBP2_ERR("failed to allocate hostinfo");
...@@ -2881,17 +2893,6 @@ static int sbp2_module_init(void) ...@@ -2881,17 +2893,6 @@ static int sbp2_module_init(void)
/* Register our high level driver with 1394 stack */ /* Register our high level driver with 1394 stack */
hpsb_register_highlevel(&sbp2_highlevel); hpsb_register_highlevel(&sbp2_highlevel);
/* Register our sbp2 status address space... */
hpsb_register_addrspace(&sbp2_highlevel, &sbp2_ops, SBP2_STATUS_FIFO_ADDRESS,
SBP2_STATUS_FIFO_ADDRESS +
SBP2_STATUS_FIFO_ENTRY_TO_OFFSET(SBP2SCSI_MAX_SCSI_IDS+1));
/* Handle data movement if physical dma is not enabled/supported
* on host controller */
#ifdef CONFIG_IEEE1394_SBP2_PHYS_DMA
hpsb_register_addrspace(&sbp2_highlevel, &sbp2_physdma_ops, 0x0ULL, 0xfffffffcULL);
#endif
hpsb_register_protocol(&sbp2_driver); hpsb_register_protocol(&sbp2_driver);
return 0; return 0;
......
...@@ -46,6 +46,7 @@ ...@@ -46,6 +46,7 @@
#include <linux/mm.h> #include <linux/mm.h>
#include <linux/ioctl32.h> #include <linux/ioctl32.h>
#include <linux/compat.h> #include <linux/compat.h>
#include <linux/cdev.h>
#include "ieee1394.h" #include "ieee1394.h"
#include "ieee1394_types.h" #include "ieee1394_types.h"
...@@ -1231,6 +1232,7 @@ static int video1394_release(struct inode *inode, struct file *file) ...@@ -1231,6 +1232,7 @@ static int video1394_release(struct inode *inode, struct file *file)
return 0; return 0;
} }
static struct cdev video1394_cdev;
static struct file_operations video1394_fops= static struct file_operations video1394_fops=
{ {
.owner = THIS_MODULE, .owner = THIS_MODULE,
...@@ -1445,18 +1447,18 @@ static void __exit video1394_exit_module (void) ...@@ -1445,18 +1447,18 @@ static void __exit video1394_exit_module (void)
hpsb_unregister_highlevel(&video1394_highlevel); hpsb_unregister_highlevel(&video1394_highlevel);
devfs_remove(VIDEO1394_DRIVER_NAME); devfs_remove(VIDEO1394_DRIVER_NAME);
ieee1394_unregister_chardev(IEEE1394_MINOR_BLOCK_VIDEO1394); cdev_unmap(IEEE1394_VIDEO1394_DEV, 16);
cdev_del(&video1394_cdev);
PRINT_G(KERN_INFO, "Removed " VIDEO1394_DRIVER_NAME " module"); PRINT_G(KERN_INFO, "Removed " VIDEO1394_DRIVER_NAME " module");
} }
static int __init video1394_init_module (void) static int __init video1394_init_module (void)
{ {
int ret; cdev_init(&video1394_cdev, &video1394_fops);
video1394_cdev.owner = THIS_MODULE;
ret = ieee1394_register_chardev(IEEE1394_MINOR_BLOCK_VIDEO1394, kobject_set_name(&video1394_cdev.kobj, VIDEO1394_DRIVER_NAME);
THIS_MODULE, &video1394_fops); if (cdev_add(&video1394_cdev, IEEE1394_VIDEO1394_DEV, 16)) {
if (ret) {
PRINT_G(KERN_ERR, "video1394: unable to get minor device block"); PRINT_G(KERN_ERR, "video1394: unable to get minor device block");
return -EIO; return -EIO;
} }
...@@ -1468,6 +1470,9 @@ static int __init video1394_init_module (void) ...@@ -1468,6 +1470,9 @@ static int __init video1394_init_module (void)
hpsb_register_protocol(&video1394_driver); hpsb_register_protocol(&video1394_driver);
#ifdef CONFIG_COMPAT #ifdef CONFIG_COMPAT
{
int ret;
/* First the compatible ones */ /* First the compatible ones */
ret = register_ioctl32_conversion(VIDEO1394_IOC_LISTEN_CHANNEL, NULL); ret = register_ioctl32_conversion(VIDEO1394_IOC_LISTEN_CHANNEL, NULL);
ret |= register_ioctl32_conversion(VIDEO1394_IOC_UNLISTEN_CHANNEL, NULL); ret |= register_ioctl32_conversion(VIDEO1394_IOC_UNLISTEN_CHANNEL, NULL);
...@@ -1487,6 +1492,7 @@ static int __init video1394_init_module (void) ...@@ -1487,6 +1492,7 @@ static int __init video1394_init_module (void)
video1394_wr_wait32); video1394_wr_wait32);
if (ret) if (ret)
PRINT_G(KERN_INFO, "Error registering ioctl32 translations"); PRINT_G(KERN_INFO, "Error registering ioctl32 translations");
}
#endif #endif
PRINT_G(KERN_INFO, "Installed " VIDEO1394_DRIVER_NAME " module"); PRINT_G(KERN_INFO, "Installed " VIDEO1394_DRIVER_NAME " module");
...@@ -1496,3 +1502,4 @@ static int __init video1394_init_module (void) ...@@ -1496,3 +1502,4 @@ static int __init video1394_init_module (void)
module_init(video1394_init_module); module_init(video1394_init_module);
module_exit(video1394_exit_module); module_exit(video1394_exit_module);
MODULE_ALIAS_CHARDEV(IEEE1394_MAJOR, IEEE1394_MINOR_BLOCK_VIDEO1394 * 16);
...@@ -1283,6 +1283,19 @@ config B44 ...@@ -1283,6 +1283,19 @@ config B44
<file:Documentation/networking/net-modules.txt>. The module will be <file:Documentation/networking/net-modules.txt>. The module will be
called b44. called b44.
config FORCEDETH
tristate "Reverse Engineered nForce Ethernet support (EXPERIMENTAL)"
depends on NET_PCI && PCI && EXPERIMENTAL
help
If you have a network (Ethernet) controller of this type, say Y and
read the Ethernet-HOWTO, available from
<http://www.tldp.org/docs.html#howto>.
To compile this driver as a module, choose M here and read
<file:Documentation/networking/net-modules.txt>. The module will be
called forcedeth.
config CS89x0 config CS89x0
tristate "CS89x0 support" tristate "CS89x0 support"
depends on NET_PCI && ISA depends on NET_PCI && ISA
......
...@@ -95,6 +95,7 @@ obj-$(CONFIG_LNE390) += lne390.o 8390.o ...@@ -95,6 +95,7 @@ obj-$(CONFIG_LNE390) += lne390.o 8390.o
obj-$(CONFIG_NE3210) += ne3210.o 8390.o obj-$(CONFIG_NE3210) += ne3210.o 8390.o
obj-$(CONFIG_NET_SB1250_MAC) += sb1250-mac.o obj-$(CONFIG_NET_SB1250_MAC) += sb1250-mac.o
obj-$(CONFIG_B44) += b44.o obj-$(CONFIG_B44) += b44.o
obj-$(CONFIG_FORCEDETH) += forcedeth.o
obj-$(CONFIG_PPP) += ppp_generic.o slhc.o obj-$(CONFIG_PPP) += ppp_generic.o slhc.o
obj-$(CONFIG_PPP_ASYNC) += ppp_async.o obj-$(CONFIG_PPP_ASYNC) += ppp_async.o
......
This diff is collapsed.
...@@ -325,6 +325,21 @@ config HDLC_X25 ...@@ -325,6 +325,21 @@ config HDLC_X25
comment "X.25/LAPB support is disabled" comment "X.25/LAPB support is disabled"
depends on WAN && HDLC && (LAPB!=m || HDLC!=m) && LAPB!=y depends on WAN && HDLC && (LAPB!=m || HDLC!=m) && LAPB!=y
config PCI200SYN
tristate "Goramo PCI200SYN support"
depends on HDLC && PCI
help
This driver is for PCI200SYN cards made by Goramo sp. j.
If you have such a card, say Y here and see
<http://hq.pm.waw.pl/pub/hdlc/>
If you want to compile the driver as a module ( = code which can be
inserted in and removed from the running kernel whenever you want),
say M here and read <file:Documentation/modules.txt>. The module
will be called pci200syn.
If unsure, say N here.
config WANXL config WANXL
tristate "SBE Inc. wanXL support" tristate "SBE Inc. wanXL support"
depends on HDLC && PCI depends on HDLC && PCI
......
...@@ -67,6 +67,7 @@ endif ...@@ -67,6 +67,7 @@ endif
obj-$(CONFIG_N2) += n2.o obj-$(CONFIG_N2) += n2.o
obj-$(CONFIG_C101) += c101.o obj-$(CONFIG_C101) += c101.o
obj-$(CONFIG_WANXL) += wanxl.o obj-$(CONFIG_WANXL) += wanxl.o
obj-$(CONFIG_PCI200SYN) += pci200syn.o
ifeq ($(CONFIG_WANXL_BUILD_FIRMWARE),y) ifeq ($(CONFIG_WANXL_BUILD_FIRMWARE),y)
ifeq ($(ARCH),m68k) ifeq ($(ARCH),m68k)
......
...@@ -23,8 +23,8 @@ ...@@ -23,8 +23,8 @@
* *
*/ */
#ifndef _HD64572_H #ifndef __HD64572_H
#define _HD64572_H #define __HD64572_H
/* Illegal Access Register */ /* Illegal Access Register */
#define ILAR 0x00 #define ILAR 0x00
...@@ -59,6 +59,9 @@ ...@@ -59,6 +59,9 @@
#define IR0_M(val, chan) ((val)<<(8*(chan))) /* Int MSCI */ #define IR0_M(val, chan) ((val)<<(8*(chan))) /* Int MSCI */
/* MSCI Channel Registers */ /* MSCI Channel Registers */
#define MSCI0_OFFSET 0x00
#define MSCI1_OFFSET 0x80
#define MD0 0x138 /* Mode reg 0 */ #define MD0 0x138 /* Mode reg 0 */
#define MD1 0x139 /* Mode reg 1 */ #define MD1 0x139 /* Mode reg 1 */
#define MD2 0x13a /* Mode reg 2 */ #define MD2 0x13a /* Mode reg 2 */
...@@ -107,6 +110,11 @@ ...@@ -107,6 +110,11 @@
#define RCR 0x156 /* Rx DMA Critical Request Reg */ #define RCR 0x156 /* Rx DMA Critical Request Reg */
/* Timer Registers */ /* Timer Registers */
#define TIMER0RX_OFFSET 0x00
#define TIMER0TX_OFFSET 0x10
#define TIMER1RX_OFFSET 0x20
#define TIMER1TX_OFFSET 0x30
#define TCNTL 0x200 /* Timer Upcounter L */ #define TCNTL 0x200 /* Timer Upcounter L */
#define TCNTH 0x201 /* Timer Upcounter H */ #define TCNTH 0x201 /* Timer Upcounter H */
#define TCONRL 0x204 /* Timer Constant Register L */ #define TCONRL 0x204 /* Timer Constant Register L */
...@@ -132,6 +140,11 @@ ...@@ -132,6 +140,11 @@
#define DCR_TX(chan) (0x59 + 2*chan) /* DMA Command Reg (Tx) */ #define DCR_TX(chan) (0x59 + 2*chan) /* DMA Command Reg (Tx) */
/* DMA Channel Registers */ /* DMA Channel Registers */
#define DMAC0RX_OFFSET 0x00
#define DMAC0TX_OFFSET 0x20
#define DMAC1RX_OFFSET 0x40
#define DMAC1TX_OFFSET 0x60
#define DARL 0x80 /* Dest Addr Register L (single-block, RX only) */ #define DARL 0x80 /* Dest Addr Register L (single-block, RX only) */
#define DARH 0x81 /* Dest Addr Register H (single-block, RX only) */ #define DARH 0x81 /* Dest Addr Register H (single-block, RX only) */
#define DARB 0x82 /* Dest Addr Register B (single-block, RX only) */ #define DARB 0x82 /* Dest Addr Register B (single-block, RX only) */
...@@ -166,6 +179,16 @@ typedef struct { ...@@ -166,6 +179,16 @@ typedef struct {
unsigned char filler[5]; /* alignment filler (16 bytes) */ unsigned char filler[5]; /* alignment filler (16 bytes) */
} pcsca_bd_t; } pcsca_bd_t;
/* Block Descriptor Structure */
typedef struct {
u32 cp; /* pointer to next block descriptor */
u32 bp; /* buffer pointer */
u16 len; /* data length */
u8 stat; /* status */
u8 unused; /* pads to 4-byte boundary */
}pkt_desc;
/* /*
Descriptor Status definitions: Descriptor Status definitions:
...@@ -190,6 +213,23 @@ typedef struct { ...@@ -190,6 +213,23 @@ typedef struct {
#define DST_SHRT 0x40 /* Short Frame */ #define DST_SHRT 0x40 /* Short Frame */
#define DST_EOM 0x80 /* End of Message */ #define DST_EOM 0x80 /* End of Message */
/* Packet Descriptor Status bits */
#define ST_TX_EOM 0x80 /* End of frame */
#define ST_TX_UNDRRUN 0x08
#define ST_TX_OWNRSHP 0x02
#define ST_TX_EOT 0x01 /* End of transmition */
#define ST_RX_EOM 0x80 /* End of frame */
#define ST_RX_SHORT 0x40 /* Short frame */
#define ST_RX_ABORT 0x20 /* Abort */
#define ST_RX_RESBIT 0x10 /* Residual bit */
#define ST_RX_OVERRUN 0x08 /* Overrun */
#define ST_RX_CRC 0x04 /* CRC */
#define ST_RX_OWNRSHP 0x02
#define ST_ERROR_MASK 0x7C
/* Status Counter Registers */ /* Status Counter Registers */
#define CMCR 0x158 /* Counter Master Ctl Reg */ #define CMCR 0x158 /* Counter Master Ctl Reg */
#define TECNTL 0x160 /* Tx EOM Counter L */ #define TECNTL 0x160 /* Tx EOM Counter L */
...@@ -246,11 +286,25 @@ typedef struct { ...@@ -246,11 +286,25 @@ typedef struct {
#define MD0_BIT_SYNC 0x80 #define MD0_BIT_SYNC 0x80
#define MD0_TRANSP 0xc0 #define MD0_TRANSP 0xc0
#define MD0_HDLC 0x80 /* Bit-sync HDLC mode */
#define MD0_CRC_NONE 0x00
#define MD0_CRC_16_0 0x04
#define MD0_CRC_16 0x05
#define MD0_CRC_ITU32 0x06
#define MD0_CRC_ITU 0x07
#define MD1_NOADDR 0x00 #define MD1_NOADDR 0x00
#define MD1_SADDR1 0x40 #define MD1_SADDR1 0x40
#define MD1_SADDR2 0x80 #define MD1_SADDR2 0x80
#define MD1_DADDR 0xc0 #define MD1_DADDR 0xc0
#define MD2_NRZI_IEEE 0x40
#define MD2_MANCHESTER 0x80
#define MD2_FM_MARK 0xA0
#define MD2_FM_SPACE 0xC0
#define MD2_LOOPBACK 0x03 /* Local data Loopback */
#define MD2_F_DUPLEX 0x00 #define MD2_F_DUPLEX 0x00
#define MD2_AUTO_ECHO 0x01 #define MD2_AUTO_ECHO 0x01
#define MD2_LOOP_HI_Z 0x02 #define MD2_LOOP_HI_Z 0x02
...@@ -274,6 +328,10 @@ typedef struct { ...@@ -274,6 +328,10 @@ typedef struct {
#define CTL_URSKP 0x40 #define CTL_URSKP 0x40
#define CTL_URCT 0x80 #define CTL_URCT 0x80
#define CTL_NORTS 0x01
#define CTL_NODTR 0x02
#define CTL_IDLE 0x10
#define RXS_BR0 0x01 #define RXS_BR0 0x01
#define RXS_BR1 0x02 #define RXS_BR1 0x02
#define RXS_BR2 0x04 #define RXS_BR2 0x04
...@@ -302,6 +360,12 @@ typedef struct { ...@@ -302,6 +360,12 @@ typedef struct {
#define EXS_TES1 0x20 #define EXS_TES1 0x20
#define EXS_TES2 0x40 #define EXS_TES2 0x40
#define CLK_BRG_MASK 0x0F
#define CLK_PIN_OUT 0x80
#define CLK_LINE 0x00 /* clock line input */
#define CLK_BRG 0x40 /* internal baud rate generator */
#define CLK_TX_RXCLK 0x60 /* TX clock from RX clock */
#define CMD_RX_RST 0x11 #define CMD_RX_RST 0x11
#define CMD_RX_ENA 0x12 #define CMD_RX_ENA 0x12
#define CMD_RX_DIS 0x13 #define CMD_RX_DIS 0x13
...@@ -324,6 +388,10 @@ typedef struct { ...@@ -324,6 +388,10 @@ typedef struct {
#define CMD_SRCH_MODE 0x31 #define CMD_SRCH_MODE 0x31
#define CMD_NOP 0x00 #define CMD_NOP 0x00
#define CMD_RESET 0x21
#define CMD_TX_ENABLE 0x02
#define CMD_RX_ENABLE 0x12
#define ST0_RXRDY 0x01 #define ST0_RXRDY 0x01
#define ST0_TXRDY 0x02 #define ST0_TXRDY 0x02
#define ST0_RXINTB 0x20 #define ST0_RXINTB 0x20
...@@ -374,6 +442,8 @@ typedef struct { ...@@ -374,6 +442,8 @@ typedef struct {
#define IE0_RXINTB 0x20 #define IE0_RXINTB 0x20
#define IE0_RXINTA 0x40 #define IE0_RXINTA 0x40
#define IE0_TXINT 0x80 #define IE0_TXINT 0x80
#define IE0_UDRN 0x00008000 /* TX underrun MSCI interrupt enable */
#define IE0_CDCD 0x00000400 /* CD level change interrupt enable */
#define IE1_IDLD 0x01 #define IE1_IDLD 0x01
#define IE1_ABTD 0x02 #define IE1_ABTD 0x02
...@@ -424,14 +494,28 @@ typedef struct { ...@@ -424,14 +494,28 @@ typedef struct {
#define DIR_EOM 0x40 #define DIR_EOM 0x40
#define DIR_EOT 0x80 #define DIR_EOT 0x80
#define DIR_REFE 0x04
#define DIR_UDRFE 0x04
#define DIR_COAE 0x08
#define DIR_COFE 0x10
#define DIR_BOFE 0x20
#define DIR_EOME 0x40
#define DIR_EOTE 0x80
#define DMR_CNTE 0x02 #define DMR_CNTE 0x02
#define DMR_NF 0x04 #define DMR_NF 0x04
#define DMR_SEOME 0x08 #define DMR_SEOME 0x08
#define DMR_TMOD 0x10 #define DMR_TMOD 0x10
#define DMER_DME 0x80 /* DMA Master Enable */
#define DCR_SW_ABT 0x01 #define DCR_SW_ABT 0x01
#define DCR_FCT_CLR 0x02 #define DCR_FCT_CLR 0x02
#define DCR_ABORT 0x01
#define DCR_CLEAR_EOF 0x02
#define PCR_COTE 0x80
#define PCR_PR0 0x01 #define PCR_PR0 0x01
#define PCR_PR1 0x02 #define PCR_PR1 0x02
#define PCR_PR2 0x04 #define PCR_PR2 0x04
...@@ -440,4 +524,4 @@ typedef struct { ...@@ -440,4 +524,4 @@ typedef struct {
#define PCR_OSB 0x40 #define PCR_OSB 0x40
#define PCR_BURST 0x80 #define PCR_BURST 0x80
#endif /* (_HD64572_H) */ #endif /* (__HD64572_H) */
This diff is collapsed.
...@@ -282,7 +282,7 @@ config PCMCIA_ATMEL ...@@ -282,7 +282,7 @@ config PCMCIA_ATMEL
one of these, you will need to provide a firmware image one of these, you will need to provide a firmware image
to be loaded into the card by the driver. The Atmel to be loaded into the card by the driver. The Atmel
firmware package can be downloaded from firmware package can be downloaded from
http://www.thekelleys.org.uk/atmel/atmel_firmware.tar.gz http://www.thekelleys.org.uk/atmel
config PCMCIA_WL3501 config PCMCIA_WL3501
tristate "Planet WL3501 PCMCIA cards" tristate "Planet WL3501 PCMCIA cards"
......
...@@ -1027,7 +1027,6 @@ struct airo_info { ...@@ -1027,7 +1027,6 @@ struct airo_info {
#define FLAG_802_11 7 #define FLAG_802_11 7
#define FLAG_PENDING_XMIT 9 #define FLAG_PENDING_XMIT 9
#define FLAG_PENDING_XMIT11 10 #define FLAG_PENDING_XMIT11 10
#define FLAG_PCI 11
#define JOB_MASK 0x1ff0000 #define JOB_MASK 0x1ff0000
#define JOB_DIE 16 #define JOB_DIE 16
#define JOB_XMIT 17 #define JOB_XMIT 17
...@@ -4623,7 +4622,6 @@ static int __devinit airo_pci_probe(struct pci_dev *pdev, ...@@ -4623,7 +4622,6 @@ static int __devinit airo_pci_probe(struct pci_dev *pdev,
return -ENODEV; return -ENODEV;
pci_set_drvdata(pdev, dev); pci_set_drvdata(pdev, dev);
set_bit (FLAG_PCI, &((struct airo_info *)dev->priv)->flags);
return 0; return 0;
} }
...@@ -4653,7 +4651,7 @@ static int __init airo_init_module( void ) ...@@ -4653,7 +4651,7 @@ static int __init airo_init_module( void )
#ifdef CONFIG_PCI #ifdef CONFIG_PCI
printk( KERN_INFO "airo: Probing for PCI adapters\n" ); printk( KERN_INFO "airo: Probing for PCI adapters\n" );
pci_module_init(&airo_driver); pci_register_driver(&airo_driver);
printk( KERN_INFO "airo: Finished probing for PCI adapters\n" ); printk( KERN_INFO "airo: Finished probing for PCI adapters\n" );
#endif #endif
...@@ -4665,22 +4663,15 @@ static int __init airo_init_module( void ) ...@@ -4665,22 +4663,15 @@ static int __init airo_init_module( void )
static void __exit airo_cleanup_module( void ) static void __exit airo_cleanup_module( void )
{ {
int is_pci = 0;
while( airo_devices ) { while( airo_devices ) {
printk( KERN_INFO "airo: Unregistering %s\n", airo_devices->dev->name ); printk( KERN_INFO "airo: Unregistering %s\n", airo_devices->dev->name );
#ifdef CONFIG_PCI
if (test_bit(FLAG_PCI, &((struct airo_info *)airo_devices->dev->priv)->flags))
is_pci = 1;
#endif
stop_airo_card( airo_devices->dev, 1 ); stop_airo_card( airo_devices->dev, 1 );
} }
remove_proc_entry("aironet", proc_root_driver); remove_proc_entry("aironet", proc_root_driver);
if (is_pci) {
#ifdef CONFIG_PCI #ifdef CONFIG_PCI
pci_unregister_driver(&airo_driver); pci_unregister_driver(&airo_driver);
#endif #endif
}
} }
#ifdef WIRELESS_EXT #ifdef WIRELESS_EXT
......
This diff is collapsed.
...@@ -330,20 +330,20 @@ static struct { ...@@ -330,20 +330,20 @@ static struct {
char *firmware; char *firmware;
char *name; char *name;
} card_table[] = { } card_table[] = {
{ 0, 0, "WLAN/802.11b PC CARD", "atmel_at76c502d.bin", "Actiontec 802CAT1" }, { 0, 0, "WLAN/802.11b PC CARD", "atmel_at76c502d%s.bin", "Actiontec 802CAT1" },
{ 0, 0, "ATMEL/AT76C502AR", "atmel_at76c502.bin", "NoName-RFMD" }, { 0, 0, "ATMEL/AT76C502AR", "atmel_at76c502%s.bin", "NoName-RFMD" },
{ 0, 0, "ATMEL/AT76C502AR_D", "atmel_at76c502d.bin", "NoName-revD" }, { 0, 0, "ATMEL/AT76C502AR_D", "atmel_at76c502d%s.bin", "NoName-revD" },
{ 0, 0, "ATMEL/AT76C502AR_E", "atmel_at76c502e.bin", "NoName-revE" }, { 0, 0, "ATMEL/AT76C502AR_E", "atmel_at76c502e%s.bin", "NoName-revE" },
{ 0, 0, "ATMEL/AT76C504", "atmel_at76c504.bin", "NoName-504" }, { 0, 0, "ATMEL/AT76C504", "atmel_at76c504%s.bin", "NoName-504" },
{ MANFID_3COM, 0x0620, NULL, "atmel_at76c502_3com.bin", "3com 3CRWE62092B" }, { MANFID_3COM, 0x0620, NULL, "atmel_at76c502_3com%s.bin", "3com 3CRWE62092B" },
{ MANFID_3COM, 0x0696, NULL, "atmel_at76c502_3com.bin", "3com 3CRSHPW_96" }, { MANFID_3COM, 0x0696, NULL, "atmel_at76c502_3com%s.bin", "3com 3CRSHPW_96" },
{ 0, 0, "SMC/2632W-V2", "atmel_at76c502.bin", "SMC 2632W-V2" }, { 0, 0, "SMC/2632W-V2", "atmel_at76c502%s.bin", "SMC 2632W-V2" },
{ 0, 0, "SMC/2632W", "atmel_at76c502d.bin", "SMC 2632W-V3" }, { 0, 0, "SMC/2632W", "atmel_at76c502d%s.bin", "SMC 2632W-V3" },
{ 0xd601, 0x0007, NULL, "atmel_at76c502.bin", "Sitecom WLAN-011"}, /* suspect - from a usenet posting. */ { 0xd601, 0x0007, NULL, "atmel_at76c502%s.bin", "Sitecom WLAN-011"}, /* suspect - from a usenet posting. */
{ 0x01bf, 0x3302, NULL, "atmel_at76c502d.bin", "Belkin F5D6060u"}, /* " " " " " */ { 0x01bf, 0x3302, NULL, "atmel_at76c502d%s.bin", "Belkin F5D6060u"}, /* " " " " " */
{ 0, 0, "BT/Voyager 1020 Laptop Adapter", "atmel_at76c502.bin", "BT Voyager 1020"}, { 0, 0, "BT/Voyager 1020 Laptop Adapter", "atmel_at76c502%s.bin", "BT Voyager 1020"},
{ 0, 0, "IEEE 802.11b/Wireless LAN PC Card", "atmel_at76c502.bin", "Siemens Gigaset PC Card II" }, { 0, 0, "IEEE 802.11b/Wireless LAN PC Card", "atmel_at76c502%s.bin", "Siemens Gigaset PC Card II" },
{ 0, 0, "CNet/CNWLC 11Mbps Wireless PC Card V-5", "atmel_at76c502e.bin", "CNet CNWLC-811ARL" } { 0, 0, "CNet/CNWLC 11Mbps Wireless PC Card V-5", "atmel_at76c502e%s.bin", "CNet CNWLC-811ARL" }
}; };
/* This is strictly temporary, until PCMCIA devices get integrated into the device model. */ /* This is strictly temporary, until PCMCIA devices get integrated into the device model. */
......
...@@ -315,8 +315,12 @@ unsigned long do_mremap(unsigned long addr, ...@@ -315,8 +315,12 @@ unsigned long do_mremap(unsigned long addr,
old_len = PAGE_ALIGN(old_len); old_len = PAGE_ALIGN(old_len);
new_len = PAGE_ALIGN(new_len); new_len = PAGE_ALIGN(new_len);
/* Don't allow the degenerate cases */ /*
if (!old_len || !new_len) * We allow a zero old-len as a special case
* for DOS-emu "duplicate shm area" thing. But
* a zero new-len is nonsensical.
*/
if (!new_len)
goto out; goto out;
/* new_addr is only valid if MREMAP_FIXED is specified */ /* new_addr is only valid if MREMAP_FIXED is specified */
......
Markdown is supported
0%
or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment