summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorLinus Torvalds <torvalds@woody.linux-foundation.org>2007-04-30 08:59:57 -0700
committerLinus Torvalds <torvalds@woody.linux-foundation.org>2007-04-30 08:59:57 -0700
commit40caf5ea5a7d47f8a33e26b63ca81dea4b5109d2 (patch)
tree3f879353d5cb69d2dee707108e4aaeae075f5a0c
parentd6454706c382ab74e2ecad7803c434cc6bd30343 (diff)
parentbcfd09ee48f77a4fe903dbc3757e7af931998ce1 (diff)
Merge branch 'for-linus' of git://git.kernel.org/pub/scm/linux/kernel/git/ieee1394/linux1394-2.6
* 'for-linus' of git://git.kernel.org/pub/scm/linux/kernel/git/ieee1394/linux1394-2.6: (56 commits) ieee1394: remove garbage from Kconfig ieee1394: more help in Kconfig ieee1394: ohci1394: Fix mistake in printk message. ieee1394: ohci1394: remove unnecessary rcvPhyPkt bit flipping in LinkControl register ieee1394: ohci1394: fix cosmetic problem in error logging ieee1394: eth1394: send async streams at S100 on 1394b buses ieee1394: eth1394: fix error path in module_init ieee1394: eth1394: correct return codes in hard_start_xmit ieee1394: eth1394: hard_start_xmit is called in atomic context ieee1394: eth1394: some conditions are unlikely ieee1394: eth1394: clean up fragment_overlap ieee1394: eth1394: don't use alloc_etherdev ieee1394: eth1394: omit useless set_mac_address callback ieee1394: eth1394: CONFIG_INET is always defined ieee1394: eth1394: allow MTU bigger than 1500 ieee1394: unexport highlevel_host_reset ieee1394: eth1394: contain host reset ieee1394: eth1394: shorter error messages ieee1394: eth1394: correct a memset argument ieee1394: eth1394: refactor .probe and .update ...
-rw-r--r--drivers/ieee1394/Kconfig52
-rw-r--r--drivers/ieee1394/config_roms.c93
-rw-r--r--drivers/ieee1394/config_roms.h20
-rw-r--r--drivers/ieee1394/csr1212.c870
-rw-r--r--drivers/ieee1394/csr1212.h483
-rw-r--r--drivers/ieee1394/dma.c24
-rw-r--r--drivers/ieee1394/dma.h22
-rw-r--r--drivers/ieee1394/eth1394.c798
-rw-r--r--drivers/ieee1394/eth1394.h25
-rw-r--r--drivers/ieee1394/highlevel.c89
-rw-r--r--drivers/ieee1394/highlevel.h55
-rw-r--r--drivers/ieee1394/hosts.c23
-rw-r--r--drivers/ieee1394/hosts.h10
-rw-r--r--drivers/ieee1394/ieee1394_core.c461
-rw-r--r--drivers/ieee1394/ieee1394_core.h100
-rw-r--r--drivers/ieee1394/ieee1394_transactions.c43
-rw-r--r--drivers/ieee1394/ieee1394_transactions.h20
-rw-r--r--drivers/ieee1394/iso.c85
-rw-r--r--drivers/ieee1394/iso.h35
-rw-r--r--drivers/ieee1394/nodemgr.c61
-rw-r--r--drivers/ieee1394/nodemgr.h24
-rw-r--r--drivers/ieee1394/ohci1394.c12
-rw-r--r--drivers/ieee1394/ohci1394.h4
-rw-r--r--drivers/ieee1394/raw1394.c3
-rw-r--r--drivers/ieee1394/sbp2.c39
-rw-r--r--drivers/ieee1394/sbp2.h8
26 files changed, 1446 insertions, 2013 deletions
diff --git a/drivers/ieee1394/Kconfig b/drivers/ieee1394/Kconfig
index cd84a55ecf20..61d7809a5a26 100644
--- a/drivers/ieee1394/Kconfig
+++ b/drivers/ieee1394/Kconfig
@@ -1,11 +1,8 @@
-# -*- shell-script -*-
-
menu "IEEE 1394 (FireWire) support"
config IEEE1394
tristate "IEEE 1394 (FireWire) support"
depends on PCI || BROKEN
- select NET
help
IEEE 1394 describes a high performance serial bus, which is also
known as FireWire(tm) or i.Link(tm) and is used for connecting all
@@ -35,24 +32,7 @@ config IEEE1394_VERBOSEDEBUG
Say Y if you really want or need the debugging output, everyone
else says N.
-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"
+comment "Controllers"
depends on IEEE1394
comment "Texas Instruments PCILynx requires I2C"
@@ -70,6 +50,10 @@ config IEEE1394_PCILYNX
To compile this driver as a module, say M here: the
module will be called pcilynx.
+ Only some old and now very rare PCI and CardBus cards and
+ PowerMacs G3 B&W contain the PCILynx controller. Therefore
+ almost everybody can say N here.
+
config IEEE1394_OHCI1394
tristate "OHCI-1394 support"
depends on PCI && IEEE1394
@@ -83,7 +67,7 @@ config IEEE1394_OHCI1394
To compile this driver as a module, say M here: the
module will be called ohci1394.
-comment "Protocol Drivers"
+comment "Protocols"
depends on IEEE1394
config IEEE1394_VIDEO1394
@@ -121,11 +105,15 @@ config IEEE1394_SBP2_PHYS_DMA
This option is buggy and currently broken on some architectures.
If unsure, say N.
+config IEEE1394_ETH1394_ROM_ENTRY
+ depends on IEEE1394
+ bool
+ default n
+
config IEEE1394_ETH1394
- tristate "Ethernet over 1394"
+ tristate "IP over 1394"
depends on IEEE1394 && EXPERIMENTAL && INET
- select IEEE1394_CONFIG_ROM_IP1394
- select IEEE1394_EXTRA_CONFIG_ROMS
+ select IEEE1394_ETH1394_ROM_ENTRY
help
This driver implements a functional majority of RFC 2734: IPv4 over
1394. It will provide IP connectivity with implementations of RFC
@@ -134,6 +122,8 @@ config IEEE1394_ETH1394
This driver is still considered experimental. It does not yet support
MCAP, therefore multicast support is significantly limited.
+ The module is called eth1394 although it does not emulate Ethernet.
+
config IEEE1394_DV1394
tristate "OHCI-DV I/O support (deprecated)"
depends on IEEE1394 && IEEE1394_OHCI1394
@@ -146,12 +136,12 @@ config IEEE1394_RAWIO
tristate "Raw IEEE1394 I/O support"
depends on IEEE1394
help
- Say Y here if you want support for the raw device. This is generally
- a good idea, so you should say Y here. The raw device enables
- direct communication of user programs with the IEEE 1394 bus and
- thus with the attached peripherals.
+ This option adds support for the raw1394 device file which enables
+ direct communication of user programs with the IEEE 1394 bus and thus
+ with the attached peripherals. Almost all application programs which
+ access FireWire require this option.
- To compile this driver as a module, say M here: the
- module will be called raw1394.
+ To compile this driver as a module, say M here: the module will be
+ called raw1394.
endmenu
diff --git a/drivers/ieee1394/config_roms.c b/drivers/ieee1394/config_roms.c
index e2de6fa0c9fe..1b981207fa76 100644
--- a/drivers/ieee1394/config_roms.c
+++ b/drivers/ieee1394/config_roms.c
@@ -26,12 +26,6 @@ struct hpsb_config_rom_entry {
/* 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);
@@ -39,7 +33,7 @@ struct hpsb_config_rom_entry {
unsigned int flag;
};
-
+/* The default host entry. This must succeed. */
int hpsb_default_host_entry(struct hpsb_host *host)
{
struct csr1212_keyval *root;
@@ -63,9 +57,9 @@ int hpsb_default_host_entry(struct hpsb_host *host)
return -ENOMEM;
}
- ret = csr1212_associate_keyval(vend_id, text);
+ csr1212_associate_keyval(vend_id, text);
csr1212_release_keyval(text);
- ret |= csr1212_attach_keyval_to_directory(root, vend_id);
+ ret = csr1212_attach_keyval_to_directory(root, vend_id);
csr1212_release_keyval(vend_id);
if (ret != CSR1212_SUCCESS) {
csr1212_destroy_csr(host->csr.rom);
@@ -78,7 +72,7 @@ int hpsb_default_host_entry(struct hpsb_host *host)
}
-#ifdef CONFIG_IEEE1394_CONFIG_ROM_IP1394
+#ifdef CONFIG_IEEE1394_ETH1394_ROM_ENTRY
#include "eth1394.h"
static struct csr1212_keyval *ip1394_ud;
@@ -103,10 +97,12 @@ static int config_rom_ip1394_init(void)
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)
+ csr1212_associate_keyval(spec_id, spec_desc);
+ csr1212_associate_keyval(ver, ver_desc);
+ if (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:
@@ -135,7 +131,7 @@ static void config_rom_ip1394_cleanup(void)
}
}
-static int config_rom_ip1394_add(struct hpsb_host *host)
+int hpsb_config_rom_ip1394_add(struct hpsb_host *host)
{
if (!ip1394_ud)
return -ENODEV;
@@ -144,92 +140,55 @@ static int config_rom_ip1394_add(struct hpsb_host *host)
ip1394_ud) != CSR1212_SUCCESS)
return -ENOMEM;
+ host->config_roms |= HPSB_CONFIG_ROM_ENTRY_IP1394;
+ host->update_config_rom = 1;
return 0;
}
+EXPORT_SYMBOL_GPL(hpsb_config_rom_ip1394_add);
-static void config_rom_ip1394_remove(struct hpsb_host *host)
+void hpsb_config_rom_ip1394_remove(struct hpsb_host *host)
{
csr1212_detach_keyval_from_directory(host->csr.rom->root_kv, ip1394_ud);
+ host->config_roms &= ~HPSB_CONFIG_ROM_ENTRY_IP1394;
+ host->update_config_rom = 1;
}
+EXPORT_SYMBOL_GPL(hpsb_config_rom_ip1394_remove);
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 */
+#endif /* CONFIG_IEEE1394_ETH1394_ROM_ENTRY */
static struct hpsb_config_rom_entry *const config_rom_entries[] = {
-#ifdef CONFIG_IEEE1394_CONFIG_ROM_IP1394
+#ifdef CONFIG_IEEE1394_ETH1394_ROM_ENTRY
&ip1394_entry,
#endif
- NULL,
};
-
+/* Initialize all config roms */
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;
-
+ for (i = 0; i < ARRAY_SIZE(config_rom_entries); i++)
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)
+/* Cleanup all config roms */
+void hpsb_cleanup_config_roms(void)
{
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;
- }
+ for (i = 0; i < ARRAY_SIZE(config_rom_entries); i++)
+ config_rom_entries[i]->cleanup();
}
diff --git a/drivers/ieee1394/config_roms.h b/drivers/ieee1394/config_roms.h
index 0a70544cfe65..1f5cd1f16c44 100644
--- a/drivers/ieee1394/config_roms.h
+++ b/drivers/ieee1394/config_roms.h
@@ -1,27 +1,19 @@
#ifndef _IEEE1394_CONFIG_ROMS_H
#define _IEEE1394_CONFIG_ROMS_H
-#include "ieee1394_types.h"
-#include "hosts.h"
+struct hpsb_host;
-/* 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
+#ifdef CONFIG_IEEE1394_ETH1394_ROM_ENTRY
+int hpsb_config_rom_ip1394_add(struct hpsb_host *host);
+void hpsb_config_rom_ip1394_remove(struct hpsb_host *host);
+#endif
+
#endif /* _IEEE1394_CONFIG_ROMS_H */
diff --git a/drivers/ieee1394/csr1212.c b/drivers/ieee1394/csr1212.c
index c28f639823d2..d08166bda1c5 100644
--- a/drivers/ieee1394/csr1212.c
+++ b/drivers/ieee1394/csr1212.c
@@ -31,12 +31,13 @@
/* TODO List:
* - Verify interface consistency: i.e., public functions that take a size
* parameter expect size to be in bytes.
- * - Convenience functions for reading a block of data from a given offset.
*/
-#ifndef __KERNEL__
-#include <string.h>
-#endif
+#include <linux/errno.h>
+#include <linux/kernel.h>
+#include <linux/string.h>
+#include <asm/bug.h>
+#include <asm/byteorder.h>
#include "csr1212.h"
@@ -46,7 +47,7 @@
#define __C (1 << CSR1212_KV_TYPE_CSR_OFFSET)
#define __D (1 << CSR1212_KV_TYPE_DIRECTORY)
#define __L (1 << CSR1212_KV_TYPE_LEAF)
-static const u_int8_t csr1212_key_id_type_map[0x30] = {
+static const u8 csr1212_key_id_type_map[0x30] = {
__C, /* used by Apple iSight */
__D | __L, /* Descriptor */
__I | __D | __L, /* Bus_Dependent_Info */
@@ -82,10 +83,10 @@ static const u_int8_t csr1212_key_id_type_map[0x30] = {
#undef __L
-#define quads_to_bytes(_q) ((_q) * sizeof(u_int32_t))
-#define bytes_to_quads(_b) (((_b) + sizeof(u_int32_t) - 1) / sizeof(u_int32_t))
+#define quads_to_bytes(_q) ((_q) * sizeof(u32))
+#define bytes_to_quads(_b) (((_b) + sizeof(u32) - 1) / sizeof(u32))
-static inline void free_keyval(struct csr1212_keyval *kv)
+static void free_keyval(struct csr1212_keyval *kv)
{
if ((kv->key.type == CSR1212_KV_TYPE_LEAF) &&
(kv->key.id != CSR1212_KV_ID_EXTENDED_ROM))
@@ -94,14 +95,14 @@ static inline void free_keyval(struct csr1212_keyval *kv)
CSR1212_FREE(kv);
}
-static u_int16_t csr1212_crc16(const u_int32_t *buffer, size_t length)
+static u16 csr1212_crc16(const u32 *buffer, size_t length)
{
int shift;
- u_int32_t data;
- u_int16_t sum, crc = 0;
+ u32 data;
+ u16 sum, crc = 0;
for (; length; length--) {
- data = CSR1212_BE32_TO_CPU(*buffer);
+ data = be32_to_cpu(*buffer);
buffer++;
for (shift = 28; shift >= 0; shift -= 4 ) {
sum = ((crc >> 12) ^ (data >> shift)) & 0xf;
@@ -110,21 +111,18 @@ static u_int16_t csr1212_crc16(const u_int32_t *buffer, size_t length)
crc &= 0xffff;
}
- return CSR1212_CPU_TO_BE16(crc);
+ return cpu_to_be16(crc);
}
-#if 0
-/* Microsoft computes the CRC with the bytes in reverse order. Therefore we
- * have a special version of the CRC algorithm to account for their buggy
- * software. */
-static u_int16_t csr1212_msft_crc16(const u_int32_t *buffer, size_t length)
+/* Microsoft computes the CRC with the bytes in reverse order. */
+static u16 csr1212_msft_crc16(const u32 *buffer, size_t length)
{
int shift;
- u_int32_t data;
- u_int16_t sum, crc = 0;
+ u32 data;
+ u16 sum, crc = 0;
for (; length; length--) {
- data = CSR1212_LE32_TO_CPU(*buffer);
+ data = le32_to_cpu(*buffer);
buffer++;
for (shift = 28; shift >= 0; shift -= 4 ) {
sum = ((crc >> 12) ^ (data >> shift)) & 0xf;
@@ -133,38 +131,35 @@ static u_int16_t csr1212_msft_crc16(const u_int32_t *buffer, size_t length)
crc &= 0xffff;
}
- return CSR1212_CPU_TO_BE16(crc);
+ return cpu_to_be16(crc);
}
-#endif
-static inline struct csr1212_dentry *csr1212_find_keyval(struct csr1212_keyval *dir,
- struct csr1212_keyval *kv)
+static struct csr1212_dentry *
+csr1212_find_keyval(struct csr1212_keyval *dir, struct csr1212_keyval *kv)
{
struct csr1212_dentry *pos;
for (pos = dir->value.directory.dentries_head;
- pos != NULL; pos = pos->next) {
+ pos != NULL; pos = pos->next)
if (pos->kv == kv)
return pos;
- }
return NULL;
}
-
-static inline struct csr1212_keyval *csr1212_find_keyval_offset(struct csr1212_keyval *kv_list,
- u_int32_t offset)
+static struct csr1212_keyval *
+csr1212_find_keyval_offset(struct csr1212_keyval *kv_list, u32 offset)
{
struct csr1212_keyval *kv;
- for (kv = kv_list->next; kv && (kv != kv_list); kv = kv->next) {
+ for (kv = kv_list->next; kv && (kv != kv_list); kv = kv->next)
if (kv->offset == offset)
return kv;
- }
return NULL;
}
/* Creation Routines */
+
struct csr1212_csr *csr1212_create_csr(struct csr1212_bus_ops *ops,
size_t bus_info_size, void *private)
{
@@ -202,27 +197,17 @@ struct csr1212_csr *csr1212_create_csr(struct csr1212_bus_ops *ops,
return csr;
}
-
-
void csr1212_init_local_csr(struct csr1212_csr *csr,
- const u_int32_t *bus_info_data, int max_rom)
+ const u32 *bus_info_data, int max_rom)
{
static const int mr_map[] = { 4, 64, 1024, 0 };
-#ifdef __KERNEL__
BUG_ON(max_rom & ~0x3);
csr->max_rom = mr_map[max_rom];
-#else
- if (max_rom & ~0x3) /* caller supplied invalid argument */
- csr->max_rom = 0;
- else
- csr->max_rom = mr_map[max_rom];
-#endif
memcpy(csr->bus_info_data, bus_info_data, csr->bus_info_len);
}
-
-static struct csr1212_keyval *csr1212_new_keyval(u_int8_t type, u_int8_t key)
+static struct csr1212_keyval *csr1212_new_keyval(u8 type, u8 key)
{
struct csr1212_keyval *kv;
@@ -246,10 +231,11 @@ static struct csr1212_keyval *csr1212_new_keyval(u_int8_t type, u_int8_t key)
return kv;
}
-struct csr1212_keyval *csr1212_new_immediate(u_int8_t key, u_int32_t value)
+struct csr1212_keyval *csr1212_new_immediate(u8 key, u32 value)
{
- struct csr1212_keyval *kv = csr1212_new_keyval(CSR1212_KV_TYPE_IMMEDIATE, key);
+ struct csr1212_keyval *kv;
+ kv = csr1212_new_keyval(CSR1212_KV_TYPE_IMMEDIATE, key);
if (!kv)
return NULL;
@@ -258,10 +244,12 @@ struct csr1212_keyval *csr1212_new_immediate(u_int8_t key, u_int32_t value)
return kv;
}
-struct csr1212_keyval *csr1212_new_leaf(u_int8_t key, const void *data, size_t data_len)
+static struct csr1212_keyval *
+csr1212_new_leaf(u8 key, const void *data, size_t data_len)
{
- struct csr1212_keyval *kv = csr1212_new_keyval(CSR1212_KV_TYPE_LEAF, key);
+ struct csr1212_keyval *kv;
+ kv = csr1212_new_keyval(CSR1212_KV_TYPE_LEAF, key);
if (!kv)
return NULL;
@@ -285,10 +273,12 @@ struct csr1212_keyval *csr1212_new_leaf(u_int8_t key, const void *data, size_t d
return kv;
}
-struct csr1212_keyval *csr1212_new_csr_offset(u_int8_t key, u_int32_t csr_offset)
+static struct csr1212_keyval *
+csr1212_new_csr_offset(u8 key, u32 csr_offset)
{
- struct csr1212_keyval *kv = csr1212_new_keyval(CSR1212_KV_TYPE_CSR_OFFSET, key);
+ struct csr1212_keyval *kv;
+ kv = csr1212_new_keyval(CSR1212_KV_TYPE_CSR_OFFSET, key);
if (!kv)
return NULL;
@@ -299,10 +289,11 @@ struct csr1212_keyval *csr1212_new_csr_offset(u_int8_t key, u_int32_t csr_offset
return kv;
}
-struct csr1212_keyval *csr1212_new_directory(u_int8_t key)
+struct csr1212_keyval *csr1212_new_directory(u8 key)
{
- struct csr1212_keyval *kv = csr1212_new_keyval(CSR1212_KV_TYPE_DIRECTORY, key);
+ struct csr1212_keyval *kv;
+ kv = csr1212_new_keyval(CSR1212_KV_TYPE_DIRECTORY, key);
if (!kv)
return NULL;
@@ -314,43 +305,29 @@ struct csr1212_keyval *csr1212_new_directory(u_int8_t key)
return kv;
}
-int csr1212_associate_keyval(struct csr1212_keyval *kv,
- struct csr1212_keyval *associate)
+void csr1212_associate_keyval(struct csr1212_keyval *kv,
+ struct csr1212_keyval *associate)
{
- if (!kv || !associate)
- return CSR1212_EINVAL;
-
- if (kv->key.id == CSR1212_KV_ID_DESCRIPTOR ||
- (associate->key.id != CSR1212_KV_ID_DESCRIPTOR &&
- associate->key.id != CSR1212_KV_ID_DEPENDENT_INFO &&
- associate->key.id != CSR1212_KV_ID_EXTENDED_KEY &&
- associate->key.id != CSR1212_KV_ID_EXTENDED_DATA &&
- associate->key.id < 0x30))
- return CSR1212_EINVAL;
-
- if (kv->key.id == CSR1212_KV_ID_EXTENDED_KEY_SPECIFIER_ID &&
- associate->key.id != CSR1212_KV_ID_EXTENDED_KEY)
- return CSR1212_EINVAL;
-
- if (kv->key.id == CSR1212_KV_ID_EXTENDED_KEY &&
- associate->key.id != CSR1212_KV_ID_EXTENDED_DATA)
- return CSR1212_EINVAL;
-
- if (associate->key.id == CSR1212_KV_ID_EXTENDED_KEY &&
- kv->key.id != CSR1212_KV_ID_EXTENDED_KEY_SPECIFIER_ID)
- return CSR1212_EINVAL;
-
- if (associate->key.id == CSR1212_KV_ID_EXTENDED_DATA &&
- kv->key.id != CSR1212_KV_ID_EXTENDED_KEY)
- return CSR1212_EINVAL;
+ BUG_ON(!kv || !associate || kv->key.id == CSR1212_KV_ID_DESCRIPTOR ||
+ (associate->key.id != CSR1212_KV_ID_DESCRIPTOR &&
+ associate->key.id != CSR1212_KV_ID_DEPENDENT_INFO &&
+ associate->key.id != CSR1212_KV_ID_EXTENDED_KEY &&
+ associate->key.id != CSR1212_KV_ID_EXTENDED_DATA &&
+ associate->key.id < 0x30) ||
+ (kv->key.id == CSR1212_KV_ID_EXTENDED_KEY_SPECIFIER_ID &&
+ associate->key.id != CSR1212_KV_ID_EXTENDED_KEY) ||
+ (kv->key.id == CSR1212_KV_ID_EXTENDED_KEY &&
+ associate->key.id != CSR1212_KV_ID_EXTENDED_DATA) ||
+ (associate->key.id == CSR1212_KV_ID_EXTENDED_KEY &&
+ kv->key.id != CSR1212_KV_ID_EXTENDED_KEY_SPECIFIER_ID) ||
+ (associate->key.id == CSR1212_KV_ID_EXTENDED_DATA &&
+ kv->key.id != CSR1212_KV_ID_EXTENDED_KEY));
if (kv->associate)
csr1212_release_keyval(kv->associate);
associate->refcnt++;
kv->associate = associate;
-
- return CSR1212_SUCCESS;
}
int csr1212_attach_keyval_to_directory(struct csr1212_keyval *dir,
@@ -358,12 +335,11 @@ int csr1212_attach_keyval_to_directory(struct csr1212_keyval *dir,
{
struct csr1212_dentry *dentry;
- if (!kv || !dir || dir->key.type != CSR1212_KV_TYPE_DIRECTORY)
- return CSR1212_EINVAL;
+ BUG_ON(!kv || !dir || dir->key.type != CSR1212_KV_TYPE_DIRECTORY);
dentry = CSR1212_MALLOC(sizeof(*dentry));
if (!dentry)
- return CSR1212_ENOMEM;
+ return -ENOMEM;
dentry->kv = kv;
@@ -382,66 +358,22 @@ int csr1212_attach_keyval_to_directory(struct csr1212_keyval *dir,
return CSR1212_SUCCESS;
}
-struct csr1212_keyval *csr1212_new_extended_immediate(u_int32_t spec, u_int32_t key,
- u_int32_t value)
-{
- struct csr1212_keyval *kvs, *kvk, *kvv;
-
- kvs = csr1212_new_immediate(CSR1212_KV_ID_EXTENDED_KEY_SPECIFIER_ID, spec);
- kvk = csr1212_new_immediate(CSR1212_KV_ID_EXTENDED_KEY, key);
- kvv = csr1212_new_immediate(CSR1212_KV_ID_EXTENDED_DATA, value);
-
- if (!kvs || !kvk || !kvv) {
- if (kvs)
- free_keyval(kvs);
- if (kvk)
- free_keyval(kvk);
- if (kvv)
- free_keyval(kvv);
- return NULL;
- }
-
- /* Don't keep a local reference to the extended key or value. */
- kvk->refcnt = 0;
- kvv->refcnt = 0;
-
- csr1212_associate_keyval(kvk, kvv);
- csr1212_associate_keyval(kvs, kvk);
-
- return kvs;
-}
-
-struct csr1212_keyval *csr1212_new_extended_leaf(u_int32_t spec, u_int32_t key,
- const void *data, size_t data_len)
-{
- struct csr1212_keyval *kvs, *kvk, *kvv;
-
- kvs = csr1212_new_immediate(CSR1212_KV_ID_EXTENDED_KEY_SPECIFIER_ID, spec);
- kvk = csr1212_new_immediate(CSR1212_KV_ID_EXTENDED_KEY, key);
- kvv = csr1212_new_leaf(CSR1212_KV_ID_EXTENDED_DATA, data, data_len);
-
- if (!kvs || !kvk || !kvv) {
- if (kvs)
- free_keyval(kvs);
- if (kvk)
- free_keyval(kvk);
- if (kvv)
- free_keyval(kvv);
- return NULL;
- }
-
- /* Don't keep a local reference to the extended key or value. */
- kvk->refcnt = 0;
- kvv->refcnt = 0;
-
- csr1212_associate_keyval(kvk, kvv);
- csr1212_associate_keyval(kvs, kvk);
-
- return kvs;
-}
-
-struct csr1212_keyval *csr1212_new_descriptor_leaf(u_int8_t dtype, u_int32_t specifier_id,
- const void *data, size_t data_len)
+#define CSR1212_DESCRIPTOR_LEAF_DATA(kv) \
+ (&((kv)->value.leaf.data[1]))
+
+#define CSR1212_DESCRIPTOR_LEAF_SET_TYPE(kv, type) \
+ ((kv)->value.leaf.data[0] = \
+ cpu_to_be32(CSR1212_DESCRIPTOR_LEAF_SPECIFIER_ID(kv) | \
+ ((type) << CSR1212_DESCRIPTOR_LEAF_TYPE_SHIFT)))
+#define CSR1212_DESCRIPTOR_LEAF_SET_SPECIFIER_ID(kv, spec_id) \
+ ((kv)->value.leaf.data[0] = \
+ cpu_to_be32((CSR1212_DESCRIPTOR_LEAF_TYPE(kv) << \
+ CSR1212_DESCRIPTOR_LEAF_TYPE_SHIFT) | \
+ ((spec_id) & CSR1212_DESCRIPTOR_LEAF_SPECIFIER_ID_MASK)))
+
+static struct csr1212_keyval *
+csr1212_new_descriptor_leaf(u8 dtype, u32 specifier_id,
+ const void *data, size_t data_len)
{
struct csr1212_keyval *kv;
@@ -453,197 +385,72 @@ struct csr1212_keyval *csr1212_new_descriptor_leaf(u_int8_t dtype, u_int32_t spe
CSR1212_DESCRIPTOR_LEAF_SET_TYPE(kv, dtype);
CSR1212_DESCRIPTOR_LEAF_SET_SPECIFIER_ID(kv, specifier_id);
- if (data) {
+ if (data)
memcpy(CSR1212_DESCRIPTOR_LEAF_DATA(kv), data, data_len);
- }
-
- return kv;
-}
-
-
-struct csr1212_keyval *csr1212_new_textual_descriptor_leaf(u_int8_t cwidth,
- u_int16_t cset,
- u_int16_t language,
- const void *data,
- size_t data_len)
-{
- struct csr1212_keyval *kv;
- char *lstr;
-
- kv = csr1212_new_descriptor_leaf(0, 0, NULL, data_len +
- CSR1212_TEXTUAL_DESCRIPTOR_LEAF_OVERHEAD);
- if (!kv)
- return NULL;
-
- CSR1212_TEXTUAL_DESCRIPTOR_LEAF_SET_WIDTH(kv, cwidth);
- CSR1212_TEXTUAL_DESCRIPTOR_LEAF_SET_CHAR_SET(kv, cset);
- CSR1212_TEXTUAL_DESCRIPTOR_LEAF_SET_LANGUAGE(kv, language);
-
- lstr = (char*)CSR1212_TEXTUAL_DESCRIPTOR_LEAF_DATA(kv);
-
- /* make sure last quadlet is zeroed out */
- *((u_int32_t*)&(lstr[(data_len - 1) & ~0x3])) = 0;
-
- /* don't copy the NUL terminator */
- memcpy(lstr, data, data_len);
return kv;
}
+/* Check if string conforms to minimal ASCII as per IEEE 1212 clause 7.4 */
static int csr1212_check_minimal_ascii(const char *s)
{
static const char minimal_ascii_table[] = {
- 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x07,
- 0x00, 0x00, 0x0a, 0x00, 0x0C, 0x0D, 0x00, 0x00,
- 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
- 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
- 0x20, 0x21, 0x22, 0x00, 0x00, 0x25, 0x26, 0x27,
- 0x28, 0x29, 0x2a, 0x2b, 0x2c, 0x2d, 0x2e, 0x2f,
- 0x30, 0x31, 0x32, 0x33, 0x34, 0x35, 0x36, 0x37,
- 0x38, 0x39, 0x3a, 0x3b, 0x3c, 0x3d, 0x3e, 0x3f,
- 0x40, 0x41, 0x42, 0x43, 0x44, 0x45, 0x46, 0x47,
- 0x48, 0x49, 0x4a, 0x4b, 0x4c, 0x4d, 0x4e, 0x4f,
- 0x50, 0x51, 0x52, 0x53, 0x54, 0x55, 0x56, 0x57,
- 0x58, 0x59, 0x5a, 0x00, 0x00, 0x00, 0x00, 0x5f,
- 0x00, 0x61, 0x62, 0x63, 0x64, 0x65, 0x66, 0x67,
- 0x68, 0x69, 0x6a, 0x6b, 0x6c, 0x6d, 0x6e, 0x6f,
- 0x70, 0x71, 0x72, 0x73, 0x74, 0x75, 0x76, 0x77,
- 0x78, 0x79, 0x7a, 0x00, 0x00, 0x00, 0x00, 0x00,
+ /* 1 2 4 8 16 32 64 128 */
+ 128, /* --, --, --, --, --, --, --, 07, */
+ 4 + 16 + 32, /* --, --, 0a, --, 0C, 0D, --, --, */
+ 0, /* --, --, --, --, --, --, --, --, */
+ 0, /* --, --, --, --, --, --, --, --, */
+ 255 - 8 - 16, /* 20, 21, 22, --, --, 25, 26, 27, */
+ 255, /* 28, 29, 2a, 2b, 2c, 2d, 2e, 2f, */
+ 255, /* 30, 31, 32, 33, 34, 35, 36, 37, */
+ 255, /* 38, 39, 3a, 3b, 3c, 3d, 3e, 3f, */
+ 255, /* 40, 41, 42, 43, 44, 45, 46, 47, */
+ 255, /* 48, 49, 4a, 4b, 4c, 4d, 4e, 4f, */
+ 255, /* 50, 51, 52, 53, 54, 55, 56, 57, */
+ 1 + 2 + 4 + 128, /* 58, 59, 5a, --, --, --, --, 5f, */
+ 255 - 1, /* --, 61, 62, 63, 64, 65, 66, 67, */
+ 255, /* 68, 69, 6a, 6b, 6c, 6d, 6e, 6f, */
+ 255, /* 70, 71, 72, 73, 74, 75, 76, 77, */
+ 1 + 2 + 4, /* 78, 79, 7a, --, --, --, --, --, */
};
+ int i, j;
+
for (; *s; s++) {
- if (minimal_ascii_table[*s & 0x7F] != *s)
- return -1; /* failed */
+ i = *s >> 3; /* i = *s / 8; */
+ j = 1 << (*s & 3); /* j = 1 << (*s % 8); */
+
+ if (i >= ARRAY_SIZE(minimal_ascii_table) ||
+ !(minimal_ascii_table[i] & j))
+ return -EINVAL;
}
- /* String conforms to minimal-ascii, as specified by IEEE 1212,
- * par. 7.4 */
return 0;
}
+/* IEEE 1212 clause 7.5.4.1 textual descriptors (English, minimal ASCII) */
struct csr1212_keyval *csr1212_new_string_descriptor_leaf(const char *s)
{
- /* Check if string conform to minimal_ascii format */
- if (csr1212_check_minimal_ascii(s))
- return NULL;
-
- /* IEEE 1212, par. 7.5.4.1 Textual descriptors (minimal ASCII) */
- return csr1212_new_textual_descriptor_leaf(0, 0, 0, s, strlen(s));
-}
-
-struct csr1212_keyval *csr1212_new_icon_descriptor_leaf(u_int32_t version,
- u_int8_t palette_depth,
- u_int8_t color_space,
- u_int16_t language,
- u_int16_t hscan,
- u_int16_t vscan,
- u_int32_t *palette,
- u_int32_t *pixels)
-{
- static const int pd[4] = { 0, 4, 16, 256 };
- static const int cs[16] = { 4, 2 };
struct csr1212_keyval *kv;
- int palette_size;
- int pixel_size = (hscan * vscan + 3) & ~0x3;
+ u32 *text;
+ size_t str_len, quads;
- if (!pixels || (!palette && palette_depth) ||
- (palette_depth & ~0x3) || (color_space & ~0xf))
+ if (!s || !*s || csr1212_check_minimal_ascii(s))
return NULL;
- palette_size = pd[palette_depth] * cs[color_space];
-
- kv = csr1212_new_descriptor_leaf(1, 0, NULL,
- palette_size + pixel_size +
- CSR1212_ICON_DESCRIPTOR_LEAF_OVERHEAD);
+ str_len = strlen(s);
+ quads = bytes_to_quads(str_len);
+ kv = csr1212_new_descriptor_leaf(0, 0, NULL, quads_to_bytes(quads) +
+ CSR1212_TEXTUAL_DESCRIPTOR_LEAF_OVERHEAD);
if (!kv)
return NULL;
- CSR1212_ICON_DESCRIPTOR_LEAF_SET_VERSION(kv, version);
- CSR1212_ICON_DESCRIPTOR_LEAF_SET_PALETTE_DEPTH(kv, palette_depth);
- CSR1212_ICON_DESCRIPTOR_LEAF_SET_COLOR_SPACE(kv, color_space);
- CSR1212_ICON_DESCRIPTOR_LEAF_SET_LANGUAGE(kv, language);
- CSR1212_ICON_DESCRIPTOR_LEAF_SET_HSCAN(kv, hscan);
- CSR1212_ICON_DESCRIPTOR_LEAF_SET_VSCAN(kv, vscan);
-
- if (palette_size)
- memcpy(CSR1212_ICON_DESCRIPTOR_LEAF_PALETTE(kv), palette,
- palette_size);
-