Commit Graph

30 Commits

Author SHA1 Message Date
Stefan Richter
0244f57302 firewire: cdev: count references of cards during inbound transactions
If a request comes in to an address range managed by a userspace driver
i.e. <linux/firewire-cdev.h> client, the card instance of request and
response may differ from the card instance of the client device.
Therefore we need to take a reference of the card until the response was
sent.

I thought about putting the reference counting into core-transaction.c,
but the various high-level drivers besides cdev clients (firewire-net,
firewire-sbp2, firedtv) use the card pointer in their fw_address_handler
address_callback method only to look up devices of which they already
hold the necessary references.  So this seems to be a specific
firewire-cdev issue which is better addressed locally.

We do not need the reference
  - in case of FCP_REQUEST or FCP_RESPONSE requests because then the
    firewire-core will send the split transaction response for us
    already in the context of the request handler,
  - if it is the same card as the client device's because we hold a
    card reference indirectly via teh client->device reference.
To keep things simple, we take the reference nevertheless.

Jay Fenlason wrote:
> there's no way for the core to tell cdev "this card is gone,
> kill any inbound transactions on it", while cdev holds the transaction
> open until userspace issues a SEND_RESPONSE ioctl, which may be a very,
> very long time.  But when it does, it calls fw_send_response(), which
> will dereference the card...
>
> So how unhappy are we about userspace potentially holding a fw_card
> open forever?

While termination of inbound transcations at card removal could be
implemented, it is IMO not worth the effort.  Currently, the effect of
holding a reference of a card that has been removed is to block the
process that called the pci_remove of the card.  This is
  - either a user process ran by root.  Root can find and kill processes
    that have /dev/fw* open, if desired.
  - a kernel thread (which one?) in case of hot removal of a PCCard or
    ExpressCard.
The latter case could be a problem indeed.  firewire-core's card
shutdown and card release should probably be improved not to block in
shutdown, just to defer freeing of memory until release.

This is not a new problem though; the same already always happens with
the client->device->card without the need of inbound transactions or
other special conditions involved, other than the client not closing the
file.

Signed-off-by: Stefan Richter <stefanr@s5r6.in-berlin.de>
2010-06-20 23:11:56 +02:00
Jay Fenlason
08bd34c98d firewire: cdev: fix responses to nodes at different card
My box has two firewire cards in it: card0 and card1.
My application opens /dev/fw0 (card 0) and allocates an address space.
The core makes the address space available on both cards.
Along comes the remote device, which sends a READ_QUADLET_REQUEST to
card1.  The request gets passed up to my application, which calls
ioctl_send_response().

ioctl_send_response() then calls fw_send_response() with card0,
because that's the card it's bound to.
Card0's driver drops the response, because it isn't part of
a transaction that it has outstanding.

So in core-cdev: handle_request(), we need to stash the
card of the inbound request in the struct inbound_transaction_resource and
use that card to send the response to.

The hard part will be refcounting the card correctly
so it can't get deallocated while we hold a pointer to it.

Here's a trivial patch, which does not do the card refcounting, but at
least demonstrates what the problem is.

Note that we can't depend on the fact that the core-cdev:client
structure holds a card open, because in this case the card it holds
open is not the card the request came in on.

..and there's no way for the core to tell cdev "this card is gone,
kill any inbound transactions on it", while cdev holds the transaction
open until userspace issues a SEND_RESPONSE ioctl, which may be a very,
very long time.  But when it does, it calls fw_send_response(), which
will dereference the card...

So how unhappy are we about userspace potentially holding a fw_card
open forever?

Signed-off-by: Jay Fenlason <fenlason@redhat.com>

Reference counting to be addressed in a separate change.

Signed-off-by: Stefan Richter <stefanr@s5r6.in-berlin.de> (whitespace)
2010-06-20 23:11:56 +02:00
Clemens Ladisch
bdfe273ee5 firewire: cdev: fix race in iso context creation
Protect the client's iso context pointer against a race that can happen
when more than one creation call is executed at the same time.

