Skip to content

Commit

Permalink
Merge branch 'for-linus' of git://git.kernel.org/pub/scm/linux/kernel…
Browse files Browse the repository at this point in the history
…/git/ieee1394/linux1394-2.6

* 'for-linus' of git://git.kernel.org/pub/scm/linux/kernel/git/ieee1394/linux1394-2.6:
  firewire, ieee1394: update Kconfig help
  firewire, ieee1394: update MAINTAINERS entries
  firewire: ohci: always use packet-per-buffer mode for isochronous reception
  firewire: cdev: fix another memory leak in an error path
  firewire: fix use of multiple AV/C devices, allow multiple FCP listeners

Comments from Stefan:

   Distributors who still ship the old stack (ieee1394, ohci1394,
   raw1394, sbp2, eth1394 and more) should now switch to the new one
   (firewire-core, firewire-ohci, firewire-sbp2, firewire-net).  In the
   first iteration, those distributors might want to ship the old stack
   also (but blacklisted) as a fallback for their users if unforeseen
   problems with the newer replacement drivers are encountered.

   The older FireWire stack contains several known problems which are
   not going to be fixed; instead, those issues are addressed by the new
   stack.  An incomplete list of these issues is kept in bugzilla:

	http://bugzilla.kernel.org/show_bug.cgi?id=10046

   We have a guide on migration from the older to the newer stack:

	http://ieee1394.wiki.kernel.org/index.php/Juju_Migration
  • Loading branch information
Linus Torvalds committed Dec 31, 2009
2 parents 5b889bf + 5d7db04 commit b7bfb2a
Show file tree
Hide file tree
Showing 10 changed files with 182 additions and 106 deletions.
15 changes: 3 additions & 12 deletions MAINTAINERS
Original file line number Diff line number Diff line change
Expand Up @@ -2169,10 +2169,9 @@ F: drivers/hwmon/f75375s.c
F: include/linux/f75375s.h

FIREWIRE SUBSYSTEM
M: Kristian Hoegsberg <krh@redhat.com>
M: Stefan Richter <stefanr@s5r6.in-berlin.de>
L: linux1394-devel@lists.sourceforge.net
W: http://www.linux1394.org/
W: http://ieee1394.wiki.kernel.org/
T: git git://git.kernel.org/pub/scm/linux/kernel/git/ieee1394/linux1394-2.6.git
S: Maintained
F: drivers/firewire/
Expand Down Expand Up @@ -2705,22 +2704,14 @@ S: Supported
F: drivers/idle/i7300_idle.c

IEEE 1394 SUBSYSTEM
M: Ben Collins <ben.collins@ubuntu.com>
M: Stefan Richter <stefanr@s5r6.in-berlin.de>
L: linux1394-devel@lists.sourceforge.net
W: http://www.linux1394.org/
W: http://ieee1394.wiki.kernel.org/
T: git git://git.kernel.org/pub/scm/linux/kernel/git/ieee1394/linux1394-2.6.git
S: Maintained
S: Obsolete
F: Documentation/debugging-via-ohci1394.txt
F: drivers/ieee1394/

IEEE 1394 RAW I/O DRIVER
M: Dan Dennedy <dan@dennedy.org>
M: Stefan Richter <stefanr@s5r6.in-berlin.de>
L: linux1394-devel@lists.sourceforge.net
S: Maintained
F: drivers/ieee1394/raw1394*

IEEE 802.15.4 SUBSYSTEM
M: Dmitry Eremin-Solenikov <dbaryshkov@gmail.com>
M: Sergey Lapin <slapin@ossfans.org>
Expand Down
2 changes: 1 addition & 1 deletion drivers/Kconfig
Original file line number Diff line number Diff line change
Expand Up @@ -28,7 +28,7 @@ source "drivers/md/Kconfig"

source "drivers/message/fusion/Kconfig"

