Commit 726a1180 authored by Linus Torvalds's avatar Linus Torvalds

Merge bk://linux-1394.bkbits.net/1394-2.6

into ppc970.osdl.org:/home/torvalds/v2.6/linux
parents ef4333ae 64632844
...@@ -1093,9 +1093,21 @@ M: Gadi Oxman <gadio@netvision.net.il> ...@@ -1093,9 +1093,21 @@ M: Gadi Oxman <gadio@netvision.net.il>
L: linux-kernel@vger.kernel.org L: linux-kernel@vger.kernel.org
S: Maintained S: Maintained
IEEE 1394 ETHERNET (eth1394)
L: linux1394-devel@lists.sourceforge.net
W: http://www.linux1394.org/
S: Orphan
IEEE 1394 SBP2
L: linux1394-devel@lists.sourceforge.net
W: http://www.linux1394.org/
S: Orphan
IEEE 1394 SUBSYSTEM IEEE 1394 SUBSYSTEM
P: Ben Collins P: Ben Collins
M: bcollins@debian.org M: bcollins@debian.org
P: Jody McIntyre
M: scjody@steamballoon.com
L: linux1394-devel@lists.sourceforge.net L: linux1394-devel@lists.sourceforge.net
W: http://www.linux1394.org/ W: http://www.linux1394.org/
S: Maintained S: Maintained
...@@ -1103,13 +1115,15 @@ S: Maintained ...@@ -1103,13 +1115,15 @@ S: Maintained
IEEE 1394 OHCI DRIVER IEEE 1394 OHCI DRIVER
P: Ben Collins P: Ben Collins
M: bcollins@debian.org M: bcollins@debian.org
P: Jody McIntyre
M: scjody@steamballoon.com
L: linux1394-devel@lists.sourceforge.net L: linux1394-devel@lists.sourceforge.net
W: http://www.linux1394.org/ W: http://www.linux1394.org/
S: Maintained S: Maintained
IEEE 1394 PCILYNX DRIVER IEEE 1394 PCILYNX DRIVER
P: Andreas Bombe P: Jody McIntyre
M: andreas.bombe@munich.netsurf.de M: scjody@steamballoon.com
L: linux1394-devel@lists.sourceforge.net L: linux1394-devel@lists.sourceforge.net
W: http://www.linux1394.org/ W: http://www.linux1394.org/
S: Maintained S: Maintained
...@@ -1117,6 +1131,8 @@ S: Maintained ...@@ -1117,6 +1131,8 @@ S: Maintained
IEEE 1394 RAW I/O DRIVER IEEE 1394 RAW I/O DRIVER
P: Ben Collins P: Ben Collins
M: bcollins@debian.org M: bcollins@debian.org
P: Dan Dennedy
M: dan@dennedy.org
L: linux1394-devel@lists.sourceforge.net L: linux1394-devel@lists.sourceforge.net
W: http://www.linux1394.org/ W: http://www.linux1394.org/
S: Maintained S: Maintained
......
...@@ -5,6 +5,7 @@ menu "IEEE 1394 (FireWire) support" ...@@ -5,6 +5,7 @@ menu "IEEE 1394 (FireWire) support"
config IEEE1394 config IEEE1394
tristate "IEEE 1394 (FireWire) support" tristate "IEEE 1394 (FireWire) support"
depends on PCI || BROKEN depends on PCI || BROKEN
select NET
help help
IEEE 1394 describes a high performance serial bus, which is also 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 known as FireWire(tm) or i.Link(tm) and is used for connecting all
......
...@@ -286,7 +286,7 @@ static struct hpsb_highlevel amdtp_highlevel; ...@@ -286,7 +286,7 @@ static struct hpsb_highlevel amdtp_highlevel;
#define OHCI1394_CONTEXT_DEAD 0x00000800 #define OHCI1394_CONTEXT_DEAD 0x00000800
#define OHCI1394_CONTEXT_ACTIVE 0x00000400 #define OHCI1394_CONTEXT_ACTIVE 0x00000400
void ohci1394_start_it_ctx(struct ti_ohci *ohci, int ctx, static void ohci1394_start_it_ctx(struct ti_ohci *ohci, int ctx,
dma_addr_t first_cmd, int z, int cycle_match) dma_addr_t first_cmd, int z, int cycle_match)
{ {
reg_write(ohci, OHCI1394_IsoXmitIntMaskSet, 1 << ctx); reg_write(ohci, OHCI1394_IsoXmitIntMaskSet, 1 << ctx);
...@@ -298,13 +298,13 @@ void ohci1394_start_it_ctx(struct ti_ohci *ohci, int ctx, ...@@ -298,13 +298,13 @@ void ohci1394_start_it_ctx(struct ti_ohci *ohci, int ctx,
OHCI1394_CONTEXT_RUN); OHCI1394_CONTEXT_RUN);
} }
void ohci1394_wake_it_ctx(struct ti_ohci *ohci, int ctx) static void ohci1394_wake_it_ctx(struct ti_ohci *ohci, int ctx)
{ {
reg_write(ohci, OHCI1394_IsoXmitContextControlSet + ctx * 16, reg_write(ohci, OHCI1394_IsoXmitContextControlSet + ctx * 16,
OHCI1394_CONTEXT_WAKE); OHCI1394_CONTEXT_WAKE);
} }
void ohci1394_stop_it_ctx(struct ti_ohci *ohci, int ctx, int synchronous) static void ohci1394_stop_it_ctx(struct ti_ohci *ohci, int ctx, int synchronous)
{ {
u32 control; u32 control;
int wait; int wait;
...@@ -530,7 +530,7 @@ static __inline__ int fraction_ceil(struct fraction *frac) ...@@ -530,7 +530,7 @@ static __inline__ int fraction_ceil(struct fraction *frac)
return frac->integer + (frac->numerator > 0 ? 1 : 0); return frac->integer + (frac->numerator > 0 ? 1 : 0);
} }
void packet_initialize(struct packet *p, struct packet *next) static void packet_initialize(struct packet *p, struct packet *next)
{ {
/* Here we initialize the dma descriptor block for /* Here we initialize the dma descriptor block for
* transferring one iso packet. We use two descriptors per * transferring one iso packet. We use two descriptors per
...@@ -559,7 +559,7 @@ void packet_initialize(struct packet *p, struct packet *next) ...@@ -559,7 +559,7 @@ void packet_initialize(struct packet *p, struct packet *next)
p->db->payload_desc.status = 0; p->db->payload_desc.status = 0;
} }
struct packet_list *packet_list_alloc(struct stream *s) static struct packet_list *packet_list_alloc(struct stream *s)
{ {
int i; int i;
struct packet_list *pl; struct packet_list *pl;
...@@ -588,7 +588,7 @@ struct packet_list *packet_list_alloc(struct stream *s) ...@@ -588,7 +588,7 @@ struct packet_list *packet_list_alloc(struct stream *s)
return pl; return pl;
} }
void packet_list_free(struct packet_list *pl, struct stream *s) static void packet_list_free(struct packet_list *pl, struct stream *s)
{ {
int i; int i;
...@@ -1010,7 +1010,7 @@ static int stream_configure(struct stream *s, int cmd, struct amdtp_ioctl *cfg) ...@@ -1010,7 +1010,7 @@ static int stream_configure(struct stream *s, int cmd, struct amdtp_ioctl *cfg)
return 0; return 0;
} }
struct stream *stream_alloc(struct amdtp_host *host) static struct stream *stream_alloc(struct amdtp_host *host)
{ {
struct stream *s; struct stream *s;
unsigned long flags; unsigned long flags;
...@@ -1062,7 +1062,7 @@ struct stream *stream_alloc(struct amdtp_host *host) ...@@ -1062,7 +1062,7 @@ struct stream *stream_alloc(struct amdtp_host *host)
return s; return s;
} }
void stream_free(struct stream *s) static void stream_free(struct stream *s)
{ {
unsigned long flags; unsigned long flags;
......
...@@ -67,8 +67,8 @@ int hpsb_default_host_entry(struct hpsb_host *host) ...@@ -67,8 +67,8 @@ int hpsb_default_host_entry(struct hpsb_host *host)
ret = csr1212_associate_keyval(vend_id, text); ret = csr1212_associate_keyval(vend_id, text);
csr1212_release_keyval(text); csr1212_release_keyval(text);
ret |= csr1212_attach_keyval_to_directory(root, vend_id); ret |= csr1212_attach_keyval_to_directory(root, vend_id);
if (ret != CSR1212_SUCCESS) {
csr1212_release_keyval(vend_id); csr1212_release_keyval(vend_id);
if (ret != CSR1212_SUCCESS) {
csr1212_destroy_csr(host->csr.rom); csr1212_destroy_csr(host->csr.rom);
return -ENOMEM; return -ENOMEM;
} }
......
...@@ -87,7 +87,8 @@ static const u_int8_t csr1212_key_id_type_map[0x30] = { ...@@ -87,7 +87,8 @@ static const u_int8_t csr1212_key_id_type_map[0x30] = {
static inline void free_keyval(struct csr1212_keyval *kv) static inline void free_keyval(struct csr1212_keyval *kv)
{ {
if (kv->key.type == CSR1212_KV_TYPE_LEAF) if ((kv->key.type == CSR1212_KV_TYPE_LEAF) &&
(kv->key.id != CSR1212_KV_ID_EXTENDED_ROM))
CSR1212_FREE(kv->value.leaf.data); CSR1212_FREE(kv->value.leaf.data);
CSR1212_FREE(kv); CSR1212_FREE(kv);
...@@ -155,7 +156,7 @@ static inline struct csr1212_keyval *csr1212_find_keyval_offset(struct csr1212_k ...@@ -155,7 +156,7 @@ static inline struct csr1212_keyval *csr1212_find_keyval_offset(struct csr1212_k
{ {
struct csr1212_keyval *kv; struct csr1212_keyval *kv;
for (kv = kv_list; kv != NULL; kv = kv->next) { for (kv = kv_list->next; kv && (kv != kv_list); kv = kv->next) {
if (kv->offset == offset) if (kv->offset == offset)
return kv; return kv;
} }
...@@ -796,7 +797,8 @@ static int csr1212_append_new_cache(struct csr1212_csr *csr, size_t romsize) ...@@ -796,7 +797,8 @@ static int csr1212_append_new_cache(struct csr1212_csr *csr, size_t romsize)
return CSR1212_ENOMEM; return CSR1212_ENOMEM;
} }
cache->ext_rom->offset = csr_addr - CSR1212_REGISTER_SPACE_BASE; cache->ext_rom->offset = csr_addr - CSR1212_REGISTER_SPACE_BASE;
cache->ext_rom->value.leaf.len = 0; cache->ext_rom->value.leaf.len = -1;
cache->ext_rom->value.leaf.data = cache->data;
/* Add cache to tail of cache list */ /* Add cache to tail of cache list */
cache->prev = csr->cache_tail; cache->prev = csr->cache_tail;
...@@ -864,20 +866,20 @@ static int csr1212_generate_layout_subdir(struct csr1212_keyval *dir, ...@@ -864,20 +866,20 @@ static int csr1212_generate_layout_subdir(struct csr1212_keyval *dir,
default: default:
case CSR1212_KV_TYPE_IMMEDIATE: case CSR1212_KV_TYPE_IMMEDIATE:
case CSR1212_KV_TYPE_CSR_OFFSET: case CSR1212_KV_TYPE_CSR_OFFSET:
continue; break;
case CSR1212_KV_TYPE_LEAF: case CSR1212_KV_TYPE_LEAF:
case CSR1212_KV_TYPE_DIRECTORY: case CSR1212_KV_TYPE_DIRECTORY:
/* Remove from list */ /* Remove from list */
if (dkv->prev) if (dkv->prev && (dkv->prev->next == dkv))
dkv->prev->next = dkv->next; dkv->prev->next = dkv->next;
if (dkv->next) if (dkv->next && (dkv->next->prev == dkv))
dkv->next->prev = dkv->prev; dkv->next->prev = dkv->prev;
if (dkv == *layout_tail) //if (dkv == *layout_tail)
*layout_tail = dkv->prev; // *layout_tail = dkv->prev;
/* Special case: Extended ROM leafs */ /* Special case: Extended ROM leafs */
if (dkv->key.id == CSR1212_KV_ID_EXTENDED_ROM) { if (dkv->key.id == CSR1212_KV_ID_EXTENDED_ROM) {
dkv->value.leaf.len = 0; /* initialize to zero */ dkv->value.leaf.len = -1;
/* Don't add Extended ROM leafs in the layout list, /* Don't add Extended ROM leafs in the layout list,
* they are handled differently. */ * they are handled differently. */
break; break;
...@@ -930,7 +932,10 @@ struct csr1212_keyval *csr1212_generate_positions(struct csr1212_csr_rom_cache * ...@@ -930,7 +932,10 @@ struct csr1212_keyval *csr1212_generate_positions(struct csr1212_csr_rom_cache *
cache->layout_head = kv; cache->layout_head = kv;
while(kv && pos < cache->size) { while(kv && pos < cache->size) {
/* Special case: Extended ROM leafs */
if (kv->key.id != CSR1212_KV_ID_EXTENDED_ROM) {
kv->offset = cache->offset + pos; kv->offset = cache->offset + pos;
}
switch(kv->key.type) { switch(kv->key.type) {
case CSR1212_KV_TYPE_LEAF: case CSR1212_KV_TYPE_LEAF:
...@@ -1090,6 +1095,9 @@ int csr1212_generate_csr_image(struct csr1212_csr *csr) ...@@ -1090,6 +1095,9 @@ int csr1212_generate_csr_image(struct csr1212_csr *csr)
bi->crc_length = bi->length; bi->crc_length = bi->length;
bi->crc = csr1212_crc16(bi->data, bi->crc_length); bi->crc = csr1212_crc16(bi->data, bi->crc_length);
csr->root_kv->next = NULL;
csr->root_kv->prev = NULL;
agg_size = csr1212_generate_layout_order(csr->root_kv); agg_size = csr1212_generate_layout_order(csr->root_kv);
init_offset = csr->bus_info_len; init_offset = csr->bus_info_len;
...@@ -1158,6 +1166,17 @@ int csr1212_generate_csr_image(struct csr1212_csr *csr) ...@@ -1158,6 +1166,17 @@ int csr1212_generate_csr_image(struct csr1212_csr *csr)
/* Copy the data into the cache buffer */ /* Copy the data into the cache buffer */
csr1212_fill_cache(cache); csr1212_fill_cache(cache);
if (cache != csr->cache_head) {
/* Set the length and CRC of the extended ROM. */
struct csr1212_keyval_img *kvi =
(struct csr1212_keyval_img*)cache->data;
kvi->length = CSR1212_CPU_TO_BE16(bytes_to_quads(cache->len) - 1);
kvi->crc = csr1212_crc16(kvi->data,
bytes_to_quads(cache->len) - 1);
}
} }
return CSR1212_SUCCESS; return CSR1212_SUCCESS;
...@@ -1174,11 +1193,6 @@ int csr1212_read(struct csr1212_csr *csr, u_int32_t offset, void *buffer, u_int3 ...@@ -1174,11 +1193,6 @@ int csr1212_read(struct csr1212_csr *csr, u_int32_t offset, void *buffer, u_int3
&cache->data[bytes_to_quads(offset - cache->offset)], &cache->data[bytes_to_quads(offset - cache->offset)],
len); len);
return CSR1212_SUCCESS; return CSR1212_SUCCESS;
} else if (((offset < cache->offset) &&
((offset + len) >= cache->offset)) ||
((offset >= cache->offset) &&
((offset + len) > (cache->offset + cache->size)))) {
return CSR1212_EINVAL;
} }
} }
return CSR1212_ENOENT; return CSR1212_ENOENT;
...@@ -1249,10 +1263,9 @@ static int csr1212_parse_bus_info_block(struct csr1212_csr *csr) ...@@ -1249,10 +1263,9 @@ static int csr1212_parse_bus_info_block(struct csr1212_csr *csr)
return CSR1212_SUCCESS; return CSR1212_SUCCESS;
} }
static inline int csr1212_parse_dir_entry(struct csr1212_keyval *dir, static int csr1212_parse_dir_entry(struct csr1212_keyval *dir,
csr1212_quad_t ki, csr1212_quad_t ki,
u_int32_t kv_pos, u_int32_t kv_pos)
struct csr1212_csr_rom_cache *cache)
{ {
int ret = CSR1212_SUCCESS; int ret = CSR1212_SUCCESS;
struct csr1212_keyval *k = NULL; struct csr1212_keyval *k = NULL;
...@@ -1291,7 +1304,7 @@ static inline int csr1212_parse_dir_entry(struct csr1212_keyval *dir, ...@@ -1291,7 +1304,7 @@ static inline int csr1212_parse_dir_entry(struct csr1212_keyval *dir,
goto fail; goto fail;
} }
k = csr1212_find_keyval_offset(cache->layout_head, offset); k = csr1212_find_keyval_offset(dir, offset);
if (k) if (k)
break; /* Found it. */ break; /* Found it. */
...@@ -1309,11 +1322,10 @@ static inline int csr1212_parse_dir_entry(struct csr1212_keyval *dir, ...@@ -1309,11 +1322,10 @@ static inline int csr1212_parse_dir_entry(struct csr1212_keyval *dir,
k->valid = 0; /* Contents not read yet so it's not valid. */ k->valid = 0; /* Contents not read yet so it's not valid. */
k->offset = offset; k->offset = offset;
k->prev = cache->layout_tail; k->prev = dir;
k->next = NULL; k->next = dir->next;
if (cache->layout_tail) dir->next->prev = k;
cache->layout_tail->next = k; dir->next = k;
cache->layout_tail = k;
} }
ret = csr1212_attach_keyval_to_directory(dir, k); ret = csr1212_attach_keyval_to_directory(dir, k);
...@@ -1325,6 +1337,7 @@ static inline int csr1212_parse_dir_entry(struct csr1212_keyval *dir, ...@@ -1325,6 +1337,7 @@ static inline int csr1212_parse_dir_entry(struct csr1212_keyval *dir,
return ret; return ret;
} }
int csr1212_parse_keyval(struct csr1212_keyval *kv, int csr1212_parse_keyval(struct csr1212_keyval *kv,
struct csr1212_csr_rom_cache *cache) struct csr1212_csr_rom_cache *cache)
{ {
...@@ -1353,22 +1366,19 @@ int csr1212_parse_keyval(struct csr1212_keyval *kv, ...@@ -1353,22 +1366,19 @@ int csr1212_parse_keyval(struct csr1212_keyval *kv,
csr1212_quad_t ki = kvi->data[i]; csr1212_quad_t ki = kvi->data[i];
/* Some devices put null entries in their unit /* Some devices put null entries in their unit
* directories. If we come across such and entry, * directories. If we come across such an entry,
* then skip it. */ * then skip it. */
if (ki == 0x0) if (ki == 0x0)
continue; continue;
ret = csr1212_parse_dir_entry(kv, ki, ret = csr1212_parse_dir_entry(kv, ki,
(kv->offset + (kv->offset +
quads_to_bytes(i + 1)), quads_to_bytes(i + 1)));
cache);
} }
kv->value.directory.len = kvi_len; kv->value.directory.len = kvi_len;
break; break;
case CSR1212_KV_TYPE_LEAF: case CSR1212_KV_TYPE_LEAF:
if (kv->key.id == CSR1212_KV_ID_EXTENDED_ROM) { if (kv->key.id != CSR1212_KV_ID_EXTENDED_ROM) {
kv->value.leaf.data = cache->data;
} else {
kv->value.leaf.data = CSR1212_MALLOC(quads_to_bytes(kvi_len)); kv->value.leaf.data = CSR1212_MALLOC(quads_to_bytes(kvi_len));
if (!kv->value.leaf.data) if (!kv->value.leaf.data)
{ {
...@@ -1399,7 +1409,6 @@ int _csr1212_read_keyval(struct csr1212_csr *csr, struct csr1212_keyval *kv) ...@@ -1399,7 +1409,6 @@ int _csr1212_read_keyval(struct csr1212_csr *csr, struct csr1212_keyval *kv)
u_int32_t *cache_ptr; u_int32_t *cache_ptr;
u_int16_t kv_len = 0; u_int16_t kv_len = 0;
if (!csr || !kv) if (!csr || !kv)
return CSR1212_EINVAL; return CSR1212_EINVAL;
...@@ -1413,7 +1422,7 @@ int _csr1212_read_keyval(struct csr1212_csr *csr, struct csr1212_keyval *kv) ...@@ -1413,7 +1422,7 @@ int _csr1212_read_keyval(struct csr1212_csr *csr, struct csr1212_keyval *kv)
if (!cache) { if (!cache) {
csr1212_quad_t q; csr1212_quad_t q;
struct csr1212_csr_rom_cache *nc; u_int32_t cache_size;
/* Only create a new cache for Extended ROM leaves. */ /* Only create a new cache for Extended ROM leaves. */
if (kv->key.id != CSR1212_KV_ID_EXTENDED_ROM) if (kv->key.id != CSR1212_KV_ID_EXTENDED_ROM)
...@@ -1425,12 +1434,20 @@ int _csr1212_read_keyval(struct csr1212_csr *csr, struct csr1212_keyval *kv) ...@@ -1425,12 +1434,20 @@ int _csr1212_read_keyval(struct csr1212_csr *csr, struct csr1212_keyval *kv)
return CSR1212_EIO; return CSR1212_EIO;
} }
kv->value.leaf.len = quads_to_bytes(CSR1212_BE32_TO_CPU(q)>>16); kv->value.leaf.len = CSR1212_BE32_TO_CPU(q) >> 16;
cache_size = (quads_to_bytes(kv->value.leaf.len + 1) +
(csr->max_rom - 1)) & ~(csr->max_rom - 1);
nc = csr1212_rom_cache_malloc(kv->offset, kv->value.leaf.len); cache = csr1212_rom_cache_malloc(kv->offset, cache_size);
cache->next = nc; if (!cache)
nc->prev = cache; return CSR1212_ENOMEM;
csr->cache_tail = nc;
kv->value.leaf.data = &cache->data[1];
csr->cache_tail->next = cache;
cache->prev = csr->cache_tail;
cache->next = NULL;
csr->cache_tail = cache;
cache->filled_head = cache->filled_head =
CSR1212_MALLOC(sizeof(struct csr1212_cache_region)); CSR1212_MALLOC(sizeof(struct csr1212_cache_region));
if (!cache->filled_head) { if (!cache->filled_head) {
...@@ -1443,6 +1460,10 @@ int _csr1212_read_keyval(struct csr1212_csr *csr, struct csr1212_keyval *kv) ...@@ -1443,6 +1460,10 @@ int _csr1212_read_keyval(struct csr1212_csr *csr, struct csr1212_keyval *kv)
cache->filled_head->next = NULL; cache->filled_head->next = NULL;
cache->filled_head->prev = NULL; cache->filled_head->prev = NULL;
cache->data[0] = q; cache->data[0] = q;
/* Don't read the entire extended ROM now. Pieces of it will
* be read when entries inside it are read. */
return csr1212_parse_keyval(kv, cache);
} }
cache_index = kv->offset - cache->offset; cache_index = kv->offset - cache->offset;
...@@ -1548,6 +1569,7 @@ int _csr1212_read_keyval(struct csr1212_csr *csr, struct csr1212_keyval *kv) ...@@ -1548,6 +1569,7 @@ int _csr1212_read_keyval(struct csr1212_csr *csr, struct csr1212_keyval *kv)
int csr1212_parse_csr(struct csr1212_csr *csr) int csr1212_parse_csr(struct csr1212_csr *csr)
{ {
static const int mr_map[] = { 4, 64, 1024, 0 }; static const int mr_map[] = { 4, 64, 1024, 0 };
struct csr1212_dentry *dentry;
int ret; int ret;
if (!csr || !csr->ops->bus_read) if (!csr || !csr->ops->bus_read)
...@@ -1570,7 +1592,21 @@ int csr1212_parse_csr(struct csr1212_csr *csr) ...@@ -1570,7 +1592,21 @@ int csr1212_parse_csr(struct csr1212_csr *csr)
csr->bus_info_len; csr->bus_info_len;
csr->root_kv->valid = 0; csr->root_kv->valid = 0;
csr->root_kv->next = csr->root_kv;
csr->root_kv->prev = csr->root_kv;
csr1212_get_keyval(csr, csr->root_kv); csr1212_get_keyval(csr, csr->root_kv);
/* Scan through the Root directory finding all extended ROM regions
* and make cache regions for them */
for (dentry = csr->root_kv->value.directory.dentries_head;
dentry; dentry = dentry->next) {
if (dentry->kv->key.id == CSR1212_KV_ID_EXTENDED_ROM) {
csr1212_get_keyval(csr, dentry->kv);
if (ret != CSR1212_SUCCESS)
return ret;
}
}
return CSR1212_SUCCESS; return CSR1212_SUCCESS;
} }
...@@ -127,16 +127,12 @@ void dma_region_free(struct dma_region *dma) ...@@ -127,16 +127,12 @@ void dma_region_free(struct dma_region *dma)
dma->dev = NULL; dma->dev = NULL;
} }
if (dma->sglist) {
vfree(dma->sglist); vfree(dma->sglist);
dma->sglist = NULL; dma->sglist = NULL;
}
if (dma->kvirt) {
vfree(dma->kvirt); vfree(dma->kvirt);
dma->kvirt = NULL; dma->kvirt = NULL;
dma->n_pages = 0; dma->n_pages = 0;
}
} }
/* find the scatterlist index and remaining offset corresponding to a /* find the scatterlist index and remaining offset corresponding to a
......
...@@ -1277,7 +1277,7 @@ static void do_dv1394_shutdown(struct video_card *video, int free_dv_buf) ...@@ -1277,7 +1277,7 @@ static void do_dv1394_shutdown(struct video_card *video, int free_dv_buf)
error-prone code in dv1394. error-prone code in dv1394.
*/ */
int dv1394_mmap(struct file *file, struct vm_area_struct *vma) static int dv1394_mmap(struct file *file, struct vm_area_struct *vma)
{ {
struct video_card *video = file_to_video_card(file); struct video_card *video = file_to_video_card(file);
int retval = -EINVAL; int retval = -EINVAL;
...@@ -2343,6 +2343,8 @@ static void dv1394_remove_host (struct hpsb_host *host) ...@@ -2343,6 +2343,8 @@ static void dv1394_remove_host (struct hpsb_host *host)
dv1394_un_init(video); dv1394_un_init(video);
} while (video != NULL); } while (video != NULL);
class_simple_device_remove(MKDEV(
IEEE1394_MAJOR, IEEE1394_MINOR_BLOCK_DV1394 * 16 + (id<<2)));
devfs_remove("ieee1394/dv/host%d/NTSC", id); devfs_remove("ieee1394/dv/host%d/NTSC", id);
devfs_remove("ieee1394/dv/host%d/PAL", id); devfs_remove("ieee1394/dv/host%d/PAL", id);
devfs_remove("ieee1394/dv/host%d", id); devfs_remove("ieee1394/dv/host%d", id);
...@@ -2359,6 +2361,9 @@ static void dv1394_add_host (struct hpsb_host *host) ...@@ -2359,6 +2361,9 @@ static void dv1394_add_host (struct hpsb_host *host)
ohci = (struct ti_ohci *)host->hostdata; ohci = (struct ti_ohci *)host->hostdata;
class_simple_device_add(hpsb_protocol_class, MKDEV(
IEEE1394_MAJOR, IEEE1394_MINOR_BLOCK_DV1394 * 16 + (id<<2)),
NULL, "dv1394-%d", id);
devfs_mk_dir("ieee1394/dv/host%d", id); devfs_mk_dir("ieee1394/dv/host%d", id);
devfs_mk_dir("ieee1394/dv/host%d/NTSC", id); devfs_mk_dir("ieee1394/dv/host%d/NTSC", id);
devfs_mk_dir("ieee1394/dv/host%d/PAL", id); devfs_mk_dir("ieee1394/dv/host%d/PAL", id);
......
...@@ -89,7 +89,7 @@ ...@@ -89,7 +89,7 @@
#define TRACE() printk(KERN_ERR "%s:%s[%d] ---- TRACE\n", driver_name, __FUNCTION__, __LINE__) #define TRACE() printk(KERN_ERR "%s:%s[%d] ---- TRACE\n", driver_name, __FUNCTION__, __LINE__)
static char version[] __devinitdata = static char version[] __devinitdata =
"$Rev: 1224 $ Ben Collins <bcollins@debian.org>"; "$Rev: 1247 $ Ben Collins <bcollins@debian.org>";
struct fragment_info { struct fragment_info {
struct list_head list; struct list_head list;
...@@ -165,8 +165,7 @@ MODULE_LICENSE("GPL"); ...@@ -165,8 +165,7 @@ MODULE_LICENSE("GPL");
/* The max_partial_datagrams parameter is the maximum number of fragmented /* The max_partial_datagrams parameter is the maximum number of fragmented
* datagrams per node that eth1394 will keep in memory. Providing an upper * datagrams per node that eth1394 will keep in memory. Providing an upper
* bound allows us to limit the amount of memory that partial datagrams * bound allows us to limit the amount of memory that partial datagrams
* consume in the event that some partial datagrams are never completed. This * consume in the event that some partial datagrams are never completed.
* should probably change to a sysctl item or the like if possible.
*/ */
static int max_partial_datagrams = 25; static int max_partial_datagrams = 25;
module_param(max_partial_datagrams, int, S_IRUGO | S_IWUSR); module_param(max_partial_datagrams, int, S_IRUGO | S_IWUSR);
...@@ -186,7 +185,7 @@ static void ether1394_header_cache_update(struct hh_cache *hh, ...@@ -186,7 +185,7 @@ static void ether1394_header_cache_update(struct hh_cache *hh,
unsigned char * haddr); unsigned char * haddr);
static int ether1394_mac_addr(struct net_device *dev, void *p); static int ether1394_mac_addr(struct net_device *dev, void *p);
static inline void purge_partial_datagram(struct list_head *old); static void purge_partial_datagram(struct list_head *old);
static int ether1394_tx(struct sk_buff *skb, struct net_device *dev); static int ether1394_tx(struct sk_buff *skb, struct net_device *dev);
static void ether1394_iso(struct hpsb_iso *iso); static void ether1394_iso(struct hpsb_iso *iso);
...@@ -289,7 +288,7 @@ static int ether1394_change_mtu(struct net_device *dev, int new_mtu) ...@@ -289,7 +288,7 @@ static int ether1394_change_mtu(struct net_device *dev, int new_mtu)
return 0; return 0;
} }
static inline void purge_partial_datagram(struct list_head *old) static void purge_partial_datagram(struct list_head *old)
{ {
struct partial_datagram *pd = list_entry(old, struct partial_datagram, list); struct partial_datagram *pd = list_entry(old, struct partial_datagram, list);
struct list_head *lh, *n; struct list_head *lh, *n;
...@@ -1187,7 +1186,7 @@ static int ether1394_data_handler(struct net_device *dev, int srcid, int destid, ...@@ -1187,7 +1186,7 @@ static int ether1394_data_handler(struct net_device *dev, int srcid, int destid,
lh = find_partial_datagram(pdgl, dgl); lh = find_partial_datagram(pdgl, dgl);
if (lh == NULL) { if (lh == NULL) {
if (pdg->sz == max_partial_datagrams) { while (pdg->sz >= max_partial_datagrams) {
/* remove the oldest */ /* remove the oldest */
purge_partial_datagram(pdgl->prev); purge_partial_datagram(pdgl->prev);
pdg->sz--; pdg->sz--;
...@@ -1771,7 +1770,7 @@ static int ether1394_tx (struct sk_buff *skb, struct net_device *dev) ...@@ -1771,7 +1770,7 @@ static int ether1394_tx (struct sk_buff *skb, struct net_device *dev)
static void ether1394_get_drvinfo(struct net_device *dev, struct ethtool_drvinfo *info) static void ether1394_get_drvinfo(struct net_device *dev, struct ethtool_drvinfo *info)
{ {
strcpy (info->driver, driver_name); strcpy (info->driver, driver_name);
strcpy (info->version, "$Rev: 1224 $"); strcpy (info->version, "$Rev: 1247 $");
/* FIXME XXX provide sane businfo */ /* FIXME XXX provide sane businfo */
strcpy (info->bus_info, "ieee1394"); strcpy (info->bus_info, "ieee1394");
} }
......
...@@ -173,18 +173,6 @@ void hpsb_set_hostinfo_key(struct hpsb_highlevel *hl, struct hpsb_host *host, un ...@@ -173,18 +173,6 @@ void hpsb_set_hostinfo_key(struct hpsb_highlevel *hl, struct hpsb_host *host, un
} }
unsigned long hpsb_get_hostinfo_key(struct hpsb_highlevel *hl, struct hpsb_host *host)
{
struct hl_host_info *hi;
hi = hl_get_hostinfo(hl, host);
if (hi)
return hi->key;
return 0;
}
void *hpsb_get_hostinfo_bykey(struct hpsb_highlevel *hl, unsigned long key) void *hpsb_get_hostinfo_bykey(struct hpsb_highlevel *hl, unsigned long key)
{ {
struct hl_host_info *hi; struct hl_host_info *hi;
...@@ -206,26 +194,6 @@ void *hpsb_get_hostinfo_bykey(struct hpsb_highlevel *hl, unsigned long key) ...@@ -206,26 +194,6 @@ void *hpsb_get_hostinfo_bykey(struct hpsb_highlevel *hl, unsigned long key)
} }
struct hpsb_host *hpsb_get_host_bykey(struct hpsb_highlevel *hl, unsigned long key)
{
struct hl_host_info *hi;
struct hpsb_host *host = NULL;
if (!hl)
return NULL;
read_lock(&hl->host_info_lock);
list_for_each_entry(hi, &hl->host_info_list, list) {
if (hi->key == key) {
host = hi->host;
break;
}
}
read_unlock(&hl->host_info_lock);
return host;
}
static int highlevel_for_each_host_reg(struct hpsb_host *host, void *__data) static int highlevel_for_each_host_reg(struct hpsb_host *host, void *__data)
{ {
struct hpsb_highlevel *hl = __data; struct hpsb_highlevel *hl = __data;
...@@ -416,7 +384,7 @@ int hpsb_register_addrspace(struct hpsb_highlevel *hl, struct hpsb_host *host, ...@@ -416,7 +384,7 @@ int hpsb_register_addrspace(struct hpsb_highlevel *hl, struct hpsb_host *host,
} }
as = (struct hpsb_address_serve *) as = (struct hpsb_address_serve *)
kmalloc(sizeof(struct hpsb_address_serve), GFP_KERNEL); kmalloc(sizeof(struct hpsb_address_serve), GFP_ATOMIC);
if (as == NULL) { if (as == NULL) {
return 0; return 0;
} }
......
...@@ -77,6 +77,30 @@ extern const char *hpsb_speedto_str[]; ...@@ -77,6 +77,30 @@ extern const char *hpsb_speedto_str[];
#define SELFID_PORT_NONE 0x0 #define SELFID_PORT_NONE 0x0
/* 1394a PHY bitmasks */
#define PHY_00_PHYSICAL_ID 0xFC
#define PHY_00_R 0x02 /* Root */
#define PHY_00_PS 0x01 /* Power Status*/
#define PHY_01_RHB 0x80 /* Root Hold-Off */
#define PHY_01_IBR 0x80 /* Initiate Bus Reset */
#define PHY_01_GAP_COUNT 0x3F
#define PHY_02_EXTENDED 0xE0 /* 0x7 for 1394a-compliant PHY */
#define PHY_02_TOTAL_PORTS 0x1F
#define PHY_03_MAX_SPEED 0xE0
#define PHY_03_DELAY 0x0F
#define PHY_04_LCTRL 0x80 /* Link Active Report Control */
#define PHY_04_CONTENDER 0x40
#define PHY_04_JITTER 0x38
#define PHY_04_PWR_CLASS 0x07 /* Power Class */
#define PHY_05_WATCHDOG 0x80
#define PHY_05_ISBR 0x40 /* Initiate Short Bus Reset */
#define PHY_05_LOOP 0x20 /* Loop Detect */
#define PHY_05_PWR_FAIL 0x10 /* Cable Power Failure Detect */
#define PHY_05_TIMEOUT 0x08 /* Arbitration State Machine Timeout */
#define PHY_05_PORT_EVENT 0x04 /* Port Event Detect */
#define PHY_05_ENAB_ACCEL 0x02 /* Enable Arbitration Acceleration */
#define PHY_05_ENAB_MULTI 0x01 /* Ena. Multispeed Packet Concatenation */
#include <asm/byteorder.h> #include <asm/byteorder.h>
#ifdef __BIG_ENDIAN_BITFIELD #ifdef __BIG_ENDIAN_BITFIELD
......
...@@ -56,11 +56,18 @@ static int disable_nodemgr = 0; ...@@ -56,11 +56,18 @@ static int disable_nodemgr = 0;
module_param(disable_nodemgr, int, 0444); module_param(disable_nodemgr, int, 0444);
MODULE_PARM_DESC(disable_nodemgr, "Disable nodemgr functionality."); MODULE_PARM_DESC(disable_nodemgr, "Disable nodemgr functionality.");
/* Disable Isochronous Resource Manager functionality */
int hpsb_disable_irm = 0;
module_param_named(disable_irm, hpsb_disable_irm, bool, 0);
MODULE_PARM_DESC(disable_irm,
"Disable Isochronous Resource Manager functionality.");
/* We are GPL, so treat us special */ /* We are GPL, so treat us special */
MODULE_LICENSE("GPL"); MODULE_LICENSE("GPL");
/* Some globals used */ /* Some globals used */
const char *hpsb_speedto_str[] = { "S100", "S200", "S400", "S800", "S1600", "S3200" }; const char *hpsb_speedto_str[] = { "S100", "S200", "S400", "S800", "S1600", "S3200" };
struct class_simple *hpsb_protocol_class;
#ifdef CONFIG_IEEE1394_VERBOSEDEBUG #ifdef CONFIG_IEEE1394_VERBOSEDEBUG
static void dump_packet(const char *text, quadlet_t *data, int size) static void dump_packet(const char *text, quadlet_t *data, int size)
...@@ -79,6 +86,7 @@ static void dump_packet(const char *text, quadlet_t *data, int size) ...@@ -79,6 +86,7 @@ static void dump_packet(const char *text, quadlet_t *data, int size)
#define dump_packet(x,y,z) #define dump_packet(x,y,z)
#endif #endif
static void abort_requests(struct hpsb_host *host);
static void queue_packet_complete(struct hpsb_packet *packet); static void queue_packet_complete(struct hpsb_packet *packet);
...@@ -512,6 +520,7 @@ int hpsb_send_packet(struct hpsb_packet *packet) ...@@ -512,6 +520,7 @@ int hpsb_send_packet(struct hpsb_packet *packet)
if (!packet->no_waiter || packet->expect_response) { if (!packet->no_waiter || packet->expect_response) {
atomic_inc(&packet->refcnt); atomic_inc(&packet->refcnt);
packet->sendtime = jiffies;
skb_queue_tail(&host->pending_packet_queue, packet->skb); skb_queue_tail(&host->pending_packet_queue, packet->skb);
} }
...@@ -939,7 +948,7 @@ void hpsb_packet_received(struct hpsb_host *host, quadlet_t *data, size_t size, ...@@ -939,7 +948,7 @@ void hpsb_packet_received(struct hpsb_host *host, quadlet_t *data, size_t size,
} }
void abort_requests(struct hpsb_host *host) static void abort_requests(struct hpsb_host *host)
{ {
struct hpsb_packet *packet; struct hpsb_packet *packet;
struct sk_buff *skb; struct sk_buff *skb;
...@@ -1002,7 +1011,7 @@ void abort_timedouts(unsigned long __opaque) ...@@ -1002,7 +1011,7 @@ void abort_timedouts(unsigned long __opaque)
* the stack. */ * the stack. */
static int khpsbpkt_pid = -1, khpsbpkt_kill; static int khpsbpkt_pid = -1, khpsbpkt_kill;
static DECLARE_COMPLETION(khpsbpkt_complete); static DECLARE_COMPLETION(khpsbpkt_complete);
struct sk_buff_head hpsbpkt_queue; static struct sk_buff_head hpsbpkt_queue;
static DECLARE_MUTEX_LOCKED(khpsbpkt_sig); static DECLARE_MUTEX_LOCKED(khpsbpkt_sig);
...@@ -1030,14 +1039,18 @@ static int hpsbpkt_thread(void *__hi) ...@@ -1030,14 +1039,18 @@ static int hpsbpkt_thread(void *__hi)
daemonize("khpsbpkt"); daemonize("khpsbpkt");
while (!down_interruptible(&khpsbpkt_sig)) { while (1) {
if (khpsbpkt_kill) if (down_interruptible(&khpsbpkt_sig)) {
break;
if (current->flags & PF_FREEZE) { if (current->flags & PF_FREEZE) {
refrigerator(0); refrigerator(0);
continue; continue;
} }
printk("khpsbpkt: received unexpected signal?!\n" );
break;
}
if (khpsbpkt_kill)
break;
while ((skb = skb_dequeue(&hpsbpkt_queue)) != NULL) { while ((skb = skb_dequeue(&hpsbpkt_queue)) != NULL) {
packet = (struct hpsb_packet *)skb->data; packet = (struct hpsb_packet *)skb->data;
...@@ -1054,7 +1067,6 @@ static int hpsbpkt_thread(void *__hi) ...@@ -1054,7 +1067,6 @@ static int hpsbpkt_thread(void *__hi)
complete_and_exit(&khpsbpkt_complete, 0); complete_and_exit(&khpsbpkt_complete, 0);
} }
static int __init ieee1394_init(void) static int __init ieee1394_init(void)
{ {
int i, ret; int i, ret;
...@@ -1109,18 +1121,33 @@ static int __init ieee1394_init(void) ...@@ -1109,18 +1121,33 @@ static int __init ieee1394_init(void)
if (ret < 0) if (ret < 0)
goto release_all_bus; goto release_all_bus;
hpsb_protocol_class = class_simple_create(THIS_MODULE, "ieee1394_protocol");
if (IS_ERR(hpsb_protocol_class)) {
ret = PTR_ERR(hpsb_protocol_class);
goto release_class_host;
}
ret = init_csr(); ret = init_csr();
if (ret) { if (ret) {
HPSB_INFO("init csr failed"); HPSB_INFO("init csr failed");
ret = -ENOMEM; ret = -ENOMEM;
goto release_class; goto release_class_protocol;
} }
if (disable_nodemgr) { if (disable_nodemgr) {
HPSB_INFO("nodemgr functionality disabled"); HPSB_INFO("nodemgr and IRM functionality disabled");
/* We shouldn't contend for IRM with nodemgr disabled, since
nodemgr implements functionality required of ieee1394a-2000
IRMs */
hpsb_disable_irm = 1;
return 0; return 0;
} }
if (hpsb_disable_irm) {
HPSB_INFO("IRM functionality disabled");
}
ret = init_ieee1394_nodemgr(); ret = init_ieee1394_nodemgr();
if (ret < 0) { if (ret < 0) {
HPSB_INFO("init nodemgr failed"); HPSB_INFO("init nodemgr failed");
...@@ -1131,7 +1158,9 @@ static int __init ieee1394_init(void) ...@@ -1131,7 +1158,9 @@ static int __init ieee1394_init(void)
cleanup_csr: cleanup_csr:
cleanup_csr(); cleanup_csr();
release_class: release_class_protocol:
class_simple_destroy(hpsb_protocol_class);
release_class_host:
class_unregister(&hpsb_host_class); class_unregister(&hpsb_host_class);
release_all_bus: release_all_bus:
for (i = 0; fw_bus_attrs[i]; i++) for (i = 0; fw_bus_attrs[i]; i++)
...@@ -1160,6 +1189,7 @@ static void __exit ieee1394_cleanup(void) ...@@ -1160,6 +1189,7 @@ static void __exit ieee1394_cleanup(void)
cleanup_csr(); cleanup_csr();
class_simple_destroy(hpsb_protocol_class);
class_unregister(&hpsb_host_class); class_unregister(&hpsb_host_class);
for (i = 0; fw_bus_attrs[i]; i++) for (i = 0; fw_bus_attrs[i]; i++)
bus_remove_file(&ieee1394_bus_type, fw_bus_attrs[i]); bus_remove_file(&ieee1394_bus_type, fw_bus_attrs[i]);
...@@ -1191,6 +1221,7 @@ EXPORT_SYMBOL(hpsb_update_config_rom_image); ...@@ -1191,6 +1221,7 @@ EXPORT_SYMBOL(hpsb_update_config_rom_image);
/** ieee1394_core.c **/ /** ieee1394_core.c **/
EXPORT_SYMBOL(hpsb_speedto_str); EXPORT_SYMBOL(hpsb_speedto_str);
EXPORT_SYMBOL(hpsb_protocol_class);
EXPORT_SYMBOL(hpsb_set_packet_complete_task); EXPORT_SYMBOL(hpsb_set_packet_complete_task);
EXPORT_SYMBOL(hpsb_alloc_packet); EXPORT_SYMBOL(hpsb_alloc_packet);
EXPORT_SYMBOL(hpsb_free_packet); EXPORT_SYMBOL(hpsb_free_packet);
...@@ -1203,6 +1234,7 @@ EXPORT_SYMBOL(hpsb_selfid_received); ...@@ -1203,6 +1234,7 @@ EXPORT_SYMBOL(hpsb_selfid_received);
EXPORT_SYMBOL(hpsb_selfid_complete); EXPORT_SYMBOL(hpsb_selfid_complete);
EXPORT_SYMBOL(hpsb_packet_sent); EXPORT_SYMBOL(hpsb_packet_sent);
EXPORT_SYMBOL(hpsb_packet_received); EXPORT_SYMBOL(hpsb_packet_received);
EXPORT_SYMBOL_GPL(hpsb_disable_irm);
/** ieee1394_transactions.c **/ /** ieee1394_transactions.c **/
EXPORT_SYMBOL(hpsb_get_tlabel); EXPORT_SYMBOL(hpsb_get_tlabel);
...@@ -1217,8 +1249,6 @@ EXPORT_SYMBOL(hpsb_make_isopacket); ...@@ -1217,8 +1249,6 @@ EXPORT_SYMBOL(hpsb_make_isopacket);
EXPORT_SYMBOL(hpsb_read); EXPORT_SYMBOL(hpsb_read);
EXPORT_SYMBOL(hpsb_write); EXPORT_SYMBOL(hpsb_write);
EXPORT_SYMBOL(hpsb_lock); EXPORT_SYMBOL(hpsb_lock);
EXPORT_SYMBOL(hpsb_lock64);
EXPORT_SYMBOL(hpsb_send_gasp);
EXPORT_SYMBOL(hpsb_packet_success); EXPORT_SYMBOL(hpsb_packet_success);
/** highlevel.c **/ /** highlevel.c **/
...@@ -1230,28 +1260,18 @@ EXPORT_SYMBOL(hpsb_allocate_and_register_addrspace); ...@@ -1230,28 +1260,18 @@ EXPORT_SYMBOL(hpsb_allocate_and_register_addrspace);
EXPORT_SYMBOL(hpsb_listen_channel); EXPORT_SYMBOL(hpsb_listen_channel);
EXPORT_SYMBOL(hpsb_unlisten_channel); EXPORT_SYMBOL(hpsb_unlisten_channel);
EXPORT_SYMBOL(hpsb_get_hostinfo); EXPORT_SYMBOL(hpsb_get_hostinfo);
EXPORT_SYMBOL(hpsb_get_host_bykey);
EXPORT_SYMBOL(hpsb_create_hostinfo); EXPORT_SYMBOL(hpsb_create_hostinfo);
EXPORT_SYMBOL(hpsb_destroy_hostinfo); EXPORT_SYMBOL(hpsb_destroy_hostinfo);
EXPORT_SYMBOL(hpsb_set_hostinfo_key); EXPORT_SYMBOL(hpsb_set_hostinfo_key);
EXPORT_SYMBOL(hpsb_get_hostinfo_key);
EXPORT_SYMBOL(hpsb_get_hostinfo_bykey); EXPORT_SYMBOL(hpsb_get_hostinfo_bykey);
EXPORT_SYMBOL(hpsb_set_hostinfo); EXPORT_SYMBOL(hpsb_set_hostinfo);
EXPORT_SYMBOL(highlevel_read);
EXPORT_SYMBOL(highlevel_write);
EXPORT_SYMBOL(highlevel_lock);
EXPORT_SYMBOL(highlevel_lock64);
EXPORT_SYMBOL(highlevel_add_host); EXPORT_SYMBOL(highlevel_add_host);
EXPORT_SYMBOL(highlevel_remove_host); EXPORT_SYMBOL(highlevel_remove_host);
EXPORT_SYMBOL(highlevel_host_reset); EXPORT_SYMBOL(highlevel_host_reset);
/** nodemgr.c **/ /** nodemgr.c **/
EXPORT_SYMBOL(hpsb_guid_get_entry);
EXPORT_SYMBOL(hpsb_nodeid_get_entry);
EXPORT_SYMBOL(hpsb_node_fill_packet); EXPORT_SYMBOL(hpsb_node_fill_packet);
EXPORT_SYMBOL(hpsb_node_read);
EXPORT_SYMBOL(hpsb_node_write); EXPORT_SYMBOL(hpsb_node_write);
EXPORT_SYMBOL(hpsb_node_lock);
EXPORT_SYMBOL(hpsb_register_protocol); EXPORT_SYMBOL(hpsb_register_protocol);
EXPORT_SYMBOL(hpsb_unregister_protocol); EXPORT_SYMBOL(hpsb_unregister_protocol);
EXPORT_SYMBOL(ieee1394_bus_type); EXPORT_SYMBOL(ieee1394_bus_type);
...@@ -1295,27 +1315,14 @@ EXPORT_SYMBOL(hpsb_iso_recv_flush); ...@@ -1295,27 +1315,14 @@ EXPORT_SYMBOL(hpsb_iso_recv_flush);
EXPORT_SYMBOL(csr1212_create_csr); EXPORT_SYMBOL(csr1212_create_csr);
EXPORT_SYMBOL(csr1212_init_local_csr); EXPORT_SYMBOL(csr1212_init_local_csr);
EXPORT_SYMBOL(csr1212_new_immediate); EXPORT_SYMBOL(csr1212_new_immediate);
EXPORT_SYMBOL(csr1212_new_leaf);
EXPORT_SYMBOL(csr1212_new_csr_offset);
EXPORT_SYMBOL(csr1212_new_directory); EXPORT_SYMBOL(csr1212_new_directory);
EXPORT_SYMBOL(csr1212_associate_keyval); EXPORT_SYMBOL(csr1212_associate_keyval);
EXPORT_SYMBOL(csr1212_attach_keyval_to_directory); EXPORT_SYMBOL(csr1212_attach_keyval_to_directory);
EXPORT_SYMBOL(csr1212_new_extended_immediate);
EXPORT_SYMBOL(csr1212_new_extended_leaf);
EXPORT_SYMBOL(csr1212_new_descriptor_leaf);
EXPORT_SYMBOL(csr1212_new_textual_descriptor_leaf);
EXPORT_SYMBOL(csr1212_new_string_descriptor_leaf); EXPORT_SYMBOL(csr1212_new_string_descriptor_leaf);
EXPORT_SYMBOL(csr1212_new_icon_descriptor_leaf);
EXPORT_SYMBOL(csr1212_new_modifiable_descriptor_leaf);
EXPORT_SYMBOL(csr1212_new_keyword_leaf);
EXPORT_SYMBOL(csr1212_detach_keyval_from_directory); EXPORT_SYMBOL(csr1212_detach_keyval_from_directory);
EXPORT_SYMBOL(csr1212_disassociate_keyval);
EXPORT_SYMBOL(csr1212_release_keyval); EXPORT_SYMBOL(csr1212_release_keyval);
EXPORT_SYMBOL(csr1212_destroy_csr); EXPORT_SYMBOL(csr1212_destroy_csr);
EXPORT_SYMBOL(csr1212_read); EXPORT_SYMBOL(csr1212_read);
EXPORT_SYMBOL(csr1212_generate_positions);
EXPORT_SYMBOL(csr1212_generate_layout_order);
EXPORT_SYMBOL(csr1212_fill_cache);
EXPORT_SYMBOL(csr1212_generate_csr_image); EXPORT_SYMBOL(csr1212_generate_csr_image);
EXPORT_SYMBOL(csr1212_parse_keyval); EXPORT_SYMBOL(csr1212_parse_keyval);
EXPORT_SYMBOL(csr1212_parse_csr); EXPORT_SYMBOL(csr1212_parse_csr);
......
...@@ -89,7 +89,6 @@ static inline struct hpsb_packet *driver_packet(struct list_head *l) ...@@ -89,7 +89,6 @@ static inline struct hpsb_packet *driver_packet(struct list_head *l)
} }
void abort_timedouts(unsigned long __opaque); void abort_timedouts(unsigned long __opaque);
void abort_requests(struct hpsb_host *host);
struct hpsb_packet *hpsb_alloc_packet(size_t data_size); struct hpsb_packet *hpsb_alloc_packet(size_t data_size);
void hpsb_free_packet(struct hpsb_packet *packet); void hpsb_free_packet(struct hpsb_packet *packet);
...@@ -219,9 +218,11 @@ static inline unsigned char ieee1394_file_to_instance(struct file *file) ...@@ -219,9 +218,11 @@ static inline unsigned char ieee1394_file_to_instance(struct file *file)
return file->f_dentry->d_inode->i_cindex; return file->f_dentry->d_inode->i_cindex;
} }
extern int hpsb_disable_irm;
/* Our sysfs bus entry */ /* Our sysfs bus entry */
extern struct bus_type ieee1394_bus_type; extern struct bus_type ieee1394_bus_type;
extern struct class hpsb_host_class; extern struct class hpsb_host_class;
extern struct class_simple *hpsb_protocol_class;
#endif /* _IEEE1394_CORE_H */ #endif /* _IEEE1394_CORE_H */
...@@ -566,34 +566,6 @@ int hpsb_lock(struct hpsb_host *host, nodeid_t node, unsigned int generation, ...@@ -566,34 +566,6 @@ int hpsb_lock(struct hpsb_host *host, nodeid_t node, unsigned int generation,
return retval; return retval;
} }
int hpsb_lock64(struct hpsb_host *host, nodeid_t node, unsigned int generation,
u64 addr, int extcode, octlet_t *data, octlet_t arg)
{
struct hpsb_packet *packet;
int retval = 0;
BUG_ON(in_interrupt()); // We can't be called in an interrupt, yet
packet = hpsb_make_lock64packet(host, node, addr, extcode, data, arg);
if (!packet)
return -ENOMEM;
packet->generation = generation;
retval = hpsb_send_packet_and_wait(packet);
if (retval < 0)
goto hpsb_lock64_fail;
retval = hpsb_packet_success(packet);
if (retval == 0)
*data = (u64)packet->data[1] << 32 | packet->data[0];
hpsb_lock64_fail:
hpsb_free_tlabel(packet);
hpsb_free_packet(packet);
return retval;
}
int hpsb_send_gasp(struct hpsb_host *host, int channel, unsigned int generation, int hpsb_send_gasp(struct hpsb_host *host, int channel, unsigned int generation,
quadlet_t *buffer, size_t length, u32 specifier_id, quadlet_t *buffer, size_t length, u32 specifier_id,
......
...@@ -23,6 +23,7 @@ ...@@ -23,6 +23,7 @@
#include "ieee1394_types.h" #include "ieee1394_types.h"
#include "ieee1394.h" #include "ieee1394.h"
#include "ieee1394_core.h"
#include "hosts.h" #include "hosts.h"
#include "ieee1394_transactions.h" #include "ieee1394_transactions.h"
#include "highlevel.h" #include "highlevel.h"
...@@ -146,7 +147,7 @@ static void ne_cls_release(struct class_device *class_dev) ...@@ -146,7 +147,7 @@ static void ne_cls_release(struct class_device *class_dev)
put_device(&container_of((class_dev), struct node_entry, class_dev)->device); put_device(&container_of((class_dev), struct node_entry, class_dev)->device);
} }
struct class nodemgr_ne_class = { static struct class nodemgr_ne_class = {
.name = "ieee1394_node", .name = "ieee1394_node",
.release = ne_cls_release, .release = ne_cls_release,
}; };
...@@ -158,7 +159,7 @@ static void ud_cls_release(struct class_device *class_dev) ...@@ -158,7 +159,7 @@ static void ud_cls_release(struct class_device *class_dev)
/* The name here is only so that unit directory hotplug works with old /* The name here is only so that unit directory hotplug works with old
* style hotplug, which only ever did unit directories anyway. */ * style hotplug, which only ever did unit directories anyway. */
struct class nodemgr_ud_class = { static struct class nodemgr_ud_class = {
.name = "ieee1394", .name = "ieee1394",
.release = ud_cls_release, .release = ud_cls_release,
.hotplug = nodemgr_hotplug, .hotplug = nodemgr_hotplug,
...@@ -831,6 +832,31 @@ static struct node_entry *find_entry_by_nodeid(struct hpsb_host *host, nodeid_t ...@@ -831,6 +832,31 @@ static struct node_entry *find_entry_by_nodeid(struct hpsb_host *host, nodeid_t
} }
static void nodemgr_register_device(struct node_entry *ne,
struct unit_directory *ud, struct device *parent)
{
memcpy(&ud->device, &nodemgr_dev_template_ud,
sizeof(ud->device));
ud->device.parent = parent;
snprintf(ud->device.bus_id, BUS_ID_SIZE, "%s-%u",
ne->device.bus_id, ud->id);
ud->class_dev.dev = &ud->device;
ud->class_dev.class = &nodemgr_ud_class;
snprintf(ud->class_dev.class_id, BUS_ID_SIZE, "%s-%u",
ne->device.bus_id, ud->id);
device_register(&ud->device);
class_device_register(&ud->class_dev);
get_device(&ud->device);
if (ud->vendor_oui)
device_create_file(&ud->device, &dev_attr_ud_vendor_oui);
nodemgr_create_ud_dev_files(ud);
}
/* This implementation currently only scans the config rom and its /* This implementation currently only scans the config rom and its
* immediate unit directories looking for software_id and * immediate unit directories looking for software_id and
...@@ -840,7 +866,7 @@ static struct unit_directory *nodemgr_process_unit_directory ...@@ -840,7 +866,7 @@ static struct unit_directory *nodemgr_process_unit_directory
unsigned int *id, struct unit_directory *parent) unsigned int *id, struct unit_directory *parent)
{ {
struct unit_directory *ud; struct unit_directory *ud;
struct unit_directory *ud_temp = NULL; struct unit_directory *ud_child = NULL;
struct csr1212_dentry *dentry; struct csr1212_dentry *dentry;
struct csr1212_keyval *kv; struct csr1212_keyval *kv;
u8 last_key_id = 0; u8 last_key_id = 0;
...@@ -907,42 +933,61 @@ static struct unit_directory *nodemgr_process_unit_directory ...@@ -907,42 +933,61 @@ static struct unit_directory *nodemgr_process_unit_directory
break; break;
case CSR1212_KV_ID_DEPENDENT_INFO: case CSR1212_KV_ID_DEPENDENT_INFO:
if (kv->key.type == CSR1212_KV_TYPE_DIRECTORY) { /* Logical Unit Number */
if (kv->key.type == CSR1212_KV_TYPE_IMMEDIATE) {
if (ud->flags & UNIT_DIRECTORY_HAS_LUN) {
ud_child = kmalloc(sizeof(struct unit_directory), GFP_KERNEL);
if (!ud_child)
goto unit_directory_error;
memcpy(ud_child, ud, sizeof(struct unit_directory));
nodemgr_register_device(ne, ud_child, &ne->device);
ud_child = NULL;
ud->id = (*id)++;
}
ud->lun = kv->value.immediate;
ud->flags |= UNIT_DIRECTORY_HAS_LUN;
/* Logical Unit Directory */
} else if (kv->key.type == CSR1212_KV_TYPE_DIRECTORY) {
/* This should really be done in SBP2 as this is /* This should really be done in SBP2 as this is
* doing SBP2 specific parsing. */ * doing SBP2 specific parsing.
*/
/* first register the parent unit */
ud->flags |= UNIT_DIRECTORY_HAS_LUN_DIRECTORY; ud->flags |= UNIT_DIRECTORY_HAS_LUN_DIRECTORY;
ud_temp = nodemgr_process_unit_directory(hi, ne, kv, id, if (ud->device.bus != &ieee1394_bus_type)
parent); nodemgr_register_device(ne, ud, &ne->device);
/* process the child unit */
ud_child = nodemgr_process_unit_directory(hi, ne, kv, id, ud);
if (ud_temp == NULL) if (ud_child == NULL)
break; break;
/* inherit unspecified values */ /* inherit unspecified values so hotplug picks it up */
if ((ud->flags & UNIT_DIRECTORY_VENDOR_ID) &&
!(ud_temp->flags & UNIT_DIRECTORY_VENDOR_ID))
{
ud_temp->flags |= UNIT_DIRECTORY_VENDOR_ID;
ud_temp->vendor_id = ud->vendor_id;
ud_temp->vendor_oui = ud->vendor_oui;
}
if ((ud->flags & UNIT_DIRECTORY_MODEL_ID) && if ((ud->flags & UNIT_DIRECTORY_MODEL_ID) &&
!(ud_temp->flags & UNIT_DIRECTORY_MODEL_ID)) !(ud_child->flags & UNIT_DIRECTORY_MODEL_ID))
{ {
ud_temp->flags |= UNIT_DIRECTORY_MODEL_ID; ud_child->flags |= UNIT_DIRECTORY_MODEL_ID;
ud_temp->model_id = ud->model_id; ud_child->model_id = ud->model_id;
} }
if ((ud->flags & UNIT_DIRECTORY_SPECIFIER_ID) && if ((ud->flags & UNIT_DIRECTORY_SPECIFIER_ID) &&
!(ud_temp->flags & UNIT_DIRECTORY_SPECIFIER_ID)) !(ud_child->flags & UNIT_DIRECTORY_SPECIFIER_ID))
{ {
ud_temp->flags |= UNIT_DIRECTORY_SPECIFIER_ID; ud_child->flags |= UNIT_DIRECTORY_SPECIFIER_ID;
ud_temp->specifier_id = ud->specifier_id; ud_child->specifier_id = ud->specifier_id;
} }
if ((ud->flags & UNIT_DIRECTORY_VERSION) && if ((ud->flags & UNIT_DIRECTORY_VERSION) &&
!(ud_temp->flags & UNIT_DIRECTORY_VERSION)) !(ud_child->flags & UNIT_DIRECTORY_VERSION))
{ {
ud_temp->flags |= UNIT_DIRECTORY_VERSION; ud_child->flags |= UNIT_DIRECTORY_VERSION;
ud_temp->version = ud->version; ud_child->version = ud->version;
} }
/* register the child unit */
ud_child->flags |= UNIT_DIRECTORY_LUN_DIRECTORY;
nodemgr_register_device(ne, ud_child, &ud->device);
} }
break; break;
...@@ -953,30 +998,9 @@ static struct unit_directory *nodemgr_process_unit_directory ...@@ -953,30 +998,9 @@ static struct unit_directory *nodemgr_process_unit_directory
last_key_id = kv->key.id; last_key_id = kv->key.id;
} }
memcpy(&ud->device, &nodemgr_dev_template_ud, /* do not process child units here and only if not already registered */
sizeof(ud->device)); if (!parent && ud->device.bus != &ieee1394_bus_type)
nodemgr_register_device(ne, ud, &ne->device);
if (parent) {
ud->flags |= UNIT_DIRECTORY_LUN_DIRECTORY;
ud->device.parent = &parent->device;
} else
ud->device.parent = &ne->device;
snprintf(ud->device.bus_id, BUS_ID_SIZE, "%s-%u",
ne->device.bus_id, ud->id);
ud->class_dev.dev = &ud->device;
ud->class_dev.class = &nodemgr_ud_class;
snprintf(ud->class_dev.class_id, BUS_ID_SIZE, "%s-%u",
ne->device.bus_id, ud->id);
device_register(&ud->device);
class_device_register(&ud->class_dev);
get_device(&ud->device);
if (ud->vendor_oui)
device_create_file(&ud->device, &dev_attr_ud_vendor_oui);
nodemgr_create_ud_dev_files(ud);
return ud; return ud;
...@@ -1141,6 +1165,13 @@ static void nodemgr_update_node(struct node_entry *ne, struct csr1212_csr *csr, ...@@ -1141,6 +1165,13 @@ static void nodemgr_update_node(struct node_entry *ne, struct csr1212_csr *csr,
/* Mark the node as new, so it gets re-probed */ /* Mark the node as new, so it gets re-probed */
ne->needs_probe = 1; ne->needs_probe = 1;
} else {
/* old cache is valid, so update its generation */
struct nodemgr_csr_info *ci = ne->csr->private;
ci->generation = generation;
/* free the partially filled now unneeded new cache */
kfree(csr->private);
csr1212_destroy_csr(csr);
} }
if (ne->in_limbo) if (ne->in_limbo)
...@@ -1431,7 +1462,7 @@ static int nodemgr_check_irm_capability(struct hpsb_host *host, int cycles) ...@@ -1431,7 +1462,7 @@ static int nodemgr_check_irm_capability(struct hpsb_host *host, int cycles)
quadlet_t bc; quadlet_t bc;
int status; int status;
if (host->is_irm) if (hpsb_disable_irm || host->is_irm)
return 1; return 1;
status = hpsb_read(host, LOCAL_BUS | (host->irm_id), status = hpsb_read(host, LOCAL_BUS | (host->irm_id),
...@@ -1553,29 +1584,6 @@ static int nodemgr_host_thread(void *__hi) ...@@ -1553,29 +1584,6 @@ static int nodemgr_host_thread(void *__hi)
complete_and_exit(&hi->exited, 0); complete_and_exit(&hi->exited, 0);
} }
struct node_entry *hpsb_guid_get_entry(u64 guid)
{
struct node_entry *ne;
down(&nodemgr_serialize);
ne = find_entry_by_guid(guid);
up(&nodemgr_serialize);
return ne;
}
struct node_entry *hpsb_nodeid_get_entry(struct hpsb_host *host, nodeid_t nodeid)
{
struct node_entry *ne;
down(&nodemgr_serialize);
ne = find_entry_by_nodeid(host, nodeid);
up(&nodemgr_serialize);
return ne;
}
int nodemgr_for_each_host(void *__data, int (*cb)(struct hpsb_host *, void *)) int nodemgr_for_each_host(void *__data, int (*cb)(struct hpsb_host *, void *))
{ {
struct class *class = &hpsb_host_class; struct class *class = &hpsb_host_class;
...@@ -1618,16 +1626,6 @@ void hpsb_node_fill_packet(struct node_entry *ne, struct hpsb_packet *pkt) ...@@ -1618,16 +1626,6 @@ void hpsb_node_fill_packet(struct node_entry *ne, struct hpsb_packet *pkt)
pkt->node_id = ne->nodeid; pkt->node_id = ne->nodeid;
} }
int hpsb_node_read(struct node_entry *ne, u64 addr,
quadlet_t *buffer, size_t length)
{
unsigned int generation = ne->generation;
barrier();
return hpsb_read(ne->host, ne->nodeid, generation,
addr, buffer, length);
}
int hpsb_node_write(struct node_entry *ne, u64 addr, int hpsb_node_write(struct node_entry *ne, u64 addr,
quadlet_t *buffer, size_t length) quadlet_t *buffer, size_t length)
{ {
...@@ -1638,16 +1636,6 @@ int hpsb_node_write(struct node_entry *ne, u64 addr, ...@@ -1638,16 +1636,6 @@ int hpsb_node_write(struct node_entry *ne, u64 addr,
addr, buffer, length); addr, buffer, length);
} }
int hpsb_node_lock(struct node_entry *ne, u64 addr,
int extcode, quadlet_t *data, quadlet_t arg)
{
unsigned int generation = ne->generation;
barrier();
return hpsb_lock(ne->host, ne->nodeid, generation,
addr, extcode, data, arg);
}
static void nodemgr_add_host(struct hpsb_host *host) static void nodemgr_add_host(struct hpsb_host *host)
{ {
struct host_info *hi; struct host_info *hi;
......
...@@ -51,6 +51,7 @@ struct bus_options { ...@@ -51,6 +51,7 @@ struct bus_options {
#define UNIT_DIRECTORY_VERSION 0x08 #define UNIT_DIRECTORY_VERSION 0x08
#define UNIT_DIRECTORY_HAS_LUN_DIRECTORY 0x10 #define UNIT_DIRECTORY_HAS_LUN_DIRECTORY 0x10
#define UNIT_DIRECTORY_LUN_DIRECTORY 0x20 #define UNIT_DIRECTORY_LUN_DIRECTORY 0x20
#define UNIT_DIRECTORY_HAS_LUN 0x40
/* /*
* A unit directory corresponds to a protocol supported by the * A unit directory corresponds to a protocol supported by the
...@@ -82,6 +83,7 @@ struct unit_directory { ...@@ -82,6 +83,7 @@ struct unit_directory {
struct class_device class_dev; struct class_device class_dev;
struct csr1212_keyval *ud_kv; struct csr1212_keyval *ud_kv;
u32 lun; /* logical unit number immediate value */
}; };
struct node_entry { struct node_entry {
......
...@@ -162,7 +162,7 @@ printk(level "%s: " fmt "\n" , OHCI1394_DRIVER_NAME , ## args) ...@@ -162,7 +162,7 @@ printk(level "%s: " fmt "\n" , OHCI1394_DRIVER_NAME , ## args)
printk(level "%s: fw-host%d: " fmt "\n" , OHCI1394_DRIVER_NAME, ohci->host->id , ## args) printk(level "%s: fw-host%d: " fmt "\n" , OHCI1394_DRIVER_NAME, ohci->host->id , ## args)
static char version[] __devinitdata = static char version[] __devinitdata =
"$Rev: 1223 $ Ben Collins <bcollins@debian.org>"; "$Rev: 1250 $ Ben Collins <bcollins@debian.org>";
/* Module Parameters */ /* Module Parameters */
static int phys_dma = 1; static int phys_dma = 1;
...@@ -482,7 +482,9 @@ static void ohci_initialize(struct ti_ohci *ohci) ...@@ -482,7 +482,9 @@ static void ohci_initialize(struct ti_ohci *ohci)
/* Put some defaults to these undefined bus options */ /* Put some defaults to these undefined bus options */
buf = reg_read(ohci, OHCI1394_BusOptions); buf = reg_read(ohci, OHCI1394_BusOptions);
buf |= 0xE0000000; /* Enable IRMC, CMC and ISC */ buf |= 0x60000000; /* Enable CMC and ISC */
if (!hpsb_disable_irm)
buf |= 0x80000000; /* Enable IRMC */
buf &= ~0x00ff0000; /* XXX: Set cyc_clk_acc to zero for now */ buf &= ~0x00ff0000; /* XXX: Set cyc_clk_acc to zero for now */
buf &= ~0x18000000; /* Disable PMC and BMC */ buf &= ~0x18000000; /* Disable PMC and BMC */
reg_write(ohci, OHCI1394_BusOptions, buf); reg_write(ohci, OHCI1394_BusOptions, buf);
...@@ -497,10 +499,12 @@ static void ohci_initialize(struct ti_ohci *ohci) ...@@ -497,10 +499,12 @@ static void ohci_initialize(struct ti_ohci *ohci)
reg_write(ohci, OHCI1394_LinkControlClear, 0xffffffff); reg_write(ohci, OHCI1394_LinkControlClear, 0xffffffff);
/* Enable cycle timer and cycle master and set the IRM /* Enable cycle timer and cycle master and set the IRM
* contender bit in our self ID packets. */ * contender bit in our self ID packets if appropriate. */
reg_write(ohci, OHCI1394_LinkControlSet, OHCI1394_LinkControl_CycleTimerEnable | reg_write(ohci, OHCI1394_LinkControlSet,
OHCI1394_LinkControl_CycleTimerEnable |
OHCI1394_LinkControl_CycleMaster); OHCI1394_LinkControl_CycleMaster);
set_phy_reg_mask(ohci, 4, 0xc0); set_phy_reg_mask(ohci, 4, PHY_04_LCTRL |
(hpsb_disable_irm ? 0 : PHY_04_CONTENDER));
/* Set up self-id dma buffer */ /* Set up self-id dma buffer */
reg_write(ohci, OHCI1394_SelfIDBuffer, ohci->selfid_buf_bus); reg_write(ohci, OHCI1394_SelfIDBuffer, ohci->selfid_buf_bus);
...@@ -516,12 +520,6 @@ static void ohci_initialize(struct ti_ohci *ohci) ...@@ -516,12 +520,6 @@ static void ohci_initialize(struct ti_ohci *ohci)
ohci->max_packet_size = ohci->max_packet_size =
1<<(((reg_read(ohci, OHCI1394_BusOptions)>>12)&0xf)+1); 1<<(((reg_read(ohci, OHCI1394_BusOptions)>>12)&0xf)+1);
if (ohci->max_packet_size < 512) {
HPSB_ERR("warning: Invalid max packet size of %d, setting to 512",
ohci->max_packet_size);
ohci->max_packet_size = 512;
}
/* Don't accept phy packets into AR request context */ /* Don't accept phy packets into AR request context */
reg_write(ohci, OHCI1394_LinkControlClear, 0x00000400); reg_write(ohci, OHCI1394_LinkControlClear, 0x00000400);
...@@ -2545,6 +2543,10 @@ static void insert_dma_buffer(struct dma_rcv_ctx *d, int idx) ...@@ -2545,6 +2543,10 @@ static void insert_dma_buffer(struct dma_rcv_ctx *d, int idx)
idx = (idx + d->num_desc - 1 ) % d->num_desc; idx = (idx + d->num_desc - 1 ) % d->num_desc;
d->prg_cpu[idx]->branchAddress |= le32_to_cpu(0x00000001); d->prg_cpu[idx]->branchAddress |= le32_to_cpu(0x00000001);
/* To avoid a race, ensure 1394 interface hardware sees the inserted
* context program descriptors before it sees the wakeup bit set. */
wmb();
/* wake up the dma context if necessary */ /* wake up the dma context if necessary */
if (!(reg_read(ohci, d->ctrlSet) & 0x400)) { if (!(reg_read(ohci, d->ctrlSet) & 0x400)) {
PRINT(KERN_INFO, PRINT(KERN_INFO,
......
...@@ -384,6 +384,7 @@ static quadlet_t generate_own_selfid(struct ti_lynx *lynx, ...@@ -384,6 +384,7 @@ static quadlet_t generate_own_selfid(struct ti_lynx *lynx,
lsid = 0x80400000 | ((phyreg[0] & 0xfc) << 22); lsid = 0x80400000 | ((phyreg[0] & 0xfc) << 22);
lsid |= (phyreg[1] & 0x3f) << 16; /* gap count */ lsid |= (phyreg[1] & 0x3f) << 16; /* gap count */
lsid |= (phyreg[2] & 0xc0) << 8; /* max speed */ lsid |= (phyreg[2] & 0xc0) << 8; /* max speed */
if (!hpsb_disable_irm)
lsid |= (phyreg[6] & 0x01) << 11; /* contender (phy dependent) */ lsid |= (phyreg[6] & 0x01) << 11; /* contender (phy dependent) */
/* lsid |= 1 << 11; *//* set contender (hack) */ /* lsid |= 1 << 11; *//* set contender (hack) */
lsid |= (phyreg[6] & 0x10) >> 3; /* initiated reset */ lsid |= (phyreg[6] & 0x10) >> 3; /* initiated reset */
...@@ -500,7 +501,7 @@ static void send_next(struct ti_lynx *lynx, int what) ...@@ -500,7 +501,7 @@ static void send_next(struct ti_lynx *lynx, int what)
pcl.async_error_next = PCL_NEXT_INVALID; pcl.async_error_next = PCL_NEXT_INVALID;
pcl.pcl_status = 0; pcl.pcl_status = 0;
pcl.buffer[0].control = packet->speed_code << 14 | packet->header_size; pcl.buffer[0].control = packet->speed_code << 14 | packet->header_size;
#ifdef __BIG_ENDIAN #ifndef __BIG_ENDIAN
pcl.buffer[0].control |= PCL_BIGENDIAN; pcl.buffer[0].control |= PCL_BIGENDIAN;
#endif #endif
pcl.buffer[0].pointer = d->header_dma; pcl.buffer[0].pointer = d->header_dma;
...@@ -1521,10 +1522,6 @@ static int __devinit add_card(struct pci_dev *dev, ...@@ -1521,10 +1522,6 @@ static int __devinit add_card(struct pci_dev *dev,
int i; int i;
int error; int error;
/* needed for i2c communication with serial eeprom */
struct i2c_adapter i2c_adapter;
struct i2c_algo_bit_data i2c_adapter_data;
error = -ENXIO; error = -ENXIO;
if (pci_set_dma_mask(dev, 0xffffffff)) if (pci_set_dma_mask(dev, 0xffffffff))
...@@ -1697,7 +1694,7 @@ static int __devinit add_card(struct pci_dev *dev, ...@@ -1697,7 +1694,7 @@ static int __devinit add_card(struct pci_dev *dev,
pcl.async_error_next = PCL_NEXT_INVALID; pcl.async_error_next = PCL_NEXT_INVALID;
pcl.buffer[0].control = PCL_CMD_RCV | 16; pcl.buffer[0].control = PCL_CMD_RCV | 16;
#ifdef __BIG_ENDIAN #ifndef __BIG_ENDIAN
pcl.buffer[0].control |= PCL_BIGENDIAN; pcl.buffer[0].control |= PCL_BIGENDIAN;
#endif #endif
pcl.buffer[1].control = PCL_LAST_BUFF | 4080; pcl.buffer[1].control = PCL_LAST_BUFF | 4080;
...@@ -1780,25 +1777,39 @@ static int __devinit add_card(struct pci_dev *dev, ...@@ -1780,25 +1777,39 @@ static int __devinit add_card(struct pci_dev *dev,
| LINK_CONTROL_RESET_TX | LINK_CONTROL_RESET_RX); | LINK_CONTROL_RESET_TX | LINK_CONTROL_RESET_RX);
if (!lynx->phyic.reg_1394a) { if (!lynx->phyic.reg_1394a) {
/* attempt to enable contender bit -FIXME- would this work if (!hpsb_disable_irm) {
* elsewhere? */ /* attempt to enable contender bit -FIXME- would this
* work elsewhere? */
reg_set_bits(lynx, GPIO_CTRL_A, 0x1); reg_set_bits(lynx, GPIO_CTRL_A, 0x1);
reg_write(lynx, GPIO_DATA_BASE + 0x3c, 0x1); reg_write(lynx, GPIO_DATA_BASE + 0x3c, 0x1);
}
} else { } else {
/* set the contender and LCtrl bit in the extended PHY register /* set the contender (if appropriate) and LCtrl bit in the
* set. (Should check that bis 0,1,2 (=0xE0) is set * extended PHY register set. (Should check that PHY_02_EXTENDED
* in register 2?) * is set in register 2?)
*/ */
i = get_phy_reg(lynx, 4); i = get_phy_reg(lynx, 4);
if (i != -1) set_phy_reg(lynx, 4, i | 0xc0); i |= PHY_04_LCTRL;
if (hpsb_disable_irm)
i &= !PHY_04_CONTENDER;
else
i |= PHY_04_CONTENDER;
if (i != -1) set_phy_reg(lynx, 4, i);
} }
if (!skip_eeprom) if (!skip_eeprom)
{ {
i2c_adapter = bit_ops; /* needed for i2c communication with serial eeprom */
struct i2c_adapter *i2c_ad;
struct i2c_algo_bit_data i2c_adapter_data;
error = -ENOMEM;
i2c_ad = kmalloc(sizeof(struct i2c_adapter), SLAB_KERNEL);
if (!i2c_ad) FAIL("failed to allocate I2C adapter memory");
memcpy(i2c_ad, &bit_ops, sizeof(struct i2c_adapter));
i2c_adapter_data = bit_data; i2c_adapter_data = bit_data;
i2c_adapter.algo_data = &i2c_adapter_data; i2c_ad->algo_data = &i2c_adapter_data;
i2c_adapter_data.data = lynx; i2c_adapter_data.data = lynx;
PRINTD(KERN_DEBUG, lynx->id,"original eeprom control: %d", PRINTD(KERN_DEBUG, lynx->id,"original eeprom control: %d",
...@@ -1808,8 +1819,9 @@ static int __devinit add_card(struct pci_dev *dev, ...@@ -1808,8 +1819,9 @@ static int __devinit add_card(struct pci_dev *dev,
lynx->i2c_driven_state = 0x00000070; lynx->i2c_driven_state = 0x00000070;
reg_write(lynx, SERIAL_EEPROM_CONTROL, lynx->i2c_driven_state); reg_write(lynx, SERIAL_EEPROM_CONTROL, lynx->i2c_driven_state);
if (i2c_bit_add_bus(&i2c_adapter) < 0) if (i2c_bit_add_bus(i2c_ad) < 0)
{ {
kfree(i2c_ad);
error = -ENXIO; error = -ENXIO;
FAIL("unable to register i2c"); FAIL("unable to register i2c");
} }
...@@ -1825,13 +1837,13 @@ static int __devinit add_card(struct pci_dev *dev, ...@@ -1825,13 +1837,13 @@ static int __devinit add_card(struct pci_dev *dev,
#ifdef CONFIG_IEEE1394_VERBOSEDEBUG #ifdef CONFIG_IEEE1394_VERBOSEDEBUG
union i2c_smbus_data data; union i2c_smbus_data data;
if (i2c_smbus_xfer(&i2c_adapter, 80, 0, I2C_SMBUS_WRITE, 0, I2C_SMBUS_BYTE,NULL)) if (i2c_smbus_xfer(i2c_ad, 80, 0, I2C_SMBUS_WRITE, 0, I2C_SMBUS_BYTE,NULL))
PRINT(KERN_ERR, lynx->id,"eeprom read start has failed"); PRINT(KERN_ERR, lynx->id,"eeprom read start has failed");
else else
{ {
u16 addr; u16 addr;
for (addr=0x00; addr < 0x100; addr++) { for (addr=0x00; addr < 0x100; addr++) {
if (i2c_smbus_xfer(&i2c_adapter, 80, 0, I2C_SMBUS_READ, 0, I2C_SMBUS_BYTE,& data)) { if (i2c_smbus_xfer(i2c_ad, 80, 0, I2C_SMBUS_READ, 0, I2C_SMBUS_BYTE,& data)) {
PRINT(KERN_ERR, lynx->id, "unable to read i2c %x", addr); PRINT(KERN_ERR, lynx->id, "unable to read i2c %x", addr);
break; break;
} }
...@@ -1843,7 +1855,7 @@ static int __devinit add_card(struct pci_dev *dev, ...@@ -1843,7 +1855,7 @@ static int __devinit add_card(struct pci_dev *dev,
/* we use i2c_transfer, because i2c_smbus_read_block_data does not work properly and we /* we use i2c_transfer, because i2c_smbus_read_block_data does not work properly and we
do it more efficiently in one transaction rather then using several reads */ do it more efficiently in one transaction rather then using several reads */
if (i2c_transfer(&i2c_adapter, msg, 2) < 0) { if (i2c_transfer(i2c_ad, msg, 2) < 0) {
PRINT(KERN_ERR, lynx->id, "unable to read bus info block from i2c"); PRINT(KERN_ERR, lynx->id, "unable to read bus info block from i2c");
} else { } else {
int i; int i;
...@@ -1863,13 +1875,15 @@ static int __devinit add_card(struct pci_dev *dev, ...@@ -1863,13 +1875,15 @@ static int __devinit add_card(struct pci_dev *dev,
{ {
PRINT(KERN_DEBUG, lynx->id, "read a valid bus info block from"); PRINT(KERN_DEBUG, lynx->id, "read a valid bus info block from");
} else { } else {
kfree(i2c_ad);
error = -ENXIO; error = -ENXIO;
FAIL("read something from serial eeprom, but it does not seem to be a valid bus info block"); FAIL("read something from serial eeprom, but it does not seem to be a valid bus info block");
} }
} }
i2c_bit_del_bus(&i2c_adapter); i2c_bit_del_bus(i2c_ad);
kfree(i2c_ad);
} }
} }
......
...@@ -79,14 +79,16 @@ static const int iso_buffer_max = 4 * 1024 * 1024; /* 4 MB */ ...@@ -79,14 +79,16 @@ static const int iso_buffer_max = 4 * 1024 * 1024; /* 4 MB */
static struct hpsb_highlevel raw1394_highlevel; static struct hpsb_highlevel raw1394_highlevel;
static int arm_read (struct hpsb_host *host, int nodeid, quadlet_t *buffer, static int arm_read(struct hpsb_host *host, int nodeid, quadlet_t * buffer,
u64 addr, size_t length, u16 flags); u64 addr, size_t length, u16 flags);
static int arm_write (struct hpsb_host *host, int nodeid, int destid, static int arm_write(struct hpsb_host *host, int nodeid, int destid,
quadlet_t *data, u64 addr, size_t length, u16 flags); quadlet_t * data, u64 addr, size_t length, u16 flags);
static int arm_lock (struct hpsb_host *host, int nodeid, quadlet_t *store, static int arm_lock(struct hpsb_host *host, int nodeid, quadlet_t * store,
u64 addr, quadlet_t data, quadlet_t arg, int ext_tcode, u16 flags); u64 addr, quadlet_t data, quadlet_t arg, int ext_tcode,
static int arm_lock64 (struct hpsb_host *host, int nodeid, octlet_t *store, u16 flags);
u64 addr, octlet_t data, octlet_t arg, int ext_tcode, u16 flags); static int arm_lock64(struct hpsb_host *host, int nodeid, octlet_t * store,
u64 addr, octlet_t data, octlet_t arg, int ext_tcode,
u16 flags);
static struct hpsb_address_ops arm_ops = { static struct hpsb_address_ops arm_ops = {
.read = arm_read, .read = arm_read,
.write = arm_write, .write = arm_write,
...@@ -185,7 +187,6 @@ static void queue_complete_cb(struct pending_request *req) ...@@ -185,7 +187,6 @@ static void queue_complete_cb(struct pending_request *req)
queue_complete_req(req); queue_complete_req(req);
} }
static void add_host(struct hpsb_host *host) static void add_host(struct hpsb_host *host)
{ {
struct host_info *hi; struct host_info *hi;
...@@ -207,7 +208,6 @@ static void add_host(struct hpsb_host *host) ...@@ -207,7 +208,6 @@ static void add_host(struct hpsb_host *host)
atomic_inc(&internal_generation); atomic_inc(&internal_generation);
} }
static struct host_info *find_host_info(struct hpsb_host *host) static struct host_info *find_host_info(struct hpsb_host *host)
{ {
struct host_info *hi; struct host_info *hi;
...@@ -268,11 +268,14 @@ static void host_reset(struct hpsb_host *host) ...@@ -268,11 +268,14 @@ static void host_reset(struct hpsb_host *host)
if (req != NULL) { if (req != NULL) {
req->file_info = fi; req->file_info = fi;
req->req.type = RAW1394_REQ_BUS_RESET; req->req.type = RAW1394_REQ_BUS_RESET;
req->req.generation = get_hpsb_generation(host); req->req.generation =
get_hpsb_generation(host);
req->req.misc = (host->node_id << 16) req->req.misc = (host->node_id << 16)
| host->node_count; | host->node_count;
if (fi->protocol_version > 3) { if (fi->protocol_version > 3) {
req->req.misc |= (NODEID_TO_NODE(host->irm_id) req->req.misc |=
(NODEID_TO_NODE
(host->irm_id)
<< 8); << 8);
} }
...@@ -284,7 +287,7 @@ static void host_reset(struct hpsb_host *host) ...@@ -284,7 +287,7 @@ static void host_reset(struct hpsb_host *host)
spin_unlock_irqrestore(&host_info_lock, flags); spin_unlock_irqrestore(&host_info_lock, flags);
} }
static void iso_receive(struct hpsb_host *host, int channel, quadlet_t *data, static void iso_receive(struct hpsb_host *host, int channel, quadlet_t * data,
size_t length) size_t length)
{ {
unsigned long flags; unsigned long flags;
...@@ -308,7 +311,8 @@ static void iso_receive(struct hpsb_host *host, int channel, quadlet_t *data, ...@@ -308,7 +311,8 @@ static void iso_receive(struct hpsb_host *host, int channel, quadlet_t *data,
continue; continue;
req = __alloc_pending_request(SLAB_ATOMIC); req = __alloc_pending_request(SLAB_ATOMIC);
if (!req) break; if (!req)
break;
if (!ibs) { if (!ibs) {
ibs = kmalloc(sizeof(struct iso_block_store) ibs = kmalloc(sizeof(struct iso_block_store)
...@@ -345,7 +349,7 @@ static void iso_receive(struct hpsb_host *host, int channel, quadlet_t *data, ...@@ -345,7 +349,7 @@ static void iso_receive(struct hpsb_host *host, int channel, quadlet_t *data,
} }
static void fcp_request(struct hpsb_host *host, int nodeid, int direction, static void fcp_request(struct hpsb_host *host, int nodeid, int direction,
int cts, u8 *data, size_t length) int cts, u8 * data, size_t length)
{ {
unsigned long flags; unsigned long flags;
struct host_info *hi; struct host_info *hi;
...@@ -368,7 +372,8 @@ static void fcp_request(struct hpsb_host *host, int nodeid, int direction, ...@@ -368,7 +372,8 @@ static void fcp_request(struct hpsb_host *host, int nodeid, int direction,
continue; continue;
req = __alloc_pending_request(SLAB_ATOMIC); req = __alloc_pending_request(SLAB_ATOMIC);
if (!req) break; if (!req)
break;
if (!ibs) { if (!ibs) {
ibs = kmalloc(sizeof(struct iso_block_store) ibs = kmalloc(sizeof(struct iso_block_store)
...@@ -404,13 +409,13 @@ static void fcp_request(struct hpsb_host *host, int nodeid, int direction, ...@@ -404,13 +409,13 @@ static void fcp_request(struct hpsb_host *host, int nodeid, int direction,
queue_complete_req(req); queue_complete_req(req);
} }
static ssize_t raw1394_read(struct file *file, char __user * buffer,
static ssize_t raw1394_read(struct file *file, char __user *buffer, size_t count, size_t count, loff_t * offset_is_ignored)
loff_t *offset_is_ignored)
{ {
struct file_info *fi = (struct file_info *)file->private_data; struct file_info *fi = (struct file_info *)file->private_data;
struct list_head *lh; struct list_head *lh;
struct pending_request *req; struct pending_request *req;
ssize_t ret;
if (count != sizeof(struct raw1394_request)) { if (count != sizeof(struct raw1394_request)) {
return -EINVAL; return -EINVAL;
...@@ -443,13 +448,17 @@ static ssize_t raw1394_read(struct file *file, char __user *buffer, size_t count ...@@ -443,13 +448,17 @@ static ssize_t raw1394_read(struct file *file, char __user *buffer, size_t count
req->req.error = RAW1394_ERROR_MEMFAULT; req->req.error = RAW1394_ERROR_MEMFAULT;
} }
} }
__copy_to_user(buffer, &req->req, sizeof(req->req)); if (copy_to_user(buffer, &req->req, sizeof(req->req))) {
ret = -EFAULT;
goto out;
}
ret = (ssize_t) sizeof(struct raw1394_request);
out:
free_pending_request(req); free_pending_request(req);
return sizeof(struct raw1394_request); return ret;
} }
static int state_opened(struct file_info *fi, struct pending_request *req) static int state_opened(struct file_info *fi, struct pending_request *req)
{ {
if (req->req.type == RAW1394_REQ_INITIALIZE) { if (req->req.type == RAW1394_REQ_INITIALIZE) {
...@@ -496,7 +505,7 @@ static int state_initialized(struct file_info *fi, struct pending_request *req) ...@@ -496,7 +505,7 @@ static int state_initialized(struct file_info *fi, struct pending_request *req)
if (khl != NULL) { if (khl != NULL) {
req->req.misc = host_count; req->req.misc = host_count;
req->data = (quadlet_t *)khl; req->data = (quadlet_t *) khl;
list_for_each_entry(hi, &host_info_list, list) { list_for_each_entry(hi, &host_info_list, list) {
khl->nodes = hi->host->node_count; khl->nodes = hi->host->node_count;
...@@ -509,7 +518,8 @@ static int state_initialized(struct file_info *fi, struct pending_request *req) ...@@ -509,7 +518,8 @@ static int state_initialized(struct file_info *fi, struct pending_request *req)
if (khl != NULL) { if (khl != NULL) {
req->req.error = RAW1394_ERROR_NONE; req->req.error = RAW1394_ERROR_NONE;
req->req.length = min(req->req.length, req->req.length = min(req->req.length,
(u32)(sizeof(struct raw1394_khost_list) (u32) (sizeof
(struct raw1394_khost_list)
* req->req.misc)); * req->req.misc));
req->free_data = 1; req->free_data = 1;
} else { } else {
...@@ -534,7 +544,8 @@ static int state_initialized(struct file_info *fi, struct pending_request *req) ...@@ -534,7 +544,8 @@ static int state_initialized(struct file_info *fi, struct pending_request *req)
req->req.misc = (fi->host->node_id << 16) req->req.misc = (fi->host->node_id << 16)
| fi->host->node_count; | fi->host->node_count;
if (fi->protocol_version > 3) { if (fi->protocol_version > 3) {
req->req.misc |= NODEID_TO_NODE(fi->host->irm_id) << 8; req->req.misc |=
NODEID_TO_NODE(fi->host->irm_id) << 8;
} }
} else { } else {
req->req.error = RAW1394_ERROR_INVALID_ARG; req->req.error = RAW1394_ERROR_INVALID_ARG;
...@@ -566,7 +577,8 @@ static void handle_iso_listen(struct file_info *fi, struct pending_request *req) ...@@ -566,7 +577,8 @@ static void handle_iso_listen(struct file_info *fi, struct pending_request *req)
if (fi->listen_channels & (1ULL << channel)) { if (fi->listen_channels & (1ULL << channel)) {
req->req.error = RAW1394_ERROR_ALREADY; req->req.error = RAW1394_ERROR_ALREADY;
} else { } else {
if (hpsb_listen_channel(&raw1394_highlevel, fi->host, channel)) { if (hpsb_listen_channel
(&raw1394_highlevel, fi->host, channel)) {
req->req.error = RAW1394_ERROR_ALREADY; req->req.error = RAW1394_ERROR_ALREADY;
} else { } else {
fi->listen_channels |= 1ULL << channel; fi->listen_channels |= 1ULL << channel;
...@@ -579,7 +591,8 @@ static void handle_iso_listen(struct file_info *fi, struct pending_request *req) ...@@ -579,7 +591,8 @@ static void handle_iso_listen(struct file_info *fi, struct pending_request *req)
channel = ~channel; channel = ~channel;
if (fi->listen_channels & (1ULL << channel)) { if (fi->listen_channels & (1ULL << channel)) {
hpsb_unlisten_channel(&raw1394_highlevel, fi->host, channel); hpsb_unlisten_channel(&raw1394_highlevel, fi->host,
channel);
fi->listen_channels &= ~(1ULL << channel); fi->listen_channels &= ~(1ULL << channel);
} else { } else {
req->req.error = RAW1394_ERROR_INVALID_ARG; req->req.error = RAW1394_ERROR_INVALID_ARG;
...@@ -611,7 +624,6 @@ static void handle_fcp_listen(struct file_info *fi, struct pending_request *req) ...@@ -611,7 +624,6 @@ static void handle_fcp_listen(struct file_info *fi, struct pending_request *req)
queue_complete_req(req); queue_complete_req(req);
} }
static int handle_async_request(struct file_info *fi, static int handle_async_request(struct file_info *fi,
struct pending_request *req, int node) struct pending_request *req, int node)
{ {
...@@ -621,7 +633,8 @@ static int handle_async_request(struct file_info *fi, ...@@ -621,7 +633,8 @@ static int handle_async_request(struct file_info *fi,
switch (req->req.type) { switch (req->req.type) {
case RAW1394_REQ_ASYNC_READ: case RAW1394_REQ_ASYNC_READ:
DBGMSG("read_request called"); DBGMSG("read_request called");
packet = hpsb_make_readpacket(fi->host, node, addr, req->req.length); packet =
hpsb_make_readpacket(fi->host, node, addr, req->req.length);
if (!packet) if (!packet)
return -ENOMEM; return -ENOMEM;
...@@ -642,11 +655,13 @@ static int handle_async_request(struct file_info *fi, ...@@ -642,11 +655,13 @@ static int handle_async_request(struct file_info *fi,
return -ENOMEM; return -ENOMEM;
if (req->req.length == 4) { if (req->req.length == 4) {
if (copy_from_user(&packet->header[3], int2ptr(req->req.sendb), if (copy_from_user
(&packet->header[3], int2ptr(req->req.sendb),
req->req.length)) req->req.length))
req->req.error = RAW1394_ERROR_MEMFAULT; req->req.error = RAW1394_ERROR_MEMFAULT;
} else { } else {
if (copy_from_user(packet->data, int2ptr(req->req.sendb), if (copy_from_user
(packet->data, int2ptr(req->req.sendb),
req->req.length)) req->req.length))
req->req.error = RAW1394_ERROR_MEMFAULT; req->req.error = RAW1394_ERROR_MEMFAULT;
} }
...@@ -657,8 +672,11 @@ static int handle_async_request(struct file_info *fi, ...@@ -657,8 +672,11 @@ static int handle_async_request(struct file_info *fi,
case RAW1394_REQ_ASYNC_STREAM: case RAW1394_REQ_ASYNC_STREAM:
DBGMSG("stream_request called"); DBGMSG("stream_request called");
packet = hpsb_make_streampacket(fi->host, NULL, req->req.length, node & 0x3f/*channel*/, packet =
(req->req.misc >> 16) & 0x3, req->req.misc & 0xf); hpsb_make_streampacket(fi->host, NULL, req->req.length,
node & 0x3f /*channel */ ,
(req->req.misc >> 16) & 0x3,
req->req.misc & 0xf);
if (!packet) if (!packet)
return -ENOMEM; return -ENOMEM;
...@@ -686,7 +704,8 @@ static int handle_async_request(struct file_info *fi, ...@@ -686,7 +704,8 @@ static int handle_async_request(struct file_info *fi,
packet = hpsb_make_lockpacket(fi->host, node, addr, packet = hpsb_make_lockpacket(fi->host, node, addr,
req->req.misc, NULL, 0); req->req.misc, NULL, 0);
if (!packet) return -ENOMEM; if (!packet)
return -ENOMEM;
if (copy_from_user(packet->data, int2ptr(req->req.sendb), if (copy_from_user(packet->data, int2ptr(req->req.sendb),
req->req.length)) { req->req.length)) {
...@@ -714,7 +733,8 @@ static int handle_async_request(struct file_info *fi, ...@@ -714,7 +733,8 @@ static int handle_async_request(struct file_info *fi,
} }
packet = hpsb_make_lock64packet(fi->host, node, addr, packet = hpsb_make_lock64packet(fi->host, node, addr,
req->req.misc, NULL, 0); req->req.misc, NULL, 0);
if (!packet) return -ENOMEM; if (!packet)
return -ENOMEM;
if (copy_from_user(packet->data, int2ptr(req->req.sendb), if (copy_from_user(packet->data, int2ptr(req->req.sendb),
req->req.length)) { req->req.length)) {
...@@ -738,7 +758,8 @@ static int handle_async_request(struct file_info *fi, ...@@ -738,7 +758,8 @@ static int handle_async_request(struct file_info *fi,
return sizeof(struct raw1394_request); return sizeof(struct raw1394_request);
} }
hpsb_set_packet_complete_task(packet, (void(*)(void*))queue_complete_cb, req); hpsb_set_packet_complete_task(packet,
(void (*)(void *))queue_complete_cb, req);
spin_lock_irq(&fi->reqlists_lock); spin_lock_irq(&fi->reqlists_lock);
list_add_tail(&req->list, &fi->req_pending); list_add_tail(&req->list, &fi->req_pending);
...@@ -761,7 +782,8 @@ static int handle_iso_send(struct file_info *fi, struct pending_request *req, ...@@ -761,7 +782,8 @@ static int handle_iso_send(struct file_info *fi, struct pending_request *req,
struct hpsb_packet *packet; struct hpsb_packet *packet;
packet = hpsb_make_isopacket(fi->host, req->req.length, channel & 0x3f, packet = hpsb_make_isopacket(fi->host, req->req.length, channel & 0x3f,
(req->req.misc >> 16) & 0x3, req->req.misc & 0xf); (req->req.misc >> 16) & 0x3,
req->req.misc & 0xf);
if (!packet) if (!packet)
return -ENOMEM; return -ENOMEM;
...@@ -778,7 +800,9 @@ static int handle_iso_send(struct file_info *fi, struct pending_request *req, ...@@ -778,7 +800,9 @@ static int handle_iso_send(struct file_info *fi, struct pending_request *req,
} }
req->req.length = 0; req->req.length = 0;
hpsb_set_packet_complete_task(packet, (void (*)(void*))queue_complete_req, req); hpsb_set_packet_complete_task(packet,
(void (*)(void *))queue_complete_req,
req);
spin_lock_irq(&fi->reqlists_lock); spin_lock_irq(&fi->reqlists_lock);
list_add_tail(&req->list, &fi->req_pending); list_add_tail(&req->list, &fi->req_pending);
...@@ -801,17 +825,17 @@ static int handle_async_send(struct file_info *fi, struct pending_request *req) ...@@ -801,17 +825,17 @@ static int handle_async_send(struct file_info *fi, struct pending_request *req)
int header_length = req->req.misc & 0xffff; int header_length = req->req.misc & 0xffff;
int expect_response = req->req.misc >> 16; int expect_response = req->req.misc >> 16;
if ((header_length > req->req.length) || if ((header_length > req->req.length) || (header_length < 12)) {
(header_length < 12)) {
req->req.error = RAW1394_ERROR_INVALID_ARG; req->req.error = RAW1394_ERROR_INVALID_ARG;
req->req.length = 0; req->req.length = 0;
queue_complete_req(req); queue_complete_req(req);
return sizeof(struct raw1394_request); return sizeof(struct raw1394_request);
} }
packet = hpsb_alloc_packet(req->req.length-header_length); packet = hpsb_alloc_packet(req->req.length - header_length);
req->packet = packet; req->packet = packet;
if (!packet) return -ENOMEM; if (!packet)
return -ENOMEM;
if (copy_from_user(packet->header, int2ptr(req->req.sendb), if (copy_from_user(packet->header, int2ptr(req->req.sendb),
header_length)) { header_length)) {
...@@ -821,7 +845,8 @@ static int handle_async_send(struct file_info *fi, struct pending_request *req) ...@@ -821,7 +845,8 @@ static int handle_async_send(struct file_info *fi, struct pending_request *req)
return sizeof(struct raw1394_request); return sizeof(struct raw1394_request);
} }
if (copy_from_user(packet->data, int2ptr(req->req.sendb) + header_length, if (copy_from_user
(packet->data, int2ptr(req->req.sendb) + header_length,
packet->data_size)) { packet->data_size)) {
req->req.error = RAW1394_ERROR_MEMFAULT; req->req.error = RAW1394_ERROR_MEMFAULT;
req->req.length = 0; req->req.length = 0;
...@@ -832,14 +857,15 @@ static int handle_async_send(struct file_info *fi, struct pending_request *req) ...@@ -832,14 +857,15 @@ static int handle_async_send(struct file_info *fi, struct pending_request *req)
packet->type = hpsb_async; packet->type = hpsb_async;
packet->node_id = packet->header[0] >> 16; packet->node_id = packet->header[0] >> 16;
packet->tcode = (packet->header[0] >> 4) & 0xf; packet->tcode = (packet->header[0] >> 4) & 0xf;
packet->tlabel = (packet->header[0] >> 10) &0x3f; packet->tlabel = (packet->header[0] >> 10) & 0x3f;
packet->host = fi->host; packet->host = fi->host;
packet->expect_response = expect_response; packet->expect_response = expect_response;
packet->header_size=header_length; packet->header_size = header_length;
packet->data_size=req->req.length-header_length; packet->data_size = req->req.length - header_length;
req->req.length = 0; req->req.length = 0;
hpsb_set_packet_complete_task(packet, (void(*)(void*))queue_complete_cb, req); hpsb_set_packet_complete_task(packet,
(void (*)(void *))queue_complete_cb, req);
spin_lock_irq(&fi->reqlists_lock); spin_lock_irq(&fi->reqlists_lock);
list_add_tail(&req->list, &fi->req_pending); list_add_tail(&req->list, &fi->req_pending);
...@@ -856,7 +882,7 @@ static int handle_async_send(struct file_info *fi, struct pending_request *req) ...@@ -856,7 +882,7 @@ static int handle_async_send(struct file_info *fi, struct pending_request *req)
return sizeof(struct raw1394_request); return sizeof(struct raw1394_request);
} }
static int arm_read (struct hpsb_host *host, int nodeid, quadlet_t *buffer, static int arm_read(struct hpsb_host *host, int nodeid, quadlet_t * buffer,
u64 addr, size_t length, u16 flags) u64 addr, size_t length, u16 flags)
{ {
struct pending_request *req; struct pending_request *req;
...@@ -866,12 +892,12 @@ static int arm_read (struct hpsb_host *host, int nodeid, quadlet_t *buffer, ...@@ -866,12 +892,12 @@ static int arm_read (struct hpsb_host *host, int nodeid, quadlet_t *buffer,
struct arm_addr *arm_addr = NULL; struct arm_addr *arm_addr = NULL;
struct arm_request *arm_req = NULL; struct arm_request *arm_req = NULL;
struct arm_response *arm_resp = NULL; struct arm_response *arm_resp = NULL;
int found=0, size=0, rcode=-1; int found = 0, size = 0, rcode = -1;
struct arm_request_response *arm_req_resp = NULL; struct arm_request_response *arm_req_resp = NULL;
DBGMSG("arm_read called by node: %X" DBGMSG("arm_read called by node: %X"
"addr: %4.4x %8.8x length: %Zu", nodeid, "addr: %4.4x %8.8x length: %Zu", nodeid,
(u16) ((addr >>32) & 0xFFFF), (u32) (addr & 0xFFFFFFFF), (u16) ((addr >> 32) & 0xFFFF), (u32) (addr & 0xFFFFFFFF),
length); length);
spin_lock(&host_info_lock); spin_lock(&host_info_lock);
hi = find_host_info(host); /* search address-entry */ hi = find_host_info(host); /* search address-entry */
...@@ -879,9 +905,11 @@ static int arm_read (struct hpsb_host *host, int nodeid, quadlet_t *buffer, ...@@ -879,9 +905,11 @@ static int arm_read (struct hpsb_host *host, int nodeid, quadlet_t *buffer,
list_for_each_entry(fi, &hi->file_info_list, list) { list_for_each_entry(fi, &hi->file_info_list, list) {
entry = fi->addr_list.next; entry = fi->addr_list.next;
while (entry != &(fi->addr_list)) { while (entry != &(fi->addr_list)) {
arm_addr = list_entry(entry, struct arm_addr, addr_list); arm_addr =
if (((arm_addr->start) <= (addr)) && list_entry(entry, struct arm_addr,
((arm_addr->end) >= (addr+length))) { addr_list);
if (((arm_addr->start) <= (addr))
&& ((arm_addr->end) >= (addr + length))) {
found = 1; found = 1;
break; break;
} }
...@@ -908,7 +936,10 @@ static int arm_read (struct hpsb_host *host, int nodeid, quadlet_t *buffer, ...@@ -908,7 +936,10 @@ static int arm_read (struct hpsb_host *host, int nodeid, quadlet_t *buffer,
if (rcode == -1) { if (rcode == -1) {
if (arm_addr->access_rights & ARM_READ) { if (arm_addr->access_rights & ARM_READ) {
if (!(arm_addr->client_transactions & ARM_READ)) { if (!(arm_addr->client_transactions & ARM_READ)) {
memcpy(buffer,(arm_addr->addr_space_buffer)+(addr-(arm_addr->start)), memcpy(buffer,
(arm_addr->addr_space_buffer) + (addr -
(arm_addr->
start)),
length); length);
DBGMSG("arm_read -> (rcode_complete)"); DBGMSG("arm_read -> (rcode_complete)");
rcode = RCODE_COMPLETE; rcode = RCODE_COMPLETE;
...@@ -924,51 +955,64 @@ static int arm_read (struct hpsb_host *host, int nodeid, quadlet_t *buffer, ...@@ -924,51 +955,64 @@ static int arm_read (struct hpsb_host *host, int nodeid, quadlet_t *buffer,
if (!req) { if (!req) {
DBGMSG("arm_read -> rcode_conflict_error"); DBGMSG("arm_read -> rcode_conflict_error");
spin_unlock(&host_info_lock); spin_unlock(&host_info_lock);
return(RCODE_CONFLICT_ERROR); /* A resource conflict was detected. return (RCODE_CONFLICT_ERROR); /* A resource conflict was detected.
The request may be retried */ The request may be retried */
} }
if (rcode == RCODE_COMPLETE) { if (rcode == RCODE_COMPLETE) {
size = sizeof(struct arm_request)+sizeof(struct arm_response) + size =
sizeof(struct arm_request) +
sizeof(struct arm_response) +
length * sizeof(byte_t) + length * sizeof(byte_t) +
sizeof (struct arm_request_response); sizeof(struct arm_request_response);
} else { } else {
size = sizeof(struct arm_request)+sizeof(struct arm_response) + size =
sizeof (struct arm_request_response); sizeof(struct arm_request) +
sizeof(struct arm_response) +
sizeof(struct arm_request_response);
} }
req->data = kmalloc(size, SLAB_ATOMIC); req->data = kmalloc(size, SLAB_ATOMIC);
if (!(req->data)) { if (!(req->data)) {
free_pending_request(req); free_pending_request(req);
DBGMSG("arm_read -> rcode_conflict_error"); DBGMSG("arm_read -> rcode_conflict_error");
spin_unlock(&host_info_lock); spin_unlock(&host_info_lock);
return(RCODE_CONFLICT_ERROR); /* A resource conflict was detected. return (RCODE_CONFLICT_ERROR); /* A resource conflict was detected.
The request may be retried */ The request may be retried */
} }
req->free_data=1; req->free_data = 1;
req->file_info = fi; req->file_info = fi;
req->req.type = RAW1394_REQ_ARM; req->req.type = RAW1394_REQ_ARM;
req->req.generation = get_hpsb_generation(host); req->req.generation = get_hpsb_generation(host);
req->req.misc = ( ((length << 16) & (0xFFFF0000)) | (ARM_READ & 0xFF)); req->req.misc =
(((length << 16) & (0xFFFF0000)) | (ARM_READ & 0xFF));
req->req.tag = arm_addr->arm_tag; req->req.tag = arm_addr->arm_tag;
req->req.recvb = arm_addr->recvb; req->req.recvb = arm_addr->recvb;
req->req.length = size; req->req.length = size;
arm_req_resp = (struct arm_request_response *) (req->data); arm_req_resp = (struct arm_request_response *)(req->data);
arm_req = (struct arm_request *) ((byte_t *)(req->data) + arm_req = (struct arm_request *)((byte_t *) (req->data) +
(sizeof (struct arm_request_response))); (sizeof
arm_resp = (struct arm_response *) ((byte_t *)(arm_req) + (struct
arm_request_response)));
arm_resp =
(struct arm_response *)((byte_t *) (arm_req) +
(sizeof(struct arm_request))); (sizeof(struct arm_request)));
arm_req->buffer = NULL; arm_req->buffer = NULL;
arm_resp->buffer = NULL; arm_resp->buffer = NULL;
if (rcode == RCODE_COMPLETE) { if (rcode == RCODE_COMPLETE) {
byte_t *buf = (byte_t *)arm_resp + sizeof(struct arm_response); byte_t *buf =
memcpy (buf, (byte_t *) arm_resp + sizeof(struct arm_response);
(arm_addr->addr_space_buffer)+(addr-(arm_addr->start)), memcpy(buf,
(arm_addr->addr_space_buffer) + (addr -
(arm_addr->
start)),
length); length);
arm_resp->buffer = int2ptr((arm_addr->recvb) + arm_resp->buffer =
sizeof (struct arm_request_response) + int2ptr((arm_addr->recvb) +
sizeof (struct arm_request) + sizeof(struct arm_request_response) +
sizeof (struct arm_response)); sizeof(struct arm_request) +
} sizeof(struct arm_response));
arm_resp->buffer_length = (rcode == RCODE_COMPLETE) ? length : 0; }
arm_resp->buffer_length =
(rcode == RCODE_COMPLETE) ? length : 0;
arm_resp->response_code = rcode; arm_resp->response_code = rcode;
arm_req->buffer_length = 0; arm_req->buffer_length = 0;
arm_req->generation = req->req.generation; arm_req->generation = req->req.generation;
...@@ -979,18 +1023,20 @@ static int arm_read (struct hpsb_host *host, int nodeid, quadlet_t *buffer, ...@@ -979,18 +1023,20 @@ static int arm_read (struct hpsb_host *host, int nodeid, quadlet_t *buffer,
arm_req->tlabel = (flags >> 10) & 0x3f; arm_req->tlabel = (flags >> 10) & 0x3f;
arm_req->tcode = (flags >> 4) & 0x0f; arm_req->tcode = (flags >> 4) & 0x0f;
arm_req_resp->request = int2ptr((arm_addr->recvb) + arm_req_resp->request = int2ptr((arm_addr->recvb) +
sizeof (struct arm_request_response)); sizeof(struct
arm_req_resp->response = int2ptr((arm_addr->recvb) + arm_request_response));
sizeof (struct arm_request_response) + arm_req_resp->response =
sizeof (struct arm_request)); int2ptr((arm_addr->recvb) +
sizeof(struct arm_request_response) +
sizeof(struct arm_request));
queue_complete_req(req); queue_complete_req(req);
} }
spin_unlock(&host_info_lock); spin_unlock(&host_info_lock);
return(rcode); return (rcode);
} }
static int arm_write (struct hpsb_host *host, int nodeid, int destid, static int arm_write(struct hpsb_host *host, int nodeid, int destid,
quadlet_t *data, u64 addr, size_t length, u16 flags) quadlet_t * data, u64 addr, size_t length, u16 flags)
{ {
struct pending_request *req; struct pending_request *req;
struct host_info *hi; struct host_info *hi;
...@@ -999,12 +1045,12 @@ static int arm_write (struct hpsb_host *host, int nodeid, int destid, ...@@ -999,12 +1045,12 @@ static int arm_write (struct hpsb_host *host, int nodeid, int destid,
struct arm_addr *arm_addr = NULL; struct arm_addr *arm_addr = NULL;
struct arm_request *arm_req = NULL; struct arm_request *arm_req = NULL;
struct arm_response *arm_resp = NULL; struct arm_response *arm_resp = NULL;
int found=0, size=0, rcode=-1, length_conflict=0; int found = 0, size = 0, rcode = -1, length_conflict = 0;
struct arm_request_response *arm_req_resp = NULL; struct arm_request_response *arm_req_resp = NULL;
DBGMSG("arm_write called by node: %X" DBGMSG("arm_write called by node: %X"
"addr: %4.4x %8.8x length: %Zu", nodeid, "addr: %4.4x %8.8x length: %Zu", nodeid,
(u16) ((addr >>32) & 0xFFFF), (u32) (addr & 0xFFFFFFFF), (u16) ((addr >> 32) & 0xFFFF), (u32) (addr & 0xFFFFFFFF),
length); length);
spin_lock(&host_info_lock); spin_lock(&host_info_lock);
hi = find_host_info(host); /* search address-entry */ hi = find_host_info(host); /* search address-entry */
...@@ -1012,9 +1058,11 @@ static int arm_write (struct hpsb_host *host, int nodeid, int destid, ...@@ -1012,9 +1058,11 @@ static int arm_write (struct hpsb_host *host, int nodeid, int destid,
list_for_each_entry(fi, &hi->file_info_list, list) { list_for_each_entry(fi, &hi->file_info_list, list) {
entry = fi->addr_list.next; entry = fi->addr_list.next;
while (entry != &(fi->addr_list)) { while (entry != &(fi->addr_list)) {
arm_addr = list_entry(entry, struct arm_addr, addr_list); arm_addr =
if (((arm_addr->start) <= (addr)) && list_entry(entry, struct arm_addr,
((arm_addr->end) >= (addr+length))) { addr_list);
if (((arm_addr->start) <= (addr))
&& ((arm_addr->end) >= (addr + length))) {
found = 1; found = 1;
break; break;
} }
...@@ -1042,8 +1090,9 @@ static int arm_write (struct hpsb_host *host, int nodeid, int destid, ...@@ -1042,8 +1090,9 @@ static int arm_write (struct hpsb_host *host, int nodeid, int destid,
if (rcode == -1) { if (rcode == -1) {
if (arm_addr->access_rights & ARM_WRITE) { if (arm_addr->access_rights & ARM_WRITE) {
if (!(arm_addr->client_transactions & ARM_WRITE)) { if (!(arm_addr->client_transactions & ARM_WRITE)) {
memcpy((arm_addr->addr_space_buffer)+(addr-(arm_addr->start)), memcpy((arm_addr->addr_space_buffer) +
data, length); (addr - (arm_addr->start)), data,
length);
DBGMSG("arm_write -> (rcode_complete)"); DBGMSG("arm_write -> (rcode_complete)");
rcode = RCODE_COMPLETE; rcode = RCODE_COMPLETE;
} }
...@@ -1058,40 +1107,45 @@ static int arm_write (struct hpsb_host *host, int nodeid, int destid, ...@@ -1058,40 +1107,45 @@ static int arm_write (struct hpsb_host *host, int nodeid, int destid,
if (!req) { if (!req) {
DBGMSG("arm_write -> rcode_conflict_error"); DBGMSG("arm_write -> rcode_conflict_error");
spin_unlock(&host_info_lock); spin_unlock(&host_info_lock);
return(RCODE_CONFLICT_ERROR); /* A resource conflict was detected. return (RCODE_CONFLICT_ERROR); /* A resource conflict was detected.
The request my be retried */ The request my be retried */
} }
size = sizeof(struct arm_request)+sizeof(struct arm_response) + size =
sizeof(struct arm_request) + sizeof(struct arm_response) +
(length) * sizeof(byte_t) + (length) * sizeof(byte_t) +
sizeof (struct arm_request_response); sizeof(struct arm_request_response);
req->data = kmalloc(size, SLAB_ATOMIC); req->data = kmalloc(size, SLAB_ATOMIC);
if (!(req->data)) { if (!(req->data)) {
free_pending_request(req); free_pending_request(req);
DBGMSG("arm_write -> rcode_conflict_error"); DBGMSG("arm_write -> rcode_conflict_error");
spin_unlock(&host_info_lock); spin_unlock(&host_info_lock);
return(RCODE_CONFLICT_ERROR); /* A resource conflict was detected. return (RCODE_CONFLICT_ERROR); /* A resource conflict was detected.
The request may be retried */ The request may be retried */
} }
req->free_data=1; req->free_data = 1;
req->file_info = fi; req->file_info = fi;
req->req.type = RAW1394_REQ_ARM; req->req.type = RAW1394_REQ_ARM;
req->req.generation = get_hpsb_generation(host); req->req.generation = get_hpsb_generation(host);
req->req.misc = ( ((length << 16) & (0xFFFF0000)) | (ARM_WRITE & 0xFF)); req->req.misc =
(((length << 16) & (0xFFFF0000)) | (ARM_WRITE & 0xFF));
req->req.tag = arm_addr->arm_tag; req->req.tag = arm_addr->arm_tag;
req->req.recvb = arm_addr->recvb; req->req.recvb = arm_addr->recvb;
req->req.length = size; req->req.length = size;
arm_req_resp = (struct arm_request_response *) (req->data); arm_req_resp = (struct arm_request_response *)(req->data);
arm_req = (struct arm_request *) ((byte_t *)(req->data) + arm_req = (struct arm_request *)((byte_t *) (req->data) +
(sizeof (struct arm_request_response))); (sizeof
arm_resp = (struct arm_response *) ((byte_t *)(arm_req) + (struct
arm_request_response)));
arm_resp =
(struct arm_response *)((byte_t *) (arm_req) +
(sizeof(struct arm_request))); (sizeof(struct arm_request)));
arm_resp->buffer = NULL; arm_resp->buffer = NULL;
memcpy ((byte_t *)arm_resp + sizeof(struct arm_response), memcpy((byte_t *) arm_resp + sizeof(struct arm_response),
data, length); data, length);
arm_req->buffer = int2ptr((arm_addr->recvb) + arm_req->buffer = int2ptr((arm_addr->recvb) +
sizeof (struct arm_request_response) + sizeof(struct arm_request_response) +
sizeof (struct arm_request) + sizeof(struct arm_request) +
sizeof (struct arm_response)); sizeof(struct arm_response));
arm_req->buffer_length = length; arm_req->buffer_length = length;
arm_req->generation = req->req.generation; arm_req->generation = req->req.generation;
arm_req->extended_transaction_code = 0; arm_req->extended_transaction_code = 0;
...@@ -1103,18 +1157,21 @@ static int arm_write (struct hpsb_host *host, int nodeid, int destid, ...@@ -1103,18 +1157,21 @@ static int arm_write (struct hpsb_host *host, int nodeid, int destid,
arm_resp->buffer_length = 0; arm_resp->buffer_length = 0;
arm_resp->response_code = rcode; arm_resp->response_code = rcode;
arm_req_resp->request = int2ptr((arm_addr->recvb) + arm_req_resp->request = int2ptr((arm_addr->recvb) +
sizeof (struct arm_request_response)); sizeof(struct
arm_req_resp->response = int2ptr((arm_addr->recvb) + arm_request_response));
sizeof (struct arm_request_response) + arm_req_resp->response =
sizeof (struct arm_request)); int2ptr((arm_addr->recvb) +
sizeof(struct arm_request_response) +
sizeof(struct arm_request));
queue_complete_req(req); queue_complete_req(req);
} }
spin_unlock(&host_info_lock); spin_unlock(&host_info_lock);
return(rcode); return (rcode);
} }
static int arm_lock (struct hpsb_host *host, int nodeid, quadlet_t *store, static int arm_lock(struct hpsb_host *host, int nodeid, quadlet_t * store,
u64 addr, quadlet_t data, quadlet_t arg, int ext_tcode, u16 flags) u64 addr, quadlet_t data, quadlet_t arg, int ext_tcode,
u16 flags)
{ {
struct pending_request *req; struct pending_request *req;
struct host_info *hi; struct host_info *hi;
...@@ -1123,7 +1180,7 @@ static int arm_lock (struct hpsb_host *host, int nodeid, quadlet_t *store, ...@@ -1123,7 +1180,7 @@ static int arm_lock (struct hpsb_host *host, int nodeid, quadlet_t *store,
struct arm_addr *arm_addr = NULL; struct arm_addr *arm_addr = NULL;
struct arm_request *arm_req = NULL; struct arm_request *arm_req = NULL;
struct arm_response *arm_resp = NULL; struct arm_response *arm_resp = NULL;
int found=0, size=0, rcode=-1; int found = 0, size = 0, rcode = -1;
quadlet_t old, new; quadlet_t old, new;
struct arm_request_response *arm_req_resp = NULL; struct arm_request_response *arm_req_resp = NULL;
...@@ -1131,13 +1188,15 @@ static int arm_lock (struct hpsb_host *host, int nodeid, quadlet_t *store, ...@@ -1131,13 +1188,15 @@ static int arm_lock (struct hpsb_host *host, int nodeid, quadlet_t *store,
((ext_tcode & 0xFF) == EXTCODE_LITTLE_ADD)) { ((ext_tcode & 0xFF) == EXTCODE_LITTLE_ADD)) {
DBGMSG("arm_lock called by node: %X " DBGMSG("arm_lock called by node: %X "
"addr: %4.4x %8.8x extcode: %2.2X data: %8.8X", "addr: %4.4x %8.8x extcode: %2.2X data: %8.8X",
nodeid, (u16) ((addr >>32) & 0xFFFF), (u32) (addr & 0xFFFFFFFF), nodeid, (u16) ((addr >> 32) & 0xFFFF),
ext_tcode & 0xFF , be32_to_cpu(data)); (u32) (addr & 0xFFFFFFFF), ext_tcode & 0xFF,
be32_to_cpu(data));
} else { } else {
DBGMSG("arm_lock called by node: %X " DBGMSG("arm_lock called by node: %X "
"addr: %4.4x %8.8x extcode: %2.2X data: %8.8X arg: %8.8X", "addr: %4.4x %8.8x extcode: %2.2X data: %8.8X arg: %8.8X",
nodeid, (u16) ((addr >>32) & 0xFFFF), (u32) (addr & 0xFFFFFFFF), nodeid, (u16) ((addr >> 32) & 0xFFFF),
ext_tcode & 0xFF , be32_to_cpu(data), be32_to_cpu(arg)); (u32) (addr & 0xFFFFFFFF), ext_tcode & 0xFF,
be32_to_cpu(data), be32_to_cpu(arg));
} }
spin_lock(&host_info_lock); spin_lock(&host_info_lock);
hi = find_host_info(host); /* search address-entry */ hi = find_host_info(host); /* search address-entry */
...@@ -1145,9 +1204,12 @@ static int arm_lock (struct hpsb_host *host, int nodeid, quadlet_t *store, ...@@ -1145,9 +1204,12 @@ static int arm_lock (struct hpsb_host *host, int nodeid, quadlet_t *store,
list_for_each_entry(fi, &hi->file_info_list, list) { list_for_each_entry(fi, &hi->file_info_list, list) {
entry = fi->addr_list.next; entry = fi->addr_list.next;
while (entry != &(fi->addr_list)) { while (entry != &(fi->addr_list)) {
arm_addr = list_entry(entry, struct arm_addr, addr_list); arm_addr =
if (((arm_addr->start) <= (addr)) && list_entry(entry, struct arm_addr,
((arm_addr->end) >= (addr+sizeof(*store)))) { addr_list);
if (((arm_addr->start) <= (addr))
&& ((arm_addr->end) >=
(addr + sizeof(*store)))) {
found = 1; found = 1;
break; break;
} }
...@@ -1170,7 +1232,10 @@ static int arm_lock (struct hpsb_host *host, int nodeid, quadlet_t *store, ...@@ -1170,7 +1232,10 @@ static int arm_lock (struct hpsb_host *host, int nodeid, quadlet_t *store,
if (rcode == -1) { if (rcode == -1) {
if (arm_addr->access_rights & ARM_LOCK) { if (arm_addr->access_rights & ARM_LOCK) {
if (!(arm_addr->client_transactions & ARM_LOCK)) { if (!(arm_addr->client_transactions & ARM_LOCK)) {
memcpy(&old,(arm_addr->addr_space_buffer)+(addr-(arm_addr->start)), memcpy(&old,
(arm_addr->addr_space_buffer) + (addr -
(arm_addr->
start)),
sizeof(old)); sizeof(old));
switch (ext_tcode) { switch (ext_tcode) {
case (EXTCODE_MASK_SWAP): case (EXTCODE_MASK_SWAP):
...@@ -1184,39 +1249,50 @@ static int arm_lock (struct hpsb_host *host, int nodeid, quadlet_t *store, ...@@ -1184,39 +1249,50 @@ static int arm_lock (struct hpsb_host *host, int nodeid, quadlet_t *store,
} }
break; break;
case (EXTCODE_FETCH_ADD): case (EXTCODE_FETCH_ADD):
new = cpu_to_be32(be32_to_cpu(data) + be32_to_cpu(old)); new =
cpu_to_be32(be32_to_cpu(data) +
be32_to_cpu(old));
break; break;
case (EXTCODE_LITTLE_ADD): case (EXTCODE_LITTLE_ADD):
new = cpu_to_le32(le32_to_cpu(data) + le32_to_cpu(old)); new =
cpu_to_le32(le32_to_cpu(data) +
le32_to_cpu(old));
break; break;
case (EXTCODE_BOUNDED_ADD): case (EXTCODE_BOUNDED_ADD):
if (old != arg) { if (old != arg) {
new = cpu_to_be32(be32_to_cpu(data) + new =
be32_to_cpu(old)); cpu_to_be32(be32_to_cpu
(data) +
be32_to_cpu
(old));
} else { } else {
new = old; new = old;
} }
break; break;
case (EXTCODE_WRAP_ADD): case (EXTCODE_WRAP_ADD):
if (old != arg) { if (old != arg) {
new = cpu_to_be32(be32_to_cpu(data) + new =
be32_to_cpu(old)); cpu_to_be32(be32_to_cpu
(data) +
be32_to_cpu
(old));
} else { } else {
new = data; new = data;
} }
break; break;
default: default:
rcode = RCODE_TYPE_ERROR; /* function not allowed */ rcode = RCODE_TYPE_ERROR; /* function not allowed */
printk(KERN_ERR "raw1394: arm_lock FAILED " printk(KERN_ERR
"raw1394: arm_lock FAILED "
"ext_tcode not allowed -> rcode_type_error\n"); "ext_tcode not allowed -> rcode_type_error\n");
break; break;
} /*switch*/ } /*switch */
if (rcode == -1) { if (rcode == -1) {
DBGMSG("arm_lock -> (rcode_complete)"); DBGMSG("arm_lock -> (rcode_complete)");
rcode = RCODE_COMPLETE; rcode = RCODE_COMPLETE;
memcpy (store, &old, sizeof(*store)); memcpy(store, &old, sizeof(*store));
memcpy ((arm_addr->addr_space_buffer)+ memcpy((arm_addr->addr_space_buffer) +
(addr-(arm_addr->start)), (addr - (arm_addr->start)),
&new, sizeof(*store)); &new, sizeof(*store));
} }
} }
...@@ -1232,48 +1308,49 @@ static int arm_lock (struct hpsb_host *host, int nodeid, quadlet_t *store, ...@@ -1232,48 +1308,49 @@ static int arm_lock (struct hpsb_host *host, int nodeid, quadlet_t *store,
if (!req) { if (!req) {
DBGMSG("arm_lock -> rcode_conflict_error"); DBGMSG("arm_lock -> rcode_conflict_error");
spin_unlock(&host_info_lock); spin_unlock(&host_info_lock);
return(RCODE_CONFLICT_ERROR); /* A resource conflict was detected. return (RCODE_CONFLICT_ERROR); /* A resource conflict was detected.
The request may be retried */ The request may be retried */
} }
size = sizeof(struct arm_request)+sizeof(struct arm_response) + size = sizeof(struct arm_request) + sizeof(struct arm_response) + 3 * sizeof(*store) + sizeof(struct arm_request_response); /* maximum */
3 * sizeof(*store) +
sizeof (struct arm_request_response); /* maximum */
req->data = kmalloc(size, SLAB_ATOMIC); req->data = kmalloc(size, SLAB_ATOMIC);
if (!(req->data)) { if (!(req->data)) {
free_pending_request(req); free_pending_request(req);
DBGMSG("arm_lock -> rcode_conflict_error"); DBGMSG("arm_lock -> rcode_conflict_error");
spin_unlock(&host_info_lock); spin_unlock(&host_info_lock);
return(RCODE_CONFLICT_ERROR); /* A resource conflict was detected. return (RCODE_CONFLICT_ERROR); /* A resource conflict was detected.
The request may be retried */ The request may be retried */
} }
req->free_data=1; req->free_data = 1;
arm_req_resp = (struct arm_request_response *) (req->data); arm_req_resp = (struct arm_request_response *)(req->data);
arm_req = (struct arm_request *) ((byte_t *)(req->data) + arm_req = (struct arm_request *)((byte_t *) (req->data) +
(sizeof (struct arm_request_response))); (sizeof
arm_resp = (struct arm_response *) ((byte_t *)(arm_req) + (struct
arm_request_response)));
arm_resp =
(struct arm_response *)((byte_t *) (arm_req) +
(sizeof(struct arm_request))); (sizeof(struct arm_request)));
buf1 = (byte_t *)arm_resp + sizeof(struct arm_response); buf1 = (byte_t *) arm_resp + sizeof(struct arm_response);
buf2 = buf1 + 2 * sizeof(*store); buf2 = buf1 + 2 * sizeof(*store);
if ((ext_tcode == EXTCODE_FETCH_ADD) || if ((ext_tcode == EXTCODE_FETCH_ADD) ||
(ext_tcode == EXTCODE_LITTLE_ADD)) { (ext_tcode == EXTCODE_LITTLE_ADD)) {
arm_req->buffer_length = sizeof(*store); arm_req->buffer_length = sizeof(*store);
memcpy (buf1, &data, sizeof(*store)); memcpy(buf1, &data, sizeof(*store));
} else { } else {
arm_req->buffer_length = 2 * sizeof(*store); arm_req->buffer_length = 2 * sizeof(*store);
memcpy (buf1, &arg, sizeof(*store)); memcpy(buf1, &arg, sizeof(*store));
memcpy (buf1 + sizeof(*store), &data, sizeof(*store)); memcpy(buf1 + sizeof(*store), &data, sizeof(*store));
} }
if (rcode == RCODE_COMPLETE) { if (rcode == RCODE_COMPLETE) {
arm_resp->buffer_length = sizeof(*store); arm_resp->buffer_length = sizeof(*store);
memcpy (buf2, &old, sizeof(*store)); memcpy(buf2, &old, sizeof(*store));
} else { } else {
arm_resp->buffer_length = 0; arm_resp->buffer_length = 0;
} }
req->file_info = fi; req->file_info = fi;
req->req.type = RAW1394_REQ_ARM; req->req.type = RAW1394_REQ_ARM;
req->req.generation = get_hpsb_generation(host); req->req.generation = get_hpsb_generation(host);
req->req.misc = ( (((sizeof(*store)) << 16) & (0xFFFF0000)) | req->req.misc = ((((sizeof(*store)) << 16) & (0xFFFF0000)) |
(ARM_LOCK & 0xFF)); (ARM_LOCK & 0xFF));
req->req.tag = arm_addr->arm_tag; req->req.tag = arm_addr->arm_tag;
req->req.recvb = arm_addr->recvb; req->req.recvb = arm_addr->recvb;
...@@ -1287,27 +1364,31 @@ static int arm_lock (struct hpsb_host *host, int nodeid, quadlet_t *store, ...@@ -1287,27 +1364,31 @@ static int arm_lock (struct hpsb_host *host, int nodeid, quadlet_t *store,
arm_req->tcode = (flags >> 4) & 0x0f; arm_req->tcode = (flags >> 4) & 0x0f;
arm_resp->response_code = rcode; arm_resp->response_code = rcode;
arm_req_resp->request = int2ptr((arm_addr->recvb) + arm_req_resp->request = int2ptr((arm_addr->recvb) +
sizeof (struct arm_request_response)); sizeof(struct
arm_req_resp->response = int2ptr((arm_addr->recvb) + arm_request_response));
sizeof (struct arm_request_response) + arm_req_resp->response =
sizeof (struct arm_request)); int2ptr((arm_addr->recvb) +
arm_req->buffer = int2ptr((arm_addr->recvb) + sizeof(struct arm_request_response) +
sizeof (struct arm_request_response) + sizeof(struct arm_request));
sizeof (struct arm_request) + arm_req->buffer =
sizeof (struct arm_response)); int2ptr((arm_addr->recvb) +
arm_resp->buffer = int2ptr((arm_addr->recvb) + sizeof(struct arm_request_response) +
sizeof (struct arm_request_response) + sizeof(struct arm_request) +
sizeof (struct arm_request) + sizeof(struct arm_response));
sizeof (struct arm_response) + arm_resp->buffer =
2* sizeof (*store)); int2ptr((arm_addr->recvb) +
sizeof(struct arm_request_response) +
sizeof(struct arm_request) +
sizeof(struct arm_response) + 2 * sizeof(*store));
queue_complete_req(req); queue_complete_req(req);
} }
spin_unlock(&host_info_lock); spin_unlock(&host_info_lock);
return(rcode); return (rcode);
} }
static int arm_lock64 (struct hpsb_host *host, int nodeid, octlet_t *store, static int arm_lock64(struct hpsb_host *host, int nodeid, octlet_t * store,
u64 addr, octlet_t data, octlet_t arg, int ext_tcode, u16 flags) u64 addr, octlet_t data, octlet_t arg, int ext_tcode,
u16 flags)
{ {
struct pending_request *req; struct pending_request *req;
struct host_info *hi; struct host_info *hi;
...@@ -1316,7 +1397,7 @@ static int arm_lock64 (struct hpsb_host *host, int nodeid, octlet_t *store, ...@@ -1316,7 +1397,7 @@ static int arm_lock64 (struct hpsb_host *host, int nodeid, octlet_t *store,
struct arm_addr *arm_addr = NULL; struct arm_addr *arm_addr = NULL;
struct arm_request *arm_req = NULL; struct arm_request *arm_req = NULL;
struct arm_response *arm_resp = NULL; struct arm_response *arm_resp = NULL;
int found=0, size=0, rcode=-1; int found = 0, size = 0, rcode = -1;
octlet_t old, new; octlet_t old, new;
struct arm_request_response *arm_req_resp = NULL; struct arm_request_response *arm_req_resp = NULL;
...@@ -1324,18 +1405,18 @@ static int arm_lock64 (struct hpsb_host *host, int nodeid, octlet_t *store, ...@@ -1324,18 +1405,18 @@ static int arm_lock64 (struct hpsb_host *host, int nodeid, octlet_t *store,
((ext_tcode & 0xFF) == EXTCODE_LITTLE_ADD)) { ((ext_tcode & 0xFF) == EXTCODE_LITTLE_ADD)) {
DBGMSG("arm_lock64 called by node: %X " DBGMSG("arm_lock64 called by node: %X "
"addr: %4.4x %8.8x extcode: %2.2X data: %8.8X %8.8X ", "addr: %4.4x %8.8x extcode: %2.2X data: %8.8X %8.8X ",
nodeid, (u16) ((addr >>32) & 0xFFFF), nodeid, (u16) ((addr >> 32) & 0xFFFF),
(u32) (addr & 0xFFFFFFFF), (u32) (addr & 0xFFFFFFFF),
ext_tcode & 0xFF , ext_tcode & 0xFF,
(u32) ((be64_to_cpu(data) >> 32) & 0xFFFFFFFF), (u32) ((be64_to_cpu(data) >> 32) & 0xFFFFFFFF),
(u32) (be64_to_cpu(data) & 0xFFFFFFFF)); (u32) (be64_to_cpu(data) & 0xFFFFFFFF));
} else { } else {
DBGMSG("arm_lock64 called by node: %X " DBGMSG("arm_lock64 called by node: %X "
"addr: %4.4x %8.8x extcode: %2.2X data: %8.8X %8.8X arg: " "addr: %4.4x %8.8x extcode: %2.2X data: %8.8X %8.8X arg: "
"%8.8X %8.8X ", "%8.8X %8.8X ",
nodeid, (u16) ((addr >>32) & 0xFFFF), nodeid, (u16) ((addr >> 32) & 0xFFFF),
(u32) (addr & 0xFFFFFFFF), (u32) (addr & 0xFFFFFFFF),
ext_tcode & 0xFF , ext_tcode & 0xFF,
(u32) ((be64_to_cpu(data) >> 32) & 0xFFFFFFFF), (u32) ((be64_to_cpu(data) >> 32) & 0xFFFFFFFF),
(u32) (be64_to_cpu(data) & 0xFFFFFFFF), (u32) (be64_to_cpu(data) & 0xFFFFFFFF),
(u32) ((be64_to_cpu(arg) >> 32) & 0xFFFFFFFF), (u32) ((be64_to_cpu(arg) >> 32) & 0xFFFFFFFF),
...@@ -1347,9 +1428,12 @@ static int arm_lock64 (struct hpsb_host *host, int nodeid, octlet_t *store, ...@@ -1347,9 +1428,12 @@ static int arm_lock64 (struct hpsb_host *host, int nodeid, octlet_t *store,
list_for_each_entry(fi, &hi->file_info_list, list) { list_for_each_entry(fi, &hi->file_info_list, list) {
entry = fi->addr_list.next; entry = fi->addr_list.next;
while (entry != &(fi->addr_list)) { while (entry != &(fi->addr_list)) {
arm_addr = list_entry(entry, struct arm_addr, addr_list); arm_addr =
if (((arm_addr->start) <= (addr)) && list_entry(entry, struct arm_addr,
((arm_addr->end) >= (addr+sizeof(*store)))) { addr_list);
if (((arm_addr->start) <= (addr))
&& ((arm_addr->end) >=
(addr + sizeof(*store)))) {
found = 1; found = 1;
break; break;
} }
...@@ -1362,7 +1446,8 @@ static int arm_lock64 (struct hpsb_host *host, int nodeid, octlet_t *store, ...@@ -1362,7 +1446,8 @@ static int arm_lock64 (struct hpsb_host *host, int nodeid, octlet_t *store,
} }
rcode = -1; rcode = -1;
if (!found) { if (!found) {
printk(KERN_ERR "raw1394: arm_lock64 FAILED addr_entry not found" printk(KERN_ERR
"raw1394: arm_lock64 FAILED addr_entry not found"
" -> rcode_address_error\n"); " -> rcode_address_error\n");
spin_unlock(&host_info_lock); spin_unlock(&host_info_lock);
return (RCODE_ADDRESS_ERROR); return (RCODE_ADDRESS_ERROR);
...@@ -1372,7 +1457,10 @@ static int arm_lock64 (struct hpsb_host *host, int nodeid, octlet_t *store, ...@@ -1372,7 +1457,10 @@ static int arm_lock64 (struct hpsb_host *host, int nodeid, octlet_t *store,
if (rcode == -1) { if (rcode == -1) {
if (arm_addr->access_rights & ARM_LOCK) { if (arm_addr->access_rights & ARM_LOCK) {
if (!(arm_addr->client_transactions & ARM_LOCK)) { if (!(arm_addr->client_transactions & ARM_LOCK)) {
memcpy(&old,(arm_addr->addr_space_buffer)+(addr-(arm_addr->start)), memcpy(&old,
(arm_addr->addr_space_buffer) + (addr -
(arm_addr->
start)),
sizeof(old)); sizeof(old));
switch (ext_tcode) { switch (ext_tcode) {
case (EXTCODE_MASK_SWAP): case (EXTCODE_MASK_SWAP):
...@@ -1386,45 +1474,58 @@ static int arm_lock64 (struct hpsb_host *host, int nodeid, octlet_t *store, ...@@ -1386,45 +1474,58 @@ static int arm_lock64 (struct hpsb_host *host, int nodeid, octlet_t *store,
} }
break; break;
case (EXTCODE_FETCH_ADD): case (EXTCODE_FETCH_ADD):
new = cpu_to_be64(be64_to_cpu(data) + be64_to_cpu(old)); new =
cpu_to_be64(be64_to_cpu(data) +
be64_to_cpu(old));
break; break;
case (EXTCODE_LITTLE_ADD): case (EXTCODE_LITTLE_ADD):
new = cpu_to_le64(le64_to_cpu(data) + le64_to_cpu(old)); new =
cpu_to_le64(le64_to_cpu(data) +
le64_to_cpu(old));
break; break;
case (EXTCODE_BOUNDED_ADD): case (EXTCODE_BOUNDED_ADD):
if (old != arg) { if (old != arg) {
new = cpu_to_be64(be64_to_cpu(data) + new =
be64_to_cpu(old)); cpu_to_be64(be64_to_cpu
(data) +
be64_to_cpu
(old));
} else { } else {
new = old; new = old;
} }
break; break;
case (EXTCODE_WRAP_ADD): case (EXTCODE_WRAP_ADD):
if (old != arg) { if (old != arg) {
new = cpu_to_be64(be64_to_cpu(data) + new =
be64_to_cpu(old)); cpu_to_be64(be64_to_cpu
(data) +
be64_to_cpu
(old));
} else { } else {
new = data; new = data;
} }
break; break;
default: default:
printk(KERN_ERR "raw1394: arm_lock64 FAILED " printk(KERN_ERR
"raw1394: arm_lock64 FAILED "
"ext_tcode not allowed -> rcode_type_error\n"); "ext_tcode not allowed -> rcode_type_error\n");
rcode = RCODE_TYPE_ERROR; /* function not allowed */ rcode = RCODE_TYPE_ERROR; /* function not allowed */
break; break;
} /*switch*/ } /*switch */
if (rcode == -1) { if (rcode == -1) {
DBGMSG("arm_lock64 -> (rcode_complete)"); DBGMSG
("arm_lock64 -> (rcode_complete)");
rcode = RCODE_COMPLETE; rcode = RCODE_COMPLETE;
memcpy (store, &old, sizeof(*store)); memcpy(store, &old, sizeof(*store));
memcpy ((arm_addr->addr_space_buffer)+ memcpy((arm_addr->addr_space_buffer) +
(addr-(arm_addr->start)), (addr - (arm_addr->start)),
&new, sizeof(*store)); &new, sizeof(*store));
} }
} }
} else { } else {
rcode = RCODE_TYPE_ERROR; /* function not allowed */ rcode = RCODE_TYPE_ERROR; /* function not allowed */
DBGMSG("arm_lock64 -> rcode_type_error (access denied)"); DBGMSG
("arm_lock64 -> rcode_type_error (access denied)");
} }
} }
if (arm_addr->notification_options & ARM_LOCK) { if (arm_addr->notification_options & ARM_LOCK) {
...@@ -1434,48 +1535,49 @@ static int arm_lock64 (struct hpsb_host *host, int nodeid, octlet_t *store, ...@@ -1434,48 +1535,49 @@ static int arm_lock64 (struct hpsb_host *host, int nodeid, octlet_t *store,
if (!req) { if (!req) {
spin_unlock(&host_info_lock); spin_unlock(&host_info_lock);
DBGMSG("arm_lock64 -> rcode_conflict_error"); DBGMSG("arm_lock64 -> rcode_conflict_error");
return(RCODE_CONFLICT_ERROR); /* A resource conflict was detected. return (RCODE_CONFLICT_ERROR); /* A resource conflict was detected.
The request may be retried */ The request may be retried */
} }
size = sizeof(struct arm_request)+sizeof(struct arm_response) + size = sizeof(struct arm_request) + sizeof(struct arm_response) + 3 * sizeof(*store) + sizeof(struct arm_request_response); /* maximum */
3 * sizeof(*store) +
sizeof (struct arm_request_response); /* maximum */
req->data = kmalloc(size, SLAB_ATOMIC); req->data = kmalloc(size, SLAB_ATOMIC);
if (!(req->data)) { if (!(req->data)) {
free_pending_request(req); free_pending_request(req);
spin_unlock(&host_info_lock); spin_unlock(&host_info_lock);
DBGMSG("arm_lock64 -> rcode_conflict_error"); DBGMSG("arm_lock64 -> rcode_conflict_error");
return(RCODE_CONFLICT_ERROR); /* A resource conflict was detected. return (RCODE_CONFLICT_ERROR); /* A resource conflict was detected.
The request may be retried */ The request may be retried */
} }
req->free_data=1; req->free_data = 1;
arm_req_resp = (struct arm_request_response *) (req->data); arm_req_resp = (struct arm_request_response *)(req->data);
arm_req = (struct arm_request *) ((byte_t *)(req->data) + arm_req = (struct arm_request *)((byte_t *) (req->data) +
(sizeof (struct arm_request_response))); (sizeof
arm_resp = (struct arm_response *) ((byte_t *)(arm_req) + (struct
arm_request_response)));
arm_resp =
(struct arm_response *)((byte_t *) (arm_req) +
(sizeof(struct arm_request))); (sizeof(struct arm_request)));
buf1 = (byte_t *)arm_resp + sizeof(struct arm_response); buf1 = (byte_t *) arm_resp + sizeof(struct arm_response);
buf2 = buf1 + 2 * sizeof(*store); buf2 = buf1 + 2 * sizeof(*store);
if ((ext_tcode == EXTCODE_FETCH_ADD) || if ((ext_tcode == EXTCODE_FETCH_ADD) ||
(ext_tcode == EXTCODE_LITTLE_ADD)) { (ext_tcode == EXTCODE_LITTLE_ADD)) {
arm_req->buffer_length = sizeof(*store); arm_req->buffer_length = sizeof(*store);
memcpy (buf1, &data, sizeof(*store)); memcpy(buf1, &data, sizeof(*store));
} else { } else {
arm_req->buffer_length = 2 * sizeof(*store); arm_req->buffer_length = 2 * sizeof(*store);
memcpy (buf1, &arg, sizeof(*store)); memcpy(buf1, &arg, sizeof(*store));
memcpy (buf1 + sizeof(*store), &data, sizeof(*store)); memcpy(buf1 + sizeof(*store), &data, sizeof(*store));
} }
if (rcode == RCODE_COMPLETE) { if (rcode == RCODE_COMPLETE) {
arm_resp->buffer_length = sizeof(*store); arm_resp->buffer_length = sizeof(*store);
memcpy (buf2, &old, sizeof(*store)); memcpy(buf2, &old, sizeof(*store));
} else { } else {
arm_resp->buffer_length = 0; arm_resp->buffer_length = 0;
} }
req->file_info = fi; req->file_info = fi;
req->req.type = RAW1394_REQ_ARM; req->req.type = RAW1394_REQ_ARM;
req->req.generation = get_hpsb_generation(host); req->req.generation = get_hpsb_generation(host);
req->req.misc = ( (((sizeof(*store)) << 16) & (0xFFFF0000)) | req->req.misc = ((((sizeof(*store)) << 16) & (0xFFFF0000)) |
(ARM_LOCK & 0xFF)); (ARM_LOCK & 0xFF));
req->req.tag = arm_addr->arm_tag; req->req.tag = arm_addr->arm_tag;
req->req.recvb = arm_addr->recvb; req->req.recvb = arm_addr->recvb;
...@@ -1489,23 +1591,26 @@ static int arm_lock64 (struct hpsb_host *host, int nodeid, octlet_t *store, ...@@ -1489,23 +1591,26 @@ static int arm_lock64 (struct hpsb_host *host, int nodeid, octlet_t *store,
arm_req->tcode = (flags >> 4) & 0x0f; arm_req->tcode = (flags >> 4) & 0x0f;
arm_resp->response_code = rcode; arm_resp->response_code = rcode;
arm_req_resp->request = int2ptr((arm_addr->recvb) + arm_req_resp->request = int2ptr((arm_addr->recvb) +
sizeof (struct arm_request_response)); sizeof(struct
arm_req_resp->response = int2ptr((arm_addr->recvb) + arm_request_response));
sizeof (struct arm_request_response) + arm_req_resp->response =
sizeof (struct arm_request)); int2ptr((arm_addr->recvb) +
arm_req->buffer = int2ptr((arm_addr->recvb) + sizeof(struct arm_request_response) +
sizeof (struct arm_request_response) + sizeof(struct arm_request));
sizeof (struct arm_request) + arm_req->buffer =
sizeof (struct arm_response)); int2ptr((arm_addr->recvb) +
arm_resp->buffer = int2ptr((arm_addr->recvb) + sizeof(struct arm_request_response) +
sizeof (struct arm_request_response) + sizeof(struct arm_request) +
sizeof (struct arm_request) + sizeof(struct arm_response));
sizeof (struct arm_response) + arm_resp->buffer =
2* sizeof (*store)); int2ptr((arm_addr->recvb) +
sizeof(struct arm_request_response) +
sizeof(struct arm_request) +
sizeof(struct arm_response) + 2 * sizeof(*store));
queue_complete_req(req); queue_complete_req(req);
} }
spin_unlock(&host_info_lock); spin_unlock(&host_info_lock);
return(rcode); return (rcode);
} }
static int arm_register(struct file_info *fi, struct pending_request *req) static int arm_register(struct file_info *fi, struct pending_request *req)
...@@ -1523,13 +1628,14 @@ static int arm_register(struct file_info *fi, struct pending_request *req) ...@@ -1523,13 +1628,14 @@ static int arm_register(struct file_info *fi, struct pending_request *req)
"addr(Offset): %8.8x %8.8x length: %u " "addr(Offset): %8.8x %8.8x length: %u "
"rights: %2.2X notify: %2.2X " "rights: %2.2X notify: %2.2X "
"max_blk_len: %4.4X", "max_blk_len: %4.4X",
(u32) ((req->req.address >>32) & 0xFFFF), (u32) ((req->req.address >> 32) & 0xFFFF),
(u32) (req->req.address & 0xFFFFFFFF), (u32) (req->req.address & 0xFFFFFFFF),
req->req.length, ((req->req.misc >> 8) & 0xFF), req->req.length, ((req->req.misc >> 8) & 0xFF),
(req->req.misc & 0xFF),((req->req.misc >> 16) & 0xFFFF)); (req->req.misc & 0xFF), ((req->req.misc >> 16) & 0xFFFF));
/* check addressrange */ /* check addressrange */
if ((((req->req.address) & ~(0xFFFFFFFFFFFFULL)) != 0) || if ((((req->req.address) & ~(0xFFFFFFFFFFFFULL)) != 0) ||
(((req->req.address + req->req.length) & ~(0xFFFFFFFFFFFFULL)) != 0)) { (((req->req.address + req->req.length) & ~(0xFFFFFFFFFFFFULL)) !=
0)) {
req->req.length = 0; req->req.length = 0;
return (-EINVAL); return (-EINVAL);
} }
...@@ -1540,19 +1646,20 @@ static int arm_register(struct file_info *fi, struct pending_request *req) ...@@ -1540,19 +1646,20 @@ static int arm_register(struct file_info *fi, struct pending_request *req)
return (-ENOMEM); return (-ENOMEM);
} }
/* allocation of addr_space_buffer */ /* allocation of addr_space_buffer */
addr->addr_space_buffer = (u8 *)vmalloc(req->req.length); addr->addr_space_buffer = (u8 *) vmalloc(req->req.length);
if (!(addr->addr_space_buffer)) { if (!(addr->addr_space_buffer)) {
kfree(addr); kfree(addr);
req->req.length = 0; req->req.length = 0;
return (-ENOMEM); return (-ENOMEM);
} }
/* initialization of addr_space_buffer */ /* initialization of addr_space_buffer */
if ((req->req.sendb)== (unsigned long)NULL) { if ((req->req.sendb) == (unsigned long)NULL) {
/* init: set 0 */ /* init: set 0 */
memset(addr->addr_space_buffer, 0,req->req.length); memset(addr->addr_space_buffer, 0, req->req.length);
} else { } else {
/* init: user -> kernel */ /* init: user -> kernel */
if (copy_from_user(addr->addr_space_buffer,int2ptr(req->req.sendb), if (copy_from_user
(addr->addr_space_buffer, int2ptr(req->req.sendb),
req->req.length)) { req->req.length)) {
vfree(addr->addr_space_buffer); vfree(addr->addr_space_buffer);
kfree(addr); kfree(addr);
...@@ -1578,9 +1685,10 @@ static int arm_register(struct file_info *fi, struct pending_request *req) ...@@ -1578,9 +1685,10 @@ static int arm_register(struct file_info *fi, struct pending_request *req)
list_for_each_entry(fi_hlp, &hi->file_info_list, list) { list_for_each_entry(fi_hlp, &hi->file_info_list, list) {
entry = fi_hlp->addr_list.next; entry = fi_hlp->addr_list.next;
while (entry != &(fi_hlp->addr_list)) { while (entry != &(fi_hlp->addr_list)) {
arm_addr = list_entry(entry, struct arm_addr, addr_list); arm_addr =
if ( (arm_addr->start == addr->start) && list_entry(entry, struct arm_addr, addr_list);
(arm_addr->end == addr->end)) { if ((arm_addr->start == addr->start)
&& (arm_addr->end == addr->end)) {
DBGMSG("same host ownes same " DBGMSG("same host ownes same "
"addressrange -> EALREADY"); "addressrange -> EALREADY");
same_host = 1; same_host = 1;
...@@ -1605,10 +1713,13 @@ static int arm_register(struct file_info *fi, struct pending_request *req) ...@@ -1605,10 +1713,13 @@ static int arm_register(struct file_info *fi, struct pending_request *req)
list_for_each_entry(fi_hlp, &hi->file_info_list, list) { list_for_each_entry(fi_hlp, &hi->file_info_list, list) {
entry = fi_hlp->addr_list.next; entry = fi_hlp->addr_list.next;
while (entry != &(fi_hlp->addr_list)) { while (entry != &(fi_hlp->addr_list)) {
arm_addr = list_entry(entry, struct arm_addr, addr_list); arm_addr =
if ( (arm_addr->start == addr->start) && list_entry(entry, struct arm_addr,
(arm_addr->end == addr->end)) { addr_list);
DBGMSG("another host ownes same " if ((arm_addr->start == addr->start)
&& (arm_addr->end == addr->end)) {
DBGMSG
("another host ownes same "
"addressrange"); "addressrange");
another_host = 1; another_host = 1;
break; break;
...@@ -1624,7 +1735,7 @@ static int arm_register(struct file_info *fi, struct pending_request *req) ...@@ -1624,7 +1735,7 @@ static int arm_register(struct file_info *fi, struct pending_request *req)
if (another_host) { if (another_host) {
DBGMSG("another hosts entry is valid -> SUCCESS"); DBGMSG("another hosts entry is valid -> SUCCESS");
if (copy_to_user(int2ptr(req->req.recvb), if (copy_to_user(int2ptr(req->req.recvb),
&addr->start,sizeof(u64))) { &addr->start, sizeof(u64))) {
printk(KERN_ERR "raw1394: arm_register failed " printk(KERN_ERR "raw1394: arm_register failed "
" address-range-entry is invalid -> EFAULT !!!\n"); " address-range-entry is invalid -> EFAULT !!!\n");
vfree(addr->addr_space_buffer); vfree(addr->addr_space_buffer);
...@@ -1638,13 +1749,15 @@ static int arm_register(struct file_info *fi, struct pending_request *req) ...@@ -1638,13 +1749,15 @@ static int arm_register(struct file_info *fi, struct pending_request *req)
spin_unlock_irqrestore(&host_info_lock, flags); spin_unlock_irqrestore(&host_info_lock, flags);
return sizeof(struct raw1394_request); return sizeof(struct raw1394_request);
} }
retval = hpsb_register_addrspace(&raw1394_highlevel, fi->host, &arm_ops, req->req.address, retval =
hpsb_register_addrspace(&raw1394_highlevel, fi->host, &arm_ops,
req->req.address,
req->req.address + req->req.length); req->req.address + req->req.length);
if (retval) { if (retval) {
/* INSERT ENTRY */ /* INSERT ENTRY */
list_add_tail(&addr->addr_list, &fi->addr_list); list_add_tail(&addr->addr_list, &fi->addr_list);
} else { } else {
DBGMSG("arm_register failed errno: %d \n",retval); DBGMSG("arm_register failed errno: %d \n", retval);
vfree(addr->addr_space_buffer); vfree(addr->addr_space_buffer);
kfree(addr); kfree(addr);
spin_unlock_irqrestore(&host_info_lock, flags); spin_unlock_irqrestore(&host_info_lock, flags);
...@@ -1669,7 +1782,7 @@ static int arm_unregister(struct file_info *fi, struct pending_request *req) ...@@ -1669,7 +1782,7 @@ static int arm_unregister(struct file_info *fi, struct pending_request *req)
DBGMSG("arm_Unregister called addr(Offset): " DBGMSG("arm_Unregister called addr(Offset): "
"%8.8x %8.8x", "%8.8x %8.8x",
(u32) ((req->req.address >>32) & 0xFFFF), (u32) ((req->req.address >> 32) & 0xFFFF),
(u32) (req->req.address & 0xFFFFFFFF)); (u32) (req->req.address & 0xFFFFFFFF));
spin_lock_irqsave(&host_info_lock, flags); spin_lock_irqsave(&host_info_lock, flags);
/* get addr */ /* get addr */
...@@ -1697,9 +1810,9 @@ static int arm_unregister(struct file_info *fi, struct pending_request *req) ...@@ -1697,9 +1810,9 @@ static int arm_unregister(struct file_info *fi, struct pending_request *req)
entry = fi_hlp->addr_list.next; entry = fi_hlp->addr_list.next;
while (entry != &(fi_hlp->addr_list)) { while (entry != &(fi_hlp->addr_list)) {
arm_addr = list_entry(entry, arm_addr = list_entry(entry,
struct arm_addr, addr_list); struct arm_addr,
if (arm_addr->start == addr_list);
addr->start) { if (arm_addr->start == addr->start) {
DBGMSG("another host ownes " DBGMSG("another host ownes "
"same addressrange"); "same addressrange");
another_host = 1; another_host = 1;
...@@ -1722,7 +1835,9 @@ static int arm_unregister(struct file_info *fi, struct pending_request *req) ...@@ -1722,7 +1835,9 @@ static int arm_unregister(struct file_info *fi, struct pending_request *req)
spin_unlock_irqrestore(&host_info_lock, flags); spin_unlock_irqrestore(&host_info_lock, flags);
return sizeof(struct raw1394_request); return sizeof(struct raw1394_request);
} }
retval = hpsb_unregister_addrspace(&raw1394_highlevel, fi->host, addr->start); retval =
hpsb_unregister_addrspace(&raw1394_highlevel, fi->host,
addr->start);
if (!retval) { if (!retval) {
printk(KERN_ERR "raw1394: arm_Unregister failed -> EINVAL\n"); printk(KERN_ERR "raw1394: arm_Unregister failed -> EINVAL\n");
spin_unlock_irqrestore(&host_info_lock, flags); spin_unlock_irqrestore(&host_info_lock, flags);
...@@ -1749,8 +1864,7 @@ static int arm_get_buf(struct file_info *fi, struct pending_request *req) ...@@ -1749,8 +1864,7 @@ static int arm_get_buf(struct file_info *fi, struct pending_request *req)
DBGMSG("arm_get_buf " DBGMSG("arm_get_buf "
"addr(Offset): %04X %08X length: %u", "addr(Offset): %04X %08X length: %u",
(u32) ((req->req.address >> 32) & 0xFFFF), (u32) ((req->req.address >> 32) & 0xFFFF),
(u32) (req->req.address & 0xFFFFFFFF), (u32) (req->req.address & 0xFFFFFFFF), (u32) req->req.length);
(u32) req->req.length);
spin_lock_irqsave(&host_info_lock, flags); spin_lock_irqsave(&host_info_lock, flags);
entry = fi->addr_list.next; entry = fi->addr_list.next;
...@@ -1761,13 +1875,18 @@ static int arm_get_buf(struct file_info *fi, struct pending_request *req) ...@@ -1761,13 +1875,18 @@ static int arm_get_buf(struct file_info *fi, struct pending_request *req)
if (req->req.address + req->req.length <= arm_addr->end) { if (req->req.address + req->req.length <= arm_addr->end) {
offset = req->req.address - arm_addr->start; offset = req->req.address - arm_addr->start;
DBGMSG("arm_get_buf copy_to_user( %08X, %p, %u )", DBGMSG
("arm_get_buf copy_to_user( %08X, %p, %u )",
(u32) req->req.recvb, (u32) req->req.recvb,
arm_addr->addr_space_buffer+offset, arm_addr->addr_space_buffer + offset,
(u32) req->req.length); (u32) req->req.length);
if (copy_to_user(int2ptr(req->req.recvb), arm_addr->addr_space_buffer+offset, req->req.length)) { if (copy_to_user
spin_unlock_irqrestore(&host_info_lock, flags); (int2ptr(req->req.recvb),
arm_addr->addr_space_buffer + offset,
req->req.length)) {
spin_unlock_irqrestore(&host_info_lock,
flags);
return (-EFAULT); return (-EFAULT);
} }
...@@ -1789,7 +1908,6 @@ static int arm_get_buf(struct file_info *fi, struct pending_request *req) ...@@ -1789,7 +1908,6 @@ static int arm_get_buf(struct file_info *fi, struct pending_request *req)
return (-EINVAL); return (-EINVAL);
} }
/* Copy data from user buffer to ARM buffer(s). */ /* Copy data from user buffer to ARM buffer(s). */
static int arm_set_buf(struct file_info *fi, struct pending_request *req) static int arm_set_buf(struct file_info *fi, struct pending_request *req)
{ {
...@@ -1802,9 +1920,7 @@ static int arm_set_buf(struct file_info *fi, struct pending_request *req) ...@@ -1802,9 +1920,7 @@ static int arm_set_buf(struct file_info *fi, struct pending_request *req)
DBGMSG("arm_set_buf " DBGMSG("arm_set_buf "
"addr(Offset): %04X %08X length: %u", "addr(Offset): %04X %08X length: %u",
(u32) ((req->req.address >> 32) & 0xFFFF), (u32) ((req->req.address >> 32) & 0xFFFF),
(u32) (req->req.address & 0xFFFFFFFF), (u32) (req->req.address & 0xFFFFFFFF), (u32) req->req.length);
(u32) req->req.length);
spin_lock_irqsave(&host_info_lock, flags); spin_lock_irqsave(&host_info_lock, flags);
entry = fi->addr_list.next; entry = fi->addr_list.next;
...@@ -1815,13 +1931,18 @@ static int arm_set_buf(struct file_info *fi, struct pending_request *req) ...@@ -1815,13 +1931,18 @@ static int arm_set_buf(struct file_info *fi, struct pending_request *req)
if (req->req.address + req->req.length <= arm_addr->end) { if (req->req.address + req->req.length <= arm_addr->end) {
offset = req->req.address - arm_addr->start; offset = req->req.address - arm_addr->start;
DBGMSG("arm_set_buf copy_from_user( %p, %08X, %u )", DBGMSG
arm_addr->addr_space_buffer+offset, ("arm_set_buf copy_from_user( %p, %08X, %u )",
arm_addr->addr_space_buffer + offset,
(u32) req->req.sendb, (u32) req->req.sendb,
(u32) req->req.length); (u32) req->req.length);
if (copy_from_user(arm_addr->addr_space_buffer+offset, int2ptr(req->req.sendb), req->req.length)) { if (copy_from_user
spin_unlock_irqrestore(&host_info_lock, flags); (arm_addr->addr_space_buffer + offset,
int2ptr(req->req.sendb),
req->req.length)) {
spin_unlock_irqrestore(&host_info_lock,
flags);
return (-EFAULT); return (-EFAULT);
} }
...@@ -1843,10 +1964,10 @@ static int arm_set_buf(struct file_info *fi, struct pending_request *req) ...@@ -1843,10 +1964,10 @@ static int arm_set_buf(struct file_info *fi, struct pending_request *req)
static int reset_notification(struct file_info *fi, struct pending_request *req) static int reset_notification(struct file_info *fi, struct pending_request *req)
{ {
DBGMSG("reset_notification called - switch %s ", DBGMSG("reset_notification called - switch %s ",
(req->req.misc == RAW1394_NOTIFY_OFF)?"OFF":"ON"); (req->req.misc == RAW1394_NOTIFY_OFF) ? "OFF" : "ON");
if ((req->req.misc == RAW1394_NOTIFY_OFF) || if ((req->req.misc == RAW1394_NOTIFY_OFF) ||
(req->req.misc == RAW1394_NOTIFY_ON)) { (req->req.misc == RAW1394_NOTIFY_ON)) {
fi->notification=(u8)req->req.misc; fi->notification = (u8) req->req.misc;
free_pending_request(req); /* we have to free the request, because we queue no response, and therefore nobody will free it */ free_pending_request(req); /* we have to free the request, because we queue no response, and therefore nobody will free it */
return sizeof(struct raw1394_request); return sizeof(struct raw1394_request);
} }
...@@ -1857,16 +1978,18 @@ static int reset_notification(struct file_info *fi, struct pending_request *req) ...@@ -1857,16 +1978,18 @@ static int reset_notification(struct file_info *fi, struct pending_request *req)
static int write_phypacket(struct file_info *fi, struct pending_request *req) static int write_phypacket(struct file_info *fi, struct pending_request *req)
{ {
struct hpsb_packet *packet = NULL; struct hpsb_packet *packet = NULL;
int retval=0; int retval = 0;
quadlet_t data; quadlet_t data;
data = be32_to_cpu((u32)req->req.sendb); data = be32_to_cpu((u32) req->req.sendb);
DBGMSG("write_phypacket called - quadlet 0x%8.8x ",data); DBGMSG("write_phypacket called - quadlet 0x%8.8x ", data);
packet = hpsb_make_phypacket (fi->host, data); packet = hpsb_make_phypacket(fi->host, data);
if (!packet) return -ENOMEM; if (!packet)
req->req.length=0; return -ENOMEM;
req->packet=packet; req->req.length = 0;
hpsb_set_packet_complete_task(packet, (void(*)(void*))queue_complete_cb, req); req->packet = packet;
hpsb_set_packet_complete_task(packet,
(void (*)(void *))queue_complete_cb, req);
spin_lock_irq(&fi->reqlists_lock); spin_lock_irq(&fi->reqlists_lock);
list_add_tail(&req->list, &fi->req_pending); list_add_tail(&req->list, &fi->req_pending);
spin_unlock_irq(&fi->reqlists_lock); spin_unlock_irq(&fi->reqlists_lock);
...@@ -1883,25 +2006,26 @@ static int write_phypacket(struct file_info *fi, struct pending_request *req) ...@@ -1883,25 +2006,26 @@ static int write_phypacket(struct file_info *fi, struct pending_request *req)
static int get_config_rom(struct file_info *fi, struct pending_request *req) static int get_config_rom(struct file_info *fi, struct pending_request *req)
{ {
int ret=sizeof(struct raw1394_request); int ret = sizeof(struct raw1394_request);
quadlet_t *data = kmalloc(req->req.length, SLAB_KERNEL); quadlet_t *data = kmalloc(req->req.length, SLAB_KERNEL);
int status; int status;
if (!data) return -ENOMEM; if (!data)
return -ENOMEM;
status = csr1212_read(fi->host->csr.rom, CSR1212_CONFIG_ROM_SPACE_OFFSET, status =
csr1212_read(fi->host->csr.rom, CSR1212_CONFIG_ROM_SPACE_OFFSET,
data, req->req.length); data, req->req.length);
if (copy_to_user(int2ptr(req->req.recvb), data, if (copy_to_user(int2ptr(req->req.recvb), data, req->req.length))
req->req.length))
ret = -EFAULT; ret = -EFAULT;
if (copy_to_user(int2ptr(req->req.tag), &fi->host->csr.rom->cache_head->len, if (copy_to_user
(int2ptr(req->req.tag), &fi->host->csr.rom->cache_head->len,
sizeof(fi->host->csr.rom->cache_head->len))) sizeof(fi->host->csr.rom->cache_head->len)))
ret = -EFAULT; ret = -EFAULT;
if (copy_to_user(int2ptr(req->req.address), &fi->host->csr.generation, if (copy_to_user(int2ptr(req->req.address), &fi->host->csr.generation,
sizeof(fi->host->csr.generation))) sizeof(fi->host->csr.generation)))
ret = -EFAULT; ret = -EFAULT;
if (copy_to_user(int2ptr(req->req.sendb), &status, if (copy_to_user(int2ptr(req->req.sendb), &status, sizeof(status)))
sizeof(status)))
ret = -EFAULT; ret = -EFAULT;
kfree(data); kfree(data);
if (ret >= 0) { if (ret >= 0) {
...@@ -1912,18 +2036,19 @@ static int get_config_rom(struct file_info *fi, struct pending_request *req) ...@@ -1912,18 +2036,19 @@ static int get_config_rom(struct file_info *fi, struct pending_request *req)
static int update_config_rom(struct file_info *fi, struct pending_request *req) static int update_config_rom(struct file_info *fi, struct pending_request *req)
{ {
int ret=sizeof(struct raw1394_request); int ret = sizeof(struct raw1394_request);
quadlet_t *data = kmalloc(req->req.length, SLAB_KERNEL); quadlet_t *data = kmalloc(req->req.length, SLAB_KERNEL);
if (!data) return -ENOMEM; if (!data)
if (copy_from_user(data,int2ptr(req->req.sendb), return -ENOMEM;
req->req.length)) { if (copy_from_user(data, int2ptr(req->req.sendb), req->req.length)) {
ret= -EFAULT; ret = -EFAULT;
} else { } else {
int status = hpsb_update_config_rom(fi->host, int status = hpsb_update_config_rom(fi->host,
data, req->req.length, data, req->req.length,
(unsigned char) req->req.misc); (unsigned char)req->req.
if (copy_to_user(int2ptr(req->req.recvb), misc);
&status, sizeof(status))) if (copy_to_user
(int2ptr(req->req.recvb), &status, sizeof(status)))
ret = -ENOMEM; ret = -ENOMEM;
} }
kfree(data); kfree(data);
...@@ -1943,23 +2068,32 @@ static int modify_config_rom(struct file_info *fi, struct pending_request *req) ...@@ -1943,23 +2068,32 @@ static int modify_config_rom(struct file_info *fi, struct pending_request *req)
int ret = 0; int ret = 0;
if (req->req.misc == ~0) { if (req->req.misc == ~0) {
if (req->req.length == 0) return -EINVAL; if (req->req.length == 0)
return -EINVAL;
/* Find an unused slot */ /* Find an unused slot */
for (dr = 0; dr < RAW1394_MAX_USER_CSR_DIRS && fi->csr1212_dirs[dr]; dr++); for (dr = 0;
dr < RAW1394_MAX_USER_CSR_DIRS && fi->csr1212_dirs[dr];
dr++) ;
if (dr == RAW1394_MAX_USER_CSR_DIRS) return -ENOMEM; if (dr == RAW1394_MAX_USER_CSR_DIRS)
return -ENOMEM;
fi->csr1212_dirs[dr] = csr1212_new_directory(CSR1212_KV_ID_VENDOR); fi->csr1212_dirs[dr] =
if (!fi->csr1212_dirs[dr]) return -ENOMEM; csr1212_new_directory(CSR1212_KV_ID_VENDOR);
if (!fi->csr1212_dirs[dr])
return -ENOMEM;
} else { } else {
dr = req->req.misc; dr = req->req.misc;
if (!fi->csr1212_dirs[dr]) return -EINVAL; if (!fi->csr1212_dirs[dr])
return -EINVAL;
/* Delete old stuff */ /* Delete old stuff */
for (dentry = fi->csr1212_dirs[dr]->value.directory.dentries_head; for (dentry =
fi->csr1212_dirs[dr]->value.directory.dentries_head;
dentry; dentry = dentry->next) { dentry; dentry = dentry->next) {
csr1212_detach_keyval_from_directory(fi->host->csr.rom->root_kv, csr1212_detach_keyval_from_directory(fi->host->csr.rom->
root_kv,
dentry->kv); dentry->kv);
} }
...@@ -1980,7 +2114,8 @@ static int modify_config_rom(struct file_info *fi, struct pending_request *req) ...@@ -1980,7 +2114,8 @@ static int modify_config_rom(struct file_info *fi, struct pending_request *req)
return -ENOMEM; return -ENOMEM;
} }
cache->filled_head = kmalloc(sizeof(struct csr1212_cache_region), GFP_KERNEL); cache->filled_head =
kmalloc(sizeof(struct csr1212_cache_region), GFP_KERNEL);
if (!cache->filled_head) { if (!cache->filled_head) {
csr1212_release_keyval(fi->csr1212_dirs[dr]); csr1212_release_keyval(fi->csr1212_dirs[dr]);
fi->csr1212_dirs[dr] = NULL; fi->csr1212_dirs[dr] = NULL;
...@@ -1994,11 +2129,11 @@ static int modify_config_rom(struct file_info *fi, struct pending_request *req) ...@@ -1994,11 +2129,11 @@ static int modify_config_rom(struct file_info *fi, struct pending_request *req)
csr1212_release_keyval(fi->csr1212_dirs[dr]); csr1212_release_keyval(fi->csr1212_dirs[dr]);
fi->csr1212_dirs[dr] = NULL; fi->csr1212_dirs[dr] = NULL;
CSR1212_FREE(cache); CSR1212_FREE(cache);
ret= -EFAULT; ret = -EFAULT;
} else { } else {
cache->len = req->req.length; cache->len = req->req.length;
cache->filled_head->offset_start = 0; cache->filled_head->offset_start = 0;
cache->filled_head->offset_end = cache->size -1; cache->filled_head->offset_end = cache->size - 1;
cache->layout_head = cache->layout_tail = fi->csr1212_dirs[dr]; cache->layout_head = cache->layout_tail = fi->csr1212_dirs[dr];
...@@ -2010,9 +2145,12 @@ static int modify_config_rom(struct file_info *fi, struct pending_request *req) ...@@ -2010,9 +2145,12 @@ static int modify_config_rom(struct file_info *fi, struct pending_request *req)
} }
/* attach top level items to the root directory */ /* attach top level items to the root directory */
for (dentry = fi->csr1212_dirs[dr]->value.directory.dentries_head; for (dentry =
fi->csr1212_dirs[dr]->value.directory.dentries_head;
ret == CSR1212_SUCCESS && dentry; dentry = dentry->next) { ret == CSR1212_SUCCESS && dentry; dentry = dentry->next) {
ret = csr1212_attach_keyval_to_directory(fi->host->csr.rom->root_kv, ret =
csr1212_attach_keyval_to_directory(fi->host->csr.
rom->root_kv,
dentry->kv); dentry->kv);
} }
...@@ -2034,9 +2172,11 @@ static int modify_config_rom(struct file_info *fi, struct pending_request *req) ...@@ -2034,9 +2172,11 @@ static int modify_config_rom(struct file_info *fi, struct pending_request *req)
free_pending_request(req); free_pending_request(req);
return sizeof(struct raw1394_request); return sizeof(struct raw1394_request);
} else { } else {
for (dentry = fi->csr1212_dirs[dr]->value.directory.dentries_head; for (dentry =
fi->csr1212_dirs[dr]->value.directory.dentries_head;
dentry; dentry = dentry->next) { dentry; dentry = dentry->next) {
csr1212_detach_keyval_from_directory(fi->host->csr.rom->root_kv, csr1212_detach_keyval_from_directory(fi->host->csr.rom->
root_kv,
dentry->kv); dentry->kv);
} }
csr1212_release_keyval(fi->csr1212_dirs[dr]); csr1212_release_keyval(fi->csr1212_dirs[dr]);
...@@ -2132,9 +2272,8 @@ static int state_connected(struct file_info *fi, struct pending_request *req) ...@@ -2132,9 +2272,8 @@ static int state_connected(struct file_info *fi, struct pending_request *req)
return handle_async_request(fi, req, node); return handle_async_request(fi, req, node);
} }
static ssize_t raw1394_write(struct file *file, const char __user * buffer,
static ssize_t raw1394_write(struct file *file, const char __user *buffer, size_t count, size_t count, loff_t * offset_is_ignored)
loff_t *offset_is_ignored)
{ {
struct file_info *fi = (struct file_info *)file->private_data; struct file_info *fi = (struct file_info *)file->private_data;
struct pending_request *req; struct pending_request *req;
...@@ -2200,7 +2339,8 @@ static void queue_rawiso_event(struct file_info *fi) ...@@ -2200,7 +2339,8 @@ static void queue_rawiso_event(struct file_info *fi)
/* only one ISO activity event may be in the queue */ /* only one ISO activity event may be in the queue */
if (!__rawiso_event_in_queue(fi)) { if (!__rawiso_event_in_queue(fi)) {
struct pending_request *req = __alloc_pending_request(SLAB_ATOMIC); struct pending_request *req =
__alloc_pending_request(SLAB_ATOMIC);
if (req) { if (req) {
req->file_info = fi; req->file_info = fi;
...@@ -2237,7 +2377,8 @@ static void rawiso_activity_cb(struct hpsb_iso *iso) ...@@ -2237,7 +2377,8 @@ static void rawiso_activity_cb(struct hpsb_iso *iso)
} }
/* helper function - gather all the kernel iso status bits for returning to user-space */ /* helper function - gather all the kernel iso status bits for returning to user-space */
static void raw1394_iso_fill_status(struct hpsb_iso *iso, struct raw1394_iso_status *stat) static void raw1394_iso_fill_status(struct hpsb_iso *iso,
struct raw1394_iso_status *stat)
{ {
stat->config.data_buf_size = iso->buf_size; stat->config.data_buf_size = iso->buf_size;
stat->config.buf_packets = iso->buf_packets; stat->config.buf_packets = iso->buf_packets;
...@@ -2249,7 +2390,7 @@ static void raw1394_iso_fill_status(struct hpsb_iso *iso, struct raw1394_iso_sta ...@@ -2249,7 +2390,7 @@ static void raw1394_iso_fill_status(struct hpsb_iso *iso, struct raw1394_iso_sta
stat->xmit_cycle = iso->xmit_cycle; stat->xmit_cycle = iso->xmit_cycle;
} }
static int raw1394_iso_xmit_init(struct file_info *fi, void __user *uaddr) static int raw1394_iso_xmit_init(struct file_info *fi, void __user * uaddr)
{ {
struct raw1394_iso_status stat; struct raw1394_iso_status stat;
...@@ -2281,7 +2422,7 @@ static int raw1394_iso_xmit_init(struct file_info *fi, void __user *uaddr) ...@@ -2281,7 +2422,7 @@ static int raw1394_iso_xmit_init(struct file_info *fi, void __user *uaddr)
return 0; return 0;
} }
static int raw1394_iso_recv_init(struct file_info *fi, void __user *uaddr) static int raw1394_iso_recv_init(struct file_info *fi, void __user * uaddr)
{ {
struct raw1394_iso_status stat; struct raw1394_iso_status stat;
...@@ -2309,7 +2450,7 @@ static int raw1394_iso_recv_init(struct file_info *fi, void __user *uaddr) ...@@ -2309,7 +2450,7 @@ static int raw1394_iso_recv_init(struct file_info *fi, void __user *uaddr)
return 0; return 0;
} }
static int raw1394_iso_get_status(struct file_info *fi, void __user *uaddr) static int raw1394_iso_get_status(struct file_info *fi, void __user * uaddr)
{ {
struct raw1394_iso_status stat; struct raw1394_iso_status stat;
struct hpsb_iso *iso = fi->iso_handle; struct hpsb_iso *iso = fi->iso_handle;
...@@ -2325,7 +2466,7 @@ static int raw1394_iso_get_status(struct file_info *fi, void __user *uaddr) ...@@ -2325,7 +2466,7 @@ static int raw1394_iso_get_status(struct file_info *fi, void __user *uaddr)
} }
/* copy N packet_infos out of the ringbuffer into user-supplied array */ /* copy N packet_infos out of the ringbuffer into user-supplied array */
static int raw1394_iso_recv_packets(struct file_info *fi, void __user *uaddr) static int raw1394_iso_recv_packets(struct file_info *fi, void __user * uaddr)
{ {
struct raw1394_iso_packets upackets; struct raw1394_iso_packets upackets;
unsigned int packet = fi->iso_handle->first_packet; unsigned int packet = fi->iso_handle->first_packet;
...@@ -2339,7 +2480,8 @@ static int raw1394_iso_recv_packets(struct file_info *fi, void __user *uaddr) ...@@ -2339,7 +2480,8 @@ static int raw1394_iso_recv_packets(struct file_info *fi, void __user *uaddr)
/* ensure user-supplied buffer is accessible and big enough */ /* ensure user-supplied buffer is accessible and big enough */
if (verify_area(VERIFY_WRITE, upackets.infos, if (verify_area(VERIFY_WRITE, upackets.infos,
upackets.n_packets * sizeof(struct raw1394_iso_packet_info))) upackets.n_packets *
sizeof(struct raw1394_iso_packet_info)))
return -EFAULT; return -EFAULT;
/* copy the packet_infos out */ /* copy the packet_infos out */
...@@ -2356,7 +2498,7 @@ static int raw1394_iso_recv_packets(struct file_info *fi, void __user *uaddr) ...@@ -2356,7 +2498,7 @@ static int raw1394_iso_recv_packets(struct file_info *fi, void __user *uaddr)
} }
/* copy N packet_infos from user to ringbuffer, and queue them for transmission */ /* copy N packet_infos from user to ringbuffer, and queue them for transmission */
static int raw1394_iso_send_packets(struct file_info *fi, void __user *uaddr) static int raw1394_iso_send_packets(struct file_info *fi, void __user * uaddr)
{ {
struct raw1394_iso_packets upackets; struct raw1394_iso_packets upackets;
int i, rv; int i, rv;
...@@ -2369,7 +2511,8 @@ static int raw1394_iso_send_packets(struct file_info *fi, void __user *uaddr) ...@@ -2369,7 +2511,8 @@ static int raw1394_iso_send_packets(struct file_info *fi, void __user *uaddr)
/* ensure user-supplied buffer is accessible and big enough */ /* ensure user-supplied buffer is accessible and big enough */
if (verify_area(VERIFY_READ, upackets.infos, if (verify_area(VERIFY_READ, upackets.infos,
upackets.n_packets * sizeof(struct raw1394_iso_packet_info))) upackets.n_packets *
sizeof(struct raw1394_iso_packet_info)))
return -EFAULT; return -EFAULT;
/* copy the infos structs in and queue the packets */ /* copy the infos structs in and queue the packets */
...@@ -2410,14 +2553,15 @@ static int raw1394_mmap(struct file *file, struct vm_area_struct *vma) ...@@ -2410,14 +2553,15 @@ static int raw1394_mmap(struct file *file, struct vm_area_struct *vma)
} }
/* ioctl is only used for rawiso operations */ /* ioctl is only used for rawiso operations */
static int raw1394_ioctl(struct inode *inode, struct file *file, unsigned int cmd, unsigned long arg) static int raw1394_ioctl(struct inode *inode, struct file *file,
unsigned int cmd, unsigned long arg)
{ {
struct file_info *fi = file->private_data; struct file_info *fi = file->private_data;
void __user *argp = (void __user *)arg; void __user *argp = (void __user *)arg;
switch(fi->iso_state) { switch (fi->iso_state) {
case RAW1394_ISO_INACTIVE: case RAW1394_ISO_INACTIVE:
switch(cmd) { switch (cmd) {
case RAW1394_IOC_ISO_XMIT_INIT: case RAW1394_IOC_ISO_XMIT_INIT:
return raw1394_iso_xmit_init(fi, argp); return raw1394_iso_xmit_init(fi, argp);
case RAW1394_IOC_ISO_RECV_INIT: case RAW1394_IOC_ISO_RECV_INIT:
...@@ -2427,34 +2571,42 @@ static int raw1394_ioctl(struct inode *inode, struct file *file, unsigned int cm ...@@ -2427,34 +2571,42 @@ static int raw1394_ioctl(struct inode *inode, struct file *file, unsigned int cm
} }
break; break;
case RAW1394_ISO_RECV: case RAW1394_ISO_RECV:
switch(cmd) { switch (cmd) {
case RAW1394_IOC_ISO_RECV_START: { case RAW1394_IOC_ISO_RECV_START:{
/* copy args from user-space */ /* copy args from user-space */
int args[3]; int args[3];
if (copy_from_user(&args[0], argp, sizeof(args))) if (copy_from_user
(&args[0], argp, sizeof(args)))
return -EFAULT; return -EFAULT;
return hpsb_iso_recv_start(fi->iso_handle, args[0], args[1], args[2]); return hpsb_iso_recv_start(fi->iso_handle,
args[0], args[1],
args[2]);
} }
case RAW1394_IOC_ISO_XMIT_RECV_STOP: case RAW1394_IOC_ISO_XMIT_RECV_STOP:
hpsb_iso_stop(fi->iso_handle); hpsb_iso_stop(fi->iso_handle);
return 0; return 0;
case RAW1394_IOC_ISO_RECV_LISTEN_CHANNEL: case RAW1394_IOC_ISO_RECV_LISTEN_CHANNEL:
return hpsb_iso_recv_listen_channel(fi->iso_handle, arg); return hpsb_iso_recv_listen_channel(fi->iso_handle,
arg);
case RAW1394_IOC_ISO_RECV_UNLISTEN_CHANNEL: case RAW1394_IOC_ISO_RECV_UNLISTEN_CHANNEL:
return hpsb_iso_recv_unlisten_channel(fi->iso_handle, arg); return hpsb_iso_recv_unlisten_channel(fi->iso_handle,
case RAW1394_IOC_ISO_RECV_SET_CHANNEL_MASK: { arg);
case RAW1394_IOC_ISO_RECV_SET_CHANNEL_MASK:{
/* copy the u64 from user-space */ /* copy the u64 from user-space */
u64 mask; u64 mask;
if (copy_from_user(&mask, argp, sizeof(mask))) if (copy_from_user(&mask, argp, sizeof(mask)))
return -EFAULT; return -EFAULT;
return hpsb_iso_recv_set_channel_mask(fi->iso_handle, mask); return hpsb_iso_recv_set_channel_mask(fi->
iso_handle,
mask);
} }
case RAW1394_IOC_ISO_GET_STATUS: case RAW1394_IOC_ISO_GET_STATUS:
return raw1394_iso_get_status(fi, argp); return raw1394_iso_get_status(fi, argp);
case RAW1394_IOC_ISO_RECV_PACKETS: case RAW1394_IOC_ISO_RECV_PACKETS:
return raw1394_iso_recv_packets(fi, argp); return raw1394_iso_recv_packets(fi, argp);
case RAW1394_IOC_ISO_RECV_RELEASE_PACKETS: case RAW1394_IOC_ISO_RECV_RELEASE_PACKETS:
return hpsb_iso_recv_release_packets(fi->iso_handle, arg); return hpsb_iso_recv_release_packets(fi->iso_handle,
arg);
case RAW1394_IOC_ISO_RECV_FLUSH: case RAW1394_IOC_ISO_RECV_FLUSH:
return hpsb_iso_recv_flush(fi->iso_handle); return hpsb_iso_recv_flush(fi->iso_handle);
case RAW1394_IOC_ISO_SHUTDOWN: case RAW1394_IOC_ISO_SHUTDOWN:
...@@ -2466,13 +2618,15 @@ static int raw1394_ioctl(struct inode *inode, struct file *file, unsigned int cm ...@@ -2466,13 +2618,15 @@ static int raw1394_ioctl(struct inode *inode, struct file *file, unsigned int cm
} }
break; break;
case RAW1394_ISO_XMIT: case RAW1394_ISO_XMIT:
switch(cmd) { switch (cmd) {
case RAW1394_IOC_ISO_XMIT_START: { case RAW1394_IOC_ISO_XMIT_START:{
/* copy two ints from user-space */ /* copy two ints from user-space */
int args[2]; int args[2];
if (copy_from_user(&args[0], argp, sizeof(args))) if (copy_from_user
(&args[0], argp, sizeof(args)))
return -EFAULT; return -EFAULT;
return hpsb_iso_xmit_start(fi->iso_handle, args[0], args[1]); return hpsb_iso_xmit_start(fi->iso_handle,
args[0], args[1]);
} }
case RAW1394_IOC_ISO_XMIT_SYNC: case RAW1394_IOC_ISO_XMIT_SYNC:
return hpsb_iso_xmit_sync(fi->iso_handle); return hpsb_iso_xmit_sync(fi->iso_handle);
...@@ -2498,7 +2652,7 @@ static int raw1394_ioctl(struct inode *inode, struct file *file, unsigned int cm ...@@ -2498,7 +2652,7 @@ static int raw1394_ioctl(struct inode *inode, struct file *file, unsigned int cm
return -EINVAL; return -EINVAL;
} }
static unsigned int raw1394_poll(struct file *file, poll_table *pt) static unsigned int raw1394_poll(struct file *file, poll_table * pt)
{ {
struct file_info *fi = file->private_data; struct file_info *fi = file->private_data;
unsigned int mask = POLLOUT | POLLWRNORM; unsigned int mask = POLLOUT | POLLWRNORM;
...@@ -2579,14 +2733,17 @@ static int raw1394_release(struct inode *inode, struct file *file) ...@@ -2579,14 +2733,17 @@ static int raw1394_release(struct inode *inode, struct file *file)
same addressrange? */ same addressrange? */
list_for_each_entry(hi, &host_info_list, list) { list_for_each_entry(hi, &host_info_list, list) {
if (hi->host != fi->host) { if (hi->host != fi->host) {
list_for_each_entry(fi_hlp, &hi->file_info_list, list) { list_for_each_entry(fi_hlp, &hi->file_info_list,
list) {
entry = fi_hlp->addr_list.next; entry = fi_hlp->addr_list.next;
while (entry != &(fi_hlp->addr_list)) { while (entry != &(fi_hlp->addr_list)) {
arm_addr = list_entry(entry, arm_addr = list_entry(entry, struct
struct arm_addr, addr_list); arm_addr,
addr_list);
if (arm_addr->start == if (arm_addr->start ==
addr->start) { addr->start) {
DBGMSG("raw1394_release: " DBGMSG
("raw1394_release: "
"another host ownes " "another host ownes "
"same addressrange"); "same addressrange");
another_host = 1; another_host = 1;
...@@ -2602,10 +2759,13 @@ static int raw1394_release(struct inode *inode, struct file *file) ...@@ -2602,10 +2759,13 @@ static int raw1394_release(struct inode *inode, struct file *file)
} }
if (!another_host) { if (!another_host) {
DBGMSG("raw1394_release: call hpsb_arm_unregister"); DBGMSG("raw1394_release: call hpsb_arm_unregister");
retval = hpsb_unregister_addrspace(&raw1394_highlevel, fi->host, addr->start); retval =
hpsb_unregister_addrspace(&raw1394_highlevel,
fi->host, addr->start);
if (!retval) { if (!retval) {
++fail; ++fail;
printk(KERN_ERR "raw1394_release arm_Unregister failed\n"); printk(KERN_ERR
"raw1394_release arm_Unregister failed\n");
} }
} }
DBGMSG("raw1394_release: delete addr_entry from list"); DBGMSG("raw1394_release: delete addr_entry from list");
...@@ -2631,28 +2791,37 @@ static int raw1394_release(struct inode *inode, struct file *file) ...@@ -2631,28 +2791,37 @@ static int raw1394_release(struct inode *inode, struct file *file)
free_pending_request(req); free_pending_request(req);
} }
if (list_empty(&fi->req_pending)) done = 1; if (list_empty(&fi->req_pending))
done = 1;
spin_unlock_irq(&fi->reqlists_lock); spin_unlock_irq(&fi->reqlists_lock);
if (!done) down_interruptible(&fi->complete_sem); if (!done)
down_interruptible(&fi->complete_sem);
} }
/* Remove any sub-trees left by user space programs */ /* Remove any sub-trees left by user space programs */
for (i = 0; i < RAW1394_MAX_USER_CSR_DIRS; i++) { for (i = 0; i < RAW1394_MAX_USER_CSR_DIRS; i++) {
struct csr1212_dentry *dentry; struct csr1212_dentry *dentry;
if (!fi->csr1212_dirs[i]) continue; if (!fi->csr1212_dirs[i])
for (dentry = fi->csr1212_dirs[i]->value.directory.dentries_head; continue;
dentry; dentry = dentry->next) { for (dentry =
csr1212_detach_keyval_from_directory(fi->host->csr.rom->root_kv, dentry->kv); fi->csr1212_dirs[i]->value.directory.dentries_head; dentry;
dentry = dentry->next) {
csr1212_detach_keyval_from_directory(fi->host->csr.rom->
root_kv,
dentry->kv);
} }
csr1212_release_keyval(fi->csr1212_dirs[i]); csr1212_release_keyval(fi->csr1212_dirs[i]);
fi->csr1212_dirs[i] = NULL; fi->csr1212_dirs[i] = NULL;
csr_mod = 1; csr_mod = 1;
} }
if ((csr_mod || fi->cfgrom_upd) && hpsb_update_config_rom_image(fi->host) < 0) if ((csr_mod || fi->cfgrom_upd)
HPSB_ERR("Failed to generate Configuration ROM image for host %d", fi->host->id); && hpsb_update_config_rom_image(fi->host) < 0)
HPSB_ERR
("Failed to generate Configuration ROM image for host %d",
fi->host->id);
if (fi->state == connected) { if (fi->state == connected) {
spin_lock_irq(&host_info_lock); spin_lock_irq(&host_info_lock);
...@@ -2667,7 +2836,6 @@ static int raw1394_release(struct inode *inode, struct file *file) ...@@ -2667,7 +2836,6 @@ static int raw1394_release(struct inode *inode, struct file *file)
return 0; return 0;
} }
/*** HOTPLUG STUFF **********************************************************/ /*** HOTPLUG STUFF **********************************************************/
/* /*
* Export information about protocols/devices supported by this driver. * Export information about protocols/devices supported by this driver.
...@@ -2676,14 +2844,20 @@ static struct ieee1394_device_id raw1394_id_table[] = { ...@@ -2676,14 +2844,20 @@ static struct ieee1394_device_id raw1394_id_table[] = {
{ {
.match_flags = IEEE1394_MATCH_SPECIFIER_ID | IEEE1394_MATCH_VERSION, .match_flags = IEEE1394_MATCH_SPECIFIER_ID | IEEE1394_MATCH_VERSION,
.specifier_id = AVC_UNIT_SPEC_ID_ENTRY & 0xffffff, .specifier_id = AVC_UNIT_SPEC_ID_ENTRY & 0xffffff,
.version = AVC_SW_VERSION_ENTRY & 0xffffff .version = AVC_SW_VERSION_ENTRY & 0xffffff},
},
{ {
.match_flags = IEEE1394_MATCH_SPECIFIER_ID | IEEE1394_MATCH_VERSION, .match_flags = IEEE1394_MATCH_SPECIFIER_ID | IEEE1394_MATCH_VERSION,
.specifier_id = CAMERA_UNIT_SPEC_ID_ENTRY & 0xffffff, .specifier_id = CAMERA_UNIT_SPEC_ID_ENTRY & 0xffffff,
.version = CAMERA_SW_VERSION_ENTRY & 0xffffff .version = CAMERA_SW_VERSION_ENTRY & 0xffffff},
}, {
{ } .match_flags = IEEE1394_MATCH_SPECIFIER_ID | IEEE1394_MATCH_VERSION,
.specifier_id = CAMERA_UNIT_SPEC_ID_ENTRY & 0xffffff,
.version = (CAMERA_SW_VERSION_ENTRY + 1) & 0xffffff},
{
.match_flags = IEEE1394_MATCH_SPECIFIER_ID | IEEE1394_MATCH_VERSION,
.specifier_id = CAMERA_UNIT_SPEC_ID_ENTRY & 0xffffff,
.version = (CAMERA_SW_VERSION_ENTRY + 2) & 0xffffff},
{}
}; };
MODULE_DEVICE_TABLE(ieee1394, raw1394_id_table); MODULE_DEVICE_TABLE(ieee1394, raw1394_id_table);
...@@ -2697,10 +2871,8 @@ static struct hpsb_protocol_driver raw1394_driver = { ...@@ -2697,10 +2871,8 @@ static struct hpsb_protocol_driver raw1394_driver = {
}, },
}; };
/******************************************************************************/ /******************************************************************************/
static struct hpsb_highlevel raw1394_highlevel = { static struct hpsb_highlevel raw1394_highlevel = {
.name = RAW1394_DEVICE_NAME, .name = RAW1394_DEVICE_NAME,
.add_host = add_host, .add_host = add_host,
...@@ -2724,11 +2896,19 @@ static struct file_operations raw1394_fops = { ...@@ -2724,11 +2896,19 @@ static struct file_operations raw1394_fops = {
static int __init init_raw1394(void) static int __init init_raw1394(void)
{ {
int ret; int ret = 0;
hpsb_register_highlevel(&raw1394_highlevel); hpsb_register_highlevel(&raw1394_highlevel);
devfs_mk_cdev(MKDEV(IEEE1394_MAJOR, IEEE1394_MINOR_BLOCK_RAW1394 * 16), if (IS_ERR(class_simple_device_add(hpsb_protocol_class, MKDEV(
IEEE1394_MAJOR, IEEE1394_MINOR_BLOCK_RAW1394 * 16),
NULL, RAW1394_DEVICE_NAME))) {
ret = -EFAULT;
goto out_unreg;
}
devfs_mk_cdev(MKDEV(
IEEE1394_MAJOR, IEEE1394_MINOR_BLOCK_RAW1394 * 16),
S_IFCHR | S_IRUSR | S_IWUSR, RAW1394_DEVICE_NAME); S_IFCHR | S_IRUSR | S_IWUSR, RAW1394_DEVICE_NAME);
cdev_init(&raw1394_cdev, &raw1394_fops); cdev_init(&raw1394_cdev, &raw1394_fops);
...@@ -2737,9 +2917,7 @@ static int __init init_raw1394(void) ...@@ -2737,9 +2917,7 @@ static int __init init_raw1394(void)
ret = cdev_add(&raw1394_cdev, IEEE1394_RAW1394_DEV, 1); ret = cdev_add(&raw1394_cdev, IEEE1394_RAW1394_DEV, 1);
if (ret) { if (ret) {
HPSB_ERR("raw1394 failed to register minor device block"); HPSB_ERR("raw1394 failed to register minor device block");
devfs_remove(RAW1394_DEVICE_NAME); goto out_dev;
hpsb_unregister_highlevel(&raw1394_highlevel);
return ret;
} }
HPSB_INFO("raw1394: /dev/%s device initialized", RAW1394_DEVICE_NAME); HPSB_INFO("raw1394: /dev/%s device initialized", RAW1394_DEVICE_NAME);
...@@ -2748,16 +2926,25 @@ static int __init init_raw1394(void) ...@@ -2748,16 +2926,25 @@ static int __init init_raw1394(void)
if (ret) { if (ret) {
HPSB_ERR("raw1394: failed to register protocol"); HPSB_ERR("raw1394: failed to register protocol");
cdev_del(&raw1394_cdev); cdev_del(&raw1394_cdev);
goto out_dev;
}
goto out;
out_dev:
devfs_remove(RAW1394_DEVICE_NAME); devfs_remove(RAW1394_DEVICE_NAME);
class_simple_device_remove(MKDEV(
IEEE1394_MAJOR, IEEE1394_MINOR_BLOCK_RAW1394 * 16));
out_unreg:
hpsb_unregister_highlevel(&raw1394_highlevel); hpsb_unregister_highlevel(&raw1394_highlevel);
out:
return ret; return ret;
}
return 0;
} }
static void __exit cleanup_raw1394(void) static void __exit cleanup_raw1394(void)
{ {
class_simple_device_remove(MKDEV(
IEEE1394_MAJOR, IEEE1394_MINOR_BLOCK_RAW1394 * 16));
hpsb_unregister_protocol(&raw1394_driver); hpsb_unregister_protocol(&raw1394_driver);
cdev_del(&raw1394_cdev); cdev_del(&raw1394_cdev);
devfs_remove(RAW1394_DEVICE_NAME); devfs_remove(RAW1394_DEVICE_NAME);
......
...@@ -64,7 +64,10 @@ ...@@ -64,7 +64,10 @@
#include <asm/system.h> #include <asm/system.h>
#include <asm/scatterlist.h> #include <asm/scatterlist.h>
#include "../scsi/scsi.h" #include <scsi/scsi.h>
#include <scsi/scsi_cmnd.h>
#include <scsi/scsi_dbg.h>
#include <scsi/scsi_device.h>
#include <scsi/scsi_host.h> #include <scsi/scsi_host.h>
#include "csr1212.h" #include "csr1212.h"
...@@ -224,12 +227,12 @@ static void sbp2scsi_complete_all_commands(struct scsi_id_instance_data *scsi_id ...@@ -224,12 +227,12 @@ static void sbp2scsi_complete_all_commands(struct scsi_id_instance_data *scsi_id
u32 status); u32 status);
static void sbp2scsi_complete_command(struct scsi_id_instance_data *scsi_id, static void sbp2scsi_complete_command(struct scsi_id_instance_data *scsi_id,
u32 scsi_status, Scsi_Cmnd *SCpnt, u32 scsi_status, struct scsi_cmnd *SCpnt,
void (*done)(Scsi_Cmnd *)); void (*done)(struct scsi_cmnd *));
static Scsi_Host_Template scsi_driver_template; static struct scsi_host_template scsi_driver_template;
const u8 sbp2_speedto_max_payload[] = { 0x7, 0x8, 0x9, 0xA, 0xB, 0xC }; static const u8 sbp2_speedto_max_payload[] = { 0x7, 0x8, 0x9, 0xA, 0xB, 0xC };
static void sbp2_host_reset(struct hpsb_host *host); static void sbp2_host_reset(struct hpsb_host *host);
...@@ -373,7 +376,7 @@ static void sbp2_free_packet(struct hpsb_packet *packet) ...@@ -373,7 +376,7 @@ static void sbp2_free_packet(struct hpsb_packet *packet)
/* This is much like hpsb_node_write(), except it ignores the response /* This is much like hpsb_node_write(), except it ignores the response
* subaction and returns immediately. Can be used from interrupts. * subaction and returns immediately. Can be used from interrupts.
*/ */
int sbp2util_node_write_no_wait(struct node_entry *ne, u64 addr, static int sbp2util_node_write_no_wait(struct node_entry *ne, u64 addr,
quadlet_t *buffer, size_t length) quadlet_t *buffer, size_t length)
{ {
struct hpsb_packet *packet; struct hpsb_packet *packet;
...@@ -520,8 +523,8 @@ static struct sbp2_command_info *sbp2util_find_command_for_SCpnt(struct scsi_id_ ...@@ -520,8 +523,8 @@ static struct sbp2_command_info *sbp2util_find_command_for_SCpnt(struct scsi_id_
*/ */
static struct sbp2_command_info *sbp2util_allocate_command_orb( static struct sbp2_command_info *sbp2util_allocate_command_orb(
struct scsi_id_instance_data *scsi_id, struct scsi_id_instance_data *scsi_id,
Scsi_Cmnd *Current_SCpnt, struct scsi_cmnd *Current_SCpnt,
void (*Current_done)(Scsi_Cmnd *)) void (*Current_done)(struct scsi_cmnd *))
{ {
struct list_head *lh; struct list_head *lh;
struct sbp2_command_info *command = NULL; struct sbp2_command_info *command = NULL;
...@@ -1521,8 +1524,9 @@ static void sbp2_parse_unit_directory(struct scsi_id_instance_data *scsi_id, ...@@ -1521,8 +1524,9 @@ static void sbp2_parse_unit_directory(struct scsi_id_instance_data *scsi_id,
SBP2_DEBUG("sbp2_management_agent_addr = %x", SBP2_DEBUG("sbp2_management_agent_addr = %x",
(unsigned int) management_agent_addr); (unsigned int) management_agent_addr);
} else } else if (kv->key.type == CSR1212_KV_TYPE_IMMEDIATE) {
scsi_id->sbp2_device_type_and_lun = kv->value.immediate; scsi_id->sbp2_device_type_and_lun = kv->value.immediate;
}
break; break;
case SBP2_COMMAND_SET_SPEC_ID_KEY: case SBP2_COMMAND_SET_SPEC_ID_KEY:
...@@ -1613,6 +1617,8 @@ static void sbp2_parse_unit_directory(struct scsi_id_instance_data *scsi_id, ...@@ -1613,6 +1617,8 @@ static void sbp2_parse_unit_directory(struct scsi_id_instance_data *scsi_id,
scsi_id->sbp2_unit_characteristics = unit_characteristics; scsi_id->sbp2_unit_characteristics = unit_characteristics;
scsi_id->sbp2_firmware_revision = firmware_revision; scsi_id->sbp2_firmware_revision = firmware_revision;
scsi_id->workarounds = workarounds; scsi_id->workarounds = workarounds;
if (ud->flags & UNIT_DIRECTORY_HAS_LUN)
scsi_id->sbp2_device_type_and_lun = ud->lun;
} }
} }
...@@ -1700,14 +1706,14 @@ static int sbp2_create_command_orb(struct scsi_id_instance_data *scsi_id, ...@@ -1700,14 +1706,14 @@ static int sbp2_create_command_orb(struct scsi_id_instance_data *scsi_id,
unsigned int scsi_use_sg, unsigned int scsi_use_sg,
unsigned int scsi_request_bufflen, unsigned int scsi_request_bufflen,
void *scsi_request_buffer, void *scsi_request_buffer,
unsigned char scsi_dir) enum dma_data_direction dma_dir)
{ {
struct sbp2scsi_host_info *hi = scsi_id->hi; struct sbp2scsi_host_info *hi = scsi_id->hi;
struct scatterlist *sgpnt = (struct scatterlist *) scsi_request_buffer; struct scatterlist *sgpnt = (struct scatterlist *) scsi_request_buffer;
struct sbp2_command_orb *command_orb = &command->command_orb; struct sbp2_command_orb *command_orb = &command->command_orb;
struct sbp2_unrestricted_page_table *scatter_gather_element = struct sbp2_unrestricted_page_table *scatter_gather_element =
&command->scatter_gather_element[0]; &command->scatter_gather_element[0];
int dma_dir = scsi_to_pci_dma_dir (scsi_dir);
u32 sg_count, sg_len, orb_direction; u32 sg_count, sg_len, orb_direction;
dma_addr_t sg_addr; dma_addr_t sg_addr;
int i; int i;
...@@ -1730,22 +1736,22 @@ static int sbp2_create_command_orb(struct scsi_id_instance_data *scsi_id, ...@@ -1730,22 +1736,22 @@ static int sbp2_create_command_orb(struct scsi_id_instance_data *scsi_id,
* Get the direction of the transfer. If the direction is unknown, then use our * Get the direction of the transfer. If the direction is unknown, then use our
* goofy table as a back-up. * goofy table as a back-up.
*/ */
switch (scsi_dir) { switch (dma_dir) {
case SCSI_DATA_NONE: case DMA_NONE:
orb_direction = ORB_DIRECTION_NO_DATA_TRANSFER; orb_direction = ORB_DIRECTION_NO_DATA_TRANSFER;
break; break;
case SCSI_DATA_WRITE: case DMA_TO_DEVICE:
orb_direction = ORB_DIRECTION_WRITE_TO_MEDIA; orb_direction = ORB_DIRECTION_WRITE_TO_MEDIA;
break; break;
case SCSI_DATA_READ: case DMA_FROM_DEVICE:
orb_direction = ORB_DIRECTION_READ_FROM_MEDIA; orb_direction = ORB_DIRECTION_READ_FROM_MEDIA;
break; break;
case SCSI_DATA_UNKNOWN: case DMA_BIDIRECTIONAL:
default: default:
SBP2_ERR("SCSI data transfer direction not specified. " SBP2_ERR("SCSI data transfer direction not specified. "
"Update the SBP2 direction table in sbp2.h if " "Update the SBP2 direction table in sbp2.h if "
"necessary for your application"); "necessary for your application");
print_command (scsi_cmd); __scsi_print_command(scsi_cmd);
orb_direction = sbp2scsi_direction_table[*scsi_cmd]; orb_direction = sbp2scsi_direction_table[*scsi_cmd];
break; break;
} }
...@@ -2031,7 +2037,8 @@ static int sbp2_link_orb_command(struct scsi_id_instance_data *scsi_id, ...@@ -2031,7 +2037,8 @@ static int sbp2_link_orb_command(struct scsi_id_instance_data *scsi_id,
* This function is called in order to begin a regular SBP-2 command. * This function is called in order to begin a regular SBP-2 command.
*/ */
static int sbp2_send_command(struct scsi_id_instance_data *scsi_id, static int sbp2_send_command(struct scsi_id_instance_data *scsi_id,
Scsi_Cmnd *SCpnt, void (*done)(Scsi_Cmnd *)) struct scsi_cmnd *SCpnt,
void (*done)(struct scsi_cmnd *))
{ {
unchar *cmd = (unchar *) SCpnt->cmnd; unchar *cmd = (unchar *) SCpnt->cmnd;
unsigned int request_bufflen = SCpnt->request_bufflen; unsigned int request_bufflen = SCpnt->request_bufflen;
...@@ -2040,7 +2047,7 @@ static int sbp2_send_command(struct scsi_id_instance_data *scsi_id, ...@@ -2040,7 +2047,7 @@ static int sbp2_send_command(struct scsi_id_instance_data *scsi_id,
SBP2_DEBUG("sbp2_send_command"); SBP2_DEBUG("sbp2_send_command");
#if (CONFIG_IEEE1394_SBP2_DEBUG >= 2) || defined(CONFIG_IEEE1394_SBP2_PACKET_DUMP) #if (CONFIG_IEEE1394_SBP2_DEBUG >= 2) || defined(CONFIG_IEEE1394_SBP2_PACKET_DUMP)
printk("[scsi command]\n "); printk("[scsi command]\n ");
print_command (cmd); scsi_print_command(SCpnt);
#endif #endif
SBP2_DEBUG("SCSI transfer size = %x", request_bufflen); SBP2_DEBUG("SCSI transfer size = %x", request_bufflen);
SBP2_DEBUG("SCSI s/g elements = %x", (unsigned int)SCpnt->use_sg); SBP2_DEBUG("SCSI s/g elements = %x", (unsigned int)SCpnt->use_sg);
...@@ -2233,7 +2240,7 @@ static unsigned int sbp2_status_to_sense_data(unchar *sbp2_status, unchar *sense ...@@ -2233,7 +2240,7 @@ static unsigned int sbp2_status_to_sense_data(unchar *sbp2_status, unchar *sense
* response data translations for the SCSI stack * response data translations for the SCSI stack
*/ */
static void sbp2_check_sbp2_response(struct scsi_id_instance_data *scsi_id, static void sbp2_check_sbp2_response(struct scsi_id_instance_data *scsi_id,
Scsi_Cmnd *SCpnt) struct scsi_cmnd *SCpnt)
{ {
u8 *scsi_buf = SCpnt->request_buffer; u8 *scsi_buf = SCpnt->request_buffer;
u8 device_type = SBP2_DEVICE_TYPE (scsi_id->sbp2_device_type_and_lun); u8 device_type = SBP2_DEVICE_TYPE (scsi_id->sbp2_device_type_and_lun);
...@@ -2312,7 +2319,7 @@ static int sbp2_handle_status_write(struct hpsb_host *host, int nodeid, int dest ...@@ -2312,7 +2319,7 @@ static int sbp2_handle_status_write(struct hpsb_host *host, int nodeid, int dest
struct sbp2scsi_host_info *hi; struct sbp2scsi_host_info *hi;
struct scsi_id_instance_data *scsi_id = NULL, *scsi_id_tmp; struct scsi_id_instance_data *scsi_id = NULL, *scsi_id_tmp;
u32 id; u32 id;
Scsi_Cmnd *SCpnt = NULL; struct scsi_cmnd *SCpnt = NULL;
u32 scsi_status = SBP2_SCSI_STATUS_GOOD; u32 scsi_status = SBP2_SCSI_STATUS_GOOD;
struct sbp2_command_info *command; struct sbp2_command_info *command;
...@@ -2454,7 +2461,8 @@ static int sbp2_handle_status_write(struct hpsb_host *host, int nodeid, int dest ...@@ -2454,7 +2461,8 @@ static int sbp2_handle_status_write(struct hpsb_host *host, int nodeid, int dest
* This routine is the main request entry routine for doing I/O. It is * This routine is the main request entry routine for doing I/O. It is
* called from the scsi stack directly. * called from the scsi stack directly.
*/ */
static int sbp2scsi_queuecommand (Scsi_Cmnd *SCpnt, void (*done)(Scsi_Cmnd *)) static int sbp2scsi_queuecommand(struct scsi_cmnd *SCpnt,
void (*done)(struct scsi_cmnd *))
{ {
struct scsi_id_instance_data *scsi_id = struct scsi_id_instance_data *scsi_id =
(struct scsi_id_instance_data *)SCpnt->device->host->hostdata[0]; (struct scsi_id_instance_data *)SCpnt->device->host->hostdata[0];
...@@ -2550,9 +2558,8 @@ static void sbp2scsi_complete_all_commands(struct scsi_id_instance_data *scsi_id ...@@ -2550,9 +2558,8 @@ static void sbp2scsi_complete_all_commands(struct scsi_id_instance_data *scsi_id
PCI_DMA_BIDIRECTIONAL); PCI_DMA_BIDIRECTIONAL);
sbp2util_mark_command_completed(scsi_id, command); sbp2util_mark_command_completed(scsi_id, command);
if (command->Current_SCpnt) { if (command->Current_SCpnt) {
void (*done)(Scsi_Cmnd *) = command->Current_done;
command->Current_SCpnt->result = status << 16; command->Current_SCpnt->result = status << 16;
done (command->Current_SCpnt); command->Current_done(command->Current_SCpnt);
} }
} }
...@@ -2565,8 +2572,8 @@ static void sbp2scsi_complete_all_commands(struct scsi_id_instance_data *scsi_id ...@@ -2565,8 +2572,8 @@ static void sbp2scsi_complete_all_commands(struct scsi_id_instance_data *scsi_id
* This can be called in interrupt context. * This can be called in interrupt context.
*/ */
static void sbp2scsi_complete_command(struct scsi_id_instance_data *scsi_id, static void sbp2scsi_complete_command(struct scsi_id_instance_data *scsi_id,
u32 scsi_status, Scsi_Cmnd *SCpnt, u32 scsi_status, struct scsi_cmnd *SCpnt,
void (*done)(Scsi_Cmnd *)) void (*done)(struct scsi_cmnd *))
{ {
unsigned long flags; unsigned long flags;
...@@ -2611,8 +2618,8 @@ static void sbp2scsi_complete_command(struct scsi_id_instance_data *scsi_id, ...@@ -2611,8 +2618,8 @@ static void sbp2scsi_complete_command(struct scsi_id_instance_data *scsi_id,
* Debug stuff * Debug stuff
*/ */
#if CONFIG_IEEE1394_SBP2_DEBUG >= 1 #if CONFIG_IEEE1394_SBP2_DEBUG >= 1
print_command (SCpnt->cmnd); scsi_print_command(SCpnt);
print_sense("bh", SCpnt); scsi_print_sense("bh", SCpnt);
#endif #endif
break; break;
...@@ -2620,7 +2627,7 @@ static void sbp2scsi_complete_command(struct scsi_id_instance_data *scsi_id, ...@@ -2620,7 +2627,7 @@ static void sbp2scsi_complete_command(struct scsi_id_instance_data *scsi_id,
case SBP2_SCSI_STATUS_SELECTION_TIMEOUT: case SBP2_SCSI_STATUS_SELECTION_TIMEOUT:
SBP2_ERR("SBP2_SCSI_STATUS_SELECTION_TIMEOUT"); SBP2_ERR("SBP2_SCSI_STATUS_SELECTION_TIMEOUT");
SCpnt->result = DID_NO_CONNECT << 16; SCpnt->result = DID_NO_CONNECT << 16;
print_command (SCpnt->cmnd); scsi_print_command(SCpnt);
break; break;
case SBP2_SCSI_STATUS_CONDITION_MET: case SBP2_SCSI_STATUS_CONDITION_MET:
...@@ -2628,7 +2635,7 @@ static void sbp2scsi_complete_command(struct scsi_id_instance_data *scsi_id, ...@@ -2628,7 +2635,7 @@ static void sbp2scsi_complete_command(struct scsi_id_instance_data *scsi_id,
case SBP2_SCSI_STATUS_COMMAND_TERMINATED: case SBP2_SCSI_STATUS_COMMAND_TERMINATED:
SBP2_ERR("Bad SCSI status = %x", scsi_status); SBP2_ERR("Bad SCSI status = %x", scsi_status);
SCpnt->result = DID_ERROR << 16; SCpnt->result = DID_ERROR << 16;
print_command (SCpnt->cmnd); scsi_print_command(SCpnt);
break; break;
default: default:
...@@ -2688,7 +2695,7 @@ static int sbp2scsi_slave_configure (struct scsi_device *sdev) ...@@ -2688,7 +2695,7 @@ static int sbp2scsi_slave_configure (struct scsi_device *sdev)
* Called by scsi stack when something has really gone wrong. Usually * Called by scsi stack when something has really gone wrong. Usually
* called when a command has timed-out for some reason. * called when a command has timed-out for some reason.
*/ */
static int sbp2scsi_abort (Scsi_Cmnd *SCpnt) static int sbp2scsi_abort(struct scsi_cmnd *SCpnt)
{ {
struct scsi_id_instance_data *scsi_id = struct scsi_id_instance_data *scsi_id =
(struct scsi_id_instance_data *)SCpnt->device->host->hostdata[0]; (struct scsi_id_instance_data *)SCpnt->device->host->hostdata[0];
...@@ -2696,7 +2703,7 @@ static int sbp2scsi_abort (Scsi_Cmnd *SCpnt) ...@@ -2696,7 +2703,7 @@ static int sbp2scsi_abort (Scsi_Cmnd *SCpnt)
struct sbp2_command_info *command; struct sbp2_command_info *command;
SBP2_ERR("aborting sbp2 command"); SBP2_ERR("aborting sbp2 command");
print_command (SCpnt->cmnd); scsi_print_command(SCpnt);
if (scsi_id) { if (scsi_id) {
...@@ -2717,9 +2724,8 @@ static int sbp2scsi_abort (Scsi_Cmnd *SCpnt) ...@@ -2717,9 +2724,8 @@ static int sbp2scsi_abort (Scsi_Cmnd *SCpnt)
PCI_DMA_BIDIRECTIONAL); PCI_DMA_BIDIRECTIONAL);
sbp2util_mark_command_completed(scsi_id, command); sbp2util_mark_command_completed(scsi_id, command);
if (command->Current_SCpnt) { if (command->Current_SCpnt) {
void (*done)(Scsi_Cmnd *) = command->Current_done;
command->Current_SCpnt->result = DID_ABORT << 16; command->Current_SCpnt->result = DID_ABORT << 16;
done (command->Current_SCpnt); command->Current_done(command->Current_SCpnt);
} }
} }
...@@ -2736,7 +2742,7 @@ static int sbp2scsi_abort (Scsi_Cmnd *SCpnt) ...@@ -2736,7 +2742,7 @@ static int sbp2scsi_abort (Scsi_Cmnd *SCpnt)
/* /*
* Called by scsi stack when something has really gone wrong. * Called by scsi stack when something has really gone wrong.
*/ */
static int sbp2scsi_reset (Scsi_Cmnd *SCpnt) static int sbp2scsi_reset(struct scsi_cmnd *SCpnt)
{ {
struct scsi_id_instance_data *scsi_id = struct scsi_id_instance_data *scsi_id =
(struct scsi_id_instance_data *)SCpnt->device->host->hostdata[0]; (struct scsi_id_instance_data *)SCpnt->device->host->hostdata[0];
...@@ -2789,7 +2795,7 @@ MODULE_SUPPORTED_DEVICE(SBP2_DEVICE_NAME); ...@@ -2789,7 +2795,7 @@ MODULE_SUPPORTED_DEVICE(SBP2_DEVICE_NAME);
MODULE_LICENSE("GPL"); MODULE_LICENSE("GPL");
/* SCSI host template */ /* SCSI host template */
static Scsi_Host_Template scsi_driver_template = { static struct scsi_host_template scsi_driver_template = {
.module = THIS_MODULE, .module = THIS_MODULE,
.name = "SBP-2 IEEE-1394", .name = "SBP-2 IEEE-1394",
.proc_name = SBP2_DEVICE_NAME, .proc_name = SBP2_DEVICE_NAME,
......
...@@ -324,8 +324,8 @@ struct sbp2_command_info { ...@@ -324,8 +324,8 @@ struct sbp2_command_info {
struct list_head list; struct list_head list;
struct sbp2_command_orb command_orb ____cacheline_aligned; struct sbp2_command_orb command_orb ____cacheline_aligned;
dma_addr_t command_orb_dma ____cacheline_aligned; dma_addr_t command_orb_dma ____cacheline_aligned;
Scsi_Cmnd *Current_SCpnt; struct scsi_cmnd *Current_SCpnt;
void (*Current_done)(Scsi_Cmnd *); void (*Current_done)(struct scsi_cmnd *);
/* Also need s/g structure for each sbp2 command */ /* Also need s/g structure for each sbp2 command */
struct sbp2_unrestricted_page_table scatter_gather_element[SG_ALL] ____cacheline_aligned; struct sbp2_unrestricted_page_table scatter_gather_element[SG_ALL] ____cacheline_aligned;
...@@ -434,8 +434,8 @@ static void sbp2util_remove_command_orb_pool(struct scsi_id_instance_data *scsi_ ...@@ -434,8 +434,8 @@ static void sbp2util_remove_command_orb_pool(struct scsi_id_instance_data *scsi_
static struct sbp2_command_info *sbp2util_find_command_for_orb(struct scsi_id_instance_data *scsi_id, dma_addr_t orb); static struct sbp2_command_info *sbp2util_find_command_for_orb(struct scsi_id_instance_data *scsi_id, dma_addr_t orb);
static struct sbp2_command_info *sbp2util_find_command_for_SCpnt(struct scsi_id_instance_data *scsi_id, void *SCpnt); static struct sbp2_command_info *sbp2util_find_command_for_SCpnt(struct scsi_id_instance_data *scsi_id, void *SCpnt);
static struct sbp2_command_info *sbp2util_allocate_command_orb(struct scsi_id_instance_data *scsi_id, static struct sbp2_command_info *sbp2util_allocate_command_orb(struct scsi_id_instance_data *scsi_id,
Scsi_Cmnd *Current_SCpnt, struct scsi_cmnd *Current_SCpnt,
void (*Current_done)(Scsi_Cmnd *)); void (*Current_done)(struct scsi_cmnd *));
static void sbp2util_mark_command_completed(struct scsi_id_instance_data *scsi_id, static void sbp2util_mark_command_completed(struct scsi_id_instance_data *scsi_id,
struct sbp2_command_info *command); struct sbp2_command_info *command);
...@@ -466,14 +466,16 @@ static int sbp2_create_command_orb(struct scsi_id_instance_data *scsi_id, ...@@ -466,14 +466,16 @@ static int sbp2_create_command_orb(struct scsi_id_instance_data *scsi_id,
unsigned int scsi_use_sg, unsigned int scsi_use_sg,
unsigned int scsi_request_bufflen, unsigned int scsi_request_bufflen,
void *scsi_request_buffer, void *scsi_request_buffer,
unsigned char scsi_dir); enum dma_data_direction dma_dir);
static int sbp2_link_orb_command(struct scsi_id_instance_data *scsi_id, static int sbp2_link_orb_command(struct scsi_id_instance_data *scsi_id,
struct sbp2_command_info *command); struct sbp2_command_info *command);
static int sbp2_send_command(struct scsi_id_instance_data *scsi_id, static int sbp2_send_command(struct scsi_id_instance_data *scsi_id,
Scsi_Cmnd *SCpnt, void (*done)(Scsi_Cmnd *)); struct scsi_cmnd *SCpnt,
void (*done)(struct scsi_cmnd *));
static unsigned int sbp2_status_to_sense_data(unchar *sbp2_status, unchar *sense_data); static unsigned int sbp2_status_to_sense_data(unchar *sbp2_status, unchar *sense_data);
static void sbp2_check_sbp2_command(struct scsi_id_instance_data *scsi_id, unchar *cmd); static void sbp2_check_sbp2_command(struct scsi_id_instance_data *scsi_id, unchar *cmd);
static void sbp2_check_sbp2_response(struct scsi_id_instance_data *scsi_id, Scsi_Cmnd *SCpnt); static void sbp2_check_sbp2_response(struct scsi_id_instance_data *scsi_id,
struct scsi_cmnd *SCpnt);
static void sbp2_parse_unit_directory(struct scsi_id_instance_data *scsi_id, static void sbp2_parse_unit_directory(struct scsi_id_instance_data *scsi_id,
struct unit_directory *ud); struct unit_directory *ud);
static int sbp2_set_busy_timeout(struct scsi_id_instance_data *scsi_id); static int sbp2_set_busy_timeout(struct scsi_id_instance_data *scsi_id);
......
...@@ -16,14 +16,25 @@ ...@@ -16,14 +16,25 @@
* You should have received a copy of the GNU General Public License * You should have received a copy of the GNU General Public License
* along with this program; if not, write to the Free Software Foundation, * along with this program; if not, write to the Free Software Foundation,
* Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. * Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
*
* NOTES:
*
* jds -- add private data to file to keep track of iso contexts associated
* with each open -- so release won't kill all iso transfers.
*
* Damien Douxchamps: Fix failure when the number of DMA pages per frame is
* one.
*
* ioctl return codes:
* EFAULT is only for invalid address for the argp
* EINVAL for out of range values
* EBUSY when trying to use an already used resource
* ESRCH when trying to free/stop a not used resource
* EAGAIN for resource allocation failure that could perhaps succeed later
* ENOTTY for unsupported ioctl request
*
*/ */
/* jds -- add private data to file to keep track of iso contexts associated
with each open -- so release won't kill all iso transfers */
/* Damien Douxchamps: Fix failure when the number of DMA pages per frame is
one */
#include <linux/config.h> #include <linux/config.h>
#include <linux/kernel.h> #include <linux/kernel.h>
#include <linux/list.h> #include <linux/list.h>
...@@ -146,8 +157,8 @@ printk(level "video1394: " fmt "\n" , ## args) ...@@ -146,8 +157,8 @@ printk(level "video1394: " fmt "\n" , ## args)
#define PRINT(level, card, fmt, args...) \ #define PRINT(level, card, fmt, args...) \
printk(level "video1394_%d: " fmt "\n" , card , ## args) printk(level "video1394_%d: " fmt "\n" , card , ## args)
void wakeup_dma_ir_ctx(unsigned long l); static void wakeup_dma_ir_ctx(unsigned long l);
void wakeup_dma_it_ctx(unsigned long l); static void wakeup_dma_it_ctx(unsigned long l);
static struct hpsb_highlevel video1394_highlevel; static struct hpsb_highlevel video1394_highlevel;
...@@ -487,7 +498,7 @@ find_ctx(struct list_head *list, int type, int channel) ...@@ -487,7 +498,7 @@ find_ctx(struct list_head *list, int type, int channel)
return NULL; return NULL;
} }
void wakeup_dma_ir_ctx(unsigned long l) static void wakeup_dma_ir_ctx(unsigned long l)
{ {
struct dma_iso_ctx *d = (struct dma_iso_ctx *) l; struct dma_iso_ctx *d = (struct dma_iso_ctx *) l;
int i; int i;
...@@ -560,7 +571,7 @@ static inline void put_timestamp(struct ti_ohci *ohci, struct dma_iso_ctx * d, ...@@ -560,7 +571,7 @@ static inline void put_timestamp(struct ti_ohci *ohci, struct dma_iso_ctx * d,
#endif #endif
} }
void wakeup_dma_it_ctx(unsigned long l) static void wakeup_dma_it_ctx(unsigned long l)
{ {
struct dma_iso_ctx *d = (struct dma_iso_ctx *) l; struct dma_iso_ctx *d = (struct dma_iso_ctx *) l;
struct ti_ohci *ohci = d->ohci; struct ti_ohci *ohci = d->ohci;
...@@ -723,7 +734,12 @@ static int __video1394_ioctl(struct file *file, ...@@ -723,7 +734,12 @@ static int __video1394_ioctl(struct file *file,
/* if channel < 0, find lowest available one */ /* if channel < 0, find lowest available one */
if (v.channel < 0) { if (v.channel < 0) {
mask = (u64)0x1; mask = (u64)0x1;
for (i=0; i<ISO_CHANNELS; i++) { for (i=0; ; i++) {
if (i == ISO_CHANNELS) {
PRINT(KERN_ERR, ohci->host->id,
"No free channel found");
return EAGAIN;
}
if (!(ohci->ISO_channel_usage & mask)) { if (!(ohci->ISO_channel_usage & mask)) {
v.channel = i; v.channel = i;
PRINT(KERN_INFO, ohci->host->id, "Found free channel %d", i); PRINT(KERN_INFO, ohci->host->id, "Found free channel %d", i);
...@@ -731,42 +747,40 @@ static int __video1394_ioctl(struct file *file, ...@@ -731,42 +747,40 @@ static int __video1394_ioctl(struct file *file,
} }
mask = mask << 1; mask = mask << 1;
} }
} } else if (v.channel >= ISO_CHANNELS) {
if (v.channel<0 || v.channel>(ISO_CHANNELS-1)) {
PRINT(KERN_ERR, ohci->host->id, PRINT(KERN_ERR, ohci->host->id,
"Iso channel %d out of bounds", v.channel); "Iso channel %d out of bounds", v.channel);
return -EFAULT; return -EINVAL;
} } else {
mask = (u64)0x1<<v.channel; mask = (u64)0x1<<v.channel;
printk("mask: %08X%08X usage: %08X%08X\n", }
PRINT(KERN_INFO, ohci->host->id, "mask: %08X%08X usage: %08X%08X\n",
(u32)(mask>>32),(u32)(mask&0xffffffff), (u32)(mask>>32),(u32)(mask&0xffffffff),
(u32)(ohci->ISO_channel_usage>>32), (u32)(ohci->ISO_channel_usage>>32),
(u32)(ohci->ISO_channel_usage&0xffffffff)); (u32)(ohci->ISO_channel_usage&0xffffffff));
if (ohci->ISO_channel_usage & mask) { if (ohci->ISO_channel_usage & mask) {
PRINT(KERN_ERR, ohci->host->id, PRINT(KERN_ERR, ohci->host->id,
"Channel %d is already taken", v.channel); "Channel %d is already taken", v.channel);
return -EFAULT; return -EBUSY;
} }
ohci->ISO_channel_usage |= mask;
if (v.buf_size == 0 || v.buf_size > VIDEO1394_MAX_SIZE) { if (v.buf_size == 0 || v.buf_size > VIDEO1394_MAX_SIZE) {
PRINT(KERN_ERR, ohci->host->id, PRINT(KERN_ERR, ohci->host->id,
"Invalid %d length buffer requested",v.buf_size); "Invalid %d length buffer requested",v.buf_size);
return -EFAULT; return -EINVAL;
} }
if (v.nb_buffers == 0 || v.nb_buffers > VIDEO1394_MAX_SIZE) { if (v.nb_buffers == 0 || v.nb_buffers > VIDEO1394_MAX_SIZE) {
PRINT(KERN_ERR, ohci->host->id, PRINT(KERN_ERR, ohci->host->id,
"Invalid %d buffers requested",v.nb_buffers); "Invalid %d buffers requested",v.nb_buffers);
return -EFAULT; return -EINVAL;
} }
if (v.nb_buffers * v.buf_size > VIDEO1394_MAX_SIZE) { if (v.nb_buffers * v.buf_size > VIDEO1394_MAX_SIZE) {
PRINT(KERN_ERR, ohci->host->id, PRINT(KERN_ERR, ohci->host->id,
"%d buffers of size %d bytes is too big", "%d buffers of size %d bytes is too big",
v.nb_buffers, v.buf_size); v.nb_buffers, v.buf_size);
return -EFAULT; return -EINVAL;
} }
if (cmd == VIDEO1394_IOC_LISTEN_CHANNEL) { if (cmd == VIDEO1394_IOC_LISTEN_CHANNEL) {
...@@ -777,7 +791,7 @@ static int __video1394_ioctl(struct file *file, ...@@ -777,7 +791,7 @@ static int __video1394_ioctl(struct file *file,
if (d == NULL) { if (d == NULL) {
PRINT(KERN_ERR, ohci->host->id, PRINT(KERN_ERR, ohci->host->id,
"Couldn't allocate ir context"); "Couldn't allocate ir context");
return -EFAULT; return -EAGAIN;
} }
initialize_dma_ir_ctx(d, v.sync_tag, v.flags); initialize_dma_ir_ctx(d, v.sync_tag, v.flags);
...@@ -798,7 +812,7 @@ static int __video1394_ioctl(struct file *file, ...@@ -798,7 +812,7 @@ static int __video1394_ioctl(struct file *file,
if (d == NULL) { if (d == NULL) {
PRINT(KERN_ERR, ohci->host->id, PRINT(KERN_ERR, ohci->host->id,
"Couldn't allocate it context"); "Couldn't allocate it context");
return -EFAULT; return -EAGAIN;
} }
initialize_dma_it_ctx(d, v.sync_tag, initialize_dma_it_ctx(d, v.sync_tag,
v.syt_offset, v.flags); v.syt_offset, v.flags);
...@@ -814,8 +828,12 @@ static int __video1394_ioctl(struct file *file, ...@@ -814,8 +828,12 @@ static int __video1394_ioctl(struct file *file,
v.channel); v.channel);
} }
if (copy_to_user(argp, &v, sizeof(v))) if (copy_to_user((void *)arg, &v, sizeof(v))) {
/* FIXME : free allocated dma resources */
return -EFAULT; return -EFAULT;
}
ohci->ISO_channel_usage |= mask;
return 0; return 0;
} }
...@@ -829,16 +847,16 @@ static int __video1394_ioctl(struct file *file, ...@@ -829,16 +847,16 @@ static int __video1394_ioctl(struct file *file,
if (copy_from_user(&channel, argp, sizeof(int))) if (copy_from_user(&channel, argp, sizeof(int)))
return -EFAULT; return -EFAULT;
if (channel<0 || channel>(ISO_CHANNELS-1)) { if (channel < 0 || channel >= ISO_CHANNELS) {
PRINT(KERN_ERR, ohci->host->id, PRINT(KERN_ERR, ohci->host->id,
"Iso channel %d out of bound", channel); "Iso channel %d out of bound", channel);
return -EFAULT; return -EINVAL;
} }
mask = (u64)0x1<<channel; mask = (u64)0x1<<channel;
if (!(ohci->ISO_channel_usage & mask)) { if (!(ohci->ISO_channel_usage & mask)) {
PRINT(KERN_ERR, ohci->host->id, PRINT(KERN_ERR, ohci->host->id,
"Channel %d is not being used", channel); "Channel %d is not being used", channel);
return -EFAULT; return -ESRCH;
} }
/* Mark this channel as unused */ /* Mark this channel as unused */
...@@ -849,7 +867,7 @@ static int __video1394_ioctl(struct file *file, ...@@ -849,7 +867,7 @@ static int __video1394_ioctl(struct file *file,
else else
d = find_ctx(&ctx->context_list, OHCI_ISO_TRANSMIT, channel); d = find_ctx(&ctx->context_list, OHCI_ISO_TRANSMIT, channel);
if (d == NULL) return -EFAULT; if (d == NULL) return -ESRCH;
PRINT(KERN_INFO, ohci->host->id, "Iso context %d " PRINT(KERN_INFO, ohci->host->id, "Iso context %d "
"stop talking on channel %d", d->ctx, channel); "stop talking on channel %d", d->ctx, channel);
free_dma_iso_ctx(d); free_dma_iso_ctx(d);
...@@ -870,7 +888,7 @@ static int __video1394_ioctl(struct file *file, ...@@ -870,7 +888,7 @@ static int __video1394_ioctl(struct file *file,
if ((v.buffer<0) || (v.buffer>d->num_desc)) { if ((v.buffer<0) || (v.buffer>d->num_desc)) {
PRINT(KERN_ERR, ohci->host->id, PRINT(KERN_ERR, ohci->host->id,
"Buffer %d out of range",v.buffer); "Buffer %d out of range",v.buffer);
return -EFAULT; return -EINVAL;
} }
spin_lock_irqsave(&d->lock,flags); spin_lock_irqsave(&d->lock,flags);
...@@ -879,7 +897,7 @@ static int __video1394_ioctl(struct file *file, ...@@ -879,7 +897,7 @@ static int __video1394_ioctl(struct file *file,
PRINT(KERN_ERR, ohci->host->id, PRINT(KERN_ERR, ohci->host->id,
"Buffer %d is already used",v.buffer); "Buffer %d is already used",v.buffer);
spin_unlock_irqrestore(&d->lock,flags); spin_unlock_irqrestore(&d->lock,flags);
return -EFAULT; return -EBUSY;
} }
d->buffer_status[v.buffer]=VIDEO1394_BUFFER_QUEUED; d->buffer_status[v.buffer]=VIDEO1394_BUFFER_QUEUED;
...@@ -933,7 +951,7 @@ static int __video1394_ioctl(struct file *file, ...@@ -933,7 +951,7 @@ static int __video1394_ioctl(struct file *file,
if ((v.buffer<0) || (v.buffer>d->num_desc)) { if ((v.buffer<0) || (v.buffer>d->num_desc)) {
PRINT(KERN_ERR, ohci->host->id, PRINT(KERN_ERR, ohci->host->id,
"Buffer %d out of range",v.buffer); "Buffer %d out of range",v.buffer);
return -EFAULT; return -EINVAL;
} }
/* /*
...@@ -976,7 +994,7 @@ static int __video1394_ioctl(struct file *file, ...@@ -976,7 +994,7 @@ static int __video1394_ioctl(struct file *file,
PRINT(KERN_ERR, ohci->host->id, PRINT(KERN_ERR, ohci->host->id,
"Buffer %d is not queued",v.buffer); "Buffer %d is not queued",v.buffer);
spin_unlock_irqrestore(&d->lock, flags); spin_unlock_irqrestore(&d->lock, flags);
return -EFAULT; return -ESRCH;
} }
/* set time of buffer */ /* set time of buffer */
...@@ -1015,7 +1033,7 @@ static int __video1394_ioctl(struct file *file, ...@@ -1015,7 +1033,7 @@ static int __video1394_ioctl(struct file *file,
if ((v.buffer<0) || (v.buffer>d->num_desc)) { if ((v.buffer<0) || (v.buffer>d->num_desc)) {
PRINT(KERN_ERR, ohci->host->id, PRINT(KERN_ERR, ohci->host->id,
"Buffer %d out of range",v.buffer); "Buffer %d out of range",v.buffer);
return -EFAULT; return -EINVAL;
} }
if (d->flags & VIDEO1394_VARIABLE_PACKET_SIZE) { if (d->flags & VIDEO1394_VARIABLE_PACKET_SIZE) {
...@@ -1044,7 +1062,7 @@ static int __video1394_ioctl(struct file *file, ...@@ -1044,7 +1062,7 @@ static int __video1394_ioctl(struct file *file,
spin_unlock_irqrestore(&d->lock,flags); spin_unlock_irqrestore(&d->lock,flags);
if (psizes) if (psizes)
kfree(psizes); kfree(psizes);
return -EFAULT; return -EBUSY;
} }
if (d->flags & VIDEO1394_VARIABLE_PACKET_SIZE) { if (d->flags & VIDEO1394_VARIABLE_PACKET_SIZE) {
...@@ -1118,7 +1136,7 @@ static int __video1394_ioctl(struct file *file, ...@@ -1118,7 +1136,7 @@ static int __video1394_ioctl(struct file *file,
if ((v.buffer<0) || (v.buffer>d->num_desc)) { if ((v.buffer<0) || (v.buffer>d->num_desc)) {
PRINT(KERN_ERR, ohci->host->id, PRINT(KERN_ERR, ohci->host->id,
"Buffer %d out of range",v.buffer); "Buffer %d out of range",v.buffer);
return -EFAULT; return -EINVAL;
} }
switch(d->buffer_status[v.buffer]) { switch(d->buffer_status[v.buffer]) {
...@@ -1144,11 +1162,11 @@ static int __video1394_ioctl(struct file *file, ...@@ -1144,11 +1162,11 @@ static int __video1394_ioctl(struct file *file,
default: default:
PRINT(KERN_ERR, ohci->host->id, PRINT(KERN_ERR, ohci->host->id,
"Buffer %d is not queued",v.buffer); "Buffer %d is not queued",v.buffer);
return -EFAULT; return -ESRCH;
} }
} }
default: default:
return -EINVAL; return -ENOTTY;
} }
} }
...@@ -1170,7 +1188,7 @@ static long video1394_ioctl(struct file *file, unsigned int cmd, unsigned long a ...@@ -1170,7 +1188,7 @@ static long video1394_ioctl(struct file *file, unsigned int cmd, unsigned long a
* But e.g. pte_alloc() does not work in modules ... :-( * But e.g. pte_alloc() does not work in modules ... :-(
*/ */
int video1394_mmap(struct file *file, struct vm_area_struct *vma) static int video1394_mmap(struct file *file, struct vm_area_struct *vma)
{ {
struct file_ctx *ctx = (struct file_ctx *)file->private_data; struct file_ctx *ctx = (struct file_ctx *)file->private_data;
int res = -EINVAL; int res = -EINVAL;
...@@ -1269,6 +1287,16 @@ static struct ieee1394_device_id video1394_id_table[] = { ...@@ -1269,6 +1287,16 @@ static struct ieee1394_device_id video1394_id_table[] = {
.specifier_id = CAMERA_UNIT_SPEC_ID_ENTRY & 0xffffff, .specifier_id = CAMERA_UNIT_SPEC_ID_ENTRY & 0xffffff,
.version = CAMERA_SW_VERSION_ENTRY & 0xffffff .version = CAMERA_SW_VERSION_ENTRY & 0xffffff
}, },
{
.match_flags = IEEE1394_MATCH_SPECIFIER_ID | IEEE1394_MATCH_VERSION,
.specifier_id = CAMERA_UNIT_SPEC_ID_ENTRY & 0xffffff,
.version = (CAMERA_SW_VERSION_ENTRY + 1) & 0xffffff
},
{
.match_flags = IEEE1394_MATCH_SPECIFIER_ID | IEEE1394_MATCH_VERSION,
.specifier_id = CAMERA_UNIT_SPEC_ID_ENTRY & 0xffffff,
.version = (CAMERA_SW_VERSION_ENTRY + 2) & 0xffffff
},
{ } { }
}; };
...@@ -1304,6 +1332,9 @@ static void video1394_add_host (struct hpsb_host *host) ...@@ -1304,6 +1332,9 @@ static void video1394_add_host (struct hpsb_host *host)
hpsb_set_hostinfo_key(&video1394_highlevel, host, ohci->host->id); hpsb_set_hostinfo_key(&video1394_highlevel, host, ohci->host->id);
minor = IEEE1394_MINOR_BLOCK_VIDEO1394 * 16 + ohci->host->id; minor = IEEE1394_MINOR_BLOCK_VIDEO1394 * 16 + ohci->host->id;
class_simple_device_add(hpsb_protocol_class, MKDEV(
IEEE1394_MAJOR, minor),
NULL, "%s-%d", VIDEO1394_DRIVER_NAME, ohci->host->id);
devfs_mk_cdev(MKDEV(IEEE1394_MAJOR, minor), devfs_mk_cdev(MKDEV(IEEE1394_MAJOR, minor),
S_IFCHR | S_IRUSR | S_IWUSR, S_IFCHR | S_IRUSR | S_IWUSR,
"%s/%d", VIDEO1394_DRIVER_NAME, ohci->host->id); "%s/%d", VIDEO1394_DRIVER_NAME, ohci->host->id);
...@@ -1314,8 +1345,11 @@ static void video1394_remove_host (struct hpsb_host *host) ...@@ -1314,8 +1345,11 @@ static void video1394_remove_host (struct hpsb_host *host)
{ {
struct ti_ohci *ohci = hpsb_get_hostinfo(&video1394_highlevel, host); struct ti_ohci *ohci = hpsb_get_hostinfo(&video1394_highlevel, host);
if (ohci) if (ohci) {
class_simple_device_remove(MKDEV(IEEE1394_MAJOR,
IEEE1394_MINOR_BLOCK_VIDEO1394 * 16 + ohci->host->id));
devfs_remove("%s/%d", VIDEO1394_DRIVER_NAME, ohci->host->id); devfs_remove("%s/%d", VIDEO1394_DRIVER_NAME, ohci->host->id);
}
return; return;
} }
......
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