Commit 467d43e7 authored by Ben Collins's avatar Ben Collins Committed by Linus Torvalds

[PATCH] Merge to current SVN repo (r915)

Changes:

  - Convert to a static highlevel handle for all drivers. Gets rid of
    a kmalloc for each driver and consolidates the highlevel handle and
    highlevel ops. Reduces points of failure as well.
  - Move host number allocation to hosts.c, giving all drivers access to
    it.
  - Implemented S800 changes for core and sbp2. Thanks to TI and LaCie
    for hardware to test this. 1394b support coming soon.
  - Convert nodemgr to using a similar device classification hack as
    usb. The old class_num hack I had in place was broken do to its
    removal. This is a much cleaner solution.
parent 13d861c0
......@@ -268,7 +268,7 @@ struct amdtp_host {
spinlock_t stream_list_lock;
};
static struct hpsb_highlevel *amdtp_highlevel;
static struct hpsb_highlevel amdtp_highlevel;
/* FIXME: This doesn't belong here... */
......@@ -1169,7 +1169,7 @@ static int amdtp_open(struct inode *inode, struct file *file)
struct amdtp_host *host;
int i = ieee1394_file_to_instance(file);
host = hpsb_get_hostinfo_bykey(amdtp_highlevel, i);
host = hpsb_get_hostinfo_bykey(&amdtp_highlevel, i);
if (host == NULL)
return -ENODEV;
......@@ -1201,7 +1201,7 @@ static struct file_operations amdtp_fops =
/* IEEE1394 Subsystem functions */
static void amdtp_add_host(struct hpsb_host *host, struct hpsb_highlevel *hl)
static void amdtp_add_host(struct hpsb_host *host)
{
struct amdtp_host *ah;
int minor;
......@@ -1210,7 +1210,7 @@ static void amdtp_add_host(struct hpsb_host *host, struct hpsb_highlevel *hl)
if (strcmp(host->driver->name, OHCI1394_DRIVER_NAME) != 0)
return;
ah = hpsb_create_hostinfo(hl, host, sizeof(*ah));
ah = hpsb_create_hostinfo(&amdtp_highlevel, host, sizeof(*ah));
if (!ah) {
HPSB_ERR("amdtp: Unable able to alloc hostinfo");
return;
......@@ -1219,7 +1219,7 @@ static void amdtp_add_host(struct hpsb_host *host, struct hpsb_highlevel *hl)
ah->host = host;
ah->ohci = host->hostdata;
hpsb_set_hostinfo_key(hl, host, ah->ohci->id);
hpsb_set_hostinfo_key(&amdtp_highlevel, host, ah->ohci->id);
minor = IEEE1394_MINOR_BLOCK_AMDTP * 16 + ah->ohci->id;
......@@ -1234,7 +1234,7 @@ static void amdtp_add_host(struct hpsb_host *host, struct hpsb_highlevel *hl)
static void amdtp_remove_host(struct hpsb_host *host)
{
struct amdtp_host *ah = hpsb_get_hostinfo(amdtp_highlevel, host);
struct amdtp_host *ah = hpsb_get_hostinfo(&amdtp_highlevel, host);
if (ah)
devfs_remove("amdtp/%d", ah->ohci->id);
......@@ -1242,7 +1242,8 @@ static void amdtp_remove_host(struct hpsb_host *host)
return;
}
static struct hpsb_highlevel_ops amdtp_highlevel_ops = {
static struct hpsb_highlevel amdtp_highlevel = {
.name = "amdtp",
.add_host = amdtp_add_host,
.remove_host = amdtp_remove_host,
};
......@@ -1268,14 +1269,7 @@ static int __init amdtp_init_module (void)
devfs_mk_dir("amdtp");
amdtp_highlevel = hpsb_register_highlevel ("amdtp",
&amdtp_highlevel_ops);
if (amdtp_highlevel == NULL) {
HPSB_ERR("amdtp: unable to register highlevel ops");
devfs_remove("amdtp");
ieee1394_unregister_chardev(IEEE1394_MINOR_BLOCK_AMDTP);
return -EIO;
}
hpsb_register_highlevel(&amdtp_highlevel);
#ifdef CONFIG_COMPAT
ret = register_ioctl32_conversion(AMDTP_IOC_CHANNEL, NULL);
......@@ -1304,7 +1298,7 @@ static void __exit amdtp_exit_module (void)
HPSB_ERR("amdtp: Error unregistering ioctl32 translations");
#endif
hpsb_unregister_highlevel(amdtp_highlevel);
hpsb_unregister_highlevel(&amdtp_highlevel);
devfs_remove("amdtp");
ieee1394_unregister_chardev(IEEE1394_MINOR_BLOCK_AMDTP);
......
......@@ -75,7 +75,7 @@ enum {
#define CSR_PCR_MAP 0x900
#define CSR_PCR_MAP_END 0x9fc
static struct hpsb_highlevel *cmp_highlevel;
static struct hpsb_highlevel cmp_highlevel;
struct cmp_pcr *
cmp_register_opcr(struct hpsb_host *host, int opcr_number, int payload,
......@@ -85,7 +85,7 @@ cmp_register_opcr(struct hpsb_host *host, int opcr_number, int payload,
struct cmp_host *ch;
struct plug *plug;
ch = hpsb_get_hostinfo(cmp_highlevel, host);
ch = hpsb_get_hostinfo(&cmp_highlevel, host);
if (opcr_number >= ch->u.ompr.nplugs ||
ch->opcr[opcr_number].update != NULL)
......@@ -108,7 +108,7 @@ void cmp_unregister_opcr(struct hpsb_host *host, struct cmp_pcr *opcr)
struct cmp_host *ch;
struct plug *plug;
ch = hpsb_get_hostinfo(cmp_highlevel, host);
ch = hpsb_get_hostinfo(&cmp_highlevel, host);
plug = (struct plug *)opcr;
if (plug - ch->opcr >= ch->u.ompr.nplugs) BUG();
......@@ -128,9 +128,9 @@ static void reset_plugs(struct cmp_host *ch)
}
}
static void cmp_add_host(struct hpsb_host *host, struct hpsb_highlevel *hl)
static void cmp_add_host(struct hpsb_host *host)
{
struct cmp_host *ch = hpsb_create_hostinfo(hl, host, sizeof (*ch));
struct cmp_host *ch = hpsb_create_hostinfo(&cmp_highlevel, host, sizeof (*ch));
if (ch == NULL) {
HPSB_ERR("Failed to allocate cmp_host");
......@@ -149,7 +149,7 @@ static void cmp_host_reset(struct hpsb_host *host)
{
struct cmp_host *ch;
ch = hpsb_get_hostinfo(cmp_highlevel, host);
ch = hpsb_get_hostinfo(&cmp_highlevel, host);
if (ch == NULL) {
HPSB_ERR("cmp: Tried to reset unknown host");
return;
......@@ -168,7 +168,7 @@ static int pcr_read(struct hpsb_host *host, int nodeid, quadlet_t *buf,
if (length != 4)
return RCODE_TYPE_ERROR;
ch = hpsb_get_hostinfo(cmp_highlevel, host);
ch = hpsb_get_hostinfo(&cmp_highlevel, host);
if (csraddr == 0x900) {
*buf = cpu_to_be32(ch->u.ompr_quadlet);
return RCODE_COMPLETE;
......@@ -201,7 +201,7 @@ static int pcr_lock(struct hpsb_host *host, int nodeid, quadlet_t *store,
int plug;
struct cmp_host *ch;
ch = hpsb_get_hostinfo(cmp_highlevel, host);
ch = hpsb_get_hostinfo(&cmp_highlevel, host);
if (extcode != EXTCODE_COMPARE_SWAP)
return RCODE_TYPE_ERROR;
......@@ -258,7 +258,8 @@ static int pcr_lock(struct hpsb_host *host, int nodeid, quadlet_t *store,
}
static struct hpsb_highlevel_ops cmp_highlevel_ops = {
static struct hpsb_highlevel cmp_highlevel = {
.name = "cmp",
.add_host = cmp_add_host,
.host_reset = cmp_host_reset,
};
......@@ -280,14 +281,9 @@ EXPORT_SYMBOL(cmp_unregister_opcr);
static int __init cmp_init_module (void)
{
cmp_highlevel = hpsb_register_highlevel ("cmp",
&cmp_highlevel_ops);
if (cmp_highlevel == NULL) {
HPSB_ERR("cmp: unable to register highlevel ops");
return -EIO;
}
hpsb_register_highlevel (&cmp_highlevel);
hpsb_register_addrspace(cmp_highlevel, &pcr_ops,
hpsb_register_addrspace(&cmp_highlevel, &pcr_ops,
CSR_REGISTER_BASE + CSR_PCR_MAP,
CSR_REGISTER_BASE + CSR_PCR_MAP_END);
......@@ -298,7 +294,7 @@ static int __init cmp_init_module (void)
static void __exit cmp_exit_module (void)
{
hpsb_unregister_highlevel(cmp_highlevel);
hpsb_unregister_highlevel(&cmp_highlevel);
HPSB_INFO("Unloaded CMP driver");
}
......
......@@ -90,7 +90,7 @@ static void host_reset(struct hpsb_host *host)
}
static void add_host(struct hpsb_host *host, struct hpsb_highlevel *hl)
static void add_host(struct hpsb_host *host)
{
host->csr.lock = SPIN_LOCK_UNLOCKED;
......@@ -647,7 +647,8 @@ static int write_fcp(struct hpsb_host *host, int nodeid, int dest,
}
static struct hpsb_highlevel_ops csr_ops = {
static struct hpsb_highlevel csr_highlevel = {
.name = "standard registers",
.add_host = add_host,
.host_reset = host_reset,
};
......@@ -668,35 +669,29 @@ static struct hpsb_address_ops reg_ops = {
.lock64 = lock64_regs,
};
static struct hpsb_highlevel *hl;
void init_csr(void)
{
hl = hpsb_register_highlevel("standard registers", &csr_ops);
if (hl == NULL) {
HPSB_ERR("out of memory during ieee1394 initialization");
return;
}
hpsb_register_highlevel(&csr_highlevel);
hpsb_register_addrspace(hl, &reg_ops, CSR_REGISTER_BASE,
hpsb_register_addrspace(&csr_highlevel, &reg_ops, CSR_REGISTER_BASE,
CSR_REGISTER_BASE + CSR_CONFIG_ROM);
hpsb_register_addrspace(hl, &map_ops,
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(hl, &fcp_ops,
hpsb_register_addrspace(&csr_highlevel, &fcp_ops,
CSR_REGISTER_BASE + CSR_FCP_COMMAND,
CSR_REGISTER_BASE + CSR_FCP_END);
}
hpsb_register_addrspace(hl, &map_ops,
hpsb_register_addrspace(&csr_highlevel, &map_ops,
CSR_REGISTER_BASE + CSR_TOPOLOGY_MAP,
CSR_REGISTER_BASE + CSR_TOPOLOGY_MAP_END);
hpsb_register_addrspace(hl, &map_ops,
hpsb_register_addrspace(&csr_highlevel, &map_ops,
CSR_REGISTER_BASE + CSR_SPEED_MAP,
CSR_REGISTER_BASE + CSR_SPEED_MAP_END);
}
void cleanup_csr(void)
{
hpsb_unregister_highlevel(hl);
hpsb_unregister_highlevel(&csr_highlevel);
}
......@@ -175,8 +175,6 @@ static void ir_tasklet_func(unsigned long data);
static LIST_HEAD(dv1394_cards);
static spinlock_t dv1394_cards_lock = SPIN_LOCK_UNLOCKED;
static struct hpsb_highlevel *hl_handle; /* = NULL; */
/* translate from a struct file* to the corresponding struct video_card* */
static inline struct video_card* file_to_video_card(struct file *file)
......@@ -2620,7 +2618,7 @@ static void dv1394_remove_host (struct hpsb_host *host)
#endif
}
static void dv1394_add_host (struct hpsb_host *host, struct hpsb_highlevel *hl)
static void dv1394_add_host (struct hpsb_host *host)
{
struct ti_ohci *ohci;
char buf[16];
......@@ -2776,7 +2774,8 @@ static void dv1394_host_reset(struct hpsb_host *host)
wake_up_interruptible(&video->waitq);
}
static struct hpsb_highlevel_ops hl_ops = {
static struct hpsb_highlevel dv1394_highlevel = {
.name = "dv1394",
.add_host = dv1394_add_host,
.remove_host = dv1394_remove_host,
.host_reset = dv1394_host_reset,
......@@ -2900,7 +2899,7 @@ static void __exit dv1394_exit_module(void)
hpsb_unregister_protocol(&dv1394_driver);
hpsb_unregister_highlevel (hl_handle);
hpsb_unregister_highlevel(&dv1394_highlevel);
ieee1394_unregister_chardev(IEEE1394_MINOR_BLOCK_DV1394);
#ifdef CONFIG_DEVFS_FS
devfs_remove("ieee1394/dv");
......@@ -2937,18 +2936,7 @@ static int __init dv1394_init_module(void)
}
#endif
hl_handle = hpsb_register_highlevel ("dv1394", &hl_ops);
if (hl_handle == NULL) {
printk(KERN_ERR "dv1394: hpsb_register_highlevel failed\n");
ieee1394_unregister_chardev(IEEE1394_MINOR_BLOCK_DV1394);
#ifdef CONFIG_DEVFS_FS
devfs_remove("ieee1394/dv");
#endif
#ifdef CONFIG_PROC_FS
dv1394_procfs_del("dv");
#endif
return -ENOMEM;
}
hpsb_register_highlevel(&dv1394_highlevel);
hpsb_register_protocol(&dv1394_driver);
......
......@@ -78,14 +78,14 @@
printk(KERN_ERR fmt, ## args)
static char version[] __devinitdata =
"$Rev: 895 $ Ben Collins <bcollins@debian.org>";
"$Rev: 906 $ Ben Collins <bcollins@debian.org>";
/* Our ieee1394 highlevel driver */
#define ETHER1394_DRIVER_NAME "ether1394"
static kmem_cache_t *packet_task_cache;
static struct hpsb_highlevel *hl_handle = NULL;
static struct hpsb_highlevel eth1394_highlevel;
/* Use common.lf to determine header len */
static int hdr_type_len[] = {
......@@ -318,7 +318,7 @@ static int ether1394_init_dev (struct net_device *dev)
* when the module is installed. This is where we add all of our ethernet
* devices. One for each host.
*/
static void ether1394_add_host (struct hpsb_host *host, struct hpsb_highlevel *hl)
static void ether1394_add_host (struct hpsb_host *host)
{
struct host_info *hi = NULL;
struct net_device *dev = NULL;
......@@ -342,7 +342,7 @@ static void ether1394_add_host (struct hpsb_host *host, struct hpsb_highlevel *h
priv->host = host;
spin_lock_init(&priv->lock);
hi = hpsb_create_hostinfo(hl, host, sizeof(*hi));
hi = hpsb_create_hostinfo(&eth1394_highlevel, host, sizeof(*hi));
if (hi == NULL)
goto out;
......@@ -373,7 +373,7 @@ static void ether1394_add_host (struct hpsb_host *host, struct hpsb_highlevel *h
if (dev != NULL)
kfree (dev);
if (hi)
hpsb_destroy_hostinfo(hl, host);
hpsb_destroy_hostinfo(&eth1394_highlevel, host);
ETH1394_PRINT_G (KERN_ERR, "Out of memory\n");
......@@ -383,7 +383,7 @@ static void ether1394_add_host (struct hpsb_host *host, struct hpsb_highlevel *h
/* Remove a card from our list */
static void ether1394_remove_host (struct hpsb_host *host)
{
struct host_info *hi = hpsb_get_hostinfo(hl_handle, host);
struct host_info *hi = hpsb_get_hostinfo(&eth1394_highlevel, host);
if (hi != NULL) {
struct eth1394_priv *priv = (struct eth1394_priv *)hi->dev->priv;
......@@ -401,7 +401,7 @@ static void ether1394_remove_host (struct hpsb_host *host)
/* A reset has just arisen */
static void ether1394_host_reset (struct hpsb_host *host)
{
struct host_info *hi = hpsb_get_hostinfo(hl_handle, host);
struct host_info *hi = hpsb_get_hostinfo(&eth1394_highlevel, host);
struct net_device *dev;
/* This can happen for hosts that we don't use */
......@@ -518,7 +518,7 @@ static int ether1394_write (struct hpsb_host *host, int srcid, int destid,
struct sk_buff *skb;
char *buf = (char *)data;
unsigned long flags;
struct host_info *hi = hpsb_get_hostinfo(hl_handle, host);
struct host_info *hi = hpsb_get_hostinfo(&eth1394_highlevel, host);
struct net_device *dev;
struct eth1394_priv *priv;
......@@ -590,7 +590,7 @@ static void ether1394_iso(struct hpsb_iso *iso)
quadlet_t *data;
char *buf;
unsigned long flags;
struct host_info *hi = hpsb_get_hostinfo(hl_handle, iso->host);
struct host_info *hi = hpsb_get_hostinfo(&eth1394_highlevel, iso->host);
struct net_device *dev;
struct eth1394_priv *priv;
unsigned int len;
......@@ -879,7 +879,8 @@ static struct hpsb_address_ops addr_ops = {
};
/* Ieee1394 highlevel driver functions */
static struct hpsb_highlevel_ops hl_ops = {
static struct hpsb_highlevel eth1394_highlevel = {
.name = ETHER1394_DRIVER_NAME,
.add_host = ether1394_add_host,
.remove_host = ether1394_remove_host,
.host_reset = ether1394_host_reset,
......@@ -891,14 +892,9 @@ static int __init ether1394_init_module (void)
0, 0, NULL, NULL);
/* Register ourselves as a highlevel driver */
hl_handle = hpsb_register_highlevel (ETHER1394_DRIVER_NAME, &hl_ops);
hpsb_register_highlevel(&eth1394_highlevel);
if (hl_handle == NULL) {
ETH1394_PRINT_G (KERN_ERR, "No more memory for driver\n");
return -ENOMEM;
}
hpsb_register_addrspace (hl_handle, &addr_ops, ETHER1394_REGION_ADDR,
hpsb_register_addrspace(&eth1394_highlevel, &addr_ops, ETHER1394_REGION_ADDR,
ETHER1394_REGION_ADDR_END);
return 0;
......@@ -906,7 +902,7 @@ static int __init ether1394_init_module (void)
static void __exit ether1394_exit_module (void)
{
hpsb_unregister_highlevel (hl_handle);
hpsb_unregister_highlevel(&eth1394_highlevel);
kmem_cache_destroy(packet_task_cache);
}
......
......@@ -54,6 +54,9 @@ static struct hl_host_info *hl_get_hostinfo(struct hpsb_highlevel *hl,
struct hl_host_info *hi = NULL;
struct list_head *lh;
if (!hl || !host)
return NULL;
read_lock(&hl->host_info_lock);
list_for_each (lh, &hl->host_info_list) {
hi = list_entry(lh, struct hl_host_info, list);
......@@ -185,6 +188,9 @@ void *hpsb_get_hostinfo_bykey(struct hpsb_highlevel *hl, unsigned long key)
struct hl_host_info *hi;
void *data = NULL;
if (!hl)
return NULL;
read_lock(&hl->host_info_lock);
list_for_each (lh, &hl->host_info_list) {
hi = list_entry(lh, struct hl_host_info, list);
......@@ -199,42 +205,53 @@ void *hpsb_get_hostinfo_bykey(struct hpsb_highlevel *hl, unsigned long key)
}
struct hpsb_highlevel *hpsb_register_highlevel(const char *name,
struct hpsb_highlevel_ops *ops)
struct hpsb_host *hpsb_get_host_bykey(struct hpsb_highlevel *hl, unsigned long key)
{
struct hpsb_highlevel *hl;
struct list_head *lh;
unsigned long flags;
struct hl_host_info *hi;
struct hpsb_host *host = NULL;
hl = (struct hpsb_highlevel *)kmalloc(sizeof(struct hpsb_highlevel),
GFP_KERNEL);
if (hl == NULL) {
if (!hl)
return NULL;
read_lock(&hl->host_info_lock);
list_for_each (lh, &hl->host_info_list) {
hi = list_entry(lh, struct hl_host_info, list);
if (hi->key == key) {
host = hi->host;
break;
}
}
read_unlock(&hl->host_info_lock);
return host;
}
void hpsb_register_highlevel(struct hpsb_highlevel *hl)
{
struct list_head *lh;
unsigned long flags;
INIT_LIST_HEAD(&hl->hl_list);
INIT_LIST_HEAD(&hl->addr_list);
INIT_LIST_HEAD(&hl->host_info_list);
rwlock_init(&hl->host_info_lock);
hl->name = name;
hl->op = ops;
write_lock_irqsave(&hl_drivers_lock, flags);
list_add_tail(&hl->hl_list, &hl_drivers);
write_unlock_irqrestore(&hl_drivers_lock, flags);
if (hl->op->add_host) {
if (hl->add_host) {
down(&hpsb_hosts_lock);
list_for_each (lh, &hpsb_hosts) {
struct hpsb_host *host = list_entry(lh, struct hpsb_host, host_list);
hl->op->add_host(host, hl);
hl->add_host(host);
}
up(&hpsb_hosts_lock);
}
return hl;
return;
}
void hpsb_unregister_highlevel(struct hpsb_highlevel *hl)
......@@ -243,10 +260,6 @@ void hpsb_unregister_highlevel(struct hpsb_highlevel *hl)
struct hpsb_address_serve *as;
unsigned long flags;
if (hl == NULL) {
return;
}
write_lock_irqsave(&addr_space_lock, flags);
list_for_each_safe (lh, next, &hl->addr_list) {
as = list_entry(lh, struct hpsb_address_serve, addr_list);
......@@ -259,18 +272,16 @@ void hpsb_unregister_highlevel(struct hpsb_highlevel *hl)
list_del(&hl->hl_list);
write_unlock_irqrestore(&hl_drivers_lock, flags);
if (hl->op->remove_host) {
if (hl->remove_host) {
down(&hpsb_hosts_lock);
list_for_each(lh, &hpsb_hosts) {
struct hpsb_host *host = list_entry(lh, struct hpsb_host, host_list);
hl->op->remove_host(host);
hl->remove_host(host);
hpsb_destroy_hostinfo(hl, host);
}
up(&hpsb_hosts_lock);
}
kfree(hl);
}
int hpsb_register_addrspace(struct hpsb_highlevel *hl,
......@@ -386,8 +397,8 @@ void highlevel_add_host(struct hpsb_host *host)
read_lock(&hl_drivers_lock);
list_for_each(entry, &hl_drivers) {
hl = list_entry(entry, struct hpsb_highlevel, hl_list);
if (hl->op->add_host)
hl->op->add_host(host, hl);
if (hl->add_host)
hl->add_host(host);
}
read_unlock(&hl_drivers_lock);
}
......@@ -401,8 +412,8 @@ void highlevel_remove_host(struct hpsb_host *host)
list_for_each(entry, &hl_drivers) {
hl = list_entry(entry, struct hpsb_highlevel, hl_list);
if (hl->op->remove_host) {
hl->op->remove_host(host);
if (hl->remove_host) {
hl->remove_host(host);
hpsb_destroy_hostinfo(hl, host);
}
}
......@@ -418,8 +429,8 @@ void highlevel_host_reset(struct hpsb_host *host)
list_for_each(entry, &hl_drivers) {
hl = list_entry(entry, struct hpsb_highlevel, hl_list);
if (hl->op->host_reset)
hl->op->host_reset(host);
if (hl->host_reset)
hl->host_reset(host);
}
read_unlock(&hl_drivers_lock);
}
......@@ -436,8 +447,8 @@ void highlevel_iso_receive(struct hpsb_host *host, void *data,
while (entry != &hl_drivers) {
hl = list_entry(entry, struct hpsb_highlevel, hl_list);
if (hl->op->iso_receive) {
hl->op->iso_receive(host, channel, data, length);
if (hl->iso_receive) {
hl->iso_receive(host, channel, data, length);
}
entry = entry->next;
}
......@@ -456,8 +467,8 @@ void highlevel_fcp_request(struct hpsb_host *host, int nodeid, int direction,
while (entry != &hl_drivers) {
hl = list_entry(entry, struct hpsb_highlevel, hl_list);
if (hl->op->fcp_request) {
hl->op->fcp_request(host, nodeid, direction, cts, data,
if (hl->fcp_request) {
hl->fcp_request(host, nodeid, direction, cts, data,
length);
}
entry = entry->next;
......
......@@ -3,21 +3,6 @@
#define IEEE1394_HIGHLEVEL_H
struct hpsb_highlevel {
struct list_head hl_list;
/* List of hpsb_address_serve. */
struct list_head addr_list;
const char *name;
struct hpsb_highlevel_ops *op;
/* Used by the highlevel drivers to store data per host */
struct list_head host_info_list;
rwlock_t host_info_lock;
};
struct hpsb_address_serve {
struct list_head as_list; /* global list */
......@@ -35,14 +20,16 @@ struct hpsb_address_serve {
* following structures are of interest to actual highlevel drivers.
*/
struct hpsb_highlevel_ops {
struct hpsb_highlevel {
const char *name;
/* Any of the following pointers can legally be NULL, except for
* iso_receive which can only be NULL when you don't request
* channels. */
/* New host initialized. Will also be called during
* hpsb_register_highlevel for all hosts already installed. */
void (*add_host) (struct hpsb_host *host, struct hpsb_highlevel *hl);
void (*add_host) (struct hpsb_host *host);
/* Host about to be removed. Will also be called during
* hpsb_unregister_highlevel once for each host. */
......@@ -66,6 +53,13 @@ struct hpsb_highlevel_ops {
*/
void (*fcp_request) (struct hpsb_host *host, int nodeid, int direction,
int cts, u8 *data, unsigned int length);
struct list_head hl_list;
struct list_head addr_list;
struct list_head host_info_list;
rwlock_t host_info_lock;
};
struct hpsb_address_ops {
......@@ -131,8 +125,7 @@ void highlevel_fcp_request(struct hpsb_host *host, int nodeid, int direction,
* Register highlevel driver. The name pointer has to stay valid at all times
* because the string is not copied.
*/
struct hpsb_highlevel *hpsb_register_highlevel(const char *name,
struct hpsb_highlevel_ops *ops);
void hpsb_register_highlevel(struct hpsb_highlevel *hl);
void hpsb_unregister_highlevel(struct hpsb_highlevel *hl);
/*
......@@ -162,19 +155,28 @@ void hpsb_unlisten_channel(struct hpsb_highlevel *hl, struct hpsb_host *host,
/* Retrieve a hostinfo pointer bound to this driver/host */
void *hpsb_get_hostinfo(struct hpsb_highlevel *hl, struct hpsb_host *host);
/* Allocate a hostinfo pointer of data_size bound to this driver/host */
void *hpsb_create_hostinfo(struct hpsb_highlevel *hl, struct hpsb_host *host,
size_t data_size);
/* Free and remove the hostinfo pointer bound to this driver/host */
void hpsb_destroy_hostinfo(struct hpsb_highlevel *hl, struct hpsb_host *host);
/* Set an alternate lookup key for the hostinfo bound to this driver/host */
void hpsb_set_hostinfo_key(struct hpsb_highlevel *hl, struct hpsb_host *host, unsigned long key);
/* Retrieve the alternate lookup key for the hostinfo bound to this driver/host */
unsigned long hpsb_get_hostinfo_key(struct hpsb_highlevel *hl, struct hpsb_host *host);
/* Retrive a hostinfo pointer bound to this driver using its alternate key */
/* Retrieve a hostinfo pointer bound to this driver using its alternate key */
void *hpsb_get_hostinfo_bykey(struct hpsb_highlevel *hl, unsigned long key);
/* Set the hostinfo pointer to something useful. Usually follows a call to
* hpsb_create_hostinfo, where the size is 0. */
int hpsb_set_hostinfo(struct hpsb_highlevel *hl, struct hpsb_host *host, void *data);
/* Retrieve hpsb_host using a highlevel handle and a key */
struct hpsb_host *hpsb_get_host_bykey(struct hpsb_highlevel *hl, unsigned long key);
#endif /* IEEE1394_HIGHLEVEL_H */
......@@ -148,9 +148,36 @@ struct hpsb_host *hpsb_alloc_host(struct hpsb_host_driver *drv, size_t extra)
return h;
}
static int alloc_hostnum(void)
{
int hostnum = 0;
while (1) {
struct list_head *lh;
int found = 0;
list_for_each(lh, &hpsb_hosts) {
struct hpsb_host *host = list_entry(lh, struct hpsb_host, host_list);
if (host->id == hostnum) {
found = 1;
break;
}
}
if (!found)
return hostnum;
hostnum++;
}
return 0;
}
void hpsb_add_host(struct hpsb_host *host)
{
down(&hpsb_hosts_lock);
host->id = alloc_hostnum();
list_add_tail(&host->host_list, &hpsb_hosts);
up(&hpsb_hosts_lock);
......
......@@ -66,6 +66,8 @@ struct hpsb_host {
struct pci_dev *pdev;
int id;
struct device device;
};
......
......@@ -52,10 +52,13 @@
#define SPEED_800 0x03
#define SPEED_1600 0x04
#define SPEED_3200 0x05
/* The current highest tested speed supported by the subsystem */
#define SPEED_MAX SPEED_800
/* Maps speed values above to a string representation */
extern const char *hpsb_speedto_str[];
extern const u8 hpsb_speedto_maxrec[];
#define SELFID_PWRCL_NO_POWER 0x0
#define SELFID_PWRCL_PROVIDE_15W 0x1
......
......@@ -60,6 +60,7 @@ static kmem_cache_t *hpsb_packet_cache;
/* Some globals used */
const char *hpsb_speedto_str[] = { "S100", "S200", "S400", "S800", "S1600", "S3200" };
const u8 hpsb_speedto_maxrec[] = { 0x7, 0x8, 0x9, 0x10, 0x11, 0x12 };
static void dump_packet(const char *text, quadlet_t *data, int size)
{
......@@ -285,7 +286,7 @@ static void build_speed_map(struct hpsb_host *host, int nodecount)
for (i = 0; i < (nodecount * 64); i += 64) {
for (j = 0; j < nodecount; j++) {
map[i+j] = SPEED_400;
map[i+j] = SPEED_MAX;
}
}
......@@ -1239,6 +1240,7 @@ EXPORT_SYMBOL(hpsb_unref_host);
/** ieee1394_core.c **/
EXPORT_SYMBOL(hpsb_speedto_str);
EXPORT_SYMBOL(hpsb_speedto_maxrec);
EXPORT_SYMBOL(hpsb_set_packet_complete_task);
EXPORT_SYMBOL(alloc_hpsb_packet);
EXPORT_SYMBOL(free_hpsb_packet);
......@@ -1278,6 +1280,7 @@ EXPORT_SYMBOL(hpsb_unregister_addrspace);
EXPORT_SYMBOL(hpsb_listen_channel);
EXPORT_SYMBOL(hpsb_unlisten_channel);
EXPORT_SYMBOL(hpsb_get_hostinfo);
EXPORT_SYMBOL(hpsb_get_host_bykey);
EXPORT_SYMBOL(hpsb_create_hostinfo);
EXPORT_SYMBOL(hpsb_destroy_hostinfo);
EXPORT_SYMBOL(hpsb_set_hostinfo_key);
......
......@@ -70,7 +70,6 @@ static char *nodemgr_find_oui_name(int oui)
static DECLARE_MUTEX(nodemgr_serialize);
static struct hpsb_highlevel *nodemgr_hl;
struct host_info {
struct hpsb_host *host;
......@@ -78,10 +77,24 @@ struct host_info {
struct completion exited;
struct semaphore reset_sem;
int pid;
int id;
char daemon_name[15];
};
static struct hpsb_highlevel nodemgr_highlevel;
static int nodemgr_driverdata_ne;
static int nodemgr_driverdata_host;
static struct device_driver nodemgr_driver_ne = {
.name = "ieee1394_node",
.bus = &ieee1394_bus_type,
};
static struct device_driver nodemgr_driver_host = {
.name = "ieee1394_host",
.bus = &ieee1394_bus_type,
};
#define fw_attr(class, class_type, field, type, format_string) \
static ssize_t fw_show_##class##_##field (struct device *dev, char *buf)\
......@@ -364,7 +377,9 @@ static int nodemgr_bus_match(struct device * dev, struct device_driver * drv)
struct unit_directory *ud;
struct ieee1394_device_id *id;
if (dev->class_num != DEV_CLASS_UNIT_DIRECTORY)
if (dev->driver_data == &nodemgr_driverdata_ne ||
dev->driver_data == &nodemgr_driverdata_host ||
drv == &nodemgr_driver_ne || drv == &nodemgr_driver_host)
return 0;
ud = container_of(dev, struct unit_directory, device);
......@@ -448,7 +463,7 @@ static void nodemgr_update_ud_names(struct host_info *hi, struct node_entry *ne)
snprintf(ud->device.name, DEVICE_NAME_SIZE,
"IEEE-1394 unit directory %d-" NODE_BUS_FMT "-%u",
hi->id, NODE_BUS_ARGS(ne->nodeid), ud->id);
hi->host->id, NODE_BUS_ARGS(ne->nodeid), ud->id);
}
}
......@@ -494,18 +509,21 @@ static void nodemgr_remove_host_dev(struct device *dev)
static struct device nodemgr_dev_template_ud = {
.bus = &ieee1394_bus_type,
.release = nodemgr_release_ud,
.class_num = DEV_CLASS_UNIT_DIRECTORY,
};
static struct device nodemgr_dev_template_ne = {
.bus = &ieee1394_bus_type,
.release = nodemgr_release_ne,
.class_num = DEV_CLASS_NODE,
.driver = &nodemgr_driver_ne,
.driver_data = &nodemgr_driverdata_ne,
};
static struct device nodemgr_dev_template_host = {
.bus = &ieee1394_bus_type,
.class_num = DEV_CLASS_HOST,
.driver = &nodemgr_driver_host,
.driver_data = &nodemgr_driverdata_host,
};
......@@ -696,7 +714,7 @@ static struct node_entry *nodemgr_create_node(octlet_t guid, quadlet_t busoption
snprintf(ne->device.bus_id, BUS_ID_SIZE, "%016Lx",
(unsigned long long)(ne->guid));
snprintf(ne->device.name, DEVICE_NAME_SIZE,
"IEEE-1394 device %d-" NODE_BUS_FMT, hi->id,
"IEEE-1394 device %d-" NODE_BUS_FMT, host->id,
NODE_BUS_ARGS(ne->nodeid));
device_register(&ne->device);
......@@ -711,7 +729,7 @@ static struct node_entry *nodemgr_create_node(octlet_t guid, quadlet_t busoption
HPSB_DEBUG("%s added: ID:BUS[%d-" NODE_BUS_FMT "] GUID[%016Lx]",
(host->node_id == nodeid) ? "Host" : "Node",
hi->id, NODE_BUS_ARGS(nodeid), (unsigned long long)guid);
host->id, NODE_BUS_ARGS(nodeid), (unsigned long long)guid);
return ne;
}
......@@ -727,7 +745,7 @@ static int nodemgr_guid_search_cb(struct device *dev, void *__data)
struct guid_search_baton *search = __data;
struct node_entry *ne;
if (dev->class_num != DEV_CLASS_NODE)
if (dev->driver_data != &nodemgr_driverdata_ne)
return 0;
ne = container_of(dev, struct node_entry, device);
......@@ -764,7 +782,7 @@ static int nodemgr_nodeid_search_cb(struct device *dev, void *__data)
struct nodeid_search_baton *search = __data;
struct node_entry *ne;
if (dev->class_num != DEV_CLASS_NODE)
if (dev->driver_data != &nodemgr_driverdata_ne)
return 0;
ne = container_of(dev, struct node_entry, device);
......@@ -1131,7 +1149,9 @@ static int nodemgr_hotplug(struct device *dev, char **envp, int num_envp,
if (!dev)
return -ENODEV;
if (dev->class_num != DEV_CLASS_UNIT_DIRECTORY)
/* Have to check driver_data, since on remove, driver == NULL */
if (dev->driver_data == &nodemgr_driverdata_ne ||
dev->driver_data == &nodemgr_driverdata_host)
return -ENODEV;
ud = container_of(dev, struct unit_directory, device);
......@@ -1173,20 +1193,6 @@ static int nodemgr_hotplug(struct device *dev, char **envp, int num_envp,
#endif /* CONFIG_HOTPLUG */
static DECLARE_MUTEX(host_num_sema);
/* Must hold above mutex until the result of the below call is assigned to
* a hostinfo entry. */
static int nodemgr_alloc_host_num(void)
{
int hostnum;
for (hostnum = 0; hpsb_get_hostinfo_bykey(nodemgr_hl, hostnum); hostnum++)
/* Do nothing */;
return hostnum;
}
int hpsb_register_protocol(struct hpsb_protocol_driver *driver)
{
driver_register(&driver->driver);
......@@ -1258,7 +1264,8 @@ static int nodemgr_driver_search_cb(struct device *dev, void *__data)
struct node_entry *ne = __data;
struct unit_directory *ud;
if (dev->class_num != DEV_CLASS_UNIT_DIRECTORY)
if (dev->driver_data == &nodemgr_driverdata_ne ||
dev->driver_data == &nodemgr_driverdata_host)
return 0;
ud = container_of(dev, struct unit_directory, device);
......@@ -1295,7 +1302,7 @@ static void nodemgr_update_node(struct node_entry *ne, quadlet_t busoptions,
if (ne->nodeid != nodeid) {
snprintf(ne->device.name, DEVICE_NAME_SIZE,
"IEEE-1394 device %d-" NODE_BUS_FMT,
hi->id, NODE_BUS_ARGS(ne->nodeid));
hi->host->id, NODE_BUS_ARGS(ne->nodeid));
HPSB_DEBUG("Node " NODE_BUS_FMT " changed to " NODE_BUS_FMT,
NODE_BUS_ARGS(ne->nodeid), NODE_BUS_ARGS(nodeid));
ne->nodeid = nodeid;
......@@ -1446,7 +1453,7 @@ static int nodemgr_remove_node(struct device *dev, void *__data)
struct cleanup_baton *cleanup = __data;
struct node_entry *ne;
if (dev->class_num != DEV_CLASS_NODE)
if (dev->driver_data != &nodemgr_driverdata_ne)
return 0;
ne = container_of(dev, struct node_entry, device);
......@@ -1550,7 +1557,7 @@ static void nodemgr_do_irm_duties(struct hpsb_host *host)
else {
HPSB_DEBUG("The root node is not cycle master capable; "
"selecting a new root node and resetting...");
hpsb_send_phy_config(host, host->node_id, -1);
hpsb_send_phy_config(host, NODEID_TO_NODE(host->node_id), -1);
hpsb_reset_bus(host, LONG_RESET_FORCE_ROOT);
}
}
......@@ -1583,7 +1590,7 @@ static int nodemgr_check_irm_capability(struct hpsb_host *host, int cycles)
return 1;
}
hpsb_send_phy_config(host, host->node_id, -1);
hpsb_send_phy_config(host, NODEID_TO_NODE(host->node_id), -1);
hpsb_reset_bus(host, LONG_RESET_FORCE_ROOT);
return 0;
......@@ -1732,27 +1739,17 @@ int hpsb_node_lock(struct node_entry *ne, u64 addr,
addr, extcode, data, arg);
}
static void nodemgr_add_host(struct hpsb_host *host, struct hpsb_highlevel *hl)
static void nodemgr_add_host(struct hpsb_host *host)
{
struct host_info *hi;
int id;
down(&host_num_sema);
/* Must be called before we create the hostinfo entry, else it
* will match entry '0' since all keys default to zero */
id = nodemgr_alloc_host_num();
hi = hpsb_create_hostinfo(hl, host, sizeof(*hi));
hi = hpsb_create_hostinfo(&nodemgr_highlevel, host, sizeof(*hi));
if (!hi) {
up(&host_num_sema);
HPSB_ERR ("NodeMgr: out of memory in add host");
return;
}
hi->id = id;
hpsb_set_hostinfo_key(hl, host, hi->id);
up(&host_num_sema);
hi->host = host;
init_completion(&hi->exited);
sema_init(&hi->reset_sem, 0);
......@@ -1760,11 +1757,11 @@ static void nodemgr_add_host(struct hpsb_host *host, struct hpsb_highlevel *hl)
memcpy(&host->device, &nodemgr_dev_template_host,
sizeof(host->device));
host->device.parent = &host->pdev->dev;
snprintf(host->device.bus_id, BUS_ID_SIZE, "fw-host%d", hi->id);
snprintf(host->device.bus_id, BUS_ID_SIZE, "fw-host%d", host->id);
snprintf(host->device.name, DEVICE_NAME_SIZE, "IEEE-1394 Host %s-%d",
host->driver->name, hi->id);
host->driver->name, host->id);
sprintf(hi->daemon_name, "knodemgrd_%d", hi->id);
sprintf(hi->daemon_name, "knodemgrd_%d", host->id);
hi->pid = kernel_thread(nodemgr_host_thread, hi,
CLONE_FS | CLONE_FILES | CLONE_SIGHAND);
......@@ -1772,7 +1769,7 @@ static void nodemgr_add_host(struct hpsb_host *host, struct hpsb_highlevel *hl)
if (hi->pid < 0) {
HPSB_ERR ("NodeMgr: failed to start %s thread for %s",
hi->daemon_name, host->driver->name);
hpsb_destroy_hostinfo(hl, host);
hpsb_destroy_hostinfo(&nodemgr_highlevel, host);
return;
}
......@@ -1781,7 +1778,7 @@ static void nodemgr_add_host(struct hpsb_host *host, struct hpsb_highlevel *hl)
static void nodemgr_host_reset(struct hpsb_host *host)
{
struct host_info *hi = hpsb_get_hostinfo(nodemgr_hl, host);
struct host_info *hi = hpsb_get_hostinfo(&nodemgr_highlevel, host);
if (hi != NULL) {
#ifdef CONFIG_IEEE1394_VERBOSEDEBUG
......@@ -1796,7 +1793,7 @@ static void nodemgr_host_reset(struct hpsb_host *host)
static void nodemgr_remove_host(struct hpsb_host *host)
{
struct host_info *hi = hpsb_get_hostinfo(nodemgr_hl, host);
struct host_info *hi = hpsb_get_hostinfo(&nodemgr_highlevel, host);
if (hi) {
if (hi->pid >= 0) {
......@@ -1812,7 +1809,8 @@ static void nodemgr_remove_host(struct hpsb_host *host)
return;
}
static struct hpsb_highlevel_ops nodemgr_ops = {
static struct hpsb_highlevel nodemgr_highlevel = {
.name = "Node manager",
.add_host = nodemgr_add_host,
.host_reset = nodemgr_host_reset,
.remove_host = nodemgr_remove_host,
......@@ -1821,16 +1819,17 @@ static struct hpsb_highlevel_ops nodemgr_ops = {
void init_ieee1394_nodemgr(void)
{
bus_register(&ieee1394_bus_type);
driver_register(&nodemgr_driver_host);
driver_register(&nodemgr_driver_ne);
nodemgr_hl = hpsb_register_highlevel("Node manager", &nodemgr_ops);
if (!nodemgr_hl) {
HPSB_ERR("NodeMgr: out of memory during ieee1394 initialization");
}
hpsb_register_highlevel(&nodemgr_highlevel);
}
void cleanup_ieee1394_nodemgr(void)
{
hpsb_unregister_highlevel(nodemgr_hl);
hpsb_unregister_highlevel(&nodemgr_highlevel);
driver_unregister(&nodemgr_driver_ne);
driver_unregister(&nodemgr_driver_host);
bus_unregister(&ieee1394_bus_type);
}
......@@ -79,11 +79,6 @@ struct bus_options {
u16 max_rec; /* Maximum packet size node can receive */
};
enum {
DEV_CLASS_NODE,
DEV_CLASS_UNIT_DIRECTORY,
DEV_CLASS_HOST,
};
#define UNIT_DIRECTORY_VENDOR_ID 0x01
#define UNIT_DIRECTORY_MODEL_ID 0x02
......
......@@ -164,7 +164,7 @@ printk(level "%s: " fmt "\n" , OHCI1394_DRIVER_NAME , ## args)
printk(level "%s_%d: " fmt "\n" , OHCI1394_DRIVER_NAME, card , ## args)
static char version[] __devinitdata =
"$Rev: 902 $ Ben Collins <bcollins@debian.org>";
"$Rev: 908 $ Ben Collins <bcollins@debian.org>";
/* Module Parameters */
static int phys_dma = 1;
......
......@@ -77,11 +77,11 @@ static int host_count;
static spinlock_t host_info_lock = SPIN_LOCK_UNLOCKED;
static atomic_t internal_generation = ATOMIC_INIT(0);
static struct hpsb_highlevel *hl_handle;
static atomic_t iso_buffer_size;
static const int iso_buffer_max = 4 * 1024 * 1024; /* 4 MB */
static struct hpsb_highlevel raw1394_highlevel;
static int arm_read (struct hpsb_host *host, int nodeid, quadlet_t *buffer,
u64 addr, unsigned int length, u16 flags);
static int arm_write (struct hpsb_host *host, int nodeid, int destid,
......@@ -188,7 +188,7 @@ static void queue_complete_cb(struct pending_request *req)
}
static void add_host(struct hpsb_host *host, struct hpsb_highlevel *hl)
static void add_host(struct hpsb_host *host)
{
struct host_info *hi;
unsigned long flags;
......@@ -601,7 +601,7 @@ static void handle_iso_listen(struct file_info *fi, struct pending_request *req)
if (fi->listen_channels & (1ULL << channel)) {
req->req.error = RAW1394_ERROR_ALREADY;
} else {
if(hpsb_listen_channel(hl_handle, fi->host, channel)) {
if(hpsb_listen_channel(&raw1394_highlevel, fi->host, channel)) {
req->req.error = RAW1394_ERROR_ALREADY;
} else {
fi->listen_channels |= 1ULL << channel;
......@@ -614,7 +614,7 @@ static void handle_iso_listen(struct file_info *fi, struct pending_request *req)
channel = ~channel;
if (fi->listen_channels & (1ULL << channel)) {
hpsb_unlisten_channel(hl_handle, fi->host, channel);
hpsb_unlisten_channel(&raw1394_highlevel, fi->host, channel);
fi->listen_channels &= ~(1ULL << channel);
} else {
req->req.error = RAW1394_ERROR_INVALID_ARG;
......@@ -1679,7 +1679,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(hl_handle, &arm_ops, req->req.address,
retval = hpsb_register_addrspace(&raw1394_highlevel, &arm_ops, req->req.address,
req->req.address + req->req.length);
if (retval) {
/* INSERT ENTRY */
......@@ -1766,7 +1766,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(hl_handle, addr->start);
retval = hpsb_unregister_addrspace(&raw1394_highlevel, addr->start);
if (!retval) {
printk(KERN_ERR "raw1394: arm_Unregister failed -> EINVAL\n");
spin_unlock_irqrestore(&host_info_lock, flags);
......@@ -2379,7 +2379,7 @@ static int raw1394_release(struct inode *inode, struct file *file)
for (i = 0; i < 64; i++) {
if (fi->listen_channels & (1ULL << i)) {
hpsb_unlisten_channel(hl_handle, fi->host, i);
hpsb_unlisten_channel(&raw1394_highlevel, fi->host, i);
}
}
......@@ -2424,7 +2424,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(hl_handle, addr->start);
retval = hpsb_unregister_addrspace(&raw1394_highlevel, addr->start);
if (!retval) {
++fail;
printk(KERN_ERR "raw1394_release arm_Unregister failed\n");
......@@ -2507,7 +2507,8 @@ static struct hpsb_protocol_driver raw1394_driver = {
/******************************************************************************/
static struct hpsb_highlevel_ops hl_ops = {
static struct hpsb_highlevel raw1394_highlevel = {
.name = RAW1394_DEVICE_NAME,
.add_host = add_host,
.remove_host = remove_host,
.host_reset = host_reset,
......@@ -2528,11 +2529,7 @@ static struct file_operations file_ops = {
static int __init init_raw1394(void)
{
hl_handle = hpsb_register_highlevel(RAW1394_DEVICE_NAME, &hl_ops);
if (hl_handle == NULL) {
HPSB_ERR("raw1394 failed to register with ieee1394 highlevel");
return -ENOMEM;
}
hpsb_register_highlevel(&raw1394_highlevel);
devfs_register(NULL, RAW1394_DEVICE_NAME, 0,
IEEE1394_MAJOR, IEEE1394_MINOR_BLOCK_RAW1394 * 16,
......@@ -2542,7 +2539,7 @@ static int __init init_raw1394(void)
THIS_MODULE, &file_ops)) {
HPSB_ERR("raw1394 failed to register minor device block");
devfs_remove(RAW1394_DEVICE_NAME);
hpsb_unregister_highlevel(hl_handle);
hpsb_unregister_highlevel(&raw1394_highlevel);
return -EBUSY;
}
......@@ -2558,7 +2555,7 @@ static void __exit cleanup_raw1394(void)
hpsb_unregister_protocol(&raw1394_driver);
ieee1394_unregister_chardev(IEEE1394_MINOR_BLOCK_RAW1394);
devfs_remove(RAW1394_DEVICE_NAME);
hpsb_unregister_highlevel(hl_handle);
hpsb_unregister_highlevel(&raw1394_highlevel);
}
module_init(init_raw1394);
......
......@@ -298,7 +298,7 @@
#include "sbp2.h"
static char version[] __devinitdata =
"$Rev: 896 $ James Goodwin <jamesg@filanet.com>";
"$Rev: 912 $ James Goodwin <jamesg@filanet.com>";
/*
* Module load parameter definitions
......@@ -311,15 +311,10 @@ static char version[] __devinitdata =
* NOTE: On certain OHCI parts I have seen short packets on async transmit
* (probably due to PCI latency/throughput issues with the part). You can
* bump down the speed if you are running into problems.
*
* Valid values:
* max_speed = 2 (default: max speed 400mb)
* max_speed = 1 (max speed 200mb)
* max_speed = 0 (max speed 100mb)
*/
static int max_speed = SPEED_400;
static int max_speed = SPEED_MAX;
module_param(max_speed, int, 0644);
MODULE_PARM_DESC(max_speed, "Force max speed (2 = 400mb default, 1 = 200mb, 0 = 100mb)");
MODULE_PARM_DESC(max_speed, "Force max speed (3 = 800mb, 2 = 400mb default, 1 = 200mb, 0 = 100mb)");
/*
* Set serialize_io to 1 if you'd like only one scsi command sent
......@@ -454,11 +449,8 @@ static void sbp2scsi_complete_command(struct scsi_id_instance_data *scsi_id,
static Scsi_Host_Template scsi_driver_template;
static u8 sbp2_speedto_maxrec[] = { 0x7, 0x8, 0x9 };
static struct hpsb_highlevel *sbp2_hl_handle = NULL;
static struct hpsb_highlevel_ops sbp2_hl_ops = {
static struct hpsb_highlevel sbp2_highlevel = {
.name = SBP2_DEVICE_NAME,
.remove_host = sbp2_remove_host,
};
......@@ -774,21 +766,22 @@ static struct sbp2_command_info *sbp2util_allocate_command_orb(
/* Free our DMA's */
static void sbp2util_free_command_dma(struct sbp2_command_info *command)
{
struct sbp2scsi_host_info *hi;
struct hpsb_host *host;
hi = hpsb_get_hostinfo_bykey(sbp2_hl_handle, (unsigned long)command->Current_SCpnt->device->host);
if (!hi) {
printk(KERN_ERR "%s: hi == NULL\n", __FUNCTION__);
host = hpsb_get_host_bykey(&sbp2_highlevel,
(unsigned long)command->Current_SCpnt->device->host);
if (!host) {
printk(KERN_ERR "%s: host == NULL\n", __FUNCTION__);
return;
}
if (command->cmd_dma) {
if (command->dma_type == CMD_DMA_SINGLE) {
pci_unmap_single(hi->host->pdev, command->cmd_dma,
pci_unmap_single(host->pdev, command->cmd_dma,
command->dma_size, command->dma_dir);
SBP2_DMA_FREE("single bulk");
} else if (command->dma_type == CMD_DMA_PAGE) {
pci_unmap_page(hi->host->pdev, command->cmd_dma,
pci_unmap_page(host->pdev, command->cmd_dma,
command->dma_size, command->dma_dir);
SBP2_DMA_FREE("single page");
} /* XXX: Check for CMD_DMA_NONE bug */
......@@ -797,7 +790,7 @@ static void sbp2util_free_command_dma(struct sbp2_command_info *command)
}
if (command->sge_buffer) {
pci_unmap_sg(hi->host->pdev, command->sge_buffer,
pci_unmap_sg(host->pdev, command->sge_buffer,
command->dma_size, command->dma_dir);
SBP2_DMA_FREE("scatter list");
command->sge_buffer = NULL;
......@@ -910,7 +903,7 @@ static struct sbp2scsi_host_info *sbp2_add_host(struct hpsb_host *host)
SBP2_DEBUG("sbp2_add_host");
hi = hpsb_get_hostinfo(sbp2_hl_handle, host);
hi = hpsb_get_hostinfo(&sbp2_highlevel, host);
if (hi)
return hi;
......@@ -921,13 +914,13 @@ static struct sbp2scsi_host_info *sbp2_add_host(struct hpsb_host *host)
return NULL;
}
hi = hpsb_create_hostinfo(sbp2_hl_handle, host, sizeof(*hi));
hi = hpsb_create_hostinfo(&sbp2_highlevel, host, sizeof(*hi));
if (!hi) {
SBP2_ERR("failed to allocate hostinfo");
scsi_unregister(hi->scsi_host);
}
hpsb_set_hostinfo_key(sbp2_hl_handle, host, (unsigned long)scsi_host);
hpsb_set_hostinfo_key(&sbp2_highlevel, host, (unsigned long)scsi_host);
hi->scsi_host = scsi_host;
hi->host = host;
......@@ -941,7 +934,7 @@ static struct sbp2scsi_host_info *sbp2_add_host(struct hpsb_host *host)
if (scsi_add_host(hi->scsi_host, NULL)) {
SBP2_ERR("failed to add scsi host");
scsi_unregister(hi->scsi_host);
hpsb_destroy_hostinfo(sbp2_hl_handle, host);
hpsb_destroy_hostinfo(&sbp2_highlevel, host);
}
return hi;
......@@ -957,13 +950,12 @@ static void sbp2_remove_host(struct hpsb_host *host)
SBP2_DEBUG("sbp2_remove_host");
hi = hpsb_get_hostinfo(sbp2_hl_handle, host);
hi = hpsb_get_hostinfo(&sbp2_highlevel, host);
if (hi) {
scsi_remove_host(hi->scsi_host);
scsi_unregister(hi->scsi_host);
} else
SBP2_ERR("attempt to remove unknown host %p", host);
}
}
/*
......@@ -1092,7 +1084,7 @@ static int sbp2_start_device(struct sbp2scsi_host_info *hi, struct unit_director
scsi_id->ne = ne;
scsi_id->ud = ud;
scsi_id->speed_code = SPEED_100;
scsi_id->max_payload_size = sbp2_speedto_maxrec[SPEED_100];
scsi_id->max_payload_size = hpsb_speedto_maxrec[SPEED_100];
ud->device.driver_data = scsi_id;
atomic_set(&scsi_id->sbp2_login_complete, 0);
......@@ -1854,7 +1846,7 @@ static int sbp2_max_speed_and_size(struct scsi_id_instance_data *scsi_id)
/* Payload size is the lesser of what our speed supports and what
* our host supports. */
scsi_id->max_payload_size = min(sbp2_speedto_maxrec[scsi_id->speed_code],
scsi_id->max_payload_size = min(hpsb_speedto_maxrec[scsi_id->speed_code],
(u8)(((be32_to_cpu(hi->host->csr.rom[2]) >> 12) & 0xf) - 1));
SBP2_ERR("Node[" NODE_BUS_FMT "]: Max speed [%s] - Max payload [%u]",
......@@ -2565,7 +2557,7 @@ static int sbp2_handle_status_write(struct hpsb_host *host, int nodeid, int dest
return(RCODE_ADDRESS_ERROR);
}
hi = hpsb_get_hostinfo(sbp2_hl_handle, host);
hi = hpsb_get_hostinfo(&sbp2_highlevel, host);
if (!hi) {
SBP2_ERR("host info is NULL - this is bad!");
......@@ -2712,7 +2704,7 @@ static int sbp2scsi_queuecommand (Scsi_Cmnd *SCpnt, void (*done)(Scsi_Cmnd *))
/*
* Pull our host info and scsi id instance data from the scsi command
*/
hi = hpsb_get_hostinfo_bykey(sbp2_hl_handle, (unsigned long)SCpnt->device->host);
hi = hpsb_get_hostinfo_bykey(&sbp2_highlevel, (unsigned long)SCpnt->device->host);
if (!hi) {
SBP2_ERR("sbp2scsi_host_info is NULL - this is bad!");
......@@ -2941,7 +2933,7 @@ static void sbp2scsi_complete_command(struct scsi_id_instance_data *scsi_id,
*/
static int sbp2scsi_abort (Scsi_Cmnd *SCpnt)
{
struct sbp2scsi_host_info *hi = hpsb_get_hostinfo_bykey(sbp2_hl_handle,
struct sbp2scsi_host_info *hi = hpsb_get_hostinfo_bykey(&sbp2_highlevel,
(unsigned long)SCpnt->device->host);
struct scsi_id_instance_data *scsi_id = hi->scsi_id[SCpnt->device->id];
struct sbp2_command_info *command;
......@@ -2992,7 +2984,7 @@ static int sbp2scsi_abort (Scsi_Cmnd *SCpnt)
*/
static int sbp2scsi_reset (Scsi_Cmnd *SCpnt)
{
struct sbp2scsi_host_info *hi = hpsb_get_hostinfo_bykey(sbp2_hl_handle,
struct sbp2scsi_host_info *hi = hpsb_get_hostinfo_bykey(&sbp2_highlevel,
(unsigned long)SCpnt->device->host);
struct scsi_id_instance_data *scsi_id = hi->scsi_id[SCpnt->device->id];
......@@ -3019,24 +3011,24 @@ static int sbp2scsi_proc_info(char *buffer, char **start, off_t offset,
int length, int hostno, int inout)
{
Scsi_Device *scd;
struct Scsi_Host *host;
struct sbp2scsi_host_info *hi;
struct Scsi_Host *scsi_host;
struct hpsb_host *host;
char *pos = buffer;
/* if someone is sending us data, just throw it away */
if (inout)
return length;
host = scsi_host_hn_get(hostno);
if (!host) /* if we couldn't find it, we return an error */
scsi_host = scsi_host_hn_get(hostno);
if (!scsi_host) /* if we couldn't find it, we return an error */
return -ESRCH;
hi = hpsb_get_hostinfo_bykey(sbp2_hl_handle, (unsigned long)host);
if (!hi) /* shouldn't happen, but... */
host = hpsb_get_host_bykey(&sbp2_highlevel, (unsigned long)scsi_host);
if (!host) /* shouldn't happen, but... */
return -ESRCH;
SPRINTF("Host scsi%d : SBP-2 IEEE-1394 (%s)\n", hostno,
hi->host->driver->name);
host->driver->name);
SPRINTF("Driver version : %s\n", version);
SPRINTF("\nModule options :\n");
......@@ -3045,10 +3037,10 @@ static int sbp2scsi_proc_info(char *buffer, char **start, off_t offset,
SPRINTF(" serialize_io : %s\n", serialize_io ? "yes" : "no");
SPRINTF(" exclusive_login : %s\n", exclusive_login ? "yes" : "no");
SPRINTF("\nAttached devices : %s\n", !list_empty(&host->my_devices) ?
SPRINTF("\nAttached devices : %s\n", !list_empty(&scsi_host->my_devices) ?
"" : "none");
list_for_each_entry (scd, &host->my_devices, siblings) {
list_for_each_entry (scd, &scsi_host->my_devices, siblings) {
int i;
SPRINTF(" [Channel: %02d, Id: %02d, Lun: %02d] ", scd->channel,
......@@ -3070,7 +3062,7 @@ static int sbp2scsi_proc_info(char *buffer, char **start, off_t offset,
SPRINTF("\n");
/* release the reference count on this host */
scsi_host_put(host);
scsi_host_put(scsi_host);
/* Calculate start of next buffer, and return value. */
*start = buffer + offset;
......@@ -3112,49 +3104,33 @@ static int sbp2_module_init(void)
{
SBP2_DEBUG("sbp2_module_init");
/* Module load debug option to force one command at a time
* (serializing I/O) */
/* Module load debug option to force one command at a time (serializing I/O) */
if (serialize_io) {
SBP2_ERR("Driver forced to serialize I/O (serialize_io = 1)");
scsi_driver_template.can_queue = 1;
scsi_driver_template.cmd_per_lun = 1;
}
/*
* Set max sectors (module load option). Default is 255 sectors.
*/
/* Set max sectors (module load option). Default is 255 sectors. */
scsi_driver_template.max_sectors = max_sectors;
/*
* Register our high level driver with 1394 stack
*/
sbp2_hl_handle = hpsb_register_highlevel(SBP2_DEVICE_NAME,
&sbp2_hl_ops);
if (!sbp2_hl_handle) {
SBP2_ERR("sbp2 failed to register with ieee1394 highlevel");
return(-ENOMEM);
}
/* Register our high level driver with 1394 stack */
hpsb_register_highlevel(&sbp2_highlevel);
/*
* Register our sbp2 status address space...
*/
hpsb_register_addrspace(sbp2_hl_handle, &sbp2_ops,
SBP2_STATUS_FIFO_ADDRESS,
/* 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));
SBP2_STATUS_FIFO_ENTRY_TO_OFFSET(SBP2SCSI_MAX_SCSI_IDS+1));
/*
* Handle data movement if physical dma is not enabled/supported
* on host controller
*/
/* Handle data movement if physical dma is not enabled/supported
* on host controller */
#ifdef CONFIG_IEEE1394_SBP2_PHYS_DMA
hpsb_register_addrspace(sbp2_hl_handle, &sbp2_physdma_ops,
0x0ULL, 0xfffffffcULL);
hpsb_register_addrspace(&sbp2_highlevel, &sbp2_physdma_ops, 0x0ULL, 0xfffffffcULL);
#endif
hpsb_register_protocol(&sbp2_driver);
return 0;
}
......@@ -3163,8 +3139,8 @@ static void __exit sbp2_module_exit(void)
SBP2_DEBUG("sbp2_module_exit");
hpsb_unregister_protocol(&sbp2_driver);
if (sbp2_hl_handle)
hpsb_unregister_highlevel(sbp2_hl_handle);
hpsb_unregister_highlevel(&sbp2_highlevel);
}
module_init(sbp2_module_init);
......
......@@ -146,8 +146,7 @@ printk(level "video1394_%d: " fmt "\n" , card , ## args)
void wakeup_dma_ir_ctx(unsigned long l);
void wakeup_dma_it_ctx(unsigned long l);
static struct hpsb_highlevel *hl_handle = NULL;
static struct hpsb_highlevel video1394_highlevel;
static int free_dma_iso_ctx(struct dma_iso_ctx *d)
{
......@@ -1151,7 +1150,7 @@ static int video1394_open(struct inode *inode, struct file *file)
struct ti_ohci *ohci;
struct file_ctx *ctx;
ohci = hpsb_get_hostinfo_bykey(hl_handle, i);
ohci = hpsb_get_hostinfo_bykey(&video1394_highlevel, i);
if (ohci == NULL)
return -EIO;
......@@ -1236,7 +1235,7 @@ static struct hpsb_protocol_driver video1394_driver = {
};
static void video1394_add_host (struct hpsb_host *host, struct hpsb_highlevel *hl)
static void video1394_add_host (struct hpsb_host *host)
{
struct ti_ohci *ohci;
char name[16];
......@@ -1248,13 +1247,13 @@ static void video1394_add_host (struct hpsb_host *host, struct hpsb_highlevel *h
ohci = (struct ti_ohci *)host->hostdata;
if (!hpsb_create_hostinfo(hl, host, 0)) {
if (!hpsb_create_hostinfo(&video1394_highlevel, host, 0)) {
PRINT(KERN_ERR, ohci->id, "Cannot allocate hostinfo");
return;
}
hpsb_set_hostinfo(hl, host, ohci);
hpsb_set_hostinfo_key(hl, host, ohci->id);
hpsb_set_hostinfo(&video1394_highlevel, host, ohci);
hpsb_set_hostinfo_key(&video1394_highlevel, host, ohci->id);
sprintf(name, "%s/%d", VIDEO1394_DRIVER_NAME, ohci->id);
minor = IEEE1394_MINOR_BLOCK_VIDEO1394 * 16 + ohci->id;
......@@ -1267,7 +1266,7 @@ static void video1394_add_host (struct hpsb_host *host, struct hpsb_highlevel *h
static void video1394_remove_host (struct hpsb_host *host)
{
struct ti_ohci *ohci = hpsb_get_hostinfo(hl_handle, host);
struct ti_ohci *ohci = hpsb_get_hostinfo(&video1394_highlevel, host);
if (ohci)
devfs_remove("%s/%d", VIDEO1394_DRIVER_NAME, ohci->id);
......@@ -1276,7 +1275,8 @@ static void video1394_remove_host (struct hpsb_host *host)
}
static struct hpsb_highlevel_ops hl_ops = {
static struct hpsb_highlevel video1394_highlevel = {
.name = VIDEO1394_DRIVER_NAME,
.add_host = video1394_add_host,
.remove_host = video1394_remove_host,
};
......@@ -1415,7 +1415,7 @@ static void __exit video1394_exit_module (void)
hpsb_unregister_protocol(&video1394_driver);
hpsb_unregister_highlevel (hl_handle);
hpsb_unregister_highlevel(&video1394_highlevel);
devfs_remove(VIDEO1394_DRIVER_NAME);
ieee1394_unregister_chardev(IEEE1394_MINOR_BLOCK_VIDEO1394);
......@@ -1436,13 +1436,7 @@ static int __init video1394_init_module (void)
devfs_mk_dir(VIDEO1394_DRIVER_NAME);
hl_handle = hpsb_register_highlevel (VIDEO1394_DRIVER_NAME, &hl_ops);
if (hl_handle == NULL) {
PRINT_G(KERN_ERR, "No more memory for driver\n");
devfs_remove(VIDEO1394_DRIVER_NAME);
ieee1394_unregister_chardev(IEEE1394_MINOR_BLOCK_VIDEO1394);
return -ENOMEM;
}
hpsb_register_highlevel(&video1394_highlevel);
hpsb_register_protocol(&video1394_driver);
......
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