Skip to content

Commit

Permalink
---
Browse files Browse the repository at this point in the history
yaml
---
r: 101389
b: refs/heads/master
c: 64fd52a
h: refs/heads/master
i:
  101387: a2857e5
v: v3
  • Loading branch information
Linus Torvalds committed Jul 15, 2008
1 parent c79e848 commit 66e14b0
Show file tree
Hide file tree
Showing 20 changed files with 182 additions and 59 deletions.
2 changes: 1 addition & 1 deletion [refs]
Original file line number Diff line number Diff line change
@@ -1,2 +1,2 @@
---
refs/heads/master: 6c9fcaf2eec1b9f85226a694230dd957dd7926b3
refs/heads/master: 64fd52a52077d3cd5a778ca031c0aaecf885eaa6
5 changes: 5 additions & 0 deletions trunk/MAINTAINERS
Original file line number Diff line number Diff line change
Expand Up @@ -1777,6 +1777,11 @@ M: hch@infradead.org
W: ftp://ftp.openlinux.org/pub/people/hch/vxfs
S: Maintained

FTRACE
P: Steven Rostedt
M: srostedt@redhat.com
S: Maintained

FUJITSU FR-V (FRV) PORT
P: David Howells
M: dhowells@redhat.com
Expand Down
32 changes: 21 additions & 11 deletions trunk/drivers/firewire/fw-card.c
Original file line number Diff line number Diff line change
Expand Up @@ -16,12 +16,15 @@
* Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
*/

#include <linux/module.h>
#include <linux/errno.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/kref.h>
#include <linux/module.h>
#include <linux/mutex.h>
#include <linux/crc-itu-t.h>

