Commit 5917ab47 authored by Alexander Viro's avatar Alexander Viro Committed by Linus Torvalds

[PATCH] drivers/atm/ambassador.c delousing

Translated to C.  Original was anything but.

BTW, even if they were writing in Pascal, their use of nested functions
would be gratuitous for such a situation.
parent 8c881385
...@@ -1706,11 +1706,8 @@ static void destroy_queues (amb_dev * dev) { ...@@ -1706,11 +1706,8 @@ static void destroy_queues (amb_dev * dev) {
} }
/********** basic loader commands and error handling **********/ /********** basic loader commands and error handling **********/
// centisecond timeouts - guessing away here
static int __init do_loader_command (volatile loader_block * lb, static unsigned int command_timeouts [] = {
const amb_dev * dev, loader_command cmd) {
// centisecond timeouts - guessing away here
unsigned int command_timeouts [] = {
[host_memory_test] = 15, [host_memory_test] = 15,
[read_adapter_memory] = 2, [read_adapter_memory] = 2,
[write_adapter_memory] = 2, [write_adapter_memory] = 2,
...@@ -1722,9 +1719,10 @@ static int __init do_loader_command (volatile loader_block * lb, ...@@ -1722,9 +1719,10 @@ static int __init do_loader_command (volatile loader_block * lb,
[adap_erase_flash] = 1, [adap_erase_flash] = 1,
[adap_run_in_iram] = 1, [adap_run_in_iram] = 1,
[adap_end_download] = 1 [adap_end_download] = 1
}; };
unsigned int command_successes [] = { unsigned int command_successes [] = {
[host_memory_test] = COMMAND_PASSED_TEST, [host_memory_test] = COMMAND_PASSED_TEST,
[read_adapter_memory] = COMMAND_READ_DATA_OK, [read_adapter_memory] = COMMAND_READ_DATA_OK,
[write_adapter_memory] = COMMAND_WRITE_DATA_OK, [write_adapter_memory] = COMMAND_WRITE_DATA_OK,
...@@ -1736,11 +1734,12 @@ static int __init do_loader_command (volatile loader_block * lb, ...@@ -1736,11 +1734,12 @@ static int __init do_loader_command (volatile loader_block * lb,
[adap_erase_flash] = COMMAND_COMPLETE, [adap_erase_flash] = COMMAND_COMPLETE,
[adap_run_in_iram] = COMMAND_COMPLETE, [adap_run_in_iram] = COMMAND_COMPLETE,
[adap_end_download] = COMMAND_COMPLETE [adap_end_download] = COMMAND_COMPLETE
}; };
int decode_loader_result (loader_command cmd, u32 result) { static int decode_loader_result (loader_command cmd, u32 result)
{
int res; int res;
const char * msg; const char *msg;
if (result == command_successes[cmd]) if (result == command_successes[cmd])
return 0; return 0;
...@@ -1797,14 +1796,18 @@ static int __init do_loader_command (volatile loader_block * lb, ...@@ -1797,14 +1796,18 @@ static int __init do_loader_command (volatile loader_block * lb,
default: default:
res = -EINVAL; res = -EINVAL;
msg = "unknown error"; msg = "unknown error";
PRINTD (DBG_LOAD|DBG_ERR, "decode_loader_result got %d=%x !", PRINTD (DBG_LOAD|DBG_ERR,
"decode_loader_result got %d=%x !",
result, result); result, result);
break; break;
} }
PRINTK (KERN_ERR, "%s", msg); PRINTK (KERN_ERR, "%s", msg);
return res; return res;
} }
static int __init do_loader_command (volatile loader_block * lb,
const amb_dev * dev, loader_command cmd) {
unsigned long timeout; unsigned long timeout;
...@@ -1930,6 +1933,11 @@ static int __init loader_start (loader_block * lb, ...@@ -1930,6 +1933,11 @@ static int __init loader_start (loader_block * lb,
/********** reset card **********/ /********** reset card **********/
static inline void sf (const char * msg)
{
PRINTK (KERN_ERR, "self-test failed: %s", msg);
}
static int amb_reset (amb_dev * dev, int diags) { static int amb_reset (amb_dev * dev, int diags) {
u32 word; u32 word;
...@@ -1974,9 +1982,6 @@ static int amb_reset (amb_dev * dev, int diags) { ...@@ -1974,9 +1982,6 @@ static int amb_reset (amb_dev * dev, int diags) {
// XXX double check byte-order // XXX double check byte-order
word = rd_mem (dev, offsetof(amb_mem, mb.loader.result)); word = rd_mem (dev, offsetof(amb_mem, mb.loader.result));
if (word & SELF_TEST_FAILURE) { if (word & SELF_TEST_FAILURE) {
void sf (const char * msg) {
PRINTK (KERN_ERR, "self-test failed: %s", msg);
}
if (word & GPINT_TST_FAILURE) if (word & GPINT_TST_FAILURE)
sf ("interrupt"); sf ("interrupt");
if (word & SUNI_DATA_PATTERN_FAILURE) if (word & SUNI_DATA_PATTERN_FAILURE)
...@@ -2045,30 +2050,30 @@ static int __init ucode_init (loader_block * lb, amb_dev * dev) { ...@@ -2045,30 +2050,30 @@ static int __init ucode_init (loader_block * lb, amb_dev * dev) {
/********** give adapter parameters **********/ /********** give adapter parameters **********/
static inline u32 bus_addr(void * addr) {
return cpu_to_be32 (virt_to_bus (addr));
}
static int __init amb_talk (amb_dev * dev) { static int __init amb_talk (amb_dev * dev) {
adap_talk_block a; adap_talk_block a;
unsigned char pool; unsigned char pool;
unsigned long timeout; unsigned long timeout;
u32 x (void * addr) {
return cpu_to_be32 (virt_to_bus (addr));
}
PRINTD (DBG_FLOW, "amb_talk %p", dev); PRINTD (DBG_FLOW, "amb_talk %p", dev);
a.command_start = x (dev->cq.ptrs.start); a.command_start = bus_addr (dev->cq.ptrs.start);
a.command_end = x (dev->cq.ptrs.limit); a.command_end = bus_addr (dev->cq.ptrs.limit);
a.tx_start = x (dev->txq.in.start); a.tx_start = bus_addr (dev->txq.in.start);
a.tx_end = x (dev->txq.in.limit); a.tx_end = bus_addr (dev->txq.in.limit);
a.txcom_start = x (dev->txq.out.start); a.txcom_start = bus_addr (dev->txq.out.start);
a.txcom_end = x (dev->txq.out.limit); a.txcom_end = bus_addr (dev->txq.out.limit);
for (pool = 0; pool < NUM_RX_POOLS; ++pool) { for (pool = 0; pool < NUM_RX_POOLS; ++pool) {
// the other "a" items are set up by the adapter // the other "a" items are set up by the adapter
a.rec_struct[pool].buffer_start = x (dev->rxq[pool].in.start); a.rec_struct[pool].buffer_start = bus_addr (dev->rxq[pool].in.start);
a.rec_struct[pool].buffer_end = x (dev->rxq[pool].in.limit); a.rec_struct[pool].buffer_end = bus_addr (dev->rxq[pool].in.limit);
a.rec_struct[pool].rx_start = x (dev->rxq[pool].out.start); a.rec_struct[pool].rx_start = bus_addr (dev->rxq[pool].out.start);
a.rec_struct[pool].rx_end = x (dev->rxq[pool].out.limit); a.rec_struct[pool].rx_end = bus_addr (dev->rxq[pool].out.limit);
a.rec_struct[pool].buffer_size = cpu_to_be32 (dev->rxq[pool].buffer_size); a.rec_struct[pool].buffer_size = cpu_to_be32 (dev->rxq[pool].buffer_size);
} }
...@@ -2112,14 +2117,9 @@ static void __init amb_ucode_version (amb_dev * dev) { ...@@ -2112,14 +2117,9 @@ static void __init amb_ucode_version (amb_dev * dev) {
PRINTK (KERN_INFO, "microcode version is %u.%u", major, minor); PRINTK (KERN_INFO, "microcode version is %u.%u", major, minor);
} }
// get end station address // swap bits within byte to get Ethernet ordering
static void __init amb_esi (amb_dev * dev, u8 * esi) { u8 bit_swap (u8 byte)
u32 lower4; {
u16 upper2;
command cmd;
// swap bits within byte to get Ethernet ordering
u8 bit_swap (u8 byte) {
const u8 swap[] = { const u8 swap[] = {
0x0, 0x8, 0x4, 0xc, 0x0, 0x8, 0x4, 0xc,
0x2, 0xa, 0x6, 0xe, 0x2, 0xa, 0x6, 0xe,
...@@ -2127,7 +2127,13 @@ static void __init amb_esi (amb_dev * dev, u8 * esi) { ...@@ -2127,7 +2127,13 @@ static void __init amb_esi (amb_dev * dev, u8 * esi) {
0x3, 0xb, 0x7, 0xf 0x3, 0xb, 0x7, 0xf
}; };
return ((swap[byte & 0xf]<<4) | swap[byte>>4]); return ((swap[byte & 0xf]<<4) | swap[byte>>4]);
} }
// get end station address
static void __init amb_esi (amb_dev * dev, u8 * esi) {
u32 lower4;
u16 upper2;
command cmd;
cmd.request = cpu_to_be32 (SRB_GET_BIA); cmd.request = cpu_to_be32 (SRB_GET_BIA);
while (command_do (dev, &cmd)) { while (command_do (dev, &cmd)) {
...@@ -2156,28 +2162,30 @@ static void __init amb_esi (amb_dev * dev, u8 * esi) { ...@@ -2156,28 +2162,30 @@ static void __init amb_esi (amb_dev * dev, u8 * esi) {
return; return;
} }
static int __init amb_init (amb_dev * dev) { static void fixup_plx_window (amb_dev *dev, loader_block *lb)
loader_block lb; {
void fixup_plx_window (void) {
// fix up the PLX-mapped window base address to match the block // fix up the PLX-mapped window base address to match the block
unsigned long blb; unsigned long blb;
u32 mapreg; u32 mapreg;
blb = virt_to_bus (&lb); blb = virt_to_bus(lb);
// the kernel stack had better not ever cross a 1Gb boundary! // the kernel stack had better not ever cross a 1Gb boundary!
mapreg = rd_plain (dev, offsetof(amb_mem, stuff[10])); mapreg = rd_plain (dev, offsetof(amb_mem, stuff[10]));
mapreg &= ~onegigmask; mapreg &= ~onegigmask;
mapreg |= blb & onegigmask; mapreg |= blb & onegigmask;
wr_plain (dev, offsetof(amb_mem, stuff[10]), mapreg); wr_plain (dev, offsetof(amb_mem, stuff[10]), mapreg);
return; return;
} }
static int __init amb_init (amb_dev * dev)
{
loader_block lb;
u32 version; u32 version;
if (amb_reset (dev, 1)) { if (amb_reset (dev, 1)) {
PRINTK (KERN_ERR, "card reset failed!"); PRINTK (KERN_ERR, "card reset failed!");
} else { } else {
fixup_plx_window (); fixup_plx_window (dev, &lb);
if (get_loader_version (&lb, dev, &version)) { if (get_loader_version (&lb, dev, &version)) {
PRINTK (KERN_INFO, "failed to get loader version"); PRINTK (KERN_INFO, "failed to get loader version");
...@@ -2210,28 +2218,17 @@ static int __init amb_init (amb_dev * dev) { ...@@ -2210,28 +2218,17 @@ static int __init amb_init (amb_dev * dev) {
return -1; return -1;
} }
static int __init amb_probe (void) { static void setup_dev(amb_dev *dev, struct pci_dev *pci_dev)
struct pci_dev * pci_dev; {
int devs;
void __init do_pci_device (void) {
amb_dev * dev;
// read resources from PCI configuration space
u8 irq = pci_dev->irq;
u32 * membase = bus_to_virt (pci_resource_start (pci_dev, 0));
u32 iobase = pci_resource_start (pci_dev, 1);
void setup_dev (void) {
unsigned char pool; unsigned char pool;
memset (dev, 0, sizeof(amb_dev)); memset (dev, 0, sizeof(amb_dev));
// set up known dev items straight away // set up known dev items straight away
dev->pci_dev = pci_dev; dev->pci_dev = pci_dev;
dev->iobase = iobase; dev->iobase = pci_resource_start (pci_dev, 1);
dev->irq = irq; dev->irq = pci_dev->irq;
dev->membase = membase; dev->membase = bus_to_virt(pci_resource_start(pci_dev, 0));
// flags (currently only dead) // flags (currently only dead)
dev->flags = 0; dev->flags = 0;
...@@ -2258,16 +2255,17 @@ static int __init amb_probe (void) { ...@@ -2258,16 +2255,17 @@ static int __init amb_probe (void) {
spin_lock_init (&dev->txq.lock); spin_lock_init (&dev->txq.lock);
for (pool = 0; pool < NUM_RX_POOLS; ++pool) for (pool = 0; pool < NUM_RX_POOLS; ++pool)
spin_lock_init (&dev->rxq[pool].lock); spin_lock_init (&dev->rxq[pool].lock);
} }
void setup_pci_dev (void) { static void setup_pci_dev(struct pci_dev *pci_dev)
{
unsigned char lat; unsigned char lat;
/* XXX check return value */ /* XXX check return value */
pci_enable_device (pci_dev); pci_enable_device(pci_dev);
// enable bus master accesses // enable bus master accesses
pci_set_master (pci_dev); pci_set_master(pci_dev);
// frobnicate latency (upwards, usually) // frobnicate latency (upwards, usually)
pci_read_config_byte (pci_dev, PCI_LATENCY_TIMER, &lat); pci_read_config_byte (pci_dev, PCI_LATENCY_TIMER, &lat);
...@@ -2280,7 +2278,17 @@ static int __init amb_probe (void) { ...@@ -2280,7 +2278,17 @@ static int __init amb_probe (void) {
"increasing", lat, MIN_PCI_LATENCY); "increasing", lat, MIN_PCI_LATENCY);
pci_write_config_byte (pci_dev, PCI_LATENCY_TIMER, MIN_PCI_LATENCY); pci_write_config_byte (pci_dev, PCI_LATENCY_TIMER, MIN_PCI_LATENCY);
} }
} }
static int __init do_pci_device(struct pci_dev *pci_dev)
{
amb_dev * dev;
int err;
// read resources from PCI configuration space
u8 irq = pci_dev->irq;
u32 * membase = bus_to_virt (pci_resource_start (pci_dev, 0));
u32 iobase = pci_resource_start (pci_dev, 1);
PRINTD (DBG_INFO, "found Madge ATM adapter (amb) at" PRINTD (DBG_INFO, "found Madge ATM adapter (amb) at"
" IO %x, IRQ %u, MEM %p", iobase, irq, membase); " IO %x, IRQ %u, MEM %p", iobase, irq, membase);
...@@ -2288,35 +2296,39 @@ static int __init amb_probe (void) { ...@@ -2288,35 +2296,39 @@ static int __init amb_probe (void) {
// check IO region // check IO region
if (!request_region (iobase, AMB_EXTENT, DEV_LABEL)) { if (!request_region (iobase, AMB_EXTENT, DEV_LABEL)) {
PRINTK (KERN_ERR, "IO range already in use!"); PRINTK (KERN_ERR, "IO range already in use!");
return; return -EBUSY;
} }
dev = kmalloc (sizeof(amb_dev), GFP_KERNEL); dev = kmalloc (sizeof(amb_dev), GFP_KERNEL);
if (!dev) { if (!dev) {
// perhaps we should be nice: deregister all adapters and abort?
PRINTK (KERN_ERR, "out of memory!"); PRINTK (KERN_ERR, "out of memory!");
release_region (iobase, AMB_EXTENT); err = -ENOMEM;
return; goto out;
} }
setup_dev(); setup_dev(dev, pci_dev);
if (amb_init (dev)) { if (amb_init (dev)) {
PRINTK (KERN_ERR, "adapter initialisation failure"); PRINTK (KERN_ERR, "adapter initialisation failure");
} else { err = -EINVAL;
goto out1;
}
setup_pci_dev(); setup_pci_dev(pci_dev);
// grab (but share) IRQ and install handler // grab (but share) IRQ and install handler
if (request_irq (irq, interrupt_handler, SA_SHIRQ, DEV_LABEL, dev)) { if (request_irq (irq, interrupt_handler, SA_SHIRQ, DEV_LABEL, dev)) {
PRINTK (KERN_ERR, "request IRQ failed!"); PRINTK (KERN_ERR, "request IRQ failed!");
// free_irq is at "endif" err = -EBUSY;
} else { goto out2;
}
dev->atm_dev = atm_dev_register (DEV_LABEL, &amb_ops, -1, NULL); dev->atm_dev = atm_dev_register (DEV_LABEL, &amb_ops, -1, NULL);
if (!dev->atm_dev) { if (!dev->atm_dev) {
PRINTD (DBG_ERR, "failed to register Madge ATM adapter"); PRINTD (DBG_ERR, "failed to register Madge ATM adapter");
} else { err = -EINVAL;
goto out3;
}
PRINTD (DBG_INFO, "registered Madge ATM adapter (no. %d) (%p) at %p", PRINTD (DBG_INFO, "registered Madge ATM adapter (no. %d) (%p) at %p",
dev->atm_dev->number, dev, dev->atm_dev); dev->atm_dev->number, dev, dev->atm_dev);
...@@ -2329,30 +2341,29 @@ static int __init amb_probe (void) { ...@@ -2329,30 +2341,29 @@ static int __init amb_probe (void) {
dev->atm_dev->ci_range.vpi_bits = NUM_VPI_BITS; dev->atm_dev->ci_range.vpi_bits = NUM_VPI_BITS;
dev->atm_dev->ci_range.vci_bits = NUM_VCI_BITS; dev->atm_dev->ci_range.vci_bits = NUM_VCI_BITS;
// update count and linked list // update linked list
++devs;
dev->prev = amb_devs; dev->prev = amb_devs;
amb_devs = dev; amb_devs = dev;
// enable host interrupts // enable host interrupts
interrupts_on (dev); interrupts_on (dev);
// success return 0;
return;
// not currently reached
atm_dev_deregister (dev->atm_dev);
} /* atm_dev_register */
out3:
free_irq (irq, dev); free_irq (irq, dev);
} /* request_irq */ out2:
amb_reset (dev, 0); amb_reset (dev, 0);
} /* amb_init */ out1:
kfree (dev); kfree (dev);
out:
release_region (iobase, AMB_EXTENT); release_region (iobase, AMB_EXTENT);
} /* kmalloc, end-of-fn */ return err;
}
static int __init amb_probe (void) {
struct pci_dev * pci_dev;
int devs;
PRINTD (DBG_FLOW, "amb_probe"); PRINTD (DBG_FLOW, "amb_probe");
...@@ -2360,8 +2371,11 @@ static int __init amb_probe (void) { ...@@ -2360,8 +2371,11 @@ static int __init amb_probe (void) {
pci_dev = NULL; pci_dev = NULL;
while ((pci_dev = pci_find_device while ((pci_dev = pci_find_device
(PCI_VENDOR_ID_MADGE, PCI_DEVICE_ID_MADGE_AMBASSADOR, pci_dev) (PCI_VENDOR_ID_MADGE, PCI_DEVICE_ID_MADGE_AMBASSADOR, pci_dev)
)) )) {
do_pci_device(); if (do_pci_device(pci_dev) == 0)
devs++;
}
pci_dev = NULL; pci_dev = NULL;
while ((pci_dev = pci_find_device while ((pci_dev = pci_find_device
......
Markdown is supported
0%
or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment