aboutsummaryrefslogtreecommitdiffstats
path: root/drivers/ieee1394/ohci1394.c
diff options
context:
space:
mode:
Diffstat (limited to 'drivers/ieee1394/ohci1394.c')
-rw-r--r--drivers/ieee1394/ohci1394.c73
1 files changed, 42 insertions, 31 deletions
diff --git a/drivers/ieee1394/ohci1394.c b/drivers/ieee1394/ohci1394.c
index 448df2773377..8fd0030475ba 100644
--- a/drivers/ieee1394/ohci1394.c
+++ b/drivers/ieee1394/ohci1394.c
@@ -136,7 +136,7 @@
136#define DBGMSG(fmt, args...) \ 136#define DBGMSG(fmt, args...) \
137printk(KERN_INFO "%s: fw-host%d: " fmt "\n" , OHCI1394_DRIVER_NAME, ohci->host->id , ## args) 137printk(KERN_INFO "%s: fw-host%d: " fmt "\n" , OHCI1394_DRIVER_NAME, ohci->host->id , ## args)
138#else 138#else
139#define DBGMSG(fmt, args...) 139#define DBGMSG(fmt, args...) do {} while (0)
140#endif 140#endif
141 141
142#ifdef CONFIG_IEEE1394_OHCI_DMA_DEBUG 142#ifdef CONFIG_IEEE1394_OHCI_DMA_DEBUG
@@ -148,8 +148,8 @@ printk(KERN_INFO "%s: fw-host%d: " fmt "\n" , OHCI1394_DRIVER_NAME, ohci->host->
148 --global_outstanding_dmas, ## args) 148 --global_outstanding_dmas, ## args)
149static int global_outstanding_dmas = 0; 149static int global_outstanding_dmas = 0;
150#else 150#else
151#define OHCI_DMA_ALLOC(fmt, args...) 151#define OHCI_DMA_ALLOC(fmt, args...) do {} while (0)
152#define OHCI_DMA_FREE(fmt, args...) 152#define OHCI_DMA_FREE(fmt, args...) do {} while (0)
153#endif 153#endif
154 154
155/* print general (card independent) information */ 155/* print general (card independent) information */
@@ -181,36 +181,35 @@ static int alloc_dma_trm_ctx(struct ti_ohci *ohci, struct dma_trm_ctx *d,
181static void ohci1394_pci_remove(struct pci_dev *pdev); 181static void ohci1394_pci_remove(struct pci_dev *pdev);
182 182
183#ifndef __LITTLE_ENDIAN 183#ifndef __LITTLE_ENDIAN
184static unsigned hdr_sizes[] = 184const static size_t hdr_sizes[] = {
185{
186 3, /* TCODE_WRITEQ */ 185 3, /* TCODE_WRITEQ */
187 4, /* TCODE_WRITEB */ 186 4, /* TCODE_WRITEB */
188 3, /* TCODE_WRITE_RESPONSE */ 187 3, /* TCODE_WRITE_RESPONSE */
189 0, /* ??? */ 188 0, /* reserved */
190 3, /* TCODE_READQ */ 189 3, /* TCODE_READQ */
191 4, /* TCODE_READB */ 190 4, /* TCODE_READB */
192 3, /* TCODE_READQ_RESPONSE */ 191 3, /* TCODE_READQ_RESPONSE */
193 4, /* TCODE_READB_RESPONSE */ 192 4, /* TCODE_READB_RESPONSE */
194 1, /* TCODE_CYCLE_START (???) */ 193 1, /* TCODE_CYCLE_START */
195 4, /* TCODE_LOCK_REQUEST */ 194 4, /* TCODE_LOCK_REQUEST */
196 2, /* TCODE_ISO_DATA */ 195 2, /* TCODE_ISO_DATA */
197 4, /* TCODE_LOCK_RESPONSE */ 196 4, /* TCODE_LOCK_RESPONSE */
197 /* rest is reserved or link-internal */
198}; 198};
199 199
200/* Swap headers */ 200static inline void header_le32_to_cpu(quadlet_t *data, unsigned char tcode)
201static inline void packet_swab(quadlet_t *data, int tcode)
202{ 201{
203 size_t size = hdr_sizes[tcode]; 202 size_t size;
204 203
205 if (tcode > TCODE_LOCK_RESPONSE || hdr_sizes[tcode] == 0) 204 if (unlikely(tcode >= ARRAY_SIZE(hdr_sizes)))
206 return; 205 return;
207 206
207 size = hdr_sizes[tcode];
208 while (size--) 208 while (size--)
209 data[size] = swab32(data[size]); 209 data[size] = le32_to_cpu(data[size]);
210} 210}
211#else 211#else
212/* Don't waste cycles on same sex byte swaps */ 212#define header_le32_to_cpu(w,x) do {} while (0)
213#define packet_swab(w,x)
214#endif /* !LITTLE_ENDIAN */ 213#endif /* !LITTLE_ENDIAN */
215 214
216/*********************************** 215/***********************************
@@ -701,7 +700,7 @@ static void insert_packet(struct ti_ohci *ohci,
701 d->prg_cpu[idx]->data[2] = packet->header[2]; 700 d->prg_cpu[idx]->data[2] = packet->header[2];
702 d->prg_cpu[idx]->data[3] = packet->header[3]; 701 d->prg_cpu[idx]->data[3] = packet->header[3];
703 } 702 }
704 packet_swab(d->prg_cpu[idx]->data, packet->tcode); 703 header_le32_to_cpu(d->prg_cpu[idx]->data, packet->tcode);
705 } 704 }
706 705
707 if (packet->data_size) { /* block transmit */ 706 if (packet->data_size) { /* block transmit */
@@ -777,7 +776,7 @@ static void insert_packet(struct ti_ohci *ohci,
777 d->prg_cpu[idx]->data[0] = packet->speed_code<<16 | 776 d->prg_cpu[idx]->data[0] = packet->speed_code<<16 |
778 (packet->header[0] & 0xFFFF); 777 (packet->header[0] & 0xFFFF);
779 d->prg_cpu[idx]->data[1] = packet->header[0] & 0xFFFF0000; 778 d->prg_cpu[idx]->data[1] = packet->header[0] & 0xFFFF0000;
780 packet_swab(d->prg_cpu[idx]->data, packet->tcode); 779 header_le32_to_cpu(d->prg_cpu[idx]->data, packet->tcode);
781 780
782 d->prg_cpu[idx]->begin.control = 781 d->prg_cpu[idx]->begin.control =
783 cpu_to_le32(DMA_CTL_OUTPUT_MORE | 782 cpu_to_le32(DMA_CTL_OUTPUT_MORE |
@@ -2598,8 +2597,9 @@ static const int TCODE_SIZE[16] = {20, 0, 16, -1, 16, 20, 20, 0,
2598 * Determine the length of a packet in the buffer 2597 * Determine the length of a packet in the buffer
2599 * Optimization suggested by Pascal Drolet <pascal.drolet@informission.ca> 2598 * Optimization suggested by Pascal Drolet <pascal.drolet@informission.ca>
2600 */ 2599 */
2601static __inline__ int packet_length(struct dma_rcv_ctx *d, int idx, quadlet_t *buf_ptr, 2600static inline int packet_length(struct dma_rcv_ctx *d, int idx,
2602 int offset, unsigned char tcode, int noswap) 2601 quadlet_t *buf_ptr, int offset,
2602 unsigned char tcode, int noswap)
2603{ 2603{
2604 int length = -1; 2604 int length = -1;
2605 2605
@@ -2730,7 +2730,7 @@ static void dma_rcv_tasklet (unsigned long data)
2730 * bus reset. We always ignore it. */ 2730 * bus reset. We always ignore it. */
2731 if (tcode != OHCI1394_TCODE_PHY) { 2731 if (tcode != OHCI1394_TCODE_PHY) {
2732 if (!ohci->no_swap_incoming) 2732 if (!ohci->no_swap_incoming)
2733 packet_swab(d->spb, tcode); 2733 header_le32_to_cpu(d->spb, tcode);
2734 DBGMSG("Packet received from node" 2734 DBGMSG("Packet received from node"
2735 " %d ack=0x%02X spd=%d tcode=0x%X" 2735 " %d ack=0x%02X spd=%d tcode=0x%X"
2736 " length=%d ctx=%d tlabel=%d", 2736 " length=%d ctx=%d tlabel=%d",
@@ -2738,7 +2738,7 @@ static void dma_rcv_tasklet (unsigned long data)
2738 (cond_le32_to_cpu(d->spb[length/4-1], ohci->no_swap_incoming)>>16)&0x1f, 2738 (cond_le32_to_cpu(d->spb[length/4-1], ohci->no_swap_incoming)>>16)&0x1f,
2739 (cond_le32_to_cpu(d->spb[length/4-1], ohci->no_swap_incoming)>>21)&0x3, 2739 (cond_le32_to_cpu(d->spb[length/4-1], ohci->no_swap_incoming)>>21)&0x3,
2740 tcode, length, d->ctx, 2740 tcode, length, d->ctx,
2741 (cond_le32_to_cpu(d->spb[0], ohci->no_swap_incoming)>>10)&0x3f); 2741 (d->spb[0]>>10)&0x3f);
2742 2742
2743 ack = (((cond_le32_to_cpu(d->spb[length/4-1], ohci->no_swap_incoming)>>16)&0x1f) 2743 ack = (((cond_le32_to_cpu(d->spb[length/4-1], ohci->no_swap_incoming)>>16)&0x1f)
2744 == 0x11) ? 1 : 0; 2744 == 0x11) ? 1 : 0;
@@ -3529,9 +3529,10 @@ static void ohci1394_pci_remove(struct pci_dev *pdev)
3529 put_device(dev); 3529 put_device(dev);
3530} 3530}
3531 3531
3532 3532#ifdef CONFIG_PM
3533static int ohci1394_pci_resume (struct pci_dev *pdev) 3533static int ohci1394_pci_resume (struct pci_dev *pdev)
3534{ 3534{
3535/* PowerMac resume code comes first */
3535#ifdef CONFIG_PPC_PMAC 3536#ifdef CONFIG_PPC_PMAC
3536 if (machine_is(powermac)) { 3537 if (machine_is(powermac)) {
3537 struct device_node *of_node; 3538 struct device_node *of_node;
@@ -3543,17 +3544,23 @@ static int ohci1394_pci_resume (struct pci_dev *pdev)
3543 } 3544 }
3544#endif /* CONFIG_PPC_PMAC */ 3545#endif /* CONFIG_PPC_PMAC */
3545 3546
3547 pci_set_power_state(pdev, PCI_D0);
3546 pci_restore_state(pdev); 3548 pci_restore_state(pdev);
3547 pci_enable_device(pdev); 3549 return pci_enable_device(pdev);
3548
3549 return 0;
3550} 3550}
3551 3551
3552
3553static int ohci1394_pci_suspend (struct pci_dev *pdev, pm_message_t state) 3552static int ohci1394_pci_suspend (struct pci_dev *pdev, pm_message_t state)
3554{ 3553{
3555 pci_save_state(pdev); 3554 int err;
3555
3556 err = pci_save_state(pdev);
3557 if (err)
3558 goto out;
3559 err = pci_set_power_state(pdev, pci_choose_state(pdev, state));
3560 if (err)
3561 goto out;
3556 3562
3563/* PowerMac suspend code comes last */
3557#ifdef CONFIG_PPC_PMAC 3564#ifdef CONFIG_PPC_PMAC
3558 if (machine_is(powermac)) { 3565 if (machine_is(powermac)) {
3559 struct device_node *of_node; 3566 struct device_node *of_node;
@@ -3563,11 +3570,11 @@ static int ohci1394_pci_suspend (struct pci_dev *pdev, pm_message_t state)
3563 if (of_node) 3570 if (of_node)
3564 pmac_call_feature(PMAC_FTR_1394_ENABLE, of_node, 0, 0); 3571 pmac_call_feature(PMAC_FTR_1394_ENABLE, of_node, 0, 0);
3565 } 3572 }
3566#endif 3573#endif /* CONFIG_PPC_PMAC */
3567 3574out:
3568 return 0; 3575 return err;
3569} 3576}
3570 3577#endif /* CONFIG_PM */
3571 3578
3572#define PCI_CLASS_FIREWIRE_OHCI ((PCI_CLASS_SERIAL_FIREWIRE << 8) | 0x10) 3579#define PCI_CLASS_FIREWIRE_OHCI ((PCI_CLASS_SERIAL_FIREWIRE << 8) | 0x10)
3573 3580
@@ -3590,8 +3597,10 @@ static struct pci_driver ohci1394_pci_driver = {
3590 .id_table = ohci1394_pci_tbl, 3597 .id_table = ohci1394_pci_tbl,
3591 .probe = ohci1394_pci_probe, 3598 .probe = ohci1394_pci_probe,
3592 .remove = ohci1394_pci_remove, 3599 .remove = ohci1394_pci_remove,
3600#ifdef CONFIG_PM
3593 .resume = ohci1394_pci_resume, 3601 .resume = ohci1394_pci_resume,
3594 .suspend = ohci1394_pci_suspend, 3602 .suspend = ohci1394_pci_suspend,
3603#endif
3595}; 3604};
3596 3605
3597/*********************************** 3606/***********************************
@@ -3718,5 +3727,7 @@ static int __init ohci1394_init(void)
3718 return pci_register_driver(&ohci1394_pci_driver); 3727 return pci_register_driver(&ohci1394_pci_driver);
3719} 3728}
3720 3729
3721module_init(ohci1394_init); 3730/* Register before most other device drivers.
3731 * Useful for remote debugging via physical DMA, e.g. using firescope. */
3732fs_initcall(ohci1394_init);
3722module_exit(ohci1394_cleanup); 3733module_exit(ohci1394_cleanup);