extern struct bus_type visorbus_type;
typedef void (*visorbus_state_complete_func) (struct visor_device *dev,
- int status, void *dev_info);
+ int status);
struct visorchipset_state {
u32 created:1;
u32 attached:1;
* fails or completes successfully.
*/
int (*pause)(struct visor_device *dev,
- visorbus_state_complete_func complete_func,
- void *dev_info);
+ visorbus_state_complete_func complete_func);
int (*resume)(struct visor_device *dev,
- visorbus_state_complete_func complete_func,
- void *dev_info);
+ visorbus_state_complete_func complete_func);
/** These fields are for private use by the bus driver only. */
struct device_driver driver;
static void chipset_bus_create(struct visor_device *bus_info);
static void chipset_bus_destroy(struct visor_device *bus_info);
-static void chipset_device_create(struct visorchipset_device_info *dev_info);
-static void chipset_device_destroy(struct visorchipset_device_info *dev_info);
-static void chipset_device_pause(struct visorchipset_device_info *dev_info);
-static void chipset_device_resume(struct visorchipset_device_info *dev_info);
+static void chipset_device_create(struct visor_device *dev_info);
+static void chipset_device_destroy(struct visor_device *dev_info);
+static void chipset_device_pause(struct visor_device *dev_info);
+static void chipset_device_resume(struct visor_device *dev_info);
/** These functions are implemented herein, and are called by the chipset
* driver to notify us about specific events.
dev_set_drvdata(xdev, NULL);
kfree(dev);
- kfree(xdev);
}
/** This is called when device_unregister() is called for each child
* initialized.
*/
if (!dev->responded_to_device_create) {
- struct visorchipset_device_info dev_info;
-
- if (!visorchipset_get_device_info(dev->chipset_bus_no,
- dev->chipset_dev_no,
- &dev_info))
- /* hmm, what to do here */
- return rc;
dev->responded_to_device_create = true;
if (chipset_responders.device_create)
- (*chipset_responders.device_create)(&dev_info, rc);
+ (*chipset_responders.device_create)(dev, rc);
}
return rc;
}
* device.
*/
static int
-create_visor_device(struct visor_device *bdev,
- struct visorchipset_device_info *dev_info)
+create_visor_device(struct visor_device *dev)
{
int rc = -1;
- struct visor_device *dev = NULL;
- bool gotten = false, registered1 = false, registered2 = false;
- u32 chipset_bus_no = dev_info->bus_no;
- u32 chipset_dev_no = dev_info->dev_no;
+ u32 chipset_bus_no = dev->chipset_bus_no;
+ u32 chipset_dev_no = dev->chipset_dev_no;
POSTCODE_LINUX_4(DEVICE_CREATE_ENTRY_PC, chipset_dev_no, chipset_bus_no,
POSTCODE_SEVERITY_INFO);
- dev = kmalloc(sizeof(*dev), GFP_KERNEL);
- if (!dev) {
- POSTCODE_LINUX_3(DEVICE_CREATE_FAILURE_PC, chipset_dev_no,
- DIAG_SEVERITY_ERR);
- goto away;
- }
- memset(dev, 0, sizeof(struct visor_device));
- dev->visorchannel = dev_info->visorchannel;
- dev->channel_type_guid = dev_info->channel_type_guid;
- dev->chipset_bus_no = chipset_bus_no;
- dev->chipset_dev_no = chipset_dev_no;
- dev->device.parent = &bdev->device;
sema_init(&dev->visordriver_callback_lock, 1); /* unlocked */
dev->device.bus = &visorbus_type;
dev->device.groups = visorbus_dev_groups;
dev->device.release = visorbus_release_device;
/* keep a reference just for us (now 2) */
get_device(&dev->device);
- gotten = true;
dev->periodic_work =
visor_periodic_work_create(POLLJIFFIES_NORMALCHANNEL,
periodic_dev_workqueue,
goto away;
}
- /* note: device_register is simply device_initialize + device_add */
- registered1 = true;
-
rc = register_devmajorminor_attributes(dev);
if (rc < 0) {
POSTCODE_LINUX_3(DEVICE_REGISTER_FAILURE_PC, chipset_dev_no,
DIAG_SEVERITY_ERR);
- goto away;
+ goto away_register;
}
- registered2 = true;
- rc = 0;
+ list_add_tail(&dev->list_all, &list_all_device_instances);
+ return 0;
+away_register:
+ device_unregister(&dev->device);
away:
- if (rc < 0) {
- if (registered2)
- unregister_devmajorminor_attributes(dev);
- if (gotten)
- put_device(&dev->device);
- kfree(dev);
- } else {
- list_add_tail(&dev->list_all, &list_all_device_instances);
- }
+ put_device(&dev->device);
return rc;
}
device_unregister(&dev->device);
}
-static struct visor_device *
-find_visor_device_by_channel(struct visorchannel *channel)
-{
- struct list_head *listentry, *listtmp;
-
- list_for_each_safe(listentry, listtmp, &list_all_device_instances) {
- struct visor_device *dev = list_entry(listentry,
- struct visor_device,
- list_all);
- if (dev->visorchannel == channel)
- return dev;
- }
- return NULL;
-}
-
static int
get_vbus_header_info(struct visorchannel *chan,
struct spar_vbus_headerinfo *hdr_info)
}
static void
-chipset_device_create(struct visorchipset_device_info *dev_info)
+chipset_device_create(struct visor_device *dev_info)
{
- struct visor_device *bdev;
int rc = -1;
- u32 bus_no = dev_info->bus_no;
- u32 dev_no = dev_info->dev_no;
+ u32 bus_no = dev_info->chipset_bus_no;
+ u32 dev_no = dev_info->chipset_dev_no;
POSTCODE_LINUX_4(DEVICE_CREATE_ENTRY_PC, dev_no, bus_no,
POSTCODE_SEVERITY_INFO);
- bdev = visorbus_get_device_by_id(bus_no, BUS_ROOT_DEVICE, NULL);
- if (!bdev)
- goto away;
-
- POSTCODE_LINUX_4(DEVICE_CREATE_EXIT_PC, dev_no, bus_no,
- POSTCODE_SEVERITY_INFO);
-
- rc = create_visor_device(bdev, dev_info);
-away:
+ rc = create_visor_device(dev_info);
if (rc < 0) {
POSTCODE_LINUX_4(DEVICE_CREATE_FAILURE_PC, dev_no, bus_no,
POSTCODE_SEVERITY_ERR);
}
static void
-chipset_device_destroy(struct visorchipset_device_info *dev_info)
+chipset_device_destroy(struct visor_device *dev_info)
{
- struct visor_device *dev;
- int rc = -1;
-
- dev = find_visor_device_by_channel(dev_info->visorchannel);
- if (!dev)
- goto away;
- rc = 0;
-away:
- if (rc < 0)
- return;
+ remove_visor_device(dev_info);
if (chipset_responders.device_destroy)
- (*chipset_responders.device_destroy) (dev_info, rc);
- remove_visor_device(dev);
+ (*chipset_responders.device_destroy) (dev_info, 0);
}
/* This is the callback function specified for a function driver, to
* completed.
*/
static void
-pause_state_change_complete(struct visor_device *dev, int status,
- void *info)
+pause_state_change_complete(struct visor_device *dev, int status)
{
- struct visorchipset_device_info *dev_info = info;
-
if (!dev->pausing)
return;
/* Notify the chipset driver that the pause is complete, which
* will presumably want to send some sort of response to the
* initiator. */
- (*chipset_responders.device_pause) (dev_info, status);
+ (*chipset_responders.device_pause) (dev, status);
}
/* This is the callback function specified for a function driver, to
* completed.
*/
static void
-resume_state_change_complete(struct visor_device *dev, int status,
- void *info)
+resume_state_change_complete(struct visor_device *dev, int status)
{
- struct visorchipset_device_info *dev_info = info;
-
if (!dev->resuming)
return;
/* Notify the chipset driver that the resume is complete,
* which will presumably want to send some sort of response to
* the initiator. */
- (*chipset_responders.device_resume) (dev_info, status);
+ (*chipset_responders.device_resume) (dev, status);
}
/* Tell the subordinate function driver for a specific device to pause
* callback function.
*/
static void
-initiate_chipset_device_pause_resume(struct visorchipset_device_info *dev_info,
- bool is_pause)
+initiate_chipset_device_pause_resume(struct visor_device *dev, bool is_pause)
{
- struct visor_device *dev = NULL;
int rc = -1, x;
struct visor_driver *drv = NULL;
- void (*notify_func)(struct visorchipset_device_info *dev_info,
- int response) = NULL;
+ void (*notify_func)(struct visor_device *dev, int response) = NULL;
if (is_pause)
notify_func = chipset_responders.device_pause;
if (!notify_func)
goto away;
- dev = find_visor_device_by_channel(dev_info->visorchannel);
- if (!dev)
- goto away;
-
drv = to_visor_driver(dev->device.driver);
if (!drv)
goto away;
goto away;
dev->pausing = true;
- x = drv->pause(dev, pause_state_change_complete,
- (void *)dev_info);
+ x = drv->pause(dev, pause_state_change_complete);
} else {
/* This should be done at BUS resume time, but an
* existing problem prevents us from ever getting a bus
goto away;
dev->resuming = true;
- x = drv->resume(dev, resume_state_change_complete,
- (void *)dev_info);
+ x = drv->resume(dev, resume_state_change_complete);
}
if (x < 0) {
if (is_pause)
away:
if (rc < 0) {
if (notify_func)
- (*notify_func)(dev_info, rc);
+ (*notify_func)(dev, rc);
}
}
static void
-chipset_device_pause(struct visorchipset_device_info *dev_info)
+chipset_device_pause(struct visor_device *dev_info)
{
initiate_chipset_device_pause_resume(dev_info, true);
}
static void
-chipset_device_resume(struct visorchipset_device_info *dev_info)
+chipset_device_resume(struct visor_device *dev_info)
{
initiate_chipset_device_pause_resume(dev_info, false);
}
#include <linux/uuid.h>
-#include "channel.h"
#include "controlvmchannel.h"
#include "vbusdeviceinfo.h"
#include "vbushelper.h"
-struct visorchannel;
-
-/** Attributes for a particular Supervisor device.
- * Any visorchipset client can query these attributes using
- * visorchipset_get_client_device_info() or
- * visorchipset_get_server_device_info().
- */
-struct visorchipset_device_info {
- struct list_head entry;
- u32 bus_no;
- u32 dev_no;
- uuid_le dev_inst_uuid;
- struct visorchipset_state state;
- struct visorchannel *visorchannel;
- uuid_le channel_type_guid;
- u32 reserved1; /* control_vm_id */
- u64 reserved2;
- u32 switch_no; /* when devState.attached==1 */
- u32 internal_port_no; /* when devState.attached==1 */
- struct controlvm_message_header *pending_msg_hdr;/* CONTROLVM_MESSAGE */
- /** For private use by the bus driver */
- void *bus_driver_context;
-};
-
/* These functions will be called from within visorchipset when certain
* events happen. (The implementation of these functions is outside of
* visorchipset.)
struct visorchipset_busdev_notifiers {
void (*bus_create)(struct visor_device *bus_info);
void (*bus_destroy)(struct visor_device *bus_info);
- void (*device_create)(struct visorchipset_device_info *bus_info);
- void (*device_destroy)(struct visorchipset_device_info *bus_info);
- void (*device_pause)(struct visorchipset_device_info *bus_info);
- void (*device_resume)(struct visorchipset_device_info *bus_info);
+ void (*device_create)(struct visor_device *bus_info);
+ void (*device_destroy)(struct visor_device *bus_info);
+ void (*device_pause)(struct visor_device *bus_info);
+ void (*device_resume)(struct visor_device *bus_info);
};
/* These functions live inside visorchipset, and will be called to indicate
struct visorchipset_busdev_responders {
void (*bus_create)(struct visor_device *p, int response);
void (*bus_destroy)(struct visor_device *p, int response);
- void (*device_create)(struct visorchipset_device_info *p, int response);
- void (*device_destroy)(struct visorchipset_device_info *p,
- int response);
- void (*device_pause)(struct visorchipset_device_info *p, int response);
- void (*device_resume)(struct visorchipset_device_info *p, int response);
+ void (*device_create)(struct visor_device *p, int response);
+ void (*device_destroy)(struct visor_device *p, int response);
+ void (*device_pause)(struct visor_device *p, int response);
+ void (*device_resume)(struct visor_device *p, int response);
};
/** Register functions (in the bus driver) to get called by visorchipset
struct visorchipset_busdev_responders *responders,
struct ultra_vbus_deviceinfo *driver_info);
-bool visorchipset_get_bus_info(u32 bus_no,
- struct visor_device *bus_info);
-bool visorchipset_get_device_info(u32 bus_no, u32 dev_no,
- struct visorchipset_device_info *dev_info);
-bool visorchipset_set_bus_context(struct visor_device *bus_info,
- void *context);
-
/* visorbus init and exit functions */
int visorbus_init(void);
void visorbus_exit(void);
static void bus_create_response(struct visor_device *p, int response);
static void bus_destroy_response(struct visor_device *p, int response);
-static void device_create_response(struct visorchipset_device_info *p,
- int response);
-static void device_destroy_response(struct visorchipset_device_info *p,
- int response);
-static void device_resume_response(struct visorchipset_device_info *p,
- int response);
+static void device_create_response(struct visor_device *p, int response);
+static void device_destroy_response(struct visor_device *p, int response);
+static void device_resume_response(struct visor_device *p, int response);
-static void
-visorchipset_device_pause_response(struct visorchipset_device_info *p,
- int response);
+static void visorchipset_device_pause_response(struct visor_device *p,
+ int response);
static struct visorchipset_busdev_responders busdev_responders = {
.bus_create = bus_create_response,
return count;
}
-static void
-dev_info_clear(void *v)
-{
- struct visorchipset_device_info *p =
- (struct visorchipset_device_info *) v;
-
- memset(p, 0, sizeof(struct visorchipset_device_info));
-}
-
struct visor_busdev {
u32 bus_no;
u32 dev_no;
}
EXPORT_SYMBOL(visorbus_get_device_by_id);
-static struct visorchipset_device_info *
-device_find(struct list_head *list, u32 bus_no, u32 dev_no)
-{
- struct visorchipset_device_info *p;
-
- list_for_each_entry(p, list, entry) {
- if (p->bus_no == bus_no && p->dev_no == dev_no)
- return p;
- }
-
- return NULL;
-}
-
-static void busdevices_del(struct list_head *list, u32 bus_no)
-{
- struct visorchipset_device_info *p, *tmp;
-
- list_for_each_entry_safe(p, tmp, list, entry) {
- if (p->bus_no == bus_no) {
- list_del(&p->entry);
- kfree(p);
- }
- }
-}
-
static u8
check_chipset_events(void)
{
}
EXPORT_SYMBOL_GPL(visorchipset_register_busdev);
-static void
-cleanup_controlvm_structures(void)
-{
- struct visorchipset_device_info *di, *tmp_di;
-
- list_for_each_entry_safe(di, tmp_di, &dev_info_list, entry) {
- dev_info_clear(di);
- list_del(&di->entry);
- kfree(di);
- }
-}
-
static void
chipset_init(struct controlvm_message *inmsg)
{
features |= ULTRA_CHIPSET_FEATURE_REPLY;
cleanup:
- if (rc < 0)
- cleanup_controlvm_structures();
if (inmsg->hdr.flags.response_expected)
controlvm_respond_chipset_init(&inmsg->hdr, rc, features);
}
static void
device_changestate_responder(enum controlvm_id cmd_id,
- struct visorchipset_device_info *p, int response,
+ struct visor_device *p, int response,
struct spar_segment_state response_state)
{
struct controlvm_message outmsg;
- u32 bus_no = p->bus_no;
- u32 dev_no = p->dev_no;
+ u32 bus_no = p->chipset_bus_no;
+ u32 dev_no = p->chipset_dev_no;
if (p->pending_msg_hdr == NULL)
return; /* no controlvm response needed */
}
static void
-device_epilog(struct visorchipset_device_info *dev_info,
+device_epilog(struct visor_device *dev_info,
struct spar_segment_state state, u32 cmd,
struct controlvm_message_header *msg_hdr, int response,
bool need_response, bool for_visorbus)
{
struct visorchipset_busdev_notifiers *notifiers;
bool notified = false;
- u32 bus_no = dev_info->bus_no;
- u32 dev_no = dev_info->dev_no;
+ u32 bus_no = dev_info->chipset_bus_no;
+ u32 dev_no = dev_info->chipset_dev_no;
struct controlvm_message_header *pmsg_hdr = NULL;
char *envp[] = {
struct controlvm_message_packet *cmd = &inmsg->cmd;
u32 bus_no = cmd->create_device.bus_no;
u32 dev_no = cmd->create_device.dev_no;
- struct visorchipset_device_info *dev_info;
+ struct visor_device *dev_info = NULL;
struct visor_device *bus_info;
struct visorchannel *visorchannel;
int rc = CONTROLVM_RESP_SUCCESS;
- dev_info = device_find(&dev_info_list, bus_no, dev_no);
- if (dev_info && (dev_info->state.created == 1)) {
+ bus_info = visorbus_get_device_by_id(bus_no, BUS_ROOT_DEVICE, NULL);
+ if (!bus_info) {
POSTCODE_LINUX_4(DEVICE_CREATE_FAILURE_PC, dev_no, bus_no,
POSTCODE_SEVERITY_ERR);
- rc = -CONTROLVM_RESP_ERROR_ALREADY_DONE;
+ rc = -CONTROLVM_RESP_ERROR_BUS_INVALID;
goto cleanup;
}
- bus_info = visorbus_get_device_by_id(bus_no, dev_no, NULL);
- if (!bus_info) {
+
+ if (bus_info->state.created == 0) {
POSTCODE_LINUX_4(DEVICE_CREATE_FAILURE_PC, dev_no, bus_no,
POSTCODE_SEVERITY_ERR);
rc = -CONTROLVM_RESP_ERROR_BUS_INVALID;
goto cleanup;
}
- if (bus_info->state.created == 0) {
+
+ dev_info = visorbus_get_device_by_id(bus_no, dev_no, NULL);
+ if (dev_info && (dev_info->state.created == 1)) {
POSTCODE_LINUX_4(DEVICE_CREATE_FAILURE_PC, dev_no, bus_no,
POSTCODE_SEVERITY_ERR);
- rc = -CONTROLVM_RESP_ERROR_BUS_INVALID;
+ rc = -CONTROLVM_RESP_ERROR_ALREADY_DONE;
goto cleanup;
}
+
dev_info = kzalloc(sizeof(*dev_info), GFP_KERNEL);
if (!dev_info) {
POSTCODE_LINUX_4(DEVICE_CREATE_FAILURE_PC, dev_no, bus_no,
goto cleanup;
}
- INIT_LIST_HEAD(&dev_info->entry);
- dev_info->bus_no = bus_no;
- dev_info->dev_no = dev_no;
- dev_info->dev_inst_uuid = cmd->create_device.dev_inst_uuid;
+ dev_info->chipset_bus_no = bus_no;
+ dev_info->chipset_dev_no = dev_no;
+ dev_info->inst = cmd->create_device.dev_inst_uuid;
+
+ /* not sure where the best place to set the 'parent' */
+ dev_info->device.parent = &bus_info->device;
+
POSTCODE_LINUX_4(DEVICE_CREATE_ENTRY_PC, dev_no, bus_no,
POSTCODE_SEVERITY_INFO);
}
dev_info->visorchannel = visorchannel;
dev_info->channel_type_guid = cmd->create_device.data_type_uuid;
- list_add(&dev_info->entry, &dev_info_list);
POSTCODE_LINUX_4(DEVICE_CREATE_EXIT_PC, dev_no, bus_no,
POSTCODE_SEVERITY_INFO);
cleanup:
u32 bus_no = cmd->device_change_state.bus_no;
u32 dev_no = cmd->device_change_state.dev_no;
struct spar_segment_state state = cmd->device_change_state.state;
- struct visorchipset_device_info *dev_info;
+ struct visor_device *dev_info;
int rc = CONTROLVM_RESP_SUCCESS;
- dev_info = device_find(&dev_info_list, bus_no, dev_no);
+ dev_info = visorbus_get_device_by_id(bus_no, dev_no, NULL);
if (!dev_info) {
POSTCODE_LINUX_4(DEVICE_CHANGESTATE_FAILURE_PC, dev_no, bus_no,
POSTCODE_SEVERITY_ERR);
struct controlvm_message_packet *cmd = &inmsg->cmd;
u32 bus_no = cmd->destroy_device.bus_no;
u32 dev_no = cmd->destroy_device.dev_no;
- struct visorchipset_device_info *dev_info;
+ struct visor_device *dev_info;
int rc = CONTROLVM_RESP_SUCCESS;
- dev_info = device_find(&dev_info_list, bus_no, dev_no);
+ dev_info = visorbus_get_device_by_id(bus_no, dev_no, NULL);
if (!dev_info)
rc = -CONTROLVM_RESP_ERROR_DEVICE_INVALID;
else if (dev_info->state.created == 0)
{
if (response >= 0) {
bus_info->state.created = 1;
- } else {
- if (response != -CONTROLVM_RESP_ERROR_ALREADY_DONE)
- /* undo the row we just created... */
- busdevices_del(&dev_info_list,
- bus_info->chipset_bus_no);
}
bus_responder(CONTROLVM_BUS_CREATE, bus_info->pending_msg_hdr,
kfree(bus_info->pending_msg_hdr);
bus_info->pending_msg_hdr = NULL;
-
- busdevices_del(&dev_info_list, bus_info->chipset_bus_no);
}
static void
-device_create_response(struct visorchipset_device_info *dev_info, int response)
+device_create_response(struct visor_device *dev_info, int response)
{
if (response >= 0)
dev_info->state.created = 1;
response);
kfree(dev_info->pending_msg_hdr);
- dev_info->pending_msg_hdr = NULL;
}
static void
-device_destroy_response(struct visorchipset_device_info *dev_info, int response)
+device_destroy_response(struct visor_device *dev_info, int response)
{
device_responder(CONTROLVM_DEVICE_DESTROY, dev_info->pending_msg_hdr,
response);
kfree(dev_info->pending_msg_hdr);
dev_info->pending_msg_hdr = NULL;
-
- dev_info_clear(dev_info);
}
static void
-visorchipset_device_pause_response(struct visorchipset_device_info *dev_info,
+visorchipset_device_pause_response(struct visor_device *dev_info,
int response)
{
device_changestate_responder(CONTROLVM_DEVICE_CHANGESTATE,
}
static void
-device_resume_response(struct visorchipset_device_info *dev_info, int response)
+device_resume_response(struct visor_device *dev_info, int response)
{
device_changestate_responder(CONTROLVM_DEVICE_CHANGESTATE,
dev_info, response,
dev_info->pending_msg_hdr = NULL;
}
-bool
-visorchipset_get_device_info(u32 bus_no, u32 dev_no,
- struct visorchipset_device_info *dev_info)
-{
- void *p = device_find(&dev_info_list, bus_no, dev_no);
-
- if (!p)
- return false;
- memcpy(dev_info, p, sizeof(struct visorchipset_device_info));
- return true;
-}
-EXPORT_SYMBOL_GPL(visorchipset_get_device_info);
-
-bool
-visorchipset_set_device_context(struct visorchipset_device_info *p,
- void *context)
-{
- if (!p)
- return false;
- p->bus_driver_context = context;
- return true;
-}
-EXPORT_SYMBOL_GPL(visorchipset_set_device_context);
-
static ssize_t chipsetready_store(struct device *dev,
struct device_attribute *attr,
const char *buf, size_t count)
periodic_controlvm_workqueue = NULL;
destroy_controlvm_payload_info(&controlvm_payload_info);
- cleanup_controlvm_structures();
-
memset(&g_chipset_msg_hdr, 0, sizeof(struct controlvm_message_header));
visorchannel_destroy(controlvm_channel);