Commit 01bf693c authored by David S. Miller's avatar David S. Miller

Merge branch 'sparc64-add-MDESC-and-VIO-support-for-VCC'

Jag Raman says:

====================
sparc64: Add MDESC & VIO support for VCC

This series of patches is part of an effort to add VCC (Virtual Console
Concentrator) support to Linux.

VCC enables the virtualization of serial console on SPARC processors. VCC
provides access to the guest domain's serial console.

VCC depends on some core functionalities in the linux kernel for SPARC. The
functionalities include LDC (Logical Domain Channels), MDESC (Machine
Descriptor) and VIO (Virtual IO protocol). In order for VCC to be enabled,
it requires that these core functionalities support them.

This series of patches adds MDESC & VIO support to enable VCC on Linux. It
is the second batch of changes to enable VCC.

This version of the series addresses the following changes
suggested by Dave Miller
Patch 4/5:
 - "name" field in vdev_port md_node_info is declared as "const char *"
 - Code has been modified to dynamically allocate & free "name" in
   vdev_port md_node_info
 - Parameters to mdesc_get_node(), mdesc_get_node_info() &
   mdesc_get_node_ops() have been updated to use "const char *"

Patch 6/5:
 - "node_name" parameter in vio_create_one() has been
   changed to "const char *" type from "char *"
 - Typecasts in vio_create_one() invocations to convert
   "const char *" to "char *" have been removed

Patch 11/5:
 - Invocations of mdesc_node_get() & mdesc_get_node_info()
   have been updated to use the prototypes defined in patch 4/5
