forked from luck/tmp_suning_uos_patched
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: fw-ohci: shut up false compiler warning on PPC32 firewire: fw-ohci: use dma_alloc_coherent for ar_buffer ieee1394: sbp2: fix for SYM13FW500 bridge (Datafab disk) firewire: fw-sbp2: fix for SYM13FW500 bridge (Datafab disk) firewire: update Kconfig help text firewire: warn on fatal condition in topology code firewire: fw-sbp2: set single-phase retry_limit firewire: fw-ohci: Apple UniNorth 1st generation support firewire: fw-ohci: PPC PMac platform code firewire: endianess annotations firewire: endianess fix
This commit is contained in:
commit
4faa849665
@ -1,5 +1,3 @@
|
|||||||
# -*- shell-script -*-
|
|
||||||
|
|
||||||
comment "An alternative FireWire stack is available with EXPERIMENTAL=y"
|
comment "An alternative FireWire stack is available with EXPERIMENTAL=y"
|
||||||
depends on EXPERIMENTAL=n
|
depends on EXPERIMENTAL=n
|
||||||
|
|
||||||
@ -21,27 +19,7 @@ config FIREWIRE
|
|||||||
NOTE:
|
NOTE:
|
||||||
|
|
||||||
You should only build ONE of the stacks, unless you REALLY know what
|
You should only build ONE of the stacks, unless you REALLY know what
|
||||||
you are doing. If you install both, you should configure them only as
|
you are doing.
|
||||||
modules rather than link them statically, and you should blacklist one
|
|
||||||
of the concurrent low-level drivers in /etc/modprobe.conf. Add either
|
|
||||||
|
|
||||||
blacklist firewire-ohci
|
|
||||||
or
|
|
||||||
blacklist ohci1394
|
|
||||||
|
|
||||||
there depending on which driver you DON'T want to have auto-loaded.
|
|
||||||
You can optionally do the same with the other IEEE 1394/ FireWire
|
|
||||||
drivers.
|
|
||||||
|
|
||||||
If you have an old modprobe which doesn't implement the blacklist
|
|
||||||
directive, use either
|
|
||||||
|
|
||||||
install firewire-ohci /bin/true
|
|
||||||
or
|
|
||||||
install ohci1394 /bin/true
|
|
||||||
|
|
||||||
and so on, depending on which modules you DON't want to have
|
|
||||||
auto-loaded.
|
|
||||||
|
|
||||||
config FIREWIRE_OHCI
|
config FIREWIRE_OHCI
|
||||||
tristate "Support for OHCI FireWire host controllers"
|
tristate "Support for OHCI FireWire host controllers"
|
||||||
@ -57,8 +35,24 @@ config FIREWIRE_OHCI
|
|||||||
|
|
||||||
NOTE:
|
NOTE:
|
||||||
|
|
||||||
If you also build ohci1394 of the classic stack, blacklist either
|
You should only build ohci1394 or firewire-ohci, but not both.
|
||||||
ohci1394 or firewire-ohci to let hotplug load only the desired driver.
|
If you nevertheless want to install both, 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. The latter two modules should be
|
||||||
|
blacklisted together with ohci1394 because they depend on ohci1394.
|
||||||
|
|
||||||
|
If you have an old modprobe which doesn't implement the blacklist
|
||||||
|
directive, use "install modulename /bin/true" for the modules to be
|
||||||
|
blacklisted.
|
||||||
|
|
||||||
config FIREWIRE_SBP2
|
config FIREWIRE_SBP2
|
||||||
tristate "Support for storage devices (SBP-2 protocol driver)"
|
tristate "Support for storage devices (SBP-2 protocol driver)"
|
||||||
@ -75,9 +69,3 @@ config FIREWIRE_SBP2
|
|||||||
|
|
||||||
You should also enable support for disks, CD-ROMs, etc. in the SCSI
|
You should also enable support for disks, CD-ROMs, etc. in the SCSI
|
||||||
configuration section.
|
configuration section.
|
||||||
|
|
||||||
NOTE:
|
|
||||||
|
|
||||||
If you also build sbp2 of the classic stack, blacklist either sbp2
|
|
||||||
or firewire-sbp2 to let hotplug load only the desired driver.
|
|
||||||
|
|
||||||
|
@ -33,6 +33,10 @@
|
|||||||
#include <asm/page.h>
|
#include <asm/page.h>
|
||||||
#include <asm/system.h>
|
#include <asm/system.h>
|
||||||
|
|
||||||
|
#ifdef CONFIG_PPC_PMAC
|
||||||
|
#include <asm/pmac_feature.h>
|
||||||
|
#endif
|
||||||
|
|
||||||
#include "fw-ohci.h"
|
#include "fw-ohci.h"
|
||||||
#include "fw-transaction.h"
|
#include "fw-transaction.h"
|
||||||
|
|
||||||
@ -175,6 +179,7 @@ struct fw_ohci {
|
|||||||
int generation;
|
int generation;
|
||||||
int request_generation;
|
int request_generation;
|
||||||
u32 bus_seconds;
|
u32 bus_seconds;
|
||||||
|
bool old_uninorth;
|
||||||
|
|
||||||
/*
|
/*
|
||||||
* Spinlock for accessing fw_ohci data. Never call out of
|
* Spinlock for accessing fw_ohci data. Never call out of
|
||||||
@ -276,19 +281,13 @@ static int ar_context_add_page(struct ar_context *ctx)
|
|||||||
{
|
{
|
||||||
struct device *dev = ctx->ohci->card.device;
|
struct device *dev = ctx->ohci->card.device;
|
||||||
struct ar_buffer *ab;
|
struct ar_buffer *ab;
|
||||||
dma_addr_t ab_bus;
|
dma_addr_t uninitialized_var(ab_bus);
|
||||||
size_t offset;
|
size_t offset;
|
||||||
|
|
||||||
ab = (struct ar_buffer *) __get_free_page(GFP_ATOMIC);
|
ab = dma_alloc_coherent(dev, PAGE_SIZE, &ab_bus, GFP_ATOMIC);
|
||||||
if (ab == NULL)
|
if (ab == NULL)
|
||||||
return -ENOMEM;
|
return -ENOMEM;
|
||||||
|
|
||||||
ab_bus = dma_map_single(dev, ab, PAGE_SIZE, DMA_BIDIRECTIONAL);
|
|
||||||
if (dma_mapping_error(ab_bus)) {
|
|
||||||
free_page((unsigned long) ab);
|
|
||||||
return -ENOMEM;
|
|
||||||
}
|
|
||||||
|
|
||||||
memset(&ab->descriptor, 0, sizeof(ab->descriptor));
|
memset(&ab->descriptor, 0, sizeof(ab->descriptor));
|
||||||
ab->descriptor.control = cpu_to_le16(DESCRIPTOR_INPUT_MORE |
|
ab->descriptor.control = cpu_to_le16(DESCRIPTOR_INPUT_MORE |
|
||||||
DESCRIPTOR_STATUS |
|
DESCRIPTOR_STATUS |
|
||||||
@ -299,8 +298,6 @@ static int ar_context_add_page(struct ar_context *ctx)
|
|||||||
ab->descriptor.res_count = cpu_to_le16(PAGE_SIZE - offset);
|
ab->descriptor.res_count = cpu_to_le16(PAGE_SIZE - offset);
|
||||||
ab->descriptor.branch_address = 0;
|
ab->descriptor.branch_address = 0;
|
||||||
|
|
||||||
dma_sync_single_for_device(dev, ab_bus, PAGE_SIZE, DMA_BIDIRECTIONAL);
|
|
||||||
|
|
||||||
ctx->last_buffer->descriptor.branch_address = cpu_to_le32(ab_bus | 1);
|
ctx->last_buffer->descriptor.branch_address = cpu_to_le32(ab_bus | 1);
|
||||||
ctx->last_buffer->next = ab;
|
ctx->last_buffer->next = ab;
|
||||||
ctx->last_buffer = ab;
|
ctx->last_buffer = ab;
|
||||||
@ -311,15 +308,22 @@ static int ar_context_add_page(struct ar_context *ctx)
|
|||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
#if defined(CONFIG_PPC_PMAC) && defined(CONFIG_PPC32)
|
||||||
|
#define cond_le32_to_cpu(v) \
|
||||||
|
(ohci->old_uninorth ? (__force __u32)(v) : le32_to_cpu(v))
|
||||||
|
#else
|
||||||
|
#define cond_le32_to_cpu(v) le32_to_cpu(v)
|
||||||
|
#endif
|
||||||
|
|
||||||
static __le32 *handle_ar_packet(struct ar_context *ctx, __le32 *buffer)
|
static __le32 *handle_ar_packet(struct ar_context *ctx, __le32 *buffer)
|
||||||
{
|
{
|
||||||
struct fw_ohci *ohci = ctx->ohci;
|
struct fw_ohci *ohci = ctx->ohci;
|
||||||
struct fw_packet p;
|
struct fw_packet p;
|
||||||
u32 status, length, tcode;
|
u32 status, length, tcode;
|
||||||
|
|
||||||
p.header[0] = le32_to_cpu(buffer[0]);
|
p.header[0] = cond_le32_to_cpu(buffer[0]);
|
||||||
p.header[1] = le32_to_cpu(buffer[1]);
|
p.header[1] = cond_le32_to_cpu(buffer[1]);
|
||||||
p.header[2] = le32_to_cpu(buffer[2]);
|
p.header[2] = cond_le32_to_cpu(buffer[2]);
|
||||||
|
|
||||||
tcode = (p.header[0] >> 4) & 0x0f;
|
tcode = (p.header[0] >> 4) & 0x0f;
|
||||||
switch (tcode) {
|
switch (tcode) {
|
||||||
@ -331,7 +335,7 @@ static __le32 *handle_ar_packet(struct ar_context *ctx, __le32 *buffer)
|
|||||||
break;
|
break;
|
||||||
|
|
||||||
case TCODE_READ_BLOCK_REQUEST :
|
case TCODE_READ_BLOCK_REQUEST :
|
||||||
p.header[3] = le32_to_cpu(buffer[3]);
|
p.header[3] = cond_le32_to_cpu(buffer[3]);
|
||||||
p.header_length = 16;
|
p.header_length = 16;
|
||||||
p.payload_length = 0;
|
p.payload_length = 0;
|
||||||
break;
|
break;
|
||||||
@ -340,7 +344,7 @@ static __le32 *handle_ar_packet(struct ar_context *ctx, __le32 *buffer)
|
|||||||
case TCODE_READ_BLOCK_RESPONSE:
|
case TCODE_READ_BLOCK_RESPONSE:
|
||||||
case TCODE_LOCK_REQUEST:
|
case TCODE_LOCK_REQUEST:
|
||||||
case TCODE_LOCK_RESPONSE:
|
case TCODE_LOCK_RESPONSE:
|
||||||
p.header[3] = le32_to_cpu(buffer[3]);
|
p.header[3] = cond_le32_to_cpu(buffer[3]);
|
||||||
p.header_length = 16;
|
p.header_length = 16;
|
||||||
p.payload_length = p.header[3] >> 16;
|
p.payload_length = p.header[3] >> 16;
|
||||||
break;
|
break;
|
||||||
@ -357,7 +361,7 @@ static __le32 *handle_ar_packet(struct ar_context *ctx, __le32 *buffer)
|
|||||||
|
|
||||||
/* FIXME: What to do about evt_* errors? */
|
/* FIXME: What to do about evt_* errors? */
|
||||||
length = (p.header_length + p.payload_length + 3) / 4;
|
length = (p.header_length + p.payload_length + 3) / 4;
|
||||||
status = le32_to_cpu(buffer[length]);
|
status = cond_le32_to_cpu(buffer[length]);
|
||||||
|
|
||||||
p.ack = ((status >> 16) & 0x1f) - 16;
|
p.ack = ((status >> 16) & 0x1f) - 16;
|
||||||
p.speed = (status >> 21) & 0x7;
|
p.speed = (status >> 21) & 0x7;
|
||||||
@ -375,7 +379,7 @@ static __le32 *handle_ar_packet(struct ar_context *ctx, __le32 *buffer)
|
|||||||
*/
|
*/
|
||||||
|
|
||||||
if (p.ack + 16 == 0x09)
|
if (p.ack + 16 == 0x09)
|
||||||
ohci->request_generation = (buffer[2] >> 16) & 0xff;
|
ohci->request_generation = (p.header[2] >> 16) & 0xff;
|
||||||
else if (ctx == &ohci->ar_request_ctx)
|
else if (ctx == &ohci->ar_request_ctx)
|
||||||
fw_core_handle_request(&ohci->card, &p);
|
fw_core_handle_request(&ohci->card, &p);
|
||||||
else
|
else
|
||||||
@ -397,6 +401,7 @@ static void ar_context_tasklet(unsigned long data)
|
|||||||
|
|
||||||
if (d->res_count == 0) {
|
if (d->res_count == 0) {
|
||||||
size_t size, rest, offset;
|
size_t size, rest, offset;
|
||||||
|
dma_addr_t buffer_bus;
|
||||||
|
|
||||||
/*
|
/*
|
||||||
* This descriptor is finished and we may have a
|
* This descriptor is finished and we may have a
|
||||||
@ -405,9 +410,7 @@ static void ar_context_tasklet(unsigned long data)
|
|||||||
*/
|
*/
|
||||||
|
|
||||||
offset = offsetof(struct ar_buffer, data);
|
offset = offsetof(struct ar_buffer, data);
|
||||||
dma_unmap_single(ohci->card.device,
|
buffer_bus = le32_to_cpu(ab->descriptor.data_address) - offset;
|
||||||
le32_to_cpu(ab->descriptor.data_address) - offset,
|
|
||||||
PAGE_SIZE, DMA_BIDIRECTIONAL);
|
|
||||||
|
|
||||||
buffer = ab;
|
buffer = ab;
|
||||||
ab = ab->next;
|
ab = ab->next;
|
||||||
@ -423,7 +426,8 @@ static void ar_context_tasklet(unsigned long data)
|
|||||||
while (buffer < end)
|
while (buffer < end)
|
||||||
buffer = handle_ar_packet(ctx, buffer);
|
buffer = handle_ar_packet(ctx, buffer);
|
||||||
|
|
||||||
free_page((unsigned long)buffer);
|
dma_free_coherent(ohci->card.device, PAGE_SIZE,
|
||||||
|
buffer, buffer_bus);
|
||||||
ar_context_add_page(ctx);
|
ar_context_add_page(ctx);
|
||||||
} else {
|
} else {
|
||||||
buffer = ctx->pointer;
|
buffer = ctx->pointer;
|
||||||
@ -532,7 +536,7 @@ static int
|
|||||||
context_add_buffer(struct context *ctx)
|
context_add_buffer(struct context *ctx)
|
||||||
{
|
{
|
||||||
struct descriptor_buffer *desc;
|
struct descriptor_buffer *desc;
|
||||||
dma_addr_t bus_addr;
|
dma_addr_t uninitialized_var(bus_addr);
|
||||||
int offset;
|
int offset;
|
||||||
|
|
||||||
/*
|
/*
|
||||||
@ -1022,13 +1026,14 @@ static void bus_reset_tasklet(unsigned long data)
|
|||||||
*/
|
*/
|
||||||
|
|
||||||
self_id_count = (reg_read(ohci, OHCI1394_SelfIDCount) >> 3) & 0x3ff;
|
self_id_count = (reg_read(ohci, OHCI1394_SelfIDCount) >> 3) & 0x3ff;
|
||||||
generation = (le32_to_cpu(ohci->self_id_cpu[0]) >> 16) & 0xff;
|
generation = (cond_le32_to_cpu(ohci->self_id_cpu[0]) >> 16) & 0xff;
|
||||||
rmb();
|
rmb();
|
||||||
|
|
||||||
for (i = 1, j = 0; j < self_id_count; i += 2, j++) {
|
for (i = 1, j = 0; j < self_id_count; i += 2, j++) {
|
||||||
if (ohci->self_id_cpu[i] != ~ohci->self_id_cpu[i + 1])
|
if (ohci->self_id_cpu[i] != ~ohci->self_id_cpu[i + 1])
|
||||||
fw_error("inconsistent self IDs\n");
|
fw_error("inconsistent self IDs\n");
|
||||||
ohci->self_id_buffer[j] = le32_to_cpu(ohci->self_id_cpu[i]);
|
ohci->self_id_buffer[j] =
|
||||||
|
cond_le32_to_cpu(ohci->self_id_cpu[i]);
|
||||||
}
|
}
|
||||||
rmb();
|
rmb();
|
||||||
|
|
||||||
@ -1316,7 +1321,7 @@ ohci_set_config_rom(struct fw_card *card, u32 *config_rom, size_t length)
|
|||||||
unsigned long flags;
|
unsigned long flags;
|
||||||
int retval = -EBUSY;
|
int retval = -EBUSY;
|
||||||
__be32 *next_config_rom;
|
__be32 *next_config_rom;
|
||||||
dma_addr_t next_config_rom_bus;
|
dma_addr_t uninitialized_var(next_config_rom_bus);
|
||||||
|
|
||||||
ohci = fw_ohci(card);
|
ohci = fw_ohci(card);
|
||||||
|
|
||||||
@ -1487,7 +1492,7 @@ static int handle_ir_dualbuffer_packet(struct context *context,
|
|||||||
void *p, *end;
|
void *p, *end;
|
||||||
int i;
|
int i;
|
||||||
|
|
||||||
if (db->first_res_count > 0 && db->second_res_count > 0) {
|
if (db->first_res_count != 0 && db->second_res_count != 0) {
|
||||||
if (ctx->excess_bytes <= le16_to_cpu(db->second_req_count)) {
|
if (ctx->excess_bytes <= le16_to_cpu(db->second_req_count)) {
|
||||||
/* This descriptor isn't done yet, stop iteration. */
|
/* This descriptor isn't done yet, stop iteration. */
|
||||||
return 0;
|
return 0;
|
||||||
@ -1513,7 +1518,7 @@ static int handle_ir_dualbuffer_packet(struct context *context,
|
|||||||
memcpy(ctx->header + i + 4, p + 8, ctx->base.header_size - 4);
|
memcpy(ctx->header + i + 4, p + 8, ctx->base.header_size - 4);
|
||||||
i += ctx->base.header_size;
|
i += ctx->base.header_size;
|
||||||
ctx->excess_bytes +=
|
ctx->excess_bytes +=
|
||||||
(le32_to_cpu(*(u32 *)(p + 4)) >> 16) & 0xffff;
|
(le32_to_cpu(*(__le32 *)(p + 4)) >> 16) & 0xffff;
|
||||||
p += ctx->base.header_size + 4;
|
p += ctx->base.header_size + 4;
|
||||||
}
|
}
|
||||||
ctx->header_length = i;
|
ctx->header_length = i;
|
||||||
@ -2048,6 +2053,18 @@ pci_probe(struct pci_dev *dev, const struct pci_device_id *ent)
|
|||||||
int err;
|
int err;
|
||||||
size_t size;
|
size_t size;
|
||||||
|
|
||||||
|
#ifdef CONFIG_PPC_PMAC
|
||||||
|
/* Necessary on some machines if fw-ohci was loaded/ unloaded before */
|
||||||
|
if (machine_is(powermac)) {
|
||||||
|
struct device_node *ofn = pci_device_to_OF_node(dev);
|
||||||
|
|
||||||
|
if (ofn) {
|
||||||
|
pmac_call_feature(PMAC_FTR_1394_CABLE_POWER, ofn, 0, 1);
|
||||||
|
pmac_call_feature(PMAC_FTR_1394_ENABLE, ofn, 0, 1);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
#endif /* CONFIG_PPC_PMAC */
|
||||||
|
|
||||||
ohci = kzalloc(sizeof(*ohci), GFP_KERNEL);
|
ohci = kzalloc(sizeof(*ohci), GFP_KERNEL);
|
||||||
if (ohci == NULL) {
|
if (ohci == NULL) {
|
||||||
fw_error("Could not malloc fw_ohci data.\n");
|
fw_error("Could not malloc fw_ohci data.\n");
|
||||||
@ -2066,6 +2083,10 @@ pci_probe(struct pci_dev *dev, const struct pci_device_id *ent)
|
|||||||
pci_write_config_dword(dev, OHCI1394_PCI_HCI_Control, 0);
|
pci_write_config_dword(dev, OHCI1394_PCI_HCI_Control, 0);
|
||||||
pci_set_drvdata(dev, ohci);
|
pci_set_drvdata(dev, ohci);
|
||||||
|
|
||||||
|
#if defined(CONFIG_PPC_PMAC) && defined(CONFIG_PPC32)
|
||||||
|
ohci->old_uninorth = dev->vendor == PCI_VENDOR_ID_APPLE &&
|
||||||
|
dev->device == PCI_DEVICE_ID_APPLE_UNI_N_FW;
|
||||||
|
#endif
|
||||||
spin_lock_init(&ohci->lock);
|
spin_lock_init(&ohci->lock);
|
||||||
|
|
||||||
tasklet_init(&ohci->bus_reset_tasklet,
|
tasklet_init(&ohci->bus_reset_tasklet,
|
||||||
@ -2182,6 +2203,19 @@ static void pci_remove(struct pci_dev *dev)
|
|||||||
pci_disable_device(dev);
|
pci_disable_device(dev);
|
||||||
fw_card_put(&ohci->card);
|
fw_card_put(&ohci->card);
|
||||||
|
|
||||||
|
#ifdef CONFIG_PPC_PMAC
|
||||||
|
/* On UniNorth, power down the cable and turn off the chip clock
|
||||||
|
* to save power on laptops */
|
||||||
|
if (machine_is(powermac)) {
|
||||||
|
struct device_node *ofn = pci_device_to_OF_node(dev);
|
||||||
|
|
||||||
|
if (ofn) {
|
||||||
|
pmac_call_feature(PMAC_FTR_1394_ENABLE, ofn, 0, 0);
|
||||||
|
pmac_call_feature(PMAC_FTR_1394_CABLE_POWER, ofn, 0, 0);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
#endif /* CONFIG_PPC_PMAC */
|
||||||
|
|
||||||
fw_notify("Removed fw-ohci device.\n");
|
fw_notify("Removed fw-ohci device.\n");
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -2202,6 +2236,16 @@ static int pci_suspend(struct pci_dev *pdev, pm_message_t state)
|
|||||||
if (err)
|
if (err)
|
||||||
fw_error("pci_set_power_state failed with %d\n", err);
|
fw_error("pci_set_power_state failed with %d\n", err);
|
||||||
|
|
||||||
|
/* PowerMac suspend code comes last */
|
||||||
|
#ifdef CONFIG_PPC_PMAC
|
||||||
|
if (machine_is(powermac)) {
|
||||||
|
struct device_node *ofn = pci_device_to_OF_node(pdev);
|
||||||
|
|
||||||
|
if (ofn)
|
||||||
|
pmac_call_feature(PMAC_FTR_1394_ENABLE, ofn, 0, 0);
|
||||||
|
}
|
||||||
|
#endif /* CONFIG_PPC_PMAC */
|
||||||
|
|
||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -2210,6 +2254,16 @@ static int pci_resume(struct pci_dev *pdev)
|
|||||||
struct fw_ohci *ohci = pci_get_drvdata(pdev);
|
struct fw_ohci *ohci = pci_get_drvdata(pdev);
|
||||||
int err;
|
int err;
|
||||||
|
|
||||||
|
/* PowerMac resume code comes first */
|
||||||
|
#ifdef CONFIG_PPC_PMAC
|
||||||
|
if (machine_is(powermac)) {
|
||||||
|
struct device_node *ofn = pci_device_to_OF_node(pdev);
|
||||||
|
|
||||||
|
if (ofn)
|
||||||
|
pmac_call_feature(PMAC_FTR_1394_ENABLE, ofn, 0, 1);
|
||||||
|
}
|
||||||
|
#endif /* CONFIG_PPC_PMAC */
|
||||||
|
|
||||||
pci_set_power_state(pdev, PCI_D0);
|
pci_set_power_state(pdev, PCI_D0);
|
||||||
pci_restore_state(pdev);
|
pci_restore_state(pdev);
|
||||||
err = pci_enable_device(pdev);
|
err = pci_enable_device(pdev);
|
||||||
|
@ -173,6 +173,7 @@ struct sbp2_target {
|
|||||||
#define SBP2_ORB_TIMEOUT 2000U /* Timeout in ms */
|
#define SBP2_ORB_TIMEOUT 2000U /* Timeout in ms */
|
||||||
#define SBP2_ORB_NULL 0x80000000
|
#define SBP2_ORB_NULL 0x80000000
|
||||||
#define SBP2_MAX_SG_ELEMENT_LENGTH 0xf000
|
#define SBP2_MAX_SG_ELEMENT_LENGTH 0xf000
|
||||||
|
#define SBP2_RETRY_LIMIT 0xf /* 15 retries */
|
||||||
|
|
||||||
#define SBP2_DIRECTION_TO_MEDIA 0x0
|
#define SBP2_DIRECTION_TO_MEDIA 0x0
|
||||||
#define SBP2_DIRECTION_FROM_MEDIA 0x1
|
#define SBP2_DIRECTION_FROM_MEDIA 0x1
|
||||||
@ -330,6 +331,11 @@ static const struct {
|
|||||||
.model = ~0,
|
.model = ~0,
|
||||||
.workarounds = SBP2_WORKAROUND_128K_MAX_TRANS,
|
.workarounds = SBP2_WORKAROUND_128K_MAX_TRANS,
|
||||||
},
|
},
|
||||||
|
/* Datafab MD2-FW2 with Symbios/LSILogic SYM13FW500 bridge */ {
|
||||||
|
.firmware_revision = 0x002600,
|
||||||
|
.model = ~0,
|
||||||
|
.workarounds = SBP2_WORKAROUND_128K_MAX_TRANS,
|
||||||
|
},
|
||||||
|
|
||||||
/*
|
/*
|
||||||
* There are iPods (2nd gen, 3rd gen) with model_id == 0, but
|
* There are iPods (2nd gen, 3rd gen) with model_id == 0, but
|
||||||
@ -812,6 +818,30 @@ static void sbp2_target_put(struct sbp2_target *tgt)
|
|||||||
kref_put(&tgt->kref, sbp2_release_target);
|
kref_put(&tgt->kref, sbp2_release_target);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
static void
|
||||||
|
complete_set_busy_timeout(struct fw_card *card, int rcode,
|
||||||
|
void *payload, size_t length, void *done)
|
||||||
|
{
|
||||||
|
complete(done);
|
||||||
|
}
|
||||||
|
|
||||||
|
static void sbp2_set_busy_timeout(struct sbp2_logical_unit *lu)
|
||||||
|
{
|
||||||
|
struct fw_device *device = fw_device(lu->tgt->unit->device.parent);
|
||||||
|
DECLARE_COMPLETION_ONSTACK(done);
|
||||||
|
struct fw_transaction t;
|
||||||
|
static __be32 busy_timeout;
|
||||||
|
|
||||||
|
/* FIXME: we should try to set dual-phase cycle_limit too */
|
||||||
|
busy_timeout = cpu_to_be32(SBP2_RETRY_LIMIT);
|
||||||
|
|
||||||
|
fw_send_request(device->card, &t, TCODE_WRITE_QUADLET_REQUEST,
|
||||||
|
lu->tgt->node_id, lu->generation, device->max_speed,
|
||||||
|
CSR_REGISTER_BASE + CSR_BUSY_TIMEOUT, &busy_timeout,
|
||||||
|
sizeof(busy_timeout), complete_set_busy_timeout, &done);
|
||||||
|
wait_for_completion(&done);
|
||||||
|
}
|
||||||
|
|
||||||
static void sbp2_reconnect(struct work_struct *work);
|
static void sbp2_reconnect(struct work_struct *work);
|
||||||
|
|
||||||
static void sbp2_login(struct work_struct *work)
|
static void sbp2_login(struct work_struct *work)
|
||||||
@ -864,10 +894,8 @@ static void sbp2_login(struct work_struct *work)
|
|||||||
fw_notify("%s: logged in to LUN %04x (%d retries)\n",
|
fw_notify("%s: logged in to LUN %04x (%d retries)\n",
|
||||||
tgt->bus_id, lu->lun, lu->retries);
|
tgt->bus_id, lu->lun, lu->retries);
|
||||||
|
|
||||||
#if 0
|
/* set appropriate retry limit(s) in BUSY_TIMEOUT register */
|
||||||
/* FIXME: The linux1394 sbp2 does this last step. */
|
sbp2_set_busy_timeout(lu);
|
||||||
sbp2_set_busy_timeout(scsi_id);
|
|
||||||
#endif
|
|
||||||
|
|
||||||
PREPARE_DELAYED_WORK(&lu->work, sbp2_reconnect);
|
PREPARE_DELAYED_WORK(&lu->work, sbp2_reconnect);
|
||||||
sbp2_agent_reset(lu);
|
sbp2_agent_reset(lu);
|
||||||
|
@ -21,6 +21,7 @@
|
|||||||
#include <linux/module.h>
|
#include <linux/module.h>
|
||||||
#include <linux/wait.h>
|
#include <linux/wait.h>
|
||||||
#include <linux/errno.h>
|
#include <linux/errno.h>
|
||||||
|
#include <asm/bug.h>
|
||||||
#include <asm/system.h>
|
#include <asm/system.h>
|
||||||
#include "fw-transaction.h"
|
#include "fw-transaction.h"
|
||||||
#include "fw-topology.h"
|
#include "fw-topology.h"
|
||||||
@ -424,8 +425,8 @@ update_tree(struct fw_card *card, struct fw_node *root)
|
|||||||
node1 = fw_node(list1.next);
|
node1 = fw_node(list1.next);
|
||||||
|
|
||||||
while (&node0->link != &list0) {
|
while (&node0->link != &list0) {
|
||||||
|
WARN_ON(node0->port_count != node1->port_count);
|
||||||
|
|
||||||
/* assert(node0->port_count == node1->port_count); */
|
|
||||||
if (node0->link_on && !node1->link_on)
|
if (node0->link_on && !node1->link_on)
|
||||||
event = FW_NODE_LINK_OFF;
|
event = FW_NODE_LINK_OFF;
|
||||||
else if (!node0->link_on && node1->link_on)
|
else if (!node0->link_on && node1->link_on)
|
||||||
|
@ -751,7 +751,7 @@ handle_topology_map(struct fw_card *card, struct fw_request *request,
|
|||||||
void *payload, size_t length, void *callback_data)
|
void *payload, size_t length, void *callback_data)
|
||||||
{
|
{
|
||||||
int i, start, end;
|
int i, start, end;
|
||||||
u32 *map;
|
__be32 *map;
|
||||||
|
|
||||||
if (!TCODE_IS_READ_REQUEST(tcode)) {
|
if (!TCODE_IS_READ_REQUEST(tcode)) {
|
||||||
fw_send_response(card, request, RCODE_TYPE_ERROR);
|
fw_send_response(card, request, RCODE_TYPE_ERROR);
|
||||||
|
@ -86,12 +86,12 @@
|
|||||||
static inline void
|
static inline void
|
||||||
fw_memcpy_from_be32(void *_dst, void *_src, size_t size)
|
fw_memcpy_from_be32(void *_dst, void *_src, size_t size)
|
||||||
{
|
{
|
||||||
u32 *dst = _dst;
|
u32 *dst = _dst;
|
||||||
u32 *src = _src;
|
__be32 *src = _src;
|
||||||
int i;
|
int i;
|
||||||
|
|
||||||
for (i = 0; i < size / 4; i++)
|
for (i = 0; i < size / 4; i++)
|
||||||
dst[i] = cpu_to_be32(src[i]);
|
dst[i] = be32_to_cpu(src[i]);
|
||||||
}
|
}
|
||||||
|
|
||||||
static inline void
|
static inline void
|
||||||
|
@ -376,6 +376,11 @@ static const struct {
|
|||||||
.model_id = SBP2_ROM_VALUE_WILDCARD,
|
.model_id = SBP2_ROM_VALUE_WILDCARD,
|
||||||
.workarounds = SBP2_WORKAROUND_128K_MAX_TRANS,
|
.workarounds = SBP2_WORKAROUND_128K_MAX_TRANS,
|
||||||
},
|
},
|
||||||
|
/* Datafab MD2-FW2 with Symbios/LSILogic SYM13FW500 bridge */ {
|
||||||
|
.firmware_revision = 0x002600,
|
||||||
|
.model_id = SBP2_ROM_VALUE_WILDCARD,
|
||||||
|
.workarounds = SBP2_WORKAROUND_128K_MAX_TRANS,
|
||||||
|
},
|
||||||
/* iPod 4th generation */ {
|
/* iPod 4th generation */ {
|
||||||
.firmware_revision = 0x0a2700,
|
.firmware_revision = 0x0a2700,
|
||||||
.model_id = 0x000021,
|
.model_id = 0x000021,
|
||||||
|
Loading…
Reference in New Issue
Block a user