Skip to content
Projects
Groups
Snippets
Help
Loading...
Help
Support
Keyboard shortcuts
?
Submit feedback
Contribute to GitLab
Sign in / Register
Toggle navigation
L
linux
Project overview
Project overview
Details
Activity
Releases
Repository
Repository
Files
Commits
Branches
Tags
Contributors
Graph
Compare
Issues
0
Issues
0
List
Boards
Labels
Milestones
Merge Requests
0
Merge Requests
0
Analytics
Analytics
Repository
Value Stream
Wiki
Wiki
Snippets
Snippets
Members
Members
Collapse sidebar
Close sidebar
Activity
Graph
Create a new issue
Commits
Issue Boards
Open sidebar
Kirill Smelkov
linux
Commits
d412a4c3
Commit
d412a4c3
authored
Dec 29, 2003
by
Ben Collins
Browse files
Options
Browse Files
Download
Plain Diff
Merge
http://linux.bkbits.net/linux-2.5
into debian.org:/usr/src/kernel/linux-2.6
parents
bfd3fcff
94030996
Changes
19
Show whitespace changes
Inline
Side-by-side
Showing
19 changed files
with
470 additions
and
423 deletions
+470
-423
drivers/ieee1394/Kconfig
drivers/ieee1394/Kconfig
+10
-10
drivers/ieee1394/eth1394.c
drivers/ieee1394/eth1394.c
+8
-8
drivers/ieee1394/highlevel.c
drivers/ieee1394/highlevel.c
+24
-20
drivers/ieee1394/highlevel.h
drivers/ieee1394/highlevel.h
+3
-2
drivers/ieee1394/hosts.c
drivers/ieee1394/hosts.c
+21
-83
drivers/ieee1394/hosts.h
drivers/ieee1394/hosts.h
+3
-19
drivers/ieee1394/ieee1394_core.c
drivers/ieee1394/ieee1394_core.c
+63
-57
drivers/ieee1394/ieee1394_core.h
drivers/ieee1394/ieee1394_core.h
+12
-12
drivers/ieee1394/ieee1394_transactions.c
drivers/ieee1394/ieee1394_transactions.c
+29
-40
drivers/ieee1394/iso.c
drivers/ieee1394/iso.c
+12
-4
drivers/ieee1394/iso.h
drivers/ieee1394/iso.h
+11
-0
drivers/ieee1394/nodemgr.c
drivers/ieee1394/nodemgr.c
+46
-42
drivers/ieee1394/nodemgr.h
drivers/ieee1394/nodemgr.h
+9
-0
drivers/ieee1394/ohci1394.c
drivers/ieee1394/ohci1394.c
+31
-20
drivers/ieee1394/oui.db
drivers/ieee1394/oui.db
+3
-3
drivers/ieee1394/pcilynx.c
drivers/ieee1394/pcilynx.c
+17
-13
drivers/ieee1394/raw1394.c
drivers/ieee1394/raw1394.c
+116
-10
drivers/ieee1394/raw1394.h
drivers/ieee1394/raw1394.h
+5
-0
drivers/ieee1394/sbp2.c
drivers/ieee1394/sbp2.c
+47
-80
No files found.
drivers/ieee1394/Kconfig
View file @
d412a4c3
# -*- shell-script -*-
menu "IEEE 1394 (FireWire) support (EXPERIMENTAL)"
depends on
PCI &&
EXPERIMENTAL
depends on EXPERIMENTAL
config IEEE1394
tristate "IEEE 1394 (FireWire) support (EXPERIMENTAL)"
...
...
@@ -15,7 +15,7 @@ config IEEE1394
is the core support only, you will also need to select a driver for
your IEEE 1394 adapter.
To compile this driver as a module,
choose
M here: the
To compile this driver as a module,
say
M here: the
module will be called ieee1394.
comment "Subsystem Options"
...
...
@@ -56,13 +56,13 @@ comment "Texas Instruments PCILynx requires I2C bit-banging"
config IEEE1394_PCILYNX
tristate "Texas Instruments PCILynx support"
depends on IEEE1394 && I2C_ALGOBIT
depends on
PCI &&
IEEE1394 && I2C_ALGOBIT
help
Say Y here if you have an IEEE-1394 controller with the Texas
Instruments PCILynx chip. Note: this driver is written for revision
2 of this chip and may not work with revision 0.
To compile this driver as a module,
choose
M here: the
To compile this driver as a module,
say
M here: the
module will be called pcilynx.
# Non-maintained pcilynx options
...
...
@@ -72,7 +72,7 @@ config IEEE1394_PCILYNX
# fi
config IEEE1394_OHCI1394
tristate "OHCI-1394 support"
depends on IEEE1394
depends on
PCI &&
IEEE1394
help
Enable this driver if you have an IEEE 1394 controller based on the
OHCI-1394 specification. The current driver is only tested with OHCI
...
...
@@ -80,7 +80,7 @@ config IEEE1394_OHCI1394
use one of these chipsets. It should work with any OHCI-1394
compliant card, however.
To compile this driver as a module,
choose
M here: the
To compile this driver as a module,
say
M here: the
module will be called ohci1394.
comment "Protocol Drivers"
...
...
@@ -122,7 +122,7 @@ config IEEE1394_DV1394
The user-space API for dv1394 is documented in dv1394.h.
To compile this driver as a module,
choose
M here: the
To compile this driver as a module,
say
M here: the
module will be called dv1394.
config IEEE1394_RAWIO
...
...
@@ -134,7 +134,7 @@ config IEEE1394_RAWIO
direct communication of user programs with the IEEE 1394 bus and
thus with the attached peripherals.
To compile this driver as a module,
choose
M here: the
To compile this driver as a module,
say
M here: the
module will be called raw1394.
config IEEE1394_CMP
...
...
@@ -144,7 +144,7 @@ config IEEE1394_CMP
This option enables the Connection Management Procedures
(IEC61883-1) driver, which implements input and output plugs.
To compile this driver as a module,
choose
M here: the
To compile this driver as a module,
say
M here: the
module will be called cmp.
config IEEE1394_AMDTP
...
...
@@ -157,7 +157,7 @@ config IEEE1394_AMDTP
The userspace interface is documented in amdtp.h.
To compile this driver as a module,
choose
M here: the
To compile this driver as a module,
say
M here: the
module will be called amdtp.
endmenu
drivers/ieee1394/eth1394.c
View file @
d412a4c3
...
...
@@ -89,7 +89,7 @@
#define TRACE() printk(KERN_ERR "%s:%s[%d] ---- TRACE\n", driver_name, __FUNCTION__, __LINE__)
static
char
version
[]
__devinitdata
=
"$Rev: 10
43
$ Ben Collins <bcollins@debian.org>"
;
"$Rev: 10
79
$ Ben Collins <bcollins@debian.org>"
;
struct
fragment_info
{
struct
list_head
list
;
...
...
@@ -220,7 +220,7 @@ static int ether1394_init_bc(struct net_device *dev)
priv
->
iso
=
hpsb_iso_recv_init
(
priv
->
host
,
16
*
4096
,
16
,
priv
->
broadcast_channel
,
1
,
ether1394_iso
);
HPSB_ISO_DMA_PACKET_PER_BUFFER
,
1
,
ether1394_iso
);
if
(
priv
->
iso
==
NULL
)
{
ETH1394_PRINT
(
KERN_ERR
,
dev
->
name
,
"failed to change broadcast "
...
...
@@ -475,7 +475,7 @@ static void ether1394_add_host (struct hpsb_host *host)
priv
->
broadcast_channel
=
host
->
csr
.
broadcast_channel
&
0x3f
;
priv
->
iso
=
hpsb_iso_recv_init
(
host
,
16
*
4096
,
16
,
priv
->
broadcast_channel
,
1
,
ether1394_iso
);
HPSB_ISO_DMA_PACKET_PER_BUFFER
,
1
,
ether1394_iso
);
if
(
priv
->
iso
==
NULL
)
{
priv
->
bc_state
=
ETHER1394_BC_CLOSED
;
}
...
...
@@ -1258,7 +1258,7 @@ static inline struct hpsb_packet *ether1394_alloc_common_packet(struct hpsb_host
{
struct
hpsb_packet
*
p
;
p
=
alloc_hpsb
_packet
(
0
);
p
=
hpsb_alloc
_packet
(
0
);
if
(
p
)
{
p
->
host
=
host
;
p
->
data
=
NULL
;
...
...
@@ -1327,7 +1327,7 @@ static inline void ether1394_free_packet(struct hpsb_packet *packet)
if
(
packet
->
tcode
!=
TCODE_STREAM_DATA
)
hpsb_free_tlabel
(
packet
);
packet
->
data
=
NULL
;
free_hpsb
_packet
(
packet
);
hpsb_free
_packet
(
packet
);
}
static
void
ether1394_complete_cb
(
void
*
__ptask
);
...
...
@@ -1349,7 +1349,7 @@ static int ether1394_send_packet(struct packet_task *ptask, unsigned int tx_len)
ptask
->
dest_node
,
ptask
->
addr
,
ptask
->
skb
->
data
,
tx_len
))
{
free_hpsb
_packet
(
packet
);
hpsb_free
_packet
(
packet
);
return
-
1
;
}
...
...
@@ -1357,7 +1357,7 @@ static int ether1394_send_packet(struct packet_task *ptask, unsigned int tx_len)
hpsb_set_packet_complete_task
(
ptask
->
packet
,
ether1394_complete_cb
,
ptask
);
if
(
!
hpsb_send_packet
(
packet
)
)
{
if
(
hpsb_send_packet
(
packet
)
<
0
)
{
ether1394_free_packet
(
packet
);
return
-
1
;
}
...
...
@@ -1599,7 +1599,7 @@ static int ether1394_ethtool_ioctl(struct net_device *dev, void *useraddr)
case
ETHTOOL_GDRVINFO
:
{
struct
ethtool_drvinfo
info
=
{
ETHTOOL_GDRVINFO
};
strcpy
(
info
.
driver
,
driver_name
);
strcpy
(
info
.
version
,
"$Rev: 10
43
$"
);
strcpy
(
info
.
version
,
"$Rev: 10
79
$"
);
/* FIXME XXX provide sane businfo */
strcpy
(
info
.
bus_info
,
"ieee1394"
);
if
(
copy_to_user
(
useraddr
,
&
info
,
sizeof
(
info
)))
...
...
drivers/ieee1394/highlevel.c
View file @
d412a4c3
...
...
@@ -26,6 +26,7 @@
#include "hosts.h"
#include "ieee1394_core.h"
#include "highlevel.h"
#include "nodemgr.h"
struct
hl_host_info
{
...
...
@@ -227,10 +228,17 @@ struct hpsb_host *hpsb_get_host_bykey(struct hpsb_highlevel *hl, unsigned long k
return
host
;
}
static
int
highlevel_for_each_host_reg
(
struct
hpsb_host
*
host
,
void
*
__data
)
{
struct
hpsb_highlevel
*
hl
=
__data
;
hl
->
add_host
(
host
);
return
0
;
}
void
hpsb_register_highlevel
(
struct
hpsb_highlevel
*
hl
)
{
struct
list_head
*
lh
;
unsigned
long
flags
;
INIT_LIST_HEAD
(
&
hl
->
addr_list
);
...
...
@@ -242,18 +250,22 @@ void hpsb_register_highlevel(struct hpsb_highlevel *hl)
list_add_tail
(
&
hl
->
hl_list
,
&
hl_drivers
);
write_unlock_irqrestore
(
&
hl_drivers_lock
,
flags
);
if
(
hl
->
add_host
)
{
down
(
&
hpsb_hosts_lock
);
list_for_each
(
lh
,
&
hpsb_hosts
)
{
struct
hpsb_host
*
host
=
list_entry
(
lh
,
struct
hpsb_host
,
host_list
);
hl
->
add_host
(
host
);
}
up
(
&
hpsb_hosts_lock
);
}
if
(
hl
->
add_host
)
nodemgr_for_each_host
(
hl
,
highlevel_for_each_host_reg
);
return
;
}
static
int
highlevel_for_each_host_unreg
(
struct
hpsb_host
*
host
,
void
*
__data
)
{
struct
hpsb_highlevel
*
hl
=
__data
;
hl
->
remove_host
(
host
);
hpsb_destroy_hostinfo
(
hl
,
host
);
return
0
;
}
void
hpsb_unregister_highlevel
(
struct
hpsb_highlevel
*
hl
)
{
struct
list_head
*
lh
,
*
next
;
...
...
@@ -272,16 +284,8 @@ void hpsb_unregister_highlevel(struct hpsb_highlevel *hl)
list_del
(
&
hl
->
hl_list
);
write_unlock_irqrestore
(
&
hl_drivers_lock
,
flags
);
if
(
hl
->
remove_host
)
{
down
(
&
hpsb_hosts_lock
);
list_for_each
(
lh
,
&
hpsb_hosts
)
{
struct
hpsb_host
*
host
=
list_entry
(
lh
,
struct
hpsb_host
,
host_list
);
hl
->
remove_host
(
host
);
hpsb_destroy_hostinfo
(
hl
,
host
);
}
up
(
&
hpsb_hosts_lock
);
}
if
(
hl
->
remove_host
)
nodemgr_for_each_host
(
hl
,
highlevel_for_each_host_unreg
);
}
int
hpsb_register_addrspace
(
struct
hpsb_highlevel
*
hl
,
...
...
drivers/ieee1394/highlevel.h
View file @
d412a4c3
...
...
@@ -92,8 +92,6 @@ struct hpsb_address_ops {
};
void
init_hpsb_highlevel
(
void
);
void
highlevel_add_host
(
struct
hpsb_host
*
host
);
void
highlevel_remove_host
(
struct
hpsb_host
*
host
);
void
highlevel_host_reset
(
struct
hpsb_host
*
host
);
...
...
@@ -180,4 +178,7 @@ int hpsb_set_hostinfo(struct hpsb_highlevel *hl, struct hpsb_host *host, void *d
/* Retrieve hpsb_host using a highlevel handle and a key */
struct
hpsb_host
*
hpsb_get_host_bykey
(
struct
hpsb_highlevel
*
hl
,
unsigned
long
key
);
/* Initialize the highlevel system */
void
init_hpsb_highlevel
(
void
);
#endif
/* IEEE1394_HIGHLEVEL_H */
drivers/ieee1394/hosts.c
View file @
d412a4c3
...
...
@@ -16,14 +16,14 @@
#include <linux/list.h>
#include <linux/init.h>
#include <linux/slab.h>
#include <linux/pci.h>
#include "ieee1394_types.h"
#include "hosts.h"
#include "ieee1394_core.h"
#include "highlevel.h"
#include "nodemgr.h"
LIST_HEAD
(
hpsb_hosts
);
DECLARE_MUTEX
(
hpsb_hosts_lock
);
static
int
dummy_transmit_packet
(
struct
hpsb_host
*
h
,
struct
hpsb_packet
*
p
)
{
...
...
@@ -46,54 +46,14 @@ static struct hpsb_host_driver dummy_driver = {
.
isoctl
=
dummy_isoctl
};
/**
* hpsb_ref_host - increase reference count for host controller.
* @host: the host controller
*
* Increase the reference count for the specified host controller.
* When holding a reference to a host, the memory allocated for the
* host struct will not be freed and the host is guaranteed to be in a
* consistent state. The driver may be unloaded or the controller may
* be removed (PCMCIA), but the host struct will remain valid.
*/
int
hpsb_ref_host
(
struct
hpsb_host
*
host
)
static
int
alloc_hostnum_cb
(
struct
hpsb_host
*
host
,
void
*
__data
)
{
struct
list_head
*
lh
;
int
retval
=
0
;
down
(
&
hpsb_hosts_lock
);
list_for_each
(
lh
,
&
hpsb_hosts
)
{
if
(
host
==
list_entry
(
lh
,
struct
hpsb_host
,
host_list
))
{
if
(
try_module_get
(
host
->
driver
->
owner
))
{
atomic_inc
(
&
host
->
refcount
);
retval
=
1
;
}
break
;
}
}
up
(
&
hpsb_hosts_lock
);
return
retval
;
}
int
*
hostnum
=
__data
;
/**
* hpsb_unref_host - decrease reference count for host controller.
* @host: the host controller
*
* Decrease the reference count for the specified host controller.
* When the reference count reaches zero, the memory allocated for the
* &hpsb_host will be freed.
*/
if
(
host
->
id
==
*
hostnum
)
return
1
;
void
hpsb_unref_host
(
struct
hpsb_host
*
host
)
{
module_put
(
host
->
driver
->
owner
);
down
(
&
hpsb_hosts_lock
);
if
(
atomic_dec_and_test
(
&
host
->
refcount
)
&&
host
->
is_shutdown
)
device_unregister
(
&
host
->
device
);
up
(
&
hpsb_hosts_lock
);
return
0
;
}
/**
...
...
@@ -108,19 +68,16 @@ void hpsb_unref_host(struct hpsb_host *host)
* driver specific parts, enable the controller and make it available
* to the general subsystem using hpsb_add_host().
*
* The &hpsb_host is allocated with an single initial reference
* belonging to the driver. Once the driver is done with the struct,
* for example, when the driver is unloaded, it should release this
* reference using hpsb_unref_host().
*
* Return Value: a pointer to the &hpsb_host if succesful, %NULL if
* no memory was available.
*/
struct
hpsb_host
*
hpsb_alloc_host
(
struct
hpsb_host_driver
*
drv
,
size_t
extra
)
struct
hpsb_host
*
hpsb_alloc_host
(
struct
hpsb_host_driver
*
drv
,
size_t
extra
,
struct
device
*
dev
)
{
struct
hpsb_host
*
h
;
int
i
;
int
hostnum
=
0
;
h
=
kmalloc
(
sizeof
(
struct
hpsb_host
)
+
extra
,
SLAB_KERNEL
);
if
(
!
h
)
return
NULL
;
...
...
@@ -128,7 +85,6 @@ struct hpsb_host *hpsb_alloc_host(struct hpsb_host_driver *drv, size_t extra)
h
->
hostdata
=
h
+
1
;
h
->
driver
=
drv
;
atomic_set
(
&
h
->
refcount
,
1
);
INIT_LIST_HEAD
(
&
h
->
pending_packets
);
spin_lock_init
(
&
h
->
pending_pkt_lock
);
...
...
@@ -146,53 +102,35 @@ struct hpsb_host *hpsb_alloc_host(struct hpsb_host_driver *drv, size_t extra)
h
->
topology_map
=
h
->
csr
.
topology_map
+
3
;
h
->
speed_map
=
(
u8
*
)(
h
->
csr
.
speed_map
+
2
);
return
h
;
}
static
int
alloc_hostnum
(
void
)
{
int
hostnum
=
0
;
while
(
1
)
{
struct
list_head
*
lh
;
int
found
=
0
;
list_for_each
(
lh
,
&
hpsb_hosts
)
{
struct
hpsb_host
*
host
=
list_entry
(
lh
,
struct
hpsb_host
,
host_list
);
if
(
host
->
id
==
hostnum
)
{
found
=
1
;
if
(
!
nodemgr_for_each_host
(
&
hostnum
,
alloc_hostnum_cb
))
{
h
->
id
=
hostnum
;
break
;
}
}
if
(
!
found
)
return
hostnum
;
hostnum
++
;
}
return
0
;
memcpy
(
&
h
->
device
,
&
nodemgr_dev_template_host
,
sizeof
(
h
->
device
));
h
->
device
.
parent
=
dev
;
snprintf
(
h
->
device
.
bus_id
,
BUS_ID_SIZE
,
"fw-host%d"
,
h
->
id
);
device_register
(
&
h
->
device
);
return
h
;
}
void
hpsb_add_host
(
struct
hpsb_host
*
host
)
{
down
(
&
hpsb_hosts_lock
);
host
->
id
=
alloc_hostnum
();
list_add_tail
(
&
host
->
host_list
,
&
hpsb_hosts
);
up
(
&
hpsb_hosts_lock
);
highlevel_add_host
(
host
);
host
->
driver
->
devctl
(
host
,
RESET_BUS
,
LONG_RESET
);
}
void
hpsb_remove_host
(
struct
hpsb_host
*
host
)
{
down
(
&
hpsb_hosts_lock
);
host
->
is_shutdown
=
1
;
host
->
driver
=
&
dummy_driver
;
list_del
(
&
host
->
host_list
);
up
(
&
hpsb_hosts_lock
);
highlevel_remove_host
(
host
);
device_unregister
(
&
host
->
device
);
}
drivers/ieee1394/hosts.h
View file @
d412a4c3
...
...
@@ -29,8 +29,6 @@ struct hpsb_host {
atomic_t
generation
;
atomic_t
refcount
;
struct
list_head
pending_packets
;
spinlock_t
pending_pkt_lock
;
struct
timer_list
timeout
;
...
...
@@ -165,7 +163,7 @@ struct hpsb_host_driver {
* packet->type == raw) and do byte-swapping as necessary or instruct
* the hardware to do so. It can return immediately after the packet
* was queued for sending. After sending, hpsb_sent_packet() has to be
* called. Return 0
for
failure.
* called. Return 0
on success, negative errno on
failure.
* NOTE: The function must be callable in interrupt context.
*/
int
(
*
transmit_packet
)
(
struct
hpsb_host
*
host
,
...
...
@@ -195,22 +193,8 @@ struct hpsb_host_driver {
};
extern
struct
list_head
hpsb_hosts
;
extern
struct
semaphore
hpsb_hosts_lock
;
/*
* In order to prevent hosts from unloading, use hpsb_ref_host(). This prevents
* the host from going away (e.g. makes module unloading of the driver
* impossible), but still can not guarantee it (e.g. PC-Card being pulled by the
* user). hpsb_ref_host() returns false if host could not be locked. If it is
* successful, host is valid as a pointer until hpsb_unref_host() (not just
* until after remove_host).
*/
int
hpsb_ref_host
(
struct
hpsb_host
*
host
);
void
hpsb_unref_host
(
struct
hpsb_host
*
host
);
struct
hpsb_host
*
hpsb_alloc_host
(
struct
hpsb_host_driver
*
drv
,
size_t
extra
);
struct
hpsb_host
*
hpsb_alloc_host
(
struct
hpsb_host_driver
*
drv
,
size_t
extra
,
struct
device
*
dev
);
void
hpsb_add_host
(
struct
hpsb_host
*
host
);
void
hpsb_remove_host
(
struct
hpsb_host
*
h
);
...
...
drivers/ieee1394/ieee1394_core.c
View file @
d412a4c3
...
...
@@ -109,7 +109,7 @@ void hpsb_set_packet_complete_task(struct hpsb_packet *packet,
}
/**
*
alloc_hpsb
_packet - allocate new packet structure
*
hpsb_alloc
_packet - allocate new packet structure
* @data_size: size of the data block to be allocated
*
* This function allocates, initializes and returns a new &struct hpsb_packet.
...
...
@@ -128,7 +128,7 @@ void hpsb_set_packet_complete_task(struct hpsb_packet *packet,
* Return value: A pointer to a &struct hpsb_packet or NULL on allocation
* failure.
*/
struct
hpsb_packet
*
alloc_hpsb
_packet
(
size_t
data_size
)
struct
hpsb_packet
*
hpsb_alloc
_packet
(
size_t
data_size
)
{
struct
hpsb_packet
*
packet
=
NULL
;
void
*
data
=
NULL
;
...
...
@@ -152,25 +152,23 @@ struct hpsb_packet *alloc_hpsb_packet(size_t data_size)
}
INIT_LIST_HEAD
(
&
packet
->
list
);
sema_init
(
&
packet
->
state_change
,
0
);
packet
->
complete_routine
=
NULL
;
packet
->
complete_data
=
NULL
;
packet
->
state
=
hpsb_unused
;
packet
->
generation
=
-
1
;
packet
->
data_be
=
1
;
return
packet
;
}
/**
*
free_hpsb
_packet - free packet and data associated with it
*
hpsb_free
_packet - free packet and data associated with it
* @packet: packet to free (is NULL safe)
*
* This function will free packet->data, packet->header and finally the packet
* itself.
*/
void
free_hpsb
_packet
(
struct
hpsb_packet
*
packet
)
void
hpsb_free
_packet
(
struct
hpsb_packet
*
packet
)
{
if
(
!
packet
)
return
;
...
...
@@ -420,14 +418,12 @@ void hpsb_packet_sent(struct hpsb_host *host, struct hpsb_packet *packet,
if
(
packet
->
no_waiter
)
{
/* must not have a tlabel allocated */
free_hpsb
_packet
(
packet
);
hpsb_free
_packet
(
packet
);
return
;
}
if
(
ackcode
!=
ACK_PENDING
||
!
packet
->
expect_response
)
{
packet
->
state
=
hpsb_complete
;
up
(
&
packet
->
state_change
);
up
(
&
packet
->
state_change
);
run_packet_complete
(
packet
);
return
;
}
...
...
@@ -439,7 +435,6 @@ void hpsb_packet_sent(struct hpsb_host *host, struct hpsb_packet *packet,
list_add_tail
(
&
packet
->
list
,
&
host
->
pending_packets
);
spin_unlock_irqrestore
(
&
host
->
pending_pkt_lock
,
flags
);
up
(
&
packet
->
state_change
);
mod_timer
(
&
host
->
timeout
,
jiffies
+
host
->
timeout_interval
);
}
...
...
@@ -465,7 +460,7 @@ int hpsb_send_phy_config(struct hpsb_host *host, int rootid, int gapcnt)
return
-
EINVAL
;
}
packet
=
alloc_hpsb
_packet
(
0
);
packet
=
hpsb_alloc
_packet
(
0
);
if
(
!
packet
)
return
-
ENOMEM
;
...
...
@@ -485,16 +480,8 @@ int hpsb_send_phy_config(struct hpsb_host *host, int rootid, int gapcnt)
packet
->
generation
=
get_hpsb_generation
(
host
);
if
(
!
hpsb_send_packet
(
packet
))
{
retval
=
-
EINVAL
;
goto
fail
;
}
down
(
&
packet
->
state_change
);
down
(
&
packet
->
state_change
);
fail:
free_hpsb_packet
(
packet
);
retval
=
hpsb_send_packet_and_wait
(
packet
);
hpsb_free_packet
(
packet
);
return
retval
;
}
...
...
@@ -504,23 +491,24 @@ int hpsb_send_phy_config(struct hpsb_host *host, int rootid, int gapcnt)
* @packet: packet to send
*
* The packet is sent through the host specified in the packet->host field.
* Before sending, the packet's transmit speed is automatically determined
using
* the local speed map when it is an async, non-broadcast packet.
* Before sending, the packet's transmit speed is automatically determined
*
using
the local speed map when it is an async, non-broadcast packet.
*
* Possibilities for failure are that host is either not initialized, in bus
* reset, the packet's generation number doesn't match the current generation
* number or the host reports a transmit error.
*
* Return value:
False (0) on failure, true (1) otherwis
e.
* Return value:
0 on success, negative errno on failur
e.
*/
int
hpsb_send_packet
(
struct
hpsb_packet
*
packet
)
{
struct
hpsb_host
*
host
=
packet
->
host
;
if
(
host
->
is_shutdown
||
host
->
in_bus_reset
||
(
packet
->
generation
!=
get_hpsb_generation
(
host
)))
{
return
0
;
}
if
(
host
->
is_shutdown
)
return
-
EINVAL
;
if
(
host
->
in_bus_reset
||
(
packet
->
generation
!=
get_hpsb_generation
(
host
)))
return
-
EAGAIN
;
packet
->
state
=
hpsb_queued
;
...
...
@@ -532,23 +520,13 @@ int hpsb_send_packet(struct hpsb_packet *packet)
data
=
kmalloc
(
packet
->
header_size
+
packet
->
data_size
,
GFP_ATOMIC
);
if
(
!
data
)
{
HPSB_ERR
(
"unable to allocate memory for concatenating header and data"
);
return
0
;
return
-
ENOMEM
;
}
memcpy
(
data
,
packet
->
header
,
packet
->
header_size
);
if
(
packet
->
data_size
)
{
if
(
packet
->
data_be
)
{
memcpy
(((
u8
*
)
data
)
+
packet
->
header_size
,
packet
->
data
,
packet
->
data_size
);
}
else
{
int
i
;
quadlet_t
*
my_data
=
(
quadlet_t
*
)
((
u8
*
)
data
+
packet
->
data_size
);
for
(
i
=
0
;
i
<
packet
->
data_size
/
4
;
i
++
)
{
my_data
[
i
]
=
cpu_to_be32
(
packet
->
data
[
i
]);
}
}
}
dump_packet
(
"send packet local:"
,
packet
->
header
,
packet
->
header_size
);
...
...
@@ -558,7 +536,7 @@ int hpsb_send_packet(struct hpsb_packet *packet)
kfree
(
data
);
return
1
;
return
0
;
}
if
(
packet
->
type
==
hpsb_async
&&
packet
->
node_id
!=
ALL_NODES
)
{
...
...
@@ -584,10 +562,33 @@ int hpsb_send_packet(struct hpsb_packet *packet)
return
host
->
driver
->
transmit_packet
(
host
,
packet
);
}
/* We could just use complete() directly as the packet complete
* callback, but this is more typesafe, in the sense that we get a
* compiler error if the prototype for complete() changes. */
static
void
complete_packet
(
void
*
data
)
{
complete
((
struct
completion
*
)
data
);
}
int
hpsb_send_packet_and_wait
(
struct
hpsb_packet
*
packet
)
{
struct
completion
done
;
int
retval
;
init_completion
(
&
done
);
hpsb_set_packet_complete_task
(
packet
,
complete_packet
,
&
done
);
retval
=
hpsb_send_packet
(
packet
);
if
(
retval
==
0
)
wait_for_completion
(
&
done
);
return
retval
;
}
static
void
send_packet_nocare
(
struct
hpsb_packet
*
packet
)
{
if
(
!
hpsb_send_packet
(
packet
)
)
{
free_hpsb
_packet
(
packet
);
if
(
hpsb_send_packet
(
packet
)
<
0
)
{
hpsb_free
_packet
(
packet
);
}
}
...
...
@@ -668,7 +669,6 @@ void handle_packet_response(struct hpsb_host *host, int tcode, quadlet_t *data,
}
packet
->
state
=
hpsb_complete
;
up
(
&
packet
->
state_change
);
run_packet_complete
(
packet
);
}
...
...
@@ -680,7 +680,7 @@ static struct hpsb_packet *create_reply_packet(struct hpsb_host *host,
dsize
+=
(
dsize
%
4
?
4
-
(
dsize
%
4
)
:
0
);
p
=
alloc_hpsb
_packet
(
dsize
);
p
=
hpsb_alloc
_packet
(
dsize
);
if
(
p
==
NULL
)
{
/* FIXME - send data_error response */
return
NULL
;
...
...
@@ -820,6 +820,8 @@ static void handle_incoming_packet(struct hpsb_host *host, int tcode,
if
(
rcode
>=
0
)
{
fill_async_readblock_resp
(
packet
,
rcode
,
length
);
send_packet_nocare
(
packet
);
}
else
{
hpsb_free_packet
(
packet
);
}
break
;
...
...
@@ -874,7 +876,7 @@ static void handle_incoming_packet(struct hpsb_host *host, int tcode,
if
(
rcode
>=
0
)
{
send_packet_nocare
(
packet
);
}
else
{
free_hpsb
_packet
(
packet
);
hpsb_free
_packet
(
packet
);
}
break
;
}
...
...
@@ -949,7 +951,6 @@ void abort_requests(struct hpsb_host *host)
list_del
(
&
packet
->
list
);
packet
->
state
=
hpsb_complete
;
packet
->
ack_code
=
ACKX_ABORTED
;
up
(
&
packet
->
state_change
);
run_packet_complete
(
packet
);
}
}
...
...
@@ -987,7 +988,6 @@ void abort_timedouts(unsigned long __opaque)
list_del
(
&
packet
->
list
);
packet
->
state
=
hpsb_complete
;
packet
->
ack_code
=
ACKX_TIMEOUT
;
up
(
&
packet
->
state_change
);
run_packet_complete
(
packet
);
}
}
...
...
@@ -1171,19 +1171,22 @@ static int ieee1394_dispatch_open(struct inode *inode, struct file *file)
static
int
__init
ieee1394_init
(
void
)
{
hpsb_packet_cache
=
kmem_cache_create
(
"hpsb_packet"
,
sizeof
(
struct
hpsb_packet
),
0
,
0
,
NULL
,
NULL
);
devfs_mk_dir
(
"ieee1394"
);
if
(
register_chrdev
(
IEEE1394_MAJOR
,
"ieee1394"
,
&
ieee1394_chardev_ops
))
{
HPSB_ERR
(
"unable to register character device major %d!
\n
"
,
IEEE1394_MAJOR
);
devfs_remove
(
"ieee1394"
);
return
-
ENODEV
;
}
devfs_mk_dir
(
"ieee1394"
);
hpsb_packet_cache
=
kmem_cache_create
(
"hpsb_packet"
,
sizeof
(
struct
hpsb_packet
),
0
,
0
,
NULL
,
NULL
);
bus_register
(
&
ieee1394_bus_type
);
init_hpsb_highlevel
();
init_csr
();
if
(
!
disable_nodemgr
)
init_ieee1394_nodemgr
();
else
...
...
@@ -1198,6 +1201,9 @@ static void __exit ieee1394_cleanup(void)
cleanup_ieee1394_nodemgr
();
cleanup_csr
();
bus_unregister
(
&
ieee1394_bus_type
);
kmem_cache_destroy
(
hpsb_packet_cache
);
unregister_chrdev
(
IEEE1394_MAJOR
,
"ieee1394"
);
...
...
@@ -1213,16 +1219,15 @@ module_exit(ieee1394_cleanup);
EXPORT_SYMBOL
(
hpsb_alloc_host
);
EXPORT_SYMBOL
(
hpsb_add_host
);
EXPORT_SYMBOL
(
hpsb_remove_host
);
EXPORT_SYMBOL
(
hpsb_ref_host
);
EXPORT_SYMBOL
(
hpsb_unref_host
);
/** ieee1394_core.c **/
EXPORT_SYMBOL
(
hpsb_speedto_str
);
EXPORT_SYMBOL
(
hpsb_set_packet_complete_task
);
EXPORT_SYMBOL
(
alloc_hpsb
_packet
);
EXPORT_SYMBOL
(
free_hpsb
_packet
);
EXPORT_SYMBOL
(
hpsb_alloc
_packet
);
EXPORT_SYMBOL
(
hpsb_free
_packet
);
EXPORT_SYMBOL
(
hpsb_send_phy_config
);
EXPORT_SYMBOL
(
hpsb_send_packet
);
EXPORT_SYMBOL
(
hpsb_send_packet_and_wait
);
EXPORT_SYMBOL
(
hpsb_reset_bus
);
EXPORT_SYMBOL
(
hpsb_bus_reset
);
EXPORT_SYMBOL
(
hpsb_selfid_received
);
...
...
@@ -1282,6 +1287,7 @@ EXPORT_SYMBOL(hpsb_node_lock);
EXPORT_SYMBOL
(
hpsb_register_protocol
);
EXPORT_SYMBOL
(
hpsb_unregister_protocol
);
EXPORT_SYMBOL
(
ieee1394_bus_type
);
EXPORT_SYMBOL
(
nodemgr_for_each_host
);
/** csr.c **/
EXPORT_SYMBOL
(
hpsb_update_config_rom
);
...
...
drivers/ieee1394/ieee1394_core.h
View file @
d412a4c3
...
...
@@ -40,11 +40,6 @@ struct hpsb_packet {
unsigned
expect_response
:
1
;
unsigned
no_waiter
:
1
;
/* Data big endianness flag - may vary from request to request. The
* header is always in machine byte order.
* Not really used currently. */
unsigned
data_be
:
1
;
/* Speed to transmit with: 0 = 100Mbps, 1 = 200Mbps, 2 = 400Mbps */
unsigned
speed_code
:
2
;
...
...
@@ -64,9 +59,6 @@ struct hpsb_packet {
struct
hpsb_host
*
host
;
unsigned
int
generation
;
/* Very core internal, don't care. */
struct
semaphore
state_change
;
/* Function (and possible data to pass to it) to call when this
* packet is completed. */
void
(
*
complete_routine
)(
void
*
);
...
...
@@ -90,8 +82,8 @@ static inline struct hpsb_packet *driver_packet(struct list_head *l)
void
abort_timedouts
(
unsigned
long
__opaque
);
void
abort_requests
(
struct
hpsb_host
*
host
);
struct
hpsb_packet
*
alloc_hpsb
_packet
(
size_t
data_size
);
void
free_hpsb
_packet
(
struct
hpsb_packet
*
packet
);
struct
hpsb_packet
*
hpsb_alloc
_packet
(
size_t
data_size
);
void
hpsb_free
_packet
(
struct
hpsb_packet
*
packet
);
/*
...
...
@@ -108,15 +100,23 @@ static inline unsigned int get_hpsb_generation(struct hpsb_host *host)
}
/*
* Send a PHY configuration packet.
* Send a PHY configuration packet, return 0 on success, negative
* errno on failure.
*/
int
hpsb_send_phy_config
(
struct
hpsb_host
*
host
,
int
rootid
,
int
gapcnt
);
/*
* Queue packet for transmitting, return 0 for failure.
* Queue packet for transmitting, return 0 on success, negative errno
* on failure.
*/
int
hpsb_send_packet
(
struct
hpsb_packet
*
packet
);
/*
* Queue packet for transmitting, and block until the transaction
* completes. Return 0 on success, negative errno on failure.
*/
int
hpsb_send_packet_and_wait
(
struct
hpsb_packet
*
packet
);
/* Initiate bus reset on the given host. Returns 1 if bus reset already in
* progress, 0 otherwise. */
int
hpsb_reset_bus
(
struct
hpsb_host
*
host
,
int
type
);
...
...
drivers/ieee1394/ieee1394_transactions.c
View file @
d412a4c3
...
...
@@ -263,7 +263,7 @@ struct hpsb_packet *hpsb_make_readpacket(struct hpsb_host *host, nodeid_t node,
if
(
length
==
0
)
return
NULL
;
packet
=
alloc_hpsb
_packet
(
length
+
(
length
%
4
?
4
-
(
length
%
4
)
:
0
));
packet
=
hpsb_alloc
_packet
(
length
+
(
length
%
4
?
4
-
(
length
%
4
)
:
0
));
if
(
!
packet
)
return
NULL
;
...
...
@@ -271,7 +271,7 @@ struct hpsb_packet *hpsb_make_readpacket(struct hpsb_host *host, nodeid_t node,
packet
->
node_id
=
node
;
if
(
hpsb_get_tlabel
(
packet
))
{
free_hpsb
_packet
(
packet
);
hpsb_free
_packet
(
packet
);
return
NULL
;
}
...
...
@@ -291,7 +291,7 @@ struct hpsb_packet *hpsb_make_writepacket (struct hpsb_host *host, nodeid_t node
if
(
length
==
0
)
return
NULL
;
packet
=
alloc_hpsb
_packet
(
length
+
(
length
%
4
?
4
-
(
length
%
4
)
:
0
));
packet
=
hpsb_alloc
_packet
(
length
+
(
length
%
4
?
4
-
(
length
%
4
)
:
0
));
if
(
!
packet
)
return
NULL
;
...
...
@@ -302,7 +302,7 @@ struct hpsb_packet *hpsb_make_writepacket (struct hpsb_host *host, nodeid_t node
packet
->
node_id
=
node
;
if
(
hpsb_get_tlabel
(
packet
))
{
free_hpsb
_packet
(
packet
);
hpsb_free
_packet
(
packet
);
return
NULL
;
}
...
...
@@ -325,7 +325,7 @@ struct hpsb_packet *hpsb_make_streampacket(struct hpsb_host *host, u8 *buffer, i
if
(
length
==
0
)
return
NULL
;
packet
=
alloc_hpsb
_packet
(
length
+
(
length
%
4
?
4
-
(
length
%
4
)
:
0
));
packet
=
hpsb_alloc
_packet
(
length
+
(
length
%
4
?
4
-
(
length
%
4
)
:
0
));
if
(
!
packet
)
return
NULL
;
...
...
@@ -335,7 +335,7 @@ struct hpsb_packet *hpsb_make_streampacket(struct hpsb_host *host, u8 *buffer, i
packet
->
host
=
host
;
if
(
hpsb_get_tlabel
(
packet
))
{
free_hpsb
_packet
(
packet
);
hpsb_free
_packet
(
packet
);
return
NULL
;
}
...
...
@@ -353,13 +353,13 @@ struct hpsb_packet *hpsb_make_lockpacket(struct hpsb_host *host, nodeid_t node,
struct
hpsb_packet
*
p
;
u32
length
;
p
=
alloc_hpsb
_packet
(
8
);
p
=
hpsb_alloc
_packet
(
8
);
if
(
!
p
)
return
NULL
;
p
->
host
=
host
;
p
->
node_id
=
node
;
if
(
hpsb_get_tlabel
(
p
))
{
free_hpsb
_packet
(
p
);
hpsb_free
_packet
(
p
);
return
NULL
;
}
...
...
@@ -390,13 +390,13 @@ struct hpsb_packet *hpsb_make_lock64packet(struct hpsb_host *host, nodeid_t node
struct
hpsb_packet
*
p
;
u32
length
;
p
=
alloc_hpsb
_packet
(
16
);
p
=
hpsb_alloc
_packet
(
16
);
if
(
!
p
)
return
NULL
;
p
->
host
=
host
;
p
->
node_id
=
node
;
if
(
hpsb_get_tlabel
(
p
))
{
free_hpsb
_packet
(
p
);
hpsb_free
_packet
(
p
);
return
NULL
;
}
...
...
@@ -429,7 +429,7 @@ struct hpsb_packet *hpsb_make_phypacket(struct hpsb_host *host,
{
struct
hpsb_packet
*
p
;
p
=
alloc_hpsb
_packet
(
0
);
p
=
hpsb_alloc
_packet
(
0
);
if
(
!
p
)
return
NULL
;
p
->
host
=
host
;
...
...
@@ -444,7 +444,7 @@ struct hpsb_packet *hpsb_make_isopacket(struct hpsb_host *host,
{
struct
hpsb_packet
*
p
;
p
=
alloc_hpsb
_packet
(
length
);
p
=
hpsb_alloc
_packet
(
length
);
if
(
!
p
)
return
NULL
;
p
->
host
=
host
;
...
...
@@ -478,13 +478,10 @@ int hpsb_read(struct hpsb_host *host, nodeid_t node, unsigned int generation,
}
packet
->
generation
=
generation
;
if
(
!
hpsb_send_packet
(
packet
))
{
retval
=
-
EINVAL
;
retval
=
hpsb_send_packet_and_wait
(
packet
);
if
(
retval
<
0
)
goto
hpsb_read_fail
;
}
down
(
&
packet
->
state_change
);
down
(
&
packet
->
state_change
);
retval
=
hpsb_packet_success
(
packet
);
if
(
retval
==
0
)
{
...
...
@@ -497,7 +494,7 @@ int hpsb_read(struct hpsb_host *host, nodeid_t node, unsigned int generation,
hpsb_read_fail:
hpsb_free_tlabel
(
packet
);
free_hpsb
_packet
(
packet
);
hpsb_free
_packet
(
packet
);
return
retval
;
}
...
...
@@ -520,18 +517,15 @@ int hpsb_write(struct hpsb_host *host, nodeid_t node, unsigned int generation,
return
-
ENOMEM
;
packet
->
generation
=
generation
;
if
(
!
hpsb_send_packet
(
packet
))
{
retval
=
-
EINVAL
;
retval
=
hpsb_send_packet_and_wait
(
packet
);
if
(
retval
<
0
)
goto
hpsb_write_fail
;
}
down
(
&
packet
->
state_change
);
down
(
&
packet
->
state_change
);
retval
=
hpsb_packet_success
(
packet
);
hpsb_write_fail:
hpsb_free_tlabel
(
packet
);
free_hpsb
_packet
(
packet
);
hpsb_free
_packet
(
packet
);
return
retval
;
}
...
...
@@ -550,12 +544,10 @@ int hpsb_lock(struct hpsb_host *host, nodeid_t node, unsigned int generation,
return
-
ENOMEM
;
packet
->
generation
=
generation
;
if
(
!
hpsb_send_packet
(
packet
))
{
retval
=
-
EINVAL
;
retval
=
hpsb_send_packet_and_wait
(
packet
);
if
(
retval
<
0
)
goto
hpsb_lock_fail
;
}
down
(
&
packet
->
state_change
);
down
(
&
packet
->
state_change
);
retval
=
hpsb_packet_success
(
packet
);
if
(
retval
==
0
)
{
...
...
@@ -564,7 +556,7 @@ int hpsb_lock(struct hpsb_host *host, nodeid_t node, unsigned int generation,
hpsb_lock_fail:
hpsb_free_tlabel
(
packet
);
free_hpsb
_packet
(
packet
);
hpsb_free
_packet
(
packet
);
return
retval
;
}
...
...
@@ -582,12 +574,10 @@ int hpsb_lock64(struct hpsb_host *host, nodeid_t node, unsigned int generation,
return
-
ENOMEM
;
packet
->
generation
=
generation
;
if
(
!
hpsb_send_packet
(
packet
))
{
retval
=
-
EINVAL
;
retval
=
hpsb_send_packet_and_wait
(
packet
);
if
(
retval
<
0
)
goto
hpsb_lock64_fail
;
}
down
(
&
packet
->
state_change
);
down
(
&
packet
->
state_change
);
retval
=
hpsb_packet_success
(
packet
);
if
(
retval
==
0
)
...
...
@@ -595,7 +585,7 @@ int hpsb_lock64(struct hpsb_host *host, nodeid_t node, unsigned int generation,
hpsb_lock64_fail:
hpsb_free_tlabel
(
packet
);
free_hpsb
_packet
(
packet
);
hpsb_free
_packet
(
packet
);
return
retval
;
}
...
...
@@ -626,10 +616,9 @@ int hpsb_send_gasp(struct hpsb_host *host, int channel, unsigned int generation,
packet
->
no_waiter
=
1
;
if
(
!
hpsb_send_packet
(
packet
))
{
free_hpsb_packet
(
packet
);
retval
=
-
EINVAL
;
}
retval
=
hpsb_send_packet
(
packet
);
if
(
retval
<
0
)
hpsb_free_packet
(
packet
);
return
retval
;
}
drivers/ieee1394/iso.c
View file @
d412a4c3
...
...
@@ -40,6 +40,7 @@ static struct hpsb_iso* hpsb_iso_common_init(struct hpsb_host *host, enum hpsb_i
unsigned
int
data_buf_size
,
unsigned
int
buf_packets
,
int
channel
,
int
dma_mode
,
int
irq_interval
,
void
(
*
callback
)(
struct
hpsb_iso
*
))
{
...
...
@@ -58,8 +59,13 @@ static struct hpsb_iso* hpsb_iso_common_init(struct hpsb_host *host, enum hpsb_i
if
(
buf_packets
<
2
)
buf_packets
=
2
;
if
(
irq_interval
<
1
||
irq_interval
>
buf_packets
/
2
)
irq_interval
=
buf_packets
/
2
;
if
((
dma_mode
<
HPSB_ISO_DMA_DEFAULT
)
||
(
dma_mode
>
HPSB_ISO_DMA_PACKET_PER_BUFFER
))
dma_mode
=
HPSB_ISO_DMA_DEFAULT
;
if
(
irq_interval
==
0
)
/* really interrupt for each packet*/
irq_interval
=
1
;
else
if
((
irq_interval
<
0
)
||
(
irq_interval
>
buf_packets
/
4
))
irq_interval
=
buf_packets
/
4
;
if
(
channel
<
-
1
||
channel
>=
64
)
return
NULL
;
...
...
@@ -83,6 +89,7 @@ static struct hpsb_iso* hpsb_iso_common_init(struct hpsb_host *host, enum hpsb_i
init_waitqueue_head
(
&
iso
->
waitq
);
iso
->
channel
=
channel
;
iso
->
irq_interval
=
irq_interval
;
iso
->
dma_mode
=
dma_mode
;
dma_region_init
(
&
iso
->
data_buf
);
iso
->
buf_size
=
round_up_to_page
(
data_buf_size
);
iso
->
buf_packets
=
buf_packets
;
...
...
@@ -136,7 +143,7 @@ struct hpsb_iso* hpsb_iso_xmit_init(struct hpsb_host *host,
{
struct
hpsb_iso
*
iso
=
hpsb_iso_common_init
(
host
,
HPSB_ISO_XMIT
,
data_buf_size
,
buf_packets
,
channel
,
irq_interval
,
callback
);
channel
,
HPSB_ISO_DMA_DEFAULT
,
irq_interval
,
callback
);
if
(
!
iso
)
return
NULL
;
...
...
@@ -158,12 +165,13 @@ struct hpsb_iso* hpsb_iso_recv_init(struct hpsb_host *host,
unsigned
int
data_buf_size
,
unsigned
int
buf_packets
,
int
channel
,
int
dma_mode
,
int
irq_interval
,
void
(
*
callback
)(
struct
hpsb_iso
*
))
{
struct
hpsb_iso
*
iso
=
hpsb_iso_common_init
(
host
,
HPSB_ISO_RECV
,
data_buf_size
,
buf_packets
,
channel
,
irq_interval
,
callback
);
channel
,
dma_mode
,
irq_interval
,
callback
);
if
(
!
iso
)
return
NULL
;
...
...
drivers/ieee1394/iso.h
View file @
d412a4c3
...
...
@@ -51,6 +51,14 @@ struct hpsb_iso_packet_info {
enum
hpsb_iso_type
{
HPSB_ISO_RECV
=
0
,
HPSB_ISO_XMIT
=
1
};
/* The mode of the dma when receiving iso data. Must be supported by chip */
enum
raw1394_iso_dma_recv_mode
{
HPSB_ISO_DMA_DEFAULT
=
-
1
,
HPSB_ISO_DMA_OLD_ABI
=
0
,
HPSB_ISO_DMA_BUFFERFILL
=
1
,
HPSB_ISO_DMA_PACKET_PER_BUFFER
=
2
};
struct
hpsb_iso
{
enum
hpsb_iso_type
type
;
...
...
@@ -68,6 +76,8 @@ struct hpsb_iso {
int
speed
;
/* IEEE1394_SPEED_100, 200, or 400 */
int
channel
;
/* -1 if multichannel */
int
dma_mode
;
/* dma receive mode */
/* greatest # of packets between interrupts - controls
the maximum latency of the buffer */
...
...
@@ -139,6 +149,7 @@ struct hpsb_iso* hpsb_iso_recv_init(struct hpsb_host *host,
unsigned
int
data_buf_size
,
unsigned
int
buf_packets
,
int
channel
,
int
dma_mode
,
int
irq_interval
,
void
(
*
callback
)(
struct
hpsb_iso
*
));
...
...
drivers/ieee1394/nodemgr.c
View file @
d412a4c3
...
...
@@ -516,8 +516,7 @@ static struct device nodemgr_dev_template_ne = {
.
driver_data
=
&
nodemgr_driverdata_ne
,
};
static
struct
device
nodemgr_dev_template_host
=
{
struct
device
nodemgr_dev_template_host
=
{
.
bus
=
&
ieee1394_bus_type
,
.
release
=
nodemgr_release_host
,
.
driver
=
&
nodemgr_driver_host
,
...
...
@@ -1255,36 +1254,6 @@ void hpsb_unregister_protocol(struct hpsb_protocol_driver *driver)
}
/* Searches the list of ud's that match a ne as the parent. If the ud has
* a driver associated with it, we call that driver's update function
* with the ud as the argument. */
static
int
nodemgr_driver_search_cb
(
struct
device
*
dev
,
void
*
__data
)
{
struct
node_entry
*
ne
=
__data
;
struct
unit_directory
*
ud
;
if
(
dev
->
driver_data
==
&
nodemgr_driverdata_ne
||
dev
->
driver_data
==
&
nodemgr_driverdata_host
)
return
0
;
ud
=
container_of
(
dev
,
struct
unit_directory
,
device
);
if
(
&
ne
->
device
!=
ud
->
device
.
parent
)
return
0
;
if
(
ud
->
device
.
driver
)
{
struct
hpsb_protocol_driver
*
pdrv
;
pdrv
=
container_of
(
ud
->
device
.
driver
,
struct
hpsb_protocol_driver
,
driver
);
if
(
pdrv
->
update
)
pdrv
->
update
(
ud
);
}
return
0
;
}
/*
* This function updates nodes that were present on the bus before the
* reset and still are after the reset. The nodeid and the config rom
...
...
@@ -1480,9 +1449,24 @@ static int nodemgr_probe_ne_cb(struct device *dev, void *__data)
ne
->
needs_probe
=
0
;
return
1
;
}
else
{
struct
list_head
*
lh
;
/* Update unit_dirs with attached drivers */
bus_for_each_dev
(
&
ieee1394_bus_type
,
NULL
,
ne
,
nodemgr_driver_search_cb
);
list_for_each
(
lh
,
&
dev
->
children
)
{
struct
unit_directory
*
ud
;
ud
=
container_of
(
list_to_dev
(
lh
),
struct
unit_directory
,
device
);
if
(
ud
->
device
.
driver
)
{
struct
hpsb_protocol_driver
*
pdrv
;
pdrv
=
container_of
(
ud
->
device
.
driver
,
struct
hpsb_protocol_driver
,
driver
);
if
(
pdrv
->
update
)
pdrv
->
update
(
ud
);
}
}
}
return
0
;
}
...
...
@@ -1664,7 +1648,6 @@ static int nodemgr_host_thread(void *__hi)
allow_signal
(
SIGTERM
);
/* Setup our device-model entries */
device_register
(
&
host
->
device
);
nodemgr_create_host_dev_files
(
host
);
/* Sit and wait for a signal to probe the nodes on the bus. This
...
...
@@ -1753,6 +1736,34 @@ struct node_entry *hpsb_nodeid_get_entry(struct hpsb_host *host, nodeid_t nodeid
return
ne
;
}
struct
for_each_host_struct
{
int
(
*
cb
)(
struct
hpsb_host
*
,
void
*
);
void
*
data
;
};
static
int
nodemgr_for_each_host_cb
(
struct
device
*
dev
,
void
*
__data
)
{
struct
for_each_host_struct
*
host_data
=
__data
;
struct
hpsb_host
*
host
;
if
(
dev
->
driver_data
!=
&
nodemgr_driverdata_host
)
return
0
;
host
=
container_of
(
dev
,
struct
hpsb_host
,
device
);
return
host_data
->
cb
(
host
,
host_data
->
data
);
}
int
nodemgr_for_each_host
(
void
*
__data
,
int
(
*
cb
)(
struct
hpsb_host
*
,
void
*
))
{
struct
for_each_host_struct
host_data
;
host_data
.
cb
=
cb
;
host_data
.
data
=
__data
;
return
bus_for_each_dev
(
&
ieee1394_bus_type
,
NULL
,
&
host_data
,
nodemgr_for_each_host_cb
);
}
/* The following four convenience functions use a struct node_entry
* for addressing a node on the bus. They are intended for use by any
* process context, not just the nodemgr thread, so we need to be a
...
...
@@ -1821,11 +1832,6 @@ static void nodemgr_add_host(struct hpsb_host *host)
init_completion
(
&
hi
->
exited
);
sema_init
(
&
hi
->
reset_sem
,
0
);
memcpy
(
&
host
->
device
,
&
nodemgr_dev_template_host
,
sizeof
(
host
->
device
));
host
->
device
.
parent
=
&
host
->
pdev
->
dev
;
snprintf
(
host
->
device
.
bus_id
,
BUS_ID_SIZE
,
"fw-host%d"
,
host
->
id
);
sprintf
(
hi
->
daemon_name
,
"knodemgrd_%d"
,
host
->
id
);
hi
->
pid
=
kernel_thread
(
nodemgr_host_thread
,
hi
,
CLONE_KERNEL
);
...
...
@@ -1879,7 +1885,6 @@ static struct hpsb_highlevel nodemgr_highlevel = {
void
init_ieee1394_nodemgr
(
void
)
{
bus_register
(
&
ieee1394_bus_type
);
driver_register
(
&
nodemgr_driver_host
);
driver_register
(
&
nodemgr_driver_ne
);
...
...
@@ -1892,5 +1897,4 @@ void cleanup_ieee1394_nodemgr(void)
driver_unregister
(
&
nodemgr_driver_ne
);
driver_unregister
(
&
nodemgr_driver_host
);
bus_unregister
(
&
ieee1394_bus_type
);
}
drivers/ieee1394/nodemgr.h
View file @
d412a4c3
...
...
@@ -219,7 +219,16 @@ int hpsb_node_lock(struct node_entry *ne, u64 addr,
int
extcode
,
quadlet_t
*
data
,
quadlet_t
arg
);
/* Iterate the hosts, calling a given function with supplied data for each
* host. */
int
nodemgr_for_each_host
(
void
*
__data
,
int
(
*
cb
)(
struct
hpsb_host
*
,
void
*
));
void
init_ieee1394_nodemgr
(
void
);
void
cleanup_ieee1394_nodemgr
(
void
);
/* The template for a host device */
extern
struct
device
nodemgr_dev_template_host
;
#endif
/* _IEEE1394_NODEMGR_H */
drivers/ieee1394/ohci1394.c
View file @
d412a4c3
...
...
@@ -134,7 +134,7 @@
#ifdef OHCI1394_DEBUG
#define DBGMSG(card, fmt, args...) \
printk(KERN_INFO "%s
_
%d: " fmt "\n" , OHCI1394_DRIVER_NAME, card , ## args)
printk(KERN_INFO "%s
: fw-host
%d: " fmt "\n" , OHCI1394_DRIVER_NAME, card , ## args)
#else
#define DBGMSG(card, fmt, args...)
#endif
...
...
@@ -158,10 +158,10 @@ printk(level "%s: " fmt "\n" , OHCI1394_DRIVER_NAME , ## args)
/* print card specific information */
#define PRINT(level, card, fmt, args...) \
printk(level "%s
_
%d: " fmt "\n" , OHCI1394_DRIVER_NAME, card , ## args)
printk(level "%s
: fw-host
%d: " fmt "\n" , OHCI1394_DRIVER_NAME, card , ## args)
static
char
version
[]
__devinitdata
=
"$Rev: 10
45
$ Ben Collins <bcollins@debian.org>"
;
"$Rev: 10
87
$ Ben Collins <bcollins@debian.org>"
;
/* Module Parameters */
static
int
phys_dma
=
1
;
...
...
@@ -845,7 +845,7 @@ static int ohci_transmit(struct hpsb_host *host, struct hpsb_packet *packet)
PRINT
(
KERN_ERR
,
ohci
->
id
,
"Transmit packet size %Zd is too big"
,
packet
->
data_size
);
return
0
;
return
-
EOVERFLOW
;
}
/* Decide whether we have an iso, a request, or a response packet */
...
...
@@ -862,7 +862,7 @@ static int ohci_transmit(struct hpsb_host *host, struct hpsb_packet *packet)
if
(
in_interrupt
())
{
PRINT
(
KERN_ERR
,
ohci
->
id
,
"legacy IT context cannot be initialized during interrupt"
);
return
0
;
return
-
EINVAL
;
}
if
(
alloc_dma_trm_ctx
(
ohci
,
&
ohci
->
it_legacy_context
,
...
...
@@ -870,7 +870,7 @@ static int ohci_transmit(struct hpsb_host *host, struct hpsb_packet *packet)
OHCI1394_IsoXmitContextBase
)
<
0
)
{
PRINT
(
KERN_ERR
,
ohci
->
id
,
"error initializing legacy IT context"
);
return
0
;
return
-
ENOMEM
;
}
initialize_dma_trm_ctx
(
&
ohci
->
it_legacy_context
);
...
...
@@ -890,7 +890,7 @@ static int ohci_transmit(struct hpsb_host *host, struct hpsb_packet *packet)
spin_unlock_irqrestore
(
&
d
->
lock
,
flags
);
return
1
;
return
0
;
}
static
int
ohci_devctl
(
struct
hpsb_host
*
host
,
enum
devctl_cmd
cmd
,
int
arg
)
...
...
@@ -1113,8 +1113,8 @@ struct ohci_iso_recv {
struct
ohci1394_iso_tasklet
task
;
int
task_active
;
enum
{
BUFFER_FILL_MODE
,
PACKET_PER_BUFFER_MODE
}
dma_mode
;
enum
{
BUFFER_FILL_MODE
=
0
,
PACKET_PER_BUFFER_MODE
=
1
}
dma_mode
;
/* memory and PCI mapping for the DMA descriptors */
struct
dma_prog_region
prog
;
...
...
@@ -1175,7 +1175,8 @@ static int ohci_iso_recv_init(struct hpsb_iso *iso)
/* use buffer-fill mode, unless irq_interval is 1
(note: multichannel requires buffer-fill) */
if
(
iso
->
irq_interval
==
1
&&
iso
->
channel
!=
-
1
)
{
if
(((
iso
->
irq_interval
==
1
&&
iso
->
dma_mode
==
HPSB_ISO_DMA_OLD_ABI
)
||
iso
->
dma_mode
==
HPSB_ISO_DMA_PACKET_PER_BUFFER
)
&&
iso
->
channel
!=
-
1
)
{
recv
->
dma_mode
=
PACKET_PER_BUFFER_MODE
;
}
else
{
recv
->
dma_mode
=
BUFFER_FILL_MODE
;
...
...
@@ -1194,8 +1195,11 @@ static int ohci_iso_recv_init(struct hpsb_iso *iso)
}
/* iso->irq_interval is in packets - translate that to blocks */
/* (err, sort of... 1 is always the safest value) */
recv
->
block_irq_interval
=
iso
->
irq_interval
/
recv
->
nblocks
;
if
(
iso
->
irq_interval
==
1
)
recv
->
block_irq_interval
=
1
;
else
recv
->
block_irq_interval
=
iso
->
irq_interval
*
((
recv
->
nblocks
+
1
)
/
iso
->
buf_packets
);
if
(
recv
->
block_irq_interval
*
4
>
recv
->
nblocks
)
recv
->
block_irq_interval
=
recv
->
nblocks
/
4
;
if
(
recv
->
block_irq_interval
<
1
)
...
...
@@ -1205,6 +1209,10 @@ static int ohci_iso_recv_init(struct hpsb_iso *iso)
int
max_packet_size
;
recv
->
nblocks
=
iso
->
buf_packets
;
recv
->
block_irq_interval
=
iso
->
irq_interval
;
if
(
recv
->
block_irq_interval
*
4
>
iso
->
buf_packets
)
recv
->
block_irq_interval
=
iso
->
buf_packets
/
4
;
if
(
recv
->
block_irq_interval
<
1
)
recv
->
block_irq_interval
=
1
;
/* choose a buffer stride */
...
...
@@ -3271,7 +3279,6 @@ do { \
static
int
__devinit
ohci1394_pci_probe
(
struct
pci_dev
*
dev
,
const
struct
pci_device_id
*
ent
)
{
static
unsigned
int
card_id_counter
=
0
;
static
int
version_printed
=
0
;
struct
hpsb_host
*
host
;
...
...
@@ -3282,15 +3289,14 @@ static int __devinit ohci1394_pci_probe(struct pci_dev *dev,
PRINT_G
(
KERN_INFO
,
"%s"
,
version
);
if
(
pci_enable_device
(
dev
))
FAIL
(
-
ENXIO
,
"Failed to enable OHCI hardware %d"
,
card_id_counter
++
);
FAIL
(
-
ENXIO
,
"Failed to enable OHCI hardware"
);
pci_set_master
(
dev
);
host
=
hpsb_alloc_host
(
&
ohci1394_driver
,
sizeof
(
struct
ti_ohci
));
host
=
hpsb_alloc_host
(
&
ohci1394_driver
,
sizeof
(
struct
ti_ohci
)
,
&
dev
->
dev
);
if
(
!
host
)
FAIL
(
-
ENOMEM
,
"Failed to allocate host structure"
);
ohci
=
host
->
hostdata
;
ohci
->
id
=
card_id_counter
++
;
ohci
->
id
=
host
->
id
;
ohci
->
dev
=
dev
;
ohci
->
host
=
host
;
ohci
->
init_state
=
OHCI_INIT_ALLOC_HOST
;
...
...
@@ -3462,11 +3468,14 @@ static int __devinit ohci1394_pci_probe(struct pci_dev *dev,
static
void
ohci1394_pci_remove
(
struct
pci_dev
*
pdev
)
{
struct
ti_ohci
*
ohci
;
struct
device
*
dev
;
ohci
=
pci_get_drvdata
(
pdev
);
if
(
!
ohci
)
return
;
dev
=
get_device
(
&
ohci
->
host
->
device
);
switch
(
ohci
->
init_state
)
{
case
OHCI_INIT_DONE
:
hpsb_remove_host
(
ohci
->
host
);
...
...
@@ -3555,8 +3564,10 @@ static void ohci1394_pci_remove(struct pci_dev *pdev)
case
OHCI_INIT_ALLOC_HOST
:
pci_set_drvdata
(
ohci
->
dev
,
NULL
);
hpsb_unref_host
(
ohci
->
host
);
}
if
(
dev
)
put_device
(
dev
);
}
...
...
drivers/ieee1394/oui.db
View file @
d412a4c3
...
...
@@ -1612,7 +1612,7 @@
000658 Helmut Fischer GmbH & Co. KG
000659 EAL (Apeldoorn) B.V.
00065A Strix Systems
00065B Dell
Inc
.
00065B Dell
Computer Corp
.
00065C Malachite Technologies, Inc.
00065D Heidelberg Web Systems
00065E Photuris, Inc.
...
...
@@ -3965,7 +3965,7 @@
00B0C2 Cisco Systems, Inc.
00B0C7 Tellabs Operations, Inc.
00B0CE TECHNOLOGY RESCUE
00B0D0 Dell
Inc
.
00B0D0 Dell
Computer Corp
.
00B0DB Nextcell, Inc.
00B0DF Reliable Data Technology, Inc.
00B0E7 British Federal Ltd.
...
...
@@ -4054,7 +4054,7 @@
00C04C DEPARTMENT OF FOREIGN AFFAIRS
00C04D MITEC, INC.
00C04E COMTROL CORPORATION
00C04F D
ell Inc.
00C04F D
ELL COMPUTER CORPORATION
00C050 TOYO DENKI SEIZO K.K.
00C051 ADVANCED INTEGRATION RESEARCH
00C052 BURR-BROWN
...
...
drivers/ieee1394/pcilynx.c
View file @
d412a4c3
...
...
@@ -521,10 +521,6 @@ static void send_next(struct ti_lynx *lynx, int what)
break
;
}
if
(
!
packet
->
data_be
)
{
pcl
.
buffer
[
1
].
control
|=
PCL_BIGENDIAN
;
}
put_pcl
(
lynx
,
d
->
pcl
,
&
pcl
);
run_pcl
(
lynx
,
d
->
pcl_start
,
d
->
channel
);
}
...
...
@@ -540,7 +536,7 @@ static int lynx_transmit(struct hpsb_host *host, struct hpsb_packet *packet)
if
(
packet
->
data_size
>=
4096
)
{
PRINT
(
KERN_ERR
,
lynx
->
id
,
"transmit packet data too big (%Zd)"
,
packet
->
data_size
);
return
0
;
return
-
EOVERFLOW
;
}
switch
(
packet
->
type
)
{
...
...
@@ -554,7 +550,7 @@ static int lynx_transmit(struct hpsb_host *host, struct hpsb_packet *packet)
default:
PRINT
(
KERN_ERR
,
lynx
->
id
,
"invalid packet type %d"
,
packet
->
type
);
return
0
;
return
-
EINVAL
;
}
if
(
packet
->
tcode
==
TCODE_WRITEQ
...
...
@@ -570,7 +566,7 @@ static int lynx_transmit(struct hpsb_host *host, struct hpsb_packet *packet)
spin_unlock_irqrestore
(
&
d
->
queue_lock
,
flags
);
return
1
;
return
0
;
}
...
...
@@ -1120,7 +1116,7 @@ static ssize_t mem_read(struct file *file, char *buffer, size_t count,
retval
=
copy_to_user
(
buffer
,
md
->
lynx
->
mem_dma_buffer
,
count
);
up
(
&
md
->
lynx
->
mem_dma_mutex
);
if
(
retval
<
0
)
return
retval
;
if
(
retval
)
return
-
EFAULT
;
*
offset
+=
count
;
return
count
;
}
...
...
@@ -1141,14 +1137,17 @@ static ssize_t mem_write(struct file *file, const char *buffer, size_t count,
/* FIXME: dereferencing pointers to PCI mem doesn't work everywhere */
switch
(
md
->
type
)
{
case
aux
:
copy_from_user
(
md
->
lynx
->
aux_port
+
(
*
offset
),
buffer
,
count
);
if
(
copy_from_user
(
md
->
lynx
->
aux_port
+
(
*
offset
),
buffer
,
count
))
return
-
EFAULT
;
break
;
case
ram
:
copy_from_user
(
md
->
lynx
->
local_ram
+
(
*
offset
),
buffer
,
count
);
if
(
copy_from_user
(
md
->
lynx
->
local_ram
+
(
*
offset
),
buffer
,
count
))
return
-
EFAULT
;
break
;
case
rom
:
/* the ROM may be writeable */
copy_from_user
(
md
->
lynx
->
local_rom
+
(
*
offset
),
buffer
,
count
);
if
(
copy_from_user
(
md
->
lynx
->
local_rom
+
(
*
offset
),
buffer
,
count
))
return
-
EFAULT
;
break
;
}
...
...
@@ -1443,12 +1442,15 @@ static void iso_rcv_bh(struct ti_lynx *lynx)
static
void
remove_card
(
struct
pci_dev
*
dev
)
{
struct
ti_lynx
*
lynx
;
struct
device
*
lynx_dev
;
int
i
;
lynx
=
pci_get_drvdata
(
dev
);
if
(
!
lynx
)
return
;
pci_set_drvdata
(
dev
,
NULL
);
lynx_dev
=
get_device
(
&
lynx
->
host
->
device
);
switch
(
lynx
->
state
)
{
case
is_host
:
reg_write
(
lynx
,
PCI_INT_ENABLE
,
0
);
...
...
@@ -1498,7 +1500,9 @@ static void remove_card(struct pci_dev *dev)
}
tasklet_kill
(
&
lynx
->
iso_rcv
.
tq
);
hpsb_unref_host
(
lynx
->
host
);
if
(
lynx_dev
)
put_device
(
lynx_dev
);
}
...
...
@@ -1535,7 +1539,7 @@ static int __devinit add_card(struct pci_dev *dev,
error
=
-
ENOMEM
;
host
=
hpsb_alloc_host
(
&
lynx_driver
,
sizeof
(
struct
ti_lynx
));
host
=
hpsb_alloc_host
(
&
lynx_driver
,
sizeof
(
struct
ti_lynx
)
,
&
dev
->
dev
);
if
(
!
host
)
FAIL
(
"failed to allocate control structure memory"
);
lynx
=
host
->
hostdata
;
...
...
drivers/ieee1394/raw1394.c
View file @
d412a4c3
...
...
@@ -128,7 +128,7 @@ static void free_pending_request(struct pending_request *req)
}
else
if
(
req
->
free_data
)
{
kfree
(
req
->
data
);
}
free_hpsb
_packet
(
req
->
packet
);
hpsb_free
_packet
(
req
->
packet
);
kfree
(
req
);
}
...
...
@@ -558,7 +558,7 @@ static int state_initialized(struct file_info *fi, struct pending_request *req)
lh
=
lh
->
next
;
}
hi
=
list_entry
(
lh
,
struct
host_info
,
list
);
hpsb_ref_host
(
hi
->
host
);
// XXX Need to handle failure case
get_device
(
&
hi
->
host
->
device
);
// XXX Need to handle failure case
list_add_tail
(
&
fi
->
list
,
&
hi
->
file_info_list
);
fi
->
host
=
hi
->
host
;
fi
->
state
=
connected
;
...
...
@@ -782,7 +782,7 @@ static int handle_async_request(struct file_info *fi,
packet
->
generation
=
req
->
req
.
generation
;
if
(
!
hpsb_send_packet
(
packet
)
)
{
if
(
hpsb_send_packet
(
packet
)
<
0
)
{
req
->
req
.
error
=
RAW1394_ERROR_SEND_ERROR
;
req
->
req
.
length
=
0
;
hpsb_free_tlabel
(
packet
);
...
...
@@ -823,7 +823,7 @@ static int handle_iso_send(struct file_info *fi, struct pending_request *req,
/* Update the generation of the packet just before sending. */
packet
->
generation
=
req
->
req
.
generation
;
if
(
!
hpsb_send_packet
(
packet
)
)
{
if
(
hpsb_send_packet
(
packet
)
<
0
)
{
req
->
req
.
error
=
RAW1394_ERROR_SEND_ERROR
;
queue_complete_req
(
req
);
}
...
...
@@ -846,7 +846,7 @@ static int handle_async_send(struct file_info *fi, struct pending_request *req)
return
sizeof
(
struct
raw1394_request
);
}
packet
=
alloc_hpsb
_packet
(
req
->
req
.
length
-
header_length
);
packet
=
hpsb_alloc
_packet
(
req
->
req
.
length
-
header_length
);
req
->
packet
=
packet
;
if
(
!
packet
)
return
-
ENOMEM
;
...
...
@@ -885,7 +885,7 @@ static int handle_async_send(struct file_info *fi, struct pending_request *req)
/* Update the generation of the packet just before sending. */
packet
->
generation
=
req
->
req
.
generation
;
if
(
!
hpsb_send_packet
(
packet
)
)
{
if
(
hpsb_send_packet
(
packet
)
<
0
)
{
req
->
req
.
error
=
RAW1394_ERROR_SEND_ERROR
;
queue_complete_req
(
req
);
}
...
...
@@ -1797,6 +1797,106 @@ static int arm_unregister(struct file_info *fi, struct pending_request *req)
return
sizeof
(
struct
raw1394_request
);
}
/* Copy data from ARM buffer(s) to user buffer. */
static
int
arm_get_buf
(
struct
file_info
*
fi
,
struct
pending_request
*
req
)
{
struct
arm_addr
*
arm_addr
=
NULL
;
unsigned
long
flags
;
unsigned
long
offset
;
struct
list_head
*
entry
;
DBGMSG
(
"arm_get_buf "
"addr(Offset): %04X %08X length: %u"
,
(
u32
)
((
req
->
req
.
address
>>
32
)
&
0xFFFF
),
(
u32
)
(
req
->
req
.
address
&
0xFFFFFFFF
),
(
u32
)
req
->
req
.
length
);
spin_lock_irqsave
(
&
host_info_lock
,
flags
);
entry
=
fi
->
addr_list
.
next
;
while
(
entry
!=
&
(
fi
->
addr_list
))
{
arm_addr
=
list_entry
(
entry
,
struct
arm_addr
,
addr_list
);
if
((
arm_addr
->
start
<=
req
->
req
.
address
)
&&
(
arm_addr
->
end
>
req
->
req
.
address
))
{
if
(
req
->
req
.
address
+
req
->
req
.
length
<=
arm_addr
->
end
)
{
offset
=
req
->
req
.
address
-
arm_addr
->
start
;
DBGMSG
(
"arm_get_buf copy_to_user( %08X, %08X, %u )"
,
(
u32
)
req
->
req
.
recvb
,
(
u32
)
(
arm_addr
->
addr_space_buffer
+
offset
),
(
u32
)
req
->
req
.
length
);
if
(
copy_to_user
(
int2ptr
(
req
->
req
.
recvb
),
arm_addr
->
addr_space_buffer
+
offset
,
req
->
req
.
length
))
{
spin_unlock_irqrestore
(
&
host_info_lock
,
flags
);
return
(
-
EFAULT
);
}
spin_unlock_irqrestore
(
&
host_info_lock
,
flags
);
free_pending_request
(
req
);
/* we have to free the request, because we queue no response, and therefore nobody will free it */
return
sizeof
(
struct
raw1394_request
);
}
else
{
DBGMSG
(
"arm_get_buf request exceeded mapping"
);
spin_unlock_irqrestore
(
&
host_info_lock
,
flags
);
return
(
-
EINVAL
);
}
}
entry
=
entry
->
next
;
}
spin_unlock_irqrestore
(
&
host_info_lock
,
flags
);
return
(
-
EINVAL
);
}
/* Copy data from user buffer to ARM buffer(s). */
static
int
arm_set_buf
(
struct
file_info
*
fi
,
struct
pending_request
*
req
)
{
struct
arm_addr
*
arm_addr
=
NULL
;
unsigned
long
flags
;
unsigned
long
offset
;
struct
list_head
*
entry
;
DBGMSG
(
"arm_set_buf "
"addr(Offset): %04X %08X length: %u"
,
(
u32
)
((
req
->
req
.
address
>>
32
)
&
0xFFFF
),
(
u32
)
(
req
->
req
.
address
&
0xFFFFFFFF
),
(
u32
)
req
->
req
.
length
);
spin_lock_irqsave
(
&
host_info_lock
,
flags
);
entry
=
fi
->
addr_list
.
next
;
while
(
entry
!=
&
(
fi
->
addr_list
))
{
arm_addr
=
list_entry
(
entry
,
struct
arm_addr
,
addr_list
);
if
((
arm_addr
->
start
<=
req
->
req
.
address
)
&&
(
arm_addr
->
end
>
req
->
req
.
address
))
{
if
(
req
->
req
.
address
+
req
->
req
.
length
<=
arm_addr
->
end
)
{
offset
=
req
->
req
.
address
-
arm_addr
->
start
;
DBGMSG
(
"arm_set_buf copy_from_user( %08X, %08X, %u )"
,
(
u32
)
(
arm_addr
->
addr_space_buffer
+
offset
),
(
u32
)
req
->
req
.
sendb
,
(
u32
)
req
->
req
.
length
);
if
(
copy_from_user
(
arm_addr
->
addr_space_buffer
+
offset
,
int2ptr
(
req
->
req
.
sendb
),
req
->
req
.
length
))
{
spin_unlock_irqrestore
(
&
host_info_lock
,
flags
);
return
(
-
EFAULT
);
}
spin_unlock_irqrestore
(
&
host_info_lock
,
flags
);
free_pending_request
(
req
);
/* we have to free the request, because we queue no response, and therefore nobody will free it */
return
sizeof
(
struct
raw1394_request
);
}
else
{
DBGMSG
(
"arm_set_buf request exceeded mapping"
);
spin_unlock_irqrestore
(
&
host_info_lock
,
flags
);
return
(
-
EINVAL
);
}
}
entry
=
entry
->
next
;
}
spin_unlock_irqrestore
(
&
host_info_lock
,
flags
);
return
(
-
EINVAL
);
}
static
int
reset_notification
(
struct
file_info
*
fi
,
struct
pending_request
*
req
)
{
DBGMSG
(
"reset_notification called - switch %s "
,
...
...
@@ -1829,9 +1929,8 @@ static int write_phypacket(struct file_info *fi, struct pending_request *req)
spin_unlock_irq
(
&
fi
->
reqlists_lock
);
packet
->
generation
=
req
->
req
.
generation
;
retval
=
hpsb_send_packet
(
packet
);
DBGMSG
(
"write_phypacket send_packet called => retval: %d "
,
retval
);
if
(
!
retval
)
{
DBGMSG
(
"write_phypacket send_packet called => retval: %d "
,
retval
);
if
(
retval
<
0
)
{
req
->
req
.
error
=
RAW1394_ERROR_SEND_ERROR
;
req
->
req
.
length
=
0
;
queue_complete_req
(
req
);
...
...
@@ -1912,6 +2011,12 @@ static int state_connected(struct file_info *fi, struct pending_request *req)
case
RAW1394_REQ_ARM_UNREGISTER
:
return
arm_unregister
(
fi
,
req
);
case
RAW1394_REQ_ARM_SET_BUF
:
return
arm_set_buf
(
fi
,
req
);
case
RAW1394_REQ_ARM_GET_BUF
:
return
arm_get_buf
(
fi
,
req
);
case
RAW1394_REQ_RESET_NOTIFY
:
return
reset_notification
(
fi
,
req
);
...
...
@@ -2137,6 +2242,7 @@ static int raw1394_iso_recv_init(struct file_info *fi, void *uaddr)
stat
.
config
.
data_buf_size
,
stat
.
config
.
buf_packets
,
stat
.
config
.
channel
,
stat
.
config
.
dma_mode
,
stat
.
config
.
irq_interval
,
rawiso_activity_cb
);
if
(
!
fi
->
iso_handle
)
...
...
@@ -2489,7 +2595,7 @@ static int raw1394_release(struct inode *inode, struct file *file)
list_del
(
&
fi
->
list
);
spin_unlock_irq
(
&
host_info_lock
);
hpsb_unref_host
(
fi
->
host
);
put_device
(
&
fi
->
host
->
device
);
}
kfree
(
fi
);
...
...
drivers/ieee1394/raw1394.h
View file @
d412a4c3
...
...
@@ -30,6 +30,8 @@
#define RAW1394_REQ_ARM_REGISTER 300
#define RAW1394_REQ_ARM_UNREGISTER 301
#define RAW1394_REQ_ARM_SET_BUF 302
#define RAW1394_REQ_ARM_GET_BUF 303
#define RAW1394_REQ_RESET_NOTIFY 400
...
...
@@ -149,6 +151,9 @@ struct raw1394_iso_config {
/* xmit only - iso transmission speed */
__u8
speed
;
/* The mode of the dma when receiving iso data. Must be supported by chip */
__u8
dma_mode
;
/* max. latency of buffer, in packets (-1 if you don't care) */
__s32
irq_interval
;
};
...
...
drivers/ieee1394/sbp2.c
View file @
d412a4c3
...
...
@@ -77,7 +77,7 @@
#include "sbp2.h"
static
char
version
[]
__devinitdata
=
"$Rev: 10
34
$ Ben Collins <bcollins@debian.org>"
;
"$Rev: 10
82
$ Ben Collins <bcollins@debian.org>"
;
/*
* Module load parameter definitions
...
...
@@ -361,38 +361,34 @@ static int sbp2util_down_timeout(atomic_t *done, int timeout)
static
void
sbp2_free_packet
(
struct
hpsb_packet
*
packet
)
{
hpsb_free_tlabel
(
packet
);
free_hpsb
_packet
(
packet
);
hpsb_free
_packet
(
packet
);
}
/*
* This function is called to retrieve a block write packet from our
* packet pool. This function is used in place of calling
* alloc_hpsb_packet (which costs us three kmallocs). Instead we just pull
* out a free request packet and re-initialize values in it. I'm sure this
* can still stand some more optimization.
*/
static
struct
hpsb_packet
*
sbp2util_allocate_write_packet
(
struct
sbp2scsi_host_info
*
hi
,
struct
node_entry
*
ne
,
u64
addr
,
size_t
data_size
,
quadlet_t
*
data
)
/* This is much like hpsb_node_write(), except it ignores the response
* subaction and returns immediately. Can be used from interrupts.
*/
int
sbp2util_node_write_no_wait
(
struct
node_entry
*
ne
,
u64
addr
,
quadlet_t
*
buffer
,
size_t
length
)
{
struct
hpsb_packet
*
packet
;
packet
=
hpsb_make_writepacket
(
hi
->
host
,
ne
->
nodeid
,
addr
,
data
,
data_size
);
packet
=
hpsb_make_writepacket
(
ne
->
host
,
ne
->
nodeid
,
addr
,
buffer
,
length
);
if
(
!
packet
)
return
NULL
;
return
-
ENOMEM
;
hpsb_set_packet_complete_task
(
packet
,
(
void
(
*
)(
void
*
))
sbp2_free_packet
,
packet
);
hpsb_node_fill_packet
(
ne
,
packet
);
return
packet
;
}
if
(
hpsb_send_packet
(
packet
)
<
0
)
{
sbp2_free_packet
(
packet
);
return
-
EIO
;
}
return
0
;
}
/*
* This function is called to create a pool of command orbs used for
...
...
@@ -1734,9 +1730,9 @@ static int sbp2_max_speed_and_size(struct scsi_id_instance_data *scsi_id)
*/
static
int
sbp2_agent_reset
(
struct
scsi_id_instance_data
*
scsi_id
,
int
wait
)
{
struct
sbp2scsi_host_info
*
hi
=
scsi_id
->
hi
;
struct
hpsb_packet
*
packet
;
quadlet_t
data
;
u64
addr
;
int
retval
;
SBP2_DEBUG
(
"sbp2_agent_reset"
);
...
...
@@ -1744,25 +1740,16 @@ static int sbp2_agent_reset(struct scsi_id_instance_data *scsi_id, int wait)
* Ok, let's write to the target's management agent register
*/
data
=
ntohl
(
SBP2_AGENT_RESET_DATA
);
packet
=
sbp2util_allocate_write_packet
(
hi
,
scsi_id
->
ne
,
scsi_id
->
sbp2_command_block_agent_addr
+
SBP2_AGENT_RESET_OFFSET
,
4
,
&
data
);
if
(
!
packet
)
{
SBP2_ERR
(
"sbp2util_allocate_write_packet failed"
);
return
(
-
ENOMEM
);
}
addr
=
scsi_id
->
sbp2_command_block_agent_addr
+
SBP2_AGENT_RESET_OFFSET
;
if
(
!
hpsb_send_packet
(
packet
))
{
SBP2_ERR
(
"hpsb_send_packet failed"
);
sbp2_free_packet
(
packet
);
return
(
-
EIO
);
}
if
(
wait
)
retval
=
hpsb_node_write
(
scsi_id
->
ne
,
addr
,
&
data
,
4
);
else
retval
=
sbp2util_node_write_no_wait
(
scsi_id
->
ne
,
addr
,
&
data
,
4
);
if
(
wait
)
{
down
(
&
packet
->
state_change
);
down
(
&
packet
->
state_change
)
;
if
(
retval
<
0
)
{
SBP2_ERR
(
"hpsb_node_write failed.
\n
"
);
return
-
EIO
;
}
/*
...
...
@@ -2032,8 +2019,9 @@ static int sbp2_link_orb_command(struct scsi_id_instance_data *scsi_id,
struct
sbp2_command_info
*
command
)
{
struct
sbp2scsi_host_info
*
hi
=
scsi_id
->
hi
;
struct
hpsb_packet
*
packet
;
struct
sbp2_command_orb
*
command_orb
=
&
command
->
command_orb
;
struct
node_entry
*
ne
=
scsi_id
->
ne
;
u64
addr
;
outstanding_orb_incr
;
SBP2_ORB_DEBUG
(
"sending command orb %p, total orbs = %x"
,
...
...
@@ -2049,40 +2037,30 @@ static int sbp2_link_orb_command(struct scsi_id_instance_data *scsi_id,
* Check to see if there are any previous orbs to use
*/
if
(
scsi_id
->
last_orb
==
NULL
)
{
quadlet_t
data
[
2
];
/*
* Ok, let's write to the target's management agent register
*/
if
(
hpsb_node_entry_valid
(
scsi_id
->
ne
))
{
packet
=
sbp2util_allocate_write_packet
(
hi
,
scsi_id
->
ne
,
scsi_id
->
sbp2_command_block_agent_addr
+
SBP2_ORB_POINTER_OFFSET
,
8
,
NULL
);
if
(
!
packet
)
{
SBP2_ERR
(
"sbp2util_allocate_write_packet failed"
);
return
(
-
ENOMEM
);
}
packet
->
data
[
0
]
=
ORB_SET_NODE_ID
(
hi
->
host
->
node_id
);
packet
->
data
[
1
]
=
command
->
command_orb_dma
;
sbp2util_cpu_to_be32_buffer
(
packet
->
data
,
8
);
addr
=
scsi_id
->
sbp2_command_block_agent_addr
+
SBP2_ORB_POINTER_OFFSET
;
data
[
0
]
=
ORB_SET_NODE_ID
(
hi
->
host
->
node_id
);
data
[
1
]
=
command
->
command_orb_dma
;
sbp2util_cpu_to_be32_buffer
(
data
,
8
);
SBP2_ORB_DEBUG
(
"write command agent, command orb %p"
,
command_orb
);
if
(
!
hpsb_send_packet
(
packet
))
{
SBP2_ERR
(
"hpsb_send_packet failed"
);
sbp2_free_packet
(
packet
);
return
(
-
EIO
);
if
(
sbp2util_node_write_no_wait
(
ne
,
addr
,
data
,
8
)
<
0
)
{
SBP2_ERR
(
"sbp2util_node_write_no_wait failed.
\n
"
);
return
-
EIO
;
}
SBP2_ORB_DEBUG
(
"write command agent complete"
);
}
scsi_id
->
last_orb
=
command_orb
;
scsi_id
->
last_orb_dma
=
command
->
command_orb_dma
;
}
else
{
quadlet_t
data
;
/*
* We have an orb already sent (maybe or maybe not
...
...
@@ -2102,26 +2080,15 @@ static int sbp2_link_orb_command(struct scsi_id_instance_data *scsi_id,
/*
* Ring the doorbell
*/
if
(
hpsb_node_entry_valid
(
scsi_id
->
ne
))
{
quadlet_t
data
=
cpu_to_be32
(
command
->
command_orb_dma
);
packet
=
sbp2util_allocate_write_packet
(
hi
,
scsi_id
->
ne
,
scsi_id
->
sbp2_command_block_agent_addr
+
SBP2_DOORBELL_OFFSET
,
4
,
&
data
);
if
(
!
packet
)
{
SBP2_ERR
(
"sbp2util_allocate_write_packet failed"
);
return
(
-
ENOMEM
);
}
data
=
cpu_to_be32
(
command
->
command_orb_dma
);
addr
=
scsi_id
->
sbp2_command_block_agent_addr
+
SBP2_DOORBELL_OFFSET
;
SBP2_ORB_DEBUG
(
"ring doorbell, command orb %p"
,
command_orb
);
if
(
!
hpsb_send_packet
(
packet
))
{
SBP2_ERR
(
"hpsb_send_packet failed"
);
sbp2_free_packet
(
packet
);
if
(
sbp2util_node_write_no_wait
(
ne
,
addr
,
&
data
,
4
)
<
0
)
{
SBP2_ERR
(
"sbp2util_node_write_no_wait failed"
);
return
(
-
EIO
);
}
}
scsi_id
->
last_orb
=
command_orb
;
scsi_id
->
last_orb_dma
=
command
->
command_orb_dma
;
...
...
Write
Preview
Markdown
is supported
0%
Try again
or
attach a new file
Attach a file
Cancel
You are about to add
0
people
to the discussion. Proceed with caution.
Finish editing this message first!
Cancel
Please
register
or
sign in
to comment