diff options
author | Kristian Høgsberg <krh@redhat.com> | 2007-02-16 17:34:49 -0500 |
---|---|---|
committer | Stefan Richter <stefanr@s5r6.in-berlin.de> | 2007-03-09 16:03:03 -0500 |
commit | e364cf4e0aa245ba2ce5942289e8a43935505e53 (patch) | |
tree | d12544f02a83a33f13babf430d225adbd7ba1252 /drivers | |
parent | 68be3fa15a420d96b1aaed4c519607bf2bfcb2e1 (diff) |
firewire: Store OHCI version and make sure we have at least 1.1 before doing dualbuffer.
Signed-off-by: Kristian Høgsberg <krh@redhat.com>
Signed-off-by: Stefan Richter <stefanr@s5r6.in-berlin.de>
Diffstat (limited to 'drivers')
-rw-r--r-- | drivers/firewire/fw-ohci.c | 19 |
1 files changed, 15 insertions, 4 deletions
diff --git a/drivers/firewire/fw-ohci.c b/drivers/firewire/fw-ohci.c index 18769d906ca9..12f109da4d8d 100644 --- a/drivers/firewire/fw-ohci.c +++ b/drivers/firewire/fw-ohci.c | |||
@@ -152,6 +152,7 @@ struct iso_context { | |||
152 | struct fw_ohci { | 152 | struct fw_ohci { |
153 | struct fw_card card; | 153 | struct fw_card card; |
154 | 154 | ||
155 | u32 version; | ||
155 | __iomem char *registers; | 156 | __iomem char *registers; |
156 | dma_addr_t self_id_bus; | 157 | dma_addr_t self_id_bus; |
157 | __le32 *self_id_cpu; | 158 | __le32 *self_id_cpu; |
@@ -210,6 +211,7 @@ static inline struct fw_ohci *fw_ohci(struct fw_card *card) | |||
210 | #define OHCI1394_PCI_HCI_Control 0x40 | 211 | #define OHCI1394_PCI_HCI_Control 0x40 |
211 | #define SELF_ID_BUF_SIZE 0x800 | 212 | #define SELF_ID_BUF_SIZE 0x800 |
212 | #define OHCI_TCODE_PHY_PACKET 0x0e | 213 | #define OHCI_TCODE_PHY_PACKET 0x0e |
214 | #define OHCI_VERSION_1_1 0x010010 | ||
213 | 215 | ||
214 | static char ohci_driver_name[] = KBUILD_MODNAME; | 216 | static char ohci_driver_name[] = KBUILD_MODNAME; |
215 | 217 | ||
@@ -1357,6 +1359,10 @@ ohci_allocate_iso_context(struct fw_card *card, int type, size_t header_size) | |||
1357 | callback = handle_ir_bufferfill_packet; | 1359 | callback = handle_ir_bufferfill_packet; |
1358 | } | 1360 | } |
1359 | 1361 | ||
1362 | if (callback == handle_ir_dualbuffer_packet && | ||
1363 | ohci->version < OHCI_VERSION_1_1) | ||
1364 | return ERR_PTR(-EINVAL); | ||
1365 | |||
1360 | spin_lock_irqsave(&ohci->lock, flags); | 1366 | spin_lock_irqsave(&ohci->lock, flags); |
1361 | index = ffs(*mask) - 1; | 1367 | index = ffs(*mask) - 1; |
1362 | if (index >= 0) | 1368 | if (index >= 0) |
@@ -1687,14 +1693,19 @@ ohci_queue_iso(struct fw_iso_context *base, | |||
1687 | struct fw_iso_buffer *buffer, | 1693 | struct fw_iso_buffer *buffer, |
1688 | unsigned long payload) | 1694 | unsigned long payload) |
1689 | { | 1695 | { |
1696 | struct iso_context *ctx = container_of(base, struct iso_context, base); | ||
1697 | |||
1690 | if (base->type == FW_ISO_CONTEXT_TRANSMIT) | 1698 | if (base->type == FW_ISO_CONTEXT_TRANSMIT) |
1691 | return ohci_queue_iso_transmit(base, packet, buffer, payload); | 1699 | return ohci_queue_iso_transmit(base, packet, buffer, payload); |
1692 | else if (base->header_size == 0) | 1700 | else if (base->header_size == 0) |
1693 | return ohci_queue_iso_receive_bufferfill(base, packet, | 1701 | return ohci_queue_iso_receive_bufferfill(base, packet, |
1694 | buffer, payload); | 1702 | buffer, payload); |
1695 | else | 1703 | else if (ctx->context.ohci->version >= OHCI_VERSION_1_1) |
1696 | return ohci_queue_iso_receive_dualbuffer(base, packet, | 1704 | return ohci_queue_iso_receive_dualbuffer(base, packet, |
1697 | buffer, payload); | 1705 | buffer, payload); |
1706 | else | ||
1707 | /* FIXME: Implement fallback for OHCI 1.0 controllers. */ | ||
1708 | return -EINVAL; | ||
1698 | } | 1709 | } |
1699 | 1710 | ||
1700 | static const struct fw_card_driver ohci_driver = { | 1711 | static const struct fw_card_driver ohci_driver = { |
@@ -1767,7 +1778,7 @@ static int __devinit | |||
1767 | pci_probe(struct pci_dev *dev, const struct pci_device_id *ent) | 1778 | pci_probe(struct pci_dev *dev, const struct pci_device_id *ent) |
1768 | { | 1779 | { |
1769 | struct fw_ohci *ohci; | 1780 | struct fw_ohci *ohci; |
1770 | u32 bus_options, max_receive, link_speed, version; | 1781 | u32 bus_options, max_receive, link_speed; |
1771 | u64 guid; | 1782 | u64 guid; |
1772 | int error_code; | 1783 | int error_code; |
1773 | size_t size; | 1784 | size_t size; |
@@ -1894,9 +1905,9 @@ pci_probe(struct pci_dev *dev, const struct pci_device_id *ent) | |||
1894 | if (error_code < 0) | 1905 | if (error_code < 0) |
1895 | return cleanup(ohci, CLEANUP_SELF_ID, error_code); | 1906 | return cleanup(ohci, CLEANUP_SELF_ID, error_code); |
1896 | 1907 | ||
1897 | version = reg_read(ohci, OHCI1394_Version); | 1908 | ohci->version = reg_read(ohci, OHCI1394_Version) & 0x00ff00ff; |
1898 | fw_notify("Added fw-ohci device %s, OHCI version %x.%x\n", | 1909 | fw_notify("Added fw-ohci device %s, OHCI version %x.%x\n", |
1899 | dev->dev.bus_id, (version >> 16) & 0xff, version & 0xff); | 1910 | dev->dev.bus_id, ohci->version >> 16, ohci->version & 0xff); |
1900 | 1911 | ||
1901 | return 0; | 1912 | return 0; |
1902 | } | 1913 | } |