aboutsummaryrefslogtreecommitdiffstats
path: root/drivers
diff options
context:
space:
mode:
authorClemens Ladisch <clemens@ladisch.de>2010-11-30 02:25:17 -0500
committerStefan Richter <stefanr@s5r6.in-berlin.de>2010-12-13 14:39:15 -0500
commitec766a7970126f99665992c0b0b10bd60a4d6208 (patch)
treedc049e0bcb3e1fb33a68efea8760391af62f6681 /drivers
parent2dd5bed59356e03610bebe1a37c397788df50b9b (diff)
firewire: ohci: use common buffer for self IDs and AR descriptors
The buffers used for the selfIDs packets and the AR request and response descriptors end up using three pages because dma_alloc_coherent() allocates at least one page per call. However, these data structures would all fit into 4 KB, so we can save space by using a common buffer for them. Signed-off-by: Clemens Ladisch <clemens@ladisch.de> Signed-off-by: Stefan Richter <stefanr@s5r6.in-berlin.de>
Diffstat (limited to 'drivers')
-rw-r--r--drivers/firewire/ohci.c66
1 files changed, 34 insertions, 32 deletions
diff --git a/drivers/firewire/ohci.c b/drivers/firewire/ohci.c
index 01b3bc9154a6..eb7b591e1c1b 100644
--- a/drivers/firewire/ohci.c
+++ b/drivers/firewire/ohci.c
@@ -193,6 +193,9 @@ struct fw_ohci {
193 193
194 struct mutex phy_reg_mutex; 194 struct mutex phy_reg_mutex;
195 195
196 void *misc_buffer;
197 dma_addr_t misc_buffer_bus;
198
196 struct ar_context ar_request_ctx; 199 struct ar_context ar_request_ctx;
197 struct ar_context ar_response_ctx; 200 struct ar_context ar_response_ctx;
198 struct context at_request_ctx; 201 struct context at_request_ctx;
@@ -623,11 +626,6 @@ static void ar_context_release(struct ar_context *ctx)
623{ 626{
624 unsigned int i; 627 unsigned int i;
625 628
626 if (ctx->descriptors)
627 dma_free_coherent(ctx->ohci->card.device,
628 AR_BUFFERS * sizeof(struct descriptor),
629 ctx->descriptors, ctx->descriptors_bus);
630
631 if (ctx->buffer) 629 if (ctx->buffer)
632 vm_unmap_ram(ctx->buffer, AR_BUFFERS + AR_WRAPAROUND_PAGES); 630 vm_unmap_ram(ctx->buffer, AR_BUFFERS + AR_WRAPAROUND_PAGES);
633 631
@@ -925,8 +923,8 @@ error:
925 ctx->pointer = NULL; 923 ctx->pointer = NULL;
926} 924}
927 925
928static int ar_context_init(struct ar_context *ctx, 926static int ar_context_init(struct ar_context *ctx, struct fw_ohci *ohci,
929 struct fw_ohci *ohci, u32 regs) 927 unsigned int descriptors_offset, u32 regs)
930{ 928{
931 unsigned int i; 929 unsigned int i;
932 dma_addr_t dma_addr; 930 dma_addr_t dma_addr;
@@ -960,13 +958,8 @@ static int ar_context_init(struct ar_context *ctx,
960 if (!ctx->buffer) 958 if (!ctx->buffer)
961 goto out_of_memory; 959 goto out_of_memory;
962 960
963 ctx->descriptors = 961 ctx->descriptors = ohci->misc_buffer + descriptors_offset;
964 dma_alloc_coherent(ohci->card.device, 962 ctx->descriptors_bus = ohci->misc_buffer_bus + descriptors_offset;
965 AR_BUFFERS * sizeof(struct descriptor),
966 &ctx->descriptors_bus,
967 GFP_KERNEL);
968 if (!ctx->descriptors)
969 goto out_of_memory;
970 963
971 for (i = 0; i < AR_BUFFERS; i++) { 964 for (i = 0; i < AR_BUFFERS; i++) {
972 d = &ctx->descriptors[i]; 965 d = &ctx->descriptors[i];
@@ -3108,12 +3101,28 @@ static int __devinit pci_probe(struct pci_dev *dev,
3108 if (param_quirks) 3101 if (param_quirks)
3109 ohci->quirks = param_quirks; 3102 ohci->quirks = param_quirks;
3110 3103
3111 err = ar_context_init(&ohci->ar_request_ctx, ohci, 3104 /*
3105 * Because dma_alloc_coherent() allocates at least one page,
3106 * we save space by using a common buffer for the AR request/
3107 * response descriptors and the self IDs buffer.
3108 */
3109 BUILD_BUG_ON(AR_BUFFERS * sizeof(struct descriptor) > PAGE_SIZE/4);
3110 BUILD_BUG_ON(SELF_ID_BUF_SIZE > PAGE_SIZE/2);
3111 ohci->misc_buffer = dma_alloc_coherent(ohci->card.device,
3112 PAGE_SIZE,
3113 &ohci->misc_buffer_bus,
3114 GFP_KERNEL);
3115 if (!ohci->misc_buffer) {
3116 err = -ENOMEM;
3117 goto fail_iounmap;
3118 }
3119
3120 err = ar_context_init(&ohci->ar_request_ctx, ohci, 0,
3112 OHCI1394_AsReqRcvContextControlSet); 3121 OHCI1394_AsReqRcvContextControlSet);
3113 if (err < 0) 3122 if (err < 0)
3114 goto fail_iounmap; 3123 goto fail_misc_buf;
3115 3124
3116 err = ar_context_init(&ohci->ar_response_ctx, ohci, 3125 err = ar_context_init(&ohci->ar_response_ctx, ohci, PAGE_SIZE/4,
3117 OHCI1394_AsRspRcvContextControlSet); 3126 OHCI1394_AsRspRcvContextControlSet);
3118 if (err < 0) 3127 if (err < 0)
3119 goto fail_arreq_ctx; 3128 goto fail_arreq_ctx;
@@ -3148,15 +3157,8 @@ static int __devinit pci_probe(struct pci_dev *dev,
3148 goto fail_contexts; 3157 goto fail_contexts;
3149 } 3158 }
3150 3159
3151 /* self-id dma buffer allocation */ 3160 ohci->self_id_cpu = ohci->misc_buffer + PAGE_SIZE/2;
3152 ohci->self_id_cpu = dma_alloc_coherent(ohci->card.device, 3161 ohci->self_id_bus = ohci->misc_buffer_bus + PAGE_SIZE/2;
3153 SELF_ID_BUF_SIZE,
3154 &ohci->self_id_bus,
3155 GFP_KERNEL);
3156 if (ohci->self_id_cpu == NULL) {
3157 err = -ENOMEM;
3158 goto fail_contexts;
3159 }
3160 3162
3161 bus_options = reg_read(ohci, OHCI1394_BusOptions); 3163 bus_options = reg_read(ohci, OHCI1394_BusOptions);
3162 max_receive = (bus_options >> 12) & 0xf; 3164 max_receive = (bus_options >> 12) & 0xf;
@@ -3166,7 +3168,7 @@ static int __devinit pci_probe(struct pci_dev *dev,
3166 3168
3167 err = fw_card_add(&ohci->card, max_receive, link_speed, guid); 3169 err = fw_card_add(&ohci->card, max_receive, link_speed, guid);
3168 if (err) 3170 if (err)
3169 goto fail_self_id; 3171 goto fail_contexts;
3170 3172
3171 version = reg_read(ohci, OHCI1394_Version) & 0x00ff00ff; 3173 version = reg_read(ohci, OHCI1394_Version) & 0x00ff00ff;
3172 fw_notify("Added fw-ohci device %s, OHCI v%x.%x, " 3174 fw_notify("Added fw-ohci device %s, OHCI v%x.%x, "
@@ -3176,9 +3178,6 @@ static int __devinit pci_probe(struct pci_dev *dev,
3176 3178
3177 return 0; 3179 return 0;
3178 3180
3179 fail_self_id:
3180 dma_free_coherent(ohci->card.device, SELF_ID_BUF_SIZE,
3181 ohci->self_id_cpu, ohci->self_id_bus);
3182 fail_contexts: 3181 fail_contexts:
3183 kfree(ohci->ir_context_list); 3182 kfree(ohci->ir_context_list);
3184 kfree(ohci->it_context_list); 3183 kfree(ohci->it_context_list);
@@ -3189,6 +3188,9 @@ static int __devinit pci_probe(struct pci_dev *dev,
3189 ar_context_release(&ohci->ar_response_ctx); 3188 ar_context_release(&ohci->ar_response_ctx);
3190 fail_arreq_ctx: 3189 fail_arreq_ctx:
3191 ar_context_release(&ohci->ar_request_ctx); 3190 ar_context_release(&ohci->ar_request_ctx);
3191 fail_misc_buf:
3192 dma_free_coherent(ohci->card.device, PAGE_SIZE,
3193 ohci->misc_buffer, ohci->misc_buffer_bus);
3192 fail_iounmap: 3194 fail_iounmap:
3193 pci_iounmap(dev, ohci->registers); 3195 pci_iounmap(dev, ohci->registers);
3194 fail_iomem: 3196 fail_iomem:
@@ -3228,10 +3230,10 @@ static void pci_remove(struct pci_dev *dev)
3228 if (ohci->config_rom) 3230 if (ohci->config_rom)
3229 dma_free_coherent(ohci->card.device, CONFIG_ROM_SIZE, 3231 dma_free_coherent(ohci->card.device, CONFIG_ROM_SIZE,
3230 ohci->config_rom, ohci->config_rom_bus); 3232 ohci->config_rom, ohci->config_rom_bus);
3231 dma_free_coherent(ohci->card.device, SELF_ID_BUF_SIZE,
3232 ohci->self_id_cpu, ohci->self_id_bus);
3233 ar_context_release(&ohci->ar_request_ctx); 3233 ar_context_release(&ohci->ar_request_ctx);
3234 ar_context_release(&ohci->ar_response_ctx); 3234 ar_context_release(&ohci->ar_response_ctx);
3235 dma_free_coherent(ohci->card.device, PAGE_SIZE,
3236 ohci->misc_buffer, ohci->misc_buffer_bus);
3235 context_release(&ohci->at_request_ctx); 3237 context_release(&ohci->at_request_ctx);
3236 context_release(&ohci->at_response_ctx); 3238 context_release(&ohci->at_response_ctx);
3237 kfree(ohci->it_context_list); 3239 kfree(ohci->it_context_list);