Commit a7e8ddd8 authored by Linus Torvalds's avatar Linus Torvalds

Merge git://git.kernel.org/pub/scm/linux/kernel/git/davem/sparc

Pull sparc update from David Miller:
 "Not a lot of stuff this time around, mostly bug fixing:

   - Fix alignment of 32-bit crosscall datastructure on Leon, from
     Andreas Larsson.

   - Several fixes to the virtual disk driver on sparc64 by Dwight
     Engen, including handling resets of the service domain properly"

* git://git.kernel.org/pub/scm/linux/kernel/git/davem/sparc:
  sunvdc: reconnect ldc after vds service domain restarts
  sparc/ldc: create separate ldc_unbind from ldc_free
  vio: create routines for inc,dec vio dring indexes
  sunvdc: fix module unload/reload
  sparc32, leon: Align ccall_info to prevent unaligned traps on crosscall
parents ad8f723a 76e74bbe
......@@ -61,6 +61,7 @@ void ldc_free(struct ldc_channel *lp);
/* Register TX and RX queues of the link with the hypervisor. */
int ldc_bind(struct ldc_channel *lp);
void ldc_unbind(struct ldc_channel *lp);
/* For non-RAW protocols we need to complete a handshake before
* communication can proceed. ldc_connect() does that, if the
......
......@@ -300,6 +300,21 @@ static inline u32 vio_dring_avail(struct vio_dring_state *dr,
((dr->prod - dr->cons) & (ring_size - 1)) - 1);
}
static inline u32 vio_dring_next(struct vio_dring_state *dr, u32 index)
{
if (++index == dr->num_entries)
index = 0;
return index;
}
static inline u32 vio_dring_prev(struct vio_dring_state *dr, u32 index)
{
if (index == 0)
return dr->num_entries - 1;
else
return index - 1;
}
#define VIO_MAX_TYPE_LEN 32
#define VIO_MAX_COMPAT_LEN 64
......
......@@ -1222,11 +1222,12 @@ struct ldc_channel *ldc_alloc(unsigned long id,
}
EXPORT_SYMBOL(ldc_alloc);
void ldc_free(struct ldc_channel *lp)
void ldc_unbind(struct ldc_channel *lp)
{
if (lp->flags & LDC_FLAG_REGISTERED_IRQS) {
free_irq(lp->cfg.rx_irq, lp);
free_irq(lp->cfg.tx_irq, lp);
lp->flags &= ~LDC_FLAG_REGISTERED_IRQS;
}
if (lp->flags & LDC_FLAG_REGISTERED_QUEUES) {
......@@ -1240,10 +1241,15 @@ void ldc_free(struct ldc_channel *lp)
lp->flags &= ~LDC_FLAG_ALLOCED_QUEUES;
}
hlist_del(&lp->list);
ldc_set_state(lp, LDC_STATE_INIT);
}
EXPORT_SYMBOL(ldc_unbind);
void ldc_free(struct ldc_channel *lp)
{
ldc_unbind(lp);
hlist_del(&lp->list);
kfree(lp->mssbuf);
ldc_iommu_release(lp);
kfree(lp);
......
......@@ -368,7 +368,7 @@ static struct smp_funcall {
unsigned long arg5;
unsigned long processors_in[NR_CPUS]; /* Set when ipi entered. */
unsigned long processors_out[NR_CPUS]; /* Set when ipi exited. */
} ccall_info;
} ccall_info __attribute__((aligned(8)));
static DEFINE_SPINLOCK(cross_call_lock);
......
This diff is collapsed.
......@@ -466,23 +466,6 @@ static int vnet_send_ack(struct vnet_port *port, struct vio_dring_state *dr,
return err;
}
static u32 next_idx(u32 idx, struct vio_dring_state *dr)
{
if (++idx == dr->num_entries)
idx = 0;
return idx;
}
static u32 prev_idx(u32 idx, struct vio_dring_state *dr)
{
if (idx == 0)
idx = dr->num_entries - 1;
else
idx--;
return idx;
}
static struct vio_net_desc *get_rx_desc(struct vnet_port *port,
struct vio_dring_state *dr,
u32 index)
......@@ -556,7 +539,8 @@ static int vnet_walk_rx(struct vnet_port *port, struct vio_dring_state *dr,
int ack_start = -1, ack_end = -1;
bool send_ack = true;
end = (end == (u32) -1) ? prev_idx(start, dr) : next_idx(end, dr);
end = (end == (u32) -1) ? vio_dring_prev(dr, start)
: vio_dring_next(dr, end);
viodbg(DATA, "vnet_walk_rx start[%08x] end[%08x]\n", start, end);
......@@ -570,7 +554,7 @@ static int vnet_walk_rx(struct vnet_port *port, struct vio_dring_state *dr,
if (ack_start == -1)
ack_start = start;
ack_end = start;
start = next_idx(start, dr);
start = vio_dring_next(dr, start);
if (ack && start != end) {
err = vnet_send_ack(port, dr, ack_start, ack_end,
VIO_DRING_ACTIVE);
......@@ -584,7 +568,7 @@ static int vnet_walk_rx(struct vnet_port *port, struct vio_dring_state *dr,
}
}
if (unlikely(ack_start == -1))
ack_start = ack_end = prev_idx(start, dr);
ack_start = ack_end = vio_dring_prev(dr, start);
if (send_ack) {
port->napi_resume = false;
return vnet_send_ack(port, dr, ack_start, ack_end,
......@@ -633,7 +617,7 @@ static int idx_is_pending(struct vio_dring_state *dr, u32 end)
found = 1;
break;
}
idx = next_idx(idx, dr);
idx = vio_dring_next(dr, idx);
}
return found;
}
......@@ -663,7 +647,7 @@ static int vnet_ack(struct vnet_port *port, void *msgbuf)
/* sync for race conditions with vnet_start_xmit() and tell xmit it
* is time to send a trigger.
*/
dr->cons = next_idx(end, dr);
dr->cons = vio_dring_next(dr, end);
desc = vio_dring_entry(dr, dr->cons);
if (desc->hdr.state == VIO_DESC_READY && !port->start_cons) {
/* vnet_start_xmit() just populated this dring but missed
......@@ -784,7 +768,7 @@ static int vnet_event_napi(struct vnet_port *port, int budget)
pkt->tag.stype = VIO_SUBTYPE_INFO;
pkt->tag.stype_env = VIO_DRING_DATA;
pkt->seq = dr->rcv_nxt;
pkt->start_idx = next_idx(port->napi_stop_idx, dr);
pkt->start_idx = vio_dring_next(dr, port->napi_stop_idx);
pkt->end_idx = -1;
goto napi_resume;
}
......
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