Commit 72c55a9d authored by Jody McIntyre's avatar Jody McIntyre

Merge modernduck.com:/usr/src/bk/linux-2.5

into modernduck.com:/usr/src/bk/1394-2.6
parents b389f382 743d27bf
...@@ -1082,30 +1082,40 @@ M: Gadi Oxman <gadio@netvision.net.il> ...@@ -1082,30 +1082,40 @@ 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: Jody McIntyre
M: bcollins@debian.org 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 OHCI DRIVER IEEE 1394 OHCI DRIVER
P: Ben Collins P: Jody McIntyre
M: bcollins@debian.org 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
IEEE 1394 RAW I/O DRIVER IEEE 1394 RAW I/O DRIVER
P: Ben Collins P: Dan Dennedy
M: bcollins@debian.org 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
......
...@@ -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;
...@@ -1697,7 +1698,7 @@ static int __devinit add_card(struct pci_dev *dev, ...@@ -1697,7 +1698,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,20 +1781,26 @@ static int __devinit add_card(struct pci_dev *dev, ...@@ -1780,20 +1781,26 @@ 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; i2c_adapter = bit_ops;
......
...@@ -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