aboutsummaryrefslogtreecommitdiffstats
path: root/drivers/firewire/fw-ohci.c
diff options
context:
space:
mode:
authorStefan Richter <stefanr@s5r6.in-berlin.de>2008-02-29 20:47:15 -0500
committerStefan Richter <stefanr@s5r6.in-berlin.de>2008-03-13 19:56:59 -0400
commit11bf20ad028880a56689f086bfbabfd88b2af38b (patch)
treee09c2597d61ef8aa989dd2833889004c76d6a058 /drivers/firewire/fw-ohci.c
parentea8d006b91ac58ec5a0862d09e0b629db399517f (diff)
firewire: fw-ohci: Apple UniNorth 1st generation support
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>
Diffstat (limited to 'drivers/firewire/fw-ohci.c')
-rw-r--r--drivers/firewire/fw-ohci.c29
1 files changed, 21 insertions, 8 deletions
diff --git a/drivers/firewire/fw-ohci.c b/drivers/firewire/fw-ohci.c
index 182be8672dfd..eaa213e21592 100644
--- a/drivers/firewire/fw-ohci.c
+++ b/drivers/firewire/fw-ohci.c
@@ -179,6 +179,7 @@ struct fw_ohci {
179 int generation; 179 int generation;
180 int request_generation; 180 int request_generation;
181 u32 bus_seconds; 181 u32 bus_seconds;
182 bool old_uninorth;
182 183
183 /* 184 /*
184 * Spinlock for accessing fw_ohci data. Never call out of 185 * Spinlock for accessing fw_ohci data. Never call out of
@@ -315,15 +316,22 @@ static int ar_context_add_page(struct ar_context *ctx)
315 return 0; 316 return 0;
316} 317}
317 318
319#if defined(CONFIG_PPC_PMAC) && defined(CONFIG_PPC32)
320#define cond_le32_to_cpu(v) \
321 (ohci->old_uninorth ? (__force __u32)(v) : le32_to_cpu(v))
322#else
323#define cond_le32_to_cpu(v) le32_to_cpu(v)
324#endif
325
318static __le32 *handle_ar_packet(struct ar_context *ctx, __le32 *buffer) 326static __le32 *handle_ar_packet(struct ar_context *ctx, __le32 *buffer)
319{ 327{
320 struct fw_ohci *ohci = ctx->ohci; 328 struct fw_ohci *ohci = ctx->ohci;
321 struct fw_packet p; 329 struct fw_packet p;
322 u32 status, length, tcode; 330 u32 status, length, tcode;
323 331
324 p.header[0] = le32_to_cpu(buffer[0]); 332 p.header[0] = cond_le32_to_cpu(buffer[0]);
325 p.header[1] = le32_to_cpu(buffer[1]); 333 p.header[1] = cond_le32_to_cpu(buffer[1]);
326 p.header[2] = le32_to_cpu(buffer[2]); 334 p.header[2] = cond_le32_to_cpu(buffer[2]);
327 335
328 tcode = (p.header[0] >> 4) & 0x0f; 336 tcode = (p.header[0] >> 4) & 0x0f;
329 switch (tcode) { 337 switch (tcode) {
@@ -335,7 +343,7 @@ static __le32 *handle_ar_packet(struct ar_context *ctx, __le32 *buffer)
335 break; 343 break;
336 344
337 case TCODE_READ_BLOCK_REQUEST : 345 case TCODE_READ_BLOCK_REQUEST :
338 p.header[3] = le32_to_cpu(buffer[3]); 346 p.header[3] = cond_le32_to_cpu(buffer[3]);
339 p.header_length = 16; 347 p.header_length = 16;
340 p.payload_length = 0; 348 p.payload_length = 0;
341 break; 349 break;
@@ -344,7 +352,7 @@ static __le32 *handle_ar_packet(struct ar_context *ctx, __le32 *buffer)
344 case TCODE_READ_BLOCK_RESPONSE: 352 case TCODE_READ_BLOCK_RESPONSE:
345 case TCODE_LOCK_REQUEST: 353 case TCODE_LOCK_REQUEST:
346 case TCODE_LOCK_RESPONSE: 354 case TCODE_LOCK_RESPONSE:
347 p.header[3] = le32_to_cpu(buffer[3]); 355 p.header[3] = cond_le32_to_cpu(buffer[3]);
348 p.header_length = 16; 356 p.header_length = 16;
349 p.payload_length = p.header[3] >> 16; 357 p.payload_length = p.header[3] >> 16;
350 break; 358 break;
@@ -361,7 +369,7 @@ static __le32 *handle_ar_packet(struct ar_context *ctx, __le32 *buffer)
361 369
362 /* FIXME: What to do about evt_* errors? */ 370 /* FIXME: What to do about evt_* errors? */
363 length = (p.header_length + p.payload_length + 3) / 4; 371 length = (p.header_length + p.payload_length + 3) / 4;
364 status = le32_to_cpu(buffer[length]); 372 status = cond_le32_to_cpu(buffer[length]);
365 373
366 p.ack = ((status >> 16) & 0x1f) - 16; 374 p.ack = ((status >> 16) & 0x1f) - 16;
367 p.speed = (status >> 21) & 0x7; 375 p.speed = (status >> 21) & 0x7;
@@ -1026,13 +1034,14 @@ static void bus_reset_tasklet(unsigned long data)
1026 */ 1034 */
1027 1035
1028 self_id_count = (reg_read(ohci, OHCI1394_SelfIDCount) >> 3) & 0x3ff; 1036 self_id_count = (reg_read(ohci, OHCI1394_SelfIDCount) >> 3) & 0x3ff;
1029 generation = (le32_to_cpu(ohci->self_id_cpu[0]) >> 16) & 0xff; 1037 generation = (cond_le32_to_cpu(ohci->self_id_cpu[0]) >> 16) & 0xff;
1030 rmb(); 1038 rmb();
1031 1039
1032 for (i = 1, j = 0; j < self_id_count; i += 2, j++) { 1040 for (i = 1, j = 0; j < self_id_count; i += 2, j++) {
1033 if (ohci->self_id_cpu[i] != ~ohci->self_id_cpu[i + 1]) 1041 if (ohci->self_id_cpu[i] != ~ohci->self_id_cpu[i + 1])
1034 fw_error("inconsistent self IDs\n"); 1042 fw_error("inconsistent self IDs\n");
1035 ohci->self_id_buffer[j] = le32_to_cpu(ohci->self_id_cpu[i]); 1043 ohci->self_id_buffer[j] =
1044 cond_le32_to_cpu(ohci->self_id_cpu[i]);
1036 } 1045 }
1037 rmb(); 1046 rmb();
1038 1047
@@ -2082,6 +2091,10 @@ pci_probe(struct pci_dev *dev, const struct pci_device_id *ent)
2082 pci_write_config_dword(dev, OHCI1394_PCI_HCI_Control, 0); 2091 pci_write_config_dword(dev, OHCI1394_PCI_HCI_Control, 0);
2083 pci_set_drvdata(dev, ohci); 2092 pci_set_drvdata(dev, ohci);
2084 2093
2094#if defined(CONFIG_PPC_PMAC) && defined(CONFIG_PPC32)
2095 ohci->old_uninorth = dev->vendor == PCI_VENDOR_ID_APPLE &&
2096 dev->device == PCI_DEVICE_ID_APPLE_UNI_N_FW;
2097#endif
2085 spin_lock_init(&ohci->lock); 2098 spin_lock_init(&ohci->lock);
2086 2099
2087 tasklet_init(&ohci->bus_reset_tasklet, 2100 tasklet_init(&ohci->bus_reset_tasklet,