Commit 627f8b57 authored by Jeff Garzik's avatar Jeff Garzik

Merge bk://kernel.bkbits.net/jgarzik/net-drivers-2.5

into redhat.com:/spare/repo/net-drivers-2.5
parents cca52de4 eba34e05
......@@ -40,7 +40,7 @@ config IEEE1394_OUI_DB
help
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
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,
or kernel (depending on whether you compile ieee1394 as a
module, or static in the kernel).
......
......@@ -82,6 +82,7 @@
#include <linux/poll.h>
#include <linux/ioctl32.h>
#include <linux/compat.h>
#include <linux/cdev.h>
#include <asm/uaccess.h>
#include <asm/atomic.h>
......@@ -1196,6 +1197,7 @@ static int amdtp_release(struct inode *inode, struct file *file)
return 0;
}
static struct cdev amdtp_cdev;
static struct file_operations amdtp_fops =
{
.owner = THIS_MODULE,
......@@ -1262,12 +1264,11 @@ MODULE_LICENSE("GPL");
static int __init amdtp_init_module (void)
{
int ret;
ret = ieee1394_register_chardev(IEEE1394_MINOR_BLOCK_AMDTP,
THIS_MODULE, &amdtp_fops);
if (ret) {
HPSB_ERR("amdtp: unable to get minor device block");
cdev_init(&amdtp_cdev, &amdtp_fops);
amdtp_cdev.owner = THIS_MODULE;
kobject_set_name(&amdtp_cdev.kobj, "amdtp");
if (cdev_add(&amdtp_cdev, IEEE1394_AMDTP_DEV, 16)) {
HPSB_ERR("amdtp: unable to add char device");
return -EIO;
}
......@@ -1276,12 +1277,15 @@ static int __init amdtp_init_module (void)
hpsb_register_highlevel(&amdtp_highlevel);
#ifdef CONFIG_COMPAT
ret = register_ioctl32_conversion(AMDTP_IOC_CHANNEL, NULL);
ret |= register_ioctl32_conversion(AMDTP_IOC_PLUG, NULL);
ret |= register_ioctl32_conversion(AMDTP_IOC_PING, NULL);
ret |= register_ioctl32_conversion(AMDTP_IOC_ZAP, NULL);
if (ret)
HPSB_ERR("amdtp: Error registering ioctl32 translations");
{
int ret;
ret = register_ioctl32_conversion(AMDTP_IOC_CHANNEL, NULL);
ret |= register_ioctl32_conversion(AMDTP_IOC_PLUG, NULL);
ret |= register_ioctl32_conversion(AMDTP_IOC_PING, NULL);
ret |= register_ioctl32_conversion(AMDTP_IOC_ZAP, NULL);
if (ret)
HPSB_ERR("amdtp: Error registering ioctl32 translations");
}
#endif
HPSB_INFO("Loaded AMDTP driver");
......@@ -1304,10 +1308,12 @@ static void __exit amdtp_exit_module (void)
hpsb_unregister_highlevel(&amdtp_highlevel);
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");
}
module_init(amdtp_init_module);
module_exit(amdtp_exit_module);
MODULE_ALIAS_CHARDEV(IEEE1394_MAJOR, IEEE1394_MINOR_BLOCK_AMDTP * 16);
......@@ -77,6 +77,25 @@ enum {
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 *
cmp_register_opcr(struct hpsb_host *host, int opcr_number, int payload,
void (*update)(struct cmp_pcr *pcr, void *data),
......@@ -137,6 +156,10 @@ static void cmp_add_host(struct hpsb_host *host)
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->u.ompr.rate = IEEE1394_SPEED_100;
ch->u.ompr.bcast_channel_base = 63;
......@@ -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_AUTHOR("Kristian Hogsberg <hogsberg@users.sf.net>");
......@@ -283,10 +295,6 @@ static int __init cmp_init_module (void)
{
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");
return 0;
......
......@@ -35,6 +35,43 @@ static int fcp = 1;
module_param(fcp, int, 0444);
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)
{
int check=0, i;
......@@ -125,6 +162,24 @@ static inline void calculate_expire(struct csr_control *csr)
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.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,
}
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)
{
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)
......
......@@ -110,6 +110,7 @@
#include <linux/string.h>
#include <linux/ioctl32.h>
#include <linux/compat.h>
#include <linux/cdev.h>
#include "ieee1394.h"
#include "ieee1394_types.h"
......@@ -2165,6 +2166,7 @@ static void ir_tasklet_func(unsigned long data)
spin_unlock(&video->spinlock);
}
static struct cdev dv1394_cdev;
static struct file_operations dv1394_fops=
{
.owner = THIS_MODULE,
......@@ -2607,17 +2609,17 @@ static void __exit dv1394_exit_module(void)
hpsb_unregister_protocol(&dv1394_driver);
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");
}
static int __init dv1394_init_module(void)
{
int ret;
ret = ieee1394_register_chardev(IEEE1394_MINOR_BLOCK_DV1394,
THIS_MODULE, &dv1394_fops);
if (ret) {
cdev_init(&dv1394_cdev, &dv1394_fops);
dv1394_cdev.owner = THIS_MODULE;
kobject_set_name(&dv1394_cdev.kobj, "dv1394");
if (cdev_add(&dv1394_cdev, IEEE1394_DV1394_DEV, 16)) {
printk(KERN_ERR "dv1394: unable to register character device\n");
return -EIO;
}
......@@ -2629,18 +2631,22 @@ static int __init dv1394_init_module(void)
hpsb_register_protocol(&dv1394_driver);
#ifdef CONFIG_COMPAT
/* First compatible ones */
ret = register_ioctl32_conversion(DV1394_IOC_SHUTDOWN, NULL);
ret |= register_ioctl32_conversion(DV1394_IOC_SUBMIT_FRAMES, NULL);
ret |= register_ioctl32_conversion(DV1394_IOC_WAIT_FRAMES, NULL);
ret |= register_ioctl32_conversion(DV1394_IOC_RECEIVE_FRAMES, NULL);
ret |= register_ioctl32_conversion(DV1394_IOC_START_RECEIVE, NULL);
/* These need to be handled by translation */
ret |= register_ioctl32_conversion(DV1394_IOC32_INIT, handle_dv1394_init);
ret |= register_ioctl32_conversion(DV1394_IOC32_GET_STATUS, handle_dv1394_get_status);
if (ret)
printk(KERN_ERR "dv1394: Error registering ioctl32 translations\n");
{
int ret;
/* First compatible ones */
ret = register_ioctl32_conversion(DV1394_IOC_SHUTDOWN, NULL);
ret |= register_ioctl32_conversion(DV1394_IOC_SUBMIT_FRAMES, NULL);
ret |= register_ioctl32_conversion(DV1394_IOC_WAIT_FRAMES, NULL);
ret |= register_ioctl32_conversion(DV1394_IOC_RECEIVE_FRAMES, NULL);
ret |= register_ioctl32_conversion(DV1394_IOC_START_RECEIVE, NULL);
/* These need to be handled by translation */
ret |= register_ioctl32_conversion(DV1394_IOC32_INIT, handle_dv1394_init);
ret |= register_ioctl32_conversion(DV1394_IOC32_GET_STATUS, handle_dv1394_get_status);
if (ret)
printk(KERN_ERR "dv1394: Error registering ioctl32 translations\n");
}
#endif
return 0;
......@@ -2648,3 +2654,4 @@ static int __init dv1394_init_module(void)
module_init(dv1394_init_module);
module_exit(dv1394_exit_module);
MODULE_ALIAS_CHARDEV(IEEE1394_MAJOR, IEEE1394_MINOR_BLOCK_DV1394 * 16);
......@@ -89,7 +89,7 @@
#define TRACE() printk(KERN_ERR "%s:%s[%d] ---- TRACE\n", driver_name, __FUNCTION__, __LINE__)
static char version[] __devinitdata =
"$Rev: 1079 $ Ben Collins <bcollins@debian.org>";
"$Rev: 1096 $ Ben Collins <bcollins@debian.org>";
struct fragment_info {
struct list_head list;
......@@ -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_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)
{
priv->bc_state = ETHER1394_BC_CLOSED;
......@@ -420,6 +440,10 @@ static void ether1394_add_host (struct hpsb_host *host)
struct eth1394_priv *priv;
static int version_printed = 0;
hpsb_register_addrspace(&eth1394_highlevel, host, &addr_ops,
ETHER1394_REGION_ADDR,
ETHER1394_REGION_ADDR_END);
if (version_printed++ == 0)
ETH1394_PRINT_G (KERN_INFO, "%s\n", version);
......@@ -1599,7 +1623,7 @@ static int ether1394_ethtool_ioctl(struct net_device *dev, void *useraddr)
case ETHTOOL_GDRVINFO: {
struct ethtool_drvinfo info = { ETHTOOL_GDRVINFO };
strcpy (info.driver, driver_name);
strcpy (info.version, "$Rev: 1079 $");
strcpy (info.version, "$Rev: 1096 $");
/* FIXME XXX provide sane businfo */
strcpy (info.bus_info, "ieee1394");
if (copy_to_user (useraddr, &info, sizeof (info)))
......@@ -1619,18 +1643,6 @@ static int ether1394_ethtool_ioctl(struct net_device *dev, void *useraddr)
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)
{
......@@ -1640,9 +1652,6 @@ static int __init ether1394_init_module (void)
/* Register ourselves as a highlevel driver */
hpsb_register_highlevel(&eth1394_highlevel);
hpsb_register_addrspace(&eth1394_highlevel, &addr_ops, ETHER1394_REGION_ADDR,
ETHER1394_REGION_ADDR_END);
return 0;
}
......
......@@ -39,7 +39,10 @@ struct hl_host_info {
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 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)
void hpsb_register_highlevel(struct hpsb_highlevel *hl)
{
unsigned long flags;
INIT_LIST_HEAD(&hl->addr_list);
INIT_LIST_HEAD(&hl->host_info_list);
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);
write_unlock_irqrestore(&hl_drivers_lock, flags);
up_write(&hl_drivers_sem);
if (hl->add_host)
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;
}
......@@ -280,15 +285,19 @@ void hpsb_unregister_highlevel(struct hpsb_highlevel *hl)
}
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);
write_unlock_irqrestore(&hl_drivers_lock, flags);
up_write(&hl_drivers_sem);
if (hl->remove_host)
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_serve *as;
......@@ -314,7 +323,7 @@ int hpsb_register_addrspace(struct hpsb_highlevel *hl,
as->end = end;
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
<= start) {
......@@ -336,7 +345,8 @@ int hpsb_register_addrspace(struct hpsb_highlevel *hl,
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;
struct hpsb_address_serve *as;
......@@ -350,7 +360,7 @@ int hpsb_unregister_addrspace(struct hpsb_highlevel *hl, u64 start)
while (entry != &hl->addr_list) {
as = list_entry(entry, struct hpsb_address_serve, addr_list);
entry = entry->next;
if (as->start == start) {
if (as->start == start && as->host == host) {
list_del(&as->as_list);
list_del(&as->addr_list);
kfree(as);
......@@ -395,89 +405,82 @@ void hpsb_unlisten_channel(struct hpsb_highlevel *hl, struct hpsb_host *host,
void highlevel_add_host(struct hpsb_host *host)
{
struct list_head *entry;
struct hpsb_highlevel *hl;
read_lock(&hl_drivers_lock);
list_for_each(entry, &hl_drivers) {
hl = list_entry(entry, struct hpsb_highlevel, hl_list);
down_read(&hl_drivers_sem);
list_for_each_entry(hl, &hl_drivers, hl_list) {
if (hl->add_host)
hl->add_host(host);
}
read_unlock(&hl_drivers_lock);
up_read(&hl_drivers_sem);
}
void highlevel_remove_host(struct hpsb_host *host)
{
struct list_head *entry;
struct hpsb_highlevel *hl;
struct list_head *lh, *next;
struct hpsb_address_serve *as;
unsigned long flags;
read_lock(&hl_drivers_lock);
list_for_each(entry, &hl_drivers) {
hl = list_entry(entry, struct hpsb_highlevel, hl_list);
down_read(&hl_drivers_sem);
list_for_each_entry(hl, &hl_drivers, hl_list) {
if (hl->remove_host) {
hl->remove_host(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)
{
struct list_head *entry;
struct hpsb_highlevel *hl;
read_lock(&hl_drivers_lock);
list_for_each(entry, &hl_drivers) {
hl = list_entry(entry, struct hpsb_highlevel, hl_list);
read_lock(&hl_irqs_lock);
list_for_each_entry(hl, &hl_irqs, hl_list) {
if (hl->host_reset)
hl->host_reset(host);
}
read_unlock(&hl_drivers_lock);
read_unlock(&hl_irqs_lock);
}
void highlevel_iso_receive(struct hpsb_host *host, void *data,
size_t length)
void highlevel_iso_receive(struct hpsb_host *host, void *data, size_t length)
{
struct list_head *entry;
struct hpsb_highlevel *hl;
int channel = (((quadlet_t *)data)[0] >> 8) & 0x3f;
read_lock(&hl_drivers_lock);
entry = hl_drivers.next;
while (entry != &hl_drivers) {
hl = list_entry(entry, struct hpsb_highlevel, hl_list);
if (hl->iso_receive) {
read_lock(&hl_irqs_lock);
list_for_each_entry(hl, &hl_irqs, irq_list) {
if (hl->iso_receive)
hl->iso_receive(host, channel, data, length);
}
entry = entry->next;
}
read_unlock(&hl_drivers_lock);
read_unlock(&hl_irqs_lock);
}
void highlevel_fcp_request(struct hpsb_host *host, int nodeid, int direction,
void *data, size_t length)
{
struct list_head *entry;
struct hpsb_highlevel *hl;
int cts = ((quadlet_t *)data)[0] >> 4;
read_lock(&hl_drivers_lock);
entry = hl_drivers.next;
while (entry != &hl_drivers) {
hl = list_entry(entry, struct hpsb_highlevel, hl_list);
if (hl->fcp_request) {
read_lock(&hl_irqs_lock);
list_for_each_entry(hl, &hl_irqs, irq_list) {
if (hl->fcp_request)
hl->fcp_request(host, nodeid, direction, cts, data,
length);
}
entry = entry->next;
length);
}
read_unlock(&hl_drivers_lock);
read_unlock(&hl_irqs_lock);
}
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);
entry = addr_space.next;
entry = host->addr_space.next;
as = list_entry(entry, struct hpsb_address_serve, as_list);
while (as->start <= addr) {
......@@ -536,7 +539,7 @@ int highlevel_write(struct hpsb_host *host, int nodeid, int destid,
read_lock(&addr_space_lock);
entry = addr_space.next;
entry = host->addr_space.next;
as = list_entry(entry, struct hpsb_address_serve, as_list);
while (as->start <= addr) {
......@@ -582,7 +585,7 @@ int highlevel_lock(struct hpsb_host *host, int nodeid, quadlet_t *store,
read_lock(&addr_space_lock);
entry = addr_space.next;
entry = host->addr_space.next;
as = list_entry(entry, struct hpsb_address_serve, as_list);
while (as->start <= addr) {
......@@ -615,7 +618,7 @@ int highlevel_lock64(struct hpsb_host *host, int nodeid, octlet_t *store,
read_lock(&addr_space_lock);
entry = addr_space.next;
entry = host->addr_space.next;
as = list_entry(entry, struct hpsb_address_serve, as_list);
while (as->start <= addr) {
......@@ -640,7 +643,7 @@ int highlevel_lock64(struct hpsb_host *host, int nodeid, octlet_t *store,
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.addr_list);
......@@ -652,6 +655,6 @@ void init_hpsb_highlevel(void)
dummy_zero_addr.start = dummy_zero_addr.end = 0;
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_max_addr.as_list, &addr_space);
list_add_tail(&dummy_zero_addr.as_list, &host->addr_space);
list_add_tail(&dummy_max_addr.as_list, &host->addr_space);
}
......@@ -10,6 +10,8 @@ struct hpsb_address_serve {
struct hpsb_address_ops *op;
struct hpsb_host *host;
/* first address handled and first address behind, quadlet aligned */
u64 start, end;
};
......@@ -36,9 +38,9 @@ struct hpsb_highlevel {
* hpsb_unregister_highlevel once for each host. */
void (*remove_host) (struct hpsb_host *host);
/* Host experienced bus reset with possible configuration changes. Note
* that this one may occur during interrupt/bottom half handling. You
* can not expect to be able to do stock hpsb_reads. */
/* Host experienced bus reset with possible configuration changes.
* Note that this one may occur during interrupt/bottom half handling.
* You can not expect to be able to do stock hpsb_reads. */
void (*host_reset) (struct hpsb_host *host);
/* An isochronous packet was received. Channel contains the channel
......@@ -50,13 +52,14 @@ struct hpsb_highlevel {
/* A write request was received on either the FCP_COMMAND (direction =
* 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,
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 irq_list;
struct list_head addr_list;
struct list_head host_info_list;
......@@ -137,10 +140,11 @@ void hpsb_unregister_highlevel(struct hpsb_highlevel *hl);
* It returns true for successful allocation. There is no unregister function,
* 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);
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
......@@ -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);
/* Initialize the highlevel system */
void init_hpsb_highlevel(void);
void init_hpsb_highlevel(struct hpsb_host *host);
#endif /* IEEE1394_HIGHLEVEL_H */
......@@ -89,6 +89,8 @@ struct hpsb_host *hpsb_alloc_host(struct hpsb_host_driver *drv, size_t extra,
INIT_LIST_HEAD(&h->pending_packets);
spin_lock_init(&h->pending_pkt_lock);
INIT_LIST_HEAD(&h->addr_space);
for (i = 0; i < ARRAY_SIZE(h->tpool); i++)
HPSB_TPOOL_INIT(&h->tpool[i]);
......
......@@ -69,6 +69,8 @@ struct hpsb_host {
int id;
struct device device;
struct list_head addr_space;
};
......
......@@ -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)
{
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);
return -ENODEV;
}
......@@ -1184,7 +1009,6 @@ static int __init ieee1394_init(void)
bus_register(&ieee1394_bus_type);
init_hpsb_highlevel();
init_csr();
if (!disable_nodemgr)
......@@ -1206,7 +1030,7 @@ static void __exit ieee1394_cleanup(void)
kmem_cache_destroy(hpsb_packet_cache);
unregister_chrdev(IEEE1394_MAJOR, "ieee1394");
unregister_chrdev_region(IEEE1394_CORE_DEV, 256);
devfs_remove("ieee1394");
}
......@@ -1234,8 +1058,6 @@ EXPORT_SYMBOL(hpsb_selfid_received);
EXPORT_SYMBOL(hpsb_selfid_complete);
EXPORT_SYMBOL(hpsb_packet_sent);
EXPORT_SYMBOL(hpsb_packet_received);
EXPORT_SYMBOL(ieee1394_register_chardev);
EXPORT_SYMBOL(ieee1394_unregister_chardev);
/** ieee1394_transactions.c **/
EXPORT_SYMBOL(hpsb_get_tlabel);
......
......@@ -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
* blocks of 16.
*
* The core ieee1394.o modules handles the initial open() for all
* character devices on major 171; it then dispatches to the
* appropriate task-specific driver.
* The core ieee1394.o module allocates the device number region
* 171:0-255, the various drivers must then cdev_add() their cdev
* objects to handle their respective sub-regions.
*
* Minor device number block allocations:
*
......@@ -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_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 */
static inline unsigned char ieee1394_file_to_instance(struct file *file)
{
unsigned char minor = iminor(file->f_dentry->d_inode);
/* return lower 4 bits */
return minor & 0xF;
return file->f_dentry->d_inode->i_cindex;
}
/*
* 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 */
extern struct bus_type ieee1394_bus_type;
......
......@@ -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)
static char version[] __devinitdata =
"$Rev: 1087 $ Ben Collins <bcollins@debian.org>";
"$Rev: 1097 $ Ben Collins <bcollins@debian.org>";
/* Module Parameters */
static int phys_dma = 1;
......@@ -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,
enum context_type type, int ctx, int num_desc,
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 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) {
reg_write(ohci, OHCI1394_HCControlSet, OHCI1394_HCControl_softReset);
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;
mdelay(1);
}
......@@ -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);
if (ohci->ir_legacy_channels == 0) {
stop_dma_rcv_ctx(&ohci->ir_legacy_context);
free_dma_rcv_ctx(&ohci->ir_legacy_context);
DBGMSG(ohci->id, "ISO receive legacy context deactivated");
}
......@@ -2249,6 +2251,14 @@ static irqreturn_t ohci_irq_handler(int irq, void *dev_id,
if (!event)
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);
if (event & OHCI1394_unrecoverableError) {
......@@ -2811,15 +2821,8 @@ static void dma_trm_tasklet (unsigned long data)
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) {
ohci1394_stop_context(d->ohci, d->ctrlClear, NULL);
......@@ -2831,6 +2834,17 @@ static void free_dma_rcv_ctx(struct dma_rcv_ctx *d)
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) {
for (i=0; i<d->num_desc; i++)
......@@ -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);
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) {
for (i=0; i<d->num_desc; i++)
if (d->prg_cpu[i] && d->prg_bus[i]) {
......@@ -3511,6 +3512,8 @@ static void ohci1394_pci_remove(struct pci_dev *pdev)
free_irq(ohci->dev->irq, ohci);
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_dma_rcv_ctx(&ohci->ar_req_context);
free_dma_rcv_ctx(&ohci->ar_resp_context);
......
This diff is collapsed.
......@@ -38,6 +38,7 @@
#include <linux/smp_lock.h>
#include <linux/interrupt.h>
#include <linux/vmalloc.h>
#include <linux/cdev.h>
#include <asm/uaccess.h>
#include <asm/atomic.h>
#include <linux/devfs_fs_kernel.h>
......@@ -1695,7 +1696,7 @@ static int arm_register(struct file_info *fi, struct pending_request *req)
spin_unlock_irqrestore(&host_info_lock, flags);
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);
if (retval) {
/* INSERT ENTRY */
......@@ -1782,7 +1783,7 @@ static int arm_unregister(struct file_info *fi, struct pending_request *req)
spin_unlock_irqrestore(&host_info_lock, flags);
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) {
printk(KERN_ERR "raw1394: arm_Unregister failed -> EINVAL\n");
spin_unlock_irqrestore(&host_info_lock, flags);
......@@ -2464,10 +2465,6 @@ static int raw1394_open(struct inode *inode, struct file *file)
{
struct file_info *fi;
if (ieee1394_file_to_instance(file) > 0) {
return -ENXIO;
}
fi = kmalloc(sizeof(struct file_info), SLAB_KERNEL);
if (fi == NULL)
return -ENOMEM;
......@@ -2554,7 +2551,7 @@ static int raw1394_release(struct inode *inode, struct file *file)
}
if (!another_host) {
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) {
++fail;
printk(KERN_ERR "raw1394_release arm_Unregister failed\n");
......@@ -2646,7 +2643,8 @@ static struct hpsb_highlevel raw1394_highlevel = {
.fcp_request = fcp_request,
};
static struct file_operations file_ops = {
static struct cdev raw1394_cdev;
static struct file_operations raw1394_fops = {
.owner = THIS_MODULE,
.read = raw1394_read,
.write = raw1394_write,
......@@ -2664,8 +2662,10 @@ static int __init init_raw1394(void)
devfs_mk_cdev(MKDEV(IEEE1394_MAJOR, IEEE1394_MINOR_BLOCK_RAW1394 * 16),
S_IFCHR | S_IRUSR | S_IWUSR, RAW1394_DEVICE_NAME);
if (ieee1394_register_chardev(IEEE1394_MINOR_BLOCK_RAW1394,
THIS_MODULE, &file_ops)) {
cdev_init(&raw1394_cdev, &raw1394_fops);
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");
devfs_remove(RAW1394_DEVICE_NAME);
hpsb_unregister_highlevel(&raw1394_highlevel);
......@@ -2682,7 +2682,8 @@ static int __init init_raw1394(void)
static void __exit cleanup_raw1394(void)
{
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);
hpsb_unregister_highlevel(&raw1394_highlevel);
}
......@@ -2690,3 +2691,4 @@ static void __exit cleanup_raw1394(void)
module_init(init_raw1394);
module_exit(cleanup_raw1394);
MODULE_LICENSE("GPL");
MODULE_ALIAS_CHARDEV(IEEE1394_MAJOR, IEEE1394_MINOR_BLOCK_RAW1394 * 16);
......@@ -77,7 +77,7 @@
#include "sbp2.h"
static char version[] __devinitdata =
"$Rev: 1082 $ Ben Collins <bcollins@debian.org>";
"$Rev: 1096 $ Ben Collins <bcollins@debian.org>";
/*
* Module load parameter definitions
......@@ -712,6 +712,18 @@ static struct sbp2scsi_host_info *sbp2_add_host(struct hpsb_host *host)
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));
if (!hi) {
SBP2_ERR("failed to allocate hostinfo");
......@@ -2881,17 +2893,6 @@ static int sbp2_module_init(void)
/* Register our high level driver with 1394 stack */
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);
return 0;
......
......@@ -46,6 +46,7 @@
#include <linux/mm.h>
#include <linux/ioctl32.h>
#include <linux/compat.h>
#include <linux/cdev.h>
#include "ieee1394.h"
#include "ieee1394_types.h"
......@@ -1231,6 +1232,7 @@ static int video1394_release(struct inode *inode, struct file *file)
return 0;
}
static struct cdev video1394_cdev;
static struct file_operations video1394_fops=
{
.owner = THIS_MODULE,
......@@ -1445,18 +1447,18 @@ static void __exit video1394_exit_module (void)
hpsb_unregister_highlevel(&video1394_highlevel);
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");
}
static int __init video1394_init_module (void)
{
int ret;
ret = ieee1394_register_chardev(IEEE1394_MINOR_BLOCK_VIDEO1394,
THIS_MODULE, &video1394_fops);
if (ret) {
cdev_init(&video1394_cdev, &video1394_fops);
video1394_cdev.owner = THIS_MODULE;
kobject_set_name(&video1394_cdev.kobj, VIDEO1394_DRIVER_NAME);
if (cdev_add(&video1394_cdev, IEEE1394_VIDEO1394_DEV, 16)) {
PRINT_G(KERN_ERR, "video1394: unable to get minor device block");
return -EIO;
}
......@@ -1468,25 +1470,29 @@ static int __init video1394_init_module (void)
hpsb_register_protocol(&video1394_driver);
#ifdef CONFIG_COMPAT
/* First the compatible ones */
ret = register_ioctl32_conversion(VIDEO1394_IOC_LISTEN_CHANNEL, NULL);
ret |= register_ioctl32_conversion(VIDEO1394_IOC_UNLISTEN_CHANNEL, NULL);
ret |= register_ioctl32_conversion(VIDEO1394_IOC_TALK_CHANNEL, NULL);
ret |= register_ioctl32_conversion(VIDEO1394_IOC_UNTALK_CHANNEL, NULL);
/* These need translation */
ret |= register_ioctl32_conversion(VIDEO1394_IOC32_LISTEN_QUEUE_BUFFER,
video1394_w_wait32);
ret |= register_ioctl32_conversion(VIDEO1394_IOC32_LISTEN_WAIT_BUFFER,
video1394_wr_wait32);
ret |= register_ioctl32_conversion(VIDEO1394_IOC_TALK_QUEUE_BUFFER,
video1394_queue_buf32);
ret |= register_ioctl32_conversion(VIDEO1394_IOC32_TALK_WAIT_BUFFER,
video1394_w_wait32);
ret |= register_ioctl32_conversion(VIDEO1394_IOC32_LISTEN_POLL_BUFFER,
video1394_wr_wait32);
if (ret)
PRINT_G(KERN_INFO, "Error registering ioctl32 translations");
{
int ret;
/* First the compatible ones */
ret = register_ioctl32_conversion(VIDEO1394_IOC_LISTEN_CHANNEL, NULL);
ret |= register_ioctl32_conversion(VIDEO1394_IOC_UNLISTEN_CHANNEL, NULL);
ret |= register_ioctl32_conversion(VIDEO1394_IOC_TALK_CHANNEL, NULL);
ret |= register_ioctl32_conversion(VIDEO1394_IOC_UNTALK_CHANNEL, NULL);
/* These need translation */
ret |= register_ioctl32_conversion(VIDEO1394_IOC32_LISTEN_QUEUE_BUFFER,
video1394_w_wait32);
ret |= register_ioctl32_conversion(VIDEO1394_IOC32_LISTEN_WAIT_BUFFER,
video1394_wr_wait32);
ret |= register_ioctl32_conversion(VIDEO1394_IOC_TALK_QUEUE_BUFFER,
video1394_queue_buf32);
ret |= register_ioctl32_conversion(VIDEO1394_IOC32_TALK_WAIT_BUFFER,
video1394_w_wait32);
ret |= register_ioctl32_conversion(VIDEO1394_IOC32_LISTEN_POLL_BUFFER,
video1394_wr_wait32);
if (ret)
PRINT_G(KERN_INFO, "Error registering ioctl32 translations");
}
#endif
PRINT_G(KERN_INFO, "Installed " VIDEO1394_DRIVER_NAME " module");
......@@ -1496,3 +1502,4 @@ static int __init video1394_init_module (void)
module_init(video1394_init_module);
module_exit(video1394_exit_module);
MODULE_ALIAS_CHARDEV(IEEE1394_MAJOR, IEEE1394_MINOR_BLOCK_VIDEO1394 * 16);
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