#include "fw-transaction.h"
#include "fw-topology.h"
#include "fw-device.h"
Expand Down Expand Up @@ -396,14 +399,16 @@ fw_card_initialize(struct fw_card *card, const struct fw_card_driver *driver,
{
static atomic_t index = ATOMIC_INIT(-1);

atomic_set(&card->device_count, 0);
card->index = atomic_inc_return(&index);
card->driver = driver;
card->device = device;
card->current_tlabel = 0;
card->tlabel_mask = 0;
card->color = 0;
card->broadcast_channel = BROADCAST_CHANNEL_INITIAL;

kref_init(&card->kref);
init_completion(&card->done);
INIT_LIST_HEAD(&card->transaction_list);
spin_lock_init(&card->lock);
setup_timer(&card->flush_timer,
Expand Down Expand Up @@ -496,7 +501,6 @@ dummy_enable_phys_dma(struct fw_card *card,
}

static struct fw_card_driver dummy_driver = {
.name = "dummy",
.enable = dummy_enable,
.update_phy_reg = dummy_update_phy_reg,
.set_config_rom = dummy_set_config_rom,
Expand All @@ -506,6 +510,14 @@ static struct fw_card_driver dummy_driver = {
.enable_phys_dma = dummy_enable_phys_dma,
};

void
fw_card_release(struct kref *kref)
{
struct fw_card *card = container_of(kref, struct fw_card, kref);

complete(&card->done);
}

void
fw_core_remove_card(struct fw_card *card)
{
Expand All @@ -521,12 +533,10 @@ fw_core_remove_card(struct fw_card *card)
card->driver = &dummy_driver;

fw_destroy_nodes(card);
/*
* Wait for all device workqueue jobs to finish. Otherwise the
* firewire-core module could be unloaded before the jobs ran.
*/
while (atomic_read(&card->device_count) > 0)
msleep(100);

/* Wait for all users, especially device workqueue jobs, to finish. */
fw_card_put(card);
wait_for_completion(&card->done);

cancel_delayed_work_sync(&card->work);
fw_flush_transactions(card);
Expand Down
5 changes: 2 additions & 3 deletions trunk/drivers/firewire/fw-device.c
Original file line number Diff line number Diff line change
Expand Up @@ -168,7 +168,7 @@ static void fw_device_release(struct device *dev)
fw_node_put(device->node);
kfree(device->config_rom);
kfree(device);
atomic_dec(&card->device_count);
fw_card_put(card);
}

int fw_device_enable_phys_dma(struct fw_device *device)
Expand Down Expand Up @@ -946,8 +946,7 @@ void fw_node_event(struct fw_card *card, struct fw_node *node, int event)
*/
device_initialize(&device->device);
atomic_set(&device->state, FW_DEVICE_INITIALIZING);
atomic_inc(&card->device_count);
device->card = card;
device->card = fw_card_get(card);
device->node = fw_node_get(node);
device->node_id = node->node_id;
device->generation = card->generation;
Expand Down
1 change: 0 additions & 1 deletion trunk/drivers/firewire/fw-device.h
Original file line number Diff line number Diff line change
Expand Up @@ -62,7 +62,6 @@ struct fw_device {
bool cmc;
struct fw_card *card;
struct device device;
struct list_head link;
struct list_head client_list;
u32 *config_rom;
size_t config_rom_length;
Expand Down
1 change: 0 additions & 1 deletion trunk/drivers/firewire/fw-ohci.c
Original file line number Diff line number Diff line change
Expand Up @@ -2292,7 +2292,6 @@ ohci_queue_iso(struct fw_iso_context *base,
}

static const struct fw_card_driver ohci_driver = {
.name = ohci_driver_name,
.enable = ohci_enable,
.update_phy_reg = ohci_update_phy_reg,
.set_config_rom = ohci_set_config_rom,
Expand Down
25 changes: 23 additions & 2 deletions trunk/drivers/firewire/fw-sbp2.c
Original file line number Diff line number Diff line change
Expand Up @@ -86,6 +86,11 @@ MODULE_PARM_DESC(exclusive_login, "Exclusive login to sbp2 device "
* - delay inquiry
* Wait extra SBP2_INQUIRY_DELAY seconds after login before SCSI inquiry.
*
* - power condition
* Set the power condition field in the START STOP UNIT commands sent by
* sd_mod on suspend, resume, and shutdown (if manage_start_stop is on).
* Some disks need this to spin down or to resume properly.
*
* - override internal blacklist
* Instead of adding to the built-in blacklist, use only the workarounds
* specified in the module load parameter.
Expand All @@ -97,6 +102,7 @@ MODULE_PARM_DESC(exclusive_login, "Exclusive login to sbp2 device "
#define SBP2_WORKAROUND_FIX_CAPACITY 0x8
#define SBP2_WORKAROUND_DELAY_INQUIRY 0x10
#define SBP2_INQUIRY_DELAY 12
#define SBP2_WORKAROUND_POWER_CONDITION 0x20
#define SBP2_WORKAROUND_OVERRIDE 0x100

static int sbp2_param_workarounds;
Expand All @@ -107,6 +113,8 @@ MODULE_PARM_DESC(workarounds, "Work around device bugs (default = 0"
", skip mode page 8 = " __stringify(SBP2_WORKAROUND_MODE_SENSE_8)
", fix capacity = " __stringify(SBP2_WORKAROUND_FIX_CAPACITY)
", delay inquiry = " __stringify(SBP2_WORKAROUND_DELAY_INQUIRY)
", set power condition in start stop unit = "
__stringify(SBP2_WORKAROUND_POWER_CONDITION)
", override internal blacklist = " __stringify(SBP2_WORKAROUND_OVERRIDE)
", or a combination)");

Expand Down Expand Up @@ -310,18 +318,25 @@ static const struct {
.firmware_revision = 0x002800,
.model = 0x001010,
.workarounds = SBP2_WORKAROUND_INQUIRY_36 |
SBP2_WORKAROUND_MODE_SENSE_8,
SBP2_WORKAROUND_MODE_SENSE_8 |
SBP2_WORKAROUND_POWER_CONDITION,
},
/* DViCO Momobay FX-3A with TSB42AA9A bridge */ {
.firmware_revision = 0x002800,
.model = 0x000000,
.workarounds = SBP2_WORKAROUND_DELAY_INQUIRY,
.workarounds = SBP2_WORKAROUND_DELAY_INQUIRY |
SBP2_WORKAROUND_POWER_CONDITION,
},
/* Initio bridges, actually only needed for some older ones */ {
.firmware_revision = 0x000200,
.model = ~0,
.workarounds = SBP2_WORKAROUND_INQUIRY_36,
},
/* PL-3507 bridge with Prolific firmware */ {
.firmware_revision = 0x012800,
.model = ~0,
.workarounds = SBP2_WORKAROUND_POWER_CONDITION,
},
/* Symbios bridge */ {
.firmware_revision = 0xa0b800,
.model = ~0,
Expand Down Expand Up @@ -1530,6 +1545,9 @@ static int sbp2_scsi_slave_configure(struct scsi_device *sdev)

sdev->use_10_for_rw = 1;

if (sbp2_param_exclusive_login)
sdev->manage_start_stop = 1;

if (sdev->type == TYPE_ROM)
sdev->use_10_for_ms = 1;

Expand All @@ -1540,6 +1558,9 @@ static int sbp2_scsi_slave_configure(struct scsi_device *sdev)
if (lu->tgt->workarounds & SBP2_WORKAROUND_FIX_CAPACITY)
sdev->fix_capacity = 1;

if (lu->tgt->workarounds & SBP2_WORKAROUND_POWER_CONDITION)
sdev->start_stop_pwr_cond = 1;

if (lu->tgt->workarounds & SBP2_WORKAROUND_128K_MAX_TRANS)
blk_queue_max_sectors(sdev->request_queue, 128 * 1024 / 512);

Expand Down
32 changes: 23 additions & 9 deletions trunk/drivers/firewire/fw-transaction.c
Original file line number Diff line number Diff line change
Expand Up @@ -55,6 +55,9 @@
#define HEADER_GET_DATA_LENGTH(q) (((q) >> 16) & 0xffff)
#define HEADER_GET_EXTENDED_TCODE(q) (((q) >> 0) & 0xffff)

#define HEADER_DESTINATION_IS_BROADCAST(q) \
(((q) & HEADER_DESTINATION(0x3f)) == HEADER_DESTINATION(0x3f))

#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)
Expand Down Expand Up @@ -624,12 +627,9 @@ allocate_request(struct fw_packet *p)
void
fw_send_response(struct fw_card *card, struct fw_request *request, int rcode)
{
/*
* Broadcast packets are reported as ACK_COMPLETE, so this
* check is sufficient to ensure we don't send response to
* broadcast packets or posted writes.
*/
if (request->ack != ACK_PENDING) {
/* unified transaction or broadcast transaction: don't respond */
if (request->ack != ACK_PENDING ||
HEADER_DESTINATION_IS_BROADCAST(request->request_header[0])) {
kfree(request);
return;
}
Expand Down Expand Up @@ -817,12 +817,13 @@ handle_registers(struct fw_card *card, struct fw_request *request,
int reg = offset & ~CSR_REGISTER_BASE;
unsigned long long bus_time;
__be32 *data = payload;
int rcode = RCODE_COMPLETE;

switch (reg) {
case CSR_CYCLE_TIME:
case CSR_BUS_TIME:
if (!TCODE_IS_READ_REQUEST(tcode) || length != 4) {
fw_send_response(card, request, RCODE_TYPE_ERROR);
rcode = RCODE_TYPE_ERROR;
break;
}

Expand All @@ -831,7 +832,17 @@ handle_registers(struct fw_card *card, struct fw_request *request,
*data = cpu_to_be32(bus_time);
else
*data = cpu_to_be32(bus_time >> 25);
fw_send_response(card, request, RCODE_COMPLETE);
break;

case CSR_BROADCAST_CHANNEL:
if (tcode == TCODE_READ_QUADLET_REQUEST)
*data = cpu_to_be32(card->broadcast_channel);
else if (tcode == TCODE_WRITE_QUADLET_REQUEST)
card->broadcast_channel =
(be32_to_cpu(*data) & BROADCAST_CHANNEL_VALID) |
BROADCAST_CHANNEL_INITIAL;
else
rcode = RCODE_TYPE_ERROR;
break;

case CSR_BUS_MANAGER_ID:
Expand All @@ -850,10 +861,13 @@ handle_registers(struct fw_card *card, struct fw_request *request,

case CSR_BUSY_TIMEOUT:
/* FIXME: Implement this. */

default:
fw_send_response(card, request, RCODE_ADDRESS_ERROR);
rcode = RCODE_ADDRESS_ERROR;
break;
}

fw_send_response(card, request, rcode);
}

static struct fw_address_handler registers = {
Expand Down
34 changes: 26 additions & 8 deletions trunk/drivers/firewire/fw-transaction.h
Original file line number Diff line number Diff line change
Expand Up @@ -19,14 +19,15 @@
#ifndef __fw_transaction_h
#define __fw_transaction_h

#include <linux/completion.h>
#include <linux/device.h>
#include <linux/timer.h>
#include <linux/interrupt.h>
#include <linux/list.h>
#include <linux/fs.h>
#include <linux/dma-mapping.h>
#include <linux/firewire-constants.h>
#include <asm/atomic.h>
#include <linux/kref.h>
#include <linux/list.h>
#include <linux/spinlock_types.h>
#include <linux/timer.h>
#include <linux/workqueue.h>

#define TCODE_IS_READ_REQUEST(tcode) (((tcode) & ~1) == 4)
#define TCODE_IS_BLOCK_PACKET(tcode) (((tcode) & 1) != 0)
Expand Down Expand Up @@ -80,6 +81,9 @@
#define CSR_SPEED_MAP 0x2000
#define CSR_SPEED_MAP_END 0x3000

#define BROADCAST_CHANNEL_INITIAL (1 << 31 | 31)
#define BROADCAST_CHANNEL_VALID (1 << 30)

#define fw_notify(s, args...) printk(KERN_NOTICE KBUILD_MODNAME ": " s, ## args)
#define fw_error(s, args...) printk(KERN_ERR KBUILD_MODNAME ": " s, ## args)

Expand Down Expand Up @@ -216,7 +220,8 @@ extern struct bus_type fw_bus_type;
struct fw_card {
const struct fw_card_driver *driver;
struct device *device;
atomic_t device_count;
struct kref kref;
struct completion done;

int node_id;
int generation;
Expand All @@ -236,6 +241,7 @@ struct fw_card {
*/
int self_id_count;
u32 topology_map[252 + 3];
u32 broadcast_channel;

spinlock_t lock; /* Take this lock when handling the lists in
* this struct. */
Expand All @@ -256,6 +262,20 @@ struct fw_card {
int bm_generation;
};

static inline struct fw_card *fw_card_get(struct fw_card *card)
{
kref_get(&card->kref);

return card;
}

void fw_card_release(struct kref *kref);

static inline void fw_card_put(struct fw_card *card)
{
kref_put(&card->kref, fw_card_release);
}

/*
* The iso packet format allows for an immediate header/payload part
* stored in 'header' immediately after the packet info plus an
Expand Down Expand Up @@ -348,8 +368,6 @@ int
fw_iso_context_stop(struct fw_iso_context *ctx);

struct fw_card_driver {
const char *name;

/*
* Enable the given card with the given initial config rom.
* This function is expected to activate the card, and either
Expand Down
Loading

0 comments on commit 66e14b0

Please sign in to comment.