Commit f83b1e61 authored by Linus Torvalds's avatar Linus Torvalds

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:
  firewire: core: use more outbound tlabels
  firewire: core: don't update Broadcast_Channel if RFC 2734 conditions aren't met
  firewire: core: prepare for non-core children of card devices
  firewire: core: include linux/uaccess.h instead of asm/uaccess.h
  firewire: add parent-of-unit accessor
  firewire: rename source files
  firewire: reorganize header files
  firewire: clean up includes
  firewire: ohci: access bus_seconds atomically
  firewire: also use vendor ID in root directory for driver matches
  firewire: share device ID table type with ieee1394
  firewire: core: add sysfs attribute for easier udev rules
  firewire: core: check for missing struct update at build time, not run time
  firewire: core: improve check for local node
parents 2f38d70f 1e626fdc
......@@ -2,10 +2,10 @@
# Makefile for the Linux IEEE 1394 implementation
#
firewire-core-y += fw-card.o fw-topology.o fw-transaction.o fw-iso.o \
fw-device.o fw-cdev.o
firewire-ohci-y += fw-ohci.o
firewire-sbp2-y += fw-sbp2.o
firewire-core-y += core-card.o core-cdev.o core-device.o \
core-iso.o core-topology.o core-transaction.o
firewire-ohci-y += ohci.o
firewire-sbp2-y += sbp2.o
obj-$(CONFIG_FIREWIRE) += firewire-core.o
obj-$(CONFIG_FIREWIRE_OHCI) += firewire-ohci.o
......
......@@ -16,18 +16,27 @@
* Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
*/
#include <linux/bug.h>
#include <linux/completion.h>
#include <linux/crc-itu-t.h>
#include <linux/delay.h>
#include <linux/device.h>
#include <linux/errno.h>
#include <linux/firewire.h>
#include <linux/firewire-constants.h>
#include <linux/jiffies.h>
#include <linux/kernel.h>
#include <linux/kref.h>
#include <linux/list.h>
#include <linux/module.h>
#include <linux/mutex.h>
#include <linux/spinlock.h>
#include <linux/timer.h>
#include <linux/workqueue.h>
#include "fw-transaction.h"
#include "fw-topology.h"
#include "fw-device.h"
#include <asm/atomic.h>
#include <asm/byteorder.h>
#include "core.h"
int fw_compute_block_crc(u32 *block)
{
......@@ -181,12 +190,6 @@ void fw_core_remove_descriptor(struct fw_descriptor *desc)
mutex_unlock(&card_mutex);
}
static int set_broadcast_channel(struct device *dev, void *data)
{
fw_device_set_broadcast_channel(fw_device(dev), (long)data);
return 0;
}
static void allocate_broadcast_channel(struct fw_card *card, int generation)
{
int channel, bandwidth = 0;
......@@ -196,7 +199,7 @@ static void allocate_broadcast_channel(struct fw_card *card, int generation)
if (channel == 31) {
card->broadcast_channel_allocated = true;
device_for_each_child(card->device, (void *)(long)generation,
set_broadcast_channel);
fw_device_set_broadcast_channel);
}
}
......
......@@ -22,6 +22,7 @@
#include <linux/delay.h>
#include <linux/device.h>
#include <linux/errno.h>
#include <linux/firewire.h>
#include <linux/firewire-cdev.h>
#include <linux/idr.h>
#include <linux/jiffies.h>
......@@ -34,16 +35,14 @@
#include <linux/preempt.h>
#include <linux/spinlock.h>
#include <linux/time.h>
#include <linux/uaccess.h>
#include <linux/vmalloc.h>
#include <linux/wait.h>
#include <linux/workqueue.h>
#include <asm/system.h>
#include <asm/uaccess.h>
#include "fw-device.h"
#include "fw-topology.h"
#include "fw-transaction.h"
#include "core.h"
struct client {
u32 version;
......@@ -739,15 +738,11 @@ static void release_descriptor(struct client *client,
static int ioctl_add_descriptor(struct client *client, void *buffer)
{
struct fw_cdev_add_descriptor *request = buffer;
struct fw_card *card = client->device->card;
struct descriptor_resource *r;
int ret;
/* Access policy: Allow this ioctl only on local nodes' device files. */
spin_lock_irq(&card->lock);
ret = client->device->node_id != card->local_node->node_id;
spin_unlock_irq(&card->lock);
if (ret)
if (!client->device->is_local)
return -ENOSYS;
if (request->length > 256)
......
......@@ -22,10 +22,14 @@
#include <linux/delay.h>
#include <linux/device.h>
#include <linux/errno.h>
#include <linux/firewire.h>
#include <linux/firewire-constants.h>
#include <linux/idr.h>
#include <linux/jiffies.h>
#include <linux/kobject.h>
#include <linux/list.h>
#include <linux/mod_devicetable.h>
#include <linux/module.h>
#include <linux/mutex.h>
#include <linux/rwsem.h>
#include <linux/semaphore.h>
......@@ -33,11 +37,11 @@
#include <linux/string.h>
#include <linux/workqueue.h>
#include <asm/atomic.h>
#include <asm/byteorder.h>
#include <asm/system.h>
#include "fw-device.h"
#include "fw-topology.h"
#include "fw-transaction.h"
#include "core.h"
void fw_csr_iterator_init(struct fw_csr_iterator *ci, u32 * p)
{
......@@ -55,9 +59,10 @@ int fw_csr_iterator_next(struct fw_csr_iterator *ci, int *key, int *value)
}
EXPORT_SYMBOL(fw_csr_iterator_next);
static int is_fw_unit(struct device *dev);
static bool is_fw_unit(struct device *dev);
static int match_unit_directory(u32 * directory, const struct fw_device_id *id)
static int match_unit_directory(u32 *directory, u32 match_flags,
const struct ieee1394_device_id *id)
{
struct fw_csr_iterator ci;
int key, value, match;
......@@ -65,31 +70,42 @@ static int match_unit_directory(u32 * directory, const struct fw_device_id *id)
match = 0;
fw_csr_iterator_init(&ci, directory);
while (fw_csr_iterator_next(&ci, &key, &value)) {
if (key == CSR_VENDOR && value == id->vendor)
match |= FW_MATCH_VENDOR;
if (key == CSR_MODEL && value == id->model)
match |= FW_MATCH_MODEL;
if (key == CSR_VENDOR && value == id->vendor_id)
match |= IEEE1394_MATCH_VENDOR_ID;
if (key == CSR_MODEL && value == id->model_id)
match |= IEEE1394_MATCH_MODEL_ID;
if (key == CSR_SPECIFIER_ID && value == id->specifier_id)
match |= FW_MATCH_SPECIFIER_ID;
match |= IEEE1394_MATCH_SPECIFIER_ID;
if (key == CSR_VERSION && value == id->version)
match |= FW_MATCH_VERSION;
match |= IEEE1394_MATCH_VERSION;
}
return (match & id->match_flags) == id->match_flags;
return (match & match_flags) == match_flags;
}
static int fw_unit_match(struct device *dev, struct device_driver *drv)
{
struct fw_unit *unit = fw_unit(dev);
struct fw_driver *driver = fw_driver(drv);
int i;
struct fw_device *device;
const struct ieee1394_device_id *id;
/* We only allow binding to fw_units. */
if (!is_fw_unit(dev))
return 0;
for (i = 0; driver->id_table[i].match_flags != 0; i++) {
if (match_unit_directory(unit->directory, &driver->id_table[i]))
device = fw_parent_device(unit);
id = container_of(drv, struct fw_driver, driver)->id_table;
for (; id->match_flags != 0; id++) {
if (match_unit_directory(unit->directory, id->match_flags, id))
return 1;
/* Also check vendor ID in the root directory. */
if ((id->match_flags & IEEE1394_MATCH_VENDOR_ID) &&
match_unit_directory(&device->config_rom[5],
IEEE1394_MATCH_VENDOR_ID, id) &&
match_unit_directory(unit->directory, id->match_flags
& ~IEEE1394_MATCH_VENDOR_ID, id))
return 1;
}
......@@ -98,7 +114,7 @@ static int fw_unit_match(struct device *dev, struct device_driver *drv)
static int get_modalias(struct fw_unit *unit, char *buffer, size_t buffer_size)
{
struct fw_device *device = fw_device(unit->device.parent);
struct fw_device *device = fw_parent_device(unit);
struct fw_csr_iterator ci;
int key, value;
......@@ -292,8 +308,7 @@ static void init_fw_attribute_group(struct device *dev,
group->attrs[j++] = &attr->attr;
}
BUG_ON(j >= ARRAY_SIZE(group->attrs));
group->attrs[j++] = NULL;
group->attrs[j] = NULL;
group->groups[0] = &group->group;
group->groups[1] = NULL;
group->group.attrs = group->attrs;
......@@ -356,9 +371,56 @@ static ssize_t guid_show(struct device *dev,
return ret;
}
static int units_sprintf(char *buf, u32 *directory)
{
struct fw_csr_iterator ci;
int key, value;
int specifier_id = 0;
int version = 0;
fw_csr_iterator_init(&ci, directory);
while (fw_csr_iterator_next(&ci, &key, &value)) {
switch (key) {
case CSR_SPECIFIER_ID:
specifier_id = value;
break;
case CSR_VERSION:
version = value;
break;
}
}
return sprintf(buf, "0x%06x:0x%06x ", specifier_id, version);
}
static ssize_t units_show(struct device *dev,
struct device_attribute *attr, char *buf)
{
struct fw_device *device = fw_device(dev);
struct fw_csr_iterator ci;
int key, value, i = 0;
down_read(&fw_device_rwsem);
fw_csr_iterator_init(&ci, &device->config_rom[5]);
while (fw_csr_iterator_next(&ci, &key, &value)) {
if (key != (CSR_UNIT | CSR_DIRECTORY))
continue;
i += units_sprintf(&buf[i], ci.p + value - 1);
if (i >= PAGE_SIZE - (8 + 1 + 8 + 1))
break;
}
up_read(&fw_device_rwsem);
if (i)
buf[i - 1] = '\n';
return i;
}
static struct device_attribute fw_device_attributes[] = {
__ATTR_RO(config_rom),
__ATTR_RO(guid),
__ATTR_RO(units),
__ATTR_NULL,
};
......@@ -518,7 +580,9 @@ static int read_bus_info_block(struct fw_device *device, int generation)
kfree(old_rom);
ret = 0;
device->cmc = rom[2] >> 30 & 1;
device->max_rec = rom[2] >> 12 & 0xf;
device->cmc = rom[2] >> 30 & 1;
device->irmc = rom[2] >> 31 & 1;
out:
kfree(rom);
......@@ -537,7 +601,7 @@ static struct device_type fw_unit_type = {
.release = fw_unit_release,
};
static int is_fw_unit(struct device *dev)
static bool is_fw_unit(struct device *dev)
{
return dev->type == &fw_unit_type;
}
......@@ -570,9 +634,13 @@ static void create_units(struct fw_device *device)
unit->device.parent = &device->device;
dev_set_name(&unit->device, "%s.%d", dev_name(&device->device), i++);
BUILD_BUG_ON(ARRAY_SIZE(unit->attribute_group.attrs) <
ARRAY_SIZE(fw_unit_attributes) +
ARRAY_SIZE(config_rom_attributes));
init_fw_attribute_group(&unit->device,
fw_unit_attributes,
&unit->attribute_group);
if (device_register(&unit->device) < 0)
goto skip_unit;
......@@ -683,6 +751,11 @@ static struct device_type fw_device_type = {
.release = fw_device_release,
};
static bool is_fw_device(struct device *dev)
{
return dev->type == &fw_device_type;
}
static int update_unit(struct device *dev, void *data)
{
struct fw_unit *unit = fw_unit(dev);
......@@ -719,6 +792,9 @@ static int lookup_existing_device(struct device *dev, void *data)
struct fw_card *card = new->card;
int match = 0;
if (!is_fw_device(dev))
return 0;
down_read(&fw_device_rwsem); /* serialize config_rom access */
spin_lock_irq(&card->lock); /* serialize node access */
......@@ -758,7 +834,7 @@ static int lookup_existing_device(struct device *dev, void *data)
enum { BC_UNKNOWN = 0, BC_UNIMPLEMENTED, BC_IMPLEMENTED, };
void fw_device_set_broadcast_channel(struct fw_device *device, int generation)
static void set_broadcast_channel(struct fw_device *device, int generation)
{
struct fw_card *card = device->card;
__be32 data;
......@@ -767,6 +843,20 @@ void fw_device_set_broadcast_channel(struct fw_device *device, int generation)
if (!card->broadcast_channel_allocated)
return;
/*
* The Broadcast_Channel Valid bit is required by nodes which want to
* transmit on this channel. Such transmissions are practically
* exclusive to IP over 1394 (RFC 2734). IP capable nodes are required
* to be IRM capable and have a max_rec of 8 or more. We use this fact
* to narrow down to which nodes we send Broadcast_Channel updates.
*/
if (!device->irmc || device->max_rec < 8)
return;
/*
* Some 1394-1995 nodes crash if this 1394a-2000 register is written.
* Perform a read test first.
*/
if (device->bc_implemented == BC_UNKNOWN) {
rcode = fw_run_transaction(card, TCODE_READ_QUADLET_REQUEST,
device->node_id, generation, device->max_speed,
......@@ -794,6 +884,14 @@ void fw_device_set_broadcast_channel(struct fw_device *device, int generation)
}
}
int fw_device_set_broadcast_channel(struct device *dev, void *gen)
{
if (is_fw_device(dev))
set_broadcast_channel(fw_device(dev), (long)gen);
return 0;
}
static void fw_device_init(struct work_struct *work)
{
struct fw_device *device =
......@@ -849,9 +947,13 @@ static void fw_device_init(struct work_struct *work)
device->device.devt = MKDEV(fw_cdev_major, minor);
dev_set_name(&device->device, "fw%d", minor);
BUILD_BUG_ON(ARRAY_SIZE(device->attribute_group.attrs) <
ARRAY_SIZE(fw_device_attributes) +
ARRAY_SIZE(config_rom_attributes));
init_fw_attribute_group(&device->device,
fw_device_attributes,
&device->attribute_group);
if (device_add(&device->device)) {
fw_error("Failed to add device.\n");
goto error_with_cdev;
......@@ -888,7 +990,7 @@ static void fw_device_init(struct work_struct *work)
1 << device->max_speed);
device->config_rom_retries = 0;
fw_device_set_broadcast_channel(device, device->generation);
set_broadcast_channel(device, device->generation);
}
/*
......@@ -993,6 +1095,9 @@ static void fw_device_refresh(struct work_struct *work)
create_units(device);
/* Userspace may want to re-read attributes. */
kobject_uevent(&device->device.kobj, KOBJ_CHANGE);
if (atomic_cmpxchg(&device->state,
FW_DEVICE_INITIALIZING,
FW_DEVICE_RUNNING) == FW_DEVICE_GONE)
......@@ -1042,6 +1147,7 @@ void fw_node_event(struct fw_card *card, struct fw_node *node, int event)
device->node = fw_node_get(node);
device->node_id = node->node_id;
device->generation = card->generation;
device->is_local = node == card->local_node;
mutex_init(&device->client_list_mutex);
INIT_LIST_HEAD(&device->client_list);
......@@ -1075,7 +1181,7 @@ void fw_node_event(struct fw_card *card, struct fw_node *node, int event)
FW_DEVICE_INITIALIZING) == FW_DEVICE_RUNNING) {
PREPARE_DELAYED_WORK(&device->work, fw_device_refresh);
schedule_delayed_work(&device->work,
node == card->local_node ? 0 : INITIAL_DELAY);
device->is_local ? 0 : INITIAL_DELAY);
}
break;
......
......@@ -22,14 +22,16 @@
#include <linux/dma-mapping.h>
#include <linux/errno.h>
#include <linux/firewire.h>
#include <linux/firewire-constants.h>
#include <linux/kernel.h>
#include <linux/mm.h>
#include <linux/spinlock.h>
#include <linux/vmalloc.h>
#include "fw-topology.h"
#include "fw-transaction.h"
#include <asm/byteorder.h>
#include "core.h"
/*
* Isochronous DMA context management
......
......@@ -18,13 +18,22 @@
* Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
*/
#include <linux/module.h>
#include <linux/wait.h>
#include <linux/bug.h>
#include <linux/errno.h>
#include <asm/bug.h>
#include <linux/firewire.h>
#include <linux/firewire-constants.h>
#include <linux/jiffies.h>
#include <linux/kernel.h>
#include <linux/list.h>
#include <linux/module.h>
#include <linux/slab.h>
#include <linux/spinlock.h>
#include <linux/string.h>
#include <asm/atomic.h>
#include <asm/system.h>
#include "fw-transaction.h"
#include "fw-topology.h"
#include "core.h"
#define SELF_ID_PHY_ID(q) (((q) >> 24) & 0x3f)
#define SELF_ID_EXTENDED(q) (((q) >> 23) & 0x01)
......@@ -37,6 +46,11 @@
#define SELF_ID_EXT_SEQUENCE(q) (((q) >> 20) & 0x07)
#define SELFID_PORT_CHILD 0x3
#define SELFID_PORT_PARENT 0x2
#define SELFID_PORT_NCONN 0x1
#define SELFID_PORT_NONE 0x0
static u32 *count_ports(u32 *sid, int *total_port_count, int *child_port_count)
{
u32 q;
......
......@@ -18,24 +18,28 @@
* Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
*/
#include <linux/bug.h>
#include <linux/completion.h>
#include <linux/device.h>
#include <linux/errno.h>
#include <linux/firewire.h>
#include <linux/firewire-constants.h>
#include <linux/fs.h>
#include <linux/init.h>
#include <linux/idr.h>
#include <linux/jiffies.h>
#include <linux/kernel.h>
#include <linux/kref.h>
#include <linux/module.h>
#include <linux/mutex.h>
#include <linux/init.h>
#include <linux/interrupt.h>
#include <linux/pci.h>
#include <linux/delay.h>
#include <linux/poll.h>
#include <linux/list.h>
#include <linux/kthread.h>
#include <asm/uaccess.h>
#include <linux/module.h>
#include <linux/slab.h>
#include <linux/spinlock.h>
#include <linux/string.h>
#include <linux/timer.h>
#include <linux/types.h>
#include "fw-transaction.h"
#include "fw-topology.h"
#include "fw-device.h"
#include <asm/byteorder.h>
#include "core.h"
#define HEADER_PRI(pri) ((pri) << 0)
#define HEADER_TCODE(tcode) ((tcode) << 4)
......@@ -60,6 +64,10 @@
#define HEADER_DESTINATION_IS_BROADCAST(q) \
(((q) & HEADER_DESTINATION(0x3f)) == HEADER_DESTINATION(0x3f))
#define PHY_PACKET_CONFIG 0x0
#define PHY_PACKET_LINK_ON 0x1
#define PHY_PACKET_SELF_ID 0x2
#define PHY_CONFIG_GAP_COUNT(gap_count) (((gap_count) << 16) | (1 << 22))
#define PHY_CONFIG_ROOT_ID(node_id) ((((node_id) & 0x3f) << 24) | (1 << 23))
#define PHY_IDENTIFIER(id) ((id) << 30)
......@@ -74,7 +82,7 @@ static int close_transaction(struct fw_transaction *transaction,
list_for_each_entry(t, &card->transaction_list, link) {
if (t == transaction) {
list_del(&t->link);
card->tlabel_mask &= ~(1 << t->tlabel);
card->tlabel_mask &= ~(1ULL << t->tlabel);
break;
}
}
......@@ -280,14 +288,14 @@ void fw_send_request(struct fw_card *card, struct fw_transaction *t, int tcode,
spin_lock_irqsave(&card->lock, flags);
tlabel = card->current_tlabel;
if (card->tlabel_mask & (1 << tlabel)) {
if (card->tlabel_mask & (1ULL << tlabel)) {
spin_unlock_irqrestore(&card->lock, flags);
callback(card, RCODE_SEND_ERROR, NULL, 0, callback_data);
return;
}
card->current_tlabel = (card->current_tlabel + 1) & 0x1f;
card->tlabel_mask |= (1 << tlabel);
card->current_tlabel = (card->current_tlabel + 1) & 0x3f;
card->tlabel_mask |= (1ULL << tlabel);
t->node_id = destination_id;
t->tlabel = tlabel;
......
/*
* Copyright (C) 2003-2006 Kristian Hoegsberg <krh@bitplanet.net>
*
* This program is free software; you can redistribute it and/or modify
* it under the terms of the GNU General Public License as published by
* the Free Software Foundation; either version 2 of the License, or
* (at your option) any later version.
*
* This program is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU General Public License for more details.
*
* You should have received a copy of the GNU General Public License
* along with this program; if not, write to the Free Software Foundation,
* Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
*/
#ifndef __fw_topology_h
#define __fw_topology_h
#include <linux/list.h>
#include <linux/slab.h>
#include <asm/atomic.h>
enum {
FW_NODE_CREATED,
FW_NODE_UPDATED,
FW_NODE_DESTROYED,
FW_NODE_LINK_ON,
FW_NODE_LINK_OFF,
FW_NODE_INITIATED_RESET,
};
struct fw_node {
u16 node_id;
u8 color;
u8 port_count;
u8 link_on : 1;
u8 initiated_reset : 1;
u8 b_path : 1;
u8 phy_speed : 2; /* As in the self ID packet. */
u8 max_speed : 2; /* Minimum of all phy-speeds on the path from the
* local node to this node. */
u8 max_depth : 4; /* Maximum depth to any leaf node */
u8 max_hops : 4; /* Max hops in this sub tree */
atomic_t ref_count;
/* For serializing node topology into a list. */
struct list_head link;
/* Upper layer specific data. */
void *data;
struct fw_node *ports[0];
};
static inline struct fw_node *fw_node_get(struct fw_node *node)
{
atomic_inc(&node->ref_count);
return node;
}
static inline void fw_node_put(struct fw_node *node)
{
if (atomic_dec_and_test(&node->ref_count))
kfree(node);
}
struct fw_card;
void fw_destroy_nodes(struct fw_card *card);
int fw_compute_block_crc(u32 *block);
#endif /* __fw_topology_h */
......@@ -20,17 +20,25 @@
#include <linux/compiler.h>
#include <linux/delay.h>
#include <linux/device.h>
#include <linux/dma-mapping.h>
#include <linux/firewire.h>
#include <linux/firewire-constants.h>
#include <linux/gfp.h>
#include <linux/init.h>
#include <linux/interrupt.h>
#include <linux/io.h>
#include <linux/kernel.h>
#include <linux/list.h>
#include <linux/mm.h>
#include <linux/module.h>
#include <linux/moduleparam.h>
#include <linux/pci.h>
#include <linux/spinlock.h>
#include <linux/string.h>
#include <asm/atomic.h>
#include <asm/byteorder.h>
#include <asm/page.h>
#include <asm/system.h>
......@@ -38,8 +46,8 @@
#include <asm/pmac_feature.h>
#endif
#include "fw-ohci.h"
#include "fw-transaction.h"
#include "core.h"
#include "ohci.h"
#define DESCRIPTOR_OUTPUT_MORE 0
#define DESCRIPTOR_OUTPUT_LAST (1 << 12)
......@@ -178,7 +186,7 @@ struct fw_ohci {
int node_id;
int generation;
int request_generation; /* for timestamping incoming requests */
u32 bus_seconds;
atomic_t bus_seconds;
bool use_dualbuffer;
bool old_uninorth;
......@@ -231,7 +239,6 @@ static inline struct fw_ohci *fw_ohci(struct fw_card *card)
#define OHCI1394_MAX_AT_RESP_RETRIES 0x2
#define OHCI1394_MAX_PHYS_RESP_RETRIES 0x8
#define FW_OHCI_MAJOR 240
#define OHCI1394_REGISTER_SIZE 0x800
#define OHCI_LOOP_COUNT 500
#define OHCI1394_PCI_HCI_Control 0x40
......@@ -1434,7 +1441,7 @@ static irqreturn_t irq_handler(int irq, void *data)
if (event & OHCI1394_cycle64Seconds) {
cycle_time = reg_read(ohci, OHCI1394_IsochronousCycleTimer);
if ((cycle_time & 0x80000000) == 0)
ohci->bus_seconds++;
atomic_inc(&ohci->bus_seconds);
}
return IRQ_HANDLED;
......@@ -1770,7 +1777,7 @@ static u64 ohci_get_bus_time(struct fw_card *card)
u64 bus_time;
cycle_time = reg_read(ohci, OHCI1394_IsochronousCycleTimer);
bus_time = ((u64) ohci->bus_seconds << 32) | cycle_time;
bus_time = ((u64)atomic_read(&ohci->bus_seconds) << 32) | cycle_time;
return bus_time;
}
......
#ifndef __fw_ohci_h
#define __fw_ohci_h
#ifndef _FIREWIRE_OHCI_H
#define _FIREWIRE_OHCI_H
/* OHCI register map */
......@@ -154,4 +154,4 @@
#define OHCI1394_phy_tcode 0xe
#endif /* __fw_ohci_h */
#endif /* _FIREWIRE_OHCI_H */
......@@ -30,18 +30,28 @@
#include <linux/blkdev.h>
#include <linux/bug.h>
#include <linux/completion.h>
#include <linux/delay.h>
#include <linux/device.h>
#include <linux/dma-mapping.h>
#include <linux/firewire.h>
#include <linux/firewire-constants.h>
#include <linux/init.h>
#include <linux/jiffies.h>
#include <linux/kernel.h>
#include <linux/kref.h>
#include <linux/list.h>
#include <linux/mod_devicetable.h>
#include <linux/module.h>
#include <linux/moduleparam.h>
#include <linux/scatterlist.h>
#include <linux/slab.h>
#include <linux/spinlock.h>
#include <linux/string.h>
#include <linux/stringify.h>
#include <linux/timer.h>
#include <linux/workqueue.h>
#include <asm/byteorder.h>
#include <asm/system.h>
#include <scsi/scsi.h>
......@@ -49,10 +59,6 @@
#include <scsi/scsi_device.h>
#include <scsi/scsi_host.h>
#include "fw-device.h"
#include "fw-topology.h"
#include "fw-transaction.h"
/*
* So far only bridges from Oxford Semiconductor are known to support
* concurrent logins. Depending on firmware, four or two concurrent logins
......@@ -174,6 +180,11 @@ struct sbp2_target {
int blocked; /* ditto */
};
static struct fw_device *target_device(struct sbp2_target *tgt)
{
return fw_parent_device(tgt->unit);
}
/* Impossible login_id, to detect logout attempt before successful login */
#define INVALID_LOGIN_ID 0x10000
......@@ -482,7 +493,7 @@ static void complete_transaction(struct fw_card *card, int rcode,
static void sbp2_send_orb(struct sbp2_orb *orb, struct sbp2_logical_unit *lu,
int node_id, int generation, u64 offset)
{
struct fw_device *device = fw_device(lu->tgt->unit->device.parent);
struct fw_device *device = target_device(lu->tgt);
unsigned long flags;
orb->pointer.high = 0;
......@@ -504,7 +515,7 @@ static void sbp2_send_orb(struct sbp2_orb *orb, struct sbp2_logical_unit *lu,
static int sbp2_cancel_orbs(struct sbp2_logical_unit *lu)
{
struct fw_device *device = fw_device(lu->tgt->unit->device.parent);
struct fw_device *device = target_device(lu->tgt);
struct sbp2_orb *orb, *next;
struct list_head list;
unsigned long flags;
......@@ -542,7 +553,7 @@ static int sbp2_send_management_orb(struct sbp2_logical_unit *lu, int node_id,
int generation, int function,
int lun_or_login_id, void *response)
{
struct fw_device *device = fw_device(lu->tgt->unit->device.parent);
struct fw_device *device = target_device(lu->tgt);
struct sbp2_management_orb *orb;
unsigned int timeout;
int retval = -ENOMEM;
......@@ -638,7 +649,7 @@ static int sbp2_send_management_orb(struct sbp2_logical_unit *lu, int node_id,
static void sbp2_agent_reset(struct sbp2_logical_unit *lu)
{
struct fw_device *device = fw_device(lu->tgt->unit->device.parent);
struct fw_device *device = target_device(lu->tgt);
__be32 d = 0;
fw_run_transaction(device->card, TCODE_WRITE_QUADLET_REQUEST,
......@@ -655,7 +666,7 @@ static void complete_agent_reset_write_no_wait(struct fw_card *card,
static void sbp2_agent_reset_no_wait(struct sbp2_logical_unit *lu)
{
struct fw_device *device = fw_device(lu->tgt->unit->device.parent);
struct fw_device *device = target_device(lu->tgt);
struct fw_transaction *t;
static __be32 d;
......@@ -694,7 +705,7 @@ static inline void sbp2_allow_block(struct sbp2_logical_unit *lu)
static void sbp2_conditionally_block(struct sbp2_logical_unit *lu)
{
struct sbp2_target *tgt = lu->tgt;
struct fw_card *card = fw_device(tgt->unit->device.parent)->card;
struct fw_card *card = target_device(tgt)->card;
struct Scsi_Host *shost =
container_of((void *)tgt, struct Scsi_Host, hostdata[0]);
unsigned long flags;
......@@ -718,7 +729,7 @@ static void sbp2_conditionally_block(struct sbp2_logical_unit *lu)
static void sbp2_conditionally_unblock(struct sbp2_logical_unit *lu)
{
struct sbp2_target *tgt = lu->tgt;
struct fw_card *card = fw_device(tgt->unit->device.parent)->card;
struct fw_card *card = target_device(tgt)->card;
struct Scsi_Host *shost =
container_of((void *)tgt, struct Scsi_Host, hostdata[0]);
unsigned long flags;
......@@ -743,7 +754,7 @@ static void sbp2_conditionally_unblock(struct sbp2_logical_unit *lu)
*/
static void sbp2_unblock(struct sbp2_target *tgt)
{
struct fw_card *card = fw_device(tgt->unit->device.parent)->card;
struct fw_card *card = target_device(tgt)->card;
struct Scsi_Host *shost =
container_of((void *)tgt, struct Scsi_Host, hostdata[0]);
unsigned long flags;
......@@ -773,7 +784,7 @@ static void sbp2_release_target(struct kref *kref)
struct Scsi_Host *shost =
container_of((void *)tgt, struct Scsi_Host, hostdata[0]);
struct scsi_device *sdev;
struct fw_device *device = fw_device(tgt->unit->device.parent);
struct fw_device *device = target_device(tgt);
/* prevent deadlocks */
sbp2_unblock(tgt);
......@@ -846,7 +857,7 @@ static void sbp2_queue_work(struct sbp2_logical_unit *lu, unsigned long delay)
*/
static void sbp2_set_busy_timeout(struct sbp2_logical_unit *lu)
{
struct fw_device *device = fw_device(lu->tgt->unit->device.parent);
struct fw_device *device = target_device(lu->tgt);
__be32 d = cpu_to_be32(SBP2_CYCLE_LIMIT | SBP2_RETRY_LIMIT);
fw_run_transaction(device->card, TCODE_WRITE_QUADLET_REQUEST,
......@@ -862,7 +873,7 @@ static void sbp2_login(struct work_struct *work)
struct sbp2_logical_unit *lu =
container_of(work, struct sbp2_logical_unit, work.work);
struct sbp2_target *tgt = lu->tgt;
struct fw_device *device = fw_device(tgt->unit->device.parent);
struct fw_device *device = target_device(tgt);
struct Scsi_Host *shost;
struct scsi_device *sdev;
struct sbp2_login_response response;
......@@ -1110,7 +1121,7 @@ static struct scsi_host_template scsi_driver_template;
static int sbp2_probe(struct device *dev)
{
struct fw_unit *unit = fw_unit(dev);
struct fw_device *device = fw_device(unit->device.parent);
struct fw_device *device = fw_parent_device(unit);
struct sbp2_target *tgt;
struct sbp2_logical_unit *lu;
struct Scsi_Host *shost;
......@@ -1191,7 +1202,7 @@ static void sbp2_reconnect(struct work_struct *work)
struct sbp2_logical_unit *lu =
container_of(work, struct sbp2_logical_unit, work.work);
struct sbp2_target *tgt = lu->tgt;
struct fw_device *device = fw_device(tgt->unit->device.parent);
struct fw_device *device = target_device(tgt);
int generation, node_id, local_node_id;
if (fw_device_is_shutdown(device))
......@@ -1243,7 +1254,7 @@ static void sbp2_update(struct fw_unit *unit)
struct sbp2_target *tgt = dev_get_drvdata(&unit->device);
struct sbp2_logical_unit *lu;
fw_device_enable_phys_dma(fw_device(unit->device.parent));
fw_device_enable_phys_dma(fw_parent_device(unit));
/*
* Fw-core serializes sbp2_update() against sbp2_remove().
......@@ -1259,9 +1270,10 @@ static void sbp2_update(struct fw_unit *unit)
#define SBP2_UNIT_SPEC_ID_ENTRY 0x0000609e
#define SBP2_SW_VERSION_ENTRY 0x00010483
static const struct fw_device_id sbp2_id_table[] = {
static const struct ieee1394_device_id sbp2_id_table[] = {
{
.match_flags = FW_MATCH_SPECIFIER_ID | FW_MATCH_VERSION,
.match_flags = IEEE1394_MATCH_SPECIFIER_ID |
IEEE1394_MATCH_VERSION,
.specifier_id = SBP2_UNIT_SPEC_ID_ENTRY,
.version = SBP2_SW_VERSION_ENTRY,
},
......@@ -1335,7 +1347,7 @@ static void complete_command_orb(struct sbp2_orb *base_orb,
{
struct sbp2_command_orb *orb =
container_of(base_orb, struct sbp2_command_orb, base);
struct fw_device *device = fw_device(orb->lu->tgt->unit->device.parent);
struct fw_device *device = target_device(orb->lu->tgt);
int result;
if (status != NULL) {
......@@ -1442,7 +1454,7 @@ static int sbp2_map_scatterlist(struct sbp2_command_orb *orb,
static int sbp2_scsi_queuecommand(struct scsi_cmnd *cmd, scsi_done_fn_t done)
{
struct sbp2_logical_unit *lu = cmd->device->hostdata;
struct fw_device *device = fw_device(lu->tgt->unit->device.parent);
struct fw_device *device = target_device(lu->tgt);
struct sbp2_command_orb *orb;
int generation, retval = SCSI_MLQUEUE_HOST_BUSY;
......
Markdown is supported
0%
or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment