diff options
Diffstat (limited to 'drivers/ieee1394/csr1212.c')
-rw-r--r-- | drivers/ieee1394/csr1212.c | 37 |
1 files changed, 27 insertions, 10 deletions
diff --git a/drivers/ieee1394/csr1212.c b/drivers/ieee1394/csr1212.c index 7c4330e2e875..61ddd5d37eff 100644 --- a/drivers/ieee1394/csr1212.c +++ b/drivers/ieee1394/csr1212.c | |||
@@ -209,7 +209,15 @@ void csr1212_init_local_csr(struct csr1212_csr *csr, | |||
209 | { | 209 | { |
210 | static const int mr_map[] = { 4, 64, 1024, 0 }; | 210 | static const int mr_map[] = { 4, 64, 1024, 0 }; |
211 | 211 | ||
212 | #ifdef __KERNEL__ | ||
213 | BUG_ON(max_rom & ~0x3); | ||
212 | csr->max_rom = mr_map[max_rom]; | 214 | csr->max_rom = mr_map[max_rom]; |
215 | #else | ||
216 | if (max_rom & ~0x3) /* caller supplied invalid argument */ | ||
217 | csr->max_rom = 0; | ||
218 | else | ||
219 | csr->max_rom = mr_map[max_rom]; | ||
220 | #endif | ||
213 | memcpy(csr->bus_info_data, bus_info_data, csr->bus_info_len); | 221 | memcpy(csr->bus_info_data, bus_info_data, csr->bus_info_len); |
214 | } | 222 | } |
215 | 223 | ||
@@ -533,12 +541,15 @@ struct csr1212_keyval *csr1212_new_icon_descriptor_leaf(u_int32_t version, | |||
533 | static const int pd[4] = { 0, 4, 16, 256 }; | 541 | static const int pd[4] = { 0, 4, 16, 256 }; |
534 | static const int cs[16] = { 4, 2 }; | 542 | static const int cs[16] = { 4, 2 }; |
535 | struct csr1212_keyval *kv; | 543 | struct csr1212_keyval *kv; |
536 | int palette_size = pd[palette_depth] * cs[color_space]; | 544 | int palette_size; |
537 | int pixel_size = (hscan * vscan + 3) & ~0x3; | 545 | int pixel_size = (hscan * vscan + 3) & ~0x3; |
538 | 546 | ||
539 | if ((palette_depth && !palette) || !pixels) | 547 | if (!pixels || (!palette && palette_depth) || |
548 | (palette_depth & ~0x3) || (color_space & ~0xf)) | ||
540 | return NULL; | 549 | return NULL; |
541 | 550 | ||
551 | palette_size = pd[palette_depth] * cs[color_space]; | ||
552 | |||
542 | kv = csr1212_new_descriptor_leaf(1, 0, NULL, | 553 | kv = csr1212_new_descriptor_leaf(1, 0, NULL, |
543 | palette_size + pixel_size + | 554 | palette_size + pixel_size + |
544 | CSR1212_ICON_DESCRIPTOR_LEAF_OVERHEAD); | 555 | CSR1212_ICON_DESCRIPTOR_LEAF_OVERHEAD); |
@@ -760,9 +771,9 @@ static int csr1212_append_new_cache(struct csr1212_csr *csr, size_t romsize) | |||
760 | struct csr1212_csr_rom_cache *cache; | 771 | struct csr1212_csr_rom_cache *cache; |
761 | u_int64_t csr_addr; | 772 | u_int64_t csr_addr; |
762 | 773 | ||
763 | if (!csr || !csr->ops->allocate_addr_range || | 774 | if (!csr || !csr->ops || !csr->ops->allocate_addr_range || |
764 | !csr->ops->release_addr) | 775 | !csr->ops->release_addr || csr->max_rom < 1) |
765 | return CSR1212_ENOMEM; | 776 | return CSR1212_EINVAL; |
766 | 777 | ||
767 | /* ROM size must be a multiple of csr->max_rom */ | 778 | /* ROM size must be a multiple of csr->max_rom */ |
768 | romsize = (romsize + (csr->max_rom - 1)) & ~(csr->max_rom - 1); | 779 | romsize = (romsize + (csr->max_rom - 1)) & ~(csr->max_rom - 1); |
@@ -1145,6 +1156,8 @@ int csr1212_generate_csr_image(struct csr1212_csr *csr) | |||
1145 | 1156 | ||
1146 | /* Make sure the Extended ROM leaf is a multiple of | 1157 | /* Make sure the Extended ROM leaf is a multiple of |
1147 | * max_rom in size. */ | 1158 | * max_rom in size. */ |
1159 | if (csr->max_rom < 1) | ||
1160 | return CSR1212_EINVAL; | ||
1148 | leaf_size = (cache->len + (csr->max_rom - 1)) & | 1161 | leaf_size = (cache->len + (csr->max_rom - 1)) & |
1149 | ~(csr->max_rom - 1); | 1162 | ~(csr->max_rom - 1); |
1150 | 1163 | ||
@@ -1409,7 +1422,7 @@ int _csr1212_read_keyval(struct csr1212_csr *csr, struct csr1212_keyval *kv) | |||
1409 | u_int32_t *cache_ptr; | 1422 | u_int32_t *cache_ptr; |
1410 | u_int16_t kv_len = 0; | 1423 | u_int16_t kv_len = 0; |
1411 | 1424 | ||
1412 | if (!csr || !kv) | 1425 | if (!csr || !kv || csr->max_rom < 1) |
1413 | return CSR1212_EINVAL; | 1426 | return CSR1212_EINVAL; |
1414 | 1427 | ||
1415 | /* First find which cache the data should be in (or go in if not read | 1428 | /* First find which cache the data should be in (or go in if not read |
@@ -1572,7 +1585,7 @@ int csr1212_parse_csr(struct csr1212_csr *csr) | |||
1572 | struct csr1212_dentry *dentry; | 1585 | struct csr1212_dentry *dentry; |
1573 | int ret; | 1586 | int ret; |
1574 | 1587 | ||
1575 | if (!csr || !csr->ops->bus_read) | 1588 | if (!csr || !csr->ops || !csr->ops->bus_read) |
1576 | return CSR1212_EINVAL; | 1589 | return CSR1212_EINVAL; |
1577 | 1590 | ||
1578 | ret = csr1212_parse_bus_info_block(csr); | 1591 | ret = csr1212_parse_bus_info_block(csr); |
@@ -1581,9 +1594,13 @@ int csr1212_parse_csr(struct csr1212_csr *csr) | |||
1581 | 1594 | ||
1582 | if (!csr->ops->get_max_rom) | 1595 | if (!csr->ops->get_max_rom) |
1583 | csr->max_rom = mr_map[0]; /* default value */ | 1596 | csr->max_rom = mr_map[0]; /* default value */ |
1584 | else | 1597 | else { |
1585 | csr->max_rom = mr_map[csr->ops->get_max_rom(csr->bus_info_data, | 1598 | int i = csr->ops->get_max_rom(csr->bus_info_data, |
1586 | csr->private)]; | 1599 | csr->private); |
1600 | if (i & ~0x3) | ||
1601 | return CSR1212_EINVAL; | ||
1602 | csr->max_rom = mr_map[i]; | ||
1603 | } | ||
1587 | 1604 | ||
1588 | csr->cache_head->layout_head = csr->root_kv; | 1605 | csr->cache_head->layout_head = csr->root_kv; |
1589 | csr->cache_head->layout_tail = csr->root_kv; | 1606 | csr->cache_head->layout_tail = csr->root_kv; |