Signed-off-by: Clemens Ladisch <clemens@ladisch.de>
Signed-off-by: Stefan Richter <stefanr@s5r6.in-berlin.de>
2010-06-20 23:11:56 +02:00
Stefan Richter
33e553fe2b firewire: remove an unused function argument
void (*fw_address_callback_t)(..., int speed, ...) is the speed that a
remote node chose to transmit a request to us.  In case of split
transactions, firewire-core will transmit the response at that speed.

Upper layer drivers on the other hand (firewire-net, -sbp2, firedtv, and
userspace drivers) cannot do anything useful with that speed datum,
except log it for debug purposes.  But data that is merely potentially
(not even actually) used for debug purposes does not belong into the API.

Signed-off-by: Stefan Richter <stefanr@s5r6.in-berlin.de>
2010-06-20 23:11:55 +02:00
Stefan Richter
56d04cb189 firewire: core: remove an unnecessary zero initialization
All of the fields of the iso_interrupt_event instance are overwritten
right after it was allocated.

Signed-off-by: Stefan Richter <stefanr@s5r6.in-berlin.de>
2010-06-20 17:06:25 +02:00
Stefan Richter
0fcff4e393 firewire: rename CSR access driver methods
Rather than "read a Control and Status Registers (CSR) Architecture
register" I prefer to say "read a Control and Status Register".

Signed-off-by: Stefan Richter <stefanr@s5r6.in-berlin.de>
2010-06-19 13:01:41 +02:00
Clemens Ladisch
60d32970c5 firewire: add read_csr_reg driver callback
To prepare for the following additions of more OHCI-implemented CSR
registers, replace the get_cycle_time driver callback with a generic
CSR register callback.

Signed-off-by: Clemens Ladisch <clemens@ladisch.de>
2010-06-10 08:24:35 +02:00
Clemens Ladisch
a10c0ce760 firewire: check cdev response length
Add a check that the data length in the SEND_RESPONSE ioctl is correct.
Incidentally, this also fixes the previously wrong response length of
software-handled lock requests.

Signed-off-by: Clemens Ladisch <clemens@ladisch.de>
Signed-off-by: Stefan Richter <stefanr@s5r6.in-berlin.de>
2010-06-09 19:42:18 +02:00
Stefan Richter
3ac26b2ee3 firewire: cdev: mark char device files as not seekable
The <linux/firewire-cdev.h> character device file ABI (i.e. /dev/fw*
character device file interface) does not make any use of lseek(),
pread(), pwrite() (or any kind of write() at all).

Use nonseekable_open() and, redundantly, set file_operations.llseek to
no_llseek to remove any doubt whether the BKL-grabbing default_llseek
handler is used.  (Also shuffle file_operations initialization according
to the order of handler definitions.)

Signed-off-by: Stefan Richter <stefanr@s5r6.in-berlin.de>
2010-04-10 16:51:14 +02:00
Stefan Richter
9cac00b8f0 firewire: cdev: fix information leak
A userspace client got to see uninitialized stack-allocated memory if it
specified an _IOC_READ type of ioctl and an argument size larger than
expected by firewire-core's ioctl handlers (but not larger than the
core's union ioctl_arg).

Fix this by clearing the requested buffer size to zero, but only at _IOR
ioctls.  This way, there is almost no runtime penalty to legitimate
ioctls.  The only legitimate _IOR is FW_CDEV_IOC_GET_CYCLE_TIMER with 12
or 16 bytes to memset.

[Another way to fix this would be strict checking of argument size (and
possibly direction) vs. command number.  However, we then need a lookup
table, and we need to allow for slight size deviations in case of 32bit
userland on 64bit kernel.]

