diff options
-rw-r--r-- | drivers/firewire/fw-iso.c | 3 | ||||
-rw-r--r-- | drivers/firewire/fw-ohci.c | 14 | ||||
-rw-r--r-- | drivers/firewire/fw-transaction.h | 2 |
3 files changed, 14 insertions, 5 deletions
diff --git a/drivers/firewire/fw-iso.c b/drivers/firewire/fw-iso.c index 3ff2cfc1bba6..39f3bacee404 100644 --- a/drivers/firewire/fw-iso.c +++ b/drivers/firewire/fw-iso.c | |||
@@ -110,7 +110,8 @@ struct fw_iso_context *fw_iso_context_create(struct fw_card *card, | |||
110 | { | 110 | { |
111 | struct fw_iso_context *ctx; | 111 | struct fw_iso_context *ctx; |
112 | 112 | ||
113 | ctx = card->driver->allocate_iso_context(card, type, header_size); | 113 | ctx = card->driver->allocate_iso_context(card, |
114 | type, channel, header_size); | ||
114 | if (IS_ERR(ctx)) | 115 | if (IS_ERR(ctx)) |
115 | return ctx; | 116 | return ctx; |
116 | 117 | ||
diff --git a/drivers/firewire/fw-ohci.c b/drivers/firewire/fw-ohci.c index 4c7cf15986ae..859af71b06a8 100644 --- a/drivers/firewire/fw-ohci.c +++ b/drivers/firewire/fw-ohci.c | |||
@@ -205,6 +205,7 @@ struct fw_ohci { | |||
205 | 205 | ||
206 | u32 it_context_mask; | 206 | u32 it_context_mask; |
207 | struct iso_context *it_context_list; | 207 | struct iso_context *it_context_list; |
208 | u64 ir_context_channels; | ||
208 | u32 ir_context_mask; | 209 | u32 ir_context_mask; |
209 | struct iso_context *ir_context_list; | 210 | struct iso_context *ir_context_list; |
210 | }; | 211 | }; |
@@ -1877,20 +1878,23 @@ static int handle_it_packet(struct context *context, | |||
1877 | } | 1878 | } |
1878 | 1879 | ||
1879 | static struct fw_iso_context *ohci_allocate_iso_context(struct fw_card *card, | 1880 | static struct fw_iso_context *ohci_allocate_iso_context(struct fw_card *card, |
1880 | int type, size_t header_size) | 1881 | int type, int channel, size_t header_size) |
1881 | { | 1882 | { |
1882 | struct fw_ohci *ohci = fw_ohci(card); | 1883 | struct fw_ohci *ohci = fw_ohci(card); |
1883 | struct iso_context *ctx, *list; | 1884 | struct iso_context *ctx, *list; |
1884 | descriptor_callback_t callback; | 1885 | descriptor_callback_t callback; |
1886 | u64 *channels, dont_care = ~0ULL; | ||
1885 | u32 *mask, regs; | 1887 | u32 *mask, regs; |
1886 | unsigned long flags; | 1888 | unsigned long flags; |
1887 | int index, ret = -ENOMEM; | 1889 | int index, ret = -ENOMEM; |
1888 | 1890 | ||
1889 | if (type == FW_ISO_CONTEXT_TRANSMIT) { | 1891 | if (type == FW_ISO_CONTEXT_TRANSMIT) { |
1892 | channels = &dont_care; | ||
1890 | mask = &ohci->it_context_mask; | 1893 | mask = &ohci->it_context_mask; |
1891 | list = ohci->it_context_list; | 1894 | list = ohci->it_context_list; |
1892 | callback = handle_it_packet; | 1895 | callback = handle_it_packet; |
1893 | } else { | 1896 | } else { |
1897 | channels = &ohci->ir_context_channels; | ||
1894 | mask = &ohci->ir_context_mask; | 1898 | mask = &ohci->ir_context_mask; |
1895 | list = ohci->ir_context_list; | 1899 | list = ohci->ir_context_list; |
1896 | if (ohci->use_dualbuffer) | 1900 | if (ohci->use_dualbuffer) |
@@ -1900,9 +1904,11 @@ static struct fw_iso_context *ohci_allocate_iso_context(struct fw_card *card, | |||
1900 | } | 1904 | } |
1901 | 1905 | ||
1902 | spin_lock_irqsave(&ohci->lock, flags); | 1906 | spin_lock_irqsave(&ohci->lock, flags); |
1903 | index = ffs(*mask) - 1; | 1907 | index = *channels & 1ULL << channel ? ffs(*mask) - 1 : -1; |
1904 | if (index >= 0) | 1908 | if (index >= 0) { |
1909 | *channels &= ~(1ULL << channel); | ||
1905 | *mask &= ~(1 << index); | 1910 | *mask &= ~(1 << index); |
1911 | } | ||
1906 | spin_unlock_irqrestore(&ohci->lock, flags); | 1912 | spin_unlock_irqrestore(&ohci->lock, flags); |
1907 | 1913 | ||
1908 | if (index < 0) | 1914 | if (index < 0) |
@@ -2012,6 +2018,7 @@ static void ohci_free_iso_context(struct fw_iso_context *base) | |||
2012 | } else { | 2018 | } else { |
2013 | index = ctx - ohci->ir_context_list; | 2019 | index = ctx - ohci->ir_context_list; |
2014 | ohci->ir_context_mask |= 1 << index; | 2020 | ohci->ir_context_mask |= 1 << index; |
2021 | ohci->ir_context_channels |= 1ULL << base->channel; | ||
2015 | } | 2022 | } |
2016 | 2023 | ||
2017 | spin_unlock_irqrestore(&ohci->lock, flags); | 2024 | spin_unlock_irqrestore(&ohci->lock, flags); |
@@ -2424,6 +2431,7 @@ static int __devinit pci_probe(struct pci_dev *dev, | |||
2424 | ohci->it_context_list = kzalloc(size, GFP_KERNEL); | 2431 | ohci->it_context_list = kzalloc(size, GFP_KERNEL); |
2425 | 2432 | ||
2426 | reg_write(ohci, OHCI1394_IsoXmitIntMaskSet, ~0); | 2433 | reg_write(ohci, OHCI1394_IsoXmitIntMaskSet, ~0); |
2434 | ohci->ir_context_channels = ~0ULL; | ||
2427 | ohci->ir_context_mask = reg_read(ohci, OHCI1394_IsoXmitIntMaskSet); | 2435 | ohci->ir_context_mask = reg_read(ohci, OHCI1394_IsoXmitIntMaskSet); |
2428 | reg_write(ohci, OHCI1394_IsoXmitIntMaskClear, ~0); | 2436 | reg_write(ohci, OHCI1394_IsoXmitIntMaskClear, ~0); |
2429 | size = sizeof(struct iso_context) * hweight32(ohci->ir_context_mask); | 2437 | size = sizeof(struct iso_context) * hweight32(ohci->ir_context_mask); |
diff --git a/drivers/firewire/fw-transaction.h b/drivers/firewire/fw-transaction.h index 0dd96ecc2dcd..48e88d53998b 100644 --- a/drivers/firewire/fw-transaction.h +++ b/drivers/firewire/fw-transaction.h | |||
@@ -383,7 +383,7 @@ struct fw_card_driver { | |||
383 | 383 | ||
384 | struct fw_iso_context * | 384 | struct fw_iso_context * |
385 | (*allocate_iso_context)(struct fw_card *card, | 385 | (*allocate_iso_context)(struct fw_card *card, |
386 | int type, size_t header_size); | 386 | int type, int channel, size_t header_size); |
387 | void (*free_iso_context)(struct fw_iso_context *ctx); | 387 | void (*free_iso_context)(struct fw_iso_context *ctx); |
388 | 388 | ||
389 | int (*start_iso)(struct fw_iso_context *ctx, | 389 | int (*start_iso)(struct fw_iso_context *ctx, |