Skip to content

Commit

Permalink
firewire: fw-ohci: Apple UniNorth 1st generation support
Browse files Browse the repository at this point in the history
Mostly copied from ohci1394.c.  Necessary for some older Macs, e.g.
PowerBook G3 Pismo and early PowerBook G4 Titanium.

Signed-off-by: Stefan Richter <stefanr@s5r6.in-berlin.de>
  • Loading branch information
Stefan Richter committed Mar 13, 2008
1 parent ea8d006 commit 11bf20a
Showing 1 changed file with 21 additions and 8 deletions.
29 changes: 21 additions & 8 deletions drivers/firewire/fw-ohci.c
Original file line number Diff line number Diff line change
Expand Up @@ -179,6 +179,7 @@ struct fw_ohci {
int generation;
int request_generation;
u32 bus_seconds;
bool old_uninorth;

/*
* Spinlock for accessing fw_ohci data. Never call out of
Expand Down Expand Up @@ -315,15 +316,22 @@ static int ar_context_add_page(struct ar_context *ctx)
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)
{
struct fw_ohci *ohci = ctx->ohci;
struct fw_packet p;
u32 status, length, tcode;

p.header[0] = le32_to_cpu(buffer[0]);
p.header[1] = le32_to_cpu(buffer[1]);
p.header[2] = le32_to_cpu(buffer[2]);
p.header[0] = cond_le32_to_cpu(buffer[0]);
p.header[1] = cond_le32_to_cpu(buffer[1]);
p.header[2] = cond_le32_to_cpu(buffer[2]);

tcode = (p.header[0] >> 4) & 0x0f;
switch (tcode) {
Expand All @@ -335,7 +343,7 @@ static __le32 *handle_ar_packet(struct ar_context *ctx, __le32 *buffer)
break;

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.payload_length = 0;
break;
Expand All @@ -344,7 +352,7 @@ static __le32 *handle_ar_packet(struct ar_context *ctx, __le32 *buffer)
case TCODE_READ_BLOCK_RESPONSE:
case TCODE_LOCK_REQUEST:
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.payload_length = p.header[3] >> 16;
break;
Expand All @@ -361,7 +369,7 @@ static __le32 *handle_ar_packet(struct ar_context *ctx, __le32 *buffer)

/* FIXME: What to do about evt_* errors? */
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.speed = (status >> 21) & 0x7;
Expand Down Expand Up @@ -1026,13 +1034,14 @@ static void bus_reset_tasklet(unsigned long data)
*/

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();

for (i = 1, j = 0; j < self_id_count; i += 2, j++) {
if (ohci->self_id_cpu[i] != ~ohci->self_id_cpu[i + 1])
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();

Expand Down Expand Up @@ -2082,6 +2091,10 @@ pci_probe(struct pci_dev *dev, const struct pci_device_id *ent)
pci_write_config_dword(dev, OHCI1394_PCI_HCI_Control, 0);
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);

tasklet_init(&ohci->bus_reset_tasklet,
Expand Down

0 comments on commit 11bf20a

Please sign in to comment.