Reported-by: Clemens Ladisch <clemens@ladisch.de>
Signed-off-by: Stefan Richter <stefanr@s5r6.in-berlin.de>
2010-04-10 16:51:13 +02:00
Clemens Ladisch
385ab5bcd4 firewire: cdev: require quadlet-aligned headers for transmit packets
The definition of struct fw_cdev_iso_packet seems to imply that the
header_length must be quadlet-aligned, and in fact, specifying an
unaligned header has never really worked when using multiple packet
structures, because the position of the next control word is computed by
rounding the header_length _down_, so the last one to three bytes of the
header would overlap the next control word.

To avoid this problem, check that the header length is properly aligned.

Signed-off-by: Clemens Ladisch <clemens@ladisch.de>
Signed-off-by: Stefan Richter <stefanr@s5r6.in-berlin.de>
2010-04-10 16:51:13 +02:00
Clemens Ladisch
4ba1d9c0c2 firewire: cdev: disallow receive packets without header
In receive contexts, reject packets with header_length==0.  This would
be an instruction to queue zero packets which would not make sense.

This prevents a division by zero in the OHCI driver.

Signed-off-by: Clemens Ladisch <clemens@ladisch.de>
Signed-off-by: Stefan Richter <stefanr@s5r6.in-berlin.de>
2010-04-10 16:51:13 +02:00
Stefan Richter
64582298b9 firewire: core: combine a bit of repeated code
Signed-off-by: Stefan Richter <stefanr@s5r6.in-berlin.de>
2010-02-24 20:36:55 +01:00
Stefan Richter
6e95dea728 firewire: core: change type of a data buffer
from array of char to union of structs.  I already used a union to size
the buffer which holds ioctl arguments; more consequent is to define it
as an instance of this union in the first place.

Also rename several local variables from "request" to "a"(rgument) since
the term request can be mistaken to mean a transaction subaction, e.g.
an instance of struct fw_request.

Signed-off-by: Stefan Richter <stefanr@s5r6.in-berlin.de>
2010-02-24 20:36:55 +01:00
Stefan Richter
abfe5a01ef firewire: cdev: add more flexible cycle timer ioctl
The system time from CLOCK_REALTIME is not monotonic, hence problematic
for the main user of the FW_CDEV_IOC_GET_CYCLE_TIMER ioctl.  This issue
exists in its successor ABI, i.e. raw1394, too.
http://subversion.ffado.org/ticket/242

We now offer an alternative ioctl which lets the caller choose between
CLOCK_REALTIME, CLOCK_MONOTONIC, and CLOCK_MONOTONIC_RAW as source of
the local time, very similar to the clock_gettime libc function.  The
format of the local time return value matches that of clock_gettime
(seconds and nanoseconds, instead of a single microseconds value from
the existing ioctl).

Signed-off-by: Stefan Richter <stefanr@s5r6.in-berlin.de>
2010-02-24 20:36:54 +01:00
Stefan Richter
109d28152b Merge tag 'v2.6.33' for its firewire changes since last branch point
Signed-off-by: Stefan Richter <stefanr@s5r6.in-berlin.de>
2010-02-24 20:33:45 +01:00
Stefan Richter
168cf9af69 firewire: remove incomplete Bus_Time CSR support
The current implementation of Bus_Time read access was buggy since it
did not ensure that Bus_Time.second_count_hi and second_count_lo came
from the same 128 seconds period.

Reported-by: Håkan Johansson <f96hajo@chalmers.se>

Instead of a fix, remove Bus_Time register support altogether.  The spec
requires all cycle master capable nodes to implement this (all Linux
nodes are cycle master capable) while it also says that it "may" be
initialized by the bus manager or by the IRM standing in for a bus
manager.  (Neither Linux' firewire-core nor ieee1394 nodemgr implement
this.)

Since we cannot rely on Bus_Time having been initialized by a bus
manager, it is better to return an error instead of a nonsensical value
on a read request to Bus_Time.

Alternatively, we could fix the Bus_Time read integrity bug _and_
implement (a) cycle master's write support of the register as well as
(b) bus manager's Bus_Time initialization service, i.e. preservation of
the Bus_Time when the cycle master node of a bus changes.  However, that
would be quite some code for a feature that is unreliable to begin with
and very likely unused in practice.