====================
Signed-off-by: default avatarDavid S. Miller <davem@davemloft.net>
parents 69f57978 15c35e4e
......@@ -16,6 +16,7 @@ struct mdesc_handle *mdesc_grab(void);
void mdesc_release(struct mdesc_handle *);
#define MDESC_NODE_NULL (~(u64)0)
#define MDESC_MAX_STR_LEN 256
u64 mdesc_node_by_name(struct mdesc_handle *handle,
u64 from_node, const char *name);
......@@ -62,15 +63,32 @@ u64 mdesc_arc_target(struct mdesc_handle *hp, u64 arc);
void mdesc_update(void);
struct mdesc_notifier_client {
void (*add)(struct mdesc_handle *handle, u64 node);
void (*remove)(struct mdesc_handle *handle, u64 node);
void (*add)(struct mdesc_handle *handle, u64 node,
const char *node_name);
void (*remove)(struct mdesc_handle *handle, u64 node,
const char *node_name);
const char *node_name;
struct mdesc_notifier_client *next;
};
void mdesc_register_notifier(struct mdesc_notifier_client *client);
union md_node_info {
struct vdev_port {
u64 id; /* id */
u64 parent_cfg_hdl; /* parent config handle */
const char *name; /* name (property) */
} vdev_port;
struct ds_port {
u64 id; /* id */
} ds_port;
};
u64 mdesc_get_node(struct mdesc_handle *hp, const char *node_name,
union md_node_info *node_info);
int mdesc_get_node_info(struct mdesc_handle *hp, u64 node,
const char *node_name, union md_node_info *node_info);
void mdesc_fill_in_cpu_data(cpumask_t *mask);
void mdesc_populate_present_mask(cpumask_t *mask);
void mdesc_get_page_sizes(cpumask_t *mask, unsigned long *pgsz_mask);
......
......@@ -316,24 +316,33 @@ static inline u32 vio_dring_prev(struct vio_dring_state *dr, u32 index)
}
#define VIO_MAX_TYPE_LEN 32
#define VIO_MAX_NAME_LEN 32
#define VIO_MAX_COMPAT_LEN 64
struct vio_dev {
u64 mp;
struct device_node *dp;
char node_name[VIO_MAX_NAME_LEN];
char type[VIO_MAX_TYPE_LEN];
char compat[VIO_MAX_COMPAT_LEN];
int compat_len;
u64 dev_no;
u64 id;
unsigned long port_id;
unsigned long channel_id;
unsigned int tx_irq;
unsigned int rx_irq;
u64 rx_ino;
u64 tx_ino;
/* Handle to the root of "channel-devices" sub-tree in MDESC */
u64 cdev_handle;
/* MD specific data used to identify the vdev in MD */
union md_node_info md_node_info;
struct device dev;
};
......@@ -347,6 +356,7 @@ struct vio_driver {
void (*shutdown)(struct vio_dev *dev);
unsigned long driver_data;
struct device_driver driver;
bool no_irq;
};
struct vio_version {
......@@ -490,5 +500,6 @@ int vio_driver_init(struct vio_driver_state *vio, struct vio_dev *vdev,
void vio_port_up(struct vio_driver_state *vio);
int vio_set_intr(unsigned long dev_ino, int state);
u64 vio_vdev_node(struct mdesc_handle *hp, struct vio_dev *vdev);
#endif /* _SPARC64_VIO_H */
......@@ -1347,6 +1347,14 @@ int ldc_bind(struct ldc_channel *lp)
lp->hs_state = LDC_HS_OPEN;
ldc_set_state(lp, LDC_STATE_BOUND);
if (lp->cfg.mode == LDC_MODE_RAW) {
/*
* There is no handshake in RAW mode, so handshake
* is completed.
*/
lp->hs_state = LDC_HS_COMPLETE;
}
spin_unlock_irqrestore(&lp->lock, flags);
return 0;
......@@ -1460,11 +1468,13 @@ void ldc_set_state(struct ldc_channel *lp, u8 state)
lp->state = state;
}
EXPORT_SYMBOL(ldc_set_state);
int ldc_mode(struct ldc_channel *lp)
{
return lp->cfg.mode;
}
EXPORT_SYMBOL(ldc_mode);
int ldc_rx_reset(struct ldc_channel *lp)
{
......
This diff is collapsed.
This diff is collapsed.
......@@ -223,6 +223,9 @@ static int send_rdx(struct vio_driver_state *vio)
static int send_attr(struct vio_driver_state *vio)
{
if (!vio->ops)
return -EINVAL;
return vio->ops->send_attr(vio);
}
......@@ -283,6 +286,7 @@ static int process_ver_info(struct vio_driver_state *vio,
ver.minor = vap->minor;
pkt->minor = ver.minor;
pkt->tag.stype = VIO_SUBTYPE_ACK;
pkt->dev_class = vio->dev_class;
viodbg(HS, "SEND VERSION ACK maj[%u] min[%u]\n",
pkt->major, pkt->minor);
err = send_ctrl(vio, &pkt->tag, sizeof(*pkt));
......@@ -374,6 +378,9 @@ static int process_attr(struct vio_driver_state *vio, void *pkt)
if (!(vio->hs_state & VIO_HS_GOTVERS))
return handshake_failure(vio);
if (!vio->ops)
return 0;
err = vio->ops->handle_attr(vio, pkt);
if (err < 0) {
return handshake_failure(vio);
......@@ -388,6 +395,7 @@ static int process_attr(struct vio_driver_state *vio, void *pkt)
vio->hs_state |= VIO_HS_SENT_DREG;
}
}
return 0;
}
......@@ -647,10 +655,13 @@ int vio_control_pkt_engine(struct vio_driver_state *vio, void *pkt)
err = process_unknown(vio, pkt);
break;
}
if (!err &&
vio->hs_state != prev_state &&
(vio->hs_state & VIO_HS_COMPLETE))
(vio->hs_state & VIO_HS_COMPLETE)) {
if (vio->ops)
vio->ops->handshake_complete(vio);
}
return err;
}
......@@ -765,7 +776,11 @@ void vio_port_up(struct vio_driver_state *vio)
}
if (!err) {
if (ldc_mode(vio->lp) == LDC_MODE_RAW)
ldc_set_state(vio->lp, LDC_STATE_CONNECTED);
else
err = ldc_connect(vio->lp);
if (err)
printk(KERN_WARNING "%s: Port %lu connect failed, "
"err=%d\n",
......@@ -805,8 +820,7 @@ int vio_driver_init(struct vio_driver_state *vio, struct vio_dev *vdev,
return -EINVAL;
}
if (!ops->send_attr ||
!ops->handle_attr ||
if (!ops || !ops->send_attr || !ops->handle_attr ||
!ops->handshake_complete)
return -EINVAL;
......
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