aboutsummaryrefslogtreecommitdiffstats
path: root/drivers/firewire
diff options
context:
space:
mode:
authorStefan Richter <stefanr@s5r6.in-berlin.de>2009-10-07 18:41:59 -0400
committerStefan Richter <stefanr@s5r6.in-berlin.de>2009-10-14 17:10:48 -0400
commit8e85973efc87dfae8508f1a3440fd44612897458 (patch)
tree9b8f0f0d1adf5a2611b58565db4d9da0ebd1cc9c /drivers/firewire
parente21fcf798e246202d7b60e864f1d7302ebaaf41c (diff)
firewire: optimize config ROM creation
The config ROM image of the local node was created in CPU byte order, then a temporary big endian copy was created to compute the CRC, and finally the card driver created its own big endian copy. We now generate it in big endian byte order in the first place to avoid one byte order conversion and the temporary on-stack copy of the ROM image (1000 bytes stack usage in process context). Furthermore, two 1000 bytes memset()s are replaced by one 1000 bytes - ROM length sized memset. The trivial fw_memcpy_{from,to}_be32() helpers are now superfluous and removed. The newly added __compute_block_crc() function will be folded into fw_compute_block_crc() in a subsequent change. Signed-off-by: Stefan Richter <stefanr@s5r6.in-berlin.de>
Diffstat (limited to 'drivers/firewire')
-rw-r--r--drivers/firewire/core-card.c62
-rw-r--r--drivers/firewire/core.h7
-rw-r--r--drivers/firewire/ohci.c30
3 files changed, 60 insertions, 39 deletions
diff --git a/drivers/firewire/core-card.c b/drivers/firewire/core-card.c
index 33898b63cdf7..f73e3bdfc84c 100644
--- a/drivers/firewire/core-card.c
+++ b/drivers/firewire/core-card.c
@@ -38,6 +38,18 @@
38 38
39#include "core.h" 39#include "core.h"
40 40
41static int __compute_block_crc(__be32 *block)
42{
43 int length;
44 u16 crc;
45
46 length = (be32_to_cpu(block[0]) >> 16) & 0xff;
47 crc = crc_itu_t(0, (u8 *)&block[1], length * 4);
48 *block |= cpu_to_be32(crc);
49
50 return length;
51}
52
41int fw_compute_block_crc(u32 *block) 53int fw_compute_block_crc(u32 *block)
42{ 54{
43 __be32 be32_block[256]; 55 __be32 be32_block[256];
@@ -72,11 +84,11 @@ static int descriptor_count;
72#define BIB_CMC ((1) << 30) 84#define BIB_CMC ((1) << 30)
73#define BIB_IMC ((1) << 31) 85#define BIB_IMC ((1) << 31)
74 86
75static u32 *generate_config_rom(struct fw_card *card, size_t *config_rom_length) 87static __be32 *generate_config_rom(struct fw_card *card, size_t *rom_length)
76{ 88{
77 struct fw_descriptor *desc; 89 struct fw_descriptor *desc;
78 static u32 config_rom[256]; 90 static __be32 config_rom[256];
79 int i, j, length; 91 int i, j, k, length;
80 92
81 /* 93 /*
82 * Initialize contents of config rom buffer. On the OHCI 94 * Initialize contents of config rom buffer. On the OHCI
@@ -87,40 +99,39 @@ static u32 *generate_config_rom(struct fw_card *card, size_t *config_rom_length)
87 * the version stored in the OHCI registers. 99 * the version stored in the OHCI registers.
88 */ 100 */
89 101
90 memset(config_rom, 0, sizeof(config_rom)); 102 config_rom[0] = cpu_to_be32(
91 config_rom[0] = BIB_CRC_LENGTH(4) | BIB_INFO_LENGTH(4) | BIB_CRC(0); 103 BIB_CRC_LENGTH(4) | BIB_INFO_LENGTH(4) | BIB_CRC(0));
92 config_rom[1] = 0x31333934; 104 config_rom[1] = cpu_to_be32(0x31333934);
93 105 config_rom[2] = cpu_to_be32(
94 config_rom[2] =
95 BIB_LINK_SPEED(card->link_speed) | 106 BIB_LINK_SPEED(card->link_speed) |
96 BIB_GENERATION(card->config_rom_generation++ % 14 + 2) | 107 BIB_GENERATION(card->config_rom_generation++ % 14 + 2) |
97 BIB_MAX_ROM(2) | 108 BIB_MAX_ROM(2) |
98 BIB_MAX_RECEIVE(card->max_receive) | 109 BIB_MAX_RECEIVE(card->max_receive) |
99 BIB_BMC | BIB_ISC | BIB_CMC | BIB_IMC; 110 BIB_BMC | BIB_ISC | BIB_CMC | BIB_IMC);
100 config_rom[3] = card->guid >> 32; 111 config_rom[3] = cpu_to_be32(card->guid >> 32);
101 config_rom[4] = card->guid; 112 config_rom[4] = cpu_to_be32(card->guid);
102 113
103 /* Generate root directory. */ 114 /* Generate root directory. */
104 i = 5; 115 config_rom[6] = cpu_to_be32(0x0c0083c0); /* node capabilities */
105 config_rom[i++] = 0; 116 i = 7;
106 config_rom[i++] = 0x0c0083c0; /* node capabilities */ 117 j = 7 + descriptor_count;
107 j = i + descriptor_count;
108 118
109 /* Generate root directory entries for descriptors. */ 119 /* Generate root directory entries for descriptors. */
110 list_for_each_entry (desc, &descriptor_list, link) { 120 list_for_each_entry (desc, &descriptor_list, link) {
111 if (desc->immediate > 0) 121 if (desc->immediate > 0)
112 config_rom[i++] = desc->immediate; 122 config_rom[i++] = cpu_to_be32(desc->immediate);
113 config_rom[i] = desc->key | (j - i); 123 config_rom[i] = cpu_to_be32(desc->key | (j - i));
114 i++; 124 i++;
115 j += desc->length; 125 j += desc->length;
116 } 126 }
117 127
118 /* Update root directory length. */ 128 /* Update root directory length. */
119 config_rom[5] = (i - 5 - 1) << 16; 129 config_rom[5] = cpu_to_be32((i - 5 - 1) << 16);
120 130
121 /* End of root directory, now copy in descriptors. */ 131 /* End of root directory, now copy in descriptors. */
122 list_for_each_entry (desc, &descriptor_list, link) { 132 list_for_each_entry (desc, &descriptor_list, link) {
123 memcpy(&config_rom[i], desc->data, desc->length * 4); 133 for (k = 0; k < desc->length; k++)
134 config_rom[i + k] = cpu_to_be32(desc->data[k]);
124 i += desc->length; 135 i += desc->length;
125 } 136 }
126 137
@@ -129,9 +140,9 @@ static u32 *generate_config_rom(struct fw_card *card, size_t *config_rom_length)
129 * the bus info block, which is always the case for this 140 * the bus info block, which is always the case for this
130 * implementation. */ 141 * implementation. */
131 for (i = 0; i < j; i += length + 1) 142 for (i = 0; i < j; i += length + 1)
132 length = fw_compute_block_crc(config_rom + i); 143 length = __compute_block_crc(config_rom + i);
133 144
134 *config_rom_length = j; 145 *rom_length = j;
135 146
136 return config_rom; 147 return config_rom;
137} 148}
@@ -139,7 +150,7 @@ static u32 *generate_config_rom(struct fw_card *card, size_t *config_rom_length)
139static void update_config_roms(void) 150static void update_config_roms(void)
140{ 151{
141 struct fw_card *card; 152 struct fw_card *card;
142 u32 *config_rom; 153 __be32 *config_rom;
143 size_t length; 154 size_t length;
144 155
145 list_for_each_entry (card, &card_list, link) { 156 list_for_each_entry (card, &card_list, link) {
@@ -432,7 +443,7 @@ EXPORT_SYMBOL(fw_card_initialize);
432int fw_card_add(struct fw_card *card, 443int fw_card_add(struct fw_card *card,
433 u32 max_receive, u32 link_speed, u64 guid) 444 u32 max_receive, u32 link_speed, u64 guid)
434{ 445{
435 u32 *config_rom; 446 __be32 *config_rom;
436 size_t length; 447 size_t length;
437 int ret; 448 int ret;
438 449
@@ -462,7 +473,8 @@ EXPORT_SYMBOL(fw_card_add);
462 * shutdown still need to be provided by the card driver. 473 * shutdown still need to be provided by the card driver.
463 */ 474 */
464 475
465static int dummy_enable(struct fw_card *card, u32 *config_rom, size_t length) 476static int dummy_enable(struct fw_card *card,
477 const __be32 *config_rom, size_t length)
466{ 478{
467 BUG(); 479 BUG();
468 return -1; 480 return -1;
@@ -475,7 +487,7 @@ static int dummy_update_phy_reg(struct fw_card *card, int address,
475} 487}
476 488
477static int dummy_set_config_rom(struct fw_card *card, 489static int dummy_set_config_rom(struct fw_card *card,
478 u32 *config_rom, size_t length) 490 const __be32 *config_rom, size_t length)
479{ 491{
480 /* 492 /*
481 * We take the card out of card_list before setting the dummy 493 * We take the card out of card_list before setting the dummy
diff --git a/drivers/firewire/core.h b/drivers/firewire/core.h
index 7ff6e7585152..7adca7cb9f55 100644
--- a/drivers/firewire/core.h
+++ b/drivers/firewire/core.h
@@ -40,7 +40,8 @@ struct fw_card_driver {
40 * enable the PHY or set the link_on bit and initiate a bus 40 * enable the PHY or set the link_on bit and initiate a bus
41 * reset. 41 * reset.
42 */ 42 */
43 int (*enable)(struct fw_card *card, u32 *config_rom, size_t length); 43 int (*enable)(struct fw_card *card,
44 const __be32 *config_rom, size_t length);
44 45
45 int (*update_phy_reg)(struct fw_card *card, int address, 46 int (*update_phy_reg)(struct fw_card *card, int address,
46 int clear_bits, int set_bits); 47 int clear_bits, int set_bits);
@@ -48,10 +49,10 @@ struct fw_card_driver {
48 /* 49 /*
49 * Update the config rom for an enabled card. This function 50 * Update the config rom for an enabled card. This function
50 * should change the config rom that is presented on the bus 51 * should change the config rom that is presented on the bus
51 * an initiate a bus reset. 52 * and initiate a bus reset.
52 */ 53 */
53 int (*set_config_rom)(struct fw_card *card, 54 int (*set_config_rom)(struct fw_card *card,
54 u32 *config_rom, size_t length); 55 const __be32 *config_rom, size_t length);
55 56
56 void (*send_request)(struct fw_card *card, struct fw_packet *packet); 57 void (*send_request)(struct fw_card *card, struct fw_packet *packet);
57 void (*send_response)(struct fw_card *card, struct fw_packet *packet); 58 void (*send_response)(struct fw_card *card, struct fw_packet *packet);
diff --git a/drivers/firewire/ohci.c b/drivers/firewire/ohci.c
index 5d524254499e..418415564791 100644
--- a/drivers/firewire/ohci.c
+++ b/drivers/firewire/ohci.c
@@ -205,7 +205,7 @@ struct fw_ohci {
205 dma_addr_t config_rom_bus; 205 dma_addr_t config_rom_bus;
206 __be32 *next_config_rom; 206 __be32 *next_config_rom;
207 dma_addr_t next_config_rom_bus; 207 dma_addr_t next_config_rom_bus;
208 u32 next_header; 208 __be32 next_header;
209 209
210 struct ar_context ar_request_ctx; 210 struct ar_context ar_request_ctx;
211 struct ar_context ar_response_ctx; 211 struct ar_context ar_response_ctx;
@@ -1355,8 +1355,9 @@ static void bus_reset_tasklet(unsigned long data)
1355 */ 1355 */
1356 reg_write(ohci, OHCI1394_BusOptions, 1356 reg_write(ohci, OHCI1394_BusOptions,
1357 be32_to_cpu(ohci->config_rom[2])); 1357 be32_to_cpu(ohci->config_rom[2]));
1358 ohci->config_rom[0] = cpu_to_be32(ohci->next_header); 1358 ohci->config_rom[0] = ohci->next_header;
1359 reg_write(ohci, OHCI1394_ConfigROMhdr, ohci->next_header); 1359 reg_write(ohci, OHCI1394_ConfigROMhdr,
1360 be32_to_cpu(ohci->next_header));
1360 } 1361 }
1361 1362
1362#ifdef CONFIG_FIREWIRE_OHCI_REMOTE_DMA 1363#ifdef CONFIG_FIREWIRE_OHCI_REMOTE_DMA
@@ -1464,7 +1465,17 @@ static int software_reset(struct fw_ohci *ohci)
1464 return -EBUSY; 1465 return -EBUSY;
1465} 1466}
1466 1467
1467static int ohci_enable(struct fw_card *card, u32 *config_rom, size_t length) 1468static void copy_config_rom(__be32 *dest, const __be32 *src, size_t length)
1469{
1470 size_t size = length * 4;
1471
1472 memcpy(dest, src, size);
1473 if (size < CONFIG_ROM_SIZE)
1474 memset(&dest[length], 0, CONFIG_ROM_SIZE - size);
1475}
1476
1477static int ohci_enable(struct fw_card *card,
1478 const __be32 *config_rom, size_t length)
1468{ 1479{
1469 struct fw_ohci *ohci = fw_ohci(card); 1480 struct fw_ohci *ohci = fw_ohci(card);
1470 struct pci_dev *dev = to_pci_dev(card->device); 1481 struct pci_dev *dev = to_pci_dev(card->device);
@@ -1565,8 +1576,7 @@ static int ohci_enable(struct fw_card *card, u32 *config_rom, size_t length)
1565 if (ohci->next_config_rom == NULL) 1576 if (ohci->next_config_rom == NULL)
1566 return -ENOMEM; 1577 return -ENOMEM;
1567 1578
1568 memset(ohci->next_config_rom, 0, CONFIG_ROM_SIZE); 1579 copy_config_rom(ohci->next_config_rom, config_rom, length);
1569 fw_memcpy_to_be32(ohci->next_config_rom, config_rom, length * 4);
1570 } else { 1580 } else {
1571 /* 1581 /*
1572 * In the suspend case, config_rom is NULL, which 1582 * In the suspend case, config_rom is NULL, which
@@ -1576,7 +1586,7 @@ static int ohci_enable(struct fw_card *card, u32 *config_rom, size_t length)
1576 ohci->next_config_rom_bus = ohci->config_rom_bus; 1586 ohci->next_config_rom_bus = ohci->config_rom_bus;
1577 } 1587 }
1578 1588
1579 ohci->next_header = be32_to_cpu(ohci->next_config_rom[0]); 1589 ohci->next_header = ohci->next_config_rom[0];
1580 ohci->next_config_rom[0] = 0; 1590 ohci->next_config_rom[0] = 0;
1581 reg_write(ohci, OHCI1394_ConfigROMhdr, 0); 1591 reg_write(ohci, OHCI1394_ConfigROMhdr, 0);
1582 reg_write(ohci, OHCI1394_BusOptions, 1592 reg_write(ohci, OHCI1394_BusOptions,
@@ -1610,7 +1620,7 @@ static int ohci_enable(struct fw_card *card, u32 *config_rom, size_t length)
1610} 1620}
1611 1621
1612static int ohci_set_config_rom(struct fw_card *card, 1622static int ohci_set_config_rom(struct fw_card *card,
1613 u32 *config_rom, size_t length) 1623 const __be32 *config_rom, size_t length)
1614{ 1624{
1615 struct fw_ohci *ohci; 1625 struct fw_ohci *ohci;
1616 unsigned long flags; 1626 unsigned long flags;
@@ -1659,9 +1669,7 @@ static int ohci_set_config_rom(struct fw_card *card,
1659 ohci->next_config_rom = next_config_rom; 1669 ohci->next_config_rom = next_config_rom;
1660 ohci->next_config_rom_bus = next_config_rom_bus; 1670 ohci->next_config_rom_bus = next_config_rom_bus;
1661 1671
1662 memset(ohci->next_config_rom, 0, CONFIG_ROM_SIZE); 1672 copy_config_rom(ohci->next_config_rom, config_rom, length);
1663 fw_memcpy_to_be32(ohci->next_config_rom, config_rom,
1664 length * 4);
1665 1673
1666 ohci->next_header = config_rom[0]; 1674 ohci->next_header = config_rom[0];
1667 ohci->next_config_rom[0] = 0; 1675 ohci->next_config_rom[0] = 0;