Signed-off-by: Stefan Richter <stefanr@s5r6.in-berlin.de>
2010-02-20 22:33:14 +01:00
Stefan Richter
4a9bde9b8a firewire: get_cycle_timer optimization and cleanup
ohci:  Break out of the retry loop if too many attempts were necessary.
This may theoretically happen if the chip is fatally defective or if the
get_cycle_timer ioctl was performed after a CardBus controller was
ejected.

Also micro-optimize the loop by re-using the last two register reads in
the next iteration, remove a questionable inline keyword, and shuffle a
comment around.

core:  ioctl_get_cycle_timer() is always called with interrupts on,
therefore local_irq_save() can be replaced by local_irq_disable().
Disabled local IRQs imply disabled preemption, hence preempt_disable()
can be removed.

Signed-off-by: Stefan Richter <stefanr@s5r6.in-berlin.de>
2010-02-20 22:33:13 +01:00
Stefan Richter
281e20323a firewire: core: fix use-after-free regression in FCP handler
Commit db5d247a "firewire: fix use of multiple AV/C devices, allow
multiple FCP listeners" introduced a regression into 2.6.33-rc3:
The core freed payloads of incoming requests to FCP_Request or
FCP_Response before a userspace driver accessed them.

We need to copy such payloads for each registered userspace client
and free the copies according to the lifetime rules of non-FCP client
request resources.

(This could possibly be optimized by reference counts instead of
copies.)

The presently only kernelspace driver which listens for FCP requests,
firedtv, was not affected because it already copies FCP frames into an
own buffer before returning to firewire-core's FCP handler dispatcher.

Signed-off-by: Stefan Richter <stefanr@s5r6.in-berlin.de>
2010-01-26 20:54:50 +01:00
Stefan Richter
cf0e575dcc firewire: cdev: fix another memory leak in an error path
If copy_from_user in an FW_CDEV_IOC_SEND_RESPONSE ioctl failed, the
fw_request pointed to by the inbound_transaction_resource is no
longer referenced and needs to be freed.

Signed-off-by: Stefan Richter <stefanr@s5r6.in-berlin.de>
2009-12-29 19:58:16 +01:00
Clemens Ladisch
db5d247ae8 firewire: fix use of multiple AV/C devices, allow multiple FCP listeners
Control of more than one AV/C device at once --- e.g. camcorders, tape
decks, audio devices, TV tuners --- failed or worked only unreliably,
depending on driver implementation.  This affected kernelspace and
userspace drivers alike and was caused by firewire-core's inability to
accept multiple registrations of FCP listeners.

The fix allows multiple address handlers to be registered for the FCP
command and response registers.  When a request for these registers is
received, all handlers are invoked, and the Firewire response is
generated by the core and not by any handler.

The cdev API does not change, i.e., userspace is still expected to send
a response for FCP requests; this response is silently ignored.

Signed-off-by: Clemens Ladisch <clemens@ladisch.de>
Signed-off-by: Stefan Richter <stefanr@s5r6.in-berlin.de> (changelog, rebased, whitespace)
2009-12-29 19:58:16 +01:00
Linus Torvalds
bb592cf474 Merge branch 'for-linus' of git://git.kernel.org/pub/scm/linux/kernel/git/ieee1394/linux1394-2.6
* 'for-linus' of git://git.kernel.org/pub/scm/linux/kernel/git/ieee1394/linux1394-2.6:
  ieee1394: Use hweight32
  firewire: cdev: reduce stack usage by ioctl_dispatch
  firewire: ohci: 0 may be a valid DMA address
  firewire: core: WARN on wrong usage of core transaction functions
  firewire: core: optimize Topology Map creation
  firewire: core: clarify generate_config_rom usage
  firewire: optimize config ROM creation
  firewire: cdev: normalize variable names
  firewire: normalize style of queue_work wrappers
  firewire: cdev: fix memory leak in an error path
