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); ...@@ -61,6 +61,7 @@ void ldc_free(struct ldc_channel *lp);
/* Register TX and RX queues of the link with the hypervisor. */ /* Register TX and RX queues of the link with the hypervisor. */
int ldc_bind(struct ldc_channel *lp); 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 /* For non-RAW protocols we need to complete a handshake before
* communication can proceed. ldc_connect() does that, if the * communication can proceed. ldc_connect() does that, if the
......
...@@ -300,6 +300,21 @@ static inline u32 vio_dring_avail(struct vio_dring_state *dr, ...@@ -300,6 +300,21 @@ static inline u32 vio_dring_avail(struct vio_dring_state *dr,
((dr->prod - dr->cons) & (ring_size - 1)) - 1); ((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_TYPE_LEN 32
#define VIO_MAX_COMPAT_LEN 64 #define VIO_MAX_COMPAT_LEN 64
......
...@@ -1222,11 +1222,12 @@ struct ldc_channel *ldc_alloc(unsigned long id, ...@@ -1222,11 +1222,12 @@ struct ldc_channel *ldc_alloc(unsigned long id,
} }
EXPORT_SYMBOL(ldc_alloc); 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) { if (lp->flags & LDC_FLAG_REGISTERED_IRQS) {
free_irq(lp->cfg.rx_irq, lp); free_irq(lp->cfg.rx_irq, lp);
free_irq(lp->cfg.tx_irq, lp); free_irq(lp->cfg.tx_irq, lp);
lp->flags &= ~LDC_FLAG_REGISTERED_IRQS;
} }
if (lp->flags & LDC_FLAG_REGISTERED_QUEUES) { if (lp->flags & LDC_FLAG_REGISTERED_QUEUES) {
...@@ -1240,10 +1241,15 @@ void ldc_free(struct ldc_channel *lp) ...@@ -1240,10 +1241,15 @@ void ldc_free(struct ldc_channel *lp)
lp->flags &= ~LDC_FLAG_ALLOCED_QUEUES; 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); kfree(lp->mssbuf);
ldc_iommu_release(lp); ldc_iommu_release(lp);
kfree(lp); kfree(lp);
......
...@@ -368,7 +368,7 @@ static struct smp_funcall { ...@@ -368,7 +368,7 @@ static struct smp_funcall {
unsigned long arg5; unsigned long arg5;
unsigned long processors_in[NR_CPUS]; /* Set when ipi entered. */ unsigned long processors_in[NR_CPUS]; /* Set when ipi entered. */
unsigned long processors_out[NR_CPUS]; /* Set when ipi exited. */ unsigned long processors_out[NR_CPUS]; /* Set when ipi exited. */
} ccall_info; } ccall_info __attribute__((aligned(8)));
static DEFINE_SPINLOCK(cross_call_lock); 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, ...@@ -466,23 +466,6 @@ static int vnet_send_ack(struct vnet_port *port, struct vio_dring_state *dr,
return err; 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, static struct vio_net_desc *get_rx_desc(struct vnet_port *port,
struct vio_dring_state *dr, struct vio_dring_state *dr,
u32 index) u32 index)
...@@ -556,7 +539,8 @@ static int vnet_walk_rx(struct vnet_port *port, struct vio_dring_state *dr, ...@@ -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; int ack_start = -1, ack_end = -1;
bool send_ack = true; 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); 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, ...@@ -570,7 +554,7 @@ static int vnet_walk_rx(struct vnet_port *port, struct vio_dring_state *dr,
if (ack_start == -1) if (ack_start == -1)
ack_start = start; ack_start = start;
ack_end = start; ack_end = start;
start = next_idx(start, dr); start = vio_dring_next(dr, start);
if (ack && start != end) { if (ack && start != end) {
err = vnet_send_ack(port, dr, ack_start, ack_end, err = vnet_send_ack(port, dr, ack_start, ack_end,
VIO_DRING_ACTIVE); VIO_DRING_ACTIVE);
...@@ -584,7 +568,7 @@ static int vnet_walk_rx(struct vnet_port *port, struct vio_dring_state *dr, ...@@ -584,7 +568,7 @@ static int vnet_walk_rx(struct vnet_port *port, struct vio_dring_state *dr,
} }
} }
if (unlikely(ack_start == -1)) 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) { if (send_ack) {
port->napi_resume = false; port->napi_resume = false;
return vnet_send_ack(port, dr, ack_start, ack_end, 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) ...@@ -633,7 +617,7 @@ static int idx_is_pending(struct vio_dring_state *dr, u32 end)
found = 1; found = 1;
break; break;
} }
idx = next_idx(idx, dr); idx = vio_dring_next(dr, idx);
} }
return found; return found;
} }
...@@ -663,7 +647,7 @@ static int vnet_ack(struct vnet_port *port, void *msgbuf) ...@@ -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 /* sync for race conditions with vnet_start_xmit() and tell xmit it
* is time to send a trigger. * 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); desc = vio_dring_entry(dr, dr->cons);
if (desc->hdr.state == VIO_DESC_READY && !port->start_cons) { if (desc->hdr.state == VIO_DESC_READY && !port->start_cons) {
/* vnet_start_xmit() just populated this dring but missed /* vnet_start_xmit() just populated this dring but missed
...@@ -784,7 +768,7 @@ static int vnet_event_napi(struct vnet_port *port, int budget) ...@@ -784,7 +768,7 @@ static int vnet_event_napi(struct vnet_port *port, int budget)
pkt->tag.stype = VIO_SUBTYPE_INFO; pkt->tag.stype = VIO_SUBTYPE_INFO;
pkt->tag.stype_env = VIO_DRING_DATA; pkt->tag.stype_env = VIO_DRING_DATA;
pkt->seq = dr->rcv_nxt; 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; pkt->end_idx = -1;
goto napi_resume; 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