source "drivers/ieee1394/Kconfig"
source "drivers/firewire/Kconfig"

source "drivers/message/i2o/Kconfig"

Expand Down
44 changes: 13 additions & 31 deletions drivers/firewire/Kconfig
Original file line number Diff line number Diff line change
@@ -1,5 +1,10 @@
menu "IEEE 1394 (FireWire) support"
depends on PCI || BROKEN
# firewire-core does not depend on PCI but is
# not useful without PCI controller driver

comment "You can enable one or both FireWire driver stacks."
comment "See the help texts for more information."
comment "The newer stack is recommended."

config FIREWIRE
tristate "FireWire driver stack"
Expand All @@ -15,16 +20,6 @@ config FIREWIRE
To compile this driver as a module, say M here: the module will be
called firewire-core.

This module functionally replaces ieee1394, raw1394, and video1394.
To access it from application programs, you generally need at least
libraw1394 v2. IIDC/DCAM applications need libdc1394 v2.
No libraries are required to access storage devices through the
firewire-sbp2 driver.

NOTE:
FireWire audio devices currently require the old drivers (ieee1394,
ohci1394, raw1394).

config FIREWIRE_OHCI
tristate "OHCI-1394 controllers"
depends on PCI && FIREWIRE
Expand All @@ -34,22 +29,7 @@ config FIREWIRE_OHCI
is the only chipset in use, so say Y here.

To compile this driver as a module, say M here: The module will be
called firewire-ohci. It replaces ohci1394 of the classic IEEE 1394
stack.

NOTE:
If you want to install firewire-ohci and ohci1394 together, you
should configure them only as modules and blacklist the driver(s)
which you don't want to have auto-loaded. Add either

blacklist firewire-ohci
or
blacklist ohci1394
blacklist video1394
blacklist dv1394

to /etc/modprobe.conf or /etc/modprobe.d/* and update modprobe.conf
depending on your distribution.
called firewire-ohci.

config FIREWIRE_OHCI_DEBUG
bool
Expand All @@ -66,8 +46,7 @@ config FIREWIRE_SBP2
like scanners.

To compile this driver as a module, say M here: The module will be
called firewire-sbp2. It replaces sbp2 of the classic IEEE 1394
stack.
called firewire-sbp2.

You should also enable support for disks, CD-ROMs, etc. in the SCSI
configuration section.
Expand All @@ -83,5 +62,8 @@ config FIREWIRE_NET
NOTE, this driver is not stable yet!

To compile this driver as a module, say M here: The module will be
called firewire-net. It replaces eth1394 of the classic IEEE 1394
stack.
called firewire-net.

source "drivers/ieee1394/Kconfig"

endmenu
27 changes: 16 additions & 11 deletions drivers/firewire/core-cdev.c
Original file line number Diff line number Diff line change
Expand Up @@ -601,8 +601,9 @@ static void release_request(struct client *client,
struct inbound_transaction_resource *r = container_of(resource,
struct inbound_transaction_resource, resource);

fw_send_response(client->device->card, r->request,
RCODE_CONFLICT_ERROR);
if (r->request)
fw_send_response(client->device->card, r->request,
RCODE_CONFLICT_ERROR);
kfree(r);
}

Expand Down Expand Up @@ -645,7 +646,8 @@ static void handle_request(struct fw_card *card, struct fw_request *request,
failed:
kfree(r);
kfree(e);
fw_send_response(card, request, RCODE_CONFLICT_ERROR);
if (request)
fw_send_response(card, request, RCODE_CONFLICT_ERROR);
}

static void release_address_handler(struct client *client,
Expand Down Expand Up @@ -715,15 +717,18 @@ static int ioctl_send_response(struct client *client, void *buffer)

r = container_of(resource, struct inbound_transaction_resource,
resource);
if (request->length < r->length)
r->length = request->length;

if (copy_from_user(r->data, u64_to_uptr(request->data), r->length)) {
ret = -EFAULT;
goto out;
if (r->request) {
if (request->length < r->length)
r->length = request->length;
if (copy_from_user(r->data, u64_to_uptr(request->data),
r->length)) {
ret = -EFAULT;
kfree(r->request);
goto out;
}
fw_send_response(client->device->card, r->request,
request->rcode);
}

fw_send_response(client->device->card, r->request, request->rcode);
out:
kfree(r);

Expand Down
118 changes: 97 additions & 21 deletions drivers/firewire/core-transaction.c
Original file line number Diff line number Diff line change
Expand Up @@ -432,14 +432,20 @@ static struct fw_address_handler *lookup_overlapping_address_handler(
return NULL;
}

static bool is_enclosing_handler(struct fw_address_handler *handler,
unsigned long long offset, size_t length)
{
return handler->offset <= offset &&
offset + length <= handler->offset + handler->length;
}

static struct fw_address_handler *lookup_enclosing_address_handler(
struct list_head *list, unsigned long long offset, size_t length)
{
struct fw_address_handler *handler;

list_for_each_entry(handler, list, link) {
if (handler->offset <= offset &&
offset + length <= handler->offset + handler->length)
if (is_enclosing_handler(handler, offset, length))
return handler;
}

Expand All @@ -465,6 +471,12 @@ const struct fw_address_region fw_unit_space_region =
{ .start = 0xfffff0000900ULL, .end = 0x1000000000000ULL, };
#endif /* 0 */