2009-12-08 08:13:10 -08:00
Stefan Richter
b2c0a2ac3e firewire: cdev: reduce stack usage by ioctl_dispatch
Replace a hardcoded buffer size by a sizeof union {}.  This shrinks the
stack-allocated ioctl argument buffer from 256 to 40 bytes.  (This is
not much, but subsequent stack usage particularly by the queue_iso ioctl
handler adds up.)

The new form is also easier to keep up to date than a hardcoded size if
more ioctls are added.

Signed-off-by: Stefan Richter <stefanr@s5r6.in-berlin.de>
2009-10-31 11:40:52 +01:00
Stefan Richter
e21fcf798e firewire: cdev: normalize variable names
Unify some names:
  - "e" for pointers to subtypes of struct event,
  - "event" for struct members and pointers to struct event,
  - "r" for pointers to subtypes of struct client_resource,
  - "resource" for struct members and pointers to struct client_resource,
  - other names for struct members and pointers to other types.

Signed-off-by: Stefan Richter <stefanr@s5r6.in-berlin.de>
2009-10-14 23:10:48 +02:00
Stefan Richter
9fb551bf72 firewire: normalize style of queue_work wrappers
A few stylistic changes to unify some code patterns in the subsystem:

  - The similar queue_delayed_work helpers fw_schedule_bm_work,
    schedule_iso_resource, and sbp2_queue_work now have the same call
    convention.
  - Two conditional calls of schedule_iso_resource are factored into
    another small helper.
  - An sbp2_target_get helper is added as counterpart to
    sbp2_target_put.

Object size of firewire-core is decreased a little bit, object size of
firewire-sbp2 remains unchanged.

Signed-off-by: Stefan Richter <stefanr@s5r6.in-berlin.de>
2009-10-14 23:10:48 +02:00
Stefan Richter
7e44c0b56b firewire: cdev: fix memory leak in an error path
If copy_from_user in an FW_CDEV_IOC_SEND_RESPONSE ioctl failed, an
inbound_transaction_resource instance is no longer referenced and needs
to be freed.

Signed-off-by: Stefan Richter <stefanr@s5r6.in-berlin.de>
2009-10-14 21:55:19 +02:00
Alexey Dobriyan
a99bbaf5ee headers: remove sched.h from poll.h
Signed-off-by: Alexey Dobriyan <adobriyan@gmail.com>
Signed-off-by: Linus Torvalds <torvalds@linux-foundation.org>
2009-10-04 15:05:10 -07:00
Stefan Richter
6fdc037094 firewire: core: do not DMA-map stack addresses
The DMA mapping API cannot map on-stack addresses, as explained in
Documentation/DMA-mapping.txt.  Convert the two cases of on-stack packet
payload buffers in firewire-core (payload of lock requests in the bus
manager work and in iso resource management) to slab-allocated memory.

There are a number on-stack buffers for quadlet write or quadlet read
requests in firewire-core and firewire-sbp2.  These are harmless; they
are copied to/ from card driver internal DMA buffers since quadlet
payloads are inlined with packet headers.

Signed-off-by: Stefan Richter <stefanr@s5r6.in-berlin.de>
2009-06-25 19:42:36 +02:00
Stefan Richter
e034d24259 firewire: core: include linux/uaccess.h instead of asm/uaccess.h
Signed-off-by: Stefan Richter <stefanr@s5r6.in-berlin.de>
2009-06-06 21:45:50 +02:00
Stefan Richter
e71d31da06 firewire: rename source files
The source files of firewire-core, firewire-ohci, firewire-sbp2, i.e.
 "drivers/firewire/fw-*.c"
are renamed to
 "drivers/firewire/core-*.c",
 "drivers/firewire/ohci.c",
 "drivers/firewire/sbp2.c".

The old fw- prefix was redundant to the directory name.  The new core-
prefix distinguishes the files according to which driver they belong to.

This change comes a little late, but still before further firewire
drivers are added as anticipated RSN.

Signed-off-by: Stefan Richter <stefanr@s5r6.in-berlin.de>
2009-06-05 16:26:18 +02:00