aboutsummaryrefslogtreecommitdiffstats
path: root/drivers/staging/xillybus/xillybus_core.c
diff options
context:
space:
mode:
Diffstat (limited to '')
-rw-r--r--drivers/staging/xillybus/xillybus_core.c541
1 files changed, 199 insertions, 342 deletions
diff --git a/drivers/staging/xillybus/xillybus_core.c b/drivers/staging/xillybus/xillybus_core.c
index fe8f9d28b03b..0214009f7513 100644
--- a/drivers/staging/xillybus/xillybus_core.c
+++ b/drivers/staging/xillybus/xillybus_core.c
@@ -44,14 +44,14 @@ MODULE_LICENSE("GPL v2");
#define XILLY_RX_TIMEOUT (10*HZ/1000)
#define XILLY_TIMEOUT (100*HZ/1000)
-#define fpga_msg_ctrl_reg 0x0002
-#define fpga_dma_control_reg 0x0008
-#define fpga_dma_bufno_reg 0x0009
-#define fpga_dma_bufaddr_lowaddr_reg 0x000a
-#define fpga_dma_bufaddr_highaddr_reg 0x000b
-#define fpga_buf_ctrl_reg 0x000c
-#define fpga_buf_offset_reg 0x000d
-#define fpga_endian_reg 0x0010
+#define fpga_msg_ctrl_reg 0x0008
+#define fpga_dma_control_reg 0x0020
+#define fpga_dma_bufno_reg 0x0024
+#define fpga_dma_bufaddr_lowaddr_reg 0x0028
+#define fpga_dma_bufaddr_highaddr_reg 0x002c
+#define fpga_buf_ctrl_reg 0x0030
+#define fpga_buf_offset_reg 0x0034
+#define fpga_endian_reg 0x0040
#define XILLYMSG_OPCODE_RELEASEBUF 1
#define XILLYMSG_OPCODE_QUIESCEACK 2
@@ -138,7 +138,6 @@ irqreturn_t xillybus_isr(int irq, void *data)
* guaranteed no interrupt will occur, but in theory, the cache
* lines may not be updated. So a memory barrier is issued.
*/
-
smp_rmb();
buf = ep->msgbuf_addr;
@@ -159,10 +158,10 @@ irqreturn_t xillybus_isr(int irq, void *data)
ep->msg_counter,
i/2);
- if (++ep->failed_messages > 10)
+ if (++ep->failed_messages > 10) {
dev_err(ep->dev,
"Lost sync with interrupt messages. Stopping.\n");
- else {
+ } else {
ep->ephw->hw_sync_sgl_for_device(
ep,
ep->msgbuf_dma_addr,
@@ -170,7 +169,7 @@ irqreturn_t xillybus_isr(int irq, void *data)
DMA_FROM_DEVICE);
iowrite32(0x01, /* Message NACK */
- &ep->registers[fpga_msg_ctrl_reg]);
+ ep->registers + fpga_msg_ctrl_reg);
}
return IRQ_HANDLED;
} else if (buf[i] & (1 << 22)) /* Last message */
@@ -267,6 +266,12 @@ irqreturn_t xillybus_isr(int irq, void *data)
break;
case XILLYMSG_OPCODE_FIFOEOF:
+ if ((msg_channel > ep->num_channels) ||
+ (msg_channel == 0) || (!msg_dir) ||
+ !ep->channels[msg_channel]->num_wr_buffers) {
+ malformed_message(ep, &buf[i]);
+ break;
+ }
channel = ep->channels[msg_channel];
spin_lock(&channel->wr_spinlock);
channel->wr_eof = msg_bufno;
@@ -299,7 +304,7 @@ irqreturn_t xillybus_isr(int irq, void *data)
ep->msg_counter = (ep->msg_counter + 1) & 0xf;
ep->failed_messages = 0;
- iowrite32(0x03, &ep->registers[fpga_msg_ctrl_reg]); /* Message ACK */
+ iowrite32(0x03, ep->registers + fpga_msg_ctrl_reg); /* Message ACK */
return IRQ_HANDLED;
}
@@ -311,108 +316,142 @@ EXPORT_SYMBOL(xillybus_isr);
* no locks are applied!
*/
-void xillybus_do_cleanup(struct xilly_cleanup *mem,
- struct xilly_endpoint *endpoint)
+static void xillybus_autoflush(struct work_struct *work);
+
+struct xilly_alloc_state {
+ void *salami;
+ int left_of_salami;
+ int nbuffer;
+ enum dma_data_direction direction;
+ u32 regdirection;
+};
+
+static int xilly_get_dma_buffers(struct xilly_endpoint *ep,
+ struct xilly_alloc_state *s,
+ struct xilly_buffer **buffers,
+ int bufnum, int bytebufsize)
{
- struct list_head *this, *next;
+ int i, rc;
+ dma_addr_t dma_addr;
+ struct device *dev = ep->dev;
+ struct xilly_buffer *this_buffer = NULL; /* Init to silence warning */
- list_for_each_safe(this, next, &mem->to_unmap) {
- struct xilly_dma *entry =
- list_entry(this, struct xilly_dma, node);
+ if (buffers) { /* Not the message buffer */
+ this_buffer = devm_kzalloc(
+ dev, bufnum * sizeof(struct xilly_buffer),
+ GFP_KERNEL);
- endpoint->ephw->unmap_single(entry);
- kfree(entry);
+ if (!this_buffer)
+ return -ENOMEM;
}
- INIT_LIST_HEAD(&mem->to_unmap);
-
- list_for_each_safe(this, next, &mem->to_kfree)
- kfree(this);
+ for (i = 0; i < bufnum; i++) {
+ /*
+ * Buffers are expected in descending size order, so there
+ * is either enough space for this buffer or none at all.
+ */
- INIT_LIST_HEAD(&mem->to_kfree);
+ if ((s->left_of_salami < bytebufsize) &&
+ (s->left_of_salami > 0)) {
+ dev_err(ep->dev,
+ "Corrupt buffer allocation in IDT. Aborting.\n");
+ return -ENODEV;
+ }
- list_for_each_safe(this, next, &mem->to_pagefree) {
- struct xilly_page *entry =
- list_entry(this, struct xilly_page, node);
+ if (s->left_of_salami == 0) {
+ int allocorder, allocsize;
- free_pages(entry->addr, entry->order);
- kfree(entry);
- }
- INIT_LIST_HEAD(&mem->to_pagefree);
-}
-EXPORT_SYMBOL(xillybus_do_cleanup);
+ allocsize = PAGE_SIZE;
+ allocorder = 0;
+ while (bytebufsize > allocsize) {
+ allocsize *= 2;
+ allocorder++;
+ }
-static void *xilly_malloc(struct xilly_cleanup *mem, size_t size)
-{
- void *ptr;
+ s->salami = (void *) devm_get_free_pages(
+ dev,
+ GFP_KERNEL | __GFP_DMA32 | __GFP_ZERO,
+ allocorder);
- ptr = kzalloc(sizeof(struct list_head) + size, GFP_KERNEL);
+ if (!s->salami)
+ return -ENOMEM;
+ s->left_of_salami = allocsize;
+ }
- if (!ptr)
- return ptr;
+ rc = ep->ephw->map_single(ep, s->salami,
+ bytebufsize, s->direction,
+ &dma_addr);
- list_add_tail((struct list_head *) ptr, &mem->to_kfree);
+ if (rc)
+ return rc;
- return ptr + sizeof(struct list_head);
-}
+ iowrite32((u32) (dma_addr & 0xffffffff),
+ ep->registers + fpga_dma_bufaddr_lowaddr_reg);
+ iowrite32(((u32) ((((u64) dma_addr) >> 32) & 0xffffffff)),
+ ep->registers + fpga_dma_bufaddr_highaddr_reg);
+ mmiowb();
-static unsigned long xilly_pagealloc(struct xilly_cleanup *mem,
- unsigned long order)
-{
- unsigned long addr;
- struct xilly_page *this;
+ if (buffers) { /* Not the message buffer */
+ this_buffer->addr = s->salami;
+ this_buffer->dma_addr = dma_addr;
+ buffers[i] = this_buffer++;
- this = kmalloc(sizeof(struct xilly_page), GFP_KERNEL);
- if (!this)
- return 0;
+ iowrite32(s->regdirection | s->nbuffer++,
+ ep->registers + fpga_dma_bufno_reg);
+ } else {
+ ep->msgbuf_addr = s->salami;
+ ep->msgbuf_dma_addr = dma_addr;
+ ep->msg_buf_size = bytebufsize;
- addr = __get_free_pages(GFP_KERNEL | __GFP_DMA32 | __GFP_ZERO, order);
+ iowrite32(s->regdirection,
+ ep->registers + fpga_dma_bufno_reg);
+ }
- if (!addr) {
- kfree(this);
- return 0;
+ s->left_of_salami -= bytebufsize;
+ s->salami += bytebufsize;
}
-
- this->addr = addr;
- this->order = order;
-
- list_add_tail(&this->node, &mem->to_pagefree);
-
- return addr;
+ return 0; /* Success */
}
-
-static void xillybus_autoflush(struct work_struct *work);
-
static int xilly_setupchannels(struct xilly_endpoint *ep,
- struct xilly_cleanup *mem,
unsigned char *chandesc,
int entries
)
{
- int i, entry, wr_nbuffer, rd_nbuffer;
+ struct device *dev = ep->dev;
+ int i, entry, rc;
struct xilly_channel *channel;
int channelnum, bufnum, bufsize, format, is_writebuf;
int bytebufsize;
int synchronous, allowpartial, exclusive_open, seekable;
int supports_nonempty;
- void *wr_salami = NULL;
- void *rd_salami = NULL;
- int left_of_wr_salami = 0;
- int left_of_rd_salami = 0;
- dma_addr_t dma_addr;
int msg_buf_done = 0;
- struct xilly_buffer *this_buffer = NULL; /* Init to silence warning */
-
- channel = xilly_malloc(mem, ep->num_channels *
- sizeof(struct xilly_channel));
+ struct xilly_alloc_state rd_alloc = {
+ .salami = NULL,
+ .left_of_salami = 0,
+ .nbuffer = 1,
+ .direction = DMA_TO_DEVICE,
+ .regdirection = 0,
+ };
+
+ struct xilly_alloc_state wr_alloc = {
+ .salami = NULL,
+ .left_of_salami = 0,
+ .nbuffer = 1,
+ .direction = DMA_FROM_DEVICE,
+ .regdirection = 0x80000000,
+ };
+
+ channel = devm_kzalloc(dev, ep->num_channels *
+ sizeof(struct xilly_channel), GFP_KERNEL);
if (!channel)
goto memfail;
- ep->channels = xilly_malloc(mem, (ep->num_channels + 1) *
- sizeof(struct xilly_channel *));
+ ep->channels = devm_kzalloc(dev, (ep->num_channels + 1) *
+ sizeof(struct xilly_channel *),
+ GFP_KERNEL);
if (!ep->channels)
goto memfail;
@@ -457,17 +496,9 @@ static int xilly_setupchannels(struct xilly_endpoint *ep,
ep->channels[i] = channel++;
}
- /*
- * The DMA buffer address update is atomic on the FPGA, so even if
- * it was in the middle of sending messages to some buffer, changing
- * the address is safe, since the data will go to either of the
- * buffers. Not that this situation should occur at all anyhow.
- */
-
- wr_nbuffer = 1;
- rd_nbuffer = 1; /* Buffer zero isn't used at all */
-
for (entry = 0; entry < entries; entry++, chandesc += 4) {
+ struct xilly_buffer **buffers = NULL;
+
is_writebuf = chandesc[0] & 0x01;
channelnum = (chandesc[0] >> 1) | ((chandesc[1] & 0x0f) << 7);
format = (chandesc[1] >> 4) & 0x03;
@@ -488,40 +519,35 @@ static int xilly_setupchannels(struct xilly_endpoint *ep,
channel = ep->channels[channelnum]; /* NULL for msg channel */
- bytebufsize = bufsize << 2; /* Overwritten just below */
-
- if (!is_writebuf) {
- channel->num_rd_buffers = bufnum;
+ if (!is_writebuf || channelnum > 0) {
channel->log2_element_size = ((format > 2) ?
2 : format);
+
bytebufsize = channel->rd_buf_size = bufsize *
(1 << channel->log2_element_size);
- channel->rd_allow_partial = allowpartial;
- channel->rd_synchronous = synchronous;
- channel->rd_exclusive_open = exclusive_open;
- channel->seekable = seekable;
-
- channel->rd_buffers = xilly_malloc(
- mem,
- bufnum * sizeof(struct xilly_buffer *));
- if (!channel->rd_buffers)
- goto memfail;
-
- this_buffer = xilly_malloc(
- mem,
- bufnum * sizeof(struct xilly_buffer));
+ buffers = devm_kzalloc(dev,
+ bufnum * sizeof(struct xilly_buffer *),
+ GFP_KERNEL);
- if (!this_buffer)
+ if (!buffers)
goto memfail;
+ } else {
+ bytebufsize = bufsize << 2;
}
- else if (channelnum > 0) {
+ if (!is_writebuf) {
+ channel->num_rd_buffers = bufnum;
+ channel->rd_allow_partial = allowpartial;
+ channel->rd_synchronous = synchronous;
+ channel->rd_exclusive_open = exclusive_open;
+ channel->seekable = seekable;
+
+ channel->rd_buffers = buffers;
+ rc = xilly_get_dma_buffers(ep, &rd_alloc, buffers,
+ bufnum, bytebufsize);
+ } else if (channelnum > 0) {
channel->num_wr_buffers = bufnum;
- channel->log2_element_size = ((format > 2) ?
- 2 : format);
- bytebufsize = channel->wr_buf_size = bufsize *
- (1 << channel->log2_element_size);
channel->seekable = seekable;
channel->wr_supports_nonempty = supports_nonempty;
@@ -530,172 +556,17 @@ static int xilly_setupchannels(struct xilly_endpoint *ep,
channel->wr_synchronous = synchronous;
channel->wr_exclusive_open = exclusive_open;
- channel->wr_buffers = xilly_malloc(
- mem,
- bufnum * sizeof(struct xilly_buffer *));
-
- if (!channel->wr_buffers)
- goto memfail;
-
- this_buffer = xilly_malloc(
- mem,
- bufnum * sizeof(struct xilly_buffer));
-
- if (!this_buffer)
- goto memfail;
+ channel->wr_buffers = buffers;
+ rc = xilly_get_dma_buffers(ep, &wr_alloc, buffers,
+ bufnum, bytebufsize);
+ } else {
+ rc = xilly_get_dma_buffers(ep, &wr_alloc, NULL,
+ bufnum, bytebufsize);
+ msg_buf_done++;
}
- /*
- * Although daunting, we cut the chunks for read buffers
- * from a different salami than the write buffers',
- * possibly improving performance.
- */
-
- if (is_writebuf)
- for (i = 0; i < bufnum; i++) {
- /*
- * Buffers are expected in descending
- * byte-size order, so there is either
- * enough for this buffer or none at all.
- */
- if ((left_of_wr_salami < bytebufsize) &&
- (left_of_wr_salami > 0)) {
- dev_err(ep->dev,
- "Corrupt buffer allocation in IDT. Aborting.\n");
- return -ENODEV;
- }
-
- if (left_of_wr_salami == 0) {
- int allocorder, allocsize;
-
- allocsize = PAGE_SIZE;
- allocorder = 0;
- while (bytebufsize > allocsize) {
- allocsize *= 2;
- allocorder++;
- }
-
- wr_salami = (void *)
- xilly_pagealloc(mem,
- allocorder);
- if (!wr_salami)
- goto memfail;
- left_of_wr_salami = allocsize;
- }
-
- dma_addr = ep->ephw->map_single(
- mem,
- ep,
- wr_salami,
- bytebufsize,
- DMA_FROM_DEVICE);
-
- if (!dma_addr)
- goto dmafail;
-
- iowrite32(
- (u32) (dma_addr & 0xffffffff),
- &ep->registers[
- fpga_dma_bufaddr_lowaddr_reg]
- );
- iowrite32(
- ((u32) ((((u64) dma_addr) >> 32)
- & 0xffffffff)),
- &ep->registers[
- fpga_dma_bufaddr_highaddr_reg]
- );
- mmiowb();
-
- if (channelnum > 0) {
- this_buffer->addr = wr_salami;
- this_buffer->dma_addr = dma_addr;
- channel->wr_buffers[i] = this_buffer++;
-
- iowrite32(
- 0x80000000 | wr_nbuffer++,
- &ep->registers[
- fpga_dma_bufno_reg]);
- } else {
- ep->msgbuf_addr = wr_salami;
- ep->msgbuf_dma_addr = dma_addr;
- ep->msg_buf_size = bytebufsize;
- msg_buf_done++;
-
- iowrite32(
- 0x80000000, &ep->registers[
- fpga_dma_bufno_reg]);
- }
-
- left_of_wr_salami -= bytebufsize;
- wr_salami += bytebufsize;
- }
- else /* Read buffers */
- for (i = 0; i < bufnum; i++) {
- /*
- * Buffers are expected in descending
- * byte-size order, so there is either
- * enough for this buffer or none at all.
- */
- if ((left_of_rd_salami < bytebufsize) &&
- (left_of_rd_salami > 0)) {
- dev_err(ep->dev,
- "Corrupt buffer allocation in IDT. Aborting.\n");
- return -ENODEV;
- }
-
- if (left_of_rd_salami == 0) {
- int allocorder, allocsize;
-
- allocsize = PAGE_SIZE;
- allocorder = 0;
- while (bytebufsize > allocsize) {
- allocsize *= 2;
- allocorder++;
- }
-
- rd_salami = (void *)
- xilly_pagealloc(
- mem,
- allocorder);
-
- if (!rd_salami)
- goto memfail;
- left_of_rd_salami = allocsize;
- }
-
- dma_addr = ep->ephw->map_single(
- mem,
- ep,
- rd_salami,
- bytebufsize,
- DMA_TO_DEVICE);
-
- if (!dma_addr)
- goto dmafail;
-
- iowrite32(
- (u32) (dma_addr & 0xffffffff),
- &ep->registers[
- fpga_dma_bufaddr_lowaddr_reg]
- );
- iowrite32(
- ((u32) ((((u64) dma_addr) >> 32)
- & 0xffffffff)),
- &ep->registers[
- fpga_dma_bufaddr_highaddr_reg]
- );
- mmiowb();
-
- this_buffer->addr = rd_salami;
- this_buffer->dma_addr = dma_addr;
- channel->rd_buffers[i] = this_buffer++;
-
- iowrite32(rd_nbuffer++,
- &ep->registers[fpga_dma_bufno_reg]);
-
- left_of_rd_salami -= bytebufsize;
- rd_salami += bytebufsize;
- }
+ if (rc)
+ goto memfail;
}
if (!msg_buf_done) {
@@ -703,15 +574,11 @@ static int xilly_setupchannels(struct xilly_endpoint *ep,
"Corrupt IDT: No message buffer. Aborting.\n");
return -ENODEV;
}
-
return 0;
memfail:
dev_err(ep->dev,
- "Failed to allocate write buffer memory. Aborting.\n");
- return -ENOMEM;
-dmafail:
- dev_err(ep->dev, "Failed to map DMA memory!. Aborting.\n");
+ "Failed to assign DMA buffer memory. Aborting.\n");
return -ENOMEM;
}
@@ -742,8 +609,8 @@ static void xilly_scan_idt(struct xilly_endpoint *endpoint,
"IDT device name list overflow. Aborting.\n");
idt_handle->chandesc = NULL;
return;
- } else
- idt_handle->chandesc = scan;
+ }
+ idt_handle->chandesc = scan;
len = endpoint->idtlen - (3 + ((int) (scan - idt)));
@@ -772,7 +639,7 @@ static int xilly_obtain_idt(struct xilly_endpoint *endpoint)
iowrite32(1 |
(3 << 24), /* Opcode 3 for channel 0 = Send IDT */
- &endpoint->registers[fpga_buf_ctrl_reg]);
+ endpoint->registers + fpga_buf_ctrl_reg);
mmiowb(); /* Just to appear safe */
wait_event_interruptible_timeout(channel->wr_wait,
@@ -854,6 +721,7 @@ static ssize_t xillybus_read(struct file *filp, char __user *userbuf,
while (1) { /* Note that we may drop mutex within this loop */
int bytes_to_do = count - bytes_done;
+
spin_lock_irqsave(&channel->wr_spinlock, flags);
empty = channel->wr_empty;
@@ -944,8 +812,8 @@ static ssize_t xillybus_read(struct file *filp, char __user *userbuf,
iowrite32(1 | (channel->chan_num << 1)
| (bufidx << 12),
- &channel->endpoint->registers[
- fpga_buf_ctrl_reg]);
+ channel->endpoint->registers +
+ fpga_buf_ctrl_reg);
mmiowb(); /* Just to appear safe */
}
@@ -1031,15 +899,15 @@ static ssize_t xillybus_read(struct file *filp, char __user *userbuf,
mutex_lock(&channel->endpoint->register_mutex);
iowrite32(offsetlimit,
- &channel->endpoint->registers[
- fpga_buf_offset_reg]);
+ channel->endpoint->registers +
+ fpga_buf_offset_reg);
mmiowb();
iowrite32(1 | (channel->chan_num << 1) |
(2 << 24) | /* 2 = offset limit */
(waiting_bufidx << 12),
- &channel->endpoint->registers[
- fpga_buf_ctrl_reg]);
+ channel->endpoint->registers +
+ fpga_buf_ctrl_reg);
mmiowb(); /* Just to appear safe */
@@ -1131,8 +999,8 @@ desperate:
iowrite32(1 | (channel->chan_num << 1) |
(3 << 24) | /* Opcode 3, flush it all! */
(waiting_bufidx << 12),
- &channel->endpoint->registers[
- fpga_buf_ctrl_reg]);
+ channel->endpoint->registers +
+ fpga_buf_ctrl_reg);
mmiowb(); /* Just to appear safe */
}
@@ -1244,13 +1112,13 @@ static int xillybus_myflush(struct xilly_channel *channel, long timeout)
mutex_lock(&channel->endpoint->register_mutex);
iowrite32(end_offset_plus1 - 1,
- &channel->endpoint->registers[fpga_buf_offset_reg]);
+ channel->endpoint->registers + fpga_buf_offset_reg);
mmiowb();
iowrite32((channel->chan_num << 1) | /* Channel ID */
(2 << 24) | /* Opcode 2, submit buffer */
(bufidx << 12),
- &channel->endpoint->registers[fpga_buf_ctrl_reg]);
+ channel->endpoint->registers + fpga_buf_ctrl_reg);
mmiowb(); /* Just to appear safe */
mutex_unlock(&channel->endpoint->register_mutex);
@@ -1494,14 +1362,14 @@ static ssize_t xillybus_write(struct file *filp, const char __user *userbuf,
mutex_lock(&channel->endpoint->register_mutex);
iowrite32(end_offset_plus1 - 1,
- &channel->endpoint->registers[
- fpga_buf_offset_reg]);
+ channel->endpoint->registers +
+ fpga_buf_offset_reg);
mmiowb();
iowrite32((channel->chan_num << 1) |
(2 << 24) | /* 2 = submit buffer */
(bufidx << 12),
- &channel->endpoint->registers[
- fpga_buf_ctrl_reg]);
+ channel->endpoint->registers +
+ fpga_buf_ctrl_reg);
mmiowb(); /* Just to appear safe */
mutex_unlock(&channel->endpoint->
@@ -1696,8 +1564,8 @@ static int xillybus_open(struct inode *inode, struct file *filp)
iowrite32(1 | (channel->chan_num << 1) |
(4 << 24) | /* Opcode 4, open channel */
((channel->wr_synchronous & 1) << 23),
- &channel->endpoint->registers[
- fpga_buf_ctrl_reg]);
+ channel->endpoint->registers +
+ fpga_buf_ctrl_reg);
mmiowb(); /* Just to appear safe */
}
@@ -1718,8 +1586,8 @@ static int xillybus_open(struct inode *inode, struct file *filp)
iowrite32((channel->chan_num << 1) |
(4 << 24), /* Opcode 4, open channel */
- &channel->endpoint->registers[
- fpga_buf_ctrl_reg]);
+ channel->endpoint->registers +
+ fpga_buf_ctrl_reg);
mmiowb(); /* Just to appear safe */
}
@@ -1771,8 +1639,8 @@ static int xillybus_release(struct inode *inode, struct file *filp)
iowrite32((channel->chan_num << 1) | /* Channel ID */
(5 << 24), /* Opcode 5, close channel */
- &channel->endpoint->registers[
- fpga_buf_ctrl_reg]);
+ channel->endpoint->registers +
+ fpga_buf_ctrl_reg);
mmiowb(); /* Just to appear safe */
}
mutex_unlock(&channel->rd_mutex);
@@ -1792,8 +1660,8 @@ static int xillybus_release(struct inode *inode, struct file *filp)
iowrite32(1 | (channel->chan_num << 1) |
(5 << 24), /* Opcode 5, close channel */
- &channel->endpoint->registers[
- fpga_buf_ctrl_reg]);
+ channel->endpoint->registers +
+ fpga_buf_ctrl_reg);
mmiowb(); /* Just to appear safe */
/*
@@ -1898,11 +1766,11 @@ static loff_t xillybus_llseek(struct file *filp, loff_t offset, int whence)
mutex_lock(&channel->endpoint->register_mutex);
iowrite32(pos >> channel->log2_element_size,
- &channel->endpoint->registers[fpga_buf_offset_reg]);
+ channel->endpoint->registers + fpga_buf_offset_reg);
mmiowb();
iowrite32((channel->chan_num << 1) |
(6 << 24), /* Opcode 6, set address */
- &channel->endpoint->registers[fpga_buf_ctrl_reg]);
+ channel->endpoint->registers + fpga_buf_ctrl_reg);
mmiowb(); /* Just to appear safe */
mutex_unlock(&channel->endpoint->register_mutex);
@@ -2095,17 +1963,12 @@ struct xilly_endpoint *xillybus_init_endpoint(struct pci_dev *pdev,
struct xilly_endpoint *endpoint;
endpoint = devm_kzalloc(dev, sizeof(*endpoint), GFP_KERNEL);
- if (!endpoint) {
- dev_err(dev, "Failed to allocate memory. Aborting.\n");
+ if (!endpoint)
return NULL;
- }
endpoint->pdev = pdev;
endpoint->dev = dev;
endpoint->ephw = ephw;
- INIT_LIST_HEAD(&endpoint->cleanup.to_kfree);
- INIT_LIST_HEAD(&endpoint->cleanup.to_pagefree);
- INIT_LIST_HEAD(&endpoint->cleanup.to_unmap);
endpoint->msg_counter = 0x0b;
endpoint->failed_messages = 0;
endpoint->fatal_error = 0;
@@ -2122,7 +1985,7 @@ static int xilly_quiesce(struct xilly_endpoint *endpoint)
endpoint->idtlen = -1;
wmb(); /* Make sure idtlen is set before sending command */
iowrite32((u32) (endpoint->dma_using_dac & 0x0001),
- &endpoint->registers[fpga_dma_control_reg]);
+ endpoint->registers + fpga_dma_control_reg);
mmiowb();
wait_event_interruptible_timeout(endpoint->ep_wait,
@@ -2131,7 +1994,7 @@ static int xilly_quiesce(struct xilly_endpoint *endpoint)
if (endpoint->idtlen < 0) {
dev_err(endpoint->dev,
- "Failed to quiesce the device on exit. Quitting while leaving a mess.\n");
+ "Failed to quiesce the device on exit.\n");
return -ENODEV;
}
return 0; /* Success */
@@ -2141,8 +2004,9 @@ int xillybus_endpoint_discovery(struct xilly_endpoint *endpoint)
{
int rc = 0;
- struct xilly_cleanup tmpmem;
+ void *bootstrap_resources;
int idtbuffersize = (1 << PAGE_SHIFT);
+ struct device *dev = endpoint->dev;
/*
* The bogus IDT is used during bootstrap for allocating the initial
@@ -2155,30 +2019,30 @@ int xillybus_endpoint_discovery(struct xilly_endpoint *endpoint)
3, 192, PAGE_SHIFT, 0 };
struct xilly_idt_handle idt_handle;
- INIT_LIST_HEAD(&tmpmem.to_kfree);
- INIT_LIST_HEAD(&tmpmem.to_pagefree);
- INIT_LIST_HEAD(&tmpmem.to_unmap);
-
/*
* Writing the value 0x00000001 to Endianness register signals which
* endianness this processor is using, so the FPGA can swap words as
* necessary.
*/
- iowrite32(1, &endpoint->registers[fpga_endian_reg]);
+ iowrite32(1, endpoint->registers + fpga_endian_reg);
mmiowb(); /* Writes below are affected by the one above. */
/* Bootstrap phase I: Allocate temporary message buffer */
+ bootstrap_resources = devres_open_group(dev, NULL, GFP_KERNEL);
+ if (!bootstrap_resources)
+ return -ENOMEM;
+
endpoint->num_channels = 0;
- rc = xilly_setupchannels(endpoint, &tmpmem, bogus_idt, 1);
+ rc = xilly_setupchannels(endpoint, bogus_idt, 1);
if (rc)
- goto failed_buffers;
+ return rc;
/* Clear the message subsystem (and counter in particular) */
- iowrite32(0x04, &endpoint->registers[fpga_msg_ctrl_reg]);
+ iowrite32(0x04, endpoint->registers + fpga_msg_ctrl_reg);
mmiowb();
endpoint->idtlen = -1;
@@ -2190,7 +2054,7 @@ int xillybus_endpoint_discovery(struct xilly_endpoint *endpoint)
* buffer size.
*/
iowrite32((u32) (endpoint->dma_using_dac & 0x0001),
- &endpoint->registers[fpga_dma_control_reg]);
+ endpoint->registers + fpga_dma_control_reg);
mmiowb();
wait_event_interruptible_timeout(endpoint->ep_wait,
@@ -2199,13 +2063,12 @@ int xillybus_endpoint_discovery(struct xilly_endpoint *endpoint)
if (endpoint->idtlen < 0) {
dev_err(endpoint->dev, "No response from FPGA. Aborting.\n");
- rc = -ENODEV;
- goto failed_quiesce;
+ return -ENODEV;
}
/* Enable DMA */
iowrite32((u32) (0x0002 | (endpoint->dma_using_dac & 0x0001)),
- &endpoint->registers[fpga_dma_control_reg]);
+ endpoint->registers + fpga_dma_control_reg);
mmiowb();
/* Bootstrap phase II: Allocate buffer for IDT and obtain it */
@@ -2216,7 +2079,7 @@ int xillybus_endpoint_discovery(struct xilly_endpoint *endpoint)
endpoint->num_channels = 1;
- rc = xilly_setupchannels(endpoint, &tmpmem, bogus_idt, 2);
+ rc = xilly_setupchannels(endpoint, bogus_idt, 2);
if (rc)
goto failed_idt;
@@ -2234,10 +2097,12 @@ int xillybus_endpoint_discovery(struct xilly_endpoint *endpoint)
rc = -ENODEV;
goto failed_idt;
}
+
+ devres_close_group(dev, bootstrap_resources);
+
/* Bootstrap phase III: Allocate buffers according to IDT */
rc = xilly_setupchannels(endpoint,
- &endpoint->cleanup,
idt_handle.chandesc,
idt_handle.entries);
@@ -2260,7 +2125,7 @@ int xillybus_endpoint_discovery(struct xilly_endpoint *endpoint)
if (rc)
goto failed_chrdevs;
- xillybus_do_cleanup(&tmpmem, endpoint);
+ devres_release_group(dev, bootstrap_resources);
return 0;
@@ -2270,16 +2135,8 @@ failed_chrdevs:
mutex_unlock(&ep_list_lock);
failed_idt:
- /* Quiesce the device. Now it's serious to do it */
- rc = xilly_quiesce(endpoint);
-
- if (rc)
- return rc; /* FPGA may still DMA, so no release */
-
+ xilly_quiesce(endpoint);
flush_workqueue(xillybus_wq);
-failed_quiesce:
-failed_buffers:
- xillybus_do_cleanup(&tmpmem, endpoint);
return rc;
}