diff options
Diffstat (limited to 'drivers/ieee1394/ohci1394.c')
-rw-r--r-- | drivers/ieee1394/ohci1394.c | 73 |
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...) \ |
137 | printk(KERN_INFO "%s: fw-host%d: " fmt "\n" , OHCI1394_DRIVER_NAME, ohci->host->id , ## args) | 137 | printk(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) |
149 | static int global_outstanding_dmas = 0; | 149 | static 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, | |||
181 | static void ohci1394_pci_remove(struct pci_dev *pdev); | 181 | static void ohci1394_pci_remove(struct pci_dev *pdev); |
182 | 182 | ||
183 | #ifndef __LITTLE_ENDIAN | 183 | #ifndef __LITTLE_ENDIAN |
184 | static unsigned hdr_sizes[] = | 184 | const 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 */ | 200 | static inline void header_le32_to_cpu(quadlet_t *data, unsigned char tcode) |
201 | static 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 | */ |
2601 | static __inline__ int packet_length(struct dma_rcv_ctx *d, int idx, quadlet_t *buf_ptr, | 2600 | static 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 | |
3533 | static int ohci1394_pci_resume (struct pci_dev *pdev) | 3533 | static 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 | |||
3553 | static int ohci1394_pci_suspend (struct pci_dev *pdev, pm_message_t state) | 3552 | static 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 | 3574 | out: | |
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 | ||
3721 | module_init(ohci1394_init); | 3730 | /* Register before most other device drivers. |
3731 | * Useful for remote debugging via physical DMA, e.g. using firescope. */ | ||
3732 | fs_initcall(ohci1394_init); | ||
3722 | module_exit(ohci1394_cleanup); | 3733 | module_exit(ohci1394_cleanup); |