diff options
author | Clemens Ladisch <clemens@ladisch.de> | 2010-11-30 02:25:17 -0500 |
---|---|---|
committer | Stefan Richter <stefanr@s5r6.in-berlin.de> | 2010-12-13 14:39:15 -0500 |
commit | ec766a7970126f99665992c0b0b10bd60a4d6208 (patch) | |
tree | dc049e0bcb3e1fb33a68efea8760391af62f6681 /drivers | |
parent | 2dd5bed59356e03610bebe1a37c397788df50b9b (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.c | 66 |
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 | ||
928 | static int ar_context_init(struct ar_context *ctx, | 926 | static 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); |