aboutsummaryrefslogtreecommitdiffstats
path: root/drivers/atm/ambassador.c
diff options
context:
space:
mode:
authorDavid Woodhouse <dwmw2@infradead.org>2008-06-05 07:59:51 -0400
committerDavid Woodhouse <David.Woodhouse@intel.com>2008-07-10 09:49:39 -0400
commit27d202fff1555f5b0eb16a5aedc452566f9ab8bb (patch)
tree702f44afc97e1eee2f99f4cf88ca605ee2b50981 /drivers/atm/ambassador.c
parentec6752f5afce659025962e25fb2f42b3911254a1 (diff)
firmware: convert Ambassador ATM driver to request_firmware()
Since it had various regions to be loaded to separate addresses, and it wanted to do them in fairly small chunks anyway, switch it to use the new ihex code. Encode the start address in the first record. Signed-off-by: David Woodhouse <dwmw2@infradead.org> Acked-by: Chas Williams <chas@cmf.nrl.navy.mil>
Diffstat (limited to 'drivers/atm/ambassador.c')
-rw-r--r--drivers/atm/ambassador.c140
1 files changed, 57 insertions, 83 deletions
diff --git a/drivers/atm/ambassador.c b/drivers/atm/ambassador.c
index 6adb72a2f876..703364b52170 100644
--- a/drivers/atm/ambassador.c
+++ b/drivers/atm/ambassador.c
@@ -34,6 +34,8 @@
34#include <linux/poison.h> 34#include <linux/poison.h>
35#include <linux/bitrev.h> 35#include <linux/bitrev.h>
36#include <linux/mutex.h> 36#include <linux/mutex.h>
37#include <linux/firmware.h>
38#include <linux/ihex.h>
37 39
38#include <asm/atomic.h> 40#include <asm/atomic.h>
39#include <asm/io.h> 41#include <asm/io.h>
@@ -290,29 +292,6 @@ static inline void __init show_version (void) {
290 292
291*/ 293*/
292 294
293/********** microcode **********/
294
295#ifdef AMB_NEW_MICROCODE
296#define UCODE(x) UCODE2(atmsar12.x)
297#else
298#define UCODE(x) UCODE2(atmsar11.x)
299#endif
300#define UCODE2(x) #x
301
302static u32 __devinitdata ucode_start =
303#include UCODE(start)
304;
305
306static region __devinitdata ucode_regions[] = {
307#include UCODE(regions)
308 { 0, 0 }
309};
310
311static u32 __devinitdata ucode_data[] = {
312#include UCODE(data)
313 0xdeadbeef
314};
315
316static void do_housekeeping (unsigned long arg); 295static void do_housekeeping (unsigned long arg);
317/********** globals **********/ 296/********** globals **********/
318 297
@@ -1841,45 +1820,34 @@ static int __devinit get_loader_version (loader_block * lb,
1841 1820
1842/* loader: write memory data blocks */ 1821/* loader: write memory data blocks */
1843 1822
1844static int __devinit loader_write (loader_block * lb, 1823static int __devinit loader_write (loader_block* lb,
1845 const amb_dev * dev, const u32 * data, 1824 const amb_dev *dev,
1846 u32 address, unsigned int count) { 1825 const struct ihex_binrec *rec) {
1847 unsigned int i;
1848 transfer_block * tb = &lb->payload.transfer; 1826 transfer_block * tb = &lb->payload.transfer;
1849 1827
1850 PRINTD (DBG_FLOW|DBG_LOAD, "loader_write"); 1828 PRINTD (DBG_FLOW|DBG_LOAD, "loader_write");
1851 1829
1852 if (count > MAX_TRANSFER_DATA) 1830 tb->address = rec->addr;
1853 return -EINVAL; 1831 tb->count = cpu_to_be32(be16_to_cpu(rec->len) / 4);
1854 tb->address = cpu_to_be32 (address); 1832 memcpy(tb->data, rec->data, be16_to_cpu(rec->len));
1855 tb->count = cpu_to_be32 (count);
1856 for (i = 0; i < count; ++i)
1857 tb->data[i] = cpu_to_be32 (data[i]);
1858 return do_loader_command (lb, dev, write_adapter_memory); 1833 return do_loader_command (lb, dev, write_adapter_memory);
1859} 1834}
1860 1835
1861/* loader: verify memory data blocks */ 1836/* loader: verify memory data blocks */
1862 1837
1863static int __devinit loader_verify (loader_block * lb, 1838static int __devinit loader_verify (loader_block * lb,
1864 const amb_dev * dev, const u32 * data, 1839 const amb_dev *dev,
1865 u32 address, unsigned int count) { 1840 const struct ihex_binrec *rec) {
1866 unsigned int i;
1867 transfer_block * tb = &lb->payload.transfer; 1841 transfer_block * tb = &lb->payload.transfer;
1868 int res; 1842 int res;
1869 1843
1870 PRINTD (DBG_FLOW|DBG_LOAD, "loader_verify"); 1844 PRINTD (DBG_FLOW|DBG_LOAD, "loader_verify");
1871 1845
1872 if (count > MAX_TRANSFER_DATA) 1846 tb->address = rec->addr;
1873 return -EINVAL; 1847 tb->count = cpu_to_be32(be16_to_cpu(rec->len) / 4);
1874 tb->address = cpu_to_be32 (address);
1875 tb->count = cpu_to_be32 (count);
1876 res = do_loader_command (lb, dev, read_adapter_memory); 1848 res = do_loader_command (lb, dev, read_adapter_memory);
1877 if (!res) 1849 if (!res && memcmp(tb->data, rec->data, be16_to_cpu(rec->len)))
1878 for (i = 0; i < count; ++i) 1850 res = -EINVAL;
1879 if (tb->data[i] != cpu_to_be32 (data[i])) {
1880 res = -EINVAL;
1881 break;
1882 }
1883 return res; 1851 return res;
1884} 1852}
1885 1853
@@ -1962,47 +1930,53 @@ static int amb_reset (amb_dev * dev, int diags) {
1962/********** transfer and start the microcode **********/ 1930/********** transfer and start the microcode **********/
1963 1931
1964static int __devinit ucode_init (loader_block * lb, amb_dev * dev) { 1932static int __devinit ucode_init (loader_block * lb, amb_dev * dev) {
1965 unsigned int i = 0; 1933 const struct firmware *fw;
1966 unsigned int total = 0; 1934 unsigned long start_address;
1967 const u32 * pointer = ucode_data; 1935 const struct ihex_binrec *rec;
1968 u32 address;
1969 unsigned int count;
1970 int res; 1936 int res;
1971 1937
1938 res = request_ihex_firmware(&fw, "atmsar11.fw", &dev->pci_dev->dev);
1939 if (res) {
1940 PRINTK (KERN_ERR, "Cannot load microcode data");
1941 return res;
1942 }
1943
1944 /* First record contains just the start address */
1945 rec = (const struct ihex_binrec *)fw->data;
1946 if (be16_to_cpu(rec->len) != sizeof(__be32) || be32_to_cpu(rec->addr)) {
1947 PRINTK (KERN_ERR, "Bad microcode data (no start record)");
1948 return -EINVAL;
1949 }
1950 start_address = be32_to_cpup((__be32 *)rec->data);
1951
1952 rec = ihex_next_binrec(rec);
1953
1972 PRINTD (DBG_FLOW|DBG_LOAD, "ucode_init"); 1954 PRINTD (DBG_FLOW|DBG_LOAD, "ucode_init");
1973 1955
1974 while (address = ucode_regions[i].start, 1956 while (rec) {
1975 count = ucode_regions[i].count) { 1957 PRINTD (DBG_LOAD, "starting region (%x, %u)", be32_to_cpu(rec->addr),
1976 PRINTD (DBG_LOAD, "starting region (%x, %u)", address, count); 1958 be16_to_cpu(rec->len));
1977 while (count) { 1959 if (be16_to_cpu(rec->len) > 4 * MAX_TRANSFER_DATA) {
1978 unsigned int words; 1960 PRINTK (KERN_ERR, "Bad microcode data (record too long)");
1979 if (count <= MAX_TRANSFER_DATA) 1961 return -EINVAL;
1980 words = count;
1981 else
1982 words = MAX_TRANSFER_DATA;
1983 total += words;
1984 res = loader_write (lb, dev, pointer, address, words);
1985 if (res)
1986 return res;
1987 res = loader_verify (lb, dev, pointer, address, words);
1988 if (res)
1989 return res;
1990 count -= words;
1991 address += sizeof(u32) * words;
1992 pointer += words;
1993 } 1962 }
1994 i += 1; 1963 if (be16_to_cpu(rec->len) & 3) {
1995 } 1964 PRINTK (KERN_ERR, "Bad microcode data (odd number of bytes)");
1996 if (*pointer == ATM_POISON) { 1965 return -EINVAL;
1997 return loader_start (lb, dev, ucode_start); 1966 }
1998 } else { 1967 res = loader_write(lb, dev, rec);
1999 // cast needed as there is no %? for pointer differnces 1968 if (res)
2000 PRINTD (DBG_LOAD|DBG_ERR, 1969 break;
2001 "offset=%li, *pointer=%x, address=%x, total=%u", 1970
2002 (long) (pointer - ucode_data), *pointer, address, total); 1971 res = loader_verify(lb, dev, rec);
2003 PRINTK (KERN_ERR, "incorrect microcode data"); 1972 if (res)
2004 return -ENOMEM; 1973 break;
2005 } 1974 }
1975 release_firmware(fw);
1976 if (!res)
1977 res = loader_start(lb, dev, start_address);
1978
1979 return res;
2006} 1980}
2007 1981
2008/********** give adapter parameters **********/ 1982/********** give adapter parameters **********/