Commit bd3895ad authored by Ben Collins's avatar Ben Collins

IEEE1394(r1172): Generalize the default config rom entries for new hosts.

parent b066237f
......@@ -47,6 +47,23 @@ config IEEE1394_OUI_DB
This option is not needed for userspace programs like gscanbus
to show this information.
config IEEE1394_EXTRA_CONFIG_ROMS
bool "Build in extra config rom entries for certain functionality"
depends on IEEE1394
help
Some IEEE1394 functionality depends on extra config rom entries
being available in the host adapters CSR. These options will
allow you to choose which ones.
config IEEE1394_CONFIG_ROM_IP1394
bool "IP-1394 Entry"
depends on IEEE1394_EXTRA_CONFIG_ROMS && IEEE1394
help
Adds an entry for using IP-over-1394. If you want to use your
IEEE1394 bus as a network for IP systems (including interacting
with MacOSX and WinXP IP-over-1394), enable this option and the
eth1394 option below.
comment "Device Drivers"
depends on IEEE1394
......@@ -108,6 +125,8 @@ config IEEE1394_SBP2_PHYS_DMA
config IEEE1394_ETH1394
tristate "Ethernet over 1394"
depends on IEEE1394 && EXPERIMENTAL
select IEEE1394_CONFIG_ROM_IP1394
select IEEE1394_EXTRA_CONFIG_ROMS
help
This driver implements a functional majority of RFC 2734: IPv4 over
1394. It will provide IP connectivity with implementations of RFC
......
......@@ -4,7 +4,7 @@
ieee1394-objs := ieee1394_core.o ieee1394_transactions.o hosts.o \
highlevel.o csr.o nodemgr.o oui.o dma.o iso.o \
csr1212.o
csr1212.o config_roms.o
obj-$(CONFIG_IEEE1394) += ieee1394.o
obj-$(CONFIG_IEEE1394_PCILYNX) += pcilynx.o
......
/*
* IEEE 1394 for Linux
*
* ConfigROM entries
*
* Copyright (C) 2004 Ben Collins
*
* This code is licensed under the GPL. See the file COPYING in the root
* directory of the kernel sources for details.
*/
#include <linux/config.h>
#include <linux/types.h>
#include "csr1212.h"
#include "ieee1394.h"
#include "ieee1394_types.h"
#include "hosts.h"
#include "ieee1394_core.h"
#include "highlevel.h"
#include "csr.h"
#include "config_roms.h"
struct hpsb_config_rom_entry {
const char *name;
/* Base initialization, called at module load */
int (*init)(void);
/* Add entry to specified host */
int (*add)(struct hpsb_host *host);
/* Remove entry from specified host */
void (*remove)(struct hpsb_host *host);
/* Cleanup called at module exit */
void (*cleanup)(void);
/* The flag added to host->config_roms */
unsigned int flag;
};
int hpsb_default_host_entry(struct hpsb_host *host)
{
struct csr1212_keyval *root;
struct csr1212_keyval *vend_id = NULL;
struct csr1212_keyval *text = NULL;
char csr_name[128];
int ret;
sprintf(csr_name, "Linux - %s", host->driver->name);
root = host->csr.rom->root_kv;
vend_id = csr1212_new_immediate(CSR1212_KV_ID_VENDOR, host->csr.guid_hi >> 8);
text = csr1212_new_string_descriptor_leaf(csr_name);
if (!vend_id || !text) {
if (vend_id)
csr1212_release_keyval(vend_id);
if (text)
csr1212_release_keyval(text);
csr1212_destroy_csr(host->csr.rom);
return -ENOMEM;
}
ret = csr1212_associate_keyval(vend_id, text);
csr1212_release_keyval(text);
ret |= csr1212_attach_keyval_to_directory(root, vend_id);
if (ret != CSR1212_SUCCESS) {
csr1212_release_keyval(vend_id);
csr1212_destroy_csr(host->csr.rom);
return -ENOMEM;
}
host->update_config_rom = 1;
return 0;
}
#ifdef CONFIG_IEEE1394_CONFIG_ROM_IP1394
#include "eth1394.h"
static struct csr1212_keyval *ip1394_ud;
static int config_rom_ip1394_init(void)
{
struct csr1212_keyval *spec_id = NULL;
struct csr1212_keyval *spec_desc = NULL;
struct csr1212_keyval *ver = NULL;
struct csr1212_keyval *ver_desc = NULL;
int ret = -ENOMEM;
ip1394_ud = csr1212_new_directory(CSR1212_KV_ID_UNIT);
spec_id = csr1212_new_immediate(CSR1212_KV_ID_SPECIFIER_ID,
ETHER1394_GASP_SPECIFIER_ID);
spec_desc = csr1212_new_string_descriptor_leaf("IANA");
ver = csr1212_new_immediate(CSR1212_KV_ID_VERSION,
ETHER1394_GASP_VERSION);
ver_desc = csr1212_new_string_descriptor_leaf("IPv4");
if (!ip1394_ud || !spec_id || !spec_desc || !ver || !ver_desc)
goto ip1394_fail;
if (csr1212_associate_keyval(spec_id, spec_desc) == CSR1212_SUCCESS &&
csr1212_associate_keyval(ver, ver_desc) == CSR1212_SUCCESS &&
csr1212_attach_keyval_to_directory(ip1394_ud, spec_id) == CSR1212_SUCCESS &&
csr1212_attach_keyval_to_directory(ip1394_ud, ver) == CSR1212_SUCCESS)
ret = 0;
ip1394_fail:
if (ret && ip1394_ud) {
csr1212_release_keyval(ip1394_ud);
ip1394_ud = NULL;
}
if (spec_id)
csr1212_release_keyval(spec_id);
if (spec_desc)
csr1212_release_keyval(spec_desc);
if (ver)
csr1212_release_keyval(ver);
if (ver_desc)
csr1212_release_keyval(ver_desc);
return ret;
}
static void config_rom_ip1394_cleanup(void)
{
if (ip1394_ud) {
csr1212_release_keyval(ip1394_ud);
ip1394_ud = NULL;
}
}
static int config_rom_ip1394_add(struct hpsb_host *host)
{
if (!ip1394_ud)
return -ENODEV;
if (csr1212_attach_keyval_to_directory(host->csr.rom->root_kv,
ip1394_ud) != CSR1212_SUCCESS)
return -ENOMEM;
return 0;
}
static void config_rom_ip1394_remove(struct hpsb_host *host)
{
csr1212_detach_keyval_from_directory(host->csr.rom->root_kv, ip1394_ud);
}
static struct hpsb_config_rom_entry ip1394_entry = {
.name = "ip1394",
.init = config_rom_ip1394_init,
.add = config_rom_ip1394_add,
.remove = config_rom_ip1394_remove,
.cleanup = config_rom_ip1394_cleanup,
.flag = HPSB_CONFIG_ROM_ENTRY_IP1394,
};
#endif /* CONFIG_IEEE1394_CONFIG_ROM_IP1394 */
static struct hpsb_config_rom_entry *const config_rom_entries[] = {
#ifdef CONFIG_IEEE1394_CONFIG_ROM_IP1394
&ip1394_entry,
#endif
NULL,
};
int hpsb_init_config_roms(void)
{
int i, error = 0;
for (i = 0; config_rom_entries[i]; i++) {
if (!config_rom_entries[i]->init)
continue;
if (config_rom_entries[i]->init()) {
HPSB_ERR("Failed to initialize config rom entry `%s'",
config_rom_entries[i]->name);
error = -1;
} else
HPSB_DEBUG("Initialized config rom entry `%s'",
config_rom_entries[i]->name);
}
return error;
}
void hpsb_cleanup_config_roms(void)
{
int i;
for (i = 0; config_rom_entries[i]; i++) {
if (config_rom_entries[i]->cleanup)
config_rom_entries[i]->cleanup();
}
}
int hpsb_add_extra_config_roms(struct hpsb_host *host)
{
int i, error = 0;
for (i = 0; config_rom_entries[i]; i++) {
if (config_rom_entries[i]->add(host)) {
HPSB_ERR("fw-host%d: Failed to attach config rom entry `%s'",
host->id, config_rom_entries[i]->name);
error = -1;
} else {
host->config_roms |= config_rom_entries[i]->flag;
host->update_config_rom = 1;
}
}
return error;
}
void hpsb_remove_extra_config_roms(struct hpsb_host *host)
{
int i;
for (i = 0; config_rom_entries[i]; i++) {
if (!(host->config_roms & config_rom_entries[i]->flag))
continue;
config_rom_entries[i]->remove(host);
host->config_roms &= ~config_rom_entries[i]->flag;
host->update_config_rom = 1;
}
}
#ifndef _IEEE1394_CONFIG_ROMS_H
#define _IEEE1394_CONFIG_ROMS_H
#include "ieee1394_types.h"
#include "hosts.h"
/* The default host entry. This must succeed. */
int hpsb_default_host_entry(struct hpsb_host *host);
/* Initialize all config roms */
int hpsb_init_config_roms(void);
/* Cleanup all config roms */
void hpsb_cleanup_config_roms(void);
/* Add extra config roms to specified host */
int hpsb_add_extra_config_roms(struct hpsb_host *host);
/* Remove extra config roms from specified host */
void hpsb_remove_extra_config_roms(struct hpsb_host *host);
/* List of flags to check if a host contains a certain extra config rom
* entry. Available in the host->config_roms member. */
#define HPSB_CONFIG_ROM_ENTRY_IP1394 0x00000001
#endif /* _IEEE1394_CONFIG_ROMS_H */
......@@ -76,6 +76,7 @@
#include "iso.h"
#include "nodemgr.h"
#include "eth1394.h"
#include "config_roms.h"
#define ETH1394_PRINT_G(level, fmt, args...) \
printk(level "%s: " fmt, driver_name, ## args)
......@@ -106,8 +107,6 @@ struct partial_datagram {
struct list_head frag_info;
};
static struct csr1212_keyval *eth1394_ud = NULL;
struct pdg_list {
struct list_head list; /* partial datagram list per node */
unsigned int sz; /* partial datagram list size per node */
......@@ -553,9 +552,11 @@ static void ether1394_add_host (struct hpsb_host *host)
struct net_device *dev = NULL;
struct eth1394_priv *priv;
static int version_printed = 0;
u64 fifo_addr;
if (!(host->config_roms & HPSB_CONFIG_ROM_ENTRY_IP1394))
return;
fifo_addr = hpsb_allocate_and_register_addrspace(&eth1394_highlevel,
host,
&addr_ops,
......@@ -634,14 +635,6 @@ static void ether1394_add_host (struct hpsb_host *host)
priv->bc_state = ETHER1394_BC_RUNNING;
}
if (csr1212_attach_keyval_to_directory(host->csr.rom->root_kv,
eth1394_ud) != CSR1212_SUCCESS) {
ETH1394_PRINT (KERN_ERR, dev->name,
"Cannot attach IP 1394 Unit Directory to "
"Config ROM\n");
goto out;
}
hi->host->update_config_rom = 1;
return;
out:
......@@ -668,10 +661,6 @@ static void ether1394_remove_host (struct hpsb_host *host)
if (priv->iso != NULL)
hpsb_iso_shutdown(priv->iso);
csr1212_detach_keyval_from_directory(hi->host->csr.rom->root_kv,
eth1394_ud);
hi->host->update_config_rom = 1;
if (hi->dev) {
unregister_netdev (hi->dev);
free_netdev(hi->dev);
......@@ -1829,67 +1818,13 @@ static int ether1394_ethtool_ioctl(struct net_device *dev, void *useraddr)
static int __init ether1394_init_module (void)
{
int ret;
struct csr1212_keyval *spec_id = NULL;
struct csr1212_keyval *spec_desc = NULL;
struct csr1212_keyval *ver = NULL;
struct csr1212_keyval *ver_desc = NULL;
packet_task_cache = kmem_cache_create("packet_task", sizeof(struct packet_task),
0, 0, NULL, NULL);
eth1394_ud = csr1212_new_directory(CSR1212_KV_ID_UNIT);
spec_id = csr1212_new_immediate(CSR1212_KV_ID_SPECIFIER_ID,
ETHER1394_GASP_SPECIFIER_ID);
spec_desc = csr1212_new_string_descriptor_leaf("IANA");
ver = csr1212_new_immediate(CSR1212_KV_ID_VERSION,
ETHER1394_GASP_VERSION);
ver_desc = csr1212_new_string_descriptor_leaf("IPv4");
if ((!eth1394_ud) ||
(!spec_id) ||
(!spec_desc) ||
(!ver) ||
(!ver_desc)) {
ret = -ENOMEM;
goto out;
}
ret = csr1212_associate_keyval(spec_id, spec_desc);
if (ret != CSR1212_SUCCESS)
goto out;
ret = csr1212_associate_keyval(ver, ver_desc);
if (ret != CSR1212_SUCCESS)
goto out;
ret = csr1212_attach_keyval_to_directory(eth1394_ud, spec_id);
if (ret != CSR1212_SUCCESS)
goto out;
ret = csr1212_attach_keyval_to_directory(eth1394_ud, ver);
if (ret != CSR1212_SUCCESS)
goto out;
/* Register ourselves as a highlevel driver */
hpsb_register_highlevel(&eth1394_highlevel);
ret = hpsb_register_protocol(&eth1394_proto_driver);
out:
if ((ret != 0) && eth1394_ud) {
csr1212_release_keyval(eth1394_ud);
}
if (spec_id)
csr1212_release_keyval(spec_id);
if (spec_desc)
csr1212_release_keyval(spec_desc);
if (ver)
csr1212_release_keyval(ver);
if (ver_desc)
csr1212_release_keyval(ver_desc);
return ret;
return hpsb_register_protocol(&eth1394_proto_driver);
}
static void __exit ether1394_exit_module (void)
......@@ -1897,10 +1832,6 @@ static void __exit ether1394_exit_module (void)
hpsb_unregister_protocol(&eth1394_proto_driver);
hpsb_unregister_highlevel(&eth1394_highlevel);
kmem_cache_destroy(packet_task_cache);
if (eth1394_ud) {
csr1212_release_keyval(eth1394_ud);
}
}
module_init(ether1394_init_module);
......
......@@ -24,6 +24,8 @@
#ifndef __ETH1394_H
#define __ETH1394_H
#include <linux/netdevice.h>
#include "ieee1394.h"
/* Register for incoming packets. This is 4096 bytes, which supports up to
......
......@@ -27,6 +27,7 @@
#include "highlevel.h"
#include "nodemgr.h"
#include "csr.h"
#include "config_roms.h"
static void delayed_reset_bus(unsigned long __reset_info)
......@@ -173,9 +174,16 @@ struct hpsb_host *hpsb_alloc_host(struct hpsb_host_driver *drv, size_t extra,
return h;
}
void hpsb_add_host(struct hpsb_host *host)
int hpsb_add_host(struct hpsb_host *host)
{
highlevel_add_host(host);
if (hpsb_default_host_entry(host))
return -ENOMEM;
hpsb_add_extra_config_roms(host);
highlevel_add_host(host);
return 0;
}
void hpsb_remove_host(struct hpsb_host *host)
......@@ -185,6 +193,8 @@ void hpsb_remove_host(struct hpsb_host *host)
highlevel_remove_host(host);
hpsb_remove_extra_config_roms(host);
class_device_unregister(&host->class_dev);
device_unregister(&host->device);
}
......
......@@ -66,6 +66,8 @@ struct hpsb_host {
int update_config_rom;
struct timer_list delayed_reset;
unsigned int config_roms;
struct list_head addr_space;
};
......@@ -191,7 +193,7 @@ struct hpsb_host_driver {
struct hpsb_host *hpsb_alloc_host(struct hpsb_host_driver *drv, size_t extra,
struct device *dev);
void hpsb_add_host(struct hpsb_host *host);
int hpsb_add_host(struct hpsb_host *host);
void hpsb_remove_host(struct hpsb_host *h);
/* The following 2 functions are deprecated and will be removed when the
......
......@@ -45,6 +45,7 @@
#include "nodemgr.h"
#include "dma.h"
#include "iso.h"
#include "config_roms.h"
/*
* Disable the nodemgr detection and config rom reading functionality.
......@@ -1052,6 +1053,11 @@ static int __init ieee1394_init(void)
{
int i;
if (hpsb_init_config_roms()) {
HPSB_ERR("Failed to initialize some config rom entries.\n");
HPSB_ERR("Some features may not be available\n");
}
khpsbpkt_pid = kernel_thread(hpsbpkt_thread, NULL, CLONE_KERNEL);
if (khpsbpkt_pid < 0) {
HPSB_ERR("Failed to start hpsbpkt thread!\n");
......@@ -1115,6 +1121,8 @@ static void __exit ieee1394_cleanup(void)
mempool_destroy(hpsb_packet_mempool);
kmem_cache_destroy(hpsb_packet_cache);
hpsb_cleanup_config_roms();
unregister_chrdev_region(IEEE1394_CORE_DEV, 256);
devfs_remove("ieee1394");
}
......
......@@ -3153,11 +3153,6 @@ do { \
static int __devinit ohci1394_pci_probe(struct pci_dev *dev,
const struct pci_device_id *ent)
{
struct csr1212_keyval *root;
struct csr1212_keyval *vend_id = NULL;
struct csr1212_keyval *text = NULL;
int ret;
static int version_printed = 0;
struct hpsb_host *host;
......@@ -3342,38 +3337,6 @@ static int __devinit ohci1394_pci_probe(struct pci_dev *dev,
ohci->init_state = OHCI_INIT_HAVE_IRQ;
ohci_initialize(ohci);
/* Setup initial root directory entries */
root = host->csr.rom->root_kv;
vend_id = csr1212_new_immediate(CSR1212_KV_ID_VENDOR,
reg_read(ohci, OHCI1394_GUIDHi) >> 8);
text = csr1212_new_string_descriptor_leaf("Linux 1394 - OHCI");
if (!vend_id || !text) {
if (vend_id) {
csr1212_release_keyval(vend_id);
}
if (text) {
csr1212_release_keyval(text);
}
FAIL(-ENOMEM, "Failed to allocate memory for mandatory ConfigROM entries!");
}
ret = csr1212_associate_keyval(vend_id, text);
csr1212_release_keyval(text);
if(ret != CSR1212_SUCCESS) {
csr1212_release_keyval(vend_id);
FAIL(ret, "Failed to associate text descriptor to vendor id");
}
ret = csr1212_attach_keyval_to_directory(root, vend_id);
if(ret != CSR1212_SUCCESS) {
csr1212_release_keyval(vend_id);
FAIL(ret, "Failed to attach vendor id to root directory");
}
host->update_config_rom = 1;
/* Set certain csr values */
host->csr.guid_hi = reg_read(ohci, OHCI1394_GUIDHi);
host->csr.guid_lo = reg_read(ohci, OHCI1394_GUIDLo);
......@@ -3382,7 +3345,9 @@ static int __devinit ohci1394_pci_probe(struct pci_dev *dev,
host->csr.lnk_spd = reg_read(ohci, OHCI1394_BusOptions) & 0x7;
/* Tell the highlevel this host is ready */
hpsb_add_host(host);
if (hpsb_add_host(host))
FAIL(-ENOMEM, "Failed to register host with highlevel");
ohci->init_state = OHCI_INIT_DONE;
return 0;
......
......@@ -1516,11 +1516,6 @@ static int __devinit add_card(struct pci_dev *dev,
return error; \
} while (0)
struct csr1212_keyval *root;
struct csr1212_keyval *vend_id = NULL;
struct csr1212_keyval *text = NULL;
int ret;
char irq_buf[16];
struct hpsb_host *host;
struct ti_lynx *lynx; /* shortcut to currently handled device */
......@@ -1890,42 +1885,14 @@ static int __devinit add_card(struct pci_dev *dev,
else
host->csr.lnk_spd = be32_to_cpu(lynx->bus_info_block[2]) & 0x7;
/* Setup initial root directory entries */
root = host->csr.rom->root_kv;
vend_id = csr1212_new_immediate(CSR1212_KV_ID_VENDOR,
be32_to_cpu(lynx->bus_info_block[3]) >> 8);
text = csr1212_new_string_descriptor_leaf("Linux 1394 - PCI-Lynx");
if (!vend_id || !text) {
if (vend_id)
csr1212_release_keyval(vend_id);
if (text)
csr1212_release_keyval(text);
if (hpsb_add_host(host)) {
error = -ENOMEM;
FAIL("Failed to allocate memory for mandatory ConfigROM entries!");
}
ret = csr1212_associate_keyval(vend_id, text);
csr1212_release_keyval(text); /* no longer needed locally. */
if(ret != CSR1212_SUCCESS) {
csr1212_release_keyval(vend_id);
error = ret;
FAIL("Failed to associate text descriptor to vendor id");
}
ret = csr1212_attach_keyval_to_directory(root, vend_id);
csr1212_release_keyval(vend_id); /* no longer needed locally. */
if(ret != CSR1212_SUCCESS) {
error = ret;
FAIL("Failed to attach vendor id to root directory");
FAIL("Failed to register host with highlevel");
}
host->update_config_rom = 1;
hpsb_add_host(host);
lynx->state = is_host;
return ret;
return 0;
#undef FAIL
}
......
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