Commit 64632844 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 1274fcd6 10107e9c
...@@ -1082,9 +1082,21 @@ M: Gadi Oxman <gadio@netvision.net.il> ...@@ -1082,9 +1082,21 @@ M: Gadi Oxman <gadio@netvision.net.il>
L: linux-kernel@vger.kernel.org L: linux-kernel@vger.kernel.org
S: Maintained S: Maintained
IEEE 1394 ETHERNET (eth1394)
L: linux1394-devel@lists.sourceforge.net
W: http://www.linux1394.org/
S: Orphan
IEEE 1394 SBP2
L: linux1394-devel@lists.sourceforge.net
W: http://www.linux1394.org/
S: Orphan
IEEE 1394 SUBSYSTEM IEEE 1394 SUBSYSTEM
P: Ben Collins P: Ben Collins
M: bcollins@debian.org M: bcollins@debian.org
P: Jody McIntyre
M: scjody@steamballoon.com
L: linux1394-devel@lists.sourceforge.net L: linux1394-devel@lists.sourceforge.net
W: http://www.linux1394.org/ W: http://www.linux1394.org/
S: Maintained S: Maintained
...@@ -1092,13 +1104,15 @@ S: Maintained ...@@ -1092,13 +1104,15 @@ S: Maintained
IEEE 1394 OHCI DRIVER IEEE 1394 OHCI DRIVER
P: Ben Collins P: Ben Collins
M: bcollins@debian.org M: bcollins@debian.org
P: Jody McIntyre
M: scjody@steamballoon.com
L: linux1394-devel@lists.sourceforge.net L: linux1394-devel@lists.sourceforge.net
W: http://www.linux1394.org/ W: http://www.linux1394.org/
S: Maintained S: Maintained
IEEE 1394 PCILYNX DRIVER IEEE 1394 PCILYNX DRIVER
P: Andreas Bombe P: Jody McIntyre
M: andreas.bombe@munich.netsurf.de M: scjody@steamballoon.com
L: linux1394-devel@lists.sourceforge.net L: linux1394-devel@lists.sourceforge.net
W: http://www.linux1394.org/ W: http://www.linux1394.org/
S: Maintained S: Maintained
...@@ -1106,6 +1120,8 @@ S: Maintained ...@@ -1106,6 +1120,8 @@ S: Maintained
IEEE 1394 RAW I/O DRIVER IEEE 1394 RAW I/O DRIVER
P: Ben Collins P: Ben Collins
M: bcollins@debian.org M: bcollins@debian.org
P: Dan Dennedy
M: dan@dennedy.org
L: linux1394-devel@lists.sourceforge.net L: linux1394-devel@lists.sourceforge.net
W: http://www.linux1394.org/ W: http://www.linux1394.org/
S: Maintained S: Maintained
......
...@@ -5,6 +5,7 @@ menu "IEEE 1394 (FireWire) support" ...@@ -5,6 +5,7 @@ menu "IEEE 1394 (FireWire) support"
config IEEE1394 config IEEE1394
tristate "IEEE 1394 (FireWire) support" tristate "IEEE 1394 (FireWire) support"
depends on PCI || BROKEN depends on PCI || BROKEN
select NET
help help
IEEE 1394 describes a high performance serial bus, which is also IEEE 1394 describes a high performance serial bus, which is also
known as FireWire(tm) or i.Link(tm) and is used for connecting all known as FireWire(tm) or i.Link(tm) and is used for connecting all
......
...@@ -286,7 +286,7 @@ static struct hpsb_highlevel amdtp_highlevel; ...@@ -286,7 +286,7 @@ static struct hpsb_highlevel amdtp_highlevel;
#define OHCI1394_CONTEXT_DEAD 0x00000800 #define OHCI1394_CONTEXT_DEAD 0x00000800
#define OHCI1394_CONTEXT_ACTIVE 0x00000400 #define OHCI1394_CONTEXT_ACTIVE 0x00000400
void ohci1394_start_it_ctx(struct ti_ohci *ohci, int ctx, static void ohci1394_start_it_ctx(struct ti_ohci *ohci, int ctx,
dma_addr_t first_cmd, int z, int cycle_match) dma_addr_t first_cmd, int z, int cycle_match)
{ {
reg_write(ohci, OHCI1394_IsoXmitIntMaskSet, 1 << ctx); reg_write(ohci, OHCI1394_IsoXmitIntMaskSet, 1 << ctx);
...@@ -298,13 +298,13 @@ void ohci1394_start_it_ctx(struct ti_ohci *ohci, int ctx, ...@@ -298,13 +298,13 @@ void ohci1394_start_it_ctx(struct ti_ohci *ohci, int ctx,
OHCI1394_CONTEXT_RUN); OHCI1394_CONTEXT_RUN);
} }
void ohci1394_wake_it_ctx(struct ti_ohci *ohci, int ctx) static void ohci1394_wake_it_ctx(struct ti_ohci *ohci, int ctx)
{ {
reg_write(ohci, OHCI1394_IsoXmitContextControlSet + ctx * 16, reg_write(ohci, OHCI1394_IsoXmitContextControlSet + ctx * 16,
OHCI1394_CONTEXT_WAKE); OHCI1394_CONTEXT_WAKE);
} }
void ohci1394_stop_it_ctx(struct ti_ohci *ohci, int ctx, int synchronous) static void ohci1394_stop_it_ctx(struct ti_ohci *ohci, int ctx, int synchronous)
{ {
u32 control; u32 control;
int wait; int wait;
...@@ -530,7 +530,7 @@ static __inline__ int fraction_ceil(struct fraction *frac) ...@@ -530,7 +530,7 @@ static __inline__ int fraction_ceil(struct fraction *frac)
return frac->integer + (frac->numerator > 0 ? 1 : 0); return frac->integer + (frac->numerator > 0 ? 1 : 0);
} }
void packet_initialize(struct packet *p, struct packet *next) static void packet_initialize(struct packet *p, struct packet *next)
{ {
/* Here we initialize the dma descriptor block for /* Here we initialize the dma descriptor block for
* transferring one iso packet. We use two descriptors per * transferring one iso packet. We use two descriptors per
...@@ -559,7 +559,7 @@ void packet_initialize(struct packet *p, struct packet *next) ...@@ -559,7 +559,7 @@ void packet_initialize(struct packet *p, struct packet *next)
p->db->payload_desc.status = 0; p->db->payload_desc.status = 0;
} }
struct packet_list *packet_list_alloc(struct stream *s) static struct packet_list *packet_list_alloc(struct stream *s)
{ {
int i; int i;
struct packet_list *pl; struct packet_list *pl;
...@@ -588,7 +588,7 @@ struct packet_list *packet_list_alloc(struct stream *s) ...@@ -588,7 +588,7 @@ struct packet_list *packet_list_alloc(struct stream *s)
return pl; return pl;
} }
void packet_list_free(struct packet_list *pl, struct stream *s) static void packet_list_free(struct packet_list *pl, struct stream *s)
{ {
int i; int i;
...@@ -1010,7 +1010,7 @@ static int stream_configure(struct stream *s, int cmd, struct amdtp_ioctl *cfg) ...@@ -1010,7 +1010,7 @@ static int stream_configure(struct stream *s, int cmd, struct amdtp_ioctl *cfg)
return 0; return 0;
} }
struct stream *stream_alloc(struct amdtp_host *host) static struct stream *stream_alloc(struct amdtp_host *host)
{ {
struct stream *s; struct stream *s;
unsigned long flags; unsigned long flags;
...@@ -1062,7 +1062,7 @@ struct stream *stream_alloc(struct amdtp_host *host) ...@@ -1062,7 +1062,7 @@ struct stream *stream_alloc(struct amdtp_host *host)
return s; return s;
} }
void stream_free(struct stream *s) static void stream_free(struct stream *s)
{ {
unsigned long flags; unsigned long flags;
......
...@@ -67,8 +67,8 @@ int hpsb_default_host_entry(struct hpsb_host *host) ...@@ -67,8 +67,8 @@ int hpsb_default_host_entry(struct hpsb_host *host)
ret = csr1212_associate_keyval(vend_id, text); ret = csr1212_associate_keyval(vend_id, text);
csr1212_release_keyval(text); csr1212_release_keyval(text);
ret |= csr1212_attach_keyval_to_directory(root, vend_id); ret |= csr1212_attach_keyval_to_directory(root, vend_id);
csr1212_release_keyval(vend_id);
if (ret != CSR1212_SUCCESS) { if (ret != CSR1212_SUCCESS) {
csr1212_release_keyval(vend_id);
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;
} }
...@@ -181,9 +182,9 @@ struct csr1212_csr *csr1212_create_csr(struct csr1212_bus_ops *ops, ...@@ -181,9 +182,9 @@ struct csr1212_csr *csr1212_create_csr(struct csr1212_bus_ops *ops,
return NULL; return NULL;
} }
/* The keyval key id is not used for the root node, but a valid key id /* The keyval key id is not used for the root node, but a valid key id
* that can be used for a directory needs to be passed to * that can be used for a directory needs to be passed to
* csr1212_new_directory(). */ * csr1212_new_directory(). */
csr->root_kv = csr1212_new_directory(CSR1212_KV_ID_VENDOR); csr->root_kv = csr1212_new_directory(CSR1212_KV_ID_VENDOR);
if (!csr->root_kv) { if (!csr->root_kv) {
CSR1212_FREE(csr->cache_head); CSR1212_FREE(csr->cache_head);
...@@ -709,7 +710,7 @@ void _csr1212_destroy_keyval(struct csr1212_keyval *kv) ...@@ -709,7 +710,7 @@ void _csr1212_destroy_keyval(struct csr1212_keyval *kv)
tail->next = k->value.directory.dentries_head; tail->next = k->value.directory.dentries_head;
k->value.directory.dentries_head->prev = tail; k->value.directory.dentries_head->prev = tail;
tail = k->value.directory.dentries_tail; tail = k->value.directory.dentries_tail;
} }
} }
free_keyval(k); free_keyval(k);
k = a; k = a;
...@@ -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;
...@@ -919,8 +921,8 @@ size_t csr1212_generate_layout_order(struct csr1212_keyval *kv) ...@@ -919,8 +921,8 @@ size_t csr1212_generate_layout_order(struct csr1212_keyval *kv)
} }
struct csr1212_keyval *csr1212_generate_positions(struct csr1212_csr_rom_cache *cache, struct csr1212_keyval *csr1212_generate_positions(struct csr1212_csr_rom_cache *cache,
struct csr1212_keyval *start_kv, struct csr1212_keyval *start_kv,
int start_pos) int start_pos)
{ {
struct csr1212_keyval *kv = start_kv; struct csr1212_keyval *kv = start_kv;
struct csr1212_keyval *okv = start_kv; struct csr1212_keyval *okv = start_kv;
...@@ -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) {
kv->offset = cache->offset + pos; /* Special case: Extended ROM leafs */
if (kv->key.id != CSR1212_KV_ID_EXTENDED_ROM) {
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;
...@@ -1227,8 +1241,8 @@ static int csr1212_parse_bus_info_block(struct csr1212_csr *csr) ...@@ -1227,8 +1241,8 @@ static int csr1212_parse_bus_info_block(struct csr1212_csr *csr)
return CSR1212_EINVAL; return CSR1212_EINVAL;
#if 0 #if 0
/* Apparently there are too many differnt wrong implementations of the /* Apparently there are too many differnt wrong implementations of the
* CRC algorithm that verifying them is moot. */ * CRC algorithm that verifying them is moot. */
if ((csr1212_crc16(bi->data, bi->crc_length) != bi->crc) && if ((csr1212_crc16(bi->data, bi->crc_length) != bi->crc) &&
(csr1212_msft_crc16(bi->data, bi->crc_length) != bi->crc)) (csr1212_msft_crc16(bi->data, bi->crc_length) != bi->crc))
return CSR1212_EINVAL; return CSR1212_EINVAL;
...@@ -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)
{ {
...@@ -1338,8 +1351,8 @@ int csr1212_parse_keyval(struct csr1212_keyval *kv, ...@@ -1338,8 +1351,8 @@ int csr1212_parse_keyval(struct csr1212_keyval *kv,
kvi_len = CSR1212_BE16_TO_CPU(kvi->length); kvi_len = CSR1212_BE16_TO_CPU(kvi->length);
#if 0 #if 0
/* Apparently there are too many differnt wrong implementations of the /* Apparently there are too many differnt wrong implementations of the
* CRC algorithm that verifying them is moot. */ * CRC algorithm that verifying them is moot. */
if ((csr1212_crc16(kvi->data, kvi_len) != kvi->crc) && if ((csr1212_crc16(kvi->data, kvi_len) != kvi->crc) &&
(csr1212_msft_crc16(kvi->data, kvi_len) != kvi->crc)) { (csr1212_msft_crc16(kvi->data, kvi_len) != kvi->crc)) {
ret = CSR1212_EINVAL; ret = CSR1212_EINVAL;
...@@ -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;
...@@ -449,7 +448,7 @@ static int eth1394_update(struct unit_directory *ud) ...@@ -449,7 +448,7 @@ static int eth1394_update(struct unit_directory *ud)
if (!node_info) { if (!node_info) {
kfree(node); kfree(node);
return -ENOMEM; return -ENOMEM;
} }
spin_lock_init(&node_info->pdg.lock); spin_lock_init(&node_info->pdg.lock);
INIT_LIST_HEAD(&node_info->pdg.list); INIT_LIST_HEAD(&node_info->pdg.list);
...@@ -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--;
...@@ -1583,7 +1582,7 @@ static inline void ether1394_dg_complete(struct packet_task *ptask, int fail) ...@@ -1583,7 +1582,7 @@ static inline void ether1394_dg_complete(struct packet_task *ptask, int fail)
struct sk_buff *skb = ptask->skb; struct sk_buff *skb = ptask->skb;
struct net_device *dev = skb->dev; struct net_device *dev = skb->dev;
struct eth1394_priv *priv = netdev_priv(dev); struct eth1394_priv *priv = netdev_priv(dev);
unsigned long flags; unsigned long flags;
/* Statistics */ /* Statistics */
spin_lock_irqsave(&priv->lock, flags); spin_lock_irqsave(&priv->lock, flags);
...@@ -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,15 +1039,19 @@ static int hpsbpkt_thread(void *__hi) ...@@ -1030,15 +1039,19 @@ 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)) {
if (current->flags & PF_FREEZE) {
refrigerator(0);
continue;
}
printk("khpsbpkt: received unexpected signal?!\n" );
break; break;
if (current->flags & PF_FREEZE) {
refrigerator(0);
continue;
} }
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;
...@@ -952,31 +997,10 @@ static struct unit_directory *nodemgr_process_unit_directory ...@@ -952,31 +997,10 @@ 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);
...@@ -515,12 +519,6 @@ static void ohci_initialize(struct ti_ohci *ohci) ...@@ -515,12 +519,6 @@ static void ohci_initialize(struct ti_ohci *ohci)
/* Now get our max packet size */ /* Now get our max packet size */
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,7 +384,8 @@ static quadlet_t generate_own_selfid(struct ti_lynx *lynx, ...@@ -384,7 +384,8 @@ 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 */
lsid |= (phyreg[6] & 0x01) << 11; /* contender (phy dependent) */ if (!hpsb_disable_irm)
lsid |= (phyreg[6] & 0x01) << 11; /* contender (phy dependent) */
/* lsid |= 1 << 11; *//* set contender (hack) */ /* lsid |= 1 << 11; *//* set contender (hack) */
lsid |= (phyreg[6] & 0x10) >> 3; /* initiated reset */ lsid |= (phyreg[6] & 0x10) >> 3; /* initiated reset */
...@@ -500,7 +501,7 @@ static void send_next(struct ti_lynx *lynx, int what) ...@@ -500,7 +501,7 @@ static void send_next(struct ti_lynx *lynx, int what)
pcl.async_error_next = PCL_NEXT_INVALID; pcl.async_error_next = PCL_NEXT_INVALID;
pcl.pcl_status = 0; pcl.pcl_status = 0;
pcl.buffer[0].control = packet->speed_code << 14 | packet->header_size; pcl.buffer[0].control = packet->speed_code << 14 | packet->header_size;
#ifdef __BIG_ENDIAN #ifndef __BIG_ENDIAN
pcl.buffer[0].control |= PCL_BIGENDIAN; pcl.buffer[0].control |= PCL_BIGENDIAN;
#endif #endif
pcl.buffer[0].pointer = d->header_dma; pcl.buffer[0].pointer = d->header_dma;
...@@ -1521,10 +1522,6 @@ static int __devinit add_card(struct pci_dev *dev, ...@@ -1521,10 +1522,6 @@ static int __devinit add_card(struct pci_dev *dev,
int i; int i;
int error; int error;
/* needed for i2c communication with serial eeprom */
struct i2c_adapter i2c_adapter;
struct i2c_algo_bit_data i2c_adapter_data;
error = -ENXIO; error = -ENXIO;
if (pci_set_dma_mask(dev, 0xffffffff)) if (pci_set_dma_mask(dev, 0xffffffff))
...@@ -1697,7 +1694,7 @@ static int __devinit add_card(struct pci_dev *dev, ...@@ -1697,7 +1694,7 @@ static int __devinit add_card(struct pci_dev *dev,
pcl.async_error_next = PCL_NEXT_INVALID; pcl.async_error_next = PCL_NEXT_INVALID;
pcl.buffer[0].control = PCL_CMD_RCV | 16; pcl.buffer[0].control = PCL_CMD_RCV | 16;
#ifdef __BIG_ENDIAN #ifndef __BIG_ENDIAN
pcl.buffer[0].control |= PCL_BIGENDIAN; pcl.buffer[0].control |= PCL_BIGENDIAN;
#endif #endif
pcl.buffer[1].control = PCL_LAST_BUFF | 4080; pcl.buffer[1].control = PCL_LAST_BUFF | 4080;
...@@ -1779,26 +1776,40 @@ static int __devinit add_card(struct pci_dev *dev, ...@@ -1779,26 +1776,40 @@ static int __devinit add_card(struct pci_dev *dev,
| LINK_CONTROL_TX_ASYNC_EN | LINK_CONTROL_RX_ASYNC_EN | LINK_CONTROL_TX_ASYNC_EN | LINK_CONTROL_RX_ASYNC_EN
| 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
reg_set_bits(lynx, GPIO_CTRL_A, 0x1); * work elsewhere? */
reg_write(lynx, GPIO_DATA_BASE + 0x3c, 0x1); reg_set_bits(lynx, GPIO_CTRL_A, 0x1);
} else { reg_write(lynx, GPIO_DATA_BASE + 0x3c, 0x1);
/* set the contender and LCtrl bit in the extended PHY register }
* set. (Should check that bis 0,1,2 (=0xE0) is set } else {
* in register 2?) /* set the contender (if appropriate) and LCtrl bit in the
*/ * extended PHY register set. (Should check that PHY_02_EXTENDED
i = get_phy_reg(lynx, 4); * is set in register 2?)
if (i != -1) set_phy_reg(lynx, 4, i | 0xc0); */
} i = get_phy_reg(lynx, 4);
i |= PHY_04_LCTRL;
if (hpsb_disable_irm)
i &= !PHY_04_CONTENDER;
else
i |= PHY_04_CONTENDER;
if (i != -1) set_phy_reg(lynx, 4, i);
}
if (!skip_eeprom) if (!skip_eeprom)
{ {
i2c_adapter = bit_ops; /* needed for i2c communication with serial eeprom */
struct i2c_adapter *i2c_ad;
struct i2c_algo_bit_data i2c_adapter_data;
error = -ENOMEM;
i2c_ad = kmalloc(sizeof(struct i2c_adapter), SLAB_KERNEL);
if (!i2c_ad) FAIL("failed to allocate I2C adapter memory");
memcpy(i2c_ad, &bit_ops, sizeof(struct i2c_adapter));
i2c_adapter_data = bit_data; i2c_adapter_data = bit_data;
i2c_adapter.algo_data = &i2c_adapter_data; i2c_ad->algo_data = &i2c_adapter_data;
i2c_adapter_data.data = lynx; i2c_adapter_data.data = lynx;
PRINTD(KERN_DEBUG, lynx->id,"original eeprom control: %d", PRINTD(KERN_DEBUG, lynx->id,"original eeprom control: %d",
...@@ -1808,8 +1819,9 @@ static int __devinit add_card(struct pci_dev *dev, ...@@ -1808,8 +1819,9 @@ static int __devinit add_card(struct pci_dev *dev,
lynx->i2c_driven_state = 0x00000070; lynx->i2c_driven_state = 0x00000070;
reg_write(lynx, SERIAL_EEPROM_CONTROL, lynx->i2c_driven_state); reg_write(lynx, SERIAL_EEPROM_CONTROL, lynx->i2c_driven_state);
if (i2c_bit_add_bus(&i2c_adapter) < 0) if (i2c_bit_add_bus(i2c_ad) < 0)
{ {
kfree(i2c_ad);
error = -ENXIO; error = -ENXIO;
FAIL("unable to register i2c"); FAIL("unable to register i2c");
} }
...@@ -1825,13 +1837,13 @@ static int __devinit add_card(struct pci_dev *dev, ...@@ -1825,13 +1837,13 @@ static int __devinit add_card(struct pci_dev *dev,
#ifdef CONFIG_IEEE1394_VERBOSEDEBUG #ifdef CONFIG_IEEE1394_VERBOSEDEBUG
union i2c_smbus_data data; union i2c_smbus_data data;
if (i2c_smbus_xfer(&i2c_adapter, 80, 0, I2C_SMBUS_WRITE, 0, I2C_SMBUS_BYTE,NULL)) if (i2c_smbus_xfer(i2c_ad, 80, 0, I2C_SMBUS_WRITE, 0, I2C_SMBUS_BYTE,NULL))
PRINT(KERN_ERR, lynx->id,"eeprom read start has failed"); PRINT(KERN_ERR, lynx->id,"eeprom read start has failed");
else else
{ {
u16 addr; u16 addr;
for (addr=0x00; addr < 0x100; addr++) { for (addr=0x00; addr < 0x100; addr++) {
if (i2c_smbus_xfer(&i2c_adapter, 80, 0, I2C_SMBUS_READ, 0, I2C_SMBUS_BYTE,& data)) { if (i2c_smbus_xfer(i2c_ad, 80, 0, I2C_SMBUS_READ, 0, I2C_SMBUS_BYTE,& data)) {
PRINT(KERN_ERR, lynx->id, "unable to read i2c %x", addr); PRINT(KERN_ERR, lynx->id, "unable to read i2c %x", addr);
break; break;
} }
...@@ -1843,7 +1855,7 @@ static int __devinit add_card(struct pci_dev *dev, ...@@ -1843,7 +1855,7 @@ static int __devinit add_card(struct pci_dev *dev,
/* we use i2c_transfer, because i2c_smbus_read_block_data does not work properly and we /* we use i2c_transfer, because i2c_smbus_read_block_data does not work properly and we
do it more efficiently in one transaction rather then using several reads */ do it more efficiently in one transaction rather then using several reads */
if (i2c_transfer(&i2c_adapter, msg, 2) < 0) { if (i2c_transfer(i2c_ad, msg, 2) < 0) {
PRINT(KERN_ERR, lynx->id, "unable to read bus info block from i2c"); PRINT(KERN_ERR, lynx->id, "unable to read bus info block from i2c");
} else { } else {
int i; int i;
...@@ -1863,13 +1875,15 @@ static int __devinit add_card(struct pci_dev *dev, ...@@ -1863,13 +1875,15 @@ static int __devinit add_card(struct pci_dev *dev,
{ {
PRINT(KERN_DEBUG, lynx->id, "read a valid bus info block from"); PRINT(KERN_DEBUG, lynx->id, "read a valid bus info block from");
} else { } else {
kfree(i2c_ad);
error = -ENXIO; error = -ENXIO;
FAIL("read something from serial eeprom, but it does not seem to be a valid bus info block"); FAIL("read something from serial eeprom, but it does not seem to be a valid bus info block");
} }
} }
i2c_bit_del_bus(&i2c_adapter); i2c_bit_del_bus(i2c_ad);
kfree(i2c_ad);
} }
} }
......
This source diff could not be displayed because it is too large. You can view the blob instead.
...@@ -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; PRINT(KERN_INFO, ohci->host->id, "mask: %08X%08X usage: %08X%08X\n",
printk("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,9 +1345,12 @@ static void video1394_remove_host (struct hpsb_host *host) ...@@ -1314,9 +1345,12 @@ 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