static bool is_in_fcp_region(u64 offset, size_t length)
{
return offset >= (CSR_REGISTER_BASE | CSR_FCP_COMMAND) &&
offset + length <= (CSR_REGISTER_BASE | CSR_FCP_END);
}

/**
* fw_core_add_address_handler - register for incoming requests
* @handler: callback
Expand All @@ -477,8 +489,11 @@ const struct fw_address_region fw_unit_space_region =
* give the details of the particular request.
*
* Return value: 0 on success, non-zero otherwise.
*
* The start offset of the handler's address region is determined by
* fw_core_add_address_handler() and is returned in handler->offset.
*
* Address allocations are exclusive, except for the FCP registers.
*/
int fw_core_add_address_handler(struct fw_address_handler *handler,
const struct fw_address_region *region)
Expand All @@ -498,10 +513,12 @@ int fw_core_add_address_handler(struct fw_address_handler *handler,

handler->offset = region->start;
while (handler->offset + handler->length <= region->end) {
other =
lookup_overlapping_address_handler(&address_handler_list,
handler->offset,
handler->length);
if (is_in_fcp_region(handler->offset, handler->length))
other = NULL;
else
other = lookup_overlapping_address_handler
(&address_handler_list,
handler->offset, handler->length);
if (other != NULL) {
handler->offset += other->length;
} else {
Expand Down Expand Up @@ -668,6 +685,9 @@ static struct fw_request *allocate_request(struct fw_packet *p)
void fw_send_response(struct fw_card *card,
struct fw_request *request, int rcode)
{
if (WARN_ONCE(!request, "invalid for FCP address handlers"))
return;

/* unified transaction or broadcast transaction: don't respond */
if (request->ack != ACK_PENDING ||
HEADER_DESTINATION_IS_BROADCAST(request->request_header[0])) {
Expand All @@ -686,26 +706,15 @@ void fw_send_response(struct fw_card *card,
}
EXPORT_SYMBOL(fw_send_response);

void fw_core_handle_request(struct fw_card *card, struct fw_packet *p)
static void handle_exclusive_region_request(struct fw_card *card,
struct fw_packet *p,
struct fw_request *request,
unsigned long long offset)
{
struct fw_address_handler *handler;
struct fw_request *request;
unsigned long long offset;
unsigned long flags;
int tcode, destination, source;

if (p->ack != ACK_PENDING && p->ack != ACK_COMPLETE)
return;

request = allocate_request(p);
if (request == NULL) {
/* FIXME: send statically allocated busy packet. */
return;
}

offset =
((unsigned long long)
HEADER_GET_OFFSET_HIGH(p->header[1]) << 32) | p->header[2];
tcode = HEADER_GET_TCODE(p->header[0]);
destination = HEADER_GET_DESTINATION(p->header[0]);
source = HEADER_GET_SOURCE(p->header[1]);
Expand All @@ -732,6 +741,73 @@ void fw_core_handle_request(struct fw_card *card, struct fw_packet *p)
request->data, request->length,
handler->callback_data);
}

static void handle_fcp_region_request(struct fw_card *card,
struct fw_packet *p,
struct fw_request *request,
unsigned long long offset)
{
struct fw_address_handler *handler;
unsigned long flags;
int tcode, destination, source;

if ((offset != (CSR_REGISTER_BASE | CSR_FCP_COMMAND) &&
offset != (CSR_REGISTER_BASE | CSR_FCP_RESPONSE)) ||
request->length > 0x200) {
fw_send_response(card, request, RCODE_ADDRESS_ERROR);

return;
}

tcode = HEADER_GET_TCODE(p->header[0]);
destination = HEADER_GET_DESTINATION(p->header[0]);
source = HEADER_GET_SOURCE(p->header[1]);

if (tcode != TCODE_WRITE_QUADLET_REQUEST &&
tcode != TCODE_WRITE_BLOCK_REQUEST) {
fw_send_response(card, request, RCODE_TYPE_ERROR);

return;
}

spin_lock_irqsave(&address_handler_lock, flags);
list_for_each_entry(handler, &address_handler_list, link) {
if (is_enclosing_handler(handler, offset, request->length))
handler->address_callback(card, NULL, tcode,
destination, source,
p->generation, p->speed,
offset, request->data,
request->length,
handler->callback_data);
}
spin_unlock_irqrestore(&address_handler_lock, flags);

fw_send_response(card, request, RCODE_COMPLETE);
}

void fw_core_handle_request(struct fw_card *card, struct fw_packet *p)
{
struct fw_request *request;
unsigned long long offset;

if (p->ack != ACK_PENDING && p->ack != ACK_COMPLETE)
return;

request = allocate_request(p);
if (request == NULL) {
/* FIXME: send statically allocated busy packet. */
return;
}

offset = ((u64)HEADER_GET_OFFSET_HIGH(p->header[1]) << 32) |
p->header[2];

if (!is_in_fcp_region(offset, request->length))
handle_exclusive_region_request(card, p, request, offset);
else
handle_fcp_region_request(card, p, request, offset);

}
EXPORT_SYMBOL(fw_core_handle_request);

void fw_core_handle_response(struct fw_card *card, struct fw_packet *p)
Expand Down
4 changes: 3 additions & 1 deletion drivers/firewire/ohci.c
Original file line number Diff line number Diff line change
Expand Up @@ -2226,7 +2226,6 @@ static int ohci_queue_iso_receive_dualbuffer(struct fw_iso_context *base,
if (rest == 0)
return -EINVAL;

/* FIXME: make packet-per-buffer/dual-buffer a context option */
while (rest > 0) {
d = context_get_descriptors(&ctx->context,
z + header_z, &d_bus);
Expand Down Expand Up @@ -2470,7 +2469,10 @@ static int __devinit pci_probe(struct pci_dev *dev,
}

version = reg_read(ohci, OHCI1394_Version) & 0x00ff00ff;
#if 0
/* FIXME: make it a context option or remove dual-buffer mode */
ohci->use_dualbuffer = version >= OHCI_VERSION_1_1;
#endif

/* dual-buffer mode is broken if more than one IR context is active */
if (dev->vendor == PCI_VENDOR_ID_AGERE &&
Expand Down
Loading

0 comments on commit b7bfb2a

Please sign in to comment.