#include <linux/atmdev.h>
#include <linux/delay.h>
#include <linux/interrupt.h>
+#include <linux/poison.h>
#include <asm/atomic.h>
#include <asm/io.h>
#endif
#define UCODE2(x) #x
-static u32 __initdata ucode_start =
+static u32 __devinitdata ucode_start =
#include UCODE(start)
;
-static region __initdata ucode_regions[] = {
+static region __devinitdata ucode_regions[] = {
#include UCODE(regions)
{ 0, 0 }
};
-static u32 __initdata ucode_data[] = {
+static u32 __devinitdata ucode_data[] = {
#include UCODE(data)
0xdeadbeef
};
}
static inline void wr_mem (const amb_dev * dev, size_t addr, u32 data) {
- u32 be = cpu_to_be32 (data);
+ __be32 be = cpu_to_be32 (data);
PRINTD (DBG_FLOW|DBG_REGS, "wr: %08zx <- %08x b[%08x]", addr, data, be);
#ifdef AMB_MMIO
dev->membase[addr / sizeof(u32)] = be;
static inline u32 rd_mem (const amb_dev * dev, size_t addr) {
#ifdef AMB_MMIO
- u32 be = dev->membase[addr / sizeof(u32)];
+ __be32 be = dev->membase[addr / sizeof(u32)];
#else
- u32 be = inl (dev->iobase + addr);
+ __be32 be = inl (dev->iobase + addr);
#endif
u32 data = be32_to_cpu (be);
PRINTD (DBG_FLOW|DBG_REGS, "rd: %08zx -> %08x b[%08x]", addr, data, be);
// VC layer stats
atomic_inc(&atm_vcc->stats->rx);
- do_gettimeofday(&skb->stamp);
+ __net_timestamp(skb);
// end of our responsability
atm_vcc->push (atm_vcc, skb);
return;
amb_cq * cq = &dev->cq;
volatile amb_cq_ptrs * ptrs = &cq->ptrs;
command * my_slot;
- unsigned long timeout;
PRINTD (DBG_FLOW|DBG_CMD, "command_do %p", dev);
// mail the command
wr_mem (dev, offsetof(amb_mem, mb.adapter.cmd_address), virt_to_bus (ptrs->in));
- // prepare to wait for cq->pending milliseconds
- // effectively one centisecond on i386
- timeout = (cq->pending*HZ+999)/1000;
-
if (cq->pending > cq->high)
cq->high = cq->pending;
spin_unlock (&cq->lock);
- while (timeout) {
- // go to sleep
- // PRINTD (DBG_CMD, "wait: sleeping %lu for command", timeout);
- set_current_state(TASK_UNINTERRUPTIBLE);
- timeout = schedule_timeout (timeout);
- }
+ // these comments were in a while-loop before, msleep removes the loop
+ // go to sleep
+ // PRINTD (DBG_CMD, "wait: sleeping %lu for command", timeout);
+ msleep(cq->pending);
// wait for my slot to be reached (all waiters are here or above, until...)
while (ptrs->out != my_slot) {
drain_rx_pool (dev, pool);
}
-static inline void fill_rx_pool (amb_dev * dev, unsigned char pool, int priority) {
+static inline void fill_rx_pool (amb_dev * dev, unsigned char pool,
+ gfp_t priority)
+{
rx_in rx;
amb_rxq * rxq;
/********** creation of communication queues **********/
-static int __init create_queues (amb_dev * dev, unsigned int cmds,
+static int __devinit create_queues (amb_dev * dev, unsigned int cmds,
unsigned int txs, unsigned int * rxs,
unsigned int * rx_buffer_sizes) {
unsigned char pool;
};
-unsigned int command_successes [] = {
+static unsigned int command_successes [] = {
[host_memory_test] = COMMAND_PASSED_TEST,
[read_adapter_memory] = COMMAND_READ_DATA_OK,
[write_adapter_memory] = COMMAND_WRITE_DATA_OK,
return res;
}
-static int __init do_loader_command (volatile loader_block * lb,
+static int __devinit do_loader_command (volatile loader_block * lb,
const amb_dev * dev, loader_command cmd) {
unsigned long timeout;
// dump_loader_block (lb);
wr_mem (dev, offsetof(amb_mem, doorbell), virt_to_bus (lb) & ~onegigmask);
- timeout = command_timeouts[cmd] * HZ/100;
+ timeout = command_timeouts[cmd] * 10;
while (!lb->result || lb->result == cpu_to_be32 (COMMAND_IN_PROGRESS))
if (timeout) {
- set_current_state(TASK_UNINTERRUPTIBLE);
- timeout = schedule_timeout (timeout);
+ timeout = msleep_interruptible(timeout);
} else {
PRINTD (DBG_LOAD|DBG_ERR, "command %d timed out", cmd);
dump_registers (dev);
if (cmd == adapter_start) {
// wait for start command to acknowledge...
- timeout = HZ/10;
+ timeout = 100;
while (rd_plain (dev, offsetof(amb_mem, doorbell)))
if (timeout) {
- timeout = schedule_timeout (timeout);
+ timeout = msleep_interruptible(timeout);
} else {
PRINTD (DBG_LOAD|DBG_ERR, "start command did not clear doorbell, res=%08x",
be32_to_cpu (lb->result));
/* loader: determine loader version */
-static int __init get_loader_version (loader_block * lb,
+static int __devinit get_loader_version (loader_block * lb,
const amb_dev * dev, u32 * version) {
int res;
/* loader: write memory data blocks */
-static int __init loader_write (loader_block * lb,
+static int __devinit loader_write (loader_block * lb,
const amb_dev * dev, const u32 * data,
u32 address, unsigned int count) {
unsigned int i;
/* loader: verify memory data blocks */
-static int __init loader_verify (loader_block * lb,
+static int __devinit loader_verify (loader_block * lb,
const amb_dev * dev, const u32 * data,
u32 address, unsigned int count) {
unsigned int i;
/* loader: start microcode */
-static int __init loader_start (loader_block * lb,
+static int __devinit loader_start (loader_block * lb,
const amb_dev * dev, u32 address) {
PRINTD (DBG_FLOW|DBG_LOAD, "loader_start");
if (diags) {
unsigned long timeout;
// 4.2 second wait
- timeout = HZ*42/10;
- while (timeout) {
- set_current_state(TASK_UNINTERRUPTIBLE);
- timeout = schedule_timeout (timeout);
- }
+ msleep(4200);
// half second time-out
- timeout = HZ/2;
+ timeout = 500;
while (!rd_plain (dev, offsetof(amb_mem, mb.loader.ready)))
if (timeout) {
- set_current_state(TASK_UNINTERRUPTIBLE);
- timeout = schedule_timeout (timeout);
+ timeout = msleep_interruptible(timeout);
} else {
PRINTD (DBG_LOAD|DBG_ERR, "reset timed out");
return -ETIMEDOUT;
/********** transfer and start the microcode **********/
-static int __init ucode_init (loader_block * lb, amb_dev * dev) {
+static int __devinit ucode_init (loader_block * lb, amb_dev * dev) {
unsigned int i = 0;
unsigned int total = 0;
const u32 * pointer = ucode_data;
}
i += 1;
}
- if (*pointer == 0xdeadbeef) {
+ if (*pointer == ATM_POISON) {
return loader_start (lb, dev, ucode_start);
} else {
// cast needed as there is no %? for pointer differnces
/********** give adapter parameters **********/
-static inline u32 bus_addr(void * addr) {
+static inline __be32 bus_addr(void * addr) {
return cpu_to_be32 (virt_to_bus (addr));
}
-static int __init amb_talk (amb_dev * dev) {
+static int __devinit amb_talk (amb_dev * dev) {
adap_talk_block a;
unsigned char pool;
unsigned long timeout;
wr_mem (dev, offsetof(amb_mem, doorbell), virt_to_bus (&a));
// 2.2 second wait (must not touch doorbell during 2 second DMA test)
- timeout = HZ*22/10;
- while (timeout)
- timeout = schedule_timeout (timeout);
+ msleep(2200);
// give the adapter another half second?
- timeout = HZ/2;
+ timeout = 500;
while (rd_plain (dev, offsetof(amb_mem, doorbell)))
if (timeout) {
- timeout = schedule_timeout (timeout);
+ timeout = msleep_interruptible(timeout);
} else {
PRINTD (DBG_INIT|DBG_ERR, "adapter init timed out");
return -ETIMEDOUT;
}
// get microcode version
-static void __init amb_ucode_version (amb_dev * dev) {
+static void __devinit amb_ucode_version (amb_dev * dev) {
u32 major;
u32 minor;
command cmd;
}
// swap bits within byte to get Ethernet ordering
-u8 bit_swap (u8 byte)
+static u8 bit_swap (u8 byte)
{
const u8 swap[] = {
0x0, 0x8, 0x4, 0xc,
}
// get end station address
-static void __init amb_esi (amb_dev * dev, u8 * esi) {
+static void __devinit amb_esi (amb_dev * dev, u8 * esi) {
u32 lower4;
u16 upper2;
command cmd;
return;
}
-static int __init amb_init (amb_dev * dev)
+static int __devinit amb_init (amb_dev * dev)
{
loader_block lb;
spin_lock_init (&dev->rxq[pool].lock);
}
-static int setup_pci_dev(struct pci_dev *pci_dev)
+static void setup_pci_dev(struct pci_dev *pci_dev)
{
unsigned char lat;
- int ret;
// enable bus master accesses
pci_set_master(pci_dev);
-
- ret = pci_enable_device(pci_dev);
- if (ret < 0)
- goto out;
// frobnicate latency (upwards, usually)
pci_read_config_byte (pci_dev, PCI_LATENCY_TIMER, &lat);
lat, pci_lat);
pci_write_config_byte(pci_dev, PCI_LATENCY_TIMER, pci_lat);
}
-out:
- return ret;
}
static int __devinit amb_probe(struct pci_dev *pci_dev, const struct pci_device_id *pci_ent)
{
amb_dev * dev;
int err;
+ unsigned int irq;
+
+ err = pci_enable_device(pci_dev);
+ if (err < 0) {
+ PRINTK (KERN_ERR, "skipped broken (PLX rev 2) card");
+ goto out;
+ }
// read resources from PCI configuration space
- unsigned int irq = pci_dev->irq;
+ irq = pci_dev->irq;
if (pci_dev->device == PCI_DEVICE_ID_MADGE_AMBASSADOR_BAD) {
PRINTK (KERN_ERR, "skipped broken (PLX rev 2) card");
err = -EINVAL;
- goto out;
+ goto out_disable;
}
PRINTD (DBG_INFO, "found Madge ATM adapter (amb) at"
- " IO %lx, IRQ %u, MEM %p", pci_resource_start(pci_dev, 1),
+ " IO %llx, IRQ %u, MEM %p",
+ (unsigned long long)pci_resource_start(pci_dev, 1),
irq, bus_to_virt(pci_resource_start(pci_dev, 0)));
// check IO region
err = pci_request_region(pci_dev, 1, DEV_LABEL);
if (err < 0) {
PRINTK (KERN_ERR, "IO range already in use!");
- goto out;
+ goto out_disable;
}
dev = kmalloc (sizeof(amb_dev), GFP_KERNEL);
goto out_free;
}
- err = setup_pci_dev(pci_dev);
- if (err < 0)
- goto out_reset;
+ setup_pci_dev(pci_dev);
// grab (but share) IRQ and install handler
- err = request_irq(irq, interrupt_handler, SA_SHIRQ, DEV_LABEL, dev);
+ err = request_irq(irq, interrupt_handler, IRQF_SHARED, DEV_LABEL, dev);
if (err < 0) {
PRINTK (KERN_ERR, "request IRQ failed!");
- goto out_disable;
+ goto out_reset;
}
dev->atm_dev = atm_dev_register (DEV_LABEL, &amb_ops, -1, NULL);
out_free_irq:
free_irq(irq, dev);
-out_disable:
- pci_disable_device(pci_dev);
out_reset:
amb_reset(dev, 0);
out_free:
kfree(dev);
out_release:
pci_release_region(pci_dev, 1);
+out_disable:
+ pci_disable_device(pci_dev);
goto out;
}
amb_check_args();
// get the juice
- return pci_module_init(&amb_driver);
+ return pci_register_driver(&amb_driver);
}
/********** module exit **********/