aboutsummaryrefslogtreecommitdiffstats
path: root/drivers
diff options
context:
space:
mode:
authorKristian Høgsberg <krh@redhat.com>2007-02-16 17:34:49 -0500
committerStefan Richter <stefanr@s5r6.in-berlin.de>2007-03-09 16:03:03 -0500
commite364cf4e0aa245ba2ce5942289e8a43935505e53 (patch)
treed12544f02a83a33f13babf430d225adbd7ba1252 /drivers
parent68be3fa15a420d96b1aaed4c519607bf2bfcb2e1 (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.c19
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 {
152struct fw_ohci { 152struct 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
214static char ohci_driver_name[] = KBUILD_MODNAME; 216static 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
1700static const struct fw_card_driver ohci_driver = { 1711static const struct fw_card_driver ohci_driver = {
@@ -1767,7 +1778,7 @@ static int __devinit
1767pci_probe(struct pci_dev *dev, const struct pci_device_id *ent) 1778pci_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}