Commit 53efec9513cfb1acff602c7ebdd945d677808e9e
1 parent
6e86841d05
Exists in
master
and in
39 other branches
pcmcia: only copy CIS override data once
Instead of copying CIS override data in socket_sysfs.c or ds.c, and then again in cistpl.c, only do so once. Also, cisdump_t is now only used by the deprecated ioctl. Signed-off-by: Dominik Brodowski <linux@dominikbrodowski.net>
Showing 7 changed files with 23 additions and 42 deletions Side-by-side Diff
drivers/pcmcia/cistpl.c
... | ... | @@ -265,13 +265,13 @@ |
265 | 265 | ======================================================================*/ |
266 | 266 | |
267 | 267 | static void read_cis_cache(struct pcmcia_socket *s, int attr, u_int addr, |
268 | - u_int len, void *ptr) | |
268 | + size_t len, void *ptr) | |
269 | 269 | { |
270 | 270 | struct cis_cache_entry *cis; |
271 | 271 | int ret; |
272 | 272 | |
273 | 273 | if (s->fake_cis) { |
274 | - if (s->fake_cis_len > addr+len) | |
274 | + if (s->fake_cis_len >= addr+len) | |
275 | 275 | memcpy(ptr, s->fake_cis+addr, len); |
276 | 276 | else |
277 | 277 | memset(ptr, 0xff, len); |
278 | 278 | |
279 | 279 | |
280 | 280 | |
... | ... | @@ -380,17 +380,17 @@ |
380 | 380 | |
381 | 381 | ======================================================================*/ |
382 | 382 | |
383 | -int pcmcia_replace_cis(struct pcmcia_socket *s, cisdump_t *cis) | |
383 | +int pcmcia_replace_cis(struct pcmcia_socket *s, | |
384 | + const u8 *data, const size_t len) | |
384 | 385 | { |
385 | - kfree(s->fake_cis); | |
386 | - s->fake_cis = NULL; | |
387 | - if (cis->Length > CISTPL_MAX_CIS_SIZE) | |
386 | + if (len > CISTPL_MAX_CIS_SIZE) | |
388 | 387 | return CS_BAD_SIZE; |
389 | - s->fake_cis = kmalloc(cis->Length, GFP_KERNEL); | |
388 | + kfree(s->fake_cis); | |
389 | + s->fake_cis = kmalloc(len, GFP_KERNEL); | |
390 | 390 | if (s->fake_cis == NULL) |
391 | 391 | return CS_OUT_OF_RESOURCE; |
392 | - s->fake_cis_len = cis->Length; | |
393 | - memcpy(s->fake_cis, cis->Data, cis->Length); | |
392 | + s->fake_cis_len = len; | |
393 | + memcpy(s->fake_cis, data, len); | |
394 | 394 | return CS_SUCCESS; |
395 | 395 | } |
396 | 396 | EXPORT_SYMBOL(pcmcia_replace_cis); |
drivers/pcmcia/ds.c
... | ... | @@ -854,7 +854,6 @@ |
854 | 854 | int ret = -ENOMEM; |
855 | 855 | int no_funcs; |
856 | 856 | int old_funcs; |
857 | - cisdump_t *cis; | |
858 | 857 | cistpl_longlink_mfc_t mfc; |
859 | 858 | |
860 | 859 | if (!filename) |
... | ... | @@ -877,16 +876,7 @@ |
877 | 876 | goto release; |
878 | 877 | } |
879 | 878 | |
880 | - cis = kzalloc(sizeof(cisdump_t), GFP_KERNEL); | |
881 | - if (!cis) { | |
882 | - ret = -ENOMEM; | |
883 | - goto release; | |
884 | - } | |
885 | - | |
886 | - cis->Length = fw->size + 1; | |
887 | - memcpy(cis->Data, fw->data, fw->size); | |
888 | - | |
889 | - if (!pcmcia_replace_cis(s, cis)) | |
879 | + if (!pcmcia_replace_cis(s, fw->data, fw->size)) | |
890 | 880 | ret = 0; |
891 | 881 | else { |
892 | 882 | printk(KERN_ERR "pcmcia: CIS override failed\n"); |
drivers/pcmcia/pcmcia_ioctl.c
... | ... | @@ -867,7 +867,7 @@ |
867 | 867 | &buf->win_info.map); |
868 | 868 | break; |
869 | 869 | case DS_REPLACE_CIS: |
870 | - ret = pcmcia_replace_cis(s, &buf->cisdump); | |
870 | + ret = pcmcia_replace_cis(s, buf->cisdump.Data, buf->cisdump.Length); | |
871 | 871 | break; |
872 | 872 | case DS_BIND_REQUEST: |
873 | 873 | if (!capable(CAP_SYS_ADMIN)) { |
drivers/pcmcia/socket_sysfs.c
... | ... | @@ -316,27 +316,18 @@ |
316 | 316 | char *buf, loff_t off, size_t count) |
317 | 317 | { |
318 | 318 | struct pcmcia_socket *s = to_socket(container_of(kobj, struct device, kobj)); |
319 | - cisdump_t *cis; | |
320 | 319 | int error; |
321 | 320 | |
322 | 321 | if (off) |
323 | 322 | return -EINVAL; |
324 | 323 | |
325 | - if (count >= 0x200) | |
324 | + if (count >= CISTPL_MAX_CIS_SIZE) | |
326 | 325 | return -EINVAL; |
327 | 326 | |
328 | 327 | if (!(s->state & SOCKET_PRESENT)) |
329 | 328 | return -ENODEV; |
330 | 329 | |
331 | - cis = kzalloc(sizeof(cisdump_t), GFP_KERNEL); | |
332 | - if (!cis) | |
333 | - return -ENOMEM; | |
334 | - | |
335 | - cis->Length = count + 1; | |
336 | - memcpy(cis->Data, buf, count); | |
337 | - | |
338 | - error = pcmcia_replace_cis(s, cis); | |
339 | - kfree(cis); | |
330 | + error = pcmcia_replace_cis(s, buf, count); | |
340 | 331 | if (error) |
341 | 332 | return -EIO; |
342 | 333 |
include/pcmcia/cistpl.h
... | ... | @@ -580,14 +580,8 @@ |
580 | 580 | |
581 | 581 | #define CISTPL_MAX_CIS_SIZE 0x200 |
582 | 582 | |
583 | -/* For ReplaceCIS */ | |
584 | -typedef struct cisdump_t { | |
585 | - u_int Length; | |
586 | - cisdata_t Data[CISTPL_MAX_CIS_SIZE]; | |
587 | -} cisdump_t; | |
588 | - | |
589 | - | |
590 | -int pcmcia_replace_cis(struct pcmcia_socket *s, cisdump_t *cis); | |
583 | +int pcmcia_replace_cis(struct pcmcia_socket *s, | |
584 | + const u8 *data, const size_t len); | |
591 | 585 | |
592 | 586 | /* don't use outside of PCMCIA core yet */ |
593 | 587 | int pccard_get_next_tuple(struct pcmcia_socket *s, unsigned int func, tuple_t *tuple); |
include/pcmcia/ds.h
... | ... | @@ -68,6 +68,12 @@ |
68 | 68 | #define REGION_BAR_MASK 0xe000 |
69 | 69 | #define REGION_BAR_SHIFT 13 |
70 | 70 | |
71 | +/* For ReplaceCIS */ | |
72 | +typedef struct cisdump_t { | |
73 | + u_int Length; | |
74 | + cisdata_t Data[CISTPL_MAX_CIS_SIZE]; | |
75 | +} cisdump_t; | |
76 | + | |
71 | 77 | typedef union ds_ioctl_arg_t { |
72 | 78 | adjust_t adjust; |
73 | 79 | config_info_t config; |
include/pcmcia/ss.h
... | ... | @@ -199,8 +199,8 @@ |
199 | 199 | io_window_t io[MAX_IO_WIN]; |
200 | 200 | window_t win[MAX_WIN]; |
201 | 201 | struct list_head cis_cache; |
202 | - u_int fake_cis_len; | |
203 | - char *fake_cis; | |
202 | + size_t fake_cis_len; | |
203 | + u8 *fake_cis; | |
204 | 204 | |
205 | 205 | struct list_head socket_list; |
206 | 206 | struct completion socket_released; |